Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion silkworm
28 changes: 25 additions & 3 deletions src/actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,8 @@ Receipt evm_contract::execute_tx(const runtime_config& rc, eosio::name miner, Bl
check_result( r, tx, "validate_transaction error" );

Receipt receipt;
const auto res = ep.execute_transaction(tx, receipt, gas_params);
CallResult call_result;
const auto res = ep.execute_transaction(tx, receipt, gas_params, call_result);

// Calculate the miner portion of the actual gas fee (if necessary):
std::optional<intx::uint256> gas_fee_miner_portion;
Expand All @@ -287,8 +288,29 @@ Receipt evm_contract::execute_tx(const runtime_config& rc, eosio::name miner, Bl
}
}

if (rc.abort_on_failure)
eosio::check(receipt.success, "tx executed inline by contract must succeed");
if (rc.abort_on_failure) {
if (receipt.success == false) {
size_t size = (int)call_result.data.length();
constexpr size_t max_size = 1024;
std::string errmsg;
errmsg.reserve(max_size);
errmsg += "inline evm tx failed, evmc_status_code:";
errmsg += std::to_string((int)call_result.status);
errmsg += ", data:[";
errmsg += std::to_string(size);
errmsg += "]";
size_t i = 0;
for (; i < size && errmsg.length() < max_size - 6; ++i ) {
static const char hex_chars[] = "0123456789abcdef";
errmsg += hex_chars[((uint8_t)call_result.data[i]) >> 4];
errmsg += hex_chars[((uint8_t)call_result.data[i]) & 0xf];
}
if (i < size) {
errmsg += "...";
}
eosio::check(false, errmsg);
}
}

