mirror of https://github.com/status-im/nim-eth.git
Introduce wrapper type for EIP-4844 transactions (#682)
EIP-4844 blob sidecars are a concept that only exists in the mempool. After inclusion of a transaction into an execution block, only the versioned hash within the transaction remains. To improve type safety, replace the `Transaction.networkPayload` member with a wrapper type `PooledTransaction` that is used in contexts where blob sidecars exist.
This commit is contained in:
parent
4cd9e27c09
commit
c482b4c5b6
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2022-2023 Status Research & Development GmbH
|
# Copyright (c) 2022-2024 Status Research & Development GmbH
|
||||||
# Licensed and distributed under either of
|
# Licensed and distributed under either of
|
||||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
||||||
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||||
|
@ -75,10 +75,6 @@ type
|
||||||
TxEip1559 # 2
|
TxEip1559 # 2
|
||||||
TxEip4844 # 3
|
TxEip4844 # 3
|
||||||
|
|
||||||
# instead of wrap Transaction with
|
|
||||||
# NetworkPayload, we embed it to Transaction
|
|
||||||
# the rest of magic happened in RLP
|
|
||||||
# encoding decoding
|
|
||||||
NetworkPayload* = ref object
|
NetworkPayload* = ref object
|
||||||
blobs* : seq[NetworkBlob]
|
blobs* : seq[NetworkBlob]
|
||||||
commitments* : seq[KzgCommitment]
|
commitments* : seq[KzgCommitment]
|
||||||
|
@ -98,10 +94,13 @@ type
|
||||||
accessList* : AccessList # EIP-2930
|
accessList* : AccessList # EIP-2930
|
||||||
maxFeePerBlobGas*: UInt256 # EIP-4844
|
maxFeePerBlobGas*: UInt256 # EIP-4844
|
||||||
versionedHashes*: VersionedHashes # EIP-4844
|
versionedHashes*: VersionedHashes # EIP-4844
|
||||||
networkPayload*: NetworkPayload # EIP-4844
|
|
||||||
V* : int64
|
V* : int64
|
||||||
R*, S* : UInt256
|
R*, S* : UInt256
|
||||||
|
|
||||||
|
PooledTransaction* = object
|
||||||
|
tx*: Transaction
|
||||||
|
networkPayload*: NetworkPayload # EIP-4844
|
||||||
|
|
||||||
TransactionStatus* = enum
|
TransactionStatus* = enum
|
||||||
Unknown,
|
Unknown,
|
||||||
Queued,
|
Queued,
|
||||||
|
@ -176,6 +175,11 @@ type
|
||||||
uncles* : seq[BlockHeader]
|
uncles* : seq[BlockHeader]
|
||||||
withdrawals*: Option[seq[Withdrawal]] # EIP-4895
|
withdrawals*: Option[seq[Withdrawal]] # EIP-4895
|
||||||
|
|
||||||
|
BlobsBundle* = object
|
||||||
|
commitments*: seq[KzgCommitment]
|
||||||
|
proofs*: seq[KzgProof]
|
||||||
|
blobs*: seq[NetworkBlob]
|
||||||
|
|
||||||
# TODO: Make BlockNumber a uint64 and deprecate either this or BlockHashOrNumber
|
# TODO: Make BlockNumber a uint64 and deprecate either this or BlockHashOrNumber
|
||||||
HashOrNum* = object
|
HashOrNum* = object
|
||||||
case isHash*: bool
|
case isHash*: bool
|
||||||
|
@ -294,12 +298,6 @@ func destination*(tx: Transaction): EthAddress =
|
||||||
if tx.to.isSome:
|
if tx.to.isSome:
|
||||||
return tx.to.get
|
return tx.to.get
|
||||||
|
|
||||||
func removeNetworkPayload*(tx: Transaction): Transaction =
|
|
||||||
if tx.networkPayload.isNil:
|
|
||||||
return tx
|
|
||||||
result = tx
|
|
||||||
result.networkPayload = nil
|
|
||||||
|
|
||||||
func init*(T: type BlockHashOrNumber, str: string): T
|
func init*(T: type BlockHashOrNumber, str: string): T
|
||||||
{.raises: [ValueError].} =
|
{.raises: [ValueError].} =
|
||||||
if str.startsWith "0x":
|
if str.startsWith "0x":
|
||||||
|
@ -330,4 +328,3 @@ func `==`*(a, b: NetworkId): bool =
|
||||||
|
|
||||||
func `$`*(x: NetworkId): string =
|
func `$`*(x: NetworkId): string =
|
||||||
`$`(uint(x))
|
`$`(uint(x))
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,6 @@ proc appendTxLegacy(w: var RlpWriter, tx: Transaction) =
|
||||||
w.append(tx.S)
|
w.append(tx.S)
|
||||||
|
|
||||||
proc appendTxEip2930(w: var RlpWriter, tx: Transaction) =
|
proc appendTxEip2930(w: var RlpWriter, tx: Transaction) =
|
||||||
w.append(TxEip2930)
|
|
||||||
w.startList(11)
|
w.startList(11)
|
||||||
w.append(tx.chainId.uint64)
|
w.append(tx.chainId.uint64)
|
||||||
w.append(tx.nonce)
|
w.append(tx.nonce)
|
||||||
|
@ -98,7 +97,6 @@ proc appendTxEip2930(w: var RlpWriter, tx: Transaction) =
|
||||||
w.append(tx.S)
|
w.append(tx.S)
|
||||||
|
|
||||||
proc appendTxEip1559(w: var RlpWriter, tx: Transaction) =
|
proc appendTxEip1559(w: var RlpWriter, tx: Transaction) =
|
||||||
w.append(TxEip1559)
|
|
||||||
w.startList(12)
|
w.startList(12)
|
||||||
w.append(tx.chainId.uint64)
|
w.append(tx.chainId.uint64)
|
||||||
w.append(tx.nonce)
|
w.append(tx.nonce)
|
||||||
|
@ -113,8 +111,7 @@ proc appendTxEip1559(w: var RlpWriter, tx: Transaction) =
|
||||||
w.append(tx.R)
|
w.append(tx.R)
|
||||||
w.append(tx.S)
|
w.append(tx.S)
|
||||||
|
|
||||||
proc appendTxEip4844Signed(w: var RlpWriter, tx: Transaction) =
|
proc appendTxEip4844(w: var RlpWriter, tx: Transaction) =
|
||||||
# exclude tx type
|
|
||||||
w.startList(14)
|
w.startList(14)
|
||||||
w.append(tx.chainId.uint64)
|
w.append(tx.chainId.uint64)
|
||||||
w.append(tx.nonce)
|
w.append(tx.nonce)
|
||||||
|
@ -131,25 +128,7 @@ proc appendTxEip4844Signed(w: var RlpWriter, tx: Transaction) =
|
||||||
w.append(tx.R)
|
w.append(tx.R)
|
||||||
w.append(tx.S)
|
w.append(tx.S)
|
||||||
|
|
||||||
proc appendTxEip4844Network(w: var RlpWriter, tx: Transaction) =
|
proc appendTxPayload(w: var RlpWriter, tx: Transaction) =
|
||||||
# exclude tx type
|
|
||||||
# spec: rlp([tx_payload, blobs, commitments, proofs])
|
|
||||||
w.startList(4)
|
|
||||||
w.appendTxEip4844Signed(tx)
|
|
||||||
w.append(tx.networkPayload.blobs)
|
|
||||||
w.append(tx.networkPayload.commitments)
|
|
||||||
w.append(tx.networkPayload.proofs)
|
|
||||||
|
|
||||||
proc appendTxEip4844(w: var RlpWriter, tx: Transaction) =
|
|
||||||
# append the tx type first
|
|
||||||
w.append(TxEip4844)
|
|
||||||
|
|
||||||
if tx.networkPayload.isNil:
|
|
||||||
w.appendTxEip4844Signed(tx)
|
|
||||||
else:
|
|
||||||
w.appendTxEip4844Network(tx)
|
|
||||||
|
|
||||||
proc append*(w: var RlpWriter, tx: Transaction) =
|
|
||||||
case tx.txType
|
case tx.txType
|
||||||
of TxLegacy:
|
of TxLegacy:
|
||||||
w.appendTxLegacy(tx)
|
w.appendTxLegacy(tx)
|
||||||
|
@ -160,6 +139,25 @@ proc append*(w: var RlpWriter, tx: Transaction) =
|
||||||
of TxEip4844:
|
of TxEip4844:
|
||||||
w.appendTxEip4844(tx)
|
w.appendTxEip4844(tx)
|
||||||
|
|
||||||
|
proc append*(w: var RlpWriter, tx: Transaction) =
|
||||||
|
if tx.txType != TxLegacy:
|
||||||
|
w.append(tx.txType)
|
||||||
|
w.appendTxPayload(tx)
|
||||||
|
|
||||||
|
proc append(w: var RlpWriter, networkPayload: NetworkPayload) =
|
||||||
|
w.append(networkPayload.blobs)
|
||||||
|
w.append(networkPayload.commitments)
|
||||||
|
w.append(networkPayload.proofs)
|
||||||
|
|
||||||
|
proc append*(w: var RlpWriter, tx: PooledTransaction) =
|
||||||
|
if tx.tx.txType != TxLegacy:
|
||||||
|
w.append(tx.tx.txType)
|
||||||
|
if tx.networkPayload != nil:
|
||||||
|
w.startList(4) # spec: rlp([tx_payload, blobs, commitments, proofs])
|
||||||
|
w.appendTxPayload(tx.tx)
|
||||||
|
if tx.networkPayload != nil:
|
||||||
|
w.append(tx.networkPayload)
|
||||||
|
|
||||||
template read[T](rlp: var Rlp, val: var T) =
|
template read[T](rlp: var Rlp, val: var T) =
|
||||||
val = rlp.read(type val)
|
val = rlp.read(type val)
|
||||||
|
|
||||||
|
@ -213,7 +211,8 @@ proc readTxEip1559(rlp: var Rlp, tx: var Transaction)=
|
||||||
rlp.read(tx.R)
|
rlp.read(tx.R)
|
||||||
rlp.read(tx.S)
|
rlp.read(tx.S)
|
||||||
|
|
||||||
proc readTxEip4844Signed(rlp: var Rlp, tx: var Transaction) =
|
proc readTxEip4844(rlp: var Rlp, tx: var Transaction) =
|
||||||
|
tx.txType = TxEip4844
|
||||||
rlp.tryEnterList()
|
rlp.tryEnterList()
|
||||||
tx.chainId = rlp.read(uint64).ChainId
|
tx.chainId = rlp.read(uint64).ChainId
|
||||||
rlp.read(tx.nonce)
|
rlp.read(tx.nonce)
|
||||||
|
@ -230,28 +229,11 @@ proc readTxEip4844Signed(rlp: var Rlp, tx: var Transaction) =
|
||||||
rlp.read(tx.R)
|
rlp.read(tx.R)
|
||||||
rlp.read(tx.S)
|
rlp.read(tx.S)
|
||||||
|
|
||||||
proc readTxEip4844Network(rlp: var Rlp, tx: var Transaction) =
|
proc readTxType(rlp: var Rlp): TxType =
|
||||||
# spec: rlp([tx_payload, blobs, commitments, proofs])
|
if rlp.isList:
|
||||||
rlp.tryEnterList()
|
raise newException(RlpTypeMismatch,
|
||||||
rlp.readTxEip4844Signed(tx)
|
"Transaction type expected, but source RLP is a list")
|
||||||
var np = NetworkPayload()
|
|
||||||
rlp.read(np.blobs)
|
|
||||||
rlp.read(np.commitments)
|
|
||||||
rlp.read(np.proofs)
|
|
||||||
tx.networkPayload = np
|
|
||||||
|
|
||||||
proc readTxEip4844(rlp: var Rlp, tx: var Transaction) =
|
|
||||||
tx.txType = TxEip4844
|
|
||||||
let listLen = rlp.listLen
|
|
||||||
if listLen == 4:
|
|
||||||
rlp.readTxEip4844Network(tx)
|
|
||||||
elif listLen == 14:
|
|
||||||
rlp.readTxEip4844Signed(tx)
|
|
||||||
else:
|
|
||||||
raise newException(MalformedRlpError,
|
|
||||||
"Invalid EIP-4844 transaction: listLen should be in 4 or 14, got: " & $listLen)
|
|
||||||
|
|
||||||
proc readTxTyped(rlp: var Rlp, tx: var Transaction) {.inline.} =
|
|
||||||
# EIP-2718: We MUST decode the first byte as a byte, not `rlp.read(int)`.
|
# EIP-2718: We MUST decode the first byte as a byte, not `rlp.read(int)`.
|
||||||
# If decoded with `rlp.read(int)`, bad transaction data (from the network)
|
# If decoded with `rlp.read(int)`, bad transaction data (from the network)
|
||||||
# or even just incorrectly framed data for other reasons fails with
|
# or even just incorrectly framed data for other reasons fails with
|
||||||
|
@ -273,22 +255,27 @@ proc readTxTyped(rlp: var Rlp, tx: var Transaction) {.inline.} =
|
||||||
|
|
||||||
var txVal: TxType
|
var txVal: TxType
|
||||||
if checkedEnumAssign(txVal, txType):
|
if checkedEnumAssign(txVal, txType):
|
||||||
case txVal:
|
return txVal
|
||||||
of TxEip2930:
|
|
||||||
rlp.readTxEip2930(tx)
|
|
||||||
return
|
|
||||||
of TxEip1559:
|
|
||||||
rlp.readTxEip1559(tx)
|
|
||||||
return
|
|
||||||
of TxEip4844:
|
|
||||||
rlp.readTxEip4844(tx)
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
discard
|
|
||||||
|
|
||||||
raise newException(UnsupportedRlpError,
|
raise newException(UnsupportedRlpError,
|
||||||
"TypedTransaction type must be 1, 2, or 3 in this version, got " & $txType)
|
"TypedTransaction type must be 1, 2, or 3 in this version, got " & $txType)
|
||||||
|
|
||||||
|
proc readTxPayload(rlp: var Rlp, tx: var Transaction, txType: TxType) =
|
||||||
|
case txType
|
||||||
|
of TxLegacy:
|
||||||
|
raise newException(RlpTypeMismatch,
|
||||||
|
"LegacyTransaction should not be wrapped in a list")
|
||||||
|
of TxEip2930:
|
||||||
|
rlp.readTxEip2930(tx)
|
||||||
|
of TxEip1559:
|
||||||
|
rlp.readTxEip1559(tx)
|
||||||
|
of TxEip4844:
|
||||||
|
rlp.readTxEip4844(tx)
|
||||||
|
|
||||||
|
proc readTxTyped(rlp: var Rlp, tx: var Transaction) =
|
||||||
|
let txType = rlp.readTxType()
|
||||||
|
rlp.readTxPayload(tx, txType)
|
||||||
|
|
||||||
proc read*(rlp: var Rlp, T: type Transaction): T =
|
proc read*(rlp: var Rlp, T: type Transaction): T =
|
||||||
# Individual transactions are encoded and stored as either `RLP([fields..])`
|
# Individual transactions are encoded and stored as either `RLP([fields..])`
|
||||||
# for legacy transactions, or `Type || RLP([fields..])`. Both of these
|
# for legacy transactions, or `Type || RLP([fields..])`. Both of these
|
||||||
|
@ -299,8 +286,36 @@ proc read*(rlp: var Rlp, T: type Transaction): T =
|
||||||
else:
|
else:
|
||||||
rlp.readTxTyped(result)
|
rlp.readTxTyped(result)
|
||||||
|
|
||||||
proc read*(rlp: var Rlp,
|
proc read(rlp: var Rlp, T: type NetworkPayload): T =
|
||||||
T: (type seq[Transaction]) | (type openArray[Transaction])): seq[Transaction] =
|
result = NetworkPayload()
|
||||||
|
rlp.read(result.blobs)
|
||||||
|
rlp.read(result.commitments)
|
||||||
|
rlp.read(result.proofs)
|
||||||
|
|
||||||
|
proc readTxTyped(rlp: var Rlp, tx: var PooledTransaction) =
|
||||||
|
let
|
||||||
|
txType = rlp.readTxType()
|
||||||
|
hasNetworkPayload =
|
||||||
|
if txType == TxEip4844:
|
||||||
|
rlp.listLen == 4
|
||||||
|
else:
|
||||||
|
false
|
||||||
|
if hasNetworkPayload:
|
||||||
|
rlp.tryEnterList() # spec: rlp([tx_payload, blobs, commitments, proofs])
|
||||||
|
rlp.readTxPayload(tx.tx, txType)
|
||||||
|
if hasNetworkPayload:
|
||||||
|
rlp.read(tx.networkPayload)
|
||||||
|
|
||||||
|
proc read*(rlp: var Rlp, T: type PooledTransaction): T =
|
||||||
|
if rlp.isList:
|
||||||
|
rlp.readTxLegacy(result.tx)
|
||||||
|
else:
|
||||||
|
rlp.readTxTyped(result)
|
||||||
|
|
||||||
|
proc read*(
|
||||||
|
rlp: var Rlp,
|
||||||
|
T: (type seq[Transaction]) | (type openArray[Transaction])
|
||||||
|
): seq[Transaction] =
|
||||||
# In arrays (sequences), transactions are encoded as either `RLP([fields..])`
|
# In arrays (sequences), transactions are encoded as either `RLP([fields..])`
|
||||||
# for legacy transactions, or `RLP(Type || RLP([fields..]))` for all typed
|
# for legacy transactions, or `RLP(Type || RLP([fields..]))` for all typed
|
||||||
# transactions to date. Spot the extra `RLP(..)` blob encoding, to make it
|
# transactions to date. Spot the extra `RLP(..)` blob encoding, to make it
|
||||||
|
@ -325,6 +340,22 @@ proc read*(rlp: var Rlp,
|
||||||
rr.readTxTyped(tx)
|
rr.readTxTyped(tx)
|
||||||
result.add tx
|
result.add tx
|
||||||
|
|
||||||
|
proc read*(
|
||||||
|
rlp: var Rlp,
|
||||||
|
T: (type seq[PooledTransaction]) | (type openArray[PooledTransaction])
|
||||||
|
): seq[PooledTransaction] =
|
||||||
|
if not rlp.isList:
|
||||||
|
raise newException(RlpTypeMismatch,
|
||||||
|
"PooledTransaction list expected, but source RLP is not a list")
|
||||||
|
for item in rlp:
|
||||||
|
var tx: PooledTransaction
|
||||||
|
if item.isList:
|
||||||
|
item.readTxLegacy(tx.tx)
|
||||||
|
else:
|
||||||
|
var rr = rlpFromBytes(rlp.read(Blob))
|
||||||
|
rr.readTxTyped(tx)
|
||||||
|
result.add tx
|
||||||
|
|
||||||
proc append*(rlpWriter: var RlpWriter,
|
proc append*(rlpWriter: var RlpWriter,
|
||||||
txs: seq[Transaction] | openArray[Transaction]) {.inline.} =
|
txs: seq[Transaction] | openArray[Transaction]) {.inline.} =
|
||||||
# See above about encoding arrays/sequences of transactions.
|
# See above about encoding arrays/sequences of transactions.
|
||||||
|
@ -335,6 +366,16 @@ proc append*(rlpWriter: var RlpWriter,
|
||||||
else:
|
else:
|
||||||
rlpWriter.append(rlp.encode(tx))
|
rlpWriter.append(rlp.encode(tx))
|
||||||
|
|
||||||
|
proc append*(
|
||||||
|
rlpWriter: var RlpWriter,
|
||||||
|
txs: seq[PooledTransaction] | openArray[PooledTransaction]) {.inline.} =
|
||||||
|
rlpWriter.startList(txs.len)
|
||||||
|
for tx in txs:
|
||||||
|
if tx.tx.txType == TxLegacy:
|
||||||
|
rlpWriter.append(tx)
|
||||||
|
else:
|
||||||
|
rlpWriter.append(rlp.encode(tx))
|
||||||
|
|
||||||
proc append*(w: var RlpWriter, rec: Receipt) =
|
proc append*(w: var RlpWriter, rec: Receipt) =
|
||||||
if rec.receiptType in {Eip2930Receipt, Eip1559Receipt, Eip4844Receipt}:
|
if rec.receiptType in {Eip2930Receipt, Eip1559Receipt, Eip4844Receipt}:
|
||||||
w.append(rec.receiptType.int)
|
w.append(rec.receiptType.int)
|
||||||
|
@ -477,8 +518,8 @@ proc append*(rlpWriter: var RlpWriter, t: EthTime) {.inline.} =
|
||||||
proc rlpHash*[T](v: T): Hash256 =
|
proc rlpHash*[T](v: T): Hash256 =
|
||||||
keccakHash(rlp.encode(v))
|
keccakHash(rlp.encode(v))
|
||||||
|
|
||||||
proc rlpHash*(tx: Transaction): Hash256 =
|
proc rlpHash*(tx: PooledTransaction): Hash256 =
|
||||||
keccakHash(rlp.encode(tx.removeNetworkPayload))
|
keccakHash(rlp.encode(tx.tx))
|
||||||
|
|
||||||
func blockHash*(h: BlockHeader): KeccakHash {.inline.} = rlpHash(h)
|
func blockHash*(h: BlockHeader): KeccakHash {.inline.} = rlpHash(h)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Nimbus
|
# Nimbus
|
||||||
# Copyright (c) 2023 Status Research & Development GmbH
|
# Copyright (c) 2023-2024 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)
|
||||||
|
@ -26,26 +26,29 @@ const
|
||||||
blob = default(NetworkBlob)
|
blob = default(NetworkBlob)
|
||||||
abcdef = hexToSeqByte("abcdef")
|
abcdef = hexToSeqByte("abcdef")
|
||||||
|
|
||||||
proc tx0(i: int): Transaction =
|
proc tx0(i: int): PooledTransaction =
|
||||||
Transaction(
|
PooledTransaction(
|
||||||
|
tx: Transaction(
|
||||||
txType: TxLegacy,
|
txType: TxLegacy,
|
||||||
nonce: i.AccountNonce,
|
nonce: i.AccountNonce,
|
||||||
to: recipient.some,
|
to: recipient.some,
|
||||||
gasLimit: 1.GasInt,
|
gasLimit: 1.GasInt,
|
||||||
gasPrice: 2.GasInt,
|
gasPrice: 2.GasInt,
|
||||||
payload: abcdef)
|
payload: abcdef))
|
||||||
|
|
||||||
proc tx1(i: int): Transaction =
|
proc tx1(i: int): PooledTransaction =
|
||||||
Transaction(
|
PooledTransaction(
|
||||||
|
tx: Transaction(
|
||||||
# Legacy tx contract creation.
|
# Legacy tx contract creation.
|
||||||
txType: TxLegacy,
|
txType: TxLegacy,
|
||||||
nonce: i.AccountNonce,
|
nonce: i.AccountNonce,
|
||||||
gasLimit: 1.GasInt,
|
gasLimit: 1.GasInt,
|
||||||
gasPrice: 2.GasInt,
|
gasPrice: 2.GasInt,
|
||||||
payload: abcdef)
|
payload: abcdef))
|
||||||
|
|
||||||
proc tx2(i: int): Transaction =
|
proc tx2(i: int): PooledTransaction =
|
||||||
Transaction(
|
PooledTransaction(
|
||||||
|
tx: Transaction(
|
||||||
# Tx with non-zero access list.
|
# Tx with non-zero access list.
|
||||||
txType: TxEip2930,
|
txType: TxEip2930,
|
||||||
chainId: 1.ChainId,
|
chainId: 1.ChainId,
|
||||||
|
@ -54,10 +57,11 @@ proc tx2(i: int): Transaction =
|
||||||
gasLimit: 123457.GasInt,
|
gasLimit: 123457.GasInt,
|
||||||
gasPrice: 10.GasInt,
|
gasPrice: 10.GasInt,
|
||||||
accessList: accesses,
|
accessList: accesses,
|
||||||
payload: abcdef)
|
payload: abcdef))
|
||||||
|
|
||||||
proc tx3(i: int): Transaction =
|
proc tx3(i: int): PooledTransaction =
|
||||||
Transaction(
|
PooledTransaction(
|
||||||
|
tx: Transaction(
|
||||||
# Tx with empty access list.
|
# Tx with empty access list.
|
||||||
txType: TxEip2930,
|
txType: TxEip2930,
|
||||||
chainId: 1.ChainId,
|
chainId: 1.ChainId,
|
||||||
|
@ -65,33 +69,36 @@ proc tx3(i: int): Transaction =
|
||||||
to: recipient.some,
|
to: recipient.some,
|
||||||
gasLimit: 123457.GasInt,
|
gasLimit: 123457.GasInt,
|
||||||
gasPrice: 10.GasInt,
|
gasPrice: 10.GasInt,
|
||||||
payload: abcdef)
|
payload: abcdef))
|
||||||
|
|
||||||
proc tx4(i: int): Transaction =
|
proc tx4(i: int): PooledTransaction =
|
||||||
Transaction(
|
PooledTransaction(
|
||||||
|
tx: Transaction(
|
||||||
# Contract creation with access list.
|
# Contract creation with access list.
|
||||||
txType: TxEip2930,
|
txType: TxEip2930,
|
||||||
chainId: 1.ChainId,
|
chainId: 1.ChainId,
|
||||||
nonce: i.AccountNonce,
|
nonce: i.AccountNonce,
|
||||||
gasLimit: 123457.GasInt,
|
gasLimit: 123457.GasInt,
|
||||||
gasPrice: 10.GasInt,
|
gasPrice: 10.GasInt,
|
||||||
accessList: accesses)
|
accessList: accesses))
|
||||||
|
|
||||||
proc tx5(i: int): Transaction =
|
proc tx5(i: int): PooledTransaction =
|
||||||
Transaction(
|
PooledTransaction(
|
||||||
|
tx: Transaction(
|
||||||
txType: TxEip1559,
|
txType: TxEip1559,
|
||||||
chainId: 1.ChainId,
|
chainId: 1.ChainId,
|
||||||
nonce: i.AccountNonce,
|
nonce: i.AccountNonce,
|
||||||
gasLimit: 123457.GasInt,
|
gasLimit: 123457.GasInt,
|
||||||
maxPriorityFee: 42.GasInt,
|
maxPriorityFee: 42.GasInt,
|
||||||
maxFee: 10.GasInt,
|
maxFee: 10.GasInt,
|
||||||
accessList: accesses)
|
accessList: accesses))
|
||||||
|
|
||||||
proc tx6(i: int): Transaction =
|
proc tx6(i: int): PooledTransaction =
|
||||||
const
|
const
|
||||||
digest = "010657f37554c781402a22917dee2f75def7ab966d7b770905398eba3c444014".toDigest
|
digest = "010657f37554c781402a22917dee2f75def7ab966d7b770905398eba3c444014".toDigest
|
||||||
|
|
||||||
Transaction(
|
PooledTransaction(
|
||||||
|
tx: Transaction(
|
||||||
txType: TxEip4844,
|
txType: TxEip4844,
|
||||||
chainId: 1.ChainId,
|
chainId: 1.ChainId,
|
||||||
nonce: i.AccountNonce,
|
nonce: i.AccountNonce,
|
||||||
|
@ -99,19 +106,18 @@ proc tx6(i: int): Transaction =
|
||||||
maxPriorityFee: 42.GasInt,
|
maxPriorityFee: 42.GasInt,
|
||||||
maxFee: 10.GasInt,
|
maxFee: 10.GasInt,
|
||||||
accessList: accesses,
|
accessList: accesses,
|
||||||
versionedHashes: @[digest],
|
versionedHashes: @[digest]),
|
||||||
networkPayload: NetworkPayload(
|
networkPayload: NetworkPayload(
|
||||||
blobs: @[blob],
|
blobs: @[blob],
|
||||||
commitments: @[zeroG1],
|
commitments: @[zeroG1],
|
||||||
proofs: @[zeroG1],
|
proofs: @[zeroG1]))
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
proc tx7(i: int): Transaction =
|
proc tx7(i: int): PooledTransaction =
|
||||||
const
|
const
|
||||||
digest = "01624652859a6e98ffc1608e2af0147ca4e86e1ce27672d8d3f3c9d4ffd6ef7e".toDigest
|
digest = "01624652859a6e98ffc1608e2af0147ca4e86e1ce27672d8d3f3c9d4ffd6ef7e".toDigest
|
||||||
|
|
||||||
Transaction(
|
PooledTransaction(
|
||||||
|
tx: Transaction(
|
||||||
txType: TxEip4844,
|
txType: TxEip4844,
|
||||||
chainID: 1.ChainId,
|
chainID: 1.ChainId,
|
||||||
nonce: i.AccountNonce,
|
nonce: i.AccountNonce,
|
||||||
|
@ -120,14 +126,14 @@ proc tx7(i: int): Transaction =
|
||||||
maxFee: 10.GasInt,
|
maxFee: 10.GasInt,
|
||||||
accessList: accesses,
|
accessList: accesses,
|
||||||
versionedHashes: @[digest],
|
versionedHashes: @[digest],
|
||||||
maxFeePerBlobGas: 10000000.u256,
|
maxFeePerBlobGas: 10000000.u256))
|
||||||
)
|
|
||||||
|
|
||||||
proc tx8(i: int): Transaction =
|
proc tx8(i: int): PooledTransaction =
|
||||||
const
|
const
|
||||||
digest = "01624652859a6e98ffc1608e2af0147ca4e86e1ce27672d8d3f3c9d4ffd6ef7e".toDigest
|
digest = "01624652859a6e98ffc1608e2af0147ca4e86e1ce27672d8d3f3c9d4ffd6ef7e".toDigest
|
||||||
|
|
||||||
Transaction(
|
PooledTransaction(
|
||||||
|
tx: Transaction(
|
||||||
txType: TxEip4844,
|
txType: TxEip4844,
|
||||||
chainID: 1.ChainId,
|
chainID: 1.ChainId,
|
||||||
nonce: i.AccountNonce,
|
nonce: i.AccountNonce,
|
||||||
|
@ -137,13 +143,12 @@ proc tx8(i: int): Transaction =
|
||||||
maxFee: 10.GasInt,
|
maxFee: 10.GasInt,
|
||||||
accessList: accesses,
|
accessList: accesses,
|
||||||
versionedHashes: @[digest],
|
versionedHashes: @[digest],
|
||||||
maxFeePerBlobGas: 10000000.u256,
|
maxFeePerBlobGas: 10000000.u256))
|
||||||
)
|
|
||||||
|
|
||||||
template roundTrip(txFunc: untyped, i: int) =
|
template roundTrip(txFunc: untyped, i: int) =
|
||||||
let tx = txFunc(i)
|
let tx = txFunc(i)
|
||||||
let bytes = rlp.encode(tx)
|
let bytes = rlp.encode(tx)
|
||||||
let tx2 = rlp.decode(bytes, Transaction)
|
let tx2 = rlp.decode(bytes, PooledTransaction)
|
||||||
let bytes2 = rlp.encode(tx2)
|
let bytes2 = rlp.encode(tx2)
|
||||||
check bytes == bytes2
|
check bytes == bytes2
|
||||||
|
|
||||||
|
@ -178,7 +183,7 @@ suite "Transaction RLP Encoding":
|
||||||
test "Network payload survive encode decode":
|
test "Network payload survive encode decode":
|
||||||
let tx = tx6(10)
|
let tx = tx6(10)
|
||||||
let bytes = rlp.encode(tx)
|
let bytes = rlp.encode(tx)
|
||||||
let zz = rlp.decode(bytes, Transaction)
|
let zz = rlp.decode(bytes, PooledTransaction)
|
||||||
check not zz.networkPayload.isNil
|
check not zz.networkPayload.isNil
|
||||||
check zz.networkPayload.proofs == tx.networkPayload.proofs
|
check zz.networkPayload.proofs == tx.networkPayload.proofs
|
||||||
check zz.networkPayload.blobs == tx.networkPayload.blobs
|
check zz.networkPayload.blobs == tx.networkPayload.blobs
|
||||||
|
@ -187,21 +192,21 @@ suite "Transaction RLP Encoding":
|
||||||
test "No Network payload still no network payload":
|
test "No Network payload still no network payload":
|
||||||
let tx = tx7(11)
|
let tx = tx7(11)
|
||||||
let bytes = rlp.encode(tx)
|
let bytes = rlp.encode(tx)
|
||||||
let zz = rlp.decode(bytes, Transaction)
|
let zz = rlp.decode(bytes, PooledTransaction)
|
||||||
check zz.networkPayload.isNil
|
check zz.networkPayload.isNil
|
||||||
|
|
||||||
test "Minimal Blob tx recipient survive encode decode":
|
test "Minimal Blob tx recipient survive encode decode":
|
||||||
let tx = tx8(12)
|
let tx = tx8(12)
|
||||||
let bytes = rlp.encode(tx)
|
let bytes = rlp.encode(tx)
|
||||||
let zz = rlp.decode(bytes, Transaction)
|
let zz = rlp.decode(bytes, PooledTransaction)
|
||||||
check zz.to.isSome
|
check zz.tx.to.isSome
|
||||||
|
|
||||||
test "Tx List 0,1,2,3,4,5,6,7,8":
|
test "Tx List 0,1,2,3,4,5,6,7,8":
|
||||||
let txs = @[tx0(3), tx1(3), tx2(3), tx3(3), tx4(3),
|
let txs = @[tx0(3), tx1(3), tx2(3), tx3(3), tx4(3),
|
||||||
tx5(3), tx6(3), tx7(3), tx8(3)]
|
tx5(3), tx6(3), tx7(3), tx8(3)]
|
||||||
|
|
||||||
let bytes = rlp.encode(txs)
|
let bytes = rlp.encode(txs)
|
||||||
let zz = rlp.decode(bytes, seq[Transaction])
|
let zz = rlp.decode(bytes, seq[PooledTransaction])
|
||||||
let bytes2 = rlp.encode(zz)
|
let bytes2 = rlp.encode(zz)
|
||||||
check bytes2 == bytes
|
check bytes2 == bytes
|
||||||
|
|
||||||
|
@ -210,7 +215,7 @@ suite "Transaction RLP Encoding":
|
||||||
tx3(3), tx2(3), tx1(3), tx0(3)]
|
tx3(3), tx2(3), tx1(3), tx0(3)]
|
||||||
|
|
||||||
let bytes = rlp.encode(txs)
|
let bytes = rlp.encode(txs)
|
||||||
let zz = rlp.decode(bytes, seq[Transaction])
|
let zz = rlp.decode(bytes, seq[PooledTransaction])
|
||||||
let bytes2 = rlp.encode(zz)
|
let bytes2 = rlp.encode(zz)
|
||||||
check bytes2 == bytes
|
check bytes2 == bytes
|
||||||
|
|
||||||
|
@ -219,7 +224,7 @@ suite "Transaction RLP Encoding":
|
||||||
tx4(3), tx3(3), tx2(3), tx1(3)]
|
tx4(3), tx3(3), tx2(3), tx1(3)]
|
||||||
|
|
||||||
let bytes = rlp.encode(txs)
|
let bytes = rlp.encode(txs)
|
||||||
let zz = rlp.decode(bytes, seq[Transaction])
|
let zz = rlp.decode(bytes, seq[PooledTransaction])
|
||||||
let bytes2 = rlp.encode(zz)
|
let bytes2 = rlp.encode(zz)
|
||||||
check bytes2 == bytes
|
check bytes2 == bytes
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue