diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_composer.nr index 50de33ebc3c3..f87036ee9d8a 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_composer.nr @@ -1,12 +1,16 @@ -use crate::components::private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer; +mod meter_gas_used; + +use crate::components::{ + private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer, + tail_output_composer::meter_gas_used::meter_gas_used +}; use dep::types::{ abis::{ - accumulated_data::combined_accumulated_data::CombinedAccumulatedData, gas::Gas, + accumulated_data::combined_accumulated_data::CombinedAccumulatedData, kernel_circuit_public_inputs::{KernelCircuitPublicInputs, PrivateKernelCircuitPublicInputs}, log_hash::{ScopedEncryptedLogHash, NoteLogHash, ScopedLogHash}, note_hash::ScopedNoteHash, nullifier::ScopedNullifier }, - constants::{DA_BYTES_PER_FIELD, DA_GAS_PER_BYTE, L2_GAS_PER_NOTE_HASH, L2_GAS_PER_NULLIFIER, L2_GAS_PER_LOG_BYTE}, hash::{compute_tx_logs_hash, compute_tx_note_logs_hash}, messaging::l2_to_l1_message::ScopedL2ToL1Message }; @@ -45,37 +49,7 @@ impl TailOutputComposer { data.note_encrypted_log_preimages_length = source.note_encrypted_logs_hashes.storage.fold(0, |len, l: NoteLogHash| len + l.length); data.encrypted_log_preimages_length = source.encrypted_logs_hashes.storage.fold(0, |len, l: ScopedEncryptedLogHash| len + l.log_hash.length); data.unencrypted_log_preimages_length = source.unencrypted_logs_hashes.storage.fold(0, |len, l: ScopedLogHash| len + l.log_hash.length); - data.gas_used = self.meter_gas_used(data); + data.gas_used = meter_gas_used(data, self.output_composer.public_inputs.constants.tx_context.gas_settings); data } - - fn meter_gas_used(self, data: CombinedAccumulatedData) -> Gas { - let mut metered_da_bytes = 0; - let mut metered_l2_gas = 0; - - let data_builder = self.output_composer.public_inputs.end; - // IMPORTANT: Must use data_builder.__.len(), which is the the number of items pushed to the BoundedVec. - // Do not use data.__.len(), which is the array's max length. - metered_da_bytes += data_builder.note_hashes.len() * DA_BYTES_PER_FIELD; - metered_l2_gas += data_builder.note_hashes.len() * L2_GAS_PER_NOTE_HASH; - - metered_da_bytes += data_builder.nullifiers.len() * DA_BYTES_PER_FIELD; - metered_l2_gas += data_builder.nullifiers.len() * L2_GAS_PER_NULLIFIER; - - metered_da_bytes += data_builder.l2_to_l1_msgs.len() * DA_BYTES_PER_FIELD; - - metered_da_bytes += data.note_encrypted_log_preimages_length as u32; - metered_l2_gas += data.note_encrypted_log_preimages_length as u32 * L2_GAS_PER_LOG_BYTE; - - metered_da_bytes += data.encrypted_log_preimages_length as u32; - metered_l2_gas += data.encrypted_log_preimages_length as u32 * L2_GAS_PER_LOG_BYTE; - - metered_da_bytes += data.unencrypted_log_preimages_length as u32; - metered_l2_gas += data.unencrypted_log_preimages_length as u32 * L2_GAS_PER_LOG_BYTE; - - let teardown_gas = self.output_composer.public_inputs.constants.tx_context.gas_settings.teardown_gas_limits; - Gas::new(metered_da_bytes * DA_GAS_PER_BYTE, metered_l2_gas) - + Gas::tx_overhead() - + teardown_gas - } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_composer/meter_gas_used.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_composer/meter_gas_used.nr new file mode 100644 index 000000000000..e0585bd0ffe5 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_composer/meter_gas_used.nr @@ -0,0 +1,36 @@ +use dep::types::{ + abis::{ + accumulated_data::combined_accumulated_data::CombinedAccumulatedData, gas::Gas, + gas_settings::GasSettings +}, + constants::{DA_BYTES_PER_FIELD, DA_GAS_PER_BYTE, L2_GAS_PER_NOTE_HASH, L2_GAS_PER_NULLIFIER, L2_GAS_PER_LOG_BYTE}, + utils::arrays::array_length +}; + +fn meter_gas_used(data: CombinedAccumulatedData, gas_settings: GasSettings) -> Gas { + let mut metered_da_bytes = 0; + let mut metered_l2_gas = 0; + + let num_note_hashes = array_length(data.note_hashes); + metered_da_bytes += num_note_hashes * DA_BYTES_PER_FIELD; + metered_l2_gas += num_note_hashes * L2_GAS_PER_NOTE_HASH; + + let num_nullifiers = array_length(data.nullifiers); + metered_da_bytes += num_nullifiers * DA_BYTES_PER_FIELD; + metered_l2_gas += num_nullifiers * L2_GAS_PER_NULLIFIER; + + let num_l2_to_l1_msgs = array_length(data.l2_to_l1_msgs); + metered_da_bytes += num_l2_to_l1_msgs * DA_BYTES_PER_FIELD; + + metered_da_bytes += data.note_encrypted_log_preimages_length as u32; + metered_l2_gas += data.note_encrypted_log_preimages_length as u32 * L2_GAS_PER_LOG_BYTE; + + metered_da_bytes += data.encrypted_log_preimages_length as u32; + metered_l2_gas += data.encrypted_log_preimages_length as u32 * L2_GAS_PER_LOG_BYTE; + + metered_da_bytes += data.unencrypted_log_preimages_length as u32; + metered_l2_gas += data.unencrypted_log_preimages_length as u32 * L2_GAS_PER_LOG_BYTE; + + let teardown_gas = gas_settings.teardown_gas_limits; + Gas::new(metered_da_bytes * DA_GAS_PER_BYTE, metered_l2_gas) + Gas::tx_overhead() + teardown_gas +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_validator.nr index 135c7312a72d..7ef9a42e0762 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_validator.nr @@ -1,9 +1,12 @@ mod kernel_circuit_output_hints; mod validate_value_transformation; -use crate::components::tail_output_validator::{ +use crate::components::{ + tail_output_composer::meter_gas_used::meter_gas_used, + tail_output_validator::{ kernel_circuit_output_hints::{generate_kernel_circuit_output_hints, Hints}, validate_value_transformation::{validate_transformed_values, validate_value_transformation} +} }; use dep::types::{ abis::{ @@ -37,7 +40,7 @@ impl TailOutputValidator { self.validate_propagated_values(); self.validate_propagated_sorted_siloed_values(hints); self.validate_accumulated_values(hints); - self.validate_gas_limits(); + self.validate_gas_used(); } fn validate_empty_values(self) { @@ -149,7 +152,13 @@ impl TailOutputValidator { ); } - fn validate_gas_limits(self) { + fn validate_gas_used(self) { + let gas_used = meter_gas_used( + self.output.end, + self.output.constants.tx_context.gas_settings + ); + assert(self.output.end.gas_used == gas_used, "incorrect metered gas used"); + let limits = self.previous_kernel.constants.tx_context.gas_settings.gas_limits; assert(self.output.end.gas_used.within(limits), "The gas used exceeds the gas limits"); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer.nr index a51363f34b60..52fdf81766b2 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer.nr @@ -34,8 +34,8 @@ impl TailToPublicOutputComposer { end_non_revertible.gas_used = meter_gas_used_non_revertible(end_non_revertible); let teardown_gas = source.constants.tx_context.gas_settings.teardown_gas_limits; end.gas_used = meter_gas_used_revertible(end, teardown_gas); - output.end_non_revertible = end_non_revertible.finish(); - output.end = end.finish(); + output.end_non_revertible = end_non_revertible; + output.end = end; output } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer/meter_gas_used.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer/meter_gas_used.nr index 6c85ef2e5c92..3614a49df5df 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer/meter_gas_used.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer/meter_gas_used.nr @@ -1,47 +1,50 @@ use dep::types::{ abis::{ - accumulated_data::{public_accumulated_data_builder::PublicAccumulatedDataBuilder}, gas::Gas, + accumulated_data::{public_accumulated_data_builder::PublicAccumulatedData}, gas::Gas, log_hash::{LogHash, ScopedLogHash} }, constants::{ DA_BYTES_PER_FIELD, DA_GAS_PER_BYTE, FIXED_AVM_STARTUP_L2_GAS, L2_GAS_PER_NOTE_HASH, L2_GAS_PER_NULLIFIER, L2_GAS_PER_LOG_BYTE -} +}, + utils::arrays::array_length }; -fn meter_gas_used(data: PublicAccumulatedDataBuilder) -> Gas { +fn meter_gas_used(data: PublicAccumulatedData) -> Gas { let mut metered_da_bytes = 0; let mut metered_l2_gas = 0; - metered_da_bytes += data.note_hashes.len() * DA_BYTES_PER_FIELD; - metered_l2_gas += data.note_hashes.len() * L2_GAS_PER_NOTE_HASH; + let num_note_hashes = array_length(data.note_hashes); + metered_da_bytes += num_note_hashes * DA_BYTES_PER_FIELD; + metered_l2_gas += num_note_hashes * L2_GAS_PER_NOTE_HASH; - metered_da_bytes += data.nullifiers.len() * DA_BYTES_PER_FIELD; - metered_l2_gas += data.nullifiers.len() * L2_GAS_PER_NULLIFIER; + let num_nullifiers = array_length(data.nullifiers); + metered_da_bytes += num_nullifiers * DA_BYTES_PER_FIELD; + metered_l2_gas += num_nullifiers * L2_GAS_PER_NULLIFIER; - metered_da_bytes += data.l2_to_l1_msgs.len() * DA_BYTES_PER_FIELD; + metered_da_bytes += array_length(data.l2_to_l1_msgs) * DA_BYTES_PER_FIELD; - let note_encrypted_log_preimages_length = data.note_encrypted_logs_hashes.storage.fold(0, |len, l: LogHash| len + l.length); + let note_encrypted_log_preimages_length = data.note_encrypted_logs_hashes.fold(0, |len, l: LogHash| len + l.length); metered_da_bytes += note_encrypted_log_preimages_length as u32; metered_l2_gas += note_encrypted_log_preimages_length as u32 * L2_GAS_PER_LOG_BYTE; - let encrypted_log_preimages_length = data.encrypted_logs_hashes.storage.fold(0, |len, l: LogHash| len + l.length); + let encrypted_log_preimages_length = data.encrypted_logs_hashes.fold(0, |len, l: LogHash| len + l.length); metered_da_bytes += encrypted_log_preimages_length as u32; metered_l2_gas += encrypted_log_preimages_length as u32 * L2_GAS_PER_LOG_BYTE; - let unencrypted_log_preimages_length = data.unencrypted_logs_hashes.storage.fold(0, |len, l: ScopedLogHash| len + l.log_hash.length); + let unencrypted_log_preimages_length = data.unencrypted_logs_hashes.fold(0, |len, l: ScopedLogHash| len + l.log_hash.length); metered_da_bytes += unencrypted_log_preimages_length as u32; metered_l2_gas += unencrypted_log_preimages_length as u32 * L2_GAS_PER_LOG_BYTE; - metered_l2_gas += data.public_call_stack.len() * FIXED_AVM_STARTUP_L2_GAS; + metered_l2_gas += array_length(data.public_call_stack) * FIXED_AVM_STARTUP_L2_GAS; Gas::new(metered_da_bytes * DA_GAS_PER_BYTE, metered_l2_gas) } -pub fn meter_gas_used_non_revertible(data: PublicAccumulatedDataBuilder) -> Gas { +pub fn meter_gas_used_non_revertible(data: PublicAccumulatedData) -> Gas { meter_gas_used(data) + Gas::tx_overhead() } -pub fn meter_gas_used_revertible(data: PublicAccumulatedDataBuilder, teardown_gas: Gas) -> Gas { +pub fn meter_gas_used_revertible(data: PublicAccumulatedData, teardown_gas: Gas) -> Gas { meter_gas_used(data) + Gas::new(teardown_gas.da_gas, teardown_gas.l2_gas) } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer/split_to_public.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer/split_to_public.nr index 95a11b1b631d..e6d19a486e51 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer/split_to_public.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer/split_to_public.nr @@ -1,6 +1,7 @@ use dep::types::abis::{ accumulated_data::{ private_accumulated_data_builder::PrivateAccumulatedDataBuilder, + public_accumulated_data::PublicAccumulatedData, public_accumulated_data_builder::PublicAccumulatedDataBuilder } }; @@ -8,7 +9,7 @@ use dep::types::abis::{ pub fn split_to_public( data: PrivateAccumulatedDataBuilder, min_revertible_side_effect_counter: u32 -) -> (PublicAccumulatedDataBuilder, PublicAccumulatedDataBuilder) { +) -> (PublicAccumulatedData, PublicAccumulatedData) { assert(min_revertible_side_effect_counter != 0, "min_revertible_side_effect_counter must not be 0"); let mut non_revertible_builder = PublicAccumulatedDataBuilder::empty(); @@ -106,5 +107,5 @@ pub fn split_to_public( } } - (non_revertible_builder, revertible_builder) + (non_revertible_builder.finish(), revertible_builder.finish()) } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_validator.nr index dcbf1722b4f6..ece36c83ad04 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_validator.nr @@ -2,6 +2,7 @@ mod tail_to_public_output_hints; use crate::components::{ tail_output_validator::validate_value_transformation::{validate_transformed_values, validate_value_transformation}, + tail_to_public_output_composer::meter_gas_used::{meter_gas_used_non_revertible, meter_gas_used_revertible}, tail_to_public_output_validator::tail_to_public_output_hints::{generate_tail_to_public_output_hints, TailToPublicOutputHints} }; use dep::types::{ @@ -33,7 +34,7 @@ impl TailToPublicOutputValidator { self.validate_empty_values(); self.validate_propagated_values(); self.validate_propagated_sorted_siloed_values(hints); - self.validate_gas_limits(); + self.validate_gas_used(); } fn validate_empty_values(self) { @@ -180,7 +181,18 @@ impl TailToPublicOutputValidator { ) } - fn validate_gas_limits(self) { + fn validate_gas_used(self) { + let gas_used = meter_gas_used_non_revertible(self.output.end_non_revertible); + assert( + self.output.end_non_revertible.gas_used == gas_used, "incorrect metered non-revertible gas used" + ); + + let gas_used = meter_gas_used_revertible( + self.output.end, + self.output.constants.tx_context.gas_settings.teardown_gas_limits + ); + assert(self.output.end.gas_used == gas_used, "incorrect metered revertible gas used"); + let limits = self.previous_kernel.constants.tx_context.gas_settings.gas_limits; let total_gas_used = self.output.end_non_revertible.gas_used + self.output.end.gas_used; assert(total_gas_used.within(limits), "The gas used exceeds the gas limits"); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder/meter_gas_used.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder/meter_gas_used.nr new file mode 100644 index 000000000000..4450cb2cd2fa --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder/meter_gas_used.nr @@ -0,0 +1,73 @@ +use crate::components::tail_output_composer::meter_gas_used::meter_gas_used; +use dep::types::{ + abis::gas::Gas, + constants::{DA_BYTES_PER_FIELD, DA_GAS_PER_BYTE, L2_GAS_PER_NOTE_HASH, L2_GAS_PER_NULLIFIER, L2_GAS_PER_LOG_BYTE}, + tests::fixture_builder::FixtureBuilder +}; + +fn new_builder() -> FixtureBuilder { + let mut builder = FixtureBuilder::new(); + builder.tx_context.gas_settings.teardown_gas_limits = Gas::new(12, 345); + builder +} + +#[test] +fn meter_gas_used_empty_succeeds() { + let builder = new_builder(); + let data = builder.to_combined_accumulated_data(); + let gas_settings = builder.tx_context.gas_settings; + let gas = meter_gas_used(data, gas_settings); + assert_eq(gas, Gas::tx_overhead() + gas_settings.teardown_gas_limits); +} + +#[test] +fn meter_gas_used_everything_succeeds() { + let mut builder = new_builder(); + let mut metered_da_bytes = 0; + let mut computed_l2_gas = 0; + + builder.append_note_hashes(4); + metered_da_bytes += 4 * DA_BYTES_PER_FIELD; + computed_l2_gas += 4 * L2_GAS_PER_NOTE_HASH; + + builder.append_nullifiers(3); + metered_da_bytes += 3 * DA_BYTES_PER_FIELD; + computed_l2_gas += 3 * L2_GAS_PER_NULLIFIER; + + builder.append_l2_to_l1_msgs(1); + metered_da_bytes += 1 * DA_BYTES_PER_FIELD; + + builder.add_note_encrypted_log_hash(1001, 12, 0); + metered_da_bytes += 12; + computed_l2_gas += 12 * L2_GAS_PER_LOG_BYTE; + + builder.add_note_encrypted_log_hash(1002, 8, 0); + metered_da_bytes += 8; + computed_l2_gas += 8 * L2_GAS_PER_LOG_BYTE; + + builder.add_note_encrypted_log_hash(1003, 20, 0); + metered_da_bytes += 20; + computed_l2_gas += 20 * L2_GAS_PER_LOG_BYTE; + + builder.add_encrypted_log_hash(2001, 2); + metered_da_bytes += 2; + computed_l2_gas += 2 * L2_GAS_PER_LOG_BYTE; + + builder.add_encrypted_log_hash(2002, 6); + metered_da_bytes += 6; + computed_l2_gas += 6 * L2_GAS_PER_LOG_BYTE; + + builder.add_unencrypted_log_hash(3001, 51); + metered_da_bytes += 51; + computed_l2_gas += 51 * L2_GAS_PER_LOG_BYTE; + + let data = builder.to_combined_accumulated_data(); + let gas_settings = builder.tx_context.gas_settings; + let gas = meter_gas_used(data, gas_settings); + + assert_eq( + gas, Gas::new(metered_da_bytes * DA_GAS_PER_BYTE, computed_l2_gas) + + Gas::tx_overhead() + + gas_settings.teardown_gas_limits + ); +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder/mod.nr similarity index 98% rename from noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder.nr rename to noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder/mod.nr index b73651287517..0bdc19122bd9 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder/mod.nr @@ -1,3 +1,5 @@ +mod meter_gas_used; + use crate::components::tail_output_composer::TailOutputComposer; use dep::types::{abis::kernel_circuit_public_inputs::KernelCircuitPublicInputs, tests::fixture_builder::FixtureBuilder}; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/mod.nr index 6baadc391fbc..524e283b332d 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/mod.nr @@ -1,10 +1,14 @@ mod validate_accumulated_values; mod validate_empty_values; +mod validate_gas_used; mod validate_propagated_sorted_siloed_values; mod validate_propagated_values; -use crate::components::tail_output_validator::TailOutputValidator; -use dep::types::tests::fixture_builder::FixtureBuilder; +use crate::components::{tail_output_composer::meter_gas_used::meter_gas_used, tail_output_validator::TailOutputValidator}; +use dep::types::{ + abis::{gas_settings::GasSettings, kernel_circuit_public_inputs::KernelCircuitPublicInputs}, + tests::fixture_builder::FixtureBuilder +}; struct TailOutputValidatorBuilder { output: FixtureBuilder, @@ -15,13 +19,26 @@ impl TailOutputValidatorBuilder { pub fn new() -> Self { let mut output = FixtureBuilder::new(); let mut previous_kernel = FixtureBuilder::new(); + output.tx_context.gas_settings = GasSettings::default(); + previous_kernel.tx_context.gas_settings = GasSettings::default(); output.set_first_nullifier(); previous_kernel.set_first_nullifier(); TailOutputValidatorBuilder { output, previous_kernel } } + pub fn export_output(self) -> KernelCircuitPublicInputs { + let mut output = self.output.to_kernel_circuit_public_inputs(); + output.end.gas_used = meter_gas_used(output.end, output.constants.tx_context.gas_settings); + output + } + pub fn validate(self) { - let output = self.output.to_kernel_circuit_public_inputs(); + let output = self.export_output(); + let previous_kernel = self.previous_kernel.to_private_kernel_circuit_public_inputs(); + TailOutputValidator::new(output, previous_kernel).validate(); + } + + pub fn validate_with_output(self, output: KernelCircuitPublicInputs) { let previous_kernel = self.previous_kernel.to_private_kernel_circuit_public_inputs(); TailOutputValidator::new(output, previous_kernel).validate(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/validate_gas_used.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/validate_gas_used.nr new file mode 100644 index 000000000000..de9c3b78ff9f --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/validate_gas_used.nr @@ -0,0 +1,73 @@ +use crate::tests::tail_output_validator_builder::TailOutputValidatorBuilder; + +impl TailOutputValidatorBuilder { + pub fn new_with_data() -> Self { + let mut builder = TailOutputValidatorBuilder::new(); + + builder.previous_kernel.append_note_hashes(3); + builder.output.append_siloed_note_hashes(3); + + builder.previous_kernel.append_note_encrypted_log_hashes(3); + builder.output.append_note_encrypted_log_hashes(3); + builder.output.hash_note_encrypted_log_hashes(); + + builder + } +} + +#[test] +fn validate_gas_used_succeeds() { + let builder = TailOutputValidatorBuilder::new_with_data(); + let output = builder.export_output(); + builder.validate_with_output(output); +} + +#[test(should_fail_with="incorrect metered gas used")] +fn validate_gas_used_wrong_da_gas_fails() { + let builder = TailOutputValidatorBuilder::new_with_data(); + let mut output = builder.export_output(); + + // Tweak the da gas in the output to be a wrong value. + output.end.gas_used.da_gas += 1; + + builder.validate_with_output(output); +} + +#[test(should_fail_with="incorrect metered gas used")] +fn validate_gas_used_wrong_l2_gas_fails() { + let builder = TailOutputValidatorBuilder::new_with_data(); + let mut output = builder.export_output(); + + // Tweak the l2 gas in the output to be a wrong value. + output.end.gas_used.l2_gas += 1; + + builder.validate_with_output(output); +} + +#[test(should_fail_with="The gas used exceeds the gas limits")] +fn validate_gas_used_exceed_da_limit_fails() { + let mut builder = TailOutputValidatorBuilder::new_with_data(); + let mut output = builder.export_output(); + + let gas_used = output.end.gas_used.da_gas; + // Tweak the da gas limit to be less than the gas used. + output.constants.tx_context.gas_settings.gas_limits.da_gas = gas_used - 1; + // Constants must match. + builder.previous_kernel.tx_context.gas_settings.gas_limits.da_gas = gas_used - 1; + + builder.validate_with_output(output); +} + +#[test(should_fail_with="The gas used exceeds the gas limits")] +fn validate_gas_used_exceed_l2_limit_fails() { + let mut builder = TailOutputValidatorBuilder::new_with_data(); + let mut output = builder.export_output(); + + let gas_used = output.end.gas_used.l2_gas; + // Tweak the l2 gas limit to be less than the gas used. + output.constants.tx_context.gas_settings.gas_limits.l2_gas = gas_used - 1; + // Constants must match. + builder.previous_kernel.tx_context.gas_settings.gas_limits.l2_gas = gas_used - 1; + + builder.validate_with_output(output); +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/meter_gas_used.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/meter_gas_used.nr index bab21a8b0906..8dec06d95c77 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/meter_gas_used.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/meter_gas_used.nr @@ -11,7 +11,7 @@ use dep::types::{ #[test] fn meter_gas_used_non_revertible_empty_succeeds() { let builder = FixtureBuilder::new(); - let data = builder.to_public_accumulated_data_builder(); + let data = builder.to_public_accumulated_data(); let gas = meter_gas_used_non_revertible(data); assert_eq(gas, Gas::tx_overhead()); } @@ -32,7 +32,7 @@ fn meter_gas_used_non_revertible_everything_succeeds() { builder.append_public_call_requests(2); builder.end_setup(); - let data = builder.to_public_accumulated_data_builder(); + let data = builder.to_public_accumulated_data(); let gas = meter_gas_used_non_revertible(data); let total_num_side_effects = 4 + 3 + 1; @@ -51,7 +51,7 @@ fn meter_gas_used_non_revertible_everything_succeeds() { #[test] fn meter_gas_used_revertible_empty_succeeds() { let builder = FixtureBuilder::new(); - let data = builder.to_public_accumulated_data_builder(); + let data = builder.to_public_accumulated_data(); let teardown_gas = Gas::new(42, 17); let gas = meter_gas_used_revertible(data, teardown_gas); assert_eq(gas, teardown_gas); @@ -73,7 +73,7 @@ fn meter_gas_used_revertible_everything_succeeds() { builder.append_public_call_requests(2); builder.end_setup(); - let data = builder.to_public_accumulated_data_builder(); + let data = builder.to_public_accumulated_data(); let teardown_gas = Gas::new(42, 17); let gas = meter_gas_used_revertible(data, teardown_gas); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/mod.nr similarity index 100% rename from noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder.nr rename to noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/mod.nr diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/split_to_public.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/split_to_public.nr index d87bdfb6b700..8998a01e387a 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/split_to_public.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/split_to_public.nr @@ -31,56 +31,47 @@ fn split_to_public_succeeds() { // note_hashes let expected = combined_data.note_hashes; + assert_array_eq(non_revertible.note_hashes, [expected[0], expected[1]]); assert_array_eq( - non_revertible.note_hashes.storage, - [expected[0], expected[1]] - ); - assert_array_eq( - revertible.note_hashes.storage, + revertible.note_hashes, [expected[2], expected[3], expected[4]] ); // nullifiers let expected = combined_data.nullifiers; - assert_array_eq(non_revertible.nullifiers.storage, [expected[0], expected[1]]); - assert_array_eq(revertible.nullifiers.storage, [expected[2]]); + assert_array_eq(non_revertible.nullifiers, [expected[0], expected[1]]); + assert_array_eq(revertible.nullifiers, [expected[2]]); // l2_to_l1_msgs let expected = combined_data.l2_to_l1_msgs; - assert_array_eq(non_revertible.l2_to_l1_msgs.storage, [expected[0]]); - assert_array_eq(revertible.l2_to_l1_msgs.storage, [expected[1]]); + assert_array_eq(non_revertible.l2_to_l1_msgs, [expected[0]]); + assert_array_eq(revertible.l2_to_l1_msgs, [expected[1]]); // note_encrypted_logs_hashes let expected = combined_data.note_encrypted_logs_hashes; assert_array_eq( - non_revertible.note_encrypted_logs_hashes.storage, + non_revertible.note_encrypted_logs_hashes, [expected[0], expected[1], expected[2]] ); - assert_array_eq(revertible.note_encrypted_logs_hashes.storage, [expected[3]]); + assert_array_eq(revertible.note_encrypted_logs_hashes, [expected[3]]); // encrypted_logs_hashes let expected = combined_data.encrypted_logs_hashes; assert_array_eq( - non_revertible.encrypted_logs_hashes.storage, + non_revertible.encrypted_logs_hashes, [expected[0], expected[1]] ); - assert_array_eq( - revertible.encrypted_logs_hashes.storage, - [expected[2], expected[3]] - ); + assert_array_eq(revertible.encrypted_logs_hashes, [expected[2], expected[3]]); // unencrypted_logs_hashes let expected = combined_data.unencrypted_logs_hashes; - assert_array_eq(non_revertible.unencrypted_logs_hashes.storage, [expected[0]]); - assert_array_eq(revertible.unencrypted_logs_hashes.storage, [expected[1]]); + assert_array_eq(non_revertible.unencrypted_logs_hashes, [expected[0]]); + assert_array_eq(revertible.unencrypted_logs_hashes, [expected[1]]); // public_call_stack let expected = combined_data.public_call_stack; - assert_array_eq(non_revertible.public_call_stack.storage, [expected[0]]); - assert_array_eq( - revertible.public_call_stack.storage, - [expected[1], expected[2]] - ); + assert_array_eq(non_revertible.public_call_stack, [expected[0]]); + assert_array_eq(revertible.public_call_stack, [expected[1], expected[2]]); } #[test(should_fail_with="min_revertible_side_effect_counter must not be 0")]