@@ -1525,6 +1525,101 @@ 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| {
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+
15281623 #[ test]
15291624 fn test_builder_amount ( ) {
15301625 use :: * ;
0 commit comments