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

feat: Use tail public inputs as transaction hash #11100

Merged
merged 35 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
58bbabc
chore: Refactor tail public inputs
sirasistant Jan 3, 2025
250a23d
fixes
sirasistant Jan 3, 2025
31fb61c
rename structs
sirasistant Jan 3, 2025
e703574
fix
sirasistant Jan 3, 2025
ed2ae8a
Merge branch 'master' into arv/refactor_tail_public_inputs
sirasistant Jan 7, 2025
247eb4c
renaming
sirasistant Jan 7, 2025
8b1407f
Merge branch 'arv/refactor_tail_public_inputs' of github.com:AztecPro…
sirasistant Jan 7, 2025
a0f0087
fix bad merge
sirasistant Jan 7, 2025
4938eb0
fmt
sirasistant Jan 7, 2025
52c94d4
fix
sirasistant Jan 7, 2025
2986210
update constants
sirasistant Jan 7, 2025
f74cf0a
wip tx hash
sirasistant Jan 7, 2025
3d9022c
update tx hash computation
sirasistant Jan 7, 2025
e4de49d
fix constants in processedtx
sirasistant Jan 7, 2025
d7b1379
Merge branch 'arv/refactor_tail_public_inputs' into arv/tx_hash_is_tx…
sirasistant Jan 7, 2025
c6d133e
fix
sirasistant Jan 7, 2025
eb0afc0
fix tobuffer
sirasistant Jan 7, 2025
bda845c
Merge branch 'master' into arv/tx_hash_is_tx_object
sirasistant Jan 8, 2025
0058c2b
fix
sirasistant Jan 8, 2025
9f7b6d5
fix blob parsing
sirasistant Jan 8, 2025
6bf9a22
fixes
sirasistant Jan 8, 2025
6a7427c
fix note processing unit test
sirasistant Jan 8, 2025
d21015e
fix public nonce computation
sirasistant Jan 9, 2025
d145dcb
remove console log
sirasistant Jan 9, 2025
8d79883
fix
sirasistant Jan 9, 2025
3254f23
fix
sirasistant Jan 9, 2025
a835bf6
added profiling
sirasistant Jan 9, 2025
cb68fab
fix logs
sirasistant Jan 9, 2025
df53d4f
fix log level
sirasistant Jan 9, 2025
67de841
remove profiling logs
sirasistant Jan 10, 2025
9b51829
remvoe optional
sirasistant Jan 10, 2025
2c7a005
Merge branch 'master' into arv/tx_hash_is_tx_object
sirasistant Jan 10, 2025
3cb2efa
fix docs
sirasistant Jan 10, 2025
7be5e50
fix test of blob building
sirasistant Jan 10, 2025
8632c49
Merge branch 'master' into arv/tx_hash_is_tx_object
sirasistant Jan 10, 2025
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
7 changes: 4 additions & 3 deletions barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,8 @@ void AvmTraceBuilder::insert_private_revertible_state(const std::vector<FF>& sil

for (size_t i = 0; i < siloed_note_hashes.size(); i++) {
size_t note_index_in_tx = i + get_inserted_note_hashes_count();
FF nonce = AvmMerkleTreeTraceBuilder::unconstrained_compute_note_hash_nonce(get_tx_hash(), note_index_in_tx);
FF nonce =
AvmMerkleTreeTraceBuilder::unconstrained_compute_note_hash_nonce(get_first_nullifier(), note_index_in_tx);
unique_note_hashes.push_back(
AvmMerkleTreeTraceBuilder::unconstrained_compute_unique_note_hash(nonce, siloed_note_hashes.at(i)));
}
Expand Down Expand Up @@ -3101,8 +3102,8 @@ AvmError AvmTraceBuilder::op_emit_note_hash(uint8_t indirect, uint32_t note_hash
AppendTreeHint note_hash_write_hint = execution_hints.note_hash_write_hints.at(note_hash_write_counter++);
FF siloed_note_hash = AvmMerkleTreeTraceBuilder::unconstrained_silo_note_hash(
current_public_call_request.contract_address, row.main_ia);
FF nonce =
AvmMerkleTreeTraceBuilder::unconstrained_compute_note_hash_nonce(get_tx_hash(), inserted_note_hashes_count);
FF nonce = AvmMerkleTreeTraceBuilder::unconstrained_compute_note_hash_nonce(get_first_nullifier(),
inserted_note_hashes_count);
FF unique_note_hash = AvmMerkleTreeTraceBuilder::unconstrained_compute_unique_note_hash(nonce, siloed_note_hash);

ASSERT(unique_note_hash == note_hash_write_hint.leaf_value);
Expand Down
2 changes: 1 addition & 1 deletion barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ class AvmTraceBuilder {
uint32_t get_inserted_note_hashes_count();
uint32_t get_inserted_nullifiers_count();
uint32_t get_public_data_writes_count();
FF get_tx_hash() const { return public_inputs.previous_non_revertible_accumulated_data.nullifiers[0]; }
FF get_first_nullifier() const { return public_inputs.previous_non_revertible_accumulated_data.nullifiers[0]; }

// TODO: remove these once everything is constrained.
AvmMemoryTag unconstrained_get_memory_tag(AddressWithMode addr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use types::{
};

pub(crate) struct TxEffect {
pub(crate) tx_hash: Field,
pub(crate) revert_code: u8,
pub(crate) transaction_fee: Field,
pub(crate) note_hashes: [Field; MAX_NOTE_HASHES_PER_TX],
Expand All @@ -25,6 +26,7 @@ pub(crate) struct TxEffect {
impl Empty for TxEffect {
fn empty() -> Self {
TxEffect {
tx_hash: 0,
revert_code: 0,
transaction_fee: 0,
note_hashes: [0; MAX_NOTE_HASHES_PER_TX],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ impl PrivateBaseRollupInputs {

let out_hash = compute_kernel_out_hash(siloed_l2_to_l1_msgs);
let tx_effect = TxEffect {
tx_hash: self.tube_data.public_inputs.hash(),
revert_code: 0,
transaction_fee,
note_hashes: self.tube_data.public_inputs.end.note_hashes,
Expand Down Expand Up @@ -247,7 +248,7 @@ mod tests {
NULLIFIER_SUBTREE_HEIGHT, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_TREE_HEIGHT,
NULLIFIERS_PREFIX, PRIVATE_KERNEL_EMPTY_INDEX, PRIVATE_LOG_SIZE_IN_FIELDS,
PRIVATE_LOGS_PREFIX, PUBLIC_DATA_TREE_HEIGHT, REVERT_CODE_PREFIX, TUBE_VK_INDEX,
TX_FEE_PREFIX, TX_START_PREFIX, UNENCRYPTED_LOGS_PREFIX,
TX_FEE_PREFIX, TX_START_PREFIX,
},
data::{public_data_hint::PublicDataHint, PublicDataTreeLeaf, PublicDataTreeLeafPreimage},
hash::silo_l2_to_l1_message,
Expand Down Expand Up @@ -822,26 +823,29 @@ mod tests {
unconstrained fn non_empty_tx_effects_sponge() {
let mut builder = PrivateBaseRollupInputsBuilder::new();
builder.tube_data.append_note_hashes(50);
let outputs = builder.execute();
let mut tx_effects = [0; 53];
// TODO(#8954): This test uses 50 notes and 3 extra absorbed fields
let inputs = builder.build_inputs();
let outputs = inputs.execute();
let mut tx_effects = [0; 54];
// TODO(#8954): This test uses 50 notes and 4 extra absorbed fields
// This may change when logs are deconstructed
// Initial field = TX_START_PREFIX | 0 | txlen[0] txlen[1] | 0 | REVERT_CODE_PREFIX | 0 | revert_code
// The first 3 are: i=0 init field, i=1: tx fee, i=2: note prefix
// The first 4 are: i=0 init field, i=1: tx hash, i=2: tx fee, i=3: note prefix
tx_effects[0] = field_from_bytes(
array_concat(
TX_START_PREFIX.to_be_bytes::<8>(),
[0, 0, tx_effects.len() as u8, 0, REVERT_CODE_PREFIX, 0, 0],
),
true,
);
tx_effects[1] = field_from_bytes(
// TX hash
tx_effects[1] = inputs.tube_data.public_inputs.hash();
tx_effects[2] = field_from_bytes(
array_concat([TX_FEE_PREFIX, 0], (0).to_be_bytes::<29>()),
true,
);
tx_effects[2] = encode_blob_prefix(NOTES_PREFIX, 50);
tx_effects[3] = encode_blob_prefix(NOTES_PREFIX, 50);
for i in 0..50 {
tx_effects[i + 3] = builder.tube_data.note_hashes.storage()[i].value();
tx_effects[i + 4] = builder.tube_data.note_hashes.storage()[i].value();
}
let mut expected_sponge = outputs.start_sponge_blob;

Expand All @@ -855,21 +859,8 @@ mod tests {
let NUM_NULLIFIERS = 3;
let NUM_MSGS = 5;
let NUM_PRIV_EVENT_LOGS = 4;
let NUM_UNENC_LOGS = 6;
let NUM_CC_LOGS = 1;
let TOTAL_BLOB_FIELDS = 2 // revert code and tx fee
+ NUM_NOTES
+ 1 // notes and prefix
+ NUM_NULLIFIERS
+ 1 // nullifiers and prefix
+ NUM_MSGS
+ 1 // L2 to L1 msgs and prefix
+ NUM_UNENC_LOGS
+ 1 // unenc. logs and prefix
+ NUM_CC_LOGS
+ 1 // contract class logs and prefix
+ (NUM_NOTES + NUM_PRIV_EVENT_LOGS) * PRIVATE_LOG_SIZE_IN_FIELDS
+ 1; // private logs and prefix

let mut builder = PrivateBaseRollupInputsBuilder::new();
builder.tube_data.set_gas_used(100, 200);
builder.constants.global_variables.gas_fees.fee_per_da_gas = 1;
Expand All @@ -893,17 +884,19 @@ mod tests {
builder.tube_data.append_private_logs(NUM_PRIV_EVENT_LOGS);
// Below will only work with NUM_CC_LOGS=1
builder.tube_data.add_contract_class_log_hash(1, 2);
let outputs = builder.execute();
let inputs = builder.build_inputs();
let outputs = inputs.execute();

let mut reconstructed_tx_effects = [0; TX_EFFECTS_BLOB_HASH_INPUT_FIELDS];

// tx hash
reconstructed_tx_effects[1] = inputs.tube_data.public_inputs.hash();
// tx fee
reconstructed_tx_effects[1] = field_from_bytes(
reconstructed_tx_effects[2] = field_from_bytes(
array_concat([TX_FEE_PREFIX, 0], tx_fee.to_be_bytes::<29>()),
true,
);
// notes
let mut offset = 2;
let mut offset = 3;
let notes_prefix = encode_blob_prefix(NOTES_PREFIX, NUM_NOTES);
reconstructed_tx_effects[offset] = notes_prefix;
offset += 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ impl PublicBaseRollupInputs {
.fold(0, |len, l: ScopedLogHash| len + l.log_hash.length);

TxEffect {
tx_hash: self.tube_data.public_inputs.hash(),
revert_code,
transaction_fee: from_public.transaction_fee,
note_hashes: from_public.accumulated_data.note_hashes,
Expand Down Expand Up @@ -917,26 +918,29 @@ mod tests {
unconstrained fn non_empty_tx_effects_sponge() {
let mut builder = PublicBaseRollupInputsBuilder::new();
builder.avm_data.append_note_hashes(50);
let outputs = builder.execute();
let mut tx_effects = [0; 53];
// TODO(#8954): This test uses 50 notes and 3 extra absorbed fields
let inputs = builder.build_inputs();
let outputs = inputs.execute();
let mut tx_effects = [0; 54];
// TODO(#8954): This test uses 50 notes and 4 extra absorbed fields
// This may change when logs are deconstructed
// Initial field = TX_START_PREFIX | 0 | txlen[0] txlen[1] | 0 | REVERT_CODE_PREFIX | 0 | revert_code
// The first 3 are: i=0 init field, i=1: tx fee, i=2: note prefix
// The first 4 are: i=0 init field, i=1: tx hash, i=2: tx fee, i=3: note prefix
tx_effects[0] = field_from_bytes(
array_concat(
TX_START_PREFIX.to_be_bytes::<8>(),
[0, 0, tx_effects.len() as u8, 0, REVERT_CODE_PREFIX, 0, 0],
),
true,
);
tx_effects[1] = field_from_bytes(
// TX hash
tx_effects[1] = inputs.tube_data.public_inputs.hash();
tx_effects[2] = field_from_bytes(
array_concat([TX_FEE_PREFIX, 0], (0).to_be_bytes::<29>()),
true,
);
tx_effects[2] = encode_blob_prefix(NOTES_PREFIX, 50);
tx_effects[3] = encode_blob_prefix(NOTES_PREFIX, 50);
for i in 0..50 {
tx_effects[i + 3] = builder.avm_data.note_hashes.storage()[i].value();
tx_effects[i + 4] = builder.avm_data.note_hashes.storage()[i].value();
}
let mut expected_sponge = outputs.start_sponge_blob;

Expand All @@ -954,7 +958,7 @@ mod tests {
let NUM_CC_LOGS = 1;
let PUB_DATA_SLOT = 25;
let PUB_DATA_VALUE = 60;
let TOTAL_BLOB_FIELDS = 2 // revert code and tx fee
let TOTAL_BLOB_FIELDS = 3 // revert code, tx hash and tx fee
+ NUM_NOTES
+ 1 // notes and prefix
+ NUM_NULLIFIERS
Expand Down Expand Up @@ -994,7 +998,8 @@ mod tests {
builder.avm_data.append_unencrypted_log_hashes(NUM_UNENC_LOGS);
// Below will only work with NUM_CC_LOGS=1
builder.tube_data.add_contract_class_log_hash(1, 2);
let outputs = builder.execute();
let inputs = builder.build_inputs();
let outputs = inputs.execute();

let mut reconstructed_tx_effects = [0; TX_EFFECTS_BLOB_HASH_INPUT_FIELDS];
// Initial field = TX_START_PREFIX | 0 | txlen[0] txlen[1] | 0 | REVERT_CODE_PREFIX | 0 | revert_code
Expand All @@ -1015,13 +1020,15 @@ mod tests {
),
true,
);
// tx hash
reconstructed_tx_effects[1] = inputs.tube_data.public_inputs.hash();
// tx fee
reconstructed_tx_effects[1] = field_from_bytes(
reconstructed_tx_effects[2] = field_from_bytes(
array_concat([TX_FEE_PREFIX, 0], tx_fee.to_be_bytes::<29>()),
true,
);
// notes
let mut offset = 2;
let mut offset = 3;
let notes_prefix = encode_blob_prefix(NOTES_PREFIX, NUM_NOTES);
reconstructed_tx_effects[offset] = notes_prefix;
offset += 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ pub fn encode_blob_prefix(input_type: u8, array_len: u32) -> Field {

// Tx effects consist of
// 1 field for revert code
// 1 field for tx hash
// 1 field for transaction fee
// MAX_NOTE_HASHES_PER_TX fields for note hashes
// MAX_NULLIFIERS_PER_TX fields for nullifiers
Expand All @@ -256,6 +257,7 @@ pub fn encode_blob_prefix(input_type: u8, array_len: u32) -> Field {
// MAX_CONTRACT_CLASS_LOGS_PER_TX fields for contract class logs
// 7 fields for prefixes for each of the above categories
pub(crate) global TX_EFFECTS_BLOB_HASH_INPUT_FIELDS: u32 = 1
+ 1
+ 1
+ MAX_NOTE_HASHES_PER_TX
+ MAX_NULLIFIERS_PER_TX
Expand All @@ -277,8 +279,8 @@ pub(crate) fn append_tx_effects_for_blob(
let mut out_sponge = start_sponge_blob;

// If we have an empty tx (usually a padding tx), we don't want to absorb anything
// An empty tx will only have 2 effects - revert code and fee - hence offset = 2
if offset != 2 {
// An empty tx will only have 3 effects - revert code, tx hash and fee - hence offset = 3
if offset != 3 {
out_sponge.absorb(tx_effects_hash_input, offset);
}

Expand Down Expand Up @@ -313,6 +315,9 @@ fn get_tx_effects_hash_input(
// We only know the value once the appending is complete, hence we overwrite input[0] below
offset += 1;

assert_eq(tx_effects_hash_input[offset], tx_effect.tx_hash);
offset += 1;

// TX FEE
// Using 29 bytes to encompass all reasonable fee lengths
assert_eq(
Expand Down Expand Up @@ -505,6 +510,9 @@ unconstrained fn get_tx_effects_hash_input_helper(
tx_effects_hash_input[offset] = 0;
offset += 1;

tx_effects_hash_input[offset] = tx_effect.tx_hash;
offset += 1;

// TX FEE
// Using 29 bytes to encompass all reasonable fee lengths
tx_effects_hash_input[offset] = field_from_bytes(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ use crate::{
validation_requests::RollupValidationRequests,
},
address::AztecAddress,
constants::PRIVATE_TO_PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH,
traits::{Deserialize, Empty, Serialize},
constants::{
GENERATOR_INDEX__PUBLIC_TX_HASH, PRIVATE_TO_PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH,
},
hash::poseidon2_hash_with_separator,
traits::{Deserialize, Empty, Hash, Serialize},
utils::reader::Reader,
};

Expand Down Expand Up @@ -65,6 +68,12 @@ impl Serialize<PRIVATE_TO_PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH> for Privat
}
}

impl Hash for PrivateToPublicKernelCircuitPublicInputs {
fn hash(self) -> Field {
poseidon2_hash_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_TX_HASH)
}
}

impl Deserialize<PRIVATE_TO_PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH> for PrivateToPublicKernelCircuitPublicInputs {
fn deserialize(
fields: [Field; PRIVATE_TO_PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ use crate::{
tx_constant_data::TxConstantData, validation_requests::RollupValidationRequests,
},
address::AztecAddress,
constants::PRIVATE_TO_ROLLUP_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH,
traits::{Deserialize, Empty, Serialize},
constants::{
GENERATOR_INDEX__PRIVATE_TX_HASH, PRIVATE_TO_ROLLUP_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH,
},
hash::poseidon2_hash_with_separator,
traits::{Deserialize, Empty, Hash, Serialize},
utils::reader::Reader,
};
use std::meta::derive;
Expand Down Expand Up @@ -48,6 +51,12 @@ impl Serialize<PRIVATE_TO_ROLLUP_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH> for Privat
}
}

impl Hash for PrivateToRollupKernelCircuitPublicInputs {
fn hash(self) -> Field {
poseidon2_hash_with_separator(self.serialize(), GENERATOR_INDEX__PRIVATE_TX_HASH)
}
}

impl Deserialize<PRIVATE_TO_ROLLUP_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH> for PrivateToRollupKernelCircuitPublicInputs {
fn deserialize(
fields: [Field; PRIVATE_TO_ROLLUP_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH],
Expand Down
21 changes: 4 additions & 17 deletions noir-projects/noir-protocol-circuits/crates/types/src/constants.nr
Original file line number Diff line number Diff line change
Expand Up @@ -490,20 +490,7 @@ pub global AVM_PROOF_LENGTH_IN_FIELDS: u32 = 4155;
pub global AVM_PUBLIC_COLUMN_MAX_SIZE: u32 = 1024;
pub global AVM_PUBLIC_INPUTS_FLATTENED_SIZE: u32 =
2 * AVM_PUBLIC_COLUMN_MAX_SIZE + PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH;
/**
* Enumerate the hash_indices which are used for pedersen hashing.
* We start from 1 to avoid the default generators. The generator indices are listed
* based on the number of elements each index hashes. The following conditions must be met:
*
* +-----------+-------------------------------+----------------------+
* | Hash size | Number of elements hashed (n) | Condition to use |
* |-----------+-------------------------------+----------------------|
* | LOW | n <= 8 | 0 < hash_index <= 32 |
* | MID | 8 < n <= 16 | 32 < hash_index <= 40 |
* | HIGH | 16 < n <= 48 | 40 < hash_index <= 48 |
* +-----------+-------------------------------+----------------------+
*/
// Indices with size <= 8

pub global GENERATOR_INDEX__NOTE_HASH: u32 = 1;
pub global GENERATOR_INDEX__NOTE_HASH_NONCE: u32 = 2;
pub global GENERATOR_INDEX__UNIQUE_NOTE_HASH: u32 = 3;
Expand Down Expand Up @@ -536,14 +523,11 @@ pub global GENERATOR_INDEX__SIDE_EFFECT: u32 = 29;
pub global GENERATOR_INDEX__FEE_PAYLOAD: u32 = 30;
pub global GENERATOR_INDEX__COMBINED_PAYLOAD: u32 = 31;
pub global GENERATOR_INDEX__TX_NULLIFIER: u32 = 32;
// Indices with size <= 16
pub global GENERATOR_INDEX__TX_REQUEST: u32 = 33;
pub global GENERATOR_INDEX__SIGNATURE_PAYLOAD: u32 = 34;
// Indices with size <= 44
pub global GENERATOR_INDEX__VK: u32 = 41;
pub global GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS: u32 = 42;
pub global GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS: u32 = 43;
// TODO: Function args generator index is being used to hash 64 items
pub global GENERATOR_INDEX__FUNCTION_ARGS: u32 = 44;
pub global GENERATOR_INDEX__AUTHWIT_INNER: u32 = 45;
pub global GENERATOR_INDEX__AUTHWIT_OUTER: u32 = 46;
Expand All @@ -558,6 +542,9 @@ pub global GENERATOR_INDEX__NOTE_NULLIFIER: u32 = 53;
pub global GENERATOR_INDEX__NOTE_HIDING_POINT: u32 = 54;
pub global GENERATOR_INDEX__SYMMETRIC_KEY: u8 = 55;

pub global GENERATOR_INDEX__PUBLIC_TX_HASH: u32 = 56;
pub global GENERATOR_INDEX__PRIVATE_TX_HASH: u32 = 57;

// AVM memory tags
pub global MEM_TAG_FF: Field = 0;
pub global MEM_TAG_U1: Field = 1;
Expand Down
Loading