@@ -179,6 +179,12 @@ impl<'a> InvoiceRequestBuilder<'a> {
179
179
let InvoiceRequestBuilder { offer, invoice_request } = self ;
180
180
Ok ( UnsignedInvoiceRequest { offer, invoice_request } )
181
181
}
182
+
183
+ #[ cfg( test) ]
184
+ fn build_unchecked ( self ) -> UnsignedInvoiceRequest < ' a > {
185
+ let InvoiceRequestBuilder { offer, invoice_request } = self ;
186
+ UnsignedInvoiceRequest { offer, invoice_request }
187
+ }
182
188
}
183
189
184
190
/// A semantically valid [`InvoiceRequest`] that hasn't been signed.
@@ -471,13 +477,13 @@ mod tests {
471
477
472
478
use bitcoin:: blockdata:: constants:: ChainHash ;
473
479
use bitcoin:: network:: constants:: Network ;
474
- use bitcoin:: secp256k1:: { KeyPair , Message , PublicKey , Secp256k1 , SecretKey } ;
480
+ use bitcoin:: secp256k1:: { KeyPair , Message , PublicKey , Secp256k1 , SecretKey , self } ;
475
481
use bitcoin:: secp256k1:: schnorr:: Signature ;
476
482
use core:: convert:: TryFrom ;
477
483
use core:: num:: NonZeroU64 ;
478
484
use crate :: ln:: features:: InvoiceRequestFeatures ;
479
485
use crate :: ln:: msgs:: DecodeError ;
480
- use crate :: offers:: offer:: { OfferBuilder , Quantity } ;
486
+ use crate :: offers:: offer:: { Amount , Offer , OfferBuilder , Quantity } ;
481
487
use crate :: offers:: parse:: { ParseError , SemanticError } ;
482
488
use crate :: util:: ser:: { BigSize , Writeable } ;
483
489
use crate :: util:: string:: PrintableString ;
@@ -792,6 +798,318 @@ mod tests {
792
798
assert_eq ! ( tlv_stream. payer_note, Some ( & String :: from( "baz" ) ) ) ;
793
799
}
794
800
801
+ #[ test]
802
+ fn parses_invoice_request_with_metadata ( ) {
803
+ let invoice_request = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
804
+ . amount_msats ( 1000 )
805
+ . build ( ) . unwrap ( )
806
+ . request_invoice ( payer_pubkey ( ) )
807
+ . metadata ( vec ! [ 42 ; 32 ] )
808
+ . build ( ) . unwrap ( )
809
+ . sign ( payer_sign) . unwrap ( ) ;
810
+
811
+ let mut buffer = Vec :: new ( ) ;
812
+ invoice_request. write ( & mut buffer) . unwrap ( ) ;
813
+
814
+ if let Err ( e) = InvoiceRequest :: try_from ( buffer) {
815
+ panic ! ( "error parsing invoice_request: {:?}" , e) ;
816
+ }
817
+ }
818
+
819
+ #[ test]
820
+ fn parses_invoice_request_with_chain ( ) {
821
+ let invoice_request = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
822
+ . amount_msats ( 1000 )
823
+ . build ( ) . unwrap ( )
824
+ . request_invoice ( payer_pubkey ( ) )
825
+ . chain ( Network :: Bitcoin )
826
+ . build ( ) . unwrap ( )
827
+ . sign ( payer_sign) . unwrap ( ) ;
828
+
829
+ let mut buffer = Vec :: new ( ) ;
830
+ invoice_request. write ( & mut buffer) . unwrap ( ) ;
831
+
832
+ if let Err ( e) = InvoiceRequest :: try_from ( buffer) {
833
+ panic ! ( "error parsing invoice_request: {:?}" , e) ;
834
+ }
835
+
836
+ let invoice_request = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
837
+ . amount_msats ( 1000 )
838
+ . build ( ) . unwrap ( )
839
+ . request_invoice ( payer_pubkey ( ) )
840
+ . chain ( Network :: Testnet )
841
+ . build_unchecked ( )
842
+ . sign ( payer_sign) . unwrap ( ) ;
843
+
844
+ let mut buffer = Vec :: new ( ) ;
845
+ invoice_request. write ( & mut buffer) . unwrap ( ) ;
846
+
847
+ match InvoiceRequest :: try_from ( buffer) {
848
+ Ok ( _) => panic ! ( "expected error" ) ,
849
+ Err ( e) => assert_eq ! ( e, ParseError :: InvalidSemantics ( SemanticError :: UnsupportedChain ) ) ,
850
+ }
851
+ }
852
+
853
+ #[ test]
854
+ fn parses_invoice_request_with_amount ( ) {
855
+ let invoice_request = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
856
+ . amount_msats ( 1000 )
857
+ . build ( ) . unwrap ( )
858
+ . request_invoice ( payer_pubkey ( ) )
859
+ . build ( ) . unwrap ( )
860
+ . sign ( payer_sign) . unwrap ( ) ;
861
+
862
+ let mut buffer = Vec :: new ( ) ;
863
+ invoice_request. write ( & mut buffer) . unwrap ( ) ;
864
+
865
+ if let Err ( e) = InvoiceRequest :: try_from ( buffer) {
866
+ panic ! ( "error parsing invoice_request: {:?}" , e) ;
867
+ }
868
+
869
+ let invoice_request = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
870
+ . build ( ) . unwrap ( )
871
+ . request_invoice ( payer_pubkey ( ) )
872
+ . amount_msats ( 1000 )
873
+ . build ( ) . unwrap ( )
874
+ . sign ( payer_sign) . unwrap ( ) ;
875
+
876
+ let mut buffer = Vec :: new ( ) ;
877
+ invoice_request. write ( & mut buffer) . unwrap ( ) ;
878
+
879
+ if let Err ( e) = InvoiceRequest :: try_from ( buffer) {
880
+ panic ! ( "error parsing invoice_request: {:?}" , e) ;
881
+ }
882
+
883
+ let invoice_request = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
884
+ . build ( ) . unwrap ( )
885
+ . request_invoice ( payer_pubkey ( ) )
886
+ . build_unchecked ( )
887
+ . sign ( payer_sign) . unwrap ( ) ;
888
+
889
+ let mut buffer = Vec :: new ( ) ;
890
+ invoice_request. write ( & mut buffer) . unwrap ( ) ;
891
+
892
+ match InvoiceRequest :: try_from ( buffer) {
893
+ Ok ( _) => panic ! ( "expected error" ) ,
894
+ Err ( e) => assert_eq ! ( e, ParseError :: InvalidSemantics ( SemanticError :: MissingAmount ) ) ,
895
+ }
896
+
897
+ let invoice_request = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
898
+ . amount_msats ( 1000 )
899
+ . build ( ) . unwrap ( )
900
+ . request_invoice ( payer_pubkey ( ) )
901
+ . amount_msats ( 999 )
902
+ . build_unchecked ( )
903
+ . sign ( payer_sign) . unwrap ( ) ;
904
+
905
+ let mut buffer = Vec :: new ( ) ;
906
+ invoice_request. write ( & mut buffer) . unwrap ( ) ;
907
+
908
+ match InvoiceRequest :: try_from ( buffer) {
909
+ Ok ( _) => panic ! ( "expected error" ) ,
910
+ Err ( e) => assert_eq ! ( e, ParseError :: InvalidSemantics ( SemanticError :: InsufficientAmount ) ) ,
911
+ }
912
+
913
+ let invoice_request = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
914
+ . amount ( Amount :: Currency { iso4217_code : * b"USD" , amount : 1000 } )
915
+ . build_unchecked ( )
916
+ . request_invoice ( payer_pubkey ( ) )
917
+ . build_unchecked ( )
918
+ . sign ( payer_sign) . unwrap ( ) ;
919
+
920
+ let mut buffer = Vec :: new ( ) ;
921
+ invoice_request. write ( & mut buffer) . unwrap ( ) ;
922
+
923
+ match InvoiceRequest :: try_from ( buffer) {
924
+ Ok ( _) => panic ! ( "expected error" ) ,
925
+ Err ( e) => {
926
+ assert_eq ! ( e, ParseError :: InvalidSemantics ( SemanticError :: UnsupportedCurrency ) ) ;
927
+ } ,
928
+ }
929
+ }
930
+
931
+ #[ test]
932
+ fn parses_invoice_request_with_quantity ( ) {
933
+ let ten = NonZeroU64 :: new ( 10 ) . unwrap ( ) ;
934
+
935
+ let invoice_request = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
936
+ . amount_msats ( 1000 )
937
+ . supported_quantity ( Quantity :: one ( ) )
938
+ . build ( ) . unwrap ( )
939
+ . request_invoice ( payer_pubkey ( ) )
940
+ . build ( ) . unwrap ( )
941
+ . sign ( payer_sign) . unwrap ( ) ;
942
+
943
+ let mut buffer = Vec :: new ( ) ;
944
+ invoice_request. write ( & mut buffer) . unwrap ( ) ;
945
+
946
+ if let Err ( e) = InvoiceRequest :: try_from ( buffer) {
947
+ panic ! ( "error parsing invoice_request: {:?}" , e) ;
948
+ }
949
+
950
+ let invoice_request = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
951
+ . amount_msats ( 1000 )
952
+ . supported_quantity ( Quantity :: one ( ) )
953
+ . build ( ) . unwrap ( )
954
+ . request_invoice ( payer_pubkey ( ) )
955
+ . amount_msats ( 2_000 )
956
+ . quantity ( 2 )
957
+ . build_unchecked ( )
958
+ . sign ( payer_sign) . unwrap ( ) ;
959
+
960
+ let mut buffer = Vec :: new ( ) ;
961
+ invoice_request. write ( & mut buffer) . unwrap ( ) ;
962
+
963
+ match InvoiceRequest :: try_from ( buffer) {
964
+ Ok ( _) => panic ! ( "expected error" ) ,
965
+ Err ( e) => {
966
+ assert_eq ! ( e, ParseError :: InvalidSemantics ( SemanticError :: UnexpectedQuantity ) ) ;
967
+ } ,
968
+ }
969
+
970
+ let invoice_request = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
971
+ . amount_msats ( 1000 )
972
+ . supported_quantity ( Quantity :: Bounded ( ten) )
973
+ . build ( ) . unwrap ( )
974
+ . request_invoice ( payer_pubkey ( ) )
975
+ . amount_msats ( 10_000 )
976
+ . quantity ( 10 )
977
+ . build ( ) . unwrap ( )
978
+ . sign ( payer_sign) . unwrap ( ) ;
979
+
980
+ let mut buffer = Vec :: new ( ) ;
981
+ invoice_request. write ( & mut buffer) . unwrap ( ) ;
982
+
983
+ if let Err ( e) = InvoiceRequest :: try_from ( buffer) {
984
+ panic ! ( "error parsing invoice_request: {:?}" , e) ;
985
+ }
986
+
987
+ let invoice_request = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
988
+ . amount_msats ( 1000 )
989
+ . supported_quantity ( Quantity :: Bounded ( ten) )
990
+ . build ( ) . unwrap ( )
991
+ . request_invoice ( payer_pubkey ( ) )
992
+ . amount_msats ( 11_000 )
993
+ . quantity ( 11 )
994
+ . build_unchecked ( )
995
+ . sign ( payer_sign) . unwrap ( ) ;
996
+
997
+ let mut buffer = Vec :: new ( ) ;
998
+ invoice_request. write ( & mut buffer) . unwrap ( ) ;
999
+
1000
+ match InvoiceRequest :: try_from ( buffer) {
1001
+ Ok ( _) => panic ! ( "expected error" ) ,
1002
+ Err ( e) => assert_eq ! ( e, ParseError :: InvalidSemantics ( SemanticError :: InvalidQuantity ) ) ,
1003
+ }
1004
+
1005
+ let invoice_request = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
1006
+ . amount_msats ( 1000 )
1007
+ . supported_quantity ( Quantity :: Unbounded )
1008
+ . build ( ) . unwrap ( )
1009
+ . request_invoice ( payer_pubkey ( ) )
1010
+ . amount_msats ( 2_000 )
1011
+ . quantity ( 2 )
1012
+ . build ( ) . unwrap ( )
1013
+ . sign ( payer_sign) . unwrap ( ) ;
1014
+
1015
+ let mut buffer = Vec :: new ( ) ;
1016
+ invoice_request. write ( & mut buffer) . unwrap ( ) ;
1017
+
1018
+ if let Err ( e) = InvoiceRequest :: try_from ( buffer) {
1019
+ panic ! ( "error parsing invoice_request: {:?}" , e) ;
1020
+ }
1021
+
1022
+ let invoice_request = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
1023
+ . amount_msats ( 1000 )
1024
+ . supported_quantity ( Quantity :: Unbounded )
1025
+ . build ( ) . unwrap ( )
1026
+ . request_invoice ( payer_pubkey ( ) )
1027
+ . build_unchecked ( )
1028
+ . sign ( payer_sign) . unwrap ( ) ;
1029
+
1030
+ let mut buffer = Vec :: new ( ) ;
1031
+ invoice_request. write ( & mut buffer) . unwrap ( ) ;
1032
+
1033
+ match InvoiceRequest :: try_from ( buffer) {
1034
+ Ok ( _) => panic ! ( "expected error" ) ,
1035
+ Err ( e) => assert_eq ! ( e, ParseError :: InvalidSemantics ( SemanticError :: MissingQuantity ) ) ,
1036
+ }
1037
+ }
1038
+
1039
+ #[ test]
1040
+ fn parses_invoice_request_with_payer_id ( ) {
1041
+ let invoice_request = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
1042
+ . amount_msats ( 1000 )
1043
+ . build ( ) . unwrap ( )
1044
+ . request_invoice ( payer_pubkey ( ) )
1045
+ . build ( ) . unwrap ( )
1046
+ . sign ( payer_sign) . unwrap ( ) ;
1047
+
1048
+ let mut buffer = Vec :: new ( ) ;
1049
+ invoice_request. write ( & mut buffer) . unwrap ( ) ;
1050
+
1051
+ if let Err ( e) = InvoiceRequest :: try_from ( buffer) {
1052
+ panic ! ( "error parsing invoice_request: {:?}" , e) ;
1053
+ }
1054
+
1055
+ let offer = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
1056
+ . amount_msats ( 1000 )
1057
+ . build ( ) . unwrap ( ) ;
1058
+ let mut unsigned_invoice_request = offer. request_invoice ( payer_pubkey ( ) ) . build ( ) . unwrap ( ) ;
1059
+ let mut tlv_stream = unsigned_invoice_request. invoice_request . as_tlv_stream ( ) ;
1060
+ tlv_stream. 2 . payer_id = None ;
1061
+
1062
+ let mut buffer = Vec :: new ( ) ;
1063
+ tlv_stream. write ( & mut buffer) . unwrap ( ) ;
1064
+
1065
+ match InvoiceRequest :: try_from ( buffer) {
1066
+ Ok ( _) => panic ! ( "expected error" ) ,
1067
+ Err ( e) => assert_eq ! ( e, ParseError :: InvalidSemantics ( SemanticError :: MissingPayerId ) ) ,
1068
+ }
1069
+ }
1070
+
1071
+ #[ test]
1072
+ fn fails_parsing_invoice_request_with_missing_node_id ( ) {
1073
+ let offer = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
1074
+ . amount_msats ( 1000 )
1075
+ . build ( ) . unwrap ( ) ;
1076
+ let mut unsigned_invoice_request = offer. request_invoice ( payer_pubkey ( ) ) . build ( ) . unwrap ( ) ;
1077
+ let mut tlv_stream = unsigned_invoice_request. invoice_request . as_tlv_stream ( ) ;
1078
+ tlv_stream. 1 . node_id = None ;
1079
+
1080
+ let mut buffer = Vec :: new ( ) ;
1081
+ tlv_stream. write ( & mut buffer) . unwrap ( ) ;
1082
+
1083
+ match InvoiceRequest :: try_from ( buffer) {
1084
+ Ok ( _) => panic ! ( "expected error" ) ,
1085
+ Err ( e) => {
1086
+ assert_eq ! ( e, ParseError :: InvalidSemantics ( SemanticError :: MissingSigningPubkey ) ) ;
1087
+ } ,
1088
+ }
1089
+ }
1090
+
1091
+ #[ test]
1092
+ fn fails_parsing_invoice_request_with_invalid_signature ( ) {
1093
+ let mut invoice_request = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
1094
+ . amount_msats ( 1000 )
1095
+ . build ( ) . unwrap ( )
1096
+ . request_invoice ( payer_pubkey ( ) )
1097
+ . build ( ) . unwrap ( )
1098
+ . sign ( payer_sign) . unwrap ( ) ;
1099
+ let last_signature_byte = invoice_request. bytes . last_mut ( ) . unwrap ( ) ;
1100
+ * last_signature_byte = last_signature_byte. wrapping_add ( 1 ) ;
1101
+
1102
+ let mut buffer = Vec :: new ( ) ;
1103
+ invoice_request. write ( & mut buffer) . unwrap ( ) ;
1104
+
1105
+ match InvoiceRequest :: try_from ( buffer) {
1106
+ Ok ( _) => panic ! ( "expected error" ) ,
1107
+ Err ( e) => {
1108
+ assert_eq ! ( e, ParseError :: InvalidSignature ( secp256k1:: Error :: InvalidSignature ) ) ;
1109
+ } ,
1110
+ }
1111
+ }
1112
+
795
1113
#[ test]
796
1114
fn fails_parsing_invoice_request_with_extra_tlv_records ( ) {
797
1115
let secp_ctx = Secp256k1 :: new ( ) ;
0 commit comments