Adds test for committing Canopy blocks on Regtest

This commit is contained in:
Arya 2024-04-29 20:05:55 -04:00
parent 071cb1c0e5
commit 088e4e4904
6 changed files with 114 additions and 4 deletions

View File

@ -199,14 +199,13 @@ impl Network {
pub fn kind(&self) -> NetworkKind {
match self {
Network::Mainnet => NetworkKind::Mainnet,
// TODO: Return `NetworkKind::Regtest` if the parameters match the default Regtest params
Network::Testnet(params) if params.is_regtest() => NetworkKind::Regtest,
Network::Testnet(_) => NetworkKind::Testnet,
}
}
/// Returns an iterator over [`Network`] variants.
pub fn iter() -> impl Iterator<Item = Self> {
// TODO: Use default values of `Testnet` variant when adding fields for #7845.
[Self::Mainnet, Self::new_default_testnet()].into_iter()
}

View File

@ -109,12 +109,11 @@ lazy_static! {
let mut hash_map = HashMap::new();
hash_map.insert(NetworkKind::Mainnet, Height(1_046_400)..Height(2_726_400));
hash_map.insert(NetworkKind::Testnet, Height(1_028_500)..Height(2_796_000));
hash_map.insert(NetworkKind::Regtest, Height(1_028_500)..Height(2_796_000));
hash_map
};
/// Convenient storage for all addresses, for all receivers and networks
// TODO: Move the value here to a field on `testnet::Parameters` (#8367)
// There are no funding stream addresses on Regtest in zcashd, zebrad should do the same for compatibility.
pub static ref FUNDING_STREAM_ADDRESSES: HashMap<NetworkKind, HashMap<FundingStreamReceiver, Vec<String>>> = {
let mut addresses_by_network = HashMap::with_capacity(2);
@ -132,6 +131,16 @@ lazy_static! {
testnet_addresses.insert(FundingStreamReceiver::MajorGrants, FUNDING_STREAM_MG_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
addresses_by_network.insert(NetworkKind::Testnet, testnet_addresses);
// Regtest addresses
// TODO: Move the value here to a field on `testnet::Parameters` (#8367)
// There are no funding stream addresses on Regtest in zcashd, zebrad should do the same for compatibility.
let mut regtest_addresses = HashMap::with_capacity(3);
regtest_addresses.insert(FundingStreamReceiver::Ecc, FUNDING_STREAM_ECC_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
regtest_addresses.insert(FundingStreamReceiver::ZcashFoundation, FUNDING_STREAM_ZF_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
regtest_addresses.insert(FundingStreamReceiver::MajorGrants, FUNDING_STREAM_MG_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
addresses_by_network.insert(NetworkKind::Testnet, regtest_addresses);
addresses_by_network
};
}

View File

@ -399,6 +399,7 @@ lazy_static! {
hash_map.insert(NetworkKind::Mainnet, Version::min_specified_for_upgrade(&Mainnet, Nu5));
hash_map.insert(NetworkKind::Testnet, Version::min_specified_for_upgrade(&Network::new_default_testnet(), Nu5));
hash_map.insert(NetworkKind::Regtest, Version::min_specified_for_upgrade(&Network::new_regtest(None), Nu5));
hash_map
};

View File

@ -3127,3 +3127,14 @@ async fn validate_regtest_genesis_block() {
"validated block hash should match network genesis hash"
)
}
/// Test successful `getblocktemplate` and `submitblock` RPC calls on Regtest on Canopy.
///
/// See [`common::regtest::submit_blocks`] for more information.
// TODO: Test this with an NU5 activation height too once config can be serialized.
#[tokio::test]
#[cfg(feature = "getblocktemplate-rpcs")]
async fn regtest_submit_blocks() -> Result<()> {
common::regtest::submit_blocks_test().await?;
Ok(())
}

View File

@ -24,5 +24,8 @@ pub mod checkpoints;
#[cfg(feature = "getblocktemplate-rpcs")]
pub mod get_block_template_rpcs;
#[cfg(feature = "getblocktemplate-rpcs")]
pub mod regtest;
#[cfg(feature = "shielded-scan")]
pub mod shielded_scan;

View File

@ -0,0 +1,87 @@
//! Test submitblock RPC method on Regtest.
//!
//! This test will get block templates via the `getblocktemplate` RPC method and submit them as new blocks
//! via the `submitblock` RPC method on Regtest.
use std::{net::SocketAddr, time::Duration};
use color_eyre::eyre::{Context, Result};
use tracing::*;
use zebra_chain::{parameters::Network, serialization::ZcashSerialize};
use zebra_node_services::rpc_client::RpcRequestClient;
use zebra_rpc::methods::get_block_template_rpcs::get_block_template::{
proposal::TimeSource, proposal_block_from_template, GetBlockTemplate,
};
use zebra_test::args;
use crate::common::{
config::{random_known_rpc_port_config, testdir},
launch::ZebradTestDirExt,
};
/// Number of blocks that should be submitted before the test is considered successful.
const NUM_BLOCKS_TO_SUBMIT: usize = 200;
pub(crate) async fn submit_blocks_test() -> Result<()> {
let _init_guard = zebra_test::init();
info!("starting regtest submit_blocks test");
let network = Network::new_regtest(None);
let mut config = random_known_rpc_port_config(false, &network)?;
let rpc_address = config.rpc.listen_addr.unwrap();
let mut zebrad = testdir()?
.with_config(&mut config)?
.spawn_child(args!["start"])?;
info!("waiting for zebrad to start");
tokio::time::sleep(Duration::from_secs(30)).await;
info!("attempting to submit blocks");
submit_blocks(rpc_address).await?;
zebrad.kill(false)?;
let output = zebrad.wait_with_output()?;
let output = output.assert_failure()?;
// [Note on port conflict](#Note on port conflict)
output
.assert_was_killed()
.wrap_err("Possible port conflict. Are there other acceptance tests running?")
}
/// Get block templates and submit blocks
async fn submit_blocks(rpc_address: SocketAddr) -> Result<()> {
let client = RpcRequestClient::new(rpc_address);
for _ in 0..NUM_BLOCKS_TO_SUBMIT {
let block_template: GetBlockTemplate = client
.json_result_from_call("getblocktemplate", "[]".to_string())
.await
.expect("response should be success output with a serialized `GetBlockTemplate`");
let block_data = hex::encode(
proposal_block_from_template(&block_template, TimeSource::default())?
.zcash_serialize_to_vec()?,
);
let submit_block_response = client
.text_from_call("submitblock", format!(r#"["{block_data}"]"#))
.await?;
let was_submission_successful = submit_block_response.contains(r#""result":null"#);
info!(was_submission_successful, "submitted block");
// Check that the block was validated and committed.
assert!(
submit_block_response.contains(r#""result":null"#),
"unexpected response from submitblock RPC, should be null, was: {submit_block_response}"
);
}
Ok(())
}