mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 09:54:16 +01:00
gossipd: erase old entries from the store, don't just append.
We use the high bit of the length field: this way we can still check that the checksums are valid on deleted fields. Once this is done, serially reading the gossip_store file will result in a complete, ordered, minimal gossip broadcast. Also, the horrible corner case where we might try to delete things from the store during load time is completely gone: we only load non-deleted things. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
696dc6b597
commit
df00f20e4a
@ -2,6 +2,7 @@
|
||||
#include <ccan/endian/endian.h>
|
||||
#include <common/gossip_store.h>
|
||||
#include <common/status.h>
|
||||
#include <common/utils.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
@ -23,7 +24,8 @@ u8 *gossip_store_read(const tal_t *ctx, int gossip_store_fd, u64 offset)
|
||||
offset, strerror(errno));
|
||||
}
|
||||
|
||||
msglen = be32_to_cpu(hdr[0]);
|
||||
/* FIXME: We should skip over these deleted entries! */
|
||||
msglen = be32_to_cpu(hdr[0]) & ~GOSSIP_STORE_LEN_DELETED_BIT;
|
||||
checksum = be32_to_cpu(hdr[1]);
|
||||
msg = tal_arr(ctx, u8, msglen);
|
||||
if (pread(gossip_store_fd, msg, msglen, offset + sizeof(hdr)) != msglen)
|
||||
@ -33,8 +35,8 @@ u8 *gossip_store_read(const tal_t *ctx, int gossip_store_fd, u64 offset)
|
||||
|
||||
if (checksum != crc32c(0, msg, msglen))
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"gossip_store: bad checksum offset %"PRIu64,
|
||||
offset);
|
||||
"gossip_store: bad checksum offset %"PRIu64": %s",
|
||||
offset, tal_hex(tmpctx, msg));
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
@ -7,7 +7,12 @@
|
||||
/**
|
||||
* gossip_store -- On-disk storage related information
|
||||
*/
|
||||
#define GOSSIP_STORE_VERSION 4
|
||||
#define GOSSIP_STORE_VERSION 5
|
||||
|
||||
/**
|
||||
* Bit of length we use to mark a deleted record.
|
||||
*/
|
||||
#define GOSSIP_STORE_LEN_DELETED_BIT 0x80000000U
|
||||
|
||||
/**
|
||||
* Direct store accessor: loads gossip msg from store.
|
||||
|
@ -45,17 +45,21 @@ int main(int argc, char *argv[])
|
||||
while (read(fd, &belen, sizeof(belen)) == sizeof(belen) &&
|
||||
read(fd, &becsum, sizeof(becsum)) == sizeof(becsum)) {
|
||||
struct amount_sat sat;
|
||||
struct short_channel_id scid;
|
||||
u32 msglen = be32_to_cpu(belen);
|
||||
u8 *msg = tal_arr(NULL, u8, msglen), *inner;
|
||||
u8 *msg, *inner;
|
||||
bool deleted = (msglen & GOSSIP_STORE_LEN_DELETED_BIT);
|
||||
|
||||
msglen &= ~GOSSIP_STORE_LEN_DELETED_BIT;
|
||||
msg = tal_arr(NULL, u8, msglen);
|
||||
if (read(fd, msg, msglen) != msglen)
|
||||
errx(1, "%zu: Truncated file?", off);
|
||||
|
||||
if (be32_to_cpu(becsum) != crc32c(0, msg, msglen))
|
||||
warnx("Checksum verification failed");
|
||||
|
||||
if (fromwire_gossip_store_channel_amount(msg, &sat)) {
|
||||
if (deleted) {
|
||||
printf("%zu: DELETED\n", off);
|
||||
} else if (fromwire_gossip_store_channel_amount(msg, &sat)) {
|
||||
printf("%zu: channel_amount: %s\n", off,
|
||||
type_to_string(tmpctx, struct amount_sat, &sat));
|
||||
} else if (fromwire_peektype(msg) == WIRE_CHANNEL_ANNOUNCEMENT) {
|
||||
@ -70,11 +74,6 @@ int main(int argc, char *argv[])
|
||||
} else if (fromwire_peektype(msg) == WIRE_GOSSIPD_LOCAL_ADD_CHANNEL) {
|
||||
printf("%zu: local_add_channel: %s\n",
|
||||
off, tal_hex(msg, msg));
|
||||
} else if (fromwire_gossip_store_channel_delete(msg, &scid)) {
|
||||
printf("%zu: channel_delete: %s\n",
|
||||
off,
|
||||
type_to_string(msg, struct short_channel_id,
|
||||
&scid));
|
||||
} else if (fromwire_gossip_store_private_update(msg, msg,
|
||||
&inner)) {
|
||||
printf("%zu: private channel_update: %s\n",
|
||||
|
@ -206,6 +206,12 @@ static size_t transfer_store_msg(int from_fd, size_t from_off, int to_fd,
|
||||
}
|
||||
|
||||
msglen = be32_to_cpu(hdr[0]);
|
||||
if (msglen & GOSSIP_STORE_LEN_DELETED_BIT) {
|
||||
status_broken("Can't transfer deleted msg from gossip store @%zu",
|
||||
from_off);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME: Reuse buffer? */
|
||||
msg = tal_arr(tmpctx, u8, sizeof(hdr) + msglen);
|
||||
memcpy(msg, hdr, sizeof(hdr));
|
||||
@ -396,19 +402,46 @@ u64 gossip_store_add_private_update(struct gossip_store *gs, const u8 *update)
|
||||
return gossip_store_add(gs, pupdate, NULL);
|
||||
}
|
||||
|
||||
void gossip_store_add_channel_delete(struct gossip_store *gs,
|
||||
const struct short_channel_id *scid)
|
||||
void gossip_store_delete(struct gossip_store *gs,
|
||||
struct broadcastable *bcast,
|
||||
int type)
|
||||
{
|
||||
u8 *msg = towire_gossip_store_channel_delete(NULL, scid);
|
||||
beint32_t belen;
|
||||
int flags;
|
||||
|
||||
if (!bcast->index)
|
||||
return;
|
||||
|
||||
/* Should never get here during loading! */
|
||||
assert(gs->writable);
|
||||
|
||||
if (!append_msg(gs->fd, msg, &gs->len))
|
||||
#if DEVELOPER
|
||||
u8 *msg = gossip_store_read(tmpctx, gs->fd, bcast->index);
|
||||
assert(fromwire_peektype(msg) == type);
|
||||
#endif
|
||||
if (pread(gs->fd, &belen, sizeof(belen), bcast->index) != sizeof(belen))
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Failed writing channel_delete to gossip store: %s",
|
||||
strerror(errno));
|
||||
tal_free(msg);
|
||||
"Failed reading len to delete @%u: %s",
|
||||
bcast->index, strerror(errno));
|
||||
|
||||
assert((be32_to_cpu(belen) & GOSSIP_STORE_LEN_DELETED_BIT) == 0);
|
||||
belen |= cpu_to_be32(GOSSIP_STORE_LEN_DELETED_BIT);
|
||||
/* From man pwrite(2):
|
||||
*
|
||||
* BUGS
|
||||
* POSIX requires that opening a file with the O_APPEND flag should
|
||||
* have no effect on the location at which pwrite() writes data.
|
||||
* However, on Linux, if a file is opened with O_APPEND, pwrite()
|
||||
* appends data to the end of the file, regardless of the value of
|
||||
* offset.
|
||||
*/
|
||||
flags = fcntl(gs->fd, F_GETFL);
|
||||
fcntl(gs->fd, F_SETFL, flags & ~O_APPEND);
|
||||
if (pwrite(gs->fd, &belen, sizeof(belen), bcast->index) != sizeof(belen))
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Failed writing len to delete @%u: %s",
|
||||
bcast->index, strerror(errno));
|
||||
fcntl(gs->fd, F_SETFL, flags);
|
||||
}
|
||||
|
||||
const u8 *gossip_store_get(const tal_t *ctx,
|
||||
@ -443,7 +476,6 @@ void gossip_store_load(struct routing_state *rstate, struct gossip_store *gs)
|
||||
u32 msglen, checksum;
|
||||
u8 *msg;
|
||||
struct amount_sat satoshis;
|
||||
struct short_channel_id scid;
|
||||
const char *bad;
|
||||
size_t stats[] = {0, 0, 0, 0};
|
||||
struct timeabs start = time_now();
|
||||
@ -452,7 +484,7 @@ void gossip_store_load(struct routing_state *rstate, struct gossip_store *gs)
|
||||
|
||||
gs->writable = false;
|
||||
while (pread(gs->fd, hdr, sizeof(hdr), gs->len) == sizeof(hdr)) {
|
||||
msglen = be32_to_cpu(hdr[0]);
|
||||
msglen = be32_to_cpu(hdr[0]) & ~GOSSIP_STORE_LEN_DELETED_BIT;
|
||||
checksum = be32_to_cpu(hdr[1]);
|
||||
msg = tal_arr(tmpctx, u8, msglen);
|
||||
|
||||
@ -466,6 +498,10 @@ void gossip_store_load(struct routing_state *rstate, struct gossip_store *gs)
|
||||
goto truncate;
|
||||
}
|
||||
|
||||
/* Skip deleted entries */
|
||||
if (be32_to_cpu(hdr[0]) & GOSSIP_STORE_LEN_DELETED_BIT)
|
||||
goto next;
|
||||
|
||||
switch (fromwire_peektype(msg)) {
|
||||
case WIRE_GOSSIP_STORE_CHANNEL_AMOUNT:
|
||||
if (!fromwire_gossip_store_channel_amount(msg,
|
||||
@ -473,12 +509,9 @@ void gossip_store_load(struct routing_state *rstate, struct gossip_store *gs)
|
||||
bad = "Bad gossip_store_channel_amount";
|
||||
goto truncate;
|
||||
}
|
||||
/* Should follow channel_announcement */
|
||||
if (!chan_ann) {
|
||||
bad = "gossip_store_channel_amount without"
|
||||
" channel_announcement";
|
||||
goto truncate;
|
||||
}
|
||||
/* Previous channel_announcement may have been deleted */
|
||||
if (!chan_ann)
|
||||
break;
|
||||
if (!routing_add_channel_announcement(rstate,
|
||||
take(chan_ann),
|
||||
satoshis,
|
||||
@ -520,19 +553,6 @@ void gossip_store_load(struct routing_state *rstate, struct gossip_store *gs)
|
||||
}
|
||||
stats[2]++;
|
||||
break;
|
||||
case WIRE_GOSSIP_STORE_CHANNEL_DELETE:
|
||||
if (!fromwire_gossip_store_channel_delete(msg, &scid)) {
|
||||
bad = "Bad channel_delete";
|
||||
goto truncate;
|
||||
}
|
||||
struct chan *c = get_channel(rstate, &scid);
|
||||
if (!c) {
|
||||
bad = "Bad channel_delete scid";
|
||||
goto truncate;
|
||||
}
|
||||
free_chan(rstate, c);
|
||||
stats[3]++;
|
||||
break;
|
||||
case WIRE_GOSSIPD_LOCAL_ADD_CHANNEL:
|
||||
if (!handle_local_add_channel(rstate, msg, gs->len)) {
|
||||
bad = "Bad local_add_channel";
|
||||
@ -543,10 +563,11 @@ void gossip_store_load(struct routing_state *rstate, struct gossip_store *gs)
|
||||
bad = "Unknown message";
|
||||
goto truncate;
|
||||
}
|
||||
gs->len += sizeof(hdr) + msglen;
|
||||
|
||||
if (fromwire_peektype(msg) != WIRE_GOSSIP_STORE_CHANNEL_AMOUNT)
|
||||
gs->count++;
|
||||
next:
|
||||
gs->len += sizeof(hdr) + msglen;
|
||||
clean_tmpctx();
|
||||
}
|
||||
goto out;
|
||||
@ -570,9 +591,3 @@ out:
|
||||
gs->len);
|
||||
gs->writable = true;
|
||||
}
|
||||
|
||||
/* FIXME: Remove */
|
||||
bool gossip_store_loading(const struct gossip_store *gs)
|
||||
{
|
||||
return !gs->writable;
|
||||
}
|
||||
|
@ -6,9 +6,6 @@
|
||||
gossip_store_channel_amount,4101
|
||||
gossip_store_channel_amount,,satoshis,struct amount_sat
|
||||
|
||||
gossip_store_channel_delete,4099
|
||||
gossip_store_channel_delete,,short_channel_id,struct short_channel_id
|
||||
|
||||
gossip_store_private_update,4102
|
||||
gossip_store_private_update,,len,u16
|
||||
gossip_store_private_update,,update,len*u8
|
||||
|
|
@ -39,10 +39,13 @@ u64 gossip_store_add(struct gossip_store *gs, const u8 *gossip_msg,
|
||||
|
||||
|
||||
/**
|
||||
* Remember that we deleted a channel as a result of its outpoint being spent
|
||||
* Delete the broadcast associated with this (if any).
|
||||
*
|
||||
* In developer mode, checks that type is correct.
|
||||
*/
|
||||
void gossip_store_add_channel_delete(struct gossip_store *gs,
|
||||
const struct short_channel_id *scid);
|
||||
void gossip_store_delete(struct gossip_store *gs,
|
||||
struct broadcastable *bcast,
|
||||
int type);
|
||||
|
||||
/**
|
||||
* Direct store accessor: loads gossip msg back from store.
|
||||
@ -88,7 +91,4 @@ bool gossip_store_compact(struct gossip_store *gs,
|
||||
*/
|
||||
int gossip_store_readonly_fd(struct gossip_store *gs);
|
||||
|
||||
/* FIXME: Remove */
|
||||
bool gossip_store_loading(const struct gossip_store *gs);
|
||||
|
||||
#endif /* LIGHTNING_GOSSIPD_GOSSIP_STORE_H */
|
||||
|
@ -2802,13 +2802,11 @@ static struct io_plan *handle_outpoint_spent(struct io_conn *conn,
|
||||
"Deleting channel %s due to the funding outpoint being "
|
||||
"spent",
|
||||
type_to_string(msg, struct short_channel_id, &scid));
|
||||
remove_channel_from_store(rstate, chan);
|
||||
/* Freeing is sufficient since everything else is allocated off
|
||||
* of the channel and this takes care of unregistering
|
||||
* the channel */
|
||||
free_chan(rstate, chan);
|
||||
/* We put a tombstone marker in the channel store, so we don't
|
||||
* have to replay blockchain spends on restart. */
|
||||
gossip_store_add_channel_delete(rstate->broadcasts->gs, &scid);
|
||||
}
|
||||
|
||||
return daemon_conn_read_next(conn, daemon->master);
|
||||
|
@ -330,6 +330,9 @@ static void remove_chan_from_node(struct routing_state *rstate,
|
||||
|
||||
/* Last channel? Simply delete node (and associated announce) */
|
||||
if (num_chans == 0) {
|
||||
gossip_store_delete(rstate->broadcasts->gs,
|
||||
&node->bcast,
|
||||
WIRE_NODE_ANNOUNCEMENT);
|
||||
tal_free(node);
|
||||
return;
|
||||
}
|
||||
@ -337,14 +340,11 @@ static void remove_chan_from_node(struct routing_state *rstate,
|
||||
if (!node->bcast.index)
|
||||
return;
|
||||
|
||||
/* FIXME: Remove when we get rid of WIRE_GOSSIP_STORE_CHANNEL_DELETE.
|
||||
* For the moment, it can cause us to try to write to the store. */
|
||||
(void)WIRE_GOSSIP_STORE_CHANNEL_DELETE;
|
||||
if (gossip_store_loading(rstate->broadcasts->gs))
|
||||
return;
|
||||
|
||||
/* Removed only public channel? Remove node announcement. */
|
||||
if (!node_has_broadcastable_channels(node)) {
|
||||
gossip_store_delete(rstate->broadcasts->gs,
|
||||
&node->bcast,
|
||||
WIRE_NODE_ANNOUNCEMENT);
|
||||
broadcast_del(rstate->broadcasts, &node->bcast);
|
||||
} else if (node_announce_predates_channels(node)) {
|
||||
const u8 *announce;
|
||||
@ -356,6 +356,9 @@ static void remove_chan_from_node(struct routing_state *rstate,
|
||||
* Move to end (we could, in theory, move to just past next
|
||||
* channel_announce, but we don't care that much about spurious
|
||||
* retransmissions in this corner case */
|
||||
gossip_store_delete(rstate->broadcasts->gs,
|
||||
&node->bcast,
|
||||
WIRE_NODE_ANNOUNCEMENT);
|
||||
broadcast_del(rstate->broadcasts, &node->bcast);
|
||||
insert_broadcast(&rstate->broadcasts, announce, NULL,
|
||||
&node->bcast);
|
||||
@ -1416,8 +1419,10 @@ bool routing_add_channel_announcement(struct routing_state *rstate,
|
||||
}
|
||||
|
||||
/* Pretend it didn't exist, for the moment. */
|
||||
if (chan)
|
||||
if (chan) {
|
||||
remove_channel_from_store(rstate, chan);
|
||||
free_chan(rstate, chan);
|
||||
}
|
||||
|
||||
uc = tal(rstate, struct unupdated_channel);
|
||||
uc->channel_announce = tal_dup_arr(uc, u8, msg, tal_count(msg), 0);
|
||||
@ -1836,7 +1841,13 @@ bool routing_add_channel_update(struct routing_state *rstate,
|
||||
message_flags, channel_flags,
|
||||
timestamp, htlc_minimum, htlc_maximum);
|
||||
|
||||
/* Safe even if was never added */
|
||||
/* Safe even if was never added, but if it's a private channel it
|
||||
* would be a WIRE_GOSSIP_STORE_PRIVATE_UPDATE. */
|
||||
gossip_store_delete(rstate->broadcasts->gs,
|
||||
&chan->half[direction].bcast,
|
||||
is_chan_public(chan)
|
||||
? WIRE_CHANNEL_UPDATE
|
||||
: WIRE_GOSSIP_STORE_PRIVATE_UPDATE);
|
||||
broadcast_del(rstate->broadcasts, &chan->half[direction].bcast);
|
||||
|
||||
/* BOLT #7:
|
||||
@ -1899,6 +1910,28 @@ static const struct node_id *get_channel_owner(struct routing_state *rstate,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void remove_channel_from_store(struct routing_state *rstate,
|
||||
struct chan *chan)
|
||||
{
|
||||
int update_type, announcment_type;
|
||||
|
||||
if (is_chan_public(chan)) {
|
||||
update_type = WIRE_CHANNEL_UPDATE;
|
||||
announcment_type = WIRE_CHANNEL_ANNOUNCEMENT;
|
||||
} else {
|
||||
update_type = WIRE_GOSSIP_STORE_PRIVATE_UPDATE;
|
||||
announcment_type = WIRE_GOSSIPD_LOCAL_ADD_CHANNEL;
|
||||
}
|
||||
|
||||
/* If these aren't in the store, these are noops. */
|
||||
gossip_store_delete(rstate->broadcasts->gs,
|
||||
&chan->bcast, announcment_type);
|
||||
gossip_store_delete(rstate->broadcasts->gs,
|
||||
&chan->half[0].bcast, update_type);
|
||||
gossip_store_delete(rstate->broadcasts->gs,
|
||||
&chan->half[1].bcast, update_type);
|
||||
}
|
||||
|
||||
u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES,
|
||||
const char *source)
|
||||
{
|
||||
@ -2108,6 +2141,9 @@ bool routing_add_node_announcement(struct routing_state *rstate,
|
||||
}
|
||||
|
||||
/* Harmless if it was never added */
|
||||
gossip_store_delete(rstate->broadcasts->gs,
|
||||
&node->bcast,
|
||||
WIRE_NODE_ANNOUNCEMENT);
|
||||
broadcast_del(rstate->broadcasts, &node->bcast);
|
||||
|
||||
node->bcast.timestamp = timestamp;
|
||||
@ -2428,8 +2464,10 @@ void route_prune(struct routing_state *rstate)
|
||||
}
|
||||
|
||||
/* Now free all the chans and maybe even nodes. */
|
||||
for (size_t i = 0; i < tal_count(pruned); i++)
|
||||
for (size_t i = 0; i < tal_count(pruned); i++) {
|
||||
remove_channel_from_store(rstate, pruned[i]);
|
||||
free_chan(rstate, pruned[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#if DEVELOPER
|
||||
|
@ -426,4 +426,7 @@ static inline void local_enable_chan(struct routing_state *rstate,
|
||||
/* Helper to convert on-wire addresses format to wireaddrs array */
|
||||
struct wireaddr *read_addresses(const tal_t *ctx, const u8 *ser);
|
||||
|
||||
/* Remove channel from store: announcement and any updates. */
|
||||
void remove_channel_from_store(struct routing_state *rstate,
|
||||
struct chan *chan);
|
||||
#endif /* LIGHTNING_GOSSIPD_ROUTING_H */
|
||||
|
@ -42,9 +42,6 @@ bool fromwire_gossipd_local_add_channel(const void *p UNNEEDED, struct short_cha
|
||||
/* Generated stub for fromwire_gossip_store_channel_amount */
|
||||
bool fromwire_gossip_store_channel_amount(const void *p UNNEEDED, struct amount_sat *satoshis UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_store_channel_amount called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_gossip_store_channel_delete */
|
||||
bool fromwire_gossip_store_channel_delete(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_store_channel_delete called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_gossip_store_private_update */
|
||||
bool fromwire_gossip_store_private_update(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **update UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_store_private_update called!\n"); abort(); }
|
||||
@ -85,9 +82,6 @@ u8 *towire_gossipd_local_add_channel(const tal_t *ctx UNNEEDED, const struct sho
|
||||
/* Generated stub for towire_gossip_store_channel_amount */
|
||||
u8 *towire_gossip_store_channel_amount(const tal_t *ctx UNNEEDED, struct amount_sat satoshis UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossip_store_channel_amount called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossip_store_channel_delete */
|
||||
u8 *towire_gossip_store_channel_delete(const tal_t *ctx UNNEEDED, const struct short_channel_id *short_channel_id UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossip_store_channel_delete called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossip_store_private_update */
|
||||
u8 *towire_gossip_store_private_update(const tal_t *ctx UNNEEDED, const u8 *update UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossip_store_private_update called!\n"); abort(); }
|
||||
|
@ -31,9 +31,6 @@ bool fromwire_gossipd_local_add_channel(const void *p UNNEEDED, struct short_cha
|
||||
/* Generated stub for fromwire_gossip_store_channel_amount */
|
||||
bool fromwire_gossip_store_channel_amount(const void *p UNNEEDED, struct amount_sat *satoshis UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_store_channel_amount called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_gossip_store_channel_delete */
|
||||
bool fromwire_gossip_store_channel_delete(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_store_channel_delete called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_gossip_store_private_update */
|
||||
bool fromwire_gossip_store_private_update(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **update UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_store_private_update called!\n"); abort(); }
|
||||
@ -74,9 +71,6 @@ u8 *towire_gossipd_local_add_channel(const tal_t *ctx UNNEEDED, const struct sho
|
||||
/* Generated stub for towire_gossip_store_channel_amount */
|
||||
u8 *towire_gossip_store_channel_amount(const tal_t *ctx UNNEEDED, struct amount_sat satoshis UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossip_store_channel_amount called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossip_store_channel_delete */
|
||||
u8 *towire_gossip_store_channel_delete(const tal_t *ctx UNNEEDED, const struct short_channel_id *short_channel_id UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossip_store_channel_delete called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossip_store_private_update */
|
||||
u8 *towire_gossip_store_private_update(const tal_t *ctx UNNEEDED, const u8 *update UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossip_store_private_update called!\n"); abort(); }
|
||||
|
@ -29,9 +29,6 @@ bool fromwire_gossipd_local_add_channel(const void *p UNNEEDED, struct short_cha
|
||||
/* Generated stub for fromwire_gossip_store_channel_amount */
|
||||
bool fromwire_gossip_store_channel_amount(const void *p UNNEEDED, struct amount_sat *satoshis UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_store_channel_amount called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_gossip_store_channel_delete */
|
||||
bool fromwire_gossip_store_channel_delete(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_store_channel_delete called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_gossip_store_private_update */
|
||||
bool fromwire_gossip_store_private_update(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **update UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_store_private_update called!\n"); abort(); }
|
||||
@ -72,9 +69,6 @@ u8 *towire_gossipd_local_add_channel(const tal_t *ctx UNNEEDED, const struct sho
|
||||
/* Generated stub for towire_gossip_store_channel_amount */
|
||||
u8 *towire_gossip_store_channel_amount(const tal_t *ctx UNNEEDED, struct amount_sat satoshis UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossip_store_channel_amount called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossip_store_channel_delete */
|
||||
u8 *towire_gossip_store_channel_delete(const tal_t *ctx UNNEEDED, const struct short_channel_id *short_channel_id UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossip_store_channel_delete called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossip_store_private_update */
|
||||
u8 *towire_gossip_store_private_update(const tal_t *ctx UNNEEDED, const u8 *update UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossip_store_private_update called!\n"); abort(); }
|
||||
|
@ -29,9 +29,6 @@ bool fromwire_gossipd_local_add_channel(const void *p UNNEEDED, struct short_cha
|
||||
/* Generated stub for fromwire_gossip_store_channel_amount */
|
||||
bool fromwire_gossip_store_channel_amount(const void *p UNNEEDED, struct amount_sat *satoshis UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_store_channel_amount called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_gossip_store_channel_delete */
|
||||
bool fromwire_gossip_store_channel_delete(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_store_channel_delete called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_gossip_store_private_update */
|
||||
bool fromwire_gossip_store_private_update(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **update UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_store_private_update called!\n"); abort(); }
|
||||
@ -72,9 +69,6 @@ u8 *towire_gossipd_local_add_channel(const tal_t *ctx UNNEEDED, const struct sho
|
||||
/* Generated stub for towire_gossip_store_channel_amount */
|
||||
u8 *towire_gossip_store_channel_amount(const tal_t *ctx UNNEEDED, struct amount_sat satoshis UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossip_store_channel_amount called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossip_store_channel_delete */
|
||||
u8 *towire_gossip_store_channel_delete(const tal_t *ctx UNNEEDED, const struct short_channel_id *short_channel_id UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossip_store_channel_delete called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossip_store_private_update */
|
||||
u8 *towire_gossip_store_private_update(const tal_t *ctx UNNEEDED, const u8 *update UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossip_store_private_update called!\n"); abort(); }
|
||||
|
@ -861,7 +861,7 @@ def test_gossip_store_load(node_factory):
|
||||
"""Make sure we can read canned gossip store"""
|
||||
l1 = node_factory.get_node(start=False)
|
||||
with open(os.path.join(l1.daemon.lightning_dir, 'gossip_store'), 'wb') as f:
|
||||
f.write(bytearray.fromhex("04" # GOSSIP_STORE_VERSION
|
||||
f.write(bytearray.fromhex("05" # GOSSIP_STORE_VERSION
|
||||
"000001b0" # len
|
||||
"697dac9f" # csum
|
||||
"0100" # WIRE_CHANNEL_ANNOUNCEMENT
|
||||
|
Loading…
Reference in New Issue
Block a user