Skip to content

Commit 7a918d8

Browse files
committed
Offer parsing tests
Test semantic errors when parsing offer bytes.
1 parent 3137eb9 commit 7a918d8

File tree

1 file changed

+181
-1
lines changed

1 file changed

+181
-1
lines changed

lightning/src/offers/offer.rs

Lines changed: 181 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ mod tests {
590590
use core::time::Duration;
591591
use ln::features::OfferFeatures;
592592
use ln::msgs::MAX_VALUE_MSAT;
593-
use offers::parse::SemanticError;
593+
use offers::parse::{ParseError, SemanticError};
594594
use onion_message::{BlindedHop, BlindedPath};
595595
use util::ser::Writeable;
596596

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

9641144
#[cfg(test)]

0 commit comments

Comments
 (0)