Commit Graph

2387 Commits

Author SHA1 Message Date
Rusty Russell 2752e04f8f db: add `scid` field to channels table.
Normally, we'd use the delete_columns function to remove the old
`short_channel_id` string field, *but* we can't do that for sqlite, as
there are other tables with references to it.  So add a FIXME to do
it once everyone has upgraded to an sqlite3 which has native support
for column deletion.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-22 15:19:46 +02:00
Rusty Russell 63457229cb wallet: replace forwarded_payments table with forwards table.
This one directly contains the scids of the channels involved, not
references, so can outlive the channels.  As a side-effect, however,
it now never lists `payment_hash`.  Having it listed (via join) is not
possible as it is a *string* in the channels table, and difficult
anyway because of channel aliases.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-22 15:19:46 +02:00
Rusty Russell 4cab396cc8 autoclean: handle cleaning of old payments (not just invoices).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-22 15:19:46 +02:00
Rusty Russell 660c9af1d9 autoclean: allow cleaning of paid invoices too.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-22 15:19:46 +02:00
Rusty Russell 7da51892e8 autoclean: save stats on how much we cleaned.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-22 15:19:46 +02:00
Rusty Russell 17858c9490 lightningd: deprecated "delexpiredinvoice", put functionality in autoclean plugin.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Deprecated: JSON-RPC: `delexpiredinvoice`: use `autoclean-once`.
2022-09-22 15:19:46 +02:00
Rusty Russell bd76a196f5 autoclean: new interface
In preparation for more things being autocleaned.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-22 15:19:46 +02:00
Rusty Russell 0868fa9f1e lightningd: allow extra tlv types in non-experimental mode.
The old `experimental-accept-extra-tlv-types` is now `accept-htlc-tlv-types`.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: Config: `accept-htlc-tlv-types` lets us accept unknown even HTLC TLV fields we would normally reject on parsing (was EXPERIMENTAL-only `experimental-accept-extra-tlv-types`).
2022-09-22 17:19:11 +09:30
Rusty Russell df4b477e88 keysend: allow extratlvs parameter, even in non-experimental mode.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: JSON-RPC: `keysend` now has `extratlvs` option in non-EXPERIMENTAL builds.
2022-09-22 17:19:11 +09:30
Rusty Russell ce0f544073 keysend: try to find description in TLV.
"Who needs specs?"  FFS...

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: Protocol: `keysend` will now attach the longest valid text field in the onion to the invoice (so you can have Sphinx.chat users spam you!)
2022-09-22 17:19:11 +09:30
Rusty Russell 0db01c882f pytest: fix flake in test_sendcustommsg
We assume that because we've told l3 to shut down, l2 already sees it
as disconnected.  But CI is ...slow... today!

