From 0b937e103aabc62d044efd27862996948a8aadd8 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Wed, 25 Mar 2020 14:21:59 -0500 Subject: [PATCH 1/3] add pruned_block to signed_block conversion --- libraries/chain/block.cpp | 19 +++++++++++++++++++ libraries/chain/include/eosio/chain/block.hpp | 9 ++++++--- unittests/misc_tests.cpp | 6 ++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/libraries/chain/block.cpp b/libraries/chain/block.cpp index 5508b92000a..e635a6d6887 100644 --- a/libraries/chain/block.cpp +++ b/libraries/chain/block.cpp @@ -1,4 +1,5 @@ #include +#include namespace eosio { namespace chain { void additional_block_signatures_extension::reflector_init() { @@ -111,4 +112,22 @@ namespace eosio { namespace chain { return validate_and_extract_block_extensions( block_extensions ); } + signed_block_ptr pruned_block::to_signed_block() const { + if (prune_state != prune_state_type::complete_legacy) + return signed_block_ptr{}; + + auto result = std::make_shared(*this); + result->block_extensions = this->block_extensions; + + auto visitor = overloaded{ + [](const transaction_id_type &id) -> transaction_receipt::trx_type { return id; }, + [](const pruned_transaction &trx) -> transaction_receipt::trx_type { + return packed_transaction{trx.get_signed_transaction(), trx.get_compression()}; + }}; + + for (const pruned_transaction_receipt &r : transactions){ + result->transactions.emplace_back(transaction_receipt{r, r.trx.visit(visitor)}); + } + return result; + } } } /// namespace eosio::chain diff --git a/libraries/chain/include/eosio/chain/block.hpp b/libraries/chain/include/eosio/chain/block.hpp index ff8fb821c4c..fe887184eca 100644 --- a/libraries/chain/include/eosio/chain/block.hpp +++ b/libraries/chain/include/eosio/chain/block.hpp @@ -31,12 +31,13 @@ namespace eosio { namespace chain { }; struct transaction_receipt : public transaction_receipt_header { - - transaction_receipt():transaction_receipt_header(){} + using trx_type = fc::static_variant; + transaction_receipt() : transaction_receipt_header() {} + transaction_receipt(const transaction_receipt_header& header, trx_type&& t): transaction_receipt_header(header), trx(t){} explicit transaction_receipt( const transaction_id_type& tid ):transaction_receipt_header(executed),trx(tid){} explicit transaction_receipt( const packed_transaction& ptrx ):transaction_receipt_header(executed),trx(ptrx){} - fc::static_variant trx; + trx_type trx; digest_type digest()const { digest_type::encoder enc; @@ -161,6 +162,8 @@ namespace eosio { namespace chain { } flat_multimap validate_and_extract_extensions()const; + + signed_block_ptr to_signed_block() const; }; using pruned_block_ptr = std::shared_ptr; diff --git a/unittests/misc_tests.cpp b/unittests/misc_tests.cpp index 270dfab9e1b..90460ead316 100644 --- a/unittests/misc_tests.cpp +++ b/unittests/misc_tests.cpp @@ -1018,6 +1018,10 @@ BOOST_AUTO_TEST_CASE(pruned_block_test) { BOOST_TEST(basic.transaction_mroot.str() == original->transaction_mroot.str()); BOOST_TEST(basic.transaction_mroot.str() == calculate_trx_merkle(basic.transactions).str()); + signed_block_ptr recovered = basic.to_signed_block(); + BOOST_REQUIRE(recovered); + BOOST_TEST(fc::raw::pack(*original) == fc::raw::pack(*recovered)); + fc::datastream size_stream; std::size_t padded_size = basic.pack(size_stream, pruned_transaction::cf_compression_type::none); BOOST_TEST(size_stream.tellp() <= padded_size); @@ -1037,6 +1041,8 @@ BOOST_AUTO_TEST_CASE(pruned_block_test) { fc::datastream out(buffer.data(), buffer.size()); deserialized.pack(out, pruned_transaction::cf_compression_type::none); BOOST_TEST(out.tellp() <= buffer.size()); + + BOOST_TEST(!deserialized.to_signed_block()); } BOOST_AUTO_TEST_CASE(reflector_init_test) { From bbcf4b65c532839c459b0125fd68bcdca58376ef Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Wed, 25 Mar 2020 17:49:39 -0500 Subject: [PATCH 2/3] fixed on review comments --- libraries/chain/block.cpp | 13 ++++++++----- libraries/chain/include/eosio/chain/block.hpp | 5 ++--- libraries/chain/include/eosio/chain/exceptions.hpp | 2 ++ libraries/chain/include/eosio/chain/transaction.hpp | 3 +++ libraries/chain/transaction.cpp | 12 ++++++++++++ 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/libraries/chain/block.cpp b/libraries/chain/block.cpp index e635a6d6887..89d06dd1ce7 100644 --- a/libraries/chain/block.cpp +++ b/libraries/chain/block.cpp @@ -116,14 +116,17 @@ namespace eosio { namespace chain { if (prune_state != prune_state_type::complete_legacy) return signed_block_ptr{}; - auto result = std::make_shared(*this); + auto result = std::make_shared(*static_cast(this)); result->block_extensions = this->block_extensions; auto visitor = overloaded{ - [](const transaction_id_type &id) -> transaction_receipt::trx_type { return id; }, - [](const pruned_transaction &trx) -> transaction_receipt::trx_type { - return packed_transaction{trx.get_signed_transaction(), trx.get_compression()}; - }}; + [](const transaction_id_type &id) -> transaction_receipt::trx_type { return id; }, + [](const pruned_transaction &trx) -> transaction_receipt::trx_type { + auto& prunable_data = trx.get_prunable_data().prunable_data; + EOS_ASSERT(prunable_data.contains(), tx_not_full_legacy, "pruned_transaction does not contain the full legacy data"); + auto& legacy = prunable_data.get(); + return packed_transaction(trx.get_packed_transaction(), legacy.signatures, legacy.packed_context_free_data, trx.get_compression()); + }}; for (const pruned_transaction_receipt &r : transactions){ result->transactions.emplace_back(transaction_receipt{r, r.trx.visit(visitor)}); diff --git a/libraries/chain/include/eosio/chain/block.hpp b/libraries/chain/include/eosio/chain/block.hpp index fe887184eca..df9e2c2408c 100644 --- a/libraries/chain/include/eosio/chain/block.hpp +++ b/libraries/chain/include/eosio/chain/block.hpp @@ -33,7 +33,7 @@ namespace eosio { namespace chain { struct transaction_receipt : public transaction_receipt_header { using trx_type = fc::static_variant; transaction_receipt() : transaction_receipt_header() {} - transaction_receipt(const transaction_receipt_header& header, trx_type&& t): transaction_receipt_header(header), trx(t){} + transaction_receipt(const transaction_receipt_header& header, trx_type&& t): transaction_receipt_header(header), trx(std::move(t)){} explicit transaction_receipt( const transaction_id_type& tid ):transaction_receipt_header(executed),trx(tid){} explicit transaction_receipt( const packed_transaction& ptrx ):transaction_receipt_header(executed),trx(ptrx){} @@ -140,6 +140,7 @@ namespace eosio { namespace chain { pruned_block( pruned_block&& ) = default; pruned_block& operator=(const pruned_block&) = delete; pruned_block clone() const { return *this; } + signed_block_ptr to_signed_block() const; fc::enum_type prune_state{prune_state_type::complete_legacy}; deque transactions; /// new or generated transactions @@ -162,8 +163,6 @@ namespace eosio { namespace chain { } flat_multimap validate_and_extract_extensions()const; - - signed_block_ptr to_signed_block() const; }; using pruned_block_ptr = std::shared_ptr; diff --git a/libraries/chain/include/eosio/chain/exceptions.hpp b/libraries/chain/include/eosio/chain/exceptions.hpp index b534844ea53..21aad3e18b3 100644 --- a/libraries/chain/include/eosio/chain/exceptions.hpp +++ b/libraries/chain/include/eosio/chain/exceptions.hpp @@ -279,6 +279,8 @@ namespace eosio { namespace chain { 3040018, "Transaction exceeded transient resource limit" ) FC_DECLARE_DERIVED_EXCEPTION( tx_prune_exception, transaction_exception, 3040019, "Prunable data not found" ) + FC_DECLARE_DERIVED_EXCEPTION( tx_not_full_legacy, transaction_exception, + 3040019, "Prunable transaction is not full legacy" ) FC_DECLARE_DERIVED_EXCEPTION( action_validate_exception, chain_exception, diff --git a/libraries/chain/include/eosio/chain/transaction.hpp b/libraries/chain/include/eosio/chain/transaction.hpp index cd1c6e0bf43..14cd9d1c544 100644 --- a/libraries/chain/include/eosio/chain/transaction.hpp +++ b/libraries/chain/include/eosio/chain/transaction.hpp @@ -159,6 +159,8 @@ namespace eosio { namespace chain { local_pack_context_free_data(); } + packed_transaction(const bytes& packed_txn, const vector& sigs, const bytes& packed_cfd, compression_type _compression); + // used by abi_serializer packed_transaction( bytes&& packed_txn, vector&& sigs, bytes&& packed_cfd, compression_type _compression ); packed_transaction( bytes&& packed_txn, vector&& sigs, vector&& cfd, compression_type _compression ); @@ -290,6 +292,7 @@ namespace eosio { namespace chain { const bytes* get_context_free_data(std::size_t segment_ordinal); const fc::enum_type& get_compression()const { return compression; } const bytes& get_packed_transaction()const { return packed_trx; } + const prunable_transaction_data& get_prunable_data() const { return prunable_data; } void prune_all(); diff --git a/libraries/chain/transaction.cpp b/libraries/chain/transaction.cpp index c42e28a4928..7320f25c204 100644 --- a/libraries/chain/transaction.cpp +++ b/libraries/chain/transaction.cpp @@ -270,6 +270,18 @@ bytes packed_transaction::get_raw_transaction() const } FC_CAPTURE_AND_RETHROW((compression)(packed_trx)) } +packed_transaction::packed_transaction(const bytes& packed_txn, const vector& sigs, const bytes& packed_cfd, compression_type _compression ) +:signatures(sigs) +,compression(_compression) +,packed_context_free_data(packed_cfd) +,packed_trx(packed_txn) +{ + local_unpack_transaction({}); + if( !packed_context_free_data.empty() ) { + local_unpack_context_free_data(); + } +} + packed_transaction::packed_transaction( bytes&& packed_txn, vector&& sigs, bytes&& packed_cfd, compression_type _compression ) :signatures(std::move(sigs)) ,compression(_compression) From 717282e60cdebb090983f7155255739eca6c2070 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Thu, 26 Mar 2020 08:14:48 -0500 Subject: [PATCH 3/3] Remove unnecessary assertion --- libraries/chain/block.cpp | 4 +--- libraries/chain/include/eosio/chain/exceptions.hpp | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/libraries/chain/block.cpp b/libraries/chain/block.cpp index 89d06dd1ce7..616c1d3975f 100644 --- a/libraries/chain/block.cpp +++ b/libraries/chain/block.cpp @@ -122,9 +122,7 @@ namespace eosio { namespace chain { auto visitor = overloaded{ [](const transaction_id_type &id) -> transaction_receipt::trx_type { return id; }, [](const pruned_transaction &trx) -> transaction_receipt::trx_type { - auto& prunable_data = trx.get_prunable_data().prunable_data; - EOS_ASSERT(prunable_data.contains(), tx_not_full_legacy, "pruned_transaction does not contain the full legacy data"); - auto& legacy = prunable_data.get(); + const auto& legacy = trx.get_prunable_data().prunable_data.get(); return packed_transaction(trx.get_packed_transaction(), legacy.signatures, legacy.packed_context_free_data, trx.get_compression()); }}; diff --git a/libraries/chain/include/eosio/chain/exceptions.hpp b/libraries/chain/include/eosio/chain/exceptions.hpp index 21aad3e18b3..b534844ea53 100644 --- a/libraries/chain/include/eosio/chain/exceptions.hpp +++ b/libraries/chain/include/eosio/chain/exceptions.hpp @@ -279,8 +279,6 @@ namespace eosio { namespace chain { 3040018, "Transaction exceeded transient resource limit" ) FC_DECLARE_DERIVED_EXCEPTION( tx_prune_exception, transaction_exception, 3040019, "Prunable data not found" ) - FC_DECLARE_DERIVED_EXCEPTION( tx_not_full_legacy, transaction_exception, - 3040019, "Prunable transaction is not full legacy" ) FC_DECLARE_DERIVED_EXCEPTION( action_validate_exception, chain_exception,