Skip to content

Commit

Permalink
collect_lock_scripts: audit preloaded witness
Browse files Browse the repository at this point in the history
Benchmarks and profiles reveal that this is surprisingly expensive. So
we only do this check at program init. This program loops over
variable-sized elements *without* any range checks, so I consider this
commit essential for soundness.

Cf. #190.
  • Loading branch information
Sword-Smith committed Sep 26, 2024
1 parent 0bf9cc6 commit e959d61
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 28 deletions.
6 changes: 3 additions & 3 deletions benches/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ mod transaction {
);
}

#[divan::bench(sample_count = 1, args = [COMMON])]
#[divan::bench(sample_count = 1, args = [COMMON, LARGEISH])]
fn collect_lock_scripts(args: (usize, usize)) {
let (num_inputs, num_outputs) = args;
let mut test_runner = TestRunner::deterministic();
Expand All @@ -166,7 +166,7 @@ mod transaction {
);
}

#[divan::bench(sample_count = 1, args = [COMMON])]
#[divan::bench(sample_count = 1, args = [COMMON, LARGEISH])]
fn collect_type_scripts(args: (usize, usize)) {
let (num_inputs, num_outputs) = args;
let mut test_runner = TestRunner::deterministic();
Expand All @@ -193,7 +193,7 @@ mod transaction {
);
}

