change(ci): Run block proposal tests in CI (#5963)
* Revert "Temporarily fix the code for a disabled test" This reverts commit d915624417cc946e53aac76449e0b5b719e03d2a. * Check every valid time source in the proposal tests * Activate block proposal tests in CI * Repeats block proposal test a few times at an interval to sample different mempool contents * Increase the number of templates tested to 10 Co-authored-by: Arya <aryasolhi@gmail.com> --------- Co-authored-by: arya2 <aryasolhi@gmail.com>
This commit is contained in:
parent
8390e4e0cd
commit
14fdd3002b
|
|
@ -131,6 +131,13 @@ impl TimeSource {
|
||||||
Raw(_) | RawNow => false,
|
Raw(_) | RawNow => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator of time sources that are valid according to the consensus rules.
|
||||||
|
pub fn valid_sources() -> impl IntoIterator<Item = TimeSource> {
|
||||||
|
use TimeSource::*;
|
||||||
|
|
||||||
|
[CurTime, MinTime, MaxTime, ClampedNow].into_iter()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for TimeSource {
|
impl FromStr for TimeSource {
|
||||||
|
|
@ -160,7 +167,7 @@ impl FromStr for TimeSource {
|
||||||
///
|
///
|
||||||
/// If `time_source` is not supplied, uses the current time from the template.
|
/// If `time_source` is not supplied, uses the current time from the template.
|
||||||
pub fn proposal_block_from_template(
|
pub fn proposal_block_from_template(
|
||||||
template: GetBlockTemplate,
|
template: &GetBlockTemplate,
|
||||||
time_source: impl Into<Option<TimeSource>>,
|
time_source: impl Into<Option<TimeSource>>,
|
||||||
) -> Result<Block, SerializationError> {
|
) -> Result<Block, SerializationError> {
|
||||||
let GetBlockTemplate {
|
let GetBlockTemplate {
|
||||||
|
|
@ -177,7 +184,7 @@ pub fn proposal_block_from_template(
|
||||||
ref coinbase_txn,
|
ref coinbase_txn,
|
||||||
transactions: ref tx_templates,
|
transactions: ref tx_templates,
|
||||||
..
|
..
|
||||||
} = template;
|
} = *template;
|
||||||
|
|
||||||
if Height(height) > Height::MAX {
|
if Height(height) > Height::MAX {
|
||||||
Err(SerializationError::Parse(
|
Err(SerializationError::Parse(
|
||||||
|
|
@ -188,7 +195,7 @@ pub fn proposal_block_from_template(
|
||||||
let time = time_source
|
let time = time_source
|
||||||
.into()
|
.into()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.time_from_template(&template);
|
.time_from_template(template);
|
||||||
|
|
||||||
let mut transactions = vec![coinbase_txn.data.as_ref().zcash_deserialize_into()?];
|
let mut transactions = vec![coinbase_txn.data.as_ref().zcash_deserialize_into()?];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ fn main() -> Result<()> {
|
||||||
let template: GetBlockTemplate = serde_json::from_value(template)?;
|
let template: GetBlockTemplate = serde_json::from_value(template)?;
|
||||||
|
|
||||||
// generate proposal according to arguments
|
// generate proposal according to arguments
|
||||||
let proposal = proposal_block_from_template(template, time_source)?;
|
let proposal = proposal_block_from_template(&template, time_source)?;
|
||||||
eprintln!("{proposal:#?}");
|
eprintln!("{proposal:#?}");
|
||||||
|
|
||||||
let proposal = proposal
|
let proposal = proposal
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,10 @@ use crate::common::{
|
||||||
/// We've seen it take anywhere from 1-45 seconds for the mempool to have some transactions in it.
|
/// We've seen it take anywhere from 1-45 seconds for the mempool to have some transactions in it.
|
||||||
pub const EXPECTED_MEMPOOL_TRANSACTION_TIME: Duration = Duration::from_secs(45);
|
pub const EXPECTED_MEMPOOL_TRANSACTION_TIME: Duration = Duration::from_secs(45);
|
||||||
|
|
||||||
|
/// Number of times we want to try submitting a block template as a block proposal at an interval
|
||||||
|
/// that allows testing the varying mempool contents.
|
||||||
|
const NUM_SUCCESSFUL_BLOCK_PROPOSALS_REQUIRED: usize = 10;
|
||||||
|
|
||||||
/// Launch Zebra, wait for it to sync, and check the getblocktemplate RPC returns without errors.
|
/// Launch Zebra, wait for it to sync, and check the getblocktemplate RPC returns without errors.
|
||||||
pub(crate) async fn run() -> Result<()> {
|
pub(crate) async fn run() -> Result<()> {
|
||||||
let _init_guard = zebra_test::init();
|
let _init_guard = zebra_test::init();
|
||||||
|
|
@ -86,25 +90,24 @@ pub(crate) async fn run() -> Result<()> {
|
||||||
|
|
||||||
assert!(is_response_success);
|
assert!(is_response_success);
|
||||||
|
|
||||||
tracing::info!(
|
for _ in 0..NUM_SUCCESSFUL_BLOCK_PROPOSALS_REQUIRED {
|
||||||
"waiting {EXPECTED_MEMPOOL_TRANSACTION_TIME:?} for the mempool \
|
tracing::info!(
|
||||||
to download and verify some transactions...",
|
"waiting {EXPECTED_MEMPOOL_TRANSACTION_TIME:?} for the mempool \
|
||||||
);
|
to download and verify some transactions...",
|
||||||
|
);
|
||||||
|
|
||||||
tokio::time::sleep(EXPECTED_MEMPOOL_TRANSACTION_TIME).await;
|
tokio::time::sleep(EXPECTED_MEMPOOL_TRANSACTION_TIME).await;
|
||||||
|
|
||||||
/* TODO: activate this test after #5925 and #5953 have merged,
|
tracing::info!(
|
||||||
and we've checked for any other bugs using #5944.
|
"calling getblocktemplate RPC method at {rpc_address}, \
|
||||||
tracing::info!(
|
with a mempool that likely has transactions and attempting \
|
||||||
"calling getblocktemplate RPC method at {rpc_address}, \
|
to validate response result as a block proposal",
|
||||||
with a mempool that likely has transactions and attempting \
|
);
|
||||||
to validate response result as a block proposal",
|
|
||||||
);
|
|
||||||
|
|
||||||
try_validate_block_template(&client)
|
try_validate_block_template(&client)
|
||||||
.await
|
.await
|
||||||
.expect("block proposal validation failed");
|
.expect("block proposal validation failed");
|
||||||
*/
|
}
|
||||||
|
|
||||||
zebrad.kill(false)?;
|
zebrad.kill(false)?;
|
||||||
|
|
||||||
|
|
@ -130,7 +133,6 @@ pub(crate) async fn run() -> Result<()> {
|
||||||
/// If an RPC call returns a failure
|
/// If an RPC call returns a failure
|
||||||
/// If the response result cannot be deserialized to `GetBlockTemplate` in 'template' mode
|
/// If the response result cannot be deserialized to `GetBlockTemplate` in 'template' mode
|
||||||
/// or `ProposalResponse` in 'proposal' mode.
|
/// or `ProposalResponse` in 'proposal' mode.
|
||||||
#[allow(dead_code)]
|
|
||||||
async fn try_validate_block_template(client: &RPCRequestClient) -> Result<()> {
|
async fn try_validate_block_template(client: &RPCRequestClient) -> Result<()> {
|
||||||
let response_json_result = client
|
let response_json_result = client
|
||||||
.json_result_from_call("getblocktemplate", "[]".to_string())
|
.json_result_from_call("getblocktemplate", "[]".to_string())
|
||||||
|
|
@ -142,16 +144,16 @@ async fn try_validate_block_template(client: &RPCRequestClient) -> Result<()> {
|
||||||
"got getblocktemplate response, hopefully with transactions"
|
"got getblocktemplate response, hopefully with transactions"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Propose a new block with an empty solution and nonce field
|
for time_source in TimeSource::valid_sources() {
|
||||||
tracing::info!("calling getblocktemplate with a block proposal...",);
|
// Propose a new block with an empty solution and nonce field
|
||||||
|
tracing::info!(
|
||||||
|
"calling getblocktemplate with a block proposal and time source {time_source:?}...",
|
||||||
|
);
|
||||||
|
|
||||||
// TODO: update this to use all valid time sources in the next PR
|
let raw_proposal_block = hex::encode(
|
||||||
#[allow(clippy::single_element_loop)]
|
proposal_block_from_template(&response_json_result, time_source)?
|
||||||
for proposal_block in [proposal_block_from_template(
|
.zcash_serialize_to_vec()?,
|
||||||
response_json_result,
|
);
|
||||||
TimeSource::CurTime,
|
|
||||||
)?] {
|
|
||||||
let raw_proposal_block = hex::encode(proposal_block.zcash_serialize_to_vec()?);
|
|
||||||
|
|
||||||
let json_result = client
|
let json_result = client
|
||||||
.json_result_from_call(
|
.json_result_from_call(
|
||||||
|
|
@ -163,7 +165,7 @@ async fn try_validate_block_template(client: &RPCRequestClient) -> Result<()> {
|
||||||
|
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
?json_result,
|
?json_result,
|
||||||
?proposal_block.header.time,
|
?time_source,
|
||||||
"got getblocktemplate proposal response"
|
"got getblocktemplate proposal response"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue