Skip to content

Commit 53d9fae

Browse files
authored
Merge of #5010
2 parents e278d54 + 26a62fb commit 53d9fae

File tree

7 files changed

+455
-140
lines changed

7 files changed

+455
-140
lines changed

beacon_node/client/src/builder.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ where
505505
network_senders: None,
506506
network_globals: None,
507507
beacon_processor_send: None,
508+
beacon_processor_reprocess_send: None,
508509
eth1_service: Some(genesis_service.eth1_service.clone()),
509510
log: context.log().clone(),
510511
sse_logging_components: runtime_context.sse_logging_components.clone(),
@@ -747,6 +748,9 @@ where
747748
network_globals: self.network_globals.clone(),
748749
eth1_service: self.eth1_service.clone(),
749750
beacon_processor_send: Some(beacon_processor_channels.beacon_processor_tx.clone()),
751+
beacon_processor_reprocess_send: Some(
752+
beacon_processor_channels.work_reprocessing_tx.clone(),
753+
),
750754
sse_logging_components: runtime_context.sse_logging_components.clone(),
751755
log: log.clone(),
752756
});

beacon_node/http_api/src/lib.rs

Lines changed: 22 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ mod database;
1616
mod metrics;
1717
mod produce_block;
1818
mod proposer_duties;
19+
mod publish_attestations;
1920
mod publish_blocks;
2021
mod standard_block_rewards;
2122
mod state_id;
@@ -35,7 +36,7 @@ use beacon_chain::{
3536
validator_monitor::timestamp_now, AttestationError as AttnError, BeaconChain, BeaconChainError,
3637
BeaconChainTypes, WhenSlotSkipped,
3738
};
38-
use beacon_processor::BeaconProcessorSend;
39+
use beacon_processor::{work_reprocessing_queue::ReprocessQueueMessage, BeaconProcessorSend};
3940
pub use block_id::BlockId;
4041
use builder_states::get_next_withdrawals;
4142
use bytes::Bytes;
@@ -129,6 +130,7 @@ pub struct Context<T: BeaconChainTypes> {
129130
pub network_senders: Option<NetworkSenders<T::EthSpec>>,
130131
pub network_globals: Option<Arc<NetworkGlobals<T::EthSpec>>>,
131132
pub beacon_processor_send: Option<BeaconProcessorSend<T::EthSpec>>,
133+
pub beacon_processor_reprocess_send: Option<Sender<ReprocessQueueMessage>>,
132134
pub eth1_service: Option<eth1::Service>,
133135
pub sse_logging_components: Option<SSELoggingComponents>,
134136
pub log: Logger,
@@ -534,6 +536,11 @@ pub fn serve<T: BeaconChainTypes>(
534536
.filter(|_| config.enable_beacon_processor);
535537
let task_spawner_filter =
536538
warp::any().map(move || TaskSpawner::new(beacon_processor_send.clone()));
539+
let beacon_processor_reprocess_send = ctx
540+
.beacon_processor_reprocess_send
541+
.clone()
542+
.filter(|_| config.enable_beacon_processor);
543+
let reprocess_send_filter = warp::any().map(move || beacon_processor_reprocess_send.clone());
537544

538545
let duplicate_block_status_code = ctx.config.duplicate_block_status_code;
539546

@@ -1756,140 +1763,26 @@ pub fn serve<T: BeaconChainTypes>(
17561763
.and(warp::path::end())
17571764
.and(warp_utils::json::json())
17581765
.and(network_tx_filter.clone())
1766+
.and(reprocess_send_filter)
17591767
.and(log_filter.clone())
17601768
.then(
17611769
|task_spawner: TaskSpawner<T::EthSpec>,
17621770
chain: Arc<BeaconChain<T>>,
17631771
attestations: Vec<Attestation<T::EthSpec>>,
17641772
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
1765-
log: Logger| {
1766-
task_spawner.blocking_json_task(Priority::P0, move || {
1767-
let seen_timestamp = timestamp_now();
1768-
let mut failures = Vec::new();
1769-
let mut num_already_known = 0;
1770-
1771-
for (index, attestation) in attestations.as_slice().iter().enumerate() {
1772-
let attestation = match chain
1773-
.verify_unaggregated_attestation_for_gossip(attestation, None)
1774-
{
1775-
Ok(attestation) => attestation,
1776-
Err(AttnError::PriorAttestationKnown { .. }) => {
1777-
num_already_known += 1;
1778-
1779-
// Skip to the next attestation since an attestation for this
1780-
// validator is already known in this epoch.
1781-
//
1782-
// There's little value for the network in validating a second
1783-
// attestation for another validator since it is either:
1784-
//
1785-
// 1. A duplicate.
1786-
// 2. Slashable.
1787-
// 3. Invalid.
1788-
//
1789-
// We are likely to get duplicates in the case where a VC is using
1790-
// fallback BNs. If the first BN actually publishes some/all of a
1791-
// batch of attestations but fails to respond in a timely fashion,
1792-
// the VC is likely to try publishing the attestations on another
1793-
// BN. That second BN may have already seen the attestations from
1794-
// the first BN and therefore indicate that the attestations are
1795-
// "already seen". An attestation that has already been seen has
1796-
// been published on the network so there's no actual error from
1797-
// the perspective of the user.
1798-
//
1799-
// It's better to prevent slashable attestations from ever
1800-
// appearing on the network than trying to slash validators,
1801-
// especially those validators connected to the local API.
1802-
//
1803-
// There might be *some* value in determining that this attestation
1804-
// is invalid, but since a valid attestation already it exists it
1805-
// appears that this validator is capable of producing valid
1806-
// attestations and there's no immediate cause for concern.
1807-
continue;
1808-
}
1809-
Err(e) => {
1810-
error!(log,
1811-
"Failure verifying attestation for gossip";
1812-
"error" => ?e,
1813-
"request_index" => index,
1814-
"committee_index" => attestation.data.index,
1815-
"attestation_slot" => attestation.data.slot,
1816-
);
1817-
failures.push(api_types::Failure::new(
1818-
index,
1819-
format!("Verification: {:?}", e),
1820-
));
1821-
// skip to the next attestation so we do not publish this one to gossip
1822-
continue;
1823-
}
1824-
};
1825-
1826-
// Notify the validator monitor.
1827-
chain
1828-
.validator_monitor
1829-
.read()
1830-
.register_api_unaggregated_attestation(
1831-
seen_timestamp,
1832-
attestation.indexed_attestation(),
1833-
&chain.slot_clock,
1834-
);
1835-
1836-
publish_pubsub_message(
1837-
&network_tx,
1838-
PubsubMessage::Attestation(Box::new((
1839-
attestation.subnet_id(),
1840-
attestation.attestation().clone(),
1841-
))),
1842-
)?;
1843-
1844-
let committee_index = attestation.attestation().data.index;
1845-
let slot = attestation.attestation().data.slot;
1846-
1847-
if let Err(e) = chain.apply_attestation_to_fork_choice(&attestation) {
1848-
error!(log,
1849-
"Failure applying verified attestation to fork choice";
1850-
"error" => ?e,
1851-
"request_index" => index,
1852-
"committee_index" => committee_index,
1853-
"slot" => slot,
1854-
);
1855-
failures.push(api_types::Failure::new(
1856-
index,
1857-
format!("Fork choice: {:?}", e),
1858-
));
1859-
};
1860-
1861-
if let Err(e) = chain.add_to_naive_aggregation_pool(&attestation) {
1862-
error!(log,
1863-
"Failure adding verified attestation to the naive aggregation pool";
1864-
"error" => ?e,
1865-
"request_index" => index,
1866-
"committee_index" => committee_index,
1867-
"slot" => slot,
1868-
);
1869-
failures.push(api_types::Failure::new(
1870-
index,
1871-
format!("Naive aggregation pool: {:?}", e),
1872-
));
1873-
}
1874-
}
1875-
1876-
if num_already_known > 0 {
1877-
debug!(
1878-
log,
1879-
"Some unagg attestations already known";
1880-
"count" => num_already_known
1881-
);
1882-
}
1883-
1884-
if failures.is_empty() {
1885-
Ok(())
1886-
} else {
1887-
Err(warp_utils::reject::indexed_bad_request(
1888-
"error processing attestations".to_string(),
1889-
failures,
1890-
))
1891-
}
1892-
})
1773+
reprocess_tx: Option<Sender<ReprocessQueueMessage>>,
1774+
log: Logger| async move {
1775+
let result = crate::publish_attestations::publish_attestations(
1776+
task_spawner,
1777+
chain,
1778+
attestations,
1779+
network_tx,
1780+
reprocess_tx,
1781+
log,
1782+
)
1783+
.await
1784+
.map(|()| warp::reply::json(&()));
1785+
task_spawner::convert_rejection(result).await
18931786
},
18941787
);
18951788

0 commit comments

Comments
 (0)