未验证 提交 e12abf3f 编写于 作者: W wanderingbort 提交者: GitHub

Merge pull request #6494 from EOSIO/packed-txn

packed_transaction enhancement
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
namespace eosio { namespace chain { namespace eosio { namespace chain {
void chain_id_type::reflector_verify()const { void chain_id_type::reflector_init()const {
EOS_ASSERT( *reinterpret_cast<const fc::sha256*>(this) != fc::sha256(), chain_id_type_exception, "chain_id_type cannot be zero" ); EOS_ASSERT( *reinterpret_cast<const fc::sha256*>(this) != fc::sha256(), chain_id_type_exception, "chain_id_type cannot be zero" );
} }
......
...@@ -1009,7 +1009,8 @@ struct controller_impl { ...@@ -1009,7 +1009,8 @@ struct controller_impl {
} }
} }
transaction_context trx_context(self, trx->trx, trx->id, start); const signed_transaction& trn = trx->packed_trx->get_signed_transaction();
transaction_context trx_context(self, trn, trx->id, start);
if ((bool)subjective_cpu_leeway && pending->_block_status == controller::block_status::incomplete) { if ((bool)subjective_cpu_leeway && pending->_block_status == controller::block_status::incomplete) {
trx_context.leeway = *subjective_cpu_leeway; trx_context.leeway = *subjective_cpu_leeway;
} }
...@@ -1022,17 +1023,17 @@ struct controller_impl { ...@@ -1022,17 +1023,17 @@ struct controller_impl {
trx_context.init_for_implicit_trx(); trx_context.init_for_implicit_trx();
trx_context.enforce_whiteblacklist = false; trx_context.enforce_whiteblacklist = false;
} else { } else {
bool skip_recording = replay_head_time && (time_point(trx->trx.expiration) <= *replay_head_time); bool skip_recording = replay_head_time && (time_point(trn.expiration) <= *replay_head_time);
trx_context.init_for_input_trx( trx->packed_trx->get_unprunable_size(), trx_context.init_for_input_trx( trx->packed_trx->get_unprunable_size(),
trx->packed_trx->get_prunable_size(), trx->packed_trx->get_prunable_size(),
skip_recording); skip_recording);
} }
trx_context.delay = fc::seconds(trx->trx.delay_sec); trx_context.delay = fc::seconds(trn.delay_sec);
if( !self.skip_auth_check() && !trx->implicit ) { if( !self.skip_auth_check() && !trx->implicit ) {
authorization.check_authorization( authorization.check_authorization(
trx->trx.actions, trn.actions,
trx->recover_keys( chain_id ), trx->recover_keys( chain_id ),
{}, {},
trx_context.delay, trx_context.delay,
......
...@@ -583,27 +583,36 @@ namespace impl { ...@@ -583,27 +583,36 @@ namespace impl {
from_variant(vo["compression"], compression); from_variant(vo["compression"], compression);
bytes packed_cfd; bytes packed_cfd;
std::vector<bytes> cfd;
bool use_packed_cfd = false;
if( vo.contains("packed_context_free_data") && vo["packed_context_free_data"].is_string() && !vo["packed_context_free_data"].as_string().empty() ) {
from_variant(vo["packed_context_free_data"], packed_cfd );
use_packed_cfd = true;
} else if( vo.contains("context_free_data") ) {
from_variant(vo["context_free_data"], cfd);
}
if( vo.contains("packed_trx") && vo["packed_trx"].is_string() && !vo["packed_trx"].as_string().empty() ) { if( vo.contains("packed_trx") && vo["packed_trx"].is_string() && !vo["packed_trx"].as_string().empty() ) {
bytes packed_trx; bytes packed_trx;
std::vector<bytes> cfd;
from_variant(vo["packed_trx"], packed_trx); from_variant(vo["packed_trx"], packed_trx);
if( vo.contains("packed_context_free_data") && vo["packed_context_free_data"].is_string() && !vo["packed_context_free_data"].as_string().empty() ) { if( use_packed_cfd ) {
from_variant(vo["packed_context_free_data"], packed_cfd ); ptrx = packed_transaction( std::move( packed_trx ), std::move( signatures ), std::move( packed_cfd ), compression );
} else if( vo.contains("context_free_data") ) { } else {
from_variant(vo["context_free_data"], cfd); ptrx = packed_transaction( std::move( packed_trx ), std::move( signatures ), std::move( cfd ), compression );
} }
ptrx = packed_transaction( std::move(packed_trx), std::move(signatures), std::move(packed_cfd), std::move(cfd), compression );
} else { } else {
EOS_ASSERT(vo.contains("transaction"), packed_transaction_type_exception, "Missing transaction"); EOS_ASSERT(vo.contains("transaction"), packed_transaction_type_exception, "Missing transaction");
signed_transaction trx; if( use_packed_cfd ) {
trx.signatures = std::move(signatures); transaction trx;
extract(vo["transaction"], trx, resolver, ctx); extract( vo["transaction"], trx, resolver, ctx );
if( vo.contains("packed_context_free_data") && vo["packed_context_free_data"].is_string() && !vo["packed_context_free_data"].as_string().empty() ) { ptrx = packed_transaction( std::move(trx), std::move(signatures), std::move(packed_cfd), compression );
from_variant(vo["packed_context_free_data"], packed_cfd ); } else {
} else if( vo.contains("context_free_data") ) { signed_transaction trx;
from_variant(vo["context_free_data"], trx.context_free_data ); extract( vo["transaction"], trx, resolver, ctx );
trx.signatures = std::move( signatures );
trx.context_free_data = std::move(cfd);
ptrx = packed_transaction( std::move( trx ), compression );
} }
ptrx = packed_transaction( std::move(trx), std::move(packed_cfd), compression );
} }
} }
}; };
...@@ -616,11 +625,11 @@ namespace impl { ...@@ -616,11 +625,11 @@ namespace impl {
* @tparam Reslover - callable with the signature (const name& code_account) -> optional<abi_def> * @tparam Reslover - callable with the signature (const name& code_account) -> optional<abi_def>
*/ */
template<typename T, typename Resolver> template<typename T, typename Resolver>
class abi_from_variant_visitor : reflector_verifier_visitor<T> class abi_from_variant_visitor : reflector_init_visitor<T>
{ {
public: public:
abi_from_variant_visitor( const variant_object& _vo, T& v, Resolver _resolver, abi_traverse_context& _ctx ) abi_from_variant_visitor( const variant_object& _vo, T& v, Resolver _resolver, abi_traverse_context& _ctx )
: reflector_verifier_visitor<T>(v) : reflector_init_visitor<T>(v)
,_vo(_vo) ,_vo(_vo)
,_resolver(_resolver) ,_resolver(_resolver)
,_ctx(_ctx) ,_ctx(_ctx)
......
...@@ -84,7 +84,7 @@ struct asset ...@@ -84,7 +84,7 @@ struct asset
friend struct fc::reflector<asset>; friend struct fc::reflector<asset>;
void reflector_verify()const { void reflector_init()const {
EOS_ASSERT( is_amount_within_range(), asset_type_exception, "magnitude of asset amount must be less than 2^62" ); EOS_ASSERT( is_amount_within_range(), asset_type_exception, "magnitude of asset amount must be less than 2^62" );
EOS_ASSERT( sym.valid(), asset_type_exception, "invalid symbol" ); EOS_ASSERT( sym.valid(), asset_type_exception, "invalid symbol" );
} }
......
...@@ -34,7 +34,7 @@ namespace chain { ...@@ -34,7 +34,7 @@ namespace chain {
return ds; return ds;
} }
void reflector_verify()const; void reflector_init()const;
private: private:
chain_id_type() = default; chain_id_type() = default;
......
...@@ -137,7 +137,7 @@ namespace eosio { ...@@ -137,7 +137,7 @@ namespace eosio {
return ds << s.to_string(); return ds << s.to_string();
} }
void reflector_verify()const { void reflector_init()const {
EOS_ASSERT( decimals() <= max_precision, symbol_type_exception, "precision ${p} should be <= 18", ("p", decimals()) ); EOS_ASSERT( decimals() <= max_precision, symbol_type_exception, "precision ${p} should be <= 18", ("p", decimals()) );
EOS_ASSERT( valid_name(name()), symbol_type_exception, "invalid symbol: ${name}", ("name",name())); EOS_ASSERT( valid_name(name()), symbol_type_exception, "invalid symbol: ${name}", ("name",name()));
} }
......
...@@ -85,8 +85,12 @@ namespace eosio { namespace chain { ...@@ -85,8 +85,12 @@ namespace eosio { namespace chain {
: transaction(std::move(trx)) : transaction(std::move(trx))
, signatures(signatures) , signatures(signatures)
, context_free_data(context_free_data) , context_free_data(context_free_data)
{ {}
} signed_transaction( transaction&& trx, const vector<signature_type>& signatures, vector<bytes>&& context_free_data)
: transaction(std::move(trx))
, signatures(signatures)
, context_free_data(std::move(context_free_data))
{}
vector<signature_type> signatures; vector<signature_type> signatures;
vector<bytes> context_free_data; ///< for each context-free action, there is an entry here vector<bytes> context_free_data; ///< for each context-free action, there is an entry here
...@@ -111,48 +115,50 @@ namespace eosio { namespace chain { ...@@ -111,48 +115,50 @@ namespace eosio { namespace chain {
packed_transaction& operator=(packed_transaction&&) = default; packed_transaction& operator=(packed_transaction&&) = default;
explicit packed_transaction(const signed_transaction& t, compression_type _compression = none) explicit packed_transaction(const signed_transaction& t, compression_type _compression = none)
:signatures(t.signatures), compression(_compression) :signatures(t.signatures), compression(_compression), unpacked_trx(t)
{ {
set_transaction(t); local_pack_transaction();
set_context_free_data(t.context_free_data); local_pack_context_free_data();
} }
explicit packed_transaction(signed_transaction&& t, compression_type _compression = none) explicit packed_transaction(signed_transaction&& t, compression_type _compression = none)
:signatures(std::move(t.signatures)), compression(_compression) :signatures(t.signatures), compression(_compression), unpacked_trx(std::move(t))
{ {
set_transaction(t); local_pack_transaction();
set_context_free_data(t.context_free_data); local_pack_context_free_data();
} }
// used by abi_serializer // used by abi_serializer
explicit packed_transaction( bytes&& packed_txn, vector<signature_type>&& sigs, packed_transaction( bytes&& packed_txn, vector<signature_type>&& sigs, bytes&& packed_cfd, compression_type _compression );
bytes&& packed_cfd, vector<bytes>&& cfd, compression_type _compression ); packed_transaction( bytes&& packed_txn, vector<signature_type>&& sigs, vector<bytes>&& cfd, compression_type _compression );
explicit packed_transaction( signed_transaction&& t, bytes&& packed_cfd, compression_type _compression ); packed_transaction( transaction&& t, vector<signature_type>&& sigs, bytes&& packed_cfd, compression_type _compression );
uint32_t get_unprunable_size()const; uint32_t get_unprunable_size()const;
uint32_t get_prunable_size()const; uint32_t get_prunable_size()const;
digest_type packed_digest()const; digest_type packed_digest()const;
time_point_sec expiration()const; transaction_id_type id()const { return unpacked_trx.id(); }
transaction_id_type id()const; bytes get_raw_transaction()const;
transaction_id_type get_uncached_id()const; // thread safe
bytes get_raw_transaction()const; // thread safe
vector<bytes> get_context_free_data()const;
transaction get_transaction()const;
signed_transaction get_signed_transaction()const;
time_point_sec expiration()const { return unpacked_trx.expiration; }
const vector<bytes>& get_context_free_data()const { return unpacked_trx.context_free_data; }
const transaction& get_transaction()const { return unpacked_trx; }
const signed_transaction& get_signed_transaction()const { return unpacked_trx; }
const vector<signature_type>& get_signatures()const { return signatures; } const vector<signature_type>& get_signatures()const { return signatures; }
const fc::enum_type<uint8_t,compression_type>& get_compression()const { return compression; } const fc::enum_type<uint8_t,compression_type>& get_compression()const { return compression; }
const bytes& get_packed_context_free_data()const { return packed_context_free_data; } const bytes& get_packed_context_free_data()const { return packed_context_free_data; }
const bytes& get_packed_transaction()const { return packed_trx; } const bytes& get_packed_transaction()const { return packed_trx; }
private: private:
void local_unpack()const; void local_unpack_transaction(vector<bytes>&& context_free_data);
void set_transaction(const transaction& t); void local_unpack_context_free_data();
void set_context_free_data(const vector<bytes>& cfd); void local_pack_transaction();
void local_pack_context_free_data();
friend struct fc::reflector<packed_transaction>; friend struct fc::reflector<packed_transaction>;
friend struct fc::reflector_init_visitor<packed_transaction>;
void reflector_init();
private: private:
vector<signature_type> signatures; vector<signature_type> signatures;
fc::enum_type<uint8_t,compression_type> compression; fc::enum_type<uint8_t,compression_type> compression;
...@@ -160,7 +166,8 @@ namespace eosio { namespace chain { ...@@ -160,7 +166,8 @@ namespace eosio { namespace chain {
bytes packed_trx; bytes packed_trx;
private: private:
mutable optional<transaction> unpacked_trx; // <-- intermediate buffer used to retrieve values // cache unpacked trx, for thread safety do not modify after construction
signed_transaction unpacked_trx;
}; };
using packed_transaction_ptr = std::shared_ptr<packed_transaction>; using packed_transaction_ptr = std::shared_ptr<packed_transaction>;
......
...@@ -23,7 +23,6 @@ class transaction_metadata { ...@@ -23,7 +23,6 @@ class transaction_metadata {
public: public:
transaction_id_type id; transaction_id_type id;
transaction_id_type signed_id; transaction_id_type signed_id;
signed_transaction trx;
packed_transaction_ptr packed_trx; packed_transaction_ptr packed_trx;
fc::microseconds sig_cpu_usage; fc::microseconds sig_cpu_usage;
optional<pair<chain_id_type, flat_set<public_key_type>>> signing_keys; optional<pair<chain_id_type, flat_set<public_key_type>>> signing_keys;
...@@ -40,13 +39,13 @@ class transaction_metadata { ...@@ -40,13 +39,13 @@ class transaction_metadata {
transaction_metadata operator=(transaction_metadata&&) = delete; transaction_metadata operator=(transaction_metadata&&) = delete;
explicit transaction_metadata( const signed_transaction& t, packed_transaction::compression_type c = packed_transaction::none ) explicit transaction_metadata( const signed_transaction& t, packed_transaction::compression_type c = packed_transaction::none )
:id(t.id()), trx(t), packed_trx(std::make_shared<packed_transaction>(t, c)) { :id(t.id()), packed_trx(std::make_shared<packed_transaction>(t, c)) {
//raw_packed = fc::raw::pack( static_cast<const transaction&>(trx) ); //raw_packed = fc::raw::pack( static_cast<const transaction&>(trx) );
signed_id = digest_type::hash(*packed_trx); signed_id = digest_type::hash(*packed_trx);
} }
explicit transaction_metadata( const packed_transaction_ptr& ptrx ) explicit transaction_metadata( const packed_transaction_ptr& ptrx )
:id(ptrx->id()), trx( ptrx->get_signed_transaction() ), packed_trx(ptrx) { :id(ptrx->id()), packed_trx(ptrx) {
//raw_packed = fc::raw::pack( static_cast<const transaction&>(trx) ); //raw_packed = fc::raw::pack( static_cast<const transaction&>(trx) );
signed_id = digest_type::hash(*packed_trx); signed_id = digest_type::hash(*packed_trx);
} }
...@@ -54,9 +53,8 @@ class transaction_metadata { ...@@ -54,9 +53,8 @@ class transaction_metadata {
const flat_set<public_key_type>& recover_keys( const chain_id_type& chain_id ); const flat_set<public_key_type>& recover_keys( const chain_id_type& chain_id );
static void create_signing_keys_future( const transaction_metadata_ptr& mtrx, boost::asio::thread_pool& thread_pool, static void create_signing_keys_future( const transaction_metadata_ptr& mtrx, boost::asio::thread_pool& thread_pool,
const chain_id_type& chain_id, fc::microseconds timelimit ); const chain_id_type& chain_id, fc::microseconds time_limit );
uint32_t total_actions()const { return trx.context_free_actions.size() + trx.actions.size(); }
}; };
} } // eosio::chain } } // eosio::chain
...@@ -289,127 +289,110 @@ bytes packed_transaction::get_raw_transaction() const ...@@ -289,127 +289,110 @@ bytes packed_transaction::get_raw_transaction() const
} FC_CAPTURE_AND_RETHROW((compression)(packed_trx)) } FC_CAPTURE_AND_RETHROW((compression)(packed_trx))
} }
vector<bytes> packed_transaction::get_context_free_data()const packed_transaction::packed_transaction( bytes&& packed_txn, vector<signature_type>&& sigs, bytes&& packed_cfd, compression_type _compression )
:signatures(std::move(sigs))
,compression(_compression)
,packed_context_free_data(std::move(packed_cfd))
,packed_trx(std::move(packed_txn))
{ {
try { local_unpack_transaction({});
switch(compression) { if( !packed_context_free_data.empty() ) {
case none: local_unpack_context_free_data();
return unpack_context_free_data(packed_context_free_data); }
case zlib:
return zlib_decompress_context_free_data(packed_context_free_data);
default:
EOS_THROW(unknown_transaction_compression, "Unknown transaction compression algorithm");
}
} FC_CAPTURE_AND_RETHROW((compression)(packed_context_free_data))
} }
time_point_sec packed_transaction::expiration()const packed_transaction::packed_transaction( bytes&& packed_txn, vector<signature_type>&& sigs, vector<bytes>&& cfd, compression_type _compression )
:signatures(std::move(sigs))
,compression(_compression)
,packed_trx(std::move(packed_txn))
{ {
local_unpack(); local_unpack_transaction( std::move( cfd ) );
return unpacked_trx->expiration; if( !unpacked_trx.context_free_data.empty() ) {
local_pack_context_free_data();
}
} }
transaction_id_type packed_transaction::id()const packed_transaction::packed_transaction( transaction&& t, vector<signature_type>&& sigs, bytes&& packed_cfd, compression_type _compression )
:signatures(std::move(sigs))
,compression(_compression)
,packed_context_free_data(std::move(packed_cfd))
,unpacked_trx(std::move(t), signatures, {})
{ {
local_unpack(); local_pack_transaction();
return get_transaction().id(); if( !packed_context_free_data.empty() ) {
local_unpack_context_free_data();
}
} }
transaction_id_type packed_transaction::get_uncached_id()const void packed_transaction::reflector_init()
{ {
const auto raw = get_raw_transaction(); // called after construction, but always on the same thread and before packed_transaction passed to any other threads
return fc::raw::unpack<transaction>( raw ).id(); static_assert(&fc::reflector_init_visitor<packed_transaction>::reflector_init, "FC with reflector_init required");
static_assert(fc::raw::has_feature_reflector_init_on_unpacked_reflected_types,
"FC unpack needs to call reflector_init otherwise unpacked_trx will not be initialized");
EOS_ASSERT( unpacked_trx.expiration == time_point_sec(), tx_decompression_error, "packed_transaction already unpacked" );
local_unpack_transaction({});
local_unpack_context_free_data();
} }
void packed_transaction::local_unpack()const void packed_transaction::local_unpack_transaction(vector<bytes>&& context_free_data)
{ {
if (!unpacked_trx) { try {
try { switch( compression ) {
switch(compression) {
case none: case none:
unpacked_trx = unpack_transaction(packed_trx); unpacked_trx = signed_transaction( unpack_transaction( packed_trx ), signatures, std::move(context_free_data) );
break; break;
case zlib: case zlib:
unpacked_trx = zlib_decompress_transaction(packed_trx); unpacked_trx = signed_transaction( zlib_decompress_transaction( packed_trx ), signatures, std::move(context_free_data) );
break; break;
default: default:
EOS_THROW(unknown_transaction_compression, "Unknown transaction compression algorithm"); EOS_THROW( unknown_transaction_compression, "Unknown transaction compression algorithm" );
} }
} FC_CAPTURE_AND_RETHROW((compression)(packed_trx)) } FC_CAPTURE_AND_RETHROW( (compression) )
}
}
transaction packed_transaction::get_transaction()const
{
local_unpack();
return transaction(*unpacked_trx);
} }
signed_transaction packed_transaction::get_signed_transaction() const void packed_transaction::local_unpack_context_free_data()
{ {
try { try {
switch(compression) { EOS_ASSERT(unpacked_trx.context_free_data.empty(), tx_decompression_error, "packed_transaction.context_free_data not empty");
switch( compression ) {
case none: case none:
return signed_transaction(get_transaction(), signatures, unpack_context_free_data(packed_context_free_data)); unpacked_trx.context_free_data = unpack_context_free_data( packed_context_free_data );
break;
case zlib: case zlib:
return signed_transaction(get_transaction(), signatures, zlib_decompress_context_free_data(packed_context_free_data)); unpacked_trx.context_free_data = zlib_decompress_context_free_data( packed_context_free_data );
break;
default: default:
EOS_THROW(unknown_transaction_compression, "Unknown transaction compression algorithm"); EOS_THROW( unknown_transaction_compression, "Unknown transaction compression algorithm" );
} }
} FC_CAPTURE_AND_RETHROW((compression)(packed_trx)(packed_context_free_data)) } FC_CAPTURE_AND_RETHROW( (compression) )
} }
packed_transaction::packed_transaction( bytes&& packed_txn, vector<signature_type>&& sigs, void packed_transaction::local_pack_transaction()
bytes&& packed_cfd, vector<bytes>&& cfd, compression_type _compression )
:signatures(std::move(sigs))
,compression(_compression)
,packed_context_free_data(std::move(packed_cfd))
,packed_trx(std::move(packed_txn))
{
EOS_ASSERT(packed_cfd.empty() || cfd.empty(), tx_decompression_error, "Invalid packed_transaction");
if( !cfd.empty() ) {
set_context_free_data(cfd);
}
}
packed_transaction::packed_transaction( signed_transaction&& t, bytes&& packed_cfd, compression_type _compression )
:signatures(std::move(t.signatures))
,compression(_compression)
,packed_context_free_data(std::move(packed_cfd))
{
set_transaction(t);
// allow passed in packed_cfd to overwrite signed_transaction.context_free_data if provided
if( packed_context_free_data.empty() ) {
set_context_free_data(t.context_free_data);
}
}
void packed_transaction::set_transaction(const transaction& t)
{ {
try { try {
switch(compression) { switch(compression) {
case none: case none:
packed_trx = pack_transaction(t); packed_trx = pack_transaction(unpacked_trx);
break; break;
case zlib: case zlib:
packed_trx = zlib_compress_transaction(t); packed_trx = zlib_compress_transaction(unpacked_trx);
break; break;
default: default:
EOS_THROW(unknown_transaction_compression, "Unknown transaction compression algorithm"); EOS_THROW(unknown_transaction_compression, "Unknown transaction compression algorithm");
} }
} FC_CAPTURE_AND_RETHROW((compression)(t)) } FC_CAPTURE_AND_RETHROW((compression))
} }
void packed_transaction::set_context_free_data(const vector<bytes>& cfd) void packed_transaction::local_pack_context_free_data()
{ {
try { try {
switch(compression) { switch(compression) {
case none: case none:
packed_context_free_data = pack_context_free_data(cfd); packed_context_free_data = pack_context_free_data(unpacked_trx.context_free_data);
break; break;
case zlib: case zlib:
packed_context_free_data = zlib_compress_context_free_data(cfd); packed_context_free_data = zlib_compress_context_free_data(unpacked_trx.context_free_data);
break; break;
default: default:
EOS_THROW(unknown_transaction_compression, "Unknown transaction compression algorithm"); EOS_THROW(unknown_transaction_compression, "Unknown transaction compression algorithm");
......
...@@ -17,7 +17,7 @@ const flat_set<public_key_type>& transaction_metadata::recover_keys( const chain ...@@ -17,7 +17,7 @@ const flat_set<public_key_type>& transaction_metadata::recover_keys( const chain
} }
} }
flat_set<public_key_type> recovered_pub_keys; flat_set<public_key_type> recovered_pub_keys;
sig_cpu_usage = trx.get_signature_keys( chain_id, fc::time_point::maximum(), recovered_pub_keys ); sig_cpu_usage = packed_trx->get_signed_transaction().get_signature_keys( chain_id, fc::time_point::maximum(), recovered_pub_keys );
signing_keys.emplace( chain_id, std::move( recovered_pub_keys )); signing_keys.emplace( chain_id, std::move( recovered_pub_keys ));
} }
return signing_keys->second; return signing_keys->second;
...@@ -36,7 +36,8 @@ void transaction_metadata::create_signing_keys_future( const transaction_metadat ...@@ -36,7 +36,8 @@ void transaction_metadata::create_signing_keys_future( const transaction_metadat
fc::microseconds cpu_usage; fc::microseconds cpu_usage;
flat_set<public_key_type> recovered_pub_keys; flat_set<public_key_type> recovered_pub_keys;
if( mtrx ) { if( mtrx ) {
cpu_usage = mtrx->trx.get_signature_keys( chain_id, deadline, recovered_pub_keys ); const signed_transaction& trn = mtrx->packed_trx->get_signed_transaction();
cpu_usage = trn.get_signature_keys( chain_id, deadline, recovered_pub_keys );
} }
return std::make_tuple( chain_id, cpu_usage, std::move( recovered_pub_keys )); return std::make_tuple( chain_id, cpu_usage, std::move( recovered_pub_keys ));
} ); } );
......
Subproject commit a8613d3786cddfcc336808d2b9b7df655e6cc6d1 Subproject commit a6bbb25c3d395b8ccc62314311822db89569eb9d
...@@ -441,7 +441,7 @@ namespace eosio { ...@@ -441,7 +441,7 @@ namespace eosio {
if( itr != _transaction_status.end() ) { if( itr != _transaction_status.end() ) {
if( !itr->known_by_peer() ) { if( !itr->known_by_peer() ) {
_transaction_status.modify( itr, [&]( auto& stat ) { _transaction_status.modify( itr, [&]( auto& stat ) {
stat.expired = std::min<fc::time_point>( fc::time_point::now() + fc::seconds(5), t->trx.expiration ); stat.expired = std::min<fc::time_point>( fc::time_point::now() + fc::seconds(5), t->packed_trx->expiration() );
}); });
} }
return; return;
...@@ -555,8 +555,7 @@ namespace eosio { ...@@ -555,8 +555,7 @@ namespace eosio {
for( const auto& receipt : s->block->transactions ) { for( const auto& receipt : s->block->transactions ) {
if( receipt.trx.which() == 1 ) { if( receipt.trx.which() == 1 ) {
const auto& pt = receipt.trx.get<packed_transaction>(); const auto& pt = receipt.trx.get<packed_transaction>();
// get id via get_uncached_id() as packed_transaction.id() mutates internal transaction state const auto& tid = pt.id();
const auto& tid = pt.get_uncached_id();
auto itr = _transaction_status.find( tid ); auto itr = _transaction_status.find( tid );
if( itr != _transaction_status.end() ) if( itr != _transaction_status.end() )
_transaction_status.erase(itr); _transaction_status.erase(itr);
...@@ -1014,8 +1013,7 @@ namespace eosio { ...@@ -1014,8 +1013,7 @@ namespace eosio {
for( const auto& receipt : b->transactions ) { for( const auto& receipt : b->transactions ) {
if( receipt.trx.which() == 1 ) { if( receipt.trx.which() == 1 ) {
const auto& pt = receipt.trx.get<packed_transaction>(); const auto& pt = receipt.trx.get<packed_transaction>();
// get id via get_uncached_id() as packed_transaction.id() mutates internal transaction state const auto& id = pt.id();
const auto& id = pt.get_uncached_id();
mark_transaction_known_by_peer(id); mark_transaction_known_by_peer(id);
} }
} }
...@@ -1552,8 +1550,7 @@ namespace eosio { ...@@ -1552,8 +1550,7 @@ namespace eosio {
// ilog( "recv trx ${n}", ("n", id) ); // ilog( "recv trx ${n}", ("n", id) );
if( p->expiration() < fc::time_point::now() ) return; if( p->expiration() < fc::time_point::now() ) return;
// get id via get_uncached_id() as packed_transaction.id() mutates internal transaction state const auto& id = p->id();
const auto& id = p->get_uncached_id();
if( mark_transaction_known_by_peer( id ) ) if( mark_transaction_known_by_peer( id ) )
return; return;
......
...@@ -734,7 +734,7 @@ void mongo_db_plugin_impl::_process_accepted_transaction( const chain::transacti ...@@ -734,7 +734,7 @@ void mongo_db_plugin_impl::_process_accepted_transaction( const chain::transacti
using bsoncxx::builder::basic::make_array; using bsoncxx::builder::basic::make_array;
namespace bbb = bsoncxx::builder::basic; namespace bbb = bsoncxx::builder::basic;
const auto& trx = t->trx; const signed_transaction& trx = t->packed_trx->get_signed_transaction();
if( !filter_include( trx ) ) return; if( !filter_include( trx ) ) return;
...@@ -1095,11 +1095,8 @@ void mongo_db_plugin_impl::_process_irreversible_block(const chain::block_state_ ...@@ -1095,11 +1095,8 @@ void mongo_db_plugin_impl::_process_irreversible_block(const chain::block_state_
string trx_id_str; string trx_id_str;
if( receipt.trx.contains<packed_transaction>() ) { if( receipt.trx.contains<packed_transaction>() ) {
const auto& pt = receipt.trx.get<packed_transaction>(); const auto& pt = receipt.trx.get<packed_transaction>();
// get id via get_raw_transaction() as packed_transaction.id() mutates internal transaction state if( !filter_include( pt.get_signed_transaction() ) ) continue;
const auto& raw = pt.get_raw_transaction(); const auto& id = pt.id();
const auto& trx = fc::raw::unpack<transaction>( raw );
if( !filter_include( trx ) ) continue;
const auto& id = trx.id();
trx_id_str = id.str(); trx_id_str = id.str();
} else { } else {
const auto& id = receipt.trx.get<transaction_id_type>(); const auto& id = receipt.trx.get<transaction_id_type>();
......
...@@ -58,13 +58,14 @@ std::pair<signed_block_ptr, signed_block_ptr> corrupt_trx_in_block(validating_te ...@@ -58,13 +58,14 @@ std::pair<signed_block_ptr, signed_block_ptr> corrupt_trx_in_block(validating_te
// Make a copy of the valid block and corrupt the transaction // Make a copy of the valid block and corrupt the transaction
auto copy_b = std::make_shared<signed_block>(b->clone()); auto copy_b = std::make_shared<signed_block>(b->clone());
auto signed_tx = copy_b->transactions.back().trx.get<packed_transaction>().get_signed_transaction(); const auto& packed_trx = copy_b->transactions.back().trx.get<packed_transaction>();
auto signed_tx = packed_trx.get_signed_transaction();
// Corrupt one signature // Corrupt one signature
signed_tx.signatures.clear(); signed_tx.signatures.clear();
signed_tx.sign(main.get_private_key(act_name, "active"), main.control->get_chain_id()); signed_tx.sign(main.get_private_key(act_name, "active"), main.control->get_chain_id());
// Replace the valid transaction with the invalid transaction // Replace the valid transaction with the invalid transaction
auto invalid_packed_tx = packed_transaction(signed_tx); auto invalid_packed_tx = packed_transaction(signed_tx, packed_trx.get_compression());
copy_b->transactions.back().trx = invalid_packed_tx; copy_b->transactions.back().trx = invalid_packed_tx;
// Re-calculate the transaction merkle // Re-calculate the transaction merkle
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册