GasInt, BlockNumber, fields name closer to the spec (#696)

This commit is contained in:
andri lim 2024-06-12 00:13:11 +07:00 committed by GitHub
parent c3f9160fd2
commit 9b6497ed8a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 97 additions and 159 deletions

View File

@ -10,12 +10,18 @@
## from many places
import
std/[options, hashes, strutils],
stew/[byteutils, endians2], stint,
./eth_hash, ./eth_times
std/[hashes, strutils],
stew/[byteutils, endians2],
stint,
results,
./eth_hash,
./eth_times
export
options, stint, eth_hash, eth_times
results,
stint,
eth_hash,
eth_times
type
Hash256* = MDigest[256]
@ -28,7 +34,7 @@ type
EthAddress* = array[20, byte]
DifficultyInt* = UInt256
GasInt* = int64
GasInt* = uint64
## Type alias used for gas computation
# For reference - https://github.com/status-im/nimbus/issues/35#issuecomment-391726518
@ -38,7 +44,7 @@ type
ForkID* = tuple[crc: uint32, nextFork: uint64]
# EIP 2364/2124
BlockNumber* = UInt256
BlockNumber* = uint64
StorageKey* = array[32, byte]
# beware that although in some cases
@ -85,16 +91,16 @@ type
chainId* : ChainId # EIP-2930
nonce* : AccountNonce
gasPrice* : GasInt
maxPriorityFee*: GasInt # EIP-1559
maxFee* : GasInt # EIP-1559
maxPriorityFeePerGas*: GasInt # EIP-1559
maxFeePerGas* : GasInt # EIP-1559
gasLimit* : GasInt
to* : Option[EthAddress]
to* : Opt[EthAddress]
value* : UInt256
payload* : Blob
accessList* : AccessList # EIP-2930
maxFeePerBlobGas*: UInt256 # EIP-4844
versionedHashes*: VersionedHashes # EIP-4844
V* : int64
V* : uint64
R*, S* : UInt256
PooledTransaction* = object
@ -125,27 +131,26 @@ type
coinbase*: EthAddress
stateRoot*: Hash256
txRoot*: Hash256
receiptRoot*: Hash256
bloom*: BloomFilter
receiptsRoot*: Hash256
logsBloom*: BloomFilter
difficulty*: DifficultyInt
blockNumber*: BlockNumber
number*: BlockNumber
gasLimit*: GasInt
gasUsed*: GasInt
timestamp*: EthTime
extraData*: Blob
mixDigest*: Hash256
mixHash*: Hash256
nonce*: BlockNonce
# `baseFee` is the get/set of `fee`
fee*: Option[UInt256] # EIP-1559
withdrawalsRoot*: Option[Hash256] # EIP-4895
blobGasUsed*: Option[uint64] # EIP-4844
excessBlobGas*: Option[uint64] # EIP-4844
parentBeaconBlockRoot*: Option[Hash256] # EIP-4788
baseFeePerGas*: Opt[UInt256] # EIP-1559
withdrawalsRoot*: Opt[Hash256] # EIP-4895
blobGasUsed*: Opt[uint64] # EIP-4844
excessBlobGas*: Opt[uint64] # EIP-4844
parentBeaconBlockRoot*: Opt[Hash256] # EIP-4788
BlockBody* = object
transactions*: seq[Transaction]
uncles*: seq[BlockHeader]
withdrawals*: Option[seq[Withdrawal]] # EIP-4895
withdrawals*: Opt[seq[Withdrawal]] # EIP-4895
Log* = object
address*: EthAddress
@ -166,14 +171,14 @@ type
status* : bool # EIP-658
hash* : Hash256
cumulativeGasUsed*: GasInt
bloom* : BloomFilter
logsBloom* : BloomFilter
logs* : seq[Log]
EthBlock* = object
header* : BlockHeader
transactions*: seq[Transaction]
uncles* : seq[BlockHeader]
withdrawals*: Option[seq[Withdrawal]] # EIP-4895
withdrawals*: Opt[seq[Withdrawal]] # EIP-4895
BlobsBundle* = object
commitments*: seq[KzgCommitment]
@ -213,56 +218,12 @@ template txs*(blk: EthBlock): seq[Transaction] =
# Legacy name emulation
blk.transactions
when BlockNumber is int64:
## The goal of these templates is to make it easier to switch
## the block number type to a different representation
template vmWordToBlockNumber*(word: VMWord): BlockNumber =
BlockNumber(word.toInt)
template blockNumberToVmWord*(n: BlockNumber): VMWord =
u256(n)
template toBlockNumber*(n: SomeInteger): BlockNumber =
int64(n)
template toBlockNumber*(n: UInt256): BlockNumber =
n.toInt
template toInt*(n: BlockNumber): int =
int(n)
else:
template vmWordToBlockNumber*(word: VMWord): BlockNumber =
word
template blockNumberToVmWord*(n: BlockNumber): VMWord =
n
template toBlockNumber*(n: SomeInteger): BlockNumber =
u256(n)
template toBlockNumber*(n: UInt256): BlockNumber =
n
template u256*(n: BlockNumber): UInt256 =
n
# EIP-1559 conveniences
func baseFee*(h: BlockHeader): UInt256 =
if h.fee.isSome:
h.fee.get()
else:
0.u256
template `baseFee=`*(h: BlockHeader, data: UInt256) =
h.fee = some(data)
# starting from EIP-4399, `mixHash`/`mixDigest` field will be alled `prevRandao`
template prevRandao*(h: BlockHeader): Hash256 =
h.mixDigest
h.mixHash
template `prevRandao=`*(h: BlockHeader, hash: Hash256) =
h.mixDigest = hash
h.mixHash = hash
func toBlockNonce*(n: uint64): BlockNonce =
n.toBytesBE()
@ -316,7 +277,7 @@ func `$`*(x: BlockHashOrNumber): string =
template hasData*(b: Blob): bool = b.len > 0
template deref*(b: Blob): auto = b
template deref*(o: Option): auto = o.get
template deref*(o: Opt): auto = o.get
func `==`*(a, b: NetworkId): bool =
a.uint == b.uint

View File

@ -50,7 +50,7 @@ proc append*(rlpWriter: var RlpWriter, value: StUint) =
rlpWriter.append bytes.toOpenArray(bytes.len - nonZeroBytes,
bytes.len - 1)
else:
rlpWriter.append(value.truncate(int))
rlpWriter.append(value.truncate(uint))
proc read*(rlp: var Rlp, T: type StInt): T {.inline.} =
# The Ethereum Yellow Paper defines the RLP serialization only
@ -64,7 +64,7 @@ proc append*(rlpWriter: var RlpWriter, value: StInt) =
{.fatal: "RLP serialization of signed integers is not allowed".}
discard
proc append*[T](w: var RlpWriter, val: Option[T]) =
proc append*[T](w: var RlpWriter, val: Opt[T]) =
if val.isSome:
w.append(val.get())
else:
@ -100,8 +100,8 @@ proc appendTxEip1559(w: var RlpWriter, tx: Transaction) =
w.startList(12)
w.append(tx.chainId.uint64)
w.append(tx.nonce)
w.append(tx.maxPriorityFee)
w.append(tx.maxFee)
w.append(tx.maxPriorityFeePerGas)
w.append(tx.maxFeePerGas)
w.append(tx.gasLimit)
w.append(tx.to)
w.append(tx.value)
@ -115,8 +115,8 @@ proc appendTxEip4844(w: var RlpWriter, tx: Transaction) =
w.startList(14)
w.append(tx.chainId.uint64)
w.append(tx.nonce)
w.append(tx.maxPriorityFee)
w.append(tx.maxFee)
w.append(tx.maxPriorityFeePerGas)
w.append(tx.maxFeePerGas)
w.append(tx.gasLimit)
w.append(tx.to)
w.append(tx.value)
@ -161,9 +161,9 @@ proc append*(w: var RlpWriter, tx: PooledTransaction) =
template read[T](rlp: var Rlp, val: var T) =
val = rlp.read(type val)
proc read[T](rlp: var Rlp, val: var Option[T]) =
proc read[T](rlp: var Rlp, val: var Opt[T]) =
if rlp.blobLen != 0:
val = some(rlp.read(T))
val = Opt.some(rlp.read(T))
else:
rlp.skipElem
@ -200,8 +200,8 @@ proc readTxEip1559(rlp: var Rlp, tx: var Transaction) =
rlp.tryEnterList()
tx.chainId = rlp.read(uint64).ChainId
rlp.read(tx.nonce)
rlp.read(tx.maxPriorityFee)
rlp.read(tx.maxFee)
rlp.read(tx.maxPriorityFeePerGas)
rlp.read(tx.maxFeePerGas)
rlp.read(tx.gasLimit)
rlp.read(tx.to)
rlp.read(tx.value)
@ -216,8 +216,8 @@ proc readTxEip4844(rlp: var Rlp, tx: var Transaction) =
rlp.tryEnterList()
tx.chainId = rlp.read(uint64).ChainId
rlp.read(tx.nonce)
rlp.read(tx.maxPriorityFee)
rlp.read(tx.maxFee)
rlp.read(tx.maxPriorityFeePerGas)
rlp.read(tx.maxFeePerGas)
rlp.read(tx.gasLimit)
rlp.read(tx.to)
rlp.read(tx.value)
@ -378,7 +378,7 @@ proc append*(
proc append*(w: var RlpWriter, rec: Receipt) =
if rec.receiptType in {Eip2930Receipt, Eip1559Receipt, Eip4844Receipt}:
w.append(rec.receiptType.int)
w.append(rec.receiptType.uint)
w.startList(4)
if rec.isHash:
@ -387,7 +387,7 @@ proc append*(w: var RlpWriter, rec: Receipt) =
w.append(rec.status.uint8)
w.append(rec.cumulativeGasUsed)
w.append(rec.bloom)
w.append(rec.logsBloom)
w.append(rec.logs)
proc readReceiptLegacy(rlp: var Rlp, receipt: var Receipt) =
@ -404,7 +404,7 @@ proc readReceiptLegacy(rlp: var Rlp, receipt: var Receipt) =
"HashOrStatus expected, but the source RLP is not a blob of right size.")
rlp.read(receipt.cumulativeGasUsed)
rlp.read(receipt.bloom)
rlp.read(receipt.logsBloom)
rlp.read(receipt.logs)
proc readReceiptTyped(rlp: var Rlp, receipt: var Receipt) =
@ -443,7 +443,7 @@ proc readReceiptTyped(rlp: var Rlp, receipt: var Receipt) =
"HashOrStatus expected, but the source RLP is not a blob of right size.")
rlp.read(receipt.cumulativeGasUsed)
rlp.read(receipt.bloom)
rlp.read(receipt.logsBloom)
rlp.read(receipt.logs)
proc read*(rlp: var Rlp, T: type Receipt): T =

