mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-03 17:44:29 +00:00
418 lines
22 KiB
Markdown
418 lines
22 KiB
Markdown
- [Introduction](#introduction)
|
|
- [Getting Started](#getting-started)
|
|
* [Running locally](#running-locally)
|
|
* [Running remotely](#running-remotely)
|
|
* [Testing](#testing)
|
|
- [FAQ](#faq)
|
|
* [RPC Implementation Status](#rpc-implementation-status)
|
|
* [Securing the communication between RPC daemon and Erigon instance via TLS and authentication](#securing-the-communication-between-rpc-daemon-and-erigon-instance-via-tls-and-authentication)
|
|
* [Ethstats](#ethstats)
|
|
* [Allowing only specific methods (Allowlist)](#allowing-only-specific-methods--allowlist-)
|
|
* [Trace transactions progress](#trace-transactions-progress)
|
|
* [Clients getting timeout, but server load is low](#clients-getting-timeout--but-server-load-is-low)
|
|
* [Server load too high](#server-load-too-high)
|
|
* [Batch requests](#batch-requests)
|
|
- [For Developers](#for-developers)
|
|
* [Code generation](#code-generation)
|
|
|
|
## Introduction
|
|
|
|
Erigon's `rpcdaemon` runs in its own seperate process.
|
|
|
|
This brings many benefits including easier development, the ability to run multiple daemons at once, and the ability to
|
|
run the daemon remotely. It is possible to run the daemon locally as well (read-only) if both processes have access to
|
|
the data folder.
|
|
|
|
## Getting Started
|
|
|
|
The `rpcdaemon` gets built as part of the main `erigon` build process, but you can build it directly with this command:
|
|
|
|
```[bash]
|
|
make rpcdaemon
|
|
```
|
|
|
|
### Running locally
|
|
|
|
Run `rpcdaemon` on same computer with Erigon. It's default option because it using Shared Memory access to Erigon's db -
|
|
it's much faster than TCP access. Provide both `--datadir` and `--private.api.addr` flags:
|
|
|
|
```[bash]
|
|
make erigon
|
|
./build/bin/erigon --datadir=<your_data_dir> --private.api.addr=localhost:9090
|
|
make rpcdaemon
|
|
./build/bin/rpcdaemon --datadir=<your_data_dir> --private.api.addr=localhost:9090 --http.api=eth,erigon,web3,net,debug,trace,txpool,shh
|
|
```
|
|
|
|
Note that we've also specified which RPC namespaces to enable in the above command by `--http.api` flag.
|
|
|
|
### Running remotely
|
|
|
|
To start the daemon remotely - just don't set `--datadir` flag:
|
|
|
|
```[bash]
|
|
make erigon
|
|
./build/bin/erigon --datadir=<your_data_dir> --private.api.addr=0.0.0.0:9090
|
|
make rpcdaemon
|
|
./build/bin/rpcdaemon --private.api.addr=<erigon_ip>:9090 --http.api=eth,erigon,web3,net,debug,trace,txpool,shh
|
|
```
|
|
|
|
The daemon should respond with something like:
|
|
|
|
```[bash]
|
|
INFO [date-time] HTTP endpoint opened url=localhost:8545...
|
|
```
|
|
|
|
### Testing
|
|
|
|
By default, the `rpcdaemon` serves data from `localhost:8545`. You may send `curl` commands to see if things are
|
|
working.
|
|
|
|
Try `eth_blockNumber` for example. In a third terminal window enter this command:
|
|
|
|
```[bash]
|
|
curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id":1}' localhost:8545
|
|
```
|
|
|
|
This should return something along the lines of this (depending on how far your Erigon node has synced):
|
|
|
|
```[bash]
|
|
{
|
|
"jsonrpc": "2.0",
|
|
"id": 1,
|
|
"result":" 0xa5b9ba"
|
|
}
|
|
```
|
|
|
|
Also, there
|
|
are [extensive instructions for using Postman](https://github.com/ledgerwatch/erigon/wiki/Using-Postman-to-Test-TurboGeth-RPC)
|
|
to test the RPC.
|
|
|
|
## FAQ
|
|
|
|
### RPC Implementation Status
|
|
|
|
The following table shows the current implementation status of Erigon's RPC daemon.
|
|
|
|
| Command | Avail | Notes |
|
|
| ------------------------------------------ | ------- | ------------------------------------------ |
|
|
| web3_clientVersion | Yes | |
|
|
| web3_sha3 | Yes | |
|
|
| | | |
|
|
| net_listening | HC | (remote only hard coded returns true) |
|
|
| net_peerCount | Limited | internal sentries only |
|
|
| net_version | Yes | remote only |
|
|
| | | |
|
|
| eth_blockNumber | Yes | |
|
|
| eth_chainID | Yes | |
|
|
| eth_protocolVersion | Yes | |
|
|
| eth_syncing | Yes | |
|
|
| eth_gasPrice | Yes | |
|
|
| | | |
|
|
| eth_getBlockByHash | Yes | |
|
|
| eth_getBlockByNumber | Yes | |
|
|
| eth_getBlockTransactionCountByHash | Yes | |
|
|
| eth_getBlockTransactionCountByNumber | Yes | |
|
|
| eth_getUncleByBlockHashAndIndex | Yes | |
|
|
| eth_getUncleByBlockNumberAndIndex | Yes | |
|
|
| eth_getUncleCountByBlockHash | Yes | |
|
|
| eth_getUncleCountByBlockNumber | Yes | |
|
|
| | | |
|
|
| eth_getTransactionByHash | Yes | |
|
|
| eth_getRawTransactionByHash | Yes | |
|
|
| eth_getTransactionByBlockHashAndIndex | Yes | |
|
|
| eth_retRawTransactionByBlockHashAndIndex | Yes | |
|
|
| eth_getTransactionByBlockNumberAndIndex | Yes | |
|
|
| eth_retRawTransactionByBlockNumberAndIndex | Yes | |
|
|
| eth_getTransactionReceipt | Yes | |
|
|
| eth_getBlockReceipts | Yes | |
|
|
| | | |
|
|
| eth_estimateGas | Yes | |
|
|
| eth_getBalance | Yes | |
|
|
| eth_getCode | Yes | |
|
|
| eth_getTransactionCount | Yes | |
|
|
| eth_getStorageAt | Yes | |
|
|
| eth_call | Yes | |
|
|
| eth_callBundle | Yes | |
|
|
| | | |
|
|
| eth_newFilter | - | not yet implemented |
|
|
| eth_newBlockFilter | - | not yet implemented |
|
|
| eth_newPendingTransactionFilter | - | not yet implemented |
|
|
| eth_getFilterChanges | - | not yet implemented |
|
|
| eth_uninstallFilter | - | not yet implemented |
|
|
| eth_getLogs | Yes | |
|
|
| | | |
|
|
| eth_accounts | No | deprecated |
|
|
| eth_sendRawTransaction | Yes | remote only |
|
|
| eth_sendTransaction | - | not yet implemented |
|
|
| eth_sign | No | deprecated |
|
|
| eth_signTransaction | - | not yet implemented |
|
|
| eth_signTypedData | - | ???? |
|
|
| | | |
|
|
| eth_getProof | - | not yet implemented |
|
|
| | | |
|
|
| eth_mining | Yes | returns true if --mine flag provided |
|
|
| eth_coinbase | Yes | |
|
|
| eth_hashrate | Yes | |
|
|
| eth_submitHashrate | Yes | |
|
|
| eth_getWork | Yes | |
|
|
| eth_submitWork | Yes | |
|
|
| | | |
|
|
| eth_subscribe | Limited | Websock Only - newHeads, |
|
|
| | | newPendingTransaction |
|
|
| eth_unsubscribe | Yes | Websock Only |
|
|
| | | |
|
|
| debug_accountRange | Yes | Private Erigon debug module |
|
|
| debug_accountAt | Yes | Private Erigon debug module |
|
|
| debug_getModifiedAccountsByNumber | Yes | |
|
|
| debug_getModifiedAccountsByHash | Yes | |
|
|
| debug_storageRangeAt | Yes | |
|
|
| debug_traceTransaction | Yes | Streaming (can handle huge results) |
|
|
| debug_traceCall | Yes | Streaming (can handle huge results) |
|
|
| | | |
|
|
| trace_call | Yes | |
|
|
| trace_callMany | Yes | |
|
|
| trace_rawTransaction | - | not yet implemented (come help!) |
|
|
| trace_replayBlockTransactions | yes | stateDiff only (come help!) |
|
|
| trace_replayTransaction | yes | stateDiff only (come help!) |
|
|
| trace_block | Yes | |
|
|
| trace_filter | Yes | no pagination, but streaming |
|
|
| trace_get | Yes | |
|
|
| trace_transaction | Yes | |
|
|
| | | |
|
|
| txpool_content | Yes | remote only |
|
|
| | | |
|
|
| eth_getCompilers | No | deprecated |
|
|
| eth_compileLLL | No | deprecated |
|
|
| eth_compileSolidity | No | deprecated |
|
|
| eth_compileSerpent | No | deprecated |
|
|
| | | |
|
|
| db_putString | No | deprecated |
|
|
| db_getString | No | deprecated |
|
|
| db_putHex | No | deprecated |
|
|
| db_getHex | No | deprecated |
|
|
| | | |
|
|
| shh_post | No | deprecated |
|
|
| shh_version | No | deprecated |
|
|
| shh_newIdentity | No | deprecated |
|
|
| shh_hasIdentity | No | deprecated |
|
|
| shh_newGroup | No | deprecated |
|
|
| shh_addToGroup | No | deprecated |
|
|
| shh_newFilter | No | deprecated |
|
|
| shh_uninstallFilter | No | deprecated |
|
|
| shh_getFilterChanges | No | deprecated |
|
|
| shh_getMessages | No | deprecated |
|
|
| | | |
|
|
| erigon_getHeaderByHash | Yes | Erigon only |
|
|
| erigon_getHeaderByNumber | Yes | Erigon only |
|
|
| erigon_getLogsByHash | Yes | Erigon only |
|
|
| erigon_forks | Yes | Erigon only |
|
|
| erigon_issuance | Yes | Erigon only |
|
|
|
|
This table is constantly updated. Please visit again.
|
|
|
|
### Securing the communication between RPC daemon and Erigon instance via TLS and authentication
|
|
|
|
In some cases, it is useful to run Erigon nodes in a different network (for example, in a Public cloud), but RPC daemon
|
|
locally. To ensure the integrity of communication and access control to the Erigon node, TLS authentication can be
|
|
enabled. On the high level, the process consists of these steps (this process needs to be done for any "cluster" of
|
|
Erigon and RPC daemon nodes that are supposed to work together):
|
|
|
|
1. Generate key pair for the Certificate Authority (CA). The private key of CA will be used to authorise new Erigon
|
|
instances as well as new RPC daemon instances, so that they can mutually authenticate.
|
|
2. Create CA certificate file that needs to be deployed on any Erigon instance and any RPC daemon. This CA cerf file is
|
|
used as a "root of trust", whatever is in it, will be trusted by the participants when they authenticate their
|
|
counterparts.
|
|
3. For each Erigon instance and each RPC daemon instance, generate a key pair. If you are lazy, you can generate one
|
|
pair for all Erigon nodes, and one pair for all RPC daemons, and copy these keys around.
|
|
4. Using the CA private key, create cerificate file for each public key generated on the previous step. This
|
|
effectively "inducts" these keys into the "cluster of trust".
|
|
5. On each instance, deploy 3 files - CA certificate, instance key, and certificate signed by CA for this instance key.
|
|
|
|
Following is the detailed description of how it can be done using `openssl` suite of tools.
|
|
|
|
Generate CA key pair using Elliptic Curve (as opposed to RSA). The generated CA key will be in the file `CA-key.pem`.
|
|
Access to this file will allow anyone to later include any new instance key pair into the "cluster of trust", so keep it
|
|
secure.
|
|
|
|
```
|
|
openssl ecparam -name prime256v1 -genkey -noout -out CA-key.pem
|
|
```
|
|
|
|
Create CA self-signed certificate (this command will ask questions, answers aren't important for now). The file created
|
|
by this command is `CA-cert.pem`
|
|
|
|
```
|
|
openssl req -x509 -new -nodes -key CA-key.pem -sha256 -days 3650 -out CA-cert.pem
|
|
```
|
|
|
|
For Erigon node, generate a key pair:
|
|
|
|
```
|
|
openssl ecparam -name prime256v1 -genkey -noout -out erigon-key.pem
|
|
```
|
|
|
|
Also, generate one for the RPC daemon:
|
|
|
|
```
|
|
openssl ecparam -name prime256v1 -genkey -noout -out RPC-key.pem
|
|
```
|
|
|
|
Now create certificate signing request for Erigon key pair:
|
|
|
|
```
|
|
openssl req -new -key erigon-key.pem -out erigon.csr
|
|
```
|
|
|
|
And from this request, produce the certificate (signed by CA), proving that this key is now part of the "cluster of
|
|
trust"
|
|
|
|
```
|
|
openssl x509 -req -in erigon.csr -CA CA-cert.pem -CAkey CA-key.pem -CAcreateserial -out erigon.crt -days 3650 -sha256
|
|
```
|
|
|
|
Then, produce the certificate signing request for RPC daemon key pair:
|
|
|
|
```
|
|
openssl req -new -key RPC-key.pem -out RPC.csr
|
|
```
|
|
|
|
And from this request, produce the certificate (signed by CA), proving that this key is now part of the "cluster of
|
|
trust"
|
|
|
|
```
|
|
openssl x509 -req -in RPC.csr -CA CA-cert.pem -CAkey CA-key.pem -CAcreateserial -out RPC.crt -days 3650 -sha256
|
|
```
|
|
|
|
When this is all done, these three files need to be placed on the machine where Erigon is running: `CA-cert.pem`
|
|
, `erigon-key.pem`, `erigon.crt`. And Erigon needs to be run with these extra options:
|
|
|
|
```
|
|
--tls --tls.cacert CA-cert.pem --tls.key erigon-key.pem --tls.cert erigon.crt
|
|
```
|
|
|
|
On the RPC daemon machine, these three files need to be placed: `CA-cert.pem`, `RPC-key.pem`, and `RPC.crt`. And RPC
|
|
daemon needs to be started with these extra options:
|
|
|
|
```
|
|
--tls.key RPC-key.pem --tls.cacert CA-cert.pem --tls.cert RPC.crt
|
|
```
|
|
|
|
**WARNING** Normally, the "client side" (which in our case is RPC daemon), verifies that the host name of the server
|
|
matches the "Common Name" attribute of the "server" cerificate. At this stage, this verification is turned off, and it
|
|
will be turned on again once we have updated the instruction above on how to properly generate cerificates with "Common
|
|
Name".
|
|
|
|
When running Erigon instance in the Google Cloud, for example, you need to specify the **Internal IP** in
|
|
the `--private.api.addr` option. And, you will need to open the firewall on the port you are using, to that connection
|
|
to the Erigon instances can be made.
|
|
|
|
### Ethstats
|
|
|
|
This version of the RPC daemon is compatible with [ethstats-client](https://github.com/goerli/ethstats-client).
|
|
|
|
To run ethstats, run the RPC daemon remotely and open some of the APIs.
|
|
|
|
`./build/bin/rpcdaemon --private.api.addr=localhost:9090 --http.api=net,eth,web3`
|
|
|
|
Then update your `app.json` for ethstats-client like that:
|
|
|
|
```json
|
|
[
|
|
{
|
|
"name": "ethstats",
|
|
"script": "app.js",
|
|
"log_date_format": "YYYY-MM-DD HH:mm Z",
|
|
"merge_logs": false,
|
|
"watch": false,
|
|
"max_restarts": 10,
|
|
"exec_interpreter": "node",
|
|
"exec_mode": "fork_mode",
|
|
"env": {
|
|
"NODE_ENV": "production",
|
|
"RPC_HOST": "localhost",
|
|
"RPC_PORT": "8545",
|
|
"LISTENING_PORT": "30303",
|
|
"INSTANCE_NAME": "Erigon node",
|
|
"CONTACT_DETAILS": <your
|
|
twitter
|
|
handle>,
|
|
"WS_SERVER": "wss://ethstats.net/api",
|
|
"WS_SECRET": <put
|
|
your
|
|
secret
|
|
key
|
|
there>,
|
|
"VERBOSITY": 2
|
|
}
|
|
}
|
|
]
|
|
```
|
|
|
|
Run ethstats-client through pm2 as usual.
|
|
|
|
You will see these warnings in the RPC daemon output, but they are expected
|
|
|
|
```
|
|
WARN [11-05|09:03:47.911] Served conn=127.0.0.1:59753 method=eth_newBlockFilter reqid=5 t="21.194µs" err="the method eth_newBlockFilter does not exist/is not available"
|
|
WARN [11-05|09:03:47.911] Served conn=127.0.0.1:59754 method=eth_newPendingTransactionFilter reqid=6 t="9.053µs" err="the method eth_newPendingTransactionFilter does not exist/is not available"
|
|
```
|
|
|
|
### Allowing only specific methods (Allowlist)
|
|
|
|
In some cases you might want to only allow certain methods in the namespaces and hide others. That is possible
|
|
with `rpc.accessList` flag.
|
|
|
|
1. Create a file, say, `rules.json`
|
|
|
|
2. Add the following content
|
|
|
|
```json
|
|
{
|
|
"allow": [
|
|
"net_version",
|
|
"web3_eth_getBlockByHash"
|
|
]
|
|
}
|
|
```
|
|
|
|
3. Provide this file to the rpcdaemon using `--rpc.accessList` flag
|
|
|
|
```
|
|
> rpcdaemon --private.api.addr=localhost:9090 --http.api=eth,debug,net,web3 --rpc.accessList=rules.json
|
|
```
|
|
|
|
Now only these two methods are available.
|
|
|
|
### Clients getting timeout, but server load is low
|
|
|
|
In this case: increase default rate-limit - amount of requests server handle simultaneously - requests over this limit
|
|
will wait. Increase it - if your 'hot data' is small or have much RAM or see "request timeout" while server load is low.
|
|
|
|
```
|
|
./build/bin/erigon --private.api.addr=localhost:9090 --private.api.ratelimit=1024
|
|
```
|
|
|
|
### Server load too high
|
|
|
|
Reduce `--private.api.ratelimit`
|
|
|
|
### Read DB directly without Json-RPC/Graphql
|
|
|
|
[./docs/programmers_guide/db_faq.md](./docs/programmers_guide/db_faq.md)
|
|
|
|
### Batch requests
|
|
|
|
Currently batch requests are spawn multiple goroutines and process all sub-requests in parallel. To limit impact of 1
|
|
huge batch to other users - added flag `--rpc.batch.concurrency` (default: 50). Increase it to process large batches
|
|
faster.
|
|
|
|
Known Issue: if at least 1 request is "stremable" (has parameter of type *jsoniter.Stream) - then whole batch will
|
|
processed sequentially (on 1 goroutine).
|
|
|
|
## For Developers
|
|
|
|
### Code generation
|
|
|
|
`go.mod` stores right version of generators, use `make grpc` to install it and generate code (it also installs protoc
|
|
into ./build/bin folder).
|