| 517 | } FC_CAPTURE_AND_RETHROW( (next_block.block_num()) ) } |
| 518 | |
| 519 | void database::notify_changed_objects() |
| 520 | { try { |
| 521 | if( _undo_db.enabled() ) |
| 522 | { |
| 523 | const auto& head_undo = _undo_db.head(); |
| 524 | vector<object_id_type> changed_ids; changed_ids.reserve(head_undo.old_values.size()); |
| 525 | for( const auto& item : head_undo.old_values ) changed_ids.push_back(item.first); |
| 526 | for( const auto& item : head_undo.new_ids ) changed_ids.push_back(item); |
| 527 | vector<const object*> removed; |
| 528 | removed.reserve( head_undo.removed.size() ); |
| 529 | for( const auto& item : head_undo.removed ) |
| 530 | { |
| 531 | changed_ids.push_back( item.first ); |
| 532 | removed.emplace_back( item.second.get() ); |
| 533 | } |
| 534 | changed_objects(changed_ids); |
| 535 | } |
| 536 | } FC_CAPTURE_AND_RETHROW() } |
| 537 | |
| 538 | processed_transaction database::apply_transaction(const signed_transaction& trx, uint32_t skip) |
| 539 | { |
| 540 | processed_transaction result; |
| 541 | detail::with_skip_flags( *this, skip, [&]() |
| 542 | { |
| 543 | result = _apply_transaction(trx); |
| 544 | }); |
| 545 | return result; |
| 546 | } |
| 547 | |
| 548 | processed_transaction database::_apply_transaction(const signed_transaction& trx) |
| 549 | { try { |
| 550 | uint32_t skip = get_node_properties().skip_flags; |
| 551 | trx.validate(); |
| 552 | auto& trx_idx = get_mutable_index_type<transaction_index>(); |
| 553 | const chain_id_type& chain_id = get_chain_id(); |
| 554 | auto trx_id = trx.id(); |
| 555 | FC_ASSERT( (skip & skip_transaction_dupe_check) || |
| 556 | trx_idx.indices().get<by_trx_id>().find(trx_id) == trx_idx.indices().get<by_trx_id>().end() ); |
| 557 | transaction_evaluation_state eval_state(this); |
| 558 | const chain_parameters& chain_parameters = get_global_properties().parameters; |
| 559 | eval_state._trx = &trx; |
| 560 | |
| 561 | if( !(skip & (skip_transaction_signatures | skip_authority_check) ) ) |
| 562 | { |
| 563 | auto get_active = [&]( account_id_type id ) { return &id(*this).active; }; |
| 564 | auto get_owner = [&]( account_id_type id ) { return &id(*this).owner; }; |
| 565 | trx.verify_authority( chain_id, get_active, get_owner, get_global_properties().parameters.max_authority_depth ); |
| 566 | } |
| 567 | |
| 568 | //Skip all manner of expiration and TaPoS checking if we're on block 1; It's impossible that the transaction is |
| 569 | //expired, and TaPoS makes no sense as no blocks exist. |
| 570 | if( BOOST_LIKELY(head_block_num() > 0) ) |
| 571 | { |
| 572 | if( !(skip & skip_tapos_check) ) |
| 573 | { |
| 574 | const auto& tapos_block_summary = block_summary_id_type( trx.ref_block_num )(*this); |
| 575 | |
| 576 | //Verify TaPoS block summary has correct ID prefix, and that this block's time is not past the expiration |