@@ -1525,6 +1525,97 @@ mod test {
1525
1525
assert ! ( new_signed. check_signature( ) ) ;
1526
1526
}
1527
1527
1528
+ #[ test]
1529
+ fn test_check_feature_bits ( ) {
1530
+ use TaggedField :: * ;
1531
+ use lightning:: ln:: features:: InvoiceFeatures ;
1532
+ use secp256k1:: Secp256k1 ;
1533
+ use secp256k1:: key:: SecretKey ;
1534
+ use { RawInvoice , RawHrp , RawDataPart , Currency , Sha256 , PositiveTimestamp , Invoice ,
1535
+ SemanticError } ;
1536
+
1537
+ let private_key = SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ;
1538
+ let payment_secret = lightning:: ln:: PaymentSecret ( [ 21 ; 32 ] ) ;
1539
+ let invoice_template = RawInvoice {
1540
+ hrp : RawHrp {
1541
+ currency : Currency :: Bitcoin ,
1542
+ raw_amount : None ,
1543
+ si_prefix : None ,
1544
+ } ,
1545
+ data : RawDataPart {
1546
+ timestamp : PositiveTimestamp :: from_unix_timestamp ( 1496314658 ) . unwrap ( ) ,
1547
+ tagged_fields : vec ! [
1548
+ PaymentHash ( Sha256 ( sha256:: Hash :: from_hex(
1549
+ "0001020304050607080900010203040506070809000102030405060708090102"
1550
+ ) . unwrap( ) ) ) . into( ) ,
1551
+ Description (
1552
+ :: Description :: new(
1553
+ "Please consider supporting this project" . to_owned( )
1554
+ ) . unwrap( )
1555
+ ) . into( ) ,
1556
+ ] ,
1557
+ } ,
1558
+ } ;
1559
+
1560
+ // Missing features
1561
+ let invoice = {
1562
+ let mut invoice = invoice_template. clone ( ) ;
1563
+ invoice. data . tagged_fields . push ( PaymentSecret ( payment_secret) . into ( ) ) ;
1564
+ invoice. sign :: < _ , ( ) > ( |hash| Ok ( Secp256k1 :: new ( ) . sign_recoverable ( hash, & private_key) ) )
1565
+ } . unwrap ( ) ;
1566
+ assert_eq ! ( Invoice :: from_signed( invoice) , Err ( SemanticError :: InvalidFeatures ) ) ;
1567
+
1568
+ // Missing feature bits
1569
+ let invoice = {
1570
+ let mut invoice = invoice_template. clone ( ) ;
1571
+ invoice. data . tagged_fields . push ( PaymentSecret ( payment_secret) . into ( ) ) ;
1572
+ invoice. data . tagged_fields . push ( Features ( InvoiceFeatures :: empty ( ) ) . into ( ) ) ;
1573
+ invoice. sign :: < _ , ( ) > ( |hash| Ok ( Secp256k1 :: new ( ) . sign_recoverable ( hash, & private_key) ) )
1574
+ } . unwrap ( ) ;
1575
+ assert_eq ! ( Invoice :: from_signed( invoice) , Err ( SemanticError :: InvalidFeatures ) ) ;
1576
+
1577
+ // Including payment secret and feature bits
1578
+ let invoice = {
1579
+ let mut invoice = invoice_template. clone ( ) ;
1580
+ invoice. data . tagged_fields . push ( PaymentSecret ( payment_secret) . into ( ) ) ;
1581
+ invoice. data . tagged_fields . push ( Features ( InvoiceFeatures :: known ( ) ) . into ( ) ) ;
1582
+ invoice. sign :: < _ , ( ) > ( |hash| Ok ( Secp256k1 :: new ( ) . sign_recoverable ( hash, & private_key) ) )
1583
+ } . unwrap ( ) ;
1584
+ assert ! ( Invoice :: from_signed( invoice) . is_ok( ) ) ;
1585
+
1586
+ // No payment secret or features
1587
+ let invoice = {
1588
+ let invoice = invoice_template. clone ( ) ;
1589
+ invoice. sign :: < _ , ( ) > ( |hash| Ok ( Secp256k1 :: new ( ) . sign_recoverable ( hash, & private_key) ) )
1590
+ } . unwrap ( ) ;
1591
+ assert ! ( Invoice :: from_signed( invoice) . is_ok( ) ) ;
1592
+
1593
+ // No payment secret or feature bits
1594
+ let invoice = {
1595
+ let mut invoice = invoice_template. clone ( ) ;
1596
+ invoice. data . tagged_fields . push ( Features ( InvoiceFeatures :: empty ( ) ) . into ( ) ) ;
1597
+ invoice. sign :: < _ , ( ) > ( |hash| Ok ( Secp256k1 :: new ( ) . sign_recoverable ( hash, & private_key) ) )
1598
+ } . unwrap ( ) ;
1599
+ assert ! ( Invoice :: from_signed( invoice) . is_ok( ) ) ;
1600
+
1601
+ // Missing payment secret
1602
+ let invoice = {
1603
+ let mut invoice = invoice_template. clone ( ) ;
1604
+ invoice. data . tagged_fields . push ( Features ( InvoiceFeatures :: known ( ) ) . into ( ) ) ;
1605
+ invoice. sign :: < _ , ( ) > ( |hash| Ok ( Secp256k1 :: new ( ) . sign_recoverable ( hash, & private_key) ) )
1606
+ } . unwrap ( ) ;
1607
+ assert_eq ! ( Invoice :: from_signed( invoice) , Err ( SemanticError :: InvalidFeatures ) ) ;
1608
+
1609
+ // Multiple payment secrets
1610
+ let invoice = {
1611
+ let mut invoice = invoice_template. clone ( ) ;
1612
+ invoice. data . tagged_fields . push ( PaymentSecret ( payment_secret) . into ( ) ) ;
1613
+ invoice. data . tagged_fields . push ( PaymentSecret ( payment_secret) . into ( ) ) ;
1614
+ invoice. sign :: < _ , ( ) > ( |hash| Ok ( Secp256k1 :: new ( ) . sign_recoverable ( hash, & private_key) ) )
1615
+ } . unwrap ( ) ;
1616
+ assert_eq ! ( Invoice :: from_signed( invoice) , Err ( SemanticError :: MultiplePaymentSecrets ) ) ;
1617
+ }
1618
+
1528
1619
#[ test]
1529
1620
fn test_builder_amount ( ) {
1530
1621
use :: * ;
0 commit comments