adds test for issuance check
This commit is contained in:
parent
3f7e68af69
commit
62bfef3fe0
|
@ -4,8 +4,8 @@
|
|||
#[cfg(any(test, feature = "proptest-impl"))]
|
||||
pub(crate) mod arbitrary;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
#[cfg(any(test, feature = "proptest-impl"))]
|
||||
pub mod tests;
|
||||
|
||||
mod asset_state;
|
||||
mod burn;
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
#[cfg(test)]
|
||||
mod issuance;
|
||||
mod vectors;
|
||||
|
||||
pub mod vectors;
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
use crate::{block::Block, serialization::ZcashDeserialize, transaction::Transaction};
|
||||
use crate::{
|
||||
block::Block, orchard_zsa::IssuedAssetsChange, serialization::ZcashDeserialize,
|
||||
transaction::Transaction,
|
||||
};
|
||||
|
||||
use super::vectors::BLOCKS;
|
||||
|
||||
#[test]
|
||||
fn issuance_block() {
|
||||
let issuance_block =
|
||||
Block::zcash_deserialize(BLOCKS[0].as_ref()).expect("issuance block should deserialize");
|
||||
Block::zcash_deserialize(BLOCKS[0]).expect("issuance block should deserialize");
|
||||
|
||||
IssuedAssetsChange::from_transactions(&issuance_block.transactions)
|
||||
.expect("issuance in block should be valid");
|
||||
|
||||
for transaction in issuance_block.transactions {
|
||||
if let Transaction::V6 {
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
mod blocks;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub(crate) use blocks::BLOCKS;
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::{block::Block, serialization::ZcashDeserializeInto};
|
||||
|
||||
// TODO: Move this to zebra-test.
|
||||
pub fn valid_issuance_blocks() -> Vec<Arc<Block>> {
|
||||
BLOCKS
|
||||
.iter()
|
||||
.copied()
|
||||
.map(ZcashDeserializeInto::zcash_deserialize_into)
|
||||
.map(|result| result.map(Arc::new))
|
||||
.try_collect()
|
||||
.expect("hard-coded block data must deserialize successfully")
|
||||
}
|
||||
|
|
|
@ -59,9 +59,7 @@ pub fn valid_burns_and_issuance(
|
|||
.apply_change(change)
|
||||
.ok_or(ValidateContextError::InvalidIssuance)?;
|
||||
|
||||
issued_assets
|
||||
.insert(asset_base, updated_asset_state)
|
||||
.expect("transactions must have only one burn item per asset base");
|
||||
issued_assets.insert(asset_base, updated_asset_state);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,3 +4,6 @@ mod anchors;
|
|||
mod nullifier;
|
||||
mod utxo;
|
||||
mod vectors;
|
||||
|
||||
#[cfg(feature = "tx-v6")]
|
||||
mod issuance;
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use zebra_chain::{
|
||||
block::{self, genesis::regtest_genesis_block, Block},
|
||||
orchard_zsa::{tests::vectors::valid_issuance_blocks, IssuedAssets},
|
||||
parameters::Network,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
check::{self, Chain},
|
||||
service::{finalized_state::FinalizedState, write::validate_and_commit_non_finalized},
|
||||
CheckpointVerifiedBlock, Config, NonFinalizedState,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn check_burns_and_issuance() {
|
||||
let _init_guard = zebra_test::init();
|
||||
|
||||
let network = Network::new_regtest(Some(1), None, Some(1));
|
||||
|
||||
let mut finalized_state = FinalizedState::new_with_debug(
|
||||
&Config::ephemeral(),
|
||||
&network,
|
||||
true,
|
||||
#[cfg(feature = "elasticsearch")]
|
||||
false,
|
||||
false,
|
||||
);
|
||||
|
||||
let mut non_finalized_state = NonFinalizedState::new(&network);
|
||||
|
||||
let regtest_genesis_block = regtest_genesis_block();
|
||||
let regtest_genesis_hash = regtest_genesis_block.hash();
|
||||
|
||||
finalized_state
|
||||
.commit_finalized_direct(regtest_genesis_block.into(), None, "test")
|
||||
.expect("unexpected invalid genesis block test vector");
|
||||
|
||||
let block = valid_issuance_blocks().first().unwrap().clone();
|
||||
let mut header = Arc::<block::Header>::unwrap_or_clone(block.header.clone());
|
||||
header.previous_block_hash = regtest_genesis_hash;
|
||||
header.commitment_bytes = [0; 32].into();
|
||||
let block = Arc::new(Block {
|
||||
header: Arc::new(header),
|
||||
transactions: block.transactions.clone(),
|
||||
});
|
||||
|
||||
let CheckpointVerifiedBlock(block) = CheckpointVerifiedBlock::new(block, None, None)
|
||||
.expect("semantic validation of issued assets changes should pass");
|
||||
|
||||
let empty_chain = Chain::new(
|
||||
&network,
|
||||
finalized_state
|
||||
.db
|
||||
.finalized_tip_height()
|
||||
.unwrap_or(block::Height::MIN),
|
||||
finalized_state.db.sprout_tree_for_tip(),
|
||||
finalized_state.db.sapling_tree_for_tip(),
|
||||
finalized_state.db.orchard_tree_for_tip(),
|
||||
finalized_state.db.history_tree(),
|
||||
finalized_state.db.finalized_value_pool(),
|
||||
);
|
||||
|
||||
let block_1_issued_assets = check::issuance::valid_burns_and_issuance(
|
||||
&finalized_state.db,
|
||||
&Arc::new(empty_chain),
|
||||
&block,
|
||||
)
|
||||
.expect("test transactions should be valid");
|
||||
|
||||
validate_and_commit_non_finalized(&finalized_state.db, &mut non_finalized_state, block)
|
||||
.expect("validation should succeed");
|
||||
|
||||
let best_chain = non_finalized_state
|
||||
.best_chain()
|
||||
.expect("should have a non-finalized chain");
|
||||
|
||||
assert_eq!(
|
||||
IssuedAssets::from(best_chain.issued_assets.clone()),
|
||||
block_1_issued_assets,
|
||||
"issued assets for chain should match those of block 1"
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue