Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions common/json.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,21 @@ bool json_to_u16(const char *buffer, const jsmntok_t *tok,
return true;
}

bool json_to_u32(const char *buffer, const jsmntok_t *tok,
uint32_t *num)
{
uint64_t u64;

if (!json_to_u64(buffer, tok, &u64))
return false;
*num = u64;

/* Just in case it doesn't fit. */
if (*num != u64)
return false;
return true;
}

bool json_to_int(const char *buffer, const jsmntok_t *tok, int *num)
{
char *end;
Expand Down
4 changes: 4 additions & 0 deletions common/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ bool json_to_number(const char *buffer, const jsmntok_t *tok,
bool json_to_u64(const char *buffer, const jsmntok_t *tok,
uint64_t *num);

/* Extract number from this (may be a string, or a number literal) */
bool json_to_u32(const char *buffer, const jsmntok_t *tok,
uint32_t *num);

/* Extract number from this (may be a string, or a number literal) */
bool json_to_u16(const char *buffer, const jsmntok_t *tok,
uint16_t *num);
Expand Down
10 changes: 10 additions & 0 deletions contrib/pyln-client/pyln/client/lightning.py
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,16 @@ def waitanyinvoice(self, lastpay_index=None):
}
return self.call("waitanyinvoice", payload)

def waitblockheight(self, blockheight, timeout=None):
"""
Wait for the blockchain to reach the specified block height.
"""
payload = {
"blockheight": blockheight,
"timeout": timeout
}
return self.call("waitblockheight", payload)

def waitinvoice(self, label):
"""
Wait for an incoming payment matching the invoice with {label}
Expand Down
1 change: 1 addition & 0 deletions doc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ MANPAGES := doc/lightning-cli.1 \
doc/lightning-txsend.7 \
doc/lightning-waitinvoice.7 \
doc/lightning-waitanyinvoice.7 \
doc/lightning-waitblockheight.7 \
doc/lightning-waitsendpay.7 \
doc/lightning-withdraw.7

Expand Down
3 changes: 2 additions & 1 deletion doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ c-lightning Documentation
:maxdepth: 1
:caption: Manpages

lightningd <lightningd.8.md>
lightningd-config <lightningd-config.5.md>
lightningd <lightningd.8.md>
lightning-autocleaninvoice <lightning-autocleaninvoice.7.md>
lightning-check <lightning-check.7.md>
lightning-checkmessage <lightning-checkmessage.7.md>
Expand Down Expand Up @@ -64,6 +64,7 @@ c-lightning Documentation
lightning-txprepare <lightning-txprepare.7.md>
lightning-txsend <lightning-txsend.7.md>
lightning-waitanyinvoice <lightning-waitanyinvoice.7.md>
lightning-waitblockheight <lightning-waitblockheight.7.md>
lightning-waitinvoice <lightning-waitinvoice.7.md>
lightning-waitsendpay <lightning-waitsendpay.7.md>
lightning-withdraw <lightning-withdraw.7.md>
36 changes: 36 additions & 0 deletions doc/lightning-waitblockheight.7

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions doc/lightning-waitblockheight.7.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
lightning-waitblockheight -- Command for waiting for blocks on the blockchain
=============================================================================

SYNOPSIS
--------

**waitblockheight** *blockheight* \[*timeout*\]

DESCRIPTION
-----------

The **waitblockheight** RPC command waits until the blockchain
has reached the specified *blockheight*.
It will only wait up to *timeout* seconds (default 60).

If the *blockheight* is a present or past block height, then this
command returns immediately.

RETURN VALUE
------------

Once the specified block height has been achieved by the blockchain,
an object with the single field *blockheight* is returned, which is
the block height at the time the command returns.

If *timeout* seconds is reached without the specified blockheight
being reached, this command will fail.

AUTHOR
------

ZmnSCPxj <<ZmnSCPxj@protonmail.com>> is mainly responsible.

RESOURCES
---------

Main web site: <https://github.com/ElementsProject/lightning>
2 changes: 2 additions & 0 deletions lightningd/lightningd.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
list_head_init(&ld->sendpay_commands);
list_head_init(&ld->close_commands);
list_head_init(&ld->ping_commands);
list_head_init(&ld->waitblockheight_commands);

/*~ Tal also explicitly supports arrays: it stores the number of
* elements, which can be accessed with tal_count() (or tal_bytelen()
Expand Down Expand Up @@ -597,6 +598,7 @@ void notify_new_block(struct lightningd *ld, u32 block_height)
htlcs_notify_new_block(ld, block_height);
channel_notify_new_block(ld, block_height);
gossip_notify_new_block(ld, block_height);
waitblockheight_notify_new_block(ld, block_height);
}

static void on_sigint(int _ UNUSED)
Expand Down
3 changes: 3 additions & 0 deletions lightningd/lightningd.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,9 @@ struct lightningd {
bool encrypted_hsm;

mode_t initial_umask;

/* Outstanding waitblockheight commands. */
struct list_head waitblockheight_commands;
};

/* Turning this on allows a tal allocation to return NULL, rather than aborting.
Expand Down
107 changes: 107 additions & 0 deletions lightningd/peer_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <common/initial_commit_tx.h>
#include <common/json_command.h>
#include <common/json_helpers.h>
#include <common/json_tok.h>
#include <common/jsonrpc_errors.h>
#include <common/key_derive.h>
#include <common/param.h>
Expand Down Expand Up @@ -1750,6 +1751,112 @@ static const struct json_command getinfo_command = {
};
AUTODATA(json_command, &getinfo_command);

/* Wait for at least a specific blockheight, then return, or time out. */
struct waitblockheight_waiter {
/* struct lightningd::waitblockheight_commands. */
struct list_node list;
/* Command structure. This is the parent of the close command. */
struct command *cmd;
/* The block height being waited for. */
u32 block_height;
/* Whether we have been removed from the list. */
bool removed;
};
/* Completes a pending waitblockheight. */
static struct command_result *
waitblockheight_complete(struct command *cmd,
u32 block_height)
{
struct json_stream *response;

response = json_stream_success(cmd);
json_add_num(response, "blockheight", block_height);
return command_success(cmd, response);
}
/* Called when command is destroyed without being resolved. */
static void
destroy_waitblockheight_waiter(struct waitblockheight_waiter *w)
{
if (!w->removed)
list_del(&w->list);
}
/* Called on timeout. */
static void
timeout_waitblockheight_waiter(struct waitblockheight_waiter *w)
{
list_del(&w->list);
w->removed = true;
tal_steal(tmpctx, w);
was_pending(command_fail(w->cmd, LIGHTNINGD,
"Timed out."));
}
/* Called by lightningd at each new block. */
void waitblockheight_notify_new_block(struct lightningd *ld,
u32 block_height)
{
struct waitblockheight_waiter *w, *n;
char *to_delete = tal(NULL, char);

/* Use safe since we could resolve commands and thus
* trigger removal of list elements.
*/
list_for_each_safe(&ld->waitblockheight_commands, w, n, list) {
/* Skip commands that have not been reached yet. */
if (w->block_height > block_height)
continue;

list_del(&w->list);
w->removed = true;
tal_steal(to_delete, w);
was_pending(waitblockheight_complete(w->cmd,
block_height));
}
tal_free(to_delete);
}
static struct command_result *json_waitblockheight(struct command *cmd,
const char *buffer,
const jsmntok_t *obj,
const jsmntok_t *params)
{
unsigned int *target_block_height;
u32 block_height;
unsigned int *timeout;
struct waitblockheight_waiter *w;

if (!param(cmd, buffer, params,
p_req("blockheight", param_number, &target_block_height),
p_opt_def("timeout", param_number, &timeout, 60),
NULL))
return command_param_failed();

/* Check if already reached anyway. */
block_height = get_block_height(cmd->ld->topology);
if (*target_block_height <= block_height)
return waitblockheight_complete(cmd, block_height);

/* Create a new waitblockheight command. */
w = tal(cmd, struct waitblockheight_waiter);
tal_add_destructor(w, &destroy_waitblockheight_waiter);
list_add(&cmd->ld->waitblockheight_commands, &w->list);
w->cmd = cmd;
w->block_height = *target_block_height;
w->removed = false;
/* Install the timeout. */
(void) new_reltimer(cmd->ld->timers, w, time_from_sec(*timeout),
&timeout_waitblockheight_waiter, w);

return command_still_pending(cmd);
}

static const struct json_command waitblockheight_command = {
"waitblockheight",
"utility",
&json_waitblockheight,
"Wait for the blockchain to reach {blockheight}, up to "
"{timeout} seconds."
};
AUTODATA(json_command, &waitblockheight_command);

static struct command_result *param_channel_or_all(struct command *cmd,
const char *name,
const char *buffer,
Expand Down
4 changes: 4 additions & 0 deletions lightningd/peer_control.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,8 @@ struct htlc_in_map *load_channels_from_wallet(struct lightningd *ld);
void peer_dev_memleak(struct command *cmd);
#endif /* DEVELOPER */

/* Triggered at each new block. */
void waitblockheight_notify_new_block(struct lightningd *ld,
u32 block_height);

#endif /* LIGHTNING_LIGHTNINGD_PEER_CONTROL_H */
3 changes: 3 additions & 0 deletions lightningd/test/run-find_my_abspath.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ bool wallet_network_check(struct wallet *w UNNEEDED)
/* Generated stub for wallet_new */
struct wallet *wallet_new(struct lightningd *ld UNNEEDED, struct timers *timers UNNEEDED)
{ fprintf(stderr, "wallet_new called!\n"); abort(); }
/* Generated stub for waitblockheight_notify_new_block */
void waitblockheight_notify_new_block(struct lightningd *ld UNNEEDED, u32 blockheight UNNEEDED)
{ fprintf(stderr, "waitblockheight_notify_new_block called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */

struct log *crashlog;
Expand Down
Loading