Skip to content

Commit f2e3344

Browse files
authored
Merge pull request #1036 from AntelopeIO/GH-1030-irreversible-mode-trx
Support speculative trx execution in irreversible mode
2 parents 7c54987 + 792f477 commit f2e3344

File tree

7 files changed

+30
-33
lines changed

7 files changed

+30
-33
lines changed

libraries/chain/controller.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -5325,7 +5325,6 @@ transaction_trace_ptr controller::push_transaction( const transaction_metadata_p
53255325
uint32_t billed_cpu_time_us, bool explicit_billed_cpu_time,
53265326
int64_t subjective_cpu_bill_us ) {
53275327
validate_db_available_size();
5328-
EOS_ASSERT( get_read_mode() != db_read_mode::IRREVERSIBLE, transaction_type_exception, "push transaction not allowed in irreversible mode" );
53295328
EOS_ASSERT( trx && !trx->implicit() && !trx->scheduled(), transaction_type_exception, "Implicit/Scheduled transaction not allowed" );
53305329
return my->push_transaction(trx, block_deadline, max_transaction_time, billed_cpu_time_us, explicit_billed_cpu_time, subjective_cpu_bill_us );
53315330
}
@@ -5334,7 +5333,6 @@ transaction_trace_ptr controller::push_scheduled_transaction( const transaction_
53345333
fc::time_point block_deadline, fc::microseconds max_transaction_time,
53355334
uint32_t billed_cpu_time_us, bool explicit_billed_cpu_time )
53365335
{
5337-
EOS_ASSERT( get_read_mode() != db_read_mode::IRREVERSIBLE, transaction_type_exception, "push scheduled transaction not allowed in irreversible mode" );
53385336
validate_db_available_size();
53395337
return my->push_scheduled_transaction( trxid, block_deadline, max_transaction_time, billed_cpu_time_us, explicit_billed_cpu_time );
53405338
}

