Skip to content

Commit

Permalink
fix(core): bring validator node MR inline with other merkle root code (
Browse files Browse the repository at this point in the history
…#4692)

Description
---
- calculates validator node MR in `calculate_merkle_roots` function
- allows tari_core and wallet to compile without base node feature
- removes validator_node_mr param from `BlockHeader::from_previous`
- removes validator_node_mr from NewBlocktemplate
- removes validator node mr validation task from async validator
- adds validator node mr validator to `check_merkle_roots`
- removes unused get_validator_mr function from blockchain db
- checks validator node mr in genesis block sanity check
- removes panic from grpc conversion code

Motivation and Context
---
Validator node MR is created and checked in a different way from other merkle roots, this PR brings that code inline with other the current merkle root code + number of minor improvements.

How Has This Been Tested?
---
Existing tests - TODO: write validator node registration tests for blockchain db and block validators
  • Loading branch information
sdbondi authored Sep 20, 2022
1 parent 0fef174 commit 613b655
Show file tree
Hide file tree
Showing 30 changed files with 145 additions and 233 deletions.
4 changes: 1 addition & 3 deletions applications/tari_app_grpc/proto/block.proto
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ message BlockHeader {
// Sum of script offsets for all kernels in this block.
bytes total_script_offset = 15;
// Merkle root of validator nodes
bytes validator_node_merkle_root = 16;
bytes validator_node_mr = 16;
}

// Metadata required for validating the Proof of Work calculation
Expand Down Expand Up @@ -119,8 +119,6 @@ message NewBlockHeaderTemplate {
// uint64 target_difficulty = 6;
// Sum of script offsets for all kernels in this block.
bytes total_script_offset = 7;
// Merkle root of validator nodes
bytes validator_node_merkle_root = 8;
}

// The new block template is used constructing a new partial block, allowing a miner to added the coinbase utxo and as a final step the Base node to add the MMR roots to the header.
Expand Down
2 changes: 1 addition & 1 deletion applications/tari_app_grpc/proto/wallet.proto
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ message TransactionEventResponse {
}

message RegisterValidatorNodeRequest {
string validator_node_public_key = 1;
bytes validator_node_public_key = 1;
Signature validator_node_signature = 2;
uint64 fee_per_gram = 3;
string message = 4;
Expand Down
6 changes: 3 additions & 3 deletions applications/tari_app_grpc/src/conversions/block_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl From<BlockHeader> for grpc::BlockHeader {
pow_algo: pow_algo.as_u64(),
pow_data: h.pow.pow_data,
}),
validator_node_merkle_root: h.validator_node_merkle_root,
validator_node_mr: h.validator_node_mr.to_vec(),
}
}
}
Expand Down Expand Up @@ -86,13 +86,13 @@ impl TryFrom<grpc::BlockHeader> for BlockHeader {
output_mr: FixedHash::try_from(header.output_mr).map_err(|err| err.to_string())?,
witness_mr: FixedHash::try_from(header.witness_mr).map_err(|err| err.to_string())?,
output_mmr_size: header.output_mmr_size,
kernel_mr: FixedHash::try_from(header.kernel_mr).expect("Array size 32 cannot fail"),
kernel_mr: FixedHash::try_from(header.kernel_mr).map_err(|err| err.to_string())?,
kernel_mmr_size: header.kernel_mmr_size,
total_kernel_offset,
total_script_offset,
nonce: header.nonce,
pow,
validator_node_merkle_root: header.validator_node_merkle_root,
validator_node_mr: FixedHash::try_from(header.validator_node_mr).map_err(|err| err.to_string())?,
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ impl TryFrom<NewBlockTemplate> for grpc::NewBlockTemplate {
pow_algo: block.header.pow.pow_algo.as_u64(),
pow_data: block.header.pow.pow_data,
}),
validator_node_merkle_root: block.header.validator_node_merkle_root,
};
Ok(Self {
body: Some(grpc::AggregateBody {
Expand Down Expand Up @@ -92,7 +91,6 @@ impl TryFrom<grpc::NewBlockTemplate> for NewBlockTemplate {
total_kernel_offset,
total_script_offset,
pow,
validator_node_merkle_root: header.validator_node_merkle_root,
};
let body = block
.body
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ use crate::tari_rpc as grpc;
//---------------------------------- SideChainFeature --------------------------------------------//
impl From<SideChainFeature> for grpc::SideChainFeature {
fn from(value: SideChainFeature) -> Self {
value.into()
Self {
side_chain_feature: Some(value.into()),
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,7 @@ impl wallet_server::Wallet for WalletGrpcServer {
) -> Result<Response<RegisterValidatorNodeResponse>, Status> {
let request = request.into_inner();
let mut transaction_service = self.get_transaction_service();
let validator_node_public_key = CommsPublicKey::from_hex(&request.validator_node_public_key)
let validator_node_public_key = CommsPublicKey::from_bytes(&request.validator_node_public_key)
.map_err(|_| Status::internal("Destination address is malformed".to_string()))?;
let validator_node_signature = request
.validator_node_signature
Expand Down
5 changes: 5 additions & 0 deletions base_layer/common_types/src/types/fixed_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ impl PartialEq<Vec<u8>> for FixedHash {
self == other.as_slice()
}
}
impl PartialEq<FixedHash> for Vec<u8> {
fn eq(&self, other: &FixedHash) -> bool {
self == other.as_slice()
}
}

impl AsRef<[u8]> for FixedHash {
fn as_ref(&self) -> &[u8] {
Expand Down
4 changes: 2 additions & 2 deletions base_layer/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ version = "0.38.3"
edition = "2018"

[features]
default = ["croaring", "tari_mmr", "transactions", "base_node", "mempool_proto", "base_node_proto", "monero", "randomx-rs"]
default = ["base_node"]
transactions = []
mempool_proto = []
base_node = ["croaring", "tari_mmr", "transactions", "base_node_proto", "monero", "randomx-rs"]
base_node = ["croaring", "tari_mmr", "transactions", "mempool_proto", "base_node_proto", "monero", "randomx-rs"]
base_node_proto = []
avx2 = ["tari_crypto/simd_backend"]
benches = ["base_node", "criterion"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,7 @@ where B: BlockchainBackend + 'static
},
NodeCommsRequest::GetNewBlockTemplate(request) => {
let best_block_header = self.blockchain_db.fetch_tip_header().await?;
let vns = self.blockchain_db.get_validator_nodes_mr().await?;
let mut header = BlockHeader::from_previous(best_block_header.header(), vns);
let mut header = BlockHeader::from_previous(best_block_header.header());
let constants = self.consensus_manager.consensus_constants(header.height);
header.version = constants.blockchain_version();
header.pow.pow_algo = request.algo;
Expand Down
8 changes: 4 additions & 4 deletions base_layer/core/src/base_node/sync/header_sync/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ mod test {
let (validator, db) = setup();
let mut tip = db.fetch_tip_header().await.unwrap();
for _ in 0..n {
let mut header = BlockHeader::from_previous(tip.header(), tip.header().validator_node_merkle_root.clone());
let mut header = BlockHeader::from_previous(tip.header());
// Needed to have unique keys for the blockchain db mmr count indexes (MDB_KEY_EXIST error)
header.kernel_mmr_size += 1;
header.output_mmr_size += 1;
Expand Down Expand Up @@ -316,11 +316,11 @@ mod test {
let (mut validator, _, tip) = setup_with_headers(1).await;
validator.initialize_state(tip.hash()).await.unwrap();
assert!(validator.valid_headers().is_empty());
let next = BlockHeader::from_previous(tip.header(), tip.header().validator_node_merkle_root.clone());
let next = BlockHeader::from_previous(tip.header());
validator.validate(next).unwrap();
assert_eq!(validator.valid_headers().len(), 1);
let tip = validator.valid_headers().last().cloned().unwrap();
let next = BlockHeader::from_previous(tip.header(), tip.header().validator_node_merkle_root.clone());
let next = BlockHeader::from_previous(tip.header());
validator.validate(next).unwrap();
assert_eq!(validator.valid_headers().len(), 2);
}
Expand All @@ -329,7 +329,7 @@ mod test {
async fn it_fails_if_height_is_not_serial() {
let (mut validator, _, tip) = setup_with_headers(2).await;
validator.initialize_state(tip.hash()).await.unwrap();
let mut next = BlockHeader::from_previous(tip.header(), tip.header().validator_node_merkle_root.clone());
let mut next = BlockHeader::from_previous(tip.header());
next.height = 10;
let err = validator.validate(next).unwrap_err();
unpack_enum!(BlockHeaderSyncError::InvalidBlockHeight { expected, actual } = err);
Expand Down
16 changes: 7 additions & 9 deletions base_layer/core/src/blocks/block_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ use crate::{
blocks::BlocksHashDomain,
consensus::{ConsensusDecoding, ConsensusEncoding, ConsensusEncodingSized, DomainSeparatedConsensusHasher},
proof_of_work::{PowAlgorithm, PowError, ProofOfWork},
ValidatorNodeMmr,
};

#[derive(Debug, Error)]
Expand Down Expand Up @@ -111,14 +110,13 @@ pub struct BlockHeader {
pub nonce: u64,
/// Proof of work summary
pub pow: ProofOfWork,
// Merkle root of all active validator node.
pub validator_node_merkle_root: Vec<u8>,
/// Merkle root of all active validator node.
pub validator_node_mr: FixedHash,
}

impl BlockHeader {
/// Create a new, default header with the given version.
pub fn new(blockchain_version: u16) -> BlockHeader {
let vn_mmr = ValidatorNodeMmr::new(Vec::new());
BlockHeader {
version: blockchain_version,
height: 0,
Expand All @@ -134,7 +132,7 @@ impl BlockHeader {
total_script_offset: BlindingFactor::default(),
nonce: 0,
pow: ProofOfWork::default(),
validator_node_merkle_root: vn_mmr.get_merkle_root().unwrap(),
validator_node_mr: FixedHash::zero(),
}
}

Expand All @@ -150,7 +148,7 @@ impl BlockHeader {
/// Create a new block header using relevant data from the previous block. The height is incremented by one, the
/// previous block hash is set, the timestamp is set to the current time, and the kernel/output mmr sizes are set to
/// the previous block. All other fields, including proof of work are set to defaults.
pub fn from_previous(prev: &BlockHeader, validator_node_merkle_root: Vec<u8>) -> BlockHeader {
pub fn from_previous(prev: &BlockHeader) -> BlockHeader {
let prev_hash = prev.hash();
BlockHeader {
version: prev.version,
Expand All @@ -167,7 +165,7 @@ impl BlockHeader {
total_script_offset: BlindingFactor::default(),
nonce: 0,
pow: ProofOfWork::default(),
validator_node_merkle_root,
validator_node_mr: FixedHash::zero(),
}
}

Expand Down Expand Up @@ -269,7 +267,7 @@ impl From<NewBlockHeaderTemplate> for BlockHeader {
total_script_offset: header_template.total_script_offset,
nonce: 0,
pow: header_template.pow,
validator_node_merkle_root: header_template.validator_node_merkle_root,
validator_node_mr: FixedHash::zero(),
}
}
}
Expand Down Expand Up @@ -369,7 +367,7 @@ mod test {
h1.nonce = 7600;
assert_eq!(h1.height, 0, "Default block height");
let hash1 = h1.hash();
let h2 = BlockHeader::from_previous(&h1, h1.validator_node_merkle_root.clone());
let h2 = BlockHeader::from_previous(&h1);
assert_eq!(h2.height, h1.height + 1, "Incrementing block height");
assert!(h2.timestamp > h1.timestamp, "Timestamp");
assert_eq!(h2.prev_hash, hash1, "Previous hash");
Expand Down
Loading

0 comments on commit 613b655

Please sign in to comment.