1231 { try {
1232
1235
1236 maybe_session undo_session;
1238 undo_session = maybe_session(
db);
1239
1240 auto gtrx = generated_transaction(gto);
1241
1242
1243
1244
1245
1246
1247
1249
1251
1254
1255 signed_transaction dtrx;
1260 trx->accepted = true;
1261
1264 trace = std::make_shared<transaction_trace>();
1265 trace->id = gtrx.trx_id;
1269 trace->scheduled = true;
1271 trace->account_ram_delta = account_delta( gtrx.payer, trx_removal_ram_delta );
1275 undo_session.squash();
1276 return trace;
1277 }
1278
1281 });
1283
1284 uint32_t cpu_time_to_bill_us = billed_cpu_time_us;
1285
1286 transaction_checktime_timer trx_timer(
timer);
1287 transaction_context trx_context(
self, *trx->packed_trx(), std::move(trx_timer) );
1289 trx_context.block_deadline = block_deadline;
1290 trx_context.max_transaction_time_subjective = max_transaction_time;
1291 trx_context.explicit_billed_cpu_time = explicit_billed_cpu_time;
1292 trx_context.billed_cpu_time_us = billed_cpu_time_us;
1294 trace = trx_context.trace;
1295
1296 auto handle_exception = [&](const auto& e)
1297 {
1300 trace->except = e;
1301 trace->except_ptr = std::current_exception();
1303
1305 dm_logger->on_fail_deferred();
1306 }
1307 };
1308
1309 try {
1310 trx_context.init_for_deferred_trx( gtrx.published );
1311
1313 flat_set<account_name> actors;
1314 for( const auto& act : trx->packed_trx()->get_transaction().actions ) {
1315 for( const auto& auth : act.authorization ) {
1316 actors.insert( auth.actor );
1317 }
1318 }
1320 }
1321
1322 trx_context.exec();
1323 trx_context.finalize();
1324
1326
1329 trx_context.billed_cpu_time_us,
1330 trace->net_usage );
1331
1333 std::move(trx_context.executed_action_receipt_digests) );
1334
1335 trace->account_ram_delta = account_delta( gtrx.payer, trx_removal_ram_delta );
1336
1340
1341 trx_context.squash();
1342 undo_session.squash();
1343
1344 restore.cancel();
1345
1346 return trace;
1347 } catch( const disallowed_transaction_extensions_bad_block_exception& ) {
1348 throw;
1349 } catch( const protocol_feature_bad_block_exception& ) {
1350 throw;
1351 } catch ( const std::bad_alloc& ) {
1352 throw;
1353 } catch ( const boost::interprocess::bad_alloc& ) {
1354 throw;
1356 handle_exception(e);
1357 } catch ( const std::exception& e) {
1359 handle_exception(wrapper);
1360 }
1361
1362 trx_context.undo();
1363
1364
1365
1367
1368
1369 auto error_trace =
apply_onerror( gtrx, block_deadline, max_transaction_time, trx_context.pseudo_start,
1370 cpu_time_to_bill_us, billed_cpu_time_us, explicit_billed_cpu_time,
1371 trx_context.enforce_whiteblacklist );
1372 error_trace->failed_dtrx_trace = trace;
1373 trace = error_trace;
1374 if( !trace->except_ptr ) {
1375 trace->account_ram_delta = account_delta( gtrx.payer, trx_removal_ram_delta );
1379 undo_session.squash();
1380 return trace;
1381 }
1383 }
1384
1385
1386
1387
1388 bool subjective = false;
1389 if (validating) {
1391 } else {
1393 }
1394
1395 if ( !subjective ) {
1396
1397
1398 if( !validating ) {
1401 int64_t account_cpu_limit = 0;
1402 std::tie( std::ignore, account_cpu_limit, std::ignore, std::ignore ) = trx_context.max_bandwidth_billed_accounts_can_pay( true );
1403
1405 std::min(
static_cast<int64_t>(cpu_time_to_bill_us), account_cpu_limit ),
1406 trx_context.initial_objective_duration_limit.count() ) );
1407 SYS_ASSERT( !explicit_billed_cpu_time || (cpu_time_to_bill_us == limited_cpu_time_to_bill_us),
1408 transaction_exception,
"cpu to bill ${cpu} != limited ${limit}", (
"cpu", cpu_time_to_bill_us)(
"limit", limited_cpu_time_to_bill_us) );
1409 cpu_time_to_bill_us = limited_cpu_time_to_bill_us;
1410 }
1411
1414
1416 trace->account_ram_delta = account_delta( gtrx.payer, trx_removal_ram_delta );
1417
1421
1422 undo_session.squash();
1423 } else {
1427 }
1428
1429 return trace;
signal< void(const transaction_metadata_ptr &)> accepted_transaction
bool is_producing_block() const
std::optional< block_id_type > pending_producer_block_id() const
@ incomplete
this is an incomplete block (either being produced by a producer or speculatively produced by a node)
signal< void(std::tuple< const transaction_trace_ptr &, const packed_transaction_ptr & >)> applied_transaction
bool skip_db_sessions() const
resource_limits_manager & get_mutable_resource_limits_manager()
void update_account_usage(const flat_set< account_name > &accounts, uint32_t ordinal)
void add_transaction_usage(const flat_set< account_name > &accounts, uint64_t cpu_usage, uint64_t net_usage, uint32_t ordinal)
static const Segment ds(Segment::ds)
int64_t remove_scheduled_transaction(const generated_transaction_object >o)
void dmlog_applied_transaction(const transaction_trace_ptr &t)
transaction_trace_ptr apply_onerror(const generated_transaction >rx, fc::time_point block_deadline, fc::microseconds max_transaction_time, fc::time_point start, uint32_t &cpu_time_to_bill_us, uint32_t billed_cpu_time_us, bool explicit_billed_cpu_time=false, bool enforce_whiteblacklist=true)
bool in_trx_requiring_checks
if true, checks that are normally skipped on replay (e.g. auth checks) cannot be skipped
bool scheduled_failure_is_subjective(const fc::exception &e) const
void check_actor_list(const flat_set< account_name > &actors) const
bool failure_is_subjective(const fc::exception &e) const
bool sender_avoids_whitelist_blacklist_enforcement(account_name sender) const