mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-01 17:47:30 +01:00
lightningd: track balance in way which matches channeld.
Currently it's fairly ad-hoc, but we need to tell it to channeld when it restarts, so we define it as the non-HTLC balance. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
f918c3a0e7
commit
a55b58d0d5
4 changed files with 63 additions and 20 deletions
|
@ -587,11 +587,11 @@ static void json_getpeers(struct command *cmd,
|
|||
if (p->scid)
|
||||
json_add_short_channel_id(response, "channel", p->scid);
|
||||
if (p->balance) {
|
||||
json_add_u64(response, "msatoshi_to_us",
|
||||
p->balance[LOCAL]);
|
||||
json_add_u64(response, "msatoshi_to_them",
|
||||
p->balance[REMOTE]);
|
||||
json_add_u64(response, "msatoshi_to_us", *p->balance);
|
||||
json_add_u64(response, "msatoshi_total",
|
||||
p->funding_satoshi * 1000);
|
||||
}
|
||||
|
||||
if (leveltok) {
|
||||
info.response = response;
|
||||
json_array_start(response, "log");
|
||||
|
@ -982,9 +982,11 @@ static void peer_start_channeld(struct peer *peer, enum peer_state oldstate,
|
|||
log_debug(peer->log, "Waiting for HSM file descriptor");
|
||||
|
||||
/* Now we can consider balance set. */
|
||||
peer->balance = tal_arr(peer, u64, NUM_SIDES);
|
||||
peer->balance[peer->funder] = peer->funding_satoshi * 1000 - peer->push_msat;
|
||||
peer->balance[!peer->funder] = peer->push_msat;
|
||||
peer->balance = tal(peer, u64);
|
||||
if (peer->funder == LOCAL)
|
||||
*peer->balance = peer->funding_satoshi * 1000 - peer->push_msat;
|
||||
else
|
||||
*peer->balance = peer->push_msat;
|
||||
|
||||
peer_set_condition(peer, oldstate, GETTING_HSMFD);
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ struct peer {
|
|||
u16 funding_outnum;
|
||||
u64 funding_satoshi, push_msat;
|
||||
|
||||
/* Channel balance (LOCAL and REMOTE); if we have one. */
|
||||
/* Amount going to us, not counting unfinished HTLCs; if we have one. */
|
||||
u64 *balance;
|
||||
|
||||
/* Keys for channel. */
|
||||
|
|
|
@ -175,8 +175,8 @@ static void fulfill_htlc(struct htlc_in *hin, const struct preimage *preimage)
|
|||
{
|
||||
u8 *msg;
|
||||
|
||||
hin->key.peer->balance[LOCAL] += hin->msatoshi;
|
||||
hin->key.peer->balance[REMOTE] -= hin->msatoshi;
|
||||
hin->preimage = tal_dup(hin, struct preimage, preimage);
|
||||
htlc_in_check(hin, __func__);
|
||||
|
||||
/* FIXME: fail the peer if it doesn't tell us that htlc fulfill is
|
||||
* committed before deadline.
|
||||
|
@ -628,10 +628,6 @@ static bool peer_fulfilled_our_htlc(struct peer *peer,
|
|||
|
||||
/* FIXME: Save to db */
|
||||
|
||||
/* They fulfilled our HTLC. Credit them, forward immediately. */
|
||||
peer->balance[REMOTE] += hout->msatoshi;
|
||||
peer->balance[LOCAL] -= hout->msatoshi;
|
||||
|
||||
if (hout->in)
|
||||
fulfill_htlc(hout->in, &fulfilled->payment_preimage);
|
||||
else
|
||||
|
@ -665,16 +661,30 @@ static bool peer_failed_our_htlc(struct peer *peer,
|
|||
static void remove_htlc_in(struct peer *peer, struct htlc_in *hin)
|
||||
{
|
||||
htlc_in_check(hin, __func__);
|
||||
log_debug(peer->log, "Removing in HTLC %"PRIu64" state %s",
|
||||
hin->key.id, htlc_state_name(hin->hstate));
|
||||
assert(hin->failuremsg || hin->preimage);
|
||||
|
||||
log_debug(peer->log, "Removing in HTLC %"PRIu64" state %s %s",
|
||||
hin->key.id, htlc_state_name(hin->hstate),
|
||||
hin->failuremsg ? "FAILED" : "FULFILLED");
|
||||
|
||||
/* If we fulfilled their HTLC, credit us. */
|
||||
if (hin->preimage) {
|
||||
log_debug(peer->log, "Balance %"PRIu64" -> %"PRIu64,
|
||||
*peer->balance,
|
||||
*peer->balance + hin->msatoshi);
|
||||
*peer->balance += hin->msatoshi;
|
||||
}
|
||||
|
||||
tal_free(hin);
|
||||
}
|
||||
|
||||
static void remove_htlc_out(struct peer *peer, struct htlc_out *hout)
|
||||
{
|
||||
htlc_out_check(hout, __func__);
|
||||
log_debug(peer->log, "Removing out HTLC %"PRIu64" state %s",
|
||||
hout->key.id, htlc_state_name(hout->hstate));
|
||||
assert(hout->failuremsg || hout->preimage);
|
||||
log_debug(peer->log, "Removing out HTLC %"PRIu64" state %s %s",
|
||||
hout->key.id, htlc_state_name(hout->hstate),
|
||||
hout->failuremsg ? "FAILED" : "FULFILLED");
|
||||
|
||||
/* If it's failed, now we can forward since it's completely locked-in */
|
||||
if (hout->failuremsg) {
|
||||
|
@ -687,6 +697,9 @@ static void remove_htlc_out(struct peer *peer, struct htlc_out *hout)
|
|||
} else {
|
||||
payment_failed(peer->ld, hout);
|
||||
}
|
||||
} else {
|
||||
/* We paid for this HTLC, so deduct balance. */
|
||||
*peer->balance -= hout->msatoshi;
|
||||
}
|
||||
|
||||
tal_free(hout);
|
||||
|
|
|
@ -204,6 +204,18 @@ class LightningDTests(BaseLightningDTests):
|
|||
assert p1['owner'] == 'lightningd_gossip'
|
||||
assert p2['owner'] == 'lightningd_gossip'
|
||||
|
||||
def test_balance(self):
|
||||
l1,l2 = self.connect()
|
||||
|
||||
self.fund_channel(l1, l2, 10**6)
|
||||
|
||||
p1 = l1.rpc.getpeer(l2.info['id'], 'info')
|
||||
p2 = l2.rpc.getpeer(l1.info['id'], 'info')
|
||||
assert p1['msatoshi_to_us'] == 10**6 * 1000
|
||||
assert p1['msatoshi_total'] == 10**6 * 1000
|
||||
assert p2['msatoshi_to_us'] == 0
|
||||
assert p2['msatoshi_total'] == 10**6 * 1000
|
||||
|
||||
def test_sendpay(self):
|
||||
l1,l2 = self.connect()
|
||||
|
||||
|
@ -246,10 +258,27 @@ class LightningDTests(BaseLightningDTests):
|
|||
self.assertRaises(ValueError, l1.rpc.sendpay, to_json([rs]), rhash)
|
||||
assert l2.rpc.listinvoice('testpayment2')[0]['complete'] == False
|
||||
|
||||
# FIXME: test paying via another node, should fail to pay twice.
|
||||
p1 = l1.rpc.getpeer(l2.info['id'], 'info')
|
||||
p2 = l2.rpc.getpeer(l1.info['id'], 'info')
|
||||
assert p1['msatoshi_to_us'] == 10**6 * 1000
|
||||
assert p1['msatoshi_total'] == 10**6 * 1000
|
||||
assert p2['msatoshi_to_us'] == 0
|
||||
assert p2['msatoshi_total'] == 10**6 * 1000
|
||||
|
||||
# This works.
|
||||
l1.rpc.sendpay(to_json([routestep]), rhash)
|
||||
assert l2.rpc.listinvoice('testpayment2')[0]['complete'] == True
|
||||
|
||||
|
||||
# Balances should reflect it.
|
||||
time.sleep(1)
|
||||
p1 = l1.rpc.getpeer(l2.info['id'], 'info')
|
||||
p2 = l2.rpc.getpeer(l1.info['id'], 'info')
|
||||
assert p1['msatoshi_to_us'] == 10**6 * 1000 - amt
|
||||
assert p1['msatoshi_total'] == 10**6 * 1000
|
||||
assert p2['msatoshi_to_us'] == amt
|
||||
assert p2['msatoshi_total'] == 10**6 * 1000
|
||||
|
||||
# Repeat will "succeed", but won't actually send anything (duplicate)
|
||||
assert not l1.daemon.is_in_log('... succeeded')
|
||||
l1.rpc.sendpay(to_json([routestep]), rhash)
|
||||
|
@ -263,7 +292,6 @@ class LightningDTests(BaseLightningDTests):
|
|||
l1.rpc.sendpay(to_json([routestep]), rhash)
|
||||
assert l2.rpc.listinvoice('testpayment3')[0]['complete'] == True
|
||||
|
||||
# FIXME: test paying via another node, should fail to pay twice.
|
||||
|
||||
def test_gossip_jsonrpc(self):
|
||||
l1,l2 = self.connect()
|
||||
|
|
Loading…
Add table
Reference in a new issue