From c059de756fd72c6185759eb07a3ddc4337c1b2c2 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Mon, 9 Apr 2018 18:12:38 +0800 Subject: [PATCH] Add additional test case for 1972 --- .../testing/include/eosio/testing/tester.hpp | 9 ++-- libraries/testing/tester.cpp | 4 +- tests/chain_tests/block_tests.cpp | 45 +++++++++++++++++++ 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/libraries/testing/include/eosio/testing/tester.hpp b/libraries/testing/include/eosio/testing/tester.hpp index c80b0a306..7e140d688 100644 --- a/libraries/testing/include/eosio/testing/tester.hpp +++ b/libraries/testing/include/eosio/testing/tester.hpp @@ -89,8 +89,11 @@ namespace eosio { namespace testing { uint32_t expiration = DEFAULT_EXPIRATION_DELTA, uint32_t delay_sec = 0)const; - void create_accounts( vector names, bool multisig = false ) { - for( auto n : names ) create_account(n, config::system_account_name, multisig ); + vector create_accounts( vector names, bool multisig = false ) { + vector traces; + traces.reserve(names.size()); + for( auto n : names ) traces.emplace_back(create_account(n, config::system_account_name, multisig )); + return traces; } void push_genesis_block(); @@ -105,7 +108,7 @@ namespace eosio { namespace testing { void delete_authority( account_name account, permission_name perm, const vector& auths, const vector& keys ); void delete_authority( account_name account, permission_name perm ); - void create_account( account_name name, account_name creator = config::system_account_name, bool multisig = false ); + transaction_trace create_account( account_name name, account_name creator = config::system_account_name, bool multisig = false ); transaction_trace push_reqauth( account_name from, const vector& auths, const vector& keys ); transaction_trace push_reqauth(account_name from, string role, bool multi_sig = false); diff --git a/libraries/testing/tester.cpp b/libraries/testing/tester.cpp index cad5adea6..66352633e 100644 --- a/libraries/testing/tester.cpp +++ b/libraries/testing/tester.cpp @@ -131,7 +131,7 @@ namespace eosio { namespace testing { } - void base_tester::create_account( account_name a, account_name creator, bool multisig ) { + transaction_trace base_tester::create_account( account_name a, account_name creator, bool multisig ) { signed_transaction trx; set_transaction_headers(trx); @@ -154,7 +154,7 @@ namespace eosio { namespace testing { set_transaction_headers(trx); trx.sign( get_private_key( creator, "active" ), chain_id_type() ); - push_transaction( trx ); + return push_transaction( trx ); } transaction_trace base_tester::push_transaction( packed_transaction& trx, uint32_t skip_flag ) { try { diff --git a/tests/chain_tests/block_tests.cpp b/tests/chain_tests/block_tests.cpp index 8aafeaa57..fc9497987 100644 --- a/tests/chain_tests/block_tests.cpp +++ b/tests/chain_tests/block_tests.cpp @@ -956,4 +956,49 @@ BOOST_AUTO_TEST_CASE(get_required_keys) } FC_LOG_AND_RETHROW() } + +// Test transaction_mroot matches with the specification in Github #1972 https://github.com/EOSIO/eos/issues/1972 +// Which is a root of a Merkle tree over commitments for each region processed in the block ordered in ascending region id order. +// Commitment for each region is a merkle tree over commitments for each shard inside the cycle of that region. +// Commitment for the shard itself is a merkle tree over the transactions commitments inside that shard. +// The transaction commitment is digest of the concentanation of region_id, cycle_index, shard_index, tx_index, +// transaction_receipt and packed_trx_digest (if the tx is an input tx, which doesn't include implicit/ deferred tx) +BOOST_AUTO_TEST_CASE(transaction_mroot) +{ try { + validating_tester chain; + // Finalize current block (which has set contract transaction for eosio) + chain.produce_block(); + + // any transaction will do + vector traces = chain.create_accounts({"test1", "test2", "test3"}); + + // Calculate expected tx roots + vector tx_roots; + for( uint64_t tx_index = 0; tx_index < traces.size(); tx_index++ ) { + const auto& tx = traces[tx_index]; + digest_type::encoder enc; + // region_id, cycle_index, shard_index, tx_index, transaction_receipt and packed_trx_digest (if the tx is an input tx) + fc::raw::pack( enc, tx.region_id ); + fc::raw::pack( enc, tx.cycle_index ); + fc::raw::pack( enc, tx.shard_index ); + fc::raw::pack( enc, tx_index ); + fc::raw::pack( enc, *static_cast(&tx) ); + if( tx.packed_trx_digest.valid() ) fc::raw::pack( enc, *tx.packed_trx_digest ); + tx_roots.emplace_back(enc.result()); + } + auto expected_shard_tx_root = merkle(tx_roots); + + // Hardcoded on_block tx_root, since there's no easy way to calculate the tx_root with current interface + auto on_block_tx_root = digest_type("aa63d366cc2ef41746bb150258d1c0662c8133469f785425cb996dbe2a227086"); + // There is only 1 region, 2 cycle, 1 shard in first cycle, 1 shard in second cycle + auto expected_tx_mroot = merkle({on_block_tx_root, expected_shard_tx_root}); + + // Compare with head block tx mroot + chain.produce_block(); + auto head_block_tx_mroot = chain.control->head_block_header().transaction_mroot; + BOOST_TEST(expected_tx_mroot.str() == head_block_tx_mroot.str()); + +} FC_LOG_AND_RETHROW() } + + BOOST_AUTO_TEST_SUITE_END() -- GitLab