@@ -80,8 +80,6 @@ using transaction_id_with_expiry_index = multi_index_container<
80
80
>
81
81
>;
82
82
83
-
84
-
85
83
enum class pending_block_mode {
86
84
producing,
87
85
speculating
@@ -878,6 +876,13 @@ fc::time_point producer_plugin_impl::calculate_pending_block_time() const {
878
876
return block_time;
879
877
}
880
878
879
+ enum class tx_category {
880
+ PERSISTED,
881
+ UNEXPIRED_UNPERSISTED,
882
+ EXPIRED,
883
+ };
884
+
885
+
881
886
producer_plugin_impl::start_block_result producer_plugin_impl::start_block (bool &last_block) {
882
887
chain::controller& chain = app ().get_plugin <chain_plugin>().chain ();
883
888
@@ -978,71 +983,66 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block(bool
978
983
try {
979
984
size_t orig_pending_txn_size = _pending_incoming_transactions.size ();
980
985
981
- if (!persisted_by_expiry.empty () || _pending_block_mode == pending_block_mode::producing) {
982
- auto unapplied_trxs = chain.get_unapplied_transactions ();
983
-
984
- if (!persisted_by_expiry.empty ()) {
985
- for (auto itr = unapplied_trxs.begin (); itr != unapplied_trxs.end (); ++itr) {
986
- const auto & trx = *itr;
987
- if (persisted_by_id.find (trx->id ) != persisted_by_id.end ()) {
988
- // this is a persisted transaction, push it into the block (even if we are speculating) with
989
- // no deadline as it has already passed the subjective deadlines once and we want to represent
990
- // the state of the chain including this transaction
991
- try {
992
- chain.push_transaction (trx, fc::time_point::maximum ());
993
- } catch ( const guard_exception& e ) {
994
- app ().get_plugin <chain_plugin>().handle_guard_exception (e);
995
- return start_block_result::failed;
996
- } FC_LOG_AND_DROP ();
997
-
998
- // remove it from further consideration as it is applied
999
- *itr = nullptr ;
1000
- }
1001
- }
1002
- }
1003
-
1004
- if (_pending_block_mode == pending_block_mode::producing) {
1005
- for (const auto & trx : unapplied_trxs) {
1006
- if (block_time <= fc::time_point::now ()) exhausted = true ;
1007
- if (exhausted) {
1008
- break ;
1009
- }
986
+ // Processing unapplied transactions...
987
+ //
988
+ if (_producers.empty () && persisted_by_id.empty ()) {
989
+ // if this node can never produce and has no persisted transactions,
990
+ // there is no need for unapplied transactions they can be dropped
991
+ chain.drop_all_unapplied_transactions ();
992
+ } else {
993
+ std::vector<transaction_metadata_ptr> apply_trxs;
994
+ { // derive appliable transactions from unapplied_transactions and drop droppable transactions
995
+ auto unapplied_trxs = chain.get_unapplied_transactions ();
996
+ apply_trxs.reserve (unapplied_trxs.size ());
1010
997
1011
- if (!trx) {
1012
- // nulled in the loop above, skip it
1013
- continue ;
998
+ auto calculate_transaction_category = [&](const transaction_metadata_ptr& trx) {
999
+ if (trx->packed_trx .expiration () < pbs->header .timestamp .to_time_point ()) {
1000
+ return tx_category::EXPIRED;
1001
+ } else if (persisted_by_id.find (trx->id ) != persisted_by_id.end ()) {
1002
+ return tx_category::PERSISTED;
1003
+ } else {
1004
+ return tx_category::UNEXPIRED_UNPERSISTED;
1014
1005
}
1006
+ };
1015
1007
1016
- if (trx->packed_trx .expiration () < pbs->header .timestamp .to_time_point ()) {
1017
- // expired, drop it
1008
+ for (auto & trx: unapplied_trxs) {
1009
+ auto category = calculate_transaction_category (trx);
1010
+ if (category == tx_category::EXPIRED || (category == tx_category::UNEXPIRED_UNPERSISTED && _producers.empty ())) {
1018
1011
chain.drop_unapplied_transaction (trx);
1019
- continue ;
1012
+ } else if (category == tx_category::PERSISTED || (category == tx_category::UNEXPIRED_UNPERSISTED && _pending_block_mode == pending_block_mode::producing)) {
1013
+ apply_trxs.emplace_back (std::move (trx));
1020
1014
}
1015
+ }
1016
+ }
1021
1017
1022
- try {
1023
- auto deadline = fc::time_point::now () + fc::milliseconds (_max_transaction_time_ms);
1024
- bool deadline_is_subjective = false ;
1025
- if (_max_transaction_time_ms < 0 || (_pending_block_mode == pending_block_mode::producing && block_time < deadline)) {
1026
- deadline_is_subjective = true ;
1027
- deadline = block_time;
1028
- }
1018
+ for (const auto & trx: apply_trxs) {
1019
+ if (block_time <= fc::time_point::now ()) exhausted = true ;
1020
+ if (exhausted) {
1021
+ break ;
1022
+ }
1029
1023
1030
- auto trace = chain.push_transaction (trx, deadline);
1031
- if (trace->except ) {
1032
- if (failure_is_subjective (*trace->except , deadline_is_subjective)) {
1033
- exhausted = true ;
1034
- } else {
1035
- // this failed our configured maximum transaction time, we don't want to replay it
1036
- chain.drop_unapplied_transaction (trx);
1037
- }
1024
+ try {
1025
+ auto deadline = fc::time_point::now () + fc::milliseconds (_max_transaction_time_ms);
1026
+ bool deadline_is_subjective = false ;
1027
+ if (_max_transaction_time_ms < 0 || (_pending_block_mode == pending_block_mode::producing && block_time < deadline)) {
1028
+ deadline_is_subjective = true ;
1029
+ deadline = block_time;
1030
+ }
1031
+
1032
+ auto trace = chain.push_transaction (trx, deadline);
1033
+ if (trace->except ) {
1034
+ if (failure_is_subjective (*trace->except , deadline_is_subjective)) {
1035
+ exhausted = true ;
1036
+ } else {
1037
+ // this failed our configured maximum transaction time, we don't want to replay it
1038
+ chain.drop_unapplied_transaction (trx);
1038
1039
}
1039
- } catch ( const guard_exception& e ) {
1040
- app (). get_plugin <chain_plugin>(). handle_guard_exception (e);
1041
- return start_block_result::failed ;
1042
- } FC_LOG_AND_DROP () ;
1043
- }
1040
+ }
1041
+ } catch ( const guard_exception& e ) {
1042
+ app (). get_plugin <chain_plugin>(). handle_guard_exception (e) ;
1043
+ return start_block_result::failed ;
1044
+ } FC_LOG_AND_DROP ();
1044
1045
}
1045
-
1046
1046
}
1047
1047
1048
1048
if (_pending_block_mode == pending_block_mode::producing) {
0 commit comments