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,6 +96,12 @@ type
|
|||
status*: TransactionStatus
|
||||
data*: Blob
|
||||
|
||||
Withdrawal* = object # EIP-4895
|
||||
index* : uint64
|
||||
validatorIndex*: uint64
|
||||
address* : EthAddress
|
||||
amount* : UInt256
|
||||
|
||||
BlockHeader* = object
|
||||
parentHash*: Hash256
|
||||
ommersHash*: Hash256
|
||||
|
@ -114,6 +120,7 @@ type
|
|||
nonce*: BlockNonce
|
||||
# `baseFee` is the get/set of `fee`
|
||||
fee*: Option[UInt256] # EIP-1559
|
||||
withdrawalsRoot*: Option[Hash256] # EIP-4895
|
||||
|
||||
BlockBody* = object
|
||||
transactions*: seq[Transaction]
|
||||
|
|
|
@ -113,6 +113,13 @@ proc append*(w: var RlpWriter, tx: Transaction) =
|
|||
of TxEip1559:
|
||||
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)=
|
||||
val = rlp.read(type val)
|
||||
|
||||
|
@ -308,28 +315,36 @@ proc append*(rlpWriter: var RlpWriter, t: Time) {.inline.} =
|
|||
rlpWriter.append(t.toUnix())
|
||||
|
||||
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):
|
||||
when k != "fee":
|
||||
when k notin ["fee", "withdrawalsRoot"]:
|
||||
w.append(v)
|
||||
if h.fee.isSome:
|
||||
w.append(h.fee.get())
|
||||
if h.withdrawalsRoot.isSome:
|
||||
w.append(h.withdrawalsRoot.get())
|
||||
|
||||
proc read*(rlp: var Rlp, T: type BlockHeader): T =
|
||||
let len = rlp.listLen
|
||||
|
||||
if len notin {15, 16}:
|
||||
if len notin {15, 16, 17}:
|
||||
raise newException(UnsupportedRlpError,
|
||||
"BlockHeader elems should be 15 or 16 got " & $len)
|
||||
"BlockHeader elems should be 15, 16, or 17 got " & $len)
|
||||
|
||||
rlp.tryEnterList()
|
||||
for k, v in fieldPairs(result):
|
||||
when k != "fee":
|
||||
when k notin ["fee", "withdrawalsRoot"]:
|
||||
v = rlp.read(type v)
|
||||
|
||||
if len == 16:
|
||||
if len >= 16:
|
||||
# EIP-1559
|
||||
result.baseFee = rlp.read(UInt256)
|
||||
if len >= 17:
|
||||
# EIP-4895
|
||||
result.withdrawalsRoot = some rlp.read(Hash256)
|
||||
|
||||
proc rlpHash*[T](v: T): Hash256 =
|
||||
keccakHash(rlp.encode(v))
|
||||
|
|
|
@ -79,6 +79,19 @@ proc suite1() =
|
|||
check aa == a
|
||||
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() =
|
||||
suite "eip 2718 transaction":
|
||||
for i in 0..<10:
|
||||
|
|
Loading…
Reference in New Issue