Skip to content

Commit

Permalink
Hacky way to retry applying orphan state witness if the parent block …
Browse files Browse the repository at this point in the history
…doesn't yet exist (#10535)
  • Loading branch information
robin-near authored Jan 31, 2024
1 parent d3ea7ed commit ef5564c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 8 deletions.
6 changes: 5 additions & 1 deletion chain/client/src/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ pub enum ProcessTxResponse {
pub struct ChunkStateWitnessMessage {
pub witness: ChunkStateWitness,
pub peer_id: PeerId,
pub attempts_remaining: usize,
}

#[derive(actix::Message, Debug)]
Expand Down Expand Up @@ -349,7 +350,10 @@ impl near_network::client::Client for Adapter {
async fn chunk_state_witness(&self, witness: ChunkStateWitness, peer_id: PeerId) {
match self
.client_addr
.send(ChunkStateWitnessMessage { witness, peer_id }.with_span_context())
.send(
ChunkStateWitnessMessage { witness, peer_id, attempts_remaining: 5 }
.with_span_context(),
)
.await
{
Ok(()) => {}
Expand Down
27 changes: 24 additions & 3 deletions chain/client/src/client_actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2006,11 +2006,32 @@ impl Handler<WithSpanContext<ChunkStateWitnessMessage>> for ClientActor {
fn handle(
&mut self,
msg: WithSpanContext<ChunkStateWitnessMessage>,
_: &mut Context<Self>,
ctx: &mut Context<Self>,
) -> Self::Result {
let (_span, msg) = handler_debug_span!(target: "client", msg);
if let Err(err) = self.client.process_chunk_state_witness(msg.witness, msg.peer_id) {
tracing::error!(target: "client", ?err, "Error processing chunk state witness");
let peer_id = msg.peer_id.clone();
let attempts_remaining = msg.attempts_remaining;
match self.client.process_chunk_state_witness(msg.witness, msg.peer_id) {
Err(err) => {
tracing::error!(target: "client", ?err, "Error processing chunk state witness");
}
Ok(Some(witness)) => {
if attempts_remaining > 0 {
ctx.run_later(Duration::from_millis(100), move |_, ctx| {
ctx.address().do_send(
ChunkStateWitnessMessage {
witness,
peer_id,
attempts_remaining: attempts_remaining - 1,
}
.with_span_context(),
);
});
} else {
tracing::error!(target: "client", "Failed to process chunk state witness even after 5 tries due to missing parent block");
}
}
Ok(None) => {}
}
}
}
Expand Down
13 changes: 9 additions & 4 deletions chain/client/src/stateless_validation/chunk_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,13 +574,18 @@ impl Client {
&mut self,
witness: ChunkStateWitness,
peer_id: PeerId,
) -> Result<(), Error> {
) -> Result<Option<ChunkStateWitness>, Error> {
// TODO(#10502): Handle production of state witness for first chunk after genesis.
// Properly handle case for chunk right after genesis.
// Context: We are currently unable to handle production of the state witness for the
// first chunk after genesis as it's not possible to run the genesis chunk in runtime.
let prev_block_hash = witness.inner.chunk_header.prev_block_hash();
let prev_block = self.chain.get_block(prev_block_hash)?;
let prev_block = match self.chain.get_block(prev_block_hash) {
Ok(block) => block,
Err(_) => {
return Ok(Some(witness));
}
};
let prev_chunk_header = Chain::get_prev_chunk_header(
self.epoch_manager.as_ref(),
&prev_block,
Expand All @@ -597,7 +602,7 @@ impl Client {
&self.chunk_validator.network_sender,
self.chunk_endorsement_tracker.chunk_endorsements.as_ref(),
);
return Ok(());
return Ok(None);
}

// TODO(#10265): If the previous block does not exist, we should
Expand All @@ -616,6 +621,6 @@ impl Client {
},
));
}
result
result.map(|_| None)
}
}

0 comments on commit ef5564c

Please sign in to comment.