common/per_per_state: generalize lightningd/peer_comm Part 1

Encapsulating the peer state was a win for lightningd; not surprisingly,
it's even more of a win for the other daemons, especially as we want
to add a little gossip information.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2019-06-04 03:41:25 +09:30
parent f1b4b14be5
commit 38d2899fbb
45 changed files with 490 additions and 436 deletions

View File

@@ -62,6 +62,7 @@ CLOSINGD_COMMON_OBJS := \
common/msg_queue.o \
common/peer_billboard.o \
common/peer_failed.o \
common/per_peer_state.o \
common/permute_tx.o \
common/read_peer_msg.o \
common/socket_close.o \

View File

@@ -1,8 +1,9 @@
#include <common/cryptomsg.h>
#include <common/htlc_wire.h>
#include <common/per_peer_state.h>
# Begin! (passes peer fd, gossipd-client fd)
closing_init,2001
closing_init,,crypto_state,struct crypto_state
closing_init,,pps,struct per_peer_state
closing_init,,funding_txid,struct bitcoin_txid
closing_init,,funding_txout,u16
closing_init,,funding_satoshi,struct amount_sat
1 #include <common/cryptomsg.h>
2 #include <common/htlc_wire.h>
3 #include <common/per_peer_state.h>
4 # Begin! (passes peer fd, gossipd-client fd)
5 closing_init,2001
6 closing_init,,crypto_state,struct crypto_state closing_init,,pps,struct per_peer_state
7 closing_init,,funding_txid,struct bitcoin_txid
8 closing_init,,funding_txout,u16
9 closing_init,,funding_satoshi,struct amount_sat

View File

@@ -8,6 +8,7 @@
#include <common/memleak.h>
#include <common/peer_billboard.h>
#include <common/peer_failed.h>
#include <common/per_peer_state.h>
#include <common/read_peer_msg.h>
#include <common/socket_close.h>
#include <common/status.h>
@@ -27,13 +28,10 @@
/* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = hsmd */
#define REQ_FD STDIN_FILENO
#define PEER_FD 3
#define GOSSIP_FD 4
#define GOSSIP_STORE_FD 5
#define HSM_FD 6
static struct bitcoin_tx *close_tx(const tal_t *ctx,
struct crypto_state *cs,
struct per_peer_state *pps,
const struct channel_id *channel_id,
u8 *scriptpubkey[NUM_SIDES],
const struct bitcoin_txid *funding_txid,
@@ -50,7 +48,7 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx,
out_minus_fee[LOCAL] = out[LOCAL];
out_minus_fee[REMOTE] = out[REMOTE];
if (!amount_sat_sub(&out_minus_fee[funder], out[funder], fee))
peer_failed(cs, channel_id,
peer_failed(pps, channel_id,
"Funder cannot afford fee %s (%s and %s)",
type_to_string(tmpctx, struct amount_sat, &fee),
type_to_string(tmpctx, struct amount_sat,
@@ -73,7 +71,7 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx,
out_minus_fee[REMOTE],
dust_limit);
if (!tx)
peer_failed(cs, channel_id,
peer_failed(pps, channel_id,
"Both outputs below dust limit:"
" funding = %s"
" fee = %s"
@@ -90,7 +88,7 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx,
/* Handle random messages we might get, returning the first non-handled one. */
static u8 *closing_read_peer_msg(const tal_t *ctx,
struct crypto_state *cs,
struct per_peer_state *pps,
const struct channel_id *channel_id)
{
for (;;) {
@@ -98,22 +96,17 @@ static u8 *closing_read_peer_msg(const tal_t *ctx,
bool from_gossipd;
clean_tmpctx();
msg = peer_or_gossip_sync_read(ctx, PEER_FD, GOSSIP_FD,
cs, &from_gossipd);
msg = peer_or_gossip_sync_read(ctx, pps, &from_gossipd);
if (from_gossipd) {
handle_gossip_msg(PEER_FD, GOSSIP_FD, GOSSIP_STORE_FD,
cs, take(msg));
handle_gossip_msg(pps, take(msg));
continue;
}
if (!handle_peer_gossip_or_error(PEER_FD, GOSSIP_FD,
GOSSIP_STORE_FD,
cs,
channel_id, msg))
if (!handle_peer_gossip_or_error(pps, channel_id, msg))
return msg;
}
}
static void do_reconnect(struct crypto_state *cs,
static void do_reconnect(struct per_peer_state *pps,
const struct channel_id *channel_id,
const u64 next_index[NUM_SIDES],
u64 revocations_received,
@@ -174,13 +167,13 @@ static void do_reconnect(struct crypto_state *cs,
revocations_received,
last_remote_per_commit_secret,
&my_current_per_commitment_point);
sync_crypto_write(cs, PEER_FD, take(msg));
sync_crypto_write(pps, take(msg));
/* They might have already send reestablish, which triggered us */
if (!channel_reestablish) {
do {
tal_free(channel_reestablish);
channel_reestablish = closing_read_peer_msg(tmpctx, cs,
channel_reestablish = closing_read_peer_msg(tmpctx, pps,
channel_id);
/* They *should* send reestablish first, but lnd
* sends other messages, which we can ignore since
@@ -192,7 +185,7 @@ static void do_reconnect(struct crypto_state *cs,
if (!fromwire_channel_reestablish(channel_reestablish, &their_channel_id,
&next_local_commitment_number,
&next_remote_revocation_number)) {
peer_failed(cs, channel_id,
peer_failed(pps, channel_id,
"bad reestablish msg: %s %s",
wire_type_name(fromwire_peektype(channel_reestablish)),
tal_hex(tmpctx, channel_reestablish));
@@ -210,13 +203,13 @@ static void do_reconnect(struct crypto_state *cs,
* - MUST retransmit `shutdown`.
*/
msg = towire_shutdown(NULL, channel_id, final_scriptpubkey);
sync_crypto_write(cs, PEER_FD, take(msg));
sync_crypto_write(pps, take(msg));
/* FIXME: Spec says to re-xmit funding_locked here if we haven't
* done any updates. */
}
static void send_offer(struct crypto_state *cs,
static void send_offer(struct per_peer_state *pps,
const struct channel_id *channel_id,
const struct pubkey funding_pubkey[NUM_SIDES],
u8 *scriptpubkey[NUM_SIDES],
@@ -238,7 +231,7 @@ static void send_offer(struct crypto_state *cs,
* transaction, as specified in [BOLT
* #3](03-transactions.md#closing-transaction).
*/
tx = close_tx(tmpctx, cs, channel_id,
tx = close_tx(tmpctx, pps, channel_id,
scriptpubkey,
funding_txid,
funding_txout,
@@ -270,7 +263,7 @@ static void send_offer(struct crypto_state *cs,
assert(our_sig.sighash_type == SIGHASH_ALL);
msg = towire_closing_signed(NULL, channel_id, fee_to_offer, &our_sig.s);
sync_crypto_write(cs, PEER_FD, take(msg));
sync_crypto_write(pps, take(msg));
}
static void tell_master_their_offer(const struct bitcoin_signature *their_sig,
@@ -292,7 +285,7 @@ static void tell_master_their_offer(const struct bitcoin_signature *their_sig,
/* Returns fee they offered. */
static struct amount_sat
receive_offer(struct crypto_state *cs,
receive_offer(struct per_peer_state *pps,
const struct channel_id *channel_id,
const struct pubkey funding_pubkey[NUM_SIDES],
const u8 *funding_wscript,
@@ -314,7 +307,7 @@ receive_offer(struct crypto_state *cs,
/* Wait for them to say something interesting */
do {
msg = closing_read_peer_msg(tmpctx, cs, channel_id);
msg = closing_read_peer_msg(tmpctx, pps, channel_id);
/* BOLT #2:
*
@@ -336,7 +329,7 @@ receive_offer(struct crypto_state *cs,
their_sig.sighash_type = SIGHASH_ALL;
if (!fromwire_closing_signed(msg, &their_channel_id,
&received_fee, &their_sig.s))
peer_failed(cs, channel_id,
peer_failed(pps, channel_id,
"Expected closing_signed: %s",
tal_hex(tmpctx, msg));
@@ -347,7 +340,7 @@ receive_offer(struct crypto_state *cs,
* specified in [BOLT #3](03-transactions.md#closing-transaction):
* - MUST fail the connection.
*/
tx = close_tx(tmpctx, cs, channel_id,
tx = close_tx(tmpctx, pps, channel_id,
scriptpubkey,
funding_txid,
funding_txout,
@@ -376,7 +369,7 @@ receive_offer(struct crypto_state *cs,
* `dust_limit_satoshis`.
* - MAY eliminate its own output.
*/
trimmed = close_tx(tmpctx, cs, channel_id,
trimmed = close_tx(tmpctx, pps, channel_id,
scriptpubkey,
funding_txid,
funding_txout,
@@ -386,7 +379,7 @@ receive_offer(struct crypto_state *cs,
if (!trimmed
|| !check_tx_sig(trimmed, 0, NULL, funding_wscript,
&funding_pubkey[REMOTE], &their_sig)) {
peer_failed(cs, channel_id,
peer_failed(pps, channel_id,
"Bad closing_signed signature for"
" %s (and trimmed version %s)",
type_to_string(tmpctx,
@@ -470,7 +463,7 @@ static void adjust_feerange(struct feerange *feerange,
}
/* Figure out what we should offer now. */
static struct amount_sat adjust_offer(struct crypto_state *cs,
static struct amount_sat adjust_offer(struct per_peer_state *pps,
const struct channel_id *channel_id,
const struct feerange *feerange,
struct amount_sat remote_offer,
@@ -480,7 +473,7 @@ static struct amount_sat adjust_offer(struct crypto_state *cs,
/* Within 1 satoshi? Agree. */
if (!amount_sat_add(&min_plus_one, feerange->min, AMOUNT_SAT(1)))
peer_failed(cs, channel_id,
peer_failed(pps, channel_id,
"Fee offer %s min too large",
type_to_string(tmpctx, struct amount_sat,
&feerange->min));
@@ -490,7 +483,7 @@ static struct amount_sat adjust_offer(struct crypto_state *cs,
/* Max is below our minimum acceptable? */
if (amount_sat_less(feerange->max, min_fee_to_accept))
peer_failed(cs, channel_id,
peer_failed(pps, channel_id,
"Feerange %s-%s"
" below minimum acceptable %s",
type_to_string(tmpctx, struct amount_sat,
@@ -505,7 +498,7 @@ static struct amount_sat adjust_offer(struct crypto_state *cs,
min_fee_to_accept = feerange->min;
if (!amount_sat_add(&avg, feerange->max, min_fee_to_accept))
peer_failed(cs, channel_id,
peer_failed(pps, channel_id,
"Fee offer %s max too large",
type_to_string(tmpctx, struct amount_sat,
&feerange->max));
@@ -539,8 +532,8 @@ int main(int argc, char *argv[])
{
setup_locale();
struct crypto_state cs;
const tal_t *ctx = tal(NULL, char);
struct per_peer_state *pps;
u8 *msg;
struct pubkey funding_pubkey[NUM_SIDES];
struct bitcoin_txid funding_txid, closing_txid;
@@ -564,7 +557,7 @@ int main(int argc, char *argv[])
msg = wire_sync_read(tmpctx, REQ_FD);
if (!fromwire_closing_init(ctx, msg,
&cs,
&pps,
&funding_txid, &funding_txout,
&funding,
&funding_pubkey[LOCAL],
@@ -586,6 +579,9 @@ int main(int argc, char *argv[])
&last_remote_per_commit_secret))
master_badmsg(WIRE_CLOSING_INIT, msg);
/* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = hsmd */
per_peer_state_set_fds(pps, 3, 4, 5);
status_trace("out = %s/%s",
type_to_string(tmpctx, struct amount_sat, &out[LOCAL]),
type_to_string(tmpctx, struct amount_sat, &out[REMOTE]));
@@ -600,7 +596,7 @@ int main(int argc, char *argv[])
&funding_pubkey[REMOTE]);
if (reconnected)
do_reconnect(&cs, &channel_id,
do_reconnect(pps, &channel_id,
next_index, revocations_received,
channel_reestablish, final_scriptpubkey,
&last_remote_per_commit_secret);
@@ -626,7 +622,7 @@ int main(int argc, char *argv[])
whose_turn = funder;
for (size_t i = 0; i < 2; i++, whose_turn = !whose_turn) {
if (whose_turn == LOCAL) {
send_offer(&cs,
send_offer(pps,
&channel_id, funding_pubkey,
scriptpubkey, &funding_txid, funding_txout,
funding, out, funder,
@@ -644,7 +640,7 @@ int main(int argc, char *argv[])
struct amount_sat,
&offer[LOCAL]));
offer[REMOTE]
= receive_offer(&cs,
= receive_offer(pps,
&channel_id, funding_pubkey,
funding_wscript,
scriptpubkey, &funding_txid,
@@ -669,11 +665,11 @@ int main(int argc, char *argv[])
offer[!whose_turn], !whose_turn);
if (whose_turn == LOCAL) {
offer[LOCAL] = adjust_offer(&cs,
offer[LOCAL] = adjust_offer(pps,
&channel_id,
&feerange, offer[REMOTE],
min_fee_to_accept);
send_offer(&cs, &channel_id,
send_offer(pps, &channel_id,
funding_pubkey,
scriptpubkey, &funding_txid, funding_txout,
funding, out, funder,
@@ -686,7 +682,7 @@ int main(int argc, char *argv[])
" theirs was %"PRIu64" satoshi,",
offer[LOCAL], offer[REMOTE]);
offer[REMOTE]
= receive_offer(&cs, &channel_id,
= receive_offer(pps, &channel_id,
funding_pubkey,
funding_wscript,
scriptpubkey, &funding_txid,
@@ -711,7 +707,7 @@ int main(int argc, char *argv[])
/* We're done! */
/* Properly close the channel first. */
if (!socket_close(PEER_FD))
if (!socket_close(pps->peer_fd))
status_unusual("Closing and draining peerfd gave error: %s",
strerror(errno));
/* Sending the below will kill us! */