From f7026d728f668d3c782ba66a8bdbbfb63e50f870 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Sun, 11 Jul 2021 23:49:33 -0300 Subject: [PATCH] move `Utxo` type to zebra-chain (#2481) --- zebra-chain/src/transparent.rs | 2 ++ .../src => zebra-chain/src/transparent}/utxo.rs | 2 +- zebra-consensus/src/block.rs | 3 ++- zebra-consensus/src/script.rs | 3 +-- zebra-consensus/src/transaction.rs | 4 ++-- zebra-consensus/src/transaction/tests.rs | 5 ++--- zebra-state/src/lib.rs | 2 -- zebra-state/src/request.rs | 8 +++----- zebra-state/src/response.rs | 5 ++--- zebra-state/src/service.rs | 4 ++-- zebra-state/src/service/finalized_state.rs | 4 ++-- .../src/service/finalized_state/disk_format.rs | 8 +++----- zebra-state/src/service/non_finalized_state.rs | 4 ++-- .../src/service/non_finalized_state/chain.rs | 13 ++++++++----- .../service/non_finalized_state/queued_blocks.rs | 6 +++--- zebra-state/src/service/pending_utxos.rs | 8 ++++---- zebra-state/src/service/tests.rs | 4 ++-- zebra-state/src/tests.rs | 2 +- 18 files changed, 42 insertions(+), 45 deletions(-) rename {zebra-state/src => zebra-chain/src/transparent}/utxo.rs (98%) diff --git a/zebra-chain/src/transparent.rs b/zebra-chain/src/transparent.rs index b1a74b1f3..7395a2ba6 100644 --- a/zebra-chain/src/transparent.rs +++ b/zebra-chain/src/transparent.rs @@ -5,9 +5,11 @@ mod address; mod keys; mod script; mod serialize; +mod utxo; pub use address::Address; pub use script::Script; +pub use utxo::{new_outputs, Utxo}; #[cfg(any(test, feature = "proptest-impl"))] use proptest_derive::Arbitrary; diff --git a/zebra-state/src/utxo.rs b/zebra-chain/src/transparent/utxo.rs similarity index 98% rename from zebra-state/src/utxo.rs rename to zebra-chain/src/transparent/utxo.rs index 65c43f5cb..dbab18c11 100644 --- a/zebra-state/src/utxo.rs +++ b/zebra-chain/src/transparent/utxo.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; -use zebra_chain::{ +use crate::{ block::{self, Block}, transaction, transparent, }; diff --git a/zebra-consensus/src/block.rs b/zebra-consensus/src/block.rs index 86dba1e5e..bca718ab5 100644 --- a/zebra-consensus/src/block.rs +++ b/zebra-consensus/src/block.rs @@ -24,6 +24,7 @@ use tracing::Instrument; use zebra_chain::{ block::{self, Block}, parameters::Network, + transparent, work::equihash, }; use zebra_state as zs; @@ -173,7 +174,7 @@ where let mut async_checks = FuturesUnordered::new(); - let known_utxos = Arc::new(zs::new_outputs(&block, &transaction_hashes)); + let known_utxos = Arc::new(transparent::new_outputs(&block, &transaction_hashes)); for transaction in &block.transactions { let rsp = transaction_verifier .ready_and() diff --git a/zebra-consensus/src/script.rs b/zebra-consensus/src/script.rs index f57577ee3..d71c3b94f 100644 --- a/zebra-consensus/src/script.rs +++ b/zebra-consensus/src/script.rs @@ -5,7 +5,6 @@ use tracing::Instrument; use zebra_chain::{parameters::NetworkUpgrade, transparent}; use zebra_script::CachedFfiTransaction; -use zebra_state::Utxo; use crate::BoxError; @@ -59,7 +58,7 @@ pub struct Request { /// A set of additional UTXOs known in the context of this verification request. /// /// This allows specifying additional UTXOs that are not already known to the chain state. - pub known_utxos: Arc>, + pub known_utxos: Arc>, /// The network upgrade active in the context of this verification request. /// /// Because the consensus branch ID changes with each network upgrade, diff --git a/zebra-consensus/src/transaction.rs b/zebra-consensus/src/transaction.rs index 6d4bae053..022e282b4 100644 --- a/zebra-consensus/src/transaction.rs +++ b/zebra-consensus/src/transaction.rs @@ -70,7 +70,7 @@ pub enum Request { /// The transaction itself. transaction: Arc, /// Additional UTXOs which are known at the time of verification. - known_utxos: Arc>, + known_utxos: Arc>, /// The height of the block containing this transaction. height: block::Height, }, @@ -100,7 +100,7 @@ impl Request { } /// The set of additional known unspent transaction outputs that's in this request. - pub fn known_utxos(&self) -> Arc> { + pub fn known_utxos(&self) -> Arc> { match self { Request::Block { known_utxos, .. } => known_utxos.clone(), Request::Mempool { .. } => HashMap::new().into(), diff --git a/zebra-consensus/src/transaction/tests.rs b/zebra-consensus/src/transaction/tests.rs index 8fb52ccbc..0583fcbb0 100644 --- a/zebra-consensus/src/transaction/tests.rs +++ b/zebra-consensus/src/transaction/tests.rs @@ -17,7 +17,6 @@ use zebra_chain::{ }, transparent::{self, CoinbaseData}, }; -use zebra_state::Utxo; use super::{check, Request, Verifier}; @@ -839,7 +838,7 @@ fn mock_transparent_transfer( ) -> ( transparent::Input, transparent::Output, - HashMap, + HashMap, ) { // A script with a single opcode that accepts the transaction (pushes true on the stack) let accepting_script = transparent::Script::new(&[1, 1]); @@ -863,7 +862,7 @@ fn mock_transparent_transfer( lock_script, }; - let previous_utxo = Utxo { + let previous_utxo = transparent::Utxo { output: previous_output, height: previous_utxo_height, from_coinbase: false, diff --git a/zebra-state/src/lib.rs b/zebra-state/src/lib.rs index 0a75eb66b..499393a65 100644 --- a/zebra-state/src/lib.rs +++ b/zebra-state/src/lib.rs @@ -24,7 +24,6 @@ mod request; mod response; mod service; mod util; -mod utxo; // TODO: move these to integration tests. #[cfg(test)] @@ -36,4 +35,3 @@ pub use error::{BoxError, CloneError, CommitBlockError, ValidateContextError}; pub use request::{FinalizedBlock, HashOrHeight, PreparedBlock, Request}; pub use response::Response; pub use service::init; -pub use utxo::{new_outputs, Utxo}; diff --git a/zebra-state/src/request.rs b/zebra-state/src/request.rs index 1295533e3..0a0949cc7 100644 --- a/zebra-state/src/request.rs +++ b/zebra-state/src/request.rs @@ -5,8 +5,6 @@ use zebra_chain::{ transaction, transparent, }; -use crate::Utxo; - // Allow *only* this unused import, so that rustdoc link resolution // will work with inline links. #[allow(unused_imports)] @@ -73,7 +71,7 @@ pub struct PreparedBlock { /// Note: although these transparent outputs are newly created, they may not /// be unspent, since a later transaction in a block can spend outputs of an /// earlier transaction. - pub new_outputs: HashMap, + pub new_outputs: HashMap, /// A precomputed list of the hashes of the transactions in this block. pub transaction_hashes: Vec, // TODO: add these parameters when we can compute anchors. @@ -98,7 +96,7 @@ pub struct FinalizedBlock { /// Note: although these transparent outputs are newly created, they may not /// be unspent, since a later transaction in a block can spend outputs of an /// earlier transaction. - pub(crate) new_outputs: HashMap, + pub(crate) new_outputs: HashMap, /// A precomputed list of the hashes of the transactions in this block. pub(crate) transaction_hashes: Vec, } @@ -117,7 +115,7 @@ impl From> for FinalizedBlock { .iter() .map(|tx| tx.hash()) .collect::>(); - let new_outputs = crate::utxo::new_outputs(&block, transaction_hashes.as_slice()); + let new_outputs = transparent::new_outputs(&block, transaction_hashes.as_slice()); Self { block, diff --git a/zebra-state/src/response.rs b/zebra-state/src/response.rs index 9268dbe26..efadb3b89 100644 --- a/zebra-state/src/response.rs +++ b/zebra-state/src/response.rs @@ -2,10 +2,9 @@ use std::sync::Arc; use zebra_chain::{ block::{self, Block}, transaction::Transaction, + transparent, }; -use crate::Utxo; - // Allow *only* this unused import, so that rustdoc link resolution // will work with inline links. #[allow(unused_imports)] @@ -34,7 +33,7 @@ pub enum Response { Block(Option>), /// The response to a `AwaitUtxo` request. - Utxo(Utxo), + Utxo(transparent::Utxo), /// The response to a `FindBlockHashes` request. BlockHashes(Vec), diff --git a/zebra-state/src/service.rs b/zebra-state/src/service.rs index b886249f4..ae01bf0ce 100644 --- a/zebra-state/src/service.rs +++ b/zebra-state/src/service.rs @@ -23,7 +23,7 @@ use zebra_chain::{ use crate::{ request::HashOrHeight, BoxError, CommitBlockError, Config, FinalizedBlock, PreparedBlock, - Request, Response, Utxo, ValidateContextError, + Request, Response, ValidateContextError, }; #[cfg(any(test, feature = "proptest-impl"))] @@ -314,7 +314,7 @@ impl StateService { } /// Return the [`Utxo`] pointed to by `outpoint` if it exists in any chain. - pub fn any_utxo(&self, outpoint: &transparent::OutPoint) -> Option { + pub fn any_utxo(&self, outpoint: &transparent::OutPoint) -> Option { self.mem .any_utxo(outpoint) .or_else(|| self.queued_blocks.utxo(outpoint)) diff --git a/zebra-state/src/service/finalized_state.rs b/zebra-state/src/service/finalized_state.rs index ed5bdc085..85d994910 100644 --- a/zebra-state/src/service/finalized_state.rs +++ b/zebra-state/src/service/finalized_state.rs @@ -14,7 +14,7 @@ use zebra_chain::{ transaction::{self, Transaction}, }; -use crate::{BoxError, Config, FinalizedBlock, HashOrHeight, Utxo}; +use crate::{BoxError, Config, FinalizedBlock, HashOrHeight}; use self::disk_format::{DiskDeserialize, DiskSerialize, FromDisk, IntoDisk, TransactionLocation}; @@ -363,7 +363,7 @@ impl FinalizedState { /// Returns the `transparent::Output` pointed to by the given /// `transparent::OutPoint` if it is present. - pub fn utxo(&self, outpoint: &transparent::OutPoint) -> Option { + pub fn utxo(&self, outpoint: &transparent::OutPoint) -> Option { let utxo_by_outpoint = self.db.cf_handle("utxo_by_outpoint").unwrap(); self.db.zs_get(utxo_by_outpoint, outpoint) } diff --git a/zebra-state/src/service/finalized_state/disk_format.rs b/zebra-state/src/service/finalized_state/disk_format.rs index 31546de48..4da8886d5 100644 --- a/zebra-state/src/service/finalized_state/disk_format.rs +++ b/zebra-state/src/service/finalized_state/disk_format.rs @@ -9,8 +9,6 @@ use zebra_chain::{ sprout, transaction, transparent, }; -use crate::Utxo; - #[derive(Debug, Clone, Copy, PartialEq)] pub struct TransactionLocation { pub height: block::Height, @@ -195,7 +193,7 @@ impl FromDisk for block::Height { } } -impl IntoDisk for Utxo { +impl IntoDisk for transparent::Utxo { type Bytes = Vec; fn as_bytes(&self) -> Self::Bytes { @@ -209,7 +207,7 @@ impl IntoDisk for Utxo { } } -impl FromDisk for Utxo { +impl FromDisk for transparent::Utxo { fn from_bytes(bytes: impl AsRef<[u8]>) -> Self { let (meta_bytes, output_bytes) = bytes.as_ref().split_at(5); let height = block::Height(u32::from_be_bytes(meta_bytes[0..4].try_into().unwrap())); @@ -395,6 +393,6 @@ mod tests { fn roundtrip_transparent_output() { zebra_test::init(); - proptest!(|(val in any::())| assert_value_properties(val)); + proptest!(|(val in any::())| assert_value_properties(val)); } } diff --git a/zebra-state/src/service/non_finalized_state.rs b/zebra-state/src/service/non_finalized_state.rs index 79e2ee4cf..3dc1a98b3 100644 --- a/zebra-state/src/service/non_finalized_state.rs +++ b/zebra-state/src/service/non_finalized_state.rs @@ -19,7 +19,7 @@ use zebra_chain::{ transparent, }; -use crate::{FinalizedBlock, HashOrHeight, PreparedBlock, Utxo, ValidateContextError}; +use crate::{FinalizedBlock, HashOrHeight, PreparedBlock, ValidateContextError}; use self::chain::Chain; @@ -158,7 +158,7 @@ impl NonFinalizedState { /// Returns the `transparent::Output` pointed to by the given /// `transparent::OutPoint` if it is present in any chain. - pub fn any_utxo(&self, outpoint: &transparent::OutPoint) -> Option { + pub fn any_utxo(&self, outpoint: &transparent::OutPoint) -> Option { for chain in self.chain_set.iter().rev() { if let Some(output) = chain.created_utxos.get(outpoint) { return Some(output.clone()); diff --git a/zebra-state/src/service/non_finalized_state/chain.rs b/zebra-state/src/service/non_finalized_state/chain.rs index 768202951..b247eaca2 100644 --- a/zebra-state/src/service/non_finalized_state/chain.rs +++ b/zebra-state/src/service/non_finalized_state/chain.rs @@ -10,7 +10,7 @@ use zebra_chain::{ transaction::Transaction::*, transparent, work::difficulty::PartialCumulativeWork, }; -use crate::{PreparedBlock, Utxo, ValidateContextError}; +use crate::{PreparedBlock, ValidateContextError}; #[derive(Default, Clone)] pub struct Chain { @@ -18,7 +18,7 @@ pub struct Chain { pub height_by_hash: HashMap, pub tx_by_hash: HashMap, - pub created_utxos: HashMap, + pub created_utxos: HashMap, spent_utxos: HashSet, // TODO: add sprout, sapling and orchard anchors (#1320) sprout_anchors: HashSet, @@ -303,17 +303,20 @@ impl UpdateWith for Chain { } } -impl UpdateWith> for Chain { +impl UpdateWith> for Chain { fn update_chain_state_with( &mut self, - utxos: &HashMap, + utxos: &HashMap, ) -> Result<(), ValidateContextError> { self.created_utxos .extend(utxos.iter().map(|(k, v)| (*k, v.clone()))); Ok(()) } - fn revert_chain_state_with(&mut self, utxos: &HashMap) { + fn revert_chain_state_with( + &mut self, + utxos: &HashMap, + ) { self.created_utxos .retain(|outpoint, _| !utxos.contains_key(outpoint)); } diff --git a/zebra-state/src/service/non_finalized_state/queued_blocks.rs b/zebra-state/src/service/non_finalized_state/queued_blocks.rs index d42c7d69d..5fe2d4bd6 100644 --- a/zebra-state/src/service/non_finalized_state/queued_blocks.rs +++ b/zebra-state/src/service/non_finalized_state/queued_blocks.rs @@ -6,7 +6,7 @@ use std::{ use tracing::instrument; use zebra_chain::{block, transparent}; -use crate::{service::QueuedBlock, Utxo}; +use crate::service::QueuedBlock; /// A queue of blocks, awaiting the arrival of parent blocks. #[derive(Default)] @@ -18,7 +18,7 @@ pub struct QueuedBlocks { /// Hashes from `queued_blocks`, indexed by block height. by_height: BTreeMap>, /// Known UTXOs. - known_utxos: HashMap, + known_utxos: HashMap, } impl QueuedBlocks { @@ -150,7 +150,7 @@ impl QueuedBlocks { } /// Try to look up this UTXO in any queued block. - pub fn utxo(&self, outpoint: &transparent::OutPoint) -> Option { + pub fn utxo(&self, outpoint: &transparent::OutPoint) -> Option { self.known_utxos.get(outpoint).cloned() } } diff --git a/zebra-state/src/service/pending_utxos.rs b/zebra-state/src/service/pending_utxos.rs index 277173f7b..6fbb71cfd 100644 --- a/zebra-state/src/service/pending_utxos.rs +++ b/zebra-state/src/service/pending_utxos.rs @@ -5,10 +5,10 @@ use tokio::sync::broadcast; use zebra_chain::transparent; -use crate::{BoxError, Response, Utxo}; +use crate::{BoxError, Response}; #[derive(Debug, Default)] -pub struct PendingUtxos(HashMap>); +pub struct PendingUtxos(HashMap>); impl PendingUtxos { /// Returns a future that will resolve to the `transparent::Output` pointed @@ -37,7 +37,7 @@ impl PendingUtxos { /// Notify all requests waiting for the [`Utxo`] pointed to by the given /// [`transparent::OutPoint`] that the [`Utxo`] has arrived. - pub fn respond(&mut self, outpoint: &transparent::OutPoint, utxo: Utxo) { + pub fn respond(&mut self, outpoint: &transparent::OutPoint, utxo: transparent::Utxo) { if let Some(sender) = self.0.remove(outpoint) { // Adding the outpoint as a field lets us crossreference // with the trace of the verification that made the request. @@ -47,7 +47,7 @@ impl PendingUtxos { } /// Check the list of pending UTXO requests against the supplied UTXO index. - pub fn check_against(&mut self, utxos: &HashMap) { + pub fn check_against(&mut self, utxos: &HashMap) { for (outpoint, utxo) in utxos.iter() { if let Some(sender) = self.0.remove(outpoint) { tracing::trace!(?outpoint, "found pending UTXO"); diff --git a/zebra-state/src/service/tests.rs b/zebra-state/src/service/tests.rs index 7ba0201f4..40cfd619b 100644 --- a/zebra-state/src/service/tests.rs +++ b/zebra-state/src/service/tests.rs @@ -10,7 +10,7 @@ use zebra_chain::{ }; use zebra_test::{prelude::*, transcript::Transcript}; -use crate::{init, service::arbitrary, BoxError, Config, Request, Response, Utxo}; +use crate::{init, service::arbitrary, BoxError, Config, Request, Response}; const LAST_BLOCK_HEIGHT: u32 = 10; @@ -88,7 +88,7 @@ async fn test_populated_state_responds_correctly( hash: transaction_hash, index: index as _, }; - let utxo = Utxo { + let utxo = transparent::Utxo { output, height, from_coinbase, diff --git a/zebra-state/src/tests.rs b/zebra-state/src/tests.rs index ba1097399..224d454bc 100644 --- a/zebra-state/src/tests.rs +++ b/zebra-state/src/tests.rs @@ -21,7 +21,7 @@ impl Prepare for Arc { let hash = block.hash(); let height = block.coinbase_height().unwrap(); let transaction_hashes: Vec<_> = block.transactions.iter().map(|tx| tx.hash()).collect(); - let new_outputs = crate::utxo::new_outputs(&block, transaction_hashes.as_slice()); + let new_outputs = transparent::new_outputs(&block, transaction_hashes.as_slice()); PreparedBlock { block,