mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-10 23:27:56 -05:00
blockchain/Block: proper hash usage
This commit is contained in:
@@ -108,11 +108,10 @@ impl Block {
|
||||
fn hash(&self) -> Result<blake2b_simd::Hash> {
|
||||
let mut hasher = blake2b_simd::Params::new().hash_length(HASH_LEN).to_state();
|
||||
|
||||
let mut len: usize = 0;
|
||||
len += self.header.encode(&mut hasher)?;
|
||||
len += self.header.txtree.root(0).unwrap().encode(&mut hasher)?;
|
||||
len += self.txs.len().encode(&mut hasher)?;
|
||||
len.encode(&mut hasher)?;
|
||||
self.header.nonce.encode(&mut hasher)?;
|
||||
self.header.previous_hash.encode(&mut hasher)?;
|
||||
self.header.timestamp.encode(&mut hasher)?;
|
||||
self.header.txtree.root(0).unwrap().encode(&mut hasher)?;
|
||||
|
||||
Ok(hasher.finalize())
|
||||
}
|
||||
|
||||
@@ -52,11 +52,17 @@ impl Block {
|
||||
Self { header, txs, signature }
|
||||
}
|
||||
|
||||
/// Compute the block's blockchain hash
|
||||
pub fn hash(&self) -> Result<blake3::Hash> {
|
||||
let mut hasher = blake3::Hasher::new();
|
||||
self.encode(&mut hasher)?;
|
||||
Ok(hasher.finalize())
|
||||
/// A block's hash is the same as the hash of its header
|
||||
pub fn hash(&self) -> blake3::Hash {
|
||||
self.header
|
||||
}
|
||||
|
||||
/// Generate a `Block` from a `BlockInfo`
|
||||
pub fn from_block_info(block_info: &BlockInfo) -> Result<Self> {
|
||||
let header = block_info.header.hash()?;
|
||||
let txs = block_info.txs.iter().map(|x| blake3::hash(&serialize(x))).collect();
|
||||
let signature = block_info.signature;
|
||||
Ok(Self { header, txs, signature })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,22 +113,15 @@ impl BlockInfo {
|
||||
Self { header, txs, signature, slots }
|
||||
}
|
||||
|
||||
/// Compute the block's blockchain hash
|
||||
/// A block's hash is the same as the hash of its header
|
||||
pub fn hash(&self) -> Result<blake3::Hash> {
|
||||
let block: Block = self.clone().into();
|
||||
block.hash()
|
||||
self.header.hash()
|
||||
}
|
||||
|
||||
/// Compute the block's hash used for mining
|
||||
pub fn mining_hash(&self) -> Result<blake3::Hash> {
|
||||
/// Compute the block's full hash
|
||||
pub fn full_hash(&self) -> Result<blake3::Hash> {
|
||||
let mut hasher = blake3::Hasher::new();
|
||||
|
||||
let mut len: usize = 0;
|
||||
len += self.header.encode(&mut hasher)?;
|
||||
len += self.header.tree.root(0).unwrap().encode(&mut hasher)?;
|
||||
len += self.txs.len().encode(&mut hasher)?;
|
||||
len.encode(&mut hasher)?;
|
||||
|
||||
self.encode(&mut hasher)?;
|
||||
Ok(hasher.finalize())
|
||||
}
|
||||
|
||||
@@ -149,13 +148,6 @@ impl BlockInfo {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BlockInfo> for Block {
|
||||
fn from(block_info: BlockInfo) -> Self {
|
||||
let txs = block_info.txs.iter().map(|x| blake3::hash(&serialize(x))).collect();
|
||||
Self { header: block_info.header.hash().unwrap(), txs, signature: block_info.signature }
|
||||
}
|
||||
}
|
||||
|
||||
/// [`Block`] sled tree
|
||||
const SLED_BLOCK_TREE: &[u8] = b"_blocks";
|
||||
|
||||
@@ -180,17 +172,16 @@ impl BlockStore {
|
||||
|
||||
/// Generate the sled batch corresponding to an insert, so caller
|
||||
/// can handle the write operation.
|
||||
/// The blocks are hashed with BLAKE3 and this block hash is used as
|
||||
/// the key, while value is the serialized [`Block`] itself.
|
||||
/// The block's hash() function output is used as the key,
|
||||
/// while value is the serialized [`Block`] itself.
|
||||
/// On success, the function returns the block hashes in the same order.
|
||||
pub fn insert_batch(&self, blocks: &[Block]) -> Result<(sled::Batch, Vec<blake3::Hash>)> {
|
||||
let mut ret = Vec::with_capacity(blocks.len());
|
||||
let mut batch = sled::Batch::default();
|
||||
|
||||
for block in blocks {
|
||||
let serialized = serialize(block);
|
||||
let blockhash = blake3::hash(&serialized);
|
||||
batch.insert(blockhash.as_bytes(), serialized);
|
||||
let blockhash = block.hash();
|
||||
batch.insert(blockhash.as_bytes(), serialize(block));
|
||||
ret.push(blockhash);
|
||||
}
|
||||
|
||||
@@ -250,17 +241,16 @@ impl BlockStoreOverlay {
|
||||
}
|
||||
|
||||
/// Insert a slice of [`Block`] into the overlay.
|
||||
/// The block are hashed with BLAKE3 and this block hash is used as
|
||||
/// the key, while value is the serialized [`Block`] itself.
|
||||
/// The block's hash() function output is used as the key,
|
||||
/// while value is the serialized [`Block`] itself.
|
||||
/// On success, the function returns the block hashes in the same order.
|
||||
pub fn insert(&self, blocks: &[Block]) -> Result<Vec<blake3::Hash>> {
|
||||
let mut ret = Vec::with_capacity(blocks.len());
|
||||
let mut lock = self.0.lock().unwrap();
|
||||
|
||||
for block in blocks {
|
||||
let serialized = serialize(block);
|
||||
let blockhash = blake3::hash(&serialized);
|
||||
lock.insert(SLED_BLOCK_TREE, blockhash.as_bytes(), &serialized)?;
|
||||
let blockhash = block.hash();
|
||||
lock.insert(SLED_BLOCK_TREE, blockhash.as_bytes(), &serialize(block))?;
|
||||
ret.push(blockhash);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,15 @@ impl Header {
|
||||
/// Compute the header's hash
|
||||
pub fn hash(&self) -> Result<blake3::Hash> {
|
||||
let mut hasher = blake3::Hasher::new();
|
||||
self.encode(&mut hasher)?;
|
||||
|
||||
self.version.encode(&mut hasher)?;
|
||||
self.previous.encode(&mut hasher)?;
|
||||
self.epoch.encode(&mut hasher)?;
|
||||
self.height.encode(&mut hasher)?;
|
||||
self.timestamp.encode(&mut hasher)?;
|
||||
self.nonce.encode(&mut hasher)?;
|
||||
self.tree.root(0).unwrap().encode(&mut hasher)?;
|
||||
|
||||
Ok(hasher.finalize())
|
||||
}
|
||||
}
|
||||
@@ -108,8 +116,8 @@ impl HeaderStore {
|
||||
|
||||
/// Generate the sled batch corresponding to an insert, so caller
|
||||
/// can handle the write operation.
|
||||
/// The headers are hashed with BLAKE3 and this header hash is used as
|
||||
/// the key, while value is the serialized [`Header`] itself.
|
||||
/// The header's hash() function output is used as the key,
|
||||
/// while value is the serialized [`Header`] itself.
|
||||
/// On success, the function returns the header hashes in the same
|
||||
/// order, along with the corresponding operation batch.
|
||||
pub fn insert_batch(&self, headers: &[Header]) -> Result<(sled::Batch, Vec<blake3::Hash>)> {
|
||||
@@ -117,9 +125,8 @@ impl HeaderStore {
|
||||
let mut batch = sled::Batch::default();
|
||||
|
||||
for header in headers {
|
||||
let serialized = serialize(header);
|
||||
let headerhash = blake3::hash(&serialized);
|
||||
batch.insert(headerhash.as_bytes(), serialized);
|
||||
let headerhash = header.hash()?;
|
||||
batch.insert(headerhash.as_bytes(), serialize(header));
|
||||
ret.push(headerhash);
|
||||
}
|
||||
|
||||
@@ -179,17 +186,16 @@ impl HeaderStoreOverlay {
|
||||
}
|
||||
|
||||
/// Insert a slice of [`Header`] into the overlay.
|
||||
/// The headers are hashed with BLAKE3 and this headerhash is used as
|
||||
/// the key, while value is the serialized [`Header`] itself.
|
||||
/// The header's hash() function output is used as the key,
|
||||
/// while value is the serialized [`Header`] itself.
|
||||
/// On success, the function returns the header hashes in the same order.
|
||||
pub fn insert(&self, headers: &[Header]) -> Result<Vec<blake3::Hash>> {
|
||||
let mut ret = Vec::with_capacity(headers.len());
|
||||
let mut lock = self.0.lock().unwrap();
|
||||
|
||||
for header in headers {
|
||||
let serialized = serialize(header);
|
||||
let headerhash = blake3::hash(&serialized);
|
||||
lock.insert(SLED_HEADER_TREE, headerhash.as_bytes(), &serialized)?;
|
||||
let headerhash = header.hash()?;
|
||||
lock.insert(SLED_HEADER_TREE, headerhash.as_bytes(), &serialize(header))?;
|
||||
ret.push(headerhash);
|
||||
}
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ impl Blockchain {
|
||||
batches.push(headers_batch);
|
||||
|
||||
// Store block
|
||||
let blk: Block = Block::from(block.clone());
|
||||
let blk: Block = Block::from_block_info(block)?;
|
||||
let (bocks_batch, block_hashes) = self.blocks.insert_batch(&[blk])?;
|
||||
let block_hash = block_hashes[0];
|
||||
let block_hash_vec = [block_hash];
|
||||
@@ -219,7 +219,7 @@ impl Blockchain {
|
||||
// Retrieve extra stuff based on block version
|
||||
let mut block_slots = vec![];
|
||||
if header.version > 0 {
|
||||
let slots = self.blocks_slots.get(&[block.hash()?], true)?;
|
||||
let slots = self.blocks_slots.get(&[block.hash()], true)?;
|
||||
let slots = slots[0].clone().unwrap();
|
||||
let slots = self.slots.get(&slots, true)?;
|
||||
block_slots = slots.iter().map(|x| x.clone().unwrap()).collect();
|
||||
@@ -484,7 +484,7 @@ impl BlockchainOverlay {
|
||||
self.headers.insert(&[block.header.clone()])?;
|
||||
|
||||
// Store block
|
||||
let blk: Block = Block::from(block.clone());
|
||||
let blk: Block = Block::from_block_info(block)?;
|
||||
let block_hash = self.blocks.insert(&[blk])?[0];
|
||||
let block_hash_vec = [block_hash];
|
||||
|
||||
@@ -564,7 +564,7 @@ impl BlockchainOverlay {
|
||||
// Retrieve extra stuff based on block version
|
||||
let mut block_slots = vec![];
|
||||
if header.version > 0 {
|
||||
let slots = self.blocks_slots.get(&[block.hash()?], true)?;
|
||||
let slots = self.blocks_slots.get(&[block.hash()], true)?;
|
||||
let slots = slots[0].clone().unwrap();
|
||||
let slots = self.slots.get(&slots, true)?;
|
||||
block_slots = slots.iter().map(|x| x.clone().unwrap()).collect();
|
||||
|
||||
@@ -61,7 +61,7 @@ fn consensus_contract_stake_unstake() -> Result<()> {
|
||||
|
||||
// Now Alice can stake her owncoin
|
||||
let alice_staked_oc =
|
||||
th.execute_stake(&HOLDERS, &Holder::Alice, current_slot, &alice_oc, 28).await?;
|
||||
th.execute_stake(&HOLDERS, &Holder::Alice, current_slot, &alice_oc, 181).await?;
|
||||
|
||||
// We progress after grace period
|
||||
current_slot += (calculate_grace_period() * EPOCH_LENGTH) + EPOCH_LENGTH;
|
||||
@@ -98,7 +98,7 @@ fn consensus_contract_stake_unstake() -> Result<()> {
|
||||
|
||||
// Now Alice can stake her unstaked owncoin again to try some mallicious cases
|
||||
let alice_staked_oc = th
|
||||
.execute_stake(&HOLDERS, &Holder::Alice, current_slot, &alice_unstaked_oc, 92)
|
||||
.execute_stake(&HOLDERS, &Holder::Alice, current_slot, &alice_unstaked_oc, 148)
|
||||
.await?;
|
||||
|
||||
// Alice tries to stake her coin again
|
||||
@@ -106,7 +106,7 @@ fn consensus_contract_stake_unstake() -> Result<()> {
|
||||
info!(target: "consensus", "[Malicious] Checking staking coin again");
|
||||
info!(target: "consensus", "[Malicious] ===========================");
|
||||
let (stake_tx, _, _) = th
|
||||
.stake(&Holder::Alice, current_slot, &alice_unstaked_oc, pallas::Base::from(92))
|
||||
.stake(&Holder::Alice, current_slot, &alice_unstaked_oc, pallas::Base::from(148))
|
||||
.await?;
|
||||
th.execute_erroneous_txs(
|
||||
TxAction::ConsensusStake,
|
||||
@@ -188,7 +188,7 @@ fn consensus_contract_stake_unstake() -> Result<()> {
|
||||
|
||||
// Now Alice can stake her unstaked owncoin again
|
||||
let alice_staked_oc = th
|
||||
.execute_stake(&HOLDERS, &Holder::Alice, current_slot, &alice_unstaked_oc, 77)
|
||||
.execute_stake(&HOLDERS, &Holder::Alice, current_slot, &alice_unstaked_oc, 86)
|
||||
.await?;
|
||||
|
||||
// We progress after grace period
|
||||
|
||||
@@ -62,7 +62,7 @@ impl TestHarness {
|
||||
pallas::Scalar::random(&mut OsRng),
|
||||
pallas::Base::random(&mut OsRng),
|
||||
pallas::Scalar::random(&mut OsRng),
|
||||
pallas::Base::from(41),
|
||||
pallas::Base::from(62),
|
||||
)?;
|
||||
|
||||
let (genesis_stake_params, genesis_stake_proofs) =
|
||||
|
||||
Reference in New Issue
Block a user