@aztec/stdlib 4.0.0-devnet.2-patch.3 → 4.0.0-devnet.3-patch.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/abi/buffer.d.ts +14 -4
- package/dest/abi/buffer.d.ts.map +1 -1
- package/dest/abi/buffer.js +25 -4
- package/dest/abi/decoder.d.ts +6 -45
- package/dest/abi/decoder.d.ts.map +1 -1
- package/dest/abi/decoder.js +17 -70
- package/dest/abi/encoder.d.ts +1 -1
- package/dest/abi/encoder.d.ts.map +1 -1
- package/dest/abi/encoder.js +37 -6
- package/dest/abi/event_metadata_definition.d.ts +3 -1
- package/dest/abi/event_metadata_definition.d.ts.map +1 -1
- package/dest/abi/event_metadata_definition.js +1 -1
- package/dest/abi/function_selector.js +1 -1
- package/dest/abi/function_signature_decoder.d.ts +43 -0
- package/dest/abi/function_signature_decoder.d.ts.map +1 -0
- package/dest/abi/function_signature_decoder.js +66 -0
- package/dest/abi/index.d.ts +2 -1
- package/dest/abi/index.d.ts.map +1 -1
- package/dest/abi/index.js +1 -0
- package/dest/abi/utils.d.ts +14 -1
- package/dest/abi/utils.d.ts.map +1 -1
- package/dest/abi/utils.js +15 -0
- package/dest/avm/avm.d.ts +300 -300
- package/dest/avm/avm_accumulated_data.js +2 -2
- package/dest/avm/avm_circuit_public_inputs.js +2 -2
- package/dest/avm/avm_proving_request.d.ts +166 -166
- package/dest/avm/revert_code.d.ts +16 -1
- package/dest/avm/revert_code.d.ts.map +1 -1
- package/dest/avm/revert_code.js +15 -5
- package/dest/block/l2_block.d.ts +9 -1
- package/dest/block/l2_block.d.ts.map +1 -1
- package/dest/block/l2_block.js +12 -2
- package/dest/block/l2_block_source.d.ts +16 -8
- package/dest/block/l2_block_source.d.ts.map +1 -1
- package/dest/block/l2_block_stream/l2_block_stream.d.ts +1 -1
- package/dest/block/l2_block_stream/l2_block_stream.d.ts.map +1 -1
- package/dest/block/l2_block_stream/l2_block_stream.js +10 -0
- package/dest/checkpoint/checkpoint.d.ts +2 -1
- package/dest/checkpoint/checkpoint.d.ts.map +1 -1
- package/dest/checkpoint/checkpoint.js +9 -4
- package/dest/checkpoint/index.d.ts +2 -1
- package/dest/checkpoint/index.d.ts.map +1 -1
- package/dest/checkpoint/index.js +1 -0
- package/dest/checkpoint/validate.d.ts +36 -0
- package/dest/checkpoint/validate.d.ts.map +1 -0
- package/dest/checkpoint/validate.js +120 -0
- package/dest/config/sequencer-config.d.ts +2 -2
- package/dest/config/sequencer-config.d.ts.map +1 -1
- package/dest/config/sequencer-config.js +11 -0
- package/dest/epoch-helpers/index.d.ts +9 -1
- package/dest/epoch-helpers/index.d.ts.map +1 -1
- package/dest/epoch-helpers/index.js +13 -2
- package/dest/gas/gas_fees.d.ts +1 -1
- package/dest/gas/gas_fees.d.ts.map +1 -1
- package/dest/gas/gas_fees.js +4 -1
- package/dest/hash/hash.d.ts +19 -1
- package/dest/hash/hash.d.ts.map +1 -1
- package/dest/hash/hash.js +29 -0
- package/dest/interfaces/allowed_element.d.ts +26 -20
- package/dest/interfaces/allowed_element.d.ts.map +1 -1
- package/dest/interfaces/allowed_element.js +8 -8
- package/dest/interfaces/archiver.d.ts +1 -1
- package/dest/interfaces/archiver.d.ts.map +1 -1
- package/dest/interfaces/archiver.js +3 -2
- package/dest/interfaces/aztec-node-admin.d.ts +67 -27
- package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
- package/dest/interfaces/aztec-node.d.ts +12 -6
- package/dest/interfaces/aztec-node.d.ts.map +1 -1
- package/dest/interfaces/aztec-node.js +5 -2
- package/dest/interfaces/block-builder.d.ts +38 -11
- package/dest/interfaces/block-builder.d.ts.map +1 -1
- package/dest/interfaces/block-builder.js +13 -6
- package/dest/interfaces/configs.d.ts +67 -32
- package/dest/interfaces/configs.d.ts.map +1 -1
- package/dest/interfaces/configs.js +7 -2
- package/dest/interfaces/merkle_tree_operations.d.ts +9 -19
- package/dest/interfaces/merkle_tree_operations.d.ts.map +1 -1
- package/dest/interfaces/p2p.d.ts +3 -8
- package/dest/interfaces/p2p.d.ts.map +1 -1
- package/dest/interfaces/prover-client.d.ts +6 -1
- package/dest/interfaces/prover-client.d.ts.map +1 -1
- package/dest/interfaces/prover-client.js +7 -1
- package/dest/interfaces/validator.d.ts +67 -25
- package/dest/interfaces/validator.d.ts.map +1 -1
- package/dest/interfaces/validator.js +6 -2
- package/dest/interfaces/world_state.d.ts +5 -4
- package/dest/interfaces/world_state.d.ts.map +1 -1
- package/dest/kernel/claimed_length_array.js +1 -1
- package/dest/kernel/hints/build_note_hash_read_request_hints.d.ts +3 -3
- package/dest/kernel/hints/build_note_hash_read_request_hints.d.ts.map +1 -1
- package/dest/kernel/hints/build_note_hash_read_request_hints.js +13 -10
- package/dest/kernel/hints/build_nullifier_read_request_hints.d.ts +3 -3
- package/dest/kernel/hints/build_nullifier_read_request_hints.d.ts.map +1 -1
- package/dest/kernel/hints/build_nullifier_read_request_hints.js +13 -10
- package/dest/kernel/hints/build_transient_data_hints.d.ts +5 -2
- package/dest/kernel/hints/build_transient_data_hints.d.ts.map +1 -1
- package/dest/kernel/hints/build_transient_data_hints.js +9 -3
- package/dest/kernel/hints/private_kernel_reset_hints.d.ts +1 -1
- package/dest/kernel/hints/private_kernel_reset_hints.d.ts.map +1 -1
- package/dest/kernel/padded_side_effects.js +1 -1
- package/dest/kernel/private_kernel_tail_circuit_public_inputs.d.ts +2 -1
- package/dest/kernel/private_kernel_tail_circuit_public_inputs.d.ts.map +1 -1
- package/dest/kernel/private_kernel_tail_circuit_public_inputs.js +4 -0
- package/dest/kernel/private_to_avm_accumulated_data.js +2 -2
- package/dest/kernel/private_to_public_accumulated_data.js +2 -2
- package/dest/kernel/private_to_rollup_accumulated_data.js +1 -1
- package/dest/logs/debug_log_store.d.ts +30 -0
- package/dest/logs/debug_log_store.d.ts.map +1 -0
- package/dest/logs/debug_log_store.js +30 -0
- package/dest/logs/extended_directional_app_tagging_secret.d.ts +47 -0
- package/dest/logs/extended_directional_app_tagging_secret.d.ts.map +1 -0
- package/dest/logs/{directional_app_tagging_secret.js → extended_directional_app_tagging_secret.js} +35 -20
- package/dest/logs/index.d.ts +4 -2
- package/dest/logs/index.d.ts.map +1 -1
- package/dest/logs/index.js +3 -1
- package/dest/logs/log_filter.d.ts +4 -1
- package/dest/logs/log_filter.d.ts.map +1 -1
- package/dest/logs/log_filter.js +2 -1
- package/dest/logs/message_context.d.ts +4 -7
- package/dest/logs/message_context.d.ts.map +1 -1
- package/dest/logs/message_context.js +23 -9
- package/dest/logs/pending_tagged_log.d.ts +2 -3
- package/dest/logs/pending_tagged_log.d.ts.map +1 -1
- package/dest/logs/pending_tagged_log.js +2 -2
- package/dest/logs/pre_tag.d.ts +16 -11
- package/dest/logs/pre_tag.d.ts.map +1 -1
- package/dest/logs/pre_tag.js +2 -2
- package/dest/logs/private_log.js +1 -1
- package/dest/logs/public_log.d.ts +4 -3
- package/dest/logs/public_log.d.ts.map +1 -1
- package/dest/logs/public_log.js +9 -2
- package/dest/logs/shared_secret_derivation.d.ts +11 -10
- package/dest/logs/shared_secret_derivation.d.ts.map +1 -1
- package/dest/logs/shared_secret_derivation.js +15 -9
- package/dest/logs/siloed_tag.d.ts +8 -3
- package/dest/logs/siloed_tag.d.ts.map +1 -1
- package/dest/logs/siloed_tag.js +11 -2
- package/dest/logs/tag.js +1 -1
- package/dest/logs/tagging_index_range.d.ts +40 -0
- package/dest/logs/tagging_index_range.d.ts.map +1 -0
- package/dest/logs/tagging_index_range.js +8 -0
- package/dest/logs/tx_scoped_l2_log.d.ts +3 -1
- package/dest/logs/tx_scoped_l2_log.d.ts.map +1 -1
- package/dest/logs/tx_scoped_l2_log.js +7 -0
- package/dest/messaging/l1_to_l2_message.d.ts +3 -2
- package/dest/messaging/l1_to_l2_message.d.ts.map +1 -1
- package/dest/messaging/l1_to_l2_message.js +11 -13
- package/dest/messaging/l2_to_l1_membership.d.ts +32 -6
- package/dest/messaging/l2_to_l1_membership.d.ts.map +1 -1
- package/dest/messaging/l2_to_l1_membership.js +69 -26
- package/dest/noir/index.d.ts +3 -3
- package/dest/noir/index.d.ts.map +1 -1
- package/dest/note/note_dao.d.ts +1 -1
- package/dest/note/note_dao.d.ts.map +1 -1
- package/dest/note/note_dao.js +1 -4
- package/dest/p2p/attestation_utils.d.ts +11 -1
- package/dest/p2p/attestation_utils.d.ts.map +1 -1
- package/dest/p2p/attestation_utils.js +45 -0
- package/dest/p2p/checkpoint_proposal.d.ts +1 -6
- package/dest/p2p/checkpoint_proposal.d.ts.map +1 -1
- package/dest/p2p/checkpoint_proposal.js +13 -23
- package/dest/p2p/client_type.d.ts +2 -5
- package/dest/p2p/client_type.d.ts.map +1 -1
- package/dest/p2p/client_type.js +0 -7
- package/dest/p2p/index.d.ts +1 -2
- package/dest/p2p/index.d.ts.map +1 -1
- package/dest/p2p/index.js +0 -1
- package/dest/p2p/peer_error.d.ts +3 -1
- package/dest/p2p/peer_error.d.ts.map +1 -1
- package/dest/p2p/peer_error.js +5 -0
- package/dest/p2p/topic_type.d.ts +3 -4
- package/dest/p2p/topic_type.d.ts.map +1 -1
- package/dest/p2p/topic_type.js +7 -24
- package/dest/parity/parity_base_private_inputs.js +1 -1
- package/dest/proofs/chonk_proof.d.ts +1 -1
- package/dest/proofs/chonk_proof.d.ts.map +1 -1
- package/dest/proofs/chonk_proof.js +7 -1
- package/dest/rollup/base_rollup_hints.js +2 -2
- package/dest/rollup/block_root_rollup_private_inputs.js +5 -5
- package/dest/rollup/checkpoint_rollup_public_inputs.js +1 -1
- package/dest/rollup/checkpoint_root_rollup_private_inputs.js +3 -3
- package/dest/rollup/root_rollup_public_inputs.js +1 -1
- package/dest/rollup/tree_snapshot_diff_hints.js +2 -2
- package/dest/slashing/tally.d.ts +7 -2
- package/dest/slashing/tally.d.ts.map +1 -1
- package/dest/slashing/tally.js +30 -2
- package/dest/tests/factories.d.ts +3 -1
- package/dest/tests/factories.d.ts.map +1 -1
- package/dest/tests/factories.js +8 -0
- package/dest/tests/mocks.d.ts +5 -3
- package/dest/tests/mocks.d.ts.map +1 -1
- package/dest/tests/mocks.js +18 -13
- package/dest/tx/block_header.d.ts +3 -1
- package/dest/tx/block_header.d.ts.map +1 -1
- package/dest/tx/block_header.js +4 -0
- package/dest/tx/capsule.d.ts +6 -2
- package/dest/tx/capsule.d.ts.map +1 -1
- package/dest/tx/capsule.js +9 -3
- package/dest/tx/private_execution_result.d.ts +6 -6
- package/dest/tx/private_execution_result.d.ts.map +1 -1
- package/dest/tx/private_execution_result.js +6 -6
- package/dest/tx/profiling.d.ts +17 -5
- package/dest/tx/profiling.d.ts.map +1 -1
- package/dest/tx/profiling.js +15 -5
- package/dest/tx/protocol_contracts.js +2 -2
- package/dest/tx/public_simulation_output.d.ts +4 -2
- package/dest/tx/public_simulation_output.d.ts.map +1 -1
- package/dest/tx/public_simulation_output.js +7 -3
- package/dest/tx/simulated_tx.d.ts +5 -2
- package/dest/tx/simulated_tx.d.ts.map +1 -1
- package/dest/tx/simulated_tx.js +4 -1
- package/dest/tx/tx.d.ts +6 -5
- package/dest/tx/tx.d.ts.map +1 -1
- package/dest/tx/tx.js +18 -6
- package/dest/tx/tx_receipt.d.ts +22 -3
- package/dest/tx/tx_receipt.d.ts.map +1 -1
- package/dest/tx/tx_receipt.js +15 -4
- package/dest/tx/validator/error_texts.d.ts +9 -1
- package/dest/tx/validator/error_texts.d.ts.map +1 -1
- package/dest/tx/validator/error_texts.js +10 -0
- package/dest/update-checker/index.d.ts +3 -2
- package/dest/update-checker/index.d.ts.map +1 -1
- package/dest/update-checker/index.js +2 -1
- package/dest/update-checker/package_version.d.ts +3 -0
- package/dest/update-checker/package_version.d.ts.map +1 -0
- package/dest/update-checker/package_version.js +24 -0
- package/dest/update-checker/version_checker.d.ts +25 -0
- package/dest/update-checker/version_checker.d.ts.map +1 -0
- package/dest/update-checker/version_checker.js +50 -0
- package/dest/validators/errors.d.ts +6 -1
- package/dest/validators/errors.d.ts.map +1 -1
- package/dest/validators/errors.js +7 -0
- package/dest/versioning/versioning.d.ts +4 -2
- package/dest/versioning/versioning.d.ts.map +1 -1
- package/dest/versioning/versioning.js +4 -1
- package/dest/vks/vk_data.js +1 -1
- package/package.json +10 -10
- package/src/abi/buffer.ts +25 -4
- package/src/abi/decoder.ts +36 -82
- package/src/abi/encoder.ts +49 -6
- package/src/abi/event_metadata_definition.ts +2 -0
- package/src/abi/function_selector.ts +1 -1
- package/src/abi/function_signature_decoder.ts +77 -0
- package/src/abi/index.ts +1 -0
- package/src/abi/utils.ts +25 -0
- package/src/avm/avm_accumulated_data.ts +6 -6
- package/src/avm/avm_circuit_public_inputs.ts +4 -4
- package/src/avm/revert_code.ts +15 -0
- package/src/block/l2_block.ts +13 -1
- package/src/block/l2_block_source.ts +16 -7
- package/src/block/l2_block_stream/l2_block_stream.ts +21 -0
- package/src/checkpoint/checkpoint.ts +12 -3
- package/src/checkpoint/index.ts +1 -0
- package/src/checkpoint/validate.ts +230 -0
- package/src/config/sequencer-config.ts +16 -1
- package/src/epoch-helpers/index.ts +22 -0
- package/src/gas/README.md +123 -0
- package/src/gas/gas_fees.ts +7 -1
- package/src/hash/hash.ts +34 -0
- package/src/interfaces/allowed_element.ts +29 -9
- package/src/interfaces/archiver.ts +3 -2
- package/src/interfaces/aztec-node.ts +24 -5
- package/src/interfaces/block-builder.ts +60 -14
- package/src/interfaces/configs.ts +29 -8
- package/src/interfaces/merkle_tree_operations.ts +8 -18
- package/src/interfaces/p2p.ts +2 -13
- package/src/interfaces/prover-client.ts +8 -0
- package/src/interfaces/validator.ts +18 -2
- package/src/interfaces/world_state.ts +4 -3
- package/src/kernel/claimed_length_array.ts +2 -2
- package/src/kernel/hints/build_note_hash_read_request_hints.ts +14 -18
- package/src/kernel/hints/build_nullifier_read_request_hints.ts +15 -18
- package/src/kernel/hints/build_transient_data_hints.ts +17 -2
- package/src/kernel/hints/private_kernel_reset_hints.ts +5 -2
- package/src/kernel/hints/read_request_hints.ts +3 -3
- package/src/kernel/padded_side_effects.ts +3 -3
- package/src/kernel/private_kernel_tail_circuit_public_inputs.ts +9 -0
- package/src/kernel/private_to_avm_accumulated_data.ts +4 -4
- package/src/kernel/private_to_public_accumulated_data.ts +10 -10
- package/src/kernel/private_to_rollup_accumulated_data.ts +5 -5
- package/src/logs/debug_log_store.ts +54 -0
- package/src/logs/{directional_app_tagging_secret.ts → extended_directional_app_tagging_secret.ts} +41 -22
- package/src/logs/index.ts +3 -1
- package/src/logs/log_filter.ts +5 -0
- package/src/logs/message_context.ts +17 -7
- package/src/logs/pending_tagged_log.ts +1 -3
- package/src/logs/pre_tag.ts +5 -5
- package/src/logs/private_log.ts +1 -1
- package/src/logs/public_log.ts +15 -3
- package/src/logs/shared_secret_derivation.ts +21 -10
- package/src/logs/siloed_tag.ts +14 -3
- package/src/logs/tag.ts +1 -1
- package/src/logs/tagging_index_range.ts +24 -0
- package/src/logs/tx_scoped_l2_log.ts +16 -0
- package/src/messaging/l1_to_l2_message.ts +12 -9
- package/src/messaging/l2_to_l1_membership.ts +98 -33
- package/src/noir/index.ts +2 -2
- package/src/note/note_dao.ts +1 -4
- package/src/p2p/attestation_utils.ts +56 -0
- package/src/p2p/checkpoint_proposal.ts +23 -37
- package/src/p2p/client_type.ts +0 -6
- package/src/p2p/index.ts +0 -1
- package/src/p2p/peer_error.ts +7 -0
- package/src/p2p/topic_type.ts +8 -15
- package/src/parity/parity_base_private_inputs.ts +1 -1
- package/src/proofs/chonk_proof.ts +9 -1
- package/src/rollup/base_rollup_hints.ts +2 -2
- package/src/rollup/block_root_rollup_private_inputs.ts +8 -8
- package/src/rollup/checkpoint_rollup_public_inputs.ts +2 -2
- package/src/rollup/checkpoint_root_rollup_private_inputs.ts +4 -4
- package/src/rollup/root_rollup_public_inputs.ts +2 -2
- package/src/rollup/tree_snapshot_diff_hints.ts +5 -5
- package/src/slashing/tally.ts +34 -1
- package/src/tests/factories.ts +9 -0
- package/src/tests/mocks.ts +25 -10
- package/src/tx/block_header.ts +6 -0
- package/src/tx/capsule.ts +10 -2
- package/src/tx/private_execution_result.ts +5 -5
- package/src/tx/profiling.ts +14 -5
- package/src/tx/protocol_contracts.ts +2 -2
- package/src/tx/public_simulation_output.ts +4 -0
- package/src/tx/simulated_tx.ts +8 -1
- package/src/tx/tx.ts +20 -11
- package/src/tx/tx_receipt.ts +17 -2
- package/src/tx/validator/error_texts.ts +12 -0
- package/src/update-checker/index.ts +2 -1
- package/src/update-checker/package_version.ts +30 -0
- package/src/update-checker/version_checker.ts +65 -0
- package/src/validators/errors.ts +9 -0
- package/src/versioning/versioning.ts +4 -1
- package/src/vks/vk_data.ts +1 -1
- package/dest/logs/directional_app_tagging_secret.d.ts +0 -40
- package/dest/logs/directional_app_tagging_secret.d.ts.map +0 -1
- package/dest/update-checker/update-checker.d.ts +0 -49
- package/dest/update-checker/update-checker.d.ts.map +0 -1
- package/dest/update-checker/update-checker.js +0 -130
- package/src/update-checker/update-checker.ts +0 -166
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { ABIParameter, ABIVariable, AbiType } from './abi.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Decodes the signature of a function from the name and parameters.
|
|
5
|
+
*/
|
|
6
|
+
export class FunctionSignatureDecoder {
|
|
7
|
+
private separator: string;
|
|
8
|
+
constructor(
|
|
9
|
+
private name: string,
|
|
10
|
+
private parameters: ABIParameter[],
|
|
11
|
+
private includeNames = false,
|
|
12
|
+
) {
|
|
13
|
+
this.separator = includeNames ? ', ' : ',';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Decodes a single function parameter type for the function signature.
|
|
18
|
+
* @param param - The parameter type to decode.
|
|
19
|
+
* @returns A string representing the parameter type.
|
|
20
|
+
*/
|
|
21
|
+
private getParameterType(param: AbiType): string {
|
|
22
|
+
switch (param.kind) {
|
|
23
|
+
case 'field':
|
|
24
|
+
return 'Field';
|
|
25
|
+
case 'integer':
|
|
26
|
+
return param.sign === 'signed' ? `i${param.width}` : `u${param.width}`;
|
|
27
|
+
case 'boolean':
|
|
28
|
+
return 'bool';
|
|
29
|
+
case 'array':
|
|
30
|
+
return `[${this.getParameterType(param.type)};${param.length}]`;
|
|
31
|
+
case 'string':
|
|
32
|
+
return `str<${param.length}>`;
|
|
33
|
+
case 'struct':
|
|
34
|
+
return `(${param.fields.map(field => `${this.decodeParameter(field)}`).join(this.separator)})`;
|
|
35
|
+
default:
|
|
36
|
+
throw new Error(`Unsupported type: ${param.kind}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Decodes a single function parameter for the function signature.
|
|
42
|
+
* @param param - The parameter to decode.
|
|
43
|
+
* @returns A string representing the parameter type and optionally its name.
|
|
44
|
+
*/
|
|
45
|
+
private decodeParameter(param: ABIVariable): string {
|
|
46
|
+
const type = this.getParameterType(param.type);
|
|
47
|
+
return this.includeNames ? `${param.name}: ${type}` : type;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Decodes all the parameters and build the function signature
|
|
52
|
+
* @returns The function signature.
|
|
53
|
+
*/
|
|
54
|
+
public decode(): string {
|
|
55
|
+
return `${this.name}(${this.parameters.map(param => this.decodeParameter(param)).join(this.separator)})`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Decodes a function signature from the name and parameters.
|
|
61
|
+
* @param name - The name of the function.
|
|
62
|
+
* @param parameters - The parameters of the function.
|
|
63
|
+
* @returns - The function signature.
|
|
64
|
+
*/
|
|
65
|
+
export function decodeFunctionSignature(name: string, parameters: ABIParameter[]) {
|
|
66
|
+
return new FunctionSignatureDecoder(name, parameters).decode();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Decodes a function signature from the name and parameters including parameter names.
|
|
71
|
+
* @param name - The name of the function.
|
|
72
|
+
* @param parameters - The parameters of the function.
|
|
73
|
+
* @returns - The user-friendly function signature.
|
|
74
|
+
*/
|
|
75
|
+
export function decodeFunctionSignatureWithParameterNames(name: string, parameters: ABIParameter[]) {
|
|
76
|
+
return new FunctionSignatureDecoder(name, parameters, true).decode();
|
|
77
|
+
}
|
package/src/abi/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './abi.js';
|
|
2
2
|
export * from './buffer.js';
|
|
3
3
|
export * from './decoder.js';
|
|
4
|
+
export * from './function_signature_decoder.js';
|
|
4
5
|
export * from './encoder.js';
|
|
5
6
|
export * from './authorization_selector.js';
|
|
6
7
|
export * from './event_metadata_definition.js';
|
package/src/abi/utils.ts
CHANGED
|
@@ -81,6 +81,31 @@ export function isBoundedVecStruct(abiType: AbiType) {
|
|
|
81
81
|
);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Returns whether the ABI type is Noir's std::option::Option lowered to a struct.
|
|
86
|
+
* @param abiType - Type to check.
|
|
87
|
+
* @returns A boolean indicating whether the ABI type is an Option struct.
|
|
88
|
+
*/
|
|
89
|
+
export function isOptionStruct(abiType: AbiType) {
|
|
90
|
+
return (
|
|
91
|
+
abiType.kind === 'struct' &&
|
|
92
|
+
abiType.path === 'std::option::Option' &&
|
|
93
|
+
abiType.fields.length === 2 &&
|
|
94
|
+
abiType.fields[0].name === '_is_some' &&
|
|
95
|
+
abiType.fields[1].name === '_value'
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Returns whether `null` or `undefined` can be mapped to a valid ABI value for this type.
|
|
101
|
+
*
|
|
102
|
+
* @param abiType - Type to check.
|
|
103
|
+
* @returns A boolean indicating whether nullish values are valid shorthand for this ABI type.
|
|
104
|
+
*/
|
|
105
|
+
export function canBeMappedFromNullOrUndefined(abiType: AbiType) {
|
|
106
|
+
return isOptionStruct(abiType);
|
|
107
|
+
}
|
|
108
|
+
|
|
84
109
|
/**
|
|
85
110
|
* Returns a bigint by parsing a serialized 2's complement signed int.
|
|
86
111
|
* @param b - The signed int as a buffer
|
|
@@ -88,11 +88,11 @@ export class AvmAccumulatedData {
|
|
|
88
88
|
static fromBuffer(buffer: Buffer | BufferReader) {
|
|
89
89
|
const reader = BufferReader.asReader(buffer);
|
|
90
90
|
return new this(
|
|
91
|
-
reader.
|
|
92
|
-
reader.
|
|
93
|
-
reader.
|
|
91
|
+
reader.readTuple(MAX_NOTE_HASHES_PER_TX, Fr),
|
|
92
|
+
reader.readTuple(MAX_NULLIFIERS_PER_TX, Fr),
|
|
93
|
+
reader.readTuple(MAX_L2_TO_L1_MSGS_PER_TX, ScopedL2ToL1Message),
|
|
94
94
|
reader.readObject(FlatPublicLogs),
|
|
95
|
-
reader.
|
|
95
|
+
reader.readTuple(MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataWrite),
|
|
96
96
|
);
|
|
97
97
|
}
|
|
98
98
|
|
|
@@ -115,9 +115,9 @@ export class AvmAccumulatedData {
|
|
|
115
115
|
return new this(
|
|
116
116
|
reader.readFieldArray(MAX_NOTE_HASHES_PER_TX),
|
|
117
117
|
reader.readFieldArray(MAX_NULLIFIERS_PER_TX),
|
|
118
|
-
reader.
|
|
118
|
+
reader.readTuple(MAX_L2_TO_L1_MSGS_PER_TX, ScopedL2ToL1Message),
|
|
119
119
|
reader.readObject(FlatPublicLogs),
|
|
120
|
-
reader.
|
|
120
|
+
reader.readTuple(MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataWrite),
|
|
121
121
|
);
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -143,8 +143,8 @@ export class AvmCircuitPublicInputs {
|
|
|
143
143
|
reader.readObject(AztecAddress),
|
|
144
144
|
reader.readObject(Fr),
|
|
145
145
|
reader.readObject(PublicCallRequestArrayLengths),
|
|
146
|
-
reader.
|
|
147
|
-
reader.
|
|
146
|
+
reader.readTuple(MAX_ENQUEUED_CALLS_PER_TX, PublicCallRequest),
|
|
147
|
+
reader.readTuple(MAX_ENQUEUED_CALLS_PER_TX, PublicCallRequest),
|
|
148
148
|
reader.readObject(PublicCallRequest),
|
|
149
149
|
reader.readObject(PrivateToAvmAccumulatedDataArrayLengths),
|
|
150
150
|
reader.readObject(PrivateToAvmAccumulatedDataArrayLengths),
|
|
@@ -206,8 +206,8 @@ export class AvmCircuitPublicInputs {
|
|
|
206
206
|
AztecAddress.fromFields(reader),
|
|
207
207
|
reader.readField(),
|
|
208
208
|
PublicCallRequestArrayLengths.fromFields(reader),
|
|
209
|
-
reader.
|
|
210
|
-
reader.
|
|
209
|
+
reader.readTuple(MAX_ENQUEUED_CALLS_PER_TX, PublicCallRequest),
|
|
210
|
+
reader.readTuple(MAX_ENQUEUED_CALLS_PER_TX, PublicCallRequest),
|
|
211
211
|
PublicCallRequest.fromFields(reader),
|
|
212
212
|
PrivateToAvmAccumulatedDataArrayLengths.fromFields(reader),
|
|
213
213
|
PrivateToAvmAccumulatedDataArrayLengths.fromFields(reader),
|
package/src/avm/revert_code.ts
CHANGED
|
@@ -5,10 +5,25 @@ import { BufferReader, FieldReader } from '@aztec/foundation/serialize';
|
|
|
5
5
|
import { inspect } from 'util';
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Tracks which revertible phases of a transaction's public execution reverted.
|
|
10
|
+
*
|
|
11
|
+
* A transaction executes in three sequential phases:
|
|
12
|
+
* 1. SETUP – non-revertible; if this fails the entire transaction is rejected.
|
|
13
|
+
* 2. APP_LOGIC – revertible; its state changes are rolled back on failure.
|
|
14
|
+
* 3. TEARDOWN – revertible; always runs (even after app-logic revert) so the fee-payment contract can clean up.
|
|
15
|
+
*
|
|
16
|
+
* Only APP_LOGIC and TEARDOWN can produce a revert code. SETUP failures throw instead and discard the transaction
|
|
17
|
+
* entirely.
|
|
18
|
+
*/
|
|
8
19
|
export enum RevertCodeEnum {
|
|
20
|
+
/** All phases completed successfully; no state was rolled back. */
|
|
9
21
|
OK = 0,
|
|
22
|
+
/** APP_LOGIC reverted; its state changes were discarded. If present, TEARDOWN still ran and succeeded. */
|
|
10
23
|
APP_LOGIC_REVERTED = 1,
|
|
24
|
+
/** TEARDOWN reverted; its state changes were discarded. APP_LOGIC succeeded. */
|
|
11
25
|
TEARDOWN_REVERTED = 2,
|
|
26
|
+
/** Both APP_LOGIC and TEARDOWN reverted; only SETUP effects are kept. */
|
|
12
27
|
BOTH_REVERTED = 3,
|
|
13
28
|
}
|
|
14
29
|
|
package/src/block/l2_block.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type BlockBlobData, encodeBlockBlobData } from '@aztec/blob-lib/encoding';
|
|
2
|
+
import { DA_GAS_PER_FIELD } from '@aztec/constants';
|
|
2
3
|
import {
|
|
3
4
|
BlockNumber,
|
|
4
5
|
CheckpointNumber,
|
|
@@ -175,7 +176,7 @@ export class L2Block {
|
|
|
175
176
|
} & Partial<Parameters<typeof BlockHeader.random>[0]> = {},
|
|
176
177
|
): Promise<L2Block> {
|
|
177
178
|
const archive = new AppendOnlyTreeSnapshot(Fr.random(), blockNumber + 1);
|
|
178
|
-
const header = BlockHeader.random({
|
|
179
|
+
const header = BlockHeader.random({ ...blockHeaderOverrides, blockNumber });
|
|
179
180
|
const body = await Body.random({ txsPerBlock, makeTxOptions, ...txOptions });
|
|
180
181
|
return new L2Block(archive, header, body, checkpointNumber, indexWithinCheckpoint);
|
|
181
182
|
}
|
|
@@ -221,4 +222,15 @@ export class L2Block {
|
|
|
221
222
|
timestamp: this.header.globalVariables.timestamp,
|
|
222
223
|
};
|
|
223
224
|
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Compute how much DA gas this block uses.
|
|
228
|
+
*
|
|
229
|
+
* @remarks This assumes DA gas is computed solely based on the number of blob fields in transactions.
|
|
230
|
+
* This may change in the future, but we cannot access the actual DA gas used in a block since it's not exposed
|
|
231
|
+
* in the L2BlockHeader, so we have to rely on recomputing it.
|
|
232
|
+
*/
|
|
233
|
+
computeDAGasUsed(): number {
|
|
234
|
+
return this.body.txEffects.reduce((total, txEffect) => total + txEffect.getNumBlobFields(), 0) * DA_GAS_PER_FIELD;
|
|
235
|
+
}
|
|
224
236
|
}
|
|
@@ -49,6 +49,12 @@ export interface L2BlockSource {
|
|
|
49
49
|
*/
|
|
50
50
|
getBlockNumber(): Promise<BlockNumber>;
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Gets the number of the latest L2 checkpoint processed by the block source implementation.
|
|
54
|
+
* @returns The number of the latest L2 checkpoint processed by the block source implementation.
|
|
55
|
+
*/
|
|
56
|
+
getCheckpointNumber(): Promise<CheckpointNumber>;
|
|
57
|
+
|
|
52
58
|
/**
|
|
53
59
|
* Gets the number of the latest L2 block proven seen by the block source implementation.
|
|
54
60
|
* @returns The number of the latest L2 block proven seen by the block source implementation.
|
|
@@ -62,9 +68,8 @@ export interface L2BlockSource {
|
|
|
62
68
|
getCheckpointedL2BlockNumber(): Promise<BlockNumber>;
|
|
63
69
|
|
|
64
70
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* TODO(#13569): Compute proper finalized block number based on L1 finalized block.
|
|
71
|
+
* Returns the finalized L2 block number. A block is finalized when it was proven
|
|
72
|
+
* in an L1 block that has itself been finalized on Ethereum.
|
|
68
73
|
* @returns The finalized block number.
|
|
69
74
|
*/
|
|
70
75
|
getFinalizedL2BlockNumber(): Promise<BlockNumber>;
|
|
@@ -170,14 +175,18 @@ export interface L2BlockSource {
|
|
|
170
175
|
getSettledTxReceipt(txHash: TxHash): Promise<TxReceipt | undefined>;
|
|
171
176
|
|
|
172
177
|
/**
|
|
173
|
-
* Returns the
|
|
178
|
+
* Returns the last L2 slot number for which we have all L1 data needed to build the next checkpoint.
|
|
179
|
+
* Determined by the max of two signals: L1 block sync progress and latest synced checkpoint slot.
|
|
180
|
+
* The checkpoint signal handles missed L1 blocks, since a published checkpoint seals the message tree
|
|
181
|
+
* for the next checkpoint via the inbox LAG mechanism.
|
|
174
182
|
*/
|
|
175
|
-
|
|
183
|
+
getSyncedL2SlotNumber(): Promise<SlotNumber | undefined>;
|
|
176
184
|
|
|
177
185
|
/**
|
|
178
|
-
* Returns the
|
|
186
|
+
* Returns the last L2 epoch number that has been fully synchronized from L1.
|
|
187
|
+
* An epoch is fully synced when all its L2 slots have been fully synced.
|
|
179
188
|
*/
|
|
180
|
-
|
|
189
|
+
getSyncedL2EpochNumber(): Promise<EpochNumber | undefined>;
|
|
181
190
|
|
|
182
191
|
/**
|
|
183
192
|
* Returns all checkpointed block headers for a given epoch.
|
|
@@ -109,6 +109,27 @@ export class L2BlockStream {
|
|
|
109
109
|
|
|
110
110
|
let nextBlockNumber = latestBlockNumber + 1;
|
|
111
111
|
let nextCheckpointToEmit = CheckpointNumber(localTips.checkpointed.checkpoint.number + 1);
|
|
112
|
+
|
|
113
|
+
// When startingBlock is set, also skip ahead for checkpoints.
|
|
114
|
+
if (
|
|
115
|
+
this.opts.startingBlock !== undefined &&
|
|
116
|
+
this.opts.startingBlock >= 1 &&
|
|
117
|
+
nextCheckpointToEmit <= sourceTips.checkpointed.checkpoint.number
|
|
118
|
+
) {
|
|
119
|
+
const startingBlockCheckpoints = await this.l2BlockSource.getCheckpointedBlocks(
|
|
120
|
+
BlockNumber(this.opts.startingBlock),
|
|
121
|
+
1,
|
|
122
|
+
);
|
|
123
|
+
if (startingBlockCheckpoints.length > 0) {
|
|
124
|
+
nextCheckpointToEmit = CheckpointNumber(
|
|
125
|
+
Math.max(nextCheckpointToEmit, startingBlockCheckpoints[0].checkpointNumber),
|
|
126
|
+
);
|
|
127
|
+
} else {
|
|
128
|
+
// startingBlock is past all checkpointed blocks; skip Loop 1 entirely.
|
|
129
|
+
nextCheckpointToEmit = CheckpointNumber(sourceTips.checkpointed.checkpoint.number + 1);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
112
133
|
if (this.opts.skipFinalized) {
|
|
113
134
|
// When skipping finalized blocks we need to provide reliable reorg detection while fetching as few blocks as
|
|
114
135
|
// possible. Finalized blocks cannot be reorged by definition, so we can skip most of them. We do need the very
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
IndexWithinCheckpoint,
|
|
7
7
|
SlotNumber,
|
|
8
8
|
} from '@aztec/foundation/branded-types';
|
|
9
|
-
import { sum } from '@aztec/foundation/collection';
|
|
9
|
+
import { pick, sum } from '@aztec/foundation/collection';
|
|
10
10
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
11
11
|
import { BufferReader, serializeSignedBigInt, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
12
12
|
import type { FieldsOf } from '@aztec/foundation/types';
|
|
@@ -152,10 +152,12 @@ export class Checkpoint {
|
|
|
152
152
|
startBlockNumber?: number;
|
|
153
153
|
previousArchive?: AppendOnlyTreeSnapshot;
|
|
154
154
|
feeAssetPriceModifier?: bigint;
|
|
155
|
+
archive?: AppendOnlyTreeSnapshot;
|
|
155
156
|
} & Partial<Parameters<typeof CheckpointHeader.random>[0]> &
|
|
156
157
|
Partial<Parameters<typeof L2Block.random>[1]> = {},
|
|
157
158
|
) {
|
|
158
|
-
const
|
|
159
|
+
const headerOptions = previousArchive ? { lastArchiveRoot: previousArchive.root, ...options } : options;
|
|
160
|
+
const header = CheckpointHeader.random(headerOptions);
|
|
159
161
|
|
|
160
162
|
// Create blocks sequentially to chain archive roots properly.
|
|
161
163
|
// Each block's header.lastArchive must equal the previous block's archive.
|
|
@@ -166,11 +168,18 @@ export class Checkpoint {
|
|
|
166
168
|
indexWithinCheckpoint: IndexWithinCheckpoint(i),
|
|
167
169
|
...options,
|
|
168
170
|
...(lastArchive ? { lastArchive } : {}),
|
|
171
|
+
...pick(header, 'slotNumber', 'timestamp', 'coinbase', 'feeRecipient', 'gasFees'),
|
|
169
172
|
});
|
|
170
173
|
lastArchive = block.archive;
|
|
171
174
|
blocks.push(block);
|
|
172
175
|
}
|
|
173
176
|
|
|
174
|
-
return new Checkpoint(
|
|
177
|
+
return new Checkpoint(
|
|
178
|
+
options.archive ?? AppendOnlyTreeSnapshot.random(),
|
|
179
|
+
header,
|
|
180
|
+
blocks,
|
|
181
|
+
checkpointNumber,
|
|
182
|
+
feeAssetPriceModifier,
|
|
183
|
+
);
|
|
175
184
|
}
|
|
176
185
|
}
|
package/src/checkpoint/index.ts
CHANGED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { BLOBS_PER_CHECKPOINT, FIELDS_PER_BLOB, MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT } from '@aztec/constants';
|
|
2
|
+
import type { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { sum } from '@aztec/foundation/collection';
|
|
4
|
+
|
|
5
|
+
import { MAX_BLOCKS_PER_CHECKPOINT } from '../deserialization/index.js';
|
|
6
|
+
import type { Checkpoint } from './checkpoint.js';
|
|
7
|
+
|
|
8
|
+
export class CheckpointValidationError extends Error {
|
|
9
|
+
constructor(
|
|
10
|
+
message: string,
|
|
11
|
+
public readonly checkpointNumber: CheckpointNumber,
|
|
12
|
+
public readonly slot: SlotNumber,
|
|
13
|
+
) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = 'CheckpointValidationError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Validates a checkpoint. Throws a CheckpointValidationError if any validation fails.
|
|
21
|
+
* - Validates structural integrity (non-empty, block count, sequential numbers, archive chaining, slot consistency)
|
|
22
|
+
* - Validates checkpoint blob field count against maxBlobFields limit
|
|
23
|
+
* - Validates total L2 gas used by checkpoint blocks against the Rollup contract mana limit
|
|
24
|
+
* - Validates total DA gas used by checkpoint blocks against MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT
|
|
25
|
+
* - Validates individual block L2 gas and DA gas against maxL2BlockGas and maxDABlockGas limits
|
|
26
|
+
*/
|
|
27
|
+
export function validateCheckpoint(
|
|
28
|
+
checkpoint: Checkpoint,
|
|
29
|
+
opts: {
|
|
30
|
+
rollupManaLimit?: number;
|
|
31
|
+
maxL2BlockGas?: number;
|
|
32
|
+
maxDABlockGas?: number;
|
|
33
|
+
maxTxsPerCheckpoint?: number;
|
|
34
|
+
maxTxsPerBlock?: number;
|
|
35
|
+
},
|
|
36
|
+
): void {
|
|
37
|
+
validateCheckpointStructure(checkpoint);
|
|
38
|
+
validateCheckpointLimits(checkpoint, opts);
|
|
39
|
+
validateCheckpointBlocksLimits(checkpoint, opts);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Validates structural integrity of a checkpoint.
|
|
44
|
+
* - Non-empty block list
|
|
45
|
+
* - Block count within MAX_BLOCKS_PER_CHECKPOINT
|
|
46
|
+
* - Checkpoint slot matches the first block's slot
|
|
47
|
+
* - Checkpoint lastArchiveRoot matches the first block's lastArchive root
|
|
48
|
+
* - Sequential block numbers without gaps
|
|
49
|
+
* - Sequential indexWithinCheckpoint starting at 0
|
|
50
|
+
* - Archive root chaining between consecutive blocks
|
|
51
|
+
* - Consistent slot number across all blocks
|
|
52
|
+
* - Global variables (slot, timestamp, coinbase, feeRecipient, gasFees) match checkpoint header for each block
|
|
53
|
+
*/
|
|
54
|
+
export function validateCheckpointStructure(checkpoint: Checkpoint): void {
|
|
55
|
+
const { blocks, number, slot } = checkpoint;
|
|
56
|
+
|
|
57
|
+
if (blocks.length === 0) {
|
|
58
|
+
throw new CheckpointValidationError('Checkpoint has no blocks', number, slot);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (blocks.length > MAX_BLOCKS_PER_CHECKPOINT) {
|
|
62
|
+
throw new CheckpointValidationError(
|
|
63
|
+
`Checkpoint has ${blocks.length} blocks, exceeding limit of ${MAX_BLOCKS_PER_CHECKPOINT}`,
|
|
64
|
+
number,
|
|
65
|
+
slot,
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const firstBlock = blocks[0];
|
|
70
|
+
|
|
71
|
+
if (!checkpoint.header.lastArchiveRoot.equals(firstBlock.header.lastArchive.root)) {
|
|
72
|
+
throw new CheckpointValidationError(
|
|
73
|
+
`Checkpoint lastArchiveRoot does not match first block's lastArchive root`,
|
|
74
|
+
number,
|
|
75
|
+
slot,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
80
|
+
const block = blocks[i];
|
|
81
|
+
|
|
82
|
+
if (block.indexWithinCheckpoint !== i) {
|
|
83
|
+
throw new CheckpointValidationError(
|
|
84
|
+
`Block at index ${i} has indexWithinCheckpoint ${block.indexWithinCheckpoint}, expected ${i}`,
|
|
85
|
+
number,
|
|
86
|
+
slot,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (block.slot !== slot) {
|
|
91
|
+
throw new CheckpointValidationError(
|
|
92
|
+
`Block ${block.number} has slot ${block.slot}, expected ${slot} (all blocks must share the same slot)`,
|
|
93
|
+
number,
|
|
94
|
+
slot,
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (!checkpoint.header.matchesGlobalVariables(block.header.globalVariables)) {
|
|
99
|
+
throw new CheckpointValidationError(
|
|
100
|
+
`Block ${block.number} global variables (slot, timestamp, coinbase, feeRecipient, gasFees) do not match checkpoint header`,
|
|
101
|
+
number,
|
|
102
|
+
slot,
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (i > 0) {
|
|
107
|
+
const prev = blocks[i - 1];
|
|
108
|
+
if (block.number !== prev.number + 1) {
|
|
109
|
+
throw new CheckpointValidationError(
|
|
110
|
+
`Block numbers are not sequential: block at index ${i - 1} has number ${prev.number}, block at index ${i} has number ${block.number}`,
|
|
111
|
+
number,
|
|
112
|
+
slot,
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!block.header.lastArchive.root.equals(prev.archive.root)) {
|
|
117
|
+
throw new CheckpointValidationError(
|
|
118
|
+
`Block ${block.number} lastArchive root does not match archive root of block ${prev.number}`,
|
|
119
|
+
number,
|
|
120
|
+
slot,
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Validates checkpoint blocks gas limits */
|
|
128
|
+
function validateCheckpointBlocksLimits(
|
|
129
|
+
checkpoint: Checkpoint,
|
|
130
|
+
opts: {
|
|
131
|
+
maxL2BlockGas?: number;
|
|
132
|
+
maxDABlockGas?: number;
|
|
133
|
+
maxTxsPerBlock?: number;
|
|
134
|
+
},
|
|
135
|
+
): void {
|
|
136
|
+
const { maxL2BlockGas, maxDABlockGas, maxTxsPerBlock } = opts;
|
|
137
|
+
|
|
138
|
+
if (maxL2BlockGas !== undefined) {
|
|
139
|
+
for (const block of checkpoint.blocks) {
|
|
140
|
+
const blockL2Gas = block.header.totalManaUsed.toNumber();
|
|
141
|
+
if (blockL2Gas > maxL2BlockGas) {
|
|
142
|
+
throw new CheckpointValidationError(
|
|
143
|
+
`Block ${block.number} in checkpoint has L2 gas used ${blockL2Gas} exceeding limit of ${maxL2BlockGas}`,
|
|
144
|
+
checkpoint.number,
|
|
145
|
+
checkpoint.slot,
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (maxDABlockGas !== undefined) {
|
|
152
|
+
for (const block of checkpoint.blocks) {
|
|
153
|
+
const blockDAGas = block.computeDAGasUsed();
|
|
154
|
+
if (blockDAGas > maxDABlockGas) {
|
|
155
|
+
throw new CheckpointValidationError(
|
|
156
|
+
`Block ${block.number} in checkpoint has DA gas used ${blockDAGas} exceeding limit of ${maxDABlockGas}`,
|
|
157
|
+
checkpoint.number,
|
|
158
|
+
checkpoint.slot,
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (maxTxsPerBlock !== undefined) {
|
|
165
|
+
for (const block of checkpoint.blocks) {
|
|
166
|
+
const blockTxCount = block.body.txEffects.length;
|
|
167
|
+
if (blockTxCount > maxTxsPerBlock) {
|
|
168
|
+
throw new CheckpointValidationError(
|
|
169
|
+
`Block ${block.number} in checkpoint has ${blockTxCount} txs exceeding limit of ${maxTxsPerBlock}`,
|
|
170
|
+
checkpoint.number,
|
|
171
|
+
checkpoint.slot,
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Validates checkpoint max blob fields, gas limits, and tx limits */
|
|
179
|
+
function validateCheckpointLimits(
|
|
180
|
+
checkpoint: Checkpoint,
|
|
181
|
+
opts: {
|
|
182
|
+
rollupManaLimit?: number;
|
|
183
|
+
maxTxsPerCheckpoint?: number;
|
|
184
|
+
},
|
|
185
|
+
): void {
|
|
186
|
+
const { rollupManaLimit, maxTxsPerCheckpoint } = opts;
|
|
187
|
+
|
|
188
|
+
const maxBlobFields = BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB;
|
|
189
|
+
const maxDAGas = MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT;
|
|
190
|
+
|
|
191
|
+
if (rollupManaLimit !== undefined) {
|
|
192
|
+
const checkpointMana = sum(checkpoint.blocks.map(block => block.header.totalManaUsed.toNumber()));
|
|
193
|
+
if (checkpointMana > rollupManaLimit) {
|
|
194
|
+
throw new CheckpointValidationError(
|
|
195
|
+
`Checkpoint mana cost ${checkpointMana} exceeds rollup limit of ${rollupManaLimit}`,
|
|
196
|
+
checkpoint.number,
|
|
197
|
+
checkpoint.slot,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const checkpointDAGas = sum(checkpoint.blocks.map(block => block.computeDAGasUsed()));
|
|
203
|
+
if (checkpointDAGas > maxDAGas) {
|
|
204
|
+
throw new CheckpointValidationError(
|
|
205
|
+
`Checkpoint DA gas cost ${checkpointDAGas} exceeds limit of ${maxDAGas}`,
|
|
206
|
+
checkpoint.number,
|
|
207
|
+
checkpoint.slot,
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const checkpointBlobFields = checkpoint.toBlobFields().length;
|
|
212
|
+
if (checkpointBlobFields > maxBlobFields) {
|
|
213
|
+
throw new CheckpointValidationError(
|
|
214
|
+
`Checkpoint blob field count ${checkpointBlobFields} exceeds limit of ${maxBlobFields}`,
|
|
215
|
+
checkpoint.number,
|
|
216
|
+
checkpoint.slot,
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (maxTxsPerCheckpoint !== undefined) {
|
|
221
|
+
const checkpointTxCount = sum(checkpoint.blocks.map(block => block.body.txEffects.length));
|
|
222
|
+
if (checkpointTxCount > maxTxsPerCheckpoint) {
|
|
223
|
+
throw new CheckpointValidationError(
|
|
224
|
+
`Checkpoint tx count ${checkpointTxCount} exceeds limit of ${maxTxsPerCheckpoint}`,
|
|
225
|
+
checkpoint.number,
|
|
226
|
+
checkpoint.slot,
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
@@ -8,7 +8,9 @@ import type { SequencerConfig } from '../interfaces/configs.js';
|
|
|
8
8
|
* (like blockDurationMs needed by both p2p and sequencer-client) are defined here
|
|
9
9
|
* to avoid duplication.
|
|
10
10
|
*/
|
|
11
|
-
export const sharedSequencerConfigMappings: ConfigMappingsType<
|
|
11
|
+
export const sharedSequencerConfigMappings: ConfigMappingsType<
|
|
12
|
+
Pick<SequencerConfig, 'blockDurationMs' | 'expectedBlockProposalsPerSlot' | 'maxTxsPerBlock'>
|
|
13
|
+
> = {
|
|
12
14
|
blockDurationMs: {
|
|
13
15
|
env: 'SEQ_BLOCK_DURATION_MS',
|
|
14
16
|
description:
|
|
@@ -16,4 +18,17 @@ export const sharedSequencerConfigMappings: ConfigMappingsType<Pick<SequencerCon
|
|
|
16
18
|
'If undefined (default), builds a single block per slot using the full slot duration.',
|
|
17
19
|
parseEnv: (val: string) => (val ? parseInt(val, 10) : undefined),
|
|
18
20
|
},
|
|
21
|
+
expectedBlockProposalsPerSlot: {
|
|
22
|
+
env: 'SEQ_EXPECTED_BLOCK_PROPOSALS_PER_SLOT',
|
|
23
|
+
description:
|
|
24
|
+
'Expected number of block proposals per slot for P2P peer scoring. ' +
|
|
25
|
+
'0 (default) disables block proposal scoring. Set to a positive value to enable.',
|
|
26
|
+
parseEnv: (val: string) => (val ? parseInt(val, 10) : 0),
|
|
27
|
+
defaultValue: 0,
|
|
28
|
+
},
|
|
29
|
+
maxTxsPerBlock: {
|
|
30
|
+
env: 'SEQ_MAX_TX_PER_BLOCK',
|
|
31
|
+
description: 'The maximum number of txs to include in a block.',
|
|
32
|
+
parseEnv: (val: string) => (val ? parseInt(val, 10) : undefined),
|
|
33
|
+
},
|
|
19
34
|
};
|
|
@@ -12,6 +12,7 @@ export type L1RollupConstants = {
|
|
|
12
12
|
ethereumSlotDuration: number;
|
|
13
13
|
proofSubmissionEpochs: number;
|
|
14
14
|
targetCommitteeSize: number;
|
|
15
|
+
rollupManaLimit: number;
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
export const EmptyL1RollupConstants: L1RollupConstants = {
|
|
@@ -22,6 +23,7 @@ export const EmptyL1RollupConstants: L1RollupConstants = {
|
|
|
22
23
|
ethereumSlotDuration: 1,
|
|
23
24
|
proofSubmissionEpochs: 1,
|
|
24
25
|
targetCommitteeSize: 48,
|
|
26
|
+
rollupManaLimit: Number.MAX_SAFE_INTEGER,
|
|
25
27
|
};
|
|
26
28
|
|
|
27
29
|
export const L1RollupConstantsSchema = zodFor<L1RollupConstants>()(
|
|
@@ -33,6 +35,7 @@ export const L1RollupConstantsSchema = zodFor<L1RollupConstants>()(
|
|
|
33
35
|
ethereumSlotDuration: z.number(),
|
|
34
36
|
proofSubmissionEpochs: z.number(),
|
|
35
37
|
targetCommitteeSize: z.number(),
|
|
38
|
+
rollupManaLimit: z.number(),
|
|
36
39
|
}),
|
|
37
40
|
);
|
|
38
41
|
|
|
@@ -54,6 +57,25 @@ export function getSlotAtTimestamp(
|
|
|
54
57
|
: SlotNumber.fromBigInt((ts - constants.l1GenesisTime) / BigInt(constants.slotDuration));
|
|
55
58
|
}
|
|
56
59
|
|
|
60
|
+
/** Returns the timestamp of the next L1 slot boundary after the given wall-clock time. */
|
|
61
|
+
export function getNextL1SlotTimestamp(
|
|
62
|
+
nowInSeconds: number,
|
|
63
|
+
constants: Pick<L1RollupConstants, 'l1GenesisTime' | 'ethereumSlotDuration'>,
|
|
64
|
+
): bigint {
|
|
65
|
+
const now = BigInt(nowInSeconds);
|
|
66
|
+
const elapsed = now - constants.l1GenesisTime;
|
|
67
|
+
const currentL1Slot = elapsed / BigInt(constants.ethereumSlotDuration);
|
|
68
|
+
return constants.l1GenesisTime + (currentL1Slot + 1n) * BigInt(constants.ethereumSlotDuration);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Returns the timestamp of the last L1 slot within a given L2 slot. */
|
|
72
|
+
export function getLastL1SlotTimestampForL2Slot(
|
|
73
|
+
slot: SlotNumber,
|
|
74
|
+
constants: Pick<L1RollupConstants, 'l1GenesisTime' | 'slotDuration' | 'ethereumSlotDuration'>,
|
|
75
|
+
): bigint {
|
|
76
|
+
return getTimestampForSlot(slot, constants) + BigInt(constants.slotDuration - constants.ethereumSlotDuration);
|
|
77
|
+
}
|
|
78
|
+
|
|
57
79
|
/** Returns the L2 slot number at the next L1 block based on the current timestamp. */
|
|
58
80
|
export function getSlotAtNextL1Block(
|
|
59
81
|
currentL1Timestamp: bigint,
|