mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-10 11:06:49 +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
|
# Nimbus
|
||||||
# Copyright (c) 2023-2024 Status Research & Development GmbH
|
# Copyright (c) 2023-2025 Status Research & Development GmbH
|
||||||
# Licensed under either of
|
# Licensed under either of
|
||||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0)
|
# http://www.apache.org/licenses/LICENSE-2.0)
|
||||||
@ -34,6 +34,7 @@ type
|
|||||||
blobGasFee*: UInt256
|
blobGasFee*: UInt256
|
||||||
blobCount* : int
|
blobCount* : int
|
||||||
blobID* : BlobID
|
blobID* : BlobID
|
||||||
|
authorizationList*: seq[Authorization]
|
||||||
|
|
||||||
BigInitcodeTx* = object of BaseTx
|
BigInitcodeTx* = object of BaseTx
|
||||||
initcodeLength*: int
|
initcodeLength*: int
|
||||||
@ -75,6 +76,7 @@ type
|
|||||||
data* : Opt[seq[byte]]
|
data* : Opt[seq[byte]]
|
||||||
chainId* : Opt[ChainId]
|
chainId* : Opt[ChainId]
|
||||||
signature* : Opt[CustSig]
|
signature* : Opt[CustSig]
|
||||||
|
auth* : Opt[Authorization]
|
||||||
|
|
||||||
const
|
const
|
||||||
TestAccountCount = 1000
|
TestAccountCount = 1000
|
||||||
@ -203,6 +205,21 @@ proc makeTxOfType(params: MakeTxParams, tc: BaseTx): PooledTransaction =
|
|||||||
proofs: blobData.proofs.mapIt(KzgProof it.bytes),
|
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:
|
else:
|
||||||
raiseAssert "unsupported tx type"
|
raiseAssert "unsupported tx type"
|
||||||
|
|
||||||
@ -433,7 +450,7 @@ proc customizeTransaction*(sender: TxSender,
|
|||||||
if custTx.chainId.isSome:
|
if custTx.chainId.isSome:
|
||||||
modTx.chainId = custTx.chainId.get
|
modTx.chainId = custTx.chainId.get
|
||||||
|
|
||||||
if baseTx.txType in {TxEip1559, TxEip4844}:
|
if baseTx.txType in {TxEip1559, TxEip4844, TxEip7702}:
|
||||||
if custTx.gasPriceOrGasFeeCap.isSome:
|
if custTx.gasPriceOrGasFeeCap.isSome:
|
||||||
modTx.maxFeePerGas = custTx.gasPriceOrGasFeeCap.get.GasInt
|
modTx.maxFeePerGas = custTx.gasPriceOrGasFeeCap.get.GasInt
|
||||||
|
|
||||||
@ -449,6 +466,11 @@ proc customizeTransaction*(sender: TxSender,
|
|||||||
doAssert(baseTx.txType == TxEip4844)
|
doAssert(baseTx.txType == TxEip4844)
|
||||||
modTx.maxFeePerBlobGas = custTx.blobGas.get
|
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:
|
if custTx.signature.isSome:
|
||||||
let signature = custTx.signature.get
|
let signature = custTx.signature.get
|
||||||
modTx.V = signature.V
|
modTx.V = signature.V
|
||||||
@ -458,3 +480,17 @@ proc customizeTransaction*(sender: TxSender,
|
|||||||
modTx.signature = modTx.sign(acc.key, eip155 = true)
|
modTx.signature = modTx.sign(acc.key, eip155 = true)
|
||||||
|
|
||||||
modTx
|
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
|
# Nimbus
|
||||||
# Copyright (c) 2024 Status Research & Development GmbH
|
# Copyright (c) 2024-2025 Status Research & Development GmbH
|
||||||
# Licensed under either of
|
# Licensed under either of
|
||||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0)
|
# http://www.apache.org/licenses/LICENSE-2.0)
|
||||||
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
import
|
import
|
||||||
../evm/code_bytes,
|
../evm/code_bytes,
|
||||||
|
../constants,
|
||||||
results,
|
results,
|
||||||
stew/assign2,
|
stew/assign2,
|
||||||
eth/common/eth_types,
|
eth/common/eth_types,
|
||||||
@ -26,6 +27,16 @@ const
|
|||||||
PER_EMPTY_ACCOUNT_COST* = 25000
|
PER_EMPTY_ACCOUNT_COST* = 25000
|
||||||
|
|
||||||
func authority*(auth: Authorization): Opt[Address] =
|
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)
|
let sigHash = rlpHashForSigning(auth)
|
||||||
|
|
||||||
var bytes: array[65, byte]
|
var bytes: array[65, byte]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Nimbus
|
# Nimbus
|
||||||
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
# Copyright (c) 2018-2025 Status Research & Development GmbH
|
||||||
# Licensed under either of
|
# Licensed under either of
|
||||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0)
|
# http://www.apache.org/licenses/LICENSE-2.0)
|
||||||
@ -273,15 +273,6 @@ proc validateTxBasic*(
|
|||||||
if tx.authorizationList.len == 0:
|
if tx.authorizationList.len == 0:
|
||||||
return err("invalid tx: authorization list must not empty")
|
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()
|
ok()
|
||||||
|
|
||||||
proc validateTransaction*(
|
proc validateTransaction*(
|
||||||
|
@ -572,5 +572,47 @@ proc txPoolMain*() =
|
|||||||
inc count
|
inc count
|
||||||
check count == hs.len
|
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:
|
when isMainModule:
|
||||||
txPoolMain()
|
txPoolMain()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user