diff --git a/builder/src/bin/permissioned-builder.rs b/builder/src/bin/permissioned-builder.rs index 2532ad0b93..4905c5748f 100644 --- a/builder/src/bin/permissioned-builder.rs +++ b/builder/src/bin/permissioned-builder.rs @@ -5,19 +5,25 @@ use std::{ use anyhow::{bail, Context}; use builder::permissioned::init_node; use clap::Parser; -use espresso_types::{eth_signature_key::EthKeyPair, parse_duration}; +use espresso_types::{ + eth_signature_key::EthKeyPair, parse_duration, FeeVersion, MarketplaceVersion, + SequencerVersions, V0_1, +}; use ethers::types::Address; use hotshot_types::{ data::ViewNumber, light_client::StateSignKey, signature_key::BLSPrivKey, - traits::{metrics::NoMetrics, node_implementation::ConsensusTime}, + traits::{ + metrics::NoMetrics, + node_implementation::{ConsensusTime, Versions}, + }, }; use libp2p::Multiaddr; use sequencer::{persistence::no_storage::NoStorage, Genesis, L1Params, NetworkParams}; use sequencer_utils::logging; use url::Url; -use vbs::version::{StaticVersion, StaticVersionType}; +use vbs::version::StaticVersionType; #[derive(Parser, Clone, Debug)] pub struct PermissionedBuilderOptions { @@ -214,11 +220,12 @@ impl PermissionedBuilderOptions { } } } -#[async_std::main] -async fn main() -> anyhow::Result<()> { - let opt = PermissionedBuilderOptions::parse(); - opt.logging.init(); +async fn run( + genesis: Genesis, + opt: PermissionedBuilderOptions, + versions: V, +) -> anyhow::Result<()> { let (private_staking_key, private_state_key) = opt.private_keys()?; let l1_params = L1Params { @@ -259,8 +266,6 @@ async fn main() -> anyhow::Result<()> { catchup_backoff: Default::default(), }; - let sequencer_version = StaticVersion::<0, 1>::instance(); - let builder_server_url: Url = format!("http://0.0.0.0:{}", opt.port).parse().unwrap(); let bootstrapped_view = ViewNumber::new(opt.view_number); @@ -273,7 +278,7 @@ async fn main() -> anyhow::Result<()> { // it will internally spawn the builder web server let ctx = init_node( - Genesis::from_file(&opt.genesis_file)?, + genesis, network_params, &NoMetrics, l1_params, @@ -282,7 +287,7 @@ async fn main() -> anyhow::Result<()> { bootstrapped_view, opt.tx_channel_capacity, opt.event_channel_capacity, - sequencer_version, + versions, NoStorage, max_api_response_timeout_duration, buffer_view_num_count, @@ -296,3 +301,32 @@ async fn main() -> anyhow::Result<()> { Ok(()) } + +#[async_std::main] +async fn main() -> anyhow::Result<()> { + let opt = PermissionedBuilderOptions::parse(); + opt.logging.init(); + + let genesis = Genesis::from_file(&opt.genesis_file)?; + tracing::info!(?genesis, "genesis"); + + let base = genesis.base_version; + let upgrade = genesis.upgrade_version; + + match (base, upgrade) { + (V0_1::VERSION, FeeVersion::VERSION) => { + run(genesis, opt, SequencerVersions::::new()).await + } + (FeeVersion::VERSION, MarketplaceVersion::VERSION) => { + run( + genesis, + opt, + SequencerVersions::::new(), + ) + .await + } + _ => panic!( + "Invalid base ({base}) and upgrade ({upgrade}) versions specified in the toml file." + ), + } +} diff --git a/builder/src/bin/permissionless-builder.rs b/builder/src/bin/permissionless-builder.rs index f1e3944718..d1c55d0a39 100644 --- a/builder/src/bin/permissionless-builder.rs +++ b/builder/src/bin/permissionless-builder.rs @@ -2,13 +2,19 @@ use std::{num::NonZeroUsize, path::PathBuf, time::Duration}; use builder::non_permissioned::{build_instance_state, BuilderConfig}; use clap::Parser; -use espresso_types::{eth_signature_key::EthKeyPair, parse_duration}; +use espresso_types::{ + eth_signature_key::EthKeyPair, parse_duration, FeeVersion, MarketplaceVersion, + SequencerVersions, V0_1, +}; use hotshot::traits::ValidatedState; -use hotshot_types::{data::ViewNumber, traits::node_implementation::ConsensusTime}; +use hotshot_types::{ + data::ViewNumber, + traits::node_implementation::{ConsensusTime, Versions}, +}; use sequencer::{Genesis, L1Params}; use sequencer_utils::logging; use url::Url; -use vbs::version::{StaticVersion, StaticVersionType}; +use vbs::version::StaticVersionType; #[derive(Parser, Clone, Debug)] struct NonPermissionedBuilderOptions { @@ -92,7 +98,34 @@ async fn main() -> anyhow::Result<()> { opt.logging.init(); let genesis = Genesis::from_file(&opt.genesis_file)?; + tracing::info!(?genesis, "genesis"); + + let base = genesis.base_version; + let upgrade = genesis.upgrade_version; + + match (base, upgrade) { + (V0_1::VERSION, FeeVersion::VERSION) => { + run(genesis, opt, SequencerVersions::::new()).await + } + (FeeVersion::VERSION, MarketplaceVersion::VERSION) => { + run( + genesis, + opt, + SequencerVersions::::new(), + ) + .await + } + _ => panic!( + "Invalid base ({base}) and upgrade ({upgrade}) versions specified in the toml file." + ), + } +} +async fn run( + genesis: Genesis, + opt: NonPermissionedBuilderOptions, + versions: V, +) -> anyhow::Result<()> { let l1_params = L1Params { url: opt.l1_provider_url, events_max_block_range: 10000, @@ -103,13 +136,8 @@ async fn main() -> anyhow::Result<()> { let builder_server_url: Url = format!("http://0.0.0.0:{}", opt.port).parse().unwrap(); - let instance_state = build_instance_state( - genesis.chain_config, - l1_params, - opt.state_peers, - StaticVersion::<0, 1>::instance(), - ) - .unwrap(); + let instance_state = + build_instance_state::(genesis.chain_config, l1_params, opt.state_peers).unwrap(); let base_fee = genesis.max_base_fee(); @@ -136,6 +164,7 @@ async fn main() -> anyhow::Result<()> { buffer_view_num_count, txn_timeout_duration, base_fee, + versions, ) .await?; diff --git a/builder/src/lib.rs b/builder/src/lib.rs index 810928d2ad..85e44e6b5f 100755 --- a/builder/src/lib.rs +++ b/builder/src/lib.rs @@ -65,7 +65,7 @@ use sequencer::{ context::{Consensus, SequencerContext}, network, state_signature::{static_stake_table_commitment, StakeTableCommitmentType, StateSigner}, - L1Params, NetworkParams, Node, + L1Params, NetworkParams, Node, SequencerApiVersion, }; use tide_disco::{app, method::ReadState, App, Url}; use vbs::version::{StaticVersion, StaticVersionType}; @@ -98,7 +98,7 @@ pub fn run_builder_api_service(url: Url, source: ProxyGlobalState) { app.register_module("txn_submit", private_mempool_api) .expect("Failed to register the private mempool API"); - async_spawn(app.serve(url, StaticVersion::<0, 1>::instance())); + async_spawn(app.serve(url, SequencerApiVersion::instance())); } #[cfg(test)] @@ -167,13 +167,13 @@ pub mod testing { block_contents::{vid_commitment, BlockHeader, GENESIS_VID_NUM_STORAGE_NODES}, metrics::NoMetrics, network::Topic, - node_implementation::ConsensusTime, + node_implementation::{ConsensusTime, Versions}, signature_key::BuilderSignatureKey as _, }, ExecutionType, HotShotConfig, PeerConfig, ValidatorConfig, }; use portpicker::pick_unused_port; - use sequencer::{state_signature::StateSignatureMemStorage, testing::TestConfig}; + use sequencer::{state_signature::StateSignatureMemStorage, SequencerApiVersion}; use serde::{Deserialize, Serialize}; use surf_disco::Client; use vbs::version::StaticVersion; @@ -345,11 +345,14 @@ pub mod testing { } } - pub async fn init_nodes( + pub async fn init_nodes( &self, - bind_version: Ver, + bind_version: V, options: impl PersistenceOptions, - ) -> Vec<(Arc>, Option>)> { + ) -> Vec<( + Arc>, + Option>, + )> { let num_staked_nodes = self.num_staked_nodes(); let mut is_staked = false; let stake_table_commit = static_stake_table_commitment( @@ -379,15 +382,18 @@ pub mod testing { .await } - pub async fn init_node( + pub async fn init_node( &self, i: usize, is_staked: bool, stake_table_commit: StakeTableCommitmentType, metrics: &dyn Metrics, - bind_version: Ver, + bind_version: V, persistence: P, - ) -> (Consensus, StateSigner) { + ) -> ( + Consensus, + StateSigner, + ) { let mut config = self.config.clone(); let num_staked_nodes = self.num_staked_nodes(); @@ -410,8 +416,8 @@ pub mod testing { ChainConfig::default(), L1Client::new(self.anvil.endpoint().parse().unwrap(), 1), MockStateCatchup::default(), + V::Base::VERSION, ) - .with_current_version(Ver::VERSION) .with_genesis(ValidatedState::default()); tracing::info!("Before init hotshot"); @@ -463,14 +469,14 @@ pub mod testing { app.register_module("hotshot-events", hotshot_events_api) .expect("Failed to register hotshot events API"); - async_spawn(app.serve(url, StaticVersion::<0, 1>::instance())); + async_spawn(app.serve(url, SequencerApiVersion::instance())); } // enable hotshot event streaming - pub fn enable_hotshot_node_event_streaming( + pub fn enable_hotshot_node_event_streaming( hotshot_events_api_url: Url, known_nodes_with_stake: Vec>, num_non_staking_nodes: usize, - hotshot_context_handle: Arc>, + hotshot_context_handle: Arc>, ) { // create a event streamer let events_streamer = Arc::new(RwLock::new(EventsStreamer::new( @@ -538,10 +544,11 @@ pub mod testing { impl NonPermissionedBuilderTestConfig { pub const SUBSCRIBED_DA_NODE_ID: usize = 5; - pub async fn init_non_permissioned_builder( + pub async fn init_non_permissioned_builder( hotshot_events_streaming_api_url: Url, hotshot_builder_api_url: Url, num_nodes: usize, + versions: V, ) -> Self { // generate builder keys let seed = [201_u8; 32]; @@ -562,7 +569,7 @@ pub mod testing { tx_channel_capacity, event_channel_capacity, node_count, - NodeState::default(), + NodeState::default().with_current_version(V::Base::VERSION), ValidatedState::default(), hotshot_events_streaming_api_url, hotshot_builder_api_url, @@ -570,6 +577,7 @@ pub mod testing { 15, Duration::from_millis(500), ChainConfig::default().base_fee, + versions, ) .await .unwrap(); @@ -581,25 +589,20 @@ pub mod testing { } } - pub struct PermissionedBuilderTestConfig< - P: SequencerPersistence, - Ver: StaticVersionType + 'static, - > { - pub builder_context: BuilderContext, + pub struct PermissionedBuilderTestConfig { + pub builder_context: BuilderContext, pub fee_account: FeeAccount, } - impl - PermissionedBuilderTestConfig - { + impl PermissionedBuilderTestConfig { pub async fn init_permissioned_builder( - hotshot_handle: Arc>, + hotshot_handle: Arc>, node_id: u64, - state_signer: Arc>, + state_signer: Arc>, hotshot_builder_api_url: Url, ) -> Self { // setup the instance state - let node_state = NodeState::default(); + let node_state = NodeState::default().with_current_version(V::Base::VERSION); // generate builder keys let seed = [201_u8; 32]; @@ -784,7 +787,7 @@ pub mod testing { mod test { use async_std::stream::IntoStream; use clap::builder; - use espresso_types::{Header, NodeState, Payload, ValidatedState}; + use espresso_types::{Header, MockSequencerVersions, NodeState, Payload, ValidatedState}; use ethers::providers::Quorum; use futures::StreamExt; use hotshot::types::EventType::Decide; @@ -811,13 +814,13 @@ mod test { async fn test_non_voting_hotshot_node() { setup_test(); - let ver = StaticVersion::<0, 1>::instance(); - let success_height = 5; // Assign `config` so it isn't dropped early. let config = HotShotTestConfig::default(); tracing::debug!("Done with hotshot test config"); - let handles = config.init_nodes(ver, no_storage::Options).await; + let handles = config + .init_nodes(MockSequencerVersions::new(), no_storage::Options) + .await; tracing::debug!("Done with init nodes"); let total_nodes = HotShotTestConfig::total_nodes(); diff --git a/builder/src/non_permissioned.rs b/builder/src/non_permissioned.rs index 15d77c4587..1f6b0bff47 100644 --- a/builder/src/non_permissioned.rs +++ b/builder/src/non_permissioned.rs @@ -10,8 +10,8 @@ use async_compatibility_layer::{ }; use async_std::sync::{Arc, RwLock}; use espresso_types::{ - eth_signature_key::EthKeyPair, v0_3::ChainConfig, FeeAmount, L1Client, NodeState, Payload, - SeqTypes, SequencerVersions, ValidatedState, + eth_signature_key::EthKeyPair, v0_3::ChainConfig, FeeAmount, L1Client, MockSequencerVersions, + NodeState, Payload, SeqTypes, SequencerVersions, ValidatedState, }; use ethers::{ core::k256::ecdsa::SigningKey, @@ -39,16 +39,16 @@ use hotshot_types::{ data::{fake_commitment, Leaf, ViewNumber}, traits::{ block_contents::{vid_commitment, GENESIS_VID_NUM_STORAGE_NODES}, - node_implementation::{ConsensusTime, NodeType}, + node_implementation::{ConsensusTime, NodeType, Versions}, EncodeBytes, }, utils::BuilderCommitment, }; -use sequencer::{catchup::StatePeers, L1Params, NetworkParams}; +use sequencer::{catchup::StatePeers, L1Params, NetworkParams, SequencerApiVersion}; use surf::http::headers::ACCEPT; use surf_disco::Client; use tide_disco::{app, method::ReadState, App, Url}; -use vbs::version::StaticVersionType; +use vbs::version::{StaticVersionType, Version}; use crate::run_builder_api_service; @@ -59,28 +59,28 @@ pub struct BuilderConfig { pub hotshot_builder_apis_url: Url, } -pub fn build_instance_state( +pub fn build_instance_state( chain_config: ChainConfig, l1_params: L1Params, state_peers: Vec, - _: Ver, ) -> anyhow::Result { let l1_client = L1Client::new(l1_params.url, l1_params.events_max_block_range); let instance_state = NodeState::new( u64::MAX, // dummy node ID, only used for debugging chain_config, l1_client, - Arc::new(StatePeers::::from_urls( + Arc::new(StatePeers::::from_urls( state_peers, Default::default(), )), + V::Base::VERSION, ); Ok(instance_state) } impl BuilderConfig { #[allow(clippy::too_many_arguments)] - pub async fn init( + pub async fn init( builder_key_pair: EthKeyPair, bootstrapped_view: ViewNumber, tx_channel_capacity: NonZeroUsize, @@ -94,6 +94,7 @@ impl BuilderConfig { buffered_view_num_count: usize, maximize_txns_count_timeout_duration: Duration, base_fee: FeeAmount, + _: V, ) -> anyhow::Result { tracing::info!( address = %builder_key_pair.fee_account(), @@ -196,7 +197,7 @@ impl BuilderConfig { let global_state_clone = global_state.clone(); tracing::info!("Running permissionless builder against hotshot events API at {events_url}",); async_spawn(async move { - let res = run_non_permissioned_standalone_builder_service::<_, SequencerVersions>( + let res = run_non_permissioned_standalone_builder_service::<_, V>( da_sender, qc_sender, decide_sender, @@ -229,7 +230,7 @@ mod test { }; use async_lock::RwLock; use async_std::{stream::StreamExt, task}; - use espresso_types::{BaseVersion, Event, FeeAccount, NamespaceId, Transaction}; + use espresso_types::{Event, FeeAccount, NamespaceId, Transaction}; use ethers::utils::Anvil; use futures::Stream; use hotshot::types::EventType; @@ -312,18 +313,19 @@ mod test { ) .network_config(network_config) .build(); - let network = TestNetwork::new(config, BaseVersion::instance()).await; + let network = TestNetwork::new(config, MockSequencerVersions::new()).await; let builder_config = NonPermissionedBuilderTestConfig::init_non_permissioned_builder( event_service_url.clone(), builder_api_url.clone(), network.cfg.num_nodes(), + MockSequencerVersions::new(), ) .await; let events_service_client = Client::< hotshot_events_service::events::Error, - StaticVersion<0, 1>, + SequencerApiVersion, >::new(event_service_url.clone()); events_service_client.connect(None).await; diff --git a/builder/src/permissioned.rs b/builder/src/permissioned.rs index 76048a2b7f..62bb7544c6 100644 --- a/builder/src/permissioned.rs +++ b/builder/src/permissioned.rs @@ -88,7 +88,7 @@ use hotshot_types::{ election::Membership, metrics::Metrics, network::{ConnectedNetwork, Topic}, - node_implementation::{ConsensusTime, NodeType}, + node_implementation::{ConsensusTime, NodeType, Versions}, EncodeBytes, }, utils::BuilderCommitment, @@ -100,10 +100,9 @@ use sequencer::{ catchup::StatePeers, context::{Consensus, SequencerContext}, genesis::L1Finalized, - network, - network::libp2p::split_off_peer_id, + network::{self, libp2p::split_off_peer_id}, state_signature::{static_stake_table_commitment, StakeTableCommitmentType, StateSigner}, - Genesis, L1Params, NetworkParams, Node, + Genesis, L1Params, NetworkParams, Node, SequencerApiVersion, }; use surf_disco::Client; use tide_disco::{app, method::ReadState, App, Url}; @@ -111,19 +110,15 @@ use vbs::version::StaticVersionType; use crate::run_builder_api_service; -pub struct BuilderContext< - N: ConnectedNetwork, - P: SequencerPersistence, - Ver: StaticVersionType + 'static, -> { +pub struct BuilderContext, P: SequencerPersistence, V: Versions> { /// The consensus handle - pub hotshot_handle: Arc>, + pub hotshot_handle: Arc>, /// Index of this sequencer node pub node_index: u64, /// Context for generating state signatures. - pub state_signer: Arc>, + pub state_signer: Arc>, /// An orchestrator to wait for before starting consensus. pub wait_for_orchestrator: Option>, @@ -136,7 +131,7 @@ pub struct BuilderContext< } #[allow(clippy::too_many_arguments)] -pub async fn init_node( +pub async fn init_node( genesis: Genesis, network_params: NetworkParams, metrics: &dyn Metrics, @@ -146,13 +141,13 @@ pub async fn init_node anyhow::Result> { +) -> anyhow::Result> { // Orchestrator client let validator_args = ValidatorArgs { url: network_params.orchestrator_url, @@ -275,13 +270,13 @@ pub async fn init_node::from_urls( + peers: Arc::new(StatePeers::::from_urls( network_params.state_peers, network_params.catchup_backoff, )), node_id: node_index, upgrades: Default::default(), - current_version: Ver::VERSION, + current_version: V::Base::VERSION, }; let stake_table_commit = @@ -323,11 +318,7 @@ pub async fn init_node, - P: SequencerPersistence, - Ver: StaticVersionType + 'static, ->( +pub async fn init_hotshot, P: SequencerPersistence, V: Versions>( config: HotShotConfig, stake_table_entries_for_non_voting_nodes: Option< Vec>, @@ -338,9 +329,9 @@ pub async fn init_hotshot< node_id: u64, state_relay_server: Option, stake_table_commit: StakeTableCommitmentType, - _: Ver, + _: V, persistence: P, -) -> (Consensus, StateSigner) { +) -> (Consensus, StateSigner) { let combined_known_nodes_with_stake = match stake_table_entries_for_non_voting_nodes { Some(stake_table_entries) => { let combined_entries = config @@ -399,7 +390,7 @@ pub async fn init_hotshot< tracing::debug!("Hotshot handle initialized"); - let mut state_signer: StateSigner = StateSigner::new(state_key_pair, stake_table_commit); + let mut state_signer = StateSigner::new(state_key_pair, stake_table_commit); if let Some(url) = state_relay_server { state_signer = state_signer.with_relay_server(url); @@ -407,14 +398,12 @@ pub async fn init_hotshot< (hotshot_handle, state_signer) } -impl, P: SequencerPersistence, Ver: StaticVersionType + 'static> - BuilderContext -{ +impl, P: SequencerPersistence, V: Versions> BuilderContext { /// Constructor #[allow(clippy::too_many_arguments)] pub async fn init( - hotshot_handle: Arc>, - state_signer: Arc>, + hotshot_handle: Arc>, + state_signer: Arc>, node_index: u64, eth_key_pair: EthKeyPair, bootstrapped_view: ViewNumber, @@ -561,8 +550,7 @@ mod test { use async_lock::RwLock; use async_std::task; - use espresso_types::{BaseVersion, FeeAccount, NamespaceId, Transaction}; - use ethers::utils::Anvil; + use espresso_types::{FeeAccount, MockSequencerVersions, NamespaceId, Transaction}; use hotshot_builder_api::v0_1::{ block_info::{AvailableBlockData, AvailableBlockHeaderInput, AvailableBlockInfo}, builder::BuildError, @@ -615,13 +603,13 @@ mod test { // async fn test_permissioned_builder() { // setup_test(); - // let query_port = pick_unused_port().expect("No ports free"); + // Hotshot Test Config + // let hotshot_config = HotShotTestConfig::default(); - // let event_port = pick_unused_port().expect("No ports free"); - // let event_service_url: Url = format!("http://localhost:{event_port}").parse().unwrap(); - - // let builder_port = pick_unused_port().expect("No ports free"); - // let builder_api_url: Url = format!("http://localhost:{builder_port}").parse().unwrap(); + // // Get the handle for all the nodes, including both the non-builder and builder nodes + // let mut handles = hotshot_config + // .init_nodes(MockSequencerVersions::new(), no_storage::Options) + // .await; // // Set up and start the network // let anvil = Anvil::new().spawn(); diff --git a/data/genesis/demo.toml b/data/genesis/demo.toml index 00a6b60ef5..91a23484bc 100644 --- a/data/genesis/demo.toml +++ b/data/genesis/demo.toml @@ -1,3 +1,6 @@ +base_version = "0.1" +upgrade_version = "0.2" + [stake_table] capacity = 10 diff --git a/data/messages.bin b/data/v1/messages.bin similarity index 100% rename from data/messages.bin rename to data/v1/messages.bin diff --git a/data/messages.json b/data/v1/messages.json similarity index 100% rename from data/messages.json rename to data/v1/messages.json diff --git a/data/v2/messages.bin b/data/v2/messages.bin new file mode 100644 index 0000000000..64ba1cde6d Binary files /dev/null and b/data/v2/messages.bin differ diff --git a/data/v2/messages.json b/data/v2/messages.json new file mode 100644 index 0000000000..e79962a852 --- /dev/null +++ b/data/v2/messages.json @@ -0,0 +1,435 @@ +[ + { + "kind": { + "Consensus": { + "General": { + "Proposal": { + "_pd": null, + "data": { + "block_header": { + "fields": { + "block_merkle_tree_root": "MERKLE_COMM~AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAQA", + "builder_commitment": "BUILDER_COMMITMENT~tEvs0rxqOiMCvfe2R0omNNaphSlUiEDrb2q0IZpRcgA_", + "builder_signature": null, + "chain_config": { + "chain_config": { + "Left": { + "base_fee": "0", + "chain_id": "35353", + "fee_contract": null, + "fee_recipient": "0x0000000000000000000000000000000000000000", + "max_block_size": "30720" + } + } + }, + "fee_info": { + "account": "0x0000000000000000000000000000000000000000", + "amount": "0" + }, + "fee_merkle_tree_root": "MERKLE_COMM~AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAKA", + "height": 0, + "l1_finalized": null, + "l1_head": 0, + "ns_table": { + "bytes": "AAAAAA==" + }, + "payload_commitment": "HASH~AazstQer_ho1SqgGT0r10_Gs0BnjfbPBHJdSO3HHbp29", + "timestamp": 0 + }, + "version": { + "Version": { + "major": 0, + "minor": 2 + } + } + }, + "justify_qc": { + "_pd": null, + "data": { + "leaf_commit": "COMMIT~eaBGKF8-lw-t211wxLq7tcXEEqacbvDVcFFR9aCddO3G" + }, + "signatures": null, + "view_number": 0, + "vote_commitment": "COMMIT~0-ZxNgMSsUEPeGDdq5-TZE8PDsYwgI4O2fVGMKooP87D" + }, + "proposal_certificate": { + "Timeout": { + "_pd": null, + "data": { + "view": 0 + }, + "signatures": null, + "view_number": 0, + "vote_commitment": "COMMIT~TZG1F34lxU6Ny9aKQMkjZAxjW9zotdwW75EHEGbyALOi" + } + }, + "upgrade_certificate": { + "_pd": null, + "data": { + "decide_by": 0, + "new_version": { + "major": 1, + "minor": 0 + }, + "new_version_first_view": 0, + "new_version_hash": [], + "old_version": { + "major": 0, + "minor": 1 + }, + "old_version_last_view": 0 + }, + "signatures": null, + "view_number": 0, + "vote_commitment": "COMMIT~roiQgLLeI4uYqYxjz-0jPwtLyNhSlnfriPEVZ-_4RUrW" + }, + "view_number": 0 + }, + "signature": "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "Vote": { + "data": { + "leaf_commit": "COMMIT~eaBGKF8-lw-t211wxLq7tcXEEqacbvDVcFFR9aCddO3G" + }, + "signature": [ + "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U", + "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + ], + "view_number": 0 + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "ViewSyncPreCommitVote": { + "data": { + "relay": 0, + "round": 0 + }, + "signature": [ + "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U", + "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + ], + "view_number": 0 + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "ViewSyncCommitVote": { + "data": { + "relay": 0, + "round": 0 + }, + "signature": [ + "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U", + "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + ], + "view_number": 0 + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "ViewSyncFinalizeVote": { + "data": { + "relay": 0, + "round": 0 + }, + "signature": [ + "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U", + "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + ], + "view_number": 0 + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "ViewSyncPreCommitCertificate": { + "_pd": null, + "data": { + "relay": 0, + "round": 0 + }, + "signatures": null, + "view_number": 0, + "vote_commitment": "COMMIT~OQecZxfFpuEuPJgkpsQoglnqY0fm6Qi1PUarYCgiFQ0T" + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "ViewSyncCommitCertificate": { + "_pd": null, + "data": { + "relay": 0, + "round": 0 + }, + "signatures": null, + "view_number": 0, + "vote_commitment": "COMMIT~POgBCaDjtUV3Il5-FXVr5KN2KzYSgipfKX6Ci0-nxduO" + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "ViewSyncFinalizeCertificate": { + "_pd": null, + "data": { + "relay": 0, + "round": 0 + }, + "signatures": null, + "view_number": 0, + "vote_commitment": "COMMIT~s5i9wmQWH7VU90CUiEWRdAG19LI1iXydSMxp9gZ7kHco" + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "TimeoutVote": { + "data": { + "view": 0 + }, + "signature": [ + "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U", + "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + ], + "view_number": 0 + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "UpgradeProposal": { + "_pd": null, + "data": { + "upgrade_proposal": { + "decide_by": 0, + "new_version": { + "major": 1, + "minor": 0 + }, + "new_version_first_view": 0, + "new_version_hash": [], + "old_version": { + "major": 0, + "minor": 1 + }, + "old_version_last_view": 0 + }, + "view_number": 0 + }, + "signature": "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "UpgradeVote": { + "data": { + "decide_by": 0, + "new_version": { + "major": 1, + "minor": 0 + }, + "new_version_first_view": 0, + "new_version_hash": [], + "old_version": { + "major": 0, + "minor": 1 + }, + "old_version_last_view": 0 + }, + "signature": [ + "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U", + "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + ], + "view_number": 0 + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "Da": { + "DaProposal": { + "_pd": null, + "data": { + "encoded_transactions": [ + 1, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 1, + 2, + 3 + ], + "metadata": { + "bytes": "AQAAAAEAAAALAAAA" + }, + "view_number": 0 + }, + "signature": "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "Da": { + "DaVote": { + "data": { + "payload_commit": "HASH~AazstQer_ho1SqgGT0r10_Gs0BnjfbPBHJdSO3HHbp29" + }, + "signature": [ + "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U", + "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + ], + "view_number": 0 + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "Da": { + "DaCertificate": { + "_pd": null, + "data": { + "payload_commit": "HASH~AazstQer_ho1SqgGT0r10_Gs0BnjfbPBHJdSO3HHbp29" + }, + "signatures": null, + "view_number": 0, + "vote_commitment": "COMMIT~5E3F3rC4E9DBhMBqOTmjZ9tjX4VFaV5gqrZJl0y6V05D" + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "Da": { + "VidDisperseMsg": { + "_pd": null, + "data": { + "common": { + "all_evals_digest": "FIELD~rF4TMFZMXJCieDeov31aNuDG5nDGR-iQdteEgBjXkErn", + "multiplicity": 1, + "num_storage_nodes": 1, + "payload_byte_len": 11, + "poly_commits": "FIELD~AQAAAAAAAAD2xsICwO-z0CXx_ucl0FV1j-zJ3tgPO-OL8gYLvXkIkNE" + }, + "payload_commitment": "HASH~Z03vXeC1EEaBGf5iacsBEWYiA7PHi3K6uS9gVpmlUx3t", + "recipient_key": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U", + "share": { + "aggregate_proofs": "FIELD~AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQGY", + "evals": "FIELD~AQAAAAAAAAABAAAAAwAAAAECAwAAAAAAAAAAAAAAAAAAAAAAAAAAAMk", + "evals_proof": { + "pos": "FIELD~AAAAAAAAAAD7", + "proof": [ + { + "Leaf": { + "elem": "FIELD~AQAAAAAAAAABAAAAAwAAAAECAwAAAAAAAAAAAAAAAAAAAAAAAAAAAMk", + "pos": "FIELD~AAAAAAAAAAD7", + "value": "FIELD~rF4TMFZMXJCieDeov31aNuDG5nDGR-iQdteEgBjXkErn" + } + } + ] + }, + "index": 0 + }, + "view_number": 0 + }, + "signature": "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Data": { + "SubmitTransaction": [ + { + "namespace": 1, + "payload": "AQID" + }, + 0 + ] + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + } +] \ No newline at end of file diff --git a/data/v3/messages.bin b/data/v3/messages.bin new file mode 100644 index 0000000000..d257b38fa7 Binary files /dev/null and b/data/v3/messages.bin differ diff --git a/data/v3/messages.json b/data/v3/messages.json new file mode 100644 index 0000000000..cc1d8d33ac --- /dev/null +++ b/data/v3/messages.json @@ -0,0 +1,443 @@ +[ + { + "kind": { + "Consensus": { + "General": { + "Proposal": { + "_pd": null, + "data": { + "block_header": { + "fields": { + "auction_results": { + "reserve_bids": [], + "view_number": 0, + "winning_bids": [] + }, + "block_merkle_tree_root": "MERKLE_COMM~AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAQA", + "builder_commitment": "BUILDER_COMMITMENT~tEvs0rxqOiMCvfe2R0omNNaphSlUiEDrb2q0IZpRcgA_", + "builder_signature": [], + "chain_config": { + "chain_config": { + "Left": { + "base_fee": "0", + "bid_recipient": null, + "chain_id": "35353", + "fee_contract": null, + "fee_recipient": "0x0000000000000000000000000000000000000000", + "max_block_size": "30720" + } + } + }, + "fee_info": [ + { + "account": "0x0000000000000000000000000000000000000000", + "amount": "0" + } + ], + "fee_merkle_tree_root": "MERKLE_COMM~AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAKA", + "height": 0, + "l1_finalized": null, + "l1_head": 0, + "ns_table": { + "bytes": "AAAAAA==" + }, + "payload_commitment": "HASH~AazstQer_ho1SqgGT0r10_Gs0BnjfbPBHJdSO3HHbp29", + "timestamp": 0 + }, + "version": { + "Version": { + "major": 0, + "minor": 3 + } + } + }, + "justify_qc": { + "_pd": null, + "data": { + "leaf_commit": "COMMIT~eaBGKF8-lw-t211wxLq7tcXEEqacbvDVcFFR9aCddO3G" + }, + "signatures": null, + "view_number": 0, + "vote_commitment": "COMMIT~0-ZxNgMSsUEPeGDdq5-TZE8PDsYwgI4O2fVGMKooP87D" + }, + "proposal_certificate": { + "Timeout": { + "_pd": null, + "data": { + "view": 0 + }, + "signatures": null, + "view_number": 0, + "vote_commitment": "COMMIT~TZG1F34lxU6Ny9aKQMkjZAxjW9zotdwW75EHEGbyALOi" + } + }, + "upgrade_certificate": { + "_pd": null, + "data": { + "decide_by": 0, + "new_version": { + "major": 1, + "minor": 0 + }, + "new_version_first_view": 0, + "new_version_hash": [], + "old_version": { + "major": 0, + "minor": 1 + }, + "old_version_last_view": 0 + }, + "signatures": null, + "view_number": 0, + "vote_commitment": "COMMIT~roiQgLLeI4uYqYxjz-0jPwtLyNhSlnfriPEVZ-_4RUrW" + }, + "view_number": 0 + }, + "signature": "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "Vote": { + "data": { + "leaf_commit": "COMMIT~eaBGKF8-lw-t211wxLq7tcXEEqacbvDVcFFR9aCddO3G" + }, + "signature": [ + "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U", + "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + ], + "view_number": 0 + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "ViewSyncPreCommitVote": { + "data": { + "relay": 0, + "round": 0 + }, + "signature": [ + "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U", + "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + ], + "view_number": 0 + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "ViewSyncCommitVote": { + "data": { + "relay": 0, + "round": 0 + }, + "signature": [ + "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U", + "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + ], + "view_number": 0 + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "ViewSyncFinalizeVote": { + "data": { + "relay": 0, + "round": 0 + }, + "signature": [ + "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U", + "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + ], + "view_number": 0 + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "ViewSyncPreCommitCertificate": { + "_pd": null, + "data": { + "relay": 0, + "round": 0 + }, + "signatures": null, + "view_number": 0, + "vote_commitment": "COMMIT~OQecZxfFpuEuPJgkpsQoglnqY0fm6Qi1PUarYCgiFQ0T" + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "ViewSyncCommitCertificate": { + "_pd": null, + "data": { + "relay": 0, + "round": 0 + }, + "signatures": null, + "view_number": 0, + "vote_commitment": "COMMIT~POgBCaDjtUV3Il5-FXVr5KN2KzYSgipfKX6Ci0-nxduO" + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "ViewSyncFinalizeCertificate": { + "_pd": null, + "data": { + "relay": 0, + "round": 0 + }, + "signatures": null, + "view_number": 0, + "vote_commitment": "COMMIT~s5i9wmQWH7VU90CUiEWRdAG19LI1iXydSMxp9gZ7kHco" + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "TimeoutVote": { + "data": { + "view": 0 + }, + "signature": [ + "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U", + "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + ], + "view_number": 0 + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "UpgradeProposal": { + "_pd": null, + "data": { + "upgrade_proposal": { + "decide_by": 0, + "new_version": { + "major": 1, + "minor": 0 + }, + "new_version_first_view": 0, + "new_version_hash": [], + "old_version": { + "major": 0, + "minor": 1 + }, + "old_version_last_view": 0 + }, + "view_number": 0 + }, + "signature": "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "General": { + "UpgradeVote": { + "data": { + "decide_by": 0, + "new_version": { + "major": 1, + "minor": 0 + }, + "new_version_first_view": 0, + "new_version_hash": [], + "old_version": { + "major": 0, + "minor": 1 + }, + "old_version_last_view": 0 + }, + "signature": [ + "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U", + "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + ], + "view_number": 0 + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "Da": { + "DaProposal": { + "_pd": null, + "data": { + "encoded_transactions": [ + 1, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 1, + 2, + 3 + ], + "metadata": { + "bytes": "AQAAAAEAAAALAAAA" + }, + "view_number": 0 + }, + "signature": "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "Da": { + "DaVote": { + "data": { + "payload_commit": "HASH~AazstQer_ho1SqgGT0r10_Gs0BnjfbPBHJdSO3HHbp29" + }, + "signature": [ + "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U", + "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + ], + "view_number": 0 + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "Da": { + "DaCertificate": { + "_pd": null, + "data": { + "payload_commit": "HASH~AazstQer_ho1SqgGT0r10_Gs0BnjfbPBHJdSO3HHbp29" + }, + "signatures": null, + "view_number": 0, + "vote_commitment": "COMMIT~5E3F3rC4E9DBhMBqOTmjZ9tjX4VFaV5gqrZJl0y6V05D" + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Consensus": { + "Da": { + "VidDisperseMsg": { + "_pd": null, + "data": { + "common": { + "all_evals_digest": "FIELD~rF4TMFZMXJCieDeov31aNuDG5nDGR-iQdteEgBjXkErn", + "multiplicity": 1, + "num_storage_nodes": 1, + "payload_byte_len": 11, + "poly_commits": "FIELD~AQAAAAAAAAD2xsICwO-z0CXx_ucl0FV1j-zJ3tgPO-OL8gYLvXkIkNE" + }, + "payload_commitment": "HASH~Z03vXeC1EEaBGf5iacsBEWYiA7PHi3K6uS9gVpmlUx3t", + "recipient_key": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U", + "share": { + "aggregate_proofs": "FIELD~AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQGY", + "evals": "FIELD~AQAAAAAAAAABAAAAAwAAAAECAwAAAAAAAAAAAAAAAAAAAAAAAAAAAMk", + "evals_proof": { + "pos": "FIELD~AAAAAAAAAAD7", + "proof": [ + { + "Leaf": { + "elem": "FIELD~AQAAAAAAAAABAAAAAwAAAAECAwAAAAAAAAAAAAAAAAAAAAAAAAAAAMk", + "pos": "FIELD~AAAAAAAAAAD7", + "value": "FIELD~rF4TMFZMXJCieDeov31aNuDG5nDGR-iQdteEgBjXkErn" + } + } + ] + }, + "index": 0 + }, + "view_number": 0 + }, + "signature": "BLS_SIG~g3CUcLMD7fnDsBhItKvSqXLwEqdWfvusSrgpL1GBAxf-SWFW0t32Agt2jrOiempjjpI7dBwYGgXv-0mvI4sGEEE" + } + } + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + }, + { + "kind": { + "Data": { + "SubmitTransaction": [ + { + "namespace": 1, + "payload": "AQID" + }, + 0 + ] + } + }, + "sender": "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U" + } +] \ No newline at end of file diff --git a/hotshot-state-prover/src/bin/state-prover.rs b/hotshot-state-prover/src/bin/state-prover.rs index a55b21cb96..52061db44a 100644 --- a/hotshot-state-prover/src/bin/state-prover.rs +++ b/hotshot-state-prover/src/bin/state-prover.rs @@ -1,7 +1,7 @@ use std::time::Duration; use clap::Parser; -use espresso_types::{parse_duration, BaseVersion}; +use espresso_types::parse_duration; use ethers::{ providers::{Http, Middleware, Provider}, signers::{coins_bip39::English, MnemonicBuilder, Signer}, @@ -11,7 +11,7 @@ use hotshot_stake_table::config::STAKE_TABLE_CAPACITY; use hotshot_state_prover::service::{run_prover_once, run_prover_service, StateProverConfig}; use sequencer_utils::logging; use url::Url; -use vbs::version::StaticVersionType; +use vbs::version::StaticVersion; #[derive(Parser)] struct Args { @@ -113,12 +113,12 @@ async fn main() { if args.daemon { // Launching the prover service daemon - if let Err(err) = run_prover_service(config, BaseVersion::instance()).await { + if let Err(err) = run_prover_service(config, StaticVersion::<0, 1> {}).await { tracing::error!("Error running prover service: {:?}", err); }; } else { // Run light client state update once - if let Err(err) = run_prover_once(config, BaseVersion::instance()).await { + if let Err(err) = run_prover_once(config, StaticVersion::<0, 1> {}).await { tracing::error!("Error running prover once: {:?}", err); }; } diff --git a/hotshot-state-prover/src/service.rs b/hotshot-state-prover/src/service.rs index b0c5d549e1..f869e0df57 100644 --- a/hotshot-state-prover/src/service.rs +++ b/hotshot-state-prover/src/service.rs @@ -235,8 +235,8 @@ pub fn load_proving_key(stake_table_capacity: usize) -> ProvingKey { pk } -pub async fn fetch_latest_state( - client: &Client, +pub async fn fetch_latest_state( + client: &Client, ) -> Result { tracing::info!("Fetching the latest state signatures bundle from relay server."); client @@ -307,10 +307,10 @@ pub async fn submit_state_and_proof( Ok(()) } -pub async fn sync_state( +pub async fn sync_state( st: &StakeTable, proving_key: Arc, - relay_server_client: &Client, + relay_server_client: &Client, config: &StateProverConfig, ) -> Result<(), ProverError> { let light_client_address = config.light_client_address; @@ -393,16 +393,16 @@ pub async fn sync_state( Ok(()) } -fn start_http_server( +fn start_http_server( port: u16, light_client_address: Address, - bind_version: Ver, + bind_version: ApiVer, ) -> io::Result<()> { let mut app = tide_disco::App::<_, ServerError>::with_state(()); let toml = toml::from_str::(include_str!("../api/prover-service.toml")) .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; - let mut api = Api::<_, ServerError, Ver>::new(toml) + let mut api = Api::<_, ServerError, ApiVer>::new(toml) .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; api.get("getlightclientcontract", move |_, _| { @@ -416,9 +416,9 @@ fn start_http_server( Ok(()) } -pub async fn run_prover_service( +pub async fn run_prover_service( config: StateProverConfig, - bind_version: Ver, + bind_version: ApiVer, ) -> Result<()> { let stake_table_capacity = config.stake_table_capacity; tracing::info!("Stake table capacity: {}", stake_table_capacity); @@ -431,15 +431,16 @@ pub async fn run_prover_service( run_prover_service_with_stake_table(config, bind_version, st).await } -pub async fn run_prover_service_with_stake_table( +pub async fn run_prover_service_with_stake_table( config: StateProverConfig, - bind_version: Ver, + bind_version: ApiVer, st: Arc>, ) -> Result<()> { tracing::info!("Light client address: {:?}", config.light_client_address); - let relay_server_client = - Arc::new(Client::::new(config.relay_server.clone())); + let relay_server_client = Arc::new(Client::::new( + config.relay_server.clone(), + )); // Start the HTTP server to get a functioning healthcheck before any heavy computations. if let Some(port) = config.port { @@ -466,9 +467,9 @@ pub async fn run_prover_service_with_stake_table( +pub async fn run_prover_once( config: StateProverConfig, - _: Ver, + _: ApiVer, ) -> Result<()> { let st = init_stake_table_from_sequencer(&config.sequencer_url, config.stake_table_capacity) .await @@ -476,7 +477,7 @@ pub async fn run_prover_once( let stake_table_capacity = config.stake_table_capacity; let proving_key = spawn_blocking(move || Arc::new(load_proving_key(stake_table_capacity))).await; - let relay_server_client = Client::::new(config.relay_server.clone()); + let relay_server_client = Client::::new(config.relay_server.clone()); sync_state(&st, proving_key, &relay_server_client, &config) .await diff --git a/marketplace-builder/src/bin/marketplace-builder.rs b/marketplace-builder/src/bin/marketplace-builder.rs index 2fe23ff6a4..abf9463cda 100644 --- a/marketplace-builder/src/bin/marketplace-builder.rs +++ b/marketplace-builder/src/bin/marketplace-builder.rs @@ -3,10 +3,14 @@ use std::{num::NonZeroUsize, path::PathBuf, time::Duration}; use async_compatibility_layer::logging::{setup_backtrace, setup_logging}; use clap::Parser; use espresso_types::{ - eth_signature_key::EthKeyPair, parse_duration, BaseVersion, FeeAmount, NamespaceId, + eth_signature_key::EthKeyPair, parse_duration, FeeAmount, FeeVersion, MarketplaceVersion, + NamespaceId, SequencerVersions, V0_1, }; use hotshot::traits::ValidatedState; -use hotshot_types::{data::ViewNumber, traits::node_implementation::ConsensusTime}; +use hotshot_types::{ + data::ViewNumber, + traits::node_implementation::{ConsensusTime, Versions}, +}; use marketplace_builder::{ builder::{build_instance_state, BuilderConfig}, hooks::BidConfig, @@ -123,8 +127,36 @@ async fn main() -> anyhow::Result<()> { setup_backtrace(); let opt = NonPermissionedBuilderOptions::parse(); + let genesis = Genesis::from_file(&opt.genesis_file)?; + tracing::info!(?genesis, "genesis"); + + let base = genesis.base_version; + let upgrade = genesis.upgrade_version; + + match (base, upgrade) { + (V0_1::VERSION, FeeVersion::VERSION) => { + run(genesis, opt, SequencerVersions::::new()).await + } + (FeeVersion::VERSION, MarketplaceVersion::VERSION) => { + run( + genesis, + opt, + SequencerVersions::::new(), + ) + .await + } + _ => panic!( + "Invalid base ({base}) and upgrade ({upgrade}) versions specified in the toml file." + ), + } +} +async fn run( + genesis: Genesis, + opt: NonPermissionedBuilderOptions, + versions: V, +) -> anyhow::Result<()> { let l1_params = L1Params { url: opt.l1_provider_url, events_max_block_range: 10000, @@ -145,13 +177,8 @@ async fn main() -> anyhow::Result<()> { let builder_server_url: Url = format!("http://0.0.0.0:{}", opt.port).parse().unwrap(); - let instance_state = build_instance_state( - genesis.chain_config, - l1_params, - opt.state_peers, - BaseVersion::instance(), - ) - .unwrap(); + let instance_state = + build_instance_state::(genesis.chain_config, l1_params, opt.state_peers).unwrap(); let base_fee = genesis.max_base_fee(); @@ -181,6 +208,7 @@ async fn main() -> anyhow::Result<()> { base_fee, bid_config, opt.solver_url, + versions, ) .await?; diff --git a/marketplace-builder/src/builder.rs b/marketplace-builder/src/builder.rs index 67e34153ab..fb564e7b1e 100644 --- a/marketplace-builder/src/builder.rs +++ b/marketplace-builder/src/builder.rs @@ -11,8 +11,8 @@ use async_compatibility_layer::{ use async_lock::RwLock; use async_std::sync::Arc; use espresso_types::{ - eth_signature_key::EthKeyPair, v0_3::ChainConfig, FeeAmount, L1Client, NamespaceId, NodeState, - Payload, SeqTypes, SequencerVersions, ValidatedState, + eth_signature_key::EthKeyPair, v0_3::ChainConfig, FeeAmount, L1Client, MockSequencerVersions, + NamespaceId, NodeState, Payload, SeqTypes, SequencerVersions, ValidatedState, }; use ethers::{ core::k256::ecdsa::SigningKey, @@ -31,7 +31,7 @@ use hotshot_types::{ data::{fake_commitment, Leaf, ViewNumber}, traits::{ block_contents::{vid_commitment, GENESIS_VID_NUM_STORAGE_NODES}, - node_implementation::{ConsensusTime, NodeType}, + node_implementation::{ConsensusTime, NodeType, Versions}, EncodeBytes, }, utils::BuilderCommitment, @@ -45,11 +45,11 @@ use marketplace_builder_core::{ ProxyGlobalState, ReceivedTransaction, }, }; -use sequencer::{catchup::StatePeers, L1Params, NetworkParams}; +use sequencer::{catchup::StatePeers, L1Params, NetworkParams, SequencerApiVersion}; use surf::http::headers::ACCEPT; use surf_disco::Client; use tide_disco::{app, method::ReadState, App, Url}; -use vbs::version::StaticVersionType; +use vbs::version::{StaticVersion, StaticVersionType}; use crate::{ hooks::{self, BidConfig, EspressoFallbackHooks, EspressoReserveHooks}, @@ -63,28 +63,29 @@ pub struct BuilderConfig { pub hotshot_builder_apis_url: Url, } -pub fn build_instance_state( +pub fn build_instance_state( chain_config: ChainConfig, l1_params: L1Params, state_peers: Vec, - _: Ver, ) -> anyhow::Result { let l1_client = L1Client::new(l1_params.url, l1_params.events_max_block_range); + let instance_state = NodeState::new( u64::MAX, // dummy node ID, only used for debugging chain_config, l1_client, - Arc::new(StatePeers::::from_urls( + Arc::new(StatePeers::::from_urls( state_peers, Default::default(), )), + V::Base::version(), ); Ok(instance_state) } impl BuilderConfig { #[allow(clippy::too_many_arguments)] - pub async fn init( + pub async fn init( is_reserve: bool, builder_key_pair: EthKeyPair, bootstrapped_view: ViewNumber, @@ -101,6 +102,7 @@ impl BuilderConfig { base_fee: FeeAmount, bid_config: Option, solver_api_url: Url, + _: V, ) -> anyhow::Result { tracing::info!( address = %builder_key_pair.fee_account(), @@ -204,9 +206,10 @@ impl BuilderConfig { }; async_spawn(async move { - let res = run_non_permissioned_standalone_builder_service::<_, SequencerVersions>( - hooks, senders, events_url, - ) + let res = run_non_permissioned_standalone_builder_service::< + SeqTypes, + V, // todo change this function to take only api version + >(hooks, senders, events_url) .await; tracing::error!(?res, "Reserve builder service exited"); if res.is_err() { @@ -219,7 +222,7 @@ impl BuilderConfig { let hooks = hooks::EspressoFallbackHooks { solver_api_url }; async_spawn(async move { - let res = run_non_permissioned_standalone_builder_service::<_, SequencerVersions>( + let res = run_non_permissioned_standalone_builder_service::( hooks, senders, events_url, ) .await; @@ -252,8 +255,8 @@ mod test { use async_std::{stream::StreamExt, task}; use committable::Commitment; use espresso_types::{ - mock::MockStateCatchup, BaseVersion, FeeAccount, MarketplaceVersion, NamespaceId, PubKey, - SeqTypes, Transaction, + mock::MockStateCatchup, FeeAccount, MarketplaceVersion, NamespaceId, PubKey, SeqTypes, + SequencerVersions, Transaction, }; use ethers::utils::Anvil; use hotshot::types::{BLSPrivKey, Event, EventType}; @@ -282,6 +285,7 @@ mod test { api::test_helpers::TestNetworkConfigBuilder, persistence::no_storage::{self, NoStorage}, testing::TestConfigBuilder, + SequencerApiVersion, }; use sequencer::{ api::{fs::DataSource, options::HotshotEvents, test_helpers::TestNetwork, Options}, @@ -291,6 +295,7 @@ mod test { use surf_disco::Client; use tempfile::TempDir; use tide_disco::error::ServerError; + use vbs::version::StaticVersion; use super::*; @@ -328,7 +333,7 @@ mod test { ) .network_config(network_config) .build(); - let network = TestNetwork::new(config, BaseVersion::instance()).await; + let network = TestNetwork::new(config, MockSequencerVersions::new()).await; // Start the builder let init = BuilderConfig::init( @@ -351,11 +356,12 @@ mod test { amount: FeeAmount::from(10), }), format!("http://localhost:{}", 3000).parse().unwrap(), + MockSequencerVersions::new(), ); let _builder_config = init.await; // Wait for at least one empty block to be sequenced (after consensus starts VID). - let sequencer_client: Client = Client::new(query_api_url); + let sequencer_client: Client = Client::new(query_api_url); sequencer_client.connect(None).await; sequencer_client .socket("availability/stream/leaves/0") @@ -372,15 +378,11 @@ mod test { Client::new(builder_api_url.clone()); builder_client.connect(None).await; - // TODO(AG): workaround for version mismatch between bundle and submit APIs - let submission_client: Client = Client::new(builder_api_url); - submission_client.connect(None).await; - // Test submitting transactions let transactions = (0..10) .map(|i| Transaction::new(0u32.into(), vec![1, 1, 1, i])) .collect::>(); - submission_client + builder_client .post::>>("txn_submit/batch") .body_json(&transactions) .unwrap() @@ -388,10 +390,10 @@ mod test { .await .unwrap(); - let events_service_client = - Client::::new( - event_service_url.clone(), - ); + let events_service_client = Client::< + hotshot_events_service::events::Error, + SequencerApiVersion, + >::new(event_service_url.clone()); events_service_client.connect(None).await; let mut subscribed_events = events_service_client diff --git a/marketplace-builder/src/hooks.rs b/marketplace-builder/src/hooks.rs index 467a92ec4a..9b4ca99102 100644 --- a/marketplace-builder/src/hooks.rs +++ b/marketplace-builder/src/hooks.rs @@ -4,7 +4,7 @@ use async_trait::async_trait; use espresso_types::v0_3::BidTxBody; use espresso_types::v0_3::RollupRegistration; -use espresso_types::BaseVersion; + use espresso_types::SeqTypes; use hotshot::types::EventType; @@ -22,6 +22,7 @@ use espresso_types::NamespaceId; use hotshot_types::traits::node_implementation::NodeType; use marketplace_solver::SolverError; +use sequencer::SequencerApiVersion; use surf_disco::Client; use tide_disco::Url; @@ -36,8 +37,10 @@ pub struct BidConfig { pub amount: FeeAmount, } -pub async fn connect_to_solver(solver_api_url: Url) -> Option> { - let client = Client::::new( +pub async fn connect_to_solver( + solver_api_url: Url, +) -> Option> { + let client = Client::::new( solver_api_url.join("marketplace-solver/").unwrap(), ); diff --git a/marketplace-builder/src/lib.rs b/marketplace-builder/src/lib.rs index 486455055d..50b62240aa 100755 --- a/marketplace-builder/src/lib.rs +++ b/marketplace-builder/src/lib.rs @@ -19,7 +19,7 @@ use espresso_types::{ eth_signature_key::EthKeyPair, v0::traits::{PersistenceOptions, SequencerPersistence, StateCatchup}, v0_3::BidTxBody, - BaseVersion, SeqTypes, + MarketplaceVersion, SeqTypes, SequencerVersions, }; use ethers::{ core::k256::ecdsa::SigningKey, @@ -73,7 +73,7 @@ use sequencer::{ use surf_disco::Client; use tide_disco::{app, method::ReadState, App, Url}; use tracing::error; -use vbs::version::StaticVersionType; +use vbs::version::{StaticVersion, StaticVersionType}; pub mod builder; @@ -92,7 +92,7 @@ pub fn run_builder_api_service(url: Url, source: ProxyGlobalState) { let private_mempool_api = hotshot_builder_api::v0_3::builder::submit_api::< ProxyGlobalState, SeqTypes, - BaseVersion, + MarketplaceVersion, >(&HotshotBuilderApiOptions::default()) .expect("Failed to construct the builder API for private mempool txns"); @@ -104,5 +104,5 @@ pub fn run_builder_api_service(url: Url, source: ProxyGlobalState) { app.register_module("txn_submit", private_mempool_api) .expect("Failed to register the private mempool API"); - async_spawn(app.serve(url, BaseVersion::instance())); + async_spawn(app.serve(url, MarketplaceVersion::instance())); } diff --git a/marketplace-solver/src/api.rs b/marketplace-solver/src/api.rs index 337dfad621..f8596d6df7 100644 --- a/marketplace-solver/src/api.rs +++ b/marketplace-solver/src/api.rs @@ -141,11 +141,11 @@ where Ok(api) } -pub(crate) fn load_api( +pub(crate) fn load_api( path: Option>, default: &str, extensions: impl IntoIterator, -) -> Result, ApiError> { +) -> Result, ApiError> { let mut toml = match path { Some(path) => load_toml(path.as_ref())?, None => toml::from_str(default).map_err(|err| ApiError::CannotReadToml { diff --git a/marketplace-solver/src/events.rs b/marketplace-solver/src/events.rs index 4dd32375aa..1495c5f352 100644 --- a/marketplace-solver/src/events.rs +++ b/marketplace-solver/src/events.rs @@ -2,20 +2,22 @@ use std::{pin::Pin, sync::Arc}; use anyhow::Context; use async_std::sync::RwLock; -use espresso_types::{BaseVersion, SeqTypes}; +use espresso_types::SeqTypes; use futures::{Stream, StreamExt as _}; use hotshot::types::Event; use hotshot_events_service::{events, events_source::StartupInfo}; use surf_disco::Client; use tide_disco::Url; +use vbs::version::StaticVersion; use crate::state::GlobalState; -pub struct EventsServiceClient(Client); +// TODO (ab): Change +pub struct EventsServiceClient(Client>); impl EventsServiceClient { pub async fn new(url: Url) -> Self { - let client = Client::::new(url.clone()); + let client = Client::new(url.clone()); client.connect(None).await; diff --git a/marketplace-solver/src/main.rs b/marketplace-solver/src/main.rs index 8810670884..005eb70140 100644 --- a/marketplace-solver/src/main.rs +++ b/marketplace-solver/src/main.rs @@ -4,7 +4,7 @@ use anyhow::Context; use async_compatibility_layer::logging::{setup_backtrace, setup_logging}; use async_std::{sync::RwLock, task::spawn}; use clap::Parser; -use espresso_types::BaseVersion; +use espresso_types::MarketplaceVersion; use marketplace_solver::{ define_api, handle_events, state::{GlobalState, SolverState, StakeTable}, @@ -13,8 +13,6 @@ use marketplace_solver::{ use tide_disco::App; use vbs::version::StaticVersionType; -type Version = BaseVersion; - #[async_std::main] async fn main() -> anyhow::Result<()> { setup_logging(); @@ -62,11 +60,14 @@ async fn main() -> anyhow::Result<()> { let mut api = define_api(Default::default())?; api.with_version(env!("CARGO_PKG_VERSION").parse()?); - app.register_module::("marketplace-solver", api)?; + app.register_module::("marketplace-solver", api)?; - app.serve(format!("0.0.0.0:{}", solver_api_port), Version::instance()) - .await - .unwrap(); + app.serve( + format!("0.0.0.0:{}", solver_api_port), + MarketplaceVersion::instance(), + ) + .await + .unwrap(); event_handler.cancel().await; diff --git a/marketplace-solver/src/testing.rs b/marketplace-solver/src/testing.rs index cb60ec99a8..c4ae0c137b 100755 --- a/marketplace-solver/src/testing.rs +++ b/marketplace-solver/src/testing.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use async_compatibility_layer::art::async_spawn; use async_std::{sync::RwLock, task::JoinHandle}; -use espresso_types::BaseVersion; +use espresso_types::MarketplaceVersion; use hotshot_query_service::data_source::sql::testing::TmpDb; use portpicker::pick_unused_port; use tide_disco::{App, Url}; @@ -80,7 +80,7 @@ impl MockSolver { let mut api = define_api(Default::default()).unwrap(); api.with_version(env!("CARGO_PKG_VERSION").parse().unwrap()); - app.register_module::("solver_api", api) + app.register_module::("solver_api", api) .unwrap(); let solver_api_port = pick_unused_port().expect("no free port"); @@ -89,7 +89,7 @@ impl MockSolver { let solver_api_handle = async_spawn({ let solver_url = solver_url.clone(); async move { - let _ = app.serve(solver_url, BaseVersion::instance()).await; + let _ = app.serve(solver_url, MarketplaceVersion::instance()).await; } }); @@ -119,7 +119,7 @@ mod test { use committable::Committable; use espresso_types::{ v0_3::{RollupRegistration, RollupRegistrationBody, RollupUpdate, RollupUpdatebody}, - BaseVersion, SeqTypes, + MarketplaceVersion, SeqTypes, }; use hotshot::types::{BLSPubKey, SignatureKey}; use hotshot_types::traits::node_implementation::NodeType; @@ -132,7 +132,7 @@ mod test { async fn test_rollup_registration() { let mock_solver = MockSolver::init().await; let solver_api = mock_solver.solver_api(); - let client = surf_disco::Client::::new(solver_api); + let client = surf_disco::Client::::new(solver_api); // Create a list of signature keys for rollup registration data let mut signature_keys = Vec::new(); @@ -280,7 +280,7 @@ mod test { async fn test_update_rollup_not_registered() { let mock_solver = MockSolver::init().await; let solver_api = mock_solver.solver_api(); - let client = surf_disco::Client::::new(solver_api); + let client = surf_disco::Client::::new(solver_api); let private_key = ::PrivateKey::generate(&mut rand::thread_rng()); @@ -331,7 +331,7 @@ mod test { let mock_solver = MockSolver::init().await; let solver_api = mock_solver.solver_api(); - let client = surf_disco::Client::::new(solver_api); + let client = surf_disco::Client::::new(solver_api); // Create a list of signature keys for rollup registration data let mut signature_keys = Vec::new(); @@ -477,7 +477,7 @@ mod test { let solver_api = mock_solver.solver_api(); - let client = surf_disco::Client::::new(solver_api); + let client = surf_disco::Client::::new(solver_api); let result: String = client.post("submit_bid").send().await.unwrap(); assert_eq!(result, "Bid Submitted".to_string()); diff --git a/node-metrics/src/api/node_validator/v0/cdn/mod.rs b/node-metrics/src/api/node_validator/v0/cdn/mod.rs index 227cfe3b32..bd0f5e8bd4 100644 --- a/node-metrics/src/api/node_validator/v0/cdn/mod.rs +++ b/node-metrics/src/api/node_validator/v0/cdn/mod.rs @@ -100,8 +100,8 @@ impl CdnReceiveMessagesTask { for message in messages { // We want to try and decode this message. - let message_deserialize_result: Result, _> = - bincode::deserialize(&message); + let message_deserialize_result = + bincode::deserialize::>(&message); let message = match message_deserialize_result { Ok(message) => message, @@ -558,7 +558,7 @@ mod test { let mut message_receiver = message_receiver; let next_message = message_receiver.next().await.unwrap(); - let next_message: Message = bincode::deserialize(&next_message).unwrap(); + let next_message = bincode::deserialize::>(&next_message).unwrap(); let external_message = match next_message.kind { MessageKind::External(external_message) => external_message, diff --git a/node-metrics/src/api/node_validator/v0/mod.rs b/node-metrics/src/api/node_validator/v0/mod.rs index 0cae3c51ce..490a11ceef 100644 --- a/node-metrics/src/api/node_validator/v0/mod.rs +++ b/node-metrics/src/api/node_validator/v0/mod.rs @@ -100,9 +100,9 @@ impl From for LoadApiError { } } -pub(crate) fn load_api( +pub(crate) fn load_api( default: &str, -) -> Result, LoadApiError> { +) -> Result, LoadApiError> { let toml: toml::Value = toml::from_str(default)?; Ok(Api::new(toml)?) } diff --git a/sequencer/src/api.rs b/sequencer/src/api.rs index 367dedb721..a939be30d4 100644 --- a/sequencer/src/api.rs +++ b/sequencer/src/api.rs @@ -9,7 +9,7 @@ use data_source::{CatchupDataSource, SubmitDataSource}; use derivative::Derivative; use espresso_types::{ v0::traits::SequencerPersistence, v0_3::ChainConfig, AccountQueryData, BlockMerkleTree, - FeeAccountProof, NodeState, PubKey, Transaction, + FeeAccountProof, MockSequencerVersions, NodeState, PubKey, Transaction, }; use ethers::prelude::Address; use futures::{ @@ -24,15 +24,16 @@ use hotshot_orchestrator::config::NetworkConfig; use hotshot_query_service::data_source::ExtensibleDataSource; use hotshot_state_prover::service::light_client_genesis_from_stake_table; use hotshot_types::{ - data::ViewNumber, light_client::StateSignatureRequestBody, traits::network::ConnectedNetwork, + data::ViewNumber, + light_client::StateSignatureRequestBody, + traits::{network::ConnectedNetwork, node_implementation::Versions}, }; use jf_merkle_tree::MerkleTreeScheme; -use vbs::version::StaticVersionType; use self::data_source::{HotShotConfigDataSource, PublicNetworkConfig, StateSignatureDataSource}; use crate::{ context::Consensus, network, persistence::ChainConfigPersistence, state_signature::StateSigner, - SeqTypes, SequencerContext, + SeqTypes, SequencerApiVersion, SequencerContext, }; pub mod data_source; @@ -50,21 +51,20 @@ type BoxLazy = Pin>>>; #[derive(Derivative)] #[derivative(Debug(bound = ""))] -struct ConsensusState, P: SequencerPersistence, Ver: StaticVersionType> -{ - state_signer: Arc>, +struct ConsensusState, P: SequencerPersistence, V: Versions> { + state_signer: Arc>, event_streamer: Arc>>, node_state: NodeState, config: NetworkConfig, #[derivative(Debug = "ignore")] - handle: Arc>>, + handle: Arc>>, } -impl, P: SequencerPersistence, Ver: StaticVersionType + 'static> - From<&SequencerContext> for ConsensusState +impl, P: SequencerPersistence, V: Versions> + From<&SequencerContext> for ConsensusState { - fn from(ctx: &SequencerContext) -> Self { + fn from(ctx: &SequencerContext) -> Self { Self { state_signer: ctx.state_signer(), event_streamer: ctx.event_streamer(), @@ -77,19 +77,17 @@ impl, P: SequencerPersistence, Ver: StaticVersionTyp #[derive(Derivative)] #[derivative(Clone(bound = ""), Debug(bound = ""))] -struct ApiState, P: SequencerPersistence, Ver: StaticVersionType> { +struct ApiState, P: SequencerPersistence, V: Versions> { // The consensus state is initialized lazily so we can start the API (and healthcheck endpoints) // before consensus has started. Any endpoint that uses consensus state will wait for // initialization to finish, but endpoints that do not require a consensus handle can proceed // without waiting. #[derivative(Debug = "ignore")] - consensus: BoxLazy>, + consensus: BoxLazy>, } -impl, P: SequencerPersistence, Ver: StaticVersionType + 'static> - ApiState -{ - fn new(init: impl Future> + Send + 'static) -> Self { +impl, P: SequencerPersistence, V: Versions> ApiState { + fn new(init: impl Future> + Send + 'static) -> Self { Self { consensus: Arc::pin(Lazy::from_future(init.boxed())), } @@ -102,7 +100,7 @@ impl, P: SequencerPersistence, Ver: StaticVersionTyp .flatten_stream() } - async fn state_signer(&self) -> &StateSigner { + async fn state_signer(&self) -> &StateSigner { &self.consensus.as_ref().get().await.get_ref().state_signer } @@ -110,7 +108,7 @@ impl, P: SequencerPersistence, Ver: StaticVersionTyp &self.consensus.as_ref().get().await.get_ref().event_streamer } - async fn consensus(&self) -> Arc>> { + async fn consensus(&self) -> Arc>> { Arc::clone(&self.consensus.as_ref().get().await.get_ref().handle) } @@ -123,11 +121,11 @@ impl, P: SequencerPersistence, Ver: StaticVersionTyp } } -type StorageState = ExtensibleDataSource>; +type StorageState = ExtensibleDataSource>; #[async_trait] -impl, Ver: StaticVersionType + 'static, P: SequencerPersistence> - EventsSource for ApiState +impl, P: SequencerPersistence, V: Versions> EventsSource + for ApiState { type EventStream = BoxStream<'static, Arc>>; @@ -152,20 +150,16 @@ impl, Ver: StaticVersionType + 'static, P: Sequencer } } -impl< - N: ConnectedNetwork, - D: Send + Sync, - Ver: StaticVersionType + 'static, - P: SequencerPersistence, - > SubmitDataSource for StorageState +impl, D: Send + Sync, V: Versions, P: SequencerPersistence> + SubmitDataSource for StorageState { async fn submit(&self, tx: Transaction) -> anyhow::Result<()> { self.as_ref().submit(tx).await } } -impl, Ver: StaticVersionType + 'static, P: SequencerPersistence> - SubmitDataSource for ApiState +impl, V: Versions, P: SequencerPersistence> SubmitDataSource + for ApiState { async fn submit(&self, tx: Transaction) -> anyhow::Result<()> { let handle = self.consensus().await; @@ -204,10 +198,10 @@ impl, Ver: StaticVersionType + 'static, P: Sequencer impl< N: ConnectedNetwork, - Ver: StaticVersionType + 'static, + V: Versions, P: SequencerPersistence, D: CatchupDataSource + Send + Sync, - > CatchupDataSource for StorageState + > CatchupDataSource for StorageState { #[tracing::instrument(skip(self))] async fn get_account( @@ -262,10 +256,10 @@ impl< #[async_trait] impl< N: ConnectedNetwork, - Ver: StaticVersionType + 'static, + V: Versions, P: SequencerPersistence, D: ChainConfigPersistence + Send + Sync, - > ChainConfigPersistence for StorageState + > ChainConfigPersistence for StorageState { async fn insert_chain_config(&mut self, chain_config: ChainConfig) -> anyhow::Result<()> { self.inner_mut().insert_chain_config(chain_config).await @@ -278,8 +272,8 @@ impl< } } -impl, Ver: StaticVersionType + 'static, P: SequencerPersistence> - CatchupDataSource for ApiState +impl, V: Versions, P: SequencerPersistence> CatchupDataSource + for ApiState { #[tracing::instrument(skip(self))] async fn get_account( @@ -336,20 +330,16 @@ impl, Ver: StaticVersionType + 'static, P: Sequencer } } -impl< - N: ConnectedNetwork, - D: Sync, - Ver: StaticVersionType + 'static, - P: SequencerPersistence, - > HotShotConfigDataSource for StorageState +impl, D: Sync, V: Versions, P: SequencerPersistence> + HotShotConfigDataSource for StorageState { async fn get_config(&self) -> PublicNetworkConfig { self.as_ref().network_config().await.into() } } -impl, Ver: StaticVersionType + 'static, P: SequencerPersistence> - HotShotConfigDataSource for ApiState +impl, V: Versions, P: SequencerPersistence> HotShotConfigDataSource + for ApiState { async fn get_config(&self) -> PublicNetworkConfig { self.network_config().await.into() @@ -357,12 +347,8 @@ impl, Ver: StaticVersionType + 'static, P: Sequencer } #[async_trait] -impl< - N: ConnectedNetwork, - D: Sync, - Ver: StaticVersionType + 'static, - P: SequencerPersistence, - > StateSignatureDataSource for StorageState +impl, D: Sync, V: Versions, P: SequencerPersistence> + StateSignatureDataSource for StorageState { async fn get_state_signature(&self, height: u64) -> Option { self.as_ref().get_state_signature(height).await @@ -370,8 +356,8 @@ impl< } #[async_trait] -impl, Ver: StaticVersionType + 'static, P: SequencerPersistence> - StateSignatureDataSource for ApiState +impl, V: Versions, P: SequencerPersistence> StateSignatureDataSource + for ApiState { async fn get_state_signature(&self, height: u64) -> Option { self.state_signer().await.get_state_signature(height).await @@ -388,7 +374,7 @@ pub mod test_helpers { use espresso_types::{ mock::MockStateCatchup, v0::traits::{PersistenceOptions, StateCatchup}, - BaseVersion, NamespaceId, ValidatedState, + NamespaceId, ValidatedState, }; use ethers::{prelude::Address, utils::Anvil}; use futures::{ @@ -407,6 +393,7 @@ pub mod test_helpers { use sequencer_utils::test_utils::setup_test; use surf_disco::Client; use tide_disco::error::ServerError; + use vbs::version::StaticVersion; use super::*; use crate::{ @@ -416,13 +403,9 @@ pub mod test_helpers { pub const STAKE_TABLE_CAPACITY_FOR_TEST: u64 = 10; - pub struct TestNetwork< - P: PersistenceOptions, - const NUM_NODES: usize, - Ver: StaticVersionType + 'static, - > { - pub server: SequencerContext, - pub peers: Vec>, + pub struct TestNetwork { + pub server: SequencerContext, + pub peers: Vec>, pub cfg: TestConfig<{ NUM_NODES }>, } @@ -535,12 +518,10 @@ pub mod test_helpers { } } - impl - TestNetwork - { + impl TestNetwork { pub async fn new( cfg: TestNetworkConfig<{ NUM_NODES }, P, C>, - _bind_ver: Ver, + bind_version: V, ) -> Self { let mut cfg = cfg; let (builder_task, builder_url) = @@ -558,26 +539,23 @@ pub mod test_helpers { let upgrades_map = cfg.upgrades(); async move { if i == 0 { - opt.serve( - |metrics| { - let cfg = cfg.clone(); - async move { - cfg.init_node( - 0, - state, - persistence, - catchup, - &*metrics, - STAKE_TABLE_CAPACITY_FOR_TEST, - Ver::instance(), - upgrades_map, - ) - .await - } - .boxed() - }, - Ver::instance(), - ) + opt.serve(|metrics| { + let cfg = cfg.clone(); + async move { + cfg.init_node( + 0, + state, + persistence, + catchup, + &*metrics, + STAKE_TABLE_CAPACITY_FOR_TEST, + bind_version, + upgrades_map, + ) + .await + } + .boxed() + }) .await .unwrap() } else { @@ -588,7 +566,7 @@ pub mod test_helpers { catchup, &NoMetrics, STAKE_TABLE_CAPACITY_FOR_TEST, - Ver::instance(), + bind_version, upgrades_map, ) .await @@ -643,7 +621,7 @@ pub mod test_helpers { let port = pick_unused_port().expect("No ports free"); let url = format!("http://localhost:{port}").parse().unwrap(); - let client: Client = Client::new(url); + let client: Client> = Client::new(url); let options = opt(Options::with_port(port).status(Default::default())); let anvil = Anvil::new().spawn(); @@ -653,7 +631,7 @@ pub mod test_helpers { .api_config(options) .network_config(network_config) .build(); - let _network = TestNetwork::new(config, BaseVersion::instance()).await; + let _network = TestNetwork::new(config, MockSequencerVersions::new()).await; client.connect(None).await; // The status API is well tested in the query service repo. Here we are just smoke testing @@ -695,7 +673,7 @@ pub mod test_helpers { let port = pick_unused_port().expect("No ports free"); let url = format!("http://localhost:{port}").parse().unwrap(); - let client: Client = Client::new(url); + let client: Client> = Client::new(url); let options = opt(Options::with_port(port).submit(Default::default())); let anvil = Anvil::new().spawn(); @@ -705,7 +683,7 @@ pub mod test_helpers { .api_config(options) .network_config(network_config) .build(); - let network = TestNetwork::new(config, BaseVersion::instance()).await; + let network = TestNetwork::new(config, MockSequencerVersions::new()).await; let mut events = network.server.event_stream().await; client.connect(None).await; @@ -730,7 +708,8 @@ pub mod test_helpers { let port = pick_unused_port().expect("No ports free"); let url = format!("http://localhost:{port}").parse().unwrap(); - let client: Client = Client::new(url); + + let client: Client> = Client::new(url); let options = opt(Options::with_port(port)); let anvil = Anvil::new().spawn(); @@ -740,7 +719,7 @@ pub mod test_helpers { .api_config(options) .network_config(network_config) .build(); - let network = TestNetwork::new(config, BaseVersion::instance()).await; + let network = TestNetwork::new(config, MockSequencerVersions::new()).await; let mut height: u64; // Wait for block >=2 appears @@ -772,7 +751,7 @@ pub mod test_helpers { let port = pick_unused_port().expect("No ports free"); let url = format!("http://localhost:{port}").parse().unwrap(); - let client: Client = Client::new(url); + let client: Client> = Client::new(url); let options = opt(Options::with_port(port).catchup(Default::default())); let anvil = Anvil::new().spawn(); @@ -782,7 +761,7 @@ pub mod test_helpers { .api_config(options) .network_config(network_config) .build(); - let network = TestNetwork::new(config, BaseVersion::instance()).await; + let network = TestNetwork::new(config, MockSequencerVersions::new()).await; client.connect(None).await; // Wait for a few blocks to be decided. @@ -863,7 +842,7 @@ mod api_tests { use data_source::testing::TestableSequencerDataSource; use endpoints::NamespaceProofQueryData; - use espresso_types::{BaseVersion, Header, NamespaceId}; + use espresso_types::{Header, NamespaceId}; use ethers::utils::Anvil; use futures::stream::StreamExt; use hotshot_query_service::availability::{LeafQueryData, VidCommonQueryData}; @@ -875,6 +854,7 @@ mod api_tests { TestNetwork, TestNetworkConfigBuilder, }; use tide_disco::error::ServerError; + use vbs::version::StaticVersion; use self::options::HotshotEvents; use super::*; @@ -916,11 +896,11 @@ mod api_tests { .api_config(D::options(&storage, Options::with_port(port)).submit(Default::default())) .network_config(network_config) .build(); - let network = TestNetwork::new(config, BaseVersion::instance()).await; + let network = TestNetwork::new(config, MockSequencerVersions::new()).await; let mut events = network.server.event_stream().await; // Connect client. - let client: Client = + let client: Client> = Client::new(format!("http://localhost:{port}").parse().unwrap()); client.connect(None).await; @@ -1019,7 +999,7 @@ mod api_tests { events_service_port: hotshot_event_streaming_port, }; - let client: Client = Client::new(url); + let client: Client> = Client::new(url); let options = Options::with_port(query_service_port).hotshot_events(hotshot_events); @@ -1030,7 +1010,7 @@ mod api_tests { .api_config(options) .network_config(network_config) .build(); - let _network = TestNetwork::new(config, BaseVersion::instance()).await; + let _network = TestNetwork::new(config, MockSequencerVersions::new()).await; let mut subscribed_events = client .socket("hotshot-events/events") @@ -1067,8 +1047,8 @@ mod test { use espresso_types::{ mock::MockStateCatchup, v0_1::{UpgradeMode, ViewBasedUpgrade}, - BaseVersion, FeeAccount, FeeAmount, Header, TimeBasedUpgrade, Timestamp, Upgrade, - UpgradeType, UpgradeVersion, ValidatedState, + FeeAccount, FeeAmount, Header, MockSequencerVersions, TimeBasedUpgrade, Timestamp, Upgrade, + UpgradeType, ValidatedState, }; use ethers::utils::Anvil; use futures::{ @@ -1095,6 +1075,7 @@ mod test { }; use tide_disco::{app::AppHealth, error::ServerError, healthcheck::HealthStatus}; use time::OffsetDateTime; + use vbs::version::{StaticVersion, StaticVersionType}; use self::{ data_source::{testing::TestableSequencerDataSource, PublicHotShotConfig}, @@ -1113,7 +1094,7 @@ mod test { let port = pick_unused_port().expect("No ports free"); let url = format!("http://localhost:{port}").parse().unwrap(); - let client: Client = Client::new(url); + let client: Client> = Client::new(url); let options = Options::with_port(port); let anvil = Anvil::new().spawn(); let l1 = anvil.endpoint().parse().unwrap(); @@ -1122,7 +1103,7 @@ mod test { .api_config(options) .network_config(network_config) .build(); - let _network = TestNetwork::new(config, BaseVersion::instance()).await; + let _network = TestNetwork::new(config, MockSequencerVersions::new()).await; client.connect(None).await; let health = client.get::("healthcheck").send().await.unwrap(); @@ -1150,7 +1131,7 @@ mod test { } #[async_std::test] - async fn test_merklized_state_api() { + async fn slow_test_merklized_state_api() { setup_test(); let port = pick_unused_port().expect("No ports free"); @@ -1163,16 +1144,16 @@ mod test { .status(Default::default()), ); - let anvil: ethers::utils::AnvilInstance = Anvil::new().spawn(); + let anvil = Anvil::new().spawn(); let l1 = anvil.endpoint().parse().unwrap(); let network_config = TestConfigBuilder::default().l1_url(l1).build(); let config = TestNetworkConfigBuilder::default() .api_config(options) .network_config(network_config) .build(); - let mut network = TestNetwork::new(config, BaseVersion::instance()).await; + let mut network = TestNetwork::new(config, MockSequencerVersions::new()).await; let url = format!("http://localhost:{port}").parse().unwrap(); - let client: Client = Client::new(url); + let client: Client = Client::new(url); client.connect(None).await; @@ -1235,13 +1216,13 @@ mod test { .api_config(Options::with_port(port).catchup(Default::default())) .network_config(TestConfigBuilder::default().l1_url(l1).build()) .catchups(std::array::from_fn(|_| { - StatePeers::::from_urls( + StatePeers::>::from_urls( vec![format!("http://localhost:{port}").parse().unwrap()], Default::default(), ) })) .build(); - let mut network = TestNetwork::new(config, BaseVersion::instance()).await; + let mut network = TestNetwork::new(config, MockSequencerVersions::new()).await; // Wait for replica 0 to reach a (non-genesis) decide, before disconnecting it. let mut events = network.peers[0].event_stream().await; @@ -1279,13 +1260,13 @@ mod test { 1, ValidatedState::default(), no_storage::Options, - StatePeers::::from_urls( + StatePeers::>::from_urls( vec![format!("http://localhost:{port}").parse().unwrap()], Default::default(), ), &NoMetrics, test_helpers::STAKE_TABLE_CAPACITY_FOR_TEST, - BaseVersion::instance(), + MockSequencerVersions::new(), Default::default(), ) .await; @@ -1342,7 +1323,7 @@ mod test { .api_config(Options::with_port(port).catchup(Default::default())) .states(states) .catchups(std::array::from_fn(|_| { - StatePeers::::from_urls( + StatePeers::>::from_urls( vec![format!("http://localhost:{port}").parse().unwrap()], Default::default(), ) @@ -1350,7 +1331,7 @@ mod test { .network_config(TestConfigBuilder::default().l1_url(l1).build()) .build(); - let mut network = TestNetwork::new(config, BaseVersion::instance()).await; + let mut network = TestNetwork::new(config, MockSequencerVersions::new()).await; // Wait for few blocks to be decided. network @@ -1419,7 +1400,7 @@ mod test { ) .states(states) .catchups(std::array::from_fn(|_| { - StatePeers::::from_urls( + StatePeers::>::from_urls( vec![format!("http://localhost:{port}").parse().unwrap()], Default::default(), ) @@ -1427,7 +1408,7 @@ mod test { .network_config(TestConfigBuilder::default().l1_url(l1).build()) .build(); - let mut network = TestNetwork::new(config, BaseVersion::instance()).await; + let mut network = TestNetwork::new(config, MockSequencerVersions::new()).await; // Wait for a few blocks to be decided. network @@ -1489,7 +1470,7 @@ mod test { let mut upgrades = std::collections::BTreeMap::new(); upgrades.insert( - UpgradeVersion::VERSION, + StaticVersion::<0, 2>::version(), Upgrade { mode, upgrade_type: UpgradeType::Fee { @@ -1511,7 +1492,7 @@ mod test { .status(Default::default()), ) .catchups(std::array::from_fn(|_| { - StatePeers::::from_urls( + StatePeers::::from_urls( vec![format!("http://localhost:{port}").parse().unwrap()], Default::default(), ) @@ -1524,7 +1505,7 @@ mod test { ) .build(); - let mut network = TestNetwork::new(config, BaseVersion::instance()).await; + let mut network = TestNetwork::new(config, MockSequencerVersions::new()).await; let mut events = network.server.event_stream().await; loop { @@ -1534,14 +1515,17 @@ mod test { EventType::UpgradeProposal { proposal, .. } => { let upgrade = proposal.data.upgrade_proposal; let new_version = upgrade.new_version; - assert_eq!(new_version, UpgradeVersion::VERSION); + assert_eq!( + new_version, + ::Upgrade::VERSION + ); break; } _ => continue, } } - let client: Client = + let client: Client = Client::new(format!("http://localhost:{port}").parse().unwrap()); client.connect(None).await; tracing::info!(port, "server running"); @@ -1599,10 +1583,10 @@ mod test { .persistences(persistence) .network_config(TestConfigBuilder::default().l1_url(l1).build()) .build(); - let mut network = TestNetwork::new(config, BaseVersion::instance()).await; + let mut network = TestNetwork::new(config, MockSequencerVersions::new()).await; // Connect client. - let client: Client = + let client: Client = Client::new(format!("http://localhost:{port}").parse().unwrap()); client.connect(None).await; tracing::info!(port, "server running"); @@ -1669,15 +1653,15 @@ mod test { // Catchup using node 0 as a peer. Node 0 was running the archival state service // before the restart, so it should be able to resume without catching up by loading // state from storage. - StatePeers::::from_urls( + StatePeers::>::from_urls( vec![format!("http://localhost:{port}").parse().unwrap()], Default::default(), ) })) .network_config(TestConfigBuilder::default().l1_url(l1).build()) .build(); - let _network = TestNetwork::new(config, BaseVersion::instance()).await; - let client: Client = + let _network = TestNetwork::new(config, MockSequencerVersions::new()).await; + let client: Client> = Client::new(format!("http://localhost:{port}").parse().unwrap()); client.connect(None).await; tracing::info!(port, "server running"); @@ -1718,7 +1702,7 @@ mod test { let port = pick_unused_port().expect("No ports free"); let url: surf_disco::Url = format!("http://localhost:{port}").parse().unwrap(); - let client: Client = Client::new(url.clone()); + let client: Client> = Client::new(url.clone()); let options = Options::with_port(port).config(Default::default()); let anvil = Anvil::new().spawn(); @@ -1728,12 +1712,12 @@ mod test { .api_config(options) .network_config(network_config) .build(); - let network = TestNetwork::new(config, BaseVersion::instance()).await; + let network = TestNetwork::new(config, MockSequencerVersions::new()).await; client.connect(None).await; // Fetch a network config from the API server. The first peer URL is bogus, to test the // failure/retry case. - let peers = StatePeers::::from_urls( + let peers = StatePeers::>::from_urls( vec!["https://notarealnode.network".parse().unwrap(), url], Default::default(), ); diff --git a/sequencer/src/api/data_source.rs b/sequencer/src/api/data_source.rs index 0518795211..358a45109f 100644 --- a/sequencer/src/api/data_source.rs +++ b/sequencer/src/api/data_source.rs @@ -21,12 +21,13 @@ use hotshot_query_service::{ status::StatusDataSource, }; use hotshot_types::{ - data::ViewNumber, light_client::StateSignatureRequestBody, traits::network::ConnectedNetwork, + data::ViewNumber, + light_client::StateSignatureRequestBody, + traits::{network::ConnectedNetwork, node_implementation::Versions}, ExecutionType, HotShotConfig, PeerConfig, ValidatorConfig, }; use serde::{Deserialize, Serialize}; use tide_disco::Url; -use vbs::version::StaticVersionType; use vec1::Vec1; use super::{ @@ -36,7 +37,7 @@ use super::{ }; use crate::{ persistence::{self}, - SeqTypes, + SeqTypes, SequencerApiVersion, }; pub trait DataSourceOptions: PersistenceOptions { @@ -84,9 +85,9 @@ pub trait SequencerDataSource: pub type Provider = AnyProvider; /// Create a provider for fetching missing data from a list of peer query services. -pub fn provider( +pub fn provider( peers: impl IntoIterator, - bind_version: Ver, + bind_version: SequencerApiVersion, ) -> Provider { let mut provider = Provider::default(); for peer in peers { diff --git a/sequencer/src/api/endpoints.rs b/sequencer/src/api/endpoints.rs index d32703c454..d75473a558 100644 --- a/sequencer/src/api/endpoints.rs +++ b/sequencer/src/api/endpoints.rs @@ -21,7 +21,10 @@ use hotshot_query_service::{ }; use hotshot_types::{ data::ViewNumber, - traits::{network::ConnectedNetwork, node_implementation::ConsensusTime}, + traits::{ + network::ConnectedNetwork, + node_implementation::{ConsensusTime, Versions}, + }, }; use serde::{de::Error as _, Deserialize, Serialize}; use snafu::OptionExt; @@ -39,7 +42,7 @@ use super::{ }, StorageState, }; -use crate::{SeqTypes, SequencerPersistence}; +use crate::{SeqTypes, SequencerApiVersion, SequencerPersistence}; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct NamespaceProofQueryData { @@ -47,16 +50,15 @@ pub struct NamespaceProofQueryData { pub transactions: Vec, } -pub(super) type AvailState = Arc>>; +pub(super) type AvailState = Arc>>; -type AvailabilityApi = Api, availability::Error, Ver>; +type AvailabilityApi = Api, availability::Error, ApiVer>; // TODO (abdul): replace snafu with `this_error` in hotshot query service // Snafu has been replaced by `this_error` everywhere. // However, the query service still uses snafu -pub(super) fn availability( - bind_version: Ver, -) -> Result> +pub(super) fn availability( +) -> Result> where N: ConnectedNetwork, D: SequencerDataSource + Send + Sync + 'static, @@ -67,9 +69,9 @@ where options.extensions.push(extension); let timeout = options.fetch_timeout; - let mut api = availability::define_api::, SeqTypes, Ver>( + let mut api = availability::define_api::, SeqTypes, _>( &options, - bind_version, + SequencerApiVersion::instance(), )?; api.get("getnamespaceproof", move |req, state| { @@ -125,37 +127,36 @@ where Ok(api) } -type ExplorerApi = Api, explorer::Error, Ver>; +type ExplorerApi = Api, explorer::Error, ApiVer>; -pub(super) fn explorer( - bind_version: Ver, -) -> Result> +pub(super) fn explorer( +) -> Result> where N: ConnectedNetwork, D: ExplorerStorage + Send + Sync + 'static, P: SequencerPersistence, { - let api = explorer::define_api::, SeqTypes, Ver>(bind_version)?; + let api = explorer::define_api::, SeqTypes, _>( + SequencerApiVersion::instance(), + )?; Ok(api) } -type NodeApi = Api, node::Error, Ver>; +type NodeApi = Api, node::Error, ApiVer>; -pub(super) fn node( - bind_version: Ver, -) -> Result> +pub(super) fn node() -> Result> where N: ConnectedNetwork, D: SequencerDataSource + Send + Sync + 'static, P: SequencerPersistence, { - let api = node::define_api::, SeqTypes, Ver>( + let api = node::define_api::, SeqTypes, _>( &Default::default(), - bind_version, + SequencerApiVersion::instance(), )?; Ok(api) } -pub(super) fn submit() -> Result> +pub(super) fn submit() -> Result> where N: ConnectedNetwork, S: 'static + Send + Sync + WriteState, @@ -163,12 +164,12 @@ where S::State: Send + Sync + SubmitDataSource, { let toml = toml::from_str::(include_str!("../../api/submit.toml"))?; - let mut api = Api::::new(toml)?; + let mut api = Api::::new(toml)?; api.at("submit", |req, state| { async move { let tx = req - .body_auto::(Ver::instance()) + .body_auto::(ApiVer::instance()) .map_err(Error::from_request_error)?; let hash = tx.commit(); @@ -184,16 +185,16 @@ where Ok(api) } -pub(super) fn state_signature( - _: Ver, -) -> Result> +pub(super) fn state_signature( + _: ApiVer, +) -> Result> where N: ConnectedNetwork, S: 'static + Send + Sync + ReadState, S::State: Send + Sync + StateSignatureDataSource, { let toml = toml::from_str::(include_str!("../../api/state_signature.toml"))?; - let mut api = Api::::new(toml)?; + let mut api = Api::::new(toml)?; api.get("get_state_signature", |req, state| { async move { @@ -214,13 +215,15 @@ where Ok(api) } -pub(super) fn catchup(_: Ver) -> Result> +pub(super) fn catchup( + _: ApiVer, +) -> Result> where S: 'static + Send + Sync + ReadState, S::State: Send + Sync + CatchupDataSource, { let toml = toml::from_str::(include_str!("../../api/catchup.toml"))?; - let mut api = Api::::new(toml)?; + let mut api = Api::::new(toml)?; api.get("account", |req, state| { async move { @@ -280,10 +283,10 @@ where Ok(api) } -type MerklizedStateApi = Api, merklized_state::Error, Ver>; -pub(super) fn merklized_state( - _: Ver, -) -> Result> +type MerklizedStateApi = + Api, merklized_state::Error, ApiVer>; +pub(super) fn merklized_state( +) -> Result> where N: ConnectedNetwork, D: MerklizedStateDataSource @@ -295,19 +298,25 @@ where P: SequencerPersistence, for<'a> >::Error: std::fmt::Display, { - let api = merklized_state::define_api::, SeqTypes, S, Ver, ARITY>( - &Default::default(), - )?; + let api = merklized_state::define_api::< + AvailState, + SeqTypes, + S, + SequencerApiVersion, + ARITY, + >(&Default::default())?; Ok(api) } -pub(super) fn config(_: Ver) -> Result> +pub(super) fn config( + _: ApiVer, +) -> Result> where S: 'static + Send + Sync + ReadState, S::State: Send + Sync + HotShotConfigDataSource, { let toml = toml::from_str::(include_str!("../../api/config.toml"))?; - let mut api = Api::::new(toml)?; + let mut api = Api::::new(toml)?; let env_variables = get_public_env_vars() .map_err(|err| Error::catch_all(StatusCode::INTERNAL_SERVER_ERROR, format!("{err:#}")))?; diff --git a/sequencer/src/api/options.rs b/sequencer/src/api/options.rs index 7ccaf05be4..d800e56f1b 100644 --- a/sequencer/src/api/options.rs +++ b/sequencer/src/api/options.rs @@ -17,6 +17,7 @@ use hotshot_query_service::{ use hotshot_types::traits::{ metrics::{Metrics, NoMetrics}, network::ConnectedNetwork, + node_implementation::Versions, }; use tide_disco::{ listener::RateLimitListener, @@ -38,6 +39,7 @@ use crate::{ context::{SequencerContext, TaskList}, persistence, state::update_state_storage_loop, + SequencerApiVersion, }; #[derive(Clone, Debug)] @@ -145,15 +147,14 @@ impl Options { /// The function `init_context` is used to create a sequencer context from a metrics object and /// optional saved consensus state. The metrics object is created from the API data source, so /// that consensus will populuate metrics that can then be read and served by the API. - pub async fn serve( + pub async fn serve( mut self, init_context: F, - bind_version: Ver, - ) -> anyhow::Result> + ) -> anyhow::Result> where N: ConnectedNetwork, P: SequencerPersistence, - F: FnOnce(Box) -> BoxFuture<'static, SequencerContext>, + F: FnOnce(Box) -> BoxFuture<'static, SequencerContext>, { // Create a channel to send the context to the web server after it is initialized. This // allows the web server to start before initialization can complete, since initialization @@ -181,11 +182,23 @@ impl Options { // we handle the two cases differently. let metrics = if let Some(query_opt) = self.query.take() { if let Some(opt) = self.storage_sql.take() { - self.init_with_query_module_sql(query_opt, opt, state, &mut tasks, bind_version) - .await? + self.init_with_query_module_sql( + query_opt, + opt, + state, + &mut tasks, + SequencerApiVersion::instance(), + ) + .await? } else if let Some(opt) = self.storage_fs.take() { - self.init_with_query_module_fs(query_opt, opt, state, &mut tasks, bind_version) - .await? + self.init_with_query_module_fs( + query_opt, + opt, + state, + &mut tasks, + SequencerApiVersion::instance(), + ) + .await? } else { bail!("query module requested but not storage provided"); } @@ -199,20 +212,20 @@ impl Options { ))); // Initialize status API. - let status_api = status::define_api(&Default::default(), bind_version)?; + let status_api = + status::define_api(&Default::default(), SequencerApiVersion::instance())?; app.register_module("status", status_api)?; - self.init_hotshot_modules::<_, _, _, Ver>(&mut app)?; + self.init_hotshot_modules(&mut app)?; if self.hotshot_events.is_some() { - self.init_and_spawn_hotshot_event_streaming_module( - state, - &mut tasks, - bind_version, - )?; + self.init_and_spawn_hotshot_event_streaming_module(state, &mut tasks)?; } - tasks.spawn("API server", self.listen(self.http.port, app, bind_version)); + tasks.spawn( + "API server", + self.listen(self.http.port, app, SequencerApiVersion::instance()), + ); metrics } else { @@ -224,17 +237,16 @@ impl Options { // better have been provided the leaf ahead of time if we want it at all. let mut app = App::<_, Error>::with_state(RwLock::new(state.clone())); - self.init_hotshot_modules::<_, _, _, Ver>(&mut app)?; + self.init_hotshot_modules(&mut app)?; if self.hotshot_events.is_some() { - self.init_and_spawn_hotshot_event_streaming_module( - state, - &mut tasks, - bind_version, - )?; + self.init_and_spawn_hotshot_event_streaming_module(state, &mut tasks)?; } - tasks.spawn("API server", self.listen(self.http.port, app, bind_version)); + tasks.spawn( + "API server", + self.listen(self.http.port, app, SequencerApiVersion::instance()), + ); Box::new(NoMetrics) }; @@ -242,16 +254,16 @@ impl Options { Ok(init_context(metrics).await.with_task_list(tasks)) } - async fn init_app_modules( + async fn init_app_modules( &self, ds: D, - state: ApiState, + state: ApiState, tasks: &mut TaskList, - bind_version: Ver, + bind_version: SequencerApiVersion, ) -> anyhow::Result<( Box, - Arc>>, - App>>, Error>, + Arc>>, + App>>, Error>, )> where N: ConnectedNetwork, @@ -259,13 +271,13 @@ impl Options { D: SequencerDataSource + CatchupDataSource + Send + Sync + 'static, { let metrics = ds.populate_metrics(); - let ds: endpoints::AvailState = + let ds: endpoints::AvailState = Arc::new(RwLock::new(ExtensibleDataSource::new(ds, state.clone()))); let mut app = App::<_, Error>::with_state(ds.clone()); // Initialize status API if self.status.is_some() { - let status_api = status::define_api::, Ver>( + let status_api = status::define_api::, _>( &Default::default(), bind_version, )?; @@ -273,10 +285,10 @@ impl Options { } // Initialize availability and node APIs (these both use the same data source). - app.register_module("availability", endpoints::availability(bind_version)?)?; - app.register_module("node", endpoints::node(bind_version)?)?; + app.register_module("availability", endpoints::availability()?)?; + app.register_module("node", endpoints::node()?)?; - self.init_hotshot_modules::<_, _, _, Ver>(&mut app)?; + self.init_hotshot_modules(&mut app)?; tasks.spawn( "query storage updater", @@ -286,13 +298,13 @@ impl Options { Ok((metrics, ds, app)) } - async fn init_with_query_module_fs( + async fn init_with_query_module_fs( &self, query_opt: Query, mod_opt: persistence::fs::Options, - state: ApiState, + state: ApiState, tasks: &mut TaskList, - bind_version: Ver, + bind_version: SequencerApiVersion, ) -> anyhow::Result> where N: ConnectedNetwork, @@ -300,7 +312,7 @@ impl Options { { let ds = ::create( mod_opt, - provider(query_opt.peers, bind_version), + provider::(query_opt.peers, bind_version), false, ) .await?; @@ -310,23 +322,20 @@ impl Options { .await?; if self.hotshot_events.is_some() { - self.init_and_spawn_hotshot_event_streaming_module(state, tasks, bind_version)?; + self.init_and_spawn_hotshot_event_streaming_module(state, tasks)?; } - tasks.spawn( - "API server", - self.listen(self.http.port, app, Ver::instance()), - ); + tasks.spawn("API server", self.listen(self.http.port, app, bind_version)); Ok(metrics) } - async fn init_with_query_module_sql( + async fn init_with_query_module_sql( self, query_opt: Query, mod_opt: persistence::sql::Options, - state: ApiState, + state: ApiState, tasks: &mut TaskList, - bind_version: Ver, + bind_version: SequencerApiVersion, ) -> anyhow::Result> where N: ConnectedNetwork, @@ -334,7 +343,7 @@ impl Options { { let ds = sql::DataSource::create( mod_opt.clone(), - provider(query_opt.peers.clone(), bind_version), + provider::(query_opt.peers.clone(), bind_version), false, ) .await?; @@ -343,19 +352,19 @@ impl Options { .await?; if self.explorer.is_some() { - app.register_module("explorer", endpoints::explorer(bind_version)?)?; + app.register_module("explorer", endpoints::explorer()?)?; } if self.state.is_some() { // Initialize merklized state module for block merkle tree app.register_module( "block-state", - endpoints::merklized_state::(bind_version)?, + endpoints::merklized_state::()?, )?; // Initialize merklized state module for fee merkle tree app.register_module( "fee-state", - endpoints::merklized_state::(bind_version)?, + endpoints::merklized_state::()?, )?; let state = state.clone(); @@ -367,12 +376,12 @@ impl Options { } if self.hotshot_events.is_some() { - self.init_and_spawn_hotshot_event_streaming_module(state, tasks, bind_version)?; + self.init_and_spawn_hotshot_event_streaming_module(state, tasks)?; } tasks.spawn( "API server", - self.listen(self.http.port, app, Ver::instance()), + self.listen(self.http.port, app, SequencerApiVersion::instance()), ); Ok(metrics) } @@ -382,10 +391,7 @@ impl Options { /// This function adds the `submit`, `state`, and `state_signature` API modules to the given /// app. These modules only require a HotShot handle as state, and thus they work with any data /// source, so initialization is the same no matter what mode the service is running in. - fn init_hotshot_modules( - &self, - app: &mut App, - ) -> anyhow::Result<()> + fn init_hotshot_modules(&self, app: &mut App) -> anyhow::Result<()> where S: 'static + Send + Sync + ReadState + WriteState, P: SequencerPersistence, @@ -397,10 +403,10 @@ impl Options { + HotShotConfigDataSource, N: ConnectedNetwork, { - let bind_version = Ver::instance(); + let bind_version = SequencerApiVersion::instance(); // Initialize submit API if self.submit.is_some() { - let submit_api = endpoints::submit::<_, _, _, Ver>()?; + let submit_api = endpoints::submit::<_, _, _, SequencerApiVersion>()?; app.register_module("submit", submit_api)?; } @@ -425,12 +431,11 @@ impl Options { fn init_and_spawn_hotshot_event_streaming_module< N, P: SequencerPersistence, - Ver: StaticVersionType + 'static, + V: Versions + 'static, >( &self, - state: ApiState, + state: ApiState, tasks: &mut TaskList, - bind_version: Ver, ) -> anyhow::Result<()> where N: ConnectedNetwork, @@ -447,30 +452,30 @@ impl Options { &hotshot_events_service::events::Options::default(), )?; - app.register_module::<_, Ver>("hotshot-events", hotshot_events_api)?; + app.register_module::<_, SequencerApiVersion>("hotshot-events", hotshot_events_api)?; tasks.spawn( "Hotshot Events Streaming API server", self.listen( self.hotshot_events.unwrap().events_service_port, app, - bind_version, + SequencerApiVersion::instance(), ), ); Ok(()) } - fn listen( + fn listen( &self, port: u16, app: App, - bind_version: Ver, + bind_version: ApiVer, ) -> impl Future> where S: Send + Sync + 'static, E: Send + Sync + tide_disco::Error, - Ver: StaticVersionType + 'static, + ApiVer: StaticVersionType + 'static, { let max_connections = self.http.max_connections; diff --git a/sequencer/src/api/update.rs b/sequencer/src/api/update.rs index 4efb4eba90..bc323b2654 100644 --- a/sequencer/src/api/update.rs +++ b/sequencer/src/api/update.rs @@ -5,14 +5,13 @@ use espresso_types::{v0::traits::SequencerPersistence, PubKey}; use futures::stream::{Stream, StreamExt}; use hotshot::types::Event; use hotshot_query_service::data_source::{UpdateDataSource, VersionedDataSource}; -use hotshot_types::traits::network::ConnectedNetwork; -use vbs::version::StaticVersionType; +use hotshot_types::traits::{network::ConnectedNetwork, node_implementation::Versions}; use super::{data_source::SequencerDataSource, StorageState}; use crate::SeqTypes; -pub(super) async fn update_loop( - state: Arc>>, +pub(super) async fn update_loop( + state: Arc>>, mut events: impl Stream> + Unpin, ) where N: ConnectedNetwork, @@ -38,8 +37,8 @@ pub(super) async fn update_loop( tracing::warn!("end of HotShot event stream, updater task will exit"); } -async fn update_state( - state: &mut StorageState, +async fn update_state( + state: &mut StorageState, event: &Event, ) -> anyhow::Result<()> where diff --git a/sequencer/src/bin/commitment-task.rs b/sequencer/src/bin/commitment-task.rs index 8955f26bdd..eaaf5a02a0 100644 --- a/sequencer/src/bin/commitment-task.rs +++ b/sequencer/src/bin/commitment-task.rs @@ -2,10 +2,13 @@ use std::{io, time::Duration}; use async_std::task::spawn; use clap::Parser; -use espresso_types::{parse_duration, BaseVersion}; +use espresso_types::parse_duration; use ethers::prelude::*; use futures::FutureExt; -use sequencer::hotshot_commitment::{run_hotshot_commitment_task, CommitmentTaskOptions}; +use sequencer::{ + hotshot_commitment::{run_hotshot_commitment_task, CommitmentTaskOptions}, + SequencerApiVersion, +}; use sequencer_utils::logging; use tide_disco::{error::ServerError, Api}; use url::Url; @@ -65,7 +68,7 @@ async fn main() { opt.logging.init(); if let Some(port) = opt.port { - start_http_server(port, opt.hotshot_address, BaseVersion::instance()).unwrap(); + start_http_server(port, opt.hotshot_address, SequencerApiVersion::instance()).unwrap(); } let hotshot_contract_options = CommitmentTaskOptions { @@ -79,19 +82,19 @@ async fn main() { query_service_url: Some(opt.sequencer_url), }; tracing::info!("Launching HotShot commitment task.."); - run_hotshot_commitment_task::(&hotshot_contract_options).await; + run_hotshot_commitment_task::(&hotshot_contract_options).await; } -fn start_http_server( +fn start_http_server( port: u16, hotshot_address: Address, - bind_version: Ver, + bind_version: ApiVer, ) -> io::Result<()> { let mut app = tide_disco::App::<(), ServerError>::with_state(()); let toml = toml::from_str::(include_str!("../../api/commitment_task.toml")) .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; - let mut api = Api::<(), ServerError, Ver>::new(toml) + let mut api = Api::<(), ServerError, ApiVer>::new(toml) .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; api.get("gethotshotcontract", move |_, _| { @@ -108,8 +111,8 @@ fn start_http_server( #[cfg(test)] mod test { - use espresso_types::BaseVersion; use portpicker::pick_unused_port; + use sequencer::SequencerApiVersion; use sequencer_utils::test_utils::setup_test; use surf_disco::Client; use vbs::version::StaticVersionType; @@ -124,10 +127,10 @@ mod test { let expected_addr = "0xED15E1FE0789c524398137a066ceb2EF9884E5D8" .parse::
() .unwrap(); - start_http_server(port, expected_addr, BaseVersion::instance()) + start_http_server(port, expected_addr, SequencerApiVersion::instance()) .expect("Failed to start the server"); - let client: Client = + let client: Client = Client::new(format!("http://localhost:{port}").parse().unwrap()); client.connect(None).await; diff --git a/sequencer/src/bin/dev-rollup.rs b/sequencer/src/bin/dev-rollup.rs index f9c43619a0..e75e370c71 100644 --- a/sequencer/src/bin/dev-rollup.rs +++ b/sequencer/src/bin/dev-rollup.rs @@ -5,7 +5,7 @@ use clap::{Parser, Subcommand}; use committable::Committable; use espresso_types::{ v0_3::{RollupRegistration, RollupRegistrationBody, RollupUpdate, RollupUpdatebody}, - SeqTypes, + MarketplaceVersion, SeqTypes, }; use hotshot::types::BLSPubKey; use hotshot_types::traits::{node_implementation::NodeType, signature_key::SignatureKey}; @@ -13,7 +13,6 @@ use marketplace_solver::SolverError; use sequencer_utils::logging; use url::Url; -use vbs::version::StaticVersion; #[derive(Debug, Parser)] struct Options { @@ -110,7 +109,7 @@ async fn register(opt: Register) -> Result<()> { private_key, } = opt; - let client = surf_disco::Client::>::new( + let client = surf_disco::Client::::new( solver_url.join("marketplace-solver").unwrap(), ); @@ -169,7 +168,7 @@ async fn update(opt: Update) -> Result<()> { private_key, } = opt; - let client = surf_disco::Client::>::new( + let client = surf_disco::Client::::new( solver_url.join("marketplace-solver").unwrap(), ); let (pubkey, privkey) = if let Some(privkey) = private_key { diff --git a/sequencer/src/bin/espresso-bridge.rs b/sequencer/src/bin/espresso-bridge.rs index 8de5d02793..8f65b21a34 100644 --- a/sequencer/src/bin/espresso-bridge.rs +++ b/sequencer/src/bin/espresso-bridge.rs @@ -4,9 +4,7 @@ use anyhow::{bail, ensure, Context}; use async_std::{sync::Arc, task::sleep}; use clap::{Parser, Subcommand}; use contract_bindings::fee_contract::FeeContract; -use espresso_types::{ - eth_signature_key::EthKeyPair, BaseVersion, FeeAccount, FeeAmount, FeeMerkleTree, Header, -}; +use espresso_types::{eth_signature_key::EthKeyPair, FeeAccount, FeeAmount, FeeMerkleTree, Header}; use ethers::{ middleware::{Middleware, SignerMiddleware}, providers::Provider, @@ -17,10 +15,11 @@ use jf_merkle_tree::{ prelude::{MerkleProof, Sha3Node}, MerkleTreeScheme, }; +use sequencer::SequencerApiVersion; use sequencer_utils::logging; use surf_disco::{error::ClientError, Url}; -type EspressoClient = surf_disco::Client; +type EspressoClient = surf_disco::Client; type FeeMerkleProof = MerkleProof; diff --git a/sequencer/src/bin/espresso-dev-node.rs b/sequencer/src/bin/espresso-dev-node.rs index 1e018b0ff9..f5172b6074 100644 --- a/sequencer/src/bin/espresso-dev-node.rs +++ b/sequencer/src/bin/espresso-dev-node.rs @@ -4,7 +4,7 @@ use async_std::task::spawn; use async_trait::async_trait; use clap::Parser; use contract_bindings::light_client_mock::LightClientMock; -use espresso_types::{parse_duration, BaseVersion}; +use espresso_types::{parse_duration, MockSequencerVersions}; use ethers::{ middleware::{MiddlewareBuilder, SignerMiddleware}, providers::{Http, Middleware, Provider}, @@ -25,6 +25,7 @@ use sequencer::{ persistence, state_signature::relay_server::run_relay_server, testing::TestConfigBuilder, + SequencerApiVersion, }; use sequencer_utils::{ deployer::{deploy, Contract, Contracts}, @@ -187,7 +188,7 @@ async fn main() -> anyhow::Result<()> { .network_config(network_config) .build(); - let network = TestNetwork::new(config, BaseVersion::instance()).await; + let network = TestNetwork::new(config, MockSequencerVersions::new()).await; let st = network.cfg.stake_table(); let total_stake = st.total_stake(SnapshotVersion::LastEpochStart).unwrap(); let config = network.cfg.hotshot_config(); @@ -285,7 +286,7 @@ async fn main() -> anyhow::Result<()> { let prover_handle = spawn(run_prover_service_with_stake_table( prover_config, - BaseVersion::instance(), + SequencerApiVersion::instance(), Arc::new(st.clone()), )); handles.push(prover_handle); @@ -298,7 +299,7 @@ async fn main() -> anyhow::Result<()> { format!("http://0.0.0.0:{relay_server_port}") .parse() .unwrap(), - BaseVersion::instance(), + SequencerApiVersion::instance(), ) .await; @@ -337,7 +338,7 @@ async fn main() -> anyhow::Result<()> { dev_node_port, mock_contracts, dev_info, - BaseVersion::instance(), + SequencerApiVersion::instance(), )); handles.push(dev_node_handle); @@ -366,18 +367,18 @@ impl ReadState for ApiState { } } -async fn run_dev_node_server( +async fn run_dev_node_server( port: u16, contracts: BTreeMap, S>>>, dev_info: DevInfo, - bind_version: Ver, + bind_version: ApiVer, ) -> anyhow::Result<()> { let mut app = tide_disco::App::<_, ServerError>::with_state(ApiState(contracts)); let toml = toml::from_str::(include_str!("../../api/espresso_dev_node.toml")) .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; - let mut api = Api::<_, ServerError, Ver>::new(toml) + let mut api = Api::<_, ServerError, ApiVer>::new(toml) .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; api.get("devinfo", move |_, _| { let info = dev_info.clone(); @@ -387,7 +388,7 @@ async fn run_dev_node_server| { async move { let body = req - .body_auto::(Ver::instance()) + .body_auto::(ApiVer::instance()) .map_err(ServerError::from_request_error)?; // if chain id is not provided, primary L1 light client is used @@ -422,7 +423,7 @@ async fn run_dev_node_server, Ver>(Ver::instance()) + .body_auto::, ApiVer>(ApiVer::instance()) .map_err(ServerError::from_request_error)? .map(|b| b.chain_id); @@ -500,7 +501,7 @@ mod tests { use committable::{Commitment, Committable}; use contract_bindings::light_client::LightClient; use escargot::CargoBuild; - use espresso_types::{BaseVersion, BlockMerkleTree, Header, SeqTypes, Transaction}; + use espresso_types::{BlockMerkleTree, Header, SeqTypes, Transaction}; use ethers::{providers::Middleware, types::U256}; use futures::TryStreamExt; use hotshot_query_service::{ @@ -510,7 +511,7 @@ mod tests { use jf_merkle_tree::MerkleTreeScheme; use portpicker::pick_unused_port; use rand::Rng; - use sequencer::api::endpoints::NamespaceProofQueryData; + use sequencer::{api::endpoints::NamespaceProofQueryData, SequencerApiVersion}; use sequencer_utils::{init_signer, test_utils::setup_test, Anvil, AnvilOptions}; use surf_disco::Client; use tide_disco::error::ServerError; @@ -577,7 +578,7 @@ mod tests { let process = BackgroundProcess(process); - let api_client: Client = + let api_client: Client = Client::new(format!("http://localhost:{api_port}").parse().unwrap()); api_client.connect(None).await; @@ -751,7 +752,7 @@ mod tests { } } - let dev_node_client: Client = + let dev_node_client: Client = Client::new(format!("http://localhost:{dev_node_port}").parse().unwrap()); dev_node_client.connect(None).await; @@ -895,7 +896,7 @@ mod tests { let process = BackgroundProcess(process); - let api_client: Client = + let api_client: Client = Client::new(format!("http://localhost:{api_port}").parse().unwrap()); api_client.connect(None).await; @@ -910,7 +911,7 @@ mod tests { .await .unwrap(); - let dev_node_client: Client = + let dev_node_client: Client = Client::new(format!("http://localhost:{dev_node_port}").parse().unwrap()); dev_node_client.connect(None).await; diff --git a/sequencer/src/bin/nasty-client.rs b/sequencer/src/bin/nasty-client.rs index f9f0bbee38..2a5f941d28 100644 --- a/sequencer/src/bin/nasty-client.rs +++ b/sequencer/src/bin/nasty-client.rs @@ -21,8 +21,7 @@ use clap::Parser; use committable::Committable; use derivative::Derivative; use espresso_types::{ - parse_duration, v0_3::IterableFeeInfo, BaseVersion, BlockMerkleTree, FeeMerkleTree, Header, - SeqTypes, + parse_duration, v0_3::IterableFeeInfo, BlockMerkleTree, FeeMerkleTree, Header, SeqTypes, }; use futures::{ future::{FutureExt, TryFuture, TryFutureExt}, @@ -38,7 +37,7 @@ use jf_merkle_tree::{ ForgetableMerkleTreeScheme, MerkleCommitment, MerkleTreeScheme, UniversalMerkleTreeScheme, }; use rand::{seq::SliceRandom, RngCore}; -use sequencer::api::endpoints::NamespaceProofQueryData; +use sequencer::{api::endpoints::NamespaceProofQueryData, SequencerApiVersion}; use sequencer_utils::logging; use serde::de::DeserializeOwned; use std::{ @@ -402,7 +401,7 @@ impl Queryable for PayloadQueryData { } } -type Connection = socket::Connection; +type Connection = socket::Connection; #[derive(Derivative)] #[derivative(Debug)] @@ -415,7 +414,7 @@ struct Subscription { #[derive(Debug)] struct ResourceManager { - client: surf_disco::Client, + client: surf_disco::Client, open_streams: BTreeMap>, next_stream_id: u64, metrics: Arc, @@ -1260,14 +1259,14 @@ async fn serve(port: u16, metrics: PrometheusMetrics) { METHOD = "METRICS" }; let mut app = App::<_, ServerError>::with_state(RwLock::new(metrics)); - app.module::("status", api) + app.module::("status", api) .unwrap() .metrics("metrics", |_req, state| { async move { Ok(Cow::Borrowed(state)) }.boxed() }) .unwrap(); if let Err(err) = app - .serve(format!("0.0.0.0:{port}"), BaseVersion::instance()) + .serve(format!("0.0.0.0:{port}"), SequencerApiVersion::instance()) .await { tracing::error!("web server exited unexpectedly: {err:#}"); diff --git a/sequencer/src/bin/state-relay-server.rs b/sequencer/src/bin/state-relay-server.rs index b29ec02e9b..3803c97a02 100644 --- a/sequencer/src/bin/state-relay-server.rs +++ b/sequencer/src/bin/state-relay-server.rs @@ -1,8 +1,7 @@ use clap::Parser; -use espresso_types::BaseVersion; use ethers::types::U256; use hotshot_state_prover::service::one_honest_threshold; -use sequencer::state_signature::relay_server::run_relay_server; +use sequencer::{state_signature::relay_server::run_relay_server, SequencerApiVersion}; use sequencer_utils::logging; use vbs::version::StaticVersionType; @@ -46,7 +45,7 @@ async fn main() { None, threshold, format!("http://0.0.0.0:{}", args.port).parse().unwrap(), - BaseVersion::instance(), + SequencerApiVersion::instance(), ) .await .unwrap(); diff --git a/sequencer/src/bin/submit-transactions.rs b/sequencer/src/bin/submit-transactions.rs index 6385f34c37..5001a27635 100644 --- a/sequencer/src/bin/submit-transactions.rs +++ b/sequencer/src/bin/submit-transactions.rs @@ -8,7 +8,7 @@ use std::{ use async_std::task::{sleep, spawn}; use clap::Parser; use committable::{Commitment, Committable}; -use espresso_types::{parse_duration, parse_size, BaseVersion, SeqTypes, Transaction}; +use espresso_types::{parse_duration, parse_size, SeqTypes, Transaction}; use futures::{ channel::mpsc::{self, Sender}, sink::SinkExt, @@ -18,6 +18,7 @@ use hotshot_query_service::{availability::BlockQueryData, types::HeightIndexed, use rand::{Rng, RngCore, SeedableRng}; use rand_chacha::ChaChaRng; use rand_distr::Distribution; +use sequencer::SequencerApiVersion; use sequencer_utils::logging; use surf_disco::{Client, Url}; use tide_disco::{error::ServerError, App}; @@ -173,7 +174,7 @@ async fn main() { let mut rng = ChaChaRng::seed_from_u64(seed); // Subscribe to block stream so we can check that our transactions are getting sequenced. - let client = Client::::new(opt.url.clone()); + let client = Client::::new(opt.url.clone()); let block_height: usize = client.get("status/block-height").send().await.unwrap(); let mut blocks = client .socket(&format!("availability/stream/blocks/{}", block_height - 1)) @@ -188,13 +189,13 @@ async fn main() { opt.clone(), sender.clone(), ChaChaRng::from_rng(&mut rng).unwrap(), - BaseVersion::instance(), + SequencerApiVersion::instance(), )); } // Start healthcheck endpoint once tasks are running. if let Some(port) = opt.port { - spawn(server(port, BaseVersion::instance())); + spawn(server(port, SequencerApiVersion::instance())); } // Keep track of the results. @@ -380,15 +381,15 @@ struct SubmittedTransaction { submitted_at: Instant, } -async fn submit_transactions( +async fn submit_transactions( opt: Options, mut sender: Sender, mut rng: ChaChaRng, - _: Ver, + _: ApiVer, ) { let url = opt.submit_url(); tracing::info!(%url, "starting load generator task"); - let client = Client::::new(url); + let client = Client::::new(url); // Create an exponential distribution for sampling delay times. The distribution should have // mean `opt.delay`, or parameter `\lambda = 1 / opt.delay`. @@ -454,7 +455,7 @@ async fn submit_transactions( } } -async fn server(port: u16, bind_version: Ver) { +async fn server(port: u16, bind_version: ApiVer) { if let Err(err) = App::<(), ServerError>::with_state(()) .serve(format!("0.0.0.0:{port}"), bind_version) .await diff --git a/sequencer/src/bin/verify-headers.rs b/sequencer/src/bin/verify-headers.rs index a6bc3cf241..9ef7945783 100644 --- a/sequencer/src/bin/verify-headers.rs +++ b/sequencer/src/bin/verify-headers.rs @@ -4,10 +4,11 @@ use std::{cmp::max, process::exit, time::Duration}; use async_std::{sync::Arc, task::sleep}; use clap::Parser; -use espresso_types::{BaseVersion, Header, L1BlockInfo}; +use espresso_types::{Header, L1BlockInfo}; use ethers::prelude::*; use futures::future::join_all; use itertools::Itertools; +use sequencer::SequencerApiVersion; use sequencer_utils::logging; use surf_disco::Url; use vbs::version::StaticVersionType; @@ -53,11 +54,11 @@ struct Options { logging: logging::Config, } -type SequencerClient = surf_disco::Client; +type SequencerClient = surf_disco::Client; -async fn verify_header( +async fn verify_header( opt: &Options, - seq: &SequencerClient, + seq: &SequencerClient, l1: Option<&Provider>, parent: Option
, height: usize, @@ -116,7 +117,10 @@ async fn verify_header( (header, ok) } -async fn get_header(seq: &SequencerClient, height: usize) -> Header { +async fn get_header( + seq: &SequencerClient, + height: usize, +) -> Header { loop { match seq .get(&format!("availability/header/{height}")) @@ -169,7 +173,7 @@ async fn main() { let opt = Arc::new(Options::parse()); opt.logging.init(); - let seq = Arc::new(SequencerClient::::new(opt.url.clone())); + let seq = Arc::new(SequencerClient::::new(opt.url.clone())); let block_height: usize = seq.get("status/latest_block_height").send().await.unwrap(); let from = opt.from.unwrap_or(0); diff --git a/sequencer/src/catchup.rs b/sequencer/src/catchup.rs index 035b1809fa..5950a6bdfa 100644 --- a/sequencer/src/catchup.rs +++ b/sequencer/src/catchup.rs @@ -32,12 +32,12 @@ use crate::{ // This newtype is probably not worth having. It's only used to be able to log // URLs before doing requests. #[derive(Debug, Clone)] -struct Client { - inner: surf_disco::Client, +struct Client { + inner: surf_disco::Client, url: Url, } -impl Client { +impl Client { pub fn new(url: Url) -> Self { Self { inner: surf_disco::Client::new(url.clone()), @@ -45,7 +45,7 @@ impl Client { } } - pub fn get(&self, route: &str) -> Request { + pub fn get(&self, route: &str) -> Request { self.inner.get(route) } } @@ -66,12 +66,12 @@ pub(crate) async fn local_and_remote( } #[derive(Debug, Clone, Default)] -pub struct StatePeers { - clients: Vec>, +pub struct StatePeers { + clients: Vec>, backoff: BackoffParams, } -impl StatePeers { +impl StatePeers { pub fn from_urls(urls: Vec, backoff: BackoffParams) -> Self { if urls.is_empty() { panic!("Cannot create StatePeers with no peers"); @@ -116,7 +116,7 @@ impl StatePeers { } #[async_trait] -impl StateCatchup for StatePeers { +impl StateCatchup for StatePeers { #[tracing::instrument(skip(self))] async fn try_fetch_account( &self, diff --git a/sequencer/src/context.rs b/sequencer/src/context.rs index 7d353ff487..fabc3eba00 100644 --- a/sequencer/src/context.rs +++ b/sequencer/src/context.rs @@ -7,8 +7,7 @@ use async_std::{ }; use derivative::Derivative; use espresso_types::{ - v0::traits::SequencerPersistence, NodeState, PubKey, SequencerVersions, Transaction, - ValidatedState, + v0::traits::SequencerPersistence, NodeState, PubKey, Transaction, ValidatedState, }; use futures::{ future::{join_all, Future}, @@ -30,33 +29,29 @@ use hotshot_types::{ election::Membership, metrics::Metrics, network::{ConnectedNetwork, Topic}, + node_implementation::Versions, }, }; use url::Url; -use vbs::version::StaticVersionType; use crate::{ external_event_handler::{self, ExternalEventHandler}, state_signature::StateSigner, - static_stake_table_commitment, Node, SeqTypes, + static_stake_table_commitment, Node, SeqTypes, SequencerApiVersion, }; /// The consensus handle -pub type Consensus = SystemContextHandle, SequencerVersions>; +pub type Consensus = SystemContextHandle, V>; /// The sequencer context contains a consensus handle and other sequencer specific information. #[derive(Derivative)] #[derivative(Debug(bound = ""))] -pub struct SequencerContext< - N: ConnectedNetwork, - P: SequencerPersistence, - Ver: StaticVersionType + 'static, -> { +pub struct SequencerContext, P: SequencerPersistence, V: Versions> { /// The consensus handle #[derivative(Debug = "ignore")] - handle: Arc>>, + handle: Arc>>, /// Context for generating state signatures. - state_signer: Arc>, + state_signer: Arc>, /// An orchestrator to wait for before starting consensus. #[derivative(Debug = "ignore")] @@ -75,9 +70,7 @@ pub struct SequencerContext< config: NetworkConfig, } -impl, P: SequencerPersistence, Ver: StaticVersionType + 'static> - SequencerContext -{ +impl, P: SequencerPersistence, V: Versions> SequencerContext { #[tracing::instrument(skip_all, fields(node_id = instance_state.node_id))] #[allow(clippy::too_many_arguments)] pub async fn init( @@ -89,7 +82,7 @@ impl, P: SequencerPersistence, Ver: StaticVersionTyp metrics: &dyn Metrics, stake_table_capacity: u64, public_api_url: Option, - _: Ver, + _: V, marketplace_config: MarketplaceConfig>, ) -> anyhow::Result { let config = &network_config.config; @@ -183,10 +176,10 @@ impl, P: SequencerPersistence, Ver: StaticVersionTyp /// Constructor fn new( - handle: Consensus, + handle: Consensus, persistence: Arc>, - state_signer: StateSigner, - external_event_handler: ExternalEventHandler, + state_signer: StateSigner, + external_event_handler: ExternalEventHandler, event_streamer: Arc>>, node_state: NodeState, config: NetworkConfig, @@ -230,7 +223,7 @@ impl, P: SequencerPersistence, Ver: StaticVersionTyp } /// Return a reference to the consensus state signer. - pub fn state_signer(&self) -> Arc> { + pub fn state_signer(&self) -> Arc> { self.state_signer.clone() } @@ -250,7 +243,7 @@ impl, P: SequencerPersistence, Ver: StaticVersionTyp } /// Return a reference to the underlying consensus handle. - pub fn consensus(&self) -> Arc>> { + pub fn consensus(&self) -> Arc>> { Arc::clone(&self.handle) } @@ -322,8 +315,8 @@ impl, P: SequencerPersistence, Ver: StaticVersionTyp } } -impl, P: SequencerPersistence, Ver: StaticVersionType + 'static> Drop - for SequencerContext +impl, P: SequencerPersistence, V: Versions> Drop + for SequencerContext { fn drop(&mut self) { if !self.detached { @@ -332,11 +325,11 @@ impl, P: SequencerPersistence, Ver: StaticVersionTyp } } -async fn handle_events( +async fn handle_events( mut events: impl Stream> + Unpin, persistence: Arc>, - state_signer: Arc>, - external_event_handler: ExternalEventHandler, + state_signer: Arc>, + external_event_handler: ExternalEventHandler, events_streamer: Option>>>, ) { while let Some(event) = events.next().await { diff --git a/sequencer/src/external_event_handler.rs b/sequencer/src/external_event_handler.rs index 3e1b23c46e..f1efef879b 100644 --- a/sequencer/src/external_event_handler.rs +++ b/sequencer/src/external_event_handler.rs @@ -7,10 +7,13 @@ use espresso_types::{PubKey, SeqTypes}; use hotshot::types::{BLSPubKey, Message}; use hotshot_types::{ message::MessageKind, - traits::network::{BroadcastDelay, ConnectedNetwork, Topic}, + traits::{ + network::{BroadcastDelay, ConnectedNetwork, Topic}, + node_implementation::Versions, + }, }; use serde::{Deserialize, Serialize}; -use std::sync::Arc; +use std::{marker::PhantomData, sync::Arc}; use url::Url; /// An external message that can be sent to or received from a node @@ -33,7 +36,7 @@ pub struct RollCallInfo { } /// The external event handler state -pub struct ExternalEventHandler { +pub struct ExternalEventHandler { // The `RollCallInfo` of the node (used in the roll call response) pub roll_call_info: RollCallInfo, @@ -45,6 +48,8 @@ pub struct ExternalEventHandler { // The outbound message queue pub outbound_message_sender: Sender, + + _pd: PhantomData, } // The different types of outbound messages (broadcast or direct) @@ -54,7 +59,7 @@ pub enum OutboundMessage { Broadcast(Vec), } -impl ExternalEventHandler { +impl ExternalEventHandler { /// Creates a new `ExternalEventHandler` with the given network and roll call info pub async fn new>( network: Arc, @@ -90,6 +95,7 @@ impl ExternalEventHandler { public_key, _tasks: tasks, outbound_message_sender, + _pd: Default::default(), }) } diff --git a/sequencer/src/genesis.rs b/sequencer/src/genesis.rs index 254b746eb9..c85acffae4 100644 --- a/sequencer/src/genesis.rs +++ b/sequencer/src/genesis.rs @@ -38,13 +38,17 @@ pub enum L1Finalized { /// Genesis of an Espresso chain. #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Genesis { + #[serde(with = "version_ser")] + pub base_version: Version, + #[serde(with = "version_ser")] + pub upgrade_version: Version, pub chain_config: ChainConfig, pub stake_table: StakeTableConfig, #[serde(default)] pub accounts: HashMap, pub l1_finalized: Option, pub header: GenesisHeader, - #[serde(rename = "upgrade", with = "upgrade_serialization")] + #[serde(rename = "upgrade", with = "upgrade_ser")] #[serde(default)] pub upgrades: BTreeMap, } @@ -65,7 +69,41 @@ impl Genesis { } } -mod upgrade_serialization { +mod version_ser { + + use vbs::version::Version; + + use serde::{de, Deserialize, Deserializer, Serializer}; + + pub fn serialize(ver: &Version, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&ver.to_string()) + } + + pub fn deserialize<'de, D>(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let version_str = String::deserialize(deserializer)?; + + let version: Vec<_> = version_str.split('.').collect(); + + let version = Version { + major: version[0] + .parse() + .map_err(|_| de::Error::custom("invalid version format"))?, + minor: version[1] + .parse() + .map_err(|_| de::Error::custom("invalid version format"))?, + }; + + Ok(version) + } +} + +mod upgrade_ser { use std::{collections::BTreeMap, fmt}; @@ -142,8 +180,12 @@ mod upgrade_serialization { let version: Vec<_> = fields.version.split('.').collect(); let version = Version { - major: version[0].parse().expect("invalid version"), - minor: version[1].parse().expect("invalid version"), + major: version[0] + .parse() + .map_err(|_| de::Error::custom("invalid version format"))?, + minor: version[1] + .parse() + .map_err(|_| de::Error::custom("invalid version format"))?, }; match (fields.time_based, fields.view_based) { @@ -230,6 +272,9 @@ mod test { #[test] fn test_genesis_from_toml_with_optional_fields() { let toml = toml! { + base_version = "0.1" + upgrade_version = "0.2" + [stake_table] capacity = 10 @@ -305,6 +350,9 @@ mod test { #[test] fn test_genesis_from_toml_without_optional_fields() { let toml = toml! { + base_version = "0.1" + upgrade_version = "0.2" + [stake_table] capacity = 10 @@ -345,6 +393,9 @@ mod test { #[test] fn test_genesis_l1_finalized_number_only() { let toml = toml! { + base_version = "0.1" + upgrade_version = "0.2" + [stake_table] capacity = 10 @@ -372,6 +423,9 @@ mod test { #[test] fn test_genesis_from_toml_units() { let toml = toml! { + base_version = "0.1" + upgrade_version = "0.2" + [stake_table] capacity = 10 @@ -403,6 +457,9 @@ mod test { // without optional fields // with view settings let toml = toml! { + base_version = "0.1" + upgrade_version = "0.2" + [stake_table] capacity = 10 @@ -467,6 +524,9 @@ mod test { // without optional fields // with time settings let toml = toml! { + base_version = "0.1" + upgrade_version = "0.2" + [stake_table] capacity = 10 @@ -533,6 +593,9 @@ mod test { // set both time and view parameters // this should err let toml = toml! { + base_version = "0.1" + upgrade_version = "0.2" + [stake_table] capacity = 10 @@ -579,6 +642,9 @@ mod test { #[test] fn test_marketplace_upgrade_toml() { let toml = toml! { + base_version = "0.1" + upgrade_version = "0.2" + [stake_table] capacity = 10 @@ -617,6 +683,9 @@ mod test { #[test] fn test_marketplace_and_fee_upgrade_toml() { let toml = toml! { + base_version = "0.1" + upgrade_version = "0.2" + [stake_table] capacity = 10 diff --git a/sequencer/src/hotshot_commitment.rs b/sequencer/src/hotshot_commitment.rs index 3b220e02aa..ba9f291ac5 100644 --- a/sequencer/src/hotshot_commitment.rs +++ b/sequencer/src/hotshot_commitment.rs @@ -22,7 +22,7 @@ use crate::SeqTypes; const RETRY_DELAY: Duration = Duration::from_secs(1); -type HotShotClient = surf_disco::Client; +type HotShotClient = surf_disco::Client; #[derive(Clone, Debug)] pub struct CommitmentTaskOptions { @@ -62,9 +62,9 @@ pub struct CommitmentTaskOptions { } /// main logic for the commitment task, which sync the latest blocks from HotShot to L1 contracts -pub async fn run_hotshot_commitment_task(opt: &CommitmentTaskOptions) { +pub async fn run_hotshot_commitment_task(opt: &CommitmentTaskOptions) { // init a client connecting to HotShot query service - let hotshot = HotShotClient::::builder( + let hotshot = HotShotClient::::builder( opt.query_service_url .clone() .expect("query service URL must be specified"), @@ -87,8 +87,8 @@ pub async fn run_hotshot_commitment_task(opt: &Commitmen sequence(hotshot, contract, opt.delay).await; } -async fn sequence( - hotshot: HotShotClient, +async fn sequence( + hotshot: HotShotClient, contract: HotShot, delay: Option, ) { @@ -147,7 +147,7 @@ trait HotShotDataSource { } #[async_trait] -impl HotShotDataSource for HotShotClient { +impl HotShotDataSource for HotShotClient { type Error = hotshot_query_service::Error; async fn block_height(&self) -> Result { diff --git a/sequencer/src/lib.rs b/sequencer/src/lib.rs index b91684f5dc..4ed26806b4 100644 --- a/sequencer/src/lib.rs +++ b/sequencer/src/lib.rs @@ -16,7 +16,7 @@ use catchup::StatePeers; use context::SequencerContext; use espresso_types::{ BackoffParams, L1Client, NodeState, PubKey, SeqTypes, SolverAuctionResultsProvider, - UpgradeVersion, ValidatedState, + ValidatedState, }; use ethers::types::U256; #[cfg(feature = "libp2p")] @@ -59,7 +59,7 @@ use hotshot_types::{ traits::{ metrics::Metrics, network::{ConnectedNetwork, Topic}, - node_implementation::{NodeImplementation, NodeType}, + node_implementation::{NodeImplementation, NodeType, Versions}, signature_key::{BuilderSignatureKey, StakeTableEntryType}, }, utils::BuilderCommitment, @@ -67,7 +67,7 @@ use hotshot_types::{ }; pub use options::Options; use serde::{Deserialize, Serialize}; -use vbs::version::StaticVersionType; +use vbs::version::{StaticVersion, StaticVersionType}; pub mod network; /// The Sequencer node is generic over the hotshot CommChannel. @@ -90,6 +90,8 @@ impl, P: SequencerPersistence> Clone for Node } } +pub type SequencerApiVersion = StaticVersion<0, 1>; + impl, P: SequencerPersistence> NodeImplementation for Node { @@ -127,17 +129,17 @@ pub struct L1Params { } #[allow(clippy::too_many_arguments)] -pub async fn init_node( +pub async fn init_node( genesis: Genesis, network_params: NetworkParams, metrics: &dyn Metrics, persistence_opt: P, l1_params: L1Params, - bind_version: Ver, + seq_versions: V, is_da: bool, identity: Identity, marketplace_config: MarketplaceConfig>, -) -> anyhow::Result> { +) -> anyhow::Result> { // Expose git information via status API. metrics .text_family( @@ -233,7 +235,8 @@ pub async fn init_node( // If we were told to fetch the config from an already-started peer, do so. (None, Some(peers)) => { tracing::info!(?peers, "loading network config from peers"); - let peers = StatePeers::::from_urls(peers, network_params.catchup_backoff); + let peers = + StatePeers::::from_urls(peers, network_params.catchup_backoff); let config = peers.fetch_config(my_config.clone()).await; tracing::info!( @@ -272,7 +275,7 @@ pub async fn init_node( } }; - if let Some(upgrade) = genesis.upgrades.get(&UpgradeVersion::VERSION) { + if let Some(upgrade) = genesis.upgrades.get(&V::Upgrade::VERSION) { upgrade.set_hotshot_config_parameters(&mut config.config); } @@ -385,7 +388,7 @@ pub async fn init_node( l1_genesis, peers: catchup::local_and_remote( persistence_opt, - StatePeers::::from_urls( + StatePeers::::from_urls( network_params.state_peers, network_params.catchup_backoff, ), @@ -393,7 +396,7 @@ pub async fn init_node( .await, node_id: node_index, upgrades: genesis.upgrades, - current_version: Ver::VERSION, + current_version: V::Base::VERSION, }; let mut ctx = SequencerContext::init( @@ -405,7 +408,7 @@ pub async fn init_node( metrics, genesis.stake_table.capacity, network_params.public_api_url, - bind_version, + seq_versions, marketplace_config, ) .await?; @@ -428,7 +431,7 @@ pub mod testing { eth_signature_key::EthKeyPair, mock::MockStateCatchup, v0::traits::{PersistenceOptions, StateCatchup}, - Event, FeeAccount, PubKey, SeqTypes, Transaction, Upgrade, UpgradeVersion, + Event, FeeAccount, MockSequencerVersions, PubKey, SeqTypes, Transaction, Upgrade, }; use futures::{ future::join_all, @@ -516,7 +519,10 @@ pub mod testing { } pub fn build(mut self) -> TestConfig { - if let Some(upgrade) = self.upgrades.get(&UpgradeVersion::VERSION) { + if let Some(upgrade) = self + .upgrades + .get(&::Upgrade::VERSION) + { upgrade.set_hotshot_config_parameters(&mut self.config) } @@ -644,10 +650,10 @@ pub mod testing { self.upgrades.clone() } - pub async fn init_nodes( + pub async fn init_nodes( &self, - bind_version: Ver, - ) -> Vec> { + bind_version: V, + ) -> Vec> { join_all((0..self.num_nodes()).map(|i| async move { self.init_node( i, @@ -685,7 +691,7 @@ pub mod testing { } #[allow(clippy::too_many_arguments)] - pub async fn init_node( + pub async fn init_node( &self, i: usize, mut state: ValidatedState, @@ -693,9 +699,9 @@ pub mod testing { catchup: impl StateCatchup + 'static, metrics: &dyn Metrics, stake_table_capacity: u64, - bind_version: Ver, + bind_version: V, upgrades: BTreeMap, - ) -> SequencerContext { + ) -> SequencerContext { let mut config = self.config.clone(); let my_peer_config = &config.known_nodes_with_stake[i]; let is_da = config.known_da_nodes.contains(my_peer_config); @@ -729,8 +735,9 @@ pub mod testing { state.chain_config.resolve().unwrap_or_default(), L1Client::new(self.l1_url.clone(), 1000), catchup::local_and_remote(persistence_opt.clone(), catchup).await, + V::Base::VERSION, ) - .with_current_version(Ver::version()) + .with_current_version(V::Base::version()) .with_genesis(state) .with_upgrades(upgrades); @@ -807,7 +814,7 @@ pub mod testing { #[cfg(test)] mod test { - use espresso_types::{BaseVersion, Header, NamespaceId, Payload, Transaction}; + use espresso_types::{Header, MockSequencerVersions, NamespaceId, Payload, Transaction}; use futures::StreamExt; use hotshot::types::EventType::Decide; use hotshot_types::{ @@ -825,7 +832,6 @@ mod test { #[async_std::test] async fn test_skeleton_instantiation() { setup_test(); - let ver = BaseVersion::instance(); // Assign `config` so it isn't dropped early. let anvil = AnvilOptions::default().spawn().await; let url = anvil.url(); @@ -838,7 +844,7 @@ mod test { config.set_builder_urls(vec1::vec1![builder_url]); - let handles = config.init_nodes(ver).await; + let handles = config.init_nodes(MockSequencerVersions::new()).await; let handle_0 = &handles[0]; @@ -867,7 +873,6 @@ mod test { setup_test(); let success_height = 30; - let ver = BaseVersion::instance(); // Assign `config` so it isn't dropped early. let anvil = AnvilOptions::default().spawn().await; let url = anvil.url(); @@ -879,7 +884,7 @@ mod test { let (builder_task, builder_url) = run_test_builder::(None).await; config.set_builder_urls(vec1::vec1![builder_url]); - let handles = config.init_nodes(ver).await; + let handles = config.init_nodes(MockSequencerVersions::new()).await; let handle_0 = &handles[0]; diff --git a/sequencer/src/main.rs b/sequencer/src/main.rs index 762bbc6fcd..635279c01b 100644 --- a/sequencer/src/main.rs +++ b/sequencer/src/main.rs @@ -1,10 +1,12 @@ use std::{net::ToSocketAddrs, sync::Arc}; use clap::Parser; -use espresso_types::{BaseVersion, SolverAuctionResultsProvider}; +use espresso_types::{ + FeeVersion, MarketplaceVersion, SequencerVersions, SolverAuctionResultsProvider, V0_1, +}; use futures::future::FutureExt; use hotshot::MarketplaceConfig; -use hotshot_types::traits::metrics::NoMetrics; +use hotshot_types::traits::{metrics::NoMetrics, node_implementation::Versions}; use sequencer::{ api::{self, data_source::DataSourceOptions}, init_node, @@ -18,37 +20,77 @@ async fn main() -> anyhow::Result<()> { let opt = Options::parse(); opt.logging.init(); - let mut modules = opt.modules(); + let modules = opt.modules(); tracing::warn!(?modules, "sequencer starting up"); + let genesis = Genesis::from_file(&opt.genesis_file)?; + tracing::info!(?genesis, "genesis"); + + let base = genesis.base_version; + let upgrade = genesis.upgrade_version; + + match (base, upgrade) { + (V0_1::VERSION, FeeVersion::VERSION) => { + run( + genesis, + modules, + opt, + SequencerVersions::::new(), + ) + .await + } + (FeeVersion::VERSION, MarketplaceVersion::VERSION) => { + run( + genesis, + modules, + opt, + SequencerVersions::::new(), + ) + .await + } + _ => panic!( + "Invalid base ({base}) and upgrade ({upgrade}) versions specified in the toml file." + ), + } +} + +async fn run( + genesis: Genesis, + mut modules: Modules, + opt: Options, + versions: V, +) -> anyhow::Result<()> +where + V: Versions, +{ if let Some(storage) = modules.storage_fs.take() { - init_with_storage(modules, opt, storage, BaseVersion::instance()).await + init_with_storage(genesis, modules, opt, storage, versions).await } else if let Some(storage) = modules.storage_sql.take() { - init_with_storage(modules, opt, storage, BaseVersion::instance()).await + init_with_storage(genesis, modules, opt, storage, versions).await } else { // Persistence is required. If none is provided, just use the local file system. init_with_storage( + genesis, modules, opt, persistence::fs::Options::default(), - BaseVersion::instance(), + versions, ) .await } } -async fn init_with_storage( +async fn init_with_storage( + genesis: Genesis, modules: Modules, opt: Options, storage_opt: S, - bind_version: Ver, + versions: V, ) -> anyhow::Result<()> where S: DataSourceOptions, + V: Versions, { - let genesis = Genesis::from_file(&opt.genesis_file)?; - tracing::info!(?genesis, "genesis"); - let (private_staking_key, private_state_key) = opt.private_keys()?; let l1_params = L1Params { url: opt.l1_provider_url, @@ -129,27 +171,24 @@ where } http_opt - .serve( - move |metrics| { - async move { - init_node( - genesis, - network_params, - &*metrics, - storage_opt, - l1_params, - bind_version, - opt.is_da, - opt.identity, - marketplace_config, - ) - .await - .unwrap() - } - .boxed() - }, - bind_version, - ) + .serve(move |metrics| { + async move { + init_node( + genesis, + network_params, + &*metrics, + storage_opt, + l1_params, + versions, + opt.is_da, + opt.identity, + marketplace_config, + ) + .await + .unwrap() + } + .boxed() + }) .await? } None => { @@ -159,7 +198,7 @@ where &NoMetrics, storage_opt, l1_params, - bind_version, + versions, opt.is_da, opt.identity, marketplace_config, @@ -181,17 +220,19 @@ mod test { use async_std::task::spawn; - use espresso_types::PubKey; + use espresso_types::{MockSequencerVersions, PubKey}; use hotshot_types::{light_client::StateKeyPair, traits::signature_key::SignatureKey}; use portpicker::pick_unused_port; use sequencer::{ api::options::{Http, Status}, genesis::StakeTableConfig, persistence::fs, + SequencerApiVersion, }; use sequencer_utils::test_utils::setup_test; use surf_disco::{error::ClientError, Client, Url}; use tempfile::TempDir; + use vbs::version::Version; use super::*; @@ -213,6 +254,8 @@ mod test { l1_finalized: Default::default(), header: Default::default(), upgrades: Default::default(), + base_version: Version { major: 0, minor: 1 }, + upgrade_version: Version { major: 0, minor: 2 }, }; genesis.to_file(&genesis_file).unwrap(); @@ -237,10 +280,11 @@ mod test { tracing::info!(port, "starting sequencer"); let task = spawn(async move { if let Err(err) = init_with_storage( + genesis, modules, opt, fs::Options::new(tmp.path().into()), - BaseVersion::instance(), + MockSequencerVersions::new(), ) .await { @@ -252,7 +296,7 @@ mod test { // orchestrator. tracing::info!("waiting for API to start"); let url: Url = format!("http://localhost:{port}").parse().unwrap(); - let client = Client::::new(url.clone()); + let client = Client::::new(url.clone()); assert!(client.connect(Some(Duration::from_secs(60))).await); client.get::<()>("healthcheck").send().await.unwrap(); diff --git a/sequencer/src/message_compat_tests.rs b/sequencer/src/message_compat_tests.rs index 884896cda2..ce5715403f 100755 --- a/sequencer/src/message_compat_tests.rs +++ b/sequencer/src/message_compat_tests.rs @@ -17,7 +17,7 @@ use std::path::Path; use committable::Committable; -use espresso_types::{BaseVersion, Leaf, NodeState, PubKey, ValidatedState}; +use espresso_types::{Leaf, NodeState, PubKey, ValidatedState}; use hotshot::traits::election::static_committee::GeneralStaticCommittee; use hotshot_types::{ data::{ @@ -45,13 +45,13 @@ use hotshot_types::{ use jf_vid::VidScheme; use pretty_assertions::assert_eq; use serde_json::Value; -use vbs::{version::Version, BinarySerializer}; - -type Serializer = vbs::Serializer; +use vbs::{ + version::{StaticVersion, StaticVersionType, Version}, + BinarySerializer, +}; -#[async_std::test] #[cfg(feature = "testing")] -async fn test_message_compat() { +async fn test_message_compat(_ver: Ver) { use espresso_types::{Payload, SeqTypes, Transaction}; use hotshot_types::traits::network::Topic; @@ -72,7 +72,11 @@ async fn test_message_compat() { old_version_last_view: ViewNumber::genesis(), new_version_first_view: ViewNumber::genesis(), }; - let leaf = Leaf::genesis(&ValidatedState::default(), &NodeState::mock()).await; + let leaf = Leaf::genesis( + &ValidatedState::default(), + &NodeState::mock().with_current_version(Ver::VERSION), + ) + .await; let block_header = leaf.block_header().clone(); let transaction = Transaction::new(1_u32.into(), vec![1, 2, 3]); let (payload, metadata) = Payload::from_transactions( @@ -239,8 +243,11 @@ async fn test_message_compat() { .map(|kind| Message { kind, sender }) .collect::>>(); + let version_sub_dir = format!("v{}", Ver::VERSION.minor); // Load the expected serialization from the repo. - let data_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("../data"); + let data_dir = Path::new(env!("CARGO_MANIFEST_DIR")) + .join("../data") + .join(version_sub_dir); let expected_bytes = std::fs::read(data_dir.join("messages.json")).unwrap(); let expected: Value = serde_json::from_slice(&expected_bytes).unwrap(); @@ -278,7 +285,7 @@ async fn test_message_compat() { // Ensure the current serialization implementation generates the same binary output as the // committed reference. let expected = std::fs::read(data_dir.join("messages.bin")).unwrap(); - let actual = Serializer::serialize(&messages).unwrap(); + let actual = vbs::Serializer::::serialize(&messages).unwrap(); if actual != expected { // Write the actual output to a file to make it easier to compare with/replace the expected // file if the serialization change was actually intended. @@ -300,6 +307,20 @@ async fn test_message_compat() { } // Ensure the current `Message` type can be parsed from the committed reference binary. - let parsed: Vec> = Serializer::deserialize(&expected).unwrap(); + let parsed: Vec> = vbs::Serializer::::deserialize(&expected).unwrap(); assert_eq!(parsed, messages); } + +#[async_std::test] +async fn test_v1_message_compat() { + test_message_compat(StaticVersion::<0, 1> {}).await; +} + +#[async_std::test] +async fn test_v2_message_compat() { + test_message_compat(StaticVersion::<0, 2> {}).await; +} +#[async_std::test] +async fn test_v3_message_compat() { + test_message_compat(StaticVersion::<0, 3> {}).await; +} diff --git a/sequencer/src/state_signature.rs b/sequencer/src/state_signature.rs index 8488bdddc8..cf4e7e041c 100644 --- a/sequencer/src/state_signature.rs +++ b/sequencer/src/state_signature.rs @@ -38,7 +38,7 @@ pub mod relay_server; const SIGNATURE_STORAGE_CAPACITY: usize = 100; #[derive(Debug)] -pub struct StateSigner { +pub struct StateSigner { /// Key pair for signing a new light client state key_pair: StateKeyPair, @@ -49,10 +49,10 @@ pub struct StateSigner { stake_table_comm: StakeTableCommitmentType, /// The state relay server url - relay_server_client: Option>, + relay_server_client: Option>, } -impl StateSigner { +impl StateSigner { pub fn new(key_pair: StateKeyPair, stake_table_comm: StakeTableCommitmentType) -> Self { Self { key_pair, diff --git a/sequencer/src/state_signature/relay_server.rs b/sequencer/src/state_signature/relay_server.rs index 082482cc9f..de61ba92de 100644 --- a/sequencer/src/state_signature/relay_server.rs +++ b/sequencer/src/state_signature/relay_server.rs @@ -183,16 +183,16 @@ pub struct Options { } /// Set up APIs for relay server -fn define_api( +fn define_api( options: &Options, - _: Ver, -) -> Result, ApiError> + _: ApiVer, +) -> Result, ApiError> where State: 'static + Send + Sync + ReadState + WriteState, ::State: Send + Sync + StateRelayServerDataSource, { let mut api = match &options.api_path { - Some(path) => Api::::from_file(path)?, + Some(path) => Api::::from_file(path)?, None => { let toml: toml::Value = toml::from_str(include_str!( "../../api/state_relay_server.toml" @@ -200,7 +200,7 @@ where .map_err(|err| ApiError::CannotReadToml { reason: err.to_string(), })?; - Api::::new(toml)? + Api::::new(toml)? } }; @@ -214,7 +214,7 @@ where state: lcstate, signature, } = req - .body_auto::(Ver::instance()) + .body_auto::(ApiVer::instance()) .map_err(Error::from_request_error)?; state.post_signature(key, lcstate, signature) } @@ -224,11 +224,11 @@ where Ok(api) } -pub async fn run_relay_server( +pub async fn run_relay_server( shutdown_listener: Option>, threshold: U256, url: Url, - bind_version: Ver, + bind_version: ApiVer, ) -> std::io::Result<()> { let options = Options::default(); diff --git a/types/src/v0/impls/auction.rs b/types/src/v0/impls/auction.rs index 17e94d11bd..550743869a 100644 --- a/types/src/v0/impls/auction.rs +++ b/types/src/v0/impls/auction.rs @@ -1,4 +1,4 @@ -use super::{state::ValidatedState, BaseVersion}; +use super::state::ValidatedState; use crate::{ eth_signature_key::{EthKeyPair, SigningError}, v0_3::{BidTx, BidTxBody, FullNetworkTx, SolverAuctionResults}, @@ -19,6 +19,7 @@ use std::str::FromStr; use thiserror::Error; use tide_disco::error::ServerError; use url::Url; +use vbs::version::StaticVersion; impl FullNetworkTx { /// Proxy for `execute` method of each transaction variant. @@ -279,7 +280,7 @@ impl HasUrls for SolverAuctionResults { } } -type SurfClient = surf_disco::Client; +type SurfClient = surf_disco::Client>; #[derive(Debug, Clone, Eq, PartialEq, Hash)] /// Auction Results provider holding the Url of the solver in order to fetch auction results. diff --git a/types/src/v0/impls/header.rs b/types/src/v0/impls/header.rs index 7c6cdfb2f9..bdf456c4ec 100644 --- a/types/src/v0/impls/header.rs +++ b/types/src/v0/impls/header.rs @@ -24,12 +24,14 @@ use time::OffsetDateTime; use vbs::version::{StaticVersionType, Version}; use crate::{ - v0::header::{EitherOrVersion, VersionedHeader}, + v0::{ + header::{EitherOrVersion, VersionedHeader}, + MarketplaceVersion, + }, v0_1, v0_2, v0_3::{self, ChainConfig, IterableFeeInfo, SolverAuctionResults}, BlockMerkleCommitment, BuilderSignature, FeeAccount, FeeAmount, FeeInfo, FeeMerkleCommitment, - Header, L1BlockInfo, L1Snapshot, Leaf, MarketplaceVersion, NamespaceId, NsTable, SeqTypes, - UpgradeType, + Header, L1BlockInfo, L1Snapshot, Leaf, NamespaceId, NsTable, SeqTypes, UpgradeType, }; use super::{instance_state::NodeState, state::ValidatedState}; diff --git a/types/src/v0/impls/instance_state.rs b/types/src/v0/impls/instance_state.rs index 5ff664c168..38b434f856 100644 --- a/types/src/v0/impls/instance_state.rs +++ b/types/src/v0/impls/instance_state.rs @@ -5,10 +5,9 @@ use crate::{ use hotshot_types::traits::states::InstanceState; use hotshot_types::HotShotConfig; use std::{collections::BTreeMap, sync::Arc}; -use vbs::version::{StaticVersionType, Version}; +use vbs::version::{StaticVersion, StaticVersionType, Version}; use super::state::ValidatedState; -use super::BaseVersion; /// Represents the immutable state of a node. /// @@ -47,6 +46,7 @@ impl NodeState { chain_config: ChainConfig, l1_client: L1Client, catchup: impl StateCatchup + 'static, + current_version: Version, ) -> Self { Self { node_id, @@ -60,17 +60,20 @@ impl NodeState { }, l1_genesis: None, upgrades: Default::default(), - current_version: BaseVersion::version(), + current_version, } } #[cfg(any(test, feature = "testing"))] pub fn mock() -> Self { + use vbs::version::StaticVersion; + Self::new( 0, ChainConfig::default(), L1Client::new("http://localhost:3331".parse().unwrap(), 10000), mock::MockStateCatchup::default(), + StaticVersion::<0, 1>::version(), ) } @@ -110,6 +113,7 @@ impl Default for NodeState { ChainConfig::default(), L1Client::new("http://localhost:3331".parse().unwrap(), 10000), mock::MockStateCatchup::default(), + StaticVersion::<0, 1>::version(), ) } } diff --git a/types/src/v0/mod.rs b/types/src/v0/mod.rs index 1ee0b0c38e..cae27b5ace 100644 --- a/types/src/v0/mod.rs +++ b/types/src/v0/mod.rs @@ -1,3 +1,5 @@ +use std::marker::PhantomData; + use hotshot::traits::election::static_committee::GeneralStaticCommittee; use hotshot_types::{ data::ViewNumber, @@ -19,7 +21,7 @@ pub use impls::{ StateValidationError, }; pub use utils::*; -use vbs::version::StaticVersion; +use vbs::version::{StaticVersion, StaticVersionType}; // This is the single source of truth for minor versions supported by this major version. // @@ -135,25 +137,37 @@ impl NodeType for SeqTypes { type BuilderSignatureKey = FeeAccount; type AuctionResult = SolverAuctionResults; } +#[derive(Clone, Default, Debug, Copy)] +pub struct SequencerVersions { + _pd: PhantomData<(Base, Upgrade)>, +} -#[derive(Debug, Copy, Clone)] -pub struct SequencerVersions; - -impl Versions for SequencerVersions { - type Base = StaticVersion<0, 1>; - type Upgrade = StaticVersion<0, 2>; - type Marketplace = StaticVersion<0, 3>; +impl SequencerVersions { + pub fn new() -> Self { + Self { + _pd: Default::default(), + } + } +} +impl Versions + for SequencerVersions +{ + type Base = Base; + type Upgrade = Upgrade; const UPGRADE_HASH: [u8; 32] = [ 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, ]; + + type Marketplace = MarketplaceVersion; } -/// Type aliases for readability -pub type BaseVersion = ::Base; -pub type UpgradeVersion = ::Upgrade; -pub type MarketplaceVersion = ::Marketplace; +pub type MockSequencerVersions = SequencerVersions, StaticVersion<0, 2>>; + +pub type V0_1 = StaticVersion<0, 1>; +pub type FeeVersion = StaticVersion<0, 2>; +pub type MarketplaceVersion = StaticVersion<0, 3>; pub type Leaf = hotshot_types::data::Leaf; pub type Event = hotshot::types::Event;