The btcsuite/fastsha256 registers itself in the crypto package of
golang as a replacement for sha256. This causes problems in TLS1.3
connections that require the hash implementations to be serializable
and results in the "tls: internal error: failed to clone hash" error.
By removing all uses of the library we fix that error.
This commit extends the link with a new synchronous delivery point for
local UpdateAddHTLC messages. The switch method SendHTLC is updated to
use this delivery point and thereby becomes a synchronous call.
For MPP payments, synchronous hand-off is important. Otherwise the next
pathfinding round could start without the channel balance updated yet.
Modifies some of the older mailbox tests that were left untouched as of
PR #4174 to use the new mailbox test context. This ensures that the
config members of each mailbox's config are properly initialized. In
certain instances where travis is slow, this would cause test panics.
This commit adds a PendingCommitTicker to the link config, which allows
us to control how quickly we fail the link if the commitment dance
stalls. Now that the mailbox has the ability to cancel packets, when the
link fails it will reset the mailbox packets on exit, forcing a
reevaluation of the HTLCs against their mailbox expiries.
Now that packet failure is handled by the mailbox, we can now enforce
a delivery deadline and fail the packet if it the deadilne is exceeded.
This gives senders quicker feedback about tried routes, and allows them
to try alternative paths to the destination in the meantime.
This commit splits the packet courier internally into two distinct
queues, one for adds and one for settles+fails. This allows us to
prioritize HTLCs that will clear the commitment transaction and make
space for adds. Previously this responsibility was handled by the
overflow queue.
This commit delays the advancement of the pktHead until after the
message has been delivered. This is a prepatory step, as in the future
we may fail to deliver the packet due to a deadline expiring.
This commit moves the current logic for sending failures out of the link
and into the mailbox in preparation for our failing delayed htlcs. We do
so because the mailbox may need to fail packets while the link is
offline, and needs to be able to complete the task without member
methods on the link.
This commit removes the overflowQueue from the link. We do so in order
to promote better UX for senders, so that HTLCs are failed faster when
the commitment is full. This gives the sender the opportunity to try
another, more open path, rather than perceive the HTLC as being stuck.
At the same time, we remove the total number of active goroutines in lnd
by a factor of N where N is the number of active channels.
This commit is preparation for the test added in the subsequent commit.
We modify makeHoldPayment to return any failures direectly when trying
to add an HTLC to the switch. This lets us know that the HTLC was indeed
sent without failure when the method returns.
A following commits will move/modify callsites of AckPacket, Start, and
Stop, none of which use the return value and ultimately cause the linter
to complain. However, none of these in-memory operations can fail so we
just remove the returned errors altogether.
The linter complains about not checking the return value from
WipeChannel in certain places. Instead of checking we simply remove the
returned error because the in-memory modifications cannot fail.
This commit changes the switch to only log an error if update_fail_htlc
comes in and closeCircuit returns ErrUnknownCircuit. Rationale
being that only settles should hit this code path, anything else
is a result of a link flap and should be treated as an error.
This commit modifies updateCommitTx to error with ErrLinkShuttingDown
when we try to send a ContractUpdate on the htlcUpdates chan and the
link has closed the quit chan. It also changes the order of the call
to ackDownStreamPackets and contract update call for consistency since
the packets should be acknowledged before the link goes down.
This commit changes the fallback in NextLocalHtlcIndex to
RemoteCommitment since the LocalHtlcIndex field lags behind
on the LocalCommitment. Without this bug fix, open circuits
would get prematurely trimmed, resulting in more erroneous
logs. A test case is included to check that the fix works.
This commit adds link failure notifications for failures which occur
on our incoming link. These failures may be receives which we failed or
forwards which we could not parse.
Add notifications for local initiated sends settles and forwarding
failures. As with link failures, local send settles and forwarding
failures are reported directly to the router so must have their own
notification handling.
Notify link failures for our own payments. Separate handling code is
required for local payment link failures because we do not pass these
failures back through the switch (like we do for link failures for
forwards), but rather send them straight back to the router. Our own
sends have the payment ID saved in the incoming htlc ID of the packet's
incoming circuit. This change replaces that value with for the sake
of consistent notifying of sends and receives from our node.
This commit adds notifications for htlcs which are forwarded through
our node. Forwards are notified when the htlc is added on our ougoing
link, settles when we send a settle message to the downstream peer.
If a failure occurs, we check whether it occurred at our node, then
notify a link or forwarding failure accordingly.
Note that this change also adds forward event notifications for sends
which are initiated by our node because the handling code for adding
a htlc which originates from our node is the same as that for handling
forwards. Htlcs for our locally initiated sends have our internal pid
set in the incoming htlcs id field, so we extract this value and notify
with a zero htlc id to be consistent with receives (which have zero
outgoing circuits). Subsequent settles or failures are not noitfied
for local sends in this commit, and will be handled in a follow up.
This commit sets more fields on the htlcPacket created to fail adding
a htlc packet to the switch for notification purposes. This new data is
copied by value from the original packet. The packet is then failed
back to the peer that forwarded us the packet, which is handled by
handledownstream packet. The values added to the packet are not used
in the handling of a failed packet.
In this commit, a htlcNotifier interface is added to allow for easy
unit testing. Instances of the HtlcNotifier are added to the server,
switch and link.
This commit adds a HTLCNotifier to htlcswitch which HTLC events
will be piped through to provide clients with subscriptions to
HTLC level events.
The event types added are forward events (which occur for sends
from and forwards through our node), forward failues (when a
send or forward fails down the line), settles for forwards or
receives to our node and link failures which occur when a htlc
is failed at our node (which may occur for a send, receive or
foreward).
Since we want to handle the edge case where paying the HTLC fee would
take the initiator below the reserve, we move the subtraction of the
reserve into availableBalance where this calculation will be performed.
This commit enables the user to specify he is not interested in
automatically close channels with pending payments that their
corresponding htlcs have timed-out.
By requiring a configurable grace period uptime of our node
before closing such channels, we give a chance to the other node to
properly cancel the htlc and avoid unnecessary on-chain transaction.
In mobile it is very important for the user experience as otherwise
channels will be force closed more frequently.
This commit adds LinkErrors with failure details to htlcs which fail on
our incoming link. This change is made with the intention of notifying
detailed htlc failure reasons in sendHTLCError. The FailureDetail
interface is implemented on FailureResolutionResults so that they can
directly be used to enrich LinkErrors. sendHtlcError is updated to
take a LinkError in preparation for the addition of a htlcnotifier
which will notify the detail of the error.
This commit adds a linkError field to track the value of failures
which occur at our node. This field is set when local payments or
multi hop htlcs fail in the switch or on our outgoing link. This
addition is required for the addition of a htlc notifier which will
notify these failures in handleDownstreamPacket.
The passing of link error to failAddPacket removes the need for an
additional error field, because the link error's failure detail will
contain any additional metadata. In the places where the failure detail
does not cover all the metadata that was previously supplied by addr
err, the error is logged before calling failAddPacket so that this
change does not reduce the amount of information we log.
Add a FailureDetail interface which allows us have different kinds of
failures for link errors. This interface will be used to cover failures
that occur when on invoice payment, because the errors have already
been enumerated in the invoices package.
Rename FailureDetail in a separate commit so that a FailureDetail
interface can be introduced in the following commit.
OutgoingFailureOnionDecode is renamed to OutgoingFailureDecodeError
to specifically indicate that we could not decode the wire
failure that our payment experienced.
This commit repalces the htlcResolution struct with an interface.
This interface is implemeted by failure, settle and accept resolution
structs. Only settles and fails are exported because the existing
code that handles htlc resolutions uses a nil resolution to indicate
that a htlc was accepted. The accept resolution is used internally
to report on the resolution result of the accepted htlc, but a nil
resolution is surfaced. Further refactoring of all the functions
that call NotifyExitHopHtlc to handle a htlc accept case (rather than
having a nil check) is required.
Add a CheckCircularForward function which detects packets which are
forwards over the same incoming and outgoing link, and errors if the
node is configured to disallow forwards of this nature. This check is
added to increase the cost of a liquidity lockup attack, because it
increases the length of the route required to lock up an individual
node's bandwidth. Since nodes are currently limited to 20 hops,
increasing the length of the route needed to lock up capital increases
the number of malicious payments an attacker will have to route, which
increases the capital requirement of the attack overall.
Update the ChannelLink interface to specifically
return the LinkError struct. This error implements
the ClearTextError interface, so will be picked
up as a routing realted error by the router.
With LinkErrors implemented, the switch now
returns a LinkError for all failures on our
incoming/outgoing link and ForwardingError when
the failure occurs down the line.
Update the type check used for checking local payment
failures to check on the ClearTextError interface rather
than on the ForwardingError type. This change prepares
for splitting payment errors up into Link and Forwarding
errors.
This change introduces a LinkError implementation
of the ClearTextError interface. This error is intended
to represent failures which occur on our incoming and
outgoing link when sending, receiving and forwarding
htlcs. Paired with ForwardingError, which is represents
failures that did not occur at our node, this error
covers all non-opaque errors that the switch experiences.
This commit adds a ClearTextError interface
which is implemented by non-opaque errors that
we know the underlying wire failure message for.
This interface is implemented by ForwardingErrors,
because we can fully decrypt the onion blob to
obtain the underlying failure reason. This interface
will also be implemented by errors which originate
at our node in following commits, because we know
the failure reason when we fail the htlc.
The lnwire interface is un-embedded in the
ForwardingError struct in favour of implementing
this interface. This change is made to protect
against accidental passing of a ForwardingError
to the wire, where the embedded FailureMessage
interface will present as wire failure but
will not serialize properly.
Add a constructor for the creation of forwarding errors.
A special constructor is added for the case where we have
an unknown wire failure, and must set a nil failure message.
We abstract away how keys are generated for the different channel types
types (currently tweak(less)).
Intention is that more of the logic that is unique for each commitment
type lives in commitment.go, making the channel state machine oblivious
to the keys and outputs being created on the commitment tx for a given
channel state.
This commit adds a getResolutionFailure function
which returns an appropriate wire failure based
on the outcome of a htlc resolution. It also updates
the MissionControlStore test to ensure that lnd
can handle failures which occur due to mpp timeout.
This commit moves handling of invoice not found
errors into NotifyExitHopHtlc and exposes a
resolution result to the calling functions. The
intention of this change is to make calling
functions as naive of the invoice registry's
mechanics as possible.
When NotifyExitHopHtlc is called and an invoice
is not found, calling functions can take action
based on the HtlcResolution's InvoiceNotFound
outcome rather than having to add a special error
check on every call to handle the error.
This commit adds the resolution result obtained
while updating an invoice in the registry to
htlcResolution. The field can be used by calling
functions to determine the outcome of the
update and act appropriately.
This commit renames HodlEvent to HtlcResolution
to better reflect the fact that the struct is
only used for htlc settles and cancels, and that
it is not specifically used for hodl invoices.
This commit adds InvoiceExpryWatcher which is a separate class that
receives new invoices (and existing ones upon restart) from InvoiceRegistry
and actively watches their expiry. When an invoice is expired
InvoiceExpiryWatcher will call into InvoiceRegistry to cancel the
invoice and by that notify all subscribers about the state change.
This commit is adapted from @Bluetegu's original
pull request #1462.
This commit reads an optional address to pay funds out to
from a user iniitiated close channel address. If the channel
already has a shutdown script set, the request will fail if
an address is provided. Otherwise, the cooperative close will
pay out to the address provided.
This commit restructures an invoice's ContractTerms to better encompass
the restrictions placed on settling. For instance, the final ctlv delta
and invoice expiry are moved from the main invoice body (where
additional metadata is stored). Additionally, it moves the State field
outside of the terms since it is rather metadata about the invoice
instead of any terms offered to the sender in the payment request.
Tlv is used more widely in lnd than just for the onion payload. This
commit isolated the protocol-specific odd/even logic, so that tlv can be
used freely elsewhere. An example of this use is db serialization.
With the introduction of additional payload fields for mpp, it becomes
a necessity to have their values available in the on-chain resolution
flow. The incoming contest resolver notifies the invoice registry of the
arrival of a payment and needs to supply all parameters for the registry
to validate the htlc.
Replace logCommitTick as a way to deal with revocation window exhaustion
by retrying to update the commit tx when the remote revocation is
received.
The rationale is that the revocation window always opens up because of a
revoke message that is received from the other party. It is therefore
not necessary to set a timer for this. The reception of the revoke
message is the trigger to send a new commit sig if necessary.
Instead of tracking local updates in a separate link variable, query
this state from the channel itself.
This commit also fixes the issue where the commit tx was not updated
anymore after a failed first attempt because the revocation window was
closed. Also those pending updates will be taken into account when the
remote party revokes.
Previously the channel method FullySynced was used to decide whether to
send a new commit sig message. However, it could happen that FullySynced
was false, but that we didn't owe a commitment signature. Instead we
were waiting on the other party to send us a signature. If that
happened, we'd send out an empty commit sig. This commit modifies the
condition that triggers a new commit sig and fixes this deviation from
the spec.
In this commit, we create a new chainfee package, that houses all fee
related functionality used within the codebase. The creation of this new
package furthers our long-term goal of extracting functionality from the
bloated `lnwallet` package into new distinct packages. Additionally,
this new packages resolves a class of import cycle that could arise if a
new package that was imported by something in `lnwallet` wanted to use
the existing fee related functions in the prior `lnwallet` package.
In this commit, we convert the existing `channeldb.ChannelType` type
into a _bit field_. This doesn't require us to change the current
serialization or interpretation or the type as it is, since all the
current defined values us a distinct bit. This PR lays the ground work
for any future changes that may introduce new channel types (like anchor
outputs), and also any changes that may modify the existing invariants
around channels (if we're the initiator, we always have the funding
transaction).
This commit modifies the NewPayloadFromReader to apply known
presence/omission contraints in the event that the tlv parser returns an
unknown required type failure.
Now that the parser has been modified to finished parsing the stream to
obtain a proper parsed type set, we can accurately apply these higher
level validation checks. This overrides required type failures, such
that they are only returned if the sender properly abided by the
constraints on fields for which we know.
The unit tests are updated to create otherwise valid payloads that then
return unknown required type failures. In one case, a test which
previously returned an unknown required type failure is made to return
an included failure for the sid, indicating the unknown required type 0
is being overruled.
This commit modifies the link return an InvalidOnionPayload failure when
it cannot parse a TLV payload. The offset is left at zero, since its
unclear how useful it will be in practice and would require some
significant reworkings of the abstractions in the tlv package.
TODO: add unit tests. currently none of the test unit infrastructure is
setup to handle TLV payloads, so this would require implementing a
separate mock iterator for TLV payloads that also supports injecting
invalid payloads. Deferring this non-trival effor till a later date
This commit adds a hop.PayloadViolation enum which encompasses the cases
where the sender omits, includes, or requires a type that causes an
ErrInvalidPayload faiulre.
The existing Omitted bool is converted to this PayloadViolation, and
NewPayloadFromReader is updated to return such a failure with a
RequiredViolation when an unknown required type is detected.
The unit tests are updated to cover the three possible cases of
RequiredViolations, as well as included valid intermediate and final hop
tests.
In the scenario where the requested channel does not have enough balance
and another channel towards the same node generates a different failure,
we erroneously returned UnknownNextPeer instead of the expected
TemporaryChannelFailure.
This commit rewrites the non-strict forwarding logic in the switch to
return the proper failure message. Part of this is moving the link
balance check inside the link.
The previous limit of 1008 proved to be low, given that almost 50% of
the network still advertises CLTV deltas of 144 blocks, possibly
resulting in routes with many hops failing.
In this commit, we update the tower+link logic to tag a commitment as
the new (tweakless) format if it applies. In order to do this, the
BackupTask method has gained an additional parameter to indicate the
type of commitment that we're attempting to upload. This new tweakless
bool is then threaded through all the way to back up task creation to
ensure that we make the proper input.Input.
Finally, we've added a new test case for each existing test case to test
each case w/ and w/o the tweakless modifier.
In this commit, we update the funding workflow to be aware of the new
channel type that doesn't tweak the remote party's output within the
non-delay script on their commitment transaction. To do this, we now
allow the caller of `InnitChannelReservation` to signal if they want the
old or new (tweakless) commitment style.
The funding tests are also updated to test both funding variants, as
we'll still need to understand the legacy format for older nodes.
In this commit, we update the channel state machine to be aware of
tweakless commits. In several areas, we'll now check the channel's type
to see if it's `SingleFunderTweakless`. If so, then we'll opt to use the
remote party's non-delay based point directly in the script, skipping
any additional cryptographic operations. Along the way we move the
`validateCommitmentSanity` method to be defined _before_ it's used as is
cutomary within the codebase.
Notably, within the `NewUnilateralCloseSummary` method, we'll now _blank
out_ the `SingleTweak` value if the commitment is tweakless. This
indicates to callers the witness type they should map to, as the value
isn't needed at all any longer when sweeping a non-delay output.
We also update the signing+verification tests to also test that we're
able to properly generate a valid witness for the new tweakless
commitment format.
Earlier this delay was needed to increase the likelihood that the DLP
scanario was successfully completed. Since we would risk the connection
being torn down, and the link exit, we could end up with the remote
marking the channel borked, but not finishing the force close.
With the previous set of commits, we should now trigger the force close
before we merk the channel borked, which should ensure we'll resume the
orocess on next restart/connect.
Instead of marking the channel Borked in cases where we want to force
close it, we immediately let the peer fail the link. The channel state
will instead be updated by the channel arbitrator, which will transition
to StateBroadcastCommit, marking the channel borked, then marking the
commitment tx broadcasted right before publishing the force close tx. We
do this to avoid the case where we would mark it Borked, but go down
before being able to publish the closing tx.
Storing the force close tx ensures it will be re-published on startup.
Instead of marking the database state when processing the channel
reestablishment message, we wait for the result of this processing to
arrive in the link, and mark it accordingly in the database here.
We do this move the logic determining whether we should force close the
channel or not, and what state to mark it in the DB, to the same place,
as these need to be consistent.
This commit converts the ErrCommitSyncLocalDataLoss error into a struct,
that also holds the received last unrevoked commit point from the remote
party.
In this commit, we update the router and link to support users
updating the max HTLC policy for their channels. By updating these internal
systems before updating the RPC server and lncli, we protect users from
being shown an option that doesn't actually work.
The policy update logic that resided part in the gossiper and
part in the rpc server is extracted into its own object.
This prepares for additional validation logic to be added for policy
updates that would otherwise make the gossiper heavier.
It is also a small first step towards separation of our own channel data
from the rest of the graph.
Now that the link will remain ineligible until it receives
channel_reestablish from the remote peer, we can remove the channel
reestablish timeout entirely.
This commit modifies the link's EligibleToForward() method only return
true once the peers have successfully exchanged channel reestablish
messages. This is a preliminary step to increasing the reestablish
timeout, ensuring the switch won't try to forward over links while
we're waiting for the remote peer to resume the connection.
Since we will now wait to deliver the event after channel reestablish,
notifying when the link is added to the switch will no longer be
sufficient. Later, we will add receiving reestablish as an additional
requirement for EligibleToForward returning true.
The inactive ntfn is also moved, to ensure that we don't fire inactive
notifications if no corresponding active notification was sent.
Extends the invalid payment details failure with the new accept height
field. This allows sender to distinguish between a genuine invalid
details situation and a delay caused by intermediate nodes.
This commit modifies hodl htlc notification from invoice registry from a
single notification per hash to distinct notifications per htlc. This
prepares for htlc-specific information (accept height) to be added to the
notification.
In this commit, we fix a bug where if a user updates a forwarding policy to be
zero, the update will be applied to the policy correctly on-disk, but not
in-memory.
We solve this issue by having the gossiper return the list of on-disk updated
policies and passing these policies to the switch, so the switch can assume
that zero-valued fields are intentional and not just uninitialized.
Logging for the hop package is controlled via the parent htlcswitch
package. Unfortunately the parent package only controlled the
initialization, but didn't enable the logger when the log level came
in from the main lnd package.
From BOLT 04:
The writer:
- MUST include amt_to_forward and outgoing_cltv_value for every node.
- MUST include short_channel_id for every non-final node.
- MUST NOT include short_channel_id for the final node.
This commit adds an additional return value to
Stream.DecodeWithParsedTypes, which returns the set of types that were
encountered during decoding. The set will contain all known types that
were decoded, as well as unknown odd types that were ignored.
The rationale for the return value (rather than an internal member) is
so that the stream remains stateless.
This return value can be used by callers during decoding to make
assertions as to whether specific types were included in the stream.
This is need, for example, when parsing onion payloads where certain
fields must be included/omitted depending on the hop type.
The original Decode method would incur the additional performance hit of
needing to track the parsed types, so we can selectively enable this
functionality when a decoder requires it by using a helper which
conditionally tracks the parsed types.
Currently the invoice registry cannot tell apart the htlcs that pay to
an invoice. Because htlcs may also be replayed on startup, it isn't
possible to determine the total amount paid to an invoice.
This commit is a first step towards fixing that. It reports the circuit
keys of htlcs to the invoice registry, which forms the basis for
accurate invoice accounting.
In this commit, we begin to enforce a maximum channel commitment fee for
channel initiators when attempting to update their commitment fee. Now,
if the new commitment fee happens to exceed their maximum, then a fee
update of the maximum fee allocation will be proposed instead if needed.
A default of up to 50% of the channel initiator's balance is enforced
for the maximum channel commitment fee. It can be modified through the
`--max-channel-fee-allocation` CLI flag.
In this commit, we update the `HopIterator` to gain awareness of the new
TLV hop payload. The default `HopIterator` will now hide the details of
the TLV from the caller, and return the same `ForwardingInfo` struct in
a uniform manner. We also add a new method: `ExtraOnionBlob` to allow
the caller to obtain the raw EOB (the serialized TLV stream) to pass
around.
Within the link, we'll now pass the EOB information into the invoice
registry. This allows the registry to parse out any additional
information from the EOB that it needs to settle the payment, such as a
preimage shard in the AMP case.
htlcs
config: Adding RejectHTLC field in config struct
This commit adds a RejectHTLC field in the config struct in config.go.
This allows the user to run lnd as a node that does not accept onward
HTLCs.
htlcswitch/switch: Adding a field RejectHTLC to the switch config
This commit adds a field RejectHTLC to the switch config. When the
switch receives an HTLC it will check this flag and if the HTLC is not
from the source hop, the HTLC will be rejected.
htlcswitch/switch: adding check for RejectHTLC flag and incomingChanID
This commit adds a check when receiving UpdateAddHTLC. The check looks
for the RejectHTLC flag set and whether the HTLC is from the sourceHop
(the local switch). If the HTLC is not from the sourceHop, then we
reject the HTLC and return a FailChannelDisabled error.
server: adding RejectHTLC field to initialization of switch
lnd_test: adding test for RejectHTLC
This commit adds a test which tests that a node with the --rejecthtlc
flag will reject any onward HTLCs but still can receive direct HTLCs and
can send HTLCs.
Previously a temporary channel failure was returning for unexpected
malformed htlc failures. This is not what we want to communicate to the
sender, because the sender may apply a penalty to us only.
Returning the temporary channel failure is especially problematic if we
ourselves are the sender and the malformed htlc failure comes from our
direct peer. When interpretating the failure, we aren't able to
distinguish anymore between our channel not having enough balance and
our peer sending an unexpected failure back.
Debug invoices are rarely used nowadays, but keep asking for maintenance
every time refactoring in primarily the invoice registry occurs. We have
passed the cost/benefit tipping point, so therefore the debug invoice
concept is removed in this commit.
Previously the debughtlc flag also controlled whether hodl masks were
active. It is safe to remove that additional condition because the hodl
masks are still guarded by the dev build tag.
In order to prevent information leaks by nodes probing with a payment
hash, this commit changes exit hop processing so that it always returns
incorrect_or_unknown_payment_details and leaves the prober in the dark
about whether an invoice actually exists.
Align naming better with the lightning spec. Not the full name of the
failure (FailIncorrectOrUnknownPaymentDetails) is used, because this
would cause too many long lines in the code.
The current value was based on the previous default CLTV delta of 144
blocks. This has been lowered to 40 since lnd v0.6.0-beta, making the
current value of 5000 blocks a bit high. Lowering it to one week should
be more than enough to account for the other major lightning
implementations. Eclair currently has a default CLTV delta of 144, while
c-lightning's is 14.
This commit makes the outgoing link pipeline the settle to the
switch as soon as it receives it. Previously, it would wait for a
revocation before sending it, which caused increased latency on
payments as well as possibly never settling on the incoming link.
A duplicate settle is still sent to the switch, but it is handled
gracefully. A new AckEventTicker was added to the switch which
acknowledges any pending settle / fail entries in an outgoing
link's fwd pkgs in batch. This was needed in order to reduce the
number of db txn's which would have been incurred by acking whenever
we receive a duplicate settle without batching.
Methods on failure message types used to be defined on value receivers.
This allowed assignment of a failure message to ForwardingError both as
a value and as a pointer. This is error-prone, especially when using a
type switch.
In this commit the failure message methods are changed so that they
target pointer receivers.
Two instances where a value was assigned instead of a reference are
fixed.
TestSwitchGetPaymentResult tests that the switch interacts as expected
with the circuit map and network result store when looking up the result
of a payment ID. This is important for not to lose results under
concurrent lookup and receiving results.
paymentResultStore is a persistent store where we keep track of all
received payment results. This is used to ensure we don't lose results
from payment attempts on restarts.
In this commit, we fix a lingering TOOD statement in the channel arb.
Before this commitment, we would simply wipe our our local HTLC set of
the HTLC set that was on the remote commitment transaction on force
close. This was incorrect as if our commitment transaction had an HTLC
that the remote commitment didn't, then we would fail to cancel that
back, and cause both channels to time out on chain.
In order to remedy this, we introduce a new `HtlcSetKey` struct to track
all 3 possible in-flight set of HTLCs: ours, theirs, and their pending.
We also we start to tack on additional data to all the unilateral close
messages we send to subscribers. This new data is the CommitSet, or the
set of valid commitments at channel closure time. This new information
will be used by the channel arb in an upcoming commit to ensure it will
cancel back HTLCs in the case of split commitment state.
Finally, we start to thread through an optional *CommitSet to the
advanceState method. This additional information will give the channel
arb addition information it needs to ensure it properly cancels back
HTLCs that are about to time out or may time out depending on which
commitment is played.
Within the htlcswitch pakage, we modify the `SignNextCommitment` method
to return the new set of pending HTLCs for the remote party's commitment
transaction and `ReceiveRevocation` to return the latest set of
commitment transactions on the remote party's commitment as well. This
is a preparatory change which is part of a larger change to address a
lingering TODO in the cnct.
Additionally, rather than just send of the set of HTLCs after the we
revoke, we'll also send of the set of HTLCs after the remote party
revokes, and we create a pending commitment state for it.
In this commit we move handing the deobfuscator from the router to the
switch from when the payment is initiated, to when the result is
queried.
We do this because only the router can recreate the deobfuscator after a
restart, and we are preparing for being able to handle results across
restarts.
Since the deobfuscator cannot be nil anymore, we can also get rid of
that special case.
This lets us distinguish an critical error from a actual payment result
(success or failure). This is important since we know that we can only
attempt another payment when a final result from the previous payment
attempt is received.
With the following commits, it'll become important to not resuse
paymentIDs, since there is no way to tell whether the HTLC in question
has already been forwarded and settled/failed.
We clarify this in the SendHTLC comments, and alter the tests to not
attempt to resend an HTLC with a duplicate payment ID.
This commit moves the responsibility of generating a unique payment ID
from the switch to the router. This will make it easier for the router
to keep track of which HTLCs were successfully forwarded onto the
network, as it can query the switch for existing HTLCs as long as the
paymentIDs are kept.
The router is expected to maintain a map from paymentHash->paymentID,
such that they can be replayed on restart. This also lets the router
check the status of a sent payment after a restart, by querying the
switch for the paymentID in question.
This commit is the final step in making the link unaware of invoices. It
now purely offers the htlc to the invoice registry and follows
instructions from the invoice registry about how and when to respond to
the htlc.
The change also fixes a bug where upon restart, hodl htlcs were
subjected to the invoice minimum cltv delta requirement again. If the
block height has increased in the mean while, the htlc would be canceled
back.
Furthermore the invoice registry interaction is aligned between link and
contract resolvers.
Now that the success resolver preimage field is always populated by the
incoming contest resolver, preimage lookups earlier in the
process (channel and channel arbitrator) can mostly be removed.
In this commit, we add a new test to ensure that we're able to properly
convert malformed HTLC errors that are sourced from multiple hops away,
or our direct channel peers. In order to test this effectively, we force
the onion decryptors of various peers to always fail which will trigger
the malformed HTLC logic.
In this commit, we now properly convert multi-hop malformed HTLC
failures. Before this commit, we wouldn't properly add a layer of
encryption to these errors meaning that the destination would fail to
decrypt the error as it was actually plaintext.
To remedy this, we'll now check if we need to convert an error, and if
so we'll encrypt it as if it we were the source of the error (the true
source is our direct channel peer).
In this commit, we fix a bug that caused us to be unable to properly
handle malformed HTLC failures from our direct link. Before this commit,
we would attempt to decrypt it and fail since it wasn't well formed. In
this commit, if its an error for a local payment, and it needed to be
converted, then we'll decode it w/o decrypting since it's already
plaintext.
In this commit, we add a new method to the ErrorEncrypter interface:
`EncryptMalformedError`. This takes a raw error (no encryption or MAC),
and encrypts it as if we were the originator of this error. This will be
used by the switch to convert malformed fail errors to regular fully
encrypted errors.
In this commit, we start the first phase of fixing an existing bug
within the switch. As is, we don't properly convert
`UpdateFailMalformedHTLC` to regular `UpdateFailHTLC` messages that are
fully encrypted. When we receive a `UpdateFailMalformedHTLC` today,
we'll convert it into a regular fail message by simply encoding the
failure message raw. This failure message doesn't have a MAC yet, so if
we sent it backwards, then the destination wouldn't be able to decrypt
it. We can recognize this type of failure as it'll be the same size as
the raw failure message max size, but it has 4 extra bytes for the
encoding. When we come across this message, we'll mark is as needing
conversion so the switch can take care of it.
In this commit, we fix a bug that would cause a node with a hodl HTLC to
cancel back the HTLC upon restart if the invoice has been settled, but
the HTLC is still present on the commitment transaction. A fix for the
HTLC still being present (not triggering a new commitment) has been
fixed recently. However, for older nodes with a lingering HTLC, on
restart it would be failed back.
In this commit, we make the check stricter by only performing these
checks for HTLCs that are in the open state. This ensures that we'll
only check this constraints the first time around, before the HTLC has
been transitioned to the accepted state.
This commit adds a brief delay when sending our channel reestablish
message if the link contains a restored channel to ensure we first have
a stable connection. Sending the message will cause the remote peer to
force close the channel, which currently may not be resumed reliably if
the connection is being torn town simultaneously. This delay can be
removed after the force close is reliable, but in the meantime it
improves the reliability of successfully closing out the channel and
allows the `channel_backup_restore/restore_during_creation` to pass
reliably.
In this commit, we modify the starting link logic to always send the
chan sync message to the remote peer in a synchronous manner. Otherwise,
it's possible that we fail very quickly below this block, and don't ever
send the message to the remote peer.
The idea of the batch counter is to increase it for commit tx updates,
so that if the commit tx cannot be updated immediately (revocation
window exhausted), the batch ticker makes sure it happens later.
The batch counter was increased for forwarded htlcs, but not for exit hop
resolutions.
This lead to the situation where the commitment tx would not be updated,
even though the htlc was settled locally. When no other changes happen
on the channel, the htlc eventually reaches its expiry and the channel
is force closed.