The `payment_secret` feature was made mandatory in #1810 and is the default
in other implementations as well. We can thus force it to be available when
decoding onion payloads, which simplifies downstream components (no need
to handle the case where a `payment_secret` may be missing anymore).
We also rename messages in `PaymentInitiator` to remove the confusion with
Bolt 11 payment requests.
There are no functional changes, but bitcoin-lib 0.19 is based on secp256k1-kmp (instead of our own fork of secp256k1's JNI wrapper) which is cleaner, easier to maintain and used in our mobile apps.
With the move to akka _typed_, we will be using more and more
scalatest's `eventually` as a replacement for akka's `awaitCond`
(which isn't available in `testkit.typed`).
But there is a catch:
- `awaitCond` expects a boolean
- `eventually` expects a non-failure
Which means that we must use `eventually(assert(cond))`, and not
`eventually(cond)`.
Make `Setup.datadir` visible to code that receives an instance of
`Setup`. This allows plugin to know where the eclair data directory
is and potentially enrich it.
The spec defines `max_accepted_htlcs` and `max_htlc_value_in_flight_msat`
to let nodes reduce their exposure to pending HTLCs. This only applies to
received HTLCs, and we use the remote peer's values for outgoing HTLCs.
But when we're more restrictive than our peer, it makes sense to apply our
limits to outgoing HTLCs as well.
This allows us to use the full power of scala collections, to iterate
over results, convert to options, etc. while staying purely functional
and immutable.
There is a catch though: the iterator is lazy, it must be materialized
before the result set is closed, by converting the end result in a
collection or an option. In other words, database methods must never
return an `Iterable` or `Iterator`.
* Reduce log level for explorer API errors
* Reduce log level for remote peer invalid open_channel
* Don't send duplicate commands in PostRestartHtlcCleaner: if there
is already a pending HTLC settlement command in the DB, the post
restart handler should let the channel replay it instead of sending
a conflicting command.
* Workaround for lnd bug in reestablish: sometimes lnd sends
announcement_signatures before sending their channel reestablish.
This is a minor spec violation, we can simply delay the message and
handle it later (hopefully once we've received their reestablish).
* Log shared secrets in Sphinx error: Breez sometimes returns errors
that we fail to parse. Unfortunately we didn't correctly log the shared
secrets because the variable was shadowed, so we can't investigate
further for now.
* Fix utxo metric checks: if we're unable to fetch the number of
unconfirmed parents for a utxo, this shouldn't cause the global utxo
check to fail. We log a warning and let operations continue to ensure
the metric is updated.
* Handle ChannelIdAssigned when disconnected: there may be a race
condition where a peer disconnect in the middle of a channel id assignment.
In that case, we still want to record the up-to-date mapping.
Naming was confusing because it led to believe messages were related to
htlcs that have not yet been relayed, whereas those are settlement
messages, meaning that htlcs have relayed and are pending resolution
upstream.
The database has been renamed to a more generic `PendingCommandsDb`
because we may store other types of commands for which we need reliable
delivery.
In case of catastrophic failures of the `SecureRandom` instance, we add
a secondary randomness source that we mix into the random stream.
This is a somewhat weak random source and should not be used on its own,
but it doesn't hurt to xor it with the output of `SecureRandom`.
We use an actor that listens to events in the system and inject them
in our weak pseudo-RNG.
One of ZMQ's drawbacks is that subscribers on an unreliable network may
silently disconnect from publishers in case of network failures.
In our case, we want to reconnect immediately when that happens, so we set
a tcp keep-alive to ensure this.
Fixes#1789
This is a security feature that has been introduced a long time ago and is
widely supported across the network.
We can safely make it mandatory which closes probing attack vectors.
* Update default path-finding weight ratios
* The two months window for channel age was too small for today's network
* CLTV is less of an issue nowadays: there are fewer stuck payments and
we're encouraging nodes to increase their CLTV because of the recent
mempool congestions
There are two cases depending on whether you use weight ratios or not.
They used to behave very differently:
* Without weight ratios, the weight would be the total amount to send (base amount + fees)
* With weight ratios, the ratios would apply to the total amount, not just the fees.
The effect is that only the number of hops and then the weight factors matter as
the fee itself is negligible compared to the total amount.
The code is now shared and the weight is now the sum of the fees
(multiplied by a factor if using weight ratios).
We use one actor per topic, but each actor previously registered to multiple
topics so we received duplicate events and consumed twice the necessary
bandwidth.
We don't need `SERIALIZABLE` consistency guarantees when all we do is
updating timestamp columns. This happens concurrently to channel data
update and raised serialization errors in postgres.
Fixed#1786.
Co-authored-by: Bastien Teinturier <31281497+t-bast@users.noreply.github.com>
We need to group incoming HTLCs together by payment_hash and payment_secret,
otherwise we will reject valid payments that are split into multiple distinct
trampoline parts (same payment_hash but different payment_secret).
Fixes#1723
Did some refactoring in tests and introduced a new `migrationCheck`
helper method.
Note that the change of data type in sqlite for the `commitment_number`
field (from `BLOB` to `INTEGER`) is not a migration. If the table has
been created before, it will stay like it was. It doesn't matter due to
how sqlite stores data, and we make sure in tests that there is no
regression.
* rework the db version management
The way our `getVersion`/`setVersion` was very unintuitive and led to
comments like the following in tests:
```scala
dbs.getVersion(statement, "network", 1) // this will set version to 1
```
The reason is that we treat unitialized databases and up-to-date
databases exactly the same way. That is why a `getVersion` will set the
version to the most up-to-date if none is found. It's also why we use
`CREATE IF NOT EXISTS` statements for tables and indices.
With this change, the `getVersion` now only _gets_ the version, or
returns `None` if no version exists.
Since we now differentiate between uninitialized and up-to-date db, we
don't need to make the create statements idempotent. This makes the code
more strict, and we will see errors if our versioning system has bugs.
Internal tables (used for versioning, locking, etc.) have been left
unchanged.
Co-authored-by: Bastien Teinturier <31281497+t-bast@users.noreply.github.com>
* use prepared statements for pruning
* optional read-only user
It is good practice to create a dedicated read-only user to browse the
database safely. But since the app itself creates its tables, the
postgres user is the owner and a manual `GRANT` is required everytime a
new table is added.
This PR makes it possible to specify an arbitrary username, that will be
granted read-only access to all tables in the `public` schema.
NB: The assumption here is that eclair is the only app using the
eclair database (in the `CREATE DATABASE eclair` sense), which I believe
is reasonable.
* set timezone on lease table
This only affects newly created table, there is no migration.
Users that are already using postgres will keep the previous column
type, it doesn't change anything for them.
* put back lock timeout on lease table
We use a timeout, because due to concurrency we may not be able to
obtain a lock immediately.
The timeout has been set to its original value of 5s and made
configurable.
* obtain lock before initializing tables
* Add trampoline info to auditDB
Add a new table containing the recipient and amount sent to the recipient in case of trampoline relaying.
When using trampoline, the recipient may not be the next node on the path.
We don't want a database error to cause force close of channels.
Database errors are more likely to happen when using Postgres, but can
also happen with Sqlite in case of e.g. full disk.
Since we always write to disk before sending messages, we should be able
to recover gracefully after the db issue is fixed and eclair is
restarted.
The `ReconnectionTask` was only catching
`ConnectionResult.Failure.ConnectionFailed`, which is a subset of
possible failures. It should instead have caught
`ConnectionResult.Failure`.
All authentication and initialization failures were not caught and
didn't trigger reconnections.
Co-authored-by: Bastien Teinturier <31281497+t-bast@users.noreply.github.com>
Introduce a `TxPublisher` actor to publish channel txs.
Move logic from watcher to this new actor.
Remove the `TxSigningKit` abstraction that was introduced a bit too early.
The `TxPublisher` will hold all the logic so we'll start by providing the full
commitments, and we'll extract more compact objects later.
We also now publish the commit-tx and its anchor-tx independently.
* preserve pg lock exception cause
* specialize connections by backend type
* added concurrency test on channels table
This test unveils a concurrency issue in the upsert logic of the local
channels db, with the following error being thrown when we update many
channels concurrently:
```
Canceled on identification as a pivot, during conflict out checking
```
* use pg upsert construct
This is the recommended pattern according to postgres doc
(https://www.postgresql.org/docs/current/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE):
> It is recommended that applications use INSERT with ON CONFLICT DO
UPDATE rather than actually using this pattern.
* reproduce and fix same issue in peers db
* proper formatting
* prefix sqlite-specific tests
* fix double init tests
Due to how the `TestDatabases` is instantiated, calling `dbs.dbName`
twice was a no-op.
* add jdbcurl files to gitignore
Electrum support was provided for mobile wallets, server nodes should always
run a bitcoind node as this provides more control (especially for utxo
management for anchor outputs channels).
Since wallets will use https://github.com/acinq/eclair-kmp instead of eclair,
we can now remove Electrum and API fee providers from eclair.
We also removed 3rd-party fee API providers that were only used on wallets.
We need to wait for the channel relayer to be registered to the event stream
before publishing an event, otherwise the channel relayer will never receive it.
We send it a first message and wait for its response to ensure it had time
to correctly initialize.