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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ check-tmpctx:
@if git grep -n 'tal_free[(]tmpctx)' | grep -Ev '^ccan/|/test/|^common/setup.c:|^common/utils.c:'; then echo "Don't free tmpctx!">&2; exit 1; fi

check-discouraged-functions:
@if git grep -E "[^a-z_/](fgets|fputs|gets|scanf|sprintf)\(" -- "*.c" "*.h" ":(exclude)ccan/" ":(exclude)contrib/"; then exit 1; fi
@if git grep -nE "[^a-z_/](fgets|fputs|gets|scanf|sprintf|randombytes_buf|time_now)\(" -- "*.c" "*.h" ":(exclude)ccan/" ":(exclude)contrib/" | grep -Fv '/* discouraged:'; then exit 1; fi

check-bad-sprintf:
@if git grep -n "%[*]\.s"; then exit 1; fi
Expand Down
2 changes: 1 addition & 1 deletion bitcoin/script.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#include <bitcoin/pubkey.h>
#include <bitcoin/script.h>
#include <ccan/mem/mem.h>
#include <common/randbytes.h>
#include <common/utils.h>
#include <sodium/randombytes.h>
#include <wally_script.h>

/* To push 0-75 bytes onto stack. */
Expand Down
4 changes: 2 additions & 2 deletions bitcoin/short_channel_id.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "config.h"
#include <bitcoin/short_channel_id.h>
#include <ccan/tal/str/str.h>
#include <sodium/randombytes.h>
#include <common/randbytes.h>
#include <stdio.h>
#include <wire/wire.h>

