More clean-up since eth types refactor (#2742)
This commit is contained in:
parent
f797d55c35
commit
b885f822d0
|
@ -10,6 +10,7 @@
|
||||||
import
|
import
|
||||||
chronos,
|
chronos,
|
||||||
testutils/unittests,
|
testutils/unittests,
|
||||||
|
stew/byteutils,
|
||||||
json_rpc/rpcserver,
|
json_rpc/rpcserver,
|
||||||
json_rpc/clients/httpclient,
|
json_rpc/clients/httpclient,
|
||||||
stint,
|
stint,
|
||||||
|
@ -67,6 +68,6 @@ procSuite "Discovery v5 JSON-RPC API":
|
||||||
|
|
||||||
check:
|
check:
|
||||||
nodeEnr == tc.localDiscovery.localNode.record.toURI()
|
nodeEnr == tc.localDiscovery.localNode.record.toURI()
|
||||||
nodeId == "0x" & tc.localDiscovery.localNode.id.toHex()
|
nodeId == tc.localDiscovery.localNode.id.toBytesBE().to0xHex()
|
||||||
|
|
||||||
waitFor tc.stop()
|
waitFor tc.stop()
|
||||||
|
|
|
@ -79,9 +79,9 @@ func asReceipt(receiptObject: ReceiptObject): Result[Receipt, string] =
|
||||||
var logs: seq[Log]
|
var logs: seq[Log]
|
||||||
if receiptObject.logs.len > 0:
|
if receiptObject.logs.len > 0:
|
||||||
for log in receiptObject.logs:
|
for log in receiptObject.logs:
|
||||||
var topics: seq[eth_types.Topic]
|
var topics: seq[Topic]
|
||||||
for topic in log.topics:
|
for topic in log.topics:
|
||||||
topics.add(eth_types.Topic(topic))
|
topics.add(Topic(topic))
|
||||||
|
|
||||||
logs.add(Log(address: log.address, data: log.data, topics: topics))
|
logs.add(Log(address: log.address, data: log.data, topics: topics))
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import
|
||||||
chronos,
|
chronos,
|
||||||
json_rpc/rpcclient,
|
json_rpc/rpcclient,
|
||||||
stew/byteutils,
|
stew/byteutils,
|
||||||
eth/keys,
|
eth/common/keys,
|
||||||
./utp_test_rpc_client
|
./utp_test_rpc_client
|
||||||
|
|
||||||
proc generateBytesHex(rng: var HmacDrbgContext, length: int): string =
|
proc generateBytesHex(rng: var HmacDrbgContext, length: int): string =
|
||||||
|
|
|
@ -17,7 +17,7 @@ import
|
||||||
eth/p2p/discoveryv5/protocol,
|
eth/p2p/discoveryv5/protocol,
|
||||||
eth/p2p/discoveryv5/enr,
|
eth/p2p/discoveryv5/enr,
|
||||||
eth/utp/[utp_discv5_protocol, utp_router],
|
eth/utp/[utp_discv5_protocol, utp_router],
|
||||||
eth/keys,
|
eth/common/keys,
|
||||||
../../rpc/rpc_discovery_api,
|
../../rpc/rpc_discovery_api,
|
||||||
./utp_rpc_types
|
./utp_rpc_types
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ proc writeValue*(w: var JsonWriter[JrpcConv], v: Record) {.gcsafe, raises: [IOEr
|
||||||
proc readValue*(
|
proc readValue*(
|
||||||
r: var JsonReader[JrpcConv], val: var Record
|
r: var JsonReader[JrpcConv], val: var Record
|
||||||
) {.gcsafe, raises: [IOError, JsonReaderError].} =
|
) {.gcsafe, raises: [IOError, JsonReaderError].} =
|
||||||
if not fromURI(val, r.parseString()):
|
val = enr.Record.fromURI(r.parseString()).valueOr:
|
||||||
r.raiseUnexpectedValue("Invalid ENR")
|
r.raiseUnexpectedValue("Invalid ENR")
|
||||||
|
|
||||||
proc installUtpHandlers(
|
proc installUtpHandlers(
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
{.push raises: [].}
|
{.push raises: [].}
|
||||||
|
|
||||||
import std/tables, web3/primitives, stew/keyed_queue, results, ./rpc/rpc_utils
|
import eth/common/hashes, web3/primitives, stew/keyed_queue, results, ./rpc/rpc_utils
|
||||||
|
|
||||||
## Cache for payloads received through block gossip and validated by the
|
## Cache for payloads received through block gossip and validated by the
|
||||||
## consensus light client.
|
## consensus light client.
|
||||||
|
@ -15,15 +15,14 @@ import std/tables, web3/primitives, stew/keyed_queue, results, ./rpc/rpc_utils
|
||||||
## oldest payload is deleted first.
|
## oldest payload is deleted first.
|
||||||
type BlockCache* = ref object
|
type BlockCache* = ref object
|
||||||
max: int
|
max: int
|
||||||
blocks: KeyedQueue[BlockHash, ExecutionData]
|
blocks: KeyedQueue[Hash32, ExecutionData]
|
||||||
|
|
||||||
proc `==`(x, y: Quantity): bool {.borrow, noSideEffect.}
|
proc `==`(x, y: Quantity): bool {.borrow, noSideEffect.}
|
||||||
|
|
||||||
proc new*(T: type BlockCache, max: uint32): T =
|
proc new*(T: type BlockCache, max: uint32): T =
|
||||||
let maxAsInt = int(max)
|
let maxAsInt = int(max)
|
||||||
return BlockCache(
|
return
|
||||||
max: maxAsInt, blocks: KeyedQueue[BlockHash, ExecutionData].init(maxAsInt)
|
BlockCache(max: maxAsInt, blocks: KeyedQueue[Hash32, ExecutionData].init(maxAsInt))
|
||||||
)
|
|
||||||
|
|
||||||
func len*(self: BlockCache): int =
|
func len*(self: BlockCache): int =
|
||||||
return len(self.blocks)
|
return len(self.blocks)
|
||||||
|
@ -54,5 +53,5 @@ proc getByNumber*(self: BlockCache, number: Quantity): Opt[ExecutionData] =
|
||||||
|
|
||||||
return payloadResult
|
return payloadResult
|
||||||
|
|
||||||
proc getPayloadByHash*(self: BlockCache, hash: BlockHash): Opt[ExecutionData] =
|
proc getPayloadByHash*(self: BlockCache, hash: Hash32): Opt[ExecutionData] =
|
||||||
return self.blocks.eq(hash)
|
return self.blocks.eq(hash)
|
||||||
|
|
|
@ -200,7 +200,7 @@ proc run*(
|
||||||
try:
|
try:
|
||||||
headerCallback(cstring(Json.encode(forkyHeader)), 0)
|
headerCallback(cstring(Json.encode(forkyHeader)), 0)
|
||||||
except SerializationError as e:
|
except SerializationError as e:
|
||||||
notice "finalizedHeaderCallback exception"
|
error "finalizedHeaderCallback exception", error = e.msg
|
||||||
|
|
||||||
proc onOptimisticHeader(
|
proc onOptimisticHeader(
|
||||||
lightClient: LightClient, optimisticHeader: ForkedLightClientHeader
|
lightClient: LightClient, optimisticHeader: ForkedLightClientHeader
|
||||||
|
@ -212,7 +212,7 @@ proc run*(
|
||||||
try:
|
try:
|
||||||
headerCallback(cstring(Json.encode(forkyHeader)), 1)
|
headerCallback(cstring(Json.encode(forkyHeader)), 1)
|
||||||
except SerializationError as e:
|
except SerializationError as e:
|
||||||
notice "optimisticHeaderCallback exception"
|
error "optimisticHeaderCallback exception", error = e.msg
|
||||||
|
|
||||||
lightClient.onFinalizedHeader = onFinalizedHeader
|
lightClient.onFinalizedHeader = onFinalizedHeader
|
||||||
lightClient.onOptimisticHeader = onOptimisticHeader
|
lightClient.onOptimisticHeader = onOptimisticHeader
|
||||||
|
|
|
@ -8,15 +8,14 @@
|
||||||
{.push raises: [].}
|
{.push raises: [].}
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[strutils, typetraits],
|
std/strutils,
|
||||||
stint,
|
stint,
|
||||||
stew/byteutils,
|
stew/byteutils,
|
||||||
results,
|
results,
|
||||||
chronicles,
|
chronicles,
|
||||||
json_rpc/[rpcproxy, rpcserver, rpcclient],
|
json_rpc/[rpcproxy, rpcserver, rpcclient],
|
||||||
eth/common/eth_types as etypes,
|
eth/common/accounts,
|
||||||
web3,
|
web3/[primitives, eth_api_types, eth_api],
|
||||||
web3/[primitives, eth_api_types],
|
|
||||||
beacon_chain/el/el_manager,
|
beacon_chain/el/el_manager,
|
||||||
beacon_chain/networking/network_metadata,
|
beacon_chain/networking/network_metadata,
|
||||||
beacon_chain/spec/forks,
|
beacon_chain/spec/forks,
|
||||||
|
@ -26,15 +25,9 @@ import
|
||||||
|
|
||||||
export forks
|
export forks
|
||||||
|
|
||||||
type
|
|
||||||
FixedBytes[N: static int] = primitives.FixedBytes[N]
|
|
||||||
Address = primitives.Address
|
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
topics = "verified_proxy"
|
topics = "verified_proxy"
|
||||||
|
|
||||||
proc `==`(x, y: Quantity): bool {.borrow, noSideEffect.}
|
|
||||||
|
|
||||||
type
|
type
|
||||||
VerifiedRpcProxy* = ref object
|
VerifiedRpcProxy* = ref object
|
||||||
proxy: RpcProxy
|
proxy: RpcProxy
|
||||||
|
@ -63,7 +56,7 @@ func parseQuantityTag(blockTag: BlockTag): Result[QuantityTag, string] =
|
||||||
else:
|
else:
|
||||||
return err("Unsupported blockTag: " & tag)
|
return err("Unsupported blockTag: " & tag)
|
||||||
else:
|
else:
|
||||||
let quantity = blockTag.number.Quantity
|
let quantity = blockTag.number
|
||||||
return ok(QuantityTag(kind: BlockNumber, blockNumber: quantity))
|
return ok(QuantityTag(kind: BlockNumber, blockNumber: quantity))
|
||||||
|
|
||||||
template checkPreconditions(proxy: VerifiedRpcProxy) =
|
template checkPreconditions(proxy: VerifiedRpcProxy) =
|
||||||
|
@ -197,7 +190,7 @@ proc installEthApiHandlers*(lcProxy: VerifiedRpcProxy) =
|
||||||
|
|
||||||
let account = accountResult.get()
|
let account = accountResult.get()
|
||||||
|
|
||||||
if account.codeHash == etypes.EMPTY_CODE_HASH:
|
if account.codeHash == EMPTY_CODE_HASH:
|
||||||
# account does not have any code, return empty hex data
|
# account does not have any code, return empty hex data
|
||||||
return @[]
|
return @[]
|
||||||
|
|
||||||
|
@ -233,7 +226,7 @@ proc installEthApiHandlers*(lcProxy: VerifiedRpcProxy) =
|
||||||
return Opt.some(asBlockObject(executionPayload.get()))
|
return Opt.some(asBlockObject(executionPayload.get()))
|
||||||
|
|
||||||
lcProxy.proxy.rpc("eth_getBlockByHash") do(
|
lcProxy.proxy.rpc("eth_getBlockByHash") do(
|
||||||
blockHash: BlockHash, fullTransactions: bool
|
blockHash: Hash32, fullTransactions: bool
|
||||||
) -> Opt[BlockObject]:
|
) -> Opt[BlockObject]:
|
||||||
let executionPayload = lcProxy.blockCache.getPayloadByHash(blockHash)
|
let executionPayload = lcProxy.blockCache.getPayloadByHash(blockHash)
|
||||||
|
|
||||||
|
|
|
@ -8,24 +8,19 @@
|
||||||
{.push raises: [].}
|
{.push raises: [].}
|
||||||
|
|
||||||
import
|
import
|
||||||
std/typetraits,
|
eth/common/[base_rlp, headers_rlp, blocks, hashes],
|
||||||
eth/common/eth_types as etypes,
|
|
||||||
eth/rlp,
|
|
||||||
nimcrypto/hash,
|
|
||||||
stint,
|
stint,
|
||||||
web3,
|
web3/eth_api_types,
|
||||||
web3/engine_api_types,
|
web3/engine_api_types,
|
||||||
../../nimbus/db/core_db
|
../../nimbus/db/core_db
|
||||||
|
|
||||||
type
|
export eth_api_types, engine_api_types
|
||||||
FixedBytes[N: static int] = primitives.FixedBytes[N]
|
|
||||||
Address = primitives.Address
|
|
||||||
|
|
||||||
type ExecutionData* = object
|
type ExecutionData* = object
|
||||||
parentHash*: BlockHash
|
parentHash*: Hash32
|
||||||
feeRecipient*: Address
|
feeRecipient*: Address
|
||||||
stateRoot*: BlockHash
|
stateRoot*: Hash32
|
||||||
receiptsRoot*: BlockHash
|
receiptsRoot*: Hash32
|
||||||
logsBloom*: FixedBytes[256]
|
logsBloom*: FixedBytes[256]
|
||||||
prevRandao*: FixedBytes[32]
|
prevRandao*: FixedBytes[32]
|
||||||
blockNumber*: Quantity
|
blockNumber*: Quantity
|
||||||
|
@ -34,7 +29,7 @@ type ExecutionData* = object
|
||||||
timestamp*: Quantity
|
timestamp*: Quantity
|
||||||
extraData*: DynamicBytes[0, 32]
|
extraData*: DynamicBytes[0, 32]
|
||||||
baseFeePerGas*: UInt256
|
baseFeePerGas*: UInt256
|
||||||
blockHash*: BlockHash
|
blockHash*: Hash32
|
||||||
transactions*: seq[TypedTransaction]
|
transactions*: seq[TypedTransaction]
|
||||||
withdrawals*: seq[WithdrawalV1]
|
withdrawals*: seq[WithdrawalV1]
|
||||||
|
|
||||||
|
@ -77,15 +72,9 @@ proc asExecutionData*(payload: SomeExecutionPayload): ExecutionData =
|
||||||
withdrawals: payload.withdrawals,
|
withdrawals: payload.withdrawals,
|
||||||
)
|
)
|
||||||
|
|
||||||
func toFixedBytes(d: MDigest[256]): FixedBytes[32] =
|
|
||||||
FixedBytes[32](d.data)
|
|
||||||
|
|
||||||
template asEthHash(hash: BlockHash): etypes.Hash32 =
|
|
||||||
etypes.Hash32(distinctBase(hash))
|
|
||||||
|
|
||||||
proc calculateTransactionData(
|
proc calculateTransactionData(
|
||||||
items: openArray[TypedTransaction]
|
items: openArray[TypedTransaction]
|
||||||
): (etypes.Hash32, seq[TxOrHash], uint64) =
|
): (Hash32, seq[TxOrHash], uint64) =
|
||||||
## returns tuple composed of
|
## returns tuple composed of
|
||||||
## - root of transactions trie
|
## - root of transactions trie
|
||||||
## - list of transactions hashes
|
## - list of transactions hashes
|
||||||
|
@ -97,30 +86,30 @@ proc calculateTransactionData(
|
||||||
let tx = distinctBase(t)
|
let tx = distinctBase(t)
|
||||||
txSize = txSize + uint64(len(tx))
|
txSize = txSize + uint64(len(tx))
|
||||||
tr.merge(rlp.encode(uint64 i), tx).expect "merge data"
|
tr.merge(rlp.encode(uint64 i), tx).expect "merge data"
|
||||||
txHashes.add(txOrHash keccakHash(tx))
|
txHashes.add(txOrHash keccak256(tx))
|
||||||
let rootHash = tr.state(updateOk = true).expect "hash"
|
let rootHash = tr.state(updateOk = true).expect "hash"
|
||||||
(rootHash, txHashes, txSize)
|
(rootHash, txHashes, txSize)
|
||||||
|
|
||||||
func blockHeaderSize(payload: ExecutionData, txRoot: etypes.Hash32): uint64 =
|
func blockHeaderSize(payload: ExecutionData, txRoot: Hash32): uint64 =
|
||||||
let bh = etypes.BlockHeader(
|
let header = Header(
|
||||||
parentHash: payload.parentHash,
|
parentHash: payload.parentHash,
|
||||||
ommersHash: etypes.EMPTY_UNCLE_HASH,
|
ommersHash: EMPTY_UNCLE_HASH,
|
||||||
coinbase: payload.feeRecipient,
|
coinbase: payload.feeRecipient,
|
||||||
stateRoot: payload.stateRoot,
|
stateRoot: payload.stateRoot,
|
||||||
transactionsRoot: txRoot,
|
transactionsRoot: txRoot,
|
||||||
receiptsRoot: payload.receiptsRoot,
|
receiptsRoot: payload.receiptsRoot,
|
||||||
logsBloom: distinctBase(payload.logsBloom).to(Bloom),
|
logsBloom: payload.logsBloom,
|
||||||
difficulty: default(etypes.DifficultyInt),
|
difficulty: default(DifficultyInt),
|
||||||
number: payload.blockNumber.distinctBase,
|
number: distinctBase(payload.blockNumber),
|
||||||
gasLimit: distinctBase(payload.gasLimit),
|
gasLimit: distinctBase(payload.gasLimit),
|
||||||
gasUsed: distinctBase(payload.gasUsed),
|
gasUsed: distinctBase(payload.gasUsed),
|
||||||
timestamp: payload.timestamp.EthTime,
|
timestamp: payload.timestamp.EthTime,
|
||||||
extraData: bytes payload.extraData,
|
extraData: payload.extraData.data,
|
||||||
mixHash: payload.prevRandao,
|
mixHash: payload.prevRandao,
|
||||||
nonce: default(etypes.BlockNonce),
|
nonce: default(Bytes8),
|
||||||
baseFeePerGas: Opt.some payload.baseFeePerGas,
|
baseFeePerGas: Opt.some payload.baseFeePerGas,
|
||||||
)
|
)
|
||||||
return uint64(len(rlp.encode(bh)))
|
return uint64(len(rlp.encode(header)))
|
||||||
|
|
||||||
proc asBlockObject*(p: ExecutionData): BlockObject {.raises: [ValueError].} =
|
proc asBlockObject*(p: ExecutionData): BlockObject {.raises: [ValueError].} =
|
||||||
# TODO: currently we always calculate txHashes as BlockObject does not have
|
# TODO: currently we always calculate txHashes as BlockObject does not have
|
||||||
|
@ -130,10 +119,10 @@ proc asBlockObject*(p: ExecutionData): BlockObject {.raises: [ValueError].} =
|
||||||
let headerSize = blockHeaderSize(p, txRoot)
|
let headerSize = blockHeaderSize(p, txRoot)
|
||||||
let blockSize = txSize + headerSize
|
let blockSize = txSize + headerSize
|
||||||
BlockObject(
|
BlockObject(
|
||||||
number: web3.BlockNumber p.blockNumber,
|
number: p.blockNumber,
|
||||||
hash: p.blockHash,
|
hash: p.blockHash,
|
||||||
parentHash: p.parentHash,
|
parentHash: p.parentHash,
|
||||||
sha3Uncles: etypes.EMPTY_UNCLE_HASH,
|
sha3Uncles: EMPTY_UNCLE_HASH,
|
||||||
logsBloom: p.logsBloom,
|
logsBloom: p.logsBloom,
|
||||||
transactionsRoot: txRoot,
|
transactionsRoot: txRoot,
|
||||||
stateRoot: p.stateRoot,
|
stateRoot: p.stateRoot,
|
||||||
|
@ -144,7 +133,7 @@ proc asBlockObject*(p: ExecutionData): BlockObject {.raises: [ValueError].} =
|
||||||
gasLimit: p.gasLimit,
|
gasLimit: p.gasLimit,
|
||||||
gasUsed: p.gasUsed,
|
gasUsed: p.gasUsed,
|
||||||
timestamp: p.timestamp,
|
timestamp: p.timestamp,
|
||||||
nonce: Opt.some(default(FixedBytes[8])),
|
nonce: Opt.some(default(Bytes8)),
|
||||||
size: Quantity(blockSize),
|
size: Quantity(blockSize),
|
||||||
# TODO: It does not matter what we put here after merge blocks.
|
# TODO: It does not matter what we put here after merge blocks.
|
||||||
# Other projects like `helios` return `0`, data providers like alchemy return
|
# Other projects like `helios` return `0`, data providers like alchemy return
|
||||||
|
|
|
@ -8,82 +8,51 @@
|
||||||
{.push raises: [].}
|
{.push raises: [].}
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[sequtils, typetraits, options],
|
std/sequtils,
|
||||||
stint,
|
stint,
|
||||||
results,
|
results,
|
||||||
nimcrypto/hash,
|
eth/common/[base_rlp, accounts_rlp, hashes_rlp],
|
||||||
eth/common/eth_types as etypes,
|
eth/trie/[hexary_proof_verification],
|
||||||
eth/common/eth_types_rlp,
|
|
||||||
eth/rlp,
|
|
||||||
eth/trie/[hexary, hexary_proof_verification],
|
|
||||||
web3/eth_api_types
|
web3/eth_api_types
|
||||||
|
|
||||||
export results
|
export results, stint, hashes_rlp, accounts_rlp, eth_api_types
|
||||||
|
|
||||||
type
|
|
||||||
FixedBytes[N: static int] = primitives.FixedBytes[N]
|
|
||||||
Address = primitives.Address
|
|
||||||
|
|
||||||
func toMDigest(arg: primitives.FixedBytes[32]): MDigest[256] =
|
|
||||||
MDigest[256](data: distinctBase(arg))
|
|
||||||
|
|
||||||
func emptyAccount(): etypes.Account =
|
|
||||||
return etypes.Account(
|
|
||||||
nonce: uint64(0),
|
|
||||||
balance: UInt256.zero,
|
|
||||||
storageRoot: etypes.EMPTY_ROOT_HASH,
|
|
||||||
codeHash: etypes.EMPTY_CODE_HASH,
|
|
||||||
)
|
|
||||||
|
|
||||||
proc isValidProof(
|
|
||||||
branch: seq[seq[byte]], rootHash: KeccakHash, key, value: seq[byte]
|
|
||||||
): bool =
|
|
||||||
try:
|
|
||||||
# TODO: Investigate if this handles proof of non-existence.
|
|
||||||
# Probably not as bool is not expressive enough to say if proof is valid,
|
|
||||||
# but key actually does not exists in MPT
|
|
||||||
return isValidBranch(branch, rootHash, key, value)
|
|
||||||
except RlpError:
|
|
||||||
return false
|
|
||||||
|
|
||||||
proc getAccountFromProof*(
|
proc getAccountFromProof*(
|
||||||
stateRoot: Hash32,
|
stateRoot: Hash32,
|
||||||
accountAddress: Address,
|
accountAddress: Address,
|
||||||
accountBalance: UInt256,
|
accountBalance: UInt256,
|
||||||
accountNonce: Quantity,
|
accountNonce: Quantity,
|
||||||
accountCodeHash: CodeHash,
|
accountCodeHash: Hash32,
|
||||||
accountStorageRootHash: StorageHash,
|
accountStorageRoot: Hash32,
|
||||||
mptNodes: seq[RlpEncodedBytes],
|
mptNodes: seq[RlpEncodedBytes],
|
||||||
): Result[etypes.Account, string] =
|
): Result[Account, string] =
|
||||||
let
|
let
|
||||||
mptNodesBytes = mptNodes.mapIt(distinctBase(it))
|
mptNodesBytes = mptNodes.mapIt(distinctBase(it))
|
||||||
keccakStateRootHash = Hash32(stateRoot)
|
acc = Account(
|
||||||
acc = etypes.Account(
|
|
||||||
nonce: distinctBase(accountNonce),
|
nonce: distinctBase(accountNonce),
|
||||||
balance: accountBalance,
|
balance: accountBalance,
|
||||||
storageRoot: Hash32(accountStorageRootHash),
|
storageRoot: accountStorageRoot,
|
||||||
codeHash: Hash32(accountCodeHash),
|
codeHash: accountCodeHash,
|
||||||
)
|
)
|
||||||
accountEncoded = rlp.encode(acc)
|
accountEncoded = rlp.encode(acc)
|
||||||
accountKey = toSeq(keccakHash(distinctBase(accountAddress)).data)
|
accountKey = toSeq(keccak256((accountAddress.data)).data)
|
||||||
|
|
||||||
let proofResult =
|
let proofResult = verifyMptProof(mptNodesBytes, stateRoot, accountKey, accountEncoded)
|
||||||
verifyMptProof(mptNodesBytes, keccakStateRootHash, accountKey, accountEncoded)
|
|
||||||
|
|
||||||
case proofResult.kind
|
case proofResult.kind
|
||||||
of MissingKey:
|
of MissingKey:
|
||||||
return ok(emptyAccount())
|
return ok(EMPTY_ACCOUNT)
|
||||||
of ValidProof:
|
of ValidProof:
|
||||||
return ok(acc)
|
return ok(acc)
|
||||||
of InvalidProof:
|
of InvalidProof:
|
||||||
return err(proofResult.errorMsg)
|
return err(proofResult.errorMsg)
|
||||||
|
|
||||||
proc getStorageData(
|
proc getStorageData(
|
||||||
account: etypes.Account, storageProof: StorageProof
|
account: Account, storageProof: StorageProof
|
||||||
): Result[UInt256, string] =
|
): Result[UInt256, string] =
|
||||||
let
|
let
|
||||||
storageMptNodes = storageProof.proof.mapIt(distinctBase(it))
|
storageMptNodes = storageProof.proof.mapIt(distinctBase(it))
|
||||||
key = toSeq(keccakHash(toBytesBE(storageProof.key)).data)
|
key = toSeq(keccak256(toBytesBE(storageProof.key)).data)
|
||||||
encodedValue = rlp.encode(storageProof.value)
|
encodedValue = rlp.encode(storageProof.value)
|
||||||
proofResult =
|
proofResult =
|
||||||
verifyMptProof(storageMptNodes, account.storageRoot, key, encodedValue)
|
verifyMptProof(storageMptNodes, account.storageRoot, key, encodedValue)
|
||||||
|
@ -105,7 +74,7 @@ proc getStorageData*(
|
||||||
proof.storageHash, proof.accountProof,
|
proof.storageHash, proof.accountProof,
|
||||||
)
|
)
|
||||||
|
|
||||||
if account.storageRoot == etypes.EMPTY_ROOT_HASH:
|
if account.storageRoot == EMPTY_ROOT_HASH:
|
||||||
# valid account with empty storage, in that case getStorageAt
|
# valid account with empty storage, in that case getStorageAt
|
||||||
# return 0 value
|
# return 0 value
|
||||||
return ok(u256(0))
|
return ok(u256(0))
|
||||||
|
@ -113,15 +82,15 @@ proc getStorageData*(
|
||||||
if len(proof.storageProof) != 1:
|
if len(proof.storageProof) != 1:
|
||||||
return err("no storage proof for requested slot")
|
return err("no storage proof for requested slot")
|
||||||
|
|
||||||
let sproof = proof.storageProof[0]
|
let storageProof = proof.storageProof[0]
|
||||||
|
|
||||||
if len(sproof.proof) == 0:
|
if len(storageProof.proof) == 0:
|
||||||
return err("empty mpt proof for account with not empty storage")
|
return err("empty mpt proof for account with not empty storage")
|
||||||
|
|
||||||
if sproof.key != requestedSlot:
|
if storageProof.key != requestedSlot:
|
||||||
return err("received proof for invalid slot")
|
return err("received proof for invalid slot")
|
||||||
|
|
||||||
return getStorageData(account, sproof)
|
getStorageData(account, storageProof)
|
||||||
|
|
||||||
func isValidCode*(account: etypes.Account, code: openArray[byte]): bool =
|
func isValidCode*(account: Account, code: openArray[byte]): bool =
|
||||||
return account.codeHash == keccakHash(code)
|
account.codeHash == keccak256(code)
|
||||||
|
|
Loading…
Reference in New Issue