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..9a6212b626 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,26 +167,159 @@ 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;
+ 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 pull resp
+ 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"
+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 {
@@ -250,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 */
@@ -259,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. */
@@ -359,8 +494,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,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 that need pushing */
- fd_hash_t * need_push;
+ /* Index into values vector */
ulong need_push_head;
- ulong need_push_cnt;
/* Table of receive statistics */
fd_stats_elem_t * stats;
@@ -423,8 +557,8 @@ 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, 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 +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_hash_t*)FD_SCRATCH_ALLOC_APPEND(l, alignof(fd_hash_t), FD_NEED_PUSH_MAX*sizeof(fd_hash_t));
- 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_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;
@@ -489,7 +626,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 +1263,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 +1337,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->wallclockvalue!=NULL ) {
+ ele->value->del = 1; // Mark for deletion
+ ele->value = NULL;
continue;
}
/* Choose which filter packet based on the high bits in the hash,
@@ -1377,15 +1517,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,30 +1524,30 @@ 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)) {
+ 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: ;
@@ -1449,28 +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
-
-/* 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;
-}
+#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
@@ -1488,111 +1598,46 @@ 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;
- /* OK to reuse since sha256_init is called in every iteration */
- fd_sha256_t sha2[1];
+ 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;
- /* 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 ];
- /* Setup fd_crds_value_processed_t entry */
- switch (tmp->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;
- break;
- case fd_crds_data_enum_vote:
- tmp->pubkey = &tmp->crd->data.inner.vote.from;
- tmp->wallclock = tmp->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;
- 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;
- 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;
- 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;
- 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;
- 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;
- 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;
- 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;
- 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;
- 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;
- 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;
- 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;
- break;
- default:
- INC_RECV_CRDS_DROP_METRIC( UNKNOWN_DISCRIMINANT );
- return;
- }
+ /**************** Filter pass ******************/
+ for( ulong i = 0; i < crds_len; ++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 */
+
+ 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 ][ 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;
}
- /* 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 ) ) {
- FD_LOG_ERR(("fd_crds_value_encode failed"));
- }
- tmp->encoded_len = (ulong)((uchar *)ctx.data - tmp->encoded_val);
-
- /* 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_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 +1645,46 @@ 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 );
- 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);
- glob->metrics.push_crds_queue_cnt = glob->need_push_cnt;
- } else {
- INC_RECV_CRDS_DROP_METRIC( PUSH_QUEUE_FULL );
+ /**************** 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;
}
- fd_crds_value_t * crd = crd_p->crd;
+ /* 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 );
+
+ fd_value_meta_map_value_init( ele,
+ val->wallclock,
+ val );
+
- if (crd->data.discriminant == fd_crds_data_enum_contact_info_v2) {
+ fd_crds_value_t * crd = retained_crds[ i ];
+
+ 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 +1692,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 +1722,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 +1847,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);
- if (ele != NULL) {
- fd_value_table_remove( glob->values, &glob->last_contact_info_v2_key );
+ 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 );
}
}
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 +1923,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;
@@ -2080,33 +2135,35 @@ 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_hash_t * h = 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--;
- 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 +2174,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;
}
@@ -2151,71 +2208,53 @@ fd_gossip_push( fd_gossip_t * glob, fd_pending_event_arg_t * arg ) {
static int
fd_gossip_push_value_nolock( fd_gossip_t * glob, fd_crds_data_t * data, fd_hash_t * key_opt ) {
#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
+ glob->metrics.push_crds_drop_reason[ CRDS_DROP_REASON_IDX( REASON ) ] += 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;
}
-
/* 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_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, &val->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).
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_table_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);
- /* We store the serialized form for convenience */
- fd_memcpy(msg->data, buf, datalen);
- msg->datalen = datalen;
+ ele = fd_value_meta_map_insert( glob->value_metas, &val->key );
- 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);
- } else {
- INC_PUSH_CRDS_DROP_METRIC( PUSH_QUEUE_FULL );
- }
+ fd_value_meta_map_value_init( ele,
+ val->wallclock,
+ val );
- 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;
@@ -2250,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) {
@@ -2370,16 +2409,121 @@ 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)15e9 );
+
+ ulong value_expire = FD_NANOSEC_TO_MILLI(glob->now) - FD_GOSSIP_VALUE_EXPIRE;
+ 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->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 );
+}
+
/* 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) 15e9 );
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