@@ -1525,6 +1525,97 @@ mod test {
15251525 assert ! ( new_signed. check_signature( ) ) ;
15261526 }
15271527
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+
15281619 #[ test]
15291620 fn test_builder_amount ( ) {
15301621 use :: * ;
0 commit comments