Replace eth_getBlockReceipts return type with Opt[T] instead of Optio… (#131)

* Replace eth_getBlockReceipts return type with Opt[T] instead of Option[T]

reason:
Option[T] failed to compile when using nim v2
it is related to ref object. But also hard to reproduce outside
combination of nim-json-serialization + nim-json-rpc + something

* Add note about nim v2 regression

* Add test case of eth_getBlockReceipts usage
This commit is contained in:
andri lim 2024-02-14 18:40:57 +07:00 committed by GitHub
parent a67213af4f
commit 10538c667a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 60 additions and 12 deletions

View File

@ -81,16 +81,10 @@ proc installHandlers*(server: RpcServer) =
if x != "-1".JsonString: if x != "-1".JsonString:
result = decodeFromString(x, Quantity) result = decodeFromString(x, Quantity)
when NimMajor >= 2: server.rpc("eth_getBlockReceipts") do(x: JsonString, blockId: RtBlockIdentifier) -> Opt[seq[ReceiptObject]]:
server.rpc("eth_getBlockReceipts") do(x: JsonString, blockId: RtBlockIdentifier) -> JsonString: if x != "-1".JsonString:
# TODO: cannot prove obj is not nil let r = decodeFromString(x, Opt[seq[ReceiptObject]])
let jsonBytes = JrpcConv.decode(x.string, string) return r
return jsonBytes.JsonString
else:
server.rpc("eth_getBlockReceipts") do(x: JsonString, blockId: RtBlockIdentifier) -> Option[seq[ReceiptObject]]:
if x != "-1".JsonString:
let r = decodeFromString(x, Option[seq[ReceiptObject]])
return r
server.rpc("eth_getBlockByNumber") do(x: JsonString, blockId: RtBlockIdentifier, fullTransactions: bool) -> BlockObject: server.rpc("eth_getBlockByNumber") do(x: JsonString, blockId: RtBlockIdentifier, fullTransactions: bool) -> BlockObject:
var blk: BlockObject var blk: BlockObject

View File

@ -5,7 +5,9 @@ import
json_rpc/[rpcclient, rpcserver], json_rpc/[rpcclient, rpcserver],
json_rpc/private/jrpc_sys, json_rpc/private/jrpc_sys,
../web3/conversions, ../web3/conversions,
./helpers/handlers ./helpers/handlers,
../web3/eth_api,
results
type type
TestData = tuple TestData = tuple
@ -109,3 +111,23 @@ suite "Ethereum execution api":
waitFor srv.stop() waitFor srv.stop()
waitFor srv.closeWait() waitFor srv.closeWait()
proc setupMethods(server: RpcServer) =
server.rpc("eth_getBlockReceipts") do(blockId: RtBlockIdentifier) -> Opt[seq[ReceiptObject]]:
var res: seq[ReceiptObject]
return Opt.some(res)
suite "Test eth api":
var srv = newRpcHttpServer(["127.0.0.1:0"])
srv.setupMethods()
srv.start()
test "eth_getBlockReceipts generic functions":
let client = newRpcHttpClient()
waitFor client.connect("http://" & $srv.localAddress()[0])
let res = waitFor client.eth_getBlockReceipts(blockId("latest"))
check res.isSome
waitFor client.close()
waitFor srv.stop()
waitFor srv.closeWait()

View File

@ -14,6 +14,7 @@ import
faststreams/textio, faststreams/textio,
json_rpc/jsonmarshal, json_rpc/jsonmarshal,
json_serialization/std/options, json_serialization/std/options,
json_serialization/stew/results,
json_serialization, json_serialization,
./primitives, ./primitives,
./engine_api_types, ./engine_api_types,
@ -364,6 +365,26 @@ proc writeValue*(w: var JsonWriter[JrpcConv], v: SyncingStatus)
else: else:
w.writeValue(v.syncObject) w.writeValue(v.syncObject)
# Somehow nim2 refuse to generate automatically
proc readValue*(r: var JsonReader[JrpcConv], val: var Opt[seq[ReceiptObject]])
{.gcsafe, raises: [IOError, SerializationError].} =
mixin readValue
if r.tokKind == JsonValueKind.Null:
reset val
r.parseNull()
else:
val.ok r.readValue(seq[ReceiptObject])
proc writeValue*(w: var JsonWriter[JrpcConv], v: Opt[seq[ReceiptObject]])
{.gcsafe, raises: [IOError].} =
mixin writeValue
if v.isOk:
w.writeValue v.get
else:
w.writeValue JsonString("null")
func `$`*(v: Quantity): string {.inline.} = func `$`*(v: Quantity): string {.inline.} =
encodeQuantity(v.uint64) encodeQuantity(v.uint64)

View File

@ -11,6 +11,7 @@
import import
std/[json, options], std/[json, options],
json_serialization/std/[options], json_serialization/std/[options],
json_serialization/stew/results,
json_rpc/[client, jsonmarshal], json_rpc/[client, jsonmarshal],
stint, stint,
./conversions, ./conversions,
@ -39,7 +40,17 @@ createRpcSigsFromNim(RpcClient):
proc eth_getTransactionCount(data: Address, blockId: BlockIdentifier): Quantity proc eth_getTransactionCount(data: Address, blockId: BlockIdentifier): Quantity
proc eth_getBlockTransactionCountByHash(data: BlockHash): Quantity proc eth_getBlockTransactionCountByHash(data: BlockHash): Quantity
proc eth_getBlockTransactionCountByNumber(blockId: BlockIdentifier): Quantity proc eth_getBlockTransactionCountByNumber(blockId: BlockIdentifier): Quantity
proc eth_getBlockReceipts(blockId: BlockIdentifier): Option[seq[ReceiptObject]]
# TODO: Investigate why nim v2 cannot instantiate generic functions
# with oneof params `blockId: BlockIdentifier` and and return type
# Opt[seq[ReceiptObject]], this is a regression after all
when false:
proc eth_getBlockReceipts(blockId: BlockIdentifier): Opt[seq[ReceiptObject]]
proc eth_getBlockReceipts(blockId: string): Opt[seq[ReceiptObject]]
proc eth_getBlockReceipts(blockId: BlockNumber): Opt[seq[ReceiptObject]]
proc eth_getBlockReceipts(blockId: RtBlockIdentifier): Opt[seq[ReceiptObject]]
proc eth_getUncleCountByBlockHash(data: BlockHash): Quantity proc eth_getUncleCountByBlockHash(data: BlockHash): Quantity
proc eth_getUncleCountByBlockNumber(blockId: BlockIdentifier): Quantity proc eth_getUncleCountByBlockNumber(blockId: BlockIdentifier): Quantity
proc eth_getCode(data: Address, blockId: BlockIdentifier): seq[byte] proc eth_getCode(data: Address, blockId: BlockIdentifier): seq[byte]