Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Developer mode #3699

Closed
pistomat opened this issue Jul 10, 2023 · 6 comments · Fixed by #3727
Closed

Add Developer mode #3699

pistomat opened this issue Jul 10, 2023 · 6 comments · Fixed by #3727
Labels
A-cli Related to the reth CLI C-enhancement New feature or request

Comments

@pistomat
Copy link
Contributor

Describe the feature

Introduction

The --dev flag in Geth client introduces a simple option to run a local single-node test network with no external connections. It uses zero gas fees, a custom genesis block and Clique proof-of-authority with the local node as a single trusted signer. It is often convenient for developers to work in an environment where changes to client or application software can be deployed and tested rapidly and without putting real-world users or assets at risk.

Current state

The auto-seal crate is "a [Consensus] implementation for local testing purposes that automatically seals blocks." It was developed for the hive tests, but as far as I know it does not work as a standalone local testnet (at least I could not get it to mine new transactions).

Additional context

Geth documentation of the --dev flag: https://geth.ethereum.org/docs/developers/dapp-developer/dev-mode

Reth auto-seal crate used by the --auto-miner flag: https://github.com/paradigmxyz/reth/tree/3910babb913e17debd2479c385a48799d7fa6157/crates/consensus/auto-seal

@pistomat pistomat added C-enhancement New feature or request S-needs-triage This issue needs to be labelled labels Jul 10, 2023
@pistomat
Copy link
Contributor Author

pistomat commented Jul 10, 2023

i have been using the following testnet.json:

{
    "config": {
        "chainId": 1337,
        "homesteadBlock": 0,
        "eip150Block": 0,
        "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
        "eip155Block": 0,
        "eip158Block": 0,
        "byzantiumBlock": 0,
        "constantinopleBlock": 0,
        "petersburgBlock": 0,
        "istanbulBlock": 0,
        "muirGlacierBlock": 0,
        "berlinBlock": 0,
        "londonBlock": 0,
        "arrowGlacierBlock": 0,
        "grayGlacierBlock": 0,
        "shanghaiTime": 0,
        "terminalTotalDifficulty": 0,
        "terminalTotalDifficultyPassed": true,
        "ethash": {}
    },
    "nonce": "0x0",
    "timestamp": "0x0",
    "extraData": "0x",
    "gasLimit": "0x4c4b40",
    "difficulty": "0x1",
    "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "coinbase": "0x0000000000000000000000000000000000000000",
    "alloc": {
        "0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf": {
            "balance": "0x56bc75e2d63100000"
        }
    },
    "number": "0x0",
    "gasUsed": "0x0",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "baseFeePerGas": "0x0"
}

Running the node on commit 31af4d5 with reth node --datadir ./testnet --auto-mine --http --disable-discovery --chain ./testnet/testnet.json produces the following output:

INFO reth::cli: reth 0.1.0-alpha.2 (d35531e7) starting
INFO reth::cli: Configuration loaded path="./testnet/reth.toml"
INFO reth::cli: Opening database path="./testnet/db"
INFO reth::cli: Database opened
INFO reth::cli: Pre-merge hard forks (block based):
- Homestead                        @0
- Tangerine                        @0
- SpuriousDragon                   @0
- Byzantium                        @0
- Constantinople                   @0
- Petersburg                       @0
- Istanbul                         @0
- MuirGlacier                      @0
- Berlin                           @0
- London                           @0
- ArrowGlacier                     @0
- GrayGlacier                      @0
Merge hard forks:
- Paris                            @0 (network is not known to be merged)

Post-merge hard forks (timestamp based):
- Shanghai                         @0

