The disk availability health check is less critical than our chain
access check, and may break existing setups (particularly mobile) if we
enable it by default. Here we disable by default, but leave our other
default values in so that it can easily be flipped on.
Since we store all-time flap count for a peer, we add a cooldown factor
which will discount poor flap counts in the past. This is only applied
to peers that have not flapped for at least a cooldown period, so that
we do not downgrade our rate limiting for badly behaved peers.
Since we will use peer flap rate to determine how we rate limit, we
store this value on disk per peer per channel. This allows us to
restart with memory of our peers past behaviour, so we don't give badly
behaving peers have a fresh start on restart. Last flap timestamp is
stored with our flap count so that we can degrade this all time flap
count over time for peers that have not recently flapped.
To prevent flapping peers from endlessly dos-ing us with online and
offline events, we rate limit the number of events we will store per
period using their flap rate to determine how often we will add their
events to our in memory list of online events.
Since we are tracking online events, we need to track the aggregate
change over the rate limited period, otherwise we will lose track of
a peer's current state. For example, if we store an online event, then
do not store the subsequent offline event, we will believe that the
peer is online when they actually aren't. To address this, we "stage"
a single event which keeps track of all the events that occurred while
we were rate limiting the peer. At the end of the rate limting period,
we will store the last state for that peer, thereby ensureing that
we maintain our record of their most recent state.
When dealing with online events, we actually need to track our events
by peer, not by channel. All we need to track channels is to have a
set of online events for a peer which at least contain those events.
This change refactors chanfitness to track by peer.
We currently query the store for uptime and lifespan individually. As
we add more fields, we will need to add more queries with this design.
This change combines requests into a single channel infor request so
that we do not need to add unnecessary boilerplate going forward.
To get our uptime, we first filter our event log to get online periods.
This change updates this code to be tolerant of consecutive online or
offline events in the log. This will be required for rate limiting,
because we will not record every event for anti-dos reasons, so we could
record an online event, ignore an offline event and then record another
offline event. We could just ignore this duplicate event, but we will
also need this tolerance for when we persist uptime and our peers
can have their last event before restart as an online event and record
another online event when we come back up.
As we add more elements to the chanfitness subsystem, we will require
more complex testing. The current tests are built around the inability
to mock subscriptions, which is remedied by addition of our own mock.
This context allows us to run the full store in a test, rather than
having to manually spin up the main goroutine. Mocking our subscriptions
is required so that we can block our subscribe updates on consumption,
using the real package provides us with no guarantee that the client
receives the update before shutdown, which produces test flakes.
This change also makes a move towards separating out the testing of our
event store from testing the underlying event logs to prepare for
further refactoring.
The current implementation of subscribe is difficult to mock because
the queue that we send updates on in unexported, so you cannot create
a subscribe.Client object and then add your own updates. While it is
possible to run a subscribe server in tests, subscribe servers will
shutdown before dispatching their udpates to all clients, which can be
flakey (and is difficult to workaround). In this commit, we add a
subscription interface so that these testing struggles can be addressed
with a mock.
Original PR was written with 4 spaces instead of 8, do a once off fix
here rather than fixing bit-by bit in the subsequent commits and
cluttering them for review.
Add a new health check package which will periodically poll health
check functions and shutdown if we do not succeed after our set number
of attempts. The first check that we add is one for our chain backend,
to ensure that we are connected to a bitcoin node.
This commit adds a shutdown logger which will send a request for
shutdown on critical errors. It uses the signal package to request safe
shutdown of the daemon. Since we init our logs in config validation,
we add a started channel to the signal package to prevent the case where
we have a critical log after the ShutdownLogger has started but before
the daemon has started listening for intercepts. In this case, we just
ignore the shutdown request.
Follow up labelling of external transactions with labels for the
transaction types we create within lnd. Since these labels will live
a life of string matching, a version number and rigid format is added
so that string matching is less painful. We start out with channel ID,
where available, and a transaction "type". External labels, added in a
previous PR, are not updated to this new versioned label because they
are not lnd-initiated transactions. Label matching can check this case,
then check for a version number.
When a remote peer claims one of our outgoing htlcs on chain, we do
not care whether they claimed with multiple stages. We simply store
the claim outgome then forget the resolver.
Incoming htlcs that are timed out or failed (invalid htlc or invoice
condition not met), save a single on chain resolution because we don't
need to take any actions on them ourselves (we don't need to worry
about 2 stage claims since this is the success path for our peer).
Our current set of reports contain much of the information we will
need to persist contract resolutions. We add a function to create
resolver reports from our exiting set of resolutions.
To allow us to write the outcome of our resolver to disk, we add
optional resolver reports to the CheckPoint function. Variadic params
are used because some checkpoints may have no reports (when the resolver
is not yet complete) and some may have two (in the case of a two stage
resolution).
Add a new top level bucket which holds closed channels nested by chain
hash which contains additional information about channel closes. We add
resolver resolutions under their own key so that we can extend the
bucket with additional information if required.
Use the new paginatior strcut for payments. Add some tests which will
specifically test cases on and around the missing index we force in our
test to ensure that we properly handle this case. We also add a sanity
check in the test that checks that we can query when we have no
payments.
With our new index of sequence number to index, it is possible for
more than one sequence number to point to the same hash because legacy
lnd allowed duplicate payments under the same hash. We now store these
payments in a nested bucket within the payments database. To allow
lookup of the correct payment from an index, we require matching of the
payment hash and sequence number.
We now use the same method of pagination for invoices and payments.
Rather than duplicate logic across calls, we add a pagnator struct
which can have query specific logic plugged into it. This commit also
addresses an existing issue where a reverse query for invoices with an
offset larger than our last offset would not return any invoices. We
update this behaviour to act more like c.Seek and just start from the
last entry. This behaviour change is covered by a unit test that
previously checked for the lack of invoices.
In our current invoice pagination logic, we would not return any
invoices if our offset index was more than 1 off our last index and we
were paginating backwards. This commit adds a test case for this
behaviour before fixing it in the next commit.
Add an entry to a payments index bucket which maps sequence number
to payment hash when we initiate payments. This allows for more
efficient paginated queries. We create the top level bucket in its
own migration so that we do not need to create it on the fly.
When we retry payments and provide them with a new sequence number, we
delete the index for their existing payment so that we do not have an
index that points to a non-existent payment.
If we delete a payment, we also delete its index entry. This prevents
us from looking up entries from indexes to payments that do not exist.
Update our current tests to include lookup of duplicate payments. We
do so in preparation for changing our lookup to be based on a new
payments index. We add an append duplicate function which will add a
duplicate payment with the minimum information required to successfully
read it from disk in tests.
Add label parameter to PublishTransaction in WalletController
interface. A labels package is added to store generic labels that are
used for the different types of transactions that are published by lnd.
To keep commit size down, the two endpoints that require a label
parameter be passed down have a todo added, which will be removed in
subsequent commits.
Checkout v1 has a known flake:
https://github.com/actions/checkout/issues/23#issuecomment-572688577.
For our linter to pass, we need to checkout our full history (default
depth is 1 commit). We could set fetch-depth, but we will eventually
move that depth past the linter's start point commit and need to
implement another fix. Indead, we add an extra step in our linter to
fetch full history so that the linter reference commit is found.
Add start and end height parameters to the rpc and cli GetTransactions
endpoints. Default to returning all transactions from genesis to tip,
including unconfirmed transactions to maintain backwards compatibility.
Update the PendingChannel message from a bool to an enum to
differentiate between the case where the remote party initiated the
channel and we have no record of the channel initiator. The previous
field has not been included in a release of lnd, so we can replace the
field directly.
Move enum out of CloseSummary struct for more general use. This does
not change the encoding of the enum, and will only cause compile time
errors for existing clients. This enum has not been included in a
release yet, so we can make this move without much disruption.
The pending closing channels field was present to cover an edge case
where coperatively closed channels were closed before upgrade and
confirmed after the upgrade. This commit deprecates the field and adds
a warning log to cover these edge cases.
Add a balance at height lookup function which can be used to
obtain local/remote balance at a given height. The current in memory
commits and revocation log are used to source this information.
This change adds a set of errors to the peer struct returned by list
peers. A latest error boolean is added to allow for more succinct
default lncli responses.
Add an error buffer to the peer struct which will store errors for
peers that we have active channels with. We do not store these errors
with peers that we do not have channels open with to prevent peers from
connecting and costlessly spamming us with error messages. When the peer
disconnects, the error buffer is offloaded to the server so that we can
track errors across connections. When peers reconnect, they are created
with their historic error buffer.
This commit introduces a fixed size circular buffer which stores
elements in a fixed size underlying array, wrapping to overwrite items
when the buffer gets full.
Update channel updates and subscription itest to check that close
initiator is appropriately set for cooperative and force closes for the
local and remote party.
Add an initiator enum which allows up to display an unknown value for
channels that are not in the historical chan bucket, rather than having
and ambiguous false value also representing no-value. A both option is
added to cover the case where both parties initiated a close on chain.
Add an optional channel status CloseChannel which will be stored on the
hitsorical channel which is persisted at channel close. This status is
used to set the close initiator for channels that do not complete the
funding flow or we abandon. In follow up commits, this status will be
used to record force and breach closes. The value is written to the
historical channel bucket for diplay over rpc.
This commit adds two new channel statuses which indicate the party that
initatited closing the channel. These statuses are set in conjunction
with the existing commit broadcast status so that we do not need to
migrate existing logic to handle multiple types of closes. This status
is set for locally initiated force closes in this commit because they
follow a similar pattern to cooparative closes, marking the commitment
broadcast then proceeding with tx broadcast. Remote force closes are
added in the following commit, as they are handled differently.
This commit adds link failure notifications for failures which occur
on our incoming link. These failures may be receives which we failed or
forwards which we could not parse.
Add notifications for local initiated sends settles and forwarding
failures. As with link failures, local send settles and forwarding
failures are reported directly to the router so must have their own
notification handling.
Notify link failures for our own payments. Separate handling code is
required for local payment link failures because we do not pass these
failures back through the switch (like we do for link failures for
forwards), but rather send them straight back to the router. Our own
sends have the payment ID saved in the incoming htlc ID of the packet's
incoming circuit. This change replaces that value with for the sake
of consistent notifying of sends and receives from our node.
This commit adds notifications for htlcs which are forwarded through
our node. Forwards are notified when the htlc is added on our ougoing
link, settles when we send a settle message to the downstream peer.
If a failure occurs, we check whether it occurred at our node, then
notify a link or forwarding failure accordingly.
Note that this change also adds forward event notifications for sends
which are initiated by our node because the handling code for adding
a htlc which originates from our node is the same as that for handling
forwards. Htlcs for our locally initiated sends have our internal pid
set in the incoming htlcs id field, so we extract this value and notify
with a zero htlc id to be consistent with receives (which have zero
outgoing circuits). Subsequent settles or failures are not noitfied
for local sends in this commit, and will be handled in a follow up.
This commit sets more fields on the htlcPacket created to fail adding
a htlc packet to the switch for notification purposes. This new data is
copied by value from the original packet. The packet is then failed
back to the peer that forwarded us the packet, which is handled by
handledownstream packet. The values added to the packet are not used
in the handling of a failed packet.
In this commit, a htlcNotifier interface is added to allow for easy
unit testing. Instances of the HtlcNotifier are added to the server,
switch and link.
This commit adds a HTLCNotifier to htlcswitch which HTLC events
will be piped through to provide clients with subscriptions to
HTLC level events.
The event types added are forward events (which occur for sends
from and forwards through our node), forward failues (when a
send or forward fails down the line), settles for forwards or
receives to our node and link failures which occur when a htlc
is failed at our node (which may occur for a send, receive or
foreward).
This changes replaces the pending an waiting booleans in fetchChannels
with optional filters which can be more flexibly used. This change
allows filtering of channels without having to reason about the matrix
of possible boolean combinations. A test is added to ensure that the
combinations of these filters act as expected.
This commit adds LinkErrors with failure details to htlcs which fail on
our incoming link. This change is made with the intention of notifying
detailed htlc failure reasons in sendHTLCError. The FailureDetail
interface is implemented on FailureResolutionResults so that they can
directly be used to enrich LinkErrors. sendHtlcError is updated to
take a LinkError in preparation for the addition of a htlcnotifier
which will notify the detail of the error.