Expand Down Expand Up @@ -104,6 +104,6 @@ struct short_channel_id fromwire_short_channel_id(const u8 **cursor, size_t *max
struct short_channel_id random_scid(void)
{
struct short_channel_id scid;
randombytes_buf(&scid, sizeof(scid));
randbytes(&scid, sizeof(scid));
return scid;
}
1 change: 1 addition & 0 deletions channeld/test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ channeld/test/run-full_channel: \
common/msg_queue.o \
common/permute_tx.o \
common/pseudorand.o \
common/randbytes.o \
common/setup.o \
common/utils.o

Expand Down
1 change: 1 addition & 0 deletions channeld/test/run-commit_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ static bool print_superverbose;
#include <common/channel_id.h>
#include <common/daemon.h>
#include <common/key_derive.h>
#include <common/memleak.h>
#include <common/setup.h>
#include <common/status.h>

Expand Down
1 change: 1 addition & 0 deletions channeld/test/run-full_channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <ccan/err/err.h>
#include <ccan/io/io.h>
#include <common/daemon.h>
#include <common/randbytes.h>
#include <common/setup.h>
#include <wire/wire_io.h>
#include <wire/wire_sync.h>
Expand Down
2 changes: 2 additions & 0 deletions common/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ COMMON_SRC_NOGEN := \
common/channel_config.c \
common/channel_id.c \
common/channel_type.c \
common/clock_time.c \
common/close_tx.c \
common/codex32.c \
common/coin_mvt.c \
Expand Down Expand Up @@ -86,6 +87,7 @@ COMMON_SRC_NOGEN := \
common/psbt_keypath.c \
common/psbt_open.c \
common/pseudorand.c \
common/randbytes.c \
common/random_select.c \
common/read_peer_msg.c \
common/route.c \
Expand Down
2 changes: 1 addition & 1 deletion common/blindedpath.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct tlv_encrypted_data_tlv_payment_relay;
* @next_path_privkey: (out) e(i+1), the next blinding secret (optional)
* @node_alias: (out) the blinded pubkey of the node to tell the recipient.
*
* You create a blinding secret using randombytes_buf(), then call this
* You create a blinding secret using randbytes(), then call this
* iteratively for each node in the path.
*/
u8 *encrypt_tlv_encrypted_data(const tal_t *ctx,
Expand Down
36 changes: 36 additions & 0 deletions common/clock_time.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "config.h"
#include <assert.h>
#include <common/clock_time.h>

static bool used = false;
static struct timeabs dev_override;

bool clock_time_overridden(void)
{
return dev_override.ts.tv_sec != 0;
}

struct timeabs clock_time(void)
{
used = true;
if (!clock_time_overridden())
return time_now(); /* discouraged: use clock_time so we can override */

return dev_override;
}

struct timeabs clock_time_progresses_(u64 *progress)
{
if (!clock_time_overridden())
return clock_time();

return timeabs_add(dev_override, time_from_sec((*progress)++));
}

void dev_override_clock_time(struct timeabs now)
{
assert(!used);

dev_override = now;
assert(clock_time_overridden());
}
19 changes: 19 additions & 0 deletions common/clock_time.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef LIGHTNING_COMMON_CLOCK_TIME_H
#define LIGHTNING_COMMON_CLOCK_TIME_H
#include "config.h"
#include <ccan/short_types/short_types.h>
#include <ccan/time/time.h>

/* We use this instead of time_now, for overriding when we want reproducibility */
struct timeabs clock_time(void);

/* If you need a clock that progresses even when reproducible, use this. */
#define clock_time_progresses() ({static u64 progress; clock_time_progresses_(&progress);})
struct timeabs clock_time_progresses_(u64 *progress);

/* dev setting to override time */
void dev_override_clock_time(struct timeabs now);

/* Did someone override time? */
bool clock_time_overridden(void);
#endif /* LIGHTNING_COMMON_CLOCK_TIME_H */
24 changes: 17 additions & 7 deletions common/coin_mvt.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <ccan/bitops/bitops.h>
#include <ccan/ccan/cast/cast.h>
#include <ccan/tal/str/str.h>
#include <ccan/time/time.h>
#include <common/clock_time.h>
#include <common/coin_mvt.h>
#include <common/node_id.h>
#include <common/utils.h>
Expand Down Expand Up @@ -155,6 +155,12 @@ static enum mvt_tag mvt_tag_in_db(enum mvt_tag mvt_tag)
abort();
}

/* This puts the coin movements in order */
u64 coinmvt_current_time(void)
{
return clock_time_progresses().ts.tv_sec;
}

const char *mvt_tag_str(enum mvt_tag tag)
{
assert((unsigned)tag < NUM_MVT_TAGS);
Expand Down Expand Up @@ -338,7 +344,7 @@ static struct chain_coin_mvt *new_chain_coin_mvt_sat(const tal_t *ctx,
assert(ok);

return new_chain_coin_mvt(ctx, channel, account_name,
time_now().ts.tv_sec, tx_txid,
coinmvt_current_time(), tx_txid,
outpoint, payment_hash,
blockheight, tags, direction, amt_msat,
/* All amounts that are sat are
Expand Down Expand Up @@ -393,7 +399,7 @@ struct chain_coin_mvt *new_coin_channel_close(const tal_t *ctx,
tags = mk_mvt_tags(MVT_CHANNEL_CLOSE);

mvt = new_chain_coin_mvt(ctx, channel, alt_account,
time_now().ts.tv_sec, txid,
coinmvt_current_time(), txid,
out, NULL, blockheight,
tags,
COIN_DEBIT, amount,
Expand Down Expand Up @@ -421,7 +427,7 @@ struct chain_coin_mvt *new_coin_channel_open_proposed(const tal_t *ctx,
if (is_leased)
mvt_tag_set(&tags, MVT_LEASED);

mvt = new_chain_coin_mvt(ctx, channel, NULL, time_now().ts.tv_sec,
mvt = new_chain_coin_mvt(ctx, channel, NULL, coinmvt_current_time(),
NULL, out, NULL, 0,
tags,
COIN_CREDIT, amount, output_val, 0);
Expand Down Expand Up @@ -474,7 +480,7 @@ struct chain_coin_mvt *new_coin_channel_open(const tal_t *ctx,
bool is_leased)
{
return new_coin_channel_open_general(ctx, channel, NULL,
time_now().ts.tv_sec,
coinmvt_current_time(),
out, peer_id, blockheight,
amount, output_val, is_opener, is_leased);
}
Expand Down Expand Up @@ -516,7 +522,7 @@ struct chain_coin_mvt *new_coin_external_spend(const tal_t *ctx,
struct mvt_tags tags)
{
return new_chain_coin_mvt(ctx, NULL, ACCOUNT_NAME_EXTERNAL,
time_now().ts.tv_sec, txid,
coinmvt_current_time(), txid,
outpoint, NULL, blockheight,
tags,
COIN_CREDIT, AMOUNT_MSAT(0), amount, 0);
Expand Down Expand Up @@ -584,7 +590,7 @@ struct channel_coin_mvt *new_coin_channel_push(const tal_t *ctx,
struct mvt_tags tags)
{
return new_coin_channel_push_general(ctx, channel, NULL,
time_now().ts.tv_sec,
coinmvt_current_time(),
direction, amount, tags);
}

Expand Down Expand Up @@ -731,6 +737,10 @@ void fromwire_chain_coin_mvt(const u8 **cursor, size_t *max, struct chain_coin_m
} else
mvt->peer_id = NULL;
mvt->timestamp = fromwire_u64(cursor, max);

/* Align onchaind's timestamps with ours if we're deterministic */
if (clock_time_overridden())
mvt->timestamp = coinmvt_current_time();
}

struct mvt_tags mk_mvt_tags_(enum mvt_tag tag, ...)
Expand Down
3 changes: 3 additions & 0 deletions common/coin_mvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,4 +346,7 @@ bool mvt_tag_parse(const char *buf, size_t len, enum mvt_tag *tag);
void towire_chain_coin_mvt(u8 **pptr, const struct chain_coin_mvt *mvt);
void fromwire_chain_coin_mvt(const u8 **cursor, size_t *max, struct chain_coin_mvt *mvt);

/* Time helper for deterministic timestamps: always moves forwards */
u64 coinmvt_current_time(void);

#endif /* LIGHTNING_COMMON_COIN_MVT_H */
18 changes: 18 additions & 0 deletions common/daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
#include <ccan/err/err.h>
#include <ccan/io/io.h>
#include <ccan/tal/str/str.h>
#include <common/clock_time.h>
#include <common/daemon.h>
#include <common/memleak.h>
#include <common/randbytes.h>
#include <common/setup.h>
#include <common/utils.h>
#include <common/version.h>
Expand Down Expand Up @@ -201,6 +203,7 @@ void daemon_shutdown(void)
bool daemon_developer_mode(char *argv[])
{
bool developer = false, debug = false;
const char *entropy_override, *time_override;

for (int i = 1; argv[i]; i++) {
if (streq(argv[i], "--dev-debug-self"))
Expand All @@ -225,6 +228,21 @@ bool daemon_developer_mode(char *argv[])
kill(getpid(), SIGSTOP);
}

/* We can override cryptographic randomness with this var in development
* mode, for reproducible results */
entropy_override = getenv("CLN_DEV_ENTROPY_SEED");
if (entropy_override)
dev_override_randbytes(argv[0], atol(entropy_override));

/* We can also control TIME ITSELF! */
time_override = getenv("CLN_DEV_SET_TIME");
if (time_override) {
struct timeabs t;
t.ts.tv_nsec = 0;
t.ts.tv_sec = atol(time_override);
dev_override_clock_time(t);
}

/* This checks for any tal_steal loops, but it's not free:
* only use if we're already using the fairly heavy memleak
* detection. */
Expand Down
3 changes: 2 additions & 1 deletion common/onion_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <ccan/cast/cast.h>
#include <common/blindedpath.h>
#include <common/onion_message.h>
#include <common/randbytes.h>
#include <common/sphinx.h>
#include <sodium.h>

Expand Down Expand Up @@ -66,7 +67,7 @@ struct blinded_path *blinded_path_from_encdata_tlvs(const tal_t *ctx,
assert(nhops > 0);
assert(tal_count(ids) > 0);

randombytes_buf(&first_blinding, sizeof(first_blinding));
randbytes(&first_blinding, sizeof(first_blinding));
if (!pubkey_from_privkey(&first_blinding, &path->first_path_key))
abort();
sciddir_or_pubkey_from_pubkey(&path->first_node_id, &ids[0]);
Expand Down
27 changes: 22 additions & 5 deletions common/pseudorand.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <ccan/isaac/isaac64.h>
#include <ccan/tal/tal.h>
#include <common/pseudorand.h>
#include <sodium/randombytes.h>
#include <common/randbytes.h>

static struct isaac64_ctx isaac64;
static struct siphash_seed siphashseed;
Expand All @@ -16,7 +16,7 @@ static void init_if_needed(void)
unsigned char seedbuf[16];
struct sha256 sha;

randombytes_buf(seedbuf, sizeof(seedbuf));
randbytes(seedbuf, sizeof(seedbuf));
memcpy(&siphashseed, seedbuf, sizeof(siphashseed));

/* In case isaac is reversible, don't leak seed. */
Expand All @@ -26,25 +26,42 @@ static void init_if_needed(void)
}
}

uint64_t pseudorand(uint64_t max)
uint64_t pseudorand_(uint64_t max, uint64_t *offset)
{
init_if_needed();

assert(max);

/* We try to avoid being order-dependent here. */
if (randbytes_overridden()) {
uint64_t rand;
randbytes_(&rand, sizeof(rand), offset);
return rand % max;
}
return isaac64_next_uint(&isaac64, max);
}

uint64_t pseudorand_u64(void)
uint64_t pseudorand_u64_(uint64_t *offset)
{
init_if_needed();

if (randbytes_overridden()) {
uint64_t rand;
randbytes_(&rand, sizeof(rand), offset);
return rand;
}
return isaac64_next_uint64(&isaac64);
}

double pseudorand_double(void)
double pseudorand_double_(uint64_t *offset)
{
init_if_needed();

if (randbytes_overridden()) {
uint64_t rand;
randbytes_(&rand, sizeof(rand), offset);
return rand / (double)UINT64_MAX;
}
return isaac64_next_double(&isaac64);
}

Expand Down
11 changes: 7 additions & 4 deletions common/pseudorand.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,21 @@
/**
* pseudorand - pseudo (guessable!) random number between 0 and max-1.
*/
uint64_t pseudorand(uint64_t max);
#define pseudorand(max) ({static uint64_t offset; pseudorand_((max), &offset);})
uint64_t pseudorand_(uint64_t max, uint64_t *offset);

/**
* pseudorand - pseudo (guessable!) random number between 0 and UINT64_MAX.
* pseudorand_u64 - pseudo (guessable!) random number between 0 and UINT64_MAX.
*/
uint64_t pseudorand_u64(void);
#define pseudorand_u64() ({static uint64_t offset; pseudorand_u64_(&offset);})
uint64_t pseudorand_u64_(uint64_t *offset);

/**
* pseudorand - pseudo (guessable!) random number between 0 (inclusive) and 1
* (exclusive).
*/
double pseudorand_double(void);
#define pseudorand_double() ({static uint64_t offset; pseudorand_double_(&offset);})
double pseudorand_double_(uint64_t *offset);

/**
* Get the siphash seed for hash tables.
Expand Down
Loading
Loading