Revert round-advance on TendermintMachine::new if local clock is ahead of block start

It was improperly implemented, as it assumed rounds had a constant time
interval, which they do not. It also is against the spec and was meant to
absolve us of issues with poor performance when post-starting blockchains. The
new, and much more proper, workaround for the latter is a 120-second delay
between the Substrate time and the Tributary start time.
This commit is contained in:
Luke Parker 2023-08-13 04:32:21 -04:00
parent 13a8b0afc1
commit e2901cab06
No known key found for this signature in database
2 changed files with 12 additions and 14 deletions

View file

@ -77,7 +77,8 @@ async fn handle_new_set<
// Since this block is in the past, and Tendermint doesn't play nice with starting chains after // Since this block is in the past, and Tendermint doesn't play nice with starting chains after
// their start time (though it does eventually work), delay the start time by 120 seconds // their start time (though it does eventually work), delay the start time by 120 seconds
// This is meant to handle ~20 blocks of lack of finalization for this first block // This is meant to handle ~20 blocks of lack of finalization for this first block
let time = time + 120; const SUBSTRATE_TO_TRIBUTARY_TIME_DELAY: u64 = 120;
let time = time + SUBSTRATE_TO_TRIBUTARY_TIME_DELAY;
let spec = TributarySpec::new(block.hash(), time, set, set_data); let spec = TributarySpec::new(block.hash(), time, set, set_data);
create_new_tributary(db, spec.clone()).await; create_new_tributary(db, spec.clone()).await;

View file

@ -265,13 +265,19 @@ impl<N: Network + 'static> TendermintMachine<N> {
synced_block_result: synced_block_result_recv, synced_block_result: synced_block_result_recv,
messages: msg_send, messages: msg_send,
machine: { machine: {
let now = SystemTime::now();
let sys_time = sys_time(last_time); let sys_time = sys_time(last_time);
let time_until = sys_time.duration_since(SystemTime::now()).unwrap_or(Duration::ZERO); let mut negative = false;
let time_until = sys_time.duration_since(now).unwrap_or_else(|_| {
negative = true;
now.duration_since(sys_time).unwrap_or(Duration::ZERO)
});
log::info!( log::info!(
target: "tendermint", target: "tendermint",
"new TendermintMachine building off block {} is scheduled to start in {}s", "new TendermintMachine building off block {} is scheduled to start in {}{}s",
last_block.0, last_block.0,
time_until.as_secs() if negative { "-" } else { "" },
time_until.as_secs(),
); );
// If the last block hasn't ended yet, sleep until it has // If the last block hasn't ended yet, sleep until it has
@ -308,16 +314,7 @@ impl<N: Network + 'static> TendermintMachine<N> {
// after it, without the standard amount of separation (so their times will be // after it, without the standard amount of separation (so their times will be
// equivalent or minimally offset) // equivalent or minimally offset)
// For callers wishing to avoid this, they should pass (0, GENESIS + N::block_time()) // For callers wishing to avoid this, they should pass (0, GENESIS + N::block_time())
let start_time = CanonicalInstant::new(last_time); machine.round(RoundNumber(0), Some(CanonicalInstant::new(last_time)));
machine.round(RoundNumber(0), Some(start_time));
// If we're past the start time, skip to and only join the next round
let rounds_to_skip = Instant::now().duration_since(start_time.instant()).as_secs() /
u64::from(N::block_time());
if rounds_to_skip != 0 {
log::trace!("joining mid-block so skipping {rounds_to_skip} rounds");
machine.round(RoundNumber(rounds_to_skip.try_into().unwrap()), None);
}
machine machine
}, },
} }