INFO reth::cli: Transaction pool initialized
INFO reth::cli: Connecting to P2P network
INFO net::peers: Loading saved peers file=./testnet/known-peers.json
INFO reth::cli: Connected to P2P network peer_id=0x1e4a…63fe local_addr=0.0.0.0:30303
INFO reth::cli: Consensus engine initialized
INFO reth::cli: Engine API handler initialized
INFO reth::cli: RPC auth server started url=127.0.0.1:8551
INFO reth::cli: RPC IPC server started url=/tmp/reth.ipc
INFO reth::cli: RPC HTTP server started url=127.0.0.1:8545
INFO reth::cli: Starting consensus engine
INFO reth::cli: Status connected_peers=0 latest_block=0
WARN make_canonical{block_hash=0xa0a615d75cf09ed29de0b997558d9fb52023b781840b63208cc9fb23e506454d}: blockchain_tree: Block hash not found in block indices block_hash=0xa0a615d75cf09ed29de0b997558d9fb52023b781840b63208cc9fb23e506454d
WARN consensus::engine: Failed to canonicalize the head hash error=Execution(BlockHashNotFoundInChain { block_hash: 0xa0a615d75cf09ed29de0b997558d9fb52023b781840b63208cc9fb23e506454d }) state=ForkchoiceState { head_block_hash: 0xa0a615d75cf09ed29de0b997558d9fb52023b781840b63208cc9fb23e506454d, safe_block_hash: 0xa0a615d75cf09ed29de0b997558d9fb52023b781840b63208cc9fb23e506454d, finalized_block_hash: 0xa0a615d75cf09ed29de0b997558d9fb52023b781840b63208cc9fb23e506454d }
INFO reth::node::events: Forkchoice updated head_block_hash=0xa0a615d75cf09ed29de0b997558d9fb52023b781840b63208cc9fb23e506454d safe_block_hash=0xa0a615d75cf09ed29de0b997558d9fb52023b781840b63208cc9fb23e506454d finalized_block_hash=0xa0a615d75cf09ed29de0b997558d9fb52023b781840b63208cc9fb23e506454d status=Syncing
INFO try_insert_validated_block{block=(1, 0xa0a615d75cf09ed29de0b997558d9fb52023b781840b63208cc9fb23e506454d)}: blockchain_tree: return=Ok(Valid)
INFO make_canonical{block_hash=0xa0a615d75cf09ed29de0b997558d9fb52023b781840b63208cc9fb23e506454d}: blockchain_tree: Committing new canonical chain: [(1, 0xa0a615d75cf09ed29de0b997558d9fb52023b781840b63208cc9fb23e506454d)]
INFO reth::cli: Status connected_peers=0 latest_block=0

As we can see there are two WARN logs about failing to canonicalize block 1 with hash 0xa0a6, but it seems to be resolved and looking into db with reth db --datadir ./testnet list CanonicalHeaders there are both blocks 0 and 1 (hence probably only a warning and not an error).

Sending a raw transaction:

$ curl http://127.0.0.1:8545 \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["0xf86e808502540be400825208942b5ad5c4795c026514f8317c7a215e218dccd6cf880de0b6b3a764000080820a96a00f6fe5f68d0727ebfff61366e08c681ffa1a8ae044e67bc583c3582ab77006fca05067cccf52537635dc30bee10785a0de31ce6df2c8943d7ff437ee59854f984c"],"id":1}'

{"jsonrpc":"2.0","result":"0x24feba64144876530eade5c98f1530388e34512164251dcb53ac1d75f99d418b","id":1}

does not actually mine the transaction. Trace logs from the node about the eth_sendRawTransaction call are

TRACE mio::poll: registering event source with poller: token=Token(4), interests=READABLE | WRITABLE    
DEBUG connection{remote_addr=127.0.0.1:54260 conn_id=0}: jsonrpsee_server::server: Accepting new connection 1/100
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::conn: Conn::read_head
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::conn: flushed({role=server}): State { reading: Init, writing: Init, keep_alive: Busy }
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::conn: Conn::read_head
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::io: received 430 bytes
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}:parse_headers: hyper::proto::h1::role: Request.parse bytes=430
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}:parse_headers: hyper::proto::h1::role: Request.parse Complete(132)
DEBUG connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::io: parsed 5 headers
DEBUG connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::conn: incoming body is content-length (298 bytes)
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: jsonrpsee_server::server: Request { method: POST, uri: /, version: HTTP/1.1, headers: {"host": "127.0.0.1:8545", "user-agent": "curl/7.88.1", "accept": "*/*", "content-type": "application/json", "content-length": "298"}, body: Body(Streaming) }
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::decode: decode; state=Length(298)
DEBUG connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::conn: incoming body completed
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: jsonrpsee_core::http_helpers: HTTP response body: {"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["0xf86e808502540be400825208942b5ad5c4795c026514f8317c7a215e218dccd6cf880de0b6b3a764000080820a96a00f6fe5f68d0727ebfff61366e08c681ffa1a8ae044e67bc583c3582ab77006fca05067cccf52537635dc30bee10785a0de31ce6df2c8943d7ff437ee59854f984c"],"id":1}
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}:method_call{method="eth_sendRawTransaction"}: jsonrpsee_core::tracing: recv="{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_sendRawTransaction\",\"params\":[\"0xf86e808502540be400825208942b5ad5c4795c026514f8317c7a215e218dccd6cf880de0b6b3a764000080820a96a00f6fe5f68d0727ebfff61366e08c681ffa1a8ae044e67bc583c3582ab77006fca05067cccf52537635dc30bee10785a0de31ce6df2c8943d7ff437ee59854f984c\"]}"
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}:method_call{method="eth_sendRawTransaction"}: jsonrpsee_types::params: [next_inner] Params JSON: "[\"0xf86e808502540be400825208942b5ad5c4795c026514f8317c7a215e218dccd6cf880de0b6b3a764000080820a96a00f6fe5f68d0727ebfff61366e08c681ffa1a8ae044e67bc583c3582ab77006fca05067cccf52537635dc30bee10785a0de31ce6df2c8943d7ff437ee59854f984c\"]"
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}:method_call{method="eth_sendRawTransaction"}: rpc::eth: Serving eth_sendRawTransaction tx=Bytes(0xf86e808502540be400825208942b5ad5c4795c026514f8317c7a215e218dccd6cf880de0b6b3a764000080820a96a00f6fe5f68d0727ebfff61366e08c681ffa1a8ae044e67bc583c3582ab77006fca05067cccf52537635dc30bee10785a0de31ce6df2c8943d7ff437ee59854f984c)
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::conn: flushed({role=server}): State { reading: KeepAlive, writing: Init, keep_alive: Busy }
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::conn: flushed({role=server}): State { reading: KeepAlive, writing: Init, keep_alive: Busy }
TRACE providers::blockchain: Getting latest block state provider
TRACE providers::db: Returning latest state provider
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}:method_call{method="eth_sendRawTransaction"}: jsonrpsee_core::tracing: send="{\"jsonrpc\":\"2.0\",\"result\":\"0x24feba64144876530eade5c98f1530388e34512164251dcb53ac1d75f99d418b\",\"id\":1}"
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}:encode_headers: hyper::proto::h1::role: Server::encode status=200, body=Some(Known(102)), req_method=Some(POST)
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::io: buffer.queue self.len=124 buf.len=102
DEBUG connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::io: flushed 226 bytes
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::conn: flushed({role=server}): State { reading: Init, writing: Init, keep_alive: Idle }
TRACE net::tx: Start propagating transactions
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::conn: Conn::read_head
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::io: received 0 bytes
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::io: parse eof
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::conn: State::close_read()
DEBUG connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::conn: read eof
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::conn: State::close_write()
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::conn: State::close_read()
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::conn: State::close_write()
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::conn: flushed({role=server}): State { reading: Closed, writing: Closed, keep_alive: Disabled }
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: hyper::proto::h1::conn: shut down IO complete
TRACE connection{remote_addr=127.0.0.1:54260 conn_id=0}: mio::poll: deregistering event source from poller 

