channel: now we're always complete, fields don't have to be optional.

Now any struct channel is a genuine channel, the following fields are
always valid:

1. funding_txid: doesn't need to be a pointer.
2. our_msatoshi: doesn't need to be a pointer.
3. last_sig: doesn't need to be a pointer.
4. channel_info: doesn't need to be a pointer.

In addition, 'last_tx' is always valid.

The main effect is to remove a whole heap of branches from the wallet code.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2018-02-19 11:36:12 +10:30
parent 8db8c51201
commit e0603d7221
8 changed files with 165 additions and 270 deletions

View File

@ -158,8 +158,7 @@ void channel_set_last_tx(struct channel *channel,
struct bitcoin_tx *tx,
const secp256k1_ecdsa_signature *sig)
{
tal_free(channel->last_sig);
channel->last_sig = tal_dup(channel, secp256k1_ecdsa_signature, sig);
channel->last_sig = *sig;
tal_free(channel->last_tx);
channel->last_tx = tal_steal(channel, tx);
}

View File

@ -3,6 +3,7 @@
#include "config.h"
#include <ccan/list/list.h>
#include <lightningd/peer_state.h>
#include <lightningd/peer_htlcs.h>
#include <wallet/wallet.h>
struct uncommitted_channel;
@ -48,8 +49,8 @@ struct channel {
u64 next_index[NUM_SIDES];
u64 next_htlc_id;
/* Funding txid and amounts (once known) */
struct bitcoin_txid *funding_txid;
/* Funding txid and amounts */
struct bitcoin_txid funding_txid;
u16 funding_outnum;
u64 funding_satoshi, push_msat;
bool remote_funding_locked;
@ -57,15 +58,15 @@ struct channel {
struct short_channel_id *scid;
/* Amount going to us, not counting unfinished HTLCs; if we have one. */
u64 *our_msatoshi;
u64 our_msatoshi;
/* Last tx they gave us (if any). */
/* Last tx they gave us. */
struct bitcoin_tx *last_tx;
secp256k1_ecdsa_signature *last_sig;
secp256k1_ecdsa_signature last_sig;
secp256k1_ecdsa_signature *last_htlc_sigs;
/* Keys for channel. */
struct channel_info *channel_info;
/* Keys for channel */
struct channel_info channel_info;
/* Secret seed (FIXME: Move to hsm!) */
struct privkey seed;

View File

@ -206,7 +206,7 @@ static void sign_last_tx(struct channel *channel)
funding_wscript = bitcoin_redeem_2of2(tmpctx,
&local_funding_pubkey,
&channel->channel_info->remote_fundingkey);
&channel->channel_info.remote_fundingkey);
/* Need input amount for signing */
channel->last_tx->input[0].amount = tal_dup(channel->last_tx->input, u64,
&channel->funding_satoshi);
@ -217,9 +217,9 @@ static void sign_last_tx(struct channel *channel)
channel->last_tx->input[0].witness
= bitcoin_witness_2of2(channel->last_tx->input,
channel->last_sig,
&channel->last_sig,
&sig,
&channel->channel_info->remote_fundingkey,
&channel->channel_info.remote_fundingkey,
&local_funding_pubkey);
tal_free(tmpctx);
@ -585,11 +585,8 @@ static struct channel *channel_by_channel_id(struct peer *peer,
list_for_each(&peer->channels, channel, list) {
struct channel_id cid;
if (!channel->funding_txid)
continue;
derive_channel_id(&cid,
channel->funding_txid,
&channel->funding_txid,
channel->funding_outnum);
if (structeq(&cid, channel_id))
return channel;
@ -836,16 +833,13 @@ static void gossipd_getpeers_complete(struct subd *gossip, const u8 *msg,
json_add_short_channel_id(response,
"short_channel_id",
channel->scid);
if (channel->funding_txid)
json_add_txid(response,
"funding_txid",
channel->funding_txid);
if (channel->our_msatoshi) {
json_add_u64(response, "msatoshi_to_us",
*channel->our_msatoshi);
json_add_u64(response, "msatoshi_total",
channel->funding_satoshi * 1000);
}
json_add_txid(response,
"funding_txid",
&channel->funding_txid);
json_add_u64(response, "msatoshi_to_us",
channel->our_msatoshi);
json_add_u64(response, "msatoshi_total",
channel->funding_satoshi * 1000);
/* channel config */
json_add_u64(response, "dust_limit_satoshis",
@ -1445,27 +1439,27 @@ static enum watch_result funding_spent(struct channel *channel,
msg = towire_onchain_init(channel,
&channel->seed, &channel->their_shachain.chain,
channel->funding_satoshi,
&channel->channel_info->old_remote_per_commit,
&channel->channel_info->remote_per_commit,
&channel->channel_info.old_remote_per_commit,
&channel->channel_info.remote_per_commit,
/* BOLT #2:
* `to_self_delay` is the number of blocks
* that the other nodes to-self outputs
* must be delayed */
/* So, these are reversed: they specify ours,
* we specify theirs. */
channel->channel_info->their_config.to_self_delay,
channel->channel_info.their_config.to_self_delay,
channel->our_config.to_self_delay,
get_feerate(ld->topology, FEERATE_NORMAL),
channel->our_config.dust_limit_satoshis,
&channel->channel_info->theirbase.revocation,
&channel->channel_info.theirbase.revocation,
&our_last_txid,
scriptpubkey,
channel->remote_shutdown_scriptpubkey,
&ourkey,
channel->funder,
&channel->channel_info->theirbase.payment,
&channel->channel_info->theirbase.htlc,
&channel->channel_info->theirbase.delayed_payment,
&channel->channel_info.theirbase.payment,
&channel->channel_info.theirbase.htlc,
&channel->channel_info.theirbase.delayed_payment,
tx,
block->height,
/* FIXME: config for 'reasonable depth' */
@ -1584,13 +1578,13 @@ static void opening_got_hsm_funding_sig(struct channel *channel,
/* FIXME: Remove arg from cb? */
watch_txo(channel, ld->topology, channel,
channel->funding_txid, channel->funding_outnum,
&channel->funding_txid, channel->funding_outnum,
funding_spent, NULL);
json_object_start(response, NULL);
linear = linearize_tx(response, tx);
json_add_hex(response, "tx", linear, tal_len(linear));
json_add_txid(response, "txid", channel->funding_txid);
json_add_txid(response, "txid", &channel->funding_txid);
json_object_end(response);
command_success(cmd, response);
@ -1885,7 +1879,7 @@ static void peer_start_closingd(struct channel *channel,
* calculated in [BOLT
* #3](03-transactions.md#fee-calculation).
*/
feelimit = commit_tx_base_fee(channel->channel_info->feerate_per_kw[LOCAL],
feelimit = commit_tx_base_fee(channel->channel_info.feerate_per_kw[LOCAL],
0);
minfee = commit_tx_base_fee(get_feerate(ld->topology, FEERATE_SLOW), 0);
@ -1907,16 +1901,16 @@ static void peer_start_closingd(struct channel *channel,
/* Convert unit */
funding_msatoshi = channel->funding_satoshi * 1000;
/* What is not ours is theirs */
our_msatoshi = *channel->our_msatoshi;
our_msatoshi = channel->our_msatoshi;
their_msatoshi = funding_msatoshi - our_msatoshi;
initmsg = towire_closing_init(tmpctx,
cs,
gossip_index,
&channel->seed,
channel->funding_txid,
&channel->funding_txid,
channel->funding_outnum,
channel->funding_satoshi,
&channel->channel_info->remote_fundingkey,
&channel->channel_info.remote_fundingkey,
channel->funder,
our_msatoshi / 1000, /* Rounds down */
their_msatoshi / 1000, /* Rounds down */
@ -2057,8 +2051,6 @@ static bool peer_start_channeld(struct channel *channel,
struct lightningd *ld = channel->peer->ld;
const struct config *cfg = &ld->config;
assert(channel->our_msatoshi);
msg = towire_hsm_client_hsmfd(tmpctx, &channel->peer->id, HSM_CAP_SIGN_GOSSIP | HSM_CAP_ECDH);
if (!wire_sync_write(ld->hsm_fd, take(msg)))
fatal("Could not write to HSM: %s", strerror(errno));
@ -2115,27 +2107,27 @@ static bool peer_start_channeld(struct channel *channel,
initmsg = towire_channel_init(tmpctx,
&get_chainparams(ld)->genesis_blockhash,
channel->funding_txid,
&channel->funding_txid,
channel->funding_outnum,
channel->funding_satoshi,
&channel->our_config,
&channel->channel_info->their_config,
channel->channel_info->feerate_per_kw,
&channel->channel_info.their_config,
channel->channel_info.feerate_per_kw,
feerate_min(ld),
feerate_max(ld),
channel->last_sig,
&channel->last_sig,
cs, gossip_index,
&channel->channel_info->remote_fundingkey,
&channel->channel_info->theirbase.revocation,
&channel->channel_info->theirbase.payment,
&channel->channel_info->theirbase.htlc,
&channel->channel_info->theirbase.delayed_payment,
&channel->channel_info->remote_per_commit,
&channel->channel_info->old_remote_per_commit,
&channel->channel_info.remote_fundingkey,
&channel->channel_info.theirbase.revocation,
&channel->channel_info.theirbase.payment,
&channel->channel_info.theirbase.htlc,
&channel->channel_info.theirbase.delayed_payment,
&channel->channel_info.remote_per_commit,
&channel->channel_info.old_remote_per_commit,
channel->funder,
cfg->fee_base,
cfg->fee_per_satoshi,
*channel->our_msatoshi,
channel->our_msatoshi,
&channel->seed,
&ld->id,
&channel->peer->id,
@ -2192,37 +2184,33 @@ wallet_commit_channel(struct lightningd *ld,
channel->minimum_depth = uc->minimum_depth;
channel->next_index[LOCAL] = channel->next_index[REMOTE] = 1;
channel->next_htlc_id = 0;
channel->funding_txid = tal_dup(channel, struct bitcoin_txid,
funding_txid);
channel->funding_txid = *funding_txid;
channel->funding_outnum = funding_outnum;
channel->funding_satoshi = funding_satoshi;
channel->push_msat = push_msat;
channel->remote_funding_locked = false;
channel->scid = NULL;
channel->our_msatoshi = tal(channel, u64);
if (channel->funder == LOCAL)
*channel->our_msatoshi
channel->our_msatoshi
= channel->funding_satoshi * 1000 - channel->push_msat;
else
*channel->our_msatoshi = channel->push_msat;
channel->our_msatoshi = channel->push_msat;
channel->last_tx = tal_steal(channel, remote_commit);
channel->last_sig = tal_dup(channel, secp256k1_ecdsa_signature,
remote_commit_sig);
channel->last_sig = *remote_commit_sig;
channel->last_htlc_sigs = NULL;
channel->channel_info = tal_dup(channel, struct channel_info,
channel_info);
channel->channel_info = *channel_info;
/* Feerates begin identical. */
channel->channel_info->feerate_per_kw[LOCAL]
= channel->channel_info->feerate_per_kw[REMOTE]
channel->channel_info.feerate_per_kw[LOCAL]
= channel->channel_info.feerate_per_kw[REMOTE]
= feerate;
/* old_remote_per_commit not valid yet, copy valid one. */
channel->channel_info->old_remote_per_commit
= channel->channel_info->remote_per_commit;
channel->channel_info.old_remote_per_commit
= channel->channel_info.remote_per_commit;
/* Now we finally put it in the database. */
wallet_channel_insert(ld->wallet, channel);
@ -2252,7 +2240,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
assert(tal_count(fds) == 2);
/* This is a new channel_info->their_config so set its ID to 0 */
/* This is a new channel_info.their_config so set its ID to 0 */
channel_info.their_config.id = 0;
if (!fromwire_opening_funder_reply(resp, resp, NULL,
@ -2402,7 +2390,7 @@ static void opening_fundee_finished(struct subd *openingd,
log_debug(uc->log, "Got opening_fundee_finish_response");
assert(tal_count(fds) == 2);
/* This is a new channel_info->their_config, set its ID to 0 */
/* This is a new channel_info.their_config, set its ID to 0 */
channel_info.their_config.id = 0;
if (!fromwire_opening_fundee_reply(tmpctx, reply, NULL,
@ -2444,12 +2432,12 @@ static void opening_fundee_finished(struct subd *openingd,
log_debug(channel->log, "Watching funding tx %s",
type_to_string(reply, struct bitcoin_txid,
channel->funding_txid));
watch_txid(channel, ld->topology, channel, channel->funding_txid,
&channel->funding_txid));
watch_txid(channel, ld->topology, channel, &channel->funding_txid,
funding_lockin_cb, NULL);
/* FIXME: Remove arg from cb? */
watch_txo(channel, ld->topology, channel, channel->funding_txid,
watch_txo(channel, ld->topology, channel, &channel->funding_txid,
channel->funding_outnum, funding_spent, NULL);
/* On to normal operation! */
@ -2919,14 +2907,13 @@ static void activate_peer(struct peer *peer)
}
list_for_each(&peer->channels, channel, list) {
assert(channel->funding_txid);
/* This may be unnecessary, but it's harmless. */
watch_txid(channel, ld->topology, channel, channel->funding_txid,
watch_txid(channel, ld->topology, channel,
&channel->funding_txid,
funding_lockin_cb, NULL);
watch_txo(channel, ld->topology, channel,
channel->funding_txid, channel->funding_outnum,
&channel->funding_txid, channel->funding_outnum,
funding_spent, NULL);
}
}
@ -2965,10 +2952,6 @@ static void json_sign_last_tx(struct command *cmd,
command_fail(cmd, "Could has not active channel");
return;
}
if (!channel->last_tx) {
command_fail(cmd, "Peer has no final transaction");
return;
}
log_debug(channel->log, "dev-sign-last-tx: signing tx with %zu outputs",
tal_count(channel->last_tx->output));
@ -3109,7 +3092,7 @@ static void process_dev_forget_channel(struct bitcoind *bitcoind UNUSED,
json_object_start(response, NULL);
json_add_bool(response, "forced", forget->force);
json_add_bool(response, "funding_unspent", txout != NULL);
json_add_txid(response, "funding_txid", forget->channel->funding_txid);
json_add_txid(response, "funding_txid", &forget->channel->funding_txid);
json_object_end(response);
delete_channel(forget->channel, "dev-forget-channel called");
@ -3173,15 +3156,11 @@ static void json_dev_forget_channel(struct command *cmd, const char *buffer,
return;
}
if (!forget->channel->funding_txid) {
process_dev_forget_channel(cmd->ld->topology->bitcoind, NULL, forget);
} else {
bitcoind_gettxout(cmd->ld->topology->bitcoind,
forget->channel->funding_txid,
forget->channel->funding_outnum,
process_dev_forget_channel, forget);
command_still_pending(cmd);
}
bitcoind_gettxout(cmd->ld->topology->bitcoind,
&forget->channel->funding_txid,
forget->channel->funding_outnum,
process_dev_forget_channel, forget);
command_still_pending(cmd);
}
static const struct json_command dev_forget_channel_command = {

View File

@ -820,9 +820,9 @@ static void remove_htlc_in(struct channel *channel, struct htlc_in *hin)
/* If we fulfilled their HTLC, credit us. */
if (hin->preimage) {
log_debug(channel->log, "Balance %"PRIu64" -> %"PRIu64,
*channel->our_msatoshi,
*channel->our_msatoshi + hin->msatoshi);
*channel->our_msatoshi += hin->msatoshi;
channel->our_msatoshi,
channel->our_msatoshi + hin->msatoshi);
channel->our_msatoshi += hin->msatoshi;
}
tal_free(hin);
@ -844,9 +844,9 @@ static void remove_htlc_out(struct channel *channel, struct htlc_out *hout)
} else {
/* We paid for this HTLC, so deduct balance. */
log_debug(channel->log, "Balance %"PRIu64" -> %"PRIu64,
*channel->our_msatoshi,
*channel->our_msatoshi - hout->msatoshi);
*channel->our_msatoshi -= hout->msatoshi;
channel->our_msatoshi,
channel->our_msatoshi - hout->msatoshi);
channel->our_msatoshi -= hout->msatoshi;
}
tal_free(hout);
@ -1005,7 +1005,7 @@ void peer_sending_commitsig(struct channel *channel, const u8 *msg)
}
/* Update their feerate. */
channel->channel_info->feerate_per_kw[REMOTE] = feerate;
channel->channel_info.feerate_per_kw[REMOTE] = feerate;
if (!peer_save_commitsig_sent(channel, commitnum))
return;
@ -1162,8 +1162,8 @@ void peer_got_commitsig(struct channel *channel, const u8 *msg)
/* Update both feerates: if we're funder, REMOTE should already be
* that feerate, if we're not, we're about to ACK anyway. */
channel->channel_info->feerate_per_kw[LOCAL]
= channel->channel_info->feerate_per_kw[REMOTE]
channel->channel_info.feerate_per_kw[LOCAL]
= channel->channel_info.feerate_per_kw[REMOTE]
= feerate;
/* Since we're about to send revoke, bump state again. */
@ -1189,7 +1189,7 @@ void peer_got_commitsig(struct channel *channel, const u8 *msg)
void update_per_commit_point(struct channel *channel,
const struct pubkey *per_commitment_point)
{
struct channel_info *ci = channel->channel_info;
struct channel_info *ci = &channel->channel_info;
ci->old_remote_per_commit = ci->remote_per_commit;
ci->remote_per_commit = *per_commitment_point;
}

View File

@ -3,9 +3,15 @@
#define LIGHTNING_LIGHTNINGD_PEER_HTLCS_H
#include "config.h"
#include <ccan/short_types/short_types.h>
#include <common/channel_config.h>
#include <common/derive_basepoints.h>
#include <common/htlc_wire.h>
struct channel;
struct htlc_in;
struct htlc_out;
struct htlc_stub;
/* FIXME: Define serialization primitive for this? */
struct channel_info {
struct channel_config their_config;

View File

@ -766,7 +766,7 @@ static bool bitcoin_tx_eq(const struct bitcoin_tx *tx1,
static bool channelseq(struct channel *c1, struct channel *c2)
{
struct peer *p1 = c1->peer, *p2 = c2->peer;
struct channel_info *ci1 = c1->channel_info, *ci2 = c2->channel_info;
struct channel_info *ci1 = &c1->channel_info, *ci2 = &c2->channel_info;
struct changed_htlc *lc1 = c1->last_sent_commit, *lc2 = c2->last_sent_commit;
CHECK(c1->dbid == c2->dbid);
CHECK(c1->first_blocknum == c2->first_blocknum);
@ -775,29 +775,24 @@ static bool channelseq(struct channel *c1, struct channel *c2)
CHECK(c1->their_shachain.id == c2->their_shachain.id);
CHECK_MSG(pubkey_eq(&p1->id, &p2->id), "NodeIDs do not match");
CHECK((c1->scid == NULL && c2->scid == NULL) || short_channel_id_eq(c1->scid, c2->scid));
CHECK((c1->our_msatoshi == NULL) == (c2->our_msatoshi == NULL));
if (c1->our_msatoshi)
CHECK(*c1->our_msatoshi == *c2->our_msatoshi);
CHECK(c1->our_msatoshi == c2->our_msatoshi);
CHECK((c1->remote_shutdown_scriptpubkey == NULL && c2->remote_shutdown_scriptpubkey == NULL) || memeq(
c1->remote_shutdown_scriptpubkey,
tal_len(c1->remote_shutdown_scriptpubkey),
c2->remote_shutdown_scriptpubkey,
tal_len(c2->remote_shutdown_scriptpubkey)));
CHECK((c1->funding_txid == NULL && c2->funding_txid == NULL) || memeq(
c1->funding_txid,
CHECK(memeq(
&c1->funding_txid,
sizeof(struct sha256_double),
c2->funding_txid,
&c2->funding_txid,
sizeof(struct sha256_double)));
CHECK((ci1 != NULL) == (ci2 != NULL));
if(ci1) {
CHECK(pubkey_eq(&ci1->remote_fundingkey, &ci2->remote_fundingkey));
CHECK(pubkey_eq(&ci1->theirbase.revocation, &ci2->theirbase.revocation));
CHECK(pubkey_eq(&ci1->theirbase.payment, &ci2->theirbase.payment));
CHECK(pubkey_eq(&ci1->theirbase.delayed_payment, &ci2->theirbase.delayed_payment));
CHECK(pubkey_eq(&ci1->remote_per_commit, &ci2->remote_per_commit));
CHECK(pubkey_eq(&ci1->old_remote_per_commit, &ci2->old_remote_per_commit));
CHECK(ci1->their_config.id != 0 && ci1->their_config.id == ci2->their_config.id);
}
CHECK(pubkey_eq(&ci1->remote_fundingkey, &ci2->remote_fundingkey));
CHECK(pubkey_eq(&ci1->theirbase.revocation, &ci2->theirbase.revocation));
CHECK(pubkey_eq(&ci1->theirbase.payment, &ci2->theirbase.payment));
CHECK(pubkey_eq(&ci1->theirbase.delayed_payment, &ci2->theirbase.delayed_payment));
CHECK(pubkey_eq(&ci1->remote_per_commit, &ci2->remote_per_commit));
CHECK(pubkey_eq(&ci1->old_remote_per_commit, &ci2->old_remote_per_commit));
CHECK(ci1->their_config.id != 0 && ci1->their_config.id == ci2->their_config.id);
CHECK(c1->our_config.id != 0 && c1->our_config.id == c2->our_config.id);
CHECK((lc1 != NULL) == (lc2 != NULL));
@ -810,11 +805,8 @@ static bool channelseq(struct channel *c1, struct channel *c2)
if(c1->last_tx) {
CHECK(bitcoin_tx_eq(c1->last_tx, c2->last_tx));
}
CHECK((c1->last_sig != NULL) == (c2->last_sig != NULL));
if(c1->last_sig) {
CHECK(memeq(c1->last_sig, sizeof(*c1->last_sig),
c2->last_sig, sizeof(*c2->last_sig)));
}
CHECK(memeq(&c1->last_sig, sizeof(c1->last_sig),
&c2->last_sig, sizeof(c2->last_sig)));
if (c1->remote_shutdown_scriptpubkey) {
CHECK(c2->remote_shutdown_scriptpubkey);
@ -848,46 +840,45 @@ static bool test_channel_crud(struct lightningd *ld, const tal_t *ctx)
struct wallet *w = create_test_wallet(ld, ctx);
struct channel c1, *c2 = tal(w, struct channel);
struct peer *p;
struct channel_info ci;
struct channel_info *ci = &c1.channel_info;
struct bitcoin_txid *hash = tal(w, struct bitcoin_txid);
struct pubkey pk;
struct changed_htlc last_commit;
secp256k1_ecdsa_signature *sig = tal(w, secp256k1_ecdsa_signature);
u64 msat = 12345;
u8 *scriptpubkey = tal_arr(ctx, u8, 100);
memset(&c1, 0, sizeof(c1));
memset(c2, 0, sizeof(*c2));
memset(&ci, 3, sizeof(ci));
memset(ci, 3, sizeof(*ci));
mempat(hash, sizeof(*hash));
mempat(sig, sizeof(*sig));
mempat(&last_commit, sizeof(last_commit));
pubkey_from_der(tal_hexdata(w, "02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc", 66), 33, &pk);
ci.feerate_per_kw[LOCAL] = ci.feerate_per_kw[REMOTE] = 31337;
ci->feerate_per_kw[LOCAL] = ci->feerate_per_kw[REMOTE] = 31337;
mempat(scriptpubkey, tal_len(scriptpubkey));
c1.first_blocknum = 1;
p = new_peer(ld, 0, &pk, NULL);
c1.peer = p;
c1.dbid = wallet_get_channel_dbid(w);
c1.our_msatoshi = NULL;
c1.last_tx = NULL;
c1.state = CHANNELD_NORMAL;
memset(&ci.their_config, 0, sizeof(struct channel_config));
ci.remote_fundingkey = pk;
ci.theirbase.revocation = pk;
ci.theirbase.payment = pk;
ci.theirbase.htlc = pk;
ci.theirbase.delayed_payment = pk;
ci.remote_per_commit = pk;
ci.old_remote_per_commit = pk;
memset(&ci->their_config, 0, sizeof(struct channel_config));
ci->remote_fundingkey = pk;
ci->theirbase.revocation = pk;
ci->theirbase.payment = pk;
ci->theirbase.htlc = pk;
ci->theirbase.delayed_payment = pk;
ci->remote_per_commit = pk;
ci->old_remote_per_commit = pk;
/* last_tx taken from BOLT #3 */
c1.last_tx = bitcoin_tx_from_hex(w, "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110ae8f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe260147304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", strlen("02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110ae8f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe260147304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220"));
c1.last_sig = *sig;
db_begin_transaction(w->db);
CHECK(!wallet_err);
wallet_channel_insert(w, &c1);
/* Variant 1: insert with null for scid, funding_tx_id, channel_info, last_tx */
/* Variant 1: insert with null for scid, last_sent_commit */
wallet_channel_save(w, &c1);
CHECK_MSG(!wallet_err,
tal_fmt(w, "Insert into DB: %s", wallet_err));
@ -904,6 +895,7 @@ static bool test_channel_crud(struct lightningd *ld, const tal_t *ctx)
/* Variant 2: update with scid set */
c1.scid = talz(w, struct short_channel_id);
c1.last_was_revoke = !c1.last_was_revoke;
wallet_channel_save(w, &c1);
CHECK_MSG(!wallet_err,
tal_fmt(w, "Insert into DB: %s", wallet_err));
@ -918,39 +910,7 @@ static bool test_channel_crud(struct lightningd *ld, const tal_t *ctx)
CHECK(c1.peer->dbid == 1);
CHECK(c1.their_shachain.id == 1);
/* Variant 3: update with our_satoshi set */
c1.our_msatoshi = &msat;
c1.last_was_revoke = !c1.last_was_revoke;
wallet_channel_save(w, &c1);
CHECK_MSG(!wallet_err, tal_fmt(w, "Insert into DB: %s", wallet_err));
CHECK_MSG(c2 = wallet_channel_load(w, c1.dbid), tal_fmt(w, "Load from DB"));
CHECK_MSG(!wallet_err,
tal_fmt(w, "Insert into DB: %s", wallet_err));
CHECK_MSG(channelseq(&c1, c2), "Compare loaded with saved (v3)");
tal_free(c2);
/* Variant 4: update with funding_tx_id */
c1.funding_txid = hash;
wallet_channel_save(w, &c1);
CHECK_MSG(!wallet_err, tal_fmt(w, "Insert into DB: %s", wallet_err));
CHECK_MSG(c2 = wallet_channel_load(w, c1.dbid), tal_fmt(w, "Load from DB"));
CHECK_MSG(!wallet_err,
tal_fmt(w, "Insert into DB: %s", wallet_err));
CHECK_MSG(channelseq(&c1, c2), "Compare loaded with saved (v4)");
tal_free(c2);
/* Variant 5: update with channel_info */
c1.channel_info = &ci;
wallet_channel_save(w, &c1);
CHECK_MSG(!wallet_err, tal_fmt(w, "Insert into DB: %s", wallet_err));
CHECK_MSG(c2 = wallet_channel_load(w, c1.dbid), tal_fmt(w, "Load from DB"));
CHECK_MSG(!wallet_err,
tal_fmt(w, "Insert into DB: %s", wallet_err));
CHECK_MSG(channelseq(&c1, c2), "Compare loaded with saved (v5)");
tal_free(c2);
/* Variant 6: update with last_commit_sent */
/* Variant 3: update with last_commit_sent */
c1.last_sent_commit = &last_commit;
wallet_channel_save(w, &c1);
CHECK_MSG(!wallet_err, tal_fmt(w, "Insert into DB: %s", wallet_err));
@ -960,18 +920,7 @@ static bool test_channel_crud(struct lightningd *ld, const tal_t *ctx)
CHECK_MSG(channelseq(&c1, c2), "Compare loaded with saved (v6)");
tal_free(c2);
/* Variant 7: update with last_tx (taken from BOLT #3) */
c1.last_tx = bitcoin_tx_from_hex(w, "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110ae8f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe260147304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", strlen("02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110ae8f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe260147304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220"));
c1.last_sig = sig;
wallet_channel_save(w, &c1);
CHECK_MSG(!wallet_err, tal_fmt(w, "Insert into DB: %s", wallet_err));
CHECK_MSG(c2 = wallet_channel_load(w, c1.dbid), tal_fmt(w, "Load from DB"));
CHECK_MSG(!wallet_err,
tal_fmt(w, "Insert into DB: %s", wallet_err));
CHECK_MSG(channelseq(&c1, c2), "Compare loaded with saved (v7)");
tal_free(c2);
/* Variant 8: update and add remote_shutdown_scriptpubkey */
/* Variant 4: update and add remote_shutdown_scriptpubkey */
c1.remote_shutdown_scriptpubkey = scriptpubkey;
c1.local_shutdown_idx = 1337;
wallet_channel_save(w, &c1);

View File

@ -537,48 +537,28 @@ static struct channel *wallet_stmt2channel(const tal_t *ctx, struct wallet *w, s
chan->next_index[REMOTE] = sqlite3_column_int64(stmt, 10);
chan->next_htlc_id = sqlite3_column_int64(stmt, 11);
if (sqlite3_column_type(stmt, 12) != SQLITE_NULL) {
assert(sqlite3_column_bytes(stmt, 12) == 32);
chan->funding_txid = tal(chan->peer, struct bitcoin_txid);
memcpy(chan->funding_txid, sqlite3_column_blob(stmt, 12), 32);
} else {
chan->funding_txid = NULL;
}
sqlite3_column_sha256_double(stmt, 12, &chan->funding_txid.shad);
chan->funding_outnum = sqlite3_column_int(stmt, 13);
chan->funding_satoshi = sqlite3_column_int64(stmt, 14);
chan->remote_funding_locked =
sqlite3_column_int(stmt, 15) != 0;
chan->push_msat = sqlite3_column_int64(stmt, 16);
chan->our_msatoshi = sqlite3_column_int64(stmt, 17);
if (sqlite3_column_type(stmt, 17) != SQLITE_NULL) {
chan->our_msatoshi = tal(chan->peer, u64);
*chan->our_msatoshi = sqlite3_column_int64(stmt, 17);
}else {
chan->our_msatoshi = tal_free(chan->our_msatoshi);
}
channel_info = &chan->channel_info;
/* See if we have a valid commit_sig indicating the presence
* of channel_info */
if (sqlite3_column_type(stmt, 18) != SQLITE_NULL) {
/* OK, so we have a valid sig, instantiate and/or fill
* in channel_info */
if (!chan->channel_info)
chan->channel_info = tal(chan, struct channel_info);
channel_info = chan->channel_info;
/* Populate channel_info */
ok &= sqlite3_column_pubkey(stmt, 18, &channel_info->remote_fundingkey);
ok &= sqlite3_column_pubkey(stmt, 19, &channel_info->theirbase.revocation);
ok &= sqlite3_column_pubkey(stmt, 20, &channel_info->theirbase.payment);
ok &= sqlite3_column_pubkey(stmt, 21, &channel_info->theirbase.htlc);
ok &= sqlite3_column_pubkey(stmt, 22, &channel_info->theirbase.delayed_payment);
ok &= sqlite3_column_pubkey(stmt, 23, &channel_info->remote_per_commit);
ok &= sqlite3_column_pubkey(stmt, 24, &channel_info->old_remote_per_commit);
channel_info->feerate_per_kw[LOCAL] = sqlite3_column_int(stmt, 25);
channel_info->feerate_per_kw[REMOTE] = sqlite3_column_int(stmt, 26);
wallet_channel_config_load(w, remote_config_id, &chan->channel_info->their_config);
}
/* Populate channel_info */
ok &= sqlite3_column_pubkey(stmt, 18, &channel_info->remote_fundingkey);
ok &= sqlite3_column_pubkey(stmt, 19, &channel_info->theirbase.revocation);
ok &= sqlite3_column_pubkey(stmt, 20, &channel_info->theirbase.payment);
ok &= sqlite3_column_pubkey(stmt, 21, &channel_info->theirbase.htlc);
ok &= sqlite3_column_pubkey(stmt, 22, &channel_info->theirbase.delayed_payment);
ok &= sqlite3_column_pubkey(stmt, 23, &channel_info->remote_per_commit);
ok &= sqlite3_column_pubkey(stmt, 24, &channel_info->old_remote_per_commit);
channel_info->feerate_per_kw[LOCAL] = sqlite3_column_int(stmt, 25);
channel_info->feerate_per_kw[REMOTE] = sqlite3_column_int(stmt, 26);
wallet_channel_config_load(w, remote_config_id, &channel_info->their_config);
/* Load shachain */
u64 shachain_id = sqlite3_column_int64(stmt, 27);
@ -605,15 +585,8 @@ static struct channel *wallet_stmt2channel(const tal_t *ctx, struct wallet *w, s
chan->last_sent_commit = tal_free(chan->last_sent_commit);
}
/* Do we have last_tx? If so, populate. */
if (sqlite3_column_type(stmt, 32) != SQLITE_NULL) {
chan->last_tx = sqlite3_column_tx(chan, stmt, 32);
chan->last_sig = tal(chan, secp256k1_ecdsa_signature);
sqlite3_column_signature(stmt, 33, chan->last_sig);
} else {
chan->last_tx = tal_free(chan->last_tx);
chan->last_sig = tal_free(chan->last_sig);
}
chan->last_tx = sqlite3_column_tx(chan, stmt, 32);
sqlite3_column_signature(stmt, 33, &chan->last_sig);
chan->last_was_revoke = sqlite3_column_int(stmt, 34) != 0;
@ -843,16 +816,13 @@ void wallet_channel_save(struct wallet *w, struct channel *chan)
sqlite3_bind_int64(stmt, 8, chan->next_index[REMOTE]);
sqlite3_bind_int64(stmt, 9, chan->next_htlc_id);
if (chan->funding_txid)
sqlite3_bind_blob(stmt, 10, chan->funding_txid, sizeof(*chan->funding_txid), SQLITE_TRANSIENT);
sqlite3_bind_sha256_double(stmt, 10, &chan->funding_txid.shad);
sqlite3_bind_int(stmt, 11, chan->funding_outnum);
sqlite3_bind_int64(stmt, 12, chan->funding_satoshi);
sqlite3_bind_int(stmt, 13, chan->remote_funding_locked);
sqlite3_bind_int64(stmt, 14, chan->push_msat);
if (chan->our_msatoshi)
sqlite3_bind_int64(stmt, 15, *chan->our_msatoshi);
sqlite3_bind_int64(stmt, 15, chan->our_msatoshi);
if (chan->remote_shutdown_scriptpubkey)
sqlite3_bind_blob(stmt, 16, chan->remote_shutdown_scriptpubkey,
@ -861,43 +831,37 @@ void wallet_channel_save(struct wallet *w, struct channel *chan)
sqlite3_bind_int64(stmt, 17, chan->local_shutdown_idx);
sqlite3_bind_int64(stmt, 18, chan->our_config.id);
if (chan->last_tx)
sqlite3_bind_tx(stmt, 19, chan->last_tx);
if (chan->last_sig)
sqlite3_bind_signature(stmt, 20, chan->last_sig);
sqlite3_bind_tx(stmt, 19, chan->last_tx);
sqlite3_bind_signature(stmt, 20, &chan->last_sig);
sqlite3_bind_int(stmt, 21, chan->last_was_revoke);
sqlite3_bind_int64(stmt, 22, chan->dbid);
db_exec_prepared(w->db, stmt);
if (chan->channel_info) {
if (chan->channel_info->their_config.id == 0)
wallet_channel_config_insert(w, &chan->channel_info->their_config);
wallet_channel_config_save(w, &chan->channel_info->their_config);
stmt = db_prepare(w->db, "UPDATE channels SET"
" fundingkey_remote=?,"
" revocation_basepoint_remote=?,"
" payment_basepoint_remote=?,"
" htlc_basepoint_remote=?,"
" delayed_payment_basepoint_remote=?,"
" per_commit_remote=?,"
" old_per_commit_remote=?,"
" local_feerate_per_kw=?,"
" remote_feerate_per_kw=?,"
" channel_config_remote=?"
" WHERE id=?");
sqlite3_bind_pubkey(stmt, 1, &chan->channel_info->remote_fundingkey);
sqlite3_bind_pubkey(stmt, 2, &chan->channel_info->theirbase.revocation);
sqlite3_bind_pubkey(stmt, 3, &chan->channel_info->theirbase.payment);
sqlite3_bind_pubkey(stmt, 4, &chan->channel_info->theirbase.htlc);
sqlite3_bind_pubkey(stmt, 5, &chan->channel_info->theirbase.delayed_payment);
sqlite3_bind_pubkey(stmt, 6, &chan->channel_info->remote_per_commit);
sqlite3_bind_pubkey(stmt, 7, &chan->channel_info->old_remote_per_commit);
sqlite3_bind_int(stmt, 8, chan->channel_info->feerate_per_kw[LOCAL]);
sqlite3_bind_int(stmt, 9, chan->channel_info->feerate_per_kw[REMOTE]);
sqlite3_bind_int64(stmt, 10, chan->channel_info->their_config.id);
sqlite3_bind_int64(stmt, 11, chan->dbid);
db_exec_prepared(w->db, stmt);
}
wallet_channel_config_save(w, &chan->channel_info.their_config);
stmt = db_prepare(w->db, "UPDATE channels SET"
" fundingkey_remote=?,"
" revocation_basepoint_remote=?,"
" payment_basepoint_remote=?,"
" htlc_basepoint_remote=?,"
" delayed_payment_basepoint_remote=?,"
" per_commit_remote=?,"
" old_per_commit_remote=?,"
" local_feerate_per_kw=?,"
" remote_feerate_per_kw=?,"
" channel_config_remote=?"
" WHERE id=?");
sqlite3_bind_pubkey(stmt, 1, &chan->channel_info.remote_fundingkey);
sqlite3_bind_pubkey(stmt, 2, &chan->channel_info.theirbase.revocation);
sqlite3_bind_pubkey(stmt, 3, &chan->channel_info.theirbase.payment);
sqlite3_bind_pubkey(stmt, 4, &chan->channel_info.theirbase.htlc);
sqlite3_bind_pubkey(stmt, 5, &chan->channel_info.theirbase.delayed_payment);
sqlite3_bind_pubkey(stmt, 6, &chan->channel_info.remote_per_commit);
sqlite3_bind_pubkey(stmt, 7, &chan->channel_info.old_remote_per_commit);
sqlite3_bind_int(stmt, 8, chan->channel_info.feerate_per_kw[LOCAL]);
sqlite3_bind_int(stmt, 9, chan->channel_info.feerate_per_kw[REMOTE]);
sqlite3_bind_int64(stmt, 10, chan->channel_info.their_config.id);
sqlite3_bind_int64(stmt, 11, chan->dbid);
db_exec_prepared(w->db, stmt);
/* If we have a last_sent_commit, store it */
if (chan->last_sent_commit) {
@ -943,8 +907,7 @@ void wallet_channel_insert(struct wallet *w, struct channel *chan)
db_exec_prepared(w->db, stmt);
wallet_channel_config_insert(w, &chan->our_config);
if (chan->channel_info)
wallet_channel_config_insert(w, &chan->channel_info->their_config);
wallet_channel_config_insert(w, &chan->channel_info.their_config);
wallet_shachain_init(w, &chan->their_shachain);
/* Now save path as normal */

View File

@ -503,9 +503,6 @@ static void json_listfunds(struct command *cmd, const char *buffer UNUSED,
list_for_each(&cmd->ld->peers, p, list) {
struct channel *c;
list_for_each(&p->channels, c, list) {
if (!c->our_msatoshi || !c->funding_txid)
continue;
json_object_start(response, NULL);
json_add_pubkey(response, "peer_id", &p->id);
if (c->scid)
@ -515,10 +512,11 @@ static void json_listfunds(struct command *cmd, const char *buffer UNUSED,
/* Poor man's rounding to satoshis to match the unit for outputs */
json_add_u64(response, "channel_sat",
(*c->our_msatoshi + 500)/1000);
(c->our_msatoshi + 500)/1000);
json_add_u64(response, "channel_total_sat",
c->funding_satoshi);
json_add_txid(response, "funding_txid", c->funding_txid);
json_add_txid(response, "funding_txid",
&c->funding_txid);
json_object_end(response);
}
}