Commit Graph

802 Commits

Author SHA1 Message Date
Rusty Russell
247d249ea8 gossipd: provide helper to get a channels cupdate, create routine to use it.
The idea is that gossipd can give us the cupdate we need for an error, and
we wire things up so that we ask for it (async) just before we send the
error to the subdaemon.

I tried many other things, but they were all too high-risk.

1. We need to ask gossipd every time, since it produces these lazily
   (in particular, it doesn't actually generate an offline update unless
   the channel is used).
2. We can't do async calls in random places, since we'll end up with
   an HTLC in limbo.  What if another path tries to fail it at the same time?
3. This allows us to use a temporary_node_failure error, and upgrade it
   when gossipd replies.  This doesn't change any existing assumptions.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-02-28 09:44:47 +10:30
Rusty Russell
2aad3ffcf8 common: tal_dup_talarr() helper.
This is a common thing to do, so create a macro.

Unfortunately, it still needs the type arg, because the paramter may
be const, and the return cannot be, and C doesn't have a general
"(-const)" cast.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-02-27 14:16:16 +10:30
Rusty Russell
c9e73dc4e0 lightningd: rename htlc_in field from failcode to badonion.
That's all it's used for now.

And remove unreferenced failoutchannel.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-02-25 11:12:12 +10:30
Rusty Russell
447730e70f wallet: only store BADONION codes in db for incoming htlcs: rest are all onionreplyies.
This completes the conversion; any in-flight HTLC failures get turned into temporary_node_failures.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-02-25 11:12:12 +10:30
Rusty Russell
72d55d3e3b lightningd: store raw msg rather than code for locally-failed outgoing HTLCs
At the moment, we store e.g. WIRE_TEMPORARY_CHANNEL_FAILURE, and then
lightningd has a large demux function which turns that into the correct
error message.

Such an enum demuxer is an anti-pattern.

Instead, store the message directly for output HTLCs; channeld now
sends us an error message rather than an error code.

For input HTLCs we will still need the failure code if the onion was
bad (since we need to prompt channeld to send a completely different
message than normal), though we can (and will!) eliminate its use in
non-BADONION failure cases.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-02-25 11:12:12 +10:30
Rusty Russell
a150b09665 wallet: Add new htlc column "localfailmsg" for outgoing htlcs.
We're going to change our internal structure next, so this is preparation.
We populate existing errors with temporary node failures, for simplicity.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-02-25 11:12:12 +10:30
Rusty Russell
ed839bfda0 channeld: get the onionreply back from lightningd for failed htlcs.
Instead of making it ourselves, lightningd does it.  Now we only have
two cases of failed htlcs: completely malformed (BADONION), and with
an already-wrapped onion reply to send.

This makes channeld's job much simpler.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-02-25 11:12:12 +10:30
Rusty Russell
7ab5c424b6 gossipd: provide (stripped) channel_update when resolving a channel.
I hadn't realized that lightningd asks gossipd every time we forward
a payment.  But I'm going to abuse it here to get the latest channel_update,
otherwise (as lightningd takes over error message generation) lightningd
needs to do an async request at various painful points.

So have gossipd tell us the lastest update (stripped so compatible with
the strange in-onion-error format).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-02-25 11:12:12 +10:30
Rusty Russell
c7bbdd76d3 lightningd: handle fail_htlc_in with no known outgoing channel.
Turn it into temporary node failure: this only happens if we restart
with a failed htlc in, but it's clearer and more robust to handle it
generically.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-02-25 11:12:12 +10:30
Rusty Russell
b84b4b4695 lightningd: rename htlc_in and htlc_out failuremsg fields to failonion.
This is clearer, especially when we also deal with raw not-yet-onion-wrapped
failure messages.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-02-25 11:12:12 +10:30
Rusty Russell
d478dc0e59 wallet: fix null column access for pre-0.7.3 dbs.
Added in d901304120, this column is null in old dbs like mine:

