void queue_pkt_close_signature(struct peer *peer) { CloseSignature *c = tal(peer, CloseSignature); struct bitcoin_tx *close_tx; struct signature our_close_sig; close_signature__init(c); close_tx = peer_create_close_tx(peer, peer->closing.our_fee); peer_sign_mutual_close(peer, close_tx, &our_close_sig); c->sig = signature_to_proto(c, peer->dstate->secpctx, &our_close_sig); c->close_fee = peer->closing.our_fee; log_info(peer->log, "queue_pkt_close_signature: offered close fee %" PRIu64, c->close_fee); queue_pkt(peer, PKT__PKT_CLOSE_SIGNATURE, c); }
Pkt *accept_pkt_close_sig(struct peer *peer, const Pkt *pkt, bool *acked, bool *we_agree) { const CloseSignature *c = pkt->close_signature; struct bitcoin_tx *close_tx; struct bitcoin_signature theirsig; log_info(peer->log, "accept_pkt_close_sig: they offered close fee %" PRIu64, c->close_fee); *acked = *we_agree = false; /* BOLT #2: * * The sender MUST set `close_fee` lower than or equal to the fee of the * final commitment transaction, and MUST set `close_fee` to an even * number of satoshis. */ if ((c->close_fee & 1) || c->close_fee > commit_tx_fee(peer->them.commit->tx, peer->anchor.satoshis)) { return pkt_err(peer, "Invalid close fee"); } /* FIXME: Don't accept tiny fee at all? */ /* BOLT #2: ... otherwise it SHOULD propose a value strictly between the received `close_fee` and its previously-sent `close_fee`. */ if (peer->closing.their_sig) { /* We want more, they should give more. */ if (peer->closing.our_fee > peer->closing.their_fee) { if (c->close_fee <= peer->closing.their_fee) return pkt_err(peer, "Didn't increase close fee"); } else { if (c->close_fee >= peer->closing.their_fee) return pkt_err(peer, "Didn't decrease close fee"); } } /* BOLT #2: * * The receiver MUST check `sig` is valid for the close * transaction, and MUST fail the connection if it is not. */ theirsig.stype = SIGHASH_ALL; if (!proto_to_signature(c->sig, &theirsig.sig)) return pkt_err(peer, "Invalid signature format"); close_tx = peer_create_close_tx(peer, c->close_fee); if (!check_tx_sig(peer->dstate->secpctx, close_tx, 0, NULL, 0, peer->anchor.witnessscript, &peer->them.commitkey, &theirsig)) return pkt_err(peer, "Invalid signature"); tal_free(peer->closing.their_sig); peer->closing.their_sig = tal_dup(peer, struct bitcoin_signature, &theirsig); peer->closing.their_fee = c->close_fee; if (peer->closing.our_fee == peer->closing.their_fee) { log_info(peer->log, "accept_pkt_close_sig: That's an ack"); *acked = true; } else { /* Adjust our fee to close on their fee. */ u64 sum; /* Beware overflow! */ sum = (u64)peer->closing.our_fee + peer->closing.their_fee; peer->closing.our_fee = sum / 2; if (peer->closing.our_fee & 1) peer->closing.our_fee++; log_info(peer->log, "accept_pkt_close_sig: we change to %"PRIu64, peer->closing.our_fee); /* Corner case: we may now agree with them. */ if (peer->closing.our_fee == peer->closing.their_fee) *we_agree = true; } /* FIXME: Dynamic fee! */ return NULL; }