More clean-up since eth types refactor (#2742)

This commit is contained in:
Kim De Mey 2024-10-16 14:18:02 +02:00 committed by GitHub
parent f797d55c35
commit b885f822d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 63 additions and 112 deletions

View File

@ -10,6 +10,7 @@
import
chronos,
testutils/unittests,
stew/byteutils,
json_rpc/rpcserver,
json_rpc/clients/httpclient,
stint,
@ -67,6 +68,6 @@ procSuite "Discovery v5 JSON-RPC API":
check:
nodeEnr == tc.localDiscovery.localNode.record.toURI()
nodeId == "0x" & tc.localDiscovery.localNode.id.toHex()
nodeId == tc.localDiscovery.localNode.id.toBytesBE().to0xHex()
waitFor tc.stop()

View File

@ -79,9 +79,9 @@ func asReceipt(receiptObject: ReceiptObject): Result[Receipt, string] =
var logs: seq[Log]
if receiptObject.logs.len > 0:
for log in receiptObject.logs:
var topics: seq[eth_types.Topic]
var topics: seq[Topic]
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))

View File

@ -12,7 +12,7 @@ import
chronos,
json_rpc/rpcclient,
stew/byteutils,
eth/keys,
eth/common/keys,
./utp_test_rpc_client
proc generateBytesHex(rng: var HmacDrbgContext, length: int): string =

View File

