zpay32: add functional opt to error out on unknown feature bit
This commit adds two functional options to the zpay32.Decode function. `WithKnownFeatureBits` allows the caller to overwrite the default set of known feature bits used by the function. `WithErrorOnUnknownFeatureBit` allows the caller to instruct the function to error out if the invoice that is decoded contaijns unknown feature bits. We then use this new error-out option from the `rpcServer`'s `extractPaymentIntent` method.
This commit is contained in:
3 files changed
+133
-4
No files matched your search
+64
-3
@@ -17,10 +17,53 @@ import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// DecodeOption is a type that can be used to supply functional options to the
|
||||
// Decode function.
|
||||
type DecodeOption func(*decodeOptions)
|
||||
|
||||
// WithKnownFeatureBits is a functional option that overwrites the set of
|
||||
// known feature bits. If not set, then LND's lnwire.Features variable will be
|
||||
// used by default.
|
||||
func WithKnownFeatureBits(features map[lnwire.FeatureBit]string) DecodeOption {
|
||||
return func(options *decodeOptions) {
|
||||
options.knownFeatureBits = features
|
||||
}
|
||||
}
|
||||
|
||||
// WithErrorOnUnknownFeatureBit is a functional option that will cause the
|
||||
// Decode function to return an error if the decoded invoice contains an unknown
|
||||
// feature bit.
|
||||
func WithErrorOnUnknownFeatureBit() DecodeOption {
|
||||
return func(options *decodeOptions) {
|
||||
options.errorOnUnknownFeature = true
|
||||
}
|
||||
}
|
||||
|
||||
// decodeOptions holds the set of Decode options.
|
||||
type decodeOptions struct {
|
||||
knownFeatureBits map[lnwire.FeatureBit]string
|
||||
errorOnUnknownFeature bool
|
||||
}
|
||||
|
||||
// newDecodeOptions constructs the default decodeOptions struct.
|
||||
func newDecodeOptions() *decodeOptions {
|
||||
return &decodeOptions{
|
||||
knownFeatureBits: lnwire.Features,
|
||||
errorOnUnknownFeature: false,
|
||||
}
|
||||
}
|
||||
|
||||
// Decode parses the provided encoded invoice and returns a decoded Invoice if
|
||||
// it is valid by BOLT-0011 and matches the provided active network.
|
||||
func Decode(invoice string, net *chaincfg.Params) (*Invoice, error) {
|
||||
decodedInvoice := Invoice{}
|
||||
func Decode(invoice string, net *chaincfg.Params, opts ...DecodeOption) (
|
||||
*Invoice, error) {
|
||||
|
||||
options := newDecodeOptions()
|
||||
for _, o := range opts {
|
||||
o(options)
|
||||
}
|
||||
|
||||
var decodedInvoice Invoice
|
||||
|
||||
// Before bech32 decoding the invoice, make sure that it is not too large.
|
||||
// This is done as an anti-DoS measure since bech32 decoding is expensive.
|
||||
@@ -134,7 +177,7 @@ func Decode(invoice string, net *chaincfg.Params) (*Invoice, error) {
|
||||
// If no feature vector was decoded, populate an empty one.
|
||||
if decodedInvoice.Features == nil {
|
||||
decodedInvoice.Features = lnwire.NewFeatureVector(
|
||||
nil, lnwire.Features,
|
||||
nil, options.knownFeatureBits,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -144,6 +187,24 @@ func Decode(invoice string, net *chaincfg.Params) (*Invoice, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if options.errorOnUnknownFeature {
|
||||
// Make sure that we understand all the required feature bits
|
||||
// in the invoice.
|
||||
unknownFeatureBits := decodedInvoice.Features.
|
||||
UnknownRequiredFeatures()
|
||||
|
||||
if len(unknownFeatureBits) > 0 {
|
||||
errStr := fmt.Sprintf("invoice contains " +
|
||||
"unknown feature bits:")
|
||||
|
||||
for _, bit := range unknownFeatureBits {
|
||||
errStr += fmt.Sprintf(" %d,", bit)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf(strings.TrimRight(errStr, ","))
|
||||
}
|
||||
}
|
||||
|
||||
return &decodedInvoice, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user