@@ -1525,6 +1525,101 @@ 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| {
1565
+ Ok ( Secp256k1 :: new ( ) . sign_recoverable ( hash, & private_key) )
1566
+ } ) . unwrap ( )
1567
+ } ;
1568
+ assert_eq ! ( Invoice :: from_signed( invoice) , Err ( SemanticError :: InvalidFeatures ) ) ;
1569
+
1570
+ // Missing feature bits
1571
+ let invoice = {
1572
+ let mut invoice = invoice_template. clone ( ) ;
1573
+ invoice. data . tagged_fields . push ( PaymentSecret ( payment_secret) . into ( ) ) ;
1574
+ invoice. data . tagged_fields . push ( Features ( InvoiceFeatures :: empty ( ) ) . into ( ) ) ;
1575
+ invoice. sign :: < _ , ( ) > ( |hash| {
1576
+ Ok ( Secp256k1 :: new ( ) . sign_recoverable ( hash, & private_key) )
1577
+ } ) . unwrap ( )
1578
+ } ;
1579
+ assert_eq ! ( Invoice :: from_signed( invoice) , Err ( SemanticError :: InvalidFeatures ) ) ;
1580
+
1581
+ // Including payment secret and feature bits
1582
+ let invoice = {
1583
+ let mut invoice = invoice_template. clone ( ) ;
1584
+ invoice. data . tagged_fields . push ( PaymentSecret ( payment_secret) . into ( ) ) ;
1585
+ invoice. data . tagged_fields . push ( Features ( InvoiceFeatures :: known ( ) ) . into ( ) ) ;
1586
+ invoice. sign :: < _ , ( ) > ( |hash| {
1587
+ Ok ( Secp256k1 :: new ( ) . sign_recoverable ( hash, & private_key) )
1588
+ } ) . unwrap ( )
1589
+ } ;
1590
+ assert ! ( Invoice :: from_signed( invoice) . is_ok( ) ) ;
1591
+
1592
+ // No payment secret or features
1593
+ let invoice = {
1594
+ let invoice = invoice_template. clone ( ) ;
1595
+ invoice. sign :: < _ , ( ) > ( |hash| {
1596
+ Ok ( Secp256k1 :: new ( ) . sign_recoverable ( hash, & private_key) )
1597
+ } ) . unwrap ( )
1598
+ } ;
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| {
1606
+ Ok ( Secp256k1 :: new ( ) . sign_recoverable ( hash, & private_key) )
1607
+ } ) . unwrap ( )
1608
+ } ;
1609
+ assert_eq ! ( Invoice :: from_signed( invoice) , Err ( SemanticError :: InvalidFeatures ) ) ;
1610
+
1611
+ // Multiple payment secrets
1612
+ let invoice = {
1613
+ let mut invoice = invoice_template. clone ( ) ;
1614
+ invoice. data . tagged_fields . push ( PaymentSecret ( payment_secret) . into ( ) ) ;
1615
+ invoice. data . tagged_fields . push ( PaymentSecret ( payment_secret) . into ( ) ) ;
1616
+ invoice. sign :: < _ , ( ) > ( |hash| {
1617
+ Ok ( Secp256k1 :: new ( ) . sign_recoverable ( hash, & private_key) )
1618
+ } ) . unwrap ( )
1619
+ } ;
1620
+ assert_eq ! ( Invoice :: from_signed( invoice) , Err ( SemanticError :: MultiplePaymentSecrets ) ) ;
1621
+ }
1622
+
1528
1623
#[ test]
1529
1624
fn test_builder_amount ( ) {
1530
1625
use :: * ;
0 commit comments