@aztec/simulator 0.76.4 → 0.77.0-testnet-ignition.21
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/README.md +3 -3
- package/dest/client.d.ts +5 -0
- package/dest/client.d.ts.map +1 -0
- package/dest/client.js +3 -0
- package/dest/{public → common}/db_interfaces.d.ts +8 -33
- package/dest/common/db_interfaces.d.ts.map +1 -0
- package/dest/common/db_interfaces.js +1 -0
- package/dest/common/debug_fn_name.d.ts +3 -2
- package/dest/common/debug_fn_name.d.ts.map +1 -1
- package/dest/common/debug_fn_name.js +2 -5
- package/dest/common/errors.d.ts +4 -4
- package/dest/common/errors.d.ts.map +1 -1
- package/dest/common/errors.js +30 -39
- package/dest/common/index.d.ts +2 -1
- package/dest/common/index.d.ts.map +1 -1
- package/dest/common/index.js +2 -2
- package/dest/common/message_load_oracle_inputs.d.ts +2 -2
- package/dest/common/message_load_oracle_inputs.d.ts.map +1 -1
- package/dest/common/message_load_oracle_inputs.js +8 -8
- package/dest/common/stats/index.d.ts.map +1 -0
- package/dest/{stats → common/stats}/stats.d.ts +2 -2
- package/dest/common/stats/stats.d.ts.map +1 -0
- package/dest/common/stats/stats.js +10 -0
- package/dest/{acvm → private/acvm}/acvm.d.ts +4 -4
- package/dest/private/acvm/acvm.d.ts.map +1 -0
- package/dest/private/acvm/acvm.js +70 -0
- package/dest/{acvm → private/acvm}/acvm_types.d.ts +1 -1
- package/dest/private/acvm/acvm_types.d.ts.map +1 -0
- package/dest/private/acvm/acvm_types.js +3 -0
- package/dest/{acvm → private/acvm}/deserialize.d.ts +2 -2
- package/dest/private/acvm/deserialize.d.ts.map +1 -0
- package/dest/private/acvm/deserialize.js +42 -0
- package/dest/private/acvm/index.d.ts.map +1 -0
- package/dest/private/acvm/index.js +5 -0
- package/dest/{acvm → private/acvm}/oracle/index.d.ts +1 -1
- package/dest/private/acvm/oracle/index.d.ts.map +1 -0
- package/dest/private/acvm/oracle/index.js +2 -0
- package/dest/{acvm → private/acvm}/oracle/oracle.d.ts +4 -3
- package/dest/private/acvm/oracle/oracle.d.ts.map +1 -0
- package/dest/private/acvm/oracle/oracle.js +263 -0
- package/dest/{acvm → private/acvm}/oracle/typed_oracle.d.ts +12 -6
- package/dest/private/acvm/oracle/typed_oracle.d.ts.map +1 -0
- package/dest/private/acvm/oracle/typed_oracle.js +132 -0
- package/dest/{acvm → private/acvm}/serialize.d.ts +7 -3
- package/dest/private/acvm/serialize.d.ts.map +1 -0
- package/dest/private/acvm/serialize.js +46 -0
- package/dest/{client → private}/client_execution_context.d.ts +20 -17
- package/dest/private/client_execution_context.d.ts.map +1 -0
- package/dest/private/client_execution_context.js +378 -0
- package/dest/{client → private}/db_oracle.d.ts +19 -7
- package/dest/private/db_oracle.d.ts.map +1 -0
- package/dest/private/db_oracle.js +14 -0
- package/dest/{client → private}/execution_note_cache.d.ts +2 -2
- package/dest/private/execution_note_cache.d.ts.map +1 -0
- package/dest/private/execution_note_cache.js +180 -0
- package/dest/{common → private}/hashed_values_cache.d.ts +2 -2
- package/dest/private/hashed_values_cache.d.ts.map +1 -0
- package/dest/private/hashed_values_cache.js +46 -0
- package/dest/private/index.d.ts +13 -0
- package/dest/private/index.d.ts.map +1 -0
- package/dest/private/index.js +12 -0
- package/dest/{client → private}/pick_notes.d.ts +1 -1
- package/dest/private/pick_notes.d.ts.map +1 -0
- package/dest/private/pick_notes.js +51 -0
- package/dest/private/private_execution.d.ts +24 -0
- package/dest/private/private_execution.d.ts.map +1 -0
- package/dest/private/private_execution.js +90 -0
- package/dest/{providers → private/providers}/acvm_native.d.ts +5 -5
- package/dest/private/providers/acvm_native.d.ts.map +1 -0
- package/dest/private/providers/acvm_native.js +139 -0
- package/dest/{providers → private/providers}/acvm_wasm.d.ts +4 -4
- package/dest/private/providers/acvm_wasm.d.ts.map +1 -0
- package/dest/private/providers/acvm_wasm.js +62 -0
- package/dest/{providers → private/providers}/acvm_wasm_with_blobs.d.ts +5 -5
- package/dest/private/providers/acvm_wasm_with_blobs.d.ts.map +1 -0
- package/dest/{providers → private/providers}/acvm_wasm_with_blobs.js +3 -6
- package/dest/{providers → private/providers}/factory.d.ts +1 -1
- package/dest/private/providers/factory.d.ts.map +1 -0
- package/dest/private/providers/factory.js +27 -0
- package/dest/{common → private/providers}/simulation_provider.d.ts +5 -5
- package/dest/private/providers/simulation_provider.d.ts.map +1 -0
- package/dest/private/providers/simulation_provider.js +24 -0
- package/dest/private/simulator.d.ts +36 -0
- package/dest/private/simulator.d.ts.map +1 -0
- package/dest/private/simulator.js +78 -0
- package/dest/{client → private}/unconstrained_execution.d.ts +5 -5
- package/dest/private/unconstrained_execution.d.ts.map +1 -0
- package/dest/private/unconstrained_execution.js +27 -0
- package/dest/{client → private}/view_data_oracle.d.ts +15 -7
- package/dest/private/view_data_oracle.d.ts.map +1 -0
- package/dest/private/view_data_oracle.js +260 -0
- package/dest/{avm → public/avm}/avm_context.d.ts +7 -5
- package/dest/public/avm/avm_context.d.ts.map +1 -0
- package/dest/public/avm/avm_context.js +44 -0
- package/dest/{avm → public/avm}/avm_contract_call_result.d.ts +5 -5
- package/dest/public/avm/avm_contract_call_result.d.ts.map +1 -0
- package/dest/public/avm/avm_contract_call_result.js +50 -0
- package/dest/{avm → public/avm}/avm_execution_environment.d.ts +2 -2
- package/dest/public/avm/avm_execution_environment.d.ts.map +1 -0
- package/dest/public/avm/avm_execution_environment.js +31 -0
- package/dest/public/avm/avm_gas.d.ts.map +1 -0
- package/dest/public/avm/avm_gas.js +202 -0
- package/dest/{avm → public/avm}/avm_machine_state.d.ts +2 -2
- package/dest/public/avm/avm_machine_state.d.ts.map +1 -0
- package/dest/public/avm/avm_machine_state.js +106 -0
- package/dest/{avm → public/avm}/avm_memory_types.d.ts +2 -2
- package/dest/public/avm/avm_memory_types.d.ts.map +1 -0
- package/dest/public/avm/avm_memory_types.js +340 -0
- package/dest/{avm → public/avm}/avm_simulator.d.ts +5 -3
- package/dest/public/avm/avm_simulator.d.ts.map +1 -0
- package/dest/public/avm/avm_simulator.js +202 -0
- package/dest/public/avm/bytecode_utils.d.ts.map +1 -0
- package/dest/public/avm/bytecode_utils.js +17 -0
- package/dest/{avm → public/avm}/errors.d.ts +5 -4
- package/dest/public/avm/errors.d.ts.map +1 -0
- package/dest/public/avm/errors.js +179 -0
- package/dest/{avm → public/avm}/fixtures/avm_simulation_tester.d.ts +6 -6
- package/dest/public/avm/fixtures/avm_simulation_tester.d.ts.map +1 -0
- package/dest/public/avm/fixtures/avm_simulation_tester.js +76 -0
- package/dest/{avm → public/avm}/fixtures/base_avm_simulation_tester.d.ts +13 -12
- package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts.map +1 -0
- package/dest/public/avm/fixtures/base_avm_simulation_tester.js +83 -0
- package/dest/{avm → public/avm}/fixtures/index.d.ts +24 -7
- package/dest/public/avm/fixtures/index.d.ts.map +1 -0
- package/dest/public/avm/fixtures/index.js +175 -0
- package/dest/{avm → public/avm}/fixtures/simple_contract_data_source.d.ts +10 -6
- package/dest/public/avm/fixtures/simple_contract_data_source.d.ts.map +1 -0
- package/dest/public/avm/fixtures/simple_contract_data_source.js +74 -0
- package/dest/public/avm/index.d.ts +4 -0
- package/dest/public/avm/index.d.ts.map +1 -0
- package/dest/{avm/index.d.ts → public/avm/index.js} +1 -2
- package/dest/public/avm/journal/index.d.ts.map +1 -0
- package/dest/{avm → public/avm}/journal/journal.d.ts +51 -18
- package/dest/public/avm/journal/journal.d.ts.map +1 -0
- package/dest/public/avm/journal/journal.js +486 -0
- package/dest/{avm → public/avm}/journal/nullifiers.d.ts +8 -6
- package/dest/public/avm/journal/nullifiers.d.ts.map +1 -0
- package/dest/public/avm/journal/nullifiers.js +97 -0
- package/dest/{avm → public/avm}/journal/public_storage.d.ts +2 -2
- package/dest/public/avm/journal/public_storage.d.ts.map +1 -0
- package/dest/public/avm/journal/public_storage.js +145 -0
- package/dest/public/avm/opcodes/accrued_substate.d.ts.map +1 -0
- package/dest/public/avm/opcodes/accrued_substate.js +252 -0
- package/dest/public/avm/opcodes/addressing_mode.d.ts.map +1 -0
- package/dest/public/avm/opcodes/addressing_mode.js +74 -0
- package/dest/public/avm/opcodes/arithmetic.d.ts.map +1 -0
- package/dest/public/avm/opcodes/arithmetic.js +73 -0
- package/dest/public/avm/opcodes/bitwise.d.ts.map +1 -0
- package/dest/public/avm/opcodes/bitwise.js +106 -0
- package/dest/public/avm/opcodes/comparators.d.ts.map +1 -0
- package/dest/public/avm/opcodes/comparators.js +43 -0
- package/dest/public/avm/opcodes/contract.d.ts.map +1 -0
- package/dest/public/avm/opcodes/contract.js +66 -0
- package/dest/public/avm/opcodes/control_flow.d.ts.map +1 -0
- package/dest/public/avm/opcodes/control_flow.js +105 -0
- package/dest/{avm → public/avm}/opcodes/conversion.d.ts +1 -1
- package/dest/public/avm/opcodes/conversion.d.ts.map +1 -0
- package/dest/public/avm/opcodes/conversion.js +69 -0
- package/dest/{avm → public/avm}/opcodes/ec_add.d.ts +1 -1
- package/dest/public/avm/opcodes/ec_add.d.ts.map +1 -0
- package/dest/public/avm/opcodes/ec_add.js +84 -0
- package/dest/public/avm/opcodes/environment_getters.d.ts.map +1 -0
- package/dest/public/avm/opcodes/environment_getters.js +79 -0
- package/dest/public/avm/opcodes/external_calls.d.ts.map +1 -0
- package/dest/public/avm/opcodes/external_calls.js +180 -0
- package/dest/{avm → public/avm}/opcodes/hashing.d.ts +1 -1
- package/dest/public/avm/opcodes/hashing.d.ts.map +1 -0
- package/dest/public/avm/opcodes/hashing.js +114 -0
- package/dest/public/avm/opcodes/index.d.ts.map +1 -0
- package/dest/{avm → public/avm}/opcodes/instruction.d.ts +2 -2
- package/dest/public/avm/opcodes/instruction.d.ts.map +1 -0
- package/dest/public/avm/opcodes/instruction.js +91 -0
- package/dest/public/avm/opcodes/instruction_impl.d.ts.map +1 -0
- package/dest/public/avm/opcodes/instruction_impl.js +30 -0
- package/dest/public/avm/opcodes/memory.d.ts.map +1 -0
- package/dest/public/avm/opcodes/memory.js +253 -0
- package/dest/{avm → public/avm}/opcodes/misc.d.ts +1 -1
- package/dest/public/avm/opcodes/misc.d.ts.map +1 -0
- package/dest/public/avm/opcodes/misc.js +48 -0
- package/dest/public/avm/opcodes/storage.d.ts.map +1 -0
- package/dest/public/avm/opcodes/storage.js +66 -0
- package/dest/public/avm/serialization/buffer_cursor.d.ts.map +1 -0
- package/dest/public/avm/serialization/buffer_cursor.js +99 -0
- package/dest/{avm → public/avm}/serialization/bytecode_serialization.d.ts +1 -1
- package/dest/public/avm/serialization/bytecode_serialization.d.ts.map +1 -0
- package/dest/public/avm/serialization/bytecode_serialization.js +328 -0
- package/dest/{avm → public/avm}/serialization/instruction_serialization.d.ts +1 -2
- package/dest/public/avm/serialization/instruction_serialization.d.ts.map +1 -0
- package/dest/public/avm/serialization/instruction_serialization.js +225 -0
- package/dest/{avm → public/avm}/test_utils.d.ts +6 -4
- package/dest/public/avm/test_utils.d.ts.map +1 -0
- package/dest/public/avm/test_utils.js +52 -0
- package/dest/public/bytecode_errors.js +1 -2
- package/dest/public/execution.d.ts +8 -2
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +4 -5
- package/dest/public/executor_metrics.js +16 -12
- package/dest/public/fixtures/index.js +0 -1
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts +15 -9
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
- package/dest/public/fixtures/public_tx_simulation_tester.js +54 -53
- package/dest/public/fixtures/utils.d.ts +7 -11
- package/dest/public/fixtures/utils.d.ts.map +1 -1
- package/dest/public/fixtures/utils.js +92 -32
- package/dest/public/index.d.ts +5 -4
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/index.js +5 -5
- package/dest/public/public_db_sources.d.ts +82 -34
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +171 -196
- package/dest/public/{public_processor.d.ts → public_processor/public_processor.d.ts} +10 -8
- package/dest/public/public_processor/public_processor.d.ts.map +1 -0
- package/dest/public/public_processor/public_processor.js +379 -0
- package/dest/public/{public_processor_metrics.d.ts → public_processor/public_processor_metrics.d.ts} +3 -3
- package/dest/public/public_processor/public_processor_metrics.d.ts.map +1 -0
- package/dest/public/public_processor/public_processor_metrics.js +125 -0
- package/dest/public/{public_tx_context.d.ts → public_tx_simulator/public_tx_context.d.ts} +14 -8
- package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -0
- package/dest/public/public_tx_simulator/public_tx_context.js +320 -0
- package/dest/public/{public_tx_simulator.d.ts → public_tx_simulator/public_tx_simulator.d.ts} +10 -7
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -0
- package/dest/public/public_tx_simulator/public_tx_simulator.js +325 -0
- package/dest/public/side_effect_errors.js +1 -2
- package/dest/public/side_effect_trace.d.ts +16 -10
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +82 -149
- package/dest/public/side_effect_trace_interface.d.ts +9 -7
- package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
- package/dest/public/side_effect_trace_interface.js +1 -2
- package/dest/public/tx_contract_cache.d.ts +41 -0
- package/dest/public/tx_contract_cache.d.ts.map +1 -0
- package/dest/public/tx_contract_cache.js +49 -0
- package/dest/public/unique_class_ids.js +23 -28
- package/dest/public/utils.d.ts +2 -2
- package/dest/public/utils.d.ts.map +1 -1
- package/dest/public/utils.js +17 -12
- package/dest/server.d.ts +4 -4
- package/dest/server.d.ts.map +1 -1
- package/dest/server.js +3 -5
- package/dest/test/utils.d.ts +3 -2
- package/dest/test/utils.d.ts.map +1 -1
- package/dest/test/utils.js +9 -7
- package/package.json +19 -21
- package/src/client.ts +4 -0
- package/src/{public → common}/db_interfaces.ts +8 -40
- package/src/common/debug_fn_name.ts +4 -2
- package/src/common/errors.ts +5 -5
- package/src/common/index.ts +2 -1
- package/src/common/message_load_oracle_inputs.ts +2 -2
- package/src/common/stats/index.ts +1 -0
- package/src/{stats → common/stats}/stats.ts +2 -2
- package/src/{acvm → private/acvm}/acvm.ts +5 -5
- package/src/{acvm → private/acvm}/acvm_types.ts +1 -1
- package/src/{acvm → private/acvm}/deserialize.ts +2 -2
- package/src/{acvm → private/acvm}/oracle/index.ts +1 -1
- package/src/{acvm → private/acvm}/oracle/oracle.ts +22 -12
- package/src/{acvm → private/acvm}/oracle/typed_oracle.ts +50 -55
- package/src/{acvm → private/acvm}/serialize.ts +10 -3
- package/src/{client → private}/client_execution_context.ts +54 -37
- package/src/{client → private}/db_oracle.ts +20 -20
- package/src/{client → private}/execution_note_cache.ts +3 -3
- package/src/{common → private}/hashed_values_cache.ts +2 -2
- package/src/private/index.ts +12 -0
- package/src/{client → private}/pick_notes.ts +1 -1
- package/src/{client → private}/private_execution.ts +46 -14
- package/src/{providers → private/providers}/acvm_native.ts +6 -6
- package/src/{providers → private/providers}/acvm_wasm.ts +4 -4
- package/src/{providers → private/providers}/acvm_wasm_with_blobs.ts +5 -5
- package/src/{providers → private/providers}/factory.ts +1 -1
- package/src/{common → private/providers}/simulation_provider.ts +5 -5
- package/src/{client → private}/simulator.ts +31 -123
- package/src/{client → private}/unconstrained_execution.ts +7 -7
- package/src/{client → private}/view_data_oracle.ts +25 -28
- package/src/{avm → public/avm}/avm_context.ts +12 -7
- package/src/{avm → public/avm}/avm_contract_call_result.ts +6 -6
- package/src/{avm → public/avm}/avm_execution_environment.ts +2 -2
- package/src/{avm → public/avm}/avm_gas.ts +1 -3
- package/src/{avm → public/avm}/avm_machine_state.ts +2 -2
- package/src/{avm → public/avm}/avm_memory_types.ts +4 -4
- package/src/{avm → public/avm}/avm_simulator.ts +12 -6
- package/src/{avm → public/avm}/errors.ts +5 -4
- package/src/{avm → public/avm}/fixtures/avm_simulation_tester.ts +16 -15
- package/src/{avm → public/avm}/fixtures/base_avm_simulation_tester.ts +45 -40
- package/src/{avm → public/avm}/fixtures/index.ts +77 -12
- package/src/{avm → public/avm}/fixtures/simple_contract_data_source.ts +26 -19
- package/src/{avm → public/avm}/index.ts +1 -1
- package/src/public/avm/journal/index.ts +1 -0
- package/src/{avm → public/avm}/journal/journal.ts +330 -305
- package/src/{avm → public/avm}/journal/nullifiers.ts +20 -19
- package/src/{avm → public/avm}/journal/public_storage.ts +2 -2
- package/src/{avm → public/avm}/opcodes/contract.ts +1 -1
- package/src/{avm → public/avm}/opcodes/control_flow.ts +1 -1
- package/src/{avm → public/avm}/opcodes/conversion.ts +1 -1
- package/src/{avm → public/avm}/opcodes/ec_add.ts +2 -2
- package/src/{avm → public/avm}/opcodes/external_calls.ts +5 -6
- package/src/{avm → public/avm}/opcodes/hashing.ts +1 -1
- package/src/public/avm/opcodes/index.ts +15 -0
- package/src/{avm → public/avm}/opcodes/instruction.ts +2 -2
- package/src/{avm → public/avm}/opcodes/misc.ts +1 -1
- package/src/public/avm/serialization/bytecode_serialization.ts +204 -0
- package/src/{avm → public/avm}/serialization/instruction_serialization.ts +0 -1
- package/src/{avm → public/avm}/test_utils.ts +10 -7
- package/src/public/execution.ts +9 -12
- package/src/public/fixtures/public_tx_simulation_tester.ts +66 -72
- package/src/public/fixtures/utils.ts +122 -33
- package/src/public/index.ts +5 -4
- package/src/public/public_db_sources.ts +216 -222
- package/src/public/{public_processor.ts → public_processor/public_processor.ts} +78 -53
- package/src/public/{public_processor_metrics.ts → public_processor/public_processor_metrics.ts} +3 -3
- package/src/public/{public_tx_context.ts → public_tx_simulator/public_tx_context.ts} +70 -75
- package/src/public/{public_tx_simulator.ts → public_tx_simulator/public_tx_simulator.ts} +104 -91
- package/src/public/side_effect_trace.ts +85 -160
- package/src/public/side_effect_trace_interface.ts +10 -23
- package/src/public/tx_contract_cache.ts +69 -0
- package/src/public/unique_class_ids.ts +1 -1
- package/src/public/utils.ts +2 -2
- package/src/server.ts +4 -4
- package/src/test/utils.ts +5 -3
- package/dest/acvm/acvm.d.ts.map +0 -1
- package/dest/acvm/acvm.js +0 -73
- package/dest/acvm/acvm_types.d.ts.map +0 -1
- package/dest/acvm/acvm_types.js +0 -2
- package/dest/acvm/deserialize.d.ts.map +0 -1
- package/dest/acvm/deserialize.js +0 -46
- package/dest/acvm/index.d.ts.map +0 -1
- package/dest/acvm/index.js +0 -6
- package/dest/acvm/oracle/index.d.ts.map +0 -1
- package/dest/acvm/oracle/index.js +0 -3
- package/dest/acvm/oracle/oracle.d.ts.map +0 -1
- package/dest/acvm/oracle/oracle.js +0 -230
- package/dest/acvm/oracle/typed_oracle.d.ts.map +0 -1
- package/dest/acvm/oracle/typed_oracle.js +0 -131
- package/dest/acvm/serialize.d.ts.map +0 -1
- package/dest/acvm/serialize.js +0 -48
- package/dest/avm/avm_context.d.ts.map +0 -1
- package/dest/avm/avm_context.js +0 -44
- package/dest/avm/avm_contract_call_result.d.ts.map +0 -1
- package/dest/avm/avm_contract_call_result.js +0 -45
- package/dest/avm/avm_execution_environment.d.ts.map +0 -1
- package/dest/avm/avm_execution_environment.js +0 -28
- package/dest/avm/avm_gas.d.ts.map +0 -1
- package/dest/avm/avm_gas.js +0 -170
- package/dest/avm/avm_machine_state.d.ts.map +0 -1
- package/dest/avm/avm_machine_state.js +0 -112
- package/dest/avm/avm_memory_types.d.ts.map +0 -1
- package/dest/avm/avm_memory_types.js +0 -327
- package/dest/avm/avm_simulator.d.ts.map +0 -1
- package/dest/avm/avm_simulator.js +0 -193
- package/dest/avm/avm_tree.d.ts +0 -282
- package/dest/avm/avm_tree.d.ts.map +0 -1
- package/dest/avm/avm_tree.js +0 -684
- package/dest/avm/bytecode_utils.d.ts.map +0 -1
- package/dest/avm/bytecode_utils.js +0 -15
- package/dest/avm/errors.d.ts.map +0 -1
- package/dest/avm/errors.js +0 -196
- package/dest/avm/fixtures/avm_simulation_tester.d.ts.map +0 -1
- package/dest/avm/fixtures/avm_simulation_tester.js +0 -73
- package/dest/avm/fixtures/base_avm_simulation_tester.d.ts.map +0 -1
- package/dest/avm/fixtures/base_avm_simulation_tester.js +0 -76
- package/dest/avm/fixtures/index.d.ts.map +0 -1
- package/dest/avm/fixtures/index.js +0 -134
- package/dest/avm/fixtures/simple_contract_data_source.d.ts.map +0 -1
- package/dest/avm/fixtures/simple_contract_data_source.js +0 -75
- package/dest/avm/index.d.ts.map +0 -1
- package/dest/avm/index.js +0 -4
- package/dest/avm/journal/index.d.ts.map +0 -1
- package/dest/avm/journal/index.js +0 -2
- package/dest/avm/journal/journal.d.ts.map +0 -1
- package/dest/avm/journal/journal.js +0 -499
- package/dest/avm/journal/nullifiers.d.ts.map +0 -1
- package/dest/avm/journal/nullifiers.js +0 -99
- package/dest/avm/journal/public_storage.d.ts.map +0 -1
- package/dest/avm/journal/public_storage.js +0 -159
- package/dest/avm/opcodes/accrued_substate.d.ts.map +0 -1
- package/dest/avm/opcodes/accrued_substate.js +0 -215
- package/dest/avm/opcodes/addressing_mode.d.ts.map +0 -1
- package/dest/avm/opcodes/addressing_mode.js +0 -81
- package/dest/avm/opcodes/arithmetic.d.ts.map +0 -1
- package/dest/avm/opcodes/arithmetic.js +0 -70
- package/dest/avm/opcodes/bitwise.d.ts.map +0 -1
- package/dest/avm/opcodes/bitwise.js +0 -90
- package/dest/avm/opcodes/comparators.d.ts.map +0 -1
- package/dest/avm/opcodes/comparators.js +0 -40
- package/dest/avm/opcodes/contract.d.ts.map +0 -1
- package/dest/avm/opcodes/contract.js +0 -63
- package/dest/avm/opcodes/control_flow.d.ts.map +0 -1
- package/dest/avm/opcodes/control_flow.js +0 -97
- package/dest/avm/opcodes/conversion.d.ts.map +0 -1
- package/dest/avm/opcodes/conversion.js +0 -64
- package/dest/avm/opcodes/ec_add.d.ts.map +0 -1
- package/dest/avm/opcodes/ec_add.js +0 -82
- package/dest/avm/opcodes/environment_getters.d.ts.map +0 -1
- package/dest/avm/opcodes/environment_getters.js +0 -78
- package/dest/avm/opcodes/external_calls.d.ts.map +0 -1
- package/dest/avm/opcodes/external_calls.js +0 -169
- package/dest/avm/opcodes/hashing.d.ts.map +0 -1
- package/dest/avm/opcodes/hashing.js +0 -103
- package/dest/avm/opcodes/index.d.ts.map +0 -1
- package/dest/avm/opcodes/index.js +0 -16
- package/dest/avm/opcodes/instruction.d.ts.map +0 -1
- package/dest/avm/opcodes/instruction.js +0 -100
- package/dest/avm/opcodes/instruction_impl.d.ts.map +0 -1
- package/dest/avm/opcodes/instruction_impl.js +0 -33
- package/dest/avm/opcodes/memory.d.ts.map +0 -1
- package/dest/avm/opcodes/memory.js +0 -226
- package/dest/avm/opcodes/misc.d.ts.map +0 -1
- package/dest/avm/opcodes/misc.js +0 -45
- package/dest/avm/opcodes/multi_scalar_mul.d.ts +0 -16
- package/dest/avm/opcodes/multi_scalar_mul.d.ts.map +0 -1
- package/dest/avm/opcodes/multi_scalar_mul.js +0 -112
- package/dest/avm/opcodes/storage.d.ts.map +0 -1
- package/dest/avm/opcodes/storage.js +0 -61
- package/dest/avm/serialization/buffer_cursor.d.ts.map +0 -1
- package/dest/avm/serialization/buffer_cursor.js +0 -99
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +0 -1
- package/dest/avm/serialization/bytecode_serialization.js +0 -132
- package/dest/avm/serialization/instruction_serialization.d.ts.map +0 -1
- package/dest/avm/serialization/instruction_serialization.js +0 -187
- package/dest/avm/test_utils.d.ts.map +0 -1
- package/dest/avm/test_utils.js +0 -52
- package/dest/client/client_execution_context.d.ts.map +0 -1
- package/dest/client/client_execution_context.js +0 -392
- package/dest/client/db_oracle.d.ts.map +0 -1
- package/dest/client/db_oracle.js +0 -17
- package/dest/client/execution_note_cache.d.ts.map +0 -1
- package/dest/client/execution_note_cache.js +0 -181
- package/dest/client/index.d.ts +0 -16
- package/dest/client/index.d.ts.map +0 -1
- package/dest/client/index.js +0 -15
- package/dest/client/pick_notes.d.ts.map +0 -1
- package/dest/client/pick_notes.js +0 -54
- package/dest/client/private_execution.d.ts +0 -19
- package/dest/client/private_execution.d.ts.map +0 -1
- package/dest/client/private_execution.js +0 -72
- package/dest/client/simulator.d.ts +0 -60
- package/dest/client/simulator.d.ts.map +0 -1
- package/dest/client/simulator.js +0 -136
- package/dest/client/unconstrained_execution.d.ts.map +0 -1
- package/dest/client/unconstrained_execution.js +0 -30
- package/dest/client/view_data_oracle.d.ts.map +0 -1
- package/dest/client/view_data_oracle.js +0 -268
- package/dest/common/hashed_values_cache.d.ts.map +0 -1
- package/dest/common/hashed_values_cache.js +0 -50
- package/dest/common/simulation_provider.d.ts.map +0 -1
- package/dest/common/simulation_provider.js +0 -27
- package/dest/common.d.ts +0 -2
- package/dest/common.d.ts.map +0 -1
- package/dest/common.js +0 -2
- package/dest/providers/acvm_native.d.ts.map +0 -1
- package/dest/providers/acvm_native.js +0 -125
- package/dest/providers/acvm_wasm.d.ts.map +0 -1
- package/dest/providers/acvm_wasm.js +0 -54
- package/dest/providers/acvm_wasm_with_blobs.d.ts.map +0 -1
- package/dest/providers/factory.d.ts.map +0 -1
- package/dest/providers/factory.js +0 -27
- package/dest/providers/index.d.ts +0 -5
- package/dest/providers/index.d.ts.map +0 -1
- package/dest/providers/index.js +0 -5
- package/dest/public/db_interfaces.d.ts.map +0 -1
- package/dest/public/db_interfaces.js +0 -2
- package/dest/public/fee_payment.d.ts +0 -11
- package/dest/public/fee_payment.d.ts.map +0 -1
- package/dest/public/fee_payment.js +0 -21
- package/dest/public/public_processor.d.ts.map +0 -1
- package/dest/public/public_processor.js +0 -352
- package/dest/public/public_processor_metrics.d.ts.map +0 -1
- package/dest/public/public_processor_metrics.js +0 -106
- package/dest/public/public_tx_context.d.ts.map +0 -1
- package/dest/public/public_tx_context.js +0 -341
- package/dest/public/public_tx_simulator.d.ts.map +0 -1
- package/dest/public/public_tx_simulator.js +0 -333
- package/dest/stats/index.d.ts.map +0 -1
- package/dest/stats/index.js +0 -2
- package/dest/stats/stats.d.ts.map +0 -1
- package/dest/stats/stats.js +0 -11
- package/src/avm/avm_tree.ts +0 -887
- package/src/avm/opcodes/multi_scalar_mul.ts +0 -121
- package/src/avm/serialization/bytecode_serialization.ts +0 -212
- package/src/client/index.ts +0 -15
- package/src/common.ts +0 -1
- package/src/providers/index.ts +0 -4
- package/src/public/fee_payment.ts +0 -23
- /package/dest/{stats → common/stats}/index.d.ts +0 -0
- /package/{src/stats/index.ts → dest/common/stats/index.js} +0 -0
- /package/dest/{acvm → private/acvm}/index.d.ts +0 -0
- /package/dest/{avm → public/avm}/avm_gas.d.ts +0 -0
- /package/dest/{avm → public/avm}/bytecode_utils.d.ts +0 -0
- /package/dest/{avm → public/avm}/journal/index.d.ts +0 -0
- /package/{src/avm/journal/index.ts → dest/public/avm/journal/index.js} +0 -0
- /package/dest/{avm → public/avm}/opcodes/accrued_substate.d.ts +0 -0
- /package/dest/{avm → public/avm}/opcodes/addressing_mode.d.ts +0 -0
- /package/dest/{avm → public/avm}/opcodes/arithmetic.d.ts +0 -0
- /package/dest/{avm → public/avm}/opcodes/bitwise.d.ts +0 -0
- /package/dest/{avm → public/avm}/opcodes/comparators.d.ts +0 -0
- /package/dest/{avm → public/avm}/opcodes/contract.d.ts +0 -0
- /package/dest/{avm → public/avm}/opcodes/control_flow.d.ts +0 -0
- /package/dest/{avm → public/avm}/opcodes/environment_getters.d.ts +0 -0
- /package/dest/{avm → public/avm}/opcodes/external_calls.d.ts +0 -0
- /package/dest/{avm → public/avm}/opcodes/index.d.ts +0 -0
- /package/{src/avm/opcodes/index.ts → dest/public/avm/opcodes/index.js} +0 -0
- /package/dest/{avm → public/avm}/opcodes/instruction_impl.d.ts +0 -0
- /package/dest/{avm → public/avm}/opcodes/memory.d.ts +0 -0
- /package/dest/{avm → public/avm}/opcodes/storage.d.ts +0 -0
- /package/dest/{avm → public/avm}/serialization/buffer_cursor.d.ts +0 -0
- /package/src/{acvm → private/acvm}/index.ts +0 -0
- /package/src/{avm → public/avm}/bytecode_utils.ts +0 -0
- /package/src/{avm → public/avm}/opcodes/.eslintrc.cjs +0 -0
- /package/src/{avm → public/avm}/opcodes/accrued_substate.ts +0 -0
- /package/src/{avm → public/avm}/opcodes/addressing_mode.ts +0 -0
- /package/src/{avm → public/avm}/opcodes/arithmetic.ts +0 -0
- /package/src/{avm → public/avm}/opcodes/bitwise.ts +0 -0
- /package/src/{avm → public/avm}/opcodes/comparators.ts +0 -0
- /package/src/{avm → public/avm}/opcodes/environment_getters.ts +0 -0
- /package/src/{avm → public/avm}/opcodes/instruction_impl.ts +0 -0
- /package/src/{avm → public/avm}/opcodes/memory.ts +0 -0
- /package/src/{avm → public/avm}/opcodes/storage.ts +0 -0
- /package/src/{avm → public/avm}/serialization/buffer_cursor.ts +0 -0
package/dest/avm/avm_tree.js
DELETED
|
@@ -1,684 +0,0 @@
|
|
|
1
|
-
import { MerkleTreeId } from '@aztec/circuit-types';
|
|
2
|
-
import { AppendOnlyTreeSnapshot, NullifierLeafPreimage, PublicDataTreeLeafPreimage } from '@aztec/circuits.js';
|
|
3
|
-
import { poseidon2Hash } from '@aztec/foundation/crypto';
|
|
4
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
5
|
-
import { strict as assert } from 'assert';
|
|
6
|
-
import cloneDeep from 'lodash.clonedeep';
|
|
7
|
-
const MAX_TREE_DEPTH = 128;
|
|
8
|
-
/**
|
|
9
|
-
* Helper function to precompute zero hashes
|
|
10
|
-
*/
|
|
11
|
-
async function preComputeZeroHashes() {
|
|
12
|
-
let currentHash = Fr.zero();
|
|
13
|
-
const zeroHashes = [];
|
|
14
|
-
for (let i = 0; i < MAX_TREE_DEPTH; i++) {
|
|
15
|
-
zeroHashes.push(currentHash);
|
|
16
|
-
currentHash = await poseidon2Hash([currentHash, currentHash]);
|
|
17
|
-
}
|
|
18
|
-
return zeroHashes;
|
|
19
|
-
}
|
|
20
|
-
/****************************************************/
|
|
21
|
-
/****** The AvmEphemeralForest Class ****************/
|
|
22
|
-
/****************************************************/
|
|
23
|
-
/**
|
|
24
|
-
* This provides a forkable abstraction over the EphemeralAvmTree class
|
|
25
|
-
* It contains the logic to look up into a read-only MerkleTreeDb to discover
|
|
26
|
-
* the sibling paths and low witnesses that weren't inserted as part of this tx
|
|
27
|
-
*/
|
|
28
|
-
export class AvmEphemeralForest {
|
|
29
|
-
constructor(treeDb, treeMap,
|
|
30
|
-
// This contains the [leaf index,indexed leaf preimages] tuple that were updated or inserted in the ephemeral tree
|
|
31
|
-
// This is needed since we have a sparse collection of keys sorted leaves in the ephemeral tree
|
|
32
|
-
indexedUpdates, indexedSortedKeys) {
|
|
33
|
-
this.treeDb = treeDb;
|
|
34
|
-
this.treeMap = treeMap;
|
|
35
|
-
this.indexedUpdates = indexedUpdates;
|
|
36
|
-
this.indexedSortedKeys = indexedSortedKeys;
|
|
37
|
-
}
|
|
38
|
-
static async create(treeDb) {
|
|
39
|
-
const treeMap = new Map();
|
|
40
|
-
for (const treeType of [MerkleTreeId.NULLIFIER_TREE, MerkleTreeId.NOTE_HASH_TREE, MerkleTreeId.PUBLIC_DATA_TREE]) {
|
|
41
|
-
const treeInfo = await treeDb.getTreeInfo(treeType);
|
|
42
|
-
const tree = await EphemeralAvmTree.create(treeInfo.size, treeInfo.depth, treeDb, treeType);
|
|
43
|
-
treeMap.set(treeType, tree);
|
|
44
|
-
}
|
|
45
|
-
const indexedSortedKeys = new Map();
|
|
46
|
-
indexedSortedKeys.set(MerkleTreeId.NULLIFIER_TREE, []);
|
|
47
|
-
indexedSortedKeys.set(MerkleTreeId.PUBLIC_DATA_TREE, []);
|
|
48
|
-
return new AvmEphemeralForest(treeDb, treeMap, new Map(), indexedSortedKeys);
|
|
49
|
-
}
|
|
50
|
-
fork() {
|
|
51
|
-
return new AvmEphemeralForest(this.treeDb, cloneDeep(this.treeMap), cloneDeep(this.indexedUpdates), cloneDeep(this.indexedSortedKeys));
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Gets sibling path for a leaf - if the sibling path is not found in the tree, it is fetched from the DB
|
|
55
|
-
* @param treeId - The tree to be queried for a sibling path.
|
|
56
|
-
* @param index - The index of the leaf for which a sibling path should be returned.
|
|
57
|
-
* @returns The sibling path of the leaf.
|
|
58
|
-
*/
|
|
59
|
-
async getSiblingPath(treeId, index) {
|
|
60
|
-
const tree = this.treeMap.get(treeId);
|
|
61
|
-
let path = await tree.getSiblingPath(index);
|
|
62
|
-
if (path === undefined) {
|
|
63
|
-
// We dont have the sibling path in our tree - we have to get it from the DB
|
|
64
|
-
path = (await this.treeDb.getSiblingPath(treeId, index)).toFields();
|
|
65
|
-
// Since the sibling path could be outdated, we compare it with nodes in our tree
|
|
66
|
-
// if we encounter a mismatch, we replace it with the node we found in our tree.
|
|
67
|
-
for (let i = 0; i < path.length; i++) {
|
|
68
|
-
const siblingIndex = index ^ 1n;
|
|
69
|
-
const node = tree.getNode(siblingIndex, tree.depth - i);
|
|
70
|
-
if (node !== undefined) {
|
|
71
|
-
const nodeHash = await tree.hashTree(node, i + 1);
|
|
72
|
-
if (!nodeHash.equals(path[i])) {
|
|
73
|
-
path[i] = nodeHash;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
index >>= 1n;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return path;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* This does the work of appending the new leaf and updating the low witness
|
|
83
|
-
* @param treeId - The tree to be queried for a sibling path.
|
|
84
|
-
* @param lowWitnessIndex - The index of the low leaf in the tree.
|
|
85
|
-
* @param lowWitness - The preimage of the low leaf.
|
|
86
|
-
* @param newLeafPreimage - The preimage of the new leaf to be inserted.
|
|
87
|
-
* @returns The sibling path of the new leaf (i.e. the insertion path)
|
|
88
|
-
*/
|
|
89
|
-
async appendIndexedTree(treeId, lowLeafIndex, lowLeafPreimage, newLeafPreimage) {
|
|
90
|
-
const tree = this.treeMap.get(treeId);
|
|
91
|
-
const newLeaf = await this.hashPreimage(newLeafPreimage);
|
|
92
|
-
const insertIndex = tree.leafCount;
|
|
93
|
-
const lowLeaf = await this.hashPreimage(lowLeafPreimage);
|
|
94
|
-
// Update the low nullifier hash
|
|
95
|
-
this.setIndexedUpdates(treeId, lowLeafIndex, lowLeafPreimage);
|
|
96
|
-
tree.updateLeaf(lowLeaf, lowLeafIndex);
|
|
97
|
-
// Append the new leaf
|
|
98
|
-
tree.appendLeaf(newLeaf);
|
|
99
|
-
this.setIndexedUpdates(treeId, insertIndex, newLeafPreimage);
|
|
100
|
-
return (await tree.getSiblingPath(insertIndex));
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* This writes or updates a slot in the public data tree with a value
|
|
104
|
-
* @param slot - The slot to be written to.
|
|
105
|
-
* @param newValue - The value to be written or updated to
|
|
106
|
-
* @returns The insertion result which contains the insertion path, low leaf and the new leaf index
|
|
107
|
-
*/
|
|
108
|
-
async writePublicStorage(slot, newValue) {
|
|
109
|
-
// This only works for the public data tree
|
|
110
|
-
const treeId = MerkleTreeId.PUBLIC_DATA_TREE;
|
|
111
|
-
const tree = this.treeMap.get(treeId);
|
|
112
|
-
const [leafOrLowLeafInfo, pathAbsentInEphemeralTree] = await this._getLeafOrLowLeafInfo(treeId, slot);
|
|
113
|
-
const { preimage, index: lowLeafIndex, alreadyPresent: update } = leafOrLowLeafInfo;
|
|
114
|
-
const siblingPath = await this.getSiblingPath(treeId, lowLeafIndex);
|
|
115
|
-
if (pathAbsentInEphemeralTree) {
|
|
116
|
-
// Since we have never seen this before - we should insert it into our tree as it is about to be updated.
|
|
117
|
-
this.treeMap.get(treeId).insertSiblingPath(lowLeafIndex, siblingPath);
|
|
118
|
-
}
|
|
119
|
-
if (update) {
|
|
120
|
-
const updatedPreimage = cloneDeep(preimage);
|
|
121
|
-
const existingPublicDataSiblingPath = siblingPath;
|
|
122
|
-
updatedPreimage.value = newValue;
|
|
123
|
-
tree.updateLeaf(await this.hashPreimage(updatedPreimage), lowLeafIndex);
|
|
124
|
-
this.setIndexedUpdates(treeId, lowLeafIndex, updatedPreimage);
|
|
125
|
-
this._updateSortedKeys(treeId, [updatedPreimage.slot], [lowLeafIndex]);
|
|
126
|
-
return {
|
|
127
|
-
element: updatedPreimage,
|
|
128
|
-
lowWitness: {
|
|
129
|
-
preimage: preimage,
|
|
130
|
-
index: lowLeafIndex,
|
|
131
|
-
siblingPath: existingPublicDataSiblingPath,
|
|
132
|
-
},
|
|
133
|
-
update: true,
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
// We are writing to a new slot, so our preimage is a lowNullifier
|
|
137
|
-
const insertionIndex = tree.leafCount;
|
|
138
|
-
const updatedLowLeaf = cloneDeep(preimage);
|
|
139
|
-
updatedLowLeaf.nextSlot = slot;
|
|
140
|
-
updatedLowLeaf.nextIndex = insertionIndex;
|
|
141
|
-
const newPublicDataLeaf = new PublicDataTreeLeafPreimage(slot, newValue, new Fr(preimage.getNextKey()), preimage.getNextIndex());
|
|
142
|
-
const insertionPath = await this.appendIndexedTree(treeId, lowLeafIndex, updatedLowLeaf, newPublicDataLeaf);
|
|
143
|
-
// Even though the low leaf key is not updated, we still need to update the sorted keys in case we have
|
|
144
|
-
// not seen the low leaf before
|
|
145
|
-
this._updateSortedKeys(treeId, [newPublicDataLeaf.slot, updatedLowLeaf.slot], [insertionIndex, lowLeafIndex]);
|
|
146
|
-
return {
|
|
147
|
-
element: newPublicDataLeaf,
|
|
148
|
-
lowWitness: {
|
|
149
|
-
preimage,
|
|
150
|
-
index: lowLeafIndex,
|
|
151
|
-
siblingPath,
|
|
152
|
-
},
|
|
153
|
-
update: false,
|
|
154
|
-
leafIndex: insertionIndex,
|
|
155
|
-
insertionPath: insertionPath,
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
_updateSortedKeys(treeId, keys, index) {
|
|
159
|
-
// This is a reference
|
|
160
|
-
const existingKeyVector = this.indexedSortedKeys.get(treeId);
|
|
161
|
-
// Should already be sorted so not need to re-sort if we just update or splice
|
|
162
|
-
for (let i = 0; i < keys.length; i++) {
|
|
163
|
-
const foundIndex = existingKeyVector.findIndex(x => x[1] === index[i]);
|
|
164
|
-
if (foundIndex === -1) {
|
|
165
|
-
// New element, we splice it into the correct location
|
|
166
|
-
const spliceIndex = indexOrNextLowestInArray(keys[i], existingKeyVector.map(x => x[0])) + 1;
|
|
167
|
-
existingKeyVector.splice(spliceIndex, 0, [keys[i], index[i]]);
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
// Update the existing element
|
|
171
|
-
existingKeyVector[foundIndex][0] = keys[i];
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* This appends a nullifier to the nullifier tree, and throws if the nullifier already exists
|
|
177
|
-
* @param value - The nullifier to be appended
|
|
178
|
-
* @returns The insertion result which contains the insertion path, low leaf and the new leaf index
|
|
179
|
-
*/
|
|
180
|
-
async appendNullifier(nullifier) {
|
|
181
|
-
const treeId = MerkleTreeId.NULLIFIER_TREE;
|
|
182
|
-
const tree = this.treeMap.get(treeId);
|
|
183
|
-
const [leafOrLowLeafInfo, pathAbsentInEphemeralTree] = await this._getLeafOrLowLeafInfo(treeId, nullifier);
|
|
184
|
-
const { preimage, index, alreadyPresent } = leafOrLowLeafInfo;
|
|
185
|
-
const siblingPath = await this.getSiblingPath(treeId, index);
|
|
186
|
-
if (pathAbsentInEphemeralTree) {
|
|
187
|
-
// Since we have never seen this before - we should insert it into our tree as it is about to be updated.
|
|
188
|
-
this.treeMap.get(treeId).insertSiblingPath(index, siblingPath);
|
|
189
|
-
}
|
|
190
|
-
assert(!alreadyPresent, 'Nullifier already exists in the tree. Cannot update a nullifier!');
|
|
191
|
-
// We are writing a new entry
|
|
192
|
-
const insertionIndex = tree.leafCount;
|
|
193
|
-
const updatedLowNullifier = cloneDeep(preimage);
|
|
194
|
-
updatedLowNullifier.nextNullifier = nullifier;
|
|
195
|
-
updatedLowNullifier.nextIndex = insertionIndex;
|
|
196
|
-
const newNullifierLeaf = new NullifierLeafPreimage(nullifier, preimage.nextNullifier, preimage.nextIndex);
|
|
197
|
-
const insertionPath = await this.appendIndexedTree(treeId, index, updatedLowNullifier, newNullifierLeaf);
|
|
198
|
-
// Even though the low nullifier key is not updated, we still need to update the sorted keys in case we have
|
|
199
|
-
// not seen the low nullifier before
|
|
200
|
-
this._updateSortedKeys(treeId, [newNullifierLeaf.nullifier, updatedLowNullifier.nullifier], [insertionIndex, index]);
|
|
201
|
-
return {
|
|
202
|
-
element: newNullifierLeaf,
|
|
203
|
-
lowWitness: {
|
|
204
|
-
preimage,
|
|
205
|
-
index,
|
|
206
|
-
siblingPath,
|
|
207
|
-
},
|
|
208
|
-
leafIndex: insertionIndex,
|
|
209
|
-
insertionPath: insertionPath,
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* This appends a note hash to the note hash tree
|
|
214
|
-
* @param value - The note hash to be appended
|
|
215
|
-
* @returns The insertion result which contains the insertion path
|
|
216
|
-
*/
|
|
217
|
-
async appendNoteHash(noteHash) {
|
|
218
|
-
const tree = this.treeMap.get(MerkleTreeId.NOTE_HASH_TREE);
|
|
219
|
-
tree.appendLeaf(noteHash);
|
|
220
|
-
// We use leafCount - 1 here because we would have just appended a leaf
|
|
221
|
-
const insertionPath = await tree.getSiblingPath(tree.leafCount - 1n);
|
|
222
|
-
return insertionPath;
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* This is wrapper around treeId to set values in the indexedUpdates map
|
|
226
|
-
*/
|
|
227
|
-
setIndexedUpdates(treeId, index, preimage) {
|
|
228
|
-
let updates = this.indexedUpdates.get(treeId);
|
|
229
|
-
if (updates === undefined) {
|
|
230
|
-
updates = new Map();
|
|
231
|
-
this.indexedUpdates.set(treeId, updates);
|
|
232
|
-
}
|
|
233
|
-
updates.set(index, preimage);
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* This is wrapper around treeId to get values in the indexedUpdates map.
|
|
237
|
-
* Should only be called if we know the value exists.
|
|
238
|
-
*/
|
|
239
|
-
getIndexedUpdate(treeId, index) {
|
|
240
|
-
const updates = this.indexedUpdates.get(treeId);
|
|
241
|
-
assert(updates !== undefined, `No updates exist in the ephemeral ${MerkleTreeId[treeId]} tree.`);
|
|
242
|
-
const preimage = updates.get(index);
|
|
243
|
-
assert(updates !== undefined, `No update exists in the ephemeral ${MerkleTreeId[treeId]} tree for leafIndex ${index}.`);
|
|
244
|
-
return preimage;
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* This is wrapper around treeId to check membership (i.e. has()) of index in the indexedUpdates map
|
|
248
|
-
*/
|
|
249
|
-
hasLocalUpdates(treeId, index) {
|
|
250
|
-
const updates = this.indexedUpdates.get(treeId);
|
|
251
|
-
if (updates === undefined) {
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
|
-
return updates.has(index);
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Get the leaf or low leaf preimage and its index in the indexed tree given a key (slot or nullifier value).
|
|
258
|
-
* If the key is not found in the tree, it does an external lookup to the underlying merkle DB.
|
|
259
|
-
* @param treeId - The tree we are looking up in
|
|
260
|
-
* @param key - The key for which we are look up the leaf or low leaf for.
|
|
261
|
-
* @param T - The type of the preimage (PublicData or Nullifier)
|
|
262
|
-
* @returns The leaf or low leaf info (preimage & leaf index).
|
|
263
|
-
*/
|
|
264
|
-
async getLeafOrLowLeafInfo(treeId, key) {
|
|
265
|
-
const [leafOrLowLeafInfo, _] = await this._getLeafOrLowLeafInfo(treeId, key);
|
|
266
|
-
return leafOrLowLeafInfo;
|
|
267
|
-
}
|
|
268
|
-
/**
|
|
269
|
-
* Internal helper to get the leaf or low leaf preimage and its index in the indexed tree given a key (slot or nullifier value).
|
|
270
|
-
* If the key is not found in the tree, it does an external lookup to the underlying merkle DB.
|
|
271
|
-
* Indicates whethe the sibling path is absent in the ephemeral tree.
|
|
272
|
-
* @param treeId - The tree we are looking up in
|
|
273
|
-
* @param key - The key for which we are look up the leaf or low leaf for.
|
|
274
|
-
* @param T - The type of the preimage (PublicData or Nullifier)
|
|
275
|
-
* @returns [
|
|
276
|
-
* getLeafResult - The leaf or low leaf info (preimage & leaf index),
|
|
277
|
-
* pathAbsentInEphemeralTree - whether its sibling path is absent in the ephemeral tree (useful during insertions)
|
|
278
|
-
* ]
|
|
279
|
-
*/
|
|
280
|
-
async _getLeafOrLowLeafInfo(treeId, key) {
|
|
281
|
-
const bigIntKey = key.toBigInt();
|
|
282
|
-
// In this function, "min" refers to the leaf with the
|
|
283
|
-
// largest key <= the specified key in the indexedUpdates.
|
|
284
|
-
// In other words, the leaf with the "next lowest" key in indexedUpdates.
|
|
285
|
-
// First, search the indexed updates (no DB fallback) to find
|
|
286
|
-
// the leafIndex of the leaf with the largest key <= the specified key.
|
|
287
|
-
const minIndexedLeafIndex = this._getLeafIndexOrNextLowestInIndexedUpdates(treeId, key);
|
|
288
|
-
// Then we search on the external DB
|
|
289
|
-
const leafOrLowLeafWitnessFromExternalDb = await this._getLeafOrLowLeafWitnessInExternalDb(treeId, bigIntKey);
|
|
290
|
-
// If the indexed updates are empty, we can return the leaf from the DB
|
|
291
|
-
if (minIndexedLeafIndex === -1n) {
|
|
292
|
-
return [leafOrLowLeafWitnessFromExternalDb, /*pathAbsentInEphemeralTree=*/ true];
|
|
293
|
-
}
|
|
294
|
-
// Otherwise, we return the closest one. First fetch the leaf from the indexed updates.
|
|
295
|
-
const minIndexedUpdate = this.getIndexedUpdate(treeId, minIndexedLeafIndex);
|
|
296
|
-
// And get both keys
|
|
297
|
-
const keyFromIndexed = minIndexedUpdate.getKey();
|
|
298
|
-
const keyFromExternal = leafOrLowLeafWitnessFromExternalDb.preimage.getKey();
|
|
299
|
-
if (keyFromExternal > keyFromIndexed) {
|
|
300
|
-
// this.log.debug(`Using leaf from external DB for ${MerkleTreeId[treeId]}`);
|
|
301
|
-
return [leafOrLowLeafWitnessFromExternalDb, /*pathAbsentInEphemeralTree=*/ true];
|
|
302
|
-
}
|
|
303
|
-
else {
|
|
304
|
-
// this.log.debug(`Using leaf from indexed DB for ${MerkleTreeId[treeId]}`);
|
|
305
|
-
const leafInfo = {
|
|
306
|
-
preimage: minIndexedUpdate,
|
|
307
|
-
index: minIndexedLeafIndex,
|
|
308
|
-
alreadyPresent: keyFromIndexed === bigIntKey,
|
|
309
|
-
};
|
|
310
|
-
return [leafInfo, /*pathAbsentInEphemeralTree=*/ false];
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* Helper to search for the leaf with the specified key in the indexedUpdates
|
|
315
|
-
* and return its leafIndex.
|
|
316
|
-
* If not present, return the leafIndex of the largest leaf <= the specified key
|
|
317
|
-
* (the leafIndex of the next lowest key).
|
|
318
|
-
*
|
|
319
|
-
* If no entry exists in indexedUpdates <= the specified key, return -1.
|
|
320
|
-
* @returns - The leafIndex of the leaf with the largest key <= the specified key.
|
|
321
|
-
*/
|
|
322
|
-
_getLeafIndexOrNextLowestInIndexedUpdates(treeId, key) {
|
|
323
|
-
const keyOrderedVector = this.indexedSortedKeys.get(treeId);
|
|
324
|
-
const indexInVector = indexOrNextLowestInArray(key, keyOrderedVector.map(x => x[0]));
|
|
325
|
-
if (indexInVector !== -1) {
|
|
326
|
-
const [_, leafIndex] = keyOrderedVector[indexInVector];
|
|
327
|
-
return leafIndex;
|
|
328
|
-
}
|
|
329
|
-
else {
|
|
330
|
-
// no leaf <= the specified key was found
|
|
331
|
-
return -1n;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
/**
|
|
335
|
-
* Query the external DB to get leaf if present, low leaf if absent
|
|
336
|
-
*/
|
|
337
|
-
async _getLeafOrLowLeafWitnessInExternalDb(treeId, key) {
|
|
338
|
-
// "key" is siloed slot (leafSlot) or siloed nullifier
|
|
339
|
-
const previousValueIndex = await this.treeDb.getPreviousValueIndex(treeId, key);
|
|
340
|
-
assert(previousValueIndex !== undefined, `${MerkleTreeId[treeId]} low leaf index should always be found (even if target leaf does not exist)`);
|
|
341
|
-
const { index: leafIndex, alreadyPresent } = previousValueIndex;
|
|
342
|
-
const leafPreimage = await this.treeDb.getLeafPreimage(treeId, leafIndex);
|
|
343
|
-
assert(leafPreimage !== undefined, `${MerkleTreeId[treeId]} low leaf preimage should never be undefined (even if target leaf does not exist)`);
|
|
344
|
-
return { preimage: leafPreimage, index: leafIndex, alreadyPresent };
|
|
345
|
-
}
|
|
346
|
-
/**
|
|
347
|
-
* This hashes the preimage to a field element
|
|
348
|
-
*/
|
|
349
|
-
hashPreimage(preimage) {
|
|
350
|
-
const input = preimage.toHashInputs().map(x => Fr.fromBuffer(x));
|
|
351
|
-
return poseidon2Hash(input);
|
|
352
|
-
}
|
|
353
|
-
async getTreeSnapshot(id) {
|
|
354
|
-
const tree = this.treeMap.get(id);
|
|
355
|
-
const root = await tree.getRoot();
|
|
356
|
-
return new AppendOnlyTreeSnapshot(root, Number(tree.leafCount));
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
/****************************************************/
|
|
360
|
-
/****** Some useful Structs and Enums **************/
|
|
361
|
-
/****************************************************/
|
|
362
|
-
var TreeType;
|
|
363
|
-
(function (TreeType) {
|
|
364
|
-
TreeType[TreeType["LEAF"] = 0] = "LEAF";
|
|
365
|
-
TreeType[TreeType["NODE"] = 1] = "NODE";
|
|
366
|
-
})(TreeType || (TreeType = {}));
|
|
367
|
-
var SiblingStatus;
|
|
368
|
-
(function (SiblingStatus) {
|
|
369
|
-
SiblingStatus[SiblingStatus["MEMBER"] = 0] = "MEMBER";
|
|
370
|
-
SiblingStatus[SiblingStatus["NONMEMBER"] = 1] = "NONMEMBER";
|
|
371
|
-
SiblingStatus[SiblingStatus["ERROR"] = 2] = "ERROR";
|
|
372
|
-
})(SiblingStatus || (SiblingStatus = {}));
|
|
373
|
-
/****************************************************/
|
|
374
|
-
/****** Some Helpful Constructors for Trees ********/
|
|
375
|
-
/****************************************************/
|
|
376
|
-
const Node = (left, right) => ({
|
|
377
|
-
tag: TreeType.NODE,
|
|
378
|
-
leftTree: left,
|
|
379
|
-
rightTree: right,
|
|
380
|
-
});
|
|
381
|
-
const Leaf = (value) => ({
|
|
382
|
-
tag: TreeType.LEAF,
|
|
383
|
-
value,
|
|
384
|
-
});
|
|
385
|
-
/****************************************************/
|
|
386
|
-
/****** The EphemeralAvmTree Class *****************/
|
|
387
|
-
/****************************************************/
|
|
388
|
-
/**
|
|
389
|
-
* This class contains a recursively defined tree that has leaves at different heights
|
|
390
|
-
* It is seeded by an existing merkle treeDb for which it derives a frontier
|
|
391
|
-
* It is intended to be a lightweight tree that contains only the necessary information to suppport appends or updates
|
|
392
|
-
*/
|
|
393
|
-
export class EphemeralAvmTree {
|
|
394
|
-
constructor(root, leafCount, depth, zeroHashes) {
|
|
395
|
-
this.root = root;
|
|
396
|
-
this.leafCount = leafCount;
|
|
397
|
-
this.depth = depth;
|
|
398
|
-
this.zeroHashes = zeroHashes;
|
|
399
|
-
this.tree = root;
|
|
400
|
-
this.frontier = [];
|
|
401
|
-
}
|
|
402
|
-
static async create(forkedLeafCount, depth, treeDb, merkleId) {
|
|
403
|
-
let zeroHashes = EphemeralAvmTree.precomputedZeroHashes;
|
|
404
|
-
if (zeroHashes === undefined) {
|
|
405
|
-
zeroHashes = await preComputeZeroHashes();
|
|
406
|
-
EphemeralAvmTree.precomputedZeroHashes = zeroHashes;
|
|
407
|
-
}
|
|
408
|
-
const zeroHash = zeroHashes[depth];
|
|
409
|
-
const tree = new EphemeralAvmTree(Leaf(zeroHash), forkedLeafCount, depth, zeroHashes);
|
|
410
|
-
await tree.initializeFrontier(treeDb, merkleId);
|
|
411
|
-
return tree;
|
|
412
|
-
}
|
|
413
|
-
/**
|
|
414
|
-
* This is a recursive function that inserts a leaf into the tree
|
|
415
|
-
* @param value - The value of the leaf to be inserted
|
|
416
|
-
*/
|
|
417
|
-
appendLeaf(value) {
|
|
418
|
-
const insertPath = this._derivePathLE(this.leafCount);
|
|
419
|
-
this.tree = this._insertLeaf(value, insertPath, this.depth, this.tree);
|
|
420
|
-
this.leafCount++;
|
|
421
|
-
}
|
|
422
|
-
/**
|
|
423
|
-
* This is a recursive function that upserts a leaf into the tree at a index and depth
|
|
424
|
-
* @param value - The value of the leaf to be inserted
|
|
425
|
-
* @param index - The index of the leaf to be inserted
|
|
426
|
-
* @param depth - The depth of the leaf to be inserted (defaults to the bottom of the tree)
|
|
427
|
-
*/
|
|
428
|
-
updateLeaf(value, index, depth = this.depth) {
|
|
429
|
-
const insertPath = this._derivePathLE(index, depth);
|
|
430
|
-
this.tree = this._insertLeaf(value, insertPath, depth, this.tree);
|
|
431
|
-
}
|
|
432
|
-
/**
|
|
433
|
-
* Get the sibling path of a leaf in the tree
|
|
434
|
-
* @param index - The index of the leaf for which a sibling path should be returned.
|
|
435
|
-
* @returns The sibling path of the leaf, can fail if the path is not found
|
|
436
|
-
*/
|
|
437
|
-
async getSiblingPath(index) {
|
|
438
|
-
const searchPath = this._derivePathLE(index);
|
|
439
|
-
// Handle cases where we error out
|
|
440
|
-
const { path, status } = await this._getSiblingPath(searchPath, this.tree, []);
|
|
441
|
-
if (status === SiblingStatus.ERROR) {
|
|
442
|
-
return undefined;
|
|
443
|
-
}
|
|
444
|
-
return path;
|
|
445
|
-
}
|
|
446
|
-
/**
|
|
447
|
-
* This upserts the nodes of the sibling path into the tree
|
|
448
|
-
* @param index - The index of the leaf that the sibling path is derived from
|
|
449
|
-
* @param siblingPath - The sibling path of the index
|
|
450
|
-
*/
|
|
451
|
-
insertSiblingPath(index, siblingPath) {
|
|
452
|
-
for (let i = 0; i < siblingPath.length; i++) {
|
|
453
|
-
// Flip(XOR) the last bit because we are inserting siblings of the leaf
|
|
454
|
-
const sibIndex = index ^ 1n;
|
|
455
|
-
const node = this.getNode(sibIndex, this.depth - i);
|
|
456
|
-
// If we are inserting a sibling path and we already have a branch at that index in our
|
|
457
|
-
// ephemeral tree, we should not overwrite it
|
|
458
|
-
if (node === undefined || node.tag === TreeType.LEAF) {
|
|
459
|
-
this.updateLeaf(siblingPath[i], sibIndex, this.depth - i);
|
|
460
|
-
}
|
|
461
|
-
index >>= 1n;
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
/**
|
|
465
|
-
* This is a helper function that computes the index of the frontier nodes at each depth
|
|
466
|
-
* @param leafCount - The number of leaves in the tree
|
|
467
|
-
* @returns An array of frontier indices at each depth, sorted from leaf to root
|
|
468
|
-
*/
|
|
469
|
-
// Do we really need LeafCount to be a bigint - log2 is on numbers only
|
|
470
|
-
static computeFrontierLeafIndices(leafCount) {
|
|
471
|
-
const numFrontierEntries = Math.floor(Math.log2(leafCount)) + 1;
|
|
472
|
-
const frontierIndices = [];
|
|
473
|
-
for (let i = 0; i < numFrontierEntries; i++) {
|
|
474
|
-
if (leafCount === 0) {
|
|
475
|
-
frontierIndices.push(0);
|
|
476
|
-
}
|
|
477
|
-
else if (leafCount % 2 === 0) {
|
|
478
|
-
frontierIndices.push(leafCount - 2);
|
|
479
|
-
}
|
|
480
|
-
else {
|
|
481
|
-
frontierIndices.push(leafCount - 1);
|
|
482
|
-
}
|
|
483
|
-
leafCount >>= 1;
|
|
484
|
-
}
|
|
485
|
-
return frontierIndices;
|
|
486
|
-
}
|
|
487
|
-
/**
|
|
488
|
-
* This derives the frontier and inserts them into the tree
|
|
489
|
-
* @param treeDb - The treeDb to be queried for sibling paths
|
|
490
|
-
* @param merkleId - The treeId of the tree to be queried for sibling paths
|
|
491
|
-
*/
|
|
492
|
-
async initializeFrontier(treeDb, merkleId) {
|
|
493
|
-
// The frontier indices are sorted from the leaf to root
|
|
494
|
-
const frontierIndices = EphemeralAvmTree.computeFrontierLeafIndices(Number(this.leafCount));
|
|
495
|
-
// The frontier indices are level-based - i.e. index N at level L.
|
|
496
|
-
// Since we can only ask the DB for paths from the root to the leaf, we do the following complicated calculations
|
|
497
|
-
// 1) The goal is to insert the frontier node N at level L into the tree.
|
|
498
|
-
// 2) We get the path to a leaf that passes through the frontier node we want (there are multiple paths so we just pick one)
|
|
499
|
-
// 3) We can only get sibling paths from the root to the leaf, so we get the sibling path of the leaf from (2)
|
|
500
|
-
// NOTE: This is terribly inefficient and we should probably change the DB API to allow for getting paths to a node
|
|
501
|
-
const frontierValues = [];
|
|
502
|
-
// These are leaf indexes that pass through the frontier nodes
|
|
503
|
-
for (let i = 0; i < frontierIndices.length; i++) {
|
|
504
|
-
// Given the index to a frontier, we first xor it so we can get its sibling index at depth L
|
|
505
|
-
// We then extend the path to that sibling index by shifting left the requisite number of times (for simplicity we just go left down the tree - it doesnt matter)
|
|
506
|
-
// This provides us the leaf index such that if we ask for this leafIndex's sibling path, it will pass through the frontier node
|
|
507
|
-
const index = BigInt(frontierIndices[i] ^ 1) << BigInt(i);
|
|
508
|
-
// This path passes through our frontier node at depth - i
|
|
509
|
-
const path = await treeDb.getSiblingPath(merkleId, index);
|
|
510
|
-
// We derive the path that we can walk and truncate it so that it terminates exactly at the frontier node
|
|
511
|
-
const frontierPath = this._derivePathLE(BigInt(frontierIndices[i]), this.depth - i);
|
|
512
|
-
// The value of the frontier is the at the i-th index of the sibling path
|
|
513
|
-
const frontierValue = path.toFields()[i];
|
|
514
|
-
frontierValues.push(frontierValue);
|
|
515
|
-
// We insert it at depth - i (the truncated position)
|
|
516
|
-
// Note this is a leaf node that wont necessarily be at the bottom of the tree (besides the first frontier)
|
|
517
|
-
this.tree = this._insertLeaf(frontierValue, frontierPath, this.depth - i, this.tree);
|
|
518
|
-
}
|
|
519
|
-
this.frontier = frontierValues;
|
|
520
|
-
}
|
|
521
|
-
/**
|
|
522
|
-
* Computes the root of the tree
|
|
523
|
-
*/
|
|
524
|
-
getRoot() {
|
|
525
|
-
return this.hashTree(this.tree, this.depth);
|
|
526
|
-
}
|
|
527
|
-
/**
|
|
528
|
-
* Recursively hashes the subtree
|
|
529
|
-
* @param tree - The tree to be hashed
|
|
530
|
-
* @param depth - The depth of the tree
|
|
531
|
-
*/
|
|
532
|
-
async hashTree(tree, depth) {
|
|
533
|
-
switch (tree.tag) {
|
|
534
|
-
case TreeType.NODE: {
|
|
535
|
-
return poseidon2Hash([
|
|
536
|
-
await this.hashTree(tree.leftTree, depth - 1),
|
|
537
|
-
await this.hashTree(tree.rightTree, depth - 1),
|
|
538
|
-
]);
|
|
539
|
-
}
|
|
540
|
-
case TreeType.LEAF: {
|
|
541
|
-
return tree.value;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
/**
|
|
546
|
-
* Extracts the subtree from a given index and depth
|
|
547
|
-
* @param index - The index of the node to be extracted
|
|
548
|
-
* @param depth - The depth of the node to be extracted
|
|
549
|
-
* @returns The subtree rooted at the index and depth
|
|
550
|
-
*/
|
|
551
|
-
getNode(index, depth) {
|
|
552
|
-
const path = this._derivePathBE(index, depth);
|
|
553
|
-
const truncatedPath = path.slice(0, depth);
|
|
554
|
-
truncatedPath.reverse();
|
|
555
|
-
try {
|
|
556
|
-
return this._getNode(truncatedPath, this.tree);
|
|
557
|
-
}
|
|
558
|
-
catch (e) {
|
|
559
|
-
return undefined;
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
/**
|
|
563
|
-
* This is the recursive helper for getNode
|
|
564
|
-
*/
|
|
565
|
-
_getNode(nodePath, tree) {
|
|
566
|
-
if (nodePath.length === 0) {
|
|
567
|
-
return tree;
|
|
568
|
-
}
|
|
569
|
-
switch (tree.tag) {
|
|
570
|
-
case TreeType.NODE:
|
|
571
|
-
return nodePath.pop() === 0 ? this._getNode(nodePath, tree.leftTree) : this._getNode(nodePath, tree.rightTree);
|
|
572
|
-
case TreeType.LEAF:
|
|
573
|
-
throw new Error('Node not found');
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
/** Our tree traversal uses an array of 1s and 0s to represent the path to a leaf and expects them to be in LE order
|
|
577
|
-
* This helps with deriving it given an index and (optionally a depth)
|
|
578
|
-
* @param index - The index to derive a path to within the tree, does not have to terminate at a leaf
|
|
579
|
-
* @param depth - The depth to traverse, if not provided it will traverse to the bottom of the tree
|
|
580
|
-
* @returns The path to the leaf in LE order
|
|
581
|
-
*/
|
|
582
|
-
_derivePathLE(index, depth = this.depth) {
|
|
583
|
-
return this._derivePathBE(index, depth).reverse();
|
|
584
|
-
}
|
|
585
|
-
/** Sometimes we want it in BE order, to make truncating easier
|
|
586
|
-
* @param index - The index to derive a path to within the tree, does not have to terminate at a leaf
|
|
587
|
-
* @param depth - The depth to traverse, if not provided it will traverse to the bottom of the tree
|
|
588
|
-
* @returns The path to the leaf in LE order
|
|
589
|
-
*/
|
|
590
|
-
_derivePathBE(index, depth = this.depth) {
|
|
591
|
-
return index
|
|
592
|
-
.toString(2)
|
|
593
|
-
.padStart(depth, '0')
|
|
594
|
-
.split('')
|
|
595
|
-
.map(x => parseInt(x));
|
|
596
|
-
}
|
|
597
|
-
/**
|
|
598
|
-
* This is a recursive function that upserts a leaf into the tree given a path
|
|
599
|
-
* @param value - The value of the leaf to be upserted
|
|
600
|
-
* @param insertPath - The path to the leaf, this should be ordered from leaf to root (i.e. LE encoded)
|
|
601
|
-
* @param depth - The depth of the tree
|
|
602
|
-
* @param tree - The current tree
|
|
603
|
-
* @param appendMode - If true we append the relevant zeroHashes to the tree as we traverse
|
|
604
|
-
*/
|
|
605
|
-
_insertLeaf(value, insertPath, depth, tree) {
|
|
606
|
-
if (insertPath.length > this.depth || depth > this.depth) {
|
|
607
|
-
throw new Error('PATH EXCEEDS DEPTH');
|
|
608
|
-
}
|
|
609
|
-
if (depth === 0 || insertPath.length === 0) {
|
|
610
|
-
return Leaf(value);
|
|
611
|
-
}
|
|
612
|
-
switch (tree.tag) {
|
|
613
|
-
case TreeType.NODE: {
|
|
614
|
-
return insertPath.pop() === 0
|
|
615
|
-
? Node(this._insertLeaf(value, insertPath, depth - 1, tree.leftTree), tree.rightTree)
|
|
616
|
-
: Node(tree.leftTree, this._insertLeaf(value, insertPath, depth - 1, tree.rightTree));
|
|
617
|
-
}
|
|
618
|
-
case TreeType.LEAF: {
|
|
619
|
-
const zeroLeaf = Leaf(this.zeroHashes[depth - 1]);
|
|
620
|
-
return insertPath.pop() === 0
|
|
621
|
-
? Node(this._insertLeaf(value, insertPath, depth - 1, zeroLeaf), zeroLeaf)
|
|
622
|
-
: Node(zeroLeaf, this._insertLeaf(value, insertPath, depth - 1, zeroLeaf));
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
/* Recursive helper for getSiblingPath, this only looks inside the tree and does not resolve using
|
|
627
|
-
* a DB. If a path is not found, it returns an error status that is expected to be handled by the caller
|
|
628
|
-
* @param searchPath - The path to the leaf for which we would like the sibling pathin LE order
|
|
629
|
-
* @param tree - The current tree
|
|
630
|
-
* @param acc - The accumulated sibling path
|
|
631
|
-
*/
|
|
632
|
-
async _getSiblingPath(searchPath, tree, acc) {
|
|
633
|
-
// If we have reached the end of the path, we should be at a leaf or empty node
|
|
634
|
-
// If it is a leaf, we check if the value is equal to the leaf value
|
|
635
|
-
// If it is empty we check if the value is equal to zero
|
|
636
|
-
if (searchPath.length === 0) {
|
|
637
|
-
switch (tree.tag) {
|
|
638
|
-
case TreeType.LEAF:
|
|
639
|
-
return { path: acc, status: SiblingStatus.MEMBER };
|
|
640
|
-
case TreeType.NODE:
|
|
641
|
-
return { path: [], status: SiblingStatus.ERROR };
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
// Keep exploring here
|
|
645
|
-
switch (tree.tag) {
|
|
646
|
-
case TreeType.NODE: {
|
|
647
|
-
// Look at the next element of the path to decided if we go left or right, note this mutates!
|
|
648
|
-
return searchPath.pop() === 0
|
|
649
|
-
? await this._getSiblingPath(searchPath, tree.leftTree, [await this.hashTree(tree.rightTree, searchPath.length)].concat(acc))
|
|
650
|
-
: await this._getSiblingPath(searchPath, tree.rightTree, [await this.hashTree(tree.leftTree, searchPath.length)].concat(acc));
|
|
651
|
-
}
|
|
652
|
-
// In these two situations we are exploring a subtree we dont have information about
|
|
653
|
-
// We should return an error and look inside the DB
|
|
654
|
-
case TreeType.LEAF:
|
|
655
|
-
return { path: [], status: SiblingStatus.ERROR };
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
/**
|
|
660
|
-
* Return the index of the key in the array, or index-1 if they key is not found.
|
|
661
|
-
*/
|
|
662
|
-
function indexOrNextLowestInArray(key, arr) {
|
|
663
|
-
// We are looking for the index of the largest element in the array that is less than the key
|
|
664
|
-
let start = 0;
|
|
665
|
-
let end = arr.length;
|
|
666
|
-
// Note that the easiest way is to increment the search key by 1 and then do a binary search
|
|
667
|
-
const keyPlus1 = key.add(Fr.ONE);
|
|
668
|
-
while (start < end) {
|
|
669
|
-
const mid = Math.floor((start + end) / 2);
|
|
670
|
-
if (arr[mid].cmp(keyPlus1) < 0) {
|
|
671
|
-
// The key + 1 is greater than the midpoint, so we can continue searching the top half
|
|
672
|
-
start = mid + 1;
|
|
673
|
-
}
|
|
674
|
-
else {
|
|
675
|
-
// The key + 1 is LT or EQ the arr element, so we can continue searching the bottom half
|
|
676
|
-
end = mid;
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
// We either found key + 1 or start is now at the index of the largest element that we would have inserted key + 1
|
|
680
|
-
// Therefore start - 1 is the index of the element just below - note it can be -1 if the first element in the array is
|
|
681
|
-
// greater than the key
|
|
682
|
-
return start - 1;
|
|
683
|
-
}
|
|
684
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXZtX3RyZWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXZtL2F2bV90cmVlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBc0IsWUFBWSxFQUFpQyxNQUFNLHNCQUFzQixDQUFDO0FBQ3ZHLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxxQkFBcUIsRUFBRSwwQkFBMEIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQy9HLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFHOUMsT0FBTyxFQUFFLE1BQU0sSUFBSSxNQUFNLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDMUMsT0FBTyxTQUFTLE1BQU0sa0JBQWtCLENBQUM7QUFFekMsTUFBTSxjQUFjLEdBQUcsR0FBRyxDQUFDO0FBRTNCOztHQUVHO0FBQ0gsS0FBSyxVQUFVLG9CQUFvQjtJQUNqQyxJQUFJLFdBQVcsR0FBRyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDNUIsTUFBTSxVQUFVLEdBQVMsRUFBRSxDQUFDO0lBQzVCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxjQUFjLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUN4QyxVQUFVLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzdCLFdBQVcsR0FBRyxNQUFNLGFBQWEsQ0FBQyxDQUFDLFdBQVcsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFDRCxPQUFPLFVBQVUsQ0FBQztBQUNwQixDQUFDO0FBdURELHNEQUFzRDtBQUN0RCxzREFBc0Q7QUFDdEQsc0RBQXNEO0FBRXREOzs7O0dBSUc7QUFDSCxNQUFNLE9BQU8sa0JBQWtCO0lBQzdCLFlBQ1MsTUFBZ0MsRUFDaEMsT0FBNEM7SUFDbkQsa0hBQWtIO0lBQ2xILCtGQUErRjtJQUN4Rixj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
|