This fixes 2 related issues:
* Now that the bor consensus engine is required for queries it can't be
created based on the pretense of a db directory, but must be based on
chain config read from the db. Using the DB presence causes Bor to get
instantiated for non bor chains which breaks.
* At the moment eth_calls on a remote daemon don't check Bor headers
prior to calling the EVM code as it was just using a fake ETHash
instance - which performs ETH header validation only.
The current version is mostly working but needs adapting to perform lazy
initialization of the engine.
Otterscan API search methods allow the user to inform the page size.
This PR adds an internal max (default == 25 results) to cap the page
size, regardless of what the user asks.
It also adds a `--ots.search.max.pagesize` CLI args to override this max
(either in erigon and rpcdaemon binaries).
This PR separates ENGINE from Ethbackend. It makes it so:
1) EthBackend not a god class
2) We can abstract away engine API so that we can make it CL-like and
enable Consensus-Execution driven design
3) Objective is Json-RPC -> Engine Consensus Module -> Execution module.
- breaks dependency from staged_sync to package with block_reader
implementation
- breaks dependency from snap_sync to package with block_reader
implementation
- breaks dependency from mining to txpool implementation
- always RLock all snapshots - to guarantee consistency
- introduce class View (analog of RoTx and MakeContext)
- move read methods to View object
- View object will be managed by temporal_tx
---------
Co-authored-by: Alex Sharp <alexsharp@Alexs-MacBook-Pro-2.local>
This is the beginning of the series of changes to make it possible to
run multiple instances of erigon inside a single process (as devnet tool
does), with the logging from these processes going to respective log
files correctly.
This is the first part where the initial infrastructure is being
established
---------
Co-authored-by: Alex Sharp <alexsharp@Alexs-MacBook-Pro-2.local>
The CLI logging currently emits the configured address when noting that
the HTTP or Engine RPC services are started. This is _usually_ the same
as the listening address, but not always. In particular, when the bind
directive specifies an ambiguous parameter, like port 0 for an ephemeral
port, the actually bound address will differ.
This change will help users to operate Erigon while binding to ephemeral
ports. This is especially helpful for developers trying to run multiple
instances of Erigon concurrently in tests which may or may not be
executing in parallel.
Co-authored-by: Jason Yellick <jason@enya.ai>
That's an initial PR mostly for code review, not ready for production
use
Got basic GraphQL working when querying a single block
---------
Co-authored-by: Alex Sharov <AskAlexSharov@gmail.com>
Discord user had issue
`
hey guys, any tips how to enable ws ? (other than --ws)? Ah its running
on 8545 by default. I was expecting it on 8546. I would like if this
could also be set by a flag same way as a HTTP flag.
`
later conversation
```
Q: yeah, is it not clear that it's enabling websocket for the http handler?
A: Its not super obvious no.
```
Adds a small copy to ws flag to make this more obvious
this pr adds CLI flag to allow the rpcdaemon to bind to a TCP port.
this is very useful if one wants to maintain a remote connection with
the rpcdaemon without using websocket. This is useful because a lot of
issues come with the websocket protocol (compression, max size, etc).
TCP socket gets around these things (it is just raw json over tcp
stream)
the rpc package already supports this, it was just a matter of adding
the bind.
try `echo
'{"jsonrpc":"2.0","method":"eth_blockNumber","id":"1","params":[""]}' |
nc localhost 8548` as a basic test
to test. Subscriptions are also working (idk how to send keepalives with
netcat)
the default rpc.(*Client).Dial method does not support TCP. I have not
included that in this PR. The code for such is as follow
```
// DialTCP create a new TCP client that connects to the given endpoint.
//
// The context is used for the initial connection establishment. It does not
// affect subsequent interactions with the client.
func DialTCP(ctx context.Context, endpoint string) (*Client, error) {
parsed, err := url.Parse(endpoint)
if err != nil {
return nil, err
}
ans := make(chan *Client)
errc := make(chan error)
go func() {
client, err := newClient(ctx, func(ctx context.Context) (ServerCodec, error) {
conn, err := net.Dial("tcp", parsed.Host)
if err != nil {
return nil, err
}
return NewCodec(conn), nil
})
if err != nil {
errc <- err
return
}
ans <- client
}()
select {
case err := <-errc:
return nil, err
case a := <-ans:
return a, nil
case <-ctx.Done():
return nil, ctx.Err()
}
}
// DialContext creates a new RPC client, just like Dial.
//
// The context is used to cancel or time out the initial connection establishment. It does
// not affect subsequent interactions with the client.
func DialContext(ctx context.Context, rawurl string) (*Client, error) {
u, err := url.Parse(rawurl)
if err != nil {
return nil, err
}
switch u.Scheme {
case "http", "https":
return DialHTTP(rawurl)
case "ws", "wss":
return DialWebsocket(ctx, rawurl, "")
case "tcp":
return DialTCP(ctx, rawurl)
case "stdio":
return DialStdIO(ctx)
case "":
return DialIPC(ctx, rawurl)
default:
return nil, fmt.Errorf("no known transport for URL scheme %q", u.Scheme)
}
}
```
let me know if you would like me to add this to the PR as well. the TCP
connection can then be established with `rpc.Dial("tcp://host:port")`