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>
This commit is contained in:
Rusty Russell 2019-12-13 03:48:25 +10:30 committed by Christian Decker
parent 4270031d75
commit 72aa315b5e
19 changed files with 191 additions and 90 deletions

View File

@ -1,6 +1,7 @@
#include <common/cryptomsg.h>
#include <common/channel_config.h>
#include <common/derive_basepoints.h>
#include <common/fee_states.h>
#include <common/per_peer_state.h>
# Begin! (passes gossipd-client fd)
@ -12,8 +13,7 @@ msgdata,channel_init,funding_satoshi,amount_sat,
msgdata,channel_init,minimum_depth,u32,
msgdata,channel_init,our_config,channel_config,
msgdata,channel_init,their_config,channel_config,
# FIXME: Fix generate-wire.py to allow NUM_SIDES*u32 here.,
msgdata,channel_init,feerate_per_kw,u32,2
msgdata,channel_init,fee_states,fee_states,
msgdata,channel_init,feerate_min,u32,
msgdata,channel_init,feerate_max,u32,
msgdata,channel_init,first_commit_sig,bitcoin_signature,
@ -108,7 +108,7 @@ msgdata,channel_got_funding_locked,next_per_commit_point,pubkey,
# When we send a commitment_signed message, tell master.
msgtype,channel_sending_commitsig,1020
msgdata,channel_sending_commitsig,commitnum,u64,
msgdata,channel_sending_commitsig,feerate,u32,
msgdata,channel_sending_commitsig,fee_states,fee_states,
# SENT_ADD_COMMIT, SENT_REMOVE_ACK_COMMIT, SENT_ADD_ACK_COMMIT, SENT_REMOVE_COMMIT
msgdata,channel_sending_commitsig,num_changed,u16,
msgdata,channel_sending_commitsig,changed,changed_htlc,num_changed
@ -122,7 +122,7 @@ msgtype,channel_sending_commitsig_reply,1120
# When we have a commitment_signed message, tell master to remember.
msgtype,channel_got_commitsig,1021
msgdata,channel_got_commitsig,commitnum,u64,
msgdata,channel_got_commitsig,feerate,u32,
msgdata,channel_got_commitsig,fee_states,fee_states,
msgdata,channel_got_commitsig,signature,bitcoin_signature,
msgdata,channel_got_commitsig,num_htlcs,u16,
msgdata,channel_got_commitsig,htlc_signature,secp256k1_ecdsa_signature,num_htlcs
@ -150,7 +150,7 @@ msgdata,channel_got_revoke,revokenum,u64,
msgdata,channel_got_revoke,per_commitment_secret,secret,
msgdata,channel_got_revoke,next_per_commit_point,pubkey,
# RCVD_ADD_ACK_REVOCATION, RCVD_REMOVE_ACK_REVOCATION, RCVD_ADD_REVOCATION, RCVD_REMOVE_REVOCATION
msgdata,channel_got_revoke,feerate,u32,
msgdata,channel_got_revoke,fee_states,fee_states,
msgdata,channel_got_revoke,num_changed,u16,
msgdata,channel_got_revoke,changed,changed_htlc,num_changed
# Wait for reply, to make sure it's on disk before we continue

1 #include <common/cryptomsg.h>
2 #include <common/channel_config.h>
3 #include <common/derive_basepoints.h>
4 #include <common/fee_states.h>
5 #include <common/per_peer_state.h>
6 # Begin! (passes gossipd-client fd)
7 msgtype,channel_init,1000
13 msgdata,channel_init,our_config,channel_config,
14 msgdata,channel_init,their_config,channel_config,
15 # FIXME: Fix generate-wire.py to allow NUM_SIDES*u32 here., msgdata,channel_init,fee_states,fee_states,
16 msgdata,channel_init,feerate_per_kw,u32,2 msgdata,channel_init,feerate_min,u32,
msgdata,channel_init,feerate_min,u32,
17 msgdata,channel_init,feerate_max,u32,
18 msgdata,channel_init,first_commit_sig,bitcoin_signature,
19 msgdata,channel_init,per_peer_state,per_peer_state,
108 msgdata,channel_sending_commitsig,num_htlc_sigs,u16,
109 msgdata,channel_sending_commitsig,htlc_sigs,secp256k1_ecdsa_signature,num_htlc_sigs
110 # Wait for reply, to make sure it's on disk before we send commit.
111 msgtype,channel_sending_commitsig_reply,1120
112 # When we have a commitment_signed message, tell master to remember.
113 msgtype,channel_got_commitsig,1021
114 msgdata,channel_got_commitsig,commitnum,u64,
122 msgdata,channel_got_commitsig,shared_secret,secret,num_added
123 # RCVD_REMOVE_COMMIT: we're now no longer committed to these HTLCs.
124 msgdata,channel_got_commitsig,num_fulfilled,u16,
125 msgdata,channel_got_commitsig,fulfilled,fulfilled_htlc,num_fulfilled
126 msgdata,channel_got_commitsig,num_failed,u16,
127 msgdata,channel_got_commitsig,failed,failed_htlc,num_failed
128 # RCVD_ADD_ACK_COMMIT, RCVD_REMOVE_ACK_COMMIT
150 # Peer told us that channel is shutting down
151 msgtype,channel_got_shutdown,1024
152 msgdata,channel_got_shutdown,scriptpubkey_len,u16,
153 msgdata,channel_got_shutdown,scriptpubkey,u8,scriptpubkey_len
154 # Shutdown is complete, ready for closing negotiation. + peer_fd & gossip_fd.
155 msgtype,channel_shutdown_complete,1025
156 msgdata,channel_shutdown_complete,per_peer_state,per_peer_state,

