move `Utxo` type to zebra-chain (#2481)

This commit is contained in:
Alfredo Garcia 2021-07-11 23:49:33 -03:00 committed by GitHub
parent 6d24ee1d21
commit f7026d728f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 42 additions and 45 deletions

View File

@ -5,9 +5,11 @@ mod address;
mod keys; mod keys;
mod script; mod script;
mod serialize; mod serialize;
mod utxo;
pub use address::Address; pub use address::Address;
pub use script::Script; pub use script::Script;
pub use utxo::{new_outputs, Utxo};
#[cfg(any(test, feature = "proptest-impl"))] #[cfg(any(test, feature = "proptest-impl"))]
use proptest_derive::Arbitrary; use proptest_derive::Arbitrary;

View File

@ -2,7 +2,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use zebra_chain::{ use crate::{
block::{self, Block}, block::{self, Block},
transaction, transparent, transaction, transparent,
}; };

View File

@ -24,6 +24,7 @@ use tracing::Instrument;
use zebra_chain::{ use zebra_chain::{
block::{self, Block}, block::{self, Block},
parameters::Network, parameters::Network,
transparent,
work::equihash, work::equihash,
}; };
use zebra_state as zs; use zebra_state as zs;
@ -173,7 +174,7 @@ where
let mut async_checks = FuturesUnordered::new(); 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 { for transaction in &block.transactions {
let rsp = transaction_verifier let rsp = transaction_verifier
.ready_and() .ready_and()

View File

@ -5,7 +5,6 @@ use tracing::Instrument;
use zebra_chain::{parameters::NetworkUpgrade, transparent}; use zebra_chain::{parameters::NetworkUpgrade, transparent};
use zebra_script::CachedFfiTransaction; use zebra_script::CachedFfiTransaction;
use zebra_state::Utxo;
use crate::BoxError; use crate::BoxError;
@ -59,7 +58,7 @@ pub struct Request {
/// A set of additional UTXOs known in the context of this verification 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. /// This allows specifying additional UTXOs that are not already known to the chain state.
pub known_utxos: Arc<HashMap<transparent::OutPoint, Utxo>>, pub known_utxos: Arc<HashMap<transparent::OutPoint, transparent::Utxo>>,
/// The network upgrade active in the context of this verification request. /// The network upgrade active in the context of this verification request.
/// ///
/// Because the consensus branch ID changes with each network upgrade, /// Because the consensus branch ID changes with each network upgrade,

View File

@ -70,7 +70,7 @@ pub enum Request {
/// The transaction itself. /// The transaction itself.
transaction: Arc<Transaction>, transaction: Arc<Transaction>,
/// Additional UTXOs which are known at the time of verification. /// Additional UTXOs which are known at the time of verification.
known_utxos: Arc<HashMap<transparent::OutPoint, zs::Utxo>>, known_utxos: Arc<HashMap<transparent::OutPoint, transparent::Utxo>>,
/// The height of the block containing this transaction. /// The height of the block containing this transaction.
height: block::Height, height: block::Height,
}, },
@ -100,7 +100,7 @@ impl Request {
} }
/// The set of additional known unspent transaction outputs that's in this request. /// The set of additional known unspent transaction outputs that's in this request.
pub fn known_utxos(&self) -> Arc<HashMap<transparent::OutPoint, zs::Utxo>> { pub fn known_utxos(&self) -> Arc<HashMap<transparent::OutPoint, transparent::Utxo>> {
match self { match self {
Request::Block { known_utxos, .. } => known_utxos.clone(), Request::Block { known_utxos, .. } => known_utxos.clone(),
Request::Mempool { .. } => HashMap::new().into(), Request::Mempool { .. } => HashMap::new().into(),

View File

@ -17,7 +17,6 @@ use zebra_chain::{
}, },
transparent::{self, CoinbaseData}, transparent::{self, CoinbaseData},
}; };
use zebra_state::Utxo;
use super::{check, Request, Verifier}; use super::{check, Request, Verifier};
@ -839,7 +838,7 @@ fn mock_transparent_transfer(
) -> ( ) -> (
transparent::Input, transparent::Input,
transparent::Output, transparent::Output,
HashMap<transparent::OutPoint, Utxo>, HashMap<transparent::OutPoint, transparent::Utxo>,
) { ) {
// A script with a single opcode that accepts the transaction (pushes true on the stack) // A script with a single opcode that accepts the transaction (pushes true on the stack)
let accepting_script = transparent::Script::new(&[1, 1]); let accepting_script = transparent::Script::new(&[1, 1]);
@ -863,7 +862,7 @@ fn mock_transparent_transfer(
lock_script, lock_script,
}; };
let previous_utxo = Utxo { let previous_utxo = transparent::Utxo {
output: previous_output, output: previous_output,
height: previous_utxo_height, height: previous_utxo_height,
from_coinbase: false, from_coinbase: false,

View File

@ -24,7 +24,6 @@ mod request;
mod response; mod response;
mod service; mod service;
mod util; mod util;
mod utxo;
// TODO: move these to integration tests. // TODO: move these to integration tests.
#[cfg(test)] #[cfg(test)]
@ -36,4 +35,3 @@ pub use error::{BoxError, CloneError, CommitBlockError, ValidateContextError};
pub use request::{FinalizedBlock, HashOrHeight, PreparedBlock, Request}; pub use request::{FinalizedBlock, HashOrHeight, PreparedBlock, Request};
pub use response::Response; pub use response::Response;
pub use service::init; pub use service::init;
pub use utxo::{new_outputs, Utxo};

View File

@ -5,8 +5,6 @@ use zebra_chain::{
transaction, transparent, transaction, transparent,
}; };
use crate::Utxo;
// Allow *only* this unused import, so that rustdoc link resolution // Allow *only* this unused import, so that rustdoc link resolution
// will work with inline links. // will work with inline links.
#[allow(unused_imports)] #[allow(unused_imports)]
@ -73,7 +71,7 @@ pub struct PreparedBlock {
/// Note: although these transparent outputs are newly created, they may not /// 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 /// be unspent, since a later transaction in a block can spend outputs of an
/// earlier transaction. /// earlier transaction.
pub new_outputs: HashMap<transparent::OutPoint, Utxo>, pub new_outputs: HashMap<transparent::OutPoint, transparent::Utxo>,
/// A precomputed list of the hashes of the transactions in this block. /// A precomputed list of the hashes of the transactions in this block.
pub transaction_hashes: Vec<transaction::Hash>, pub transaction_hashes: Vec<transaction::Hash>,
// TODO: add these parameters when we can compute anchors. // 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 /// 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 /// be unspent, since a later transaction in a block can spend outputs of an
/// earlier transaction. /// earlier transaction.
pub(crate) new_outputs: HashMap<transparent::OutPoint, Utxo>, pub(crate) new_outputs: HashMap<transparent::OutPoint, transparent::Utxo>,
/// A precomputed list of the hashes of the transactions in this block. /// A precomputed list of the hashes of the transactions in this block.
pub(crate) transaction_hashes: Vec<transaction::Hash>, pub(crate) transaction_hashes: Vec<transaction::Hash>,
} }
@ -117,7 +115,7 @@ impl From<Arc<Block>> for FinalizedBlock {
.iter() .iter()
.map(|tx| tx.hash()) .map(|tx| tx.hash())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let new_outputs = crate::utxo::new_outputs(&block, transaction_hashes.as_slice()); let new_outputs = transparent::new_outputs(&block, transaction_hashes.as_slice());
Self { Self {
block, block,

View File

@ -2,10 +2,9 @@ use std::sync::Arc;
use zebra_chain::{ use zebra_chain::{
block::{self, Block}, block::{self, Block},
transaction::Transaction, transaction::Transaction,
transparent,
}; };
use crate::Utxo;
// Allow *only* this unused import, so that rustdoc link resolution // Allow *only* this unused import, so that rustdoc link resolution
// will work with inline links. // will work with inline links.
#[allow(unused_imports)] #[allow(unused_imports)]
@ -34,7 +33,7 @@ pub enum Response {
Block(Option<Arc<Block>>), Block(Option<Arc<Block>>),
/// The response to a `AwaitUtxo` request. /// The response to a `AwaitUtxo` request.
Utxo(Utxo), Utxo(transparent::Utxo),
/// The response to a `FindBlockHashes` request. /// The response to a `FindBlockHashes` request.
BlockHashes(Vec<block::Hash>), BlockHashes(Vec<block::Hash>),

View File

@ -23,7 +23,7 @@ use zebra_chain::{
use crate::{ use crate::{
request::HashOrHeight, BoxError, CommitBlockError, Config, FinalizedBlock, PreparedBlock, request::HashOrHeight, BoxError, CommitBlockError, Config, FinalizedBlock, PreparedBlock,
Request, Response, Utxo, ValidateContextError, Request, Response, ValidateContextError,
}; };
#[cfg(any(test, feature = "proptest-impl"))] #[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. /// Return the [`Utxo`] pointed to by `outpoint` if it exists in any chain.
pub fn any_utxo(&self, outpoint: &transparent::OutPoint) -> Option<Utxo> { pub fn any_utxo(&self, outpoint: &transparent::OutPoint) -> Option<transparent::Utxo> {
self.mem self.mem
.any_utxo(outpoint) .any_utxo(outpoint)
.or_else(|| self.queued_blocks.utxo(outpoint)) .or_else(|| self.queued_blocks.utxo(outpoint))

View File

@ -14,7 +14,7 @@ use zebra_chain::{
transaction::{self, Transaction}, 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}; use self::disk_format::{DiskDeserialize, DiskSerialize, FromDisk, IntoDisk, TransactionLocation};
@ -363,7 +363,7 @@ impl FinalizedState {
/// Returns the `transparent::Output` pointed to by the given /// Returns the `transparent::Output` pointed to by the given
/// `transparent::OutPoint` if it is present. /// `transparent::OutPoint` if it is present.
pub fn utxo(&self, outpoint: &transparent::OutPoint) -> Option<Utxo> { pub fn utxo(&self, outpoint: &transparent::OutPoint) -> Option<transparent::Utxo> {
let utxo_by_outpoint = self.db.cf_handle("utxo_by_outpoint").unwrap(); let utxo_by_outpoint = self.db.cf_handle("utxo_by_outpoint").unwrap();
self.db.zs_get(utxo_by_outpoint, outpoint) self.db.zs_get(utxo_by_outpoint, outpoint)
} }

View File

@ -9,8 +9,6 @@ use zebra_chain::{
sprout, transaction, transparent, sprout, transaction, transparent,
}; };
use crate::Utxo;
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct TransactionLocation { pub struct TransactionLocation {
pub height: block::Height, 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<u8>; type Bytes = Vec<u8>;
fn as_bytes(&self) -> Self::Bytes { 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 { fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
let (meta_bytes, output_bytes) = bytes.as_ref().split_at(5); 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())); 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() { fn roundtrip_transparent_output() {
zebra_test::init(); zebra_test::init();
proptest!(|(val in any::<Utxo>())| assert_value_properties(val)); proptest!(|(val in any::<transparent::Utxo>())| assert_value_properties(val));
} }
} }

View File

@ -19,7 +19,7 @@ use zebra_chain::{
transparent, transparent,
}; };
use crate::{FinalizedBlock, HashOrHeight, PreparedBlock, Utxo, ValidateContextError}; use crate::{FinalizedBlock, HashOrHeight, PreparedBlock, ValidateContextError};
use self::chain::Chain; use self::chain::Chain;
@ -158,7 +158,7 @@ impl NonFinalizedState {
/// Returns the `transparent::Output` pointed to by the given /// Returns the `transparent::Output` pointed to by the given
/// `transparent::OutPoint` if it is present in any chain. /// `transparent::OutPoint` if it is present in any chain.
pub fn any_utxo(&self, outpoint: &transparent::OutPoint) -> Option<Utxo> { pub fn any_utxo(&self, outpoint: &transparent::OutPoint) -> Option<transparent::Utxo> {
for chain in self.chain_set.iter().rev() { for chain in self.chain_set.iter().rev() {
if let Some(output) = chain.created_utxos.get(outpoint) { if let Some(output) = chain.created_utxos.get(outpoint) {
return Some(output.clone()); return Some(output.clone());

View File

@ -10,7 +10,7 @@ use zebra_chain::{
transaction::Transaction::*, transparent, work::difficulty::PartialCumulativeWork, transaction::Transaction::*, transparent, work::difficulty::PartialCumulativeWork,
}; };
use crate::{PreparedBlock, Utxo, ValidateContextError}; use crate::{PreparedBlock, ValidateContextError};
#[derive(Default, Clone)] #[derive(Default, Clone)]
pub struct Chain { pub struct Chain {
@ -18,7 +18,7 @@ pub struct Chain {
pub height_by_hash: HashMap<block::Hash, block::Height>, pub height_by_hash: HashMap<block::Hash, block::Height>,
pub tx_by_hash: HashMap<transaction::Hash, (block::Height, usize)>, pub tx_by_hash: HashMap<transaction::Hash, (block::Height, usize)>,
pub created_utxos: HashMap<transparent::OutPoint, Utxo>, pub created_utxos: HashMap<transparent::OutPoint, transparent::Utxo>,
spent_utxos: HashSet<transparent::OutPoint>, spent_utxos: HashSet<transparent::OutPoint>,
// TODO: add sprout, sapling and orchard anchors (#1320) // TODO: add sprout, sapling and orchard anchors (#1320)
sprout_anchors: HashSet<sprout::tree::Root>, sprout_anchors: HashSet<sprout::tree::Root>,
@ -303,17 +303,20 @@ impl UpdateWith<PreparedBlock> for Chain {
} }
} }
impl UpdateWith<HashMap<transparent::OutPoint, Utxo>> for Chain { impl UpdateWith<HashMap<transparent::OutPoint, transparent::Utxo>> for Chain {
fn update_chain_state_with( fn update_chain_state_with(
&mut self, &mut self,
utxos: &HashMap<transparent::OutPoint, Utxo>, utxos: &HashMap<transparent::OutPoint, transparent::Utxo>,
) -> Result<(), ValidateContextError> { ) -> Result<(), ValidateContextError> {
self.created_utxos self.created_utxos
.extend(utxos.iter().map(|(k, v)| (*k, v.clone()))); .extend(utxos.iter().map(|(k, v)| (*k, v.clone())));
Ok(()) Ok(())
} }
fn revert_chain_state_with(&mut self, utxos: &HashMap<transparent::OutPoint, Utxo>) { fn revert_chain_state_with(
&mut self,
utxos: &HashMap<transparent::OutPoint, transparent::Utxo>,
) {
self.created_utxos self.created_utxos
.retain(|outpoint, _| !utxos.contains_key(outpoint)); .retain(|outpoint, _| !utxos.contains_key(outpoint));
} }

View File

@ -6,7 +6,7 @@ use std::{
use tracing::instrument; use tracing::instrument;
use zebra_chain::{block, transparent}; use zebra_chain::{block, transparent};
use crate::{service::QueuedBlock, Utxo}; use crate::service::QueuedBlock;
/// A queue of blocks, awaiting the arrival of parent blocks. /// A queue of blocks, awaiting the arrival of parent blocks.
#[derive(Default)] #[derive(Default)]
@ -18,7 +18,7 @@ pub struct QueuedBlocks {
/// Hashes from `queued_blocks`, indexed by block height. /// Hashes from `queued_blocks`, indexed by block height.
by_height: BTreeMap<block::Height, HashSet<block::Hash>>, by_height: BTreeMap<block::Height, HashSet<block::Hash>>,
/// Known UTXOs. /// Known UTXOs.
known_utxos: HashMap<transparent::OutPoint, Utxo>, known_utxos: HashMap<transparent::OutPoint, transparent::Utxo>,
} }
impl QueuedBlocks { impl QueuedBlocks {
@ -150,7 +150,7 @@ impl QueuedBlocks {
} }
/// Try to look up this UTXO in any queued block. /// Try to look up this UTXO in any queued block.
pub fn utxo(&self, outpoint: &transparent::OutPoint) -> Option<Utxo> { pub fn utxo(&self, outpoint: &transparent::OutPoint) -> Option<transparent::Utxo> {
self.known_utxos.get(outpoint).cloned() self.known_utxos.get(outpoint).cloned()
} }
} }

View File

@ -5,10 +5,10 @@ use tokio::sync::broadcast;
use zebra_chain::transparent; use zebra_chain::transparent;
use crate::{BoxError, Response, Utxo}; use crate::{BoxError, Response};
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct PendingUtxos(HashMap<transparent::OutPoint, broadcast::Sender<Utxo>>); pub struct PendingUtxos(HashMap<transparent::OutPoint, broadcast::Sender<transparent::Utxo>>);
impl PendingUtxos { impl PendingUtxos {
/// Returns a future that will resolve to the `transparent::Output` pointed /// 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 /// Notify all requests waiting for the [`Utxo`] pointed to by the given
/// [`transparent::OutPoint`] that the [`Utxo`] has arrived. /// [`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) { if let Some(sender) = self.0.remove(outpoint) {
// Adding the outpoint as a field lets us crossreference // Adding the outpoint as a field lets us crossreference
// with the trace of the verification that made the request. // 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. /// Check the list of pending UTXO requests against the supplied UTXO index.
pub fn check_against(&mut self, utxos: &HashMap<transparent::OutPoint, Utxo>) { pub fn check_against(&mut self, utxos: &HashMap<transparent::OutPoint, transparent::Utxo>) {
for (outpoint, utxo) in utxos.iter() { for (outpoint, utxo) in utxos.iter() {
if let Some(sender) = self.0.remove(outpoint) { if let Some(sender) = self.0.remove(outpoint) {
tracing::trace!(?outpoint, "found pending UTXO"); tracing::trace!(?outpoint, "found pending UTXO");

View File

@ -10,7 +10,7 @@ use zebra_chain::{
}; };
use zebra_test::{prelude::*, transcript::Transcript}; 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; const LAST_BLOCK_HEIGHT: u32 = 10;
@ -88,7 +88,7 @@ async fn test_populated_state_responds_correctly(
hash: transaction_hash, hash: transaction_hash,
index: index as _, index: index as _,
}; };
let utxo = Utxo { let utxo = transparent::Utxo {
output, output,
height, height,
from_coinbase, from_coinbase,

View File

@ -21,7 +21,7 @@ impl Prepare for Arc<Block> {
let hash = block.hash(); let hash = block.hash();
let height = block.coinbase_height().unwrap(); let height = block.coinbase_height().unwrap();
let transaction_hashes: Vec<_> = block.transactions.iter().map(|tx| tx.hash()).collect(); 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 { PreparedBlock {
block, block,