queryrates: make it dev-only

Since we now use 'compact_lease' to gate an open (if the rates have
changed, we fail), we no longer need to rely on query rates for figuring
things out, so we make it dev-only.

Changelog-Changed: JSON-API: queryrates is now developer only
This commit is contained in:
niftynei 2021-07-06 13:48:35 -05:00 committed by neil saitug
parent b067820dd8
commit 77d2c538b3
4 changed files with 118 additions and 110 deletions

View file

@ -109,7 +109,7 @@ start_nodes() {
# Start the lightning nodes
test -f "/tmp/l$i-$network/lightningd-$network.pid" || \
"$LIGHTNINGD" "--lightning-dir=/tmp/l$i-$network" --daemon
"$LIGHTNINGD" "--lightning-dir=/tmp/l$i-$network" &
# shellcheck disable=SC2139 disable=SC2086
alias l$i-cli="$LCLI --lightning-dir=/tmp/l$i-$network"
# shellcheck disable=SC2139 disable=SC2086

View file

@ -2509,106 +2509,6 @@ static struct command_result *init_set_feerate(struct command *cmd,
return NULL;
}
static struct command_result *json_queryrates(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
{
struct node_id *id;
struct peer *peer;
struct channel *channel;
u32 *feerate_per_kw_funding;
u32 *feerate_per_kw;
struct amount_sat *amount, *request_amt;
struct wally_psbt *psbt;
struct open_attempt *oa;
u8 *msg;
struct command_result *res;
if (!param(cmd, buffer, params,
p_req("id", param_node_id, &id),
p_req("amount", param_sat, &amount),
p_req("request_amt", param_sat, &request_amt),
p_opt("commitment_feerate", param_feerate, &feerate_per_kw),
p_opt("funding_feerate", param_feerate, &feerate_per_kw_funding),
NULL))
return command_param_failed();
res = init_set_feerate(cmd, &feerate_per_kw, &feerate_per_kw_funding);
if (res)
return res;
peer = peer_by_id(cmd->ld, id);
if (!peer) {
return command_fail(cmd, FUNDING_UNKNOWN_PEER, "Unknown peer");
}
/* We can't query rates for a peer we have a channel with */
channel = peer_active_channel(peer);
if (channel)
return command_fail(cmd, LIGHTNINGD, "Peer in state %s,"
" can't query peer's rates if already"
" have a channel",
channel_state_name(channel));
channel = peer_unsaved_channel(peer);
if (!channel || !channel->owner)
return command_fail(cmd, FUNDING_PEER_NOT_CONNECTED,
"Peer not connected");
if (channel->open_attempt
|| !list_empty(&channel->inflights))
return command_fail(cmd, FUNDING_STATE_INVALID,
"Channel funding in-progress. %s",
channel_state_name(channel));
if (!feature_negotiated(cmd->ld->our_features,
peer->their_features,
OPT_DUAL_FUND)) {
return command_fail(cmd, FUNDING_V2_NOT_SUPPORTED,
"v2 openchannel not supported "
"by peer, can't query rates");
}
/* BOLT #2:
* - if both nodes advertised `option_support_large_channel`:
* - MAY set `funding_satoshis` greater than or equal to 2^24 satoshi.
* - otherwise:
* - MUST set `funding_satoshis` to less than 2^24 satoshi.
*/
if (!feature_negotiated(cmd->ld->our_features,
peer->their_features, OPT_LARGE_CHANNELS)
&& amount_sat_greater(*amount, chainparams->max_funding))
return command_fail(cmd, FUND_MAX_EXCEEDED,
"Amount exceeded %s",
type_to_string(tmpctx, struct amount_sat,
&chainparams->max_funding));
/* Get a new open_attempt going, keeps us from re-initing
* while looking */
channel->opener = LOCAL;
channel->open_attempt = oa = new_channel_open_attempt(channel);
channel->channel_flags = OUR_CHANNEL_FLAGS;
oa->funding = *amount;
oa->cmd = cmd;
/* empty psbt to start */
psbt = create_psbt(tmpctx, 0, 0, 0);
msg = towire_dualopend_opener_init(NULL,
psbt, *amount,
oa->our_upfront_shutdown_script,
*feerate_per_kw,
*feerate_per_kw_funding,
channel->channel_flags,
*request_amt,
get_block_height(cmd->ld->topology),
true,
NULL);
subd_send_msg(channel->owner, take(msg));
return command_still_pending(cmd);
}
static struct command_result *json_openchannel_init(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
@ -3135,14 +3035,118 @@ static unsigned int dual_opend_msg(struct subd *dualopend,
return 0;
}
#if DEVELOPER
static struct command_result *json_queryrates(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
{
struct node_id *id;
struct peer *peer;
struct channel *channel;
u32 *feerate_per_kw_funding;
u32 *feerate_per_kw;
struct amount_sat *amount, *request_amt;
struct wally_psbt *psbt;
struct open_attempt *oa;
u8 *msg;
struct command_result *res;
if (!param(cmd, buffer, params,
p_req("id", param_node_id, &id),
p_req("amount", param_sat, &amount),
p_req("request_amt", param_sat, &request_amt),
p_opt("commitment_feerate", param_feerate, &feerate_per_kw),
p_opt("funding_feerate", param_feerate, &feerate_per_kw_funding),
NULL))
return command_param_failed();
res = init_set_feerate(cmd, &feerate_per_kw, &feerate_per_kw_funding);
if (res)
return res;
peer = peer_by_id(cmd->ld, id);
if (!peer) {
return command_fail(cmd, FUNDING_UNKNOWN_PEER, "Unknown peer");
}
/* We can't query rates for a peer we have a channel with */
channel = peer_active_channel(peer);
if (channel)
return command_fail(cmd, LIGHTNINGD, "Peer in state %s,"
" can't query peer's rates if already"
" have a channel",
channel_state_name(channel));
channel = peer_unsaved_channel(peer);
if (!channel || !channel->owner)
return command_fail(cmd, FUNDING_PEER_NOT_CONNECTED,
"Peer not connected");
if (channel->open_attempt
|| !list_empty(&channel->inflights))
return command_fail(cmd, FUNDING_STATE_INVALID,
"Channel funding in-progress. %s",
channel_state_name(channel));
if (!feature_negotiated(cmd->ld->our_features,
peer->their_features,
OPT_DUAL_FUND)) {
return command_fail(cmd, FUNDING_V2_NOT_SUPPORTED,
"v2 openchannel not supported "
"by peer, can't query rates");
}
/* BOLT #2:
* - if both nodes advertised `option_support_large_channel`:
* - MAY set `funding_satoshis` greater than or equal to 2^24 satoshi.
* - otherwise:
* - MUST set `funding_satoshis` to less than 2^24 satoshi.
*/
if (!feature_negotiated(cmd->ld->our_features,
peer->their_features, OPT_LARGE_CHANNELS)
&& amount_sat_greater(*amount, chainparams->max_funding))
return command_fail(cmd, FUND_MAX_EXCEEDED,
"Amount exceeded %s",
type_to_string(tmpctx, struct amount_sat,
&chainparams->max_funding));
/* Get a new open_attempt going, keeps us from re-initing
* while looking */
channel->opener = LOCAL;
channel->open_attempt = oa = new_channel_open_attempt(channel);
channel->channel_flags = OUR_CHANNEL_FLAGS;
oa->funding = *amount;
oa->cmd = cmd;
/* empty psbt to start */
psbt = create_psbt(tmpctx, 0, 0, 0);
msg = towire_dualopend_opener_init(NULL,
psbt, *amount,
oa->our_upfront_shutdown_script,
*feerate_per_kw,
*feerate_per_kw_funding,
channel->channel_flags,
*request_amt,
get_block_height(cmd->ld->topology),
true,
NULL);
subd_send_msg(channel->owner, take(msg));
return command_still_pending(cmd);
}
static const struct json_command queryrates_command = {
"queryrates",
"dev-queryrates",
"channels",
json_queryrates,
"Ask a peer what their contribution and liquidity rates are"
" for the given {amount} and {requested_amt}"
};
AUTODATA(json_command, &queryrates_command);
#endif /* DEVELOPER */
static const struct json_command openchannel_init_command = {
"openchannel_init",
"channels",
@ -3181,7 +3185,6 @@ static const struct json_command openchannel_abort_command = {
"Abort {channel_id}'s open. Usable while `commitment_signed=false`."
};
AUTODATA(json_command, &queryrates_command);
AUTODATA(json_command, &openchannel_init_command);
AUTODATA(json_command, &openchannel_update_command);
AUTODATA(json_command, &openchannel_signed_command);

View file

@ -729,6 +729,7 @@ def calc_lease_fee(amt, feerate, rates):
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
@pytest.mark.openchannel('v2')
@pytest.mark.slow_test
@pytest.mark.developer("requres 'dev-queryrates'")
def test_channel_lease_falls_behind(node_factory, bitcoind):
'''
If our peer falls too far behind/doesn't send us an update for
@ -745,7 +746,7 @@ def test_channel_lease_falls_behind(node_factory, bitcoind):
l2.fundwallet(20000000)
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
rates = l1.rpc.queryrates(l2.info['id'], amount, amount)
rates = l1.rpc.dev_queryrates(l2.info['id'], amount, amount)
l1.daemon.wait_for_log('disconnect')
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
# l1 leases a channel from l2
@ -768,6 +769,7 @@ def test_channel_lease_falls_behind(node_factory, bitcoind):
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
@pytest.mark.openchannel('v2')
@pytest.mark.developer("requres 'dev-queryrates'")
@pytest.mark.slow_test
def test_channel_lease_post_expiry(node_factory, bitcoind):
@ -868,7 +870,7 @@ def test_channel_lease_unilat_closes(node_factory, bitcoind):
l3.fundwallet(20000000)
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
rates = l1.rpc.queryrates(l2.info['id'], amount, amount)
rates = l1.rpc.dev_queryrates(l2.info['id'], amount, amount)
l1.daemon.wait_for_log('disconnect')
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
# l1 leases a channel from l2
@ -878,7 +880,7 @@ def test_channel_lease_unilat_closes(node_factory, bitcoind):
# l2 leases a channel from l3
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
rates = l2.rpc.queryrates(l3.info['id'], amount, amount)
rates = l2.rpc.dev_queryrates(l3.info['id'], amount, amount)
l3.daemon.wait_for_log('disconnect')
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
l2.rpc.fundchannel(l3.info['id'], amount, request_amt=amount,
@ -949,6 +951,7 @@ def test_channel_lease_unilat_closes(node_factory, bitcoind):
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
@pytest.mark.openchannel('v2')
@unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "Makes use of the sqlite3 db")
@pytest.mark.developer("requres 'dev-queryrates'")
def test_channel_lease_lessor_cheat(node_factory, bitcoind, chainparams):
'''
Check that lessee can recover funds if lessor cheats
@ -966,7 +969,7 @@ def test_channel_lease_lessor_cheat(node_factory, bitcoind, chainparams):
l2.fundwallet(20000000)
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
rates = l1.rpc.queryrates(l2.info['id'], amount, amount)
rates = l1.rpc.dev_queryrates(l2.info['id'], amount, amount)
l1.daemon.wait_for_log('disconnect')
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
# l1 leases a channel from l2
@ -1021,6 +1024,7 @@ def test_channel_lease_lessor_cheat(node_factory, bitcoind, chainparams):
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
@pytest.mark.openchannel('v2')
@unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "Makes use of the sqlite3 db")
@pytest.mark.developer("requres 'dev-queryrates'")
def test_channel_lease_lessee_cheat(node_factory, bitcoind, chainparams):
'''
Check that lessor can recover funds if lessee cheats
@ -1038,7 +1042,7 @@ def test_channel_lease_lessee_cheat(node_factory, bitcoind, chainparams):
l2.fundwallet(20000000)
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
rates = l1.rpc.queryrates(l2.info['id'], amount, amount)
rates = l1.rpc.dev_queryrates(l2.info['id'], amount, amount)
l1.daemon.wait_for_log('disconnect')
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
# l1 leases a channel from l2

View file

@ -17,6 +17,7 @@ def find_next_feerate(node, peer):
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
@pytest.mark.openchannel('v2')
@pytest.mark.developer("requres 'dev-queryrates'")
def test_queryrates(node_factory, bitcoind):
l1, l2 = node_factory.get_nodes(2)
@ -27,7 +28,7 @@ def test_queryrates(node_factory, bitcoind):
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
with pytest.raises(RpcError, match=r'not advertising liquidity'):
l1.rpc.queryrates(l2.info['id'], amount, amount * 10)
l1.rpc.dev_queryrates(l2.info['id'], amount, amount * 10)
l2.rpc.call('funderupdate', {'policy': 'match',
'policy_mod': 100,
@ -40,7 +41,7 @@ def test_queryrates(node_factory, bitcoind):
'channel_fee_max_proportional_thousandths': 101})
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
result = l1.rpc.queryrates(l2.info['id'], amount, amount)
result = l1.rpc.dev_queryrates(l2.info['id'], amount, amount)
assert result['our_funding_msat'] == Millisatoshi(amount * 1000)
assert result['their_funding_msat'] == Millisatoshi(amount * 1000)
assert result['funding_weight'] == 1000