libraries/chain/fork_database.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,11 @@ namespace eosio::chain {
192192

193193
template<class BSP>
194194
void fork_database_impl<BSP>::reset_root_impl( const bsp_t& root_bsp ) {
195-
index.clear();
196195
assert(root_bsp);
197196
root = root_bsp;
198197
root->set_valid(true);
198+
pending_savanna_lib_id = block_id_type{};
199+
index.clear();
199200
}
200201

201202
template<class BSP>

plugins/chain_plugin/chain_plugin.cpp

-8
Original file line numberDiff line numberDiff line change
@@ -942,12 +942,6 @@ void chain_plugin_impl::plugin_initialize(const variables_map& options) {
942942
}
943943
api_accept_transactions = options.at( "api-accept-transactions" ).as<bool>();
944944

945-
if( chain_config->read_mode == db_read_mode::IRREVERSIBLE ) {
946-
if( api_accept_transactions ) {
947-
api_accept_transactions = false;
948-
wlog( "api-accept-transactions set to false due to read-mode: irreversible" );
949-
}
950-
}
951945
if( api_accept_transactions ) {
952946
enable_accept_transactions();
953947
}
@@ -1138,8 +1132,6 @@ void chain_plugin::plugin_initialize(const variables_map& options) {
11381132

11391133
void chain_plugin_impl::plugin_startup()
11401134
{ try {
1141-
EOS_ASSERT( chain_config->read_mode != db_read_mode::IRREVERSIBLE || !accept_transactions, plugin_config_exception,
1142-
"read-mode = irreversible. transactions should not be enabled by enable_accept_transactions" );
11431135
try {
11441136
auto shutdown = [](){ return app().quit(); };
11451137
auto check_shutdown = [](){ return app().is_quiting(); };

plugins/net_plugin/net_plugin.cpp

-7
Original file line numberDiff line numberDiff line change
@@ -4277,14 +4277,7 @@ namespace eosio {
42774277

42784278
chain_id = chain_plug->get_chain_id();
42794279
fc::rand_pseudo_bytes( node_id.data(), node_id.data_size());
4280-
const controller& cc = chain_plug->chain();
42814280

4282-
if( cc.get_read_mode() == db_read_mode::IRREVERSIBLE ) {
4283-
if( p2p_accept_transactions ) {
4284-
p2p_accept_transactions = false;
4285-
fc_wlog( logger, "p2p-accept-transactions set to false due to read-mode: irreversible" );
4286-
}
4287-
}
42884281
if( p2p_accept_transactions ) {
42894282
chain_plug->enable_accept_transactions();
42904283
}

plugins/producer_plugin/producer_plugin.cpp

+19-5
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,7 @@ class producer_plugin_impl : public std::enable_shared_from_this<producer_plugin
687687
std::map<chain::public_key_type, signature_provider_type> _signature_providers;
688688
chain::bls_pub_priv_key_map_t _finalizer_keys; // public, private
689689
std::set<chain::account_name> _producers;
690+
chain::db_read_mode _db_read_mode = db_read_mode::HEAD;
690691
boost::asio::deadline_timer _timer;
691692
block_timing_util::producer_watermarks _producer_watermarks;
692693
pending_block_mode _pending_block_mode = pending_block_mode::speculating;
@@ -833,6 +834,10 @@ class producer_plugin_impl : public std::enable_shared_from_this<producer_plugin
833834
return !_producers.empty();
834835
}
835836

837+
bool irreversible_mode() const {
838+
return _db_read_mode == db_read_mode::IRREVERSIBLE;
839+
}
840+
836841
void on_accepted_block(const signed_block_ptr& block, const block_id_type& id) {
837842
auto& chain = chain_plug->chain();
838843
auto before = _unapplied_transactions.size();
@@ -1532,10 +1537,12 @@ void producer_plugin_impl::plugin_startup() {
15321537
dlog("producer plugin: plugin_startup() begin");
15331538

15341539
chain::controller& chain = chain_plug->chain();
1535-
EOS_ASSERT(!is_configured_producer() || chain.get_read_mode() != chain::db_read_mode::IRREVERSIBLE, plugin_config_exception,
1540+
_db_read_mode = chain.get_read_mode();
1541+
1542+
EOS_ASSERT(!is_configured_producer() || !irreversible_mode(), plugin_config_exception,
15361543
"node cannot have any producer-name configured because block production is impossible when read_mode is \"irreversible\"");
15371544

1538-
EOS_ASSERT(_finalizer_keys.empty() || chain.get_read_mode() != chain::db_read_mode::IRREVERSIBLE, plugin_config_exception,
1545+
EOS_ASSERT(_finalizer_keys.empty() || !irreversible_mode(), plugin_config_exception,
15391546
"node cannot have any finalizers configured because finalization is impossible when read_mode is \"irreversible\"");
15401547

15411548
EOS_ASSERT(!is_configured_producer() || chain.get_validation_mode() == chain::validation_mode::FULL, plugin_config_exception,
@@ -1587,6 +1594,10 @@ void producer_plugin_impl::plugin_startup() {
15871594
_irreversible_block_time = fc::time_point::maximum();
15881595
}
15891596

1597+
if (!_is_savanna_active && irreversible_mode() && chain_plug->accept_transactions()) {
1598+
wlog("Legacy consensus active. Accepting speculative transaction execution not recommended in read-mode=irreversible");
1599+
}
1600+
15901601
if (is_configured_producer()) {
15911602
ilog("Launching block production for ${n} producers at ${time}.", ("n", _producers.size())("time", fc::time_point::now()));
15921603

@@ -1978,8 +1989,11 @@ bool producer_plugin_impl::should_interrupt_start_block(const fc::time_point& de
19781989
if (in_producing_mode()) {
19791990
return deadline <= fc::time_point::now();
19801991
}
1981-
// if we can produce then honor deadline so production starts on time
1982-
return (is_configured_producer() && deadline <= fc::time_point::now()) || (_received_block >= pending_block_num);
1992+
// if we can produce then honor deadline so production starts on time.
1993+
// if in irreversible mode then a received block should not interrupt since the incoming block is not processed until
1994+
// it becomes irreversible. We could check if LIB changed, but doesn't seem like the extra complexity is worth it.
1995+
return (is_configured_producer() && deadline <= fc::time_point::now())
1996+
|| (!irreversible_mode() && _received_block >= pending_block_num);
19831997
}
19841998

19851999
producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {
@@ -2081,7 +2095,7 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {
20812095
// Determine if we are syncing: if we have recently started an old block then assume we are syncing
20822096
if (last_start_block_time < now + fc::microseconds(config::block_interval_us)) {
20832097
auto head_block_age = now - chain.head().block_time();
2084-
if (head_block_age > fc::seconds(5))
2098+
if (head_block_age > fc::minutes(5))
20852099
return start_block_result::waiting_for_block; // if syncing no need to create a block just to immediately abort it
20862100
}
20872101
last_start_block_time = now;

tests/CMakeLists.txt

-2
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,6 @@ set_property(TEST get_account_test PROPERTY LABELS nonparallelizable_tests)
228228

229229
add_test(NAME distributed-transactions-test COMMAND tests/distributed-transactions-test.py -d 2 -p 4 -n 6 -v ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
230230
set_property(TEST distributed-transactions-test PROPERTY LABELS nonparallelizable_tests)
231-
add_test(NAME distributed-transactions-speculative-test COMMAND tests/distributed-transactions-test.py -d 2 -p 4 -n 6 --speculative -v ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
232-
set_property(TEST distributed-transactions-speculative-test PROPERTY LABELS nonparallelizable_tests)
233231
add_test(NAME distributed-transactions-if-test COMMAND tests/distributed-transactions-test.py -d 2 -p 4 -n 6 --activate-if -v ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
234232
set_property(TEST distributed-transactions-if-test PROPERTY LABELS nonparallelizable_tests)
235233
add_test(NAME restart-scenarios-test-resync COMMAND tests/restart-scenarios-test.py -c resync -p4 -v ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})

tests/distributed-transactions-test.py

+9-8
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# Performs currency transfers between N accounts sent to http endpoints of
1313
# N nodes and verifies, after a steady state is reached, that the accounts
1414
# balances are correct
15-
# if called with --nodes-file it will will load a json description of nodes
15+
# if called with --nodes-file it will load a json description of nodes
1616
# that are already running and run distributed test against them (not
1717
# currently testing this feature)
1818
#
@@ -22,20 +22,19 @@
2222
errorExit=Utils.errorExit
2323

2424
appArgs = AppArgs()
25-
extraArgs = appArgs.add_bool(flag="--speculative", help="Run nodes in read-mode=speculative")
26-
args=TestHelper.parse_args({"-p","-n","-d","-s","--nodes-file","--seed", "--speculative", "--activate-if"
25+
args=TestHelper.parse_args({"-p","-n","-d","-s","--nodes-file","--seed", "--activate-if"
2726
,"--dump-error-details","-v","--leave-running","--keep-logs","--unshared"}, applicationSpecificArgs=appArgs)
2827

2928
pnodes=args.p
3029
topo=args.s
3130
delay=args.d
3231
total_nodes = pnodes if args.n < pnodes else args.n
32+
total_nodes = total_nodes if total_nodes > pnodes + 3 else pnodes + 3
3333
debug=args.v
3434
nodesFile=args.nodes_file
3535
dontLaunch=nodesFile is not None
3636
seed=args.seed
3737
dumpErrorDetails=args.dump_error_details
38-
speculative=args.speculative
3938
activateIF=args.activate_if
4039

4140
Utils.Debug=debug
@@ -64,11 +63,13 @@
6463
(pnodes, total_nodes-pnodes, topo, delay))
6564

6665
Print("Stand up cluster")
67-
extraNodeosArgs = ""
68-
if speculative:
69-
extraNodeosArgs = " --read-mode speculative "
66+
specificExtraNodeosArgs = {}
67+
specificExtraNodeosArgs[total_nodes-1] = f' --read-mode head '
68+
if activateIF: # irreversible mode speculative trx execution not recommended in legacy mode
69+
specificExtraNodeosArgs[total_nodes-2] = f' --read-mode irreversible '
70+
specificExtraNodeosArgs[total_nodes-3] = f' --read-mode speculative '
7071

71-
if cluster.launch(pnodes=pnodes, totalNodes=total_nodes, topo=topo, delay=delay, extraNodeosArgs=extraNodeosArgs, activateIF=activateIF) is False:
72+
if cluster.launch(pnodes=pnodes, totalNodes=total_nodes, topo=topo, delay=delay, specificExtraNodeosArgs=specificExtraNodeosArgs, activateIF=activateIF) is False:
7273
errorExit("Failed to stand up eos cluster.")
7374

7475
Print ("Wait for Cluster stabilization")

0 commit comments

Comments
 (0)