Skip to content

Commit 3f2ed45

Browse files
committed
Offer parsing tests
Test semantic errors when parsing offer bytes.
1 parent d64e736 commit 3f2ed45

File tree

1 file changed

+181
-1
lines changed

1 file changed

+181
-1
lines changed

lightning/src/offers/offer.rs

+181-1
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ mod tests {
588588
use core::time::Duration;
589589
use ln::features::OfferFeatures;
590590
use ln::msgs::MAX_VALUE_MSAT;
591-
use offers::parse::SemanticError;
591+
use offers::parse::{ParseError, SemanticError};
592592
use onion_message::{BlindedHop, BlindedPath};
593593
use util::ser::Writeable;
594594
use util::string::PrintableString;
@@ -958,6 +958,186 @@ mod tests {
958958
Err(e) => assert_eq!(e, SemanticError::InvalidQuantity),
959959
}
960960
}
961+
962+
#[test]
963+
fn parses_offer_with_chains() {
964+
let offer = OfferBuilder::new("foo".into(), pubkey(42))
965+
.chain(Network::Bitcoin)
966+
.chain(Network::Testnet)
967+
.build()
968+
.unwrap();
969+
if let Err(e) = offer.to_string().parse::<Offer>() {
970+
panic!("error parsing offer: {:?}", e);
971+
}
972+
973+
let unsupported_chain = ChainHash::from(&[42; 32][..]);
974+
let mut builder = OfferBuilder::new("foo".into(), pubkey(42));
975+
builder.offer.chains = Some(vec![unsupported_chain]);
976+
977+
let offer = builder.build().unwrap();
978+
match offer.to_string().parse::<Offer>() {
979+
Ok(_) => panic!("expected error"),
980+
Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::UnsupportedChain)),
981+
}
982+
}
983+
984+
#[test]
985+
fn parses_offer_with_amount() {
986+
let offer = OfferBuilder::new("foo".into(), pubkey(42))
987+
.amount(Amount::Bitcoin { amount_msats: 1000 })
988+
.build()
989+
.unwrap();
990+
if let Err(e) = offer.to_string().parse::<Offer>() {
991+
panic!("error parsing offer: {:?}", e);
992+
}
993+
994+
let mut tlv_stream = offer.as_tlv_stream();
995+
tlv_stream.currency = Some(b"USD");
996+
997+
let mut encoded_offer = Vec::new();
998+
tlv_stream.write(&mut encoded_offer).unwrap();
999+
1000+
match Offer::try_from(encoded_offer) {
1001+
Ok(_) => panic!("expected error"),
1002+
Err(e) => {
1003+
assert_eq!(e, ParseError::InvalidSemantics(SemanticError::UnsupportedCurrency));
1004+
},
1005+
}
1006+
1007+
let mut tlv_stream = offer.as_tlv_stream();
1008+
tlv_stream.amount = None;
1009+
tlv_stream.currency = Some(b"USD");
1010+
1011+
let mut encoded_offer = Vec::new();
1012+
tlv_stream.write(&mut encoded_offer).unwrap();
1013+
1014+
match Offer::try_from(encoded_offer) {
1015+
Ok(_) => panic!("expected error"),
1016+
Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingAmount)),
1017+
}
1018+
}
1019+
1020+
#[test]
1021+
fn parses_offer_with_description() {
1022+
let offer = OfferBuilder::new("foo".into(), pubkey(42)).build().unwrap();
1023+
if let Err(e) = offer.to_string().parse::<Offer>() {
1024+
panic!("error parsing offer: {:?}", e);
1025+
}
1026+
1027+
let mut tlv_stream = offer.as_tlv_stream();
1028+
tlv_stream.description = None;
1029+
1030+
let mut encoded_offer = Vec::new();
1031+
tlv_stream.write(&mut encoded_offer).unwrap();
1032+
1033+
match Offer::try_from(encoded_offer) {
1034+
Ok(_) => panic!("expected error"),
1035+
Err(e) => {
1036+
assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingDescription));
1037+
},
1038+
}
1039+
}
1040+
1041+
#[test]
1042+
fn parses_offer_with_paths() {
1043+
let offer = OfferBuilder::new("foo".into(), pubkey(42))
1044+
.path(BlindedPath {
1045+
introduction_node_id: pubkey(40),
1046+
blinding_point: pubkey(41),
1047+
blinded_hops: vec![
1048+
BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 43] },
1049+
BlindedHop { blinded_node_id: pubkey(44), encrypted_payload: vec![0; 44] },
1050+
],
1051+
})
1052+
.path(BlindedPath {
1053+
introduction_node_id: pubkey(40),
1054+
blinding_point: pubkey(41),
1055+
blinded_hops: vec![
1056+
BlindedHop { blinded_node_id: pubkey(45), encrypted_payload: vec![0; 45] },
1057+
BlindedHop { blinded_node_id: pubkey(46), encrypted_payload: vec![0; 46] },
1058+
],
1059+
})
1060+
.build()
1061+
.unwrap();
1062+
if let Err(e) = offer.to_string().parse::<Offer>() {
1063+
panic!("error parsing offer: {:?}", e);
1064+
}
1065+
1066+
let mut builder = OfferBuilder::new("foo".into(), pubkey(42));
1067+
builder.offer.paths = Some(vec![]);
1068+
1069+
let offer = builder.build().unwrap();
1070+
match offer.to_string().parse::<Offer>() {
1071+
Ok(_) => panic!("expected error"),
1072+
Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPaths)),
1073+
}
1074+
}
1075+
1076+
#[test]
1077+
fn parses_offer_with_quantity() {
1078+
let five = NonZeroU64::new(5).unwrap();
1079+
let ten = NonZeroU64::new(10).unwrap();
1080+
1081+
let offer = OfferBuilder::new("foo".into(), pubkey(42))
1082+
.quantity_range(five..=ten)
1083+
.build()
1084+
.unwrap();
1085+
if let Err(e) = offer.to_string().parse::<Offer>() {
1086+
panic!("error parsing offer: {:?}", e);
1087+
}
1088+
1089+
// quantity_min < 1
1090+
let mut builder = OfferBuilder::new("foo".into(), pubkey(42));
1091+
builder.offer.quantity_min = Some(0);
1092+
1093+
let offer = builder.build().unwrap();
1094+
match offer.to_string().parse::<Offer>() {
1095+
Ok(_) => panic!("expected error"),
1096+
Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidQuantity)),
1097+
}
1098+
1099+
// quantity_min > quantity_max
1100+
let mut tlv_stream = offer.as_tlv_stream();
1101+
tlv_stream.quantity_min = Some(5);
1102+
tlv_stream.quantity_max = Some(4);
1103+
1104+
let mut encoded_offer = Vec::new();
1105+
tlv_stream.write(&mut encoded_offer).unwrap();
1106+
1107+
match Offer::try_from(encoded_offer) {
1108+
Ok(_) => panic!("expected error"),
1109+
Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidQuantity)),
1110+
}
1111+
1112+
// quantity_max < 1
1113+
tlv_stream.quantity_min = None;
1114+
tlv_stream.quantity_max = Some(0);
1115+
1116+
let mut encoded_offer = Vec::new();
1117+
tlv_stream.write(&mut encoded_offer).unwrap();
1118+
1119+
match Offer::try_from(encoded_offer) {
1120+
Ok(_) => panic!("expected error"),
1121+
Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidQuantity)),
1122+
}
1123+
}
1124+
1125+
#[test]
1126+
fn parses_offer_with_node_id() {
1127+
let offer = OfferBuilder::new("foo".into(), pubkey(42)).build().unwrap();
1128+
if let Err(e) = offer.to_string().parse::<Offer>() {
1129+
panic!("error parsing offer: {:?}", e);
1130+
}
1131+
1132+
let mut builder = OfferBuilder::new("foo".into(), pubkey(42));
1133+
builder.offer.signing_pubkey = None;
1134+
1135+
let offer = builder.build().unwrap();
1136+
match offer.to_string().parse::<Offer>() {
1137+
Ok(_) => panic!("expected error"),
1138+
Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingNodeId)),
1139+
}
1140+
}
9611141
}
9621142

9631143
#[cfg(test)]

0 commit comments

Comments
 (0)