```
        # `l3` is disconnected and we can't send messages to it
>       assert(not l2.rpc.listpeers(l3.info['id'])['peers'][0]['connected'])
E       assert not True

tests/test_misc.py:2218: AssertionError
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-21 12:15:48 +02:00
Christian Decker 774d16a72e openingd: Fail if dust and max_htlcs result in 0output commitment tx
Prior to this we might end up with a commitment transaction without
any outputs, if combined with `--dev-allowdustreserve`. Otherwise the
reserve being larger than dust means the funder could not drop its
direct output to be below dust.

Reported-by: Rusty Russell <@rustyrussell>
2022-09-21 11:25:47 +02:00
Christian Decker 493a0dfcd4 pytest: Exercise all dust zeroreserve case
This just shows we need to add that constraint.

Reported-by: Rusty Russell <@rustyrussell>
2022-09-21 11:25:47 +02:00
Christian Decker bdda62e1a4 pytest: Add test for mixed zeroreserve funding
Tests that we can have zeroreserve nodes accept and open new channels
with non-zeroreserve nodes, without throwing errors
2022-09-21 11:25:47 +02:00
Christian Decker 54b4baabb0 opening: Add `dev-allowdustreserve` option to opt into dust reserves
Technically this is a non-conformance with the spec, hence the `dev`
flag to opt-in, however I'm being told that it is also implemented in
other implementations. I'll follow this up with a proposal to the spec
to remove the checks we now bypass.
2022-09-21 11:25:47 +02:00
Christian Decker c5b2aee5c6 pytest: Add a zeroreserve test 2022-09-21 11:25:47 +02:00
Rusty Russell 3380f559f9 memleak: simplify API.
Mainly renaming.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-19 11:34:42 +09:30
Rusty Russell caecd1ee0a lightningd: don't log JSON ids as debug, use log io.
They are cute, sure, but they do spam the logs.

@Suggested-by: @niftynei
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-16 12:31:45 +09:30
Rusty Russell f1f2c1322d contrib/pyln-client: construct JSON ID correctly.
They can set their name explicitly, but if they don't we extract it from argv[0].

We also set it around callbacks, so it will be expanded by default.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-16 12:31:45 +09:30
Rusty Russell d360075d22 libplugin: use string ids correctly.
Build them from the command which caused them, and take plugin name
as basename with extension stripped.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-16 12:31:45 +09:30
Rusty Russell e8ef42b741 plugin: wire JSON id for commands which caused hooks to fire.
Most obvious one is the "connect" hook.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-16 12:31:45 +09:30
Rusty Russell eceb9f4328 lightningd: wire plugin command JSON id through to plugin commands.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-16 12:31:45 +09:30
Rusty Russell ea7903f69a lightningd: trace JSON id prefixes through sendrawtx.
First, merge the _ahf_ and non-ahf interfaces.
Second, remove the always-NULL txs->cmd field.

Then, add optional id_prefix for bitcoind_sendrawx, so if it's
triggered by a command (e.g. "withdraw") it's shown correctly in logs.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-16 12:31:45 +09:30
Rusty Russell a9557d5194 lightningd: derive JSONRPC ids from incoming id (append /cln:<method>#NNN).
Usually the calls are spontanous, so it's just "cln:<method>#NNN", but
json_invoice() calls listincoming, and json_checkmessage calls
listnodes, so those become "cli:invoice-<pid>/cln:listincoming#NNN".

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-16 12:31:45 +09:30
Rusty Russell 8fcf880e0f lightningd: explicitly remember if JSON id was a string.
This lets us use 'cmd->id' as an unquoted string (for building
new ids!).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-16 12:31:45 +09:30
Rusty Russell ed3f700991 lightningd: use string as json req ids when we create them.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-16 12:31:45 +09:30
Rusty Russell 8711241535 lightning-cli: use cli:<method>-<pid> for all requests.
This is the format we should standardize on.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-16 12:31:45 +09:30
Michael Schmoock c8ab8192ca peer_control: getinfo show correct port on discovered IPs
Changelog-Fixed: peer_control: getinfo shows the correct port on discovered IPs
2022-09-15 13:30:06 +09:30
Rusty Russell 4ca6b36439 lightningd: refuse to upgrade db on non-released versions by default.
This is a good sanity check that users understand that if they upgrade
to master mid-cycle they can't go back!

Suggested-by: @wtogami
Changelog-Added: Config: `--database-upgrade=true` required if a non-release version wants to (irrevocably!) upgrade the db.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-15 13:25:58 +09:30
fiatjaf 1ef8fb7ef8 rename `block_processed` to `block_added` 2022-09-14 13:50:38 -05:00
fiatjaf 9b33a921f0 Add plugin notification topic "block_processed".
Changelog-Added: Plugins: Added notification topic "block_processed".
2022-09-14 13:50:38 -05:00
Rusty Russell a6d4756d08 commando: make rune alternatives a JSON array.
This avoids having to escape | or &, though we still allow that for
the deprecation period.

To detect deprecated usage, we insist that alternatives are *always*
an array (which could be loosened later), but that also means that
restrictions must *always* be an array for now.

Before:

```
# invoice, description either A or B
lightning-cli commando-rune '["method=invoice","pnamedescription=A|pnamedescription=B"]'
# invoice, description literally 'A|B'
lightning-cli commando-rune '["method=invoice","pnamedescription=A\\|B"]'
```

After:

```
# invoice, description either A or B
lightning-cli commando-rune '[["method=invoice"],["pnamedescription=A", "pnamedescription=B"]]'
# invoice, description literally 'A|B'
lightning-cli commando-rune '[["method=invoice"],["pnamedescription=A|B"]]'
```

Changelog-Deprecated: JSON-RPC: `commando-rune` restrictions is always an array, each element an array of alternatives.  Replaces a string with `|`-separators, so no escaping necessary except for `\\`.
2022-09-14 17:46:43 +02:00
Rusty Russell d57d87ea3a commando: unmangle JSON.
JSON needs to escape \, since it can't be in front of anything unexpected,
so no \|.  So we need to return \\ to \, and in theory handle \n etc.

Changelog-Fixed: JSON-RPC: `commando-rune` now handles \\ escapes properly.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-14 17:46:43 +02:00
Rusty Russell 897245e3b7 pytest: test for escapes in commando values.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-14 17:46:43 +02:00
Christian Decker cb3ee0ac2e wallet: Load and value `completed_at` timestamp from DB 2022-09-14 13:14:10 +02:00
niftynei 3ad8347969 bkpr-test: maybe fix race in test_bookkeeping_closing_trimmed_htlcs
test_bookkeeping_closing_trimmed_htlcs fails to find 'all outputs
resolved' occassionally, seems like it's because the
OUR_DELAYED_TO_WALLET doesn't make it into the mempool before we start
mining blocks?

So here make sure there's something in the mempool before before we
start making new blocks.
2022-09-14 15:59:37 +09:30
niftynei efad09f966 bkpr: confirm that replaying the open+lock-in txs at start is ok
Make sure that we're not issuing duplicate lease_fee events!
2022-09-14 15:59:37 +09:30
niftynei c143914ebf bkpr: migration to delete any duplicate lease_fee entries
Clean up for #5557.

If you've got duplicate 'lease_fee' entries, we delete them!
2022-09-14 15:59:37 +09:30
niftynei 1980ba420b notif: dont send balance snapshot for not yet opened channel
We were double counting channel lease fees because we were double firing
the channel open event sequence (so to speak). If we don't report
balances for unopened channels, we don't have this problem?

Changelog-Changed: Plugins: `balance_snapshot` notification does not send balances for channels that aren't locked-in/opened yet
2022-09-14 15:59:37 +09:30
niftynei 8452d903b4 bkpr: failing test for bookkeeper crash
Reproduce crash for #5557!

If we record the channel open because bookkeeper was added after the
channel open request started but the channel confirms later, we end up
with re-recording any associated push or leased fees (paid or rcvd).

In the case where you've paid for these fees, your channel balance goes
negative and the node crashes the next time you call `listbalances`.

Reported-by: @chrisguida
2022-09-14 15:59:37 +09:30
Michael Schmoock e0d6f3ceb1 connectd: DNS Bolt7 #911 no longer EXPERIMENTAL
Changelog-Changed: Bolt7 #911 DNS annoucenent support is no longer EXPERIMENTAL
2022-09-13 06:42:20 +09:30
Rusty Russell 375215a141 lightningd: more graceful shutdown.
Be more graceful in shutting down: this should fix the issue where
bookkeeper gets upset that its commands are rejected during shutdown,
and generally make things more graceful.

1. Stop any new RPC connections.
2. Stop any per-peer daemons (channeld, etc).
3. Shut down plugins.
4. Stop all existing RPC connections.
5. Stop global daemons.
6. Free up peer, chanen HTLC datastructures.
7. Close database.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Changed: Plugins: RPC operations are now still available during shutdown.
2022-09-12 14:00:41 +02:00
Rusty Russell 5b7f14a7cb channeld/dualopend/lightningd: use channel_ready everywhere.
This alters the billboard, but that's a human-readable thing so not
noted in CHANGELOG.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Changed: JSON-RPC: `listpeers` `status` now refers to "channel ready" rather than "funding locked" (BOLT language change for zeroconf channels)
Changelog-Added: JSON-RPC: `channel_opened` notification `channel_ready` flag.
Changelog-Deprecated: JSON-RPC: `channel_opened` notification `funding_locked` flag (use `channel_ready`: BOLTs namechange).
2022-09-12 09:34:52 +09:30
Rusty Russell 1b30ea4b82 doc: update BOLTs to bc86304b4b0af5fd5ce9d24f74e2ebbceb7e2730
This contains the zeroconf stuff, with funding_locked renamed to
channel_ready.  I change that everywhere, and try to fix up the
comments.

Also the `alias` field is called `short_channel_id`.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Changed: Protocol: `funding_locked` is now called `channel_ready` as per latest BOLTs.
2022-09-12 09:34:52 +09:30
Rusty Russell 6cf3d47505 offers: remove backwards-compatiblity invoice_request signatures.
We changed the field name in v0.11.0, so this breaks compat with
v0.10.2.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-12 09:34:52 +09:30
Rusty Russell c4203e7de6 pyln-client: allow 'msat' fields to be 'null'
This happens with deprecated-apis and listconfigs, breaking some
python plugins!

Fixes: #5546
Fixes: #5563
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-09-07 11:01:36 +09:30
Matt Morehouse 0d5808b6f6 pytest: fix test_channel_state_change_history
The test fails because the closed channel is deleted by the time we
check the state change history.

It is unnecessary to mine any blocks after the close, since the state
changes up to CLOSINGD_COMPLETE occur without onchain changes.
2022-08-31 12:23:43 +03:00
Alex Myers 0abe2e3af1 pytest: Add debugging to test_gossip_store_compact_on_load
This flake has been difficult to reproduce, so let's dump the gossip
store to aid in debugging. See issue #5410.

Changelog-None
2022-08-26 07:03:10 +09:30
adi2011 8f78a76d1a tests/test_misc.py: check logs for already existing channel. 2022-08-19 10:27:09 -04:00
Christian Decker 65549a2931 ld: Fix a log message assuming that the `channel->scid` was set
This is no longer true after we introduce `zeroconf`, so use the alias
local alias instead if not set.

Signed-off-by: Christian Decker <@cdecker>
2022-08-16 14:52:52 -05:00
Christian Decker ab1ca7f159 pytest: Reproduce a crash when we have multiple channels and 0conf
This is a case where we assume that the `channel->scid` is set, which
is no longer true with `zeroconf`

Changelog-None: Zeroconf was not yet released at the time the discovery was made

Reported-by: Yaacov Akiba Slama <@yaslama>
Reported-by: Roei Erez <@roeierez>
2022-08-16 14:52:52 -05:00
niftynei 4984014578 signpsbt: add utxo info to inputs
If you build a PSBT externally from CLN and attempt to sign for the
output, we would crash. Now we don't crash.

Changelog-Changed: JSON-RPC: `signpsbt` will now add redeemscript + witness-utxo to the PSBT for an input that we can sign for, before signing it.

Fixes #5499 ?
2022-08-13 12:57:03 -05:00
Ken Sedgwick 0878002fe6 Fix derived_secret, use correct size of secretstuff.derived secret
[ Updated tests to match -- RR]
2022-08-10 12:41:27 -05:00
Rusty Russell b173b29346 pytest: test loading lease_chan_max_msat from channel_funding_inflights
It crashes with:

```
s32 field doesn't match size: expected 4, actual 8
```

Reported-by: @zerofeerouting
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-08-10 10:34:12 -05:00
niftynei 9d3bf4a1b5 bkpr: let channel reconnect, flake? 2022-08-10 10:30:45 -05:00
niftynei 72a30fc750 bkpr: dont flake, wait til pay done before mining blocks 2022-08-10 10:30:45 -05:00
niftynei 23cd58402a bkpr: create accounts for zero sat channels
we weren't making records for 'missed' accounts that had a zero balance
at snapshot time (if peer opens channel and is unused)

Fixes: #5502
Reported-By: https://github.com/niftynei/cln-logmaid
2022-08-10 10:30:45 -05:00
Rusty Russell 9543204b79 pytest: don't use bogus scids for first hop of route.
This was a legacy from when it was redundant: with multiple channels, it
no longer is!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-08-09 16:33:24 -05:00
Rusty Russell 8a9ce55345 lightningd: don't route private channels via real scid.
Again, we should use the real channel_type, but we approximate.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: Protocol: private channels will only route using short-channel-ids if channel opened with option_scid_alias-supporting peer.
2022-08-09 16:31:36 -05:00
Rusty Russell cfe6b06fb5 lightnind: use aliases in routehints for private channels.
We *should* remember the channel type, since this is only required
if they set the channel_type to include option_scid_alias.

However, since we support channel upgrade, channel_type really needs
a new table.  I have a patch for that, from my abandoned original
"fastopen" branch for aliases, but it's too big a chance for rc2 IMHO.

Meanwhile, we allow exposeprivatechannels's scids to be either real or
the aliases.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: Protocol: invoice routehints will use fake short-channel-ids for private channels if channel opened with option_scid_alias-supporting peer.
2022-08-09 16:31:36 -05:00
Rusty Russell b479e9a9fa pytest: test that we implement option_scid_alias privacy.
Spoiler: we don't! :(

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-08-09 16:31:36 -05:00
niftynei 3fcf60ab7c bkpr: track channel rebalances, display in listincome
Track rebalances, and report income events for them.

Previously `listincome` would report:
	- invoice event, debit, outgoing channel
	- invoice_fee event, debit, outgoing channel
	- invoice event, credit, inbound channel

Now reports:
	- rebalance_fee, debit, outgoing channel
	(same value as invoice_fee above)

Note: only applies on channel events; if a rebalance falls to chain
we'll use the older style of accounting.

Changelog-None
2022-08-09 11:57:18 +09:30
Rusty Russell 80a6d9b58e lightningd: set the channel_type feature.
AFAICT we should have been doing this since we started sending and
receiving it, but didn't.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: Protocol: we now advertize the `option_channel_type` feature (which we actually supported since v0.10.2)
2022-08-08 11:49:56 -05:00
Rusty Russell 5260ea2911 pytest: make sure we never break channels in multhtlc test.
It's perfectlty safe to extend the timeout to 100 blocks, so let's do
it.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-08-04 11:16:01 -05:00
Rusty Russell 93303ffdad pytest: change multihtlc topology for simpler testing.
We were seeing flakes due to channel closures on intermidiary nodes if
the blocks came too fast.

If we use a star topology it's actually what we want and it's much simpler to
figure out what's going on.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-08-04 11:16:01 -05:00
Rusty Russell b5ee5e7fb1 pytest: simplify test_onchain_multihtlc_our_unilateral/their_unilateral
We don't actually care how it does it, just that it ends the HTLCs,
so simplify this logic which tries to match it exactly.

This also fixes the flake where we would sometimes close the upstream
channels, simply because we now wait at least one second per block.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-08-04 11:16:01 -05:00
Rusty Russell 66d8ce7c8c pytest: clarify test_onchain_multihtlc_our_unilateral / test_onchain_multihtlc_their_unilateral
Use the names, not calculations on an array.  It's simply clearer,
especially when debugging.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-08-04 11:16:01 -05:00
niftynei 4e503f7d0a bkpr/listpeeers: add lease_fees back to funds; separate out in listpeers
First, how we record "our_funds" and then apply pushes vs lease_fees
(for liquidity ad buys/sales) was exactly opposite.

For pushes we were reporting the total funded into the channel, with the
push representing how much we'd later moved to the peer.

For lease_fees we were rerporting the total in the channel, with the
push representing how much was already moved to the peer.

We fix this (from a view perspective) by re-adding lease fees to what's
reported in the channel funding totals. Since this is now new behavior
(for leased channel values), we added new fields so we can take the old
field names thru a deprecation cycle.

We also make it possible to differentiate btw a push and a lease_fee
(before they were all the same), by adding to new fields to `listpeers`:
`fee_paid_msat` and `fee_rcvd_msat`.

This allows us to avoid math in the bookkeeper, instead we just pick
the numbers out directly and record them.

Fixes #5472

Changelog-Added: JSON-RPC: `listpeers` now has a few new fields for `funding` (`remote_funds_msat`, `local_funds_msat`, `fee_paid_msat`, `fee_rcvd_msat`).
Changelog-Deprecated: JSON-RPC: `listpeers`.`funded` fields `local_msat` and `remote_msat` are now deprecated.
2022-07-31 21:53:05 +09:30
Rusty Russell 8c9fa457ba pytest: fix flake in test_gossip_timestamp_filter
```
        # 0x0100 = channel_announcement
        # 0x0102 = channel_update
        # (Node announcement may have any timestamp)
        types = Counter([m[0:4] for m in msgs])
        assert types['0100'] == 1