#[divan::bench(sample_count = 1, args = [COMMON])]
#[divan::bench(sample_count = 1, args = [COMMON, LARGEISH])]
fn kernel_to_outputs(args: (usize, usize)) {
let (num_inputs, num_outputs) = args;
let mut test_runner = TestRunner::deterministic();
Expand Down
10 changes: 5 additions & 5 deletions benchmarks/CollectLockScripts-2in-2out.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
{
"name": "CollectLockScripts-2in-2out",
"benchmark_result": {
"clock_cycle_count": 306,
"hash_table_height": 211,
"u32_table_height": 102,
"op_stack_table_height": 249,
"ram_table_height": 62
"clock_cycle_count": 606,
"hash_table_height": 391,
"u32_table_height": 200,
"op_stack_table_height": 450,
"ram_table_height": 77
},
"case": "CommonCase"
}
Expand Down
13 changes: 13 additions & 0 deletions benchmarks/CollectLockScripts-4in-4out.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[
{
"name": "CollectLockScripts-4in-4out",
"benchmark_result": {
"clock_cycle_count": 924,
"hash_table_height": 415,
"u32_table_height": 202,
"op_stack_table_height": 686,
"ram_table_height": 143
},
"case": "CommonCase"
}
]
23 changes: 13 additions & 10 deletions profiles/CollectLockScripts-2in-2out.profile
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
CollectLockScripts-2in-2out:
| Subroutine | Processor | Op Stack | RAM | Hash | U32 |
|:---------------------------------------------------------------------------------|---------------------:|---------------------:|---------------------:|---------------------:|---------------------:|
| tasmlib_hashing_algebraic_hasher_hash_varlen | 182 ( 59.5%) | 137 ( 55.0%) | 45 ( 72.6%) | 37 ( 17.5%) | 12 ( 11.8%) |
| ··tasmlib_hashing_absorb_multiple | 168 ( 54.9%) | 122 ( 49.0%) | 45 ( 72.6%) | 30 ( 14.2%) | 12 ( 11.8%) |
| ····tasmlib_hashing_absorb_multiple_hash_all_full_chunks | 30 ( 9.8%) | 20 ( 8.0%) | 40 ( 64.5%) | 24 ( 11.4%) | 0 ( 0.0%) |
| ····tasmlib_hashing_absorb_multiple_pad_varnum_zeros | 50 ( 16.3%) | 32 ( 12.9%) | 0 ( 0.0%) | 0 ( 0.0%) | 0 ( 0.0%) |
| ····tasmlib_hashing_absorb_multiple_read_remainder | 51 ( 16.7%) | 29 ( 11.6%) | 5 ( 8.1%) | 0 ( 0.0%) | 0 ( 0.0%) |
| tasmlib_hashing_eq_digest | 16 ( 5.2%) | 9 ( 3.6%) | 0 ( 0.0%) | 0 ( 0.0%) | 0 ( 0.0%) |
| neptune_consensus_transaction_collect_lock_scripts_write_all_lock_script_digests | 70 ( 22.9%) | 72 ( 28.9%) | 14 ( 22.6%) | 0 ( 0.0%) | 30 ( 29.4%) |
| Total | 306 (100.0%) | 249 (100.0%) | 62 (100.0%) | 211 (100.0%) | 102 (100.0%) |
| Subroutine | Processor | Op Stack | RAM | Hash | U32 |
|:----------------------------------------------------------------------------------|---------------------:|---------------------:|---------------------:|---------------------:|---------------------:|
| tasmlib_structure_verify_nd_si_integrity___CollectLockScriptsWitness | 297 ( 49.0%) | 194 ( 43.1%) | 15 ( 19.5%) | 0 ( 0.0%) | 188 ( 94.0%) |
| ··tasmlib_structure_tasmobject_verify_size_indicators_dyn_elem_sizes___Utxo | 236 ( 38.9%) | 156 ( 34.7%) | 12 ( 15.6%) | 0 ( 0.0%) | 120 ( 60.0%) |
| ····tasmlib_structure_tasmobject_verify_size_indicators_dyn_elem_sizes___Coin | 118 ( 19.5%) | 80 ( 17.8%) | 6 ( 7.8%) | 0 ( 0.0%) | 60 ( 30.0%) |
| tasmlib_hashing_algebraic_hasher_hash_varlen | 182 ( 30.0%) | 137 ( 30.4%) | 45 ( 58.4%) | 37 ( 9.5%) | 12 ( 6.0%) |
| ··tasmlib_hashing_absorb_multiple | 168 ( 27.7%) | 122 ( 27.1%) | 45 ( 58.4%) | 30 ( 7.7%) | 12 ( 6.0%) |
| ····tasmlib_hashing_absorb_multiple_hash_all_full_chunks | 30 ( 5.0%) | 20 ( 4.4%) | 40 ( 51.9%) | 24 ( 6.1%) | 0 ( 0.0%) |
| ····tasmlib_hashing_absorb_multiple_pad_varnum_zeros | 50 ( 8.3%) | 32 ( 7.1%) | 0 ( 0.0%) | 0 ( 0.0%) | 0 ( 0.0%) |
| ····tasmlib_hashing_absorb_multiple_read_remainder | 51 ( 8.4%) | 29 ( 6.4%) | 5 ( 6.5%) | 0 ( 0.0%) | 0 ( 0.0%) |
| tasmlib_hashing_eq_digest | 16 ( 2.6%) | 9 ( 2.0%) | 0 ( 0.0%) | 0 ( 0.0%) | 0 ( 0.0%) |
| neptune_consensus_transaction_collect_lock_scripts_write_all_lock_script_digests | 70 ( 11.6%) | 72 ( 16.0%) | 14 ( 18.2%) | 0 ( 0.0%) | 0 ( 0.0%) |
| Total | 606 (100.0%) | 450 (100.0%) | 77 (100.0%) | 391 (100.0%) | 200 (100.0%) |
14 changes: 14 additions & 0 deletions profiles/CollectLockScripts-4in-4out.profile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
CollectLockScripts-4in-4out:
| Subroutine | Processor | Op Stack | RAM | Hash | U32 |
|:----------------------------------------------------------------------------------|---------------------:|---------------------:|---------------------:|---------------------:|---------------------:|
| tasmlib_structure_verify_nd_si_integrity___CollectLockScriptsWitness | 527 ( 57.0%) | 346 ( 50.4%) | 27 ( 18.9%) | 0 ( 0.0%) | 189 ( 93.6%) |
| ··tasmlib_structure_tasmobject_verify_size_indicators_dyn_elem_sizes___Utxo | 466 ( 50.4%) | 308 ( 44.9%) | 24 ( 16.8%) | 0 ( 0.0%) | 120 ( 59.4%) |
| ····tasmlib_structure_tasmobject_verify_size_indicators_dyn_elem_sizes___Coin | 236 ( 25.5%) | 160 ( 23.3%) | 12 ( 8.4%) | 0 ( 0.0%) | 60 ( 29.7%) |
| tasmlib_hashing_algebraic_hasher_hash_varlen | 206 ( 22.3%) | 153 ( 22.3%) | 85 ( 59.4%) | 61 ( 14.7%) | 13 ( 6.4%) |
| ··tasmlib_hashing_absorb_multiple | 192 ( 20.8%) | 138 ( 20.1%) | 85 ( 59.4%) | 54 ( 13.0%) | 13 ( 6.4%) |
| ····tasmlib_hashing_absorb_multiple_hash_all_full_chunks | 54 ( 5.8%) | 36 ( 5.2%) | 80 ( 55.9%) | 48 ( 11.6%) | 0 ( 0.0%) |
| ····tasmlib_hashing_absorb_multiple_pad_varnum_zeros | 50 ( 5.4%) | 32 ( 4.7%) | 0 ( 0.0%) | 0 ( 0.0%) | 0 ( 0.0%) |
| ····tasmlib_hashing_absorb_multiple_read_remainder | 51 ( 5.5%) | 29 ( 4.2%) | 5 ( 3.5%) | 0 ( 0.0%) | 0 ( 0.0%) |
| tasmlib_hashing_eq_digest | 16 ( 1.7%) | 9 ( 1.3%) | 0 ( 0.0%) | 0 ( 0.0%) | 0 ( 0.0%) |
| neptune_consensus_transaction_collect_lock_scripts_write_all_lock_script_digests | 134 ( 14.5%) | 140 ( 20.4%) | 28 ( 19.6%) | 0 ( 0.0%) | 0 ( 0.0%) |
| Total | 924 (100.0%) | 686 (100.0%) | 143 (100.0%) | 415 (100.0%) | 202 (100.0%) |
35 changes: 25 additions & 10 deletions src/models/blockchain/transaction/validity/collect_lock_scripts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use tasm_lib::library::Library;
use tasm_lib::memory::encode_to_memory;
use tasm_lib::memory::FIRST_NON_DETERMINISTICALLY_INITIALIZED_MEMORY_ADDRESS;
use tasm_lib::structure::tasm_object::TasmObject;
use tasm_lib::structure::verify_nd_si_integrity::VerifyNdSiIntegrity;
use tasm_lib::triton_vm::prelude::*;
use tasm_lib::twenty_first::util_types::algebraic_hasher::AlgebraicHasher;
use tasm_lib::Digest;
Expand Down Expand Up @@ -96,7 +97,6 @@ impl ConsensusProgram for CollectLockScripts {

fn code(&self) -> Vec<LabelledInstruction> {
let mut library = Library::new();
// let field_salted_input_utxos = field!(CollectLockScriptsWitness::salted_input_utxos);
let field_with_size_salted_input_utxos =
field_with_size!(CollectLockScriptsWitness::salted_input_utxos);
let field_utxos = field!(SaltedUtxos::utxos);
Expand All @@ -106,37 +106,52 @@ impl ConsensusProgram for CollectLockScripts {
let write_all_lock_script_digests =
"neptune_consensus_transaction_collect_lock_scripts_write_all_lock_script_digests"
.to_string();

let audit_preloaded_data = library.import(Box::new(VerifyNdSiIntegrity::<
CollectLockScriptsWitness,
>::default()));

let payload = triton_asm! {

push {FIRST_NON_DETERMINISTICALLY_INITIALIZED_MEMORY_ADDRESS}
// _ *clsw

dup 0
call {audit_preloaded_data}
// _ *clsw witness_size

dup 1
// _ *clsw witness_size *clsw

{&field_with_size_salted_input_utxos}
// _ *salted_input_utxos size
// _ *clsw witness_size *salted_input_utxos size

dup 1 swap 1
// _ *salted_input_utxos *salted_input_utxos size
// _ *clsw witness_size *salted_input_utxos *salted_input_utxos size

call {hash_varlen}
// _ *salted_input_utxos [salted_input_utxos_hash]
// _ *clsw witness_size *salted_input_utxos [salted_input_utxos_hash]

read_io 5
// _ *salted_input_utxos [salted_input_utxos_hash] [siud]
// _ *clsw witness_size *salted_input_utxos [salted_input_utxos_hash] [siud]

call {eq_digest} assert
// _ *salted_input_utxos
// _ *clsw witness_size *salted_input_utxos

{&field_utxos}
// _ *utxos_li
// _ *clsw witness_size *utxos_li

read_mem 1 push 2 add
// _ N *utxos[0]_si
// _ *clsw witness_size N *utxos[0]_si

push 0 swap 1
// _ N 0 *utxos[0]_si
// _ *clsw witness_size N 0 *utxos[0]_si

call {write_all_lock_script_digests}
// _ N N *
// _ *clsw witness_size N N *ptr

pop 5
// _

halt

Expand Down

0 comments on commit e959d61

Please sign in to comment.