@@ -23,7 +23,7 @@ use bitcoin::hash_types::{Txid, PubkeyHash};
23
23
use ln:: { PaymentHash , PaymentPreimage } ;
24
24
use ln:: msgs:: DecodeError ;
25
25
use util:: ser:: { Readable , Writeable , Writer } ;
26
- use util:: byte_utils;
26
+ use util:: { byte_utils, transaction_utils } ;
27
27
28
28
use bitcoin:: hash_types:: WPubkeyHash ;
29
29
use bitcoin:: secp256k1:: key:: { SecretKey , PublicKey } ;
@@ -80,6 +80,50 @@ pub fn build_commitment_secret(commitment_seed: &[u8; 32], idx: u64) -> [u8; 32]
80
80
res
81
81
}
82
82
83
+ /// Build a closing transaction
84
+ pub fn build_closing_transaction ( to_holder_value_sat : u64 , to_counterparty_value_sat : u64 , to_holder_script : Script , to_counterparty_script : Script , funding_outpoint : OutPoint ) -> Transaction {
85
+ let txins = {
86
+ let mut ins: Vec < TxIn > = Vec :: new ( ) ;
87
+ ins. push ( TxIn {
88
+ previous_output : funding_outpoint,
89
+ script_sig : Script :: new ( ) ,
90
+ sequence : 0xffffffff ,
91
+ witness : Vec :: new ( ) ,
92
+ } ) ;
93
+ ins
94
+ } ;
95
+
96
+ let mut txouts: Vec < ( TxOut , ( ) ) > = Vec :: new ( ) ;
97
+
98
+ if to_counterparty_value_sat > 0 {
99
+ txouts. push ( ( TxOut {
100
+ script_pubkey : to_counterparty_script,
101
+ value : to_counterparty_value_sat
102
+ } , ( ) ) ) ;
103
+ }
104
+
105
+ if to_holder_value_sat > 0 {
106
+ txouts. push ( ( TxOut {
107
+ script_pubkey : to_holder_script,
108
+ value : to_holder_value_sat
109
+ } , ( ) ) ) ;
110
+ }
111
+
112
+ transaction_utils:: sort_outputs ( & mut txouts, |_, _| { cmp:: Ordering :: Equal } ) ; // Ordering doesnt matter if they used our pubkey...
113
+
114
+ let mut outputs: Vec < TxOut > = Vec :: new ( ) ;
115
+ for out in txouts. drain ( ..) {
116
+ outputs. push ( out. 0 ) ;
117
+ }
118
+
119
+ Transaction {
120
+ version : 2 ,
121
+ lock_time : 0 ,
122
+ input : txins,
123
+ output : outputs,
124
+ }
125
+ }
126
+
83
127
/// Implements the per-commitment secret storage scheme from
84
128
/// [BOLT 3](https://github.com/lightningnetwork/lightning-rfc/blob/dcbf8583976df087c79c3ce0b535311212e6812d/03-transactions.md#efficient-per-commitment-secret-storage).
85
129
///
@@ -846,7 +890,130 @@ impl BuiltCommitmentTransaction {
846
890
}
847
891
}
848
892
849
- /// This class tracks the per-transaction information needed to build a commitment transaction and to
893
+ /// This class tracks the per-transaction information needed to build a closing transaction and will
894
+ /// actually build it and sign.
895
+ ///
896
+ /// This class can be used inside a signer implementation to generate a signature given the relevant
897
+ /// secret key.
898
+ pub struct ClosingTransaction {
899
+ to_holder_value_sat : u64 ,
900
+ to_counterparty_value_sat : u64 ,
901
+ to_holder_script : Script ,
902
+ to_counterparty_script : Script ,
903
+ built : Transaction ,
904
+ }
905
+
906
+ impl ClosingTransaction {
907
+ /// Construct an object of the class
908
+ pub fn new (
909
+ to_holder_value_sat : u64 ,
910
+ to_counterparty_value_sat : u64 ,
911
+ to_holder_script : Script ,
912
+ to_counterparty_script : Script ,
913
+ funding_outpoint : OutPoint ,
914
+ ) -> Self {
915
+ let built = build_closing_transaction (
916
+ to_holder_value_sat, to_counterparty_value_sat,
917
+ to_holder_script. clone ( ) , to_counterparty_script. clone ( ) ,
918
+ funding_outpoint
919
+ ) ;
920
+ ClosingTransaction {
921
+ to_holder_value_sat,
922
+ to_counterparty_value_sat,
923
+ to_holder_script,
924
+ to_counterparty_script,
925
+ built
926
+ }
927
+ }
928
+
929
+ /// Trust our pre-built transaction.
930
+ ///
931
+ /// Applies a wrapper which allows access to the transaction.
932
+ ///
933
+ /// This should only be used if you fully trust the builder of this object. It should not
934
+ /// be used by an external signer - instead use the verify function.
935
+ pub fn trust ( & self ) -> TrustedClosingTransaction {
936
+ TrustedClosingTransaction { inner : self }
937
+ }
938
+
939
+ /// Verify our pre-built transaction.
940
+ ///
941
+ /// Applies a wrapper which allows access to the transaction.
942
+ ///
943
+ /// An external validating signer must call this method before signing
944
+ /// or using the built transaction.
945
+ pub fn verify ( & self , funding_outpoint : OutPoint ) -> Result < TrustedClosingTransaction , ( ) > {
946
+ let built = build_closing_transaction (
947
+ self . to_holder_value_sat , self . to_counterparty_value_sat ,
948
+ self . to_holder_script . clone ( ) , self . to_counterparty_script . clone ( ) ,
949
+ funding_outpoint
950
+ ) ;
951
+ if self . built != built {
952
+ return Err ( ( ) )
953
+ }
954
+ Ok ( TrustedClosingTransaction { inner : self } )
955
+ }
956
+
957
+ /// The value to be sent to the holder, or zero if the output will be omitted
958
+ pub fn to_holder_value_sat ( & self ) -> u64 {
959
+ self . to_holder_value_sat
960
+ }
961
+
962
+ /// The value to be sent to the counterparty, or zero if the output will be omitted
963
+ pub fn to_counterparty_value_sat ( & self ) -> u64 {
964
+ self . to_counterparty_value_sat
965
+ }
966
+
967
+ /// The destination of the holder's output
968
+ pub fn to_holder_script ( & self ) -> & Script {
969
+ & self . to_holder_script
970
+ }
971
+
972
+ /// The destination of the counterparty's output
973
+ pub fn to_counterparty_script ( & self ) -> & Script {
974
+ & self . to_counterparty_script
975
+ }
976
+ }
977
+
978
+ /// A wrapper on ClosingTransaction indicating that the built bitcoin
979
+ /// transaction is trusted.
980
+ ///
981
+ /// See trust() and verify() functions on CommitmentTransaction.
982
+ ///
983
+ /// This structure implements Deref.
984
+ pub struct TrustedClosingTransaction < ' a > {
985
+ inner : & ' a ClosingTransaction ,
986
+ }
987
+
988
+ impl < ' a > Deref for TrustedClosingTransaction < ' a > {
989
+ type Target = ClosingTransaction ;
990
+
991
+ fn deref ( & self ) -> & Self :: Target { self . inner }
992
+ }
993
+
994
+ impl < ' a > TrustedClosingTransaction < ' a > {
995
+ /// The pre-built Bitcoin commitment transaction
996
+ pub fn built_transaction ( & self ) -> & Transaction {
997
+ & self . inner . built
998
+ }
999
+
1000
+ /// Get the SIGHASH_ALL sighash value of the transaction.
1001
+ ///
1002
+ /// This can be used to verify a signature.
1003
+ pub fn get_sighash_all ( & self , funding_redeemscript : & Script , channel_value_satoshis : u64 ) -> Message {
1004
+ let sighash = & bip143:: SigHashCache :: new ( & self . inner . built ) . signature_hash ( 0 , funding_redeemscript, channel_value_satoshis, SigHashType :: All ) [ ..] ;
1005
+ hash_to_message ! ( sighash)
1006
+ }
1007
+
1008
+ /// Sign a transaction, either because we are counter-signing the counterparty's transaction or
1009
+ /// because we are about to broadcast a holder transaction.
1010
+ pub fn sign < T : secp256k1:: Signing > ( & self , funding_key : & SecretKey , funding_redeemscript : & Script , channel_value_satoshis : u64 , secp_ctx : & Secp256k1 < T > ) -> Signature {
1011
+ let sighash = self . get_sighash_all ( funding_redeemscript, channel_value_satoshis) ;
1012
+ secp_ctx. sign ( & sighash, funding_key)
1013
+ }
1014
+ }
1015
+
1016
+ /// This class tracks the per-transaction information needed to build a commitment transaction and will
850
1017
/// actually build it and sign. It is used for holder transactions that we sign only when needed
851
1018
/// and for transactions we sign for the counterparty.
852
1019
///
@@ -1110,7 +1277,7 @@ impl CommitmentTransaction {
1110
1277
/// Applies a wrapper which allows access to these fields.
1111
1278
///
1112
1279
/// This should only be used if you fully trust the builder of this object. It should not
1113
- /// be used by an external signer - instead use the verify function.
1280
+ /// be used by an external signer - instead use the verify function.
1114
1281
pub fn trust ( & self ) -> TrustedCommitmentTransaction {
1115
1282
TrustedCommitmentTransaction { inner : self }
1116
1283
}
0 commit comments