View File

@ -721,7 +721,7 @@ static struct changed_htlc *changed_htlc_arr(const tal_t *ctx,
static u8 *sending_commitsig_msg(const tal_t *ctx,
u64 remote_commit_index,
u32 remote_feerate,
const struct fee_states *fee_states,
const struct htlc **changed_htlcs,
const struct bitcoin_signature *commit_sig,
const secp256k1_ecdsa_signature *htlc_sigs)
@ -733,7 +733,7 @@ static u8 *sending_commitsig_msg(const tal_t *ctx,
* committed to. */
changed = changed_htlc_arr(tmpctx, changed_htlcs);
msg = towire_channel_sending_commitsig(ctx, remote_commit_index,
remote_feerate,
fee_states,
changed, commit_sig, htlc_sigs);
return msg;
}
@ -1180,7 +1180,7 @@ static void send_commit(struct peer *peer)
status_debug("Telling master we're about to commit...");
/* Tell master to save this next commit to database, then wait. */
msg = sending_commitsig_msg(NULL, peer->next_index[REMOTE],
channel_feerate(peer->channel, REMOTE),
peer->channel->fee_states,
changed_htlcs,
&commit_sig,
htlc_sigs);
@ -1363,10 +1363,12 @@ static void send_revocation(struct peer *peer,
/* Tell master daemon about commitsig (and by implication, that we're
* sending revoke_and_ack), then wait for it to ack. */
/* We had to do this after channel_sending_revoke_and_ack, since we
* want it to save the fee_states produced there. */
msg_for_master
= towire_channel_got_commitsig(NULL,
peer->next_index[LOCAL] - 1,
channel_feerate(peer->channel, LOCAL),
peer->channel->fee_states,
commit_sig, htlc_sigs,
added,
shared_secret,
@ -1516,7 +1518,7 @@ static u8 *got_revoke_msg(const tal_t *ctx, u64 revoke_num,
const struct secret *per_commitment_secret,
const struct pubkey *next_per_commit_point,
const struct htlc **changed_htlcs,
u32 feerate)
const struct fee_states *fee_states)
{
u8 *msg;
struct changed_htlc *changed = tal_arr(tmpctx, struct changed_htlc, 0);
@ -1535,7 +1537,7 @@ static u8 *got_revoke_msg(const tal_t *ctx, u64 revoke_num,
}
msg = towire_channel_got_revoke(ctx, revoke_num, per_commitment_secret,
next_per_commit_point, feerate, changed);
next_per_commit_point, fee_states, changed);
return msg;
}
@ -1595,7 +1597,7 @@ static void handle_peer_revoke_and_ack(struct peer *peer, const u8 *msg)
msg = got_revoke_msg(NULL, peer->revocations_received++,
&old_commit_secret, &next_per_commit,
changed_htlcs,
channel_feerate(peer->channel, LOCAL));
peer->channel->fee_states);
master_wait_sync_reply(tmpctx, peer, take(msg),
WIRE_CHANNEL_GOT_REVOKE_REPLY);
@ -2945,7 +2947,7 @@ static void init_channel(struct peer *peer)
bool reconnected;
u8 *funding_signed;
const u8 *msg;
u32 feerate_per_kw[NUM_SIDES];
struct fee_states *fee_states;
u32 minimum_depth, failheight;
struct secret last_remote_per_commit_secret;
secp256k1_ecdsa_signature *remote_ann_node_sig;
@ -2963,7 +2965,7 @@ static void init_channel(struct peer *peer)
&funding,
&minimum_depth,
&conf[LOCAL], &conf[REMOTE],
feerate_per_kw,
&fee_states,
&peer->feerate_min, &peer->feerate_max,
&peer->their_commit_sig,
&peer->pps,
@ -3020,7 +3022,7 @@ static void init_channel(struct peer *peer)
" next_idx_local = %"PRIu64
" next_idx_remote = %"PRIu64
" revocations_received = %"PRIu64
" feerates %u/%u (range %u-%u)",
" feerates %s range %u-%u",
side_to_str(funder),
type_to_string(tmpctx, struct pubkey,
&peer->remote_per_commit),
@ -3028,7 +3030,7 @@ static void init_channel(struct peer *peer)
&peer->old_remote_per_commit),
peer->next_index[LOCAL], peer->next_index[REMOTE],
peer->revocations_received,
feerate_per_kw[LOCAL], feerate_per_kw[REMOTE],
type_to_string(tmpctx, struct fee_states, fee_states),
peer->feerate_min, peer->feerate_max);
status_debug("option_static_remotekey = %u", option_static_remotekey);
@ -3062,7 +3064,7 @@ static void init_channel(struct peer *peer)
minimum_depth,
funding,
local_msat,
feerate_per_kw,
take(fee_states),
&conf[LOCAL], &conf[REMOTE],
&points[LOCAL], &points[REMOTE],
&funding_pubkey[LOCAL],
@ -3097,7 +3099,7 @@ static void init_channel(struct peer *peer)
/* Default desired feerate is the feerate we set for them last. */
if (peer->channel->funder == LOCAL)
peer->desired_feerate = feerate_per_kw[REMOTE];
peer->desired_feerate = channel_feerate(peer->channel, REMOTE);
/* from now we need keep watch over WIRE_CHANNEL_FUNDING_DEPTH */
peer->depth_togo = minimum_depth;

