make `BlockNumber` `distinct` (#137)
The `writeValue` added for `BlockNumber` in #136 interferes with other `uint64` because `BlockNumber` is not `distinct`. Marking it `distinct` avoids polluting global serialization logic.
This commit is contained in:
parent
428c46c94f
commit
80c7aa6de2
|
@ -1,5 +1,5 @@
|
||||||
# nim-web3
|
# nim-web3
|
||||||
# Copyright (c) 2018-2023 Status Research & Development GmbH
|
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
||||||
# Licensed under either of
|
# Licensed under either of
|
||||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||||
|
@ -213,8 +213,9 @@ suite "Contracts":
|
||||||
receipt = await web3.deployContract(MetaCoinCode)
|
receipt = await web3.deployContract(MetaCoinCode)
|
||||||
cc = receipt.contractAddress.get
|
cc = receipt.contractAddress.get
|
||||||
|
|
||||||
let deployedAtBlock = distinctBase(receipt.blockNumber)
|
let deployedAtBlock = receipt.blockNumber
|
||||||
echo "Deployed MetaCoin contract: ", cc, " at block ", deployedAtBlock
|
echo "Deployed MetaCoin contract: ", cc, " at block ",
|
||||||
|
distinctBase(deployedAtBlock)
|
||||||
|
|
||||||
let ns = web3.contractSender(MetaCoin, cc)
|
let ns = web3.contractSender(MetaCoin, cc)
|
||||||
|
|
||||||
|
@ -225,7 +226,8 @@ suite "Contracts":
|
||||||
fromAddr, toAddr: Address, value: UInt256)
|
fromAddr, toAddr: Address, value: UInt256)
|
||||||
{.raises: [], gcsafe.}:
|
{.raises: [], gcsafe.}:
|
||||||
try:
|
try:
|
||||||
echo "onTransfer: ", fromAddr, " transferred ", value.toHex, " to ", toAddr
|
echo "onTransfer: ", fromAddr, " transferred ", value.toHex,
|
||||||
|
" to ", toAddr
|
||||||
inc notificationsReceived
|
inc notificationsReceived
|
||||||
assert(fromAddr == web3.defaultAccount)
|
assert(fromAddr == web3.defaultAccount)
|
||||||
assert((notificationsReceived == 1 and value == 50.u256) or
|
assert((notificationsReceived == 1 and value == 50.u256) or
|
||||||
|
@ -238,12 +240,15 @@ suite "Contracts":
|
||||||
|
|
||||||
let balNow = await ns.getBalance(web3.defaultAccount).call()
|
let balNow = await ns.getBalance(web3.defaultAccount).call()
|
||||||
echo "getbalance (now): ", balNow.toHex
|
echo "getbalance (now): ", balNow.toHex
|
||||||
let balNew = await ns.getBalance(web3.defaultAccount).call(blockNumber = deployedAtBlock)
|
let balNew = await ns.getBalance(web3.defaultAccount).call(
|
||||||
|
blockNumber = deployedAtBlock)
|
||||||
echo "getbalance (after creation): ", balNew.toHex
|
echo "getbalance (after creation): ", balNew.toHex
|
||||||
|
|
||||||
# Let's try to get the balance at a point in time where the contract was not deployed yet:
|
# Let's try to get the balance at a point in time where the contract
|
||||||
|
# was not deployed yet:
|
||||||
try:
|
try:
|
||||||
let balFirst = await ns.getBalance(web3.defaultAccount).call(blockNumber = 1'u64)
|
let balFirst = await ns.getBalance(web3.defaultAccount).call(
|
||||||
|
blockNumber = 1.BlockNumber)
|
||||||
echo "getbalance (first block): ", balFirst.toHex
|
echo "getbalance (first block): ", balFirst.toHex
|
||||||
except CatchableError as err:
|
except CatchableError as err:
|
||||||
echo "getbalance (first block): ", err.msg
|
echo "getbalance (first block): ", err.msg
|
||||||
|
@ -261,7 +266,7 @@ suite "Contracts":
|
||||||
echo "transfers: ", await ns.getJsonLogs(
|
echo "transfers: ", await ns.getJsonLogs(
|
||||||
Transfer,
|
Transfer,
|
||||||
fromBlock = some(blockId(deployedAtBlock)),
|
fromBlock = some(blockId(deployedAtBlock)),
|
||||||
toBlock = some(blockId(1000'u64)))
|
toBlock = some(blockId(1000.BlockNumber)))
|
||||||
|
|
||||||
await notifFut
|
await notifFut
|
||||||
await s.unsubscribe()
|
await s.unsubscribe()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# nim-web3
|
# nim-web3
|
||||||
# Copyright (c) 2018-2023 Status Research & Development GmbH
|
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
||||||
# Licensed under either of
|
# Licensed under either of
|
||||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||||
|
@ -43,7 +43,7 @@ suite "Deposit contract":
|
||||||
|
|
||||||
var fut = newFuture[void]()
|
var fut = newFuture[void]()
|
||||||
|
|
||||||
let options = FilterOptions(fromBlock: some(blockId(0)))
|
let options = FilterOptions(fromBlock: some(blockId(0.BlockNumber)))
|
||||||
let s = await ns.subscribe(DepositEvent, options) do (
|
let s = await ns.subscribe(DepositEvent, options) do (
|
||||||
pubkey: DynamicBytes[0, 48], withdrawalCredentials: DynamicBytes[0, 32], amount: DynamicBytes[0, 8], signature: DynamicBytes[0, 96], merkleTreeIndex: DynamicBytes[0, 8])
|
pubkey: DynamicBytes[0, 48], withdrawalCredentials: DynamicBytes[0, 32], amount: DynamicBytes[0, 8], signature: DynamicBytes[0, 96], merkleTreeIndex: DynamicBytes[0, 8])
|
||||||
{.raises: [], gcsafe.}:
|
{.raises: [], gcsafe.}:
|
||||||
|
|
|
@ -27,10 +27,10 @@ proc rand[M,N](_: type DynamicBytes[M,N]): DynamicBytes[M,N] =
|
||||||
proc rand(_: type Address): Address =
|
proc rand(_: type Address): Address =
|
||||||
discard randomBytes(distinctBase result)
|
discard randomBytes(distinctBase result)
|
||||||
|
|
||||||
proc rand(_: type Quantity): Quantity =
|
proc rand[T: Quantity | BlockNumber](_: type T): T =
|
||||||
var res: array[8, byte]
|
var res: array[8, byte]
|
||||||
discard randomBytes(res)
|
discard randomBytes(res)
|
||||||
result = Quantity(uint64.fromBytesBE(res))
|
result = T(uint64.fromBytesBE(res))
|
||||||
|
|
||||||
proc rand(_: type RlpEncodedBytes): RlpEncodedBytes =
|
proc rand(_: type RlpEncodedBytes): RlpEncodedBytes =
|
||||||
discard randomBytes(distinctBase result)
|
discard randomBytes(distinctBase result)
|
||||||
|
@ -57,7 +57,7 @@ proc rand(_: type UInt256): UInt256 =
|
||||||
result = UInt256.fromBytesBE(x)
|
result = UInt256.fromBytesBE(x)
|
||||||
|
|
||||||
proc rand(_: type RtBlockIdentifier): RtBlockIdentifier =
|
proc rand(_: type RtBlockIdentifier): RtBlockIdentifier =
|
||||||
RtBlockIdentifier(kind: bidNumber, number: rand(Quantity).uint64)
|
RtBlockIdentifier(kind: bidNumber, number: rand(BlockNumber))
|
||||||
|
|
||||||
proc rand(_: type PayloadExecutionStatus): PayloadExecutionStatus =
|
proc rand(_: type PayloadExecutionStatus): PayloadExecutionStatus =
|
||||||
var x: array[1, byte]
|
var x: array[1, byte]
|
||||||
|
@ -98,32 +98,37 @@ template checkRandomObject(T: type) =
|
||||||
|
|
||||||
suite "JSON-RPC Quantity":
|
suite "JSON-RPC Quantity":
|
||||||
test "Valid":
|
test "Valid":
|
||||||
for (validQuantityStr, validQuantity) in [
|
template checkType(typeName: typedesc): untyped =
|
||||||
("0x0", Quantity 0),
|
for (validStr, validValue) in [
|
||||||
("0x123", Quantity 291),
|
("0x0", typeName 0),
|
||||||
("0x1234", Quantity 4660)]:
|
("0x123", typeName 291),
|
||||||
let validQuantityJson = JrpcConv.encode(validQuantityStr)
|
("0x1234", typeName 4660)]:
|
||||||
let resQuantity = JrpcConv.decode(validQuantityJson, Quantity)
|
let
|
||||||
let resUInt256 = JrpcConv.decode(validQuantityJson, UInt256)
|
validJson = JrpcConv.encode(validStr)
|
||||||
let resUInt256Ref = JrpcConv.decode(validQuantityJson, ref UInt256)
|
res = JrpcConv.decode(validJson, typeName)
|
||||||
|
resUInt256 = JrpcConv.decode(validJson, UInt256)
|
||||||
|
resUInt256Ref = JrpcConv.decode(validJson, ref UInt256)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
JrpcConv.decode(validQuantityJson, Quantity) == validQuantity
|
JrpcConv.decode(validJson, typeName) == validValue
|
||||||
JrpcConv.encode(validQuantity) == validQuantityJson
|
JrpcConv.encode(validValue) == validJson
|
||||||
resQuantity == validQuantity
|
res == validValue
|
||||||
resUInt256 == validQuantity.distinctBase.u256
|
resUInt256 == validValue.distinctBase.u256
|
||||||
resUInt256Ref[] == validQuantity.distinctBase.u256
|
resUInt256Ref[] == validValue.distinctBase.u256
|
||||||
|
|
||||||
test "Invalid Quantity/UInt256/ref UInt256":
|
checkType(Quantity)
|
||||||
|
checkType(BlockNumber)
|
||||||
|
|
||||||
|
test "Invalid Quantity/BlockNumber/UInt256/ref UInt256":
|
||||||
# TODO once https://github.com/status-im/nimbus-eth2/pull/3850 addressed,
|
# TODO once https://github.com/status-im/nimbus-eth2/pull/3850 addressed,
|
||||||
# re-add "0x0400" test case as invalid.
|
# re-add "0x0400" test case as invalid.
|
||||||
for invalidStr in [
|
for invalidStr in [
|
||||||
"", "1234", "01234", "x1234", "0x", "ff"]:
|
"", "1234", "01234", "x1234", "0x", "ff"]:
|
||||||
template checkInvalids(typeName: untyped) =
|
template checkInvalids(typeName: untyped) =
|
||||||
var resQuantity: `typeName`
|
var res: `typeName`
|
||||||
try:
|
try:
|
||||||
let jsonBytes = JrpcConv.encode(invalidStr)
|
let jsonBytes = JrpcConv.encode(invalidStr)
|
||||||
resQuantity = JrpcConv.decode(jsonBytes, `typeName`)
|
res = JrpcConv.decode(jsonBytes, `typeName`)
|
||||||
echo `typeName`, " ", invalidStr
|
echo `typeName`, " ", invalidStr
|
||||||
check: false
|
check: false
|
||||||
except SerializationError:
|
except SerializationError:
|
||||||
|
@ -132,6 +137,7 @@ suite "JSON-RPC Quantity":
|
||||||
check: false
|
check: false
|
||||||
|
|
||||||
checkInvalids(Quantity)
|
checkInvalids(Quantity)
|
||||||
|
checkInvalids(BlockNumber)
|
||||||
checkInvalids(UInt256)
|
checkInvalids(UInt256)
|
||||||
checkInvalids(ref UInt256)
|
checkInvalids(ref UInt256)
|
||||||
|
|
||||||
|
@ -189,11 +195,11 @@ suite "JSON-RPC Quantity":
|
||||||
checkRandomObject(GetPayloadResponse)
|
checkRandomObject(GetPayloadResponse)
|
||||||
|
|
||||||
test "check blockId":
|
test "check blockId":
|
||||||
let a = RtBlockIdentifier(kind: bidNumber, number: 77.uint64)
|
let a = RtBlockIdentifier(kind: bidNumber, number: 77.BlockNumber)
|
||||||
let x = JrpcConv.encode(a)
|
let x = JrpcConv.encode(a)
|
||||||
let c = JrpcConv.decode(x, RtBlockIdentifier)
|
let c = JrpcConv.decode(x, RtBlockIdentifier)
|
||||||
check c.kind == bidNumber
|
check c.kind == bidNumber
|
||||||
check c.number == 77
|
check c.number == 77.BlockNumber
|
||||||
|
|
||||||
let d = JrpcConv.decode("\"10\"", RtBlockIdentifier)
|
let d = JrpcConv.decode("\"10\"", RtBlockIdentifier)
|
||||||
check d.kind == bidAlias
|
check d.kind == bidAlias
|
||||||
|
@ -210,16 +216,21 @@ suite "JSON-RPC Quantity":
|
||||||
check c.kind == slkNull
|
check c.kind == slkNull
|
||||||
|
|
||||||
test "quantity parser and writer":
|
test "quantity parser and writer":
|
||||||
let a = JrpcConv.decode("\"0x016345785d8a0000\"", Quantity)
|
template checkType(typeName: typedesc): untyped =
|
||||||
|
block:
|
||||||
|
let a = JrpcConv.decode("\"0x016345785d8a0000\"", typeName)
|
||||||
check a.uint64 == 100_000_000_000_000_000'u64
|
check a.uint64 == 100_000_000_000_000_000'u64
|
||||||
let b = JrpcConv.encode(a)
|
let b = JrpcConv.encode(a)
|
||||||
check b == "\"0x16345785d8a0000\""
|
check b == "\"0x16345785d8a0000\""
|
||||||
|
|
||||||
let x = JrpcConv.decode("\"0xFFFF_FFFF_FFFF_FFFF\"", Quantity)
|
let x = JrpcConv.decode("\"0xFFFF_FFFF_FFFF_FFFF\"", typeName)
|
||||||
check x.uint64 == 0xFFFF_FFFF_FFFF_FFFF_FFFF'u64
|
check x.uint64 == 0xFFFF_FFFF_FFFF_FFFF_FFFF'u64
|
||||||
let y = JrpcConv.encode(x)
|
let y = JrpcConv.encode(x)
|
||||||
check y == "\"0xffffffffffffffff\""
|
check y == "\"0xffffffffffffffff\""
|
||||||
|
|
||||||
|
checkType(Quantity)
|
||||||
|
checkType(BlockNumber)
|
||||||
|
|
||||||
test "AccessListResult":
|
test "AccessListResult":
|
||||||
var z: AccessListResult
|
var z: AccessListResult
|
||||||
let w = JrpcConv.encode(z)
|
let w = JrpcConv.encode(z)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# nim-web3
|
# nim-web3
|
||||||
# Copyright (c) 2018-2023 Status Research & Development GmbH
|
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
||||||
# Licensed under either of
|
# Licensed under either of
|
||||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||||
|
@ -74,7 +74,7 @@ suite "Logs":
|
||||||
let notifFut = newFuture[void]()
|
let notifFut = newFuture[void]()
|
||||||
var notificationsReceived = 0
|
var notificationsReceived = 0
|
||||||
|
|
||||||
let options = FilterOptions(fromBlock: some(blockId(0)))
|
let options = FilterOptions(fromBlock: some(blockId(0.BlockNumber)))
|
||||||
let s = await ns.subscribe(MyEvent, options) do (
|
let s = await ns.subscribe(MyEvent, options) do (
|
||||||
sender: Address, value: UInt256)
|
sender: Address, value: UInt256)
|
||||||
{.raises: [], gcsafe.}:
|
{.raises: [], gcsafe.}:
|
||||||
|
|
36
web3.nim
36
web3.nim
|
@ -1,5 +1,5 @@
|
||||||
# nim-web3
|
# nim-web3
|
||||||
# Copyright (c) 2019-2023 Status Research & Development GmbH
|
# Copyright (c) 2019-2024 Status Research & Development GmbH
|
||||||
# Licensed under either of
|
# Licensed under either of
|
||||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||||
|
@ -50,7 +50,7 @@ type
|
||||||
gas*: uint64
|
gas*: uint64
|
||||||
gasPrice*: int
|
gasPrice*: int
|
||||||
chainId*: Option[ChainId]
|
chainId*: Option[ChainId]
|
||||||
blockNumber*: uint64
|
blockNumber*: BlockNumber
|
||||||
|
|
||||||
Sender*[T] = ContractInstance[T, Web3SenderImpl]
|
Sender*[T] = ContractInstance[T, Web3SenderImpl]
|
||||||
AsyncSender*[T] = ContractInstance[T, Web3AsyncSenderImpl]
|
AsyncSender*[T] = ContractInstance[T, Web3AsyncSenderImpl]
|
||||||
|
@ -354,13 +354,14 @@ proc send*[T](c: ContractInvocation[T, Web3SenderImpl],
|
||||||
gasPrice = 0): Future[TxHash] =
|
gasPrice = 0): Future[TxHash] =
|
||||||
sendData(c.sender.web3, c.sender.contractAddress, c.sender.web3.defaultAccount, c.data, value, gas, gasPrice, some(chainId))
|
sendData(c.sender.web3, c.sender.contractAddress, c.sender.web3.defaultAccount, c.data, value, gas, gasPrice, some(chainId))
|
||||||
|
|
||||||
proc callAux(web3: Web3,
|
proc callAux(
|
||||||
|
web3: Web3,
|
||||||
contractAddress: Address,
|
contractAddress: Address,
|
||||||
defaultAccount: Address,
|
defaultAccount: Address,
|
||||||
data: seq[byte],
|
data: seq[byte],
|
||||||
value = 0.u256,
|
value = 0.u256,
|
||||||
gas = 3000000'u64,
|
gas = 3000000'u64,
|
||||||
blockNumber = high(uint64)): Future[seq[byte]] {.async.} =
|
blockNumber = high(BlockNumber)): Future[seq[byte]] {.async.} =
|
||||||
var cc: EthCall
|
var cc: EthCall
|
||||||
cc.data = some(data)
|
cc.data = some(data)
|
||||||
cc.source = some(defaultAccount)
|
cc.source = some(defaultAccount)
|
||||||
|
@ -368,15 +369,16 @@ proc callAux(web3: Web3,
|
||||||
cc.gas = some(Quantity(gas))
|
cc.gas = some(Quantity(gas))
|
||||||
cc.value = some(value)
|
cc.value = some(value)
|
||||||
result =
|
result =
|
||||||
if blockNumber != high(uint64):
|
if blockNumber != high(BlockNumber):
|
||||||
await web3.provider.eth_call(cc, blockId(blockNumber))
|
await web3.provider.eth_call(cc, blockId(blockNumber))
|
||||||
else:
|
else:
|
||||||
await web3.provider.eth_call(cc, "latest")
|
await web3.provider.eth_call(cc, "latest")
|
||||||
|
|
||||||
proc call*[T](c: ContractInvocation[T, Web3SenderImpl],
|
proc call*[T](
|
||||||
|
c: ContractInvocation[T, Web3SenderImpl],
|
||||||
value = 0.u256,
|
value = 0.u256,
|
||||||
gas = 3000000'u64,
|
gas = 3000000'u64,
|
||||||
blockNumber = high(uint64)): Future[T] {.async.} =
|
blockNumber = high(BlockNumber)): Future[T] {.async.} =
|
||||||
let response = await callAux(c.sender.web3, c.sender.contractAddress, c.sender.web3.defaultAccount, c.data, value, gas, blockNumber)
|
let response = await callAux(c.sender.web3, c.sender.contractAddress, c.sender.web3.defaultAccount, c.data, value, gas, blockNumber)
|
||||||
if response.len > 0:
|
if response.len > 0:
|
||||||
discard decode(response, 0, 0, result)
|
discard decode(response, 0, 0, result)
|
||||||
|
@ -436,8 +438,15 @@ proc createMutableContractInvocation*(sender: Web3SenderImpl, ReturnType: typede
|
||||||
proc createImmutableContractInvocation*(sender: Web3SenderImpl, ReturnType: typedesc, data: sink seq[byte]): ContractInvocation[ReturnType, Web3SenderImpl] {.inline.} =
|
proc createImmutableContractInvocation*(sender: Web3SenderImpl, ReturnType: typedesc, data: sink seq[byte]): ContractInvocation[ReturnType, Web3SenderImpl] {.inline.} =
|
||||||
ContractInvocation[ReturnType, Web3SenderImpl](sender: sender, data: data)
|
ContractInvocation[ReturnType, Web3SenderImpl](sender: sender, data: data)
|
||||||
|
|
||||||
proc contractInstance*(web3: Web3, T: typedesc, toAddress: Address): AsyncSender[T] =
|
proc contractInstance*(
|
||||||
AsyncSender[T](sender: Web3AsyncSenderImpl(web3: web3, contractAddress: toAddress, defaultAccount: web3.defaultAccount, gas: 3000000, blockNumber: uint64.high))
|
web3: Web3, T: typedesc, toAddress: Address): AsyncSender[T] =
|
||||||
|
AsyncSender[T](
|
||||||
|
sender: Web3AsyncSenderImpl(
|
||||||
|
web3: web3,
|
||||||
|
contractAddress: toAddress,
|
||||||
|
defaultAccount: web3.defaultAccount,
|
||||||
|
gas: 3000000,
|
||||||
|
blockNumber: BlockNumber.high))
|
||||||
|
|
||||||
proc createMutableContractInvocation*(sender: Web3AsyncSenderImpl, ReturnType: typedesc, data: sink seq[byte]) {.async.} =
|
proc createMutableContractInvocation*(sender: Web3AsyncSenderImpl, ReturnType: typedesc, data: sink seq[byte]) {.async.} =
|
||||||
assert(sender.gas > 0)
|
assert(sender.gas > 0)
|
||||||
|
@ -445,8 +454,13 @@ proc createMutableContractInvocation*(sender: Web3AsyncSenderImpl, ReturnType: t
|
||||||
let receipt = await sender.web3.getMinedTransactionReceipt(h)
|
let receipt = await sender.web3.getMinedTransactionReceipt(h)
|
||||||
discard receipt
|
discard receipt
|
||||||
|
|
||||||
proc createImmutableContractInvocation*(sender: Web3AsyncSenderImpl, ReturnType: typedesc, data: sink seq[byte]): Future[ReturnType] {.async.} =
|
proc createImmutableContractInvocation*(
|
||||||
let response = await callAux(sender.web3, sender.contractAddress, sender.defaultAccount, data, sender.value, sender.gas, sender.blockNumber)
|
sender: Web3AsyncSenderImpl,
|
||||||
|
ReturnType: typedesc,
|
||||||
|
data: sink seq[byte]): Future[ReturnType] {.async.} =
|
||||||
|
let response = await callAux(
|
||||||
|
sender.web3, sender.contractAddress, sender.defaultAccount, data,
|
||||||
|
sender.value, sender.gas, sender.blockNumber)
|
||||||
if response.len > 0:
|
if response.len > 0:
|
||||||
discard decode(response, 0, 0, result)
|
discard decode(response, 0, 0, result)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# nim-web3
|
# nim-web3
|
||||||
# Copyright (c) 2019-2023 Status Research & Development GmbH
|
# Copyright (c) 2019-2024 Status Research & Development GmbH
|
||||||
# Licensed under either of
|
# Licensed under either of
|
||||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||||
|
@ -198,8 +198,9 @@ proc writeValue*[F: CommonJsonFlavors](w: var JsonWriter[F], v: RlpEncodedBytes)
|
||||||
{.gcsafe, raises: [IOError].} =
|
{.gcsafe, raises: [IOError].} =
|
||||||
writeHexValue w, distinctBase(v)
|
writeHexValue w, distinctBase(v)
|
||||||
|
|
||||||
proc writeValue*[F: CommonJsonFlavors](w: var JsonWriter[F], v: Quantity | BlockNumber)
|
proc writeValue*[F: CommonJsonFlavors](
|
||||||
{.gcsafe, raises: [IOError].} =
|
w: var JsonWriter[F], v: Quantity | BlockNumber
|
||||||
|
) {.gcsafe, raises: [IOError].} =
|
||||||
w.stream.write "\"0x"
|
w.stream.write "\"0x"
|
||||||
w.stream.toHex(distinctBase v)
|
w.stream.toHex(distinctBase v)
|
||||||
w.stream.write "\""
|
w.stream.write "\""
|
||||||
|
@ -243,6 +244,11 @@ proc readValue*[F: CommonJsonFlavors](r: var JsonReader[F], val: var Quantity)
|
||||||
wrapValueError:
|
wrapValueError:
|
||||||
val = Quantity fromHex[uint64](hexStr)
|
val = Quantity fromHex[uint64](hexStr)
|
||||||
|
|
||||||
|
proc readValue*[F: CommonJsonFlavors](
|
||||||
|
r: var JsonReader[F],
|
||||||
|
val: var BlockNumber) {.gcsafe, raises: [IOError, JsonReaderError].} =
|
||||||
|
r.readValue(distinctBase(val, recursive = false))
|
||||||
|
|
||||||
proc readValue*[F: CommonJsonFlavors](r: var JsonReader[F], val: var PayloadExecutionStatus)
|
proc readValue*[F: CommonJsonFlavors](r: var JsonReader[F], val: var PayloadExecutionStatus)
|
||||||
{.gcsafe, raises: [IOError, JsonReaderError].} =
|
{.gcsafe, raises: [IOError, JsonReaderError].} =
|
||||||
const enumStrings = static: getEnumStringTable(PayloadExecutionStatus)
|
const enumStrings = static: getEnumStringTable(PayloadExecutionStatus)
|
||||||
|
@ -300,7 +306,8 @@ proc readValue*(r: var JsonReader[JrpcConv], val: var RtBlockIdentifier)
|
||||||
let hexStr = r.parseString()
|
let hexStr = r.parseString()
|
||||||
wrapValueError:
|
wrapValueError:
|
||||||
if valid(hexStr):
|
if valid(hexStr):
|
||||||
val = RtBlockIdentifier(kind: bidNumber, number: fromHex[uint64](hexStr))
|
val = RtBlockIdentifier(
|
||||||
|
kind: bidNumber, number: BlockNumber fromHex[uint64](hexStr))
|
||||||
else:
|
else:
|
||||||
val = RtBlockIdentifier(kind: bidAlias, alias: hexStr)
|
val = RtBlockIdentifier(kind: bidAlias, alias: hexStr)
|
||||||
|
|
||||||
|
@ -385,7 +392,7 @@ proc writeValue*(w: var JsonWriter[JrpcConv], v: Opt[seq[ReceiptObject]])
|
||||||
else:
|
else:
|
||||||
w.writeValue JsonString("null")
|
w.writeValue JsonString("null")
|
||||||
|
|
||||||
func `$`*(v: Quantity): string {.inline.} =
|
func `$`*(v: Quantity | BlockNumber): string {.inline.} =
|
||||||
encodeQuantity(v.uint64)
|
encodeQuantity(v.uint64)
|
||||||
|
|
||||||
func `$`*(v: TypedTransaction): string {.inline.} =
|
func `$`*(v: TypedTransaction): string {.inline.} =
|
||||||
|
|
|
@ -86,7 +86,7 @@ type
|
||||||
|
|
||||||
## A block object, or null when no block was found
|
## A block object, or null when no block was found
|
||||||
BlockObject* = ref object
|
BlockObject* = ref object
|
||||||
number*: Quantity # the block number. null when its pending block.
|
number*: BlockNumber # the block number. null when its pending block.
|
||||||
hash*: Hash256 # hash of the block. null when its pending block.
|
hash*: Hash256 # hash of the block. null when its pending block.
|
||||||
parentHash*: Hash256 # hash of the parent block.
|
parentHash*: Hash256 # hash of the parent block.
|
||||||
sha3Uncles*: Hash256 # SHA3 of the uncles data in the block.
|
sha3Uncles*: Hash256 # SHA3 of the uncles data in the block.
|
||||||
|
@ -136,7 +136,7 @@ type
|
||||||
hash*: TxHash # hash of the transaction.
|
hash*: TxHash # hash of the transaction.
|
||||||
nonce*: Quantity # TODO: Is int? the number of transactions made by the sender prior to this one.
|
nonce*: Quantity # TODO: Is int? the number of transactions made by the sender prior to this one.
|
||||||
blockHash*: Option[BlockHash] # hash of the block where this transaction was in. null when its pending.
|
blockHash*: Option[BlockHash] # hash of the block where this transaction was in. null when its pending.
|
||||||
blockNumber*: Option[Quantity] # block number where this transaction was in. null when its pending.
|
blockNumber*: Option[BlockNumber] # block number where this transaction was in. null when its pending.
|
||||||
transactionIndex*: Option[Quantity] # integer of the transactions index position in the block. null when its pending.
|
transactionIndex*: Option[Quantity] # integer of the transactions index position in the block. null when its pending.
|
||||||
`from`*: Address # address of the sender.
|
`from`*: Address # address of the sender.
|
||||||
to*: Option[Address] # address of the receiver. null when its a contract creation transaction.
|
to*: Option[Address] # address of the receiver. null when its a contract creation transaction.
|
||||||
|
@ -160,7 +160,7 @@ type
|
||||||
transactionHash*: TxHash # hash of the transaction.
|
transactionHash*: TxHash # hash of the transaction.
|
||||||
transactionIndex*: Quantity # integer of the transactions index position in the block.
|
transactionIndex*: Quantity # integer of the transactions index position in the block.
|
||||||
blockHash*: BlockHash # hash of the block where this transaction was in.
|
blockHash*: BlockHash # hash of the block where this transaction was in.
|
||||||
blockNumber*: Quantity # block number where this transaction was in.
|
blockNumber*: BlockNumber # block number where this transaction was in.
|
||||||
`from`*: Address # address of the sender.
|
`from`*: Address # address of the sender.
|
||||||
to*: Option[Address] # address of the receiver. null when its a contract creation transaction.
|
to*: Option[Address] # address of the receiver. null when its a contract creation transaction.
|
||||||
cumulativeGasUsed*: Quantity # the total amount of gas used when this transaction was executed in the block.
|
cumulativeGasUsed*: Quantity # the total amount of gas used when this transaction was executed in the block.
|
||||||
|
@ -205,7 +205,7 @@ type
|
||||||
transactionIndex*: Option[Quantity] # integer of the transactions index position log was created from. null when its pending log.
|
transactionIndex*: Option[Quantity] # integer of the transactions index position log was created from. null when its pending log.
|
||||||
transactionHash*: Option[TxHash] # hash of the transactions this log was created from. null when its pending log.
|
transactionHash*: Option[TxHash] # hash of the transactions this log was created from. null when its pending log.
|
||||||
blockHash*: Option[BlockHash] # hash of the block where this log was in. null when its pending. null when its pending log.
|
blockHash*: Option[BlockHash] # hash of the block where this log was in. null when its pending. null when its pending log.
|
||||||
blockNumber*: Option[Quantity] # the block number where this log was in. null when its pending. null when its pending log.
|
blockNumber*: Option[BlockNumber] # the block number where this log was in. null when its pending. null when its pending log.
|
||||||
address*: Address # address from which this log originated.
|
address*: Address # address from which this log originated.
|
||||||
data*: seq[byte] # contains one or more 32 Bytes non-indexed arguments of the log.
|
data*: seq[byte] # contains one or more 32 Bytes non-indexed arguments of the log.
|
||||||
topics*: seq[Topic] # array of 0 to 4 32 Bytes DATA of indexed log arguments.
|
topics*: seq[Topic] # array of 0 to 4 32 Bytes DATA of indexed log arguments.
|
||||||
|
@ -228,7 +228,7 @@ type
|
||||||
storageHash*: StorageHash
|
storageHash*: StorageHash
|
||||||
storageProof*: seq[StorageProof]
|
storageProof*: seq[StorageProof]
|
||||||
|
|
||||||
BlockIdentifier* = string|BlockNumber|RtBlockIdentifier
|
BlockIdentifier* = string | BlockNumber | RtBlockIdentifier
|
||||||
|
|
||||||
BlockIdentifierKind* = enum
|
BlockIdentifierKind* = enum
|
||||||
bidNumber
|
bidNumber
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# nim-web3
|
# nim-web3
|
||||||
# Copyright (c) 2023 Status Research & Development GmbH
|
# Copyright (c) 2023-2024 Status Research & Development GmbH
|
||||||
# Licensed under either of
|
# Licensed under either of
|
||||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||||
|
@ -25,8 +25,8 @@ type
|
||||||
TxHash* = FixedBytes[32]
|
TxHash* = FixedBytes[32]
|
||||||
Hash256* = FixedBytes[32]
|
Hash256* = FixedBytes[32]
|
||||||
BlockHash* = FixedBytes[32]
|
BlockHash* = FixedBytes[32]
|
||||||
BlockNumber* = uint64
|
|
||||||
Quantity* = distinct uint64
|
Quantity* = distinct uint64
|
||||||
|
BlockNumber* = distinct Quantity
|
||||||
|
|
||||||
CodeHash* = FixedBytes[32]
|
CodeHash* = FixedBytes[32]
|
||||||
StorageHash* = FixedBytes[32]
|
StorageHash* = FixedBytes[32]
|
||||||
|
@ -37,15 +37,23 @@ type
|
||||||
template `==`*[N](a, b: FixedBytes[N]): bool =
|
template `==`*[N](a, b: FixedBytes[N]): bool =
|
||||||
distinctBase(a) == distinctBase(b)
|
distinctBase(a) == distinctBase(b)
|
||||||
|
|
||||||
template `==`*(a, b: Quantity): bool =
|
|
||||||
distinctBase(a) == distinctBase(b)
|
|
||||||
|
|
||||||
template `==`*[minLen, maxLen](a, b: DynamicBytes[minLen, maxLen]): bool =
|
template `==`*[minLen, maxLen](a, b: DynamicBytes[minLen, maxLen]): bool =
|
||||||
distinctBase(a) == distinctBase(b)
|
distinctBase(a) == distinctBase(b)
|
||||||
|
|
||||||
func `==`*(a, b: Address): bool {.inline.} =
|
func `==`*(a, b: Address): bool {.inline.} =
|
||||||
distinctBase(a) == distinctBase(b)
|
distinctBase(a) == distinctBase(b)
|
||||||
|
|
||||||
|
template ethQuantity(typ: type) {.dirty.} =
|
||||||
|
func `+`*(a: typ, b: distinctBase(typ)): typ {.borrow.}
|
||||||
|
func `-`*(a: typ, b: distinctBase(typ)): typ {.borrow.}
|
||||||
|
|
||||||
|
func `<`*(a, b: typ): bool {.borrow.}
|
||||||
|
func `<=`*(a, b: typ): bool {.borrow.}
|
||||||
|
func `==`*(a, b: typ): bool {.borrow.}
|
||||||
|
|
||||||
|
ethQuantity Quantity
|
||||||
|
ethQuantity BlockNumber
|
||||||
|
|
||||||
func hash*[N](bytes: FixedBytes[N]): Hash =
|
func hash*[N](bytes: FixedBytes[N]): Hash =
|
||||||
hash(distinctBase bytes)
|
hash(distinctBase bytes)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue