Skip to content

Commit

Permalink
Merge pull request #646 from eosnetworkfoundation/yarkin/assert_action
Browse files Browse the repository at this point in the history
Add assertnonce action.
  • Loading branch information
yarkinwho authored Aug 31, 2023
2 parents c460b54 + 3caaa22 commit 051dad8
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 4 deletions.
2 changes: 2 additions & 0 deletions include/evm_runtime/evm_contract.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ class [[eosio::contract]] evm_contract : public contract
[[eosio::action]] void bridgereg(eosio::name receiver, const eosio::asset& min_fee);
[[eosio::action]] void bridgeunreg(eosio::name receiver);

[[eosio::action]] void assertnonce(eosio::name account, uint64_t next_nonce);

#ifdef WITH_TEST_ACTIONS
[[eosio::action]] void testtx(const std::optional<bytes>& orlptx, const evm_runtime::test::block_info& bi);
[[eosio::action]] void
Expand Down
13 changes: 13 additions & 0 deletions src/actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,19 @@ void evm_contract::bridgeunreg(eosio::name receiver) {
message_receivers.erase(*it);
}


void evm_contract::assertnonce(eosio::name account, uint64_t next_nonce) {
nextnonces nextnonce_table(get_self(), get_self().value);

auto next_nonce_iter = nextnonce_table.find(account.value);
if (next_nonce_iter == nextnonce_table.end()) {
eosio::check(0 == next_nonce, "wrong nonce");
}
else {
eosio::check(next_nonce_iter->next_nonce == next_nonce, "wrong nonce");
}
}

#ifdef WITH_TEST_ACTIONS
[[eosio::action]] void evm_contract::testtx( const std::optional<bytes>& orlptx, const evm_runtime::test::block_info& bi ) {
assert_unfrozen();
Expand Down
5 changes: 5 additions & 0 deletions tests/basic_evm_tester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,11 @@ transaction_trace_ptr basic_evm_tester::bridgeunreg(name receiver) {
mvo()("receiver", receiver));
}

transaction_trace_ptr basic_evm_tester::assertnonce(name account, uint64_t next_nonce) {
return basic_evm_tester::push_action(evm_account_name, "assertnonce"_n, account,
mvo()("account", account)("next_nonce", next_nonce));
}

transaction_trace_ptr basic_evm_tester::pushtx(const silkworm::Transaction& trx, name miner)
{
silkworm::Bytes rlp;
Expand Down
1 change: 1 addition & 0 deletions tests/basic_evm_tester.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ class basic_evm_tester : public testing::validating_tester
transaction_trace_ptr bridgereg(name receiver, asset min_fee, vector<account_name> extra_signers={evm_account_name});
transaction_trace_ptr bridgeunreg(name receiver);
transaction_trace_ptr exec(const exec_input& input, const std::optional<exec_callback>& callback);
transaction_trace_ptr assertnonce(name account, uint64_t next_nonce);
transaction_trace_ptr pushtx(const silkworm::Transaction& trx, name miner = evm_account_name);
void call(name from, const evmc::bytes& to, const evmc::bytes& value, evmc::bytes& data, uint64_t gas_limit, name actor);
void admincall(const evmc::bytes& from, const evmc::bytes& to, const evmc::bytes& value, evmc::bytes& data, uint64_t gas_limit, name actor);
Expand Down
66 changes: 62 additions & 4 deletions tests/call_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,28 +471,86 @@ BOOST_FIXTURE_TEST_CASE(deploy_contract_function, call_evm_tester) try {
auto to = evmc::bytes();

auto data = evmc::from_hex(contract_bytecode);

assertnonce("alice"_n, 0);
call("alice"_n, to, silkworm::Bytes(v), *data, 1000000, "alice"_n); // nonce 0->1

auto addr = silkworm::create_address(alice_addr, 0);

assertnonce("alice"_n, 1);
call_test(addr, 1234, "alice"_n, "alice"_n); // nonce 1->2

auto count = get_count(addr);
BOOST_REQUIRE(count == 1234);

// Advance block so we do not generate same transaction.
produce_block();

auto from = evmc::bytes{std::begin(alice_addr.bytes), std::end(alice_addr.bytes)};

assertnonce("alice"_n, 2);
admincall(from, to, silkworm::Bytes(v), *data, 1000000, evm_account_name); // nonce 2->3

addr = silkworm::create_address(alice_addr, 2);
assertnonce("alice"_n, 3);
call_test(addr, 2222, "alice"_n, "alice"_n); // nonce 3->4
assertnonce("alice"_n, 4);
count = get_count(addr);
BOOST_REQUIRE(count == 2222);
} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE(assetnonce_test, call_evm_tester) try {
auto alice_addr = make_reserved_address("alice"_n.to_uint64_t());

// nonce for not opened account is zero.
assertnonce("alice"_n, 0);
BOOST_REQUIRE_EXCEPTION(assertnonce("alice"_n, 1),
eosio_assert_message_exception, eosio_assert_message_is("wrong nonce"));

// Advance block so we do not generate same transaction.
produce_block();

open("alice"_n);
transfer_token("alice"_n, evm_account_name, make_asset(1000000), "alice");

evm_eoa evm1;
evmc::bytes32 v;

auto to = evmc::bytes();

auto data = evmc::from_hex(contract_bytecode);

// Fail when nonce is 0 but tested with non-zero value
BOOST_REQUIRE_EXCEPTION(assertnonce("alice"_n, 1),
eosio_assert_message_exception, eosio_assert_message_is("wrong nonce"));

assertnonce("alice"_n, 0);
call("alice"_n, to, silkworm::Bytes(v), *data, 1000000, "alice"_n); // nonce 0->1

// Advance block so we do not generate same transaction.
produce_block();

assertnonce("alice"_n, 1);
assertnonce(evm_account_name, 0);
// Fund evm1 address with 100 EOS, should NOT increase alice nonce, but increase evm nonce.
transfer_token("alice"_n, evm_account_name, make_asset(1000000), evm1.address_0x());

// Advance block so we do not generate same transaction.
produce_block();
assertnonce("alice"_n, 1);
assertnonce(evm_account_name, 1);

// Advance block so we do not generate same transaction.
produce_block();

// Fail when nonce is non-zero but tested with another value
BOOST_REQUIRE_EXCEPTION(assertnonce("alice"_n, 2),
eosio_assert_message_exception, eosio_assert_message_is("wrong nonce"));
// Fail when nonce is non-zero but tested with 0
BOOST_REQUIRE_EXCEPTION(assertnonce("alice"_n, 0),
eosio_assert_message_exception, eosio_assert_message_is("wrong nonce"));



} FC_LOG_AND_RETHROW()



BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 051dad8

Please sign in to comment.