Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions testnet-single-node-deploy/testnet-config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[mining]
miner_address = "tmLTZegcJN5zaufWQBARHkvqC62mTumm3jR"

[network]
network = "Testnet"
listen_addr = "0.0.0.0:18233"
initial_testnet_peers = []

[network.testnet_parameters]
network_name = "QEDTestnet"
network_magic = [0x51, 0x45, 0x44, 0x54]
disable_pow = true
# extend_funding_stream_addresses_as_required prevents a startup panic from the default
# testnet funding stream address-count validation. The funding_streams = [] below clears
# them at runtime, but the extend flag is needed to survive the earlier validation pass.
extend_funding_stream_addresses_as_required = true
funding_streams = []

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if [] is a problem just specify a fixed address.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tx-tool builds a "coinbase" that doesn't include any funding outputs. If we set a fixed address as a funding stream, Zebra would require the coinbase to pay to it (which we can't do), and every block would be rejected

lockbox_disbursements = []

[network.testnet_parameters.activation_heights]
NU5 = 1
NU6 = 1
NU7 = 1

[state]
ephemeral = true

[mempool]
debug_enable_at_height = 0

[rpc]
listen_addr = "0.0.0.0:18232"
enable_cookie_auth = false
15 changes: 14 additions & 1 deletion zebra-chain/src/block/genesis.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Regtest genesis block
//! Regtest and Testnet genesis blocks

use std::sync::Arc;

Expand All @@ -17,3 +17,16 @@ pub fn regtest_genesis_block() -> Arc<Block> {
.map(Arc::new)
.expect("hard-coded Regtest genesis block data must deserialize successfully")
}

/// Genesis block for Testnet (and configured testnets that share the Testnet genesis hash),
/// copied from zcashd via `getblock 0 0 -testnet` RPC method
pub fn testnet_genesis_block() -> Arc<Block> {
let testnet_genesis_block_bytes =
<Vec<u8>>::from_hex(include_str!("genesis/block-testnet-0-000-000.txt").trim())
.expect("Block bytes are in valid hex representation");

testnet_genesis_block_bytes
.zcash_deserialize_into()
.map(Arc::new)
.expect("hard-coded Testnet genesis block data must deserialize successfully")
}
1 change: 1 addition & 0 deletions zebra-chain/src/block/genesis/block-testnet-0-000-000.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
040000000000000000000000000000000000000000000000000000000000000000000000db4d7a85b768123f1dff1d4c4cece70083b2d27e117b4ac2e31d087988a5eac40000000000000000000000000000000000000000000000000000000000000000a11e1358ffff07200600000000000000000000000000000000000000000000000000000000000000fd400500a6a51259c3f6732481e2d035197218b7a69504461d04335503cd69759b2d02bd2b53a9653f42cb33c608511c953673fa9da76170958115fe92157ad3bb5720d927f18e09459bf5c6072973e143e20f9bdf0584058c96b7c2234c7565f100d5eea083ba5d3dbaff9f0681799a113e7beff4a611d2b49590563109962baa149b628aae869af791f2f70bb041bd7ebfa658570917f6654a142b05e7ec0289a4f46470be7be5f693b90173eaaa6e84907170f32602204f1f4e1c04b1830116ffd0c54f0b1caa9a5698357bd8aa1f5ac8fc93b405265d824ba0e49f69dab5446653927298e6b7bdc61ee86ff31c07bde86331b4e500d42e4e50417e285502684b7966184505b885b42819a88469d1e9cf55072d7f3510f85580db689302eab377e4e11b14a91fdd0df7627efc048934f0aff8e7eb77eb17b3a95de13678004f2512293891d8baf8dde0ef69be520a58bbd6038ce899c9594cf3e30b8c3d9c7ecc832d4c19a6212747b50724e6f70f6451f78fd27b58ce43ca33b1641304a916186cfbe7dbca224f55d08530ba851e4df22baf7ab7078e9cbea46c0798b35a750f54103b0cdd08c81a6505c4932f6bfbd492a9fced31d54e98b6370d4c96600552fcf5b37780ed18c8787d03200963600db297a8f05dfa551321d17b9917edadcda51e274830749d133ad226f8bb6b94f13b4f77e67b35b71f52112ce9ba5da706ad9573584a2570a4ff25d29ab9761a06bdcf2c33638bf9baf2054825037881c14adf3816ba0cbd0fca689aad3ce16f2fe362c98f48134a9221765d939f0b49677d1c2447e56b46859f1810e2cf23e82a53e0d44f34dae932581b3b7f49eaec59af872cf9de757a964f7b33d143a36c270189508fcafe19398e4d2966948164d40556b05b7ff532f66f5d1edc41334ef742f78221dfe0c7ae2275bb3f24c89ae35f00afeea4e6ed187b866b209dc6e83b660593fce7c40e143beb07ac86c56f39e895385924667efe3a3f031938753c7764a2dbeb0a643fd359c46e614873fd0424e435fa7fac083b9a41a9d6bf7e284eee537ea7c50dd239f359941a43dc982745184bf3ee31a8dc850316aa9c6b66d6985acee814373be3458550659e1a06287c3b3b76a185c5cb93e38c1eebcf34ff072894b6430aed8d34122dafd925c46a515cca79b0269c92b301890ca6b0dc8b679cdac0f23318c105de73d7a46d16d2dad988d49c22e9963c117960bdc70ef0db6b091cf09445a516176b7f6d58ec29539166cc8a38bbff387acefffab2ea5faad0e8bb70625716ef0edf61940733c25993ea3de9f0be23d36e7cb8da10505f9dc426cd0e6e5b173ab4fff8c37e1f1fb56d1ea372013d075e0934c6919393cfc21395eea20718fad03542a4162a9ded66c814ad8320b2d7c2da3ecaf206da34c502db2096d1c46699a91dd1c432f019ad434e2c1ce507f91104f66f491fed37b225b8e0b2888c37276cfa0468fc13b8d593fd9a2675f0f5b20b8a15f8fa7558176a530d6865738ddb25d3426dab905221681cf9da0e0200eea5b2eba3ad3a5237d2a391f9074bf1779a2005cee43eec2b058511532635e0fea61664f531ac2b356f40db5c5d275a4cf5c82d468976455af4e3362cc8f71aa95e71d394aff3ead6f7101279f95bcd8a0fedce1d21cb3c9f6dd3b182fce0db5d6712981b651f29178a24119968b14783cafa713bc5f2a65205a42e4ce9dc7ba462bdb1f3e4553afc15f5f39998fdb53e7e231e3e520a46943734a007c2daa1eda9f495791657eefcac5c32833936e568d06187857ed04d7b97167ae207c5c5ae54e528c36016a984235e9c5b2f0718d7b3aa93c7822ccc772580b6599671b3c02ece8a21399abd33cfd3028790133167d0a97e7de53dc8ff0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff071f0104455a6361736830623963346565663862376363343137656535303031653335303039383462366665613335363833613763616331343161303433633432303634383335643334ffffffff010000000000000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000
6 changes: 5 additions & 1 deletion zebra-network/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,10 @@ impl<'de> Deserialize<'de> for Config {
}

