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

Dev/optimize merkle root #227

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions packages/consensus/src/validation/block.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ pub fn compute_and_validate_tx_data(
block_time: u32,
ref utxo_set: UtxoSet
) -> Result<(u64, Digest, Digest), ByteArray> {
let mut txids: Array<Digest> = array![];
let mut wtxids: Array<Digest> = array![];
let mut txids: Array<Box<[u32; 8]>> = array![];
let mut wtxids: Array<Box<[u32; 8]>> = array![];
let mut total_fee = 0;
let mut total_weight: u32 = 0;
let mut inner_result = Result::Ok(());
Expand All @@ -49,8 +49,8 @@ pub fn compute_and_validate_tx_data(
let txid = double_sha256_byte_array(tx_bytes_legacy);

if block_height >= SEGWIT_BLOCK {
let tx_bytes_segwit = @tx
.encode_with_witness(tx_bytes_legacy); // SegWit transaction encoding
// SegWit transaction encoding
let tx_bytes_segwit = @tx.encode_with_witness(tx_bytes_legacy);

/// The wTXID for the coinbase transaction must be set to all zeros. This is because
/// it's eventually going to contain the commitment inside it
Expand All @@ -61,16 +61,16 @@ pub fn compute_and_validate_tx_data(
double_sha256_byte_array(tx_bytes_segwit)
};

total_weight += 3 * tx_bytes_legacy.len()
+ tx_bytes_segwit.len(); // Calculate block weight with SegWit
// Calculate block weight with SegWit
total_weight += 3 * tx_bytes_legacy.len() + tx_bytes_segwit.len();

wtxids.append(wtxid); // Append wtxid to array
wtxids.append(BoxTrait::new(wtxid.value));
} else {
// For blocks before SegWit, only legacy tx weight is considered
total_weight += 4 * tx_bytes_legacy.len(); // Calculate block weight without SegWit
}

txids.append(txid);
txids.append(BoxTrait::new(txid.value));

if (is_coinbase) {
let mut vout = 0;
Expand Down Expand Up @@ -110,13 +110,15 @@ pub fn compute_and_validate_tx_data(
inner_result?;
validate_block_weight(total_weight)?;

let mut txid_root = DigestTrait::new(merkle_root(txids.span()).unbox());
let wtxid_root = if block_height >= SEGWIT_BLOCK {
merkle_root(wtxids.span())
let mut wtxid_root = merkle_root(wtxids.span());
DigestTrait::new(wtxid_root.unbox())
} else {
Zero::zero()
};

Result::Ok((total_fee, merkle_root(txids.span()), wtxid_root))
Result::Ok((total_fee, txid_root, wtxid_root))
}

/// Validates that the block hash at certain heights matches the expected hash according to BIP-30.
Expand Down
48 changes: 48 additions & 0 deletions packages/utils/src/double_sha256.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,54 @@
use super::hash::{Digest, DigestTrait};
use super::sha256::{compute_sha256_byte_array, compute_sha256_u32_array};

use core::gas::GasBuiltin;
use starknet::{SyscallResult, SyscallResultTrait};

/// A handle to the state of a SHA-256 hash.
#[derive(Copy, Drop)]
pub(crate) extern type Sha256StateHandle;

/// Initializes a new SHA-256 state handle.
extern fn sha256_state_handle_init(state: Box<[u32; 8]>) -> Sha256StateHandle nopanic;

/// returns the state of a SHA-256 hash.
extern fn sha256_state_handle_digest(state: Sha256StateHandle) -> Box<[u32; 8]> nopanic;

pub extern fn sha256_process_block_syscall(
state: Sha256StateHandle, input: Box<[u32; 16]>
) -> SyscallResult<Sha256StateHandle> implicits(GasBuiltin, System) nopanic;

const SHA256_INITIAL_STATE: [
u32
; 8] = [
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
];

const input_padding: [
u32
; 16] = [
0x80000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200
];

/// Calculates double sha256 digest perf
pub fn digest_double_sha256(inputs: Box<[u32; 16]>) -> Box<[u32; 8]> {
//stage 1
let mut state1 = sha256_state_handle_init(BoxTrait::new(SHA256_INITIAL_STATE));
state1 = sha256_process_block_syscall(state1, inputs).unwrap_syscall();
state1 = sha256_process_block_syscall(state1, BoxTrait::new(input_padding)).unwrap_syscall();
let output1: [u32; 8] = sha256_state_handle_digest(state1).unbox();

//stage 2
let mut state2 = sha256_state_handle_init(BoxTrait::new(SHA256_INITIAL_STATE));
let [i0, i1, i2, i3, i4, i5, i6, i7] = output1;
let tmp: Box<[u32; 16]> = BoxTrait::new(
[i0, i1, i2, i3, i4, i5, i6, i7, 0x80000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100],
);
state2 = sha256_process_block_syscall(state2, tmp).unwrap_syscall();

sha256_state_handle_digest(state2)
}

/// Calculates double sha256 digest of a concatenation of two hashes.
pub fn double_sha256_parent(a: @Digest, b: @Digest) -> Digest {
let mut input1: Array<u32> = array![];
Expand Down
Loading
Loading