There are still 0 Transactions in the db and we are still on block 1. Although I am not even sure about that, because the regular info prints latest block is 0:

INFO reth::cli: Status connected_peers=0 latest_block=0

@pistomat
Copy link
Contributor Author

Tagging @manylov because he has been trying to run a local node with --auto-mine for a while and has been actively posting issues regarding this functionality.

@onbjerg
Copy link
Member

onbjerg commented Jul 11, 2023

There are still 0 Transactions in the db and we are still on block 1. Although I am not even sure about that, because the regular info prints latest block is 0:

You're on block 0 (genesis) because it failed to canonicalize the first block as it wrote in the logs (the logs are not super helpful here I guess), but it's not fatal as we can always retry later. This is from the live sync component (blockchain tree)

There are still 0 Transactions in the db and we are still on block 1. Although I am not even sure about that, because the regular info prints latest block is 0:

This makes sense since the new block has not been canonicalized yet, so nothing is written to the database, although OTOH it does not make sense as you obviously want a new block to be sealed instantly.

Looping in @mattsse / @Rjected here as I think they know more about the auto-seal engine and might have ideas for what's wrong here, although I think you should probably make a bug report describing how the current auto-seal engine is broken as it is somewhat unrelated to this issue which is just UX

@onbjerg onbjerg added A-cli Related to the reth CLI and removed S-needs-triage This issue needs to be labelled labels Jul 11, 2023
@Rjected
Copy link
Member

Rjected commented Jul 11, 2023

What's happening here is because we no longer run the pipeline for short ranges, we never emit a PipelineRunning event for the Finish stage which is supposed to be caught here:

// wait for the pipeline to finish
if let Some(events) = events.as_mut() {
debug!(target: "consensus::auto", "waiting for finish stage event...");
// wait for the finish stage to
loop {
if let Some(PipelineEvent::Running { stage_id, .. }) =
events.next().await
{
if stage_id == StageId::Finish {
debug!(target: "consensus::auto", "received finish stage event");
break
}
}
}
}

@pistomat
Copy link
Contributor Author

pistomat commented Jul 11, 2023

Ah, so what is the proper course of action here?

  1. run the pipeline for short ranges again (not sure actually what you mean by that), or
  2. insert the StageId::Finish somewhere manually, or
  3. skip waiting for the finish stage (presuming auto-seal is not being run with stages anyway)

If the autoseal is working for local test node I can take on the rest of the work of adding the --dev option, setting up a tesnet genesis file etc.

@Rjected
Copy link
Member

Rjected commented Jul 11, 2023

Ah, so what is the proper course of action here?

It's basically this:

skip waiting for the finish stage (presuming auto-seal is not being run with stages anyway)

We need to listen for the block being added in some other way since the pipeline is not going to run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-cli Related to the reth CLI C-enhancement New feature or request
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants