Checkpoint commit: into warnings!

This commit is contained in:
Andrew Poelstra 2015-04-10 18:15:57 -05:00
parent 1d78dccb9e
commit 3117f95b62
13 changed files with 143 additions and 141 deletions

View File

@ -32,7 +32,7 @@ use blockdata::transaction::Transaction;
/// A block header, which contains all the block's information except /// A block header, which contains all the block's information except
/// the actual transactions /// the actual transactions
#[derive(PartialEq, Eq, Clone, Debug)] #[derive(Copy, PartialEq, Eq, Clone, Debug)]
pub struct BlockHeader { pub struct BlockHeader {
/// The protocol version. Should always be 1. /// The protocol version. Should always be 1.
pub version: u32, pub version: u32,

View File

@ -34,7 +34,7 @@ use network::encodable::{ConsensusDecodable, ConsensusEncodable};
// write an #[inline] helper function which casts to u8s. // write an #[inline] helper function which casts to u8s.
/// A script Opcode /// A script Opcode
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[repr(u8)] #[repr(u8)]
pub enum All { pub enum All {
/// Push an empty array onto the stack /// Push an empty array onto the stack
@ -633,7 +633,7 @@ pub static OP_FALSE: All = All::OP_PUSHBYTES_0;
pub static OP_TRUE: All = All::OP_PUSHNUM_1; pub static OP_TRUE: All = All::OP_PUSHNUM_1;
/// Broad categories of opcodes with similar behavior /// Broad categories of opcodes with similar behavior
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Class { pub enum Class {
/// Pushes the given number onto the stack /// Pushes the given number onto the stack
PushNum(i32), PushNum(i32),
@ -663,7 +663,7 @@ macro_rules! ordinary_opcode {
($($op:ident),*) => ( ($($op:ident),*) => (
#[repr(u8)] #[repr(u8)]
#[doc(hidden)] #[doc(hidden)]
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Ordinary { pub enum Ordinary {
$( $op = All::$op as u8 ),* $( $op = All::$op as u8 ),*
} }

View File

@ -1628,10 +1628,10 @@ macro_rules! stack_opcode {
macro_rules! num_opcode { macro_rules! num_opcode {
($stack:ident($($var:ident),*): $op:expr) => ({ ($stack:ident($($var:ident),*): $op:expr) => ({
$( $(
let $var = try!(read_scriptint(match $stack.pop() { let $var = try!(read_scriptint(&match $stack.pop() {
Some(elem) => &elem[..], Some(elem) => elem,
None => { return Err(Error::PopEmptyStack); } None => { return Err(Error::PopEmptyStack); }
})); }[..]));
)* )*
$stack.push(MaybeOwned::Owned(build_scriptint($op))); $stack.push(MaybeOwned::Owned(build_scriptint($op)));
// Return a tuple of all the variables // Return a tuple of all the variables

View File

@ -159,10 +159,9 @@ impl TxIn {
let txo = utxoset.get_utxo(self.prev_hash, self.prev_index); let txo = utxoset.get_utxo(self.prev_hash, self.prev_index);
match txo { match txo {
Some((_, txo)) => { Some((_, txo)) => {
let mut p2sh_stack = Vec::new(); let (mut p2sh_stack, mut p2sh_script) = (vec![], Script::new());
let mut p2sh_script = Script::new();
let mut stack = Vec::with_capacity(6); let mut stack = vec![];
match self.script_sig.evaluate(&mut stack, Some((txn, index)), None) { match self.script_sig.evaluate(&mut stack, Some((txn, index)), None) {
Ok(_) => {} Ok(_) => {}
Err(e) => { return Err(Error::InputScriptFailure(e)); } Err(e) => { return Err(Error::InputScriptFailure(e)); }
@ -240,8 +239,7 @@ impl Transaction {
let txo = utxoset.get_utxo(input.prev_hash, input.prev_index); let txo = utxoset.get_utxo(input.prev_hash, input.prev_index);
match txo { match txo {
Some((_, txo)) => { Some((_, txo)) => {
let mut p2sh_stack = Vec::new(); let (mut p2sh_stack, mut p2sh_script) = (vec![], Script::new());
let mut p2sh_script = Script::new();
let mut stack = Vec::with_capacity(6); let mut stack = Vec::with_capacity(6);
trace.sig_trace = input.script_sig.trace(&mut stack, Some((self, n))); trace.sig_trace = input.script_sig.trace(&mut stack, Some((self, n)));

View File

@ -196,7 +196,7 @@ impl UtxoSet {
}; };
// Check that this specific output is there // Check that this specific output is there
if vout as usize >= node.outputs.len() { return None; } if vout as usize >= node.outputs.len() { return None; }
let replace = node.outputs[vout as usize]; let replace = &node.outputs[vout as usize];
Some((node.height as usize, replace.as_ref().unwrap())) Some((node.height as usize, replace.as_ref().unwrap()))
} }
@ -283,7 +283,7 @@ impl UtxoSet {
// Return the last error since we need to finish every future before // Return the last error since we need to finish every future before
// leaving this function, and given that, it's easier to return the last. // leaving this function, and given that, it's easier to return the last.
let mut last_err = Ok(()); let mut last_err = Ok(());
for res in future_vec.iter_mut().map(|f| f.await().unwrap()) { for res in future_vec.into_iter().map(|f| f.await().unwrap()) {
if res.is_err() { last_err = res; } if res.is_err() { last_err = res; }
} }
if last_err.is_err() { return last_err; } if last_err.is_err() { return last_err; }
@ -292,7 +292,7 @@ impl UtxoSet {
for tx in block.txdata.iter().skip(1) { for tx in block.txdata.iter().skip(1) {
let txid = tx.bitcoin_hash(); let txid = tx.bitcoin_hash();
// Put the removed utxos into the stxo cache, in case we need to rewind // Put the removed utxos into the stxo cache, in case we need to rewind
(&self.spent_txos[spent_idx]).reserve(tx.input.len()); (&mut self.spent_txos[spent_idx]).reserve(tx.input.len());
for (n, input) in tx.input.iter().enumerate() { for (n, input) in tx.input.iter().enumerate() {
let taken = self.take_utxo(input.prev_hash, input.prev_index); let taken = self.take_utxo(input.prev_hash, input.prev_index);
match taken { match taken {

View File

@ -117,6 +117,8 @@ macro_rules! impl_array_newtype {
} }
} }
impl Copy for $thing {}
impl ::std::hash::Hash for $thing { impl ::std::hash::Hash for $thing {
#[inline] #[inline]
fn hash<H>(&self, state: &mut H) fn hash<H>(&self, state: &mut H)

View File

@ -56,9 +56,12 @@ extern crate rand;
extern crate rustc_serialize as serialize; extern crate rustc_serialize as serialize;
extern crate secp256k1; extern crate secp256k1;
extern crate serde; extern crate serde;
extern crate test; #[cfg(test)] extern crate test;
extern crate time; extern crate time;
#[cfg(test)]
#[macro_use]
mod test_macros;
#[macro_use] #[macro_use]
mod internal_macros; mod internal_macros;
#[macro_use] #[macro_use]

View File

@ -22,7 +22,7 @@ use network::encodable::{ConsensusDecodable, ConsensusEncodable};
use network::serialize::{SimpleEncoder, SimpleDecoder}; use network::serialize::{SimpleEncoder, SimpleDecoder};
user_enum! { user_enum! {
#[derive(PartialEq, Eq, Clone, Hash)] #[derive(Copy, PartialEq, Eq, Clone, Hash)]
#[doc="The cryptocurrency to act on"] #[doc="The cryptocurrency to act on"]
pub enum Network { pub enum Network {
#[doc="Classic Bitcoin"] #[doc="Classic Bitcoin"]

View File

@ -35,9 +35,9 @@ use util::{self, propagate_err};
/// Format an IP address in the 16-byte bitcoin protocol serialization /// Format an IP address in the 16-byte bitcoin protocol serialization
fn ipaddr_to_bitcoin_addr(ipaddr: &net::IpAddr) -> [u16; 8] { fn ipaddr_to_bitcoin_addr(ipaddr: &net::IpAddr) -> [u16; 8] {
match *ipaddr { match *ipaddr {
net::IpAddr::V4(ref addr) => &addr.to_ipv6_mapped(), net::IpAddr::V4(ref addr) => addr.to_ipv6_mapped().segments(),
net::IpAddr::V6(ref addr) => addr net::IpAddr::V6(ref addr) => addr.segments()
}.segments() }
} }
/// A network socket along with information about the peer /// A network socket along with information about the peer
@ -55,6 +55,31 @@ pub struct Socket {
pub magic: u32 pub magic: u32
} }
macro_rules! with_socket(($s:ident, $sock:ident, $body:block) => ({
use ::std::ops::DerefMut;
let mut sock_lock = $s.socket.lock();
match sock_lock {
Err(_) => {
let io_err = io::Error::new(io::ErrorKind::NotConnected,
"socket: socket mutex was poisoned");
return Err(util::Error::Io(io_err));
}
Ok(mut guard) => {
match *guard.deref_mut() {
Some(ref mut $sock) => {
$body
}
None => {
let io_err = io::Error::new(io::ErrorKind::NotConnected,
"socket: not connected to peer");
return Err(util::Error::Io(io_err));
}
}
}
}
}));
impl Socket { impl Socket {
// TODO: we fix services to 0 // TODO: we fix services to 0
/// Construct a new socket /// Construct a new socket
@ -85,30 +110,9 @@ impl Socket {
} }
} }
fn socket(&mut self) -> Result<&mut net::TcpStream, util::Error> {
let mut sock_lock = self.socket.lock();
match sock_lock {
Err(_) => {
let io_err = io::Error::new(io::ErrorKind::NotConnected,
"socket: socket mutex was poisoned");
Err(util::Error::Io(io_err))
}
Ok(guard) => {
match *guard {
Some(ref mut sock) => Ok(sock),
None => {
let io_err = io::Error::new(io::ErrorKind::NotConnected,
"socket: not connected to peer");
Err(util::Error::Io(io_err))
}
}
}
}
}
/// Peer address /// Peer address
pub fn receiver_address(&mut self) -> Result<Address, util::Error> { pub fn receiver_address(&mut self) -> Result<Address, util::Error> {
let sock = try!(self.socket()); with_socket!(self, sock, {
match sock.peer_addr() { match sock.peer_addr() {
Ok(addr) => { Ok(addr) => {
Ok(Address { Ok(Address {
@ -119,11 +123,12 @@ impl Socket {
}, },
Err(e) => Err(util::Error::Io(e)) Err(e) => Err(util::Error::Io(e))
} }
})
} }
/// Our own address /// Our own address
pub fn sender_address(&mut self) -> Result<Address, util::Error> { pub fn sender_address(&mut self) -> Result<Address, util::Error> {
let sock = try!(self.socket()); with_socket!(self, sock, {
match sock.local_addr() { match sock.local_addr() {
Ok(addr) => { Ok(addr) => {
Ok(Address { Ok(Address {
@ -134,6 +139,7 @@ impl Socket {
}, },
Err(e) => Err(util::Error::Io(e)) Err(e) => Err(util::Error::Io(e))
} }
})
} }
/// Produce a version message appropriate for this socket /// Produce a version message appropriate for this socket
@ -157,16 +163,17 @@ impl Socket {
/// Send a general message across the line /// Send a general message across the line
pub fn send_message(&mut self, payload: NetworkMessage) -> Result<(), util::Error> { pub fn send_message(&mut self, payload: NetworkMessage) -> Result<(), util::Error> {
let sock = try!(self.socket()); with_socket!(self, sock, {
let message = RawNetworkMessage { magic: self.magic, payload: payload }; let message = RawNetworkMessage { magic: self.magic, payload: payload };
try!(message.consensus_encode(&mut RawEncoder::new(sock))); try!(message.consensus_encode(&mut RawEncoder::new(&mut *sock)));
sock.flush().map_err(util::Error::Io) sock.flush().map_err(util::Error::Io)
})
} }
/// Receive the next message from the peer, decoding the network header /// Receive the next message from the peer, decoding the network header
/// and verifying its correctness. Returns the undecoded payload. /// and verifying its correctness. Returns the undecoded payload.
pub fn receive_message(&mut self) -> Result<NetworkMessage, util::Error> { pub fn receive_message(&mut self) -> Result<NetworkMessage, util::Error> {
let sock = try!(self.socket()); with_socket!(self, sock, {
// We need a new scope since the closure in here borrows read_err, // We need a new scope since the closure in here borrows read_err,
// and we try to read it afterward. Letting `iter` go out fixes it. // and we try to read it afterward. Letting `iter` go out fixes it.
let mut decoder = RawDecoder::new(sock); let mut decoder = RawDecoder::new(sock);
@ -186,6 +193,7 @@ impl Socket {
} }
} }
} }
})
} }
} }

View File

@ -48,15 +48,15 @@ pub struct Ripemd160Hash([u8; 20]);
impl_array_newtype!(Ripemd160Hash, u8, 20); impl_array_newtype!(Ripemd160Hash, u8, 20);
/// A 32-bit hash obtained by truncating a real hash /// A 32-bit hash obtained by truncating a real hash
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Hash32((u8, u8, u8, u8)); pub struct Hash32((u8, u8, u8, u8));
/// A 48-bit hash obtained by truncating a real hash /// A 48-bit hash obtained by truncating a real hash
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Hash48((u8, u8, u8, u8, u8, u8)); pub struct Hash48((u8, u8, u8, u8, u8, u8));
/// A 64-bit hash obtained by truncating a real hash /// A 64-bit hash obtained by truncating a real hash
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Hash64((u8, u8, u8, u8, u8, u8, u8, u8)); pub struct Hash64((u8, u8, u8, u8, u8, u8, u8, u8));
impl Ripemd160Hash { impl Ripemd160Hash {
@ -268,8 +268,7 @@ mod tests {
use std::io::Cursor; use std::io::Cursor;
use std::num::FromPrimitive; use std::num::FromPrimitive;
use std::str::from_utf8; use std::str::from_utf8;
use serialize::Encodable; use serde::{json, Serialize, Deserialize};
use serialize::json;
use network::serialize::{serialize, deserialize}; use network::serialize::{serialize, deserialize};
use util::hash::Sha256dHash; use util::hash::Sha256dHash;
@ -296,15 +295,15 @@ mod tests {
#[test] #[test]
fn test_hash_encode_decode() { fn test_hash_encode_decode() {
let hash = Sha256dHash::from_data(&[]); let hash = Sha256dHash::from_data(&[]);
let mut writer = Cursor::new(vec![]); let mut writer = vec![];
{ {
let mut encoder = json::Encoder::new(&mut writer); let mut serializer = json::ser::Serializer::new(&mut writer);
assert!(hash.encode(&mut encoder).is_ok()); assert!(hash.serialize(&mut serializer).is_ok());
} }
let res = writer.into_inner(); assert_eq!(&writer[..],
assert_eq!(&res[..],
"\"56944c5d3f98413ef45cf54545538103cc9f298e0575820ad3591376e2e0f65d\"".as_bytes()); "\"56944c5d3f98413ef45cf54545538103cc9f298e0575820ad3591376e2e0f65d\"".as_bytes());
assert_eq!(json::decode(from_utf8(res.as_slice()).unwrap()), Ok(hash)); let mut deserializer = json::de::Deserializer::new(writer.iter().map(|c| Ok(*c))).unwrap();
assert_eq!(hash, Deserialize::deserialize(&mut deserializer).unwrap());
} }
#[test] #[test]

View File

@ -25,7 +25,7 @@ pub fn hex_bytes(s: &str) -> Result<Vec<u8>, Error> {
let mut v = vec![]; let mut v = vec![];
let mut iter = s.chars().pair(); let mut iter = s.chars().pair();
// Do the parsing // Do the parsing
try!(iter.fold(Ok(()), |e, (f, s)| try!(iter.by_ref().fold(Ok(()), |e, (f, s)|
if e.is_err() { e } if e.is_err() { e }
else { else {
match (f.to_digit(16), s.to_digit(16)) { match (f.to_digit(16), s.to_digit(16)) {
@ -73,9 +73,8 @@ pub fn script_find_and_remove(haystack: &mut Vec<u8>, needle: &[u8]) -> usize {
let mut i = 0; let mut i = 0;
while i <= top { while i <= top {
if &haystack[i..(i + needle.len())] == needle { if &haystack[i..(i + needle.len())] == needle {
let v = &mut haystack;
for j in i..top { for j in i..top {
v.swap(j + needle.len(), j); haystack.swap(j + needle.len(), j);
} }
n_deleted += 1; n_deleted += 1;
// This is ugly but prevents infinite loop in case of overflow // This is ugly but prevents infinite loop in case of overflow

View File

@ -30,7 +30,7 @@ use network::serialize::{SimpleDecoder, SimpleEncoder};
use util::BitArray; use util::BitArray;
/// Patricia troo /// Patricia troo
pub struct PatriciaTree<K, V> { pub struct PatriciaTree<K: Copy, V> {
data: Option<V>, data: Option<V>,
child_l: Option<Box<PatriciaTree<K, V>>>, child_l: Option<Box<PatriciaTree<K, V>>>,
child_r: Option<Box<PatriciaTree<K, V>>>, child_r: Option<Box<PatriciaTree<K, V>>>,
@ -39,7 +39,7 @@ pub struct PatriciaTree<K, V> {
} }
impl<K, V> PatriciaTree<K, V> impl<K, V> PatriciaTree<K, V>
where K: BitArray + cmp::Eq + Zero + One + where K: Copy + BitArray + cmp::Eq + Zero + One +
ops::BitXor<K, Output=K> + ops::BitXor<K, Output=K> +
ops::Add<K, Output=K> + ops::Add<K, Output=K> +
ops::Shr<usize, Output=K> + ops::Shr<usize, Output=K> +
@ -221,7 +221,7 @@ impl<K, V> PatriciaTree<K, V>
/// Return value is (deletable, actual return value), where `deletable` is true /// Return value is (deletable, actual return value), where `deletable` is true
/// is true when the entire node can be deleted (i.e. it has no children) /// is true when the entire node can be deleted (i.e. it has no children)
fn recurse<K, V>(tree: &mut PatriciaTree<K, V>, key: &K, key_len: usize) -> (bool, Option<V>) fn recurse<K, V>(tree: &mut PatriciaTree<K, V>, key: &K, key_len: usize) -> (bool, Option<V>)
where K: BitArray + cmp::Eq + Zero + One + where K: Copy + BitArray + cmp::Eq + Zero + One +
ops::Add<K, Output=K> + ops::Add<K, Output=K> +
ops::Shr<usize, Output=K> + ops::Shr<usize, Output=K> +
ops::Shl<usize, Output=K> ops::Shl<usize, Output=K>
@ -333,7 +333,7 @@ impl<K, V> PatriciaTree<K, V>
/// Count all the nodes /// Count all the nodes
pub fn node_count(&self) -> usize { pub fn node_count(&self) -> usize {
fn recurse<K, V>(node: &Option<Box<PatriciaTree<K, V>>>) -> usize { fn recurse<K: Copy, V>(node: &Option<Box<PatriciaTree<K, V>>>) -> usize {
match node { match node {
&Some(ref node) => { 1 + recurse(&node.child_l) + recurse(&node.child_r) } &Some(ref node) => { 1 + recurse(&node.child_l) + recurse(&node.child_r) }
&None => 0 &None => 0
@ -362,10 +362,12 @@ impl<K, V> PatriciaTree<K, V>
} }
} }
impl<K:BitArray, V:Debug> Debug for PatriciaTree<K, V> { impl<K: Copy + BitArray, V: Debug> Debug for PatriciaTree<K, V> {
/// Print the entire tree /// Print the entire tree
fn fmt<'a>(&'a self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn fmt<'a>(&'a self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
fn recurse<'a, K:BitArray, V:Debug>(tree: &'a PatriciaTree<K, V>, f: &mut fmt::Formatter, depth: usize) -> Result<(), fmt::Error> { fn recurse<'a, K, V>(tree: &'a PatriciaTree<K, V>, f: &mut fmt::Formatter, depth: usize) -> Result<(), fmt::Error>
where K: Copy + BitArray, V: Debug
{
for i in 0..tree.skip_len as usize { for i in 0..tree.skip_len as usize {
try!(write!(f, "{:}", if tree.skip_prefix.bit(i) { 1 } else { 0 })); try!(write!(f, "{:}", if tree.skip_prefix.bit(i) { 1 } else { 0 }));
} }
@ -400,7 +402,7 @@ impl<K:BitArray, V:Debug> Debug for PatriciaTree<K, V> {
impl<S, K, V> ConsensusEncodable<S> for PatriciaTree<K, V> impl<S, K, V> ConsensusEncodable<S> for PatriciaTree<K, V>
where S: SimpleEncoder, where S: SimpleEncoder,
K: ConsensusEncodable<S>, K: Copy + ConsensusEncodable<S>,
V: ConsensusEncodable<S> V: ConsensusEncodable<S>
{ {
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
@ -416,7 +418,7 @@ impl<S, K, V> ConsensusEncodable<S> for PatriciaTree<K, V>
impl<D, K, V> ConsensusDecodable<D> for PatriciaTree<K, V> impl<D, K, V> ConsensusDecodable<D> for PatriciaTree<K, V>
where D: SimpleDecoder, where D: SimpleDecoder,
K: ConsensusDecodable<D>, K: Copy + ConsensusDecodable<D>,
V: ConsensusDecodable<D> V: ConsensusDecodable<D>
{ {
fn consensus_decode(d: &mut D) -> Result<PatriciaTree<K, V>, D::Error> { fn consensus_decode(d: &mut D) -> Result<PatriciaTree<K, V>, D::Error> {
@ -431,25 +433,25 @@ impl<D, K, V> ConsensusDecodable<D> for PatriciaTree<K, V>
} }
/// Iterator /// Iterator
pub struct Items<'tree, K: 'tree, V: 'tree> { pub struct Items<'tree, K: Copy + 'tree, V: 'tree> {
started: bool, started: bool,
node: Option<&'tree PatriciaTree<K, V>>, node: Option<&'tree PatriciaTree<K, V>>,
parents: Vec<&'tree PatriciaTree<K, V>> parents: Vec<&'tree PatriciaTree<K, V>>
} }
/// Mutable iterator /// Mutable iterator
pub struct MutItems<'tree, K: 'tree, V: 'tree> { pub struct MutItems<'tree, K: Copy + 'tree, V: 'tree> {
started: bool, started: bool,
node: *mut PatriciaTree<K, V>, node: *mut PatriciaTree<K, V>,
parents: Vec<*mut PatriciaTree<K, V>>, parents: Vec<*mut PatriciaTree<K, V>>,
marker: marker::PhantomData<&'tree PatriciaTree<K, V>> marker: marker::PhantomData<&'tree PatriciaTree<K, V>>
} }
impl<'a, K, V> Iterator for Items<'a, K, V> { impl<'a, K: Copy, V> Iterator for Items<'a, K, V> {
type Item = &'a V; type Item = &'a V;
fn next(&mut self) -> Option<&'a V> { fn next(&mut self) -> Option<&'a V> {
fn borrow_opt<'a, K, V>(opt_ptr: &'a Option<Box<PatriciaTree<K, V>>>) -> Option<&'a PatriciaTree<K, V>> { fn borrow_opt<'a, K: Copy, V>(opt_ptr: &'a Option<Box<PatriciaTree<K, V>>>) -> Option<&'a PatriciaTree<K, V>> {
opt_ptr.as_ref().map(|b| &**b) opt_ptr.as_ref().map(|b| &**b)
} }
@ -491,11 +493,11 @@ impl<'a, K, V> Iterator for Items<'a, K, V> {
} }
} }
impl<'a, K, V> Iterator for MutItems<'a, K, V> { impl<'a, K: Copy, V> Iterator for MutItems<'a, K, V> {
type Item = &'a mut V; type Item = &'a mut V;
fn next(&mut self) -> Option<&'a mut V> { fn next(&mut self) -> Option<&'a mut V> {
fn borrow_opt<'a, K, V>(opt_ptr: &'a Option<Box<PatriciaTree<K, V>>>) -> *mut PatriciaTree<K, V> { fn borrow_opt<'a, K: Copy, V>(opt_ptr: &'a Option<Box<PatriciaTree<K, V>>>) -> *mut PatriciaTree<K, V> {
match *opt_ptr { match *opt_ptr {
Some(ref data) => &**data as *const _ as *mut _, Some(ref data) => &**data as *const _ as *mut _,
None => ptr::null_mut() None => ptr::null_mut()

View File

@ -51,7 +51,7 @@ impl Default for Fingerprint {
} }
/// Extended private key /// Extended private key
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub struct ExtendedPrivKey { pub struct ExtendedPrivKey {
/// The network this key is to be used on /// The network this key is to be used on
pub network: Network, pub network: Network,
@ -68,7 +68,7 @@ pub struct ExtendedPrivKey {
} }
/// Extended public key /// Extended public key
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub struct ExtendedPubKey { pub struct ExtendedPubKey {
/// The network this key is to be used on /// The network this key is to be used on
pub network: Network, pub network: Network,
@ -85,7 +85,7 @@ pub struct ExtendedPubKey {
} }
/// A child number for a derived key /// A child number for a derived key
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum ChildNumber { pub enum ChildNumber {
/// Hardened key index, within [0, 2^31 - 1] /// Hardened key index, within [0, 2^31 - 1]
Hardened(u32), Hardened(u32),
@ -292,9 +292,9 @@ impl ExtendedPubKey {
impl ToBase58 for ExtendedPrivKey { impl ToBase58 for ExtendedPrivKey {
fn base58_layout(&self) -> Vec<u8> { fn base58_layout(&self) -> Vec<u8> {
let mut ret = Vec::with_capacity(78); let mut ret = Vec::with_capacity(78);
ret.push_all(match self.network { ret.push_all(&match self.network {
Network::Bitcoin => &[0x04, 0x88, 0xAD, 0xE4], Network::Bitcoin => [0x04, 0x88, 0xAD, 0xE4],
Network::Testnet => &[0x04, 0x35, 0x83, 0x94] Network::Testnet => [0x04, 0x35, 0x83, 0x94]
}); });
ret.push(self.depth as u8); ret.push(self.depth as u8);
ret.push_all(&self.parent_fingerprint[..]); ret.push_all(&self.parent_fingerprint[..]);
@ -346,9 +346,9 @@ impl ToBase58 for ExtendedPubKey {
fn base58_layout(&self) -> Vec<u8> { fn base58_layout(&self) -> Vec<u8> {
assert!(self.public_key.is_compressed()); assert!(self.public_key.is_compressed());
let mut ret = Vec::with_capacity(78); let mut ret = Vec::with_capacity(78);
ret.push_all(match self.network { ret.push_all(&match self.network {
Network::Bitcoin => &[0x04u8, 0x88, 0xB2, 0x1E], Network::Bitcoin => [0x04u8, 0x88, 0xB2, 0x1E],
Network::Testnet => &[0x04u8, 0x35, 0x87, 0xCF] Network::Testnet => [0x04u8, 0x35, 0x87, 0xCF]
}); });
ret.push(self.depth as u8); ret.push(self.depth as u8);
ret.push_all(&self.parent_fingerprint[..]); ret.push_all(&self.parent_fingerprint[..]);
@ -510,21 +510,12 @@ mod tests {
#[test] #[test]
pub fn encode_decode_childnumber() { pub fn encode_decode_childnumber() {
use serialize::json; serde_round_trip!(Normal(0));
serde_round_trip!(Normal(1));
let h1 = Hardened(1); serde_round_trip!(Normal((1 << 31) - 1));
let n1 = Normal(1); serde_round_trip!(Hardened(0));
serde_round_trip!(Hardened(1));
let h1_str = json::encode(&h1); serde_round_trip!(Hardened((1 << 31) - 1));
let n1_str = json::encode(&n1);
assert!(h1 != n1);
assert!(h1_str != n1_str);
let h1_dec = json::decode(&h1_str).unwrap();
let n1_dec = json::decode(&n1_str).unwrap();
assert_eq!(h1, h1_dec);
assert_eq!(n1, n1_dec);
} }
#[bench] #[bench]