diff --git a/cycles-ledger/src/storage.rs b/cycles-ledger/src/storage.rs index 60bc604..a4bb29c 100644 --- a/cycles-ledger/src/storage.rs +++ b/cycles-ledger/src/storage.rs @@ -38,6 +38,7 @@ use serde::{Deserialize, Serialize}; use serde_bytes::ByteBuf; use std::borrow::Cow; use std::cell::RefCell; +use std::collections::BTreeMap; use std::fmt::Display; const BLOCK_LOG_INDEX_MEMORY_ID: MemoryId = MemoryId::new(1); @@ -89,7 +90,95 @@ pub struct Transaction { pub memo: Option, } +fn account_to_value(account: Account) -> Value { + let mut components = vec![Value::blob(account.owner.as_slice())]; + if let Some(sub) = account.subaccount { + components.push(Value::blob(sub)) + } + Value::Array(components) +} + impl Transaction { + pub fn to_value(self) -> Value { + let mut map = BTreeMap::new(); + if let Some(created_at_time) = self.created_at_time { + map.insert( + "ts".to_string(), + Value::Nat(candid::Nat::from(created_at_time)), + ); + } + if let Some(memo) = self.memo { + map.insert("memo".to_string(), Value::Blob(memo.0)); + } + match self.operation { + Operation::Mint { to, amount, fee } => { + map.insert("op".to_string(), Value::text("mint")); + map.insert("to".to_string(), account_to_value(to)); + map.insert("amt".to_string(), Value::Nat(candid::Nat::from(amount))); + map.insert("fee".to_string(), Value::Nat(candid::Nat::from(fee))); + } + Operation::Transfer { + from, + to, + spender, + amount, + fee, + } => { + map.insert("op".to_string(), Value::text("xfer")); + map.insert("from".to_string(), account_to_value(from)); + map.insert("to".to_string(), account_to_value(to)); + if let Some(spender) = spender { + map.insert("spender".to_string(), account_to_value(spender)); + } + map.insert("amt".to_string(), Value::Nat(candid::Nat::from(amount))); + if let Some(fee) = fee { + map.insert("fee".to_string(), Value::Nat(candid::Nat::from(fee))); + } + } + Operation::Burn { + from, + spender, + amount, + } => { + map.insert("op".to_string(), Value::text("burn")); + map.insert("from".to_string(), account_to_value(from)); + if let Some(spender) = spender { + map.insert("spender".to_string(), account_to_value(spender)); + } + map.insert("amt".to_string(), Value::Nat(candid::Nat::from(amount))); + } + Operation::Approve { + from, + spender, + amount, + expected_allowance, + expires_at, + fee, + } => { + map.insert("op".to_string(), Value::text("approve")); + map.insert("from".to_string(), account_to_value(from)); + map.insert("spender".to_string(), account_to_value(spender)); + map.insert("amt".to_string(), Value::Nat(candid::Nat::from(amount))); + if let Some(expected_allowance) = expected_allowance { + map.insert( + "expected_allowance".to_string(), + Value::Nat(candid::Nat::from(expected_allowance)), + ); + } + if let Some(expires_at) = expires_at { + map.insert( + "expires_at".to_string(), + Value::Nat(candid::Nat::from(expires_at)), + ); + } + if let Some(fee) = fee { + map.insert("fee".to_string(), Value::Nat(candid::Nat::from(fee))); + } + } + } + Value::Map(map) + } + pub fn hash(&self) -> anyhow::Result { let value = ciborium::Value::serialized(self).context(format!( "Bug: unable to convert Transaction to Ciborium Value. Transaction: {:?}", @@ -380,21 +469,27 @@ impl Block { )) } - pub fn to_value(&self) -> anyhow::Result { - let value = ciborium::Value::serialized(self).context(format!( - "Bug: unable to convert Block to Ciborium Value.\nBlock: {:?}", - self - ))?; - ciborium_to_generic_value(&value, 0).context(format!( - "Bug: unable to convert Ciborium Value to Value.\nBlock: {:?}\nValue: {:?}", - self, value - )) + pub fn to_value(self) -> Value { + let mut map = BTreeMap::new(); + map.insert("tx".to_string(), self.transaction.to_value()); + map.insert( + "ts".to_string(), + Value::Nat(candid::Nat::from(self.timestamp)), + ); + if let Some(phash) = self.phash { + map.insert("phash".to_string(), Value::blob(phash)); + } + if let Some(effective_fee) = self.effective_fee { + map.insert( + "fee".to_string(), + Value::Nat(candid::Nat::from(effective_fee)), + ); + } + Value::Map(map) } - pub fn hash(&self) -> anyhow::Result { - self.to_value() - .map(|v| v.hash()) - .context("Bug: Unable to calculate block hash") + pub fn hash(self) -> Hash { + self.to_value().hash() } } @@ -562,13 +657,13 @@ impl State { if n == 0 { return (None, hash_tree); } - let last_block_hash = blocks.get(n - 1).unwrap().hash().unwrap(); + let last_block_hash = blocks.get(n - 1).unwrap().to_owned().hash(); populate_last_block_hash_and_hash_tree(&mut hash_tree, n - 1, last_block_hash); (Some(last_block_hash), hash_tree) } pub fn emit_block(&mut self, b: Block) -> Hash { - let hash = b.hash().unwrap(); + let hash = b.clone().hash(); self.cache.phash = Some(hash); let tx_hash = b.transaction.hash().unwrap(); let created_at_time = b.transaction.created_at_time; @@ -1465,13 +1560,6 @@ fn process_transaction(transaction: Transaction, now: u64) -> Result GetBlocksResult { .get(id) .unwrap_or_else(|| panic!("Bug: unable to find block at index {}!", id)) .0 - .to_value() - .unwrap_or_else(|e| panic!("Error on block at index {}: {}", id, e)); + .to_value(); let block_with_id = BlockWithId { id: Nat::from(id), block, @@ -2309,11 +2396,12 @@ mod tests { }; use proptest::{ prelude::any, - prop_assert, prop_assert_eq, prop_compose, prop_oneof, proptest, + prop_assert_eq, prop_compose, prop_oneof, proptest, strategy::{Just, Strategy}, }; use crate::{ + ciborium_to_generic_value, config::{self, MAX_MEMO_LENGTH}, storage::{prune_approvals, to_account_key, Cbor, Operation, Transaction}, }; @@ -2446,12 +2534,21 @@ mod tests { let actual_block = Cbor::::from_bytes(cblock.to_bytes()); prop_assert_eq!(&block, &actual_block.0, "{:?}", block); - let value = block.to_value() - .expect("Unable to convert value to block"); + let value = block.clone().to_value(); let actual_block = Block::from_value(value) .expect("Unable to convert value to block"); prop_assert_eq!(&block, &actual_block, "{:?}", block); - prop_assert!(block.hash().is_ok(), "{:?}", block) + prop_assert_eq!(block.clone().hash(), actual_block.hash(), "{:?}", block); + // check the "old" hash without the FI-1247 fix + let old_value = ciborium::Value::serialized(&block).unwrap_or_else(|e| panic!( + "Bug: unable to convert Block to Ciborium Value.\nBlock: {:?}: {e:?}", + block + )); + let old_value = ciborium_to_generic_value(&old_value, 0).unwrap_or_else(|e| panic!( + "Bug: unable to convert Ciborium Value to Value.\nBlock: {:?}\nValue: {:?}: {e:?}", + block, old_value + )); + prop_assert_eq!(block.hash(), old_value.hash()); }); } @@ -2468,8 +2565,7 @@ mod tests { ..Default::default() }; proptest!(test_conf, |(block in block_strategy())| { - let value = block.to_value() - .expect("Unable to convert value to block"); + let value = block.to_value(); if let Err(err) = icrc3::schema::validate(&value) { panic!("block {} is not a valid icrc3 block. Errors:\n{}", value, err) } @@ -2544,7 +2640,7 @@ mod tests { // set the phash to create a real chain for i in 1..blocks.len() { - blocks[i].phash = Some(blocks[i-1].hash().unwrap()) + blocks[i].phash = Some(blocks[i-1].clone().hash()) } for (i, block) in blocks.iter_mut().enumerate() { diff --git a/cycles-ledger/tests/tests.rs b/cycles-ledger/tests/tests.rs index 0d30c36..14aa0c6 100644 --- a/cycles-ledger/tests/tests.rs +++ b/cycles-ledger/tests/tests.rs @@ -357,9 +357,7 @@ impl TestEnv { } fn get_block_hash(&self, block_index: Nat) -> [u8; 32] { - self.get_block(block_index) - .hash() - .expect("Unable to calculate hash of block") + self.get_block(block_index).hash() } fn number_of_blocks(&self) -> Nat { @@ -664,7 +662,7 @@ fn test_deposit_flow() { &block1, &Block { // 2.2.0 second block has the first block hash as parent hash. - phash: Some(block0.hash().unwrap()), + phash: Some(block0.hash()), // 2.2.1 effective fee of mint blocks is 0. effective_fee: Some(0), // 2.2.2 timestamp is set by the ledger. @@ -761,7 +759,7 @@ fn test_withdraw_flow() { &env.get_block(withdraw_idx.clone()), &Block { // The new block parent hash is the hash of the last deposit. - phash: Some(env.get_block(withdraw_idx - 1u8).hash().unwrap()), + phash: Some(env.get_block(withdraw_idx - 1u8).hash()), // The effective fee of a burn block created by a withdrawal // is the fee of the Ledger. This is different from burn in // other Ledgers because the operation transfers cycles. @@ -815,7 +813,7 @@ fn test_withdraw_flow() { &env.get_block(withdraw_idx.clone()), &Block { // The new block parent hash is the hash of the last deposit. - phash: Some(env.get_block(withdraw_idx - 1u8).hash().unwrap()), + phash: Some(env.get_block(withdraw_idx - 1u8).hash()), // The effective fee of a burn block created by a withdrawal // is the fee of the Ledger. This is different from burn in // other Ledgers because the operation transfers cycles. @@ -870,7 +868,7 @@ fn test_withdraw_flow() { &env.get_block(withdraw_idx.clone()), &Block { // The new block parent hash is the hash of the last deposit. - phash: Some(env.get_block(withdraw_idx - 1u8).hash().unwrap()), + phash: Some(env.get_block(withdraw_idx - 1u8).hash()), // The effective fee of a burn block created by a withdrawal // is the fee of the Ledger. This is different from burn in // other Ledgers because the operation transfers cycles. @@ -1083,7 +1081,7 @@ fn test_withdraw_fails() { let burn_block = BlockWithId { id: Nat::from(blocks.len()), block: Block { - phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash().unwrap()), + phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash()), effective_fee: Some(env.icrc1_fee()), timestamp: env.nanos_since_epoch_u64(), transaction: Transaction { @@ -1096,8 +1094,7 @@ fn test_withdraw_fails() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let refund_block = BlockWithId { id: Nat::from(blocks.len()) + 1u8, @@ -1117,8 +1114,7 @@ fn test_withdraw_fails() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let blocks = blocks .into_iter() @@ -1250,7 +1246,7 @@ fn test_withdraw_from_flow() { &env.get_block(withdraw_idx.clone()), &Block { // The new block parent hash is the hash of the last deposit. - phash: Some(env.get_block(withdraw_idx - 1u8).hash().unwrap()), + phash: Some(env.get_block(withdraw_idx - 1u8).hash()), // The effective fee of a burn block created by a withdrawal // is the fee of the ledger. This is different from burn in // other ledgers because the operation transfers cycles. @@ -1323,7 +1319,7 @@ fn test_withdraw_from_flow() { &env.get_block(withdraw_idx.clone()), &Block { // The new block parent hash is the hash of the last deposit. - phash: Some(env.get_block(withdraw_idx - 1u8).hash().unwrap()), + phash: Some(env.get_block(withdraw_idx - 1u8).hash()), // The effective fee of a burn block created by a withdrawal // is the fee of the ledger. This is different from burn in // other ledgers because the operation transfers cycles. @@ -1397,7 +1393,7 @@ fn test_withdraw_from_flow() { &env.get_block(withdraw_idx.clone()), &Block { // The new block parent hash is the hash of the last deposit. - phash: Some(env.get_block(withdraw_idx - 1u8).hash().unwrap()), + phash: Some(env.get_block(withdraw_idx - 1u8).hash()), // The effective fee of a burn block created by a withdrawal // is the fee of the ledger. This is different from burn in // other ledgers because the operation transfers cycles. @@ -1470,7 +1466,7 @@ fn test_withdraw_from_flow() { &env.get_block(withdraw_idx.clone()), &Block { // The new block parent hash is the hash of the last deposit. - phash: Some(env.get_block(withdraw_idx - 1u8).hash().unwrap()), + phash: Some(env.get_block(withdraw_idx - 1u8).hash()), // The effective fee of a burn block created by a withdrawal // is the fee of the ledger. This is different from burn in // other ledgers because the operation transfers cycles. @@ -1735,7 +1731,7 @@ fn test_withdraw_from_fails() { let burn_block = BlockWithId { id: Nat::from(blocks.len()), block: Block { - phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash().unwrap()), + phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash()), effective_fee: Some(env.icrc1_fee()), timestamp: env.nanos_since_epoch_u64(), transaction: Transaction { @@ -1748,8 +1744,7 @@ fn test_withdraw_from_fails() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let refund_block = BlockWithId { id: Nat::from(blocks.len()) + 1u8, @@ -1767,8 +1762,7 @@ fn test_withdraw_from_fails() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let approve_refund_block = BlockWithId { id: Nat::from(blocks.len()) + 2u8, @@ -1789,8 +1783,7 @@ fn test_withdraw_from_fails() { memo: Some(Memo(ByteBuf::from(PENALIZE_MEMO))), }, } - .to_value() - .unwrap(), + .to_value(), }; let blocks = blocks .into_iter() @@ -1856,7 +1849,7 @@ fn test_withdraw_from_fails() { let burn_block = BlockWithId { id: Nat::from(blocks.len()), block: Block { - phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash().unwrap()), + phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash()), effective_fee: Some(env.icrc1_fee()), timestamp: env.nanos_since_epoch_u64(), transaction: Transaction { @@ -1869,8 +1862,7 @@ fn test_withdraw_from_fails() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let refund_block = BlockWithId { id: Nat::from(blocks.len()) + 1u8, @@ -1888,8 +1880,7 @@ fn test_withdraw_from_fails() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let blocks = blocks .into_iter() @@ -1955,7 +1946,7 @@ fn test_withdraw_from_fails() { let burn_block = BlockWithId { id: Nat::from(blocks.len()), block: Block { - phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash().unwrap()), + phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash()), effective_fee: Some(env.icrc1_fee()), timestamp: env.nanos_since_epoch_u64(), transaction: Transaction { @@ -1968,8 +1959,7 @@ fn test_withdraw_from_fails() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let refund_block = BlockWithId { id: Nat::from(blocks.len()) + 1u8, @@ -1987,8 +1977,7 @@ fn test_withdraw_from_fails() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let blocks = blocks .into_iter() @@ -2089,7 +2078,7 @@ fn test_withdraw_from_fails() { let burn_block = BlockWithId { id: Nat::from(blocks.len()), block: Block { - phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash().unwrap()), + phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash()), effective_fee: Some(env.icrc1_fee()), timestamp: env.nanos_since_epoch_u64(), transaction: Transaction { @@ -2102,8 +2091,7 @@ fn test_withdraw_from_fails() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let refund_block = BlockWithId { id: Nat::from(blocks.len()) + 1u8, @@ -2121,8 +2109,7 @@ fn test_withdraw_from_fails() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let approve_refund_block = BlockWithId { id: Nat::from(blocks.len()) + 2u8, @@ -2143,8 +2130,7 @@ fn test_withdraw_from_fails() { memo: Some(Memo(ByteBuf::from(PENALIZE_MEMO))), }, } - .to_value() - .unwrap(), + .to_value(), }; let blocks = blocks .into_iter() @@ -2206,7 +2192,7 @@ fn test_withdraw_from_fails() { let burn_block = BlockWithId { id: Nat::from(blocks.len()), block: Block { - phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash().unwrap()), + phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash()), effective_fee: Some(env.icrc1_fee()), timestamp: env.nanos_since_epoch_u64(), transaction: Transaction { @@ -2219,8 +2205,7 @@ fn test_withdraw_from_fails() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let blocks = blocks.into_iter().chain([burn_block]).collect::>(); assert_vec_display_eq(blocks, env.get_all_blocks_with_ids()); @@ -2638,7 +2623,7 @@ fn test_icrc1_transfer_ok_with_params( memo: args_memo, }, timestamp: env.nanos_since_epoch_u64(), - phash: Some(env.get_block(block_index - 1u8).hash().unwrap()), + phash: Some(env.get_block(block_index - 1u8).hash()), effective_fee: args_fee.xor(Some(fee)), }; expected_blocks.push(expected_new_block); @@ -3131,7 +3116,7 @@ fn test_icrc2_approve_ok_with_params( memo: args_memo, }, timestamp: env.nanos_since_epoch_u64(), - phash: Some(env.get_block(block_index - 1u8).hash().unwrap()), + phash: Some(env.get_block(block_index - 1u8).hash()), effective_fee: args_fee.xor(Some(fee)), }; expected_blocks.push(expected_new_block); @@ -3691,7 +3676,7 @@ fn test_icrc2_transfer_from_ok_with_params( memo: args_memo, }, timestamp: env.nanos_since_epoch_u64(), - phash: Some(env.get_block(block_index - 1u8).hash().unwrap()), + phash: Some(env.get_block(block_index - 1u8).hash()), effective_fee: args_fee.xor(Some(fee)), }; expected_blocks.push(expected_new_block); @@ -4514,7 +4499,7 @@ fn test_icrc3_get_blocks() { // i.e., the timestamp the ledger wrote in the real block. This is required // so that we can use the hash of the block as the parent hash. block0.timestamp = actual_blocks[0].1.timestamp; - env.validate_certificate(0, block0.hash().unwrap()); + env.validate_certificate(0, block0.clone().hash()); // add a second mint block env.deposit(account2, 3_000_000_000 + fee, None); @@ -4530,7 +4515,7 @@ fn test_icrc3_get_blocks() { }, None, None, - Some(block0.hash().unwrap()), + Some(block0.clone().hash()), ); let actual_blocks = decode_blocks_with_ids(get_blocks_res.blocks); let expected_blocks = vec![(0, block0.clone()), (1, block1.clone())]; @@ -4539,7 +4524,7 @@ fn test_icrc3_get_blocks() { // i.e., the timestamp the ledger wrote in the real block. This is required // so that we can use the hash of the block as the parent hash. block1.timestamp = actual_blocks[1].1.timestamp; - env.validate_certificate(1, block1.hash().unwrap()); + env.validate_certificate(1, block1.clone().hash()); // check retrieving a subset of the transactions let get_blocks_res = env.icrc3_get_blocks(vec![(0u64, 1u64)]); @@ -4574,7 +4559,7 @@ fn test_icrc3_get_blocks() { }, None, Some(withdraw_memo), - Some(block1.hash().unwrap()), + Some(block1.clone().hash()), ); let actual_blocks = decode_blocks_with_ids(get_blocks_res.blocks); let expected_blocks = vec![ @@ -4587,7 +4572,7 @@ fn test_icrc3_get_blocks() { // i.e., the timestamp the ledger wrote in the real block. This is required // so that we can use the hash of the block as the parent hash. block2.timestamp = actual_blocks[2].1.timestamp; - env.validate_certificate(2, block2.hash().unwrap()); + env.validate_certificate(2, block2.clone().hash()); // add a couple of blocks let _block_index = env @@ -4645,7 +4630,7 @@ fn test_icrc3_get_blocks() { }, None, None, - Some(block2.hash().unwrap()), + Some(block2.clone().hash()), ); let block4 = block( Approve { @@ -4658,7 +4643,7 @@ fn test_icrc3_get_blocks() { }, None, None, - Some(actual_blocks[3].1.hash().unwrap()), + Some(actual_blocks[3].1.clone().hash()), ); let mut block5 = block( Transfer { @@ -4670,7 +4655,7 @@ fn test_icrc3_get_blocks() { }, None, None, - Some(actual_blocks[4].1.hash().unwrap()), + Some(actual_blocks[4].1.clone().hash()), ); let expected_blocks = vec![ (0, block0.clone()), @@ -4685,7 +4670,7 @@ fn test_icrc3_get_blocks() { // i.e., the timestamp the ledger wrote in the real block. This is required // so that we can use the hash of the block as the parent hash. block5.timestamp = actual_blocks[5].1.timestamp; - env.validate_certificate(5, block5.hash().unwrap()); + env.validate_certificate(5, block5.hash()); } // Checks two lists of blocks are the same. @@ -5447,7 +5432,7 @@ fn test_create_canister_fail() { let burn_block = BlockWithId { id: Nat::from(blocks.len()), block: Block { - phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash().unwrap()), + phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash()), effective_fee: Some(fee), timestamp: env.nanos_since_epoch_u64(), transaction: Transaction { @@ -5460,8 +5445,7 @@ fn test_create_canister_fail() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let blocks = blocks.into_iter().chain([burn_block]).collect::>(); assert_vec_display_eq(&blocks, env.get_all_blocks_with_ids()); @@ -5508,7 +5492,7 @@ fn test_create_canister_fail() { let burn_block = BlockWithId { id: Nat::from(blocks.len()), block: Block { - phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash().unwrap()), + phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash()), effective_fee: Some(fee), timestamp: env.nanos_since_epoch_u64(), transaction: Transaction { @@ -5521,8 +5505,7 @@ fn test_create_canister_fail() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let refund_block = BlockWithId { id: Nat::from(blocks.len() + 1), @@ -5540,8 +5523,7 @@ fn test_create_canister_fail() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let blocks = blocks .into_iter() @@ -5619,7 +5601,7 @@ fn test_create_canister_from() { &env.get_block(block_id.clone()), &Block { // The new block parent hash is the hash of the last deposit. - phash: Some(env.get_block(block_id - 1u8).hash().unwrap()), + phash: Some(env.get_block(block_id - 1u8).hash()), // The effective fee of a burn block created by a withdrawal // is the fee of the ledger. This is different from burn in // other ledgers because the operation transfers cycles. @@ -5703,7 +5685,7 @@ fn test_create_canister_from() { &env.get_block(block_id.clone()), &Block { // The new block parent hash is the hash of the last deposit. - phash: Some(env.get_block(block_id - 1u8).hash().unwrap()), + phash: Some(env.get_block(block_id - 1u8).hash()), // The effective fee of a burn block created by a withdrawal // is the fee of the ledger. This is different from burn in // other ledgers because the operation transfers cycles. @@ -5768,7 +5750,7 @@ fn test_create_canister_from() { &env.get_block(block_id.clone()), &Block { // The new block parent hash is the hash of the last deposit. - phash: Some(env.get_block(block_id - 1u8).hash().unwrap()), + phash: Some(env.get_block(block_id - 1u8).hash()), // The effective fee of a burn block created by a withdrawal // is the fee of the ledger. This is different from burn in // other ledgers because the operation transfers cycles. @@ -5834,7 +5816,7 @@ fn test_create_canister_from() { &env.get_block(block_id.clone()), &Block { // The new block parent hash is the hash of the last deposit. - phash: Some(env.get_block(block_id - 1u8).hash().unwrap()), + phash: Some(env.get_block(block_id - 1u8).hash()), // The effective fee of a burn block created by a withdrawal // is the fee of the ledger. This is different from burn in // other ledgers because the operation transfers cycles. @@ -5899,7 +5881,7 @@ fn test_create_canister_from() { &env.get_block(block_id.clone()), &Block { // The new block parent hash is the hash of the last deposit. - phash: Some(env.get_block(block_id - 1u8).hash().unwrap()), + phash: Some(env.get_block(block_id - 1u8).hash()), // The effective fee of a burn block created by a withdrawal // is the fee of the ledger. This is different from burn in // other ledgers because the operation transfers cycles. @@ -6055,7 +6037,7 @@ fn test_create_canister_from_fail() { let burn_block = BlockWithId { id: Nat::from(blocks.len()), block: Block { - phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash().unwrap()), + phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash()), effective_fee: Some(FEE), timestamp: env.nanos_since_epoch_u64(), transaction: Transaction { @@ -6068,8 +6050,7 @@ fn test_create_canister_from_fail() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let blocks = blocks.into_iter().chain([burn_block]).collect::>(); assert_vec_display_eq(blocks, env.get_all_blocks_with_ids()); @@ -6134,7 +6115,7 @@ fn test_create_canister_from_fail() { let burn_block = BlockWithId { id: Nat::from(blocks.len()), block: Block { - phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash().unwrap()), + phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash()), effective_fee: Some(FEE), timestamp: env.nanos_since_epoch_u64(), transaction: Transaction { @@ -6147,8 +6128,7 @@ fn test_create_canister_from_fail() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let refund_block = BlockWithId { id: Nat::from(blocks.len() + 1), @@ -6166,8 +6146,7 @@ fn test_create_canister_from_fail() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let blocks = blocks .into_iter() @@ -6236,7 +6215,7 @@ fn test_create_canister_from_fail() { let burn_block = BlockWithId { id: Nat::from(blocks.len()), block: Block { - phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash().unwrap()), + phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash()), effective_fee: Some(FEE), timestamp: env.nanos_since_epoch_u64(), transaction: Transaction { @@ -6249,8 +6228,7 @@ fn test_create_canister_from_fail() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let refund_block = BlockWithId { id: Nat::from(blocks.len() + 1), @@ -6268,8 +6246,7 @@ fn test_create_canister_from_fail() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let approval_refund_block = BlockWithId { id: Nat::from(blocks.len() + 2), @@ -6290,8 +6267,7 @@ fn test_create_canister_from_fail() { memo: Some(Memo(ByteBuf::from(PENALIZE_MEMO))), }, } - .to_value() - .unwrap(), + .to_value(), }; let blocks = blocks .into_iter() @@ -6354,7 +6330,7 @@ fn test_create_canister_from_fail() { &env.get_block(block_id.clone()), &Block { // The new block parent hash is the hash of the last deposit. - phash: Some(env.get_block(block_id - 1u8).hash().unwrap()), + phash: Some(env.get_block(block_id - 1u8).hash()), // The effective fee of a burn block created by a withdrawal // is the fee of the ledger. This is different from burn in // other ledgers because the operation transfers cycles. @@ -6434,7 +6410,7 @@ fn test_create_canister_from_fail() { assert_eq!(env.icrc1_total_supply(), expected_total_supply); assert_eq!(blocks.len() + 3, env.number_of_blocks()); let approval_refund_block = Block { - phash: Some(env.get_block(Nat::from(blocks.len() + 1)).hash().unwrap()), + phash: Some(env.get_block(Nat::from(blocks.len() + 1)).hash()), effective_fee: Some(env.icrc1_fee()), timestamp: env.nanos_since_epoch_u64(), transaction: Transaction { @@ -6514,7 +6490,7 @@ fn test_create_canister_from_fail() { let burn_block = BlockWithId { id: Nat::from(blocks.len()), block: Block { - phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash().unwrap()), + phash: Some(env.get_block(Nat::from(blocks.len()) - 1u8).hash()), effective_fee: Some(FEE), timestamp: env.nanos_since_epoch_u64(), transaction: Transaction { @@ -6527,8 +6503,7 @@ fn test_create_canister_from_fail() { }, }, } - .to_value() - .unwrap(), + .to_value(), }; let blocks = blocks.into_iter().chain([burn_block]).collect::>(); assert_vec_display_eq(blocks, env.get_all_blocks_with_ids());