Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore!: change hash to use consensus encoding #3820

Merged
merged 13 commits into from Mar 16, 2022
46 changes: 24 additions & 22 deletions base_layer/core/src/blocks/block_header.rs
Expand Up @@ -57,7 +57,11 @@ use thiserror::Error;

#[cfg(feature = "base_node")]
use crate::blocks::{BlockBuilder, NewBlockHeaderTemplate};
use crate::proof_of_work::{PowAlgorithm, PowError, ProofOfWork};
use crate::{
common::hash_writer::HashWriter,
consensus::ConsensusEncoding,
proof_of_work::{PowAlgorithm, PowError, ProofOfWork},
};

#[derive(Debug, Error)]
pub enum BlockHeaderValidationError {
Expand Down Expand Up @@ -190,21 +194,20 @@ impl BlockHeader {
/// Provides a hash of the header, used for the merge mining.
/// This differs from the normal hash by not hashing the nonce and kernel pow.
pub fn merged_mining_hash(&self) -> Vec<u8> {
HashDigest::new()
.chain(self.version.to_le_bytes())
.chain(self.height.to_le_bytes())
.chain(self.prev_hash.as_bytes())
.chain(self.timestamp.as_u64().to_le_bytes())
.chain(self.input_mr.as_bytes())
.chain(self.output_mr.as_bytes())
.chain(self.output_mmr_size.to_le_bytes())
.chain(self.witness_mr.as_bytes())
.chain(self.kernel_mr.as_bytes())
.chain(self.kernel_mmr_size.to_le_bytes())
.chain(self.total_kernel_offset.as_bytes())
.chain(self.total_script_offset.as_bytes())
.finalize()
.to_vec()
let mut hasher = HashWriter::new(HashDigest::new());
self.version.consensus_encode(&mut hasher).unwrap();
self.height.consensus_encode(&mut hasher).unwrap();
self.prev_hash.consensus_encode(&mut hasher).unwrap();
self.timestamp.as_u64().consensus_encode(&mut hasher).unwrap();
self.input_mr.consensus_encode(&mut hasher).unwrap();
self.output_mr.consensus_encode(&mut hasher).unwrap();
self.output_mmr_size.consensus_encode(&mut hasher).unwrap();
self.witness_mr.consensus_encode(&mut hasher).unwrap();
self.kernel_mr.consensus_encode(&mut hasher).unwrap();
self.kernel_mmr_size.consensus_encode(&mut hasher).unwrap();
self.total_kernel_offset.consensus_encode(&mut hasher).unwrap();
self.total_script_offset.consensus_encode(&mut hasher).unwrap();
hasher.finalize().to_vec()
}

#[inline]
Expand Down Expand Up @@ -243,12 +246,11 @@ impl From<NewBlockHeaderTemplate> for BlockHeader {

impl Hashable for BlockHeader {
fn hash(&self) -> Vec<u8> {
HashDigest::new()
.chain(self.merged_mining_hash())
.chain(self.pow.to_bytes())
.chain(self.nonce.to_le_bytes())
.finalize()
.to_vec()
let mut hasher = HashWriter::new(HashDigest::new());
self.merged_mining_hash().consensus_encode(&mut hasher).unwrap();
sdbondi marked this conversation as resolved.
Show resolved Hide resolved
self.pow.consensus_encode(&mut hasher).unwrap();
self.nonce.consensus_encode(&mut hasher).unwrap();
hasher.finalize().to_vec()
}
}

Expand Down
25 changes: 23 additions & 2 deletions base_layer/core/src/proof_of_work/proof_of_work.rs
Expand Up @@ -20,13 +20,20 @@
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use std::fmt::{Display, Error, Formatter};
use std::{
fmt::{Display, Error, Formatter},
io::{self, Write},
};

use bytes::BufMut;
use integer_encoding::{VarInt, VarIntWriter};
use serde::{Deserialize, Serialize};
use tari_crypto::tari_utilities::hex::Hex;

use crate::proof_of_work::PowAlgorithm;
use crate::{
consensus::{ConsensusEncoding, ConsensusEncodingSized},
proof_of_work::PowAlgorithm,
};

pub trait AchievedDifficulty {}

Expand Down Expand Up @@ -89,6 +96,20 @@ impl Display for ProofOfWork {
}
}

impl ConsensusEncoding for ProofOfWork {
fn consensus_encode<W: Write>(&self, writer: &mut W) -> Result<usize, io::Error> {
let mut written = writer.write_varint(self.pow_algo.as_u64())?;
Cifko marked this conversation as resolved.
Show resolved Hide resolved
written += self.pow_data.consensus_encode(writer)?;
Ok(written)
}
}

impl ConsensusEncodingSized for ProofOfWork {
fn consensus_encode_exact_size(&self) -> usize {
self.pow_algo.as_u64().required_space() + self.pow_data.consensus_encode_exact_size()
Cifko marked this conversation as resolved.
Show resolved Hide resolved
}
}

#[cfg(test)]
mod test {
use crate::proof_of_work::proof_of_work::{PowAlgorithm, ProofOfWork};
Expand Down