broadcast: Implement replacing messages in the broadcast queue

If type and tag match, then we replace any existing message in the
queue. This allows us to drop old announcements. Special care needs to
be taken so that dependent messages are not reordered, but for gossip
this is the case, since the `channel_announcement` cannot be updated.
This commit is contained in:
Christian Decker 2017-02-02 19:54:52 +01:00 committed by Rusty Russell
parent 6e63429fab
commit c2764c10c5
2 changed files with 18 additions and 2 deletions

View file

@ -26,9 +26,21 @@ void queue_broadcast(struct broadcast_state *bstate,
const u8 *tag, const u8 *tag,
const u8 *payload) const u8 *payload)
{ {
struct queued_message *msg = new_queued_message(bstate, type, tag, payload); struct queued_message *msg;
u64 index = 0;
/* Remove any tag&type collisions */
while (true) {
msg = next_broadcast_message(bstate, &index);
if (msg == NULL)
break;
else if (msg->type == type && memcmp(msg->tag, tag, tal_count(tag)) == 0) {
uintmap_del(&bstate->broadcasts, index);
tal_free(msg);
}
}
/*FIXME(cdecker) Walk through old messages and purge collisions */ /* Now add the message to the queue */
msg = new_queued_message(bstate, type, tag, payload);
uintmap_add(&bstate->broadcasts, bstate->next_index, msg); uintmap_add(&bstate->broadcasts, bstate->next_index, msg);
bstate->next_index += 1; bstate->next_index += 1;
} }

View file

@ -26,6 +26,10 @@ UINTMAP(struct queued_message *) broadcasts;
struct broadcast_state *new_broadcast_state(tal_t *ctx); struct broadcast_state *new_broadcast_state(tal_t *ctx);
/* Queue a new message to be broadcast and replace any outdated
* broadcast. Replacement is done by comparing the `type` and the
* `tag`, if both match the old message is dropped from the queue. The
* new message is added to the top of the broadcast queue. */
void queue_broadcast(struct broadcast_state *bstate, void queue_broadcast(struct broadcast_state *bstate,
const int type, const int type,
const u8 *tag, const u8 *tag,