2020-02-15T00:08:41.444Z **BROKEN** database: Accessing a null column 12 in query SELECT  id, channel_htlc_id, msatoshi, cltv_expiry, hstate, payment_hash, payment_key, routing_onion, failuremsg, malformed_onion, origin_htlc, shared_secret, received_time FROM channel_htlcs WHERE direction= ? AND channel_id= ? AND hstate != ?

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-02-18 10:22:58 +10:30
Rusty Russell
fc4d01cd9d db: put scids in forwards even if we didn't actually send.
If the peer is not connected, or other error which means we don't
actually create an outgoing HTLC, we don't record the
short_channel_id.  This is unhelpful!

Pass the scid down to the wallet code, and explicitly hand the
scid and amount down to the notification code rather than handing it
the htlc_out (which it doesn't need).

Changelog-Changed: JSON API: `listforwards` now shows `out_channel` even if we couldn't forward.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-02-12 22:27:57 -06:00
darosior
c79ab0f1b0 lightningd/bitcoind: use the Bitcoin plugin for getutxout 2020-02-12 11:45:07 +10:30
darosior
947f5ddde1 lightningd/bitcoind: use the Bitcoin plugin to send transactions
This restrains the informations we get about how the sending went to
an errmsg as we cant rely on bitcoin-cli specific output nor its exit code.
2020-02-12 11:45:07 +10:30
Vasil Dimov
18a40c0c5d build: re-record the result of make update-mocks
Changelog-None
2020-02-03 15:38:11 +00:00
darosior
a589daa235 wallet: fuzz the nLockTime added to withdraw transactions 2020-02-03 00:45:27 +00:00
darosior
273029f244 wallet: set nLockTime to the tip for withdrawal transactions
This sets the nLockTime to the tip (and accordingly each input's nSequence to
0xfffffffe) for withdrawal transactions.

Even if the anti fee-sniping argument might not be valid until some time yet,
this makes our regular wallet transactions far less distinguishable from
bitcoind's ones since it now defaults to using native Segwit transactions
(like us). Moreover other wallets are likely to implement this (if they
haven't already).

Changelog-Added: wallet: withdrawal transactions now sets nlocktime to the current tip.
2020-02-03 00:45:27 +00:00
Vasil Dimov
55173a56b7 Use dedicated type for error codes
Before this patch we used `int` for error codes. The problem with
`int` is that we try to pass it to/from wire and the size of `int` is
not defined by the standard. So a sender with 4-byte `int` would write
4 bytes to the wire and a receiver with 2-byte `int` (for example) would
read just 2 bytes from the wire.

To resolve this:

* Introduce an error code type with a known size:
  `typedef s32 errcode_t`.

* Change all error code macros to constants of type `errcode_t`.
  Constants also play better with gdb - it would visualize the name of
  the constant instead of the numeric value.

* Change all functions that take error codes to take the new type
  `errcode_t` instead of `int`.

* Introduce towire / fromwire functions to send / receive the newly added
  type `errcode_t` and use it instead of `towire_int()`.

In addition:

* Remove the now unneeded `towire_int()`.

* Replace a hardcoded error code `-2` with a new constant
  `INVOICE_EXPIRED_DURING_WAIT` (903).

Changelog-Changed: The waitinvoice command would now return error code 903 to designate that the invoice expired during wait, instead of the previous -2
2020-01-31 06:02:47 +00:00
Christian Decker
ccec64d63c peer: Add custommsg hook and wire it into channeld and openingd 2020-01-28 23:50:52 +01:00
Christian Decker
3c88d5c8c4 openingd: Implement sendcustommsg handling in openingd
Most of the work is done in `lightningd`, here we just need to queue the
message itself.
2020-01-28 23:50:52 +01:00
Christian Decker
3ad8438d91 json-rpc: Add sendcustommsg command
This command injects a custom message into the encrypted transport stream to
the peer, allowing users to build custom protocols on top of c-lightning
without requiring any changes to c-lightning itself.
2020-01-28 23:50:52 +01:00
Rusty Russell
262e4c840f sphinx: use struct secret for shared secret.
Generally I prefer structures over u8, since the size is enforced at
runtime; and in several places we were doing conversions as the code
using Sphinx does treat struct secret as type of the secret.

Note that passing an array is the same as passing the address, so
changing from 'u8 secret[32]' to 'struct secret secret' means various
'secret' parameters change to '&secret'.  Technically, '&secret' also
would have worked before, since '&' is a noop on array, but that's
always seemed a bit weird.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-01-24 10:01:44 +10:30
Rusty Russell
1099f6a5e1 common: use struct onionreply.
This makes it clear we're dealing with a message which is a wrapped error
reply (needing unwrap_onionreply), not an already-wrapped one.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-01-23 16:17:42 +10:30
Rusty Russell
aa6aad0131 common: add struct onionreply
I really want a type which means "I am a wrapped onion reply" as separate
from "I am a normal wire msg".  Currently both user u8 *, and I got very
confused trying to figure out where each one was an unwrapped error msg,
or where it still needed (un)wrapping.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-01-23 16:17:42 +10:30
Rusty Russell
ddce5573c7 channeld: use wirestring for failure strings.
I think this code predated wirestring.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-01-23 16:17:42 +10:30
Christian Decker
4be1868b8a pay: Invert ownership of wallet_payment
`wallet_payment_store` would free the `wallet_payment` instance which would
then cause us to reload it from the DB. Instead of doing the store->free->load
dance we now tell `wallet_payment_store` whether it should take ownership and
leave it alone if not.

Passing the payment around instead of referencing it through payment_hash and
partid is a nice side-effect.
2020-01-13 23:34:46 +01:00
Vasil Dimov
2ea91f834c Add the missing space between "if" and "("
Changelog-None
2020-01-06 12:57:59 +01:00
Christian Decker
3f3a48dae9 db: Turn the transaction counter into an optimistic lock
The optimistic lock prevents multiple instances of c-lightning making
concurrent modifications to the database. That would be unsafe as it messes up
the state in the DB. The optimistic lock is implemented by checking whether a
gated update on the previous value of the `data_version` actually results in
an update. If that's not the case the DB has been changed under our feet.

The lock provides linearizability of DB modifications: if a database is
changed under the feet of a running process that process will `abort()`, which
from a global point of view is as if it had crashed right after the last
successful commit. Any process that also changed the DB must've started
between the last successful commit and the unsuccessful one since otherwise
its counters would not have matched (which would also have aborted that
transaction). So this reduces all the possible timelines to an equivalent
where the first process died, and the second process recovered from the DB.

This is not that interesting for `sqlite3` where we are also protected via the
PID file, but when running on multiple hosts against the same DB, e.g., with
`postgres`, this protection becomes important.

Changelog-Added: DB: Optimistic logging prevents instances from running concurrently against the same database, providing linear consistency to changes.
2020-01-02 14:12:59 -06:00
Christian Decker
2c11c54dd2 db: Track the data_version in the database
This increments the `data_version` upon committing dirty transactions, reads
the last data_version upon startup, and tracks the number in memory in
parallel to the DB (see next commit for rationale).

Changelog-Changed: JSON-RPC: Added a `data_version` field to the `db_write` hook which returns a numeric transaction counter.
2020-01-02 14:12:59 -06:00
Christian Decker
4a4184be70 db: Add numeric data_version counter to count modifying transactions
This counter is incremented on each dirty transaction.
2020-01-02 14:12:59 -06:00
Christian Decker
09247d4f95 db: Add tracking of whether the current transaction is dirty 2020-01-02 14:12:59 -06:00
Christian Decker
097af493dd db: Move db_migrate transaction up one level
We are about to do some more operations before committing, so moving this up
allows us to reuse the same transaction.
2020-01-02 14:12:59 -06:00
Christian Decker
6020a0d587 db: Consolidate access to the changes in a db
We were passing them in separately, while we could just retrieve them from the
db instance instead.
2020-01-02 14:12:59 -06:00
lisa neigut
700b766ce1 wallet: remove edgecase around transaction checks
we don't populate the tx item when we're running a transaction check
from deep chain (prior to a chain replay)
2020-01-02 16:56:42 +01:00
Rusty Russell
72aa315b5e lightningd: save the fee_states into the database.
This is the final step: we pass the complete fee_states to and from
channeld.

Changelog-Fixed: "Bad commitment signature" closing channels when we sent back-to-back update_fee messages across multiple reconnects.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2019-12-12 22:15:48 +01:00
Rusty Russell
4270031d75 wallet: add per-channel feerate_state to the database.
The upgrade here is a bit tricky: we map the two values into the
feerate_state.  This is trivial if they're both the same, but if
they're different we don't know exactly what state they're in (this
being the source of the bug!).

So, we assume that the have received the update and not acked it,
as that would be the normal case.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2019-12-12 22:15:48 +01:00
Rusty Russell
8e3234e67a lightningd: sew in htlc set.
The invoice_try_pay code now takes a set, rather than a single htlc, but
it's basically the same thing.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2019-12-12 15:03:53 +01:00
Rusty Russell
12985331f7 htlcs: remove origin_htlc_id from htlc_out.
This is a transient field, so rework things so we don't leave it in
struct htlc_out.  Instead, load htlc_in first and connect htlc_out to
them as we go.

This also changes one place where we use it instead of the am_origin
flag.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2019-12-12 15:03:53 +01:00
Rusty Russell
345ca9b122 db: add partid field to htlc_out.
This is in preparation for partial payments.  For existing payments,
partid is 0 (to match the corresponding payment).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2019-12-12 15:03:53 +01:00
Rusty Russell
2d18c3a209 db: add partid, total_msat fields to payment entries.
This is in preparation for partial payments.  For existing payments,
partid is 0 (arbitrarity) and total_msat is msatoshi.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2019-12-12 15:03:53 +01:00
Christian Decker
9660549b0c changelog: Update changelog for the 0.7.4 release 2019-12-12 00:15:23 +01:00
Christian Decker
ff5f7b194f sphinx: Return the error in parse_onionpacket
As suggested by @niftynei here: https://github.com/ElementsProject/lightning/pull/3260#discussion_r347543999

Suggested-by: Lisa Neigut <@niftynei>
Suggested-by: Rusty Russell <@rustyrussell>
Signed-off-by: Christian Decker <@cdecker>
2019-12-11 16:18:34 +01:00
Rusty Russell
f7ebbb2ec5 common: make sphinx code ignorant of payload format.
Now "raw_payload" is always the complete string (including realm or length
bytes at the front).

This has several effects:
1. We can receive an decrypt an onion which is grossly malformed.
2. We can still hand this to the htlc_accepted hook.
3. We then fail it unless the htlc_accepted accepts it manually.
4. The createonion API now takes the raw payload, and does not know
   anything about "style".

The only caveat is that the sphinx code needs to know the payload
length: we have a call for that, which simply tells it to copy the
entire onion (and treat us as the final node) if it's invalid.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2019-12-09 14:33:31 +01:00
Christian Decker
69c17d2d31 wire: Let the TLV _is_valid function actually return validity
I got this one wrong myself, since the function name implied a boolean
result. So I changed it to take the optional err_index as argument.
2019-12-03 00:37:15 +00:00
Christian Decker
16b6c31010 json-rpc: Add the error onion if we stored it in the DB
If we can't decode the onion, because the onion got corrupted or we used
`sendonion` without specifying the `shared_secrets` used, the best we can do
is tell the caller instead.
2019-12-01 15:40:47 +01:00
Christian Decker
1cf3c12a81 cleanup: The failchannel is not tal-allocated when first assigned
This makes the copy on write redundant.
2019-12-01 15:40:47 +01:00
Christian Decker
27547ce8d4 pay: Allow sendonion callers to provide shared_secrets
This means that c-lightning can now internally decrypt an eventual error
message, and not force the caller to implement the decryption. The main
difficulty was that we now have a new state (channels and nodes not specified,
while shared_secrets are specified) which needed to be handled.
2019-12-01 15:40:47 +01:00
Christian Decker
b8ce175fd2 pay: Handle payment failures resulting from sendonion correctly
We are breaking with a couple of assumptions, namely that we have the
`path_secrets` to decode the error onion. If this happens we just want it to
error out.
2019-12-01 15:40:47 +01:00
Christian Decker
41221b6ecb pay: Make wallet_payment->destination optional
If we use `sendonion` we don't actually know the destination, so we
make the destination a pointer which is NULL if we don't know.
2019-12-01 15:40:47 +01:00
Rusty Russell
b9a03a08ef wallet/Makefile: fix dependency line.
The .o files need regen, not the .c files!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2019-11-28 11:50:13 +01:00