Skip to content

Commit

Permalink
Replace eth_getBlockReceipts return type with Opt[T] instead of Optio… (
Browse files Browse the repository at this point in the history
#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
  • Loading branch information
jangko authored Feb 14, 2024
1 parent a67213a commit 10538c6
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 12 deletions.
14 changes: 4 additions & 10 deletions tests/helpers/handlers.nim
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,10 @@ proc installHandlers*(server: RpcServer) =
if x != "-1".JsonString:
result = decodeFromString(x, Quantity)

when NimMajor >= 2:
server.rpc("eth_getBlockReceipts") do(x: JsonString, blockId: RtBlockIdentifier) -> JsonString:
# TODO: cannot prove obj is not nil
let jsonBytes = JrpcConv.decode(x.string, string)
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_getBlockReceipts") do(x: JsonString, blockId: RtBlockIdentifier) -> Opt[seq[ReceiptObject]]:
if x != "-1".JsonString:
let r = decodeFromString(x, Opt[seq[ReceiptObject]])
return r

server.rpc("eth_getBlockByNumber") do(x: JsonString, blockId: RtBlockIdentifier, fullTransactions: bool) -> BlockObject:
var blk: BlockObject
Expand Down
24 changes: 23 additions & 1 deletion tests/test_execution_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import
json_rpc/[rpcclient, rpcserver],
json_rpc/private/jrpc_sys,
../web3/conversions,
./helpers/handlers
./helpers/handlers,
../web3/eth_api,
results

type
TestData = tuple
Expand Down Expand Up @@ -109,3 +111,23 @@ suite "Ethereum execution api":

waitFor srv.stop()
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()
21 changes: 21 additions & 0 deletions web3/conversions.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import
faststreams/textio,
json_rpc/jsonmarshal,
json_serialization/std/options,
json_serialization/stew/results,
json_serialization,
./primitives,
./engine_api_types,
Expand Down Expand Up @@ -364,6 +365,26 @@ proc writeValue*(w: var JsonWriter[JrpcConv], v: SyncingStatus)
else:
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.} =
encodeQuantity(v.uint64)

Expand Down
13 changes: 12 additions & 1 deletion web3/eth_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import
std/[json, options],
json_serialization/std/[options],
json_serialization/stew/results,
json_rpc/[client, jsonmarshal],
stint,
./conversions,
Expand Down Expand Up @@ -39,7 +40,17 @@ createRpcSigsFromNim(RpcClient):
proc eth_getTransactionCount(data: Address, blockId: BlockIdentifier): Quantity
proc eth_getBlockTransactionCountByHash(data: BlockHash): 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_getUncleCountByBlockNumber(blockId: BlockIdentifier): Quantity
proc eth_getCode(data: Address, blockId: BlockIdentifier): seq[byte]
Expand Down

0 comments on commit 10538c6

Please sign in to comment.