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 test/blockchaintest/blockchaintest_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ std::error_code validate_block(evmc_revision rev, state::BlobParams blob_params,
// Fail if parent header was not found: the block references a parent that is neither the
// genesis nor any previously-accepted block (an unknown or rejected parent).
if (parent_header == nullptr)
return make_error_code(INVALID_BLOCK_PARENT);
return make_error_code(UNKNOWN_PARENT);

if (test_block.block_info.number != parent_header->block_number + 1)
return make_error_code(INVALID_BLOCK_NUMBER);
Expand Down
4 changes: 2 additions & 2 deletions test/integration/statetest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ add_test(
)
set_tests_properties(
${PREFIX}/tx_invalid_nonce PROPERTIES
PASS_REGULAR_EXPRESSION "unexpected invalid transaction: nonce too high"
PASS_REGULAR_EXPRESSION "unexpected invalid transaction: TransactionException.NONCE_MISMATCH_TOO_HIGH"
)

add_test(
Expand All @@ -122,7 +122,7 @@ add_test(
)
set_tests_properties(
${PREFIX}/tx_invalid_signature PROPERTIES
PASS_REGULAR_EXPRESSION "unexpected invalid transaction: invalid transaction signature"
PASS_REGULAR_EXPRESSION "unexpected invalid transaction: TransactionException.INVALID_SIGNATURE_VRS"
)

add_test(
Expand Down
2 changes: 1 addition & 1 deletion test/integration/t8n/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ add_test(
string(
JOIN ".*" EXPECTED_OUT
# Create blob transaction should be rejected:
[=["error": "blob transaction must not be a create transaction"]=]
[=["error": "TransactionException.TYPE_3_TX_CONTRACT_CREATION"]=]
)
set_tests_properties(
${PREFIX}/${TEST_CASE}/out.json PROPERTIES
Expand Down
94 changes: 51 additions & 43 deletions test/state/errors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,34 @@
namespace evmone::state
{

/// The reasons a transaction or a block is rejected.
///
/// The message of each is the execution-spec-tests exception name for the same rule, so a test can
/// compare a rejection against the `expectException` its fixture states. Where the specs name more
/// than one exception for a rule, the message is the canonical one and the test harness carries the
/// alternatives; the few rules the specs do not name at all keep a plain message.
enum ErrorCode : int // NOLINT(*-use-enum-class)
{
SUCCESS = 0,
INTRINSIC_GAS_TOO_LOW,
TX_TYPE_NOT_SUPPORTED,
INSUFFICIENT_FUNDS,
NONCE_HAS_MAX_VALUE,
TYPE_NOT_SUPPORTED,
INSUFFICIENT_ACCOUNT_FUNDS,
NONCE_IS_MAX,
NONCE_TOO_HIGH,
NONCE_TOO_LOW,
TIP_GT_FEE_CAP,
FEE_CAP_LESS_THAN_BLOCKS,
BLOB_FEE_CAP_LESS_THAN_BLOCKS,
GAS_LIMIT_REACHED,
PRIORITY_GREATER_THAN_MAX_FEE_PER_GAS,
INSUFFICIENT_MAX_FEE_PER_GAS,
INSUFFICIENT_MAX_FEE_PER_BLOB_GAS,
GAS_ALLOWANCE_EXCEEDED,
SENDER_NOT_EOA,
INIT_CODE_SIZE_LIMIT_EXCEEDED,
INITCODE_SIZE_EXCEEDED,
CREATE_BLOB_TX,
EMPTY_BLOB_HASHES_LIST,
INVALID_BLOB_HASH_VERSION,
BLOB_GAS_LIMIT_EXCEEDED,
CREATE_SET_CODE_TX,
EMPTY_AUTHORIZATION_LIST,
MAX_GAS_LIMIT_EXCEEDED,
GAS_LIMIT_EXCEEDS_MAXIMUM,
INVALID_CHAIN_ID,
INVALID_ENCODING,
INVALID_SIGNATURE,
Expand All @@ -43,7 +49,7 @@ enum ErrorCode : int // NOLINT(*-use-enum-class)
INCORRECT_EXCESS_BLOB_GAS,
RLP_BLOCK_LIMIT_EXCEEDED,
INVALID_BLOCK_TIMESTAMP_OLDER_THAN_PARENT,
INVALID_BLOCK_PARENT,
UNKNOWN_PARENT,
INVALID_BLOCK_NUMBER,

// Block requests collection (EIP-7685).
Expand All @@ -66,51 +72,53 @@ inline const std::error_category& evmone_category() noexcept
case SUCCESS:
return "";
case INTRINSIC_GAS_TOO_LOW:
return "intrinsic gas too low";
case TX_TYPE_NOT_SUPPORTED:
return "transaction type not supported";
case INSUFFICIENT_FUNDS:
return "insufficient funds for gas * price + value";
case NONCE_HAS_MAX_VALUE:
return "nonce has max value:";
return "TransactionException.INTRINSIC_GAS_TOO_LOW";
case TYPE_NOT_SUPPORTED:
return "TransactionException.TYPE_NOT_SUPPORTED";
case INSUFFICIENT_ACCOUNT_FUNDS:
return "TransactionException.INSUFFICIENT_ACCOUNT_FUNDS";
case NONCE_IS_MAX:
return "TransactionException.NONCE_IS_MAX";
case NONCE_TOO_HIGH:
return "nonce too high";
return "TransactionException.NONCE_MISMATCH_TOO_HIGH";
case NONCE_TOO_LOW:
return "nonce too low";
case TIP_GT_FEE_CAP:
return "max priority fee per gas higher than max fee per gas";
case FEE_CAP_LESS_THAN_BLOCKS:
return "max fee per gas less than block base fee";
case BLOB_FEE_CAP_LESS_THAN_BLOCKS:
return "max blob fee per gas less than block base fee";
case GAS_LIMIT_REACHED:
return "gas limit reached";
return "TransactionException.NONCE_MISMATCH_TOO_LOW";
case PRIORITY_GREATER_THAN_MAX_FEE_PER_GAS:
return "TransactionException.PRIORITY_GREATER_THAN_MAX_FEE_PER_GAS";
case INSUFFICIENT_MAX_FEE_PER_GAS:
return "TransactionException.INSUFFICIENT_MAX_FEE_PER_GAS";
case INSUFFICIENT_MAX_FEE_PER_BLOB_GAS:
return "TransactionException.INSUFFICIENT_MAX_FEE_PER_BLOB_GAS";
case GAS_ALLOWANCE_EXCEEDED:
return "TransactionException.GAS_ALLOWANCE_EXCEEDED";
case SENDER_NOT_EOA:
return "sender not an eoa:";
case INIT_CODE_SIZE_LIMIT_EXCEEDED:
return "max initcode size exceeded";
return "TransactionException.SENDER_NOT_EOA";
case INITCODE_SIZE_EXCEEDED:
return "TransactionException.INITCODE_SIZE_EXCEEDED";
case CREATE_BLOB_TX:
return "blob transaction must not be a create transaction";
return "TransactionException.TYPE_3_TX_CONTRACT_CREATION";
case EMPTY_BLOB_HASHES_LIST:
return "empty blob hashes list";
return "TransactionException.TYPE_3_TX_ZERO_BLOBS";
case INVALID_BLOB_HASH_VERSION:
return "invalid blob hash version";
return "TransactionException.TYPE_3_TX_INVALID_BLOB_VERSIONED_HASH";
case BLOB_GAS_LIMIT_EXCEEDED:
return "blob gas limit exceeded";
return "TransactionException.TYPE_3_TX_BLOB_COUNT_EXCEEDED";
case CREATE_SET_CODE_TX:
return "set code transaction must not be a create transaction";
return "TransactionException.TYPE_4_TX_CONTRACT_CREATION";
case EMPTY_AUTHORIZATION_LIST:
return "empty authorization list";
case MAX_GAS_LIMIT_EXCEEDED:
return "max gas limit exceeded";
return "TransactionException.TYPE_4_EMPTY_AUTHORIZATION_LIST";
case GAS_LIMIT_EXCEEDS_MAXIMUM:
return "TransactionException.GAS_LIMIT_EXCEEDS_MAXIMUM";
case INVALID_CHAIN_ID:
return "invalid transaction chain id";
return "TransactionException.INVALID_CHAINID";
case INVALID_ENCODING:
// The execution specs name every way an encoding can be malformed separately
// (RLP_*), so there is no single constant standing for this one.
return "invalid transaction encoding";
case INVALID_SIGNATURE:
return "invalid transaction signature";
return "TransactionException.INVALID_SIGNATURE_VRS";
case UNKNOWN_ERROR:
return "Unknown error";
return "unknown error";
case INCORRECT_BLOCK_FORMAT:
return "BlockException.INCORRECT_BLOCK_FORMAT";
case INVALID_GASLIMIT:
Expand All @@ -123,8 +131,8 @@ inline const std::error_category& evmone_category() noexcept
return "BlockException.RLP_BLOCK_LIMIT_EXCEEDED";
case INVALID_BLOCK_TIMESTAMP_OLDER_THAN_PARENT:
return "BlockException.INVALID_BLOCK_TIMESTAMP_OLDER_THAN_PARENT";
case INVALID_BLOCK_PARENT:
return "BlockException.INVALID_BLOCK_PARENT";
case UNKNOWN_PARENT:
return "BlockException.UNKNOWN_PARENT";
case INVALID_BLOCK_NUMBER:
return "BlockException.INVALID_BLOCK_NUMBER";
case INVALID_DEPOSIT_EVENT_LAYOUT:
Expand Down
24 changes: 12 additions & 12 deletions test/state/state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ std::variant<TransactionProperties, std::error_code> validate_transaction(
{
case Transaction::Type::blob:
if (rev < EVMC_CANCUN)
return make_error_code(TX_TYPE_NOT_SUPPORTED);
return make_error_code(TYPE_NOT_SUPPORTED);
Comment thread
chfast marked this conversation as resolved.
if (!tx.to.has_value())
return make_error_code(CREATE_BLOB_TX);
if (tx.blob_hashes.empty())
Expand All @@ -455,7 +455,7 @@ std::variant<TransactionProperties, std::error_code> validate_transaction(

assert(block.blob_base_fee.has_value());
if (tx.max_blob_gas_price < *block.blob_base_fee)
return make_error_code(BLOB_FEE_CAP_LESS_THAN_BLOCKS);
return make_error_code(INSUFFICIENT_MAX_FEE_PER_BLOB_GAS);

if (std::ranges::any_of(tx.blob_hashes, [](const auto& h) { return h.bytes[0] != 0x01; }))
return make_error_code(INVALID_BLOB_HASH_VERSION);
Expand All @@ -465,7 +465,7 @@ std::variant<TransactionProperties, std::error_code> validate_transaction(

case Transaction::Type::set_code:
if (rev < EVMC_PRAGUE)
return make_error_code(TX_TYPE_NOT_SUPPORTED);
return make_error_code(TYPE_NOT_SUPPORTED);
if (!tx.to.has_value())
return make_error_code(CREATE_SET_CODE_TX);
if (tx.authorization_list.empty())
Expand All @@ -481,15 +481,15 @@ std::variant<TransactionProperties, std::error_code> validate_transaction(
case Transaction::Type::blob:
case Transaction::Type::eip1559:
if (rev < EVMC_LONDON)
return make_error_code(TX_TYPE_NOT_SUPPORTED);
return make_error_code(TYPE_NOT_SUPPORTED);

if (tx.max_priority_gas_price > tx.max_gas_price)
return make_error_code(TIP_GT_FEE_CAP); // Priority gas price is too high.
return make_error_code(PRIORITY_GREATER_THAN_MAX_FEE_PER_GAS);
[[fallthrough]];

case Transaction::Type::access_list:
if (rev < EVMC_BERLIN)
return make_error_code(TX_TYPE_NOT_SUPPORTED);
return make_error_code(TYPE_NOT_SUPPORTED);
[[fallthrough]];

case Transaction::Type::legacy:;
Expand All @@ -498,13 +498,13 @@ std::variant<TransactionProperties, std::error_code> validate_transaction(
assert(tx.max_priority_gas_price <= tx.max_gas_price);

if (rev >= EVMC_OSAKA && tx.gas_limit > MAX_TX_GAS_LIMIT)
return make_error_code(MAX_GAS_LIMIT_EXCEEDED);
return make_error_code(GAS_LIMIT_EXCEEDS_MAXIMUM);

if (tx.gas_limit > block_gas_left)
return make_error_code(GAS_LIMIT_REACHED);
return make_error_code(GAS_ALLOWANCE_EXCEEDED);

if (tx.max_gas_price < block.base_fee)
return make_error_code(FEE_CAP_LESS_THAN_BLOCKS);
return make_error_code(INSUFFICIENT_MAX_FEE_PER_GAS);

// We need some information about the sender so lookup the account in the state.
// TODO: During transaction execution this account will be also needed, so we may pass it along.
Expand All @@ -516,7 +516,7 @@ std::variant<TransactionProperties, std::error_code> validate_transaction(
return make_error_code(SENDER_NOT_EOA); // Origin must not be a contract (EIP-3607).

if (sender_acc.nonce == MAX_NONCE) // Nonce value limit (EIP-2681).
return make_error_code(NONCE_HAS_MAX_VALUE);
return make_error_code(NONCE_IS_MAX);

if (sender_acc.nonce < tx.nonce)
return make_error_code(NONCE_TOO_HIGH);
Expand All @@ -526,7 +526,7 @@ std::variant<TransactionProperties, std::error_code> validate_transaction(

// initcode size is limited by EIP-3860.
if (rev >= EVMC_SHANGHAI && !tx.to.has_value() && tx.data.size() > MAX_INITCODE_SIZE)
return make_error_code(INIT_CODE_SIZE_LIMIT_EXCEEDED);
return make_error_code(INITCODE_SIZE_EXCEEDED);

// Compute and check if sender has enough balance for the theoretical maximum transaction cost.
// Note this is different from tx_max_cost computed with effective gas price later.
Expand All @@ -541,7 +541,7 @@ std::variant<TransactionProperties, std::error_code> validate_transaction(
max_total_fee += total_blob_gas * tx.max_blob_gas_price;
}
if (sender_acc.balance < max_total_fee)
return make_error_code(INSUFFICIENT_FUNDS);
return make_error_code(INSUFFICIENT_ACCOUNT_FUNDS);

const auto [intrinsic_cost, min_cost] = compute_tx_intrinsic_cost(rev, tx);
if (tx.gas_limit < std::max(intrinsic_cost, min_cost))
Expand Down
2 changes: 1 addition & 1 deletion test/unittests/state_transition_tx_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ TEST_F(state_transition, invalid_tx_non_existing_sender)
tx.nonce = 0;
pre.erase(Sender);

expect.tx_error = INSUFFICIENT_FUNDS;
expect.tx_error = INSUFFICIENT_ACCOUNT_FUNDS;
expect.post[Sender].exists = false;
}

Expand Down
16 changes: 8 additions & 8 deletions test/unittests/state_tx_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ TEST(state_tx, validate_nonce)
EXPECT_EQ(std::get<std::error_code>(
validate_transaction(state, block, tx, EVMC_BERLIN, block.gas_limit, 0))
.message(),
"nonce too low");
"TransactionException.NONCE_MISMATCH_TOO_LOW");

tx.nonce = 2;
EXPECT_EQ(std::get<std::error_code>(
validate_transaction(state, block, tx, EVMC_BERLIN, block.gas_limit, 0))
.message(),
"nonce too high");
"TransactionException.NONCE_MISMATCH_TOO_HIGH");
}

TEST(state_tx, validate_sender)
Expand All @@ -61,14 +61,14 @@ TEST(state_tx, validate_sender)
EXPECT_EQ(std::get<std::error_code>(
validate_transaction(state, block, tx, EVMC_LONDON, block.gas_limit, 0))
.message(),
"max fee per gas less than block base fee");
"TransactionException.INSUFFICIENT_MAX_FEE_PER_GAS");

tx.max_gas_price = block.base_fee;

EXPECT_EQ(std::get<std::error_code>(
validate_transaction(state, block, tx, EVMC_LONDON, block.gas_limit, 0))
.message(),
"insufficient funds for gas * price + value");
"TransactionException.INSUFFICIENT_ACCOUNT_FUNDS");
}

TEST(state_tx, validate_blob_tx)
Expand All @@ -93,7 +93,7 @@ TEST(state_tx, validate_blob_tx)
static_cast<int64_t>(max_blob_gas_per_block(get_blob_params(EVMC_CANCUN)));
EXPECT_EQ(std::get<std::error_code>(validate_transaction(
state, block, tx, EVMC_SHANGHAI, block.gas_limit, blob_gas_limit)),
make_error_code(ErrorCode::TX_TYPE_NOT_SUPPORTED));
make_error_code(ErrorCode::TYPE_NOT_SUPPORTED));

EXPECT_EQ(std::get<std::error_code>(validate_transaction(state, block, tx, EVMC_CANCUN,
block.gas_limit, blob_gas_limit))
Expand All @@ -117,8 +117,8 @@ TEST(state_tx, validate_blob_tx)
validate_transaction(state, block, tx, EVMC_CANCUN, block.gas_limit, g));
};

EXPECT_EQ(
expect_error(blob_gas_limit), make_error_code(ErrorCode::BLOB_FEE_CAP_LESS_THAN_BLOCKS));
EXPECT_EQ(expect_error(blob_gas_limit),
make_error_code(ErrorCode::INSUFFICIENT_MAX_FEE_PER_BLOB_GAS));

tx.max_blob_gas_price = 1;
tx.blob_hashes.push_back(
Expand Down Expand Up @@ -252,5 +252,5 @@ TEST(state_tx, max_gas_limit_exceeded)

EXPECT_EQ(std::get<std::error_code>(
validate_transaction(state, block, tx, EVMC_OSAKA, block.gas_limit, 0)),
make_error_code(ErrorCode::MAX_GAS_LIMIT_EXCEEDED));
make_error_code(ErrorCode::GAS_LIMIT_EXCEEDS_MAXIMUM));
}
3 changes: 0 additions & 3 deletions test/utils/statetest.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,6 @@ json::json to_state_test(std::string_view test_name, const state::BlockInfo& blo
state::Transaction& tx, const TestState& pre, evmc_revision rev,
const std::variant<state::TransactionReceipt, std::error_code>& res, const TestState& post);

/// Returns the standardized error message for the transaction validation error.
[[nodiscard]] std::string get_invalid_tx_message(state::ErrorCode errc) noexcept;


std::vector<StateTransitionTest> load_state_tests(std::istream& input);

Expand Down
Loading