diff --git a/chain/chain-primitives/src/error.rs b/chain/chain-primitives/src/error.rs index 7dce544cc69..00762405ba0 100644 --- a/chain/chain-primitives/src/error.rs +++ b/chain/chain-primitives/src/error.rs @@ -313,6 +313,16 @@ impl From for Error { } } +pub trait EpochErrorResultToChainError { + fn into_chain_error(self) -> Result; +} + +impl EpochErrorResultToChainError for Result { + fn into_chain_error(self: Result) -> Result { + self.map_err(|err| err.into()) + } +} + impl From for Error { fn from(error: ShardLayoutError) -> Self { match error { diff --git a/chain/chain/src/chain.rs b/chain/chain/src/chain.rs index 7fd2187292e..db553cae3e6 100644 --- a/chain/chain/src/chain.rs +++ b/chain/chain/src/chain.rs @@ -3547,7 +3547,7 @@ impl Chain { ) -> Result { let head = self.head()?; let target_height = head.height + horizon - 1; - self.runtime_adapter.get_chunk_producer(epoch_id, target_height, shard_id) + Ok(self.runtime_adapter.get_chunk_producer(epoch_id, target_height, shard_id)?) } /// Find a validator that is responsible for a given shard to forward requests to @@ -4503,7 +4503,7 @@ impl Chain { { let prev_hash = *sync_block.header().prev_hash(); // If sync_hash is not on the Epoch boundary, it's malicious behavior - self.runtime_adapter.is_next_block_epoch_start(&prev_hash) + Ok(self.runtime_adapter.is_next_block_epoch_start(&prev_hash)?) } else { Ok(false) // invalid Epoch of sync_hash, possible malicious behavior } diff --git a/chain/chain/src/test_utils/kv_runtime.rs b/chain/chain/src/test_utils/kv_runtime.rs index 9cceb3962a5..4801b9e5153 100644 --- a/chain/chain/src/test_utils/kv_runtime.rs +++ b/chain/chain/src/test_utils/kv_runtime.rs @@ -231,7 +231,7 @@ impl KeyValueRuntime { self.tracks_all_shards = tracks_all_shards; } - fn get_block_header(&self, hash: &CryptoHash) -> Result, Error> { + fn get_block_header(&self, hash: &CryptoHash) -> Result, EpochError> { let mut headers_cache = self.headers_cache.write().unwrap(); if headers_cache.get(hash).is_some() { return Ok(Some(headers_cache.get(hash).unwrap().clone())); @@ -250,13 +250,13 @@ impl KeyValueRuntime { fn get_epoch_and_valset( &self, prev_hash: CryptoHash, - ) -> Result<(EpochId, usize, EpochId), Error> { + ) -> Result<(EpochId, usize, EpochId), EpochError> { if prev_hash == CryptoHash::default() { return Ok((EpochId(prev_hash), 0, EpochId(prev_hash))); } let prev_block_header = self .get_block_header(&prev_hash)? - .ok_or_else(|| Error::DBNotFoundErr(prev_hash.to_string()))?; + .ok_or_else(|| EpochError::MissingBlock(prev_hash))?; let mut hash_to_epoch = self.hash_to_epoch.write().unwrap(); let mut hash_to_next_epoch_approvals_req = @@ -326,7 +326,7 @@ impl KeyValueRuntime { self.validators_by_valset[valset].chunk_producers[shard_id as usize].clone() } - fn get_valset_for_epoch(&self, epoch_id: &EpochId) -> Result { + fn get_valset_for_epoch(&self, epoch_id: &EpochId) -> Result { // conveniently here if the prev_hash is passed mistakenly instead of the epoch_hash, // the `unwrap` will trigger Ok(*self @@ -334,7 +334,7 @@ impl KeyValueRuntime { .read() .unwrap() .get(epoch_id) - .ok_or_else(|| Error::EpochOutOfBounds(epoch_id.clone()))? as usize + .ok_or_else(|| EpochError::EpochOutOfBounds(epoch_id.clone()))? as usize % self.validators_by_valset.len()) } @@ -342,7 +342,7 @@ impl KeyValueRuntime { &self, epoch_id: &EpochId, shard_id: ShardId, - ) -> Result, Error> { + ) -> Result, EpochError> { let valset = self.get_valset_for_epoch(epoch_id)?; let block_producers = &self.validators_by_valset[valset].block_producers; let chunk_producers = &self.validators_by_valset[valset].chunk_producers[shard_id as usize]; @@ -377,7 +377,7 @@ impl EpochManagerAdapter for KeyValueRuntime { self.hash_to_valset.write().unwrap().contains_key(epoch_id) } - fn num_shards(&self, _epoch_id: &EpochId) -> Result { + fn num_shards(&self, _epoch_id: &EpochId) -> Result { Ok(self.num_shards) } @@ -395,7 +395,7 @@ impl EpochManagerAdapter for KeyValueRuntime { } } - fn get_part_owner(&self, epoch_id: &EpochId, part_id: u64) -> Result { + fn get_part_owner(&self, epoch_id: &EpochId, part_id: u64) -> Result { let validators = &self.get_epoch_block_producers_ordered(epoch_id, &CryptoHash::default())?; // if we don't use data_parts and total_parts as part of the formula here, the part owner @@ -408,19 +408,23 @@ impl EpochManagerAdapter for KeyValueRuntime { &self, account_id: &AccountId, _epoch_id: &EpochId, - ) -> Result { + ) -> Result { Ok(account_id_to_shard_id(account_id, self.num_shards)) } - fn shard_id_to_uid(&self, shard_id: ShardId, _epoch_id: &EpochId) -> Result { + fn shard_id_to_uid( + &self, + shard_id: ShardId, + _epoch_id: &EpochId, + ) -> Result { Ok(ShardUId { version: 0, shard_id: shard_id as u32 }) } - fn get_block_info(&self, _hash: &CryptoHash) -> Result, Error> { + fn get_block_info(&self, _hash: &CryptoHash) -> Result, EpochError> { Ok(Default::default()) } - fn get_epoch_config(&self, _epoch_id: &EpochId) -> Result { + fn get_epoch_config(&self, _epoch_id: &EpochId) -> Result { Ok(EpochConfig { epoch_length: 10, num_block_producer_seats: 2, @@ -447,7 +451,7 @@ impl EpochManagerAdapter for KeyValueRuntime { /// - block producers /// - chunk producers /// All the other fields have a hardcoded value or left empty. - fn get_epoch_info(&self, _epoch_id: &EpochId) -> Result, Error> { + fn get_epoch_info(&self, _epoch_id: &EpochId) -> Result, EpochError> { let validators = self.validators.iter().map(|(_, stake)| stake.clone()).collect(); let mut validator_to_index = HashMap::new(); for (i, (account_id, _)) in self.validators.iter().enumerate() { @@ -486,41 +490,44 @@ impl EpochManagerAdapter for KeyValueRuntime { ))) } - fn get_shard_layout(&self, _epoch_id: &EpochId) -> Result { + fn get_shard_layout(&self, _epoch_id: &EpochId) -> Result { Ok(ShardLayout::v0(self.num_shards, 0)) } - fn get_shard_config(&self, _epoch_id: &EpochId) -> Result { + fn get_shard_config(&self, _epoch_id: &EpochId) -> Result { panic!("get_shard_config not implemented for KeyValueRuntime"); } - fn is_next_block_epoch_start(&self, parent_hash: &CryptoHash) -> Result { + fn is_next_block_epoch_start(&self, parent_hash: &CryptoHash) -> Result { if parent_hash == &CryptoHash::default() { return Ok(true); } - let prev_block_header = self.get_block_header(parent_hash)?.ok_or_else(|| { - Error::Other(format!("Missing block {} when computing the epoch", parent_hash)) - })?; + let prev_block_header = self + .get_block_header(parent_hash)? + .ok_or_else(|| EpochError::MissingBlock(*parent_hash))?; let prev_prev_hash = *prev_block_header.prev_hash(); Ok(self.get_epoch_and_valset(*parent_hash)?.0 != self.get_epoch_and_valset(prev_prev_hash)?.0) } - fn get_epoch_id_from_prev_block(&self, parent_hash: &CryptoHash) -> Result { + fn get_epoch_id_from_prev_block( + &self, + parent_hash: &CryptoHash, + ) -> Result { Ok(self.get_epoch_and_valset(*parent_hash)?.0) } fn get_epoch_height_from_prev_block( &self, _prev_block_hash: &CryptoHash, - ) -> Result { + ) -> Result { Ok(0) } fn get_next_epoch_id_from_prev_block( &self, parent_hash: &CryptoHash, - ) -> Result { + ) -> Result { Ok(self.get_epoch_and_valset(*parent_hash)?.2) } @@ -535,11 +542,11 @@ impl EpochManagerAdapter for KeyValueRuntime { fn get_shard_layout_from_prev_block( &self, _parent_hash: &CryptoHash, - ) -> Result { + ) -> Result { Ok(ShardLayout::v0(self.num_shards, 0)) } - fn get_epoch_id(&self, block_hash: &CryptoHash) -> Result { + fn get_epoch_id(&self, block_hash: &CryptoHash) -> Result { let (epoch_id, _, _) = self.get_epoch_and_valset(*block_hash)?; Ok(epoch_id) } @@ -548,17 +555,17 @@ impl EpochManagerAdapter for KeyValueRuntime { &self, epoch_id: &EpochId, other_epoch_id: &EpochId, - ) -> Result { + ) -> Result { if epoch_id.0 == other_epoch_id.0 { return Ok(Ordering::Equal); } match (self.get_valset_for_epoch(epoch_id), self.get_valset_for_epoch(other_epoch_id)) { (Ok(index1), Ok(index2)) => Ok(index1.cmp(&index2)), - _ => Err(Error::EpochOutOfBounds(epoch_id.clone())), + _ => Err(EpochError::EpochOutOfBounds(epoch_id.clone())), } } - fn get_epoch_start_height(&self, block_hash: &CryptoHash) -> Result { + fn get_epoch_start_height(&self, block_hash: &CryptoHash) -> Result { let epoch_id = self.get_epoch_id(block_hash)?; match self.get_block_header(&epoch_id.0)? { Some(block_header) => Ok(block_header.height()), @@ -569,12 +576,12 @@ impl EpochManagerAdapter for KeyValueRuntime { fn get_prev_epoch_id_from_prev_block( &self, prev_block_hash: &CryptoHash, - ) -> Result { + ) -> Result { let mut candidate_hash = *prev_block_hash; loop { let header = self .get_block_header(&candidate_hash)? - .ok_or_else(|| Error::DBNotFoundErr(candidate_hash.to_string()))?; + .ok_or_else(|| EpochError::MissingBlock(candidate_hash))?; candidate_hash = *header.prev_hash(); if self.is_next_block_epoch_start(&candidate_hash)? { break Ok(self.get_epoch_and_valset(candidate_hash)?.0); @@ -593,7 +600,7 @@ impl EpochManagerAdapter for KeyValueRuntime { &self, epoch_id: &EpochId, _last_known_block_hash: &CryptoHash, - ) -> Result, Error> { + ) -> Result, EpochError> { let validators = self.get_block_producers(self.get_valset_for_epoch(epoch_id)?); Ok(validators.iter().map(|x| (x.clone(), false)).collect()) } @@ -601,7 +608,7 @@ impl EpochManagerAdapter for KeyValueRuntime { fn get_epoch_block_approvers_ordered( &self, parent_hash: &CryptoHash, - ) -> Result, Error> { + ) -> Result, EpochError> { let (_cur_epoch, cur_valset, next_epoch) = self.get_epoch_and_valset(*parent_hash)?; let mut validators = self .get_block_producers(cur_valset) @@ -623,7 +630,10 @@ impl EpochManagerAdapter for KeyValueRuntime { Ok(validators) } - fn get_epoch_chunk_producers(&self, _epoch_id: &EpochId) -> Result, Error> { + fn get_epoch_chunk_producers( + &self, + _epoch_id: &EpochId, + ) -> Result, EpochError> { tracing::warn!("not implemented, returning a dummy value"); Ok(vec![]) } @@ -632,7 +642,7 @@ impl EpochManagerAdapter for KeyValueRuntime { &self, epoch_id: &EpochId, height: BlockHeight, - ) -> Result { + ) -> Result { let validators = self.get_block_producers(self.get_valset_for_epoch(epoch_id)?); Ok(validators[(height as usize) % validators.len()].account_id().clone()) } @@ -642,7 +652,7 @@ impl EpochManagerAdapter for KeyValueRuntime { epoch_id: &EpochId, height: BlockHeight, shard_id: ShardId, - ) -> Result { + ) -> Result { let valset = self.get_valset_for_epoch(epoch_id)?; let chunk_producers = self.get_chunk_producers(valset, shard_id); let index = (shard_id + height + 1) as usize % chunk_producers.len(); @@ -654,7 +664,7 @@ impl EpochManagerAdapter for KeyValueRuntime { epoch_id: &EpochId, _last_known_block_hash: &CryptoHash, account_id: &AccountId, - ) -> Result<(ValidatorStake, bool), Error> { + ) -> Result<(ValidatorStake, bool), EpochError> { let validators = &self.validators_by_valset[self.get_valset_for_epoch(epoch_id)?]; for validator_stake in validators.block_producers.iter() { if validator_stake.account_id() == account_id { @@ -666,22 +676,22 @@ impl EpochManagerAdapter for KeyValueRuntime { return Ok((validator_stake.clone(), false)); } } - Err(Error::NotAValidator) + Err(EpochError::NotAValidator(account_id.clone(), epoch_id.clone())) } fn get_fisherman_by_account_id( &self, - _epoch_id: &EpochId, + epoch_id: &EpochId, _last_known_block_hash: &CryptoHash, - _account_id: &AccountId, - ) -> Result<(ValidatorStake, bool), Error> { - Err(Error::NotAValidator) + account_id: &AccountId, + ) -> Result<(ValidatorStake, bool), EpochError> { + Err(EpochError::NotAValidator(account_id.clone(), epoch_id.clone())) } fn get_validator_info( &self, _epoch_id: ValidatorInfoIdentifier, - ) -> Result { + ) -> Result { Ok(EpochValidatorInfo { current_validators: vec![], next_validators: vec![], @@ -694,11 +704,14 @@ impl EpochManagerAdapter for KeyValueRuntime { }) } - fn get_epoch_minted_amount(&self, _epoch_id: &EpochId) -> Result { + fn get_epoch_minted_amount(&self, _epoch_id: &EpochId) -> Result { Ok(0) } - fn get_epoch_protocol_version(&self, _epoch_id: &EpochId) -> Result { + fn get_epoch_protocol_version( + &self, + _epoch_id: &EpochId, + ) -> Result { Ok(PROTOCOL_VERSION) } @@ -716,7 +729,7 @@ impl EpochManagerAdapter for KeyValueRuntime { Arc, Arc, ), - Error, + EpochError, > { Ok(Default::default()) } @@ -732,7 +745,7 @@ impl EpochManagerAdapter for KeyValueRuntime { _epoch_info: EpochInfo, _next_epoch_id: &EpochId, _next_epoch_info: EpochInfo, - ) -> Result<(), Error> { + ) -> Result<(), EpochError> { Ok(()) } diff --git a/chain/chunks-primitives/src/error.rs b/chain/chunks-primitives/src/error.rs index faa84b3b596..3bd48030494 100644 --- a/chain/chunks-primitives/src/error.rs +++ b/chain/chunks-primitives/src/error.rs @@ -1,5 +1,7 @@ use std::fmt; +use near_primitives::errors::EpochError; + #[derive(Debug)] pub enum Error { InvalidPartMessage, @@ -35,3 +37,9 @@ impl From for Error { Error::ChainError(err) } } + +impl From for Error { + fn from(err: EpochError) -> Self { + Error::ChainError(err.into()) + } +} diff --git a/chain/client-primitives/src/types.rs b/chain/client-primitives/src/types.rs index 781e675a22d..a013bd1c2c1 100644 --- a/chain/client-primitives/src/types.rs +++ b/chain/client-primitives/src/types.rs @@ -39,6 +39,12 @@ pub enum Error { Other(String), } +impl From for Error { + fn from(err: near_primitives::errors::EpochError) -> Self { + Error::Chain(err.into()) + } +} + #[derive(Clone, Debug, serde::Serialize, PartialEq)] pub enum AccountOrPeerIdOrHash { AccountId(AccountId), diff --git a/chain/client/src/client.rs b/chain/client/src/client.rs index 3945d3fbcdb..e19cadd5c71 100644 --- a/chain/client/src/client.rs +++ b/chain/client/src/client.rs @@ -41,6 +41,7 @@ use near_primitives::block::{Approval, ApprovalInner, ApprovalMessage, Block, Bl use near_primitives::block_header::ApprovalType; use near_primitives::challenge::{Challenge, ChallengeBody}; use near_primitives::epoch_manager::RngSeed; +use near_primitives::errors::EpochError; use near_primitives::hash::CryptoHash; use near_primitives::merkle::{merklize, MerklePath, PartialMerkleTree}; use near_primitives::network::PeerId; @@ -1754,7 +1755,7 @@ impl Client { let next_block_epoch_id = match self.runtime_adapter.get_epoch_id_from_prev_block(&parent_hash) { Err(e) => { - self.handle_process_approval_error(approval, approval_type, true, e); + self.handle_process_approval_error(approval, approval_type, true, e.into()); return; } Ok(next_epoch_id) => next_epoch_id, @@ -1775,7 +1776,7 @@ impl Client { account_id, ) { Ok(_) => next_block_epoch_id.clone(), - Err(near_chain::Error::NotAValidator) => { + Err(EpochError::NotAValidator(_, _)) => { match self.runtime_adapter.get_next_epoch_id_from_prev_block(&parent_hash) { Ok(next_block_next_epoch_id) => next_block_next_epoch_id, Err(_) => return, diff --git a/chain/client/src/client_actor.rs b/chain/client/src/client_actor.rs index 009bab08e4e..08c05ddc2cc 100644 --- a/chain/client/src/client_actor.rs +++ b/chain/client/src/client_actor.rs @@ -33,6 +33,7 @@ use near_chain::{ ChainGenesis, DoneApplyChunkCallback, Provenance, RuntimeWithEpochManagerAdapter, }; use near_chain_configs::{ClientConfig, LogSummaryStyle}; +use near_chain_primitives::error::EpochErrorResultToChainError; use near_chunks::adapter::ShardsManagerRequestFromClient; use near_chunks::client::ShardsManagerResponse; use near_chunks::logic::cares_about_shard_this_or_next_epoch; @@ -652,7 +653,8 @@ impl Handler> for ClientActor { let validators: Vec = self .client .runtime_adapter - .get_epoch_block_producers_ordered(&head.epoch_id, &head.last_block_hash)? + .get_epoch_block_producers_ordered(&head.epoch_id, &head.last_block_hash) + .into_chain_error()? .into_iter() .map(|(validator_stake, is_slashed)| ValidatorInfo { account_id: validator_stake.take_account_id(), @@ -663,8 +665,11 @@ impl Handler> for ClientActor { let epoch_start_height = self.client.runtime_adapter.get_epoch_start_height(&head.last_block_hash).ok(); - let protocol_version = - self.client.runtime_adapter.get_epoch_protocol_version(&head.epoch_id)?; + let protocol_version = self + .client + .runtime_adapter + .get_epoch_protocol_version(&head.epoch_id) + .into_chain_error()?; let node_public_key = self.node_id.public_key().clone(); let (validator_account_id, validator_public_key) = match &self.client.validator_signer { diff --git a/chain/client/src/view_client.rs b/chain/client/src/view_client.rs index 21a44c7da9f..db244d6dedb 100644 --- a/chain/client/src/view_client.rs +++ b/chain/client/src/view_client.rs @@ -4,6 +4,7 @@ use actix::{Actor, Addr, Handler, SyncArbiter, SyncContext}; use near_async::messaging::CanSend; use near_chain::types::Tip; +use near_chain_primitives::error::EpochErrorResultToChainError; use near_primitives::receipt::Receipt; use near_primitives::static_clock::StaticClock; use near_store::{DBCol, COLD_HEAD_KEY, FINAL_HEAD_KEY, HEAD_KEY}; @@ -552,7 +553,8 @@ impl Handler> for ViewClientActor { let block = self.get_block_by_reference(&msg.0)?.ok_or(GetBlockError::NotSyncedYet)?; let block_author = self .runtime_adapter - .get_block_producer(block.header().epoch_id(), block.header().height())?; + .get_block_producer(block.header().epoch_id(), block.header().height()) + .into_chain_error()?; Ok(BlockView::from_author_block(block_author, block)) } } @@ -623,13 +625,14 @@ impl Handler> for ViewClientActor { }; let chunk_inner = chunk.cloned_header().take_inner(); - let epoch_id = - self.runtime_adapter.get_epoch_id_from_prev_block(chunk_inner.prev_block_hash())?; - let author = self.runtime_adapter.get_chunk_producer( - &epoch_id, - chunk_inner.height_created(), - chunk_inner.shard_id(), - )?; + let epoch_id = self + .runtime_adapter + .get_epoch_id_from_prev_block(chunk_inner.prev_block_hash()) + .into_chain_error()?; + let author = self + .runtime_adapter + .get_chunk_producer(&epoch_id, chunk_inner.height_created(), chunk_inner.shard_id()) + .into_chain_error()?; Ok(ChunkView::from_author_chunk(author, chunk)) } @@ -693,9 +696,7 @@ impl Handler> for ViewClientActor { ValidatorInfoIdentifier::BlockHash(self.chain.header_head()?.last_block_hash) } }; - self.runtime_adapter - .get_validator_info(epoch_identifier) - .map_err(GetValidatorInfoError::from) + Ok(self.runtime_adapter.get_validator_info(epoch_identifier).into_chain_error()?) } } @@ -914,8 +915,10 @@ impl Handler> for ViewClientActor { let mut outcome_proof = outcome; let epoch_id = self.chain.get_block(&outcome_proof.block_hash)?.header().epoch_id().clone(); - let target_shard_id = - self.runtime_adapter.account_id_to_shard_id(&account_id, &epoch_id)?; + let target_shard_id = self + .runtime_adapter + .account_id_to_shard_id(&account_id, &epoch_id) + .into_chain_error()?; let res = self.chain.get_next_block_hash_with_new_chunk( &outcome_proof.block_hash, target_shard_id, @@ -948,8 +951,10 @@ impl Handler> for ViewClientActor { } Err(near_chain::Error::DBNotFoundErr(_)) => { let head = self.chain.head()?; - let target_shard_id = - self.runtime_adapter.account_id_to_shard_id(&account_id, &head.epoch_id)?; + let target_shard_id = self + .runtime_adapter + .account_id_to_shard_id(&account_id, &head.epoch_id) + .into_chain_error()?; if self.runtime_adapter.cares_about_shard( self.validator_account_id.as_ref(), &head.last_block_hash, diff --git a/chain/epoch-manager/src/adapter.rs b/chain/epoch-manager/src/adapter.rs index 28cfbbd2152..b25cfe5f010 100644 --- a/chain/epoch-manager/src/adapter.rs +++ b/chain/epoch-manager/src/adapter.rs @@ -33,7 +33,7 @@ pub trait EpochManagerAdapter: Send + Sync { fn epoch_exists(&self, epoch_id: &EpochId) -> bool; /// Get current number of shards. - fn num_shards(&self, epoch_id: &EpochId) -> Result; + fn num_shards(&self, epoch_id: &EpochId) -> Result; /// Number of Reed-Solomon parts we split each chunk into. /// @@ -48,44 +48,51 @@ pub trait EpochManagerAdapter: Send + Sync { fn num_data_parts(&self) -> usize; /// Returns `account_id` that is supposed to have the `part_id`. - fn get_part_owner(&self, epoch_id: &EpochId, part_id: u64) -> Result; + fn get_part_owner(&self, epoch_id: &EpochId, part_id: u64) -> Result; /// Which shard the account belongs to in the given epoch. fn account_id_to_shard_id( &self, account_id: &AccountId, epoch_id: &EpochId, - ) -> Result; + ) -> Result; /// Converts `ShardId` (index of shard in the *current* layout) to /// `ShardUId` (`ShardId` + the version of shard layout itself.) - fn shard_id_to_uid(&self, shard_id: ShardId, epoch_id: &EpochId) -> Result; + fn shard_id_to_uid( + &self, + shard_id: ShardId, + epoch_id: &EpochId, + ) -> Result; - fn get_block_info(&self, hash: &CryptoHash) -> Result, Error>; + fn get_block_info(&self, hash: &CryptoHash) -> Result, EpochError>; - fn get_epoch_config(&self, epoch_id: &EpochId) -> Result; + fn get_epoch_config(&self, epoch_id: &EpochId) -> Result; - fn get_epoch_info(&self, epoch_id: &EpochId) -> Result, Error>; + fn get_epoch_info(&self, epoch_id: &EpochId) -> Result, EpochError>; - fn get_shard_layout(&self, epoch_id: &EpochId) -> Result; + fn get_shard_layout(&self, epoch_id: &EpochId) -> Result; - fn get_shard_config(&self, epoch_id: &EpochId) -> Result; + fn get_shard_config(&self, epoch_id: &EpochId) -> Result; /// Returns true, if given hash is last block in it's epoch. - fn is_next_block_epoch_start(&self, parent_hash: &CryptoHash) -> Result; + fn is_next_block_epoch_start(&self, parent_hash: &CryptoHash) -> Result; /// Get epoch id given hash of previous block. - fn get_epoch_id_from_prev_block(&self, parent_hash: &CryptoHash) -> Result; + fn get_epoch_id_from_prev_block(&self, parent_hash: &CryptoHash) + -> Result; /// Get epoch height given hash of previous block. fn get_epoch_height_from_prev_block( &self, parent_hash: &CryptoHash, - ) -> Result; + ) -> Result; /// Get next epoch id given hash of previous block. - fn get_next_epoch_id_from_prev_block(&self, parent_hash: &CryptoHash) - -> Result; + fn get_next_epoch_id_from_prev_block( + &self, + parent_hash: &CryptoHash, + ) -> Result; /// For each `ShardId` in the current block, returns its parent `ShardId` /// from previous block. @@ -102,10 +109,10 @@ pub trait EpochManagerAdapter: Send + Sync { fn get_shard_layout_from_prev_block( &self, parent_hash: &CryptoHash, - ) -> Result; + ) -> Result; /// Get [`EpochId`] from a block belonging to the epoch. - fn get_epoch_id(&self, block_hash: &CryptoHash) -> Result; + fn get_epoch_id(&self, block_hash: &CryptoHash) -> Result; /// Which of the two epochs is earlier. /// @@ -115,16 +122,16 @@ pub trait EpochManagerAdapter: Send + Sync { &self, epoch_id: &EpochId, other_epoch_id: &EpochId, - ) -> Result; + ) -> Result; /// Get epoch start from a block belonging to the epoch. - fn get_epoch_start_height(&self, block_hash: &CryptoHash) -> Result; + fn get_epoch_start_height(&self, block_hash: &CryptoHash) -> Result; /// Get previous epoch id by hash of previous block. fn get_prev_epoch_id_from_prev_block( &self, prev_block_hash: &CryptoHash, - ) -> Result; + ) -> Result; /// _If_ the next epoch will use a new protocol version, returns an /// estimated block height for when the epoch switch occurs. @@ -136,49 +143,52 @@ pub trait EpochManagerAdapter: Send + Sync { ) -> Result, EpochError>; /// Epoch block producers ordered by their order in the proposals. - /// Returns error if height is outside of known boundaries. + /// Returns EpochError if height is outside of known boundaries. fn get_epoch_block_producers_ordered( &self, epoch_id: &EpochId, last_known_block_hash: &CryptoHash, - ) -> Result, Error>; + ) -> Result, EpochError>; fn get_epoch_block_approvers_ordered( &self, parent_hash: &CryptoHash, - ) -> Result, Error>; + ) -> Result, EpochError>; /// Returns all the chunk producers for a given epoch. - fn get_epoch_chunk_producers(&self, epoch_id: &EpochId) -> Result, Error>; + fn get_epoch_chunk_producers( + &self, + epoch_id: &EpochId, + ) -> Result, EpochError>; - /// Block producers for given height for the main block. Return error if outside of known boundaries. + /// Block producers for given height for the main block. Return EpochError if outside of known boundaries. fn get_block_producer( &self, epoch_id: &EpochId, height: BlockHeight, - ) -> Result; + ) -> Result; - /// Chunk producer for given height for given shard. Return error if outside of known boundaries. + /// Chunk producer for given height for given shard. Return EpochError if outside of known boundaries. fn get_chunk_producer( &self, epoch_id: &EpochId, height: BlockHeight, shard_id: ShardId, - ) -> Result; + ) -> Result; fn get_validator_by_account_id( &self, epoch_id: &EpochId, last_known_block_hash: &CryptoHash, account_id: &AccountId, - ) -> Result<(ValidatorStake, bool), Error>; + ) -> Result<(ValidatorStake, bool), EpochError>; fn get_fisherman_by_account_id( &self, epoch_id: &EpochId, last_known_block_hash: &CryptoHash, account_id: &AccountId, - ) -> Result<(ValidatorStake, bool), Error>; + ) -> Result<(ValidatorStake, bool), EpochError>; /// WARNING: this call may be expensive. /// @@ -187,13 +197,14 @@ pub trait EpochManagerAdapter: Send + Sync { fn get_validator_info( &self, epoch_id: ValidatorInfoIdentifier, - ) -> Result; + ) -> Result; /// Amount of tokens minted in given epoch. - fn get_epoch_minted_amount(&self, epoch_id: &EpochId) -> Result; + fn get_epoch_minted_amount(&self, epoch_id: &EpochId) -> Result; /// Epoch active protocol version. - fn get_epoch_protocol_version(&self, epoch_id: &EpochId) -> Result; + fn get_epoch_protocol_version(&self, epoch_id: &EpochId) + -> Result; // TODO #3488 this likely to be updated /// Data that is necessary for prove Epochs in Epoch Sync. @@ -211,7 +222,7 @@ pub trait EpochManagerAdapter: Send + Sync { Arc, Arc, ), - Error, + EpochError, >; // TODO #3488 this likely to be updated @@ -221,7 +232,7 @@ pub trait EpochManagerAdapter: Send + Sync { prev_epoch_last_block_hash: &CryptoHash, epoch_id: &EpochId, next_epoch_id: &EpochId, - ) -> Result { + ) -> Result { let ( prev_epoch_first_block_info, prev_epoch_prev_last_block_info, @@ -252,7 +263,7 @@ pub trait EpochManagerAdapter: Send + Sync { epoch_info: EpochInfo, next_epoch_id: &EpochId, next_epoch_info: EpochInfo, - ) -> Result<(), Error>; + ) -> Result<(), EpochError>; fn verify_block_vrf( &self, @@ -290,7 +301,7 @@ pub trait EpochManagerAdapter: Send + Sync { /// Verify chunk header signature. /// return false if the header signature does not match the key for the assigned chunk producer /// for this chunk, or if the chunk producer has been slashed - /// return `Error::NotAValidator` if cannot find chunk producer info for this chunk + /// return `EpochError::NotAValidator` if cannot find chunk producer info for this chunk /// `header`: chunk header /// `epoch_id`: epoch_id that the chunk header belongs to /// `last_known_hash`: used to determine the list of chunk producers that are slashed @@ -371,9 +382,9 @@ impl EpochManagerAdapter for T { epoch_manager.get_epoch_info(epoch_id).is_ok() } - fn num_shards(&self, epoch_id: &EpochId) -> Result { + fn num_shards(&self, epoch_id: &EpochId) -> Result { let epoch_manager = self.read(); - Ok(epoch_manager.get_shard_layout(epoch_id).map_err(Error::from)?.num_shards()) + Ok(epoch_manager.get_shard_layout(epoch_id).map_err(EpochError::from)?.num_shards()) } fn num_total_parts(&self) -> usize { @@ -394,7 +405,7 @@ impl EpochManagerAdapter for T { } } - fn get_part_owner(&self, epoch_id: &EpochId, part_id: u64) -> Result { + fn get_part_owner(&self, epoch_id: &EpochId, part_id: u64) -> Result { let epoch_manager = self.read(); let epoch_info = epoch_manager.get_epoch_info(&epoch_id)?; let settlement = epoch_info.block_producers_settlement(); @@ -406,69 +417,79 @@ impl EpochManagerAdapter for T { &self, account_id: &AccountId, epoch_id: &EpochId, - ) -> Result { + ) -> Result { let epoch_manager = self.read(); - let shard_layout = epoch_manager.get_shard_layout(epoch_id).map_err(Error::from)?; + let shard_layout = epoch_manager.get_shard_layout(epoch_id).map_err(EpochError::from)?; Ok(account_id_to_shard_id(account_id, &shard_layout)) } - fn shard_id_to_uid(&self, shard_id: ShardId, epoch_id: &EpochId) -> Result { + fn shard_id_to_uid( + &self, + shard_id: ShardId, + epoch_id: &EpochId, + ) -> Result { let epoch_manager = self.read(); - let shard_layout = epoch_manager.get_shard_layout(epoch_id).map_err(Error::from)?; + let shard_layout = epoch_manager.get_shard_layout(epoch_id).map_err(EpochError::from)?; Ok(ShardUId::from_shard_id_and_layout(shard_id, &shard_layout)) } - fn get_block_info(&self, hash: &CryptoHash) -> Result, Error> { + fn get_block_info(&self, hash: &CryptoHash) -> Result, EpochError> { let epoch_manager = self.read(); - Ok(epoch_manager.get_block_info(hash).map_err(Error::from)?) + Ok(epoch_manager.get_block_info(hash).map_err(EpochError::from)?) } - fn get_epoch_config(&self, epoch_id: &EpochId) -> Result { + fn get_epoch_config(&self, epoch_id: &EpochId) -> Result { let epoch_manager = self.read(); - Ok(epoch_manager.get_epoch_config(epoch_id).map_err(Error::from)?) + Ok(epoch_manager.get_epoch_config(epoch_id).map_err(EpochError::from)?) } - fn get_epoch_info(&self, epoch_id: &EpochId) -> Result, Error> { + fn get_epoch_info(&self, epoch_id: &EpochId) -> Result, EpochError> { let epoch_manager = self.read(); - Ok(epoch_manager.get_epoch_info(epoch_id).map_err(Error::from)?) + Ok(epoch_manager.get_epoch_info(epoch_id).map_err(EpochError::from)?) } - fn get_shard_layout(&self, epoch_id: &EpochId) -> Result { + fn get_shard_layout(&self, epoch_id: &EpochId) -> Result { let epoch_manager = self.read(); - Ok(epoch_manager.get_shard_layout(epoch_id).map_err(Error::from)?) + epoch_manager.get_shard_layout(epoch_id) } - fn get_shard_config(&self, epoch_id: &EpochId) -> Result { + fn get_shard_config(&self, epoch_id: &EpochId) -> Result { let epoch_manager = self.read(); - let epoch_config = epoch_manager.get_epoch_config(epoch_id).map_err(Error::from)?; + let epoch_config = epoch_manager.get_epoch_config(epoch_id).map_err(EpochError::from)?; Ok(ShardConfig::new(epoch_config)) } - fn is_next_block_epoch_start(&self, parent_hash: &CryptoHash) -> Result { + fn is_next_block_epoch_start(&self, parent_hash: &CryptoHash) -> Result { let epoch_manager = self.read(); - epoch_manager.is_next_block_epoch_start(parent_hash).map_err(Error::from) + epoch_manager.is_next_block_epoch_start(parent_hash).map_err(EpochError::from) } - fn get_epoch_id_from_prev_block(&self, parent_hash: &CryptoHash) -> Result { + fn get_epoch_id_from_prev_block( + &self, + parent_hash: &CryptoHash, + ) -> Result { let epoch_manager = self.read(); - epoch_manager.get_epoch_id_from_prev_block(parent_hash).map_err(Error::from) + epoch_manager.get_epoch_id_from_prev_block(parent_hash) } fn get_epoch_height_from_prev_block( &self, prev_block_hash: &CryptoHash, - ) -> Result { + ) -> Result { let epoch_manager = self.read(); let epoch_id = epoch_manager.get_epoch_id_from_prev_block(prev_block_hash)?; - epoch_manager.get_epoch_info(&epoch_id).map(|info| info.epoch_height()).map_err(Error::from) + epoch_manager + .get_epoch_info(&epoch_id) + .map(|info| info.epoch_height()) + .map_err(EpochError::from) } fn get_next_epoch_id_from_prev_block( &self, parent_hash: &CryptoHash, - ) -> Result { + ) -> Result { let epoch_manager = self.read(); - epoch_manager.get_next_epoch_id_from_prev_block(parent_hash).map_err(Error::from) + epoch_manager.get_next_epoch_id_from_prev_block(parent_hash).map_err(EpochError::from) } fn get_prev_shard_ids( @@ -501,39 +522,39 @@ impl EpochManagerAdapter for T { fn get_shard_layout_from_prev_block( &self, parent_hash: &CryptoHash, - ) -> Result { + ) -> Result { let epoch_id = self.get_epoch_id_from_prev_block(parent_hash)?; self.get_shard_layout(&epoch_id) } - fn get_epoch_id(&self, block_hash: &CryptoHash) -> Result { + fn get_epoch_id(&self, block_hash: &CryptoHash) -> Result { let epoch_manager = self.read(); - epoch_manager.get_epoch_id(block_hash).map_err(Error::from) + epoch_manager.get_epoch_id(block_hash).map_err(EpochError::from) } fn compare_epoch_id( &self, epoch_id: &EpochId, other_epoch_id: &EpochId, - ) -> Result { + ) -> Result { let epoch_manager = self.read(); epoch_manager.compare_epoch_id(epoch_id, other_epoch_id).map_err(|e| e.into()) } - fn get_epoch_start_height(&self, block_hash: &CryptoHash) -> Result { + fn get_epoch_start_height(&self, block_hash: &CryptoHash) -> Result { let epoch_manager = self.read(); - epoch_manager.get_epoch_start_height(block_hash).map_err(Error::from) + epoch_manager.get_epoch_start_height(block_hash).map_err(EpochError::from) } fn get_prev_epoch_id_from_prev_block( &self, prev_block_hash: &CryptoHash, - ) -> Result { + ) -> Result { let epoch_manager = self.read(); if epoch_manager.is_next_block_epoch_start(prev_block_hash)? { - epoch_manager.get_epoch_id(prev_block_hash).map_err(Error::from) + epoch_manager.get_epoch_id(prev_block_hash).map_err(EpochError::from) } else { - epoch_manager.get_prev_epoch_id(prev_block_hash).map_err(Error::from) + epoch_manager.get_prev_epoch_id(prev_block_hash).map_err(EpochError::from) } } @@ -549,7 +570,7 @@ impl EpochManagerAdapter for T { &self, epoch_id: &EpochId, last_known_block_hash: &CryptoHash, - ) -> Result, Error> { + ) -> Result, EpochError> { let epoch_manager = self.read(); Ok(epoch_manager.get_all_block_producers_ordered(epoch_id, last_known_block_hash)?.to_vec()) } @@ -557,12 +578,15 @@ impl EpochManagerAdapter for T { fn get_epoch_block_approvers_ordered( &self, parent_hash: &CryptoHash, - ) -> Result, Error> { + ) -> Result, EpochError> { let epoch_manager = self.read(); - epoch_manager.get_all_block_approvers_ordered(parent_hash).map_err(Error::from) + epoch_manager.get_all_block_approvers_ordered(parent_hash) } - fn get_epoch_chunk_producers(&self, epoch_id: &EpochId) -> Result, Error> { + fn get_epoch_chunk_producers( + &self, + epoch_id: &EpochId, + ) -> Result, EpochError> { let epoch_manager = self.read(); Ok(epoch_manager.get_all_chunk_producers(epoch_id)?.to_vec()) } @@ -571,7 +595,7 @@ impl EpochManagerAdapter for T { &self, epoch_id: &EpochId, height: BlockHeight, - ) -> Result { + ) -> Result { let epoch_manager = self.read(); Ok(epoch_manager.get_block_producer_info(epoch_id, height)?.take_account_id()) } @@ -581,7 +605,7 @@ impl EpochManagerAdapter for T { epoch_id: &EpochId, height: BlockHeight, shard_id: ShardId, - ) -> Result { + ) -> Result { let epoch_manager = self.read(); Ok(epoch_manager.get_chunk_producer_info(epoch_id, height, shard_id)?.take_account_id()) } @@ -591,7 +615,7 @@ impl EpochManagerAdapter for T { epoch_id: &EpochId, last_known_block_hash: &CryptoHash, account_id: &AccountId, - ) -> Result<(ValidatorStake, bool), Error> { + ) -> Result<(ValidatorStake, bool), EpochError> { let epoch_manager = self.read(); let validator = epoch_manager.get_validator_by_account_id(epoch_id, account_id)?; let block_info = epoch_manager.get_block_info(last_known_block_hash)?; @@ -603,7 +627,7 @@ impl EpochManagerAdapter for T { epoch_id: &EpochId, last_known_block_hash: &CryptoHash, account_id: &AccountId, - ) -> Result<(ValidatorStake, bool), Error> { + ) -> Result<(ValidatorStake, bool), EpochError> { let epoch_manager = self.read(); let fisherman = epoch_manager.get_fisherman_by_account_id(epoch_id, account_id)?; let block_info = epoch_manager.get_block_info(last_known_block_hash)?; @@ -615,17 +639,20 @@ impl EpochManagerAdapter for T { fn get_validator_info( &self, epoch_id: ValidatorInfoIdentifier, - ) -> Result { + ) -> Result { let epoch_manager = self.read(); epoch_manager.get_validator_info(epoch_id).map_err(|e| e.into()) } - fn get_epoch_minted_amount(&self, epoch_id: &EpochId) -> Result { + fn get_epoch_minted_amount(&self, epoch_id: &EpochId) -> Result { let epoch_manager = self.read(); Ok(epoch_manager.get_epoch_info(epoch_id)?.minted_amount()) } - fn get_epoch_protocol_version(&self, epoch_id: &EpochId) -> Result { + fn get_epoch_protocol_version( + &self, + epoch_id: &EpochId, + ) -> Result { let epoch_manager = self.read(); Ok(epoch_manager.get_epoch_info(epoch_id)?.protocol_version()) } @@ -645,7 +672,7 @@ impl EpochManagerAdapter for T { Arc, Arc, ), - Error, + EpochError, > { let epoch_manager = self.read(); let last_block_info = epoch_manager.get_block_info(prev_epoch_last_block_hash)?; @@ -671,7 +698,7 @@ impl EpochManagerAdapter for T { epoch_info: EpochInfo, next_epoch_id: &EpochId, next_epoch_info: EpochInfo, - ) -> Result<(), Error> { + ) -> Result<(), EpochError> { let mut epoch_manager = self.write(); epoch_manager .init_after_epoch_sync( @@ -796,7 +823,9 @@ impl EpochManagerAdapter for T { ) -> Result { let info = { let epoch_manager = self.read(); - epoch_manager.get_all_block_approvers_ordered(prev_block_hash).map_err(Error::from)? + epoch_manager + .get_all_block_approvers_ordered(prev_block_hash) + .map_err(EpochError::from)? }; if approvals.len() > info.len() { return Ok(false); @@ -836,7 +865,9 @@ impl EpochManagerAdapter for T { ) -> Result<(), Error> { let info = { let epoch_manager = self.read(); - epoch_manager.get_heuristic_block_approvers_ordered(epoch_id).map_err(Error::from)? + epoch_manager + .get_heuristic_block_approvers_ordered(epoch_id) + .map_err(EpochError::from)? }; let message_to_sign = Approval::get_data_for_sig( diff --git a/tools/mirror/src/offline.rs b/tools/mirror/src/offline.rs index 0b6c93d6535..d8b2418bb75 100644 --- a/tools/mirror/src/offline.rs +++ b/tools/mirror/src/offline.rs @@ -4,6 +4,7 @@ use async_trait::async_trait; use near_chain::types::RuntimeAdapter; use near_chain::{ChainStore, ChainStoreAccess}; use near_chain_configs::GenesisValidationMode; +use near_chain_primitives::error::EpochErrorResultToChainError; use near_crypto::PublicKey; use near_epoch_manager::EpochManagerAdapter; use near_primitives::block::BlockHeader; @@ -191,8 +192,12 @@ impl crate::ChainAccess for ChainAccess { ) -> Result, ChainError> { let mut ret = Vec::new(); let header = self.chain.get_block_header(block_hash)?; - let shard_id = self.runtime.account_id_to_shard_id(account_id, header.epoch_id())?; - let shard_uid = self.runtime.shard_id_to_uid(shard_id, header.epoch_id())?; + let shard_id = self + .runtime + .account_id_to_shard_id(account_id, header.epoch_id()) + .into_chain_error()?; + let shard_uid = + self.runtime.shard_id_to_uid(shard_id, header.epoch_id()).into_chain_error()?; let chunk_extra = self.chain.get_chunk_extra(header.hash(), &shard_uid)?; match self .runtime