void queue_pkt_htlc_fulfill(struct peer *peer, struct htlc *htlc, const struct rval *r) { UpdateFulfillHtlc *f = tal(peer, UpdateFulfillHtlc); union htlc_staging stage; update_fulfill_htlc__init(f); f->id = htlc->id; f->r = rval_to_proto(f, r); /* BOLT #2: * * The sending node MUST add the HTLC fulfill/fail to the * unacked changeset for its remote commitment */ assert(cstate_htlc_by_id(peer->remote.staging_cstate, f->id, THEIRS) == htlc); cstate_fulfill_htlc(peer->remote.staging_cstate, htlc, THEIRS); stage.fulfill.fulfill = HTLC_FULFILL; stage.fulfill.htlc = htlc; stage.fulfill.r = *r; add_unacked(&peer->remote, &stage); remote_changes_pending(peer); queue_pkt(peer, PKT__PKT_UPDATE_FULFILL_HTLC, f); }
void queue_pkt_open(struct peer *peer, OpenChannel__AnchorOffer anchor) { OpenChannel *o = tal(peer, OpenChannel); /* Set up out commit info now: rest gets done in setup_first_commit * once anchor is established. */ peer->local.commit = new_commit_info(peer); peer->local.commit->revocation_hash = peer->local.next_revocation_hash; peer_get_revocation_hash(peer, 1, &peer->local.next_revocation_hash); open_channel__init(o); o->revocation_hash = sha256_to_proto(o, &peer->local.commit->revocation_hash); o->next_revocation_hash = sha256_to_proto(o, &peer->local.next_revocation_hash); o->commit_key = pubkey_to_proto(o, peer->dstate->secpctx, &peer->local.commitkey); o->final_key = pubkey_to_proto(o, peer->dstate->secpctx, &peer->local.finalkey); o->delay = tal(o, Locktime); locktime__init(o->delay); o->delay->locktime_case = LOCKTIME__LOCKTIME_BLOCKS; o->delay->blocks = rel_locktime_to_blocks(&peer->local.locktime); o->initial_fee_rate = peer->local.commit_fee_rate; if (anchor == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR) assert(peer->local.offer_anchor == CMD_OPEN_WITH_ANCHOR); else { assert(anchor == OPEN_CHANNEL__ANCHOR_OFFER__WONT_CREATE_ANCHOR); assert(peer->local.offer_anchor == CMD_OPEN_WITHOUT_ANCHOR); } o->anch = anchor; o->min_depth = peer->local.mindepth; queue_pkt(peer, PKT__PKT_OPEN, o); }
void queue_pkt_htlc_fail(struct peer *peer, struct htlc *htlc) { UpdateFailHtlc *f = tal(peer, UpdateFailHtlc); union htlc_staging stage; update_fail_htlc__init(f); f->id = htlc->id; /* FIXME: reason! */ f->reason = tal(f, FailReason); fail_reason__init(f->reason); /* BOLT #2: * * The sending node MUST add the HTLC fulfill/fail to the * unacked changeset for its remote commitment */ assert(cstate_htlc_by_id(peer->remote.staging_cstate, f->id, THEIRS) == htlc); cstate_fail_htlc(peer->remote.staging_cstate, htlc, THEIRS); stage.fail.fail = HTLC_FAIL; stage.fail.htlc = htlc; add_unacked(&peer->remote, &stage); remote_changes_pending(peer); queue_pkt(peer, PKT__PKT_UPDATE_FAIL_HTLC, f); }
void queue_pkt_open_complete(struct peer *peer) { OpenComplete *o = tal(peer, OpenComplete); open_complete__init(o); queue_pkt(peer, PKT__PKT_OPEN_COMPLETE, o); }
void queue_pkt_htlc_add(struct peer *peer, struct htlc *htlc) { UpdateAddHtlc *u = tal(peer, UpdateAddHtlc); union htlc_staging stage; update_add_htlc__init(u); u->id = htlc->id; u->amount_msat = htlc->msatoshis; u->r_hash = sha256_to_proto(u, &htlc->rhash); u->expiry = abs_locktime_to_proto(u, &htlc->expiry); u->route = tal(u, Routing); routing__init(u->route); u->route->info.data = tal_dup_arr(u, u8, htlc->routing, tal_count(htlc->routing), 0); u->route->info.len = tal_count(u->route->info.data); /* BOLT #2: * * The sending node MUST add the HTLC addition to the unacked * changeset for its remote commitment */ if (!cstate_add_htlc(peer->remote.staging_cstate, htlc, OURS)) fatal("Could not add HTLC?"); stage.add.add = HTLC_ADD; stage.add.htlc = htlc; add_unacked(&peer->remote, &stage); remote_changes_pending(peer); queue_pkt(peer, PKT__PKT_UPDATE_ADD_HTLC, u); }
/* Send a preimage for the old commit tx. The one we've just committed to is * in peer->us.commit. */ void queue_pkt_revocation(struct peer *peer) { UpdateRevocation *u = tal(peer, UpdateRevocation); update_revocation__init(u); assert(peer->commit_tx_counter > 0); assert(peer->us.commit); assert(peer->us.commit->prev); assert(!peer->us.commit->prev->revocation_preimage); /* We have their signature on the current one, right? */ assert(peer->us.commit->sig); peer->us.commit->prev->revocation_preimage = tal(peer->us.commit->prev, struct sha256); peer_get_revocation_preimage(peer, peer->commit_tx_counter-1, peer->us.commit->prev->revocation_preimage); u->revocation_preimage = sha256_to_proto(u, peer->us.commit->prev->revocation_preimage); u->next_revocation_hash = sha256_to_proto(u, &peer->us.next_revocation_hash); u->ack = peer_outgoing_ack(peer); queue_pkt(peer, PKT__PKT_UPDATE_REVOCATION, u); }
void queue_pkt_anchor(struct peer *peer) { OpenAnchor *a = tal(peer, OpenAnchor); open_anchor__init(a); a->txid = sha256_to_proto(a, &peer->anchor.txid.sha); a->output_index = peer->anchor.index; a->amount = peer->anchor.satoshis; /* This shouldn't happen! */ if (!setup_first_commit(peer)) { queue_pkt_err(peer, pkt_err(peer, "Own anchor has insufficient funds")); return; } /* Sign their commit sig */ peer->them.commit->sig = tal(peer->them.commit, struct bitcoin_signature); peer->them.commit->sig->stype = SIGHASH_ALL; peer_sign_theircommit(peer, peer->them.commit->tx, &peer->them.commit->sig->sig); a->commit_sig = signature_to_proto(a, &peer->them.commit->sig->sig); queue_pkt(peer, PKT__PKT_OPEN_ANCHOR, a); }
/* OK, we're sending a signature for their pending changes. */ void queue_pkt_commit(struct peer *peer) { UpdateCommit *u = tal(peer, UpdateCommit); struct commit_info *ci = new_commit_info(peer); /* Create new commit info for this commit tx. */ ci->prev = peer->remote.commit; ci->commit_num = ci->prev->commit_num + 1; ci->revocation_hash = peer->remote.next_revocation_hash; /* BOLT #2: * * A sending node MUST apply all remote acked and unacked * changes except unacked fee changes to the remote commitment * before generating `sig`. */ ci->cstate = copy_cstate(ci, peer->remote.staging_cstate); ci->tx = create_commit_tx(ci, peer->dstate->secpctx, &peer->local.finalkey, &peer->remote.finalkey, &peer->local.locktime, &peer->remote.locktime, &peer->anchor.txid, peer->anchor.index, peer->anchor.satoshis, &ci->revocation_hash, ci->cstate, THEIRS, &ci->map); log_debug(peer->log, "Signing tx for %u/%u msatoshis, %zu/%zu htlcs", ci->cstate->side[OURS].pay_msat, ci->cstate->side[THEIRS].pay_msat, tal_count(ci->cstate->side[OURS].htlcs), tal_count(ci->cstate->side[THEIRS].htlcs)); /* BOLT #2: * * A node MUST NOT send an `update_commit` message which does * not include any updates. */ assert(ci->prev->cstate->changes != ci->cstate->changes); ci->sig = tal(ci, struct bitcoin_signature); ci->sig->stype = SIGHASH_ALL; peer_sign_theircommit(peer, ci->tx, &ci->sig->sig); /* Switch to the new commitment. */ peer->remote.commit = ci; /* Now send message */ update_commit__init(u); u->sig = signature_to_proto(u, peer->dstate->secpctx, &ci->sig->sig); queue_pkt(peer, PKT__PKT_UPDATE_COMMIT, u); }
/* Send a preimage for the old commit tx. The one we've just committed to is * in peer->local.commit. */ void queue_pkt_revocation(struct peer *peer) { UpdateRevocation *u = tal(peer, UpdateRevocation); struct commit_info *ci; update_revocation__init(u); assert(peer->local.commit); ci = peer->local.commit->prev; assert(ci); assert(!ci->revocation_preimage); /* We have their signature on the current one, right? */ assert(peer->local.commit->sig); ci->revocation_preimage = tal(ci, struct sha256); peer_get_revocation_preimage(peer, ci->commit_num, ci->revocation_preimage); u->revocation_preimage = sha256_to_proto(u, ci->revocation_preimage); u->next_revocation_hash = sha256_to_proto(u, &peer->local.next_revocation_hash); queue_pkt(peer, PKT__PKT_UPDATE_REVOCATION, u); /* BOLT #2: * * The node sending `update_revocation` MUST add the local unacked * changes to the set of remote acked changes. */ /* Note: this means the unacked changes as of the commit we're * revoking */ add_acked_changes(&peer->remote.commit->acked_changes, ci->unacked_changes); apply_changeset(peer, &peer->remote, THEIRS, ci->unacked_changes, tal_count(ci->unacked_changes)); if (tal_count(ci->unacked_changes)) remote_changes_pending(peer); /* We should never look at this again. */ ci->unacked_changes = tal_free(ci->unacked_changes); /* That revocation has committed us to changes in the current commitment. * Any acked changes come from their commitment, so those are now committed * by both of us. */ peer_both_committed_to(peer, ci->acked_changes, OURS); }
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); }
void queue_pkt_close_clearing(struct peer *peer) { u8 *redeemscript; CloseClearing *c = tal(peer, CloseClearing); close_clearing__init(c); redeemscript = bitcoin_redeem_single(c, &peer->us.finalkey); peer->closing.our_script = scriptpubkey_p2sh(peer, redeemscript); c->scriptpubkey.data = tal_dup_arr(c, u8, peer->closing.our_script, tal_count(peer->closing.our_script), 0); c->scriptpubkey.len = tal_count(c->scriptpubkey.data); queue_pkt(peer, PKT__PKT_CLOSE_CLEARING, c); }
/* OK, we're sending a signature for their pending changes. */ void queue_pkt_commit(struct peer *peer) { UpdateCommit *u = tal(peer, UpdateCommit); struct commit_info *ci = talz(peer, struct commit_info); /* Create new commit info for this commit tx. */ ci->prev = peer->them.commit; ci->revocation_hash = peer->them.next_revocation_hash; ci->cstate = copy_funding(ci, peer->them.staging_cstate); ci->tx = create_commit_tx(ci, &peer->them.finalkey, &peer->us.finalkey, &peer->us.locktime, &peer->anchor.txid, peer->anchor.index, peer->anchor.satoshis, &ci->revocation_hash, ci->cstate); log_debug(peer->log, "Signing tx for %u/%u msatoshis, %zu/%zu htlcs", ci->cstate->a.pay_msat, ci->cstate->b.pay_msat, tal_count(ci->cstate->a.htlcs), tal_count(ci->cstate->b.htlcs)); /* BOLT #2: * * A node MUST NOT send an `update_commit` message which does * not include any updates. */ assert(ci->prev->cstate->changes != ci->cstate->changes); ci->sig = tal(ci, struct bitcoin_signature); ci->sig->stype = SIGHASH_ALL; peer_sign_theircommit(peer, ci->tx, &ci->sig->sig); /* Switch to the new commitment. */ peer->them.commit = ci; /* Now send message */ update_commit__init(u); u->sig = signature_to_proto(u, &ci->sig->sig); u->ack = peer_outgoing_ack(peer); queue_pkt(peer, PKT__PKT_UPDATE_COMMIT, u); }
void queue_pkt_open_commit_sig(struct peer *peer) { OpenCommitSig *s = tal(peer, OpenCommitSig); open_commit_sig__init(s); dump_tx("Creating sig for:", peer->them.commit->tx); dump_key("Using key:", &peer->us.commitkey); peer->them.commit->sig = tal(peer->them.commit, struct bitcoin_signature); peer->them.commit->sig->stype = SIGHASH_ALL; peer_sign_theircommit(peer, peer->them.commit->tx, &peer->them.commit->sig->sig); s->sig = signature_to_proto(s, &peer->them.commit->sig->sig); queue_pkt(peer, PKT__PKT_OPEN_COMMIT_SIG, s); }
void queue_pkt_anchor(struct peer *peer) { OpenAnchor *a = tal(peer, OpenAnchor); open_anchor__init(a); a->txid = sha256_to_proto(a, &peer->anchor.txid.sha); a->output_index = peer->anchor.index; a->amount = peer->anchor.satoshis; /* This shouldn't happen! */ if (!setup_first_commit(peer)) { queue_pkt_err(peer, pkt_err(peer, "Own anchor has insufficient funds")); return; } queue_pkt(peer, PKT__PKT_OPEN_ANCHOR, a); }
void queue_pkt_open_commit_sig(struct peer *peer) { OpenCommitSig *s = tal(peer, OpenCommitSig); open_commit_sig__init(s); log_debug_struct(peer->log, "Creating sig for %s", struct bitcoin_tx, peer->remote.commit->tx); log_add_struct(peer->log, " using key %s", struct pubkey, &peer->local.commitkey); peer->remote.commit->sig = tal(peer->remote.commit, struct bitcoin_signature); peer->remote.commit->sig->stype = SIGHASH_ALL; peer_sign_theircommit(peer, peer->remote.commit->tx, &peer->remote.commit->sig->sig); s->sig = signature_to_proto(s, peer->dstate->secpctx, &peer->remote.commit->sig->sig); queue_pkt(peer, PKT__PKT_OPEN_COMMIT_SIG, s); }