From b87d9f788b4877b93b90e38244d0780cd90f1c4b Mon Sep 17 00:00:00 2001 From: xjd Date: Mon, 1 Apr 2024 13:14:15 +0800 Subject: [PATCH] Optimize get_witness_layout * avoid duplicated verifications on witnesses * printf with format %zu for size_t --- c/cobuild.h | 28 +++++++------ c/molecule2_verify.h | 42 ++++++++++++++------ tests/omni_lock_rust/tests/test_omni_lock.rs | 4 +- 3 files changed, 46 insertions(+), 28 deletions(-) diff --git a/c/cobuild.h b/c/cobuild.h index 83eb03a..f9742b6 100644 --- a/c/cobuild.h +++ b/c/cobuild.h @@ -209,7 +209,8 @@ int new_otx_blake2b(blake2b_state *S) { } static inline int get_witness_layout(BytesVecType witnesses, uint32_t index, - WitnessLayoutType *witness_layout) { + WitnessLayoutType *witness_layout, + bool verify_recursively) { bool existing = false; mol2_cursor_t witness = witnesses.t->get(&witnesses, index, &existing); if (!existing) { @@ -217,7 +218,7 @@ static inline int get_witness_layout(BytesVecType witnesses, uint32_t index, } WitnessLayoutType witness_layout2 = make_WitnessLayout(&witness); - if (verify_WitnessLayout(&witness_layout2)) { + if (verify_WitnessLayout(&witness_layout2, verify_recursively)) { return COBUILD_ERROR_GENERAL; } if (witness_layout != NULL) { @@ -248,7 +249,7 @@ int ckb_fetch_sighash_message(BytesVecType witnesses, MessageType *message) { uint32_t witness_len = witnesses.t->len(&witnesses); for (uint32_t index = 0; index < witness_len; index++) { WitnessLayoutType witness_layout = {0}; - if (get_witness_layout(witnesses, index, &witness_layout) == 0) { + if (get_witness_layout(witnesses, index, &witness_layout, false) == 0) { uint32_t id = witness_layout.t->item_id(&witness_layout); if (id == WitnessLayoutSighashAll) { // tested by: @@ -280,7 +281,7 @@ static inline int ckb_fetch_otx_start(BytesVecType witnesses, bool *has_otx, uint32_t witness_len = witnesses.t->len(&witnesses); for (uint32_t index = 0; index < witness_len; index++) { WitnessLayoutType witness_layout = {0}; - err = get_witness_layout(witnesses, index, &witness_layout); + err = get_witness_layout(witnesses, index, &witness_layout, false); if (err == 0) { uint32_t id = witness_layout.t->item_id(&witness_layout); if (id == WitnessLayoutOtxStart) { @@ -398,7 +399,7 @@ int ckb_generate_smh(const Env *env, mol2_cursor_t message_cursor, CKB_COBUILD_CHECK(err); } blake2b_final(&ctx, smh, BLAKE2B_BLOCK_SIZE); - printf("ckb_generate_smh total hashed %d bytes", count); + printf("ckb_generate_smh total hashed %zu bytes", count); exit: return err; @@ -532,7 +533,7 @@ int ckb_cobuild_normal_entry(const Env *env, ScriptEntryType callback) { CKB_SOURCE_GROUP_INPUT); CKB_COBUILD_CHECK(err); WitnessLayoutType witness_layout = make_WitnessLayout(&witness); - CKB_COBUILD_CHECK2(!verify_WitnessLayout(&witness_layout), + CKB_COBUILD_CHECK2(!verify_WitnessLayout(&witness_layout, false), COBUILD_ERROR_SIGHASHALL_NOSEAL); uint32_t id = witness_layout.t->item_id(&witness_layout); @@ -691,7 +692,7 @@ int ckb_generate_otx_smh(const Env *env, mol2_cursor_t message_cursor, err = ckb_hash_cursor(&ctx, header_dep_cursor); count += header_dep_cursor.size; } - printf("ckb_generate_otx_smh totally hashed %d bytes", count); + printf("ckb_generate_otx_smh totally hashed %zu bytes", count); blake2b_final(&ctx, smh, BLAKE2B_BLOCK_SIZE); exit: return err; @@ -712,9 +713,10 @@ int ckb_cobuild_entry(const Env *env, ScriptEntryType callback, // Legacy Flow Handling *cobuild_enabled = false; for (uint32_t i = 0; i < witness_len; i++) { - if (get_witness_layout(witnesses, i, NULL) == 0) { + if (get_witness_layout(witnesses, i, NULL, true) == 0) { *cobuild_enabled = true; - break; + // Do not break here. All witnesses are recursively verified at this + // point. Subsequent witnesses will not be recursively verified. } } if (!*cobuild_enabled) { @@ -749,7 +751,7 @@ int ckb_cobuild_entry(const Env *env, ScriptEntryType callback, printf("Otx starts at index %d(inclusive)", index); for (; index < witness_len; index++) { WitnessLayoutType witness_layout = {0}; - err = get_witness_layout(witnesses, index, &witness_layout); + err = get_witness_layout(witnesses, index, &witness_layout, false); if (err != 0) { // step 6, not WitnessLayoutOtx break; @@ -861,7 +863,7 @@ int ckb_cobuild_entry(const Env *env, ScriptEntryType callback, // [0, i) [j, +infinity) if (index < i || index >= j) { WitnessLayoutType witness_layout = {0}; - err = get_witness_layout(witnesses, index, &witness_layout); + err = get_witness_layout(witnesses, index, &witness_layout, false); if (err == 0) { // test_cobuild_otx_noexistent_otx_id uint32_t id = witness_layout.t->item_id(&witness_layout); @@ -883,7 +885,7 @@ int ckb_cobuild_entry(const Env *env, ScriptEntryType callback, CKB_COBUILD_CHECK_LOOP(err); if (memcmp(hash, env->current_script_hash, sizeof(hash)) == 0) { printf( - "Same lock script found beyond otx, at index %d. " + "Same lock script found beyond otx, at index %zu. " "ckb_cobuild_normal_entry called.", index); found = true; @@ -898,7 +900,7 @@ int ckb_cobuild_entry(const Env *env, ScriptEntryType callback, CKB_COBUILD_CHECK(err); } CKB_COBUILD_CHECK2(execution_count > 0, COBUILD_ERROR_NO_CALLBACK); - printf("execution_count = %d", execution_count); + printf("execution_count = %zu", execution_count); exit: return err; } diff --git a/c/molecule2_verify.h b/c/molecule2_verify.h index 96c1b55..fec7ac9 100644 --- a/c/molecule2_verify.h +++ b/c/molecule2_verify.h @@ -17,7 +17,7 @@ typedef enum WitnessLayoutId { } WitnessLayoutId; int verify_WitnessArgs(WitnessArgsType *witness); -int verify_WitnessLayout(WitnessLayoutType *witness); +int verify_WitnessLayout(WitnessLayoutType *witness, bool recursive); #ifndef MOLECULEC_C2_DECLARATION_ONLY @@ -177,28 +177,44 @@ int get_union_id(mol2_cursor_t *cur, uint32_t *union_id) { return MOL2_OK; } -int verify_WitnessLayout(WitnessLayoutType *witness) { +int verify_WitnessLayout(WitnessLayoutType *witness, bool recursive) { int err = MOL2_OK; uint32_t union_id = 0; - CHECK(get_union_id(&witness->cur, &union_id)); - + err = get_union_id(&witness->cur, &union_id); + CHECK(err); switch (union_id) { case WitnessLayoutSighashAll: { - SighashAllType sighash_all = witness->t->as_SighashAll(witness); - return verify_SighashAll(&sighash_all); + if (recursive) { + SighashAllType sighash_all = witness->t->as_SighashAll(witness); + err = verify_SighashAll(&sighash_all); + CHECK(err); + } + break; } case WitnessLayoutSighashAllOnly: { - SighashAllOnlyType sighash_all_only = - witness->t->as_SighashAllOnly(witness); - return verify_SighashAllOnly(&sighash_all_only); + if (recursive) { + SighashAllOnlyType sighash_all_only = + witness->t->as_SighashAllOnly(witness); + err = verify_SighashAllOnly(&sighash_all_only); + CHECK(err); + } + break; } case WitnessLayoutOtx: { - OtxType otx = witness->t->as_Otx(witness); - return verify_Otx(&otx); + if (recursive) { + OtxType otx = witness->t->as_Otx(witness); + err = verify_Otx(&otx); + CHECK(err); + } + break; } case WitnessLayoutOtxStart: { - OtxStartType otx_start = witness->t->as_OtxStart(witness); - return verify_OtxStart(&otx_start); + if (recursive) { + OtxStartType otx_start = witness->t->as_OtxStart(witness); + err = verify_OtxStart(&otx_start); + CHECK(err); + } + break; } default: { return MOL2_ERR_UNKNOWN_ITEM; diff --git a/tests/omni_lock_rust/tests/test_omni_lock.rs b/tests/omni_lock_rust/tests/test_omni_lock.rs index 8d6a1c5..8f42db6 100644 --- a/tests/omni_lock_rust/tests/test_omni_lock.rs +++ b/tests/omni_lock_rust/tests/test_omni_lock.rs @@ -879,8 +879,8 @@ fn test_cobuild_sighash_all_only() { let verify_result = verifier.verify(MAX_CYCLES); let cycles = (&verify_result).as_ref().unwrap(); println!("cycles = {}", *cycles); - // about ~1397402 - assert!(*cycles < 1410000); + // about ~1419872 + assert!(*cycles < 1430000); verify_result.expect("pass verification"); }