-
Notifications
You must be signed in to change notification settings - Fork 11.2k
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
[consensus] Disable multi leader per round in universal committer #18206
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
3 Ignored Deployments
|
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.
Great find and thanks for the fix @arun-koshy ! If indeed you won't try to do accounting based on the committer index then this PR looks good
Personally I would like us to have though a test that will specifically test this case - when schedule changes and different leader that the last_decided
is elected. Since we do have the flag we can confirm that with the flag enabled/disabled we get either a double commit for same round and single with the fix. Do you believe we can add this?
crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Testnet_version_50.snap
Outdated
Show resolved
Hide resolved
@@ -172,7 +174,7 @@ impl TransactionClient { | |||
|
|||
/// Submits a list of transactions to be sequenced. The method returns when all the transactions have been successfully included | |||
/// to next proposed blocks. | |||
pub async fn submit(&self, transactions: Vec<Vec<u8>>) -> Result<(), ClientError> { | |||
pub async fn submit(&self, transactions: Vec<Vec<u8>>) -> Result<BlockRef, ClientError> { |
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.
There is a small edge case here as we don't have a guarantee that all the provided transactions will be included in the same block - they might span across multiple blocks. So based on the current functionality this will return the BlockRef
of the transactions that got included in the last block. We can ignore for now as this will consider only the soft bundle transactions, but maybe leave a TODO
to potentially refactor in the future
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.
Good point! Left a todo but wanted to ensure my understanding is correct here, if we have too many transactions for one block we will acknowledge that the transactions were included in 'Block A' and then create a new TransactionGuard
with the remaining transactions. The remaining transactions should get included in the subsequent block(s) but their acknowledgment will not be received by Sui? So like you said Sui will print out that all transactions were included in 'Block A' but may span 'Block B, C, etc.'
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.
So on the above example the Block A
transactions will not get acknowledged as the ack
channel will only get passed with the last set of transactions. Let's assume that the transactions are enough to span across three blocks, Block A, B & C
. The ack channel will only be provided to the closure that performs the acknowledgment only when the last transactions have been included to Block C
. So the last block is the one that performs the acknowledgment
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.
Personally I think just returning the last block is fine. When the last block is committed, blocks before should usually be committed. If we try to be precise here, we will need to return the mapping between transactions and blocks.
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.
Yeah I guess we could be as precise/less precise want to. As I said, this only concerns soft bundles so wouldn't prioritise any time soon if needs to change.
fa49949
to
8c6df9d
Compare
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.
Spoke offline with the team and decided to stick with the simpler solution for now and will investigate multi leader per round in the future. Also added some tests for this case
@@ -172,7 +174,7 @@ impl TransactionClient { | |||
|
|||
/// Submits a list of transactions to be sequenced. The method returns when all the transactions have been successfully included | |||
/// to next proposed blocks. | |||
pub async fn submit(&self, transactions: Vec<Vec<u8>>) -> Result<(), ClientError> { | |||
pub async fn submit(&self, transactions: Vec<Vec<u8>>) -> Result<BlockRef, ClientError> { |
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.
Good point! Left a todo but wanted to ensure my understanding is correct here, if we have too many transactions for one block we will acknowledge that the transactions were included in 'Block A' and then create a new TransactionGuard
with the remaining transactions. The remaining transactions should get included in the subsequent block(s) but their acknowledgment will not be received by Sui? So like you said Sui will print out that all transactions were included in 'Block A' but may span 'Block B, C, etc.'
8c6df9d
to
a36a1a4
Compare
…stenLabs#18206) ## Description On the boundaries of Leader Schedule change it is possible to elect a new leader for the same round resulting in multiple commits for the same round. This was unintended output from consensus as we have set the parameters to only commit 1 leader per round. Sui also only expects one commit per round, because of this the second commit of the same round is ignored by consensus handler. This led to an error in simtests where the `EndOfPublish` transaction was part of this ignored commit and we could not form a quorum to close the epoch without this node. Changes - Explicitly set number of leaders per round to 1 for Mysticeti commits. I wanted to try and maintain this but it would be a much more intrusive change and we will probably have to do a larger refactor to fully support it anyways, so better off doing the cleaner mitigation for now. - Pass back the block that the transaction was included in as part of the tx acknowledgment and include that in the logging to help with debugging future issues. - Also a minor change to print if all tests pass during simtest seed-search ## Test plan ``` ❯ scripts/simtest/seed-search.py simtest --test test_reconfig_with_committee_change_basic --num-seeds 1000 Updating git repository `https://github.com/MystenLabs/mysten-sim.git` Compiling consensus-core v0.1.0 (/Users/arunkoshy/Documents/GitHub/sui/consensus/core) ... All tests passed successfully! Killing child processes [1] 391 killed scripts/simtest/seed-search.py simtest --test --num-seeds 1000 ``` --- ## Release notes - [X] Protocol: Version 50 - Explicitly set number of leaders per round to 1 for Mysticeti commits - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: --------- Co-authored-by: Mark Logan <mark@mystenlabs.com>
Description
On the boundaries of Leader Schedule change it is possible to elect a new leader for the same round resulting in multiple commits for the same round. This was unintended output from consensus as we have set the parameters to only commit 1 leader per round. Sui also only expects one commit per round, because of this the second commit of the same round is ignored by consensus handler. This led to an error in simtests where the
EndOfPublish
transaction was part of this ignored commit and we could not form a quorum to close the epoch without this node.Changes
Test plan
Release notes