Modifies the test cases in `TestEdgeUpdateNotification` and
`TestNodeUpdateNotification` to check for the possibility of notifications
being delivered out of order. This addresses some sporadic failures that
were observed when running the test suite.
I looked through some of the open issues but didn't see any addressing this
issue in particular, but if someone could point me to any relevant issues
that would be much appreciated!
Issue
-----
Currently the test suite validates notifications received in the order they
are submitted. The check fails because the verification of each
notification is statically linked to the order in which they are delivered,
seen
[here](1be4d67ce4/routing/notifications_test.go (L403))
and
[here](1be4d67ce4/routing/notifications_test.go (L499))
in `routing/notifications_test.go`. The notifications are typically
delivered in this order, but causes the test to fail otherwise.
Proposed Changes
-------------------
Construct an index that maps a public key to its corresponding edges and/or
nodes. When a notification is received, use its identifying public key and
the index to look up the edge/node to use for validation. Entries are
removed from the index after they are verified to ensure that the same
entry is validated twice. The logic to dynamically handle the verification
of incoming notifications rests can be found here
[here](https://github.com/cfromknecht/lnd/blob/order-invariant-ntfns/routing/notifications_test.go#L420)
and
[here](https://github.com/cfromknecht/lnd/blob/order-invariant-ntfns/routing/notifications_test.go#L539).
Encountered Errors
--------------------
* `TestEdgeUpdateNotification`: notifications_test.go:379: min HTLC of
edge doesn't match: expected 16.7401473 BTC, got 19.4852751 BTC
* `TestNodeUpdateNotification`: notifications_test.go:485: node identity
keys don't match: expected
027b139b2153ac5f3c83c2022e58b3219297d0fb3170739ee6391cddf2e06fe3e7, got
03921deafb61ee13d18e9d96c3ecd9e572e59c8dbd0bb922b5b6ac609d10fe4ee4
Recreating Failing Behavior
---------------------------
The failures can be somewhat difficult to recreate, I was able to reproduce
them by running the unit tests repeatedly until they showed up. I used the
following commands to bring them out of hiding:
```
./gotest.sh -i
go test -test.v ./routing && while [ $? -eq 0 ]; do go test -test.v ./routing; done
```
I was unable to recreate these errors, or any others in this package, after
making the proposed changes and leaving the script running continuously for
~30 minutes. Previously, I could consistently generate an error after ~20
seconds had elapsed on the latest commit in master at the time of writing:
78f6caf5d2e570fea0e5c05cc440cb7395a99c1d. Moar stability ftw!
This commit fixes a bug that existed in the prior scheme we used to
synchronize between the funding manager and the peer’s readHandler.
Previously, it was possible for messages to be re-ordered before the
reached the target ChannelLink. This would result in commitment
failures as the state machine assumes a strict in-order message
delivery. This would be manifested due to the goroutine that was
launched in the case of a pending channel funding.
The new approach using the chanMsgStream is much simpler, and easier to
read. It should also be a bit snappier, as we’ll no longer at times
create a goroutine for each message.
This commit ensures that we always clean up the resources that are
created when a new instance of a lnwallet.LightningChannel is
instantiated. The is necessary due to the sigPool that’s now present as
an internal goroutine.
Note that this commit is temporary, and should be reverted once #231 is
merged. The reason we need to do this for now, is that we don’t
properly track the exact state of the remote party’s commitment. In
this test case, the resulting HTLC’s added are dust to one party, but
non-dust to another. So upon restart, the states (balance wise) has
diverged.
This commit fixes a lingering bug in the way the internal channel state
machine handled fee calculation. Previously, we would count the dust
HTLC’s that were trimmed towards the fee that the initiator paid. This
is invalid as otherwise, the initiator would always benefit from dust
HTLC’s. Instead, we now simply “donate” the dust HTLC’s to the miner in
the commitment transaction. This change puts us in compliance with
BOLT-0003.
This commit modifies the CommitSpendNoDelay script witness generation
function. We must modify this function as all non-delayed outputs now
also require a key derivation. The current default
signer.ComputeInputScript implementation is unable to directly look up
the public key required as it attempt to target the pub key using the
pkScript.
This commit adds a new command line option that allows clients to
specify a default value to use when responding to a new channel funding
request. In a future change, a pure mapping will be added, with the
command line option having higher precedence.
This commit adds a new responsibility to the breach arbiter: the
service is now responsible for sweeping the commitment outputs to-self,
in the case of a unilateral commitment broadcast by the remote party.
In this new commitment design, this output won’t be immediately
recognized by the wallet due to using a tweaked public key. As a
result, we need to sweep this output into the wallet manually.
This commit modifies the closeObserver code to populate the signDesc in
the case we have a non-trimmed balance. Additionally, we now also add a
*wire.OutPoint field to the struct in order to allow receivers of the
message to construct a witness that can spend the newly created output
to their wallet.
This commit updates the main single-funder funding workflow within the
fundingManager (initiated via the rpcserver or by a message from a
connected peer) to fully adhere to the funding protocol outlined in
BOLT-0002.
The major changes are as follows:
* All messages modified to use the new funding messages in BOLT-0002.
* The initiator of a funding workflow no longer decides how many
confirmations must elapse before the channel can be considered open.
* Rather than each side specifying their desired CSV delay, both
sides now specify the CSV delay for the _other_ party.
This commit removes the num_confs parameter within the
OpenChannelRequest struct as it’s no longer applicable with the new
funding workflow. In the new funding workflow, it’s the responder that
decides how many confirmations are required.
This commit modifies the channel close negotiation workflow to instead
take not of the fat that with the new funding workflow, the delivery
scripts are no longer pre-committed to at the start of the funding
workflow. Instead, both sides present their delivery addresses at the
start of the shutdown process, then use those to create the final
cooperative closure transaction.
To accommodate for this new change, we now have an intermediate staging
area where we store the delivery scripts for both sides.
This commit modifies the TestChannelLinkBidirectionalOneHopPayments
test to ensure that each payment sent is safely above the dust
threshold. Note that the dust threshold itself is now higher due to the
existence of the HTLC covenant transactions which the HTLC values
themselves must cover.
This change ensure that this test operates under “normal” operation
conditions in order to catch any bugs introduced during a major change.
We can safely remove the initial revocation window extension as this
has gone away with the new state machine. We instead now just fill the
window once the channel has been opened, and then maintain a fixed
window size of 2 from there on.
This commit modifies the methods that transition the state of the
channel into an active closing state. With the new commitment design,
the delivery scripts are no longer pre-committed to the initial funding
messages. Instead, the scripts are sent at the instant that either side
decides to shutdown within the Shutdown message.
This commit adds a new companion struct: OutgoingHtlcResolution to the
commitment state machine. The purpose of this struct is the provide the
caller with the information necessary to sweep all outgoing HTLC’s in
the case of a broadcast up-to-date commitment transaction.
The HTLC resolutions allow a caller to sweep an outgoing HTLC into
their wallet after the absolute timeout of the HTLc has passed. This is
a two step process, with the first portion consisting of broadcasting
the HTLC timeout transaction itself, and the second portion consisting
of claiming the HTLC itself after a CSV delay.