>       assert types['0102'] == 2
E       assert 1 == 2

tests/test_gossip.py:324: AssertionError
```

Examining the logs shows that we ask l4 for timestamps
"first_timestamp=1658892115 timestamp_range=13", and the timestamp on
the missing update is exactly `1658892128`.

So round the end time up by 1 for filtering.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-07-28 15:08:44 +09:30
Rusty Russell 22ff007d64 connectd: control connect backoff from lightningd.
We used to tell connectd to remember our connect delay, and hand it
back (increased if necessary).

Instead, simply record when we last tried to connect.  If it was less
than 10 minutes ago, double delay (up to 5 minutes max), otherwise
reset delay to 1 second.

This covers all scenarios: whether we reconnect then immediately
disconnect, or never successfully connect, it doesn't matter.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Fixes: #5453
2022-07-28 15:08:44 +09:30
Rusty Russell 9cad7d6a6a lightningd: don't consider AWAITING_UNILATERAL to be "active".
It's not active: we don't want to connect.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-07-28 15:08:44 +09:30
Rusty Russell a259698906 pytest: test that we don't try to reconnect in AWAITING_UNILATERAL.
We would just send an error, and it's annoying.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-07-28 15:08:44 +09:30
niftynei e048292fdf bkpr-zeroconf: Zeroconfs will emit 'channel_proposed' event
Keep the accounts as an 'append only' log, instead we move the marker
for the 'channel_open' forward when a 'channel_open' comes out.

We also neatly hide the 'channel_proposed' events in 'inspect' if
there's a 'channel_open' for that same event.

If you call inspect before the 'channel_open' is confirmed, you'll see
the tag as 'channel_proposed', afterwards it shows up as
'channel_open'. However the event log rolls forward -- listaccountevents
will show the correct history of the proposal then open confirming (plus
any routing that happened before the channel confirmed).
2022-07-28 12:08:18 +09:30
niftynei 30aa1d79fb bkpr: for zerconfs, we still wanna know you're opening a channel
We need a record of the channel account before you start sending
payments through it. Normally we don't start allowing payments to be
sent until after the channel has locked in but zeroconf does away with
this assumption.

Instead we push out a "channel_proposed" event, which should only show
up for zeroconfs.
2022-07-28 12:08:18 +09:30
niftynei 3c79a456c0 test-db-provider: if postgres in tests, startup a bookkeeper db
FXIME: Has a edge case where if you disable the bookkeeper, it'll
blowup because you've got an option that isn't present anywhere...
2022-07-28 12:08:18 +09:30
niftynei e5d3ce3b1f bkpr incomestmt: properly escape things for the CSVs
First off, when we pull data out of JSON, unescape it so we don't end up
with extraneous escapes in our bookkeeping data. I promise, it's worth
it.

Then, when we print descriptions out to the csvs, we gotta wrap
everything in quotes... but also we have to change all the double-quotes
to singles so that adding the quotes doesn't do anything untoward.

We also just pass it thru json_escape to get rid of linebreaks etc.

Note that in the tests we do a byte comparison instead of converting the
CSV dumps to strings because python will escape the strings on
conversion...
2022-07-28 12:08:18 +09:30
niftynei 5146baa00b bkpr csvs: koinly + cointracker only accept fees on the same line
So we print out invoice fees on the same line for those CSVs! This means
we have to do a little bit of gymnastics (but not too bad):
	- we save the fee amount onto the income event now so we can use
it later
	- we ignore every "invoice_fee" event for the koinly/cointracker

Note that since we're not skipping income events in the loops we also
move the newline character to the start of every `_entry` function so
skipped records dont incur empth lines.

Changelog-Added: bkpr: print out invoice fees on the same line for `koinly` and `cointracker` csv types
2022-07-28 12:08:18 +09:30
niftynei 352b419755 bkpr: save invoice description data to the database and display it
It'll be really nice to be able to read description data about an
invoice, if we've got it!
2022-07-28 12:08:18 +09:30
niftynei ab94c557c7 bkpr: add test for bookkeeper being added after channel has closed
We rescan and pick up the channel's close tx, but can't go back and
get the open info, since we've already deleted the channel from the
database.
2022-07-28 12:08:18 +09:30
niftynei 0617690981 coin_mvt/bkpr: add "stealable" tag to stealable outputs
If we expect further events for an onchain output (because we can steal
it away from the 'external'/rightful owner), we mark them.

This prevents us from marking a channel as 'onchain-resolved' before
all events that we're interested in have actually hit the chain.

Case that this matters:
Peer publishes a (cheating) unilateral close and a timeout htlc (which
we can steal).
We then steal the timeout htlc.

W/o the stealable flag, we'd have marked the channel as resolved when
the peer published the timeout htlc, which is incorrect as we're still
waiting for the resolution of that timeout htlc (b/c we *can* steal it).
2022-07-28 12:08:18 +09:30
niftynei c1cef773ca bkpr: make sure there's always at least on difference in blockheights
We can't divide by zero, so make sure it's always 1 (with a small loss
of precision for other cases, ce la vie)
2022-07-28 12:08:18 +09:30
niftynei d72033882f bkpr: check for channel resolution for any "originated" event
We were failing to mark channels as resolved b/c we weren't using later
events to external (but originated from this account) events as signals
to run the channel resolution check.

This fixes that, and adds a test.
2022-07-28 12:08:18 +09:30
niftynei 563910e667 bkpr: add docs, change names to 'bkpr-*'
Adds schema definitions and manpages for bkpr- commands; also renames
the commands to all start with 'bkpr-', so they're easier to identify/
make runes about.
2022-07-28 12:08:18 +09:30
niftynei e2ef44c043 bkpr: add 'msat' suffix to all msat denominated fields
Makes our json schema parsing work as expected.
2022-07-28 12:08:18 +09:30
niftynei a3d82d5a01 bkpr: exclude non-wallet events in the balance snapshot
Anchor outputs are ignored by the clightning wallet, but we keep track
of them in the bookkeeper. This causes problems when we do the balance
checks on restart w/ the balance_snapshot -- it results in us printing
out a journal_entry to 'get rid of' the anchors that the clightning node
doesnt know about.

Instead, we mark some outputs as 'ignored' and exclude these from our
account balance sums when we're comparing to the clightning snapshot.
2022-07-28 12:08:18 +09:30
niftynei eae1236db7 tests,bkpr: liquid fails all these for different reasons
- external wallet not supported yet for elements
- the close fails to propagate b/c the outputs are dusty (FIXME)
2022-07-28 12:08:18 +09:30
niftynei e7ed196f87 bkpr: separate the invoice_fees from the invoice paid
For income events, break out the amount paid in routing fees vs the
total amount of the *invoice* that is paid.

Also printout these fees, when available, on listaccountevents
2022-07-28 12:08:18 +09:30
niftynei 4326c08927 test nit: wait_for_mempool cleanup
Wait for mempool=1 before making a block
2022-07-28 12:08:18 +09:30
niftynei a7b7ea5d49 bkpr: add a 'consolidate-fees' flag to the income stmt
Defaults to true. This is actually what you want to see -- the fees for
an account's txid collapsed into a single entry.
2022-07-28 12:08:18 +09:30
niftynei 83c6cf25d2 bkpr: 'to_miner' spends are considered terminal
This is a rare case where we RBF the output of a penalty until it no
longer has an output value we can reclaim. We ignore the txid for these
events when closing a channel.
2022-07-28 12:08:18 +09:30
niftynei 1dd52ba003 bkpr: mark external deposits (withdraws) via blockheight when confirmed
We issue events for external deposits (withdrawals) before the tx is
confirmed in a block. To avoid double counting these, we don't count
them as confirmed/included until after they're confirmed. We do this
by keeping the blockheight as zero until the withdraw for the input for
them comes through.

Note that since we don't have any way to note when RBF'd withdraws
aren't eligible for block inclusion anymore, we don't really have a good
heuristic to trim them. Which is fine, they *will* show up in account
events however.
2022-07-28 12:08:18 +09:30
niftynei 25f0c76c9a tests: move 'bookkeeper' centric tests to their own file
Should we pull these out into a separate test suite?
2022-07-28 12:08:18 +09:30
niftynei 5f41d9247e bkpr: properly account for onchain fees for channel closes
onchain fees are weird at channel close because:

- you may be missing an trimmed htlc (which went to fees)
- the balance from close may have been rounded (msats cant land on
chain)
- the close might have been a past state and you've actually
  ended up with more money onchain than you had in the channel. wut

This commit accounts for all of this appropriately, with some tests.

channel_close.debit should equal onchain_fee.credit (for that txid)
plus sum(chain_event.credit [wallet/channel_acct]).

In the penalty case, channel_close.debit becomes channel_close.debit +
penalty_adj.debit, i.e.

	channel-close.debit + (penalty_adj.debit) =
		onchain_fee.credit
	      + sum(chain_event.credit [wallet/channel_acct])
2022-07-28 12:08:18 +09:30
Rusty Russell 1c26ebdb31 pytest: fix flake in test_wumbo_channels
We might only have seen one side of the channel, as shown below.  Wait
for both:

```
_____________________________ test_wumbo_channels ______________________________
[gw2] linux -- Python 3.7.13 /opt/hostedtoolcache/Python/3.7.13/x64/bin/python3

