mirror of
https://github.com/logos-co/logos-verified-proxy-module.git
synced 2026-08-27 13:01:09 +00:00
feat: the full eth*/op* mirror, generated — and CI to gate it
Grows the typed surface from 8 methods to 60: all 30 eth_* the library dispatches, plus the 30 op_* mirrors. Everything was already reachable through rpc(); what was missing was discoverability — `lm methods`, the LIDL contract, and a caller's type checker. Generated, not hand-written. Each wrapper is three lines over the same shared path, so sixty-one of them by hand is sixty-one chances to transpose an argument; the table is extracted from the library's OWN dispatch table (the `case $name` in c_frontend.nim), including each parameter's real type — which is how ethGetBlockByNumber gets a bool, ethFeeHistory a uint64 and a list, and eth_call an object rather than everything being a string. They are still committed as literal text: the module's code generator parses verified_proxy_impl.h as TEXT to build the LIDL contract, so anything hidden behind a macro would simply not exist to it. `--check` proves the committed blocks still match, and fails on a one-character edit (verified). eth_syncing is deliberately excluded from the typed surface — the runtime issues it as its own keep-alive and a wrapper would invite callers to fight it. Still reachable through rpc(). CI is new for this repo, which had none: build on Linux and macOS, unit tests (the check derivation runs the suite as part of building it), and the codegen drift check. Named explicitly rather than via `nix flake check`, which would also evaluate the x86_64-windows pseudo-system. Verified live on sepolia through a real logoscore daemon: ethGasPrice, ethMaxPriorityFeePerGas, ethBlobBaseFee, ethGetBlockTransactionCountByNumber, ethGetUncleCountByBlockNumber and ethGetBlockByNumber all answer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3d08debc57
commit
35fc0365ce
@@ -0,0 +1,63 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
- uses: cachix/cachix-action@v15
|
||||
with:
|
||||
name: logos-co
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
||||
# libverifproxy is a ~25 minute source build of the whole nimbus/Nim
|
||||
# toolchain, so the Logos cache is doing real work here rather than
|
||||
# shaving seconds.
|
||||
- name: Build module
|
||||
run: nix build -L
|
||||
|
||||
test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
- uses: cachix/cachix-action@v15
|
||||
with:
|
||||
name: logos-co
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
||||
# The check derivation RUNS the suite as part of building it, so a red
|
||||
# test is a failed build. Named explicitly rather than via `nix flake
|
||||
# check`, which would also evaluate the x86_64-windows pseudo-system.
|
||||
- name: Unit tests
|
||||
run: |
|
||||
nix build -L ".#checks.$(nix eval --impure --raw --expr builtins.currentSystem).unit-tests"
|
||||
|
||||
codegen:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# The 60 typed eth_*/op_* wrappers are generated from the library's own
|
||||
# dispatch table but COMMITTED as literal text, because the module's code
|
||||
# generator parses verified_proxy_impl.h as text and cannot see through a
|
||||
# macro. This proves nobody hand-edited the generated blocks, and that a
|
||||
# bumped nimbus input has not left them behind.
|
||||
- name: RPC wrappers match the generator
|
||||
run: python3 tools/gen_rpc_methods.py --check
|
||||
@@ -18,6 +18,7 @@ logos_module(
|
||||
SOURCES
|
||||
src/verified_proxy_impl.h
|
||||
src/verified_proxy_impl.cpp
|
||||
src/verified_proxy_rpc.cpp
|
||||
src/proxy_config.h
|
||||
src/proxy_config.cpp
|
||||
src/proxy_runtime.h
|
||||
|
||||
@@ -68,7 +68,8 @@ impossible without it. (Infura notably does not.)
|
||||
| `supportedNetworks()` | The accepted networks with their chain ids and a default endpoint pair. Build a UI selector from this, not a hardcoded list. |
|
||||
| `fetchFinalizedRoot(beaconUrl)` | Convenience: asks a beacon node for its current finalized root. **Not** a trust anchor — see below. |
|
||||
| `rpc(method, params)` | Any method the proxy supports. `params` is a JSON-RPC array. |
|
||||
| `ethBlockNumber()`, `ethGetBalance(...)`, `ethCall(...)`, … | Typed wrappers over the same path. |
|
||||
| `ethBlockNumber()`, `ethGetBalance(...)`, `ethCall(...)`, … | 30 typed `eth*` wrappers over the same path. |
|
||||
| `opBlockNumber()`, `opGetBalance(...)`, … | The 30 `op*` mirrors. Need an OP-Stack network and `opExecutionApiUrls`. |
|
||||
|
||||
Events: `proxyStarted`, `proxyStopped`, `proxyStateChanged`.
|
||||
|
||||
|
||||
@@ -284,40 +284,3 @@ StdLogosResult VerifiedProxyImpl::fetchFinalizedRoot(const std::string& beaconUr
|
||||
StdLogosResult VerifiedProxyImpl::rpc(const std::string& method, const LogosList& params) {
|
||||
return m_rt->call(method, params.is_null() ? json::array() : params);
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethBlockNumber() {
|
||||
return m_rt->call("eth_blockNumber", json::array());
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethChainId() {
|
||||
return m_rt->call("eth_chainId", json::array());
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetBalance(const std::string& address,
|
||||
const std::string& blockTag) {
|
||||
return m_rt->call("eth_getBalance", json::array({ address, blockTag }));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetCode(const std::string& address,
|
||||
const std::string& blockTag) {
|
||||
return m_rt->call("eth_getCode", json::array({ address, blockTag }));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetBlockByNumber(const std::string& blockTag,
|
||||
bool fullTransactions) {
|
||||
return m_rt->call("eth_getBlockByNumber", json::array({ blockTag, fullTransactions }));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethCall(const LogosMap& txArgs,
|
||||
const std::string& blockTag,
|
||||
bool optimisticStateFetch) {
|
||||
// The third positional parameter is upstream's own extension; a standard
|
||||
// JSON-RPC eth_call has only two.
|
||||
return m_rt->call("eth_call", json::array({ txArgs, blockTag, optimisticStateFetch }));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetTransactionByBlockNumberAndIndex(
|
||||
const std::string& blockTag, uint64_t index) {
|
||||
return m_rt->call("eth_getTransactionByBlockNumberAndIndex",
|
||||
json::array({ blockTag, index }));
|
||||
}
|
||||
|
||||
+282
-20
@@ -202,35 +202,297 @@ public:
|
||||
///
|
||||
/// Returns the decoded result value on success.
|
||||
StdLogosResult rpc(const std::string& method, const LogosList& params);
|
||||
|
||||
/// Current verified head block number.
|
||||
///
|
||||
/// Returns a JSON **number**, not a hex quantity string — upstream's
|
||||
/// encoding is not uniform (`ethChainId` and `ethGasPrice` do return hex
|
||||
/// strings). Measured against sepolia, not inferred from the JSON-RPC spec.
|
||||
StdLogosResult ethBlockNumber();
|
||||
|
||||
/// The chain id the proxy is configured for, as a hex quantity string.
|
||||
// BEGIN GENERATED RPC WRAPPERS -- edit tools/gen_rpc_methods.py, not this
|
||||
/// `eth_chainId`, verified.
|
||||
StdLogosResult ethChainId();
|
||||
|
||||
/// Verified account balance in wei, as a hex quantity string.
|
||||
/// `blockTag` is "latest", "pending", "earliest", or a hex block number.
|
||||
/// `eth_blockNumber`, verified.
|
||||
StdLogosResult ethBlockNumber();
|
||||
|
||||
/// `eth_getBalance`, verified.
|
||||
StdLogosResult ethGetBalance(const std::string& address, const std::string& blockTag);
|
||||
|
||||
/// Verified contract code at `address`, as a hex byte string.
|
||||
/// `eth_getStorageAt`, verified.
|
||||
StdLogosResult ethGetStorageAt(const std::string& address, const std::string& slot, const std::string& blockTag);
|
||||
|
||||
/// `eth_getTransactionCount`, verified.
|
||||
StdLogosResult ethGetTransactionCount(const std::string& address, const std::string& blockTag);
|
||||
|
||||
/// `eth_getCode`, verified.
|
||||
StdLogosResult ethGetCode(const std::string& address, const std::string& blockTag);
|
||||
|
||||
/// Verified block. `fullTransactions` selects full objects over hashes.
|
||||
/// `eth_getBlockByHash`, verified.
|
||||
StdLogosResult ethGetBlockByHash(const std::string& blockHash, bool fullTransactions);
|
||||
|
||||
/// `eth_getBlockByNumber`, verified.
|
||||
StdLogosResult ethGetBlockByNumber(const std::string& blockTag, bool fullTransactions);
|
||||
|
||||
/// Verified `eth_call`. `txArgs` is a transaction object ({to, data, ...}).
|
||||
/// `optimisticStateFetch` trades a stricter state check for latency.
|
||||
StdLogosResult ethCall(const LogosMap& txArgs, const std::string& blockTag,
|
||||
bool optimisticStateFetch);
|
||||
/// `eth_getUncleCountByBlockNumber`, verified.
|
||||
StdLogosResult ethGetUncleCountByBlockNumber(const std::string& blockTag);
|
||||
|
||||
/// `eth_getUncleCountByBlockHash`, verified.
|
||||
StdLogosResult ethGetUncleCountByBlockHash(const std::string& blockHash);
|
||||
|
||||
/// `eth_getBlockTransactionCountByNumber`, verified.
|
||||
StdLogosResult ethGetBlockTransactionCountByNumber(const std::string& blockTag);
|
||||
|
||||
/// `eth_getBlockTransactionCountByHash`, verified.
|
||||
StdLogosResult ethGetBlockTransactionCountByHash(const std::string& blockHash);
|
||||
|
||||
/// `eth_getTransactionByBlockNumberAndIndex`, verified.
|
||||
StdLogosResult ethGetTransactionByBlockNumberAndIndex(const std::string& blockTag, uint64_t index);
|
||||
|
||||
/// `eth_getTransactionByBlockHashAndIndex`, verified.
|
||||
StdLogosResult ethGetTransactionByBlockHashAndIndex(const std::string& blockHash, uint64_t index);
|
||||
|
||||
/// `eth_call`, verified.
|
||||
///
|
||||
/// `optimisticStateFetch` is upstream's own extension to the standard
|
||||
/// JSON-RPC signature, not a parameter callers will know from elsewhere.
|
||||
StdLogosResult ethCall(const LogosMap& txArgs, const std::string& blockTag, bool optimisticStateFetch);
|
||||
|
||||
/// `eth_createAccessList`, verified.
|
||||
///
|
||||
/// `optimisticStateFetch` is upstream's own extension to the standard
|
||||
/// JSON-RPC signature, not a parameter callers will know from elsewhere.
|
||||
StdLogosResult ethCreateAccessList(const LogosMap& txArgs, const std::string& blockTag, bool optimisticStateFetch);
|
||||
|
||||
/// `eth_estimateGas`, verified.
|
||||
///
|
||||
/// `optimisticStateFetch` is upstream's own extension to the standard
|
||||
/// JSON-RPC signature, not a parameter callers will know from elsewhere.
|
||||
StdLogosResult ethEstimateGas(const LogosMap& txArgs, const std::string& blockTag, bool optimisticStateFetch);
|
||||
|
||||
/// `eth_getTransactionByHash`, verified.
|
||||
StdLogosResult ethGetTransactionByHash(const std::string& txHash);
|
||||
|
||||
/// `eth_getBlockReceipts`, verified.
|
||||
StdLogosResult ethGetBlockReceipts(const std::string& blockTag);
|
||||
|
||||
/// `eth_getTransactionReceipt`, verified.
|
||||
StdLogosResult ethGetTransactionReceipt(const std::string& txHash);
|
||||
|
||||
/// `eth_getLogs`, verified.
|
||||
StdLogosResult ethGetLogs(const LogosMap& filterOptions);
|
||||
|
||||
/// `eth_newFilter`, verified.
|
||||
StdLogosResult ethNewFilter(const LogosMap& filterOptions);
|
||||
|
||||
/// `eth_uninstallFilter`, verified.
|
||||
StdLogosResult ethUninstallFilter(const std::string& filterId);
|
||||
|
||||
/// `eth_getFilterLogs`, verified.
|
||||
StdLogosResult ethGetFilterLogs(const std::string& filterId);
|
||||
|
||||
/// `eth_getFilterChanges`, verified.
|
||||
StdLogosResult ethGetFilterChanges(const std::string& filterId);
|
||||
|
||||
/// `eth_blobBaseFee`, verified.
|
||||
StdLogosResult ethBlobBaseFee();
|
||||
|
||||
/// `eth_gasPrice`, verified.
|
||||
StdLogosResult ethGasPrice();
|
||||
|
||||
/// `eth_maxPriorityFeePerGas`, verified.
|
||||
StdLogosResult ethMaxPriorityFeePerGas();
|
||||
|
||||
/// `eth_feeHistory`, verified.
|
||||
StdLogosResult ethFeeHistory(uint64_t blockCount, const std::string& newestBlock, const LogosList& rewardPercentiles);
|
||||
|
||||
/// `eth_sendRawTransaction`, verified.
|
||||
StdLogosResult ethSendRawTransaction(const std::string& txHexBytes);
|
||||
|
||||
/// `op_chainId`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opChainId();
|
||||
|
||||
/// `op_blockNumber`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opBlockNumber();
|
||||
|
||||
/// `op_getBalance`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetBalance(const std::string& address, const std::string& blockTag);
|
||||
|
||||
/// `op_getStorageAt`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetStorageAt(const std::string& address, const std::string& slot, const std::string& blockTag);
|
||||
|
||||
/// `op_getTransactionCount`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetTransactionCount(const std::string& address, const std::string& blockTag);
|
||||
|
||||
/// `op_getCode`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetCode(const std::string& address, const std::string& blockTag);
|
||||
|
||||
/// `op_getBlockByHash`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetBlockByHash(const std::string& blockHash, bool fullTransactions);
|
||||
|
||||
/// `op_getBlockByNumber`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetBlockByNumber(const std::string& blockTag, bool fullTransactions);
|
||||
|
||||
/// `op_getUncleCountByBlockNumber`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetUncleCountByBlockNumber(const std::string& blockTag);
|
||||
|
||||
/// `op_getUncleCountByBlockHash`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetUncleCountByBlockHash(const std::string& blockHash);
|
||||
|
||||
/// `op_getBlockTransactionCountByNumber`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetBlockTransactionCountByNumber(const std::string& blockTag);
|
||||
|
||||
/// `op_getBlockTransactionCountByHash`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetBlockTransactionCountByHash(const std::string& blockHash);
|
||||
|
||||
/// `op_getTransactionByBlockNumberAndIndex`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetTransactionByBlockNumberAndIndex(const std::string& blockTag, uint64_t index);
|
||||
|
||||
/// `op_getTransactionByBlockHashAndIndex`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetTransactionByBlockHashAndIndex(const std::string& blockHash, uint64_t index);
|
||||
|
||||
/// `op_call`, verified.
|
||||
///
|
||||
/// `optimisticStateFetch` is upstream's own extension to the standard
|
||||
/// JSON-RPC signature, not a parameter callers will know from elsewhere.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opCall(const LogosMap& txArgs, const std::string& blockTag, bool optimisticStateFetch);
|
||||
|
||||
/// `op_createAccessList`, verified.
|
||||
///
|
||||
/// `optimisticStateFetch` is upstream's own extension to the standard
|
||||
/// JSON-RPC signature, not a parameter callers will know from elsewhere.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opCreateAccessList(const LogosMap& txArgs, const std::string& blockTag, bool optimisticStateFetch);
|
||||
|
||||
/// `op_estimateGas`, verified.
|
||||
///
|
||||
/// `optimisticStateFetch` is upstream's own extension to the standard
|
||||
/// JSON-RPC signature, not a parameter callers will know from elsewhere.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opEstimateGas(const LogosMap& txArgs, const std::string& blockTag, bool optimisticStateFetch);
|
||||
|
||||
/// `op_getTransactionByHash`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetTransactionByHash(const std::string& txHash);
|
||||
|
||||
/// `op_getBlockReceipts`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetBlockReceipts(const std::string& blockTag);
|
||||
|
||||
/// `op_getTransactionReceipt`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetTransactionReceipt(const std::string& txHash);
|
||||
|
||||
/// `op_getLogs`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetLogs(const LogosMap& filterOptions);
|
||||
|
||||
/// `op_newFilter`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opNewFilter(const LogosMap& filterOptions);
|
||||
|
||||
/// `op_uninstallFilter`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opUninstallFilter(const std::string& filterId);
|
||||
|
||||
/// `op_getFilterLogs`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetFilterLogs(const std::string& filterId);
|
||||
|
||||
/// `op_getFilterChanges`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGetFilterChanges(const std::string& filterId);
|
||||
|
||||
/// `op_blobBaseFee`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opBlobBaseFee();
|
||||
|
||||
/// `op_gasPrice`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opGasPrice();
|
||||
|
||||
/// `op_maxPriorityFeePerGas`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opMaxPriorityFeePerGas();
|
||||
|
||||
/// `op_feeHistory`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opFeeHistory(uint64_t blockCount, const std::string& newestBlock, const LogosList& rewardPercentiles);
|
||||
|
||||
/// `op_sendRawTransaction`, verified.
|
||||
///
|
||||
/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the
|
||||
/// library answers with a clear error rather than a wrong value.
|
||||
StdLogosResult opSendRawTransaction(const std::string& txHexBytes);
|
||||
|
||||
// END GENERATED RPC WRAPPERS
|
||||
|
||||
/// Verified transaction by index within a block.
|
||||
StdLogosResult ethGetTransactionByBlockNumberAndIndex(const std::string& blockTag,
|
||||
uint64_t index);
|
||||
|
||||
logos_events:
|
||||
/// Emitted when start() finishes. {"success":bool,"chainId":number,"error":string}
|
||||
|
||||
@@ -0,0 +1,260 @@
|
||||
// The typed eth_*/op_* surface.
|
||||
//
|
||||
// Every one of these is three lines over the SAME dispatch path: the library's
|
||||
// proxyCall is a string `case` over the very procs its typed C entry points
|
||||
// call, so there is one FFI path here rather than sixty-one. They exist for
|
||||
// discoverability — `lm methods`, the LIDL contract, and a caller's type
|
||||
// checker — not because each needs its own binding.
|
||||
//
|
||||
// Generated. See tools/gen_rpc_methods.py; the table comes from the library's
|
||||
// own dispatch table, so a bumped nimbus input cannot silently leave this
|
||||
// behind.
|
||||
|
||||
#include "verified_proxy_impl.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
// BEGIN GENERATED RPC WRAPPERS -- edit tools/gen_rpc_methods.py, not this
|
||||
StdLogosResult VerifiedProxyImpl::ethChainId() {
|
||||
return rpc("eth_chainId", json::array({}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethBlockNumber() {
|
||||
return rpc("eth_blockNumber", json::array({}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetBalance(const std::string& address, const std::string& blockTag) {
|
||||
return rpc("eth_getBalance", json::array({address, blockTag}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetStorageAt(const std::string& address, const std::string& slot, const std::string& blockTag) {
|
||||
return rpc("eth_getStorageAt", json::array({address, slot, blockTag}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetTransactionCount(const std::string& address, const std::string& blockTag) {
|
||||
return rpc("eth_getTransactionCount", json::array({address, blockTag}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetCode(const std::string& address, const std::string& blockTag) {
|
||||
return rpc("eth_getCode", json::array({address, blockTag}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetBlockByHash(const std::string& blockHash, bool fullTransactions) {
|
||||
return rpc("eth_getBlockByHash", json::array({blockHash, fullTransactions}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetBlockByNumber(const std::string& blockTag, bool fullTransactions) {
|
||||
return rpc("eth_getBlockByNumber", json::array({blockTag, fullTransactions}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetUncleCountByBlockNumber(const std::string& blockTag) {
|
||||
return rpc("eth_getUncleCountByBlockNumber", json::array({blockTag}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetUncleCountByBlockHash(const std::string& blockHash) {
|
||||
return rpc("eth_getUncleCountByBlockHash", json::array({blockHash}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetBlockTransactionCountByNumber(const std::string& blockTag) {
|
||||
return rpc("eth_getBlockTransactionCountByNumber", json::array({blockTag}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetBlockTransactionCountByHash(const std::string& blockHash) {
|
||||
return rpc("eth_getBlockTransactionCountByHash", json::array({blockHash}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetTransactionByBlockNumberAndIndex(const std::string& blockTag, uint64_t index) {
|
||||
return rpc("eth_getTransactionByBlockNumberAndIndex", json::array({blockTag, index}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetTransactionByBlockHashAndIndex(const std::string& blockHash, uint64_t index) {
|
||||
return rpc("eth_getTransactionByBlockHashAndIndex", json::array({blockHash, index}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethCall(const LogosMap& txArgs, const std::string& blockTag, bool optimisticStateFetch) {
|
||||
return rpc("eth_call", json::array({txArgs, blockTag, optimisticStateFetch}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethCreateAccessList(const LogosMap& txArgs, const std::string& blockTag, bool optimisticStateFetch) {
|
||||
return rpc("eth_createAccessList", json::array({txArgs, blockTag, optimisticStateFetch}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethEstimateGas(const LogosMap& txArgs, const std::string& blockTag, bool optimisticStateFetch) {
|
||||
return rpc("eth_estimateGas", json::array({txArgs, blockTag, optimisticStateFetch}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetTransactionByHash(const std::string& txHash) {
|
||||
return rpc("eth_getTransactionByHash", json::array({txHash}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetBlockReceipts(const std::string& blockTag) {
|
||||
return rpc("eth_getBlockReceipts", json::array({blockTag}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetTransactionReceipt(const std::string& txHash) {
|
||||
return rpc("eth_getTransactionReceipt", json::array({txHash}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetLogs(const LogosMap& filterOptions) {
|
||||
return rpc("eth_getLogs", json::array({filterOptions}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethNewFilter(const LogosMap& filterOptions) {
|
||||
return rpc("eth_newFilter", json::array({filterOptions}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethUninstallFilter(const std::string& filterId) {
|
||||
return rpc("eth_uninstallFilter", json::array({filterId}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetFilterLogs(const std::string& filterId) {
|
||||
return rpc("eth_getFilterLogs", json::array({filterId}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGetFilterChanges(const std::string& filterId) {
|
||||
return rpc("eth_getFilterChanges", json::array({filterId}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethBlobBaseFee() {
|
||||
return rpc("eth_blobBaseFee", json::array({}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethGasPrice() {
|
||||
return rpc("eth_gasPrice", json::array({}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethMaxPriorityFeePerGas() {
|
||||
return rpc("eth_maxPriorityFeePerGas", json::array({}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethFeeHistory(uint64_t blockCount, const std::string& newestBlock, const LogosList& rewardPercentiles) {
|
||||
return rpc("eth_feeHistory", json::array({blockCount, newestBlock, rewardPercentiles}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::ethSendRawTransaction(const std::string& txHexBytes) {
|
||||
return rpc("eth_sendRawTransaction", json::array({txHexBytes}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opChainId() {
|
||||
return rpc("op_chainId", json::array({}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opBlockNumber() {
|
||||
return rpc("op_blockNumber", json::array({}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetBalance(const std::string& address, const std::string& blockTag) {
|
||||
return rpc("op_getBalance", json::array({address, blockTag}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetStorageAt(const std::string& address, const std::string& slot, const std::string& blockTag) {
|
||||
return rpc("op_getStorageAt", json::array({address, slot, blockTag}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetTransactionCount(const std::string& address, const std::string& blockTag) {
|
||||
return rpc("op_getTransactionCount", json::array({address, blockTag}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetCode(const std::string& address, const std::string& blockTag) {
|
||||
return rpc("op_getCode", json::array({address, blockTag}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetBlockByHash(const std::string& blockHash, bool fullTransactions) {
|
||||
return rpc("op_getBlockByHash", json::array({blockHash, fullTransactions}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetBlockByNumber(const std::string& blockTag, bool fullTransactions) {
|
||||
return rpc("op_getBlockByNumber", json::array({blockTag, fullTransactions}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetUncleCountByBlockNumber(const std::string& blockTag) {
|
||||
return rpc("op_getUncleCountByBlockNumber", json::array({blockTag}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetUncleCountByBlockHash(const std::string& blockHash) {
|
||||
return rpc("op_getUncleCountByBlockHash", json::array({blockHash}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetBlockTransactionCountByNumber(const std::string& blockTag) {
|
||||
return rpc("op_getBlockTransactionCountByNumber", json::array({blockTag}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetBlockTransactionCountByHash(const std::string& blockHash) {
|
||||
return rpc("op_getBlockTransactionCountByHash", json::array({blockHash}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetTransactionByBlockNumberAndIndex(const std::string& blockTag, uint64_t index) {
|
||||
return rpc("op_getTransactionByBlockNumberAndIndex", json::array({blockTag, index}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetTransactionByBlockHashAndIndex(const std::string& blockHash, uint64_t index) {
|
||||
return rpc("op_getTransactionByBlockHashAndIndex", json::array({blockHash, index}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opCall(const LogosMap& txArgs, const std::string& blockTag, bool optimisticStateFetch) {
|
||||
return rpc("op_call", json::array({txArgs, blockTag, optimisticStateFetch}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opCreateAccessList(const LogosMap& txArgs, const std::string& blockTag, bool optimisticStateFetch) {
|
||||
return rpc("op_createAccessList", json::array({txArgs, blockTag, optimisticStateFetch}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opEstimateGas(const LogosMap& txArgs, const std::string& blockTag, bool optimisticStateFetch) {
|
||||
return rpc("op_estimateGas", json::array({txArgs, blockTag, optimisticStateFetch}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetTransactionByHash(const std::string& txHash) {
|
||||
return rpc("op_getTransactionByHash", json::array({txHash}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetBlockReceipts(const std::string& blockTag) {
|
||||
return rpc("op_getBlockReceipts", json::array({blockTag}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetTransactionReceipt(const std::string& txHash) {
|
||||
return rpc("op_getTransactionReceipt", json::array({txHash}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetLogs(const LogosMap& filterOptions) {
|
||||
return rpc("op_getLogs", json::array({filterOptions}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opNewFilter(const LogosMap& filterOptions) {
|
||||
return rpc("op_newFilter", json::array({filterOptions}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opUninstallFilter(const std::string& filterId) {
|
||||
return rpc("op_uninstallFilter", json::array({filterId}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetFilterLogs(const std::string& filterId) {
|
||||
return rpc("op_getFilterLogs", json::array({filterId}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGetFilterChanges(const std::string& filterId) {
|
||||
return rpc("op_getFilterChanges", json::array({filterId}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opBlobBaseFee() {
|
||||
return rpc("op_blobBaseFee", json::array({}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opGasPrice() {
|
||||
return rpc("op_gasPrice", json::array({}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opMaxPriorityFeePerGas() {
|
||||
return rpc("op_maxPriorityFeePerGas", json::array({}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opFeeHistory(uint64_t blockCount, const std::string& newestBlock, const LogosList& rewardPercentiles) {
|
||||
return rpc("op_feeHistory", json::array({blockCount, newestBlock, rewardPercentiles}));
|
||||
}
|
||||
|
||||
StdLogosResult VerifiedProxyImpl::opSendRawTransaction(const std::string& txHexBytes) {
|
||||
return rpc("op_sendRawTransaction", json::array({txHexBytes}));
|
||||
}
|
||||
|
||||
// END GENERATED RPC WRAPPERS
|
||||
@@ -22,6 +22,7 @@ logos_test(
|
||||
../src/proxy_config.cpp
|
||||
../src/proxy_runtime.cpp
|
||||
../src/verified_proxy_impl.cpp
|
||||
../src/verified_proxy_rpc.cpp
|
||||
../src/rpc_http_server.cpp
|
||||
../src/beacon_client.cpp
|
||||
TEST_SOURCES
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate the typed eth_*/op_* wrappers from the library's own dispatch table.
|
||||
|
||||
The wrappers are three lines each over one shared `rpc()` path, so hand-writing
|
||||
sixty-one of them would be sixty-one chances to transpose an argument. They are
|
||||
generated instead — but COMMITTED as literal text, because the module's code
|
||||
generator parses verified_proxy_impl.h as TEXT to build the LIDL contract and
|
||||
would not see anything hidden behind a macro.
|
||||
|
||||
Run with --check in CI to prove the committed blocks still match.
|
||||
|
||||
The table below was extracted mechanically from nimbus-eth1's
|
||||
nimbus_verified_proxy/library/c_frontend.nim (the `case $name` inside proxyCall)
|
||||
at the revision this module pins. Re-extract with --from-source <c_frontend.nim>
|
||||
after bumping that input.
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
SRC = HERE.parent / "src"
|
||||
|
||||
BEGIN = "// BEGIN GENERATED RPC WRAPPERS -- edit tools/gen_rpc_methods.py, not this"
|
||||
END = "// END GENERATED RPC WRAPPERS"
|
||||
|
||||
# Parameter names, per RPC method, in order. Only the eth_ spellings are listed;
|
||||
# the op_ mirror reuses them. Names reach the LIDL contract and `lm methods`, so
|
||||
# they are the API's documentation as much as its signature.
|
||||
PARAM_NAMES = {
|
||||
"getBalance": ["address", "blockTag"],
|
||||
"getCode": ["address", "blockTag"],
|
||||
"getTransactionCount": ["address", "blockTag"],
|
||||
"getStorageAt": ["address", "slot", "blockTag"],
|
||||
"getBlockByNumber": ["blockTag", "fullTransactions"],
|
||||
"getBlockByHash": ["blockHash", "fullTransactions"],
|
||||
"getUncleCountByBlockNumber": ["blockTag"],
|
||||
"getUncleCountByBlockHash": ["blockHash"],
|
||||
"getBlockTransactionCountByNumber": ["blockTag"],
|
||||
"getBlockTransactionCountByHash": ["blockHash"],
|
||||
"getTransactionByBlockNumberAndIndex": ["blockTag", "index"],
|
||||
"getTransactionByBlockHashAndIndex": ["blockHash", "index"],
|
||||
"getTransactionByHash": ["txHash"],
|
||||
"getTransactionReceipt": ["txHash"],
|
||||
"getBlockReceipts": ["blockTag"],
|
||||
"call": ["txArgs", "blockTag", "optimisticStateFetch"],
|
||||
"estimateGas": ["txArgs", "blockTag", "optimisticStateFetch"],
|
||||
"createAccessList": ["txArgs", "blockTag", "optimisticStateFetch"],
|
||||
"getLogs": ["filterOptions"],
|
||||
"newFilter": ["filterOptions"],
|
||||
"uninstallFilter": ["filterId"],
|
||||
"getFilterLogs": ["filterId"],
|
||||
"getFilterChanges": ["filterId"],
|
||||
"feeHistory": ["blockCount", "newestBlock", "rewardPercentiles"],
|
||||
"sendRawTransaction": ["txHexBytes"],
|
||||
}
|
||||
|
||||
# The one JSON parameter that is an ARRAY rather than an object. Everything else
|
||||
# reaching the library as a raw JSON node is a transaction or filter object.
|
||||
JSON_LISTS = {("feeHistory", 2)}
|
||||
|
||||
CPP_TYPE = {
|
||||
"str": "const std::string& ",
|
||||
"bool": "bool ",
|
||||
"u64": "uint64_t ",
|
||||
}
|
||||
|
||||
# Methods this module drives itself; a typed wrapper would invite callers to
|
||||
# fight the runtime for control of them.
|
||||
SKIP = {"eth_syncing"}
|
||||
|
||||
|
||||
def extract(path):
|
||||
body = Path(path).read_text()
|
||||
body = body[body.index("proc proxyCall("):]
|
||||
out = []
|
||||
for block in re.split(r'\n of "', body)[1:]:
|
||||
name = block.split('"', 1)[0]
|
||||
seg = block.split('\n of "')[0]
|
||||
kinds = []
|
||||
for m in re.finditer(
|
||||
r"parsedParams\[(\d+)\]\.(getStr|getBool|getBiggestInt)\(\)"
|
||||
r"|\(\$parsedParams\[(\d+)\]\)", seg):
|
||||
if m.group(2):
|
||||
kinds.append((int(m.group(1)),
|
||||
{"getStr": "str", "getBool": "bool",
|
||||
"getBiggestInt": "u64"}[m.group(2)]))
|
||||
else:
|
||||
kinds.append((int(m.group(3)), "json"))
|
||||
out.append({"rpc": name, "params": [k for _, k in sorted(set(kinds))]})
|
||||
return out
|
||||
|
||||
|
||||
def cpp_name(rpc):
|
||||
prefix, rest = rpc.split("_", 1)
|
||||
return prefix + rest[0].upper() + rest[1:]
|
||||
|
||||
|
||||
def stem(rpc):
|
||||
return rpc.split("_", 1)[1]
|
||||
|
||||
|
||||
def signature(rpc, params):
|
||||
base = stem(rpc)
|
||||
names = PARAM_NAMES.get(base, [f"arg{i}" for i in range(len(params))])
|
||||
args = []
|
||||
for i, kind in enumerate(params):
|
||||
if kind == "json":
|
||||
t = "const LogosList& " if (base, i) in JSON_LISTS else "const LogosMap& "
|
||||
else:
|
||||
t = CPP_TYPE[kind]
|
||||
args.append(t + names[i])
|
||||
return f"StdLogosResult {cpp_name(rpc)}({', '.join(args)})"
|
||||
|
||||
|
||||
def doc(rpc, params):
|
||||
base = stem(rpc)
|
||||
lines = [f"/// `{rpc}`, verified."]
|
||||
if base in ("call", "estimateGas", "createAccessList"):
|
||||
lines.append("///")
|
||||
lines.append("/// `optimisticStateFetch` is upstream's own extension to the standard")
|
||||
lines.append("/// JSON-RPC signature, not a parameter callers will know from elsewhere.")
|
||||
if rpc.startswith("op_"):
|
||||
lines.append("///")
|
||||
lines.append("/// Requires an OP-Stack network and `opExecutionApiUrls`; otherwise the")
|
||||
lines.append("/// library answers with a clear error rather than a wrong value.")
|
||||
return lines
|
||||
|
||||
|
||||
def emit_header(table):
|
||||
out = [BEGIN]
|
||||
for e in table:
|
||||
out += [" " + l for l in doc(e["rpc"], e["params"])]
|
||||
out.append(f" {signature(e['rpc'], e['params'])};")
|
||||
out.append("")
|
||||
out.append(" " + END)
|
||||
return "\n".join(out)
|
||||
|
||||
|
||||
def emit_impl(table):
|
||||
out = [BEGIN]
|
||||
for e in table:
|
||||
base, params = stem(e["rpc"]), e["params"]
|
||||
names = PARAM_NAMES.get(base, [f"arg{i}" for i in range(len(params))])
|
||||
sig = signature(e["rpc"], params).replace(
|
||||
"StdLogosResult ", "StdLogosResult VerifiedProxyImpl::", 1)
|
||||
args = ", ".join(names)
|
||||
out.append(f"{sig} {{")
|
||||
out.append(f' return rpc("{e["rpc"]}", json::array({{{args}}}));')
|
||||
out.append("}")
|
||||
out.append("")
|
||||
out.append(END)
|
||||
return "\n".join(out)
|
||||
|
||||
|
||||
def splice(path, block):
|
||||
text = Path(path).read_text()
|
||||
i, j = text.index(BEGIN), text.index(END) + len(END)
|
||||
return text[:i] + block.strip() + text[j:]
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--from-source", help="path to c_frontend.nim to re-extract the table")
|
||||
ap.add_argument("--check", action="store_true", help="fail if the committed files differ")
|
||||
a = ap.parse_args()
|
||||
|
||||
tbl_path = HERE / "rpc_methods.json"
|
||||
if a.from_source:
|
||||
table = extract(a.from_source)
|
||||
tbl_path.write_text(json.dumps(table, indent=1) + "\n")
|
||||
table = json.loads(tbl_path.read_text())
|
||||
table = [e for e in table if e["rpc"] not in SKIP]
|
||||
|
||||
targets = {
|
||||
SRC / "verified_proxy_impl.h": emit_header(table),
|
||||
SRC / "verified_proxy_rpc.cpp": emit_impl(table),
|
||||
}
|
||||
bad = False
|
||||
for path, block in targets.items():
|
||||
new = splice(path, block)
|
||||
if a.check:
|
||||
if new != path.read_text():
|
||||
print(f"DRIFT: {path.name} does not match the generator", file=sys.stderr)
|
||||
bad = True
|
||||
else:
|
||||
path.write_text(new)
|
||||
if a.check and bad:
|
||||
print("run: python3 tools/gen_rpc_methods.py", file=sys.stderr)
|
||||
return 1
|
||||
print(f"{len(table)} wrappers {'checked' if a.check else 'generated'}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,380 @@
|
||||
[
|
||||
{
|
||||
"rpc": "eth_chainId",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"rpc": "eth_blockNumber",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"rpc": "eth_syncing",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getBalance",
|
||||
"params": [
|
||||
"str",
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getStorageAt",
|
||||
"params": [
|
||||
"str",
|
||||
"str",
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getTransactionCount",
|
||||
"params": [
|
||||
"str",
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getCode",
|
||||
"params": [
|
||||
"str",
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getBlockByHash",
|
||||
"params": [
|
||||
"str",
|
||||
"bool"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getBlockByNumber",
|
||||
"params": [
|
||||
"str",
|
||||
"bool"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getUncleCountByBlockNumber",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getUncleCountByBlockHash",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getBlockTransactionCountByNumber",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getBlockTransactionCountByHash",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getTransactionByBlockNumberAndIndex",
|
||||
"params": [
|
||||
"str",
|
||||
"u64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getTransactionByBlockHashAndIndex",
|
||||
"params": [
|
||||
"str",
|
||||
"u64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_call",
|
||||
"params": [
|
||||
"json",
|
||||
"str",
|
||||
"bool"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_createAccessList",
|
||||
"params": [
|
||||
"json",
|
||||
"str",
|
||||
"bool"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_estimateGas",
|
||||
"params": [
|
||||
"json",
|
||||
"str",
|
||||
"bool"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getTransactionByHash",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getBlockReceipts",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getTransactionReceipt",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getLogs",
|
||||
"params": [
|
||||
"json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_newFilter",
|
||||
"params": [
|
||||
"json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_uninstallFilter",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getFilterLogs",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_getFilterChanges",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_blobBaseFee",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"rpc": "eth_gasPrice",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"rpc": "eth_maxPriorityFeePerGas",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"rpc": "eth_feeHistory",
|
||||
"params": [
|
||||
"u64",
|
||||
"str",
|
||||
"json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "eth_sendRawTransaction",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_chainId",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"rpc": "op_blockNumber",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"rpc": "op_getBalance",
|
||||
"params": [
|
||||
"str",
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getStorageAt",
|
||||
"params": [
|
||||
"str",
|
||||
"str",
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getTransactionCount",
|
||||
"params": [
|
||||
"str",
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getCode",
|
||||
"params": [
|
||||
"str",
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getBlockByHash",
|
||||
"params": [
|
||||
"str",
|
||||
"bool"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getBlockByNumber",
|
||||
"params": [
|
||||
"str",
|
||||
"bool"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getUncleCountByBlockNumber",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getUncleCountByBlockHash",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getBlockTransactionCountByNumber",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getBlockTransactionCountByHash",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getTransactionByBlockNumberAndIndex",
|
||||
"params": [
|
||||
"str",
|
||||
"u64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getTransactionByBlockHashAndIndex",
|
||||
"params": [
|
||||
"str",
|
||||
"u64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_call",
|
||||
"params": [
|
||||
"json",
|
||||
"str",
|
||||
"bool"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_createAccessList",
|
||||
"params": [
|
||||
"json",
|
||||
"str",
|
||||
"bool"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_estimateGas",
|
||||
"params": [
|
||||
"json",
|
||||
"str",
|
||||
"bool"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getTransactionByHash",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getBlockReceipts",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getTransactionReceipt",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getLogs",
|
||||
"params": [
|
||||
"json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_newFilter",
|
||||
"params": [
|
||||
"json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_uninstallFilter",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getFilterLogs",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_getFilterChanges",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_blobBaseFee",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"rpc": "op_gasPrice",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"rpc": "op_maxPriorityFeePerGas",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"rpc": "op_feeHistory",
|
||||
"params": [
|
||||
"u64",
|
||||
"str",
|
||||
"json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"rpc": "op_sendRawTransaction",
|
||||
"params": [
|
||||
"str"
|
||||
]
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user