mirror of https://github.com/status-im/nim-eth.git
Add a helper type used in web3 and elsewhere to denote blocks
This commit is contained in:
parent
71d6dbd1b4
commit
5dff021cbc
|
@ -1,5 +1,6 @@
|
|||
import
|
||||
stew/endians2, options, times, chronicles,
|
||||
strutils,
|
||||
stew/[endians2, byteutils], options, times, chronicles,
|
||||
stint, nimcrypto/[keccak, hash], eth/rlp, eth/trie/[trie_defs, db]
|
||||
|
||||
export
|
||||
|
@ -125,6 +126,7 @@ type
|
|||
receiptRoot*: Hash256
|
||||
blockNumber*: BlockNumber
|
||||
|
||||
# TODO: Make BlockNumber a uint64 and deprecate either this or BlockHashOrNumber
|
||||
HashOrNum* = object
|
||||
case isHash*: bool
|
||||
of true:
|
||||
|
@ -132,6 +134,13 @@ type
|
|||
else:
|
||||
number*: BlockNumber
|
||||
|
||||
BlockHashOrNumber* = object
|
||||
case isHash*: bool
|
||||
of true:
|
||||
hash*: Hash256
|
||||
else:
|
||||
number*: uint64
|
||||
|
||||
BlocksRequest* = object
|
||||
startBlock*: HashOrNum
|
||||
maxResults*, skip*: uint
|
||||
|
@ -301,6 +310,24 @@ proc read*(rlp: var Rlp, T: typedesc[HashOrStatus]): T {.inline.} =
|
|||
raise newException(RlpTypeMismatch,
|
||||
"HashOrStatus expected, but the source RLP is not a blob of right size.")
|
||||
|
||||
func init*(T: type BlockHashOrNumber, str: string): T
|
||||
{.raises: [ValueError, Defect].} =
|
||||
if str.startsWith "0x":
|
||||
if str.len != sizeof(result.hash.data) * 2 + 2:
|
||||
raise newException(ValueError, "Block hash has incorrect length")
|
||||
|
||||
result.isHash = true
|
||||
hexToByteArray(str, result.hash.data)
|
||||
else:
|
||||
result.isHash = false
|
||||
result.number = parseBiggestUInt str
|
||||
|
||||
func `$`*(x: BlockHashOrNumber): string =
|
||||
if x.isHash:
|
||||
"0x" & x.hash.data.toHex
|
||||
else:
|
||||
$x.number
|
||||
|
||||
proc append*(rlpWriter: var RlpWriter, value: HashOrStatus) {.inline.} =
|
||||
if value.isHash:
|
||||
rlpWriter.append(value.hash)
|
||||
|
|
|
@ -2,6 +2,9 @@ import
|
|||
times, net,
|
||||
json_serialization, nimcrypto/[hash, utils], eth_types
|
||||
|
||||
export
|
||||
json_serialization
|
||||
|
||||
{.push raises: [SerializationError, IOError, Defect].}
|
||||
|
||||
proc writeValue*(w: var JsonWriter, a: MDigest) =
|
||||
|
@ -42,3 +45,12 @@ proc writeValue*(w: var JsonWriter, value: HashOrNum) =
|
|||
w.writeField("number", value.number)
|
||||
w.endRecord()
|
||||
|
||||
proc writeValue*(w: var JsonWriter, value: BlockHashOrNumber) =
|
||||
w.writeValue $value
|
||||
|
||||
proc readValue*(r: var JsonReader, value: var BlockHashOrNumber) =
|
||||
try:
|
||||
value = init(BlockHashOrNumber, r.readValue(string))
|
||||
except ValueError:
|
||||
r.raiseUnexpectedValue("A hex-encoded block hash or a decimal block number expected")
|
||||
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
import
|
||||
unittest,
|
||||
nimcrypto/hash,
|
||||
serialization/testing/generic_suite,
|
||||
../../eth/common/[eth_types, eth_types_json_serialization]
|
||||
|
||||
func `==`*(lhs, rhs: BlockHashOrNumber): bool =
|
||||
if lhs.isHash != rhs.isHash:
|
||||
return false
|
||||
|
||||
if lhs.isHash:
|
||||
lhs.hash == rhs.hash
|
||||
else:
|
||||
lhs.number == rhs.number
|
||||
|
||||
suite "BlockHashOrNumber":
|
||||
test "construction":
|
||||
expect ValueError:
|
||||
var x = BlockHashOrNumber.init ""
|
||||
echo "An empty string should not produce the value ", x
|
||||
|
||||
let x1 = BlockHashOrNumber.init "0"
|
||||
check((not x1.isHash) and x1.number == 0)
|
||||
|
||||
let x2 = BlockHashOrNumber.init "1241328"
|
||||
check((not x1.isHash) and x2.number == 1241328)
|
||||
|
||||
expect ValueError:
|
||||
var x = BlockHashOrNumber.init "0x"
|
||||
echo "An empty hash should not produce the value ", x
|
||||
|
||||
expect ValueError:
|
||||
var x = BlockHashOrNumber.init "0xff11"
|
||||
echo "A shorter hash should not produce the value ", x
|
||||
|
||||
expect ValueError:
|
||||
var x = BlockHashOrNumber.init "0x7a64245f7f95164f6176d90bd4903dbdd3e5433d555dd1385e81787f9672c58z"
|
||||
echo "An invalid hash should not produce the value ", x
|
||||
|
||||
expect ValueError:
|
||||
var x = BlockHashOrNumber.init "0x7a64245f7f95164f6176d90bd4903dbdd3e5433d555dd1385e81787f9672c58811"
|
||||
echo "A longer hash should not produce the value ", x
|
||||
|
||||
test "serialization":
|
||||
let hash = Hash256.fromHex "0x7a64245f7f95164f6176d90bd4903dbdd3e5433d555dd1385e81787f9672c588"
|
||||
|
||||
Json.roundtripTest BlockHashOrNumber(isHash: true, hash: hash),
|
||||
"\"0x7a64245f7f95164f6176d90bd4903dbdd3e5433d555dd1385e81787f9672c588\""
|
||||
|
||||
Json.roundtripTest BlockHashOrNumber(isHash: false, number: 1209231231),
|
||||
"\"1209231231\""
|
Loading…
Reference in New Issue