Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new Pectra engine API #168

Merged
merged 1 commit into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 0 additions & 66 deletions tests/test_execution_types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -64,25 +64,6 @@ suite "Execution types tests":
shouldOverrideBuilder: Opt.some(false),
)

deposit = DepositRequestV1(
pubkey: FixedBytes[48].conv(1),
withdrawalCredentials: FixedBytes[32].conv(3),
amount: 5.Quantity,
signature: FixedBytes[96].conv(7),
index: 9.Quantity
)

withdrawal = WithdrawalRequestV1(
sourceAddress: address(7),
validatorPubkey: FixedBytes[48].conv(9)
)

consolidation = ConsolidationRequestV1(
sourceAddress: address(8),
sourcePubkey: FixedBytes[48].conv(10),
targetPubkey: FixedBytes[48].conv(11)
)

test "payload version":
var badv31 = payload
badv31.blobGasUsed = Opt.none(Quantity)
Expand Down Expand Up @@ -170,50 +151,3 @@ suite "Execution types tests":

let v1 = response.V1
check v1 == v1.getPayloadResponse.V1

test "payload version 4":
var v4 = payload
v4.depositRequests = Opt.some(@[deposit])
v4.withdrawalRequests = Opt.some(@[withdrawal])
v4.consolidationRequests = Opt.some(@[consolidation])
check v4.version == Version.V4

var bad41 = v4
bad41.depositRequests = Opt.none(seq[DepositRequestV1])
check bad41.version == Version.V4

var bad42 = v4
bad42.withdrawalRequests = Opt.none(seq[WithdrawalRequestV1])
check bad42.version == Version.V4

var bad43 = v4
bad43.consolidationRequests = Opt.none(seq[ConsolidationRequestV1])
check bad43.version == Version.V4

let v41 = bad41.V4
check v41.depositRequests == newSeq[DepositRequestV1]()
check v41.withdrawalRequests == v4.withdrawalRequests.get
check v41.consolidationRequests == v4.consolidationRequests.get

let v42 = bad42.V4
check v42.depositRequests == v4.depositRequests.get
check v42.withdrawalRequests == newSeq[WithdrawalRequestV1]()
check v41.consolidationRequests == v4.consolidationRequests.get

let v43 = bad43.V4
check v43.depositRequests == v4.depositRequests.get
check v43.withdrawalRequests == v4.withdrawalRequests.get
check v43.consolidationRequests == newSeq[ConsolidationRequestV1]()

# roundtrip
let v4p = v4.V4
check v4p == v4p.executionPayload.V4

# response version 4
var resv4 = response
resv4.executionPayload = v4
check resv4.version == Version.V4

# response roundtrip
let rv3p = resv4.V4
check rv3p == rv3p.getPayloadResponse.V4
4 changes: 2 additions & 2 deletions web3/contract_dsl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ proc genFunction(cname: NimNode, functionObject: FunctionObject): NimNode =
`senderName`.sender, `output`,
static(keccak256(`signature`).data[0..<4]) & encode(`funcParamsTuple`))

proc `&`(a, b: openarray[byte]): seq[byte] =
proc `&`(a, b: openArray[byte]): seq[byte] =
let sza = a.len
let szb = b.len
result.setLen(sza + szb)
Expand All @@ -217,7 +217,7 @@ proc genConstructor(cname: NimNode, constructorObject: ConstructorObject): NimNo
funcParamsTuple.add(ident input.name)