node_factory = <pyln.testing.utils.NodeFactory object at 0x7f5d51743b10>
bitcoind = <pyln.testing.utils.BitcoinD object at 0x7f5d51699d10>

    @pytest.mark.openchannel('v1')
    @pytest.mark.openchannel('v2')
    def test_wumbo_channels(node_factory, bitcoind):
        l1, l2, l3 = node_factory.get_nodes(3,
                                            opts=[{'large-channels': None},
                                                  {'large-channels': None},
                                                  {}])
        conn = l1.rpc.connect(l2.info['id'], 'localhost', port=l2.port)
    
        expected_features = expected_peer_features(wumbo_channels=True)
        if l1.config('experimental-dual-fund'):
            expected_features = expected_peer_features(wumbo_channels=True,
                                                       extra=[21, 29])
    
        assert conn['features'] == expected_features
        assert only_one(l1.rpc.listpeers(l2.info['id'])['peers'])['features'] == expected_features
    
        # Now, can we open a giant channel?
        l1.fundwallet(1 << 26)
        l1.rpc.fundchannel(l2.info['id'], 1 << 24)
    
        # Get that mined, and announced.
        bitcoind.generate_block(6, wait_for_mempool=1)
    
        # Connect l3, get gossip.
        l3.rpc.connect(l1.info['id'], 'localhost', port=l1.port)
        wait_for(lambda: len(l3.rpc.listnodes(l1.info['id'])['nodes']) == 1)
        wait_for(lambda: 'features' in only_one(l3.rpc.listnodes(l1.info['id'])['nodes']))
    
        # Make sure channel capacity is what we expected.
