@@ -14,7 +14,7 @@ use bitcoin_hashes::ripemd160::Hash as Ripemd160;
1414use bitcoin_hashes:: hash160:: Hash as Hash160 ;
1515use bitcoin_hashes:: sha256d:: Hash as Sha256dHash ;
1616
17- use ln:: channelmanager:: PaymentHash ;
17+ use ln:: channelmanager:: { PaymentHash , PaymentPreimage } ;
1818use ln:: msgs:: DecodeError ;
1919use util:: ser:: { Readable , Writeable , Writer , WriterWriteAdaptor } ;
2020use util:: byte_utils;
@@ -23,6 +23,10 @@ use secp256k1::key::{SecretKey, PublicKey};
2323use secp256k1:: { Secp256k1 , Signature } ;
2424use secp256k1;
2525
26+ use std:: { cmp, mem} ;
27+
28+ const MAX_ALLOC_SIZE : usize = 64 * 1024 ;
29+
2630pub ( super ) const HTLC_SUCCESS_TX_WEIGHT : u64 = 703 ;
2731pub ( super ) const HTLC_TIMEOUT_TX_WEIGHT : u64 = 663 ;
2832
@@ -480,7 +484,11 @@ pub fn build_htlc_transaction(prev_hash: &Sha256dHash, feerate_per_kw: u64, to_s
480484/// to broadcast. Eventually this will require a signer which is possibly external, but for now we
481485/// just pass in the SecretKeys required.
482486pub struct LocalCommitmentTransaction {
483- tx : Transaction
487+ tx : Transaction ,
488+ //TODO: modify Channel methods to integrate HTLC material at LocalCommitmentTransaction generation to drop Option here
489+ local_keys : Option < TxCreationKeys > ,
490+ feerate_per_kw : Option < u64 > ,
491+ per_htlc : Vec < ( HTLCOutputInCommitment , Option < Signature > , Option < Transaction > ) >
484492}
485493impl LocalCommitmentTransaction {
486494 #[ cfg( test) ]
@@ -499,7 +507,11 @@ impl LocalCommitmentTransaction {
499507 input : vec ! [ dummy_input] ,
500508 output : Vec :: new ( ) ,
501509 lock_time : 0 ,
502- } }
510+ } ,
511+ local_keys : None ,
512+ feerate_per_kw : None ,
513+ per_htlc : Vec :: new ( )
514+ }
503515 }
504516
505517 /// Generate a new LocalCommitmentTransaction based on a raw commitment transaction,
@@ -520,7 +532,11 @@ impl LocalCommitmentTransaction {
520532 tx. input [ 0 ] . witness . push ( Vec :: new ( ) ) ;
521533 }
522534
523- Self { tx }
535+ Self { tx,
536+ local_keys : None ,
537+ feerate_per_kw : None ,
538+ per_htlc : Vec :: new ( )
539+ }
524540 }
525541
526542 /// Get the txid of the local commitment transaction contained in this
@@ -577,6 +593,67 @@ impl LocalCommitmentTransaction {
577593 assert ! ( self . has_local_sig( ) ) ;
578594 & self . tx
579595 }
596+
597+ /// Set HTLC cache to generate any local HTLC transaction spending one of htlc ouput
598+ /// from this local commitment transaction
599+ pub ( crate ) fn set_htlc_cache ( & mut self , local_keys : TxCreationKeys , feerate_per_kw : u64 , htlc_outputs : Vec < ( HTLCOutputInCommitment , Option < Signature > , Option < Transaction > ) > ) {
600+ self . local_keys = Some ( local_keys) ;
601+ self . feerate_per_kw = Some ( feerate_per_kw) ;
602+ self . per_htlc = htlc_outputs;
603+ }
604+
605+ /// Add local signature for a htlc transaction, do nothing if a cached signed transaction is
606+ /// already present
607+ pub fn add_htlc_sig < T : secp256k1:: Signing > ( & mut self , htlc_base_key : & SecretKey , htlc_index : u32 , preimage : Option < PaymentPreimage > , local_csv : u16 , secp_ctx : & Secp256k1 < T > ) {
608+ if self . local_keys . is_none ( ) || self . feerate_per_kw . is_none ( ) { return ; }
609+ let local_keys = self . local_keys . as_ref ( ) . unwrap ( ) ;
610+ let txid = self . txid ( ) ;
611+ for this_htlc in self . per_htlc . iter_mut ( ) {
612+ if this_htlc. 0 . transaction_output_index . unwrap ( ) == htlc_index {
613+ if this_htlc. 2 . is_some ( ) { return ; } // we already have a cached htlc transaction at provided index
614+ let mut htlc_tx = build_htlc_transaction ( & txid, self . feerate_per_kw . unwrap ( ) , local_csv, & this_htlc. 0 , & local_keys. a_delayed_payment_key , & local_keys. revocation_key ) ;
615+ if !this_htlc. 0 . offered && preimage. is_none ( ) { return ; } // if we don't have preimage for HTLC-Success, don't try to generate
616+ let htlc_secret = if !this_htlc. 0 . offered { preimage } else { None } ; // if we have a preimage for HTLC-Timeout, don't use it that's likely a duplicate HTLC hash
617+ if this_htlc. 1 . is_none ( ) { return ; } // we don't have any remote signature for this htlc
618+ if htlc_tx. input . len ( ) != 1 { return ; }
619+ if htlc_tx. input [ 0 ] . witness . len ( ) != 0 { return ; }
620+
621+ let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys ( & this_htlc. 0 , & local_keys. a_htlc_key , & local_keys. b_htlc_key , & local_keys. revocation_key ) ;
622+
623+ if let Ok ( our_htlc_key) = derive_private_key ( secp_ctx, & local_keys. per_commitment_point , htlc_base_key) {
624+ let sighash = hash_to_message ! ( & bip143:: SighashComponents :: new( & htlc_tx) . sighash_all( & htlc_tx. input[ 0 ] , & htlc_redeemscript, this_htlc. 0 . amount_msat / 1000 ) [ ..] ) ;
625+ let our_sig = secp_ctx. sign ( & sighash, & our_htlc_key) ;
626+
627+ htlc_tx. input [ 0 ] . witness . push ( Vec :: new ( ) ) ; // First is the multisig dummy
628+
629+ htlc_tx. input [ 0 ] . witness . push ( this_htlc. 1 . unwrap ( ) . serialize_der ( ) . to_vec ( ) ) ;
630+ htlc_tx. input [ 0 ] . witness . push ( our_sig. serialize_der ( ) . to_vec ( ) ) ;
631+ htlc_tx. input [ 0 ] . witness [ 1 ] . push ( SigHashType :: All as u8 ) ;
632+ htlc_tx. input [ 0 ] . witness [ 2 ] . push ( SigHashType :: All as u8 ) ;
633+
634+ if this_htlc. 0 . offered {
635+ htlc_tx. input [ 0 ] . witness . push ( Vec :: new ( ) ) ;
636+ assert ! ( htlc_secret. is_none( ) ) ;
637+ } else {
638+ htlc_tx. input [ 0 ] . witness . push ( htlc_secret. unwrap ( ) . 0 . to_vec ( ) ) ;
639+ }
640+
641+ htlc_tx. input [ 0 ] . witness . push ( htlc_redeemscript. as_bytes ( ) . to_vec ( ) ) ;
642+
643+ this_htlc. 2 = Some ( htlc_tx) ;
644+ } else { return ; }
645+ }
646+ }
647+ }
648+ /// Expose raw htlc transaction, guarante witness is complete if non-empty
649+ pub fn htlc_with_valid_witness ( & self , htlc_index : u32 ) -> & Option < Transaction > {
650+ for this_htlc in self . per_htlc . iter ( ) {
651+ if this_htlc. 0 . transaction_output_index . unwrap ( ) == htlc_index {
652+ return & this_htlc. 2 ;
653+ }
654+ }
655+ & None
656+ }
580657}
581658impl PartialEq for LocalCommitmentTransaction {
582659 // We dont care whether we are signed in equality comparison
@@ -592,6 +669,14 @@ impl Writeable for LocalCommitmentTransaction {
592669 _ => panic ! ( "local tx must have been well-formed!" ) ,
593670 }
594671 }
672+ self . local_keys . write ( writer) ?;
673+ self . feerate_per_kw . write ( writer) ?;
674+ writer. write_all ( & byte_utils:: be64_to_array ( self . per_htlc . len ( ) as u64 ) ) ?;
675+ for & ( ref htlc, ref sig, ref htlc_tx) in self . per_htlc . iter ( ) {
676+ htlc. write ( writer) ?;
677+ sig. write ( writer) ?;
678+ htlc_tx. write ( writer) ?;
679+ }
595680 Ok ( ( ) )
596681 }
597682}
@@ -604,12 +689,27 @@ impl Readable for LocalCommitmentTransaction {
604689 _ => return Err ( DecodeError :: InvalidValue ) ,
605690 } ,
606691 } ;
692+ let local_keys = Readable :: read ( reader) ?;
693+ let feerate_per_kw = Readable :: read ( reader) ?;
694+ let htlcs_count: u64 = Readable :: read ( reader) ?;
695+ let mut per_htlc = Vec :: with_capacity ( cmp:: min ( htlcs_count as usize , MAX_ALLOC_SIZE / mem:: size_of :: < ( HTLCOutputInCommitment , Option < Signature > , Option < Transaction > ) > ( ) ) ) ;
696+ for _ in 0 ..htlcs_count {
697+ let htlc: HTLCOutputInCommitment = Readable :: read ( reader) ?;
698+ let sigs = Readable :: read ( reader) ?;
699+ let htlc_tx = Readable :: read ( reader) ?;
700+ per_htlc. push ( ( htlc, sigs, htlc_tx) ) ;
701+ }
607702
608703 if tx. input . len ( ) != 1 {
609704 // Ensure tx didn't hit the 0-input ambiguity case.
610705 return Err ( DecodeError :: InvalidValue ) ;
611706 }
612- Ok ( Self { tx } )
707+ Ok ( Self {
708+ tx,
709+ local_keys,
710+ feerate_per_kw,
711+ per_htlc,
712+ } )
613713 }
614714}
615715
0 commit comments