From d8ed02682df10e27210ce3474f17b8111b311be2 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Thu, 24 Nov 2022 15:55:57 +0100 Subject: [PATCH 1/5] extend `BlockHeader` for Capella 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). --- eth/common/eth_types.nim | 39 +++++++++++++++++++++--------------- eth/common/eth_types_rlp.nim | 7 +++++++ 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/eth/common/eth_types.nim b/eth/common/eth_types.nim index f081ed90..b8461762 100644 --- a/eth/common/eth_types.nim +++ b/eth/common/eth_types.nim @@ -96,24 +96,31 @@ type status*: TransactionStatus data*: Blob + Withdrawal* = object # EIP-4895 + index* : uint64 + validatorIndex*: uint64 + address* : EthAddress + amount* : UInt256 + BlockHeader* = object - parentHash*: Hash256 - ommersHash*: Hash256 - coinbase*: EthAddress - stateRoot*: Hash256 - txRoot*: Hash256 - receiptRoot*: Hash256 - bloom*: BloomFilter - difficulty*: DifficultyInt - blockNumber*: BlockNumber - gasLimit*: GasInt - gasUsed*: GasInt - timestamp*: EthTime - extraData*: Blob - mixDigest*: Hash256 - nonce*: BlockNonce + parentHash*: Hash256 + ommersHash*: Hash256 + coinbase*: EthAddress + stateRoot*: Hash256 + txRoot*: Hash256 + receiptRoot*: Hash256 + bloom*: BloomFilter + difficulty*: DifficultyInt + blockNumber*: BlockNumber + gasLimit*: GasInt + gasUsed*: GasInt + timestamp*: EthTime + extraData*: Blob + mixDigest*: Hash256 + nonce*: BlockNonce # `baseFee` is the get/set of `fee` - fee*: Option[UInt256] # EIP-1559 + fee*: Option[UInt256] # EIP-1559 + withdrawalsRoot*: Option[Hash256] # EIP-4895 BlockBody* = object transactions*: seq[Transaction] diff --git a/eth/common/eth_types_rlp.nim b/eth/common/eth_types_rlp.nim index 10a5df43..1627b0e1 100644 --- a/eth/common/eth_types_rlp.nim +++ b/eth/common/eth_types_rlp.nim @@ -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) From f218f5a12eb36d82f438546f67eea723508c90bb Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Thu, 24 Nov 2022 16:42:50 +0100 Subject: [PATCH 2/5] add RLP reading support and roundtrip test --- eth/common/eth_types_rlp.nim | 15 ++++++++++----- tests/rlp/test_common.nim | 13 +++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/eth/common/eth_types_rlp.nim b/eth/common/eth_types_rlp.nim index 1627b0e1..1253c503 100644 --- a/eth/common/eth_types_rlp.nim +++ b/eth/common/eth_types_rlp.nim @@ -317,26 +317,31 @@ proc append*(rlpWriter: var RlpWriter, t: Time) {.inline.} = proc append*(w: var RlpWriter, h: BlockHeader) = w.startList(if h.fee.isSome: 16 else: 15) 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)) diff --git a/tests/rlp/test_common.nim b/tests/rlp/test_common.nim index 3d20c8ee..44ebfa4d 100644 --- a/tests/rlp/test_common.nim +++ b/tests/rlp/test_common.nim @@ -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: From 8118fa5c59a0a9346bd491d2b60fc9a9cdd6177f Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Thu, 24 Nov 2022 16:52:39 +0100 Subject: [PATCH 3/5] extend `RLP fields count` test --- tests/rlp/test_object_serialization.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/rlp/test_object_serialization.nim b/tests/rlp/test_object_serialization.nim index b1773998..e7c2c3b2 100644 --- a/tests/rlp/test_object_serialization.nim +++ b/tests/rlp/test_object_serialization.nim @@ -84,5 +84,6 @@ proc suite() = Bar.rlpFieldsCount == 2 Foo.rlpFieldsCount == 3 Transaction.rlpFieldsCount == 3 + Withdrawal.rlpFieldsCount == 4 suite() From 96abb97706ac4a7a67365ef7f83323a86f2d882c Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Thu, 24 Nov 2022 19:03:39 +0100 Subject: [PATCH 4/5] Revert "extend `RLP fields count` test" This reverts commit 8118fa5c59a0a9346bd491d2b60fc9a9cdd6177f. --- tests/rlp/test_object_serialization.nim | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/rlp/test_object_serialization.nim b/tests/rlp/test_object_serialization.nim index e7c2c3b2..b1773998 100644 --- a/tests/rlp/test_object_serialization.nim +++ b/tests/rlp/test_object_serialization.nim @@ -84,6 +84,5 @@ proc suite() = Bar.rlpFieldsCount == 2 Foo.rlpFieldsCount == 3 Transaction.rlpFieldsCount == 3 - Withdrawal.rlpFieldsCount == 4 suite() From f7db4a5257aab5e267df861d9fc8dccaf3bf49b5 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Thu, 24 Nov 2022 20:11:44 +0100 Subject: [PATCH 5/5] use correct list length --- eth/common/eth_types_rlp.nim | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/eth/common/eth_types_rlp.nim b/eth/common/eth_types_rlp.nim index 1253c503..b6cb4aad 100644 --- a/eth/common/eth_types_rlp.nim +++ b/eth/common/eth_types_rlp.nim @@ -315,7 +315,10 @@ 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 notin ["fee", "withdrawalsRoot"]: w.append(v)