>       assert ([c['amount_msat'] for c in l3.rpc.listchannels()['channels']]
                == [Millisatoshi(str(1 << 24) + "sat")] * 2)
E       assert [16777216000msat] == [16777216000m...777216000msat]
E         Right contains one more item: 16777216000msat
E         Full diff:
E         - [16777216000msat, 16777216000msat]
E         + [16777216000msat]
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-07-27 19:31:04 +09:30
niftynei 2c2bcc8eb4 flake: permit test_v2_open_sigs_restart_while_dead to succeed/fail
There's a race btw disconnecting and returning a successful RPC call for
openchannel_signed; if we disconnect quickly, we get an RPC error back.

Too slow and it returns w/o an error.

This needs to be cleaned up on a whole, work that I'm planning to get
into as part of a funder re-write. For now, let's just let the test
continue whether this call succeeds or fails.
2022-07-27 19:31:04 +09:30
niftynei f4abc3a661 tests: local flake fix; l1 was waiting too long to reconnect
Impacts local tests, when TIMEOUT is set low...
2022-07-26 15:11:30 -07:00
Rusty Russell 17b9bd5ca3 pytest: fix test_commando_rune flake.
We reset counters every minute, so ratelimit tests can flake since we
might hit that boundary.

Instead, wait for the reset then test explicitly, assuming that takes
less than 60 seconds.

