Rename Hash->Uint functions to denote endianness

This commit is contained in:
Andrew Poelstra 2014-08-24 12:28:02 -07:00
parent 3a921e6b9c
commit 688a77ef38
6 changed files with 53 additions and 35 deletions

View File

@ -101,7 +101,7 @@ impl BlockHeader {
if target != required_target { if target != required_target {
return Err(SpvBadTarget); 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) } if hash <= target { Ok(()) } else { Err(SpvBadProofOfWork) }
} }

View File

@ -141,20 +141,20 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Blockchain {
let genesis_hash: Sha256dHash = try!(ConsensusDecodable::consensus_decode(d)); let genesis_hash: Sha256dHash = try!(ConsensusDecodable::consensus_decode(d));
// Lookup best tip // 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, Some(node) => &**node as NodePtr,
None => { None => {
return Err(d.error(format!("best tip {:x} not in tree", best_hash).as_slice())); return Err(d.error(format!("best tip {:x} not in tree", best_hash).as_slice()));
} }
}; };
// Lookup genesis // 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())); return Err(d.error(format!("genesis {:x} not in tree", genesis_hash).as_slice()));
} }
// Reconnect all prev pointers // Reconnect all prev pointers
let raw_tree = &tree as *const _; let raw_tree = &tree as *const _;
for node in tree.mut_iter() { 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 = let prevptr =
match unsafe { (*raw_tree).lookup(&hash, 256) } { match unsafe { (*raw_tree).lookup(&hash, 256) } {
Some(node) => &**node as NodePtr, Some(node) => &**node as NodePtr,
@ -355,7 +355,7 @@ impl Blockchain {
network: network, network: network,
tree: { tree: {
let mut pat = PatriciaTree::new(); let mut pat = PatriciaTree::new();
pat.insert(&genhash.into_uint256(), 256, new_node); pat.insert(&genhash.into_le(), 256, new_node);
pat pat
}, },
best_hash: genhash, best_hash: genhash,
@ -400,17 +400,17 @@ impl Blockchain {
/// Looks up a block in the chain and returns the BlockchainNode containing it /// 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> { 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 /// Locates a block in the chain and overwrites its txdata
pub fn add_txdata(&mut self, block: Block) -> BitcoinResult<()> { 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 /// Locates a block in the chain and removes its txdata
pub fn remove_txdata(&mut self, hash: Sha256dHash) -> BitcoinResult<()> { 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 /// Adds a block header to the chain
@ -430,13 +430,13 @@ impl Blockchain {
if hash == chain.best_hash { if hash == chain.best_hash {
Some(chain.best_tip) Some(chain.best_tip)
} else { } 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 // Check for multiple inserts (bitcoind from c9a09183 to 3c85d2ec doesn't
// handle locator hashes properly and may return blocks multiple times, // handle locator hashes properly and may return blocks multiple times,
// and this may also happen in case of a reorg. // 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); return Err(DuplicateHash);
} }
// Construct node, if possible // Construct node, if possible
@ -515,7 +515,7 @@ impl Blockchain {
// Insert the new block // Insert the new block
let raw_ptr = &*new_block as NodePtr; 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 // Replace the best tip if necessary
if unsafe { (*raw_ptr).total_work > (*self.best_tip).total_work } { if unsafe { (*raw_ptr).total_work > (*self.best_tip).total_work } {
self.set_best_tip(raw_ptr); self.set_best_tip(raw_ptr);
@ -565,7 +565,7 @@ impl Blockchain {
/// An iterator over all blocks in the chain starting from `start_hash` /// An iterator over all blocks in the chain starting from `start_hash`
pub fn iter<'a>(&'a self, start_hash: Sha256dHash) -> BlockIter<'a> { 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, Some(boxptr) => &**boxptr as NodePtr,
None => RawPtr::null() None => RawPtr::null()
}; };
@ -577,7 +577,7 @@ impl Blockchain {
/// An iterator over all blocks in reverse order to the genesis, starting with `start_hash` /// 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> { 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, Some(boxptr) => &**boxptr as NodePtr,
None => RawPtr::null() 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` /// 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> { 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) => { Some(boxptr) => {
// If we are already on the main chain, we have a dead iterator // If we are already on the main chain, we have a dead iterator
if boxptr.is_on_main_chain(self) { if boxptr.is_on_main_chain(self) {

View File

@ -112,7 +112,7 @@ impl UtxoSet {
}; };
// Get the old value, if any (this is suprisingly possible, c.f. BIP30 // Get the old value, if any (this is suprisingly possible, c.f. BIP30
// and the other comments in this file referring to it) // 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() { if ret.is_none() {
self.n_utxos += tx.output.len() as u64; 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 :( // This whole function has awkward scoping thx to lexical borrow scoping :(
let (ret, should_delete) = { let (ret, should_delete) = {
// Locate the UTXO, failing if not found // 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, Some(node) => node,
None => return None None => return None
}; };
@ -142,7 +142,7 @@ impl UtxoSet {
// Delete the whole node if it is no longer being used // Delete the whole node if it is no longer being used
if should_delete { 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 }; 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 /// Get a reference to a UTXO in the set
pub fn get_utxo<'a>(&'a self, txid: Sha256dHash, vout: u32) -> Option<&'a TxOut> { pub fn get_utxo<'a>(&'a self, txid: Sha256dHash, vout: u32) -> Option<&'a TxOut> {
// Locate the UTXO, failing if not found // 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, Some(node) => node,
None => return None None => return None
}; };
@ -317,7 +317,7 @@ impl UtxoSet {
for ((txid, n), txo) in extract_vec.move_iter() { for ((txid, n), txo) in extract_vec.move_iter() {
// Remove the tx's utxo list and patch the txo into place // Remove the tx's utxo list and patch the txo into place
let new_node = let new_node =
match self.table.pop(&txid.into_uint128()) { match self.table.pop(&txid.into_le().low_128()) {
Some(mut thinvec) => { Some(mut thinvec) => {
let old_len = thinvec.len() as u32; let old_len = thinvec.len() as u32;
if old_len < n + 1 { if old_len < n + 1 {
@ -343,7 +343,7 @@ impl UtxoSet {
} }
}; };
// Ram it back into the tree // 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; skipped_genesis = true;

View File

@ -145,20 +145,21 @@ impl Sha256dHash {
/// Converts a hash to a little-endian Uint256 /// Converts a hash to a little-endian Uint256
#[inline] #[inline]
pub fn into_uint256(self) -> Uint256 { pub fn into_le(self) -> Uint256 {
let Sha256dHash(data) = self; 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] #[inline]
pub fn into_uint128(self) -> Uint128 { pub fn into_be(self) -> Uint256 {
let Sha256dHash(data) = self; let Sha256dHash(mut data) = self;
// TODO: this function won't work correctly on big-endian machines data.reverse();
unsafe { Uint128(transmute([data[16], data[17], data[18], data[19], data[20], let mut ret: [u64, ..4] = unsafe { transmute(data) };
data[21], data[22], data[23], data[24], data[25], for x in ret.mut_iter() { *x = x.to_be(); }
data[26], data[27], data[28], data[29], data[30], Uint256(ret)
data[31]])) }
} }
/// Converts a hash to a Hash32 by truncation /// Converts a hash to a Hash32 by truncation
@ -384,5 +385,15 @@ mod tests {
"\"56944c5d3f98413ef45cf54545538103cc9f298e0575820ad3591376e2e0f65d\"".as_bytes()); "\"56944c5d3f98413ef45cf54545538103cc9f298e0575820ad3591376e2e0f65d\"".as_bytes());
assert_eq!(json::decode(from_utf8(res.as_slice()).unwrap()), Ok(hash)); 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));
}
} }

View File

@ -553,7 +553,7 @@ mod tests {
let mut tree = PatriciaTree::new(); let mut tree = PatriciaTree::new();
let mut hashes = vec![]; let mut hashes = vec![];
for i in range(0u32, 5000) { 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); tree.insert(&hash, 250, i);
hashes.push(hash); hashes.push(hash);
} }
@ -594,7 +594,7 @@ mod tests {
let mut hashes = vec![]; let mut hashes = vec![];
// Start by inserting a bunch of chunder // Start by inserting a bunch of chunder
for i in range(1u32, 500) { 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); tree.insert(&hash, 128, i * 1000);
hashes.push(hash); hashes.push(hash);
} }
@ -626,7 +626,7 @@ mod tests {
let mut data = Vec::from_elem(n_elems, None); let mut data = Vec::from_elem(n_elems, None);
// Start by inserting a bunch of stuff // Start by inserting a bunch of stuff
for i in range(0, n_elems) { 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); tree.insert(&hash, 128, i);
*data.get_mut(i) = Some(()); *data.get_mut(i) = Some(());
} }
@ -648,7 +648,7 @@ mod tests {
let mut data = Vec::from_elem(n_elems, None); let mut data = Vec::from_elem(n_elems, None);
// Start by inserting a bunch of stuff // Start by inserting a bunch of stuff
for i in range(0, n_elems) { 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); tree.insert(&hash, 128, i);
*data.get_mut(i) = Some(()); *data.get_mut(i) = Some(());
} }
@ -674,7 +674,7 @@ mod tests {
let mut tree = PatriciaTree::new(); let mut tree = PatriciaTree::new();
let mut hashes = vec![]; let mut hashes = vec![];
for i in range(0u32, 5000) { 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); tree.insert(&hash, 250, i);
hashes.push(hash); hashes.push(hash);
} }

View File

@ -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)] #[cfg(test)]