In this commit, we update all the lncfg methods used to properly pass in
a new resolver. This is required in order to ensure that we don't leak
our DNS queries if Tor mode is active.
In this commit, we move the block height dependency from the links in
the switch to the switch itself. This is possible due to a recent change
on the links no longer depending on the block height to update their
commitment fees.
We'll now only have the switch be alerted of new blocks coming in and
links will retrieve the height from it atomically.
In this commit, we address an existing issue with regards to the inital
peer bootstrapping stage. At times, the bootstrappers can be unreliable
by providing addresses for peers that no longer exist/are currently
offline. This would lead to nodes quickly entering an exponential
backoff method used to maintain a minimum target of peers without first
achieving said target.
We address this by separating the peer bootstrapper into two stages: the
initial peer bootstrapping and maintaining a target set of nodes to
maintain an up-to-date view of the network. The initial peer
bootstrapping stage has been made aggressive in order to provide such
view of the network as quickly as possible. Once done, we continue on
with the existing exponential backoff method responsible for maintaining
a target set of nodes.
traversal
In this commit, we allow our node to automatically advertise its
connection's external IPs on the ports it is currently listening on in
order to accept inbound connections. This is only done when specifying
a NAT traversal technique when starting the daemon.
We also include a handy method that watches for dynamic IP changes in
the background. If a new IP is detected, we'll craft a new node
announcement using the new IP and broadcast it to the network.
In this commit, we finish the fix for the inbound/outbound peer bool in
the server. The prior commit forgot to also flip the inbound/output maps
in Inbound/Outbound peer connected. As a result, the checks were
incorrect and could cause lnd to refuse to accept any more inbound
connections in the case of a concurrent connection attempt.
In this commit, we ensure that if we're already ignoring a connection,
then we also ignore the pending persistent connection request.
Otherwise, we'll move to accept the replaced connection, but then
continue to attempt connection requests.
In this commit, we modify the look up for inbound peers to ensure that
we connect to the "freshest" address until we need to execute the
peerTerminationWatcher. We do this as it's possible for a channel to be
created by the remote peer during our session. If we don't query for the
node's address at the latest point, then we'll miss this new node
announcement for the node.
In this commit, we address the meaning of the inbound parameter to
peerConnected. An inbound connection is defined as a connection
initiated by the peer, rather than ourselves.
We also update the inbound value for the peerConnected calls within
OutboundPeerConnected and InboundPeerConnected to reflect the definition
above.
We remove the internale broadcastMessage method, and instead handle the
mutex handling within BroadcastMessage. This lets us hold the mutex only
when neccessary.
This commit removes the sendToPeer method from the server, and instead
moves the necessary logic into SendToPeer. This let's us make the mutex
acquisition more fine-grained, only holding it while reading from the
peer map. Earlier it was required to be held during the whole call to
sendToPeer, as the method would access the map internally.
In this commit, we go through the codebase looking for TCP address
assumptions and modifying them to include the recently introduced onion
addresses. This enables us to fully support onion addresses within the
daemon.
In this commit, we update the way we reestablish inbound connections if
we lose connectivity to a node we have an open channel with. Rather than
fetching the node's advertised port, we'll fetch one of their advertised
addresses instead. This ensure that if the remote node is running behind
a proxy, we do not see the proxy's address.
In this commit, we allow the daemon to use the recently introduced Tor
Controller implementation. This will automatically create a v2 onion
service at startup in order to listen for inbound connections over Tor.
Co-Authored-By: Eugene <crypt-iq@users.noreply.github.com>
In this commit, we fix a bug where a fallback SRV lookup would leak
information if `lnd` was set to route connections over Tor. We solve
this by using the network-specific functions rather than the standard
ones found in the `net` package.
In this commit, we allow `lnd` to properly parse onion addresses in
order to advertise them to the network when set through the
`--externalip` flag.
Co-Authored-By: Eugene <crypt-iq@users.noreply.github.com>
In this commit, we introduce a new method to the channel router's config
struct: QueryBandwidth. This method allows the channel router to query
for the up-to-date available bandwidth of a particular link. In the case
that this link emanates from/to us, then we can query the switch to see
if the link is active (if not bandwidth is zero), and return the current
best estimate for the available bandwidth of the link. If the link,
isn't one of ours, then we can thread through the total maximal
capacity of the link.
In order to implement this, the missionControl struct will now query the
switch upon creation to obtain a fresh bandwidth snapshot. We take care
to do this in a distinct db transaction in order to now introduced a
circular waiting condition between the mutexes in bolt, and the channel
state machine.
The aim of this change is to reduce the number of unnecessary failures
during HTLC payment routing as we'll now skip any links that are
inactive, or just don't have enough bandwidth for the payment. Nodes
that have several hundred channels (all of which in various states of
activity and available bandwidth) should see a nice gain from this w.r.t
payment latency.
This commit adds a simple scheduling mechanism for
resolving potential deadlocks when dropping a stale
connection (via pubkey inspection).
Ideally, we'd like to wait to activate a new peer until
the previous one has exited entirely. However, the current
logic attempts to disconnect (and wait) until the peer
has been cleaned up fully, which can result in
deadlocks with other portions of the codebase, since
other blocking methods may also need acquire the mutex
before the peer can exit.
When existing connections are replaced, they now
schedule a callback that is executed inside the
peerTerminationWatcher. Since the peer now waits for
the clean exit of the prior peer, this callback is
now executed with a clean slate, adds the peer to
the server's maps, and initiates peer's Start() method.
This skips creating errChans when sending messages to
peer during broadcast. This should be a minor memory
optimization, as well as not requiring channel sends
on those which will never be read.
In this commit, we ensure that any time we send a TempChannelFailure
that's destined for a multi-hop source sender, then we'll always package
the latest channel update along with it.
This commit make the server populate the ChainArbitrator's
ContractBreach method, by a method that will reliably handoff the breach
event ot the breachArbiter. The server will now forward the breach event
to the breachArbiter, and only let the closure return a non-nil error
when the breachArbiter ACKs this event.
In this commit, we fix a minor logging bug introduced in a prior commit.
Before we would directly modify the *net.TCPAddr that was a part of the
brontide connection. This achieved our goal, but would print weird log
messages as we mutated the port in the already established connection.
In this commit, we fix that by ensuring we create a copy iff it's a
net.TCPAddr, then modify that and replace the instance in the
lnwire.NetAddress.
Fixes#991.
This commits changes the behavior of our connection
reestablishment, and resolves some minor issues that
could lead to uncancelled requests or an infinite
connection loop.
- Will not attempt to Remove connection requests with
an ID of 0. This can happen for reconnect attempts
that get scheduled, but have not started at the
time the server cancels the connection requests.
- Adds a per-peer cancellation channel, that is
closed upon a successful inbound or outbound
connection. The goroutine spwaned to handle the
reconnect by the peerTerminationWatch now
selects on this channel, and skips reconnecting
if it is closed before the backoff matures.
- Properly computes the backoff when no entry in
persistentPeersBackoff is found. Previously, a
value of 0 would be returned, cause all subsequent
backoff attempts to use a backoff of 0.
- Cancels a peers retries and remove connections
immediately after receiving an inbound connection,
to mimic the structure of OutboundPeerConnected.
- Cancels all persistent connection requests after
calling DisconnectPeers.
- Allow additional connection attempts to peers, even if
there already exists a pending connection attempt.
In this commit, we fix an existing bug within the codebase: if a peer
connected to us inbound, then we'd attempt to use the assigned port when
re-establishing a connection to them. We fix this issue in this commit
by adding a new method to look up any advertisements for the peer, and
use the specified port that matches our connection attempt. If we can't
find a proper advertisement, then we'll simply use the default peer
port.
In this commit we modify the storage location of the sphinx replay
database to be under the precise network, and not only the graph sub
directory. Before this commit, due to the usage of filepath.Dir(), the
db would lie under /graph/, rather than say, /graph/simnet.
This commit adds an backoff policy to the peer termination
watcher to avoid getting stuck in tight connection loops
with failing peers. The maximum backoff is now set to 128s,
and each backoff is randomized so that two instances using
the same algorithm have some hope of desynchronizing.
This commit adds the `lnnet` package which contains an
implementation of the newly created LightningNet interface which
multiplexes the Dial and DNS-related functions to use net
by default and torsvc if a flag is specified. This modularization
makes for cleaner code.
This commit adds a new interface named NetInterface and two
implementations of it: RegularNet & TorProxyNet. These two structs
are used in config.go in an attempt to clean up the code and
abstract away the dialer and DNS functions.
This commit adds a new module named 'torsvc' which houses all Tor
functionality in an attempt to isolate it and make it reusable in
other projecs. Some additional tweaks were made to config.go and
to the bootstrapper.
This commit adds Tor support. Users can set the --TorSocks flag
to specify which port Tor's SOCKS5 proxy is listening on so that
lnd can connect to it. When this flag is set, ALL traffic gets
routed over Tor including DNS traffic. Special functions for
DNS lookups were added, and since Tor doesn't natively support
SRV requests, the proxySRV function routes connects us to
a DNS server via Tor and SRV requests can be issued directly
to the DNS server.
Co-authored-by: MeshCollider <dobsonsa68@gmail.com>
A recent commit modified the mutex in the server to the read/write. In
order to further reduce contention, we’ll grab the read lock when we’re
examining get set of peers to ignore.
This commit aims to reduce the contention on the server's primary
mutex by (1) replacing it with a RWMutex, and (2) not holding an
exclusive lock throughout the duration of the SendToPeer method.
For the latter, we now only have to hold a shared lock until all
messages have been queued, where as before an exclusive lock
was held until all messages had been acknowledged by the target
peer's write handler. Since the initial syncing of announcements
with peer now comprises a couple thousand messages on testnet,
these changes should help keep the server from deadlocking while
completing and long-lived syncing operations.
In this commit, we modify the way that notifications are dispatched
within the chainWatcher. Before we would *always* wait for an ack back
before we started to clean up he database state. This would at times
lead to deadlocks. To remedy this, we now allow callers to decide if
they want notifications to be sync or not. The only current caller that
requires this is the breach arbiter.
In this commit, we add the IsOurAddress field into the config of the
chain arb. With this new function closure, the chain arb is able to
detect co-op on chain closes automatically.
In this commit, we modify the breach arbiter to no longer require
holding a channel object directly in order to receive new notifications
about possible breaches. Instead, we’ll contact the chain arbiter to
request a new channel event subscription.
As a result of the new architecture, we no longer need to receive a
handoff once the new channel comes online, as the chainWatcher will
always be active and watching the channel until it’s been closed.
Peers are treated as transient by default. When a peer is disconnected,
no attempt is made to reconnect. However, if we have a channel open
with a peer that peer will be added as persistent. If a persistent peer
becomes disconnected then we will attempt to reconnect.
This behavior implies that a fresh node - those without any channels -
will fall off the network over time as remote nodes restart or due to
connectivity changes. This change marks bootstrap peers as persistent
and ensures that the node remains connected to those specific peers over
time. This does not keep the node connected in the case that all
bootstrap peers are down.
Fixes#451.
In this commit, we modify the Broadcast to take a *set* of peers to
skip, rather than just a single peer. We make this modification as when
a new channel is discovered, it’s likely the case that we get the
announcement from several peers rather than a single peer. With this
change, we’ll ensure that the caller (who is aware of the set of
senders) is able to properly avoid wasting bandwidth by re-sending the
message to all peers that sent it to us originally.
This commit fixes a deadlock that could occur when
a peer disconnected during a call to sentToPeer. In
This particular case, a message would successfully
be queued, the peer would shutdown, and we would
block waiting for an error to be returned on the
message's error channel, which would deadlock.
This fixes that by also checking for peer shutdown.
This commit reorders logic in the peer termination
watcher such that we short circuit earlier if we
already have pending persistent connection requests.
Before, the debug statement may have indicated that
a reconnection was being attempted, even though it
may have exited before submitting the request to
the connection manager.
In this commit, we fix an existing bug that would cause funding
transaction to be broadcast without any fees attached at all. This is
only an issue if the fee rate reported is extremely so, as can happen
on testnet. In this case, when we went to scale down to sat/weight, we
would return a value of zero due to integer division. If we went via
the EstimateFeePerWeight call directly, then it would've been detected.
However, we accept the fee/byte from the user directly on the command
line this wasn't being done.
To fix this, we'll now manually set the fee to a sane value, if it
returns a value that can't properly be scaled to fee/weight.
In this commit, we fix a bug that would cause the DNS seeds to be
*always* active regardless of which chain+network we were on. Before we
would look up the network in the reverseChainMap. However, if we were
on regtest or testate, then it would still (incorrectly) resolve to a
valid hash.
To remedy this, we now directly use the genesis hash of the current
active chain.
In this commit, we fix an existing issue that could at times cause an
inconsistent view between the set of total coins, and the set of segwit
coins in the wallet of the node. This could be caused by initiating a
funding flow, but then the funding negotiation breaking down somewhere
along the lines. In this case, us or the other peer will disconnect.
When we initiate funding flows, we lock coins exclusively, to ensure
that concurrent funding flows don’t end up double spending the same
coin. Before this commit, we wouldn’t ever unlock those coins. As a
result, our view of available coins would be skewed.
The walletbalance call would show all the coins, but when adding the
—witness_only flag, some coins would be missing, or gone all together.
This is because the former call actually scans the txstore and manually
tallies the amount of available coins, while the latter looks at the
sent of available outputs, which is filtered based on which coins are
locked.
To remedy this, we now ensure that when a peer disconnects, we wipe all
existing reservations which will return any locked outputs to the set
of available outputs for funding flows.
Add option to set trickleDelay for AuthenticatedGossiper in
command line, with default value of 300 milliseconds. Pass this
value to newServer, which uses it when creating a new instance of
AuthenticatedGossiper. Also set this value to 300 milliseconds when
creating nodes in integration tests.
In this commit, we add a new method shouldRequestGraphSync which the
server will use in order to determine if we should request a full
channel graph sync from a newly connected remote peer. Atm, we’ll only
request a full sync iff, we have less than two peers. This is only the
initial basic logic, as we’ll later extend this to be more
comprehensive.
With this change, we’ll no longer be blasted by full channel graph
dumps for _each_ new connection after we deem that we’ve been
sufficiently bootstrapped to the network.
In this commit we add the set of local features advertised as a
parameter to the newPeer function. With this change, the server will be
able to programmatically determine _which_ bits should be set on a
connection basis, rather than re-using the same global set of bits for
each peer.
This commit adds a new field to the switch’s Config, namely the public
key of the backing lightning node. This field will soon be used to
return more detailed errors messages back to the ChannelRouter itself.
This reverts commit 6db90ef09ab974df0ff09aeaf75a3d80414d4f50.
The root cause was fixed by commit
f4e7c36c80e8e2be9edb78b3b317c69d28d6d78f. As a result, this commit is no
longer needed.
This reverts commit b7704e2de3dc96a4aebc2f47908a8f9def1da7f6.
The root issue was fixed by commit
f4e7c36c80e8e2be9edb78b3b317c69d28d6d78f. As a result, this commit is no
longer needed.
This commit removes another case of unnecessary blockage, by modifying
the sendToPeer method to be fully asynchronous. From the PoV of the
callers that utilize this method currently, there’s no reason to block
until the completion of this method. Additionally, as the graph grows
larger without more intelligent the number of messages sent during
initial dump will start to be prohibitive to waiting for full
completion before proceeding.
In this commit, we make the BroadcastMessage method on the server more
asynchronous by abandoning the two wait groups that it used for
synchronization. It has been observed that a circular waiting loop
between the AuthenticatedGossiper and a peer’s readHandler can cause
the system to dead lock.
By removing this unnecessary synchronization, we avoid the deadlock
case and allow the gossiper itself to no longer block in this scenario.
In this commit we modify the main loop within the peerBootstrapper
slightly to check for a sufficient amount of connections, _before_
checking to see if we need to back off the main loop. With this, we
avoid unnecessarily backing off unless an actual error occurs.
This commit implements 2-week zombie channel pruning. This means that
every GraphPruneInterval (currently set to one hour), we’ll scan the
channel graph, marking any channels which haven’t had *both* edges
updated in 2 weeks as a “zombie”. During the second pass, all “zombie”
channel are removed from the channel graph all together.
Adding this functionality means we’ll ensure that we maintain a
“healthy” network view, which will cut down on the number of failed
HTLC routing attempts, and also reflect an active portion of the graph.
This commit fixes an incorrect logging statement within the
peerBootstrapper goroutine. We we’re using a Debug method previously
when we should’ve been using Debugf in order to properly pass the
logging statement through.
This commit adds a listener queue for each peer, that can be used
to queue listeners that will be notified when the targetted peer
eventually comes online.
This commit adds a new primary goroutine to the server struct:
peerBootstrapper. If peer boostrapping isn’t disabled in the config,
this new goroutine will be launched to attempt to establish a set of
initial connections for a new node. The logic is pretty straight
forward: first a set of initial connections is attempted, if after our
first epoch, we don’t have enough connections yet, then we’ll attempt
to query for an additional set. In each iteration, if we haven’t been
successful, then we increase our exponential backoff in order to not
spam any of our bootstrapping sources.
This commit alters the synchronization patterns used in the server
such that the internal state is protected by a single mutex. Overall,
this simplifies the ability to reason about the behavior and
manipulation of the internal state, which has resolved a few of flakes
related to race conditions that were observed before hand.
Invoking DisconnectPeer is now fully synchronous, and waits until
the provided peer's peerTerminationWatcher has exited before
returning. Currently this is done by tracking the watcher using the
peer's WaitGroup, and locking until the peer has shutdown.
The server's API has also been refactored such that all public methods
are safe for concurrent use. Therefore, other subsystems should be
sure to make use of these endpoints to avoid corrupting the internal
state.
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.
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.
In previous commits we have intoduced the onion errors. Some of this
errors include lnwire.ChannelUpdate message. In order to change
topology accordingly to the received error, from nodes where failure
have occured, we have to propogate the update to the router subsystem.
In this commit daemon have been changed to set the proper hooks in the
channel link and switch subsystems so that they could send and receive
encrypted onion errors.