Adds a utility function to be able to compute the outgoing routing
amount from the incoming amount by taking inbound and outbound fees into
account. The discussion was contributed by user feelancer21, see
f6f05fa930.
We shift the duty of determining the policies to the backward pass as
the forward pass will only be responsible for finding the corrected
receiver amount.
Note that this is not a pure refactor as demonstrated in the test, as
the forward pass doesn't select new policies anymore, which is less
flexible and doesn't lead to the highest possible receiver amount. This
is however neccessary as we otherwise won't be able to compute
forwarding amounts involving inbound fees and this edge case is unlikely
to occur, because we search for a min amount for a route that was most
likely constructed for a larger amount.
We split up the functionality in getRouteUnifiers into checking that all
edges exist via getEdgeUnifiers and then add a backward pass that will
be responsible for determining the sender amount.
We remove the node pub key from the error string, as in route building
this is duplicate info, which can be determined from the input keys,
further it's not available in the backward pass anymore.
We refactor the BuildRoute test to use the require library and add a
test case for a max HTLC violation on the last hop.
This commit introduces more sophisticated code for selecting dummy hop
policy values for dummy hops in blinded paths.
For the case where the path does contain real hops, the dummy hop policy
values are derived by taking the average of those hop polices. For the
case where there are no real hops (in other words, we are the
introduction node), we use the default policy values used for normal
ChannelUpdates but then for the MaxHTLC value, we take the average of
all our open channel capacities.
Setting default values for the channel opening fee rate is already
done elsewhere therefore we remove on of those checks and return
an error if no fee rate is specified.
Add an itest that tests the addition of dummy hops to a blinded path. By
testing that invoices containing such a path can be paid, it also tests
the peeling of dummy hops by the receiver.
Make various sender side adjustments so that a sender is able to send an
MP payment to a single blinded path without actually including an MPP
record in the payment.
Update one of the route blinding itests to do a full end-to-end test
where the recipient generates and invoice with a blinded path and the
sender just provides that invoice to SendPayment.
The tests also covers the edge case where the recipient is the
introduction node.
The route blinding itests are now updated so that recipient logic is
tested. The creation of a blinded route is also now done through the
AddInvoice API instead of manually.
If a blinded path payload contains a signal that the following hop on
the path is a dummy hop, then we iteratively peel the dummy hops until
the final payload is reached.
We've covered all the logic for building a blinded path to ourselves and
putting that into an invoice - so now we start preparing to actually be
able to recognise the incoming payment as one from a blinded path we
created.
The incoming update_add_htlc will have an `encrypted_recipient_data`
blob for us that we would have put in the original invoice. From this we
extract the PathID which we wrote. We consider this the payment address
and we use this to derive the associated invoice location.
Blinded path payments will not include MPP records, so the payment
address and total payment amount must be gleaned from the pathID and new
totalAmtMsat onion field respectively.
This commit only covers the final hop payload of a hop in a blinded
path. Dummy hops will be handled in the following commit.
We further break up the extracTLVPayload into more modular pieces. The
pieces are structured in such a way as to prepare for extracTLVPayload
being called in a recursive manner from within
`deriveBlindedRouteForwardingInfo` when we add the logic for handling
dummy hops in a later commit. With this refactor, we completey remove
the BlindingKit's DecryptAndValidateFwdInfo method.
In this refactor commit, we extract all the steps from extractTLVPayload
that have to do with parsing the payload from the sender and verifying
the presence of various fields from the sender.
In preparation for calling the TLV payload parsing logic recursively for
when we need to peel dummy hops from an onion, this commit creates a new
extractTLVPayload function. This is a pure refactor.
Expose the ability to add blinded paths to an invoice. Also expose
various configuration values.
We also let the lncfg.Invoices struct satisfy the Validator interface so
that we can verify all its config values in one place.
Add a `FindBlindedPaths` method to the `ChannelRouter` which will use
the new `findBlindedPaths` function to get a set of candidate blinded
path routes. It then uses mission control to select the best of these
paths.
Note that as of this commit, the MC data we get from these queries won't
mean much since we wont have data about a channel in the direction
towards us. But we do this now in preparation for a future PR which will
start writing mission control success pairs for successful receives from
blinded route paths.
This commit adds a new function, `findBlindedPaths`, that does a depth
first search from the target node to find a set of blinded paths to the
target node given the set of restrictions. This function will select and
return any candidate path. A candidate path is a path to the target node
with a size determined by the given hop number constraints where all the
nodes on the path signal the route blinding feature _and_ the
introduction node for the path has more than one public channel. Any
filtering of paths based on payment value or success probabilities is
left to the caller.
Here we add a new `Blind` option to the `AddInvoiceData` which will
signal that the new invoice should encode a blinded route.
Certain other changes are also made in the case that this invoice
contains a blinded route:
1) the payment address/secret no longer needs to be in the invoice
itself since it will be put in the `PathID` recored of the encrypted
recipient record for our hop.
2) When we sign the invoice, we now use an ephemeral key since we dont
want the sender to be able to derive our real node pub key from the
invoice signature.
3) The invoice's FinalCLTV field should be zero for blinded invoices
since the CLTV delta info will be communicated in the accumulated
route policy values.
This commit adds all the logic for building a blinded path (from a given
route) and packaging it up in a zpay32.BlindedPaymentPath struct so that
it is ready for adding to an invoice. It also includes logic for padding
a path with dummy hops.
Note that in this commit, the logic for choosing an actual path to us
that can then be used in a blinded path is abstracted away. This logic
will be fleshed out in a future commit.
This commit adds a helper function that will be used to adjust a hops
policy values by certain given increase and decrease multipliers. This
will be used in blinded paths to give policy values some buffer to avoid
easy probing of blinded paths.
This commit adds a function that can be used to compute the accumulated
path policy for a blinded path as defined in the spec:
db278ab9b2/04-onion-routing.md (L255)
This commit adds a helper function called `padHopInfo` along with a test
for it. This function will be used later on when building a blinded
path. It is used to ensure that all encrypted blobs of a blinded path
that we construct are padded to the same size.
We need a new feature bit for BOLT11 invoices in order to indicate that
they contain the new blinded path tagged field. Tagged fields pre-date
TLV and so nodes who dont understand them will simply skip them.
Therefore the feature bit helps them to fail fast.
Previously we may get a floor feerate when calling `EstimateFeePerKW`
due to the fee estimator not finishing its startup process, which gives
us an empty fee map.
This is now fixed to return an error if the estimator is not started.