mirror of
https://github.com/status-im/nim-eth.git
synced 2025-01-27 23:06:44 +00:00
define Electra types and RLP encoding (#711)
Add types for EIP-6110, EIP-7002 and EIP-7251 validator operations.
This commit is contained in:
parent
b90483e9d2
commit
d8fda55c79
@ -23,6 +23,11 @@ export
|
||||
eth_hash,
|
||||
eth_times
|
||||
|
||||
const
|
||||
DEPOSIT_REQUEST_TYPE* = 0x00'u8 # EIP-6110
|
||||
WITHDRAWAL_REQUEST_TYPE* = 0x01'u8 # EIP-7002
|
||||
CONSOLIDATION_REQUEST_TYPE* = 0x02'u8 # EIP-7251
|
||||
|
||||
type
|
||||
Hash256* = MDigest[256]
|
||||
VMWord* = UInt256
|
||||
@ -124,6 +129,23 @@ type
|
||||
address* : EthAddress
|
||||
amount* : uint64
|
||||
|
||||
DepositRequest* = object # EIP-6110
|
||||
pubkey* : array[48, byte]
|
||||
withdrawalCredentials*: array[32, byte]
|
||||
amount* : uint64
|
||||
signature* : array[96, byte]
|
||||
index* : uint64
|
||||
|
||||
WithdrawalRequest* = object # EIP-7002
|
||||
sourceAddress* : array[20, byte]
|
||||
validatorPubkey*: array[48, byte]
|
||||
amount* : uint64
|
||||
|
||||
ConsolidationRequest* = object # EIP-7251
|
||||
sourceAddress*: array[20, byte]
|
||||
sourcePubkey* : array[48, byte]
|
||||
targetPubkey* : array[48, byte]
|
||||
|
||||
# https://eips.ethereum.org/EIPS/eip-4844#header-extension
|
||||
BlockHeader* = object
|
||||
parentHash*: Hash256
|
||||
@ -146,6 +168,7 @@ type
|
||||
blobGasUsed*: Opt[uint64] # EIP-4844
|
||||
excessBlobGas*: Opt[uint64] # EIP-4844
|
||||
parentBeaconBlockRoot*: Opt[Hash256] # EIP-4788
|
||||
requestsRoot*: Opt[Hash256] # EIP-7685
|
||||
|
||||
BlockBody* = object
|
||||
transactions*: seq[Transaction]
|
||||
|
@ -527,6 +527,85 @@ proc read*(rlp: var Rlp, T: type HashOrNum): T =
|
||||
proc append*(rlpWriter: var RlpWriter, t: EthTime) {.inline.} =
|
||||
rlpWriter.append(t.uint64)
|
||||
|
||||
proc append*(rlpWriter: var RlpWriter, request: DepositRequest) =
|
||||
rlpWriter.appendRawBytes([DEPOSIT_REQUEST_TYPE])
|
||||
rlpWriter.startList(5)
|
||||
rlpWriter.append(request.pubkey)
|
||||
rlpWriter.append(request.withdrawalCredentials)
|
||||
rlpWriter.append(request.amount)
|
||||
rlpWriter.append(request.signature)
|
||||
rlpWriter.append(request.index)
|
||||
|
||||
proc read*(rlp: var Rlp, T: type DepositRequest): T =
|
||||
if not rlp.hasData:
|
||||
raise (ref MalformedRlpError)(msg:
|
||||
"DEPOSIT_REQUEST_TYPE expected but source RLP is empty")
|
||||
let reqType = rlp.readRawByte()
|
||||
if reqType != DEPOSIT_REQUEST_TYPE:
|
||||
raise (ref UnsupportedRlpError)(msg:
|
||||
"Unexpected DEPOSIT_REQUEST_TYPE: " & $reqType)
|
||||
|
||||
var res: DepositRequest
|
||||
rlp.tryEnterList()
|
||||
rlp.read(res.pubkey)
|
||||
rlp.read(res.withdrawalCredentials)
|
||||
rlp.read(res.amount)
|
||||
rlp.read(res.signature)
|
||||
rlp.read(res.index)
|
||||
if rlp.hasData:
|
||||
raise (ref MalformedRlpError)(msg: "Extra data after DepositRequest")
|
||||
res
|
||||
|
||||
proc append*(rlpWriter: var RlpWriter, request: WithdrawalRequest) =
|
||||
rlpWriter.appendRawBytes([WITHDRAWAL_REQUEST_TYPE])
|
||||
rlpWriter.startList(3)
|
||||
rlpWriter.append(request.sourceAddress)
|
||||
rlpWriter.append(request.validatorPubkey)
|
||||
rlpWriter.append(request.amount)
|
||||
|
||||
proc read*(rlp: var Rlp, T: type WithdrawalRequest): T =
|
||||
if not rlp.hasData:
|
||||
raise (ref MalformedRlpError)(msg:
|
||||
"WITHDRAWAL_REQUEST_TYPE expected but source RLP is empty")
|
||||
let reqType = rlp.readRawByte()
|
||||
if reqType != WITHDRAWAL_REQUEST_TYPE:
|
||||
raise (ref UnsupportedRlpError)(msg:
|
||||
"Unexpected WITHDRAWAL_REQUEST_TYPE: " & $reqType)
|
||||
|
||||
var res: WithdrawalRequest
|
||||
rlp.tryEnterList()
|
||||
rlp.read(res.sourceAddress)
|
||||
rlp.read(res.validatorPubkey)
|
||||
rlp.read(res.amount)
|
||||
if rlp.hasData:
|
||||
raise (ref MalformedRlpError)(msg: "Extra data after WithdrawalRequest")
|
||||
res
|
||||
|
||||
proc append*(rlpWriter: var RlpWriter, request: ConsolidationRequest) =
|
||||
rlpWriter.appendRawBytes([CONSOLIDATION_REQUEST_TYPE])
|
||||
rlpWriter.startList(3)
|
||||
rlpWriter.append(request.sourceAddress)
|
||||
rlpWriter.append(request.sourcePubkey)
|
||||
rlpWriter.append(request.targetPubkey)
|
||||
|
||||
proc read*(rlp: var Rlp, T: type ConsolidationRequest): T =
|
||||
if not rlp.hasData:
|
||||
raise (ref MalformedRlpError)(msg:
|
||||
"CONSOLIDATION_REQUEST_TYPE expected but source RLP is empty")
|
||||
let reqType = rlp.readRawByte()
|
||||
if reqType != CONSOLIDATION_REQUEST_TYPE:
|
||||
raise (ref UnsupportedRlpError)(msg:
|
||||
"Unexpected CONSOLIDATION_REQUEST_TYPE: " & $reqType)
|
||||
|
||||
var res: ConsolidationRequest
|
||||
rlp.tryEnterList()
|
||||
rlp.read(res.sourceAddress)
|
||||
rlp.read(res.sourcePubkey)
|
||||
rlp.read(res.targetPubkey)
|
||||
if rlp.hasData:
|
||||
raise (ref MalformedRlpError)(msg: "Extra data after ConsolidationRequest")
|
||||
res
|
||||
|
||||
proc rlpHash*[T](v: T): Hash256 =
|
||||
keccakHash(rlp.encode(v))
|
||||
|
||||
|
@ -217,6 +217,14 @@ func getByteValue*(self: Rlp): byte =
|
||||
doAssert self.isSingleByte()
|
||||
self.bytes[self.position]
|
||||
|
||||
func readRawByte*(self: var Rlp): byte =
|
||||
### Read a raw byte that is not RLP encoded
|
||||
### This is sometimes used to communicate union type information
|
||||
doAssert self.hasData
|
||||
let res = self.bytes[self.position]
|
||||
inc self.position
|
||||
res
|
||||
|
||||
func blobLen*(self: Rlp): int =
|
||||
if self.isBlob():
|
||||
self.item().payload.len()
|
||||
|
Loading…
x
Reference in New Issue
Block a user