mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-02 12:13:46 +00:00
Merge branch 'unstable' of https://github.com/sigp/lighthouse into electra_attestation_changes
This commit is contained in:
@@ -389,35 +389,35 @@ pub struct PersistedForkChoiceStore {
|
||||
pub equivocating_indices: BTreeSet<u64>,
|
||||
}
|
||||
|
||||
impl Into<PersistedForkChoiceStore> for PersistedForkChoiceStoreV11 {
|
||||
fn into(self) -> PersistedForkChoiceStore {
|
||||
impl From<PersistedForkChoiceStoreV11> for PersistedForkChoiceStore {
|
||||
fn from(from: PersistedForkChoiceStoreV11) -> PersistedForkChoiceStore {
|
||||
PersistedForkChoiceStore {
|
||||
balances_cache: self.balances_cache,
|
||||
time: self.time,
|
||||
finalized_checkpoint: self.finalized_checkpoint,
|
||||
justified_checkpoint: self.justified_checkpoint,
|
||||
justified_balances: self.justified_balances,
|
||||
unrealized_justified_checkpoint: self.unrealized_justified_checkpoint,
|
||||
unrealized_finalized_checkpoint: self.unrealized_finalized_checkpoint,
|
||||
proposer_boost_root: self.proposer_boost_root,
|
||||
equivocating_indices: self.equivocating_indices,
|
||||
balances_cache: from.balances_cache,
|
||||
time: from.time,
|
||||
finalized_checkpoint: from.finalized_checkpoint,
|
||||
justified_checkpoint: from.justified_checkpoint,
|
||||
justified_balances: from.justified_balances,
|
||||
unrealized_justified_checkpoint: from.unrealized_justified_checkpoint,
|
||||
unrealized_finalized_checkpoint: from.unrealized_finalized_checkpoint,
|
||||
proposer_boost_root: from.proposer_boost_root,
|
||||
equivocating_indices: from.equivocating_indices,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<PersistedForkChoiceStoreV11> for PersistedForkChoiceStore {
|
||||
fn into(self) -> PersistedForkChoiceStoreV11 {
|
||||
impl From<PersistedForkChoiceStore> for PersistedForkChoiceStoreV11 {
|
||||
fn from(from: PersistedForkChoiceStore) -> PersistedForkChoiceStoreV11 {
|
||||
PersistedForkChoiceStoreV11 {
|
||||
balances_cache: self.balances_cache,
|
||||
time: self.time,
|
||||
finalized_checkpoint: self.finalized_checkpoint,
|
||||
justified_checkpoint: self.justified_checkpoint,
|
||||
justified_balances: self.justified_balances,
|
||||
balances_cache: from.balances_cache,
|
||||
time: from.time,
|
||||
finalized_checkpoint: from.finalized_checkpoint,
|
||||
justified_checkpoint: from.justified_checkpoint,
|
||||
justified_balances: from.justified_balances,
|
||||
best_justified_checkpoint: JUNK_BEST_JUSTIFIED_CHECKPOINT,
|
||||
unrealized_justified_checkpoint: self.unrealized_justified_checkpoint,
|
||||
unrealized_finalized_checkpoint: self.unrealized_finalized_checkpoint,
|
||||
proposer_boost_root: self.proposer_boost_root,
|
||||
equivocating_indices: self.equivocating_indices,
|
||||
unrealized_justified_checkpoint: from.unrealized_justified_checkpoint,
|
||||
unrealized_finalized_checkpoint: from.unrealized_finalized_checkpoint,
|
||||
proposer_boost_root: from.proposer_boost_root,
|
||||
equivocating_indices: from.equivocating_indices,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,20 +20,20 @@ pub struct PersistedForkChoice {
|
||||
pub fork_choice_store: PersistedForkChoiceStoreV17,
|
||||
}
|
||||
|
||||
impl Into<PersistedForkChoice> for PersistedForkChoiceV11 {
|
||||
fn into(self) -> PersistedForkChoice {
|
||||
impl From<PersistedForkChoiceV11> for PersistedForkChoice {
|
||||
fn from(from: PersistedForkChoiceV11) -> PersistedForkChoice {
|
||||
PersistedForkChoice {
|
||||
fork_choice: self.fork_choice,
|
||||
fork_choice_store: self.fork_choice_store.into(),
|
||||
fork_choice: from.fork_choice,
|
||||
fork_choice_store: from.fork_choice_store.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<PersistedForkChoiceV11> for PersistedForkChoice {
|
||||
fn into(self) -> PersistedForkChoiceV11 {
|
||||
impl From<PersistedForkChoice> for PersistedForkChoiceV11 {
|
||||
fn from(from: PersistedForkChoice) -> PersistedForkChoiceV11 {
|
||||
PersistedForkChoiceV11 {
|
||||
fork_choice: self.fork_choice,
|
||||
fork_choice_store: self.fork_choice_store.into(),
|
||||
fork_choice: from.fork_choice,
|
||||
fork_choice_store: from.fork_choice_store.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,9 +257,9 @@ pub mod deposit_methods {
|
||||
Latest,
|
||||
}
|
||||
|
||||
impl Into<u64> for Eth1Id {
|
||||
fn into(self) -> u64 {
|
||||
match self {
|
||||
impl From<Eth1Id> for u64 {
|
||||
fn from(from: Eth1Id) -> u64 {
|
||||
match from {
|
||||
Eth1Id::Mainnet => 1,
|
||||
Eth1Id::Custom(id) => id,
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ tempfile = { workspace = true }
|
||||
quickcheck = { workspace = true }
|
||||
quickcheck_macros = { workspace = true }
|
||||
async-channel = { workspace = true }
|
||||
logging = { workspace = true }
|
||||
|
||||
[features]
|
||||
libp2p-websocket = []
|
||||
|
||||
@@ -374,6 +374,12 @@ where
|
||||
id: outbound_info.req_id,
|
||||
})));
|
||||
}
|
||||
|
||||
// Also handle any events that are awaiting to be sent to the behaviour
|
||||
if !self.events_out.is_empty() {
|
||||
return Poll::Ready(Some(self.events_out.remove(0)));
|
||||
}
|
||||
|
||||
Poll::Ready(None)
|
||||
}
|
||||
|
||||
|
||||
@@ -316,6 +316,27 @@ where
|
||||
self.events.push(error_msg);
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the pending Requests to the disconnected peer
|
||||
// with reports of failed requests.
|
||||
self.events.iter_mut().for_each(|event| match &event {
|
||||
ToSwarm::NotifyHandler {
|
||||
peer_id: p,
|
||||
event: RPCSend::Request(request_id, req),
|
||||
..
|
||||
} if *p == peer_id => {
|
||||
*event = ToSwarm::GenerateEvent(RPCMessage {
|
||||
peer_id,
|
||||
conn_id: connection_id,
|
||||
event: HandlerEvent::Err(HandlerErr::Outbound {
|
||||
id: *request_id,
|
||||
proto: req.versioned_protocol().protocol(),
|
||||
error: RPCError::Disconnected,
|
||||
}),
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ impl<Id: ReqId, E: EthSpec> SelfRateLimiter<Id, E> {
|
||||
Err((rate_limited_req, wait_time)) => {
|
||||
let key = (peer_id, protocol);
|
||||
self.next_peer_request.insert(key, wait_time);
|
||||
queued_requests.push_back(rate_limited_req);
|
||||
queued_requests.push_front(rate_limited_req);
|
||||
// If one fails just wait for the next window that allows sending requests.
|
||||
return;
|
||||
}
|
||||
@@ -205,3 +205,72 @@ impl<Id: ReqId, E: EthSpec> SelfRateLimiter<Id, E> {
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::rpc::config::{OutboundRateLimiterConfig, RateLimiterConfig};
|
||||
use crate::rpc::rate_limiter::Quota;
|
||||
use crate::rpc::self_limiter::SelfRateLimiter;
|
||||
use crate::rpc::{OutboundRequest, Ping, Protocol};
|
||||
use crate::service::api_types::RequestId;
|
||||
use libp2p::PeerId;
|
||||
use std::time::Duration;
|
||||
use types::MainnetEthSpec;
|
||||
|
||||
/// Test that `next_peer_request_ready` correctly maintains the queue.
|
||||
#[tokio::test]
|
||||
async fn test_next_peer_request_ready() {
|
||||
let log = logging::test_logger();
|
||||
let config = OutboundRateLimiterConfig(RateLimiterConfig {
|
||||
ping_quota: Quota::n_every(1, 2),
|
||||
..Default::default()
|
||||
});
|
||||
let mut limiter: SelfRateLimiter<RequestId<u64>, MainnetEthSpec> =
|
||||
SelfRateLimiter::new(config, log).unwrap();
|
||||
let peer_id = PeerId::random();
|
||||
|
||||
for i in 1..=5 {
|
||||
let _ = limiter.allows(
|
||||
peer_id,
|
||||
RequestId::Application(i),
|
||||
OutboundRequest::Ping(Ping { data: i }),
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
let queue = limiter
|
||||
.delayed_requests
|
||||
.get(&(peer_id, Protocol::Ping))
|
||||
.unwrap();
|
||||
assert_eq!(4, queue.len());
|
||||
|
||||
// Check that requests in the queue are ordered in the sequence 2, 3, 4, 5.
|
||||
let mut iter = queue.iter();
|
||||
for i in 2..=5 {
|
||||
assert_eq!(iter.next().unwrap().request_id, RequestId::Application(i));
|
||||
}
|
||||
|
||||
assert_eq!(limiter.ready_requests.len(), 0);
|
||||
}
|
||||
|
||||
// Wait until the tokens have been regenerated, then run `next_peer_request_ready`.
|
||||
tokio::time::sleep(Duration::from_secs(3)).await;
|
||||
limiter.next_peer_request_ready(peer_id, Protocol::Ping);
|
||||
|
||||
{
|
||||
let queue = limiter
|
||||
.delayed_requests
|
||||
.get(&(peer_id, Protocol::Ping))
|
||||
.unwrap();
|
||||
assert_eq!(3, queue.len());
|
||||
|
||||
// Check that requests in the queue are ordered in the sequence 3, 4, 5.
|
||||
let mut iter = queue.iter();
|
||||
for i in 3..=5 {
|
||||
assert_eq!(iter.next().unwrap().request_id, RequestId::Application(i));
|
||||
}
|
||||
|
||||
assert_eq!(limiter.ready_requests.len(), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -700,7 +700,7 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
||||
"index" => %index,
|
||||
"commitment" => %commitment,
|
||||
);
|
||||
// Prevent recurring behaviour by penalizing the peer slightly.
|
||||
// Prevent recurring behaviour by penalizing the peer.
|
||||
self.gossip_penalize_peer(
|
||||
peer_id,
|
||||
PeerAction::LowToleranceError,
|
||||
@@ -712,10 +712,8 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
}
|
||||
GossipBlobError::FutureSlot { .. }
|
||||
| GossipBlobError::RepeatBlob { .. }
|
||||
| GossipBlobError::PastFinalizedSlot { .. } => {
|
||||
warn!(
|
||||
GossipBlobError::FutureSlot { .. } | GossipBlobError::RepeatBlob { .. } => {
|
||||
debug!(
|
||||
self.log,
|
||||
"Could not verify blob sidecar for gossip. Ignoring the blob sidecar";
|
||||
"error" => ?err,
|
||||
@@ -736,6 +734,30 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
||||
MessageAcceptance::Ignore,
|
||||
);
|
||||
}
|
||||
GossipBlobError::PastFinalizedSlot { .. } => {
|
||||
debug!(
|
||||
self.log,
|
||||
"Could not verify blob sidecar for gossip. Ignoring the blob sidecar";
|
||||
"error" => ?err,
|
||||
"slot" => %slot,
|
||||
"root" => %root,
|
||||
"index" => %index,
|
||||
"commitment" => %commitment,
|
||||
);
|
||||
// Prevent recurring behaviour by penalizing the peer. A low-tolerance
|
||||
// error is fine because there's no reason for peers to be propagating old
|
||||
// blobs on gossip, even if their view of finality is lagging.
|
||||
self.gossip_penalize_peer(
|
||||
peer_id,
|
||||
PeerAction::LowToleranceError,
|
||||
"gossip_blob_low",
|
||||
);
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id,
|
||||
MessageAcceptance::Ignore,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user