diff --git a/data_structures/src/chain/mod.rs b/data_structures/src/chain/mod.rs index c10a34ee8..1d9f74183 100644 --- a/data_structures/src/chain/mod.rs +++ b/data_structures/src/chain/mod.rs @@ -36,11 +36,8 @@ use crate::{ DataRequestError, EpochCalculationError, OutputPointerParseError, Secp256k1ConversionError, TransactionError, }, - get_environment, - proto::{ - versioning::{ProtocolVersion, VersionedHashable}, - ProtobufConvert, - }, + get_environment, get_protocol_version, + proto::{versioning::Versioned, ProtobufConvert}, superblock::SuperBlockState, transaction::{ CommitTransaction, DRTransaction, DRTransactionBody, Memoized, MintTransaction, @@ -536,7 +533,7 @@ impl Block { } pub fn is_genesis(&self, genesis: &Hash) -> bool { - self.versioned_hash(ProtocolVersion::Legacy).eq(genesis) + self.hash().eq(genesis) } } @@ -671,7 +668,9 @@ impl Hashable for BlockHeader { impl MemoizedHashable for Block { fn hashable_bytes(&self) -> Vec { - self.block_header.to_pb_bytes().unwrap() + self.block_header + .to_versioned_pb_bytes(get_protocol_version()) + .unwrap() } fn memoized_hash(&self) -> &MemoHash { @@ -4572,19 +4571,17 @@ mod tests { let block = block_example(); let expected = "70e15ac70bb00f49c7a593b2423f722dca187bbae53dc2f22647063b17608c01"; assert_eq!( - block.versioned_hash(ProtocolVersion::Legacy).to_string(), + block.versioned_hash(ProtocolVersion::V1_6).to_string(), expected ); let expected = "29ef68357a5c861b9dbe043d351a28472ca450edcda25de4c9b80a4560a28c0f"; assert_eq!( - block - .versioned_hash(ProtocolVersion::Transition) - .to_string(), + block.versioned_hash(ProtocolVersion::V1_7).to_string(), expected ); let expected = "29ef68357a5c861b9dbe043d351a28472ca450edcda25de4c9b80a4560a28c0f"; assert_eq!( - block.versioned_hash(ProtocolVersion::Final).to_string(), + block.versioned_hash(ProtocolVersion::V2_0).to_string(), expected ); } @@ -6658,7 +6655,6 @@ mod tests { 1, Hash::default(), 1, - ProtocolVersion::Legacy, ); let expected_indices = vec![0, 2, 2]; @@ -6713,7 +6709,6 @@ mod tests { 1, Hash::default(), 1, - ProtocolVersion::Legacy, ); let expected_indices = vec![0, 2, 2, 8, 10, 6, 4, 6]; @@ -6749,7 +6744,6 @@ mod tests { 1, Hash::default(), 1, - ProtocolVersion::Legacy, ); let result = sb.dr_proof_of_inclusion(&[b1, b2], &dr_txs[2]); @@ -6760,14 +6754,7 @@ mod tests { fn test_dr_merkle_root_no_block() { let dr_txs = build_test_dr_txs(3); - let sb = mining_build_superblock( - &[], - &[Hash::default()], - 1, - Hash::default(), - 1, - ProtocolVersion::Legacy, - ); + let sb = mining_build_superblock(&[], &[Hash::default()], 1, Hash::default(), 1); let result = sb.dr_proof_of_inclusion(&[], &dr_txs[2]); assert!(result.is_none()); @@ -6793,7 +6780,6 @@ mod tests { 1, Hash::default(), 1, - ProtocolVersion::Legacy, ); let expected_indices = vec![0, 2]; @@ -6832,7 +6818,6 @@ mod tests { 1, Hash::default(), 1, - ProtocolVersion::Legacy, ); let expected_indices = vec![0, 2, 2]; @@ -6895,7 +6880,6 @@ mod tests { 1, Hash::default(), 1, - ProtocolVersion::Legacy, ); let expected_indices = vec![0, 2, 2, 8, 10, 6, 4, 6]; @@ -6931,7 +6915,6 @@ mod tests { 1, Hash::default(), 1, - ProtocolVersion::Legacy, ); let result = sb.tally_proof_of_inclusion(&[b1, b2], &tally_txs[2]); @@ -6963,7 +6946,6 @@ mod tests { 1, Hash::default(), 1, - ProtocolVersion::Legacy, ); let expected_indices = vec![0, 2, 2]; diff --git a/data_structures/src/lib.rs b/data_structures/src/lib.rs index e14acd6e5..c57f2386a 100644 --- a/data_structures/src/lib.rs +++ b/data_structures/src/lib.rs @@ -13,7 +13,7 @@ #[macro_use] extern crate protobuf_convert; -use crate::chain::Environment; +use crate::{chain::Environment, proto::versioning::ProtocolVersion}; use lazy_static::lazy_static; use std::sync::RwLock; @@ -82,6 +82,9 @@ lazy_static! { // can work without having to manually set the environment. // The default environment will also be used in tests. static ref ENVIRONMENT: RwLock = RwLock::new(Environment::Mainnet); + /// Protocol version that we are running. + /// default to legacy for now — it's the v2 bootstrapping module's responsibility to upgrade it. + static ref PROTOCOL_VERSION: RwLock = RwLock::new(ProtocolVersion::V1_6); } /// Environment in which we are running: mainnet or testnet. @@ -114,6 +117,34 @@ pub fn set_environment(environment: Environment) { } } +/// Protocol version that we are running. +pub fn get_protocol_version() -> ProtocolVersion { + // This unwrap is safe as long as the lock is not poisoned. + // The lock can only become poisoned when a writer panics. + // The only writer is the one used in `set_environment`, which should only + // be used during initialization. + *PROTOCOL_VERSION.read().unwrap() +} + +/// Set the protocol version that we are running. +/// This function should only be called once during initialization. +// Changing the environment in tests is not supported, as it can cause spurious failures: +// multiple tests can run in parallel and some tests might fail when the environment changes. +// But if you need to change the environment in some test, just create a separate thread-local +// variable and mock get and set. +#[cfg(not(test))] +pub fn set_protocol_version(protocol_version: ProtocolVersion) { + match PROTOCOL_VERSION.write() { + Ok(mut x) => { + *x = protocol_version; + log::debug!("Protocol version set to {}", protocol_version); + } + Err(e) => { + log::error!("Failed to set protocol version: {}", e); + } + } +} + #[cfg(test)] mod tests { use super::*; @@ -124,4 +155,12 @@ mod tests { // addresses serialized as Bech32 will fail assert_eq!(get_environment(), Environment::Mainnet); } + + #[test] + fn default_protocol_version() { + // If this default changes before the transition to V2 is complete, almost everything will + // break because data structures change schema and, serialization changes and hash + // derivation breaks too + assert_eq!(get_protocol_version(), ProtocolVersion::V1_6); + } } diff --git a/data_structures/src/superblock.rs b/data_structures/src/superblock.rs index ed8c2bd8f..626661a55 100644 --- a/data_structures/src/superblock.rs +++ b/data_structures/src/superblock.rs @@ -1,11 +1,3 @@ -use crate::{ - chain::{ - tapi::{after_second_hard_fork, in_emergency_period}, - AltKeys, BlockHeader, Bn256PublicKey, CheckpointBeacon, Epoch, Hash, Hashable, - PublicKeyHash, SuperBlock, SuperBlockVote, - }, - get_environment, -}; use std::{ collections::{HashMap, HashSet}, convert::{TryFrom, TryInto}, @@ -13,12 +5,20 @@ use std::{ use serde::{Deserialize, Serialize}; -use crate::proto::versioning::{ProtocolVersion, VersionedHashable}; use witnet_crypto::{ hash::{calculate_sha256, Sha256}, merkle::merkle_tree_root as crypto_merkle_tree_root, }; +use crate::{ + chain::{ + tapi::{after_second_hard_fork, in_emergency_period}, + AltKeys, BlockHeader, Bn256PublicKey, CheckpointBeacon, Epoch, Hash, Hashable, + PublicKeyHash, SuperBlock, SuperBlockVote, + }, + get_environment, +}; + /// Possible result of SuperBlockState::add_vote #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum AddSuperBlockVote { @@ -418,7 +418,6 @@ impl SuperBlockState { alt_keys: &AltKeys, sync_superblock: Option, block_epoch: Epoch, - protocol_version: ProtocolVersion, ) -> SuperBlock { let key_leaves = hash_key_leaves(&ars_identities.get_rep_ordered_bn256_list(alt_keys)); @@ -470,14 +469,13 @@ impl SuperBlockState { superblock_index, last_block_in_previous_superblock, self.signing_committee.len() as u32, - ProtocolVersion::Legacy, ) }; // update the superblock_beacon self.current_superblock_beacon = CheckpointBeacon { checkpoint: superblock_index, - hash_prev_block: superblock.versioned_hash(protocol_version), + hash_prev_block: superblock.hash(), }; let old_votes = self.votes_mempool.clear_and_remove_votes(); @@ -676,7 +674,6 @@ pub fn mining_build_superblock( index: u32, last_block_in_previous_superblock: Hash, signing_committee_length: u32, - protocol_version: ProtocolVersion, ) -> SuperBlock { let last_block = block_headers.last(); match last_block { @@ -702,7 +699,7 @@ pub fn mining_build_superblock( ) } Some(last_block_header) => { - let last_block_hash = last_block_header.versioned_hash(protocol_version); + let last_block_hash = last_block_header.hash(); let merkle_drs: Vec = block_headers .iter() .map(|b| b.merkle_roots.dr_hash_merkle_root) @@ -715,13 +712,7 @@ pub fn mining_build_superblock( let ars_root = hash_merkle_tree_root(ars_ordered_hash_leaves); let blocks: Vec<_> = block_headers .iter() - .map(|b| { - format!( - "#{}: {}", - b.beacon.checkpoint, - b.versioned_hash(protocol_version) - ) - }) + .map(|b| format!("#{}: {}", b.beacon.checkpoint, b.hash())) .collect(); log::trace!( "Created superblock #{} with hash_prev_block {}, ARS {}, signing_committee_length: {}, blocks {:?}", @@ -764,19 +755,22 @@ pub fn hash_merkle_tree_root(hashes: &[Hash]) -> Hash { #[cfg(test)] mod tests { - use super::*; + use itertools::Itertools; + + use witnet_crypto::hash::{calculate_sha256, EMPTY_SHA256}; + use crate::{ chain::{BlockMerkleRoots, Bn256SecretKey, CheckpointBeacon, PublicKey, Signature}, + proto::versioning::{ProtocolVersion, VersionedHashable}, vrf::BlockEligibilityClaim, }; - use itertools::Itertools; - use witnet_crypto::hash::{calculate_sha256, EMPTY_SHA256}; + + use super::*; #[test] fn test_superblock_creation_no_blocks() { let default_hash = Hash::default(); - let superblock = - mining_build_superblock(&[], &[], 0, default_hash, 0, ProtocolVersion::Legacy); + let superblock = mining_build_superblock(&[], &[], 0, default_hash, 0); let expected = SuperBlock::new( 0, @@ -829,19 +823,12 @@ mod tests { default_hash, dr_merkle_root_1, 0, - block.versioned_hash(ProtocolVersion::Legacy), + block.versioned_hash(ProtocolVersion::V1_6), default_hash, tally_merkle_root_1, ); - let superblock = mining_build_superblock( - &[block], - &[default_hash], - 0, - default_hash, - 1, - ProtocolVersion::Legacy, - ); + let superblock = mining_build_superblock(&[block], &[default_hash], 0, default_hash, 1); assert_eq!(superblock, expected_superblock); } @@ -904,19 +891,13 @@ mod tests { default_hash, expected_superblock_dr_root, 0, - block_2.versioned_hash(ProtocolVersion::Legacy), + block_2.versioned_hash(ProtocolVersion::V1_6), default_hash, expected_superblock_tally_root, ); - let superblock = mining_build_superblock( - &[block_1, block_2], - &[default_hash], - 0, - default_hash, - 1, - ProtocolVersion::Legacy, - ); + let superblock = + mining_build_superblock(&[block_1, block_2], &[default_hash], 0, default_hash, 1); assert_eq!(superblock, expected_superblock); } @@ -977,7 +958,6 @@ mod tests { &AltKeys::default(), None, 1, - ProtocolVersion::Legacy, ); let mut v0 = SuperBlockVote::new_unsigned(sb1.hash(), 1); @@ -1032,7 +1012,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let v1 = SuperBlockVote::new_unsigned(sb1.hash(), 0); assert_eq!( @@ -1063,7 +1042,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let expected_superblock = SuperBlock::new( @@ -1118,7 +1096,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let expected_second_superblock = SuperBlock::new( @@ -1143,7 +1120,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ), expected_second_superblock ); @@ -1188,7 +1164,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); // After building a new superblock the cache is invalidated but the previous ARS is still empty assert_eq!( @@ -1206,7 +1181,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let v1 = SuperBlockVote::new_unsigned(Hash::SHA256([2; 32]), 1); assert_eq!( @@ -1251,7 +1225,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); // The ARS included in superblock 0 is empty, so none of the superblock votes for index 1 @@ -1265,7 +1238,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); // The ARS included in superblock 1 contains only identity p1, so only its vote will be @@ -1279,7 +1251,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let mut v1 = SuperBlockVote::new_unsigned(sb2.hash(), 2); v1.secp256k1_signature.public_key = p1.clone(); @@ -1316,7 +1287,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); // The ARS included in superblock 0 is empty, so none of the superblock votes for index 1 @@ -1330,7 +1300,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let mut v2 = SuperBlockVote::new_unsigned(Hash::SHA256([2; 32]), 2); @@ -1348,7 +1317,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let mut v1 = SuperBlockVote::new_unsigned(sb2.hash(), 2); v1.secp256k1_signature.public_key = p1; @@ -1382,7 +1350,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); // The ARS included in superblock 0 is empty, so none of the superblock votes for index 1 @@ -1396,7 +1363,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); // The ARS included in superblock 1 contains only identity p1, so only its vote will be @@ -1410,7 +1376,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let mut v1 = SuperBlockVote::new_unsigned(sb2.hash(), 2); v1.secp256k1_signature.public_key = p1.clone(); @@ -1448,7 +1413,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); // The ARS included in superblock 0 is empty, so none of the superblock votes for index 1 @@ -1462,7 +1426,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); // The ARS included in superblock 1 contains only identity p1, so only its vote will be @@ -1476,7 +1439,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let mut v1 = SuperBlockVote::new_unsigned(sb2.hash(), 2); v1.secp256k1_signature.public_key = p1; @@ -1543,7 +1505,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let (v1, v2, v3) = create_votes(sb0.hash(), 0); assert_eq!( @@ -1570,7 +1531,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let (v1, v2, v3) = create_votes(sb1.hash(), 1); assert_eq!( @@ -1597,7 +1557,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let (v1, v2, v3) = create_votes(sb2.hash(), 2); assert_eq!(sbs.add_vote(&v1, 2), AddSuperBlockVote::ValidWithSameHash); @@ -1621,7 +1580,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let (v1, v2, v3) = create_votes(sb3.hash(), 3); assert_eq!( @@ -1645,7 +1603,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let (v1, v2, v3) = create_votes(sb4.hash(), 4); assert_eq!( @@ -1704,7 +1661,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let (v1, v2, v3, v4) = create_votes(sb0.hash(), 0); assert_eq!( @@ -1736,7 +1692,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let (v1, _v2, v3, v4) = create_votes(sb1.hash(), 1); let mut v2 = SuperBlockVote::new_unsigned( @@ -1766,7 +1721,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let mut v1 = SuperBlockVote::new_unsigned(sb2.hash(), 5); @@ -1834,7 +1788,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let (v1, v2, v3, v4) = create_votes(sb0.hash(), 0); assert_eq!( @@ -1864,7 +1817,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let (v1, v2, v3, v4) = create_votes(sb1.hash(), 1); assert_eq!(sbs.add_vote(&v1, 1), AddSuperBlockVote::ValidWithSameHash); @@ -1901,7 +1853,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let (v1, v2, v3, v4) = create_votes(sb2.hash(), 2); assert_eq!(sbs.add_vote(&v1, 2), AddSuperBlockVote::ValidWithSameHash); @@ -1952,7 +1903,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let expected_sb2 = mining_build_superblock( @@ -1961,7 +1911,6 @@ mod tests { 1, genesis_hash, 3, - ProtocolVersion::Legacy, ); let sb2_hash = expected_sb2.hash(); @@ -1982,7 +1931,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); assert_eq!(sb2, expected_sb2); let mut hh: HashMap<_, Vec<_>> = HashMap::new(); @@ -2008,7 +1956,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); // votes_on_each_superblock are cleared when the local superblock changes assert_eq!(sbs.votes_mempool.get_valid_votes(), HashMap::new()); @@ -2045,7 +1992,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); // superblock with index 1 let sb2 = sbs.build_superblock( @@ -2057,7 +2003,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let expected_sb2 = mining_build_superblock( @@ -2066,7 +2011,6 @@ mod tests { 1, genesis_hash, 2, - ProtocolVersion::Legacy, ); assert_eq!(sb2, expected_sb2); @@ -2124,7 +2068,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); assert_eq!(sbs.add_vote(&v0, 9), AddSuperBlockVote::MaybeValid); @@ -2154,7 +2097,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let _sb2 = sbs.build_superblock( @@ -2166,7 +2108,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); assert_eq!( @@ -2211,7 +2152,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); // superblock with index 1 let sb2 = sbs.build_superblock( @@ -2223,7 +2163,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); let expected_sb2 = mining_build_superblock( @@ -2232,7 +2171,6 @@ mod tests { 1, genesis_hash, 2, - ProtocolVersion::Legacy, ); assert_eq!(sb2, expected_sb2); @@ -2294,7 +2232,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); sbs.ars_previous_identities = ars_identities.clone(); let committee_size = 4; @@ -2340,7 +2277,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); // Signing committee size of 2 has been included @@ -2355,7 +2291,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); // SB2_A is different to SB1 and a signing committee size of 3 has been included @@ -2371,7 +2306,6 @@ mod tests { &alt_keys, Some(sb1.clone()), 1, - ProtocolVersion::Legacy, ); // SB2_B is equal to SB1 and a signing committee size of 2 has been included @@ -2417,7 +2351,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); sbs.ars_previous_identities = ars_identities; let committee_size = 4; @@ -2463,7 +2396,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); sbs.ars_previous_identities = ars_identities.clone(); let committee_size = 2; @@ -2725,7 +2657,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); // The ARS included in superblock 0 is empty, so none of the superblock votes for index 1 @@ -2739,7 +2670,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); // The ARS included in superblock 1 contains only identity p1, so only its vote will be @@ -2753,7 +2683,6 @@ mod tests { &alt_keys, None, 1, - ProtocolVersion::Legacy, ); // 2 valid votes and 3 missing votes -> Unknown diff --git a/data_structures/src/types.rs b/data_structures/src/types.rs index 6feda901e..10afcc31c 100644 --- a/data_structures/src/types.rs +++ b/data_structures/src/types.rs @@ -53,7 +53,7 @@ impl fmt::Display for Command { Command::Version(_) => f.write_str("VERSION"), Command::Block(block) => write!( f, - "BLOCK: #{}: {}", + "BLOCK #{}: {}", block.block_header.beacon.checkpoint, block.hash() ), @@ -64,7 +64,7 @@ impl fmt::Display for Command { highest_superblock_checkpoint: s, }) => write!( f, - "LAST_BEACON: Block: #{}: {} Superblock: #{}: {}", + "LAST_BEACON Block: #{}: {} Superblock: #{}: {}", h.checkpoint, h.hash_prev_block, s.checkpoint, s.hash_prev_block ), Command::Transaction(tx) => { diff --git a/data_structures/tests/serializers.rs b/data_structures/tests/serializers.rs index 28f5bfde7..8de51b1e5 100644 --- a/data_structures/tests/serializers.rs +++ b/data_structures/tests/serializers.rs @@ -418,17 +418,15 @@ fn message_block_to_bytes() { }; let expected_buf: Vec = EXAMPLE_BLOCK_VECTOR_LEGACY.to_vec(); - let result: Vec = msg.to_versioned_pb_bytes(ProtocolVersion::Legacy).unwrap(); + let result: Vec = msg.to_versioned_pb_bytes(ProtocolVersion::V1_6).unwrap(); assert_eq!(result, expected_buf); let expected_buf: Vec = EXAMPLE_BLOCK_VECTOR_TRANSITION.to_vec(); - let result: Vec = msg - .to_versioned_pb_bytes(ProtocolVersion::Transition) - .unwrap(); + let result: Vec = msg.to_versioned_pb_bytes(ProtocolVersion::V1_7).unwrap(); assert_eq!(result, expected_buf); let expected_buf: Vec = EXAMPLE_BLOCK_VECTOR_FINAL.to_vec(); - let result: Vec = msg.to_versioned_pb_bytes(ProtocolVersion::Final).unwrap(); + let result: Vec = msg.to_versioned_pb_bytes(ProtocolVersion::V2_0).unwrap(); assert_eq!(result, expected_buf); } diff --git a/node/src/actors/chain_manager/handlers.rs b/node/src/actors/chain_manager/handlers.rs index 3709276e7..710d2e93f 100644 --- a/node/src/actors/chain_manager/handlers.rs +++ b/node/src/actors/chain_manager/handlers.rs @@ -966,11 +966,17 @@ impl Handler for ChainManager { }, _, )) => { - self.sync_target = Some(SyncTarget { + let target = SyncTarget { block: consensus_beacon, superblock: superblock_consensus, - }); - log::debug!("Sync target {:?}", self.sync_target); + }; + self.sync_target = Some(target); + log::info!( + "Synchronization target has been set ({}: {})", + target.block.checkpoint, + target.block.hash_prev_block + ); + log::debug!("{:#?}", target); let our_beacon = self.get_chain_beacon(); log::debug!( @@ -996,13 +1002,18 @@ impl Handler for ChainManager { { // Fork case log::warn!( - "[CONSENSUS]: We are on {:?} but the network is on {:?}", + "[CONSENSUS]: The local chain is apparently forked.\n\ + We are on {:?} but the network is on {:?}.\n\ + The node will automatically try to recover from this forked situation by restoring the chain state from the storage.", our_beacon, consensus_beacon ); self.initialize_from_storage(ctx); - log::info!("Restored chain state from storage"); + log::info!( + "The chain state has been restored from storage.\n\ + Now the node will try to resynchronize." + ); StateMachine::WaitingConsensus } else { diff --git a/node/src/actors/chain_manager/mod.rs b/node/src/actors/chain_manager/mod.rs index 175fb4b9a..f2d6908de 100644 --- a/node/src/actors/chain_manager/mod.rs +++ b/node/src/actors/chain_manager/mod.rs @@ -70,7 +70,6 @@ use witnet_data_structures::{ }, data_request::DataRequestPool, get_environment, - proto::versioning::ProtocolVersion, radon_report::{RadonReport, ReportContext}, superblock::{ARSIdentities, AddSuperBlockVote, SuperBlockConsensus}, transaction::{RevealTransaction, TallyTransaction, Transaction}, @@ -727,8 +726,9 @@ impl ChainManager { || block.block_header.beacon.checkpoint == current_epoch + 1) { log::debug!( - "Ignoring received block #{} because its beacon is too old", - block.block_header.beacon.checkpoint + "Ignoring received block candidate because its beacon shows an old epoch ({}). The current epoch is {}.", + block.block_header.beacon.checkpoint, + current_epoch, ); return; @@ -1915,9 +1915,6 @@ impl ChainManager { &act.chain_state.alt_keys, sync_superblock, block_epoch, - // TODO: read from the right place so that this can react to the protocol - // version change during the 2.0 transition - ProtocolVersion::Legacy, ); // Put the local superblock into chain state diff --git a/validations/src/validations.rs b/validations/src/validations.rs index 8200dfccb..1c678e89f 100644 --- a/validations/src/validations.rs +++ b/validations/src/validations.rs @@ -29,6 +29,8 @@ use witnet_data_structures::{ calculate_witness_reward_before_second_hard_fork, create_tally, DataRequestPool, }, error::{BlockError, DataRequestError, TransactionError}, + get_protocol_version, + proto::versioning::ProtocolVersion, radon_report::{RadonReport, ReportContext}, transaction::{ CommitTransaction, DRTransaction, MintTransaction, RevealTransaction, StakeTransaction, @@ -1278,6 +1280,8 @@ pub fn validate_block_signature( let signature = keyed_signature.signature.clone().try_into()?; let public_key = keyed_signature.public_key.clone().try_into()?; + // TODO: take into account block epoch to decide protocol version (with regards to data + // structures and hashing) let Hash::SHA256(message) = block.hash(); add_secp_block_signature_to_verify(signatures_to_verify, &public_key, &message, &signature); @@ -1846,6 +1850,8 @@ pub fn validate_block_transactions( ); } + // TODO skip all staking logic if protocol version is legacy + // validate stake transactions in a block let mut st_mt = ProgressiveMerkleTree::sha256(); let mut st_weight: u32 = 0; @@ -1902,8 +1908,6 @@ pub fn validate_block_transactions( // } } - let st_hash_merkle_root = st_mt.root(); - let mut ut_mt = ProgressiveMerkleTree::sha256(); let mut ut_weight: u32 = 0; @@ -1939,7 +1943,12 @@ pub fn validate_block_transactions( // } } - let ut_hash_merkle_root = ut_mt.root(); + // Nullify roots for legacy protocol version + // TODO skip all staking logic if protocol version is legacy + let (st_root, ut_root) = match get_protocol_version() { + ProtocolVersion::V1_6 => Default::default(), + _ => (Hash::from(st_mt.root()), Hash::from(ut_mt.root())), + }; // Validate Merkle Root let merkle_roots = BlockMerkleRoots { @@ -1949,8 +1958,8 @@ pub fn validate_block_transactions( commit_hash_merkle_root: Hash::from(co_hash_merkle_root), reveal_hash_merkle_root: Hash::from(re_hash_merkle_root), tally_hash_merkle_root: Hash::from(ta_hash_merkle_root), - stake_hash_merkle_root: Hash::from(st_hash_merkle_root), - unstake_hash_merkle_root: Hash::from(ut_hash_merkle_root), + stake_hash_merkle_root: st_root, + unstake_hash_merkle_root: ut_root, }; if merkle_roots != block.block_header.merkle_roots {