Skip to content

Commit

Permalink
Implement EIP-7702 part 2: Tx validation
Browse files Browse the repository at this point in the history
  • Loading branch information
jangko committed Sep 18, 2024
1 parent 98aefa2 commit 6c4bf7b
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 7 deletions.
2 changes: 1 addition & 1 deletion nimbus/core/tx_pool/tx_tasks/tx_classify.nim
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ proc txFeesCovered(xp: TxPoolRef; item: TxItemRef): bool =
baseFee = xp.baseFee
return false

if item.tx.txType >= TxEip4844:
if item.tx.txType == TxEip4844:
let
excessBlobGas = xp.excessBlobGas
blobGasPrice = getBlobBaseFee(excessBlobGas)
Expand Down
22 changes: 19 additions & 3 deletions nimbus/core/validate.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import
std/[sequtils, sets, strformat],
../db/ledger,
".."/[transaction, common/common],
".."/[errors],
".."/[errors, constants],
../utils/utils,
"."/[dao, eip4844, gaslimit, withdrawals],
./pow/[difficulty, header],
Expand Down Expand Up @@ -205,6 +205,9 @@ proc validateTxBasic*(
if tx.txType == TxEip4844 and fork < FkCancun:
return err("invalid tx: Eip4844 Tx type detected before Cancun")

if tx.txType == TxEip7702 and fork < FkPrague:
return err("invalid tx: Eip7702 Tx type detected before Prague")

if fork >= FkShanghai and tx.contractCreation and tx.payload.len > EIP3860_MAX_INITCODE_SIZE:
return err("invalid tx: initcode size exceeds maximum")

Expand All @@ -228,7 +231,7 @@ proc validateTxBasic*(
return err("invalid tx: access list storage keys len exceeds MAX_ACCESS_LIST_STORAGE_KEYS. " &
&"index={i}, len={acl.storageKeys.len}")

if tx.txType >= TxEip4844:
if tx.txType == TxEip4844:
if tx.to.isNone:
return err("invalid tx: destination must be not empty")

Expand All @@ -243,6 +246,19 @@ proc validateTxBasic*(
return err("invalid tx: one of blobVersionedHash has invalid version. " &
&"get={bv.data[0].int}, expect={VERSIONED_HASH_VERSION_KZG.int}")

if tx.txType == TxEip7702:
if tx.authorizationList.len == 0:
return err("invalid tx: authorization list must not empty")

const SECP256K1halfN = SECPK1_N div 2

for auth in tx.authorizationList:
if auth.yParity > 1'u64:
return err("invalid tx: auth.yParity must be 0 or 1")

if auth.S > SECP256K1halfN:
return err("invalid tx: auth.S must be <= SECP256K1N/2")

ok()

proc validateTransaction*(
Expand Down Expand Up @@ -306,7 +322,7 @@ proc validateTransaction*(
if codeHash != EMPTY_CODE_HASH:
return err(&"invalid tx: sender is not an EOA. sender={sender.toHex}, codeHash={codeHash.data.toHex}")

if tx.txType >= TxEip4844:
if tx.txType == TxEip4844:
# ensure that the user was willing to at least pay the current data gasprice
let blobGasPrice = getBlobBaseFee(excessBlobGas)
if tx.maxFeePerBlobGas < blobGasPrice:
Expand Down
9 changes: 6 additions & 3 deletions premix/parser.nim
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,15 @@ proc parseTransaction*(n: JsonNode): Transaction =
for acn in accessList:
tx.accessList.add parseAccessPair(acn)

if tx.txType >= TxEip4844:
if tx.txType == TxEip4844:
n.fromJson "maxFeePerBlobGas", tx.maxFeePerBlobGas

if n.hasKey("versionedHashes") and n["versionedHashes"].kind != JNull:
n.fromJson "versionedHashes", tx.versionedHashes
if n.hasKey("versionedHashes") and n["versionedHashes"].kind != JNull:
n.fromJson "versionedHashes", tx.versionedHashes

if tx.txType == TxEip7702:
n.fromJson "authorizationList", tx.authorizationList

tx

proc parseWithdrawal*(n: JsonNode): Withdrawal =
Expand Down

0 comments on commit 6c4bf7b

Please sign in to comment.