Skip to content

Commit

Permalink
devnet-5: Move EIP-7702 Authorization validation to authority func (#…
Browse files Browse the repository at this point in the history
…2999)

* Move EIP-7702 Authorization validation to authority func

If the authorization is invalid the transaction itself is still valid,
the invalid authorization will be skipped.

* Fix copyright year
  • Loading branch information
jangko authored Jan 15, 2025
1 parent 288ee28 commit 265d794
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 13 deletions.
40 changes: 38 additions & 2 deletions hive_integration/nodocker/engine/tx_sender.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Nimbus
# Copyright (c) 2023-2024 Status Research & Development GmbH
# Copyright (c) 2023-2025 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# http://www.apache.org/licenses/LICENSE-2.0)
Expand Down Expand Up @@ -34,6 +34,7 @@ type
blobGasFee*: UInt256
blobCount* : int
blobID* : BlobID
authorizationList*: seq[Authorization]

BigInitcodeTx* = object of BaseTx
initcodeLength*: int
Expand Down Expand Up @@ -75,6 +76,7 @@ type
data* : Opt[seq[byte]]
chainId* : Opt[ChainId]
signature* : Opt[CustSig]
auth* : Opt[Authorization]

const
TestAccountCount = 1000
Expand Down Expand Up @@ -203,6 +205,21 @@ proc makeTxOfType(params: MakeTxParams, tc: BaseTx): PooledTransaction =
proofs: blobData.proofs.mapIt(KzgProof it.bytes),
)
)
of TxEip7702:
PooledTransaction(
tx: Transaction(
txType : TxEip7702,
nonce : params.nonce,
gasLimit: tc.gasLimit,
maxFeePerGas: gasFeeCap,
maxPriorityFeePerGas: gasTipCap,
to : tc.recipient,
value : tc.amount,
payload : tc.payload,
chainId : params.chainId,
authorizationList: tc.authorizationList,
)
)
else:
raiseAssert "unsupported tx type"

Expand Down Expand Up @@ -433,7 +450,7 @@ proc customizeTransaction*(sender: TxSender,
if custTx.chainId.isSome:
modTx.chainId = custTx.chainId.get

if baseTx.txType in {TxEip1559, TxEip4844}:
if baseTx.txType in {TxEip1559, TxEip4844, TxEip7702}:
if custTx.gasPriceOrGasFeeCap.isSome:
modTx.maxFeePerGas = custTx.gasPriceOrGasFeeCap.get.GasInt

Expand All @@ -449,6 +466,11 @@ proc customizeTransaction*(sender: TxSender,
doAssert(baseTx.txType == TxEip4844)
modTx.maxFeePerBlobGas = custTx.blobGas.get

if custTx.auth.isSome:
doAssert(baseTx.txType == TxEip7702)
doAssert(baseTx.authorizationList.len > 0)
modTx.authorizationList[0] = custTx.auth.get

if custTx.signature.isSome:
let signature = custTx.signature.get
modTx.V = signature.V
Expand All @@ -458,3 +480,17 @@ proc customizeTransaction*(sender: TxSender,
modTx.signature = modTx.sign(acc.key, eip155 = true)

modTx

proc makeAuth*(sender: TxSender, acc: TestAccount, nonce: AccountNonce): Authorization =
var auth = Authorization(
chainId: sender.chainId,
address: acc.address,
nonce: nonce,
)
let hash = auth.rlpHashForSigning()
let sig = sign(acc.key, SkMessage(hash.data))
let raw = sig.toRaw()

auth.r = UInt256.fromBytesBE(raw.toOpenArray(0, 31))
auth.s = UInt256.fromBytesBE(raw.toOpenArray(32, 63))
auth.v = raw[64].uint64
13 changes: 12 additions & 1 deletion nimbus/core/eip7702.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Nimbus
# Copyright (c) 2024 Status Research & Development GmbH
# Copyright (c) 2024-2025 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# http://www.apache.org/licenses/LICENSE-2.0)
Expand All @@ -12,6 +12,7 @@

import
../evm/code_bytes,
../constants,
results,
stew/assign2,
eth/common/eth_types,
Expand All @@ -26,6 +27,16 @@ const
PER_EMPTY_ACCOUNT_COST* = 25000

func authority*(auth: Authorization): Opt[Address] =
const SECP256K1halfN = SECPK1_N div 2

if auth.v > 1'u64:
# auth.v must be 0 or 1
return Opt.none(Address)

if auth.s > SECP256K1halfN:
# auth.s must be <= SECP256K1N/2
return Opt.none(Address)

let sigHash = rlpHashForSigning(auth)

var bytes: array[65, byte]
Expand Down
11 changes: 1 addition & 10 deletions nimbus/core/validate.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Nimbus
# Copyright (c) 2018-2024 Status Research & Development GmbH
# Copyright (c) 2018-2025 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# http://www.apache.org/licenses/LICENSE-2.0)
Expand Down Expand Up @@ -273,15 +273,6 @@ proc validateTxBasic*(
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.v > 1'u64:
return err("invalid tx: auth.v must be 0 or 1")

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

ok()

proc validateTransaction*(
Expand Down
42 changes: 42 additions & 0 deletions tests/test_txpool.nim
Original file line number Diff line number Diff line change
Expand Up @@ -572,5 +572,47 @@ proc txPoolMain*() =
inc count
check count == hs.len

test "EIP-7702 transaction before Prague":
let
acc = mx.getAccount(24)
auth = mx.makeAuth(acc, 0)
tc = BaseTx(
txType: Opt.some(TxEip7702),
gasLimit: 75000,
recipient: Opt.some(recipient214),
amount: amount,
authorizationList: @[auth],
)
tx = mx.makeTx(tc, 0)

xp.checkAddTx(tx, txErrorBasicValidation)

test "EIP-7702 transaction invalid auth signature":
let
env = initEnv(Prague)
xp = env.xp
mx = env.sender
acc = mx.getAccount(25)
auth = mx.makeAuth(acc, 0)
tc = BaseTx(
txType: Opt.some(TxEip7702),
gasLimit: 75000,
recipient: Opt.some(recipient214),
amount: amount,
authorizationList: @[auth],
)
ptx = mx.makeTx(tc, 0)

# invalid auth
var invauth = auth
invauth.v = 3.uint64
let
ctx = CustomTx(auth: Opt.some(invauth))
tx = mx.customizeTransaction(acc, ptx.tx, ctx)

xp.checkAddTx(tx)
# invalid auth, but the tx itself still valid
xp.checkImportBlock(1, 0)

when isMainModule:
txPoolMain()

0 comments on commit 265d794

Please sign in to comment.