Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.2] Emit correct trace id for deferred trx before replace_deferred protocol feature activation #1379

Merged
merged 2 commits into from
Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1154,7 +1154,7 @@ struct controller_impl {

transaction_checktime_timer trx_timer(timer);
const packed_transaction trx( std::move( etrx ) );
transaction_context trx_context( self, trx, std::move(trx_timer), start );
transaction_context trx_context( self, trx, trx.id(), std::move(trx_timer), start );

trx_context.block_deadline = block_deadline;
trx_context.max_transaction_time_subjective = max_transaction_time;
Expand Down Expand Up @@ -1315,7 +1315,7 @@ struct controller_impl {
uint32_t cpu_time_to_bill_us = billed_cpu_time_us;

transaction_checktime_timer trx_timer(timer);
transaction_context trx_context( self, *trx->packed_trx(), std::move(trx_timer) );
transaction_context trx_context( self, *trx->packed_trx(), gtrx.trx_id, std::move(trx_timer) );
trx_context.leeway = fc::microseconds(0); // avoid stealing cpu resource
trx_context.block_deadline = block_deadline;
trx_context.max_transaction_time_subjective = max_transaction_time;
Expand Down Expand Up @@ -1528,7 +1528,7 @@ struct controller_impl {

const signed_transaction& trn = trx->packed_trx()->get_signed_transaction();
transaction_checktime_timer trx_timer(timer);
transaction_context trx_context(self, *trx->packed_trx(), std::move(trx_timer), start, trx->read_only);
transaction_context trx_context(self, *trx->packed_trx(), trx->id(), std::move(trx_timer), start, trx->read_only);
if ((bool)subjective_cpu_leeway && pending->_block_status == controller::block_status::incomplete) {
trx_context.leeway = *subjective_cpu_leeway;
}
Expand Down
2 changes: 2 additions & 0 deletions libraries/chain/include/eosio/chain/transaction_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ namespace eosio { namespace chain {

transaction_context( controller& c,
const packed_transaction& t,
const transaction_id_type& trx_id, // trx_id diff than t.id() before replace_deferred
transaction_checktime_timer&& timer,
fc::time_point start = fc::time_point::now(),
bool read_only=false);
Expand Down Expand Up @@ -121,6 +122,7 @@ namespace eosio { namespace chain {

controller& control;
const packed_transaction& packed_trx;
const transaction_id_type& id;
std::optional<chainbase::database::session> undo_session;
transaction_trace_ptr trace;
fc::time_point start;
Expand Down
8 changes: 5 additions & 3 deletions libraries/chain/transaction_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ namespace eosio { namespace chain {

transaction_context::transaction_context( controller& c,
const packed_transaction& t,
const transaction_id_type& trx_id,
transaction_checktime_timer&& tmr,
fc::time_point s,
bool read_only)
:control(c)
,packed_trx(t)
,id(trx_id)
,undo_session()
,trace(std::make_shared<transaction_trace>())
,start(s)
Expand All @@ -62,7 +64,7 @@ namespace eosio { namespace chain {
if (!c.skip_db_sessions()) {
undo_session.emplace(c.mutable_db().start_undo_session(true));
}
trace->id = packed_trx.id();
trace->id = id;
trace->block_num = c.head_block_num() + 1;
trace->block_time = c.pending_block_time();
trace->producer_block_id = c.pending_producer_block_id();
Expand Down Expand Up @@ -271,7 +273,7 @@ namespace eosio { namespace chain {
validate_referenced_accounts( trx, enforce_whiteblacklist && control.is_producing_block() );
}
init( initial_net_usage);
record_transaction( packed_trx.id(), trx.expiration ); /// checks for dupes
record_transaction( id, trx.expiration ); /// checks for dupes
}

void transaction_context::init_for_deferred_trx( fc::time_point p )
Expand Down Expand Up @@ -700,7 +702,7 @@ namespace eosio { namespace chain {

uint32_t trx_size = 0;
const auto& cgto = control.mutable_db().create<generated_transaction_object>( [&]( auto& gto ) {
gto.trx_id = packed_trx.id();
gto.trx_id = id;
gto.payer = first_auth;
gto.sender = account_name(); /// delayed transactions have no sender
gto.sender_id = transaction_id_to_sender_id( gto.trx_id );
Expand Down
17 changes: 17 additions & 0 deletions unittests/protocol_feature_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,14 @@ BOOST_AUTO_TEST_CASE( replace_deferred_test ) try {
cfg.disable_all_subjective_mitigations = true;
c.init( cfg );

transaction_trace_ptr trace;
auto h = c.control->applied_transaction.connect( [&](std::tuple<const transaction_trace_ptr&, const packed_transaction_ptr&> x) {
auto& t = std::get<0>(x);
if( t && !eosio::chain::is_onblock(*t)) {
trace = t;
}
} );

BOOST_CHECK_EQUAL( c.control->get_resource_limits_manager().get_account_ram_usage( "alice"_n ), alice_ram_usage0 );

c.push_action( "test"_n, "defercall"_n, "alice"_n, fc::mutable_variant_object()
Expand Down Expand Up @@ -448,6 +456,8 @@ BOOST_AUTO_TEST_CASE( replace_deferred_test ) try {

dtrxs = c.get_scheduled_transactions();
BOOST_CHECK_EQUAL( dtrxs.size(), 0 );
// must be equal before builtin_protocol_feature_t::replace_deferred to support replay of blocks before activation
BOOST_CHECK( first_dtrx_id.str() == trace->id.str() );

c.produce_block();

Expand Down Expand Up @@ -507,6 +517,13 @@ BOOST_AUTO_TEST_CASE( replace_deferred_test ) try {
BOOST_CHECK_EQUAL( dtrxs.size(), 1 );
BOOST_CHECK_EQUAL( first_dtrx_id2, dtrxs[0] );

c.produce_block();

dtrxs = c.get_scheduled_transactions();
BOOST_CHECK_EQUAL( dtrxs.size(), 0 );
// Not equal after builtin_protocol_feature_t::replace_deferred activated
BOOST_CHECK( first_dtrx_id2.str() != trace->id.str() );

} FC_LOG_AND_RETHROW()

BOOST_AUTO_TEST_CASE( no_duplicate_deferred_id_test ) try {
Expand Down