Restrict network limits based on merge fork epoch (#2839)

This commit is contained in:
Pawan Dhananjay
2021-12-01 20:00:39 -06:00
committed by Paul Hauner
parent 144978f8f8
commit f3c237cfa0
12 changed files with 57 additions and 66 deletions

View File

@@ -16,8 +16,10 @@ use std::sync::Arc;
use std::time::Duration;
use types::{ForkContext, ForkName};
/// The maximum transmit size of gossip messages in bytes.
pub const GOSSIP_MAX_SIZE: usize = 10 * 1_048_576; // 10M
/// The maximum transmit size of gossip messages in bytes pre-merge.
const GOSSIP_MAX_SIZE: usize = 1_048_576; // 1M
/// The maximum transmit size of gossip messages in bytes post-merge.
const GOSSIP_MAX_SIZE_POST_MERGE: usize = 10 * 1_048_576; // 10M
/// This is a constant to be used in discovery. The lower bound of the gossipsub mesh.
pub const MESH_N_LOW: usize = 6;
@@ -40,6 +42,15 @@ pub const DUPLICATE_CACHE_TIME: Duration = Duration::from_secs(33 * 12 + 1);
// const MESSAGE_DOMAIN_INVALID_SNAPPY: [u8; 4] = [0, 0, 0, 0];
const MESSAGE_DOMAIN_VALID_SNAPPY: [u8; 4] = [1, 0, 0, 0];
/// The maximum size of gossip messages.
pub fn gossip_max_size(is_merge_enabled: bool) -> usize {
if is_merge_enabled {
GOSSIP_MAX_SIZE_POST_MERGE
} else {
GOSSIP_MAX_SIZE
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
/// Network configuration for lighthouse.
@@ -231,6 +242,7 @@ pub fn gossipsub_config(fork_context: Arc<ForkContext>) -> GossipsubConfig {
}
}
let is_merge_enabled = fork_context.fork_exists(ForkName::Merge);
let gossip_message_id = move |message: &GossipsubMessage| {
MessageId::from(
&Sha256::digest(
@@ -239,7 +251,7 @@ pub fn gossipsub_config(fork_context: Arc<ForkContext>) -> GossipsubConfig {
)
};
GossipsubConfigBuilder::default()
.max_transmit_size(GOSSIP_MAX_SIZE)
.max_transmit_size(gossip_max_size(is_merge_enabled))
.heartbeat_interval(Duration::from_millis(700))
.mesh_n(8)
.mesh_n_low(MESH_N_LOW)

View File

@@ -16,7 +16,7 @@ pub mod rpc;
mod service;
pub mod types;
pub use config::GOSSIP_MAX_SIZE;
pub use config::gossip_max_size;
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use std::str::FromStr;

View File

@@ -697,9 +697,9 @@ mod tests {
version: Version,
message: &mut BytesMut,
) -> Result<Option<RPCResponse<Spec>>, RPCError> {
let max_packet_size = 1_048_576;
let snappy_protocol_id = ProtocolId::new(protocol, version, Encoding::SSZSnappy);
let fork_context = Arc::new(fork_context());
let max_packet_size = max_rpc_size(&fork_context);
let mut snappy_outbound_codec =
SSZSnappyOutboundCodec::<Spec>::new(snappy_protocol_id, max_packet_size, fork_context);
// decode message just as snappy message
@@ -1124,7 +1124,7 @@ mod tests {
);
}
/// Test sending a message with encoded length prefix > MAX_RPC_SIZE.
/// Test sending a message with encoded length prefix > max_rpc_size.
#[test]
fn test_decode_invalid_length() {
// 10 byte snappy stream identifier

View File

@@ -5,7 +5,7 @@ use super::methods::{
GoodbyeReason, RPCCodedResponse, RPCResponseErrorCode, RequestId, ResponseTermination,
};
use super::outbound::OutboundRequestContainer;
use super::protocol::{InboundRequest, Protocol, RPCError, RPCProtocol};
use super::protocol::{max_rpc_size, InboundRequest, Protocol, RPCError, RPCProtocol};
use super::{RPCReceived, RPCSend};
use crate::rpc::outbound::{OutboundFramed, OutboundRequest};
use crate::rpc::protocol::InboundFramed;
@@ -951,6 +951,7 @@ where
OutboundRequestContainer {
req: req.clone(),
fork_context: self.fork_context.clone(),
max_rpc_size: max_rpc_size(&self.fork_context),
},
(),
)

View File

@@ -30,7 +30,7 @@ pub use methods::{
RPCResponseErrorCode, RequestId, ResponseTermination, StatusMessage, MAX_REQUEST_BLOCKS,
};
pub(crate) use outbound::OutboundRequest;
pub use protocol::{Protocol, RPCError, MAX_RPC_SIZE};
pub use protocol::{max_rpc_size, Protocol, RPCError};
pub(crate) mod codec;
mod handler;
@@ -186,6 +186,7 @@ where
SubstreamProtocol::new(
RPCProtocol {
fork_context: self.fork_context.clone(),
max_rpc_size: max_rpc_size(&self.fork_context),
phantom: PhantomData,
},
(),

View File

@@ -2,7 +2,7 @@ use std::marker::PhantomData;
use super::methods::*;
use super::protocol::Protocol;
use super::protocol::{ProtocolId, MAX_RPC_SIZE};
use super::protocol::ProtocolId;
use super::RPCError;
use crate::rpc::protocol::Encoding;
use crate::rpc::protocol::Version;
@@ -29,6 +29,7 @@ use types::{EthSpec, ForkContext};
pub struct OutboundRequestContainer<TSpec: EthSpec> {
pub req: OutboundRequest<TSpec>,
pub fork_context: Arc<ForkContext>,
pub max_rpc_size: usize,
}
#[derive(Debug, Clone, PartialEq)]
@@ -150,7 +151,7 @@ where
Encoding::SSZSnappy => {
let ssz_snappy_codec = BaseOutboundCodec::new(SSZSnappyOutboundCodec::new(
protocol,
MAX_RPC_SIZE,
self.max_rpc_size,
self.fork_context.clone(),
));
OutboundCodec::SSZSnappy(ssz_snappy_codec)

View File

@@ -22,7 +22,7 @@ use tokio_util::{
};
use types::{
BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockMerge, EthSpec, ForkContext,
Hash256, MainnetEthSpec, Signature, SignedBeaconBlock,
ForkName, Hash256, MainnetEthSpec, Signature, SignedBeaconBlock,
};
lazy_static! {
@@ -92,8 +92,10 @@ lazy_static! {
}
/// The maximum bytes that can be sent across the RPC.
pub const MAX_RPC_SIZE: usize = 10 * 1_048_576; // 10M
/// The maximum bytes that can be sent across the RPC pre-merge.
pub(crate) const MAX_RPC_SIZE: usize = 1_048_576; // 1M
/// The maximum bytes that can be sent across the RPC post-merge.
pub(crate) const MAX_RPC_SIZE_POST_MERGE: usize = 10 * 1_048_576; // 10M
/// The protocol prefix the RPC protocol id.
const PROTOCOL_PREFIX: &str = "/eth2/beacon_chain/req";
/// Time allowed for the first byte of a request to arrive before we time out (Time To First Byte).
@@ -102,6 +104,15 @@ const TTFB_TIMEOUT: u64 = 5;
/// established before the stream is terminated.
const REQUEST_TIMEOUT: u64 = 15;
/// Returns the maximum bytes that can be sent across the RPC.
pub fn max_rpc_size(fork_context: &ForkContext) -> usize {
if fork_context.fork_exists(ForkName::Merge) {
MAX_RPC_SIZE_POST_MERGE
} else {
MAX_RPC_SIZE
}
}
/// Protocol names to be used.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Protocol {
@@ -170,6 +181,7 @@ impl std::fmt::Display for Version {
#[derive(Debug, Clone)]
pub struct RPCProtocol<TSpec: EthSpec> {
pub fork_context: Arc<ForkContext>,
pub max_rpc_size: usize,
pub phantom: PhantomData<TSpec>,
}
@@ -206,7 +218,7 @@ impl RpcLimits {
Self { min, max }
}
/// Returns true if the given length is greater than `MAX_RPC_SIZE` or out of
/// Returns true if the given length is greater than `max_rpc_size` or out of
/// bounds for the given ssz type, returns false otherwise.
pub fn is_out_of_bounds(&self, length: usize, max_rpc_size: usize) -> bool {
length > std::cmp::min(self.max, max_rpc_size) || length < self.min
@@ -365,7 +377,7 @@ where
Encoding::SSZSnappy => {
let ssz_snappy_codec = BaseInboundCodec::new(SSZSnappyInboundCodec::new(
protocol,
MAX_RPC_SIZE,
self.max_rpc_size,
self.fork_context.clone(),
));
InboundCodec::SSZSnappy(ssz_snappy_codec)