From 487a16a43fec4a7db3c1acab2eae91d44448ce19 Mon Sep 17 00:00:00 2001 From: Kirill Mikheev Date: Fri, 27 Dec 2024 12:59:43 +0300 Subject: [PATCH] refactor: use `GenesisInfo` from types --- block-util/src/block/block_proof_stuff.rs | 3 +- block-util/src/dict.rs | 2 +- cli/src/cmd/debug/mempool.rs | 7 ++-- cli/src/cmd/tools/gen_zerostate.rs | 3 +- cli/src/node/mod.rs | 2 +- collator/src/collator/do_collate/finalize.rs | 34 +++++++++--------- collator/src/collator/mod.rs | 14 +++++--- collator/src/manager/mod.rs | 13 +++---- collator/src/mempool/impls/std_impl.rs | 16 ++++----- consensus/src/dag/producer.rs | 2 +- consensus/src/engine/mempool_config.rs | 38 +++++++------------- consensus/src/models/point/body.rs | 2 +- consensus/src/test_utils/bootstrap.rs | 4 +-- core/src/global_config.rs | 11 +++--- 14 files changed, 70 insertions(+), 81 deletions(-) diff --git a/block-util/src/block/block_proof_stuff.rs b/block-util/src/block/block_proof_stuff.rs index 76077ef18..005e37b66 100644 --- a/block-util/src/block/block_proof_stuff.rs +++ b/block-util/src/block/block_proof_stuff.rs @@ -63,8 +63,7 @@ impl BlockProofStuff { consensus_info: ConsensusInfo { vset_switch_round: 0, prev_vset_switch_round: 0, - genesis_round: 0, - genesis_millis: 0, + genesis_info: GenesisInfo::default(), prev_shuffle_mc_validators: true, }, signature_count: 0, diff --git a/block-util/src/dict.rs b/block-util/src/dict.rs index c4d2fc8ca..da0f0e31f 100644 --- a/block-util/src/dict.rs +++ b/block-util/src/dict.rs @@ -56,7 +56,7 @@ where dict_root: build_aug_dict_from_sorted_iter( iter.into_iter().map(|(k, a, v)| { // SAFETY: We know that this cell is not a library cell. - let value = unsafe { v.inner().as_slice_unchecked() }; + let value = v.inner().as_slice_allow_pruned(); (k, a, value) }), K::BITS, diff --git a/cli/src/cmd/debug/mempool.rs b/cli/src/cmd/debug/mempool.rs index 5dacb74e7..f4d702147 100644 --- a/cli/src/cmd/debug/mempool.rs +++ b/cli/src/cmd/debug/mempool.rs @@ -6,6 +6,7 @@ use std::sync::Arc; use anyhow::{Context, Result}; use clap::Parser; use everscale_crypto::ed25519; +use everscale_types::models::GenesisInfo; use tokio::sync::mpsc; use tycho_block_util::state::ShardStateStuff; use tycho_consensus::prelude::{Engine, InputBuffer, MempoolAdapterStore, MempoolConfigBuilder}; @@ -229,13 +230,11 @@ impl Mempool { // FIXME load genesis data from McStateExtra instead of using default let global_config = self.config_override.unwrap_or(MempoolGlobalConfig { - start_round: 0, - genesis_time_millis: 0, + genesis_info: GenesisInfo::default(), consensus_config: None, }); - self.config_builder - .set_genesis(global_config.start_round, global_config.genesis_time_millis); + self.config_builder.set_genesis(global_config.genesis_info); let consensus_config = match &global_config.consensus_config { Some(consensus_config) => consensus_config, diff --git a/cli/src/cmd/tools/gen_zerostate.rs b/cli/src/cmd/tools/gen_zerostate.rs index 79f7b41ad..f44db5002 100644 --- a/cli/src/cmd/tools/gen_zerostate.rs +++ b/cli/src/cmd/tools/gen_zerostate.rs @@ -395,8 +395,7 @@ impl ZerostateConfig { consensus_info: ConsensusInfo { vset_switch_round: session_seqno, prev_vset_switch_round: session_seqno, - genesis_round: 0, - genesis_millis: 0, + genesis_info: GenesisInfo::default(), prev_shuffle_mc_validators: collation_config.shuffle_mc_validators, }, prev_blocks: AugDict::new(), diff --git a/cli/src/node/mod.rs b/cli/src/node/mod.rs index 2d81c5322..0f70e5af8 100644 --- a/cli/src/node/mod.rs +++ b/cli/src/node/mod.rs @@ -285,7 +285,7 @@ impl Node { if let Some(consensus_config) = &global.consensus_config { config.set_consensus_config(consensus_config); } // else: will be set from mc state after sync - config.set_genesis(global.start_round, global.genesis_time_millis); + config.set_genesis(global.genesis_info); }) .await; }; diff --git a/collator/src/collator/do_collate/finalize.rs b/collator/src/collator/do_collate/finalize.rs index 649645946..6ddcc2250 100644 --- a/collator/src/collator/do_collate/finalize.rs +++ b/collator/src/collator/do_collate/finalize.rs @@ -719,11 +719,10 @@ impl Phase { let mut consensus_info = prev_state_extra.consensus_info; if let Some(mp_cfg_override) = &collation_data.mempool_config_override { - if mp_cfg_override.start_round >= consensus_info.genesis_round - && mp_cfg_override.genesis_time_millis > consensus_info.genesis_millis + if mp_cfg_override.genesis_info.start_round >= consensus_info.genesis_info.start_round + && mp_cfg_override.genesis_info.millis > consensus_info.genesis_info.millis { - consensus_info.genesis_round = mp_cfg_override.start_round; - consensus_info.genesis_millis = mp_cfg_override.genesis_time_millis; + consensus_info.genesis_info = mp_cfg_override.genesis_info; is_key_block = true; } @@ -780,19 +779,20 @@ impl Phase { // mempool can create `max_consensus_lag` rounds in DAG until it stops to wait let mempool_last_round_to_create = prev_processed_to_anchor + consensus_config.max_consensus_lag_rounds as u32; - let session_last_round = - if consensus_info.prev_vset_switch_round > consensus_info.genesis_round { - // consensus session cannot abort until reaching full history amount of rounds, - // because mempool has to re-validate historical points during sync, - // and can hold just one previous vset to check peer authority - let full_history_round = consensus_info.prev_vset_switch_round - + consensus_config.max_total_rounds(); - mempool_last_round_to_create.max(full_history_round) - } else { - // mempool history does not span across genesis, - // so can change vset earlier without invalidating points - mempool_last_round_to_create - }; + let session_last_round = if consensus_info.prev_vset_switch_round + > consensus_info.genesis_info.start_round + { + // consensus session cannot abort until reaching full history amount of rounds, + // because mempool has to re-validate historical points during sync, + // and can hold just one previous vset to check peer authority + let full_history_round = consensus_info.prev_vset_switch_round + + consensus_config.max_total_rounds(); + mempool_last_round_to_create.max(full_history_round) + } else { + // mempool history does not span across genesis, + // so can change vset earlier without invalidating points + mempool_last_round_to_create + }; // `+1` because it will be the first mempool round in the new session session_last_round + 1 }; diff --git a/collator/src/collator/mod.rs b/collator/src/collator/mod.rs index 4be63b55f..3ccd480c2 100644 --- a/collator/src/collator/mod.rs +++ b/collator/src/collator/mod.rs @@ -441,13 +441,17 @@ impl CollatorStdImpl { working_state: &WorkingState, anchors_proc_info: AnchorsProcessingInfo, ) -> Result, CollatorError> { - let import_init_anchors = match &self.mempool_config_override { + let import_init_anchors = match self + .mempool_config_override + .as_ref() + .map(|c| c.genesis_info) + { // There may be cases when processed to anchor in shard is before anchor in master. // We can produce incorrect shard block, then ignore it, take correct from bc and try to collate next one. - Some(mempool_config) if mempool_config.start_round > 0 => { + Some(genesis_info) if genesis_info.start_round > 0 => { let import_init_anchors = - if anchors_proc_info.processed_to_anchor_id <= mempool_config.start_round { - if anchors_proc_info.processed_to_anchor_id == mempool_config.start_round { + if anchors_proc_info.processed_to_anchor_id <= genesis_info.start_round { + if anchors_proc_info.processed_to_anchor_id == genesis_info.start_round { // when we start from new genesis we unable to import anchor on the start round // because mempool actually is starting from the next round // so we should not try to import init anchors @@ -482,7 +486,7 @@ impl CollatorStdImpl { .map_err(|e| CollatorError::Anyhow(e.into()))? .created_by; let anchor_info = AnchorInfo { - id: mempool_config.start_round, + id: genesis_info.start_round, ct: anchors_proc_info.last_imported_chain_time, all_exts_count: 0, our_exts_count: 0, diff --git a/collator/src/manager/mod.rs b/collator/src/manager/mod.rs index 9a113efb6..e5df958ae 100644 --- a/collator/src/manager/mod.rs +++ b/collator/src/manager/mod.rs @@ -1168,14 +1168,15 @@ where let last_consesus_info = self .blocks_cache .get_consensus_info_for_mc_block(&last_applied_mc_block_key)?; - if mp_cfg_override.start_round >= last_consesus_info.genesis_round - && mp_cfg_override.genesis_time_millis > last_consesus_info.genesis_millis + if mp_cfg_override.genesis_info.start_round + >= last_consesus_info.genesis_info.start_round + && mp_cfg_override.genesis_info.millis > last_consesus_info.genesis_info.millis { tracing::debug!(target: tracing_targets::COLLATION_MANAGER, - prev_genesis_start_round = last_consesus_info.genesis_round, - prev_genesis_time_millis = last_consesus_info.genesis_millis, - new_genesis_start_round = mp_cfg_override.start_round, - new_genesis_time_millis = mp_cfg_override.genesis_time_millis, + prev_genesis_start_round = last_consesus_info.genesis_info.start_round, + prev_genesis_time_millis = last_consesus_info.genesis_info.millis, + new_genesis_start_round = mp_cfg_override.genesis_info.start_round, + new_genesis_time_millis = mp_cfg_override.genesis_info.millis, "will drop uncommitted internal messages from queue on new genesis", ); self.mq_adapter.clear_session_state()?; diff --git a/collator/src/mempool/impls/std_impl.rs b/collator/src/mempool/impls/std_impl.rs index 98585b147..fd8f8fa35 100644 --- a/collator/src/mempool/impls/std_impl.rs +++ b/collator/src/mempool/impls/std_impl.rs @@ -118,7 +118,7 @@ impl MempoolAdapterStdImpl { let estimated_sync_bottom = last_state_update .top_processed_to_anchor_id .saturating_sub(mempool_config.consensus.reset_rounds()) - .max(mempool_config.genesis.start_round); + .max(mempool_config.genesis_info.start_round); if estimated_sync_bottom >= last_state_update.consensus_info.vset_switch_round { if last_state_update.prev_validator_set.is_some() { tracing::info!(target: tracing_targets::MEMPOOL_ADAPTER, "will not use prev vset"); @@ -138,7 +138,7 @@ impl MempoolAdapterStdImpl { is older than prev vset switch round {}; \ start round {}, top processed to anchor {} in block {}", last_state_update.consensus_info.prev_vset_switch_round, - mempool_config.genesis.start_round, + mempool_config.genesis_info.start_round, last_state_update.top_processed_to_anchor_id, last_state_update.mc_block_id, ) @@ -283,8 +283,8 @@ impl MempoolAdapter for MempoolAdapterStdImpl { ); if let Some(genesis) = (config_guard.builder.get_genesis()).filter(|genesis| { - genesis.start_round >= new_cx.consensus_info.genesis_round - && genesis.time_millis > new_cx.consensus_info.genesis_millis + genesis.start_round >= new_cx.consensus_info.genesis_info.start_round + && genesis.millis > new_cx.consensus_info.genesis_info.millis }) { // Note: assume that global config is applied to mempool adapter // before collator is run in synchronous code, so this method is called later @@ -293,7 +293,7 @@ impl MempoolAdapter for MempoolAdapterStdImpl { // will be saved into next block, so genesis can have values GEQ than in prev block anyhow::ensure!( genesis.start_round >= new_cx.top_processed_to_anchor_id - && genesis.time_millis >= new_cx.mc_block_chain_time, + && genesis.millis >= new_cx.mc_block_chain_time, "new {genesis:?} should be >= \ top processed_to_anchor_id {} and block gen chain_time {}", new_cx.top_processed_to_anchor_id, @@ -327,10 +327,8 @@ impl MempoolAdapter for MempoolAdapterStdImpl { } } } else { - config_guard.builder.set_genesis( - new_cx.consensus_info.genesis_round, - new_cx.consensus_info.genesis_millis, - ); + let genesis_info = new_cx.consensus_info.genesis_info; + config_guard.builder.set_genesis(genesis_info); (config_guard.builder).set_consensus_config(&new_cx.consensus_config); }; diff --git a/consensus/src/dag/producer.rs b/consensus/src/dag/producer.rs index 657cd46e8..b316723a5 100644 --- a/consensus/src/dag/producer.rs +++ b/consensus/src/dag/producer.rs @@ -79,7 +79,7 @@ impl Producer { let (time, anchor_time, payload) = if finished_round.round() == Genesis::id().round { // first produced point is reproducible - let time = UnixTime::from_millis(CachedConfig::get().genesis.time_millis); + let time = UnixTime::from_millis(CachedConfig::get().genesis_info.millis); (time.next(), time, Vec::new()) } else { let (time, anchor_time) = diff --git a/consensus/src/engine/mempool_config.rs b/consensus/src/engine/mempool_config.rs index 9f8a9fbd6..ebec21f9c 100644 --- a/consensus/src/engine/mempool_config.rs +++ b/consensus/src/engine/mempool_config.rs @@ -3,7 +3,7 @@ use std::sync::OnceLock; use anyhow::{anyhow, ensure, Result}; use everscale_crypto::ed25519::{KeyPair, SecretKey}; -use everscale_types::models::ConsensusConfig; +use everscale_types::models::{ConsensusConfig, GenesisInfo}; use serde::{Deserialize, Serialize}; use tycho_network::OverlayId; @@ -30,13 +30,13 @@ impl CachedConfig { } pub fn init(config: &MempoolConfig) -> (Point, OverlayId) { - let genesis_round = align_genesis(config.genesis.start_round); + let genesis_round = align_genesis(config.genesis_info.start_round); // reset types to u128 as it does not match fields in `ConsensusConfig` // and may be changed just to keep them handy, that must not affect hash let mut hasher = blake3::Hasher::new(); hasher.update(&(genesis_round.0 as u128).to_be_bytes()); - hasher.update(&(config.genesis.time_millis as u128).to_be_bytes()); + hasher.update(&(config.genesis_info.millis as u128).to_be_bytes()); hasher.update(&(config.consensus.clock_skew_millis as u128).to_be_bytes()); hasher.update(&(config.consensus.payload_batch_bytes as u128).to_be_bytes()); hasher.update(&(config.consensus.commit_history_rounds as u128).to_be_bytes()); @@ -56,12 +56,12 @@ impl CachedConfig { Default::default(), PointData { author: genesis_keys.public_key.into(), - time: UnixTime::from_millis(config.genesis.time_millis), + time: UnixTime::from_millis(config.genesis_info.millis), includes: Default::default(), witness: Default::default(), anchor_trigger: Link::ToSelf, anchor_proof: Link::ToSelf, - anchor_time: UnixTime::from_millis(config.genesis.time_millis), + anchor_time: UnixTime::from_millis(config.genesis_info.millis), }, ); @@ -79,7 +79,7 @@ impl CachedConfig { #[derive(Clone, Debug, PartialEq, Eq)] pub struct MempoolConfig { - pub genesis: GenesisData, + pub genesis_info: GenesisInfo, pub consensus: ConsensusConfig, pub node: MempoolNodeConfig, /// Estimated hard limit on serialized point size @@ -88,7 +88,7 @@ pub struct MempoolConfig { #[derive(Default, Debug)] pub struct MempoolConfigBuilder { - genesis_data: Option, + genesis_info: Option, consensus_config: Option, node_config: Option, } @@ -102,24 +102,21 @@ impl MempoolConfigBuilder { self.consensus_config = Some(consensus_config.clone()); } - pub fn set_genesis(&mut self, start_round: u32, time_millis: u64) { - self.genesis_data = Some(GenesisData { - start_round, - time_millis, - }); + pub fn set_genesis(&mut self, info: GenesisInfo) { + self.genesis_info = Some(info); } pub fn get_consensus_config(&self) -> Option<&ConsensusConfig> { self.consensus_config.as_ref() } - pub fn get_genesis(&self) -> Option { - self.genesis_data + pub fn get_genesis(&self) -> Option { + self.genesis_info } pub fn build(&self) -> Result { let genesis_data = *self - .genesis_data + .genesis_info .as_ref() .ok_or(anyhow!("mempool genesis data for config is not known"))?; let consensus_config = self @@ -146,7 +143,7 @@ impl MempoolConfigBuilder { ); Ok(MempoolConfig { - genesis: genesis_data, + genesis_info: genesis_data, consensus: consensus_config, node: node_config, point_max_bytes, @@ -154,15 +151,6 @@ impl MempoolConfigBuilder { } } -// Note: never derive Default for Genesis data -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct GenesisData { - /// will be aligned to become genesis round (will not be lesser, may become a bit greater) - pub start_round: u32, - /// value will be copied to genesis point without changes - pub time_millis: u64, -} - #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct MempoolNodeConfig { /// `true` to truncate hashes, signatures and use non-standard format for large structs diff --git a/consensus/src/models/point/body.rs b/consensus/src/models/point/body.rs index 5b5a6c356..9d4a4190d 100644 --- a/consensus/src/models/point/body.rs +++ b/consensus/src/models/point/body.rs @@ -101,7 +101,7 @@ impl PointBody { && self.data.anchor_link_id(AnchorStageRole::Proof, genesis_round_next) .map_or(false, |anchor| anchor == *Genesis::id()) && self.data.time == self.data.anchor_time.next() - && self.data.anchor_time.millis() == CachedConfig::get().genesis.time_millis + && self.data.anchor_time.millis() == CachedConfig::get().genesis_info.millis )) // leader must maintain its chain of proofs, // while others must link to previous points (checked at the end of this method); diff --git a/consensus/src/test_utils/bootstrap.rs b/consensus/src/test_utils/bootstrap.rs index 1dbcdcc42..e562cce5a 100644 --- a/consensus/src/test_utils/bootstrap.rs +++ b/consensus/src/test_utils/bootstrap.rs @@ -1,7 +1,7 @@ use std::num::NonZeroU16; use everscale_crypto::ed25519::{KeyPair, PublicKey, SecretKey}; -use everscale_types::models::ConsensusConfig; +use everscale_types::models::{ConsensusConfig, GenesisInfo}; use tycho_network::{ Address, DhtClient, DhtConfig, DhtService, Network, NetworkConfig, OverlayConfig, OverlayService, PeerId, PeerInfo, PeerResolver, PeerResolverConfig, Router, ToSocket, @@ -32,7 +32,7 @@ pub fn default_test_config() -> MempoolConfig { }; let mut builder = MempoolConfigBuilder::default(); - builder.set_genesis(0, 0); + builder.set_genesis(GenesisInfo::default()); builder.set_consensus_config(&consensus_config); builder.set_node_config(&node_config); diff --git a/core/src/global_config.rs b/core/src/global_config.rs index 2294c72ed..81ad3f19d 100644 --- a/core/src/global_config.rs +++ b/core/src/global_config.rs @@ -2,7 +2,7 @@ use std::path::Path; use anyhow::Result; use everscale_types::cell::HashBytes; -use everscale_types::models::{BlockId, ConsensusConfig, ShardIdent}; +use everscale_types::models::{BlockId, ConsensusConfig, GenesisInfo, ShardIdent}; use serde::{Deserialize, Serialize}; use tycho_network::{OverlayId, PeerInfo}; @@ -60,10 +60,11 @@ impl ZerostateId { /// Also, this genesis must have round not less than in last applied mc block. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct MempoolGlobalConfig { - /// must be set to the `processed_to_anchor_id` from last signed master chain block - /// actual genesis round may be greater (or still equal) after alignment - pub start_round: u32, - pub genesis_time_millis: u64, + /// start round must be set to the `processed_to_anchor_id` from last applied master chain block + /// actual genesis round may be greater (or still equal) after alignment; + /// millis must be set not less than last applied mc block time, or better use actual time + #[serde(flatten)] + pub genesis_info: GenesisInfo, #[serde(flatten)] pub consensus_config: Option, }