Skip to content

Commit

Permalink
Fixed VC panic when fee-recipient-file is unreadable & reload cached …
Browse files Browse the repository at this point in the history
…file contents
  • Loading branch information
pk910 committed Jan 19, 2022
1 parent 815b4de commit 4330306
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 42 deletions.
2 changes: 1 addition & 1 deletion beacon_node/execution_layer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ impl ExecutionLayer {
) -> Result<(), Error> {
info!(
self.log(),
"Received proposer preperation data";
"Received proposer preparation data";
"count" => preparation_data.len(),
);

Expand Down
8 changes: 4 additions & 4 deletions validator_client/src/fee_recipient_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@ impl FeeRecipientFile {
/// default fee-recipient.
///
/// Returns an error if loading from the fee-recipient file fails.
pub fn get_fee_recipient(
&mut self,
public_key: &PublicKeyBytes,
) -> Result<Option<Address>, Error> {
pub fn get_fee_recipient(&self, public_key: &PublicKeyBytes) -> Result<Option<Address>, Error> {
Ok(self
.fee_recipients
.get(public_key)
Expand Down Expand Up @@ -82,6 +79,9 @@ impl FeeRecipientFile {

let lines = reader.lines();

self.default = None;
self.fee_recipients.clear();

for line in lines {
let line = line.map_err(|e| Error::InvalidLine(e.to_string()))?;
let (pk_opt, fee_recipient) = read_line(&line)?;
Expand Down
104 changes: 67 additions & 37 deletions validator_client/src/preparation_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,16 @@ impl<T: SlotClock + 'static, E: EthSpec> PreparationService<T, E> {
self.slot_clock.duration_to_next_epoch(E::slots_per_epoch())
{
sleep(duration_to_next_epoch).await;
self.prepare_proposers_and_publish().await.unwrap();
self.prepare_proposers_and_publish()
.await
.map_err(|e| {
error!(
log,
"Error during proposer preparation";
"error" => format!("{:?}", e),
)
})
.unwrap_or(());
} else {
error!(log, "Failed to read slot clock");
// If we can't read the slot clock, just wait another slot.
Expand All @@ -157,29 +166,45 @@ impl<T: SlotClock + 'static, E: EthSpec> PreparationService<T, E> {

/// Prepare proposer preparations and send to beacon node
async fn prepare_proposers_and_publish(&self) -> Result<(), String> {
let preparation_data = self.collect_preparation_data().unwrap();
if !preparation_data.is_empty() {
self.publish_preparation_data(preparation_data).await?;
}

Ok(())
}

fn collect_preparation_data(&self) -> Result<Vec<ProposerPreparationData>, String> {
let log = self.context.log();

let fee_recipient_file = self
.fee_recipient_file
.clone()
.map(|mut fee_recipient_file| {
fee_recipient_file
.read_fee_recipient_file()
.map_err(|e| {
error!(
log,
"{}", format!("Error loading fee-recipient file: {:?}", e);
);
})
.unwrap_or(());
fee_recipient_file
});

let all_pubkeys: Vec<_> = self
.validator_store
.voting_pubkeys(DoppelgangerStatus::ignored);

if self.fee_recipient_file.is_some() {
self.fee_recipient_file
.clone()
.unwrap()
.read_fee_recipient_file()
.unwrap();
}

let preparation_data: Vec<_> = all_pubkeys
.into_iter()
.filter_map(|pubkey| {
let validator_index = self.validator_store.validator_index(&pubkey);
if let Some(validator_index) = validator_index {
let fee_recipient = self
.fee_recipient_file
.clone()
.and_then(|mut g| match g.get_fee_recipient(&pubkey) {
let fee_recipient = fee_recipient_file
.as_ref()
.and_then(|g| match g.get_fee_recipient(&pubkey) {
Ok(g) => g,
Err(_e) => None,
})
Expand All @@ -195,33 +220,38 @@ impl<T: SlotClock + 'static, E: EthSpec> PreparationService<T, E> {
})
.collect();

let proposal_preparation = preparation_data.as_slice();
Ok(preparation_data)
}

async fn publish_preparation_data(
&self,
preparation_data: Vec<ProposerPreparationData>,
) -> Result<(), String> {
let log = self.context.log();

// Post the proposer preparations to the BN.
let preparation_data_len = preparation_data.len();
if preparation_data_len > 0 {
// Post the proposer preparations to the BN.
match self
.beacon_nodes
.first_success(RequireSynced::Yes, |beacon_node| async move {
beacon_node
.post_validator_prepare_beacon_proposer(proposal_preparation)
.await
})
.await
{
Ok(()) => info!(
log,
"Successfully published proposer preparation";
"count" => preparation_data_len,
),
Err(e) => error!(
log,
"Unable to publish proposer preparation";
"error" => %e,
),
}
let preparation_entries = preparation_data.as_slice();
match self
.beacon_nodes
.first_success(RequireSynced::Yes, |beacon_node| async move {
beacon_node
.post_validator_prepare_beacon_proposer(preparation_entries)
.await
})
.await
{
Ok(()) => info!(
log,
"Successfully published proposer preparation";
"count" => preparation_data_len,
),
Err(e) => error!(
log,
"Unable to publish proposer preparation";
"error" => %e,
),
}

Ok(())
}
}

0 comments on commit 4330306

Please sign in to comment.