2019-01-06 15:21:34 +00:00
|
|
|
import
|
|
|
|
json, strutils, times, options, os,
|
2019-02-05 19:15:50 +00:00
|
|
|
eth/[rlp, common], httputils, nimcrypto, chronicles,
|
2019-07-07 10:12:01 +00:00
|
|
|
stint, stew/byteutils
|
2019-01-06 15:21:34 +00:00
|
|
|
|
2020-07-30 08:24:22 +00:00
|
|
|
import ../nimbus/transaction
|
|
|
|
from ../nimbus/rpc/hexstrings import encodeQuantity
|
2019-01-06 15:21:34 +00:00
|
|
|
|
2019-01-11 06:53:18 +00:00
|
|
|
func hexToInt*(s: string, T: typedesc[SomeInteger]): T =
|
2019-01-06 15:21:34 +00:00
|
|
|
var i = 0
|
|
|
|
if s[i] == '0' and (s[i+1] in {'x', 'X'}): inc(i, 2)
|
|
|
|
if s.len - i > sizeof(T) * 2:
|
|
|
|
raise newException(ValueError, "input hex too big for destination int")
|
|
|
|
while i < s.len:
|
|
|
|
result = result shl 4 or readHexChar(s[i]).T
|
|
|
|
inc(i)
|
|
|
|
|
|
|
|
proc prefixHex*(x: Hash256): string =
|
|
|
|
"0x" & toLowerAscii($x)
|
|
|
|
|
|
|
|
proc prefixHex*(x: int64 | uint64 | byte | int): string =
|
2020-07-23 07:54:32 +00:00
|
|
|
toLowerAscii(encodeQuantity(x.uint64).string)
|
2019-01-06 15:21:34 +00:00
|
|
|
|
|
|
|
proc prefixHex*(x: openArray[byte]): string =
|
|
|
|
"0x" & toHex(x, true)
|
|
|
|
|
|
|
|
proc prefixHex*(x: UInt256): string =
|
|
|
|
"0x" & stint.toHex(x)
|
|
|
|
|
|
|
|
proc prefixHex*(x: string): string =
|
|
|
|
"0x" & toLowerAscii(x)
|
|
|
|
|
|
|
|
type
|
2019-09-03 15:06:43 +00:00
|
|
|
SomeData* = EthAddress | BloomFilter | BlockNonce
|
2019-01-06 15:21:34 +00:00
|
|
|
|
2019-09-03 15:06:43 +00:00
|
|
|
proc fromJson*(n: JsonNode, name: string, x: var SomeData) =
|
2019-01-06 15:21:34 +00:00
|
|
|
hexToByteArray(n[name].getStr(), x)
|
2019-09-03 15:06:43 +00:00
|
|
|
if x.prefixHex != toLowerAscii(n[name].getStr()):
|
|
|
|
debugEcho "name: ", name
|
|
|
|
debugEcho "A: ", x.prefixHex
|
|
|
|
debugEcho "B: ", toLowerAscii(n[name].getStr())
|
|
|
|
quit(1)
|
2019-01-06 15:21:34 +00:00
|
|
|
|
2019-09-03 15:06:43 +00:00
|
|
|
doAssert(x.prefixHex == toLowerAscii(n[name].getStr()), name)
|
|
|
|
|
|
|
|
proc fromJson*(n: JsonNode, name: string, x: var Hash256) =
|
2019-01-06 15:21:34 +00:00
|
|
|
hexToByteArray(n[name].getStr(), x.data)
|
2019-09-03 15:06:43 +00:00
|
|
|
doAssert(x.prefixHex == toLowerAscii(n[name].getStr()), name)
|
2019-01-06 15:21:34 +00:00
|
|
|
|
2019-09-03 15:06:43 +00:00
|
|
|
proc fromJson*(n: JsonNode, name: string, x: var Blob) =
|
2019-01-06 15:21:34 +00:00
|
|
|
x = hexToSeqByte(n[name].getStr())
|
2019-09-03 15:06:43 +00:00
|
|
|
doAssert(x.prefixHex == toLowerAscii(n[name].getStr()), name)
|
2019-01-06 15:21:34 +00:00
|
|
|
|
2019-09-03 15:06:43 +00:00
|
|
|
proc fromJson*(n: JsonNode, name: string, x: var UInt256) =
|
2019-01-06 15:21:34 +00:00
|
|
|
x = UInt256.fromHex(n[name].getStr())
|
2019-09-03 15:06:43 +00:00
|
|
|
doAssert(x.prefixHex == toLowerAscii(n[name].getStr()), name)
|
2019-01-06 15:21:34 +00:00
|
|
|
|
2019-09-03 15:06:43 +00:00
|
|
|
proc fromJson*(n: JsonNode, name: string, x: var SomeInteger) =
|
2019-01-06 15:21:34 +00:00
|
|
|
x = hexToInt(n[name].getStr(), type(x))
|
2019-09-03 15:06:43 +00:00
|
|
|
doAssert(x.prefixHex == toLowerAscii(n[name].getStr()), name)
|
2019-01-06 15:21:34 +00:00
|
|
|
|
2019-09-03 15:06:43 +00:00
|
|
|
proc fromJson*(n: JsonNode, name: string, x: var EthTime) =
|
2019-01-06 15:21:34 +00:00
|
|
|
x = initTime(hexToInt(n[name].getStr(), int64), 0)
|
2019-09-03 15:06:43 +00:00
|
|
|
doAssert(x.toUnix.prefixHex == toLowerAscii(n[name].getStr()), name)
|
2019-01-06 15:21:34 +00:00
|
|
|
|
|
|
|
proc parseBlockHeader*(n: JsonNode): BlockHeader =
|
|
|
|
n.fromJson "parentHash", result.parentHash
|
|
|
|
n.fromJson "sha3Uncles", result.ommersHash
|
|
|
|
n.fromJson "miner", result.coinbase
|
|
|
|
n.fromJson "stateRoot", result.stateRoot
|
|
|
|
n.fromJson "transactionsRoot", result.txRoot
|
|
|
|
n.fromJson "receiptsRoot", result.receiptRoot
|
|
|
|
n.fromJson "logsBloom", result.bloom
|
|
|
|
n.fromJson "difficulty", result.difficulty
|
|
|
|
n.fromJson "number", result.blockNumber
|
|
|
|
n.fromJson "gasLimit", result.gasLimit
|
|
|
|
n.fromJson "gasUsed", result.gasUsed
|
|
|
|
n.fromJson "timestamp", result.timestamp
|
|
|
|
n.fromJson "extraData", result.extraData
|
|
|
|
n.fromJson "mixHash", result.mixDigest
|
|
|
|
n.fromJson "nonce", result.nonce
|
|
|
|
|
|
|
|
proc parseTransaction*(n: JsonNode): Transaction =
|
2021-05-15 06:37:40 +00:00
|
|
|
var tx: LegacyTx
|
|
|
|
n.fromJson "nonce", tx.nonce
|
|
|
|
n.fromJson "gasPrice", tx.gasPrice
|
|
|
|
n.fromJson "gas", tx.gasLimit
|
|
|
|
|
|
|
|
tx.isContractCreation = n["to"].kind == JNull
|
|
|
|
if not tx.isContractCreation:
|
|
|
|
n.fromJson "to", tx.to
|
|
|
|
|
|
|
|
n.fromJson "value", tx.value
|
|
|
|
n.fromJson "input", tx.payload
|
|
|
|
n.fromJson "v", tx.V
|
|
|
|
n.fromJson "r", tx.R
|
|
|
|
n.fromJson "s", tx.S
|
|
|
|
|
|
|
|
var sender = tx.getSender()
|
2019-03-13 21:36:54 +00:00
|
|
|
doAssert sender.prefixHex == n["from"].getStr()
|
2021-05-15 06:37:40 +00:00
|
|
|
doAssert n["hash"].getStr() == tx.rlpHash().prefixHex
|
|
|
|
result = Transaction(txType: LegacyTxType, legacyTx: tx)
|
2019-01-06 15:21:34 +00:00
|
|
|
|
|
|
|
proc parseLog(n: JsonNode): Log =
|
|
|
|
n.fromJson "address", result.address
|
|
|
|
n.fromJson "data", result.data
|
|
|
|
let topics = n["topics"]
|
|
|
|
result.topics = newSeqOfCap[Topic](n.len)
|
|
|
|
var topicHash: Topic
|
|
|
|
for tp in topics:
|
|
|
|
hexToByteArray(tp.getStr(), topicHash)
|
|
|
|
result.topics.add topicHash
|
|
|
|
|
|
|
|
proc parseLogs(n: JsonNode): seq[Log] =
|
|
|
|
if n.len > 0:
|
|
|
|
result = newSeqOfCap[Log](n.len)
|
|
|
|
for log in n:
|
|
|
|
result.add parseLog(log)
|
|
|
|
else:
|
|
|
|
result = @[]
|
|
|
|
|
|
|
|
proc parseReceipt*(n: JsonNode): Receipt =
|
2021-05-15 06:37:40 +00:00
|
|
|
var rec: LegacyReceipt
|
2019-01-06 15:21:34 +00:00
|
|
|
if n.hasKey("root"):
|
|
|
|
var hash: Hash256
|
|
|
|
n.fromJson "root", hash
|
2021-05-15 06:37:40 +00:00
|
|
|
rec.stateRootOrStatus = hashOrStatus(hash)
|
2019-01-06 15:21:34 +00:00
|
|
|
else:
|
|
|
|
var status: int
|
|
|
|
n.fromJson "status", status
|
2021-05-15 06:37:40 +00:00
|
|
|
rec.stateRootOrStatus = hashOrStatus(status == 1)
|
2019-01-06 15:21:34 +00:00
|
|
|
|
2021-05-15 06:37:40 +00:00
|
|
|
n.fromJson "cumulativeGasUsed", rec.cumulativeGasUsed
|
|
|
|
n.fromJson "logsBloom", rec.bloom
|
|
|
|
rec.logs = parseLogs(n["logs"])
|
|
|
|
Receipt(receiptType: LegacyReceiptType, legacyReceipt: rec)
|
2019-01-06 15:21:34 +00:00
|
|
|
|
|
|
|
proc headerHash*(n: JsonNode): Hash256 =
|
|
|
|
n.fromJson "hash", result
|
2019-01-15 08:55:39 +00:00
|
|
|
|
|
|
|
proc parseAccount*(n: JsonNode): Account =
|
|
|
|
n.fromJson "nonce", result.nonce
|
|
|
|
n.fromJson "balance", result.balance
|
|
|
|
n.fromJson "storageRoot", result.storageRoot
|
|
|
|
n.fromJson "codeHash", result.codeHash
|