Browse Source

daemon: reorder and collapse functions.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 9 years ago
parent
commit
773a6088e4
  1. 259
      daemon/peer.c

259
daemon/peer.c

@ -78,11 +78,18 @@ static struct json_result *null_response(const tal_t *ctx)
return response;
}
/* FIXME: reorder to avoid predecls. */
static bool peer_uncommitted_changes(const struct peer *peer);
static void state_event(struct peer *peer,
const enum state_input input,
const union input *idata);
static bool peer_uncommitted_changes(const struct peer *peer)
{
/* Not initialized yet? */
if (!peer->remote.staging_cstate
|| !peer->remote.commit
|| !peer->remote.commit->cstate)
return false;
/* We could have proposed changes to their commit */
return peer->remote.staging_cstate->changes
!= peer->remote.commit->cstate->changes;
}
void peer_update_complete(struct peer *peer, const char *problem)
{
@ -124,87 +131,6 @@ static void set_peer_state(struct peer *peer, enum state newstate,
peer->state = newstate;
}
/* FIXME: Flatten into do_commit. */
static void command_send_commit(struct peer *peer, struct command *jsoncmd)
{
assert(state_can_commit(peer->state));
assert(!peer->commit_jsoncmd);
peer->commit_jsoncmd = jsoncmd;
if (peer->state == STATE_CLEARING) {
queue_pkt_commit(peer);
set_peer_state(peer, STATE_CLEARING_COMMITTING, __func__);
} else {
/* You can send commands if closing; peer->cond == CLOSING */
assert(peer->state == STATE_NORMAL);
state_event(peer, CMD_SEND_COMMIT, NULL);
}
}
static bool command_htlc_fail(struct peer *peer, u64 id, struct command *jsoncmd)
{
if (!state_can_remove_htlc(peer->state)) {
if (jsoncmd)
command_fail(jsoncmd,
"htlc_fail not possible in state %s",
state_name(peer->state));
return false;
}
if (peer->state == STATE_CLEARING) {
queue_pkt_htlc_fail(peer, id);
} else {
union input idata;
struct htlc_progress prog;
prog.stage.fail.fail = HTLC_FAIL;
prog.stage.fail.id = id;
/* FIXME: get rid of htlc_progress, just use htlc_staging. */
idata.htlc_prog = &prog;
state_event(peer, CMD_SEND_HTLC_FAIL, &idata);
}
if (jsoncmd)
command_success(jsoncmd, null_response(jsoncmd));
return true;
}
/* FIXME: Flatten into json_fulfillhtlc. */
static bool command_htlc_fulfill(struct peer *peer,
u64 id,
const struct sha256 *r,
struct command *jsoncmd)
{
if (!state_can_remove_htlc(peer->state)) {
if (jsoncmd)
command_fail(jsoncmd,
"htlc_fulfill not possible in state %s",
state_name(peer->state));
return false;
}
/* Commands should still be blocked during this! */
assert(peer->state != STATE_CLEARING_COMMITTING);
if (peer->state == STATE_CLEARING) {
queue_pkt_htlc_fulfill(peer, id, r);
} else {
union input idata;
struct htlc_progress prog;
prog.stage.fulfill.fulfill = HTLC_FULFILL;
prog.stage.fulfill.r = *r;
prog.stage.fulfill.id = id;
/* FIXME: get rid of htlc_progress, just use htlc_staging. */
idata.htlc_prog = &prog;
state_event(peer, CMD_SEND_HTLC_FULFILL, &idata);
}
if (jsoncmd)
command_success(jsoncmd, null_response(jsoncmd));
return true;
}
static void peer_breakdown(struct peer *peer)
{
/* If we have a closing tx, use it. */
@ -224,19 +150,6 @@ static void peer_breakdown(struct peer *peer)
}
}
static bool peer_uncommitted_changes(const struct peer *peer)
{
/* Not initialized yet? */
if (!peer->remote.staging_cstate
|| !peer->remote.commit
|| !peer->remote.commit->cstate)
return false;
/* We could have proposed changes to their commit */
return peer->remote.staging_cstate->changes
!= peer->remote.commit->cstate->changes;
}
/* All unrevoked commit txs must have no HTLCs in them. */
static bool committed_to_htlcs(const struct peer *peer)
{
@ -575,6 +488,52 @@ static void state_event(struct peer *peer,
}
}
static bool command_htlc_fail(struct peer *peer, u64 id)
{
if (!state_can_remove_htlc(peer->state))
return false;
if (peer->state == STATE_CLEARING) {
queue_pkt_htlc_fail(peer, id);
} else {
union input idata;
struct htlc_progress prog;
prog.stage.fail.fail = HTLC_FAIL;
prog.stage.fail.id = id;
/* FIXME: get rid of htlc_progress, just use htlc_staging. */
idata.htlc_prog = &prog;
state_event(peer, CMD_SEND_HTLC_FAIL, &idata);
}
return true;
}
static bool command_htlc_fulfill(struct peer *peer,
u64 id,
const struct sha256 *r)
{
if (!state_can_remove_htlc(peer->state))
return false;
/* Commands should still be blocked during this! */
assert(peer->state != STATE_CLEARING_COMMITTING);
if (peer->state == STATE_CLEARING) {
queue_pkt_htlc_fulfill(peer, id, r);
} else {
union input idata;
struct htlc_progress prog;
prog.stage.fulfill.fulfill = HTLC_FULFILL;
prog.stage.fulfill.r = *r;
prog.stage.fulfill.id = id;
/* FIXME: get rid of htlc_progress, just use htlc_staging. */
idata.htlc_prog = &prog;
state_event(peer, CMD_SEND_HTLC_FULFILL, &idata);
}
return true;
}
static struct io_plan *pkt_out(struct io_conn *conn, struct peer *peer)
{
Pkt *out;
@ -675,16 +634,24 @@ static void peer_disconnect(struct io_conn *conn, struct peer *peer)
static void do_commit(struct peer *peer, struct command *jsoncmd)
{
/* We can have changes we suggested, or changes they suggested. */
if (peer_uncommitted_changes(peer)) {
log_debug(peer->log, "do_commit: sending commit command");
command_send_commit(peer, jsoncmd);
return;
if (!peer_uncommitted_changes(peer)) {
log_debug(peer->log, "do_commit: no changes to commit");
if (jsoncmd)
command_fail(jsoncmd, "no changes to commit");
}
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");
assert(state_can_commit(peer->state));
assert(!peer->commit_jsoncmd);
peer->commit_jsoncmd = jsoncmd;
if (peer->state == STATE_CLEARING) {
queue_pkt_commit(peer);
set_peer_state(peer, STATE_CLEARING_COMMITTING, __func__);
} else {
assert(peer->state == STATE_NORMAL);
state_event(peer, CMD_SEND_COMMIT, NULL);
}
}
@ -2328,7 +2295,7 @@ static void check_htlc_expiry(struct peer *peer)
continue;
/* This can fail only if we're in an error state. */
command_htlc_fail(peer, htlc->id, NULL);
command_htlc_fail(peer, htlc->id);
return;
}
}
@ -2506,32 +2473,15 @@ static size_t find_their_committed_htlc(struct peer *peer,
return funding_find_htlc(peer->remote.staging_cstate, rhash, THEIRS);
}
static void do_fullfill(struct peer *peer,
const struct sha256 *r,
struct command *jsoncmd)
{
struct sha256 rhash;
size_t i;
u64 id;
sha256(&rhash, r, sizeof(*r));
i = find_their_committed_htlc(peer, &rhash);
if (i == -1) {
command_fail(jsoncmd, "preimage htlc not found");
return;
}
id = peer->remote.staging_cstate->side[THEIRS].htlcs[i].id;
command_htlc_fulfill(peer, id, r, jsoncmd);
}
static void json_fulfillhtlc(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
struct peer *peer;
jsmntok_t *peeridtok, *rtok;
struct sha256 r;
struct sha256 rhash;
size_t i;
u64 id;
if (!json_get_params(buffer, params,
"peerid", &peeridtok,
@ -2560,7 +2510,22 @@ static void json_fulfillhtlc(struct command *cmd,
buffer + rtok->start);
return;
}
do_fullfill(peer, &r, cmd);
sha256(&rhash, &r, sizeof(r));
i = find_their_committed_htlc(peer, &rhash);
if (i == -1) {
command_fail(cmd, "preimage htlc not found");
return;
}
id = peer->remote.staging_cstate->side[THEIRS].htlcs[i].id;
if (command_htlc_fulfill(peer, id, &r))
command_success(cmd, null_response(cmd));
else
command_fail(cmd,
"htlc_fulfill not possible in state %s",
state_name(peer->state));
}
const struct json_command fulfillhtlc_command = {
@ -2570,31 +2535,14 @@ const struct json_command fulfillhtlc_command = {
"Returns an empty result on success"
};
/* FIXME: Flatten into json_failhtlc. */
static void do_failhtlc(struct peer *peer,
const struct sha256 *rhash,
struct command *jsoncmd)
{
size_t i;
u64 id;
/* Look in peer->remote.staging_cstate->a, as that's where we'll
* immediately remove it from: avoids double-handling. */
i = find_their_committed_htlc(peer, rhash);
if (i == -1) {
command_fail(jsoncmd, "htlc not found");
return;
}
id = peer->remote.staging_cstate->side[THEIRS].htlcs[i].id;
command_htlc_fail(peer, id, jsoncmd);
}
static void json_failhtlc(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
struct peer *peer;
jsmntok_t *peeridtok, *rhashtok;
struct sha256 rhash;
size_t i;
u64 id;
if (!json_get_params(buffer, params,
"peerid", &peeridtok,
@ -2624,7 +2572,20 @@ static void json_failhtlc(struct command *cmd,
return;
}
do_failhtlc(peer, &rhash, cmd);
/* Look in peer->remote.staging_cstate->a, as that's where we'll
* immediately remove it from: avoids double-handling. */
i = find_their_committed_htlc(peer, &rhash);
if (i == -1) {
command_fail(cmd, "htlc not found");
return;
}
id = peer->remote.staging_cstate->side[THEIRS].htlcs[i].id;
if (command_htlc_fail(peer, id))
command_success(cmd, null_response(cmd));
else
command_fail(cmd,
"htlc_fail not possible in state %s",
state_name(peer->state));
}
const struct json_command failhtlc_command = {

Loading…
Cancel
Save