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 unshifted_expt = self.bits >> 24;
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 {
(self.bits & 0xFFFFFF, 8 * ((self.bits >> 24) - 3))
}
@ -89,7 +89,7 @@ impl BlockHeader {
if mant > 0x7FFFFF {
Zero::zero()
} 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_json!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce)
impl_consensus_encoding!(Block, header, txdata)
impl_consensus_encoding!(LoneBlockHeader, header, tx_count)
impl_consensus_encoding!(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!(LoneBlockHeader, header, tx_count);
#[cfg(test)]
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.
struct LocatorHashIter {
index: NodePtr,
count: uint,
skip: uint
count: usize,
skip: usize
}
impl LocatorHashIter {
@ -341,7 +341,7 @@ impl Blockchain {
pub fn new(network: Network) -> Blockchain {
let genesis = genesis_block(network);
let genhash = genesis.header.bitcoin_hash();
let new_node = box BlockchainNode {
let new_node = Box::new(BlockchainNode {
total_work: Zero::zero(),
required_difficulty: genesis.header.target(),
block: genesis,
@ -349,7 +349,7 @@ impl Blockchain {
has_txdata: true,
prev: RawPtr::null(),
next: RawPtr::null()
};
});
let raw_ptr = &*new_node as NodePtr;
Blockchain {
network: network,
@ -490,7 +490,7 @@ impl Blockchain {
unsafe { (*prev).required_difficulty }
};
// Create node
let ret = box BlockchainNode {
let ret = Box::new(BlockchainNode {
total_work: block.header.work().add(unsafe { &(*prev).total_work }),
block: block,
required_difficulty: difficulty,
@ -498,7 +498,7 @@ impl Blockchain {
has_txdata: has_txdata,
prev: prev,
next: RawPtr::null()
};
});
unsafe {
let prev = prev as *mut BlockchainNode;
(*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)
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,

View File

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

View File

@ -98,9 +98,9 @@ pub enum ScriptError {
/// An OP_RETURN or synonym was executed
ExecutedReturn,
/// A multisig tx with negative or too many keys
MultisigBadKeyCount(int),
MultisigBadKeyCount(isize),
/// A multisig tx with negative or too many signatures
MultisigBadSigCount(int),
MultisigBadSigCount(isize),
/// Used OP_PICK with a negative index
NegativePick,
/// Used OP_ROLL with a negative index
@ -126,15 +126,15 @@ pub enum ScriptError {
/// A rule for validating an abstract stack element
pub struct Validator {
/// 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
/// 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
/// value, if it has a value, otherwise updates the element's value
/// based on the current stack, if possible. Returns `false` if it
/// is forced to do something inconsistent.
update: fn(&mut AbstractStackElem, &[uint]) -> Result<(), ScriptError>
update: fn(&mut AbstractStackElem, &[usize]) -> Result<(), ScriptError>
}
impl Clone for Validator {
@ -148,13 +148,13 @@ impl Clone for Validator {
}
// 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]) };
elem.num_hi() >= other.len_lo() 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> {
let (lo, hi) = {
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)
}
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 two = unsafe { elem.lookup(others[1]) };
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> {
match elem.bool_value() {
None => update_boolean(elem),
@ -240,8 +240,8 @@ fn update_op_equal(elem: &mut AbstractStackElem, others: &[uint])
(Some(_), Some(_)) => { return Err(Unsatisfiable); }
}
// Equalize full values
match (one.raw_value().map(|r| Vec::from_slice(r)),
two.raw_value().map(|r| Vec::from_slice(r))) {
match (one.raw_value().map(|r| r.to_vec()),
two.raw_value().map(|r| r.to_vec())) {
(None, None) => {},
(None, Some(x)) => try!(one.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]) };
if !one.may_be_numeric() {
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> {
match elem.bool_value() {
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]) };
if !one.may_be_numeric() { return false; }
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> {
match elem.bool_value() {
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 two = unsafe { elem.lookup(others[1]) };
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> {
match elem.bool_value() {
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 two = unsafe { elem.lookup(others[1]) };
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> {
match elem.bool_value() {
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 two = unsafe { elem.lookup(others[1]) };
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> {
match elem.bool_value() {
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 two = unsafe { elem.lookup(others[1]) };
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> {
match elem.bool_value() {
None => try!(update_boolean(elem)),
@ -478,7 +478,7 @@ fn update_op_numgt(elem: &mut AbstractStackElem, others: &[uint])
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 two = unsafe { elem.lookup(others[1]) };
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> {
match elem.bool_value() {
None => try!(update_boolean(elem)),
@ -516,7 +516,7 @@ fn update_op_numlteq(elem: &mut AbstractStackElem, others: &[uint])
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 two = unsafe { elem.lookup(others[1]) };
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> {
match elem.bool_value() {
None => try!(update_boolean(elem)),
@ -554,11 +554,11 @@ fn update_op_numgteq(elem: &mut AbstractStackElem, others: &[uint])
Ok(())
}
fn check_op_ripemd160(elem: &AbstractStackElem, _: &[uint]) -> bool {
fn check_op_ripemd160(elem: &AbstractStackElem, _: &[usize]) -> bool {
elem.may_be_hash160()
}
fn update_op_ripemd160(elem: &mut AbstractStackElem, others: &[uint])
fn update_op_ripemd160(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> {
try!(elem.set_len_lo(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()
}
fn update_op_sha1(elem: &mut AbstractStackElem, others: &[uint])
fn update_op_sha1(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> {
try!(elem.set_len_lo(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()
}
fn update_op_hash160(elem: &mut AbstractStackElem, others: &[uint])
fn update_op_hash160(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> {
try!(elem.set_len_lo(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()
}
fn update_op_sha256(elem: &mut AbstractStackElem, others: &[uint])
fn update_op_sha256(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> {
try!(elem.set_len_lo(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()
}
fn update_op_hash256(elem: &mut AbstractStackElem, others: &[uint])
fn update_op_hash256(elem: &mut AbstractStackElem, others: &[usize])
-> Result<(), ScriptError> {
try!(elem.set_len_lo(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 two = unsafe { elem.lookup(others[1]) };
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> {
match elem.bool_value() {
None => update_boolean(elem),
@ -732,13 +732,13 @@ pub struct AbstractStackElem {
/// Upper bound when read as number
num_hi: i64,
/// Length lower bound
len_lo: uint,
len_lo: usize,
/// Length upper bound
len_hi: uint,
len_hi: usize,
/// Relations this must satisfy
validators: Vec<Validator>,
/// Index of the element in its stack allocator
alloc_index: Option<uint>
alloc_index: Option<usize>
}
impl AbstractStackElem {
@ -771,7 +771,7 @@ impl AbstractStackElem {
len_lo: data.len(),
len_hi: data.len(),
bool_val: Some(read_scriptbool(data)),
raw: Some(Vec::from_slice(data)),
raw: Some(data.to_vec()),
validators: vec![],
alloc_index: None
}
@ -792,17 +792,17 @@ impl AbstractStackElem {
}
/// 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 myidx = self.alloc_index.unwrap() as int;
&*mypos.offset(idx as int - myidx)
let myidx = self.alloc_index.unwrap() as isize;
&*mypos.offset(idx as isize - myidx)
}
/// 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 myidx = self.alloc_index.unwrap() as int;
&mut *mypos.offset(idx as int - myidx)
let myidx = self.alloc_index.unwrap() as isize;
&mut *mypos.offset(idx as isize - myidx)
}
/// 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
/// exists as a finite value, though the default upper limit is some
/// impractically large number
pub fn len_hi(&self) -> uint {
pub fn len_hi(&self) -> usize {
self.len_hi
}
/// Retrieve the lower bound for this element's length. This always
/// exists since it is at least zero :)
pub fn len_lo(&self) -> uint {
pub fn len_lo(&self) -> usize {
self.len_lo
}
@ -901,7 +901,7 @@ impl AbstractStackElem {
/// Sets the entire value of the
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) } }
None => {
try!(self.set_len_lo(val.len()));
@ -915,7 +915,7 @@ impl AbstractStackElem {
Err(_) => {}
}
try!(self.set_bool_value(read_scriptbool(val)));
self.raw = Some(Vec::from_slice(val));
self.raw = Some(val.to_vec());
Ok(())
}
}
@ -1012,7 +1012,7 @@ impl AbstractStackElem {
}
/// 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 {
self.len_lo = value;
if value > 0 { try!(self.set_bool_value(true)); }
@ -1023,7 +1023,7 @@ impl AbstractStackElem {
}
/// 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 {
self.len_hi = value;
try!(self.update());
@ -1043,11 +1043,11 @@ impl AbstractStackElem {
#[deriving(Clone)]
pub struct AbstractStack {
/// Actual elements on the stack
stack: Vec<uint>,
stack: Vec<usize>,
/// Actual elements on the altstack
alt_stack: Vec<uint>,
alt_stack: Vec<usize>,
/// 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
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());
self.alloc.push(elem);
self.alloc.len() - 1
@ -1084,24 +1084,24 @@ impl AbstractStack {
/// Increase the stack size to `n`, adding elements to the initial
/// 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 {
self.push_initial(AbstractStackElem::new_unknown());
}
}
/// 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]
}
/// 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)
}
/// 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);
}
@ -1123,7 +1123,7 @@ impl AbstractStack {
}
/// 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 {
self.push_initial(AbstractStackElem::new_unknown());
}
@ -1131,7 +1131,7 @@ impl AbstractStack {
}
/// Drop the top stack item
fn pop(&mut self) -> uint {
fn pop(&mut self) -> usize {
if self.stack.len() == 0 {
self.push_initial(AbstractStackElem::new_unknown());
}
@ -1171,28 +1171,28 @@ impl AbstractStack {
/// Immutable view of the current stack as a slice (to be compatible
/// 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()
}
/// 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)
}
/// Mutable view of the current stack as a slice (to be compatible
/// 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()
}
/// Length of the current stack
fn len(&self) -> uint {
fn len(&self) -> usize {
self.stack.len()
}
/// 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);
}
}
@ -1206,8 +1206,8 @@ impl json::ToJson for ScriptError {
/// A single iteration of a script execution
#[deriving(PartialEq, Eq, Show, Clone)]
pub struct TraceIteration {
index: uint,
op_count: uint,
index: usize,
op_count: usize,
opcode: allops::Opcode,
executed: bool,
errored: bool,
@ -1228,7 +1228,7 @@ pub struct ScriptTrace {
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,
/// specifically in the last 5 bits `byte & 31`
@ -1269,7 +1269,7 @@ pub enum MaybeOwned<'a> {
/// Freshly allocated memory
Owned(Vec<u8>),
/// Pointer into the original script
Slice(&'a [u8])
Borrowed(&'a [u8])
}
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] {
match *self {
Owned(ref v) => v.as_slice(),
Slice(ref s) => s.as_slice()
Borrowed(ref s) => s.as_slice()
}
}
}
impl<'a> Collection for MaybeOwned<'a> {
#[inline]
fn len(&self) -> uint {
fn len(&self) -> usize {
match *self {
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 mut abs = if neg { -n } else { n } as uint;
let mut abs = if neg { -n } else { n } as usize;
let mut v = vec![];
while abs > 0xFF {
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); }
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 {
ret &= (1 << sh - 1) - 1;
ret = -ret;
@ -1366,12 +1366,12 @@ pub fn read_scriptbool(v: &[u8]) -> bool {
}
/// Read a script-encoded unsigned integer
pub fn read_uint<'a, I:Iterator<&'a u8>>(mut iter: I, size: uint)
-> Result<uint, ScriptError> {
pub fn read_uint<'a, I:Iterator<&'a u8>>(mut iter: I, size: usize)
-> Result<usize, ScriptError> {
let mut ret = 0;
for i in range(0, size) {
match iter.next() {
Some(&n) => ret += n as uint << (i * 8),
Some(&n) => ret += (n as usize) << (i * 8),
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
/// into a 0/1 to push onto the script stack
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
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
// for an example of what Rust vector-stack manipulation looks
// like.
macro_rules! stack_opcode(
macro_rules! stack_opcode {
($stack:ident($min:expr):
$(require $r:expr)*
$(copy $c:expr)*
$(swap ($a:expr, $b:expr))*
$(perm ($first:expr $(->$i:expr)*) )*
$(drop $d:expr)*
$(require $r:expr);*
$(copy $c:expr);*
$(swap ($a:expr, $b:expr));*
$(perm ($first:expr, $($i:expr),*) );*
$(drop $d:expr);*
) => ({
$( $stack.require_n_elems($r); )*
// Record top
@ -1502,10 +1502,10 @@ macro_rules! stack_opcode(
// Do drops last so that dropped values will be available above
$( $stack.remove(top - $d); )*
});
)
}
/// Macro to translate numerical operations into stack ones
macro_rules! num_opcode(
macro_rules! num_opcode {
($stack:ident($($var:ident),*): $op:expr) => ({
$(
let $var = try!(read_scriptint(match $stack.pop() {
@ -1517,9 +1517,9 @@ macro_rules! num_opcode(
// Return a tuple of all the variables
($( $var ),*)
});
)
}
macro_rules! unary_opcode_satisfy(
macro_rules! unary_opcode_satisfy {
($stack:ident, $op:ident) => ({
let one = $stack.pop();
let cond = $stack.push_alloc(AbstractStackElem::new_unknown());
@ -1527,9 +1527,9 @@ macro_rules! unary_opcode_satisfy(
check: concat_idents!(check_, $op),
update: concat_idents!(update_, $op) }));
})
)
}
macro_rules! boolean_opcode_satisfy(
macro_rules! boolean_opcode_satisfy {
($stack:ident, unary $op:ident) => ({
let one = $stack.pop();
let cond = $stack.push_alloc(AbstractStackElem::new_unknown());
@ -1557,10 +1557,10 @@ macro_rules! boolean_opcode_satisfy(
check: concat_idents!(check_, $op),
update: concat_idents!(update_, $op) }));
});
)
}
/// Macro to translate hashing operations into stack ones
macro_rules! hash_opcode(
macro_rules! hash_opcode {
($stack:ident, $hash:ident) => ({
match $stack.pop() {
None => { return Err(PopEmptyStack); }
@ -1576,10 +1576,10 @@ macro_rules! hash_opcode(
}
}
});
)
}
// OP_VERIFY macro
macro_rules! op_verify (
macro_rules! op_verify {
($stack:expr, $err:expr) => (
match $stack.last().map(|v| read_scriptbool(v.as_slice())) {
None => { return Err(VerifyEmptyStack); }
@ -1587,14 +1587,14 @@ macro_rules! op_verify (
Some(true) => { $stack.pop(); }
}
)
)
}
macro_rules! op_verify_satisfy (
macro_rules! op_verify_satisfy {
($stack:expr) => ({
try!($stack.peek_mut().set_bool_value(true));
$stack.pop();
})
)
}
impl 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)) }
/// The length in bytes of the script
pub fn len(&self) -> uint {
pub fn len(&self) -> usize {
let &Script(ref raw) = self;
raw.len()
}
@ -1640,7 +1640,7 @@ impl Script {
let &Script(ref mut raw) = self;
// Start with a PUSH opcode
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 => {
raw.push(opcodes::OP_PUSHDATA1 as u8);
raw.push(n as u8);
@ -1657,7 +1657,7 @@ impl Script {
raw.push(((n / 0x10000) % 0x100) 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
raw.extend(data.iter().map(|n| *n));
@ -1676,26 +1676,26 @@ impl Script {
}
/// 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;
raw.slice_to(n)
}
/// 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;
raw.slice_from(n)
}
/// 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;
raw.slice(s, e)
}
/// Trace a script
pub fn trace<'a>(&'a self, stack: &mut Vec<MaybeOwned<'a>>,
input_context: Option<(&Transaction, uint)>)
input_context: Option<(&Transaction, usize)>)
-> ScriptTrace {
let mut trace = ScriptTrace {
script: self.clone(),
@ -1713,12 +1713,12 @@ impl Script {
/// Evaluate the script, modifying the stack in place
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>>)
-> Result<(), ScriptError> {
let &Script(ref raw) = self;
let mut codeseparator_index = 0u;
let mut codeseparator_index = 0;
let mut exec_stack = vec![];
let mut alt_stack = vec![];
@ -1757,35 +1757,35 @@ impl Script {
// Data-reading statements still need to read, even when not executing
(_, opcodes::PushBytes(n)) => {
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;
}
(_, opcodes::Ordinary(opcodes::OP_PUSHDATA1)) => {
if raw.len() < index + 1 { return Err(EarlyEndOfScript); }
let n = try!(read_uint(raw.slice_from(index).iter(), 1));
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;
}
(_, opcodes::Ordinary(opcodes::OP_PUSHDATA2)) => {
if raw.len() < index + 2 { return Err(EarlyEndOfScript); }
let n = try!(read_uint(raw.slice_from(index).iter(), 2));
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;
}
(_, opcodes::Ordinary(opcodes::OP_PUSHDATA4)) => {
if raw.len() < index + 4 { return Err(EarlyEndOfScript); }
let n = try!(read_uint(raw.slice_from(index).iter(), 4));
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;
}
// If-statements take effect when not executing
(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_ELSE)) => {
match exec_stack.mut_last() {
match exec_stack.last_mut() {
Some(ref_e) => { *ref_e = !*ref_e }
None => { return Err(ElseWithoutIf); }
}
@ -1816,7 +1816,7 @@ impl Script {
}
}
opcodes::OP_ELSE => {
match exec_stack.mut_last() {
match exec_stack.last_mut() {
Some(ref_e) => { *ref_e = !*ref_e }
None => { return Err(ElseWithoutIf); }
}
@ -1839,13 +1839,13 @@ impl Script {
Some(elem) => { stack.push(elem); }
}
}
opcodes::OP_2DROP => stack_opcode!(stack(2): drop 1 drop 2),
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_2OVER => stack_opcode!(stack(4): copy 4 copy 3),
opcodes::OP_2ROT => stack_opcode!(stack(6): perm (1 -> 3 -> 5)
perm (2 -> 4 -> 6)),
opcodes::OP_2SWAP => stack_opcode!(stack(4): swap (2, 4) swap (1, 3)),
opcodes::OP_2DROP => stack_opcode!(stack(2): drop 1; drop 2),
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_2OVER => stack_opcode!(stack(4): copy 4; copy 3),
opcodes::OP_2ROT => stack_opcode!(stack(6): perm (1, 3, 5);
perm (2, 4, 6)),
opcodes::OP_2SWAP => stack_opcode!(stack(4): swap (2, 4); swap (1, 3)),
opcodes::OP_DROP => stack_opcode!(stack(1): drop 1),
opcodes::OP_DUP => stack_opcode!(stack(1): copy 1),
opcodes::OP_NIP => stack_opcode!(stack(2): drop 2),
@ -1856,7 +1856,7 @@ impl Script {
None => { return Err(PopEmptyStack); }
};
if n < 0 { return Err(NegativePick); }
let n = n as uint;
let n = n as usize;
stack_opcode!(stack(n + 1): copy n + 1)
}
opcodes::OP_ROLL => {
@ -1865,12 +1865,12 @@ impl Script {
None => { return Err(PopEmptyStack); }
};
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)
}
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_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 => {
match stack.last().map(|v| read_scriptbool(v.as_slice())) {
None => { return Err(IfEmptyStack); }
@ -1892,7 +1892,7 @@ impl Script {
if stack.len() < 2 { return Err(PopEmptyStack); }
let a = 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 {
op_verify!(stack, EqualVerifyFailed(a.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
// 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();
remove.push_slice(sig_slice);
script_find_and_remove(&mut script, remove.as_slice());
@ -1955,8 +1955,8 @@ impl Script {
let (tx, input_index) = input_context.unwrap();
match check_signature( sig_slice, pk_slice, script, tx, input_index) {
Ok(()) => stack.push(Slice(SCRIPT_TRUE)),
_ => stack.push(Slice(SCRIPT_FALSE)),
Ok(()) => stack.push(Borrowed(SCRIPT_TRUE)),
_ => stack.push(Borrowed(SCRIPT_FALSE)),
}
if op == opcodes::OP_CHECKSIGVERIFY { op_verify!(stack, VerifyFailed); }
}
@ -1965,11 +1965,11 @@ impl Script {
if stack.len() < 1 { return Err(PopEmptyStack); }
let n_keys = try!(read_scriptint(stack.pop().unwrap().as_slice()));
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); }
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) {
keys.push(stack.pop().unwrap());
}
@ -1978,11 +1978,11 @@ impl Script {
if stack.len() < 1 { return Err(PopEmptyStack); }
let n_sigs = try!(read_scriptint(stack.pop().unwrap().as_slice()));
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); }
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) {
sigs.push(stack.pop().unwrap());
}
@ -1992,7 +1992,7 @@ impl Script {
// Compute the section of script that needs to be hashed: everything
// 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() {
let mut remove = Script::new();
remove.push_slice(sig.as_slice());
@ -2024,12 +2024,12 @@ impl Script {
}
// Run out of signatures, success
(_, None) => {
stack.push(Slice(SCRIPT_TRUE));
stack.push(Borrowed(SCRIPT_TRUE));
break;
}
// Run out of keys to match to signatures, fail
(None, Some(_)) => {
stack.push(Slice(SCRIPT_FALSE));
stack.push(Borrowed(SCRIPT_FALSE));
break;
}
}
@ -2041,7 +2041,7 @@ impl Script {
} // end loop
// Store the stack in the trace
trace.as_mut().map(|t|
t.mut_last().map(|t| {
t.last_mut().map(|t| {
t.errored = false;
t.stack = stack.iter().map(|elem| elem.as_slice().to_hex()).collect();
})
@ -2077,7 +2077,7 @@ impl Script {
fn recurse<'a>(script: &'a [u8],
mut stack: AbstractStack,
mut exec_stack: Vec<bool>,
depth: uint) -> Result<Vec<AbstractStackElem>, ScriptError> {
depth: usize) -> Result<Vec<AbstractStackElem>, ScriptError> {
// Avoid doing more than 64k forks
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_NOTIF)) => exec_stack.push(false),
(false, opcodes::Ordinary(opcodes::OP_ELSE)) => {
match exec_stack.mut_last() {
match exec_stack.last_mut() {
Some(ref_e) => { *ref_e = !*ref_e }
None => { return Err(ElseWithoutIf); }
}
@ -2212,7 +2212,7 @@ impl Script {
}
}
opcodes::OP_ELSE => {
match exec_stack.mut_last() {
match exec_stack.last_mut() {
Some(ref_e) => { *ref_e = !*ref_e }
None => { return Err(ElseWithoutIf); }
}
@ -2225,15 +2225,15 @@ impl Script {
opcodes::OP_VERIFY => op_verify_satisfy!(stack),
opcodes::OP_TOALTSTACK => { stack.to_altstack(); }
opcodes::OP_FROMALTSTACK => { try!(stack.from_altstack()); }
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_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_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_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_2ROT => stack_opcode!(stack(6): require 6
perm (1 -> 3 -> 5)
perm (2 -> 4 -> 6)),
perm (1, 3, 5);
perm (2, 4, 6)),
opcodes::OP_2SWAP => stack_opcode!(stack(4): require 4
swap (2, 4)
swap (2, 4);
swap (1, 3)),
opcodes::OP_DROP => stack_opcode!(stack(1): require 1 drop 1),
opcodes::OP_DUP => stack_opcode!(stack(1): require 1 copy 1),
@ -2244,7 +2244,7 @@ impl Script {
let top = stack.peek_mut();
try!(top.set_numeric());
try!(top.set_num_lo(0));
top.num_value().map(|n| n as uint)
top.num_value().map(|n| n as usize)
};
stack.pop();
match top_n {
@ -2262,7 +2262,7 @@ impl Script {
let top = stack.peek_mut();
try!(top.set_numeric());
try!(top.set_num_lo(0));
top.num_value().map(|n| n as uint)
top.num_value().map(|n| n as usize)
};
stack.pop();
match top_n {
@ -2274,9 +2274,9 @@ impl Script {
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_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 => {
let top_bool = {
let top = stack.peek_mut();
@ -2423,8 +2423,8 @@ impl json::ToJson for Script {
let &Script(ref raw) = self;
let mut ret = String::new();
for dat in raw.iter() {
ret.push_char(from_digit((dat / 0x10) as uint, 16).unwrap());
ret.push_char(from_digit((dat & 0x0f) as uint, 16).unwrap());
ret.push_char(from_digit((dat / 0x10) as usize, 16).unwrap());
ret.push_char(from_digit((dat & 0x0f) as usize, 16).unwrap());
}
json::String(ret)
}

View File

@ -27,7 +27,7 @@ use std::default::Default;
use serialize::json;
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 network::encodable::ConsensusEncodable;
use network::serialize::BitcoinHash;
@ -81,7 +81,7 @@ impl TxOut {
if self.script_pubkey.len() == 25 &&
self.script_pubkey.slice_to(3) == &[0x76, 0xa9, 0x14] &&
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 {
Unknown
}
@ -133,16 +133,16 @@ impl json::ToJson for TransactionError {
#[deriving(PartialEq, Eq, Clone, Show)]
pub struct InputTrace {
input_txid: Sha256dHash,
input_vout: uint,
input_vout: usize,
sig_trace: ScriptTrace,
pubkey_trace: Option<ScriptTrace>,
p2sh_trace: Option<ScriptTrace>,
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,
pubkey_trace, p2sh_trace, error)
pubkey_trace, p2sh_trace, error);
/// A trace of a transaction's execution
#[deriving(PartialEq, Eq, Clone, Show)]
@ -151,14 +151,14 @@ pub struct TransactionTrace {
inputs: Vec<InputTrace>
}
impl_json!(TransactionTrace, txid, inputs)
impl_json!(TransactionTrace, txid, inputs);
impl TxIn {
/// Check an input's script for validity
pub fn validate(&self,
utxoset: &UtxoSet,
txn: &Transaction,
index: uint) -> Result<(), TransactionError> {
index: usize) -> Result<(), TransactionError> {
let txo = utxoset.get_utxo(self.prev_hash, self.prev_index);
match txo {
Some((_, txo)) => {
@ -174,7 +174,7 @@ impl TxIn {
p2sh_stack = stack.clone();
p2sh_script = match p2sh_stack.pop() {
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!()
};
}
@ -228,7 +228,7 @@ impl Transaction {
// Setup trace
let mut trace = InputTrace {
input_txid: input.prev_hash,
input_vout: input.prev_index as uint,
input_vout: input.prev_index as usize,
sig_trace: ScriptTrace {
script: Script::new(),
initial_stack: vec![],
@ -255,7 +255,7 @@ impl Transaction {
p2sh_stack = stack.clone();
p2sh_script = match p2sh_stack.pop() {
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!()
};
}
@ -303,12 +303,12 @@ impl BitcoinHash for Transaction {
}
}
impl_consensus_encoding!(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_json!(TxOut, value, script_pubkey)
impl_consensus_encoding!(Transaction, version, input, output, lock_time)
impl_json!(Transaction, version, input, output, lock_time)
impl_consensus_encoding!(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_json!(TxOut, value, script_pubkey);
impl_consensus_encoding!(Transaction, version, input, output, lock_time);
impl_json!(Transaction, version, input, output, lock_time);
#[cfg(test)]

View File

@ -65,27 +65,27 @@ struct UtxoNode {
/// Vector of outputs; None indicates a nonexistent or already spent output
outputs: ThinVec<Option<TxOut>>
}
impl_consensus_encoding!(UtxoNode, height, outputs)
impl_consensus_encoding!(UtxoNode, height, outputs);
/// An iterator over UTXOs
pub struct UtxoIterator<'a> {
tx_iter: Entries<'a, Sha256dHash, UtxoNode>,
current_key: Sha256dHash,
current: Option<&'a UtxoNode>,
tx_index: uint
tx_index: u32
}
impl<'a> Iterator<(Sha256dHash, uint, &'a TxOut, uint)> for UtxoIterator<'a> {
fn next(&mut self) -> Option<(Sha256dHash, uint, &'a TxOut, uint)> {
impl<'a> Iterator<(Sha256dHash, u32, &'a TxOut, u32)> for UtxoIterator<'a> {
fn next(&mut self) -> Option<(Sha256dHash, u32, &'a TxOut, u32)> {
while self.current.is_some() {
let current = &self.current.unwrap().outputs;
while self.tx_index < current.len() {
while self.tx_index < current.len() as u32 {
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,
self.tx_index,
unsafe { current.get(self.tx_index - 1) }.as_ref().unwrap(),
self.current.unwrap().height as uint));
unsafe { current.get(self.tx_index as usize - 1) }.as_ref().unwrap(),
self.current.unwrap().height));
}
}
match self.tx_iter.next() {
@ -113,11 +113,11 @@ pub struct UtxoSet {
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 {
/// 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
// reference client does not add its sole output to the UTXO set. We
// 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() {
// Unsafe since we are not uninitializing the old data in the vector
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_pruned += 1;
} 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 }
@ -171,8 +171,8 @@ impl UtxoSet {
let ret = {
// Check that this specific output is there
if vout as uint >= node.outputs.len() { return None; }
let replace = unsafe { node.outputs.get_mut(vout as uint) };
if vout as usize >= node.outputs.len() { return None; }
let replace = unsafe { node.outputs.get_mut(vout as usize) };
replace.take()
};
@ -190,20 +190,20 @@ impl UtxoSet {
}
/// 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
let node = match self.table.find(&txid) {
Some(node) => node,
None => return None
};
// Check that this specific output is there
if vout as uint >= node.outputs.len() { return None; }
let replace = unsafe { node.outputs.get(vout as uint) };
Some((node.height as uint, replace.as_ref().unwrap()))
if vout as usize >= node.outputs.len() { return None; }
let replace = unsafe { node.outputs.get(vout as usize) };
Some((node.height as usize, replace.as_ref().unwrap()))
}
/// 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> {
// Make sure we are extending the UTXO set in order
if validation >= ChainValidation &&
@ -214,7 +214,7 @@ impl UtxoSet {
// Set the next hash immediately so that if anything goes wrong,
// we can rewind from the point that we're at.
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_txos.get_mut(spent_idx).clear();
@ -240,7 +240,7 @@ impl UtxoSet {
// Otherwise put the replaced txouts into the `deleted` cache
// so that rewind will put them back.
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() {
Some(txo) => { self.spent_txos.get_mut(spent_idx).push(((txid, n as u32), (replace.height, txo))); }
None => {}
@ -269,7 +269,7 @@ impl UtxoSet {
let s = self as *mut _ as *const UtxoSet;
let txes = &block.txdata as *const _;
future_vec.push(Future::spawn(proc() {
future_vec.push(Future::spawn(move || {
let txes = unsafe {&*txes};
for tx in txes.slice(start, end).iter() {
match tx.validate(unsafe {&*s}) {
@ -283,7 +283,7 @@ impl UtxoSet {
// Return the last error since we need to finish every future before
// leaving this function, and given that, it's easier to return the last.
let mut last_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() {
last_error = res;
}
@ -348,8 +348,8 @@ impl UtxoSet {
// Read deleted txouts
if skipped_genesis {
let mut extract_vec = vec![];
mem::swap(&mut extract_vec, self.spent_txos.get_mut(self.spent_idx as uint));
for ((txid, n), (height, txo)) in extract_vec.move_iter() {
mem::swap(&mut extract_vec, self.spent_txos.get_mut(self.spent_idx as usize));
for ((txid, n), (height, txo)) in extract_vec.into_iter() {
// Remove the tx's utxo list and patch the txo into place
let new_node =
match self.table.pop(&txid) {
@ -359,20 +359,20 @@ impl UtxoSet {
unsafe {
node.outputs.reserve(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
}
None => {
unsafe {
let mut thinvec = ThinVec::with_capacity(n + 1);
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 }
}
}
@ -397,14 +397,14 @@ impl UtxoSet {
}
/// Get the number of UTXOs in the set
pub fn n_utxos(&self) -> uint {
self.n_utxos as uint
pub fn n_utxos(&self) -> usize {
self.n_utxos as usize
}
/// 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).
pub fn n_pruned(&self) -> uint {
self.n_pruned as uint
pub fn n_pruned(&self) -> usize {
self.n_pruned as usize
}
/// Get an iterator over all UTXOs

View File

@ -12,9 +12,7 @@
// 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),+) => (
impl<S: ::network::serialize::SimpleEncoder<E>, E> ::network::encodable::ConsensusEncodable<S, E> for $thing {
#[inline]
@ -34,9 +32,9 @@ macro_rules! impl_consensus_encoding(
}
}
);
)
}
macro_rules! impl_newtype_consensus_encoding(
macro_rules! impl_newtype_consensus_encoding {
($thing:ident) => (
impl<S: ::network::serialize::SimpleEncoder<E>, E> ::network::encodable::ConsensusEncodable<S, E> for $thing {
#[inline]
@ -53,9 +51,9 @@ macro_rules! impl_newtype_consensus_encoding(
}
}
);
)
}
macro_rules! impl_json(
macro_rules! impl_json {
($thing:ident, $($field:ident),+) => (
impl ::serialize::json::ToJson for $thing {
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) => {
impl $thing {
#[inline]
@ -81,21 +79,21 @@ macro_rules! impl_array_newtype(
#[inline]
/// 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;
dat.slice(s, e)
}
#[inline]
/// 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;
dat.slice_to(n)
}
#[inline]
/// 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;
dat.slice_from(n)
}
@ -116,7 +114,7 @@ macro_rules! impl_array_newtype(
#[inline]
/// 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
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]
fn index<'a>(&'a self, idx: &uint) -> &'a $ty {
fn index<'a>(&'a self, idx: &usize) -> &'a $ty {
let &$thing(ref data) = self;
&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) => {
impl<D: ::serialize::Decoder<E>, E> ::serialize::Decodable<D, E> for $thing {
fn decode(d: &mut D) -> ::std::prelude::Result<$thing, E> {
@ -173,7 +171,7 @@ macro_rules! impl_array_newtype_encodable(
} else {
unsafe {
use std::mem;
let mut ret: [$ty, ..$len] = mem::uninitialized();
let mut ret: [$ty; $len] = mem::uninitialized();
for i in range(0, len) {
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) => {
impl ::std::fmt::Show for $thing {
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"]
// Experimental features we need
#![feature(globs)]
#![feature(macro_rules)]
#![feature(overloaded_calls)]
#![feature(unsafe_destructor)]
#![feature(default_type_params)]
#![feature(struct_variant)]
#![feature(unboxed_closure_sugar)]
#![feature(unboxed_closures)]
@ -50,18 +46,17 @@
extern crate alloc;
extern crate collections;
extern crate core;
extern crate num;
extern crate rand;
extern crate rustrt;
extern crate serialize;
extern crate sync;
extern crate test;
extern crate time;
extern crate "bitcoin-secp256k1-rs" as secp256k1;
extern crate "rust-crypto" as crypto;
extern crate crypto;
#[macro_use]
mod internal_macros;
#[macro_use]
pub mod macros;
pub mod network;
pub mod blockdata;

View File

@ -16,14 +16,12 @@
//!
//! Macros available to users of the Bitcoin library
#![macro_escape]
#[macro_export]
macro_rules! nu_select(
($($name:pat from $rx:expr => $code:expr),+) => ({
nu_select!{ $($name from $rx using recv => $code),+ }
macro_rules! nu_select {
($($name:pat = $rx:expr => $code:expr),+) => ({
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::task::Task;
use sync::comm::Packet;
@ -82,10 +80,10 @@ macro_rules! nu_select(
ret
}
})
)
}
#[macro_export]
macro_rules! user_enum(
macro_rules! user_enum {
($(#[$attr:meta])* pub enum $name:ident { $(#[$doc:meta] $elem:ident <-> $txt:expr),* }) => (
$(#[$attr])*
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
pub services: u64,
/// Network byte-order ipv6 address, or ipv4-mapped ipv6 address
pub address: [u8, ..16],
pub address: [u8; 16],
/// Network port
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,
0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x0a, 0,
0, 1, 0x20, 0x8d]);
assert!(addr.is_ok())
assert!(addr.is_ok());
let full = addr.unwrap();
assert!(full.services == 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::serialize::{SimpleEncoder, SimpleDecoder};
user_enum!(
user_enum! {
#[deriving(PartialEq, Eq, Clone, Hash)]
#[doc="The cryptocurrency to act on"]
pub enum Network {
@ -30,11 +30,11 @@ user_enum!(
#[doc="Bitcoin's testnet"]
BitcoinTestnet <-> "testnet"
}
)
}
pub static PROTOCOL_VERSION: u32 = 70001;
pub static SERVICES: u64 = 0;
pub static USER_AGENT: &'static str = "bitcoin-rust v0.1";
pub const PROTOCOL_VERSION: u32 = 70001;
pub const SERVICES: u64 = 0;
pub const USER_AGENT: &'static str = "bitcoin-rust v0.1";
/// Return the network magic bytes, which should be encoded little-endian
/// 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![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());
}
}

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> {
let &VarInt(n) = self;
match n {
0..0xFC => { (n as u8).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) }
_ => { try!(s.emit_u8(0xFF)); (n as u64).consensus_encode(s) }
0...0xFC => { (n as u8).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) }
_ => { 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
macro_rules! impl_array(
macro_rules! impl_array {
( $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]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
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]
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
let mut ret = [try!(ConsensusDecodable::consensus_decode(d)), ..$size];
let mut ret = [try!(ConsensusDecodable::consensus_decode(d)); $size];
// Set the rest
for i in range(1, $size) { ret[i] = try!(ConsensusDecodable::consensus_decode(d)); }
Ok(ret)
}
}
);
)
}
impl_array!(2)
impl_array!(4)
impl_array!(8)
impl_array!(12)
impl_array!(16)
impl_array!(32)
impl_array!(2);
impl_array!(4);
impl_array!(8);
impl_array!(12);
impl_array!(16);
impl_array!(32);
impl<'a, S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for &'a [T] {
#[inline]
@ -224,7 +224,7 @@ impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>> ConsensusDecodable<D, E>
#[inline]
fn consensus_decode(d: &mut D) -> Result<Vec<T>, E> {
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))); }
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
// 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.
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)
}
}
@ -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
fn sha2_checksum(data: &[u8]) -> [u8, ..4] {
fn sha2_checksum(data: &[u8]) -> [u8; 4] {
let checksum = Sha256dHash::from_data(data);
[checksum[0u], checksum[1u], checksum[2u], checksum[3u]]
[checksum[0], checksum[1], checksum[2], checksum[3]]
}
// 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> {
let &CheckedData(ref data) = self;
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
for ch in data.iter() {
try!(ch.consensus_encode(s));
@ -306,8 +306,8 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for CheckedData {
#[inline]
fn consensus_decode(d: &mut D) -> Result<CheckedData, E> {
let len: u32 = try!(ConsensusDecodable::consensus_decode(d));
let checksum: [u8, ..4] = try!(ConsensusDecodable::consensus_decode(d));
let mut ret = Vec::with_capacity(len as uint);
let checksum: [u8; 4] = try!(ConsensusDecodable::consensus_decode(d));
let mut ret = Vec::with_capacity(len as usize);
for _ in range(0, len) { ret.push(try!(ConsensusDecodable::consensus_decode(d))); }
let expected_checksum = sha2_checksum(ret.as_slice());
if expected_checksum != checksum {
@ -319,7 +319,7 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for CheckedData {
}
// Tuples
macro_rules! tuple_encode(
macro_rules! tuple_encode {
($($x:ident),*) => (
impl <SS:SimpleEncoder<EE>, EE, $($x: ConsensusEncodable<SS, EE>),*> ConsensusEncodable<SS, EE> for ($($x),*) {
#[inline]
@ -339,12 +339,12 @@ macro_rules! tuple_encode(
}
}
);
)
}
tuple_encode!(A, B)
tuple_encode!(A, B, C, D)
tuple_encode!(A, B, C, D, E, F)
tuple_encode!(A, B, C, D, E, F, G, H)
tuple_encode!(A, B);
tuple_encode!(A, B, C, D);
tuple_encode!(A, B, C, D, E, F);
tuple_encode!(A, B, C, D, E, F, G, H);
// 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> {
#[inline]
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> {
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) {
ret.insert(try!(ConsensusDecodable::consensus_decode(d)),
try!(ConsensusDecodable::consensus_decode(d)));
@ -474,9 +474,9 @@ mod tests {
#[test]
fn serialize_box_test() {
assert_eq!(serialize(&box 1u8), Ok(vec![1u8]));
assert_eq!(serialize(&box 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(1u8)), Ok(vec![1u8]));
assert_eq!(serialize(&Box::new(1u16)), Ok(vec![1u8, 0]));
assert_eq!(serialize(&Box::new(1u64)), Ok(vec![1u8, 0, 0, 0, 0, 0, 0, 0]));
}
#[test]
@ -560,8 +560,8 @@ mod tests {
fn deserialize_box_test() {
let zero: IoResult<Box<u8>> = deserialize(vec![0u8]);
let one: IoResult<Box<u8>> = deserialize(vec![1u8]);
assert_eq!(zero, Ok(box 0));
assert_eq!(one, Ok(box 1));
assert_eq!(zero, Ok(Box::new(0)));
assert_eq!(one, Ok(Box::new(1)));
}
}

View File

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

View File

@ -41,7 +41,7 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for CommandString {
#[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
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.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 {
#[inline]
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 }));
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 {
/// 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 {
#[inline]
@ -119,7 +119,7 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Inventory {
1 => InvTransaction,
2 => InvBlock,
// TODO do not fail here
_ => { fail!("bad inventory type field") }
_ => { panic!("bad inventory type field") }
},
hash: try!(ConsensusDecodable::consensus_decode(d))
})

View File

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

View File

@ -34,7 +34,7 @@ use network::serialize::{RawEncoder, RawDecoder};
use util::misc::prepend_err;
/// 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 {
ip::Ipv4Addr(a, b, c, d) =>
[0, 0, 0, 0, 0, 0, 0, 0,

View File

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

View File

@ -25,7 +25,7 @@ pub type BitcoinResult<T> = Result<T, BitcoinError>;
#[deriving(PartialEq, Eq, Show, Clone)]
pub enum BitcoinError {
/// An I/O error
IoError(IoError),
InputOutput(IoError),
/// An object was attempted to be added twice
DuplicateHash,
/// 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 std::default::Default;
use std::fmt;
use std::io::extensions::u64_from_be_bytes;
use std::io::MemWriter;
use std::mem::transmute;
use std::hash;
use serialize::json::{mod, ToJson};
use serialize::json::{self, ToJson};
use crypto::digest::Digest;
use crypto::sha2::Sha256;
@ -30,12 +31,11 @@ use crypto::ripemd160::Ripemd160;
use network::encodable::{ConsensusDecodable, ConsensusEncodable};
use network::serialize::{RawEncoder, BitcoinHash, SimpleDecoder};
use util::uint::Uint128;
use util::uint::Uint256;
/// A Bitcoin hash, 32-bytes, computed from x as SHA256(SHA256(x))
pub struct Sha256dHash([u8, ..32]);
impl_array_newtype!(Sha256dHash, u8, 32)
pub struct Sha256dHash([u8; 32]);
impl_array_newtype!(Sha256dHash, u8, 32);
impl ::std::fmt::Show for Sha256dHash {
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
pub struct Ripemd160Hash([u8, ..20]);
impl_array_newtype!(Ripemd160Hash, u8, 20)
pub struct 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;
/// The state of a `DumbHasher`
pub struct DumbHasherState([u8; 8]);
/// A 32-bit hash obtained by truncating a real hash
#[deriving(Clone, PartialEq, Eq, Show)]
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.
impl hash::Hash<u64> for Sha256dHash {
impl hash::Hash<DumbHasherState> for Sha256dHash {
#[inline]
fn hash(&self, state: &mut u64) {
use std::mem;
let myarr: [u64, ..4] = unsafe { mem::transmute(*self) };
*state = myarr[0];
fn hash(&self, state: &mut DumbHasherState) {
let &Sha256dHash(ref hash) = self;
let &DumbHasherState(ref mut arr) = state;
for i in range(0, 8) {
arr[i] += hash[i];
}
}
}
impl hash::Hash<u64> for Uint256 {
impl hash::Hasher<DumbHasherState> for DumbHasher {
#[inline]
fn hash(&self, state: &mut u64) {
use std::mem;
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;
fn hash<T: hash::Hash<DumbHasherState>>(&self, value: &T) -> u64 {
let mut ret = DumbHasherState([0; 8]);
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 {
/// Create a hash by hashing some data
pub fn from_data(data: &[u8]) -> Ripemd160Hash {
let mut ret = [0, ..20];
let mut ret = [0; 20];
let mut rmd = Ripemd160::new();
rmd.input(data);
rmd.result(ret.as_mut_slice());
@ -146,7 +121,7 @@ impl Ripemd160Hash {
// in the C++ reference client
impl Default for Sha256dHash {
#[inline]
fn default() -> Sha256dHash { Sha256dHash([0u8, ..32]) }
fn default() -> Sha256dHash { Sha256dHash([0u8; 32]) }
}
impl Sha256dHash {
@ -166,8 +141,8 @@ impl Sha256dHash {
#[inline]
pub fn into_le(self) -> Uint256 {
let Sha256dHash(data) = self;
let mut ret: [u64, ..4] = unsafe { transmute(data) };
for x in ret.as_mut_slice().mut_iter() { *x = x.to_le(); }
let mut ret: [u64; 4] = unsafe { transmute(data) };
for x in ret.as_mut_slice().iter_mut() { *x = x.to_le(); }
Uint256(ret)
}
@ -176,8 +151,8 @@ impl Sha256dHash {
pub fn into_be(self) -> Uint256 {
let Sha256dHash(mut data) = self;
data.reverse();
let mut ret: [u64, ..4] = unsafe { transmute(data) };
for x in ret.mut_iter() { *x = x.to_be(); }
let mut ret: [u64; 4] = unsafe { transmute(data) };
for x in ret.iter_mut() { *x = x.to_be(); }
Uint256(ret)
}
@ -209,9 +184,9 @@ impl Sha256dHash {
pub fn le_hex_string(&self) -> String {
let &Sha256dHash(data) = self;
let mut ret = String::with_capacity(64);
for i in range(0u, 32) {
ret.push_char(from_digit((data[i] / 0x10) as uint, 16).unwrap());
ret.push_char(from_digit((data[i] & 0x0f) as uint, 16).unwrap());
for i in range(0, 32) {
ret.push_char(from_digit((data[i] / 0x10) as usize, 16).unwrap());
ret.push_char(from_digit((data[i] & 0x0f) as usize, 16).unwrap());
}
ret
}
@ -220,9 +195,9 @@ impl Sha256dHash {
pub fn be_hex_string(&self) -> String {
let &Sha256dHash(data) = self;
let mut ret = String::with_capacity(64);
for i in range(0u, 32).rev() {
ret.push_char(from_digit((data[i] / 0x10) as uint, 16).unwrap());
ret.push_char(from_digit((data[i] & 0x0f) as uint, 16).unwrap());
for i in range(0, 32).rev() {
ret.push_char(from_digit((data[i] / 0x10) as usize, 16).unwrap());
ret.push_char(from_digit((data[i] & 0x0f) as usize, 16).unwrap());
}
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()
.map_err(|_| d.error("non-hexadecimal hash string")));
let mut ret = [0u8, ..32];
let mut ret = [0u8; 32];
for i in range(0, 32) {
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)
impl_newtype_consensus_encoding!(Hash32)
impl_newtype_consensus_encoding!(Hash48)
impl_newtype_consensus_encoding!(Hash64)
impl_newtype_consensus_encoding!(Sha256dHash)
impl_newtype_consensus_encoding!(Hash32);
impl_newtype_consensus_encoding!(Hash48);
impl_newtype_consensus_encoding!(Hash64);
impl_newtype_consensus_encoding!(Sha256dHash);
impl fmt::LowerHex for Sha256dHash {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let &Sha256dHash(data) = self;
let mut rv = [0, ..64];
let mut rv = [0; 64];
let mut hex = data.iter().rev().map(|n| *n).enumerate();
for (i, ch) in hex {
rv[2*i] = from_digit(ch as uint / 16, 16).unwrap() as u8;
rv[2*i + 1] = 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 usize % 16, 16).unwrap() as u8;
}
f.write(rv.as_slice())
}

View File

@ -41,7 +41,7 @@ impl<A, I: Iterator<A>> Iterator<(A, A)> for Pair<A, I> {
}
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
fn size_hint(&self) -> (usize, Option<usize>) {
match self.iter.size_hint() {
(n, None) => (n/2, None),
(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 {
kind: err.kind,
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>) {
match res {
Ok(_) => {},
Err(e) => { println!("{:s}: {:}", s, e); }
Err(e) => { println!("{}: {}", s, e); }
};
}
/// Search for `needle` in the vector `haystack` and remove every
/// instance of it, returning the number of instances removed.
/// 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() == 0 { return 0; }

View File

@ -28,15 +28,15 @@ pub mod uint;
/// A trait which allows numbers to act as fixed-size bit arrays
pub trait BitArray {
/// 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
fn bit_slice(&self, start: uint, end: uint) -> Self;
fn bit_slice(&self, start: usize, end: usize) -> Self;
/// Bitwise and with `n` ones
fn mask(&self, n: uint) -> Self;
fn mask(&self, n: usize) -> Self;
/// 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
}
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
pub fn new() -> PatriciaTree<K, V> {
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
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
// 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.
@ -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
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 key_idx = 0;
loop {
// If the search key is shorter than the node prefix, there is no
// 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;
}
// 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;
}
// 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();
} else {
// 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 };
match subtree {
&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
/// stored against `key`, do nothing and return false.
#[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)
}
/// Inserts a value with key `key`, returning true on success. If a value is already
/// stored against `key`, overwrite it and return false.
#[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)
}
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 idx = 0;
loop {
// 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 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)
{ (&mut tmp.child_r, &mut tmp.child_l) }
else { (&mut tmp.child_l, &mut tmp.child_r) };
*insert = Some(box PatriciaTree {
*insert = Some(Box::new(PatriciaTree {
data: None,
child_l: None,
child_r: None,
skip_prefix: key.bit_slice(idx + diff + 1, key_len),
skip_len: (key_len - idx - diff - 1) as u8
});
*neighbor = Some(box PatriciaTree {
}));
*neighbor = Some(Box::new(PatriciaTree {
data: value_neighbor,
child_l: child_l,
child_r: child_r,
skip_prefix: tmp.skip_prefix >> (diff + 1),
skip_len: tmp.skip_len - diff as u8 - 1
});
}));
// Chop the prefix down
tmp.skip_len = diff as u8;
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;
// Search key is shorter than skip prefix: truncate the prefix and attach
// 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
let child_l = node.child_l.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
let new_child = if node.skip_prefix.bit(slice_len)
{ &mut node.child_r } else { &mut node.child_l };
*new_child = Some(box PatriciaTree {
*new_child = Some(Box::new(PatriciaTree {
data: value_neighbor,
child_l: child_l,
child_r: child_r,
skip_prefix: node.skip_prefix >> (slice_len + 1),
skip_len: node.skip_len - slice_len as u8 - 1
});
}));
// Chop the prefix down and put the new data in place
node.skip_len = slice_len as u8;
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;
}
// 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() {
node.data = Some(value);
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
else {
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)
{ &mut tmp.child_r } else { &mut tmp.child_l };
// Recurse, adding a new node if necessary
if subtree.is_none() {
*subtree = Some(box PatriciaTree {
*subtree = Some(Box::new(PatriciaTree {
data: None,
child_l: None,
child_r: None,
skip_prefix: key.bit_slice(idx, key_len),
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
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
/// 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
/// 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
// 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);
}
// 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);
}
// 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
let ret = tree.data.take();
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()) {
(Some(_), Some(_)) => unreachable!(),
(Some(box PatriciaTree { data, child_l, child_r, skip_prefix, skip_len }), None) |
(None, Some(box PatriciaTree { data, child_l, child_r, skip_prefix, skip_len })) => {
(Some(Box::new(PatriciaTree { data, child_l, child_r, skip_prefix, skip_len })), None) |
(None, Some(Box::new(PatriciaTree { data, child_l, child_r, skip_prefix, skip_len }))) => {
tree.data = data;
tree.child_l = child_l;
tree.child_r = child_r;
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() };
tree.skip_prefix = tree.skip_prefix +
new_bit +
(skip_prefix << (1 + tree.skip_len as uint));
(skip_prefix << (1 + tree.skip_len as usize));
tree.skip_len += 1 + skip_len;
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
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
// 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.
@ -271,8 +271,8 @@ impl<K:BitArray+Eq+Zero+One+BitXor<K,K>+Shl<uint,K>+Shr<uint,K>, V> PatriciaTree
}
// Otherwise, do it
let (delete_child, ret) = recurse(&mut **target.as_mut().unwrap(),
&key.shr(&(tree.skip_len as uint + 1)),
key_len - tree.skip_len as uint - 1);
&key.shr(&(tree.skip_len as usize + 1)),
key_len - tree.skip_len as usize - 1);
if delete_child {
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);
}
// One child? Consolidate
(bit, Some(box PatriciaTree { data, child_l, child_r, skip_prefix, skip_len }), None) |
(bit, None, Some(box PatriciaTree { data, child_l, child_r, skip_prefix, skip_len })) => {
(bit, Some(Box::new(PatriciaTree { data, child_l, child_r, skip_prefix, skip_len })), None) |
(bit, None, Some(Box::new(PatriciaTree { data, child_l, child_r, skip_prefix, skip_len }))) => {
tree.data = data;
tree.child_l = child_l;
tree.child_r = child_r;
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() };
tree.skip_prefix = tree.skip_prefix +
new_bit +
(skip_prefix << (1 + tree.skip_len as uint));
(skip_prefix << (1 + tree.skip_len as usize));
tree.skip_len += 1 + skip_len;
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
pub fn node_count(&self) -> uint {
fn recurse<K, V>(node: &Option<Box<PatriciaTree<K, V>>>) -> uint {
pub fn node_count(&self) -> usize {
fn recurse<K, V>(node: &Option<Box<PatriciaTree<K, V>>>) -> usize {
match node {
&Some(ref node) => { 1 + recurse(&node.child_l) + recurse(&node.child_r) }
&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> {
/// Print the entire tree
pub fn print<'a>(&'a self) {
fn recurse<'a, K:BitArray, V:Show>(tree: &'a PatriciaTree<K, V>, depth: uint) {
for i in range(0, tree.skip_len as uint) {
print!("{:}", if tree.skip_prefix.bit(i) { 1u } else { 0 });
fn recurse<'a, K:BitArray, V:Show>(tree: &'a PatriciaTree<K, V>, depth: usize) {
for i in range(0, tree.skip_len as usize) {
print!("{:}", if tree.skip_prefix.bit(i) { 1 } else { 0 });
}
println!(": {:}", tree.data);
// left gets no indentation
match tree.child_l {
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!("0");
recurse(&**t, depth + tree.skip_len as uint + 1);
recurse(&**t, depth + tree.skip_len as usize + 1);
}
None => { }
}
// right one gets indentation
match tree.child_r {
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!("1");
recurse(&**t, depth + tree.skip_len as uint + 1);
recurse(&**t, depth + tree.skip_len as usize + 1);
}
None => { }
}
@ -529,8 +529,8 @@ mod tests {
use network::serialize::{deserialize, serialize};
use util::hash::Sha256dHash;
use util::uint::Uint128;
use util::uint::Uint256;
use util::usize::Uint128;
use util::usize::Uint256;
use util::patricia_tree::PatriciaTree;
#[test]
@ -601,14 +601,14 @@ mod tests {
// Do the actual test -- note that we also test insertion and deletion
// at the root here.
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) {
let m = tree.lookup(&Zero::zero(), i as uint);
let m = tree.lookup(&Zero::zero(), i as usize);
assert_eq!(m, Some(&i));
}
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));
}
// Check that the chunder was unharmed

View File

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

View File

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

View File

@ -38,15 +38,6 @@ pub struct 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
/// is contained in this.
#[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 {
fn base58_layout(&self) -> Vec<u8> {
let mut ret = vec![

View File

@ -21,18 +21,46 @@
use std::collections::HashMap;
use collections::hash::sip::hash_with_keys;
use secp256k1::key::SecretKey;
use blockdata::transaction::{TxOut, PayToPubkeyHash};
use blockdata::utxoset::UtxoSet;
use blockdata::script::Script;
use network::constants::Network;
use wallet::address::Address;
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
#[deriving(Clone, PartialEq, Eq, Show)]
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,
k1: u64,
k2: u64
@ -44,21 +72,35 @@ impl AddressIndex {
pub fn new(utxo_set: &UtxoSet, wallet: &Wallet) -> AddressIndex {
let (k1, k2) = wallet.siphash_key();
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(),
k1: k1,
k2: k2
};
for (key, idx, txo, height) in utxo_set.iter() {
if ret.admissible_txo(txo) {
ret.index.insert_or_update_with(txo.script_pubkey.clone(),
vec![(key, idx, txo.clone(), height)],
|_, v| v.push((key, idx, txo.clone(), height)));
let new = WalletTxOut {
txid: key,
vout: idx,
height: height,
txo: txo.clone(),
kind: Unknown
};
ret.tentative_index.find_or_insert(txo.script_pubkey.clone(), vec![]).push(new);
}
}
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.
#[inline]
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
/// may be more than one for any given scriptpubkey.
#[inline]
pub fn find_by_script<'a>(&'a self, pubkey: &Script) -> &'a [(Sha256dHash, uint, TxOut, uint)] {
self.index.find(pubkey).map(|v| v.as_slice()).unwrap_or(&[])
pub fn find_by_script<'a>(&'a self, pubkey: &Script) -> &'a [WalletTxOut] {
self.tentative_index.find(pubkey).map(|v| v.as_slice()).unwrap_or(&[])
}
}

View File

@ -35,16 +35,16 @@ use util::base58::{Base58Error,
FromBase58, ToBase58};
/// A chain code
pub struct ChainCode([u8, ..32]);
impl_array_newtype!(ChainCode, u8, 32)
impl_array_newtype_show!(ChainCode)
impl_array_newtype_encodable!(ChainCode, u8, 32)
pub struct ChainCode([u8; 32]);
impl_array_newtype!(ChainCode, u8, 32);
impl_array_newtype_show!(ChainCode);
impl_array_newtype_encodable!(ChainCode, u8, 32);
/// A fingerprint
pub struct Fingerprint([u8, ..4]);
impl_array_newtype!(Fingerprint, u8, 4)
impl_array_newtype_show!(Fingerprint)
impl_array_newtype_encodable!(Fingerprint, u8, 4)
pub struct Fingerprint([u8; 4]);
impl_array_newtype!(Fingerprint, u8, 4);
impl_array_newtype_show!(Fingerprint);
impl_array_newtype_encodable!(Fingerprint, u8, 4);
impl Default for Fingerprint {
fn default() -> Fingerprint { Fingerprint([0, 0, 0, 0]) }
@ -56,7 +56,7 @@ pub struct ExtendedPrivKey {
/// The network this key is to be used on
pub network: Network,
/// 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)
pub parent_fingerprint: Fingerprint,
/// 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
pub network: Network,
/// How many derivations this key is from the master (which is 0)
pub depth: uint,
pub depth: u8,
/// Fingerprint of the parent key
pub parent_fingerprint: Fingerprint,
/// Child number of the key used to derive from parent (0 for master)
@ -129,7 +129,7 @@ pub enum Error {
impl ExtendedPrivKey {
/// Construct a new master key from a seed value
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());
hmac.input(seed);
hmac.raw_result(result.as_mut_slice());
@ -156,7 +156,7 @@ impl ExtendedPrivKey {
/// Private->Private child key derivation
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());
match i {
Normal(n) => {
@ -190,9 +190,9 @@ impl ExtendedPrivKey {
}
/// Returns the HASH160 of the chaincode
pub fn identifier(&self) -> [u8, ..20] {
let mut sha2_res = [0, ..32];
let mut ripemd_res = [0, ..20];
pub fn identifier(&self) -> [u8; 20] {
let mut sha2_res = [0; 32];
let mut ripemd_res = [0; 20];
// Compute extended public key
let pk = ExtendedPubKey::from_private(self);
// Do SHA256 of just the ECDSA pubkey
@ -242,7 +242,7 @@ impl ExtendedPubKey {
hmac.input(self.public_key.as_slice());
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());
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
pub fn identifier(&self) -> [u8, ..20] {
let mut sha2_res = [0, ..32];
let mut ripemd_res = [0, ..20];
pub fn identifier(&self) -> [u8; 20] {
let mut sha2_res = [0; 32];
let mut ripemd_res = [0; 20];
// Do SHA256 of just the ECDSA pubkey
let mut sha2 = Sha256::new();
sha2.input(self.public_key.as_slice());
@ -321,9 +321,9 @@ impl FromBase58 for ExtendedPrivKey {
network: match data.slice_to(4) {
[0x04, 0x88, 0xAD, 0xE4] => Bitcoin,
[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)),
child_number: child_number,
chain_code: ChainCode::from_slice(data.slice(13, 45)),
@ -372,9 +372,9 @@ impl FromBase58 for ExtendedPubKey {
network: match data.slice_to(4) {
[0x04, 0x88, 0xB2, 0x1E] => Bitcoin,
[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)),
child_number: child_number,
chain_code: ChainCode::from_slice(data.slice(13, 45)),

View File

@ -25,7 +25,7 @@ use secp256k1::key::PublicKey;
use blockdata::utxoset::UtxoSet;
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_index::AddressIndex;
@ -273,8 +273,8 @@ impl Wallet {
let sk = try!(master.ckd_priv(cnum).map_err(Bip32Error));
let pk = ExtendedPubKey::from_private(&sk);
let addr = Address::from_key(pk.network, &pk.public_key);
for &(_, _, ref out, _) in index.find_by_script(&addr.script_pubkey()).iter() {
ret += out.value;
for out in index.find_by_script(&addr.script_pubkey()).iter() {
ret += out.txo.value;
}
}
// Sum external balance
@ -285,8 +285,8 @@ impl Wallet {
let sk = try!(master.ckd_priv(cnum).map_err(Bip32Error));
let pk = ExtendedPubKey::from_private(&sk);
let addr = Address::from_key(pk.network, &pk.public_key);
for &(_, _, ref out, _) in index.find_by_script(&addr.script_pubkey()).iter() {
ret += out.value;
for out in index.find_by_script(&addr.script_pubkey()).iter() {
ret += out.txo.value;
}
}