diff --git a/lightningd/closing/closing.c b/lightningd/closing/closing.c index 0cabac987..0769412ef 100644 --- a/lightningd/closing/closing.c +++ b/lightningd/closing/closing.c @@ -355,6 +355,7 @@ int main(int argc, char *argv[]) trimmed) : "NONE"); } + tx = trimmed; } status_trace("Received fee offer %"PRIu64, received_fee); @@ -377,8 +378,7 @@ int main(int argc, char *argv[]) } else { status_trace("Fee accepted."); msg = towire_closing_received_signature(tmpctx, - received_fee, - &sig); + &sig, tx); if (!wire_sync_write(REQ_FD, take(msg))) status_failed(WIRE_CLOSING_INTERNAL_ERROR, "Writing received to master: %s", diff --git a/lightningd/closing/closing_wire.csv b/lightningd/closing/closing_wire.csv index 3196b595b..91ba9494a 100644 --- a/lightningd/closing/closing_wire.csv +++ b/lightningd/closing/closing_wire.csv @@ -42,8 +42,8 @@ closing_init,,revocations_received,u64 # We received an offer, save signature. closing_received_signature,2 -closing_received_signature,,fee_satoshi,u64 closing_received_signature,,signature,secp256k1_ecdsa_signature +closing_received_signature,,tx,struct bitcoin_tx closing_received_signature_reply,102 diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 4d4c56599..d7a0009bb 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -97,7 +97,44 @@ static void peer_reconnect(struct peer *peer) static void drop_to_chain(struct peer *peer) { + const tal_t *tmpctx = tal_tmpctx(peer); + u8 *funding_wscript; + struct pubkey local_funding_pubkey; + struct secrets secrets; + secp256k1_ecdsa_signature sig; + /* FIXME: Implement. */ + if (peer->state != CLOSINGD_SIGEXCHANGE) { + tal_free(tmpctx); + return; + } + + derive_basepoints(peer->seed, &local_funding_pubkey, NULL, &secrets, + NULL); + + funding_wscript = bitcoin_redeem_2of2(tmpctx, + &local_funding_pubkey, + &peer->channel_info->remote_fundingkey); + /* Need input amount for signing */ + peer->last_tx->input[0].amount = tal_dup(peer->last_tx->input, u64, + &peer->funding_satoshi); + sign_tx_input(peer->last_tx, 0, NULL, funding_wscript, + &secrets.funding_privkey, + &local_funding_pubkey, + &sig); + + peer->last_tx->input[0].witness + = bitcoin_witness_2of2(peer->last_tx->input, + peer->last_sig, + &sig, + &peer->channel_info->remote_fundingkey, + &local_funding_pubkey); + + /* Keep broadcasting until we say stop (can fail due to dup, + * if they beat us to the broadcast). */ + broadcast_tx(peer->ld->topology, peer, peer->last_tx, NULL); + + tal_free(tmpctx); } void peer_fail_permanent(struct peer *peer, const u8 *msg) @@ -500,7 +537,6 @@ void add_peer(struct lightningd *ld, u64 unique_id, = peer->num_revocations_received = 0; peer->next_htlc_id = 0; wallet_shachain_init(ld->wallet, &peer->their_shachain); - peer->closing_sig_received = NULL; idname = type_to_string(peer, struct pubkey, id); @@ -1240,39 +1276,57 @@ static int closingd_got_negotiation_error(struct peer *peer, const u8 *msg) return -1; } -static bool better_closing_fee(struct peer *peer, u64 fee_satoshi) +void peer_last_tx(struct peer *peer, struct bitcoin_tx *tx, + const secp256k1_ecdsa_signature *sig) { - /* FIXME: Use estimatefee 24 or something? */ - u64 min_feerate = get_feerate(peer->ld->topology) / 2; - /* FIXME: Real fee, using real tx, and estimatefee 6 */ - u64 ideal_fee = commit_tx_base_fee(get_feerate(peer->ld->topology), 0); - s64 old_diff, new_diff; + /* FIXME: save to db. */ - /* FIXME: Use real tx here! (+ 74 for sig). */ - if (fee_satoshi < commit_tx_base_fee(min_feerate, 0)) + tal_free(peer->last_sig); + peer->last_sig = tal_dup(peer, secp256k1_ecdsa_signature, sig); + tal_free(peer->last_tx); + peer->last_tx = tal_steal(peer, tx); +} + +/* Is this better than the last tx we were holding? */ +static bool better_closing_fee(struct peer *peer, const struct bitcoin_tx *tx) +{ + u64 weight, fee, last_fee, ideal_fee, min_fee; + s64 old_diff, new_diff; + size_t i; + + /* Calculate actual fee. */ + fee = peer->funding_satoshi; + for (i = 0; i < tal_count(tx->output); i++) + fee -= tx->output[i].amount; + + last_fee = peer->funding_satoshi; + for (i = 0; i < tal_count(peer->last_tx); i++) + last_fee -= peer->last_tx->output[i].amount; + + /* Weight once we add in sigs. */ + weight = measure_tx_cost(tx) + 74 * 2; + + /* FIXME: Use estimatefee 24 or something? */ + min_fee = get_feerate(peer->ld->topology) / 5 * weight / 1000; + if (fee < min_fee) return false; - /* FIXME: Derive old fee from last tx, which would work even - * for the case where we're using the final commitment tx. */ - if (!peer->closing_sig_received) - return true; - - /* FIXME: Real fee, using real tx, and estimatefee 6 */ + /* FIXME: Use estimatefee 6 */ + ideal_fee = get_feerate(peer->ld->topology) / 2 * weight / 1000; /* We prefer fee which is closest to our ideal. */ - old_diff = imaxabs((s64)ideal_fee - (s64)peer->closing_fee_received); - new_diff = imaxabs((s64)ideal_fee - (s64)fee_satoshi); + old_diff = imaxabs((s64)ideal_fee - (s64)last_fee); + new_diff = imaxabs((s64)ideal_fee - (s64)fee); return (new_diff < old_diff); } static int peer_received_closing_signature(struct peer *peer, const u8 *msg) { - u64 fee_satoshi; secp256k1_ecdsa_signature sig; + struct bitcoin_tx *tx = tal(msg, struct bitcoin_tx); - if (!fromwire_closing_received_signature(msg, NULL, - &fee_satoshi, &sig)) { + if (!fromwire_closing_received_signature(msg, NULL, &sig, tx)) { peer_internal_error(peer, "Bad closing_received_signature %s", tal_hex(peer, msg)); return -1; @@ -1280,14 +1334,8 @@ static int peer_received_closing_signature(struct peer *peer, const u8 *msg) /* FIXME: Make sure signature is correct! */ - if (better_closing_fee(peer, fee_satoshi)) { - /* FIXME: save to db. */ - - peer->closing_fee_received = fee_satoshi; - tal_free(peer->closing_sig_received); - peer->closing_sig_received - = tal_dup(peer, secp256k1_ecdsa_signature, &sig); - } + if (better_closing_fee(peer, tx)) + peer_last_tx(peer, tx, &sig); /* OK, you can continue now. */ subd_send_msg(peer->owner, @@ -1297,13 +1345,6 @@ static int peer_received_closing_signature(struct peer *peer, const u8 *msg) static int peer_closing_complete(struct peer *peer, const u8 *msg) { - struct bitcoin_tx *tx; - u8 *local_scriptpubkey, *funding_wscript; - u64 out_amounts[NUM_SIDES]; - struct pubkey local_funding_pubkey; - struct secrets secrets; - secp256k1_ecdsa_signature sig; - if (!fromwire_closing_complete(msg, NULL)) { peer_internal_error(peer, "Bad closing_complete %s", tal_hex(peer, msg)); @@ -1314,60 +1355,7 @@ static int peer_closing_complete(struct peer *peer, const u8 *msg) if (peer->state == CLOSINGD_COMPLETE) return -1; - if (!peer->closing_sig_received) { - peer_internal_error(peer, - "closing_complete without sending sig!"); - return -1; - } - - local_scriptpubkey = p2wpkh_for_keyidx(msg, peer->ld, - peer->local_shutdown_idx); - if (!local_scriptpubkey) { - peer_internal_error(peer, - "Can't generate local shutdown scriptpubkey"); - return -1; - } - - /* BOLT #3: - * - * The amounts for each output MUST BE rounded down to whole satoshis. - */ - out_amounts[LOCAL] = *peer->our_msatoshi / 1000; - out_amounts[REMOTE] = peer->funding_satoshi - - (*peer->our_msatoshi / 1000); - out_amounts[peer->funder] -= peer->closing_fee_received; - - derive_basepoints(peer->seed, &local_funding_pubkey, NULL, &secrets, - NULL); - - tx = create_close_tx(msg, local_scriptpubkey, - peer->remote_shutdown_scriptpubkey, - peer->funding_txid, - peer->funding_outnum, - peer->funding_satoshi, - out_amounts[LOCAL], - out_amounts[REMOTE], - peer->our_config.dust_limit_satoshis); - - funding_wscript = bitcoin_redeem_2of2(msg, - &local_funding_pubkey, - &peer->channel_info->remote_fundingkey); - sign_tx_input(tx, 0, NULL, funding_wscript, - &secrets.funding_privkey, - &local_funding_pubkey, - &sig); - - tx->input[0].witness - = bitcoin_witness_2of2(tx->input, - peer->closing_sig_received, - &sig, - &peer->channel_info->remote_fundingkey, - &local_funding_pubkey); - - /* Keep broadcasting until we say stop (can fail due to dup, - * if they beat us to the broadcast). */ - broadcast_tx(peer->ld->topology, peer, tx, NULL); - + drop_to_chain(peer); peer_set_condition(peer, CLOSINGD_SIGEXCHANGE, CLOSINGD_COMPLETE); return -1; } diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h index 1d1e8667e..5340a531f 100644 --- a/lightningd/peer_control.h +++ b/lightningd/peer_control.h @@ -91,10 +91,6 @@ struct peer { /* Our key for shutdown (-1 if not chosen yet) */ s64 local_shutdown_idx; - /* Closing stuff. */ - u64 closing_fee_received; - secp256k1_ecdsa_signature *closing_sig_received; - /* Reestablishment stuff: last sent commit and revocation details. */ bool last_was_revoke; struct changed_htlc *last_sent_commit; @@ -142,6 +138,9 @@ struct peer *peer_from_json(struct lightningd *ld, const char *buffer, jsmntok_t *peeridtok); +void peer_last_tx(struct peer *peer, struct bitcoin_tx *tx, + const secp256k1_ecdsa_signature *sig); + void peer_fundee_open(struct peer *peer, const u8 *msg, const struct crypto_state *cs, int peer_fd, int gossip_fd); diff --git a/wallet/wallet.c b/wallet/wallet.c index 8a8550b94..e06597dac 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -525,16 +525,7 @@ static bool wallet_stmt2channel(struct wallet *w, sqlite3_stmt *stmt, col += 2; } - chan->peer->closing_fee_received = sqlite3_column_int64(stmt, col++); - if (sqlite3_column_type(stmt, col) != SQLITE_NULL) { - if (!chan->peer->closing_sig_received) { - chan->peer->closing_sig_received = tal(chan->peer, secp256k1_ecdsa_signature); - } - ok &= sqlite3_column_sig(stmt, col++, chan->peer->closing_sig_received); - } else { - col++; - } - assert(col == 36); + assert(col == 34); return ok; } @@ -559,8 +550,8 @@ bool wallet_channel_load(struct wallet *w, const u64 id, "old_per_commit_remote, feerate_per_kw, shachain_remote_id, " "shutdown_scriptpubkey_remote, shutdown_keyidx_local, " "last_sent_commit_state, last_sent_commit_id, " - "last_tx, last_sig, " - "closing_fee_received, closing_sig_received FROM channels WHERE " + "last_tx, last_sig " + "FROM channels WHERE " "id=%" PRIu64 ";"; sqlite3_stmt *stmt = db_query(__func__, w->db, channel_query, id); @@ -702,9 +693,7 @@ bool wallet_channel_save(struct wallet *w, struct wallet_channel *chan){ " shutdown_scriptpubkey_remote='%s'," " shutdown_keyidx_local=%"PRIu64"," " channel_config_local=%"PRIu64"," - " last_tx=%s, last_sig=%s, " - " closing_fee_received=%"PRIu64"," - " closing_sig_received=%s" + " last_tx=%s, last_sig=%s" " WHERE id=%"PRIu64, p->their_shachain.id, p->scid?tal_fmt(tmpctx,"'%s'", short_channel_id_to_str(tmpctx, p->scid)):"null", @@ -727,8 +716,6 @@ bool wallet_channel_save(struct wallet *w, struct wallet_channel *chan){ p->our_config.id, db_serialize_tx(tmpctx, p->last_tx), db_serialize_signature(tmpctx, p->last_sig), - p->closing_fee_received, - db_serialize_signature(tmpctx, p->closing_sig_received), chan->id); if (chan->peer->channel_info) { diff --git a/wallet/wallet_tests.c b/wallet/wallet_tests.c index 34a484514..137944e04 100644 --- a/wallet/wallet_tests.c +++ b/wallet/wallet_tests.c @@ -176,14 +176,6 @@ static bool channelseq(struct wallet_channel *c1, struct wallet_channel *c2) p2->last_sig, sizeof(*p2->last_sig))); } - CHECK((p1->closing_sig_received != NULL) == (p2->closing_sig_received != NULL)); - if(p1->closing_sig_received) { - CHECK(memeq(p1->closing_sig_received, - sizeof(secp256k1_ecdsa_signature), - p2->closing_sig_received, - sizeof(secp256k1_ecdsa_signature))); - } - return true; } @@ -275,12 +267,6 @@ static bool test_channel_crud(const tal_t *ctx) CHECK_MSG(wallet_channel_load(w, c1.id, c2), tal_fmt(w, "Load from DB: %s", w->db->err)); CHECK_MSG(channelseq(&c1, c2), "Compare loaded with saved (v7)"); - /* Variant 8: update with closing_sig */ - p.closing_sig_received = sig; - CHECK_MSG(wallet_channel_save(w, &c1), tal_fmt(w, "Insert into DB: %s", w->db->err)); - CHECK_MSG(wallet_channel_load(w, c1.id, c2), tal_fmt(w, "Load from DB: %s", w->db->err)); - CHECK_MSG(channelseq(&c1, c2), "Compare loaded with saved (v8)"); - tal_free(w); return true; }