```
        for rune, cmd, params in failures:
            print("{} {}".format(cmd, params))
            with pytest.raises(RpcError, match='Not authorized:') as exc_info:
                l2.rpc.call(method='commando',
                            payload={'peer_id': l1.info['id'],
                                     'rune': rune['rune'],
                                     'method': cmd,
>                                    'params': params})
E               Failed: DID NOT RAISE <class 'pyln.client.lightning.RpcError'>
...
DEBUG:root:Calling commando with payload {'peer_id': '0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518', 'rune': 'O8Zr-ULTBKO3_pKYz0QKE9xYl1vQ4Xx9PtlHuist9Rk9NCZwbnVtPTAmcmF0ZT0zJnJhdGU9MQ==', 'method': 'getinfo', 'params': {}}
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-07-26 09:48:56 -07:00
Rusty Russell 85180dbfee pytest: fix flake in test_feerates
As the comment in set_feerates says: "Technically, this waits until
it's called, not until it's processed.".

And the wait_for() line doesn't work, since that condition is already true.

```
    @unittest.skipIf(TEST_NETWORK == 'liquid-regtest', "Fees on elements are different")
    @unittest.skipIf(
        not DEVELOPER or DEPRECATED_APIS, "Without DEVELOPER=1 we snap to "
        "FEERATE_FLOOR on testnets, and we test the new API."
    )
    def test_feerates(node_factory):
        l1 = node_factory.get_node(options={'log-level': 'io',
                                            'dev-no-fake-fees': True}, start=False)
        l1.daemon.rpcproxy.mock_rpc('estimatesmartfee', {
            'error': {"errors": ["Insufficient data or no feerate found"], "blocks": 0}
        })
        l1.start()
    
        # All estimation types
        types = ["opening", "mutual_close", "unilateral_close", "delayed_to_us",
                 "htlc_resolution", "penalty"]
    
        # Try parsing the feerates, won't work because can't estimate
        for t in types:
            with pytest.raises(RpcError, match=r'Cannot estimate fees'):
                feerate = l1.rpc.parsefeerate(t)
    
        # Query feerates (shouldn't give any!)
        wait_for(lambda: len(l1.rpc.feerates('perkw')['perkw']) == 2)
        feerates = l1.rpc.feerates('perkw')
        assert feerates['warning_missing_feerates'] == 'Some fee estimates unavailable: bitcoind startup?'
        assert 'perkb' not in feerates
        assert feerates['perkw']['max_acceptable'] == 2**32 - 1
        assert feerates['perkw']['min_acceptable'] == 253
        for t in types:
            assert t not in feerates['perkw']
    
        wait_for(lambda: len(l1.rpc.feerates('perkb')['perkb']) == 2)
        feerates = l1.rpc.feerates('perkb')
        assert feerates['warning_missing_feerates'] == 'Some fee estimates unavailable: bitcoind startup?'
        assert 'perkw' not in feerates
        assert feerates['perkb']['max_acceptable'] == (2**32 - 1)
        assert feerates['perkb']['min_acceptable'] == 253 * 4
        for t in types:
            assert t not in feerates['perkb']
    
        # Now try setting them, one at a time.
        # Set CONSERVATIVE/2 feerate, for max
        l1.set_feerates((15000, 0, 0, 0), True)
        wait_for(lambda: len(l1.rpc.feerates('perkw')['perkw']) == 2)
        feerates = l1.rpc.feerates('perkw')
        assert feerates['warning_missing_feerates'] == 'Some fee estimates unavailable: bitcoind startup?'
        assert 'perkb' not in feerates
