@@ -824,3 +824,214 @@ fn feerate_bump<F: Deref, L: Deref>(predicted_weight: usize, input_amounts: u64,
824
824
} ;
825
825
Some ( ( new_fee, new_fee * 1000 / ( predicted_weight as u64 ) ) )
826
826
}
827
+
828
+ #[ cfg( test) ]
829
+ mod tests {
830
+ use chain:: package:: { CounterpartyReceivedHTLCOutput , HolderHTLCOutput , PackageTemplate , PackageSolvingData , RevokedOutput , WEIGHT_REVOKED_OUTPUT } ;
831
+ use chain:: Txid ;
832
+ use ln:: chan_utils:: HTLCOutputInCommitment ;
833
+ use ln:: { PaymentPreimage , PaymentHash } ;
834
+
835
+ use bitcoin:: blockdata:: constants:: WITNESS_SCALE_FACTOR ;
836
+ use bitcoin:: blockdata:: script:: Script ;
837
+ use bitcoin:: blockdata:: transaction:: OutPoint as BitcoinOutPoint ;
838
+
839
+ use bitcoin:: hashes:: hex:: FromHex ;
840
+
841
+ use bitcoin:: secp256k1:: key:: { PublicKey , SecretKey } ;
842
+ use bitcoin:: secp256k1:: Secp256k1 ;
843
+
844
+ macro_rules! dumb_revk_output {
845
+ ( $secp_ctx: expr) => {
846
+ {
847
+ let dumb_scalar = SecretKey :: from_slice( & hex:: decode( "0101010101010101010101010101010101010101010101010101010101010101" ) . unwrap( ) [ ..] ) . unwrap( ) ;
848
+ let dumb_point = PublicKey :: from_secret_key( & $secp_ctx, & dumb_scalar) ;
849
+ PackageSolvingData :: RevokedOutput ( RevokedOutput :: build( dumb_point, dumb_point, dumb_point, dumb_scalar, 0 , 0 ) )
850
+ }
851
+ }
852
+ }
853
+
854
+ macro_rules! dumb_counterparty_output {
855
+ ( $secp_ctx: expr, $amt: expr) => {
856
+ {
857
+ let dumb_scalar = SecretKey :: from_slice( & hex:: decode( "0101010101010101010101010101010101010101010101010101010101010101" ) . unwrap( ) [ ..] ) . unwrap( ) ;
858
+ let dumb_point = PublicKey :: from_secret_key( & $secp_ctx, & dumb_scalar) ;
859
+ let hash = PaymentHash ( [ 1 ; 32 ] ) ;
860
+ let htlc = HTLCOutputInCommitment { offered: true , amount_msat: $amt, cltv_expiry: 0 , payment_hash: hash, transaction_output_index: None } ;
861
+ PackageSolvingData :: CounterpartyReceivedHTLCOutput ( CounterpartyReceivedHTLCOutput :: build( dumb_point, dumb_point, dumb_point, htlc) )
862
+ }
863
+ }
864
+ }
865
+
866
+ macro_rules! dumb_htlc_output {
867
+ ( ) => {
868
+ {
869
+ let preimage = PaymentPreimage ( [ 2 ; 32 ] ) ;
870
+ PackageSolvingData :: HolderHTLCOutput ( HolderHTLCOutput :: build( Some ( preimage) , 0 ) )
871
+ }
872
+ }
873
+ }
874
+
875
+ #[ test]
876
+ #[ should_panic]
877
+ fn test_package_differing_heights ( ) {
878
+ let txid = Txid :: from_hex ( "c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e" ) . unwrap ( ) ;
879
+ let secp_ctx = Secp256k1 :: new ( ) ;
880
+ let revk_outp = dumb_revk_output ! ( secp_ctx) ;
881
+
882
+ let mut package_one_hundred = PackageTemplate :: build_package ( txid, 0 , revk_outp. clone ( ) , 1000 , true , 100 ) ;
883
+ let package_two_hundred = PackageTemplate :: build_package ( txid, 1 , revk_outp. clone ( ) , 1000 , true , 200 ) ;
884
+ package_one_hundred. merge_package ( package_two_hundred) ;
885
+ }
886
+
887
+ #[ test]
888
+ #[ should_panic]
889
+ fn test_package_untractable_merge_to ( ) {
890
+ let txid = Txid :: from_hex ( "c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e" ) . unwrap ( ) ;
891
+ let secp_ctx = Secp256k1 :: new ( ) ;
892
+ let revk_outp = dumb_revk_output ! ( secp_ctx) ;
893
+ let htlc_outp = dumb_htlc_output ! ( ) ;
894
+
895
+ let mut untractable_package = PackageTemplate :: build_package ( txid, 0 , revk_outp. clone ( ) , 1000 , true , 100 ) ;
896
+ let malleable_package = PackageTemplate :: build_package ( txid, 1 , htlc_outp. clone ( ) , 1000 , true , 100 ) ;
897
+ untractable_package. merge_package ( malleable_package) ;
898
+ }
899
+
900
+ #[ test]
901
+ #[ should_panic]
902
+ fn test_package_untractable_merge_from ( ) {
903
+ let txid = Txid :: from_hex ( "c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e" ) . unwrap ( ) ;
904
+ let secp_ctx = Secp256k1 :: new ( ) ;
905
+ let htlc_outp = dumb_htlc_output ! ( ) ;
906
+ let revk_outp = dumb_revk_output ! ( secp_ctx) ;
907
+
908
+ let mut malleable_package = PackageTemplate :: build_package ( txid, 0 , htlc_outp. clone ( ) , 1000 , true , 100 ) ;
909
+ let untractable_package = PackageTemplate :: build_package ( txid, 1 , revk_outp. clone ( ) , 1000 , true , 100 ) ;
910
+ malleable_package. merge_package ( untractable_package) ;
911
+ }
912
+
913
+ #[ test]
914
+ #[ should_panic]
915
+ fn test_package_noaggregation_to ( ) {
916
+ let txid = Txid :: from_hex ( "c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e" ) . unwrap ( ) ;
917
+ let secp_ctx = Secp256k1 :: new ( ) ;
918
+ let revk_outp = dumb_revk_output ! ( secp_ctx) ;
919
+
920
+ let mut noaggregation_package = PackageTemplate :: build_package ( txid, 0 , revk_outp. clone ( ) , 1000 , false , 100 ) ;
921
+ let aggregation_package = PackageTemplate :: build_package ( txid, 1 , revk_outp. clone ( ) , 1000 , true , 100 ) ;
922
+ noaggregation_package. merge_package ( aggregation_package) ;
923
+ }
924
+
925
+ #[ test]
926
+ #[ should_panic]
927
+ fn test_package_noaggregation_from ( ) {
928
+ let txid = Txid :: from_hex ( "c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e" ) . unwrap ( ) ;
929
+ let secp_ctx = Secp256k1 :: new ( ) ;
930
+ let revk_outp = dumb_revk_output ! ( secp_ctx) ;
931
+
932
+ let mut aggregation_package = PackageTemplate :: build_package ( txid, 0 , revk_outp. clone ( ) , 1000 , true , 100 ) ;
933
+ let noaggregation_package = PackageTemplate :: build_package ( txid, 1 , revk_outp. clone ( ) , 1000 , false , 100 ) ;
934
+ aggregation_package. merge_package ( noaggregation_package) ;
935
+ }
936
+
937
+ #[ test]
938
+ #[ should_panic]
939
+ fn test_package_empty ( ) {
940
+ let txid = Txid :: from_hex ( "c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e" ) . unwrap ( ) ;
941
+ let secp_ctx = Secp256k1 :: new ( ) ;
942
+ let revk_outp = dumb_revk_output ! ( secp_ctx) ;
943
+
944
+ let mut empty_package = PackageTemplate :: build_package ( txid, 0 , revk_outp. clone ( ) , 1000 , true , 100 ) ;
945
+ empty_package. inputs = vec ! [ ] ;
946
+ let package = PackageTemplate :: build_package ( txid, 1 , revk_outp. clone ( ) , 1000 , true , 100 ) ;
947
+ empty_package. merge_package ( package) ;
948
+ }
949
+
950
+ #[ test]
951
+ #[ should_panic]
952
+ fn test_package_differing_categories ( ) {
953
+ let txid = Txid :: from_hex ( "c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e" ) . unwrap ( ) ;
954
+ let secp_ctx = Secp256k1 :: new ( ) ;
955
+ let revk_outp = dumb_revk_output ! ( secp_ctx) ;
956
+ let counterparty_outp = dumb_counterparty_output ! ( secp_ctx, 0 ) ;
957
+
958
+ let mut revoked_package = PackageTemplate :: build_package ( txid, 0 , revk_outp, 1000 , true , 100 ) ;
959
+ let counterparty_package = PackageTemplate :: build_package ( txid, 1 , counterparty_outp, 1000 , true , 100 ) ;
960
+ revoked_package. merge_package ( counterparty_package) ;
961
+ }
962
+
963
+ #[ test]
964
+ fn test_package_split_malleable ( ) {
965
+ let txid = Txid :: from_hex ( "c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e" ) . unwrap ( ) ;
966
+ let secp_ctx = Secp256k1 :: new ( ) ;
967
+ let revk_outp_one = dumb_revk_output ! ( secp_ctx) ;
968
+ let revk_outp_two = dumb_revk_output ! ( secp_ctx) ;
969
+ let revk_outp_three = dumb_revk_output ! ( secp_ctx) ;
970
+
971
+ let mut package_one = PackageTemplate :: build_package ( txid, 0 , revk_outp_one, 1000 , true , 100 ) ;
972
+ let package_two = PackageTemplate :: build_package ( txid, 1 , revk_outp_two, 1000 , true , 100 ) ;
973
+ let package_three = PackageTemplate :: build_package ( txid, 2 , revk_outp_three, 1000 , true , 100 ) ;
974
+
975
+ package_one. merge_package ( package_two) ;
976
+ package_one. merge_package ( package_three) ;
977
+ assert_eq ! ( package_one. outpoints( ) . len( ) , 3 ) ;
978
+
979
+ if let Some ( split_package) = package_one. split_package ( & BitcoinOutPoint { txid, vout : 1 } ) {
980
+ // Packages attributes should be identical
981
+ assert ! ( split_package. is_malleable( ) ) ;
982
+ assert_eq ! ( split_package. soonest_conf_deadline, package_one. soonest_conf_deadline) ;
983
+ assert_eq ! ( split_package. aggregable, package_one. aggregable) ;
984
+ assert_eq ! ( split_package. feerate_previous, package_one. feerate_previous) ;
985
+ assert_eq ! ( split_package. height_timer, package_one. height_timer) ;
986
+ assert_eq ! ( split_package. height_original, package_one. height_original) ;
987
+ } else { panic ! ( ) ; }
988
+ assert_eq ! ( package_one. outpoints( ) . len( ) , 2 ) ;
989
+ }
990
+
991
+ #[ test]
992
+ fn test_package_split_untractable ( ) {
993
+ let txid = Txid :: from_hex ( "c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e" ) . unwrap ( ) ;
994
+ let htlc_outp_one = dumb_htlc_output ! ( ) ;
995
+
996
+ let mut package_one = PackageTemplate :: build_package ( txid, 0 , htlc_outp_one, 1000 , true , 100 ) ;
997
+ let ret_split = package_one. split_package ( & BitcoinOutPoint { txid, vout : 0 } ) ;
998
+ assert ! ( ret_split. is_none( ) ) ;
999
+ }
1000
+
1001
+ #[ test]
1002
+ fn test_package_timer ( ) {
1003
+ let txid = Txid :: from_hex ( "c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e" ) . unwrap ( ) ;
1004
+ let secp_ctx = Secp256k1 :: new ( ) ;
1005
+ let revk_outp = dumb_revk_output ! ( secp_ctx) ;
1006
+
1007
+ let mut package = PackageTemplate :: build_package ( txid, 0 , revk_outp, 1000 , true , 100 ) ;
1008
+ let timer_none = package. timer ( ) ;
1009
+ assert ! ( timer_none. is_none( ) ) ;
1010
+ package. set_timer ( Some ( 100 ) ) ;
1011
+ if let Some ( timer_some) = package. timer ( ) {
1012
+ assert_eq ! ( timer_some, 100 ) ;
1013
+ } else { panic ! ( ) }
1014
+ }
1015
+
1016
+ #[ test]
1017
+ fn test_package_amounts ( ) {
1018
+ let txid = Txid :: from_hex ( "c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e" ) . unwrap ( ) ;
1019
+ let secp_ctx = Secp256k1 :: new ( ) ;
1020
+ let counterparty_outp = dumb_counterparty_output ! ( secp_ctx, 1_000_000 ) ;
1021
+
1022
+ let package = PackageTemplate :: build_package ( txid, 0 , counterparty_outp, 1000 , true , 100 ) ;
1023
+ assert_eq ! ( package. package_amount( ) , 1000 ) ;
1024
+ }
1025
+
1026
+ #[ test]
1027
+ fn test_package_weight ( ) {
1028
+ let txid = Txid :: from_hex ( "c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e" ) . unwrap ( ) ;
1029
+ let secp_ctx = Secp256k1 :: new ( ) ;
1030
+ let revk_outp = dumb_revk_output ! ( secp_ctx) ;
1031
+
1032
+ let package = PackageTemplate :: build_package ( txid, 0 , revk_outp, 0 , true , 100 ) ;
1033
+ // (nVersion (4) + nLocktime (4) + count_tx_in (1) + prevout (36) + sequence (4) + script_length (1) + count_tx_out (1) + value (8) + var_int (1)) * WITNESS_SCALE_FACTOR
1034
+ // + witness marker (2) + WEIGHT_REVOKED_OUTPUT
1035
+ assert_eq ! ( package. package_weight( & Script :: new( ) ) , ( 4 + 4 + 1 + 36 + 4 + 1 + 1 + 8 + 1 ) * WITNESS_SCALE_FACTOR + 2 + WEIGHT_REVOKED_OUTPUT as usize ) ;
1036
+ }
1037
+ }
0 commit comments