Skip to content

Commit

Permalink
dynamic versioning (#1878)
Browse files Browse the repository at this point in the history
* dynamic versioning

* initialize versions from genesis file

* add base and upgrade version serialization

* fix tests

* add slow prefix to test_merklized_state_api

* update demo.toml

* replace v0.1 w marketplace version for dev-rollup

* remove Versions type requirement from node-metrics

* rename ver to apiver

* remove comment

* make panic message clearer

* remove upgrade lock from node-metrics test

* message compat test for each version

* lint

* fix test

* better aliases
  • Loading branch information
imabdulbasit authored Aug 22, 2024
1 parent 232529d commit 18b96df
Show file tree
Hide file tree
Showing 51 changed files with 1,774 additions and 638 deletions.
56 changes: 45 additions & 11 deletions builder/src/bin/permissioned-builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -214,11 +220,12 @@ impl PermissionedBuilderOptions {
}
}
}
#[async_std::main]
async fn main() -> anyhow::Result<()> {
let opt = PermissionedBuilderOptions::parse();
opt.logging.init();

async fn run<V: Versions>(
genesis: Genesis,
opt: PermissionedBuilderOptions,
versions: V,
) -> anyhow::Result<()> {
let (private_staking_key, private_state_key) = opt.private_keys()?;

let l1_params = L1Params {
Expand Down Expand Up @@ -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);
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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::<V0_1, FeeVersion>::new()).await
}
(FeeVersion::VERSION, MarketplaceVersion::VERSION) => {
run(
genesis,
opt,
SequencerVersions::<FeeVersion, MarketplaceVersion>::new(),
)
.await
}
_ => panic!(
"Invalid base ({base}) and upgrade ({upgrade}) versions specified in the toml file."
),
}
}
49 changes: 39 additions & 10 deletions builder/src/bin/permissionless-builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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::<V0_1, FeeVersion>::new()).await
}
(FeeVersion::VERSION, MarketplaceVersion::VERSION) => {
run(
genesis,
opt,
SequencerVersions::<FeeVersion, MarketplaceVersion>::new(),
)
.await
}
_ => panic!(
"Invalid base ({base}) and upgrade ({upgrade}) versions specified in the toml file."
),
}
}

async fn run<V: Versions>(
genesis: Genesis,
opt: NonPermissionedBuilderOptions,
versions: V,
) -> anyhow::Result<()> {
let l1_params = L1Params {
url: opt.l1_provider_url,
events_max_block_range: 10000,
Expand All @@ -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::<V>(genesis.chain_config, l1_params, opt.state_peers).unwrap();

let base_fee = genesis.max_base_fee();

Expand All @@ -136,6 +164,7 @@ async fn main() -> anyhow::Result<()> {
buffer_view_num_count,
txn_timeout_duration,
base_fee,
versions,
)
.await?;

Expand Down
65 changes: 34 additions & 31 deletions builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -98,7 +98,7 @@ pub fn run_builder_api_service(url: Url, source: ProxyGlobalState<SeqTypes>) {
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)]
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -345,11 +345,14 @@ pub mod testing {
}
}

pub async fn init_nodes<P: SequencerPersistence, Ver: StaticVersionType + 'static>(
pub async fn init_nodes<P: SequencerPersistence, V: Versions>(
&self,
bind_version: Ver,
bind_version: V,
options: impl PersistenceOptions<Persistence = P>,
) -> Vec<(Arc<Consensus<network::Memory, P>>, Option<StateSigner<Ver>>)> {
) -> Vec<(
Arc<Consensus<network::Memory, P, V>>,
Option<StateSigner<SequencerApiVersion>>,
)> {
let num_staked_nodes = self.num_staked_nodes();
let mut is_staked = false;
let stake_table_commit = static_stake_table_commitment(
Expand Down Expand Up @@ -379,15 +382,18 @@ pub mod testing {
.await
}

pub async fn init_node<P: SequencerPersistence, Ver: StaticVersionType + 'static>(
pub async fn init_node<P: SequencerPersistence, V: Versions>(
&self,
i: usize,
is_staked: bool,
stake_table_commit: StakeTableCommitmentType,
metrics: &dyn Metrics,
bind_version: Ver,
bind_version: V,
persistence: P,
) -> (Consensus<network::Memory, P>, StateSigner<Ver>) {
) -> (
Consensus<network::Memory, P, V>,
StateSigner<SequencerApiVersion>,
) {
let mut config = self.config.clone();

let num_staked_nodes = self.num_staked_nodes();
Expand All @@ -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");
Expand Down Expand Up @@ -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<P: SequencerPersistence>(
pub fn enable_hotshot_node_event_streaming<P: SequencerPersistence, V: Versions>(
hotshot_events_api_url: Url,
known_nodes_with_stake: Vec<PeerConfig<VerKey>>,
num_non_staking_nodes: usize,
hotshot_context_handle: Arc<Consensus<network::Memory, P>>,
hotshot_context_handle: Arc<Consensus<network::Memory, P, V>>,
) {
// create a event streamer
let events_streamer = Arc::new(RwLock::new(EventsStreamer::new(
Expand Down Expand Up @@ -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<V: Versions>(
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];
Expand All @@ -562,14 +569,15 @@ 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,
Duration::from_millis(2000),
15,
Duration::from_millis(500),
ChainConfig::default().base_fee,
versions,
)
.await
.unwrap();
Expand All @@ -581,25 +589,20 @@ pub mod testing {
}
}

pub struct PermissionedBuilderTestConfig<
P: SequencerPersistence,
Ver: StaticVersionType + 'static,
> {
pub builder_context: BuilderContext<network::Memory, P, Ver>,
pub struct PermissionedBuilderTestConfig<P: SequencerPersistence, V: Versions> {
pub builder_context: BuilderContext<network::Memory, P, V>,
pub fee_account: FeeAccount,
}

impl<P: SequencerPersistence, Ver: StaticVersionType + 'static>
PermissionedBuilderTestConfig<P, Ver>
{
impl<P: SequencerPersistence, V: Versions> PermissionedBuilderTestConfig<P, V> {
pub async fn init_permissioned_builder(
hotshot_handle: Arc<Consensus<network::Memory, P>>,
hotshot_handle: Arc<Consensus<network::Memory, P, V>>,
node_id: u64,
state_signer: Arc<StateSigner<Ver>>,
state_signer: Arc<StateSigner<SequencerApiVersion>>,
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];
Expand Down Expand Up @@ -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;
Expand All @@ -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();

Expand Down
Loading

0 comments on commit 18b96df

Please sign in to comment.