// Backs the hand-built state/diff helpers below, which are compiled only for `common`'s own // unit tests. They rely on `lee::test_utils`, gated behind `lee`'s `test-utils` feature and // enabled here via dev-dependencies, so it never reaches a production build. #[cfg(test)] use std::collections::HashMap; use lee::AccountId; #[cfg(test)] use lee::{Account, PrivateKey, PublicKey, V03State, ValidatedStateDiff}; use crate::{ HashType, block::{Block, HashableBlockData}, transaction::{LeeTransaction, clock_invocation}, }; // Helpers #[must_use] pub fn sequencer_sign_key_for_testing() -> lee::PrivateKey { lee::PrivateKey::try_new([37; 32]).unwrap() } /// A syntactically valid `Public` transaction. Its contents are irrelevant to the /// bridge guard, which only branches on the transaction *variant* and the diff. #[cfg(test)] #[must_use] pub fn any_public_transaction() -> LeeTransaction { let sender_key = PrivateKey::try_new([9_u8; 32]).expect("valid key"); let sender_id = AccountId::from(&PublicKey::new_from_private_key(&sender_key)); let recipient_key = PrivateKey::try_new([8_u8; 32]).expect("valid key"); let recipient_id = AccountId::from(&PublicKey::new_from_private_key(&recipient_key)); create_transaction_native_token_transfer(sender_id, 0, recipient_id, 1, &sender_key) } /// Builds a state whose only entry is `account_id` (set to `pre`) and a single-entry diff /// that maps `account_id` to `post`, so the validation guards can be exercised in isolation. #[cfg(test)] #[must_use] pub fn state_and_diff( account_id: AccountId, pre: Account, post: Account, ) -> (V03State, ValidatedStateDiff) { let state = V03State::new().with_public_accounts([(account_id, pre)]); let diff = lee::test_utils::validated_state_diff_from_public_diff(HashMap::from([(account_id, post)])); (state, diff) } // Dummy producers /// Produce dummy block with provided transactions + clock transaction an the end. /// /// `id` - block id, provide zero for genesis. /// /// `prev_hash` - hash of previous block, provide None for genesis. /// /// `transactions` - vector of `EncodedTransaction` objects. #[must_use] pub fn produce_dummy_block( id: u64, prev_hash: Option, mut transactions: Vec, ) -> Block { transactions.push(LeeTransaction::Public(clock_invocation( id.saturating_mul(100), ))); let block_data = HashableBlockData { block_id: id, prev_block_hash: prev_hash.unwrap_or_default(), timestamp: id.saturating_mul(100), transactions, }; block_data.into_pending_block(&sequencer_sign_key_for_testing()) } #[must_use] pub fn produce_dummy_empty_transaction() -> LeeTransaction { let program_id = programs::authenticated_transfer().id(); let account_ids = vec![]; let nonces = vec![]; let message = lee::public_transaction::Message::try_new( program_id, account_ids, nonces, authenticated_transfer_core::Instruction::Initialize, ) .unwrap(); let private_key = lee::PrivateKey::try_new([1; 32]).unwrap(); let witness_set = lee::public_transaction::WitnessSet::for_message(&message, &[&private_key]); let lee_tx = lee::PublicTransaction::new(message, witness_set); LeeTransaction::Public(lee_tx) } #[must_use] pub fn create_transaction_native_token_transfer( from: AccountId, nonce: u128, to: AccountId, balance_to_move: u128, signing_key: &lee::PrivateKey, ) -> LeeTransaction { let account_ids = vec![from, to]; let nonces = vec![nonce.into()]; let program_id = programs::authenticated_transfer().id(); let message = lee::public_transaction::Message::try_new( program_id, account_ids, nonces, authenticated_transfer_core::Instruction::Transfer { amount: balance_to_move, }, ) .unwrap(); let witness_set = lee::public_transaction::WitnessSet::for_message(&message, &[signing_key]); let lee_tx = lee::PublicTransaction::new(message, witness_set); LeeTransaction::Public(lee_tx) }