@ -17,7 +17,7 @@ import
eth/p2p/discoveryv5/protocol,
eth/p2p/discoveryv5/enr,
eth/utp/[utp_discv5_protocol, utp_router],
eth/keys,
eth/common/keys,
../../rpc/rpc_discovery_api,
./utp_rpc_types
@ -46,7 +46,7 @@ proc writeValue*(w: var JsonWriter[JrpcConv], v: Record) {.gcsafe, raises: [IOEr
proc readValue*(
r: var JsonReader[JrpcConv], val: var Record
) {.gcsafe, raises: [IOError, JsonReaderError].} =
if not fromURI(val, r.parseString()):
val = enr.Record.fromURI(r.parseString()).valueOr:
r.raiseUnexpectedValue("Invalid ENR")
proc installUtpHandlers(

View File

@ -7,7 +7,7 @@
{.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
## consensus light client.
@ -15,15 +15,14 @@ import std/tables, web3/primitives, stew/keyed_queue, results, ./rpc/rpc_utils
## oldest payload is deleted first.
type BlockCache* = ref object
max: int
blocks: KeyedQueue[BlockHash, ExecutionData]
blocks: KeyedQueue[Hash32, ExecutionData]
proc `==`(x, y: Quantity): bool {.borrow, noSideEffect.}
proc new*(T: type BlockCache, max: uint32): T =
let maxAsInt = int(max)
return BlockCache(
max: maxAsInt, blocks: KeyedQueue[BlockHash, ExecutionData].init(maxAsInt)
)
return
BlockCache(max: maxAsInt, blocks: KeyedQueue[Hash32, ExecutionData].init(maxAsInt))
func len*(self: BlockCache): int =
return len(self.blocks)
@ -54,5 +53,5 @@ proc getByNumber*(self: BlockCache, number: Quantity): Opt[ExecutionData] =
return payloadResult
proc getPayloadByHash*(self: BlockCache, hash: BlockHash): Opt[ExecutionData] =
proc getPayloadByHash*(self: BlockCache, hash: Hash32): Opt[ExecutionData] =
return self.blocks.eq(hash)

View File

@ -200,7 +200,7 @@ proc run*(
try:
headerCallback(cstring(Json.encode(forkyHeader)), 0)
except SerializationError as e:
notice "finalizedHeaderCallback exception"
error "finalizedHeaderCallback exception", error = e.msg
proc onOptimisticHeader(
lightClient: LightClient, optimisticHeader: ForkedLightClientHeader
@ -212,7 +212,7 @@ proc run*(
try:
headerCallback(cstring(Json.encode(forkyHeader)), 1)
except SerializationError as e:
notice "optimisticHeaderCallback exception"
error "optimisticHeaderCallback exception", error = e.msg
lightClient.onFinalizedHeader = onFinalizedHeader
lightClient.onOptimisticHeader = onOptimisticHeader

View File

@ -8,15 +8,14 @@
{.push raises: [].}
import
std/[strutils, typetraits],
std/strutils,
stint,
stew/byteutils,
results,
chronicles,
json_rpc/[rpcproxy, rpcserver, rpcclient],
eth/common/eth_types as etypes,
web3,
web3/[primitives, eth_api_types],
eth/common/accounts,
web3/[primitives, eth_api_types, eth_api],
beacon_chain/el/el_manager,
beacon_chain/networking/network_metadata,
beacon_chain/spec/forks,
@ -26,15 +25,9 @@ import
export forks
type
FixedBytes[N: static int] = primitives.FixedBytes[N]
Address = primitives.Address
logScope:
topics = "verified_proxy"
proc `==`(x, y: Quantity): bool {.borrow, noSideEffect.}
type
VerifiedRpcProxy* = ref object
proxy: RpcProxy
@ -63,7 +56,7 @@ func parseQuantityTag(blockTag: BlockTag): Result[QuantityTag, string] =
else:
return err("Unsupported blockTag: " & tag)
else:
let quantity = blockTag.number.Quantity
let quantity = blockTag.number
return ok(QuantityTag(kind: BlockNumber, blockNumber: quantity))
template checkPreconditions(proxy: VerifiedRpcProxy) =
@ -197,7 +190,7 @@ proc installEthApiHandlers*(lcProxy: VerifiedRpcProxy) =
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
return @[]
@ -233,7 +226,7 @@ proc installEthApiHandlers*(lcProxy: VerifiedRpcProxy) =
return Opt.some(asBlockObject(executionPayload.get()))
lcProxy.proxy.rpc("eth_getBlockByHash") do(
blockHash: BlockHash, fullTransactions: bool
blockHash: Hash32, fullTransactions: bool
) -> Opt[BlockObject]:
let executionPayload = lcProxy.blockCache.getPayloadByHash(blockHash)

View File

@ -8,24 +8,19 @@
{.push raises: [].}
import
std/typetraits,
eth/common/eth_types as etypes,
eth/rlp,
nimcrypto/hash,
eth/common/[base_rlp, headers_rlp, blocks, hashes],
stint,
web3,
web3/eth_api_types,
web3/engine_api_types,
../../nimbus/db/core_db
type
FixedBytes[N: static int] = primitives.FixedBytes[N]
Address = primitives.Address
export eth_api_types, engine_api_types
type ExecutionData* = object
parentHash*: BlockHash
parentHash*: Hash32
feeRecipient*: Address
stateRoot*: BlockHash
receiptsRoot*: BlockHash
stateRoot*: Hash32
receiptsRoot*: Hash32
logsBloom*: FixedBytes[256]
prevRandao*: FixedBytes[32]
blockNumber*: Quantity
@ -34,7 +29,7 @@ type ExecutionData* = object
timestamp*: Quantity
extraData*: DynamicBytes[0, 32]
baseFeePerGas*: UInt256
blockHash*: BlockHash
blockHash*: Hash32
transactions*: seq[TypedTransaction]
withdrawals*: seq[WithdrawalV1]
@ -77,15 +72,9 @@ proc asExecutionData*(payload: SomeExecutionPayload): ExecutionData =
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(
items: openArray[TypedTransaction]
): (etypes.Hash32, seq[TxOrHash], uint64) =
): (Hash32, seq[TxOrHash], uint64) =
## returns tuple composed of
## - root of transactions trie
## - list of transactions hashes
@ -97,30 +86,30 @@ proc calculateTransactionData(
let tx = distinctBase(t)
txSize = txSize + uint64(len(tx))
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"
(rootHash, txHashes, txSize)
func blockHeaderSize(payload: ExecutionData, txRoot: etypes.Hash32): uint64 =
let bh = etypes.BlockHeader(
func blockHeaderSize(payload: ExecutionData, txRoot: Hash32): uint64 =
let header = Header(
parentHash: payload.parentHash,
ommersHash: etypes.EMPTY_UNCLE_HASH,
ommersHash: EMPTY_UNCLE_HASH,
coinbase: payload.feeRecipient,
stateRoot: payload.stateRoot,
transactionsRoot: txRoot,
receiptsRoot: payload.receiptsRoot,
logsBloom: distinctBase(payload.logsBloom).to(Bloom),
difficulty: default(etypes.DifficultyInt),
number: payload.blockNumber.distinctBase,
logsBloom: payload.logsBloom,
difficulty: default(DifficultyInt),
number: distinctBase(payload.blockNumber),
gasLimit: distinctBase(payload.gasLimit),
gasUsed: distinctBase(payload.gasUsed),
timestamp: payload.timestamp.EthTime,
extraData: bytes payload.extraData,
extraData: payload.extraData.data,
mixHash: payload.prevRandao,
nonce: default(etypes.BlockNonce),
nonce: default(Bytes8),
baseFeePerGas: Opt.some payload.baseFeePerGas,
)
return uint64(len(rlp.encode(bh)))
return uint64(len(rlp.encode(header)))
proc asBlockObject*(p: ExecutionData): BlockObject {.raises: [ValueError].} =
# 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 blockSize = txSize + headerSize
BlockObject(
number: web3.BlockNumber p.blockNumber,
number: p.blockNumber,
hash: p.blockHash,
parentHash: p.parentHash,
sha3Uncles: etypes.EMPTY_UNCLE_HASH,
sha3Uncles: EMPTY_UNCLE_HASH,
logsBloom: p.logsBloom,
transactionsRoot: txRoot,
stateRoot: p.stateRoot,
@ -144,7 +133,7 @@ proc asBlockObject*(p: ExecutionData): BlockObject {.raises: [ValueError].} =
gasLimit: p.gasLimit,
gasUsed: p.gasUsed,
timestamp: p.timestamp,
nonce: Opt.some(default(FixedBytes[8])),
nonce: Opt.some(default(Bytes8)),
size: Quantity(blockSize),
# TODO: It does not matter what we put here after merge blocks.
# Other projects like `helios` return `0`, data providers like alchemy return

View File

@ -8,82 +8,51 @@
{.push raises: [].}
import
std/[sequtils, typetraits, options],
std/sequtils,
stint,
results,
nimcrypto/hash,
eth/common/eth_types as etypes,
eth/common/eth_types_rlp,
eth/rlp,
eth/trie/[hexary, hexary_proof_verification],
eth/common/[base_rlp, accounts_rlp, hashes_rlp],
eth/trie/[hexary_proof_verification],
web3/eth_api_types
export results
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
export results, stint, hashes_rlp, accounts_rlp, eth_api_types
proc getAccountFromProof*(
stateRoot: Hash32,
accountAddress: Address,
accountBalance: UInt256,
accountNonce: Quantity,
accountCodeHash: CodeHash,
accountStorageRootHash: StorageHash,
accountCodeHash: Hash32,
accountStorageRoot: Hash32,
mptNodes: seq[RlpEncodedBytes],
): Result[etypes.Account, string] =
): Result[Account, string] =
let
mptNodesBytes = mptNodes.mapIt(distinctBase(it))
keccakStateRootHash = Hash32(stateRoot)
acc = etypes.Account(
acc = Account(
nonce: distinctBase(accountNonce),
balance: accountBalance,
storageRoot: Hash32(accountStorageRootHash),
codeHash: Hash32(accountCodeHash),
storageRoot: accountStorageRoot,
codeHash: accountCodeHash,
)
accountEncoded = rlp.encode(acc)
accountKey = toSeq(keccakHash(distinctBase(accountAddress)).data)
accountKey = toSeq(keccak256((accountAddress.data)).data)
let proofResult =
verifyMptProof(mptNodesBytes, keccakStateRootHash, accountKey, accountEncoded)
let proofResult = verifyMptProof(mptNodesBytes, stateRoot, accountKey, accountEncoded)
case proofResult.kind
of MissingKey:
return ok(emptyAccount())
return ok(EMPTY_ACCOUNT)
of ValidProof:
return ok(acc)
of InvalidProof:
return err(proofResult.errorMsg)
proc getStorageData(
account: etypes.Account, storageProof: StorageProof
account: Account, storageProof: StorageProof
): Result[UInt256, string] =
let
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)
proofResult =
verifyMptProof(storageMptNodes, account.storageRoot, key, encodedValue)
@ -105,7 +74,7 @@ proc getStorageData*(
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
# return 0 value
return ok(u256(0))
@ -113,15 +82,15 @@ proc getStorageData*(
if len(proof.storageProof) != 1:
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")
if sproof.key != requestedSlot:
if storageProof.key != requestedSlot:
return err("received proof for invalid slot")
return getStorageData(account, sproof)
getStorageData(account, storageProof)
func isValidCode*(account: etypes.Account, code: openArray[byte]): bool =
return account.codeHash == keccakHash(code)
func isValidCode*(account: Account, code: openArray[byte]): bool =
account.codeHash == keccak256(code)