Add missing fields to RPC object conversion (#2863)

* Add missing fields to RPC object conversion

* Fix populateBlockObject call

* Remove server_api_helpers.nim

* Add metric defined conditional compilation

* link with rocksdb
This commit is contained in:
andri lim 2024-11-22 17:07:53 +07:00 committed by GitHub
parent a241050c94
commit 7b2b59a976
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 134 additions and 233 deletions

View File

@ -322,17 +322,17 @@ utp-test: | build deps
# Nimbus Verified Proxy related targets # Nimbus Verified Proxy related targets
# Builds the nimbus_verified_proxy # Builds the nimbus_verified_proxy
nimbus_verified_proxy: | build deps nimbus_verified_proxy: | build deps rocksdb
echo -e $(BUILD_MSG) "build/$@" && \ echo -e $(BUILD_MSG) "build/$@" && \
$(ENV_SCRIPT) nim nimbus_verified_proxy $(NIM_PARAMS) nimbus.nims $(ENV_SCRIPT) nim nimbus_verified_proxy $(NIM_PARAMS) nimbus.nims
# builds and runs the nimbus_verified_proxy test suite # builds and runs the nimbus_verified_proxy test suite
nimbus-verified-proxy-test: | build deps nimbus-verified-proxy-test: | build deps rocksdb
$(ENV_SCRIPT) nim nimbus_verified_proxy_test $(NIM_PARAMS) nimbus.nims $(ENV_SCRIPT) nim nimbus_verified_proxy_test $(NIM_PARAMS) nimbus.nims
# Shared library for verified proxy # Shared library for verified proxy
libverifproxy: | build deps libverifproxy: | build deps rocksdb
+ echo -e $(BUILD_MSG) "build/$@" && \ + echo -e $(BUILD_MSG) "build/$@" && \
$(ENV_SCRIPT) nim --version && \ $(ENV_SCRIPT) nim --version && \
$(ENV_SCRIPT) nim c --app:lib -d:"libp2p_pki_schemes=secp256k1" --noMain:on --threads:on --nimcache:nimcache/libverifproxy -o:$(VERIF_PROXY_OUT_PATH)/$@.$(VERIF_PROXY_SHAREDLIBEXT) $(NIM_PARAMS) nimbus_verified_proxy/libverifproxy/verifproxy.nim $(ENV_SCRIPT) nim c --app:lib -d:"libp2p_pki_schemes=secp256k1" --noMain:on --threads:on --nimcache:nimcache/libverifproxy -o:$(VERIF_PROXY_OUT_PATH)/$@.$(VERIF_PROXY_SHAREDLIBEXT) $(NIM_PARAMS) nimbus_verified_proxy/libverifproxy/verifproxy.nim

View File

@ -20,7 +20,6 @@ import
../../[aristo_blobify, aristo_desc], ../../[aristo_blobify, aristo_desc],
../init_common, ../init_common,
./rdb_desc, ./rdb_desc,
metrics,
std/concurrency/atomics std/concurrency/atomics
const const
@ -34,49 +33,53 @@ when extraTraceMessages:
logScope: logScope:
topics = "aristo-rocksdb" topics = "aristo-rocksdb"
type when defined(metrics):
RdbVtxLruCounter = ref object of Counter import
RdbKeyLruCounter = ref object of Counter metrics
var type
rdbVtxLruStatsMetric {.used.} = RdbVtxLruCounter.newCollector( RdbVtxLruCounter = ref object of Counter
"aristo_rdb_vtx_lru_total", RdbKeyLruCounter = ref object of Counter
"Vertex LRU lookup (hit/miss, world/account, branch/leaf)",
labels = ["state", "vtype", "hit"], var
) rdbVtxLruStatsMetric {.used.} = RdbVtxLruCounter.newCollector(
rdbKeyLruStatsMetric {.used.} = RdbKeyLruCounter.newCollector( "aristo_rdb_vtx_lru_total",
"aristo_rdb_key_lru_total", "HashKey LRU lookup", labels = ["state", "hit"] "Vertex LRU lookup (hit/miss, world/account, branch/leaf)",
) labels = ["state", "vtype", "hit"],
)
method collect*(collector: RdbVtxLruCounter, output: MetricHandler) = rdbKeyLruStatsMetric {.used.} = RdbKeyLruCounter.newCollector(
let timestamp = collector.now() "aristo_rdb_key_lru_total", "HashKey LRU lookup", labels = ["state", "hit"]
)
# We don't care about synchronization between each type of metric or between
# the metrics thread and others since small differences like this don't matter method collect*(collector: RdbVtxLruCounter, output: MetricHandler) =
for state in RdbStateType: let timestamp = collector.now()
for vtype in VertexType:
# We don't care about synchronization between each type of metric or between
# the metrics thread and others since small differences like this don't matter
for state in RdbStateType:
for vtype in VertexType:
for hit in [false, true]:
output(
name = "aristo_rdb_vtx_lru_total",
value = float64(rdbVtxLruStats[state][vtype].get(hit)),
labels = ["state", "vtype", "hit"],
labelValues = [$state, $vtype, $ord(hit)],
timestamp = timestamp,
)
method collect*(collector: RdbKeyLruCounter, output: MetricHandler) =
let timestamp = collector.now()
for state in RdbStateType:
for hit in [false, true]: for hit in [false, true]:
output( output(
name = "aristo_rdb_vtx_lru_total", name = "aristo_rdb_key_lru_total",
value = float64(rdbVtxLruStats[state][vtype].get(hit)), value = float64(rdbKeyLruStats[state].get(hit)),
labels = ["state", "vtype", "hit"], labels = ["state", "hit"],
labelValues = [$state, $vtype, $ord(hit)], labelValues = [$state, $ord(hit)],
timestamp = timestamp, timestamp = timestamp,
) )
method collect*(collector: RdbKeyLruCounter, output: MetricHandler) =
let timestamp = collector.now()
for state in RdbStateType:
for hit in [false, true]:
output(
name = "aristo_rdb_key_lru_total",
value = float64(rdbKeyLruStats[state].get(hit)),
labels = ["state", "hit"],
labelValues = [$state, $ord(hit)],
timestamp = timestamp,
)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Public functions # Public functions
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@ -54,7 +54,7 @@ proc calculateMedianGasPrice*(chain: CoreDbRef): GasInt {.raises: [RlpError].} =
# For compatibility with `ethpandaops/ethereum-package`, set this to a # For compatibility with `ethpandaops/ethereum-package`, set this to a
# sane minimum for compatibility to unblock testing. # sane minimum for compatibility to unblock testing.
# Note: When this is fixed, update `tests/graphql/queries.toml` and # Note: When this is fixed, update `tests/graphql/queries.toml` and
# re-enable the "query.gasPrice" test case (remove `skip = true`). # re-enable the "query.gasPrice" test case (remove `skip = true`).
result = max(result, minGasPrice) result = max(result, minGasPrice)
proc unsignedTx*(tx: TransactionArgs, chain: CoreDbRef, defaultNonce: AccountNonce, chainId: ChainId): Transaction proc unsignedTx*(tx: TransactionArgs, chain: CoreDbRef, defaultNonce: AccountNonce, chainId: ChainId): Transaction
@ -92,112 +92,126 @@ proc unsignedTx*(tx: TransactionArgs, chain: CoreDbRef, defaultNonce: AccountNon
proc toWd(wd: Withdrawal): WithdrawalObject = proc toWd(wd: Withdrawal): WithdrawalObject =
WithdrawalObject( WithdrawalObject(
index: Quantity wd.index, index: Quantity(wd.index),
validatorIndex: Quantity wd.validatorIndex, validatorIndex: Quantity wd.validatorIndex,
address: wd.address, address: wd.address,
amount: Quantity wd.amount, amount: Quantity wd.amount,
) )
proc toWdList(list: openArray[Withdrawal]): seq[WithdrawalObject] = proc toWdList(list: openArray[Withdrawal]): seq[WithdrawalObject] =
var res = newSeqOfCap[WithdrawalObject](list.len) result = newSeqOfCap[WithdrawalObject](list.len)
for x in list: for x in list:
res.add toWd(x) result.add toWd(x)
return res
func toWdList(x: Opt[seq[eth_types.Withdrawal]]): func toWdList(x: Opt[seq[Withdrawal]]):
Opt[seq[WithdrawalObject]] = Opt[seq[WithdrawalObject]] =
if x.isNone: Opt.none(seq[WithdrawalObject]) if x.isNone: Opt.none(seq[WithdrawalObject])
else: Opt.some(toWdList x.get) else: Opt.some(toWdList x.get)
func toAuth*(x: Authorization): AuthorizationObject =
AuthorizationObject(
chainId: Quantity(x.chainId),
address: x.address,
nonce: Quantity(x.nonce),
v: Quantity(x.v),
r: x.r,
s: x.s,
)
proc toAuthList(list: openArray[Authorization]): seq[AuthorizationObject] =
result = newSeqOfCap[AuthorizationObject](list.len)
for x in list:
result.add toAuth(x)
proc populateTransactionObject*(tx: Transaction, proc populateTransactionObject*(tx: Transaction,
optionalHash: Opt[eth_types.Hash32] = Opt.none(eth_types.Hash32), optionalHash: Opt[eth_types.Hash32] = Opt.none(eth_types.Hash32),
optionalNumber: Opt[eth_types.BlockNumber] = Opt.none(eth_types.BlockNumber), optionalNumber: Opt[eth_types.BlockNumber] = Opt.none(eth_types.BlockNumber),
txIndex: Opt[uint64] = Opt.none(uint64)): TransactionObject = txIndex: Opt[uint64] = Opt.none(uint64)): TransactionObject =
var res = TransactionObject() result = TransactionObject()
res.`type` = Opt.some Quantity(tx.txType) result.`type` = Opt.some Quantity(tx.txType)
res.blockHash = optionalHash result.blockHash = optionalHash
res.blockNumber = w3Qty(optionalNumber) result.blockNumber = w3Qty(optionalNumber)
if (let sender = tx.recoverSender(); sender.isOk): if (let sender = tx.recoverSender(); sender.isOk):
res.`from` = sender[] result.`from` = sender[]
res.gas = Quantity(tx.gasLimit) result.gas = Quantity(tx.gasLimit)
res.gasPrice = Quantity(tx.gasPrice) result.gasPrice = Quantity(tx.gasPrice)
res.hash = tx.rlpHash result.hash = tx.rlpHash
res.input = tx.payload result.input = tx.payload
res.nonce = Quantity(tx.nonce) result.nonce = Quantity(tx.nonce)
res.to = Opt.some(tx.destination) result.to = Opt.some(tx.destination)
if txIndex.isSome: if txIndex.isSome:
res.transactionIndex = Opt.some(Quantity(txIndex.get)) result.transactionIndex = Opt.some(Quantity(txIndex.get))
res.value = tx.value result.value = tx.value
res.v = Quantity(tx.V) result.v = Quantity(tx.V)
res.r = tx.R result.r = tx.R
res.s = tx.S result.s = tx.S
res.maxFeePerGas = Opt.some Quantity(tx.maxFeePerGas) result.maxFeePerGas = Opt.some Quantity(tx.maxFeePerGas)
res.maxPriorityFeePerGas = Opt.some Quantity(tx.maxPriorityFeePerGas) result.maxPriorityFeePerGas = Opt.some Quantity(tx.maxPriorityFeePerGas)
if tx.txType >= TxEip2930: if tx.txType >= TxEip2930:
res.chainId = Opt.some(Quantity(tx.chainId)) result.chainId = Opt.some(Quantity(tx.chainId))
res.accessList = Opt.some(tx.accessList) result.accessList = Opt.some(tx.accessList)
if tx.txType >= TxEip4844: if tx.txType >= TxEip4844:
res.maxFeePerBlobGas = Opt.some(tx.maxFeePerBlobGas) result.maxFeePerBlobGas = Opt.some(tx.maxFeePerBlobGas)
res.blobVersionedHashes = Opt.some(tx.versionedHashes) result.blobVersionedHashes = Opt.some(tx.versionedHashes)
return res if tx.txType >= TxEip7702:
result.authorizationList = Opt.some(toAuthList(tx.authorizationList))
proc populateBlockObject*(blockHash: Hash32, proc populateBlockObject*(blockHash: eth_types.Hash32,
blk: Block, blk: Block,
totalDifficulty: UInt256, totalDifficulty: UInt256,
fullTx: bool, fullTx: bool,
isUncle = false): BlockObject = withUncles: bool = false): BlockObject =
template header: auto = blk.header template header: auto = blk.header
var res = BlockObject() result = BlockObject()
res.number = Quantity(header.number) result.number = Quantity(header.number)
res.hash = blockHash result.hash = blockHash
res.parentHash = header.parentHash result.parentHash = header.parentHash
res.nonce = Opt.some(header.nonce) result.nonce = Opt.some(header.nonce)
res.sha3Uncles = header.ommersHash result.sha3Uncles = header.ommersHash
res.logsBloom = header.logsBloom result.logsBloom = header.logsBloom
res.transactionsRoot = header.txRoot result.transactionsRoot = header.txRoot
res.stateRoot = header.stateRoot result.stateRoot = header.stateRoot
res.receiptsRoot = header.receiptsRoot result.receiptsRoot = header.receiptsRoot
res.miner = header.coinbase result.miner = header.coinbase
res.difficulty = header.difficulty result.difficulty = header.difficulty
res.extraData = HistoricExtraData header.extraData result.extraData = HistoricExtraData header.extraData
res.mixHash = Hash32 header.mixHash result.mixHash = Hash32 header.mixHash
# discard sizeof(seq[byte]) of extraData and use actual length # discard sizeof(seq[byte]) of extraData and use actual length
let size = sizeof(Header) - sizeof(seq[byte]) + header.extraData.len let size = sizeof(eth_types.Header) - sizeof(eth_api_types.Blob) + header.extraData.len
res.size = Quantity(size) result.size = Quantity(size)
res.gasLimit = Quantity(header.gasLimit) result.gasLimit = Quantity(header.gasLimit)
res.gasUsed = Quantity(header.gasUsed) result.gasUsed = Quantity(header.gasUsed)
res.timestamp = Quantity(header.timestamp) result.timestamp = Quantity(header.timestamp)
res.baseFeePerGas = header.baseFeePerGas result.baseFeePerGas = header.baseFeePerGas
res.totalDifficulty = totalDifficulty result.totalDifficulty = totalDifficulty
if not isUncle: if not withUncles:
res.uncles = blk.uncles.mapIt(it.blockHash) result.uncles = blk.uncles.mapIt(it.blockHash)
if fullTx: if fullTx:
for i, tx in blk.transactions: for i, tx in blk.transactions:
let txObj = populateTransactionObject(tx, let txObj = populateTransactionObject(tx,
Opt.some(blockHash), Opt.some(blockHash),
Opt.some(header.number), Opt.some(i.uint64)) Opt.some(header.number), Opt.some(i.uint64))
res.transactions.add txOrHash(txObj) result.transactions.add txOrHash(txObj)
else: else:
for i, tx in blk.transactions: for i, tx in blk.transactions:
let txHash = rlpHash(tx) let txHash = rlpHash(tx)
res.transactions.add txOrHash(txHash) result.transactions.add txOrHash(txHash)
res.withdrawalsRoot = header.withdrawalsRoot result.withdrawalsRoot = header.withdrawalsRoot
res.withdrawals = toWdList blk.withdrawals result.withdrawals = toWdList blk.withdrawals
res.parentBeaconBlockRoot = header.parentBeaconBlockRoot result.parentBeaconBlockRoot = header.parentBeaconBlockRoot
res.blobGasUsed = w3Qty(header.blobGasUsed) result.blobGasUsed = w3Qty(header.blobGasUsed)
res.excessBlobGas = w3Qty(header.excessBlobGas) result.excessBlobGas = w3Qty(header.excessBlobGas)
result.requestsHash = header.requestsHash
return res
proc populateReceipt*(receipt: Receipt, gasUsed: GasInt, tx: Transaction, proc populateReceipt*(receipt: Receipt, gasUsed: GasInt, tx: Transaction,
txIndex: uint64, header: Header): ReceiptObject = txIndex: uint64, header: Header): ReceiptObject =

View File

@ -1,116 +0,0 @@
# Nimbus
# Copyright (c) 2024 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
# at your option.
# This file may not be copied, modified, or distributed except according to
# those terms.
{.push raises: [].}
import
eth/common/[eth_types, eth_types_rlp, transaction_utils],
web3/eth_api_types,
../constants,
../transaction
from ../beacon/web3_eth_conv import w3Qty
proc toWd(wd: eth_types.Withdrawal): WithdrawalObject =
WithdrawalObject(
index: Quantity(wd.index),
validatorIndex: Quantity wd.validatorIndex,
address: wd.address,
amount: Quantity wd.amount,
)
proc toWdList(list: openArray[eth_types.Withdrawal]): seq[WithdrawalObject] =
result = newSeqOfCap[WithdrawalObject](list.len)
for x in list:
result.add toWd(x)
func toWdList(x: Opt[seq[eth_types.Withdrawal]]):
Opt[seq[WithdrawalObject]] =
if x.isNone: Opt.none(seq[WithdrawalObject])
else: Opt.some(toWdList x.get)
proc populateTransactionObject*(tx: Transaction,
optionalHash: Opt[eth_types.Hash32] = Opt.none(eth_types.Hash32),
optionalNumber: Opt[eth_types.BlockNumber] = Opt.none(eth_types.BlockNumber),
txIndex: Opt[uint64] = Opt.none(uint64)): TransactionObject =
result = TransactionObject()
result.`type` = Opt.some Quantity(tx.txType)
result.blockHash = optionalHash
result.blockNumber = w3Qty(optionalNumber)
if (let sender = tx.recoverSender(); sender.isOk):
result.`from` = sender[]
result.gas = Quantity(tx.gasLimit)
result.gasPrice = Quantity(tx.gasPrice)
result.hash = tx.rlpHash
result.input = tx.payload
result.nonce = Quantity(tx.nonce)
result.to = Opt.some(tx.destination)
if txIndex.isSome:
result.transactionIndex = Opt.some(Quantity(txIndex.get))
result.value = tx.value
result.v = Quantity(tx.V)
result.r = tx.R
result.s = tx.S
result.maxFeePerGas = Opt.some Quantity(tx.maxFeePerGas)
result.maxPriorityFeePerGas = Opt.some Quantity(tx.maxPriorityFeePerGas)
if tx.txType >= TxEip2930:
result.chainId = Opt.some(Quantity(tx.chainId))
result.accessList = Opt.some(tx.accessList)
if tx.txType >= TxEip4844:
result.maxFeePerBlobGas = Opt.some(tx.maxFeePerBlobGas)
result.blobVersionedHashes = Opt.some(tx.versionedHashes)
proc populateBlockObject*(blockHash: eth_types.Hash32,
blk: Block,
fullTx: bool): BlockObject =
template header: auto = blk.header
result = BlockObject()
result.number = Quantity(header.number)
result.hash = blockHash
result.parentHash = header.parentHash
result.nonce = Opt.some(header.nonce)
result.sha3Uncles = header.ommersHash
result.logsBloom = header.logsBloom
result.transactionsRoot = header.txRoot
result.stateRoot = header.stateRoot
result.receiptsRoot = header.receiptsRoot
result.miner = header.coinbase
result.difficulty = header.difficulty
result.extraData = HistoricExtraData header.extraData
result.mixHash = Hash32 header.mixHash
# discard sizeof(seq[byte]) of extraData and use actual length
let size = sizeof(eth_types.Header) - sizeof(eth_api_types.Blob) + header.extraData.len
result.size = Quantity(size)
result.gasLimit = Quantity(header.gasLimit)
result.gasUsed = Quantity(header.gasUsed)
result.timestamp = Quantity(header.timestamp)
result.baseFeePerGas = header.baseFeePerGas
if fullTx:
for i, tx in blk.transactions:
let txObj = populateTransactionObject(tx,
Opt.some(blockHash),
Opt.some(header.number), Opt.some(i.uint64))
result.transactions.add txOrHash(txObj)
else:
for i, tx in blk.transactions:
let txHash = rlpHash(tx)
result.transactions.add txOrHash(txHash)
result.withdrawalsRoot = header.withdrawalsRoot
result.withdrawals = toWdList blk.withdrawals
result.parentBeaconBlockRoot = header.parentBeaconBlockRoot
result.blobGasUsed = w3Qty(header.blobGasUsed)
result.excessBlobGas = w3Qty(header.excessBlobGas)

View File

@ -6,7 +6,7 @@
# at your option. This file may not be copied, modified, or distributed except according to those terms. # at your option. This file may not be copied, modified, or distributed except according to those terms.
import import
std/[atomics, json, os, strutils, net], std/[atomics, json, strutils, net],
../nimbus_verified_proxy, ../nimbus_verified_proxy,
../nimbus_verified_proxy_conf ../nimbus_verified_proxy_conf

View File

@ -21,7 +21,7 @@ import
beacon_chain/spec/beaconstate, beacon_chain/spec/beaconstate,
beacon_chain/spec/datatypes/[phase0, altair, bellatrix], beacon_chain/spec/datatypes/[phase0, altair, bellatrix],
beacon_chain/[light_client, nimbus_binary_common, version], beacon_chain/[light_client, nimbus_binary_common, version],
../nimbus/rpc/[cors, server_api_helpers], ../nimbus/rpc/[cors, rpc_utils],
../nimbus/beacon/payload_conv, ../nimbus/beacon/payload_conv,
./rpc/rpc_eth_api, ./rpc/rpc_eth_api,
./nimbus_verified_proxy_conf, ./nimbus_verified_proxy_conf,
@ -147,7 +147,7 @@ proc run*(
parentBeaconBlockRoot = Opt.none(Hash32), parentBeaconBlockRoot = Opt.none(Hash32),
requestsHash = Opt.none(Hash32), requestsHash = Opt.none(Hash32),
) )
blockCache.add(populateBlockObject(blk.header.rlpHash, blk, true)) blockCache.add(populateBlockObject(blk.header.rlpHash, blk, 0.u256, true))
except RlpError as exc: except RlpError as exc:
debug "Invalid block received", err = exc.msg debug "Invalid block received", err = exc.msg

2
vendor/nim-web3 vendored

@ -1 +1 @@
Subproject commit 40854fb51fd444b7537da767800fbca2189eb2b7 Subproject commit ff92d2877985faee5ac6abc3bea805b85f2be1c8