575                                                                                         {
  578 
  579         auto send_response = [
this, &trx, &chain, &
next](
const std::variant<fc::exception_ptr, transaction_trace_ptr>& response) {
 
  581 
  582            auto get_trace = [&](
const std::variant<fc::exception_ptr, transaction_trace_ptr>& response) -> 
fc::variant {
 
  583               if (std::holds_alternative<fc::exception_ptr>(response)) {
  584                  return fc::variant{std::get<fc::exception_ptr>(response)};
 
  585               } else {
  587               }
  588 
  589            };
  590 
  592            if (std::holds_alternative<fc::exception_ptr>(response)) {
  593               except_ptr = std::get<fc::exception_ptr>(response);
  594            } else if (std::get<transaction_trace_ptr>(response)->except) {
  595               except_ptr = std::get<transaction_trace_ptr>(response)->except->dynamic_copy_exception();
  596            }
  597 
  598            if (!trx->read_only) {
  600            }
  601 
  602            if (except_ptr) {
  605                        ("block_num", chain.head_block_num() + 1)
  607                        ("txid", trx->id())
  608                        ("a", trx->packed_trx()->get_transaction().first_authorizer())
  609                        ("why", except_ptr->what()));
  610                  fc_dlog(
_trx_log, 
"[TRX_TRACE] Block ${block_num} for producer ${prod} is REJECTING tx: ${trx}",
 
  615                                ("entire_trace", get_trace(response)));
  616               } else {
  618                          ("txid", trx->id())
  619                          ("a", trx->packed_trx()->get_transaction().first_authorizer())
  620                          ("why", except_ptr->what()));
  621                  fc_dlog(
_trx_log, 
"[TRX_TRACE] Speculative execution is REJECTING tx: ${trx} ",
 
  624                          ("entire_trace", get_trace(response)));
  625               }
  626            } else {
  629                          ("block_num", chain.head_block_num() + 1)
  631                          ("txid", trx->id())
  632                          ("a", trx->packed_trx()->get_transaction().first_authorizer())
  633                          ("cpu", trx->billed_cpu_time_us));
  634                  fc_dlog(
_trx_log, 
"[TRX_TRACE] Block ${block_num} for producer ${prod} is ACCEPTING tx: ${trx}",
 
  639                                   ("entire_trace", get_trace(response)));
  640               } else {
  642                          ("txid", trx->id())
  643                          ("a", trx->packed_trx()->get_transaction().first_authorizer())
  644                          ("cpu", trx->billed_cpu_time_us));
  646                           ("entire_trace", get_trace(response)));
  647                  fc_dlog(
_trx_log, 
"[TRX_TRACE] Speculative execution is ACCEPTING tx: ${trx}",
 
  649               }
  650            }
  651         };
  652 
  653         try {
  654            const auto& id = trx->id();
  655 
  656            fc::time_point bt = chain.is_building_block() ? chain.pending_block_time() : chain.head_block_time();
 
  659               send_response( std::static_pointer_cast<fc::exception>(
  660                     std::make_shared<expired_tx_exception>(
  661                           FC_LOG_MESSAGE( error, 
"expired transaction ${id}, expiration ${e}, block time ${bt}",
 
  662                                           (
"id", 
id)(
"e", expire)( 
"bt", 
bt )))));
 
  663               return true;
  664            }
  665 
  666            if( chain.is_known_unexpired_transaction( id )) {
  667               send_response( std::static_pointer_cast<fc::exception>( std::make_shared<tx_duplicate>(
  668                     FC_LOG_MESSAGE( error, 
"duplicate transaction ${id}", (
"id", 
id)))) );
 
  669               return true;
  670            }
  671 
  672            if( !chain.is_building_block()) {
  674               return true;
  675            }
  676 
  677            auto first_auth = trx->packed_trx()->get_transaction().first_authorizer();
  679               send_response( std::static_pointer_cast<fc::exception>( std::make_shared<tx_cpu_usage_exceeded>(
  680                     FC_LOG_MESSAGE( error, 
"transaction ${id} exceeded failure limit for account ${a}",
 
  681                                     ("id", trx->id())("a", first_auth) ) ) ) );
  682               return true;
  683            }
  684 
  689 
  693                                              || trx->read_only;
  694 
  696            if( !disable_subjective_billing )
  698 
  699            auto prev_billed_cpu_time_us = trx->billed_cpu_time_us;
  700            auto trace = chain.push_transaction( trx, block_deadline, max_trx_time, prev_billed_cpu_time_us, false, sub_bill );
  702            if( trace->except ) {
  703               if( exception_is_exhausted( *trace->except ) ) {
  707                              ("block_num", chain.head_block_num() + 1)
  709                              ("txid", trx->id()));
  710                  } else {
  712                              ("txid", trx->id()));
  713                  }
  715               } else {
  716                   if (!disable_subjective_billing)
  718 
  720                     auto failure_code = trace->except->code();
  721                     if( failure_code != tx_duplicate::code_value ) {
  722                        
  723                        fc_dlog( 
_log, 
"Failed ${c} trx, prev billed: ${p}us, ran: ${r}us, id: ${id}",
 
  724                                 ("c", trace->except->code())( "p", prev_billed_cpu_time_us )
  727                     }
  728                  }
  729                  if( return_failure_traces ) {
  730                     send_response( trace );
  731                  } else {
  732                     auto e_ptr = trace->except->dynamic_copy_exception();
  733                     send_response( e_ptr );
  734                  }
  735               }
  736            } else {
  738                  
  739                  
  740                  
  742               } else {
  743                  
  744                  if (!disable_subjective_billing)
  747               }
  748               send_response( trace );
  749            }
  750 
  753         } catch ( boost::interprocess::bad_alloc& ) {
  755         } catch ( std::bad_alloc& ) {
  758 
  760      }
void publish(int priority, const Data &data)
 
constexpr int64_t count() const
 
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
 
void add_incoming(const transaction_metadata_ptr &trx, bool persist_until_expired, bool return_failure_trace, next_func_t next)
 
void add_persisted(const transaction_metadata_ptr &trx)
 
fc::variant get_log_trx_trace(const chain::transaction_trace_ptr &trx_trace) const
 
fc::variant get_log_trx(const transaction &trx) const
 
bool _disable_persist_until_expired
 
bool _disable_subjective_p2p_billing
 
fc::time_point calculate_block_deadline(const fc::time_point &) const
 
bool block_is_exhausted() const
 
bool _disable_subjective_api_billing
 
account_failures _account_fails
 
account_name get_pending_block_producer()
 
int64_t get_subjective_bill(const account_name &first_auth, const fc::time_point &now) const
 
void subjective_bill(const transaction_id_type &id, const fc::time_point &expire, const account_name &first_auth, const fc::microseconds &elapsed, bool in_pending_block)
 
void subjective_bill_failure(const account_name &first_auth, const fc::microseconds &elapsed, const fc::time_point &now)
 
#define FC_LOG_MESSAGE(LOG_LEVEL, FORMAT,...)
A helper method for generating log messages.
 
std::shared_ptr< exception > exception_ptr
 
fc::logger _trx_trace_success_log
 
fc::logger _trx_trace_failure_log
 
fc::logger _trx_failed_trace_log
 
fc::logger _trx_successful_trace_log
 
void bt(const Operand &op, const Reg ®)