More changes, incl. dropping DumbHasher in favor of SipHasher
only json stuff left in this round of compiler errors :)
This commit is contained in:
parent
7738722ab5
commit
7b89c15ed5
|
@ -23,13 +23,13 @@
|
|||
//!
|
||||
|
||||
use std::num::Zero;
|
||||
use std::{marker, ptr};
|
||||
use std::{marker, num, ptr};
|
||||
|
||||
use blockdata::block::{Block, BlockHeader};
|
||||
use blockdata::transaction::Transaction;
|
||||
use blockdata::constants::{DIFFCHANGE_INTERVAL, DIFFCHANGE_TIMESPAN,
|
||||
TARGET_BLOCK_SPACING, max_target, genesis_block};
|
||||
use network::constants::Network::{self, BitcoinTestnet};
|
||||
use network::constants::Network;
|
||||
use network::encodable::{ConsensusDecodable, ConsensusEncodable};
|
||||
use network::serialize::{BitcoinHash, SimpleDecoder, SimpleEncoder};
|
||||
use util::BitArray;
|
||||
|
@ -462,7 +462,7 @@ impl Blockchain {
|
|||
// Compute new target
|
||||
let mut target = unsafe { (*prev).block.header.target() };
|
||||
target = target.mul_u32(timespan);
|
||||
target = target / FromPrimitive::from_u64(DIFFCHANGE_TIMESPAN as u64).unwrap();
|
||||
target = target / num::FromPrimitive::from_u64(DIFFCHANGE_TIMESPAN as u64).unwrap();
|
||||
// Clamp below MAX_TARGET (difficulty 1)
|
||||
let max = max_target(self.network);
|
||||
if target > max { target = max };
|
||||
|
@ -470,13 +470,13 @@ impl Blockchain {
|
|||
satoshi_the_precision(&target)
|
||||
// On non-diffchange blocks, Testnet has a rule that any 20-minute-long
|
||||
// block intervals result the difficulty
|
||||
} else if self.network == BitcoinTestnet &&
|
||||
} else if self.network == Network::BitcoinTestnet &&
|
||||
block.header.time > unsafe { (*prev).block.header.time } + 2*TARGET_BLOCK_SPACING {
|
||||
max_target(self.network)
|
||||
// On the other hand, if we are in Testnet and the block interval is less
|
||||
// than 20 minutes, we need to scan backward to find a block for which the
|
||||
// previous rule did not apply, to find the "real" difficulty.
|
||||
} else if self.network == BitcoinTestnet {
|
||||
} else if self.network == Network::BitcoinTestnet {
|
||||
// Scan back DIFFCHANGE_INTERVAL blocks
|
||||
unsafe {
|
||||
let mut scan = prev;
|
||||
|
|
|
@ -26,7 +26,7 @@ use blockdata::opcodes;
|
|||
use blockdata::script::Script;
|
||||
use blockdata::transaction::{Transaction, TxOut, TxIn};
|
||||
use blockdata::block::{Block, BlockHeader};
|
||||
use network::constants::Network::{Bitcoin, BitcoinTestnet};
|
||||
use network::constants::Network;
|
||||
use util::misc::hex_bytes;
|
||||
use util::hash::MerkleRoot;
|
||||
use util::uint::Uint256;
|
||||
|
@ -74,7 +74,7 @@ fn bitcoin_genesis_tx() -> Transaction {
|
|||
// Outputs
|
||||
let mut out_script = Script::new();
|
||||
out_script.push_slice(hex_bytes("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f").unwrap().as_slice());
|
||||
out_script.push_opcode(opcodes::all::OP_CHECKSIG);
|
||||
out_script.push_opcode(opcodes::All::OP_CHECKSIG);
|
||||
ret.output.push(TxOut {
|
||||
value: 50 * COIN_VALUE,
|
||||
script_pubkey: out_script
|
||||
|
@ -87,7 +87,7 @@ fn bitcoin_genesis_tx() -> Transaction {
|
|||
/// Constructs and returns the genesis block
|
||||
pub fn genesis_block(network: Network) -> Block {
|
||||
match network {
|
||||
Bitcoin => {
|
||||
Network::Bitcoin => {
|
||||
let txdata = vec![bitcoin_genesis_tx()];
|
||||
Block {
|
||||
header: BlockHeader {
|
||||
|
@ -101,7 +101,7 @@ pub fn genesis_block(network: Network) -> Block {
|
|||
txdata: txdata
|
||||
}
|
||||
}
|
||||
BitcoinTestnet => {
|
||||
Network::Testnet => {
|
||||
let txdata = vec![bitcoin_genesis_tx()];
|
||||
Block {
|
||||
header: BlockHeader {
|
||||
|
@ -123,7 +123,7 @@ mod test {
|
|||
use std::default::Default;
|
||||
use serialize::hex::FromHex;
|
||||
|
||||
use network::constants::Network::{Bitcoin, BitcoinTestnet};
|
||||
use network::constants::Network;
|
||||
use network::serialize::{BitcoinHash, serialize};
|
||||
use blockdata::constants::{genesis_block, bitcoin_genesis_tx};
|
||||
use blockdata::constants::{MAX_SEQUENCE, COIN_VALUE};
|
||||
|
@ -152,7 +152,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn bitcoin_genesis_full_block() {
|
||||
let gen = genesis_block(Bitcoin);
|
||||
let gen = genesis_block(network::Bitcoin);
|
||||
|
||||
assert_eq!(gen.header.version, 1);
|
||||
assert_eq!(gen.header.prev_blockhash, Default::default());
|
||||
|
@ -167,7 +167,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn testnet_genesis_full_block() {
|
||||
let gen = genesis_block(BitcoinTestnet);
|
||||
let gen = genesis_block(network::Testnet);
|
||||
assert_eq!(gen.header.version, 1);
|
||||
assert_eq!(gen.header.prev_blockhash, Default::default());
|
||||
assert_eq!(gen.header.merkle_root.be_hex_string(),
|
||||
|
|
|
@ -623,9 +623,9 @@ impl json::ToJson for All {
|
|||
}
|
||||
|
||||
/// Empty stack is also FALSE
|
||||
pub static OP_FALSE: All = OP_PUSHBYTES_0;
|
||||
pub static OP_FALSE: All = All::OP_PUSHBYTES_0;
|
||||
/// Number 1 is also TRUE
|
||||
pub static OP_TRUE: All = OP_PUSHNUM_1;
|
||||
pub static OP_TRUE: All = All::OP_PUSHNUM_1;
|
||||
|
||||
/// Broad categories of opcodes with similar behavior
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
|
|
|
@ -50,11 +50,23 @@ use util::misc::script_find_and_remove;
|
|||
/// A Bitcoin script
|
||||
pub struct Script(Box<[u8]>);
|
||||
|
||||
impl<S: hash::Writer> hash::Hash<S> for Script {
|
||||
impl hash::Hash for Script {
|
||||
#[inline]
|
||||
fn hash(&self, state: &mut S) {
|
||||
fn hash<H>(&self, state: &mut H)
|
||||
where H: hash::Hasher
|
||||
{
|
||||
let &Script(ref raw) = self;
|
||||
(&raw[..]).hash(state)
|
||||
(&raw[..]).hash(state);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn hash_slice<H>(data: &[Script], state: &mut H)
|
||||
where H: hash::Hasher
|
||||
{
|
||||
for s in data.iter() {
|
||||
let &Script(ref raw) = s;
|
||||
(&raw[..]).hash(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1293,7 +1305,7 @@ impl<'a> ops::Index<ops::Range<usize>> for MaybeOwned<'a> {
|
|||
type Output = [u8];
|
||||
|
||||
#[inline]
|
||||
fn index(&self, index: Range<usize>) -> &[u8] {
|
||||
fn index(&self, index: ops::Range<usize>) -> &[u8] {
|
||||
match *self {
|
||||
MaybeOwned::Owned(ref v) => &v[index],
|
||||
MaybeOwned::Borrowed(ref s) => &s[index]
|
||||
|
@ -1305,7 +1317,7 @@ impl<'a> ops::Index<ops::RangeTo<usize>> for MaybeOwned<'a> {
|
|||
type Output = [u8];
|
||||
|
||||
#[inline]
|
||||
fn index(&self, index: RangeTo<usize>) -> &[u8] {
|
||||
fn index(&self, index: ops::RangeTo<usize>) -> &[u8] {
|
||||
match *self {
|
||||
MaybeOwned::Owned(ref v) => &v[index],
|
||||
MaybeOwned::Borrowed(ref s) => &s[index]
|
||||
|
@ -1317,7 +1329,7 @@ impl<'a> ops::Index<ops::RangeFrom<usize>> for MaybeOwned<'a> {
|
|||
type Output = [u8];
|
||||
|
||||
#[inline]
|
||||
fn index(&self, index: RangeFrom<usize>) -> &[u8] {
|
||||
fn index(&self, index: ops::RangeFrom<usize>) -> &[u8] {
|
||||
match *self {
|
||||
MaybeOwned::Owned(ref v) => &v[index],
|
||||
MaybeOwned::Borrowed(ref s) => &s[index]
|
||||
|
@ -1325,11 +1337,11 @@ impl<'a> ops::Index<ops::RangeFrom<usize>> for MaybeOwned<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ops::Index<ops::RangeAll<usize>> for MaybeOwned<'a> {
|
||||
impl<'a> ops::Index<ops::RangeFull<usize>> for MaybeOwned<'a> {
|
||||
type Output = [u8];
|
||||
|
||||
#[inline]
|
||||
fn index(&self, _: RangeAll<usize>) -> &[u8] {
|
||||
fn index(&self, _: ops::RangeFull<usize>) -> &[u8] {
|
||||
match *self {
|
||||
MaybeOwned::Owned(ref v) => &v[..],
|
||||
MaybeOwned::Borrowed(ref s) => &s[..]
|
||||
|
@ -1833,7 +1845,7 @@ impl Script {
|
|||
// If-statements take effect when not executing
|
||||
(false, opcodes::Class::Ordinary(opcodes::Ordinary::OP_IF)) => exec_stack.push(false),
|
||||
(false, opcodes::Class::Ordinary(opcodes::Ordinary::OP_NOTIF)) => exec_stack.push(false),
|
||||
(false, opcodes::Ordinary(opcodes::Ordinary::OP_ELSE)) => {
|
||||
(false, opcodes::Class::Ordinary(opcodes::Ordinary::OP_ELSE)) => {
|
||||
match exec_stack.last_mut() {
|
||||
Some(ref_e) => { *ref_e = !*ref_e }
|
||||
None => { return Err(Error::ElseWithoutIf); }
|
||||
|
|
|
@ -173,8 +173,8 @@ impl TxIn {
|
|||
if txo.script_pubkey.is_p2sh() && stack.len() > 0 {
|
||||
p2sh_stack = stack.clone();
|
||||
p2sh_script = match p2sh_stack.pop() {
|
||||
Some(script::Owned(v)) => Script::from_vec(v),
|
||||
Some(script::Borrowed(s)) => Script::from_vec(s.to_vec()),
|
||||
Some(script::MaybeOwned::Owned(v)) => Script::from_vec(v),
|
||||
Some(script::MaybeOwned::Borrowed(s)) => Script::from_vec(s.to_vec()),
|
||||
None => unreachable!()
|
||||
};
|
||||
}
|
||||
|
@ -254,8 +254,8 @@ impl Transaction {
|
|||
if txo.script_pubkey.is_p2sh() && stack.len() > 0 {
|
||||
p2sh_stack = stack.clone();
|
||||
p2sh_script = match p2sh_stack.pop() {
|
||||
Some(script::Owned(v)) => Script::from_vec(v),
|
||||
Some(script::Borrowed(s)) => Script::from_vec(s.to_vec()),
|
||||
Some(script::MaybeOwned::Owned(v)) => Script::from_vec(v),
|
||||
Some(script::MaybeOwned::Borrowed(s)) => Script::from_vec(s.to_vec()),
|
||||
None => unreachable!()
|
||||
};
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
use std::cmp;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash::map::Iter;
|
||||
use std::hash::SipHasher;
|
||||
use std::default::Default;
|
||||
use std::mem;
|
||||
use num_cpus;
|
||||
|
@ -31,7 +32,7 @@ use blockdata::constants::genesis_block;
|
|||
use blockdata::block::Block;
|
||||
use network::constants::Network;
|
||||
use network::serialize::BitcoinHash;
|
||||
use util::hash::{DumbHasher, Sha256dHash};
|
||||
use util::hash::Sha256dHash;
|
||||
|
||||
/// The amount of validation to do when updating the UTXO set
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug)]
|
||||
|
@ -101,7 +102,7 @@ impl<'a> Iterator<(Sha256dHash, u32, &'a TxOut, u32)> for UtxoIterator<'a> {
|
|||
|
||||
/// The UTXO set
|
||||
pub struct UtxoSet {
|
||||
table: HashMap<Sha256dHash, UtxoNode, DumbHasher>,
|
||||
table: HashMap<Sha256dHash, UtxoNode, SipHasher>,
|
||||
last_hash: Sha256dHash,
|
||||
// A circular buffer of deleted utxos, grouped by block
|
||||
spent_txos: Vec<Vec<((Sha256dHash, u32), (u32, TxOut))>>,
|
||||
|
@ -121,7 +122,7 @@ impl UtxoSet {
|
|||
// must follow suit, otherwise we will accept a transaction spending it
|
||||
// while the reference client won't, causing us to fork off the network.
|
||||
UtxoSet {
|
||||
table: HashMap::with_hasher(DumbHasher),
|
||||
table: HashMap::with_hasher(SipHasher::new()),
|
||||
last_hash: genesis_block(network).header.bitcoin_hash(),
|
||||
spent_txos: Vec::from_elem(rewind_limit, vec![]),
|
||||
spent_idx: 0,
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#![crate_type = "rlib"]
|
||||
|
||||
// Experimental features we need
|
||||
#![feature(box_patterns)]
|
||||
#![feature(custom_derive, plugin)]
|
||||
#![feature(overloaded_calls)]
|
||||
#![feature(unsafe_destructor)]
|
||||
|
|
|
@ -28,7 +28,7 @@ user_enum! {
|
|||
#[doc="Classic Bitcoin"]
|
||||
Bitcoin <-> "bitcoin",
|
||||
#[doc="Bitcoin's testnet"]
|
||||
BitcoinTestnet <-> "testnet"
|
||||
Testnet <-> "testnet"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ pub const USER_AGENT: &'static str = "bitcoin-rust v0.1";
|
|||
pub fn magic(network: Network) -> u32 {
|
||||
match network {
|
||||
Network::Bitcoin => 0xD9B4BEF9,
|
||||
Network::BitcoinTestnet => 0x0709110B
|
||||
Network::Testnet => 0x0709110B
|
||||
// Note: any new entries here must be added to `deserialize` below
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Network {
|
|||
let magic: u32 = try!(ConsensusDecodable::consensus_decode(d));
|
||||
match magic {
|
||||
0xD9B4BEF9 => Ok(Network::Bitcoin),
|
||||
0x0709110B => Ok(Network::BitcoinTestnet),
|
||||
0x0709110B => Ok(Network::Testnet),
|
||||
x => Err(d.error(format!("Unknown network (magic {:x})", x).as_slice()))
|
||||
}
|
||||
}
|
||||
|
@ -74,10 +74,10 @@ mod tests {
|
|||
#[test]
|
||||
fn serialize_test() {
|
||||
assert_eq!(serialize(&Network::Bitcoin).unwrap(), vec![0xf9, 0xbe, 0xb4, 0xd9]);
|
||||
assert_eq!(serialize(&Network::BitcoinTestnet).unwrap(), vec![0x0b, 0x11, 0x09, 0x07]);
|
||||
assert_eq!(serialize(&Network::Testnet).unwrap(), vec![0x0b, 0x11, 0x09, 0x07]);
|
||||
|
||||
assert_eq!(deserialize(vec![0xf9, 0xbe, 0xb4, 0xd9]), Ok(Network::Bitcoin));
|
||||
assert_eq!(deserialize(vec![0x0b, 0x11, 0x09, 0x07]), Ok(Network::BitcoinTestnet));
|
||||
assert_eq!(deserialize(vec![0x0b, 0x11, 0x09, 0x07]), Ok(Network::Testnet));
|
||||
|
||||
let bad: Result<Network, _> = deserialize("fakenet".as_bytes().to_vec());
|
||||
assert!(bad.is_err());
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
//! to connect to a peer, send network messages, and receive Bitcoin data.
|
||||
//!
|
||||
|
||||
use std::io::{Result, Error, ErrorKind};
|
||||
use std::{io, thread};
|
||||
use std::sync::mpsc::{channel, Receiver};
|
||||
|
||||
use network::constants::Network;
|
||||
use network::message;
|
||||
use network::message::SocketResponse::{self, MessageReceived};
|
||||
use network::message::NetworkMessage::Verack;
|
||||
use network::socket::Socket;
|
||||
|
||||
|
@ -35,13 +35,13 @@ pub trait Listener {
|
|||
/// Return the network this `Listener` is operating on
|
||||
fn network(&self) -> Network;
|
||||
/// Main listen loop
|
||||
fn start(&self) -> Result<(Receiver<SocketResponse>, Socket)> {
|
||||
fn start(&self) -> io::Result<(Receiver<message::SocketResponse>, Socket)> {
|
||||
// Open socket
|
||||
let mut ret_sock = Socket::new(self.network());
|
||||
match ret_sock.connect(self.peer(), self.port()) {
|
||||
Ok(_) => {},
|
||||
Err(_) => return Err(Error::new(ErrorKind::ConnectionFailed,
|
||||
"Listener connection failed", None))
|
||||
Err(_) => return Err(io::Error::new(io::ErrorKind::ConnectionFailed,
|
||||
"Listener connection failed", None))
|
||||
}
|
||||
let mut sock = ret_sock.clone();
|
||||
|
||||
|
@ -52,7 +52,7 @@ pub trait Listener {
|
|||
try!(sock.send_message(version_message));
|
||||
|
||||
// Message loop
|
||||
spawn(move || {
|
||||
thread::spawn(move || {
|
||||
let mut handshake_complete = false;
|
||||
let mut sock = sock;
|
||||
loop {
|
||||
|
@ -76,7 +76,7 @@ pub trait Listener {
|
|||
// We have to pass the message to the main thread for processing,
|
||||
// unfortunately, because sipa says we have to handle everything
|
||||
// in order.
|
||||
recv_tx.send(MessageReceived(payload));
|
||||
recv_tx.send(message::SocketResponse::MessageReceived(payload));
|
||||
}
|
||||
Err(e) => {
|
||||
// On failure we send an error message to the main thread, along with
|
||||
|
@ -84,7 +84,7 @@ pub trait Listener {
|
|||
// thread. (If we simply exited immediately, the channel would be torn
|
||||
// down and the main thread would never see the error message.)
|
||||
let (tx, rx) = channel();
|
||||
recv_tx.send(message::ConnectionFailed(e, tx));
|
||||
recv_tx.send(message::SocketResponse::ConnectionFailed(e, tx));
|
||||
rx.recv();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
//!
|
||||
|
||||
use collections::Vec;
|
||||
use std::iter;
|
||||
use std::io::{self, Cursor};
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
use blockdata::block;
|
||||
use blockdata::transaction;
|
||||
|
@ -50,7 +52,7 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for CommandString {
|
|||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<CommandString, E> {
|
||||
let rawbytes: [u8; 12] = try!(ConsensusDecodable::consensus_decode(d));
|
||||
let rv = FromIterator::from_iter(rawbytes.iter().filter_map(|&u| if u > 0 { Some(u as char) } else { None }));
|
||||
let rv = iter::FromIterator::from_iter(rawbytes.iter().filter_map(|&u| if u > 0 { Some(u as char) } else { None }));
|
||||
Ok(CommandString(rv))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,11 +27,11 @@ use util::hash::Sha256dHash;
|
|||
/// The type of an inventory object
|
||||
pub enum InvType {
|
||||
/// Error --- these inventories can be ignored
|
||||
InvError,
|
||||
Error,
|
||||
/// Transaction
|
||||
InvTransaction,
|
||||
Transaction,
|
||||
/// Block
|
||||
InvBlock
|
||||
Block
|
||||
}
|
||||
|
||||
// Some simple messages
|
||||
|
@ -101,9 +101,9 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Inventory {
|
|||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
try!(match self.inv_type {
|
||||
InvError => 0u32,
|
||||
InvTransaction => 1,
|
||||
InvBlock => 2
|
||||
InvType::Error => 0u32,
|
||||
InvType::Transaction => 1,
|
||||
InvType::Block => 2
|
||||
}.consensus_encode(s));
|
||||
self.hash.consensus_encode(s)
|
||||
}
|
||||
|
@ -115,9 +115,9 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Inventory {
|
|||
let int_type: u32 = try!(ConsensusDecodable::consensus_decode(d));
|
||||
Ok(Inventory {
|
||||
inv_type: match int_type {
|
||||
0 => InvError,
|
||||
1 => InvTransaction,
|
||||
2 => InvBlock,
|
||||
0 => InvType::Error,
|
||||
1 => InvType::Transaction,
|
||||
2 => InvType::Block,
|
||||
// TODO do not fail here
|
||||
_ => { panic!("bad inventory type field") }
|
||||
},
|
||||
|
|
|
@ -47,15 +47,6 @@ impl ::std::fmt::Debug for Sha256dHash {
|
|||
pub struct Ripemd160Hash([u8; 20]);
|
||||
impl_array_newtype!(Ripemd160Hash, u8, 20);
|
||||
|
||||
/// A "hasher" which just truncates and adds data to its state. Should
|
||||
/// only be used for hashtables indexed by "already random" data such
|
||||
/// as SHA2 hashes
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct DumbHasher;
|
||||
|
||||
/// The state of a `DumbHasher`
|
||||
pub struct DumbHasherState([u8; 8]);
|
||||
|
||||
/// A 32-bit hash obtained by truncating a real hash
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Hash32((u8, u8, u8, u8));
|
||||
|
@ -68,44 +59,6 @@ pub struct Hash48((u8, u8, u8, u8, u8, u8));
|
|||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Hash64((u8, u8, u8, u8, u8, u8, u8, u8));
|
||||
|
||||
|
||||
// Allow these to be used as a key for Rust's HashMap et. al.
|
||||
impl hash::Hash<DumbHasherState> for Sha256dHash {
|
||||
#[inline]
|
||||
fn hash(&self, state: &mut DumbHasherState) {
|
||||
let &Sha256dHash(ref hash) = self;
|
||||
let &DumbHasherState(ref mut arr) = state;
|
||||
for i in 0..8 {
|
||||
arr[i] += hash[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl hash::Hasher<DumbHasherState> for DumbHasher {
|
||||
#[inline]
|
||||
fn hash<T: hash::Hash<DumbHasherState>>(&self, value: &T) -> u64 {
|
||||
let mut ret = DumbHasherState([0; 8]);
|
||||
value.hash(&mut ret);
|
||||
let DumbHasherState(res) = ret;
|
||||
LittleEndian::read_u64(&res[0..8])
|
||||
}
|
||||
}
|
||||
|
||||
impl hash::Writer for DumbHasherState {
|
||||
#[inline]
|
||||
fn write(&mut self, msg: &[u8]) {
|
||||
let &DumbHasherState(ref mut arr) = self;
|
||||
for (n, &ch) in msg.iter().enumerate() {
|
||||
arr[n % 8] += ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for DumbHasher {
|
||||
#[inline]
|
||||
fn default() -> DumbHasher { DumbHasher }
|
||||
}
|
||||
|
||||
impl Ripemd160Hash {
|
||||
/// Create a hash by hashing some data
|
||||
pub fn from_data(data: &[u8]) -> Ripemd160Hash {
|
||||
|
|
|
@ -238,8 +238,8 @@ impl<K:BitArray+cmp::Eq+Zero+One+ops::BitXor<K,K>+ops::Shl<usize,K>+ops::Shr<usi
|
|||
}
|
||||
match (tree.child_l.take(), tree.child_r.take()) {
|
||||
(Some(_), Some(_)) => unreachable!(),
|
||||
(Some(Box::new(PatriciaTree { data, child_l, child_r, skip_prefix, skip_len })), None) |
|
||||
(None, Some(Box::new(PatriciaTree { data, child_l, child_r, skip_prefix, skip_len }))) => {
|
||||
(Some(box PatriciaTree { data, child_l, child_r, skip_prefix, skip_len }), None) |
|
||||
(None, Some(box PatriciaTree { data, child_l, child_r, skip_prefix, skip_len })) => {
|
||||
tree.data = data;
|
||||
tree.child_l = child_l;
|
||||
tree.child_r = child_r;
|
||||
|
@ -296,8 +296,8 @@ impl<K:BitArray+cmp::Eq+Zero+One+ops::BitXor<K,K>+ops::Shl<usize,K>+ops::Shr<usi
|
|||
return (false, ret);
|
||||
}
|
||||
// One child? Consolidate
|
||||
(bit, Some(Box::new(PatriciaTree { data, child_l, child_r, skip_prefix, skip_len })), None) |
|
||||
(bit, None, Some(Box::new(PatriciaTree { data, child_l, child_r, skip_prefix, skip_len }))) => {
|
||||
(bit, Some(box PatriciaTree { data, child_l, child_r, skip_prefix, skip_len }), None) |
|
||||
(bit, None, Some(box PatriciaTree { data, child_l, child_r, skip_prefix, skip_len })) => {
|
||||
tree.data = data;
|
||||
tree.child_l = child_l;
|
||||
tree.child_r = child_r;
|
||||
|
|
|
@ -22,7 +22,7 @@ use crypto::sha2::Sha256;
|
|||
|
||||
use blockdata::script::Script;
|
||||
use blockdata::opcodes;
|
||||
use network::constants::Network::{self, Bitcoin, BitcoinTestnet};
|
||||
use network::constants::Network;
|
||||
use util::hash::Ripemd160Hash;
|
||||
use util::base58::{self, FromBase58, ToBase58};
|
||||
|
||||
|
@ -89,8 +89,8 @@ impl ToBase58 for Address {
|
|||
fn base58_layout(&self) -> Vec<u8> {
|
||||
let mut ret = vec![
|
||||
match self.network {
|
||||
Bitcoin => 0,
|
||||
BitcoinTestnet => 111
|
||||
Network::Bitcoin => 0,
|
||||
Network::Testnet => 111
|
||||
}
|
||||
];
|
||||
ret.push_all(self.hash.as_slice());
|
||||
|
@ -106,8 +106,8 @@ impl FromBase58 for Address {
|
|||
|
||||
Ok(Address {
|
||||
network: match data[0] {
|
||||
0 => Bitcoin,
|
||||
111 => BitcoinTestnet,
|
||||
0 => Network::Bitcoin,
|
||||
111 => Network::Testnet,
|
||||
x => { return Err(base58::Error::InvalidVersion(vec![x])); }
|
||||
},
|
||||
hash: Ripemd160Hash::from_slice(data.slice_from(1))
|
||||
|
|
|
@ -30,7 +30,7 @@ use blockdata::script::Script;
|
|||
use network::constants::Network;
|
||||
use wallet::address::Address;
|
||||
use wallet::wallet::Wallet;
|
||||
use util::hash::{DumbHasher, Sha256dHash};
|
||||
use util::hash::Sha256dHash;
|
||||
|
||||
/// The type of a wallet-spendable txout
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
|
@ -61,7 +61,7 @@ pub struct WalletTxOut {
|
|||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct AddressIndex {
|
||||
tentative_index: HashMap<Script, Vec<WalletTxOut>>,
|
||||
index: HashMap<(Sha256dHash, u32), Vec<WalletTxOut>, DumbHasher>,
|
||||
index: HashMap<(Sha256dHash, u32), Vec<WalletTxOut>, SipHasher>,
|
||||
network: Network,
|
||||
k1: u64,
|
||||
k2: u64
|
||||
|
@ -74,7 +74,7 @@ impl AddressIndex {
|
|||
let (k1, k2) = wallet.siphash_key();
|
||||
let mut ret = AddressIndex {
|
||||
tentative_index: HashMap::with_capacity(utxo_set.n_utxos() / 256),
|
||||
index: HashMap::with_hasher(DumbHasher),
|
||||
index: HashMap::with_hasher(SipHasher::new()),
|
||||
network: wallet.network(),
|
||||
k1: k1,
|
||||
k2: k2
|
||||
|
|
|
@ -29,7 +29,7 @@ use crypto::sha2::Sha512;
|
|||
use secp256k1::key::{PublicKey, SecretKey};
|
||||
use secp256k1;
|
||||
|
||||
use network::constants::Network::{self, Bitcoin, BitcoinTestnet};
|
||||
use network::constants::Network;
|
||||
use util::base58;
|
||||
use util::base58::{FromBase58, ToBase58};
|
||||
|
||||
|
@ -288,8 +288,8 @@ impl ToBase58 for ExtendedPrivKey {
|
|||
fn base58_layout(&self) -> Vec<u8> {
|
||||
let mut ret = Vec::with_capacity(78);
|
||||
ret.push_all(match self.network {
|
||||
Bitcoin => [0x04, 0x88, 0xAD, 0xE4],
|
||||
BitcoinTestnet => [0x04, 0x35, 0x83, 0x94]
|
||||
Network::Bitcoin => [0x04, 0x88, 0xAD, 0xE4],
|
||||
Network::Testnet => [0x04, 0x35, 0x83, 0x94]
|
||||
});
|
||||
ret.push(self.depth as u8);
|
||||
ret.push_all(self.parent_fingerprint.as_slice());
|
||||
|
@ -320,8 +320,8 @@ impl FromBase58 for ExtendedPrivKey {
|
|||
|
||||
Ok(ExtendedPrivKey {
|
||||
network: match data.slice_to(4) {
|
||||
[0x04, 0x88, 0xAD, 0xE4] => Bitcoin,
|
||||
[0x04, 0x35, 0x83, 0x94] => BitcoinTestnet,
|
||||
[0x04, 0x88, 0xAD, 0xE4] => Network::Bitcoin,
|
||||
[0x04, 0x35, 0x83, 0x94] => Network::Testnet,
|
||||
_ => { return Err(base58::Error::InvalidVersion(data.slice_to(4).to_vec())); }
|
||||
},
|
||||
depth: data[4],
|
||||
|
@ -340,8 +340,8 @@ impl ToBase58 for ExtendedPubKey {
|
|||
assert!(self.public_key.is_compressed());
|
||||
let mut ret = Vec::with_capacity(78);
|
||||
ret.push_all(match self.network {
|
||||
Bitcoin => [0x04, 0x88, 0xB2, 0x1E],
|
||||
BitcoinTestnet => [0x04, 0x35, 0x87, 0xCF]
|
||||
Network::Bitcoin => [0x04, 0x88, 0xB2, 0x1E],
|
||||
Network::Testnet => [0x04, 0x35, 0x87, 0xCF]
|
||||
});
|
||||
ret.push(self.depth as u8);
|
||||
ret.push_all(self.parent_fingerprint.as_slice());
|
||||
|
@ -371,8 +371,8 @@ impl FromBase58 for ExtendedPubKey {
|
|||
|
||||
Ok(ExtendedPubKey {
|
||||
network: match data.slice_to(4) {
|
||||
[0x04, 0x88, 0xB2, 0x1E] => Bitcoin,
|
||||
[0x04, 0x35, 0x87, 0xCF] => BitcoinTestnet,
|
||||
[0x04, 0x88, 0xB2, 0x1E] => Network::Bitcoin,
|
||||
[0x04, 0x35, 0x87, 0xCF] => Network::Testnet,
|
||||
_ => { return Err(base58::Error::InvalidVersion(data.slice_to(4).to_vec())); }
|
||||
},
|
||||
depth: data[4],
|
||||
|
|
Loading…
Reference in New Issue