diff --git a/base_layer/core/src/blocks/genesis_block.rs b/base_layer/core/src/blocks/genesis_block.rs index 7251799eaa..1552fb0b1a 100644 --- a/base_layer/core/src/blocks/genesis_block.rs +++ b/base_layer/core/src/blocks/genesis_block.rs @@ -50,10 +50,11 @@ use crate::{ /// Returns the genesis block for the selected network. pub fn get_genesis_block(network: Network) -> ChainBlock { - use Network::{Dibbler, Esmeralda, Igor, LocalNet, MainNet, Ridcully, StageNet, Stibbons, Weatherwax}; + use Network::{Dibbler, Esmeralda, Igor, LocalNet, MainNet, NextNet, Ridcully, StageNet, Stibbons, Weatherwax}; match network { MainNet => get_mainnet_genesis_block(), StageNet => get_stagenet_genesis_block(), + NextNet => get_nextnet_genesis_block(), Igor => get_igor_genesis_block(), Esmeralda => get_esmeralda_genesis_block(), LocalNet => get_esmeralda_genesis_block(), @@ -80,7 +81,7 @@ pub fn get_stagenet_genesis_block() -> ChainBlock { } fn get_stagenet_genesis_block_raw() -> Block { - // Note: Use print_new_genesis_block_stagenet in core/tests/helpers/block_builders.rs to generate the required + // Note: Use print_new_genesis_block_nextnet in core/tests/helpers/block_builders.rs to generate the required // fields below let excess_sig = Signature::new( PublicKey::from_hex("e487276e01039473094f492f20b707d3805399f799fc9d4ad77c648f2a5c0d18").unwrap(), @@ -158,6 +159,100 @@ fn get_stagenet_genesis_block_raw() -> Block { } } +pub fn get_nextnet_genesis_block() -> ChainBlock { + let block = get_nextnet_genesis_block_raw(); + + let accumulated_data = BlockHeaderAccumulatedData { + hash: block.hash(), + total_kernel_offset: block.header.total_kernel_offset.clone(), + achieved_difficulty: 1.into(), + total_accumulated_difficulty: 1, + accumulated_monero_difficulty: 1.into(), + accumulated_sha_difficulty: 1.into(), + target_difficulty: 1.into(), + }; + ChainBlock::try_construct(Arc::new(block), accumulated_data).unwrap() +} + +fn get_nextnet_genesis_block_raw() -> Block { + // Note: Use print_new_genesis_block_stagenet in core/tests/helpers/block_builders.rs to generate the required + // fields below + let excess_sig = Signature::new( + PublicKey::from_hex("c2e01e3c69a7b9f664dcf6069bf0ac5ddba7ec24f7b37628649355cabefdd66a").unwrap(), + PrivateKey::from_hex("079988886b259373587a3d4f9abd6b4b7e3d483a6bc6fd67810291b9c5402d01").unwrap(), + ); + let coinbase_meta_sig = CommitmentAndPublicKeySignature::new( + Commitment::from_hex("3a2704f98f7a2f29d01c4f313955616f70a2afd54cff6addeb0d696e8a4b5e76").unwrap(), + PublicKey::from_hex("a25019606afab39eec37dca1b3ed928831116ab9761459cff91768377677f741").unwrap(), + PrivateKey::from_hex("3f047693eab2e424bbd41fdeea7c99cdf6fdcdccb6d679e621f95dca24029603").unwrap(), + PrivateKey::from_hex("58e625717af1fd2cf8634fda866fc13e0bd7b32dae0b85ed2597ec0191828a0f").unwrap(), + PrivateKey::from_hex("71cec1b930693191db40c3f62e5544b0ecba43686d79d61f1537cbbfa8ffd90c").unwrap(), + ); + let extra = "Mathematical proof that something happened"; + let coinbase = TransactionOutput::new( + TransactionOutputVersion::get_current_version(), + OutputFeatures::create_coinbase(360, Some(extra.as_bytes().to_vec())), + Commitment::from_hex("dc06fb061ce57f7a785e970e3ac3f61be38cb18a094d6f56d46ff237aaf0dd29").unwrap(), + BulletRangeProof::from_hex("01262ef222ceaa3ad01b29d4e2c860226c55f098da593ece40f2f288217ce3d02458bdd4c7e0ccfdf95860fa0495c93a8e4c19cbc267c00fe1820a0bc1b23fc85a4ab1dba8d11e3bf22fe2836545baabd73cc01c35d36e04d6cbe6e26a8ae9227274f27ee2003ad9b42a0014f2d39c9090c7c4815a9a67755d623bbbd21e66d80918e62b4687dcab350b1c10c12426e62dc7f739ac2bc6c0336ddac37478da2c5e2c7bc0202212780a89c5184f4ab19a2a2562c1b81c2f8433524907a00e075a19b02e537dd72eb8889ac6a0ccefb621ace5ddc4d0c3457cb089c7ed84ba1acb0c1e957f739c6aa6fb866082fa9ef139556b19356a3bc1f9181c55c49723dfbf62a4ddf90b37b8ae76e245a9eaba87ebe4cb238f1b172ce09483ee635b2acad910524ef872385bdc18c20f4c72d55249d46dd8097b2d36d710962c85b71afb412fceb9a3e6d53712885c280abcfed3ff1468226f6bbcb3e1a314753b4db08a9032985fff2b819053b5bc44e464e9557242b0a45bcf1db2df17bd18e4d3d89b15684408e0051aacc69785eed91c7112fbcd2a5daaa0d7fd7084a430e48a9921531120f0395139b2950fe03dc24ccde6683aae2f6496b399c8e14703f9d042939f4b9c9f6168cdc6e4f0ef696f207b13284d104664af825fda2d2efca4f47872ee3c1c3140655a2215c0b3aa6696e59d950be6a69832a82f959ac9b2bc94cb0101003620089f16577e5281152441def452891e2145f7972a0213d8972d74bf5625087dba65abdab63be8def59bf9ac50be3c94986dac852983ece8e9d2a201f72603").unwrap(), + // A default script can never be spent, intentionally + script!(Nop), + // The Sender offset public key is not checked for coinbase outputs + PublicKey::from_hex("b6ec474ed5106296da315ae066739042597ba35094a6ae152a33bdd117661b2e").unwrap(), + coinbase_meta_sig, + // Covenant + Covenant::default(), + EncryptedValue::default(), + // Genesis blocks don't need to prove a minimum value + MicroTari::zero(), + ); + let kernel = TransactionKernel::new( + TransactionKernelVersion::V0, + KernelFeatures::COINBASE_KERNEL, + MicroTari(0), + 0, + Commitment::from_hex("e43e1ebfd31a86ed27ed9167522b31108e4117806ce12a1ede06e02e67da5f1c").unwrap(), + excess_sig, + None, + ); + let mut body = AggregateBody::new(vec![], vec![coinbase], vec![kernel]); + body.sort(); + // set genesis timestamp + let genesis = DateTime::parse_from_rfc2822("24 Feb 2023 12:15:00 +0100").unwrap(); + #[allow(clippy::cast_sign_loss)] + let timestamp = genesis.timestamp() as u64; + Block { + header: BlockHeader { + version: 0, + height: 0, + prev_hash: FixedHash::zero(), + timestamp: timestamp.into(), + output_mr: FixedHash::from_hex("dbd70217d48910988e34a677528d49cec3c0cb091ba9edfb41f5320b565d314c").unwrap(), + witness_mr: FixedHash::from_hex("381e281523a39da58158a47e901ed78c6a86da1b913c25102b92deb369e718eb") + .unwrap(), + output_mmr_size: 1, + kernel_mr: FixedHash::from_hex("dfe55fd7137908009c05ec37e5c6e4b9d773e6cc1ca8f4c83c976ca118355c6b").unwrap(), + kernel_mmr_size: 1, + input_mr: FixedHash::zero(), + total_kernel_offset: PrivateKey::from_hex( + "0000000000000000000000000000000000000000000000000000000000000000", + ) + .unwrap(), + total_script_offset: PrivateKey::from_hex( + "0000000000000000000000000000000000000000000000000000000000000000", + ) + .unwrap(), + nonce: 0, + pow: ProofOfWork { + pow_algo: PowAlgorithm::Sha3, + pow_data: vec![], + }, + validator_node_mr: FixedHash::from_hex("e1d55f91ecc7e435080ac2641280516a355a5ecbe231158987da217b5af30047") + .unwrap(), + }, + body, + } +} + pub fn get_mainnet_genesis_block() -> ChainBlock { unimplemented!() } @@ -478,6 +573,14 @@ mod test { check_block(Network::StageNet, &block, 1, 1); } + #[test] + fn nextnet_genesis_sanity_check() { + // Note: Generate new data for `pub fn get_nextnet_genesis_block()` and `fn get_stagenet_genesis_block_raw()` + // if consensus values change, e.g. new faucet or other + let block = get_nextnet_genesis_block(); + check_block(Network::NextNet, &block, 1, 1); + } + #[test] fn esmeralda_genesis_sanity_check() { // Note: Generate new data for `pub fn get_esmeralda_genesis_block()` and `fn get_esmeralda_genesis_block_raw()` diff --git a/base_layer/core/src/consensus/consensus_constants.rs b/base_layer/core/src/consensus/consensus_constants.rs index 96b64467f9..34501cc79b 100644 --- a/base_layer/core/src/consensus/consensus_constants.rs +++ b/base_layer/core/src/consensus/consensus_constants.rs @@ -667,6 +667,52 @@ impl ConsensusConstants { }] } + pub fn nextnet() -> Vec { + // Note these values are all placeholders for final values + let mut algos = HashMap::new(); + algos.insert(PowAlgorithm::Sha3, PowAlgorithmConstants { + max_target_time: 1800, + min_difficulty: 60_000_000.into(), + max_difficulty: u64::MAX.into(), + target_time: 300, + }); + algos.insert(PowAlgorithm::Monero, PowAlgorithmConstants { + max_target_time: 1200, + min_difficulty: 60_000.into(), + max_difficulty: u64::MAX.into(), + target_time: 200, + }); + let (input_version_range, output_version_range, kernel_version_range) = version_zero(); + vec![ConsensusConstants { + effective_from_height: 0, + coinbase_lock_height: 360, + blockchain_version: 0, + valid_blockchain_version_range: 0..=0, + future_time_limit: 540, + difficulty_block_window: 90, + max_block_transaction_weight: 127_795, + median_timestamp_count: 11, + emission_initial: 18_462_816_327 * uT, + emission_decay: &EMISSION_DECAY, + emission_tail: 800 * T, + max_randomx_seed_height: 3000, + proof_of_work: algos, + faucet_value: 0.into(), + transaction_weight: TransactionWeight::v1(), + max_script_byte_size: 2048, + input_version_range, + output_version_range, + kernel_version_range, + permitted_output_types: Self::current_permitted_output_types(), + vn_epoch_length: 60, + vn_validity_period_epochs: VnEpoch(100), + vn_registration_min_deposit_amount: MicroTari(0), + vn_registration_lock_height: 0, + vn_registration_shuffle_interval: VnEpoch(100), + coinbase_output_features_extra_max_length: 64, + }] + } + pub fn mainnet() -> Vec { // Note these values are all placeholders for final values let difficulty_block_window = 90; diff --git a/base_layer/core/src/consensus/network.rs b/base_layer/core/src/consensus/network.rs index b98a92cdf0..76d3956a03 100644 --- a/base_layer/core/src/consensus/network.rs +++ b/base_layer/core/src/consensus/network.rs @@ -30,10 +30,11 @@ pub struct NetworkConsensus(Network); impl NetworkConsensus { pub fn create_consensus_constants(&self) -> Vec { - use Network::{Dibbler, Esmeralda, Igor, LocalNet, MainNet, Ridcully, StageNet, Stibbons, Weatherwax}; + use Network::{Dibbler, Esmeralda, Igor, LocalNet, MainNet, NextNet, Ridcully, StageNet, Stibbons, Weatherwax}; match self.as_network() { MainNet => ConsensusConstants::mainnet(), StageNet => ConsensusConstants::stagenet(), + NextNet => ConsensusConstants::nextnet(), LocalNet => ConsensusConstants::localnet(), Dibbler => ConsensusConstants::dibbler(), Igor => ConsensusConstants::igor(), diff --git a/base_layer/core/tests/helpers/block_builders.rs b/base_layer/core/tests/helpers/block_builders.rs index cd0e3b4c96..354f7efca4 100644 --- a/base_layer/core/tests/helpers/block_builders.rs +++ b/base_layer/core/tests/helpers/block_builders.rs @@ -119,6 +119,17 @@ fn genesis_template( (block, output) } +// #[ignore = "used to generate a new nextnet genesis block"] +/// This is a helper function to generate and print out a block that can be used as the genesis block. +/// 1. Run `cargo test --package tari_core --test mempool -- helpers::block_builders::print_new_genesis_block_nextnet +/// --exact --nocapture` +/// 1. The block and range proof will be printed +/// 1. Profit! +#[test] +fn print_new_genesis_block_nextnet() { + print_new_genesis_block(Network::NextNet, "Mathematical proof that something happened"); +} + // #[ignore = "used to generate a new stagenet genesis block"] /// This is a helper function to generate and print out a block that can be used as the genesis block. /// 1. Run `cargo test --package tari_core --test mempool -- helpers::block_builders::print_new_genesis_block_stagenet diff --git a/common/config/presets/b_peer_seeds.toml b/common/config/presets/b_peer_seeds.toml index fd829bc57f..8b712252d2 100644 --- a/common/config/presets/b_peer_seeds.toml +++ b/common/config/presets/b_peer_seeds.toml @@ -15,6 +15,17 @@ # All DNS seed records must pass DNSSEC validation #dns_seeds_use_dnssec = false +[nextnet.p2p.seeds] +# DNS seeds hosts - DNS TXT records are queried from these hosts and the resulting peers added to the comms peer list. +dns_seeds = ["seeds.nextnet.tari.com"] +# Custom specified peer seed nodes +peer_seeds = [ + # 44444408d5fa29410d9752770f + "2c84ccdf0dcb7b4845f167ea8988166384a36451d068e0ae1bb84b5bf0d52425::/onion3/7gwfakr7ko5uo3fl3yz3fsjc7elccbzter5botggodrmmwi2exm3vbid:18141", + # bbbbbb87215db9ee00bb2763b5 + "64639314dc3c9a4b0fa57f812d68b381a882e72eb9cc20e861ce6e04936ef438::/onion3/lvsj75guqc4gfqasgyhg3of2clijf3vkgipbpufh6dmhyapp2dmuelad:18141", +] + [stagenet.p2p.seeds] # DNS seeds hosts - DNS TXT records are queried from these hosts and the resulting peers added to the comms peer list. dns_seeds = ["seeds.stagenet.tari.com"] diff --git a/common/config/presets/c_base_node.toml b/common/config/presets/c_base_node.toml index 02607a8c9f..8023036638 100644 --- a/common/config/presets/c_base_node.toml +++ b/common/config/presets/c_base_node.toml @@ -17,9 +17,6 @@ identity_file = "config/base_node_id_dibbler.json" # A path to the file that stores your node identity and secret key (default = "config/base_node_id.json") identity_file = "config/base_node_id_igor.json" -# The socket to expose for the gRPC base node server (default = "/ip4/127.0.0.1/tcp/18152") -#grpc_address = "/ip4/127.0.0.1/tcp/18152" - [esmeralda.base_node] # A path to the file that stores your node identity and secret key (default = "config/base_node_id.json") identity_file = "config/base_node_id_esmeralda.json" @@ -27,8 +24,10 @@ identity_file = "config/base_node_id_esmeralda.json" [stagenet.base_node] # A path to the file that stores your node identity and secret key (default = "config/base_node_id.json") identity_file = "config/base_node_id_stagenet.json" -# The socket to expose for the gRPC base node server (default = "/ip4/127.0.0.1/tcp/18142") -#grpc_address = "/ip4/127.0.0.1/tcp/18142" + +[nextnet.base_node] +# A path to the file that stores your node identity and secret key (default = "config/base_node_id.json") +identity_file = "config/base_node_id_nextnet.json" [base_node] # Selected network (Note: Not implemented properly, please specify on the command line) (default = "emseralda") diff --git a/common/src/configuration/bootstrap.rs b/common/src/configuration/bootstrap.rs index 898a9ba6fc..8506f2a7a1 100644 --- a/common/src/configuration/bootstrap.rs +++ b/common/src/configuration/bootstrap.rs @@ -104,6 +104,7 @@ pub fn grpc_default_port(app_type: ApplicationType, network: Network) -> u16 { ApplicationType::BaseNode => match network { Network::MainNet => 18102u16, Network::StageNet => 18172u16, + Network::NextNet => 18182u16, Network::Weatherwax => 18112, Network::Dibbler => 18122, Network::Esmeralda => 18142, @@ -114,6 +115,7 @@ pub fn grpc_default_port(app_type: ApplicationType, network: Network) -> u16 { ApplicationType::ConsoleWallet => match network { Network::MainNet => 18103u16, Network::StageNet => 18173u16, + Network::NextNet => 18183u16, Network::Weatherwax => 18113, Network::Dibbler => 18123, Network::Esmeralda => 18143, diff --git a/common/src/configuration/network.rs b/common/src/configuration/network.rs index 140a88cc56..ce9a600284 100644 --- a/common/src/configuration/network.rs +++ b/common/src/configuration/network.rs @@ -39,6 +39,7 @@ use crate::ConfigurationError; pub enum Network { MainNet = 0x00, StageNet = 0x01, + NextNet = 0x02, LocalNet = 0x10, Ridcully = 0x21, Stibbons = 0x22, @@ -59,6 +60,7 @@ impl Network { match self { MainNet => "mainnet", StageNet => "stagenet", + NextNet => "nextnet", Ridcully => "ridcully", Stibbons => "stibbons", Weatherwax => "weatherwax", @@ -89,6 +91,7 @@ impl FromStr for Network { "stibbons" => Ok(Stibbons), "weatherwax" => Ok(Weatherwax), "mainnet" => Ok(MainNet), + "nextnet" => Ok(NextNet), "stagenet" => Ok(StageNet), "localnet" => Ok(LocalNet), "igor" => Ok(Igor), @@ -123,6 +126,7 @@ impl TryFrom for Network { match v { x if x == Network::MainNet as u8 => Ok(Network::MainNet), x if x == Network::StageNet as u8 => Ok(Network::StageNet), + x if x == Network::NextNet as u8 => Ok(Network::NextNet), x if x == Network::LocalNet as u8 => Ok(Network::LocalNet), x if x == Network::Ridcully as u8 => Ok(Network::Ridcully), x if x == Network::Stibbons as u8 => Ok(Network::Stibbons), @@ -154,6 +158,7 @@ mod test { // get networks let mainnet = Network::MainNet; let stagenet = Network::StageNet; + let nextnet = Network::NextNet; let localnet = Network::LocalNet; let ridcully = Network::Ridcully; let stibbons = Network::Stibbons; @@ -165,6 +170,7 @@ mod test { // test .as_byte() assert_eq!(mainnet.as_byte(), 0x00_u8); assert_eq!(stagenet.as_byte(), 0x01_u8); + assert_eq!(nextnet.as_byte(), 0x02_u8); assert_eq!(localnet.as_byte(), 0x10_u8); assert_eq!(ridcully.as_byte(), 0x21_u8); assert_eq!(stibbons.as_byte(), 0x22_u8); @@ -176,6 +182,7 @@ mod test { // test .as_key_str() assert_eq!(mainnet.as_key_str(), "mainnet"); assert_eq!(stagenet.as_key_str(), "stagenet"); + assert_eq!(nextnet.as_key_str(), "nextnet"); assert_eq!(localnet.as_key_str(), "localnet"); assert_eq!(ridcully.as_key_str(), "ridcully"); assert_eq!(stibbons.as_key_str(), "stibbons"); @@ -196,6 +203,7 @@ mod test { // test .from_str() assert_eq!(Network::from_str("mainnet").unwrap(), Network::MainNet); assert_eq!(Network::from_str("stagenet").unwrap(), Network::StageNet); + assert_eq!(Network::from_str("nextnet").unwrap(), Network::NextNet); assert_eq!(Network::from_str("localnet").unwrap(), Network::LocalNet); assert_eq!(Network::from_str("ridcully").unwrap(), Network::Ridcully); assert_eq!(Network::from_str("stibbons").unwrap(), Network::Stibbons); @@ -213,6 +221,7 @@ mod test { fn network_from_byte() { assert_eq!(Network::try_from(0x00).unwrap(), Network::MainNet); assert_eq!(Network::try_from(0x01).unwrap(), Network::StageNet); + assert_eq!(Network::try_from(0x02).unwrap(), Network::NextNet); assert_eq!(Network::try_from(0x10).unwrap(), Network::LocalNet); assert_eq!(Network::try_from(0x21).unwrap(), Network::Ridcully); assert_eq!(Network::try_from(0x22).unwrap(), Network::Stibbons);