Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 32daed0840 | |||
| 6d9dff6713 | |||
| f07e688305 | |||
| 44b56b38ca | |||
| c600fbe0b8 | |||
| 07af448870 | |||
| fb21cdecb0 | |||
| b3cc74f621 | |||
| 8d86d7d2d4 | |||
| 59cf021b08 | |||
| 5969e8b6fe | |||
| 8cbd7decca | |||
| c9fcb2ac2c | |||
| b5232f0eaf | |||
| ac1a035b5e | |||
| 2597e02383 | |||
| 191aafc8f6 | |||
| 405ac4178d | |||
| 41bb796d77 | |||
| 1e80205270 | |||
| 483b462717 | |||
| ec471ad8e5 | |||
| 3dbc0baeeb | |||
| f3c424ef90 | |||
| 971102e243 | |||
| 0ed5d6da9e | |||
| 38d3c39e9d |
+1
-1
@@ -16,7 +16,7 @@ set( CXX_STANDARD_REQUIRED ON)
|
||||
set(VERSION_MAJOR 4)
|
||||
set(VERSION_MINOR 0)
|
||||
set(VERSION_PATCH 0)
|
||||
set(VERSION_SUFFIX rc1)
|
||||
set(VERSION_SUFFIX rc2)
|
||||
|
||||
if(VERSION_SUFFIX)
|
||||
set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}")
|
||||
|
||||
@@ -2680,7 +2680,7 @@ struct controller_impl {
|
||||
// only called from non-main threads (read-only trx execution threads)
|
||||
// when producer_plugin starts them
|
||||
void init_thread_local_data() {
|
||||
EOS_ASSERT( !is_main_thread(), misc_exception, "init_thread_local_data called on the main thread");
|
||||
EOS_ASSERT( !is_on_main_thread(), misc_exception, "init_thread_local_data called on the main thread");
|
||||
#ifdef EOSIO_EOS_VM_OC_RUNTIME_ENABLED
|
||||
if ( is_eos_vm_oc_enabled() )
|
||||
// EOSVMOC needs further initialization of its thread local data
|
||||
@@ -2691,10 +2691,10 @@ struct controller_impl {
|
||||
wasmif_thread_local = std::make_unique<wasm_interface>( conf.wasm_runtime, conf.eosvmoc_tierup, db, conf.state_dir, conf.eosvmoc_config, !conf.profile_accounts.empty());
|
||||
}
|
||||
|
||||
bool is_main_thread() { return main_thread_id == std::this_thread::get_id(); };
|
||||
bool is_on_main_thread() { return main_thread_id == std::this_thread::get_id(); };
|
||||
|
||||
wasm_interface& get_wasm_interface() {
|
||||
if ( is_main_thread()
|
||||
if ( is_on_main_thread()
|
||||
#ifdef EOSIO_EOS_VM_OC_RUNTIME_ENABLED
|
||||
|| is_eos_vm_oc_enabled()
|
||||
#endif
|
||||
@@ -3686,6 +3686,10 @@ void controller::init_thread_local_data() {
|
||||
my->init_thread_local_data();
|
||||
}
|
||||
|
||||
bool controller::is_on_main_thread() const {
|
||||
return my->is_on_main_thread();
|
||||
}
|
||||
|
||||
/// Protocol feature activation handlers:
|
||||
|
||||
template<>
|
||||
|
||||
@@ -373,6 +373,7 @@ namespace eosio { namespace chain {
|
||||
void set_db_read_only_mode();
|
||||
void unset_db_read_only_mode();
|
||||
void init_thread_local_data();
|
||||
bool is_on_main_thread() const;
|
||||
|
||||
private:
|
||||
friend class apply_context;
|
||||
|
||||
@@ -2374,6 +2374,7 @@ read_only::get_raw_abi_results read_only::get_raw_abi( const get_raw_abi_params&
|
||||
}
|
||||
|
||||
read_only::get_account_results read_only::get_account( const get_account_params& params, const fc::time_point& deadline )const {
|
||||
try {
|
||||
get_account_results result;
|
||||
result.account_name = params.account_name;
|
||||
|
||||
@@ -2541,6 +2542,7 @@ read_only::get_account_results read_only::get_account( const get_account_params&
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} EOS_RETHROW_EXCEPTIONS(chain::account_query_exception, "unable to retrieve account info")
|
||||
}
|
||||
|
||||
read_only::get_required_keys_result read_only::get_required_keys( const get_required_keys_params& params, const fc::time_point& deadline )const {
|
||||
|
||||
@@ -403,13 +403,13 @@ namespace eosio {
|
||||
fc_elog( logger(), "Unable to parse arguments to ${api}.${call}", ("api", api_name)( "call", call_name ) );
|
||||
fc_dlog( logger(), "Bad arguments: ${args}", ("args", body) );
|
||||
} catch (fc::exception& e) {
|
||||
error_results results{500, "Internal Service Error", error_results::error_info(e, verbose_http_errors)};
|
||||
cb( 500, fc::time_point::maximum(), fc::variant( results ));
|
||||
error_results results{400, "Exception", error_results::error_info(e, verbose_http_errors)};
|
||||
cb( 400, fc::time_point::maximum(), fc::variant( results ));
|
||||
fc_dlog( logger(), "Exception while processing ${api}.${call}: ${e}",
|
||||
("api", api_name)( "call", call_name )("e", e.to_detail_string()) );
|
||||
} catch (std::exception& e) {
|
||||
error_results results{500, "Internal Service Error", error_results::error_info(fc::exception( FC_LOG_MESSAGE( error, e.what())), verbose_http_errors)};
|
||||
cb( 500, fc::time_point::maximum(), fc::variant( results ));
|
||||
error_results results{400, "Exception", error_results::error_info(fc::exception( FC_LOG_MESSAGE( error, e.what())), verbose_http_errors)};
|
||||
cb( 400, fc::time_point::maximum(), fc::variant( results ));
|
||||
fc_dlog( logger(), "STD Exception encountered while processing ${api}.${call}: ${e}",
|
||||
("api", api_name)("call", call_name)("e", e.what()) );
|
||||
} catch (...) {
|
||||
|
||||
@@ -256,39 +256,53 @@ struct block_time_tracker {
|
||||
block_idle_time += idle;
|
||||
}
|
||||
|
||||
void add_fail_time( const fc::microseconds& fail_time ) {
|
||||
trx_fail_time += fail_time;
|
||||
++trx_fail_num;
|
||||
void add_fail_time( const fc::microseconds& fail_time, bool is_transient ) {
|
||||
if( is_transient ) {
|
||||
// transient time includes both success and fail time
|
||||
transient_trx_time += fail_time;
|
||||
++transient_trx_num;
|
||||
} else {
|
||||
trx_fail_time += fail_time;
|
||||
++trx_fail_num;
|
||||
}
|
||||
}
|
||||
|
||||
void add_success_time( const fc::microseconds& time ) {
|
||||
trx_success_time += time;
|
||||
++trx_success_num;
|
||||
void add_success_time( const fc::microseconds& time, bool is_transient ) {
|
||||
if( is_transient ) {
|
||||
transient_trx_time += time;
|
||||
++transient_trx_num;
|
||||
} else {
|
||||
trx_success_time += time;
|
||||
++trx_success_num;
|
||||
}
|
||||
}
|
||||
|
||||
void report( const fc::time_point& idle_trx_time, uint32_t block_num ) {
|
||||
if( _log.is_enabled( fc::log_level::debug ) ) {
|
||||
auto now = fc::time_point::now();
|
||||
add_idle_time( now - idle_trx_time );
|
||||
fc_dlog( _log, "Block #${n} trx idle: ${i}us out of ${t}us, success: ${sn}, ${s}us, fail: ${fn}, ${f}us, other: ${o}us",
|
||||
fc_dlog( _log, "Block #${n} trx idle: ${i}us out of ${t}us, success: ${sn}, ${s}us, fail: ${fn}, ${f}us, transient: ${tn}, ${t}us, other: ${o}us",
|
||||
("n", block_num)
|
||||
("i", block_idle_time)("t", now - clear_time)("sn", trx_success_num)("s", trx_success_time)
|
||||
("fn", trx_fail_num)("f", trx_fail_time)
|
||||
("o", (now - clear_time) - block_idle_time - trx_success_time - trx_fail_time) );
|
||||
("tn", transient_trx_num)("t", transient_trx_time)
|
||||
("o", (now - clear_time) - block_idle_time - trx_success_time - trx_fail_time - transient_trx_time) );
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
block_idle_time = trx_fail_time = trx_success_time = fc::microseconds{};
|
||||
trx_fail_num = trx_success_num = 0;
|
||||
block_idle_time = trx_fail_time = trx_success_time = transient_trx_time = fc::microseconds{};
|
||||
trx_fail_num = trx_success_num = transient_trx_num = 0;
|
||||
clear_time = fc::time_point::now();
|
||||
}
|
||||
|
||||
fc::microseconds block_idle_time;
|
||||
uint32_t trx_success_num = 0;
|
||||
uint32_t trx_fail_num = 0;
|
||||
uint32_t transient_trx_num = 0;
|
||||
fc::microseconds trx_success_time;
|
||||
fc::microseconds trx_fail_time;
|
||||
fc::microseconds transient_trx_time;
|
||||
fc::time_point clear_time{fc::time_point::now()};
|
||||
};
|
||||
|
||||
@@ -429,11 +443,13 @@ class producer_plugin_impl : public std::enable_shared_from_this<producer_plugin
|
||||
fc::microseconds _ro_read_window_time_us{ 60000 };
|
||||
static constexpr fc::microseconds _ro_read_window_minimum_time_us{ 10000 };
|
||||
fc::microseconds _ro_read_window_effective_time_us{ 0 }; // calculated during option initialization
|
||||
std::atomic<int64_t> _ro_all_threads_exec_time_us; // total time spent by all threads executing transactions. use atomic for simplicity and performance
|
||||
fc::time_point _ro_read_window_start_time;
|
||||
boost::asio::deadline_timer _ro_write_window_timer;
|
||||
boost::asio::deadline_timer _ro_read_window_timer;
|
||||
fc::microseconds _ro_max_trx_time_us{ 0 }; // calculated during option initialization
|
||||
ro_trx_queue_t _ro_trx_queue;
|
||||
std::atomic<uint32_t> _ro_num_active_trx_exec_tasks{ 0 };
|
||||
std::atomic<uint32_t> _ro_num_active_trx_exec_tasks{ 0 };
|
||||
std::vector<std::future<bool>> _ro_trx_exec_tasks_fut;
|
||||
|
||||
void start_write_window();
|
||||
@@ -688,7 +704,8 @@ class producer_plugin_impl : public std::enable_shared_from_this<producer_plugin
|
||||
self->log_trx_results( trx, nullptr, ex, 0, start, is_transient );
|
||||
next( std::move(ex) );
|
||||
self->_idle_trx_time = fc::time_point::now();
|
||||
self->_time_tracker.add_fail_time(self->_idle_trx_time - start);
|
||||
auto dur = self->_idle_trx_time - start;
|
||||
self->_time_tracker.add_fail_time(dur, is_transient);
|
||||
};
|
||||
try {
|
||||
auto result = future.get();
|
||||
@@ -2214,7 +2231,7 @@ producer_plugin_impl::push_transaction( const fc::time_point& block_deadline,
|
||||
log_trx_results( trx, except_ptr );
|
||||
next( except_ptr );
|
||||
}
|
||||
_time_tracker.add_fail_time(fc::time_point::now() - start);
|
||||
_time_tracker.add_fail_time(fc::time_point::now() - start, trx->is_transient());
|
||||
return push_result{.failed = true};
|
||||
}
|
||||
|
||||
@@ -2261,8 +2278,10 @@ producer_plugin_impl::handle_push_result( const transaction_metadata_ptr& trx,
|
||||
auto end = fc::time_point::now();
|
||||
push_result pr;
|
||||
if( trace->except ) {
|
||||
if ( !trx->is_read_only() )
|
||||
_time_tracker.add_fail_time(end - start);
|
||||
if ( chain.is_on_main_thread() ) {
|
||||
auto dur = end - start;
|
||||
_time_tracker.add_fail_time(dur, trx->is_transient());
|
||||
}
|
||||
if( exception_is_exhausted( *trace->except ) ) {
|
||||
if( _pending_block_mode == pending_block_mode::producing ) {
|
||||
fc_dlog(_trx_failed_trace_log, "[TRX_TRACE] Block ${block_num} for producer ${prod} COULD NOT FIT, tx: ${txid} RETRYING ",
|
||||
@@ -2302,8 +2321,10 @@ producer_plugin_impl::handle_push_result( const transaction_metadata_ptr& trx,
|
||||
} else {
|
||||
fc_tlog( _log, "Subjective bill for success ${a}: ${b} elapsed ${t}us, time ${r}us",
|
||||
("a",first_auth)("b",sub_bill)("t",trace->elapsed)("r", end - start));
|
||||
if ( !trx->is_read_only() )
|
||||
_time_tracker.add_success_time(end - start);
|
||||
if ( chain.is_on_main_thread() ) {
|
||||
auto dur = end - start;
|
||||
_time_tracker.add_success_time(dur, trx->is_transient());
|
||||
}
|
||||
log_trx_results( trx, trace, start );
|
||||
// if producing then trx is in objective cpu account billing
|
||||
if (!disable_subjective_enforcement && _pending_block_mode != pending_block_mode::producing) {
|
||||
@@ -2446,7 +2467,7 @@ void producer_plugin_impl::process_scheduled_and_incoming_trxs( const fc::time_p
|
||||
auto trace = chain.push_scheduled_transaction(trx_id, deadline, max_trx_time, 0, false);
|
||||
auto end = fc::time_point::now();
|
||||
if (trace->except) {
|
||||
_time_tracker.add_fail_time(end - start);
|
||||
_time_tracker.add_fail_time(end - start, false); // delayed transaction cannot be transient
|
||||
if (exception_is_exhausted(*trace->except)) {
|
||||
if( block_is_exhausted() ) {
|
||||
exhausted = true;
|
||||
@@ -2466,7 +2487,7 @@ void producer_plugin_impl::process_scheduled_and_incoming_trxs( const fc::time_p
|
||||
num_failed++;
|
||||
}
|
||||
} else {
|
||||
_time_tracker.add_success_time(end - start);
|
||||
_time_tracker.add_success_time(end - start, false); // delayed transaction cannot be transient
|
||||
fc_dlog(_trx_successful_trace_log,
|
||||
"[TRX_TRACE] Block ${block_num} for producer ${prod} is ACCEPTING scheduled tx: ${txid}, time: ${r}, auth: ${a}, cpu: ${cpu}",
|
||||
("block_num", chain.head_block_num() + 1)("prod", get_pending_block_producer())
|
||||
@@ -2766,6 +2787,14 @@ void producer_plugin::log_failed_transaction(const transaction_id_type& trx_id,
|
||||
|
||||
// Called from app thread
|
||||
void producer_plugin_impl::switch_to_write_window() {
|
||||
if ( _log.is_enabled( fc::log_level::debug ) ) {
|
||||
auto now = fc::time_point::now();
|
||||
fc_dlog( _log, "Read-only threads ${n}, read window ${r}us, total all threads ${t}us",
|
||||
("n", _ro_thread_pool_size)
|
||||
("r", now - _ro_read_window_start_time)
|
||||
("t", _ro_all_threads_exec_time_us.load()));
|
||||
}
|
||||
|
||||
// this method can be called from multiple places. it is possible
|
||||
// we are already in write window.
|
||||
if ( app().executor().is_write_window() ) {
|
||||
@@ -2819,6 +2848,8 @@ void producer_plugin_impl::switch_to_read_window() {
|
||||
app().executor().set_to_read_window();
|
||||
chain_plug->chain().set_db_read_only_mode();
|
||||
_received_block = false;
|
||||
_ro_read_window_start_time = fc::time_point::now();
|
||||
_ro_all_threads_exec_time_us = 0;
|
||||
|
||||
// start a read-only transaction execution task in each thread in the thread pool
|
||||
_ro_num_active_trx_exec_tasks = _ro_thread_pool_size;
|
||||
@@ -2933,7 +2964,12 @@ bool producer_plugin_impl::push_read_only_transaction(
|
||||
auto remaining_time_in_read_window_us = _ro_read_window_time_us - time_used_in_read_window_us;
|
||||
// Ensure the trx to finish by the end of read-window.
|
||||
auto window_deadline = std::min( start + remaining_time_in_read_window_us, block_deadline );
|
||||
|
||||
auto trace = chain.push_transaction( trx, window_deadline, _ro_max_trx_time_us, 0, false, 0 );
|
||||
if ( _log.is_enabled( fc::log_level::debug ) ) {
|
||||
auto dur = fc::time_point::now() - start;
|
||||
_ro_all_threads_exec_time_us += dur.count();
|
||||
}
|
||||
auto pr = handle_push_result(trx, next, start, chain, trace, true /*return_failure_trace*/, true /*disable_subjective_enforcement*/, {} /*first_auth*/, 0 /*sub_bill*/, 0 /*prev_billed_cpu_time_us*/);
|
||||
// If a transaction was exhausted, that indicates we are close to
|
||||
// the end of read window. Retry in next round.
|
||||
|
||||
@@ -103,7 +103,7 @@ public:
|
||||
void pop_entry(bool call_send = true) {
|
||||
send_queue.erase(send_queue.begin());
|
||||
sending = false;
|
||||
if (call_send)
|
||||
if (call_send || !send_queue.empty())
|
||||
send();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,11 @@ from .Node import BlockType
|
||||
from .Node import Node
|
||||
from .WalletMgr import WalletMgr
|
||||
from .launch_transaction_generators import TransactionGeneratorsLauncher, TpsTrxGensConfig
|
||||
from .libc import unshare, CLONE_NEWNET
|
||||
from .interfaces import getInterfaceFlags, setInterfaceUp, IFF_LOOPBACK
|
||||
try:
|
||||
from .libc import unshare, CLONE_NEWNET
|
||||
from .interfaces import getInterfaceFlags, setInterfaceUp, IFF_LOOPBACK
|
||||
except:
|
||||
pass
|
||||
|
||||
# Protocol Feature Setup Policy
|
||||
class PFSetupPolicy:
|
||||
@@ -1727,4 +1730,7 @@ class Cluster(object):
|
||||
for line in f:
|
||||
firstTrxs.append(line.rstrip('\n'))
|
||||
Utils.Print(f"first transactions: {firstTrxs}")
|
||||
node.waitForTransactionsInBlock(firstTrxs)
|
||||
status = node.waitForTransactionsInBlock(firstTrxs)
|
||||
if status is None:
|
||||
Utils.Print('ERROR: Failed to spin up transaction generators: never received first transactions')
|
||||
return status
|
||||
|
||||
@@ -61,7 +61,7 @@ class Node(Transactions):
|
||||
self.fetchBlock = lambda blockNum: self.processUrllibRequest("trace_api", "get_block", {"block_num":blockNum}, silentErrors=False, exitOnError=True)
|
||||
self.fetchKeyCommand = lambda: "[transaction][transaction_header][ref_block_num]"
|
||||
self.fetchRefBlock = lambda trans: trans["transaction_header"]["ref_block_num"]
|
||||
self.cleosLimit = "--time-limit 99999"
|
||||
self.cleosLimit = "--time-limit 999"
|
||||
self.fetchHeadBlock = lambda node, headBlock: node.processUrllibRequest("chain", "get_block_info", {"block_num":headBlock}, silentErrors=False, exitOnError=True)
|
||||
|
||||
def __str__(self):
|
||||
|
||||
@@ -118,10 +118,10 @@ class NodeosQueries:
|
||||
# could be a transaction response
|
||||
if cntxt.hasKey("processed"):
|
||||
cntxt.add("processed")
|
||||
cntxt.add("action_traces")
|
||||
cntxt.index(0)
|
||||
if not cntxt.isSectionNull("except"):
|
||||
return "no_block"
|
||||
cntxt.add("action_traces")
|
||||
cntxt.index(0)
|
||||
return cntxt.add("block_num")
|
||||
|
||||
# or what the trace api plugin returns
|
||||
@@ -242,7 +242,7 @@ class NodeosQueries:
|
||||
assert(isinstance(transId, str))
|
||||
exitOnErrorForDelayed=not delayedRetry and exitOnError
|
||||
timeout=3
|
||||
cmdDesc="get transaction_trace"
|
||||
cmdDesc=self.fetchTransactionCommand()
|
||||
cmd="%s %s" % (cmdDesc, transId)
|
||||
msg="(transaction id=%s)" % (transId);
|
||||
for i in range(0,(int(60/timeout) - 1)):
|
||||
@@ -295,8 +295,8 @@ class NodeosQueries:
|
||||
refBlockNum=None
|
||||
key=""
|
||||
try:
|
||||
key="[transaction][transaction_header][ref_block_num]"
|
||||
refBlockNum=trans["transaction_header"]["ref_block_num"]
|
||||
key = self.fetchKeyCommand()
|
||||
refBlockNum = self.fetchRefBlock(trans)
|
||||
refBlockNum=int(refBlockNum)+1
|
||||
except (TypeError, ValueError, KeyError) as _:
|
||||
Utils.Print("transaction%s not found. Transaction: %s" % (key, trans))
|
||||
@@ -346,9 +346,9 @@ class NodeosQueries:
|
||||
return self.processCleosCmd(cmd, cmdDesc, silentErrors=False, exitOnError=exitOnError, exitMsg=msg, returnType=returnType)
|
||||
|
||||
def getTable(self, contract, scope, table, exitOnError=False):
|
||||
cmdDesc = "get table --time-limit 999"
|
||||
cmd="%s %s %s %s" % (cmdDesc, contract, scope, table)
|
||||
msg="contract=%s, scope=%s, table=%s" % (contract, scope, table);
|
||||
cmdDesc = "get table"
|
||||
cmd=f"{cmdDesc} {self.cleosLimit} {contract} {scope} {table}"
|
||||
msg=f"contract={contract}, scope={scope}, table={table}"
|
||||
return self.processCleosCmd(cmd, cmdDesc, exitOnError=exitOnError, exitMsg=msg)
|
||||
|
||||
def getTableAccountBalance(self, contract, scope):
|
||||
@@ -529,7 +529,7 @@ class NodeosQueries:
|
||||
return m.group(1)
|
||||
except subprocess.CalledProcessError as ex:
|
||||
end=time.perf_counter()
|
||||
msg=ex.output.decode("utf-8")
|
||||
msg=ex.stderr.decode("utf-8")
|
||||
Utils.Print("ERROR: Exception during code hash retrieval. cmd Duration: %.3f sec. %s" % (end-start, msg))
|
||||
return None
|
||||
|
||||
@@ -580,8 +580,9 @@ class NodeosQueries:
|
||||
except subprocess.CalledProcessError as ex:
|
||||
if not silentErrors:
|
||||
end=time.perf_counter()
|
||||
msg=ex.output.decode("utf-8")
|
||||
errorMsg="Exception during \"%s\". Exception message: %s. cmd Duration=%.3f sec. %s" % (cmdDesc, msg, end-start, exitMsg)
|
||||
out=ex.output.decode("utf-8")
|
||||
msg=ex.stderr.decode("utf-8")
|
||||
errorMsg="Exception during \"%s\". Exception message: %s. stdout: %s. cmd Duration=%.3f sec. %s" % (cmdDesc, msg, out, end-start, exitMsg)
|
||||
if exitOnError:
|
||||
Utils.cmdError(errorMsg)
|
||||
Utils.errorExit(errorMsg)
|
||||
|
||||
@@ -107,7 +107,7 @@ class Transactions(NodeosQueries):
|
||||
self.trackCmdTransaction(trans, reportStatus=reportStatus)
|
||||
except subprocess.CalledProcessError as ex:
|
||||
end=time.perf_counter()
|
||||
msg=ex.output.decode("utf-8")
|
||||
msg=ex.stderr.decode("utf-8")
|
||||
Utils.Print("ERROR: Exception during funds transfer. cmd Duration: %.3f sec. %s" % (end-start, msg))
|
||||
if exitOnError:
|
||||
Utils.cmdError("could not transfer \"%s\" from %s to %s" % (amountStr, source, destination))
|
||||
@@ -131,7 +131,7 @@ class Transactions(NodeosQueries):
|
||||
Utils.Print("cmd Duration: %.3f sec" % (end-start))
|
||||
except subprocess.CalledProcessError as ex:
|
||||
end=time.perf_counter()
|
||||
msg=ex.output.decode("utf-8")
|
||||
msg=ex.stderr.decode("utf-8")
|
||||
Utils.Print("ERROR: Exception during spawn of funds transfer. cmd Duration: %.3f sec. %s" % (end-start, msg))
|
||||
if exitOnError:
|
||||
Utils.cmdError("could not transfer \"%s\" from %s to %s" % (amountStr, source, destination))
|
||||
@@ -158,15 +158,15 @@ class Transactions(NodeosQueries):
|
||||
except subprocess.CalledProcessError as ex:
|
||||
if not shouldFail:
|
||||
end=time.perf_counter()
|
||||
msg=ex.output.decode("utf-8")
|
||||
Utils.Print("ERROR: Exception during set contract. cmd Duration: %.3f sec. %s" % (end-start, msg))
|
||||
out=ex.output.decode("utf-8")
|
||||
msg=ex.stderr.decode("utf-8")
|
||||
Utils.Print("ERROR: Exception during set contract. stderr: %s. stdout: %s. cmd Duration: %.3f sec." % (msg, out, end-start))
|
||||
return None
|
||||
else:
|
||||
retMap={}
|
||||
retMap["returncode"]=ex.returncode
|
||||
retMap["cmd"]=ex.cmd
|
||||
retMap["output"]=ex.output
|
||||
retMap["stdout"]=ex.stdout
|
||||
retMap["stderr"]=ex.stderr
|
||||
return retMap
|
||||
|
||||
@@ -213,7 +213,7 @@ class Transactions(NodeosQueries):
|
||||
Utils.Print("cmd Duration: %.3f sec" % (end-start))
|
||||
return (NodeosQueries.getTransStatus(retTrans) == 'executed', retTrans)
|
||||
except subprocess.CalledProcessError as ex:
|
||||
msg=ex.output.decode("utf-8")
|
||||
msg=ex.stderr.decode("utf-8")
|
||||
if not silentErrors:
|
||||
end=time.perf_counter()
|
||||
Utils.Print("ERROR: Exception during push transaction. cmd Duration=%.3f sec. %s" % (end - start, msg))
|
||||
@@ -245,7 +245,6 @@ class Transactions(NodeosQueries):
|
||||
except subprocess.CalledProcessError as ex:
|
||||
msg=ex.stderr.decode("utf-8")
|
||||
output=ex.output.decode("utf-8")
|
||||
msg=ex.output.decode("utf-8")
|
||||
if not silentErrors:
|
||||
end=time.perf_counter()
|
||||
Utils.Print("ERROR: Exception during push message. stderr: %s. stdout: %s. cmd Duration=%.3f sec." % (msg, output, end - start))
|
||||
|
||||
+1
-1
@@ -352,7 +352,7 @@ def abi_file_with_nodeos_test():
|
||||
os.makedirs(data_dir, exist_ok=True)
|
||||
walletMgr = WalletMgr(True)
|
||||
walletMgr.launch()
|
||||
node = Node('localhost', 8888, nodeId, cmd="./programs/nodeos/nodeos -e -p eosio --plugin eosio::trace_api_plugin --trace-no-abis --plugin eosio::producer_plugin --plugin eosio::producer_api_plugin --plugin eosio::chain_api_plugin --plugin eosio::chain_plugin --plugin eosio::http_plugin --access-control-allow-origin=* --http-validate-host=false --resource-monitor-not-shutdown-on-threshold-exceeded " + "--data-dir " + data_dir + " --config-dir " + data_dir, walletMgr=walletMgr)
|
||||
node = Node('localhost', 8888, nodeId, cmd="./programs/nodeos/nodeos -e -p eosio --plugin eosio::trace_api_plugin --trace-no-abis --plugin eosio::producer_plugin --plugin eosio::producer_api_plugin --plugin eosio::chain_api_plugin --plugin eosio::chain_plugin --plugin eosio::http_plugin --access-control-allow-origin=* --http-validate-host=false --max-transaction-time=-1 --resource-monitor-not-shutdown-on-threshold-exceeded " + "--data-dir " + data_dir + " --config-dir " + data_dir, walletMgr=walletMgr)
|
||||
node.verifyAlive() # Setting node state to not alive
|
||||
node.relaunch(newChain=True, cachePopen=True)
|
||||
node.waitForBlock(1)
|
||||
|
||||
@@ -133,7 +133,8 @@ try:
|
||||
acctPrivKeysList=[account1PrivKey,account2PrivKey], nodeId=snapshotNodeId, tpsPerGenerator=targetTpsPerGenerator,
|
||||
numGenerators=trxGeneratorCnt, durationSec=testTrxGenDurationSec, waitToComplete=False)
|
||||
|
||||
cluster.waitForTrxGeneratorsSpinup(nodeId=snapshotNodeId, numGenerators=trxGeneratorCnt)
|
||||
status = cluster.waitForTrxGeneratorsSpinup(nodeId=snapshotNodeId, numGenerators=trxGeneratorCnt)
|
||||
assert status is not None, "ERROR: Failed to spinup Transaction Generators"
|
||||
|
||||
blockNum=node0.getBlockNum(BlockType.head)
|
||||
timePerBlock=500
|
||||
|
||||
@@ -118,7 +118,8 @@ try:
|
||||
tpsPerGenerator=targetTpsPerGenerator, numGenerators=trxGeneratorCnt, durationSec=testTrxGenDurationSec,
|
||||
waitToComplete=False)
|
||||
|
||||
cluster.waitForTrxGeneratorsSpinup(nodeId=node0.nodeId, numGenerators=trxGeneratorCnt)
|
||||
status = cluster.waitForTrxGeneratorsSpinup(nodeId=node0.nodeId, numGenerators=trxGeneratorCnt)
|
||||
assert status is not None, "ERROR: Failed to spinup Transaction Generators"
|
||||
|
||||
blockNum=head(node0)
|
||||
timePerBlock=500
|
||||
|
||||
@@ -56,7 +56,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
"http_plugin", "db_size_api_plugin", "prometheus_plugin"]
|
||||
nodeos_plugins = "--plugin eosio::" + " --plugin eosio::".join(plugin_names)
|
||||
nodeos_flags = (" --data-dir=%s --config-dir=%s --trace-dir=%s --trace-no-abis --access-control-allow-origin=%s "
|
||||
"--contracts-console --http-validate-host=%s --verbose-http-errors --abi-serializer-max-time-ms 30000 --http-max-response-time-ms 30000 "
|
||||
"--contracts-console --http-validate-host=%s --verbose-http-errors --max-transaction-time -1 --abi-serializer-max-time-ms 30000 --http-max-response-time-ms 30000 "
|
||||
"--p2p-peer-address localhost:9011 --resource-monitor-not-shutdown-on-threshold-exceeded ") % (self.data_dir, self.config_dir, self.data_dir, "\'*\'", "false")
|
||||
start_nodeos_cmd = ("%s -e -p eosio %s %s ") % (Utils.EosServerPath, nodeos_plugins, nodeos_flags)
|
||||
self.nodeos.launchCmd(start_nodeos_cmd, self.node_id)
|
||||
@@ -337,7 +337,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
# get_account with valid parameter
|
||||
payload = {"account_name":"default"}
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# get_code with empty parameter
|
||||
command = "get_code"
|
||||
@@ -355,7 +355,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
# get_code with valid parameter
|
||||
payload = {"account_name":"default"}
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# get_code_hash with empty parameter
|
||||
command = "get_code_hash"
|
||||
@@ -373,7 +373,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
# get_code_hash with valid parameter
|
||||
payload = {"account_name":"default"}
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# get_abi with empty parameter
|
||||
command = "get_abi"
|
||||
@@ -391,7 +391,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
# get_abi with valid parameter
|
||||
payload = {"account_name":"default"}
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# get_raw_code_and_abi with empty parameter
|
||||
command = "get_raw_code_and_abi"
|
||||
@@ -409,7 +409,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
# get_raw_code_and_abi with valid parameter
|
||||
payload = {"account_name":"default"}
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# get_raw_abi with empty parameter
|
||||
command = "get_raw_abi"
|
||||
@@ -427,7 +427,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
# get_raw_abi with valid parameter
|
||||
payload = {"account_name":"default"}
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# get_table_rows with empty parameter
|
||||
command = "get_table_rows"
|
||||
@@ -452,7 +452,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
"lower_bound":"0x0000000000000000D0F2A472A8EB6A57",
|
||||
"upper_bound":"0xFFFFFFFFFFFFFFFFD0F2A472A8EB6A57"}
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# get_table_by_scope with empty parameter
|
||||
command = "get_table_by_scope"
|
||||
@@ -474,7 +474,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
"lower_bound":"0x0000000000000000D0F2A472A8EB6A57",
|
||||
"upper_bound":"0xFFFFFFFFFFFFFFFFD0F2A472A8EB6A57"}
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# get_currency_balance with empty parameter
|
||||
command = "get_currency_balance"
|
||||
@@ -492,7 +492,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
# get_currency_balance with valid parameter
|
||||
payload = {"code":"eosio.token", "account":"unknown"}
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# get_currency_stats with empty parameter
|
||||
command = "get_currency_stats"
|
||||
@@ -510,7 +510,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
# get_currency_stats with valid parameter
|
||||
payload = {"code":"eosio.token","symbol":"SYS"}
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# get_producers with empty parameter
|
||||
command = "get_producers"
|
||||
@@ -585,7 +585,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
"EOS7d9A3uLe6As66jzN8j44TXJUqJSK3bFjjEEqR4oTvNAB3iM9SA",
|
||||
"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"]}
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# get_transaction_id with empty parameter
|
||||
command = "get_transaction_id"
|
||||
@@ -652,7 +652,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
"packed_context_free_data": "context_free_data",
|
||||
"packed_trx": "packed_trx"}
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# push_transactions with empty parameter
|
||||
command = "push_transactions"
|
||||
@@ -694,7 +694,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
"packed_context_free_data": "context_free_data",
|
||||
"packed_trx": "packed_trx"}
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
|
||||
# test all net api
|
||||
@@ -1091,7 +1091,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
["EOS696giL6VxeJhtEgKtWPK8aQeT8YXNjw2a7vE5wHunffhfa5QSQ"],
|
||||
"cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f"]
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload, endpoint=endpoint)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
self.assertEqual(ret_json["error"]["code"], 3120004)
|
||||
|
||||
# create with empty parameter
|
||||
@@ -1105,7 +1105,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
self.assertEqual(ret_json["error"]["code"], 3200006)
|
||||
# create with invalid parameter
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, self.http_post_invalid_param, endpoint=endpoint)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
self.assertEqual(ret_json["error"]["code"], 3120000)
|
||||
# create with valid parameter
|
||||
payload = "test1"
|
||||
@@ -1123,12 +1123,12 @@ class PluginHttpTest(unittest.TestCase):
|
||||
self.assertEqual(ret_json["error"]["code"], 3200006)
|
||||
# create with invalid parameter
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, self.http_post_invalid_param, endpoint=endpoint)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
self.assertEqual(ret_json["error"]["code"], 3120000)
|
||||
# create with valid parameter
|
||||
payload = "fakeacct"
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload, endpoint=endpoint)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# lock_all with empty parameter
|
||||
command = "lock_all"
|
||||
@@ -1153,7 +1153,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
self.assertEqual(ret_json["error"]["code"], 3200006)
|
||||
# lock with invalid parameter
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, self.http_post_invalid_param, endpoint=endpoint)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
self.assertEqual(ret_json["error"]["code"], 3120002)
|
||||
# lock with valid parameter
|
||||
payload = {"name":"auser"}
|
||||
@@ -1176,7 +1176,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
# unlock with valid parameter
|
||||
payload = ["auser", "nopassword"]
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload, endpoint=endpoint)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# import_key with empty parameter
|
||||
command = "import_key"
|
||||
@@ -1194,7 +1194,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
# import_key with valid parameter
|
||||
payload = ["auser", "nokey"]
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload, endpoint=endpoint)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# remove_key with empty parameter
|
||||
command = "remove_key"
|
||||
@@ -1212,7 +1212,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
# remove_key with valid parameter
|
||||
payload = ["auser", "none", "none"]
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload, endpoint=endpoint)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# create_key with empty parameter
|
||||
command = "create_key"
|
||||
@@ -1230,7 +1230,7 @@ class PluginHttpTest(unittest.TestCase):
|
||||
# create_key with valid parameter
|
||||
payload = ["auser", "none"]
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload, endpoint=endpoint)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# list_wallets with empty parameter
|
||||
command = "list_wallets"
|
||||
@@ -1260,15 +1260,15 @@ class PluginHttpTest(unittest.TestCase):
|
||||
# list_keys with valid parameter
|
||||
payload = ["auser", "unknownkey"]
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, payload, endpoint=endpoint)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
# get_public_keys with empty parameter
|
||||
command = "get_public_keys"
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, endpoint=endpoint)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
# get_public_keys with empty content parameter
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, self.empty_content_dict, endpoint=endpoint)
|
||||
self.assertEqual(ret_json["code"], 500)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
# list_wallets with invalid parameter
|
||||
ret_json = self.nodeos.processUrllibRequest(resource, command, self.http_post_invalid_param, endpoint=endpoint)
|
||||
self.assertEqual(ret_json["code"], 400)
|
||||
|
||||
@@ -259,7 +259,7 @@ try:
|
||||
runReadOnlyTrxAndRpcInParallel("chain", "get_raw_code_and_abi", "account_name", expectedValue=testAccountName, payload = {"account_name":testAccountName})
|
||||
runReadOnlyTrxAndRpcInParallel("chain", "get_raw_abi", "account_name", expectedValue=testAccountName, payload = {"account_name":testAccountName})
|
||||
runReadOnlyTrxAndRpcInParallel("chain", "get_producers", "rows", payload = {"json":"true","lower_bound":""})
|
||||
runReadOnlyTrxAndRpcInParallel("chain", "get_table_rows", code=500, payload = {"json":"true","table":"noauth"})
|
||||
runReadOnlyTrxAndRpcInParallel("chain", "get_table_rows", code=400, payload = {"json":"true","table":"noauth"})
|
||||
runReadOnlyTrxAndRpcInParallel("chain", "get_table_by_scope", fieldIn="rows", payload = {"json":"true","table":"noauth"})
|
||||
runReadOnlyTrxAndRpcInParallel("chain", "get_currency_balance", code=200, payload = {"code":"eosio.token", "account":testAccountName})
|
||||
runReadOnlyTrxAndRpcInParallel("chain", "get_currency_stats", fieldIn="SYS", payload = {"code":"eosio.token", "symbol":"SYS"})
|
||||
|
||||
Reference in New Issue
Block a user