@@ -19,7 +19,7 @@ use bitcoin::util::address::Payload;
1919use bitcoin:: hashes:: { Hash , HashEngine } ;
2020use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
2121use bitcoin:: hashes:: ripemd160:: Hash as Ripemd160 ;
22- use bitcoin:: hash_types:: { Txid , PubkeyHash , WPubkeyHash } ;
22+ use bitcoin:: hash_types:: { BlockHash , Txid , PubkeyHash , WPubkeyHash } ;
2323
2424use crate :: chain:: chaininterface:: fee_for_weight;
2525use crate :: chain:: package:: WEIGHT_REVOKED_OUTPUT ;
@@ -858,6 +858,210 @@ pub fn build_anchor_input_witness(funding_key: &PublicKey, funding_sig: &Signatu
858858 ret
859859}
860860
861+ pub ( crate ) struct ChannelFundingTransaction {
862+ tx : Option < Transaction > ,
863+ txo : Option < chain:: transaction:: OutPoint > ,
864+ /// The hash of the block in which the funding transaction was included.
865+ tx_confirmed_in : Option < BlockHash > ,
866+ tx_confirmation_height : Option < u32 > ,
867+ }
868+
869+ /// Stores into about a funding transaction:
870+ /// - TX outpoint and/or the full Transaction
871+ /// - confirmation block/height for confirmed transactions
872+ impl ChannelFundingTransaction {
873+ pub ( crate ) fn new_empty ( ) -> Self {
874+ Self { tx : None , txo : None , tx_confirmed_in : None , tx_confirmation_height : None }
875+ }
876+
877+ pub ( crate ) fn get_tx ( & self ) -> Option < & Transaction > { self . tx . as_ref ( ) }
878+
879+ pub ( crate ) fn set_tx ( & mut self , tx : Transaction ) {
880+ self . tx = Some ( tx) ;
881+ }
882+
883+ pub ( crate ) fn set_txo ( & mut self , txo : chain:: transaction:: OutPoint ) {
884+ self . txo = Some ( txo) ;
885+ }
886+
887+ pub ( crate ) fn is_confirmed ( & self ) -> bool {
888+ self . tx_confirmation_height . is_some ( ) && self . tx_confirmed_in . is_some ( )
889+ }
890+
891+ /// Returns the current number of confirmations
892+ pub ( crate ) fn get_tx_confirmations ( & mut self , height : u32 ) -> Option < i64 > {
893+ match self . tx_confirmation_height {
894+ // We either haven't seen any confirmation yet, or observed a reorg.
895+ None => None ,
896+ Some ( h) => {
897+ let confs = height as i64 - h as i64 + 1 ;
898+ // Reset on reorg
899+ if confs <= 0 {
900+ self . tx_confirmation_height = None ;
901+ }
902+ Some ( confs)
903+ }
904+ }
905+ }
906+
907+ /// Returns the current number of confirmations
908+ pub ( crate ) fn get_tx_confirmations_nocheck ( & self , height : u32 ) -> Option < u32 > {
909+ match self . tx_confirmation_height {
910+ // We either haven't seen any confirmation yet, or observed a reorg.
911+ None => None ,
912+ Some ( h) => height. checked_sub ( h) . map ( |c| c + 1 )
913+ }
914+ }
915+
916+ fn set_confirmed ( & mut self , block_hash : BlockHash , block_height : u32 ) {
917+ // TODO check if confirmed already
918+ self . tx_confirmed_in = Some ( block_hash) ;
919+ self . tx_confirmation_height = Some ( block_height) ;
920+ }
921+
922+ // fn reset_unconfirmed(&mut self) {
923+ // self.tx_confirmed_in = None;
924+ // self.tx_confirmation_height = None;
925+ // }
926+
927+ pub ( crate ) fn get_tx_confirmed_in ( & self ) -> Option < BlockHash > { self . tx_confirmed_in }
928+ pub ( crate ) fn get_tx_confirmation_height ( & self ) -> Option < u32 > { self . tx_confirmation_height }
929+ }
930+
931+ impl Writeable for ChannelFundingTransaction {
932+ fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , io:: Error > {
933+ self . tx . write ( writer) ?;
934+ self . txo . write ( writer) ?;
935+ self . tx_confirmed_in . write ( writer) ?;
936+ self . tx_confirmation_height . write ( writer) ?;
937+ Ok ( ( ) )
938+ }
939+ }
940+
941+ impl Readable for ChannelFundingTransaction {
942+ fn read < R : io:: Read > ( reader : & mut R ) -> Result < Self , DecodeError > {
943+ let tx = Readable :: read ( reader) ?;
944+ let txo = Readable :: read ( reader) ?;
945+ let tx_confirmed_in = Readable :: read ( reader) ?;
946+ let tx_confirmation_height = Readable :: read ( reader) ?;
947+ Ok ( Self { tx, txo, tx_confirmed_in, tx_confirmation_height } )
948+ }
949+ }
950+
951+ /// Stores info about zero or one funding transaction:
952+ /// - none in case of unfunded channels
953+ /// 1 in case of funded channels (can be uncofirmed or confirmed)
954+ /// It is prepared to handle multiple funding transaction candidates (e.g. in case of Splicing)
955+ pub ( crate ) struct ChannelFundingTransactions {
956+ tx : Option < ChannelFundingTransaction > ,
957+ }
958+
959+ impl ChannelFundingTransactions {
960+ pub ( crate ) fn new_empty ( ) -> Self {
961+ Self { tx : None }
962+ }
963+
964+ pub ( crate ) fn is_some ( & self ) -> bool {
965+ self . tx . is_some ( )
966+ }
967+
968+ pub ( crate ) fn set_tx ( & mut self , tx : Transaction ) {
969+ if let Some ( cft) = self . tx . as_mut ( ) {
970+ cft. set_tx ( tx) ;
971+ } else {
972+ let mut cft = ChannelFundingTransaction :: new_empty ( ) ;
973+ cft. set_tx ( tx) ;
974+ self . tx = Some ( cft) ;
975+ }
976+ }
977+
978+ pub ( crate ) fn set_txo ( & mut self , txo : chain:: transaction:: OutPoint ) {
979+ if let Some ( cft) = self . tx . as_mut ( ) {
980+ cft. set_txo ( txo) ;
981+ } else {
982+ let mut cft = ChannelFundingTransaction :: new_empty ( ) ;
983+ cft. set_txo ( txo) ;
984+ self . tx = Some ( cft) ;
985+ }
986+ }
987+
988+ pub ( crate ) fn is_confirmed ( & self ) -> bool {
989+ self . tx . as_ref ( ) . map_or ( false , |tx| tx. is_confirmed ( ) )
990+ // match &self.tx {
991+ // None => false,
992+ // Some(tx) => tx.is_confirmed(),
993+ // }
994+ }
995+
996+ pub ( crate ) fn is_unconfirmed ( & self ) -> bool {
997+ self . tx . as_ref ( ) . map_or ( true , |tx| !tx. is_confirmed ( ) )
998+ }
999+
1000+ pub ( crate ) fn set_confirmed ( & mut self , block_hash : BlockHash , block_height : u32 ) {
1001+ if let Some ( tx) = self . tx . as_mut ( ) {
1002+ tx. set_confirmed ( block_hash, block_height) ;
1003+ } else {
1004+ panic ! ( "Set_confirmed() invoked, but there is no funding tx!" ) ;
1005+ }
1006+ }
1007+
1008+ pub ( crate ) fn get_tx ( & self ) -> Option < Transaction > {
1009+ match & self . tx {
1010+ None => None ,
1011+ Some ( tx) => match tx. get_tx ( ) {
1012+ None => None ,
1013+ Some ( tx) => Some ( tx. clone ( ) ) ,
1014+ }
1015+ }
1016+ }
1017+
1018+ pub ( crate ) fn tx_take ( & mut self ) -> Option < Transaction > {
1019+ match self . tx . take ( ) {
1020+ None => None ,
1021+ Some ( tx) => match tx. get_tx ( ) {
1022+ None => None ,
1023+ Some ( tx) => Some ( tx. clone ( ) )
1024+ }
1025+ }
1026+ }
1027+
1028+ /// Returns the block hash in the funding transaction was confirmed.
1029+ pub ( crate ) fn get_tx_confirmed_in ( & self ) -> Option < BlockHash > {
1030+ match & self . tx {
1031+ None => None ,
1032+ Some ( tx) => tx. get_tx_confirmed_in ( ) ,
1033+ }
1034+ }
1035+
1036+ pub ( crate ) fn get_tx_confirmation_height ( & self ) -> Option < u32 > {
1037+ self . tx . as_ref ( ) . map_or ( None , |tx| tx. get_tx_confirmation_height ( ) )
1038+ }
1039+
1040+ /// Returns the current number of confirmations
1041+ pub ( crate ) fn get_tx_confirmations ( & mut self , height : u32 ) -> Option < i64 > {
1042+ self . tx . as_mut ( ) . map_or ( None , |tx| tx. get_tx_confirmations ( height) )
1043+ }
1044+
1045+ /// Returns the current number of confirmations
1046+ pub ( crate ) fn get_tx_confirmations_nocheck ( & self , height : u32 ) -> Option < u32 > {
1047+ self . tx . as_ref ( ) . map_or ( None , |tx| tx. get_tx_confirmations_nocheck ( height) )
1048+ }
1049+ }
1050+
1051+ impl Writeable for ChannelFundingTransactions {
1052+ fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , io:: Error > {
1053+ self . tx . write ( writer) ?;
1054+ Ok ( ( ) )
1055+ }
1056+ }
1057+
1058+ impl Readable for ChannelFundingTransactions {
1059+ fn read < R : io:: Read > ( reader : & mut R ) -> Result < Self , DecodeError > {
1060+ let tx = Readable :: read ( reader) ?;
1061+ Ok ( Self { tx } )
1062+ }
1063+ }
1064+
8611065/// Per-channel data used to build transactions in conjunction with the per-commitment data (CommitmentTransaction).
8621066/// The fields are organized by holder/counterparty.
8631067///
0 commit comments