Many syntax changes for rustc, incomplete

This commit is contained in:
Andrew Poelstra 2015-01-18 12:16:01 -06:00
parent 97bfbe790b
commit c3377032f8
31 changed files with 621 additions and 602 deletions

View File

@ -79,7 +79,7 @@ impl BlockHeader {
let (mant, expt) = { let (mant, expt) = {
let unshifted_expt = self.bits >> 24; let unshifted_expt = self.bits >> 24;
if unshifted_expt <= 3 { if unshifted_expt <= 3 {
((self.bits & 0xFFFFFF) >> 8 * (3 - unshifted_expt as uint), 0) ((self.bits & 0xFFFFFF) >> 8 * (3 - unshifted_expt as usize), 0)
} else { } else {
(self.bits & 0xFFFFFF, 8 * ((self.bits >> 24) - 3)) (self.bits & 0xFFFFFF, 8 * ((self.bits >> 24) - 3))
} }
@ -89,7 +89,7 @@ impl BlockHeader {
if mant > 0x7FFFFF { if mant > 0x7FFFFF {
Zero::zero() Zero::zero()
} else { } else {
from_u64::<Uint256>(mant as u64).unwrap() << (expt as uint) from_u64::<Uint256>(mant as u64).unwrap() << (expt as usize)
} }
} }
@ -130,10 +130,10 @@ impl BitcoinHash for Block {
} }
} }
impl_consensus_encoding!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce) impl_consensus_encoding!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce);
impl_json!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce) impl_json!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce);
impl_consensus_encoding!(Block, header, txdata) impl_consensus_encoding!(Block, header, txdata);
impl_consensus_encoding!(LoneBlockHeader, header, tx_count) impl_consensus_encoding!(LoneBlockHeader, header, tx_count);
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View File

