This commit fixes a deadlock bug within the readHandler of the peer.
Previously, once a channel was pending opening, _no_ other message
would be processed by the readHandler as it would be blocked waiting
for the channel to open. On testnet this would be manifsted as a node
locking up, until the channel was detected as being open.
We fix this bug by tracking which channel streams are active. If a
channel stream is active, then we can send the update directly to it.
Otherwise, we launch a goroutine that’ll block until the channel is
open, then in a synchronized manner, update the channel stream as being
active and send the update to the channel.
This commit modifies the order of operations after a channel has been
detected as fully opened. Rather than waiting until we receive the
FundingLocked message to announce the channel, we now do so immediately
after we detect the channel has been opened.
Additionally, we also patch a possible dead-lock bug by ensuring that
the RevokeAndAck message is always sent _after_ the FundingLocked
message. We do this by only passing the newly created channel too the
relevant sub-systems _after_ we receive the FundingLocked message. This
movement also serves to pave the way for our switch to the spec’s
funding workflow, as once we remove the initial revocation window,
there’ll be no way for us to initiate a state transition until we
receive the FundingLocked message from the remote party.
This commit modifies the way the fundingManager tracks pending funding
workflows internally. Rather than using the old auto-incrementing
64-bit pending channel ID’s, we now use a 32-byte pending channel ID
which is generated using a CSPRG. Additionally, once the final funding
message has been sent, we now de-multiplex the FundingLocked message
according to the new Channel ID’s which replace the old ChannelPoint’s
and are exactly 32-bytes long.
This commit modifies the testNodeAnnouncment to no longer open a
channel for the duration of the test. As the test is only exercising
the proper behavior of announcement propagation and doesn’t require a
channel to be open for the duration. Also we now properly shutdown the
created “dave” node, as it’s no longer needed after the tests
concludes.
This commit does to things: moves the prior ShortChannelID struct into
a new short_channel_id.go file, and also implements the new ChannelID’s
currently used within he specification.
These new ID’s are 32-bytes in length and used during initial channel
funding as well as during normal channel updates. During initial
channel funding, the ID is to be a random 32-byte string, while once
normal channel operation has began, the ID is to be (txid XOR index),
where index is the index of the funding outpoint.
This commit re-writes the GetNetworkInfo implenetaiton to use a single
database transaction. We’re now able to do this due to the recent
change in the API for the ChannelGraph struct and it’s related objects.
The recent change allows the passed callback to accept a db
transaction, with this, the callback is now able to issue another
traversal routine _within_ the prior one.
This commit modifies the ForEachNode on the ChannelGraph and
ForEachChannel on the LightningNode struct to accept a database
transaction as its first argument. With this change, it’ll now be
possible to implement graph traversals that typically required a nested
loop with all the vertex loaded into memory using the callback API
instead:
c.ForEachNode(nil, func(tx, node) {
node.ForEachChannel(tx, func(…) {
})
})
This commit modifies the fundingManager config to use the a SignMesage
function rather than two distinct functions for singing one half the
channel announcement proofs. This change unifies the signing of
messages under a single abstraction: the MessageSigner interface.
This commit modifies the SignAnnouncement helper function to instead
take a MessageSigner interface rather than the deprecated MessageSigner
struct. We also modify the function to explicitly take the identity
public key to use when signing.
This commit removes the now deprecated FundingSigner struct as part of
the btcwallet package, and instead replaces it within an implementation
of the MessageSigner interface.
This commit introduces the MessageSigner interface which is an abstract
object capable of signing arbitrary messages with a target public key.
This interface will be used within the daemon for: signing channel
authentication proofs, signing node/channel announcements, and also to
possibly sign arbitrary messages in the future.
This commit modifies the ConnectPeer method on the testing framework to
block (with a timeout) until the target peer is actually detected as
being connected. This was added as the peer connection logic was made
to be more asynchronous in a prior commit.
This commit fixes a pretty nasty unnoticed bug within the main
k-shortest paths algorithm loop. After a new candidate path is found,
the rootPath (the path up to the pivot node) and the spurPath (the
_new_ path after the pivot node) are to be combined into a new candiate
shortest path. The prior logic simply appended the spurPath onto the
end of the rootPath to create a slice. However, if the case that the
currnet rootPath is really a sub-path in a larger slice, then this will
mutate the underlying slice.
This bug would manifest when doing path finding and cause an infinite
loop as the slice kept growing with new spurPaths, causing the loop to
never terminate. We remedy this bug by properly create a new backing
slice, and adding the elements to them rather than incorrectly mutating
an underlying slice.
This commit fixes a bug within the k-shortest paths routine which could
result in a daemon panic when traversing a graph with particular
characteristics. Before referencing the path to create a sub-slice, we
we’re properly asserting that the length of the path was at least as
long as the current rootPath in question. We fix this by simply
ensuring the length of the slice is adequate before proceeding with the
operation.
This map was added very early on as a possible path to implement proper
retransmission. However, we now have a proper persistent retransmission
sub-system being proposed as a PR, therefore we no longer have any use
for this.
This commit patches a whole in our optimistic channel synchronization
logic by making the logCommitTimer a persistent ticker rather than one
that is activated after receiving a commitment, and disabled once we
send a new commitment ourself. In the setting of batched full-duplex
channel updates, the prior approach could at times result in a benign
state desync caused by one side being one commitment ahead of the other
because one of the nodes failed to, or was unable to provide the other
with a state update during the workflow.
This commit simplifies the channel state update handling by doing away
with the commitmentState.pendingUpdate method all together. The newly
added LightningChannel.FullySynced method replace the prior state and
also replaced all other uses of PendingUpdates.
By moving to using channel.FullySynced() we also eliminate class of
desynchronization error caused by a node failing to provide the other
side with the latest commitment state.
This commit improves the channel state machine by converting the
objective PendingUpdates method to a subjective FullySynced method
which is to be used in place of PendingUpdates. The new FullySynced
method is fully encompassing and replaces any upper state required by
the state machine which wraps this one.
The new FullySynced method is identical to PendingUpdates aside from
the fact that: it now also factors in the log message index of the
remote commitment chain, and also introduces a concept of an “owed
commitment”. A commitment chain owes a commitment if the height of the
local commitment chain is higher than that of the remote chain.
This commit removes the theirPrevPkScript field from the
LightningChannel struct all together. It’s no longer needed as the more
fundamental mutation bug has been fixed within the channel state
machine.
This commit fixes a class of bug that can arise in the channel state
machine when a very high throughput workflow is attempted. Since the
PaymentDescriptor’s within a commitment pointed directly into the log,
any changes to a payment descriptor would also be reflected in all
other ones. Due to this mutation possibility, at times, the
locateOutputIndex method would fail since the HTLC’s pkScript was
modified, causing the channel to fail.
We fix this class of bug by simply ensure that once an HTLC has been
associated with a particular commitment, then it becomes immutable.
This commit fixes a prior oversight in the implementation of
SendPayment that could result in tens of thousands of goroutines
OOM’ing an lnd daemon. Previously we didn’t limit the number of
outstanding payments that were allowed by a client. Users on machines
with a small amount of RAM were reporting crashes when sending a very
large number of payments in a consistent stream. This commit fixes this
issue by now using a semaphore to limit the number of outstanding
payments (and therefore) goroutines allowed in the SendPayment method.
This commit implements an easy optimization by using bolt db’s Batch
method when writing payment details to disk. The AddPaymnent method can
be concurrently called by thousands of grouting due to the way the
payment dispatch pipeline is architected. With this commit, we shave of
a significant amount of running time when users are sending thousands
of payments a second as what would’ve been thousands of writes can now
be coalesced into one or two writes!
This commit eliminates a possible deadlock (or repeated peer connection
failures) that can arise due to the [inbound|outbound]PeerConnected
methods holding the peer mutex too long. We now alleviate this
concurrency issue by calling s.peerConnected in an asynchronous manner.
This is safe as all operations within the method are themselves
goroutine-safe.
This commit fixes a build issue that appears when attempting to
cross-compile binaries to a 32-bit system from a 64-bit system. The
issue was that the defined max-state hint overflows a 32-bit integer. To
fix this issue, we now proeprly specify a type of a uint64 for the typed
constant.