-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Allow producer to produce predefined blocks #2081
Conversation
} | ||
should_continue = true; | ||
} else { | ||
tracing::error!("The PoA task should be the holder of the `Sender`"); |
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.
I don't understand this message here. If I read this correctly, this branch is taken iff the PoA task drops the channel, which happens only if it panics. Maybe "The PoA task panicked!" or something like that would be appropriate? Maybe this function should panic as well?
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.
This comment was here before. I agree it's not clear.
The whole mechanism should be documented somehow, somewhere. Probably in doc comments in some relevant trait or function. |
tests/tests/snapshot.rs
Outdated
@@ -28,10 +28,10 @@ async fn loads_snapshot() { | |||
// setup config | |||
let starting_state = StateConfig { | |||
last_block: Some(LastBlockConfig { | |||
block_height: (u32::MAX - 1).into(), | |||
block_height: (u32::MAX - 2).into(), |
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.
Why do we need to change this file?
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.
Because the code internally calls next_block
now. If it's u32::Max
(as it becomes) then next_block
will panic.
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.
Then test shouldn't produce any blocks, maybe we need to disable block producer
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.
Adding Trigger::Never
doesn't seem to fix the issue; the producer is still being run.
// Update last block time | ||
self.last_height = *sealed_block.entity.header().height(); | ||
self.last_timestamp = sealed_block.entity.header().time(); | ||
self.last_block_created = last_block_created; |
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.
Because you don't set the timer here, I think after applying predefined blocks the server will halt in the case of Interval
trigger more
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.
Maybe we could somehow reuse main part of the produce_block
function
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.
It will be removed during #1917
|
||
for (tx_id, err) in skipped_transactions { | ||
let maybe_tx = txs.iter().find(|tx| tx.id(chain_id) == tx_id); | ||
if let Some(tx) = maybe_tx { |
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.
We should always be able to find the transaction. Maybe it is better to return an error
let txs = predefined_block.transactions(); | ||
|
||
for (tx_id, err) in skipped_transactions { | ||
let maybe_tx = txs.iter().find(|tx| tx.id(chain_id) == tx_id); |
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.
It is very performance-heavy. It is better to iterate over all transactions in the block and check that it is in the hash map of failed transactions.
let maybe_tx = txs.iter().find(|tx| tx.id(chain_id) == tx_id); | ||
if let Some(tx) = maybe_tx { | ||
tracing::error!( | ||
"During block production got invalid transaction {:?} with error {:?}", |
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.
We agreed that in the case of discarded predefined transactions we want to print them in JSON format with some BEGIN {JSON_TX} END
marker.
let maybe_block = self.predefined_blocks.get_block(&next_height); | ||
if let Some(block) = maybe_block { | ||
self.produce_predefined_block(&block, &chain_id).await?; | ||
should_continue = true; |
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.
Could we please make an early return here? To avoid shifting a big part of the code into the if
statement?
We can move the code below into the else {
in a separate PR
(2u32.into(), block_for_height(2)), | ||
(3u32.into(), block_for_height(3)), | ||
(4u32.into(), block_for_height(4)), |
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.
Could we also test the case when we produce some blocks first form the interval, then we have predefined blocks, please?
let actual = block_receiver.recv().await.unwrap(); | ||
assert_eq!(expected, actual); | ||
} | ||
let maybe_produced_block = block_receiver.recv().await.unwrap(); |
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.
Could this test also verify the production of the block after pre-defined blocks, please? Like 3 predefined blocks, and 1-3 non predefined(from interval)
Linked Issues/PRs
Part of #1902
Description
Provide mechanism for taking predefined blocks and including them in block production.
Does not provide the mechanism for introducing those predefined blocks into the running system, e.g. parsing from file or something. That will come after.
Checklist
Before requesting review
After merging, notify other teams
[Add or remove entries as needed]