@ -193,8 +193,8 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Blockchain {
// with a ContravariantLifetime marker tying it to the tree's lifetime. // with a ContravariantLifetime marker tying it to the tree's lifetime.
struct LocatorHashIter { struct LocatorHashIter {
index: NodePtr, index: NodePtr,
count: uint, count: usize,
skip: uint skip: usize
} }
impl LocatorHashIter { impl LocatorHashIter {
@ -341,7 +341,7 @@ impl Blockchain {
pub fn new(network: Network) -> Blockchain { pub fn new(network: Network) -> Blockchain {
let genesis = genesis_block(network); let genesis = genesis_block(network);
let genhash = genesis.header.bitcoin_hash(); let genhash = genesis.header.bitcoin_hash();
let new_node = box BlockchainNode { let new_node = Box::new(BlockchainNode {
total_work: Zero::zero(), total_work: Zero::zero(),
required_difficulty: genesis.header.target(), required_difficulty: genesis.header.target(),
block: genesis, block: genesis,
@ -349,7 +349,7 @@ impl Blockchain {
has_txdata: true, has_txdata: true,
prev: RawPtr::null(), prev: RawPtr::null(),
next: RawPtr::null() next: RawPtr::null()
}; });
let raw_ptr = &*new_node as NodePtr; let raw_ptr = &*new_node as NodePtr;
Blockchain { Blockchain {
network: network, network: network,
@ -490,7 +490,7 @@ impl Blockchain {
unsafe { (*prev).required_difficulty } unsafe { (*prev).required_difficulty }
}; };
// Create node // Create node
let ret = box BlockchainNode { let ret = Box::new(BlockchainNode {
total_work: block.header.work().add(unsafe { &(*prev).total_work }), total_work: block.header.work().add(unsafe { &(*prev).total_work }),
block: block, block: block,
required_difficulty: difficulty, required_difficulty: difficulty,
@ -498,7 +498,7 @@ impl Blockchain {
has_txdata: has_txdata, has_txdata: has_txdata,
prev: prev, prev: prev,
next: RawPtr::null() next: RawPtr::null()
}; });
unsafe { unsafe {
let prev = prev as *mut BlockchainNode; let prev = prev as *mut BlockchainNode;
(*prev).next = &*ret as NodePtr; (*prev).next = &*ret as NodePtr;

View File

@ -39,7 +39,7 @@ pub static DIFFCHANGE_TIMESPAN: u32 = 14 * 24 * 3600;
/// In Bitcoind this is insanely described as ~((u256)0 >> 32) /// In Bitcoind this is insanely described as ~((u256)0 >> 32)
pub fn max_target(_: Network) -> Uint256 { pub fn max_target(_: Network) -> Uint256 {
from_u64::<Uint256>(0xFFFF).unwrap() << 208u from_u64::<Uint256>(0xFFFF).unwrap() << 208
} }
/// The maximum value allowed in an output (useful for sanity checking, /// The maximum value allowed in an output (useful for sanity checking,

View File

@ -594,10 +594,10 @@ pub mod all {
super::PushNum(-1) super::PushNum(-1)
// 16 opcodes // 16 opcodes
} else if OP_PUSHNUM_1 as u8 <= *self as u8 && *self as u8 <= OP_PUSHNUM_16 as u8 { } else if OP_PUSHNUM_1 as u8 <= *self as u8 && *self as u8 <= OP_PUSHNUM_16 as u8 {
super::PushNum(1 + *self as int - OP_PUSHNUM_1 as int) super::PushNum(1 + *self as isize - OP_PUSHNUM_1 as isize)
// 76 opcodes // 76 opcodes
} else if *self as u8 <= OP_PUSHBYTES_75 as u8 { } else if *self as u8 <= OP_PUSHBYTES_75 as u8 {
super::PushBytes(*self as uint) super::PushBytes(*self as usize)
// 60 opcodes // 60 opcodes
} else { } else {
super::Ordinary(unsafe { transmute(*self) }) super::Ordinary(unsafe { transmute(*self) })
@ -635,9 +635,9 @@ pub mod all {
#[deriving(Clone, PartialEq, Eq, Show)] #[deriving(Clone, PartialEq, Eq, Show)]
pub enum OpcodeClass { pub enum OpcodeClass {
/// Pushes the given number onto the stack /// Pushes the given number onto the stack
PushNum(int), PushNum(isize),
/// Pushes the given number of bytes onto the stack /// Pushes the given number of bytes onto the stack
PushBytes(uint), PushBytes(usize),
/// Fails the script if executed /// Fails the script if executed
ReturnOp, ReturnOp,
/// Fails the script even if not executed /// Fails the script even if not executed
@ -654,7 +654,7 @@ impl json::ToJson for OpcodeClass {
} }
} }
macro_rules! ordinary_opcode( macro_rules! ordinary_opcode {
($($op:ident),*) => ( ($($op:ident),*) => (
#[repr(u8)] #[repr(u8)]
#[doc(hidden)] #[doc(hidden)]
@ -663,10 +663,10 @@ macro_rules! ordinary_opcode(
$( $op = all::$op as u8 ),* $( $op = all::$op as u8 ),*
} }
); );
) }
/// "Ordinary" opcodes -- should be 60 of these /// "Ordinary" opcodes -- should be 60 of these
ordinary_opcode!( ordinary_opcode! {
// pushdata // pushdata
OP_PUSHDATA1, OP_PUSHDATA2, OP_PUSHDATA4, OP_PUSHDATA1, OP_PUSHDATA2, OP_PUSHDATA4,
// control flow // control flow
@ -688,6 +688,6 @@ ordinary_opcode!(
OP_RIPEMD160, OP_SHA1, OP_SHA256, OP_HASH160, OP_HASH256, OP_RIPEMD160, OP_SHA1, OP_SHA256, OP_HASH160, OP_HASH256,
OP_CODESEPARATOR, OP_CHECKSIG, OP_CHECKSIGVERIFY, OP_CODESEPARATOR, OP_CHECKSIG, OP_CHECKSIGVERIFY,
OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY
) }

View File

@ -98,9 +98,9 @@ pub enum ScriptError {
/// An OP_RETURN or synonym was executed /// An OP_RETURN or synonym was executed
ExecutedReturn, ExecutedReturn,
/// A multisig tx with negative or too many keys /// A multisig tx with negative or too many keys
MultisigBadKeyCount(int), MultisigBadKeyCount(isize),
/// A multisig tx with negative or too many signatures /// A multisig tx with negative or too many signatures
MultisigBadSigCount(int), MultisigBadSigCount(isize),
/// Used OP_PICK with a negative index /// Used OP_PICK with a negative index
NegativePick, NegativePick,
/// Used OP_ROLL with a negative index /// Used OP_ROLL with a negative index
@ -126,15 +126,15 @@ pub enum ScriptError {
/// A rule for validating an abstract stack element /// A rule for validating an abstract stack element
pub struct Validator { pub struct Validator {
/// List of other elements to pass to both `check` and `update` /// List of other elements to pass to both `check` and `update`
args: Vec<uint>, args: Vec<usize>,
/// Function which confirms that the current value is consistent with /// Function which confirms that the current value is consistent with
/// the stack state, returning `false` if not. /// the stack state, returning `false` if not.
check: fn(&AbstractStackElem, &[uint]) -> bool, check: fn(&AbstractStackElem, &[usize]) -> bool,
/// Function which updates the current stack based on the element's /// Function which updates the current stack based on the element's
/// value, if it has a value, otherwise updates the element's value /// value, if it has a value, otherwise updates the element's value
/// based on the current stack, if possible. Returns `false` if it /// based on the current stack, if possible. Returns `false` if it
/// is forced to do something inconsistent. /// is forced to do something inconsistent.
update: fn(&mut AbstractStackElem, &[uint]) -> Result<(), ScriptError> update: fn(&mut AbstractStackElem, &[usize]) -> Result<(), ScriptError>
} }
impl Clone for Validator { impl Clone for Validator {
@ -148,13 +148,13 @@ impl Clone for Validator {
} }
// Validators // Validators
fn check_op_size(elem: &AbstractStackElem, others: &[uint]) -> bool { fn check_op_size(elem: &AbstractStackElem, others: &[usize]) -> bool {
let other = unsafe { elem.lookup(others[0]) }; let other = unsafe { elem.lookup(others[0]) };
elem.num_hi() >= other.len_lo() as i64 && elem.num_hi() >= other.len_lo() as i64 &&
elem.num_lo() <= other.len_hi() as i64 elem.num_lo() <= other.len_hi() as i64
} }
fn update_op_size(elem: &mut AbstractStackElem, others: &[uint]) fn update_op_size(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
let (lo, hi) = { let (lo, hi) = {
let one = unsafe { elem.lookup(others[0]) }; let one = unsafe { elem.lookup(others[0]) };
@ -165,7 +165,7 @@ fn update_op_size(elem: &mut AbstractStackElem, others: &[uint])
elem.set_num_hi(hi) elem.set_num_hi(hi)
} }
fn check_op_equal(elem: &AbstractStackElem, others: &[uint]) -> bool { fn check_op_equal(elem: &AbstractStackElem, others: &[usize]) -> bool {
let one = unsafe { elem.lookup(others[0]) }; let one = unsafe { elem.lookup(others[0]) };
let two = unsafe { elem.lookup(others[1]) }; let two = unsafe { elem.lookup(others[1]) };
match elem.bool_value() { match elem.bool_value() {
@ -207,7 +207,7 @@ fn update_boolean(elem: &mut AbstractStackElem)
} }
} }
fn update_op_equal(elem: &mut AbstractStackElem, others: &[uint]) fn update_op_equal(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
match elem.bool_value() { match elem.bool_value() {
None => update_boolean(elem), None => update_boolean(elem),
@ -240,8 +240,8 @@ fn update_op_equal(elem: &mut AbstractStackElem, others: &[uint])
(Some(_), Some(_)) => { return Err(Unsatisfiable); } (Some(_), Some(_)) => { return Err(Unsatisfiable); }
} }
// Equalize full values // Equalize full values
match (one.raw_value().map(|r| Vec::from_slice(r)), match (one.raw_value().map(|r| r.to_vec()),
two.raw_value().map(|r| Vec::from_slice(r))) { two.raw_value().map(|r| r.to_vec())) {
(None, None) => {}, (None, None) => {},
(None, Some(x)) => try!(one.set_value(x.as_slice())), (None, Some(x)) => try!(one.set_value(x.as_slice())),
(Some(x), None) => try!(two.set_value(x.as_slice())), (Some(x), None) => try!(two.set_value(x.as_slice())),
@ -252,7 +252,7 @@ fn update_op_equal(elem: &mut AbstractStackElem, others: &[uint])
} }
} }
fn check_op_not(elem: &AbstractStackElem, others: &[uint]) -> bool { fn check_op_not(elem: &AbstractStackElem, others: &[usize]) -> bool {
let one = unsafe { elem.lookup(others[0]) }; let one = unsafe { elem.lookup(others[0]) };
if !one.may_be_numeric() { if !one.may_be_numeric() {
return false; return false;
@ -265,7 +265,7 @@ fn check_op_not(elem: &AbstractStackElem, others: &[uint]) -> bool {
} }
} }
fn update_op_not(elem: &mut AbstractStackElem, others: &[uint]) fn update_op_not(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
match elem.bool_value() { match elem.bool_value() {
None => update_boolean(elem), None => update_boolean(elem),
@ -290,7 +290,7 @@ fn update_op_not(elem: &mut AbstractStackElem, others: &[uint])
} }
} }
fn check_op_0notequal(elem: &AbstractStackElem, others: &[uint]) -> bool { fn check_op_0notequal(elem: &AbstractStackElem, others: &[usize]) -> bool {
let one = unsafe { elem.lookup(others[0]) }; let one = unsafe { elem.lookup(others[0]) };
if !one.may_be_numeric() { return false; } if !one.may_be_numeric() { return false; }
match elem.bool_value() { match elem.bool_value() {
@ -300,7 +300,7 @@ fn check_op_0notequal(elem: &AbstractStackElem, others: &[uint]) -> bool {
} }
} }
fn update_op_0notequal(elem: &mut AbstractStackElem, others: &[uint]) fn update_op_0notequal(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
match elem.bool_value() { match elem.bool_value() {
None => update_boolean(elem), None => update_boolean(elem),
@ -325,7 +325,7 @@ fn update_op_0notequal(elem: &mut AbstractStackElem, others: &[uint])
} }
} }
fn check_op_numequal(elem: &AbstractStackElem, others: &[uint]) -> bool { fn check_op_numequal(elem: &AbstractStackElem, others: &[usize]) -> bool {
let one = unsafe { elem.lookup(others[0]) }; let one = unsafe { elem.lookup(others[0]) };
let two = unsafe { elem.lookup(others[1]) }; let two = unsafe { elem.lookup(others[1]) };
if !one.may_be_numeric() { return false; } if !one.may_be_numeric() { return false; }
@ -349,7 +349,7 @@ fn check_op_numequal(elem: &AbstractStackElem, others: &[uint]) -> bool {
} }
} }
fn update_op_numequal(elem: &mut AbstractStackElem, others: &[uint]) fn update_op_numequal(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
match elem.bool_value() { match elem.bool_value() {
None => update_boolean(elem), None => update_boolean(elem),
@ -370,7 +370,7 @@ fn update_op_numequal(elem: &mut AbstractStackElem, others: &[uint])
} }
} }
fn check_op_numnotequal(elem: &AbstractStackElem, others: &[uint]) -> bool { fn check_op_numnotequal(elem: &AbstractStackElem, others: &[usize]) -> bool {
let one = unsafe { elem.lookup(others[0]) }; let one = unsafe { elem.lookup(others[0]) };
let two = unsafe { elem.lookup(others[1]) }; let two = unsafe { elem.lookup(others[1]) };
if !one.may_be_numeric() { return false; } if !one.may_be_numeric() { return false; }
@ -382,7 +382,7 @@ fn check_op_numnotequal(elem: &AbstractStackElem, others: &[uint]) -> bool {
} }
} }
fn update_op_numnotequal(elem: &mut AbstractStackElem, others: &[uint]) fn update_op_numnotequal(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
match elem.bool_value() { match elem.bool_value() {
None => update_boolean(elem), None => update_boolean(elem),
@ -403,7 +403,7 @@ fn update_op_numnotequal(elem: &mut AbstractStackElem, others: &[uint])
} }
} }
fn check_op_numlt(elem: &AbstractStackElem, others: &[uint]) -> bool { fn check_op_numlt(elem: &AbstractStackElem, others: &[usize]) -> bool {
let one = unsafe { elem.lookup(others[0]) }; let one = unsafe { elem.lookup(others[0]) };
let two = unsafe { elem.lookup(others[1]) }; let two = unsafe { elem.lookup(others[1]) };
if !one.may_be_numeric() { return false; } if !one.may_be_numeric() { return false; }
@ -415,7 +415,7 @@ fn check_op_numlt(elem: &AbstractStackElem, others: &[uint]) -> bool {
} }
} }
fn update_op_numlt(elem: &mut AbstractStackElem, others: &[uint]) fn update_op_numlt(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
match elem.bool_value() { match elem.bool_value() {
None => update_boolean(elem), None => update_boolean(elem),
@ -440,7 +440,7 @@ fn update_op_numlt(elem: &mut AbstractStackElem, others: &[uint])
} }
} }
fn check_op_numgt(elem: &AbstractStackElem, others: &[uint]) -> bool { fn check_op_numgt(elem: &AbstractStackElem, others: &[usize]) -> bool {
let one = unsafe { elem.lookup(others[0]) }; let one = unsafe { elem.lookup(others[0]) };
let two = unsafe { elem.lookup(others[1]) }; let two = unsafe { elem.lookup(others[1]) };
if !one.may_be_numeric() { return false; } if !one.may_be_numeric() { return false; }
@ -452,7 +452,7 @@ fn check_op_numgt(elem: &AbstractStackElem, others: &[uint]) -> bool {
} }
} }
fn update_op_numgt(elem: &mut AbstractStackElem, others: &[uint]) fn update_op_numgt(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
match elem.bool_value() { match elem.bool_value() {
None => try!(update_boolean(elem)), None => try!(update_boolean(elem)),
@ -478,7 +478,7 @@ fn update_op_numgt(elem: &mut AbstractStackElem, others: &[uint])
Ok(()) Ok(())
} }
fn check_op_numlteq(elem: &AbstractStackElem, others: &[uint]) -> bool { fn check_op_numlteq(elem: &AbstractStackElem, others: &[usize]) -> bool {
let one = unsafe { elem.lookup(others[0]) }; let one = unsafe { elem.lookup(others[0]) };
let two = unsafe { elem.lookup(others[1]) }; let two = unsafe { elem.lookup(others[1]) };
if !one.may_be_numeric() { return false; } if !one.may_be_numeric() { return false; }
@ -490,7 +490,7 @@ fn check_op_numlteq(elem: &AbstractStackElem, others: &[uint]) -> bool {
} }
} }
fn update_op_numlteq(elem: &mut AbstractStackElem, others: &[uint]) fn update_op_numlteq(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
match elem.bool_value() { match elem.bool_value() {
None => try!(update_boolean(elem)), None => try!(update_boolean(elem)),
@ -516,7 +516,7 @@ fn update_op_numlteq(elem: &mut AbstractStackElem, others: &[uint])
Ok(()) Ok(())
} }
fn check_op_numgteq(elem: &AbstractStackElem, others: &[uint]) -> bool { fn check_op_numgteq(elem: &AbstractStackElem, others: &[usize]) -> bool {
let one = unsafe { elem.lookup(others[0]) }; let one = unsafe { elem.lookup(others[0]) };
let two = unsafe { elem.lookup(others[1]) }; let two = unsafe { elem.lookup(others[1]) };
if !one.may_be_numeric() { return false; } if !one.may_be_numeric() { return false; }
@ -528,7 +528,7 @@ fn check_op_numgteq(elem: &AbstractStackElem, others: &[uint]) -> bool {
} }
} }
fn update_op_numgteq(elem: &mut AbstractStackElem, others: &[uint]) fn update_op_numgteq(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
match elem.bool_value() { match elem.bool_value() {
None => try!(update_boolean(elem)), None => try!(update_boolean(elem)),
@ -554,11 +554,11 @@ fn update_op_numgteq(elem: &mut AbstractStackElem, others: &[uint])
Ok(()) Ok(())
} }
fn check_op_ripemd160(elem: &AbstractStackElem, _: &[uint]) -> bool { fn check_op_ripemd160(elem: &AbstractStackElem, _: &[usize]) -> bool {
elem.may_be_hash160() elem.may_be_hash160()
} }
fn update_op_ripemd160(elem: &mut AbstractStackElem, others: &[uint]) fn update_op_ripemd160(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
try!(elem.set_len_lo(20)); try!(elem.set_len_lo(20));
try!(elem.set_len_hi(20)); try!(elem.set_len_hi(20));
@ -580,11 +580,11 @@ fn update_op_ripemd160(elem: &mut AbstractStackElem, others: &[uint])
} }
} }
fn check_op_sha1(elem: &AbstractStackElem, _: &[uint]) -> bool { fn check_op_sha1(elem: &AbstractStackElem, _: &[usize]) -> bool {
elem.may_be_hash160() elem.may_be_hash160()
} }
fn update_op_sha1(elem: &mut AbstractStackElem, others: &[uint]) fn update_op_sha1(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
try!(elem.set_len_lo(20)); try!(elem.set_len_lo(20));
try!(elem.set_len_hi(20)); try!(elem.set_len_hi(20));
@ -606,11 +606,11 @@ fn update_op_sha1(elem: &mut AbstractStackElem, others: &[uint])
} }
} }
fn check_op_hash160(elem: &AbstractStackElem, _: &[uint]) -> bool { fn check_op_hash160(elem: &AbstractStackElem, _: &[usize]) -> bool {
elem.may_be_hash160() elem.may_be_hash160()
} }
fn update_op_hash160(elem: &mut AbstractStackElem, others: &[uint]) fn update_op_hash160(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
try!(elem.set_len_lo(20)); try!(elem.set_len_lo(20));
try!(elem.set_len_hi(20)); try!(elem.set_len_hi(20));
@ -636,11 +636,11 @@ fn update_op_hash160(elem: &mut AbstractStackElem, others: &[uint])
} }
} }
fn check_op_sha256(elem: &AbstractStackElem, _: &[uint]) -> bool { fn check_op_sha256(elem: &AbstractStackElem, _: &[usize]) -> bool {
elem.may_be_hash256() elem.may_be_hash256()
} }
fn update_op_sha256(elem: &mut AbstractStackElem, others: &[uint]) fn update_op_sha256(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
try!(elem.set_len_lo(32)); try!(elem.set_len_lo(32));
try!(elem.set_len_hi(32)); try!(elem.set_len_hi(32));
@ -662,11 +662,11 @@ fn update_op_sha256(elem: &mut AbstractStackElem, others: &[uint])
} }
} }
fn check_op_hash256(elem: &AbstractStackElem, _: &[uint]) -> bool { fn check_op_hash256(elem: &AbstractStackElem, _: &[usize]) -> bool {
elem.may_be_hash256() elem.may_be_hash256()
} }
fn update_op_hash256(elem: &mut AbstractStackElem, others: &[uint]) fn update_op_hash256(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
try!(elem.set_len_lo(32)); try!(elem.set_len_lo(32));
try!(elem.set_len_hi(32)); try!(elem.set_len_hi(32));
@ -691,7 +691,7 @@ fn update_op_hash256(elem: &mut AbstractStackElem, others: &[uint])
} }
} }
fn check_op_checksig(elem: &AbstractStackElem, others: &[uint]) -> bool { fn check_op_checksig(elem: &AbstractStackElem, others: &[usize]) -> bool {
let one = unsafe { elem.lookup(others[0]) }; let one = unsafe { elem.lookup(others[0]) };
let two = unsafe { elem.lookup(others[1]) }; let two = unsafe { elem.lookup(others[1]) };
match elem.bool_value() { match elem.bool_value() {
@ -701,7 +701,7 @@ fn check_op_checksig(elem: &AbstractStackElem, others: &[uint]) -> bool {
} }
} }
fn update_op_checksig(elem: &mut AbstractStackElem, others: &[uint]) fn update_op_checksig(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
match elem.bool_value() { match elem.bool_value() {
None => update_boolean(elem), None => update_boolean(elem),
@ -732,13 +732,13 @@ pub struct AbstractStackElem {
/// Upper bound when read as number /// Upper bound when read as number
num_hi: i64, num_hi: i64,
/// Length lower bound /// Length lower bound
len_lo: uint, len_lo: usize,
/// Length upper bound /// Length upper bound
len_hi: uint, len_hi: usize,
/// Relations this must satisfy /// Relations this must satisfy
validators: Vec<Validator>, validators: Vec<Validator>,
/// Index of the element in its stack allocator /// Index of the element in its stack allocator
alloc_index: Option<uint> alloc_index: Option<usize>
} }
impl AbstractStackElem { impl AbstractStackElem {
@ -771,7 +771,7 @@ impl AbstractStackElem {
len_lo: data.len(), len_lo: data.len(),
len_hi: data.len(), len_hi: data.len(),
bool_val: Some(read_scriptbool(data)), bool_val: Some(read_scriptbool(data)),
raw: Some(Vec::from_slice(data)), raw: Some(data.to_vec()),
validators: vec![], validators: vec![],
alloc_index: None alloc_index: None
} }
@ -792,17 +792,17 @@ impl AbstractStackElem {
} }
/// Looks up another stack item by index /// Looks up another stack item by index
unsafe fn lookup<'a>(&'a self, idx: uint) -> &'a AbstractStackElem { unsafe fn lookup<'a>(&'a self, idx: usize) -> &'a AbstractStackElem {
let mypos = self as *const _; let mypos = self as *const _;
let myidx = self.alloc_index.unwrap() as int; let myidx = self.alloc_index.unwrap() as isize;
&*mypos.offset(idx as int - myidx) &*mypos.offset(idx as isize - myidx)
} }
/// Looks up another stack item by index /// Looks up another stack item by index
unsafe fn lookup_mut<'a>(&'a self, idx: uint) -> &'a mut AbstractStackElem { unsafe fn lookup_mut<'a>(&'a self, idx: usize) -> &'a mut AbstractStackElem {
let mypos = self as *const _ as *mut _; let mypos = self as *const _ as *mut _;
let myidx = self.alloc_index.unwrap() as int; let myidx = self.alloc_index.unwrap() as isize;
&mut *mypos.offset(idx as int - myidx) &mut *mypos.offset(idx as isize - myidx)
} }
/// Retrieve the boolean value of the stack element, if it can be determined /// Retrieve the boolean value of the stack element, if it can be determined
@ -832,13 +832,13 @@ impl AbstractStackElem {
/// Retrieve the upper bound for this element's length. This always /// Retrieve the upper bound for this element's length. This always
/// exists as a finite value, though the default upper limit is some /// exists as a finite value, though the default upper limit is some
/// impractically large number /// impractically large number
pub fn len_hi(&self) -> uint { pub fn len_hi(&self) -> usize {
self.len_hi self.len_hi
} }
/// Retrieve the lower bound for this element's length. This always /// Retrieve the lower bound for this element's length. This always
/// exists since it is at least zero :) /// exists since it is at least zero :)
pub fn len_lo(&self) -> uint { pub fn len_lo(&self) -> usize {
self.len_lo self.len_lo
} }
@ -901,7 +901,7 @@ impl AbstractStackElem {
/// Sets the entire value of the /// Sets the entire value of the
pub fn set_value(&mut self, val: &[u8]) -> Result<(), ScriptError> { pub fn set_value(&mut self, val: &[u8]) -> Result<(), ScriptError> {
match self.raw_value().map(|x| Vec::from_slice(x)) { match self.raw_value().map(|x| x.to_vec()) {
Some(x) => { if x.as_slice() == val { Ok(()) } else { Err(Unsatisfiable) } } Some(x) => { if x.as_slice() == val { Ok(()) } else { Err(Unsatisfiable) } }
None => { None => {
try!(self.set_len_lo(val.len())); try!(self.set_len_lo(val.len()));
@ -915,7 +915,7 @@ impl AbstractStackElem {
Err(_) => {} Err(_) => {}
} }
try!(self.set_bool_value(read_scriptbool(val))); try!(self.set_bool_value(read_scriptbool(val)));
self.raw = Some(Vec::from_slice(val)); self.raw = Some(val.to_vec());
Ok(()) Ok(())
} }
} }
@ -1012,7 +1012,7 @@ impl AbstractStackElem {
} }
/// Sets a lower length bound on a value /// Sets a lower length bound on a value
pub fn set_len_lo(&mut self, value: uint) -> Result<(), ScriptError> { pub fn set_len_lo(&mut self, value: usize) -> Result<(), ScriptError> {
if self.len_lo < value { if self.len_lo < value {
self.len_lo = value; self.len_lo = value;
if value > 0 { try!(self.set_bool_value(true)); } if value > 0 { try!(self.set_bool_value(true)); }
@ -1023,7 +1023,7 @@ impl AbstractStackElem {
} }
/// Sets a upper length bound on a value /// Sets a upper length bound on a value
pub fn set_len_hi(&mut self, value: uint) -> Result<(), ScriptError> { pub fn set_len_hi(&mut self, value: usize) -> Result<(), ScriptError> {
if self.len_hi > value { if self.len_hi > value {
self.len_hi = value; self.len_hi = value;
try!(self.update()); try!(self.update());
@ -1043,11 +1043,11 @@ impl AbstractStackElem {
#[deriving(Clone)] #[deriving(Clone)]
pub struct AbstractStack { pub struct AbstractStack {
/// Actual elements on the stack /// Actual elements on the stack
stack: Vec<uint>, stack: Vec<usize>,
/// Actual elements on the altstack /// Actual elements on the altstack
alt_stack: Vec<uint>, alt_stack: Vec<usize>,
/// Stack needed to satisfy the script before execution /// Stack needed to satisfy the script before execution
initial_stack: Vec<uint>, initial_stack: Vec<usize>,
/// Local allocator to allow cloning; refs are indices into here /// Local allocator to allow cloning; refs are indices into here
alloc: Vec<AbstractStackElem> alloc: Vec<AbstractStackElem>
} }
@ -1063,7 +1063,7 @@ impl AbstractStack {
} }
} }
fn allocate(&mut self, mut elem: AbstractStackElem) -> uint { fn allocate(&mut self, mut elem: AbstractStackElem) -> usize {
elem.alloc_index = Some(self.alloc.len()); elem.alloc_index = Some(self.alloc.len());
self.alloc.push(elem); self.alloc.push(elem);
self.alloc.len() - 1 self.alloc.len() - 1
@ -1084,24 +1084,24 @@ impl AbstractStack {
/// Increase the stack size to `n`, adding elements to the initial /// Increase the stack size to `n`, adding elements to the initial
/// stack as necessary /// stack as necessary
pub fn require_n_elems(&mut self, n: uint) { pub fn require_n_elems(&mut self, n: usize) {
while self.stack.len() < n { while self.stack.len() < n {
self.push_initial(AbstractStackElem::new_unknown()); self.push_initial(AbstractStackElem::new_unknown());
} }
} }
/// Lookup an element by index /// Lookup an element by index
pub fn get_elem(&self, alloc_index: uint) -> &AbstractStackElem { pub fn get_elem(&self, alloc_index: usize) -> &AbstractStackElem {
&self.alloc[alloc_index] &self.alloc[alloc_index]
} }
/// Lookup an element by index /// Lookup an element by index
pub fn get_elem_mut(&mut self, alloc_index: uint) -> &mut AbstractStackElem { pub fn get_elem_mut(&mut self, alloc_index: usize) -> &mut AbstractStackElem {
self.alloc.get_mut(alloc_index) self.alloc.get_mut(alloc_index)
} }
/// Push a copy of an existing element by index /// Push a copy of an existing element by index
pub fn push(&mut self, elem: uint) { pub fn push(&mut self, elem: usize) {
self.stack.push(elem); self.stack.push(elem);
} }
@ -1123,7 +1123,7 @@ impl AbstractStack {
} }
/// Obtain a stackref to the current top element /// Obtain a stackref to the current top element
pub fn peek_index(&mut self) -> uint { pub fn peek_index(&mut self) -> usize {
if self.stack.len() == 0 { if self.stack.len() == 0 {
self.push_initial(AbstractStackElem::new_unknown()); self.push_initial(AbstractStackElem::new_unknown());
} }
@ -1131,7 +1131,7 @@ impl AbstractStack {
} }
/// Drop the top stack item /// Drop the top stack item
fn pop(&mut self) -> uint { fn pop(&mut self) -> usize {
if self.stack.len() == 0 { if self.stack.len() == 0 {
self.push_initial(AbstractStackElem::new_unknown()); self.push_initial(AbstractStackElem::new_unknown());
} }
@ -1171,28 +1171,28 @@ impl AbstractStack {
/// Immutable view of the current stack as a slice (to be compatible /// Immutable view of the current stack as a slice (to be compatible
/// with the `stack_opcode!` macro /// with the `stack_opcode!` macro
pub fn as_slice<'a>(&'a self) -> &'a [uint] { pub fn as_slice<'a>(&'a self) -> &'a [usize] {
self.stack.as_slice() self.stack.as_slice()
} }
/// Immutable view of the current stack as a slice of bytes /// Immutable view of the current stack as a slice of bytes
pub fn slice_to<'a>(&'a self, n: uint) -> &'a [uint] { pub fn slice_to<'a>(&'a self, n: usize) -> &'a [usize] {
self.stack.slice_to(n) self.stack.slice_to(n)
} }
/// Mutable view of the current stack as a slice (to be compatible /// Mutable view of the current stack as a slice (to be compatible
/// with the `stack_opcode!` macro /// with the `stack_opcode!` macro
fn as_mut_slice<'a>(&'a mut self) -> &'a mut [uint] { fn as_mut_slice<'a>(&'a mut self) -> &'a mut [usize] {
self.stack.as_mut_slice() self.stack.as_mut_slice()
} }
/// Length of the current stack /// Length of the current stack
fn len(&self) -> uint { fn len(&self) -> usize {
self.stack.len() self.stack.len()
} }
/// Delete an element from the middle of the current stack /// Delete an element from the middle of the current stack
fn remove(&mut self, idx: uint) { fn remove(&mut self, idx: usize) {
self.stack.remove(idx); self.stack.remove(idx);
} }
} }
@ -1206,8 +1206,8 @@ impl json::ToJson for ScriptError {
/// A single iteration of a script execution /// A single iteration of a script execution
#[deriving(PartialEq, Eq, Show, Clone)] #[deriving(PartialEq, Eq, Show, Clone)]
pub struct TraceIteration { pub struct TraceIteration {
index: uint, index: usize,
op_count: uint, op_count: usize,
opcode: allops::Opcode, opcode: allops::Opcode,
executed: bool, executed: bool,
errored: bool, errored: bool,
@ -1228,7 +1228,7 @@ pub struct ScriptTrace {
pub error: Option<ScriptError> pub error: Option<ScriptError>
} }
impl_json!(TraceIteration, index, opcode, op_count, executed, errored, effect, stack) impl_json!(TraceIteration, index, opcode, op_count, executed, errored, effect, stack);
/// Hashtype of a transaction, encoded in the last byte of a signature, /// Hashtype of a transaction, encoded in the last byte of a signature,
/// specifically in the last 5 bits `byte & 31` /// specifically in the last 5 bits `byte & 31`
@ -1269,7 +1269,7 @@ pub enum MaybeOwned<'a> {
/// Freshly allocated memory /// Freshly allocated memory
Owned(Vec<u8>), Owned(Vec<u8>),
/// Pointer into the original script /// Pointer into the original script
Slice(&'a [u8]) Borrowed(&'a [u8])
} }
impl<'a> PartialEq for MaybeOwned<'a> { impl<'a> PartialEq for MaybeOwned<'a> {
@ -1284,17 +1284,17 @@ impl<'a> Slice<u8> for MaybeOwned<'a> {
fn as_slice<'a>(&'a self) -> &'a [u8] { fn as_slice<'a>(&'a self) -> &'a [u8] {
match *self { match *self {
Owned(ref v) => v.as_slice(), Owned(ref v) => v.as_slice(),
Slice(ref s) => s.as_slice() Borrowed(ref s) => s.as_slice()
} }
} }
} }
impl<'a> Collection for MaybeOwned<'a> { impl<'a> Collection for MaybeOwned<'a> {
#[inline] #[inline]
fn len(&self) -> uint { fn len(&self) -> usize {
match *self { match *self {
Owned(ref v) => v.len(), Owned(ref v) => v.len(),
Slice(ref s) => s.len() Borrowed(ref s) => s.len()
} }
} }
} }
@ -1308,7 +1308,7 @@ fn build_scriptint(n: i64) -> Vec<u8> {
let neg = n < 0; let neg = n < 0;
let mut abs = if neg { -n } else { n } as uint; let mut abs = if neg { -n } else { n } as usize;
let mut v = vec![]; let mut v = vec![];
while abs > 0xFF { while abs > 0xFF {
v.push((abs & 0xFF) as u8); v.push((abs & 0xFF) as u8);
@ -1348,7 +1348,7 @@ pub fn read_scriptint(v: &[u8]) -> Result<i64, ScriptError> {
if len > 4 { return Err(NumericOverflow); } if len > 4 { return Err(NumericOverflow); }
let (mut ret, sh) = v.iter() let (mut ret, sh) = v.iter()
.fold((0, 0), |(acc, sh), n| (acc + (*n as i64 << sh), sh + 8)); .fold((0, 0), |(acc, sh), n| (acc + ((*n as i64) << sh), sh + 8));
if v[len - 1] & 0x80 != 0 { if v[len - 1] & 0x80 != 0 {
ret &= (1 << sh - 1) - 1; ret &= (1 << sh - 1) - 1;
ret = -ret; ret = -ret;
@ -1366,12 +1366,12 @@ pub fn read_scriptbool(v: &[u8]) -> bool {
} }
/// Read a script-encoded unsigned integer /// Read a script-encoded unsigned integer
pub fn read_uint<'a, I:Iterator<&'a u8>>(mut iter: I, size: uint) pub fn read_uint<'a, I:Iterator<&'a u8>>(mut iter: I, size: usize)
-> Result<uint, ScriptError> { -> Result<usize, ScriptError> {
let mut ret = 0; let mut ret = 0;
for i in range(0, size) { for i in range(0, size) {
match iter.next() { match iter.next() {
Some(&n) => ret += n as uint << (i * 8), Some(&n) => ret += (n as usize) << (i * 8),
None => { return Err(EarlyEndOfScript); } None => { return Err(EarlyEndOfScript); }
} }
} }
@ -1381,7 +1381,7 @@ pub fn read_uint<'a, I:Iterator<&'a u8>>(mut iter: I, size: uint)
/// Check a signature -- returns an error that is currently just translated /// Check a signature -- returns an error that is currently just translated
/// into a 0/1 to push onto the script stack /// into a 0/1 to push onto the script stack
fn check_signature(sig_slice: &[u8], pk_slice: &[u8], script: Vec<u8>, fn check_signature(sig_slice: &[u8], pk_slice: &[u8], script: Vec<u8>,
tx: &Transaction, input_index: uint) -> Result<(), ScriptError> { tx: &Transaction, input_index: usize) -> Result<(), ScriptError> {
// Check public key // Check public key
let pubkey = PublicKey::from_slice(pk_slice); let pubkey = PublicKey::from_slice(pk_slice);
@ -1478,13 +1478,13 @@ fn check_signature(sig_slice: &[u8], pk_slice: &[u8], script: Vec<u8>,
// were really hard to read and verify -- see OP_PICK and OP_ROLL // were really hard to read and verify -- see OP_PICK and OP_ROLL
// for an example of what Rust vector-stack manipulation looks // for an example of what Rust vector-stack manipulation looks
// like. // like.
macro_rules! stack_opcode( macro_rules! stack_opcode {
($stack:ident($min:expr): ($stack:ident($min:expr):
$(require $r:expr)* $(require $r:expr);*
$(copy $c:expr)* $(copy $c:expr);*
$(swap ($a:expr, $b:expr))* $(swap ($a:expr, $b:expr));*
$(perm ($first:expr $(->$i:expr)*) )* $(perm ($first:expr, $($i:expr),*) );*
$(drop $d:expr)* $(drop $d:expr);*
) => ({ ) => ({
$( $stack.require_n_elems($r); )* $( $stack.require_n_elems($r); )*
// Record top // Record top
@ -1502,10 +1502,10 @@ macro_rules! stack_opcode(
// Do drops last so that dropped values will be available above // Do drops last so that dropped values will be available above
$( $stack.remove(top - $d); )* $( $stack.remove(top - $d); )*
}); });
) }
/// Macro to translate numerical operations into stack ones /// Macro to translate numerical operations into stack ones
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() {
@ -1517,9 +1517,9 @@ macro_rules! num_opcode(
// Return a tuple of all the variables // Return a tuple of all the variables
($( $var ),*) ($( $var ),*)
}); });
) }
macro_rules! unary_opcode_satisfy( macro_rules! unary_opcode_satisfy {
($stack:ident, $op:ident) => ({ ($stack:ident, $op:ident) => ({
let one = $stack.pop(); let one = $stack.pop();
let cond = $stack.push_alloc(AbstractStackElem::new_unknown()); let cond = $stack.push_alloc(AbstractStackElem::new_unknown());
@ -1527,9 +1527,9 @@ macro_rules! unary_opcode_satisfy(
check: concat_idents!(check_, $op), check: concat_idents!(check_, $op),
update: concat_idents!(update_, $op) })); update: concat_idents!(update_, $op) }));
}) })
) }
macro_rules! boolean_opcode_satisfy( macro_rules! boolean_opcode_satisfy {
($stack:ident, unary $op:ident) => ({ ($stack:ident, unary $op:ident) => ({
let one = $stack.pop(); let one = $stack.pop();
let cond = $stack.push_alloc(AbstractStackElem::new_unknown()); let cond = $stack.push_alloc(AbstractStackElem::new_unknown());
@ -1557,10 +1557,10 @@ macro_rules! boolean_opcode_satisfy(
check: concat_idents!(check_, $op), check: concat_idents!(check_, $op),
update: concat_idents!(update_, $op) })); update: concat_idents!(update_, $op) }));
}); });
) }
/// Macro to translate hashing operations into stack ones /// Macro to translate hashing operations into stack ones
macro_rules! hash_opcode( macro_rules! hash_opcode {
($stack:ident, $hash:ident) => ({ ($stack:ident, $hash:ident) => ({
match $stack.pop() { match $stack.pop() {
None => { return Err(PopEmptyStack); } None => { return Err(PopEmptyStack); }
@ -1576,10 +1576,10 @@ macro_rules! hash_opcode(
} }
} }
}); });
) }
// OP_VERIFY macro // OP_VERIFY macro
macro_rules! op_verify ( macro_rules! op_verify {
($stack:expr, $err:expr) => ( ($stack:expr, $err:expr) => (
match $stack.last().map(|v| read_scriptbool(v.as_slice())) { match $stack.last().map(|v| read_scriptbool(v.as_slice())) {
None => { return Err(VerifyEmptyStack); } None => { return Err(VerifyEmptyStack); }
@ -1587,14 +1587,14 @@ macro_rules! op_verify (
Some(true) => { $stack.pop(); } Some(true) => { $stack.pop(); }
} }
) )
) }
macro_rules! op_verify_satisfy ( macro_rules! op_verify_satisfy {
($stack:expr) => ({ ($stack:expr) => ({
try!($stack.peek_mut().set_bool_value(true)); try!($stack.peek_mut().set_bool_value(true));
$stack.pop(); $stack.pop();
}) })
) }
impl Script { impl Script {
/// Creates a new empty script /// Creates a new empty script
@ -1604,7 +1604,7 @@ impl Script {
pub fn from_vec(v: Vec<u8>) -> Script { Script(ThinVec::from_vec(v)) } pub fn from_vec(v: Vec<u8>) -> Script { Script(ThinVec::from_vec(v)) }
/// The length in bytes of the script /// The length in bytes of the script
pub fn len(&self) -> uint { pub fn len(&self) -> usize {
let &Script(ref raw) = self; let &Script(ref raw) = self;
raw.len() raw.len()
} }
@ -1640,7 +1640,7 @@ impl Script {
let &Script(ref mut raw) = self; let &Script(ref mut raw) = self;
// Start with a PUSH opcode // Start with a PUSH opcode
match data.len() { match data.len() {
n if n < opcodes::OP_PUSHDATA1 as uint => { raw.push(n as u8); }, n if n < opcodes::OP_PUSHDATA1 as usize => { raw.push(n as u8); },
n if n < 0x100 => { n if n < 0x100 => {
raw.push(opcodes::OP_PUSHDATA1 as u8); raw.push(opcodes::OP_PUSHDATA1 as u8);
raw.push(n as u8); raw.push(n as u8);
@ -1657,7 +1657,7 @@ impl Script {
raw.push(((n / 0x10000) % 0x100) as u8); raw.push(((n / 0x10000) % 0x100) as u8);
raw.push((n / 0x1000000) as u8); raw.push((n / 0x1000000) as u8);
} }
_ => fail!("tried to put a 4bn+ sized object into a script!") _ => panic!("tried to put a 4bn+ sized object into a script!")
} }
// Then push the acraw // Then push the acraw
raw.extend(data.iter().map(|n| *n)); raw.extend(data.iter().map(|n| *n));
@ -1676,26 +1676,26 @@ impl Script {
} }
/// Returns a view into the script as a slice /// Returns a view into the script as a slice
pub fn slice_to(&self, n: uint) -> &[u8] { pub fn slice_to(&self, n: usize) -> &[u8] {
let &Script(ref raw) = self; let &Script(ref raw) = self;
raw.slice_to(n) raw.slice_to(n)
} }
/// Returns a view into the script as a slice /// Returns a view into the script as a slice
pub fn slice_from(&self, n: uint) -> &[u8] { pub fn slice_from(&self, n: usize) -> &[u8] {
let &Script(ref raw) = self; let &Script(ref raw) = self;
raw.slice_from(n) raw.slice_from(n)
} }
/// Returns a view into the script as a slice /// Returns a view into the script as a slice
pub fn slice(&self, s: uint, e: uint) -> &[u8] { pub fn slice(&self, s: usize, e: usize) -> &[u8] {
let &Script(ref raw) = self; let &Script(ref raw) = self;
raw.slice(s, e) raw.slice(s, e)
} }
/// Trace a script /// Trace a script
pub fn trace<'a>(&'a self, stack: &mut Vec<MaybeOwned<'a>>, pub fn trace<'a>(&'a self, stack: &mut Vec<MaybeOwned<'a>>,
input_context: Option<(&Transaction, uint)>) input_context: Option<(&Transaction, usize)>)
-> ScriptTrace { -> ScriptTrace {
let mut trace = ScriptTrace { let mut trace = ScriptTrace {
script: self.clone(), script: self.clone(),
@ -1713,12 +1713,12 @@ impl Script {
/// Evaluate the script, modifying the stack in place /// Evaluate the script, modifying the stack in place
pub fn evaluate<'a>(&'a self, stack: &mut Vec<MaybeOwned<'a>>, pub fn evaluate<'a>(&'a self, stack: &mut Vec<MaybeOwned<'a>>,
input_context: Option<(&Transaction, uint)>, input_context: Option<(&Transaction, usize)>,
mut trace: Option<&mut Vec<TraceIteration>>) mut trace: Option<&mut Vec<TraceIteration>>)
-> Result<(), ScriptError> { -> Result<(), ScriptError> {
let &Script(ref raw) = self; let &Script(ref raw) = self;
let mut codeseparator_index = 0u; let mut codeseparator_index = 0;
let mut exec_stack = vec![]; let mut exec_stack = vec![];
let mut alt_stack = vec![]; let mut alt_stack = vec![];
@ -1757,35 +1757,35 @@ impl Script {
// Data-reading statements still need to read, even when not executing // Data-reading statements still need to read, even when not executing
(_, opcodes::PushBytes(n)) => { (_, opcodes::PushBytes(n)) => {
if raw.len() < index + n { return Err(EarlyEndOfScript); } if raw.len() < index + n { return Err(EarlyEndOfScript); }
if executing { stack.push(Slice(raw.slice(index, index + n))); } if executing { stack.push(Borrowed(raw.slice(index, index + n))); }
index += n; index += n;
} }
(_, opcodes::Ordinary(opcodes::OP_PUSHDATA1)) => { (_, opcodes::Ordinary(opcodes::OP_PUSHDATA1)) => {
if raw.len() < index + 1 { return Err(EarlyEndOfScript); } if raw.len() < index + 1 { return Err(EarlyEndOfScript); }
let n = try!(read_uint(raw.slice_from(index).iter(), 1)); let n = try!(read_uint(raw.slice_from(index).iter(), 1));
if raw.len() < index + 1 + n { return Err(EarlyEndOfScript); } if raw.len() < index + 1 + n { return Err(EarlyEndOfScript); }
if executing { stack.push(Slice(raw.slice(index + 1, index + n + 1))); } if executing { stack.push(Borrowed(raw.slice(index + 1, index + n + 1))); }
index += 1 + n; index += 1 + n;
} }
(_, opcodes::Ordinary(opcodes::OP_PUSHDATA2)) => { (_, opcodes::Ordinary(opcodes::OP_PUSHDATA2)) => {
if raw.len() < index + 2 { return Err(EarlyEndOfScript); } if raw.len() < index + 2 { return Err(EarlyEndOfScript); }
let n = try!(read_uint(raw.slice_from(index).iter(), 2)); let n = try!(read_uint(raw.slice_from(index).iter(), 2));
if raw.len() < index + 2 + n { return Err(EarlyEndOfScript); } if raw.len() < index + 2 + n { return Err(EarlyEndOfScript); }
if executing { stack.push(Slice(raw.slice(index + 2, index + n + 2))); } if executing { stack.push(Borrowed(raw.slice(index + 2, index + n + 2))); }
index += 2 + n; index += 2 + n;
} }
(_, opcodes::Ordinary(opcodes::OP_PUSHDATA4)) => { (_, opcodes::Ordinary(opcodes::OP_PUSHDATA4)) => {
if raw.len() < index + 4 { return Err(EarlyEndOfScript); } if raw.len() < index + 4 { return Err(EarlyEndOfScript); }
let n = try!(read_uint(raw.slice_from(index).iter(), 4)); let n = try!(read_uint(raw.slice_from(index).iter(), 4));
if raw.len() < index + 4 + n { return Err(EarlyEndOfScript); } if raw.len() < index + 4 + n { return Err(EarlyEndOfScript); }
if executing { stack.push(Slice(raw.slice(index + 4, index + n + 4))); } if executing { stack.push(Borrowed(raw.slice(index + 4, index + n + 4))); }
index += 4 + n; index += 4 + n;
} }
// If-statements take effect when not executing // If-statements take effect when not executing
(false, opcodes::Ordinary(opcodes::OP_IF)) => exec_stack.push(false), (false, opcodes::Ordinary(opcodes::OP_IF)) => exec_stack.push(false),
(false, opcodes::Ordinary(opcodes::OP_NOTIF)) => exec_stack.push(false), (false, opcodes::Ordinary(opcodes::OP_NOTIF)) => exec_stack.push(false),
(false, opcodes::Ordinary(opcodes::OP_ELSE)) => { (false, opcodes::Ordinary(opcodes::OP_ELSE)) => {
match exec_stack.mut_last() { match exec_stack.last_mut() {
Some(ref_e) => { *ref_e = !*ref_e } Some(ref_e) => { *ref_e = !*ref_e }
None => { return Err(ElseWithoutIf); } None => { return Err(ElseWithoutIf); }
} }
@ -1816,7 +1816,7 @@ impl Script {
} }
} }
opcodes::OP_ELSE => { opcodes::OP_ELSE => {
match exec_stack.mut_last() { match exec_stack.last_mut() {
Some(ref_e) => { *ref_e = !*ref_e } Some(ref_e) => { *ref_e = !*ref_e }
None => { return Err(ElseWithoutIf); } None => { return Err(ElseWithoutIf); }
} }
@ -1839,13 +1839,13 @@ impl Script {
Some(elem) => { stack.push(elem); } Some(elem) => { stack.push(elem); }
} }
} }
opcodes::OP_2DROP => stack_opcode!(stack(2): drop 1 drop 2), opcodes::OP_2DROP => stack_opcode!(stack(2): drop 1; drop 2),
opcodes::OP_2DUP => stack_opcode!(stack(2): copy 2 copy 1), opcodes::OP_2DUP => stack_opcode!(stack(2): copy 2; copy 1),
opcodes::OP_3DUP => stack_opcode!(stack(3): copy 3 copy 2 copy 1), opcodes::OP_3DUP => stack_opcode!(stack(3): copy 3; copy 2; copy 1),
opcodes::OP_2OVER => stack_opcode!(stack(4): copy 4 copy 3), opcodes::OP_2OVER => stack_opcode!(stack(4): copy 4; copy 3),
opcodes::OP_2ROT => stack_opcode!(stack(6): perm (1 -> 3 -> 5) opcodes::OP_2ROT => stack_opcode!(stack(6): perm (1, 3, 5);
perm (2 -> 4 -> 6)), perm (2, 4, 6)),
opcodes::OP_2SWAP => stack_opcode!(stack(4): swap (2, 4) swap (1, 3)), opcodes::OP_2SWAP => stack_opcode!(stack(4): swap (2, 4); swap (1, 3)),
opcodes::OP_DROP => stack_opcode!(stack(1): drop 1), opcodes::OP_DROP => stack_opcode!(stack(1): drop 1),
opcodes::OP_DUP => stack_opcode!(stack(1): copy 1), opcodes::OP_DUP => stack_opcode!(stack(1): copy 1),
opcodes::OP_NIP => stack_opcode!(stack(2): drop 2), opcodes::OP_NIP => stack_opcode!(stack(2): drop 2),
@ -1856,7 +1856,7 @@ impl Script {
None => { return Err(PopEmptyStack); } None => { return Err(PopEmptyStack); }
}; };
if n < 0 { return Err(NegativePick); } if n < 0 { return Err(NegativePick); }
let n = n as uint; let n = n as usize;
stack_opcode!(stack(n + 1): copy n + 1) stack_opcode!(stack(n + 1): copy n + 1)
} }
opcodes::OP_ROLL => { opcodes::OP_ROLL => {
@ -1865,12 +1865,12 @@ impl Script {
None => { return Err(PopEmptyStack); } None => { return Err(PopEmptyStack); }
}; };
if n < 0 { return Err(NegativeRoll); } if n < 0 { return Err(NegativeRoll); }
let n = n as uint; let n = n as usize;
stack_opcode!(stack(n + 1): copy n + 1 drop n + 1) stack_opcode!(stack(n + 1): copy n + 1 drop n + 1)
} }
opcodes::OP_ROT => stack_opcode!(stack(3): perm (1 -> 2 -> 3)), opcodes::OP_ROT => stack_opcode!(stack(3): perm (1, 2, 3)),
opcodes::OP_SWAP => stack_opcode!(stack(2): swap (1, 2)), opcodes::OP_SWAP => stack_opcode!(stack(2): swap (1, 2)),
opcodes::OP_TUCK => stack_opcode!(stack(2): copy 2 copy 1 drop 2), opcodes::OP_TUCK => stack_opcode!(stack(2): copy 2; copy 1 drop 2),
opcodes::OP_IFDUP => { opcodes::OP_IFDUP => {
match stack.last().map(|v| read_scriptbool(v.as_slice())) { match stack.last().map(|v| read_scriptbool(v.as_slice())) {
None => { return Err(IfEmptyStack); } None => { return Err(IfEmptyStack); }
@ -1892,7 +1892,7 @@ impl Script {
if stack.len() < 2 { return Err(PopEmptyStack); } if stack.len() < 2 { return Err(PopEmptyStack); }
let a = stack.pop().unwrap(); let a = stack.pop().unwrap();
let b = stack.pop().unwrap(); let b = stack.pop().unwrap();
stack.push(Slice(if a == b { SCRIPT_TRUE } else { SCRIPT_FALSE })); stack.push(Borrowed(if a == b { SCRIPT_TRUE } else { SCRIPT_FALSE }));
if op == opcodes::OP_EQUALVERIFY { if op == opcodes::OP_EQUALVERIFY {
op_verify!(stack, EqualVerifyFailed(a.as_slice().to_hex(), op_verify!(stack, EqualVerifyFailed(a.as_slice().to_hex(),
b.as_slice().to_hex())); b.as_slice().to_hex()));
@ -1943,7 +1943,7 @@ impl Script {
// Compute the section of script that needs to be hashed: everything // Compute the section of script that needs to be hashed: everything
// from the last CODESEPARATOR, except the signature itself. // from the last CODESEPARATOR, except the signature itself.
let mut script = Vec::from_slice(raw.slice_from(codeseparator_index)); let mut script = raw.slice_from(codeseparator_index).to_vec();
let mut remove = Script::new(); let mut remove = Script::new();
remove.push_slice(sig_slice); remove.push_slice(sig_slice);
script_find_and_remove(&mut script, remove.as_slice()); script_find_and_remove(&mut script, remove.as_slice());
@ -1955,8 +1955,8 @@ impl Script {
let (tx, input_index) = input_context.unwrap(); let (tx, input_index) = input_context.unwrap();
match check_signature( sig_slice, pk_slice, script, tx, input_index) { match check_signature( sig_slice, pk_slice, script, tx, input_index) {
Ok(()) => stack.push(Slice(SCRIPT_TRUE)), Ok(()) => stack.push(Borrowed(SCRIPT_TRUE)),
_ => stack.push(Slice(SCRIPT_FALSE)), _ => stack.push(Borrowed(SCRIPT_FALSE)),
} }
if op == opcodes::OP_CHECKSIGVERIFY { op_verify!(stack, VerifyFailed); } if op == opcodes::OP_CHECKSIGVERIFY { op_verify!(stack, VerifyFailed); }
} }
@ -1965,11 +1965,11 @@ impl Script {
if stack.len() < 1 { return Err(PopEmptyStack); } if stack.len() < 1 { return Err(PopEmptyStack); }
let n_keys = try!(read_scriptint(stack.pop().unwrap().as_slice())); let n_keys = try!(read_scriptint(stack.pop().unwrap().as_slice()));
if n_keys < 0 || n_keys > 20 { if n_keys < 0 || n_keys > 20 {
return Err(MultisigBadKeyCount(n_keys as int)); return Err(MultisigBadKeyCount(n_keys as isize));
} }
if (stack.len() as i64) < n_keys { return Err(PopEmptyStack); } if (stack.len() as i64) < n_keys { return Err(PopEmptyStack); }
let mut keys = Vec::with_capacity(n_keys as uint); let mut keys = Vec::with_capacity(n_keys as usize);
for _ in range(0, n_keys) { for _ in range(0, n_keys) {
keys.push(stack.pop().unwrap()); keys.push(stack.pop().unwrap());
} }
@ -1978,11 +1978,11 @@ impl Script {
if stack.len() < 1 { return Err(PopEmptyStack); } if stack.len() < 1 { return Err(PopEmptyStack); }
let n_sigs = try!(read_scriptint(stack.pop().unwrap().as_slice())); let n_sigs = try!(read_scriptint(stack.pop().unwrap().as_slice()));
if n_sigs < 0 || n_sigs > n_keys { if n_sigs < 0 || n_sigs > n_keys {
return Err(MultisigBadSigCount(n_sigs as int)); return Err(MultisigBadSigCount(n_sigs as isize));
} }
if (stack.len() as i64) < n_sigs { return Err(PopEmptyStack); } if (stack.len() as i64) < n_sigs { return Err(PopEmptyStack); }
let mut sigs = Vec::with_capacity(n_sigs as uint); let mut sigs = Vec::with_capacity(n_sigs as usize);
for _ in range(0, n_sigs) { for _ in range(0, n_sigs) {
sigs.push(stack.pop().unwrap()); sigs.push(stack.pop().unwrap());
} }
@ -1992,7 +1992,7 @@ impl Script {
// Compute the section of script that needs to be hashed: everything // Compute the section of script that needs to be hashed: everything
// from the last CODESEPARATOR, except the signatures themselves. // from the last CODESEPARATOR, except the signatures themselves.
let mut script = Vec::from_slice(raw.slice_from(codeseparator_index)); let mut script = raw.slice_from(codeseparator_index).to_vec();
for sig in sigs.iter() { for sig in sigs.iter() {
let mut remove = Script::new(); let mut remove = Script::new();
remove.push_slice(sig.as_slice()); remove.push_slice(sig.as_slice());
@ -2024,12 +2024,12 @@ impl Script {
} }
// Run out of signatures, success // Run out of signatures, success
(_, None) => { (_, None) => {
stack.push(Slice(SCRIPT_TRUE)); stack.push(Borrowed(SCRIPT_TRUE));
break; break;
} }
// Run out of keys to match to signatures, fail // Run out of keys to match to signatures, fail
(None, Some(_)) => { (None, Some(_)) => {
stack.push(Slice(SCRIPT_FALSE)); stack.push(Borrowed(SCRIPT_FALSE));
break; break;
} }
} }
@ -2041,7 +2041,7 @@ impl Script {
} // end loop } // end loop
// Store the stack in the trace // Store the stack in the trace
trace.as_mut().map(|t| trace.as_mut().map(|t|
t.mut_last().map(|t| { t.last_mut().map(|t| {
t.errored = false; t.errored = false;
t.stack = stack.iter().map(|elem| elem.as_slice().to_hex()).collect(); t.stack = stack.iter().map(|elem| elem.as_slice().to_hex()).collect();
}) })
@ -2077,7 +2077,7 @@ impl Script {
fn recurse<'a>(script: &'a [u8], fn recurse<'a>(script: &'a [u8],
mut stack: AbstractStack, mut stack: AbstractStack,
mut exec_stack: Vec<bool>, mut exec_stack: Vec<bool>,
depth: uint) -> Result<Vec<AbstractStackElem>, ScriptError> { depth: usize) -> Result<Vec<AbstractStackElem>, ScriptError> {
// Avoid doing more than 64k forks // Avoid doing more than 64k forks
if depth > 16 { return Err(InterpreterStackOverflow); } if depth > 16 { return Err(InterpreterStackOverflow); }
@ -2143,7 +2143,7 @@ impl Script {
(false, opcodes::Ordinary(opcodes::OP_IF)) => exec_stack.push(false), (false, opcodes::Ordinary(opcodes::OP_IF)) => exec_stack.push(false),
(false, opcodes::Ordinary(opcodes::OP_NOTIF)) => exec_stack.push(false), (false, opcodes::Ordinary(opcodes::OP_NOTIF)) => exec_stack.push(false),
(false, opcodes::Ordinary(opcodes::OP_ELSE)) => { (false, opcodes::Ordinary(opcodes::OP_ELSE)) => {
match exec_stack.mut_last() { match exec_stack.last_mut() {
Some(ref_e) => { *ref_e = !*ref_e } Some(ref_e) => { *ref_e = !*ref_e }
None => { return Err(ElseWithoutIf); } None => { return Err(ElseWithoutIf); }
} }
@ -2212,7 +2212,7 @@ impl Script {
} }
} }
opcodes::OP_ELSE => { opcodes::OP_ELSE => {
match exec_stack.mut_last() { match exec_stack.last_mut() {
Some(ref_e) => { *ref_e = !*ref_e } Some(ref_e) => { *ref_e = !*ref_e }
None => { return Err(ElseWithoutIf); } None => { return Err(ElseWithoutIf); }
} }
@ -2225,15 +2225,15 @@ impl Script {
opcodes::OP_VERIFY => op_verify_satisfy!(stack), opcodes::OP_VERIFY => op_verify_satisfy!(stack),
opcodes::OP_TOALTSTACK => { stack.to_altstack(); } opcodes::OP_TOALTSTACK => { stack.to_altstack(); }
opcodes::OP_FROMALTSTACK => { try!(stack.from_altstack()); } opcodes::OP_FROMALTSTACK => { try!(stack.from_altstack()); }
opcodes::OP_2DROP => stack_opcode!(stack(2): require 2 drop 1 drop 2), opcodes::OP_2DROP => stack_opcode!(stack(2): require 2 drop 1; drop 2),
opcodes::OP_2DUP => stack_opcode!(stack(2): require 2 copy 2 copy 1), opcodes::OP_2DUP => stack_opcode!(stack(2): require 2 copy 2; copy 1),
opcodes::OP_3DUP => stack_opcode!(stack(3): require 3 copy 3 copy 2 copy 1), opcodes::OP_3DUP => stack_opcode!(stack(3): require 3 copy 3; copy 2; copy 1),
opcodes::OP_2OVER => stack_opcode!(stack(4): require 4 copy 4 copy 3), opcodes::OP_2OVER => stack_opcode!(stack(4): require 4 copy 4; copy 3),
opcodes::OP_2ROT => stack_opcode!(stack(6): require 6 opcodes::OP_2ROT => stack_opcode!(stack(6): require 6
perm (1 -> 3 -> 5) perm (1, 3, 5);
perm (2 -> 4 -> 6)), perm (2, 4, 6)),
opcodes::OP_2SWAP => stack_opcode!(stack(4): require 4 opcodes::OP_2SWAP => stack_opcode!(stack(4): require 4
swap (2, 4) swap (2, 4);
swap (1, 3)), swap (1, 3)),
opcodes::OP_DROP => stack_opcode!(stack(1): require 1 drop 1), opcodes::OP_DROP => stack_opcode!(stack(1): require 1 drop 1),
opcodes::OP_DUP => stack_opcode!(stack(1): require 1 copy 1), opcodes::OP_DUP => stack_opcode!(stack(1): require 1 copy 1),
@ -2244,7 +2244,7 @@ impl Script {
let top = stack.peek_mut(); let top = stack.peek_mut();
try!(top.set_numeric()); try!(top.set_numeric());
try!(top.set_num_lo(0)); try!(top.set_num_lo(0));
top.num_value().map(|n| n as uint) top.num_value().map(|n| n as usize)
}; };
stack.pop(); stack.pop();
match top_n { match top_n {
@ -2262,7 +2262,7 @@ impl Script {
let top = stack.peek_mut(); let top = stack.peek_mut();
try!(top.set_numeric()); try!(top.set_numeric());
try!(top.set_num_lo(0)); try!(top.set_num_lo(0));
top.num_value().map(|n| n as uint) top.num_value().map(|n| n as usize)
}; };
stack.pop(); stack.pop();
match top_n { match top_n {
@ -2274,9 +2274,9 @@ impl Script {
None => { return Err(Unanalyzable); } None => { return Err(Unanalyzable); }
} }
} }
opcodes::OP_ROT => stack_opcode!(stack(3): require 3 perm (1 -> 2 -> 3)), opcodes::OP_ROT => stack_opcode!(stack(3): require 3 perm (1, 2, 3)),
opcodes::OP_SWAP => stack_opcode!(stack(2): require 3 swap (1, 2)), opcodes::OP_SWAP => stack_opcode!(stack(2): require 3 swap (1, 2)),
opcodes::OP_TUCK => stack_opcode!(stack(2): require 2 copy 2 copy 1 drop 2), opcodes::OP_TUCK => stack_opcode!(stack(2): require 2 copy 2; copy 1 drop 2),
opcodes::OP_IFDUP => { opcodes::OP_IFDUP => {
let top_bool = { let top_bool = {
let top = stack.peek_mut(); let top = stack.peek_mut();
@ -2423,8 +2423,8 @@ impl json::ToJson for Script {
let &Script(ref raw) = self; let &Script(ref raw) = self;
let mut ret = String::new(); let mut ret = String::new();
for dat in raw.iter() { for dat in raw.iter() {
ret.push_char(from_digit((dat / 0x10) as uint, 16).unwrap()); ret.push_char(from_digit((dat / 0x10) as usize, 16).unwrap());
ret.push_char(from_digit((dat & 0x0f) as uint, 16).unwrap()); ret.push_char(from_digit((dat & 0x0f) as usize, 16).unwrap());
} }
json::String(ret) json::String(ret)
} }

View File

@ -27,7 +27,7 @@ use std::default::Default;
use serialize::json; use serialize::json;
use util::hash::Sha256dHash; use util::hash::Sha256dHash;
use blockdata::script::{mod, Script, ScriptError, ScriptTrace, read_scriptbool}; use blockdata::script::{self, Script, ScriptError, ScriptTrace, read_scriptbool};
use blockdata::utxoset::UtxoSet; use blockdata::utxoset::UtxoSet;
use network::encodable::ConsensusEncodable; use network::encodable::ConsensusEncodable;
use network::serialize::BitcoinHash; use network::serialize::BitcoinHash;
@ -81,7 +81,7 @@ impl TxOut {
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] &&
self.script_pubkey.slice_from(23) == &[0x88, 0xac] { self.script_pubkey.slice_from(23) == &[0x88, 0xac] {
PayToPubkeyHash(Address::from_slice(network, self.script_pubkey.slice(3, 23))) PayToPubkeyHash(self.script_pubkey.slice(3, 23).to_address(network))
} else { } else {
Unknown Unknown
} }
@ -133,16 +133,16 @@ impl json::ToJson for TransactionError {
#[deriving(PartialEq, Eq, Clone, Show)] #[deriving(PartialEq, Eq, Clone, Show)]
pub struct InputTrace { pub struct InputTrace {
input_txid: Sha256dHash, input_txid: Sha256dHash,
input_vout: uint, input_vout: usize,
sig_trace: ScriptTrace, sig_trace: ScriptTrace,
pubkey_trace: Option<ScriptTrace>, pubkey_trace: Option<ScriptTrace>,
p2sh_trace: Option<ScriptTrace>, p2sh_trace: Option<ScriptTrace>,
error: Option<TransactionError> error: Option<TransactionError>
} }
impl_json!(ScriptTrace, script, initial_stack, iterations, error) impl_json!(ScriptTrace, script, initial_stack, iterations, error);
impl_json!(InputTrace, input_txid, input_vout, sig_trace, impl_json!(InputTrace, input_txid, input_vout, sig_trace,
pubkey_trace, p2sh_trace, error) pubkey_trace, p2sh_trace, error);
/// A trace of a transaction's execution /// A trace of a transaction's execution
#[deriving(PartialEq, Eq, Clone, Show)] #[deriving(PartialEq, Eq, Clone, Show)]
@ -151,14 +151,14 @@ pub struct TransactionTrace {
inputs: Vec<InputTrace> inputs: Vec<InputTrace>
} }
impl_json!(TransactionTrace, txid, inputs) impl_json!(TransactionTrace, txid, inputs);
impl TxIn { impl TxIn {
/// Check an input's script for validity /// Check an input's script for validity
pub fn validate(&self, pub fn validate(&self,
utxoset: &UtxoSet, utxoset: &UtxoSet,
txn: &Transaction, txn: &Transaction,
index: uint) -> Result<(), TransactionError> { index: usize) -> Result<(), TransactionError> {
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)) => {
@ -174,7 +174,7 @@ impl TxIn {
p2sh_stack = stack.clone(); p2sh_stack = stack.clone();
p2sh_script = match p2sh_stack.pop() { p2sh_script = match p2sh_stack.pop() {
Some(script::Owned(v)) => Script::from_vec(v), Some(script::Owned(v)) => Script::from_vec(v),
Some(script::Slice(s)) => Script::from_vec(Vec::from_slice(s)), Some(script::Borrowed(s)) => Script::from_vec(s.to_vec()),
None => unreachable!() None => unreachable!()
}; };
} }
@ -228,7 +228,7 @@ impl Transaction {
// Setup trace // Setup trace
let mut trace = InputTrace { let mut trace = InputTrace {
input_txid: input.prev_hash, input_txid: input.prev_hash,
input_vout: input.prev_index as uint, input_vout: input.prev_index as usize,
sig_trace: ScriptTrace { sig_trace: ScriptTrace {
script: Script::new(), script: Script::new(),
initial_stack: vec![], initial_stack: vec![],
@ -255,7 +255,7 @@ impl Transaction {
p2sh_stack = stack.clone(); p2sh_stack = stack.clone();
p2sh_script = match p2sh_stack.pop() { p2sh_script = match p2sh_stack.pop() {
Some(script::Owned(v)) => Script::from_vec(v), Some(script::Owned(v)) => Script::from_vec(v),
Some(script::Slice(s)) => Script::from_vec(Vec::from_slice(s)), Some(script::Borrowed(s)) => Script::from_vec(s.to_vec()),
None => unreachable!() None => unreachable!()
}; };
} }
@ -303,12 +303,12 @@ impl BitcoinHash for Transaction {
} }
} }
impl_consensus_encoding!(TxIn, prev_hash, prev_index, script_sig, sequence) impl_consensus_encoding!(TxIn, prev_hash, prev_index, script_sig, sequence);
impl_json!(TxIn, prev_hash, prev_index, script_sig, sequence) impl_json!(TxIn, prev_hash, prev_index, script_sig, sequence);
impl_consensus_encoding!(TxOut, value, script_pubkey) impl_consensus_encoding!(TxOut, value, script_pubkey);
impl_json!(TxOut, value, script_pubkey) impl_json!(TxOut, value, script_pubkey);
impl_consensus_encoding!(Transaction, version, input, output, lock_time) impl_consensus_encoding!(Transaction, version, input, output, lock_time);
impl_json!(Transaction, version, input, output, lock_time) impl_json!(Transaction, version, input, output, lock_time);
#[cfg(test)] #[cfg(test)]

View File

@ -65,27 +65,27 @@ struct UtxoNode {
/// Vector of outputs; None indicates a nonexistent or already spent output /// Vector of outputs; None indicates a nonexistent or already spent output
outputs: ThinVec<Option<TxOut>> outputs: ThinVec<Option<TxOut>>
} }
impl_consensus_encoding!(UtxoNode, height, outputs) impl_consensus_encoding!(UtxoNode, height, outputs);
/// An iterator over UTXOs /// An iterator over UTXOs
pub struct UtxoIterator<'a> { pub struct UtxoIterator<'a> {
tx_iter: Entries<'a, Sha256dHash, UtxoNode>, tx_iter: Entries<'a, Sha256dHash, UtxoNode>,
current_key: Sha256dHash, current_key: Sha256dHash,
current: Option<&'a UtxoNode>, current: Option<&'a UtxoNode>,
tx_index: uint tx_index: u32
} }
impl<'a> Iterator<(Sha256dHash, uint, &'a TxOut, uint)> for UtxoIterator<'a> { impl<'a> Iterator<(Sha256dHash, u32, &'a TxOut, u32)> for UtxoIterator<'a> {
fn next(&mut self) -> Option<(Sha256dHash, uint, &'a TxOut, uint)> { fn next(&mut self) -> Option<(Sha256dHash, u32, &'a TxOut, u32)> {
while self.current.is_some() { while self.current.is_some() {
let current = &self.current.unwrap().outputs; let current = &self.current.unwrap().outputs;
while self.tx_index < current.len() { while self.tx_index < current.len() as u32 {
self.tx_index += 1; self.tx_index += 1;
if unsafe { current.get(self.tx_index - 1) }.is_some() { if unsafe { current.get(self.tx_index as usize - 1) }.is_some() {
return Some((self.current_key, return Some((self.current_key,
self.tx_index, self.tx_index,
unsafe { current.get(self.tx_index - 1) }.as_ref().unwrap(), unsafe { current.get(self.tx_index as usize - 1) }.as_ref().unwrap(),
self.current.unwrap().height as uint)); self.current.unwrap().height));
} }
} }
match self.tx_iter.next() { match self.tx_iter.next() {
@ -113,11 +113,11 @@ pub struct UtxoSet {
n_pruned: u64 n_pruned: u64
} }
impl_consensus_encoding!(UtxoSet, last_hash, n_utxos, n_pruned, spent_txos, spent_idx, table) impl_consensus_encoding!(UtxoSet, last_hash, n_utxos, n_pruned, spent_txos, spent_idx, table);
impl UtxoSet { impl UtxoSet {
/// Constructs a new UTXO set /// Constructs a new UTXO set
pub fn new(network: Network, rewind_limit: uint) -> UtxoSet { pub fn new(network: Network, rewind_limit: usize) -> UtxoSet {
// There is in fact a transaction in the genesis block, but the Bitcoin // There is in fact a transaction in the genesis block, but the Bitcoin
// reference client does not add its sole output to the UTXO set. We // reference client does not add its sole output to the UTXO set. We
// must follow suit, otherwise we will accept a transaction spending it // must follow suit, otherwise we will accept a transaction spending it
@ -141,11 +141,11 @@ impl UtxoSet {
for (vout, txo) in tx.output.iter().enumerate() { for (vout, txo) in tx.output.iter().enumerate() {
// Unsafe since we are not uninitializing the old data in the vector // Unsafe since we are not uninitializing the old data in the vector
if txo.script_pubkey.is_provably_unspendable() { if txo.script_pubkey.is_provably_unspendable() {
new_node.init(vout as uint, None); new_node.init(vout as usize, None);
self.n_utxos -= 1; self.n_utxos -= 1;
self.n_pruned += 1; self.n_pruned += 1;
} else { } else {
new_node.init(vout as uint, Some(txo.clone())); new_node.init(vout as usize, Some(txo.clone()));
} }
} }
UtxoNode { outputs: new_node, height: height } UtxoNode { outputs: new_node, height: height }
@ -171,8 +171,8 @@ impl UtxoSet {
let ret = { let ret = {
// Check that this specific output is there // Check that this specific output is there
if vout as uint >= node.outputs.len() { return None; } if vout as usize >= node.outputs.len() { return None; }
let replace = unsafe { node.outputs.get_mut(vout as uint) }; let replace = unsafe { node.outputs.get_mut(vout as usize) };
replace.take() replace.take()
}; };
@ -190,20 +190,20 @@ 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<(uint, &'a TxOut)> { pub fn get_utxo<'a>(&'a self, txid: Sha256dHash, vout: u32) -> Option<(usize, &'a TxOut)> {
// Locate the UTXO, failing if not found // Locate the UTXO, failing if not found
let node = match self.table.find(&txid) { let node = match self.table.find(&txid) {
Some(node) => node, Some(node) => node,
None => return None None => return None
}; };
// Check that this specific output is there // Check that this specific output is there
if vout as uint >= node.outputs.len() { return None; } if vout as usize >= node.outputs.len() { return None; }
let replace = unsafe { node.outputs.get(vout as uint) }; let replace = unsafe { node.outputs.get(vout as usize) };
Some((node.height as uint, replace.as_ref().unwrap())) Some((node.height as usize, replace.as_ref().unwrap()))
} }
/// Apply the transactions contained in a block /// Apply the transactions contained in a block
pub fn update(&mut self, block: &Block, blockheight: uint, validation: ValidationLevel) pub fn update(&mut self, block: &Block, blockheight: usize, validation: ValidationLevel)
-> Result<(), UtxoSetError> { -> Result<(), UtxoSetError> {
// Make sure we are extending the UTXO set in order // Make sure we are extending the UTXO set in order
if validation >= ChainValidation && if validation >= ChainValidation &&
@ -214,7 +214,7 @@ impl UtxoSet {
// Set the next hash immediately so that if anything goes wrong, // Set the next hash immediately so that if anything goes wrong,
// we can rewind from the point that we're at. // we can rewind from the point that we're at.
self.last_hash = block.header.bitcoin_hash(); self.last_hash = block.header.bitcoin_hash();
let spent_idx = self.spent_idx as uint; let spent_idx = self.spent_idx as usize;
self.spent_idx = (self.spent_idx + 1) % self.spent_txos.len() as u64; self.spent_idx = (self.spent_idx + 1) % self.spent_txos.len() as u64;
self.spent_txos.get_mut(spent_idx).clear(); self.spent_txos.get_mut(spent_idx).clear();
@ -240,7 +240,7 @@ impl UtxoSet {
// Otherwise put the replaced txouts into the `deleted` cache // Otherwise put the replaced txouts into the `deleted` cache
// so that rewind will put them back. // so that rewind will put them back.
self.spent_txos.get_mut(spent_idx).reserve_additional(replace.outputs.len()); self.spent_txos.get_mut(spent_idx).reserve_additional(replace.outputs.len());
for (n, input) in replace.outputs.mut_iter().enumerate() { for (n, input) in replace.outputs.iter_mut().enumerate() {
match input.take() { match input.take() {
Some(txo) => { self.spent_txos.get_mut(spent_idx).push(((txid, n as u32), (replace.height, txo))); } Some(txo) => { self.spent_txos.get_mut(spent_idx).push(((txid, n as u32), (replace.height, txo))); }
None => {} None => {}
@ -269,7 +269,7 @@ impl UtxoSet {
let s = self as *mut _ as *const UtxoSet; let s = self as *mut _ as *const UtxoSet;
let txes = &block.txdata as *const _; let txes = &block.txdata as *const _;
future_vec.push(Future::spawn(proc() { future_vec.push(Future::spawn(move || {
let txes = unsafe {&*txes}; let txes = unsafe {&*txes};
for tx in txes.slice(start, end).iter() { for tx in txes.slice(start, end).iter() {
match tx.validate(unsafe {&*s}) { match tx.validate(unsafe {&*s}) {
@ -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_error = Ok(()); let mut last_error = Ok(());
for res in future_vec.mut_iter().map(|f| f.get()) { for res in future_vec.iter_mut().map(|f| f.get()) {
if res.is_err() { if res.is_err() {
last_error = res; last_error = res;
} }
@ -348,8 +348,8 @@ impl UtxoSet {
// Read deleted txouts // Read deleted txouts
if skipped_genesis { if skipped_genesis {
let mut extract_vec = vec![]; let mut extract_vec = vec![];
mem::swap(&mut extract_vec, self.spent_txos.get_mut(self.spent_idx as uint)); mem::swap(&mut extract_vec, self.spent_txos.get_mut(self.spent_idx as usize));
for ((txid, n), (height, txo)) in extract_vec.move_iter() { for ((txid, n), (height, txo)) in extract_vec.into_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) { match self.table.pop(&txid) {
@ -359,20 +359,20 @@ impl UtxoSet {
unsafe { unsafe {
node.outputs.reserve(n + 1); node.outputs.reserve(n + 1);
for i in range(old_len, n + 1) { for i in range(old_len, n + 1) {
node.outputs.init(i as uint, None); node.outputs.init(i as usize, None);
} }
} }
} }
unsafe { *node.outputs.get_mut(n as uint) = Some(txo); } unsafe { *node.outputs.get_mut(n as usize) = Some(txo); }
node node
} }
None => { None => {
unsafe { unsafe {
let mut thinvec = ThinVec::with_capacity(n + 1); let mut thinvec = ThinVec::with_capacity(n + 1);
for i in range(0, n) { for i in range(0, n) {
thinvec.init(i as uint, None); thinvec.init(i as usize, None);
} }
thinvec.init(n as uint, Some(txo)); thinvec.init(n as usize, Some(txo));
UtxoNode { outputs: thinvec, height: height } UtxoNode { outputs: thinvec, height: height }
} }
} }
@ -397,14 +397,14 @@ impl UtxoSet {
} }
/// Get the number of UTXOs in the set /// Get the number of UTXOs in the set
pub fn n_utxos(&self) -> uint { pub fn n_utxos(&self) -> usize {
self.n_utxos as uint self.n_utxos as usize
} }
/// Get the number of UTXOs ever pruned from the set (this is not updated /// Get the number of UTXOs ever pruned from the set (this is not updated
/// during reorgs, so it may return a higher number than is realistic). /// during reorgs, so it may return a higher number than is realistic).
pub fn n_pruned(&self) -> uint { pub fn n_pruned(&self) -> usize {
self.n_pruned as uint self.n_pruned as usize
} }
/// Get an iterator over all UTXOs /// Get an iterator over all UTXOs

View File

@ -12,9 +12,7 @@
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. // If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
// //
#![macro_escape] macro_rules! impl_consensus_encoding {
macro_rules! impl_consensus_encoding(
($thing:ident, $($field:ident),+) => ( ($thing:ident, $($field:ident),+) => (
impl<S: ::network::serialize::SimpleEncoder<E>, E> ::network::encodable::ConsensusEncodable<S, E> for $thing { impl<S: ::network::serialize::SimpleEncoder<E>, E> ::network::encodable::ConsensusEncodable<S, E> for $thing {
#[inline] #[inline]
@ -34,9 +32,9 @@ macro_rules! impl_consensus_encoding(
} }
} }
); );
) }
macro_rules! impl_newtype_consensus_encoding( macro_rules! impl_newtype_consensus_encoding {
($thing:ident) => ( ($thing:ident) => (
impl<S: ::network::serialize::SimpleEncoder<E>, E> ::network::encodable::ConsensusEncodable<S, E> for $thing { impl<S: ::network::serialize::SimpleEncoder<E>, E> ::network::encodable::ConsensusEncodable<S, E> for $thing {
#[inline] #[inline]
@ -53,9 +51,9 @@ macro_rules! impl_newtype_consensus_encoding(
} }
} }
); );
) }
macro_rules! impl_json( macro_rules! impl_json {
($thing:ident, $($field:ident),+) => ( ($thing:ident, $($field:ident),+) => (
impl ::serialize::json::ToJson for $thing { impl ::serialize::json::ToJson for $thing {
fn to_json(&self) -> ::serialize::json::Json { fn to_json(&self) -> ::serialize::json::Json {
@ -67,9 +65,9 @@ macro_rules! impl_json(
} }
} }
); );
) }
macro_rules! impl_array_newtype( macro_rules! impl_array_newtype {
($thing:ident, $ty:ty, $len:expr) => { ($thing:ident, $ty:ty, $len:expr) => {
impl $thing { impl $thing {
#[inline] #[inline]
@ -81,21 +79,21 @@ macro_rules! impl_array_newtype(
#[inline] #[inline]
/// Provides an immutable view into the object from index `s` inclusive to `e` exclusive /// Provides an immutable view into the object from index `s` inclusive to `e` exclusive
pub fn slice<'a>(&'a self, s: uint, e: uint) -> &'a [$ty] { pub fn slice<'a>(&'a self, s: usize, e: usize) -> &'a [$ty] {
let &$thing(ref dat) = self; let &$thing(ref dat) = self;
dat.slice(s, e) dat.slice(s, e)
} }
#[inline] #[inline]
/// Provides an immutable view into the object, up to index `n` exclusive /// Provides an immutable view into the object, up to index `n` exclusive
pub fn slice_to<'a>(&'a self, n: uint) -> &'a [$ty] { pub fn slice_to<'a>(&'a self, n: usize) -> &'a [$ty] {
let &$thing(ref dat) = self; let &$thing(ref dat) = self;
dat.slice_to(n) dat.slice_to(n)
} }
#[inline] #[inline]
/// Provides an immutable view into the object, starting from index `n` /// Provides an immutable view into the object, starting from index `n`
pub fn slice_from<'a>(&'a self, n: uint) -> &'a [$ty] { pub fn slice_from<'a>(&'a self, n: usize) -> &'a [$ty] {
let &$thing(ref dat) = self; let &$thing(ref dat) = self;
dat.slice_from(n) dat.slice_from(n)
} }
@ -116,7 +114,7 @@ macro_rules! impl_array_newtype(
#[inline] #[inline]
/// Returns the length of the object as an array /// Returns the length of the object as an array
pub fn len(&self) -> uint { $len } pub fn len(&self) -> usize { $len }
/// Constructs a new object from raw data /// Constructs a new object from raw data
pub fn from_slice(data: &[$ty]) -> $thing { pub fn from_slice(data: &[$ty]) -> $thing {
@ -133,9 +131,9 @@ macro_rules! impl_array_newtype(
} }
} }
impl Index<uint, $ty> for $thing { impl Index<usize, $ty> for $thing {
#[inline] #[inline]
fn index<'a>(&'a self, idx: &uint) -> &'a $ty { fn index<'a>(&'a self, idx: &usize) -> &'a $ty {
let &$thing(ref data) = self; let &$thing(ref data) = self;
&data[*idx] &data[*idx]
} }
@ -157,9 +155,9 @@ macro_rules! impl_array_newtype(
} }
} }
} }
) }
macro_rules! impl_array_newtype_encodable( macro_rules! impl_array_newtype_encodable {
($thing:ident, $ty:ty, $len:expr) => { ($thing:ident, $ty:ty, $len:expr) => {
impl<D: ::serialize::Decoder<E>, E> ::serialize::Decodable<D, E> for $thing { impl<D: ::serialize::Decoder<E>, E> ::serialize::Decodable<D, E> for $thing {
fn decode(d: &mut D) -> ::std::prelude::Result<$thing, E> { fn decode(d: &mut D) -> ::std::prelude::Result<$thing, E> {
@ -173,7 +171,7 @@ macro_rules! impl_array_newtype_encodable(
} else { } else {
unsafe { unsafe {
use std::mem; use std::mem;
let mut ret: [$ty, ..$len] = mem::uninitialized(); let mut ret: [$ty; $len] = mem::uninitialized();
for i in range(0, len) { for i in range(0, len) {
ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d))); ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d)));
} }
@ -190,9 +188,9 @@ macro_rules! impl_array_newtype_encodable(
} }
} }
} }
) }
macro_rules! impl_array_newtype_show( macro_rules! impl_array_newtype_show {
($thing:ident) => { ($thing:ident) => {
impl ::std::fmt::Show for $thing { impl ::std::fmt::Show for $thing {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
@ -200,5 +198,5 @@ macro_rules! impl_array_newtype_show(
} }
} }
} }
) }

View File

@ -28,12 +28,8 @@
#![crate_type = "rlib"] #![crate_type = "rlib"]
// Experimental features we need // Experimental features we need
#![feature(globs)]
#![feature(macro_rules)]
#![feature(overloaded_calls)] #![feature(overloaded_calls)]
#![feature(unsafe_destructor)] #![feature(unsafe_destructor)]
#![feature(default_type_params)]
#![feature(struct_variant)]
#![feature(unboxed_closure_sugar)] #![feature(unboxed_closure_sugar)]
#![feature(unboxed_closures)] #![feature(unboxed_closures)]
@ -50,18 +46,17 @@
extern crate alloc; extern crate alloc;
extern crate collections; extern crate collections;
extern crate core; extern crate core;
extern crate num;
extern crate rand; extern crate rand;
extern crate rustrt;
extern crate serialize; extern crate serialize;
extern crate sync;
extern crate test; extern crate test;
extern crate time; extern crate time;
extern crate "bitcoin-secp256k1-rs" as secp256k1; extern crate "bitcoin-secp256k1-rs" as secp256k1;
extern crate "rust-crypto" as crypto; extern crate crypto;
#[macro_use]
mod internal_macros; mod internal_macros;
#[macro_use]
pub mod macros; pub mod macros;
pub mod network; pub mod network;
pub mod blockdata; pub mod blockdata;

View File

@ -16,14 +16,12 @@
//! //!
//! Macros available to users of the Bitcoin library //! Macros available to users of the Bitcoin library
#![macro_escape]
#[macro_export] #[macro_export]
macro_rules! nu_select( macro_rules! nu_select {
($($name:pat from $rx:expr => $code:expr),+) => ({ ($($name:pat = $rx:expr => $code:expr),+) => ({
nu_select!{ $($name from $rx using recv => $code),+ } nu_select!{ $($name = $rx, recv => $code),+ }
}); });
($($name:pat from $rx:expr using $meth:ident => $code:expr),+) => ({ ($($name:pat = $rx:expr, $meth:ident => $code:expr),+) => ({
use rustrt::local::Local; use rustrt::local::Local;
use rustrt::task::Task; use rustrt::task::Task;
use sync::comm::Packet; use sync::comm::Packet;
@ -82,10 +80,10 @@ macro_rules! nu_select(
ret ret
} }
}) })
) }
#[macro_export] #[macro_export]
macro_rules! user_enum( macro_rules! user_enum {
($(#[$attr:meta])* pub enum $name:ident { $(#[$doc:meta] $elem:ident <-> $txt:expr),* }) => ( ($(#[$attr:meta])* pub enum $name:ident { $(#[$doc:meta] $elem:ident <-> $txt:expr),* }) => (
$(#[$attr])* $(#[$attr])*
pub enum $name { pub enum $name {
@ -114,5 +112,5 @@ macro_rules! user_enum(
} }
} }
); );
) }

View File

@ -28,7 +28,7 @@ pub struct Address {
/// Services provided by the peer whose address this is /// Services provided by the peer whose address this is
pub services: u64, pub services: u64,
/// Network byte-order ipv6 address, or ipv4-mapped ipv6 address /// Network byte-order ipv6 address, or ipv4-mapped ipv6 address
pub address: [u8, ..16], pub address: [u8; 16],
/// Network port /// Network port
pub port: u16 pub port: u16
} }
@ -117,7 +117,7 @@ mod test {
let mut addr: IoResult<Address> = deserialize(vec![1u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, let mut addr: IoResult<Address> = deserialize(vec![1u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x0a, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x0a, 0,
0, 1, 0x20, 0x8d]); 0, 1, 0x20, 0x8d]);
assert!(addr.is_ok()) assert!(addr.is_ok());
let full = addr.unwrap(); let full = addr.unwrap();
assert!(full.services == 1); assert!(full.services == 1);
assert!(full.address == [0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x0a, 0, 0, 1]); assert!(full.address == [0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x0a, 0, 0, 1]);

View File

@ -21,7 +21,7 @@
use network::encodable::{ConsensusDecodable, ConsensusEncodable}; use network::encodable::{ConsensusDecodable, ConsensusEncodable};
use network::serialize::{SimpleEncoder, SimpleDecoder}; use network::serialize::{SimpleEncoder, SimpleDecoder};
user_enum!( user_enum! {
#[deriving(PartialEq, Eq, Clone, Hash)] #[deriving(PartialEq, Eq, Clone, Hash)]
#[doc="The cryptocurrency to act on"] #[doc="The cryptocurrency to act on"]
pub enum Network { pub enum Network {
@ -30,11 +30,11 @@ user_enum!(
#[doc="Bitcoin's testnet"] #[doc="Bitcoin's testnet"]
BitcoinTestnet <-> "testnet" BitcoinTestnet <-> "testnet"
} }
) }
pub static PROTOCOL_VERSION: u32 = 70001; pub const PROTOCOL_VERSION: u32 = 70001;
pub static SERVICES: u64 = 0; pub const SERVICES: u64 = 0;
pub static USER_AGENT: &'static str = "bitcoin-rust v0.1"; pub const USER_AGENT: &'static str = "bitcoin-rust v0.1";
/// Return the network magic bytes, which should be encoded little-endian /// Return the network magic bytes, which should be encoded little-endian
/// at the start of every message /// at the start of every message
@ -79,7 +79,7 @@ mod tests {
assert_eq!(deserialize(vec![0xf9, 0xbe, 0xb4, 0xd9]), Ok(Bitcoin)); assert_eq!(deserialize(vec![0xf9, 0xbe, 0xb4, 0xd9]), Ok(Bitcoin));
assert_eq!(deserialize(vec![0x0b, 0x11, 0x09, 0x07]), Ok(BitcoinTestnet)); assert_eq!(deserialize(vec![0x0b, 0x11, 0x09, 0x07]), Ok(BitcoinTestnet));
let bad: Result<Network, _> = deserialize(Vec::from_slice("fakenet".as_bytes())); let bad: Result<Network, _> = deserialize("fakenet".as_bytes().to_vec());
assert!(bad.is_err()); assert!(bad.is_err());
} }
} }

View File

@ -94,10 +94,10 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for VarInt {
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
let &VarInt(n) = self; let &VarInt(n) = self;
match n { match n {
0..0xFC => { (n as u8).consensus_encode(s) } 0...0xFC => { (n as u8).consensus_encode(s) }
0xFD..0xFFFF => { try!(s.emit_u8(0xFD)); (n as u16).consensus_encode(s) } 0xFD...0xFFFF => { try!(s.emit_u8(0xFD)); (n as u16).consensus_encode(s) }
0x10000..0xFFFFFFFF => { try!(s.emit_u8(0xFE)); (n as u32).consensus_encode(s) } 0x10000...0xFFFFFFFF => { try!(s.emit_u8(0xFE)); (n as u32).consensus_encode(s) }
_ => { try!(s.emit_u8(0xFF)); (n as u64).consensus_encode(s) } _ => { try!(s.emit_u8(0xFF)); (n as u64).consensus_encode(s) }
} }
} }
} }
@ -173,9 +173,9 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for String {
// Arrays // Arrays
macro_rules! impl_array( macro_rules! impl_array {
( $size:expr ) => ( ( $size:expr ) => (
impl<S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for [T, ..$size] { impl<S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for [T; $size] {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
for i in self.iter() { try!(i.consensus_encode(s)); } for i in self.iter() { try!(i.consensus_encode(s)); }
@ -183,25 +183,25 @@ macro_rules! impl_array(
} }
} }
impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>+Copy> ConsensusDecodable<D, E> for [T, ..$size] { impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>+Copy> ConsensusDecodable<D, E> for [T; $size] {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<[T, ..$size], E> { fn consensus_decode(d: &mut D) -> Result<[T; $size], E> {
// Set everything to the first decode // Set everything to the first decode
let mut ret = [try!(ConsensusDecodable::consensus_decode(d)), ..$size]; let mut ret = [try!(ConsensusDecodable::consensus_decode(d)); $size];
// Set the rest // Set the rest
for i in range(1, $size) { ret[i] = try!(ConsensusDecodable::consensus_decode(d)); } for i in range(1, $size) { ret[i] = try!(ConsensusDecodable::consensus_decode(d)); }
Ok(ret) Ok(ret)
} }
} }
); );
) }
impl_array!(2) impl_array!(2);
impl_array!(4) impl_array!(4);
impl_array!(8) impl_array!(8);
impl_array!(12) impl_array!(12);
impl_array!(16) impl_array!(16);
impl_array!(32) impl_array!(32);
impl<'a, S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for &'a [T] { impl<'a, S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for &'a [T] {
#[inline] #[inline]
@ -224,7 +224,7 @@ impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>> ConsensusDecodable<D, E>
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<Vec<T>, E> { fn consensus_decode(d: &mut D) -> Result<Vec<T>, E> {
let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d)); let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d));
let mut ret = Vec::with_capacity(len as uint); let mut ret = Vec::with_capacity(len as usize);
for _ in range(0, len) { ret.push(try!(ConsensusDecodable::consensus_decode(d))); } for _ in range(0, len) { ret.push(try!(ConsensusDecodable::consensus_decode(d))); }
Ok(ret) Ok(ret)
} }
@ -247,7 +247,7 @@ impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>> ConsensusDecodable<D, E>
// Huge danger: if this fails, the remaining uninitialized part of the ThinVec // Huge danger: if this fails, the remaining uninitialized part of the ThinVec
// will be freed. This is ok, but only because the memory is u8, which has no // will be freed. This is ok, but only because the memory is u8, which has no
// destructor...and assuming there are no trap representations...very fragile. // destructor...and assuming there are no trap representations...very fragile.
for i in range(0, len as uint) { ret.init(i, try!(ConsensusDecodable::consensus_decode(d))); } for i in range(0, len as usize) { ret.init(i, try!(ConsensusDecodable::consensus_decode(d))); }
Ok(ret) Ok(ret)
} }
} }
@ -282,9 +282,9 @@ impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>> ConsensusDecodable<D, E>
/// Do a double-SHA256 on some data and return the first 4 bytes /// Do a double-SHA256 on some data and return the first 4 bytes
fn sha2_checksum(data: &[u8]) -> [u8, ..4] { fn sha2_checksum(data: &[u8]) -> [u8; 4] {
let checksum = Sha256dHash::from_data(data); let checksum = Sha256dHash::from_data(data);
[checksum[0u], checksum[1u], checksum[2u], checksum[3u]] [checksum[0], checksum[1], checksum[2], checksum[3]]
} }
// Checked data // Checked data
@ -293,7 +293,7 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for CheckedData {
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
let &CheckedData(ref data) = self; let &CheckedData(ref data) = self;
try!((data.len() as u32).consensus_encode(s)); try!((data.len() as u32).consensus_encode(s));
try!(sha2_checksum(data.as_slice()).consensus_encode(s)) try!(sha2_checksum(data.as_slice()).consensus_encode(s));
// We can't just pass to the slice encoder since it'll insert a length // We can't just pass to the slice encoder since it'll insert a length
for ch in data.iter() { for ch in data.iter() {
try!(ch.consensus_encode(s)); try!(ch.consensus_encode(s));
@ -306,8 +306,8 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for CheckedData {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<CheckedData, E> { fn consensus_decode(d: &mut D) -> Result<CheckedData, E> {
let len: u32 = try!(ConsensusDecodable::consensus_decode(d)); let len: u32 = try!(ConsensusDecodable::consensus_decode(d));
let checksum: [u8, ..4] = try!(ConsensusDecodable::consensus_decode(d)); let checksum: [u8; 4] = try!(ConsensusDecodable::consensus_decode(d));
let mut ret = Vec::with_capacity(len as uint); let mut ret = Vec::with_capacity(len as usize);
for _ in range(0, len) { ret.push(try!(ConsensusDecodable::consensus_decode(d))); } for _ in range(0, len) { ret.push(try!(ConsensusDecodable::consensus_decode(d))); }
let expected_checksum = sha2_checksum(ret.as_slice()); let expected_checksum = sha2_checksum(ret.as_slice());
if expected_checksum != checksum { if expected_checksum != checksum {
@ -319,7 +319,7 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for CheckedData {
} }
// Tuples // Tuples
macro_rules! tuple_encode( macro_rules! tuple_encode {
($($x:ident),*) => ( ($($x:ident),*) => (
impl <SS:SimpleEncoder<EE>, EE, $($x: ConsensusEncodable<SS, EE>),*> ConsensusEncodable<SS, EE> for ($($x),*) { impl <SS:SimpleEncoder<EE>, EE, $($x: ConsensusEncodable<SS, EE>),*> ConsensusEncodable<SS, EE> for ($($x),*) {
#[inline] #[inline]
@ -339,12 +339,12 @@ macro_rules! tuple_encode(
} }
} }
); );
) }
tuple_encode!(A, B) tuple_encode!(A, B);
tuple_encode!(A, B, C, D) tuple_encode!(A, B, C, D);
tuple_encode!(A, B, C, D, E, F) tuple_encode!(A, B, C, D, E, F);
tuple_encode!(A, B, C, D, E, F, G, H) tuple_encode!(A, B, C, D, E, F, G, H);
// References // References
@ -356,7 +356,7 @@ impl<S:SimpleEncoder<E>, E, T: ConsensusEncodable<S, E>> ConsensusEncodable<S, E
impl<D:SimpleDecoder<E>, E, T: ConsensusDecodable<D, E>> ConsensusDecodable<D, E> for Box<T> { impl<D:SimpleDecoder<E>, E, T: ConsensusDecodable<D, E>> ConsensusDecodable<D, E> for Box<T> {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<Box<T>, E> { fn consensus_decode(d: &mut D) -> Result<Box<T>, E> {
ConsensusDecodable::consensus_decode(d).map(|res| box res) ConsensusDecodable::consensus_decode(d).map(|res| Box::new(res))
} }
} }
@ -385,7 +385,7 @@ impl<D:SimpleDecoder<E>, E, T,
fn consensus_decode(d: &mut D) -> Result<HashMap<K, V, H>, E> { fn consensus_decode(d: &mut D) -> Result<HashMap<K, V, H>, E> {
let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d)); let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d));
let mut ret = HashMap::with_capacity_and_hasher(len as uint, Default::default()); let mut ret = HashMap::with_capacity_and_hasher(len as usize, Default::default());
for _ in range(0, len) { for _ in range(0, len) {
ret.insert(try!(ConsensusDecodable::consensus_decode(d)), ret.insert(try!(ConsensusDecodable::consensus_decode(d)),
try!(ConsensusDecodable::consensus_decode(d))); try!(ConsensusDecodable::consensus_decode(d)));
@ -474,9 +474,9 @@ mod tests {
#[test] #[test]
fn serialize_box_test() { fn serialize_box_test() {
assert_eq!(serialize(&box 1u8), Ok(vec![1u8])); assert_eq!(serialize(&Box::new(1u8)), Ok(vec![1u8]));
assert_eq!(serialize(&box 1u16), Ok(vec![1u8, 0])); assert_eq!(serialize(&Box::new(1u16)), Ok(vec![1u8, 0]));
assert_eq!(serialize(&box 1u64), Ok(vec![1u8, 0, 0, 0, 0, 0, 0, 0])); assert_eq!(serialize(&Box::new(1u64)), Ok(vec![1u8, 0, 0, 0, 0, 0, 0, 0]));
} }
#[test] #[test]
@ -560,8 +560,8 @@ mod tests {
fn deserialize_box_test() { fn deserialize_box_test() {
let zero: IoResult<Box<u8>> = deserialize(vec![0u8]); let zero: IoResult<Box<u8>> = deserialize(vec![0u8]);
let one: IoResult<Box<u8>> = deserialize(vec![1u8]); let one: IoResult<Box<u8>> = deserialize(vec![1u8]);
assert_eq!(zero, Ok(box 0)); assert_eq!(zero, Ok(Box::new(0)));
assert_eq!(one, Ok(box 1)); assert_eq!(one, Ok(Box::new(1)));
} }
} }

View File

@ -21,7 +21,7 @@
use std::io::{IoResult, standard_error, ConnectionFailed}; use std::io::{IoResult, standard_error, ConnectionFailed};
use network::constants::Network; use network::constants::Network;
use network::message::{mod, SocketResponse, MessageReceived, Verack}; use network::message::{self, SocketResponse, MessageReceived, Verack};
use network::socket::Socket; use network::socket::Socket;
/// A message which can be sent on the Bitcoin network /// A message which can be sent on the Bitcoin network
@ -49,7 +49,7 @@ pub trait Listener {
try!(sock.send_message(version_message)); try!(sock.send_message(version_message));
// Message loop // Message loop
spawn(proc() { spawn(move || {
let mut handshake_complete = false; let mut handshake_complete = false;
let mut sock = sock; let mut sock = sock;
loop { loop {

View File

@ -41,7 +41,7 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for CommandString {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
let &CommandString(ref inner_str) = self; let &CommandString(ref inner_str) = self;
let mut rawbytes = [0u8, ..12]; let mut rawbytes = [0u8; 12];
rawbytes.clone_from_slice(inner_str.as_bytes().as_slice()); rawbytes.clone_from_slice(inner_str.as_bytes().as_slice());
rawbytes.consensus_encode(s) rawbytes.consensus_encode(s)
} }
@ -50,7 +50,7 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for CommandString {
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for CommandString { impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for CommandString {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<CommandString, E> { fn consensus_decode(d: &mut D) -> Result<CommandString, E> {
let rawbytes: [u8, ..12] = try!(ConsensusDecodable::consensus_decode(d)); 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 = FromIterator::from_iter(rawbytes.iter().filter_map(|&u| if u > 0 { Some(u as char) } else { None }));
Ok(CommandString(rv)) Ok(CommandString(rv))
} }

View File

@ -82,7 +82,7 @@ impl GetBlocksMessage {
} }
} }
impl_consensus_encoding!(GetBlocksMessage, version, locator_hashes, stop_hash) impl_consensus_encoding!(GetBlocksMessage, version, locator_hashes, stop_hash);
impl GetHeadersMessage { impl GetHeadersMessage {
/// Construct a new `getheaders` message /// Construct a new `getheaders` message
@ -95,7 +95,7 @@ impl GetHeadersMessage {
} }
} }
impl_consensus_encoding!(GetHeadersMessage, version, locator_hashes, stop_hash) impl_consensus_encoding!(GetHeadersMessage, version, locator_hashes, stop_hash);
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Inventory { impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Inventory {
#[inline] #[inline]
@ -119,7 +119,7 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Inventory {
1 => InvTransaction, 1 => InvTransaction,
2 => InvBlock, 2 => InvBlock,
// TODO do not fail here // TODO do not fail here
_ => { fail!("bad inventory type field") } _ => { panic!("bad inventory type field") }
}, },
hash: try!(ConsensusDecodable::consensus_decode(d)) hash: try!(ConsensusDecodable::consensus_decode(d))
}) })

View File

@ -82,7 +82,7 @@ impl VersionMessage {
impl_consensus_encoding!(VersionMessage, version, services, timestamp, impl_consensus_encoding!(VersionMessage, version, services, timestamp,
receiver, sender, nonce, receiver, sender, nonce,
user_agent, start_height, relay) user_agent, start_height, relay);
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View File

@ -34,7 +34,7 @@ use network::serialize::{RawEncoder, RawDecoder};
use util::misc::prepend_err; use util::misc::prepend_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: &ip::IpAddr) -> [u8, ..16] { fn ipaddr_to_bitcoin_addr(ipaddr: &ip::IpAddr) -> [u8; 16] {
match *ipaddr { match *ipaddr {
ip::Ipv4Addr(a, b, c, d) => ip::Ipv4Addr(a, b, c, d) =>
[0, 0, 0, 0, 0, 0, 0, 0, [0, 0, 0, 0, 0, 0, 0, 0,

View File

@ -28,18 +28,18 @@ pub enum Base58Error {
/// Checksum was not correct (expected, actual) /// Checksum was not correct (expected, actual)
BadChecksum(u32, u32), BadChecksum(u32, u32),
/// The length (in bytes) of the object was not correct /// The length (in bytes) of the object was not correct
InvalidLength(uint), InvalidLength(usize),
/// Version byte(s) were not recognized /// Version byte(s) were not recognized
InvalidVersion(Vec<u8>), InvalidVersion(Vec<u8>),
/// Checked data was less than 4 bytes /// Checked data was less than 4 bytes
TooShort(uint), TooShort(usize),
/// Any other error /// Any other error
OtherBase58Error(String) OtherBase58Error(String)
} }
static BASE58_CHARS: &'static [u8] = b"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; static BASE58_CHARS: &'static [u8] = b"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
static BASE58_DIGITS: [Option<u8>, ..128] = [ static BASE58_DIGITS: [Option<u8>; 128] = [
None, None, None, None, None, None, None, None, // 0-7 None, None, None, None, None, None, None, None, // 0-7
None, None, None, None, None, None, None, None, // 8-15 None, None, None, None, None, None, None, None, // 8-15
None, None, None, None, None, None, None, None, // 16-23 None, None, None, None, None, None, None, None, // 16-23
@ -71,14 +71,14 @@ pub trait FromBase58 {
// Build in base 256 // Build in base 256
for d58 in data.bytes() { for d58 in data.bytes() {
// Compute "X = X * 58 + next_digit" in base 256 // Compute "X = X * 58 + next_digit" in base 256
if d58 as uint > BASE58_DIGITS.len() { if d58 as usize > BASE58_DIGITS.len() {
return Err(BadByte(d58)); return Err(BadByte(d58));
} }
let mut carry = match BASE58_DIGITS[d58 as uint] { let mut carry = match BASE58_DIGITS[d58 as usize] {
Some(d58) => d58 as u32, Some(d58) => d58 as u32,
None => { return Err(BadByte(d58)); } None => { return Err(BadByte(d58)); }
}; };
for d256 in scratch.mut_iter().rev() { for d256 in scratch.iter_mut().rev() {
carry += *d256 as u32 * 58; carry += *d256 as u32 * 58;
*d256 = carry as u8; *d256 = carry as u8;
carry /= 256; carry /= 256;
@ -91,7 +91,7 @@ pub trait FromBase58 {
.map(|_| 0) .map(|_| 0)
.collect(); .collect();
// Copy rest of string // Copy rest of string
ret.extend(scratch.move_iter().skip_while(|&x| x == 0)); ret.extend(scratch.into_iter().skip_while(|&x| x == 0));
FromBase58::from_base58_layout(ret) FromBase58::from_base58_layout(ret)
} }
@ -121,8 +121,8 @@ pub fn base58_encode_slice(data: &[u8]) -> String {
for &d256 in data.base58_layout().iter() { for &d256 in data.base58_layout().iter() {
// Compute "X = X * 256 + next_digit" in base 58 // Compute "X = X * 256 + next_digit" in base 58
let mut carry = d256 as u32; let mut carry = d256 as u32;
for d58 in scratch.mut_iter().rev() { for d58 in scratch.iter_mut().rev() {
carry += *d58 as u32 << 8; carry += (*d58 as u32) << 8;
*d58 = (carry % 58) as u8; *d58 = (carry % 58) as u8;
carry /= 58; carry /= 58;
} }
@ -136,8 +136,8 @@ pub fn base58_encode_slice(data: &[u8]) -> String {
.map(|_| BASE58_CHARS[0]) .map(|_| BASE58_CHARS[0])
.collect()); .collect());
// Copy rest of string // Copy rest of string
ret.as_mut_vec().extend(scratch.move_iter().skip_while(|&x| x == 0) ret.as_mut_vec().extend(scratch.into_iter().skip_while(|&x| x == 0)
.map(|x| BASE58_CHARS[x as uint])); .map(|x| BASE58_CHARS[x as usize]));
ret ret
} }
} }
@ -164,7 +164,7 @@ pub trait ToBase58 {
// Trivial implementations for slices and vectors // Trivial implementations for slices and vectors
impl<'a> ToBase58 for &'a [u8] { impl<'a> ToBase58 for &'a [u8] {
fn base58_layout(&self) -> Vec<u8> { Vec::from_slice(*self) } fn base58_layout(&self) -> Vec<u8> { self.to_vec() }
fn to_base58(&self) -> String { base58_encode_slice(*self) } fn to_base58(&self) -> String { base58_encode_slice(*self) }
} }
@ -174,7 +174,7 @@ impl ToBase58 for Vec<u8> {
} }
impl ToBase58 for ThinVec<u8> { impl ToBase58 for ThinVec<u8> {
fn base58_layout(&self) -> Vec<u8> { Vec::from_slice(self.as_slice()) } fn base58_layout(&self) -> Vec<u8> { self.as_slice().to_vec() }
fn to_base58(&self) -> String { base58_encode_slice(self.as_slice()) } fn to_base58(&self) -> String { base58_encode_slice(self.as_slice()) }
} }

View File

@ -25,7 +25,7 @@ pub type BitcoinResult<T> = Result<T, BitcoinError>;
#[deriving(PartialEq, Eq, Show, Clone)] #[deriving(PartialEq, Eq, Show, Clone)]
pub enum BitcoinError { pub enum BitcoinError {
/// An I/O error /// An I/O error
IoError(IoError), InputOutput(IoError),
/// An object was attempted to be added twice /// An object was attempted to be added twice
DuplicateHash, DuplicateHash,
/// Some operation was attempted on a block (or blockheader) that doesn't exist /// Some operation was attempted on a block (or blockheader) that doesn't exist

View File

@ -19,10 +19,11 @@ use core::char::from_digit;
use core::cmp::min; use core::cmp::min;
use std::default::Default; use std::default::Default;
use std::fmt; use std::fmt;
use std::io::extensions::u64_from_be_bytes;
use std::io::MemWriter; use std::io::MemWriter;
use std::mem::transmute; use std::mem::transmute;
use std::hash; use std::hash;
use serialize::json::{mod, ToJson}; use serialize::json::{self, ToJson};
use crypto::digest::Digest; use crypto::digest::Digest;
use crypto::sha2::Sha256; use crypto::sha2::Sha256;
@ -30,12 +31,11 @@ use crypto::ripemd160::Ripemd160;
use network::encodable::{ConsensusDecodable, ConsensusEncodable}; use network::encodable::{ConsensusDecodable, ConsensusEncodable};
use network::serialize::{RawEncoder, BitcoinHash, SimpleDecoder}; use network::serialize::{RawEncoder, BitcoinHash, SimpleDecoder};
use util::uint::Uint128;
use util::uint::Uint256; use util::uint::Uint256;
/// A Bitcoin hash, 32-bytes, computed from x as SHA256(SHA256(x)) /// A Bitcoin hash, 32-bytes, computed from x as SHA256(SHA256(x))
pub struct Sha256dHash([u8, ..32]); pub struct Sha256dHash([u8; 32]);
impl_array_newtype!(Sha256dHash, u8, 32) impl_array_newtype!(Sha256dHash, u8, 32);
impl ::std::fmt::Show for Sha256dHash { impl ::std::fmt::Show for Sha256dHash {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
@ -44,12 +44,18 @@ impl ::std::fmt::Show for Sha256dHash {
} }
/// A RIPEMD-160 hash /// A RIPEMD-160 hash
pub struct Ripemd160Hash([u8, ..20]); pub struct Ripemd160Hash([u8; 20]);
impl_array_newtype!(Ripemd160Hash, u8, 20) impl_array_newtype!(Ripemd160Hash, u8, 20);
/// A "hasher" which just truncates /// 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
#[deriving(Clone, PartialEq, Eq, Show)]
pub struct DumbHasher; pub struct DumbHasher;
/// The state of a `DumbHasher`
pub struct DumbHasherState([u8; 8]);
/// A 32-bit hash obtained by truncating a real hash /// A 32-bit hash obtained by truncating a real hash
#[deriving(Clone, PartialEq, Eq, Show)] #[deriving(Clone, PartialEq, Eq, Show)]
pub struct Hash32((u8, u8, u8, u8)); pub struct Hash32((u8, u8, u8, u8));
@ -64,65 +70,34 @@ 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. // Allow these to be used as a key for Rust's HashMap et. al.
impl hash::Hash<u64> for Sha256dHash { impl hash::Hash<DumbHasherState> for Sha256dHash {
#[inline] #[inline]
fn hash(&self, state: &mut u64) { fn hash(&self, state: &mut DumbHasherState) {
use std::mem; let &Sha256dHash(ref hash) = self;
let myarr: [u64, ..4] = unsafe { mem::transmute(*self) }; let &DumbHasherState(ref mut arr) = state;
*state = myarr[0]; for i in range(0, 8) {
arr[i] += hash[i];
}
} }
} }
impl hash::Hash<u64> for Uint256 { impl hash::Hasher<DumbHasherState> for DumbHasher {
#[inline] #[inline]
fn hash(&self, state: &mut u64) { fn hash<T: hash::Hash<DumbHasherState>>(&self, value: &T) -> u64 {
use std::mem; let mut ret = DumbHasherState([0; 8]);
let myarr: [u64, ..4] = unsafe { mem::transmute(*self) };
*state = myarr[0];
}
}
impl hash::Hash<u64> for Uint128 {
#[inline]
fn hash(&self, state: &mut u64) {
use std::mem;
let myarr: [u64, ..2] = unsafe { mem::transmute(*self) };
*state = myarr[0];
}
}
impl hash::Hash<u64> for Hash32 {
#[inline]
fn hash(&self, state: &mut u64) {
let &Hash32((a, b, c, d)) = self;
*state = a as u64 + (b as u64 << 8) + (c as u64 << 16) + (d as u64 << 24);
}
}
impl hash::Hash<u64> for Hash48 {
#[inline]
fn hash(&self, state: &mut u64) {
let &Hash48((a, b, c, d, e, f)) = self;
*state = a as u64 + (b as u64 << 8) + (c as u64 << 16) + (d as u64 << 24) +
(e as u64 << 32) + (f as u64 << 40);
}
}
impl hash::Hash<u64> for Hash64 {
#[inline]
fn hash(&self, state: &mut u64) {
let &Hash64((a, b, c, d, e, f, g, h)) = self;
*state = a as u64 + (b as u64 << 8) + (c as u64 << 16) + (d as u64 << 24) +
(e as u64 << 32) + (f as u64 << 40) + (g as u64 << 48) + (h as u64 << 56);
}
}
impl hash::Hasher<u64> for DumbHasher {
#[inline]
fn hash<T: hash::Hash<u64>>(&self, value: &T) -> u64 {
let mut ret = 0u64;
value.hash(&mut ret); value.hash(&mut ret);
ret let DumbHasherState(res) = ret;
u64_from_be_bytes(res.as_slice(), 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;
}
} }
} }
@ -134,7 +109,7 @@ impl Default for DumbHasher {
impl Ripemd160Hash { impl Ripemd160Hash {
/// Create a hash by hashing some data /// Create a hash by hashing some data
pub fn from_data(data: &[u8]) -> Ripemd160Hash { pub fn from_data(data: &[u8]) -> Ripemd160Hash {
let mut ret = [0, ..20]; let mut ret = [0; 20];
let mut rmd = Ripemd160::new(); let mut rmd = Ripemd160::new();
rmd.input(data); rmd.input(data);
rmd.result(ret.as_mut_slice()); rmd.result(ret.as_mut_slice());
@ -146,7 +121,7 @@ impl Ripemd160Hash {
// in the C++ reference client // in the C++ reference client
impl Default for Sha256dHash { impl Default for Sha256dHash {
#[inline] #[inline]
fn default() -> Sha256dHash { Sha256dHash([0u8, ..32]) } fn default() -> Sha256dHash { Sha256dHash([0u8; 32]) }
} }
impl Sha256dHash { impl Sha256dHash {
@ -166,8 +141,8 @@ impl Sha256dHash {
#[inline] #[inline]
pub fn into_le(self) -> Uint256 { pub fn into_le(self) -> Uint256 {
let Sha256dHash(data) = self; let Sha256dHash(data) = self;
let mut ret: [u64, ..4] = unsafe { transmute(data) }; let mut ret: [u64; 4] = unsafe { transmute(data) };
for x in ret.as_mut_slice().mut_iter() { *x = x.to_le(); } for x in ret.as_mut_slice().iter_mut() { *x = x.to_le(); }
Uint256(ret) Uint256(ret)
} }
@ -176,8 +151,8 @@ impl Sha256dHash {
pub fn into_be(self) -> Uint256 { pub fn into_be(self) -> Uint256 {
let Sha256dHash(mut data) = self; let Sha256dHash(mut data) = self;
data.reverse(); data.reverse();
let mut ret: [u64, ..4] = unsafe { transmute(data) }; let mut ret: [u64; 4] = unsafe { transmute(data) };
for x in ret.mut_iter() { *x = x.to_be(); } for x in ret.iter_mut() { *x = x.to_be(); }
Uint256(ret) Uint256(ret)
} }
@ -209,9 +184,9 @@ impl Sha256dHash {
pub fn le_hex_string(&self) -> String { pub fn le_hex_string(&self) -> String {
let &Sha256dHash(data) = self; let &Sha256dHash(data) = self;
let mut ret = String::with_capacity(64); let mut ret = String::with_capacity(64);
for i in range(0u, 32) { for i in range(0, 32) {
ret.push_char(from_digit((data[i] / 0x10) as uint, 16).unwrap()); ret.push_char(from_digit((data[i] / 0x10) as usize, 16).unwrap());
ret.push_char(from_digit((data[i] & 0x0f) as uint, 16).unwrap()); ret.push_char(from_digit((data[i] & 0x0f) as usize, 16).unwrap());
} }
ret ret
} }
@ -220,9 +195,9 @@ impl Sha256dHash {
pub fn be_hex_string(&self) -> String { pub fn be_hex_string(&self) -> String {
let &Sha256dHash(data) = self; let &Sha256dHash(data) = self;
let mut ret = String::with_capacity(64); let mut ret = String::with_capacity(64);
for i in range(0u, 32).rev() { for i in range(0, 32).rev() {
ret.push_char(from_digit((data[i] / 0x10) as uint, 16).unwrap()); ret.push_char(from_digit((data[i] / 0x10) as usize, 16).unwrap());
ret.push_char(from_digit((data[i] & 0x0f) as uint, 16).unwrap()); ret.push_char(from_digit((data[i] & 0x0f) as usize, 16).unwrap());
} }
ret ret
} }
@ -258,7 +233,7 @@ impl<D: ::serialize::Decoder<E>, E> ::serialize::Decodable<D, E> for Sha256dHash
} }
let raw_str = try!(hex_str.as_slice().from_hex() let raw_str = try!(hex_str.as_slice().from_hex()
.map_err(|_| d.error("non-hexadecimal hash string"))); .map_err(|_| d.error("non-hexadecimal hash string")));
let mut ret = [0u8, ..32]; let mut ret = [0u8; 32];
for i in range(0, 32) { for i in range(0, 32) {
ret[i] = raw_str[31 - i]; ret[i] = raw_str[31 - i];
} }
@ -267,19 +242,19 @@ impl<D: ::serialize::Decoder<E>, E> ::serialize::Decodable<D, E> for Sha256dHash
} }
// Consensus encoding (little-endian) // Consensus encoding (little-endian)
impl_newtype_consensus_encoding!(Hash32) impl_newtype_consensus_encoding!(Hash32);
impl_newtype_consensus_encoding!(Hash48) impl_newtype_consensus_encoding!(Hash48);
impl_newtype_consensus_encoding!(Hash64) impl_newtype_consensus_encoding!(Hash64);
impl_newtype_consensus_encoding!(Sha256dHash) impl_newtype_consensus_encoding!(Sha256dHash);
impl fmt::LowerHex for Sha256dHash { impl fmt::LowerHex for Sha256dHash {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let &Sha256dHash(data) = self; let &Sha256dHash(data) = self;
let mut rv = [0, ..64]; let mut rv = [0; 64];
let mut hex = data.iter().rev().map(|n| *n).enumerate(); let mut hex = data.iter().rev().map(|n| *n).enumerate();
for (i, ch) in hex { for (i, ch) in hex {
rv[2*i] = from_digit(ch as uint / 16, 16).unwrap() as u8; rv[2*i] = from_digit(ch as usize / 16, 16).unwrap() as u8;
rv[2*i + 1] = from_digit(ch as uint % 16, 16).unwrap() as u8; rv[2*i + 1] = from_digit(ch as usize % 16, 16).unwrap() as u8;
} }
f.write(rv.as_slice()) f.write(rv.as_slice())
} }

View File

@ -41,7 +41,7 @@ impl<A, I: Iterator<A>> Iterator<(A, A)> for Pair<A, I> {
} }
#[inline] #[inline]
fn size_hint(&self) -> (uint, Option<uint>) { fn size_hint(&self) -> (usize, Option<usize>) {
match self.iter.size_hint() { match self.iter.size_hint() {
(n, None) => (n/2, None), (n, None) => (n/2, None),
(n, Some(m)) => (n/2, Some(m/2)) (n, Some(m)) => (n/2, Some(m/2))

View File

@ -62,7 +62,7 @@ pub fn prepend_err<T>(s: &str, res: IoResult<T>) -> IoResult<T> {
IoError { IoError {
kind: err.kind, kind: err.kind,
desc: err.desc, desc: err.desc,
detail: Some(format!("{:s}: {:}", s, match err.detail { Some(s) => s, None => String::new() })) detail: Some(format!("{}: {}", s, match err.detail { Some(s) => s, None => String::new() }))
} }
}) })
} }
@ -71,14 +71,14 @@ pub fn prepend_err<T>(s: &str, res: IoResult<T>) -> IoResult<T> {
pub fn consume_err<T>(s: &str, res: IoResult<T>) { pub fn consume_err<T>(s: &str, res: IoResult<T>) {
match res { match res {
Ok(_) => {}, Ok(_) => {},
Err(e) => { println!("{:s}: {:}", s, e); } Err(e) => { println!("{}: {}", s, e); }
}; };
} }
/// Search for `needle` in the vector `haystack` and remove every /// Search for `needle` in the vector `haystack` and remove every
/// instance of it, returning the number of instances removed. /// instance of it, returning the number of instances removed.
/// Loops through the vector opcode by opcode, skipping pushed data. /// Loops through the vector opcode by opcode, skipping pushed data.
pub fn script_find_and_remove(haystack: &mut Vec<u8>, needle: &[u8]) -> uint { pub fn script_find_and_remove(haystack: &mut Vec<u8>, needle: &[u8]) -> usize {
if needle.len() > haystack.len() { return 0; } if needle.len() > haystack.len() { return 0; }
if needle.len() == 0 { return 0; } if needle.len() == 0 { return 0; }

View File

@ -28,15 +28,15 @@ pub mod uint;
/// A trait which allows numbers to act as fixed-size bit arrays /// A trait which allows numbers to act as fixed-size bit arrays
pub trait BitArray { pub trait BitArray {
/// Is bit set? /// Is bit set?
fn bit(&self, idx: uint) -> bool; fn bit(&self, idx: usize) -> bool;
/// Returns an array which is just the bits from start to end /// Returns an array which is just the bits from start to end
fn bit_slice(&self, start: uint, end: uint) -> Self; fn bit_slice(&self, start: usize, end: usize) -> Self;
/// Bitwise and with `n` ones /// Bitwise and with `n` ones
fn mask(&self, n: uint) -> Self; fn mask(&self, n: usize) -> Self;
/// Trailing zeros /// Trailing zeros
fn trailing_zeros(&self) -> uint; fn trailing_zeros(&self) -> usize;
} }

View File

@ -38,7 +38,7 @@ pub struct PatriciaTree<K, V> {
skip_len: u8 skip_len: u8
} }
impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree<K, V> { impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<usize,K>+Shr<usize,K>, V> PatriciaTree<K, V> {
/// Constructs a new Patricia tree /// Constructs a new Patricia tree
pub fn new() -> PatriciaTree<K, V> { pub fn new() -> PatriciaTree<K, V> {
PatriciaTree { PatriciaTree {
@ -51,7 +51,7 @@ impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree
} }
/// Lookup a value by exactly matching `key` and return a referenc /// Lookup a value by exactly matching `key` and return a referenc
pub fn lookup_mut<'a>(&'a mut self, key: &K, key_len: uint) -> Option<&'a mut V> { pub fn lookup_mut<'a>(&'a mut self, key: &K, key_len: usize) -> Option<&'a mut V> {
// Caution: `lookup_mut` never modifies its self parameter (in fact its // Caution: `lookup_mut` never modifies its self parameter (in fact its
// internal recursion uses a non-mutable self, so we are OK to just // internal recursion uses a non-mutable self, so we are OK to just
// transmute our self pointer into a mutable self before passing it in. // transmute our self pointer into a mutable self before passing it in.
@ -60,28 +60,28 @@ impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree
} }
/// Lookup a value by exactly matching `key` and return a mutable reference /// Lookup a value by exactly matching `key` and return a mutable reference
pub fn lookup<'a>(&'a self, key: &K, key_len: uint) -> Option<&'a V> { pub fn lookup<'a>(&'a self, key: &K, key_len: usize) -> Option<&'a V> {
let mut node = self; let mut node = self;
let mut key_idx = 0; let mut key_idx = 0;
loop { loop {
// If the search key is shorter than the node prefix, there is no // If the search key is shorter than the node prefix, there is no
// way we can match, so fail. // way we can match, so fail.
if key_len - key_idx < node.skip_len as uint { if key_len - key_idx < node.skip_len as usize {
return None; return None;
} }
// Key fails to match prefix --- no match // Key fails to match prefix --- no match
if node.skip_prefix != key.bit_slice(key_idx, key_idx + node.skip_len as uint) { if node.skip_prefix != key.bit_slice(key_idx, key_idx + node.skip_len as usize) {
return None; return None;
} }
// Key matches prefix: if they are an exact match, return the data // Key matches prefix: if they are an exact match, return the data
if node.skip_len as uint == key_len - key_idx { if node.skip_len as usize == key_len - key_idx {
return node.data.as_ref(); return node.data.as_ref();
} else { } else {
// Key matches prefix: search key longer than node key, recurse // Key matches prefix: search key longer than node key, recurse
key_idx += 1 + node.skip_len as uint; key_idx += 1 + node.skip_len as usize;
let subtree = if key.bit(key_idx - 1) { &node.child_r } else { &node.child_l }; let subtree = if key.bit(key_idx - 1) { &node.child_r } else { &node.child_l };
match subtree { match subtree {
&Some(ref bx) => { &Some(ref bx) => {
@ -96,23 +96,23 @@ impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree
/// Inserts a value with key `key`, returning true on success. If a value is already /// Inserts a value with key `key`, returning true on success. If a value is already
/// stored against `key`, do nothing and return false. /// stored against `key`, do nothing and return false.
#[inline] #[inline]
pub fn insert(&mut self, key: &K, key_len: uint, value: V) -> bool { pub fn insert(&mut self, key: &K, key_len: usize, value: V) -> bool {
self.real_insert(key, key_len, value, false) self.real_insert(key, key_len, value, false)
} }
/// Inserts a value with key `key`, returning true on success. If a value is already /// Inserts a value with key `key`, returning true on success. If a value is already
/// stored against `key`, overwrite it and return false. /// stored against `key`, overwrite it and return false.
#[inline] #[inline]
pub fn insert_or_update(&mut self, key: &K, key_len: uint, value: V) -> bool { pub fn insert_or_update(&mut self, key: &K, key_len: usize, value: V) -> bool {
self.real_insert(key, key_len, value, true) self.real_insert(key, key_len, value, true)
} }
fn real_insert(&mut self, key: &K, key_len: uint, value: V, overwrite: bool) -> bool { fn real_insert(&mut self, key: &K, key_len: usize, value: V, overwrite: bool) -> bool {
let mut node = self; let mut node = self;
let mut idx = 0; let mut idx = 0;
loop { loop {
// Mask in case search key is shorter than node key // Mask in case search key is shorter than node key
let slice_len = cmp::min(node.skip_len as uint, key_len - idx); let slice_len = cmp::min(node.skip_len as usize, key_len - idx);
let masked_prefix = node.skip_prefix.mask(slice_len); let masked_prefix = node.skip_prefix.mask(slice_len);
let key_slice = key.bit_slice(idx, idx + slice_len); let key_slice = key.bit_slice(idx, idx + slice_len);
@ -128,20 +128,20 @@ impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree
let (insert, neighbor) = if key_slice.bit(diff) let (insert, neighbor) = if key_slice.bit(diff)
{ (&mut tmp.child_r, &mut tmp.child_l) } { (&mut tmp.child_r, &mut tmp.child_l) }
else { (&mut tmp.child_l, &mut tmp.child_r) }; else { (&mut tmp.child_l, &mut tmp.child_r) };
*insert = Some(box PatriciaTree { *insert = Some(Box::new(PatriciaTree {
data: None, data: None,
child_l: None, child_l: None,
child_r: None, child_r: None,
skip_prefix: key.bit_slice(idx + diff + 1, key_len), skip_prefix: key.bit_slice(idx + diff + 1, key_len),
skip_len: (key_len - idx - diff - 1) as u8 skip_len: (key_len - idx - diff - 1) as u8
}); }));
*neighbor = Some(box PatriciaTree { *neighbor = Some(Box::new(PatriciaTree {
data: value_neighbor, data: value_neighbor,
child_l: child_l, child_l: child_l,
child_r: child_r, child_r: child_r,
skip_prefix: tmp.skip_prefix >> (diff + 1), skip_prefix: tmp.skip_prefix >> (diff + 1),
skip_len: tmp.skip_len - diff as u8 - 1 skip_len: tmp.skip_len - diff as u8 - 1
}); }));
// Chop the prefix down // Chop the prefix down
tmp.skip_len = diff as u8; tmp.skip_len = diff as u8;
tmp.skip_prefix = tmp.skip_prefix.mask(diff); tmp.skip_prefix = tmp.skip_prefix.mask(diff);
@ -154,7 +154,7 @@ impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree
let slice_len = key_len - idx; let slice_len = key_len - idx;
// Search key is shorter than skip prefix: truncate the prefix and attach // Search key is shorter than skip prefix: truncate the prefix and attach
// the old data as a child // the old data as a child
if node.skip_len as uint > slice_len { if node.skip_len as usize > slice_len {
// Remove the old node's children // Remove the old node's children
let child_l = node.child_l.take(); let child_l = node.child_l.take();
let child_r = node.child_r.take(); let child_r = node.child_r.take();
@ -162,13 +162,13 @@ impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree
// Put the old data in a new child, with the remainder of the prefix // Put the old data in a new child, with the remainder of the prefix
let new_child = if node.skip_prefix.bit(slice_len) let new_child = if node.skip_prefix.bit(slice_len)
{ &mut node.child_r } else { &mut node.child_l }; { &mut node.child_r } else { &mut node.child_l };
*new_child = Some(box PatriciaTree { *new_child = Some(Box::new(PatriciaTree {
data: value_neighbor, data: value_neighbor,
child_l: child_l, child_l: child_l,
child_r: child_r, child_r: child_r,
skip_prefix: node.skip_prefix >> (slice_len + 1), skip_prefix: node.skip_prefix >> (slice_len + 1),
skip_len: node.skip_len - slice_len as u8 - 1 skip_len: node.skip_len - slice_len as u8 - 1
}); }));
// Chop the prefix down and put the new data in place // Chop the prefix down and put the new data in place
node.skip_len = slice_len as u8; node.skip_len = slice_len as u8;
node.skip_prefix = key_slice; node.skip_prefix = key_slice;
@ -176,7 +176,7 @@ impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree
return true; return true;
} }
// If we have an exact match, great, insert it // If we have an exact match, great, insert it
else if node.skip_len as uint == slice_len { else if node.skip_len as usize == slice_len {
if node.data.is_none() { if node.data.is_none() {
node.data = Some(value); node.data = Some(value);
return true; return true;
@ -189,18 +189,18 @@ impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree
// Search key longer than node key, recurse // Search key longer than node key, recurse
else { else {
let tmp = node; // hack to appease borrowck let tmp = node; // hack to appease borrowck
idx += tmp.skip_len as uint + 1; idx += tmp.skip_len as usize + 1;
let subtree = if key.bit(idx - 1) let subtree = if key.bit(idx - 1)
{ &mut tmp.child_r } else { &mut tmp.child_l }; { &mut tmp.child_r } else { &mut tmp.child_l };
// Recurse, adding a new node if necessary // Recurse, adding a new node if necessary
if subtree.is_none() { if subtree.is_none() {
*subtree = Some(box PatriciaTree { *subtree = Some(Box::new(PatriciaTree {
data: None, data: None,
child_l: None, child_l: None,
child_r: None, child_r: None,
skip_prefix: key.bit_slice(idx, key_len), skip_prefix: key.bit_slice(idx, key_len),
skip_len: key_len as u8 - idx as u8 skip_len: key_len as u8 - idx as u8
}); }));
} }
// subtree.get_mut_ref is a &mut Box<U> here, so &mut ** gets a &mut U // subtree.get_mut_ref is a &mut Box<U> here, so &mut ** gets a &mut U
node = &mut **subtree.as_mut().unwrap(); node = &mut **subtree.as_mut().unwrap();
@ -211,23 +211,23 @@ impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree
/// Deletes a value with key `key`, returning it on success. If no value with /// Deletes a value with key `key`, returning it on success. If no value with
/// the given key is found, return None /// the given key is found, return None
pub fn delete(&mut self, key: &K, key_len: uint) -> Option<V> { pub fn delete(&mut self, key: &K, key_len: usize) -> Option<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:BitArray+Eq+Zero+One+Add<K,K>+Shr<uint,K>+Shl<uint,K>, V>(tree: &mut PatriciaTree<K, V>, key: &K, key_len: uint) -> (bool, Option<V>) { fn recurse<K:BitArray+Eq+Zero+One+Add<K,K>+Shr<usize,K>+Shl<usize,K>, V>(tree: &mut PatriciaTree<K, V>, key: &K, key_len: usize) -> (bool, Option<V>) {
// If the search key is shorter than the node prefix, there is no // If the search key is shorter than the node prefix, there is no
// way we can match, so fail. // way we can match, so fail.
if key_len < tree.skip_len as uint { if key_len < tree.skip_len as usize {
return (false, None); return (false, None);
} }
// Key fails to match prefix --- no match // Key fails to match prefix --- no match
if tree.skip_prefix != key.mask(tree.skip_len as uint) { if tree.skip_prefix != key.mask(tree.skip_len as usize) {
return (false, None); return (false, None);
} }
// If we are here, the key matches the prefix // If we are here, the key matches the prefix
if tree.skip_len as uint == key_len { if tree.skip_len as usize == key_len {
// Exact match -- delete and return // Exact match -- delete and return
let ret = tree.data.take(); let ret = tree.data.take();
let bit = tree.child_r.is_some(); let bit = tree.child_r.is_some();
@ -238,17 +238,17 @@ impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree
} }
match (tree.child_l.take(), tree.child_r.take()) { match (tree.child_l.take(), tree.child_r.take()) {
(Some(_), Some(_)) => unreachable!(), (Some(_), Some(_)) => unreachable!(),
(Some(box PatriciaTree { data, child_l, child_r, skip_prefix, skip_len }), None) | (Some(Box::new(PatriciaTree { data, child_l, child_r, skip_prefix, skip_len })), None) |
(None, Some(box PatriciaTree { data, child_l, child_r, skip_prefix, skip_len })) => { (None, Some(Box::new(PatriciaTree { data, child_l, child_r, skip_prefix, skip_len }))) => {
tree.data = data; tree.data = data;
tree.child_l = child_l; tree.child_l = child_l;
tree.child_r = child_r; tree.child_r = child_r;
let new_bit = if bit { let ret: K = One::one(); let new_bit = if bit { let ret: K = One::one();
ret << (tree.skip_len as uint) } ret << (tree.skip_len as usize) }
else { Zero::zero() }; else { Zero::zero() };
tree.skip_prefix = tree.skip_prefix + tree.skip_prefix = tree.skip_prefix +
new_bit + new_bit +
(skip_prefix << (1 + tree.skip_len as uint)); (skip_prefix << (1 + tree.skip_len as usize));
tree.skip_len += 1 + skip_len; tree.skip_len += 1 + skip_len;
return (false, ret); return (false, ret);
} }
@ -258,7 +258,7 @@ impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree
} }
// Otherwise, the key is longer than the prefix and we need to recurse // Otherwise, the key is longer than the prefix and we need to recurse
let next_bit = key.bit(tree.skip_len as uint); let next_bit = key.bit(tree.skip_len as usize);
// Recursively get the return value. This awkward scope is required // Recursively get the return value. This awkward scope is required
// to shorten the time we mutably borrow the node's children -- we // to shorten the time we mutably borrow the node's children -- we
// might want to borrow the sibling later, so the borrow needs to end. // might want to borrow the sibling later, so the borrow needs to end.
@ -271,8 +271,8 @@ impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree
} }
// Otherwise, do it // Otherwise, do it
let (delete_child, ret) = recurse(&mut **target.as_mut().unwrap(), let (delete_child, ret) = recurse(&mut **target.as_mut().unwrap(),
&key.shr(&(tree.skip_len as uint + 1)), &key.shr(&(tree.skip_len as usize + 1)),
key_len - tree.skip_len as uint - 1); key_len - tree.skip_len as usize - 1);
if delete_child { if delete_child {
target.take(); target.take();
} }
@ -296,17 +296,17 @@ impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree
return (false, ret); return (false, ret);
} }
// One child? Consolidate // One child? Consolidate
(bit, Some(box PatriciaTree { data, child_l, child_r, skip_prefix, skip_len }), None) | (bit, Some(Box::new(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 })) => { (bit, None, Some(Box::new(PatriciaTree { data, child_l, child_r, skip_prefix, skip_len }))) => {
tree.data = data; tree.data = data;
tree.child_l = child_l; tree.child_l = child_l;
tree.child_r = child_r; tree.child_r = child_r;
let new_bit = if bit { let ret: K = One::one(); let new_bit = if bit { let ret: K = One::one();
ret << (tree.skip_len as uint) } ret << (tree.skip_len as usize) }
else { Zero::zero() }; else { Zero::zero() };
tree.skip_prefix = tree.skip_prefix + tree.skip_prefix = tree.skip_prefix +
new_bit + new_bit +
(skip_prefix << (1 + tree.skip_len as uint)); (skip_prefix << (1 + tree.skip_len as usize));
tree.skip_len += 1 + skip_len; tree.skip_len += 1 + skip_len;
return (false, ret); return (false, ret);
} }
@ -321,8 +321,8 @@ impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree
} }
/// Count all the nodes /// Count all the nodes
pub fn node_count(&self) -> uint { pub fn node_count(&self) -> usize {
fn recurse<K, V>(node: &Option<Box<PatriciaTree<K, V>>>) -> uint { fn recurse<K, 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
@ -354,30 +354,30 @@ impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree
impl<K:BitArray, V:Show> PatriciaTree<K, V> { impl<K:BitArray, V:Show> PatriciaTree<K, V> {
/// Print the entire tree /// Print the entire tree
pub fn print<'a>(&'a self) { pub fn print<'a>(&'a self) {
fn recurse<'a, K:BitArray, V:Show>(tree: &'a PatriciaTree<K, V>, depth: uint) { fn recurse<'a, K:BitArray, V:Show>(tree: &'a PatriciaTree<K, V>, depth: usize) {
for i in range(0, tree.skip_len as uint) { for i in range(0, tree.skip_len as usize) {
print!("{:}", if tree.skip_prefix.bit(i) { 1u } else { 0 }); print!("{:}", if tree.skip_prefix.bit(i) { 1 } else { 0 });
} }
println!(": {:}", tree.data); println!(": {:}", tree.data);
// left gets no indentation // left gets no indentation
match tree.child_l { match tree.child_l {
Some(ref t) => { Some(ref t) => {
for _ in range(0, depth + tree.skip_len as uint) { for _ in range(0, depth + tree.skip_len as usize) {
print!("-"); print!("-");
} }
print!("0"); print!("0");
recurse(&**t, depth + tree.skip_len as uint + 1); recurse(&**t, depth + tree.skip_len as usize + 1);
} }
None => { } None => { }
} }
// right one gets indentation // right one gets indentation
match tree.child_r { match tree.child_r {
Some(ref t) => { Some(ref t) => {
for _ in range(0, depth + tree.skip_len as uint) { for _ in range(0, depth + tree.skip_len as usize) {
print!("_"); print!("_");
} }
print!("1"); print!("1");
recurse(&**t, depth + tree.skip_len as uint + 1); recurse(&**t, depth + tree.skip_len as usize + 1);
} }
None => { } None => { }
} }
@ -529,8 +529,8 @@ mod tests {
use network::serialize::{deserialize, serialize}; use network::serialize::{deserialize, serialize};
use util::hash::Sha256dHash; use util::hash::Sha256dHash;
use util::uint::Uint128; use util::usize::Uint128;
use util::uint::Uint256; use util::usize::Uint256;
use util::patricia_tree::PatriciaTree; use util::patricia_tree::PatriciaTree;
#[test] #[test]
@ -601,14 +601,14 @@ mod tests {
// Do the actual test -- note that we also test insertion and deletion // Do the actual test -- note that we also test insertion and deletion
// at the root here. // at the root here.
for i in range(0u32, 10) { for i in range(0u32, 10) {
tree.insert(&Zero::zero(), i as uint, i); tree.insert(&Zero::zero(), i as usize, i);
} }
for i in range(0u32, 10) { for i in range(0u32, 10) {
let m = tree.lookup(&Zero::zero(), i as uint); let m = tree.lookup(&Zero::zero(), i as usize);
assert_eq!(m, Some(&i)); assert_eq!(m, Some(&i));
} }
for i in range(0u32, 10) { for i in range(0u32, 10) {
let m = tree.delete(&Zero::zero(), i as uint); let m = tree.delete(&Zero::zero(), i as usize);
assert_eq!(m, Some(i)); assert_eq!(m, Some(i));
} }
// Check that the chunder was unharmed // Check that the chunder was unharmed

View File

@ -44,7 +44,7 @@ impl<T> ThinVec<T> {
} else if capacity == 0 { } else if capacity == 0 {
ThinVec::new() ThinVec::new()
} else { } else {
let size = (capacity as uint).checked_mul(&mem::size_of::<T>()) let size = (capacity as usize).checked_mul(&mem::size_of::<T>())
.expect("ThinVec::reserve: capacity overflow"); .expect("ThinVec::reserve: capacity overflow");
let ptr = allocate(size, mem::min_align_of::<T>()); let ptr = allocate(size, mem::min_align_of::<T>());
ThinVec { ptr: ptr as *mut T, cap: capacity } ThinVec { ptr: ptr as *mut T, cap: capacity }
@ -55,7 +55,7 @@ impl<T> ThinVec<T> {
#[inline] #[inline]
pub fn from_vec(mut v: Vec<T>) -> ThinVec<T> { pub fn from_vec(mut v: Vec<T>) -> ThinVec<T> {
v.shrink_to_fit(); v.shrink_to_fit();
assert!(v.len() <= u32::MAX as uint); assert!(v.len() <= u32::MAX as usize);
let ret = ThinVec { ptr: v.as_mut_ptr(), cap: v.len() as u32 }; let ret = ThinVec { ptr: v.as_mut_ptr(), cap: v.len() as u32 };
unsafe { mem::forget(v); } unsafe { mem::forget(v); }
ret ret
@ -69,49 +69,49 @@ impl<T> ThinVec<T> {
/// Mutable iterator over elements of the vector /// Mutable iterator over elements of the vector
#[inline] #[inline]
pub fn mut_iter<'a>(&'a mut self) -> MutItems<'a, T> { pub fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T> {
self.as_mut_slice().mut_iter() self.as_mut_slice().iter_mut()
} }
/// Get vector as mutable slice /// Get vector as mutable slice
#[inline] #[inline]
pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] { pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
unsafe { mem::transmute(raw::Slice { data: self.ptr as *const T, len: self.cap as uint }) } unsafe { mem::transmute(raw::Slice { data: self.ptr as *const T, len: self.cap as usize }) }
} }
/// Accessor /// Accessor
#[inline] #[inline]
pub unsafe fn get<'a>(&'a self, index: uint) -> &'a T { pub unsafe fn get<'a>(&'a self, index: usize) -> &'a T {
&self.as_slice()[index] &self.as_slice()[index]
} }
/// Mutable accessor NOT for first use /// Mutable accessor NOT for first use
#[inline] #[inline]
pub unsafe fn get_mut<'a>(&'a mut self, index: uint) -> &'a mut T { pub unsafe fn get_mut<'a>(&'a mut self, index: usize) -> &'a mut T {
&mut self.as_mut_slice()[index] &mut self.as_mut_slice()[index]
} }
/// Mutable accessor for first use /// Mutable accessor for first use
#[inline] #[inline]
pub unsafe fn init<'a>(&'a mut self, index: uint, value: T) { pub unsafe fn init<'a>(&'a mut self, index: usize, value: T) {
ptr::write(&mut *self.ptr.offset(index as int), value); ptr::write(&mut *self.ptr.offset(index as isize), value);
} }
/// Returns a slice starting from `index` /// Returns a slice starting from `index`
#[inline] #[inline]
pub fn slice_from<'a>(&'a self, index: uint) -> &'a [T] { pub fn slice_from<'a>(&'a self, index: usize) -> &'a [T] {
self.as_slice().slice_from(index) self.as_slice().slice_from(index)
} }
/// Returns a slice ending just before `index` /// Returns a slice ending just before `index`
#[inline] #[inline]
pub fn slice_to<'a>(&'a self, index: uint) -> &'a [T] { pub fn slice_to<'a>(&'a self, index: usize) -> &'a [T] {
self.as_slice().slice_to(index) self.as_slice().slice_to(index)
} }
/// Returns a slice starting from `s` ending just before `e` /// Returns a slice starting from `s` ending just before `e`
#[inline] #[inline]
pub fn slice<'a>(&'a self, s: uint, e: uint) -> &'a [T] { pub fn slice<'a>(&'a self, s: usize, e: usize) -> &'a [T] {
self.as_slice().slice(s, e) self.as_slice().slice(s, e)
} }
@ -122,18 +122,18 @@ impl<T> ThinVec<T> {
if mem::size_of::<T>() == 0 { if mem::size_of::<T>() == 0 {
unsafe { mem::forget(value); } unsafe { mem::forget(value); }
} else { } else {
let old_size = (self.cap - 1) as uint * mem::size_of::<T>(); let old_size = (self.cap - 1) as usize * mem::size_of::<T>();
let new_size = self.cap as uint * mem::size_of::<T>(); let new_size = self.cap as usize * mem::size_of::<T>();
if new_size < old_size { fail!("ThinVec::push: cap overflow") } if new_size < old_size { panic!("ThinVec::push: cap overflow") }
unsafe { unsafe {
self.ptr = self.ptr =
if old_size == 0 { if old_size == 0 {
allocate(new_size, mem::min_align_of::<T>()) as *mut T allocate(new_size, mem::min_align_of::<T>()) as *mut T
} else { } else {
reallocate(self.ptr as *mut u8, new_size, reallocate(self.ptr as *mut u8, new_size,
mem::min_align_of::<T>(), self.cap as uint) as *mut T mem::min_align_of::<T>(), self.cap as usize) as *mut T
}; };
ptr::write(&mut *self.ptr.offset((self.cap - 1) as int), value); ptr::write(&mut *self.ptr.offset((self.cap - 1) as isize), value);
} }
} }
} }
@ -141,14 +141,14 @@ impl<T> ThinVec<T> {
/// Set the length of the vector to the minimum of the current capacity and new capacity /// Set the length of the vector to the minimum of the current capacity and new capacity
pub unsafe fn reserve(&mut self, new_cap: u32) { pub unsafe fn reserve(&mut self, new_cap: u32) {
if new_cap > self.cap { if new_cap > self.cap {
let new_size = (new_cap as uint).checked_mul(&mem::size_of::<T>()) let new_size = (new_cap as usize).checked_mul(&mem::size_of::<T>())
.expect("ThinVec::reserve: capacity overflow"); .expect("ThinVec::reserve: capacity overflow");
self.ptr = self.ptr =
if self.cap == 0 { if self.cap == 0 {
allocate(new_size, mem::min_align_of::<T>()) as *mut T allocate(new_size, mem::min_align_of::<T>()) as *mut T
} else { } else {
reallocate(self.ptr as *mut u8, new_size, reallocate(self.ptr as *mut u8, new_size,
mem::min_align_of::<T>(), self.cap as uint) as *mut T mem::min_align_of::<T>(), self.cap as usize) as *mut T
}; };
self.cap = new_cap; self.cap = new_cap;
} }
@ -165,29 +165,33 @@ impl<T:Clone> ThinVec<T> {
/// Push an entire slice onto the ThinVec /// Push an entire slice onto the ThinVec
#[inline] #[inline]
pub fn push_all(&mut self, other: &[T]) { pub fn push_all(&mut self, other: &[T]) {
let old_cap = self.cap as uint; let old_cap = self.cap as usize;
unsafe { self.reserve_additional(other.len() as u32); } unsafe { self.reserve_additional(other.len() as u32); }
// Copied from vec.rs, which claims this will be optimized to a memcpy // Copied from vec.rs, which claims this will be optimized to a memcpy
// if T is Copy // if T is Copy
for i in range(0, other.len()) { for i in range(0, other.len()) {
unsafe { unsafe {
ptr::write(self.as_mut_slice().unsafe_mut_ref(old_cap + i), ptr::write(self.as_mut_slice().unsafe_mut(old_cap + i),
other.unsafe_get(i).clone()); other.unsafe_get(i).clone());
} }
} }
} }
}
/// Constructor from a slice impl<T:Clone> CloneableVector<T> for ThinVec<T> {
#[inline] fn to_vec(&self) -> Vec<T> {
pub fn from_slice(v: &[T]) -> ThinVec<T> { self.as_slice().to_vec()
ThinVec::from_vec(Vec::from_slice(v)) }
fn into_vec(self) -> Vec<T> {
unsafe { Vec::from_raw_parts(self.cap as usize, self.cap as usize, self.ptr) }
} }
} }
impl<T> Slice<T> for ThinVec<T> { impl<T> Slice<T> for ThinVec<T> {
#[inline] #[inline]
fn as_slice<'a>(&'a self) -> &'a [T] { fn as_slice<'a>(&'a self) -> &'a [T] {
unsafe { mem::transmute(raw::Slice { data: self.ptr as *const T, len: self.cap as uint }) } unsafe { mem::transmute(raw::Slice { data: self.ptr as *const T, len: self.cap as usize }) }
} }
} }
@ -198,7 +202,7 @@ impl<T:Clone> Clone for ThinVec<T> {
// Copied from vec.rs, which claims this will be optimized to a memcpy // Copied from vec.rs, which claims this will be optimized to a memcpy
// if T is Copy // if T is Copy
for i in range(0, self.len()) { for i in range(0, self.len()) {
ptr::write(ret.as_mut_slice().unsafe_mut_ref(i), ptr::write(ret.as_mut_slice().unsafe_mut(i),
self.as_slice().unsafe_get(i).clone()); self.as_slice().unsafe_get(i).clone());
} }
ret ret
@ -212,7 +216,7 @@ impl<T> FromIterator<T> for ThinVec<T> {
#[inline] #[inline]
fn from_iter<I: Iterator<T>>(iter: I) -> ThinVec<T> { fn from_iter<I: Iterator<T>>(iter: I) -> ThinVec<T> {
let (lower, _) = iter.size_hint(); let (lower, _) = iter.size_hint();
assert!(lower <= u32::MAX as uint); assert!(lower <= u32::MAX as usize);
unsafe { unsafe {
let mut vector = ThinVec::with_capacity(lower as u32); let mut vector = ThinVec::with_capacity(lower as u32);
for (n, elem) in iter.enumerate() { for (n, elem) in iter.enumerate() {
@ -235,7 +239,7 @@ impl<T> Extendable<T> for ThinVec<T> {
unsafe { self.reserve_additional(lower as u32); } unsafe { self.reserve_additional(lower as u32); }
for (n, elem) in iter.enumerate() { for (n, elem) in iter.enumerate() {
if n < lower { if n < lower {
unsafe { self.init(old_cap as uint + n, elem) }; unsafe { self.init(old_cap as usize + n, elem) };
} else { } else {
self.push(elem); self.push(elem);
} }
@ -245,7 +249,7 @@ impl<T> Extendable<T> for ThinVec<T> {
impl<T> Collection for ThinVec<T> { impl<T> Collection for ThinVec<T> {
#[inline] #[inline]
fn len(&self) -> uint { self.cap as uint } fn len(&self) -> usize { self.cap as usize }
} }
impl<T:fmt::Show> fmt::Show for ThinVec<T> { impl<T:fmt::Show> fmt::Show for ThinVec<T> {
@ -273,7 +277,7 @@ impl<T> Drop for ThinVec<T> {
} }
if mem::size_of::<T>() != 0 { if mem::size_of::<T>() != 0 {
deallocate(self.ptr as *mut u8, deallocate(self.ptr as *mut u8,
self.cap as uint * mem::size_of::<T>(), self.cap as usize * mem::size_of::<T>(),
mem::min_align_of::<T>()); mem::min_align_of::<T>());
} }
} }
@ -292,12 +296,12 @@ mod tests {
let mut thinvec = ThinVec::with_capacity(cap); let mut thinvec = ThinVec::with_capacity(cap);
for i in range(0, cap) { for i in range(0, cap) {
thinvec.init(i as uint, Some(box i)); thinvec.init(i, Some(Box::new(i)));
} }
for i in range(0, cap) { for i in range(0, cap) {
assert_eq!(thinvec.get_mut(i as uint).take(), Some(box i)); assert_eq!(thinvec.get_mut(i).take(), Some(Box::new(i)));
assert_eq!(thinvec.get_mut(i as uint).take(), None); assert_eq!(thinvec.get_mut(i).take(), None);
} }
} }
} }

View File

@ -24,12 +24,12 @@ use std::num::{Zero, One};
use network::serialize::RawEncoder; use network::serialize::RawEncoder;
use util::BitArray; use util::BitArray;
macro_rules! construct_uint( macro_rules! construct_uint {
($name:ident, $n_words:expr) => ( ($name:ident, $n_words:expr) => (
/// Little-endian large integer type /// Little-endian large integer type
#[repr(C)] #[repr(C)]
pub struct $name(pub [u64, ..$n_words]); pub struct $name(pub [u64; $n_words]);
impl_array_newtype!($name, u64, $n_words) impl_array_newtype!($name, u64, $n_words);
impl $name { impl $name {
/// Conversion to u32 /// Conversion to u32
@ -41,20 +41,20 @@ macro_rules! construct_uint(
/// Return the least number of bits needed to represent the number /// Return the least number of bits needed to represent the number
#[inline] #[inline]
pub fn bits(&self) -> uint { pub fn bits(&self) -> uzise {
let &$name(ref arr) = self; let &$name(ref arr) = self;
for i in range(1u, $n_words) { for i in range(1, $n_words) {
if arr[$n_words - i] > 0 { return (0x40 * ($n_words - i + 1)) - arr[$n_words - i].leading_zeros() as uint; } if arr[$n_words - i] > 0 { return (0x40 * ($n_words - i + 1)) - arr[$n_words - i].leading_zeros() as usize; }
} }
0x40 - arr[0].leading_zeros() as uint 0x40 - arr[0].leading_zeros()
} }
/// Multiplication by u32 /// Multiplication by u32
pub fn mul_u32(&self, other: u32) -> $name { pub fn mul_u32(&self, other: u32) -> $name {
let &$name(ref arr) = self; let &$name(ref arr) = self;
let mut carry = [0u64, ..$n_words]; let mut carry = [0u64; $n_words];
let mut ret = [0u64, ..$n_words]; let mut ret = [0u64; $n_words];
for i in range(0u, $n_words) { for i in range(0, $n_words) {
let upper = other as u64 * (arr[i] >> 32); let upper = other as u64 * (arr[i] >> 32);
let lower = other as u64 * (arr[i] & 0xFFFFFFFF); let lower = other as u64 * (arr[i] & 0xFFFFFFFF);
if i < 3 { if i < 3 {
@ -69,7 +69,7 @@ macro_rules! construct_uint(
impl FromPrimitive for $name { impl FromPrimitive for $name {
#[inline] #[inline]
fn from_u64(init: u64) -> Option<$name> { fn from_u64(init: u64) -> Option<$name> {
let mut ret = [0, ..$n_words]; let mut ret = [0; $n_words];
ret[0] = init; ret[0] = init;
Some($name(ret)) Some($name(ret))
} }
@ -81,13 +81,13 @@ macro_rules! construct_uint(
} }
impl Zero for $name { impl Zero for $name {
fn zero() -> $name { $name([0, ..$n_words]) } fn zero() -> $name { $name([0; $n_words]) }
fn is_zero(&self) -> bool { *self == Zero::zero() } fn is_zero(&self) -> bool { *self == Zero::zero() }
} }
impl One for $name { impl One for $name {
fn one() -> $name { fn one() -> $name {
$name({ let mut ret = [0, ..$n_words]; ret[0] = 1; ret }) $name({ let mut ret = [0; $n_words]; ret[0] = 1; ret })
} }
} }
@ -95,10 +95,10 @@ macro_rules! construct_uint(
fn add(&self, other: &$name) -> $name { fn add(&self, other: &$name) -> $name {
let &$name(ref me) = self; let &$name(ref me) = self;
let &$name(ref you) = other; let &$name(ref you) = other;
let mut ret = [0u64, ..$n_words]; let mut ret = [0u64; $n_words];
let mut carry = [0u64, ..$n_words]; let mut carry = [0u64; $n_words];
let mut b_carry = false; let mut b_carry = false;
for i in range(0u, $n_words) { for i in range(0, $n_words) {
ret[i] = me[i] + you[i]; ret[i] = me[i] + you[i];
if i < $n_words - 1 && ret[i] < me[i] { if i < $n_words - 1 && ret[i] < me[i] {
carry[i + 1] = 1; carry[i + 1] = 1;
@ -120,7 +120,7 @@ macro_rules! construct_uint(
fn mul(&self, other: &$name) -> $name { fn mul(&self, other: &$name) -> $name {
let mut me = *self; let mut me = *self;
// TODO: be more efficient about this // TODO: be more efficient about this
for i in range(0u, 2 * $n_words) { for i in range(0, 2 * $n_words) {
me = me + me.mul_u32((other >> (32 * i)).low_u32()) << (32 * i); me = me + me.mul_u32((other >> (32 * i)).low_u32()) << (32 * i);
} }
me me
@ -131,7 +131,7 @@ macro_rules! construct_uint(
fn div(&self, other: &$name) -> $name { fn div(&self, other: &$name) -> $name {
let mut sub_copy = *self; let mut sub_copy = *self;
let mut shift_copy = *other; let mut shift_copy = *other;
let mut ret = [0u64, ..$n_words]; let mut ret = [0u64; $n_words];
let my_bits = self.bits(); let my_bits = self.bits();
let your_bits = other.bits(); let your_bits = other.bits();
@ -163,21 +163,21 @@ macro_rules! construct_uint(
impl BitArray for $name { impl BitArray for $name {
#[inline] #[inline]
fn bit(&self, index: uint) -> bool { fn bit(&self, index: usize) -> bool {
let &$name(ref arr) = self; let &$name(ref arr) = self;
arr[index / 64] & (1 << (index % 64)) != 0 arr[index / 64] & (1 << (index % 64)) != 0
} }
#[inline] #[inline]
fn bit_slice(&self, start: uint, end: uint) -> $name { fn bit_slice(&self, start: usize, end: usize) -> $name {
(self >> start).mask(end - start) (self >> start).mask(end - start)
} }
#[inline] #[inline]
fn mask(&self, n: uint) -> $name { fn mask(&self, n: usize) -> $name {
let &$name(ref arr) = self; let &$name(ref arr) = self;
let mut ret = [0, ..$n_words]; let mut ret = [0; $n_words];
for i in range(0u, $n_words) { for i in range(0, $n_words) {
if n >= 0x40 * (i + 1) { if n >= 0x40 * (i + 1) {
ret[i] = arr[i]; ret[i] = arr[i];
} else { } else {
@ -189,12 +189,12 @@ macro_rules! construct_uint(
} }
#[inline] #[inline]
fn trailing_zeros(&self) -> uint { fn trailing_zeros(&self) -> usize {
let &$name(ref arr) = self; let &$name(ref arr) = self;
for i in range(0u, $n_words - 1) { for i in range(0, $n_words - 1) {
if arr[i] > 0 { return (0x40 * i) + arr[i].trailing_zeros() as uint; } if arr[i] > 0 { return (0x40 * i) + arr[i].trailing_zeros(); }
} }
(0x40 * ($n_words - 1)) + arr[3].trailing_zeros() as uint (0x40 * ($n_words - 1)) + arr[3].trailing_zeros()
} }
} }
@ -203,8 +203,8 @@ macro_rules! construct_uint(
fn bitand(&self, other: &$name) -> $name { fn bitand(&self, other: &$name) -> $name {
let &$name(ref arr1) = self; let &$name(ref arr1) = self;
let &$name(ref arr2) = other; let &$name(ref arr2) = other;
let mut ret = [0u64, ..$n_words]; let mut ret = [0u64; $n_words];
for i in range(0u, $n_words) { for i in range(0, $n_words) {
ret[i] = arr1[i] & arr2[i]; ret[i] = arr1[i] & arr2[i];
} }
$name(ret) $name(ret)
@ -216,8 +216,8 @@ macro_rules! construct_uint(
fn bitxor(&self, other: &$name) -> $name { fn bitxor(&self, other: &$name) -> $name {
let &$name(ref arr1) = self; let &$name(ref arr1) = self;
let &$name(ref arr2) = other; let &$name(ref arr2) = other;
let mut ret = [0u64, ..$n_words]; let mut ret = [0u64; $n_words];
for i in range(0u, $n_words) { for i in range(0, $n_words) {
ret[i] = arr1[i] ^ arr2[i]; ret[i] = arr1[i] ^ arr2[i];
} }
$name(ret) $name(ret)
@ -229,8 +229,8 @@ macro_rules! construct_uint(
fn bitor(&self, other: &$name) -> $name { fn bitor(&self, other: &$name) -> $name {
let &$name(ref arr1) = self; let &$name(ref arr1) = self;
let &$name(ref arr2) = other; let &$name(ref arr2) = other;
let mut ret = [0u64, ..$n_words]; let mut ret = [0u64; $n_words];
for i in range(0u, $n_words) { for i in range(0, $n_words) {
ret[i] = arr1[i] | arr2[i]; ret[i] = arr1[i] | arr2[i];
} }
$name(ret) $name(ret)
@ -241,21 +241,21 @@ macro_rules! construct_uint(
#[inline] #[inline]
fn not(&self) -> $name { fn not(&self) -> $name {
let &$name(ref arr) = self; let &$name(ref arr) = self;
let mut ret = [0u64, ..$n_words]; let mut ret = [0u64; $n_words];
for i in range(0u, $n_words) { for i in range(0, $n_words) {
ret[i] = !arr[i]; ret[i] = !arr[i];
} }
$name(ret) $name(ret)
} }
} }
impl Shl<uint,$name> for $name { impl Shl<usize, $name> for $name {
fn shl(&self, shift: &uint) -> $name { fn shl(&self, shift: &usize) -> $name {
let &$name(ref original) = self; let &$name(ref original) = self;
let mut ret = [0u64, ..$n_words]; let mut ret = [0u64; $n_words];
let word_shift = *shift / 64; let word_shift = *shift / 64;
let bit_shift = *shift % 64; let bit_shift = *shift % 64;
for i in range(0u, $n_words) { for i in range(0, $n_words) {
// Shift // Shift
if bit_shift < 64 && i + word_shift < $n_words { if bit_shift < 64 && i + word_shift < $n_words {
ret[i + word_shift] += original[i] << bit_shift; ret[i + word_shift] += original[i] << bit_shift;
@ -269,14 +269,14 @@ macro_rules! construct_uint(
} }
} }
impl Shr<uint,$name> for $name { impl Shr<usize, $name> for $name {
#[allow(unsigned_negate)] #[allow(unsigned_negate)]
fn shr(&self, shift: &uint) -> $name { fn shr(&self, shift: &usize) -> $name {
let &$name(ref original) = self; let &$name(ref original) = self;
let mut ret = [0u64, ..$n_words]; let mut ret = [0u64; $n_words];
let word_shift = *shift / 64; let word_shift = *shift / 64;
let bit_shift = *shift % 64; let bit_shift = *shift % 64;
for i in range(0u, $n_words) { for i in range(0, $n_words) {
// Shift // Shift
if bit_shift < 64 && i - word_shift < $n_words { if bit_shift < 64 && i - word_shift < $n_words {
ret[i - word_shift] += original[i] >> bit_shift; ret[i - word_shift] += original[i] >> bit_shift;
@ -330,15 +330,15 @@ macro_rules! construct_uint(
impl<D: ::network::serialize::SimpleDecoder<E>, E> ::network::encodable::ConsensusDecodable<D, E> for $name { impl<D: ::network::serialize::SimpleDecoder<E>, E> ::network::encodable::ConsensusDecodable<D, E> for $name {
fn consensus_decode(d: &mut D) -> Result<$name, E> { fn consensus_decode(d: &mut D) -> Result<$name, E> {
use network::encodable::ConsensusDecodable; use network::encodable::ConsensusDecodable;
let ret: [u64, ..$n_words] = try!(ConsensusDecodable::consensus_decode(d)); let ret: [u64; $n_words] = try!(ConsensusDecodable::consensus_decode(d));
Ok($name(ret)) Ok($name(ret))
} }
} }
); );
) }
construct_uint!(Uint256, 4) construct_uint!(Uint256, 4);
construct_uint!(Uint128, 2) construct_uint!(Uint128, 2);
impl Uint256 { impl Uint256 {
/// Increment by 1 /// Increment by 1
@ -384,11 +384,11 @@ mod tests {
// Try to read the following lines out loud quickly // Try to read the following lines out loud quickly
let mut shl: Uint256 = from_u64(70000).unwrap(); let mut shl: Uint256 = from_u64(70000).unwrap();
shl = shl << 100u; shl = shl << 100;
assert_eq!(shl.bits(), 117); assert_eq!(shl.bits(), 117);
shl = shl << 100u; shl = shl << 100;
assert_eq!(shl.bits(), 217); assert_eq!(shl.bits(), 217);
shl = shl << 100u; shl = shl << 100;
assert_eq!(shl.bits(), 0); assert_eq!(shl.bits(), 0);
// Bit set check // Bit set check
@ -424,9 +424,9 @@ mod tests {
let add = init.add(&copy); let add = init.add(&copy);
assert_eq!(add, Uint256([0xBD5B7DDFBD5B7DDEu64, 1, 0, 0])); assert_eq!(add, Uint256([0xBD5B7DDFBD5B7DDEu64, 1, 0, 0]));
// Bitshifts // Bitshifts
let shl = add << 88u; let shl = add << 88;
assert_eq!(shl, Uint256([0u64, 0xDFBD5B7DDE000000, 0x1BD5B7D, 0])); assert_eq!(shl, Uint256([0u64, 0xDFBD5B7DDE000000, 0x1BD5B7D, 0]));
let shr = shl >> 40u; let shr = shl >> 40;
assert_eq!(shr, Uint256([0x7DDE000000000000u64, 0x0001BD5B7DDFBD5B, 0, 0])); assert_eq!(shr, Uint256([0x7DDE000000000000u64, 0x0001BD5B7DDFBD5B, 0, 0]));
// Increment // Increment
let mut incr = shr; let mut incr = shr;

View File

@ -38,15 +38,6 @@ pub struct Address {
} }
impl Address { impl Address {
/// Creates an address the raw 20 bytes of a hash
#[inline]
pub fn from_slice(network: Network, data: &[u8]) -> Address {
Address {
network: network,
hash: Ripemd160Hash::from_slice(data)
}
}
/// Returns a byteslice view of the `Address` --- note that no network information /// Returns a byteslice view of the `Address` --- note that no network information
/// is contained in this. /// is contained in this.
#[inline] #[inline]
@ -80,6 +71,22 @@ impl Address {
} }
} }
/// Conversion from other types into an address
pub trait ToAddress {
/// Copies `self` into a new `Address`
fn to_address(&self, network: Network) -> Address;
}
impl<'a> ToAddress for &'a [u8] {
#[inline]
fn to_address(&self, network: Network) -> Address {
Address {
network: network,
hash: Ripemd160Hash::from_slice(*self)
}
}
}
impl ToBase58 for Address { impl ToBase58 for Address {
fn base58_layout(&self) -> Vec<u8> { fn base58_layout(&self) -> Vec<u8> {
let mut ret = vec![ let mut ret = vec![

View File

@ -21,18 +21,46 @@
use std::collections::HashMap; use std::collections::HashMap;
use collections::hash::sip::hash_with_keys; use collections::hash::sip::hash_with_keys;
use secp256k1::key::SecretKey;
use blockdata::transaction::{TxOut, PayToPubkeyHash}; use blockdata::transaction::{TxOut, PayToPubkeyHash};
use blockdata::utxoset::UtxoSet; use blockdata::utxoset::UtxoSet;
use blockdata::script::Script; use blockdata::script::Script;
use network::constants::Network; use network::constants::Network;
use wallet::address::Address; use wallet::address::Address;
use wallet::wallet::Wallet; use wallet::wallet::Wallet;
use util::hash::Sha256dHash; use util::hash::{DumbHasher, Sha256dHash};
/// The type of a wallet-spendable txout
#[deriving(Clone, PartialEq, Eq, Show)]
pub enum WalletTxOutType {
/// Pay-to-address transaction redeemable using an ECDSA key
PayToAddress(SecretKey),
/// Undetermined
Unknown
}
/// A txout that is spendable by the wallet
#[deriving(Clone, PartialEq, Eq, Show)]
pub struct WalletTxOut {
/// The TXID of the transaction this output is part of
pub txid: Sha256dHash,
/// The index of the output in its transaction
pub vout: u32,
/// The blockheight at which this output appeared in the blockchain
pub height: u32,
/// The actual output
pub txo: TxOut,
/// A classification of the output
pub kind: WalletTxOutType
}
/// 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, Vec<(Sha256dHash, uint, TxOut, uint)>>, tentative_index: HashMap<Script, Vec<WalletTxOut>>,
index: HashMap<(Sha256dHash, u32), Vec<WalletTxOut>, DumbHasher>,
network: Network, network: Network,
k1: u64, k1: u64,
k2: u64 k2: u64
@ -44,21 +72,35 @@ impl AddressIndex {
pub fn new(utxo_set: &UtxoSet, wallet: &Wallet) -> AddressIndex { pub fn new(utxo_set: &UtxoSet, wallet: &Wallet) -> AddressIndex {
let (k1, k2) = wallet.siphash_key(); let (k1, k2) = wallet.siphash_key();
let mut ret = AddressIndex { let mut ret = AddressIndex {
index: HashMap::with_capacity(utxo_set.n_utxos() / 256), tentative_index: HashMap::with_capacity(utxo_set.n_utxos() / 256),
index: HashMap::with_hasher(DumbHasher),
network: wallet.network(), network: wallet.network(),
k1: k1, k1: k1,
k2: k2 k2: k2
}; };
for (key, idx, txo, height) in utxo_set.iter() { for (key, idx, txo, height) in utxo_set.iter() {
if ret.admissible_txo(txo) { if ret.admissible_txo(txo) {
ret.index.insert_or_update_with(txo.script_pubkey.clone(), let new = WalletTxOut {
vec![(key, idx, txo.clone(), height)], txid: key,
|_, v| v.push((key, idx, txo.clone(), height))); vout: idx,
height: height,
txo: txo.clone(),
kind: Unknown
};
ret.tentative_index.find_or_insert(txo.script_pubkey.clone(), vec![]).push(new);
} }
} }
ret ret
} }
///
#[inline]
pub fn index_wallet_txo(&mut self, wtx: &WalletTxOut, kind: WalletTxOutType) {
let mut new = wtx.clone();
new.kind = kind;
self.index.find_or_insert((wtx.txid, wtx.vout), vec![]).push(new);
}
/// A filtering function used for creating a small address index. /// A filtering function used for creating a small address index.
#[inline] #[inline]
pub fn admissible_address(&self, addr: &Address) -> bool { pub fn admissible_address(&self, addr: &Address) -> bool {
@ -77,8 +119,8 @@ impl AddressIndex {
/// Lookup a txout by its scriptpubkey. Returns a slice because there /// Lookup a txout by its scriptpubkey. Returns a slice because there
/// may be more than one for any given scriptpubkey. /// may be more than one for any given scriptpubkey.
#[inline] #[inline]
pub fn find_by_script<'a>(&'a self, pubkey: &Script) -> &'a [(Sha256dHash, uint, TxOut, uint)] { pub fn find_by_script<'a>(&'a self, pubkey: &Script) -> &'a [WalletTxOut] {
self.index.find(pubkey).map(|v| v.as_slice()).unwrap_or(&[]) self.tentative_index.find(pubkey).map(|v| v.as_slice()).unwrap_or(&[])
} }
} }

View File

@ -35,16 +35,16 @@ use util::base58::{Base58Error,
FromBase58, ToBase58}; FromBase58, ToBase58};
/// A chain code /// A chain code
pub struct ChainCode([u8, ..32]); pub struct ChainCode([u8; 32]);
impl_array_newtype!(ChainCode, u8, 32) impl_array_newtype!(ChainCode, u8, 32);
impl_array_newtype_show!(ChainCode) impl_array_newtype_show!(ChainCode);
impl_array_newtype_encodable!(ChainCode, u8, 32) impl_array_newtype_encodable!(ChainCode, u8, 32);
/// A fingerprint /// A fingerprint
pub struct Fingerprint([u8, ..4]); pub struct Fingerprint([u8; 4]);
impl_array_newtype!(Fingerprint, u8, 4) impl_array_newtype!(Fingerprint, u8, 4);
impl_array_newtype_show!(Fingerprint) impl_array_newtype_show!(Fingerprint);
impl_array_newtype_encodable!(Fingerprint, u8, 4) impl_array_newtype_encodable!(Fingerprint, u8, 4);
impl Default for Fingerprint { impl Default for Fingerprint {
fn default() -> Fingerprint { Fingerprint([0, 0, 0, 0]) } fn default() -> Fingerprint { Fingerprint([0, 0, 0, 0]) }
@ -56,7 +56,7 @@ 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,
/// How many derivations this key is from the master (which is 0) /// How many derivations this key is from the master (which is 0)
pub depth: uint, pub depth: u8,
/// Fingerprint of the parent key (0 for master) /// Fingerprint of the parent key (0 for master)
pub parent_fingerprint: Fingerprint, pub parent_fingerprint: Fingerprint,
/// Child number of the key used to derive from parent (0 for master) /// Child number of the key used to derive from parent (0 for master)
@ -73,7 +73,7 @@ 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,
/// How many derivations this key is from the master (which is 0) /// How many derivations this key is from the master (which is 0)
pub depth: uint, pub depth: u8,
/// Fingerprint of the parent key /// Fingerprint of the parent key
pub parent_fingerprint: Fingerprint, pub parent_fingerprint: Fingerprint,
/// Child number of the key used to derive from parent (0 for master) /// Child number of the key used to derive from parent (0 for master)
@ -129,7 +129,7 @@ pub enum Error {
impl ExtendedPrivKey { impl ExtendedPrivKey {
/// Construct a new master key from a seed value /// Construct a new master key from a seed value
pub fn new_master(network: Network, seed: &[u8]) -> Result<ExtendedPrivKey, Error> { pub fn new_master(network: Network, seed: &[u8]) -> Result<ExtendedPrivKey, Error> {
let mut result = [0, ..64]; let mut result = [0; 64];
let mut hmac = Hmac::new(Sha512::new(), b"Bitcoin seed".as_slice()); let mut hmac = Hmac::new(Sha512::new(), b"Bitcoin seed".as_slice());
hmac.input(seed); hmac.input(seed);
hmac.raw_result(result.as_mut_slice()); hmac.raw_result(result.as_mut_slice());
@ -156,7 +156,7 @@ impl ExtendedPrivKey {
/// Private->Private child key derivation /// Private->Private child key derivation
pub fn ckd_priv(&self, i: ChildNumber) -> Result<ExtendedPrivKey, Error> { pub fn ckd_priv(&self, i: ChildNumber) -> Result<ExtendedPrivKey, Error> {
let mut result = [0, ..64]; let mut result = [0; 64];
let mut hmac = Hmac::new(Sha512::new(), self.chain_code.as_slice()); let mut hmac = Hmac::new(Sha512::new(), self.chain_code.as_slice());
match i { match i {
Normal(n) => { Normal(n) => {
@ -190,9 +190,9 @@ impl ExtendedPrivKey {
} }
/// Returns the HASH160 of the chaincode /// Returns the HASH160 of the chaincode
pub fn identifier(&self) -> [u8, ..20] { pub fn identifier(&self) -> [u8; 20] {
let mut sha2_res = [0, ..32]; let mut sha2_res = [0; 32];
let mut ripemd_res = [0, ..20]; let mut ripemd_res = [0; 20];
// Compute extended public key // Compute extended public key
let pk = ExtendedPubKey::from_private(self); let pk = ExtendedPubKey::from_private(self);
// Do SHA256 of just the ECDSA pubkey // Do SHA256 of just the ECDSA pubkey
@ -242,7 +242,7 @@ impl ExtendedPubKey {
hmac.input(self.public_key.as_slice()); hmac.input(self.public_key.as_slice());
u64_to_be_bytes(n as u64, 4, |raw| hmac.input(raw)); u64_to_be_bytes(n as u64, 4, |raw| hmac.input(raw));
let mut result = [0, ..64]; let mut result = [0; 64];
hmac.raw_result(result.as_mut_slice()); hmac.raw_result(result.as_mut_slice());
let sk = try!(SecretKey::from_slice(result.slice_to(32)).map_err(EcdsaError)); let sk = try!(SecretKey::from_slice(result.slice_to(32)).map_err(EcdsaError));
@ -262,9 +262,9 @@ impl ExtendedPubKey {
} }
/// Returns the HASH160 of the chaincode /// Returns the HASH160 of the chaincode
pub fn identifier(&self) -> [u8, ..20] { pub fn identifier(&self) -> [u8; 20] {
let mut sha2_res = [0, ..32]; let mut sha2_res = [0; 32];
let mut ripemd_res = [0, ..20]; let mut ripemd_res = [0; 20];
// Do SHA256 of just the ECDSA pubkey // Do SHA256 of just the ECDSA pubkey
let mut sha2 = Sha256::new(); let mut sha2 = Sha256::new();
sha2.input(self.public_key.as_slice()); sha2.input(self.public_key.as_slice());
@ -321,9 +321,9 @@ impl FromBase58 for ExtendedPrivKey {
network: match data.slice_to(4) { network: match data.slice_to(4) {
[0x04, 0x88, 0xAD, 0xE4] => Bitcoin, [0x04, 0x88, 0xAD, 0xE4] => Bitcoin,
[0x04, 0x35, 0x83, 0x94] => BitcoinTestnet, [0x04, 0x35, 0x83, 0x94] => BitcoinTestnet,
_ => { return Err(InvalidVersion(Vec::from_slice(data.slice_to(4)))); } _ => { return Err(InvalidVersion(data.slice_to(4).to_vec())); }
}, },
depth: data[4] as uint, depth: data[4],
parent_fingerprint: Fingerprint::from_slice(data.slice(5, 9)), parent_fingerprint: Fingerprint::from_slice(data.slice(5, 9)),
child_number: child_number, child_number: child_number,
chain_code: ChainCode::from_slice(data.slice(13, 45)), chain_code: ChainCode::from_slice(data.slice(13, 45)),
@ -372,9 +372,9 @@ impl FromBase58 for ExtendedPubKey {
network: match data.slice_to(4) { network: match data.slice_to(4) {
[0x04, 0x88, 0xB2, 0x1E] => Bitcoin, [0x04, 0x88, 0xB2, 0x1E] => Bitcoin,
[0x04, 0x35, 0x87, 0xCF] => BitcoinTestnet, [0x04, 0x35, 0x87, 0xCF] => BitcoinTestnet,
_ => { return Err(InvalidVersion(Vec::from_slice(data.slice_to(4)))); } _ => { return Err(InvalidVersion(data.slice_to(4).to_vec())); }
}, },
depth: data[4] as uint, depth: data[4],
parent_fingerprint: Fingerprint::from_slice(data.slice(5, 9)), parent_fingerprint: Fingerprint::from_slice(data.slice(5, 9)),
child_number: child_number, child_number: child_number,
chain_code: ChainCode::from_slice(data.slice(13, 45)), chain_code: ChainCode::from_slice(data.slice(13, 45)),

View File

@ -25,7 +25,7 @@ use secp256k1::key::PublicKey;
use blockdata::utxoset::UtxoSet; use blockdata::utxoset::UtxoSet;
use network::constants::Network; use network::constants::Network;
use wallet::bip32::{mod, ChildNumber, ExtendedPrivKey, ExtendedPubKey, Normal, Hardened}; use wallet::bip32::{self, ChildNumber, ExtendedPrivKey, ExtendedPubKey, Normal, Hardened};
use wallet::address::Address; use wallet::address::Address;
use wallet::address_index::AddressIndex; use wallet::address_index::AddressIndex;
@ -273,8 +273,8 @@ impl Wallet {
let sk = try!(master.ckd_priv(cnum).map_err(Bip32Error)); let sk = try!(master.ckd_priv(cnum).map_err(Bip32Error));
let pk = ExtendedPubKey::from_private(&sk); let pk = ExtendedPubKey::from_private(&sk);
let addr = Address::from_key(pk.network, &pk.public_key); let addr = Address::from_key(pk.network, &pk.public_key);
for &(_, _, ref out, _) in index.find_by_script(&addr.script_pubkey()).iter() { for out in index.find_by_script(&addr.script_pubkey()).iter() {
ret += out.value; ret += out.txo.value;
} }
} }
// Sum external balance // Sum external balance
@ -285,8 +285,8 @@ impl Wallet {
let sk = try!(master.ckd_priv(cnum).map_err(Bip32Error)); let sk = try!(master.ckd_priv(cnum).map_err(Bip32Error));
let pk = ExtendedPubKey::from_private(&sk); let pk = ExtendedPubKey::from_private(&sk);
let addr = Address::from_key(pk.network, &pk.public_key); let addr = Address::from_key(pk.network, &pk.public_key);
for &(_, _, ref out, _) in index.find_by_script(&addr.script_pubkey()).iter() { for out in index.find_by_script(&addr.script_pubkey()).iter() {
ret += out.value; ret += out.txo.value;
} }
} }