diff --git a/src/bin_evm_proxy/lib_dev/ethereum_types.ml b/src/bin_evm_proxy/lib_dev/ethereum_types.ml index c35ccdf029abcb9f26ea0f3df7188992e22a7b51..856c3dd3c0030d941454f47c3e9510e2b27df114 100644 --- a/src/bin_evm_proxy/lib_dev/ethereum_types.ml +++ b/src/bin_evm_proxy/lib_dev/ethereum_types.ml @@ -572,12 +572,14 @@ let block_from_rlp bytes = Value hash; Value parent_hash; List transactions; + Value gas_used; Value timestamp; ]) -> let (Qty number) = decode_number number in let hash = decode_block_hash hash in let parent_hash = decode_block_hash parent_hash in let transactions = TxHash (decode_list decode_hash transactions) in + let gas_used = decode_number gas_used in let timestamp = decode_number timestamp in { number = Some (Block_height number); @@ -597,12 +599,12 @@ let block_from_rlp bytes = extraData = ""; size = Qty Z.zero; gasLimit = Qty Z.zero; - gasUsed = Qty Z.zero; + gasUsed = gas_used; timestamp; transactions; uncles = []; } - | _ -> raise (Invalid_argument "Expected a List of 5 elements") + | _ -> raise (Invalid_argument "Expected a List of 6 elements") let block_encoding = let open Data_encoding in diff --git a/src/kernel_evm/benchmarks/scripts/benchmarks/bench_loop_expensive.js b/src/kernel_evm/benchmarks/scripts/benchmarks/bench_loop_expensive.js new file mode 100644 index 0000000000000000000000000000000000000000..efd74178471e02e70fdc91ba30051e62b6b62fdc --- /dev/null +++ b/src/kernel_evm/benchmarks/scripts/benchmarks/bench_loop_expensive.js @@ -0,0 +1,54 @@ +// SPDX-FileCopyrightText: 2023 Marigold +// +// SPDX-License-Identifier: MIT + +// usage: node benchmarks/test_reboot_loop.js +// or to produce raw list of transactions: node benchmarks/test_reboot_loop.js raw + +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; + +// create call data with different values +let call_data_prefix = "0x0b7d796e00000000000000000000000000000000" +let call_data = function (n) { + return call_data_prefix + utils.encode_number(n) +} + +let txs = []; + +// initialisation +txs.push(utils.transfer(faucet, player1, 100000000)) +let create = utils.create(player1, 0, create_data) +txs.push(create.tx) + +let players = [] +// one player per transaction +// this make the scenario work with the proxy, which now (temporarily) forces +// 1 tx max per account +for (let i = 0; i < TOO_MANY_TXS; i++) { + players.push(addr.create_player()) +} + +for (let i = 0; i < TOO_MANY_TXS; i++) { + txs.push(utils.send(players[i], create.addr, 0, call_data(NB_LOOP))) +} + +var args = process.argv.slice(2) + +if (args.length == 1 && args[0] == "raw") { + utils.print_raw_txs(txs) +} else { + utils.print_bench([txs]) +} diff --git a/src/kernel_evm/benchmarks/scripts/benchmarks/bench_loop.js b/src/kernel_evm/benchmarks/scripts/benchmarks/bench_loop_progressive.js similarity index 100% rename from src/kernel_evm/benchmarks/scripts/benchmarks/bench_loop.js rename to src/kernel_evm/benchmarks/scripts/benchmarks/bench_loop_progressive.js diff --git a/src/kernel_evm/benchmarks/scripts/benchmarks/players/tezt_bootstraped.json b/src/kernel_evm/benchmarks/scripts/benchmarks/players/tezt_bootstraped.json new file mode 100644 index 0000000000000000000000000000000000000000..d70eaa6b3c4db98128509219a0916aa428ae6651 --- /dev/null +++ b/src/kernel_evm/benchmarks/scripts/benchmarks/players/tezt_bootstraped.json @@ -0,0 +1,6 @@ +{ + "addr": "0x6ce4d79d4E77402e1ef3417Fdda433aA744C6e1c", + "privateKey": "0x9722f6cc9ff938e63f8ccb74c3daa6b45837e5c5e3835ac08c44c50ab5f39dc0", + "publicKey": "0x046edc43401193c9321730cdf73e454f68e8aa52e377d001499b0eaa431fa4763102e685fe33851f5f51bd31adb41582bbfb0ad85c1089c0a0b4adc049a271bc01", + "nonce": 0 +} \ No newline at end of file diff --git a/src/kernel_evm/benchmarks/scripts/benchmarks/utils.js b/src/kernel_evm/benchmarks/scripts/benchmarks/utils.js index 813638ba32925775cb7e5565e1d0ba1319950d08..ba350dbbd300dcf74eb9f8c9ec902409e519e8cc 100644 --- a/src/kernel_evm/benchmarks/scripts/benchmarks/utils.js +++ b/src/kernel_evm/benchmarks/scripts/benchmarks/utils.js @@ -93,7 +93,13 @@ exports.print_bench = function (src) { print_list(inputs.shift()) console.log("]") } +exports.print_raw_txs = function (src) { + const txs = src.slice(); + txs.forEach(element => { + console.log(element) + }); +} exports.encode_number = function (n) { let s = "00000000000000000000000000000000" diff --git a/src/kernel_evm/benchmarks/scripts/lib/address.js b/src/kernel_evm/benchmarks/scripts/lib/address.js index f7cac09b6ddbb56de96df409bce1d305316c9ba7..6102e3abe35386fe973fbe817d5a62ca34db05a9 100644 --- a/src/kernel_evm/benchmarks/scripts/lib/address.js +++ b/src/kernel_evm/benchmarks/scripts/lib/address.js @@ -8,12 +8,11 @@ var Wallet = require('ethereumjs-wallet'); -const create_wallet = function () { - if (process.argv.length <= 2) { +const create_wallet = function (privateKey) { + if (arguments.length == 0) { return Wallet.default.generate(); } else { - let privateKey = process.argv[2] // remove 0x if present if (privateKey.indexOf('0x') === 0) privateKey = privateKey.substr(2) var array = new Uint8Array(privateKey.match(/../g).map(h => parseInt(h, 16))) @@ -38,7 +37,7 @@ const create_player = function (wallet) { addr: wallet.getAddressString(), privateKey: wallet.getPrivateKeyString(), publicKey: wallet.getPublicKeyString(), - nonce: 1 + nonce: 0 } } diff --git a/src/kernel_evm/benchmarks/scripts/make_addr.js b/src/kernel_evm/benchmarks/scripts/make_addr.js index 41c83c97987c2dc8265fcebec38771801a7cc965..7c710d1e90c5e13ca704186f17d20aa90853c895 100644 --- a/src/kernel_evm/benchmarks/scripts/make_addr.js +++ b/src/kernel_evm/benchmarks/scripts/make_addr.js @@ -11,6 +11,12 @@ // dependency: npm install ethereumjs-wallet --save const addr = require('./lib/address') -let wallet = addr.create_wallet(); -addr.print_wallet(wallet) +var wallet; +if (process.argv.length == 3) { + wallet = addr.create_wallet(process.argv[2]); +} else { + wallet = addr.create_wallet(); +} + +addr.print_wallet(wallet) diff --git a/src/kernel_evm/benchmarks/scripts/run_benchmarks.js b/src/kernel_evm/benchmarks/scripts/run_benchmarks.js index a3a55ebd98226e520f3c8f86459020a9e6c7a0f4..f791dff9ac44e359458a3bfd0b10715b66ea63c9 100644 --- a/src/kernel_evm/benchmarks/scripts/run_benchmarks.js +++ b/src/kernel_evm/benchmarks/scripts/run_benchmarks.js @@ -213,7 +213,8 @@ benchmark_scripts = [ "benchmarks/bench_keccak.js", "benchmarks/bench_verifySignature.js", "benchmarks/bench_erc20tok.js", - "benchmarks/bench_loop.js", + "benchmarks/bench_loop_progressive.js", + "benchmarks/bench_loop_expensive.js", ] run_all_benchmarks(benchmark_scripts); diff --git a/src/kernel_evm/ethereum/src/block.rs b/src/kernel_evm/ethereum/src/block.rs index e9e61d7e8702874af35d85d571ccf027d8b1fe2a..0c2bc94937537383cfcf51b915aedfbc6ee8e49d 100644 --- a/src/kernel_evm/ethereum/src/block.rs +++ b/src/kernel_evm/ethereum/src/block.rs @@ -151,13 +151,14 @@ impl Default for L2Block { impl Encodable for L2Block { fn rlp_append(&self, s: &mut RlpStream) { - s.begin_list(5); + s.begin_list(6); s.append(&self.number); s.append(&self.hash); s.append(&self.parent_hash); let transactions_bytes: Vec> = self.transactions.iter().map(|x| x.to_vec()).collect(); s.append_list::, _>(&transactions_bytes); + s.append(&self.gas_used); s.append(&self.timestamp.i64().to_le_bytes().to_vec()); } } @@ -165,7 +166,7 @@ impl Encodable for L2Block { impl Decodable for L2Block { fn decode(decoder: &Rlp) -> Result { if decoder.is_list() { - if Ok(5) == decoder.item_count() { + if Ok(6) == decoder.item_count() { let mut it = decoder.iter(); let number: U256 = decode_field_u256_le(&next(&mut it)?, "number")?; let hash: H256 = decode_field_h256(&next(&mut it)?, "hash")?; @@ -173,6 +174,7 @@ impl Decodable for L2Block { decode_field_h256(&next(&mut it)?, "parent_hash")?; let transactions: Vec = decode_transaction_hash_list(&next(&mut it)?, "transactions")?; + let gas_used: U256 = decode_field_u256_le(&next(&mut it)?, "gas_used")?; let timestamp_bytes = decode_field::>(&next(&mut it)?, "timestamp")?; let timestamp: Timestamp = @@ -186,6 +188,7 @@ impl Decodable for L2Block { number, hash, parent_hash, + gas_used, timestamp, transactions, ..Default::default() diff --git a/src/kernel_evm/kernel/src/block.rs b/src/kernel_evm/kernel/src/block.rs index f9162c9625d381aae7f4035dc2df2a0585e32c91..024cc53292f750683afee3aac2a9e769c88faaed 100644 --- a/src/kernel_evm/kernel/src/block.rs +++ b/src/kernel_evm/kernel/src/block.rs @@ -49,6 +49,12 @@ fn compute( evm_account_storage: &mut EthereumAccountStorage, accounts_index: &mut IndexableStorage, ) -> Result { + log!( + host, + Debug, + "Queue length {}.", + block_in_progress.queue_length() + ); // iteration over all remaining transaction in the block while block_in_progress.has_tx() { // is reboot necessary ? @@ -122,7 +128,12 @@ pub fn produce( &mut accounts_index, )? { ComputationResult::RebootNeeded => { - log!(host, Info, "Ask for reboot"); + log!( + host, + Info, + "Ask for reboot, ticks consumed: {}", + &block_in_progress.estimated_ticks + ); storage::store_block_in_progress(host, &block_in_progress)?; storage::add_reboot_flag(host)?; host.mark_for_reboot()?; diff --git a/src/kernel_evm/kernel/src/lib.rs b/src/kernel_evm/kernel/src/lib.rs index 6bd9793e3a4e5ce98d62f45a813615a033783ed4..3a31481ae7e8b307ae2940b0faf34b9b856b340f 100644 --- a/src/kernel_evm/kernel/src/lib.rs +++ b/src/kernel_evm/kernel/src/lib.rs @@ -224,6 +224,7 @@ pub fn main(host: &mut Host) -> Result<(), anyhow::Error> { host.reboot_left()? ); storage::delete_reboot_flag(host)?; + log!(host, Info, "Read queue."); fetch_queue_left(host)? } else { // first kernel run of the level diff --git a/src/kernel_evm/kernel/src/storage.rs b/src/kernel_evm/kernel/src/storage.rs index 525c81101904a4c26c8af80130e3ed73e4675df5..89439e91dd9e61a21fee87cdc798a03437837299 100644 --- a/src/kernel_evm/kernel/src/storage.rs +++ b/src/kernel_evm/kernel/src/storage.rs @@ -271,9 +271,10 @@ pub fn store_current_block( log!( host, Debug, - "Storing block {} containing {} transaction(s).", + "Storing block {} containing {} transaction(s) for {} gas used.", block.number, - block.transactions.len() + block.transactions.len(), + U256::to_string(&block.gas_used) ); Ok(()) } diff --git a/tezt/tests/evm_kernel_inputs/100-loops b/tezt/tests/evm_kernel_inputs/100-loops new file mode 100644 index 0000000000000000000000000000000000000000..3e01da297564f6c0b5f4bd8ec1fae5a8c8f068dd --- /dev/null +++ b/tezt/tests/evm_kernel_inputs/100-loops @@ -0,0 +1,103 @@ +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 diff --git a/tezt/tests/evm_kernel_inputs/README.md b/tezt/tests/evm_kernel_inputs/README.md index 0caf3f6069ff548e0654b5db5dae585efcece1c1..cc2052b505afde692f7a399bb8d8097783e32957 100644 --- a/tezt/tests/evm_kernel_inputs/README.md +++ b/tezt/tests/evm_kernel_inputs/README.md @@ -25,13 +25,20 @@ External message: # Inputs for the Proxy +## 100-inputs-for-proxy The file `100-inputs-for-proxy` is a list of signed transactions generated with `signer.js`. It can be regenerated with the following command: ``` npm install @ethereumjs/common @ethereumjs/tx ./signer.js > 100-inputs-for-proxy ``` -#Smart contracts inputs +# 100-loops +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 +``` + +# Smart contracts inputs To deploy a solidity contract on the rollup two files are necessary: - the ABI (interface), in a JSON format, diff --git a/tezt/tests/evm_rollup.ml b/tezt/tests/evm_rollup.ml index af08a32bdb145aaba0085f083ccea0e5de931273..42a2a13d0f543425ee9f4aa6053f4926830d64f8 100644 --- a/tezt/tests/evm_rollup.ml +++ b/tezt/tests/evm_rollup.ml @@ -186,6 +186,7 @@ let send_and_wait_until_tx_mined ~sc_rollup_node ~node ~client in wait_for_application ~sc_rollup_node ~node ~client send () +(* sending more than ~300 tx could fail, because or curl *) let send_n_transactions ~sc_rollup_node ~node ~client ~evm_proxy_server txs = let requests = List.map @@ -2501,6 +2502,58 @@ let register_evm_migration ~protocols = test_deposit_before_and_after_migration protocols ; test_block_storage_before_and_after_migration protocols +let test_reboot = + Protocol.register_test + ~__FILE__ + ~tags:["evm"; "reboot"; "loop"] + ~title:"Check that the kernel can handle too many txs for a single run" + @@ fun protocol -> + let* {evm_proxy_server; sc_rollup_node; node; client; sc_rollup_client; _} = + setup_past_genesis ~admin:None protocol + in + (* Retrieves all the messages and prepare them for the current rollup. *) + let txs = + read_file (kernel_inputs_path ^ "/100-loops") + |> String.trim |> String.split_on_char '\n' + in + let* requests, receipt = + send_n_transactions ~sc_rollup_node ~node ~client ~evm_proxy_server txs + in + let* block_with_many_txs = + Evm_proxy_server.( + call_evm_rpc + evm_proxy_server + { + method_ = "eth_getBlockByNumber"; + parameters = + `A + [`String (Format.sprintf "%#lx" receipt.blockNumber); `Bool false]; + }) + in + let block_with_many_txs = + block_with_many_txs |> Evm_proxy_server.extract_result |> Block.of_json + in + (match block_with_many_txs.Block.transactions with + | Block.Empty -> Test.fail "Expected a non empty block" + | Block.Full _ -> + Test.fail "Block is supposed to contain only transaction hashes" + | Block.Hash hashes -> + Check.((List.length hashes = List.length requests) int) + ~error_msg:"Expected %R transactions in the latest block, got %L") ; + let*! tick_number = Sc_rollup_client.ticks sc_rollup_client in + let max_tick = + Tezos_protocol_alpha.Protocol.Sc_rollup_wasm.V2_0_0.ticks_per_snapshot + in + Check.((tick_number > Z.to_int max_tick) int) + ~error_msg: + "Expected %L to be greater than %R, max nb of ticks per kernel run" ; + (* a single run can't do more than 11_000_000_000 / 2000 gas units *) + (* TODO: #6278 + RPC to fetch tick model / tick per gas *) + Check.((block_with_many_txs.gasUsed > 5500000l) int32) + ~error_msg:"Expected gas used %L to be superior to %R" ; + unit + let register_evm_proxy_server ~protocols = test_originate_evm_kernel protocols ; test_evm_proxy_server_connection protocols ; @@ -2542,7 +2595,8 @@ let register_evm_proxy_server ~protocols = test_deposit_dailynet protocols ; test_rpc_sendRawTransaction_nonce_too_low protocols ; test_rpc_sendRawTransaction_nonce_too_high protocols ; - test_rpc_sendRawTransaction_invalid_chain_id protocols + test_rpc_sendRawTransaction_invalid_chain_id protocols ; + test_reboot protocols let register ~protocols = register_evm_proxy_server ~protocols ;