>       assert feerates['perkw']['max_acceptable'] == 15000 * 10
E       assert 4294967295 == (15000 * 10)

tests/test_misc.py:1392: AssertionError
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-07-26 09:48:56 -07:00
Rusty Russell 0a9a87ec10 pytest: fix test_commando_stress
On fast machines, we don't get failures sometimes on commando commands.

(*But* we still got "New cmd replacing old" messages, which is how I
realized we weren't freeing them promptly, hence the previous fix).

```
        # Should have exactly one discard msg from each discard
>       nodes[0].daemon.wait_for_logs([r"New cmd from .*, replacing old"] * discards)

tests/test_plugin.py:2839: 
...
>                   raise TimeoutError('Unable to find "{}" in logs.'.format(exs))
E                   TimeoutError: Unable to find "[]" in logs.

```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-07-26 09:33:40 -07:00
Rusty Russell 8da361b49b pytest: fix flake in test_channel_persistence w/ TEST_CHECK_DBSTMTS
This was weird.  Here is the message (with \n turned into real new lines):

```
2022-07-24T07:20:08.9144998Z Plugin '/home/runner/work/lightning/lightning/tests/plugins/dblog.py' returned an invalid response to the db_write hook: {"jsonrpc": "2.0", "id": 40, "error": {"code": -32600, "message": "Error while processing db_write: UNIQUE constraint failed: shachain_known.shachain_id, shachain_known.pos", "traceback": "Traceback (most recent call last):
  File \"/home/runner/work/lightning/lightning/contrib/pyln-client/pyln/client/plugin.py\", line 631, in _dispatch_request
    result = self._exec_func(method.func, request)
  File \"/home/runner/work/lightning/lightning/contrib/pyln-client/pyln/client/plugin.py\", line 616, in _exec_func
    return func(*ba.args, **ba.kwargs)
  File \"/home/runner/work/lightning/lightning/tests/plugins/dblog.py\", line 45, in db_write
    plugin.conn.execute(c)
sqlite3.IntegrityError: UNIQUE constraint failed: shachain_known.shachain_id, shachain_known.pos
"}}
```

Finally, I realized that we *kill* l2: this means it has updated the
plugin db but not the real db.  This is expected: a real backup plugin
would handle this case.

Simply disable the test for this case.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-07-26 09:33:40 -07:00