Skip to content

Commit

Permalink
adds test for issuance check
Browse files Browse the repository at this point in the history
  • Loading branch information
arya2 committed Nov 16, 2024
1 parent 3f7e68a commit 62bfef3
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 8 deletions.
4 changes: 2 additions & 2 deletions zebra-chain/src/orchard_zsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion zebra-chain/src/orchard_zsa/tests.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
#[cfg(test)]
mod issuance;
mod vectors;

pub mod vectors;
10 changes: 8 additions & 2 deletions zebra-chain/src/orchard_zsa/tests/issuance.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
16 changes: 16 additions & 0 deletions zebra-chain/src/orchard_zsa/tests/vectors.rs
Original file line number Diff line number Diff line change
@@ -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")
}
4 changes: 1 addition & 3 deletions zebra-state/src/service/check/issuance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
3 changes: 3 additions & 0 deletions zebra-state/src/service/check/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ mod anchors;
mod nullifier;
mod utxo;
mod vectors;

#[cfg(feature = "tx-v6")]
mod issuance;
83 changes: 83 additions & 0 deletions zebra-state/src/service/check/tests/issuance.rs
Original file line number Diff line number Diff line change
@@ -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"
);
}

0 comments on commit 62bfef3

Please sign in to comment.