diff --git a/crates/rooch-benchmarks/src/tx.rs b/crates/rooch-benchmarks/src/tx.rs index 03ab575298..f2213b1b76 100644 --- a/crates/rooch-benchmarks/src/tx.rs +++ b/crates/rooch-benchmarks/src/tx.rs @@ -49,11 +49,9 @@ use rooch_sequencer::proxy::SequencerProxy; use rooch_store::RoochStore; use rooch_test_transaction_builder::TestTransactionBuilder; use rooch_types::address::RoochAddress; -use rooch_types::bitcoin::genesis::BitcoinGenesisContext; -use rooch_types::bitcoin::network::Network; -use rooch_types::chain_id::RoochChainID; use rooch_types::crypto::RoochKeyPair; use rooch_types::multichain_id::RoochMultiChainID; +use rooch_types::rooch_network::{BuiltinChainID, RoochNetwork}; use rooch_types::transaction::rooch::RoochTransaction; use rooch_types::transaction::L1BlockWithBody; @@ -77,7 +75,6 @@ pub async fn setup_service( let _ = tracing_subscriber::fmt::try_init(); let actor_system = ActorSystem::global_system(); - let chain_id = RoochChainID::LOCAL; // init storage let (mut moveos_store, rooch_store) = init_storage(datadir)?; @@ -98,12 +95,9 @@ pub async fn setup_service( let _relayer_account = RoochAddress::from(&relayer_keypair.public()); // Init executor - let btc_network = Network::default().to_num(); - let _data_import_flag = false; - - let genesis_ctx = chain_id.genesis_ctx(rooch_account); - let bitcoin_genesis_ctx = BitcoinGenesisContext::new(btc_network); - let genesis: RoochGenesis = RoochGenesis::build(genesis_ctx, bitcoin_genesis_ctx)?; + let mut network: RoochNetwork = BuiltinChainID::Dev.into(); + network.set_sequencer_account(rooch_account.into()); + let genesis: RoochGenesis = RoochGenesis::build(network)?; let root = genesis.init_genesis(&mut moveos_store)?; let executor_actor = diff --git a/crates/rooch-config/src/lib.rs b/crates/rooch-config/src/lib.rs index ce2ad6dedb..d46eb4ed9b 100644 --- a/crates/rooch-config/src/lib.rs +++ b/crates/rooch-config/src/lib.rs @@ -14,8 +14,8 @@ use serde::{Deserialize, Serialize}; use moveos_config::{temp_dir, DataDirPath}; use rooch_types::bitcoin::network::Network; -use rooch_types::chain_id::RoochChainID; use rooch_types::crypto::RoochKeyPair; +use rooch_types::rooch_network::{BuiltinChainID, RoochChainID}; use crate::da_config::DAConfig; use crate::store_config::StoreConfig; @@ -164,7 +164,7 @@ impl RoochOpt { RoochOpt { base_data_dir: Some(random_dir), - chain_id: Some(RoochChainID::LOCAL), + chain_id: Some(BuiltinChainID::Local.into()), store: StoreConfig::default(), port: None, eth_rpc_url: None, diff --git a/crates/rooch-framework-tests/src/binding_test.rs b/crates/rooch-framework-tests/src/binding_test.rs index 7cddd92c7c..85695e965e 100644 --- a/crates/rooch-framework-tests/src/binding_test.rs +++ b/crates/rooch-framework-tests/src/binding_test.rs @@ -18,10 +18,7 @@ use rooch_executor::actor::reader_executor::ReaderExecutorActor; use rooch_executor::actor::{executor::ExecutorActor, messages::ExecuteTransactionResult}; use rooch_genesis::RoochGenesis; use rooch_store::RoochStore; -use rooch_types::address::RoochAddress; -use rooch_types::bitcoin::genesis::BitcoinGenesisContext; -use rooch_types::bitcoin::network::Network; -use rooch_types::chain_id::RoochChainID; +use rooch_types::rooch_network::{BuiltinChainID, RoochNetwork}; use rooch_types::transaction::{L1BlockWithBody, RoochTransaction}; use std::env; use std::path::Path; @@ -42,7 +39,7 @@ pub fn get_data_dir() -> DataDirPath { pub struct RustBindingTest { //we should keep data_dir to make sure the temp dir is not deleted. data_dir: DataDirPath, - sequencer: RoochAddress, + sequencer: AccountAddress, pub executor: ExecutorActor, pub reader_executor: ReaderExecutorActor, root: RootObjectEntity, @@ -66,13 +63,9 @@ impl RustBindingTest { let mut moveos_store = MoveOSStore::mock_moveos_store_with_data_dir(moveos_db_path.as_path())?; let rooch_store = RoochStore::mock_rooch_store(rooch_db_path.as_path())?; - let sequencer = AccountAddress::ONE.into(); - - let genesis = RoochGenesis::build( - RoochChainID::LOCAL.genesis_ctx(sequencer), - BitcoinGenesisContext::new(Network::NetworkTestnet.to_num()), - // BitcoinGenesisContext::new(Network::default().to_num()), - )?; + let network: RoochNetwork = BuiltinChainID::Local.into(); + let sequencer = network.genesis_config.sequencer_account; + let genesis = RoochGenesis::build(network)?; let root = genesis.init_genesis(&mut moveos_store)?; let executor = ExecutorActor::new(root.clone(), moveos_store.clone(), rooch_store.clone())?; @@ -135,7 +128,7 @@ impl RustBindingTest { let tx_hash = l1_block.block.tx_hash(); let tx_size = l1_block.block.tx_size(); TxContext::new( - self.sequencer.into(), + self.sequencer, sequence_number, max_gas_amount, tx_hash, diff --git a/crates/rooch-framework-tests/src/tests/bitcoin_test.rs b/crates/rooch-framework-tests/src/tests/bitcoin_test.rs index b767dc8a46..3bac694bd8 100644 --- a/crates/rooch-framework-tests/src/tests/bitcoin_test.rs +++ b/crates/rooch-framework-tests/src/tests/bitcoin_test.rs @@ -80,6 +80,10 @@ fn test_submit_block() { //RUST_LOG=debug cargo test --release --package rooch-framework-tests --lib -- --include-ignored tests::bitcoin_test::test_utxo_progress #[test] fn test_utxo_progress() { + if cfg!(debug_assertions) { + println!("test_utxo_progress is ignored in debug mode, please run it in release mode"); + return; + } let _ = tracing_subscriber::fmt::try_init(); let mut binding_test = binding_test::RustBindingTest::new().unwrap(); diff --git a/crates/rooch-framework-tests/src/tests/chain_id_test.rs b/crates/rooch-framework-tests/src/tests/chain_id_test.rs index f58e3084dc..d1a883c1c7 100644 --- a/crates/rooch-framework-tests/src/tests/chain_id_test.rs +++ b/crates/rooch-framework-tests/src/tests/chain_id_test.rs @@ -3,7 +3,7 @@ use crate::binding_test; use moveos_types::{module_binding::MoveFunctionCaller, state_resolver::StateResolver}; -use rooch_types::{chain_id::RoochChainID, framework::chain_id::ChainID}; +use rooch_types::{framework::chain_id::ChainID, rooch_network::BuiltinChainID}; #[test] fn test_chain_id() { @@ -15,5 +15,5 @@ fn test_chain_id() { let chain_id_module = binding_test.as_module_binding::(); let chain_id = chain_id_module.chain_id().unwrap(); - assert_eq!(chain_id, RoochChainID::LOCAL.chain_id().id()); + assert_eq!(chain_id, BuiltinChainID::Local.chain_id().id()); } diff --git a/crates/rooch-genesis-builder/src/lib.rs b/crates/rooch-genesis-builder/src/lib.rs index b252a57423..0a417f32c1 100644 --- a/crates/rooch-genesis-builder/src/lib.rs +++ b/crates/rooch-genesis-builder/src/lib.rs @@ -8,21 +8,6 @@ use framework_builder::{Stdlib, StdlibBuildConfig}; use move_package::BuildConfig; use once_cell::sync::Lazy; -pub const ALL_STDLIB_PACKAGE_NAMES: [&str; 5] = [ - "MoveStdlib", - "MoveosStdlib", - "RoochFramework", - "BitcoinMove", - "RoochNursery", -]; - -pub const ALL_STDLIB_PACKAGE_NAMES_STABLE: [&str; 4] = [ - "MoveStdlib", - "MoveosStdlib", - "RoochFramework", - "BitcoinMove", -]; - static STDLIB_BUILD_CONFIGS: Lazy> = Lazy::new(|| { let move_stdlib_path = path_in_crate("../../frameworks/move-stdlib") .canonicalize() diff --git a/crates/rooch-genesis/src/lib.rs b/crates/rooch-genesis/src/lib.rs index 39dcd99d0c..276a66114d 100644 --- a/crates/rooch-genesis/src/lib.rs +++ b/crates/rooch-genesis/src/lib.rs @@ -20,13 +20,11 @@ use rooch_framework::natives::gas_parameter::gas_member::{ FromOnChainGasSchedule, InitialGasSchedule, ToOnChainGasSchedule, }; use rooch_framework::ROOCH_FRAMEWORK_ADDRESS; -use rooch_genesis_builder::{ALL_STDLIB_PACKAGE_NAMES, ALL_STDLIB_PACKAGE_NAMES_STABLE}; use rooch_types::bitcoin::genesis::BitcoinGenesisContext; -use rooch_types::bitcoin::network::Network; use rooch_types::error::GenesisError; use rooch_types::framework::genesis::GenesisContext; +use rooch_types::rooch_network::{BuiltinChainID, RoochNetwork}; use rooch_types::transaction::rooch::RoochTransaction; -use rooch_types::{address::RoochAddress, chain_id::RoochChainID}; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; use std::str::FromStr; @@ -37,19 +35,8 @@ use std::{ }; pub static ROOCH_LOCAL_GENESIS: Lazy = Lazy::new(|| { - // TODO: For now, ROOCH_LOCAL_GENESIS in only used in integration-test. - // There is no need to upgrade framework, so we set sequencer to 0x0. - // Setup sequencer for local genesis if there is only demands. - let mock_sequencer = RoochAddress::from_str("0x0").expect("parse sequencer address failed"); - // genesis for integration test, we need to build the stdlib every time for `private_generic` check - // see moveos/moveos-verifier/src/metadata.rs#L27-L30 - let bitcoin_genesis_ctx = BitcoinGenesisContext::new(Network::NetworkRegtest.to_num()); - RoochGenesis::build_with_option( - RoochChainID::LOCAL.genesis_ctx(mock_sequencer), - bitcoin_genesis_ctx, - BuildOption::Release, - ) - .expect("build rooch genesis failed") + let network: RoochNetwork = BuiltinChainID::Local.into(); + RoochGenesis::build(network).expect("build rooch genesis failed") }); pub struct FrameworksGasParameters { @@ -136,36 +123,30 @@ pub enum BuildOption { } impl RoochGenesis { - pub fn build( - genesis_ctx: GenesisContext, - bitcoin_genesis_ctx: BitcoinGenesisContext, - ) -> Result { - Self::build_with_option(genesis_ctx, bitcoin_genesis_ctx, BuildOption::Release) + pub fn build(network: RoochNetwork) -> Result { + Self::build_with_option(network, BuildOption::Release) } - pub fn build_with_option( - genesis_ctx: GenesisContext, - bitcoin_genesis_ctx: BitcoinGenesisContext, - option: BuildOption, - ) -> Result { + pub fn build_with_option(network: RoochNetwork, option: BuildOption) -> Result { let stdlib = match option { BuildOption::Fresh => Self::build_stdlib()?, BuildOption::Release => Self::load_stdlib()?, }; - //TODO put the stdlib package names to RoochChainID - let stdlib_package_names = if genesis_ctx.chain_id == RoochChainID::LOCAL.chain_id().id() - || genesis_ctx.chain_id == RoochChainID::DEV.chain_id().id() - { - ALL_STDLIB_PACKAGE_NAMES.to_vec() - } else { - ALL_STDLIB_PACKAGE_NAMES_STABLE.to_vec() - }; + let genesis_config = network.genesis_config; + let genesis_ctx = GenesisContext::new( + network.chain_id.id, + genesis_config.timestamp, + genesis_config.sequencer_account, + ); + let bitcoin_genesis_ctx = BitcoinGenesisContext::new(genesis_config.bitcoin_network); + + let stdlib_package_names = genesis_config.stdlib_package_names.clone(); let bundles = stdlib.module_bundles(stdlib_package_names.as_slice())?; let genesis_tx = RoochTransaction::new_genesis_tx( ROOCH_FRAMEWORK_ADDRESS.into(), - genesis_ctx.chain_id, + network.chain_id.id, //merge all the module bundles into one MoveAction::ModuleBundle( bundles @@ -339,24 +320,19 @@ pub fn rooch_framework_error_descriptions() -> &'static [u8] { #[cfg(test)] mod tests { - use move_core_types::account_address::AccountAddress; use moveos_store::MoveOSStore; use moveos_types::moveos_std::move_module::ModuleStore; use moveos_types::state_resolver::{RootObjectResolver, StateResolver}; - use rooch_types::bitcoin::genesis::BitcoinGenesisContext; use rooch_types::bitcoin::network::{BitcoinNetwork, Network}; - use rooch_types::chain_id::{BuiltinChainID, RoochChainID}; + use rooch_types::rooch_network::BuiltinChainID; use crate::FrameworksGasParameters; #[test] fn test_genesis_init() { let _ = tracing_subscriber::fmt::try_init(); - let sequencer = AccountAddress::ONE.into(); - let bitcoin_genesis_ctx = BitcoinGenesisContext::new(Network::NetworkRegtest.to_num()); let genesis = super::RoochGenesis::build_with_option( - RoochChainID::LOCAL.genesis_ctx(sequencer), - bitcoin_genesis_ctx, + BuiltinChainID::Local.into(), crate::BuildOption::Fresh, ) .expect("build rooch genesis failed"); @@ -399,9 +375,6 @@ mod tests { .unwrap() .into_object::() .unwrap(); - assert_eq!( - bitcoin_network.value.network, - Network::NetworkRegtest.to_num() - ); + assert_eq!(bitcoin_network.value.network, Network::Regtest.to_num()); } } diff --git a/crates/rooch-rpc-client/src/client_config.rs b/crates/rooch-rpc-client/src/client_config.rs index ec08e86f2d..92c8aea7e7 100644 --- a/crates/rooch-rpc-client/src/client_config.rs +++ b/crates/rooch-rpc-client/src/client_config.rs @@ -6,7 +6,7 @@ use anyhow::anyhow; use rooch_config::config::Config; use rooch_config::server_config::ServerConfig; use rooch_types::address::RoochAddress; -use rooch_types::chain_id::RoochChainID; +use rooch_types::rooch_network::BuiltinChainID; use serde::Deserialize; use serde::Serialize; use std::fmt::{Display, Formatter, Write}; @@ -93,7 +93,7 @@ impl Env { pub fn new_dev_env() -> Self { Self { - alias: RoochChainID::DEV.chain_name().to_lowercase(), + alias: BuiltinChainID::Dev.chain_name(), rpc: ROOCH_DEV_NET_URL.into(), ws: None, } @@ -101,7 +101,7 @@ impl Env { pub fn new_test_env() -> Self { Self { - alias: RoochChainID::TEST.chain_name().to_lowercase(), + alias: BuiltinChainID::Test.chain_name(), rpc: ROOCH_TEST_NET_URL.into(), ws: None, } @@ -111,7 +111,7 @@ impl Env { impl Default for Env { fn default() -> Self { Env { - alias: RoochChainID::LOCAL.chain_name().to_lowercase(), + alias: BuiltinChainID::Dev.chain_name(), rpc: ServerConfig::default().url(false), ws: None, } diff --git a/crates/rooch-rpc-server/src/lib.rs b/crates/rooch-rpc-server/src/lib.rs index cd042dbac7..e1a273649d 100644 --- a/crates/rooch-rpc-server/src/lib.rs +++ b/crates/rooch-rpc-server/src/lib.rs @@ -6,7 +6,7 @@ use crate::server::rooch_server::RoochServer; use crate::service::aggregate_service::AggregateService; use crate::service::rpc_logger::RpcLogger; use crate::service::rpc_service::RpcService; -use anyhow::{Error, Result}; +use anyhow::{bail, Error, Result}; use coerce::actor::scheduler::timer::Timer; use coerce::actor::{system::ActorSystem, IntoActor}; use hyper::header::HeaderValue; @@ -34,7 +34,6 @@ use rooch_indexer::actor::reader_indexer::IndexerReaderActor; use rooch_indexer::indexer_reader::IndexerReader; use rooch_indexer::proxy::IndexerProxy; use rooch_indexer::IndexerStore; -use rooch_key::key_derive::{generate_new_key_pair, retrieve_key_pair}; use rooch_pipeline_processor::actor::processor::PipelineProcessorActor; use rooch_pipeline_processor::proxy::PipelineProcessorProxy; use rooch_proposer::actor::messages::ProposeBlock; @@ -47,10 +46,8 @@ use rooch_sequencer::actor::sequencer::SequencerActor; use rooch_sequencer::proxy::SequencerProxy; use rooch_store::RoochStore; use rooch_types::address::RoochAddress; -use rooch_types::bitcoin::genesis::BitcoinGenesisContext; -use rooch_types::bitcoin::network::Network; -use rooch_types::crypto::RoochKeyPair; use rooch_types::error::{GenesisError, RoochError}; +use rooch_types::rooch_network::{RoochChainID, RoochNetwork}; use serde_json::json; use std::env; use std::fmt::Debug; @@ -171,14 +168,14 @@ pub async fn start_server(opt: &RoochOpt, server_opt: ServerOpt) -> Result Result { +pub async fn run_start_server(opt: &RoochOpt, server_opt: ServerOpt) -> Result { // We may call `start_server` multiple times in testing scenarios // tracing_subscriber can only be inited once. let _ = tracing_subscriber::fmt::try_init(); let config = ServerConfig::new_with_port(opt.port()); - let chain_id_opt = opt.chain_id.clone().unwrap_or_default(); + let chain_id = opt.chain_id.clone().unwrap_or_default(); let actor_system = ActorSystem::global_system(); @@ -199,37 +196,29 @@ pub async fn run_start_server(opt: &RoochOpt, mut server_opt: ServerOpt) -> Resu || server_opt.proposer_keypair.is_none() || server_opt.relayer_keypair.is_none() { - // only for integration test, generate test key pairs - if chain_id_opt.is_test_or_dev_or_local() { - let result = generate_new_key_pair(None, None, None, None)?; - let kp: RoochKeyPair = - retrieve_key_pair(&result.key_pair_data.private_key_encryption, None)?; - server_opt.sequencer_keypair = Some(kp.copy()); - server_opt.proposer_keypair = Some(kp.copy()); - server_opt.relayer_keypair = Some(kp.copy()); - } else { - return Err(Error::from( - RoochError::InvalidSequencerOrProposerOrRelayerKeyPair, - )); - } + return Err(Error::from( + RoochError::InvalidSequencerOrProposerOrRelayerKeyPair, + )); } let sequencer_keypair = server_opt.sequencer_keypair.unwrap(); let sequencer_account: RoochAddress = (&sequencer_keypair.public()).into(); - let btc_network = opt.btc_network.unwrap_or(Network::default().to_num()); let data_import_flag = opt.data_import_flag; + let genesis_file = arc_base_config.base_data_dir().path().join("genesis"); if root.is_genesis() { - let genesis_ctx = chain_id_opt.genesis_ctx(sequencer_account); - let bitcoin_genesis_ctx = BitcoinGenesisContext::new(btc_network); - let genesis: RoochGenesis = RoochGenesis::build(genesis_ctx, bitcoin_genesis_ctx)?; + let mut network: RoochNetwork = match chain_id { + RoochChainID::Builtin(chain_id) => chain_id.into(), + _ => bail!("Custom chain_id is not supported auto genesis, please use `rooch genesis` to init genesis. "), + }; + //TODO only set sequencer account if the network is local/dev + network.set_sequencer_account(sequencer_account.into()); + let genesis: RoochGenesis = RoochGenesis::build(network)?; root = genesis.init_genesis(&mut moveos_store)?; + genesis.save_to(genesis_file)?; } else { - //TODO if root is not genesis, we should load genesis from store - let genesis_ctx = chain_id_opt.genesis_ctx(sequencer_account); - let bitcoin_genesis_ctx = BitcoinGenesisContext::new(btc_network); - let genesis: RoochGenesis = RoochGenesis::build(genesis_ctx, bitcoin_genesis_ctx)?; + let genesis: RoochGenesis = RoochGenesis::load_from(genesis_file)?; genesis.check_genesis(moveos_store.get_config_store())?; }; diff --git a/crates/rooch-types/src/address.rs b/crates/rooch-types/src/address.rs index c6cf9e8878..e1690025b9 100644 --- a/crates/rooch-types/src/address.rs +++ b/crates/rooch-types/src/address.rs @@ -460,7 +460,7 @@ impl fmt::Display for BitcoinAddress { // Write the Bitcoin address as a hexadecimal string // Default format as bitcoin mainnet address let bitcoin_address = self - .format(network::Network::NetworkBitcoin.to_num()) + .format(network::Network::Bitcoin.to_num()) .map_err(|e| std::fmt::Error::custom(e.to_string()))?; write!(fmt, "{}", bitcoin_address) } @@ -478,7 +478,7 @@ impl BitcoinAddress { } pub fn get_pubkey_address_prefix(network: u8) -> u8 { - if network::Network::NetworkBitcoin.to_num() == network { + if network::Network::Bitcoin.to_num() == network { bitcoin::constants::PUBKEY_ADDRESS_PREFIX_MAIN } else { bitcoin::constants::PUBKEY_ADDRESS_PREFIX_TEST @@ -486,7 +486,7 @@ impl BitcoinAddress { } pub fn get_script_address_prefix(network: u8) -> u8 { - if network::Network::NetworkBitcoin.to_num() == network { + if network::Network::Bitcoin.to_num() == network { bitcoin::constants::SCRIPT_ADDRESS_PREFIX_MAIN } else { bitcoin::constants::SCRIPT_ADDRESS_PREFIX_TEST @@ -571,7 +571,7 @@ impl MoveStructState for BitcoinAddress { impl RoochSupportedAddress for BitcoinAddress { fn random() -> Self { - let bitcoin_network = Network::from(network::Network::NetworkRegtest); + let bitcoin_network = Network::from(network::Network::Regtest); let secp = Secp256k1::new(); let p2pkh_address = Address::p2pkh( @@ -865,7 +865,7 @@ mod test { let bitcoin_address = BitcoinAddress { bytes: bytes.clone(), }; - let address_str = bitcoin_address.format(network::Network::NetworkBitcoin.to_num())?; + let address_str = bitcoin_address.format(network::Network::Bitcoin.to_num())?; println!("test_bitcoin_address bitcoin address {} ", address_str); let maddress = MultiChainAddress::new(RoochMultiChainID::Bitcoin, bytes.clone()); @@ -890,7 +890,7 @@ mod test { let bitcoin_address = BitcoinAddress { bytes: bytes.clone(), }; - let address_str = bitcoin_address.format(network::Network::NetworkBitcoin.to_num())?; + let address_str = bitcoin_address.format(network::Network::Bitcoin.to_num())?; println!( "test_convert_bitcoin_address bitcoin address {} ", address_str @@ -911,8 +911,7 @@ mod test { pub fn test_bitcoin_address_from_str() -> Result<()> { let bitcoin_address_str = "3MSqmLCmL5XW1PbUnabyLtkYdLXePGokCu"; let bitcoin_address = BitcoinAddress::from_str(bitcoin_address_str)?; - let bitcoin_address_format = - bitcoin_address.format(network::Network::NetworkBitcoin.to_num())?; + let bitcoin_address_format = bitcoin_address.format(network::Network::Bitcoin.to_num())?; println!( "test_bitcoin_address_from_str bitcoin address format {} ", bitcoin_address_format diff --git a/crates/rooch-types/src/bitcoin/network.rs b/crates/rooch-types/src/bitcoin/network.rs index b9cdf55993..d68c6f6ef5 100644 --- a/crates/rooch-types/src/bitcoin/network.rs +++ b/crates/rooch-types/src/bitcoin/network.rs @@ -17,10 +17,10 @@ pub const MODULE_NAME: &IdentStr = ident_str!("network"); #[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))] #[repr(u8)] pub enum Network { - NetworkBitcoin = 1, - NetworkTestnet = 2, - NetworkSignet = 3, - NetworkRegtest = 4, + Bitcoin = 1, + Testnet = 2, + Signet = 3, + Regtest = 4, } impl TryFrom for Network { @@ -28,10 +28,10 @@ impl TryFrom for Network { fn try_from(value: u8) -> Result { match value { - 1 => Ok(Network::NetworkBitcoin), - 2 => Ok(Network::NetworkTestnet), - 3 => Ok(Network::NetworkSignet), - 4 => Ok(Network::NetworkRegtest), + 1 => Ok(Network::Bitcoin), + 2 => Ok(Network::Testnet), + 3 => Ok(Network::Signet), + 4 => Ok(Network::Regtest), _ => Err(anyhow::anyhow!("Bitcoin network {} is invalid", value)), } } @@ -43,10 +43,10 @@ impl TryFrom<&str> for Network { fn try_from(value: &str) -> Result { let value = value.to_uppercase(); match value.as_str() { - "bitcoin" => Ok(Network::NetworkBitcoin), - "testnet" => Ok(Network::NetworkTestnet), - "signet" => Ok(Network::NetworkSignet), - "regtest" => Ok(Network::NetworkRegtest), + "bitcoin" => Ok(Network::Bitcoin), + "testnet" => Ok(Network::Testnet), + "signet" => Ok(Network::Signet), + "regtest" => Ok(Network::Regtest), _ => Err(anyhow::anyhow!("Bitcoin network {} is invalid", value)), } } @@ -55,10 +55,10 @@ impl TryFrom<&str> for Network { impl std::fmt::Display for Network { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Network::NetworkBitcoin => write!(f, "bitcoin"), - Network::NetworkTestnet => write!(f, "testnet"), - Network::NetworkSignet => write!(f, "signet"), - Network::NetworkRegtest => write!(f, "regtest"), + Network::Bitcoin => write!(f, "bitcoin"), + Network::Testnet => write!(f, "testnet"), + Network::Signet => write!(f, "signet"), + Network::Regtest => write!(f, "regtest"), } } } @@ -66,10 +66,10 @@ impl std::fmt::Display for Network { impl Network { pub fn bech32_hrp(&self) -> bitcoin::bech32::Hrp { match self { - Network::NetworkBitcoin => bitcoin::bech32::hrp::BC, - Network::NetworkTestnet => bitcoin::bech32::hrp::TB, - Network::NetworkSignet => bitcoin::bech32::hrp::TB, - Network::NetworkRegtest => bitcoin::bech32::hrp::BCRT, + Network::Bitcoin => bitcoin::bech32::hrp::BC, + Network::Testnet => bitcoin::bech32::hrp::TB, + Network::Signet => bitcoin::bech32::hrp::TB, + Network::Regtest => bitcoin::bech32::hrp::BCRT, } } @@ -78,25 +78,25 @@ impl Network { } pub fn is_mainnet(&self) -> bool { - *self == Network::NetworkBitcoin + *self == Network::Bitcoin } } impl Default for Network { // default bitcoin main network fn default() -> Self { - Self::NetworkBitcoin + Self::Bitcoin } } impl From for Network { fn from(network: bitcoin::Network) -> Self { match network { - bitcoin::Network::Bitcoin => Self::NetworkBitcoin, - bitcoin::Network::Testnet => Self::NetworkTestnet, - bitcoin::Network::Signet => Self::NetworkSignet, - bitcoin::Network::Regtest => Self::NetworkRegtest, - _ => Self::NetworkRegtest, + bitcoin::Network::Bitcoin => Self::Bitcoin, + bitcoin::Network::Testnet => Self::Testnet, + bitcoin::Network::Signet => Self::Signet, + bitcoin::Network::Regtest => Self::Regtest, + _ => Self::Regtest, } } } @@ -104,10 +104,10 @@ impl From for Network { impl From for bitcoin::Network { fn from(network: Network) -> Self { match network { - Network::NetworkBitcoin => bitcoin::Network::Bitcoin, - Network::NetworkTestnet => bitcoin::Network::Testnet, - Network::NetworkSignet => bitcoin::Network::Signet, - Network::NetworkRegtest => bitcoin::Network::Regtest, + Network::Bitcoin => bitcoin::Network::Bitcoin, + Network::Testnet => bitcoin::Network::Testnet, + Network::Signet => bitcoin::Network::Signet, + Network::Regtest => bitcoin::Network::Regtest, } } } diff --git a/crates/rooch-types/src/chain_id.rs b/crates/rooch-types/src/chain_id.rs deleted file mode 100644 index c8ea37f5e5..0000000000 --- a/crates/rooch-types/src/chain_id.rs +++ /dev/null @@ -1,449 +0,0 @@ -// Copyright (c) RoochNetwork -// SPDX-License-Identifier: Apache-2.0 - -use crate::address::RoochAddress; -use crate::framework::genesis::GenesisContext; -use anyhow::{bail, format_err, Result}; -use move_core_types::account_address::AccountAddress; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use std::fmt; -use std::fmt::{Display, Formatter}; -use std::str::FromStr; - -pub const CHAIN_ID_LOCAL: u64 = 4; -pub const CHAIN_ID_DEV: u64 = 3; -pub const CHAIN_ID_TEST: u64 = 2; -pub const CHAIN_ID_MAIN: u64 = 1; - -#[derive(Clone, Copy, Debug, Deserialize, Serialize, Hash, Eq, PartialEq, JsonSchema)] -pub struct ChainID { - id: u64, -} - -impl ChainID { - pub fn new(id: u64) -> Self { - Self { id } - } - - pub fn id(self) -> u64 { - self.id - } - - pub fn is_local(self) -> bool { - self.id == CHAIN_ID_LOCAL - } - - pub fn is_dev(self) -> bool { - self.id == CHAIN_ID_DEV - } - - pub fn is_test(self) -> bool { - self.id == CHAIN_ID_TEST - } - - pub fn is_main(self) -> bool { - self.id == CHAIN_ID_MAIN - } -} - -impl Display for ChainID { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.id) - } -} - -impl FromStr for ChainID { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - let id: u64 = s.parse()?; - Ok(ChainID::new(id)) - } -} - -impl From for ChainID { - fn from(id: u64) -> Self { - Self::new(id) - } -} - -#[allow(clippy::from_over_into)] -impl Into for ChainID { - fn into(self) -> u64 { - self.id - } -} - -#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)] -#[repr(u64)] -pub enum BuiltinChainID { - /// A temp network just for developer test. - /// The data is stored in the temporary directory and will be cleared after restarting. - #[default] - Local = CHAIN_ID_LOCAL, - /// A ephemeral network just for developer test. - Dev = CHAIN_ID_DEV, - /// Rooch test network. - /// The data on the chain will be cleaned up periodically. - Test = CHAIN_ID_TEST, - /// Rooch main net. - Main = CHAIN_ID_MAIN, -} - -impl Display for BuiltinChainID { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self { - BuiltinChainID::Local => write!(f, "local"), - BuiltinChainID::Dev => write!(f, "dev"), - BuiltinChainID::Test => write!(f, "test"), - BuiltinChainID::Main => write!(f, "main"), - } - } -} - -impl From for u64 { - fn from(chain_id: BuiltinChainID) -> Self { - chain_id as u64 - } -} - -impl TryFrom for BuiltinChainID { - type Error = anyhow::Error; - - fn try_from(value: u64) -> Result { - match value { - CHAIN_ID_LOCAL => Ok(BuiltinChainID::Local), - CHAIN_ID_DEV => Ok(BuiltinChainID::Dev), - CHAIN_ID_TEST => Ok(BuiltinChainID::Test), - CHAIN_ID_MAIN => Ok(BuiltinChainID::Main), - _ => Err(anyhow::anyhow!("chain id {} is invalid", value)), - } - } -} - -impl FromStr for BuiltinChainID { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - match s { - "local" => Ok(BuiltinChainID::Local), - "dev" => Ok(BuiltinChainID::Dev), - "test" => Ok(BuiltinChainID::Test), - "main" => Ok(BuiltinChainID::Main), - s => Err(format_err!("Unknown chain: {}", s)), - } - } -} - -impl TryFrom for BuiltinChainID { - type Error = anyhow::Error; - fn try_from(id: ChainID) -> Result { - Ok(match id.id() { - CHAIN_ID_LOCAL => Self::Local, - CHAIN_ID_DEV => Self::Dev, - CHAIN_ID_TEST => Self::Test, - CHAIN_ID_MAIN => Self::Main, - id => bail!("{} is not a builtin chain id", id), - }) - } -} - -impl BuiltinChainID { - pub fn chain_name(self) -> String { - self.to_string() - } - - pub fn chain_id(self) -> ChainID { - ChainID::new(self.into()) - } - - pub fn is_local(self) -> bool { - matches!(self, BuiltinChainID::Local) - } - - pub fn is_dev(self) -> bool { - matches!(self, BuiltinChainID::Dev) - } - - pub fn is_test(self) -> bool { - matches!(self, BuiltinChainID::Test) - } - - pub fn assert_test_or_dev_or_local(self) -> Result<()> { - if !self.is_test_or_dev_or_local() { - bail!("Only support test or dev or local network.") - } - Ok(()) - } - - pub fn is_test_or_dev_or_local(self) -> bool { - matches!( - self, - BuiltinChainID::Test | BuiltinChainID::Dev | BuiltinChainID::Local - ) - } - - pub fn is_main(self) -> bool { - matches!(self, BuiltinChainID::Main) - } - - pub fn chain_ids() -> Vec { - vec![ - BuiltinChainID::Local, - BuiltinChainID::Dev, - BuiltinChainID::Test, - BuiltinChainID::Main, - ] - } - - pub fn genesis_ctx(&self, sequencer: RoochAddress) -> GenesisContext { - let chain_id = self.chain_id().id; - let sequencer_account = AccountAddress::from(sequencer); - match self { - BuiltinChainID::Local => { - //Local timestamp from 0, developer can manually set the timestamp - let timestamp = 0; - GenesisContext::new(chain_id, timestamp, sequencer_account) - } - BuiltinChainID::Dev => { - //Dev network start from Ethereum block height 9685149, timestamp: 1694571540 - let timestamp = std::time::Duration::from_secs(1694571540).as_micros() as u64; - GenesisContext::new(chain_id, timestamp, sequencer_account) - } - BuiltinChainID::Test => { - //Test network start from Ethereum block height 9685149, timestamp: 1694571540 - let timestamp = std::time::Duration::from_secs(1694571540).as_micros() as u64; - GenesisContext::new(chain_id, timestamp, sequencer_account) - } - BuiltinChainID::Main => { - //TODO config main network genesis timestamp - let timestamp = 0; - GenesisContext::new(chain_id, timestamp, sequencer_account) - } - } - } -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, Serialize, JsonSchema)] -#[allow(clippy::upper_case_acronyms)] -pub struct CustomChainID { - chain_name: String, - chain_id: ChainID, -} - -impl Display for CustomChainID { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "{}:{}", self.chain_name, self.chain_id) - } -} - -impl CustomChainID { - fn new(chain_name: String, chain_id: ChainID) -> Self { - Self { - chain_name, - chain_id, - } - } - - pub fn chain_id(&self) -> ChainID { - self.chain_id - } - - pub fn chain_name(&self) -> &str { - self.chain_name.as_str() - } - - pub fn genesis_ctx(&self, sequencer: RoochAddress) -> GenesisContext { - //TODO support custom chain genesis timestamp - let timestamp = 0; - let sequencer_account = AccountAddress::from(sequencer); - GenesisContext::new(self.chain_id.id, timestamp, sequencer_account) - } -} - -impl FromStr for CustomChainID { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - let parts: Vec<&str> = s.split(':').collect(); - if parts.len() != 2 { - bail!( - "Invalid Custom chain id {}, custom chain id format is: chain_name:chain_id", - s - ); - } - let chain_name = parts[0].to_string(); - let chain_id = ChainID::from_str(parts[1])?; - Ok(Self::new(chain_name, chain_id)) - } -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash, JsonSchema, Serialize, Deserialize)] -#[allow(clippy::upper_case_acronyms)] -pub enum RoochChainID { - Builtin(BuiltinChainID), - Custom(CustomChainID), -} - -impl Display for RoochChainID { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let name = match self { - Self::Builtin(b) => b.to_string(), - Self::Custom(c) => c.to_string(), - }; - write!(f, "{}", name) - } -} - -impl From for RoochChainID { - fn from(chain_id: BuiltinChainID) -> Self { - RoochChainID::Builtin(chain_id) - } -} - -impl From for RoochChainID { - fn from(chain_id: CustomChainID) -> Self { - RoochChainID::Custom(chain_id) - } -} - -impl TryFrom for RoochChainID { - type Error = anyhow::Error; - - fn try_from(chain_id: ChainID) -> Result { - Ok(match chain_id.id() { - CHAIN_ID_LOCAL => RoochChainID::LOCAL, - CHAIN_ID_DEV => RoochChainID::DEV, - CHAIN_ID_TEST => RoochChainID::TEST, - CHAIN_ID_MAIN => RoochChainID::MAIN, - id => RoochChainID::Custom(CustomChainID::from_str(id.to_string().as_str())?), - }) - } -} - -impl FromStr for RoochChainID { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - match BuiltinChainID::from_str(s) { - Ok(chain_id) => Ok(Self::Builtin(chain_id)), - Err(_e) => Ok(Self::Custom(CustomChainID::from_str(s)?)), - } - } -} - -impl RoochChainID { - pub const LOCAL: RoochChainID = RoochChainID::Builtin(BuiltinChainID::Local); - pub const DEV: RoochChainID = RoochChainID::Builtin(BuiltinChainID::Dev); - pub const TEST: RoochChainID = RoochChainID::Builtin(BuiltinChainID::Test); - pub const MAIN: RoochChainID = RoochChainID::Builtin(BuiltinChainID::Main); - - pub fn new_builtin(chain_id: BuiltinChainID) -> Self { - Self::Builtin(chain_id) - } - - pub fn new_custom(chain_name: String, chain_id: ChainID) -> Result { - for builtin_chain_id in BuiltinChainID::chain_ids() { - if builtin_chain_id.chain_id() == chain_id { - bail!( - "Chain id {} has used for builtin {}", - chain_id, - builtin_chain_id - ); - } - if builtin_chain_id.chain_name() == chain_name { - bail!( - "Chain name {} has used for builtin {}", - chain_name, - builtin_chain_id - ); - } - } - Ok(Self::Custom(CustomChainID::new(chain_name, chain_id))) - } - - pub fn chain_name(&self) -> String { - match self { - Self::Builtin(b) => b.chain_name(), - Self::Custom(c) => c.chain_name().to_owned(), - } - } - - pub fn chain_id(&self) -> ChainID { - match self { - Self::Builtin(b) => b.chain_id(), - Self::Custom(c) => c.chain_id(), - } - } - - pub fn genesis_ctx(&self, sequencer: RoochAddress) -> GenesisContext { - match self { - Self::Builtin(b) => b.genesis_ctx(sequencer), - Self::Custom(c) => c.genesis_ctx(sequencer), - } - } - - pub fn assert_test_or_dev_or_local(&self) -> Result<()> { - if !self.is_test_or_dev_or_local() { - bail!("Only support test or dev or local chain_id.") - } - Ok(()) - } - - pub fn is_builtin(&self) -> bool { - self.is_test() || self.is_dev() || self.is_main() - } - - pub fn is_test_or_dev_or_local(&self) -> bool { - self.is_test() || self.is_dev() || self.is_local() - } - - pub fn is_local(&self) -> bool { - matches!(self, Self::Builtin(BuiltinChainID::Local)) - } - - pub fn is_dev(&self) -> bool { - matches!(self, Self::Builtin(BuiltinChainID::Dev)) - } - - pub fn is_test(&self) -> bool { - matches!(self, Self::Builtin(BuiltinChainID::Test)) - } - - pub fn is_main(&self) -> bool { - matches!(self, Self::Builtin(BuiltinChainID::Main)) - } - - pub fn is_custom(&self) -> bool { - matches!(self, Self::Custom(_)) - } - - /// Default data dir name of this chain_id - pub fn dir_name(&self) -> String { - match self { - Self::Builtin(b) => b.chain_name().to_lowercase(), - Self::Custom(c) => c.chain_name().to_string().to_lowercase(), - } - } - - pub fn as_builtin(&self) -> Option<&BuiltinChainID> { - match self { - Self::Builtin(b) => Some(b), - _ => None, - } - } - - pub fn as_custom(&self) -> Option<&CustomChainID> { - match self { - Self::Custom(c) => Some(c), - _ => None, - } - } -} - -impl Default for RoochChainID { - fn default() -> Self { - RoochChainID::Builtin(BuiltinChainID::default()) - } -} diff --git a/crates/rooch-types/src/framework/chain_id.rs b/crates/rooch-types/src/framework/chain_id.rs index 55795f9279..51167299ae 100644 --- a/crates/rooch-types/src/framework/chain_id.rs +++ b/crates/rooch-types/src/framework/chain_id.rs @@ -1,6 +1,8 @@ // Copyright (c) RoochNetwork // SPDX-License-Identifier: Apache-2.0 +use std::str::FromStr; + use crate::addresses::ROOCH_FRAMEWORK_ADDRESS; use anyhow::Result; use move_core_types::{account_address::AccountAddress, ident_str, identifier::IdentStr}; @@ -13,21 +15,51 @@ use moveos_types::{ state::{MoveStructState, MoveStructType}, transaction::FunctionCall, }; +use schemars::JsonSchema; use serde::{Deserialize, Serialize}; pub const MODULE_NAME: &IdentStr = ident_str!("chain_id"); -#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] +#[derive(Debug, Clone, Hash, Serialize, Deserialize, Eq, PartialEq, JsonSchema)] pub struct ChainID { pub id: u64, } impl ChainID { + pub fn new(id: u64) -> Self { + ChainID { id } + } + + pub fn id(&self) -> u64 { + self.id + } + pub fn chain_id_object_id() -> ObjectID { object::named_object_id(&Self::struct_tag()) } } +impl std::fmt::Display for ChainID { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.id) + } +} + +impl FromStr for ChainID { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + let id: u64 = s.parse()?; + Ok(Self::new(id)) + } +} + +impl From for ChainID { + fn from(id: u64) -> Self { + Self::new(id) + } +} + impl MoveStructType for ChainID { const ADDRESS: AccountAddress = ROOCH_FRAMEWORK_ADDRESS; const MODULE_NAME: &'static IdentStr = MODULE_NAME; diff --git a/crates/rooch-types/src/genesis_config.rs b/crates/rooch-types/src/genesis_config.rs new file mode 100644 index 0000000000..b96e4aade3 --- /dev/null +++ b/crates/rooch-types/src/genesis_config.rs @@ -0,0 +1,99 @@ +// Copyright (c) RoochNetwork +// SPDX-License-Identifier: Apache-2.0 + +use ethers::types::H256; +use move_core_types::{account_address::AccountAddress, language_storage::StructTag}; +use moveos_types::moveos_std::object::ObjectID; +use once_cell::sync::Lazy; +use serde::{Deserialize, Serialize}; + +pub const ALL_STDLIB_PACKAGE_NAMES: [&str; 5] = [ + "MoveStdlib", + "MoveosStdlib", + "RoochFramework", + "BitcoinMove", + "RoochNursery", +]; + +pub const ALL_STDLIB_PACKAGE_NAMES_STABLE: [&str; 4] = [ + "MoveStdlib", + "MoveosStdlib", + "RoochFramework", + "BitcoinMove", +]; + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub struct GenesisObject { + pub id: ObjectID, + pub object_type: StructTag, + pub state_root: H256, + pub size: u64, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub struct GenesisConfig { + pub bitcoin_network: u8, + pub bitcoin_block_height: u64, + pub timestamp: u64, + pub sequencer_account: AccountAddress, + pub genesis_objects: Vec, + pub stdlib_package_names: Vec, +} + +pub static G_LOCAL_CONFIG: Lazy = Lazy::new(|| GenesisConfig { + bitcoin_network: crate::bitcoin::network::Network::Regtest.to_num(), + bitcoin_block_height: 0, + timestamp: 0, + sequencer_account: AccountAddress::ONE, + genesis_objects: vec![], + stdlib_package_names: ALL_STDLIB_PACKAGE_NAMES + .iter() + .copied() + .map(|s| s.to_owned()) + .collect(), +}); + +pub static G_DEV_CONFIG: Lazy = Lazy::new(|| GenesisConfig { + bitcoin_network: crate::bitcoin::network::Network::Testnet.to_num(), + bitcoin_block_height: 0, + timestamp: 0, + sequencer_account: AccountAddress::ONE, + genesis_objects: vec![], + stdlib_package_names: ALL_STDLIB_PACKAGE_NAMES + .iter() + .copied() + .map(|s| s.to_owned()) + .collect(), +}); + +pub static G_TEST_CONFIG: Lazy = Lazy::new(|| { + //TODO define test config + GenesisConfig { + bitcoin_network: crate::bitcoin::network::Network::Testnet.to_num(), + bitcoin_block_height: 0, + timestamp: 0, + sequencer_account: AccountAddress::ONE, + genesis_objects: vec![], + stdlib_package_names: ALL_STDLIB_PACKAGE_NAMES_STABLE + .iter() + .copied() + .map(|s| s.to_owned()) + .collect(), + } +}); + +pub static G_MAIN_CONFIG: Lazy = Lazy::new(|| { + //TODO define main config + GenesisConfig { + bitcoin_network: crate::bitcoin::network::Network::Bitcoin.to_num(), + bitcoin_block_height: 0, + timestamp: 0, + sequencer_account: AccountAddress::ONE, + genesis_objects: vec![], + stdlib_package_names: ALL_STDLIB_PACKAGE_NAMES_STABLE + .iter() + .copied() + .map(|s| s.to_owned()) + .collect(), + } +}); diff --git a/crates/rooch-types/src/lib.rs b/crates/rooch-types/src/lib.rs index 101f78f2a6..7b09c8f246 100644 --- a/crates/rooch-types/src/lib.rs +++ b/crates/rooch-types/src/lib.rs @@ -6,16 +6,17 @@ pub mod addresses; pub mod authentication_key; pub mod bitcoin; pub mod block; -pub mod chain_id; pub mod coin_type; pub mod crypto; pub mod error; pub mod framework; pub mod function_arg; +pub mod genesis_config; pub mod indexer; pub mod into_address; pub mod key_struct; pub mod multichain_id; +pub mod rooch_network; pub mod sequencer; pub mod stdlib_version; pub mod test_utils; diff --git a/crates/rooch-types/src/multichain_id.rs b/crates/rooch-types/src/multichain_id.rs index e1d18dfb6e..5014f56a64 100644 --- a/crates/rooch-types/src/multichain_id.rs +++ b/crates/rooch-types/src/multichain_id.rs @@ -13,8 +13,6 @@ use std::fmt; use std::fmt::{Display, Formatter}; use std::str::FromStr; -use crate::chain_id::ChainID; - pub const BITCOIN: u64 = 0; pub const ETHER: u64 = 60; pub const SUI: u64 = 784; @@ -87,12 +85,6 @@ impl From for MultiChainID { } } -impl From for MultiChainID { - fn from(chain_id: ChainID) -> Self { - Self::new(chain_id.id()) - } -} - #[allow(clippy::from_over_into)] impl Into for MultiChainID { fn into(self) -> u64 { diff --git a/crates/rooch-types/src/rooch_network.rs b/crates/rooch-types/src/rooch_network.rs new file mode 100644 index 0000000000..ea03c9ef58 --- /dev/null +++ b/crates/rooch-types/src/rooch_network.rs @@ -0,0 +1,292 @@ +// Copyright (c) RoochNetwork +// SPDX-License-Identifier: Apache-2.0 + +use crate::framework::chain_id::ChainID; +use crate::genesis_config::{self, GenesisConfig}; +use anyhow::{bail, format_err, Result}; +use move_core_types::account_address::AccountAddress; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use std::fmt; +use std::fmt::{Display, Formatter}; +use std::str::FromStr; + +pub const CHAIN_ID_LOCAL: u64 = 4; +pub const CHAIN_ID_DEV: u64 = 3; +pub const CHAIN_ID_TEST: u64 = 2; +pub const CHAIN_ID_MAIN: u64 = 1; + +#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)] +#[repr(u64)] +pub enum BuiltinChainID { + /// A temp network just for developer test. + /// The data is stored in the temporary directory and will be cleared after restarting. + #[default] + Local = CHAIN_ID_LOCAL, + /// A ephemeral network just for developer test. + Dev = CHAIN_ID_DEV, + /// Rooch test network. + /// The data on the chain will be cleaned up periodically. + Test = CHAIN_ID_TEST, + /// Rooch main net. + Main = CHAIN_ID_MAIN, +} + +impl Display for BuiltinChainID { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + BuiltinChainID::Local => write!(f, "local"), + BuiltinChainID::Dev => write!(f, "dev"), + BuiltinChainID::Test => write!(f, "test"), + BuiltinChainID::Main => write!(f, "main"), + } + } +} + +impl From for u64 { + fn from(chain_id: BuiltinChainID) -> Self { + chain_id as u64 + } +} + +impl TryFrom for BuiltinChainID { + type Error = anyhow::Error; + + fn try_from(value: u64) -> Result { + match value { + CHAIN_ID_LOCAL => Ok(BuiltinChainID::Local), + CHAIN_ID_DEV => Ok(BuiltinChainID::Dev), + CHAIN_ID_TEST => Ok(BuiltinChainID::Test), + CHAIN_ID_MAIN => Ok(BuiltinChainID::Main), + _ => Err(anyhow::anyhow!("chain id {} is invalid", value)), + } + } +} + +impl FromStr for BuiltinChainID { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + match s { + "local" => Ok(BuiltinChainID::Local), + "dev" => Ok(BuiltinChainID::Dev), + "test" => Ok(BuiltinChainID::Test), + "main" => Ok(BuiltinChainID::Main), + s => Err(format_err!("Unknown chain: {}", s)), + } + } +} + +impl TryFrom for BuiltinChainID { + type Error = anyhow::Error; + fn try_from(id: ChainID) -> Result { + Ok(match id.id() { + CHAIN_ID_LOCAL => Self::Local, + CHAIN_ID_DEV => Self::Dev, + CHAIN_ID_TEST => Self::Test, + CHAIN_ID_MAIN => Self::Main, + id => bail!("{} is not a builtin chain id", id), + }) + } +} + +impl From for ChainID { + fn from(chain_id: BuiltinChainID) -> Self { + ChainID::new(chain_id.into()) + } +} + +impl BuiltinChainID { + pub fn chain_name(self) -> String { + self.to_string().to_lowercase() + } + + pub fn chain_id(self) -> ChainID { + ChainID::new(self.into()) + } + + pub fn is_local(self) -> bool { + matches!(self, BuiltinChainID::Local) + } + + pub fn is_dev(self) -> bool { + matches!(self, BuiltinChainID::Dev) + } + + pub fn is_test(self) -> bool { + matches!(self, BuiltinChainID::Test) + } + + pub fn assert_test_or_dev_or_local(self) -> Result<()> { + if !self.is_test_or_dev_or_local() { + bail!("Only support test or dev or local network.") + } + Ok(()) + } + + pub fn is_test_or_dev_or_local(self) -> bool { + matches!( + self, + BuiltinChainID::Test | BuiltinChainID::Dev | BuiltinChainID::Local + ) + } + + pub fn is_main(self) -> bool { + matches!(self, BuiltinChainID::Main) + } + + pub fn chain_ids() -> Vec { + vec![ + BuiltinChainID::Local, + BuiltinChainID::Dev, + BuiltinChainID::Test, + BuiltinChainID::Main, + ] + } + + pub fn genesis_config(&self) -> &GenesisConfig { + match self { + BuiltinChainID::Local => &genesis_config::G_LOCAL_CONFIG, + BuiltinChainID::Dev => &genesis_config::G_DEV_CONFIG, + BuiltinChainID::Test => &genesis_config::G_TEST_CONFIG, + BuiltinChainID::Main => &genesis_config::G_MAIN_CONFIG, + } + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[allow(clippy::upper_case_acronyms)] +pub enum RoochChainID { + Builtin(BuiltinChainID), + Custom(ChainID), +} + +impl Display for RoochChainID { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let name = match self { + Self::Builtin(b) => b.to_string(), + Self::Custom(c) => c.to_string(), + }; + write!(f, "{}", name) + } +} + +impl From for RoochChainID { + fn from(chain_id: BuiltinChainID) -> Self { + RoochChainID::Builtin(chain_id) + } +} + +impl From for RoochChainID { + fn from(chain_id: ChainID) -> Self { + match chain_id.id() { + CHAIN_ID_LOCAL => RoochChainID::Builtin(BuiltinChainID::Local), + CHAIN_ID_DEV => RoochChainID::Builtin(BuiltinChainID::Dev), + CHAIN_ID_TEST => RoochChainID::Builtin(BuiltinChainID::Test), + CHAIN_ID_MAIN => RoochChainID::Builtin(BuiltinChainID::Main), + _ => RoochChainID::Custom(chain_id), + } + } +} + +impl FromStr for RoochChainID { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + match BuiltinChainID::from_str(s) { + Ok(chain_id) => Ok(Self::Builtin(chain_id)), + Err(_e) => Ok(Self::Custom(ChainID::from_str(s)?)), + } + } +} + +impl RoochChainID { + pub fn chain_name(&self) -> String { + match self { + Self::Builtin(b) => b.chain_name(), + Self::Custom(c) => c.to_string(), + } + } + + pub fn chain_id(&self) -> ChainID { + match self { + Self::Builtin(b) => b.chain_id(), + Self::Custom(c) => c.clone(), + } + } + + pub fn assert_test_or_dev_or_local(&self) -> Result<()> { + if !self.is_test_or_dev_or_local() { + bail!("Only support test or dev or local chain_id.") + } + Ok(()) + } + + pub fn is_builtin(&self) -> bool { + self.is_test() || self.is_dev() || self.is_main() + } + + pub fn is_test_or_dev_or_local(&self) -> bool { + self.is_test() || self.is_dev() || self.is_local() + } + + pub fn is_local(&self) -> bool { + matches!(self, Self::Builtin(BuiltinChainID::Local)) + } + + pub fn is_dev(&self) -> bool { + matches!(self, Self::Builtin(BuiltinChainID::Dev)) + } + + pub fn is_test(&self) -> bool { + matches!(self, Self::Builtin(BuiltinChainID::Test)) + } + + pub fn is_main(&self) -> bool { + matches!(self, Self::Builtin(BuiltinChainID::Main)) + } + + pub fn is_custom(&self) -> bool { + matches!(self, Self::Custom(_)) + } + + /// Default data dir name of this chain_id + pub fn dir_name(&self) -> String { + self.chain_name() + } +} + +impl Default for RoochChainID { + fn default() -> Self { + RoochChainID::Builtin(BuiltinChainID::default()) + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub struct RoochNetwork { + pub chain_id: ChainID, + pub genesis_config: GenesisConfig, +} + +impl From for RoochNetwork { + fn from(chain_id: BuiltinChainID) -> Self { + RoochNetwork::builtin(chain_id) + } +} + +impl RoochNetwork { + pub fn new(chain_id: ChainID, genesis_config: GenesisConfig) -> Self { + Self { + chain_id, + genesis_config, + } + } + + pub fn builtin(builtin_id: BuiltinChainID) -> Self { + Self::new(builtin_id.into(), builtin_id.genesis_config().clone()) + } + + pub fn set_sequencer_account(&mut self, account: AccountAddress) { + self.genesis_config.sequencer_account = account; + } +} diff --git a/crates/rooch-types/src/transaction/rooch.rs b/crates/rooch-types/src/transaction/rooch.rs index 3983de6595..3bc3e38c28 100644 --- a/crates/rooch-types/src/transaction/rooch.rs +++ b/crates/rooch-types/src/transaction/rooch.rs @@ -3,8 +3,9 @@ use super::RawTransaction; use super::{authenticator::Authenticator, AuthenticatorInfo}; +use crate::address::RoochAddress; use crate::crypto::{Ed25519RoochSignature, RoochKeyPair, Signature}; -use crate::{address::RoochAddress, chain_id::RoochChainID}; +use crate::rooch_network::BuiltinChainID; use anyhow::Result; use moveos_types::gas_config::GasConfig; use moveos_types::h256::H256; @@ -50,7 +51,7 @@ impl RoochTransactionData { Self { sender, sequence_number, - chain_id: RoochChainID::LOCAL.chain_id().id(), + chain_id: BuiltinChainID::Local.chain_id().id(), max_gas_amount: GasConfig::DEFAULT_MAX_GAS_AMOUNT * 100, action, } diff --git a/crates/rooch/src/commands/server/commands/start.rs b/crates/rooch/src/commands/server/commands/start.rs index b7cdb7d86f..74c553390f 100644 --- a/crates/rooch/src/commands/server/commands/start.rs +++ b/crates/rooch/src/commands/server/commands/start.rs @@ -9,8 +9,8 @@ use rooch_key::key_derive::verify_password; use rooch_key::keystore::account_keystore::AccountKeystore; use rooch_rpc_server::Service; use rooch_types::address::RoochAddress; -use rooch_types::chain_id::RoochChainID; use rooch_types::error::{RoochError, RoochResult}; +use rooch_types::rooch_network::BuiltinChainID; use rpassword::prompt_password; use std::str::FromStr; use tokio::signal::ctrl_c; @@ -145,16 +145,14 @@ impl CommandAction<()> for StartCommand { .map_err(RoochError::from)?; // Automatically switch env when use start server, if network is local or dev seed - // let mut context = self.context_options.build()?; - // let active_env = context.client_config.get_active_env()?; let rooch_chain_id = self.opt.chain_id.unwrap_or_default(); - let chain_name = rooch_chain_id.chain_name().to_lowercase(); + let chain_name = rooch_chain_id.chain_name(); // When chain_id is not equals to env alias let switch_env = if active_env.alias != chain_name { - if RoochChainID::LOCAL == rooch_chain_id { - Some(RoochChainID::LOCAL.chain_name().to_lowercase()) - } else if RoochChainID::DEV == rooch_chain_id { - Some(RoochChainID::DEV.chain_name().to_lowercase()) + if rooch_chain_id.is_local() { + Some(BuiltinChainID::Local.chain_name()) + } else if rooch_chain_id.is_dev() { + Some(BuiltinChainID::Dev.chain_name()) } else { println!( "Warning! The active env is not equals to chain_id when server start, current chain_id is `{}`, while active env is `{}`", diff --git a/crates/rooch/src/commands/statedb/commands/genesis_utxo.rs b/crates/rooch/src/commands/statedb/commands/genesis_utxo.rs index 8e75634711..d44c6097ec 100644 --- a/crates/rooch/src/commands/statedb/commands/genesis_utxo.rs +++ b/crates/rooch/src/commands/statedb/commands/genesis_utxo.rs @@ -35,11 +35,11 @@ use rooch_types::address::{BitcoinAddress, MultiChainAddress, RoochAddress}; use rooch_types::addresses::BITCOIN_MOVE_ADDRESS; use rooch_types::bitcoin::utxo::{BitcoinUTXOStore, UTXO}; use rooch_types::bitcoin::{types, utxo}; -use rooch_types::chain_id::RoochChainID; use rooch_types::error::{RoochError, RoochResult}; use rooch_types::framework::address_mapping::AddressMappingWrapper; use rooch_types::into_address::IntoAddress; use rooch_types::multichain_id::RoochMultiChainID; +use rooch_types::rooch_network::RoochChainID; use smt::UpdateSet; use crate::cli_types::WalletContextOptions; diff --git a/crates/rooch/src/commands/statedb/commands/import.rs b/crates/rooch/src/commands/statedb/commands/import.rs index 051d0e8519..d43abd77f6 100644 --- a/crates/rooch/src/commands/statedb/commands/import.rs +++ b/crates/rooch/src/commands/statedb/commands/import.rs @@ -8,8 +8,8 @@ use moveos_store::MoveOSStore; use moveos_types::h256::H256; use moveos_types::state::{KeyState, State}; use rooch_config::R_OPT_NET_HELP; -use rooch_types::chain_id::RoochChainID; use rooch_types::error::RoochResult; +use rooch_types::rooch_network::RoochChainID; use smt::{TreeChangeSet, UpdateSet}; use std::collections::BTreeMap; use std::path::PathBuf; diff --git a/crates/rooch/src/commands/statedb/commands/mod.rs b/crates/rooch/src/commands/statedb/commands/mod.rs index 2130bfd3c3..ba8bd3864c 100644 --- a/crates/rooch/src/commands/statedb/commands/mod.rs +++ b/crates/rooch/src/commands/statedb/commands/mod.rs @@ -8,7 +8,7 @@ use raw_store::rocks::RocksDB; use raw_store::StoreInstance; use rooch_config::store_config::StoreConfig; use rooch_config::{BaseConfig, RoochOpt}; -use rooch_types::chain_id::RoochChainID; +use rooch_types::rooch_network::RoochChainID; use std::path::PathBuf; use std::sync::Arc; use tracing::info; diff --git a/crates/testsuite/tests/integration.rs b/crates/testsuite/tests/integration.rs index e3a73998e4..2d131ccbe3 100644 --- a/crates/testsuite/tests/integration.rs +++ b/crates/testsuite/tests/integration.rs @@ -9,6 +9,7 @@ use cucumber::{given, then, World as _}; use jpst::TemplateContext; use rooch::RoochCli; use rooch_config::{rooch_config_dir, RoochOpt, ServerOpt}; +use rooch_key::key_derive::{generate_new_key_pair, retrieve_key_pair}; use rooch_rpc_client::wallet_context::WalletContext; use rooch_rpc_server::Service; use serde_json::Value; @@ -16,7 +17,7 @@ use tracing::{debug, error, info}; use images::bitcoin::BitcoinD; use images::ord::Ord; -use rooch_types::bitcoin::network::Network; +use rooch_types::{bitcoin::network::Network, crypto::RoochKeyPair}; use std::time::Duration; use testcontainers::{ clients::Cli, @@ -71,7 +72,7 @@ async fn start_server(w: &mut World, _scenario: String) { opt.btc_rpc_password = Some(RPC_PASS.to_string()); opt.btc_start_block_height = Some(0); opt.data_import_flag = false; // Enable data import without writing indexes - opt.btc_network = Some(Network::NetworkTestnet.to_num()); + opt.btc_network = Some(Network::Testnet.to_num()); info!("config btc rpc ok"); w.bitcoind = Some(bitcoind); @@ -81,7 +82,14 @@ async fn start_server(w: &mut World, _scenario: String) { } } - let server_opt = ServerOpt::new(); + let mut server_opt = ServerOpt::new(); + + let result = generate_new_key_pair(None, None, None, None).unwrap(); + let kp: RoochKeyPair = + retrieve_key_pair(&result.key_pair_data.private_key_encryption, None).unwrap(); + server_opt.sequencer_keypair = Some(kp.copy()); + server_opt.proposer_keypair = Some(kp.copy()); + server_opt.relayer_keypair = Some(kp.copy()); service.start(&opt, server_opt).await.unwrap(); diff --git a/frameworks/framework-builder/src/lib.rs b/frameworks/framework-builder/src/lib.rs index 2a324bb5d3..180a14055c 100644 --- a/frameworks/framework-builder/src/lib.rs +++ b/frameworks/framework-builder/src/lib.rs @@ -285,7 +285,7 @@ impl Stdlib { pub fn module_bundles( &self, - package_names: &[&str], + package_names: &[String], ) -> Result>)>> { let mut bundles = vec![]; for package_name in package_names { @@ -298,7 +298,7 @@ impl Stdlib { ); } for package in &self.packages { - if package_names.contains(&package.package_name.as_str()) { + if package_names.contains(&package.package_name) { let mut module_bundle = vec![]; for module in package.modules()? { let mut binary = vec![];