From cf9826eaf2f81ff1001f7d3472bd4543ac218e1f Mon Sep 17 00:00:00 2001 From: Ravyu Sivakumaran Date: Wed, 16 Apr 2025 16:22:21 +0000 Subject: [PATCH 1/2] flamenco, gossip: two-tiered value table for fast iteration in push and pullresp loops --- book/api/metrics-generated.md | 2 + .../metrics/generated/fd_metrics_gossip.c | 2 + .../metrics/generated/fd_metrics_gossip.h | 368 ++++++++------- src/disco/metrics/metrics.xml | 3 + src/discof/gossip/fd_gossip_tile.c | 3 + src/flamenco/gossip/fd_gossip.c | 446 ++++++++++-------- src/flamenco/gossip/fd_gossip.h | 4 + src/util/tmpl/fd_vec.c | 18 +- src/util/tmpl/test_vec.c | 19 +- 9 files changed, 488 insertions(+), 377 deletions(-) diff --git a/book/api/metrics-generated.md b/book/api/metrics-generated.md index 25ad8abd09..74629cab1a 100644 --- a/book/api/metrics-generated.md +++ b/book/api/metrics-generated.md @@ -381,6 +381,8 @@ | gossip_​peer_​counts_​repair | `gauge` | Number of peers of each type (Repair) | | gossip_​peer_​counts_​voter | `gauge` | Number of peers of each type (Voter) | | gossip_​shred_​version_​zero | `counter` | Shred version zero | +| gossip_​value_​meta_​size | `gauge` | Current size of the CRDS value metas map | +| gossip_​value_​vec_​size | `gauge` | Current size of the CRDS value vector | | gossip_​received_​packets | `counter` | Number of all gossip packets received | | gossip_​corrupted_​messages | `counter` | Number of corrupted gossip messages received | | gossip_​received_​gossip_​messages_​pull_​request | `counter` | Number of gossip messages received (Pull Request) | diff --git a/src/disco/metrics/generated/fd_metrics_gossip.c b/src/disco/metrics/generated/fd_metrics_gossip.c index 0f0e878375..469e92cc23 100644 --- a/src/disco/metrics/generated/fd_metrics_gossip.c +++ b/src/disco/metrics/generated/fd_metrics_gossip.c @@ -14,6 +14,8 @@ const fd_metrics_meta_t FD_METRICS_GOSSIP[FD_METRICS_GOSSIP_TOTAL] = { DECLARE_METRIC_ENUM( GOSSIP_PEER_COUNTS, GAUGE, PEER_TYPES, REPAIR ), DECLARE_METRIC_ENUM( GOSSIP_PEER_COUNTS, GAUGE, PEER_TYPES, VOTER ), DECLARE_METRIC( GOSSIP_SHRED_VERSION_ZERO, COUNTER ), + DECLARE_METRIC( GOSSIP_VALUE_META_SIZE, GAUGE ), + DECLARE_METRIC( GOSSIP_VALUE_VEC_SIZE, GAUGE ), DECLARE_METRIC( GOSSIP_RECEIVED_PACKETS, COUNTER ), DECLARE_METRIC( GOSSIP_CORRUPTED_MESSAGES, COUNTER ), DECLARE_METRIC_ENUM( GOSSIP_RECEIVED_GOSSIP_MESSAGES, COUNTER, GOSSIP_MESSAGE, PULL_REQUEST ), diff --git a/src/disco/metrics/generated/fd_metrics_gossip.h b/src/disco/metrics/generated/fd_metrics_gossip.h index 6a4694a0e3..7333d87235 100644 --- a/src/disco/metrics/generated/fd_metrics_gossip.h +++ b/src/disco/metrics/generated/fd_metrics_gossip.h @@ -54,351 +54,363 @@ #define FD_METRICS_COUNTER_GOSSIP_SHRED_VERSION_ZERO_DESC "Shred version zero" #define FD_METRICS_COUNTER_GOSSIP_SHRED_VERSION_ZERO_CVT (FD_METRICS_CONVERTER_NONE) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_PACKETS_OFF (28UL) +#define FD_METRICS_GAUGE_GOSSIP_VALUE_META_SIZE_OFF (28UL) +#define FD_METRICS_GAUGE_GOSSIP_VALUE_META_SIZE_NAME "gossip_value_meta_size" +#define FD_METRICS_GAUGE_GOSSIP_VALUE_META_SIZE_TYPE (FD_METRICS_TYPE_GAUGE) +#define FD_METRICS_GAUGE_GOSSIP_VALUE_META_SIZE_DESC "Current size of the CRDS value metas map" +#define FD_METRICS_GAUGE_GOSSIP_VALUE_META_SIZE_CVT (FD_METRICS_CONVERTER_NONE) + +#define FD_METRICS_GAUGE_GOSSIP_VALUE_VEC_SIZE_OFF (29UL) +#define FD_METRICS_GAUGE_GOSSIP_VALUE_VEC_SIZE_NAME "gossip_value_vec_size" +#define FD_METRICS_GAUGE_GOSSIP_VALUE_VEC_SIZE_TYPE (FD_METRICS_TYPE_GAUGE) +#define FD_METRICS_GAUGE_GOSSIP_VALUE_VEC_SIZE_DESC "Current size of the CRDS value vector" +#define FD_METRICS_GAUGE_GOSSIP_VALUE_VEC_SIZE_CVT (FD_METRICS_CONVERTER_NONE) + +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_PACKETS_OFF (30UL) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_PACKETS_NAME "gossip_received_packets" #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_PACKETS_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_PACKETS_DESC "Number of all gossip packets received" #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_PACKETS_CVT (FD_METRICS_CONVERTER_NONE) -#define FD_METRICS_COUNTER_GOSSIP_CORRUPTED_MESSAGES_OFF (29UL) +#define FD_METRICS_COUNTER_GOSSIP_CORRUPTED_MESSAGES_OFF (31UL) #define FD_METRICS_COUNTER_GOSSIP_CORRUPTED_MESSAGES_NAME "gossip_corrupted_messages" #define FD_METRICS_COUNTER_GOSSIP_CORRUPTED_MESSAGES_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_CORRUPTED_MESSAGES_DESC "Number of corrupted gossip messages received" #define FD_METRICS_COUNTER_GOSSIP_CORRUPTED_MESSAGES_CVT (FD_METRICS_CONVERTER_NONE) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_OFF (30UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_OFF (32UL) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_NAME "gossip_received_gossip_messages" #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_DESC "Number of gossip messages received" #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_CVT (FD_METRICS_CONVERTER_NONE) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_CNT (6UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_PULL_REQUEST_OFF (30UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_PULL_RESPONSE_OFF (31UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_PUSH_OFF (32UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_PRUNE_OFF (33UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_PING_OFF (34UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_PONG_OFF (35UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_PULL_REQUEST_OFF (32UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_PULL_RESPONSE_OFF (33UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_PUSH_OFF (34UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_PRUNE_OFF (35UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_PING_OFF (36UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_GOSSIP_MESSAGES_PONG_OFF (37UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_UNKNOWN_MESSAGE_OFF (36UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_UNKNOWN_MESSAGE_OFF (38UL) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_UNKNOWN_MESSAGE_NAME "gossip_received_unknown_message" #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_UNKNOWN_MESSAGE_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_UNKNOWN_MESSAGE_DESC "Number of gossip messages received that have an unknown discriminant" #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_UNKNOWN_MESSAGE_CVT (FD_METRICS_CONVERTER_NONE) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_OFF (37UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_OFF (39UL) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_NAME "gossip_received_crds_push" #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_DESC "Number of CRDS values received from push messages" #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_CVT (FD_METRICS_CONVERTER_NONE) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_CNT (14UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_CONTACT_INFO_V1_OFF (37UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_VOTE_OFF (38UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_LOWEST_SLOT_OFF (39UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_SNAPSHOT_HASHES_OFF (40UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_ACCOUNTS_HASHES_OFF (41UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_EPOCH_SLOTS_OFF (42UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_VERSION_V1_OFF (43UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_VERSION_V2_OFF (44UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_NODE_INSTANCE_OFF (45UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_DUPLICATE_SHRED_OFF (46UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_INCREMENTAL_SNAPSHOT_HASHES_OFF (47UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_CONTACT_INFO_V2_OFF (48UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_RESTART_LAST_VOTED_FORK_SLOTS_OFF (49UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_RESTART_HEAVIEST_FORK_OFF (50UL) - -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_OFF (51UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_CONTACT_INFO_V1_OFF (39UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_VOTE_OFF (40UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_LOWEST_SLOT_OFF (41UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_SNAPSHOT_HASHES_OFF (42UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_ACCOUNTS_HASHES_OFF (43UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_EPOCH_SLOTS_OFF (44UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_VERSION_V1_OFF (45UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_VERSION_V2_OFF (46UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_NODE_INSTANCE_OFF (47UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_DUPLICATE_SHRED_OFF (48UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_INCREMENTAL_SNAPSHOT_HASHES_OFF (49UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_CONTACT_INFO_V2_OFF (50UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_RESTART_LAST_VOTED_FORK_SLOTS_OFF (51UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PUSH_RESTART_HEAVIEST_FORK_OFF (52UL) + +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_OFF (53UL) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_NAME "gossip_received_crds_pull" #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_DESC "Number of CRDS values received from pull response messages" #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_CVT (FD_METRICS_CONVERTER_NONE) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_CNT (14UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_CONTACT_INFO_V1_OFF (51UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_VOTE_OFF (52UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_LOWEST_SLOT_OFF (53UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_SNAPSHOT_HASHES_OFF (54UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_ACCOUNTS_HASHES_OFF (55UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_EPOCH_SLOTS_OFF (56UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_VERSION_V1_OFF (57UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_VERSION_V2_OFF (58UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_NODE_INSTANCE_OFF (59UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_DUPLICATE_SHRED_OFF (60UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_INCREMENTAL_SNAPSHOT_HASHES_OFF (61UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_CONTACT_INFO_V2_OFF (62UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_RESTART_LAST_VOTED_FORK_SLOTS_OFF (63UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_RESTART_HEAVIEST_FORK_OFF (64UL) - -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_OFF (65UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_CONTACT_INFO_V1_OFF (53UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_VOTE_OFF (54UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_LOWEST_SLOT_OFF (55UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_SNAPSHOT_HASHES_OFF (56UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_ACCOUNTS_HASHES_OFF (57UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_EPOCH_SLOTS_OFF (58UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_VERSION_V1_OFF (59UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_VERSION_V2_OFF (60UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_NODE_INSTANCE_OFF (61UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_DUPLICATE_SHRED_OFF (62UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_INCREMENTAL_SNAPSHOT_HASHES_OFF (63UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_CONTACT_INFO_V2_OFF (64UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_RESTART_LAST_VOTED_FORK_SLOTS_OFF (65UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_PULL_RESTART_HEAVIEST_FORK_OFF (66UL) + +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_OFF (67UL) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_NAME "gossip_received_crds_duplicate_message_push" #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_DESC "Number of duplicate CRDS values received from push messages" #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_CVT (FD_METRICS_CONVERTER_NONE) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_CNT (14UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_CONTACT_INFO_V1_OFF (65UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_VOTE_OFF (66UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_LOWEST_SLOT_OFF (67UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_SNAPSHOT_HASHES_OFF (68UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_ACCOUNTS_HASHES_OFF (69UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_EPOCH_SLOTS_OFF (70UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_VERSION_V1_OFF (71UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_VERSION_V2_OFF (72UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_NODE_INSTANCE_OFF (73UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_DUPLICATE_SHRED_OFF (74UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_INCREMENTAL_SNAPSHOT_HASHES_OFF (75UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_CONTACT_INFO_V2_OFF (76UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_RESTART_LAST_VOTED_FORK_SLOTS_OFF (77UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_RESTART_HEAVIEST_FORK_OFF (78UL) - -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_OFF (79UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_CONTACT_INFO_V1_OFF (67UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_VOTE_OFF (68UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_LOWEST_SLOT_OFF (69UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_SNAPSHOT_HASHES_OFF (70UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_ACCOUNTS_HASHES_OFF (71UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_EPOCH_SLOTS_OFF (72UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_VERSION_V1_OFF (73UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_VERSION_V2_OFF (74UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_NODE_INSTANCE_OFF (75UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_DUPLICATE_SHRED_OFF (76UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_INCREMENTAL_SNAPSHOT_HASHES_OFF (77UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_CONTACT_INFO_V2_OFF (78UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_RESTART_LAST_VOTED_FORK_SLOTS_OFF (79UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PUSH_RESTART_HEAVIEST_FORK_OFF (80UL) + +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_OFF (81UL) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_NAME "gossip_received_crds_duplicate_message_pull" #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_DESC "Number of duplicate CRDS values received from pull response messages" #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_CVT (FD_METRICS_CONVERTER_NONE) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_CNT (14UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_CONTACT_INFO_V1_OFF (79UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_VOTE_OFF (80UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_LOWEST_SLOT_OFF (81UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_SNAPSHOT_HASHES_OFF (82UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_ACCOUNTS_HASHES_OFF (83UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_EPOCH_SLOTS_OFF (84UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_VERSION_V1_OFF (85UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_VERSION_V2_OFF (86UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_NODE_INSTANCE_OFF (87UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_DUPLICATE_SHRED_OFF (88UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_INCREMENTAL_SNAPSHOT_HASHES_OFF (89UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_CONTACT_INFO_V2_OFF (90UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_RESTART_LAST_VOTED_FORK_SLOTS_OFF (91UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_RESTART_HEAVIEST_FORK_OFF (92UL) - -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_OFF (93UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_CONTACT_INFO_V1_OFF (81UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_VOTE_OFF (82UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_LOWEST_SLOT_OFF (83UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_SNAPSHOT_HASHES_OFF (84UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_ACCOUNTS_HASHES_OFF (85UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_EPOCH_SLOTS_OFF (86UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_VERSION_V1_OFF (87UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_VERSION_V2_OFF (88UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_NODE_INSTANCE_OFF (89UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_DUPLICATE_SHRED_OFF (90UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_INCREMENTAL_SNAPSHOT_HASHES_OFF (91UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_CONTACT_INFO_V2_OFF (92UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_RESTART_LAST_VOTED_FORK_SLOTS_OFF (93UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DUPLICATE_MESSAGE_PULL_RESTART_HEAVIEST_FORK_OFF (94UL) + +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_OFF (95UL) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_NAME "gossip_received_crds_drop" #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_DESC "Number of CRDS values dropped on receive" #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_CVT (FD_METRICS_CONVERTER_NONE) #define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_CNT (12UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_SUCCESS_OFF (93UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_DUPLICATE_OFF (94UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_UNKNOWN_DISCRIMINANT_OFF (95UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_OWN_MESSAGE_OFF (96UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_INVALID_SIGNATURE_OFF (97UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_TABLE_FULL_OFF (98UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_PUSH_QUEUE_FULL_OFF (99UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_INVALID_GOSSIP_PORT_OFF (100UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_PEER_TABLE_FULL_OFF (101UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_INACTIVES_QUEUE_FULL_OFF (102UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_DISCARDED_PEER_OFF (103UL) -#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_ENCODING_FAILED_OFF (104UL) - -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_OFF (105UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_SUCCESS_OFF (95UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_DUPLICATE_OFF (96UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_UNKNOWN_DISCRIMINANT_OFF (97UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_OWN_MESSAGE_OFF (98UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_INVALID_SIGNATURE_OFF (99UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_TABLE_FULL_OFF (100UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_PUSH_QUEUE_FULL_OFF (101UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_INVALID_GOSSIP_PORT_OFF (102UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_PEER_TABLE_FULL_OFF (103UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_INACTIVES_QUEUE_FULL_OFF (104UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_DISCARDED_PEER_OFF (105UL) +#define FD_METRICS_COUNTER_GOSSIP_RECEIVED_CRDS_DROP_ENCODING_FAILED_OFF (106UL) + +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_OFF (107UL) #define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_NAME "gossip_push_crds" #define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DESC "Number of CRDS values pushed" #define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_CVT (FD_METRICS_CONVERTER_NONE) #define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_CNT (14UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_CONTACT_INFO_V1_OFF (105UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_VOTE_OFF (106UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_LOWEST_SLOT_OFF (107UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_SNAPSHOT_HASHES_OFF (108UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_ACCOUNTS_HASHES_OFF (109UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_EPOCH_SLOTS_OFF (110UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_VERSION_V1_OFF (111UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_VERSION_V2_OFF (112UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_NODE_INSTANCE_OFF (113UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_SHRED_OFF (114UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_INCREMENTAL_SNAPSHOT_HASHES_OFF (115UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_CONTACT_INFO_V2_OFF (116UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_RESTART_LAST_VOTED_FORK_SLOTS_OFF (117UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_RESTART_HEAVIEST_FORK_OFF (118UL) - -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_OFF (119UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_CONTACT_INFO_V1_OFF (107UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_VOTE_OFF (108UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_LOWEST_SLOT_OFF (109UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_SNAPSHOT_HASHES_OFF (110UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_ACCOUNTS_HASHES_OFF (111UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_EPOCH_SLOTS_OFF (112UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_VERSION_V1_OFF (113UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_VERSION_V2_OFF (114UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_NODE_INSTANCE_OFF (115UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_SHRED_OFF (116UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_INCREMENTAL_SNAPSHOT_HASHES_OFF (117UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_CONTACT_INFO_V2_OFF (118UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_RESTART_LAST_VOTED_FORK_SLOTS_OFF (119UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_RESTART_HEAVIEST_FORK_OFF (120UL) + +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_OFF (121UL) #define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_NAME "gossip_push_crds_duplicate_message" #define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_DESC "Number of duplicate CRDS values inserted (internally)" #define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_CVT (FD_METRICS_CONVERTER_NONE) #define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_CNT (14UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_CONTACT_INFO_V1_OFF (119UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_VOTE_OFF (120UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_LOWEST_SLOT_OFF (121UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_SNAPSHOT_HASHES_OFF (122UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_ACCOUNTS_HASHES_OFF (123UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_EPOCH_SLOTS_OFF (124UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_VERSION_V1_OFF (125UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_VERSION_V2_OFF (126UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_NODE_INSTANCE_OFF (127UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_DUPLICATE_SHRED_OFF (128UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_INCREMENTAL_SNAPSHOT_HASHES_OFF (129UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_CONTACT_INFO_V2_OFF (130UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_RESTART_LAST_VOTED_FORK_SLOTS_OFF (131UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_RESTART_HEAVIEST_FORK_OFF (132UL) - -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_OFF (133UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_CONTACT_INFO_V1_OFF (121UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_VOTE_OFF (122UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_LOWEST_SLOT_OFF (123UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_SNAPSHOT_HASHES_OFF (124UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_ACCOUNTS_HASHES_OFF (125UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_EPOCH_SLOTS_OFF (126UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_VERSION_V1_OFF (127UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_VERSION_V2_OFF (128UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_NODE_INSTANCE_OFF (129UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_DUPLICATE_SHRED_OFF (130UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_INCREMENTAL_SNAPSHOT_HASHES_OFF (131UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_CONTACT_INFO_V2_OFF (132UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_RESTART_LAST_VOTED_FORK_SLOTS_OFF (133UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DUPLICATE_MESSAGE_RESTART_HEAVIEST_FORK_OFF (134UL) + +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_OFF (135UL) #define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_NAME "gossip_push_crds_drop" #define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_DESC "Number of CRDS values dropped on push" #define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_CVT (FD_METRICS_CONVERTER_NONE) #define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_CNT (12UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_SUCCESS_OFF (133UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_DUPLICATE_OFF (134UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_UNKNOWN_DISCRIMINANT_OFF (135UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_OWN_MESSAGE_OFF (136UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_INVALID_SIGNATURE_OFF (137UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_TABLE_FULL_OFF (138UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_PUSH_QUEUE_FULL_OFF (139UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_INVALID_GOSSIP_PORT_OFF (140UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_PEER_TABLE_FULL_OFF (141UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_INACTIVES_QUEUE_FULL_OFF (142UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_DISCARDED_PEER_OFF (143UL) -#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_ENCODING_FAILED_OFF (144UL) - -#define FD_METRICS_GAUGE_GOSSIP_PUSH_CRDS_QUEUE_COUNT_OFF (145UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_SUCCESS_OFF (135UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_DUPLICATE_OFF (136UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_UNKNOWN_DISCRIMINANT_OFF (137UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_OWN_MESSAGE_OFF (138UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_INVALID_SIGNATURE_OFF (139UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_TABLE_FULL_OFF (140UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_PUSH_QUEUE_FULL_OFF (141UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_INVALID_GOSSIP_PORT_OFF (142UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_PEER_TABLE_FULL_OFF (143UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_INACTIVES_QUEUE_FULL_OFF (144UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_DISCARDED_PEER_OFF (145UL) +#define FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_ENCODING_FAILED_OFF (146UL) + +#define FD_METRICS_GAUGE_GOSSIP_PUSH_CRDS_QUEUE_COUNT_OFF (147UL) #define FD_METRICS_GAUGE_GOSSIP_PUSH_CRDS_QUEUE_COUNT_NAME "gossip_push_crds_queue_count" #define FD_METRICS_GAUGE_GOSSIP_PUSH_CRDS_QUEUE_COUNT_TYPE (FD_METRICS_TYPE_GAUGE) #define FD_METRICS_GAUGE_GOSSIP_PUSH_CRDS_QUEUE_COUNT_DESC "Number of CRDS values in the queue to be pushed" #define FD_METRICS_GAUGE_GOSSIP_PUSH_CRDS_QUEUE_COUNT_CVT (FD_METRICS_CONVERTER_NONE) -#define FD_METRICS_GAUGE_GOSSIP_ACTIVE_PUSH_DESTINATIONS_OFF (146UL) +#define FD_METRICS_GAUGE_GOSSIP_ACTIVE_PUSH_DESTINATIONS_OFF (148UL) #define FD_METRICS_GAUGE_GOSSIP_ACTIVE_PUSH_DESTINATIONS_NAME "gossip_active_push_destinations" #define FD_METRICS_GAUGE_GOSSIP_ACTIVE_PUSH_DESTINATIONS_TYPE (FD_METRICS_TYPE_GAUGE) #define FD_METRICS_GAUGE_GOSSIP_ACTIVE_PUSH_DESTINATIONS_DESC "Number of active Push destinations" #define FD_METRICS_GAUGE_GOSSIP_ACTIVE_PUSH_DESTINATIONS_CVT (FD_METRICS_CONVERTER_NONE) -#define FD_METRICS_COUNTER_GOSSIP_REFRESH_PUSH_STATES_FAIL_COUNT_OFF (147UL) +#define FD_METRICS_COUNTER_GOSSIP_REFRESH_PUSH_STATES_FAIL_COUNT_OFF (149UL) #define FD_METRICS_COUNTER_GOSSIP_REFRESH_PUSH_STATES_FAIL_COUNT_NAME "gossip_refresh_push_states_fail_count" #define FD_METRICS_COUNTER_GOSSIP_REFRESH_PUSH_STATES_FAIL_COUNT_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_REFRESH_PUSH_STATES_FAIL_COUNT_DESC "Number of failures whilst refreshing push states" #define FD_METRICS_COUNTER_GOSSIP_REFRESH_PUSH_STATES_FAIL_COUNT_CVT (FD_METRICS_CONVERTER_NONE) -#define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_FAIL_OFF (148UL) +#define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_FAIL_OFF (150UL) #define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_FAIL_NAME "gossip_pull_req_fail" #define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_FAIL_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_FAIL_DESC "Number of PullReq messages that failed" #define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_FAIL_CVT (FD_METRICS_CONVERTER_NONE) #define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_FAIL_CNT (4UL) -#define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_FAIL_PEER_NOT_IN_ACTIVES_OFF (148UL) -#define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_FAIL_UNRESPONSIVE_PEER_OFF (149UL) -#define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_FAIL_PENDING_POOL_FULL_OFF (150UL) -#define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_FAIL_ENCODING_FAILED_OFF (151UL) +#define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_FAIL_PEER_NOT_IN_ACTIVES_OFF (150UL) +#define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_FAIL_UNRESPONSIVE_PEER_OFF (151UL) +#define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_FAIL_PENDING_POOL_FULL_OFF (152UL) +#define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_FAIL_ENCODING_FAILED_OFF (153UL) -#define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_BLOOM_FILTER_OFF (152UL) +#define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_BLOOM_FILTER_OFF (154UL) #define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_BLOOM_FILTER_NAME "gossip_pull_req_bloom_filter" #define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_BLOOM_FILTER_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_BLOOM_FILTER_DESC "Result of the bloom filter check for a PullReq" #define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_BLOOM_FILTER_CVT (FD_METRICS_CONVERTER_NONE) #define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_BLOOM_FILTER_CNT (2UL) -#define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_BLOOM_FILTER_HIT_OFF (152UL) -#define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_BLOOM_FILTER_MISS_OFF (153UL) +#define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_BLOOM_FILTER_HIT_OFF (154UL) +#define FD_METRICS_COUNTER_GOSSIP_PULL_REQ_BLOOM_FILTER_MISS_OFF (155UL) -#define FD_METRICS_GAUGE_GOSSIP_PULL_REQ_RESP_PACKETS_OFF (154UL) +#define FD_METRICS_GAUGE_GOSSIP_PULL_REQ_RESP_PACKETS_OFF (156UL) #define FD_METRICS_GAUGE_GOSSIP_PULL_REQ_RESP_PACKETS_NAME "gossip_pull_req_resp_packets" #define FD_METRICS_GAUGE_GOSSIP_PULL_REQ_RESP_PACKETS_TYPE (FD_METRICS_TYPE_GAUGE) #define FD_METRICS_GAUGE_GOSSIP_PULL_REQ_RESP_PACKETS_DESC "Number of packets used to respond to a PullReq" #define FD_METRICS_GAUGE_GOSSIP_PULL_REQ_RESP_PACKETS_CVT (FD_METRICS_CONVERTER_NONE) -#define FD_METRICS_COUNTER_GOSSIP_PRUNE_FAIL_COUNT_OFF (155UL) +#define FD_METRICS_COUNTER_GOSSIP_PRUNE_FAIL_COUNT_OFF (157UL) #define FD_METRICS_COUNTER_GOSSIP_PRUNE_FAIL_COUNT_NAME "gossip_prune_fail_count" #define FD_METRICS_COUNTER_GOSSIP_PRUNE_FAIL_COUNT_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_PRUNE_FAIL_COUNT_DESC "Number of Prune messages that failed" #define FD_METRICS_COUNTER_GOSSIP_PRUNE_FAIL_COUNT_CVT (FD_METRICS_CONVERTER_NONE) #define FD_METRICS_COUNTER_GOSSIP_PRUNE_FAIL_COUNT_CNT (3UL) -#define FD_METRICS_COUNTER_GOSSIP_PRUNE_FAIL_COUNT_NOT_FOR_ME_OFF (155UL) -#define FD_METRICS_COUNTER_GOSSIP_PRUNE_FAIL_COUNT_SIGN_ENCODING_FAILED_OFF (156UL) -#define FD_METRICS_COUNTER_GOSSIP_PRUNE_FAIL_COUNT_INVALID_SIGNATURE_OFF (157UL) +#define FD_METRICS_COUNTER_GOSSIP_PRUNE_FAIL_COUNT_NOT_FOR_ME_OFF (157UL) +#define FD_METRICS_COUNTER_GOSSIP_PRUNE_FAIL_COUNT_SIGN_ENCODING_FAILED_OFF (158UL) +#define FD_METRICS_COUNTER_GOSSIP_PRUNE_FAIL_COUNT_INVALID_SIGNATURE_OFF (159UL) -#define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_STALE_ENTRY_OFF (158UL) +#define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_STALE_ENTRY_OFF (160UL) #define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_STALE_ENTRY_NAME "gossip_make_prune_stale_entry" #define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_STALE_ENTRY_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_STALE_ENTRY_DESC "Number of stale entries removed from the stats table while making prune messages" #define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_STALE_ENTRY_CVT (FD_METRICS_CONVERTER_NONE) -#define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_HIGH_DUPLICATES_OFF (159UL) +#define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_HIGH_DUPLICATES_OFF (161UL) #define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_HIGH_DUPLICATES_NAME "gossip_make_prune_high_duplicates" #define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_HIGH_DUPLICATES_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_HIGH_DUPLICATES_DESC "Number of origins with high duplicate counts found while making prune messages" #define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_HIGH_DUPLICATES_CVT (FD_METRICS_CONVERTER_NONE) -#define FD_METRICS_GAUGE_GOSSIP_MAKE_PRUNE_REQUESTED_ORIGINS_OFF (160UL) +#define FD_METRICS_GAUGE_GOSSIP_MAKE_PRUNE_REQUESTED_ORIGINS_OFF (162UL) #define FD_METRICS_GAUGE_GOSSIP_MAKE_PRUNE_REQUESTED_ORIGINS_NAME "gossip_make_prune_requested_origins" #define FD_METRICS_GAUGE_GOSSIP_MAKE_PRUNE_REQUESTED_ORIGINS_TYPE (FD_METRICS_TYPE_GAUGE) #define FD_METRICS_GAUGE_GOSSIP_MAKE_PRUNE_REQUESTED_ORIGINS_DESC "Number of requested origins in the last prune message we made" #define FD_METRICS_GAUGE_GOSSIP_MAKE_PRUNE_REQUESTED_ORIGINS_CVT (FD_METRICS_CONVERTER_NONE) -#define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_SIGN_DATA_ENCODE_FAILED_OFF (161UL) +#define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_SIGN_DATA_ENCODE_FAILED_OFF (163UL) #define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_SIGN_DATA_ENCODE_FAILED_NAME "gossip_make_prune_sign_data_encode_failed" #define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_SIGN_DATA_ENCODE_FAILED_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_SIGN_DATA_ENCODE_FAILED_DESC "Number of times we failed to encode the sign data" #define FD_METRICS_COUNTER_GOSSIP_MAKE_PRUNE_SIGN_DATA_ENCODE_FAILED_CVT (FD_METRICS_CONVERTER_NONE) -#define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_OFF (162UL) +#define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_OFF (164UL) #define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_NAME "gossip_sent_gossip_messages" #define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_DESC "Number of gossip messages sent" #define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_CVT (FD_METRICS_CONVERTER_NONE) #define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_CNT (6UL) -#define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_PULL_REQUEST_OFF (162UL) -#define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_PULL_RESPONSE_OFF (163UL) -#define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_PUSH_OFF (164UL) -#define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_PRUNE_OFF (165UL) -#define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_PING_OFF (166UL) -#define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_PONG_OFF (167UL) +#define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_PULL_REQUEST_OFF (164UL) +#define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_PULL_RESPONSE_OFF (165UL) +#define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_PUSH_OFF (166UL) +#define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_PRUNE_OFF (167UL) +#define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_PING_OFF (168UL) +#define FD_METRICS_COUNTER_GOSSIP_SENT_GOSSIP_MESSAGES_PONG_OFF (169UL) -#define FD_METRICS_COUNTER_GOSSIP_SENT_PACKETS_OFF (168UL) +#define FD_METRICS_COUNTER_GOSSIP_SENT_PACKETS_OFF (170UL) #define FD_METRICS_COUNTER_GOSSIP_SENT_PACKETS_NAME "gossip_sent_packets" #define FD_METRICS_COUNTER_GOSSIP_SENT_PACKETS_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_SENT_PACKETS_DESC "Number of Packets sent" #define FD_METRICS_COUNTER_GOSSIP_SENT_PACKETS_CVT (FD_METRICS_CONVERTER_NONE) -#define FD_METRICS_COUNTER_GOSSIP_SEND_PING_EVENT_OFF (169UL) +#define FD_METRICS_COUNTER_GOSSIP_SEND_PING_EVENT_OFF (171UL) #define FD_METRICS_COUNTER_GOSSIP_SEND_PING_EVENT_NAME "gossip_send_ping_event" #define FD_METRICS_COUNTER_GOSSIP_SEND_PING_EVENT_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_SEND_PING_EVENT_DESC "Number of Ping messages sent with non-standard outcomes" #define FD_METRICS_COUNTER_GOSSIP_SEND_PING_EVENT_CVT (FD_METRICS_CONVERTER_NONE) #define FD_METRICS_COUNTER_GOSSIP_SEND_PING_EVENT_CNT (3UL) -#define FD_METRICS_COUNTER_GOSSIP_SEND_PING_EVENT_ACTIVES_TABLE_FULL_OFF (169UL) -#define FD_METRICS_COUNTER_GOSSIP_SEND_PING_EVENT_ACTIVES_TABLE_INSERT_OFF (170UL) -#define FD_METRICS_COUNTER_GOSSIP_SEND_PING_EVENT_MAX_PING_COUNT_EXCEEDED_OFF (171UL) +#define FD_METRICS_COUNTER_GOSSIP_SEND_PING_EVENT_ACTIVES_TABLE_FULL_OFF (171UL) +#define FD_METRICS_COUNTER_GOSSIP_SEND_PING_EVENT_ACTIVES_TABLE_INSERT_OFF (172UL) +#define FD_METRICS_COUNTER_GOSSIP_SEND_PING_EVENT_MAX_PING_COUNT_EXCEEDED_OFF (173UL) -#define FD_METRICS_COUNTER_GOSSIP_RECV_PING_INVALID_SIGNATURE_OFF (172UL) +#define FD_METRICS_COUNTER_GOSSIP_RECV_PING_INVALID_SIGNATURE_OFF (174UL) #define FD_METRICS_COUNTER_GOSSIP_RECV_PING_INVALID_SIGNATURE_NAME "gossip_recv_ping_invalid_signature" #define FD_METRICS_COUNTER_GOSSIP_RECV_PING_INVALID_SIGNATURE_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_RECV_PING_INVALID_SIGNATURE_DESC "Number of times we received a Ping message with an invalid signature" #define FD_METRICS_COUNTER_GOSSIP_RECV_PING_INVALID_SIGNATURE_CVT (FD_METRICS_CONVERTER_NONE) -#define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_OFF (173UL) +#define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_OFF (175UL) #define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_NAME "gossip_recv_pong_event" #define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_TYPE (FD_METRICS_TYPE_COUNTER) #define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_DESC "Number of Pong messages processed with non-standard outcomes" #define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_CVT (FD_METRICS_CONVERTER_NONE) #define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_CNT (5UL) -#define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_NEW_PEER_OFF (173UL) -#define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_WRONG_TOKEN_OFF (174UL) -#define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_INVALID_SIGNATURE_OFF (175UL) -#define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_EXPIRED_OFF (176UL) -#define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_TABLE_FULL_OFF (177UL) +#define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_NEW_PEER_OFF (175UL) +#define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_WRONG_TOKEN_OFF (176UL) +#define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_INVALID_SIGNATURE_OFF (177UL) +#define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_EXPIRED_OFF (178UL) +#define FD_METRICS_COUNTER_GOSSIP_RECV_PONG_EVENT_TABLE_FULL_OFF (179UL) -#define FD_METRICS_GAUGE_GOSSIP_GOSSIP_PEER_COUNTS_OFF (178UL) +#define FD_METRICS_GAUGE_GOSSIP_GOSSIP_PEER_COUNTS_OFF (180UL) #define FD_METRICS_GAUGE_GOSSIP_GOSSIP_PEER_COUNTS_NAME "gossip_gossip_peer_counts" #define FD_METRICS_GAUGE_GOSSIP_GOSSIP_PEER_COUNTS_TYPE (FD_METRICS_TYPE_GAUGE) #define FD_METRICS_GAUGE_GOSSIP_GOSSIP_PEER_COUNTS_DESC "Number of gossip peers tracked" #define FD_METRICS_GAUGE_GOSSIP_GOSSIP_PEER_COUNTS_CVT (FD_METRICS_CONVERTER_NONE) #define FD_METRICS_GAUGE_GOSSIP_GOSSIP_PEER_COUNTS_CNT (3UL) -#define FD_METRICS_GAUGE_GOSSIP_GOSSIP_PEER_COUNTS_TOTAL_OFF (178UL) -#define FD_METRICS_GAUGE_GOSSIP_GOSSIP_PEER_COUNTS_ACTIVE_OFF (179UL) -#define FD_METRICS_GAUGE_GOSSIP_GOSSIP_PEER_COUNTS_INACTIVE_OFF (180UL) +#define FD_METRICS_GAUGE_GOSSIP_GOSSIP_PEER_COUNTS_TOTAL_OFF (180UL) +#define FD_METRICS_GAUGE_GOSSIP_GOSSIP_PEER_COUNTS_ACTIVE_OFF (181UL) +#define FD_METRICS_GAUGE_GOSSIP_GOSSIP_PEER_COUNTS_INACTIVE_OFF (182UL) -#define FD_METRICS_GOSSIP_TOTAL (165UL) +#define FD_METRICS_GOSSIP_TOTAL (167UL) extern const fd_metrics_meta_t FD_METRICS_GOSSIP[FD_METRICS_GOSSIP_TOTAL]; diff --git a/src/disco/metrics/metrics.xml b/src/disco/metrics/metrics.xml index 77f278b956..9b1efd429c 100644 --- a/src/disco/metrics/metrics.xml +++ b/src/disco/metrics/metrics.xml @@ -643,6 +643,9 @@ metric introduced. + + + diff --git a/src/discof/gossip/fd_gossip_tile.c b/src/discof/gossip/fd_gossip_tile.c index 4ca7dc5cc9..04fc855425 100644 --- a/src/discof/gossip/fd_gossip_tile.c +++ b/src/discof/gossip/fd_gossip_tile.c @@ -1073,6 +1073,9 @@ fd_gossip_update_gossip_metrics( fd_gossip_metrics_t * metrics ) { FD_MCNT_ENUM_COPY( GOSSIP, PUSH_CRDS_DROP, metrics->push_crds_drop_reason ); FD_MGAUGE_SET( GOSSIP, PUSH_CRDS_QUEUE_COUNT, metrics->push_crds_queue_cnt ); + FD_MGAUGE_SET( GOSSIP, VALUE_META_SIZE, metrics->value_meta_cnt ); + FD_MGAUGE_SET( GOSSIP, VALUE_VEC_SIZE, metrics->value_vec_cnt ); + FD_MGAUGE_SET( GOSSIP, ACTIVE_PUSH_DESTINATIONS, metrics->active_push_destinations ); FD_MCNT_SET( GOSSIP, REFRESH_PUSH_STATES_FAIL_COUNT, metrics->refresh_push_states_failcnt ); diff --git a/src/flamenco/gossip/fd_gossip.c b/src/flamenco/gossip/fd_gossip.c index 44e81e83f9..4b41ddf3d0 100644 --- a/src/flamenco/gossip/fd_gossip.c +++ b/src/flamenco/gossip/fd_gossip.c @@ -22,7 +22,8 @@ Purged values are counted because: - Our table (currently) does not "purge" values in the same sense Agave does - Purged values are included in bloom filter construction, so we need them anyway */ -#define FD_VALUE_KEY_MAX (1<<21) +#define FD_VALUE_KEY_MAX (1<<24) // includes purged values +#define FD_VALUE_DATA_MAX (1<<21) /* Max number of pending timed events */ #define FD_PENDING_MAX (1<<9) /* Sample rate of bloom filters. */ @@ -166,24 +167,60 @@ void fd_hash_copy( fd_hash_t * keyd, const fd_hash_t * keys ) { keyd->ul[i] = keys->ul[i]; } -/* Value table element. This table stores all received crds - values. Keyed by the hash of the value data. */ -struct fd_value_elem { - fd_hash_t key; - ulong next; - fd_pubkey_t origin; /* Where did this value originate */ - ulong wallclock; /* Original timestamp of value in millis */ - uchar data[PACKET_DATA_SIZE]; /* Serialized form of value (bincode) including signature */ - ulong datalen; +/************ Gossip Value Table Structures **************/ +/* The fd_gossip value table is backed by two structures: + a value metadata map and a value vector. The lifetime + requirement of a full value is much smaller than its + metadata (15s vs 1hr), while a full value has a much + larger size footprint (100x). Decoupling the two + allows for retaining more metadata without significantly + increasing memory footprint and iteration overhead. + + + An entry in the vector must have a corresponding entry + in the metadata map, while an entry in the metadata + map may not have an entry in the vector (denoted by a + NULL in the meta_t value ptr). */ + +/* Full gossip value representation. Stores the encoded + form of a CRDS value and other metadata. */ +struct fd_value { + fd_hash_t key; /* Hash of the value data */ + ulong wallclock; /* Original timestamp of value in millis */ + fd_pubkey_t origin; /* Where did this value originate */ + uchar data[PACKET_DATA_SIZE]; /* Serialized form of value (bincode) including signature */ + ulong datalen; +}; + +typedef struct fd_value fd_value_t; + +/* Value vector that: + - backs the values pointed by fd_value_meta_t->value + - is used in generating push and pullresp + messages */ +#define VEC_NAME fd_value_vec +#define VEC_T fd_value_t +#include "../../util/tmpl/fd_vec.c" + +/* Minimized form of fd_value that only holds metadata */ +struct fd_value_meta { + fd_hash_t key; /* Hash of the value data, also functions as map key */ + ulong wallclock; /* Timestamp of value (millis) */ + fd_value_t * value; /* Pointer to the actual value element (backed by the value vector) */ + ulong next; }; -/* Value table */ -typedef struct fd_value_elem fd_value_elem_t; -#define MAP_NAME fd_value_table +typedef struct fd_value_meta fd_value_meta_t; + +/* Value map, holds hashes of processed CRDS entries. + Used in pull request generation and de-duplication. + Also holds pointer to corresponding element in + value vec, if available. */ +#define MAP_NAME fd_value_meta_map #define MAP_KEY_T fd_hash_t #define MAP_KEY_EQ fd_hash_eq #define MAP_KEY_HASH fd_hash_hash #define MAP_KEY_COPY fd_hash_copy -#define MAP_T fd_value_elem_t +#define MAP_T fd_value_meta_t #include "../../util/tmpl/fd_map_giant.c" /* Weights table element. This table stores the weight for each peer @@ -359,8 +396,9 @@ struct fd_gossip { ulong inactives_cnt; #define INACTIVES_MAX 1024U - /* Table of crds values that we have received in the last 60 minutes, keys by hash */ - fd_value_elem_t * values; + /* Table of crds metadata, keyed by hash of the encoded data */ + fd_value_meta_t * value_metas; + fd_value_t * values; /* Vector of full values */ /* The last timestamp that we pushed our own contact info */ long last_contact_time; fd_hash_t last_contact_info_v2_key; @@ -369,8 +407,8 @@ struct fd_gossip { fd_push_state_t * push_states[FD_PUSH_LIST_MAX]; ulong push_states_cnt; fd_push_state_t * push_states_pool; - /* Queue of values that need pushing */ - fd_hash_t * need_push; + /* Queue of values vec ptrs that need pushing */ + fd_value_t * * need_push; ulong need_push_head; ulong need_push_cnt; @@ -423,8 +461,9 @@ fd_gossip_footprint( void ) { l = FD_LAYOUT_APPEND( l, fd_peer_table_align(), fd_peer_table_footprint(FD_PEER_KEY_MAX) ); l = FD_LAYOUT_APPEND( l, fd_active_table_align(), fd_active_table_footprint(FD_ACTIVE_KEY_MAX) ); l = FD_LAYOUT_APPEND( l, alignof(fd_gossip_peer_addr_t), INACTIVES_MAX*sizeof(fd_gossip_peer_addr_t) ); - l = FD_LAYOUT_APPEND( l, alignof(fd_hash_t), FD_NEED_PUSH_MAX*sizeof(fd_hash_t) ); - l = FD_LAYOUT_APPEND( l, fd_value_table_align(), fd_value_table_footprint(FD_VALUE_KEY_MAX) ); + l = FD_LAYOUT_APPEND( l, alignof(fd_value_t *), FD_NEED_PUSH_MAX*sizeof(fd_value_t *) ); + l = FD_LAYOUT_APPEND( l, fd_value_meta_map_align(), fd_value_meta_map_footprint( FD_VALUE_KEY_MAX ) ); + l = FD_LAYOUT_APPEND( l, fd_value_vec_align(), fd_value_vec_footprint( FD_VALUE_DATA_MAX ) ); l = FD_LAYOUT_APPEND( l, fd_pending_heap_align(), fd_pending_heap_footprint(FD_PENDING_MAX) ); l = FD_LAYOUT_APPEND( l, fd_stats_table_align(), fd_stats_table_footprint(FD_STATS_KEY_MAX) ); l = FD_LAYOUT_APPEND( l, fd_weights_table_align(), fd_weights_table_footprint(MAX_STAKE_WEIGHTS) ); @@ -450,10 +489,13 @@ fd_gossip_new ( void * shmem, ulong seed ) { glob->actives = fd_active_table_join(fd_active_table_new(shm, FD_ACTIVE_KEY_MAX, seed)); glob->inactives = (fd_gossip_peer_addr_t*)FD_SCRATCH_ALLOC_APPEND(l, alignof(fd_gossip_peer_addr_t), INACTIVES_MAX*sizeof(fd_gossip_peer_addr_t)); - glob->need_push = (fd_hash_t*)FD_SCRATCH_ALLOC_APPEND(l, alignof(fd_hash_t), FD_NEED_PUSH_MAX*sizeof(fd_hash_t)); + glob->need_push = (fd_value_t * *)FD_SCRATCH_ALLOC_APPEND(l, alignof(fd_value_t *), FD_NEED_PUSH_MAX*sizeof(fd_value_t *)); + + shm = FD_SCRATCH_ALLOC_APPEND( l, fd_value_meta_map_align(), fd_value_meta_map_footprint( FD_VALUE_KEY_MAX ) ); + glob->value_metas = fd_value_meta_map_join( fd_value_meta_map_new( shm, FD_VALUE_KEY_MAX, seed ) ); - shm = FD_SCRATCH_ALLOC_APPEND(l, fd_value_table_align(), fd_value_table_footprint(FD_VALUE_KEY_MAX)); - glob->values = fd_value_table_join(fd_value_table_new(shm, FD_VALUE_KEY_MAX, seed)); + shm = FD_SCRATCH_ALLOC_APPEND( l, fd_value_vec_align(), fd_value_vec_footprint( FD_VALUE_DATA_MAX ) ); + glob->values = fd_value_vec_join( fd_value_vec_new( shm, FD_VALUE_DATA_MAX ) ); glob->last_contact_time = 0; @@ -489,7 +531,8 @@ fd_gossip_delete ( void * shmap ) { fd_peer_table_delete( fd_peer_table_leave( glob->peers ) ); fd_active_table_delete( fd_active_table_leave( glob->actives ) ); - fd_value_table_delete( fd_value_table_leave( glob->values ) ); + fd_value_meta_map_delete( fd_value_meta_map_leave( glob->value_metas ) ); + fd_value_vec_delete( fd_value_vec_leave( glob->values ) ); fd_pending_heap_delete( fd_pending_heap_leave( glob->event_heap ) ); fd_stats_table_delete( fd_stats_table_leave( glob->stats ) ); fd_weights_table_delete( fd_weights_table_leave( glob->weights ) ); @@ -1125,7 +1168,7 @@ fd_gossip_random_pull( fd_gossip_t * glob, fd_pending_event_arg_t * arg ) { /* Compute the number of packets needed for all the bloom filter parts with a desired false positive rate <0.1% (upper bounded by FD_BLOOM_MAX_PACKETS ) */ - ulong nitems = fd_value_table_key_cnt(glob->values); + ulong nitems = fd_value_meta_map_key_cnt( glob->value_metas ); ulong nkeys = 1; ulong npackets = 1; uint nmaskbits = 0; @@ -1199,14 +1242,16 @@ fd_gossip_random_pull( fd_gossip_t * glob, fd_pending_event_arg_t * arg ) { ulong bits[CHUNKSIZE * FD_BLOOM_MAX_PACKETS]; /* TODO: can we bound size based on sample rate instead? */ fd_memset(bits, 0, CHUNKSIZE*8U*npackets); ulong expire = FD_NANOSEC_TO_MILLI(glob->now) - FD_GOSSIP_VALUE_EXPIRE; - for( fd_value_table_iter_t iter = fd_value_table_iter_init( glob->values ); - !fd_value_table_iter_done( glob->values, iter ); - iter = fd_value_table_iter_next( glob->values, iter ) ) { - fd_value_elem_t * ele = fd_value_table_iter_ele( glob->values, iter ); + for( fd_value_meta_map_iter_t iter = fd_value_meta_map_iter_init( glob->value_metas ); + !fd_value_meta_map_iter_done( glob->value_metas, iter ); + iter = fd_value_meta_map_iter_next( glob->value_metas, iter ) ) { + fd_value_meta_t * ele = fd_value_meta_map_iter_ele( glob->value_metas, iter ); fd_hash_t * hash = &(ele->key); - /* Purge expired values */ - if (ele->wallclock < expire) { - fd_value_table_remove( glob->values, hash ); + + /* Purge expired value's data entry */ + if (ele->wallclock < expire && ele->value != NULL) { + fd_value_vec_remove_ele( glob->values, ele->value ); + ele->value = NULL; continue; } /* Choose which filter packet based on the high bits in the hash, @@ -1377,15 +1422,6 @@ fd_gossip_random_ping( fd_gossip_t * glob, fd_pending_event_arg_t * arg ) { /* CRDS processing utils. TODO: move to a separate fd_crds file? Need to decouple gossip metrics first */ -typedef struct{ - fd_crds_value_t * crd; // Decoded CRDS value - uchar encoded_val[PACKET_DATA_SIZE]; // Raw encoded form - ulong encoded_len; // Length of encoded data - fd_hash_t val_hash; // Hash of the value (used as key in the value table) - fd_pubkey_t* pubkey; // Reference to origin's pubkey - ulong wallclock; // Timestamp -} fd_crds_value_processed_t; - /* fd_crds_dedup_check returns 1 if key exists in the CRDS value table, 0 otherwise. Also logs the - the host that sent the duplicate message @@ -1393,20 +1429,20 @@ typedef struct{ for use in making prune messages. */ static int fd_crds_dup_check( fd_gossip_t * glob, fd_hash_t * key, const fd_gossip_peer_addr_t * from, const fd_pubkey_t * origin ) { - fd_value_elem_t * msg = fd_value_table_query(glob->values, key, NULL); + fd_value_meta_t * msg = fd_value_meta_map_query( glob->value_metas, key, NULL ); - if (msg != NULL) { + if( msg!=NULL ) { /* Already have this value */ - if (from != NULL) { + if( from!=NULL ) { /* Record the dup in the receive statistics table */ fd_stats_elem_t * val = fd_stats_table_query(glob->stats, from, NULL); - if (val == NULL) { + if( val==NULL ) { if (!fd_stats_table_is_full(glob->stats)) { val = fd_stats_table_insert(glob->stats, from); val->dups_cnt = 0; } } - if (val != NULL) { + if( val!=NULL ) { val->last = glob->now; for (ulong i = 0; i < val->dups_cnt; ++i){ if (fd_hash_eq(&val->dups[i].origin, origin)) { @@ -1414,7 +1450,7 @@ fd_crds_dup_check( fd_gossip_t * glob, fd_hash_t * key, const fd_gossip_peer_add goto found_origin; } } - if (val->dups_cnt < 8) { + if( val->dups_cnt<8 ) { ulong i = val->dups_cnt++; fd_hash_copy(&val->dups[i].origin, origin); val->dups[i].cnt = 1; @@ -1451,27 +1487,6 @@ fd_crds_sigverify( uchar * crds_encoded_val, ulong crds_encoded_len, fd_pubkey_t #define INC_RECV_CRDS_DROP_METRIC( REASON ) glob->metrics.recv_crds_drop_reason[ FD_CONCAT3( FD_METRICS_ENUM_CRDS_DROP_REASON_V_, REASON, _IDX ) ] += 1UL -/* fd_crds_insert sets up and inserts a fd_value_elem_t entry - from a fully populated crd_p. - - This only fails if the table is full. */ -static void -fd_crds_insert( fd_gossip_t * glob, fd_crds_value_processed_t * crd_p ) { - if( FD_UNLIKELY( fd_value_table_is_full( glob->values ) ) ) { - INC_RECV_CRDS_DROP_METRIC( TABLE_FULL ); - FD_LOG_DEBUG(( "too many values" )); - return; - } - - fd_value_elem_t * ele = fd_value_table_insert(glob->values, &crd_p->val_hash ); - ele->wallclock = crd_p->wallclock; - fd_hash_copy( &ele->origin, crd_p->pubkey ); - - /* Store encoded form of full CRDS value (including signature) */ - fd_memcpy( ele->data, crd_p->encoded_val, crd_p->encoded_len ); - ele->datalen = crd_p->encoded_len; -} - /* fd_gossip_recv_crds_array processes crds_len crds values. First performs a filter pass, dropping duplicate/own values and exiting* on any sigverify failures. Then inserts the filtered @@ -1488,83 +1503,91 @@ fd_gossip_recv_crds_array( fd_gossip_t * glob, const fd_gossip_peer_addr_t * fro if( FD_UNLIKELY( crds_len > FD_GOSSIP_MAX_CRDS_VALS ) ) { FD_LOG_ERR(( "too many CRDS values, max %u vs %lu received", FD_GOSSIP_MAX_CRDS_VALS, crds_len )); } - fd_crds_value_processed_t filtered_crds[FD_GOSSIP_MAX_CRDS_VALS]; - ulong num_filtered_crds = 0; + + if( FD_UNLIKELY( fd_value_vec_cnt( glob->values ) + crds_len > fd_value_vec_max( glob->values ))){ + INC_RECV_CRDS_DROP_METRIC( TABLE_FULL ); + FD_LOG_DEBUG(( "too many values" )); + return; + } + fd_value_t * retained_vals = fd_value_vec_expand( glob->values, crds_len ); + fd_crds_value_t * retained_crds[FD_GOSSIP_MAX_CRDS_VALS]; /* store pointers to decoded crds entries we retain */ + ulong num_retained_crds = 0; /* OK to reuse since sha256_init is called in every iteration */ fd_sha256_t sha2[1]; - /* Filter pass */ + /**************** Filter pass ******************/ for( ulong i = 0; i < crds_len; ++i ) { - fd_crds_value_processed_t * tmp = &filtered_crds[ num_filtered_crds ]; /* This will overwrite if previous value was dedup, should be safe */ - tmp->crd = &crds[ i ]; + fd_value_t * val = &retained_vals[ num_retained_crds ]; /* This will overwrite if previous value was filtered, should be safe */ + fd_crds_value_t * crd = &crds[ i ]; + retained_crds[ num_retained_crds ] = crd; /* for use in insert pass */ /* Setup fd_crds_value_processed_t entry */ - switch (tmp->crd->data.discriminant) { + switch( crd->data.discriminant ) { case fd_crds_data_enum_contact_info_v1: - tmp->pubkey = &tmp->crd->data.inner.contact_info_v1.id; - tmp->wallclock = tmp->crd->data.inner.contact_info_v1.wallclock; + val->origin = crd->data.inner.contact_info_v1.id; + val->wallclock = crd->data.inner.contact_info_v1.wallclock; break; case fd_crds_data_enum_vote: - tmp->pubkey = &tmp->crd->data.inner.vote.from; - tmp->wallclock = tmp->crd->data.inner.vote.wallclock; + val->origin = crd->data.inner.vote.from; + val->wallclock = crd->data.inner.vote.wallclock; break; case fd_crds_data_enum_lowest_slot: - tmp->pubkey = &tmp->crd->data.inner.lowest_slot.from; - tmp->wallclock = tmp->crd->data.inner.lowest_slot.wallclock; + val->origin = crd->data.inner.lowest_slot.from; + val->wallclock = crd->data.inner.lowest_slot.wallclock; break; case fd_crds_data_enum_snapshot_hashes: - tmp->pubkey = &tmp->crd->data.inner.snapshot_hashes.from; - tmp->wallclock = tmp->crd->data.inner.snapshot_hashes.wallclock; + val->origin = crd->data.inner.snapshot_hashes.from; + val->wallclock = crd->data.inner.snapshot_hashes.wallclock; break; case fd_crds_data_enum_accounts_hashes: - tmp->pubkey = &tmp->crd->data.inner.accounts_hashes.from; - tmp->wallclock = tmp->crd->data.inner.accounts_hashes.wallclock; + val->origin = crd->data.inner.accounts_hashes.from; + val->wallclock = crd->data.inner.accounts_hashes.wallclock; break; case fd_crds_data_enum_epoch_slots: - tmp->pubkey = &tmp->crd->data.inner.epoch_slots.from; - tmp->wallclock = tmp->crd->data.inner.epoch_slots.wallclock; + val->origin = crd->data.inner.epoch_slots.from; + val->wallclock = crd->data.inner.epoch_slots.wallclock; break; case fd_crds_data_enum_version_v1: - tmp->pubkey = &tmp->crd->data.inner.version_v1.from; - tmp->wallclock = tmp->crd->data.inner.version_v1.wallclock; + val->origin = crd->data.inner.version_v1.from; + val->wallclock = crd->data.inner.version_v1.wallclock; break; case fd_crds_data_enum_version_v2: - tmp->pubkey = &tmp->crd->data.inner.version_v2.from; - tmp->wallclock = tmp->crd->data.inner.version_v2.wallclock; + val->origin = crd->data.inner.version_v2.from; + val->wallclock = crd->data.inner.version_v2.wallclock; break; case fd_crds_data_enum_node_instance: - tmp->pubkey = &tmp->crd->data.inner.node_instance.from; - tmp->wallclock = tmp->crd->data.inner.node_instance.wallclock; + val->origin = crd->data.inner.node_instance.from; + val->wallclock = crd->data.inner.node_instance.wallclock; break; case fd_crds_data_enum_duplicate_shred: - tmp->pubkey = &tmp->crd->data.inner.duplicate_shred.from; - tmp->wallclock = tmp->crd->data.inner.duplicate_shred.wallclock; + val->origin = crd->data.inner.duplicate_shred.from; + val->wallclock = crd->data.inner.duplicate_shred.wallclock; break; case fd_crds_data_enum_incremental_snapshot_hashes: - tmp->pubkey = &tmp->crd->data.inner.incremental_snapshot_hashes.from; - tmp->wallclock = tmp->crd->data.inner.incremental_snapshot_hashes.wallclock; + val->origin = crd->data.inner.incremental_snapshot_hashes.from; + val->wallclock = crd->data.inner.incremental_snapshot_hashes.wallclock; break; case fd_crds_data_enum_contact_info_v2: - tmp->pubkey = &tmp->crd->data.inner.contact_info_v2.from; - tmp->wallclock = tmp->crd->data.inner.contact_info_v2.wallclock; + val->origin = crd->data.inner.contact_info_v2.from; + val->wallclock = crd->data.inner.contact_info_v2.wallclock; break; case fd_crds_data_enum_restart_last_voted_fork_slots: - tmp->pubkey = &tmp->crd->data.inner.restart_last_voted_fork_slots.from; - tmp->wallclock = tmp->crd->data.inner.restart_last_voted_fork_slots.wallclock; + val->origin = crd->data.inner.restart_last_voted_fork_slots.from; + val->wallclock = crd->data.inner.restart_last_voted_fork_slots.wallclock; break; case fd_crds_data_enum_restart_heaviest_fork: - tmp->pubkey = &tmp->crd->data.inner.restart_heaviest_fork.from; - tmp->wallclock = tmp->crd->data.inner.restart_heaviest_fork.wallclock; + val->origin = crd->data.inner.restart_heaviest_fork.from; + val->wallclock = crd->data.inner.restart_heaviest_fork.wallclock; break; default: INC_RECV_CRDS_DROP_METRIC( UNKNOWN_DISCRIMINANT ); return; } - glob->metrics.recv_crds[ route ][ tmp->crd->data.discriminant ] += 1UL; + glob->metrics.recv_crds[ route ][ crd->data.discriminant ] += 1UL; - if (memcmp(tmp->pubkey->uc, glob->public_key->uc, 32U) == 0) { + if( memcmp( val->origin.uc, glob->public_key->uc, 32U )==0 ) { /* skip my own messages */ INC_RECV_CRDS_DROP_METRIC( OWN_MESSAGE ); continue; @@ -1572,27 +1595,27 @@ fd_gossip_recv_crds_array( fd_gossip_t * glob, const fd_gossip_peer_addr_t * fro /* Encode */ fd_bincode_encode_ctx_t ctx; - ctx.data = tmp->encoded_val; - ctx.dataend = tmp->encoded_val + PACKET_DATA_SIZE; - if ( fd_crds_value_encode( tmp->crd, &ctx ) ) { + ctx.data = val->data; + ctx.dataend = val->data + PACKET_DATA_SIZE; + if( fd_crds_value_encode( crd, &ctx ) ) { FD_LOG_ERR(("fd_crds_value_encode failed")); } - tmp->encoded_len = (ulong)((uchar *)ctx.data - tmp->encoded_val); + val->datalen = (ulong)((uchar *)ctx.data - val->data); /* Get hash */ fd_sha256_init( sha2 ); - fd_sha256_append( sha2, tmp->encoded_val, tmp->encoded_len ); - fd_sha256_fini( sha2, tmp->val_hash.uc ); + fd_sha256_append( sha2, val->data, val->datalen ); + fd_sha256_fini( sha2, val->key.uc ); - fd_msg_stats_elem_t * msg_stat = &glob->msg_stats[ tmp->crd->data.discriminant ]; + fd_msg_stats_elem_t * msg_stat = &glob->msg_stats[ crd->data.discriminant ]; msg_stat->total_cnt++; - msg_stat->bytes_rx_cnt += tmp->encoded_len; + msg_stat->bytes_rx_cnt += val->datalen; /* Dedup first */ - if ( fd_crds_dup_check( glob, &tmp->val_hash, from, tmp->pubkey ) ) { + if ( fd_crds_dup_check( glob, &val->key, from, &val->origin ) ) { msg_stat->dups_cnt++; glob->recv_dup_cnt++; - glob->metrics.recv_crds_duplicate_message[ route ][ tmp->crd->data.discriminant ]++; + glob->metrics.recv_crds_duplicate_message[ route ][ crd->data.discriminant ]++; continue; /* skip this entry */ } @@ -1600,38 +1623,55 @@ fd_gossip_recv_crds_array( fd_gossip_t * glob, const fd_gossip_peer_addr_t * fro /* Sigverify step Skip verifying epoch slots because they: - are not used anywhere within the client - - still store them in table for forwarding + - prune message construction + - still store them in table for forwarding - represent a significant portion of inbound CRDS - traffic (~90%) + traffic (~50%) - will be deprecated soon */ - if( tmp->crd->data.discriminant != fd_crds_data_enum_epoch_slots && - fd_crds_sigverify( tmp->encoded_val, tmp->encoded_len, tmp->pubkey ) ) { + if( crd->data.discriminant!=fd_crds_data_enum_epoch_slots && + fd_crds_sigverify( val->data, val->datalen, &val->origin ) ) { INC_RECV_CRDS_DROP_METRIC( INVALID_SIGNATURE ); /* drop full packet on bad signature https://github.com/anza-xyz/agave/commit/d68b5de6c0fc07d60cf9749ae82c2651a549e81b */ + fd_value_vec_contract( glob->values, crds_len ); return; } - num_filtered_crds++; + num_retained_crds++; } - /* Insert pass */ - for( ulong i = 0; i < num_filtered_crds; ++i ) { - fd_crds_value_processed_t * crd_p = &filtered_crds[ i ]; - fd_crds_insert( glob, crd_p ); + /* Contract vector by number of values not retained */ + fd_value_vec_contract( glob->values, crds_len - num_retained_crds ); + + /**************** Insert pass ****************/ + for( ulong i = 0; i < num_retained_crds; ++i ) { + fd_value_t * val = &retained_vals[ i ]; + /* Technically not needed, len(value_key_map) >>> len(values) */ + if( FD_UNLIKELY( fd_value_meta_map_is_full( glob->value_metas ) ) ) { + INC_RECV_CRDS_DROP_METRIC( TABLE_FULL ); + FD_LOG_DEBUG(( "too many values" )); + fd_value_vec_contract( glob->values, num_retained_crds ); + return; + } + + /* Insert into the value set (duplicate check performed in filter pass) */ + fd_value_meta_t * ele = fd_value_meta_map_insert( glob->value_metas, &val->key ); + + ele->key = val->key; + ele->value = val; + ele->wallclock = val->wallclock; if ( FD_UNLIKELY( glob->need_push_cnt < FD_NEED_PUSH_MAX ) ) { /* Remember that I need to push this value */ ulong i = ((glob->need_push_head + (glob->need_push_cnt++)) & (FD_NEED_PUSH_MAX-1U)); - fd_hash_copy(glob->need_push + i, &crd_p->val_hash); + /* TODO: change this to vector idx/ptrs? */ + glob->need_push[ i ] = val; glob->metrics.push_crds_queue_cnt = glob->need_push_cnt; } else { INC_RECV_CRDS_DROP_METRIC( PUSH_QUEUE_FULL ); } - fd_crds_value_t * crd = crd_p->crd; + fd_crds_value_t * crd = retained_crds[ i ]; - if (crd->data.discriminant == fd_crds_data_enum_contact_info_v2) { + if( crd->data.discriminant==fd_crds_data_enum_contact_info_v2 ) { fd_gossip_contact_info_v2_t * info = &crd->data.inner.contact_info_v2; fd_gossip_socket_addr_t socket_addr; if( fd_gossip_contact_info_v2_find_proto_ident( info, FD_GOSSIP_SOCKET_TAG_GOSSIP, &socket_addr ) ) { @@ -1639,28 +1679,28 @@ fd_gossip_recv_crds_array( fd_gossip_t * glob, const fd_gossip_peer_addr_t * fro fd_gossip_socket_addr_is_ip4( &socket_addr ) ) { /* Only support ipv4 */ /* Remember the peer */ fd_gossip_peer_addr_t pkey; - fd_memset(&pkey, 0, sizeof(pkey)); - fd_gossip_from_soladdr(&pkey, &socket_addr); - fd_peer_elem_t * val = fd_peer_table_query(glob->peers, &pkey, NULL); - if (val == NULL) { - if (fd_peer_table_is_full(glob->peers)) { + fd_memset( &pkey, 0, sizeof(pkey) ); + fd_gossip_from_soladdr( &pkey, &socket_addr ); + fd_peer_elem_t * peer = fd_peer_table_query( glob->peers, &pkey, NULL ); + if( peer==NULL ) { + if(fd_peer_table_is_full( glob->peers ) ) { INC_RECV_CRDS_DROP_METRIC( PEER_TABLE_FULL ); - FD_LOG_DEBUG(("too many peers")); + FD_LOG_DEBUG(( "too many peers" )); } else { - val = fd_peer_table_insert(glob->peers, &pkey); + peer = fd_peer_table_insert( glob->peers, &pkey ); - if ( glob->inactives_cnt >= INACTIVES_MAX ) { + if( glob->inactives_cnt>=INACTIVES_MAX ) { INC_RECV_CRDS_DROP_METRIC( INACTIVES_QUEUE_FULL ); - } else if ( fd_active_table_query(glob->actives, &pkey, NULL) == NULL ) { + } else if( fd_active_table_query( glob->actives, &pkey, NULL )==NULL ) { /* Queue this peer for later pinging */ - fd_gossip_peer_addr_copy(glob->inactives + (glob->inactives_cnt++), &pkey); + fd_gossip_peer_addr_copy( glob->inactives + (glob->inactives_cnt++), &pkey ); } } } - if (val != NULL) { - val->wallclock = crd_p->wallclock; - val->stake = 0; - fd_hash_copy(&val->id, &info->from); + if( peer!=NULL ) { + peer->wallclock = val->wallclock; + peer->stake = 0; + fd_hash_copy( &peer->id, &info->from ); } else { INC_RECV_CRDS_DROP_METRIC( DISCARDED_PEER ); } @@ -1669,18 +1709,21 @@ fd_gossip_recv_crds_array( fd_gossip_t * glob, const fd_gossip_peer_addr_t * fro fd_gossip_peer_addr_t peer_addr = { .addr = socket_addr.inner.ip4.addr, /* FIXME: hardcode to ip4 inner? */ .port = fd_ushort_bswap( fd_gossip_port_from_socketaddr( &socket_addr ) ) }; - if (glob->my_contact.ci->shred_version == 0U && fd_gossip_is_allowed_entrypoint( glob, &peer_addr )) { - FD_LOG_NOTICE(("using shred version %lu", (ulong)crd->data.inner.contact_info_v2.shred_version)); + if( glob->my_contact.ci->shred_version==0U && + fd_gossip_is_allowed_entrypoint( glob, &peer_addr ) ) { + FD_LOG_NOTICE(( "using shred version %lu", (ulong)crd->data.inner.contact_info_v2.shred_version )); glob->my_contact.ci->shred_version = crd->data.inner.contact_info_v2.shred_version; } } } glob->metrics.gossip_peer_cnt[ FD_METRICS_ENUM_GOSSIP_PEER_STATE_V_INACTIVE_IDX ] = glob->inactives_cnt; + glob->metrics.value_meta_cnt = fd_value_meta_map_key_cnt( glob->value_metas ); + glob->metrics.value_vec_cnt = fd_value_vec_cnt( glob->values ); /* Deliver the data upstream */ fd_gossip_unlock( glob ); - (*glob->deliver_fun)(&crd->data, glob->deliver_arg); + (*glob->deliver_fun)( &crd->data, glob->deliver_arg ); fd_gossip_lock( glob ); } @@ -1791,22 +1834,23 @@ fd_gossip_push_value_nolock( fd_gossip_t * glob, fd_crds_data_t * data, fd_hash_ static void fd_gossip_push_updated_contact(fd_gossip_t * glob) { /* See if we have a shred version yet */ - if (glob->my_contact.ci->shred_version == 0U) + if( glob->my_contact.ci->shred_version==0U ) return; /* Update every 1 secs */ - if (glob->now - glob->last_contact_time < (long)1e9) + if( (glob->now - glob->last_contact_time)<(long)1e9 ) return; if (glob->last_contact_time != 0) { - fd_value_elem_t * ele = fd_value_table_query(glob->values, &glob->last_contact_info_v2_key, NULL); + fd_value_meta_t * ele = fd_value_meta_map_query(glob->value_metas, &glob->last_contact_info_v2_key, NULL); if (ele != NULL) { - fd_value_table_remove( glob->values, &glob->last_contact_info_v2_key ); + fd_value_vec_remove_ele( glob->values, ele->value ); /* Remove the old value from the vector */ + fd_value_meta_map_remove( glob->value_metas, &glob->last_contact_info_v2_key ); } } glob->last_contact_time = glob->now; - glob->my_contact.ci->wallclock = FD_NANOSEC_TO_MILLI(glob->now); - fd_gossip_push_value_nolock(glob, &glob->my_contact.crd, &glob->last_contact_info_v2_key); + glob->my_contact.ci->wallclock = FD_NANOSEC_TO_MILLI( glob->now ); + fd_gossip_push_value_nolock( glob, &glob->my_contact.crd, &glob->last_contact_info_v2_key ); } /* Respond to a pull request */ @@ -1866,10 +1910,8 @@ fd_gossip_handle_pull_req(fd_gossip_t * glob, const fd_gossip_peer_addr_t * from ulong hits = 0; ulong misses = 0; uint npackets = 0; - for( fd_value_table_iter_t iter = fd_value_table_iter_init( glob->values ); - !fd_value_table_iter_done( glob->values, iter ); - iter = fd_value_table_iter_next( glob->values, iter ) ) { - fd_value_elem_t * ele = fd_value_table_iter_ele( glob->values, iter ); + for( ulong i = 0UL; i < fd_value_vec_cnt( glob->values ); ++i ) { + fd_value_t * ele = &glob->values[ i ]; fd_hash_t * hash = &(ele->key); if (ele->wallclock < expire) continue; @@ -2083,30 +2125,29 @@ fd_gossip_push( fd_gossip_t * glob, fd_pending_event_arg_t * arg ) { /* Iterate across recent values */ ulong expire = FD_NANOSEC_TO_MILLI(glob->now) - FD_GOSSIP_PULL_TIMEOUT; while (glob->need_push_cnt > 0) { - fd_hash_t * h = glob->need_push + ((glob->need_push_head++) & (FD_NEED_PUSH_MAX-1)); + fd_value_t * msg = glob->need_push[ ((glob->need_push_head++) & (FD_NEED_PUSH_MAX-1)) ]; glob->need_push_cnt--; - fd_value_elem_t * msg = fd_value_table_query(glob->values, h, NULL); - if (msg == NULL || msg->wallclock < expire) + if( msg->wallclockpush_states_cnt && npush < FD_PUSH_VALUE_MAX; ++i) { + for( ulong i = 0; ipush_states_cnt && npushpush_states[i]; /* Apply the pruning bloom filter */ int pass = 0; - for (ulong j = 0; j < FD_PRUNE_NUM_KEYS; ++j) { - ulong pos = fd_gossip_bloom_pos(&msg->origin, s->prune_keys[j], FD_PRUNE_NUM_BITS); + for( ulong j = 0; jorigin, s->prune_keys[j], FD_PRUNE_NUM_BITS ); ulong * j = s->prune_bits + (pos>>6U); /* divide by 64 */ ulong bit = 1UL<<(pos & 63U); - if (!(*j & bit)) { + if( !(*j & bit) ) { pass = 1; break; } } - if (!pass) { + if( !pass ) { s->drop_cnt++; glob->not_push_cnt++; continue; @@ -2117,30 +2158,30 @@ fd_gossip_push( fd_gossip_t * glob, fd_pending_event_arg_t * arg ) { ulong * crds_len = (ulong *)(s->packet_end_init - sizeof(ulong)); /* Add the value in already encoded form */ - if (s->packet_end + msg->datalen - s->packet > PACKET_DATA_SIZE) { + if( (s->packet_end + msg->datalen - s->packet)>PACKET_DATA_SIZE ) { /* Packet is getting too large. Flush it */ ulong sz = (ulong)(s->packet_end - s->packet); glob->metrics.send_message[ FD_METRICS_ENUM_GOSSIP_MESSAGE_V_PUSH_IDX ]++; - fd_gossip_send_raw(glob, &s->addr, s->packet, sz); + fd_gossip_send_raw( glob, &s->addr, s->packet, sz ); FD_LOG_DEBUG(("push to " GOSSIP_ADDR_FMT " size=%lu", GOSSIP_ADDR_FMT_ARGS( s->addr ), sz)); s->packet_end = s->packet_end_init; *crds_len = 0; } - fd_memcpy(s->packet_end, msg->data, msg->datalen); + fd_memcpy( s->packet_end, msg->data, msg->datalen ); s->packet_end += msg->datalen; (*crds_len)++; } } /* Flush partially full packets */ - for (ulong i = 0; i < glob->push_states_cnt; ++i) { + for( ulong i = 0; i < glob->push_states_cnt; ++i ) { fd_push_state_t* s = glob->push_states[i]; - if (s->packet_end != s->packet_end_init) { + if ( s->packet_end != s->packet_end_init ) { ulong * crds_len = (ulong *)(s->packet_end_init - sizeof(ulong)); ulong sz = (ulong)(s->packet_end - s->packet); - fd_gossip_send_raw(glob, &s->addr, s->packet, sz); + fd_gossip_send_raw( glob, &s->addr, s->packet, sz ); glob->metrics.send_message[ FD_METRICS_ENUM_GOSSIP_MESSAGE_V_PUSH_IDX ]++; - FD_LOG_DEBUG(("push to " GOSSIP_ADDR_FMT " size=%lu", GOSSIP_ADDR_FMT_ARGS( s->addr ), sz)); + FD_LOG_DEBUG(( "push to " GOSSIP_ADDR_FMT " size=%lu", GOSSIP_ADDR_FMT_ARGS( s->addr ), sz )); s->packet_end = s->packet_end_init; *crds_len = 0; } @@ -2153,7 +2194,7 @@ fd_gossip_push_value_nolock( fd_gossip_t * glob, fd_crds_data_t * data, fd_hash_ #define INC_PUSH_CRDS_DROP_METRIC( REASON ) \ glob->metrics.push_crds_drop_reason[ FD_CONCAT3( FD_METRICS_ENUM_CRDS_DROP_REASON_V_, REASON , _IDX ) ] += 1UL - if ( FD_UNLIKELY( data->discriminant >= FD_KNOWN_CRDS_ENUM_MAX ) ) { + if( FD_UNLIKELY( data->discriminant >= FD_KNOWN_CRDS_ENUM_MAX ) ) { INC_PUSH_CRDS_DROP_METRIC( UNKNOWN_DISCRIMINANT ); return -1; } @@ -2169,9 +2210,9 @@ fd_gossip_push_value_nolock( fd_gossip_t * glob, fd_crds_data_t * data, fd_hash_ fd_bincode_encode_ctx_t ctx; ctx.data = buf; ctx.dataend = buf + PACKET_DATA_SIZE; - if ( fd_crds_value_encode( &crd, &ctx ) ) { + if( fd_crds_value_encode( &crd, &ctx ) ) { INC_PUSH_CRDS_DROP_METRIC( ENCODING_FAILED ); - FD_LOG_ERR(("fd_crds_value_encode failed")); + FD_LOG_ERR(( "fd_crds_value_encode failed" )); return -1; } fd_sha256_t sha2[1]; @@ -2180,12 +2221,12 @@ fd_gossip_push_value_nolock( fd_gossip_t * glob, fd_crds_data_t * data, fd_hash_ fd_sha256_append( sha2, buf, datalen ); fd_hash_t key; fd_sha256_fini( sha2, key.uc ); - if ( key_opt != NULL ) + if( key_opt != NULL ) fd_hash_copy( key_opt, &key ); /* Store the value for later pushing/duplicate detection */ - fd_value_elem_t * msg = fd_value_table_query(glob->values, &key, NULL); - if (msg != NULL) { + fd_value_meta_t * ele = fd_value_meta_map_query( glob->value_metas, &key, NULL ); + if( ele != NULL ) { /* Already have this value, which is strange! NOTE: This is a different list from duplicate crds values received from the network (see metrics.recv_crds_duplicate_message). @@ -2194,23 +2235,29 @@ fd_gossip_push_value_nolock( fd_gossip_t * glob, fd_crds_data_t * data, fd_hash_ glob->metrics.push_crds_duplicate[ data->discriminant ] += 1UL; return -1; } - if (fd_value_table_is_full(glob->values)) { + if( fd_value_meta_map_is_full( glob->value_metas ) || fd_value_vec_is_full( glob->values ) ) { INC_PUSH_CRDS_DROP_METRIC( TABLE_FULL ); FD_LOG_DEBUG(("too many values")); return -1; } - msg = fd_value_table_insert(glob->values, &key); - msg->wallclock = FD_NANOSEC_TO_MILLI(glob->now); /* convert to ms */ - fd_hash_copy(&msg->origin, glob->public_key); + fd_value_t * val = fd_value_vec_expand( glob->values, 1UL ); + ele = fd_value_meta_map_insert( glob->value_metas, &key ); + + ele->value = val; /* Store the pointer to the value element */ + ele->wallclock = FD_NANOSEC_TO_MILLI( glob->now ); + + val->key = key; + val->wallclock = ele->wallclock; + val->origin = *glob->public_key; /* We store the serialized form for convenience */ - fd_memcpy(msg->data, buf, datalen); - msg->datalen = datalen; + fd_memcpy( val->data, buf, datalen ); + val->datalen = datalen; if (glob->need_push_cnt < FD_NEED_PUSH_MAX) { /* Remember that I need to push this value */ ulong i = ((glob->need_push_head + (glob->need_push_cnt++)) & (FD_NEED_PUSH_MAX-1U)); - fd_hash_copy(glob->need_push + i, &key); + glob->need_push[ i ] = val; /* Store the pointer to the value element */ } else { INC_PUSH_CRDS_DROP_METRIC( PUSH_QUEUE_FULL ); } @@ -2370,16 +2417,39 @@ fd_gossip_gettime( fd_gossip_t * glob ) { return glob->now; } +static void +fd_gossip_cleanup_values( fd_gossip_t * glob, + fd_pending_event_arg_t * arg FD_PARAM_UNUSED ) { + fd_gossip_add_pending( glob, fd_gossip_cleanup_values, fd_pending_event_arg_null(), glob->now + (long)3600e9 ); + + ulong value_expire = FD_NANOSEC_TO_MILLI(glob->now) - FD_GOSSIP_VALUE_EXPIRE; + // ulong value_purge = value_expire - FD_GOSSIP_VALUE_EXPIRE/4U; // for purging, which removes data entries but retains the key + for( fd_value_meta_map_iter_t iter = fd_value_meta_map_iter_init( glob->value_metas ); + !fd_value_meta_map_iter_done( glob->value_metas, iter ); + iter = fd_value_meta_map_iter_next( glob->value_metas, iter ) ) { + fd_value_meta_t * ele = fd_value_meta_map_iter_ele( glob->value_metas, iter ); + if ( ele->wallclock < value_expire) { + /* This value has expired, remove it from the value set and vector */ + if( ele->value != NULL ) + fd_value_vec_remove_ele( glob->values, ele->value ); /* Remove the old value from the vector */ + fd_value_meta_map_remove( glob->value_metas, &ele->key ); /* Remove from the value set */ + } + } + glob->metrics.value_meta_cnt = fd_value_meta_map_key_cnt( glob->value_metas ); + glob->metrics.value_vec_cnt = fd_value_vec_cnt( glob->values ); +} + /* Start timed events and other protocol behavior */ int fd_gossip_start( fd_gossip_t * glob ) { fd_gossip_lock( glob ); - fd_gossip_add_pending( glob, fd_gossip_random_pull, fd_pending_event_arg_null(), glob->now + (long) 2e9 ); - fd_gossip_add_pending( glob, fd_gossip_random_ping, fd_pending_event_arg_null(), glob->now + (long) 1e9 ); - fd_gossip_add_pending( glob, fd_gossip_log_stats, fd_pending_event_arg_null(), glob->now + (long)60e9 ); - fd_gossip_add_pending( glob, fd_gossip_refresh_push_states, fd_pending_event_arg_null(), glob->now + (long)20e9 ); - fd_gossip_add_pending( glob, fd_gossip_push, fd_pending_event_arg_null(), glob->now + (long) 1e8 ); - fd_gossip_add_pending( glob, fd_gossip_make_prune, fd_pending_event_arg_null(), glob->now + (long)30e9 ); + fd_gossip_add_pending( glob, fd_gossip_random_pull, fd_pending_event_arg_null(), glob->now + (long) 2e9 ); + fd_gossip_add_pending( glob, fd_gossip_random_ping, fd_pending_event_arg_null(), glob->now + (long) 1e9 ); + fd_gossip_add_pending( glob, fd_gossip_log_stats, fd_pending_event_arg_null(), glob->now + (long) 60e9 ); + fd_gossip_add_pending( glob, fd_gossip_refresh_push_states, fd_pending_event_arg_null(), glob->now + (long) 20e9 ); + fd_gossip_add_pending( glob, fd_gossip_push, fd_pending_event_arg_null(), glob->now + (long) 1e8 ); + fd_gossip_add_pending( glob, fd_gossip_make_prune, fd_pending_event_arg_null(), glob->now + (long) 30e9 ); + fd_gossip_add_pending( glob, fd_gossip_cleanup_values, fd_pending_event_arg_null(), glob->now + (long)3600e9 ); fd_gossip_unlock( glob ); return 0; } diff --git a/src/flamenco/gossip/fd_gossip.h b/src/flamenco/gossip/fd_gossip.h index 97bf905ed1..728a438406 100644 --- a/src/flamenco/gossip/fd_gossip.h +++ b/src/flamenco/gossip/fd_gossip.h @@ -177,6 +177,10 @@ struct fd_gossip_metrics { ulong push_crds_drop_reason[FD_METRICS_COUNTER_GOSSIP_PUSH_CRDS_DROP_CNT]; ulong push_crds_queue_cnt; + /* Value DS sizes */ + ulong value_meta_cnt; + ulong value_vec_cnt; + /* Active Push Destinations */ ulong active_push_destinations; ulong refresh_push_states_failcnt; diff --git a/src/util/tmpl/fd_vec.c b/src/util/tmpl/fd_vec.c index 1ff57ee248..c0cb358098 100644 --- a/src/util/tmpl/fd_vec.c +++ b/src/util/tmpl/fd_vec.c @@ -161,7 +161,7 @@ VEC_(new)( void * shmem, return shmem; } -FD_FN_CONST static inline VEC_T * +static inline VEC_T * VEC_(join)( void * shvec ) { if( FD_UNLIKELY( !shvec ) ) return NULL; @@ -179,7 +179,7 @@ VEC_(leave)( VEC_T * join ) { return (void *)(((ulong)join) - VEC_(private_meta_footprint)()); } -FD_FN_CONST static inline void * +static inline void * VEC_(delete)( void * shvec ) { if( FD_UNLIKELY( !shvec ) ) return NULL; @@ -223,8 +223,8 @@ VEC_(contract)( VEC_T * join, } static inline VEC_T * -VEC_(remove)( VEC_T * join, - ulong idx ) { +VEC_(remove_idx)( VEC_T * join, + ulong idx ) { VEC_(private_t) * vec = VEC_(private)( join ); ulong cnt = vec->cnt - 1UL; join[idx] = join[cnt]; /* TODO: Consider letting user decide if self copy is cheaper than testing */ @@ -233,8 +233,14 @@ VEC_(remove)( VEC_T * join, } static inline VEC_T * -VEC_(remove_compact)( VEC_T * join, - ulong idx ) { +VEC_(remove_ele)( VEC_T * join, + VEC_T * ele){ + return VEC_(remove_idx)( join, (ulong)(ele-join) ); +} + +static inline VEC_T * +VEC_(remove_compact_idx)( VEC_T * join, + ulong idx ) { VEC_(private_t) * vec = VEC_(private)( join ); ulong cnt = vec->cnt - 1UL; for( ; idx>=2; + int op = (int)(r & 7U); r>>=3; switch( op ) { default: @@ -78,19 +78,28 @@ main( int argc, break; } - case 2: { /* remove with backfill */ + case 2: { /* remove with backfill via idx */ if( !cnt ) break; ulong idx = fd_rng_ulong_roll( rng, cnt ); - FD_TEST( myvec_remove( vec, idx )==vec ); + FD_TEST( myvec_remove_idx( vec, idx )==vec ); cnt--; ref[idx] = ref[cnt]; break; } - case 3: { /* remove with compaction */ + case 3: { /* remove with backfill via ptr */ if( !cnt ) break; ulong idx = fd_rng_ulong_roll( rng, cnt ); - FD_TEST( myvec_remove_compact( vec, idx )==vec ); + FD_TEST( myvec_remove_ele( vec, &vec[idx] )==vec ); + cnt--; + ref[idx] = ref[cnt]; + break; + } + + case 4: { /* remove with compaction */ + if( !cnt ) break; + ulong idx = fd_rng_ulong_roll( rng, cnt ); + FD_TEST( myvec_remove_compact_idx( vec, idx )==vec ); cnt--; for( ; idx Date: Fri, 11 Apr 2025 20:42:47 +0000 Subject: [PATCH 2/2] flamenco, gossip: use vector as push queue; order-preserving cleanup; convenience functions --- src/flamenco/gossip/fd_gossip.c | 412 +++++++++++++++++++------------- 1 file changed, 243 insertions(+), 169 deletions(-) diff --git a/src/flamenco/gossip/fd_gossip.c b/src/flamenco/gossip/fd_gossip.c index 4b41ddf3d0..9a6212b626 100644 --- a/src/flamenco/gossip/fd_gossip.c +++ b/src/flamenco/gossip/fd_gossip.c @@ -177,6 +177,8 @@ void fd_hash_copy( fd_hash_t * keyd, const fd_hash_t * keys ) { increasing memory footprint and iteration overhead. + + An entry in the vector must have a corresponding entry in the metadata map, while an entry in the metadata map may not have an entry in the vector (denoted by a @@ -185,18 +187,104 @@ void fd_hash_copy( fd_hash_t * keyd, const fd_hash_t * keys ) { /* Full gossip value representation. Stores the encoded form of a CRDS value and other metadata. */ struct fd_value { - fd_hash_t key; /* Hash of the value data */ - ulong wallclock; /* Original timestamp of value in millis */ - fd_pubkey_t origin; /* Where did this value originate */ - uchar data[PACKET_DATA_SIZE]; /* Serialized form of value (bincode) including signature */ - ulong datalen; + fd_hash_t key; /* Hash of the value data */ + ulong wallclock; /* Original timestamp of value in millis */ + fd_pubkey_t origin; /* Where did this value originate */ + uchar data[PACKET_DATA_SIZE]; /* Serialized form of value (bincode) including signature */ + ulong datalen; + ulong del; /* Set to queue for deletion in fd_gossip_cleanup */ }; typedef struct fd_value fd_value_t; +#define CRDS_DROP_REASON_IDX( REASON ) FD_CONCAT3( FD_METRICS_ENUM_CRDS_DROP_REASON_V_, REASON, _IDX ) +static inline int +fd_value_from_crds( fd_value_t * val, + fd_crds_value_t const * crd ) { + /* OK to reuse since sha256_init is called */ + static fd_sha256_t sha2[1]; + val->del = 0; + switch( crd->data.discriminant ) { + case fd_crds_data_enum_contact_info_v1: + val->origin = crd->data.inner.contact_info_v1.id; + val->wallclock = crd->data.inner.contact_info_v1.wallclock; + break; + case fd_crds_data_enum_vote: + val->origin = crd->data.inner.vote.from; + val->wallclock = crd->data.inner.vote.wallclock; + break; + case fd_crds_data_enum_lowest_slot: + val->origin = crd->data.inner.lowest_slot.from; + val->wallclock = crd->data.inner.lowest_slot.wallclock; + break; + case fd_crds_data_enum_snapshot_hashes: + val->origin = crd->data.inner.snapshot_hashes.from; + val->wallclock = crd->data.inner.snapshot_hashes.wallclock; + break; + case fd_crds_data_enum_accounts_hashes: + val->origin = crd->data.inner.accounts_hashes.from; + val->wallclock = crd->data.inner.accounts_hashes.wallclock; + break; + case fd_crds_data_enum_epoch_slots: + val->origin = crd->data.inner.epoch_slots.from; + val->wallclock = crd->data.inner.epoch_slots.wallclock; + break; + case fd_crds_data_enum_version_v1: + val->origin = crd->data.inner.version_v1.from; + val->wallclock = crd->data.inner.version_v1.wallclock; + break; + case fd_crds_data_enum_version_v2: + val->origin = crd->data.inner.version_v2.from; + val->wallclock = crd->data.inner.version_v2.wallclock; + break; + case fd_crds_data_enum_node_instance: + val->origin = crd->data.inner.node_instance.from; + val->wallclock = crd->data.inner.node_instance.wallclock; + break; + case fd_crds_data_enum_duplicate_shred: + val->origin = crd->data.inner.duplicate_shred.from; + val->wallclock = crd->data.inner.duplicate_shred.wallclock; + break; + case fd_crds_data_enum_incremental_snapshot_hashes: + val->origin = crd->data.inner.incremental_snapshot_hashes.from; + val->wallclock = crd->data.inner.incremental_snapshot_hashes.wallclock; + break; + case fd_crds_data_enum_contact_info_v2: + val->origin = crd->data.inner.contact_info_v2.from; + val->wallclock = crd->data.inner.contact_info_v2.wallclock; + break; + case fd_crds_data_enum_restart_last_voted_fork_slots: + val->origin = crd->data.inner.restart_last_voted_fork_slots.from; + val->wallclock = crd->data.inner.restart_last_voted_fork_slots.wallclock; + break; + case fd_crds_data_enum_restart_heaviest_fork: + val->origin = crd->data.inner.restart_heaviest_fork.from; + val->wallclock = crd->data.inner.restart_heaviest_fork.wallclock; + break; + default: + return CRDS_DROP_REASON_IDX( UNKNOWN_DISCRIMINANT ); + } + + /* Encode */ + fd_bincode_encode_ctx_t ctx; + ctx.data = val->data; + ctx.dataend = val->data + PACKET_DATA_SIZE; + if( fd_crds_value_encode( crd, &ctx ) ) { + FD_LOG_ERR(("fd_crds_value_encode failed")); + } + val->datalen = (ulong)((uchar *)ctx.data - val->data); + + /* Get hash */ + fd_sha256_init( sha2 ); + fd_sha256_append( sha2, val->data, val->datalen ); + fd_sha256_fini( sha2, val->key.uc ); + + return 0; +} + /* Value vector that: - backs the values pointed by fd_value_meta_t->value - - is used in generating push and pullresp + - is used in generating push and pull resp messages */ #define VEC_NAME fd_value_vec #define VEC_T fd_value_t @@ -223,6 +311,15 @@ typedef struct fd_value_meta fd_value_meta_t; #define MAP_T fd_value_meta_t #include "../../util/tmpl/fd_map_giant.c" +static void +fd_value_meta_map_value_init( fd_value_meta_t * meta, + ulong wallclock, + fd_value_t * value ) { + /* Key should have been initialized in fd_value_meta_map_insert */ + meta->wallclock = wallclock; + meta->value = value; +} + /* Weights table element. This table stores the weight for each peer (determined by stake). */ struct fd_weights_elem { @@ -287,6 +384,7 @@ typedef struct fd_push_state fd_push_state_t; #define POOL_T fd_push_state_t #include "../../util/tmpl/fd_pool.c" +#define MAX_DUP_ORIGINS 8U /* Receive statistics table element. */ struct fd_stats_elem { fd_gossip_peer_addr_t key; /* Keyed by sender */ @@ -296,7 +394,7 @@ struct fd_stats_elem { struct { fd_pubkey_t origin; ulong cnt; - } dups[8]; + } dups[MAX_DUP_ORIGINS]; ulong dups_cnt; }; /* Receive statistics table. */ @@ -407,10 +505,8 @@ struct fd_gossip { fd_push_state_t * push_states[FD_PUSH_LIST_MAX]; ulong push_states_cnt; fd_push_state_t * push_states_pool; - /* Queue of values vec ptrs that need pushing */ - fd_value_t * * need_push; + /* Index into values vector */ ulong need_push_head; - ulong need_push_cnt; /* Table of receive statistics */ fd_stats_elem_t * stats; @@ -461,7 +557,6 @@ fd_gossip_footprint( void ) { l = FD_LAYOUT_APPEND( l, fd_peer_table_align(), fd_peer_table_footprint(FD_PEER_KEY_MAX) ); l = FD_LAYOUT_APPEND( l, fd_active_table_align(), fd_active_table_footprint(FD_ACTIVE_KEY_MAX) ); l = FD_LAYOUT_APPEND( l, alignof(fd_gossip_peer_addr_t), INACTIVES_MAX*sizeof(fd_gossip_peer_addr_t) ); - l = FD_LAYOUT_APPEND( l, alignof(fd_value_t *), FD_NEED_PUSH_MAX*sizeof(fd_value_t *) ); l = FD_LAYOUT_APPEND( l, fd_value_meta_map_align(), fd_value_meta_map_footprint( FD_VALUE_KEY_MAX ) ); l = FD_LAYOUT_APPEND( l, fd_value_vec_align(), fd_value_vec_footprint( FD_VALUE_DATA_MAX ) ); l = FD_LAYOUT_APPEND( l, fd_pending_heap_align(), fd_pending_heap_footprint(FD_PENDING_MAX) ); @@ -489,13 +584,13 @@ fd_gossip_new ( void * shmem, ulong seed ) { glob->actives = fd_active_table_join(fd_active_table_new(shm, FD_ACTIVE_KEY_MAX, seed)); glob->inactives = (fd_gossip_peer_addr_t*)FD_SCRATCH_ALLOC_APPEND(l, alignof(fd_gossip_peer_addr_t), INACTIVES_MAX*sizeof(fd_gossip_peer_addr_t)); - glob->need_push = (fd_value_t * *)FD_SCRATCH_ALLOC_APPEND(l, alignof(fd_value_t *), FD_NEED_PUSH_MAX*sizeof(fd_value_t *)); shm = FD_SCRATCH_ALLOC_APPEND( l, fd_value_meta_map_align(), fd_value_meta_map_footprint( FD_VALUE_KEY_MAX ) ); glob->value_metas = fd_value_meta_map_join( fd_value_meta_map_new( shm, FD_VALUE_KEY_MAX, seed ) ); shm = FD_SCRATCH_ALLOC_APPEND( l, fd_value_vec_align(), fd_value_vec_footprint( FD_VALUE_DATA_MAX ) ); glob->values = fd_value_vec_join( fd_value_vec_new( shm, FD_VALUE_DATA_MAX ) ); + glob->need_push_head = 0; // point to start of values glob->last_contact_time = 0; @@ -1249,8 +1344,8 @@ fd_gossip_random_pull( fd_gossip_t * glob, fd_pending_event_arg_t * arg ) { fd_hash_t * hash = &(ele->key); /* Purge expired value's data entry */ - if (ele->wallclock < expire && ele->value != NULL) { - fd_value_vec_remove_ele( glob->values, ele->value ); + if( ele->wallclockvalue!=NULL ) { + ele->value->del = 1; // Mark for deletion ele->value = NULL; continue; } @@ -1444,15 +1539,15 @@ fd_crds_dup_check( fd_gossip_t * glob, fd_hash_t * key, const fd_gossip_peer_add } if( val!=NULL ) { val->last = glob->now; - for (ulong i = 0; i < val->dups_cnt; ++i){ - if (fd_hash_eq(&val->dups[i].origin, origin)) { + for( ulong i = 0; idups_cnt; ++i ){ + if( fd_hash_eq(&val->dups[i].origin, origin ) ) { val->dups[i].cnt++; goto found_origin; } } - if( val->dups_cnt<8 ) { + if( val->dups_cntdups_cnt++; - fd_hash_copy(&val->dups[i].origin, origin); + fd_hash_copy( &val->dups[i].origin, origin ); val->dups[i].cnt = 1; } found_origin: ; @@ -1485,7 +1580,7 @@ fd_crds_sigverify( uchar * crds_encoded_val, ulong crds_encoded_len, fd_pubkey_t } -#define INC_RECV_CRDS_DROP_METRIC( REASON ) glob->metrics.recv_crds_drop_reason[ FD_CONCAT3( FD_METRICS_ENUM_CRDS_DROP_REASON_V_, REASON, _IDX ) ] += 1UL +#define INC_RECV_CRDS_DROP_METRIC( REASON ) glob->metrics.recv_crds_drop_reason[ CRDS_DROP_REASON_IDX( REASON ) ] += 1UL /* fd_gossip_recv_crds_array processes crds_len crds values. First performs a filter pass, dropping duplicate/own values and @@ -1513,8 +1608,6 @@ fd_gossip_recv_crds_array( fd_gossip_t * glob, const fd_gossip_peer_addr_t * fro fd_crds_value_t * retained_crds[FD_GOSSIP_MAX_CRDS_VALS]; /* store pointers to decoded crds entries we retain */ ulong num_retained_crds = 0; - /* OK to reuse since sha256_init is called in every iteration */ - fd_sha256_t sha2[1]; /**************** Filter pass ******************/ for( ulong i = 0; i < crds_len; ++i ) { @@ -1522,68 +1615,11 @@ fd_gossip_recv_crds_array( fd_gossip_t * glob, const fd_gossip_peer_addr_t * fro fd_crds_value_t * crd = &crds[ i ]; retained_crds[ num_retained_crds ] = crd; /* for use in insert pass */ - /* Setup fd_crds_value_processed_t entry */ - switch( crd->data.discriminant ) { - case fd_crds_data_enum_contact_info_v1: - val->origin = crd->data.inner.contact_info_v1.id; - val->wallclock = crd->data.inner.contact_info_v1.wallclock; - break; - case fd_crds_data_enum_vote: - val->origin = crd->data.inner.vote.from; - val->wallclock = crd->data.inner.vote.wallclock; - break; - case fd_crds_data_enum_lowest_slot: - val->origin = crd->data.inner.lowest_slot.from; - val->wallclock = crd->data.inner.lowest_slot.wallclock; - break; - case fd_crds_data_enum_snapshot_hashes: - val->origin = crd->data.inner.snapshot_hashes.from; - val->wallclock = crd->data.inner.snapshot_hashes.wallclock; - break; - case fd_crds_data_enum_accounts_hashes: - val->origin = crd->data.inner.accounts_hashes.from; - val->wallclock = crd->data.inner.accounts_hashes.wallclock; - break; - case fd_crds_data_enum_epoch_slots: - val->origin = crd->data.inner.epoch_slots.from; - val->wallclock = crd->data.inner.epoch_slots.wallclock; - break; - case fd_crds_data_enum_version_v1: - val->origin = crd->data.inner.version_v1.from; - val->wallclock = crd->data.inner.version_v1.wallclock; - break; - case fd_crds_data_enum_version_v2: - val->origin = crd->data.inner.version_v2.from; - val->wallclock = crd->data.inner.version_v2.wallclock; - break; - case fd_crds_data_enum_node_instance: - val->origin = crd->data.inner.node_instance.from; - val->wallclock = crd->data.inner.node_instance.wallclock; - break; - case fd_crds_data_enum_duplicate_shred: - val->origin = crd->data.inner.duplicate_shred.from; - val->wallclock = crd->data.inner.duplicate_shred.wallclock; - break; - case fd_crds_data_enum_incremental_snapshot_hashes: - val->origin = crd->data.inner.incremental_snapshot_hashes.from; - val->wallclock = crd->data.inner.incremental_snapshot_hashes.wallclock; - break; - case fd_crds_data_enum_contact_info_v2: - val->origin = crd->data.inner.contact_info_v2.from; - val->wallclock = crd->data.inner.contact_info_v2.wallclock; - break; - case fd_crds_data_enum_restart_last_voted_fork_slots: - val->origin = crd->data.inner.restart_last_voted_fork_slots.from; - val->wallclock = crd->data.inner.restart_last_voted_fork_slots.wallclock; - break; - case fd_crds_data_enum_restart_heaviest_fork: - val->origin = crd->data.inner.restart_heaviest_fork.from; - val->wallclock = crd->data.inner.restart_heaviest_fork.wallclock; - break; - default: - INC_RECV_CRDS_DROP_METRIC( UNKNOWN_DISCRIMINANT ); - return; - } + int drop_reason_idx = fd_value_from_crds( val, crd ); + if( FD_UNLIKELY( drop_reason_idx ) ) { + glob->metrics.recv_crds_drop_reason[ drop_reason_idx ] += 1UL; + return; /* Drop full packet if any issues extracting CRDS */ + }; glob->metrics.recv_crds[ route ][ crd->data.discriminant ] += 1UL; @@ -1593,20 +1629,6 @@ fd_gossip_recv_crds_array( fd_gossip_t * glob, const fd_gossip_peer_addr_t * fro continue; } - /* Encode */ - fd_bincode_encode_ctx_t ctx; - ctx.data = val->data; - ctx.dataend = val->data + PACKET_DATA_SIZE; - if( fd_crds_value_encode( crd, &ctx ) ) { - FD_LOG_ERR(("fd_crds_value_encode failed")); - } - val->datalen = (ulong)((uchar *)ctx.data - val->data); - - /* Get hash */ - fd_sha256_init( sha2 ); - fd_sha256_append( sha2, val->data, val->datalen ); - fd_sha256_fini( sha2, val->key.uc ); - fd_msg_stats_elem_t * msg_stat = &glob->msg_stats[ crd->data.discriminant ]; msg_stat->total_cnt++; msg_stat->bytes_rx_cnt += val->datalen; @@ -1655,19 +1677,10 @@ fd_gossip_recv_crds_array( fd_gossip_t * glob, const fd_gossip_peer_addr_t * fro /* Insert into the value set (duplicate check performed in filter pass) */ fd_value_meta_t * ele = fd_value_meta_map_insert( glob->value_metas, &val->key ); - ele->key = val->key; - ele->value = val; - ele->wallclock = val->wallclock; + fd_value_meta_map_value_init( ele, + val->wallclock, + val ); - if ( FD_UNLIKELY( glob->need_push_cnt < FD_NEED_PUSH_MAX ) ) { - /* Remember that I need to push this value */ - ulong i = ((glob->need_push_head + (glob->need_push_cnt++)) & (FD_NEED_PUSH_MAX-1U)); - /* TODO: change this to vector idx/ptrs? */ - glob->need_push[ i ] = val; - glob->metrics.push_crds_queue_cnt = glob->need_push_cnt; - } else { - INC_RECV_CRDS_DROP_METRIC( PUSH_QUEUE_FULL ); - } fd_crds_value_t * crd = retained_crds[ i ]; @@ -1840,10 +1853,10 @@ fd_gossip_push_updated_contact(fd_gossip_t * glob) { if( (glob->now - glob->last_contact_time)<(long)1e9 ) return; - if (glob->last_contact_time != 0) { - fd_value_meta_t * ele = fd_value_meta_map_query(glob->value_metas, &glob->last_contact_info_v2_key, NULL); - if (ele != NULL) { - fd_value_vec_remove_ele( glob->values, ele->value ); /* Remove the old value from the vector */ + if( glob->last_contact_time!=0 ) { + fd_value_meta_t * ele = fd_value_meta_map_query( glob->value_metas, &glob->last_contact_info_v2_key, NULL ); + if( ele!=NULL ) { + ele->value->del = 1UL; fd_value_meta_map_remove( glob->value_metas, &glob->last_contact_info_v2_key ); } } @@ -2122,11 +2135,14 @@ fd_gossip_push( fd_gossip_t * glob, fd_pending_event_arg_t * arg ) { /* Push an updated version of my contact info into values */ fd_gossip_push_updated_contact(glob); + ulong pending_values_cnt = fd_value_vec_cnt( glob->values ) - glob->need_push_head; + ulong need_push_cnt = fd_ulong_if( pending_values_cnt < FD_NEED_PUSH_MAX, pending_values_cnt, FD_NEED_PUSH_MAX ); + /* Iterate across recent values */ - ulong expire = FD_NANOSEC_TO_MILLI(glob->now) - FD_GOSSIP_PULL_TIMEOUT; - while (glob->need_push_cnt > 0) { - fd_value_t * msg = glob->need_push[ ((glob->need_push_head++) & (FD_NEED_PUSH_MAX-1)) ]; - glob->need_push_cnt--; + ulong expire = FD_NANOSEC_TO_MILLI( glob->now ) - FD_GOSSIP_PULL_TIMEOUT; + while( need_push_cnt>0 ) { + fd_value_t * msg = &glob->values[ glob->need_push_head++ ]; + need_push_cnt--; if( msg->wallclockmetrics.push_crds_drop_reason[ FD_CONCAT3( FD_METRICS_ENUM_CRDS_DROP_REASON_V_, REASON , _IDX ) ] += 1UL + glob->metrics.push_crds_drop_reason[ CRDS_DROP_REASON_IDX( REASON ) ] += 1UL if( FD_UNLIKELY( data->discriminant >= FD_KNOWN_CRDS_ENUM_MAX ) ) { INC_PUSH_CRDS_DROP_METRIC( UNKNOWN_DISCRIMINANT ); return -1; } - /* Wrap the data in a value stub. Sign it. */ fd_crds_value_t crd; crd.data = *data; fd_gossip_sign_crds_value(glob, &crd); - /* Perform the value hash to get the value table key */ - uchar buf[PACKET_DATA_SIZE]; - fd_bincode_encode_ctx_t ctx; - ctx.data = buf; - ctx.dataend = buf + PACKET_DATA_SIZE; - if( fd_crds_value_encode( &crd, &ctx ) ) { - INC_PUSH_CRDS_DROP_METRIC( ENCODING_FAILED ); - FD_LOG_ERR(( "fd_crds_value_encode failed" )); + if( fd_value_meta_map_is_full( glob->value_metas ) || fd_value_vec_is_full( glob->values ) ) { + INC_PUSH_CRDS_DROP_METRIC( TABLE_FULL ); + FD_LOG_DEBUG(("too many values")); return -1; } - fd_sha256_t sha2[1]; - fd_sha256_init( sha2 ); - ulong datalen = (ulong)((uchar*)ctx.data - buf); - fd_sha256_append( sha2, buf, datalen ); - fd_hash_t key; - fd_sha256_fini( sha2, key.uc ); - if( key_opt != NULL ) - fd_hash_copy( key_opt, &key ); + fd_value_t * val = fd_value_vec_expand( glob->values, 1UL ); + int drop_reason_idx = fd_value_from_crds( val, &crd ); + if( FD_UNLIKELY( drop_reason_idx ) ) { + glob->metrics.push_crds_drop_reason[ drop_reason_idx ] += 1UL; + return -1; + } + + if( key_opt!=NULL ) + fd_hash_copy( key_opt, &val->key ); /* Store the value for later pushing/duplicate detection */ - fd_value_meta_t * ele = fd_value_meta_map_query( glob->value_metas, &key, NULL ); + fd_value_meta_t * ele = fd_value_meta_map_query( glob->value_metas, &val->key, NULL ); if( ele != NULL ) { /* Already have this value, which is strange! NOTE: This is a different list from duplicate crds values received @@ -2233,36 +2244,17 @@ fd_gossip_push_value_nolock( fd_gossip_t * glob, fd_crds_data_t * data, fd_hash_ Reaching this path implies a crds value generated internally was detected as a duplicate. */ glob->metrics.push_crds_duplicate[ data->discriminant ] += 1UL; + fd_value_vec_contract( glob->values, 1UL ); return -1; } - if( fd_value_meta_map_is_full( glob->value_metas ) || fd_value_vec_is_full( glob->values ) ) { - INC_PUSH_CRDS_DROP_METRIC( TABLE_FULL ); - FD_LOG_DEBUG(("too many values")); - return -1; - } - fd_value_t * val = fd_value_vec_expand( glob->values, 1UL ); - ele = fd_value_meta_map_insert( glob->value_metas, &key ); - ele->value = val; /* Store the pointer to the value element */ - ele->wallclock = FD_NANOSEC_TO_MILLI( glob->now ); + ele = fd_value_meta_map_insert( glob->value_metas, &val->key ); - val->key = key; - val->wallclock = ele->wallclock; - val->origin = *glob->public_key; + fd_value_meta_map_value_init( ele, + val->wallclock, + val ); - /* We store the serialized form for convenience */ - fd_memcpy( val->data, buf, datalen ); - val->datalen = datalen; - - if (glob->need_push_cnt < FD_NEED_PUSH_MAX) { - /* Remember that I need to push this value */ - ulong i = ((glob->need_push_head + (glob->need_push_cnt++)) & (FD_NEED_PUSH_MAX-1U)); - glob->need_push[ i ] = val; /* Store the pointer to the value element */ - } else { - INC_PUSH_CRDS_DROP_METRIC( PUSH_QUEUE_FULL ); - } - - glob->metrics.push_crds_queue_cnt = glob->need_push_cnt; + glob->metrics.push_crds_queue_cnt = fd_value_vec_cnt( glob->values ) - glob->need_push_head; glob->metrics.push_crds[ data->discriminant ] += 1UL; return 0; @@ -2297,7 +2289,7 @@ fd_gossip_make_prune( fd_gossip_t * glob, fd_pending_event_arg_t * arg ) { continue; } /* Look for high duplicate counts */ - fd_pubkey_t origins[8]; + fd_pubkey_t origins[MAX_DUP_ORIGINS]; ulong origins_cnt = 0; for (ulong i = 0; i < ele->dups_cnt; ++i) { if (ele->dups[i].cnt >= 20U) { @@ -2417,24 +2409,106 @@ fd_gossip_gettime( fd_gossip_t * glob ) { return glob->now; } +/* Single pass values vector compaction. This + preserves ordering, which means the push queue + is unbroken. It is also performed in place which + means the values vector, which takes up a few GBs + on its own, does not need to be reallocated. + + TODO: This has high runtime complexity, but is only run + once every 15 seconds. We can simplify/improve on this by + breaking up pushed and un-pushed values into two vectors + (with the full vector being the concat of both) so that + order preservation is not needed. This lets us use a more + efficient cleanup (i.e,. swap in place) while also + simplifying the push queue management. + + See fd_gossip_cleanup_values for an example */ +static ulong +fd_gossip_compact_values( fd_gossip_t * glob ) { + fd_value_t * vec = glob->values; + + ulong start = 0; + ulong cur_count = fd_value_vec_cnt( vec ); + /* find first element to delete */ + for( ; start(start + 1) ) { + /* move all values between start and next in place */ + memmove( &vec[start - num_deleted], + &vec[start + 1], + (next - start - 1) * sizeof(fd_value_t) ); + } + start = next; + next = start + 1; + num_deleted++; + /* Need to adjust push queue */ + if( FD_UNLIKELY( glob->need_push_head > start && + glob->need_push_head <= next ) ) { + push_head_snapshot = num_deleted; + } + } else { + next++; + } + } + + glob->need_push_head -= fd_ulong_if( push_head_snapshot != ULONG_MAX, push_head_snapshot, num_deleted ); + fd_value_vec_contract( glob->values, num_deleted ); + glob->metrics.value_vec_cnt = fd_value_vec_cnt( glob->values ); + FD_LOG_NOTICE(( "GOSSIP compacted %lu values", num_deleted )); + return num_deleted; +} + +/* Implements a two-stage cleanup: + 1. Iterate through metas map and find elements to delete + based on conditions (currently determined by expiry + window). If entry has a corresponding value entry + mark it for deletion based on conditions*. An entry + might have already been marked for deletion before, + but this is not a problem. + + 2. Iterate through values vector and remove + entries marked for deletion in the first stage. + This is done to preserve ordering of the values vector. + See fd_gossip_compact_values for more details. + + + + * TODO: In the current implementation, the conditions for + removing a meta entry and a value are the same, but + they can differ. Ideally values should be more + aggressively cleaned up as they are only needed for + push messages and processing. Will come in a separate PR. */ + static void fd_gossip_cleanup_values( fd_gossip_t * glob, fd_pending_event_arg_t * arg FD_PARAM_UNUSED ) { - fd_gossip_add_pending( glob, fd_gossip_cleanup_values, fd_pending_event_arg_null(), glob->now + (long)3600e9 ); + fd_gossip_add_pending( glob, fd_gossip_cleanup_values, fd_pending_event_arg_null(), glob->now + (long)15e9 ); ulong value_expire = FD_NANOSEC_TO_MILLI(glob->now) - FD_GOSSIP_VALUE_EXPIRE; - // ulong value_purge = value_expire - FD_GOSSIP_VALUE_EXPIRE/4U; // for purging, which removes data entries but retains the key for( fd_value_meta_map_iter_t iter = fd_value_meta_map_iter_init( glob->value_metas ); !fd_value_meta_map_iter_done( glob->value_metas, iter ); iter = fd_value_meta_map_iter_next( glob->value_metas, iter ) ) { fd_value_meta_t * ele = fd_value_meta_map_iter_ele( glob->value_metas, iter ); - if ( ele->wallclock < value_expire) { - /* This value has expired, remove it from the value set and vector */ - if( ele->value != NULL ) - fd_value_vec_remove_ele( glob->values, ele->value ); /* Remove the old value from the vector */ + if ( ele->wallclockvalue!=NULL ){ + ele->value->del = 1UL; + } fd_value_meta_map_remove( glob->value_metas, &ele->key ); /* Remove from the value set */ } } + + fd_gossip_compact_values( glob ); glob->metrics.value_meta_cnt = fd_value_meta_map_key_cnt( glob->value_metas ); glob->metrics.value_vec_cnt = fd_value_vec_cnt( glob->values ); } @@ -2449,7 +2523,7 @@ fd_gossip_start( fd_gossip_t * glob ) { fd_gossip_add_pending( glob, fd_gossip_refresh_push_states, fd_pending_event_arg_null(), glob->now + (long) 20e9 ); fd_gossip_add_pending( glob, fd_gossip_push, fd_pending_event_arg_null(), glob->now + (long) 1e8 ); fd_gossip_add_pending( glob, fd_gossip_make_prune, fd_pending_event_arg_null(), glob->now + (long) 30e9 ); - fd_gossip_add_pending( glob, fd_gossip_cleanup_values, fd_pending_event_arg_null(), glob->now + (long)3600e9 ); + fd_gossip_add_pending( glob, fd_gossip_cleanup_values, fd_pending_event_arg_null(), glob->now + (long) 15e9 ); fd_gossip_unlock( glob ); return 0; }