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_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); }
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_htlc_add(struct peer *peer, const struct htlc_progress *htlc_prog) { UpdateAddHtlc *u = tal(peer, UpdateAddHtlc); update_add_htlc__init(u); assert(htlc_prog->stage.type == HTLC_ADD); u->id = htlc_prog->stage.add.htlc.id; u->amount_msat = htlc_prog->stage.add.htlc.msatoshis; u->r_hash = sha256_to_proto(u, &htlc_prog->stage.add.htlc.rhash); u->expiry = abs_locktime_to_proto(u, &htlc_prog->stage.add.htlc.expiry); /* FIXME: routing! */ u->route = tal(u, Routing); routing__init(u->route); /* We're about to send this, so their side will have it from now on. */ if (!funding_b_add_htlc(peer->them.staging_cstate, htlc_prog->stage.add.htlc.msatoshis, &htlc_prog->stage.add.htlc.expiry, &htlc_prog->stage.add.htlc.rhash, htlc_prog->stage.add.htlc.id)) fatal("Could not add HTLC?"); peer_add_htlc_expiry(peer, &htlc_prog->stage.add.htlc.expiry); queue_pkt_with_ack(peer, PKT__PKT_UPDATE_ADD_HTLC, u, add_our_htlc_ourside, tal_dup(peer, struct channel_htlc, &htlc_prog->stage.add.htlc)); }
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); }
Signature *signature_to_proto(const tal_t *ctx, const struct signature *sig) { Signature *pb = tal(ctx, Signature); signature__init(pb); assert(sig_valid(sig)); #ifdef USE_SCHNORR memcpy(&pb->r1, sig->schnorr, 8); memcpy(&pb->r2, sig->schnorr + 8, 8); memcpy(&pb->r3, sig->schnorr + 16, 8); memcpy(&pb->r4, sig->schnorr + 24, 8); memcpy(&pb->s1, sig->schnorr + 32, 8); memcpy(&pb->s2, sig->schnorr + 40, 8); memcpy(&pb->s3, sig->schnorr + 48, 8); memcpy(&pb->s4, sig->schnorr + 56, 8); #else /* FIXME: Need a portable way to encode signatures in libsecp! */ /* Kill me now... */ memcpy(&pb->r1, sig->sig.data, 8); memcpy(&pb->r2, sig->sig.data + 8, 8); memcpy(&pb->r3, sig->sig.data + 16, 8); memcpy(&pb->r4, sig->sig.data + 24, 8); memcpy(&pb->s1, sig->sig.data + 32, 8); memcpy(&pb->s2, sig->sig.data + 40, 8); memcpy(&pb->s3, sig->sig.data + 48, 8); memcpy(&pb->s4, sig->sig.data + 56, 8); #endif return pb; }
/* Wrap (and own!) member inside Pkt */ static Pkt *make_pkt(const tal_t *ctx, Pkt__PktCase type, const void *msg) { Pkt *pkt = tal(ctx, Pkt); pkt__init(pkt); pkt->pkt_case = type; /* This is a union, so doesn't matter which we assign. */ pkt->error = (Error *)tal_steal(pkt, msg); /* This makes sure all packets are valid. */ #ifndef NDEBUG { size_t len; u8 *packed; Pkt *cpy; len = pkt__get_packed_size(pkt); packed = tal_arr(pkt, u8, len); pkt__pack(pkt, packed); cpy = pkt__unpack(NULL, len, memcheck(packed, len)); assert(cpy); pkt__free_unpacked(cpy, NULL); tal_free(packed); } #endif return pkt; }
/* 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_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_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); }
static struct io_plan *handshake_success(struct io_conn *conn, const struct pubkey *them, const struct wireaddr_internal *addr, const struct crypto_state *orig_cs, char **args) { u8 *msg; struct crypto_state cs = *orig_cs; u8 *localfeatures; if (initial_sync) { localfeatures = tal(conn, u8); localfeatures[0] = (1 << 3); } else localfeatures = NULL; msg = towire_init(NULL, NULL, localfeatures); sync_crypto_write(&cs, conn->fd, take(msg)); /* Ignore their init message. */ tal_free(sync_crypto_read(NULL, &cs, conn->fd)); /* Did they ask us to send any messages? Do so now. */ if (stream_stdin) { beint16_t be_inlen; while (read_all(STDIN_FILENO, &be_inlen, sizeof(be_inlen))) { u32 msglen = be16_to_cpu(be_inlen); u8 *msg = tal_arr(NULL, u8, msglen); if (!read_all(STDIN_FILENO, msg, msglen)) err(1, "Only read partial message"); sync_crypto_write(&cs, conn->fd, take(msg)); } } while (*args) { u8 *m = tal_hexdata(NULL, *args, strlen(*args)); if (!m) errx(1, "Invalid hexdata '%s'", *args); sync_crypto_write(&cs, conn->fd, take(m)); args++; } /* Now write out whatever we get. */ while ((msg = sync_crypto_read(NULL, &cs, conn->fd)) != NULL) { be16 len = cpu_to_be16(tal_bytelen(msg)); if (!write_all(STDOUT_FILENO, &len, sizeof(len)) || !write_all(STDOUT_FILENO, msg, tal_bytelen(msg))) err(1, "Writing out msg"); tal_free(msg); if (--max_messages == 0) exit(0); } err(1, "Reading msg"); }
/* 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); }
BitcoinPubkey *pubkey_to_proto(const tal_t *ctx, const struct pubkey *key) { BitcoinPubkey *p = tal(ctx, BitcoinPubkey); bitcoin_pubkey__init(p); p->key.len = pubkey_len(key); p->key.data = tal_dup_arr(p, u8, key->key, p->key.len, 0); assert(pubkey_valid(p->key.data, p->key.len)); return p; }
Pkt *pkt_err(struct peer *peer, const char *msg, ...) { Error *e = tal(peer, Error); va_list ap; error__init(e); va_start(ap, msg); e->problem = tal_vfmt(e, msg, ap); va_end(ap); return make_pkt(peer, PKT__PKT_ERROR, e); }
void queue_pkt_htlc_fail(struct peer *peer, const struct htlc_progress *htlc_prog) { UpdateFailHtlc *f = tal(peer, UpdateFailHtlc); size_t n; update_fail_htlc__init(f); assert(htlc_prog->stage.type == HTLC_FAIL); f->id = htlc_prog->stage.fail.id; /* FIXME: reason! */ f->reason = tal(f, FailReason); fail_reason__init(f->reason); /* We're about to send this, so their side will have it from now on. */ n = funding_htlc_by_id(&peer->them.staging_cstate->a, f->id); funding_a_fail_htlc(peer->them.staging_cstate, n); queue_pkt_with_ack(peer, PKT__PKT_UPDATE_FAIL_HTLC, f, fail_their_htlc_ourside, int2ptr(f->id)); }
Sha256Hash *sha256_to_proto(const tal_t *ctx, const struct sha256 *hash) { Sha256Hash *h = tal(ctx, Sha256Hash); sha256_hash__init(h); /* Kill me now... */ memcpy(&h->a, hash->u.u8, 8); memcpy(&h->b, hash->u.u8 + 8, 8); memcpy(&h->c, hash->u.u8 + 16, 8); memcpy(&h->d, hash->u.u8 + 24, 8); return h; }
/* 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); }
Locktime *abs_locktime_to_proto(const tal_t *ctx, const struct abs_locktime *locktime) { Locktime *l = tal(ctx, Locktime); locktime__init(l); if (abs_locktime_is_seconds(locktime)) { l->locktime_case = LOCKTIME__LOCKTIME_SECONDS; l->seconds = abs_locktime_to_seconds(locktime); } else { l->locktime_case = LOCKTIME__LOCKTIME_BLOCKS; l->blocks = abs_locktime_to_blocks(locktime); } return l; }
/* 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_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); }
BitcoinPubkey *pubkey_to_proto(const tal_t *ctx, const struct pubkey *key) { BitcoinPubkey *p = tal(ctx, BitcoinPubkey); struct pubkey check; bitcoin_pubkey__init(p); p->key.len = pubkey_derlen(key); p->key.data = tal_dup_arr(p, u8, key->der, p->key.len, 0); { secp256k1_context *secpctx = secp256k1_context_create(0); assert(pubkey_from_der(secpctx, p->key.data, p->key.len, &check)); assert(pubkey_eq(&check, key)); secp256k1_context_destroy(secpctx); } return p; }
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); }
Signature *signature_to_proto(const tal_t *ctx, const struct signature *sig) { Signature *pb = tal(ctx, Signature); signature__init(pb); assert(sig_valid(sig)); /* Kill me now... */ memcpy(&pb->r1, sig->r, 8); memcpy(&pb->r2, sig->r + 8, 8); memcpy(&pb->r3, sig->r + 16, 8); memcpy(&pb->r4, sig->r + 24, 8); memcpy(&pb->s1, sig->s, 8); memcpy(&pb->s2, sig->s + 8, 8); memcpy(&pb->s3, sig->s + 16, 8); memcpy(&pb->s4, sig->s + 24, 8); return pb; }
void queue_pkt_htlc_fulfill(struct peer *peer, const struct htlc_progress *htlc_prog) { UpdateFulfillHtlc *f = tal(peer, UpdateFulfillHtlc); size_t n; update_fulfill_htlc__init(f); assert(htlc_prog->stage.type == HTLC_FULFILL); f->id = htlc_prog->stage.fulfill.id; f->r = sha256_to_proto(f, &htlc_prog->stage.fulfill.r); /* We're about to send this, so their side will have it from now on. */ n = funding_htlc_by_id(&peer->them.staging_cstate->a, f->id); funding_a_fulfill_htlc(peer->them.staging_cstate, n); queue_pkt_with_ack(peer, PKT__PKT_UPDATE_FULFILL_HTLC, f, fulfill_their_htlc_ourside, int2ptr(f->id)); }
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); }