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.
Due to a misunderstanding about how the entities/actions are encoded
inside the macaroon, only the first action was printed per entity.
Even though we add them as separate pairs in the macaroon service (for
example "offchain:read" and "offchain:write"), they are grouped in the
serialized macaroon ("offchain:read,write").
To be spec compliant, we require the initiator to not pay the anchor
values into fees on coop close. We extract the balance calculation into
commitment.go, and add back the value of the anchors to the initiator's
balance.
Give the external subservers the possibility to also use their own
validator to check any macaroons attached to calls to their registered
gRPC URIs.
This allows them to have their own root key ID database and permission
entities.
When external subservers register themselves to be served through the
same gRPC interface as the main lnd RPC, their requests are also
intercepted by the main lnd macaroon interceptor.
If the external subservers want to use their own macaroons that are
independent of lnd's, they need a way to overwrite the default validator
of the macaroon interceptor. We add this mechanism with the concept of
external validators.
When starting up with lnd.conf that contains the sample line
"tor.active", lnd crashes and prints the error:
malformed key=value (tor.active)
Using "tor.active=true" instead works as expected.
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.
A profile file can contain multiple profile entries. Each
entry has a name, a set of default options to use and an optional list
of macaroons in a jar. The profile file can be
serialized/deserialized to and from JSON.