Rename Hash->Uint functions to denote endianness
This commit is contained in:
parent
3a921e6b9c
commit
688a77ef38
|
@ -101,7 +101,7 @@ impl BlockHeader {
|
|||
if target != required_target {
|
||||
return Err(SpvBadTarget);
|
||||
}
|
||||
let ref hash = self.bitcoin_hash().into_uint256();
|
||||
let ref hash = self.bitcoin_hash().into_le();
|
||||
if hash <= target { Ok(()) } else { Err(SpvBadProofOfWork) }
|
||||
}
|
||||
|
||||
|
|
|
@ -141,20 +141,20 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Blockchain {
|
|||
let genesis_hash: Sha256dHash = try!(ConsensusDecodable::consensus_decode(d));
|
||||
|
||||
// Lookup best tip
|
||||
let best = match tree.lookup(&best_hash.into_uint256(), 256) {
|
||||
let best = match tree.lookup(&best_hash.into_le(), 256) {
|
||||
Some(node) => &**node as NodePtr,
|
||||
None => {
|
||||
return Err(d.error(format!("best tip {:x} not in tree", best_hash).as_slice()));
|
||||
}
|
||||
};
|
||||
// Lookup genesis
|
||||
if tree.lookup(&genesis_hash.into_uint256(), 256).is_none() {
|
||||
if tree.lookup(&genesis_hash.into_le(), 256).is_none() {
|
||||
return Err(d.error(format!("genesis {:x} not in tree", genesis_hash).as_slice()));
|
||||
}
|
||||
// Reconnect all prev pointers
|
||||
let raw_tree = &tree as *const _;
|
||||
for node in tree.mut_iter() {
|
||||
let hash = node.block.header.prev_blockhash.into_uint256();
|
||||
let hash = node.block.header.prev_blockhash.into_le();
|
||||
let prevptr =
|
||||
match unsafe { (*raw_tree).lookup(&hash, 256) } {
|
||||
Some(node) => &**node as NodePtr,
|
||||
|
@ -355,7 +355,7 @@ impl Blockchain {
|
|||
network: network,
|
||||
tree: {
|
||||
let mut pat = PatriciaTree::new();
|
||||
pat.insert(&genhash.into_uint256(), 256, new_node);
|
||||
pat.insert(&genhash.into_le(), 256, new_node);
|
||||
pat
|
||||
},
|
||||
best_hash: genhash,
|
||||
|
@ -400,17 +400,17 @@ impl Blockchain {
|
|||
|
||||
/// Looks up a block in the chain and returns the BlockchainNode containing it
|
||||
pub fn get_block<'a>(&'a self, hash: Sha256dHash) -> Option<&'a BlockchainNode> {
|
||||
self.tree.lookup(&hash.into_uint256(), 256).map(|node| &**node)
|
||||
self.tree.lookup(&hash.into_le(), 256).map(|node| &**node)
|
||||
}
|
||||
|
||||
/// Locates a block in the chain and overwrites its txdata
|
||||
pub fn add_txdata(&mut self, block: Block) -> BitcoinResult<()> {
|
||||
self.replace_txdata(&block.header.bitcoin_hash().into_uint256(), block.txdata, true)
|
||||
self.replace_txdata(&block.header.bitcoin_hash().into_le(), block.txdata, true)
|
||||
}
|
||||
|
||||
/// Locates a block in the chain and removes its txdata
|
||||
pub fn remove_txdata(&mut self, hash: Sha256dHash) -> BitcoinResult<()> {
|
||||
self.replace_txdata(&hash.into_uint256(), vec![], false)
|
||||
self.replace_txdata(&hash.into_le(), vec![], false)
|
||||
}
|
||||
|
||||
/// Adds a block header to the chain
|
||||
|
@ -430,13 +430,13 @@ impl Blockchain {
|
|||
if hash == chain.best_hash {
|
||||
Some(chain.best_tip)
|
||||
} else {
|
||||
chain.tree.lookup(&hash.into_uint256(), 256).map(|boxptr| &**boxptr as NodePtr)
|
||||
chain.tree.lookup(&hash.into_le(), 256).map(|boxptr| &**boxptr as NodePtr)
|
||||
}
|
||||
}
|
||||
// Check for multiple inserts (bitcoind from c9a09183 to 3c85d2ec doesn't
|
||||
// handle locator hashes properly and may return blocks multiple times,
|
||||
// and this may also happen in case of a reorg.
|
||||
if self.tree.lookup(&block.header.bitcoin_hash().into_uint256(), 256).is_some() {
|
||||
if self.tree.lookup(&block.header.bitcoin_hash().into_le(), 256).is_some() {
|
||||
return Err(DuplicateHash);
|
||||
}
|
||||
// Construct node, if possible
|
||||
|
@ -515,7 +515,7 @@ impl Blockchain {
|
|||
|
||||
// Insert the new block
|
||||
let raw_ptr = &*new_block as NodePtr;
|
||||
self.tree.insert(&new_block.block.header.bitcoin_hash().into_uint256(), 256, new_block);
|
||||
self.tree.insert(&new_block.block.header.bitcoin_hash().into_le(), 256, new_block);
|
||||
// Replace the best tip if necessary
|
||||
if unsafe { (*raw_ptr).total_work > (*self.best_tip).total_work } {
|
||||
self.set_best_tip(raw_ptr);
|
||||
|
@ -565,7 +565,7 @@ impl Blockchain {
|
|||
|
||||
/// An iterator over all blocks in the chain starting from `start_hash`
|
||||
pub fn iter<'a>(&'a self, start_hash: Sha256dHash) -> BlockIter<'a> {
|
||||
let start = match self.tree.lookup(&start_hash.into_uint256(), 256) {
|
||||
let start = match self.tree.lookup(&start_hash.into_le(), 256) {
|
||||
Some(boxptr) => &**boxptr as NodePtr,
|
||||
None => RawPtr::null()
|
||||
};
|
||||
|
@ -577,7 +577,7 @@ impl Blockchain {
|
|||
|
||||
/// An iterator over all blocks in reverse order to the genesis, starting with `start_hash`
|
||||
pub fn rev_iter<'a>(&'a self, start_hash: Sha256dHash) -> RevBlockIter<'a> {
|
||||
let start = match self.tree.lookup(&start_hash.into_uint256(), 256) {
|
||||
let start = match self.tree.lookup(&start_hash.into_le(), 256) {
|
||||
Some(boxptr) => &**boxptr as NodePtr,
|
||||
None => RawPtr::null()
|
||||
};
|
||||
|
@ -589,7 +589,7 @@ impl Blockchain {
|
|||
|
||||
/// An iterator over all blocks -not- in the best chain, in reverse order, starting from `start_hash`
|
||||
pub fn rev_stale_iter<'a>(&'a self, start_hash: Sha256dHash) -> RevStaleBlockIter<'a> {
|
||||
let start = match self.tree.lookup(&start_hash.into_uint256(), 256) {
|
||||
let start = match self.tree.lookup(&start_hash.into_le(), 256) {
|
||||
Some(boxptr) => {
|
||||
// If we are already on the main chain, we have a dead iterator
|
||||
if boxptr.is_on_main_chain(self) {
|
||||
|
|
|
@ -112,7 +112,7 @@ impl UtxoSet {
|
|||
};
|
||||
// Get the old value, if any (this is suprisingly possible, c.f. BIP30
|
||||
// and the other comments in this file referring to it)
|
||||
let ret = self.table.swap(txid.into_uint128(), new_node);
|
||||
let ret = self.table.swap(txid.into_le().low_128(), new_node);
|
||||
if ret.is_none() {
|
||||
self.n_utxos += tx.output.len() as u64;
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ impl UtxoSet {
|
|||
// This whole function has awkward scoping thx to lexical borrow scoping :(
|
||||
let (ret, should_delete) = {
|
||||
// Locate the UTXO, failing if not found
|
||||
let node = match self.table.find_mut(&txid.into_uint128()) {
|
||||
let node = match self.table.find_mut(&txid.into_le().low_128()) {
|
||||
Some(node) => node,
|
||||
None => return None
|
||||
};
|
||||
|
@ -142,7 +142,7 @@ impl UtxoSet {
|
|||
|
||||
// Delete the whole node if it is no longer being used
|
||||
if should_delete {
|
||||
self.table.remove(&txid.into_uint128());
|
||||
self.table.remove(&txid.into_le().low_128());
|
||||
}
|
||||
|
||||
self.n_utxos -= if ret.is_some() { 1 } else { 0 };
|
||||
|
@ -152,7 +152,7 @@ impl UtxoSet {
|
|||
/// Get a reference to a UTXO in the set
|
||||
pub fn get_utxo<'a>(&'a self, txid: Sha256dHash, vout: u32) -> Option<&'a TxOut> {
|
||||
// Locate the UTXO, failing if not found
|
||||
let node = match self.table.find(&txid.into_uint128()) {
|
||||
let node = match self.table.find(&txid.into_le().low_128()) {
|
||||
Some(node) => node,
|
||||
None => return None
|
||||
};
|
||||
|
@ -317,7 +317,7 @@ impl UtxoSet {
|
|||
for ((txid, n), txo) in extract_vec.move_iter() {
|
||||
// Remove the tx's utxo list and patch the txo into place
|
||||
let new_node =
|
||||
match self.table.pop(&txid.into_uint128()) {
|
||||
match self.table.pop(&txid.into_le().low_128()) {
|
||||
Some(mut thinvec) => {
|
||||
let old_len = thinvec.len() as u32;
|
||||
if old_len < n + 1 {
|
||||
|
@ -343,7 +343,7 @@ impl UtxoSet {
|
|||
}
|
||||
};
|
||||
// Ram it back into the tree
|
||||
self.table.insert(txid.into_uint128(), new_node);
|
||||
self.table.insert(txid.into_le().low_128(), new_node);
|
||||
}
|
||||
}
|
||||
skipped_genesis = true;
|
||||
|
|
|
@ -145,20 +145,21 @@ impl Sha256dHash {
|
|||
|
||||
/// Converts a hash to a little-endian Uint256
|
||||
#[inline]
|
||||
pub fn into_uint256(self) -> Uint256 {
|
||||
pub fn into_le(self) -> Uint256 {
|
||||
let Sha256dHash(data) = self;
|
||||
unsafe { Uint256(transmute(data)) }
|
||||
let mut ret: [u64, ..4] = unsafe { transmute(data) };
|
||||
for x in ret.as_mut_slice().mut_iter() { *x = x.to_le(); }
|
||||
Uint256(ret)
|
||||
}
|
||||
|
||||
/// Converts a hash to a little-endian Uint128, using only the "low" bytes
|
||||
/// Converts a hash to a big-endian Uint256
|
||||
#[inline]
|
||||
pub fn into_uint128(self) -> Uint128 {
|
||||
let Sha256dHash(data) = self;
|
||||
// TODO: this function won't work correctly on big-endian machines
|
||||
unsafe { Uint128(transmute([data[16], data[17], data[18], data[19], data[20],
|
||||
data[21], data[22], data[23], data[24], data[25],
|
||||
data[26], data[27], data[28], data[29], data[30],
|
||||
data[31]])) }
|
||||
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(); }
|
||||
Uint256(ret)
|
||||
}
|
||||
|
||||
/// Converts a hash to a Hash32 by truncation
|
||||
|
@ -384,5 +385,15 @@ mod tests {
|
|||
"\"56944c5d3f98413ef45cf54545538103cc9f298e0575820ad3591376e2e0f65d\"".as_bytes());
|
||||
assert_eq!(json::decode(from_utf8(res.as_slice()).unwrap()), Ok(hash));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sighash_single_vec() {
|
||||
let one = Sha256dHash([1, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
assert_eq!(Some(one.into_le()), FromPrimitive::from_u64(1));
|
||||
assert_eq!(Some(one.into_le().low_128()), FromPrimitive::from_u64(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -553,7 +553,7 @@ mod tests {
|
|||
let mut tree = PatriciaTree::new();
|
||||
let mut hashes = vec![];
|
||||
for i in range(0u32, 5000) {
|
||||
let hash = Sha256dHash::from_data(&[(i / 0x100) as u8, (i % 0x100) as u8]).into_uint128();
|
||||
let hash = Sha256dHash::from_data(&[(i / 0x100) as u8, (i % 0x100) as u8]).into_le().low_128();
|
||||
tree.insert(&hash, 250, i);
|
||||
hashes.push(hash);
|
||||
}
|
||||
|
@ -594,7 +594,7 @@ mod tests {
|
|||
let mut hashes = vec![];
|
||||
// Start by inserting a bunch of chunder
|
||||
for i in range(1u32, 500) {
|
||||
let hash = Sha256dHash::from_data(&[(i / 0x100) as u8, (i % 0x100) as u8]).into_uint128();
|
||||
let hash = Sha256dHash::from_data(&[(i / 0x100) as u8, (i % 0x100) as u8]).into_le().low_128();
|
||||
tree.insert(&hash, 128, i * 1000);
|
||||
hashes.push(hash);
|
||||
}
|
||||
|
@ -626,7 +626,7 @@ mod tests {
|
|||
let mut data = Vec::from_elem(n_elems, None);
|
||||
// Start by inserting a bunch of stuff
|
||||
for i in range(0, n_elems) {
|
||||
let hash = Sha256dHash::from_data(&[(i / 0x100) as u8, (i % 0x100) as u8]).into_uint128();
|
||||
let hash = Sha256dHash::from_data(&[(i / 0x100) as u8, (i % 0x100) as u8]).into_le().low_128();
|
||||
tree.insert(&hash, 128, i);
|
||||
*data.get_mut(i) = Some(());
|
||||
}
|
||||
|
@ -648,7 +648,7 @@ mod tests {
|
|||
let mut data = Vec::from_elem(n_elems, None);
|
||||
// Start by inserting a bunch of stuff
|
||||
for i in range(0, n_elems) {
|
||||
let hash = Sha256dHash::from_data(&[(i / 0x100) as u8, (i % 0x100) as u8]).into_uint128();
|
||||
let hash = Sha256dHash::from_data(&[(i / 0x100) as u8, (i % 0x100) as u8]).into_le().low_128();
|
||||
tree.insert(&hash, 128, i);
|
||||
*data.get_mut(i) = Some(());
|
||||
}
|
||||
|
@ -674,7 +674,7 @@ mod tests {
|
|||
let mut tree = PatriciaTree::new();
|
||||
let mut hashes = vec![];
|
||||
for i in range(0u32, 5000) {
|
||||
let hash = Sha256dHash::from_data(&[(i / 0x100) as u8, (i % 0x100) as u8]).into_uint128();
|
||||
let hash = Sha256dHash::from_data(&[(i / 0x100) as u8, (i % 0x100) as u8]).into_le().low_128();
|
||||
tree.insert(&hash, 250, i);
|
||||
hashes.push(hash);
|
||||
}
|
||||
|
|
|
@ -367,6 +367,13 @@ impl Uint256 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Decay to a uint128
|
||||
#[inline]
|
||||
pub fn low_128(&self) -> Uint128 {
|
||||
let &Uint256(data) = self;
|
||||
Uint128([data[0], data[1]])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
Loading…
Reference in New Issue