@@ -3192,6 +3192,8 @@ mod tests {
3192
3192
3193
3193
use bitcoin:: util:: hash:: Sha256dHash ;
3194
3194
use bitcoin:: util:: bip143;
3195
+ use bitcoin:: util:: address:: Address ;
3196
+ use bitcoin:: util:: bip32:: { ChildNumber , ExtendedPubKey , ExtendedPrivKey } ;
3195
3197
use bitcoin:: blockdata:: block:: { Block , BlockHeader } ;
3196
3198
use bitcoin:: blockdata:: transaction:: { Transaction , TxOut , TxIn , SigHashType } ;
3197
3199
use bitcoin:: blockdata:: script:: { Builder , Script } ;
@@ -7120,4 +7122,89 @@ mod tests {
7120
7122
} ;
7121
7123
check_spends ! ( spend_tx, node_txn[ 0 ] . clone( ) ) ;
7122
7124
}
7125
+
7126
+ #[ test]
7127
+ fn test_static_spendable_outputs_preimage_tx ( ) {
7128
+ let nodes = create_network ( 2 ) ;
7129
+
7130
+ // Create some initial channels
7131
+ let chan_1 = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
7132
+
7133
+ let payment_preimage = route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , 3000000 ) . 0 ;
7134
+
7135
+ let commitment_tx = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan_1. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
7136
+ assert_eq ! ( commitment_tx[ 0 ] . input. len( ) , 1 ) ;
7137
+ assert_eq ! ( commitment_tx[ 0 ] . input[ 0 ] . previous_output. txid, chan_1. 3 . txid( ) ) ;
7138
+
7139
+ // Settle A's commitment tx on B's chain
7140
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
7141
+ assert ! ( nodes[ 1 ] . node. claim_funds( payment_preimage) ) ;
7142
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
7143
+ nodes[ 1 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ commitment_tx[ 0 ] . clone( ) ] } , 1 ) ;
7144
+ let events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
7145
+ match events[ 0 ] {
7146
+ MessageSendEvent :: UpdateHTLCs { .. } => { } ,
7147
+ _ => panic ! ( "Unexpected event" ) ,
7148
+ }
7149
+ match events[ 1 ] {
7150
+ MessageSendEvent :: BroadcastChannelUpdate { .. } => { } ,
7151
+ _ => panic ! ( "Unexepected event" ) ,
7152
+ }
7153
+
7154
+ // Check B's monitor was able to send back output descriptor event for preimage tx on A's commitment tx
7155
+ let node_txn = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ; // ChannelManager : 1 (local commitment tx), ChannelMonitor: 2 (1 preimage tx) * 2 (block-rescan)
7156
+ check_spends ! ( node_txn[ 0 ] , commitment_tx[ 0 ] . clone( ) ) ;
7157
+ assert_eq ! ( node_txn[ 0 ] , node_txn[ 2 ] ) ;
7158
+ assert_eq ! ( node_txn[ 0 ] . input[ 0 ] . witness. last( ) . unwrap( ) . len( ) , 133 ) ;
7159
+ check_spends ! ( node_txn[ 1 ] , chan_1. 3 . clone( ) ) ;
7160
+
7161
+ let events = nodes[ 1 ] . chan_monitor . simple_monitor . get_and_clear_pending_events ( ) ;
7162
+ let spend_tx = match events[ 0 ] {
7163
+ Event :: SpendableOutputs { ref outputs } => {
7164
+ match outputs[ 0 ] {
7165
+ SpendableOutputDescriptor :: StaticOutput { ref outpoint, ref output } => {
7166
+ let secp_ctx = Secp256k1 :: new ( ) ;
7167
+ let input = TxIn {
7168
+ previous_output : outpoint. clone ( ) ,
7169
+ script_sig : Script :: new ( ) ,
7170
+ sequence : 0 ,
7171
+ witness : Vec :: new ( ) ,
7172
+ } ;
7173
+ let outp = TxOut {
7174
+ script_pubkey : Builder :: new ( ) . push_opcode ( opcodes:: All :: OP_RETURN ) . into_script ( ) ,
7175
+ value : output. value ,
7176
+ } ;
7177
+ let mut spend_tx = Transaction {
7178
+ version : 2 ,
7179
+ lock_time : 0 ,
7180
+ input : vec ! [ input] ,
7181
+ output : vec ! [ outp. clone( ) ] ,
7182
+ } ;
7183
+ let destination_secret = {
7184
+ match ExtendedPrivKey :: new_master ( & secp_ctx, Network :: Testnet , & nodes[ 1 ] . node_seed ) {
7185
+ Ok ( master_key) => {
7186
+ match master_key. ckd_priv ( & secp_ctx, ChildNumber :: from_hardened_idx ( 1 ) ) {
7187
+ Ok ( destination_key) => destination_key,
7188
+ Err ( _) => panic ! ( "Your RNG is busted" ) ,
7189
+ }
7190
+ }
7191
+ Err ( _) => panic ! ( "Your rng is busted" ) ,
7192
+ }
7193
+ } ;
7194
+ let destination_pubkey = ExtendedPubKey :: from_private ( & secp_ctx, & destination_secret) . public_key ;
7195
+ let witness_script = Address :: p2pkh ( & destination_pubkey, Network :: Testnet ) . script_pubkey ( ) ;
7196
+ let sighash = Message :: from_slice ( & bip143:: SighashComponents :: new ( & spend_tx) . sighash_all ( & spend_tx. input [ 0 ] , & witness_script, output. value ) [ ..] ) . unwrap ( ) ;
7197
+ let sig = secp_ctx. sign ( & sighash, & destination_secret. secret_key ) ;
7198
+ spend_tx. input [ 0 ] . witness . push ( sig. serialize_der ( & secp_ctx) . to_vec ( ) ) ;
7199
+ spend_tx. input [ 0 ] . witness [ 0 ] . push ( SigHashType :: All as u8 ) ;
7200
+ spend_tx. input [ 0 ] . witness . push ( destination_pubkey. serialize ( ) . to_vec ( ) ) ;
7201
+ spend_tx
7202
+ } ,
7203
+ _ => panic ! ( "Unexpected event !" ) ,
7204
+ }
7205
+ } ,
7206
+ _ => panic ! ( "Unexpected event !" ) ,
7207
+ } ;
7208
+ check_spends ! ( spend_tx, node_txn[ 0 ] . clone( ) ) ;
7209
+ }
7123
7210
}
0 commit comments