result = quote do:
proc deployContract*[TSender](`sender`: TSender, contractType: typedesc[`cname`], `contractCode`: openarray[byte]): auto =
proc deployContract*[TSender](`sender`: TSender, contractType: typedesc[`cname`], `contractCode`: openArray[byte]): auto =
discard
for input in constructorObject.inputs:
result[3].add nnkIdentDefs.newTree(
Expand Down
6 changes: 1 addition & 5 deletions web3/conversions.nim
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,10 @@ derefType(ReceiptObject).useDefaultSerializationIn JrpcConv
#------------------------------------------------------------------------------

WithdrawalV1.useDefaultSerializationIn JrpcConv
DepositRequestV1.useDefaultSerializationIn JrpcConv
WithdrawalRequestV1.useDefaultSerializationIn JrpcConv
ExecutionPayloadV1.useDefaultSerializationIn JrpcConv
ExecutionPayloadV2.useDefaultSerializationIn JrpcConv
ExecutionPayloadV1OrV2.useDefaultSerializationIn JrpcConv
ExecutionPayloadV3.useDefaultSerializationIn JrpcConv
ExecutionPayloadV4.useDefaultSerializationIn JrpcConv
BlobsBundleV1.useDefaultSerializationIn JrpcConv
ExecutionPayloadBodyV1.useDefaultSerializationIn JrpcConv
PayloadAttributesV1.useDefaultSerializationIn JrpcConv
Expand All @@ -82,7 +79,6 @@ GetPayloadV2ResponseExact.useDefaultSerializationIn JrpcConv
GetPayloadV3Response.useDefaultSerializationIn JrpcConv
GetPayloadV4Response.useDefaultSerializationIn JrpcConv
ClientVersionV1.useDefaultSerializationIn JrpcConv
ConsolidationRequestV1.useDefaultSerializationIn JrpcConv

#------------------------------------------------------------------------------
# execution_types
Expand Down Expand Up @@ -329,7 +325,7 @@ proc readValue*(r: var JsonReader[JrpcConv], val: var RtBlockIdentifier)
proc writeValue*(w: var JsonWriter[JrpcConv], v: RtBlockIdentifier)
{.gcsafe, raises: [IOError].} =
case v.kind
of bidNumber: w.writeValue(v.number.Quantity)
of bidNumber: w.writeValue(v.number)
of bidAlias: w.writeValue(v.alias)

proc readValue*(r: var JsonReader[JrpcConv], val: var TxOrHash)
Expand Down
36 changes: 18 additions & 18 deletions web3/encoding.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ func encode*[bits: static[int]](x: StUint[bits]): seq[byte] =
func encode*[bits: static[int]](x: StInt[bits]): seq[byte] =
@(x.toByteArrayBE())

func decode*(input: openarray[byte], baseOffset, offset: int, to: var StUint): int =
func decode*(input: openArray[byte], baseOffset, offset: int, to: var StUint): int =
const meaningfulLen = to.bits div 8
let offset = offset + baseOffset
to = type(to).fromBytesBE(input.toOpenArray(offset, offset + meaningfulLen - 1))
meaningfulLen

func decode*[N](input: openarray[byte], baseOffset, offset: int, to: var StInt[N]): int =
func decode*[N](input: openArray[byte], baseOffset, offset: int, to: var StInt[N]): int =
const meaningfulLen = N div 8
let offset = offset + baseOffset
to = type(to).fromBytesBE(input.toOpenArray(offset, offset + meaningfulLen - 1))
Expand All @@ -39,7 +39,7 @@ func encode*[N: static int](b: FixedBytes[N]): seq[byte] = encodeFixed(b.data)
func encode*(b: Address): seq[byte] = encodeFixed(b.data)
func encode*[N](b: array[N, byte]): seq[byte] {.inline.} = encodeFixed(b)

func decodeFixed(input: openarray[byte], baseOffset, offset: int, to: var openArray[byte]): int =
func decodeFixed(input: openArray[byte], baseOffset, offset: int, to: var openArray[byte]): int =
let meaningfulLen = to.len
var padding = to.len mod 32
if padding != 0:
Expand All @@ -49,10 +49,10 @@ func decodeFixed(input: openarray[byte], baseOffset, offset: int, to: var openAr
assign(to, input.toOpenArray(offset, offset + meaningfulLen - 1))
meaningfulLen + padding

func decode*[N](input: openarray[byte], baseOffset, offset: int, to: var FixedBytes[N]): int {.inline.} =
func decode*[N](input: openArray[byte], baseOffset, offset: int, to: var FixedBytes[N]): int {.inline.} =
decodeFixed(input, baseOffset, offset, array[N, byte](to))

func decode*(input: openarray[byte], baseOffset, offset: int, to: var Address): int {.inline.} =
func decode*(input: openArray[byte], baseOffset, offset: int, to: var Address): int {.inline.} =
decodeFixed(input, baseOffset, offset, array[20, byte](to))

func encodeDynamic(v: openArray[byte]): seq[byte] =
Expand All @@ -71,7 +71,7 @@ func encode*(x: seq[byte]): seq[byte] {.inline.} =
func encode*(x: string): seq[byte] {.inline.} =
encodeDynamic(x.toOpenArrayByte(0, x.high))

func decode*(input: openarray[byte], baseOffset, offset: int, to: var seq[byte]): int =
func decode*(input: openArray[byte], baseOffset, offset: int, to: var seq[byte]): int =
var dataOffsetBig, dataLenBig: UInt256
result = decode(input, baseOffset, offset, dataOffsetBig)
let dataOffset = dataOffsetBig.truncate(int)
Expand All @@ -80,7 +80,7 @@ func decode*(input: openarray[byte], baseOffset, offset: int, to: var seq[byte])
let actualDataOffset = baseOffset + dataOffset + 32
to = input[actualDataOffset ..< actualDataOffset + dataLen]

func decode*(input: openarray[byte], baseOffset, offset: int, to: var string): int =
func decode*(input: openArray[byte], baseOffset, offset: int, to: var string): int =
var dataOffsetBig, dataLenBig: UInt256
result = decode(input, baseOffset, offset, dataOffsetBig)
let dataOffset = dataOffsetBig.truncate(int)
Expand All @@ -89,15 +89,15 @@ func decode*(input: openarray[byte], baseOffset, offset: int, to: var string): i
let actualDataOffset = baseOffset + dataOffset + 32
to = string.fromBytes(input.toOpenArray(actualDataOffset, actualDataOffset + dataLen - 1))

func decode*(input: openarray[byte], baseOffset, offset: int, to: var DynamicBytes): int {.inline.} =
func decode*(input: openArray[byte], baseOffset, offset: int, to: var DynamicBytes): int {.inline.} =
var s: seq[byte]
result = decode(input, baseOffset, offset, s)
# TODO: Check data len, and raise?
to = typeof(to)(move(s))

func decode*(input: openarray[byte], baseOffset, offset: int, obj: var object): int
func decode*(input: openArray[byte], baseOffset, offset: int, obj: var object): int

func decode*[T](input: openarray[byte], baseOffset, offset: int, to: var seq[T]): int {.inline.} =
func decode*[T](input: openArray[byte], baseOffset, offset: int, to: var seq[T]): int {.inline.} =
var dataOffsetBig, dataLenBig: UInt256
result = decode(input, baseOffset, offset, dataOffsetBig)
let dataOffset = dataOffsetBig.truncate(int)
Expand All @@ -110,31 +110,31 @@ func decode*[T](input: openarray[byte], baseOffset, offset: int, to: var seq[T])
for i in 0 ..< dataLen:
offset += decode(input, baseOffset, offset, to[i])

proc isDynamicObject(T: typedesc): bool
func isDynamicObject(T: typedesc): bool

template isDynamicType(a: typedesc): bool =
when a is seq | openarray | string | DynamicBytes:
when a is seq | openArray | string | DynamicBytes:
true
elif a is object:
const r = isDynamicObject(a)
r
else:
false

proc isDynamicObject(T: typedesc): bool =
func isDynamicObject(T: typedesc): bool =
var a: T
for v in fields(a):
if isDynamicType(typeof(v)): return true
false

func encode*(x: bool): seq[byte] = encode(x.int.u256)

func decode*(input: openarray[byte], baseOffset, offset: int, to: var bool): int =
func decode*(input: openArray[byte], baseOffset, offset: int, to: var bool): int =
var i: Int256
result = decode(input, baseOffset, offset, i)
to = not i.isZero()

func decode*(input: openarray[byte], baseOffset, offset: int, obj: var object): int =
func decode*(input: openArray[byte], baseOffset, offset: int, obj: var object): int =
when isDynamicObject(typeof(obj)):
var dataOffsetBig: UInt256
result = decode(input, baseOffset, offset, dataOffsetBig)
Expand All @@ -153,7 +153,7 @@ func decode*(input: openarray[byte], baseOffset, offset: int, obj: var object):

func encode*(x: tuple): seq[byte]

func encode*[T](x: openarray[T]): seq[byte] =
func encode*[T](x: openArray[T]): seq[byte] =
result = encode(x.len.u256)
when isDynamicType(T):
result.setLen((1 + x.len) * 32)
Expand All @@ -165,7 +165,7 @@ func encode*[T](x: openarray[T]): seq[byte] =
for i in 0 ..< x.len:
result &= encode(x[i])

proc getTupleImpl(t: NimNode): NimNode =
func getTupleImpl(t: NimNode): NimNode =
getTypeImpl(t)[1].getTypeImpl()

macro typeListLen*(t: typedesc[tuple]): int =
Expand All @@ -191,5 +191,5 @@ func encode*(x: tuple): seq[byte] =
inc i

# Obsolete
func decode*(input: string, offset: int, to: var DynamicBytes): int {.inline, deprecated: "Use decode(openarray[byte], ...) instead".} =
func decode*(input: string, offset: int, to: var DynamicBytes): int {.inline, deprecated: "Use decode(openArray[byte], ...) instead".} =
decode(hexToSeqByte(input), 0, offset div 2, to) * 2
13 changes: 3 additions & 10 deletions web3/engine_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ createRpcSigsFromNim(RpcClient):
proc engine_newPayloadV1(payload: ExecutionPayloadV1): PayloadStatusV1
proc engine_newPayloadV2(payload: ExecutionPayloadV2): PayloadStatusV1
proc engine_newPayloadV3(payload: ExecutionPayloadV3, expectedBlobVersionedHashes: seq[VersionedHash], parentBeaconBlockRoot: Hash32): PayloadStatusV1
proc engine_newPayloadV4(payload: ExecutionPayloadV4, expectedBlobVersionedHashes: seq[VersionedHash], parentBeaconBlockRoot: Hash32): PayloadStatusV1
proc engine_newPayloadV4(payload: ExecutionPayloadV3, expectedBlobVersionedHashes: seq[VersionedHash], parentBeaconBlockRoot: Hash32, executionRequests: array[3, seq[byte]]): PayloadStatusV1
proc engine_forkchoiceUpdatedV1(forkchoiceState: ForkchoiceStateV1, payloadAttributes: Opt[PayloadAttributesV1]): ForkchoiceUpdatedResponse
proc engine_forkchoiceUpdatedV2(forkchoiceState: ForkchoiceStateV1, payloadAttributes: Opt[PayloadAttributesV2]): ForkchoiceUpdatedResponse
proc engine_forkchoiceUpdatedV3(forkchoiceState: ForkchoiceStateV1, payloadAttributes: Opt[PayloadAttributesV3]): ForkchoiceUpdatedResponse
Expand All @@ -54,7 +54,8 @@ createRpcSigsFromNim(RpcClient):
parentBeaconBlockRoot: Opt[Hash32]): PayloadStatusV1
proc engine_newPayloadV4(payload: ExecutionPayload,
expectedBlobVersionedHashes: Opt[seq[VersionedHash]],
parentBeaconBlockRoot: Opt[Hash32]): PayloadStatusV1
parentBeaconBlockRoot: Opt[Hash32],
executionRequests: Opt[array[3, seq[byte]]]): PayloadStatusV1
proc engine_forkchoiceUpdatedV2(forkchoiceState: ForkchoiceStateV1, payloadAttributes: Opt[PayloadAttributes]): ForkchoiceUpdatedResponse
proc engine_forkchoiceUpdatedV3(forkchoiceState: ForkchoiceStateV1, payloadAttributes: Opt[PayloadAttributes]): ForkchoiceUpdatedResponse

