Skip to content

Commit

Permalink
add(test): test disabled lightwalletd mempool gRPCs via zebrad logs (
Browse files Browse the repository at this point in the history
…#5016)

* add grpc mempool test research

* add a config flag for mempool injection of transactions in test

* Only copy the inner state directory in the send transactions test

* Preload Zcash parameters in some transaction verification tests

* Add a block and transaction Hash method to convert from display order bytes

* Update test coverage docs

* Add debugging output for mempool transaction verification

* Test fetching sent mempool transactions using gRPC

* Add extra log checks to the send transaction test

* Wait for zebrad mempool activation before running gRPC tests

* Update send transaction test for lightwalletd not returning mempool transactions

* Check zebrad logs instead of disabled lightwalletd gRPCs

* Add a debug option that makes RPCs pretend the sync is finished

* Remove an unused debug option

* Remove unused test code and downgrade some logs

* Fix test log checks

* Fix some rustdoc warnings

* Fix a compilation error due to new function arguments

* Make zebrad sync timeouts consistent and remove outdated code

* Document how to increase temporary directory space for tests

* Stop checking for a log that doesn't always happen

* Remove some commented-out code

Co-authored-by: Alfredo Garcia <[email protected]>

* Update a comment about run time

Co-authored-by: Alfredo Garcia <[email protected]>

* Add new config to new tests from the `main` branch

* Add transactions to the list, rather than replacing the list with each new block

Co-authored-by: Alfredo Garcia <[email protected]>
  • Loading branch information
teor2345 and oxarbitrage authored Sep 6, 2022
1 parent d8cef93 commit ea34baa
Show file tree
Hide file tree
Showing 22 changed files with 472 additions and 117 deletions.
13 changes: 12 additions & 1 deletion zebra-chain/src/block/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,22 @@ impl Hash {
///
/// Zebra displays transaction and block hashes in big-endian byte-order,
/// following the u256 convention set by Bitcoin and zcashd.
fn bytes_in_display_order(&self) -> [u8; 32] {
pub fn bytes_in_display_order(&self) -> [u8; 32] {
let mut reversed_bytes = self.0;
reversed_bytes.reverse();
reversed_bytes
}

/// Convert bytes in big-endian byte-order into a [`block::Hash`](crate::block::Hash).
///
/// Zebra displays transaction and block hashes in big-endian byte-order,
/// following the u256 convention set by Bitcoin and zcashd.
pub fn from_bytes_in_display_order(bytes_in_display_order: &[u8; 32]) -> Hash {
let mut internal_byte_order = *bytes_in_display_order;
internal_byte_order.reverse();

Hash(internal_byte_order)
}
}

impl fmt::Display for Hash {
Expand Down
13 changes: 12 additions & 1 deletion zebra-chain/src/transaction/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,22 @@ impl Hash {
///
/// Zebra displays transaction and block hashes in big-endian byte-order,
/// following the u256 convention set by Bitcoin and zcashd.
fn bytes_in_display_order(&self) -> [u8; 32] {
pub fn bytes_in_display_order(&self) -> [u8; 32] {
let mut reversed_bytes = self.0;
reversed_bytes.reverse();
reversed_bytes
}

/// Convert bytes in big-endian byte-order into a [`transaction::Hash`](crate::transaction::Hash).
///
/// Zebra displays transaction and block hashes in big-endian byte-order,
/// following the u256 convention set by Bitcoin and zcashd.
pub fn from_bytes_in_display_order(bytes_in_display_order: &[u8; 32]) -> Hash {
let mut internal_byte_order = *bytes_in_display_order;
internal_byte_order.reverse();

Hash(internal_byte_order)
}
}

impl ToHex for &Hash {
Expand Down
15 changes: 14 additions & 1 deletion zebra-consensus/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ where
let span = tracing::debug_span!("tx", ?tx_id);

async move {
tracing::trace!(?req);
tracing::trace!(?tx_id, ?req, "got tx verify request");

// Do basic checks first
if let Some(block_time) = req.block_time() {
Expand Down Expand Up @@ -344,6 +344,8 @@ where

check::spend_conflicts(&tx)?;

tracing::trace!(?tx_id, "passed quick checks");

// "The consensus rules applied to valueBalance, vShieldedOutput, and bindingSig
// in non-coinbase transactions MUST also be applied to coinbase transactions."
//
Expand All @@ -360,6 +362,9 @@ where

let cached_ffi_transaction =
Arc::new(CachedFfiTransaction::new(tx.clone(), spent_outputs));

tracing::trace!(?tx_id, "got state UTXOs");

let async_checks = match tx.as_ref() {
Transaction::V1 { .. } | Transaction::V2 { .. } | Transaction::V3 { .. } => {
tracing::debug!(?tx, "got transaction with wrong version");
Expand Down Expand Up @@ -391,10 +396,14 @@ where
)?,
};

tracing::trace!(?tx_id, "awaiting async checks...");

// If the Groth16 parameter download hangs,
// Zebra will timeout here, waiting for the async checks.
async_checks.check().await?;

tracing::trace!(?tx_id, "finished async checks");

// Get the `value_balance` to calculate the transaction fee.
let value_balance = tx.value_balance(&spent_utxos);

Expand Down Expand Up @@ -429,6 +438,10 @@ where

Ok(rsp)
}
.inspect(move |result| {
// Hide the transaction data to avoid filling the logs
tracing::trace!(?tx_id, result = ?result.as_ref().map(|_tx| ()), "got tx verify result");
})
.instrument(span)
.boxed()
}
Expand Down
10 changes: 9 additions & 1 deletion zebra-node-services/src/mempool/gossip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use zebra_chain::transaction::{UnminedTx, UnminedTxId};

/// A gossiped transaction, which can be the transaction itself or just its ID.
#[derive(Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Gossip {
/// Just the ID of an unmined transaction.
Id(UnminedTxId),
Expand All @@ -20,6 +20,14 @@ impl Gossip {
Gossip::Tx(tx) => tx.id,
}
}

/// Return the [`UnminedTx`] of a gossiped transaction, if we have it.
pub fn tx(&self) -> Option<UnminedTx> {
match self {
Gossip::Id(_) => None,
Gossip::Tx(tx) => Some(tx.clone()),
}
}
}

impl From<UnminedTxId> for Gossip {
Expand Down
7 changes: 7 additions & 0 deletions zebra-rpc/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ pub struct Config {
///
/// If some of those instances are outdated or failed, RPC queries can be slow or inconsistent.
pub parallel_cpu_threads: usize,

/// Test-only option that makes Zebra say it is at the chain tip,
/// no matter what the estimated height or local clock is.
pub debug_force_finished_sync: bool,
}

impl Default for Config {
Expand All @@ -59,6 +63,9 @@ impl Default for Config {

// Use a single thread, so we can detect RPC port conflicts.
parallel_cpu_threads: 1,

// Debug options are always off by default.
debug_force_finished_sync: false,
}
}
}
32 changes: 25 additions & 7 deletions zebra-rpc/src/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,20 @@ where
>,
Tip: ChainTip,
{
// Configuration
//
/// Zebra's application version.
app_version: String,

/// The configured network for this RPC service.
network: Network,

/// Test-only option that makes Zebra say it is at the chain tip,
/// no matter what the estimated height or local clock is.
debug_force_finished_sync: bool,

// Services
//
/// A handle to the mempool service.
mempool: Buffer<Mempool, mempool::Request>,

Expand All @@ -255,10 +266,8 @@ where
/// Allows efficient access to the best tip of the blockchain.
latest_chain_tip: Tip,

/// The configured network for this RPC service.
#[allow(dead_code)]
network: Network,

// Tasks
//
/// A sender component of a channel used to send transactions to the queue.
queue_sender: Sender<Option<UnminedTx>>,
}
Expand All @@ -279,10 +288,11 @@ where
/// Create a new instance of the RPC handler.
pub fn new<Version>(
app_version: Version,
network: Network,
debug_force_finished_sync: bool,
mempool: Buffer<Mempool, mempool::Request>,
state: State,
latest_chain_tip: Tip,
network: Network,
) -> (Self, JoinHandle<()>)
where
Version: ToString,
Expand All @@ -300,10 +310,11 @@ where

let rpc_impl = RpcImpl {
app_version,
network,
debug_force_finished_sync,
mempool: mempool.clone(),
state: state.clone(),
latest_chain_tip: latest_chain_tip.clone(),
network,
queue_sender: runner.sender(),
};

Expand Down Expand Up @@ -379,13 +390,18 @@ where
data: None,
})?;

let estimated_height =
let mut estimated_height =
if current_block_time > Utc::now() || zebra_estimated_height < tip_height {
tip_height
} else {
zebra_estimated_height
};

// If we're testing the mempool, force the estimated height to be the actual tip height.
if self.debug_force_finished_sync {
estimated_height = tip_height;
}

// `upgrades` object
//
// Get the network upgrades in height order, like `zcashd`.
Expand Down Expand Up @@ -506,6 +522,8 @@ where
"mempool service returned more results than expected"
);

tracing::debug!("sent transaction to mempool: {:?}", &queue_results[0]);

match &queue_results[0] {
Ok(()) => Ok(SentTransactionHash(transaction_hash)),
Err(error) => Err(Error {
Expand Down
Loading

0 comments on commit ea34baa

Please sign in to comment.