mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-05 00:36:45 +00:00
devnet-5: Move EIP-7702 Authorization validation to authority func (#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
This commit is contained in:
parent
288ee28077
commit
265d794583
@ -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)
|
||||
@ -34,6 +34,7 @@ type
|
||||
blobGasFee*: UInt256
|
||||
blobCount* : int
|
||||
blobID* : BlobID
|
||||
authorizationList*: seq[Authorization]
|
||||
|
||||
BigInitcodeTx* = object of BaseTx
|
||||
initcodeLength*: int
|
||||
@ -75,6 +76,7 @@ type
|
||||
data* : Opt[seq[byte]]
|
||||
chainId* : Opt[ChainId]
|
||||
signature* : Opt[CustSig]
|
||||
auth* : Opt[Authorization]
|
||||
|
||||
const
|
||||
TestAccountCount = 1000
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
|
@ -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)
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
import
|
||||
../evm/code_bytes,
|
||||
../constants,
|
||||
results,
|
||||
stew/assign2,
|
||||
eth/common/eth_types,
|
||||
@ -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]
|
||||
|
@ -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)
|
||||
@ -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*(
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user