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 {
|
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) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
Loading…
Reference in New Issue