mirror of
https://github.com/aljazceru/lightning.git
synced 2026-01-09 09:04:25 +01:00
peer: hoist do_commit and have it return false if it failed.
Next patch will call it from peer_start_shutdown(). Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
197
daemon/peer.c
197
daemon/peer.c
@@ -1425,6 +1425,105 @@ static bool shutdown_pkt_in(struct peer *peer, const Pkt *pkt)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool do_commit(struct peer *peer, struct command *jsoncmd)
|
||||
{
|
||||
struct commit_info *ci;
|
||||
const char *errmsg;
|
||||
static const struct htlcs_table changes[] = {
|
||||
{ SENT_ADD_HTLC, SENT_ADD_COMMIT },
|
||||
{ SENT_REMOVE_REVOCATION, SENT_REMOVE_ACK_COMMIT },
|
||||
{ SENT_ADD_REVOCATION, SENT_ADD_ACK_COMMIT},
|
||||
{ SENT_REMOVE_HTLC, SENT_REMOVE_COMMIT}
|
||||
};
|
||||
static const struct feechanges_table feechanges[] = {
|
||||
{ SENT_FEECHANGE, SENT_FEECHANGE_COMMIT },
|
||||
{ SENT_FEECHANGE_REVOCATION, SENT_FEECHANGE_ACK_COMMIT}
|
||||
};
|
||||
bool to_us_only;
|
||||
|
||||
/* We can have changes we suggested, or changes they suggested. */
|
||||
if (!peer_uncommitted_changes(peer)) {
|
||||
log_debug(peer->log, "do_commit: no changes to commit");
|
||||
if (jsoncmd)
|
||||
command_fail(jsoncmd, "no changes to commit");
|
||||
return true;
|
||||
}
|
||||
|
||||
log_debug(peer->log, "do_commit: sending commit command %"PRIu64,
|
||||
peer->remote.commit->commit_num + 1);
|
||||
|
||||
assert(state_can_commit(peer->state));
|
||||
assert(!peer->commit_jsoncmd);
|
||||
|
||||
peer->commit_jsoncmd = jsoncmd;
|
||||
ci = new_commit_info(peer, peer->remote.commit->commit_num + 1);
|
||||
|
||||
assert(!peer->their_prev_revocation_hash);
|
||||
peer->their_prev_revocation_hash
|
||||
= tal_dup(peer, struct sha256,
|
||||
&peer->remote.commit->revocation_hash);
|
||||
|
||||
db_start_transaction(peer);
|
||||
|
||||
errmsg = changestates(peer, changes, ARRAY_SIZE(changes),
|
||||
feechanges, ARRAY_SIZE(feechanges), true);
|
||||
if (errmsg) {
|
||||
log_broken(peer->log, "queue_pkt_commit: %s", errmsg);
|
||||
goto database_error;
|
||||
}
|
||||
|
||||
/* Create new commit info for this commit tx. */
|
||||
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, &ci->revocation_hash,
|
||||
ci->cstate, REMOTE, &to_us_only);
|
||||
bitcoin_txid(ci->tx, &ci->txid);
|
||||
|
||||
if (!to_us_only) {
|
||||
log_debug(peer->log, "Signing tx %"PRIu64, ci->commit_num);
|
||||
log_add_struct(peer->log, " for %s",
|
||||
struct channel_state, ci->cstate);
|
||||
log_add_struct(peer->log, " (txid %s)",
|
||||
struct sha256_double, &ci->txid);
|
||||
|
||||
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. */
|
||||
tal_free(peer->remote.commit);
|
||||
peer->remote.commit = ci;
|
||||
peer->remote.commit->order = peer->order_counter++;
|
||||
db_new_commit_info(peer, REMOTE, peer->their_prev_revocation_hash);
|
||||
|
||||
/* We don't need to remember their commit if we don't give sig. */
|
||||
if (ci->sig)
|
||||
peer_add_their_commit(peer, &ci->txid, ci->commit_num);
|
||||
|
||||
if (peer->state == STATE_SHUTDOWN) {
|
||||
set_peer_state(peer, STATE_SHUTDOWN_COMMITTING, __func__, true);
|
||||
} else {
|
||||
assert(peer->state == STATE_NORMAL);
|
||||
set_peer_state(peer, STATE_NORMAL_COMMITTING, __func__, true);
|
||||
}
|
||||
if (db_commit_transaction(peer) != NULL)
|
||||
goto database_error;
|
||||
|
||||
queue_pkt_commit(peer, ci->sig);
|
||||
return true;
|
||||
|
||||
database_error:
|
||||
db_abort_transaction(peer);
|
||||
peer_fail(peer, __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool peer_start_shutdown(struct peer *peer)
|
||||
{
|
||||
enum state newstate;
|
||||
@@ -2281,104 +2380,6 @@ static void peer_disconnect(struct io_conn *conn, struct peer *peer)
|
||||
}
|
||||
}
|
||||
|
||||
static void do_commit(struct peer *peer, struct command *jsoncmd)
|
||||
{
|
||||
struct commit_info *ci;
|
||||
const char *errmsg;
|
||||
static const struct htlcs_table changes[] = {
|
||||
{ SENT_ADD_HTLC, SENT_ADD_COMMIT },
|
||||
{ SENT_REMOVE_REVOCATION, SENT_REMOVE_ACK_COMMIT },
|
||||
{ SENT_ADD_REVOCATION, SENT_ADD_ACK_COMMIT},
|
||||
{ SENT_REMOVE_HTLC, SENT_REMOVE_COMMIT}
|
||||
};
|
||||
static const struct feechanges_table feechanges[] = {
|
||||
{ SENT_FEECHANGE, SENT_FEECHANGE_COMMIT },
|
||||
{ SENT_FEECHANGE_REVOCATION, SENT_FEECHANGE_ACK_COMMIT}
|
||||
};
|
||||
bool to_us_only;
|
||||
|
||||
/* We can have changes we suggested, or changes they suggested. */
|
||||
if (!peer_uncommitted_changes(peer)) {
|
||||
log_debug(peer->log, "do_commit: no changes to commit");
|
||||
if (jsoncmd)
|
||||
command_fail(jsoncmd, "no changes to commit");
|
||||
return;
|
||||
}
|
||||
|
||||
log_debug(peer->log, "do_commit: sending commit command %"PRIu64,
|
||||
peer->remote.commit->commit_num + 1);
|
||||
|
||||
assert(state_can_commit(peer->state));
|
||||
assert(!peer->commit_jsoncmd);
|
||||
|
||||
peer->commit_jsoncmd = jsoncmd;
|
||||
ci = new_commit_info(peer, peer->remote.commit->commit_num + 1);
|
||||
|
||||
assert(!peer->their_prev_revocation_hash);
|
||||
peer->their_prev_revocation_hash
|
||||
= tal_dup(peer, struct sha256,
|
||||
&peer->remote.commit->revocation_hash);
|
||||
|
||||
db_start_transaction(peer);
|
||||
|
||||
errmsg = changestates(peer, changes, ARRAY_SIZE(changes),
|
||||
feechanges, ARRAY_SIZE(feechanges), true);
|
||||
if (errmsg) {
|
||||
log_broken(peer->log, "queue_pkt_commit: %s", errmsg);
|
||||
goto database_error;
|
||||
}
|
||||
|
||||
/* Create new commit info for this commit tx. */
|
||||
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, &ci->revocation_hash,
|
||||
ci->cstate, REMOTE, &to_us_only);
|
||||
bitcoin_txid(ci->tx, &ci->txid);
|
||||
|
||||
if (!to_us_only) {
|
||||
log_debug(peer->log, "Signing tx %"PRIu64, ci->commit_num);
|
||||
log_add_struct(peer->log, " for %s",
|
||||
struct channel_state, ci->cstate);
|
||||
log_add_struct(peer->log, " (txid %s)",
|
||||
struct sha256_double, &ci->txid);
|
||||
|
||||
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. */
|
||||
tal_free(peer->remote.commit);
|
||||
peer->remote.commit = ci;
|
||||
peer->remote.commit->order = peer->order_counter++;
|
||||
db_new_commit_info(peer, REMOTE, peer->their_prev_revocation_hash);
|
||||
|
||||
/* We don't need to remember their commit if we don't give sig. */
|
||||
if (ci->sig)
|
||||
peer_add_their_commit(peer, &ci->txid, ci->commit_num);
|
||||
|
||||
if (peer->state == STATE_SHUTDOWN) {
|
||||
set_peer_state(peer, STATE_SHUTDOWN_COMMITTING, __func__, true);
|
||||
} else {
|
||||
assert(peer->state == STATE_NORMAL);
|
||||
set_peer_state(peer, STATE_NORMAL_COMMITTING, __func__, true);
|
||||
}
|
||||
if (db_commit_transaction(peer) != NULL)
|
||||
goto database_error;
|
||||
|
||||
queue_pkt_commit(peer, ci->sig);
|
||||
return;
|
||||
|
||||
database_error:
|
||||
db_abort_transaction(peer);
|
||||
peer_fail(peer, __func__);
|
||||
}
|
||||
|
||||
static void try_commit(struct peer *peer)
|
||||
{
|
||||
peer->commit_timer = NULL;
|
||||
|
||||
Reference in New Issue
Block a user