From 5ac02716d9adbecb408ab9d52482c05c68c67399 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Fri, 25 Oct 2024 15:03:22 +0200 Subject: [PATCH 01/23] impl in progress --- .../chain_storage/active_validator_node.rs | 1 - .../core/src/chain_storage/lmdb_db/lmdb_db.rs | 128 +++++++++--------- .../lmdb_db/validator_node_store.rs | 49 +++++-- .../core/src/consensus/consensus_constants.rs | 29 ++-- 4 files changed, 117 insertions(+), 90 deletions(-) diff --git a/base_layer/core/src/chain_storage/active_validator_node.rs b/base_layer/core/src/chain_storage/active_validator_node.rs index 5ed51aa762..688a0719c6 100644 --- a/base_layer/core/src/chain_storage/active_validator_node.rs +++ b/base_layer/core/src/chain_storage/active_validator_node.rs @@ -30,7 +30,6 @@ use tari_common_types::{ pub struct ValidatorNodeEntry { pub shard_key: [u8; 32], pub start_epoch: VnEpoch, - pub end_epoch: VnEpoch, pub public_key: PublicKey, pub commitment: Commitment, pub sidechain_id: Option, diff --git a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs index 289f22281c..2bde104d34 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs @@ -337,17 +337,17 @@ impl LMDBDatabase { InsertOrphanBlock(block) => self.insert_orphan_block(&write_txn, block)?, InsertChainHeader { header } => { self.insert_header(&write_txn, header.header(), header.accumulated_data())?; - }, + } InsertTipBlockBody { block, smt } => { self.insert_tip_block_body(&write_txn, block.header(), block.block().body.clone(), smt.clone())?; - }, + } InsertKernel { header_hash, kernel, mmr_position, } => { self.insert_kernel(&write_txn, header_hash, kernel, *mmr_position)?; - }, + } InsertOutput { header_hash, header_height, @@ -355,13 +355,13 @@ impl LMDBDatabase { output, } => { self.insert_output(&write_txn, header_hash, *header_height, *timestamp, output)?; - }, + } DeleteHeader(height) => { self.delete_header(&write_txn, *height)?; - }, + } DeleteOrphan(hash) => { self.delete_orphan(&write_txn, hash)?; - }, + } DeleteOrphanChainTip(hash) => { lmdb_delete( &write_txn, @@ -369,7 +369,7 @@ impl LMDBDatabase { hash.deref(), "orphan_chain_tips_db", )?; - }, + } InsertOrphanChainTip(hash, total_accumulated_difficulty) => { lmdb_insert( &write_txn, @@ -381,39 +381,39 @@ impl LMDBDatabase { }, "orphan_chain_tips_db", )?; - }, + } DeleteTipBlock(hash, smt) => { self.delete_tip_block_body(&write_txn, hash, smt.clone())?; - }, + } InsertMoneroSeedHeight(data, height) => { self.insert_monero_seed_height(&write_txn, data, *height)?; - }, + } SetAccumulatedDataForOrphan(accumulated_data) => { self.set_accumulated_data_for_orphan(&write_txn, accumulated_data)?; - }, + } InsertChainOrphanBlock(chain_block) => { self.insert_orphan_block(&write_txn, chain_block.block())?; self.set_accumulated_data_for_orphan(&write_txn, chain_block.accumulated_data())?; - }, + } UpdateBlockAccumulatedData { header_hash, values } => { self.update_block_accumulated_data(&write_txn, header_hash, values.clone())?; - }, + } PruneOutputsSpentAtHash { block_hash } => { self.prune_outputs_spent_at_hash(&write_txn, block_hash)?; - }, + } PruneOutputFromAllDbs { output_hash, commitment, output_type, } => { self.prune_output_from_all_dbs(&write_txn, output_hash, commitment, *output_type)?; - }, + } DeleteAllKernelsInBlock { block_hash } => { self.delete_all_kernels_in_block(&write_txn, block_hash)?; - }, + } DeleteAllInputsInBlock { block_hash } => { self.delete_all_inputs_in_block(&write_txn, block_hash)?; - }, + } SetBestBlock { height, hash, @@ -458,37 +458,37 @@ impl LMDBDatabase { MetadataKey::BestBlockTimestamp, &MetadataValue::BestBlockTimestamp(*timestamp), )?; - }, + } SetPruningHorizonConfig(pruning_horizon) => { self.set_metadata( &write_txn, MetadataKey::PruningHorizon, &MetadataValue::PruningHorizon(*pruning_horizon), )?; - }, + } SetPrunedHeight { height } => { self.set_metadata( &write_txn, MetadataKey::PrunedHeight, &MetadataValue::PrunedHeight(*height), )?; - }, + } SetHorizonData { horizon_data } => { self.set_metadata( &write_txn, MetadataKey::HorizonData, &MetadataValue::HorizonData(horizon_data.clone()), )?; - }, + } InsertBadBlock { hash, height, reason } => { self.insert_bad_block_and_cleanup(&write_txn, hash, *height, reason.to_string())?; - }, + } InsertReorg { reorg } => { lmdb_replace(&write_txn, &self.reorgs, &reorg.local_time.timestamp(), &reorg, None)?; - }, + } ClearAllReorgs => { lmdb_clear(&write_txn, &self.reorgs)?; - }, + } } } write_txn.commit()?; @@ -651,7 +651,7 @@ impl LMDBDatabase { field: "hash", value: output_hash.to_hex(), }); - }, + } Err(e) => { error!( target: LOG_TARGET, @@ -659,7 +659,7 @@ impl LMDBDatabase { output_hash.to_hex(), e ); return Err(e); - }, + } }, }; Ok(input_with_output_data) @@ -985,7 +985,7 @@ impl LMDBDatabase { } let smt_key = NodeKey::try_from(utxo.output.commitment.as_bytes())?; match output_smt.delete(&smt_key)? { - DeleteResult::Deleted(_value_hash) => {}, + DeleteResult::Deleted(_value_hash) => {} DeleteResult::KeyNotFound => { error!( target: LOG_TARGET, @@ -993,7 +993,7 @@ impl LMDBDatabase { utxo.output.commitment.to_hex(), ); return Err(ChainStorageError::UnspendableInput); - }, + } }; lmdb_delete( txn, @@ -1111,7 +1111,7 @@ impl LMDBDatabase { hash.to_hex() ); return Ok(()); - }, + } }; let parent_hash = orphan.header.prev_hash; @@ -1142,19 +1142,19 @@ impl LMDBDatabase { }, "orphan_chain_tips_db", )?; - }, + } None => { warn!( target: LOG_TARGET, "Empty 'BlockHeaderAccumulatedData' for parent hash '{}'", parent_hash.to_hex() ); - }, + } } - }, + } (false, false) => { // No entries, nothing here - }, + } _ => { // Some previous database operations were not atomic warn!( @@ -1164,7 +1164,7 @@ impl LMDBDatabase { lmdb_exists(txn, &self.orphan_header_accumulated_data_db, parent_hash.as_slice())?, parent_hash.to_hex() ); - }, + } } } @@ -1313,7 +1313,7 @@ impl LMDBDatabase { let input_with_output_data = self.input_with_output_data(txn, input)?; let smt_key = NodeKey::try_from(input_with_output_data.commitment()?.as_bytes())?; match output_smt.delete(&smt_key)? { - DeleteResult::Deleted(_value_hash) => {}, + DeleteResult::Deleted(_value_hash) => {} DeleteResult::KeyNotFound => { error!( target: LOG_TARGET, @@ -1321,7 +1321,7 @@ impl LMDBDatabase { input_with_output_data.commitment()?.to_hex(), ); return Err(ChainStorageError::UnspendableInput); - }, + } }; let features = input_with_output_data.features()?; @@ -1360,7 +1360,7 @@ impl LMDBDatabase { Ok(()) } - fn validator_node_store<'a, T: Deref>>( + fn validator_node_store<'a, T: Deref>>( &'a self, txn: &'a T, ) -> ValidatorNodeStore<'a, T> { @@ -1392,12 +1392,14 @@ impl LMDBDatabase { constants.validator_node_registration_shuffle_interval(), &header.prev_hash, ); + + let next_epoch = current_epoch + VnEpoch(1); + // TODO: looking for next available epoch + store.get_vn_set() - let next_epoch = constants.block_height_to_epoch(header.height) + VnEpoch(1); let validator_node = ValidatorNodeEntry { shard_key, start_epoch: next_epoch, - end_epoch: next_epoch + constants.validator_node_validity_period_epochs(), public_key: vn_reg.public_key().clone(), commitment: commitment.clone(), sidechain_id: vn_reg.sidechain_id().cloned(), @@ -1557,7 +1559,7 @@ impl LMDBDatabase { let key = OutputKey::new(&FixedHash::from(buffer), output_hash)?; debug!(target: LOG_TARGET, "Pruning output from 'utxos_db': key '{}'", key.0); lmdb_delete(write_txn, &self.utxos_db, &key.convert_to_comp_key(), LMDB_DB_UTXOS)?; - }, + } None => return Err(ChainStorageError::InvalidOperation("Output key not found".to_string())), } @@ -1666,12 +1668,12 @@ impl LMDBDatabase { if let Some(key) = lmdb_get::<_, Vec>(txn, &self.txos_hash_to_index_db, output_hash)? { match lmdb_get::<_, TransactionOutputRowData>(txn, &self.utxos_db, &key)? { Some(TransactionOutputRowData { - output: o, - mined_height, - header_hash, - mined_timestamp, - .. - }) => Ok(Some(OutputMinedInfo { + output: o, + mined_height, + header_hash, + mined_timestamp, + .. + }) => Ok(Some(OutputMinedInfo { output: o, mined_height, header_hash, @@ -1693,12 +1695,12 @@ impl LMDBDatabase { if let Some(key) = lmdb_get::<_, Vec>(txn, &self.deleted_txo_hash_to_header_index, output_hash)? { match lmdb_get::<_, TransactionInputRowData>(txn, &self.inputs_db, &key)? { Some(TransactionInputRowData { - input: i, - spent_height: height, - header_hash, - spent_timestamp, - .. - }) => Ok(Some(InputMinedInfo { + input: i, + spent_height: height, + header_hash, + spent_timestamp, + .. + }) => Ok(Some(InputMinedInfo { input: i, spent_height: height, header_hash, @@ -1792,7 +1794,7 @@ impl BlockchainBackend for LMDBDatabase { ); return Ok(()); - }, + } Err(ChainStorageError::DbResizeRequired(size_that_could_not_be_written)) => { info!( target: LOG_TARGET, @@ -1806,11 +1808,11 @@ impl BlockchainBackend for LMDBDatabase { unsafe { LMDBStore::resize(&self.env, &self.env_config, size_that_could_not_be_written)?; } - }, + } Err(e) => { error!(target: LOG_TARGET, "Failed to apply DB transaction: {:?}", e); return Err(e); - }, + } } } @@ -1823,7 +1825,7 @@ impl BlockchainBackend for LMDBDatabase { DbKey::HeaderHeight(k) => { let val: Option = lmdb_get(&txn, &self.headers_db, k)?; val.map(|val| DbValue::HeaderHeight(Box::new(val))) - }, + } DbKey::HeaderHash(hash) => { let k: Option = self.fetch_height_from_hash(&txn, hash)?; match k { @@ -1836,7 +1838,7 @@ impl BlockchainBackend for LMDBDatabase { ); let val: Option = lmdb_get(&txn, &self.headers_db, &k)?; val.map(|val| DbValue::HeaderHash(Box::new(val))) - }, + } None => { trace!( target: LOG_TARGET, @@ -1844,9 +1846,9 @@ impl BlockchainBackend for LMDBDatabase { hash.to_hex() ); None - }, + } } - }, + } DbKey::OrphanBlock(k) => self .fetch_orphan(&txn, k)? .map(|val| DbValue::OrphanBlock(Box::new(val))), @@ -2327,10 +2329,10 @@ impl BlockchainBackend for LMDBDatabase { } })?; Ok(Some(chain_block)) - }, + } None => Ok(None), } - }, + } None => Ok(None), } } @@ -2433,7 +2435,7 @@ impl BlockchainBackend for LMDBDatabase { } else { Err(ChainStorageError::AccessError(e)) } - }, + } Err(e) => Err(e), } } @@ -2444,7 +2446,7 @@ impl BlockchainBackend for LMDBDatabase { Some(h) => h, None => { return Ok(0); - }, + } }; let metadata = fetch_metadata(&txn, &self.metadata_db)?; diff --git a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs index 54438e2a3b..2e5d96e255 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs @@ -22,11 +22,6 @@ use std::{collections::HashMap, ops::Deref}; -use lmdb_zero::{ConstTransaction, WriteTransaction}; -use tari_common_types::types::{Commitment, PublicKey}; -use tari_storage::lmdb_store::DatabaseRef; -use tari_utilities::ByteArray; - use crate::chain_storage::{ lmdb_db::{ composite_key::CompositeKey, @@ -37,6 +32,12 @@ use crate::chain_storage::{ ValidatorNodeEntry, ValidatorNodeRegistrationInfo, }; +use lmdb_zero::{ConstTransaction, WriteTransaction}; +use serde::de::Unexpected::Option; +use tari_common_types::epoch::VnEpoch; +use tari_common_types::types::{Commitment, PublicKey}; +use tari_storage::lmdb_store::DatabaseRef; +use tari_utilities::ByteArray; pub type ShardKey = [u8; 32]; // @@ -50,7 +51,7 @@ pub struct ValidatorNodeStore<'a, Txn> { db_validator_nodes_mapping: DatabaseRef, } -impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { +impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { pub fn new(txn: &'a Txn, db_height_to_vn: DatabaseRef, idx_public_key_to_shard: DatabaseRef) -> Self { Self { txn, @@ -67,7 +68,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { validator.public_key.as_bytes(), validator.commitment.as_bytes(), ]) - .expect("insert: Composite key length is incorrect"); + .expect("insert: Composite key length is incorrect"); lmdb_insert(self.txn, &self.db_validator_nodes, &key, &validator, "Validator node")?; let key = ShardIdIndexKey::try_from_parts(&[ @@ -75,7 +76,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { height.to_be_bytes().as_slice(), validator.commitment.as_bytes(), ]) - .expect("insert: Composite key length is incorrect"); + .expect("insert: Composite key length is incorrect"); lmdb_insert( self.txn, &self.db_validator_nodes_mapping, @@ -97,7 +98,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { public_key.as_bytes(), commitment.as_bytes(), ]) - .expect("delete: Composite key length is incorrect"); + .expect("delete: Composite key length is incorrect"); lmdb_delete(self.txn, &self.db_validator_nodes, &key, "validator_nodes")?; let key = ShardIdIndexKey::try_from_parts(&[ @@ -105,7 +106,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { height.to_be_bytes().as_slice(), commitment.as_bytes(), ]) - .expect("delete: Composite key length is incorrect"); + .expect("delete: Composite key length is incorrect"); lmdb_delete( self.txn, &self.db_validator_nodes_mapping, @@ -116,7 +117,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { } } -impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { +impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { fn db_read_cursor(&self) -> Result, ChainStorageError> { let cursor = self.txn.cursor(self.db_validator_nodes.clone())?; let access = self.txn.access(); @@ -131,6 +132,26 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> Ok(cursor) } + pub fn get_vn_set_until_epoch( + &self, + epoch: VnEpoch, + sidechain_id: Option, + ) -> Result, ChainStorageError> { + let mut cursor = self.db_read_cursor()?; + let mut result = vec![]; + while let Ok(Some((_, value))) = cursor.next::() { + if value.sidechain_id == sidechain_id && value.start_epoch <= epoch { + result.push(ValidatorNodeRegistrationInfo { + public_key: value.public_key, + sidechain_id: value.sidechain_id, + shard_key: [], + }); + } + } + + Ok(result) + } + /// Returns a set of tuples ordered by height of registration. /// This set contains no duplicates. If a duplicate registration is found, the last registration is included. pub fn get_vn_set( @@ -156,7 +177,7 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> sidechain_id: vn.sidechain_id, shard_key: vn.shard_key, })); - }, + } None => return Ok(Vec::new()), } @@ -212,7 +233,7 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> return Ok(None); } Some(s) - }, + } None => return Ok(None), }; @@ -243,7 +264,7 @@ mod tests { const DBS: &[&str] = &["validator_node_store", "validator_node_index"]; - fn create_store<'a, Txn: Deref>>( + fn create_store<'a, Txn: Deref>>( db: &TempLmdbDatabase, txn: &'a Txn, ) -> ValidatorNodeStore<'a, Txn> { diff --git a/base_layer/core/src/consensus/consensus_constants.rs b/base_layer/core/src/consensus/consensus_constants.rs index b5235fd6d0..ddae89961a 100644 --- a/base_layer/core/src/consensus/consensus_constants.rs +++ b/base_layer/core/src/consensus/consensus_constants.rs @@ -115,14 +115,17 @@ pub struct ConsensusConstants { max_covenant_length: u32, /// Epoch duration in blocks vn_epoch_length: u64, - /// The number of Epochs that a validator node registration is valid - vn_validity_period_epochs: VnEpoch, /// The min amount of micro Minotari to deposit for a registration transaction to be allowed onto the blockchain vn_registration_min_deposit_amount: MicroMinotari, /// The period that the registration funds are required to be locked up. vn_registration_lock_height: u64, /// The period after which the VNs will be reshuffled. vn_registration_shuffle_interval: VnEpoch, + /// Maximum number of validator nodes activated initially + /// (in the first epoch when we do not have any vns yet). + vn_registration_max_vns_initial_epoch: u64, + /// Maximum number of validator nodes activated in an epoch. + vn_registration_max_vns_per_epoch: u64, } #[derive(Debug, Clone)] @@ -342,10 +345,6 @@ impl ConsensusConstants { self.max_covenant_length } - pub fn validator_node_validity_period_epochs(&self) -> VnEpoch { - self.vn_validity_period_epochs - } - pub fn validator_node_registration_shuffle_interval(&self) -> VnEpoch { self.vn_registration_shuffle_interval } @@ -413,11 +412,12 @@ impl ConsensusConstants { permitted_range_proof_types: Self::all_range_proof_types(), max_covenant_length: 100, vn_epoch_length: 10, - vn_validity_period_epochs: VnEpoch(100), vn_registration_min_deposit_amount: MicroMinotari(0), vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, + vn_registration_max_vns_initial_epoch: 50, + vn_registration_max_vns_per_epoch: 10, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[120], &[50], &[50]); @@ -479,11 +479,12 @@ impl ConsensusConstants { permitted_range_proof_types: Self::all_range_proof_types(), max_covenant_length: 100, vn_epoch_length: 10, - vn_validity_period_epochs: VnEpoch(3), vn_registration_min_deposit_amount: MicroMinotari(0), vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, + vn_registration_max_vns_initial_epoch: 50, + vn_registration_max_vns_per_epoch: 10, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[target_time], &[randomx_split], &[sha3x_split]); @@ -536,11 +537,12 @@ impl ConsensusConstants { permitted_range_proof_types: Self::current_permitted_range_proof_types(), max_covenant_length: 0, vn_epoch_length: 60, - vn_validity_period_epochs: VnEpoch(100), vn_registration_min_deposit_amount: MicroMinotari(0), vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, + vn_registration_max_vns_initial_epoch: 50, + vn_registration_max_vns_per_epoch: 10, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[120], &[50], &[50]); @@ -593,11 +595,12 @@ impl ConsensusConstants { permitted_range_proof_types: Self::current_permitted_range_proof_types(), max_covenant_length: 0, vn_epoch_length: 60, - vn_validity_period_epochs: VnEpoch(100), vn_registration_min_deposit_amount: MicroMinotari(0), vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, + vn_registration_max_vns_initial_epoch: 50, + vn_registration_max_vns_per_epoch: 10, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[120], &[50], &[50]); @@ -644,11 +647,12 @@ impl ConsensusConstants { permitted_range_proof_types: Self::current_permitted_range_proof_types(), max_covenant_length: 0, vn_epoch_length: 60, - vn_validity_period_epochs: VnEpoch(100), vn_registration_min_deposit_amount: MicroMinotari(0), vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, + vn_registration_max_vns_initial_epoch: 50, + vn_registration_max_vns_per_epoch: 10, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[120], &[50], &[50]); @@ -697,11 +701,12 @@ impl ConsensusConstants { permitted_range_proof_types: Self::current_permitted_range_proof_types(), max_covenant_length: 0, vn_epoch_length: 60, - vn_validity_period_epochs: VnEpoch(100), vn_registration_min_deposit_amount: MicroMinotari(0), vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, + vn_registration_max_vns_initial_epoch: 50, + vn_registration_max_vns_per_epoch: 10, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[120], &[50], &[50]); From 5e74ce327f263d0ff8f9766a1fb27ebf92219347 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Wed, 30 Oct 2024 15:01:25 +0100 Subject: [PATCH 02/23] impl in progress --- .../minotari_app_grpc/proto/types.proto | 131 +++++++++--------- .../src/conversions/consensus_constants.rs | 3 +- .../core/src/chain_storage/lmdb_db/lmdb_db.rs | 32 +++-- .../lmdb_db/validator_node_store.rs | 31 +++-- .../core/src/consensus/consensus_constants.rs | 10 +- 5 files changed, 116 insertions(+), 91 deletions(-) diff --git a/applications/minotari_app_grpc/proto/types.proto b/applications/minotari_app_grpc/proto/types.proto index eb6085634b..f44696fc30 100644 --- a/applications/minotari_app_grpc/proto/types.proto +++ b/applications/minotari_app_grpc/proto/types.proto @@ -25,8 +25,8 @@ package tari.rpc; /// An unsigned range interface to more accurately represent Rust native Range's message Range { - uint64 min = 1; - uint64 max = 2; + uint64 min = 1; + uint64 max = 2; } /// An Empty placeholder for endpoints without request parameters @@ -34,113 +34,114 @@ message Empty {} /// Define an interface for block height message BlockHeight { - uint64 block_height = 1; + uint64 block_height = 1; } // Define the explicit Signature implementation for the Minotari base layer. A different signature scheme can be // employed by redefining this type. message Signature { - bytes public_nonce = 1; - bytes signature = 2; + bytes public_nonce = 1; + bytes signature = 2; } // Define the explicit ComAndPubSignature implementation for the Minotari base layer. A different signature scheme can be // employed by redefining this type. message ComAndPubSignature { - bytes ephemeral_commitment = 1; - bytes ephemeral_pubkey = 2; - bytes u_a = 3; - bytes u_x = 4; - bytes u_y = 5; + bytes ephemeral_commitment = 1; + bytes ephemeral_pubkey = 2; + bytes u_a = 3; + bytes u_x = 4; + bytes u_y = 5; } // Define the explicit CommitmentSignature implementation for the Minotari base layer. A different signature scheme can be // employed by redefining this type message CommitmentSignature { - bytes public_nonce = 1; - bytes u = 2; - bytes v = 3; + bytes public_nonce = 1; + bytes u = 2; + bytes v = 3; } /// PoW Algorithm constants message PowAlgorithmConstants { - uint64 min_difficulty = 2; - uint64 max_difficulty = 3; - uint64 target_time = 4; + uint64 min_difficulty = 2; + uint64 max_difficulty = 3; + uint64 target_time = 4; } /// Weight params message WeightParams { - uint64 kernel_weight = 1; - uint64 input_weight = 2; - uint64 output_weight = 3; - uint64 features_and_scripts_bytes_per_gram = 4; + uint64 kernel_weight = 1; + uint64 input_weight = 2; + uint64 output_weight = 3; + uint64 features_and_scripts_bytes_per_gram = 4; } /// Output version message OutputsVersion { - Range outputs = 1; - Range features = 2; + Range outputs = 1; + Range features = 2; } /// Output types enum OutputType { - STANDARD = 0; - COINBASE = 1; - BURN = 2; - VALIDATOR_NODE_REGISTRATION = 3; - CODE_TEMPLATE_REGISTRATION = 4; + STANDARD = 0; + COINBASE = 1; + BURN = 2; + VALIDATOR_NODE_REGISTRATION = 3; + CODE_TEMPLATE_REGISTRATION = 4; } /// Range proof types enum RangeProofType { - BULLETPROOF_PLUS = 0; - REVEALED_VALUE = 1; + BULLETPROOF_PLUS = 0; + REVEALED_VALUE = 1; } message PermittedRangeProofs { - OutputType output_type = 1; - repeated RangeProofType range_proof_types = 2; + OutputType output_type = 1; + repeated RangeProofType range_proof_types = 2; } /// Range proof message RangeProof { - bytes proof_bytes = 1; + bytes proof_bytes = 1; } /// Consensus Constants response message ConsensusConstants { - uint64 coinbase_min_maturity = 1; - uint32 blockchain_version = 2; - uint64 future_time_limit = 3; - uint64 difficulty_block_window = 5; - uint64 max_block_transaction_weight = 7; - uint64 pow_algo_count = 8; - uint64 median_timestamp_count = 9; - uint64 emission_initial = 10; - repeated uint64 emission_decay = 11; - uint64 emission_tail = 12 [deprecated=true]; - uint64 min_sha3x_pow_difficulty = 13; - uint64 block_weight_inputs = 14; - uint64 block_weight_outputs = 15; - uint64 block_weight_kernels = 16; - uint64 pre_mine_value = 17; - uint64 max_script_byte_size = 18; - uint64 validator_node_validity_period = 19; - uint64 effective_from_height = 20; - Range valid_blockchain_version_range = 21; - uint64 max_randomx_seed_height = 22; - map proof_of_work = 23; - WeightParams transaction_weight = 24; - Range input_version_range = 26; - OutputsVersion output_version_range = 27; - Range kernel_version_range = 28; - repeated OutputType permitted_output_types = 29; - uint64 epoch_length = 30; - uint64 validator_node_registration_min_deposit_amount = 31; - uint64 validator_node_registration_min_lock_height = 32; - uint64 validator_node_registration_shuffle_interval_epoch = 33; - repeated PermittedRangeProofs permitted_range_proof_types = 34; - uint64 inflation_bips = 35; - uint64 tail_epoch_length = 36; + uint64 coinbase_min_maturity = 1; + uint32 blockchain_version = 2; + uint64 future_time_limit = 3; + uint64 difficulty_block_window = 5; + uint64 max_block_transaction_weight = 7; + uint64 pow_algo_count = 8; + uint64 median_timestamp_count = 9; + uint64 emission_initial = 10; + repeated uint64 emission_decay = 11; + uint64 emission_tail = 12 [deprecated = true]; + uint64 min_sha3x_pow_difficulty = 13; + uint64 block_weight_inputs = 14; + uint64 block_weight_outputs = 15; + uint64 block_weight_kernels = 16; + uint64 pre_mine_value = 17; + uint64 max_script_byte_size = 18; + uint64 vn_registration_max_vns_initial_epoch = 19; + uint64 vn_registration_max_vns_per_epoch = 20; + uint64 effective_from_height = 21; + Range valid_blockchain_version_range = 22; + uint64 max_randomx_seed_height = 23; + map proof_of_work = 24; + WeightParams transaction_weight = 25; + Range input_version_range = 26; + OutputsVersion output_version_range = 27; + Range kernel_version_range = 28; + repeated OutputType permitted_output_types = 29; + uint64 epoch_length = 30; + uint64 validator_node_registration_min_deposit_amount = 31; + uint64 validator_node_registration_min_lock_height = 32; + uint64 validator_node_registration_shuffle_interval_epoch = 33; + repeated PermittedRangeProofs permitted_range_proof_types = 34; + uint64 inflation_bips = 35; + uint64 tail_epoch_length = 36; } diff --git a/applications/minotari_app_grpc/src/conversions/consensus_constants.rs b/applications/minotari_app_grpc/src/conversions/consensus_constants.rs index 8bf7dfb797..fe7e403dcb 100644 --- a/applications/minotari_app_grpc/src/conversions/consensus_constants.rs +++ b/applications/minotari_app_grpc/src/conversions/consensus_constants.rs @@ -130,7 +130,6 @@ impl From for grpc::ConsensusConstants { output_version_range: Some(output_version_range), permitted_output_types, permitted_range_proof_types, - validator_node_validity_period: cc.validator_node_validity_period_epochs().as_u64(), epoch_length: cc.epoch_length(), validator_node_registration_min_deposit_amount: cc .validator_node_registration_min_deposit_amount() @@ -139,6 +138,8 @@ impl From for grpc::ConsensusConstants { validator_node_registration_shuffle_interval_epoch: cc .validator_node_registration_shuffle_interval() .as_u64(), + vn_registration_max_vns_initial_epoch: cc.vn_registration_max_vns_initial_epoch(), + vn_registration_max_vns_per_epoch: cc.vn_registration_max_vns_per_epoch(), } } } diff --git a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs index 2bde104d34..09e8a6a864 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs @@ -1379,10 +1379,7 @@ impl LMDBDatabase { let current_epoch = constants.block_height_to_epoch(header.height); let prev_shard_key = store.get_shard_key( - current_epoch - .as_u64() - .saturating_sub(constants.validator_node_validity_period_epochs().as_u64()) * - constants.epoch_length(), + 0, current_epoch.as_u64() * constants.epoch_length(), vn_reg.public_key(), )?; @@ -1392,10 +1389,19 @@ impl LMDBDatabase { constants.validator_node_registration_shuffle_interval(), &header.prev_hash, ); - - let next_epoch = current_epoch + VnEpoch(1); - // TODO: looking for next available epoch - store.get_vn_set() + + let mut next_epoch = current_epoch + VnEpoch(1); + + // looking for next available epoch + let current_vn_count = store.get_vn_count_until_epoch(current_epoch, vn_reg.sidechain_id().cloned())?; + let mut vn_count = store.get_vn_count_in_epoch(next_epoch, vn_reg.sidechain_id().cloned())?; + if (current_vn_count == 0 && vn_count >= constants.vn_registration_max_vns_initial_epoch()) || + (current_vn_count > 0 && vn_count > constants.vn_registration_max_vns_per_epoch()) { + while vn_count > constants.vn_registration_max_vns_per_epoch() { + next_epoch += VnEpoch(1); + vn_count = store.get_vn_count_in_epoch(next_epoch, vn_reg.sidechain_id().cloned())?; + } + } let validator_node = ValidatorNodeEntry { shard_key, @@ -2481,12 +2487,10 @@ impl BlockchainBackend for LMDBDatabase { // Get the current epoch for the height let end_epoch = constants.block_height_to_epoch(height); - // Subtract the registration validaty period to get the start epoch - let start_epoch = end_epoch.saturating_sub(constants.validator_node_validity_period_epochs()); // Convert these back to height as validators regs are indexed by height - let start_height = start_epoch.as_u64() * constants.epoch_length(); let end_height = end_epoch.as_u64() * constants.epoch_length(); - let nodes = vn_store.get_vn_set(start_height, end_height)?; + // TODO: replace with a call without start height + let nodes = vn_store.get_vn_set(0, end_height)?; Ok(nodes) } @@ -2510,10 +2514,8 @@ impl BlockchainBackend for LMDBDatabase { // Get the epoch height boundaries for our query let current_epoch = constants.block_height_to_epoch(height); - let start_epoch = current_epoch.saturating_sub(constants.validator_node_validity_period_epochs()); - let start_height = start_epoch.as_u64() * constants.epoch_length(); let end_height = current_epoch.as_u64() * constants.epoch_length(); - let maybe_shard_id = store.get_shard_key(start_height, end_height, &public_key)?; + let maybe_shard_id = store.get_shard_key(0, end_height, &public_key)?; Ok(maybe_shard_id) } diff --git a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs index 2e5d96e255..9a1636f460 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs @@ -33,7 +33,6 @@ use crate::chain_storage::{ ValidatorNodeRegistrationInfo, }; use lmdb_zero::{ConstTransaction, WriteTransaction}; -use serde::de::Unexpected::Option; use tari_common_types::epoch::VnEpoch; use tari_common_types::types::{Commitment, PublicKey}; use tari_storage::lmdb_store::DatabaseRef; @@ -132,20 +131,34 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { Ok(cursor) } - pub fn get_vn_set_until_epoch( + /// Returns validator nodes until a given epoch. + pub fn get_vn_count_until_epoch( &self, epoch: VnEpoch, sidechain_id: Option, - ) -> Result, ChainStorageError> { + ) -> Result { let mut cursor = self.db_read_cursor()?; - let mut result = vec![]; + let mut result = 0; while let Ok(Some((_, value))) = cursor.next::() { if value.sidechain_id == sidechain_id && value.start_epoch <= epoch { - result.push(ValidatorNodeRegistrationInfo { - public_key: value.public_key, - sidechain_id: value.sidechain_id, - shard_key: [], - }); + result += 1; + } + } + + Ok(result) + } + + /// Returns validator nodes in a given epoch. + pub fn get_vn_count_in_epoch( + &self, + epoch: VnEpoch, + sidechain_id: Option, + ) -> Result { + let mut cursor = self.db_read_cursor()?; + let mut result = 0; + while let Ok(Some((_, value))) = cursor.next::() { + if value.sidechain_id == sidechain_id && value.start_epoch == epoch { + result += 1; } } diff --git a/base_layer/core/src/consensus/consensus_constants.rs b/base_layer/core/src/consensus/consensus_constants.rs index ddae89961a..baad3bf93e 100644 --- a/base_layer/core/src/consensus/consensus_constants.rs +++ b/base_layer/core/src/consensus/consensus_constants.rs @@ -121,7 +121,7 @@ pub struct ConsensusConstants { vn_registration_lock_height: u64, /// The period after which the VNs will be reshuffled. vn_registration_shuffle_interval: VnEpoch, - /// Maximum number of validator nodes activated initially + /// Maximum number of validator nodes activated initially /// (in the first epoch when we do not have any vns yet). vn_registration_max_vns_initial_epoch: u64, /// Maximum number of validator nodes activated in an epoch. @@ -367,6 +367,14 @@ impl ConsensusConstants { epoch.as_u64() * self.vn_epoch_length } + pub fn vn_registration_max_vns_initial_epoch(&self) -> u64 { + self.vn_registration_max_vns_initial_epoch + } + + pub fn vn_registration_max_vns_per_epoch(&self) -> u64 { + self.vn_registration_max_vns_per_epoch + } + pub fn epoch_length(&self) -> u64 { self.vn_epoch_length } From a942896a8adb78b08367b5185eb7a14b36925958 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Thu, 31 Oct 2024 15:21:41 +0100 Subject: [PATCH 03/23] impl in progress --- .../minotari_app_grpc/proto/base_node.proto | 570 +++++++++--------- .../src/grpc/base_node_grpc_server.rs | 144 ++--- applications/minotari_node/src/grpc_method.rs | 8 +- 3 files changed, 376 insertions(+), 346 deletions(-) diff --git a/applications/minotari_app_grpc/proto/base_node.proto b/applications/minotari_app_grpc/proto/base_node.proto index 0a969b6255..e92c8227e0 100644 --- a/applications/minotari_app_grpc/proto/base_node.proto +++ b/applications/minotari_app_grpc/proto/base_node.proto @@ -31,292 +31,293 @@ package tari.rpc; // The gRPC interface for interacting with the base node. service BaseNode { - // Lists headers in the current best chain - rpc ListHeaders(ListHeadersRequest) returns (stream BlockHeaderResponse); - // Get header by hash - rpc GetHeaderByHash(GetHeaderByHashRequest) returns (BlockHeaderResponse); - // Returns blocks in the current best chain. Currently only supports querying by height - rpc GetBlocks(GetBlocksRequest) returns (stream HistoricalBlock); - // Returns the block timing for the chain heights - rpc GetBlockTiming(HeightRequest) returns (BlockTimingResponse); - // Returns the network Constants - rpc GetConstants(BlockHeight) returns (ConsensusConstants); - // Returns Block Sizes - rpc GetBlockSize (BlockGroupRequest) returns (BlockGroupResponse); - // Returns Block Fees - rpc GetBlockFees (BlockGroupRequest) returns (BlockGroupResponse); - // Get Version - rpc GetVersion(Empty) returns (StringValue); - // Check for new updates - rpc CheckForUpdates(Empty) returns (SoftwareUpdate); - // Get coins in circulation - rpc GetTokensInCirculation(GetBlocksRequest) returns (stream ValueAtHeightResponse); - // Get network difficulties - rpc GetNetworkDifficulty(HeightRequest) returns (stream NetworkDifficultyResponse); - // Get the block template - rpc GetNewBlockTemplate(NewBlockTemplateRequest) returns (NewBlockTemplateResponse); - // Construct a new block from a provided template - rpc GetNewBlock(NewBlockTemplate) returns (GetNewBlockResult); - // Construct a new block from a provided template - rpc GetNewBlockWithCoinbases(GetNewBlockWithCoinbasesRequest) returns (GetNewBlockResult); - // Construct a new block from a provided template - rpc GetNewBlockTemplateWithCoinbases(GetNewBlockTemplateWithCoinbasesRequest) returns (GetNewBlockResult); - // Construct a new block and header blob from a provided template - rpc GetNewBlockBlob(NewBlockTemplate) returns (GetNewBlockBlobResult); - // Submit a new block for propagation - rpc SubmitBlock(Block) returns (SubmitBlockResponse); - // Submit a new mined block blob for propagation - rpc SubmitBlockBlob(BlockBlobRequest) returns (SubmitBlockResponse); - // Submit a transaction for propagation - rpc SubmitTransaction(SubmitTransactionRequest) returns (SubmitTransactionResponse); - // Get the base node sync information - rpc GetSyncInfo(Empty) returns (SyncInfoResponse); - // Get the base node sync information - rpc GetSyncProgress(Empty) returns (SyncProgressResponse); - // Get the base node tip information - rpc GetTipInfo(Empty) returns (TipInfoResponse); - // Search for blocks containing the specified kernels - rpc SearchKernels(SearchKernelsRequest) returns (stream HistoricalBlock); - // Search for blocks containing the specified commitments - rpc SearchUtxos(SearchUtxosRequest) returns (stream HistoricalBlock); - // Fetch any utxos that exist in the main chain - rpc FetchMatchingUtxos(FetchMatchingUtxosRequest) returns (stream FetchMatchingUtxosResponse); - // get all peers from the base node - rpc GetPeers(GetPeersRequest) returns (stream GetPeersResponse); - rpc GetMempoolTransactions(GetMempoolTransactionsRequest) returns (stream GetMempoolTransactionsResponse); - rpc TransactionState(TransactionStateRequest) returns (TransactionStateResponse); - // This returns the node's network identity - rpc Identify (Empty) returns (NodeIdentity); - // Get Base Node network connectivity status - rpc GetNetworkStatus(Empty) returns (NetworkStatusResponse); - // List currently connected peers - rpc ListConnectedPeers(Empty) returns (ListConnectedPeersResponse); - // Get mempool stats - rpc GetMempoolStats(Empty) returns (MempoolStatsResponse); - // Get VNs - rpc GetActiveValidatorNodes(GetActiveValidatorNodesRequest) returns (stream GetActiveValidatorNodesResponse); - rpc GetShardKey(GetShardKeyRequest) returns (GetShardKeyResponse); - // Get templates - rpc GetTemplateRegistrations(GetTemplateRegistrationsRequest) returns (stream GetTemplateRegistrationResponse); - rpc GetSideChainUtxos(GetSideChainUtxosRequest) returns (stream GetSideChainUtxosResponse); + // Lists headers in the current best chain + rpc ListHeaders(ListHeadersRequest) returns (stream BlockHeaderResponse); + // Get header by hash + rpc GetHeaderByHash(GetHeaderByHashRequest) returns (BlockHeaderResponse); + // Returns blocks in the current best chain. Currently only supports querying by height + rpc GetBlocks(GetBlocksRequest) returns (stream HistoricalBlock); + // Returns the block timing for the chain heights + rpc GetBlockTiming(HeightRequest) returns (BlockTimingResponse); + // Returns the network Constants + rpc GetConstants(BlockHeight) returns (ConsensusConstants); + // Returns Block Sizes + rpc GetBlockSize (BlockGroupRequest) returns (BlockGroupResponse); + // Returns Block Fees + rpc GetBlockFees (BlockGroupRequest) returns (BlockGroupResponse); + // Get Version + rpc GetVersion(Empty) returns (StringValue); + // Check for new updates + rpc CheckForUpdates(Empty) returns (SoftwareUpdate); + // Get coins in circulation + rpc GetTokensInCirculation(GetBlocksRequest) returns (stream ValueAtHeightResponse); + // Get network difficulties + rpc GetNetworkDifficulty(HeightRequest) returns (stream NetworkDifficultyResponse); + // Get the block template + rpc GetNewBlockTemplate(NewBlockTemplateRequest) returns (NewBlockTemplateResponse); + // Construct a new block from a provided template + rpc GetNewBlock(NewBlockTemplate) returns (GetNewBlockResult); + // Construct a new block from a provided template + rpc GetNewBlockWithCoinbases(GetNewBlockWithCoinbasesRequest) returns (GetNewBlockResult); + // Construct a new block from a provided template + rpc GetNewBlockTemplateWithCoinbases(GetNewBlockTemplateWithCoinbasesRequest) returns (GetNewBlockResult); + // Construct a new block and header blob from a provided template + rpc GetNewBlockBlob(NewBlockTemplate) returns (GetNewBlockBlobResult); + // Submit a new block for propagation + rpc SubmitBlock(Block) returns (SubmitBlockResponse); + // Submit a new mined block blob for propagation + rpc SubmitBlockBlob(BlockBlobRequest) returns (SubmitBlockResponse); + // Submit a transaction for propagation + rpc SubmitTransaction(SubmitTransactionRequest) returns (SubmitTransactionResponse); + // Get the base node sync information + rpc GetSyncInfo(Empty) returns (SyncInfoResponse); + // Get the base node sync information + rpc GetSyncProgress(Empty) returns (SyncProgressResponse); + // Get the base node tip information + rpc GetTipInfo(Empty) returns (TipInfoResponse); + // Search for blocks containing the specified kernels + rpc SearchKernels(SearchKernelsRequest) returns (stream HistoricalBlock); + // Search for blocks containing the specified commitments + rpc SearchUtxos(SearchUtxosRequest) returns (stream HistoricalBlock); + // Fetch any utxos that exist in the main chain + rpc FetchMatchingUtxos(FetchMatchingUtxosRequest) returns (stream FetchMatchingUtxosResponse); + // get all peers from the base node + rpc GetPeers(GetPeersRequest) returns (stream GetPeersResponse); + rpc GetMempoolTransactions(GetMempoolTransactionsRequest) returns (stream GetMempoolTransactionsResponse); + rpc TransactionState(TransactionStateRequest) returns (TransactionStateResponse); + // This returns the node's network identity + rpc Identify (Empty) returns (NodeIdentity); + // Get Base Node network connectivity status + rpc GetNetworkStatus(Empty) returns (NetworkStatusResponse); + // List currently connected peers + rpc ListConnectedPeers(Empty) returns (ListConnectedPeersResponse); + // Get mempool stats + rpc GetMempoolStats(Empty) returns (MempoolStatsResponse); + // Get VNs + rpc GetActiveValidatorNodes(GetActiveValidatorNodesRequest) returns (stream GetActiveValidatorNodesResponse); + rpc GetValidatorNodeChanges(GetValidatorNodeChangesRequest) returns (GetValidatorNodeChangesResponse); + rpc GetShardKey(GetShardKeyRequest) returns (GetShardKeyResponse); + // Get templates + rpc GetTemplateRegistrations(GetTemplateRegistrationsRequest) returns (stream GetTemplateRegistrationResponse); + rpc GetSideChainUtxos(GetSideChainUtxosRequest) returns (stream GetSideChainUtxosResponse); } message GetAssetMetadataRequest { - bytes asset_public_key = 1; + bytes asset_public_key = 1; } message GetAssetMetadataResponse { - string name = 2; - string description =3; - string image = 4; - bytes owner_commitment = 5; - OutputFeatures features = 6; - uint64 mined_height = 7; - bytes mined_in_block = 8; + string name = 2; + string description = 3; + string image = 4; + bytes owner_commitment = 5; + OutputFeatures features = 6; + uint64 mined_height = 7; + bytes mined_in_block = 8; } message ListAssetRegistrationsRequest { - uint64 offset = 2; - uint64 count = 3; + uint64 offset = 2; + uint64 count = 3; } message ListAssetRegistrationsResponse { - bytes asset_public_key = 1; - bytes unique_id = 2; - bytes owner_commitment = 3; - uint64 mined_height = 4; - bytes mined_in_block = 5; - OutputFeatures features = 6; - bytes script = 7; + bytes asset_public_key = 1; + bytes unique_id = 2; + bytes owner_commitment = 3; + uint64 mined_height = 4; + bytes mined_in_block = 5; + OutputFeatures features = 6; + bytes script = 7; } message GetTokensRequest { - bytes asset_public_key = 1; - // Optionally get a set of specific unique_ids - repeated bytes unique_ids = 2; + bytes asset_public_key = 1; + // Optionally get a set of specific unique_ids + repeated bytes unique_ids = 2; } message GetTokensResponse { - bytes unique_id = 1; - bytes asset_public_key = 2; - bytes owner_commitment = 3; - bytes mined_in_block = 4; - uint64 mined_height = 5; - OutputFeatures features = 6; - bytes script = 7; + bytes unique_id = 1; + bytes asset_public_key = 2; + bytes owner_commitment = 3; + bytes mined_in_block = 4; + uint64 mined_height = 5; + OutputFeatures features = 6; + bytes script = 7; } message SubmitBlockResponse { - bytes block_hash = 1; + bytes block_hash = 1; } message BlockBlobRequest{ - bytes header_blob = 1; - bytes body_blob = 2; + bytes header_blob = 1; + bytes body_blob = 2; } /// return type of GetTipInfo message TipInfoResponse { - MetaData metadata = 1; - bool initial_sync_achieved = 2; - BaseNodeState base_node_state = 3; + MetaData metadata = 1; + bool initial_sync_achieved = 2; + BaseNodeState base_node_state = 3; } enum BaseNodeState{ - START_UP = 0; - HEADER_SYNC = 1; - HORIZON_SYNC = 2; - CONNECTING = 3; - BLOCK_SYNC = 4; - LISTENING = 5; - SYNC_FAILED = 6; + START_UP = 0; + HEADER_SYNC = 1; + HORIZON_SYNC = 2; + CONNECTING = 3; + BLOCK_SYNC = 4; + LISTENING = 5; + SYNC_FAILED = 6; } /// return type of GetNewBlockTemplate message NewBlockTemplateResponse { - NewBlockTemplate new_block_template = 1; - bool initial_sync_achieved = 3; - MinerData miner_data = 4; + NewBlockTemplate new_block_template = 1; + bool initial_sync_achieved = 3; + MinerData miner_data = 4; } /// return type of NewBlockTemplateRequest message NewBlockTemplateRequest{ - PowAlgo algo = 1; - //This field should be moved to optional once optional keyword is standard - uint64 max_weight = 2; + PowAlgo algo = 1; + //This field should be moved to optional once optional keyword is standard + uint64 max_weight = 2; } /// return type of NewBlockTemplateRequest message GetNewBlockTemplateWithCoinbasesRequest{ - PowAlgo algo = 1; - //This field should be moved to optional once optional keyword is standard - uint64 max_weight = 2; - repeated NewBlockCoinbase coinbases = 3; + PowAlgo algo = 1; + //This field should be moved to optional once optional keyword is standard + uint64 max_weight = 2; + repeated NewBlockCoinbase coinbases = 3; } /// request type of GetNewBlockWithCoinbasesRequest message GetNewBlockWithCoinbasesRequest{ - NewBlockTemplate new_template = 1; - repeated NewBlockCoinbase coinbases = 2; + NewBlockTemplate new_template = 1; + repeated NewBlockCoinbase coinbases = 2; } message NewBlockCoinbase{ - string address = 1; - uint64 value = 2; - bool stealth_payment= 3; - bool revealed_value_proof= 4; - bytes coinbase_extra =5; + string address = 1; + uint64 value = 2; + bool stealth_payment = 3; + bool revealed_value_proof = 4; + bytes coinbase_extra = 5; } // Network difficulty response message NetworkDifficultyResponse { - uint64 difficulty = 1; - uint64 estimated_hash_rate = 2; - uint64 height = 3; - uint64 timestamp = 4; - uint64 pow_algo = 5; - uint64 sha3x_estimated_hash_rate = 6; - uint64 randomx_estimated_hash_rate = 7; - uint64 num_coinbases = 8; - repeated bytes coinbase_extras = 9; + uint64 difficulty = 1; + uint64 estimated_hash_rate = 2; + uint64 height = 3; + uint64 timestamp = 4; + uint64 pow_algo = 5; + uint64 sha3x_estimated_hash_rate = 6; + uint64 randomx_estimated_hash_rate = 7; + uint64 num_coinbases = 8; + repeated bytes coinbase_extras = 9; } // A generic single value response for a specific height message ValueAtHeightResponse { - uint64 value= 1; - uint64 height = 2; + uint64 value = 1; + uint64 height = 2; } // A generic uint value message IntegerValue { - uint64 value = 1; + uint64 value = 1; } // A generic String value message StringValue { - string value = 1; + string value = 1; } /// GetBlockSize / GetBlockFees Request /// Either the starting and ending heights OR the from_tip param must be specified message BlockGroupRequest { - // The height from the chain tip (optional) - uint64 from_tip = 1; - // The starting height (optional) - uint64 start_height = 2; - // The ending height (optional) - uint64 end_height = 3; - /// The type of calculation required (optional) - /// Defaults to median - /// median, mean, quartile, quantile - CalcType calc_type = 4; + // The height from the chain tip (optional) + uint64 from_tip = 1; + // The starting height (optional) + uint64 start_height = 2; + // The ending height (optional) + uint64 end_height = 3; + /// The type of calculation required (optional) + /// Defaults to median + /// median, mean, quartile, quantile + CalcType calc_type = 4; } /// GetBlockSize / GetBlockFees Response message BlockGroupResponse { - repeated double value = 1; - CalcType calc_type = 2; + repeated double value = 1; + CalcType calc_type = 2; } enum CalcType { - MEAN = 0; - MEDIAN = 1; - QUANTILE = 2; - QUARTILE = 3; + MEAN = 0; + MEDIAN = 1; + QUANTILE = 2; + QUARTILE = 3; } // The request used for querying a function that requires a height, either between 2 points or from the chain tip // If start_height and end_height are set and > 0, they take precedence, otherwise from_tip is used message HeightRequest { - // The height from the chain tip (optional) - uint64 from_tip = 1; - // The starting height (optional) - uint64 start_height = 2; - // The ending height (optional) - uint64 end_height = 3; + // The height from the chain tip (optional) + uint64 from_tip = 1; + // The starting height (optional) + uint64 start_height = 2; + // The ending height (optional) + uint64 end_height = 3; } // The return type of the rpc GetBlockTiming message BlockTimingResponse { - uint64 max = 1; - uint64 min = 2; - double avg = 3; + uint64 max = 1; + uint64 min = 2; + double avg = 3; } // Request that returns a header based by hash message GetHeaderByHashRequest { - // The hash of the block header - bytes hash = 1; + // The hash of the block header + bytes hash = 1; } message BlockHeaderResponse { - // The block header - BlockHeader header = 1; - // The number of blocks from the tip of this block (a.k.a depth) - uint64 confirmations = 2; - // The block reward i.e mining reward + fees - uint64 reward = 3; - // Achieved difficulty - uint64 difficulty = 4; - // The number of transactions contained in the block - uint32 num_transactions = 5; + // The block header + BlockHeader header = 1; + // The number of blocks from the tip of this block (a.k.a depth) + uint64 confirmations = 2; + // The block reward i.e mining reward + fees + uint64 reward = 3; + // Achieved difficulty + uint64 difficulty = 4; + // The number of transactions contained in the block + uint32 num_transactions = 5; } // The request used for querying headers from the base node. The parameters `from_height` and `num_headers` can be used // to page through the current best chain. message ListHeadersRequest { - // The height to start at. Depending on sorting, will either default to use the tip or genesis block, for `SORTING_DESC` - // and `SORTING_ASC` respectively, if a value is not provided. The first header returned will be at this height - // followed by `num_headers` - 1 headers in the direction specified by `sorting`. If greater than the current tip, - // the current tip will be used. - uint64 from_height = 1; - // The number of headers to return. If not specified, it will default to 10 - uint64 num_headers = 2; - // The ordering to return the headers in. If not specified will default to SORTING_DESC. Note that if `from_height` - // is not specified or is 0, if `sorting` is SORTING_DESC, the tip will be used as `from_height`, otherwise the - // block at height 0 will be used. - Sorting sorting = 3; + // The height to start at. Depending on sorting, will either default to use the tip or genesis block, for `SORTING_DESC` + // and `SORTING_ASC` respectively, if a value is not provided. The first header returned will be at this height + // followed by `num_headers` - 1 headers in the direction specified by `sorting`. If greater than the current tip, + // the current tip will be used. + uint64 from_height = 1; + // The number of headers to return. If not specified, it will default to 10 + uint64 num_headers = 2; + // The ordering to return the headers in. If not specified will default to SORTING_DESC. Note that if `from_height` + // is not specified or is 0, if `sorting` is SORTING_DESC, the tip will be used as `from_height`, otherwise the + // block at height 0 will be used. + Sorting sorting = 3; } // The request used for querying blocks in the base node's current best chain. Currently only querying by height is @@ -328,121 +329,121 @@ message GetBlocksRequest { // The return type of the rpc GetBlocks. Blocks are not guaranteed to be returned in the order requested. message GetBlocksResponse { - repeated HistoricalBlock blocks = 1; + repeated HistoricalBlock blocks = 1; } enum Sorting { - SORTING_DESC = 0; - SORTING_ASC = 1; + SORTING_DESC = 0; + SORTING_ASC = 1; } message MetaData { - // The current chain height, or the block number of the longest valid chain, or `None` if there is no chain - uint64 best_block_height = 1; - // The block hash of the current tip of the longest valid chain, or `None` for an empty chain - bytes best_block_hash = 2; - // The current geometric mean of the pow of the chain tip, or `None` if there is no chain - bytes accumulated_difficulty = 5; - // This is the min height this node can provide complete blocks for. A 0 here means this node is archival and can provide complete blocks for every height. - uint64 pruned_height = 6; - uint64 timestamp = 7; + // The current chain height, or the block number of the longest valid chain, or `None` if there is no chain + uint64 best_block_height = 1; + // The block hash of the current tip of the longest valid chain, or `None` for an empty chain + bytes best_block_hash = 2; + // The current geometric mean of the pow of the chain tip, or `None` if there is no chain + bytes accumulated_difficulty = 5; + // This is the min height this node can provide complete blocks for. A 0 here means this node is archival and can provide complete blocks for every height. + uint64 pruned_height = 6; + uint64 timestamp = 7; } message SyncInfoResponse { - uint64 tip_height = 1; - uint64 local_height = 2; - repeated bytes peer_node_id = 3; + uint64 tip_height = 1; + uint64 local_height = 2; + repeated bytes peer_node_id = 3; } message SyncProgressResponse { - uint64 tip_height = 1; - uint64 local_height = 2; - SyncState state = 3; - string short_desc = 4; - uint64 initial_connected_peers = 5; + uint64 tip_height = 1; + uint64 local_height = 2; + SyncState state = 3; + string short_desc = 4; + uint64 initial_connected_peers = 5; } enum SyncState { - STARTUP = 0; - HEADER_STARTING = 1; - HEADER = 2; - BLOCK_STARTING = 3; - BLOCK = 4; - DONE = 5; + STARTUP = 0; + HEADER_STARTING = 1; + HEADER = 2; + BLOCK_STARTING = 3; + BLOCK = 4; + DONE = 5; } // This is the message that is returned for a miner after it asks for a new block. message GetNewBlockResult{ - // This is the header hash of the completed block - bytes block_hash = 1; - // This is the completed block - Block block = 2; - bytes merge_mining_hash =3; - bytes tari_unique_id =4; - MinerData miner_data = 5; + // This is the header hash of the completed block + bytes block_hash = 1; + // This is the completed block + Block block = 2; + bytes merge_mining_hash = 3; + bytes tari_unique_id = 4; + MinerData miner_data = 5; } // This is the message that is returned for a miner after it asks for a new block. message GetNewBlockBlobResult{ - // This is the header hash of the completed block - bytes block_hash = 1; - // This is the completed block's header - bytes header = 2; - // This is the completed block's body - bytes block_body = 3; - bytes merge_mining_hash =4; - bytes utxo_mr = 5; - bytes tari_unique_id =6; + // This is the header hash of the completed block + bytes block_hash = 1; + // This is the completed block's header + bytes header = 2; + // This is the completed block's body + bytes block_body = 3; + bytes merge_mining_hash = 4; + bytes utxo_mr = 5; + bytes tari_unique_id = 6; } // This is mining data for the miner asking for a new block message MinerData{ - PowAlgo algo = 1; - uint64 target_difficulty = 2; - uint64 reward = 3; -// bytes merge_mining_hash =4; - uint64 total_fees = 5; + PowAlgo algo = 1; + uint64 target_difficulty = 2; + uint64 reward = 3; + // bytes merge_mining_hash =4; + uint64 total_fees = 5; } // This is the request type for the Search Kernels rpc message SearchKernelsRequest{ - repeated Signature signatures = 1; + repeated Signature signatures = 1; } // This is the request type for the Search Utxo rpc message SearchUtxosRequest{ - repeated bytes commitments = 1; + repeated bytes commitments = 1; } message FetchMatchingUtxosRequest { - repeated bytes hashes = 1; + repeated bytes hashes = 1; } message FetchMatchingUtxosResponse { - TransactionOutput output = 1; + TransactionOutput output = 1; } // This is the request type of the get all peers rpc call message GetPeersResponse{ - Peer peer = 1; + Peer peer = 1; } message GetPeersRequest{} message SubmitTransactionRequest { - Transaction transaction = 1; + Transaction transaction = 1; } message SubmitTransactionResponse { - SubmitTransactionResult result =1; + SubmitTransactionResult result = 1; } enum SubmitTransactionResult { - NONE = 0; - ACCEPTED = 1; - NOT_PROCESSABLE_AT_THIS_TIME = 2; - ALREADY_MINED = 3; - REJECTED = 4; + NONE = 0; + ACCEPTED = 1; + NOT_PROCESSABLE_AT_THIS_TIME = 2; + ALREADY_MINED = 3; + REJECTED = 4; } @@ -451,74 +452,93 @@ message GetMempoolTransactionsRequest { } message GetMempoolTransactionsResponse { - Transaction transaction = 1; + Transaction transaction = 1; } message TransactionStateRequest { - Signature excess_sig = 1; + Signature excess_sig = 1; } message TransactionStateResponse { - TransactionLocation result =1; + TransactionLocation result = 1; } enum TransactionLocation { - UNKNOWN = 0; - MEMPOOL = 1; - MINED = 2; - NOT_STORED = 3; + UNKNOWN = 0; + MEMPOOL = 1; + MINED = 2; + NOT_STORED = 3; } message MempoolStatsResponse { - uint64 unconfirmed_txs = 2; - uint64 reorg_txs = 3; - uint64 unconfirmed_weight = 4; + uint64 unconfirmed_txs = 2; + uint64 reorg_txs = 3; + uint64 unconfirmed_weight = 4; } message GetActiveValidatorNodesRequest { - uint64 height = 1; - bytes sidechain_id = 2; + uint64 height = 1; + bytes sidechain_id = 2; } message GetActiveValidatorNodesResponse { - bytes shard_key = 1; - bytes public_key = 2; - bytes sidechain_id = 3; + bytes shard_key = 1; + bytes public_key = 2; + bytes sidechain_id = 3; +} + +message GetValidatorNodeChangesRequest { + uint64 start_epoch = 1; + uint64 end_epoch = 2; +} + +enum ValidatorNodeChangeState { + ADD = 0; + REMOVE = 1; +} + +message ValidatorNodeChange { + bytes public_key = 1; + ValidatorNodeChangeState state = 2; +} + +message GetValidatorNodeChangesResponse { + repeated ValidatorNodeChange changes = 1; } message GetShardKeyRequest { - uint64 height = 1; - bytes public_key = 2; + uint64 height = 1; + bytes public_key = 2; } message GetShardKeyResponse { - bytes shard_key = 1; - bool found = 2; + bytes shard_key = 1; + bool found = 2; } message GetTemplateRegistrationsRequest { - bytes start_hash = 1; - uint64 count = 2; + bytes start_hash = 1; + uint64 count = 2; } message GetTemplateRegistrationResponse { - bytes utxo_hash = 1; - TemplateRegistration registration = 2; + bytes utxo_hash = 1; + TemplateRegistration registration = 2; } message BlockInfo { - uint64 height = 1; - bytes hash = 2; - bytes next_block_hash = 3; + uint64 height = 1; + bytes hash = 2; + bytes next_block_hash = 3; } message GetSideChainUtxosRequest { - bytes start_hash = 1; - uint64 count = 2; + bytes start_hash = 1; + uint64 count = 2; } message GetSideChainUtxosResponse { - BlockInfo block_info = 1; - repeated TransactionOutput outputs = 2; + BlockInfo block_info = 1; + repeated TransactionOutput outputs = 2; } diff --git a/applications/minotari_node/src/grpc/base_node_grpc_server.rs b/applications/minotari_node/src/grpc/base_node_grpc_server.rs index bfa769db02..34243834e3 100644 --- a/applications/minotari_node/src/grpc/base_node_grpc_server.rs +++ b/applications/minotari_node/src/grpc/base_node_grpc_server.rs @@ -26,10 +26,21 @@ use std::{ str::FromStr, }; +use crate::{ + builder::BaseNodeContext, + grpc::{ + blocks::{block_fees, block_heights, block_size, GET_BLOCKS_MAX_HEIGHTS, GET_BLOCKS_PAGE_SIZE}, + hash_rate::HashRateMovingAverage, + helpers::{mean, median}, + }, + grpc_method::GrpcMethod, + BaseNodeConfig, +}; use borsh::{BorshDeserialize, BorshSerialize}; use either::Either; use futures::{channel::mpsc, SinkExt}; use log::*; +use minotari_app_grpc::tari_rpc::{GetValidatorNodeChangesRequest, GetValidatorNodeChangesResponse}; use minotari_app_grpc::{ tari_rpc, tari_rpc::{CalcType, Sorting}, @@ -73,17 +84,6 @@ use tari_utilities::{hex::Hex, message_format::MessageFormat, ByteArray}; use tokio::task; use tonic::{Request, Response, Status}; -use crate::{ - builder::BaseNodeContext, - grpc::{ - blocks::{block_fees, block_heights, block_size, GET_BLOCKS_MAX_HEIGHTS, GET_BLOCKS_PAGE_SIZE}, - hash_rate::HashRateMovingAverage, - helpers::{mean, median}, - }, - grpc_method::GrpcMethod, - BaseNodeConfig, -}; - const LOG_TARGET: &str = "minotari::base_node::grpc"; const GET_TOKENS_IN_CIRCULATION_MAX_HEIGHTS: usize = 1_000_000; const GET_TOKENS_IN_CIRCULATION_PAGE_SIZE: usize = 1_000; @@ -285,7 +285,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ))) .await; return; - }, + } }; if headers.is_empty() { @@ -322,7 +322,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(format!("Error fetching block at height {}", current_height)), ))); return; - }, + } }; if block.is_none() { let _network_difficulty_response = tx.send(Err(obscure_error_if_true( @@ -378,7 +378,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Error communicating with base node: {}", err,); return; - }, + } Ok(data) => data, }; for transaction in transactions.unconfirmed_pool { @@ -400,7 +400,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); } return; - }, + } }; if tx @@ -445,7 +445,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::internal(err.to_string()), )); - }, + } Ok(data) => data.best_block_height(), }; @@ -468,7 +468,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { (res, false) => res + 1, }; (from..=tip, true) - }, + } Sorting::Asc => (0..=num_headers.saturating_sub(1), false), } } else { @@ -479,11 +479,11 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { (res, false) => res + 1, }; (from..=from_height, true) - }, + } Sorting::Asc => { let to = from_height.saturating_add(num_headers).saturating_sub(1); (from_height..=to, false) - }, + } } }; let consensus_rules = self.consensus_rules.clone(); @@ -492,7 +492,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { header_range.end().saturating_add(1), LIST_HEADERS_PAGE_SIZE, ) - .map_err(|e| obscure_error_if_true(report_error_flag, Status::invalid_argument(e)))?; + .map_err(|e| obscure_error_if_true(report_error_flag, Status::invalid_argument(e)))?; task::spawn(async move { trace!( target: LOG_TARGET, @@ -511,7 +511,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Internal base node service error: {}", err); return; - }, + } Ok(data) => { if is_reversed { data.into_iter() @@ -530,7 +530,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { Err(obscure_error_if_true(report_error_flag, Status::internal(e)) .to_string()) - }, + } } }) .rev() @@ -552,18 +552,18 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { Err(obscure_error_if_true(report_error_flag, Status::internal(e)) .to_string()) - }, + } } }) .collect::, String>>() } - }, + } }; match result_data { Err(e) => { error!(target: LOG_TARGET, "No result headers transmitted due to error: {}", e) - }, + } Ok(result_data) => { let result_size = result_data.len(); trace!(target: LOG_TARGET, "Result headers: {}", result_size); @@ -584,7 +584,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { return; } } - }, + } } } }); @@ -680,7 +680,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - }, + } Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -688,13 +688,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - }, + } Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - }, + } }; let fees = new_block.body.get_total_fee().map_err(|_| { obscure_error_if_true( @@ -849,12 +849,12 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { })? - prev_coinbase_value, ) - .map_err(|_| { - obscure_error_if_true( - report_error_flag, - Status::internal("Single coinbase fees exceeded u64".to_string()), - ) - })?; + .map_err(|_| { + obscure_error_if_true( + report_error_flag, + Status::internal("Single coinbase fees exceeded u64".to_string()), + ) + })?; prev_coinbase_value += u128::from(coinbase.value); } @@ -895,8 +895,8 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { range_proof_type, PaymentId::Empty, ) - .await - .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; + .await + .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; new_template.body.add_output(coinbase_output); let new_nonce = key_manager .get_next_key(TransactionKeyManagerBranch::KernelNonce.get_branch_key()) @@ -950,7 +950,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - }, + } Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -958,13 +958,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - }, + } Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - }, + } }; let gen_hash = handler .get_header(0) @@ -1093,8 +1093,8 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { range_proof_type, PaymentId::Empty, ) - .await - .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; + .await + .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; block_template.body.add_output(coinbase_output); let new_nonce = key_manager .get_next_key(TransactionKeyManagerBranch::KernelNonce.get_branch_key()) @@ -1148,7 +1148,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - }, + } Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -1156,13 +1156,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - }, + } Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - }, + } }; let fees = new_block.body.get_total_fee().map_err(|_| { obscure_error_if_true( @@ -1253,7 +1253,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - }, + } Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -1261,13 +1261,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - }, + } Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - }, + } }; // construct response let block_hash = new_block.hash().to_vec(); @@ -1508,7 +1508,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { * should not think its mined, but the * node does not think it is. */ } - }, + } TxStorageResponse::NotStored | TxStorageResponse::NotStoredConsensus | TxStorageResponse::NotStoredOrphan | @@ -1598,7 +1598,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - }, + } Ok(data) => data.into_iter().filter(|b| heights.contains(&b.header().height)), }; @@ -1688,7 +1688,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - }, + } Ok(data) => data, }; for block in blocks { @@ -1744,7 +1744,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - }, + } Ok(data) => data, }; for block in blocks { @@ -1804,7 +1804,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(format!("Error communicating with local base node: {}", err)), ))); return; - }, + } Ok(data) => data, }; for output in outputs { @@ -1818,14 +1818,14 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); return; } - }, + } Err(err) => { let _ignore = tx.send(Err(obscure_error_if_true( report_error_flag, Status::internal(format!("Error communicating with local base node: {}", err)), ))); return; - }, + } } } }); @@ -1925,7 +1925,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { BlockGroupType::BlockSize, report_error_flag, ) - .await + .await } async fn get_block_fees( @@ -1940,7 +1940,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { BlockGroupType::BlockFees, report_error_flag, ) - .await + .await } async fn get_version(&self, _request: Request) -> Result, Status> { @@ -2307,7 +2307,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Base node service error: {}", err,); return; - }, + } Ok(data) => data, }; @@ -2372,7 +2372,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { header.map(|h| h.height()).ok_or_else(|| { obscure_error_if_true(report_error_flag, Status::not_found("Start hash not found")) })? - }, + } None => 0, }; @@ -2392,7 +2392,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Base node service error: {}", err); return; - }, + } Ok(data) => data, }; @@ -2482,7 +2482,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { warn!(target: LOG_TARGET, "Base node service error: {}", e); return; - }, + } }; let next_header = match node_service.get_header(height.saturating_add(1)).await { @@ -2493,7 +2493,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(e.to_string()), ))); return; - }, + } }; let sidechain_outputs = utxos @@ -2520,7 +2520,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); return; } - }, + } Err(e) => { warn!( target: LOG_TARGET, @@ -2533,13 +2533,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ))) .await; return; - }, + } }; match next_header { Some(header) => { current_header = header; - }, + } None => break, } } @@ -2550,6 +2550,12 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); Ok(Response::new(rx)) } + + async fn get_validator_node_changes(&self, request: Request) -> Result, Status> { + self.check_method_enabled(GrpcMethod::GetValidatorNodeChanges)?; + // TODO: continue impl + todo!() + } } enum BlockGroupType { @@ -2586,7 +2592,7 @@ async fn get_block_group( "Error communicating with local base node: {:?}", err, ); vec![] - }, + } Ok(data) => data, }; let extractor = match block_group_type { @@ -2602,15 +2608,15 @@ async fn get_block_group( report_error_flag, Status::unimplemented("Quantile has not been implemented"), )) - }, + } CalcType::Quartile => { return Err(obscure_error_if_true( report_error_flag, Status::unimplemented("Quartile has not been implemented"), )) - }, + } } - .unwrap_or_default(); + .unwrap_or_default(); trace!( target: LOG_TARGET, "Sending GetBlockSize response to client: {:?}", value diff --git a/applications/minotari_node/src/grpc_method.rs b/applications/minotari_node/src/grpc_method.rs index afd77b88f2..1549583767 100644 --- a/applications/minotari_node/src/grpc_method.rs +++ b/applications/minotari_node/src/grpc_method.rs @@ -62,6 +62,7 @@ pub enum GrpcMethod { ListConnectedPeers, GetMempoolStats, GetActiveValidatorNodes, + GetValidatorNodeChanges, GetShardKey, GetTemplateRegistrations, GetSideChainUtxos, @@ -69,7 +70,7 @@ pub enum GrpcMethod { impl GrpcMethod { /// All the GRPC methods as a fixed array - pub const ALL_VARIANTS: [GrpcMethod; 36] = [ + pub const ALL_VARIANTS: [GrpcMethod; 37] = [ GrpcMethod::ListHeaders, GrpcMethod::GetHeaderByHash, GrpcMethod::GetBlocks, @@ -103,6 +104,7 @@ impl GrpcMethod { GrpcMethod::ListConnectedPeers, GrpcMethod::GetMempoolStats, GrpcMethod::GetActiveValidatorNodes, + GrpcMethod::GetValidatorNodeChanges, GrpcMethod::GetShardKey, GrpcMethod::GetTemplateRegistrations, GrpcMethod::GetSideChainUtxos, @@ -110,7 +112,7 @@ impl GrpcMethod { } impl IntoIterator for GrpcMethod { - type IntoIter = std::array::IntoIter; + type IntoIter = std::array::IntoIter; type Item = GrpcMethod; fn into_iter(self) -> Self::IntoIter { @@ -158,6 +160,7 @@ impl FromStr for GrpcMethod { "list_connected_peers" => Ok(GrpcMethod::ListConnectedPeers), "get_mempool_stats" => Ok(GrpcMethod::GetMempoolStats), "get_active_validator_nodes" => Ok(GrpcMethod::GetActiveValidatorNodes), + "get_validator_node_changes" => Ok(GrpcMethod::GetValidatorNodeChanges), "get_shard_key" => Ok(GrpcMethod::GetShardKey), "get_template_registrations" => Ok(GrpcMethod::GetTemplateRegistrations), "get_side_chain_utxos" => Ok(GrpcMethod::GetSideChainUtxos), @@ -253,6 +256,7 @@ mod tests { GrpcMethod::ListConnectedPeers => count += 1, GrpcMethod::GetMempoolStats => count += 1, GrpcMethod::GetActiveValidatorNodes => count += 1, + GrpcMethod::GetValidatorNodeChanges => count += 1, GrpcMethod::GetShardKey => count += 1, GrpcMethod::GetTemplateRegistrations => count += 1, GrpcMethod::GetSideChainUtxos => count += 1, From 7f9b85b975efb2b46cc82d8419e0014ecf9b9adb Mon Sep 17 00:00:00 2001 From: ksrichard Date: Mon, 4 Nov 2024 16:07:14 +0100 Subject: [PATCH 04/23] impl in progress --- .../minotari_app_grpc/proto/base_node.proto | 6 +- .../src/grpc/base_node_grpc_server.rs | 33 +++- applications/minotari_node/src/grpc_method.rs | 7 +- .../comms_interface/comms_request.rs | 22 ++- .../comms_interface/comms_response.rs | 26 +++- .../comms_interface/inbound_handlers.rs | 145 ++++++++++-------- .../comms_interface/local_interface.rs | 36 ++++- 7 files changed, 187 insertions(+), 88 deletions(-) diff --git a/applications/minotari_app_grpc/proto/base_node.proto b/applications/minotari_app_grpc/proto/base_node.proto index e92c8227e0..eeec6e1e36 100644 --- a/applications/minotari_app_grpc/proto/base_node.proto +++ b/applications/minotari_app_grpc/proto/base_node.proto @@ -488,8 +488,9 @@ message GetActiveValidatorNodesResponse { } message GetValidatorNodeChangesRequest { - uint64 start_epoch = 1; - uint64 end_epoch = 2; + uint64 start_height = 1; + uint64 end_height = 2; + bytes sidechain_id = 3; } enum ValidatorNodeChangeState { @@ -504,6 +505,7 @@ message ValidatorNodeChange { message GetValidatorNodeChangesResponse { repeated ValidatorNodeChange changes = 1; + bytes sidechain_id = 2; } message GetShardKeyRequest { diff --git a/applications/minotari_node/src/grpc/base_node_grpc_server.rs b/applications/minotari_node/src/grpc/base_node_grpc_server.rs index 34243834e3..902c645d53 100644 --- a/applications/minotari_node/src/grpc/base_node_grpc_server.rs +++ b/applications/minotari_node/src/grpc/base_node_grpc_server.rs @@ -40,11 +40,12 @@ use borsh::{BorshDeserialize, BorshSerialize}; use either::Either; use futures::{channel::mpsc, SinkExt}; use log::*; -use minotari_app_grpc::tari_rpc::{GetValidatorNodeChangesRequest, GetValidatorNodeChangesResponse}; +use minotari_app_grpc::tari_rpc::{GetActiveValidatorNodesMrRequest, GetActiveValidatorNodesMrResponse, GetValidatorNodeChangesRequest, GetValidatorNodeChangesResponse, ValidatorNodeChange}; use minotari_app_grpc::{ tari_rpc, tari_rpc::{CalcType, Sorting}, }; +use tari_common_types::epoch::VnEpoch; use tari_common_types::{ key_branches::TransactionKeyManagerBranch, tari_address::TariAddress, @@ -159,6 +160,7 @@ impl BaseNodeGrpcServer { GrpcMethod::GetMempoolStats, GrpcMethod::GetTipInfo, GrpcMethod::GetActiveValidatorNodes, + GrpcMethod::GetValidatorNodeChanges, GrpcMethod::GetShardKey, GrpcMethod::GetTemplateRegistrations, GrpcMethod::GetHeaderByHash, @@ -2551,10 +2553,33 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Ok(Response::new(rx)) } - async fn get_validator_node_changes(&self, request: Request) -> Result, Status> { + async fn get_validator_node_changes(&self, request: Request) + -> Result, Status> { self.check_method_enabled(GrpcMethod::GetValidatorNodeChanges)?; - // TODO: continue impl - todo!() + let request = request.into_inner(); + trace!(target: LOG_TARGET, "Incoming GRPC request for GetActiveValidatorNodes"); + + let mut handler = self.node_service.clone(); + let (mut tx, rx) = mpsc::channel(1000); + + let sidechain_id = if request.sidechain_id.is_empty() { + None + } else { + Some( + PublicKey::from_canonical_bytes(&request.sidechain_id) + .map_err(|e| Status::invalid_argument(format!("Invalid sidechain_id '{}'", e)))?, + ) + }; + + let validator_node_changes = match handler.get_validator_node_changes(request.start_height, request.end_height, sidechain_id).await { + Err(err) => { + warn!(target: LOG_TARGET, "Base node service error: {}", err,); + return; + } + Ok(data) => data, + }; + + Ok(Response::new(rx)) } } diff --git a/applications/minotari_node/src/grpc_method.rs b/applications/minotari_node/src/grpc_method.rs index 1549583767..0ea257faa4 100644 --- a/applications/minotari_node/src/grpc_method.rs +++ b/applications/minotari_node/src/grpc_method.rs @@ -63,6 +63,7 @@ pub enum GrpcMethod { GetMempoolStats, GetActiveValidatorNodes, GetValidatorNodeChanges, + GetActiveValidatorNodesMr, GetShardKey, GetTemplateRegistrations, GetSideChainUtxos, @@ -70,7 +71,7 @@ pub enum GrpcMethod { impl GrpcMethod { /// All the GRPC methods as a fixed array - pub const ALL_VARIANTS: [GrpcMethod; 37] = [ + pub const ALL_VARIANTS: [GrpcMethod; 38] = [ GrpcMethod::ListHeaders, GrpcMethod::GetHeaderByHash, GrpcMethod::GetBlocks, @@ -104,6 +105,7 @@ impl GrpcMethod { GrpcMethod::ListConnectedPeers, GrpcMethod::GetMempoolStats, GrpcMethod::GetActiveValidatorNodes, + GrpcMethod::GetActiveValidatorNodesMr, GrpcMethod::GetValidatorNodeChanges, GrpcMethod::GetShardKey, GrpcMethod::GetTemplateRegistrations, @@ -112,7 +114,7 @@ impl GrpcMethod { } impl IntoIterator for GrpcMethod { - type IntoIter = std::array::IntoIter; + type IntoIter = std::array::IntoIter; type Item = GrpcMethod; fn into_iter(self) -> Self::IntoIter { @@ -160,6 +162,7 @@ impl FromStr for GrpcMethod { "list_connected_peers" => Ok(GrpcMethod::ListConnectedPeers), "get_mempool_stats" => Ok(GrpcMethod::GetMempoolStats), "get_active_validator_nodes" => Ok(GrpcMethod::GetActiveValidatorNodes), + "get_active_validator_nodes_mr" => Ok(GrpcMethod::GetActiveValidatorNodesMr), "get_validator_node_changes" => Ok(GrpcMethod::GetValidatorNodeChanges), "get_shard_key" => Ok(GrpcMethod::GetShardKey), "get_template_registrations" => Ok(GrpcMethod::GetTemplateRegistrations), diff --git a/base_layer/core/src/base_node/comms_interface/comms_request.rs b/base_layer/core/src/base_node/comms_interface/comms_request.rs index 7631622bc8..cc69b17ea4 100644 --- a/base_layer/core/src/base_node/comms_interface/comms_request.rs +++ b/base_layer/core/src/base_node/comms_interface/comms_request.rs @@ -65,6 +65,11 @@ pub enum NodeCommsRequest { height: u64, validator_network: Option, }, + FetchValidatorNodeChanges { + start_height: u64, + end_height: u64, + sidechain_id: Option, + }, GetShardKey { height: u64, public_key: PublicKey, @@ -92,12 +97,12 @@ impl Display for NodeCommsRequest { GetChainMetadata => write!(f, "GetChainMetadata"), FetchHeaders(range) => { write!(f, "FetchHeaders ({:?})", range) - }, + } FetchHeadersByHashes(v) => write!(f, "FetchHeadersByHashes (n={})", v.len()), FetchMatchingUtxos(v) => write!(f, "FetchMatchingUtxos (n={})", v.len()), FetchMatchingBlocks { range, compact } => { write!(f, "FetchMatchingBlocks ({:?}, {})", range, compact) - }, + } FetchBlocksByKernelExcessSigs(v) => write!(f, "FetchBlocksByKernelExcessSigs (n={})", v.len()), FetchBlocksByUtxos(v) => write!(f, "FetchBlocksByUtxos (n={})", v.len()), GetHeaderByHash(v) => write!(f, "GetHeaderByHash({})", v), @@ -113,7 +118,7 @@ impl Display for NodeCommsRequest { ), FetchMempoolTransactionsByExcessSigs { .. } => { write!(f, "FetchMempoolTransactionsByExcessSigs") - }, + } FetchValidatorNodesKeys { height, validator_network, @@ -127,19 +132,22 @@ impl Display for NodeCommsRequest { .map(|n| n.to_hex()) .unwrap_or_else(|| "None".to_string()) ) - }, + } GetShardKey { height, public_key } => { write!(f, "GetShardKey height ({}), public key ({:?})", height, public_key) - }, + } FetchTemplateRegistrations { start_height: start, end_height: end, } => { write!(f, "FetchTemplateRegistrations ({}..={})", start, end) - }, + } FetchUnspentUtxosInBlock { block_hash } => { write!(f, "FetchUnspentUtxosInBlock ({})", block_hash) - }, + } + FetchValidatorNodeChanges { start_height, end_height, sidechain_id } => { + write!(f, "FetchValidatorNodeChanges (Side chain ID:{:?}), Height range: {}-{}", sidechain_id, start_height, end_height) + } } } } diff --git a/base_layer/core/src/base_node/comms_interface/comms_response.rs b/base_layer/core/src/base_node/comms_interface/comms_response.rs index 2195ddef36..9a324740d8 100644 --- a/base_layer/core/src/base_node/comms_interface/comms_response.rs +++ b/base_layer/core/src/base_node/comms_interface/comms_response.rs @@ -25,17 +25,17 @@ use std::{ sync::Arc, }; -use tari_common_types::{ - chain_metadata::ChainMetadata, - types::{HashOutput, PrivateKey}, -}; - use crate::{ blocks::{Block, ChainHeader, HistoricalBlock, NewBlockTemplate}, chain_storage::{TemplateRegistrationEntry, ValidatorNodeRegistrationInfo}, proof_of_work::Difficulty, transactions::transaction_components::{Transaction, TransactionKernel, TransactionOutput}, }; +use tari_common_types::types::PublicKey; +use tari_common_types::{ + chain_metadata::ChainMetadata, + types::{HashOutput, PrivateKey}, +}; /// API Response enum #[allow(clippy::large_enum_variant)] @@ -59,6 +59,7 @@ pub enum NodeCommsResponse { MmrNodes(Vec, Vec), FetchMempoolTransactionsByExcessSigsResponse(FetchMempoolTransactionsResponse), FetchValidatorNodesKeysResponse(Vec), + FetchValidatorNodeChangesResponse(Vec), GetShardKeyResponse(Option<[u8; 32]>), FetchTemplateRegistrationsResponse(Vec), } @@ -98,6 +99,7 @@ impl Display for NodeCommsResponse { FetchValidatorNodesKeysResponse(_) => write!(f, "FetchValidatorNodesKeysResponse"), GetShardKeyResponse(_) => write!(f, "GetShardKeyResponse"), FetchTemplateRegistrationsResponse(_) => write!(f, "FetchTemplateRegistrationsResponse"), + FetchValidatorNodeChangesResponse(_) => write!(f, "FetchValidatorNodeChangesResponse"), } } } @@ -108,3 +110,17 @@ pub struct FetchMempoolTransactionsResponse { pub transactions: Vec>, pub not_found: Vec, } + +/// Represents a validator node state +#[derive(Debug, Clone)] +pub enum ValidatorNodeChangeState { + ADD, + REMOVE, +} + +/// Represents a validator node state change +#[derive(Debug, Clone)] +pub struct ValidatorNodeChange { + pub public_key: PublicKey, + pub state: ValidatorNodeChangeState, +} diff --git a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs index 64677a3cc5..959479e3f1 100644 --- a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs +++ b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs @@ -20,43 +20,35 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +use log::*; +use std::collections::HashMap; #[cfg(feature = "metrics")] use std::convert::{TryFrom, TryInto}; use std::{cmp::max, collections::HashSet, sync::Arc, time::Instant}; - -use log::*; use strum_macros::Display; -use tari_common_types::types::{BlockHash, FixedHash, HashOutput}; +use tari_common_types::types::{BlockHash, FixedHash, HashOutput, PublicKey}; use tari_comms::{connectivity::ConnectivityRequester, peer_manager::NodeId}; use tari_utilities::hex::Hex; use tokio::sync::RwLock; +use crate::base_node::comms_interface::comms_response::ValidatorNodeChangeState; #[cfg(feature = "metrics")] use crate::base_node::metrics; -use crate::{ - base_node::comms_interface::{ - error::CommsInterfaceError, - local_interface::BlockEventSender, - FetchMempoolTransactionsResponse, - NodeCommsRequest, - NodeCommsResponse, - OutboundNodeCommsInterface, - }, - blocks::{Block, BlockBuilder, BlockHeader, BlockHeaderValidationError, ChainBlock, NewBlock, NewBlockTemplate}, - chain_storage::{async_db::AsyncBlockchainDb, BlockAddResult, BlockchainBackend, ChainStorageError}, - consensus::{ConsensusConstants, ConsensusManager}, - mempool::Mempool, - proof_of_work::{ - randomx_difficulty, - randomx_factory::RandomXFactory, - sha3x_difficulty, - Difficulty, - PowAlgorithm, - PowError, - }, - transactions::aggregated_body::AggregateBody, - validation::{helpers, ValidationError}, -}; +use crate::{base_node::comms_interface::{ + error::CommsInterfaceError, + local_interface::BlockEventSender, + FetchMempoolTransactionsResponse, + NodeCommsRequest, + NodeCommsResponse, + OutboundNodeCommsInterface, +}, blocks::{Block, BlockBuilder, BlockHeader, BlockHeaderValidationError, ChainBlock, NewBlock, NewBlockTemplate}, chain_storage, chain_storage::{async_db::AsyncBlockchainDb, BlockAddResult, BlockchainBackend, ChainStorageError}, consensus::{ConsensusConstants, ConsensusManager}, mempool::Mempool, proof_of_work::{ + randomx_difficulty, + randomx_factory::RandomXFactory, + sha3x_difficulty, + Difficulty, + PowAlgorithm, + PowError, +}, transactions::aggregated_body::AggregateBody, validation::{helpers, ValidationError}}; const LOG_TARGET: &str = "c::bn::comms_interface::inbound_handler"; const MAX_REQUEST_BY_BLOCK_HASHES: usize = 100; @@ -92,7 +84,8 @@ pub struct InboundNodeCommsHandlers { } impl InboundNodeCommsHandlers -where B: BlockchainBackend + 'static +where + B: BlockchainBackend + 'static, { /// Construct a new InboundNodeCommsInterface. pub fn new( @@ -127,7 +120,7 @@ where B: BlockchainBackend + 'static NodeCommsRequest::FetchHeaders(range) => { let headers = self.blockchain_db.fetch_chain_headers(range).await?; Ok(NodeCommsResponse::BlockHeaders(headers)) - }, + } NodeCommsRequest::FetchHeadersByHashes(block_hashes) => { if block_hashes.len() > MAX_REQUEST_BY_BLOCK_HASHES { return Err(CommsInterfaceError::InvalidRequest { @@ -145,18 +138,18 @@ where B: BlockchainBackend + 'static match self.blockchain_db.fetch_chain_header_by_block_hash(block_hash).await? { Some(block_header) => { block_headers.push(block_header); - }, + } None => { error!(target: LOG_TARGET, "Could not fetch headers with hashes:{}", block_hex); return Err(CommsInterfaceError::InternalError(format!( "Could not fetch headers with hashes:{}", block_hex ))); - }, + } } } Ok(NodeCommsResponse::BlockHeaders(block_headers)) - }, + } NodeCommsRequest::FetchMatchingUtxos(utxo_hashes) => { let mut res = Vec::with_capacity(utxo_hashes.len()); for (output, spent) in (self @@ -171,11 +164,11 @@ where B: BlockchainBackend + 'static } } Ok(NodeCommsResponse::TransactionOutputs(res)) - }, + } NodeCommsRequest::FetchMatchingBlocks { range, compact } => { let blocks = self.blockchain_db.fetch_blocks(range, compact).await?; Ok(NodeCommsResponse::HistoricalBlocks(blocks)) - }, + } NodeCommsRequest::FetchBlocksByKernelExcessSigs(excess_sigs) => { if excess_sigs.len() > MAX_REQUEST_BY_KERNEL_EXCESS_SIGS { return Err(CommsInterfaceError::InvalidRequest { @@ -211,7 +204,7 @@ where B: BlockchainBackend + 'static } } Ok(NodeCommsResponse::HistoricalBlocks(blocks)) - }, + } NodeCommsRequest::FetchBlocksByUtxos(commitments) => { if commitments.len() > MAX_REQUEST_BY_UTXO_HASHES { return Err(CommsInterfaceError::InvalidRequest { @@ -246,15 +239,15 @@ where B: BlockchainBackend + 'static } } Ok(NodeCommsResponse::HistoricalBlocks(blocks)) - }, + } NodeCommsRequest::GetHeaderByHash(hash) => { let header = self.blockchain_db.fetch_chain_header_by_block_hash(hash).await?; Ok(NodeCommsResponse::BlockHeader(header)) - }, + } NodeCommsRequest::GetBlockByHash(hash) => { let block = self.blockchain_db.fetch_block_by_hash(hash, false).await?; Ok(NodeCommsResponse::HistoricalBlock(Box::new(block))) - }, + } NodeCommsRequest::GetNewBlockTemplate(request) => { let best_block_header = self.blockchain_db.fetch_tip_header().await?; let last_seen_hash = self.mempool.get_last_seen_hash().await?; @@ -328,7 +321,7 @@ where B: BlockchainBackend + 'static ); Ok(NodeCommsResponse::NewBlockTemplate(block_template)) - }, + } NodeCommsRequest::GetNewBlock(block_template) => { let height = block_template.header.height; let target_difficulty = block_template.target_difficulty; @@ -350,7 +343,7 @@ where B: BlockchainBackend + 'static error: None, block: Some(block), }) - }, + } NodeCommsRequest::GetBlockFromAllChains(hash) => { let block_hex = hash.to_hex(); debug!( @@ -388,7 +381,7 @@ where B: BlockchainBackend + 'static }; Ok(NodeCommsResponse::Block(Box::new(maybe_block))) - }, + } NodeCommsRequest::FetchKernelByExcessSig(signature) => { let kernels = match self.blockchain_db.fetch_kernel_by_excess_sig(signature).await { Ok(Some((kernel, _))) => vec![kernel], @@ -396,11 +389,11 @@ where B: BlockchainBackend + 'static Err(err) => { error!(target: LOG_TARGET, "Could not fetch kernel {}", err.to_string()); return Err(err.into()); - }, + } }; Ok(NodeCommsResponse::TransactionKernels(kernels)) - }, + } NodeCommsRequest::FetchMempoolTransactionsByExcessSigs { excess_sigs } => { let (transactions, not_found) = self.mempool.retrieve_by_excess_sigs(excess_sigs).await?; Ok(NodeCommsResponse::FetchMempoolTransactionsByExcessSigsResponse( @@ -409,7 +402,7 @@ where B: BlockchainBackend + 'static not_found, }, )) - }, + } NodeCommsRequest::FetchValidatorNodesKeys { height, validator_network, @@ -421,11 +414,11 @@ where B: BlockchainBackend + 'static Ok(NodeCommsResponse::FetchValidatorNodesKeysResponse( active_validator_nodes, )) - }, + } NodeCommsRequest::GetShardKey { height, public_key } => { let shard_key = self.blockchain_db.get_shard_key(height, public_key).await?; Ok(NodeCommsResponse::GetShardKeyResponse(shard_key)) - }, + } NodeCommsRequest::FetchTemplateRegistrations { start_height, end_height, @@ -437,11 +430,43 @@ where B: BlockchainBackend + 'static Ok(NodeCommsResponse::FetchTemplateRegistrationsResponse( template_registrations, )) - }, + } NodeCommsRequest::FetchUnspentUtxosInBlock { block_hash } => { let utxos = self.blockchain_db.fetch_outputs_in_block(block_hash).await?; Ok(NodeCommsResponse::TransactionOutputs(utxos)) - }, + } + NodeCommsRequest::FetchValidatorNodeChanges { start_height, end_height, sidechain_id } => { + let mut result = vec![]; + let mut node_changes = HashMap::::new(); + let mut nodes = self + .blockchain_db + .fetch_active_validator_nodes(start_height, sidechain_id.clone()) + .await?; + // add initial validator node set + nodes.iter().for_each(|node| { + node_changes.insert(node.public_key.clone(), ValidatorNodeChangeState::ADD); + }); + for height in start_height + 1..=end_height { + let current_nodes = self + .blockchain_db + .fetch_active_validator_nodes(height, sidechain_id.clone()) + .await?; + + current_nodes.iter().for_each(|curr_node| { + // new vn added + if !node_changes.contains_key(&curr_node.public_key) { + node_changes.insert(curr_node.public_key.clone(), ValidatorNodeChangeState::ADD); + } + // TODO: handle case when we do not find a node in the current set from old set + }); + + nodes = current_nodes; + } + + // TODO: convert node_changes into result + + Ok(NodeCommsResponse::FetchValidatorNodeChangesResponse(vec![])) + } } } @@ -729,7 +754,7 @@ where B: BlockchainBackend + 'static Err(_) => { let block = self.request_full_block_from_peer(source_peer, block_hash).await?; return Ok(block); - }, + } Ok(v) => v, }; if let Err(e) = helpers::check_mmr_roots(&header, &mmr_roots) { @@ -770,14 +795,14 @@ where B: BlockchainBackend + 'static "Invalid response from peer `{}`: Peer failed to provide the block that was propagated", source_peer ))) - }, + } Err(CommsInterfaceError::UnexpectedApiResponse) => { debug!( target: LOG_TARGET, "Peer `{}` sent unexpected API response.", source_peer ); Err(CommsInterfaceError::UnexpectedApiResponse) - }, + } Err(e) => Err(e), } } @@ -852,7 +877,7 @@ where B: BlockchainBackend + 'static } } Ok(block_hash) - }, + } Err(e @ ChainStorageError::ValidationError { .. }) => { #[cfg(feature = "metrics")] @@ -871,7 +896,7 @@ where B: BlockchainBackend + 'static ); self.publish_block_event(BlockEvent::AddBlockValidationFailed { block, source_peer }); Err(e.into()) - }, + } Err(e) => { #[cfg(feature = "metrics")] @@ -879,7 +904,7 @@ where B: BlockchainBackend + 'static self.publish_block_event(BlockEvent::AddBlockErrored { block }); Err(e.into()) - }, + } } } @@ -954,11 +979,11 @@ where B: BlockchainBackend + 'static PowAlgorithm::Sha3x => { metrics::target_difficulty_sha() .set(i64::try_from(block.accumulated_data().target_difficulty.as_u64()).unwrap_or(i64::MAX)); - }, + } PowAlgorithm::RandomX => { metrics::target_difficulty_randomx() .set(i64::try_from(block.accumulated_data().target_difficulty.as_u64()).unwrap_or(i64::MAX)); - }, + } } } @@ -969,7 +994,7 @@ where B: BlockchainBackend + 'static metrics::tip_height().set(block.height() as i64); let utxo_set_size = self.blockchain_db.utxo_count().await?; metrics::utxo_set_size().set(utxo_set_size.try_into().unwrap_or(i64::MAX)); - }, + } BlockAddResult::ChainReorg { added, removed } => { if let Some(fork_height) = added.last().map(|b| b.height()) { #[allow(clippy::cast_possible_wrap)] @@ -982,11 +1007,11 @@ where B: BlockchainBackend + 'static for block in added { update_target_difficulty(block); } - }, + } BlockAddResult::OrphanBlock => { metrics::orphaned_blocks().inc(); - }, - _ => {}, + } + _ => {} } Ok(()) } diff --git a/base_layer/core/src/base_node/comms_interface/local_interface.rs b/base_layer/core/src/base_node/comms_interface/local_interface.rs index d0e36383a4..c684bc1b38 100644 --- a/base_layer/core/src/base_node/comms_interface/local_interface.rs +++ b/base_layer/core/src/base_node/comms_interface/local_interface.rs @@ -22,13 +22,7 @@ use std::{ops::RangeInclusive, sync::Arc}; -use tari_common_types::{ - chain_metadata::ChainMetadata, - types::{BlockHash, Commitment, HashOutput, PublicKey, Signature}, -}; -use tari_service_framework::{reply_channel::SenderService, Service}; -use tokio::sync::broadcast; - +use crate::base_node::comms_interface::comms_response::ValidatorNodeChange; use crate::{ base_node::comms_interface::{ comms_request::GetNewBlockTemplateRequest, @@ -42,6 +36,12 @@ use crate::{ proof_of_work::PowAlgorithm, transactions::transaction_components::{TransactionKernel, TransactionOutput}, }; +use tari_common_types::{ + chain_metadata::ChainMetadata, + types::{BlockHash, Commitment, HashOutput, PublicKey, Signature}, +}; +use tari_service_framework::{reply_channel::SenderService, Service}; +use tokio::sync::broadcast; pub type BlockEventSender = broadcast::Sender>; pub type BlockEventReceiver = broadcast::Receiver>; @@ -180,7 +180,7 @@ impl LocalNodeCommsInterface { error.unwrap_or_else(|| "Unspecified error".to_string()), )) } - }, + } _ => Err(CommsInterfaceError::UnexpectedApiResponse), } } @@ -299,6 +299,26 @@ impl LocalNodeCommsInterface { } } + pub async fn get_validator_node_changes( + &mut self, + start_height: u64, + end_height: u64, + sidechain_id: Option, + ) -> Result, CommsInterfaceError> { + match self + .request_sender + .call(NodeCommsRequest::FetchValidatorNodeChanges { + start_height, + end_height, + sidechain_id, + }) + .await?? + { + NodeCommsResponse::FetchValidatorNodeChangesResponse(validator_node_change) => Ok(validator_node_change), + _ => Err(CommsInterfaceError::UnexpectedApiResponse), + } + } + pub async fn get_shard_key( &mut self, height: u64, From 515433dd32beb7f488ebd335fac063d4f9b48e2e Mon Sep 17 00:00:00 2001 From: ksrichard Date: Tue, 5 Nov 2024 11:52:06 +0100 Subject: [PATCH 05/23] impl almost done --- .../minotari_app_grpc/proto/base_node.proto | 1 - .../src/grpc/base_node_grpc_server.rs | 182 ++++++++++-------- .../comms_interface/comms_request.rs | 28 ++- .../comms_interface/comms_response.rs | 10 +- .../comms_interface/inbound_handlers.rs | 153 +++++++++------ .../comms_interface/local_interface.rs | 17 +- .../core/src/base_node/comms_interface/mod.rs | 7 +- .../core/src/chain_storage/lmdb_db/lmdb_db.rs | 125 ++++++------ .../lmdb_db/validator_node_store.rs | 31 +-- 9 files changed, 307 insertions(+), 247 deletions(-) diff --git a/applications/minotari_app_grpc/proto/base_node.proto b/applications/minotari_app_grpc/proto/base_node.proto index eeec6e1e36..fb91566f0f 100644 --- a/applications/minotari_app_grpc/proto/base_node.proto +++ b/applications/minotari_app_grpc/proto/base_node.proto @@ -505,7 +505,6 @@ message ValidatorNodeChange { message GetValidatorNodeChangesResponse { repeated ValidatorNodeChange changes = 1; - bytes sidechain_id = 2; } message GetShardKeyRequest { diff --git a/applications/minotari_node/src/grpc/base_node_grpc_server.rs b/applications/minotari_node/src/grpc/base_node_grpc_server.rs index 902c645d53..f7ad86a914 100644 --- a/applications/minotari_node/src/grpc/base_node_grpc_server.rs +++ b/applications/minotari_node/src/grpc/base_node_grpc_server.rs @@ -26,26 +26,20 @@ use std::{ str::FromStr, }; -use crate::{ - builder::BaseNodeContext, - grpc::{ - blocks::{block_fees, block_heights, block_size, GET_BLOCKS_MAX_HEIGHTS, GET_BLOCKS_PAGE_SIZE}, - hash_rate::HashRateMovingAverage, - helpers::{mean, median}, - }, - grpc_method::GrpcMethod, - BaseNodeConfig, -}; use borsh::{BorshDeserialize, BorshSerialize}; use either::Either; use futures::{channel::mpsc, SinkExt}; use log::*; -use minotari_app_grpc::tari_rpc::{GetActiveValidatorNodesMrRequest, GetActiveValidatorNodesMrResponse, GetValidatorNodeChangesRequest, GetValidatorNodeChangesResponse, ValidatorNodeChange}; use minotari_app_grpc::{ tari_rpc, - tari_rpc::{CalcType, Sorting}, + tari_rpc::{ + CalcType, + GetValidatorNodeChangesRequest, + GetValidatorNodeChangesResponse, + Sorting, + ValidatorNodeChange, + }, }; -use tari_common_types::epoch::VnEpoch; use tari_common_types::{ key_branches::TransactionKeyManagerBranch, tari_address::TariAddress, @@ -54,6 +48,7 @@ use tari_common_types::{ use tari_comms::{Bytes, CommsNode}; use tari_core::{ base_node::{ + comms_interface, comms_interface::CommsInterfaceError, state_machine_service::states::StateInfo, LocalNodeCommsInterface, @@ -85,6 +80,17 @@ use tari_utilities::{hex::Hex, message_format::MessageFormat, ByteArray}; use tokio::task; use tonic::{Request, Response, Status}; +use crate::{ + builder::BaseNodeContext, + grpc::{ + blocks::{block_fees, block_heights, block_size, GET_BLOCKS_MAX_HEIGHTS, GET_BLOCKS_PAGE_SIZE}, + hash_rate::HashRateMovingAverage, + helpers::{mean, median}, + }, + grpc_method::GrpcMethod, + BaseNodeConfig, +}; + const LOG_TARGET: &str = "minotari::base_node::grpc"; const GET_TOKENS_IN_CIRCULATION_MAX_HEIGHTS: usize = 1_000_000; const GET_TOKENS_IN_CIRCULATION_PAGE_SIZE: usize = 1_000; @@ -287,7 +293,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ))) .await; return; - } + }, }; if headers.is_empty() { @@ -324,7 +330,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(format!("Error fetching block at height {}", current_height)), ))); return; - } + }, }; if block.is_none() { let _network_difficulty_response = tx.send(Err(obscure_error_if_true( @@ -380,7 +386,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Error communicating with base node: {}", err,); return; - } + }, Ok(data) => data, }; for transaction in transactions.unconfirmed_pool { @@ -402,7 +408,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); } return; - } + }, }; if tx @@ -447,7 +453,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::internal(err.to_string()), )); - } + }, Ok(data) => data.best_block_height(), }; @@ -470,7 +476,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { (res, false) => res + 1, }; (from..=tip, true) - } + }, Sorting::Asc => (0..=num_headers.saturating_sub(1), false), } } else { @@ -481,11 +487,11 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { (res, false) => res + 1, }; (from..=from_height, true) - } + }, Sorting::Asc => { let to = from_height.saturating_add(num_headers).saturating_sub(1); (from_height..=to, false) - } + }, } }; let consensus_rules = self.consensus_rules.clone(); @@ -494,7 +500,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { header_range.end().saturating_add(1), LIST_HEADERS_PAGE_SIZE, ) - .map_err(|e| obscure_error_if_true(report_error_flag, Status::invalid_argument(e)))?; + .map_err(|e| obscure_error_if_true(report_error_flag, Status::invalid_argument(e)))?; task::spawn(async move { trace!( target: LOG_TARGET, @@ -513,7 +519,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Internal base node service error: {}", err); return; - } + }, Ok(data) => { if is_reversed { data.into_iter() @@ -532,7 +538,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { Err(obscure_error_if_true(report_error_flag, Status::internal(e)) .to_string()) - } + }, } }) .rev() @@ -554,18 +560,18 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { Err(obscure_error_if_true(report_error_flag, Status::internal(e)) .to_string()) - } + }, } }) .collect::, String>>() } - } + }, }; match result_data { Err(e) => { error!(target: LOG_TARGET, "No result headers transmitted due to error: {}", e) - } + }, Ok(result_data) => { let result_size = result_data.len(); trace!(target: LOG_TARGET, "Result headers: {}", result_size); @@ -586,7 +592,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { return; } } - } + }, } } }); @@ -682,7 +688,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - } + }, Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -690,13 +696,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - } + }, Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - } + }, }; let fees = new_block.body.get_total_fee().map_err(|_| { obscure_error_if_true( @@ -851,12 +857,12 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { })? - prev_coinbase_value, ) - .map_err(|_| { - obscure_error_if_true( - report_error_flag, - Status::internal("Single coinbase fees exceeded u64".to_string()), - ) - })?; + .map_err(|_| { + obscure_error_if_true( + report_error_flag, + Status::internal("Single coinbase fees exceeded u64".to_string()), + ) + })?; prev_coinbase_value += u128::from(coinbase.value); } @@ -897,8 +903,8 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { range_proof_type, PaymentId::Empty, ) - .await - .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; + .await + .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; new_template.body.add_output(coinbase_output); let new_nonce = key_manager .get_next_key(TransactionKeyManagerBranch::KernelNonce.get_branch_key()) @@ -952,7 +958,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - } + }, Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -960,13 +966,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - } + }, Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - } + }, }; let gen_hash = handler .get_header(0) @@ -1095,8 +1101,8 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { range_proof_type, PaymentId::Empty, ) - .await - .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; + .await + .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; block_template.body.add_output(coinbase_output); let new_nonce = key_manager .get_next_key(TransactionKeyManagerBranch::KernelNonce.get_branch_key()) @@ -1150,7 +1156,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - } + }, Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -1158,13 +1164,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - } + }, Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - } + }, }; let fees = new_block.body.get_total_fee().map_err(|_| { obscure_error_if_true( @@ -1255,7 +1261,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - } + }, Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -1263,13 +1269,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - } + }, Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - } + }, }; // construct response let block_hash = new_block.hash().to_vec(); @@ -1510,7 +1516,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { * should not think its mined, but the * node does not think it is. */ } - } + }, TxStorageResponse::NotStored | TxStorageResponse::NotStoredConsensus | TxStorageResponse::NotStoredOrphan | @@ -1600,7 +1606,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - } + }, Ok(data) => data.into_iter().filter(|b| heights.contains(&b.header().height)), }; @@ -1690,7 +1696,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - } + }, Ok(data) => data, }; for block in blocks { @@ -1746,7 +1752,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - } + }, Ok(data) => data, }; for block in blocks { @@ -1806,7 +1812,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(format!("Error communicating with local base node: {}", err)), ))); return; - } + }, Ok(data) => data, }; for output in outputs { @@ -1820,14 +1826,14 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); return; } - } + }, Err(err) => { let _ignore = tx.send(Err(obscure_error_if_true( report_error_flag, Status::internal(format!("Error communicating with local base node: {}", err)), ))); return; - } + }, } } }); @@ -1927,7 +1933,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { BlockGroupType::BlockSize, report_error_flag, ) - .await + .await } async fn get_block_fees( @@ -1942,7 +1948,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { BlockGroupType::BlockFees, report_error_flag, ) - .await + .await } async fn get_version(&self, _request: Request) -> Result, Status> { @@ -2309,7 +2315,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Base node service error: {}", err,); return; - } + }, Ok(data) => data, }; @@ -2374,7 +2380,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { header.map(|h| h.height()).ok_or_else(|| { obscure_error_if_true(report_error_flag, Status::not_found("Start hash not found")) })? - } + }, None => 0, }; @@ -2394,7 +2400,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Base node service error: {}", err); return; - } + }, Ok(data) => data, }; @@ -2484,7 +2490,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { warn!(target: LOG_TARGET, "Base node service error: {}", e); return; - } + }, }; let next_header = match node_service.get_header(height.saturating_add(1)).await { @@ -2495,7 +2501,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(e.to_string()), ))); return; - } + }, }; let sidechain_outputs = utxos @@ -2522,7 +2528,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); return; } - } + }, Err(e) => { warn!( target: LOG_TARGET, @@ -2535,13 +2541,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ))) .await; return; - } + }, }; match next_header { Some(header) => { current_header = header; - } + }, None => break, } } @@ -2553,14 +2559,15 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Ok(Response::new(rx)) } - async fn get_validator_node_changes(&self, request: Request) - -> Result, Status> { + async fn get_validator_node_changes( + &self, + request: Request, + ) -> Result, Status> { self.check_method_enabled(GrpcMethod::GetValidatorNodeChanges)?; let request = request.into_inner(); trace!(target: LOG_TARGET, "Incoming GRPC request for GetActiveValidatorNodes"); let mut handler = self.node_service.clone(); - let (mut tx, rx) = mpsc::channel(1000); let sidechain_id = if request.sidechain_id.is_empty() { None @@ -2571,15 +2578,26 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ) }; - let validator_node_changes = match handler.get_validator_node_changes(request.start_height, request.end_height, sidechain_id).await { - Err(err) => { - warn!(target: LOG_TARGET, "Base node service error: {}", err,); - return; - } - Ok(data) => data, - }; + let changes = handler + .get_validator_node_changes(request.start_height, request.end_height, sidechain_id) + .await + .map_err(|error| { + warn!(target: LOG_TARGET, "Base node service error: {}", error); + Status::internal("Internal error!") + })? + .iter() + .map(|node_change| ValidatorNodeChange { + public_key: node_change.public_key.to_vec(), + state: match node_change.state { + comms_interface::ValidatorNodeChangeState::ADD => tari_rpc::ValidatorNodeChangeState::Add.into(), + comms_interface::ValidatorNodeChangeState::REMOVE => { + tari_rpc::ValidatorNodeChangeState::Remove.into() + }, + }, + }) + .collect(); - Ok(Response::new(rx)) + Ok(Response::new(GetValidatorNodeChangesResponse { changes })) } } @@ -2617,7 +2635,7 @@ async fn get_block_group( "Error communicating with local base node: {:?}", err, ); vec![] - } + }, Ok(data) => data, }; let extractor = match block_group_type { @@ -2633,15 +2651,15 @@ async fn get_block_group( report_error_flag, Status::unimplemented("Quantile has not been implemented"), )) - } + }, CalcType::Quartile => { return Err(obscure_error_if_true( report_error_flag, Status::unimplemented("Quartile has not been implemented"), )) - } + }, } - .unwrap_or_default(); + .unwrap_or_default(); trace!( target: LOG_TARGET, "Sending GetBlockSize response to client: {:?}", value diff --git a/base_layer/core/src/base_node/comms_interface/comms_request.rs b/base_layer/core/src/base_node/comms_interface/comms_request.rs index cc69b17ea4..b7250fc472 100644 --- a/base_layer/core/src/base_node/comms_interface/comms_request.rs +++ b/base_layer/core/src/base_node/comms_interface/comms_request.rs @@ -97,12 +97,12 @@ impl Display for NodeCommsRequest { GetChainMetadata => write!(f, "GetChainMetadata"), FetchHeaders(range) => { write!(f, "FetchHeaders ({:?})", range) - } + }, FetchHeadersByHashes(v) => write!(f, "FetchHeadersByHashes (n={})", v.len()), FetchMatchingUtxos(v) => write!(f, "FetchMatchingUtxos (n={})", v.len()), FetchMatchingBlocks { range, compact } => { write!(f, "FetchMatchingBlocks ({:?}, {})", range, compact) - } + }, FetchBlocksByKernelExcessSigs(v) => write!(f, "FetchBlocksByKernelExcessSigs (n={})", v.len()), FetchBlocksByUtxos(v) => write!(f, "FetchBlocksByUtxos (n={})", v.len()), GetHeaderByHash(v) => write!(f, "GetHeaderByHash({})", v), @@ -118,7 +118,7 @@ impl Display for NodeCommsRequest { ), FetchMempoolTransactionsByExcessSigs { .. } => { write!(f, "FetchMempoolTransactionsByExcessSigs") - } + }, FetchValidatorNodesKeys { height, validator_network, @@ -132,22 +132,30 @@ impl Display for NodeCommsRequest { .map(|n| n.to_hex()) .unwrap_or_else(|| "None".to_string()) ) - } + }, GetShardKey { height, public_key } => { write!(f, "GetShardKey height ({}), public key ({:?})", height, public_key) - } + }, FetchTemplateRegistrations { start_height: start, end_height: end, } => { write!(f, "FetchTemplateRegistrations ({}..={})", start, end) - } + }, FetchUnspentUtxosInBlock { block_hash } => { write!(f, "FetchUnspentUtxosInBlock ({})", block_hash) - } - FetchValidatorNodeChanges { start_height, end_height, sidechain_id } => { - write!(f, "FetchValidatorNodeChanges (Side chain ID:{:?}), Height range: {}-{}", sidechain_id, start_height, end_height) - } + }, + FetchValidatorNodeChanges { + start_height, + end_height, + sidechain_id, + } => { + write!( + f, + "FetchValidatorNodeChanges (Side chain ID:{:?}), Height range: {}-{}", + sidechain_id, start_height, end_height + ) + }, } } } diff --git a/base_layer/core/src/base_node/comms_interface/comms_response.rs b/base_layer/core/src/base_node/comms_interface/comms_response.rs index 9a324740d8..8e844a5451 100644 --- a/base_layer/core/src/base_node/comms_interface/comms_response.rs +++ b/base_layer/core/src/base_node/comms_interface/comms_response.rs @@ -25,17 +25,17 @@ use std::{ sync::Arc, }; +use tari_common_types::{ + chain_metadata::ChainMetadata, + types::{HashOutput, PrivateKey, PublicKey}, +}; + use crate::{ blocks::{Block, ChainHeader, HistoricalBlock, NewBlockTemplate}, chain_storage::{TemplateRegistrationEntry, ValidatorNodeRegistrationInfo}, proof_of_work::Difficulty, transactions::transaction_components::{Transaction, TransactionKernel, TransactionOutput}, }; -use tari_common_types::types::PublicKey; -use tari_common_types::{ - chain_metadata::ChainMetadata, - types::{HashOutput, PrivateKey}, -}; /// API Response enum #[allow(clippy::large_enum_variant)] diff --git a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs index 959479e3f1..3f89625570 100644 --- a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs +++ b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs @@ -20,35 +20,49 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use log::*; -use std::collections::HashMap; #[cfg(feature = "metrics")] use std::convert::{TryFrom, TryInto}; -use std::{cmp::max, collections::HashSet, sync::Arc, time::Instant}; +use std::{ + cmp::max, + collections::{HashMap, HashSet}, + sync::Arc, + time::Instant, +}; + +use log::*; use strum_macros::Display; use tari_common_types::types::{BlockHash, FixedHash, HashOutput, PublicKey}; use tari_comms::{connectivity::ConnectivityRequester, peer_manager::NodeId}; use tari_utilities::hex::Hex; use tokio::sync::RwLock; -use crate::base_node::comms_interface::comms_response::ValidatorNodeChangeState; #[cfg(feature = "metrics")] use crate::base_node::metrics; -use crate::{base_node::comms_interface::{ - error::CommsInterfaceError, - local_interface::BlockEventSender, - FetchMempoolTransactionsResponse, - NodeCommsRequest, - NodeCommsResponse, - OutboundNodeCommsInterface, -}, blocks::{Block, BlockBuilder, BlockHeader, BlockHeaderValidationError, ChainBlock, NewBlock, NewBlockTemplate}, chain_storage, chain_storage::{async_db::AsyncBlockchainDb, BlockAddResult, BlockchainBackend, ChainStorageError}, consensus::{ConsensusConstants, ConsensusManager}, mempool::Mempool, proof_of_work::{ - randomx_difficulty, - randomx_factory::RandomXFactory, - sha3x_difficulty, - Difficulty, - PowAlgorithm, - PowError, -}, transactions::aggregated_body::AggregateBody, validation::{helpers, ValidationError}}; +use crate::{ + base_node::comms_interface::{ + comms_response::{ValidatorNodeChange, ValidatorNodeChangeState}, + error::CommsInterfaceError, + local_interface::BlockEventSender, + FetchMempoolTransactionsResponse, + NodeCommsRequest, + NodeCommsResponse, + OutboundNodeCommsInterface, + }, + blocks::{Block, BlockBuilder, BlockHeader, BlockHeaderValidationError, ChainBlock, NewBlock, NewBlockTemplate}, + chain_storage::{async_db::AsyncBlockchainDb, BlockAddResult, BlockchainBackend, ChainStorageError}, + consensus::{ConsensusConstants, ConsensusManager}, + mempool::Mempool, + proof_of_work::{ + randomx_difficulty, + randomx_factory::RandomXFactory, + sha3x_difficulty, + Difficulty, + PowAlgorithm, + PowError, + }, + transactions::aggregated_body::AggregateBody, + validation::{helpers, ValidationError}, +}; const LOG_TARGET: &str = "c::bn::comms_interface::inbound_handler"; const MAX_REQUEST_BY_BLOCK_HASHES: usize = 100; @@ -84,8 +98,7 @@ pub struct InboundNodeCommsHandlers { } impl InboundNodeCommsHandlers -where - B: BlockchainBackend + 'static, +where B: BlockchainBackend + 'static { /// Construct a new InboundNodeCommsInterface. pub fn new( @@ -120,7 +133,7 @@ where NodeCommsRequest::FetchHeaders(range) => { let headers = self.blockchain_db.fetch_chain_headers(range).await?; Ok(NodeCommsResponse::BlockHeaders(headers)) - } + }, NodeCommsRequest::FetchHeadersByHashes(block_hashes) => { if block_hashes.len() > MAX_REQUEST_BY_BLOCK_HASHES { return Err(CommsInterfaceError::InvalidRequest { @@ -138,18 +151,18 @@ where match self.blockchain_db.fetch_chain_header_by_block_hash(block_hash).await? { Some(block_header) => { block_headers.push(block_header); - } + }, None => { error!(target: LOG_TARGET, "Could not fetch headers with hashes:{}", block_hex); return Err(CommsInterfaceError::InternalError(format!( "Could not fetch headers with hashes:{}", block_hex ))); - } + }, } } Ok(NodeCommsResponse::BlockHeaders(block_headers)) - } + }, NodeCommsRequest::FetchMatchingUtxos(utxo_hashes) => { let mut res = Vec::with_capacity(utxo_hashes.len()); for (output, spent) in (self @@ -164,11 +177,11 @@ where } } Ok(NodeCommsResponse::TransactionOutputs(res)) - } + }, NodeCommsRequest::FetchMatchingBlocks { range, compact } => { let blocks = self.blockchain_db.fetch_blocks(range, compact).await?; Ok(NodeCommsResponse::HistoricalBlocks(blocks)) - } + }, NodeCommsRequest::FetchBlocksByKernelExcessSigs(excess_sigs) => { if excess_sigs.len() > MAX_REQUEST_BY_KERNEL_EXCESS_SIGS { return Err(CommsInterfaceError::InvalidRequest { @@ -204,7 +217,7 @@ where } } Ok(NodeCommsResponse::HistoricalBlocks(blocks)) - } + }, NodeCommsRequest::FetchBlocksByUtxos(commitments) => { if commitments.len() > MAX_REQUEST_BY_UTXO_HASHES { return Err(CommsInterfaceError::InvalidRequest { @@ -239,15 +252,15 @@ where } } Ok(NodeCommsResponse::HistoricalBlocks(blocks)) - } + }, NodeCommsRequest::GetHeaderByHash(hash) => { let header = self.blockchain_db.fetch_chain_header_by_block_hash(hash).await?; Ok(NodeCommsResponse::BlockHeader(header)) - } + }, NodeCommsRequest::GetBlockByHash(hash) => { let block = self.blockchain_db.fetch_block_by_hash(hash, false).await?; Ok(NodeCommsResponse::HistoricalBlock(Box::new(block))) - } + }, NodeCommsRequest::GetNewBlockTemplate(request) => { let best_block_header = self.blockchain_db.fetch_tip_header().await?; let last_seen_hash = self.mempool.get_last_seen_hash().await?; @@ -321,7 +334,7 @@ where ); Ok(NodeCommsResponse::NewBlockTemplate(block_template)) - } + }, NodeCommsRequest::GetNewBlock(block_template) => { let height = block_template.header.height; let target_difficulty = block_template.target_difficulty; @@ -343,7 +356,7 @@ where error: None, block: Some(block), }) - } + }, NodeCommsRequest::GetBlockFromAllChains(hash) => { let block_hex = hash.to_hex(); debug!( @@ -381,7 +394,7 @@ where }; Ok(NodeCommsResponse::Block(Box::new(maybe_block))) - } + }, NodeCommsRequest::FetchKernelByExcessSig(signature) => { let kernels = match self.blockchain_db.fetch_kernel_by_excess_sig(signature).await { Ok(Some((kernel, _))) => vec![kernel], @@ -389,11 +402,11 @@ where Err(err) => { error!(target: LOG_TARGET, "Could not fetch kernel {}", err.to_string()); return Err(err.into()); - } + }, }; Ok(NodeCommsResponse::TransactionKernels(kernels)) - } + }, NodeCommsRequest::FetchMempoolTransactionsByExcessSigs { excess_sigs } => { let (transactions, not_found) = self.mempool.retrieve_by_excess_sigs(excess_sigs).await?; Ok(NodeCommsResponse::FetchMempoolTransactionsByExcessSigsResponse( @@ -402,7 +415,7 @@ where not_found, }, )) - } + }, NodeCommsRequest::FetchValidatorNodesKeys { height, validator_network, @@ -414,11 +427,11 @@ where Ok(NodeCommsResponse::FetchValidatorNodesKeysResponse( active_validator_nodes, )) - } + }, NodeCommsRequest::GetShardKey { height, public_key } => { let shard_key = self.blockchain_db.get_shard_key(height, public_key).await?; Ok(NodeCommsResponse::GetShardKeyResponse(shard_key)) - } + }, NodeCommsRequest::FetchTemplateRegistrations { start_height, end_height, @@ -430,13 +443,16 @@ where Ok(NodeCommsResponse::FetchTemplateRegistrationsResponse( template_registrations, )) - } + }, NodeCommsRequest::FetchUnspentUtxosInBlock { block_hash } => { let utxos = self.blockchain_db.fetch_outputs_in_block(block_hash).await?; Ok(NodeCommsResponse::TransactionOutputs(utxos)) - } - NodeCommsRequest::FetchValidatorNodeChanges { start_height, end_height, sidechain_id } => { - let mut result = vec![]; + }, + NodeCommsRequest::FetchValidatorNodeChanges { + start_height, + end_height, + sidechain_id, + } => { let mut node_changes = HashMap::::new(); let mut nodes = self .blockchain_db @@ -452,21 +468,30 @@ where .fetch_active_validator_nodes(height, sidechain_id.clone()) .await?; - current_nodes.iter().for_each(|curr_node| { - // new vn added - if !node_changes.contains_key(&curr_node.public_key) { - node_changes.insert(curr_node.public_key.clone(), ValidatorNodeChangeState::ADD); + nodes.iter().for_each(|prev_node| { + let prev_exists_in_new_set = current_nodes + .iter() + .any(|current_node| prev_node.public_key == current_node.public_key); + if prev_exists_in_new_set { + node_changes.insert(prev_node.public_key.clone(), ValidatorNodeChangeState::ADD); + } else { + node_changes.insert(prev_node.public_key.clone(), ValidatorNodeChangeState::REMOVE); } - // TODO: handle case when we do not find a node in the current set from old set }); nodes = current_nodes; } - // TODO: convert node_changes into result - - Ok(NodeCommsResponse::FetchValidatorNodeChangesResponse(vec![])) - } + Ok(NodeCommsResponse::FetchValidatorNodeChangesResponse( + node_changes + .iter() + .map(|(pub_key, state)| ValidatorNodeChange { + public_key: pub_key.clone(), + state: state.clone(), + }) + .collect(), + )) + }, } } @@ -754,7 +779,7 @@ where Err(_) => { let block = self.request_full_block_from_peer(source_peer, block_hash).await?; return Ok(block); - } + }, Ok(v) => v, }; if let Err(e) = helpers::check_mmr_roots(&header, &mmr_roots) { @@ -795,14 +820,14 @@ where "Invalid response from peer `{}`: Peer failed to provide the block that was propagated", source_peer ))) - } + }, Err(CommsInterfaceError::UnexpectedApiResponse) => { debug!( target: LOG_TARGET, "Peer `{}` sent unexpected API response.", source_peer ); Err(CommsInterfaceError::UnexpectedApiResponse) - } + }, Err(e) => Err(e), } } @@ -877,7 +902,7 @@ where } } Ok(block_hash) - } + }, Err(e @ ChainStorageError::ValidationError { .. }) => { #[cfg(feature = "metrics")] @@ -896,7 +921,7 @@ where ); self.publish_block_event(BlockEvent::AddBlockValidationFailed { block, source_peer }); Err(e.into()) - } + }, Err(e) => { #[cfg(feature = "metrics")] @@ -904,7 +929,7 @@ where self.publish_block_event(BlockEvent::AddBlockErrored { block }); Err(e.into()) - } + }, } } @@ -979,11 +1004,11 @@ where PowAlgorithm::Sha3x => { metrics::target_difficulty_sha() .set(i64::try_from(block.accumulated_data().target_difficulty.as_u64()).unwrap_or(i64::MAX)); - } + }, PowAlgorithm::RandomX => { metrics::target_difficulty_randomx() .set(i64::try_from(block.accumulated_data().target_difficulty.as_u64()).unwrap_or(i64::MAX)); - } + }, } } @@ -994,7 +1019,7 @@ where metrics::tip_height().set(block.height() as i64); let utxo_set_size = self.blockchain_db.utxo_count().await?; metrics::utxo_set_size().set(utxo_set_size.try_into().unwrap_or(i64::MAX)); - } + }, BlockAddResult::ChainReorg { added, removed } => { if let Some(fork_height) = added.last().map(|b| b.height()) { #[allow(clippy::cast_possible_wrap)] @@ -1007,11 +1032,11 @@ where for block in added { update_target_difficulty(block); } - } + }, BlockAddResult::OrphanBlock => { metrics::orphaned_blocks().inc(); - } - _ => {} + }, + _ => {}, } Ok(()) } diff --git a/base_layer/core/src/base_node/comms_interface/local_interface.rs b/base_layer/core/src/base_node/comms_interface/local_interface.rs index c684bc1b38..5f8af2d2a7 100644 --- a/base_layer/core/src/base_node/comms_interface/local_interface.rs +++ b/base_layer/core/src/base_node/comms_interface/local_interface.rs @@ -22,10 +22,17 @@ use std::{ops::RangeInclusive, sync::Arc}; -use crate::base_node::comms_interface::comms_response::ValidatorNodeChange; +use tari_common_types::{ + chain_metadata::ChainMetadata, + types::{BlockHash, Commitment, HashOutput, PublicKey, Signature}, +}; +use tari_service_framework::{reply_channel::SenderService, Service}; +use tokio::sync::broadcast; + use crate::{ base_node::comms_interface::{ comms_request::GetNewBlockTemplateRequest, + comms_response::ValidatorNodeChange, error::CommsInterfaceError, BlockEvent, NodeCommsRequest, @@ -36,12 +43,6 @@ use crate::{ proof_of_work::PowAlgorithm, transactions::transaction_components::{TransactionKernel, TransactionOutput}, }; -use tari_common_types::{ - chain_metadata::ChainMetadata, - types::{BlockHash, Commitment, HashOutput, PublicKey, Signature}, -}; -use tari_service_framework::{reply_channel::SenderService, Service}; -use tokio::sync::broadcast; pub type BlockEventSender = broadcast::Sender>; pub type BlockEventReceiver = broadcast::Receiver>; @@ -180,7 +181,7 @@ impl LocalNodeCommsInterface { error.unwrap_or_else(|| "Unspecified error".to_string()), )) } - } + }, _ => Err(CommsInterfaceError::UnexpectedApiResponse), } } diff --git a/base_layer/core/src/base_node/comms_interface/mod.rs b/base_layer/core/src/base_node/comms_interface/mod.rs index dd3edbc32f..5804f072b0 100644 --- a/base_layer/core/src/base_node/comms_interface/mod.rs +++ b/base_layer/core/src/base_node/comms_interface/mod.rs @@ -24,7 +24,12 @@ mod comms_request; pub use comms_request::{GetNewBlockTemplateRequest, MmrStateRequest, NodeCommsRequest}; mod comms_response; -pub use comms_response::{FetchMempoolTransactionsResponse, NodeCommsResponse}; +pub use comms_response::{ + FetchMempoolTransactionsResponse, + NodeCommsResponse, + ValidatorNodeChange, + ValidatorNodeChangeState, +}; mod error; pub use error::CommsInterfaceError; diff --git a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs index 09e8a6a864..6c4fcfa0d3 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs @@ -337,17 +337,17 @@ impl LMDBDatabase { InsertOrphanBlock(block) => self.insert_orphan_block(&write_txn, block)?, InsertChainHeader { header } => { self.insert_header(&write_txn, header.header(), header.accumulated_data())?; - } + }, InsertTipBlockBody { block, smt } => { self.insert_tip_block_body(&write_txn, block.header(), block.block().body.clone(), smt.clone())?; - } + }, InsertKernel { header_hash, kernel, mmr_position, } => { self.insert_kernel(&write_txn, header_hash, kernel, *mmr_position)?; - } + }, InsertOutput { header_hash, header_height, @@ -355,13 +355,13 @@ impl LMDBDatabase { output, } => { self.insert_output(&write_txn, header_hash, *header_height, *timestamp, output)?; - } + }, DeleteHeader(height) => { self.delete_header(&write_txn, *height)?; - } + }, DeleteOrphan(hash) => { self.delete_orphan(&write_txn, hash)?; - } + }, DeleteOrphanChainTip(hash) => { lmdb_delete( &write_txn, @@ -369,7 +369,7 @@ impl LMDBDatabase { hash.deref(), "orphan_chain_tips_db", )?; - } + }, InsertOrphanChainTip(hash, total_accumulated_difficulty) => { lmdb_insert( &write_txn, @@ -381,39 +381,39 @@ impl LMDBDatabase { }, "orphan_chain_tips_db", )?; - } + }, DeleteTipBlock(hash, smt) => { self.delete_tip_block_body(&write_txn, hash, smt.clone())?; - } + }, InsertMoneroSeedHeight(data, height) => { self.insert_monero_seed_height(&write_txn, data, *height)?; - } + }, SetAccumulatedDataForOrphan(accumulated_data) => { self.set_accumulated_data_for_orphan(&write_txn, accumulated_data)?; - } + }, InsertChainOrphanBlock(chain_block) => { self.insert_orphan_block(&write_txn, chain_block.block())?; self.set_accumulated_data_for_orphan(&write_txn, chain_block.accumulated_data())?; - } + }, UpdateBlockAccumulatedData { header_hash, values } => { self.update_block_accumulated_data(&write_txn, header_hash, values.clone())?; - } + }, PruneOutputsSpentAtHash { block_hash } => { self.prune_outputs_spent_at_hash(&write_txn, block_hash)?; - } + }, PruneOutputFromAllDbs { output_hash, commitment, output_type, } => { self.prune_output_from_all_dbs(&write_txn, output_hash, commitment, *output_type)?; - } + }, DeleteAllKernelsInBlock { block_hash } => { self.delete_all_kernels_in_block(&write_txn, block_hash)?; - } + }, DeleteAllInputsInBlock { block_hash } => { self.delete_all_inputs_in_block(&write_txn, block_hash)?; - } + }, SetBestBlock { height, hash, @@ -458,37 +458,37 @@ impl LMDBDatabase { MetadataKey::BestBlockTimestamp, &MetadataValue::BestBlockTimestamp(*timestamp), )?; - } + }, SetPruningHorizonConfig(pruning_horizon) => { self.set_metadata( &write_txn, MetadataKey::PruningHorizon, &MetadataValue::PruningHorizon(*pruning_horizon), )?; - } + }, SetPrunedHeight { height } => { self.set_metadata( &write_txn, MetadataKey::PrunedHeight, &MetadataValue::PrunedHeight(*height), )?; - } + }, SetHorizonData { horizon_data } => { self.set_metadata( &write_txn, MetadataKey::HorizonData, &MetadataValue::HorizonData(horizon_data.clone()), )?; - } + }, InsertBadBlock { hash, height, reason } => { self.insert_bad_block_and_cleanup(&write_txn, hash, *height, reason.to_string())?; - } + }, InsertReorg { reorg } => { lmdb_replace(&write_txn, &self.reorgs, &reorg.local_time.timestamp(), &reorg, None)?; - } + }, ClearAllReorgs => { lmdb_clear(&write_txn, &self.reorgs)?; - } + }, } } write_txn.commit()?; @@ -651,7 +651,7 @@ impl LMDBDatabase { field: "hash", value: output_hash.to_hex(), }); - } + }, Err(e) => { error!( target: LOG_TARGET, @@ -659,7 +659,7 @@ impl LMDBDatabase { output_hash.to_hex(), e ); return Err(e); - } + }, }, }; Ok(input_with_output_data) @@ -985,7 +985,7 @@ impl LMDBDatabase { } let smt_key = NodeKey::try_from(utxo.output.commitment.as_bytes())?; match output_smt.delete(&smt_key)? { - DeleteResult::Deleted(_value_hash) => {} + DeleteResult::Deleted(_value_hash) => {}, DeleteResult::KeyNotFound => { error!( target: LOG_TARGET, @@ -993,7 +993,7 @@ impl LMDBDatabase { utxo.output.commitment.to_hex(), ); return Err(ChainStorageError::UnspendableInput); - } + }, }; lmdb_delete( txn, @@ -1111,7 +1111,7 @@ impl LMDBDatabase { hash.to_hex() ); return Ok(()); - } + }, }; let parent_hash = orphan.header.prev_hash; @@ -1142,19 +1142,19 @@ impl LMDBDatabase { }, "orphan_chain_tips_db", )?; - } + }, None => { warn!( target: LOG_TARGET, "Empty 'BlockHeaderAccumulatedData' for parent hash '{}'", parent_hash.to_hex() ); - } + }, } - } + }, (false, false) => { // No entries, nothing here - } + }, _ => { // Some previous database operations were not atomic warn!( @@ -1164,7 +1164,7 @@ impl LMDBDatabase { lmdb_exists(txn, &self.orphan_header_accumulated_data_db, parent_hash.as_slice())?, parent_hash.to_hex() ); - } + }, } } @@ -1313,7 +1313,7 @@ impl LMDBDatabase { let input_with_output_data = self.input_with_output_data(txn, input)?; let smt_key = NodeKey::try_from(input_with_output_data.commitment()?.as_bytes())?; match output_smt.delete(&smt_key)? { - DeleteResult::Deleted(_value_hash) => {} + DeleteResult::Deleted(_value_hash) => {}, DeleteResult::KeyNotFound => { error!( target: LOG_TARGET, @@ -1321,7 +1321,7 @@ impl LMDBDatabase { input_with_output_data.commitment()?.to_hex(), ); return Err(ChainStorageError::UnspendableInput); - } + }, }; let features = input_with_output_data.features()?; @@ -1360,7 +1360,7 @@ impl LMDBDatabase { Ok(()) } - fn validator_node_store<'a, T: Deref>>( + fn validator_node_store<'a, T: Deref>>( &'a self, txn: &'a T, ) -> ValidatorNodeStore<'a, T> { @@ -1396,7 +1396,8 @@ impl LMDBDatabase { let current_vn_count = store.get_vn_count_until_epoch(current_epoch, vn_reg.sidechain_id().cloned())?; let mut vn_count = store.get_vn_count_in_epoch(next_epoch, vn_reg.sidechain_id().cloned())?; if (current_vn_count == 0 && vn_count >= constants.vn_registration_max_vns_initial_epoch()) || - (current_vn_count > 0 && vn_count > constants.vn_registration_max_vns_per_epoch()) { + (current_vn_count > 0 && vn_count > constants.vn_registration_max_vns_per_epoch()) + { while vn_count > constants.vn_registration_max_vns_per_epoch() { next_epoch += VnEpoch(1); vn_count = store.get_vn_count_in_epoch(next_epoch, vn_reg.sidechain_id().cloned())?; @@ -1565,7 +1566,7 @@ impl LMDBDatabase { let key = OutputKey::new(&FixedHash::from(buffer), output_hash)?; debug!(target: LOG_TARGET, "Pruning output from 'utxos_db': key '{}'", key.0); lmdb_delete(write_txn, &self.utxos_db, &key.convert_to_comp_key(), LMDB_DB_UTXOS)?; - } + }, None => return Err(ChainStorageError::InvalidOperation("Output key not found".to_string())), } @@ -1674,12 +1675,12 @@ impl LMDBDatabase { if let Some(key) = lmdb_get::<_, Vec>(txn, &self.txos_hash_to_index_db, output_hash)? { match lmdb_get::<_, TransactionOutputRowData>(txn, &self.utxos_db, &key)? { Some(TransactionOutputRowData { - output: o, - mined_height, - header_hash, - mined_timestamp, - .. - }) => Ok(Some(OutputMinedInfo { + output: o, + mined_height, + header_hash, + mined_timestamp, + .. + }) => Ok(Some(OutputMinedInfo { output: o, mined_height, header_hash, @@ -1701,12 +1702,12 @@ impl LMDBDatabase { if let Some(key) = lmdb_get::<_, Vec>(txn, &self.deleted_txo_hash_to_header_index, output_hash)? { match lmdb_get::<_, TransactionInputRowData>(txn, &self.inputs_db, &key)? { Some(TransactionInputRowData { - input: i, - spent_height: height, - header_hash, - spent_timestamp, - .. - }) => Ok(Some(InputMinedInfo { + input: i, + spent_height: height, + header_hash, + spent_timestamp, + .. + }) => Ok(Some(InputMinedInfo { input: i, spent_height: height, header_hash, @@ -1800,7 +1801,7 @@ impl BlockchainBackend for LMDBDatabase { ); return Ok(()); - } + }, Err(ChainStorageError::DbResizeRequired(size_that_could_not_be_written)) => { info!( target: LOG_TARGET, @@ -1814,11 +1815,11 @@ impl BlockchainBackend for LMDBDatabase { unsafe { LMDBStore::resize(&self.env, &self.env_config, size_that_could_not_be_written)?; } - } + }, Err(e) => { error!(target: LOG_TARGET, "Failed to apply DB transaction: {:?}", e); return Err(e); - } + }, } } @@ -1831,7 +1832,7 @@ impl BlockchainBackend for LMDBDatabase { DbKey::HeaderHeight(k) => { let val: Option = lmdb_get(&txn, &self.headers_db, k)?; val.map(|val| DbValue::HeaderHeight(Box::new(val))) - } + }, DbKey::HeaderHash(hash) => { let k: Option = self.fetch_height_from_hash(&txn, hash)?; match k { @@ -1844,7 +1845,7 @@ impl BlockchainBackend for LMDBDatabase { ); let val: Option = lmdb_get(&txn, &self.headers_db, &k)?; val.map(|val| DbValue::HeaderHash(Box::new(val))) - } + }, None => { trace!( target: LOG_TARGET, @@ -1852,9 +1853,9 @@ impl BlockchainBackend for LMDBDatabase { hash.to_hex() ); None - } + }, } - } + }, DbKey::OrphanBlock(k) => self .fetch_orphan(&txn, k)? .map(|val| DbValue::OrphanBlock(Box::new(val))), @@ -2335,10 +2336,10 @@ impl BlockchainBackend for LMDBDatabase { } })?; Ok(Some(chain_block)) - } + }, None => Ok(None), } - } + }, None => Ok(None), } } @@ -2441,7 +2442,7 @@ impl BlockchainBackend for LMDBDatabase { } else { Err(ChainStorageError::AccessError(e)) } - } + }, Err(e) => Err(e), } } @@ -2452,7 +2453,7 @@ impl BlockchainBackend for LMDBDatabase { Some(h) => h, None => { return Ok(0); - } + }, }; let metadata = fetch_metadata(&txn, &self.metadata_db)?; diff --git a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs index 9a1636f460..36ad67aa58 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs @@ -22,6 +22,14 @@ use std::{collections::HashMap, ops::Deref}; +use lmdb_zero::{ConstTransaction, WriteTransaction}; +use tari_common_types::{ + epoch::VnEpoch, + types::{Commitment, PublicKey}, +}; +use tari_storage::lmdb_store::DatabaseRef; +use tari_utilities::ByteArray; + use crate::chain_storage::{ lmdb_db::{ composite_key::CompositeKey, @@ -32,11 +40,6 @@ use crate::chain_storage::{ ValidatorNodeEntry, ValidatorNodeRegistrationInfo, }; -use lmdb_zero::{ConstTransaction, WriteTransaction}; -use tari_common_types::epoch::VnEpoch; -use tari_common_types::types::{Commitment, PublicKey}; -use tari_storage::lmdb_store::DatabaseRef; -use tari_utilities::ByteArray; pub type ShardKey = [u8; 32]; // @@ -50,7 +53,7 @@ pub struct ValidatorNodeStore<'a, Txn> { db_validator_nodes_mapping: DatabaseRef, } -impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { +impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { pub fn new(txn: &'a Txn, db_height_to_vn: DatabaseRef, idx_public_key_to_shard: DatabaseRef) -> Self { Self { txn, @@ -67,7 +70,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { validator.public_key.as_bytes(), validator.commitment.as_bytes(), ]) - .expect("insert: Composite key length is incorrect"); + .expect("insert: Composite key length is incorrect"); lmdb_insert(self.txn, &self.db_validator_nodes, &key, &validator, "Validator node")?; let key = ShardIdIndexKey::try_from_parts(&[ @@ -75,7 +78,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { height.to_be_bytes().as_slice(), validator.commitment.as_bytes(), ]) - .expect("insert: Composite key length is incorrect"); + .expect("insert: Composite key length is incorrect"); lmdb_insert( self.txn, &self.db_validator_nodes_mapping, @@ -97,7 +100,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { public_key.as_bytes(), commitment.as_bytes(), ]) - .expect("delete: Composite key length is incorrect"); + .expect("delete: Composite key length is incorrect"); lmdb_delete(self.txn, &self.db_validator_nodes, &key, "validator_nodes")?; let key = ShardIdIndexKey::try_from_parts(&[ @@ -105,7 +108,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { height.to_be_bytes().as_slice(), commitment.as_bytes(), ]) - .expect("delete: Composite key length is incorrect"); + .expect("delete: Composite key length is incorrect"); lmdb_delete( self.txn, &self.db_validator_nodes_mapping, @@ -116,7 +119,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { } } -impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { +impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { fn db_read_cursor(&self) -> Result, ChainStorageError> { let cursor = self.txn.cursor(self.db_validator_nodes.clone())?; let access = self.txn.access(); @@ -190,7 +193,7 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { sidechain_id: vn.sidechain_id, shard_key: vn.shard_key, })); - } + }, None => return Ok(Vec::new()), } @@ -246,7 +249,7 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { return Ok(None); } Some(s) - } + }, None => return Ok(None), }; @@ -277,7 +280,7 @@ mod tests { const DBS: &[&str] = &["validator_node_store", "validator_node_index"]; - fn create_store<'a, Txn: Deref>>( + fn create_store<'a, Txn: Deref>>( db: &TempLmdbDatabase, txn: &'a Txn, ) -> ValidatorNodeStore<'a, Txn> { From 611a7f39fbfcbcee28805d624a99e8362d4f17fe Mon Sep 17 00:00:00 2001 From: ksrichard Date: Tue, 5 Nov 2024 14:08:07 +0100 Subject: [PATCH 06/23] changed logic of node add/remove changes --- .../comms_interface/inbound_handlers.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs index 3f89625570..2f5d80f958 100644 --- a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs +++ b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs @@ -458,27 +458,32 @@ where B: BlockchainBackend + 'static .blockchain_db .fetch_active_validator_nodes(start_height, sidechain_id.clone()) .await?; - // add initial validator node set - nodes.iter().for_each(|node| { - node_changes.insert(node.public_key.clone(), ValidatorNodeChangeState::ADD); - }); for height in start_height + 1..=end_height { let current_nodes = self .blockchain_db .fetch_active_validator_nodes(height, sidechain_id.clone()) .await?; + // remove nodes nodes.iter().for_each(|prev_node| { let prev_exists_in_new_set = current_nodes .iter() .any(|current_node| prev_node.public_key == current_node.public_key); - if prev_exists_in_new_set { - node_changes.insert(prev_node.public_key.clone(), ValidatorNodeChangeState::ADD); - } else { + if !prev_exists_in_new_set { node_changes.insert(prev_node.public_key.clone(), ValidatorNodeChangeState::REMOVE); } }); + // add nodes + current_nodes.iter().for_each(|current_node| { + let new_exists_in_prev = nodes + .iter() + .any(|prev_node| current_node.public_key == prev_node.public_key); + if !new_exists_in_prev { + node_changes.insert(current_node.public_key.clone(), ValidatorNodeChangeState::ADD); + } + }); + nodes = current_nodes; } From 949673f8a4424621d643d9e4813c128946916957 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Wed, 6 Nov 2024 22:18:58 +0100 Subject: [PATCH 07/23] impl in progress --- .../minotari_app_grpc/proto/base_node.proto | 1 + .../commands/command/list_validator_nodes.rs | 1 + .../src/grpc/base_node_grpc_server.rs | 2 ++ .../comms_interface/comms_response.rs | 2 ++ .../comms_interface/inbound_handlers.rs | 28 ++++++++++++++----- .../src/chain_storage/blockchain_database.rs | 7 +++-- .../core/src/chain_storage/lmdb_db/lmdb_db.rs | 17 +++++++++-- .../lmdb_db/validator_node_store.rs | 2 ++ base_layer/core/src/chain_storage/mod.rs | 6 +++- 9 files changed, 53 insertions(+), 13 deletions(-) diff --git a/applications/minotari_app_grpc/proto/base_node.proto b/applications/minotari_app_grpc/proto/base_node.proto index fb91566f0f..cc45acd3aa 100644 --- a/applications/minotari_app_grpc/proto/base_node.proto +++ b/applications/minotari_app_grpc/proto/base_node.proto @@ -501,6 +501,7 @@ enum ValidatorNodeChangeState { message ValidatorNodeChange { bytes public_key = 1; ValidatorNodeChangeState state = 2; + uint64 epoch = 3; } message GetValidatorNodeChangesResponse { diff --git a/applications/minotari_node/src/commands/command/list_validator_nodes.rs b/applications/minotari_node/src/commands/command/list_validator_nodes.rs index 818c6dd8de..b33cd467be 100644 --- a/applications/minotari_node/src/commands/command/list_validator_nodes.rs +++ b/applications/minotari_node/src/commands/command/list_validator_nodes.rs @@ -52,6 +52,7 @@ impl CommandContext { public_key, sidechain_id: validator_network, shard_key, + .. } in vns { table.add_row(row![ diff --git a/applications/minotari_node/src/grpc/base_node_grpc_server.rs b/applications/minotari_node/src/grpc/base_node_grpc_server.rs index f7ad86a914..610d01ce22 100644 --- a/applications/minotari_node/src/grpc/base_node_grpc_server.rs +++ b/applications/minotari_node/src/grpc/base_node_grpc_server.rs @@ -2323,6 +2323,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { public_key, sidechain_id, shard_key, + .. } in active_validator_nodes { let active_validator_node = tari_rpc::GetActiveValidatorNodesResponse { @@ -2594,6 +2595,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { tari_rpc::ValidatorNodeChangeState::Remove.into() }, }, + epoch: node_change.epoch.0, }) .collect(); diff --git a/base_layer/core/src/base_node/comms_interface/comms_response.rs b/base_layer/core/src/base_node/comms_interface/comms_response.rs index 8e844a5451..9ada9bafff 100644 --- a/base_layer/core/src/base_node/comms_interface/comms_response.rs +++ b/base_layer/core/src/base_node/comms_interface/comms_response.rs @@ -27,6 +27,7 @@ use std::{ use tari_common_types::{ chain_metadata::ChainMetadata, + epoch::VnEpoch, types::{HashOutput, PrivateKey, PublicKey}, }; @@ -123,4 +124,5 @@ pub enum ValidatorNodeChangeState { pub struct ValidatorNodeChange { pub public_key: PublicKey, pub state: ValidatorNodeChangeState, + pub epoch: VnEpoch, } diff --git a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs index 2f5d80f958..535c40013d 100644 --- a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs +++ b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs @@ -31,7 +31,11 @@ use std::{ use log::*; use strum_macros::Display; -use tari_common_types::types::{BlockHash, FixedHash, HashOutput, PublicKey}; +use tari_common::configuration::Network; +use tari_common_types::{ + epoch::VnEpoch, + types::{BlockHash, FixedHash, HashOutput, PublicKey}, +}; use tari_comms::{connectivity::ConnectivityRequester, peer_manager::NodeId}; use tari_utilities::hex::Hex; use tokio::sync::RwLock; @@ -50,7 +54,7 @@ use crate::{ }, blocks::{Block, BlockBuilder, BlockHeader, BlockHeaderValidationError, ChainBlock, NewBlock, NewBlockTemplate}, chain_storage::{async_db::AsyncBlockchainDb, BlockAddResult, BlockchainBackend, ChainStorageError}, - consensus::{ConsensusConstants, ConsensusManager}, + consensus::{ConsensusConstants, ConsensusConstantsBuilder, ConsensusManager}, mempool::Mempool, proof_of_work::{ randomx_difficulty, @@ -453,7 +457,8 @@ where B: BlockchainBackend + 'static end_height, sidechain_id, } => { - let mut node_changes = HashMap::::new(); + let constants = self.consensus_manager.consensus_constants(start_height); + let mut node_changes = HashMap::::new(); let mut nodes = self .blockchain_db .fetch_active_validator_nodes(start_height, sidechain_id.clone()) @@ -470,7 +475,11 @@ where B: BlockchainBackend + 'static .iter() .any(|current_node| prev_node.public_key == current_node.public_key); if !prev_exists_in_new_set { - node_changes.insert(prev_node.public_key.clone(), ValidatorNodeChangeState::REMOVE); + node_changes.insert(prev_node.public_key.clone(), ValidatorNodeChange { + public_key: prev_node.public_key.clone(), + state: ValidatorNodeChangeState::REMOVE, + epoch: prev_node.start_epoch, // TODO: revisit + }); } }); @@ -480,7 +489,11 @@ where B: BlockchainBackend + 'static .iter() .any(|prev_node| current_node.public_key == prev_node.public_key); if !new_exists_in_prev { - node_changes.insert(current_node.public_key.clone(), ValidatorNodeChangeState::ADD); + node_changes.insert(current_node.public_key.clone(), ValidatorNodeChange { + public_key: current_node.public_key.clone(), + state: ValidatorNodeChangeState::ADD, + epoch: current_node.start_epoch, + }); } }); @@ -490,9 +503,10 @@ where B: BlockchainBackend + 'static Ok(NodeCommsResponse::FetchValidatorNodeChangesResponse( node_changes .iter() - .map(|(pub_key, state)| ValidatorNodeChange { + .map(|(pub_key, change)| ValidatorNodeChange { public_key: pub_key.clone(), - state: state.clone(), + state: change.state.clone(), + epoch: change.epoch, }) .collect(), )) diff --git a/base_layer/core/src/chain_storage/blockchain_database.rs b/base_layer/core/src/chain_storage/blockchain_database.rs index 07adf1b892..ff467de6c4 100644 --- a/base_layer/core/src/chain_storage/blockchain_database.rs +++ b/base_layer/core/src/chain_storage/blockchain_database.rs @@ -1495,6 +1495,7 @@ pub fn calculate_validator_node_mr( public_key: pk, sidechain_id, shard_key, + .. } in validator_nodes { hash_map @@ -2308,14 +2309,14 @@ fn insert_orphan_and_find_new_tips( // We dont have to mark the block twice Err(e @ ValidationError::BadBlockFound { .. }) => { db.write(txn)?; - return Err(e.into()) - }, + return Err(e.into()); + } Err(e) => { txn.insert_bad_block(candidate_block.header.hash(), candidate_block.header.height, e.to_string()); db.write(txn)?; return Err(e.into()); - }, + } }; // Include the current block timestamp in the median window diff --git a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs index 6c4fcfa0d3..78eaed8a27 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs @@ -1393,17 +1393,30 @@ impl LMDBDatabase { let mut next_epoch = current_epoch + VnEpoch(1); // looking for next available epoch - let current_vn_count = store.get_vn_count_until_epoch(current_epoch, vn_reg.sidechain_id().cloned())?; + let current_vn_count = store.get_vn_count_until_epoch(next_epoch, vn_reg.sidechain_id().cloned())?; let mut vn_count = store.get_vn_count_in_epoch(next_epoch, vn_reg.sidechain_id().cloned())?; + + // TODO: remove, only for debugging + info!(target: LOG_TARGET, "Current VN count: {:?}, VN count for next epoch({:?}): {:?}", current_vn_count, next_epoch, vn_count); + if (current_vn_count == 0 && vn_count >= constants.vn_registration_max_vns_initial_epoch()) || - (current_vn_count > 0 && vn_count > constants.vn_registration_max_vns_per_epoch()) + (current_vn_count > 0 && vn_count >= constants.vn_registration_max_vns_per_epoch()) { + // TODO: remove, only for debugging + info!(target: LOG_TARGET, "Looking for a new epoch..."); + while vn_count > constants.vn_registration_max_vns_per_epoch() { next_epoch += VnEpoch(1); vn_count = store.get_vn_count_in_epoch(next_epoch, vn_reg.sidechain_id().cloned())?; + + // TODO: remove, only for debugging + info!(target: LOG_TARGET, "Next epoch({:?}) VN count: {:?}", next_epoch, vn_count); } } + // TODO: remove, only for debugging + info!(target: LOG_TARGET, "New VN start epoch: {:?}", next_epoch); + let validator_node = ValidatorNodeEntry { shard_key, start_epoch: next_epoch, diff --git a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs index 36ad67aa58..e20e9db1c8 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs @@ -192,6 +192,7 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> public_key: vn.public_key, sidechain_id: vn.sidechain_id, shard_key: vn.shard_key, + start_epoch: vn.start_epoch, })); }, None => return Ok(Vec::new()), @@ -215,6 +216,7 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> public_key: vn.public_key, sidechain_id: vn.sidechain_id, shard_key: vn.shard_key, + start_epoch: vn.start_epoch, })); i += 1; } diff --git a/base_layer/core/src/chain_storage/mod.rs b/base_layer/core/src/chain_storage/mod.rs index 8f576a2e6c..96c5b845ce 100644 --- a/base_layer/core/src/chain_storage/mod.rs +++ b/base_layer/core/src/chain_storage/mod.rs @@ -83,7 +83,10 @@ pub use utxo_mined_info::*; mod active_validator_node; pub use active_validator_node::ValidatorNodeEntry; -use tari_common_types::types::{HashOutput, PublicKey}; +use tari_common_types::{ + epoch::VnEpoch, + types::{HashOutput, PublicKey}, +}; mod template_registation; pub use template_registation::TemplateRegistrationEntry; @@ -99,4 +102,5 @@ pub struct ValidatorNodeRegistrationInfo { pub public_key: PublicKey, pub sidechain_id: Option, pub shard_key: [u8; 32], + pub start_epoch: VnEpoch, } From 19346028b9abbdfeb1b78e4cde9109a91c123c54 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Wed, 6 Nov 2024 22:56:46 +0100 Subject: [PATCH 08/23] impl in progress --- .../minotari_app_grpc/proto/base_node.proto | 2 +- .../src/grpc/base_node_grpc_server.rs | 120 +++++++++--------- .../comms_interface/comms_response.rs | 6 +- .../comms_interface/inbound_handlers.rs | 75 +++++------ 4 files changed, 102 insertions(+), 101 deletions(-) diff --git a/applications/minotari_app_grpc/proto/base_node.proto b/applications/minotari_app_grpc/proto/base_node.proto index cc45acd3aa..ae39495981 100644 --- a/applications/minotari_app_grpc/proto/base_node.proto +++ b/applications/minotari_app_grpc/proto/base_node.proto @@ -501,7 +501,7 @@ enum ValidatorNodeChangeState { message ValidatorNodeChange { bytes public_key = 1; ValidatorNodeChangeState state = 2; - uint64 epoch = 3; + uint64 start_height = 3; } message GetValidatorNodeChangesResponse { diff --git a/applications/minotari_node/src/grpc/base_node_grpc_server.rs b/applications/minotari_node/src/grpc/base_node_grpc_server.rs index 610d01ce22..9274faf0ac 100644 --- a/applications/minotari_node/src/grpc/base_node_grpc_server.rs +++ b/applications/minotari_node/src/grpc/base_node_grpc_server.rs @@ -293,7 +293,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ))) .await; return; - }, + } }; if headers.is_empty() { @@ -330,7 +330,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(format!("Error fetching block at height {}", current_height)), ))); return; - }, + } }; if block.is_none() { let _network_difficulty_response = tx.send(Err(obscure_error_if_true( @@ -386,7 +386,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Error communicating with base node: {}", err,); return; - }, + } Ok(data) => data, }; for transaction in transactions.unconfirmed_pool { @@ -408,7 +408,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); } return; - }, + } }; if tx @@ -453,7 +453,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::internal(err.to_string()), )); - }, + } Ok(data) => data.best_block_height(), }; @@ -476,7 +476,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { (res, false) => res + 1, }; (from..=tip, true) - }, + } Sorting::Asc => (0..=num_headers.saturating_sub(1), false), } } else { @@ -487,11 +487,11 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { (res, false) => res + 1, }; (from..=from_height, true) - }, + } Sorting::Asc => { let to = from_height.saturating_add(num_headers).saturating_sub(1); (from_height..=to, false) - }, + } } }; let consensus_rules = self.consensus_rules.clone(); @@ -500,7 +500,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { header_range.end().saturating_add(1), LIST_HEADERS_PAGE_SIZE, ) - .map_err(|e| obscure_error_if_true(report_error_flag, Status::invalid_argument(e)))?; + .map_err(|e| obscure_error_if_true(report_error_flag, Status::invalid_argument(e)))?; task::spawn(async move { trace!( target: LOG_TARGET, @@ -519,7 +519,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Internal base node service error: {}", err); return; - }, + } Ok(data) => { if is_reversed { data.into_iter() @@ -538,7 +538,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { Err(obscure_error_if_true(report_error_flag, Status::internal(e)) .to_string()) - }, + } } }) .rev() @@ -560,18 +560,18 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { Err(obscure_error_if_true(report_error_flag, Status::internal(e)) .to_string()) - }, + } } }) .collect::, String>>() } - }, + } }; match result_data { Err(e) => { error!(target: LOG_TARGET, "No result headers transmitted due to error: {}", e) - }, + } Ok(result_data) => { let result_size = result_data.len(); trace!(target: LOG_TARGET, "Result headers: {}", result_size); @@ -592,7 +592,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { return; } } - }, + } } } }); @@ -688,7 +688,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - }, + } Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -696,13 +696,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - }, + } Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - }, + } }; let fees = new_block.body.get_total_fee().map_err(|_| { obscure_error_if_true( @@ -857,12 +857,12 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { })? - prev_coinbase_value, ) - .map_err(|_| { - obscure_error_if_true( - report_error_flag, - Status::internal("Single coinbase fees exceeded u64".to_string()), - ) - })?; + .map_err(|_| { + obscure_error_if_true( + report_error_flag, + Status::internal("Single coinbase fees exceeded u64".to_string()), + ) + })?; prev_coinbase_value += u128::from(coinbase.value); } @@ -903,8 +903,8 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { range_proof_type, PaymentId::Empty, ) - .await - .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; + .await + .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; new_template.body.add_output(coinbase_output); let new_nonce = key_manager .get_next_key(TransactionKeyManagerBranch::KernelNonce.get_branch_key()) @@ -958,7 +958,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - }, + } Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -966,13 +966,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - }, + } Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - }, + } }; let gen_hash = handler .get_header(0) @@ -1101,8 +1101,8 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { range_proof_type, PaymentId::Empty, ) - .await - .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; + .await + .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; block_template.body.add_output(coinbase_output); let new_nonce = key_manager .get_next_key(TransactionKeyManagerBranch::KernelNonce.get_branch_key()) @@ -1156,7 +1156,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - }, + } Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -1164,13 +1164,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - }, + } Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - }, + } }; let fees = new_block.body.get_total_fee().map_err(|_| { obscure_error_if_true( @@ -1261,7 +1261,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - }, + } Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -1269,13 +1269,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - }, + } Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - }, + } }; // construct response let block_hash = new_block.hash().to_vec(); @@ -1516,7 +1516,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { * should not think its mined, but the * node does not think it is. */ } - }, + } TxStorageResponse::NotStored | TxStorageResponse::NotStoredConsensus | TxStorageResponse::NotStoredOrphan | @@ -1606,7 +1606,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - }, + } Ok(data) => data.into_iter().filter(|b| heights.contains(&b.header().height)), }; @@ -1696,7 +1696,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - }, + } Ok(data) => data, }; for block in blocks { @@ -1752,7 +1752,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - }, + } Ok(data) => data, }; for block in blocks { @@ -1812,7 +1812,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(format!("Error communicating with local base node: {}", err)), ))); return; - }, + } Ok(data) => data, }; for output in outputs { @@ -1826,14 +1826,14 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); return; } - }, + } Err(err) => { let _ignore = tx.send(Err(obscure_error_if_true( report_error_flag, Status::internal(format!("Error communicating with local base node: {}", err)), ))); return; - }, + } } } }); @@ -1933,7 +1933,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { BlockGroupType::BlockSize, report_error_flag, ) - .await + .await } async fn get_block_fees( @@ -1948,7 +1948,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { BlockGroupType::BlockFees, report_error_flag, ) - .await + .await } async fn get_version(&self, _request: Request) -> Result, Status> { @@ -2315,7 +2315,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Base node service error: {}", err,); return; - }, + } Ok(data) => data, }; @@ -2381,7 +2381,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { header.map(|h| h.height()).ok_or_else(|| { obscure_error_if_true(report_error_flag, Status::not_found("Start hash not found")) })? - }, + } None => 0, }; @@ -2401,7 +2401,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Base node service error: {}", err); return; - }, + } Ok(data) => data, }; @@ -2491,7 +2491,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { warn!(target: LOG_TARGET, "Base node service error: {}", e); return; - }, + } }; let next_header = match node_service.get_header(height.saturating_add(1)).await { @@ -2502,7 +2502,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(e.to_string()), ))); return; - }, + } }; let sidechain_outputs = utxos @@ -2529,7 +2529,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); return; } - }, + } Err(e) => { warn!( target: LOG_TARGET, @@ -2542,13 +2542,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ))) .await; return; - }, + } }; match next_header { Some(header) => { current_header = header; - }, + } None => break, } } @@ -2593,9 +2593,9 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { comms_interface::ValidatorNodeChangeState::ADD => tari_rpc::ValidatorNodeChangeState::Add.into(), comms_interface::ValidatorNodeChangeState::REMOVE => { tari_rpc::ValidatorNodeChangeState::Remove.into() - }, + } }, - epoch: node_change.epoch.0, + start_height: node_change.height, }) .collect(); @@ -2637,7 +2637,7 @@ async fn get_block_group( "Error communicating with local base node: {:?}", err, ); vec![] - }, + } Ok(data) => data, }; let extractor = match block_group_type { @@ -2653,15 +2653,15 @@ async fn get_block_group( report_error_flag, Status::unimplemented("Quantile has not been implemented"), )) - }, + } CalcType::Quartile => { return Err(obscure_error_if_true( report_error_flag, Status::unimplemented("Quartile has not been implemented"), )) - }, + } } - .unwrap_or_default(); + .unwrap_or_default(); trace!( target: LOG_TARGET, "Sending GetBlockSize response to client: {:?}", value diff --git a/base_layer/core/src/base_node/comms_interface/comms_response.rs b/base_layer/core/src/base_node/comms_interface/comms_response.rs index 9ada9bafff..e963745938 100644 --- a/base_layer/core/src/base_node/comms_interface/comms_response.rs +++ b/base_layer/core/src/base_node/comms_interface/comms_response.rs @@ -26,8 +26,8 @@ use std::{ }; use tari_common_types::{ - chain_metadata::ChainMetadata, - epoch::VnEpoch, + chain_metadata::ChainMetadata + , types::{HashOutput, PrivateKey, PublicKey}, }; @@ -124,5 +124,5 @@ pub enum ValidatorNodeChangeState { pub struct ValidatorNodeChange { pub public_key: PublicKey, pub state: ValidatorNodeChangeState, - pub epoch: VnEpoch, + pub height: u64, } diff --git a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs index 535c40013d..ad5b685562 100644 --- a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs +++ b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs @@ -102,7 +102,8 @@ pub struct InboundNodeCommsHandlers { } impl InboundNodeCommsHandlers -where B: BlockchainBackend + 'static +where + B: BlockchainBackend + 'static, { /// Construct a new InboundNodeCommsInterface. pub fn new( @@ -137,7 +138,7 @@ where B: BlockchainBackend + 'static NodeCommsRequest::FetchHeaders(range) => { let headers = self.blockchain_db.fetch_chain_headers(range).await?; Ok(NodeCommsResponse::BlockHeaders(headers)) - }, + } NodeCommsRequest::FetchHeadersByHashes(block_hashes) => { if block_hashes.len() > MAX_REQUEST_BY_BLOCK_HASHES { return Err(CommsInterfaceError::InvalidRequest { @@ -155,18 +156,18 @@ where B: BlockchainBackend + 'static match self.blockchain_db.fetch_chain_header_by_block_hash(block_hash).await? { Some(block_header) => { block_headers.push(block_header); - }, + } None => { error!(target: LOG_TARGET, "Could not fetch headers with hashes:{}", block_hex); return Err(CommsInterfaceError::InternalError(format!( "Could not fetch headers with hashes:{}", block_hex ))); - }, + } } } Ok(NodeCommsResponse::BlockHeaders(block_headers)) - }, + } NodeCommsRequest::FetchMatchingUtxos(utxo_hashes) => { let mut res = Vec::with_capacity(utxo_hashes.len()); for (output, spent) in (self @@ -181,11 +182,11 @@ where B: BlockchainBackend + 'static } } Ok(NodeCommsResponse::TransactionOutputs(res)) - }, + } NodeCommsRequest::FetchMatchingBlocks { range, compact } => { let blocks = self.blockchain_db.fetch_blocks(range, compact).await?; Ok(NodeCommsResponse::HistoricalBlocks(blocks)) - }, + } NodeCommsRequest::FetchBlocksByKernelExcessSigs(excess_sigs) => { if excess_sigs.len() > MAX_REQUEST_BY_KERNEL_EXCESS_SIGS { return Err(CommsInterfaceError::InvalidRequest { @@ -221,7 +222,7 @@ where B: BlockchainBackend + 'static } } Ok(NodeCommsResponse::HistoricalBlocks(blocks)) - }, + } NodeCommsRequest::FetchBlocksByUtxos(commitments) => { if commitments.len() > MAX_REQUEST_BY_UTXO_HASHES { return Err(CommsInterfaceError::InvalidRequest { @@ -256,15 +257,15 @@ where B: BlockchainBackend + 'static } } Ok(NodeCommsResponse::HistoricalBlocks(blocks)) - }, + } NodeCommsRequest::GetHeaderByHash(hash) => { let header = self.blockchain_db.fetch_chain_header_by_block_hash(hash).await?; Ok(NodeCommsResponse::BlockHeader(header)) - }, + } NodeCommsRequest::GetBlockByHash(hash) => { let block = self.blockchain_db.fetch_block_by_hash(hash, false).await?; Ok(NodeCommsResponse::HistoricalBlock(Box::new(block))) - }, + } NodeCommsRequest::GetNewBlockTemplate(request) => { let best_block_header = self.blockchain_db.fetch_tip_header().await?; let last_seen_hash = self.mempool.get_last_seen_hash().await?; @@ -338,7 +339,7 @@ where B: BlockchainBackend + 'static ); Ok(NodeCommsResponse::NewBlockTemplate(block_template)) - }, + } NodeCommsRequest::GetNewBlock(block_template) => { let height = block_template.header.height; let target_difficulty = block_template.target_difficulty; @@ -360,7 +361,7 @@ where B: BlockchainBackend + 'static error: None, block: Some(block), }) - }, + } NodeCommsRequest::GetBlockFromAllChains(hash) => { let block_hex = hash.to_hex(); debug!( @@ -398,7 +399,7 @@ where B: BlockchainBackend + 'static }; Ok(NodeCommsResponse::Block(Box::new(maybe_block))) - }, + } NodeCommsRequest::FetchKernelByExcessSig(signature) => { let kernels = match self.blockchain_db.fetch_kernel_by_excess_sig(signature).await { Ok(Some((kernel, _))) => vec![kernel], @@ -406,11 +407,11 @@ where B: BlockchainBackend + 'static Err(err) => { error!(target: LOG_TARGET, "Could not fetch kernel {}", err.to_string()); return Err(err.into()); - }, + } }; Ok(NodeCommsResponse::TransactionKernels(kernels)) - }, + } NodeCommsRequest::FetchMempoolTransactionsByExcessSigs { excess_sigs } => { let (transactions, not_found) = self.mempool.retrieve_by_excess_sigs(excess_sigs).await?; Ok(NodeCommsResponse::FetchMempoolTransactionsByExcessSigsResponse( @@ -419,7 +420,7 @@ where B: BlockchainBackend + 'static not_found, }, )) - }, + } NodeCommsRequest::FetchValidatorNodesKeys { height, validator_network, @@ -431,11 +432,11 @@ where B: BlockchainBackend + 'static Ok(NodeCommsResponse::FetchValidatorNodesKeysResponse( active_validator_nodes, )) - }, + } NodeCommsRequest::GetShardKey { height, public_key } => { let shard_key = self.blockchain_db.get_shard_key(height, public_key).await?; Ok(NodeCommsResponse::GetShardKeyResponse(shard_key)) - }, + } NodeCommsRequest::FetchTemplateRegistrations { start_height, end_height, @@ -447,11 +448,11 @@ where B: BlockchainBackend + 'static Ok(NodeCommsResponse::FetchTemplateRegistrationsResponse( template_registrations, )) - }, + } NodeCommsRequest::FetchUnspentUtxosInBlock { block_hash } => { let utxos = self.blockchain_db.fetch_outputs_in_block(block_hash).await?; Ok(NodeCommsResponse::TransactionOutputs(utxos)) - }, + } NodeCommsRequest::FetchValidatorNodeChanges { start_height, end_height, @@ -478,7 +479,7 @@ where B: BlockchainBackend + 'static node_changes.insert(prev_node.public_key.clone(), ValidatorNodeChange { public_key: prev_node.public_key.clone(), state: ValidatorNodeChangeState::REMOVE, - epoch: prev_node.start_epoch, // TODO: revisit + height: constants.epoch_to_block_height(prev_node.start_epoch), // TODO: revisit }); } }); @@ -492,7 +493,7 @@ where B: BlockchainBackend + 'static node_changes.insert(current_node.public_key.clone(), ValidatorNodeChange { public_key: current_node.public_key.clone(), state: ValidatorNodeChangeState::ADD, - epoch: current_node.start_epoch, + height: constants.epoch_to_block_height(current_node.start_epoch), }); } }); @@ -506,11 +507,11 @@ where B: BlockchainBackend + 'static .map(|(pub_key, change)| ValidatorNodeChange { public_key: pub_key.clone(), state: change.state.clone(), - epoch: change.epoch, + height: change.height, }) .collect(), )) - }, + } } } @@ -798,7 +799,7 @@ where B: BlockchainBackend + 'static Err(_) => { let block = self.request_full_block_from_peer(source_peer, block_hash).await?; return Ok(block); - }, + } Ok(v) => v, }; if let Err(e) = helpers::check_mmr_roots(&header, &mmr_roots) { @@ -839,14 +840,14 @@ where B: BlockchainBackend + 'static "Invalid response from peer `{}`: Peer failed to provide the block that was propagated", source_peer ))) - }, + } Err(CommsInterfaceError::UnexpectedApiResponse) => { debug!( target: LOG_TARGET, "Peer `{}` sent unexpected API response.", source_peer ); Err(CommsInterfaceError::UnexpectedApiResponse) - }, + } Err(e) => Err(e), } } @@ -921,7 +922,7 @@ where B: BlockchainBackend + 'static } } Ok(block_hash) - }, + } Err(e @ ChainStorageError::ValidationError { .. }) => { #[cfg(feature = "metrics")] @@ -940,7 +941,7 @@ where B: BlockchainBackend + 'static ); self.publish_block_event(BlockEvent::AddBlockValidationFailed { block, source_peer }); Err(e.into()) - }, + } Err(e) => { #[cfg(feature = "metrics")] @@ -948,7 +949,7 @@ where B: BlockchainBackend + 'static self.publish_block_event(BlockEvent::AddBlockErrored { block }); Err(e.into()) - }, + } } } @@ -1023,11 +1024,11 @@ where B: BlockchainBackend + 'static PowAlgorithm::Sha3x => { metrics::target_difficulty_sha() .set(i64::try_from(block.accumulated_data().target_difficulty.as_u64()).unwrap_or(i64::MAX)); - }, + } PowAlgorithm::RandomX => { metrics::target_difficulty_randomx() .set(i64::try_from(block.accumulated_data().target_difficulty.as_u64()).unwrap_or(i64::MAX)); - }, + } } } @@ -1038,7 +1039,7 @@ where B: BlockchainBackend + 'static metrics::tip_height().set(block.height() as i64); let utxo_set_size = self.blockchain_db.utxo_count().await?; metrics::utxo_set_size().set(utxo_set_size.try_into().unwrap_or(i64::MAX)); - }, + } BlockAddResult::ChainReorg { added, removed } => { if let Some(fork_height) = added.last().map(|b| b.height()) { #[allow(clippy::cast_possible_wrap)] @@ -1051,11 +1052,11 @@ where B: BlockchainBackend + 'static for block in added { update_target_difficulty(block); } - }, + } BlockAddResult::OrphanBlock => { metrics::orphaned_blocks().inc(); - }, - _ => {}, + } + _ => {} } Ok(()) } From cbb6c46882eff90952ec6d2a5ff923448fbc16d4 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Thu, 7 Nov 2024 11:12:02 +0100 Subject: [PATCH 09/23] implementation ready --- .../src/grpc/base_node_grpc_server.rs | 118 +++++++++--------- .../comms_interface/comms_response.rs | 3 +- .../comms_interface/inbound_handlers.rs | 71 ++++++----- .../core/src/chain_storage/lmdb_db/lmdb_db.rs | 16 +-- .../lmdb_db/validator_node_store.rs | 1 + 5 files changed, 98 insertions(+), 111 deletions(-) diff --git a/applications/minotari_node/src/grpc/base_node_grpc_server.rs b/applications/minotari_node/src/grpc/base_node_grpc_server.rs index 9274faf0ac..693115fb79 100644 --- a/applications/minotari_node/src/grpc/base_node_grpc_server.rs +++ b/applications/minotari_node/src/grpc/base_node_grpc_server.rs @@ -293,7 +293,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ))) .await; return; - } + }, }; if headers.is_empty() { @@ -330,7 +330,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(format!("Error fetching block at height {}", current_height)), ))); return; - } + }, }; if block.is_none() { let _network_difficulty_response = tx.send(Err(obscure_error_if_true( @@ -386,7 +386,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Error communicating with base node: {}", err,); return; - } + }, Ok(data) => data, }; for transaction in transactions.unconfirmed_pool { @@ -408,7 +408,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); } return; - } + }, }; if tx @@ -453,7 +453,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::internal(err.to_string()), )); - } + }, Ok(data) => data.best_block_height(), }; @@ -476,7 +476,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { (res, false) => res + 1, }; (from..=tip, true) - } + }, Sorting::Asc => (0..=num_headers.saturating_sub(1), false), } } else { @@ -487,11 +487,11 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { (res, false) => res + 1, }; (from..=from_height, true) - } + }, Sorting::Asc => { let to = from_height.saturating_add(num_headers).saturating_sub(1); (from_height..=to, false) - } + }, } }; let consensus_rules = self.consensus_rules.clone(); @@ -500,7 +500,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { header_range.end().saturating_add(1), LIST_HEADERS_PAGE_SIZE, ) - .map_err(|e| obscure_error_if_true(report_error_flag, Status::invalid_argument(e)))?; + .map_err(|e| obscure_error_if_true(report_error_flag, Status::invalid_argument(e)))?; task::spawn(async move { trace!( target: LOG_TARGET, @@ -519,7 +519,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Internal base node service error: {}", err); return; - } + }, Ok(data) => { if is_reversed { data.into_iter() @@ -538,7 +538,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { Err(obscure_error_if_true(report_error_flag, Status::internal(e)) .to_string()) - } + }, } }) .rev() @@ -560,18 +560,18 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { Err(obscure_error_if_true(report_error_flag, Status::internal(e)) .to_string()) - } + }, } }) .collect::, String>>() } - } + }, }; match result_data { Err(e) => { error!(target: LOG_TARGET, "No result headers transmitted due to error: {}", e) - } + }, Ok(result_data) => { let result_size = result_data.len(); trace!(target: LOG_TARGET, "Result headers: {}", result_size); @@ -592,7 +592,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { return; } } - } + }, } } }); @@ -688,7 +688,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - } + }, Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -696,13 +696,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - } + }, Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - } + }, }; let fees = new_block.body.get_total_fee().map_err(|_| { obscure_error_if_true( @@ -857,12 +857,12 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { })? - prev_coinbase_value, ) - .map_err(|_| { - obscure_error_if_true( - report_error_flag, - Status::internal("Single coinbase fees exceeded u64".to_string()), - ) - })?; + .map_err(|_| { + obscure_error_if_true( + report_error_flag, + Status::internal("Single coinbase fees exceeded u64".to_string()), + ) + })?; prev_coinbase_value += u128::from(coinbase.value); } @@ -903,8 +903,8 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { range_proof_type, PaymentId::Empty, ) - .await - .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; + .await + .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; new_template.body.add_output(coinbase_output); let new_nonce = key_manager .get_next_key(TransactionKeyManagerBranch::KernelNonce.get_branch_key()) @@ -958,7 +958,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - } + }, Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -966,13 +966,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - } + }, Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - } + }, }; let gen_hash = handler .get_header(0) @@ -1101,8 +1101,8 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { range_proof_type, PaymentId::Empty, ) - .await - .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; + .await + .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; block_template.body.add_output(coinbase_output); let new_nonce = key_manager .get_next_key(TransactionKeyManagerBranch::KernelNonce.get_branch_key()) @@ -1156,7 +1156,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - } + }, Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -1164,13 +1164,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - } + }, Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - } + }, }; let fees = new_block.body.get_total_fee().map_err(|_| { obscure_error_if_true( @@ -1261,7 +1261,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - } + }, Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -1269,13 +1269,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - } + }, Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - } + }, }; // construct response let block_hash = new_block.hash().to_vec(); @@ -1516,7 +1516,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { * should not think its mined, but the * node does not think it is. */ } - } + }, TxStorageResponse::NotStored | TxStorageResponse::NotStoredConsensus | TxStorageResponse::NotStoredOrphan | @@ -1606,7 +1606,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - } + }, Ok(data) => data.into_iter().filter(|b| heights.contains(&b.header().height)), }; @@ -1696,7 +1696,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - } + }, Ok(data) => data, }; for block in blocks { @@ -1752,7 +1752,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - } + }, Ok(data) => data, }; for block in blocks { @@ -1812,7 +1812,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(format!("Error communicating with local base node: {}", err)), ))); return; - } + }, Ok(data) => data, }; for output in outputs { @@ -1826,14 +1826,14 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); return; } - } + }, Err(err) => { let _ignore = tx.send(Err(obscure_error_if_true( report_error_flag, Status::internal(format!("Error communicating with local base node: {}", err)), ))); return; - } + }, } } }); @@ -1933,7 +1933,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { BlockGroupType::BlockSize, report_error_flag, ) - .await + .await } async fn get_block_fees( @@ -1948,7 +1948,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { BlockGroupType::BlockFees, report_error_flag, ) - .await + .await } async fn get_version(&self, _request: Request) -> Result, Status> { @@ -2315,7 +2315,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Base node service error: {}", err,); return; - } + }, Ok(data) => data, }; @@ -2381,7 +2381,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { header.map(|h| h.height()).ok_or_else(|| { obscure_error_if_true(report_error_flag, Status::not_found("Start hash not found")) })? - } + }, None => 0, }; @@ -2401,7 +2401,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Base node service error: {}", err); return; - } + }, Ok(data) => data, }; @@ -2491,7 +2491,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { warn!(target: LOG_TARGET, "Base node service error: {}", e); return; - } + }, }; let next_header = match node_service.get_header(height.saturating_add(1)).await { @@ -2502,7 +2502,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(e.to_string()), ))); return; - } + }, }; let sidechain_outputs = utxos @@ -2529,7 +2529,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); return; } - } + }, Err(e) => { warn!( target: LOG_TARGET, @@ -2542,13 +2542,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ))) .await; return; - } + }, }; match next_header { Some(header) => { current_header = header; - } + }, None => break, } } @@ -2593,7 +2593,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { comms_interface::ValidatorNodeChangeState::ADD => tari_rpc::ValidatorNodeChangeState::Add.into(), comms_interface::ValidatorNodeChangeState::REMOVE => { tari_rpc::ValidatorNodeChangeState::Remove.into() - } + }, }, start_height: node_change.height, }) @@ -2637,7 +2637,7 @@ async fn get_block_group( "Error communicating with local base node: {:?}", err, ); vec![] - } + }, Ok(data) => data, }; let extractor = match block_group_type { @@ -2653,15 +2653,15 @@ async fn get_block_group( report_error_flag, Status::unimplemented("Quantile has not been implemented"), )) - } + }, CalcType::Quartile => { return Err(obscure_error_if_true( report_error_flag, Status::unimplemented("Quartile has not been implemented"), )) - } + }, } - .unwrap_or_default(); + .unwrap_or_default(); trace!( target: LOG_TARGET, "Sending GetBlockSize response to client: {:?}", value diff --git a/base_layer/core/src/base_node/comms_interface/comms_response.rs b/base_layer/core/src/base_node/comms_interface/comms_response.rs index e963745938..9d8c7ad622 100644 --- a/base_layer/core/src/base_node/comms_interface/comms_response.rs +++ b/base_layer/core/src/base_node/comms_interface/comms_response.rs @@ -26,8 +26,7 @@ use std::{ }; use tari_common_types::{ - chain_metadata::ChainMetadata - , + chain_metadata::ChainMetadata, types::{HashOutput, PrivateKey, PublicKey}, }; diff --git a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs index ad5b685562..4cee3bdeab 100644 --- a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs +++ b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs @@ -102,8 +102,7 @@ pub struct InboundNodeCommsHandlers { } impl InboundNodeCommsHandlers -where - B: BlockchainBackend + 'static, +where B: BlockchainBackend + 'static { /// Construct a new InboundNodeCommsInterface. pub fn new( @@ -138,7 +137,7 @@ where NodeCommsRequest::FetchHeaders(range) => { let headers = self.blockchain_db.fetch_chain_headers(range).await?; Ok(NodeCommsResponse::BlockHeaders(headers)) - } + }, NodeCommsRequest::FetchHeadersByHashes(block_hashes) => { if block_hashes.len() > MAX_REQUEST_BY_BLOCK_HASHES { return Err(CommsInterfaceError::InvalidRequest { @@ -156,18 +155,18 @@ where match self.blockchain_db.fetch_chain_header_by_block_hash(block_hash).await? { Some(block_header) => { block_headers.push(block_header); - } + }, None => { error!(target: LOG_TARGET, "Could not fetch headers with hashes:{}", block_hex); return Err(CommsInterfaceError::InternalError(format!( "Could not fetch headers with hashes:{}", block_hex ))); - } + }, } } Ok(NodeCommsResponse::BlockHeaders(block_headers)) - } + }, NodeCommsRequest::FetchMatchingUtxos(utxo_hashes) => { let mut res = Vec::with_capacity(utxo_hashes.len()); for (output, spent) in (self @@ -182,11 +181,11 @@ where } } Ok(NodeCommsResponse::TransactionOutputs(res)) - } + }, NodeCommsRequest::FetchMatchingBlocks { range, compact } => { let blocks = self.blockchain_db.fetch_blocks(range, compact).await?; Ok(NodeCommsResponse::HistoricalBlocks(blocks)) - } + }, NodeCommsRequest::FetchBlocksByKernelExcessSigs(excess_sigs) => { if excess_sigs.len() > MAX_REQUEST_BY_KERNEL_EXCESS_SIGS { return Err(CommsInterfaceError::InvalidRequest { @@ -222,7 +221,7 @@ where } } Ok(NodeCommsResponse::HistoricalBlocks(blocks)) - } + }, NodeCommsRequest::FetchBlocksByUtxos(commitments) => { if commitments.len() > MAX_REQUEST_BY_UTXO_HASHES { return Err(CommsInterfaceError::InvalidRequest { @@ -257,15 +256,15 @@ where } } Ok(NodeCommsResponse::HistoricalBlocks(blocks)) - } + }, NodeCommsRequest::GetHeaderByHash(hash) => { let header = self.blockchain_db.fetch_chain_header_by_block_hash(hash).await?; Ok(NodeCommsResponse::BlockHeader(header)) - } + }, NodeCommsRequest::GetBlockByHash(hash) => { let block = self.blockchain_db.fetch_block_by_hash(hash, false).await?; Ok(NodeCommsResponse::HistoricalBlock(Box::new(block))) - } + }, NodeCommsRequest::GetNewBlockTemplate(request) => { let best_block_header = self.blockchain_db.fetch_tip_header().await?; let last_seen_hash = self.mempool.get_last_seen_hash().await?; @@ -339,7 +338,7 @@ where ); Ok(NodeCommsResponse::NewBlockTemplate(block_template)) - } + }, NodeCommsRequest::GetNewBlock(block_template) => { let height = block_template.header.height; let target_difficulty = block_template.target_difficulty; @@ -361,7 +360,7 @@ where error: None, block: Some(block), }) - } + }, NodeCommsRequest::GetBlockFromAllChains(hash) => { let block_hex = hash.to_hex(); debug!( @@ -399,7 +398,7 @@ where }; Ok(NodeCommsResponse::Block(Box::new(maybe_block))) - } + }, NodeCommsRequest::FetchKernelByExcessSig(signature) => { let kernels = match self.blockchain_db.fetch_kernel_by_excess_sig(signature).await { Ok(Some((kernel, _))) => vec![kernel], @@ -407,11 +406,11 @@ where Err(err) => { error!(target: LOG_TARGET, "Could not fetch kernel {}", err.to_string()); return Err(err.into()); - } + }, }; Ok(NodeCommsResponse::TransactionKernels(kernels)) - } + }, NodeCommsRequest::FetchMempoolTransactionsByExcessSigs { excess_sigs } => { let (transactions, not_found) = self.mempool.retrieve_by_excess_sigs(excess_sigs).await?; Ok(NodeCommsResponse::FetchMempoolTransactionsByExcessSigsResponse( @@ -420,7 +419,7 @@ where not_found, }, )) - } + }, NodeCommsRequest::FetchValidatorNodesKeys { height, validator_network, @@ -432,11 +431,11 @@ where Ok(NodeCommsResponse::FetchValidatorNodesKeysResponse( active_validator_nodes, )) - } + }, NodeCommsRequest::GetShardKey { height, public_key } => { let shard_key = self.blockchain_db.get_shard_key(height, public_key).await?; Ok(NodeCommsResponse::GetShardKeyResponse(shard_key)) - } + }, NodeCommsRequest::FetchTemplateRegistrations { start_height, end_height, @@ -448,11 +447,11 @@ where Ok(NodeCommsResponse::FetchTemplateRegistrationsResponse( template_registrations, )) - } + }, NodeCommsRequest::FetchUnspentUtxosInBlock { block_hash } => { let utxos = self.blockchain_db.fetch_outputs_in_block(block_hash).await?; Ok(NodeCommsResponse::TransactionOutputs(utxos)) - } + }, NodeCommsRequest::FetchValidatorNodeChanges { start_height, end_height, @@ -479,7 +478,7 @@ where node_changes.insert(prev_node.public_key.clone(), ValidatorNodeChange { public_key: prev_node.public_key.clone(), state: ValidatorNodeChangeState::REMOVE, - height: constants.epoch_to_block_height(prev_node.start_epoch), // TODO: revisit + height: constants.epoch_to_block_height(prev_node.start_epoch), }); } }); @@ -511,7 +510,7 @@ where }) .collect(), )) - } + }, } } @@ -799,7 +798,7 @@ where Err(_) => { let block = self.request_full_block_from_peer(source_peer, block_hash).await?; return Ok(block); - } + }, Ok(v) => v, }; if let Err(e) = helpers::check_mmr_roots(&header, &mmr_roots) { @@ -840,14 +839,14 @@ where "Invalid response from peer `{}`: Peer failed to provide the block that was propagated", source_peer ))) - } + }, Err(CommsInterfaceError::UnexpectedApiResponse) => { debug!( target: LOG_TARGET, "Peer `{}` sent unexpected API response.", source_peer ); Err(CommsInterfaceError::UnexpectedApiResponse) - } + }, Err(e) => Err(e), } } @@ -922,7 +921,7 @@ where } } Ok(block_hash) - } + }, Err(e @ ChainStorageError::ValidationError { .. }) => { #[cfg(feature = "metrics")] @@ -941,7 +940,7 @@ where ); self.publish_block_event(BlockEvent::AddBlockValidationFailed { block, source_peer }); Err(e.into()) - } + }, Err(e) => { #[cfg(feature = "metrics")] @@ -949,7 +948,7 @@ where self.publish_block_event(BlockEvent::AddBlockErrored { block }); Err(e.into()) - } + }, } } @@ -1024,11 +1023,11 @@ where PowAlgorithm::Sha3x => { metrics::target_difficulty_sha() .set(i64::try_from(block.accumulated_data().target_difficulty.as_u64()).unwrap_or(i64::MAX)); - } + }, PowAlgorithm::RandomX => { metrics::target_difficulty_randomx() .set(i64::try_from(block.accumulated_data().target_difficulty.as_u64()).unwrap_or(i64::MAX)); - } + }, } } @@ -1039,7 +1038,7 @@ where metrics::tip_height().set(block.height() as i64); let utxo_set_size = self.blockchain_db.utxo_count().await?; metrics::utxo_set_size().set(utxo_set_size.try_into().unwrap_or(i64::MAX)); - } + }, BlockAddResult::ChainReorg { added, removed } => { if let Some(fork_height) = added.last().map(|b| b.height()) { #[allow(clippy::cast_possible_wrap)] @@ -1052,11 +1051,11 @@ where for block in added { update_target_difficulty(block); } - } + }, BlockAddResult::OrphanBlock => { metrics::orphaned_blocks().inc(); - } - _ => {} + }, + _ => {}, } Ok(()) } diff --git a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs index 78eaed8a27..6d1e6d3b1d 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs @@ -1393,30 +1393,18 @@ impl LMDBDatabase { let mut next_epoch = current_epoch + VnEpoch(1); // looking for next available epoch - let current_vn_count = store.get_vn_count_until_epoch(next_epoch, vn_reg.sidechain_id().cloned())?; + let current_vn_count = store.get_vn_count_until_epoch(current_epoch, vn_reg.sidechain_id().cloned())?; let mut vn_count = store.get_vn_count_in_epoch(next_epoch, vn_reg.sidechain_id().cloned())?; - // TODO: remove, only for debugging - info!(target: LOG_TARGET, "Current VN count: {:?}, VN count for next epoch({:?}): {:?}", current_vn_count, next_epoch, vn_count); - if (current_vn_count == 0 && vn_count >= constants.vn_registration_max_vns_initial_epoch()) || (current_vn_count > 0 && vn_count >= constants.vn_registration_max_vns_per_epoch()) { - // TODO: remove, only for debugging - info!(target: LOG_TARGET, "Looking for a new epoch..."); - - while vn_count > constants.vn_registration_max_vns_per_epoch() { + while vn_count >= constants.vn_registration_max_vns_per_epoch() { next_epoch += VnEpoch(1); vn_count = store.get_vn_count_in_epoch(next_epoch, vn_reg.sidechain_id().cloned())?; - - // TODO: remove, only for debugging - info!(target: LOG_TARGET, "Next epoch({:?}) VN count: {:?}", next_epoch, vn_count); } } - // TODO: remove, only for debugging - info!(target: LOG_TARGET, "New VN start epoch: {:?}", next_epoch); - let validator_node = ValidatorNodeEntry { shard_key, start_epoch: next_epoch, diff --git a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs index e20e9db1c8..859fa056ce 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs @@ -312,6 +312,7 @@ mod tests { public_key, sidechain_id: None, shard_key, + start_epoch: Default::default(), }); } nodes.sort_by(|a, b| a.sidechain_id.cmp(&b.sidechain_id).then(a.shard_key.cmp(&b.shard_key))); From 7b695249c4606edd2b6311ed99846a6ef3c50d32 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Thu, 7 Nov 2024 12:15:26 +0100 Subject: [PATCH 10/23] final changes --- applications/minotari_node/src/grpc_method.rs | 7 ++----- .../comms_interface/inbound_handlers.rs | 8 ++----- .../core/src/chain_storage/lmdb_db/lmdb_db.rs | 7 ++++++- .../lmdb_db/validator_node_store.rs | 21 +++++++++++++++++++ .../tests/blockchain_database.rs | 2 ++ .../c_base_node_b_mining_allow_methods.toml | 1 + .../c_base_node_b_mining_deny_methods.toml | 1 + ..._base_node_b_non_mining_allow_methods.toml | 1 + 8 files changed, 36 insertions(+), 12 deletions(-) diff --git a/applications/minotari_node/src/grpc_method.rs b/applications/minotari_node/src/grpc_method.rs index 0ea257faa4..1549583767 100644 --- a/applications/minotari_node/src/grpc_method.rs +++ b/applications/minotari_node/src/grpc_method.rs @@ -63,7 +63,6 @@ pub enum GrpcMethod { GetMempoolStats, GetActiveValidatorNodes, GetValidatorNodeChanges, - GetActiveValidatorNodesMr, GetShardKey, GetTemplateRegistrations, GetSideChainUtxos, @@ -71,7 +70,7 @@ pub enum GrpcMethod { impl GrpcMethod { /// All the GRPC methods as a fixed array - pub const ALL_VARIANTS: [GrpcMethod; 38] = [ + pub const ALL_VARIANTS: [GrpcMethod; 37] = [ GrpcMethod::ListHeaders, GrpcMethod::GetHeaderByHash, GrpcMethod::GetBlocks, @@ -105,7 +104,6 @@ impl GrpcMethod { GrpcMethod::ListConnectedPeers, GrpcMethod::GetMempoolStats, GrpcMethod::GetActiveValidatorNodes, - GrpcMethod::GetActiveValidatorNodesMr, GrpcMethod::GetValidatorNodeChanges, GrpcMethod::GetShardKey, GrpcMethod::GetTemplateRegistrations, @@ -114,7 +112,7 @@ impl GrpcMethod { } impl IntoIterator for GrpcMethod { - type IntoIter = std::array::IntoIter; + type IntoIter = std::array::IntoIter; type Item = GrpcMethod; fn into_iter(self) -> Self::IntoIter { @@ -162,7 +160,6 @@ impl FromStr for GrpcMethod { "list_connected_peers" => Ok(GrpcMethod::ListConnectedPeers), "get_mempool_stats" => Ok(GrpcMethod::GetMempoolStats), "get_active_validator_nodes" => Ok(GrpcMethod::GetActiveValidatorNodes), - "get_active_validator_nodes_mr" => Ok(GrpcMethod::GetActiveValidatorNodesMr), "get_validator_node_changes" => Ok(GrpcMethod::GetValidatorNodeChanges), "get_shard_key" => Ok(GrpcMethod::GetShardKey), "get_template_registrations" => Ok(GrpcMethod::GetTemplateRegistrations), diff --git a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs index 4cee3bdeab..5adfbae867 100644 --- a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs +++ b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs @@ -31,11 +31,7 @@ use std::{ use log::*; use strum_macros::Display; -use tari_common::configuration::Network; -use tari_common_types::{ - epoch::VnEpoch, - types::{BlockHash, FixedHash, HashOutput, PublicKey}, -}; +use tari_common_types::types::{BlockHash, FixedHash, HashOutput, PublicKey}; use tari_comms::{connectivity::ConnectivityRequester, peer_manager::NodeId}; use tari_utilities::hex::Hex; use tokio::sync::RwLock; @@ -54,7 +50,7 @@ use crate::{ }, blocks::{Block, BlockBuilder, BlockHeader, BlockHeaderValidationError, ChainBlock, NewBlock, NewBlockTemplate}, chain_storage::{async_db::AsyncBlockchainDb, BlockAddResult, BlockchainBackend, ChainStorageError}, - consensus::{ConsensusConstants, ConsensusConstantsBuilder, ConsensusManager}, + consensus::{ConsensusConstants, ConsensusManager}, mempool::Mempool, proof_of_work::{ randomx_difficulty, diff --git a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs index 6d1e6d3b1d..b2edbb71f4 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs @@ -1378,6 +1378,12 @@ impl LMDBDatabase { let constants = self.get_consensus_constants(header.height); let current_epoch = constants.block_height_to_epoch(header.height); + // skip already added validator node + if store.is_vn_exists(current_epoch, vn_reg.public_key(), vn_reg.sidechain_id().cloned())? { + warn!(target: LOG_TARGET, "Validator node has been already registered: {:?}", vn_reg.public_key().to_string()); + return Ok(()); + } + let prev_shard_key = store.get_shard_key( 0, current_epoch.as_u64() * constants.epoch_length(), @@ -2491,7 +2497,6 @@ impl BlockchainBackend for LMDBDatabase { let end_epoch = constants.block_height_to_epoch(height); // Convert these back to height as validators regs are indexed by height let end_height = end_epoch.as_u64() * constants.epoch_length(); - // TODO: replace with a call without start height let nodes = vn_store.get_vn_set(0, end_height)?; Ok(nodes) } diff --git a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs index 859fa056ce..6eefaa8cb7 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs @@ -134,6 +134,27 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> Ok(cursor) } + /// Checks if the given validator node (by it's public key and side chain ID) + /// exists until a given `end_epoch`. + pub fn is_vn_exists( + &self, + end_epoch: VnEpoch, + public_key: &PublicKey, + sidechain_id: Option, + ) -> Result { + let mut cursor = self.db_read_cursor()?; + while let Ok(Some((_, vn_entry))) = cursor.next::() { + if vn_entry.public_key == *public_key && + vn_entry.sidechain_id == sidechain_id && + vn_entry.start_epoch <= end_epoch + { + return Ok(true); + } + } + + Ok(false) + } + /// Returns validator nodes until a given epoch. pub fn get_vn_count_until_epoch( &self, diff --git a/base_layer/core/src/chain_storage/tests/blockchain_database.rs b/base_layer/core/src/chain_storage/tests/blockchain_database.rs index 0da962b5ae..19fc66ab42 100644 --- a/base_layer/core/src/chain_storage/tests/blockchain_database.rs +++ b/base_layer/core/src/chain_storage/tests/blockchain_database.rs @@ -658,6 +658,7 @@ mod validator_node_merkle_root { public_key, sidechain_id: None, shard_key, + start_epoch: Default::default(), }]) .unwrap(); @@ -715,6 +716,7 @@ mod validator_node_merkle_root { public_key, sidechain_id: Some(sidechain_public), shard_key, + start_epoch: Default::default(), }]) .unwrap(); diff --git a/common/config/presets/c_base_node_b_mining_allow_methods.toml b/common/config/presets/c_base_node_b_mining_allow_methods.toml index feb7593392..542a7e22eb 100644 --- a/common/config/presets/c_base_node_b_mining_allow_methods.toml +++ b/common/config/presets/c_base_node_b_mining_allow_methods.toml @@ -48,6 +48,7 @@ grpc_server_allow_methods = [ "list_connected_peers", "get_mempool_stats", "get_active_validator_nodes", + "get_validator_node_changes", "get_shard_key", "get_template_registrations", "get_side_chain_utxos", diff --git a/common/config/presets/c_base_node_b_mining_deny_methods.toml b/common/config/presets/c_base_node_b_mining_deny_methods.toml index f84606b787..e467e8674d 100644 --- a/common/config/presets/c_base_node_b_mining_deny_methods.toml +++ b/common/config/presets/c_base_node_b_mining_deny_methods.toml @@ -33,6 +33,7 @@ grpc_server_allow_methods = [ "list_connected_peers", "get_mempool_stats", "get_active_validator_nodes", + "get_validator_node_changes", "get_shard_key", "get_template_registrations", "get_side_chain_utxos", diff --git a/common/config/presets/c_base_node_b_non_mining_allow_methods.toml b/common/config/presets/c_base_node_b_non_mining_allow_methods.toml index 455fe46769..e8e489191e 100644 --- a/common/config/presets/c_base_node_b_non_mining_allow_methods.toml +++ b/common/config/presets/c_base_node_b_non_mining_allow_methods.toml @@ -48,6 +48,7 @@ grpc_server_allow_methods = [ #"list_connected_peers", #"get_mempool_stats", #"get_active_validator_nodes", + #"get_validator_node_changes", #"get_shard_key", #"get_template_registrations", #"get_side_chain_utxos", From 31cc467a2a72e917e6decc70373f7a83f593e37d Mon Sep 17 00:00:00 2001 From: ksrichard Date: Thu, 7 Nov 2024 14:55:07 +0100 Subject: [PATCH 11/23] added full registration details to stored validator nodes --- .../minotari_app_grpc/proto/base_node.proto | 1 + .../minotari_app_grpc/src/conversions/mod.rs | 1 + .../src/conversions/validator_node_change.rs | 39 +++++++++++++++++++ .../src/grpc/base_node_grpc_server.rs | 20 +--------- .../comms_interface/comms_response.rs | 8 +++- .../comms_interface/inbound_handlers.rs | 3 ++ .../chain_storage/active_validator_node.rs | 3 ++ .../core/src/chain_storage/lmdb_db/lmdb_db.rs | 1 + .../lmdb_db/validator_node_store.rs | 2 + base_layer/core/src/chain_storage/mod.rs | 3 ++ .../side_chain/validator_node_registration.rs | 2 +- .../side_chain/validator_node_signature.rs | 2 +- 12 files changed, 64 insertions(+), 21 deletions(-) create mode 100644 applications/minotari_app_grpc/src/conversions/validator_node_change.rs diff --git a/applications/minotari_app_grpc/proto/base_node.proto b/applications/minotari_app_grpc/proto/base_node.proto index ae39495981..1f5a916d35 100644 --- a/applications/minotari_app_grpc/proto/base_node.proto +++ b/applications/minotari_app_grpc/proto/base_node.proto @@ -502,6 +502,7 @@ message ValidatorNodeChange { bytes public_key = 1; ValidatorNodeChangeState state = 2; uint64 start_height = 3; + ValidatorNodeRegistration registration = 4; } message GetValidatorNodeChangesResponse { diff --git a/applications/minotari_app_grpc/src/conversions/mod.rs b/applications/minotari_app_grpc/src/conversions/mod.rs index 799d2262a6..0ac7b649af 100644 --- a/applications/minotari_app_grpc/src/conversions/mod.rs +++ b/applications/minotari_app_grpc/src/conversions/mod.rs @@ -40,6 +40,7 @@ pub mod transaction_input; pub mod transaction_kernel; pub mod transaction_output; pub mod unblinded_output; +pub mod validator_node_change; use prost_types::Timestamp; diff --git a/applications/minotari_app_grpc/src/conversions/validator_node_change.rs b/applications/minotari_app_grpc/src/conversions/validator_node_change.rs new file mode 100644 index 0000000000..3084705028 --- /dev/null +++ b/applications/minotari_app_grpc/src/conversions/validator_node_change.rs @@ -0,0 +1,39 @@ +// Copyright 2024 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use tari_core::base_node::comms_interface::{ValidatorNodeChange, ValidatorNodeChangeState}; +use tari_utilities::ByteArray; + +impl From<&ValidatorNodeChange> for crate::tari_rpc::ValidatorNodeChange { + fn from(node_change: &ValidatorNodeChange) -> Self { + crate::tari_rpc::ValidatorNodeChange { + public_key: node_change.public_key.to_vec(), + state: match node_change.state { + ValidatorNodeChangeState::ADD => crate::tari_rpc::ValidatorNodeChangeState::Add.into(), + ValidatorNodeChangeState::REMOVE => crate::tari_rpc::ValidatorNodeChangeState::Remove.into(), + }, + start_height: node_change.height, + registration: match &node_change.registration { + Some(value) => Some(crate::tari_rpc::ValidatorNodeRegistration { + public_key: value.public_key().to_vec(), + signature: Some(crate::tari_rpc::Signature { + public_nonce: value.signature().get_public_nonce().to_vec(), + signature: value.signature().get_signature().to_vec(), + }), + claim_public_key: value.claim_public_key().to_vec(), + sidechain_id: match value.sidechain_id() { + None => vec![], + Some(id) => id.to_vec(), + }, + sidechain_id_knowledge_proof: value.sidechain_id_knowledge_proof().map(|signature| { + crate::tari_rpc::Signature { + public_nonce: signature.get_public_nonce().to_vec(), + signature: signature.get_signature().to_vec(), + } + }), + }), + None => None, + }, + } + } +} diff --git a/applications/minotari_node/src/grpc/base_node_grpc_server.rs b/applications/minotari_node/src/grpc/base_node_grpc_server.rs index 693115fb79..b010eadc47 100644 --- a/applications/minotari_node/src/grpc/base_node_grpc_server.rs +++ b/applications/minotari_node/src/grpc/base_node_grpc_server.rs @@ -32,13 +32,7 @@ use futures::{channel::mpsc, SinkExt}; use log::*; use minotari_app_grpc::{ tari_rpc, - tari_rpc::{ - CalcType, - GetValidatorNodeChangesRequest, - GetValidatorNodeChangesResponse, - Sorting, - ValidatorNodeChange, - }, + tari_rpc::{CalcType, GetValidatorNodeChangesRequest, GetValidatorNodeChangesResponse, Sorting}, }; use tari_common_types::{ key_branches::TransactionKeyManagerBranch, @@ -48,7 +42,6 @@ use tari_common_types::{ use tari_comms::{Bytes, CommsNode}; use tari_core::{ base_node::{ - comms_interface, comms_interface::CommsInterfaceError, state_machine_service::states::StateInfo, LocalNodeCommsInterface, @@ -2587,16 +2580,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal("Internal error!") })? .iter() - .map(|node_change| ValidatorNodeChange { - public_key: node_change.public_key.to_vec(), - state: match node_change.state { - comms_interface::ValidatorNodeChangeState::ADD => tari_rpc::ValidatorNodeChangeState::Add.into(), - comms_interface::ValidatorNodeChangeState::REMOVE => { - tari_rpc::ValidatorNodeChangeState::Remove.into() - }, - }, - start_height: node_change.height, - }) + .map(|node_change| node_change.into()) .collect(); Ok(Response::new(GetValidatorNodeChangesResponse { changes })) diff --git a/base_layer/core/src/base_node/comms_interface/comms_response.rs b/base_layer/core/src/base_node/comms_interface/comms_response.rs index 9d8c7ad622..1f63d0af24 100644 --- a/base_layer/core/src/base_node/comms_interface/comms_response.rs +++ b/base_layer/core/src/base_node/comms_interface/comms_response.rs @@ -34,7 +34,12 @@ use crate::{ blocks::{Block, ChainHeader, HistoricalBlock, NewBlockTemplate}, chain_storage::{TemplateRegistrationEntry, ValidatorNodeRegistrationInfo}, proof_of_work::Difficulty, - transactions::transaction_components::{Transaction, TransactionKernel, TransactionOutput}, + transactions::transaction_components::{ + Transaction, + TransactionKernel, + TransactionOutput, + ValidatorNodeRegistration, + }, }; /// API Response enum @@ -123,5 +128,6 @@ pub enum ValidatorNodeChangeState { pub struct ValidatorNodeChange { pub public_key: PublicKey, pub state: ValidatorNodeChangeState, + pub registration: Option, pub height: u64, } diff --git a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs index 5adfbae867..9a5c852bbb 100644 --- a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs +++ b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs @@ -474,6 +474,7 @@ where B: BlockchainBackend + 'static node_changes.insert(prev_node.public_key.clone(), ValidatorNodeChange { public_key: prev_node.public_key.clone(), state: ValidatorNodeChangeState::REMOVE, + registration: None, height: constants.epoch_to_block_height(prev_node.start_epoch), }); } @@ -488,6 +489,7 @@ where B: BlockchainBackend + 'static node_changes.insert(current_node.public_key.clone(), ValidatorNodeChange { public_key: current_node.public_key.clone(), state: ValidatorNodeChangeState::ADD, + registration: Some(current_node.original_registration.clone()), height: constants.epoch_to_block_height(current_node.start_epoch), }); } @@ -502,6 +504,7 @@ where B: BlockchainBackend + 'static .map(|(pub_key, change)| ValidatorNodeChange { public_key: pub_key.clone(), state: change.state.clone(), + registration: change.registration.clone(), height: change.height, }) .collect(), diff --git a/base_layer/core/src/chain_storage/active_validator_node.rs b/base_layer/core/src/chain_storage/active_validator_node.rs index 688a0719c6..7ee46b6a7b 100644 --- a/base_layer/core/src/chain_storage/active_validator_node.rs +++ b/base_layer/core/src/chain_storage/active_validator_node.rs @@ -26,6 +26,8 @@ use tari_common_types::{ types::{Commitment, PublicKey}, }; +use crate::transactions::transaction_components::ValidatorNodeRegistration; + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)] pub struct ValidatorNodeEntry { pub shard_key: [u8; 32], @@ -33,4 +35,5 @@ pub struct ValidatorNodeEntry { pub public_key: PublicKey, pub commitment: Commitment, pub sidechain_id: Option, + pub registration: ValidatorNodeRegistration, } diff --git a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs index b2edbb71f4..78eb70f542 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs @@ -1417,6 +1417,7 @@ impl LMDBDatabase { public_key: vn_reg.public_key().clone(), commitment: commitment.clone(), sidechain_id: vn_reg.sidechain_id().cloned(), + registration: vn_reg.clone(), }; store.insert(header.height, &validator_node)?; diff --git a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs index 6eefaa8cb7..3bcc3052da 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs @@ -214,6 +214,7 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> sidechain_id: vn.sidechain_id, shard_key: vn.shard_key, start_epoch: vn.start_epoch, + original_registration: vn.registration.clone(), })); }, None => return Ok(Vec::new()), @@ -238,6 +239,7 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> sidechain_id: vn.sidechain_id, shard_key: vn.shard_key, start_epoch: vn.start_epoch, + original_registration: vn.registration, })); i += 1; } diff --git a/base_layer/core/src/chain_storage/mod.rs b/base_layer/core/src/chain_storage/mod.rs index 96c5b845ce..9d9533129f 100644 --- a/base_layer/core/src/chain_storage/mod.rs +++ b/base_layer/core/src/chain_storage/mod.rs @@ -91,6 +91,8 @@ use tari_common_types::{ mod template_registation; pub use template_registation::TemplateRegistrationEntry; +use crate::transactions::transaction_components::ValidatorNodeRegistration; + #[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq, Eq)] pub struct ChainTipData { pub hash: HashOutput, @@ -103,4 +105,5 @@ pub struct ValidatorNodeRegistrationInfo { pub sidechain_id: Option, pub shard_key: [u8; 32], pub start_epoch: VnEpoch, + pub original_registration: ValidatorNodeRegistration, } diff --git a/base_layer/core/src/transactions/transaction_components/side_chain/validator_node_registration.rs b/base_layer/core/src/transactions/transaction_components/side_chain/validator_node_registration.rs index 540b294f4b..d6eb49722f 100644 --- a/base_layer/core/src/transactions/transaction_components/side_chain/validator_node_registration.rs +++ b/base_layer/core/src/transactions/transaction_components/side_chain/validator_node_registration.rs @@ -34,7 +34,7 @@ use tari_utilities::ByteArray; use crate::{consensus::DomainSeparatedConsensusHasher, transactions::transaction_components::ValidatorNodeSignature}; -#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize, BorshSerialize, BorshDeserialize)] +#[derive(Default, Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize, BorshSerialize, BorshDeserialize)] pub struct ValidatorNodeRegistration { signature: ValidatorNodeSignature, claim_public_key: PublicKey, diff --git a/base_layer/core/src/transactions/transaction_components/side_chain/validator_node_signature.rs b/base_layer/core/src/transactions/transaction_components/side_chain/validator_node_signature.rs index 49e28fe755..a9ba9cd48c 100644 --- a/base_layer/core/src/transactions/transaction_components/side_chain/validator_node_signature.rs +++ b/base_layer/core/src/transactions/transaction_components/side_chain/validator_node_signature.rs @@ -35,7 +35,7 @@ hash_domain!( 0 ); -#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize, BorshSerialize, BorshDeserialize)] +#[derive(Default, Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize, BorshSerialize, BorshDeserialize)] pub struct ValidatorNodeSignature { public_key: PublicKey, signature: Signature, From 4cac3ab60d28ae8e16602ea90243144523580822 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Fri, 8 Nov 2024 09:40:43 +0100 Subject: [PATCH 12/23] added minimum value promise --- applications/minotari_app_grpc/proto/base_node.proto | 1 + .../src/conversions/validator_node_change.rs | 1 + .../core/src/base_node/comms_interface/comms_response.rs | 9 ++++----- .../src/base_node/comms_interface/inbound_handlers.rs | 3 +++ .../core/src/chain_storage/active_validator_node.rs | 3 ++- base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs | 6 +++++- .../src/chain_storage/lmdb_db/validator_node_store.rs | 2 ++ base_layer/core/src/chain_storage/mod.rs | 3 ++- 8 files changed, 20 insertions(+), 8 deletions(-) diff --git a/applications/minotari_app_grpc/proto/base_node.proto b/applications/minotari_app_grpc/proto/base_node.proto index 1f5a916d35..07b2220391 100644 --- a/applications/minotari_app_grpc/proto/base_node.proto +++ b/applications/minotari_app_grpc/proto/base_node.proto @@ -503,6 +503,7 @@ message ValidatorNodeChange { ValidatorNodeChangeState state = 2; uint64 start_height = 3; ValidatorNodeRegistration registration = 4; + uint64 minimum_value_promise = 5; } message GetValidatorNodeChangesResponse { diff --git a/applications/minotari_app_grpc/src/conversions/validator_node_change.rs b/applications/minotari_app_grpc/src/conversions/validator_node_change.rs index 3084705028..51ded6b04b 100644 --- a/applications/minotari_app_grpc/src/conversions/validator_node_change.rs +++ b/applications/minotari_app_grpc/src/conversions/validator_node_change.rs @@ -34,6 +34,7 @@ impl From<&ValidatorNodeChange> for crate::tari_rpc::ValidatorNodeChange { }), None => None, }, + minimum_value_promise: node_change.minimum_value_promise.into(), } } } diff --git a/base_layer/core/src/base_node/comms_interface/comms_response.rs b/base_layer/core/src/base_node/comms_interface/comms_response.rs index 1f63d0af24..7782b0631d 100644 --- a/base_layer/core/src/base_node/comms_interface/comms_response.rs +++ b/base_layer/core/src/base_node/comms_interface/comms_response.rs @@ -34,11 +34,9 @@ use crate::{ blocks::{Block, ChainHeader, HistoricalBlock, NewBlockTemplate}, chain_storage::{TemplateRegistrationEntry, ValidatorNodeRegistrationInfo}, proof_of_work::Difficulty, - transactions::transaction_components::{ - Transaction, - TransactionKernel, - TransactionOutput, - ValidatorNodeRegistration, + transactions::{ + tari_amount::MicroMinotari, + transaction_components::{Transaction, TransactionKernel, TransactionOutput, ValidatorNodeRegistration}, }, }; @@ -129,5 +127,6 @@ pub struct ValidatorNodeChange { pub public_key: PublicKey, pub state: ValidatorNodeChangeState, pub registration: Option, + pub minimum_value_promise: MicroMinotari, pub height: u64, } diff --git a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs index 9a5c852bbb..7a63e49e1f 100644 --- a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs +++ b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs @@ -475,6 +475,7 @@ where B: BlockchainBackend + 'static public_key: prev_node.public_key.clone(), state: ValidatorNodeChangeState::REMOVE, registration: None, + minimum_value_promise: prev_node.minimum_value_promise, height: constants.epoch_to_block_height(prev_node.start_epoch), }); } @@ -490,6 +491,7 @@ where B: BlockchainBackend + 'static public_key: current_node.public_key.clone(), state: ValidatorNodeChangeState::ADD, registration: Some(current_node.original_registration.clone()), + minimum_value_promise: current_node.minimum_value_promise, height: constants.epoch_to_block_height(current_node.start_epoch), }); } @@ -505,6 +507,7 @@ where B: BlockchainBackend + 'static public_key: pub_key.clone(), state: change.state.clone(), registration: change.registration.clone(), + minimum_value_promise: change.minimum_value_promise, height: change.height, }) .collect(), diff --git a/base_layer/core/src/chain_storage/active_validator_node.rs b/base_layer/core/src/chain_storage/active_validator_node.rs index 7ee46b6a7b..184d58a18a 100644 --- a/base_layer/core/src/chain_storage/active_validator_node.rs +++ b/base_layer/core/src/chain_storage/active_validator_node.rs @@ -26,7 +26,7 @@ use tari_common_types::{ types::{Commitment, PublicKey}, }; -use crate::transactions::transaction_components::ValidatorNodeRegistration; +use crate::transactions::{tari_amount::MicroMinotari, transaction_components::ValidatorNodeRegistration}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)] pub struct ValidatorNodeEntry { @@ -36,4 +36,5 @@ pub struct ValidatorNodeEntry { pub commitment: Commitment, pub sidechain_id: Option, pub registration: ValidatorNodeRegistration, + pub minimum_value_promise: MicroMinotari, } diff --git a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs index 78eb70f542..a51e9f203c 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/lmdb_db.rs @@ -108,6 +108,7 @@ use crate::{ output_mr_hash_from_smt, transactions::{ aggregated_body::AggregateBody, + tari_amount::MicroMinotari, transaction_components::{ OutputType, SpentOutput, @@ -1288,8 +1289,9 @@ impl LMDBDatabase { .as_ref() .and_then(|f| f.validator_node_registration()) { - self.insert_validator_node(txn, header, &output.commitment, vn_reg)?; + self.insert_validator_node(txn, header, &output.commitment, output.minimum_value_promise, vn_reg)?; } + if let Some(template_reg) = output .features .sidechain_feature @@ -1372,6 +1374,7 @@ impl LMDBDatabase { txn: &WriteTransaction<'_>, header: &BlockHeader, commitment: &Commitment, + minimum_value_promise: MicroMinotari, vn_reg: &ValidatorNodeRegistration, ) -> Result<(), ChainStorageError> { let store = self.validator_node_store(txn); @@ -1418,6 +1421,7 @@ impl LMDBDatabase { commitment: commitment.clone(), sidechain_id: vn_reg.sidechain_id().cloned(), registration: vn_reg.clone(), + minimum_value_promise, }; store.insert(header.height, &validator_node)?; diff --git a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs index 3bcc3052da..eac50852b9 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs @@ -215,6 +215,7 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> shard_key: vn.shard_key, start_epoch: vn.start_epoch, original_registration: vn.registration.clone(), + minimum_value_promise: vn.minimum_value_promise, })); }, None => return Ok(Vec::new()), @@ -240,6 +241,7 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> shard_key: vn.shard_key, start_epoch: vn.start_epoch, original_registration: vn.registration, + minimum_value_promise: vn.minimum_value_promise, })); i += 1; } diff --git a/base_layer/core/src/chain_storage/mod.rs b/base_layer/core/src/chain_storage/mod.rs index 9d9533129f..27020e3633 100644 --- a/base_layer/core/src/chain_storage/mod.rs +++ b/base_layer/core/src/chain_storage/mod.rs @@ -91,7 +91,7 @@ use tari_common_types::{ mod template_registation; pub use template_registation::TemplateRegistrationEntry; -use crate::transactions::transaction_components::ValidatorNodeRegistration; +use crate::transactions::{tari_amount::MicroMinotari, transaction_components::ValidatorNodeRegistration}; #[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq, Eq)] pub struct ChainTipData { @@ -106,4 +106,5 @@ pub struct ValidatorNodeRegistrationInfo { pub shard_key: [u8; 32], pub start_epoch: VnEpoch, pub original_registration: ValidatorNodeRegistration, + pub minimum_value_promise: MicroMinotari, } From 1dc36baab41b3e12f67583fadcc6b7781123d1b0 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Fri, 8 Nov 2024 10:45:24 +0100 Subject: [PATCH 13/23] added grpc conversions --- .../src/conversions/error.rs | 12 ++++ .../minotari_app_grpc/src/conversions/mod.rs | 2 + .../src/conversions/validator_node_change.rs | 21 +----- .../validator_node_registration.rs | 67 +++++++++++++++++++ 4 files changed, 83 insertions(+), 19 deletions(-) create mode 100644 applications/minotari_app_grpc/src/conversions/error.rs create mode 100644 applications/minotari_app_grpc/src/conversions/validator_node_registration.rs diff --git a/applications/minotari_app_grpc/src/conversions/error.rs b/applications/minotari_app_grpc/src/conversions/error.rs new file mode 100644 index 0000000000..8219231c6f --- /dev/null +++ b/applications/minotari_app_grpc/src/conversions/error.rs @@ -0,0 +1,12 @@ +use tari_utilities::ByteArrayError; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ConversionError { + #[error("Missing field: {0}")] + MissingField(&'static str), + #[error("Public key conversion error: {0}")] + PublicKey(#[from] ByteArrayError), + #[error("Secret key conversion error: {0}")] + SecretKey(#[from] ByteArrayError), +} diff --git a/applications/minotari_app_grpc/src/conversions/mod.rs b/applications/minotari_app_grpc/src/conversions/mod.rs index 0ac7b649af..a0c24c2191 100644 --- a/applications/minotari_app_grpc/src/conversions/mod.rs +++ b/applications/minotari_app_grpc/src/conversions/mod.rs @@ -28,6 +28,7 @@ pub mod chain_metadata; pub mod com_and_pub_signature; pub mod commitment_signature; pub mod consensus_constants; +pub mod error; pub mod historical_block; pub mod new_block_template; pub mod output_features; @@ -41,6 +42,7 @@ pub mod transaction_kernel; pub mod transaction_output; pub mod unblinded_output; pub mod validator_node_change; +pub mod validator_node_registration; use prost_types::Timestamp; diff --git a/applications/minotari_app_grpc/src/conversions/validator_node_change.rs b/applications/minotari_app_grpc/src/conversions/validator_node_change.rs index 51ded6b04b..69f113620b 100644 --- a/applications/minotari_app_grpc/src/conversions/validator_node_change.rs +++ b/applications/minotari_app_grpc/src/conversions/validator_node_change.rs @@ -6,7 +6,7 @@ use tari_utilities::ByteArray; impl From<&ValidatorNodeChange> for crate::tari_rpc::ValidatorNodeChange { fn from(node_change: &ValidatorNodeChange) -> Self { - crate::tari_rpc::ValidatorNodeChange { + Self { public_key: node_change.public_key.to_vec(), state: match node_change.state { ValidatorNodeChangeState::ADD => crate::tari_rpc::ValidatorNodeChangeState::Add.into(), @@ -14,24 +14,7 @@ impl From<&ValidatorNodeChange> for crate::tari_rpc::ValidatorNodeChange { }, start_height: node_change.height, registration: match &node_change.registration { - Some(value) => Some(crate::tari_rpc::ValidatorNodeRegistration { - public_key: value.public_key().to_vec(), - signature: Some(crate::tari_rpc::Signature { - public_nonce: value.signature().get_public_nonce().to_vec(), - signature: value.signature().get_signature().to_vec(), - }), - claim_public_key: value.claim_public_key().to_vec(), - sidechain_id: match value.sidechain_id() { - None => vec![], - Some(id) => id.to_vec(), - }, - sidechain_id_knowledge_proof: value.sidechain_id_knowledge_proof().map(|signature| { - crate::tari_rpc::Signature { - public_nonce: signature.get_public_nonce().to_vec(), - signature: signature.get_signature().to_vec(), - } - }), - }), + Some(registration) => Some(registration.into()), None => None, }, minimum_value_promise: node_change.minimum_value_promise.into(), diff --git a/applications/minotari_app_grpc/src/conversions/validator_node_registration.rs b/applications/minotari_app_grpc/src/conversions/validator_node_registration.rs new file mode 100644 index 0000000000..d65251caff --- /dev/null +++ b/applications/minotari_app_grpc/src/conversions/validator_node_registration.rs @@ -0,0 +1,67 @@ +use tari_common_types::types::{PublicKey, Signature}; +use tari_core::transactions::transaction_components::{ValidatorNodeRegistration, ValidatorNodeSignature}; +use tari_crypto::ristretto::RistrettoSecretKey; +use tari_utilities::ByteArray; + +use crate::conversions::error::ConversionError; + +impl From<&ValidatorNodeRegistration> for crate::tari_rpc::ValidatorNodeRegistration { + fn from(registration: &ValidatorNodeRegistration) -> Self { + Self { + public_key: registration.public_key().to_vec(), + signature: Some(crate::tari_rpc::Signature { + public_nonce: registration.signature().get_public_nonce().to_vec(), + signature: registration.signature().get_signature().to_vec(), + }), + claim_public_key: registration.claim_public_key().to_vec(), + sidechain_id: match registration.sidechain_id() { + None => vec![], + Some(id) => id.to_vec(), + }, + sidechain_id_knowledge_proof: registration.sidechain_id_knowledge_proof().map(|signature| { + crate::tari_rpc::Signature { + public_nonce: signature.get_public_nonce().to_vec(), + signature: signature.get_signature().to_vec(), + } + }), + } + } +} + +impl TryFrom for Signature { + type Error = ConversionError; + + fn try_from(sig: crate::tari_rpc::Signature) -> Result { + Ok(Self::new( + PublicKey::from_canonical_bytes(sig.public_nonce.as_slice()).map_err(ConversionError::PublicKey)?, + RistrettoSecretKey::from_canonical_bytes(sig.signature.as_slice()).map_err(ConversionError::SecretKey)?, + )) + } +} + +impl TryFrom for ValidatorNodeRegistration { + type Error = ConversionError; + + fn try_from(reg: crate::tari_rpc::ValidatorNodeRegistration) -> Result { + let reg_signature = reg.signature.ok_or(ConversionError::MissingField("signature"))?; + let signature = ValidatorNodeSignature::new( + PublicKey::from_canonical_bytes(reg_signature.public_nonce.as_slice()) + .map_err(ConversionError::PublicKey)?, + reg_signature.try_into()?, + ); + let sidechain_id = if reg.sidechain_id.is_empty() { + None + } else { + Some(PublicKey::from_canonical_bytes(reg.sidechain_id.as_slice()).map_err(ConversionError::PublicKey)?) + }; + Ok(Self::new( + signature, + PublicKey::from_canonical_bytes(reg.claim_public_key.as_slice()).map_err(ConversionError::PublicKey)?, + sidechain_id, + match reg.sidechain_id_knowledge_proof { + None => None, + Some(signature) => signature.try_into()?, + }, + )) + } +} From c7608468361239262018b3209fa363cee9559119 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Fri, 8 Nov 2024 10:56:13 +0100 Subject: [PATCH 14/23] revert changes --- .../src/conversions/error.rs | 12 ----- .../validator_node_registration.rs | 44 +------------------ .../core/src/consensus/consensus_constants.rs | 24 +++++----- 3 files changed, 13 insertions(+), 67 deletions(-) delete mode 100644 applications/minotari_app_grpc/src/conversions/error.rs diff --git a/applications/minotari_app_grpc/src/conversions/error.rs b/applications/minotari_app_grpc/src/conversions/error.rs deleted file mode 100644 index 8219231c6f..0000000000 --- a/applications/minotari_app_grpc/src/conversions/error.rs +++ /dev/null @@ -1,12 +0,0 @@ -use tari_utilities::ByteArrayError; -use thiserror::Error; - -#[derive(Error, Debug)] -pub enum ConversionError { - #[error("Missing field: {0}")] - MissingField(&'static str), - #[error("Public key conversion error: {0}")] - PublicKey(#[from] ByteArrayError), - #[error("Secret key conversion error: {0}")] - SecretKey(#[from] ByteArrayError), -} diff --git a/applications/minotari_app_grpc/src/conversions/validator_node_registration.rs b/applications/minotari_app_grpc/src/conversions/validator_node_registration.rs index d65251caff..ac32b3aca6 100644 --- a/applications/minotari_app_grpc/src/conversions/validator_node_registration.rs +++ b/applications/minotari_app_grpc/src/conversions/validator_node_registration.rs @@ -1,10 +1,6 @@ -use tari_common_types::types::{PublicKey, Signature}; -use tari_core::transactions::transaction_components::{ValidatorNodeRegistration, ValidatorNodeSignature}; -use tari_crypto::ristretto::RistrettoSecretKey; +use tari_core::transactions::transaction_components::ValidatorNodeRegistration; use tari_utilities::ByteArray; -use crate::conversions::error::ConversionError; - impl From<&ValidatorNodeRegistration> for crate::tari_rpc::ValidatorNodeRegistration { fn from(registration: &ValidatorNodeRegistration) -> Self { Self { @@ -27,41 +23,3 @@ impl From<&ValidatorNodeRegistration> for crate::tari_rpc::ValidatorNodeRegistra } } } - -impl TryFrom for Signature { - type Error = ConversionError; - - fn try_from(sig: crate::tari_rpc::Signature) -> Result { - Ok(Self::new( - PublicKey::from_canonical_bytes(sig.public_nonce.as_slice()).map_err(ConversionError::PublicKey)?, - RistrettoSecretKey::from_canonical_bytes(sig.signature.as_slice()).map_err(ConversionError::SecretKey)?, - )) - } -} - -impl TryFrom for ValidatorNodeRegistration { - type Error = ConversionError; - - fn try_from(reg: crate::tari_rpc::ValidatorNodeRegistration) -> Result { - let reg_signature = reg.signature.ok_or(ConversionError::MissingField("signature"))?; - let signature = ValidatorNodeSignature::new( - PublicKey::from_canonical_bytes(reg_signature.public_nonce.as_slice()) - .map_err(ConversionError::PublicKey)?, - reg_signature.try_into()?, - ); - let sidechain_id = if reg.sidechain_id.is_empty() { - None - } else { - Some(PublicKey::from_canonical_bytes(reg.sidechain_id.as_slice()).map_err(ConversionError::PublicKey)?) - }; - Ok(Self::new( - signature, - PublicKey::from_canonical_bytes(reg.claim_public_key.as_slice()).map_err(ConversionError::PublicKey)?, - sidechain_id, - match reg.sidechain_id_knowledge_proof { - None => None, - Some(signature) => signature.try_into()?, - }, - )) - } -} diff --git a/base_layer/core/src/consensus/consensus_constants.rs b/base_layer/core/src/consensus/consensus_constants.rs index baad3bf93e..50ab777c88 100644 --- a/base_layer/core/src/consensus/consensus_constants.rs +++ b/base_layer/core/src/consensus/consensus_constants.rs @@ -424,8 +424,8 @@ impl ConsensusConstants { vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, - vn_registration_max_vns_initial_epoch: 50, - vn_registration_max_vns_per_epoch: 10, + vn_registration_max_vns_initial_epoch: 5, + vn_registration_max_vns_per_epoch: 2, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[120], &[50], &[50]); @@ -491,8 +491,8 @@ impl ConsensusConstants { vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, - vn_registration_max_vns_initial_epoch: 50, - vn_registration_max_vns_per_epoch: 10, + vn_registration_max_vns_initial_epoch: 5, + vn_registration_max_vns_per_epoch: 2, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[target_time], &[randomx_split], &[sha3x_split]); @@ -549,8 +549,8 @@ impl ConsensusConstants { vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, - vn_registration_max_vns_initial_epoch: 50, - vn_registration_max_vns_per_epoch: 10, + vn_registration_max_vns_initial_epoch: 5, + vn_registration_max_vns_per_epoch: 2, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[120], &[50], &[50]); @@ -607,8 +607,8 @@ impl ConsensusConstants { vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, - vn_registration_max_vns_initial_epoch: 50, - vn_registration_max_vns_per_epoch: 10, + vn_registration_max_vns_initial_epoch: 5, + vn_registration_max_vns_per_epoch: 2, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[120], &[50], &[50]); @@ -659,8 +659,8 @@ impl ConsensusConstants { vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, - vn_registration_max_vns_initial_epoch: 50, - vn_registration_max_vns_per_epoch: 10, + vn_registration_max_vns_initial_epoch: 5, + vn_registration_max_vns_per_epoch: 2, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[120], &[50], &[50]); @@ -713,8 +713,8 @@ impl ConsensusConstants { vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, - vn_registration_max_vns_initial_epoch: 50, - vn_registration_max_vns_per_epoch: 10, + vn_registration_max_vns_initial_epoch: 5, + vn_registration_max_vns_per_epoch: 2, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[120], &[50], &[50]); From 1aaa08f08e232615df55057d98edc9018c6777f4 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Fri, 8 Nov 2024 11:04:01 +0100 Subject: [PATCH 15/23] format --- applications/minotari_app_grpc/src/conversions/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/applications/minotari_app_grpc/src/conversions/mod.rs b/applications/minotari_app_grpc/src/conversions/mod.rs index a0c24c2191..7748035be5 100644 --- a/applications/minotari_app_grpc/src/conversions/mod.rs +++ b/applications/minotari_app_grpc/src/conversions/mod.rs @@ -28,7 +28,6 @@ pub mod chain_metadata; pub mod com_and_pub_signature; pub mod commitment_signature; pub mod consensus_constants; -pub mod error; pub mod historical_block; pub mod new_block_template; pub mod output_features; From 95bfc233da7fad059d66cb98ec3baf3925473d14 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Fri, 8 Nov 2024 11:21:25 +0100 Subject: [PATCH 16/23] fixed tests --- .../core/src/chain_storage/lmdb_db/validator_node_store.rs | 2 ++ .../core/src/chain_storage/tests/blockchain_database.rs | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs index eac50852b9..44d018bab3 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs @@ -338,6 +338,8 @@ mod tests { sidechain_id: None, shard_key, start_epoch: Default::default(), + original_registration: Default::default(), + minimum_value_promise: Default::default(), }); } nodes.sort_by(|a, b| a.sidechain_id.cmp(&b.sidechain_id).then(a.shard_key.cmp(&b.shard_key))); diff --git a/base_layer/core/src/chain_storage/tests/blockchain_database.rs b/base_layer/core/src/chain_storage/tests/blockchain_database.rs index 19fc66ab42..0e1de44bb1 100644 --- a/base_layer/core/src/chain_storage/tests/blockchain_database.rs +++ b/base_layer/core/src/chain_storage/tests/blockchain_database.rs @@ -659,6 +659,8 @@ mod validator_node_merkle_root { sidechain_id: None, shard_key, start_epoch: Default::default(), + original_registration: Default::default(), + minimum_value_promise: Default::default(), }]) .unwrap(); @@ -717,6 +719,8 @@ mod validator_node_merkle_root { sidechain_id: Some(sidechain_public), shard_key, start_epoch: Default::default(), + original_registration: Default::default(), + minimum_value_promise: Default::default(), }]) .unwrap(); From bccd1dbc1405ed0658984f72a2cd8117190a6cb5 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Fri, 8 Nov 2024 13:43:25 +0100 Subject: [PATCH 17/23] make registration non optional --- .../src/conversions/validator_node_change.rs | 5 +---- .../core/src/base_node/comms_interface/comms_response.rs | 2 +- .../core/src/base_node/comms_interface/inbound_handlers.rs | 4 ++-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/applications/minotari_app_grpc/src/conversions/validator_node_change.rs b/applications/minotari_app_grpc/src/conversions/validator_node_change.rs index 69f113620b..f083e5bc3f 100644 --- a/applications/minotari_app_grpc/src/conversions/validator_node_change.rs +++ b/applications/minotari_app_grpc/src/conversions/validator_node_change.rs @@ -13,10 +13,7 @@ impl From<&ValidatorNodeChange> for crate::tari_rpc::ValidatorNodeChange { ValidatorNodeChangeState::REMOVE => crate::tari_rpc::ValidatorNodeChangeState::Remove.into(), }, start_height: node_change.height, - registration: match &node_change.registration { - Some(registration) => Some(registration.into()), - None => None, - }, + registration: Some((&node_change.registration).into()), minimum_value_promise: node_change.minimum_value_promise.into(), } } diff --git a/base_layer/core/src/base_node/comms_interface/comms_response.rs b/base_layer/core/src/base_node/comms_interface/comms_response.rs index 7782b0631d..3d55bdfc81 100644 --- a/base_layer/core/src/base_node/comms_interface/comms_response.rs +++ b/base_layer/core/src/base_node/comms_interface/comms_response.rs @@ -126,7 +126,7 @@ pub enum ValidatorNodeChangeState { pub struct ValidatorNodeChange { pub public_key: PublicKey, pub state: ValidatorNodeChangeState, - pub registration: Option, + pub registration: ValidatorNodeRegistration, pub minimum_value_promise: MicroMinotari, pub height: u64, } diff --git a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs index 7a63e49e1f..1a47fe48cd 100644 --- a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs +++ b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs @@ -474,7 +474,7 @@ where B: BlockchainBackend + 'static node_changes.insert(prev_node.public_key.clone(), ValidatorNodeChange { public_key: prev_node.public_key.clone(), state: ValidatorNodeChangeState::REMOVE, - registration: None, + registration: prev_node.original_registration.clone(), minimum_value_promise: prev_node.minimum_value_promise, height: constants.epoch_to_block_height(prev_node.start_epoch), }); @@ -490,7 +490,7 @@ where B: BlockchainBackend + 'static node_changes.insert(current_node.public_key.clone(), ValidatorNodeChange { public_key: current_node.public_key.clone(), state: ValidatorNodeChangeState::ADD, - registration: Some(current_node.original_registration.clone()), + registration: current_node.original_registration.clone(), minimum_value_promise: current_node.minimum_value_promise, height: constants.epoch_to_block_height(current_node.start_epoch), }); From eb47fded79fba3f91d47e30789fec127d53415a9 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Fri, 8 Nov 2024 14:36:12 +0100 Subject: [PATCH 18/23] reverted consensus constants --- .../core/src/consensus/consensus_constants.rs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/base_layer/core/src/consensus/consensus_constants.rs b/base_layer/core/src/consensus/consensus_constants.rs index 50ab777c88..baad3bf93e 100644 --- a/base_layer/core/src/consensus/consensus_constants.rs +++ b/base_layer/core/src/consensus/consensus_constants.rs @@ -424,8 +424,8 @@ impl ConsensusConstants { vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, - vn_registration_max_vns_initial_epoch: 5, - vn_registration_max_vns_per_epoch: 2, + vn_registration_max_vns_initial_epoch: 50, + vn_registration_max_vns_per_epoch: 10, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[120], &[50], &[50]); @@ -491,8 +491,8 @@ impl ConsensusConstants { vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, - vn_registration_max_vns_initial_epoch: 5, - vn_registration_max_vns_per_epoch: 2, + vn_registration_max_vns_initial_epoch: 50, + vn_registration_max_vns_per_epoch: 10, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[target_time], &[randomx_split], &[sha3x_split]); @@ -549,8 +549,8 @@ impl ConsensusConstants { vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, - vn_registration_max_vns_initial_epoch: 5, - vn_registration_max_vns_per_epoch: 2, + vn_registration_max_vns_initial_epoch: 50, + vn_registration_max_vns_per_epoch: 10, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[120], &[50], &[50]); @@ -607,8 +607,8 @@ impl ConsensusConstants { vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, - vn_registration_max_vns_initial_epoch: 5, - vn_registration_max_vns_per_epoch: 2, + vn_registration_max_vns_initial_epoch: 50, + vn_registration_max_vns_per_epoch: 10, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[120], &[50], &[50]); @@ -659,8 +659,8 @@ impl ConsensusConstants { vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, - vn_registration_max_vns_initial_epoch: 5, - vn_registration_max_vns_per_epoch: 2, + vn_registration_max_vns_initial_epoch: 50, + vn_registration_max_vns_per_epoch: 10, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[120], &[50], &[50]); @@ -713,8 +713,8 @@ impl ConsensusConstants { vn_registration_lock_height: 0, vn_registration_shuffle_interval: VnEpoch(100), coinbase_output_features_extra_max_length: 64, - vn_registration_max_vns_initial_epoch: 5, - vn_registration_max_vns_per_epoch: 2, + vn_registration_max_vns_initial_epoch: 50, + vn_registration_max_vns_per_epoch: 10, }]; #[cfg(any(test, debug_assertions))] assert_hybrid_pow_constants(&consensus_constants, &[120], &[50], &[50]); From 475a042bf2361826034629a789e53383aed96785 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Fri, 8 Nov 2024 14:37:55 +0100 Subject: [PATCH 19/23] change comments --- .../lmdb_db/validator_node_store.rs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs index 44d018bab3..b9864d09aa 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs @@ -53,7 +53,7 @@ pub struct ValidatorNodeStore<'a, Txn> { db_validator_nodes_mapping: DatabaseRef, } -impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { +impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { pub fn new(txn: &'a Txn, db_height_to_vn: DatabaseRef, idx_public_key_to_shard: DatabaseRef) -> Self { Self { txn, @@ -70,7 +70,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { validator.public_key.as_bytes(), validator.commitment.as_bytes(), ]) - .expect("insert: Composite key length is incorrect"); + .expect("insert: Composite key length is incorrect"); lmdb_insert(self.txn, &self.db_validator_nodes, &key, &validator, "Validator node")?; let key = ShardIdIndexKey::try_from_parts(&[ @@ -78,7 +78,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { height.to_be_bytes().as_slice(), validator.commitment.as_bytes(), ]) - .expect("insert: Composite key length is incorrect"); + .expect("insert: Composite key length is incorrect"); lmdb_insert( self.txn, &self.db_validator_nodes_mapping, @@ -100,7 +100,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { public_key.as_bytes(), commitment.as_bytes(), ]) - .expect("delete: Composite key length is incorrect"); + .expect("delete: Composite key length is incorrect"); lmdb_delete(self.txn, &self.db_validator_nodes, &key, "validator_nodes")?; let key = ShardIdIndexKey::try_from_parts(&[ @@ -108,7 +108,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { height.to_be_bytes().as_slice(), commitment.as_bytes(), ]) - .expect("delete: Composite key length is incorrect"); + .expect("delete: Composite key length is incorrect"); lmdb_delete( self.txn, &self.db_validator_nodes_mapping, @@ -119,7 +119,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { } } -impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { +impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { fn db_read_cursor(&self) -> Result, ChainStorageError> { let cursor = self.txn.cursor(self.db_validator_nodes.clone())?; let access = self.txn.access(); @@ -155,7 +155,7 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> Ok(false) } - /// Returns validator nodes until a given epoch. + /// Returns validator nodes count until a given epoch. pub fn get_vn_count_until_epoch( &self, epoch: VnEpoch, @@ -172,7 +172,7 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> Ok(result) } - /// Returns validator nodes in a given epoch. + /// Returns validator nodes count in a given epoch. pub fn get_vn_count_in_epoch( &self, epoch: VnEpoch, @@ -217,7 +217,7 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> original_registration: vn.registration.clone(), minimum_value_promise: vn.minimum_value_promise, })); - }, + } None => return Ok(Vec::new()), } @@ -276,7 +276,7 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> return Ok(None); } Some(s) - }, + } None => return Ok(None), }; @@ -307,7 +307,7 @@ mod tests { const DBS: &[&str] = &["validator_node_store", "validator_node_index"]; - fn create_store<'a, Txn: Deref>>( + fn create_store<'a, Txn: Deref>>( db: &TempLmdbDatabase, txn: &'a Txn, ) -> ValidatorNodeStore<'a, Txn> { From af9b02ad06df27214fa2a1cd60fba37c580ce010 Mon Sep 17 00:00:00 2001 From: ksrichard Date: Fri, 8 Nov 2024 14:39:26 +0100 Subject: [PATCH 20/23] updated trace logging --- .../src/grpc/base_node_grpc_server.rs | 118 +++++++++--------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/applications/minotari_node/src/grpc/base_node_grpc_server.rs b/applications/minotari_node/src/grpc/base_node_grpc_server.rs index b010eadc47..47c77f34c2 100644 --- a/applications/minotari_node/src/grpc/base_node_grpc_server.rs +++ b/applications/minotari_node/src/grpc/base_node_grpc_server.rs @@ -286,7 +286,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ))) .await; return; - }, + } }; if headers.is_empty() { @@ -323,7 +323,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(format!("Error fetching block at height {}", current_height)), ))); return; - }, + } }; if block.is_none() { let _network_difficulty_response = tx.send(Err(obscure_error_if_true( @@ -379,7 +379,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Error communicating with base node: {}", err,); return; - }, + } Ok(data) => data, }; for transaction in transactions.unconfirmed_pool { @@ -401,7 +401,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); } return; - }, + } }; if tx @@ -446,7 +446,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::internal(err.to_string()), )); - }, + } Ok(data) => data.best_block_height(), }; @@ -469,7 +469,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { (res, false) => res + 1, }; (from..=tip, true) - }, + } Sorting::Asc => (0..=num_headers.saturating_sub(1), false), } } else { @@ -480,11 +480,11 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { (res, false) => res + 1, }; (from..=from_height, true) - }, + } Sorting::Asc => { let to = from_height.saturating_add(num_headers).saturating_sub(1); (from_height..=to, false) - }, + } } }; let consensus_rules = self.consensus_rules.clone(); @@ -493,7 +493,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { header_range.end().saturating_add(1), LIST_HEADERS_PAGE_SIZE, ) - .map_err(|e| obscure_error_if_true(report_error_flag, Status::invalid_argument(e)))?; + .map_err(|e| obscure_error_if_true(report_error_flag, Status::invalid_argument(e)))?; task::spawn(async move { trace!( target: LOG_TARGET, @@ -512,7 +512,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Internal base node service error: {}", err); return; - }, + } Ok(data) => { if is_reversed { data.into_iter() @@ -531,7 +531,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { Err(obscure_error_if_true(report_error_flag, Status::internal(e)) .to_string()) - }, + } } }) .rev() @@ -553,18 +553,18 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { Err(obscure_error_if_true(report_error_flag, Status::internal(e)) .to_string()) - }, + } } }) .collect::, String>>() } - }, + } }; match result_data { Err(e) => { error!(target: LOG_TARGET, "No result headers transmitted due to error: {}", e) - }, + } Ok(result_data) => { let result_size = result_data.len(); trace!(target: LOG_TARGET, "Result headers: {}", result_size); @@ -585,7 +585,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { return; } } - }, + } } } }); @@ -681,7 +681,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - }, + } Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -689,13 +689,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - }, + } Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - }, + } }; let fees = new_block.body.get_total_fee().map_err(|_| { obscure_error_if_true( @@ -850,12 +850,12 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { })? - prev_coinbase_value, ) - .map_err(|_| { - obscure_error_if_true( - report_error_flag, - Status::internal("Single coinbase fees exceeded u64".to_string()), - ) - })?; + .map_err(|_| { + obscure_error_if_true( + report_error_flag, + Status::internal("Single coinbase fees exceeded u64".to_string()), + ) + })?; prev_coinbase_value += u128::from(coinbase.value); } @@ -896,8 +896,8 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { range_proof_type, PaymentId::Empty, ) - .await - .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; + .await + .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; new_template.body.add_output(coinbase_output); let new_nonce = key_manager .get_next_key(TransactionKeyManagerBranch::KernelNonce.get_branch_key()) @@ -951,7 +951,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - }, + } Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -959,13 +959,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - }, + } Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - }, + } }; let gen_hash = handler .get_header(0) @@ -1094,8 +1094,8 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { range_proof_type, PaymentId::Empty, ) - .await - .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; + .await + .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; block_template.body.add_output(coinbase_output); let new_nonce = key_manager .get_next_key(TransactionKeyManagerBranch::KernelNonce.get_branch_key()) @@ -1149,7 +1149,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - }, + } Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -1157,13 +1157,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - }, + } Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - }, + } }; let fees = new_block.body.get_total_fee().map_err(|_| { obscure_error_if_true( @@ -1254,7 +1254,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - }, + } Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -1262,13 +1262,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - }, + } Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - }, + } }; // construct response let block_hash = new_block.hash().to_vec(); @@ -1509,7 +1509,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { * should not think its mined, but the * node does not think it is. */ } - }, + } TxStorageResponse::NotStored | TxStorageResponse::NotStoredConsensus | TxStorageResponse::NotStoredOrphan | @@ -1599,7 +1599,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - }, + } Ok(data) => data.into_iter().filter(|b| heights.contains(&b.header().height)), }; @@ -1689,7 +1689,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - }, + } Ok(data) => data, }; for block in blocks { @@ -1745,7 +1745,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - }, + } Ok(data) => data, }; for block in blocks { @@ -1805,7 +1805,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(format!("Error communicating with local base node: {}", err)), ))); return; - }, + } Ok(data) => data, }; for output in outputs { @@ -1819,14 +1819,14 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); return; } - }, + } Err(err) => { let _ignore = tx.send(Err(obscure_error_if_true( report_error_flag, Status::internal(format!("Error communicating with local base node: {}", err)), ))); return; - }, + } } } }); @@ -1926,7 +1926,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { BlockGroupType::BlockSize, report_error_flag, ) - .await + .await } async fn get_block_fees( @@ -1941,7 +1941,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { BlockGroupType::BlockFees, report_error_flag, ) - .await + .await } async fn get_version(&self, _request: Request) -> Result, Status> { @@ -2308,7 +2308,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Base node service error: {}", err,); return; - }, + } Ok(data) => data, }; @@ -2374,7 +2374,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { header.map(|h| h.height()).ok_or_else(|| { obscure_error_if_true(report_error_flag, Status::not_found("Start hash not found")) })? - }, + } None => 0, }; @@ -2394,7 +2394,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Base node service error: {}", err); return; - }, + } Ok(data) => data, }; @@ -2484,7 +2484,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { warn!(target: LOG_TARGET, "Base node service error: {}", e); return; - }, + } }; let next_header = match node_service.get_header(height.saturating_add(1)).await { @@ -2495,7 +2495,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(e.to_string()), ))); return; - }, + } }; let sidechain_outputs = utxos @@ -2522,7 +2522,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); return; } - }, + } Err(e) => { warn!( target: LOG_TARGET, @@ -2535,13 +2535,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ))) .await; return; - }, + } }; match next_header { Some(header) => { current_header = header; - }, + } None => break, } } @@ -2559,7 +2559,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ) -> Result, Status> { self.check_method_enabled(GrpcMethod::GetValidatorNodeChanges)?; let request = request.into_inner(); - trace!(target: LOG_TARGET, "Incoming GRPC request for GetActiveValidatorNodes"); + trace!(target: LOG_TARGET, "Incoming GRPC request for GetValidatorNodeChanges"); let mut handler = self.node_service.clone(); @@ -2621,7 +2621,7 @@ async fn get_block_group( "Error communicating with local base node: {:?}", err, ); vec![] - }, + } Ok(data) => data, }; let extractor = match block_group_type { @@ -2637,15 +2637,15 @@ async fn get_block_group( report_error_flag, Status::unimplemented("Quantile has not been implemented"), )) - }, + } CalcType::Quartile => { return Err(obscure_error_if_true( report_error_flag, Status::unimplemented("Quartile has not been implemented"), )) - }, + } } - .unwrap_or_default(); + .unwrap_or_default(); trace!( target: LOG_TARGET, "Sending GetBlockSize response to client: {:?}", value From 498c11652ade2dc688364f419630c83fad07ba83 Mon Sep 17 00:00:00 2001 From: Stan Bondi Date: Mon, 11 Nov 2024 10:54:17 +0400 Subject: [PATCH 21/23] clippy + licence --- .../src/conversions/validator_node_registration.rs | 3 +++ .../core/src/base_node/comms_interface/inbound_handlers.rs | 1 + 2 files changed, 4 insertions(+) diff --git a/applications/minotari_app_grpc/src/conversions/validator_node_registration.rs b/applications/minotari_app_grpc/src/conversions/validator_node_registration.rs index ac32b3aca6..69c9e71dfa 100644 --- a/applications/minotari_app_grpc/src/conversions/validator_node_registration.rs +++ b/applications/minotari_app_grpc/src/conversions/validator_node_registration.rs @@ -1,3 +1,6 @@ +// Copyright 2024 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + use tari_core::transactions::transaction_components::ValidatorNodeRegistration; use tari_utilities::ByteArray; diff --git a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs index 1a47fe48cd..c514cf8546 100644 --- a/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs +++ b/base_layer/core/src/base_node/comms_interface/inbound_handlers.rs @@ -454,6 +454,7 @@ where B: BlockchainBackend + 'static sidechain_id, } => { let constants = self.consensus_manager.consensus_constants(start_height); + #[allow(clippy::mutable_key_type)] let mut node_changes = HashMap::::new(); let mut nodes = self .blockchain_db From 7e58a86b8a27e379b1927dc5fcd77e3b79d2d76d Mon Sep 17 00:00:00 2001 From: ksrichard Date: Mon, 11 Nov 2024 08:28:54 +0100 Subject: [PATCH 22/23] cargo format --- .../src/grpc/base_node_grpc_server.rs | 116 +++++++++--------- .../lmdb_db/validator_node_store.rs | 18 +-- 2 files changed, 67 insertions(+), 67 deletions(-) diff --git a/applications/minotari_node/src/grpc/base_node_grpc_server.rs b/applications/minotari_node/src/grpc/base_node_grpc_server.rs index 47c77f34c2..2594d021c4 100644 --- a/applications/minotari_node/src/grpc/base_node_grpc_server.rs +++ b/applications/minotari_node/src/grpc/base_node_grpc_server.rs @@ -286,7 +286,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ))) .await; return; - } + }, }; if headers.is_empty() { @@ -323,7 +323,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(format!("Error fetching block at height {}", current_height)), ))); return; - } + }, }; if block.is_none() { let _network_difficulty_response = tx.send(Err(obscure_error_if_true( @@ -379,7 +379,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Error communicating with base node: {}", err,); return; - } + }, Ok(data) => data, }; for transaction in transactions.unconfirmed_pool { @@ -401,7 +401,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); } return; - } + }, }; if tx @@ -446,7 +446,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::internal(err.to_string()), )); - } + }, Ok(data) => data.best_block_height(), }; @@ -469,7 +469,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { (res, false) => res + 1, }; (from..=tip, true) - } + }, Sorting::Asc => (0..=num_headers.saturating_sub(1), false), } } else { @@ -480,11 +480,11 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { (res, false) => res + 1, }; (from..=from_height, true) - } + }, Sorting::Asc => { let to = from_height.saturating_add(num_headers).saturating_sub(1); (from_height..=to, false) - } + }, } }; let consensus_rules = self.consensus_rules.clone(); @@ -493,7 +493,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { header_range.end().saturating_add(1), LIST_HEADERS_PAGE_SIZE, ) - .map_err(|e| obscure_error_if_true(report_error_flag, Status::invalid_argument(e)))?; + .map_err(|e| obscure_error_if_true(report_error_flag, Status::invalid_argument(e)))?; task::spawn(async move { trace!( target: LOG_TARGET, @@ -512,7 +512,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Internal base node service error: {}", err); return; - } + }, Ok(data) => { if is_reversed { data.into_iter() @@ -531,7 +531,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { Err(obscure_error_if_true(report_error_flag, Status::internal(e)) .to_string()) - } + }, } }) .rev() @@ -553,18 +553,18 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { Err(obscure_error_if_true(report_error_flag, Status::internal(e)) .to_string()) - } + }, } }) .collect::, String>>() } - } + }, }; match result_data { Err(e) => { error!(target: LOG_TARGET, "No result headers transmitted due to error: {}", e) - } + }, Ok(result_data) => { let result_size = result_data.len(); trace!(target: LOG_TARGET, "Result headers: {}", result_size); @@ -585,7 +585,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { return; } } - } + }, } } }); @@ -681,7 +681,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - } + }, Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -689,13 +689,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - } + }, Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - } + }, }; let fees = new_block.body.get_total_fee().map_err(|_| { obscure_error_if_true( @@ -850,12 +850,12 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { })? - prev_coinbase_value, ) - .map_err(|_| { - obscure_error_if_true( - report_error_flag, - Status::internal("Single coinbase fees exceeded u64".to_string()), - ) - })?; + .map_err(|_| { + obscure_error_if_true( + report_error_flag, + Status::internal("Single coinbase fees exceeded u64".to_string()), + ) + })?; prev_coinbase_value += u128::from(coinbase.value); } @@ -896,8 +896,8 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { range_proof_type, PaymentId::Empty, ) - .await - .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; + .await + .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; new_template.body.add_output(coinbase_output); let new_nonce = key_manager .get_next_key(TransactionKeyManagerBranch::KernelNonce.get_branch_key()) @@ -951,7 +951,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - } + }, Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -959,13 +959,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - } + }, Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - } + }, }; let gen_hash = handler .get_header(0) @@ -1094,8 +1094,8 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { range_proof_type, PaymentId::Empty, ) - .await - .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; + .await + .map_err(|e| obscure_error_if_true(report_error_flag, Status::internal(e.to_string())))?; block_template.body.add_output(coinbase_output); let new_nonce = key_manager .get_next_key(TransactionKeyManagerBranch::KernelNonce.get_branch_key()) @@ -1149,7 +1149,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - } + }, Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -1157,13 +1157,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - } + }, Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - } + }, }; let fees = new_block.body.get_total_fee().map_err(|_| { obscure_error_if_true( @@ -1254,7 +1254,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { report_error_flag, Status::invalid_argument(message), )); - } + }, Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( tonic::Code::FailedPrecondition, @@ -1262,13 +1262,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Bytes::from_static(b"CannotCalculateNonTipMmr"), ); return Err(obscure_error_if_true(report_error_flag, status)); - } + }, Err(e) => { return Err(obscure_error_if_true( report_error_flag, Status::internal(e.to_string()), )) - } + }, }; // construct response let block_hash = new_block.hash().to_vec(); @@ -1509,7 +1509,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { * should not think its mined, but the * node does not think it is. */ } - } + }, TxStorageResponse::NotStored | TxStorageResponse::NotStoredConsensus | TxStorageResponse::NotStoredOrphan | @@ -1599,7 +1599,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - } + }, Ok(data) => data.into_iter().filter(|b| heights.contains(&b.header().height)), }; @@ -1689,7 +1689,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - } + }, Ok(data) => data, }; for block in blocks { @@ -1745,7 +1745,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Error communicating with local base node: {:?}", err, ); return; - } + }, Ok(data) => data, }; for block in blocks { @@ -1805,7 +1805,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(format!("Error communicating with local base node: {}", err)), ))); return; - } + }, Ok(data) => data, }; for output in outputs { @@ -1819,14 +1819,14 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); return; } - } + }, Err(err) => { let _ignore = tx.send(Err(obscure_error_if_true( report_error_flag, Status::internal(format!("Error communicating with local base node: {}", err)), ))); return; - } + }, } } }); @@ -1926,7 +1926,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { BlockGroupType::BlockSize, report_error_flag, ) - .await + .await } async fn get_block_fees( @@ -1941,7 +1941,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { BlockGroupType::BlockFees, report_error_flag, ) - .await + .await } async fn get_version(&self, _request: Request) -> Result, Status> { @@ -2308,7 +2308,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Base node service error: {}", err,); return; - } + }, Ok(data) => data, }; @@ -2374,7 +2374,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { header.map(|h| h.height()).ok_or_else(|| { obscure_error_if_true(report_error_flag, Status::not_found("Start hash not found")) })? - } + }, None => 0, }; @@ -2394,7 +2394,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Base node service error: {}", err); return; - } + }, Ok(data) => data, }; @@ -2484,7 +2484,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(e) => { warn!(target: LOG_TARGET, "Base node service error: {}", e); return; - } + }, }; let next_header = match node_service.get_header(height.saturating_add(1)).await { @@ -2495,7 +2495,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Status::internal(e.to_string()), ))); return; - } + }, }; let sidechain_outputs = utxos @@ -2522,7 +2522,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ); return; } - } + }, Err(e) => { warn!( target: LOG_TARGET, @@ -2535,13 +2535,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { ))) .await; return; - } + }, }; match next_header { Some(header) => { current_header = header; - } + }, None => break, } } @@ -2621,7 +2621,7 @@ async fn get_block_group( "Error communicating with local base node: {:?}", err, ); vec![] - } + }, Ok(data) => data, }; let extractor = match block_group_type { @@ -2637,15 +2637,15 @@ async fn get_block_group( report_error_flag, Status::unimplemented("Quantile has not been implemented"), )) - } + }, CalcType::Quartile => { return Err(obscure_error_if_true( report_error_flag, Status::unimplemented("Quartile has not been implemented"), )) - } + }, } - .unwrap_or_default(); + .unwrap_or_default(); trace!( target: LOG_TARGET, "Sending GetBlockSize response to client: {:?}", value diff --git a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs index b9864d09aa..d82407e193 100644 --- a/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs +++ b/base_layer/core/src/chain_storage/lmdb_db/validator_node_store.rs @@ -53,7 +53,7 @@ pub struct ValidatorNodeStore<'a, Txn> { db_validator_nodes_mapping: DatabaseRef, } -impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { +impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { pub fn new(txn: &'a Txn, db_height_to_vn: DatabaseRef, idx_public_key_to_shard: DatabaseRef) -> Self { Self { txn, @@ -70,7 +70,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { validator.public_key.as_bytes(), validator.commitment.as_bytes(), ]) - .expect("insert: Composite key length is incorrect"); + .expect("insert: Composite key length is incorrect"); lmdb_insert(self.txn, &self.db_validator_nodes, &key, &validator, "Validator node")?; let key = ShardIdIndexKey::try_from_parts(&[ @@ -78,7 +78,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { height.to_be_bytes().as_slice(), validator.commitment.as_bytes(), ]) - .expect("insert: Composite key length is incorrect"); + .expect("insert: Composite key length is incorrect"); lmdb_insert( self.txn, &self.db_validator_nodes_mapping, @@ -100,7 +100,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { public_key.as_bytes(), commitment.as_bytes(), ]) - .expect("delete: Composite key length is incorrect"); + .expect("delete: Composite key length is incorrect"); lmdb_delete(self.txn, &self.db_validator_nodes, &key, "validator_nodes")?; let key = ShardIdIndexKey::try_from_parts(&[ @@ -108,7 +108,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { height.to_be_bytes().as_slice(), commitment.as_bytes(), ]) - .expect("delete: Composite key length is incorrect"); + .expect("delete: Composite key length is incorrect"); lmdb_delete( self.txn, &self.db_validator_nodes_mapping, @@ -119,7 +119,7 @@ impl ValidatorNodeStore<'_, WriteTransaction<'_>> { } } -impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { +impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { fn db_read_cursor(&self) -> Result, ChainStorageError> { let cursor = self.txn.cursor(self.db_validator_nodes.clone())?; let access = self.txn.access(); @@ -217,7 +217,7 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { original_registration: vn.registration.clone(), minimum_value_promise: vn.minimum_value_promise, })); - } + }, None => return Ok(Vec::new()), } @@ -276,7 +276,7 @@ impl<'a, Txn: Deref>> ValidatorNodeStore<'a, Txn> { return Ok(None); } Some(s) - } + }, None => return Ok(None), }; @@ -307,7 +307,7 @@ mod tests { const DBS: &[&str] = &["validator_node_store", "validator_node_index"]; - fn create_store<'a, Txn: Deref>>( + fn create_store<'a, Txn: Deref>>( db: &TempLmdbDatabase, txn: &'a Txn, ) -> ValidatorNodeStore<'a, Txn> { From 7ff6931e825303d7c2812d259b725518d2a9815f Mon Sep 17 00:00:00 2001 From: Stan Bondi Date: Mon, 11 Nov 2024 15:19:22 +0400 Subject: [PATCH 23/23] lock hickory client to alpha.2 --- base_layer/p2p/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base_layer/p2p/Cargo.toml b/base_layer/p2p/Cargo.toml index cdc436dfc4..423943c404 100644 --- a/base_layer/p2p/Cargo.toml +++ b/base_layer/p2p/Cargo.toml @@ -37,8 +37,8 @@ tokio-stream = { version = "0.1.9", default-features = false, features = [ "time", ] } tower = "0.4.11" -hickory-client = { version = "0.25.0-alpha.2", features = ["dns-over-rustls"] } -hickory-resolver = "0.25.0-alpha.2" +hickory-client = { version = "=0.25.0-alpha.2", features = ["dns-over-rustls"] } +hickory-resolver = "=0.25.0-alpha.2" webpki-roots = "0.26.6" [dev-dependencies]