mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
rpc: implement txpool_contentFrom (#9057)
implement the `txpool_contentFrom` rpc, used to retrieve the specified address's tx contents. --------- Signed-off-by: jsvisa <delweng@gmail.com>
This commit is contained in:
parent
79ed8cad35
commit
398bcb50a0
@ -1,21 +1,21 @@
|
||||
- [Introduction](#introduction)
|
||||
- [Getting Started](#getting-started)
|
||||
* [Running locally](#running-locally)
|
||||
* [Running remotely](#running-remotely)
|
||||
* [Healthcheck](#healthcheck)
|
||||
* [Testing](#testing)
|
||||
- [Running locally](#running-locally)
|
||||
- [Running remotely](#running-remotely)
|
||||
- [Healthcheck](#healthcheck)
|
||||
- [Testing](#testing)
|
||||
- [FAQ](#faq)
|
||||
* [Relations between prune options and rpc methods](#relations-between-prune-options-and-rpc-method)
|
||||
* [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)
|
||||
* [Faster Batch requests](#faster-batch-requests)
|
||||
- [Relations between prune options and rpc methods](#relations-between-prune-options-and-rpc-method)
|
||||
- [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)
|
||||
- [Faster Batch requests](#faster-batch-requests)
|
||||
- [For Developers](#for-developers)
|
||||
* [Code generation](#code-generation)
|
||||
- [Code generation](#code-generation)
|
||||
|
||||
## Introduction
|
||||
|
||||
@ -72,7 +72,7 @@ it may scale well for some workloads that are heavy on the current state queries
|
||||
|
||||
### Healthcheck
|
||||
|
||||
There are 2 options for running healtchecks, POST request, or GET request with custom headers. Both options are available
|
||||
There are 2 options for running healtchecks, POST request, or GET request with custom headers. Both options are available
|
||||
at the `/health` endpoint.
|
||||
|
||||
#### POST request
|
||||
@ -99,7 +99,7 @@ Not adding a check disables that.
|
||||
`eth` namespace to be listed in `http.api`.
|
||||
|
||||
Example request
|
||||
```http POST http://localhost:8545/health --raw '{"min_peer_count": 3, "known_block": "0x1F"}'```
|
||||
`http POST http://localhost:8545/health --raw '{"min_peer_count": 3, "known_block": "0x1F"}'`
|
||||
Example response
|
||||
|
||||
```
|
||||
@ -114,19 +114,21 @@ Example response
|
||||
|
||||
If the healthcheck is successful it will return a 200 status code.
|
||||
|
||||
If the healthcheck fails for any reason a status 500 will be returned. This is true if one of the criteria requested
|
||||
If the healthcheck fails for any reason a status 500 will be returned. This is true if one of the criteria requested
|
||||
fails its check.
|
||||
|
||||
You can set any number of values on the `X-ERIGON-HEALTHCHECK` header. Ones that are not included are skipped in the
|
||||
You can set any number of values on the `X-ERIGON-HEALTHCHECK` header. Ones that are not included are skipped in the
|
||||
checks.
|
||||
|
||||
Available Options:
|
||||
|
||||
- `synced` - will check if the node has completed syncing
|
||||
- `min_peer_count<count>` - will check that the node has at least `<count>` many peers
|
||||
- `check_block<block>` - will check that the node is at least ahead of the `<block>` specified
|
||||
- `max_seconds_behind<seconds>` - will check that the node is no more than `<seconds>` behind from its latest block
|
||||
|
||||
Example Request
|
||||
|
||||
```
|
||||
curl --location --request GET 'http://localhost:8545/health' \
|
||||
--header 'X-ERIGON-HEALTHCHECK: min_peer_count1' \
|
||||
@ -135,6 +137,7 @@ curl --location --request GET 'http://localhost:8545/health' \
|
||||
```
|
||||
|
||||
Example Response
|
||||
|
||||
```
|
||||
{
|
||||
"check_block":"DISABLED",
|
||||
@ -194,7 +197,6 @@ If the `--http.url` flag is set, then `--http.addr` and `--http.port` with both
|
||||
|
||||
note that this is NOT geth-style IPC. for that, read the next section, IPC endpoint(geth-compatible)
|
||||
|
||||
|
||||
### HTTPS, HTTP2, and H2C
|
||||
|
||||
Erigon supports HTTPS, HTTP2, and H2C out of the box. H2C is served by the default HTTP handler.
|
||||
@ -207,7 +209,6 @@ The HTTPS server will inherit all other configuration parameters from http, for
|
||||
|
||||
If the `--https.url` flag is set, then `--https.addr` and `--https.port` with both be ignored.
|
||||
|
||||
|
||||
### IPC endpoint (geth compatible)
|
||||
|
||||
erigon supports the geth-style unix socket IPC. you can enable this with `--socket.enabled` flag,
|
||||
@ -225,7 +226,7 @@ Label "remote" means: `--private.api.addr` flag is required.
|
||||
The following table shows the current implementation status of Erigon's RPC daemon.
|
||||
|
||||
| Command | Avail | Notes |
|
||||
| ------------------------------------------ |---------|--------------------------------------|
|
||||
| ------------------------------------------ | ------- | ------------------------------------ |
|
||||
| admin_nodeInfo | Yes | |
|
||||
| admin_peers | Yes | |
|
||||
| admin_addPeer | Yes | |
|
||||
@ -280,7 +281,7 @@ The following table shows the current implementation status of Erigon's RPC daem
|
||||
| eth_getFilterChanges | Yes | |
|
||||
| eth_uninstallFilter | Yes | |
|
||||
| eth_getLogs | Yes | |
|
||||
| interned spe | | |
|
||||
| interned spe | | |
|
||||
| eth_accounts | No | deprecated |
|
||||
| eth_sendRawTransaction | Yes | `remote`. |
|
||||
| eth_sendTransaction | - | not yet implemented |
|
||||
@ -337,6 +338,7 @@ The following table shows the current implementation status of Erigon's RPC daem
|
||||
| trace_transaction | Yes | |
|
||||
| | | |
|
||||
| txpool_content | Yes | `remote` |
|
||||
| txpool_contentFrom | Yes | `remote` |
|
||||
| txpool_status | Yes | `remote` |
|
||||
| | | |
|
||||
| eth_getCompilers | No | deprecated |
|
||||
@ -371,10 +373,10 @@ The following table shows the current implementation status of Erigon's RPC daem
|
||||
|
||||
### GraphQL
|
||||
|
||||
| Command | Avail | Notes |
|
||||
|--------------------------------------------|---------|--------------------------------------|
|
||||
| GetBlockDetails | Yes | |
|
||||
| GetChainID | Yes | |
|
||||
| Command | Avail | Notes |
|
||||
| --------------- | ----- | ----- |
|
||||
| GetBlockDetails | Yes | |
|
||||
| GetChainID | Yes | |
|
||||
|
||||
This table is constantly updated. Please visit again.
|
||||
|
||||
@ -530,10 +532,7 @@ with `rpc.accessList` flag.
|
||||
|
||||
```json
|
||||
{
|
||||
"allow": [
|
||||
"net_version",
|
||||
"web3_eth_getBlockByHash"
|
||||
]
|
||||
"allow": ["net_version", "web3_eth_getBlockByHash"]
|
||||
}
|
||||
```
|
||||
|
||||
@ -568,7 +567,7 @@ Currently batch requests are spawn multiple goroutines and process all sub-reque
|
||||
huge batch to other users - added flag `--rpc.batch.concurrency` (default: 2). Increase it to process large batches
|
||||
faster.
|
||||
|
||||
Known Issue: if at least 1 request is "streamable" (has parameter of type *jsoniter.Stream) - then whole batch will
|
||||
Known Issue: if at least 1 request is "streamable" (has parameter of type \*jsoniter.Stream) - then whole batch will
|
||||
processed sequentially (on 1 goroutine).
|
||||
|
||||
## For Developers
|
||||
|
@ -3,6 +3,7 @@ package jsonrpc
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/common/hexutil"
|
||||
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
@ -14,9 +15,10 @@ import (
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
)
|
||||
|
||||
// NetAPI the interface for the net_ RPC commands
|
||||
// TxPoolAPI the interface for the txpool_ RPC commands
|
||||
type TxPoolAPI interface {
|
||||
Content(ctx context.Context) (map[string]map[string]map[string]*RPCTransaction, error)
|
||||
ContentFrom(ctx context.Context, addr libcommon.Address) (map[string]map[string]*RPCTransaction, error)
|
||||
}
|
||||
|
||||
// TxPoolAPIImpl data structure to store things needed for net_ commands
|
||||
@ -116,6 +118,76 @@ func (api *TxPoolAPIImpl) Content(ctx context.Context) (map[string]map[string]ma
|
||||
return content, nil
|
||||
}
|
||||
|
||||
func (api *TxPoolAPIImpl) ContentFrom(ctx context.Context, addr libcommon.Address) (map[string]map[string]*RPCTransaction, error) {
|
||||
reply, err := api.pool.All(ctx, &proto_txpool.AllRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
content := map[string]map[string]*RPCTransaction{
|
||||
"pending": make(map[string]*RPCTransaction),
|
||||
"baseFee": make(map[string]*RPCTransaction),
|
||||
"queued": make(map[string]*RPCTransaction),
|
||||
}
|
||||
|
||||
pending := make([]types.Transaction, 0, 4)
|
||||
baseFee := make([]types.Transaction, 0, 4)
|
||||
queued := make([]types.Transaction, 0, 4)
|
||||
for i := range reply.Txs {
|
||||
txn, err := types.DecodeWrappedTransaction(reply.Txs[i].RlpTx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding transaction from: %x: %w", reply.Txs[i].RlpTx, err)
|
||||
}
|
||||
sender := gointerfaces.ConvertH160toAddress(reply.Txs[i].Sender)
|
||||
if sender != addr {
|
||||
continue
|
||||
}
|
||||
|
||||
switch reply.Txs[i].TxnType {
|
||||
case proto_txpool.AllReply_PENDING:
|
||||
pending = append(pending, txn)
|
||||
case proto_txpool.AllReply_BASE_FEE:
|
||||
baseFee = append(baseFee, txn)
|
||||
case proto_txpool.AllReply_QUEUED:
|
||||
queued = append(queued, txn)
|
||||
}
|
||||
}
|
||||
|
||||
tx, err := api.db.BeginRo(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
cc, err := api.chainConfig(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
curHeader := rawdb.ReadCurrentHeader(tx)
|
||||
if curHeader == nil {
|
||||
return nil, nil
|
||||
}
|
||||
// Flatten the pending transactions
|
||||
dump := make(map[string]*RPCTransaction)
|
||||
for _, txn := range pending {
|
||||
dump[fmt.Sprintf("%d", txn.GetNonce())] = newRPCPendingTransaction(txn, curHeader, cc)
|
||||
}
|
||||
content["pending"] = dump
|
||||
// Flatten the baseFee transactions
|
||||
dump = make(map[string]*RPCTransaction)
|
||||
for _, txn := range baseFee {
|
||||
dump[fmt.Sprintf("%d", txn.GetNonce())] = newRPCPendingTransaction(txn, curHeader, cc)
|
||||
}
|
||||
content["baseFee"] = dump
|
||||
// Flatten the queued transactions
|
||||
dump = make(map[string]*RPCTransaction)
|
||||
for _, txn := range queued {
|
||||
dump[fmt.Sprintf("%d", txn.GetNonce())] = newRPCPendingTransaction(txn, curHeader, cc)
|
||||
}
|
||||
content["queued"] = dump
|
||||
return content, nil
|
||||
}
|
||||
|
||||
// Status returns the number of pending and queued transaction in the pool.
|
||||
func (api *TxPoolAPIImpl) Status(ctx context.Context) (map[string]hexutil.Uint, error) {
|
||||
reply, err := api.pool.Status(ctx, &proto_txpool.StatusRequest{})
|
||||
|
Loading…
Reference in New Issue
Block a user