diff --git a/Makefile b/Makefile index 533caa66f..da60ef7b6 100644 --- a/Makefile +++ b/Makefile @@ -322,17 +322,17 @@ utp-test: | build deps # Nimbus Verified Proxy related targets # Builds the nimbus_verified_proxy -nimbus_verified_proxy: | build deps +nimbus_verified_proxy: | build deps rocksdb echo -e $(BUILD_MSG) "build/$@" && \ $(ENV_SCRIPT) nim nimbus_verified_proxy $(NIM_PARAMS) nimbus.nims # 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 # Shared library for verified proxy -libverifproxy: | build deps +libverifproxy: | build deps rocksdb + echo -e $(BUILD_MSG) "build/$@" && \ $(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 diff --git a/nimbus/db/aristo/aristo_init/rocks_db/rdb_get.nim b/nimbus/db/aristo/aristo_init/rocks_db/rdb_get.nim index b784c69d7..aa0914d42 100644 --- a/nimbus/db/aristo/aristo_init/rocks_db/rdb_get.nim +++ b/nimbus/db/aristo/aristo_init/rocks_db/rdb_get.nim @@ -20,7 +20,6 @@ import ../../[aristo_blobify, aristo_desc], ../init_common, ./rdb_desc, - metrics, std/concurrency/atomics const @@ -34,49 +33,53 @@ when extraTraceMessages: logScope: topics = "aristo-rocksdb" -type - RdbVtxLruCounter = ref object of Counter - RdbKeyLruCounter = ref object of Counter - -var - rdbVtxLruStatsMetric {.used.} = RdbVtxLruCounter.newCollector( - "aristo_rdb_vtx_lru_total", - "Vertex LRU lookup (hit/miss, world/account, branch/leaf)", - labels = ["state", "vtype", "hit"], - ) - rdbKeyLruStatsMetric {.used.} = RdbKeyLruCounter.newCollector( - "aristo_rdb_key_lru_total", "HashKey LRU lookup", labels = ["state", "hit"] - ) - -method collect*(collector: RdbVtxLruCounter, output: MetricHandler) = - let timestamp = collector.now() - - # 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: +when defined(metrics): + import + metrics + + type + RdbVtxLruCounter = ref object of Counter + RdbKeyLruCounter = ref object of Counter + + var + rdbVtxLruStatsMetric {.used.} = RdbVtxLruCounter.newCollector( + "aristo_rdb_vtx_lru_total", + "Vertex LRU lookup (hit/miss, world/account, branch/leaf)", + labels = ["state", "vtype", "hit"], + ) + rdbKeyLruStatsMetric {.used.} = RdbKeyLruCounter.newCollector( + "aristo_rdb_key_lru_total", "HashKey LRU lookup", labels = ["state", "hit"] + ) + + method collect*(collector: RdbVtxLruCounter, output: MetricHandler) = + let timestamp = collector.now() + + # 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]: output( - name = "aristo_rdb_vtx_lru_total", - value = float64(rdbVtxLruStats[state][vtype].get(hit)), - labels = ["state", "vtype", "hit"], - labelValues = [$state, $vtype, $ord(hit)], + name = "aristo_rdb_key_lru_total", + value = float64(rdbKeyLruStats[state].get(hit)), + labels = ["state", "hit"], + labelValues = [$state, $ord(hit)], 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 # ------------------------------------------------------------------------------ diff --git a/nimbus/rpc/rpc_utils.nim b/nimbus/rpc/rpc_utils.nim index ff8958b3a..54bf90f67 100644 --- a/nimbus/rpc/rpc_utils.nim +++ b/nimbus/rpc/rpc_utils.nim @@ -54,7 +54,7 @@ proc calculateMedianGasPrice*(chain: CoreDbRef): GasInt {.raises: [RlpError].} = # For compatibility with `ethpandaops/ethereum-package`, set this to a # sane minimum for compatibility to unblock testing. # 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) 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 = WithdrawalObject( - index: Quantity wd.index, + index: Quantity(wd.index), validatorIndex: Quantity wd.validatorIndex, address: wd.address, amount: Quantity wd.amount, ) proc toWdList(list: openArray[Withdrawal]): seq[WithdrawalObject] = - var res = newSeqOfCap[WithdrawalObject](list.len) + result = newSeqOfCap[WithdrawalObject](list.len) for x in list: - res.add toWd(x) - return res + result.add toWd(x) -func toWdList(x: Opt[seq[eth_types.Withdrawal]]): +func toWdList(x: Opt[seq[Withdrawal]]): Opt[seq[WithdrawalObject]] = if x.isNone: Opt.none(seq[WithdrawalObject]) 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, 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 = - var res = TransactionObject() - res.`type` = Opt.some Quantity(tx.txType) - res.blockHash = optionalHash - res.blockNumber = w3Qty(optionalNumber) + result = TransactionObject() + result.`type` = Opt.some Quantity(tx.txType) + result.blockHash = optionalHash + result.blockNumber = w3Qty(optionalNumber) if (let sender = tx.recoverSender(); sender.isOk): - res.`from` = sender[] - res.gas = Quantity(tx.gasLimit) - res.gasPrice = Quantity(tx.gasPrice) - res.hash = tx.rlpHash - res.input = tx.payload - res.nonce = Quantity(tx.nonce) - res.to = Opt.some(tx.destination) + 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: - res.transactionIndex = Opt.some(Quantity(txIndex.get)) - res.value = tx.value - res.v = Quantity(tx.V) - res.r = tx.R - res.s = tx.S - res.maxFeePerGas = Opt.some Quantity(tx.maxFeePerGas) - res.maxPriorityFeePerGas = Opt.some Quantity(tx.maxPriorityFeePerGas) + 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: - res.chainId = Opt.some(Quantity(tx.chainId)) - res.accessList = Opt.some(tx.accessList) + result.chainId = Opt.some(Quantity(tx.chainId)) + result.accessList = Opt.some(tx.accessList) if tx.txType >= TxEip4844: - res.maxFeePerBlobGas = Opt.some(tx.maxFeePerBlobGas) - res.blobVersionedHashes = Opt.some(tx.versionedHashes) + result.maxFeePerBlobGas = Opt.some(tx.maxFeePerBlobGas) + 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, totalDifficulty: UInt256, fullTx: bool, - isUncle = false): BlockObject = + withUncles: bool = false): BlockObject = template header: auto = blk.header - var res = BlockObject() - res.number = Quantity(header.number) - res.hash = blockHash - res.parentHash = header.parentHash - res.nonce = Opt.some(header.nonce) - res.sha3Uncles = header.ommersHash - res.logsBloom = header.logsBloom - res.transactionsRoot = header.txRoot - res.stateRoot = header.stateRoot - res.receiptsRoot = header.receiptsRoot - res.miner = header.coinbase - res.difficulty = header.difficulty - res.extraData = HistoricExtraData header.extraData - res.mixHash = Hash32 header.mixHash + 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(Header) - sizeof(seq[byte]) + header.extraData.len - res.size = Quantity(size) + let size = sizeof(eth_types.Header) - sizeof(eth_api_types.Blob) + header.extraData.len + result.size = Quantity(size) - res.gasLimit = Quantity(header.gasLimit) - res.gasUsed = Quantity(header.gasUsed) - res.timestamp = Quantity(header.timestamp) - res.baseFeePerGas = header.baseFeePerGas - res.totalDifficulty = totalDifficulty + result.gasLimit = Quantity(header.gasLimit) + result.gasUsed = Quantity(header.gasUsed) + result.timestamp = Quantity(header.timestamp) + result.baseFeePerGas = header.baseFeePerGas + result.totalDifficulty = totalDifficulty - if not isUncle: - res.uncles = blk.uncles.mapIt(it.blockHash) + if not withUncles: + result.uncles = blk.uncles.mapIt(it.blockHash) - if fullTx: - for i, tx in blk.transactions: - let txObj = populateTransactionObject(tx, - Opt.some(blockHash), - Opt.some(header.number), Opt.some(i.uint64)) - res.transactions.add txOrHash(txObj) - else: - for i, tx in blk.transactions: - let txHash = rlpHash(tx) - res.transactions.add txOrHash(txHash) + 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) - res.withdrawalsRoot = header.withdrawalsRoot - res.withdrawals = toWdList blk.withdrawals - res.parentBeaconBlockRoot = header.parentBeaconBlockRoot - res.blobGasUsed = w3Qty(header.blobGasUsed) - res.excessBlobGas = w3Qty(header.excessBlobGas) - - return res + result.withdrawalsRoot = header.withdrawalsRoot + result.withdrawals = toWdList blk.withdrawals + result.parentBeaconBlockRoot = header.parentBeaconBlockRoot + result.blobGasUsed = w3Qty(header.blobGasUsed) + result.excessBlobGas = w3Qty(header.excessBlobGas) + result.requestsHash = header.requestsHash proc populateReceipt*(receipt: Receipt, gasUsed: GasInt, tx: Transaction, txIndex: uint64, header: Header): ReceiptObject = diff --git a/nimbus/rpc/server_api_helpers.nim b/nimbus/rpc/server_api_helpers.nim deleted file mode 100644 index 12d7ea26d..000000000 --- a/nimbus/rpc/server_api_helpers.nim +++ /dev/null @@ -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) diff --git a/nimbus_verified_proxy/libverifproxy/verifproxy.nim b/nimbus_verified_proxy/libverifproxy/verifproxy.nim index b30685b14..ac67e61d7 100644 --- a/nimbus_verified_proxy/libverifproxy/verifproxy.nim +++ b/nimbus_verified_proxy/libverifproxy/verifproxy.nim @@ -6,7 +6,7 @@ # at your option. This file may not be copied, modified, or distributed except according to those terms. import - std/[atomics, json, os, strutils, net], + std/[atomics, json, strutils, net], ../nimbus_verified_proxy, ../nimbus_verified_proxy_conf diff --git a/nimbus_verified_proxy/nimbus_verified_proxy.nim b/nimbus_verified_proxy/nimbus_verified_proxy.nim index 6c2f3b407..b4374e082 100644 --- a/nimbus_verified_proxy/nimbus_verified_proxy.nim +++ b/nimbus_verified_proxy/nimbus_verified_proxy.nim @@ -21,7 +21,7 @@ import beacon_chain/spec/beaconstate, beacon_chain/spec/datatypes/[phase0, altair, bellatrix], beacon_chain/[light_client, nimbus_binary_common, version], - ../nimbus/rpc/[cors, server_api_helpers], + ../nimbus/rpc/[cors, rpc_utils], ../nimbus/beacon/payload_conv, ./rpc/rpc_eth_api, ./nimbus_verified_proxy_conf, @@ -147,7 +147,7 @@ proc run*( parentBeaconBlockRoot = 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: debug "Invalid block received", err = exc.msg diff --git a/vendor/nim-web3 b/vendor/nim-web3 index 40854fb51..ff92d2877 160000 --- a/vendor/nim-web3 +++ b/vendor/nim-web3 @@ -1 +1 @@ -Subproject commit 40854fb51fd444b7537da767800fbca2189eb2b7 +Subproject commit ff92d2877985faee5ac6abc3bea805b85f2be1c8