check mempool::is_spent in ChainMemoryPoolTransactionOutputProvider::is_spent
This commit is contained in:
parent
1065541453
commit
fdf704f6ae
|
@ -195,6 +195,12 @@ impl Chain {
|
|||
&self.memory_pool
|
||||
}
|
||||
|
||||
/// Get mutable memory pool
|
||||
#[cfg(test)]
|
||||
pub fn memory_pool_mut(&mut self) -> &mut MemoryPool {
|
||||
&mut self.memory_pool
|
||||
}
|
||||
|
||||
/// Get number of blocks in given state
|
||||
pub fn length_of_blocks_state(&self, state: BlockState) -> u32 {
|
||||
match state {
|
||||
|
|
|
@ -198,16 +198,19 @@ impl ChainMemoryPoolTransactionOutputProvider {
|
|||
|
||||
impl PreviousTransactionOutputProvider for ChainMemoryPoolTransactionOutputProvider {
|
||||
fn previous_transaction_output(&self, prevout: &OutPoint) -> Option<TransactionOutput> {
|
||||
self.chain.read().memory_pool().previous_transaction_output(prevout)
|
||||
let chain = self.chain.read();
|
||||
chain.memory_pool().previous_transaction_output(prevout)
|
||||
.or_else(|| chain.storage().as_previous_transaction_output_provider().previous_transaction_output(prevout))
|
||||
}
|
||||
}
|
||||
|
||||
impl TransactionOutputObserver for ChainMemoryPoolTransactionOutputProvider {
|
||||
fn is_spent(&self, prevout: &OutPoint) -> Option<bool> {
|
||||
self.chain.read()
|
||||
.storage()
|
||||
.transaction_meta(&prevout.hash)
|
||||
.and_then(|tm| tm.is_spent(prevout.index as usize))
|
||||
let chain = self.chain.read();
|
||||
if chain.memory_pool().is_spent(prevout) {
|
||||
return Some(true);
|
||||
}
|
||||
chain.storage().transaction_meta(&prevout.hash).and_then(|tm| tm.is_spent(prevout.index as usize))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,12 +230,15 @@ impl TransactionOutputObserver for EmptyTransactionOutputProvider {
|
|||
pub mod tests {
|
||||
use std::sync::Arc;
|
||||
use std::collections::HashMap;
|
||||
use parking_lot::RwLock;
|
||||
use chain::Transaction;
|
||||
use synchronization_chain::{Chain, ChainRef};
|
||||
use synchronization_client::CoreVerificationSink;
|
||||
use synchronization_executor::tests::DummyTaskExecutor;
|
||||
use primitives::hash::H256;
|
||||
use super::{Verifier, BlockVerificationSink, TransactionVerificationSink};
|
||||
use db::IndexedBlock;
|
||||
use super::{Verifier, BlockVerificationSink, TransactionVerificationSink, ChainMemoryPoolTransactionOutputProvider};
|
||||
use db::{self, IndexedBlock};
|
||||
use test_data;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct DummyVerifier {
|
||||
|
@ -274,4 +280,19 @@ pub mod tests {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn when_transaction_spends_output_twice() {
|
||||
use db::TransactionOutputObserver;
|
||||
let tx1: Transaction = test_data::TransactionBuilder::with_default_input(0).into();
|
||||
let tx2: Transaction = test_data::TransactionBuilder::with_default_input(1).into();
|
||||
let out1 = tx1.inputs[0].previous_output.clone();
|
||||
let out2 = tx2.inputs[0].previous_output.clone();
|
||||
let mut chain = Chain::new(Arc::new(db::TestStorage::with_genesis_block()));
|
||||
chain.memory_pool_mut().insert_verified(tx1);
|
||||
let chain = ChainRef::new(RwLock::new(chain));
|
||||
let provider = ChainMemoryPoolTransactionOutputProvider::with_chain(chain);
|
||||
assert!(provider.is_spent(&out1).unwrap_or_default());
|
||||
assert!(!provider.is_spent(&out2).unwrap_or_default());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue