diff --git a/src/kernel_evm/CHANGES.md b/src/kernel_evm/CHANGES.md index d1131607fa965dea3b4d112a6471230a4cf719a1..50dcb3d1e3a01f48e31844b64175dc71deb5d211 100644 --- a/src/kernel_evm/CHANGES.md +++ b/src/kernel_evm/CHANGES.md @@ -13,6 +13,7 @@ address defined in its storage. (!9927) - Adds a new type of message in simulation mode, to verify that a transaction is valid by checking if the nonce is neither too low nor too high. (!9679) - Simulate if a transaction has a correct chain id. (!9752) +- Fees are now paid by the sender. (!9480) ### EVM Node diff --git a/src/kernel_evm/benchmarks/scripts/benchmarks/bench_loop_expensive.js b/src/kernel_evm/benchmarks/scripts/benchmarks/bench_loop_expensive.js index efd74178471e02e70fdc91ba30051e62b6b62fdc..40ee7d5c71432d4b2f935b85da57fe134d99518c 100644 --- a/src/kernel_evm/benchmarks/scripts/benchmarks/bench_loop_expensive.js +++ b/src/kernel_evm/benchmarks/scripts/benchmarks/bench_loop_expensive.js @@ -9,16 +9,15 @@ const utils = require('./utils'); const addr = require('../lib/address'); let faucet = require('./players/tezt_bootstraped.json'); let player1 = require('./players/player1.json'); -let player2 = require('./players/player2.json'); const { contracts_directory, compile_contract_file } = require("../lib/contract"); let contract = compile_contract_file(contracts_directory, 'loop.sol')[0]; let create_data = contract.bytecode; - const TOO_MANY_TXS = 100; const NB_LOOP = 100; +const FUNDS_PER_ACCOUNT = 10000000; // create call data with different values let call_data_prefix = "0x0b7d796e00000000000000000000000000000000" @@ -28,12 +27,10 @@ let call_data = function (n) { let txs = []; -// initialisation -txs.push(utils.transfer(faucet, player1, 100000000)) -let create = utils.create(player1, 0, create_data) -txs.push(create.tx) +let transfer_txs = []; let players = [] + // one player per transaction // this make the scenario work with the proxy, which now (temporarily) forces // 1 tx max per account @@ -41,6 +38,28 @@ for (let i = 0; i < TOO_MANY_TXS; i++) { players.push(addr.create_player()) } +// Generate all transfers for the scenario +// let total_funds = generate_transfers(players, 0, transfer_txs) + +let total_funds = TOO_MANY_TXS * FUNDS_PER_ACCOUNT + +transfer_txs.push(utils.transfer(faucet, player1, total_funds + FUNDS_PER_ACCOUNT)) +transfer_txs.push(utils.transfer(player1, players[0], total_funds)) + +for(let i = 0; i < TOO_MANY_TXS - 1; i++) { + transfer_txs.push( + utils.transfer( + players[i], + players[i+1], + (TOO_MANY_TXS - i - 1) * FUNDS_PER_ACCOUNT + ) + ) +} + +// initialisation +let create = utils.create(player1, 0, create_data) +txs.push(create.tx) + for (let i = 0; i < TOO_MANY_TXS; i++) { txs.push(utils.send(players[i], create.addr, 0, call_data(NB_LOOP))) } @@ -48,6 +67,12 @@ for (let i = 0; i < TOO_MANY_TXS; i++) { var args = process.argv.slice(2) if (args.length == 1 && args[0] == "raw") { + utils.print_raw_txs(transfer_txs) + utils.print_raw_txs(txs) +} else if (args.length == 1 && args[0] == "for-test") { + console.log("transfers") + utils.print_raw_txs(transfer_txs) + console.log("calls") utils.print_raw_txs(txs) } else { utils.print_bench([txs]) diff --git a/src/kernel_evm/evm_execution/src/handler.rs b/src/kernel_evm/evm_execution/src/handler.rs index 6e30a363c8115f4be6601fb863a36ad404d3e1e4..f5d7993c92137946e7728bc7509709ea60bb99ca 100644 --- a/src/kernel_evm/evm_execution/src/handler.rs +++ b/src/kernel_evm/evm_execution/src/handler.rs @@ -250,6 +250,29 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { } } + /// Have the caller account pay for gas. Returns `Ok(true)` if the payment + /// went through; returns `Ok(false)` if `caller` doesn't have the funds. + /// Return `Err(...)` in case something is at fault with durable storage or + /// runtime. + pub fn pre_pay_transactions( + &mut self, + caller: H160, + gas_limit: Option, + ) -> Result { + match gas_limit { + Some(gas_limit) => { + let amount = U256::from(gas_limit) * self.block.gas_price; + + debug_msg!(self.host, "{:?} pays {:?} for transaction", caller, amount); + + self.get_or_create_account(caller)? + .balance_remove(self.host, amount) + .map_err(EthereumError::from) + } + None => Ok(true), + } + } + /// Execute a SputnikVM runtime with this handler fn execute( &mut self, diff --git a/src/kernel_evm/evm_execution/src/lib.rs b/src/kernel_evm/evm_execution/src/lib.rs index 592f842f007761832a78a58ec14f93f02b3a65c4..5cc54c9bc0029c8d2004bf165c7a4c2234d84ca4 100644 --- a/src/kernel_evm/evm_execution/src/lib.rs +++ b/src/kernel_evm/evm_execution/src/lib.rs @@ -122,7 +122,8 @@ pub fn run_transaction<'a, Host>( call_data: Vec, gas_limit: Option, value: Option, -) -> Result + pay_for_gas: bool, +) -> Result, EthereumError> where Host: Runtime, { @@ -139,25 +140,36 @@ where precompiles, ); - // TODO: check gas_limit vs caller balance. Make sure caller has - // enough funds to pay for gas. - - let res = if let Some(address) = address { - if call_data.is_empty() { - // This is a transfer transaction - handler.transfer(caller, address, value.unwrap_or(U256::zero()), gas_limit) + if (!pay_for_gas) || handler.pre_pay_transactions(caller, gas_limit)? { + let result = if let Some(address) = address { + if call_data.is_empty() { + // This is a transfer transaction + handler.transfer( + caller, + address, + value.unwrap_or(U256::zero()), + gas_limit, + )? + } else { + // This must be a contract-call transaction + handler + .call_contract(caller, address, value, call_data, gas_limit, false)? + } } else { - // This must be a contract-call transaction - handler.call_contract(caller, address, value, call_data, gas_limit, false) - } - } else { - // This is a create-contract transaction - handler.create_contract(caller, value, call_data, gas_limit) - }; + // This is a create-contract transaction + handler.create_contract(caller, value, call_data, gas_limit)? + }; - handler.increment_nonce(caller)?; + handler.increment_nonce(caller)?; - res + Ok(Some(result)) + } else { + // caller was unable to pay for the gas limit + if pay_for_gas { + debug_msg!(host, "Caller was unable to pre-pay the transaction") + }; + Ok(None) + } } #[cfg(test)] @@ -262,7 +274,7 @@ mod test { &mut mock_runtime, &mut evm_account_storage, &caller, - U256::from(99), + U256::from(22099), ); set_balance( &mut mock_runtime, @@ -282,16 +294,17 @@ mod test { call_data, Some(22000), Some(transaction_value), + true, ); - let expected_result = Ok(ExecutionOutcome { + let expected_result = Ok(Some(ExecutionOutcome { gas_used: config.gas_transaction_call, is_success: false, new_address: None, logs: vec![], result: None, withdrawals: vec![], - }); + })); assert_eq!(expected_result, result); assert_eq!( @@ -327,7 +340,7 @@ mod test { &mut mock_runtime, &mut evm_account_storage, &caller, - U256::from(101), + U256::from(21101), ); let result = run_transaction( @@ -341,16 +354,17 @@ mod test { call_data, Some(21000), Some(transaction_value), + true, ); - let expected_result = Ok(ExecutionOutcome { + let expected_result = Ok(Some(ExecutionOutcome { gas_used: config.gas_transaction_call, is_success: true, new_address: None, logs: vec![], result: Some(vec![]), withdrawals: vec![], - }); + })); assert_eq!(expected_result, result); @@ -394,16 +408,17 @@ mod test { call_data, None, Some(transaction_value), + true, ); - let expected_result = Ok(ExecutionOutcome { + let expected_result = Ok(Some(ExecutionOutcome { gas_used: 0, is_success: false, new_address: None, logs: vec![], result: None, withdrawals: vec![], - }); + })); assert_eq!(expected_result, result); assert_eq!( @@ -428,7 +443,7 @@ mod test { &mut mock_runtime, &mut evm_account_storage, &caller, - U256::from(0), + U256::from(1_000_000), ); let result = run_transaction( @@ -442,6 +457,7 @@ mod test { call_data, Some(31000), Some(transaction_value), + true, ); let new_address = @@ -449,6 +465,11 @@ mod test { assert!(result.is_ok(), "execution should have succeeded"); let result = result.unwrap(); + assert!( + result.is_some(), + "execution should have produced some outcome" + ); + let result = result.unwrap(); assert!(result.is_success, "transaction should have succeeded"); assert_eq!( new_address, result.new_address, @@ -468,9 +489,15 @@ mod test { call_data2, Some(31000), Some(U256::zero()), + true, ); assert!(result2.is_ok(), "execution should have succeeded"); let result = result2.unwrap(); + assert!( + result.is_some(), + "execution should have produced some outcome" + ); + let result = result.unwrap(); assert!(result.is_success, "transaction should have succeeded"); assert!(result.result.is_some(), "Call should have returned a value"); let value = U256::from_little_endian(result.result.unwrap().as_slice()); @@ -488,9 +515,15 @@ mod test { call_data_set, Some(100000), Some(U256::zero()), + true, ); assert!(result3.is_ok(), "execution should have succeeded"); let result = result3.unwrap(); + assert!( + result.is_some(), + "execution should have produced some outcome" + ); + let result = result.unwrap(); assert!(result.is_success, "transaction should have succeeded"); assert!(result.result.is_some(), "Call should have returned a value"); let value = U256::from_big_endian(result.result.unwrap().as_slice()); @@ -507,9 +540,15 @@ mod test { hex::decode(STORAGE_CONTRACT_CALL_NUM).unwrap(), Some(31000), Some(U256::zero()), + true, ); assert!(result2.is_ok(), "execution should have succeeded"); let result = result2.unwrap(); + assert!( + result.is_some(), + "execution should have produced some outcome" + ); + let result = result.unwrap(); assert!(result.is_success, "transaction should have succeeded"); assert!(result.result.is_some(), "Call should have returned a value"); let value = U256::from_big_endian(result.result.unwrap().as_slice()); @@ -532,7 +571,7 @@ mod test { &mut mock_runtime, &mut evm_account_storage, &caller, - U256::from(0), + U256::from(100000), ); let result = run_transaction( @@ -546,10 +585,13 @@ mod test { call_data, Some(100000), Some(transaction_value), + true, ); assert!(result.is_ok()); let result = result.unwrap(); + assert!(result.is_some()); + let result = result.unwrap(); assert!(result.is_success); assert_eq!( @@ -591,16 +633,17 @@ mod test { call_data, None, Some(transaction_value), + true, ); - let expected_result = Ok(ExecutionOutcome { + let expected_result = Ok(Some(ExecutionOutcome { gas_used: 0, is_success: false, new_address: None, logs: vec![], result: None, withdrawals: vec![], - }); + })); assert_eq!(expected_result, result); assert_eq!( @@ -620,6 +663,13 @@ mod test { let caller = H160::from_low_u64_be(118u64); let data = [0u8; 32]; // Need some data to make it a call + set_balance( + &mut mock_runtime, + &mut evm_account_storage, + &caller, + U256::from(100000), + ); + // Act let result = run_transaction( &mut mock_runtime, @@ -632,17 +682,18 @@ mod test { data.to_vec(), Some(21000), None, + true, ); // Assert - let expected_result = Ok(ExecutionOutcome { + let expected_result = Ok(Some(ExecutionOutcome { gas_used: 21000, is_success: true, new_address: None, logs: vec![], result: Some(vec![]), withdrawals: vec![], - }); + })); assert_eq!(expected_result, result); } @@ -752,6 +803,13 @@ mod test { set_account_code(&mut mock_runtime, &mut evm_account_storage, &target, &code); + set_balance( + &mut mock_runtime, + &mut evm_account_storage, + &caller, + 21006.into(), + ); + // Act let result = run_transaction( &mut mock_runtime, @@ -764,17 +822,18 @@ mod test { data.to_vec(), Some(21006), None, + true, ); // Assert - let expected_result = Ok(ExecutionOutcome { + let expected_result = Ok(Some(ExecutionOutcome { gas_used: 21006, is_success: true, new_address: None, logs: vec![], result: Some(vec![]), withdrawals: vec![], - }); + })); assert_eq!(expected_result, result); } @@ -799,6 +858,13 @@ mod test { set_account_code(&mut mock_runtime, &mut evm_account_storage, &target, &code); + set_balance( + &mut mock_runtime, + &mut evm_account_storage, + &caller, + 22000.into(), + ); + // Act let result = run_transaction( &mut mock_runtime, @@ -811,17 +877,18 @@ mod test { data.to_vec(), Some(6), None, + true, ); // Assert - let expected_result = Ok(ExecutionOutcome { + let expected_result = Ok(Some(ExecutionOutcome { gas_used: 6, is_success: false, new_address: None, logs: vec![], result: None, withdrawals: vec![], - }); + })); assert_eq!(expected_result, result); } @@ -859,17 +926,18 @@ mod test { data.to_vec(), None, None, + true, ); // Assert - let expected_result = Ok(ExecutionOutcome { + let expected_result = Ok(Some(ExecutionOutcome { gas_used: 0, is_success: false, new_address: None, logs: vec![], result: None, withdrawals: vec![], - }); + })); assert_eq!(expected_result, result); } @@ -911,16 +979,17 @@ mod test { input, None, Some(U256::from(100)), + true, ); - let expected_result = Ok(ExecutionOutcome { + let expected_result = Ok(Some(ExecutionOutcome { gas_used: 0, is_success: false, new_address: None, logs: vec![], result: None, withdrawals: vec![], - }); + })); assert_eq!(expected_result, result); assert_eq!( @@ -944,6 +1013,13 @@ mod test { let caller = H160::from_low_u64_be(118u64); let data = [0u8; 32]; // Need some data to make it a contract call + set_balance( + &mut mock_runtime, + &mut evm_account_storage, + &caller, + 21006.into(), + ); + // Act let result = run_transaction( &mut mock_runtime, @@ -956,17 +1032,18 @@ mod test { data.to_vec(), Some(21001), None, + true, ); // Assert - let expected_result = Ok(ExecutionOutcome { + let expected_result = Ok(Some(ExecutionOutcome { gas_used: 21000, is_success: true, new_address: None, logs: vec![], result: Some(vec![0u8; 32]), withdrawals: vec![], - }); + })); assert_eq!(expected_result, result); } @@ -1060,6 +1137,7 @@ mod test { data.to_vec(), None, None, + true, ); // Assert @@ -1080,6 +1158,13 @@ mod test { let static_call_target = H160::from_low_u64_be(200_u64); let all_the_gas = 2_000_000_u64; + set_balance( + &mut mock_runtime, + &mut evm_account_storage, + &caller, + all_the_gas.into(), + ); + // contract that stores something in durable storage let static_call_code = vec![ Opcode::PUSH2.as_u8(), @@ -1128,18 +1213,19 @@ mod test { data.to_vec(), Some(all_the_gas), None, + true, ); // Since we execute an invalid instruction (for a static call that is) we spend // _all_ the gas. - let expected_result = Ok(ExecutionOutcome { + let expected_result = Ok(Some(ExecutionOutcome { gas_used: 86653, is_success: false, new_address: None, logs: vec![], result: None, withdrawals: vec![], - }); + })); // assert that call fails assert_eq!(result, expected_result); @@ -1157,6 +1243,13 @@ mod test { let static_call_target = H160::from_low_u64_be(200_u64); let all_the_gas = 2_000_000_u64; + set_balance( + &mut mock_runtime, + &mut evm_account_storage, + &caller, + all_the_gas.into(), + ); + // contract that does logging let static_call_code = vec![ Opcode::PUSH1.as_u8(), // push size @@ -1204,18 +1297,19 @@ mod test { data.to_vec(), Some(all_the_gas), None, + true, ); // Since we execute an invalid instruction (for a static call that is), we // expect to spend _all_ the gas. - let expected_result = Ok(ExecutionOutcome { + let expected_result = Ok(Some(ExecutionOutcome { gas_used: 86653, is_success: false, new_address: None, logs: vec![], result: None, withdrawals: vec![], - }); + })); // assert that call fails assert_eq!(result, expected_result); @@ -1233,6 +1327,13 @@ mod test { let call_target = H160::from_low_u64_be(200_u64); let all_the_gas = 2_000_000_u64; + set_balance( + &mut mock_runtime, + &mut evm_account_storage, + &caller, + all_the_gas.into(), + ); + // contract that does logging let contract_that_logs = vec![ Opcode::PUSH8.as_u8(), // push some value @@ -1301,6 +1402,7 @@ mod test { data.to_vec(), Some(all_the_gas), None, + true, ); let log_record1 = Log { @@ -1315,14 +1417,14 @@ mod test { data: vec![1, 2, 3, 4, 5, 6, 7, 8], }; - let expected_result = Ok(ExecutionOutcome { + let expected_result = Ok(Some(ExecutionOutcome { gas_used: 87048, is_success: true, new_address: None, logs: vec![log_record1, log_record2], result: Some(vec![]), withdrawals: vec![], - }); + })); assert_eq!(result, expected_result); } @@ -1339,6 +1441,13 @@ mod test { let static_call_target = H160::from_low_u64_be(200_u64); let all_the_gas = 2_000_000_u64; + set_balance( + &mut mock_runtime, + &mut evm_account_storage, + &caller, + all_the_gas.into(), + ); + // contract that does logging let static_call_code = vec![ Opcode::PUSH1.as_u8(), // push size @@ -1398,6 +1507,7 @@ mod test { data.to_vec(), Some(all_the_gas), None, + true, ); let log_record1 = Log { @@ -1406,14 +1516,14 @@ mod test { data: vec![0], }; - let expected_result = Ok(ExecutionOutcome { + let expected_result = Ok(Some(ExecutionOutcome { gas_used: 87048, is_success: true, new_address: None, logs: vec![log_record1], result: Some(vec![]), withdrawals: vec![], - }); + })); assert_eq!(result, expected_result); } @@ -1444,6 +1554,13 @@ mod test { &selfdestructing_code, ); + set_balance( + &mut mock_runtime, + &mut evm_account_storage, + &caller, + all_the_gas.into(), + ); + set_balance( &mut mock_runtime, &mut evm_account_storage, @@ -1484,16 +1601,17 @@ mod test { data.to_vec(), Some(all_the_gas), None, + true, ); - let expected_result = Ok(ExecutionOutcome { + let expected_result = Ok(Some(ExecutionOutcome { gas_used: 86656, is_success: true, new_address: None, logs: vec![], result: Some(vec![]), withdrawals: vec![], - }); + })); assert_eq!(result, expected_result); @@ -1524,6 +1642,13 @@ mod test { let selfdestructing_contract = H160::from_low_u64_be(100_u64); let all_the_gas = 1_000_000_u64; + set_balance( + &mut mock_runtime, + &mut evm_account_storage, + &caller, + all_the_gas.into(), + ); + // This contract selfdestructs and gives its funds to `caller` let selfdestructing_code = vec![ Opcode::PUSH1.as_u8(), // push address of beneficiary @@ -1585,16 +1710,17 @@ mod test { data.to_vec(), Some(all_the_gas), None, + true, ); - let expected_result = Ok(ExecutionOutcome { + let expected_result = Ok(Some(ExecutionOutcome { gas_used: all_the_gas, is_success: false, new_address: None, logs: vec![], result: None, withdrawals: vec![], - }); + })); assert_eq!(result, expected_result); diff --git a/src/kernel_evm/kernel/src/apply.rs b/src/kernel_evm/kernel/src/apply.rs index 787d5a7ea7a44b413f3b3d580e7de775219e231c..63b237d720f264b9f0d45b84e2cfa613e2809ca4 100644 --- a/src/kernel_evm/kernel/src/apply.rs +++ b/src/kernel_evm/kernel/src/apply.rs @@ -225,8 +225,9 @@ fn apply_ethereum_transaction_common( call_data, Some(gas_limit), Some(value), + true, ) { - Ok(outcome) => Some(outcome), + Ok(outcome) => outcome, Err(err) => { // TODO: https://gitlab.com/tezos/tezos/-/issues/5665 // Because the proposal's state is unclear, and we do not have a sequencer diff --git a/src/kernel_evm/kernel/src/block.rs b/src/kernel_evm/kernel/src/block.rs index fc139b0fb5e894d7681e5c888d415c1cd6e74aae..301e81fa0c89cbb868aa05c4358d92fe01dccc98 100644 --- a/src/kernel_evm/kernel/src/block.rs +++ b/src/kernel_evm/kernel/src/block.rs @@ -618,7 +618,7 @@ mod tests { let dest_balance = get_balance(&mut host, &mut evm_account_storage, &dest_address); - assert_eq!(sender_balance, U256::from(9999999999500000000u64)); + assert_eq!(sender_balance, U256::from(9999999999499979000u64)); assert_eq!(dest_balance, U256::from(500000000u64)) } @@ -941,7 +941,7 @@ mod tests { #[test] fn invalid_transaction_should_bump_nonce() { let mut host = MockHost::default(); - let evm_account_storage = init_account_storage().unwrap(); + let mut evm_account_storage = init_account_storage().unwrap(); let caller = address_from_str("f95abdf6ede4c3703e0e9453771fbee8592d31e9").unwrap(); @@ -953,11 +953,18 @@ mod tests { let default_nonce = caller_account.nonce(&host).unwrap(); assert_eq!(default_nonce, U256::zero(), "default nonce should be 0"); + let tx = dummy_eth_transaction_zero(); + // Ensures the caller has enough balance to pay for the fees, but not + // the transaction itself, otherwise the transaction will not even be + // taken into account. + let fees = BlockConstants::first_block(U256::from(0)).gas_price * tx.gas_limit; + set_balance(&mut host, &mut evm_account_storage, &caller, fees); + // Prepare a invalid transaction, i.e. with not enough funds. let tx_hash = [0; TRANSACTION_HASH_SIZE]; let transaction = Transaction { tx_hash, - content: Ethereum(dummy_eth_transaction_zero()), + content: Ethereum(tx), }; let queue = Queue { proposals: vec![blueprint(vec![transaction])], diff --git a/src/kernel_evm/kernel/src/simulation.rs b/src/kernel_evm/kernel/src/simulation.rs index fadfe3dcaedb4715f1b42ead1de988b33a38ff3d..a6bedc1cd8d323cee1ca482eedaa19014675bd7c 100644 --- a/src/kernel_evm/kernel/src/simulation.rs +++ b/src/kernel_evm/kernel/src/simulation.rs @@ -80,8 +80,11 @@ impl Evaluation { Evaluation::decode(&decoder) } - /// Execute the evaluation - pub fn run(&self, host: &mut Host) -> Result { + /// Execute the simulation + pub fn run( + &self, + host: &mut Host, + ) -> Result, Error> { let timestamp = current_timestamp(host); let timestamp = U256::from(timestamp.as_u64()); let block_constants = BlockConstants::first_block(timestamp); @@ -102,6 +105,7 @@ impl Evaluation { .map(|gas| u64::max(gas, MAX_EVALUATION_GAS)) .or(Some(MAX_EVALUATION_GAS)), // gas could be omitted self.value, + false, ) .map_err(Error::Simulation)?; Ok(outcome) @@ -323,12 +327,17 @@ fn parse_inbox(host: &mut Host) -> Result { fn store_simulation_outcome( host: &mut Host, - outcome: ExecutionOutcome, + outcome: Option, ) -> Result<(), anyhow::Error> { log!(host, Debug, "outcome={:?} ", outcome); - storage::store_simulation_status(host, outcome.is_success)?; - storage::store_evaluation_gas(host, outcome.gas_used)?; - storage::store_simulation_result(host, outcome.result) + match outcome { + Some(outcome) => { + storage::store_simulation_status(host, outcome.is_success)?; + storage::store_evaluation_gas(host, outcome.gas_used)?; + storage::store_simulation_result(host, outcome.result) + } + None => Ok(()), + } } fn store_tx_validation_outcome( @@ -485,8 +494,14 @@ mod tests { call_data, Some(31000), Some(transaction_value), + false, ); assert!(outcome.is_ok(), "contract should have been created"); + let outcome = outcome.unwrap(); + assert!( + outcome.is_some(), + "execution should have produced some outcome" + ); outcome.unwrap().new_address.unwrap() } @@ -509,6 +524,11 @@ mod tests { assert!(outcome.is_ok(), "evaluation should have succeeded"); let outcome = outcome.unwrap(); + assert!( + outcome.is_some(), + "simulation should have produced some outcome" + ); + let outcome = outcome.unwrap(); assert_eq!( Some(vec![0u8; 32]), outcome.result, @@ -528,6 +548,11 @@ mod tests { assert!(outcome.is_ok(), "simulation should have succeeded"); let outcome = outcome.unwrap(); + assert!( + outcome.is_some(), + "simulation should have produced some outcome" + ); + let outcome = outcome.unwrap(); assert_eq!( Some(vec![0u8; 32]), outcome.result, @@ -554,6 +579,11 @@ mod tests { assert!(outcome.is_ok(), "evaluation should have succeeded"); let outcome = outcome.unwrap(); + assert!( + outcome.is_some(), + "simulation should have produced some outcome" + ); + let outcome = outcome.unwrap(); assert_eq!( Some(vec![0u8; 32]), outcome.result, @@ -626,6 +656,11 @@ mod tests { if let Input::Simple(box_simple) = parsed { if let Message::Evaluation(s) = *box_simple { let res = s.run(&mut host).expect("simulation should run"); + assert!( + res.is_some(), + "Simulation should have produced some outcome" + ); + let res = res.unwrap(); return assert!(res.is_success, "simulation should have succeeded"); } } diff --git a/tezt/lib_ethereum/eth_cli.ml b/tezt/lib_ethereum/eth_cli.ml index 545d0fb09aab920d6e450aa8c230eae64e9df2de..4bbd35f5b3a2c04f4b4ce6cbbfb6caa183d11451 100644 --- a/tezt/lib_ethereum/eth_cli.ml +++ b/tezt/lib_ethereum/eth_cli.ml @@ -46,11 +46,10 @@ let spawn_command_and_read_json command decode = let balance ~account ~endpoint = let* balance = - spawn_command_and_read_json + spawn_command_and_read_string ["address:balance"; account; "--network"; endpoint] - JSON.as_int in - return @@ Wei.of_eth_int balance + return @@ Wei.of_eth_string balance let transaction_send ~source_private_key ~to_public_key ~value ~endpoint ?data () = diff --git a/tezt/lib_ethereum/transaction.ml b/tezt/lib_ethereum/transaction.ml index 473462ddefbe577508e0fca662bc6bab9ed59bf9..5b04f4074823150eddbc3f986f4c2bb7e94f563d 100644 --- a/tezt/lib_ethereum/transaction.ml +++ b/tezt/lib_ethereum/transaction.ml @@ -86,7 +86,7 @@ let logs_of_json json = removed = json |-> "removed" |> as_string; } -(* as per https://web3js.readthedocs.io/en/v1.2.9/web3-eth.html#gettransactionreceipt *) +(* as per https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionreceipt *) type transaction_receipt = { status : bool; blockHash : string; diff --git a/tezt/lib_ethereum/wei.ml b/tezt/lib_ethereum/wei.ml index b22bff595c812e44589437f04b281c03bb7241b1..d9511ed71e7bcd8ea97ef201982b8ff7f5adee5c 100644 --- a/tezt/lib_ethereum/wei.ml +++ b/tezt/lib_ethereum/wei.ml @@ -43,6 +43,14 @@ let of_wei_z z = z let of_eth_int eth = Z.of_string @@ Int.to_string eth ^ wei_pow +let of_eth_string eth = + match String.split_on_char '.' (String.trim eth) with + | [eth] -> of_string (eth ^ wei_pow) + | [eth; decimal] -> + let decimal = decimal ^ String.make (shift - String.length decimal) '0' in + Z.add (of_string eth) (of_string decimal) + | _ -> Test.fail "Invalid ETH amount: %s" eth + let ( + ) = Z.add let ( - ) = Z.sub diff --git a/tezt/lib_ethereum/wei.mli b/tezt/lib_ethereum/wei.mli index d9b66b37df38ecacf4af8fcbf294ac58ca5973ae..72542a6f1398870600c712393b434574fd797d81 100644 --- a/tezt/lib_ethereum/wei.mli +++ b/tezt/lib_ethereum/wei.mli @@ -54,6 +54,12 @@ val of_wei_z : t -> Z.t This doesn't perform any bounds checks. *) val of_eth_int : int -> t +(** Convert a [string] amount of eth to a wei one. + This doesn't perform any bounds checks. + It assumes the string represents either an integer + or a float - both denoting an amount of eth. *) +val of_eth_string : string -> t + (** Addition. This doesn't perform any bounds checks. *) val ( + ) : t -> t -> t diff --git a/tezt/tests/evm_kernel_inputs/100-loops b/tezt/tests/evm_kernel_inputs/100-loops index 3e01da297564f6c0b5f4bd8ec1fae5a8c8f068dd..4fa8e3cf79293809deea20897e8ffe2543f9a5e9 100644 --- a/tezt/tests/evm_kernel_inputs/100-loops +++ b/tezt/tests/evm_kernel_inputs/100-loops @@ -1,103 +1,101 @@ -f86680648301000094f0affc80a5f69f4a9a3ee01a640873b6ba53e5398405f5e10080820a95a08bdeb9d0419654225c0df6115757997a1b2ff2a2d1069ee19692bb8c28ef812ba07eb9567b4706365479492982b19386a92a54184e3183593b255e9943ad8ee697 -f902408064831000008080b901f0608060405234801561001057600080fd5b506101d0806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80630b7d796e14610030575b600080fd5b61004a600480360381019061004591906100c2565b61004c565b005b60005b81811015610083576001600080828254610069919061011e565b92505081905550808061007b90610152565b91505061004f565b5050565b600080fd5b6000819050919050565b61009f8161008c565b81146100aa57600080fd5b50565b6000813590506100bc81610096565b92915050565b6000602082840312156100d8576100d7610087565b5b60006100e6848285016100ad565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006101298261008c565b91506101348361008c565b925082820190508082111561014c5761014b6100ef565b5b92915050565b600061015d8261008c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361018f5761018e6100ef565b5b60018201905091905056fea26469706673582212200cd6584173dbec22eba4ce6cc7cc4e702e00e018d340f84fc0ff197faf980ad264736f6c63430008150033820a96a038acf028a2bfe60179e0b5280f270ac9ea2fc1f03779ad9dd2804e2f3d90b83da04d45442095e297512d23d0d280487975a56a91f9d55e4d05b23150ac4df0c0fa -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000000820a96a09a039dc7d0566eea799228a5eee4afc8bc52b9664ca88c941fe75c9510b71156a073658c2e0c059d944716d1b346b16200ffd4860372ff5130e9a89306fdce5a1d -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000001820a95a05fa4700cae223bc227069b2867f12a5b2745adb2893edd48021dea41268532daa01438e7eeda3ba950adc838014ff828d419687bea08b02081bf020ac96449115a -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000002820a96a0d1d175770ec4eb8466c05f1a1e375a05e8450ecbc05547bc187ad63f31635789a0209976c004c7e51bb78afb570256b25c612f00854347529ef89ac50cd4e803b9 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000003820a95a0919aa8db49c38196d28cb6a3cff00aa1dba0b41d11b9060ff42487bcb2d2350da021d77709f2dd623df01e4ba96335008a48e452d63c4e44989c74642e7241b5fc -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000004820a95a023d55332faf39e215b57a7d28da8276de48bab2a82712a8ba159c7fb234c4510a04c3df9b3b140e058a4d1ffaa9195255ce71b1fce617510d96b898f5c95afca1b -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000005820a95a0626dd8cc1703cf36a40f4b786f9c46348fc7bc5a302c7fb28def842f976e310fa02d4c6737c8f8c4abcf8bee976c62dcea0c0cf4659872710981ce641fbdec3e9d -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000006820a95a05692f758970c6e41fb2b6e19ec0ec79d93aa04d5f214500126324aa023575b16a0089593f50c13abd7c350f731a1cf413cde9ab4a1941c5a664ed17033085c8aa9 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000007820a95a0201fcda891a11e12a12c5e19067270024de09c2f720dfb7928b675f91af758efa002c99d0cfc2324101148565655c3673b3e92cf758ba9a17a8f60628ce76efb19 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000008820a96a097b7aaf2db57660f0a0f68b0a252043dae17a953d6f551cf4f25a1d612e87e14a05c119bb54f5e9a3d6d93e230f53f9cea9bb1b7bf009da48e3affd2621111c101 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000009820a96a01e9816f548533e113ea00e5867cd63b9932c49feabf8a1f5bbbdcc130fbcec48a0742c448b3ddb14b3502a531073d3b4960a7312f531255bf515537be7e5c81280 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000000a820a96a04d2d13998ceec2140730e0aa069a1cfb2b3458ebd9d0c0fefc5de2719e8e6cffa04261334d9f4ca5567ddbd4c49bab2ffa453640847d9077e78e648c9aa325a4ef -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000000b820a96a08540808fd3259143327613c9eab1aa1163c05aa19ce01c9411028f0045c75c31a0170195780ad59c31de52b623bd583ab498e0fc058045d4dccf52f31526d4b827 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000000c820a95a0558817f6b9343fe954f019386265323418e72242b0fb83e75338ee7460e81b0ca013973a0340506b853fd6a8eb5da0f13c873deb58341dff738ae1803cf4d584d6 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000000d820a96a0be54b2b25d16f04fa80420d2f837d7755cdeed44e8dd1d53bced3a5f146d85d4a05cacb418735d39468d9e2b217a88ad7a90bf7630dc5a811e6116355c501bc42e -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000000e820a95a0155932c94211267afd2c390df93608302bf419ee7a269aba24822ecc812b01c5a05ac2d1807003f18fcad61365423d50efe8972459268454c763905f354515b616 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000000f820a96a0ac88d6d8a68c8e3bd24452bccce2050f1d8768143cd2ea1c52bcdee099f89432a05e66ec788f2b50ea6e0bd7dff62c1ebcc24af21c7bbc4a6ae0e359c2893ed87e -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000010820a96a0a7be14d093aa6c6f7df4cefb7df95098d4cf361dd5ece6ebcf810b81cba07fe7a0216fbdeceb09bddf2560ef02308cc1f907c2a7b84895b1346cbcb8ff4b0142c5 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000011820a95a0e1f52cdef00a1fb6596f8e108cd73c89c3f0ee39e18f630bdf542db173d843baa01e9b4c580b91888959ffab299bf52b87821f50b50fdd08ccf0ff48da2f4392cd -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000012820a96a0641cd26dfae3311626f10067c9b3fb5cc57d3d89b70a4a8db2377d69447fa8a2a06c048b6a6b36a42409db06642a0f44c5a6775afc16a309f28a61dc5f998c253c -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000013820a96a0a1a43cc480c51f68f4852c5aac34d64524a35cc91b314762b85595b0b73db4fca06998aeaf7f2771f4e29bfbbaf5d188285e1ee2803eb6c287ef758390f8859db0 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000014820a95a07ca290a6797fa5df5f9c574c243ddc0e642b84d08da24977ac4a775815483e51a0351a8e003b17a3d5d912191bf8a03fa2aa91ec77d65e50ce25716585df16e0cc -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000015820a96a017ea96520232f0646520d8c9cd6a3e010659005bcf80dae43a21df6a22e8db84a07f60947e04d5138a67ce2a8f1f1aabcd1f1c212a0f58b24164cc0ec1df8ddb56 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000016820a95a0d498c7ae706de69d36f81248fa8dc99c5a15d9bef6650fa0176cbab6fe807ff9a074651167a0ed62d15d4707ffe21c4e3675b32cccb581b32d309b7240d2be3411 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000017820a96a05d973980b3a44f306d9d3b9c68c2d45e9e81fa12772c4023a6bbf4b4dec08e33a02a12db0011b5cca205a1c8496ee02b3352a4a34ee8db18ffb2c8f0b7c424c6f2 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000018820a95a03b4ca65e1bc9183847cf4604dfafa9a53b7f07779e984bfd7e1e61aee9a00218a0330d421abfad9ce495d928cba17072ed2fc88d91a46a0ef84007cb597388f4b9 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000019820a96a005ba99885cd9eed3d3a44a104e61da3ca46a206be11ba78b8f9c53522da329a4a00934d98516e2e301862fef1cc222ae76f783808790853146ba21ea140456c942 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000001a820a95a0c06130807e79edde899f68cfc9d87bda1b547c303dab80e658b7c3078af9d79ba04774d67402078feba37b10998e938ce6a933fddf2e4781a18eb4089b861dd594 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000001b820a96a0bbffa1d487d48eb4da9743173aa45e3961cd8783e9569196e3b5d70da14c9869a07d684dd2ca15c1c20ba220e39823277c9b33624e7122af262cf23cbf4efc842c -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000001c820a95a09bbc55f39b63f1b4d11cb12a3f3e07ba51b9f46919352b20dda0328e2e8fc77ea01f7d622164285c9d1c7f03720f31b3c19185042ac6a59ba073b06eea19bdfc68 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000001d820a96a0e34f1d6700a6659171ec0b3d9f6483f81fa955feac0da792a828271d202bf00fa00f5320f656e1490c27b2e9f18bdbee3d8659dd20cfefa254667b3267d4a66870 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000001e820a96a096e8f70da6a57b6308747cd46027e2537f1cd065928e40122d38a3dfcdec9ec0a0198bdf3d4819afc506eeec3fe7e6cc1a927e05da72267f9d84ded430331ccfe5 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000001f820a95a0f506bed455f8847eaa77c64f5a97eb918c0913ad92689223031446ad9b6f1ae0a017b105b04700f3391347c162426ad491de52c4521a82ee903110abcd2d5d4090 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000020820a96a06085b0fc2cedb018c7a352947c1c27bfec1712f3215c4168269fd9e6cc9b0c91a0060bcf761723cfb55d1eff24f5098b8494009d05f729d364b815a2b0a490af40 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000021820a95a04b8f81418b397f42d068e1264aaca9686b6c184b4c6c8fd1384bd566b830ceffa076af56358ec5f0a3fbd692ebbca9f62289bd38ea8e7d09b61c6c6cbc932d9032 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000022820a96a0a86978a9eba43bf182e3a06b9ce55b46a2e33bc0de3c1632de1fa1b3e2e38b33a00dec0edb8c78510611ccfa9c8a8f6e3833b705af2bb49491e99d77d1d4ba8ab5 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000023820a95a07751db4632665af9cea05de37a5b00b5bccec5537fc739887c5dc21e627322e4a00c3b2f2f0eb59638ceb50bdabae1525b6b5c030beca1e141c23a83d06222e19f -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000024820a96a0dd95a427569723be626629877ac2e96acac4437227f98d00b0dc292c04258f3aa06f9be029f31f5c2e9e100d84c4ed554e8b0eee3376323fc18517a158c4cca1f7 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000025820a95a04f03cc9a875db917718f2084d469f9c522cc1db2ce4312ae2079954850bbd126a0632ff20165bb4b337f1c0034c146a175c44ae890ade5cd3ed6457c550b013b03 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000026820a95a07087bbc57d23877ad01a5622efd05238fae78bd995a504ee81ac50fbc3ca7126a0763f0b98b12ffaaaaf9925a2146910e6ce32f84b62218567b7353cf9594e1fd3 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000027820a95a0e17a15e95fee81db379d36cbfc39f54902be23aea42b85b1db761e2e0677164ca0765c42c0e433bcfc09d78189f2c667304ce0ac8bdb17e8e16f7f7774087bcfe4 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000028820a96a0656bb064fa1217ab6a3cc65cdf7edabafaea22620fa6fdf1e9c32124632794aba07bbf414a27c9097b67de65094f6c091aafad388a40335782fc2359bcd1091a13 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000029820a95a09fc38b104073c543935114cd4e5167276a2a586a7d79bc1205af672b3b0617efa01ce1bec3c15a51be8f864babb524c565a5df081d03683feb1651ad868a13e56f -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000002a820a96a02bdfc705133841da4680c14a5a7666ebc3594e3f667e02e49173d4d1f26ede64a054553beb0e84a866861e4d865d4882eb4d7d9ffd891392368767ec9a6bd78efc -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000002b820a95a0f7c5fe0e9bfa817dca9b0ca3ba4aa16b736151ca8ea64f1e169815586e03b130a007afaf11960603d7c64e0848270db6a74ed7e933745ca7e5764936c53de32c9e -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000002c820a95a0568350d973be057b5147ac1ddf130c4fcbb7224e547ecadc8bfdcca931bfc077a0236d550769363ead7a4dda95da91049e3e27651046f50aca3b959ef02163154a -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000002d820a95a057928032e6fb86bb246e321e963136c1c63a5c1c3413ee13456fd240529b0bafa07ece0c0f2ced53700b9646c6d0159ee6e056f8849b87d71dafe2e7a40115c786 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000002e820a95a0c0bfc616be5eeacca6dea651258b285389675b966e6a7233438aea78ff87dd18a030c0f09b233c9af39056c30421bf675f48e42a0cb50fd0bfe06e44e963be7192 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000002f820a96a016225481516cec65b6fd64338dec15958c1c88b1c0880042d8592b6e75962a34a050ad26198296d7f49812af250a3a8f5d66ef35a1d92c86edef772e970c7c00fe -f8858064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000030820a96a09e1c548fce52443294170018f20d39e7c85691c932edd3422a26cd573f9b3f139f872c852a8da0827c12881c7c8a4058a0d8279b8fe7a57fc1ea045b918b159b -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000031820a96a0cdb0d83259230cbf2a046aa85b4d519639952eb884f5f06bfc32d1ea23a11635a0438b3cad88f0f3eb994334a44d04233c23ca98a7b451af2c3b8dcce6efc1a222 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000032820a96a0aff4c8c2b2bbbfa268d18396c3239ae9f7f287f80f1dfe183bf23bc5ec20d312a0594ab28f222fd54f8f05e99530195e6c0767f5932a4e63fb91142f7287464419 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000033820a96a05a2109763db9b4a948a8c20c013bcca2f2b40c2435c5cb50b96ed45bc6adc5d9a078ddc6ae1892e5198678fdfddbdb868379328256b0fdfc1122d167331a2c19fe -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000034820a96a024026f583ca549b509cc167b92d86dd5a5357265502bab0b1440b7ed7dbf076da075fb1e0d230a2dfcbd61a43846f77100cc08e5459d352847c34a7534121a95d8 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000035820a96a07b29cbe9c07821c90b2bd192a6c37fec6fe4a8d7648ceee9114f9ded9c86c753a033d80196b0309060e9895ddcff03d4ed08a0b4ab6a207fea6ef649bd25580df5 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000036820a96a033535772a0a76984a286359749eb103a7386c18bf78c9d4c6f656571bdc39218a07b5a64a96bef5c9386e6da2203d43cde67f95d2021b620203986caf22835536d -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000037820a95a024f339f55a142579fe68c237047bb96bb8403ae427c4ea90aa8570cb8db8e59ea0608e6f60f4f22d11b74cd3db2ac0ee49cf841733a25ee94ec82949d4e82c53cf -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000038820a95a06a0184f622b93a46420aaca8ae238aaf880a571abfafbb1f24cbd6c4d9d4b763a0123381646fd0fe27de5ae9366287a93c1d8f4e6609584362a2e4f194a8968782 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000039820a96a094eb4933e09ef576d2000d5a3e37a5f8dad1d00a07a3d48f80d0af84e3826856a05ca9a980146a08b8828360cff9351e935a403a3bc715730104821d4f6a930038 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000003a820a96a0050fe60cc7d9dca6c675dd3a9a814ccc20af29efa601557907753736058f49e7a0381d5d32dae4d4dc58d915829604f5034246529b14aff313e17d6eb714ebe906 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000003b820a95a09047af85cf785bb378013dc010938b7214e0f2bc7a252caf35481930fe7d1113a0396b8079c56d91eb67f534edaa459ecc7493325935c5efd41d0f8c2d3b9f88da -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000003c820a96a0723c5d30191ca090d8d785ec1d5e16f16546bf24456d36e9a257a47ef09c05e7a05cb7394b5ba16053e5de200c759ce683d4c55768259d80f602402f0f09a37478 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000003d820a95a0d5f77a1a099a70b1d3d46a62807e5afad8c68386ef466d6bef23dac874499882a05a2470fa41f3b6c870b3a31313b9b9f960b8daf293eb5336c5273c6106310734 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000003e820a95a02cf712634dcd77c4b83e23e03e1ba8bef825b652a7afee4db99e1dd4a71268aba079f20e28a9795494fe9fb72b4ed62cc718bd3c02ab76df62e98cb9c35eb8325d -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000003f820a95a0d72ea7fd5d624fd2914ee3663a53b11eccd943b9d2828546f100d6431b7d8635a061c1824ed937a70f45e1e83acb5bad25e24a4c3ac3ce44b306a003f9ecd27d38 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000040820a95a0bad5bd3965195b02d7d772d055e21111ca7637a348f08d32f332ee939d10e84ba01674efae74bf228aba99d0fffa66e34c755967ae2a7a24218b531a87bd649c31 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000041820a96a0a6af1aa7faea648bc52caed65ee7168bdee8f756add26bd8a7912f5efa061b65a044a10eb4308c6aef149cde62ae286b831ec01ccce1dbec4402e28401bc3bebed -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000042820a96a05a7d2257d586a79a898d1b6e18ae67e39f6f518c131bad7abc1d9bc94bc9b2d5a04ef4f9e81ccf2b6212bc3bf551d06830f1b368c6d8922edcb9c61c8d26536843 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000043820a96a0d6df2059928a50a539b29ad35db262b95b60bbf51180edb46336b91d6fae4a1aa076631c964fd7f8fccde95369ace966e287a6f974a49dbbde9ab077db83e811df -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000044820a95a0290ea7488da5d938b1c8d98762d9c55bd3db81eaf33459c869d743073c5ed03aa063f8d138af793e60758fce6bb815fc56a2463fea14da9ae0a01afdde1820cfaa -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000045820a96a074226b1e4bfc4817251f6e5b93d770b4bd920c6a672ea14e8e4f5cad79fa78d0a05aae9030a7e2a3d03ddf813e061b73d4a1fa67cf6ab7a6f29162ff79901a9b50 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000046820a96a044e3157b78b59130b2e73e32618c192a1f698b94bfa43e6d0e5a9ace10efaad0a046f8947fd489a3c4b3d6703234d149be39454709bb503f0fcc8bac980046bebf -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000047820a96a0ee7490b6f1624939793ab503a560b2b133ec863ae7568d3fc773d07e3a3c8dd0a02c75c3deca5d8ce1e2d8cf37f5cd312ef6e7ae178c189ce95706f7bf3ae91e2a -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000048820a95a050fba21b46e9d1381f3c696e44a9d83cbda689953c86e960d44ba319ee9e58b0a0644841bd36d46e5ec943c4edbf362ffcdc2fed22740a8c2bff6c9550e6e46920 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000049820a95a0f7cc221ee6cfb74cd7bbb6bf6dac3ec7b17240390d9ac80fe3eed650c9710010a02b4b2aabf3fc13bc153cc78302a0c332b7d3cb31237878c7a9384e942f91091e -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000004a820a95a082990c45c60afef166564bbe6d30e412e9c6fac29c1b9d1a2bec4d1c8ad709cca07c45d6ea2e38ae8d1d80f7da075b83a48fcd31ea7f73abe05d31d8ec36ac3f09 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000004b820a95a0ad5ecd84c45879f38f251875947d300731be11b224e23fdeefe13c2f14175bc5a00c67ff752b1ca6d7173caa14929da2ca69c9f18c732b465b5d2813f38fbb2dea -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000004c820a95a053fa4d75e18d1144b4e74de39cf2b1b4b6aa1d6720fe507f57e9b95746f96401a00e65f3d834f38f54a630e673ed21e7a081809fe64a195213ad39255653b77e79 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000004d820a95a045e8667da688f2f6aff8478a1593b5e2f49a5af28066051d45768de577f32f38a02215bbcb25fc695a04af1e07b89571daacb39f7dc99c072e3bcba0f4db518df0 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000004e820a96a0516c5fbc517f2aaf9ba706fffc50775a5c04321179967346c2bff6adbe2a8a2da01fdfe84c6fa884d764578f4416b38c89adef08b23601cd5e420e2070561d64c6 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000004f820a96a010faf061d7736674313d51089a5de7fc09efb14505f08e315a7b75f9fff2bb1fa00bf4f13c84d32cf862f33cc683fc7ff52d00b4f03658f88bfd040f59b5edb52f -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000050820a95a08fb06994a924b717a0e2c1b3f7c23e9e72ecbba201d1cafca34a511e5b2a21c2a02d7c89948c042a7dd63a120b28c8550ff336b1d30e895541844431ebf20f8ce2 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000051820a95a02624aab695a7187e7b1f3bda635c0658ddd5a1c0e0c7caf93fa758c0de801cfaa0557605d4d1b1349dfecaa23bd21c99568a461833aed89417d0aaf4b6a1424b44 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000052820a96a0df73dc2937dd5f9c95a08ead59673df1dc02b4b2b830e9db5e3eb841c9e3896ca0715eac1b7b201eb5053fe208cc1c964c87a226de38eb34910c4c77440df28800 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000053820a96a0d098082be42ca900e636041afd1e683a2ddb874a3af9505ce6148386bddb4d89a0593d0793eb193a8357010416f58b8ba618b926c783a1e85b545237743c782a07 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000054820a95a0debdc9f4fea47d6f6cc8848b63c1fba142a381454e0744e459c267c02c96116da0018685e8b288ea29e0a0fb47c059845c387ab87a434be6daf2edceb274714341 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000055820a95a0518208a275d2b716d4d0c87cc73d7dd41504069b232f7c04dbc0c56dee35c64ba035862d60d4bfe05a8055a35bbaf817aae1da507351d35cf3a5f44df056f1340d -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000056820a96a01ae7eca56e1aebf7afd222a69704cf4a36cfd2be9552f78e448d5e6f52e52ba6a01bd5f808d62b4e20ac8c29521aed86e68202b7d153c2c3499d86668200705ecd -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000057820a96a004b46ef03ebdebed3051e54978a27a8d8267e58f2c498f972cc669088bd5320da067abe4d589806bc48a19f782f32db39aa38c06bf4e588a1252547ce106a64713 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000058820a96a0b18c358e883c676736ccae9b3ad7c71bbe4286736e484aaaad7152dee0de6fb8a0511236138e32df8795c22357c9d6b30ae3b6433facbe400950525733b27618f4 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000059820a96a029fe702aa3ef71ae71b2aaf78b26de9028d18c7da80afb52f0664672d39914bfa00b7112692faf0761e7af9a0d387b38c7c8567b7e1573c1a7e08de4c048b7eb38 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000005a820a96a03e28d68bd62f8815f52508beb525dacbeaa5ea40fbec7080ef2e50eacdb9544aa06af1fdd7c41fdc30da7943e1f43bb7d9bccc22f941d7d5b9043e7f457900378f -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000005b820a95a01a13f1d65d05834f3359dbffaf22d1dee4f111e4cfff84a2f6239639187630c2a03314d70a66b57c13f10af2e1d118c5230f1f7ed6e7a3cb7167e7775f893a0d60 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000005c820a95a00deb2e8f069bce6010886448b9a79600cd1d96d918b2843feaf33e76c33dad8da022e8da3c64e7d8aef10ddbf207ad5a545987fc31b9cecf0059d5d13da2ae1c32 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000005d820a95a05be573737acbb8e2084ae5b1fc4afa183ed60d7e5daf5a4aacaa70798249d18aa01c4c1a00437897cd7b5243d4aa6e518d434a9bd646ad9874221ad750433e1485 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000005e820a95a008420ae9c8492d6a9ba83be60c101efab26b4011a4573583aa6acd8de0e83fdda020a432abafa8cdec5508fb8567cf053d9367d2b30f705ffb2b7a3dbabe284367 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e000000000000000000000000000000000000000000000000000000000000005f820a95a0be7ad12603b85f496ca7bdf101e058f135a945853c8f26c9e8d6cc2346ddaa1ea003a55737163dec174064c2fadb46429fbc304ab2ee71a7bee377c5bbfbe653ae -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000060820a95a0e0622df4e38344fc8aa820a20ca0cff6f5bb2145a72b9aebe9d099bebb527b4fa063f3165cf867d5874342226b70c1c919431994d4b8b5e035422b12349e129315 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000061820a95a0b74219fd01f3204892dd0056816df683431b62ef97f865e9e405fc2d2f6f91a2a04f04712199f577d2b343abce80be5abb479c433b2ce84c9d59ae0e2bf1df57f9 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000062820a95a04c6e6e62f2338d10a016e7027e5de7b3df9e5f98a553a9dac197f500771ef0afa018b63aae1bba2dc6e99526a17c3a6d1289fe4149ef1575b3fd20c934eeaea8a5 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000063820a96a059dd98f9ae67165a2d47d82349aef8701736ab1204b39f186e76f4bde09fa122a051b2a28f8945493d80a1aa83aa650a9a0a220e914422a06020f08d1ebf366180 -f8868064830100009412f142944da31ab85458787aaecaf5e34128619d80a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0dd21186e1b4268966872d8d4c0be315ad14de57abd82e31cc4ce2cae8497e76ba01df73779d6a304a97852225d8b4634b1e7da4e8dbc964b03b3e4d286951b3a20 +f902400164831000008080b901f0608060405234801561001057600080fd5b506101d0806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80630b7d796e14610030575b600080fd5b61004a600480360381019061004591906100c2565b61004c565b005b60005b81811015610083576001600080828254610069919061011e565b92505081905550808061007b90610152565b91505061004f565b5050565b600080fd5b6000819050919050565b61009f8161008c565b81146100aa57600080fd5b50565b6000813590506100bc81610096565b92915050565b6000602082840312156100d8576100d7610087565b5b60006100e6848285016100ad565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006101298261008c565b91506101348361008c565b925082820190508082111561014c5761014b6100ef565b5b92915050565b600061015d8261008c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361018f5761018e6100ef565b5b60018201905091905056fea26469706673582212200cd6584173dbec22eba4ce6cc7cc4e702e00e018d340f84fc0ff197faf980ad264736f6c63430008150033820a96a03598e82707fc2a808c1f23410fe22011a97335b4975631327bfc4c134776c016a0225c75f9a0eff8ac0e5e7d7b69f33e475ad0bb5e6187b0915cf1dbf9e9e52c7d +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0bee0b2863c2534713e6c136340c50ba79f3e822364a06d12562183375f29ed3ea019440a75335052fed044de2fd876157d28c1a20a422c2c403e663e3d877b1f2a +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a07ed899d0d04f84399930513831e8c3fd600683a395c194ec2ee0478f0c5b378ea036506016f3ecbda13cc213c6b16c4b7e3a30bfd9e622801907c54c5321ea8a52 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a070b532d7d047f6afc5b171684deed86df54ab8244b8dff92c77d75d2a421df83a057ce6f8d08fac3953ffa49eeab27f7ba5dc07f2b28c8e525432c62fb7003024a +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0035d2ce3e54d69a21bb50717261a63d69da84a8d656977e51cd05a7e16fdef0aa049305689e192a58a72a3a1f92b5e7c605a3465adbd86ab3735e1aa5949b52f47 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0e16155687c1fdd757037964012e5fb1c54c8dd46d8c1cb80e9afa6ada948d86ba0326340db551c8f0ed41884950ca2a3f7537d68a6dd97f1a2911b5d26a2442cc2 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0c552c8d3fb4926ab1dc189defcbe29cc3892a2f342b4c2f7daf6faafaf6b7a5ea0694b55aef8997f226bcb4129aec4acec3b754fc965f29ed029b2b4f8ea16cb17 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a09ae02e6c62a22f791cbc8449aaffb040dc34624b16ea7600249933798b09d010a00310208f1260626474a028a0662af03ff5cbde4d5b001645ef7f0379e0e7c4e5 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0abbee43f633fa4a32e8baa11c7a70593622a8d47955ccf23f6763137b15dc7e2a0586c5a4b6f6ee6398faf98e4923521398a41f47d2e78af7fd1bdadc6ee6c6834 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0f00de6171591f778adcebb133e85ad029333cc1866c0119affaaba004d2543f4a005372e3beb12446d21490d46c1d3a158c812f78d1fca03434391c3968e67f186 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0dbc8b990d3693d366c359c03b3bd5b3ad06a021e3d12c42bf26bdd1537ae3754a07c02a20443d36d2ea07a715c750696f4ec6ff1334a7d8bcc74145f7ca768aad9 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0c28e18a4b0fb9828c3e36f18ba0862d96617b05fc2e01fff442d6e4dc4c03327a01e16de3b7f402adee6d916e8f864cbbd7a1a4316e75fa1c545cf0d8f15ac75e9 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a01424fe62036a22bdb6648be2c8aaa17ede404d666059693a92ab91edb40fe841a01a35cd69a9e3292124bfb9cf42bf40eb5208089e6759d017b775b0a562b7214e +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a02e835c912dee695db88b77f1b6c29789537d3cafa9ed19d52775abe535f685afa018b8cce777fbf35e8855d2de3cacd18eb5b20811f6436e6a7e9b0efcc46a5abb +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0fcb87674c63000daece42bee1b6646838685dbf53483bb6ff1fb5f08d50f5347a076e2578fc551322e5bd433059d028bccd0386f4b8bc50dd1f3ffb269e7dd578b +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a01ae53da08e8595de9cc86da0e55e01e57594319ad8a7f396c93d5e043918f27ea01088dc6b0ae8a7ec21cfd4adf568947671dbc792e3293e3d67f36bae5ae8c381 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a033cd95e9f46e24f4bf0b3b7e77e40b47699bb28c59ffb4c98d70be2145ab6745a011cfc8bf905403487a673524f9a7f1fa569299a5ecd4aa6ce413efca57a28300 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0e7a4a35747e68ea6162559ba7874cc9cf4a8cf95a814902b5359ae6d6e9f8874a06029a56125a4b7ab37f025e9b63076aa93c4e158758476e75a177c0d0743a2c8 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0fc7c5750426bd7533d2c944fa14e0d1eae3d4d88e2747d13ee5cfc522cfda298a041f0bf8457cf2c658f181ab3836f2578de88e7933c585621e457e148b9ede683 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0b53d85b16c0e3b7f120ddbf48793381c9a3cbf086b57fcfb8fe176b79b14f869a011824af396165b009acb7116ecf1623390026630fbb129a78bf64c8387638772 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a01a60b86942e7b26f982bcc5e63c805b5839930a0defdfb41ed4cc511884fbc3aa06aceb2b7ae055cdd0978616c67155d416d5ab20c5d9abc3542343624a231e7a1 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0c079c9c419fc59c41af42fe919653a50c64d30952cbc85fbdc483c0647b701d4a06fb65c715a9bf6c0fc835453641456eb4ea3c83c19907620c235afb399f11453 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a07266abf5f6aa9f00046848f346bada234a5b859551dd94252a2c24825086b2f4a02961ea78f32fd2ef85f322c12050305f1e21a84763981cd7fdfa9cd35abed26c +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a01d47e3cd0f5818a1e8cf5616b8001ee4378fec6096f977d4bd767817ef14a3eea0391a6ffa825ffdfc6ad83da6c08c96b840296c633ce78cbb40cd82c3fdc49678 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a09262cb84ed1358f8f2f7f750cfcffad8172253dc093cc6acc9c3e4f7d3567190a071b0f885e74acd0b029722bb546a13c0bf5f5c8c18ba780813101ddd94a1c606 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0bbcfd3e7833bf6441d464717450cd5743f434339a72b170d530269874a2e8454a013230b86bbd66780641c179c5c4fa7273548ae87123b26d06587f77d21f218a3 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a079b4b8248ae839eb2b1869e886ad4b40678b4ce9f61fb9307c713a726bd99ef9a07b809f69e7971e718b18d1cefb71eb17dcc729b2d9933bdc55c960074b178993 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a03b301980f6a5ce687c27e6ba0f766ee7750a25e3924c8bfd1fb9bb14e9da30b4a0658d1545a5ae83c9ba82c9d77468670c1435ac5df557b9149b63e5edbadf5388 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a051de2d1f1675c5c9338ac05421482d044be65c17a70d226a0f30087ee72813eca054e5a82f43ae0a1ce49eb9bcfe9868c459c80a4d67ee29c77d6ab62b0b9b35a6 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a076e99c4efe35d8cf221a4201432525670194b1f5ac55e1c9db004ee9d83bc726a047525ef26bc6fb20cdf98a89d25ff09b56daede44a5a09c0b7fec1a97e9bd9ca +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0b4a2e12b5679466d97fa004eb5c152f68485aab685432d052f2943b068412d40a03d3f2801a711fab58e3469e6b32d91e78790feb1db3ac429e8b9f3a36cf71f45 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a06ca4f484b6e797ae1326a1a2344a7b34ab65bbf3341e43c7d73b8bc706c2b3c0a0584406aed4bbb9fa0c476f3e47eae6ed8e0535cd1aa3383cb055f29f933dccbe +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0b959de30ad2614dc411fdf255562e096284f18dcef9be6c9c6f29663529aa0ffa04c57836570d58e364dc2446694add5cdf4cd6b8a73eb3a66badbcdd616102939 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a097a154bd6a0f69c2b6002d0097bb1a13ce70ec468327d415e7639a408d4dc63ca07e81b754e6eeef72812c1f811eb09266448d6855b53d05f3864846154d601695 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0dbf14511c95f0937c9ae631fcdf83e04ec77ce5b213d94e8fc38ad3787c9a3c1a006c0997154c302b5868d30bfc911d1b85d27616dbfbcfabf0a281d3e08f17803 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a084da601293f9d14e56c13fe056c580bb77127c7c1c93cc1ea7f5741d0920cf42a0519de4440de2a20ccd234f7f1011d1552d9ffeb022894d2f67c5ed8c996ee6b8 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0d73a57187dee4f4342aa9943b1137f0f65aa5e583627c4b809b6c3502bed6602a07206d91e98663fed0589c64d65215c04f4472fe8cdc2a25a7af3ba04561ed15e +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0340e90489f4353ac8a61ba24b3181c240e25396bd9908ece78b30d614342b8fda045f9c0352b9c4a48328e00d76871048c997b497588ff3607bbc7b9f213d4bd22 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a00fbc95c5f04c3156fa2b009ba820452df4dd6b2c2c3c009fa8218e6bd47e534ca04b484823fc45eda237c19d9d5a155d42c5add82f86bcbe6bb24c0d80bfa07cd4 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a08b53719aae16e799f454dd006111074832ee8feb8ff7150fb08bcabcef7f1436a0207871c9097d826ab129b5b6efc2035dd6f322fdb0e2b0825ee83e63af15010e +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a073d6fdc03294a6c6f339b05983a62fff05832c9af6910c45d3f882b61176a26aa0375b9a224f76b98431a9aff6556178849b828110abbf8276454328bc07ac52e3 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0584e1b035e725ea4ba013a8f4372352cf3349fc08b46e63553f4f639d5c194f8a037ea7b0ada95a75438df0c0ed1d36fba067accdef63aaebc48e5c9c5033f3f92 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a052b1142c7b0e58ef707ceaf0d4752739fba9da4d4dce6243eaa473f037579462a02adf06fb7d83399f536b236e3c33256c5970d49b26cf1f38d7f44ef48b4337ed +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a03510207cecc06511c6f6bfe7412ef544eaefef3453d0a262beca39bd7386ab6ca02bafa1cdc5694516bbd8e56cad0d1dfc2715906f7592dbe4cecada89b21091a3 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a02c13ed1242c31ab557b1e5bf442f3de8e516a9d5ed05028d4dcac5b21d5ec3b8a0058c8a0bea66c828b747b848004b86803222b73dff44b93d2f3d8d51e988afb4 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0a3f5e208a54644dcc26682c4d6de182dca606604e9ab6e7c649c79f3042872b1a0496d7f7dc98b070504dfd05905fb858a1d05c997c62c5dbfb4addf0d15138a15 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0e6373451e5575712e60b49b9430701a6a3bed6a9f6cd0b354bed0f9e2e3658a9a045b011604b330aec397b0dbed350a3fc39feec0cba8781e6dba7e19aea4f98d1 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0c5cd7e4f22cde5a24620c53f6339cdae34ac8c2395d581e661f7f8be6f00e4e1a00f62d428bc386bf0b856a782183a68373c122ddc3b447575608b13a2c896151a +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0b741b10239f0f4ce32e7c13287fa0bd60388ad2dc421c321d08ca4823a21fcc1a05477fa170ca1da7a2a157120fc96f9ae84c0ce4e00bdf633b2494b14a7f137ce +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a039c60f0560ef932bf3dea6ca136e0a6806f26b6120f22c29af6b248c73f3a561a078bd4178a337edd1330c7638d72a23192bbd9b93e6b8c5072db6117f94a6a4cf +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0abf0c7180304601046cdb1e6ec6cc46ab1fd2ecd6869ed305b1f0291be1184d9a04300d502629e56678f3fff37d0c08d9440d2d3d9cf20b4491ffd86eb22756e69 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a069139779a0ca0ae8c2c4b2c0bc98226f54e01aa37230d15bfd1cf8aec84eb128a04a5403df3077e2c573f00e46f7cede8e5ad5283648c26b69caced51644570c9d +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a04a67238647892af9536ae7f010849e9b61be3fba83034bdc0a5f2a256fde1dc7a015322dffa7c9c673cb5480db76b5cc27494146891956784052f198cabe08d30e +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0d5a95203a75952c1bdcb1269ea22c0e7eac6843c0dc96f51bcb7a8f05947f0b8a067200d1848834ee679ef5d0b7311b61172098bf0a9dd94b3634e45ba3771a890 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a002980fd5ab39ba6e615254d9101bf30ba874eb5274cd2353d915c2fd14b16f42a07e69a5f637845ad996cb182b941eca2c955f002fe207ec58feea4e4dcf624d77 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a015a166f8d22a3f08021dd23060edabd8454ccbad88c1b0cf36c6e1630dcda57ca01209507b60491bdb1fb2d3f3b0ccb796360ff8ce9adce25702ba1074ea47f423 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0aeb6de25b070486ee8b2e9fed5a7f8d4c2db55f2f63e5dfe8f57d7f06a039f31a051c420e38bb2ddb1b86d18796ddb8444adacc45bb84fe4cdee13650cdf275f52 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0fefa55e1c2783986ffc915e3b3ce6efac8cf36571d5d3eb883a1ee4614a65e92a05a3410264a266c37781985a9613bd1a681cfa870c1fcb4e80d0eb3af6afa9376 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0f899ead78aa090c05c1a01a118320533eaef7dbe1bb96fdeb07abc8101d6f163a07206e8f0233f159b8e6b4fa7fa7f2f671aaf2628798fea2f6e6a92dea6a7d94f +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0b41d3eb20b7d004e06f06cb8946e77f5493b082a6e59f4b2e29871d9573e8c58a051bf00cdc82746929d52dd8e8047e85cf5fd497e61017e89c520180c395c687d +f88501648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a969f1797cc87ff3875e865b7ddb30212eb01f26931f4e607521c8a5294f77b50d7a058d89cc91c13c4f4b37d66636453961dda768bb5af22021e6393753d3eee2eee +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a00d9a26099248d1d11ec4a856787baeebcefef0074e0db12e6a1cdbd0e8aebe24a05ce7cc4c1d83cffabd289134d7105e26fcda1cd62ca6af4481afd72a6eed9950 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a00d900d1f17e890b111aec0c3181abc700e409d834bdf7b45469a76fdf9e74c55a074445dceaa1229731674864e3a7a314ccd3381fd2b029e70c03128646e98e05b +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0779ca710af9ade24a7f4d655b8846cedea3c9ecdd3f1cb13b2cd999665e2656ea02e8aafff4da283d77a079bd64450d3aa3fdb4ea61a7cbe60779a1f7d7650658a +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a02a433d5754bd7a308bdc2ce6a86eebdbb8e6c9dddc9dcf8ee63f4f1fb3f2654fa00ad6f282db0ae2933859311467bf111c36c293069e7cb1e921b5e4cc189a22d6 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0e1068f879a8aad6707de0354b5f9c01595b57ea095199a864956670bca6aabada047498f7b9bad24056e95fa6cb29fe2f10b4e6c0efc4af6c7ae98da8bb3e21984 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0d1761af1fc5423e9a24330b70e61531742efaf73a6c876031e0df24a27039431a05bb22a4421a4386887ea898eddb21d11cad88a47bc72cde1b0444079f1296f83 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a060bf0dcb807c6c4a1639b45b83a13dd2c5e8fe374e11de487a08247b90a3cfbfa07ba803f02251a44cdd91dd2aa0ba70e30d7042c1daace5508411e6e8a9efead1 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0b16b76d84732d44d506e40ab9084581be0d461419957a0c4a71e7c12f37e735fa05242ca1c17c9eb3b10f2f453426227667a198a1902058339923a9cc50668929f +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a00b869994f5f6c1cfaab725f5119ab213c0184d8d9526103623376138d8fc42c6a07c51aba5936d1b827dce6012b01558530a9041128bac876df9fe2804670f7e3f +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0f486db72787725bf477b4ade30c9d6f56bc7394826adc3a6775cc19a527dced7a073e96c2eca221fba8ba00cd0f965e9996f7940c389f4fcf1ff4c654038b9f9dd +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a010fc5f54d38f6c6381406863b0198cd0d1dd7252c9992d41b4bf3452415735f4a057f25b851143ae2539c6f4e5af036da1f05cbf4be919e0d7167db9e7507c163f +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a08ac9eade5e71cf76c9c8bc69f358657ffcd9fe03ced7df174aefee50194549eba053a779a9d1d6e14eb22da9a84d21acfde7dc0550e4c59d862828db99791ceb64 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a061e16da914006cafceac1a7aec11654b527327619a56f6e37d5e735a00de369ca069fc54d5828acb690a14b9852fff96af1dd229bb207ccb067c70e6735fefedfa +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a08569434cd9a090e0dffa70bdc0117493cac7641e06870fdd5f8589fb814750b3a0731a98baba9588fdf0d50ef7b25f2f92dcb13b2fa997598c32c531ceb60118b2 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0db934dbb6a7046e9198a1348562221944ad7984eb2a8cbdce7b9bd2c1d72b741a05fc64f46082cf5397adee3f32662c7b7d065b72cfff6caec1347be09f44cfe79 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0465be0166c3aea7506a6eb4ae4369aeb68d3cd5798f308192f0bf6627af95a88a027170db564c0e80a80b8e609344bf83aaba2a60eb5433c104340768b278421ed +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a077cb89ec818de2fe8a056ac3780613518ce369bfe31325e48234f4ae6d857846a0287806b5701e55d266a2a911103459e2e0e17e0c407663c981697add1990ed3f +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a044a25b6ae760a05d72a981141bbb2012aed1b155da8269aff41b2b07918cec29a0634d3e260ddfd5eb331064528f8c192ec890c71e2d767c389487f6f71fbaa97c +f88501648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a959f411cc919246260d01c2eb1592495bf6c2409f946e284b4c992f64f415fb052a0225aa7b061f9c9c32d7eb876f1766983c9725c4f438edd90869d48a12a5af7f9 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0c986178810025c7d7653009e03975ad9a9dac0a6ce44738bc273a42a2100f11ba0557afb34d7a200d7600b61fc1b8312d365168cd67cb432720f0f7dfdb671d96c +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0e8d6c618de866ae29697143eec5329493e5f171cff374ad8411e042317fbbb3da0233899aaa0ef2aa791ee420954f7b4b8ae96ad84539cd70de2b6550f1d5b5f9e +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0065114833c86dceef77858cd3a6219eb08cc57ac5d068052a552aced5051bf33a02d61e3f672a3da61535a5724292c78087b6924d6bb3c4e627bfabc49bb7f235c +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0b4b57d6c7a93f0131290518652ecfef4f1cf5756b8f5f0fa18bd15158a14433ba014031d0283e33b980ff576d30b5d016ddb0b3c7a893b448b8f7911781c695ca7 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0476f574b84a867c476274eaff76282a000281eb2382deabb9e219f005dcb7cada031fff9fa363d907bfd57fefd2185d3a7fccf8a9f4aa27595499ad2c806c9b39a +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a023d70653ff536871b0379516eb5b7866b533924fbec1aa3a22f1034b5a6917cea04ebed6bc7947ed5fb547bcca85107209d40bbb25f539b6de8cfaa6879e63953b +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0e8130d1434da5503c389fb8f3bb7a116ae64f7badb9d0317e8385ba23f68425aa04a3a34890aa3c50df2dbe895b4a96314cdbc1f85bfbb28efef674b082a1f736b +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a04fc7a12d9801e3fd8e15cd0f9fb656c38efe3dfff657ffe9a7fb8cd0dd6f4684a00e89001d03580d9d30f4f13ae78a3260489c357d60a1f54e06c749d1e913f82d +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0098f28532a5c91f72027df717f4e2da94b08e691b36d7b11b5ef6939846599d1a044a443cd11eaefbecedec4dce4e3b4767bfe31658f75fbef7cc86cb70e040eae +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0c9dc923aba3a4fe71831545c5c4fd7dd04e56af703dd2056193c01ffdf8401f6a016a2af741cc3ea8f674437d90fb5b0add85dc2d4c0179c1d16f00accb42dd0ed +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0dae3b812cdfe3ef6fd31c3d97f5ea29dd9daee716d6bf5e5922784dbcabda960a0552046be8d02bb14303fe8373fa00cfbc9d849ee61c8b195037fda4689c62247 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a003cb5be7f0fb9fd2fa7ffca1ca09de38c58d5dc865d3696a8d99bf7e78bb689da05c9a210da64b1d8100e386b86218c1a146414117cd160b462ec4ae875c396a1b +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0c66232dface3a3c4842537331c1bb82b40af73d355e1dbdc2941dc4744a7da22a07c582f2d55422ceeb280f066a5615fece52573370796af6ac0cd8b3d33e1612c +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a02e02513f5b950a66d1f936e65599f8314fc5070ec3751c94bd94ddc03e3d59b4a045d2cd526770339b581f94fce024a56e1457cee50ced76c85c4108e1cb620212 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0c1d5e1e5510c38edca36ba850bf3d6fdd2d654cd8a8039c4516b32921eb10f7ea03e92f4655fa49b2e644afec87d8087cd5f18ef0a52407e8b472f581cc17af114 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a078654a9ae7680a269cbef08c87fa12a7ec32c031b49a4ef9f511a7c750c554cea0085d357737976352520d7176b565081f0b534006a3ddd2b74e32d094bf2f5c26 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a02035e31182d5d73961a86a2145a8bc32230f256d61662c4777d500b1d4fb925aa021bb1331d150d158c40c70ebeb941d061e6cdfeb2aa78c03e11decd4eaaeb3a9 +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a0916b83fa1e4eb88659a38022e172889543823e12131caa4c33fa901f8246bc81a02a6bdd183fb9f37db0845f7f881a8f20b095c2e0a67623461e5a520f90891eec +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a0d8be97b644638f3936788a3e10de62524f47599188d16e0a157f79f87bff75eba02604417dbf7b11757db90c65098118d27fbaf7c2bad84896847dabeaa4a85d2e +f88601648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a95a00be8a11646a4cada589df6517b83e9897da53ff5bd729d6238137346dd4bfd09a01e8c76931781ecd4d979721a889fd4543d2593b4a1be5933150160e6036cb9d7 +f88680648301000094b05fef09ff8fdf67e5821722f65d5876ef339f8980a40b7d796e0000000000000000000000000000000000000000000000000000000000000064820a96a056be5318019fde3e4ca1d47b821a24406d2d016a78b6c4383e7c37c3474710a0a04c54a72c115f04a40d2c61c4a02d1284bd322235892c1d5ba9c39ca06abfb211 diff --git a/tezt/tests/evm_kernel_inputs/100-loops-transfers b/tezt/tests/evm_kernel_inputs/100-loops-transfers new file mode 100644 index 0000000000000000000000000000000000000000..8b1fe9787c8f3e16a93d7cddd11026f77ca90b91 --- /dev/null +++ b/tezt/tests/evm_kernel_inputs/100-loops-transfers @@ -0,0 +1,101 @@ +f86680648301000094f0affc80a5f69f4a9a3ee01a640873b6ba53e539843c33608080820a95a0cfef4f3254d8715ba39c078a09cd0db721060c03efab5785c78e5b5ccc598ce3a059402860e706bc7e07f6f36e3982046b8b54ea90cf455dcf35bd22aa9d28fe7a +f8658064830100009494673842faf3789947fc905a15b6b7b071455ee2843b9aca0080820a95a0307ed0536b37db527513071110fb852bd7d8e2fec7485ce9fcc8269c5d4901d09ff5fc280e604e618301329e1411eed4e4580f6c2002c12a0741d86e30e200c7 +f866806483010000949f97031f713c60686f1d5a6cd59b2515b307d81f843b02338080820a95a0eb53f4b5c261105e5371edc61557bc439c9a5a19f6d1681a4fccc1a7495b6f22a059e342aab297e0e4c2353693b1e4944d6bbdfc770bbd75114a7a43526de656b2 +f866806483010000949d9d08b7842dafb22127f046455f4d421a496545843a699d0080820a95a0fbfadecd9264a82a6b8381979fd749c3cc36b86d25d72e0f5e16b52f2fc6ae93a00b220b8790c9ca936f0673f677e3775b0c62fe3dc93cbf47ff66c75c5c695ef8 +f8668064830100009419813d6b9939615f9d4ece1fd8e1c92ba7bdc89d8439d1068080820a95a027f63cb8fb59c89b961a500dd862ac4aa92e6f608696c660ea67186dc775b990a028e774c190b6e455081984b0c61b9dc534a611807847947f43d97b870609e294 +f866806483010000944fa9cb08879af044712b3236880ff14f30ced1ee843938700080820a95a0032c7fe69c82f8e050b6c36f36c846f2a66833e7a1e640cc20b8acc3acbc3daca048970799511d6ccb9f510970e0be486fc15aebcf91cd2f96246a221e1c57636a +f866806483010000942375768347eb24c507f60422431b6244e1834e8084389fd98080820a95a045d3045f1c3a34ad8ed3612ca202e5160ff6fedf9fea983aeab0739c1d162a8ba057f88e9c32f31aac9e724005f55c9ab5d3cde88831d05a6adb538d00e16d56fc +f8668064830100009484e0fb3a5534fe0cbc38d92349da59891076c38e843807430080820a96a07666ce8e284061de6ba691d90e7f5271aff50a820f4c184923cc671dc386128ba004b590e0a6fd1ad0f5b84b2480a87542fa33dc88b3eaab462946bd191e9970f6 +f86680648301000094287df215cd47f174c00bc5f319c0be39bd87ba5684376eac8080820a96a0d0d0569c45366a891a0d472fe7f570c989f776bca513224d4d6db53c48dcb98ea028069900fc0bd5d5d8c2507e48cf00550b699dec1c285d293bdd8f8560b7c210 +f8668064830100009459a693b5160f5405bfaa2c8302764022de3abde68436d6160080820a96a02fdb346c4bae1c5ca70d0a1b46882dffd225727f791d75475d4b4a32489826a4a038b9632224546bf49512a25a951e5c5241f1b0f1884c6bf3c1770413a86009eb +f866806483010000941fbaba8a6002a207f6e8cf1a4b6f50e9f943440584363d7f8080820a96a0d9d00c89327587bcfe4bcc49a899ab53d42e392c10bcaa68046a15e08f848133a070838eab56857ce9eeedc4409bf774f6509494356b8e3db5e4ef20d168e7924b +f866806483010000948820f04fe280c9fbff4ce443b73fb702a397bcba8435a4e90080820a96a0514d2a3a6f1759382d5512f264f5a0b3c4632aef71896e7bc235f6651590f1eaa00888c45ec74c648cff31327a5d6fa601b5e399baef25b3fd95ef81cc7998a89c +f86680648301000094ec7bfae66a65b29119c198fc471cc1dbaf59b75d84350c528080820a96a0c3821991b4ba4a085aa6ea396cf3692af4b78ca2779e4e83312e747e157df585a004ab800af44c96a5bc9f0ae3e2f31794dd834e398d4d0dd0a107721fd96d824f +f8668064830100009446c1ee4c12abfe79af6de3739b9c189689a42b93843473bc0080820a95a0bda2b83ba4ce4f875a2887819bc4a77f5f9751218e16828da2c66b16913fbe78a00744eaa577c0526464628053bb68643987e87e7319224e76819ee2092931ba5d +f8668064830100009487ffa944dc6c457b069b3a4d3f3061b025dfe0238433db258080820a96a02e8a1406b3fc83a505434150a9c8ee24121e03bd0cb2890eac43446a87d38509a037eeebcbbf53c410a24dea6365e5d6420900c21a47302d9063d218766cdef291 +f8668064830100009430aee911fbb009c69b3977cd00a23503755f747e8433428f0080820a95a0756f02a637565e3c3f05335d6808c58d693823320f032e661a6118a3efbbbd49a06da112771e48831fb7778cdbed0f400defcc93a7bb1b92ffc5af054a0f5c78c1 +f866806483010000944b3cb8e4ababd36fe5ce22d60a635598393419c08432a9f88080820a95a029cb290ccdcbeeda2d0492d5bdce0a375826200008eed05f54bc1d8e16109b69a070de5c992d27f23dba6daec09ee17de009dd47b81124de9bf9c5e13e8fd57d41 +f86680648301000094efa7dd6936b3e9f8fa5e1e0de18bc7db0aeb42ba843211620080820a96a08d74bd8e9c45de14051268b020a0f06bc6a3d94beb276b876465db1d39a645aca06a2cf7a4a77052b9d9064b91dc90d5b210e55fa631fb0dd0649f5e23e5f1a465 +f866806483010000940421d495995dcb62a9504ab972647a69d939658f843178cb8080820a96a01706010d940e9c31a9019ae28845ff5fdfbd765036edc831968e50a6bc28f68da0337c683945e5d9c996e358cf744577de7e5e9b3ace481cabfa22e7b894ef7232 +f86680648301000094d796a839b036dbc9cc42b524d0e1ed5001a9b94c8430e0350080820a95a037806db425793ad128bfed34e33cd2df420692eda953cc98767b0e87d2acb745a00a24f291f7f83affc449cfa0699f2f03299175c7668d008b8818d68dac3f457b +f86680648301000094c412f3d9cc3b7cc19500bd3dd051fc006fc6758b8430479e8080820a96a0a28ed5e3586aee860b182397286a14175726f66e2b073a04fec033e9a0064ccca0156759e4a3ee316ad9973247bf805d3c2e40a4ae9a25bf42ed967033d543d1f5 +f86680648301000094c30b72352f432b8344abc51b2437fc4a51df1988842faf080080820a96a0bf999c2eb75325848086d6f8a870b1f23c77c76e93bb3133f2b5468447d55c41a001119924c4f16f0ab9d502d69aa83c2946352cf524ac5aaefa895f5ad5599f6a +f866806483010000941a702bed8f4ce9566097312166f55f6c72c4b14c842f16718080820a95a067f7e59df885c83406de567022d0e954276f9cd4d03bb008e9d5efa4f806ee7fa04eb964bcab1b0ab7b699e7082a4c11083f0265d11ba8b801e9296c242eb31526 +f8668064830100009493dbf33801c830b19764f412f1381d6457334bd5842e7ddb0080820a96a0ab0b05ef891a653c1c1abde29be35db8e8c92ac4d6461ca32f7f0e3f033d8979a039bc6d719f8f550fc5cef9e7c01fbbdbf0b7ac3a067bd3761f8c52abe3be4131 +f86680648301000094d0ed26699d40dd848b355937e513575bc1138e6f842de5448080820a96a0a9118d5697ba65e700a89a22ea6b5489b2a7c26999c061216a971271794be92ca04d3550b9e13c11e1c3ac5919f73e0e83e3c8ef268a67ed0ea58cda8dc4bab5ce +f866806483010000946f5f717eca06955b7bcb25799184120abdf1d6da842d4cae0080820a95a0993806626f3fbbc3c8556dc959be438d9f50d7f7990036c4b31a46ce9c3c65fea0057dae614ff9100fa0cdaa49c8028b52bc08977607aeb3b2d6e1ff1849e43bdd +f86680648301000094ccda3fc470cc2395aa4b8386d02ecb7d1b4a2f5c842cb4178080820a96a07b1a63376ca8bd79fc7499a9ffd1aedc0e08f961b8aa7e1a20ae8a3806497f6da02897a7c852f1dd946217f894a25ae0f70a8a1b7720fa09fadc15f333c2eb2c2e +f866806483010000943ab14c9e1e91cb6d230e3d31d819fbce4ecb3e0f842c1b810080820a95a09e5441843c3bd42ca8a6cf7057966e4ba74756e84e97e2dc68c549a2765a4f9da02234270c1b684bb6f4738b78fefe336018349277f3c80e0f49f6df2f867cbd2f +f8668064830100009455e3b51ce349e08fedecdf256427aed0b1ec1954842b82ea8080820a95a01ca19593d4675bd9d4845c197f41e3d86ebc00b56a69b89510056276df881399a0710de1693a4556625b3470190a67d367a5f47d476c86be09a229c0c5cc4de02b +f86680648301000094c6bd66ef8c3089616509161e7bdfba20c3250d87842aea540080820a96a004978079c8543d1c28b47edef712c579e7b2e8f93cccaa86c549d5bd086b1b52a049f58b0f1399927025284b293d155af34add24679b26cddf468478df2f453a40 +f866806483010000943be084b00983e93d66a94fb82c51b040302325f7842a51bd8080820a96a0142e9601fa39f1504eca5dc5459e38fa71fa29ff1583c594d42b3515b750787aa0664d153b4a46332370c7f2257fd6653619dd4072ce5c59973fcf3b16178b7c3b +f8668064830100009466310f887ca16ec6e3d7692f4d4ba80d22b61e1d8429b9270080820a95a040126fd1afb6276c2bdfc470b2a9bf09a05057a99ade050d3f02f8e790257524a053960753c99900e743ac06e31ac0ca0d6a2af85a86ddf779c433608f7fa40660 +f8668064830100009400d79dca84b4400b665ba4f37c5b1758250d20df842920908080820a95a0ee2f7d98b03aaab7ad17f7e27f2e0e9edbce0e31f5c795045063fc764b0fcb04a01d13b35aa359d461c4e99ed581858343fa6e9880922c6ca059c8fc6429d04673 +f866806483010000941b05724f7694281da89befcd78de87056ef0dddb842887fa0080820a95a042db432623a7633fb68419ed1158e5292ce253df92a36690887ab8ed8fa2fca4a0564bc09e566a2e7589817000fedb9e6dae01f4aa3e68cdd4ab7ed04d9b71eb9f +f86680648301000094404aa1cbe2e5616da70962929b72185b9473db218427ef638080820a95a0e7e1e4fc8665ff42228720a5d030d0508f1b687769084297d1bdb7d805b60993a06cae6a883c093de261a63a51eb6c0ba47f2403eafb3f51c7a693b62048c027fc +f86680648301000094ec946dea84f536bd9810c5264229787842e58620842756cd0080820a96a0e4d8c320093a643775ca4f3ceae3d8bd29e8617aa75ecab9e6be2ef6e5924d9ba01814ea352f92e327ffd82fab22a4db8cbe33832b4c8f0bd18dcb0c024da5df3f +f866806483010000944a172e6b99058411f25c0c7e774fedebecd4fc0b8426be368080820a96a04d690c07f389ad0c396b7414f681d2de91395312d7b93dc400ce01148fdd74a4a02691f1323781f51e788ae4751c19acd0fbec0f07073d326346804dfa4f4b49c2 +f86680648301000094ef34b98e8520678a28681696e805a78b9c75cab7842625a00080820a95a07ab2a71c2f814cd9ae973bd516643392ff10d0293603c66d6d070687abff2c96a01f13fe4819c9d3786542ea6056b3a607297982c2d76e739cdb2d09fe9d0818b2 +f86680648301000094ce69b662d13d9d3be1c72f726f0f9685c0cdcaf184258d098080820a96a09c329930d492b8471e01d7522019bde59c0fa27c11533ce8a4ec72f98109251da01e60b0bc980a86993293691e5ae6b272aaee9b23599b0069fa10014199ebab3b +f86680648301000094a6ab701fc79e4598d6418584bc4dba95efec92838424f4730080820a96a06e7dd23560165f80b54bc24b2a613d2a3bac774c9a257733a2492da972f468a6a0370dd31771880c83244f44f53fe6e03410c0c1d61e2c8aeee6a1a249f86b005f +f8668064830100009468684dc38610945e79435509287f1fa97babcc5484245bdc8080820a96a0fe69489508e73b88c55925d53325777fa05167c46e66c99c9482d02f0cc1cb7ca04427443b53621d1e87be039d4e1292270e4bf7e2053d703ac931bf1a5cf64a83 +f8668064830100009464406fd102881c7c42c0939be47378148c6c0e4f8423c3460080820a95a0570f41efef90223e7225218c01b07409d518594513ab93b7ec5aa2ebe9359802a034d59bd73fe830eff40106c2c28426bb1ce358525b86b3e6519e0b672fe525fc +f86680648301000094fcf5246018cda3ddb6d1cb1a88f2b63a6d42377484232aaf8080820a95a043bfe63068641dfdb66d4d5384ecdc1df8bd83e8eccd6aa10c670b87e080e9a5a07acb083968b70a42e3abce0cd2f991236ee76d7b60279f3d24ba416823acc2a5 +f866806483010000948c718a0877588fd735f42b4025e942c59a6a8024842292190080820a95a0b7b28e03bcea4356240620d4989988fd0f8b1e56ff3d68916ca83a0145260d85a01f2cd25468424d6eaf2f133d118fec42f9bfe0bb8b3b412672cdecea548a8985 +f8668064830100009457608f643bc46355ce4e909057a3bc641990adcf8421f9828080820a95a0e01fda2d0cfc9e8b70d0b1f15e8f8d09e0deca24b10860f66389a1da3c664895a052d9ff3f7df54168851b7d036226942b4519800ee4268c85bb66d59425cbca10 +f86680648301000094b8aff75713742aa36aae4d5dddd31674cd293f1d842160ec0080820a95a0b76c9a7f2b53c0f62b99513b4a06feffaf831d738f0378924c4b6d66ccbf1287a0214be454d35ea87fc5f8cbd109d10682e0ff590bd5fcc71a7a55ec76445479fe +f8668064830100009453d23d43754c99c35a5faa4cd681c14107374ca98420c8558080820a95a0d61f9d082f4d2a81ab967e86316e0888d0dc4b09a916d68258617a8961eaf0f3a04dfa347626b904cef3aa5802fa6b7f95e3fa4a6b53f711fba1012113cbab97ac +f86680648301000094daee5cdec59776e99009387dc0c66a1f3c2f35e684202fbf0080820a95a0ebf7da31943a7a2e81544ede68e6440aaa78a6238e830c95026d3e91d6f7f38aa0232b8e0ffe6147046aed06f427ed40d41559042dfa44722840fd4787a55fdb34 +f86680648301000094c44c984e65f568fcff4611b960faf3c9fc43ae63841f97288080820a95a0ff93157e49a34e02091e752d3d4eab9b4bb5cdfd5090bbd46583fa0c34bcaa93a037d10a26dd0cdba7ce1abb4a0f35e8780c4d0512101bc95768896b2c46c06641 +f86680648301000094c492d402f452d9e15b78b643fda4c5c77f3829af841efe920080820a95a038636719703697534eb0acf9c5aede18b59d3da50321647f1f3fabf51c2f8a94a0586c736c28b61795975faaa1840e13ceaa3986e4b2201a65a9c8c13f906ebfbb +f866806483010000947b0e6b60d7b5f370cb86187c50696488338d3f8c841e65fb8080820a95a0e6cb9f423adf023fc52735be730bc5e389a55ff96d9f2b0c80e3ca4bf3cc8d6ba05178dcfc31e02acb4310cebcf1a7d38fac6242673b0be3b229d577f3028163e8 +f86680648301000094e47edcf372f82eea3a23baaa486ab54442b7a9e5841dcd650080820a95a0b97568d23044142a6b652561b2ea53cb2c53efb98088a7a41494bc6db57ce51da04c129f44d32302f82e05f2537771bc1278d035a247d9ba3f5e7e2da1f0adaa78 +f866806483010000946d9ed837b95c3bb055111379a9cf34fc5e9efa3e841d34ce8080820a96a067459d2c86f3621dc30ceb6cef73c4cfa2b8b2b03b255ec063e8546c06c6015aa04c9e4bd050e3c61c4bd7047583f804790abdccba9ff0dfdaf0390dae8fe7f558 +f8668064830100009489c8d5f70d1731825f51658e92337e5945f18781841c9c380080820a96a0e6be7bace37e31db436b4a59587d33439125cd19d20e9366f93ea721dbd0d614a02ba1c5f3141e0d1279aa81b6e1b79161444a111c77a40f90eab459d7a4bc730a +f86680648301000094ea09d8baa3cb9d3774f02733fc5077e8574b2e65841c03a18080820a95a09711b0d9fd43489d7a05c3c59568f43c2462a948b7952850ac6b198892165cada062768df9b7a55e21b6ad9b94842d8e1fe2e9f600c698bfe4922b563480514c81 +f8668064830100009489193d12abe5a28a610088605487f2028c6693df841b6b0b0080820a96a078e698ee8a28b784678932a8aae347e6e4303241536b8901a1105a4e9004f3fda06124407fd0bc3c4ac7e23a7e2a2011fa23af2ab8839541eea3ae246be7a6519e +f86680648301000094939739e5d00ea5ed8b456e39eeb9b0bcaab5cf8e841ad2748080820a96a04c52855abfac835f8283ea21313c45b1c1b407c0c8882fb397e3e0ca0a48f01aa0060709c7057330c64b9a21be4b9c2959e5f7850a77166643d0fa2dc2c28e79be +f866806483010000946e90779f02ee323d753b85718575b34bd133083f841a39de0080820a95a0d3f93fc4971fe06934e042eebf33e1dd9a1a32272715263b83b10331ccb1bc36a06ee49392f94a5eb3824a843f9ac909b15e3793784f9bb2e47d6067ff5cbfef29 +f866806483010000943bcde5791701ea4aa21f001c7519e6affe5715d68419a1478080820a96a0a501fc2dfacf832257109d3cb2ad83c15a35cbede3e4d3ce9f2eed62f8ea2790a026f76f1438b2a8fde29c441f57d54624f45ef38ea6fad5d001b00011dff68aa9 +f86680648301000094c6df6cec9d211b4a995dc2fffbffc14b5bd768e9841908b10080820a96a05a7dc67d0162283d30a728ec0d8371913f8307d3969682876baa98252cda4257a00b7c1ab9e24b5681dd96b28179107c3250fb2144a8e816fd3ca58e4104ccf097 +f86680648301000094a7229ec1552f021211f3ac3745a9d4918b7769838418701a8080820a95a01aface16d210497c717a383ebc6e85270c981b10ff529299c4c6b211716bc072a02210e0f77d5c126d20e97c50e0b1c81b10a05ec6a4597ec60ee948e5d424cec1 +f86680648301000094e6b8daf856d78878ae88a0d64c2196de113adb378417d7840080820a95a0091dd8848e010dbf70db6d2f968adfc8f39a694fd0f9f15f26ee04936566fb96a06f26e5fbbca2b64b6a67055f79ac0a247c376d25698a8b045cc4f78e8a23a6f8 +f8668064830100009446e1623aa0558e2766b770d807ff518102b8118484173eed8080820a96a0da5ad9e154560be0ad8035302a134f435952cb2e0b84252792a665c6042227e3a05015236d968b0221a449a28949a41befef14bfa24e561a4c6f1449b821445b54 +f86680648301000094e99e91e191b387ae3fa8aceb59c8d604e1c994518416a6570080820a95a0fca5d87dad7d456cb6c40661c6c6a77840b67bb59c50d21377773e2029b60172a008c893ba645bdf6b863e995e69d72d7a596f3bccbe6e64e33e616c36ab359b25 +f866806483010000946f602bb808fd1e953a04190c5b11eb09af5b7f7684160dc08080820a96a0038bb53fe883bb0a16ffb12062d292a223721b6af121c4765842c2232d03ddf1a015e759463b3a8af1e62f2c756705f758ce7166c979fd6c43751bdedc75993096 +f86680648301000094a3eb9c4c3bf7c5efe158e204d55ef8cd431c9a9f8415752a0080820a95a01318e17458ddca9013130158cbcd735d489a72dfaeea0ca9b94cdf37a2d36ab7a0591c4068ad38e3f46a7c880b856c628f15a1e2ade1a6a0f67205dc20a4679617 +f86580648301000094097cafd626c59d3cef2df57166c4955198ff7e168414dc938080820a969fad2c88552160ea2642e6291b6b9b7d8341201cd8a489f3964eece8d7e12a08a0272ccb56fcf7af4ea381a559fdb29a14ee20a7f92a7d7418f1b5fcab41148af0 +f86680648301000094471fbe86ef3f3ed93489d008a779f45c4efa4a49841443fd0080820a96a0e3182139f42814ec0e07c71518eb5b8bddafd0b60baf2c07b3ec3731f2494b38a0434babe2900e0bb76fc9124035d1a642e494722a8ee74c61b635623df29786ee +f866806483010000946c8f9f662c4c5770e4fa5b79a38c731df15f02708413ab668080820a95a0726b86d1924df5d4889277fd8c97ea438e4e20bb183c256953a23deea7fb7915a00a00b9826848d156213d73ff8dc1ee274bb2052c7a1218cee3ab845c6b2db17d +f8668064830100009443bc2295c985bfdac1954f83081afe0ba7f7ca56841312d00080820a95a07a4101e8f2ed912d5863e562347a45988a4c437359e73479faf3f8611c92dfb1a0019f99c91249bbbecd2ce8ebcbdf383affd6a6c718b4588b378b20b28500965e +f8668064830100009415b1af1b3ab0edc696ea822346569419375d3cb684127a398080820a95a039cc3bf9c8f9148bfbe16a6de9dfb7edb4c5771a69d230dfe9602de202eaa4f0a01c475fcb3ebe17529bfc331fc6f2913fa7492e2cccc492d9aaf766b132c1820e +f866806483010000948fe97681c42ee298b0c1bdf48a4af6976d765cf58411e1a30080820a95a0220c9cc7028ca57d407c4191daa4c2005080e7da4cc13d522b137166ba302a5fa055c9abfa5067db64c505da582d4b39c033b5d2143fa34fe0e9b09f7d144315d0 +f866806483010000949fc8d995dd38d3b8f8271af40bd678aeda5c5bc58411490c8080820a95a036c7e86486a063123cd1fb8609c306f48d53ed274c69484a8257d2ac379b69eca064413b76b7c80d13be779d0770ad83de3d60a4fd4efa8f6a0bc08a90843d66ff +f8668064830100009426011c9100ab1cd6f0644ee443d689dda1f0af118410b0760080820a96a08398b1264ddeb03e22af42a42e11b9c0b1564c5749426438aeb338f317dae59fa0731c59b7b61e8b26ee87f3a9d451721663c2ccffd653d95d77bd3ffdb478c480 +f86680648301000094fdd567f4407bcec58cf0f4bd7c8f7a5f752f90a4841017df8080820a96a024869ada413f5120b9fbf21a07466130d75299b01a6aa5396f211dbffbd6299fa06015bc8e5ae7d7a4f28ef4d81765ed9ad53aa0900fa180667d6cc37c38a3f967 +f8668064830100009467d5d6bfd3ba17dabda076995a11bd43f8020ac2840f7f490080820a96a0fdf8b48c0b8daf6f3ca30d1bc801cee44e881cba2a0ded0eb145b69438a2f6eda05bc29503ff60d79c84d5852aedfffc7f35593ebdf07afc9aff364e406527ac55 +f8668064830100009466e3d63a11bdcbbc63edff7011a8af35c8bd1fd6840ee6b28080820a95a08e7b10abdbca998d9d95b1d199bf992964576478ec9aee86d272ebb339ed3788a03f13c1dae91f7c3dcc507b8144a057c41addd92091f05dad9cefa745a97a3d37 +f86680648301000094f5b9a88bc1e8ce0e6714a77b8bc74fa83e202d89840e4e1c0080820a96a008f88e3f1a0744b4c4fb22b63e74b1bb5ff4441852dbb2d1d393ddd71496425fa03e780f61a5543b034d71984bb04b85ac2f0baecf50f91b549b4ed8eef124dd67 +f866806483010000947166739c7957e9ef53ff0aa00cf4838f64a4d34d840db5858080820a95a02e4137498bc76354cdd75846dd474c5daf2939079859af16ccf1ec3e932ecb31a078590d09abd340a17e38ca208efa3a09ecd83ac7b11a8e6ebb35bfbe2f43f9cb +f86680648301000094e930a21a2f8b27a5f6ce3d750c8591886d7dda3c840d1cef0080820a95a05802dacfd423d6ddd102051887b817c26ad06d78c28176c99941d3561852aa93a0311742a7270afaa443afd03efab5f01e2519c59a4dcf150ee31328679fa5fee1 +f866806483010000944643e3ad25ceae1f53620f33da06af22e8983689840c84588080820a96a0130a26eaef72bb075ab7003b82f1203ca3707ae60f4f92f2dfb26ed40f302812a06f8c1e4d2110af3f614620a82898b8592dedfa045fe88d4a697042f9a11076a2 +f866806483010000947478eb52fcb86490ffac16a70118adc12a348ba9840bebc20080820a95a0cefa73b0e44ed668e069cb517396ea464bfbe3598f343ff311902ccecf57bd40a07f81bbb24eff51e9d005aa6551054228e184f72ce86e0146dca0bcbcd7090dd6 +f866806483010000948d320bcd89bb3b8957c74a1ef945e72fbfc56a6c840b532b8080820a95a0f1ff1365698e80abb8b56f0a7d609f24e8c2433b1b21c08ad3029e792f884606a03ac1a2629c12a2db54009873be2f600fa8d46340786287aad372971c72700548 +f86680648301000094b5cb7e364da2b4ae245b28e2fa81473e1fcdcf79840aba950080820a96a05ea470622a54a08515df3a5a716562d1bfc72b38c6a6b9a4275e55c2d6548c78a040769dc0a7ddc71b6e3aedeba26e0ff9ec6640dd88c5b23c27c661e15e24fd12 +f8668064830100009418fc8814fb3e9b7f1f5d88c1a603f1cc68d2b311840a21fe8080820a96a0a5179272d18be8dcb422c79fc9473c5b84c67de6f2616f56a98fd1ae43a6da26a07ac31fdf9dfdbbe62e255c5e2707a048e413e403c0ea6b4297079e3af17aa752 +f8668064830100009433155a1a87987386a0489f8b45c86f4aec3cbdbb840989680080820a96a0bc1e3ee9a52b5089344b15eb1032f73c1b519e761fd8505172790a90dca06b91a01e87a08138343ee93f272f0baa4fc758ac876112c559ae07d069f531535bcae7 +f8668064830100009440ed6f3aedbd905904dab1f3f008ae0ce9d07c988408f0d18080820a95a0f52e0f0df0ff9838b21effe5f373a24d33d65ed981fea34c958f72e169174452a0368438d31d061bd17de02597f6fab9fd3665cb6e9f1c67cbb911f6937943a605 +f86680648301000094ffad501c7a4789e14c333102a0588b9b13f6bfcc8408583b0080820a95a0796d4f82cc9af35f560187818692dec1a384cb270e6415a9d62b8d10cc2305a3a061df9e64559eec69b24a4fb37b127a547c6952772807a65796a6d52f8a8f1902 +f866806483010000944f05a2e33d0b55278323f6fcc7c4a430df6152fb8407bfa48080820a96a096150e62596108ef9f119fe43ca71e0212d5362f40940b241c20073329637e15a0042a4c5c7e234f77cffc3fd4d43dec421a432f9adf7ff2ab6de630d24caa30e8 +f86580648301000094aa2754913044c8a7af9de010630320277ab51ae28407270e0080820a96a0b8316fcfd701b4a197dc48564b2b07eb325f81062e0aeda8fecc2817e69c7e559fb3874cd0d6655b24eeda1fe868b4620f51c042e1ce82352695ba7aaaf309ce +f866806483010000945847dd76ca32d2422fb15da111a8eea920ecdf2984068e778080820a96a00f5688c3e530ddaf62a13b135ce103fe0833b34efc3d3858e33a4530b8ec9b0da0450bd1b416649847501cb722160ffeb5383ea74415c79742bf738b6e89a0d2a5 +f86680648301000094e4ec847f9e92b140ae2a19591d593b1ce74894308405f5e10080820a96a0c534e623010777a7ccd5bc7a0219d763596c4d34139d252e230ec9e850761b6ca005e07fd104e944065b21d3b49e2de1eb1188d56361872db119bc901112769ffd +f86680648301000094448c5a71c134526d85db604301233900f707f00384055d4a8080820a95a05a654e538daf7384976360b080ae516a948cc840f69fc3245686239461b795a0a0120b4d977f0508e88fed31bc766311215d2b85fb01fb1c39988263e241056cb4 +f86680648301000094bb91fcb757ac686c1051cae9c4da6910141246748404c4b40080820a96a00a1ac0533b29cf539c7e8fe1f539bffa361689060bfa6611a599361f6aa05538a07d97ea69454877e551308ae4e74621cb3b6d89d6c88983db14cd4576a87681de +f86680648301000094c523c280ab8a4bea00b0113af231540e87ca15f984042c1d8080820a95a003cb50840dfc2fd337ea0abcce958ba61eac874bbcae8f121c1fd7e27413a721a00be4c6e35bf4c43d360ddd88ba594178fcd51411cbecac77e3d810cd6e0110c0 +f86680648301000094d2abe8029e1e1fa82a5093afe19e263d700885d4840393870080820a96a0b109ec1e56efe001a55b2d0c873ce8f79c647129df4407355780a04fc691f670a025ec93d6003c5de2d4a9b96fa298ae9aeb85306314ade8b70a173f5570966fd9 +f866806483010000941c62f01f173fb84071ab5bc94b47f8324a10d4cf8402faf08080820a96a0e5dcf679ea5aab0eb0a196a4f37e4a69617fc0e9466334f9efe7b6a1a6f5a34fa06157bab743a9ab3f195d2ded87257df4147ba4ddaab5a6639416c46317d9337f +f8668064830100009440898a47b859d6843ff73130eb898b39d572ebfd8402625a0080820a96a02f9e3288f5746f6aeb23429d48335a885b55e0b919377881a2cd4a0bb1157c47a02833bd84dc3f5c3412f032c918253c23fab5c04be71e67de8d5d8e754f468e24 +f86680648301000094c8ecab1ca2aeba2895c8a7b401a875b221d002b18401c9c38080820a95a0fd61f2b26525505b9a7ff5181836d07025f708810bb5f42c6cf2c0c6723f1809a0406de647d893a8e1061349303d49ee33652eeec23b7f340e4a3bad81f1a09eae +f8668064830100009467c8d484706523074d33c31417baa73fb6974f748401312d0080820a95a03f9293d7ad764d06a63660073c0278063b3c8d5bc5a26afd058be4bc1a3d7c4ea064dec58cb8bd26cea3eb9bf90c320aa7d5adae58392b5207a441c73e6d35cb41 +f86580648301000094ea1315e6be892cbfb016b93bcf95b0cd458520018398968080820a95a00251a0c5b7564a9637cf8f3286d1ac4cfd5d2243a52d743c658523dc6e9f59dba0743c4c7d3b984621077991054d055b622dd5a18f796e9567e9b59351a946372d diff --git a/tezt/tests/evm_kernel_inputs/README.md b/tezt/tests/evm_kernel_inputs/README.md index cc2052b505afde692f7a399bb8d8097783e32957..5e79da4a086d75793bca160b94f54c147db7a8ea 100644 --- a/tezt/tests/evm_kernel_inputs/README.md +++ b/tezt/tests/evm_kernel_inputs/README.md @@ -32,11 +32,13 @@ npm install @ethereumjs/common @ethereumjs/tx ./signer.js > 100-inputs-for-proxy ``` -# 100-loops +# 100-loops and 100-loops-transfers The file `100-loops` has been produced by a scenario in `kernel_evm/benchmarks` ``` -node src/kernel_evm/benchmark/scripts/benchmarks/bench_loop_expensive.js raw +node src/kernel_evm/benchmarks/scripts/benchmarks/bench_loop_expensive.js for-test ``` +This produces both transfers and calls. The transfers goes in a file `100-loops-transfers`. +The calls go in `100-loops`. # Smart contracts inputs diff --git a/tezt/tests/evm_rollup.ml b/tezt/tests/evm_rollup.ml index 119fd0d9f347a9f8d1fa085e888237f98a3810cf..9cdcbfc12ae5aa6cd08ac3c4452c091e22b02caa 100644 --- a/tezt/tests/evm_rollup.ml +++ b/tezt/tests/evm_rollup.ml @@ -1152,7 +1152,17 @@ let transfer ?data protocol = ~receiver full_evm_setup in - Check.(Wei.(sender_balance_after = sender_balance_before - value) Wei.typ) + let* receipt = + Eth_cli.get_receipt ~endpoint:full_evm_setup.endpoint ~tx:tx_object.hash + in + let fees = + match receipt with + | Some Transaction.{status = true; gasUsed; effectiveGasPrice; _} -> + Int32.(to_string (mul gasUsed effectiveGasPrice)) |> Wei.of_string + | _ -> Test.fail "Transaction didn't succeed" + in + Check.( + Wei.(sender_balance_after = sender_balance_before - value - fees) Wei.typ) ~error_msg: "Unexpected sender balance after transfer, should be %R, but got %L" ; Check.(Wei.(receiver_balance_after = receiver_balance_before + value) Wei.typ) @@ -2622,10 +2632,22 @@ let test_reboot = setup_past_genesis ~admin:None protocol in (* Retrieves all the messages and prepare them for the current rollup. *) + let transfers = + read_file (kernel_inputs_path ^ "/100-loops-transfers") + |> String.trim |> String.split_on_char '\n' + in let txs = read_file (kernel_inputs_path ^ "/100-loops") |> String.trim |> String.split_on_char '\n' in + let* _, _transfer_receipt, _ = + send_n_transactions + ~sc_rollup_node + ~node + ~client + ~evm_proxy_server + transfers + in let* requests, receipt, _hashes = send_n_transactions ~sc_rollup_node ~node ~client ~evm_proxy_server txs in