In this commit, we update the logic to handle nonce init in
ProcessChanSyncMsg. Once a channel is already open, this is where we'll
get the new nonce data from the remote party we'll use to gain the nonce
we need to sign for their next state.
In this commit, we add a new NewCommitState struct. This preps us for
the future change wherein a partial signature is also added to the mix.
All related tests and type signatures have also been updated
accordingly.
In this commit, we extract the musig2 session management into a new
module. This allows us to re-use the session logic elsewhere in unit
tests so we don't need to instantiate the entire wallet.
In this commit, we update the Sig type to support ECDSA and schnorr
signatures. We need to do this as the HTLC signatures will become
schnorr sigs for taproot channels. The current spec draft opts to
overload this field since both the sigs are actually 64 bytes in length.
The only consideration with this move is that callers need to "coerce" a
sig to the proper type if they need schnorr signatures.
This commit adds a new interface method, `RemovePendingChannel`, to be
used when the funding flow is failed after calling `AddPendingChannel`
such that the Brontide has the most up-to-date view of the active
channels.
The funding manager has been updated to use `AddPendingChannel`. Note
that we track the pending channel before it's confirmed as the peer may
have a block height in the future(from our view), thus they may start
operating in this channel before we consider it as fully open.
The mocked peers have been updated to implement the new interface method.
memoryMailBox uses multiple container/list.List objects to track
messages and packets, which use interface{} to accept objects of any
type. go1.18 added generics to the language, which means we could use a
typed list instead, allowing us to stop using forced type assertions
when reading objects from the list.
I'm not aware of any standard library implementation of a typed list yet,
so let's just add a TODO for now.
The goroutine is very long and littered with switches on courierType. By
separating the implementations into different methods for each
courierType we eliminate the cruft and improve readability.
This commit does a few things:
- First, it gives the sessionQueue access to the TowerClient task
pipeline so that it can replay backup tasks onto the pipeline on Stop.
- Given that the above is done, the ForceQuit functionality of the
sessionQueue and TowerClient can be removed.
- The bug demonstrated in a prior commit is now fixed due to the above
changes.
The spec allows the final HTLC value and CLTV expiry to exceed
the value and expiry specified in the payload of the last hop
of the onion packet. We were over-restricting it to require
that it matches exactly.
In this commit, we eliminate some code duplication by removing the old
`HashMutex` struct as it just duplicates all the code with a different
type (uint64 and hash). We then make the main Mutex struct take a type
param, so the key can be parametrized when the struct is instantiated.
In this commit, we add a new LinkFailureDisconnect action that'll be
used if we detect that the remote party hasn't sent a revoke and ack
when it actually should.
Before this commit, we would log our action, tear down the link, but
then not actually force a connection recycle, as we assumed that if the
TCP connection was actually stale, then the read/write timeout would
expire.
In practice this doesn't always seem to be the case, so we make a strong
action here to actually force a disconnection in hopes that either side
will reconnect and keep the good times rollin' 🕺.
In this commit, we add a new LinkFailureAction enum to take over the old
force close bool. Force closing isn't the only thing we might want to do
when we decide to fail the link, so this is a prep refactoring for an
upcoming change.
Since the TowerClient now has a callback that it can use to retrieve the
retribution for a certain channel and commit height, let it use this
call back instead of requiring the info to be passed to it through
BackupState.
This commit replaces `FundingLocked` found in docs using the following
command,
```shell
find . -name "*.go" -exec sed -i '' 's/FundingLocked/ChannelReady/g' {} \;
find . -name "*.go" -exec sed -i '' 's/FundingLock/ChannelReady/g' {} \;
```
Now that we have the new package `lnd/channeldb/models` we can invert the
depenency between `channeldb` and `invoices`.
- Move all the invoice related types and errors to the
`invoices` package.
- Ensure that all the packages dealing with invoices use the types and
interfaces defined in the `invoices` package.
- Implement the InvoiceDB interface (defined in `lnd/invoices`) in
channeldb.
- Add new mock for InterfaceDB.
- `InvoiceRegistery` tests are now in its own subpacakge (they need to
import both invoices & channeldb). This is temporary until we can
decouple them.
Add a new subpackage to `lnd/channeldb` to hold some of the types that
are used in the package itself and in other packages that should not
depend on `channeldb`.
This commit replaces the clock used in the unit test
`TestMailBoxAddExpiry`. Previously the `TestClock` is used, resulting in
the unit test being not so "unit" as the maintainer needs to know the
detailed implementation of `clock.Clock`, resulting in debugging a
failed unit test more difficult as the cognitive cost is high.
Re-implement `clock.Clock` also means we need to maintain more. This is
now solved by using mock clock so we can ignore the implementation
details and care only the returned results.
This commit renames the method `GetPaymentResult` to be
`GetAttemptResult` to avoid potential confusion and to address the
one-to-many relationship between a payment and its attempts.
This changes the call-sites in several places to use the *P2P variants
to not trigger an OOM on untrusted input. This makes the code safe with
the new tlv version. Note that the call-sites prior to this change were
also safe.
This mock is used in the switch test TestUpdateFailMalformedHTLCErrorConversion.
But because the mock isn't very realistic, it doesn't detect problems
in the handling of malformed failures in the link.
The htlcswitch tests were creating temporary database files
but failing to clean them up.
We fix this by making it obvious when temporary db files are
created, and cleaning up those resources where necessary in
the tests.
Previously, the Switch would not check waiting-close channels' fwdpkgs
for settles or fails to reforward. This could result in a force close
in a rare edge case if a restart occurred at the wrong time. Now,
waiting-close fwdpkgs are checked and the issue is avoided.
NewForce's Pause method doesn't reset the ticker, so a test flake
would occur in TestChannelLinkCancelFullCommitment where
PendingCommitTicker.Pause() was called, but the underlying timer was
still ticking. When PendingCommitTicker.Resume() was called, an
unlucky Ticks() call could end up firing, leading to the link being
shut down.
In this commit, we parse the new max fee field, and pass it through the
switch, all the way to the peer where it's ultimately passed into the
chan closer state machine.
This intent of this change is to prevent privacy leaks when routing
with aliases and also to allow routing when using an alias. The
aliases are our aliases.
Introduces are two maps:
* aliasToReal:
This is an N->1 mapping for a channel. The keys are the set of
aliases and the value is the confirmed, on-chain SCID.
* baseIndex:
This is also an N->1 mapping for a channel. The keys are the set
of aliases and the value is the "base" SCID (whatever is in the
OpenChannel.ShortChannelID field). There is also a base->base
mapping, so not all keys are aliases.
The above maps are populated when a link is added to the switch and
when the channel has confirmed on-chain. The maps are not removed
from if the link is removed, but this is fine since forwarding won't
occur.
* getLinkByMapping
This function is introduced to adhere to the spec requirements that
using the confirmed SCID of a private, scid-alias-feature-bit
channel does not work. Lnd implements a stricter version of the spec
and disallows this behavior if the feature-bit was negotiated, rather
than just the channel type. The old, privacy-leak behavior is
preserved.
The spec also requires that if we must fail back an HTLC, the
ChannelUpdate must use the SCID of whatever was in the onion, to avoid
a privacy leak. This is also done by passing in the relevant SCID to
the mailbox and link. Lnd will also cancel back on the "incoming" side
if the InterceptableSwitch was used or if the link failed to decrypt
the onion. In this case, we are cautious and replace the SCID if an
alias exists.
This introduces a BigSize migration that is used to expand the width
of the ChannelStatus and ChannelType fields. Three channel "types"
are added - ZeroConfBit, ScidAliasChanBit, and ScidAliasFeatureBit.
ScidAliasChanBit denotes that the scid-alias channel type was
negotiated for the channel. ScidAliasFeatureBit denotes that the
scid-alias feature bit was negotiated during the *lifetime* of the
channel. Several helper functions on the OpenChannel struct are
exposed to aid callers from different packages.
The RefreshShortChanID has been renamed to Refresh.
A new function BroadcastHeight is used to guard access to the
mutable FundingBroadcastHeight member. This prevents data races.
With this, extra calls to RemoveLink will wait for the link to
fully stop. This is accomplished by a map that stores a single stop
channel that callers to RemoveLink will listen on. This map is not
consulted when the Switch is shutting down and calls Stop on each
individual link. Though that could be added in the future, it is
not necessary.
Warning messages are intended to add "softer" failure modes for peers,
so to start with we simply log the warnings sent to us. While we "may"
disconnect from the peer according to the spec, we start with the least
extreme option (which is also not a change in behavior because
previously we'd just log that we received an unknown odd message).
This allows Switch-initiated payments to be failed back if they don't
make it into a commitment. Prior to this commit, a Switch-initiated
HTLC could get "lost" meaning the circuit wouldn't get deleted except
if conditions were "right" and the network result store would never
be made aware of the HTLC's fate. Switch-initiated HTLC's are now
passed to the link's mailbox to ensure they can be failed back.
This change also special-cases the ErrDuplicateKeystone error from
OpenCircuits(...) so that callers of updateCommitTx() in the link
don't send an Error to the peer if they encounter the keystone error.
With the first async change, the keystone error should now always
be recoverable.
This commit changes the `NewBreachRetribution` to use the new revocation
log format, while maintaining the compatibilty to use an older
revocation log format. Unit tests have been added to make sure a breach
retribution can be created in both log formats.
This also means the watch tower needs to pass the relevant commit tx at
its backup height when creating the breach retribution during backing
up. This is achieved by recording the current remote commitment state
before advancing the remote commitment chain.
In this commit we move the tracking of the outstanding intercepted htlcs
to InterceptableSwitch. This is a preparation for making the htlc
interceptor required.
Required interception involves tracking outstanding htlcs across
multiple grpc client sessions. The per-session routerrpc
forwardInterceptor object is therefore no longer the best place for
that.
This commit was previously split into the following parts to ease
review:
- 2d746f68: replace imports
- 4008f0fd: use ecdsa.Signature
- 849e33d1: remove btcec.S256()
- b8f6ebbd: use v2 library correctly
- fa80bca9: bump go modules
The counter-party shouldn't be doing this anyways as they would be
giving away a preimage for free. Them doing this would bork their
own channel due to open circuits not getting trimmed on startup.
Removing this faulty behavior also makes it easier to reason about
the circuit logic.
This commit modifies the channel state machine to be able to derive the
proper commitment and second-level HTLC output scripts required by the
new script-enforced leased channel commitment type.
Pass htlc amount down to the channel so that we don't need to rely
on minHtlc (and pad it when the channel sets a 0 min htlc). Update
test to just check some sane values since we're no longer relying
on minHtlc amount at all.
This commit makes SendHTLC (we are the source) evaluate the dust
threshold of the outgoing channel against the default threshold of
500K satoshis. If the threshold is exceeded by adding this HTLC, we
fail backwards. It also makes handlePacketForward (we are forwarding)
evaluate the dust threshold of the incoming channel and the outgoing
channel and fails backwards if either channel's dust sum exceeds the
default threshold.
This commit extends the Mailbox interface with the SetDustClosure,
SetFeeRate, and DustPackets methods. This enables the mailbox to
report the dust exposure to the Switch when the Switch decides whether
to forward a dust packet. The dust is counted from the time an Add is
introduced via AddPacket until it is removed via AckPacket. This can
lead to some packets being counted twice before they are signed for,
but this is a trade-off between accuracy and simplicity.
With go 1.17 a change to the build flags was implemented:
https://go.googlesource.com/proposal/+/master/design/draft-gobuild.md
The formatter now automatically adds the forward-compatible build tag
format and the linter checks for them, so we need to include them in our
code.
When Alice receives a CommitSig near the end of the test, the test
assumed that she wouldn't reply with a RevokeAndAck message before
shutdownAssert was called. This led to a test flake. Instead, only
call shutdownAssert after we've received the RevokeAndAck.
In this commit, we take an initial step towards converting the existing
breach arbiter and utxo nursery logic into contract resolvers by moving
the files as is, into the `contractcourt` pacakge.
This commit is primarily move only, though we had to massage some
interfaces and config names along the way to make things compile and the
tests run properly.
In this commit, a new method `cleanClosedChannels` is added and called
when a circuit map is created. This method will delete the payment
circuits and keystones for closed channels.
This allows a caller to ensure to optimistically shut down the link
if the channel is clean. If the channel is not clean, an error is
returned and the link continues functioning as normal. The caller
should also call RemoveLink to ensure that the link isn't seen as
usable within the switch.
In lnd, log messages about channels are generally logged with a
reference to their channel point rather than the short channel id.
Channel point is reorg-resistant and also easier to look up in for
example a block explorer.
In the link however, all log messages are accompanied by short channel
id. This makes it difficult to grep a log for all channel activity. The
PEER message for example which are often crucial to analyse, are logged
with channel points.
This commit modifies the link logging to also use channel points.
This commit allows the peer to be tested without relying on a raw
htlcswitch.Switch pointer. This is accomplished by using a messageSwitch
interface and adding the CreateAndAddLink method to the
htlcswitch.Switch.
Even though the sphinx router's persistent replay log is not crucial in
the operation of lnd as its state can be re-created by creating a new
brontide connection, we want to make lnd fully stateless and therefore
have the option of not storing any state on disk.
Until now, clients of SubscribeHTLCEvents didn't have access to the settled preimage. The API allows to intercept forward event and to be updated on forward events however the forward+settle event does not include the payment preimage. This pr changes allows it.
This commit adds height-based invoice expiry for hodl invoices
that have active htlcs. This allows us to cancel our intentionally
held htlcs before channels are force closed. We only add this for
hodl invoices because we expect regular invoices to automatically
be resolved.
We still keep hodl invoices in the time-based expiry queue,
because we want to expire open invoices that reach their timeout
before any htlcs are added. Since htlcs are added after the
invoice is created, we add new htlcs as they arrive in the
invoice registry. In this commit, we allow adding of duplicate
entries for an invoice to be added to the expiry queue as each
htlc arrives to keep implementation simple. Our cancellation
logic can already handle the case where an entry is already
canceled, so this is ok.
Having it set to nil caused https://github.com/lightningnetwork/lnd/issues/5115
The problem was several layers removed from the fix. The link decides to
clean up a `fwdPkg` only if it's completed, otherwise it renotifies the
HTLCs. A package is only set to complete if it's `addAck` and
`settleFail` filters are full. For forwarded HTLCs, the `addAck` was
never being set so it would never be considered complete under this
criteria.
`addAck` is set for an HTLC when signing the next commitment TX in the
`LightningChannel`. The path for this is:
* `LightningChannel#SettleHtlc` adds the HTLC to `localUpdates`
* `LightningChannel#SignNextCommitment` builds the `ackAddRef` for all
updates with `SourceRef != nil`.
* `LightningChannel#SignNextCommitment` then passes the list of
`ackAddRef` to `OpenChannel#AppendRemoteCommitChain` to persist the new
acks in the filter
Since `SourceRef` was nil for interceptor packages, `SignNextCommitment`
ignored it and the ack was never persisted.