From c69b589879bc278006c54dfe2acfb28a579c76b3 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Fri, 15 Sep 2023 09:03:09 -0400 Subject: [PATCH 01/29] Remove defer transaction options --max-scheduled-transaction-time-per-block-ms and --incoming-defer-ratio --- .../03_plugins/producer_plugin/index.md | 25 --- .../eosio/producer_plugin/producer_plugin.hpp | 4 +- plugins/producer_plugin/producer_plugin.cpp | 168 ------------------ tests/PerformanceHarness/README.md | 12 -- 4 files changed, 1 insertion(+), 208 deletions(-) diff --git a/docs/01_nodeos/03_plugins/producer_plugin/index.md b/docs/01_nodeos/03_plugins/producer_plugin/index.md index 2008de7d6f..18a31470c4 100644 --- a/docs/01_nodeos/03_plugins/producer_plugin/index.md +++ b/docs/01_nodeos/03_plugins/producer_plugin/index.md @@ -95,13 +95,6 @@ Config Options for eosio::producer_plugin: consider block full; when within threshold of max-block-net-usage block can be produced immediately - --max-scheduled-transaction-time-per-block-ms arg (=100) - Maximum wall-clock time, in - milliseconds, spent retiring scheduled - transactions (and incoming transactions - according to incoming-defer-ratio) in - any block before returning to normal - transaction processing. --subjective-cpu-leeway-us arg (=31000) Time in microseconds allowed for a transaction that starts with @@ -114,9 +107,6 @@ Config Options for eosio::producer_plugin: --subjective-account-decay-time-minutes arg (=1440) Sets the time to return full subjective cpu for accounts - --incoming-defer-ratio arg (=1) ratio between incoming transactions and - deferred transactions when both are - queued for execution --incoming-transaction-queue-size-mb arg (=1024) Maximum size (in MiB) of the incoming transaction queue. Exceeding this value @@ -142,21 +132,6 @@ Config Options for eosio::producer_plugin: * [`chain_plugin`](../chain_plugin/index.md) -## The priority of transaction - -You can give one of the transaction types priority over another when the producer plugin has a queue of transactions pending. - -The option below sets the ratio between the incoming transaction and the deferred transaction: - -```console - --incoming-defer-ratio arg (=1) -``` - -By default value of `1`, the `producer` plugin processes one incoming transaction per deferred transaction. When `arg` sets to `10`, the `producer` plugin processes 10 incoming transactions per deferred transaction. - -If the `arg` is set to a sufficiently large number, the plugin always processes the incoming transaction first until the queue of the incoming transactions is empty. Respectively, if the `arg` is 0, the `producer` plugin processes the deferred transactions queue first. - - ### Load Dependency Examples ```console diff --git a/plugins/producer_plugin/include/eosio/producer_plugin/producer_plugin.hpp b/plugins/producer_plugin/include/eosio/producer_plugin/producer_plugin.hpp index f102dfcf0b..d8398c09ee 100644 --- a/plugins/producer_plugin/include/eosio/producer_plugin/producer_plugin.hpp +++ b/plugins/producer_plugin/include/eosio/producer_plugin/producer_plugin.hpp @@ -18,9 +18,7 @@ class producer_plugin : public appbase::plugin { std::optional max_transaction_time; std::optional max_irreversible_block_age; std::optional cpu_effort_us; - std::optional max_scheduled_transaction_time_per_block_ms; std::optional subjective_cpu_leeway_us; - std::optional incoming_defer_ratio; std::optional greylist_limit; }; @@ -199,7 +197,7 @@ class producer_plugin : public appbase::plugin { } //eosio -FC_REFLECT(eosio::producer_plugin::runtime_options, (max_transaction_time)(max_irreversible_block_age)(cpu_effort_us)(max_scheduled_transaction_time_per_block_ms)(subjective_cpu_leeway_us)(incoming_defer_ratio)(greylist_limit)); +FC_REFLECT(eosio::producer_plugin::runtime_options, (max_transaction_time)(max_irreversible_block_age)(cpu_effort_us)(subjective_cpu_leeway_us)(greylist_limit)); FC_REFLECT(eosio::producer_plugin::greylist_params, (accounts)); FC_REFLECT(eosio::producer_plugin::whitelist_blacklist, (actor_whitelist)(actor_blacklist)(contract_whitelist)(contract_blacklist)(action_blacklist)(key_blacklist) ) FC_REFLECT(eosio::producer_plugin::integrity_hash_information, (head_block_id)(integrity_hash)) diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index bffdf69e4d..bf54f734b3 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -399,7 +399,6 @@ class producer_plugin_impl : public std::enable_shared_from_thischain().get_subjective_cpu_leeway() ? chain_plug->chain().get_subjective_cpu_leeway()->count() : std::optional(), - _incoming_defer_ratio, chain_plug->chain().get_greylist_limit()}; } @@ -533,7 +530,6 @@ class producer_plugin_impl : public std::enable_shared_from_this()->default_value( 1024 ), "Threshold of NET block production to consider block full; when within threshold of max-block-net-usage block can be produced immediately") - ("max-scheduled-transaction-time-per-block-ms", boost::program_options::value()->default_value(100), - "Maximum wall-clock time, in milliseconds, spent retiring scheduled transactions (and incoming transactions according to incoming-defer-ratio) in any block before returning to normal transaction processing.") ("subjective-cpu-leeway-us", boost::program_options::value()->default_value( config::default_subjective_cpu_leeway_us ), "Time in microseconds allowed for a transaction that starts with insufficient CPU quota to complete and cover its CPU usage.") ("subjective-account-max-failures", boost::program_options::value()->default_value(3), @@ -1077,8 +1068,6 @@ void producer_plugin::set_program_options( "Sets the window size in number of blocks for subjective-account-max-failures.") ("subjective-account-decay-time-minutes", bpo::value()->default_value( config::account_cpu_usage_average_window_ms / 1000 / 60 ), "Sets the time to return full subjective cpu for accounts") - ("incoming-defer-ratio", bpo::value()->default_value(1.0), - "ratio between incoming transactions and deferred transactions when both are queued for execution") ("incoming-transaction-queue-size-mb", bpo::value()->default_value( 1024 ), "Maximum size (in MiB) of the incoming transaction queue. Exceeding this value will subjectively drop transaction with resource exhaustion.") ("disable-subjective-account-billing", boost::program_options::value>()->composing()->multitoken(), @@ -1173,8 +1162,6 @@ void producer_plugin_impl::plugin_initialize(const boost::program_options::varia _max_block_net_usage_threshold_bytes = options.at("max-block-net-usage-threshold-bytes").as(); - _max_scheduled_transaction_time_per_block_ms = options.at("max-scheduled-transaction-time-per-block-ms").as(); - if (options.at("subjective-cpu-leeway-us").as() != config::default_subjective_cpu_leeway_us) { chain.set_subjective_cpu_leeway(fc::microseconds(options.at("subjective-cpu-leeway-us").as())); } @@ -1197,8 +1184,6 @@ void producer_plugin_impl::plugin_initialize(const boost::program_options::varia _unapplied_transactions.set_max_transaction_queue_size(max_incoming_transaction_queue_size); - _incoming_defer_ratio = options.at("incoming-defer-ratio").as(); - _disable_subjective_p2p_billing = options.at("disable-subjective-p2p-billing").as(); _disable_subjective_api_billing = options.at("disable-subjective-api-billing").as(); dlog("disable-subjective-p2p-billing: ${p2p}, disable-subjective-api-billing: ${api}", @@ -1480,14 +1465,6 @@ void producer_plugin_impl::update_runtime_options(const producer_plugin::runtime _cpu_effort_us = *options.cpu_effort_us; } - if (options.max_scheduled_transaction_time_per_block_ms) { - _max_scheduled_transaction_time_per_block_ms = *options.max_scheduled_transaction_time_per_block_ms; - } - - if (options.incoming_defer_ratio) { - _incoming_defer_ratio = *options.incoming_defer_ratio; - } - if (check_speculating && in_speculating_mode()) { abort_block(); schedule_production_loop(); @@ -1994,15 +1971,6 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() { if (in_producing_mode()) { if (!process_unapplied_trxs(preprocess_deadline)) return start_block_result::exhausted; - - - auto scheduled_trx_deadline = preprocess_deadline; - if (_max_scheduled_transaction_time_per_block_ms >= 0) { - scheduled_trx_deadline = std::min( - scheduled_trx_deadline, fc::time_point::now() + fc::milliseconds(_max_scheduled_transaction_time_per_block_ms)); - } - // may exhaust scheduled_trx_deadline but not preprocess_deadline, exhausted preprocess_deadline checked below - process_scheduled_and_incoming_trxs(scheduled_trx_deadline, incoming_itr); } repost_exhausted_transactions(preprocess_deadline); @@ -2370,142 +2338,6 @@ bool producer_plugin_impl::process_unapplied_trxs(const fc::time_point& deadline return !exhausted; } -void producer_plugin_impl::process_scheduled_and_incoming_trxs(const fc::time_point& deadline, unapplied_transaction_queue::iterator& itr) { - // scheduled transactions - int num_applied = 0; - int num_failed = 0; - int num_processed = 0; - bool exhausted = false; - double incoming_trx_weight = 0.0; - - auto& blacklist_by_id = _blacklisted_transactions.get(); - chain::controller& chain = chain_plug->chain(); - time_point pending_block_time = chain.pending_block_time(); - auto end = _unapplied_transactions.incoming_end(); - const auto& sch_idx = chain.db().get_index(); - const auto scheduled_trxs_size = sch_idx.size(); - auto sch_itr = sch_idx.begin(); - while (sch_itr != sch_idx.end()) { - if (sch_itr->delay_until > pending_block_time) - break; // not scheduled yet - if (exhausted || deadline <= fc::time_point::now()) { - exhausted = true; - break; - } - if (sch_itr->published >= pending_block_time) { - ++sch_itr; - continue; // do not allow schedule and execute in same block - } - - if (blacklist_by_id.find(sch_itr->trx_id) != blacklist_by_id.end()) { - ++sch_itr; - continue; - } - - const transaction_id_type trx_id = sch_itr->trx_id; // make copy since reference could be invalidated - const auto sch_expiration = sch_itr->expiration; - auto sch_itr_next = sch_itr; // save off next since sch_itr may be invalidated by loop - ++sch_itr_next; - const auto next_delay_until = sch_itr_next != sch_idx.end() ? sch_itr_next->delay_until : sch_itr->delay_until; - const auto next_id = sch_itr_next != sch_idx.end() ? sch_itr_next->id : sch_itr->id; - - num_processed++; - - // configurable ratio of incoming txns vs deferred txns - while (incoming_trx_weight >= 1.0 && itr != end) { - if (deadline <= fc::time_point::now()) { - exhausted = true; - break; - } - - incoming_trx_weight -= 1.0; - - auto trx_meta = itr->trx_meta; - bool api_trx = itr->trx_type == trx_enum_type::incoming_api; - - auto trx_tracker = _time_tracker.start_trx(trx_meta->is_transient()); - push_result pr = push_transaction(deadline, trx_meta, api_trx, itr->return_failure_trace, trx_tracker, itr->next); - - exhausted = pr.block_exhausted; - if (pr.trx_exhausted) { - ++itr; // leave in incoming - } else { - itr = _unapplied_transactions.erase(itr); - } - - if (exhausted) - break; - } - - if (exhausted || deadline <= fc::time_point::now()) { - exhausted = true; - break; - } - - auto get_first_authorizer = [&](const transaction_trace_ptr& trace) { - for (const auto& a : trace->action_traces) { - for (const auto& u : a.act.authorization) - return u.actor; - } - return account_name(); - }; - - try { - auto start = fc::time_point::now(); - auto trx_tracker = _time_tracker.start_trx(false, start); // delayed transaction cannot be transient - fc::microseconds max_trx_time = fc::milliseconds(_max_transaction_time_ms.load()); - if (max_trx_time.count() < 0) - max_trx_time = fc::microseconds::maximum(); - - auto trace = chain.push_scheduled_transaction(trx_id, deadline, max_trx_time, 0, false); - auto end = fc::time_point::now(); - if (trace->except) { - if (exception_is_exhausted(*trace->except)) { - if (block_is_exhausted()) { - exhausted = true; - break; - } - } else { - fc_dlog(_trx_failed_trace_log, - "[TRX_TRACE] Block ${block_num} for producer ${prod} is REJECTING scheduled tx: ${txid}, time: ${r}, auth: ${a} : ${details}", - ("block_num", chain.head_block_num() + 1)("prod", get_pending_block_producer())("txid", trx_id)("r", end - start) - ("a", get_first_authorizer(trace))("details", get_detailed_contract_except_info(nullptr, trace, nullptr))); - fc_dlog(_trx_trace_failure_log, - "[TRX_TRACE] Block ${block_num} for producer ${prod} is REJECTING scheduled tx: ${entire_trace}", - ("block_num", chain.head_block_num() + 1)("prod", get_pending_block_producer()) - ("entire_trace", chain_plug->get_log_trx_trace(trace))); - // this failed our configured maximum transaction time, we don't want to replay it add it to a blacklist - _blacklisted_transactions.insert(transaction_id_with_expiry{trx_id, sch_expiration}); - num_failed++; - } - } else { - trx_tracker.trx_success(); - 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())("txid", trx_id)("r", end - start) - ("a", get_first_authorizer(trace))("cpu", trace->receipt ? trace->receipt->cpu_usage_us : 0)); - fc_dlog(_trx_trace_success_log, - "[TRX_TRACE] Block ${block_num} for producer ${prod} is ACCEPTING scheduled tx: ${entire_trace}", - ("block_num", chain.head_block_num() + 1)("prod", get_pending_block_producer()) - ("entire_trace", chain_plug->get_log_trx_trace(trace))); - num_applied++; - } - } - LOG_AND_DROP(); - - incoming_trx_weight += _incoming_defer_ratio; - - if (sch_itr_next == sch_idx.end()) - break; - sch_itr = sch_idx.lower_bound(boost::make_tuple(next_delay_until, next_id)); - } - - if (scheduled_trxs_size > 0) { - fc_dlog(_log, "Processed ${m} of ${n} scheduled transactions, Applied ${applied}, Failed/Dropped ${failed}", - ("m", num_processed)("n", scheduled_trxs_size)("applied", num_applied)("failed", num_failed)); - } -} - bool producer_plugin_impl::process_incoming_trxs(const fc::time_point& deadline, unapplied_transaction_queue::iterator& itr) { bool exhausted = false; auto end = _unapplied_transactions.incoming_end(); diff --git a/tests/PerformanceHarness/README.md b/tests/PerformanceHarness/README.md index 3178aa9e51..57a91a0647 100644 --- a/tests/PerformanceHarness/README.md +++ b/tests/PerformanceHarness/README.md @@ -1589,9 +1589,6 @@ Finally, the full detail test report for each of the determined max TPS throughp "maxBlockNetUsageThresholdBytes": null, "_maxBlockNetUsageThresholdBytesNodeosDefault": 1024, "_maxBlockNetUsageThresholdBytesNodeosArg": "--max-block-net-usage-threshold-bytes", - "maxScheduledTransactionTimePerBlockMs": null, - "_maxScheduledTransactionTimePerBlockMsNodeosDefault": 100, - "_maxScheduledTransactionTimePerBlockMsNodeosArg": "--max-scheduled-transaction-time-per-block-ms", "subjectiveCpuLeewayUs": null, "_subjectiveCpuLeewayUsNodeosDefault": 31000, "_subjectiveCpuLeewayUsNodeosArg": "--subjective-cpu-leeway-us", @@ -1604,9 +1601,6 @@ Finally, the full detail test report for each of the determined max TPS throughp "subjectiveAccountDecayTimeMinutes": null, "_subjectiveAccountDecayTimeMinutesNodeosDefault": 1440, "_subjectiveAccountDecayTimeMinutesNodeosArg": "--subjective-account-decay-time-minutes", - "incomingDeferRatio": null, - "_incomingDeferRatioNodeosDefault": 1, - "_incomingDeferRatioNodeosArg": "--incoming-defer-ratio", "incomingTransactionQueueSizeMb": null, "_incomingTransactionQueueSizeMbNodeosDefault": 1024, "_incomingTransactionQueueSizeMbNodeosArg": "--incoming-transaction-queue-size-mb", @@ -2257,9 +2251,6 @@ The Performance Test Basic generates, by default, a report that details results "maxBlockNetUsageThresholdBytes": null, "_maxBlockNetUsageThresholdBytesNodeosDefault": 1024, "_maxBlockNetUsageThresholdBytesNodeosArg": "--max-block-net-usage-threshold-bytes", - "maxScheduledTransactionTimePerBlockMs": null, - "_maxScheduledTransactionTimePerBlockMsNodeosDefault": 100, - "_maxScheduledTransactionTimePerBlockMsNodeosArg": "--max-scheduled-transaction-time-per-block-ms", "subjectiveCpuLeewayUs": null, "_subjectiveCpuLeewayUsNodeosDefault": 31000, "_subjectiveCpuLeewayUsNodeosArg": "--subjective-cpu-leeway-us", @@ -2272,9 +2263,6 @@ The Performance Test Basic generates, by default, a report that details results "subjectiveAccountDecayTimeMinutes": null, "_subjectiveAccountDecayTimeMinutesNodeosDefault": 1440, "_subjectiveAccountDecayTimeMinutesNodeosArg": "--subjective-account-decay-time-minutes", - "incomingDeferRatio": null, - "_incomingDeferRatioNodeosDefault": 1, - "_incomingDeferRatioNodeosArg": "--incoming-defer-ratio", "incomingTransactionQueueSizeMb": null, "_incomingTransactionQueueSizeMbNodeosDefault": 1024, "_incomingTransactionQueueSizeMbNodeosArg": "--incoming-transaction-queue-size-mb", From 2578ead588eb2a688c7710b309da6d7807053768 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Sat, 16 Sep 2023 16:31:29 -0400 Subject: [PATCH 02/29] remove _blacklisted_transactions, remove_expired_blacklisted_trxs, and blacklisted_transactions_total --- .../eosio/producer_plugin/producer_plugin.hpp | 1 - plugins/producer_plugin/producer_plugin.cpp | 42 ------------------- plugins/prometheus_plugin/metrics.hpp | 6 +-- tools/net-util.py | 1 - 4 files changed, 1 insertion(+), 49 deletions(-) diff --git a/plugins/producer_plugin/include/eosio/producer_plugin/producer_plugin.hpp b/plugins/producer_plugin/include/eosio/producer_plugin/producer_plugin.hpp index d8398c09ee..f2c7e914f1 100644 --- a/plugins/producer_plugin/include/eosio/producer_plugin/producer_plugin.hpp +++ b/plugins/producer_plugin/include/eosio/producer_plugin/producer_plugin.hpp @@ -160,7 +160,6 @@ class producer_plugin : public appbase::plugin { struct produced_block_metrics : public speculative_block_metrics { std::size_t unapplied_transactions_total = 0; - std::size_t blacklisted_transactions_total = 0; std::size_t subjective_bill_account_size_total = 0; std::size_t scheduled_trxs_total = 0; std::size_t trxs_produced_total = 0; diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index bf54f734b3..69f4f99f5d 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -108,19 +108,6 @@ bool exception_is_exhausted(const fc::exception& e) { } } // namespace -struct transaction_id_with_expiry { - transaction_id_type trx_id; - fc::time_point expiry; -}; - -struct by_id; -struct by_expiry; - -using transaction_id_with_expiry_index = multi_index_container< - transaction_id_with_expiry, - indexed_by, BOOST_MULTI_INDEX_MEMBER(transaction_id_with_expiry, transaction_id_type, trx_id)>, - ordered_non_unique, BOOST_MULTI_INDEX_MEMBER(transaction_id_with_expiry, fc::time_point, expiry)>>>; - namespace { // track multiple failures on unapplied transactions @@ -545,7 +532,6 @@ class producer_plugin_impl : public std::enable_shared_from_this(); - if (!blacklist_by_expiry.empty()) { - const chain::controller& chain = chain_plug->chain(); - const auto lib_time = chain.last_irreversible_block_time(); - const auto pending_block_num = chain.pending_block_num(); - - int num_expired = 0; - int orig_count = _blacklisted_transactions.size(); - - while (!blacklist_by_expiry.empty() && blacklist_by_expiry.begin()->expiry <= lib_time) { - if (should_interrupt_start_block(deadline, pending_block_num)) { - exhausted = true; - break; - } - blacklist_by_expiry.erase(blacklist_by_expiry.begin()); - num_expired++; - } - - fc_dlog(_log, "Processed ${n} blacklisted transactions, Expired ${expired}", ("n", orig_count)("expired", num_expired)); - } - return !exhausted; -} - // Returns contract name, action name, and exception text of an exception that occurred in a contract inline std::string get_detailed_contract_except_info(const packed_transaction_ptr& trx, const transaction_trace_ptr& trace, @@ -2589,7 +2548,6 @@ void producer_plugin_impl::produce_block() { if (_update_produced_block_metrics) { metrics.unapplied_transactions_total = _unapplied_transactions.size(); - metrics.blacklisted_transactions_total = _blacklisted_transactions.size(); metrics.subjective_bill_account_size_total = chain.get_subjective_billing().get_account_cache_size(); metrics.scheduled_trxs_total = chain.db().get_index().size(); metrics.trxs_produced_total = new_bs->block->transactions.size(); diff --git a/plugins/prometheus_plugin/metrics.hpp b/plugins/prometheus_plugin/metrics.hpp index 873f65f3f4..b9de6b6435 100644 --- a/plugins/prometheus_plugin/metrics.hpp +++ b/plugins/prometheus_plugin/metrics.hpp @@ -68,7 +68,6 @@ struct catalog_type { // produced blocks Counter& unapplied_transactions_total; - Counter& blacklisted_transactions_total; Counter& subjective_bill_account_size_total; Counter& scheduled_trxs_total; Counter& trxs_produced_total; @@ -110,8 +109,6 @@ struct catalog_type { , head_block_num(build("nodeos_head_block_num", "head block number")) , unapplied_transactions_total(build("nodeos_unapplied_transactions_total", "total number of unapplied transactions from produced blocks")) - , blacklisted_transactions_total(build("nodeos_blacklisted_transactions_total", - "total number of blacklisted transactions from produced blocks")) , subjective_bill_account_size_total(build( "nodeos_subjective_bill_account_size_total", "total number of subjective bill account size from produced blocks")) , scheduled_trxs_total( @@ -211,7 +208,6 @@ struct catalog_type { void update(const producer_plugin::produced_block_metrics& metrics) { unapplied_transactions_total.Increment(metrics.unapplied_transactions_total); - blacklisted_transactions_total.Increment(metrics.blacklisted_transactions_total); subjective_bill_account_size_total.Increment(metrics.subjective_bill_account_size_total); scheduled_trxs_total.Increment(metrics.scheduled_trxs_total); trxs_produced_total.Increment(metrics.trxs_produced_total); @@ -288,4 +284,4 @@ struct catalog_type { } }; -} // namespace eosio::metrics \ No newline at end of file +} // namespace eosio::metrics diff --git a/tools/net-util.py b/tools/net-util.py index 01d0862749..7dff39a70f 100755 --- a/tools/net-util.py +++ b/tools/net-util.py @@ -103,7 +103,6 @@ def __init__(self): 'nodeos_blocks_produced_total': 'Blocks Produced:', 'nodeos_trxs_produced_total': 'Trxs Produced:', 'nodeos_scheduled_trxs_total': 'Scheduled Trxs:', - 'nodeos_blacklisted_transactions_total': 'Blacklisted Trxs:', 'nodeos_unapplied_transactions_total': 'Unapplied Trxs:', 'nodeos_dropped_trxs_total': 'Dropped Trxs:', 'nodeos_failed_p2p_connections_total': 'Failed P2P Connections:', From 013b20ff4bc6cb552887506205233982516b62d8 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Sun, 17 Sep 2023 23:12:11 -0400 Subject: [PATCH 03/29] retire expired deferred transactions --- plugins/producer_plugin/producer_plugin.cpp | 93 +++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index 69f4f99f5d..fde53a32a7 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -386,6 +386,7 @@ class producer_plugin_impl : public std::enable_shared_from_this(preprocess_deadline, fc::time_point::now() + fc::milliseconds(50)); + retire_expired_deferred_trxs(deferred_trxs_deadline); } repost_exhausted_transactions(preprocess_deadline); @@ -2297,6 +2302,94 @@ bool producer_plugin_impl::process_unapplied_trxs(const fc::time_point& deadline return !exhausted; } +void producer_plugin_impl::retire_expired_deferred_trxs(const fc::time_point& deadline) { + int num_applied = 0; + int num_failed = 0; + int num_processed = 0; + bool exhausted = false; + + chain::controller& chain = chain_plug->chain(); + time_point pending_block_time = chain.pending_block_time(); + const auto& expired_idx = chain.db().get_index(); + const auto expired_size = expired_idx.size(); + auto expired_itr = expired_idx.begin(); + + while (expired_itr != expired_idx.end()) { + if (expired_itr->expiration > pending_block_time) { + break; // not expired yet + } + + if (exhausted || deadline <= fc::time_point::now()) { + exhausted = true; + break; + } + + auto get_first_authorizer = [&](const transaction_trace_ptr& trace) { + for (const auto& a : trace->action_traces) { + for (const auto& u : a.act.authorization) + return u.actor; + } + return account_name(); + }; + + const transaction_id_type trx_id = expired_itr->trx_id; // make copy since reference could be invalidated + auto expired_itr_next = expired_itr; // save off next since expired_itr may be invalidated by loop + ++expired_itr_next; + const auto next_expired = expired_itr_next != expired_idx.end() ? expired_itr_next->expiration : expired_itr->expiration; + const auto next_id = expired_itr_next != expired_idx.end() ? expired_itr_next->id : expired_itr->id; + + try { + auto start = fc::time_point::now(); + auto trx_tracker = _time_tracker.start_trx(false, start); // delayed transaction cannot be transient + fc::microseconds max_trx_time = fc::milliseconds(_max_transaction_time_ms.load()); + if (max_trx_time.count() < 0) + max_trx_time = fc::microseconds::maximum(); + + auto trace = chain.push_scheduled_transaction(trx_id, deadline, max_trx_time, 0, false); + auto end = fc::time_point::now(); + if (trace->except) { + if (exception_is_exhausted(*trace->except)) { + if (block_is_exhausted()) { + exhausted = true; + break; + } + } else { + fc_dlog(_trx_failed_trace_log, + "[TRX_TRACE] Block ${block_num} for producer ${prod} is REJECTING scheduled tx: ${txid}, time: ${r}, auth: ${a} : ${details}", + ("block_num", chain.head_block_num() + 1)("prod", get_pending_block_producer())("txid", trx_id)("r", end - start) + ("a", get_first_authorizer(trace))("details", get_detailed_contract_except_info(nullptr, trace, nullptr))); + fc_dlog(_trx_trace_failure_log, + "[TRX_TRACE] Block ${block_num} for producer ${prod} is REJECTING scheduled tx: ${entire_trace}", + ("block_num", chain.head_block_num() + 1)("prod", get_pending_block_producer()) + ("entire_trace", chain_plug->get_log_trx_trace(trace))); + num_failed++; + } + } else { + trx_tracker.trx_success(); + 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())("txid", trx_id)("r", end - start) + ("a", get_first_authorizer(trace))("cpu", trace->receipt ? trace->receipt->cpu_usage_us : 0)); + fc_dlog(_trx_trace_success_log, + "[TRX_TRACE] Block ${block_num} for producer ${prod} is ACCEPTING scheduled tx: ${entire_trace}", + ("block_num", chain.head_block_num() + 1)("prod", get_pending_block_producer()) + ("entire_trace", chain_plug->get_log_trx_trace(trace))); + num_applied++; + } + } + LOG_AND_DROP(); + + if (expired_itr_next == expired_idx.end()) + break; + expired_itr = expired_idx.lower_bound(boost::make_tuple(next_expired, next_id)); + } + + if (expired_size > 0) { + fc_dlog(_log, "Processed ${m} of ${n} scheduled transactions, Applied ${applied}, Failed/Dropped ${failed}", + ("m", num_processed)("n", expired_size)("applied", num_applied)("failed", num_failed)); + } +} + bool producer_plugin_impl::process_incoming_trxs(const fc::time_point& deadline, unapplied_transaction_queue::iterator& itr) { bool exhausted = false; auto end = _unapplied_transactions.incoming_end(); From c495ab10457103db94416566bd9411fe339f6050 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Mon, 18 Sep 2023 16:13:54 -0400 Subject: [PATCH 04/29] use >= for expiration check and logging improvement --- plugins/producer_plugin/producer_plugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index fde53a32a7..a04df6c0ec 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -2315,7 +2315,7 @@ void producer_plugin_impl::retire_expired_deferred_trxs(const fc::time_point& de auto expired_itr = expired_idx.begin(); while (expired_itr != expired_idx.end()) { - if (expired_itr->expiration > pending_block_time) { + if (expired_itr->expiration >= pending_block_time) { break; // not expired yet } @@ -2385,7 +2385,7 @@ void producer_plugin_impl::retire_expired_deferred_trxs(const fc::time_point& de } if (expired_size > 0) { - fc_dlog(_log, "Processed ${m} of ${n} scheduled transactions, Applied ${applied}, Failed/Dropped ${failed}", + fc_dlog(_log, "Processed ${m} of ${n} expired scheduled transactions, Applied ${applied}, Failed/Dropped ${failed}", ("m", num_processed)("n", expired_size)("applied", num_applied)("failed", num_failed)); } } From eeea80de41a5491a7b67fa339558913c596ccc27 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Mon, 18 Sep 2023 16:41:22 -0400 Subject: [PATCH 05/29] add back missing num_processed++; --- plugins/producer_plugin/producer_plugin.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index a04df6c0ec..c1f79f6135 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -2324,6 +2324,14 @@ void producer_plugin_impl::retire_expired_deferred_trxs(const fc::time_point& de break; } + const transaction_id_type trx_id = expired_itr->trx_id; // make copy since reference could be invalidated + auto expired_itr_next = expired_itr; // save off next since expired_itr may be invalidated by loop + ++expired_itr_next; + const auto next_expired = expired_itr_next != expired_idx.end() ? expired_itr_next->expiration : expired_itr->expiration; + const auto next_id = expired_itr_next != expired_idx.end() ? expired_itr_next->id : expired_itr->id; + + num_processed++; + auto get_first_authorizer = [&](const transaction_trace_ptr& trace) { for (const auto& a : trace->action_traces) { for (const auto& u : a.act.authorization) @@ -2332,12 +2340,6 @@ void producer_plugin_impl::retire_expired_deferred_trxs(const fc::time_point& de return account_name(); }; - const transaction_id_type trx_id = expired_itr->trx_id; // make copy since reference could be invalidated - auto expired_itr_next = expired_itr; // save off next since expired_itr may be invalidated by loop - ++expired_itr_next; - const auto next_expired = expired_itr_next != expired_idx.end() ? expired_itr_next->expiration : expired_itr->expiration; - const auto next_id = expired_itr_next != expired_idx.end() ? expired_itr_next->id : expired_itr->id; - try { auto start = fc::time_point::now(); auto trx_tracker = _time_tracker.start_trx(false, start); // delayed transaction cannot be transient From 076e18af1551d7f7c4521f849511d96b7f7f3ff8 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Mon, 18 Sep 2023 21:38:28 -0400 Subject: [PATCH 06/29] changedeferred_trxs_deadline to 10ms --- plugins/producer_plugin/producer_plugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index c1f79f6135..6cfe41b827 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -1957,8 +1957,8 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() { if (!process_unapplied_trxs(preprocess_deadline)) return start_block_result::exhausted; - // Hard-code the deadline to retire expired deferred trxs to 50ms - auto deferred_trxs_deadline = std::min(preprocess_deadline, fc::time_point::now() + fc::milliseconds(50)); + // Hard-code the deadline to retire expired deferred trxs to 10ms + auto deferred_trxs_deadline = std::min(preprocess_deadline, fc::time_point::now() + fc::milliseconds(10)); retire_expired_deferred_trxs(deferred_trxs_deadline); } From 840c05b811664b5820a672bbb87fe3d5a0e8b673 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Mon, 18 Sep 2023 22:14:40 -0400 Subject: [PATCH 07/29] block delayed transactions --- .../eosio/chain/transaction_context.hpp | 1 - libraries/chain/transaction_context.cpp | 45 +------------------ 2 files changed, 1 insertion(+), 45 deletions(-) diff --git a/libraries/chain/include/eosio/chain/transaction_context.hpp b/libraries/chain/include/eosio/chain/transaction_context.hpp index 430defce27..618d7bea80 100644 --- a/libraries/chain/include/eosio/chain/transaction_context.hpp +++ b/libraries/chain/include/eosio/chain/transaction_context.hpp @@ -112,7 +112,6 @@ namespace eosio { namespace chain { void execute_action( uint32_t action_ordinal, uint32_t recurse_depth ); - void schedule_transaction(); void record_transaction( const transaction_id_type& id, fc::time_point_sec expire ); void validate_cpu_usage_to_bill( int64_t billed_us, int64_t account_cpu_limit, bool check_minimum, int64_t subjective_billed_us )const; diff --git a/libraries/chain/transaction_context.cpp b/libraries/chain/transaction_context.cpp index 8c9e434d8f..9ea715e366 100644 --- a/libraries/chain/transaction_context.cpp +++ b/libraries/chain/transaction_context.cpp @@ -247,9 +247,7 @@ namespace eosio { namespace chain { uint64_t packed_trx_prunable_size ) { const transaction& trx = packed_trx.get_transaction(); - if ( is_transient() ) { - EOS_ASSERT( trx.delay_sec.value == 0, transaction_exception, "dry-run or read-only transaction cannot be delayed" ); - } + EOS_ASSERT( trx.delay_sec.value == 0, transaction_exception, "transaction cannot be delayed" ); if( trx.transaction_extensions.size() > 0 ) { disallow_transaction_extensions( "no transaction extensions supported yet for input transactions" ); } @@ -330,10 +328,6 @@ namespace eosio { namespace chain { for( uint32_t i = 1; i <= num_original_actions_to_execute; ++i ) { execute_action( i, 0 ); } - - if( delay != fc::microseconds() ) { - schedule_transaction(); - } } void transaction_context::finalize() { @@ -731,43 +725,6 @@ namespace eosio { namespace chain { acontext.exec(); } - - void transaction_context::schedule_transaction() { - // Charge ahead of time for the additional net usage needed to retire the delayed transaction - // whether that be by successfully executing, soft failure, hard failure, or expiration. - const transaction& trx = packed_trx.get_transaction(); - if( trx.delay_sec.value == 0 ) { // Do not double bill. Only charge if we have not already charged for the delay. - const auto& cfg = control.get_global_properties().configuration; - add_net_usage( static_cast(cfg.base_per_transaction_net_usage) - + static_cast(config::transaction_id_net_usage) ); // Will exit early if net usage cannot be payed. - } - - auto first_auth = trx.first_authorizer(); - - uint32_t trx_size = 0; - const auto& cgto = control.mutable_db().create( [&]( auto& gto ) { - gto.trx_id = id; - gto.payer = first_auth; - gto.sender = account_name(); /// delayed transactions have no sender - gto.sender_id = transaction_id_to_sender_id( gto.trx_id ); - gto.published = control.pending_block_time(); - gto.delay_until = gto.published + delay; - gto.expiration = gto.delay_until + fc::seconds(control.get_global_properties().configuration.deferred_trx_expiration_window); - trx_size = gto.set( trx ); - - if (auto dm_logger = control.get_deep_mind_logger(is_transient())) { - std::string event_id = RAM_EVENT_ID("${id}", ("id", gto.id)); - - dm_logger->on_create_deferred(deep_mind_handler::operation_qualifier::push, gto, packed_trx); - dm_logger->on_ram_trace(std::move(event_id), "deferred_trx", "push", "deferred_trx_pushed"); - } - }); - - int64_t ram_delta = (config::billable_size_v + trx_size); - add_ram_usage( cgto.payer, ram_delta ); - trace->account_ram_delta = account_delta( cgto.payer, ram_delta ); - } - void transaction_context::record_transaction( const transaction_id_type& id, fc::time_point_sec expire ) { try { control.mutable_db().create([&](transaction_object& transaction) { From fe45fc447390af8aaf0691eedd72d05be4122768 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Thu, 21 Sep 2023 08:13:56 -0400 Subject: [PATCH 08/29] add and update tests for blocking delayed transactions --- unittests/api_tests.cpp | 59 +- unittests/delay_tests.cpp | 2168 +------------------------- unittests/protocol_feature_tests.cpp | 176 --- 3 files changed, 43 insertions(+), 2360 deletions(-) diff --git a/unittests/api_tests.cpp b/unittests/api_tests.cpp index 673995ec18..7c84bcdbf1 100644 --- a/unittests/api_tests.cpp +++ b/unittests/api_tests.cpp @@ -767,47 +767,11 @@ BOOST_FIXTURE_TEST_CASE(cfa_stateful_api, validating_tester) try { BOOST_REQUIRE_EQUAL( validate(), true ); } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE(deferred_cfa_failed, validating_tester) try { +BOOST_FIXTURE_TEST_CASE(deferred_cfa_not_allowed, validating_tester) try { create_account( "testapi"_n ); - produce_blocks(1); - set_code( "testapi"_n, test_contracts::test_api_wasm() ); - - account_name a = "testapi2"_n; - account_name creator = config::system_account_name; - - signed_transaction trx; - - trx.actions.emplace_back( vector{{creator,config::active_name}}, - newaccount{ - .creator = creator, - .name = a, - .owner = authority( get_public_key( a, "owner" ) ), - .active = authority( get_public_key( a, "active" ) ) - }); - action act({}, test_api_action{}); - trx.context_free_actions.push_back(act); - set_transaction_headers(trx, 10, 2); - trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); - - BOOST_CHECK_EXCEPTION(push_transaction( trx ), fc::exception, - [&](const fc::exception &e) { - return expect_assert_message(e, "only context free api's can be used in this context"); - }); - - produce_blocks(10); - - // CFA failed, testapi2 not created - create_account( "testapi2"_n ); - - BOOST_REQUIRE_EQUAL( validate(), true ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(deferred_cfa_success, validating_tester) try { - - create_account( "testapi"_n ); - produce_blocks(1); - set_code( "testapi"_n, test_contracts::test_api_wasm() ); + produce_blocks(1); + set_code( "testapi"_n, test_contracts::test_api_wasm() ); account_name a = "testapi2"_n; account_name creator = config::system_account_name; @@ -823,22 +787,13 @@ BOOST_FIXTURE_TEST_CASE(deferred_cfa_success, validating_tester) try { }); action act({}, test_api_action{}); trx.context_free_actions.push_back(act); - set_transaction_headers(trx, 10, 2); + set_transaction_headers(trx, 10, 2); // set delay_sec to 2 trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); - auto trace = push_transaction( trx ); - BOOST_REQUIRE(trace != nullptr); - if (trace) { - BOOST_REQUIRE_EQUAL(transaction_receipt_header::status_enum::delayed, trace->receipt->status); - BOOST_REQUIRE_EQUAL(1, trace->action_traces.size()); - } - produce_blocks(10); - - // CFA success, testapi2 created - BOOST_CHECK_EXCEPTION(create_account( "testapi2"_n ), fc::exception, + BOOST_CHECK_EXCEPTION(push_transaction( trx ), fc::exception, [&](const fc::exception &e) { - return expect_assert_message(e, "Cannot create account named testapi2, as that name is already taken"); + // any incoming trx is blocked + return expect_assert_message(e, "transaction cannot be delayed"); }); - BOOST_REQUIRE_EQUAL( validate(), true ); } FC_LOG_AND_RETHROW() BOOST_AUTO_TEST_CASE(light_validation_skip_cfa) try { diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index 5b229e48d2..35e0301103 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -12,11 +12,10 @@ using namespace eosio; using namespace eosio::chain; using namespace eosio::testing; - BOOST_AUTO_TEST_SUITE(delay_tests) -BOOST_FIXTURE_TEST_CASE( delay_create_account, validating_tester) { try { - +// Delayed trxs are blocked. +BOOST_FIXTURE_TEST_CASE( delayed_trx, validating_tester) { try { produce_blocks(2); signed_transaction trx; @@ -35,58 +34,23 @@ BOOST_FIXTURE_TEST_CASE( delay_create_account, validating_tester) { try { trx.delay_sec = 3; trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); - auto trace = push_transaction( trx ); - - produce_blocks(8); - -} FC_LOG_AND_RETHROW() } - - -BOOST_FIXTURE_TEST_CASE( delay_error_create_account, validating_tester) { try { - - produce_blocks(2); - signed_transaction trx; - - account_name a = "newco"_n; - account_name creator = config::system_account_name; - - auto owner_auth = authority( get_public_key( a, "owner" ) ); - trx.actions.emplace_back( vector{{creator,config::active_name}}, - newaccount{ - .creator = "bad"_n, /// a does not exist, this should error when execute - .name = a, - .owner = owner_auth, - .active = authority( get_public_key( a, "active" ) ) - }); - set_transaction_headers(trx); - trx.delay_sec = 3; - trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); - - ilog( fc::json::to_pretty_string(trx) ); - auto trace = push_transaction( trx ); - edump((*trace)); - - produce_blocks(6); - - auto scheduled_trxs = get_scheduled_transactions(); - BOOST_REQUIRE_EQUAL(scheduled_trxs.size(), 1u); - - auto billed_cpu_time_us = control->get_global_properties().configuration.min_transaction_cpu_usage; - auto dtrace = control->push_scheduled_transaction(scheduled_trxs.front(), fc::time_point::maximum(), fc::microseconds::maximum(), billed_cpu_time_us, true); - BOOST_REQUIRE_EQUAL(dtrace->except.has_value(), true); - BOOST_REQUIRE_EQUAL(dtrace->except->code(), missing_auth_exception::code_value); + // delayed trx is blocked + BOOST_CHECK_EXCEPTION(push_transaction( trx ), fc::exception, + [&](const fc::exception &e) { + // any incoming trx is blocked + return expect_assert_message(e, "transaction cannot be delayed"); + }); } FC_LOG_AND_RETHROW() } - asset get_currency_balance(const validating_tester& chain, account_name account) { return chain.get_currency_balance("eosio.token"_n, symbol(SY(4,CUR)), account); } const std::string eosio_token = name("eosio.token"_n).to_string(); -// test link to permission with delay directly on it -BOOST_AUTO_TEST_CASE( link_delay_direct_test ) { try { +// Delayed actions are blocked. +BOOST_AUTO_TEST_CASE( delayed_action ) { try { validating_tester chain; const auto& tester_account = "tester"_n; @@ -120,7 +84,6 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_test ) { try { ("maximum_supply", "9000000.0000 CUR") ); - chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() ("to", eosio_token) ("quantity", "1000000.0000 CUR") @@ -176,54 +139,21 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_test ) { try { chain.produce_blocks(); - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "3.0000 CUR") - ("memo", "hi" ), - 20, 10 - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(1u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(18); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("96.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("4.0000 CUR"), liquid_balance); - + BOOST_CHECK_EXCEPTION( + chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() + ("from", "tester") + ("to", "tester2") + ("quantity", "3.0000 CUR") + ("memo", "hi" ), + 20, 10 + ), + fc::exception, + [&](const fc::exception &e) { + // any delayed incoming trx is blocked + return expect_assert_message(e, "transaction cannot be delayed"); + }); } FC_LOG_AND_RETHROW() }/// schedule_test - BOOST_AUTO_TEST_CASE(delete_auth_test) { try { validating_tester chain; @@ -359,2049 +289,23 @@ BOOST_AUTO_TEST_CASE(delete_auth_test) { try { } FC_LOG_AND_RETHROW() }/// delete_auth_test +BOOST_AUTO_TEST_CASE( test_blockchain_params_enabled ) { try { + //since validation_tester activates all features here we will test how setparams works without + //blockchain_parameters enabled + tester chain( setup_policy::preactivate_feature_and_new_bios ); -// test link to permission with delay on permission which is parent of min permission (special logic in permission_object::satisfies) -BOOST_AUTO_TEST_CASE( link_delay_direct_parent_permission_test ) { try { - validating_tester chain; - - const auto& tester_account = "tester"_n; - - chain.produce_blocks(); - chain.create_account("eosio.token"_n); - chain.produce_blocks(10); - - chain.set_code("eosio.token"_n, test_contracts::eosio_token_wasm()); - chain.set_abi("eosio.token"_n, test_contracts::eosio_token_abi()); - - chain.produce_blocks(); - chain.create_account("tester"_n); - chain.create_account("tester2"_n); - chain.produce_blocks(10); - - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"))) - ); - chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer") - ("requirement", "first")); - - chain.produce_blocks(); - chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() - ("issuer", eosio_token) - ("maximum_supply", "9000000.0000 CUR") - ); - - chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() - ("to", eosio_token) - ("quantity", "1000000.0000 CUR") - ("memo", "for stuff") - ); - - auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() - ("from", eosio_token) - ("to", "tester") - ("quantity", "100.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - auto gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - chain.produce_blocks(); - - auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "1.0000 CUR") - ("memo", "hi" ) - ); - - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - trace = chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "active") - ("parent", "owner") - ("auth", authority(chain.get_public_key(tester_account, "active"), 15)) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - chain.produce_blocks(); - - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "3.0000 CUR") - ("memo", "hi" ), - 20, 15 - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(1u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(28); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("96.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("4.0000 CUR"), liquid_balance); - -} FC_LOG_AND_RETHROW() }/// schedule_test - -// test link to permission with delay on permission between min permission and authorizing permission it -BOOST_AUTO_TEST_CASE( link_delay_direct_walk_parent_permissions_test ) { try { - validating_tester chain; - - const auto& tester_account = "tester"_n; - - chain.produce_blocks(); - chain.create_account("eosio.token"_n); - chain.produce_blocks(10); - - chain.set_code("eosio.token"_n, test_contracts::eosio_token_wasm()); - chain.set_abi("eosio.token"_n, test_contracts::eosio_token_abi()); - - chain.produce_blocks(); - chain.create_account("tester"_n); - chain.create_account("tester2"_n); - chain.produce_blocks(10); - - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"))) - ); - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "second") - ("parent", "first") - ("auth", authority(chain.get_public_key(tester_account, "second"))) - ); - chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer") - ("requirement", "second")); + //change max_transaction_delay to 60 sec + auto params = chain.control->get_global_properties().configuration; + params.max_transaction_delay = 60; + chain.push_action(config::system_account_name, + "setparams"_n, + config::system_account_name, + mutable_variant_object()("params", params) ); + + BOOST_CHECK_EQUAL(chain.control->get_global_properties().configuration.max_transaction_delay, 60u); chain.produce_blocks(); - chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() - ("issuer", eosio_token) - ("maximum_supply", "9000000.0000 CUR") - ); - - chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() - ("to", eosio_token) - ("quantity", "1000000.0000 CUR") - ("memo", "for stuff") - ); - - auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() - ("from", eosio_token) - ("to", "tester") - ("quantity", "100.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - auto gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - chain.produce_blocks(); - - auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "1.0000 CUR") - ("memo", "hi" ) - ); - - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - trace = chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"), 20)) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - chain.produce_blocks(); - - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "3.0000 CUR") - ("memo", "hi" ), - 30, 20 - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(1u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(38); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("96.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("4.0000 CUR"), liquid_balance); - -} FC_LOG_AND_RETHROW() }/// schedule_test - -// test removing delay on permission -BOOST_AUTO_TEST_CASE( link_delay_permission_change_test ) { try { - validating_tester chain; - - const auto& tester_account = "tester"_n; - - chain.produce_blocks(); - chain.create_account("eosio.token"_n); - chain.produce_blocks(10); - - chain.set_code("eosio.token"_n, test_contracts::eosio_token_wasm()); - chain.set_abi("eosio.token"_n, test_contracts::eosio_token_abi()); - - chain.produce_blocks(); - chain.create_account("tester"_n); - chain.create_account("tester2"_n); - chain.produce_blocks(10); - - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"), 10)) - ); - chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer") - ("requirement", "first")); - - chain.produce_blocks(); - chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() - ("issuer", eosio_token ) - ("maximum_supply", "9000000.0000 CUR" ) - ); - - chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() - ("to", eosio_token) - ("quantity", "1000000.0000 CUR") - ("memo", "for stuff") - ); - - auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() - ("from", eosio_token) - ("to", "tester") - ("quantity", "100.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - auto gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - chain.produce_blocks(); - - auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - - // this transaction will be delayed 20 blocks - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "1.0000 CUR") - ("memo", "hi" ), - 30, 10 - ); - - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(1u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // this transaction will be delayed 20 blocks - trace = chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"))), - 30, 10); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(2u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - chain.produce_blocks(16); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // this transaction will be delayed 20 blocks - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "5.0000 CUR") - ("memo", "hi" ), - 30, 10 - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(3u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // first transfer will finally be performed - chain.produce_blocks(); - - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(2u, gen_size); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - // delayed update auth removing the delay will finally execute - chain.produce_blocks(); - - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(1u, gen_size); - - // this transfer is performed right away since delay is removed - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "10.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); - - chain.produce_blocks(15); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); - - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(1u, gen_size); - - // second transfer finally is performed - chain.produce_blocks(); - - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(0u, gen_size); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("84.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("16.0000 CUR"), liquid_balance); - -} FC_LOG_AND_RETHROW() }/// schedule_test - -// test removing delay on permission based on heirarchy delay -BOOST_AUTO_TEST_CASE( link_delay_permission_change_with_delay_heirarchy_test ) { try { - validating_tester chain; - - const auto& tester_account = "tester"_n; - - chain.produce_blocks(); - chain.create_account("eosio.token"_n); - chain.produce_blocks(10); - - chain.set_code("eosio.token"_n, test_contracts::eosio_token_wasm()); - chain.set_abi("eosio.token"_n, test_contracts::eosio_token_abi()); - - chain.produce_blocks(); - chain.create_account("tester"_n); - chain.create_account("tester2"_n); - chain.produce_blocks(10); - - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"), 10)) - ); - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "second") - ("parent", "first") - ("auth", authority(chain.get_public_key(tester_account, "second"))) - ); - chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer") - ("requirement", "second")); - - chain.produce_blocks(); - chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() - ("issuer", eosio_token) - ("maximum_supply", "9000000.0000 CUR" ) - ); - - chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() - ("to", eosio_token) - ("quantity", "1000000.0000 CUR") - ("memo", "for stuff") - ); - - auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() - ("from", eosio_token) - ("to", "tester") - ("quantity", "100.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - auto gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - chain.produce_blocks(); - - auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - - // this transaction will be delayed 20 blocks - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "1.0000 CUR") - ("memo", "hi" ), - 30, 10 - ); - - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(1u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // this transaction will be delayed 20 blocks - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"))), - 30, 10 - ); - - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(2u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - chain.produce_blocks(16); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // this transaction will be delayed 20 blocks - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "5.0000 CUR") - ("memo", "hi" ), - 30, 10 - ); - - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(3u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // first transfer will finally be performed - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - // this transfer is performed right away since delay is removed - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "10.0000 CUR") - ("memo", "hi" ) - ); - - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(1u, gen_size); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); - - chain.produce_blocks(14); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); - - // second transfer finally is performed - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("84.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("16.0000 CUR"), liquid_balance); - -} FC_LOG_AND_RETHROW() }/// schedule_test - -// test moving link with delay on permission -BOOST_AUTO_TEST_CASE( link_delay_link_change_test ) { try { - validating_tester chain; - - const auto& tester_account = "tester"_n; - - chain.produce_blocks(); - chain.create_account("eosio.token"_n); - chain.produce_blocks(10); - - chain.set_code("eosio.token"_n, test_contracts::eosio_token_wasm()); - chain.set_abi("eosio.token"_n, test_contracts::eosio_token_abi()); - - chain.produce_blocks(); - chain.create_account("tester"_n); - chain.create_account("tester2"_n); - chain.produce_blocks(10); - - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"), 10)) - ); - chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer") - ("requirement", "first")); - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "second") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "second"))) - ); - - chain.produce_blocks(); - chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() - ("issuer", eosio_token) - ("maximum_supply", "9000000.0000 CUR" ) - ); - - chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() - ("to", eosio_token) - ("quantity", "1000000.0000 CUR") - ("memo", "for stuff") - ); - - auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() - ("from", eosio_token) - ("to", "tester") - ("quantity", "100.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - auto gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - chain.produce_blocks(); - - auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - - // this transaction will be delayed 20 blocks - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "1.0000 CUR") - ("memo", "hi" ), - 30, 10 - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(1u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - BOOST_REQUIRE_EXCEPTION( - chain.push_action( config::system_account_name, linkauth::get_name(), - vector{permission_level{tester_account, "first"_n}}, - fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer") - ("requirement", "second"), - 30, 3), - unsatisfied_authorization, - fc_exception_message_starts_with("transaction declares authority") - ); - - // this transaction will be delayed 20 blocks - chain.push_action( config::system_account_name, linkauth::get_name(), - vector{{tester_account, "first"_n}}, - fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer") - ("requirement", "second"), - 30, 10 - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(2u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - chain.produce_blocks(16); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // this transaction will be delayed 20 blocks - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "5.0000 CUR") - ("memo", "hi" ), - 30, 10 - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(3u, gen_size); - BOOST_CHECK_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // first transfer will finally be performed - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - // delay on minimum permission of transfer is finally removed - chain.produce_blocks(); - - // this transfer is performed right away since delay is removed - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "10.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(1u, gen_size); - - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); - - chain.produce_blocks(16); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); - - // second transfer finally is performed - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("84.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("16.0000 CUR"), liquid_balance); - -} FC_LOG_AND_RETHROW() }/// schedule_test - - -// test link with unlink -BOOST_AUTO_TEST_CASE( link_delay_unlink_test ) { try { - validating_tester chain; - - const auto& tester_account = "tester"_n; - - chain.produce_blocks(); - chain.create_account("eosio.token"_n); - chain.produce_blocks(10); - - chain.set_code("eosio.token"_n, test_contracts::eosio_token_wasm()); - chain.set_abi("eosio.token"_n, test_contracts::eosio_token_abi()); - - chain.produce_blocks(); - chain.create_account("tester"_n); - chain.create_account("tester2"_n); - chain.produce_blocks(10); - - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"), 10)) - ); - chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer") - ("requirement", "first")); - - chain.produce_blocks(); - chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() - ("issuer", eosio_token ) - ("maximum_supply", "9000000.0000 CUR" ) - ); - - chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() - ("to", eosio_token) - ("quantity", "1000000.0000 CUR") - ("memo", "for stuff") - ); - - auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() - ("from", eosio_token) - ("to", "tester") - ("quantity", "100.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - - chain.produce_blocks(); - - auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - - // this transaction will be delayed 20 blocks - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "1.0000 CUR") - ("memo", "hi" ), - 30, 10 - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - auto gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(1u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - BOOST_REQUIRE_EXCEPTION( - chain.push_action( config::system_account_name, unlinkauth::get_name(), - vector{{tester_account, "first"_n}}, - fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer"), - 30, 7 - ), - unsatisfied_authorization, - fc_exception_message_starts_with("transaction declares authority") - ); - - // this transaction will be delayed 20 blocks - chain.push_action(config::system_account_name, unlinkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer"), - 30, 10 - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(2u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - chain.produce_blocks(16); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // this transaction will be delayed 20 blocks - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "5.0000 CUR") - ("memo", "hi" ), - 30, 10 - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(3u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // first transfer will finally be performed - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - // the delayed unlinkauth finally occurs - chain.produce_blocks(); - - // this transfer is performed right away since delay is removed - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "10.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); - - chain.produce_blocks(15); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); - - // second transfer finally is performed - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("84.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("16.0000 CUR"), liquid_balance); - -} FC_LOG_AND_RETHROW() }/// link_delay_unlink_test - -// test moving link with delay on permission's parent -BOOST_AUTO_TEST_CASE( link_delay_link_change_heirarchy_test ) { try { - validating_tester chain; - - const auto& tester_account = "tester"_n; - - chain.produce_blocks(); - chain.create_account("eosio.token"_n); - chain.produce_blocks(10); - - chain.set_code("eosio.token"_n, test_contracts::eosio_token_wasm()); - chain.set_abi("eosio.token"_n, test_contracts::eosio_token_abi()); - - chain.produce_blocks(); - chain.create_account("tester"_n); - chain.create_account("tester2"_n); - chain.produce_blocks(10); - - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"), 10)) - ); - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "second") - ("parent", "first") - ("auth", authority(chain.get_public_key(tester_account, "first"))) - ); - chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer") - ("requirement", "second")); - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "third") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "third"))) - ); - - chain.produce_blocks(); - chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() - ("issuer", eosio_token) - ("maximum_supply", "9000000.0000 CUR" ) - ); - - chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() - ("to", eosio_token) - ("quantity", "1000000.0000 CUR") - ("memo", "for stuff") - ); - - auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() - ("from", eosio_token) - ("to", "tester") - ("quantity", "100.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - auto gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - chain.produce_blocks(); - - auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - - // this transaction will be delayed 20 blocks - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "1.0000 CUR") - ("memo", "hi" ), - 30, 10 - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(1u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // this transaction will be delayed 20 blocks - chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer") - ("requirement", "third"), - 30, 10 - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(2u, gen_size); - BOOST_CHECK_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - chain.produce_blocks(16); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // this transaction will be delayed 20 blocks - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "5.0000 CUR") - ("memo", "hi" ), - 30, 10 - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(3u, gen_size); - BOOST_CHECK_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // first transfer will finally be performed - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - // delay on minimum permission of transfer is finally removed - chain.produce_blocks(); - - // this transfer is performed right away since delay is removed - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "10.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(1u, gen_size); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); - - chain.produce_blocks(16); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); - - // second transfer finally is performed - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("84.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("16.0000 CUR"), liquid_balance); - -} FC_LOG_AND_RETHROW() } /// link_delay_link_change_heirarchy_test - -// test delay_sec field imposing unneeded delay -BOOST_AUTO_TEST_CASE( mindelay_test ) { try { - validating_tester chain; - - chain.produce_blocks(); - chain.create_account("eosio.token"_n); - chain.produce_blocks(10); - - chain.set_code("eosio.token"_n, test_contracts::eosio_token_wasm()); - chain.set_abi("eosio.token"_n, test_contracts::eosio_token_abi()); - - chain.produce_blocks(); - chain.create_account("tester"_n); - chain.create_account("tester2"_n); - chain.produce_blocks(10); - - chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() - ("issuer", eosio_token) - ("maximum_supply", "9000000.0000 CUR") - ); - - chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() - ("to", eosio_token) - ("quantity", "1000000.0000 CUR") - ("memo", "for stuff") - ); - - auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() - ("from", eosio_token) - ("to", "tester") - ("quantity", "100.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - auto gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - chain.produce_blocks(); - - auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "1.0000 CUR") - ("memo", "hi" ) - ); - - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - // send transfer with delay_sec set to 10 - const auto& acnt = chain.control->db().get("eosio.token"_n); - auto abi = acnt.get_abi(); - chain::abi_serializer abis(std::move(abi), abi_serializer::create_yield_function( chain.abi_serializer_max_time )); - const auto a = chain.control->db().get("eosio.token"_n).get_abi(); - - string action_type_name = abis.get_action_type(name("transfer")); - - action act; - act.account = "eosio.token"_n; - act.name = name("transfer"); - act.authorization.push_back(permission_level{"tester"_n, config::active_name}); - act.data = abis.variant_to_binary(action_type_name, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "3.0000 CUR") - ("memo", "hi" ), - abi_serializer::create_yield_function( chain.abi_serializer_max_time ) - ); - - signed_transaction trx; - trx.actions.push_back(act); - - chain.set_transaction_headers(trx, 30, 10); - trx.sign(chain.get_private_key("tester"_n, "active"), chain.control->get_chain_id()); - trace = chain.push_transaction(trx); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(1u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(18); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("96.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("4.0000 CUR"), liquid_balance); - -} FC_LOG_AND_RETHROW() }/// schedule_test - -// test canceldelay action cancelling a delayed transaction -BOOST_AUTO_TEST_CASE( canceldelay_test ) { try { - validating_tester chain; - const auto& tester_account = "tester"_n; - std::vector ids; - - chain.produce_blocks(); - chain.create_account("eosio.token"_n); - chain.produce_blocks(10); - - chain.set_code("eosio.token"_n, test_contracts::eosio_token_wasm()); - chain.set_abi("eosio.token"_n, test_contracts::eosio_token_abi()); - - chain.produce_blocks(); - chain.create_account("tester"_n); - chain.create_account("tester2"_n); - chain.produce_blocks(10); - - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"), 10)) - ); - chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer") - ("requirement", "first")); - - chain.produce_blocks(); - chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() - ("issuer", eosio_token) - ("maximum_supply", "9000000.0000 CUR") - ); - - chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() - ("to", eosio_token) - ("quantity", "1000000.0000 CUR") - ("memo", "for stuff") - ); - - auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() - ("from", eosio_token) - ("to", "tester") - ("quantity", "100.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - auto gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - chain.produce_blocks(); - auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - - // this transaction will be delayed 20 blocks - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "1.0000 CUR") - ("memo", "hi" ), - 30, 10 - ); - //wdump((fc::json::to_pretty_string(trace))); - ids.push_back(trace->id); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(1u, gen_size); - BOOST_CHECK_EQUAL(0u, trace->action_traces.size()); - - const auto& idx = chain.control->db().get_index(); - auto itr = idx.find( trace->id ); - BOOST_CHECK_EQUAL( (itr != idx.end()), true ); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - BOOST_REQUIRE_EXCEPTION( - chain.push_action( config::system_account_name, - updateauth::get_name(), - vector{{tester_account, "first"_n}}, - fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"))), - 30, 7 - ), - unsatisfied_authorization, - fc_exception_message_starts_with("transaction declares authority") - ); - - // this transaction will be delayed 20 blocks - trace = chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"))), - 30, 10 - ); - //wdump((fc::json::to_pretty_string(trace))); - ids.push_back(trace->id); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(2u, gen_size); - BOOST_CHECK_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - chain.produce_blocks(16); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // this transaction will be delayed 20 blocks - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "5.0000 CUR") - ("memo", "hi" ), - 30, 10 - ); - //wdump((fc::json::to_pretty_string(trace))); - ids.push_back(trace->id); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(3u, gen_size); - BOOST_CHECK_EQUAL(0u, trace->action_traces.size()); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // send canceldelay for first delayed transaction - signed_transaction trx; - trx.actions.emplace_back(vector{{"tester"_n, config::active_name}}, - chain::canceldelay{{"tester"_n, config::active_name}, ids[0]}); - - chain.set_transaction_headers(trx); - trx.sign(chain.get_private_key("tester"_n, "active"), chain.control->get_chain_id()); - // first push as a dry_run trx - trace = chain.push_transaction(trx, fc::time_point::maximum(), base_tester::DEFAULT_BILLED_CPU_TIME_US, false, transaction_metadata::trx_type::dry_run); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - // now push for real - trace = chain.push_transaction(trx); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(2u, gen_size); - - const auto& cidx = chain.control->db().get_index(); - auto citr = cidx.find( ids[0] ); - BOOST_CHECK_EQUAL( (citr == cidx.end()), true ); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(2u, gen_size); - - chain.produce_blocks(); - - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(2u, gen_size); - - chain.produce_blocks(); - // update auth will finally be performed - - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(1u, gen_size); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // this transfer is performed right away since delay is removed - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "10.0000 CUR") - ("memo", "hi" ) - ); - //wdump((fc::json::to_pretty_string(trace))); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(1u, gen_size); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("90.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("10.0000 CUR"), liquid_balance); - - chain.produce_blocks(15); - - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(1u, gen_size); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("90.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("10.0000 CUR"), liquid_balance); - - // second transfer finally is performed - chain.produce_blocks(); - - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(0u, gen_size); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("85.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("15.0000 CUR"), liquid_balance); -} FC_LOG_AND_RETHROW() } - -// test canceldelay action under different permission levels -BOOST_AUTO_TEST_CASE( canceldelay_test2 ) { try { - validating_tester chain; - - const auto& tester_account = "tester"_n; - - chain.produce_blocks(); - chain.create_account("eosio.token"_n); - chain.produce_blocks(); - - chain.set_code("eosio.token"_n, test_contracts::eosio_token_wasm()); - chain.set_abi("eosio.token"_n, test_contracts::eosio_token_abi()); - - chain.produce_blocks(); - chain.create_account("tester"_n); - chain.create_account("tester2"_n); - chain.produce_blocks(); - - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"), 5)) - ); - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "second") - ("parent", "first") - ("auth", authority(chain.get_public_key(tester_account, "second"))) - ); - chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer") - ("requirement", "first")); - - chain.produce_blocks(); - chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() - ("issuer", eosio_token) - ("maximum_supply", "9000000.0000 CUR") - ); - - chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() - ("to", eosio_token) - ("quantity", "1000000.0000 CUR") - ("memo", "for stuff") - ); - - auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() - ("from", eosio_token) - ("to", "tester") - ("quantity", "100.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - auto gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - chain.produce_blocks(); - auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - - ilog("attempting first delayed transfer"); - - { - // this transaction will be delayed 10 blocks - trace = chain.push_action("eosio.token"_n, name("transfer"), vector{{"tester"_n, "first"_n}}, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "1.0000 CUR") - ("memo", "hi" ), - 30, 5 - ); - auto trx_id = trace->id; - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(1u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - const auto& idx = chain.control->db().get_index(); - auto itr = idx.find( trx_id ); - BOOST_CHECK_EQUAL( (itr != idx.end()), true ); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // attempt canceldelay with wrong canceling_auth for delayed transfer of 1.0000 CUR - { - signed_transaction trx; - trx.actions.emplace_back(vector{{"tester"_n, config::active_name}}, - chain::canceldelay{{"tester"_n, config::active_name}, trx_id}); - chain.set_transaction_headers(trx); - trx.sign(chain.get_private_key("tester"_n, "active"), chain.control->get_chain_id()); - BOOST_REQUIRE_EXCEPTION( chain.push_transaction(trx), action_validate_exception, - fc_exception_message_is("canceling_auth in canceldelay action was not found as authorization in the original delayed transaction") ); - } - - // attempt canceldelay with "second" permission for delayed transfer of 1.0000 CUR - { - signed_transaction trx; - trx.actions.emplace_back(vector{{"tester"_n, "second"_n}}, - chain::canceldelay{{"tester"_n, "first"_n}, trx_id}); - chain.set_transaction_headers(trx); - trx.sign(chain.get_private_key("tester"_n, "second"), chain.control->get_chain_id()); - BOOST_REQUIRE_THROW( chain.push_transaction(trx), irrelevant_auth_exception ); - BOOST_REQUIRE_EXCEPTION( chain.push_transaction(trx), irrelevant_auth_exception, - fc_exception_message_starts_with("canceldelay action declares irrelevant authority") ); - } - - // canceldelay with "active" permission for delayed transfer of 1.0000 CUR - signed_transaction trx; - trx.actions.emplace_back(vector{{"tester"_n, config::active_name}}, - chain::canceldelay{{"tester"_n, "first"_n}, trx_id}); - chain.set_transaction_headers(trx); - trx.sign(chain.get_private_key("tester"_n, "active"), chain.control->get_chain_id()); - trace = chain.push_transaction(trx); - - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - const auto& cidx = chain.control->db().get_index(); - auto citr = cidx.find( trx_id ); - BOOST_REQUIRE_EQUAL( (citr == cidx.end()), true ); - - chain.produce_blocks(10); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - } - - ilog("reset minimum permission of transfer to second permission"); - - chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer") - ("requirement", "second"), - 30, 5 - ); - - chain.produce_blocks(11); - - - ilog("attempting second delayed transfer"); - { - // this transaction will be delayed 10 blocks - trace = chain.push_action("eosio.token"_n, name("transfer"), vector{{"tester"_n, "second"_n}}, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "5.0000 CUR") - ("memo", "hi" ), - 30, 5 - ); - auto trx_id = trace->id; - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - auto gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(1u, gen_size); - BOOST_CHECK_EQUAL(0u, trace->action_traces.size()); - - const auto& idx = chain.control->db().get_index(); - auto itr = idx.find( trx_id ); - BOOST_CHECK_EQUAL( (itr != idx.end()), true ); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // canceldelay with "first" permission for delayed transfer of 5.0000 CUR - signed_transaction trx; - trx.actions.emplace_back(vector{{"tester"_n, "first"_n}}, - chain::canceldelay{{"tester"_n, "second"_n}, trx_id}); - chain.set_transaction_headers(trx); - trx.sign(chain.get_private_key("tester"_n, "first"), chain.control->get_chain_id()); - trace = chain.push_transaction(trx); - - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - const auto& cidx = chain.control->db().get_index(); - auto citr = cidx.find( trx_id ); - BOOST_REQUIRE_EQUAL( (citr == cidx.end()), true ); - - chain.produce_blocks(10); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - } - - ilog("attempting third delayed transfer"); - - { - // this transaction will be delayed 10 blocks - trace = chain.push_action("eosio.token"_n, name("transfer"), vector{{"tester"_n, config::owner_name}}, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "10.0000 CUR") - ("memo", "hi" ), - 30, 5 - ); - auto trx_id = trace->id; - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(1u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - const auto& idx = chain.control->db().get_index(); - auto itr = idx.find( trx_id ); - BOOST_CHECK_EQUAL( (itr != idx.end()), true ); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - - // attempt canceldelay with "active" permission for delayed transfer of 10.0000 CUR - { - signed_transaction trx; - trx.actions.emplace_back(vector{{"tester"_n, "active"_n}}, - chain::canceldelay{{"tester"_n, config::owner_name}, trx_id}); - chain.set_transaction_headers(trx); - trx.sign(chain.get_private_key("tester"_n, "active"), chain.control->get_chain_id()); - BOOST_REQUIRE_THROW( chain.push_transaction(trx), irrelevant_auth_exception ); - } - - // canceldelay with "owner" permission for delayed transfer of 10.0000 CUR - signed_transaction trx; - trx.actions.emplace_back(vector{{"tester"_n, config::owner_name}}, - chain::canceldelay{{"tester"_n, config::owner_name}, trx_id}); - chain.set_transaction_headers(trx); - trx.sign(chain.get_private_key("tester"_n, "owner"), chain.control->get_chain_id()); - trace = chain.push_transaction(trx); - - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - const auto& cidx = chain.control->db().get_index(); - auto citr = cidx.find( trx_id ); - BOOST_REQUIRE_EQUAL( (citr == cidx.end()), true ); - - chain.produce_blocks(10); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); - } -} FC_LOG_AND_RETHROW() } - - -BOOST_AUTO_TEST_CASE( max_transaction_delay_create ) { try { - //assuming max transaction delay is 45 days (default in config.hpp) - validating_tester chain; - - const auto& tester_account = "tester"_n; - - chain.produce_blocks(); - chain.create_account("tester"_n); - chain.produce_blocks(10); - - BOOST_REQUIRE_EXCEPTION( - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"), 50*86400)) ), // 50 days delay - action_validate_exception, - fc_exception_message_starts_with("Cannot set delay longer than max_transacton_delay") - ); -} FC_LOG_AND_RETHROW() } - - -BOOST_AUTO_TEST_CASE( max_transaction_delay_execute ) { try { - //assuming max transaction delay is 45 days (default in config.hpp) - validating_tester chain; - - const auto& tester_account = "tester"_n; - - chain.create_account("eosio.token"_n); - chain.set_code("eosio.token"_n, test_contracts::eosio_token_wasm()); - chain.set_abi("eosio.token"_n, test_contracts::eosio_token_abi()); - - chain.produce_blocks(); - chain.create_account("tester"_n); - - chain.produce_blocks(); - chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() - ("issuer", "eosio.token" ) - ("maximum_supply", "9000000.0000 CUR" ) - ); - chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() - ("to", "tester") - ("quantity", "100.0000 CUR") - ("memo", "for stuff") - ); - - //create a permission level with delay 30 days and associate it with token transfer - auto trace = chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"), 30*86400)) // 30 days delay - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - - trace = chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", "eosio.token") - ("type", "transfer") - ("requirement", "first")); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - - chain.produce_blocks(); - - //change max_transaction_delay to 60 sec - auto params = chain.control->get_global_properties().configuration; - params.max_transaction_delay = 60; - chain.push_action( config::system_account_name, "setparams"_n, config::system_account_name, mutable_variant_object() - ("params", params) ); - - chain.produce_blocks(); - //should be able to create transaction with delay 60 sec, despite permission delay being 30 days, because max_transaction_delay is 60 sec - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "eosio.token") - ("quantity", "9.0000 CUR") - ("memo", "" ), 120, 60); - BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace->receipt->status); - - chain.produce_blocks(); - - auto gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(1u, gen_size); - BOOST_REQUIRE_EQUAL(0u, trace->action_traces.size()); - - //check that the delayed transaction executed after after 60 sec - chain.produce_blocks(120); - gen_size = chain.control->db().get_index().size(); - BOOST_CHECK_EQUAL(0u, gen_size); - - //check that the transfer really happened - auto liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("91.0000 CUR"), liquid_balance); - -} FC_LOG_AND_RETHROW() } - -BOOST_AUTO_TEST_CASE( test_blockchain_params_enabled ) { try { - //since validation_tester activates all features here we will test how setparams works without - //blockchain_parameters enabled - tester chain( setup_policy::preactivate_feature_and_new_bios ); - - //change max_transaction_delay to 60 sec - auto params = chain.control->get_global_properties().configuration; - params.max_transaction_delay = 60; - chain.push_action(config::system_account_name, - "setparams"_n, - config::system_account_name, - mutable_variant_object()("params", params) ); - - BOOST_CHECK_EQUAL(chain.control->get_global_properties().configuration.max_transaction_delay, 60u); - - chain.produce_blocks(); - -} FC_LOG_AND_RETHROW() } - -BOOST_FIXTURE_TEST_CASE( delay_expired, validating_tester) { try { - - produce_blocks(2); - signed_transaction trx; - - account_name a = "newco"_n; - account_name creator = config::system_account_name; - - auto owner_auth = authority( get_public_key( a, "owner" ) ); - trx.actions.emplace_back( vector{{creator,config::active_name}}, - newaccount{ - .creator = creator, - .name = a, - .owner = owner_auth, - .active = authority( get_public_key( a, "active" ) ) - }); - set_transaction_headers(trx); - trx.delay_sec = 3; - trx.expiration = fc::time_point_sec{control->head_block_time() + fc::microseconds(1000000)}; - trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); - - auto trace = push_transaction( trx ); - - BOOST_REQUIRE_EQUAL(transaction_receipt_header::delayed, trace->receipt->status); - - signed_block_ptr sb = produce_block(); - - sb = produce_block(); - - BOOST_REQUIRE_EQUAL(transaction_receipt_header::delayed, trace->receipt->status); - produce_empty_block(fc::milliseconds(610 * 1000)); - sb = produce_block(); - BOOST_REQUIRE_EQUAL(1u, sb->transactions.size()); - BOOST_REQUIRE_EQUAL(transaction_receipt_header::expired, sb->transactions[0].status); - - create_account(a); // account can still be created } FC_LOG_AND_RETHROW() } - BOOST_AUTO_TEST_SUITE_END() diff --git a/unittests/protocol_feature_tests.cpp b/unittests/protocol_feature_tests.cpp index e167e13d6b..eec1dab57b 100644 --- a/unittests/protocol_feature_tests.cpp +++ b/unittests/protocol_feature_tests.cpp @@ -526,182 +526,6 @@ BOOST_AUTO_TEST_CASE( replace_deferred_test ) try { } FC_LOG_AND_RETHROW() -BOOST_AUTO_TEST_CASE( no_duplicate_deferred_id_test ) try { - tester c( setup_policy::preactivate_feature_and_new_bios ); - tester c2( setup_policy::none ); - - c.preactivate_builtin_protocol_features( {builtin_protocol_feature_t::crypto_primitives} ); - c.produce_block(); - c.create_accounts( {"alice"_n, "test"_n} ); - c.set_code( "test"_n, test_contracts::deferred_test_wasm() ); - c.set_abi( "test"_n, test_contracts::deferred_test_abi() ); - c.produce_block(); - - push_blocks( c, c2 ); - - c2.push_action( "test"_n, "defercall"_n, "alice"_n, fc::mutable_variant_object() - ("payer", "alice") - ("sender_id", 1) - ("contract", "test") - ("payload", 50) - ); - - c2.finish_block(); - - BOOST_CHECK_EXCEPTION( - c2.produce_block(), - fc::exception, - fc_exception_message_is( "no transaction extensions supported yet for deferred transactions" ) - ); - - c2.produce_empty_block( fc::minutes(10) ); - - transaction_trace_ptr trace0; - auto h2 = c2.control->applied_transaction.connect( [&](std::tuple x) { - auto& t = std::get<0>(x); - if( t && t->receipt && t->receipt->status == transaction_receipt::expired) { - trace0 = t; - } - } ); - - c2.produce_block(); - - h2.disconnect(); - - BOOST_REQUIRE( trace0 ); - - c.produce_block(); - - const auto& index = c.control->db().get_index(); - - transaction_trace_ptr trace1; - auto h = c.control->applied_transaction.connect( [&](std::tuple x) { - auto& t = std::get<0>(x); - if( t && t->receipt && t->receipt->status == transaction_receipt::executed) { - trace1 = t; - } - } ); - - BOOST_REQUIRE_EQUAL(0u, index.size()); - - c.push_action( config::system_account_name, "reqauth"_n, "alice"_n, fc::mutable_variant_object() - ("from", "alice"), - 5, 2 - ); - - BOOST_REQUIRE_EQUAL(1u, index.size()); - - c.produce_block(); - - BOOST_REQUIRE_EQUAL(1u, index.size()); - - const auto& pfm = c.control->get_protocol_feature_manager(); - - auto d1 = pfm.get_builtin_digest( builtin_protocol_feature_t::replace_deferred ); - BOOST_REQUIRE( d1 ); - auto d2 = pfm.get_builtin_digest( builtin_protocol_feature_t::no_duplicate_deferred_id ); - BOOST_REQUIRE( d2 ); - - c.push_action( "test"_n, "defercall"_n, "alice"_n, fc::mutable_variant_object() - ("payer", "alice") - ("sender_id", 1) - ("contract", "test") - ("payload", 42) - ); - BOOST_REQUIRE_EQUAL(2u, index.size()); - - c.preactivate_protocol_features( {*d1, *d2} ); - c.produce_block(); - // The deferred transaction with payload 42 that was scheduled prior to the activation of the protocol features should now be retired. - - BOOST_REQUIRE( trace1 ); - BOOST_REQUIRE_EQUAL(1u, index.size()); - - trace1 = nullptr; - - // Retire the delayed eosio::reqauth transaction. - c.produce_blocks(5); - BOOST_REQUIRE( trace1 ); - BOOST_REQUIRE_EQUAL(0u, index.size()); - - h.disconnect(); - - auto check_generation_context = []( auto&& data, - const transaction_id_type& sender_trx_id, - unsigned __int128 sender_id, - account_name sender ) - { - transaction trx; - fc::datastream ds1( data.data(), data.size() ); - fc::raw::unpack( ds1, trx ); - BOOST_REQUIRE_EQUAL( trx.transaction_extensions.size(), 1u ); - BOOST_REQUIRE_EQUAL( trx.transaction_extensions.back().first, 0u ); - - fc::datastream ds2( trx.transaction_extensions.back().second.data(), - trx.transaction_extensions.back().second.size() ); - - transaction_id_type actual_sender_trx_id; - fc::raw::unpack( ds2, actual_sender_trx_id ); - BOOST_CHECK_EQUAL( actual_sender_trx_id, sender_trx_id ); - - unsigned __int128 actual_sender_id; - fc::raw::unpack( ds2, actual_sender_id ); - BOOST_CHECK( actual_sender_id == sender_id ); - - uint64_t actual_sender; - fc::raw::unpack( ds2, actual_sender ); - BOOST_CHECK_EQUAL( account_name(actual_sender), sender ); - }; - - BOOST_CHECK_EXCEPTION( - c.push_action( "test"_n, "defercall"_n, "alice"_n, fc::mutable_variant_object() - ("payer", "alice") - ("sender_id", 1) - ("contract", "test") - ("payload", 77 ) - ), - ill_formed_deferred_transaction_generation_context, - fc_exception_message_is( "deferred transaction generaction context contains mismatching sender" ) - ); - - BOOST_REQUIRE_EQUAL(0u, index.size()); - - auto trace2 = c.push_action( "test"_n, "defercall"_n, "alice"_n, fc::mutable_variant_object() - ("payer", "alice") - ("sender_id", 1) - ("contract", "test") - ("payload", 40) - ); - - BOOST_REQUIRE_EQUAL(1u, index.size()); - - check_generation_context( index.begin()->packed_trx, - trace2->id, - ((static_cast("alice"_n.to_uint64_t()) << 64) | 1), - "test"_n ); - - c.produce_block(); - - BOOST_REQUIRE_EQUAL(0u, index.size()); - - auto trace3 = c.push_action( "test"_n, "defercall"_n, "alice"_n, fc::mutable_variant_object() - ("payer", "alice") - ("sender_id", 1) - ("contract", "test") - ("payload", 50) - ); - - BOOST_REQUIRE_EQUAL(1u, index.size()); - - check_generation_context( index.begin()->packed_trx, - trace3->id, - ((static_cast("alice"_n.to_uint64_t()) << 64) | 1), - "test"_n ); - - c.produce_block(); - -} FC_LOG_AND_RETHROW() - BOOST_AUTO_TEST_CASE( fix_linkauth_restriction ) { try { tester chain( setup_policy::preactivate_feature_and_new_bios ); From 4603c864495166b0d1ed8f3caf47ab67c01151d6 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Thu, 21 Sep 2023 12:47:59 -0400 Subject: [PATCH 09/29] remove delay member from transaction_context class --- libraries/chain/controller.cpp | 8 ++------ .../chain/include/eosio/chain/transaction_context.hpp | 1 - libraries/chain/transaction_context.cpp | 6 ++---- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 045f4a8691..f9c59f26b6 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -1583,14 +1583,12 @@ struct controller_impl { trx->packed_trx()->get_prunable_size() ); } - trx_context.delay = fc::seconds(trn.delay_sec); - if( check_auth ) { authorization.check_authorization( trn.actions, trx->recovered_keys(), {}, - trx_context.delay, + fc::seconds(trn.delay_sec), [&trx_context](){ trx_context.checktime(); }, false, trx->is_dry_run() @@ -1603,9 +1601,7 @@ struct controller_impl { trx->billed_cpu_time_us = trx_context.billed_cpu_time_us; if (!trx->implicit() && !trx->is_read_only()) { - transaction_receipt::status_enum s = (trx_context.delay == fc::seconds(0)) - ? transaction_receipt::executed - : transaction_receipt::delayed; + transaction_receipt::status_enum s = transaction_receipt::executed; trace->receipt = push_receipt(*trx->packed_trx(), s, trx_context.billed_cpu_time_us, trace->net_usage); std::get(pending->_block_stage)._pending_trx_metas.emplace_back(trx); } else { diff --git a/libraries/chain/include/eosio/chain/transaction_context.hpp b/libraries/chain/include/eosio/chain/transaction_context.hpp index 618d7bea80..18d3c31e65 100644 --- a/libraries/chain/include/eosio/chain/transaction_context.hpp +++ b/libraries/chain/include/eosio/chain/transaction_context.hpp @@ -142,7 +142,6 @@ namespace eosio { namespace chain { /// the maximum number of virtual CPU instructions of the transaction that can be safely billed to the billable accounts uint64_t initial_max_billable_cpu = 0; - fc::microseconds delay; bool is_input = false; bool apply_context_free = true; bool enforce_whiteblacklist = true; diff --git a/libraries/chain/transaction_context.cpp b/libraries/chain/transaction_context.cpp index 9ea715e366..ac97cf5648 100644 --- a/libraries/chain/transaction_context.cpp +++ b/libraries/chain/transaction_context.cpp @@ -317,10 +317,8 @@ namespace eosio { namespace chain { } } - if( delay == fc::microseconds() ) { - for( const auto& act : trx.actions ) { - schedule_action( act, act.account, false, 0, 0 ); - } + for( const auto& act : trx.actions ) { + schedule_action( act, act.account, false, 0, 0 ); } auto& action_traces = trace->action_traces; From d99579178e47b38eac1ca0fdc599bd2e3d31b576 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Thu, 21 Sep 2023 13:18:18 -0400 Subject: [PATCH 10/29] remove final trx.delay_sec left behind in transaction_context.cpp --- libraries/chain/transaction_context.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/libraries/chain/transaction_context.cpp b/libraries/chain/transaction_context.cpp index ac97cf5648..cd6b872955 100644 --- a/libraries/chain/transaction_context.cpp +++ b/libraries/chain/transaction_context.cpp @@ -266,14 +266,6 @@ namespace eosio { namespace chain { uint64_t initial_net_usage = static_cast(cfg.base_per_transaction_net_usage) + packed_trx_unprunable_size + discounted_size_for_pruned_data; - - if( trx.delay_sec.value > 0 ) { - // If delayed, also charge ahead of time for the additional net usage needed to retire the delayed transaction - // whether that be by successfully executing, soft failure, hard failure, or expiration. - initial_net_usage += static_cast(cfg.base_per_transaction_net_usage) - + static_cast(config::transaction_id_net_usage); - } - published = control.pending_block_time(); is_input = true; if (!control.skip_trx_checks()) { From 0310c57001f33187ce09db3cb9290c6f59a776f2 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Sat, 23 Sep 2023 13:43:24 -0400 Subject: [PATCH 11/29] adapt protocol_feature_tests/no_duplicate_deferred_id_test for delay_sec removal instead of removing it outright --- unittests/protocol_feature_tests.cpp | 167 +++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) diff --git a/unittests/protocol_feature_tests.cpp b/unittests/protocol_feature_tests.cpp index eec1dab57b..f74df194b4 100644 --- a/unittests/protocol_feature_tests.cpp +++ b/unittests/protocol_feature_tests.cpp @@ -526,6 +526,173 @@ BOOST_AUTO_TEST_CASE( replace_deferred_test ) try { } FC_LOG_AND_RETHROW() +BOOST_AUTO_TEST_CASE( no_duplicate_deferred_id_test ) try { + tester c( setup_policy::preactivate_feature_and_new_bios ); + tester c2( setup_policy::none ); + + c.preactivate_builtin_protocol_features( {builtin_protocol_feature_t::crypto_primitives} ); + c.produce_block(); + c.create_accounts( {"alice"_n, "test"_n} ); + c.set_code( "test"_n, test_contracts::deferred_test_wasm() ); + c.set_abi( "test"_n, test_contracts::deferred_test_abi() ); + c.produce_block(); + + push_blocks( c, c2 ); + + c2.push_action( "test"_n, "defercall"_n, "alice"_n, fc::mutable_variant_object() + ("payer", "alice") + ("sender_id", 1) + ("contract", "test") + ("payload", 50) + ); + + c2.finish_block(); + + BOOST_CHECK_EXCEPTION( + c2.produce_block(), + fc::exception, + fc_exception_message_is( "no transaction extensions supported yet for deferred transactions" ) + ); + + c2.produce_empty_block( fc::minutes(10) ); + + transaction_trace_ptr trace0; + auto h2 = c2.control->applied_transaction.connect( [&](std::tuple x) { + auto& t = std::get<0>(x); + if( t && t->receipt && t->receipt->status == transaction_receipt::expired) { + trace0 = t; + } + } ); + + c2.produce_block(); + + h2.disconnect(); + + BOOST_REQUIRE( trace0 ); + + c.produce_block(); + + const auto& index = c.control->db().get_index(); + + transaction_trace_ptr trace1; + auto h = c.control->applied_transaction.connect( [&](std::tuple x) { + auto& t = std::get<0>(x); + if( t && t->receipt && t->receipt->status == transaction_receipt::executed) { + trace1 = t; + } + } ); + + BOOST_REQUIRE_EQUAL(0u, index.size()); + + BOOST_REQUIRE_EQUAL(0u, index.size()); + + const auto& pfm = c.control->get_protocol_feature_manager(); + + auto d1 = pfm.get_builtin_digest( builtin_protocol_feature_t::replace_deferred ); + BOOST_REQUIRE( d1 ); + auto d2 = pfm.get_builtin_digest( builtin_protocol_feature_t::no_duplicate_deferred_id ); + BOOST_REQUIRE( d2 ); + + c.push_action( "test"_n, "defercall"_n, "alice"_n, fc::mutable_variant_object() + ("payer", "alice") + ("sender_id", 1) + ("contract", "test") + ("payload", 42) + ); + BOOST_REQUIRE_EQUAL(1u, index.size()); + + c.preactivate_protocol_features( {*d1, *d2} ); + c.produce_block(); + // The deferred transaction with payload 42 that was scheduled prior to the activation of the protocol features should now be retired. + + BOOST_REQUIRE( trace1 ); + BOOST_REQUIRE_EQUAL(0u, index.size()); + + trace1 = nullptr; + + // Retire the delayed eosio::reqauth transaction. + c.produce_blocks(5); + BOOST_REQUIRE( trace1 ); + BOOST_REQUIRE_EQUAL(0u, index.size()); + + h.disconnect(); + + auto check_generation_context = []( auto&& data, + const transaction_id_type& sender_trx_id, + unsigned __int128 sender_id, + account_name sender ) + { + transaction trx; + fc::datastream ds1( data.data(), data.size() ); + fc::raw::unpack( ds1, trx ); + BOOST_REQUIRE_EQUAL( trx.transaction_extensions.size(), 1u ); + BOOST_REQUIRE_EQUAL( trx.transaction_extensions.back().first, 0u ); + + fc::datastream ds2( trx.transaction_extensions.back().second.data(), + trx.transaction_extensions.back().second.size() ); + + transaction_id_type actual_sender_trx_id; + fc::raw::unpack( ds2, actual_sender_trx_id ); + BOOST_CHECK_EQUAL( actual_sender_trx_id, sender_trx_id ); + + unsigned __int128 actual_sender_id; + fc::raw::unpack( ds2, actual_sender_id ); + BOOST_CHECK( actual_sender_id == sender_id ); + + uint64_t actual_sender; + fc::raw::unpack( ds2, actual_sender ); + BOOST_CHECK_EQUAL( account_name(actual_sender), sender ); + }; + + BOOST_CHECK_EXCEPTION( + c.push_action( "test"_n, "defercall"_n, "alice"_n, fc::mutable_variant_object() + ("payer", "alice") + ("sender_id", 1) + ("contract", "test") + ("payload", 77 ) + ), + ill_formed_deferred_transaction_generation_context, + fc_exception_message_is( "deferred transaction generaction context contains mismatching sender" ) + ); + + BOOST_REQUIRE_EQUAL(0u, index.size()); + + auto trace2 = c.push_action( "test"_n, "defercall"_n, "alice"_n, fc::mutable_variant_object() + ("payer", "alice") + ("sender_id", 1) + ("contract", "test") + ("payload", 40) + ); + + BOOST_REQUIRE_EQUAL(1u, index.size()); + + check_generation_context( index.begin()->packed_trx, + trace2->id, + ((static_cast("alice"_n.to_uint64_t()) << 64) | 1), + "test"_n ); + + c.produce_block(); + + BOOST_REQUIRE_EQUAL(0u, index.size()); + + auto trace3 = c.push_action( "test"_n, "defercall"_n, "alice"_n, fc::mutable_variant_object() + ("payer", "alice") + ("sender_id", 1) + ("contract", "test") + ("payload", 50) + ); + + BOOST_REQUIRE_EQUAL(1u, index.size()); + + check_generation_context( index.begin()->packed_trx, + trace3->id, + ((static_cast("alice"_n.to_uint64_t()) << 64) | 1), + "test"_n ); + + c.produce_block(); + +} FC_LOG_AND_RETHROW() + BOOST_AUTO_TEST_CASE( fix_linkauth_restriction ) { try { tester chain( setup_policy::preactivate_feature_and_new_bios ); From 218f933fcef0dec2041287cac186860a7986e66b Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Mon, 25 Sep 2023 08:34:04 -0400 Subject: [PATCH 12/29] move delete_auth from delay_tests.cpp to auth_tests.cpp --- unittests/auth_tests.cpp | 136 ++++++++++++++++++++++++++++++++++++++ unittests/delay_tests.cpp | 135 ------------------------------------- 2 files changed, 136 insertions(+), 135 deletions(-) diff --git a/unittests/auth_tests.cpp b/unittests/auth_tests.cpp index f4a9cebdf2..02fa619866 100644 --- a/unittests/auth_tests.cpp +++ b/unittests/auth_tests.cpp @@ -9,6 +9,8 @@ #include +#include + using namespace eosio; using namespace eosio::chain; using namespace eosio::testing; @@ -550,5 +552,139 @@ BOOST_AUTO_TEST_CASE( linkauth_special ) { try { } FC_LOG_AND_RETHROW() } +BOOST_AUTO_TEST_CASE(delete_auth) { try { + validating_tester chain; + + const auto& tester_account = "tester"_n; + + chain.produce_blocks(); + chain.create_account("eosio.token"_n); + chain.produce_blocks(10); + + chain.set_code("eosio.token"_n, test_contracts::eosio_token_wasm()); + chain.set_abi("eosio.token"_n, test_contracts::eosio_token_abi()); + + chain.produce_blocks(); + chain.create_account("tester"_n); + chain.create_account("tester2"_n); + chain.produce_blocks(10); + + transaction_trace_ptr trace; + + // can't delete auth because it doesn't exist + BOOST_REQUIRE_EXCEPTION( + trace = chain.push_action(config::system_account_name, deleteauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "first")), + permission_query_exception, + [] (const permission_query_exception &e)->bool { + expect_assert_message(e, "permission_query_exception: Permission Query Exception\nFailed to retrieve permission"); + return true; + }); + + // update auth + chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "first") + ("parent", "active") + ("auth", authority(chain.get_public_key(tester_account, "first"))) + ); + + // link auth + chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("code", "eosio.token") + ("type", "transfer") + ("requirement", "first")); + + // create CUR token + chain.produce_blocks(); + chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() + ("issuer", "eosio.token" ) + ("maximum_supply", "9000000.0000 CUR" ) + ); + + // issue to account "eosio.token" + chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() + ("to", "eosio.token") + ("quantity", "1000000.0000 CUR") + ("memo", "for stuff") + ); + + // transfer from eosio.token to tester + trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() + ("from", "eosio.token") + ("to", "tester") + ("quantity", "100.0000 CUR") + ("memo", "hi" ) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + chain.produce_blocks(); + + auto liquid_balance = chain.get_currency_balance("eosio.token"_n, symbol(SY(4,CUR)), "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = chain.get_currency_balance("eosio.token"_n, symbol(SY(4,CUR)), "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + + trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() + ("from", "tester") + ("to", "tester2") + ("quantity", "1.0000 CUR") + ("memo", "hi" ) + ); + + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + liquid_balance = chain.get_currency_balance("eosio.token"_n, symbol(SY(4,CUR)), "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = chain.get_currency_balance("eosio.token"_n, symbol(SY(4,CUR)), "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = chain.get_currency_balance("eosio.token"_n, symbol(SY(4,CUR)), "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + // can't delete auth because it's linked + BOOST_REQUIRE_EXCEPTION( + trace = chain.push_action(config::system_account_name, deleteauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "first")), + action_validate_exception, + [] (const action_validate_exception &e)->bool { + expect_assert_message(e, "action_validate_exception: message validation exception\nCannot delete a linked authority"); + return true; + }); + + // unlink auth + trace = chain.push_action(config::system_account_name, unlinkauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("code", "eosio.token") + ("type", "transfer")); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + // delete auth + trace = chain.push_action(config::system_account_name, deleteauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "first")); + + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + chain.produce_blocks(1);; + + trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() + ("from", "tester") + ("to", "tester2") + ("quantity", "3.0000 CUR") + ("memo", "hi" ) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + chain.produce_blocks(); + + liquid_balance = chain.get_currency_balance("eosio.token"_n, symbol(SY(4,CUR)), "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("96.0000 CUR"), liquid_balance); + liquid_balance = chain.get_currency_balance("eosio.token"_n, symbol(SY(4,CUR)), "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("4.0000 CUR"), liquid_balance); + +} FC_LOG_AND_RETHROW() }/// delete_auth BOOST_AUTO_TEST_SUITE_END() diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index 35e0301103..0a6e01c3bb 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -154,141 +154,6 @@ BOOST_AUTO_TEST_CASE( delayed_action ) { try { }); } FC_LOG_AND_RETHROW() }/// schedule_test -BOOST_AUTO_TEST_CASE(delete_auth_test) { try { - validating_tester chain; - - const auto& tester_account = "tester"_n; - - chain.produce_blocks(); - chain.create_account("eosio.token"_n); - chain.produce_blocks(10); - - chain.set_code("eosio.token"_n, test_contracts::eosio_token_wasm()); - chain.set_abi("eosio.token"_n, test_contracts::eosio_token_abi()); - - chain.produce_blocks(); - chain.create_account("tester"_n); - chain.create_account("tester2"_n); - chain.produce_blocks(10); - - transaction_trace_ptr trace; - - // can't delete auth because it doesn't exist - BOOST_REQUIRE_EXCEPTION( - trace = chain.push_action(config::system_account_name, deleteauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first")), - permission_query_exception, - [] (const permission_query_exception &e)->bool { - expect_assert_message(e, "permission_query_exception: Permission Query Exception\nFailed to retrieve permission"); - return true; - }); - - // update auth - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"))) - ); - - // link auth - chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", "eosio.token") - ("type", "transfer") - ("requirement", "first")); - - // create CUR token - chain.produce_blocks(); - chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() - ("issuer", "eosio.token" ) - ("maximum_supply", "9000000.0000 CUR" ) - ); - - // issue to account "eosio.token" - chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() - ("to", "eosio.token") - ("quantity", "1000000.0000 CUR") - ("memo", "for stuff") - ); - - // transfer from eosio.token to tester - trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() - ("from", "eosio.token") - ("to", "tester") - ("quantity", "100.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - - chain.produce_blocks(); - - auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "1.0000 CUR") - ("memo", "hi" ) - ); - - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - - liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - // can't delete auth because it's linked - BOOST_REQUIRE_EXCEPTION( - trace = chain.push_action(config::system_account_name, deleteauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first")), - action_validate_exception, - [] (const action_validate_exception &e)->bool { - expect_assert_message(e, "action_validate_exception: message validation exception\nCannot delete a linked authority"); - return true; - }); - - // unlink auth - trace = chain.push_action(config::system_account_name, unlinkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", "eosio.token") - ("type", "transfer")); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - - // delete auth - trace = chain.push_action(config::system_account_name, deleteauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first")); - - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - - chain.produce_blocks(1);; - - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "3.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("96.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("4.0000 CUR"), liquid_balance); - -} FC_LOG_AND_RETHROW() }/// delete_auth_test - BOOST_AUTO_TEST_CASE( test_blockchain_params_enabled ) { try { //since validation_tester activates all features here we will test how setparams works without //blockchain_parameters enabled From 55c51c8952f2452b15aa0ff09c6a82536a461276 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Mon, 25 Sep 2023 11:35:53 -0400 Subject: [PATCH 13/29] simplify delayed_action_blocked and minor refactor --- unittests/delay_tests.cpp | 111 +++++--------------------------------- 1 file changed, 14 insertions(+), 97 deletions(-) diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index 0a6e01c3bb..178c19d767 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -12,10 +12,16 @@ using namespace eosio; using namespace eosio::chain; using namespace eosio::testing; +static asset get_currency_balance(const validating_tester& chain, account_name account) { + return chain.get_currency_balance("eosio.token"_n, symbol(SY(4,CUR)), account); +} + +const std::string eosio_token = name("eosio.token"_n).to_string(); + BOOST_AUTO_TEST_SUITE(delay_tests) // Delayed trxs are blocked. -BOOST_FIXTURE_TEST_CASE( delayed_trx, validating_tester) { try { +BOOST_FIXTURE_TEST_CASE( delayed_trx_blocked, validating_tester ) { try { produce_blocks(2); signed_transaction trx; @@ -41,118 +47,29 @@ BOOST_FIXTURE_TEST_CASE( delayed_trx, validating_tester) { try { return expect_assert_message(e, "transaction cannot be delayed"); }); -} FC_LOG_AND_RETHROW() } - -asset get_currency_balance(const validating_tester& chain, account_name account) { - return chain.get_currency_balance("eosio.token"_n, symbol(SY(4,CUR)), account); -} - -const std::string eosio_token = name("eosio.token"_n).to_string(); +} FC_LOG_AND_RETHROW() }/// delayed_trx_blocked // Delayed actions are blocked. -BOOST_AUTO_TEST_CASE( delayed_action ) { try { +BOOST_AUTO_TEST_CASE( delayed_action_blocked ) { try { validating_tester chain; - const auto& tester_account = "tester"_n; - chain.produce_blocks(); - chain.create_account("eosio.token"_n); - chain.produce_blocks(10); - - chain.set_code("eosio.token"_n, test_contracts::eosio_token_wasm()); - chain.set_abi("eosio.token"_n, test_contracts::eosio_token_abi()); - - chain.produce_blocks(); chain.create_account("tester"_n); - chain.create_account("tester2"_n); - chain.produce_blocks(10); - - chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"))) - ); - chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer") - ("requirement", "first")); chain.produce_blocks(); - chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() - ("issuer", eosio_token) - ("maximum_supply", "9000000.0000 CUR") - ); - - chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() - ("to", eosio_token) - ("quantity", "1000000.0000 CUR") - ("memo", "for stuff") - ); - - auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() - ("from", eosio_token) - ("to", "tester") - ("quantity", "100.0000 CUR") - ("memo", "hi" ) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - auto gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - chain.produce_blocks(); - - auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); - - trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "1.0000 CUR") - ("memo", "hi" ) - ); - - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - chain.produce_blocks(); - - liquid_balance = get_currency_balance(chain, "eosio.token"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); - liquid_balance = get_currency_balance(chain, "tester2"_n); - BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); - - trace = chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + BOOST_CHECK_EXCEPTION( + chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() ("account", "tester") ("permission", "first") ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"), 10)) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); - - chain.produce_blocks(); - - BOOST_CHECK_EXCEPTION( - chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() - ("from", "tester") - ("to", "tester2") - ("quantity", "3.0000 CUR") - ("memo", "hi" ), - 20, 10 - ), + ("auth", authority(chain.get_public_key(tester_account, "first"))), + 20, 10), fc::exception, [&](const fc::exception &e) { // any delayed incoming trx is blocked return expect_assert_message(e, "transaction cannot be delayed"); }); -} FC_LOG_AND_RETHROW() }/// schedule_test +} FC_LOG_AND_RETHROW() }/// delayed_action_blocked BOOST_AUTO_TEST_CASE( test_blockchain_params_enabled ) { try { //since validation_tester activates all features here we will test how setparams works without From 0b47abed6891c5bc84824963a6994d107ac4f67a Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Mon, 25 Sep 2023 11:39:11 -0400 Subject: [PATCH 14/29] restore link_delay_direct_test and link_delay_direct_parent_permission_test using msig contracts --- unittests/delay_tests.cpp | 311 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 311 insertions(+) diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index 178c19d767..4282dca90d 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -12,6 +12,85 @@ using namespace eosio; using namespace eosio::chain; using namespace eosio::testing; +using mvo = fc::mutable_variant_object; + +static void create_accounts(validating_tester& chain) { + chain.produce_blocks(); + chain.create_accounts({"eosio.msig"_n, "eosio.token"_n}); + chain.produce_blocks(10); + + chain.push_action(config::system_account_name, + "setpriv"_n, + config::system_account_name, + mvo() + ("account", "eosio.msig") + ("is_priv", 1) ); + + chain.set_code("eosio.token"_n, test_contracts::eosio_token_wasm()); + chain.set_abi("eosio.token"_n, test_contracts::eosio_token_abi()); + chain.set_code("eosio.msig"_n, test_contracts::eosio_msig_wasm()); + chain.set_abi("eosio.msig"_n, test_contracts::eosio_msig_abi()); + + chain.produce_blocks(); + chain.create_account("tester"_n); + chain.create_account("tester2"_n); + chain.produce_blocks(10); +} + +static void propose_msig_trx(validating_tester& chain, name proposal_name, const vector& perm, uint32_t delay_sec, const std::string& quantity) { + vector transfer_perm = {{ "tester"_n, config::active_name }}; + fc::variant pretty_trx = fc::mutable_variant_object() + ("expiration", "2020-01-01T00:30") + ("ref_block_num", 2) + ("ref_block_prefix", 3) + ("max_net_usage_words", 0) + ("max_cpu_usage_ms", 0) + ("delay_sec", delay_sec) + ("actions", fc::variants({ + mvo() + ("account", name("eosio.token"_n)) + ("name", "transfer") + ("authorization", transfer_perm) + ("data", fc::mutable_variant_object() + ("from", name("tester"_n)) + ("to", name("tester2"_n)) + ("quantity", quantity) + ("memo", "hi" ) + ) + }) + ); + + transaction trx; + abi_serializer::from_variant(pretty_trx, trx, chain.get_resolver(), abi_serializer::create_yield_function(chain.abi_serializer_max_time)); + + vector requested_perm = {{ "tester"_n, config::active_name }}; + chain.push_action("eosio.msig"_n, "propose"_n, perm, + mvo() + ("proposer", "tester") + ("proposal_name", proposal_name) + ("trx", trx) + ("requested", requested_perm) + ); +} + +static void approve_msig_trx(validating_tester& chain, name proposal_name) { + chain.push_action("eosio.msig"_n, "approve"_n, "tester"_n, + mvo() + ("proposer", "tester") + ("proposal_name", proposal_name) + ("level", permission_level{ "tester"_n, config::active_name }) + ); +} + +static void exec_msig_trx(validating_tester& chain, name proposal_name) { + chain.push_action("eosio.msig"_n, "exec"_n, "tester"_n, + mvo() + ("proposer", "tester") + ("proposal_name", proposal_name) + ("executer", "tester") + ); +} + static asset get_currency_balance(const validating_tester& chain, account_name account) { return chain.get_currency_balance("eosio.token"_n, symbol(SY(4,CUR)), account); } @@ -71,6 +150,238 @@ BOOST_AUTO_TEST_CASE( delayed_action_blocked ) { try { }); } FC_LOG_AND_RETHROW() }/// delayed_action_blocked +// test link to permission with delay directly on it +BOOST_AUTO_TEST_CASE( link_delay_direct_test ) { try { + validating_tester chain; + const auto& tester_account = "tester"_n; + + create_accounts(chain); + + chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "first") + ("parent", "active") + ("auth", authority(chain.get_public_key(tester_account, "first"))) + ); + chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("code", eosio_token) + ("type", "transfer") + ("requirement", "first")); + chain.produce_blocks(); + chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() + ("issuer", eosio_token) + ("maximum_supply", "9000000.0000 CUR") + ); + + chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() + ("to", eosio_token) + ("quantity", "1000000.0000 CUR") + ("memo", "for stuff") + ); + + auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() + ("from", eosio_token) + ("to", "tester") + ("quantity", "100.0000 CUR") + ("memo", "hi" ) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + auto gen_size = chain.control->db().get_index().size(); + BOOST_REQUIRE_EQUAL(0u, gen_size); + + chain.produce_blocks(); + + auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + + trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() + ("from", "tester") + ("to", "tester2") + ("quantity", "1.0000 CUR") + ("memo", "hi" ) + ); + + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + gen_size = chain.control->db().get_index().size(); + BOOST_REQUIRE_EQUAL(0u, gen_size); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + trace = chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "first") + ("parent", "active") + ("auth", authority(chain.get_public_key(tester_account, "first"), 10)) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + gen_size = chain.control->db().get_index().size(); + BOOST_REQUIRE_EQUAL(0u, gen_size); + + chain.produce_blocks(); + + // propose an msig trx that transfers "quantity" tokens + // from tester to tester2 with a delay of "delay_seconds" + constexpr name proposal_name = "prop1"_n; + constexpr uint32_t delay_seconds = 10; + constexpr auto quantity = "3.0000 CUR"; + propose_msig_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}, delay_seconds, quantity); + + // approve the msig trx + approve_msig_trx(chain, proposal_name); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + chain.produce_blocks(18); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + // executue after delay of 10 seconds + exec_msig_trx(chain, proposal_name); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("96.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("4.0000 CUR"), liquid_balance); + +} FC_LOG_AND_RETHROW() }/// link_delay_direct_test + +// test link to permission with delay on permission which is parent of min permission (special logic in permission_object::satisfies) +BOOST_AUTO_TEST_CASE( link_delay_direct_parent_permission_test ) { try { + validating_tester chain; + + const auto& tester_account = "tester"_n; + + create_accounts(chain); + + chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "first") + ("parent", "active") + ("auth", authority(chain.get_public_key(tester_account, "first"))) + ); + chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("code", eosio_token) + ("type", "transfer") + ("requirement", "first")); + + chain.produce_blocks(); + chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() + ("issuer", eosio_token) + ("maximum_supply", "9000000.0000 CUR") + ); + + chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() + ("to", eosio_token) + ("quantity", "1000000.0000 CUR") + ("memo", "for stuff") + ); + + auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() + ("from", eosio_token) + ("to", "tester") + ("quantity", "100.0000 CUR") + ("memo", "hi" ) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + auto gen_size = chain.control->db().get_index().size(); + BOOST_REQUIRE_EQUAL(0u, gen_size); + + chain.produce_blocks(); + + auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + + trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() + ("from", "tester") + ("to", "tester2") + ("quantity", "1.0000 CUR") + ("memo", "hi" ) + ); + + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + gen_size = chain.control->db().get_index().size(); + BOOST_REQUIRE_EQUAL(0u, gen_size); + + chain.produce_blocks(); + + // Propose and approve an msig trx that transfers "quantity" tokens + // from tester to tester2 with a delay of "delay_seconds" + constexpr name proposal_name = "prop1"_n; + constexpr uint32_t delay_seconds = 15; + constexpr auto quantity = "3.0000 CUR"; + propose_msig_trx(chain, proposal_name, {{ "tester"_n, config::owner_name }}, delay_seconds, quantity); + + // approve the msig trx + approve_msig_trx(chain, proposal_name); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + chain.produce_blocks(28); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + chain.produce_blocks(); + + // executue the msig trx + exec_msig_trx(chain, proposal_name); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("96.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("4.0000 CUR"), liquid_balance); + +} FC_LOG_AND_RETHROW() }/// link_delay_direct_parent_permission_test + BOOST_AUTO_TEST_CASE( test_blockchain_params_enabled ) { try { //since validation_tester activates all features here we will test how setparams works without //blockchain_parameters enabled From 41a5c3bfbb1497066ba19de161854a299563ec4f Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Mon, 25 Sep 2023 13:05:40 -0400 Subject: [PATCH 15/29] move generated_transaction_multi_index size checks to delayed_trx_blocked and delayed_action_blocked --- unittests/delay_tests.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index 4282dca90d..347e4ed0dd 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -126,6 +126,9 @@ BOOST_FIXTURE_TEST_CASE( delayed_trx_blocked, validating_tester ) { try { return expect_assert_message(e, "transaction cannot be delayed"); }); + // no deferred trx was generated + auto gen_size = control->db().get_index().size(); + BOOST_REQUIRE_EQUAL(0u, gen_size); } FC_LOG_AND_RETHROW() }/// delayed_trx_blocked // Delayed actions are blocked. @@ -136,6 +139,7 @@ BOOST_AUTO_TEST_CASE( delayed_action_blocked ) { try { chain.create_account("tester"_n); chain.produce_blocks(); + // delayed action is blocked BOOST_CHECK_EXCEPTION( chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() ("account", "tester") @@ -148,6 +152,10 @@ BOOST_AUTO_TEST_CASE( delayed_action_blocked ) { try { // any delayed incoming trx is blocked return expect_assert_message(e, "transaction cannot be delayed"); }); + + // no deferred trx was generated + auto gen_size = chain.control->db().get_index().size(); + BOOST_REQUIRE_EQUAL(0u, gen_size); } FC_LOG_AND_RETHROW() }/// delayed_action_blocked // test link to permission with delay directly on it @@ -187,8 +195,6 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_test ) { try { ("memo", "hi" ) ); BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - auto gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); chain.produce_blocks(); @@ -205,8 +211,6 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_test ) { try { ); BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); chain.produce_blocks(); @@ -224,8 +228,6 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_test ) { try { ("auth", authority(chain.get_public_key(tester_account, "first"), 10)) ); BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); chain.produce_blocks(); @@ -311,8 +313,6 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_parent_permission_test ) { try { ("memo", "hi" ) ); BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - auto gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); chain.produce_blocks(); @@ -329,8 +329,6 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_parent_permission_test ) { try { ); BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); - gen_size = chain.control->db().get_index().size(); - BOOST_REQUIRE_EQUAL(0u, gen_size); chain.produce_blocks(); From 508397df4fe3cc124d8081e2ce47dab3901a1be2 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Mon, 25 Sep 2023 14:09:15 -0400 Subject: [PATCH 16/29] restore and adpat link_delay_direct_walk_parent_permissions_test --- unittests/delay_tests.cpp | 135 +++++++++++++++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 3 deletions(-) diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index 347e4ed0dd..af5f0a7bd3 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -37,7 +37,7 @@ static void create_accounts(validating_tester& chain) { chain.produce_blocks(10); } -static void propose_msig_trx(validating_tester& chain, name proposal_name, const vector& perm, uint32_t delay_sec, const std::string& quantity) { +static void propose_msig_token_transfer_trx(validating_tester& chain, name proposal_name, const vector& perm, uint32_t delay_sec, const std::string& quantity) { vector transfer_perm = {{ "tester"_n, config::active_name }}; fc::variant pretty_trx = fc::mutable_variant_object() ("expiration", "2020-01-01T00:30") @@ -236,7 +236,7 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_test ) { try { constexpr name proposal_name = "prop1"_n; constexpr uint32_t delay_seconds = 10; constexpr auto quantity = "3.0000 CUR"; - propose_msig_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}, delay_seconds, quantity); + propose_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}, delay_seconds, quantity); // approve the msig trx approve_msig_trx(chain, proposal_name); @@ -337,7 +337,7 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_parent_permission_test ) { try { constexpr name proposal_name = "prop1"_n; constexpr uint32_t delay_seconds = 15; constexpr auto quantity = "3.0000 CUR"; - propose_msig_trx(chain, proposal_name, {{ "tester"_n, config::owner_name }}, delay_seconds, quantity); + propose_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::owner_name }}, delay_seconds, quantity); // approve the msig trx approve_msig_trx(chain, proposal_name); @@ -399,4 +399,133 @@ BOOST_AUTO_TEST_CASE( test_blockchain_params_enabled ) { try { } FC_LOG_AND_RETHROW() } +// test link to permission with delay on permission between min permission and authorizing permission it +BOOST_AUTO_TEST_CASE( link_delay_direct_walk_parent_permissions_test ) { try { + validating_tester chain; + const auto& tester_account = "tester"_n; + + create_accounts(chain); + + chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "first") + ("parent", "active") + ("auth", authority(chain.get_public_key(tester_account, "first"))) + ); + chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "second") + ("parent", "first") + ("auth", authority(chain.get_public_key(tester_account, "second"))) + ); + chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("code", eosio_token) + ("type", "transfer") + ("requirement", "second")); + + chain.produce_blocks(); + chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() + ("issuer", eosio_token) + ("maximum_supply", "9000000.0000 CUR") + ); + + chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() + ("to", eosio_token) + ("quantity", "1000000.0000 CUR") + ("memo", "for stuff") + ); + + auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() + ("from", eosio_token) + ("to", "tester") + ("quantity", "100.0000 CUR") + ("memo", "hi" ) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + chain.produce_blocks(); + + auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + + trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() + ("from", "tester") + ("to", "tester2") + ("quantity", "1.0000 CUR") + ("memo", "hi" ) + ); + + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + trace = chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "first") + ("parent", "active") + ("auth", authority(chain.get_public_key(tester_account, "first"), 20)) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + chain.produce_blocks(); + + + // propose an msig trx that transfers "quantity" tokens + // from tester to tester2 with a delay of "delay_seconds" + constexpr name proposal_name = "prop1"_n; + constexpr uint32_t delay_seconds = 20; + constexpr auto quantity = "3.0000 CUR"; + propose_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}, delay_seconds, quantity); + + // approve the msig trx + approve_msig_trx(chain, proposal_name); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + chain.produce_blocks(38); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + // executue after delay + exec_msig_trx(chain, proposal_name); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("96.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("4.0000 CUR"), liquid_balance); + +} FC_LOG_AND_RETHROW() }/// link_delay_direct_walk_parent_permissions_test + BOOST_AUTO_TEST_SUITE_END() From de5e3c7ab8b0c9f86e3044fed462bb6336221041 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Mon, 25 Sep 2023 15:15:11 -0400 Subject: [PATCH 17/29] restore and adapt link_delay_permission_change_test --- unittests/delay_tests.cpp | 212 +++++++++++++++++++++++++++++++++++--- 1 file changed, 196 insertions(+), 16 deletions(-) diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index af5f0a7bd3..92f9dc44a9 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -37,7 +37,7 @@ static void create_accounts(validating_tester& chain) { chain.produce_blocks(10); } -static void propose_msig_token_transfer_trx(validating_tester& chain, name proposal_name, const vector& perm, uint32_t delay_sec, const std::string& quantity) { +static void propose_approve_msig_token_transfer_trx(validating_tester& chain, name proposal_name, const vector& perm, uint32_t delay_sec, const std::string& quantity) { vector transfer_perm = {{ "tester"_n, config::active_name }}; fc::variant pretty_trx = fc::mutable_variant_object() ("expiration", "2020-01-01T00:30") @@ -71,9 +71,50 @@ static void propose_msig_token_transfer_trx(validating_tester& chain, name propo ("trx", trx) ("requested", requested_perm) ); + + chain.push_action("eosio.msig"_n, "approve"_n, "tester"_n, + mvo() + ("proposer", "tester") + ("proposal_name", proposal_name) + ("level", permission_level{ "tester"_n, config::active_name }) + ); } -static void approve_msig_trx(validating_tester& chain, name proposal_name) { +static void propose_approve_msig_updateauth_trx(validating_tester& chain, name proposal_name, const vector& perm, uint32_t delay_sec) { + vector transfer_perm = {{ "tester"_n, config::active_name }}; + fc::variant pretty_trx = fc::mutable_variant_object() + ("expiration", "2020-01-01T00:30") + ("ref_block_num", 2) + ("ref_block_prefix", 3) + ("max_net_usage_words", 0) + ("max_cpu_usage_ms", 0) + ("delay_sec", delay_sec) + ("actions", fc::variants({ + mvo() + ("account", config::system_account_name) + ("name", updateauth::get_name()) + ("authorization", transfer_perm) + ("data", fc::mutable_variant_object() + ("account", "tester") + ("permission", "first") + ("parent", "active") + ("auth", authority(chain.get_public_key("tester"_n, "first"))) + ) + }) + ); + + transaction trx; + abi_serializer::from_variant(pretty_trx, trx, chain.get_resolver(), abi_serializer::create_yield_function(chain.abi_serializer_max_time)); + + vector requested_perm = {{ "tester"_n, config::active_name }}; + chain.push_action("eosio.msig"_n, "propose"_n, perm, + mvo() + ("proposer", "tester") + ("proposal_name", proposal_name) + ("trx", trx) + ("requested", requested_perm) + ); + chain.push_action("eosio.msig"_n, "approve"_n, "tester"_n, mvo() ("proposer", "tester") @@ -231,15 +272,12 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_test ) { try { chain.produce_blocks(); - // propose an msig trx that transfers "quantity" tokens + // propose and approve an msig trx that transfers "quantity" tokens // from tester to tester2 with a delay of "delay_seconds" constexpr name proposal_name = "prop1"_n; constexpr uint32_t delay_seconds = 10; constexpr auto quantity = "3.0000 CUR"; - propose_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}, delay_seconds, quantity); - - // approve the msig trx - approve_msig_trx(chain, proposal_name); + propose_approve_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}, delay_seconds, quantity); chain.produce_blocks(); @@ -337,10 +375,7 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_parent_permission_test ) { try { constexpr name proposal_name = "prop1"_n; constexpr uint32_t delay_seconds = 15; constexpr auto quantity = "3.0000 CUR"; - propose_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::owner_name }}, delay_seconds, quantity); - - // approve the msig trx - approve_msig_trx(chain, proposal_name); + propose_approve_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::owner_name }}, delay_seconds, quantity); liquid_balance = get_currency_balance(chain, "tester"_n); BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); @@ -480,15 +515,12 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_walk_parent_permissions_test ) { try { chain.produce_blocks(); - // propose an msig trx that transfers "quantity" tokens + // propose and approve an msig trx that transfers "quantity" tokens // from tester to tester2 with a delay of "delay_seconds" constexpr name proposal_name = "prop1"_n; constexpr uint32_t delay_seconds = 20; constexpr auto quantity = "3.0000 CUR"; - propose_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}, delay_seconds, quantity); - - // approve the msig trx - approve_msig_trx(chain, proposal_name); + propose_approve_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}, delay_seconds, quantity); liquid_balance = get_currency_balance(chain, "tester"_n); BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); @@ -528,4 +560,152 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_walk_parent_permissions_test ) { try { } FC_LOG_AND_RETHROW() }/// link_delay_direct_walk_parent_permissions_test +// test removing delay on permission +BOOST_AUTO_TEST_CASE( link_delay_permission_change_test ) { try { + validating_tester chain; + + const auto& tester_account = "tester"_n; + + create_accounts(chain); + + chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "first") + ("parent", "active") + ("auth", authority(chain.get_public_key(tester_account, "first"), 10)) + ); + chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("code", eosio_token) + ("type", "transfer") + ("requirement", "first")); + + chain.produce_blocks(); + chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() + ("issuer", eosio_token ) + ("maximum_supply", "9000000.0000 CUR" ) + ); + + chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() + ("to", eosio_token) + ("quantity", "1000000.0000 CUR") + ("memo", "for stuff") + ); + + auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() + ("from", eosio_token) + ("to", "tester") + ("quantity", "100.0000 CUR") + ("memo", "hi" ) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + chain.produce_blocks(); + + auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + + // this transaction will be delayed 20 blocks + constexpr name proposal_1_name = "prop1"_n; + constexpr uint32_t delay_seconds = 10; + constexpr auto quantity = "1.0000 CUR"; + propose_approve_msig_token_transfer_trx(chain, proposal_1_name, {{ "tester"_n, config::active_name }}, delay_seconds, quantity); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + // this transaction will be delayed 20 blocks + constexpr name proposal_2_name = "prop2"_n; + constexpr uint32_t delay_seconds_2 = 10; + propose_approve_msig_updateauth_trx(chain, proposal_2_name, {{ "tester"_n, config::active_name }}, delay_seconds_2); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + chain.produce_blocks(16); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + // this transaction will be delayed 20 blocks + constexpr name proposal_3_name = "prop3"_n; + constexpr uint32_t delay_seconds_3 = 10; + constexpr auto quantity_3 = "5.0000 CUR"; + propose_approve_msig_token_transfer_trx(chain, proposal_3_name, {{ "tester"_n, config::active_name }}, delay_seconds_3, quantity_3); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + // first transfer will finally be performed + exec_msig_trx(chain, proposal_1_name); + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + // delayed update auth removing the delay will finally execute + exec_msig_trx(chain, proposal_2_name); + chain.produce_blocks(); + + // this transfer is performed right away since delay is removed + trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() + ("from", "tester") + ("to", "tester2") + ("quantity", "10.0000 CUR") + ("memo", "hi" ) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); + + chain.produce_blocks(15); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); + + // second transfer finally is performed + exec_msig_trx(chain, proposal_3_name); + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("84.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("16.0000 CUR"), liquid_balance); + +} FC_LOG_AND_RETHROW() }/// link_delay_permission_change_test + BOOST_AUTO_TEST_SUITE_END() From b2418c95d044fff8d5b76745440a4e55c98f1da0 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Mon, 25 Sep 2023 15:30:08 -0400 Subject: [PATCH 18/29] restore and adapt link_delay_permission_change_with_delay_heirarchy_test --- unittests/delay_tests.cpp | 162 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index 92f9dc44a9..ecb0f32e58 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -708,4 +708,166 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_test ) { try { } FC_LOG_AND_RETHROW() }/// link_delay_permission_change_test +// test removing delay on permission based on heirarchy delay +BOOST_AUTO_TEST_CASE( link_delay_permission_change_with_delay_heirarchy_test ) { try { + validating_tester chain; + + const auto& tester_account = "tester"_n; + + create_accounts(chain); + + chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "first") + ("parent", "active") + ("auth", authority(chain.get_public_key(tester_account, "first"), 10)) + ); + chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "second") + ("parent", "first") + ("auth", authority(chain.get_public_key(tester_account, "second"))) + ); + chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("code", eosio_token) + ("type", "transfer") + ("requirement", "second")); + + chain.produce_blocks(); + chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() + ("issuer", eosio_token) + ("maximum_supply", "9000000.0000 CUR" ) + ); + + chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() + ("to", eosio_token) + ("quantity", "1000000.0000 CUR") + ("memo", "for stuff") + ); + + auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() + ("from", eosio_token) + ("to", "tester") + ("quantity", "100.0000 CUR") + ("memo", "hi" ) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + chain.produce_blocks(); + + auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + + // this transaction will be delayed 20 blocks + constexpr name proposal_1_name = "prop1"_n; + constexpr uint32_t delay_seconds = 10; + constexpr auto quantity = "1.0000 CUR"; + propose_approve_msig_token_transfer_trx(chain, proposal_1_name, {{ "tester"_n, config::active_name }}, delay_seconds, quantity); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + // this transaction will be delayed 20 blocks + constexpr name proposal_2_name = "prop2"_n; + constexpr uint32_t delay_seconds_2 = 10; + propose_approve_msig_updateauth_trx(chain, proposal_2_name, {{ "tester"_n, config::active_name }}, delay_seconds_2); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + chain.produce_blocks(16); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + // this transaction will be delayed 20 blocks + constexpr name proposal_3_name = "prop3"_n; + constexpr uint32_t delay_seconds_3 = 10; + constexpr auto quantity_3 = "5.0000 CUR"; + propose_approve_msig_token_transfer_trx(chain, proposal_3_name, {{ "tester"_n, config::active_name }}, delay_seconds_3, quantity_3); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + // first transfer will finally be performed + exec_msig_trx(chain, proposal_1_name); + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + // delayed update auth removing the delay will finally execute + exec_msig_trx(chain, proposal_2_name); + chain.produce_blocks(); + + // this transfer is performed right away since delay is removed + trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() + ("from", "tester") + ("to", "tester2") + ("quantity", "10.0000 CUR") + ("memo", "hi" ) + ); + + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); + + chain.produce_blocks(14); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); + + // second transfer finally is performed + exec_msig_trx(chain, proposal_3_name); + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("84.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("16.0000 CUR"), liquid_balance); + +} FC_LOG_AND_RETHROW() }/// link_delay_permission_change_with_delay_heirarchy_test + BOOST_AUTO_TEST_SUITE_END() From 41ceb75a1acec97b0e6539af398de973150f4153 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Mon, 25 Sep 2023 16:14:21 -0400 Subject: [PATCH 19/29] restore and adapt link_delay_link_change_test --- unittests/delay_tests.cpp | 211 +++++++++++++++++++++++++++++++++++++- 1 file changed, 210 insertions(+), 1 deletion(-) diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index ecb0f32e58..f0c5b43125 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -14,6 +14,8 @@ using namespace eosio::testing; using mvo = fc::mutable_variant_object; +const std::string eosio_token = name("eosio.token"_n).to_string(); + static void create_accounts(validating_tester& chain) { chain.produce_blocks(); chain.create_accounts({"eosio.msig"_n, "eosio.token"_n}); @@ -123,6 +125,49 @@ static void propose_approve_msig_updateauth_trx(validating_tester& chain, name p ); } +static void propose_approve_msig_linkauth_trx(validating_tester& chain, name proposal_name, const vector& perm, uint32_t delay_sec) { + vector transfer_perm = {{ "tester"_n, config::active_name }}; + fc::variant pretty_trx = fc::mutable_variant_object() + ("expiration", "2020-01-01T00:30") + ("ref_block_num", 2) + ("ref_block_prefix", 3) + ("max_net_usage_words", 0) + ("max_cpu_usage_ms", 0) + ("delay_sec", delay_sec) + ("actions", fc::variants({ + mvo() + ("account", config::system_account_name) + ("name", linkauth::get_name()) + ("authorization", transfer_perm) + ("data", fc::mutable_variant_object() + ("account", "tester") + ("code", eosio_token) + ("type", "transfer") + ("requirement", "second") + ) + }) + ); + + transaction trx; + abi_serializer::from_variant(pretty_trx, trx, chain.get_resolver(), abi_serializer::create_yield_function(chain.abi_serializer_max_time)); + + vector requested_perm = {{ "tester"_n, config::active_name }}; + chain.push_action("eosio.msig"_n, "propose"_n, perm, + mvo() + ("proposer", "tester") + ("proposal_name", proposal_name) + ("trx", trx) + ("requested", requested_perm) + ); + + chain.push_action("eosio.msig"_n, "approve"_n, "tester"_n, + mvo() + ("proposer", "tester") + ("proposal_name", proposal_name) + ("level", permission_level{ "tester"_n, config::active_name }) + ); +} + static void exec_msig_trx(validating_tester& chain, name proposal_name) { chain.push_action("eosio.msig"_n, "exec"_n, "tester"_n, mvo() @@ -136,7 +181,6 @@ static asset get_currency_balance(const validating_tester& chain, account_name a return chain.get_currency_balance("eosio.token"_n, symbol(SY(4,CUR)), account); } -const std::string eosio_token = name("eosio.token"_n).to_string(); BOOST_AUTO_TEST_SUITE(delay_tests) @@ -870,4 +914,169 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_with_delay_heirarchy_test ) { } FC_LOG_AND_RETHROW() }/// link_delay_permission_change_with_delay_heirarchy_test +// test moving link with delay on permission +BOOST_AUTO_TEST_CASE( link_delay_link_change_test ) { try { + validating_tester chain; + + const auto& tester_account = "tester"_n; + + create_accounts(chain); + + chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "first") + ("parent", "active") + ("auth", authority(chain.get_public_key(tester_account, "first"), 10)) + ); + chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("code", eosio_token) + ("type", "transfer") + ("requirement", "first")); + chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "second") + ("parent", "active") + ("auth", authority(chain.get_public_key(tester_account, "second"))) + ); + + chain.produce_blocks(); + chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() + ("issuer", eosio_token) + ("maximum_supply", "9000000.0000 CUR" ) + ); + + chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() + ("to", eosio_token) + ("quantity", "1000000.0000 CUR") + ("memo", "for stuff") + ); + + auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() + ("from", eosio_token) + ("to", "tester") + ("quantity", "100.0000 CUR") + ("memo", "hi" ) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + chain.produce_blocks(); + + auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + + // this transaction will be delayed 20 blocks + constexpr name proposal_1_name = "prop1"_n; + constexpr uint32_t delay_seconds = 10; + constexpr auto quantity = "1.0000 CUR"; + propose_approve_msig_token_transfer_trx(chain, proposal_1_name, {{ "tester"_n, config::active_name }}, delay_seconds, quantity); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + BOOST_REQUIRE_EXCEPTION( + chain.push_action( config::system_account_name, linkauth::get_name(), + vector{permission_level{tester_account, "first"_n}}, + fc::mutable_variant_object() + ("account", "tester") + ("code", eosio_token) + ("type", "transfer") + ("requirement", "second"), + 30, 0), + unsatisfied_authorization, + fc_exception_message_starts_with("transaction declares authority") + ); + + // this transaction will be delayed 20 blocks + constexpr name proposal_2_name = "prop2"_n; + constexpr uint32_t delay_seconds_2 = 10; + propose_approve_msig_linkauth_trx(chain, proposal_2_name, {{ "tester"_n, config::active_name }}, delay_seconds_2); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + chain.produce_blocks(16); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + // this transaction will be delayed 20 blocks + constexpr name proposal_3_name = "prop3"_n; + constexpr uint32_t delay_seconds_3 = 10; + constexpr auto quantity_3 = "5.0000 CUR"; + propose_approve_msig_token_transfer_trx(chain, proposal_3_name, {{ "tester"_n, config::active_name }}, delay_seconds_3, quantity_3); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + // first transfer will finally be performed + exec_msig_trx(chain, proposal_1_name); + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + // delay on minimum permission of transfer is finally removed + exec_msig_trx(chain, proposal_2_name); + chain.produce_blocks(); + + // this transfer is performed right away since delay is removed + trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() + ("from", "tester") + ("to", "tester2") + ("quantity", "10.0000 CUR") + ("memo", "hi" ) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); + + chain.produce_blocks(16); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); + + // second transfer finally is performed + exec_msig_trx(chain, proposal_3_name); + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("84.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("16.0000 CUR"), liquid_balance); + +} FC_LOG_AND_RETHROW() }/// link_delay_link_change_test + BOOST_AUTO_TEST_SUITE_END() From 7c78c44d43e849fa6878e21c20de398909d433e0 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Mon, 25 Sep 2023 17:40:39 -0400 Subject: [PATCH 20/29] restore and adapt link_delay_unlink_test --- unittests/delay_tests.cpp | 202 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index f0c5b43125..874299fab9 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -168,6 +168,48 @@ static void propose_approve_msig_linkauth_trx(validating_tester& chain, name pro ); } +static void propose_approve_msig_unlinkauth_trx(validating_tester& chain, name proposal_name, const vector& perm, uint32_t delay_sec) { + vector transfer_perm = {{ "tester"_n, config::active_name }}; + fc::variant pretty_trx = fc::mutable_variant_object() + ("expiration", "2020-01-01T00:30") + ("ref_block_num", 2) + ("ref_block_prefix", 3) + ("max_net_usage_words", 0) + ("max_cpu_usage_ms", 0) + ("delay_sec", delay_sec) + ("actions", fc::variants({ + mvo() + ("account", config::system_account_name) + ("name", unlinkauth::get_name()) + ("authorization", transfer_perm) + ("data", fc::mutable_variant_object() + ("account", "tester") + ("code", eosio_token) + ("type", "transfer") + ) + }) + ); + + transaction trx; + abi_serializer::from_variant(pretty_trx, trx, chain.get_resolver(), abi_serializer::create_yield_function(chain.abi_serializer_max_time)); + + vector requested_perm = {{ "tester"_n, config::active_name }}; + chain.push_action("eosio.msig"_n, "propose"_n, perm, + mvo() + ("proposer", "tester") + ("proposal_name", proposal_name) + ("trx", trx) + ("requested", requested_perm) + ); + + chain.push_action("eosio.msig"_n, "approve"_n, "tester"_n, + mvo() + ("proposer", "tester") + ("proposal_name", proposal_name) + ("level", permission_level{ "tester"_n, config::active_name }) + ); +} + static void exec_msig_trx(validating_tester& chain, name proposal_name) { chain.push_action("eosio.msig"_n, "exec"_n, "tester"_n, mvo() @@ -1079,4 +1121,164 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_test ) { try { } FC_LOG_AND_RETHROW() }/// link_delay_link_change_test +// test link with unlink +BOOST_AUTO_TEST_CASE( link_delay_unlink_test ) { try { + validating_tester chain; + const auto& tester_account = "tester"_n; + + create_accounts(chain); + + chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "first") + ("parent", "active") + ("auth", authority(chain.get_public_key(tester_account, "first"), 10)) + ); + chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("code", eosio_token) + ("type", "transfer") + ("requirement", "first")); + + chain.produce_blocks(); + chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() + ("issuer", eosio_token ) + ("maximum_supply", "9000000.0000 CUR" ) + ); + + chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() + ("to", eosio_token) + ("quantity", "1000000.0000 CUR") + ("memo", "for stuff") + ); + + auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() + ("from", eosio_token) + ("to", "tester") + ("quantity", "100.0000 CUR") + ("memo", "hi" ) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + chain.produce_blocks(); + + auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + + // this transaction will be delayed 20 blocks + constexpr name first_trnsfr_propsal_name = "prop1"_n; + constexpr uint32_t first_trnsfr_delay_seconds = 10; + constexpr auto first_trnsfr_quantity = "1.0000 CUR"; + propose_approve_msig_token_transfer_trx(chain, first_trnsfr_propsal_name, {{ "tester"_n, config::active_name }}, first_trnsfr_delay_seconds, first_trnsfr_quantity); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + BOOST_REQUIRE_EXCEPTION( + chain.push_action( config::system_account_name, unlinkauth::get_name(), + vector{{tester_account, "first"_n}}, + fc::mutable_variant_object() + ("account", "tester") + ("code", eosio_token) + ("type", "transfer"), + 30, 0 + ), + unsatisfied_authorization, + fc_exception_message_starts_with("transaction declares authority") + ); + + // this transaction will be delayed 20 blocks + constexpr name unlinkauth_proposal_name = "prop2"_n; + constexpr uint32_t unlinkauth_delay_seconds = 10; + propose_approve_msig_unlinkauth_trx(chain, unlinkauth_proposal_name, {{ "tester"_n, config::active_name }}, unlinkauth_delay_seconds); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + chain.produce_blocks(16); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + // this transaction will be delayed 20 blocks + constexpr name second_trnfr_propsal_name = "prop3"_n; + constexpr uint32_t second_trnfr_delay_seconds = 10; + constexpr auto second_trnfr_quantity = "5.0000 CUR"; + propose_approve_msig_token_transfer_trx(chain, second_trnfr_propsal_name, {{ "tester"_n, config::active_name }}, second_trnfr_delay_seconds, second_trnfr_quantity); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + // first transfer will finally be performed + exec_msig_trx(chain, first_trnsfr_propsal_name); + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + // the delayed unlinkauth finally occurs + exec_msig_trx(chain, unlinkauth_proposal_name); + chain.produce_blocks(); + + // this transfer is performed right away since delay is removed + trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() + ("from", "tester") + ("to", "tester2") + ("quantity", "10.0000 CUR") + ("memo", "hi" ) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); + + chain.produce_blocks(15); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); + + // second transfer finally is performed + exec_msig_trx(chain, second_trnfr_propsal_name); + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("84.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("16.0000 CUR"), liquid_balance); + +} FC_LOG_AND_RETHROW() }/// link_delay_unlink_test + BOOST_AUTO_TEST_SUITE_END() From 43a50826e21524a3975e50f9975294482bac880c Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Mon, 25 Sep 2023 18:26:14 -0400 Subject: [PATCH 21/29] restore and adapt link_delay_link_change_heirarchy_test --- unittests/delay_tests.cpp | 158 +++++++++++++++++++++++++++++++++++++- 1 file changed, 155 insertions(+), 3 deletions(-) diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index 874299fab9..0447cc62c5 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -125,7 +125,7 @@ static void propose_approve_msig_updateauth_trx(validating_tester& chain, name p ); } -static void propose_approve_msig_linkauth_trx(validating_tester& chain, name proposal_name, const vector& perm, uint32_t delay_sec) { +static void propose_approve_msig_linkauth_trx(validating_tester& chain, const name proposal_name, const name requirement, const vector& perm, uint32_t delay_sec) { vector transfer_perm = {{ "tester"_n, config::active_name }}; fc::variant pretty_trx = fc::mutable_variant_object() ("expiration", "2020-01-01T00:30") @@ -143,7 +143,7 @@ static void propose_approve_msig_linkauth_trx(validating_tester& chain, name pro ("account", "tester") ("code", eosio_token) ("type", "transfer") - ("requirement", "second") + ("requirement", requirement) ) }) ); @@ -1040,7 +1040,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_test ) { try { // this transaction will be delayed 20 blocks constexpr name proposal_2_name = "prop2"_n; constexpr uint32_t delay_seconds_2 = 10; - propose_approve_msig_linkauth_trx(chain, proposal_2_name, {{ "tester"_n, config::active_name }}, delay_seconds_2); + propose_approve_msig_linkauth_trx(chain, proposal_2_name, "second"_n, {{ "tester"_n, config::active_name }}, delay_seconds_2); chain.produce_blocks(); @@ -1281,4 +1281,156 @@ BOOST_AUTO_TEST_CASE( link_delay_unlink_test ) { try { } FC_LOG_AND_RETHROW() }/// link_delay_unlink_test +// test moving link with delay on permission's parent +BOOST_AUTO_TEST_CASE( link_delay_link_change_heirarchy_test ) { try { + validating_tester chain; + const auto& tester_account = "tester"_n; + + create_accounts(chain); + + chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "first") + ("parent", "active") + ("auth", authority(chain.get_public_key(tester_account, "first"), 10)) + ); + chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "second") + ("parent", "first") + ("auth", authority(chain.get_public_key(tester_account, "first"))) + ); + chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("code", eosio_token) + ("type", "transfer") + ("requirement", "second")); + chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "third") + ("parent", "active") + ("auth", authority(chain.get_public_key(tester_account, "third"))) + ); + + chain.produce_blocks(); + chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() + ("issuer", eosio_token) + ("maximum_supply", "9000000.0000 CUR" ) + ); + + chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() + ("to", eosio_token) + ("quantity", "1000000.0000 CUR") + ("memo", "for stuff") + ); + + auto trace = chain.push_action("eosio.token"_n, name("transfer"), "eosio.token"_n, fc::mutable_variant_object() + ("from", eosio_token) + ("to", "tester") + ("quantity", "100.0000 CUR") + ("memo", "hi" ) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + chain.produce_blocks(); + + auto liquid_balance = get_currency_balance(chain, "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + + // this transaction will be delayed 20 blocks + constexpr name first_trnsfr_propsal_name = "prop1"_n; + propose_approve_msig_token_transfer_trx(chain, first_trnsfr_propsal_name, {{ "tester"_n, config::active_name }}, 10, "1.0000 CUR"); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + // this transaction will be delayed 20 blocks + constexpr name linkauth_proposal_name = "prop2"_n; + propose_approve_msig_linkauth_trx(chain, linkauth_proposal_name, "third"_n, {{ "tester"_n, config::active_name }}, 10); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + chain.produce_blocks(16); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + // this transaction will be delayed 20 blocks + constexpr name second_trnsfr_propsal_name = "prop3"_n; + propose_approve_msig_token_transfer_trx(chain, second_trnsfr_propsal_name, {{ "tester"_n, config::active_name }}, 10, "5.0000 CUR"); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("100.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); + + // first transfer will finally be performed + exec_msig_trx(chain, first_trnsfr_propsal_name); + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + // delay on minimum permission of transfer is finally removed + exec_msig_trx(chain, linkauth_proposal_name); + chain.produce_blocks(); + + // this transfer is performed right away since delay is removed + trace = chain.push_action("eosio.token"_n, name("transfer"), "tester"_n, fc::mutable_variant_object() + ("from", "tester") + ("to", "tester2") + ("quantity", "10.0000 CUR") + ("memo", "hi" ) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); + + chain.produce_blocks(16); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("89.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); + + // second transfer finally is performed + exec_msig_trx(chain, second_trnsfr_propsal_name); + chain.produce_blocks(); + + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("84.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("16.0000 CUR"), liquid_balance); + +} FC_LOG_AND_RETHROW() } /// link_delay_link_change_heirarchy_test + BOOST_AUTO_TEST_SUITE_END() From a4d2c5d3dbb985b5817e69628f2b2626ff523525 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Tue, 26 Sep 2023 19:25:50 -0400 Subject: [PATCH 22/29] rewrite canceldelay_test --- libraries/chain/controller.cpp | 16 ++++++ .../chain/include/eosio/chain/controller.hpp | 4 ++ unittests/delay_tests.cpp | 51 +++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index f9c59f26b6..c04013cb04 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -3716,6 +3716,22 @@ void controller::code_block_num_last_used(const digest_type& code_hash, uint8_t return my->code_block_num_last_used(code_hash, vm_type, vm_version, block_num); } +// Native action hardcodes sender empty and builds sender_id from trx id. +// This method modifies those two fields for contract generated deferred +// trxs so canceldelay can be tested by canceldelay_test in delay_tests.cpp. +// It cannot be used for any other purpose. +void controller::modify_gto_for_canceldelay_test(const transaction_id_type& trx_id) { + auto gto = my->db.find(trx_id); + if (gto) { + my->db.modify(*gto, [&]( auto& gtx ) { + gtx.sender = account_name(); + + fc::uint128 _id(trx_id._hash[3], trx_id._hash[2]); + gtx.sender_id = (unsigned __int128)_id; + }); + } +} + /// Protocol feature activation handlers: template<> diff --git a/libraries/chain/include/eosio/chain/controller.hpp b/libraries/chain/include/eosio/chain/controller.hpp index e25a201050..e90a97a59f 100644 --- a/libraries/chain/include/eosio/chain/controller.hpp +++ b/libraries/chain/include/eosio/chain/controller.hpp @@ -366,6 +366,10 @@ namespace eosio { namespace chain { bool is_write_window() const; void code_block_num_last_used(const digest_type& code_hash, uint8_t vm_type, uint8_t vm_version, uint32_t block_num); + // Warning: this method is only used by canceldelay_test + // in delay_tests.cpp. Do not use it for any other purpose. + void modify_gto_for_canceldelay_test(const transaction_id_type& trx_id); + private: friend class apply_context; friend class transaction_context; diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index 0447cc62c5..9759f030b3 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -1433,4 +1433,55 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_heirarchy_test ) { try { } FC_LOG_AND_RETHROW() } /// link_delay_link_change_heirarchy_test +// test canceldelay action cancelling a delayed transaction +BOOST_AUTO_TEST_CASE( canceldelay_test ) { try { + validating_tester chain; + chain.produce_block(); + + const auto& contract_account = account_name("defcontract"); + const auto& test_account = account_name("tester"); + + chain.produce_blocks(); + chain.create_accounts({contract_account, test_account}); + chain.produce_blocks(); + chain.set_code(contract_account, test_contracts::deferred_test_wasm()); + chain.set_abi(contract_account, test_contracts::deferred_test_abi()); + chain.produce_blocks(); + + auto gen_size = chain.control->db().get_index().size(); + BOOST_CHECK_EQUAL(0u, gen_size); + + chain.push_action( contract_account, "delayedcall"_n, test_account, fc::mutable_variant_object() + ("payer", test_account) + ("sender_id", 1) + ("contract", contract_account) + ("payload", 42) + ("delay_sec", 1000) + ("replace_existing", false) + ); + + const auto& idx = chain.control->db().get_index(); + gen_size = idx.size(); + BOOST_CHECK_EQUAL(1u, gen_size); + auto deferred_id = idx.begin()->trx_id; + + // canceldelay assumes sender and sender_id to be a specific + // format. hardcode them for testing purpose only + chain.control->modify_gto_for_canceldelay_test(deferred_id); + + // send canceldelay for the delayed transaction + signed_transaction trx; + trx.actions.emplace_back( + vector{{contract_account, config::active_name}}, + chain::canceldelay{{contract_account, config::active_name}, deferred_id} + ); + chain.set_transaction_headers(trx); + trx.sign(chain.get_private_key(contract_account, "active"), chain.control->get_chain_id()); + + chain.push_transaction(trx); + + gen_size = chain.control->db().get_index().size(); + BOOST_CHECK_EQUAL(0u, gen_size); +} FC_LOG_AND_RETHROW() } + BOOST_AUTO_TEST_SUITE_END() From 604b0e1a1d4941e16452ade631de30ee75805178 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Tue, 26 Sep 2023 21:37:17 -0400 Subject: [PATCH 23/29] rewrite canceldelay_test2 --- unittests/delay_tests.cpp | 79 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index 9759f030b3..c730d0707f 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -1484,4 +1484,83 @@ BOOST_AUTO_TEST_CASE( canceldelay_test ) { try { BOOST_CHECK_EQUAL(0u, gen_size); } FC_LOG_AND_RETHROW() } +// test canceldelay action under different permission levels +BOOST_AUTO_TEST_CASE( canceldelay_test2 ) { try { + validating_tester chain; + chain.produce_block(); + + const auto& contract_account = account_name("defcontract"); + const auto& tester_account = account_name("tester"); + + chain.produce_blocks(); + chain.create_accounts({contract_account, tester_account}); + chain.produce_blocks(); + chain.set_code(contract_account, test_contracts::deferred_test_wasm()); + chain.set_abi(contract_account, test_contracts::deferred_test_abi()); + chain.produce_blocks(); + + chain.push_action(config::system_account_name, updateauth::get_name(), contract_account, fc::mutable_variant_object() + ("account", "defcontract") + ("permission", "first") + ("parent", "active") + ("auth", authority(chain.get_public_key(contract_account, "first"), 5)) + ); + chain.produce_blocks(); + + auto gen_size = chain.control->db().get_index().size(); + BOOST_CHECK_EQUAL(0u, gen_size); + + chain.push_action( contract_account, "delayedcall"_n, tester_account, fc::mutable_variant_object() + ("payer", tester_account) + ("sender_id", 1) + ("contract", contract_account) + ("payload", 42) + ("delay_sec", 1000) + ("replace_existing", false) + ); + + const auto& idx = chain.control->db().get_index(); + gen_size = idx.size(); + BOOST_CHECK_EQUAL(1u, gen_size); + auto deferred_id = idx.begin()->trx_id; + + // canceldelay assumes sender and sender_id to be a specific + // format. hardcode them for testing purpose only + chain.control->modify_gto_for_canceldelay_test(deferred_id); + + // attempt canceldelay with wrong canceling_auth for delayed trx + { + signed_transaction trx; + trx.actions.emplace_back(vector{{"tester"_n, config::active_name}}, + chain::canceldelay{{"tester"_n, config::active_name}, deferred_id}); + chain.set_transaction_headers(trx); + trx.sign(chain.get_private_key("tester"_n, "active"), chain.control->get_chain_id()); + BOOST_REQUIRE_EXCEPTION( chain.push_transaction(trx), action_validate_exception, + fc_exception_message_is("canceling_auth in canceldelay action was not found as authorization in the original delayed transaction") ); + } + + // attempt canceldelay with wrong permission for delayed trx + { + signed_transaction trx; + trx.actions.emplace_back(vector{{contract_account, "first"_n}}, + chain::canceldelay{{contract_account, "first"_n}, deferred_id}); + chain.set_transaction_headers(trx); + trx.sign(chain.get_private_key(contract_account, "first"), chain.control->get_chain_id()); + BOOST_REQUIRE_EXCEPTION( chain.push_transaction(trx), action_validate_exception, + fc_exception_message_is("canceling_auth in canceldelay action was not found as authorization in the original delayed transaction") ); + } + + // attempt canceldelay with wrong signature for delayed trx + { + signed_transaction trx; + trx.actions.emplace_back(vector{{contract_account, config::active_name}}, + chain::canceldelay{{contract_account, config::active_name}, deferred_id}); + chain.set_transaction_headers(trx); + trx.sign(chain.get_private_key(contract_account, "first"), chain.control->get_chain_id()); + BOOST_REQUIRE_THROW( chain.push_transaction(trx), unsatisfied_authorization ); + BOOST_REQUIRE_EXCEPTION( chain.push_transaction(trx), unsatisfied_authorization, + fc_exception_message_starts_with("transaction declares authority") ); + } +} FC_LOG_AND_RETHROW() } + BOOST_AUTO_TEST_SUITE_END() From c7032c5707a82775294e24249cbb45e0564180f3 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Wed, 27 Sep 2023 08:47:10 -0400 Subject: [PATCH 24/29] restore max_transaction_delay_create --- unittests/delay_tests.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index c730d0707f..ffade82bf6 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -1563,4 +1563,25 @@ BOOST_AUTO_TEST_CASE( canceldelay_test2 ) { try { } } FC_LOG_AND_RETHROW() } +BOOST_AUTO_TEST_CASE( max_transaction_delay_create ) { try { + //assuming max transaction delay is 45 days (default in config.hpp) + validating_tester chain; + + const auto& tester_account = "tester"_n; + + chain.produce_blocks(); + chain.create_account("tester"_n); + chain.produce_blocks(10); + + BOOST_REQUIRE_EXCEPTION( + chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "first") + ("parent", "active") + ("auth", authority(chain.get_public_key(tester_account, "first"), 50*86400)) ), // 50 days delay + action_validate_exception, + fc_exception_message_starts_with("Cannot set delay longer than max_transacton_delay") + ); +} FC_LOG_AND_RETHROW() } /// max_transaction_delay_create + BOOST_AUTO_TEST_SUITE_END() From 0ef0175764944f6137a446a820715194909fb898 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Wed, 27 Sep 2023 08:58:36 -0400 Subject: [PATCH 25/29] update max_transaction_delay_execute --- unittests/delay_tests.cpp | 57 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index ffade82bf6..a94af4c34a 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -1584,4 +1584,61 @@ BOOST_AUTO_TEST_CASE( max_transaction_delay_create ) { try { ); } FC_LOG_AND_RETHROW() } /// max_transaction_delay_create + +BOOST_AUTO_TEST_CASE( max_transaction_delay_execute ) { try { + //assuming max transaction delay is 45 days (default in config.hpp) + validating_tester chain; + const auto& tester_account = "tester"_n; + + create_accounts(chain); + + chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() + ("issuer", "eosio.token" ) + ("maximum_supply", "9000000.0000 CUR" ) + ); + chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() + ("to", "tester") + ("quantity", "100.0000 CUR") + ("memo", "for stuff") + ); + + //create a permission level with delay 30 days and associate it with token transfer + auto trace = chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "first") + ("parent", "active") + ("auth", authority(chain.get_public_key(tester_account, "first"), 30*86400)) // 30 days delay + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + trace = chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("code", "eosio.token") + ("type", "transfer") + ("requirement", "first")); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + chain.produce_blocks(); + + //change max_transaction_delay to 60 sec + auto params = chain.control->get_global_properties().configuration; + params.max_transaction_delay = 60; + chain.push_action( config::system_account_name, "setparams"_n, config::system_account_name, mutable_variant_object() + ("params", params) ); + + chain.produce_blocks(); + //should be able to create a msig transaction with delay 60 sec, despite permission delay being 30 days, because max_transaction_delay is 60 sec + constexpr name proposal_name = "prop1"_n; + propose_approve_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}, 60, "9.0000 CUR"); + + //check that the delayed msig transaction can be executed after after 60 sec + chain.produce_blocks(120); + exec_msig_trx(chain, proposal_name); + + //check that the transfer really happened + auto liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("91.0000 CUR"), liquid_balance); + +} FC_LOG_AND_RETHROW() } /// max_transaction_delay_execute + BOOST_AUTO_TEST_SUITE_END() From c07caf2770528318d3621b68b04f9a5594501925 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Wed, 27 Sep 2023 10:16:08 -0400 Subject: [PATCH 26/29] minor refactoring --- unittests/delay_tests.cpp | 200 ++++++++++++++------------------------ 1 file changed, 72 insertions(+), 128 deletions(-) diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index a94af4c34a..2c99288361 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -39,9 +39,29 @@ static void create_accounts(validating_tester& chain) { chain.produce_blocks(10); } -static void propose_approve_msig_token_transfer_trx(validating_tester& chain, name proposal_name, const vector& perm, uint32_t delay_sec, const std::string& quantity) { +static void propose_approve_msig_trx(validating_tester& chain, const name& proposal_name, const vector& perm, const fc::variant& pretty_trx) { + vector requested_perm = {{ "tester"_n, config::active_name }}; + transaction trx; + abi_serializer::from_variant(pretty_trx, trx, chain.get_resolver(), abi_serializer::create_yield_function(chain.abi_serializer_max_time)); + + chain.push_action("eosio.msig"_n, "propose"_n, perm, + mvo() + ("proposer", "tester") + ("proposal_name", proposal_name) + ("trx", trx) + ("requested", requested_perm) + ); + chain.push_action("eosio.msig"_n, "approve"_n, "tester"_n, + mvo() + ("proposer", "tester") + ("proposal_name", proposal_name) + ("level", permission_level{ "tester"_n, config::active_name }) + ); +} + +static void propose_approve_msig_token_transfer_trx(validating_tester& chain, const name& proposal_name, const vector& perm, uint32_t delay_sec, const std::string& quantity) { vector transfer_perm = {{ "tester"_n, config::active_name }}; - fc::variant pretty_trx = fc::mutable_variant_object() + fc::variant pretty_trx = mvo() ("expiration", "2020-01-01T00:30") ("ref_block_num", 2) ("ref_block_prefix", 3) @@ -62,27 +82,10 @@ static void propose_approve_msig_token_transfer_trx(validating_tester& chain, na }) ); - transaction trx; - abi_serializer::from_variant(pretty_trx, trx, chain.get_resolver(), abi_serializer::create_yield_function(chain.abi_serializer_max_time)); - - vector requested_perm = {{ "tester"_n, config::active_name }}; - chain.push_action("eosio.msig"_n, "propose"_n, perm, - mvo() - ("proposer", "tester") - ("proposal_name", proposal_name) - ("trx", trx) - ("requested", requested_perm) - ); - - chain.push_action("eosio.msig"_n, "approve"_n, "tester"_n, - mvo() - ("proposer", "tester") - ("proposal_name", proposal_name) - ("level", permission_level{ "tester"_n, config::active_name }) - ); + propose_approve_msig_trx(chain, proposal_name, perm, pretty_trx); } -static void propose_approve_msig_updateauth_trx(validating_tester& chain, name proposal_name, const vector& perm, uint32_t delay_sec) { +static void propose_approve_msig_updateauth_trx(validating_tester& chain, const name& proposal_name, const vector& perm, uint32_t delay_sec) { vector transfer_perm = {{ "tester"_n, config::active_name }}; fc::variant pretty_trx = fc::mutable_variant_object() ("expiration", "2020-01-01T00:30") @@ -105,27 +108,10 @@ static void propose_approve_msig_updateauth_trx(validating_tester& chain, name p }) ); - transaction trx; - abi_serializer::from_variant(pretty_trx, trx, chain.get_resolver(), abi_serializer::create_yield_function(chain.abi_serializer_max_time)); - - vector requested_perm = {{ "tester"_n, config::active_name }}; - chain.push_action("eosio.msig"_n, "propose"_n, perm, - mvo() - ("proposer", "tester") - ("proposal_name", proposal_name) - ("trx", trx) - ("requested", requested_perm) - ); - - chain.push_action("eosio.msig"_n, "approve"_n, "tester"_n, - mvo() - ("proposer", "tester") - ("proposal_name", proposal_name) - ("level", permission_level{ "tester"_n, config::active_name }) - ); + propose_approve_msig_trx(chain, proposal_name, perm, pretty_trx); } -static void propose_approve_msig_linkauth_trx(validating_tester& chain, const name proposal_name, const name requirement, const vector& perm, uint32_t delay_sec) { +static void propose_approve_msig_linkauth_trx(validating_tester& chain, const name& proposal_name, const name& requirement, const vector& perm, uint32_t delay_sec) { vector transfer_perm = {{ "tester"_n, config::active_name }}; fc::variant pretty_trx = fc::mutable_variant_object() ("expiration", "2020-01-01T00:30") @@ -148,29 +134,12 @@ static void propose_approve_msig_linkauth_trx(validating_tester& chain, const na }) ); - transaction trx; - abi_serializer::from_variant(pretty_trx, trx, chain.get_resolver(), abi_serializer::create_yield_function(chain.abi_serializer_max_time)); - - vector requested_perm = {{ "tester"_n, config::active_name }}; - chain.push_action("eosio.msig"_n, "propose"_n, perm, - mvo() - ("proposer", "tester") - ("proposal_name", proposal_name) - ("trx", trx) - ("requested", requested_perm) - ); - - chain.push_action("eosio.msig"_n, "approve"_n, "tester"_n, - mvo() - ("proposer", "tester") - ("proposal_name", proposal_name) - ("level", permission_level{ "tester"_n, config::active_name }) - ); + propose_approve_msig_trx(chain, proposal_name, perm, pretty_trx); } -static void propose_approve_msig_unlinkauth_trx(validating_tester& chain, name proposal_name, const vector& perm, uint32_t delay_sec) { +static void propose_approve_msig_unlinkauth_trx(validating_tester& chain, const name& proposal_name, const vector& perm, uint32_t delay_sec) { vector transfer_perm = {{ "tester"_n, config::active_name }}; - fc::variant pretty_trx = fc::mutable_variant_object() + fc::variant pretty_trx = mvo() ("expiration", "2020-01-01T00:30") ("ref_block_num", 2) ("ref_block_prefix", 3) @@ -190,24 +159,7 @@ static void propose_approve_msig_unlinkauth_trx(validating_tester& chain, name p }) ); - transaction trx; - abi_serializer::from_variant(pretty_trx, trx, chain.get_resolver(), abi_serializer::create_yield_function(chain.abi_serializer_max_time)); - - vector requested_perm = {{ "tester"_n, config::active_name }}; - chain.push_action("eosio.msig"_n, "propose"_n, perm, - mvo() - ("proposer", "tester") - ("proposal_name", proposal_name) - ("trx", trx) - ("requested", requested_perm) - ); - - chain.push_action("eosio.msig"_n, "approve"_n, "tester"_n, - mvo() - ("proposer", "tester") - ("proposal_name", proposal_name) - ("level", permission_level{ "tester"_n, config::active_name }) - ); + propose_approve_msig_trx(chain, proposal_name, perm, pretty_trx); } static void exec_msig_trx(validating_tester& chain, name proposal_name) { @@ -234,7 +186,7 @@ BOOST_FIXTURE_TEST_CASE( delayed_trx_blocked, validating_tester ) { try { account_name a = "newco"_n; account_name creator = config::system_account_name; - auto owner_auth = authority( get_public_key( a, "owner" ) ); + auto owner_auth = authority( get_public_key( a, "owner" ) ); trx.actions.emplace_back( vector{{creator,config::active_name}}, newaccount{ .creator = creator, @@ -249,7 +201,6 @@ BOOST_FIXTURE_TEST_CASE( delayed_trx_blocked, validating_tester ) { try { // delayed trx is blocked BOOST_CHECK_EXCEPTION(push_transaction( trx ), fc::exception, [&](const fc::exception &e) { - // any incoming trx is blocked return expect_assert_message(e, "transaction cannot be delayed"); }); @@ -276,7 +227,6 @@ BOOST_AUTO_TEST_CASE( delayed_action_blocked ) { try { 20, 10), fc::exception, [&](const fc::exception &e) { - // any delayed incoming trx is blocked return expect_assert_message(e, "transaction cannot be delayed"); }); @@ -293,20 +243,21 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_test ) { try { create_accounts(chain); chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("permission", "first") - ("parent", "active") - ("auth", authority(chain.get_public_key(tester_account, "first"))) + ("account", "tester") + ("permission", "first") + ("parent", "active") + ("auth", authority(chain.get_public_key(tester_account, "first"))) ); chain.push_action(config::system_account_name, linkauth::get_name(), tester_account, fc::mutable_variant_object() - ("account", "tester") - ("code", eosio_token) - ("type", "transfer") - ("requirement", "first")); + ("account", "tester") + ("code", eosio_token) + ("type", "transfer") + ("requirement", "first") + ); chain.produce_blocks(); chain.push_action("eosio.token"_n, "create"_n, "eosio.token"_n, mutable_variant_object() - ("issuer", eosio_token) - ("maximum_supply", "9000000.0000 CUR") + ("issuer", eosio_token) + ("maximum_supply", "9000000.0000 CUR") ); chain.push_action("eosio.token"_n, name("issue"), "eosio.token"_n, fc::mutable_variant_object() @@ -360,10 +311,8 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_test ) { try { // propose and approve an msig trx that transfers "quantity" tokens // from tester to tester2 with a delay of "delay_seconds" - constexpr name proposal_name = "prop1"_n; - constexpr uint32_t delay_seconds = 10; - constexpr auto quantity = "3.0000 CUR"; - propose_approve_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}, delay_seconds, quantity); + constexpr name proposal_name = "prop1"_n; + propose_approve_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}, 10, "3.0000 CUR"); chain.produce_blocks(); @@ -458,10 +407,8 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_parent_permission_test ) { try { // Propose and approve an msig trx that transfers "quantity" tokens // from tester to tester2 with a delay of "delay_seconds" - constexpr name proposal_name = "prop1"_n; - constexpr uint32_t delay_seconds = 15; - constexpr auto quantity = "3.0000 CUR"; - propose_approve_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::owner_name }}, delay_seconds, quantity); + constexpr name proposal_name = "prop1"_n; + propose_approve_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::owner_name }}, 15, "3.0000 CUR"); liquid_balance = get_currency_balance(chain, "tester"_n); BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); @@ -501,25 +448,6 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_parent_permission_test ) { try { } FC_LOG_AND_RETHROW() }/// link_delay_direct_parent_permission_test -BOOST_AUTO_TEST_CASE( test_blockchain_params_enabled ) { try { - //since validation_tester activates all features here we will test how setparams works without - //blockchain_parameters enabled - tester chain( setup_policy::preactivate_feature_and_new_bios ); - - //change max_transaction_delay to 60 sec - auto params = chain.control->get_global_properties().configuration; - params.max_transaction_delay = 60; - chain.push_action(config::system_account_name, - "setparams"_n, - config::system_account_name, - mutable_variant_object()("params", params) ); - - BOOST_CHECK_EQUAL(chain.control->get_global_properties().configuration.max_transaction_delay, 60u); - - chain.produce_blocks(); - -} FC_LOG_AND_RETHROW() } - // test link to permission with delay on permission between min permission and authorizing permission it BOOST_AUTO_TEST_CASE( link_delay_direct_walk_parent_permissions_test ) { try { validating_tester chain; @@ -603,10 +531,8 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_walk_parent_permissions_test ) { try { // propose and approve an msig trx that transfers "quantity" tokens // from tester to tester2 with a delay of "delay_seconds" - constexpr name proposal_name = "prop1"_n; - constexpr uint32_t delay_seconds = 20; - constexpr auto quantity = "3.0000 CUR"; - propose_approve_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}, delay_seconds, quantity); + constexpr name proposal_name = "prop1"_n; + propose_approve_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}, 20, "3.0000 CUR"); liquid_balance = get_currency_balance(chain, "tester"_n); BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); @@ -1196,9 +1122,8 @@ BOOST_AUTO_TEST_CASE( link_delay_unlink_test ) { try { ); // this transaction will be delayed 20 blocks - constexpr name unlinkauth_proposal_name = "prop2"_n; - constexpr uint32_t unlinkauth_delay_seconds = 10; - propose_approve_msig_unlinkauth_trx(chain, unlinkauth_proposal_name, {{ "tester"_n, config::active_name }}, unlinkauth_delay_seconds); + constexpr name unlinkauth_proposal_name = "prop2"_n; + propose_approve_msig_unlinkauth_trx(chain, unlinkauth_proposal_name, {{ "tester"_n, config::active_name }}, 10); chain.produce_blocks(); @@ -1353,7 +1278,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_heirarchy_test ) { try { BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); // this transaction will be delayed 20 blocks - constexpr name linkauth_proposal_name = "prop2"_n; + constexpr name linkauth_proposal_name = "prop2"_n; propose_approve_msig_linkauth_trx(chain, linkauth_proposal_name, "third"_n, {{ "tester"_n, config::active_name }}, 10); chain.produce_blocks(); @@ -1482,7 +1407,7 @@ BOOST_AUTO_TEST_CASE( canceldelay_test ) { try { gen_size = chain.control->db().get_index().size(); BOOST_CHECK_EQUAL(0u, gen_size); -} FC_LOG_AND_RETHROW() } +} FC_LOG_AND_RETHROW() } /// canceldelay_test // test canceldelay action under different permission levels BOOST_AUTO_TEST_CASE( canceldelay_test2 ) { try { @@ -1561,7 +1486,7 @@ BOOST_AUTO_TEST_CASE( canceldelay_test2 ) { try { BOOST_REQUIRE_EXCEPTION( chain.push_transaction(trx), unsatisfied_authorization, fc_exception_message_starts_with("transaction declares authority") ); } -} FC_LOG_AND_RETHROW() } +} FC_LOG_AND_RETHROW() } /// canceldelay_test2 BOOST_AUTO_TEST_CASE( max_transaction_delay_create ) { try { //assuming max transaction delay is 45 days (default in config.hpp) @@ -1641,4 +1566,23 @@ BOOST_AUTO_TEST_CASE( max_transaction_delay_execute ) { try { } FC_LOG_AND_RETHROW() } /// max_transaction_delay_execute +BOOST_AUTO_TEST_CASE( test_blockchain_params_enabled ) { try { + //since validation_tester activates all features here we will test how setparams works without + //blockchain_parameters enabled + tester chain( setup_policy::preactivate_feature_and_new_bios ); + + //change max_transaction_delay to 60 sec + auto params = chain.control->get_global_properties().configuration; + params.max_transaction_delay = 60; + chain.push_action(config::system_account_name, + "setparams"_n, + config::system_account_name, + mutable_variant_object()("params", params) ); + + BOOST_CHECK_EQUAL(chain.control->get_global_properties().configuration.max_transaction_delay, 60u); + + chain.produce_blocks(); + +} FC_LOG_AND_RETHROW() } + BOOST_AUTO_TEST_SUITE_END() From 2d7811d3f29f356ee1e01f45dee5f796c08986e1 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Wed, 27 Sep 2023 13:48:54 -0400 Subject: [PATCH 27/29] incorporate review comments for producer_plugin.cpp --- plugins/producer_plugin/producer_plugin.cpp | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index 6ff0eab1d8..ccba614c65 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -17,10 +17,6 @@ #include #include -#include -#include -#include -#include #include #include @@ -28,15 +24,6 @@ #include #include -namespace bmi = boost::multi_index; -using bmi::hashed_unique; -using bmi::indexed_by; -using bmi::member; -using bmi::ordered_non_unique; -using bmi::tag; - -using boost::multi_index_container; - using boost::signals2::scoped_connection; using std::string; using std::vector; @@ -2331,8 +2318,6 @@ void producer_plugin_impl::retire_expired_deferred_trxs(const fc::time_point& de const transaction_id_type trx_id = expired_itr->trx_id; // make copy since reference could be invalidated auto expired_itr_next = expired_itr; // save off next since expired_itr may be invalidated by loop ++expired_itr_next; - const auto next_expired = expired_itr_next != expired_idx.end() ? expired_itr_next->expiration : expired_itr->expiration; - const auto next_id = expired_itr_next != expired_idx.end() ? expired_itr_next->id : expired_itr->id; num_processed++; @@ -2347,9 +2332,7 @@ void producer_plugin_impl::retire_expired_deferred_trxs(const fc::time_point& de try { auto start = fc::time_point::now(); auto trx_tracker = _time_tracker.start_trx(false, start); // delayed transaction cannot be transient - fc::microseconds max_trx_time = fc::milliseconds(_max_transaction_time_ms.load()); - if (max_trx_time.count() < 0) - max_trx_time = fc::microseconds::maximum(); + fc::microseconds max_trx_time = fc::microseconds::maximum(); // hard-coded as it is not used in push_scheduled_transaction when trx expired. auto trace = chain.push_scheduled_transaction(trx_id, deadline, max_trx_time, 0, false); auto end = fc::time_point::now(); @@ -2387,7 +2370,7 @@ void producer_plugin_impl::retire_expired_deferred_trxs(const fc::time_point& de if (expired_itr_next == expired_idx.end()) break; - expired_itr = expired_idx.lower_bound(boost::make_tuple(next_expired, next_id)); + expired_itr = expired_itr_next; } if (expired_size > 0) { From 907d54df33f809d2ad99ca8400aa93c4c3e139fa Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Wed, 27 Sep 2023 14:43:39 -0400 Subject: [PATCH 28/29] move modify_gto_for_canceldelay_test out of controller to delay_test --- libraries/chain/controller.cpp | 16 --------------- .../chain/include/eosio/chain/controller.hpp | 5 +---- unittests/delay_tests.cpp | 20 +++++++++++++++++-- 3 files changed, 19 insertions(+), 22 deletions(-) diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index c04013cb04..f9c59f26b6 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -3716,22 +3716,6 @@ void controller::code_block_num_last_used(const digest_type& code_hash, uint8_t return my->code_block_num_last_used(code_hash, vm_type, vm_version, block_num); } -// Native action hardcodes sender empty and builds sender_id from trx id. -// This method modifies those two fields for contract generated deferred -// trxs so canceldelay can be tested by canceldelay_test in delay_tests.cpp. -// It cannot be used for any other purpose. -void controller::modify_gto_for_canceldelay_test(const transaction_id_type& trx_id) { - auto gto = my->db.find(trx_id); - if (gto) { - my->db.modify(*gto, [&]( auto& gtx ) { - gtx.sender = account_name(); - - fc::uint128 _id(trx_id._hash[3], trx_id._hash[2]); - gtx.sender_id = (unsigned __int128)_id; - }); - } -} - /// Protocol feature activation handlers: template<> diff --git a/libraries/chain/include/eosio/chain/controller.hpp b/libraries/chain/include/eosio/chain/controller.hpp index e90a97a59f..21c1bc9620 100644 --- a/libraries/chain/include/eosio/chain/controller.hpp +++ b/libraries/chain/include/eosio/chain/controller.hpp @@ -366,13 +366,10 @@ namespace eosio { namespace chain { bool is_write_window() const; void code_block_num_last_used(const digest_type& code_hash, uint8_t vm_type, uint8_t vm_version, uint32_t block_num); - // Warning: this method is only used by canceldelay_test - // in delay_tests.cpp. Do not use it for any other purpose. - void modify_gto_for_canceldelay_test(const transaction_id_type& trx_id); - private: friend class apply_context; friend class transaction_context; + friend void modify_gto_for_canceldelay_test(controller& control, const transaction_id_type& trx_id); // canceldelay_test in delay_tests.cpp need access to mutable_db chainbase::database& mutable_db()const; diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index 2c99288361..122ea997bf 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -16,6 +16,22 @@ using mvo = fc::mutable_variant_object; const std::string eosio_token = name("eosio.token"_n).to_string(); +// Native action hardcodes sender empty and builds sender_id from trx id. +// This method modifies those two fields for contract generated deferred +// trxs so canceldelay can be tested by canceldelay_test. +namespace eosio::chain { +inline void modify_gto_for_canceldelay_test(controller& control, const transaction_id_type& trx_id) { + auto gto = control.mutable_db().find(trx_id); + if (gto) { + control.mutable_db().modify(*gto, [&]( auto& gtx ) { + gtx.sender = account_name(); + + fc::uint128 _id(trx_id._hash[3], trx_id._hash[2]); + gtx.sender_id = (unsigned __int128)_id; + }); + } +}} /// namespace eosio::chain + static void create_accounts(validating_tester& chain) { chain.produce_blocks(); chain.create_accounts({"eosio.msig"_n, "eosio.token"_n}); @@ -1392,7 +1408,7 @@ BOOST_AUTO_TEST_CASE( canceldelay_test ) { try { // canceldelay assumes sender and sender_id to be a specific // format. hardcode them for testing purpose only - chain.control->modify_gto_for_canceldelay_test(deferred_id); + modify_gto_for_canceldelay_test(*(chain.control.get()), deferred_id); // send canceldelay for the delayed transaction signed_transaction trx; @@ -1451,7 +1467,7 @@ BOOST_AUTO_TEST_CASE( canceldelay_test2 ) { try { // canceldelay assumes sender and sender_id to be a specific // format. hardcode them for testing purpose only - chain.control->modify_gto_for_canceldelay_test(deferred_id); + modify_gto_for_canceldelay_test(*(chain.control.get()), deferred_id); // attempt canceldelay with wrong canceling_auth for delayed trx { From 35321c95bf093e532fe8c917960c09278f00a5f8 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Thu, 28 Sep 2023 18:22:58 -0400 Subject: [PATCH 29/29] add missing permission delay back to link_delay_direct_parent_permission_test and minor refactoring --- unittests/delay_tests.cpp | 126 +++++++++++++++++++++----------------- 1 file changed, 69 insertions(+), 57 deletions(-) diff --git a/unittests/delay_tests.cpp b/unittests/delay_tests.cpp index 122ea997bf..245aceed8b 100644 --- a/unittests/delay_tests.cpp +++ b/unittests/delay_tests.cpp @@ -55,28 +55,27 @@ static void create_accounts(validating_tester& chain) { chain.produce_blocks(10); } -static void propose_approve_msig_trx(validating_tester& chain, const name& proposal_name, const vector& perm, const fc::variant& pretty_trx) { - vector requested_perm = {{ "tester"_n, config::active_name }}; +static void propose_approve_msig_trx(validating_tester& chain, const name& proposal_name, const permission_level& perm, const fc::variant& pretty_trx) { + vector requested_perm = { perm }; transaction trx; abi_serializer::from_variant(pretty_trx, trx, chain.get_resolver(), abi_serializer::create_yield_function(chain.abi_serializer_max_time)); - chain.push_action("eosio.msig"_n, "propose"_n, perm, + chain.push_action("eosio.msig"_n, "propose"_n, vector{perm}, mvo() ("proposer", "tester") ("proposal_name", proposal_name) ("trx", trx) ("requested", requested_perm) ); - chain.push_action("eosio.msig"_n, "approve"_n, "tester"_n, + chain.push_action("eosio.msig"_n, "approve"_n, vector{perm}, mvo() ("proposer", "tester") ("proposal_name", proposal_name) - ("level", permission_level{ "tester"_n, config::active_name }) + ("level", perm) ); } -static void propose_approve_msig_token_transfer_trx(validating_tester& chain, const name& proposal_name, const vector& perm, uint32_t delay_sec, const std::string& quantity) { - vector transfer_perm = {{ "tester"_n, config::active_name }}; +static void propose_approve_msig_token_transfer_trx(validating_tester& chain, const name& proposal_name, const permission_level& perm, uint32_t delay_sec, const std::string& quantity) { fc::variant pretty_trx = mvo() ("expiration", "2020-01-01T00:30") ("ref_block_num", 2) @@ -88,7 +87,7 @@ static void propose_approve_msig_token_transfer_trx(validating_tester& chain, co mvo() ("account", name("eosio.token"_n)) ("name", "transfer") - ("authorization", transfer_perm) + ("authorization", vector{perm}) ("data", fc::mutable_variant_object() ("from", name("tester"_n)) ("to", name("tester2"_n)) @@ -101,8 +100,7 @@ static void propose_approve_msig_token_transfer_trx(validating_tester& chain, co propose_approve_msig_trx(chain, proposal_name, perm, pretty_trx); } -static void propose_approve_msig_updateauth_trx(validating_tester& chain, const name& proposal_name, const vector& perm, uint32_t delay_sec) { - vector transfer_perm = {{ "tester"_n, config::active_name }}; +static void propose_approve_msig_updateauth_trx(validating_tester& chain, const name& proposal_name, const permission_level& perm, uint32_t delay_sec) { fc::variant pretty_trx = fc::mutable_variant_object() ("expiration", "2020-01-01T00:30") ("ref_block_num", 2) @@ -114,7 +112,7 @@ static void propose_approve_msig_updateauth_trx(validating_tester& chain, const mvo() ("account", config::system_account_name) ("name", updateauth::get_name()) - ("authorization", transfer_perm) + ("authorization", vector {{ "tester"_n, config::active_name }}) ("data", fc::mutable_variant_object() ("account", "tester") ("permission", "first") @@ -127,8 +125,7 @@ static void propose_approve_msig_updateauth_trx(validating_tester& chain, const propose_approve_msig_trx(chain, proposal_name, perm, pretty_trx); } -static void propose_approve_msig_linkauth_trx(validating_tester& chain, const name& proposal_name, const name& requirement, const vector& perm, uint32_t delay_sec) { - vector transfer_perm = {{ "tester"_n, config::active_name }}; +static void propose_approve_msig_linkauth_trx(validating_tester& chain, const name& proposal_name, const name& requirement, const permission_level& perm, uint32_t delay_sec) { fc::variant pretty_trx = fc::mutable_variant_object() ("expiration", "2020-01-01T00:30") ("ref_block_num", 2) @@ -140,7 +137,7 @@ static void propose_approve_msig_linkauth_trx(validating_tester& chain, const na mvo() ("account", config::system_account_name) ("name", linkauth::get_name()) - ("authorization", transfer_perm) + ("authorization", vector{{ "tester"_n, config::active_name }}) ("data", fc::mutable_variant_object() ("account", "tester") ("code", eosio_token) @@ -153,8 +150,7 @@ static void propose_approve_msig_linkauth_trx(validating_tester& chain, const na propose_approve_msig_trx(chain, proposal_name, perm, pretty_trx); } -static void propose_approve_msig_unlinkauth_trx(validating_tester& chain, const name& proposal_name, const vector& perm, uint32_t delay_sec) { - vector transfer_perm = {{ "tester"_n, config::active_name }}; +static void propose_approve_msig_unlinkauth_trx(validating_tester& chain, const name& proposal_name, const permission_level& perm, uint32_t delay_sec) { fc::variant pretty_trx = mvo() ("expiration", "2020-01-01T00:30") ("ref_block_num", 2) @@ -166,7 +162,7 @@ static void propose_approve_msig_unlinkauth_trx(validating_tester& chain, const mvo() ("account", config::system_account_name) ("name", unlinkauth::get_name()) - ("authorization", transfer_perm) + ("authorization", vector{{ "tester"_n, config::active_name}}) ("data", fc::mutable_variant_object() ("account", "tester") ("code", eosio_token) @@ -178,8 +174,8 @@ static void propose_approve_msig_unlinkauth_trx(validating_tester& chain, const propose_approve_msig_trx(chain, proposal_name, perm, pretty_trx); } -static void exec_msig_trx(validating_tester& chain, name proposal_name) { - chain.push_action("eosio.msig"_n, "exec"_n, "tester"_n, +static void exec_msig_trx(validating_tester& chain, name proposal_name, const vector& perm) { + chain.push_action("eosio.msig"_n, "exec"_n, perm, mvo() ("proposer", "tester") ("proposal_name", proposal_name) @@ -328,7 +324,7 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_test ) { try { // propose and approve an msig trx that transfers "quantity" tokens // from tester to tester2 with a delay of "delay_seconds" constexpr name proposal_name = "prop1"_n; - propose_approve_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}, 10, "3.0000 CUR"); + propose_approve_msig_token_transfer_trx(chain, proposal_name, { "tester"_n, config::active_name }, 10, "3.0000 CUR"); chain.produce_blocks(); @@ -352,7 +348,7 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_test ) { try { BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); // executue after delay of 10 seconds - exec_msig_trx(chain, proposal_name); + exec_msig_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); @@ -419,12 +415,28 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_parent_permission_test ) { try { BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + liquid_balance = get_currency_balance(chain, "eosio.token"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("999900.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); + liquid_balance = get_currency_balance(chain, "tester2"_n); + BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); + + trace = chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object() + ("account", "tester") + ("permission", "active") + ("parent", "owner") + ("auth", authority(chain.get_public_key(tester_account, "active"), 15)) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + chain.produce_blocks(); chain.produce_blocks(); // Propose and approve an msig trx that transfers "quantity" tokens // from tester to tester2 with a delay of "delay_seconds" constexpr name proposal_name = "prop1"_n; - propose_approve_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::owner_name }}, 15, "3.0000 CUR"); + propose_approve_msig_token_transfer_trx(chain, proposal_name, { "tester"_n, config::owner_name }, 15, "3.0000 CUR"); liquid_balance = get_currency_balance(chain, "tester"_n); BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); @@ -455,7 +467,7 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_parent_permission_test ) { try { chain.produce_blocks(); // executue the msig trx - exec_msig_trx(chain, proposal_name); + exec_msig_trx(chain, proposal_name, {{ "tester"_n, config::owner_name }}); liquid_balance = get_currency_balance(chain, "tester"_n); BOOST_REQUIRE_EQUAL(asset::from_string("96.0000 CUR"), liquid_balance); @@ -548,7 +560,7 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_walk_parent_permissions_test ) { try { // propose and approve an msig trx that transfers "quantity" tokens // from tester to tester2 with a delay of "delay_seconds" constexpr name proposal_name = "prop1"_n; - propose_approve_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}, 20, "3.0000 CUR"); + propose_approve_msig_token_transfer_trx(chain, proposal_name, { "tester"_n, config::active_name }, 20, "3.0000 CUR"); liquid_balance = get_currency_balance(chain, "tester"_n); BOOST_REQUIRE_EQUAL(asset::from_string("99.0000 CUR"), liquid_balance); @@ -577,7 +589,7 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_walk_parent_permissions_test ) { try { BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); // executue after delay - exec_msig_trx(chain, proposal_name); + exec_msig_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); @@ -639,7 +651,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_test ) { try { constexpr name proposal_1_name = "prop1"_n; constexpr uint32_t delay_seconds = 10; constexpr auto quantity = "1.0000 CUR"; - propose_approve_msig_token_transfer_trx(chain, proposal_1_name, {{ "tester"_n, config::active_name }}, delay_seconds, quantity); + propose_approve_msig_token_transfer_trx(chain, proposal_1_name, { "tester"_n, config::active_name }, delay_seconds, quantity); chain.produce_blocks(); @@ -653,7 +665,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_test ) { try { // this transaction will be delayed 20 blocks constexpr name proposal_2_name = "prop2"_n; constexpr uint32_t delay_seconds_2 = 10; - propose_approve_msig_updateauth_trx(chain, proposal_2_name, {{ "tester"_n, config::active_name }}, delay_seconds_2); + propose_approve_msig_updateauth_trx(chain, proposal_2_name, { "tester"_n, config::active_name }, delay_seconds_2); chain.produce_blocks(); @@ -673,7 +685,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_test ) { try { constexpr name proposal_3_name = "prop3"_n; constexpr uint32_t delay_seconds_3 = 10; constexpr auto quantity_3 = "5.0000 CUR"; - propose_approve_msig_token_transfer_trx(chain, proposal_3_name, {{ "tester"_n, config::active_name }}, delay_seconds_3, quantity_3); + propose_approve_msig_token_transfer_trx(chain, proposal_3_name, { "tester"_n, config::active_name }, delay_seconds_3, quantity_3); chain.produce_blocks(); @@ -690,7 +702,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_test ) { try { BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); // first transfer will finally be performed - exec_msig_trx(chain, proposal_1_name); + exec_msig_trx(chain, proposal_1_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); liquid_balance = get_currency_balance(chain, "tester"_n); @@ -699,7 +711,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_test ) { try { BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); // delayed update auth removing the delay will finally execute - exec_msig_trx(chain, proposal_2_name); + exec_msig_trx(chain, proposal_2_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); // this transfer is performed right away since delay is removed @@ -726,7 +738,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_test ) { try { BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); // second transfer finally is performed - exec_msig_trx(chain, proposal_3_name); + exec_msig_trx(chain, proposal_3_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); liquid_balance = get_currency_balance(chain, "tester"_n); @@ -793,7 +805,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_with_delay_heirarchy_test ) { constexpr name proposal_1_name = "prop1"_n; constexpr uint32_t delay_seconds = 10; constexpr auto quantity = "1.0000 CUR"; - propose_approve_msig_token_transfer_trx(chain, proposal_1_name, {{ "tester"_n, config::active_name }}, delay_seconds, quantity); + propose_approve_msig_token_transfer_trx(chain, proposal_1_name, { "tester"_n, config::active_name }, delay_seconds, quantity); chain.produce_blocks(); @@ -807,7 +819,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_with_delay_heirarchy_test ) { // this transaction will be delayed 20 blocks constexpr name proposal_2_name = "prop2"_n; constexpr uint32_t delay_seconds_2 = 10; - propose_approve_msig_updateauth_trx(chain, proposal_2_name, {{ "tester"_n, config::active_name }}, delay_seconds_2); + propose_approve_msig_updateauth_trx(chain, proposal_2_name, { "tester"_n, config::active_name }, delay_seconds_2); chain.produce_blocks(); @@ -827,7 +839,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_with_delay_heirarchy_test ) { constexpr name proposal_3_name = "prop3"_n; constexpr uint32_t delay_seconds_3 = 10; constexpr auto quantity_3 = "5.0000 CUR"; - propose_approve_msig_token_transfer_trx(chain, proposal_3_name, {{ "tester"_n, config::active_name }}, delay_seconds_3, quantity_3); + propose_approve_msig_token_transfer_trx(chain, proposal_3_name, { "tester"_n, config::active_name }, delay_seconds_3, quantity_3); chain.produce_blocks(); @@ -844,7 +856,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_with_delay_heirarchy_test ) { BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); // first transfer will finally be performed - exec_msig_trx(chain, proposal_1_name); + exec_msig_trx(chain, proposal_1_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); liquid_balance = get_currency_balance(chain, "tester"_n); @@ -853,7 +865,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_with_delay_heirarchy_test ) { BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); // delayed update auth removing the delay will finally execute - exec_msig_trx(chain, proposal_2_name); + exec_msig_trx(chain, proposal_2_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); // this transfer is performed right away since delay is removed @@ -888,7 +900,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_with_delay_heirarchy_test ) { BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); // second transfer finally is performed - exec_msig_trx(chain, proposal_3_name); + exec_msig_trx(chain, proposal_3_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); liquid_balance = get_currency_balance(chain, "tester"_n); @@ -955,7 +967,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_test ) { try { constexpr name proposal_1_name = "prop1"_n; constexpr uint32_t delay_seconds = 10; constexpr auto quantity = "1.0000 CUR"; - propose_approve_msig_token_transfer_trx(chain, proposal_1_name, {{ "tester"_n, config::active_name }}, delay_seconds, quantity); + propose_approve_msig_token_transfer_trx(chain, proposal_1_name, { "tester"_n, config::active_name }, delay_seconds, quantity); chain.produce_blocks(); @@ -982,7 +994,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_test ) { try { // this transaction will be delayed 20 blocks constexpr name proposal_2_name = "prop2"_n; constexpr uint32_t delay_seconds_2 = 10; - propose_approve_msig_linkauth_trx(chain, proposal_2_name, "second"_n, {{ "tester"_n, config::active_name }}, delay_seconds_2); + propose_approve_msig_linkauth_trx(chain, proposal_2_name, "second"_n, { "tester"_n, config::active_name }, delay_seconds_2); chain.produce_blocks(); @@ -1002,7 +1014,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_test ) { try { constexpr name proposal_3_name = "prop3"_n; constexpr uint32_t delay_seconds_3 = 10; constexpr auto quantity_3 = "5.0000 CUR"; - propose_approve_msig_token_transfer_trx(chain, proposal_3_name, {{ "tester"_n, config::active_name }}, delay_seconds_3, quantity_3); + propose_approve_msig_token_transfer_trx(chain, proposal_3_name, { "tester"_n, config::active_name }, delay_seconds_3, quantity_3); chain.produce_blocks(); @@ -1019,7 +1031,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_test ) { try { BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); // first transfer will finally be performed - exec_msig_trx(chain, proposal_1_name); + exec_msig_trx(chain, proposal_1_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); liquid_balance = get_currency_balance(chain, "tester"_n); @@ -1028,7 +1040,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_test ) { try { BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); // delay on minimum permission of transfer is finally removed - exec_msig_trx(chain, proposal_2_name); + exec_msig_trx(chain, proposal_2_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); // this transfer is performed right away since delay is removed @@ -1053,7 +1065,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_test ) { try { BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); // second transfer finally is performed - exec_msig_trx(chain, proposal_3_name); + exec_msig_trx(chain, proposal_3_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); liquid_balance = get_currency_balance(chain, "tester"_n); @@ -1113,7 +1125,7 @@ BOOST_AUTO_TEST_CASE( link_delay_unlink_test ) { try { constexpr name first_trnsfr_propsal_name = "prop1"_n; constexpr uint32_t first_trnsfr_delay_seconds = 10; constexpr auto first_trnsfr_quantity = "1.0000 CUR"; - propose_approve_msig_token_transfer_trx(chain, first_trnsfr_propsal_name, {{ "tester"_n, config::active_name }}, first_trnsfr_delay_seconds, first_trnsfr_quantity); + propose_approve_msig_token_transfer_trx(chain, first_trnsfr_propsal_name, { "tester"_n, config::active_name }, first_trnsfr_delay_seconds, first_trnsfr_quantity); chain.produce_blocks(); @@ -1139,7 +1151,7 @@ BOOST_AUTO_TEST_CASE( link_delay_unlink_test ) { try { // this transaction will be delayed 20 blocks constexpr name unlinkauth_proposal_name = "prop2"_n; - propose_approve_msig_unlinkauth_trx(chain, unlinkauth_proposal_name, {{ "tester"_n, config::active_name }}, 10); + propose_approve_msig_unlinkauth_trx(chain, unlinkauth_proposal_name, { "tester"_n, config::active_name }, 10); chain.produce_blocks(); @@ -1159,7 +1171,7 @@ BOOST_AUTO_TEST_CASE( link_delay_unlink_test ) { try { constexpr name second_trnfr_propsal_name = "prop3"_n; constexpr uint32_t second_trnfr_delay_seconds = 10; constexpr auto second_trnfr_quantity = "5.0000 CUR"; - propose_approve_msig_token_transfer_trx(chain, second_trnfr_propsal_name, {{ "tester"_n, config::active_name }}, second_trnfr_delay_seconds, second_trnfr_quantity); + propose_approve_msig_token_transfer_trx(chain, second_trnfr_propsal_name, { "tester"_n, config::active_name }, second_trnfr_delay_seconds, second_trnfr_quantity); chain.produce_blocks(); @@ -1176,7 +1188,7 @@ BOOST_AUTO_TEST_CASE( link_delay_unlink_test ) { try { BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); // first transfer will finally be performed - exec_msig_trx(chain, first_trnsfr_propsal_name); + exec_msig_trx(chain, first_trnsfr_propsal_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); liquid_balance = get_currency_balance(chain, "tester"_n); @@ -1185,7 +1197,7 @@ BOOST_AUTO_TEST_CASE( link_delay_unlink_test ) { try { BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); // the delayed unlinkauth finally occurs - exec_msig_trx(chain, unlinkauth_proposal_name); + exec_msig_trx(chain, unlinkauth_proposal_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); // this transfer is performed right away since delay is removed @@ -1212,7 +1224,7 @@ BOOST_AUTO_TEST_CASE( link_delay_unlink_test ) { try { BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); // second transfer finally is performed - exec_msig_trx(chain, second_trnfr_propsal_name); + exec_msig_trx(chain, second_trnfr_propsal_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); liquid_balance = get_currency_balance(chain, "tester"_n); @@ -1282,7 +1294,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_heirarchy_test ) { try { // this transaction will be delayed 20 blocks constexpr name first_trnsfr_propsal_name = "prop1"_n; - propose_approve_msig_token_transfer_trx(chain, first_trnsfr_propsal_name, {{ "tester"_n, config::active_name }}, 10, "1.0000 CUR"); + propose_approve_msig_token_transfer_trx(chain, first_trnsfr_propsal_name, { "tester"_n, config::active_name }, 10, "1.0000 CUR"); chain.produce_blocks(); @@ -1295,7 +1307,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_heirarchy_test ) { try { // this transaction will be delayed 20 blocks constexpr name linkauth_proposal_name = "prop2"_n; - propose_approve_msig_linkauth_trx(chain, linkauth_proposal_name, "third"_n, {{ "tester"_n, config::active_name }}, 10); + propose_approve_msig_linkauth_trx(chain, linkauth_proposal_name, "third"_n, { "tester"_n, config::active_name }, 10); chain.produce_blocks(); @@ -1313,7 +1325,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_heirarchy_test ) { try { // this transaction will be delayed 20 blocks constexpr name second_trnsfr_propsal_name = "prop3"_n; - propose_approve_msig_token_transfer_trx(chain, second_trnsfr_propsal_name, {{ "tester"_n, config::active_name }}, 10, "5.0000 CUR"); + propose_approve_msig_token_transfer_trx(chain, second_trnsfr_propsal_name, { "tester"_n, config::active_name }, 10, "5.0000 CUR"); chain.produce_blocks(); @@ -1330,7 +1342,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_heirarchy_test ) { try { BOOST_REQUIRE_EQUAL(asset::from_string("0.0000 CUR"), liquid_balance); // first transfer will finally be performed - exec_msig_trx(chain, first_trnsfr_propsal_name); + exec_msig_trx(chain, first_trnsfr_propsal_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); liquid_balance = get_currency_balance(chain, "tester"_n); @@ -1339,7 +1351,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_heirarchy_test ) { try { BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance); // delay on minimum permission of transfer is finally removed - exec_msig_trx(chain, linkauth_proposal_name); + exec_msig_trx(chain, linkauth_proposal_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); // this transfer is performed right away since delay is removed @@ -1364,7 +1376,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_heirarchy_test ) { try { BOOST_REQUIRE_EQUAL(asset::from_string("11.0000 CUR"), liquid_balance); // second transfer finally is performed - exec_msig_trx(chain, second_trnsfr_propsal_name); + exec_msig_trx(chain, second_trnsfr_propsal_name, {{ "tester"_n, config::active_name }}); chain.produce_blocks(); liquid_balance = get_currency_balance(chain, "tester"_n); @@ -1570,11 +1582,11 @@ BOOST_AUTO_TEST_CASE( max_transaction_delay_execute ) { try { chain.produce_blocks(); //should be able to create a msig transaction with delay 60 sec, despite permission delay being 30 days, because max_transaction_delay is 60 sec constexpr name proposal_name = "prop1"_n; - propose_approve_msig_token_transfer_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}, 60, "9.0000 CUR"); + propose_approve_msig_token_transfer_trx(chain, proposal_name, { "tester"_n, config::active_name }, 60, "9.0000 CUR"); //check that the delayed msig transaction can be executed after after 60 sec chain.produce_blocks(120); - exec_msig_trx(chain, proposal_name); + exec_msig_trx(chain, proposal_name, {{ "tester"_n, config::active_name }}); //check that the transfer really happened auto liquid_balance = get_currency_balance(chain, "tester"_n);