@@ -14786,6 +14786,10 @@ fn body_ckb_runtime_features(
1478614786 ir::IrInstruction::Call { func, .. } if func.starts_with("__ckb_spawn") => {
1478714787 features.insert("ckb-spawn-ipc".to_string());
1478814788 }
14789+ ir::IrInstruction::Call { func, .. } if func == "__novaseal_bip340_require_signature" => {
14790+ features.insert("btc-bip340-runtime-verifier".to_string());
14791+ features.insert("ckb-spawn-ipc".to_string());
14792+ }
1478914793 ir::IrInstruction::Call { func, .. }
1479014794 if matches!(
1479114795 func.as_str(),
@@ -15025,6 +15029,45 @@ fn body_ckb_runtime_accesses(
1502515029 });
1502615030 }
1502715031 if let ir::IrInstruction::Call { func, .. } = instruction {
15032+ if func == "__novaseal_bip340_require_signature" {
15033+ accesses.extend([
15034+ CkbRuntimeAccessMetadata {
15035+ operation: "bip340-pipe".to_string(),
15036+ syscall: "PIPE".to_string(),
15037+ source: "Process".to_string(),
15038+ index: 0,
15039+ binding: "verifier::btc::bip340::require_signature".to_string(),
15040+ },
15041+ CkbRuntimeAccessMetadata {
15042+ operation: "bip340-spawn".to_string(),
15043+ syscall: "SPAWN".to_string(),
15044+ source: "CellDep".to_string(),
15045+ index: 0,
15046+ binding: "cellscript_btc_bip340_verifier_riscv".to_string(),
15047+ },
15048+ CkbRuntimeAccessMetadata {
15049+ operation: "bip340-pipe-write-18-words".to_string(),
15050+ syscall: "PIPE_WRITE".to_string(),
15051+ source: "Process".to_string(),
15052+ index: 0,
15053+ binding: "cellscript-btc-bip340-ipc-v0".to_string(),
15054+ },
15055+ CkbRuntimeAccessMetadata {
15056+ operation: "bip340-close".to_string(),
15057+ syscall: "CLOSE".to_string(),
15058+ source: "Process".to_string(),
15059+ index: 0,
15060+ binding: "cellscript-btc-bip340-ipc-v0".to_string(),
15061+ },
15062+ CkbRuntimeAccessMetadata {
15063+ operation: "bip340-wait".to_string(),
15064+ syscall: "WAIT".to_string(),
15065+ source: "Process".to_string(),
15066+ index: 0,
15067+ binding: "cellscript_btc_bip340_verifier_riscv".to_string(),
15068+ },
15069+ ]);
15070+ }
1502815071 if let Some((operation, syscall, source, binding)) = ckb_v014_runtime_access(func) {
1502915072 accesses.push(CkbRuntimeAccessMetadata {
1503015073 operation: operation.to_string(),
@@ -22797,7 +22840,8 @@ action verify(witness message: Hash, witness pubkey: [u8; 32], witness signature
2279722840}
2279822841"#;
2279922842 let result = compile(source, CompileOptions { target_profile: Some("ckb".to_string()), ..CompileOptions::default() }).unwrap();
22800- let asm = String::from_utf8(result.artifact_bytes).unwrap();
22843+ let asm = String::from_utf8(result.artifact_bytes.clone()).unwrap();
22844+ let action = result.metadata.actions.iter().find(|action| action.name == "verify").expect("verify metadata");
2280122845
2280222846 assert_eq!(
2280322847 asm.matches("# cellscript abi: novaseal bip340 ipc word ").count(),
@@ -22818,6 +22862,24 @@ action verify(witness message: Hash, witness pubkey: [u8; 32], witness signature
2281822862 "BIP340 IPC word range and fail-closed write path must remain visible:\n{}",
2281922863 asm
2282022864 );
22865+ for operation in ["bip340-pipe", "bip340-spawn", "bip340-pipe-write-18-words", "bip340-close", "bip340-wait"] {
22866+ assert!(
22867+ action.ckb_runtime_accesses.iter().any(|access| access.operation == operation),
22868+ "BIP340 lowering metadata omitted {operation}: {:?}",
22869+ action.ckb_runtime_accesses
22870+ );
22871+ }
22872+ assert!(
22873+ action.ckb_runtime_features.iter().any(|feature| feature == "btc-bip340-runtime-verifier")
22874+ && action.ckb_runtime_features.iter().any(|feature| feature == "ckb-spawn-ipc"),
22875+ "BIP340 lowering metadata omitted verifier or VM2 feature: {:?}",
22876+ action.ckb_runtime_features
22877+ );
22878+ assert!(
22879+ action.proof_plan.iter().any(|plan| plan.feature.contains("bip340")),
22880+ "BIP340 lowering must remain visible in ProofPlan: {:?}",
22881+ action.proof_plan
22882+ );
2282122883 }
2282222884
2282322885 #[test]
0 commit comments