panic in `NonFinalizedState::commit_block` before Canopy (#1909)
* add a panic in commit_block() for blocks before canopy * update tests to use a post canopy block and network Co-authored-by: teor <teor@riseup.net>
This commit is contained in:
parent
d49eaab68e
commit
9e1662d2d7
|
@ -64,7 +64,10 @@ impl StateService {
|
|||
|
||||
pub fn new(config: Config, network: Network) -> Self {
|
||||
let disk = FinalizedState::new(&config, network);
|
||||
let mem = NonFinalizedState::default();
|
||||
let mem = NonFinalizedState {
|
||||
network,
|
||||
..Default::default()
|
||||
};
|
||||
let queued_blocks = QueuedBlocks::default();
|
||||
let pending_utxos = PendingUtxos::default();
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ use std::{collections::BTreeSet, mem, ops::Deref, sync::Arc};
|
|||
|
||||
use zebra_chain::{
|
||||
block::{self, Block},
|
||||
parameters::{Network, NetworkUpgrade::Canopy},
|
||||
transaction::{self, Transaction},
|
||||
transparent,
|
||||
};
|
||||
|
@ -25,7 +26,9 @@ pub struct NonFinalizedState {
|
|||
/// Verified, non-finalized chains, in ascending order.
|
||||
///
|
||||
/// The best chain is `chain_set.last()` or `chain_set.iter().next_back()`.
|
||||
chain_set: BTreeSet<Box<Chain>>,
|
||||
pub chain_set: BTreeSet<Box<Chain>>,
|
||||
/// The configured Zcash network
|
||||
pub network: Network,
|
||||
}
|
||||
|
||||
impl NonFinalizedState {
|
||||
|
@ -70,6 +73,14 @@ impl NonFinalizedState {
|
|||
/// Commit block to the non-finalized state.
|
||||
pub fn commit_block(&mut self, prepared: PreparedBlock) {
|
||||
let parent_hash = prepared.block.header.previous_block_hash;
|
||||
let (height, hash) = (prepared.height, prepared.hash);
|
||||
|
||||
let canopy_activation_height = Canopy.activation_height(self.network).unwrap();
|
||||
if height < canopy_activation_height {
|
||||
panic!(
|
||||
"invalid non-finalized block height: the canopy checkpoint is mandatory, pre-canopy blocks must be committed to the state as finalized blocks"
|
||||
);
|
||||
}
|
||||
|
||||
let mut parent_chain = self
|
||||
.take_chain_if(|chain| chain.non_finalized_tip_hash() == parent_hash)
|
||||
|
@ -81,7 +92,6 @@ impl NonFinalizedState {
|
|||
})
|
||||
.expect("commit_block is only called with blocks that are ready to be commited");
|
||||
|
||||
let (height, hash) = (prepared.height, prepared.hash);
|
||||
parent_chain.push(prepared);
|
||||
self.chain_set.insert(parent_chain);
|
||||
self.update_metrics_for_committed_block(height, hash);
|
||||
|
@ -276,8 +286,22 @@ mod tests {
|
|||
fn best_chain_wins() -> Result<()> {
|
||||
zebra_test::init();
|
||||
|
||||
let block1: Arc<Block> =
|
||||
zebra_test::vectors::BLOCK_MAINNET_419200_BYTES.zcash_deserialize_into()?;
|
||||
best_chain_wins_for_network(Network::Mainnet)?;
|
||||
best_chain_wins_for_network(Network::Testnet)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn best_chain_wins_for_network(network: Network) -> Result<()> {
|
||||
let block1: Arc<Block> = match network {
|
||||
Network::Mainnet => {
|
||||
zebra_test::vectors::BLOCK_MAINNET_1180900_BYTES.zcash_deserialize_into()?
|
||||
}
|
||||
Network::Testnet => {
|
||||
zebra_test::vectors::BLOCK_TESTNET_1326100_BYTES.zcash_deserialize_into()?
|
||||
}
|
||||
};
|
||||
|
||||
let block2 = block1.make_fake_child().set_work(10);
|
||||
let child = block1.make_fake_child().set_work(1);
|
||||
|
||||
|
@ -297,8 +321,22 @@ mod tests {
|
|||
fn finalize_pops_from_best_chain() -> Result<()> {
|
||||
zebra_test::init();
|
||||
|
||||
let block1: Arc<Block> =
|
||||
zebra_test::vectors::BLOCK_MAINNET_419200_BYTES.zcash_deserialize_into()?;
|
||||
finalize_pops_from_best_chain_for_network(Network::Mainnet)?;
|
||||
finalize_pops_from_best_chain_for_network(Network::Testnet)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn finalize_pops_from_best_chain_for_network(network: Network) -> Result<()> {
|
||||
let block1: Arc<Block> = match network {
|
||||
Network::Mainnet => {
|
||||
zebra_test::vectors::BLOCK_MAINNET_1180900_BYTES.zcash_deserialize_into()?
|
||||
}
|
||||
Network::Testnet => {
|
||||
zebra_test::vectors::BLOCK_TESTNET_1326100_BYTES.zcash_deserialize_into()?
|
||||
}
|
||||
};
|
||||
|
||||
let block2 = block1.make_fake_child().set_work(10);
|
||||
let child = block1.make_fake_child().set_work(1);
|
||||
|
||||
|
@ -323,8 +361,24 @@ mod tests {
|
|||
fn commit_block_extending_best_chain_doesnt_drop_worst_chains() -> Result<()> {
|
||||
zebra_test::init();
|
||||
|
||||
let block1: Arc<Block> =
|
||||
zebra_test::vectors::BLOCK_MAINNET_419200_BYTES.zcash_deserialize_into()?;
|
||||
commit_block_extending_best_chain_doesnt_drop_worst_chains_for_network(Network::Mainnet)?;
|
||||
commit_block_extending_best_chain_doesnt_drop_worst_chains_for_network(Network::Testnet)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn commit_block_extending_best_chain_doesnt_drop_worst_chains_for_network(
|
||||
network: Network,
|
||||
) -> Result<()> {
|
||||
let block1: Arc<Block> = match network {
|
||||
Network::Mainnet => {
|
||||
zebra_test::vectors::BLOCK_MAINNET_1180900_BYTES.zcash_deserialize_into()?
|
||||
}
|
||||
Network::Testnet => {
|
||||
zebra_test::vectors::BLOCK_TESTNET_1326100_BYTES.zcash_deserialize_into()?
|
||||
}
|
||||
};
|
||||
|
||||
let block2 = block1.make_fake_child().set_work(10);
|
||||
let child1 = block1.make_fake_child().set_work(1);
|
||||
let child2 = block2.make_fake_child().set_work(1);
|
||||
|
@ -347,8 +401,21 @@ mod tests {
|
|||
fn shorter_chain_can_be_best_chain() -> Result<()> {
|
||||
zebra_test::init();
|
||||
|
||||
let block1: Arc<Block> =
|
||||
zebra_test::vectors::BLOCK_MAINNET_419200_BYTES.zcash_deserialize_into()?;
|
||||
shorter_chain_can_be_best_chain_for_network(Network::Mainnet)?;
|
||||
shorter_chain_can_be_best_chain_for_network(Network::Testnet)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn shorter_chain_can_be_best_chain_for_network(network: Network) -> Result<()> {
|
||||
let block1: Arc<Block> = match network {
|
||||
Network::Mainnet => {
|
||||
zebra_test::vectors::BLOCK_MAINNET_1180900_BYTES.zcash_deserialize_into()?
|
||||
}
|
||||
Network::Testnet => {
|
||||
zebra_test::vectors::BLOCK_TESTNET_1326100_BYTES.zcash_deserialize_into()?
|
||||
}
|
||||
};
|
||||
|
||||
let long_chain_block1 = block1.make_fake_child().set_work(1);
|
||||
let long_chain_block2 = long_chain_block1.make_fake_child().set_work(1);
|
||||
|
@ -371,8 +438,21 @@ mod tests {
|
|||
fn longer_chain_with_more_work_wins() -> Result<()> {
|
||||
zebra_test::init();
|
||||
|
||||
let block1: Arc<Block> =
|
||||
zebra_test::vectors::BLOCK_MAINNET_419200_BYTES.zcash_deserialize_into()?;
|
||||
longer_chain_with_more_work_wins_for_network(Network::Mainnet)?;
|
||||
longer_chain_with_more_work_wins_for_network(Network::Testnet)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn longer_chain_with_more_work_wins_for_network(network: Network) -> Result<()> {
|
||||
let block1: Arc<Block> = match network {
|
||||
Network::Mainnet => {
|
||||
zebra_test::vectors::BLOCK_MAINNET_1180900_BYTES.zcash_deserialize_into()?
|
||||
}
|
||||
Network::Testnet => {
|
||||
zebra_test::vectors::BLOCK_TESTNET_1326100_BYTES.zcash_deserialize_into()?
|
||||
}
|
||||
};
|
||||
|
||||
let long_chain_block1 = block1.make_fake_child().set_work(1);
|
||||
let long_chain_block2 = long_chain_block1.make_fake_child().set_work(1);
|
||||
|
@ -399,8 +479,20 @@ mod tests {
|
|||
fn equal_length_goes_to_more_work() -> Result<()> {
|
||||
zebra_test::init();
|
||||
|
||||
let block1: Arc<Block> =
|
||||
zebra_test::vectors::BLOCK_MAINNET_419200_BYTES.zcash_deserialize_into()?;
|
||||
equal_length_goes_to_more_work_for_network(Network::Mainnet)?;
|
||||
equal_length_goes_to_more_work_for_network(Network::Testnet)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
fn equal_length_goes_to_more_work_for_network(network: Network) -> Result<()> {
|
||||
let block1: Arc<Block> = match network {
|
||||
Network::Mainnet => {
|
||||
zebra_test::vectors::BLOCK_MAINNET_1180900_BYTES.zcash_deserialize_into()?
|
||||
}
|
||||
Network::Testnet => {
|
||||
zebra_test::vectors::BLOCK_TESTNET_1326100_BYTES.zcash_deserialize_into()?
|
||||
}
|
||||
};
|
||||
|
||||
let less_work_child = block1.make_fake_child().set_work(1);
|
||||
let more_work_child = block1.make_fake_child().set_work(3);
|
||||
|
|
Loading…
Reference in New Issue