Skip to content

INDY-2032: Fix phantom transactions in audit ledger #1151

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Apr 8, 2019

Conversation

ashcherbakov
Copy link
Contributor

  1. Fix sending of 3PC messages by a primary on an old view during or in between view changes. This was leading to phantom txns in audit ledger
  2. More integration tests
  3. Get rid of stashedOrderedRequest
  4. Improved replica 3PC validation to allow only Commits during the view change.

@ashcherbakov ashcherbakov changed the title INDY-2032: Audit logs INDY-2032: Fix phantom transactions in audit ledger Apr 5, 2019
Copy link
Contributor

@skhoroshavin skhoroshavin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good, it's a pity that some tests are still failing )

@property
def pre_view_change_in_progress(self):
return False if self.view_changer is None \
else self.view_changer.pre_view_change_in_progress
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer something more readable and more clear intentions like

if self.view_changer is None:
    return False
return self.view_changer.pre_view_change_in_progress

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

self.processOrdered(msg)
else:
logger.info("{} stashing {} since mode is {}".format(self, msg, self.mode))
self.stashedOrderedReqs.append(msg)
logger.info("{} can not process Ordered message {} since mode is {}".format(self, msg, self.mode))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be at least warning, since here we're discarding ordering result, and if I understand correctly we should never reach this point in production code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

def _apply_reqs(self, requests, three_pc_batch: ThreePcBatch):
for req in requests:
self._node.applyReq(req, three_pc_batch.pp_time)
self._node.onBatchCreated(three_pc_batch)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use one from node? It looks like this should be really an atomic operation available through node interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The one from node was deleted, since it's not used anywhere else.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. The method is in Node again.

@pre_view_change_in_progress.setter
def pre_view_change_in_progress(self, value: bool):
self._pre_view_change_in_progress = value

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need to make this a property if we are just using trivial getter and setter without any additional logic?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a quick fix, I did it similar to view_change_in_progress, but yes, agree.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -52,7 +55,7 @@ def validate_3pc_msg(self, msg):
if view_no == self.replica.viewNo and node.view_change_in_progress:
return STASH_VIEW, FUTURE_VIEW

# If Catchup in View Change finished then process a message
# If Catchup in View Change finished then process Commit messages
if node.is_synced and node.view_change_in_progress:
return PROCESS, None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explicit check that this is a really commit message would be good here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The explicit check is already done above.

Signed-off-by: ashcherbakov <[email protected]>
Signed-off-by: ashcherbakov <[email protected]>
@ashcherbakov
Copy link
Contributor Author

(ci) test this please

Signed-off-by: ashcherbakov <[email protected]>
@ashcherbakov
Copy link
Contributor Author

(ci) test this please

skhoroshavin
skhoroshavin previously approved these changes Apr 7, 2019
andkononykhin
andkononykhin previously approved these changes Apr 8, 2019
Signed-off-by: ashcherbakov <[email protected]>
@@ -2670,7 +2670,23 @@ def processOrdered(self, ordered: Ordered):
ordered.stateRootHash,
ordered.txnRootHash))

self.executeBatch(ThreePcBatch.from_ordered(ordered),
three_pc_batch = ThreePcBatch.from_ordered(ordered)
if self.db_manager.ledgers[AUDIT_LEDGER_ID].uncommittedRootHash is None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could it happen so that uncommittedRootHash is not None but due to other batch in flight, so that we still need to manually apply transactions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think no, because here we always have apply-commit cycle, so that even if this is an Ordered msg came in between catchup rounds during view change, each Ordered will be re-applied and committed immediately, so that it always end up with empty uncommitted state if the audit ledger.

@ashcherbakov ashcherbakov merged commit 68562bd into hyperledger:master Apr 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants