Checkpoint commit: into warnings!
This commit is contained in:
parent
1d78dccb9e
commit
3117f95b62
|
@ -32,7 +32,7 @@ use blockdata::transaction::Transaction;
|
|||
|
||||
/// A block header, which contains all the block's information except
|
||||
/// the actual transactions
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
#[derive(Copy, PartialEq, Eq, Clone, Debug)]
|
||||
pub struct BlockHeader {
|
||||
/// The protocol version. Should always be 1.
|
||||
pub version: u32,
|
||||
|
|
|
@ -34,7 +34,7 @@ use network::encodable::{ConsensusDecodable, ConsensusEncodable};
|
|||
// write an #[inline] helper function which casts to u8s.
|
||||
|
||||
/// A script Opcode
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
#[repr(u8)]
|
||||
pub enum All {
|
||||
/// 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;
|
||||
|
||||
/// Broad categories of opcodes with similar behavior
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum Class {
|
||||
/// Pushes the given number onto the stack
|
||||
PushNum(i32),
|
||||
|
@ -663,7 +663,7 @@ macro_rules! ordinary_opcode {
|
|||
($($op:ident),*) => (
|
||||
#[repr(u8)]
|
||||
#[doc(hidden)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum Ordinary {
|
||||
$( $op = All::$op as u8 ),*
|
||||
}
|
||||
|
|
|
@ -1628,10 +1628,10 @@ macro_rules! stack_opcode {
|
|||
macro_rules! num_opcode {
|
||||
($stack:ident($($var:ident),*): $op:expr) => ({
|
||||
$(
|
||||
let $var = try!(read_scriptint(match $stack.pop() {
|
||||
Some(elem) => &elem[..],
|
||||
let $var = try!(read_scriptint(&match $stack.pop() {
|
||||
Some(elem) => elem,
|
||||
None => { return Err(Error::PopEmptyStack); }
|
||||
}));
|
||||
}[..]));
|
||||
)*
|
||||
$stack.push(MaybeOwned::Owned(build_scriptint($op)));
|
||||
// Return a tuple of all the variables
|
||||
|
|
|
@ -153,16 +153,15 @@ pub struct TransactionTrace {
|
|||
impl TxIn {
|
||||
/// Check an input's script for validity
|
||||
pub fn validate(&self,
|
||||
utxoset: &UtxoSet,
|
||||
txn: &Transaction,
|
||||
index: usize) -> Result<(), Error> {
|
||||
utxoset: &UtxoSet,
|
||||
txn: &Transaction,
|
||||
index: usize) -> Result<(), Error> {
|
||||
let txo = utxoset.get_utxo(self.prev_hash, self.prev_index);
|
||||
match txo {
|
||||
Some((_, txo)) => {
|
||||
let mut p2sh_stack = Vec::new();
|
||||
let mut p2sh_script = Script::new();
|
||||
let (mut p2sh_stack, mut p2sh_script) = (vec![], Script::new());
|
||||
|
||||
let mut stack = Vec::with_capacity(6);
|
||||
let mut stack = vec![];
|
||||
match self.script_sig.evaluate(&mut stack, Some((txn, index)), None) {
|
||||
Ok(_) => {}
|
||||
Err(e) => { return Err(Error::InputScriptFailure(e)); }
|
||||
|
@ -220,7 +219,7 @@ impl Transaction {
|
|||
/// Produce a trace of a transaction's execution
|
||||
pub fn trace(&self, utxoset: &UtxoSet) -> TransactionTrace {
|
||||
let mut ret = TransactionTrace { txid: self.bitcoin_hash(),
|
||||
inputs: Vec::with_capacity(self.input.len()) };
|
||||
inputs: Vec::with_capacity(self.input.len()) };
|
||||
for (n, input) in self.input.iter().enumerate() {
|
||||
// Setup trace
|
||||
let mut trace = InputTrace {
|
||||
|
@ -240,8 +239,7 @@ impl Transaction {
|
|||
let txo = utxoset.get_utxo(input.prev_hash, input.prev_index);
|
||||
match txo {
|
||||
Some((_, txo)) => {
|
||||
let mut p2sh_stack = Vec::new();
|
||||
let mut p2sh_script = Script::new();
|
||||
let (mut p2sh_stack, mut p2sh_script) = (vec![], Script::new());
|
||||
|
||||
let mut stack = Vec::with_capacity(6);
|
||||
trace.sig_trace = input.script_sig.trace(&mut stack, Some((self, n)));
|
||||
|
|
|
@ -196,7 +196,7 @@ impl UtxoSet {
|
|||
};
|
||||
// Check that this specific output is there
|
||||
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()))
|
||||
}
|
||||
|
||||
|
@ -283,7 +283,7 @@ impl UtxoSet {
|
|||
// 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.
|
||||
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 last_err.is_err() { return last_err; }
|
||||
|
@ -292,7 +292,7 @@ impl UtxoSet {
|
|||
for tx in block.txdata.iter().skip(1) {
|
||||
let txid = tx.bitcoin_hash();
|
||||
// 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() {
|
||||
let taken = self.take_utxo(input.prev_hash, input.prev_index);
|
||||
match taken {
|
||||
|
|
|
@ -117,6 +117,8 @@ macro_rules! impl_array_newtype {
|
|||
}
|
||||
}
|
||||
|
||||
impl Copy for $thing {}
|
||||
|
||||
impl ::std::hash::Hash for $thing {
|
||||
#[inline]
|
||||
fn hash<H>(&self, state: &mut H)
|
||||
|
|
|
@ -56,9 +56,12 @@ extern crate rand;
|
|||
extern crate rustc_serialize as serialize;
|
||||
extern crate secp256k1;
|
||||
extern crate serde;
|
||||
extern crate test;
|
||||
#[cfg(test)] extern crate test;
|
||||
extern crate time;
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
mod test_macros;
|
||||
#[macro_use]
|
||||
mod internal_macros;
|
||||
#[macro_use]
|
||||
|
|
|
@ -22,7 +22,7 @@ use network::encodable::{ConsensusDecodable, ConsensusEncodable};
|
|||
use network::serialize::{SimpleEncoder, SimpleDecoder};
|
||||
|
||||
user_enum! {
|
||||
#[derive(PartialEq, Eq, Clone, Hash)]
|
||||
#[derive(Copy, PartialEq, Eq, Clone, Hash)]
|
||||
#[doc="The cryptocurrency to act on"]
|
||||
pub enum Network {
|
||||
#[doc="Classic Bitcoin"]
|
||||
|
|
|
@ -35,9 +35,9 @@ use util::{self, propagate_err};
|
|||
/// Format an IP address in the 16-byte bitcoin protocol serialization
|
||||
fn ipaddr_to_bitcoin_addr(ipaddr: &net::IpAddr) -> [u16; 8] {
|
||||
match *ipaddr {
|
||||
net::IpAddr::V4(ref addr) => &addr.to_ipv6_mapped(),
|
||||
net::IpAddr::V6(ref addr) => addr
|
||||
}.segments()
|
||||
net::IpAddr::V4(ref addr) => addr.to_ipv6_mapped().segments(),
|
||||
net::IpAddr::V6(ref addr) => addr.segments()
|
||||
}
|
||||
}
|
||||
|
||||
/// A network socket along with information about the peer
|
||||
|
@ -55,6 +55,31 @@ pub struct Socket {
|
|||
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 {
|
||||
// TODO: we fix services to 0
|
||||
/// Construct a new socket
|
||||
|
@ -85,55 +110,36 @@ 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
|
||||
pub fn receiver_address(&mut self) -> Result<Address, util::Error> {
|
||||
let sock = try!(self.socket());
|
||||
match sock.peer_addr() {
|
||||
Ok(addr) => {
|
||||
Ok(Address {
|
||||
services: self.services,
|
||||
address: ipaddr_to_bitcoin_addr(&addr.ip()),
|
||||
port: addr.port()
|
||||
})
|
||||
},
|
||||
Err(e) => Err(util::Error::Io(e))
|
||||
}
|
||||
with_socket!(self, sock, {
|
||||
match sock.peer_addr() {
|
||||
Ok(addr) => {
|
||||
Ok(Address {
|
||||
services: self.services,
|
||||
address: ipaddr_to_bitcoin_addr(&addr.ip()),
|
||||
port: addr.port()
|
||||
})
|
||||
},
|
||||
Err(e) => Err(util::Error::Io(e))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Our own address
|
||||
pub fn sender_address(&mut self) -> Result<Address, util::Error> {
|
||||
let sock = try!(self.socket());
|
||||
match sock.local_addr() {
|
||||
Ok(addr) => {
|
||||
Ok(Address {
|
||||
services: self.services,
|
||||
address: ipaddr_to_bitcoin_addr(&addr.ip()),
|
||||
port: addr.port()
|
||||
})
|
||||
},
|
||||
Err(e) => Err(util::Error::Io(e))
|
||||
}
|
||||
with_socket!(self, sock, {
|
||||
match sock.local_addr() {
|
||||
Ok(addr) => {
|
||||
Ok(Address {
|
||||
services: self.services,
|
||||
address: ipaddr_to_bitcoin_addr(&addr.ip()),
|
||||
port: addr.port()
|
||||
})
|
||||
},
|
||||
Err(e) => Err(util::Error::Io(e))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Produce a version message appropriate for this socket
|
||||
|
@ -157,35 +163,37 @@ impl Socket {
|
|||
|
||||
/// Send a general message across the line
|
||||
pub fn send_message(&mut self, payload: NetworkMessage) -> Result<(), util::Error> {
|
||||
let sock = try!(self.socket());
|
||||
let message = RawNetworkMessage { magic: self.magic, payload: payload };
|
||||
try!(message.consensus_encode(&mut RawEncoder::new(sock)));
|
||||
sock.flush().map_err(util::Error::Io)
|
||||
with_socket!(self, sock, {
|
||||
let message = RawNetworkMessage { magic: self.magic, payload: payload };
|
||||
try!(message.consensus_encode(&mut RawEncoder::new(&mut *sock)));
|
||||
sock.flush().map_err(util::Error::Io)
|
||||
})
|
||||
}
|
||||
|
||||
/// Receive the next message from the peer, decoding the network header
|
||||
/// and verifying its correctness. Returns the undecoded payload.
|
||||
pub fn receive_message(&mut self) -> Result<NetworkMessage, util::Error> {
|
||||
let sock = try!(self.socket());
|
||||
// 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.
|
||||
let mut decoder = RawDecoder::new(sock);
|
||||
let decode: Result<RawNetworkMessage, _> = ConsensusDecodable::consensus_decode(&mut decoder);
|
||||
match decode {
|
||||
// Check for parse errors...
|
||||
Err(e) => {
|
||||
propagate_err("receive_message".to_string(), Err(e))
|
||||
},
|
||||
Ok(ret) => {
|
||||
// Then for magic (this should come before parse error, but we can't
|
||||
// get to it if the deserialization failed). TODO restructure this
|
||||
if ret.magic != self.magic {
|
||||
Err(util::Error::BadNetworkMagic(self.magic, ret.magic))
|
||||
} else {
|
||||
Ok(ret.payload)
|
||||
with_socket!(self, sock, {
|
||||
// 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.
|
||||
let mut decoder = RawDecoder::new(sock);
|
||||
let decode: Result<RawNetworkMessage, _> = ConsensusDecodable::consensus_decode(&mut decoder);
|
||||
match decode {
|
||||
// Check for parse errors...
|
||||
Err(e) => {
|
||||
propagate_err("receive_message".to_string(), Err(e))
|
||||
},
|
||||
Ok(ret) => {
|
||||
// Then for magic (this should come before parse error, but we can't
|
||||
// get to it if the deserialization failed). TODO restructure this
|
||||
if ret.magic != self.magic {
|
||||
Err(util::Error::BadNetworkMagic(self.magic, ret.magic))
|
||||
} else {
|
||||
Ok(ret.payload)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,15 +48,15 @@ pub struct Ripemd160Hash([u8; 20]);
|
|||
impl_array_newtype!(Ripemd160Hash, u8, 20);
|
||||
|
||||
/// 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));
|
||||
|
||||
/// 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));
|
||||
|
||||
/// 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));
|
||||
|
||||
impl Ripemd160Hash {
|
||||
|
@ -268,8 +268,7 @@ mod tests {
|
|||
use std::io::Cursor;
|
||||
use std::num::FromPrimitive;
|
||||
use std::str::from_utf8;
|
||||
use serialize::Encodable;
|
||||
use serialize::json;
|
||||
use serde::{json, Serialize, Deserialize};
|
||||
|
||||
use network::serialize::{serialize, deserialize};
|
||||
use util::hash::Sha256dHash;
|
||||
|
@ -296,15 +295,15 @@ mod tests {
|
|||
#[test]
|
||||
fn test_hash_encode_decode() {
|
||||
let hash = Sha256dHash::from_data(&[]);
|
||||
let mut writer = Cursor::new(vec![]);
|
||||
let mut writer = vec![];
|
||||
{
|
||||
let mut encoder = json::Encoder::new(&mut writer);
|
||||
assert!(hash.encode(&mut encoder).is_ok());
|
||||
let mut serializer = json::ser::Serializer::new(&mut writer);
|
||||
assert!(hash.serialize(&mut serializer).is_ok());
|
||||
}
|
||||
let res = writer.into_inner();
|
||||
assert_eq!(&res[..],
|
||||
assert_eq!(&writer[..],
|
||||
"\"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]
|
||||
|
|
|
@ -25,7 +25,7 @@ pub fn hex_bytes(s: &str) -> Result<Vec<u8>, Error> {
|
|||
let mut v = vec![];
|
||||
let mut iter = s.chars().pair();
|
||||
// Do the parsing
|
||||
try!(iter.fold(Ok(()), |e, (f, s)|
|
||||
try!(iter.by_ref().fold(Ok(()), |e, (f, s)|
|
||||
if e.is_err() { e }
|
||||
else {
|
||||
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;
|
||||
while i <= top {
|
||||
if &haystack[i..(i + needle.len())] == needle {
|
||||
let v = &mut haystack;
|
||||
for j in i..top {
|
||||
v.swap(j + needle.len(), j);
|
||||
haystack.swap(j + needle.len(), j);
|
||||
}
|
||||
n_deleted += 1;
|
||||
// This is ugly but prevents infinite loop in case of overflow
|
||||
|
|
|
@ -30,7 +30,7 @@ use network::serialize::{SimpleDecoder, SimpleEncoder};
|
|||
use util::BitArray;
|
||||
|
||||
/// Patricia troo
|
||||
pub struct PatriciaTree<K, V> {
|
||||
pub struct PatriciaTree<K: Copy, V> {
|
||||
data: Option<V>,
|
||||
child_l: 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>
|
||||
where K: BitArray + cmp::Eq + Zero + One +
|
||||
where K: Copy + BitArray + cmp::Eq + Zero + One +
|
||||
ops::BitXor<K, Output=K> +
|
||||
ops::Add<K, 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
|
||||
/// 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>)
|
||||
where K: BitArray + cmp::Eq + Zero + One +
|
||||
where K: Copy + BitArray + cmp::Eq + Zero + One +
|
||||
ops::Add<K, Output=K> +
|
||||
ops::Shr<usize, Output=K> +
|
||||
ops::Shl<usize, Output=K>
|
||||
|
@ -333,7 +333,7 @@ impl<K, V> PatriciaTree<K, V>
|
|||
|
||||
/// Count all the nodes
|
||||
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 {
|
||||
&Some(ref node) => { 1 + recurse(&node.child_l) + recurse(&node.child_r) }
|
||||
&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
|
||||
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 {
|
||||
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>
|
||||
where S: SimpleEncoder,
|
||||
K: ConsensusEncodable<S>,
|
||||
K: Copy + ConsensusEncodable<S>,
|
||||
V: ConsensusEncodable<S>
|
||||
{
|
||||
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>
|
||||
where D: SimpleDecoder,
|
||||
K: ConsensusDecodable<D>,
|
||||
K: Copy + ConsensusDecodable<D>,
|
||||
V: ConsensusDecodable<D>
|
||||
{
|
||||
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
|
||||
pub struct Items<'tree, K: 'tree, V: 'tree> {
|
||||
pub struct Items<'tree, K: Copy + 'tree, V: 'tree> {
|
||||
started: bool,
|
||||
node: Option<&'tree PatriciaTree<K, V>>,
|
||||
parents: Vec<&'tree PatriciaTree<K, V>>
|
||||
}
|
||||
|
||||
/// Mutable iterator
|
||||
pub struct MutItems<'tree, K: 'tree, V: 'tree> {
|
||||
pub struct MutItems<'tree, K: Copy + 'tree, V: 'tree> {
|
||||
started: bool,
|
||||
node: *mut PatriciaTree<K, V>,
|
||||
parents: Vec<*mut 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;
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
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 {
|
||||
Some(ref data) => &**data as *const _ as *mut _,
|
||||
None => ptr::null_mut()
|
||||
|
|
|
@ -51,7 +51,7 @@ impl Default for Fingerprint {
|
|||
}
|
||||
|
||||
/// Extended private key
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
||||
pub struct ExtendedPrivKey {
|
||||
/// The network this key is to be used on
|
||||
pub network: Network,
|
||||
|
@ -68,7 +68,7 @@ pub struct ExtendedPrivKey {
|
|||
}
|
||||
|
||||
/// Extended public key
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
||||
pub struct ExtendedPubKey {
|
||||
/// The network this key is to be used on
|
||||
pub network: Network,
|
||||
|
@ -85,7 +85,7 @@ pub struct ExtendedPubKey {
|
|||
}
|
||||
|
||||
/// A child number for a derived key
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum ChildNumber {
|
||||
/// Hardened key index, within [0, 2^31 - 1]
|
||||
Hardened(u32),
|
||||
|
@ -292,9 +292,9 @@ impl ExtendedPubKey {
|
|||
impl ToBase58 for ExtendedPrivKey {
|
||||
fn base58_layout(&self) -> Vec<u8> {
|
||||
let mut ret = Vec::with_capacity(78);
|
||||
ret.push_all(match self.network {
|
||||
Network::Bitcoin => &[0x04, 0x88, 0xAD, 0xE4],
|
||||
Network::Testnet => &[0x04, 0x35, 0x83, 0x94]
|
||||
ret.push_all(&match self.network {
|
||||
Network::Bitcoin => [0x04, 0x88, 0xAD, 0xE4],
|
||||
Network::Testnet => [0x04, 0x35, 0x83, 0x94]
|
||||
});
|
||||
ret.push(self.depth as u8);
|
||||
ret.push_all(&self.parent_fingerprint[..]);
|
||||
|
@ -346,9 +346,9 @@ impl ToBase58 for ExtendedPubKey {
|
|||
fn base58_layout(&self) -> Vec<u8> {
|
||||
assert!(self.public_key.is_compressed());
|
||||
let mut ret = Vec::with_capacity(78);
|
||||
ret.push_all(match self.network {
|
||||
Network::Bitcoin => &[0x04u8, 0x88, 0xB2, 0x1E],
|
||||
Network::Testnet => &[0x04u8, 0x35, 0x87, 0xCF]
|
||||
ret.push_all(&match self.network {
|
||||
Network::Bitcoin => [0x04u8, 0x88, 0xB2, 0x1E],
|
||||
Network::Testnet => [0x04u8, 0x35, 0x87, 0xCF]
|
||||
});
|
||||
ret.push(self.depth as u8);
|
||||
ret.push_all(&self.parent_fingerprint[..]);
|
||||
|
@ -510,21 +510,12 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
pub fn encode_decode_childnumber() {
|
||||
use serialize::json;
|
||||
|
||||
let h1 = Hardened(1);
|
||||
let n1 = Normal(1);
|
||||
|
||||
let h1_str = json::encode(&h1);
|
||||
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);
|
||||
serde_round_trip!(Normal(0));
|
||||
serde_round_trip!(Normal(1));
|
||||
serde_round_trip!(Normal((1 << 31) - 1));
|
||||
serde_round_trip!(Hardened(0));
|
||||
serde_round_trip!(Hardened(1));
|
||||
serde_round_trip!(Hardened((1 << 31) - 1));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
Loading…
Reference in New Issue