This commit modifies how the htlcswitch handles close requests.
Previously it could be the case that a new channel was added, but at
the same time a channel was requested to be closed. This would result
in a circular waiting dependency: the peer contacts the switch, who
tries to contact the peer.
We eliminate this possibility by ensuring that the switch handles all
close requests asynchronously. With this, the switch won't block
indefinitely in the scenario described above.
This commit ensures that all references within the chanMsgStreams are
all removed and deleted when the readHandler exits. This ensures that
all objects don’t have extra references, and will properly be garbage
collected.
This commit implements a missing policy within the current ChannelLink
interface. If an HTLC arrives that is too close to the current block
height, then we’ll reject it. As otherwise, it may be possible for us
to lose an on-chain claim if they HTLC expires already or expires
before we’re able to get a commitment transaction in the chain.
As the exit node, we have a grace period that governs out decision. As
an intermediate node, we ensure that the HTLC isn’t close to expiry on
our outgoing link end if we forward it.
This commit makes the routing cache invalidation a bit more aggressive.
We now invalidate the cache on each new block as the routes in the
cache are based on the current block height. Using the cached items may
cause our routes to fail due to them having time locks which have
already expired.
This commit implements some missing functionality, namely before all
time locks were calculated off of a base height of 0 essentially.
That’s incorrect as all time locks within HTLC’s would then be already
expired. We remedy this requesting the latest height when creating a
route to ensure that our time locks are set properly.
This commit adds a bit of a guard to a set of RPC calls. If an RPC call
needs to interact with the server but it hasn’t yet been started. Then
we’ll exit early in order to avoid blocking the call until the server
itself has started.
A recent change to the initialization order of sub-systems within lnd
results in a state where the daemon will wait for the wallet itself to
finish syncing _before_ the server is started. This was interpreted as
a bug by some users, so we’ll make the state of the server more
explicit by returning an error.
This commit adds a new utility method to the server struct itself. This
method will allow callers to query the state of the server in order to
decide if the server has been started or not. This can be useful
elsewhere in the project as we start to decouple the lifetime of
certain sub-systems from others.
Make the fundingmanager send an updated node announcement
each time it opens a new channel. This is to make sure
our node announcement is propagated in the network, since
peers will ignore our node announcements if we haven't
opened any channels yet.
According to BOLT#7, nodes will ignore node announcements
for nodes not found in any previous channel announcements.
This commit makes the discovery service send its known
channels before its known nodes when syncing the channel
graph with a peer.
This commit introduces the requirement specified in BOLT#7,
where we ignore any node announcements for a specific node
if we yet haven't seen any channel announcements where this
node takes part. This is to prevent someone DoS-ing the
network with cheap node announcements. In the router this
is enforced by requiring a call to AddNode(node_id) to
be preceded by an AddEdge(edge_id) call, where node_id is
one of the nodes in edge_id.
Adds a HaveNodeAnnouncement field to the LightningNode
struct, which is used to indicate if we have gotten
all the necessary information to fill the remaining
fields in the struct. If we haven't gotten a node
announcement for this specific node, then we only
know the pubkey, and can only fill that field in
the struct. Still, we should be able to add it to the
channel graph and use it for routes, as long as we
know about channels to this node.
This commit modifies the NewBrontideMachine constructor to allow a
caller to specify exactly _how_ new ephemeral private keys for the
crypto handshake are generated. This allows callers a bit more
flexibility when using brontide, and also allow test cases to insert
specific public keys for use within the hand shake.
This commit temporary increases the timeout for the
TestChannelLinkBidirectionalOneHopPayments test in order to account for
the slowness of the travis instances that our tests are run on.
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.