Change UtxoSet to use full TXID as key
Sorry, this is needed to enable proper txid/vout lookups for the address index. This means any users of wizards-wallet need to rebuild their utxo sets, and will also mean an increase in RAM usage.
This commit is contained in:
parent
6250f4fd9c
commit
c25862a107
|
@ -76,6 +76,7 @@ pub enum ScriptPubkeyTemplate {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TxOut {
|
impl TxOut {
|
||||||
|
/// Determines the template that this output adheres to, if any
|
||||||
pub fn classify(&self, network: Network) -> ScriptPubkeyTemplate {
|
pub fn classify(&self, network: Network) -> ScriptPubkeyTemplate {
|
||||||
if self.script_pubkey.len() == 25 &&
|
if self.script_pubkey.len() == 25 &&
|
||||||
self.script_pubkey.slice_to(3) == &[0x76, 0xa9, 0x14] &&
|
self.script_pubkey.slice_to(3) == &[0x76, 0xa9, 0x14] &&
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::hashmap::Entries;
|
use std::collections::hashmap::Entries;
|
||||||
|
use std::default::Default;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::os::num_cpus;
|
use std::os::num_cpus;
|
||||||
use std::sync::Future;
|
use std::sync::Future;
|
||||||
use std::num::Zero;
|
|
||||||
|
|
||||||
use blockdata::transaction::{Transaction, TxOut};
|
use blockdata::transaction::{Transaction, TxOut};
|
||||||
use blockdata::transaction::{TransactionError, InputNotFound};
|
use blockdata::transaction::{TransactionError, InputNotFound};
|
||||||
|
@ -33,7 +33,6 @@ use blockdata::block::Block;
|
||||||
use network::constants::Network;
|
use network::constants::Network;
|
||||||
use network::serialize::BitcoinHash;
|
use network::serialize::BitcoinHash;
|
||||||
use util::hash::{DumbHasher, Sha256dHash};
|
use util::hash::{DumbHasher, Sha256dHash};
|
||||||
use util::uint::Uint128;
|
|
||||||
use util::thinvec::ThinVec;
|
use util::thinvec::ThinVec;
|
||||||
|
|
||||||
/// The amount of validation to do when updating the UTXO set
|
/// The amount of validation to do when updating the UTXO set
|
||||||
|
@ -65,14 +64,14 @@ type UtxoNode = ThinVec<Option<TxOut>>;
|
||||||
|
|
||||||
/// An iterator over UTXOs
|
/// An iterator over UTXOs
|
||||||
pub struct UtxoIterator<'a> {
|
pub struct UtxoIterator<'a> {
|
||||||
tx_iter: Entries<'a, Uint128, UtxoNode>,
|
tx_iter: Entries<'a, Sha256dHash, UtxoNode>,
|
||||||
current_key: Uint128,
|
current_key: Sha256dHash,
|
||||||
current: Option<&'a UtxoNode>,
|
current: Option<&'a UtxoNode>,
|
||||||
tx_index: uint
|
tx_index: uint
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator<(Uint128, uint, &'a TxOut)> for UtxoIterator<'a> {
|
impl<'a> Iterator<(Sha256dHash, uint, &'a TxOut)> for UtxoIterator<'a> {
|
||||||
fn next(&mut self) -> Option<(Uint128, uint, &'a TxOut)> {
|
fn next(&mut self) -> Option<(Sha256dHash, uint, &'a TxOut)> {
|
||||||
while self.current.is_some() {
|
while self.current.is_some() {
|
||||||
let current = self.current.unwrap();
|
let current = self.current.unwrap();
|
||||||
while self.tx_index < current.len() {
|
while self.tx_index < current.len() {
|
||||||
|
@ -98,7 +97,7 @@ impl<'a> Iterator<(Uint128, uint, &'a TxOut)> for UtxoIterator<'a> {
|
||||||
|
|
||||||
/// The UTXO set
|
/// The UTXO set
|
||||||
pub struct UtxoSet {
|
pub struct UtxoSet {
|
||||||
table: HashMap<Uint128, UtxoNode, DumbHasher>,
|
table: HashMap<Sha256dHash, UtxoNode, DumbHasher>,
|
||||||
last_hash: Sha256dHash,
|
last_hash: Sha256dHash,
|
||||||
// A circular buffer of deleted utxos, grouped by block
|
// A circular buffer of deleted utxos, grouped by block
|
||||||
spent_txos: Vec<Vec<((Sha256dHash, u32), TxOut)>>,
|
spent_txos: Vec<Vec<((Sha256dHash, u32), TxOut)>>,
|
||||||
|
@ -147,7 +146,7 @@ impl UtxoSet {
|
||||||
};
|
};
|
||||||
// Get the old value, if any (this is suprisingly possible, c.f. BIP30
|
// Get the old value, if any (this is suprisingly possible, c.f. BIP30
|
||||||
// and the other comments in this file referring to it)
|
// and the other comments in this file referring to it)
|
||||||
let ret = self.table.swap(txid.into_le().low_128(), new_node);
|
let ret = self.table.swap(txid, new_node);
|
||||||
if ret.is_none() {
|
if ret.is_none() {
|
||||||
self.n_utxos += tx.output.len() as u64;
|
self.n_utxos += tx.output.len() as u64;
|
||||||
}
|
}
|
||||||
|
@ -159,7 +158,7 @@ impl UtxoSet {
|
||||||
// This whole function has awkward scoping thx to lexical borrow scoping :(
|
// This whole function has awkward scoping thx to lexical borrow scoping :(
|
||||||
let (ret, should_delete) = {
|
let (ret, should_delete) = {
|
||||||
// Locate the UTXO, failing if not found
|
// Locate the UTXO, failing if not found
|
||||||
let node = match self.table.find_mut(&txid.into_le().low_128()) {
|
let node = match self.table.find_mut(&txid) {
|
||||||
Some(node) => node,
|
Some(node) => node,
|
||||||
None => return None
|
None => return None
|
||||||
};
|
};
|
||||||
|
@ -177,7 +176,7 @@ impl UtxoSet {
|
||||||
|
|
||||||
// Delete the whole node if it is no longer being used
|
// Delete the whole node if it is no longer being used
|
||||||
if should_delete {
|
if should_delete {
|
||||||
self.table.remove(&txid.into_le().low_128());
|
self.table.remove(&txid);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.n_utxos -= if ret.is_some() { 1 } else { 0 };
|
self.n_utxos -= if ret.is_some() { 1 } else { 0 };
|
||||||
|
@ -187,7 +186,7 @@ impl UtxoSet {
|
||||||
/// Get a reference to a UTXO in the set
|
/// Get a reference to a UTXO in the set
|
||||||
pub fn get_utxo<'a>(&'a self, txid: Sha256dHash, vout: u32) -> Option<&'a TxOut> {
|
pub fn get_utxo<'a>(&'a self, txid: Sha256dHash, vout: u32) -> Option<&'a TxOut> {
|
||||||
// Locate the UTXO, failing if not found
|
// Locate the UTXO, failing if not found
|
||||||
let node = match self.table.find(&txid.into_le().low_128()) {
|
let node = match self.table.find(&txid) {
|
||||||
Some(node) => node,
|
Some(node) => node,
|
||||||
None => return None
|
None => return None
|
||||||
};
|
};
|
||||||
|
@ -347,7 +346,7 @@ impl UtxoSet {
|
||||||
for ((txid, n), txo) in extract_vec.move_iter() {
|
for ((txid, n), txo) in extract_vec.move_iter() {
|
||||||
// Remove the tx's utxo list and patch the txo into place
|
// Remove the tx's utxo list and patch the txo into place
|
||||||
let new_node =
|
let new_node =
|
||||||
match self.table.pop(&txid.into_le().low_128()) {
|
match self.table.pop(&txid) {
|
||||||
Some(mut thinvec) => {
|
Some(mut thinvec) => {
|
||||||
let old_len = thinvec.len() as u32;
|
let old_len = thinvec.len() as u32;
|
||||||
if old_len < n + 1 {
|
if old_len < n + 1 {
|
||||||
|
@ -373,7 +372,7 @@ impl UtxoSet {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Ram it back into the tree
|
// Ram it back into the tree
|
||||||
self.table.insert(txid.into_le().low_128(), new_node);
|
self.table.insert(txid, new_node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
skipped_genesis = true;
|
skipped_genesis = true;
|
||||||
|
@ -414,7 +413,7 @@ impl UtxoSet {
|
||||||
tx_index: 0
|
tx_index: 0
|
||||||
},
|
},
|
||||||
None => UtxoIterator {
|
None => UtxoIterator {
|
||||||
current_key: Zero::zero(),
|
current_key: Default::default(),
|
||||||
current: None,
|
current: None,
|
||||||
tx_iter: iter,
|
tx_iter: iter,
|
||||||
tx_index: 0
|
tx_index: 0
|
||||||
|
|
|
@ -23,12 +23,12 @@ use std::collections::HashMap;
|
||||||
use blockdata::utxoset::UtxoSet;
|
use blockdata::utxoset::UtxoSet;
|
||||||
use blockdata::script::Script;
|
use blockdata::script::Script;
|
||||||
use wallet::wallet::Wallet;
|
use wallet::wallet::Wallet;
|
||||||
use util::uint::Uint128;
|
use util::hash::Sha256dHash;
|
||||||
|
|
||||||
/// An address index
|
/// An address index
|
||||||
#[deriving(Clone, PartialEq, Eq, Show)]
|
#[deriving(Clone, PartialEq, Eq, Show)]
|
||||||
pub struct AddressIndex {
|
pub struct AddressIndex {
|
||||||
index: HashMap<Script, (Uint128, uint)>
|
index: HashMap<Script, (Sha256dHash, uint)>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AddressIndex {
|
impl AddressIndex {
|
||||||
|
@ -48,4 +48,3 @@ impl AddressIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue