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(book): Adds a section on Regtest usage to the Zebra book #8526

Merged
merged 12 commits into from
May 22, 2024
1 change: 1 addition & 0 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- [Shielded Scanning gRPC Server](user/shielded-scan-grpc-server.md)
- [Kibana blockchain explorer](user/elasticsearch.md)
- [Forking the Zcash Testnet with Zebra](user/fork-zebra-testnet.md)
- [Regtest with Zebra](user/regtest.md)
- [OpenAPI specification](user/openapi.md)
- [Troubleshooting](user/troubleshooting.md)
- [Developer Documentation](dev.md)
Expand Down
61 changes: 61 additions & 0 deletions book/src/user/regtest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Regtest with Zebra

The Regtest network in Zebra enables testing of custom functionalities in a private testnet environment with configurable network upgrade activation heights. It allows for starting an isolated node which won't connect to any peers and currently allows for committing blocks without validating their Proof of Work (in the future, it may use a very low target difficulty and easier Equihash parameters instead of skipping Proof of Work validation altogether).

Zebra always activates the Canopy network upgrade at block height 1 due to limitations on its block construction.

In order to use Regtest, Zebra must be configured to run on the Regtest network. The `[mining]` section is also necessary for mining blocks, and the `[rpc]` section is necessary for using the `send_raw_transaction` RPC method to mine non-coinbase transactions onto the chain.

Relevant parts of the configuration file:

```toml
[mining]
miner_address = 't27eWDgjFYJGVXmzrXeVjnb5J3uXDM9xH9v'

[network]
network = "Regtest"

// This section may be omitted when testing only Canopy
arya2 marked this conversation as resolved.
Show resolved Hide resolved
[network.testnet_parameters.activation_heights]
// Configured activation heights must be greater than or equal to 1,
arya2 marked this conversation as resolved.
Show resolved Hide resolved
// block height 0 is reserved for the Genesis network upgrade in Zebra
arya2 marked this conversation as resolved.
Show resolved Hide resolved
NU5 = 1

// This section may be omitted if a persistent Regtest chain state is desired
arya2 marked this conversation as resolved.
Show resolved Hide resolved
[state]
ephemeral = true

// This section may be omitted if it's not necessary to send transactions to Zebra's mempool
arya2 marked this conversation as resolved.
Show resolved Hide resolved
[rpc]
listen_addr = "0.0.0.0:18232"
```

arya2 marked this conversation as resolved.
Show resolved Hide resolved
There are two ways to commit blocks to Zebra's state on Regtest:
- Using the `getblocktemplate` and `submitblock` RPC methods directly
- Using Zebra's experimental `internal-miner` feature

## Using Zebra's Internal Miner

Zebra can mine blocks on the Regtest network when compiled with the experimental `internal-miner` compilation feature and configured to enable to internal miner.

Compile Zebra with `cargo build --features "internal-miner"` and add `internal_miner = true` in the mining section of its configuration to use the internal miner with Regtest:
oxarbitrage marked this conversation as resolved.
Show resolved Hide resolved

```toml
[mining]
internal_miner = true
```
arya2 marked this conversation as resolved.
Show resolved Hide resolved

## Using RPC methods directly

Blocks could also be mined outside of Zebra and submitted via Zebra's RPC methods. This requires enabling the RPC server in the configuration by providing a `listen_addr` field:

```toml
[rpc]
listen_addr = "0.0.0.0:18232"
```

arya2 marked this conversation as resolved.
Show resolved Hide resolved
With Proof of Work disabled on Regtest, block templates can be converted directly into blocks with the `proposal_block_from_template()` function in the `zebra-chain` crate, serialized, hex-encoded, and then submitted via the `submitblock` RPC method.

When Proof of Work validation is enabled for Regtest with a low target difficulty and easy Equihash parameters, Zebra may have a `network.testnet_parameters.disable_pow` field in its configuration so that this would continue working.

See the `regtest_submit_blocks()` acceptance test as an example for using Zebra's RPC methods to submit blocks on Regtest.
2 changes: 1 addition & 1 deletion zebrad/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ edition = "2021"

# Zebra is only supported on the latest stable Rust version. See the README for details.
# Any Zebra release can break compatibility with older Rust versions.
rust-version = "1.73"
rust-version = "1.76"

# Settings that impact runtime behaviour

Expand Down
17 changes: 16 additions & 1 deletion zebrad/src/commands/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@
//!
//! Some of the diagnostic features are optional, and need to be enabled at compile-time.

use std::sync::Arc;

use abscissa_core::{config, Command, FrameworkError};
use color_eyre::eyre::{eyre, Report};
use futures::FutureExt;
Expand Down Expand Up @@ -113,6 +115,19 @@ pub struct StartCmd {
impl StartCmd {
async fn start(&self) -> Result<(), Report> {
let config = APPLICATION.config();
let is_regtest = config.network.network.is_regtest();

let config = if is_regtest {
Arc::new(ZebradConfig {
mempool: mempool::Config {
debug_enable_at_height: Some(0),
..config.mempool
},
..Arc::unwrap_or_clone(config)
})
} else {
config
};

info!("initializing node state");
let (_, max_checkpoint_height) = zebra_consensus::router::init_checkpoint_list(
Expand Down Expand Up @@ -301,7 +316,7 @@ impl StartCmd {
);

info!("spawning syncer task");
let syncer_task_handle = if config.network.network.is_regtest() {
let syncer_task_handle = if is_regtest {
if !syncer
.state_contains(config.network.network.genesis_hash())
.await?
Expand Down
Loading