The validateFeeRate function uses the availableBalance function to get
the current spendable balance of a channel, adds the old fee and then
ensures that the new fee is not larger than the amount we have available
to spend. This commit also removes the local reserve check in the
validateFeeRate function since the balance returned from
availableBalance already takes the local reserve into acccount.
In this commit we ensure that the max fee calculated in the MaxFeeRate
function takes the local reserve amount into account along with any
pending HTLCs. This is done by calling the avaialbeBalance function.
It over-estimates the local or remote commitment's dust sum by
counting all updates in both updateLogs that are dust using the
trimmed-to-dust mechanism if applicable. The over-estimation is done
because ensuring an accurate counting is a trade-off between code
simplicity and accuracy.
Adds a method to the LightningChannel struct called IsChannelClean
that returns a boolean telling the caller whether the channel state
is clean or not. Clean in this case means there are no lingering
updates to be signed for, no HTLC's active on either sides commitment
transaction, and no pending commitments on either side. This can be
used for dynamic commitments or during a strict cooperative close
process that ensures atomicity of the channel.
As is, if the remote party proposes a min HTLC of 0 `mSat` to us, then
we won't ever be able to _send outgoing_ in the channel as the
`MayAddOutgoingHtlc` will attempt to add a zero-value HTLC, which isn't
allowed within the protocol.
The default channels created actually already use a min HTLC value of
zero within the tests, so this test case fails as is.
This commit adds a new struct AnchorResolutions which wraps the anchor
resolutions for local/remote/pending remote commitment transactions. It
is then returned from NewAnchorResolutions. Thus the caller knows how to
retrieve a certain anchor resolution.
Messages:
- UpdateFulfillHTLC
- UpdateFee
- UpdateFailMalformedHTLC
- UpdateFailHTLC
- UpdateAddHTLC
- Shutdown
- RevokeAndAck
- ReplyShortChanIDsEnd
- ReplyChannelRange
- QueryShortChanIDs
- QueryChannelRange
- NodeAnnouncement
- Init
- GossipTimestampRange
- FundingSigned
- FundingLocked
- FundingCreated
- CommitSig
- ClosingSigned
- ChannelUpdate
- ChannelReestablish
- ChannelAnnouncement
- AnnounceSignatures
lnwire: update quickcheck tests, use constant for Error
multi: update unit tests to pass deep equal assertions with messages
In this commit, we update a series of unit tests in the code base to now
pass due to the new wire message encode/decode logic. In many instances,
we'll now manually set the extra bytes to an empty byte slice to avoid
comparisons that fail due to one message having an empty byte slice and
the other having a nil pointer.
This commit caps the update fee the initiator will send when the anchors
channel type is used. We do not limit anything on the receiver side.
10 sat/vbyte is the current default max fee rate we use. This should be
enough to ensure propagation before anchoring down the commitment
transaction.
Similar to the previous commit, we fix a bug resulting in the wrong
commit weight being calculated when an HTLC just above the remote's
duslimit was added from the remote. This was a result of using the
successFee instead of the timeoutFee when checking whether it was dust,
making us consider it dust when it shouldn't have been.
In this commit we fix a bug resulting in the wrong commit weight being
calculated when an HTLC just below the remote's duslimit was added. This
was a result of using the timeoutFee instead of the successFee when
checking whether it was dust, making us consider it non-dust when it
should have been.
To be spec compliant, we require the initiator to not pay the anchor
values into fees on coop close. We extract the balance calculation into
commitment.go, and add back the value of the anchors to the initiator's
balance.
This commit includes a regression test that checks that we remember
to restore updates that we sent to the peer but they haven't sent
us a signature for yet.
This commit moves the deletion of all updates under the unsigned
acked updates key from AppendRemoteCommitChain to
AdvanceCommitChainTail. This is done because if we went down after
signing for these updates but before receiving a revocation, we would
incorrectly reject their commitment signature:
Alice Bob
-----add----->
-----sig----->
<----rev------
<----sig------
-----rev----->
<----fail-----
<----sig------
-----rev----->
-----sig----->
*reconnect*
<----rev------
<----add------
x----sig------
It is also important to note that filtering is required when we
receive a revocation to ensure that we aren't erroneously deleting
remote updates. Take the following state transitions:
Alice Bob
-----add----->
-----sig----->
<----rev------
<----sig------
-----rev----->
-----add----->
-----sig----->
<----fail-----
<----sig------
-----rev-----> (alice stores updates here)
<----rev------
In the above case, if Alice deleted all updates rather than filtering
when receiving the final revocation from Bob, then Alice would have
to force close the channel due to missing updates. Since Alice hasn't
signed for any of the unsigned acked updates, she should not filter any
of them out.
The `restoreStateLogs` function now properly restores the
`addCommitHeightLocal` field of a settle or fail's parent add.
Previously, any updates' parent in unsignedAckedUpdates would have
the field set to the default value of 0. This would cause a force
closure when receiving a commitment due to our belt-and-suspenders
checks for update logs during commitment validation.
The bug in question occurs because the `addCommitHeightLocal` field
is only populated for a restored add if the add is on the local
commitment. `TestChannelRestoreCommitHeight` is expanded in
`lnwallet/channel_test.go` to demonstrate restoration now works.
The faulty state transition:
```
<----fail----
<----sig-----
-----rev----> (add no longer on Alice's commitment)
*Alice restores* (addCommitHeightLocal of failed htlc is 0)
```
NOTE: Alice dies after sending a revocation but before signing a
commitment. This is possible because there is a select block in the link
that can potentially exit after sending over the revocation but before
signing the next commitment state for the counterparty.
This enforces the _actualized_ fee rate of the commitment transaction,
rather than the fee floor used for estimation. The new value of 250
sat/kw corresponds to 1 sat/byte, rather than 253 which is only rounded
up during estimation to account for the fact that BOLT 3 rounds down to
the nearest satoshi and that the vbyte fee estimation is lossy.
Previously we would incorrectly fail to sign the next commitment even
though the fee was technically high enough. Restarting with this commit
should solve the issue as long as the channel hasn't already gone to
chain.
This commit adds an additional santity check that rejects zero-value
HTLCs, preventing them from being added to the channel state even if the
channel config's minhtlc value is zero.
This commit adds a test to exercise that HTLC signatures are sent in the
correct order, i.e. they match the sorting of the HTLC outputs on the
commitment after applying BOLT 3's BIP69+CLTV sort.
Since our HTLC must also be added to the remote commitment, we do the
balance caluclation also from the remote chain perspective and report
our minimum balance from the two commit views as our available balance.
When we send non-dust HTLCs as the non-initiator, the remote party will
have to pay the extra commitment fee. To account for this we figure out
if they can afford paying this fee, if not we report that we only have
balance available for dust HTLCs, since these HTLCs won't increase the
commitment fee.
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 adds an extra validation step when adding HTLCs. Previously
we would only validate the remote commitment resulting from adding an
HTLC, which in most cases is enough. However, there are situations where
the dustlimits are different, which could lead to the resulting remote
commitment from adding the HTLC being valid, but not the local
commitment.
Now we also validate the local commitment. A test to trigger the case is
added.
This commit fixes the TestMaxAcceptedHTLCs, TestMaxPendingAmount,
TestMinHTLC, & TestChanReserve unit tests to pass with the new
ReceiveHTLC logic. Instead of asserting specific failures upon
receiving a new commitment signature, the various assertions were
moved to assert on the error returned from ReceiveHTLC.
The unit test TestNewBreachRetributionSkipsDustHtlcs triggered a state
transition from Bob, even though it was Alice that had added the HTLCs.
This is wrong since it will lead to Bob still owing Alice a commitment,
which is not accounted for in the unit tests.
We add a sanity check that the add heights has been set for all entries
found in the logs, and return an error otherwise. This won't happen
during normal operation, but it does reveal the mistake in the unit
test, which is fixed by making Alice trigger the transition.
In addition we resolve a long standing TODO by removing a (purposeful)
panic in the channel state machine. Old version of lnd had a bug that
could lead to the parent entries being lost during channel restore. A
panic was added to get to the bottom of if.
This is now fixed, so new nodes shouldn't encounter it. However, to be
on the safe side, instead of panicking we return an error back to
gracefully exit the channel state machine.
Updates were always restored with the same log index. This could cause a
crash when the logs were compacted and possibly other problems
elsewhere.
Extended unit test to cover the crash scenario.
This commit updates the channel state machine to
persistently store remote updates that we have received a
signature for, but that we haven't yet included in a commit
signature of our own.
Previously those updates were only stored in memory and
dropped across restarts. This lead to the production of
an invalid signature and channel force closure. The remote
party expects us to include those updates.
This test asserts that remote updates that are locked-in on the local
commitment, but haven't been signed for on the remote commitment, are
properly restored after a restart.
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.
Without this, it was possible for a combination of our balance and max
fee allocation to result in a fee rate below the fee floor causing the
remote party to reject the update and close the channel.
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.