提交 5ba4b06e 编写于 作者: A arhag

fixes for delayed input transactions (use delay_sec field in trx)

Removed mindelay action since the `delay_sec` field makes it unnecessary.

Additional unit tests to test the new semantics of delay_sec are needed.

Also, apply_block and push_transaction now respect the skip_authority_check flag.
上级 d71cc397
......@@ -183,7 +183,6 @@ namespace eosiosystem {
typename native<SystemAccount>::setabi,
typename native<SystemAccount>::onerror,
typename native<SystemAccount>::canceldelay,
typename native<SystemAccount>::mindelay,
nonce>( code, act) ) {
//TODO: Small hack until we refactor eosio.system like eosio.token
using undelegatebw = typename delegate_bandwidth<SystemAccount>::undelegatebw;
......
......@@ -15,14 +15,14 @@ namespace eosiosystem {
struct permission_level_weight {
permission_level permission;
weight_type weight;
EOSLIB_SERIALIZE( permission_level_weight, (permission)(weight) )
};
struct key_weight {
public_key key;
weight_type weight;
EOSLIB_SERIALIZE( key_weight, (key)(weight) )
};
......@@ -30,7 +30,7 @@ namespace eosiosystem {
uint32_t threshold;
std::vector<key_weight> keys;
std::vector<permission_level_weight> accounts;
EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts) )
};
......@@ -52,14 +52,14 @@ namespace eosiosystem {
type_name name;
type_name base;
std::vector<field_def> fields;
EOSLIB_SERIALIZE( struct_def, (name)(base)(fields) )
};
struct action_def {
action_name name;
type_name type;
EOSLIB_SERIALIZE(action_def, (name)(type) )
};
......@@ -69,7 +69,7 @@ namespace eosiosystem {
std::vector<field_name> key_names;
std::vector<type_name> key_types;
type_name type;
EOSLIB_SERIALIZE(table_def, (name)(index_type)(key_names)(key_types)(type) )
};
......@@ -78,7 +78,7 @@ namespace eosiosystem {
std::vector<struct_def> structs;
std::vector<action_def> actions;
std::vector<table_def> tables;
EOSLIB_SERIALIZE( abi_def, (types)(structs)(actions)(tables) )
};
......@@ -131,12 +131,12 @@ namespace eosiosystem {
static void on( const linkauth& ) {
}
ACTION( SystemAccount, unlinkauth ) {
account_name account;
account_name code;
action_name type;
EOSLIB_SERIALIZE( unlinkauth, (account)(code)(type) )
};
......@@ -175,7 +175,7 @@ namespace eosiosystem {
ACTION( SystemAccount, setabi ) {
account_name account;
abi_def abi;
EOSLIB_SERIALIZE( setabi, (account)(abi) )
};
......@@ -188,23 +188,15 @@ namespace eosiosystem {
static void on( const onerror& ) {
}
ACTION( SystemAccount, canceldelay ) {
uint32_t sender_id;
EOSLIB_SERIALIZE( canceldelay, (sender_id) )
};
static void on( const canceldelay& ) {
}
ACTION ( SystemAccount, mindelay ) {
uint32_t delay;
EOSLIB_SERIALIZE( mindelay, (delay) )
};
static void on( const mindelay& ) {
}
};
}
......@@ -229,9 +229,9 @@ void apply_context::require_recipient( account_name code ) {
void apply_context::execute_inline( action&& a ) {
if ( !privileged ) {
if( a.account != receiver ) {
const auto delay = controller.check_authorization({a}, vector<action>(), flat_set<public_key_type>(), false, {receiver});
const auto delay = controller.check_authorization({a}, flat_set<public_key_type>(), false, {receiver});
FC_ASSERT( trx_meta.published + delay <= controller.head_block_time(),
"inline action uses a permission that imposes a delay that is not met, add an action of mindelay with delay of at least ${delay} seconds",
"inline action uses a permission that imposes a delay that is not met, set delay_sec in transaction header to at least ${delay} seconds",
("delay", delay.to_seconds()) );
}
}
......@@ -282,9 +282,9 @@ void apply_context::execute_deferred( deferred_transaction&& trx ) {
}
}
if( check_auth ) {
delay = controller.check_authorization(trx.actions, vector<action>(), flat_set<public_key_type>(), false, {receiver});
delay = controller.check_authorization(trx.actions, flat_set<public_key_type>(), false, {receiver});
FC_ASSERT( trx_meta.published + delay <= controller.head_block_time(),
"deferred transaction uses a permission that imposes a delay that is not met, add an action of mindelay with delay of at least ${delay} seconds",
"deferred transaction uses a permission that imposes a delay that is not met, set delay_sec in transaction header to at least ${delay} seconds",
("delay", delay.to_seconds()) );
}
}
......
......@@ -290,18 +290,25 @@ transaction_trace chain_controller::_push_transaction(const packed_transaction&
//idump((transaction_header(mtrx.trx())));
const transaction& trx = mtrx.trx();
mtrx.delay = fc::seconds(trx.delay_sec);
validate_transaction_with_minimal_state( trx, mtrx.billable_packed_size );
validate_expiration_not_too_far(trx, head_block_time() + mtrx.delay);
validate_referenced_accounts(trx);
validate_uniqueness(trx);
auto delay = check_transaction_authorization(trx, packed_trx.signatures, mtrx.context_free_data);
validate_expiration_not_too_far(trx, head_block_time() + delay );
mtrx.delay = delay;
if( should_check_authorization() ) {
auto enforced_delay = check_transaction_authorization(trx, packed_trx.signatures, mtrx.context_free_data);
EOS_ASSERT( mtrx.delay >= enforced_delay,
transaction_exception,
"authorization imposes a delay (${enforced_delay} sec) greater than the delay specified in transaction header (${specified_delay} sec)",
("enforced_delay", enforced_delay.to_seconds())("specified_delay", mtrx.delay.to_seconds()) );
}
auto setup_us = fc::time_point::now() - start;
transaction_trace result(mtrx.id);
if( delay.count() == 0 ) {
if( mtrx.delay.count() == 0 ) {
result = _push_transaction( std::move(mtrx) );
} else {
result = wrap_transaction_processing( std::move(mtrx),
......@@ -461,7 +468,6 @@ transaction chain_controller::_get_on_block_transaction()
trx.actions.emplace_back(std::move(on_block_act));
trx.set_reference_block(head_block_id());
trx.expiration = head_block_time() + fc::seconds(1);
trx.max_kcpu_usage = 2000; // 1 << 24;
return trx;
}
......@@ -827,16 +833,24 @@ void chain_controller::__apply_block(const signed_block& next_block)
auto itr = trx_index.find(receipt.id);
if( itr != trx_index.end() ) {
auto& trx_meta = input_metas.at(itr->second);
const auto& trx = trx_meta.trx();
const auto& trx = trx_meta.trx();
trx_meta.delay = fc::seconds(trx.delay_sec);
validate_expiration_not_too_far(trx, head_block_time() + trx_meta.delay);
validate_referenced_accounts(trx);
validate_uniqueness(trx);
FC_ASSERT( !should_check_signatures() || trx_meta.signing_keys,
"signing_keys missing from transaction_metadata of an input transaction" );
auto delay = check_authorization( trx.actions, trx.context_free_actions,
should_check_signatures() ? *trx_meta.signing_keys : flat_set<public_key_type>() );
validate_expiration_not_too_far(trx, head_block_time() + delay );
if( should_check_authorization() ) {
FC_ASSERT( !should_check_signatures() || trx_meta.signing_keys,
"signing_keys missing from transaction_metadata of an input transaction" );
auto enforced_delay = check_authorization( trx.actions,
should_check_signatures() ? *trx_meta.signing_keys
: flat_set<public_key_type>() );
EOS_ASSERT( trx_meta.delay >= enforced_delay,
transaction_exception,
"authorization imposes a delay (${enforced_delay} sec) greater than the delay specified in transaction header (${specified_delay} sec)",
("enforced_delay", enforced_delay.to_seconds())("specified_delay", trx_meta.delay.to_seconds()) );
}
trx_meta.delay = delay;
return &input_metas.at(itr->second);
} else {
const auto* gtrx = _db.find<generated_transaction_object,by_trx_id>(receipt.id);
......@@ -965,7 +979,6 @@ private:
};
fc::microseconds chain_controller::check_authorization( const vector<action>& actions,
const vector<action>& context_free_actions,
const flat_set<public_key_type>& provided_keys,
bool allow_unused_signatures,
flat_set<account_name> provided_accounts )const
......@@ -1044,15 +1057,6 @@ fc::microseconds chain_controller::check_authorization( const vector<action>& ac
}
}
for( const auto& act : context_free_actions ) {
if (act.account == config::system_account_name && act.name == contracts::mindelay::get_name()) {
const auto mindelay = act.data_as<contracts::mindelay>();
auto delay = fc::seconds(mindelay.delay);
if( max_delay < delay )
max_delay = delay;
}
}
if( !allow_unused_signatures && should_check_signatures() ) {
EOS_ASSERT( checker.all_keys_used(), tx_irrelevant_sig,
"transaction bears irrelevant signatures from these keys: ${keys}",
......@@ -1092,11 +1096,11 @@ fc::microseconds chain_controller::check_transaction_authorization(const transac
bool allow_unused_signatures)const
{
if( should_check_signatures() ) {
return check_authorization( trx.actions, trx.context_free_actions,
return check_authorization( trx.actions,
trx.get_signature_keys( signatures, chain_id_type{}, cfd, allow_unused_signatures ),
allow_unused_signatures );
} else {
return check_authorization( trx.actions, trx.context_free_actions, flat_set<public_key_type>(), true );
return check_authorization( trx.actions, flat_set<public_key_type>(), true );
}
}
......
......@@ -46,7 +46,6 @@ void chain_initializer::register_types(chain_controller& chain, chainbase::datab
SET_APP_HANDLER( eosio, eosio, passrecovery, eosio );
SET_APP_HANDLER( eosio, eosio, vetorecovery, eosio );
SET_APP_HANDLER( eosio, eosio, canceldelay, eosio );
SET_APP_HANDLER( eosio, eosio, mindelay, eosio );
}
......@@ -75,7 +74,6 @@ abi_def chain_initializer::eos_contract_abi(const abi_def& eosio_system_abi)
eos_abi.actions.push_back( action_def{name("onerror"), "onerror"} );
eos_abi.actions.push_back( action_def{name("onblock"), "onblock"} );
eos_abi.actions.push_back( action_def{name("canceldelay"), "canceldelay"} );
eos_abi.actions.push_back( action_def{name("mindelay"), "mindelay"} );
// ACTION PAYLOADS
......@@ -166,12 +164,6 @@ abi_def chain_initializer::eos_contract_abi(const abi_def& eosio_system_abi)
}
});
eos_abi.structs.emplace_back( struct_def {
"mindelay", "", {
{"delay", "uint32"},
}
});
// DATABASE RECORDS
eos_abi.structs.emplace_back( struct_def {
......
......@@ -595,8 +595,4 @@ void apply_eosio_canceldelay(apply_context& context) {
context.cancel_deferred(sender_id);
}
void apply_eosio_mindelay(apply_context& context) {
// all processing is performed in chain_controller::check_authorization
}
} } } // namespace eosio::chain::contracts
......@@ -49,7 +49,7 @@ namespace eosio { namespace chain {
skip_assert_evaluation = 1 << 8, ///< used while reindexing
skip_undo_history_check = 1 << 9, ///< used while reindexing
skip_producer_schedule_check= 1 << 10, ///< used while reindexing
skip_validate = 1 << 11, ///< used prior to checkpoint, skips validate() call on transaction
skip_validate = 1 << 11, ///< used prior to checkpoint, skips transaction validation
skip_scope_check = 1 << 12, ///< used to skip checks for proper scope
skip_output_check = 1 << 13, ///< used to skip checks for outputs in block exactly matching those created from apply
pushed_transaction = 1 << 14, ///< used to indicate that the origination of the call was from a push_transaction, to determine time allotment
......@@ -285,7 +285,6 @@ namespace eosio { namespace chain {
/**
* @param actions - the actions to check authorization across
* @param context_free_actions - the context free actions to check for mindelays across
* @param provided_keys - the set of public keys which have authorized the transaction
* @param allow_unused_signatures - true if method should not assert on unused signatures
* @param provided_accounts - the set of accounts which have authorized the transaction (presumed to be owner)
......@@ -293,7 +292,6 @@ namespace eosio { namespace chain {
* @return fc::microseconds set to the max delay that this authorization requires to complete
*/
fc::microseconds check_authorization( const vector<action>& actions,
const vector<action>& context_free_actions,
const flat_set<public_key_type>& provided_keys,
bool allow_unused_signatures = false,
flat_set<account_name> provided_accounts = flat_set<account_name>()
......@@ -412,6 +410,7 @@ namespace eosio { namespace chain {
bool should_check_for_duplicate_transactions()const { return !(_skip_flags&skip_transaction_dupe_check); }
bool should_check_tapos()const { return !(_skip_flags&skip_tapos_check); }
bool should_check_signatures()const { return !(_skip_flags&skip_transaction_signatures); }
bool should_check_authorization()const { return !(_skip_flags&skip_authority_check); }
///Steps involved in applying a new block
///@{
......
......@@ -8,7 +8,7 @@
#include <eosio/chain/types.hpp>
namespace eosio { namespace chain { namespace contracts {
namespace eosio { namespace chain { namespace contracts {
/**
* @defgroup native_action_handlers Native Action Handlers
......@@ -30,7 +30,6 @@ namespace eosio { namespace chain { namespace contracts {
void apply_eosio_onerror(apply_context&);
void apply_eosio_canceldelay(apply_context&);
void apply_eosio_mindelay(apply_context&);
///@} end action handlers
} } } /// namespace eosio::contracts
......@@ -281,18 +281,6 @@ struct canceldelay {
}
};
struct mindelay {
uint32_t delay;
static account_name get_account() {
return config::system_account_name;
}
static action_name get_name() {
return N(mindelay);
}
};
} } } /// namespace eosio::chain::contracts
FC_REFLECT( eosio::chain::contracts::type_def , (new_type_name)(type) )
......@@ -313,4 +301,3 @@ FC_REFLECT( eosio::chain::contracts::postrecovery , (account
FC_REFLECT( eosio::chain::contracts::passrecovery , (account) )
FC_REFLECT( eosio::chain::contracts::vetorecovery , (account) )
FC_REFLECT( eosio::chain::contracts::canceldelay , (sender_id) )
FC_REFLECT( eosio::chain::contracts::mindelay , (delay) )
......@@ -30,7 +30,7 @@ namespace boost { namespace test_tools { namespace tt_detail {
{
::operator<<( osm, v );
}
};
};
template<>
struct print_log_value<fc::variant_object> {
......@@ -80,14 +80,14 @@ namespace eosio { namespace testing {
transaction_trace push_transaction( signed_transaction& trx, uint32_t skip_flag = skip_nothing );
action_result push_action(action&& cert_act, uint64_t authorizer);
transaction_trace push_action( const account_name& code, const action_name& acttype, const account_name& actor, const variant_object& data, uint32_t expiration = DEFAULT_EXPIRATION_DELTA );
transaction_trace push_action( const account_name& code, const action_name& acttype, const vector<account_name>& actors, const variant_object& data, uint32_t expiration = DEFAULT_EXPIRATION_DELTA );
transaction_trace push_action( const account_name& code, const action_name& acttype, const account_name& actor, const variant_object& data, uint32_t expiration = DEFAULT_EXPIRATION_DELTA, uint32_t delay_sec = 0 );
transaction_trace push_action( const account_name& code, const action_name& acttype, const vector<account_name>& actors, const variant_object& data, uint32_t expiration = DEFAULT_EXPIRATION_DELTA, uint32_t delay_sec = 0 );
void set_tapos( signed_transaction& trx, uint32_t expiration = DEFAULT_EXPIRATION_DELTA ) const;
void set_transaction_headers(signed_transaction& trx,
uint32_t expiration = DEFAULT_EXPIRATION_DELTA,
uint32_t extra_cf_cpu_usage = 0) const;
uint32_t expiration = DEFAULT_EXPIRATION_DELTA,
uint32_t delay_sec = 0)const;
void create_accounts( vector<account_name> names, bool multisig = false ) {
for( auto n : names ) create_account(n, config::system_account_name, multisig );
......@@ -193,7 +193,7 @@ namespace eosio { namespace testing {
}
tester(chain_controller::controller_config config) {
init(config);
init(config);
}
signed_block produce_block( fc::microseconds skip_time = fc::milliseconds(config::block_interval_ms), uint32_t skip_flag = skip_missed_block_penalty )override {
......@@ -201,11 +201,11 @@ namespace eosio { namespace testing {
}
bool validate() { return true; }
};
};
class validating_tester : public base_tester {
public:
virtual ~validating_tester() {
virtual ~validating_tester() {
produce_block();
BOOST_REQUIRE_EQUAL( validate(), true );
}
......@@ -240,11 +240,11 @@ namespace eosio { namespace testing {
validating_node->push_block( sb );
return sb;
}
bool validate() {
auto hbh = control->head_block_header();
auto vn_hbh = validating_node->head_block_header();
return control->head_block_id() == validating_node->head_block_id() &&
return control->head_block_id() == validating_node->head_block_id() &&
hbh.previous == vn_hbh.previous &&
hbh.timestamp == vn_hbh.timestamp &&
hbh.transaction_mroot == vn_hbh.transaction_mroot &&
......@@ -254,7 +254,7 @@ namespace eosio { namespace testing {
}
unique_ptr<chain_controller> validating_node;
};
};
/**
* Utility predicate to check whether an FC_ASSERT message ends with a given string
......@@ -272,6 +272,5 @@ namespace eosio { namespace testing {
string expected;
};
} } /// eosio::testing
} } /// eosio::testing
......@@ -121,19 +121,13 @@ namespace eosio { namespace testing {
}
void base_tester::set_transaction_headers( signed_transaction& trx, uint32_t expiration, uint32_t extra_cf_cpu_usage ) const {
void base_tester::set_transaction_headers( signed_transaction& trx, uint32_t expiration, uint32_t delay_sec ) const {
trx.expiration = control->head_block_time() + fc::seconds(expiration);
trx.set_reference_block( control->head_block_id() );
// estimate the size of the uncompressed transaction
//uint32_t estimated_size = (uint32_t)fc::raw::pack_size(trx);
//estimated_size += trx.context_free_data.size();
//estimated_size += 4 * sizeof(signature_type); // hack to allow for 4 sigs
trx.max_net_usage_words = 0; // No limit
// estimate the usage of the context free actions
trx.max_kcpu_usage = 30000 + extra_cf_cpu_usage + (trx.context_free_actions.size() * config::default_base_per_action_cpu_usage * 10);
trx.max_kcpu_usage = 0; // No limit
trx.delay_sec = delay_sec;
}
......@@ -198,10 +192,11 @@ namespace eosio { namespace testing {
const action_name& acttype,
const account_name& actor,
const variant_object& data,
uint32_t expiration)
uint32_t expiration,
uint32_t delay_sec)
{ try {
return push_action(code, acttype, vector<account_name>{ actor }, data, expiration);
return push_action(code, acttype, vector<account_name>{ actor }, data, expiration, delay_sec);
} FC_CAPTURE_AND_RETHROW( (code)(acttype)(actor)(data)(expiration) ) }
......@@ -209,7 +204,8 @@ namespace eosio { namespace testing {
const action_name& acttype,
const vector<account_name>& actors,
const variant_object& data,
uint32_t expiration)
uint32_t expiration,
uint32_t delay_sec)
{ try {
const auto& acnt = control->get_database().get<account_object,by_name>(code);
......@@ -231,7 +227,7 @@ namespace eosio { namespace testing {
signed_transaction trx;
trx.actions.emplace_back(std::move(act));
set_transaction_headers(trx, expiration);
set_transaction_headers(trx, expiration, delay_sec);
for (const auto& actor : actors) {
trx.sign(get_private_key(actor, "active"), chain_id_type());
}
......
......@@ -155,9 +155,9 @@ transaction_trace CallAction(TESTER& test, T ac, const vector<account_name>& sco
}
template <typename T>
transaction_trace CallFunction(TESTER& test, T ac, const vector<char>& data, const vector<account_name>& scope = {N(testapi)}, uint32_t extra_cf_cpu_usage = 0) {
{
signed_transaction trx;
transaction_trace CallFunction(TESTER& test, T ac, const vector<char>& data, const vector<account_name>& scope = {N(testapi)}) {
{
signed_transaction trx;
auto pl = vector<permission_level>{{scope[0], config::active_name}};
if (scope.size() > 1)
......@@ -169,14 +169,14 @@ transaction_trace CallFunction(TESTER& test, T ac, const vector<char>& data, con
act.authorization = {{N(testapi), config::active_name}};
trx.actions.push_back(act);
test.set_transaction_headers(trx, test.DEFAULT_EXPIRATION_DELTA, extra_cf_cpu_usage );
auto sigs = trx.sign(test.get_private_key(scope[0], "active"), chain_id_type());
test.set_transaction_headers(trx, test.DEFAULT_EXPIRATION_DELTA);
auto sigs = trx.sign(test.get_private_key(scope[0], "active"), chain_id_type());
trx.get_signature_keys(chain_id_type() );
auto res = test.push_transaction(trx);
BOOST_CHECK_EQUAL(res.status, transaction_receipt::executed);
test.produce_block();
auto res = test.push_transaction(trx);
BOOST_CHECK_EQUAL(res.status, transaction_receipt::executed);
test.produce_block();
return res;
}
}
}
#define CALL_TEST_FUNCTION(_TESTER, CLS, MTH, DATA) CallFunction(_TESTER, test_api_action<TEST_METHOD(CLS, MTH)>{}, DATA)
......@@ -491,7 +491,7 @@ BOOST_FIXTURE_TEST_CASE(cf_action_tests, TESTER) { try {
produce_block();
// test send context free action
auto ttrace = CallFunction( *this, test_api_action<TEST_METHOD("test_transaction", "send_cf_action")>{}, {}, {N(testapi)}, 20000 );
auto ttrace = CALL_TEST_FUNCTION( *this, "test_transaction", "send_cf_action", {} );
BOOST_CHECK_EQUAL(ttrace.action_traces.size(), 2);
BOOST_CHECK_EQUAL(ttrace.action_traces[1].receiver == account_name("dummy"), true);
BOOST_CHECK_EQUAL(ttrace.action_traces[1].act.account == account_name("dummy"), true);
......@@ -506,7 +506,7 @@ BOOST_FIXTURE_TEST_CASE(cf_action_tests, TESTER) { try {
CALL_TEST_FUNCTION( *this, "test_transaction", "read_inline_action", {} );
CallFunction( *this, test_api_action<TEST_METHOD("test_transaction", "read_inline_cf_action")>{}, {}, {N(testapi)}, 20000 );
CALL_TEST_FUNCTION( *this, "test_transaction", "read_inline_cf_action", {} );
BOOST_REQUIRE_EQUAL( validate(), true );
} FC_LOG_AND_RETHROW() }
......@@ -696,13 +696,13 @@ BOOST_FIXTURE_TEST_CASE(transaction_tests, TESTER) { try {
control->push_deferred_transactions( true );
// test test_transaction_size
CALL_TEST_FUNCTION(*this, "test_transaction", "test_transaction_size", fc::raw::pack(57) );
CALL_TEST_FUNCTION(*this, "test_transaction", "test_transaction_size", fc::raw::pack(55) ); // TODO: Need a better way to test this.
control->push_deferred_transactions( true );
// test test_read_transaction
// this is a bit rough, but I couldn't figure out a better way to compare the hashes
auto tx_trace = CALL_TEST_FUNCTION( *this, "test_transaction", "test_read_transaction", {} );
string sha_expect = "274e873c8b2e4de20de06e53c99fe703b5099ce4faaf5d78195a4a2538caba15";
string sha_expect = "f899d4ec365702f99607bc640ec21a21b109eee01504011769a9fd4f41a5b72c"; // TODO: Need a better way to test this.
BOOST_CHECK_EQUAL(tx_trace.action_traces.front().console == sha_expect, true);
// test test_tapos_block_num
CALL_TEST_FUNCTION(*this, "test_transaction", "test_tapos_block_num", fc::raw::pack(control->head_block_num()) );
......
......@@ -123,7 +123,7 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_test ) { try {
("to", "tester2")
("quantity", "3.0000 CUR")
("memo", "hi" ),
20
20, 10
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
......@@ -263,7 +263,7 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_parent_permission_test ) { try {
("to", "tester2")
("quantity", "3.0000 CUR")
("memo", "hi" ),
20
20, 15
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
......@@ -409,7 +409,7 @@ BOOST_AUTO_TEST_CASE( link_delay_direct_walk_parent_permissions_test ) { try {
("to", "tester2")
("quantity", "3.0000 CUR")
("memo", "hi" ),
30
30, 20
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
......@@ -520,7 +520,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_test ) { try {
("to", "tester2")
("quantity", "1.0000 CUR")
("memo", "hi" ),
30
30, 10
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
......@@ -543,7 +543,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_test ) { try {
("parent", "active")
("data", authority(chain.get_public_key(tester_account, "first")))
("delay", 0),
30);
30, 10);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
BOOST_REQUIRE_EQUAL(0, trace.action_traces.size());
......@@ -568,7 +568,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_test ) { try {
("to", "tester2")
("quantity", "5.0000 CUR")
("memo", "hi" ),
30
30, 10
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
......@@ -713,7 +713,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_with_delay_heirarchy_test ) {
("to", "tester2")
("quantity", "1.0000 CUR")
("memo", "hi" ),
30
30, 10
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
......@@ -736,7 +736,8 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_with_delay_heirarchy_test ) {
("parent", "active")
("data", authority(chain.get_public_key(tester_account, "first")))
("delay", 0),
30);
30, 10
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
BOOST_REQUIRE_EQUAL(0, trace.action_traces.size());
......@@ -761,7 +762,7 @@ BOOST_AUTO_TEST_CASE( link_delay_permission_change_with_delay_heirarchy_test ) {
("to", "tester2")
("quantity", "5.0000 CUR")
("memo", "hi" ),
30
30, 10
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
......@@ -906,7 +907,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_test ) { try {
("to", "tester2")
("quantity", "1.0000 CUR")
("memo", "hi" ),
30
30, 10
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
......@@ -928,7 +929,8 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_test ) { try {
("code", "currency")
("type", "transfer")
("requirement", "second"),
30);
30, 10
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
BOOST_REQUIRE_EQUAL(0, trace.action_traces.size());
......@@ -953,7 +955,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_test ) { try {
("to", "tester2")
("quantity", "5.0000 CUR")
("memo", "hi" ),
30
30, 10
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
......@@ -1104,7 +1106,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_heirarchy_test ) { try {
("to", "tester2")
("quantity", "1.0000 CUR")
("memo", "hi" ),
30
30, 10
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
......@@ -1126,7 +1128,8 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_heirarchy_test ) { try {
("code", "currency")
("type", "transfer")
("requirement", "third"),
30);
30, 10
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
BOOST_REQUIRE_EQUAL(0, trace.action_traces.size());
......@@ -1151,7 +1154,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_heirarchy_test ) { try {
("to", "tester2")
("quantity", "5.0000 CUR")
("memo", "hi" ),
30
30, 10
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
......@@ -1220,7 +1223,7 @@ BOOST_AUTO_TEST_CASE( link_delay_link_change_heirarchy_test ) { try {
} FC_LOG_AND_RETHROW() }/// schedule_test
// test mindelay action imposing delay
// test delay_sec field imposing unneeded delay
BOOST_AUTO_TEST_CASE( mindelay_test ) { try {
TESTER chain;
......@@ -1290,7 +1293,7 @@ BOOST_AUTO_TEST_CASE( mindelay_test ) { try {
liquid_balance = get_currency_balance(chain, N(tester2));
BOOST_REQUIRE_EQUAL(asset::from_string("1.0000 CUR"), liquid_balance);
// send transfer and mindelay
// send transfer with delay_sec set to 10
const auto& acnt = chain.control->get_database().get<account_object,by_name>(N(currency));
const auto abi = acnt.get_abi();
chain::contracts::abi_serializer abis(abi);
......@@ -1312,9 +1315,7 @@ BOOST_AUTO_TEST_CASE( mindelay_test ) { try {
signed_transaction trx;
trx.actions.push_back(act);
trx.context_free_actions.emplace_back(vector<permission_level>(), chain::contracts::mindelay { .delay = 10 });
chain.set_transaction_headers(trx, 30);
chain.set_transaction_headers(trx, 30, 10);
trx.sign(chain.get_private_key(N(tester), "active"), chain_id_type());
trace = chain.push_transaction(trx);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
......@@ -1425,7 +1426,7 @@ BOOST_AUTO_TEST_CASE( canceldelay_test ) { try {
("to", "tester2")
("quantity", "1.0000 CUR")
("memo", "hi" ),
30
30, 10
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
......@@ -1448,7 +1449,8 @@ BOOST_AUTO_TEST_CASE( canceldelay_test ) { try {
("parent", "active")
("data", authority(chain.get_public_key(tester_account, "first")))
("delay", 0),
30);
30, 10
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
BOOST_REQUIRE_EQUAL(0, trace.action_traces.size());
......@@ -1473,7 +1475,7 @@ BOOST_AUTO_TEST_CASE( canceldelay_test ) { try {
("to", "tester2")
("quantity", "5.0000 CUR")
("memo", "hi" ),
30
30, 10
);
BOOST_REQUIRE_EQUAL(transaction_receipt::delayed, trace.status);
BOOST_REQUIRE_EQUAL(1, trace.deferred_transaction_requests.size());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册