// Set configured funding streams after setting any parameters that affect the funding stream address period.
// Distinguish "not configured" (None, keep defaults) from "explicitly cleared" (Some([]), clear).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes a bug where funding_streams = [] in the TOML config was silently ignored

let explicitly_configured = funding_streams.is_some()
|| post_nu6_funding_streams.is_some()
|| pre_nu6_funding_streams.is_some();
let mut funding_streams_vec = funding_streams.unwrap_or_default();

if let Some(funding_streams) = post_nu6_funding_streams {
Expand All @@ -868,7 +872,7 @@ impl<'de> Deserialize<'de> for Config {
funding_streams_vec.insert(0, funding_streams);
}

if !funding_streams_vec.is_empty() {
if explicitly_configured {
params_builder = params_builder.with_funding_streams(funding_streams_vec);
}

Expand Down
23 changes: 17 additions & 6 deletions zebrad/src/commands/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ use tokio::{pin, select, sync::oneshot};
use tower::{builder::ServiceBuilder, util::BoxService, ServiceExt};
use tracing_futures::Instrument;

use zebra_chain::block::genesis::regtest_genesis_block;
use zebra_chain::block::genesis::{regtest_genesis_block, testnet_genesis_block};
use zebra_consensus::router::BackgroundTaskHandles;
use zebra_rpc::{methods::RpcImpl, server::RpcServer, SubmitBlockChannel};

Expand Down Expand Up @@ -115,8 +115,14 @@ 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 {
// A configured testnet with PoW disabled and no peers is a private isolated network
// (similar to Regtest). It needs the same bootstrap treatment: commit the genesis block
Comment on lines +118 to +119

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are aiming for a testnet, not necessarily isolated.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do testnet Zebra by definition will try to connect to other nodes. There is only 1 situation where Zebra can use it's own genesis block without other nodes, and it's gated on is_regtest.
If we want testnet without other nodes the only option is to adapt this code.

// locally and skip the P2P syncer.
let is_isolated_configured_testnet = !is_regtest
&& config.network.network.disable_pow()
&& config.network.initial_testnet_peers.is_empty();

let config = if is_regtest || is_isolated_configured_testnet {
Arc::new(ZebradConfig {
mempool: mempool::Config {
debug_enable_at_height: Some(0),
Expand Down Expand Up @@ -370,16 +376,21 @@ impl StartCmd {
);

info!("spawning syncer task");
let syncer_task_handle = if is_regtest {
let syncer_task_handle = if is_regtest || is_isolated_configured_testnet {
if !syncer
.state_contains(config.network.network.genesis_hash())
.await?
{
let genesis_block = if is_regtest {
regtest_genesis_block()
} else {
testnet_genesis_block()
};
let genesis_hash = block_verifier_router
Comment on lines +384 to 389

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't fully understand why we need to change the zebra code. Zebra has already a stable testnet infrastructure and we need to use it. These changes will not be merged to upstream and will interfere the review process later.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Zebras testnet is designed to sync from the public Zcash testnet via peers.
The genesis block reaches the node via those peers. There is no mechanism to run a testnet node standalone - without peers

.clone()
.oneshot(zebra_consensus::Request::Commit(regtest_genesis_block()))
.oneshot(zebra_consensus::Request::Commit(genesis_block))
.await
.expect("should validate Regtest genesis block");
.expect("should validate genesis block");

assert_eq!(
genesis_hash,
Expand Down
Loading