When sending an HTTP request to DELETE /v1/channels/{channel_point.funding_txid_str}/{channel_point.output_index}, the response hangs until the next block is mined. When the response is returned it contains two JSON objects instead of a single one.
{"result":{"close_pending":{"txid":"3F8yolDdkh8OEVmdnK8lHlQaNG7a+qtHbw3WLHITGeU="}}}
{"result":{"chan_close":{"closing_txid":"3F8yolDdkh8OEVmdnK8lHlQaNG7a+qtHbw3WLHITGeU="}}}
i skimmed through the rpc.proto file and noticed that the SendPayment and OpenChannel have *Sync versions for the REST proxy but CloseChannel does not. It returns a stream instead of a response object, which I believe may be the reason why it hangs until the async operation completes.
There is also no way to pass in the --force parameter via the REST API. Currently the two parameters for funding_txid and output_index are supplied in the URL. The endpoint does not have a way to provide the additional options, such as force, time_limit, block, conf_target, sat_per_byte.
lnd: tested 0.5.2-beta and master branch as of 2a65245uname -a on *Nix): Ubuntu 16.04.5 LTS and Windows 10 Pro 1803btcd, bitcoind, or other backend: btcd version 0.12.0-beta (using --simnet)Try to close a channel via the REST API using Postman or curl
curl -X DELETE \
https://localhost:8001/v1/channels/1c1cc3d7fb9c5a94628186a376d0c832dced9951968733db745c66aa9ba4cd2d/1 \
-H 'Content-Type: application/json' \
-H 'grpc-metadata-macaroon: 0201036c6e6402cf01030a10cd26e692e9db0389751f18280815c0b71201301a160a0761646472657373120472656164120577726974651a130a04696e666f120472656164120577726974651a170a08696e766f69636573120472656164120577726974651a160a076d657373616765120472656164120577726974651a170a086f6666636861696e120472656164120577726974651a160a076f6e636861696e120472656164120577726974651a140a057065657273120472656164120577726974651a120a067369676e6572120867656e657261746500000620c1dab9cfeacb111ece9e9e49d98bc552ceec7dd4bacbde42f875ba2eb3e0bc4b'
Here's a screen cap of the issue in action on simnet
https://imgur.com/a/kGc3mzy
The HTTP response should return synchronously with the closing_txid
The HTTP response hangs until the next block is mined, which will be in minutes on mainnet/testnet
i skimmed through the rpc.proto file and noticed that the SendPayment and OpenChannel have *Sync versions for the REST proxy but CloseChannel does not. It returns a stream instead of a response object, which I believe may be the reason why it hangs until the async operation completes.
This is the problem indeed.
There is also no way to pass in the --force parameter via the REST API. Currently the two parameters for funding_txid and output_index are supplied in the URL. The endpoint does not have a way to provide the additional options, such as force, time_limit, block, conf_target, sat_per_byte.
You should be able to pass these in the URL itself, e.g. https://localhost:8001/v1/channels/1c1cc3d7fb9c5a94628186a376d0c832dced9951968733db745c66aa9ba4cd2d/1?force=true&sat_per_byte=1
{channel_point.funding_txid_str}/{channel_point.output_index}
where can i get these parameters. I got only channel point. Where can i get funding_txid_str and output_index
@infiniteannant the funding_txid_str and output_index are combined to create the channel point, separated by a colon. So given the following channel point returned from lncli listchannels:
{
...
"channel_point": "1c1cc3d7fb9c5a94628186a376d0c832dced9951968733db745c66aa9ba4cd2d:1"
...
}
funding_id_str = 1c1cc3d7fb9c5a94628186a376d0c832dced9951968733db745c66aa9ba4cd2d
output_index = 1
Hey @Roasbeef, I know this is a pretty old issue. Is the problem fixed or are you closing because it will not be fixed in the future?
something something websockets?
So it seems websockets are the only way to close a channel nicely with the rest API?
Yes. There is no "sync" variant of this RPC at the moment.
If anyone wants some example websocket code for this:
async def closeChannelStream():
channel_point = ""
output_index = 0
force = False
fee_rate = 3
url = f'/v1/channels/{channel_point}/{output_index}?force={force}&sat_per_byte={fee_rate}'
ws = await websockets.connect(f"wss://192.168.1.123:8080{url}&method=DELETE", ping_timeout=None, ping_interval=1, ssl=ssl_context, extra_headers=headers, max_size=1000000000)
close_data = {}
await ws.send(json.dumps({}).encode('UTF-8'))
hi = await ws.recv()
print(hi)
async for message in ws:
print('receiving')
try:
hi = await asyncio.wait_for(ws.recv(), timeout=5)
hi = json.loads(hi)
# hi = hi['result']
pprint(hi)
except asyncio.TimeoutError:
print('timeout!')
except asyncio.CancelledError:
print("cancelled?")
Most helpful comment
This is the problem indeed.
You should be able to pass these in the URL itself, e.g.
https://localhost:8001/v1/channels/1c1cc3d7fb9c5a94628186a376d0c832dced9951968733db745c66aa9ba4cd2d/1?force=true&sat_per_byte=1