@@ -53,24 +53,34 @@ int64_t compute_tx_intrinsic_cost(evmc_revision rev, const Transaction& tx) noex
53
53
}
54
54
55
55
// / Validates transaction and computes its execution gas limit (the amount of gas provided to EVM).
56
- // / @return Non-negative execution gas limit for valid transaction
57
- // / or negative value for invalid transaction.
56
+ // / @return Execution gas limit or transaction validation error.
58
57
std::variant<int64_t , std::error_code> validate_transaction (const Account& sender_acc,
59
58
const BlockInfo& block, const Transaction& tx, evmc_revision rev) noexcept
60
59
{
61
- if (rev < EVMC_LONDON && tx.kind == Transaction::Kind::eip1559)
62
- return make_error_code (TX_TYPE_NOT_SUPPORTED);
60
+ switch (tx.type )
61
+ {
62
+ case Transaction::Type::eip1559:
63
+ if (rev < EVMC_LONDON)
64
+ return make_error_code (TX_TYPE_NOT_SUPPORTED);
65
+
66
+ if (tx.max_priority_gas_price > tx.max_gas_price )
67
+ return make_error_code (TIP_GT_FEE_CAP); // Priority gas price is too high.
68
+ [[fallthrough]];
63
69
64
- if (rev < EVMC_BERLIN && !tx.access_list .empty ())
65
- return make_error_code (TX_TYPE_NOT_SUPPORTED);
70
+ case Transaction::Type::access_list:
71
+ if (rev < EVMC_BERLIN)
72
+ return make_error_code (TX_TYPE_NOT_SUPPORTED);
73
+ [[fallthrough]];
74
+
75
+ case Transaction::Type::legacy:;
76
+ }
66
77
67
- if (tx.max_priority_gas_price > tx.max_gas_price )
68
- return make_error_code (TIP_GT_FEE_CAP); // Priority gas price is too high.
78
+ assert (tx.max_priority_gas_price <= tx.max_gas_price );
69
79
70
80
if (tx.gas_limit > block.gas_limit )
71
81
return make_error_code (GAS_LIMIT_REACHED);
72
82
73
- if (rev >= EVMC_LONDON && tx.max_gas_price < block.base_fee )
83
+ if (tx.max_gas_price < block.base_fee )
74
84
return make_error_code (FEE_CAP_LESS_THEN_BLOCKS);
75
85
76
86
if (!sender_acc.code .empty ())
@@ -91,11 +101,11 @@ std::variant<int64_t, std::error_code> validate_transaction(const Account& sende
91
101
sender_acc.balance < tx_cost_limit_512)
92
102
return make_error_code (INSUFFICIENT_FUNDS);
93
103
94
- const auto intrinsic_cost = compute_tx_intrinsic_cost (rev, tx);
95
- if (intrinsic_cost > tx. gas_limit )
104
+ const auto execution_gas_limit = tx. gas_limit - compute_tx_intrinsic_cost (rev, tx);
105
+ if (execution_gas_limit < 0 )
96
106
return make_error_code (INTRINSIC_GAS_TOO_LOW);
97
107
98
- return tx. gas_limit - intrinsic_cost ;
108
+ return execution_gas_limit ;
99
109
}
100
110
101
111
evmc_message build_message (const Transaction& tx, int64_t execution_gas_limit) noexcept
@@ -195,7 +205,7 @@ std::variant<TransactionReceipt, std::error_code> transition(
195
205
std::erase_if (state.get_accounts (),
196
206
[](const std::pair<const address, Account>& p) noexcept { return p.second .destructed ; });
197
207
198
- auto receipt = TransactionReceipt{tx.kind , result.status_code , gas_used, host.take_logs (), {}};
208
+ auto receipt = TransactionReceipt{tx.type , result.status_code , gas_used, host.take_logs (), {}};
199
209
200
210
// Cannot put it into constructor call because logs are std::moved from host instance.
201
211
receipt.logs_bloom_filter = compute_bloom_filter (receipt.logs );
@@ -210,13 +220,13 @@ std::variant<TransactionReceipt, std::error_code> transition(
210
220
211
221
[[nodiscard]] bytes rlp_encode (const Transaction& tx)
212
222
{
213
- if (tx.kind == Transaction::Kind ::legacy)
223
+ if (tx.type == Transaction::Type ::legacy)
214
224
{
215
225
// rlp [nonce, gas_price, gas_limit, to, value, data, v, r, s];
216
226
return rlp::encode_tuple (tx.nonce , tx.max_gas_price , static_cast <uint64_t >(tx.gas_limit ),
217
227
tx.to .has_value () ? tx.to .value () : bytes_view (), tx.value , tx.data , tx.v , tx.r , tx.s );
218
228
}
219
- else if (tx.kind == Transaction::Kind::eip2930 )
229
+ else if (tx.type == Transaction::Type::access_list )
220
230
{
221
231
if (tx.v > 1 )
222
232
throw std::invalid_argument (" `v` value for eip2930 transaction must be 0 or 1" );
@@ -245,7 +255,7 @@ std::variant<TransactionReceipt, std::error_code> transition(
245
255
246
256
[[nodiscard]] bytes rlp_encode (const TransactionReceipt& receipt)
247
257
{
248
- const auto prefix = receipt.kind == Transaction::Kind ::eip1559 ? bytes{0x02 } : bytes{};
258
+ const auto prefix = receipt.type == Transaction::Type ::eip1559 ? bytes{0x02 } : bytes{};
249
259
return prefix + rlp::encode_tuple (receipt.status == EVMC_SUCCESS,
250
260
static_cast <uint64_t >(receipt.gas_used ),
251
261
bytes_view (receipt.logs_bloom_filter ), receipt.logs );
0 commit comments