From 9a2ab622b936b7d7577dc7b97c2a739f35c59713 Mon Sep 17 00:00:00 2001 From: Andrew Falaleev Date: Tue, 21 May 2019 17:14:42 +0700 Subject: [PATCH] Add storage usage to transaction receipt. #706 --- libraries/chain/controller.cpp | 19 +++++++++++++------ libraries/chain/include/eosio/chain/block.hpp | 14 +++++++++----- libraries/chain/include/eosio/chain/trace.hpp | 4 +++- .../eosio/chain/transaction_context.hpp | 6 ++++-- libraries/chain/transaction_context.cpp | 3 +++ 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index c7eb3ef1df4..39f3947d571 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -780,7 +780,8 @@ struct controller_impl { auto restore = make_block_restore_point(); trace->receipt = push_receipt( gtrx.trx_id, transaction_receipt::soft_fail, - trx_context.billed_cpu_time_us, trace->net_usage, trx_context.billed_ram_bytes ); + trx_context.billed_cpu_time_us, trace->net_usage, + trx_context.billed_ram_bytes, trace->storage_bytes ); fc::move_append( pending->_actions, move(trx_context.executed) ); trx_context.squash(); @@ -899,7 +900,8 @@ struct controller_impl { trace->block_time = self.pending_block_time(); trace->producer_block_id = self.pending_producer_block_id(); trace->scheduled = true; - trace->receipt = push_receipt( gtrx.trx_id, transaction_receipt::expired, billed.cpu_time_us, 0, billed.ram_bytes ); // expire the transaction + trace->receipt = push_receipt( gtrx.trx_id, transaction_receipt::expired, billed.cpu_time_us, 0, + billed.ram_bytes, 0 ); // expire the transaction emit( self.accepted_transaction, trx ); emit( self.applied_transaction, trace ); undo_session.squash(); @@ -939,7 +941,8 @@ struct controller_impl { transaction_receipt::executed, trx_context.billed_cpu_time_us, trace->net_usage, - trx_context.billed_ram_bytes); + trx_context.billed_ram_bytes, + trace->storage_bytes); fc::move_append( pending->_actions, move(trx_context.executed) ); @@ -1006,7 +1009,7 @@ struct controller_impl { resource_limits.add_transaction_usage( trx_context.bill_to_accounts, cpu_time_to_bill_us, 0, ram_to_bill_bytes, self.pending_block_time() ); // Should never fail - trace->receipt = push_receipt(gtrx.trx_id, transaction_receipt::hard_fail, cpu_time_to_bill_us, 0, ram_to_bill_bytes); + trace->receipt = push_receipt(gtrx.trx_id, transaction_receipt::hard_fail, cpu_time_to_bill_us, 0, ram_to_bill_bytes, 0); emit( self.accepted_transaction, trx ); emit( self.applied_transaction, trace ); @@ -1026,7 +1029,8 @@ struct controller_impl { */ template const transaction_receipt& push_receipt( const T& trx, transaction_receipt_header::status_enum status, - uint64_t cpu_usage_us, uint64_t net_usage, uint64_t ram_bytes ) { + uint64_t cpu_usage_us, uint64_t net_usage, + uint64_t ram_bytes, int64_t storage_bytes ) { uint64_t net_usage_words = net_usage / 8; EOS_ASSERT( net_usage_words*8 == net_usage, transaction_exception, "net_usage is not divisible by 8" ); pending->_pending_block_state->block->transactions.emplace_back( trx ); @@ -1034,6 +1038,7 @@ struct controller_impl { r.cpu_usage_us = cpu_usage_us; r.net_usage_words = net_usage_words; r.ram_kbytes = ram_bytes >> 10; + r.storage_kbytes = storage_bytes >> 10; r.status = status; return r; } @@ -1114,7 +1119,8 @@ struct controller_impl { transaction_receipt::status_enum s = (trx_context.delay == fc::seconds(0)) ? transaction_receipt::executed : transaction_receipt::delayed; - trace->receipt = push_receipt(*trx->packed_trx, s, trx_context.billed_cpu_time_us, trace->net_usage, trx_context.billed_ram_bytes); + trace->receipt = push_receipt(*trx->packed_trx, s, trx_context.billed_cpu_time_us, trace->net_usage, + trx_context.billed_ram_bytes, trace->storage_bytes); pending->_pending_block_state->trxs.emplace_back(trx); } else { transaction_receipt_header r; @@ -1122,6 +1128,7 @@ struct controller_impl { r.cpu_usage_us = trx_context.billed_cpu_time_us; r.net_usage_words = trace->net_usage / 8; r.ram_kbytes = trx_context.billed_ram_bytes >> 10; + r.storage_kbytes = trace->storage_bytes >> 10; trace->receipt = r; } diff --git a/libraries/chain/include/eosio/chain/block.hpp b/libraries/chain/include/eosio/chain/block.hpp index 9638f9bf8f9..c151ec6a211 100644 --- a/libraries/chain/include/eosio/chain/block.hpp +++ b/libraries/chain/include/eosio/chain/block.hpp @@ -23,13 +23,15 @@ namespace eosio { namespace chain { explicit transaction_receipt_header( status_enum s ):status(s){} friend inline bool operator ==( const transaction_receipt_header& lhs, const transaction_receipt_header& rhs ) { - return std::tie(lhs.status, lhs.cpu_usage_us, lhs.net_usage_words) == std::tie(rhs.status, rhs.cpu_usage_us, rhs.net_usage_words); + return std::tie(lhs.status, lhs.cpu_usage_us, lhs.net_usage_words, lhs.ram_kbytes, lhs.storage_kbytes) == + std::tie(rhs.status, rhs.cpu_usage_us, rhs.net_usage_words, rhs.ram_kbytes, rhs.storage_kbytes); } fc::enum_type status; - uint32_t cpu_usage_us = 0; ///< total billed CPU usage (microseconds) - fc::unsigned_int net_usage_words; ///< total billed NET usage, so we can reconstruct resource state when skipping context free data... hard failures... - uint64_t ram_kbytes = 0; ///< total billed RAM usage (kbytes) + fc::unsigned_int cpu_usage_us = 0; ///< total billed CPU usage (microseconds) + fc::unsigned_int net_usage_words; ///< total billed NET usage, so we can reconstruct resource state when skipping context free data... hard failures... + fc::unsigned_int ram_kbytes = 0; ///< total billed RAM usage (kbytes) + fc::signed_int storage_kbytes = 0; ///< total billed STORAGE usage (kbytes) }; struct transaction_receipt : public transaction_receipt_header { @@ -45,6 +47,8 @@ namespace eosio { namespace chain { fc::raw::pack( enc, status ); fc::raw::pack( enc, cpu_usage_us ); fc::raw::pack( enc, net_usage_words ); + fc::raw::pack( enc, ram_kbytes ); + fc::raw::pack( enc, storage_kbytes ); if( trx.contains() ) fc::raw::pack( enc, trx.get() ); else @@ -84,6 +88,6 @@ namespace eosio { namespace chain { FC_REFLECT_ENUM( eosio::chain::transaction_receipt::status_enum, (executed)(soft_fail)(hard_fail)(delayed)(expired) ) -FC_REFLECT(eosio::chain::transaction_receipt_header, (status)(cpu_usage_us)(net_usage_words)(ram_kbytes) ) +FC_REFLECT(eosio::chain::transaction_receipt_header, (status)(cpu_usage_us)(net_usage_words)(ram_kbytes)(storage_kbytes) ) FC_REFLECT_DERIVED(eosio::chain::transaction_receipt, (eosio::chain::transaction_receipt_header), (trx) ) FC_REFLECT_DERIVED(eosio::chain::signed_block, (eosio::chain::signed_block_header), (transactions)(archive_records)(block_extensions) ) diff --git a/libraries/chain/include/eosio/chain/trace.hpp b/libraries/chain/include/eosio/chain/trace.hpp index f61dada8901..6017f8898e2 100644 --- a/libraries/chain/include/eosio/chain/trace.hpp +++ b/libraries/chain/include/eosio/chain/trace.hpp @@ -56,7 +56,9 @@ namespace eosio { namespace chain { fc::optional producer_block_id; fc::optional receipt; fc::microseconds elapsed; + uint64_t ram_bytes = 0; uint64_t net_usage = 0; + int64_t storage_bytes = 0; bool scheduled = false; vector action_traces; ///< disposable @@ -78,5 +80,5 @@ FC_REFLECT_DERIVED( eosio::chain::action_trace, (eosio::chain::base_action_trace), (inline_traces) ) FC_REFLECT( eosio::chain::transaction_trace, (id)(block_num)(block_time)(producer_block_id) - (receipt)(elapsed)(net_usage)(scheduled) + (receipt)(elapsed)(ram_bytes)(net_usage)(storage_bytes)(scheduled) (action_traces)(failed_dtrx_trace)(except) ) diff --git a/libraries/chain/include/eosio/chain/transaction_context.hpp b/libraries/chain/include/eosio/chain/transaction_context.hpp index e0c4d7d5505..bf3b0651b96 100644 --- a/libraries/chain/include/eosio/chain/transaction_context.hpp +++ b/libraries/chain/include/eosio/chain/transaction_context.hpp @@ -92,7 +92,7 @@ namespace eosio { namespace chain { available_resources.add_net_usage(u); available_resources.check_cpu_usage((fc::time_point::now() - pseudo_start).count()); } - inline void add_cpu_usage( uint64_t u ) { billed_cpu_time_us += u;} + // inline void add_cpu_usage( uint64_t u ) { billed_cpu_time_us += u;} uint64_t get_net_usage() const {return net_usage;} uint64_t get_cpu_usage() const {return billed_cpu_time_us;} @@ -178,7 +178,7 @@ namespace eosio { namespace chain { int64_t billed_cpu_time_us = 0; bool explicit_billed_cpu_time = false; - uint64_t billed_ram_bytes = 0; + uint64_t& billed_ram_bytes; bool explicit_billed_ram_bytes = false; private: @@ -189,6 +189,8 @@ namespace eosio { namespace chain { uint64_t eager_net_limit = 0; uint64_t& net_usage; /// reference to trace->net_usage + int64_t& storage_bytes; /// reference to trace->storage_bytes + fc::microseconds initial_objective_duration_limit; fc::microseconds objective_duration_limit; fc::time_point _deadline = fc::time_point::maximum(); diff --git a/libraries/chain/transaction_context.cpp b/libraries/chain/transaction_context.cpp index 42f790af207..33feeec69fc 100644 --- a/libraries/chain/transaction_context.cpp +++ b/libraries/chain/transaction_context.cpp @@ -182,7 +182,9 @@ namespace bacc = boost::accumulators; ,chaindb_undo_session() ,trace(std::make_shared()) ,start(s) + ,billed_ram_bytes(trace->ram_bytes) ,net_usage(trace->net_usage) + ,storage_bytes(trace->storage_bytes) ,pseudo_start(s) { if (!c.skip_db_sessions()) { @@ -546,6 +548,7 @@ namespace bacc = boost::accumulators; } void transaction_context::add_storage_usage( const storage_payer_info& storage ) { + storage_bytes += storage.delta; auto now = fc::time_point::now(); if (available_resources.update_storage_usage(storage)) { available_resources.check_cpu_usage((now - pseudo_start).count());