mirror of https://github.com/status-im/nim-eth.git
extend `BlockHeader` for Capella (#562)
Adds `Withdrawal` type according to EIP-4895, and extends `BlockHeader` accordingly. Also adds RLP encoding support for `Withdrawal` to enable building `BlockHeader` (used by Nimbus-CL in empty block prod fallback).
This commit is contained in:
parent
f4ef9181c7
commit
6499ee2bc5
|
@ -96,24 +96,31 @@ type
|
||||||
status*: TransactionStatus
|
status*: TransactionStatus
|
||||||
data*: Blob
|
data*: Blob
|
||||||
|
|
||||||
|
Withdrawal* = object # EIP-4895
|
||||||
|
index* : uint64
|
||||||
|
validatorIndex*: uint64
|
||||||
|
address* : EthAddress
|
||||||
|
amount* : UInt256
|
||||||
|
|
||||||
BlockHeader* = object
|
BlockHeader* = object
|
||||||
parentHash*: Hash256
|
parentHash*: Hash256
|
||||||
ommersHash*: Hash256
|
ommersHash*: Hash256
|
||||||
coinbase*: EthAddress
|
coinbase*: EthAddress
|
||||||
stateRoot*: Hash256
|
stateRoot*: Hash256
|
||||||
txRoot*: Hash256
|
txRoot*: Hash256
|
||||||
receiptRoot*: Hash256
|
receiptRoot*: Hash256
|
||||||
bloom*: BloomFilter
|
bloom*: BloomFilter
|
||||||
difficulty*: DifficultyInt
|
difficulty*: DifficultyInt
|
||||||
blockNumber*: BlockNumber
|
blockNumber*: BlockNumber
|
||||||
gasLimit*: GasInt
|
gasLimit*: GasInt
|
||||||
gasUsed*: GasInt
|
gasUsed*: GasInt
|
||||||
timestamp*: EthTime
|
timestamp*: EthTime
|
||||||
extraData*: Blob
|
extraData*: Blob
|
||||||
mixDigest*: Hash256
|
mixDigest*: Hash256
|
||||||
nonce*: BlockNonce
|
nonce*: BlockNonce
|
||||||
# `baseFee` is the get/set of `fee`
|
# `baseFee` is the get/set of `fee`
|
||||||
fee*: Option[UInt256] # EIP-1559
|
fee*: Option[UInt256] # EIP-1559
|
||||||
|
withdrawalsRoot*: Option[Hash256] # EIP-4895
|
||||||
|
|
||||||
BlockBody* = object
|
BlockBody* = object
|
||||||
transactions*: seq[Transaction]
|
transactions*: seq[Transaction]
|
||||||
|
|
|
@ -113,6 +113,13 @@ proc append*(w: var RlpWriter, tx: Transaction) =
|
||||||
of TxEip1559:
|
of TxEip1559:
|
||||||
w.appendTxEip1559(tx)
|
w.appendTxEip1559(tx)
|
||||||
|
|
||||||
|
proc append*(w: var RlpWriter, withdrawal: Withdrawal) =
|
||||||
|
w.startList(4)
|
||||||
|
w.append(withdrawal.index)
|
||||||
|
w.append(withdrawal.validatorIndex)
|
||||||
|
w.append(withdrawal.address)
|
||||||
|
w.append(withdrawal.amount)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
|
@ -308,28 +315,36 @@ proc append*(rlpWriter: var RlpWriter, t: Time) {.inline.} =
|
||||||
rlpWriter.append(t.toUnix())
|
rlpWriter.append(t.toUnix())
|
||||||
|
|
||||||
proc append*(w: var RlpWriter, h: BlockHeader) =
|
proc append*(w: var RlpWriter, h: BlockHeader) =
|
||||||
w.startList(if h.fee.isSome: 16 else: 15)
|
var len = 15
|
||||||
|
if h.fee.isSome: inc len
|
||||||
|
if h.withdrawalsRoot.isSome: inc len
|
||||||
|
w.startList(len)
|
||||||
for k, v in fieldPairs(h):
|
for k, v in fieldPairs(h):
|
||||||
when k != "fee":
|
when k notin ["fee", "withdrawalsRoot"]:
|
||||||
w.append(v)
|
w.append(v)
|
||||||
if h.fee.isSome:
|
if h.fee.isSome:
|
||||||
w.append(h.fee.get())
|
w.append(h.fee.get())
|
||||||
|
if h.withdrawalsRoot.isSome:
|
||||||
|
w.append(h.withdrawalsRoot.get())
|
||||||
|
|
||||||
proc read*(rlp: var Rlp, T: type BlockHeader): T =
|
proc read*(rlp: var Rlp, T: type BlockHeader): T =
|
||||||
let len = rlp.listLen
|
let len = rlp.listLen
|
||||||
|
|
||||||
if len notin {15, 16}:
|
if len notin {15, 16, 17}:
|
||||||
raise newException(UnsupportedRlpError,
|
raise newException(UnsupportedRlpError,
|
||||||
"BlockHeader elems should be 15 or 16 got " & $len)
|
"BlockHeader elems should be 15, 16, or 17 got " & $len)
|
||||||
|
|
||||||
rlp.tryEnterList()
|
rlp.tryEnterList()
|
||||||
for k, v in fieldPairs(result):
|
for k, v in fieldPairs(result):
|
||||||
when k != "fee":
|
when k notin ["fee", "withdrawalsRoot"]:
|
||||||
v = rlp.read(type v)
|
v = rlp.read(type v)
|
||||||
|
|
||||||
if len == 16:
|
if len >= 16:
|
||||||
# EIP-1559
|
# EIP-1559
|
||||||
result.baseFee = rlp.read(UInt256)
|
result.baseFee = rlp.read(UInt256)
|
||||||
|
if len >= 17:
|
||||||
|
# EIP-4895
|
||||||
|
result.withdrawalsRoot = some rlp.read(Hash256)
|
||||||
|
|
||||||
proc rlpHash*[T](v: T): Hash256 =
|
proc rlpHash*[T](v: T): Hash256 =
|
||||||
keccakHash(rlp.encode(v))
|
keccakHash(rlp.encode(v))
|
||||||
|
|
|
@ -79,6 +79,19 @@ proc suite1() =
|
||||||
check aa == a
|
check aa == a
|
||||||
check bb == b
|
check bb == b
|
||||||
|
|
||||||
|
test "EIP 4895 roundtrip":
|
||||||
|
let a = Withdrawal(
|
||||||
|
index: 1,
|
||||||
|
validatorIndex: 2,
|
||||||
|
address: EthAddress [
|
||||||
|
0.byte, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
|
||||||
|
11, 12, 13, 14, 15, 16, 17, 18, 19],
|
||||||
|
amount: 4.u256 * 1_000_000_000.u256)
|
||||||
|
|
||||||
|
let abytes = rlp.encode(a)
|
||||||
|
let aa = rlp.decode(abytes, Withdrawal)
|
||||||
|
check aa == a
|
||||||
|
|
||||||
proc suite2() =
|
proc suite2() =
|
||||||
suite "eip 2718 transaction":
|
suite "eip 2718 transaction":
|
||||||
for i in 0..<10:
|
for i in 0..<10:
|
||||||
|
|
Loading…
Reference in New Issue