if(!ep.state().reserved_objects().empty()) {
intx::uint256 total_egress;
Expand Down
42 changes: 24 additions & 18 deletions tests/call_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct call_evm_tester : basic_evm_tester {
address public lastcaller;

function test(uint256 input) public {
require(input != 0);
require(input != 0, "solidity:input can't be zero");

count += input;
lastcaller = msg.sender;
Expand Down Expand Up @@ -56,7 +56,7 @@ struct call_evm_tester : basic_evm_tester {
const intx::uint256 gas_fee_notpayable_version1 = suggested_gas_price * (21274 );

const std::string contract_bytecode =
"608060405234801561001057600080fd5b5061030f806100206000396000f3fe60806040526004361061004a5760003560e01c806306661abd1461004f57806329e99f071461007a578063a1a7d817146100a3578063d097e7a6146100ad578063d79e1b6a146100d8575b600080fd5b34801561005b57600080fd5b506100646100ef565b60405161007191906101a1565b60405180910390f35b34801561008657600080fd5b506100a1600480360381019061009c91906101ed565b6100f5565b005b6100ab61015e565b005b3480156100b957600080fd5b506100c2610160565b6040516100cf919061025b565b60405180910390f35b3480156100e457600080fd5b506100ed610186565b005b60005481565b6000810361010257600080fd5b8060008082825461011391906102a5565b9250508190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b565b6000819050919050565b61019b81610188565b82525050565b60006020820190506101b66000830184610192565b92915050565b600080fd5b6101ca81610188565b81146101d557600080fd5b50565b6000813590506101e7816101c1565b92915050565b600060208284031215610203576102026101bc565b5b6000610211848285016101d8565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006102458261021a565b9050919050565b6102558161023a565b82525050565b6000602082019050610270600083018461024c565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006102b082610188565b91506102bb83610188565b92508282019050808211156102d3576102d2610276565b5b9291505056fea2646970667358221220ed95d8f74110a8eb6307b7ae52b8623fd3e959169b208830a960c99a9ba1dbf564736f6c63430008120033";
"608060405234801561001057600080fd5b506103c2806100206000396000f3fe60806040526004361061004a5760003560e01c806306661abd1461004f57806329e99f071461007a578063a1a7d817146100a3578063d097e7a6146100ad578063d79e1b6a146100d8575b600080fd5b34801561005b57600080fd5b506100646100ef565b60405161007191906101d7565b60405180910390f35b34801561008657600080fd5b506100a1600480360381019061009c9190610223565b6100f5565b005b6100ab610194565b005b3480156100b957600080fd5b506100c2610196565b6040516100cf9190610291565b60405180910390f35b3480156100e457600080fd5b506100ed6101bc565b005b60005481565b60008103610138576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012f90610309565b60405180910390fd5b806000808282546101499190610358565b9250508190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b565b6000819050919050565b6101d1816101be565b82525050565b60006020820190506101ec60008301846101c8565b92915050565b600080fd5b610200816101be565b811461020b57600080fd5b50565b60008135905061021d816101f7565b92915050565b600060208284031215610239576102386101f2565b5b60006102478482850161020e565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061027b82610250565b9050919050565b61028b81610270565b82525050565b60006020820190506102a66000830184610282565b92915050565b600082825260208201905092915050565b7f736f6c69646974793a696e7075742063616e2774206265207a65726f00000000600082015250565b60006102f3601c836102ac565b91506102fe826102bd565b602082019050919050565b60006020820190508181036000830152610322816102e6565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610363826101be565b915061036e836101be565b925082820190508082111561038657610385610329565b5b9291505056fea264697066735822122072b253e04d7675d9751c68c632df2c04d32dcce47beddcdd35fa75e485afe2fa64736f6c63430008120033";

call_evm_tester() {
create_accounts({"alice"_n});
Expand All @@ -71,7 +71,7 @@ struct call_evm_tester : basic_evm_tester {
return deploy_contract(eoa, evmc::from_hex(contract_bytecode).value());
}

void call_test(const evmc::address& contract_addr, uint64_t amount, name eos, name actor) {
void call_test(const evmc::address& contract_addr, uint64_t amount, name eos, name actor, uint64_t gaslimit = 500000) {

auto to = evmc::bytes{std::begin(contract_addr.bytes), std::end(contract_addr.bytes)};

Expand All @@ -82,7 +82,7 @@ struct call_evm_tester : basic_evm_tester {
evmc::bytes32 v;
intx::be::store(v.bytes, intx::uint256(0));

call(eos, to, silkworm::Bytes(v), data, 500000, actor);
call(eos, to, silkworm::Bytes(v), data, gaslimit, actor);
}

void call_testpay(const evmc::address& contract_addr, uint128_t amount, name eos, name actor) {
Expand Down Expand Up @@ -282,7 +282,11 @@ BOOST_FIXTURE_TEST_CASE(call_test_function, call_evm_tester) try {
auto evm_account_balance = intx::uint256(vault_balance(evm_account_name));

BOOST_REQUIRE_EXCEPTION(call_test(token_addr, 0, "alice"_n, "alice"_n),
eosio_assert_message_exception, eosio_assert_message_is("tx executed inline by contract must succeed"));
eosio_assert_message_exception, eosio_assert_message_is("inline evm tx failed, evmc_status_code:2, data:[100]08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001c736f6c69646974793a696e7075742063616e2774206265207a65726f00000000"));

// call run out of gas, EVMC_OUT_OF_GAS = 3, (gas limit > intrinsic gas)
BOOST_REQUIRE_EXCEPTION(call_test(token_addr, 0, "alice"_n, "alice"_n, 21200),
eosio_assert_message_exception, eosio_assert_message_is("inline evm tx failed, evmc_status_code:3, data:[0]"));

BOOST_REQUIRE(intx::uint256(vault_balance("alice"_n)) == alice_balance);
BOOST_REQUIRE(intx::uint256(vault_balance(evm_account_name)) == evm_account_balance);
Expand Down Expand Up @@ -316,9 +320,8 @@ BOOST_FIXTURE_TEST_CASE(call_test_function, call_evm_tester) try {
auto caller = get_lastcaller(token_addr);
BOOST_REQUIRE(caller == make_reserved_address("alice"_n.to_uint64_t()));


BOOST_REQUIRE_EXCEPTION(call_notpayable(token_addr, 100, "alice"_n, "alice"_n),
eosio_assert_message_exception, eosio_assert_message_is("tx executed inline by contract must succeed"));
eosio_assert_message_exception, eosio_assert_message_is("inline evm tx failed, evmc_status_code:2, data:[0]"));

BOOST_REQUIRE(intx::uint256(vault_balance("alice"_n)) == alice_balance);
BOOST_REQUIRE(intx::uint256(vault_balance(evm_account_name)) == evm_account_balance);
Expand Down Expand Up @@ -418,9 +421,10 @@ BOOST_FIXTURE_TEST_CASE(admincall_test_function, call_evm_tester) try {
BOOST_REQUIRE(evm_balance(evm2) == evm2_balance);
auto evm_account_balance = intx::uint256(vault_balance(evm_account_name));

BOOST_REQUIRE_EXCEPTION(admincall_test(token_addr, 0, evm2, evm_account_name),
eosio_assert_message_exception, eosio_assert_message_is("tx executed inline by contract must succeed"));

try {
BOOST_REQUIRE_EXCEPTION(admincall_test(token_addr, 0, evm2, evm_account_name),
eosio_assert_message_exception, eosio_assert_message_is("inline evm tx failed, evmc_status_code:2, data:[100]08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001c736f6c69646974793a696e7075742063616e2774206265207a65726f00000000"));
} FC_LOG_AND_RETHROW()

// Call and check results
admincall_test(token_addr, 1234, evm2, evm_account_name);
Expand Down Expand Up @@ -451,8 +455,10 @@ BOOST_FIXTURE_TEST_CASE(admincall_test_function, call_evm_tester) try {
auto caller = get_lastcaller(token_addr);
BOOST_REQUIRE(caller== evm2.address);

BOOST_REQUIRE_EXCEPTION(admincall_notpayable(token_addr, 100, evm2, evm_account_name),
eosio_assert_message_exception, eosio_assert_message_is("tx executed inline by contract must succeed"));
try {
BOOST_REQUIRE_EXCEPTION(admincall_notpayable(token_addr, 100, evm2, evm_account_name),
eosio_assert_message_exception, eosio_assert_message_is("inline evm tx failed, evmc_status_code:2, data:[0]"));
} FC_LOG_AND_RETHROW()

BOOST_REQUIRE(evm_balance(evm2)== evm2_balance);
BOOST_REQUIRE(intx::uint256(vault_balance(evm_account_name)) == evm_account_balance);
Expand Down Expand Up @@ -642,7 +648,7 @@ BOOST_FIXTURE_TEST_CASE(call_test_function_version_1, call_evm_tester) try {
auto evm_account_balance = intx::uint256(vault_balance(evm_account_name));

BOOST_REQUIRE_EXCEPTION(call_test(token_addr, 0, "alice"_n, "alice"_n),
eosio_assert_message_exception, eosio_assert_message_is("tx executed inline by contract must succeed"));
eosio_assert_message_exception, eosio_assert_message_is("inline evm tx failed, evmc_status_code:2, data:[100]08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001c736f6c69646974793a696e7075742063616e2774206265207a65726f00000000"));

BOOST_REQUIRE(intx::uint256(vault_balance("alice"_n)) == alice_balance);
BOOST_REQUIRE(intx::uint256(vault_balance(evm_account_name)) == evm_account_balance);
Expand Down Expand Up @@ -685,7 +691,7 @@ BOOST_FIXTURE_TEST_CASE(call_test_function_version_1, call_evm_tester) try {


BOOST_REQUIRE_EXCEPTION(call_notpayable(token_addr, 100, "alice"_n, "alice"_n),
eosio_assert_message_exception, eosio_assert_message_is("tx executed inline by contract must succeed"));
eosio_assert_message_exception, eosio_assert_message_is("inline evm tx failed, evmc_status_code:2, data:[0]"));

BOOST_REQUIRE(intx::uint256(vault_balance("alice"_n)) == alice_balance);
BOOST_REQUIRE(intx::uint256(vault_balance(evm_account_name)) == evm_account_balance);
Expand Down Expand Up @@ -785,7 +791,7 @@ BOOST_FIXTURE_TEST_CASE(call_other_payer_actually_same_function, call_evm_tester
auto evm_account_balance = intx::uint256(vault_balance(evm_account_name));

BOOST_REQUIRE_EXCEPTION(callotherpay_test(token_addr, 0, "alice"_n, "alice"_n, "alice"_n),
eosio_assert_message_exception, eosio_assert_message_is("tx executed inline by contract must succeed"));
eosio_assert_message_exception, eosio_assert_message_is("inline evm tx failed, evmc_status_code:2, data:[100]08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001c736f6c69646974793a696e7075742063616e2774206265207a65726f00000000"));

BOOST_REQUIRE(intx::uint256(vault_balance("alice"_n)) == alice_balance);
BOOST_REQUIRE(intx::uint256(vault_balance(evm_account_name)) == evm_account_balance);
Expand Down Expand Up @@ -826,7 +832,7 @@ BOOST_FIXTURE_TEST_CASE(call_other_payer_actually_same_function, call_evm_tester


BOOST_REQUIRE_EXCEPTION(callotherpay_notpayable(token_addr, 100, "alice"_n, "alice"_n, "alice"_n),
eosio_assert_message_exception, eosio_assert_message_is("tx executed inline by contract must succeed"));
eosio_assert_message_exception, eosio_assert_message_is("inline evm tx failed, evmc_status_code:2, data:[0]"));

BOOST_REQUIRE(intx::uint256(vault_balance("alice"_n)) == alice_balance);
BOOST_REQUIRE(intx::uint256(vault_balance(evm_account_name)) == evm_account_balance);
Expand Down Expand Up @@ -940,7 +946,7 @@ BOOST_FIXTURE_TEST_CASE(call_other_payer_function, call_evm_tester) try {
auto evm_account_balance = intx::uint256(vault_balance(evm_account_name));

BOOST_REQUIRE_EXCEPTION(callotherpay_test(token_addr, 0, "alice"_n, "alice"_n, "bob"_n),
eosio_assert_message_exception, eosio_assert_message_is("tx executed inline by contract must succeed"));
eosio_assert_message_exception, eosio_assert_message_is("inline evm tx failed, evmc_status_code:2, data:[100]08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001c736f6c69646974793a696e7075742063616e2774206265207a65726f00000000"));

BOOST_REQUIRE(intx::uint256(vault_balance("alice"_n)) == alice_balance);
BOOST_REQUIRE(intx::uint256(vault_balance(evm_account_name)) == evm_account_balance);
Expand Down Expand Up @@ -989,7 +995,7 @@ BOOST_FIXTURE_TEST_CASE(call_other_payer_function, call_evm_tester) try {
alice_balance = 100_ether;

BOOST_REQUIRE_EXCEPTION(callotherpay_notpayable(token_addr, 100, "alice"_n, "alice"_n, "bob"_n),
eosio_assert_message_exception, eosio_assert_message_is("tx executed inline by contract must succeed"));
eosio_assert_message_exception, eosio_assert_message_is("inline evm tx failed, evmc_status_code:2, data:[0]"));

BOOST_REQUIRE(intx::uint256(vault_balance("alice"_n)) == alice_balance);
BOOST_REQUIRE(intx::uint256(vault_balance(evm_account_name)) == evm_account_balance);
Expand Down