Skip to content

Commit b90dfd3

Browse files
Early-subscribe Gloas proposer_preferences and fix publish digest
Signed-off-by: Nikhil Sharma <nikhilsharma230303@gmail.com>
1 parent 1cd1a3c commit b90dfd3

3 files changed

Lines changed: 502 additions & 13 deletions

File tree

beacon_node/lighthouse_network/src/service/mod.rs

Lines changed: 107 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -818,21 +818,19 @@ impl<E: EthSpec> Network<E> {
818818
///
819819
/// Returns `true` if the subscription was successful and `false` otherwise.
820820
pub fn subscribe(&mut self, topic: GossipTopic) -> bool {
821-
// update the network globals
822-
self.network_globals
823-
.gossipsub_subscriptions
824-
.write()
825-
.insert(topic.clone());
826-
827-
let topic: Topic = topic.into();
821+
let libp2p_topic: Topic = topic.clone().into();
828822

829-
match self.gossipsub_mut().subscribe(&topic) {
823+
match self.gossipsub_mut().subscribe(&libp2p_topic) {
830824
Err(e) => {
831825
warn!(%topic, error = ?e, "Failed to subscribe to topic");
832826
false
833827
}
834828
Ok(_) => {
835829
debug!(%topic, "Subscribed to topic");
830+
self.network_globals
831+
.gossipsub_subscriptions
832+
.write()
833+
.insert(topic);
836834
true
837835
}
838836
}
@@ -856,7 +854,12 @@ impl<E: EthSpec> Network<E> {
856854
/// Publishes a list of messages on the pubsub (gossipsub) behaviour, choosing the encoding.
857855
pub fn publish(&mut self, messages: Vec<PubsubMessage<E>>) {
858856
for message in messages {
859-
for topic in message.topics(GossipEncoding::default(), self.enr_fork_id.fork_digest) {
857+
let fork_digest = gossip_fork_digest_for_publish(
858+
&message,
859+
&self.fork_context,
860+
self.enr_fork_id.fork_digest,
861+
);
862+
for topic in message.topics(GossipEncoding::default(), fork_digest) {
860863
let message_data = message.encode(GossipEncoding::default());
861864
if let Err(e) = self
862865
.gossipsub_mut()
@@ -2174,3 +2177,98 @@ impl<E: EthSpec> Network<E> {
21742177
}
21752178
}
21762179
}
2180+
2181+
/// Fork digest used when publishing a gossip message.
2182+
///
2183+
/// `ProposerPreferences` uses the digest for `proposal_slot`'s epoch so pre-fork prefs land on the
2184+
/// Gloas topic. All other messages use the current ENR fork digest.
2185+
fn gossip_fork_digest_for_publish<E: EthSpec>(
2186+
message: &PubsubMessage<E>,
2187+
fork_context: &ForkContext,
2188+
current_enr_digest: [u8; 4],
2189+
) -> [u8; 4] {
2190+
match message {
2191+
PubsubMessage::ProposerPreferences(prefs) => {
2192+
let epoch = prefs.message.proposal_slot.epoch(E::slots_per_epoch());
2193+
fork_context.context_bytes(epoch)
2194+
}
2195+
_ => current_enr_digest,
2196+
}
2197+
}
2198+
2199+
#[cfg(test)]
2200+
mod gossip_publish_digest_tests {
2201+
use super::*;
2202+
use bls::Signature;
2203+
use std::sync::Arc;
2204+
use types::{
2205+
Epoch, Hash256, MinimalEthSpec, ProposerPreferences, SignedProposerPreferences,
2206+
SignedVoluntaryExit, VoluntaryExit,
2207+
};
2208+
2209+
type E = MinimalEthSpec;
2210+
2211+
fn fulu_then_gloas_fork_context(gloas_epoch: u64) -> ForkContext {
2212+
let mut spec = E::default_spec();
2213+
spec.altair_fork_epoch = Some(Epoch::new(0));
2214+
spec.bellatrix_fork_epoch = Some(Epoch::new(0));
2215+
spec.capella_fork_epoch = Some(Epoch::new(0));
2216+
spec.deneb_fork_epoch = Some(Epoch::new(0));
2217+
spec.electra_fork_epoch = Some(Epoch::new(0));
2218+
spec.fulu_fork_epoch = Some(Epoch::new(0));
2219+
spec.gloas_fork_epoch = Some(Epoch::new(gloas_epoch));
2220+
ForkContext::new::<E>(Slot::new(0), Hash256::ZERO, &spec)
2221+
}
2222+
2223+
#[test]
2224+
fn proposer_preferences_publish_uses_proposal_epoch_digest() {
2225+
let gloas_epoch = 2;
2226+
let fork_context = fulu_then_gloas_fork_context(gloas_epoch);
2227+
let fulu_digest = fork_context.context_bytes(Epoch::new(0));
2228+
let gloas_digest = fork_context.context_bytes(Epoch::new(gloas_epoch));
2229+
assert_ne!(fulu_digest, gloas_digest);
2230+
assert_eq!(
2231+
gloas_digest,
2232+
fork_context
2233+
.spec
2234+
.compute_fork_digest(Hash256::ZERO, Epoch::new(gloas_epoch))
2235+
);
2236+
2237+
let prefs = SignedProposerPreferences {
2238+
message: ProposerPreferences {
2239+
dependent_root: Hash256::ZERO,
2240+
proposal_slot: Epoch::new(gloas_epoch).start_slot(E::slots_per_epoch()),
2241+
validator_index: 1,
2242+
fee_recipient: Default::default(),
2243+
target_gas_limit: 30_000_000,
2244+
},
2245+
signature: Signature::empty(),
2246+
};
2247+
let message = PubsubMessage::<E>::ProposerPreferences(Arc::new(prefs));
2248+
2249+
let digest = gossip_fork_digest_for_publish(&message, &fork_context, fulu_digest);
2250+
assert_eq!(digest, gloas_digest);
2251+
assert_ne!(digest, fulu_digest);
2252+
}
2253+
2254+
#[test]
2255+
fn other_messages_publish_use_current_enr_digest() {
2256+
let fork_context = fulu_then_gloas_fork_context(2);
2257+
let fulu_digest = fork_context.context_bytes(Epoch::new(0));
2258+
let other_digest = [9, 9, 9, 9];
2259+
2260+
let exit = SignedVoluntaryExit {
2261+
message: VoluntaryExit {
2262+
epoch: Epoch::new(0),
2263+
validator_index: 0,
2264+
},
2265+
signature: Signature::empty(),
2266+
};
2267+
let message = PubsubMessage::<E>::VoluntaryExit(Box::new(exit));
2268+
2269+
let digest = gossip_fork_digest_for_publish(&message, &fork_context, other_digest);
2270+
assert_eq!(digest, other_digest);
2271+
assert_ne!(digest, fork_context.context_bytes(Epoch::new(2)));
2272+
assert_eq!(fulu_digest, fork_context.current_fork_digest());
2273+
}
2274+
}

0 commit comments

Comments
 (0)