mod helpers;
use dig_coinstore::{BlockData, Bytes32, CoinAddition, CoinId};
#[test]
fn vv_req_api_005_block_data_all_nine_fields_accessible() {
let coin = helpers::test_coin(9, 8, 7);
let coin_id: CoinId = coin.coin_id();
let addition = CoinAddition {
coin_id,
coin,
same_as_parent: true,
};
let removal_id: CoinId = helpers::test_coin(3, 4, 5).coin_id();
let hint_target: CoinId = helpers::test_coin(1, 2, 3).coin_id();
let hint_payload = helpers::filled_hash(0xEE);
let block_hash = helpers::filled_hash(0x11);
let parent_hash = helpers::filled_hash(0x22);
let expected_root = Some(helpers::filled_hash(0x33));
let block = BlockData {
height: 42,
timestamp: 1_700_000_042,
block_hash,
parent_hash,
additions: vec![addition.clone()],
removals: vec![removal_id],
coinbase_coins: vec![helpers::test_coin(5, 6, 100)],
hints: vec![(hint_target, hint_payload)],
expected_state_root: expected_root,
};
assert_eq!(block.height, 42);
assert_eq!(block.timestamp, 1_700_000_042);
assert_eq!(block.block_hash, block_hash);
assert_eq!(block.parent_hash, parent_hash);
assert_eq!(block.additions.len(), 1);
assert_eq!(block.additions[0], addition);
assert_eq!(block.removals, vec![removal_id]);
assert_eq!(block.coinbase_coins.len(), 1);
assert_eq!(block.hints.len(), 1);
assert_eq!(block.hints[0].0, hint_target);
assert_eq!(block.hints[0].1, hint_payload);
assert_eq!(block.expected_state_root, expected_root);
}
#[test]
fn vv_req_api_005_block_data_empty_hints_and_none_state_root() {
let block = BlockData {
height: 1,
timestamp: 100,
block_hash: helpers::filled_hash(0x01),
parent_hash: helpers::filled_hash(0x02),
additions: vec![],
removals: vec![],
coinbase_coins: vec![],
hints: vec![],
expected_state_root: None,
};
assert!(block.hints.is_empty());
assert!(block.expected_state_root.is_none());
}
#[test]
fn vv_req_api_005_block_data_expected_state_root_some() {
let root = helpers::filled_hash(0xC0);
let block = BlockData {
height: 2,
timestamp: 200,
block_hash: helpers::filled_hash(0x03),
parent_hash: helpers::filled_hash(0x04),
additions: vec![],
removals: vec![],
coinbase_coins: vec![],
hints: vec![],
expected_state_root: Some(root),
};
assert_eq!(block.expected_state_root, Some(root));
}
#[test]
fn vv_req_api_005_coin_addition_all_three_fields_accessible() {
let coin = helpers::test_coin(7, 8, 99);
let id = coin.coin_id();
let row = CoinAddition {
coin_id: id,
coin,
same_as_parent: false,
};
assert_eq!(row.coin_id, id);
assert_eq!(row.coin.coin_id(), id);
assert!(!row.same_as_parent);
}
#[test]
fn vv_req_api_005_coin_id_mismatch_still_constructible_until_blk_validation() {
let coin = helpers::test_coin(1, 2, 3);
let wrong_id = helpers::filled_hash(0xDE);
assert_ne!(wrong_id, coin.coin_id());
let row = CoinAddition {
coin_id: wrong_id,
coin,
same_as_parent: false,
};
assert_eq!(row.coin_id, wrong_id);
}
#[test]
fn vv_req_api_005_serde_bincode_roundtrip_block_data() {
let coin = helpers::test_coin(10, 11, 12);
let original = BlockData {
height: 99,
timestamp: 12345,
block_hash: helpers::filled_hash(0xA1),
parent_hash: helpers::filled_hash(0xA2),
additions: vec![CoinAddition {
coin_id: coin.coin_id(),
coin,
same_as_parent: true,
}],
removals: vec![helpers::test_coin(20, 21, 22).coin_id()],
coinbase_coins: vec![helpers::test_coin(30, 31, 500)],
hints: vec![(
helpers::test_coin(40, 41, 1).coin_id(),
Bytes32::from([7u8; 32]),
)],
expected_state_root: Some(helpers::filled_hash(0xB0)),
};
let bytes = bincode::serialize(&original).expect("bincode serialize BlockData");
let back: BlockData = bincode::deserialize(&bytes).expect("bincode deserialize BlockData");
assert_eq!(back, original);
}
#[test]
fn vv_req_api_005_serde_bincode_roundtrip_coin_addition() {
let coin = helpers::test_coin(50, 51, 52);
let original = CoinAddition {
coin_id: coin.coin_id(),
coin,
same_as_parent: false,
};
let bytes = bincode::serialize(&original).expect("bincode serialize CoinAddition");
let back: CoinAddition =
bincode::deserialize(&bytes).expect("bincode deserialize CoinAddition");
assert_eq!(back, original);
}