View File

@ -92,7 +92,7 @@ struct channel *new_full_channel(const tal_t *ctx,
u32 minimum_depth,
struct amount_sat funding,
struct amount_msat local_msat,
const u32 feerate_per_kw[NUM_SIDES],
const struct fee_states *fee_states,
const struct channel_config *local,
const struct channel_config *remote,
const struct basepoints *local_basepoints,
@ -102,16 +102,13 @@ struct channel *new_full_channel(const tal_t *ctx,
bool option_static_remotekey,
enum side funder)
{
/* FIXME: Support full feestates! */
struct fee_states *fee_states = new_fee_states(NULL, funder,
&feerate_per_kw[funder]);
struct channel *channel = new_initial_channel(ctx,
funding_txid,
funding_txout,
minimum_depth,
funding,
local_msat,
take(fee_states),
fee_states,
local, remote,
local_basepoints,
remote_basepoints,

View File

@ -15,8 +15,7 @@
* @minimum_depth: The minimum confirmations needed for funding transaction.
* @funding: The commitment transaction amount.
* @local_msat: The amount for the local side (remainder goes to remote)
* @feerate_per_kw: feerate per kiloweight (satoshis) for the commitment
* transaction and HTLCS for each side.
* @fee_states: The fee update states.
* @local: local channel configuration
* @remote: remote channel configuration
* @local_basepoints: local basepoints.
@ -34,7 +33,7 @@ struct channel *new_full_channel(const tal_t *ctx,
u32 minimum_depth,
struct amount_sat funding,
struct amount_msat local_msat,
const u32 feerate_per_kw[NUM_SIDES],
const struct fee_states *fee_states,
const struct channel_config *local,
const struct channel_config *remote,
const struct basepoints *local_basepoints,

View File

@ -469,7 +469,8 @@ int main(void)
lchannel = new_full_channel(tmpctx,
&funding_txid, funding_output_index, 0,
funding_amount, to_local,
feerate_per_kw,
take(new_fee_states(NULL, LOCAL,
&feerate_per_kw[LOCAL])),
local_config,
remote_config,
&localbase, &remotebase,
@ -479,7 +480,8 @@ int main(void)
rchannel = new_full_channel(tmpctx,
&funding_txid, funding_output_index, 0,
funding_amount, to_remote,
feerate_per_kw,
take(new_fee_states(NULL, REMOTE,
&feerate_per_kw[REMOTE])),
remote_config,
local_config,
&remotebase, &localbase,
@ -655,6 +657,7 @@ int main(void)
/* No memory leaks please */
wally_cleanup(0);
take_cleanup();
tal_free(tmpctx);
/* FIXME: Do BOLT comparison! */

View File

@ -16,6 +16,7 @@
#include <channeld/full_channel.h>
#include <common/amount.h>
#include <common/derive_basepoints.h>
#include <common/fee_states.h>
#include <common/htlc_wire.h>
#include <common/key_derive.h>
#include <common/keyset.h>
@ -251,7 +252,7 @@ int main(int argc, char *argv[])
struct amount_sat funding_amount;
struct bitcoin_txid funding_txid;
unsigned int funding_outnum;
u32 feerate_per_kw[NUM_SIDES];
u32 feerate_per_kw;
struct pubkey local_per_commit_point, remote_per_commit_point;
struct bitcoin_signature local_sig, remote_sig;
struct channel_config localconfig, remoteconfig;
@ -318,7 +319,7 @@ int main(int argc, char *argv[])
if (!parse_amount_sat(&funding_amount, argv[argnum], strlen(argv[argnum])))
errx(1, "Bad funding-amount");
argnum++;
feerate_per_kw[LOCAL] = feerate_per_kw[REMOTE] = atoi(argv[argnum++]);
feerate_per_kw = atoi(argv[argnum++]);
if (!parse_amount_msat(&local_msat,
argv[argnum], strlen(argv[argnum])))
errx(1, "Bad local-msat");
@ -384,7 +385,8 @@ int main(int argc, char *argv[])
&funding_txid, funding_outnum, 1,
funding_amount,
local_msat,
feerate_per_kw,
take(new_fee_states(NULL, fee_payer,
&feerate_per_kw)),
&localconfig, &remoteconfig,
&localbase, &remotebase,
&funding_localkey, &funding_remotekey,

View File

@ -29,6 +29,7 @@ LIGHTNINGD_COMMON_OBJS := \
common/daemon.o \
common/derive_basepoints.o \
common/features.o \
common/fee_states.o \
common/funding_tx.o \
common/gen_peer_status_wire.o \
common/gen_status_wire.o \

View File

@ -1,6 +1,7 @@
#include <bitcoin/script.h>
#include <ccan/crypto/hkdf_sha256/hkdf_sha256.h>
#include <ccan/tal/str/str.h>
#include <common/fee_states.h>
#include <common/json_command.h>
#include <common/jsonrpc_errors.h>
#include <common/utils.h>
@ -236,6 +237,8 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
channel->last_sig = *last_sig;
channel->last_htlc_sigs = tal_steal(channel, last_htlc_sigs);
channel->channel_info = *channel_info;
channel->channel_info.fee_states
= dup_fee_states(channel, channel_info->fee_states);
channel->shutdown_scriptpubkey[REMOTE]
= tal_steal(channel, remote_shutdown_scriptpubkey);
channel->final_key_idx = final_key_idx;

View File

@ -429,7 +429,7 @@ void peer_start_channeld(struct channel *channel,
channel->minimum_depth,
&channel->our_config,
&channel->channel_info.their_config,
channel->channel_info.feerate_per_kw,
channel->channel_info.fee_states,
feerate_min(ld, NULL),
feerate_max(ld, NULL),
&channel->last_sig,

View File

@ -2,6 +2,7 @@
#include <bitcoin/script.h>
#include <closingd/gen_closing_wire.h>
#include <common/close_tx.h>
#include <common/fee_states.h>
#include <common/initial_commit_tx.h>
#include <common/per_peer_state.h>
#include <common/utils.h>
@ -181,6 +182,7 @@ void peer_start_closingd(struct channel *channel,
int hsmfd;
struct secret last_remote_per_commit_secret;
struct lightningd *ld = channel->peer->ld;
u32 final_commit_feerate;
if (!channel->shutdown_scriptpubkey[REMOTE]) {
channel_internal_error(channel,
@ -221,8 +223,9 @@ void peer_start_closingd(struct channel *channel,
* fee of the final commitment transaction, as calculated in
* [BOLT #3](03-transactions.md#fee-calculation).
*/
feelimit = commit_tx_base_fee(channel->channel_info.feerate_per_kw[LOCAL],
0);
final_commit_feerate = get_feerate(channel->channel_info.fee_states,
channel->funder, LOCAL);
feelimit = commit_tx_base_fee(final_commit_feerate, 0);
/* Pick some value above slow feerate (or min possible if unknown) */
minfee = commit_tx_base_fee(feerate_min(ld, NULL), 0);
@ -230,7 +233,7 @@ void peer_start_closingd(struct channel *channel,
/* If we can't determine feerate, start at half unilateral feerate. */
feerate = mutual_close_feerate(ld->topology);
if (!feerate) {
feerate = channel->channel_info.feerate_per_kw[LOCAL] / 2;
feerate = final_commit_feerate / 2;
if (feerate < feerate_floor())
feerate = feerate_floor();
}

View File

@ -5,6 +5,7 @@
#include <common/addr.h>
#include <common/channel_config.h>
#include <common/features.h>
#include <common/fee_states.h>
#include <common/funding_tx.h>
#include <common/json_command.h>
#include <common/jsonrpc_errors.h>
@ -194,10 +195,8 @@ wallet_commit_channel(struct lightningd *ld,
} else
our_msat = push;
/* Feerates begin identical. */
channel_info->feerate_per_kw[LOCAL]
= channel_info->feerate_per_kw[REMOTE]
= feerate;
channel_info->fee_states = new_fee_states(uc, uc->fc ? LOCAL : REMOTE,
&feerate);
/* old_remote_per_commit not valid yet, copy valid one. */
channel_info->old_remote_per_commit = channel_info->remote_per_commit;

View File

@ -449,7 +449,8 @@ static void json_add_htlcs(struct lightningd *ld,
struct htlc_in_map_iter ini;
const struct htlc_out *hout;
struct htlc_out_map_iter outi;
u32 local_feerate = channel->channel_info.feerate_per_kw[LOCAL];
u32 local_feerate = get_feerate(channel->channel_info.fee_states,
channel->funder, LOCAL);
/* FIXME: Add more fields. */
json_array_start(response, "htlcs");
@ -519,7 +520,8 @@ static struct amount_sat commit_txfee(const struct channel *channel,
const struct htlc_out *hout;
struct htlc_out_map_iter outi;
struct lightningd *ld = channel->peer->ld;
u32 local_feerate = channel->channel_info.feerate_per_kw[LOCAL];
u32 local_feerate = get_feerate(channel->channel_info.fee_states,
channel->funder, LOCAL);
size_t num_untrimmed_htlcs = 0;
/* Assume we tried to spend "spendable" */

View File

@ -1347,10 +1347,18 @@ static bool peer_save_commitsig_sent(struct channel *channel, u64 commitnum)
return true;
}
static void adjust_channel_feerate_bounds(struct channel *channel, u32 feerate)
{
if (feerate > channel->max_possible_feerate)
channel->max_possible_feerate = feerate;
if (feerate < channel->min_possible_feerate)
channel->min_possible_feerate = feerate;
}
void peer_sending_commitsig(struct channel *channel, const u8 *msg)
{
u64 commitnum;
u32 feerate;
struct fee_states *fee_states;
struct changed_htlc *changed_htlcs;
size_t i, maxid = 0, num_local_added = 0;
struct bitcoin_signature commit_sig;
@ -1361,9 +1369,10 @@ void peer_sending_commitsig(struct channel *channel, const u8 *msg)
if (!fromwire_channel_sending_commitsig(msg, msg,
&commitnum,
&feerate,
&fee_states,
&changed_htlcs,
&commit_sig, &htlc_sigs)) {
&commit_sig, &htlc_sigs)
|| !fee_states_valid(fee_states, channel->funder)) {
channel_internal_error(channel, "bad channel_sending_commitsig %s",
tal_hex(channel, msg));
return;
@ -1397,14 +1406,14 @@ void peer_sending_commitsig(struct channel *channel, const u8 *msg)
channel->next_htlc_id += num_local_added;
}
/* Update remote feerate if we are funder. */
if (channel->funder == LOCAL)
channel->channel_info.feerate_per_kw[REMOTE] = feerate;
if (feerate > channel->max_possible_feerate)
channel->max_possible_feerate = feerate;
if (feerate < channel->min_possible_feerate)
channel->min_possible_feerate = feerate;
/* FIXME: We could detect if this changed, and adjust bounds and write
* it to db iff it has. */
tal_free(channel->channel_info.fee_states);
channel->channel_info.fee_states = tal_steal(channel, fee_states);
adjust_channel_feerate_bounds(channel,
get_feerate(fee_states,
channel->funder,
REMOTE));
if (!peer_save_commitsig_sent(channel, commitnum))
return;
@ -1523,7 +1532,7 @@ static void retry_deferred_commitsig(struct chain_topology *topo,
void peer_got_commitsig(struct channel *channel, const u8 *msg)
{
u64 commitnum;
u32 feerate;
struct fee_states *fee_states;
struct bitcoin_signature commit_sig;
secp256k1_ecdsa_signature *htlc_sigs;
struct added_htlc *added;
@ -1537,7 +1546,7 @@ void peer_got_commitsig(struct channel *channel, const u8 *msg)
if (!fromwire_channel_got_commitsig(msg, msg,
&commitnum,
&feerate,
&fee_states,
&commit_sig,
&htlc_sigs,
&added,
@ -1545,7 +1554,8 @@ void peer_got_commitsig(struct channel *channel, const u8 *msg)
&fulfilled,
&failed,
&changed,
&tx)) {
&tx)
|| !fee_states_valid(fee_states, channel->funder)) {
channel_internal_error(channel,
"bad fromwire_channel_got_commitsig %s",
tal_hex(channel, msg));
@ -1575,7 +1585,8 @@ void peer_got_commitsig(struct channel *channel, const u8 *msg)
log_debug(channel->log,
"got commitsig %"PRIu64
": feerate %u, %zu added, %zu fulfilled, %zu failed, %zu changed",
commitnum, feerate, tal_count(added), tal_count(fulfilled),
commitnum, get_feerate(fee_states, channel->funder, LOCAL),
tal_count(added), tal_count(fulfilled),
tal_count(failed), tal_count(changed));
/* New HTLCs */
@ -1603,17 +1614,12 @@ void peer_got_commitsig(struct channel *channel, const u8 *msg)
}
}
/* Update both feerates if we're not funder (for funder, receiving
* commitment_signed doesn't alter fees). */
if (channel->funder == REMOTE) {
channel->channel_info.feerate_per_kw[LOCAL]
= channel->channel_info.feerate_per_kw[REMOTE]
= feerate;
}
if (feerate > channel->max_possible_feerate)
channel->max_possible_feerate = feerate;
if (feerate < channel->min_possible_feerate)
channel->min_possible_feerate = feerate;
tal_free(channel->channel_info.fee_states);
channel->channel_info.fee_states = tal_steal(channel, fee_states);
adjust_channel_feerate_bounds(channel,
get_feerate(fee_states,
channel->funder,
LOCAL));
/* Since we're about to send revoke, bump state again. */
if (!peer_sending_revocation(channel, added, fulfilled, failed, changed))
@ -1652,13 +1658,14 @@ void peer_got_revoke(struct channel *channel, const u8 *msg)
enum onion_type *failcodes;
size_t i;
struct lightningd *ld = channel->peer->ld;
u32 feerate;
struct fee_states *fee_states;
if (!fromwire_channel_got_revoke(msg, msg,
&revokenum, &per_commitment_secret,
&next_per_commitment_point,
&feerate,
&changed)) {
&fee_states,
&changed)
|| !fee_states_valid(fee_states, channel->funder)) {
channel_internal_error(channel, "bad fromwire_channel_got_revoke %s",
tal_hex(channel, msg));
return;
@ -1716,10 +1723,8 @@ void peer_got_revoke(struct channel *channel, const u8 *msg)
return;
}
/* Update feerate if we are funder, their revoke_and_ack has set
* this for local feerate. */
if (channel->funder == LOCAL)
channel->channel_info.feerate_per_kw[LOCAL] = feerate;
tal_free(channel->channel_info.fee_states);
channel->channel_info.fee_states = tal_steal(channel, fee_states);
/* FIXME: Check per_commitment_secret -> per_commit_point */
update_per_commit_point(channel, &next_per_commitment_point);

View File

@ -25,8 +25,7 @@ struct channel_info {
/* The old_remote_per_commit is for the locked-in remote commit_tx,
* and the remote_per_commit is for the commit_tx we're modifying now. */
struct pubkey remote_per_commit, old_remote_per_commit;
/* In transition, these can be different! */
u32 feerate_per_kw[NUM_SIDES];
struct fee_states *fee_states;
};
/* Get all HTLCs for a peer, to send in init message. */

View File

@ -82,6 +82,10 @@ void connect_succeeded(struct lightningd *ld UNNEEDED, const struct node_id *id
void delay_then_reconnect(struct channel *channel UNNEEDED, u32 seconds_delay UNNEEDED,
const struct wireaddr_internal *addrhint TAKES UNNEEDED)
{ fprintf(stderr, "delay_then_reconnect called!\n"); abort(); }
/* Generated stub for dup_fee_states */
struct fee_states *dup_fee_states(const tal_t *ctx UNNEEDED,
const struct fee_states *fee_states TAKES UNNEEDED)
{ fprintf(stderr, "dup_fee_states called!\n"); abort(); }
/* Generated stub for encode_scriptpubkey_to_addr */
char *encode_scriptpubkey_to_addr(const tal_t *ctx UNNEEDED,
const struct chainparams *chainparams UNNEEDED,
@ -120,6 +124,11 @@ bool fromwire_onchain_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEE
/* Generated stub for get_block_height */
u32 get_block_height(const struct chain_topology *topo UNNEEDED)
{ fprintf(stderr, "get_block_height called!\n"); abort(); }
/* Generated stub for get_feerate */
u32 get_feerate(const struct fee_states *fee_states UNNEEDED,
enum side funder UNNEEDED,
enum side side UNNEEDED)
{ fprintf(stderr, "get_feerate called!\n"); abort(); }
/* Generated stub for get_offered_bolt11features */
u8 *get_offered_bolt11features(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "get_offered_bolt11features called!\n"); abort(); }

View File

@ -221,6 +221,7 @@ class Type(FieldSet):
'per_peer_state',
'bitcoin_tx_output',
'exclude_entry',
'fee_states',
]
# Some BOLT types are re-typed based on their field name

View File

@ -8,6 +8,7 @@ WALLET_TEST_COMMON_OBJS := \
common/derive_basepoints.o \
common/htlc_state.o \
common/htlc_wire.o \
common/fee_states.o \
common/type_to_string.o \
common/memleak.o \
common/node_id.o \

View File

@ -97,16 +97,16 @@ void fatal(const char *fmt UNNEEDED, ...)
bool fromwire_channel_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)
{ fprintf(stderr, "fromwire_channel_dev_memleak_reply called!\n"); abort(); }
/* Generated stub for fromwire_channel_got_commitsig */
bool fromwire_channel_got_commitsig(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *commitnum UNNEEDED, u32 *feerate UNNEEDED, struct bitcoin_signature *signature UNNEEDED, secp256k1_ecdsa_signature **htlc_signature UNNEEDED, struct added_htlc **added UNNEEDED, struct secret **shared_secret UNNEEDED, struct fulfilled_htlc **fulfilled UNNEEDED, struct failed_htlc ***failed UNNEEDED, struct changed_htlc **changed UNNEEDED, struct bitcoin_tx **tx UNNEEDED)
bool fromwire_channel_got_commitsig(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *commitnum UNNEEDED, struct fee_states **fee_states UNNEEDED, struct bitcoin_signature *signature UNNEEDED, secp256k1_ecdsa_signature **htlc_signature UNNEEDED, struct added_htlc **added UNNEEDED, struct secret **shared_secret UNNEEDED, struct fulfilled_htlc **fulfilled UNNEEDED, struct failed_htlc ***failed UNNEEDED, struct changed_htlc **changed UNNEEDED, struct bitcoin_tx **tx UNNEEDED)
{ fprintf(stderr, "fromwire_channel_got_commitsig called!\n"); abort(); }
/* Generated stub for fromwire_channel_got_revoke */
bool fromwire_channel_got_revoke(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *revokenum UNNEEDED, struct secret *per_commitment_secret UNNEEDED, struct pubkey *next_per_commit_point UNNEEDED, u32 *feerate UNNEEDED, struct changed_htlc **changed UNNEEDED)
bool fromwire_channel_got_revoke(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *revokenum UNNEEDED, struct secret *per_commitment_secret UNNEEDED, struct pubkey *next_per_commit_point UNNEEDED, struct fee_states **fee_states UNNEEDED, struct changed_htlc **changed UNNEEDED)
{ fprintf(stderr, "fromwire_channel_got_revoke called!\n"); abort(); }
/* Generated stub for fromwire_channel_offer_htlc_reply */
bool fromwire_channel_offer_htlc_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *id UNNEEDED, u16 *failure_code UNNEEDED, u8 **failurestr UNNEEDED)
{ fprintf(stderr, "fromwire_channel_offer_htlc_reply called!\n"); abort(); }
/* Generated stub for fromwire_channel_sending_commitsig */
bool fromwire_channel_sending_commitsig(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *commitnum UNNEEDED, u32 *feerate UNNEEDED, struct changed_htlc **changed UNNEEDED, struct bitcoin_signature *commit_sig UNNEEDED, secp256k1_ecdsa_signature **htlc_sigs UNNEEDED)
bool fromwire_channel_sending_commitsig(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *commitnum UNNEEDED, struct fee_states **fee_states UNNEEDED, struct changed_htlc **changed UNNEEDED, struct bitcoin_signature *commit_sig UNNEEDED, secp256k1_ecdsa_signature **htlc_sigs UNNEEDED)
{ fprintf(stderr, "fromwire_channel_sending_commitsig called!\n"); abort(); }
/* Generated stub for fromwire_connect_peer_connected */
bool fromwire_connect_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct per_peer_state **pps UNNEEDED, u8 **features UNNEEDED)
@ -933,6 +933,17 @@ static bool channelseq(struct channel *c1, struct channel *c2)
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(fee_states_valid(ci1->fee_states, c1->funder));
CHECK(fee_states_valid(ci2->fee_states, c2->funder));
for (enum htlc_state i = 0; i < ARRAY_SIZE(ci1->fee_states->feerate);
i++) {
if (ci1->fee_states->feerate[i] == NULL) {
CHECK(ci2->fee_states->feerate[i] == NULL);
} else {
CHECK(*ci1->fee_states->feerate[i]
== *ci2->fee_states->feerate[i]);
}
}
CHECK(c1->our_config.id != 0 && c1->our_config.id == c2->our_config.id);
CHECK((lc1 != NULL) == (lc2 != NULL));
@ -993,6 +1004,7 @@ static bool test_channel_crud(struct lightningd *ld, const tal_t *ctx)
secp256k1_ecdsa_signature *node_sig1 = tal(w, secp256k1_ecdsa_signature);
secp256k1_ecdsa_signature *bitcoin_sig1 = tal(w, secp256k1_ecdsa_signature);
secp256k1_ecdsa_signature *node_sig2, *bitcoin_sig2;
u32 feerate;
bool load;
memset(&c1, 0, sizeof(c1));
@ -1006,7 +1018,8 @@ static bool test_channel_crud(struct lightningd *ld, const tal_t *ctx)
mempat(last_commit, tal_bytelen(last_commit));
pubkey_from_der(tal_hexdata(w, "02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc", 66), 33, &pk);
node_id_from_pubkey(&id, &pk);
ci->feerate_per_kw[LOCAL] = ci->feerate_per_kw[REMOTE] = 31337;
feerate = 31337;
ci->fee_states = new_fee_states(w, c1.funder, &feerate);
mempat(scriptpubkey, tal_count(scriptpubkey));
c1.first_blocknum = 1;
parse_wireaddr_internal("localhost:1234", &addr, 0, false, false, false,

View File

@ -2,8 +2,10 @@
#include "wallet.h"
#include <bitcoin/script.h>
#include <ccan/array_size/array_size.h>
#include <ccan/mem/mem.h>
#include <ccan/tal/str/str.h>
#include <common/fee_states.h>
#include <common/key_derive.h>
#include <common/memleak.h>
#include <common/wireaddr.h>
@ -805,6 +807,42 @@ fail:
return false;
}
static struct fee_states *wallet_channel_fee_states_load(struct wallet *w,
const u64 id,
enum side funder)
{
struct fee_states *fee_states;
struct db_stmt *stmt;
stmt = db_prepare_v2(w->db, SQL("SELECT hstate, feerate_per_kw FROM channel_feerates WHERE channel_id = ?"));
db_bind_u64(stmt, 0, id);
db_query_prepared(stmt);
/* Start with blank slate. */
fee_states = new_fee_states(w, funder, NULL);
while (db_step(stmt)) {
enum htlc_state hstate = db_column_int(stmt, 0);
u32 feerate = db_column_int(stmt, 1);
if (fee_states->feerate[hstate] != NULL) {
log_broken(w->log,
"duplicate channel_feerates for %s id %"PRIu64,
htlc_state_name(hstate), id);
fee_states = tal_free(fee_states);
break;
}
fee_states->feerate[hstate] = tal_dup(fee_states, u32, &feerate);
}
tal_free(stmt);
if (fee_states && !fee_states_valid(fee_states, funder)) {
log_broken(w->log,
"invalid channel_feerates for id %"PRIu64, id);
fee_states = tal_free(fee_states);
}
return fee_states;
}
/**
* wallet_stmt2channel - Helper to populate a wallet_channel from a `db_stmt`
*/
@ -894,13 +932,19 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
db_column_pubkey(stmt, 22, &channel_info.theirbase.delayed_payment);
db_column_pubkey(stmt, 23, &channel_info.remote_per_commit);
db_column_pubkey(stmt, 24, &channel_info.old_remote_per_commit);
channel_info.feerate_per_kw[LOCAL] = db_column_int(stmt, 25);
channel_info.feerate_per_kw[REMOTE] = db_column_int(stmt, 26);
wallet_channel_config_load(w, db_column_u64(stmt, 4),
&channel_info.their_config);
channel_info.fee_states
= wallet_channel_fee_states_load(w,
db_column_u64(stmt, 0),
db_column_int(stmt, 6));
if (!channel_info.fee_states)
ok = false;
if (!ok) {
tal_free(channel_info.fee_states);
return NULL;
}
@ -919,6 +963,8 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
db_column_amount_msat(stmt, 38, &msat_to_us_min);
db_column_amount_msat(stmt, 39, &msat_to_us_max);
/* We want it to take this, rather than copy. */
take(channel_info.fee_states);
chan = new_channel(peer, db_column_u64(stmt, 0),
&wshachain,
db_column_int(stmt, 5),
@ -1011,6 +1057,7 @@ static bool wallet_channels_load_active(struct wallet *w)
", delayed_payment_basepoint_remote"
", per_commit_remote"
", old_per_commit_remote"
/* FIXME: We don't use these two: */
", local_feerate_per_kw"
", remote_feerate_per_kw"
", shachain_remote_id"
@ -1358,8 +1405,6 @@ void wallet_channel_save(struct wallet *w, struct channel *chan)
" delayed_payment_basepoint_remote=?,"
" per_commit_remote=?,"
" old_per_commit_remote=?,"
" local_feerate_per_kw=?,"
" remote_feerate_per_kw=?,"
" channel_config_remote=?,"
" future_per_commitment_point=?"
" WHERE id=?"));
@ -1370,16 +1415,33 @@ void wallet_channel_save(struct wallet *w, struct channel *chan)
db_bind_pubkey(stmt, 4, &chan->channel_info.theirbase.delayed_payment);
db_bind_pubkey(stmt, 5, &chan->channel_info.remote_per_commit);
db_bind_pubkey(stmt, 6, &chan->channel_info.old_remote_per_commit);
db_bind_int(stmt, 7, chan->channel_info.feerate_per_kw[LOCAL]);
db_bind_int(stmt, 8, chan->channel_info.feerate_per_kw[REMOTE]);
db_bind_u64(stmt, 9, chan->channel_info.their_config.id);
db_bind_u64(stmt, 7, chan->channel_info.their_config.id);
if (chan->future_per_commitment_point)
db_bind_pubkey(stmt, 10, chan->future_per_commitment_point);
db_bind_pubkey(stmt, 8, chan->future_per_commitment_point);
else
db_bind_null(stmt, 10);
db_bind_u64(stmt, 11, chan->dbid);
db_bind_null(stmt, 8);
db_bind_u64(stmt, 9, chan->dbid);
db_exec_prepared_v2(take(stmt));
/* FIXME: Updates channel_feerates by discarding and rewriting. */
stmt = db_prepare_v2(w->db, SQL("DELETE FROM channel_feerates "
"WHERE channel_id=?"));
db_bind_u64(stmt, 0, chan->dbid);
db_exec_prepared_v2(take(stmt));
for (enum htlc_state i = 0;
i < ARRAY_SIZE(chan->channel_info.fee_states->feerate);
i++) {
if (!chan->channel_info.fee_states->feerate[i])
continue;
stmt = db_prepare_v2(w->db, SQL("INSERT INTO channel_feerates "
" VALUES(?, ?, ?)"));
db_bind_u64(stmt, 0, chan->dbid);
db_bind_int(stmt, 1, i);
db_bind_int(stmt, 2, *chan->channel_info.fee_states->feerate[i]);
db_exec_prepared_v2(take(stmt));
}
/* If we have a last_sent_commit, store it */
last_sent_commit = tal_arr(tmpctx, u8, 0);
for (size_t i = 0; i < tal_count(chan->last_sent_commit); i++)