View File

@ -4,31 +4,7 @@ import
export eth_types_rlp
const
EIP155_CHAIN_ID_OFFSET* = 35'i64
type
GasPrice* = ## \
## Handy definition distinct from `GasInt` which is a commodity unit while
## the `GasPrice` is the commodity valuation per unit of gas, similar to a
## kind of currency.
distinct uint64
GasPriceEx* = ## \
## Similar to `GasPrice` but is allowed to be negative.
distinct int64
proc effectiveGasTip*(tx: Transaction; baseFee: GasPrice): GasPriceEx =
## The effective miner gas tip for the globally argument `baseFee`. The
## result (which is a price per gas) might well be negative.
if tx.txType != TxEip1559:
(tx.gasPrice - baseFee.int64).GasPriceEx
else:
# London, EIP1559
min(tx.maxPriorityFee, tx.maxFee - baseFee.int64).GasPriceEx
proc effectiveGasTip*(tx: Transaction; baseFee: UInt256): GasPriceEx =
## Variant of `effectiveGasTip()`
tx.effectiveGasTip(baseFee.truncate(uint64).GasPrice)
EIP155_CHAIN_ID_OFFSET* = 35'u64
func rlpEncodeLegacy(tx: Transaction): auto =
var w = initRlpWriter()
@ -52,8 +28,8 @@ func rlpEncodeEip155(tx: Transaction): auto =
w.append(tx.value)
w.append(tx.payload)
w.append(chainId)
w.append(0)
w.append(0)
w.append(0'u8)
w.append(0'u8)
w.finish()
func rlpEncodeEip2930(tx: Transaction): auto =
@ -76,8 +52,8 @@ func rlpEncodeEip1559(tx: Transaction): auto =
w.startList(9)
w.append(tx.chainId.uint64)
w.append(tx.nonce)
w.append(tx.maxPriorityFee)
w.append(tx.maxFee)
w.append(tx.maxPriorityFeePerGas)
w.append(tx.maxFeePerGas)
w.append(tx.gasLimit)
w.append(tx.to)
w.append(tx.value)
@ -91,8 +67,8 @@ func rlpEncodeEip4844(tx: Transaction): auto =
w.startList(11)
w.append(tx.chainId.uint64)
w.append(tx.nonce)
w.append(tx.maxPriorityFee)
w.append(tx.maxFee)
w.append(tx.maxPriorityFeePerGas)
w.append(tx.maxFeePerGas)
w.append(tx.gasLimit)
w.append(tx.to)
w.append(tx.value)

View File

@ -110,17 +110,17 @@ proc suite2() =
doTest h
# EIP-1559
h.fee = some 1234.u256
h.baseFeePerGas = Opt.some 1234.u256
doTest h
# EIP-4895
h.withdrawalsRoot = some Hash256.fromHex(
h.withdrawalsRoot = Opt.some Hash256.fromHex(
"0x7a64245f7f95164f6176d90bd4903dbdd3e5433d555dd1385e81787f9672c588")
doTest h
# EIP-4844
h.blobGasUsed = some 1234'u64
h.excessBlobGas = some 1234'u64
h.blobGasUsed = Opt.some 1234'u64
h.excessBlobGas = Opt.some 1234'u64
doTest h
test "Receipts EIP-2718 + EIP-2976 encoding":

View File

@ -31,7 +31,7 @@ proc tx0(i: int): PooledTransaction =
tx: Transaction(
txType: TxLegacy,
nonce: i.AccountNonce,
to: recipient.some,
to: Opt.some recipient,
gasLimit: 1.GasInt,
gasPrice: 2.GasInt,
payload: abcdef))
@ -53,7 +53,7 @@ proc tx2(i: int): PooledTransaction =
txType: TxEip2930,
chainId: 1.ChainId,
nonce: i.AccountNonce,
to: recipient.some,
to: Opt.some recipient,
gasLimit: 123457.GasInt,
gasPrice: 10.GasInt,
accessList: accesses,
@ -66,7 +66,7 @@ proc tx3(i: int): PooledTransaction =
txType: TxEip2930,
chainId: 1.ChainId,
nonce: i.AccountNonce,
to: recipient.some,
to: Opt.some recipient,
gasLimit: 123457.GasInt,
gasPrice: 10.GasInt,
payload: abcdef))
@ -89,8 +89,8 @@ proc tx5(i: int): PooledTransaction =
chainId: 1.ChainId,
nonce: i.AccountNonce,
gasLimit: 123457.GasInt,
maxPriorityFee: 42.GasInt,
maxFee: 10.GasInt,
maxPriorityFeePerGas: 42.GasInt,
maxFeePerGas: 10.GasInt,
accessList: accesses))
proc tx6(i: int): PooledTransaction =
@ -103,8 +103,8 @@ proc tx6(i: int): PooledTransaction =
chainId: 1.ChainId,
nonce: i.AccountNonce,
gasLimit: 123457.GasInt,
maxPriorityFee: 42.GasInt,
maxFee: 10.GasInt,
maxPriorityFeePerGas:42.GasInt,
maxFeePerGas: 10.GasInt,
accessList: accesses,
versionedHashes: @[digest]),
networkPayload: NetworkPayload(
@ -122,8 +122,8 @@ proc tx7(i: int): PooledTransaction =
chainID: 1.ChainId,
nonce: i.AccountNonce,
gasLimit: 123457.GasInt,
maxPriorityFee: 42.GasInt,
maxFee: 10.GasInt,
maxPriorityFeePerGas:42.GasInt,
maxFeePerGas: 10.GasInt,
accessList: accesses,
versionedHashes: @[digest],
maxFeePerBlobGas: 10000000.u256))
@ -137,10 +137,10 @@ proc tx8(i: int): PooledTransaction =
txType: TxEip4844,
chainID: 1.ChainId,
nonce: i.AccountNonce,
to: some(recipient),
to: Opt.some(recipient),
gasLimit: 123457.GasInt,
maxPriorityFee: 42.GasInt,
maxFee: 10.GasInt,
maxPriorityFeePerGas:42.GasInt,
maxFeePerGas: 10.GasInt,
accessList: accesses,
versionedHashes: @[digest],
maxFeePerBlobGas: 10000000.u256))

