(&self)
| 72 | } |
| 73 | |
| 74 | fn generate_taproot_leaf_2_script(&self) -> ScriptBuf { |
| 75 | const TWO_WEEKS_IN_SECONDS: u32 = 60 * 60 * 24 * 14; |
| 76 | let superblock_hash_public_key = |
| 77 | &self.commitment_public_keys[&CommitmentMessageId::SuperblockHash]; |
| 78 | let start_time_public_key = &self.commitment_public_keys[&CommitmentMessageId::StartTime]; |
| 79 | |
| 80 | // Expected witness: |
| 81 | // n-of-n Schnorr signature |
| 82 | // SB' (byte stream) |
| 83 | // Committed start time (Winternitz sig) |
| 84 | // Committed SB hash (Winternitz sig) |
| 85 | |
| 86 | script! { |
| 87 | // Verify superblock hash commitment sig |
| 88 | { winternitz_message_checksig(superblock_hash_public_key) } |
| 89 | // Convert committed SB hash to number and push it to altstack |
| 90 | { sb_hash_from_nibbles() } |
| 91 | { H256::toaltstack() } // Stack: SB' sig(start_time) | Altstack: SB.hash |
| 92 | |
| 93 | // Verify start time commitment sig |
| 94 | { winternitz_message_checksig(start_time_public_key) } |
| 95 | // Convert committed start time to number and push it to altstack |
| 96 | { digits_to_number::<{ START_TIME_MESSAGE_LENGTH * 2 }, { LOG_D as usize }>() } |
| 97 | OP_TOALTSTACK // Stack: SB' | Altstack: SB.hash start_time |
| 98 | |
| 99 | extract_superblock_ts_from_header |
| 100 | // Stack: SB' SB'.time | Altstack: SB.hash start_time |
| 101 | |
| 102 | // SB'.time > start_time |
| 103 | OP_FROMALTSTACK // Stack: SB' SB'.time start_time | Altstack: SB.hash |
| 104 | OP_2DUP // Stack: SB' SB'.time start_time SB'.time start_time | Altstack: SB.hash |
| 105 | OP_GREATERTHAN OP_VERIFY // Stack: SB' SB'.time start_time | Altstack: SB.hash |
| 106 | |
| 107 | // SB'.time < start_time + 2 weeks |
| 108 | { TWO_WEEKS_IN_SECONDS } OP_ADD // Stack: SB' SB'.time (start_time + 2 weeks) | Altstack: SB.hash |
| 109 | OP_LESSTHAN OP_VERIFY // Stack: SB' | Altstack: SB.hash |
| 110 | |
| 111 | // Calculate SB' hash |
| 112 | { sha256(SUPERBLOCK_MESSAGE_LENGTH) } |
| 113 | { sha256_32bytes() } |
| 114 | { sb_hash_from_bytes() } // Stack: SB'.hash | Altstack: SB.hash |
| 115 | |
| 116 | // SB'.weight > SB.weight |
| 117 | // We're comparing hashes as numbers (smaller number = bigger weight), |
| 118 | // so we need to evaluate (SB'.hash < SB.hash). |
| 119 | { H256::fromaltstack() } // Stack: SB'.hash SB.hash |
| 120 | { H256::lessthan(1, 0) } OP_VERIFY |
| 121 | |
| 122 | { self.n_of_n_taproot_public_key } |
| 123 | OP_CHECKSIG |
| 124 | } |
| 125 | .compile() |
| 126 | } |
| 127 | |
| 128 | fn generate_taproot_leaf_2_tx_in(&self, input: &Input) -> TxIn { |
| 129 | generate_default_tx_in(input) |
no outgoing calls
no test coverage detected