2023-01-20 04:34:31 +00:00
|
|
|
# Nimbus
|
2024-05-13 08:19:00 +00:00
|
|
|
# Copyright (c) 2023-2024 Status Research & Development GmbH
|
2023-01-20 04:34:31 +00:00
|
|
|
# Licensed under either of
|
|
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0)
|
|
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
|
|
|
# http://opensource.org/licenses/MIT)
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except
|
|
|
|
# according to those terms.
|
|
|
|
{.used.}
|
|
|
|
|
|
|
|
import
|
|
|
|
stew/byteutils,
|
|
|
|
unittest2,
|
|
|
|
../../eth/common,
|
|
|
|
../../eth/rlp,
|
2024-10-01 09:54:01 +00:00
|
|
|
../../eth/common/transactions_rlp
|
2023-01-20 04:34:31 +00:00
|
|
|
|
|
|
|
const
|
2024-09-29 08:52:19 +00:00
|
|
|
recipient = address"095e7baea6a6c7c4c2dfeb977efac326af552d87"
|
|
|
|
zeroG1 = bytes48"0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
|
|
|
source = address"0x0000000000000000000000000000000000000001"
|
2023-01-20 04:34:31 +00:00
|
|
|
storageKey= default(StorageKey)
|
|
|
|
accesses = @[AccessPair(address: source, storageKeys: @[storageKey])]
|
|
|
|
blob = default(NetworkBlob)
|
|
|
|
abcdef = hexToSeqByte("abcdef")
|
|
|
|
|
2024-05-13 08:19:00 +00:00
|
|
|
proc tx0(i: int): PooledTransaction =
|
|
|
|
PooledTransaction(
|
|
|
|
tx: Transaction(
|
|
|
|
txType: TxLegacy,
|
|
|
|
nonce: i.AccountNonce,
|
2024-06-11 17:13:11 +00:00
|
|
|
to: Opt.some recipient,
|
2024-05-13 08:19:00 +00:00
|
|
|
gasLimit: 1.GasInt,
|
|
|
|
gasPrice: 2.GasInt,
|
|
|
|
payload: abcdef))
|
|
|
|
|
|
|
|
proc tx1(i: int): PooledTransaction =
|
|
|
|
PooledTransaction(
|
|
|
|
tx: Transaction(
|
|
|
|
# Legacy tx contract creation.
|
|
|
|
txType: TxLegacy,
|
|
|
|
nonce: i.AccountNonce,
|
|
|
|
gasLimit: 1.GasInt,
|
|
|
|
gasPrice: 2.GasInt,
|
|
|
|
payload: abcdef))
|
|
|
|
|
|
|
|
proc tx2(i: int): PooledTransaction =
|
|
|
|
PooledTransaction(
|
|
|
|
tx: Transaction(
|
|
|
|
# Tx with non-zero access list.
|
|
|
|
txType: TxEip2930,
|
|
|
|
chainId: 1.ChainId,
|
|
|
|
nonce: i.AccountNonce,
|
2024-06-11 17:13:11 +00:00
|
|
|
to: Opt.some recipient,
|
2024-05-13 08:19:00 +00:00
|
|
|
gasLimit: 123457.GasInt,
|
|
|
|
gasPrice: 10.GasInt,
|
|
|
|
accessList: accesses,
|
|
|
|
payload: abcdef))
|
|
|
|
|
|
|
|
proc tx3(i: int): PooledTransaction =
|
|
|
|
PooledTransaction(
|
|
|
|
tx: Transaction(
|
|
|
|
# Tx with empty access list.
|
|
|
|
txType: TxEip2930,
|
|
|
|
chainId: 1.ChainId,
|
|
|
|
nonce: i.AccountNonce,
|
2024-06-11 17:13:11 +00:00
|
|
|
to: Opt.some recipient,
|
2024-05-13 08:19:00 +00:00
|
|
|
gasLimit: 123457.GasInt,
|
|
|
|
gasPrice: 10.GasInt,
|
|
|
|
payload: abcdef))
|
|
|
|
|
|
|
|
proc tx4(i: int): PooledTransaction =
|
|
|
|
PooledTransaction(
|
|
|
|
tx: Transaction(
|
|
|
|
# Contract creation with access list.
|
|
|
|
txType: TxEip2930,
|
|
|
|
chainId: 1.ChainId,
|
|
|
|
nonce: i.AccountNonce,
|
|
|
|
gasLimit: 123457.GasInt,
|
|
|
|
gasPrice: 10.GasInt,
|
|
|
|
accessList: accesses))
|
|
|
|
|
|
|
|
proc tx5(i: int): PooledTransaction =
|
|
|
|
PooledTransaction(
|
|
|
|
tx: Transaction(
|
|
|
|
txType: TxEip1559,
|
|
|
|
chainId: 1.ChainId,
|
|
|
|
nonce: i.AccountNonce,
|
|
|
|
gasLimit: 123457.GasInt,
|
2024-06-11 17:13:11 +00:00
|
|
|
maxPriorityFeePerGas: 42.GasInt,
|
|
|
|
maxFeePerGas: 10.GasInt,
|
2024-05-13 08:19:00 +00:00
|
|
|
accessList: accesses))
|
|
|
|
|
|
|
|
proc tx6(i: int): PooledTransaction =
|
2023-01-20 04:34:31 +00:00
|
|
|
const
|
2024-10-01 09:54:01 +00:00
|
|
|
digest = hash32"010657f37554c781402a22917dee2f75def7ab966d7b770905398eba3c444014"
|
2023-01-20 04:34:31 +00:00
|
|
|
|
2024-05-13 08:19:00 +00:00
|
|
|
PooledTransaction(
|
|
|
|
tx: Transaction(
|
|
|
|
txType: TxEip4844,
|
|
|
|
chainId: 1.ChainId,
|
|
|
|
nonce: i.AccountNonce,
|
|
|
|
gasLimit: 123457.GasInt,
|
2024-06-11 17:13:11 +00:00
|
|
|
maxPriorityFeePerGas:42.GasInt,
|
|
|
|
maxFeePerGas: 10.GasInt,
|
2024-05-13 08:19:00 +00:00
|
|
|
accessList: accesses,
|
|
|
|
versionedHashes: @[digest]),
|
2023-09-24 07:33:24 +00:00
|
|
|
networkPayload: NetworkPayload(
|
2024-05-13 08:19:00 +00:00
|
|
|
blobs: @[blob],
|
|
|
|
commitments: @[zeroG1],
|
|
|
|
proofs: @[zeroG1]))
|
2023-01-20 04:34:31 +00:00
|
|
|
|
2024-05-13 08:19:00 +00:00
|
|
|
proc tx7(i: int): PooledTransaction =
|
2023-01-20 04:34:31 +00:00
|
|
|
const
|
2024-10-01 09:54:01 +00:00
|
|
|
digest = hash32"01624652859a6e98ffc1608e2af0147ca4e86e1ce27672d8d3f3c9d4ffd6ef7e"
|
2023-01-20 04:34:31 +00:00
|
|
|
|
2024-05-13 08:19:00 +00:00
|
|
|
PooledTransaction(
|
|
|
|
tx: Transaction(
|
|
|
|
txType: TxEip4844,
|
|
|
|
chainID: 1.ChainId,
|
|
|
|
nonce: i.AccountNonce,
|
|
|
|
gasLimit: 123457.GasInt,
|
2024-06-11 17:13:11 +00:00
|
|
|
maxPriorityFeePerGas:42.GasInt,
|
|
|
|
maxFeePerGas: 10.GasInt,
|
2024-05-13 08:19:00 +00:00
|
|
|
accessList: accesses,
|
|
|
|
versionedHashes: @[digest],
|
|
|
|
maxFeePerBlobGas: 10000000.u256))
|
|
|
|
|
|
|
|
proc tx8(i: int): PooledTransaction =
|
2023-01-20 04:34:31 +00:00
|
|
|
const
|
2024-10-01 09:54:01 +00:00
|
|
|
digest = hash32"01624652859a6e98ffc1608e2af0147ca4e86e1ce27672d8d3f3c9d4ffd6ef7e"
|
2023-01-20 04:34:31 +00:00
|
|
|
|
2024-05-13 08:19:00 +00:00
|
|
|
PooledTransaction(
|
|
|
|
tx: Transaction(
|
|
|
|
txType: TxEip4844,
|
|
|
|
chainID: 1.ChainId,
|
|
|
|
nonce: i.AccountNonce,
|
2024-06-11 17:13:11 +00:00
|
|
|
to: Opt.some(recipient),
|
2024-05-13 08:19:00 +00:00
|
|
|
gasLimit: 123457.GasInt,
|
2024-06-11 17:13:11 +00:00
|
|
|
maxPriorityFeePerGas:42.GasInt,
|
|
|
|
maxFeePerGas: 10.GasInt,
|
2024-05-13 08:19:00 +00:00
|
|
|
accessList: accesses,
|
|
|
|
versionedHashes: @[digest],
|
|
|
|
maxFeePerBlobGas: 10000000.u256))
|
2023-01-20 04:34:31 +00:00
|
|
|
|
|
|
|
template roundTrip(txFunc: untyped, i: int) =
|
|
|
|
let tx = txFunc(i)
|
|
|
|
let bytes = rlp.encode(tx)
|
2024-05-13 08:19:00 +00:00
|
|
|
let tx2 = rlp.decode(bytes, PooledTransaction)
|
2023-01-20 04:34:31 +00:00
|
|
|
let bytes2 = rlp.encode(tx2)
|
|
|
|
check bytes == bytes2
|
|
|
|
|
|
|
|
suite "Transaction RLP Encoding":
|
|
|
|
test "Legacy Tx Call":
|
|
|
|
roundTrip(tx0, 1)
|
|
|
|
|
|
|
|
test "Legacy tx contract creation":
|
|
|
|
roundTrip(tx1, 2)
|
|
|
|
|
|
|
|
test "Tx with non-zero access list":
|
|
|
|
roundTrip(tx2, 3)
|
|
|
|
|
|
|
|
test "Tx with empty access list":
|
|
|
|
roundTrip(tx3, 4)
|
|
|
|
|
|
|
|
test "Contract creation with access list":
|
|
|
|
roundTrip(tx4, 5)
|
|
|
|
|
|
|
|
test "Dynamic Fee Tx":
|
|
|
|
roundTrip(tx5, 6)
|
|
|
|
|
|
|
|
test "NetworkBlob Tx":
|
|
|
|
roundTrip(tx6, 7)
|
|
|
|
|
|
|
|
test "Minimal Blob Tx":
|
|
|
|
roundTrip(tx7, 8)
|
|
|
|
|
|
|
|
test "Minimal Blob Tx contract creation":
|
|
|
|
roundTrip(tx8, 9)
|
|
|
|
|
|
|
|
test "Network payload survive encode decode":
|
|
|
|
let tx = tx6(10)
|
|
|
|
let bytes = rlp.encode(tx)
|
2024-05-13 08:19:00 +00:00
|
|
|
let zz = rlp.decode(bytes, PooledTransaction)
|
2023-01-20 04:34:31 +00:00
|
|
|
check not zz.networkPayload.isNil
|
|
|
|
check zz.networkPayload.proofs == tx.networkPayload.proofs
|
|
|
|
check zz.networkPayload.blobs == tx.networkPayload.blobs
|
|
|
|
check zz.networkPayload.commitments == tx.networkPayload.commitments
|
|
|
|
|
|
|
|
test "No Network payload still no network payload":
|
|
|
|
let tx = tx7(11)
|
|
|
|
let bytes = rlp.encode(tx)
|
2024-05-13 08:19:00 +00:00
|
|
|
let zz = rlp.decode(bytes, PooledTransaction)
|
2023-01-20 04:34:31 +00:00
|
|
|
check zz.networkPayload.isNil
|
|
|
|
|
|
|
|
test "Minimal Blob tx recipient survive encode decode":
|
|
|
|
let tx = tx8(12)
|
|
|
|
let bytes = rlp.encode(tx)
|
2024-05-13 08:19:00 +00:00
|
|
|
let zz = rlp.decode(bytes, PooledTransaction)
|
|
|
|
check zz.tx.to.isSome
|
2023-01-20 04:34:31 +00:00
|
|
|
|
|
|
|
test "Tx List 0,1,2,3,4,5,6,7,8":
|
|
|
|
let txs = @[tx0(3), tx1(3), tx2(3), tx3(3), tx4(3),
|
|
|
|
tx5(3), tx6(3), tx7(3), tx8(3)]
|
|
|
|
|
|
|
|
let bytes = rlp.encode(txs)
|
2024-05-13 08:19:00 +00:00
|
|
|
let zz = rlp.decode(bytes, seq[PooledTransaction])
|
2023-01-20 04:34:31 +00:00
|
|
|
let bytes2 = rlp.encode(zz)
|
|
|
|
check bytes2 == bytes
|
|
|
|
|
|
|
|
test "Tx List 8,7,6,5,4,3,2,1,0":
|
|
|
|
let txs = @[tx8(3), tx7(3) , tx6(3), tx5(3), tx4(3),
|
|
|
|
tx3(3), tx2(3), tx1(3), tx0(3)]
|
|
|
|
|
|
|
|
let bytes = rlp.encode(txs)
|
2024-05-13 08:19:00 +00:00
|
|
|
let zz = rlp.decode(bytes, seq[PooledTransaction])
|
2023-01-20 04:34:31 +00:00
|
|
|
let bytes2 = rlp.encode(zz)
|
|
|
|
check bytes2 == bytes
|
|
|
|
|
|
|
|
test "Tx List 0,5,8,7,6,4,3,2,1":
|
|
|
|
let txs = @[tx0(3), tx5(3), tx8(3), tx7(3), tx6(3),
|
|
|
|
tx4(3), tx3(3), tx2(3), tx1(3)]
|
|
|
|
|
|
|
|
let bytes = rlp.encode(txs)
|
2024-05-13 08:19:00 +00:00
|
|
|
let zz = rlp.decode(bytes, seq[PooledTransaction])
|
2023-01-20 04:34:31 +00:00
|
|
|
let bytes2 = rlp.encode(zz)
|
|
|
|
check bytes2 == bytes
|
|
|
|
|
|
|
|
test "Receipts":
|
|
|
|
let rec = Receipt(
|
|
|
|
receiptType: Eip4844Receipt,
|
|
|
|
isHash: false,
|
|
|
|
status: false,
|
|
|
|
cumulativeGasUsed: 100.GasInt)
|
|
|
|
|
|
|
|
let bytes = rlp.encode(rec)
|
|
|
|
let zz = rlp.decode(bytes, Receipt)
|
|
|
|
let bytes2 = rlp.encode(zz)
|
|
|
|
check bytes2 == bytes
|