-
Notifications
You must be signed in to change notification settings - Fork 8.9k
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
removed the request from the pool if the the proposal is bad #4572
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, but this is not the way to fix it.
SmartBFT interprets that config change as different transactions probably due to the signatures being different.
The way to fix it, is to explicitly handle this case upon a commit of a config block:
- In the chain's deliver function
- When we replicate a config block in the synchronizer.
If a config block is committed, we must do a deep scan of the request pool and purge every transaction that has the same config update payload as the one we just committed, ignoring the signature.
Let me put it this way, the situation I am correcting: Just because this particular option has been found now doesn't mean that there won't be others in the future. For example, I will prepare 4 different transactions for 4 orders, which you will not define as the same. I'll send to each node at the same time. |
Forgot to mention. Any attempts to synchronise return the response that you have the latest everything |
But the only way to change the validity of a transaction for an orderer is via a config block. Therefore, config blocks is what we should be concerned about. We need to also take in account synchronization, because a node might be behind and in that case it will not participate in consensus, so the only way to notify that a config block was committed, is via the synchronization code. Transaction validation in BFT happens at the pre-prepare processing phase, that is not the right spot to remove requests from the request pool. Requests should only be removed from the request pool upon a block commit. |
I have already shown above that I can drop the channel and unequal config updates
Let me remind you that synchronization will fix all this with the c.MaybePruneRevokedRequests() method.
But verificationSequences are equal, so it doesn't get to deletion.
|
@yacovm I guess I should add an explanation: I first wanted to change c.MaybePruneRevokedRequests by removing the check for equal Then I thought that during synchronisation in fabric to call deletion from the pool of invalid transactions, but how to pass in synchronisation context to call deletion not every synchronisation. And the clearest, easiest and cheapest solution was to remove from the pool after a failed proposal check. Anyway, this option works. Probably the best. But when a better option is found, you can always remove mine and add a better one. |
…al is bad Signed-off-by: Fedor Partanskiy <pfi79@mail.ru>
6811c0b
to
a99dbc2
Compare
…al is bad (hyperledger#4572) Signed-off-by: Fedor Partanskiy <pfi79@mail.ru> (cherry picked from commit 073b570) Signed-off-by: Fedor Partanskiy <pfi79@mail.ru>
In the documentation and in the examples, the channel update transaction is send to one and only one orderer. Like in raft. The smartbft features are not used.
I checked what happens if a channel update transaction is sent to each orderer. There are errors.
What's happening?
When an orderer receives a channel update transaction, it takes the current channel config and applies the update to it and re-signs the transaction. It then sends it to the smartbft consensus. Total 7 different transactions appear in the consensus (1 error - not critical).
Then, one transaction (of the leader) is accepted and the rest automatically become bad. Transactions that followers send to the leader do not reach him, as they are considered bad. Followers change the leader. The new leader generates a proposal that contains a bad transaction. This proposal returns an error when checked. The mechanism of leader change is started. So in an infinite loop (the 2nd error is critical).
My current solution fixes the 2nd error. In case there is a bad transaction in the proposal, we remove it from the request pool.