Expand Down Expand Up @@ -124,14 +125,6 @@ template newPayload*(
engine_newPayloadV3(
rpcClient, payload, versionedHashes, parentBeaconBlockRoot)

template newPayload*(
rpcClient: RpcClient,
payload: ExecutionPayloadV4,
versionedHashes: seq[VersionedHash],
parentBeaconBlockRoot: Hash32): Future[PayloadStatusV1] =
engine_newPayloadV4(
rpcClient, payload, versionedHashes, parentBeaconBlockRoot)

template exchangeCapabilities*(
rpcClient: RpcClient,
methods: seq[string]): Future[seq[string]] =
Expand Down
52 changes: 4 additions & 48 deletions web3/engine_api_types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,6 @@ type
address*: Address
amount*: Quantity

# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.4/src/engine/prague.md#depositrequestv1
DepositRequestV1* = object
pubkey*: Bytes48
withdrawalCredentials*: Bytes32
amount*: Quantity
signature*: Bytes96
index*: Quantity

# https://github.com/nflaig/execution-apis/blob/update-withdrawal-request/src/engine/prague.md#withdrawalrequestv1
WithdrawalRequestV1* = object
sourceAddress*: Address
validatorPubkey*: Bytes48
amount*: Quantity

# https://github.com/ethereum/execution-apis/blob/3ae3d29fc9900e5c48924c238dff7643fdc3680e/src/engine/prague.md#consolidationrequestv1
ConsolidationRequestV1* = object
sourceAddress*: Address
sourcePubkey*: Bytes48
targetPubkey*: Bytes48

# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.4/src/engine/paris.md#executionpayloadv1
# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.4/src/engine/openrpc/schemas/payload.yaml#L51
ExecutionPayloadV1* = object
Expand Down Expand Up @@ -136,35 +116,10 @@ type
blobGasUsed*: Quantity
excessBlobGas*: Quantity

# https://github.com/ethereum/execution-apis/blob/3ae3d29fc9900e5c48924c238dff7643fdc3680e/src/engine/prague.md#executionpayloadv4
# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.4/src/engine/openrpc/schemas/payload.yaml#L246
ExecutionPayloadV4* = object
parentHash*: Hash32
feeRecipient*: Address
stateRoot*: Hash32
receiptsRoot*: Hash32
logsBloom*: Bytes256
prevRandao*: Bytes32
blockNumber*: Quantity
gasLimit*: Quantity
gasUsed*: Quantity
timestamp*: Quantity
extraData*: DynamicBytes[0, 32]
baseFeePerGas*: UInt256
blockHash*: Hash32
transactions*: seq[TypedTransaction]
withdrawals*: seq[WithdrawalV1]
blobGasUsed*: Quantity
excessBlobGas*: Quantity
depositRequests*: seq[DepositRequestV1]
withdrawalRequests*: seq[WithdrawalRequestV1]
consolidationRequests*: seq[ConsolidationRequestV1]

SomeExecutionPayload* =
ExecutionPayloadV1 |
ExecutionPayloadV2 |
ExecutionPayloadV3 |
ExecutionPayloadV4
ExecutionPayloadV3

# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.4/src/engine/cancun.md#blobsbundlev1
BlobsBundleV1* = object
Expand Down Expand Up @@ -260,12 +215,13 @@ type
blobsBundle*: BlobsBundleV1
shouldOverrideBuilder*: bool

# https://github.com/ethereum/execution-apis/blob/90a46e9137c89d58e818e62fa33a0347bba50085/src/engine/prague.md#response-1
# https://github.com/ethereum/execution-apis/blob/4140e528360fea53c34a766d86a000c6c039100e/src/engine/prague.md#response-1
GetPayloadV4Response* = object
executionPayload*: ExecutionPayloadV4
executionPayload*: ExecutionPayloadV3
blockValue*: UInt256
blobsBundle*: BlobsBundleV1
shouldOverrideBuilder*: bool
executionRequests*: array[3, seq[byte]]

SomeGetPayloadResponse* =
ExecutionPayloadV1 |
Expand Down
Loading
Loading