View File

@ -65,11 +65,11 @@ suite "BlockHashOrNumber":
test "EIP-4788 parentBeaconBlockRoot field":
let header = BlockHeader(
fee: some(0.u256),
withdrawalsRoot: some(testHash),
blobGasUsed: some(1'u64),
excessBlobGas: some(2'u64),
parentBeaconBlockRoot: some(testHash),
baseFeePerGas: Opt.some(0.u256),
withdrawalsRoot: Opt.some(testHash),
blobGasUsed: Opt.some(1'u64),
excessBlobGas: Opt.some(2'u64),
parentBeaconBlockRoot: Opt.some(testHash),
)
let rlpBytes = rlp.encode(header)
let dh = rlp.decode(rlpBytes, BlockHeader)

View File

@ -12,7 +12,8 @@
import
std/[os, strutils],
stew/[io2, results],
stew/io2,
results,
unittest2,
../../eth/[rlp, common]
@ -63,20 +64,20 @@ suite "BlockHeader roundtrip test":
roundTrip(h)
test "Header + some(baseFee)":
let h = BlockHeader(fee: some(1.u256))
let h = BlockHeader(baseFeePerGas: Opt.some(1.u256))
roundTrip(h)
test "Header + none(baseFee) + some(withdrawalsRoot)":
let h = BlockHeader(withdrawalsRoot: some(Hash256()))
let h = BlockHeader(withdrawalsRoot: Opt.some(Hash256()))
expect AssertionDefect:
roundTrip(h)
test "Header + none(baseFee) + some(withdrawalsRoot) + " &
"some(blobGasUsed) + some(excessBlobGas)":
let h = BlockHeader(
withdrawalsRoot: some(Hash256()),
blobGasUsed: some(1'u64),
excessBlobGas: some(1'u64)
withdrawalsRoot: Opt.some(Hash256()),
blobGasUsed: Opt.some(1'u64),
excessBlobGas: Opt.some(1'u64)
)
expect AssertionDefect:
roundTrip(h)
@ -84,8 +85,8 @@ suite "BlockHeader roundtrip test":
test "Header + none(baseFee) + none(withdrawalsRoot) + " &
"some(blobGasUsed) + some(excessBlobGas)":
let h = BlockHeader(
blobGasUsed: some(1'u64),
excessBlobGas: some(1'u64)
blobGasUsed: Opt.some(1'u64),
excessBlobGas: Opt.some(1'u64)
)
expect AssertionDefect:
roundTrip(h)
@ -93,27 +94,27 @@ suite "BlockHeader roundtrip test":
test "Header + some(baseFee) + none(withdrawalsRoot) + " &
"some(blobGasUsed) + some(excessBlobGas)":
let h = BlockHeader(
fee: some(2.u256),
blobGasUsed: some(1'u64),
excessBlobGas: some(1'u64)
baseFeePerGas: Opt.some(2.u256),
blobGasUsed: Opt.some(1'u64),
excessBlobGas: Opt.some(1'u64)
)
expect AssertionDefect:
roundTrip(h)
test "Header + some(baseFee) + some(withdrawalsRoot)":
let h = BlockHeader(
fee: some(2.u256),
withdrawalsRoot: some(Hash256())
baseFeePerGas: Opt.some(2.u256),
withdrawalsRoot: Opt.some(Hash256())
)
roundTrip(h)
test "Header + some(baseFee) + some(withdrawalsRoot) + " &
"some(blobGasUsed) + some(excessBlobGas)":
let h = BlockHeader(
fee: some(2.u256),
withdrawalsRoot: some(Hash256()),
blobGasUsed: some(1'u64),
excessBlobGas: some(1'u64)
baseFeePerGas: Opt.some(2.u256),
withdrawalsRoot: Opt.some(Hash256()),
blobGasUsed: Opt.some(1'u64),
excessBlobGas: Opt.some(1'u64)
)
roundTrip(h)
@ -140,7 +141,7 @@ template genTest(TT) =
roundTrip(blk)
test TTS & " with withdrawals":
let blk = TT(withdrawals: some(@[Withdrawal()]))
let blk = TT(withdrawals: Opt.some(@[Withdrawal()]))
roundTrip(blk)
test "2 " & TTS & " none(Withdrawal)+none(Withdrawal)":
@ -151,20 +152,20 @@ template genTest(TT) =
test "2 " & TTS & " none(Withdrawal)+some(Withdrawal)":
let blk1 = TT()
let blk2 = TT(withdrawals: some(@[Withdrawal()]))
let blk2 = TT(withdrawals: Opt.some(@[Withdrawal()]))
roundTrip2(blk1, blk2):
check b1.withdrawals.isNone
check b2.withdrawals.isSome
test "2 " & TTS & " some(Withdrawal)+none(Withdrawal)":
let blk1 = TT()
let blk2 = TT(withdrawals: some(@[Withdrawal()]))
let blk2 = TT(withdrawals: Opt.some(@[Withdrawal()]))
roundTrip2(blk2, blk1):
check b1.withdrawals.isSome
check b2.withdrawals.isNone
test "2 " & TTS & " some(Withdrawal)+some(Withdrawal)":
let blk = TT(withdrawals: some(@[Withdrawal()]))
let blk = TT(withdrawals: Opt.some(@[Withdrawal()]))
roundTrip2(blk, blk):
check b1.withdrawals.isSome
check b2.withdrawals.isSome