diff --git a/chain/chain/src/chain.rs b/chain/chain/src/chain.rs index c8a5154e783..ea128a6ec63 100644 --- a/chain/chain/src/chain.rs +++ b/chain/chain/src/chain.rs @@ -13,7 +13,9 @@ use crate::orphan::{Orphan, OrphanBlockPool}; use crate::rayon_spawner::RayonAsyncComputationSpawner; use crate::resharding::manager::ReshardingManager; use crate::resharding::types::ReshardingSender; -use crate::sharding::{get_receipts_shuffle_salt, shuffle_receipt_proofs}; +use crate::sharding::{ + chunk_part_owner, get_receipts_shuffle_salt, num_total_chunk_parts, shuffle_receipt_proofs, +}; use crate::signature_verification::{ verify_block_header_signature_with_epoch_manager, verify_block_vrf, verify_chunk_header_signature_with_epoch_manager, @@ -1408,8 +1410,11 @@ impl Chain { return Ok(true); } } - for part_id in 0..self.epoch_manager.num_total_parts() { - if &Some(self.epoch_manager.get_part_owner(&epoch_id, part_id as u64)?) == me { + let total_parts = num_total_chunk_parts(self.epoch_manager.as_ref()); + for part_id in 0..total_parts { + if &Some(chunk_part_owner(self.epoch_manager.as_ref(), &epoch_id, part_id as u64)?) + == me + { return Ok(true); } } diff --git a/chain/chain/src/sharding.rs b/chain/chain/src/sharding.rs index 447b6cbbd20..d19db39694f 100644 --- a/chain/chain/src/sharding.rs +++ b/chain/chain/src/sharding.rs @@ -2,11 +2,50 @@ use near_epoch_manager::EpochManagerAdapter; use near_primitives::block::Block; use near_primitives::errors::EpochError; use near_primitives::hash::CryptoHash; +use near_primitives::types::{AccountId, EpochId}; use near_primitives::version::ProtocolFeature; use rand::seq::SliceRandom; use rand::SeedableRng; use rand_chacha::ChaCha20Rng; +/// Number of Reed-Solomon parts we split each chunk into. +/// +/// Note: this shouldn't be too large, our Reed-Solomon supports at most 256 +/// parts. +pub fn num_total_chunk_parts(epoch_manager: &dyn EpochManagerAdapter) -> usize { + let seats = epoch_manager.genesis_num_block_producer_seats(); + if seats > 1 { + seats as usize + } else { + 2 + } +} + +/// How many Reed-Solomon parts are data parts. +/// +/// That is, fetching this many parts should be enough to reconstruct a +/// chunk, if there are no errors. +pub fn num_chunk_data_parts(epoch_manager: &dyn EpochManagerAdapter) -> usize { + let total_parts = num_total_chunk_parts(epoch_manager); + if total_parts <= 3 { + 1 + } else { + (total_parts - 1) / 3 + } +} + +/// Returns `account_id` that is supposed to have the `part_id`. +pub fn chunk_part_owner( + epoch_manager: &dyn EpochManagerAdapter, + epoch_id: &EpochId, + part_id: u64, +) -> Result { + let epoch_info = epoch_manager.get_epoch_info(&epoch_id)?; + let settlement = epoch_info.block_producers_settlement(); + let validator_id = settlement[part_id as usize % settlement.len()]; + Ok(epoch_info.get_validator(validator_id).account_id().clone()) +} + /// Gets salt for shuffling receipts grouped by **source shards** before /// processing them in the target shard. pub fn get_receipts_shuffle_salt<'a>( diff --git a/chain/chain/src/test_utils/kv_runtime.rs b/chain/chain/src/test_utils/kv_runtime.rs index 47e10c8f9c9..9271ee704f5 100644 --- a/chain/chain/src/test_utils/kv_runtime.rs +++ b/chain/chain/src/test_utils/kv_runtime.rs @@ -431,27 +431,8 @@ impl EpochManagerAdapter for MockEpochManager { Ok(self.get_shard_layout(epoch_id)?.shard_ids().collect()) } - fn num_total_parts(&self) -> usize { - 12 + (self.num_shards as usize + 1) % 50 - } - - fn num_data_parts(&self) -> usize { - // Same as in Nightshade Runtime - let total_parts = self.num_total_parts(); - if total_parts <= 3 { - 1 - } else { - (total_parts - 1) / 3 - } - } - - 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 - // would not depend on height, and tests wouldn't catch passing wrong height here - let idx = part_id as usize + self.num_data_parts() + self.num_total_parts(); - Ok(validators[idx as usize % validators.len()].0.account_id().clone()) + fn genesis_num_block_producer_seats(&self) -> u64 { + 12 + (self.num_shards + 1) % 50 } fn account_id_to_shard_id( diff --git a/chain/chain/src/validate.rs b/chain/chain/src/validate.rs index a499c690f6b..5fd37c277c1 100644 --- a/chain/chain/src/validate.rs +++ b/chain/chain/src/validate.rs @@ -18,6 +18,7 @@ use near_primitives::transaction::SignedTransaction; use near_primitives::types::chunk_extra::ChunkExtra; use near_primitives::types::{AccountId, BlockHeight, EpochId, Nonce}; +use crate::sharding::num_chunk_data_parts; use crate::signature_verification::{ verify_block_header_signature_with_epoch_manager, verify_chunk_header_signature_with_epoch_manager, @@ -343,7 +344,8 @@ fn validate_chunk_proofs_challenge( let tmp_chunk; let chunk_ref = match &*chunk_proofs.chunk { MaybeEncodedShardChunk::Encoded(encoded_chunk) => { - match encoded_chunk.decode_chunk(epoch_manager.num_data_parts()) { + let data_parts = num_chunk_data_parts(epoch_manager); + match encoded_chunk.decode_chunk(data_parts) { Ok(chunk) => { tmp_chunk = Some(chunk); tmp_chunk.as_ref().unwrap() diff --git a/chain/chunks/src/logic.rs b/chain/chunks/src/logic.rs index 2687e15fe89..6082fcb24cb 100644 --- a/chain/chunks/src/logic.rs +++ b/chain/chunks/src/logic.rs @@ -1,3 +1,4 @@ +use near_chain::sharding::{chunk_part_owner, num_chunk_data_parts}; use near_chain::ChainStoreAccess; use near_chain::{ types::EpochManagerAdapter, validate::validate_chunk_proofs, BlockHeader, Chain, ChainStore, @@ -34,7 +35,7 @@ pub fn need_part( epoch_manager: &dyn EpochManagerAdapter, ) -> Result { let epoch_id = epoch_manager.get_epoch_id_from_prev_block(prev_block_hash)?; - Ok(Some(&epoch_manager.get_part_owner(&epoch_id, part_ord)?) == me) + Ok(Some(&chunk_part_owner(epoch_manager, &epoch_id, part_ord)?) == me) } pub fn get_shards_cares_about_this_or_next_epoch( @@ -166,8 +167,9 @@ pub fn decode_encoded_chunk( ?chunk_hash) .entered(); + let data_parts = num_chunk_data_parts(epoch_manager); if let Ok(shard_chunk) = encoded_chunk - .decode_chunk(epoch_manager.num_data_parts()) + .decode_chunk(data_parts) .map_err(|err| Error::from(err)) .and_then(|shard_chunk| { if !validate_chunk_proofs(&shard_chunk, epoch_manager)? { diff --git a/chain/chunks/src/shards_manager_actor.rs b/chain/chunks/src/shards_manager_actor.rs index 8356f8a83d1..dfc29618699 100644 --- a/chain/chunks/src/shards_manager_actor.rs +++ b/chain/chunks/src/shards_manager_actor.rs @@ -95,6 +95,7 @@ use near_async::time::Duration; use near_async::time::{self, Clock}; use near_chain::byzantine_assert; use near_chain::near_chain_primitives::error::Error::DBNotFoundErr; +use near_chain::sharding::{chunk_part_owner, num_chunk_data_parts, num_total_chunk_parts}; use near_chain::signature_verification::{ verify_chunk_header_signature_with_epoch_manager, verify_chunk_header_signature_with_epoch_manager_and_parts, @@ -359,6 +360,7 @@ impl ShardsManagerActor { initial_chain_header_head: Tip, chunk_request_retry_period: Duration, ) -> Self { + let data_parts = num_chunk_data_parts(epoch_manager.as_ref()); Self { clock, validator_signer, @@ -369,8 +371,8 @@ impl ShardsManagerActor { peer_manager_adapter: network_adapter, client_adapter, rs: ReedSolomon::new( - epoch_manager.num_data_parts(), - epoch_manager.num_total_parts() - epoch_manager.num_data_parts(), + data_parts, + num_total_chunk_parts(epoch_manager.as_ref()) - data_parts, ) .unwrap(), encoded_chunks: EncodedChunksCache::new(), @@ -480,7 +482,8 @@ impl ShardsManagerActor { let epoch_id = self.epoch_manager.get_epoch_id_from_prev_block(ancestor_hash)?; - for part_ord in 0..self.epoch_manager.num_total_parts() { + let total_parts = num_total_chunk_parts(self.epoch_manager.as_ref()); + for part_ord in 0..total_parts { let part_ord = part_ord as u64; if cache_entry.is_some_and(|cache_entry| cache_entry.parts.contains_key(&part_ord)) { continue; @@ -489,7 +492,7 @@ impl ShardsManagerActor { // Note: If request_from_archival is true, we potentially call // get_part_owner unnecessarily. It’s probably not worth optimizing // though unless you can think of a concise way to do it. - let part_owner = self.epoch_manager.get_part_owner(&epoch_id, part_ord)?; + let part_owner = chunk_part_owner(self.epoch_manager.as_ref(), &epoch_id, part_ord)?; let we_own_part = Some(&part_owner) == me; if !request_full && !we_own_part { continue; @@ -1126,7 +1129,7 @@ impl ShardsManagerActor { chunk_hash = ?chunk.chunk_hash()) .entered(); - let data_parts = self.epoch_manager.num_data_parts(); + let data_parts = num_chunk_data_parts(self.epoch_manager.as_ref()); if chunk.content().num_fetched_parts() < data_parts { debug!(target: "chunks", num_fetched_parts = chunk.content().num_fetched_parts(), data_parts, "Incomplete"); return ChunkStatus::Incomplete; @@ -1212,7 +1215,7 @@ impl ShardsManagerActor { } // check part merkle proofs - let num_total_parts = self.epoch_manager.num_total_parts(); + let num_total_parts = num_total_chunk_parts(self.epoch_manager.as_ref()); for part_info in forward.parts.iter() { self.validate_part(forward.merkle_root, part_info, num_total_parts)?; } @@ -1260,7 +1263,7 @@ impl ShardsManagerActor { fn insert_forwarded_chunk(&mut self, forward: PartialEncodedChunkForwardMsg) { let chunk_hash = forward.chunk_hash.clone(); - let num_total_parts = self.epoch_manager.num_total_parts() as u64; + let num_total_parts = num_total_chunk_parts(self.epoch_manager.as_ref()) as u64; match self.chunk_forwards_cache.get_mut(&chunk_hash) { None => { // Never seen this chunk hash before, collect the parts and cache them @@ -1505,9 +1508,9 @@ impl ShardsManagerActor { if entry.complete { return Ok(ProcessPartialEncodedChunkResult::Known); } - debug!(target: "chunks", num_parts_in_cache = entry.parts.len(), total_needed = self.epoch_manager.num_data_parts()); + debug!(target: "chunks", num_parts_in_cache = entry.parts.len(), total_needed = num_chunk_data_parts(self.epoch_manager.as_ref())); } else { - debug!(target: "chunks", num_parts_in_cache = 0, total_needed = self.epoch_manager.num_data_parts()); + debug!(target: "chunks", num_parts_in_cache = 0, total_needed = num_chunk_data_parts(self.epoch_manager.as_ref())); } // 1.b Checking chunk height @@ -1548,7 +1551,7 @@ impl ShardsManagerActor { let partial_encoded_chunk = partial_encoded_chunk.as_ref().into_inner(); // 1.d Checking part_ords' validity - let num_total_parts = self.epoch_manager.num_total_parts(); + let num_total_parts = num_total_chunk_parts(self.epoch_manager.as_ref()); for part_info in partial_encoded_chunk.parts.iter() { // TODO: only validate parts we care about // https://github.com/near/nearcore/issues/5885 @@ -1714,7 +1717,8 @@ impl ShardsManagerActor { let have_all_parts = self.has_all_parts(&prev_block_hash, entry, me)?; let have_all_receipts = self.has_all_receipts(&prev_block_hash, entry, me)?; - let can_reconstruct = entry.parts.len() >= self.epoch_manager.num_data_parts(); + let can_reconstruct = + entry.parts.len() >= num_chunk_data_parts(self.epoch_manager.as_ref()); let chunk_producer = self .epoch_manager .get_chunk_producer_info(&ChunkProductionKey { @@ -1765,7 +1769,7 @@ impl ShardsManagerActor { let protocol_version = self.epoch_manager.get_epoch_protocol_version(&epoch_id)?; let mut encoded_chunk = EncodedShardChunk::from_header( header.clone(), - self.epoch_manager.num_total_parts(), + num_total_chunk_parts(self.epoch_manager.as_ref()), protocol_version, ); @@ -1854,9 +1858,7 @@ impl ShardsManagerActor { .iter() .filter(|part| { part_ords.contains(&part.part_ord) - && self - .epoch_manager - .get_part_owner(epoch_id, part.part_ord) + && chunk_part_owner(self.epoch_manager.as_ref(), epoch_id, part.part_ord) .is_ok_and(|owner| &owner == me) }) .cloned() @@ -1994,7 +1996,8 @@ impl ShardsManagerActor { chunk_entry: &EncodedChunksCacheEntry, me: Option<&AccountId>, ) -> Result { - for part_ord in 0..self.epoch_manager.num_total_parts() { + let total_parts = num_total_chunk_parts(self.epoch_manager.as_ref()); + for part_ord in 0..total_parts { let part_ord = part_ord as u64; if !chunk_entry.parts.contains_key(&part_ord) { if need_part(prev_block_hash, part_ord, me, self.epoch_manager.as_ref())? { @@ -2072,9 +2075,11 @@ impl ShardsManagerActor { let mut block_producer_mapping = HashMap::new(); let epoch_id = self.epoch_manager.get_epoch_id_from_prev_block(&prev_block_hash)?; - for part_ord in 0..self.epoch_manager.num_total_parts() { + let total_parts = num_total_chunk_parts(self.epoch_manager.as_ref()); + for part_ord in 0..total_parts { let part_ord = part_ord as u64; - let to_whom = self.epoch_manager.get_part_owner(&epoch_id, part_ord).unwrap(); + let to_whom = + chunk_part_owner(self.epoch_manager.as_ref(), &epoch_id, part_ord).unwrap(); let entry = block_producer_mapping.entry(to_whom).or_insert_with(Vec::new); entry.push(part_ord); @@ -2518,7 +2523,8 @@ mod test { }) .count() }; - let non_owned_part_ords: Vec = (0..(fixture.epoch_manager.num_total_parts() as u64)) + let non_owned_part_ords: Vec = (0..(num_total_chunk_parts(&fixture.epoch_manager) + as u64)) .filter(|ord| !fixture.mock_part_ords.contains(ord)) .collect(); // Received 3 partial encoded chunks; the owned part is received 3 times, but should @@ -2934,7 +2940,7 @@ mod test { let mut update = fixture.chain_store.store_update(); let shard_chunk = fixture .mock_encoded_chunk - .decode_chunk(fixture.epoch_manager.num_data_parts()) + .decode_chunk(num_chunk_data_parts(&fixture.epoch_manager)) .unwrap(); update.save_chunk(shard_chunk); update.commit().unwrap(); @@ -3026,7 +3032,7 @@ mod test { let mut update = fixture.chain_store.store_update(); let shard_chunk = fixture .mock_encoded_chunk - .decode_chunk(fixture.epoch_manager.num_data_parts()) + .decode_chunk(num_chunk_data_parts(&fixture.epoch_manager)) .unwrap(); update.save_chunk(shard_chunk); update.commit().unwrap(); @@ -3158,7 +3164,7 @@ mod test { let mut update = fixture.chain_store.store_update(); let shard_chunk = fixture .mock_encoded_chunk - .decode_chunk(fixture.epoch_manager.num_data_parts()) + .decode_chunk(num_chunk_data_parts(&fixture.epoch_manager)) .unwrap(); update.save_chunk(shard_chunk); update.commit().unwrap(); @@ -3166,7 +3172,7 @@ mod test { let (source, response) = shards_manager.prepare_partial_encoded_chunk_response(PartialEncodedChunkRequestMsg { chunk_hash: fixture.mock_chunk_header.chunk_hash(), - part_ords: vec![0, fixture.epoch_manager.num_total_parts() as u64], + part_ords: vec![0, num_total_chunk_parts(&fixture.epoch_manager) as u64], tracking_shards: HashSet::new(), }); assert_eq!(source, PartialEncodedChunkResponseSource::ShardChunkOnDisk); @@ -3194,7 +3200,7 @@ mod test { let mut update = fixture.chain_store.store_update(); let shard_chunk = fixture .mock_encoded_chunk - .decode_chunk(fixture.epoch_manager.num_data_parts()) + .decode_chunk(num_chunk_data_parts(&fixture.epoch_manager)) .unwrap(); update.save_chunk(shard_chunk); update.commit().unwrap(); diff --git a/chain/chunks/src/test_utils.rs b/chain/chunks/src/test_utils.rs index db8d77e143f..f48be6eb096 100644 --- a/chain/chunks/src/test_utils.rs +++ b/chain/chunks/src/test_utils.rs @@ -1,4 +1,5 @@ use near_async::messaging::CanSend; +use near_chain::sharding::{chunk_part_owner, num_chunk_data_parts, num_total_chunk_parts}; use near_chain::types::{EpochManagerAdapter, Tip}; use near_chain::{Chain, ChainStore}; use near_epoch_manager::shard_tracker::{ShardTracker, TrackedConfig}; @@ -87,8 +88,8 @@ impl ChunkTestFixture { let mock_network = Arc::new(MockPeerManagerAdapter::default()); let mock_client_adapter = Arc::new(MockClientAdapterForShardsManager::default()); - let data_parts = epoch_manager.num_data_parts(); - let parity_parts = epoch_manager.num_total_parts() - data_parts; + let data_parts = num_chunk_data_parts(&epoch_manager); + let parity_parts = num_total_chunk_parts(&epoch_manager) - data_parts; let rs = ReedSolomon::new(data_parts, parity_parts).unwrap(); let mock_ancestor_hash = CryptoHash::default(); // generate a random block hash for the block at height 1 @@ -175,7 +176,8 @@ impl ChunkTestFixture { .iter() .copied() .filter(|p| { - epoch_manager.get_part_owner(&mock_epoch_id, *p).unwrap() == mock_chunk_part_owner + chunk_part_owner(&epoch_manager, &mock_epoch_id, *p).unwrap() + == mock_chunk_part_owner }) .collect(); let encoded_chunk = mock_chunk.create_partial_encoded_chunk( diff --git a/chain/client/src/client.rs b/chain/client/src/client.rs index 2f00e485f80..e4536336791 100644 --- a/chain/client/src/client.rs +++ b/chain/client/src/client.rs @@ -22,6 +22,7 @@ use near_chain::chain::{ VerifyBlockHashAndSignatureResult, }; use near_chain::orphan::OrphanMissingChunks; +use near_chain::sharding::{num_chunk_data_parts, num_total_chunk_parts}; use near_chain::state_snapshot_actor::SnapshotCallbacks; use near_chain::test_utils::format_hash; use near_chain::types::PrepareTransactionsChunkContext; @@ -325,8 +326,8 @@ impl Client { false, ); let num_block_producer_seats = config.num_block_producer_seats as usize; - let data_parts = epoch_manager.num_data_parts(); - let parity_parts = epoch_manager.num_total_parts() - data_parts; + let data_parts = num_chunk_data_parts(epoch_manager.as_ref()); + let parity_parts = num_total_chunk_parts(epoch_manager.as_ref()) - data_parts; let doomslug = Doomslug::new( clock.clone(), diff --git a/chain/client/src/test_utils/client.rs b/chain/client/src/test_utils/client.rs index 337eb59b434..70673041ee0 100644 --- a/chain/client/src/test_utils/client.rs +++ b/chain/client/src/test_utils/client.rs @@ -11,6 +11,7 @@ use actix_rt::System; use itertools::Itertools; use near_async::messaging::Sender; use near_chain::chain::{do_apply_chunks, BlockCatchUpRequest}; +use near_chain::sharding::{num_chunk_data_parts, num_total_chunk_parts}; use near_chain::test_utils::{wait_for_all_blocks_in_processing, wait_for_block_in_processing}; use near_chain::{Chain, ChainStoreAccess, Provenance}; use near_client_primitives::types::Error; @@ -204,8 +205,8 @@ pub fn create_chunk( // reconstruct the chunk with changes (if any) if should_replace { // The best way it to decode chunk, replace transactions and then recreate encoded chunk. - let total_parts = client.chain.epoch_manager.num_total_parts(); - let data_parts = client.chain.epoch_manager.num_data_parts(); + let total_parts = num_total_chunk_parts(client.chain.epoch_manager.as_ref()); + let data_parts = num_chunk_data_parts(client.chain.epoch_manager.as_ref()); let decoded_chunk = chunk.decode_chunk(data_parts).unwrap(); let parity_parts = total_parts - data_parts; let rs = ReedSolomon::new(data_parts, parity_parts).unwrap(); diff --git a/chain/epoch-manager/src/adapter.rs b/chain/epoch-manager/src/adapter.rs index 408d261ecd3..396c215bad3 100644 --- a/chain/epoch-manager/src/adapter.rs +++ b/chain/epoch-manager/src/adapter.rs @@ -42,20 +42,7 @@ pub trait EpochManagerAdapter: Send + Sync { /// Get the list of shard ids fn shard_ids(&self, epoch_id: &EpochId) -> Result, EpochError>; - /// Number of Reed-Solomon parts we split each chunk into. - /// - /// Note: this shouldn't be too large, our Reed-Solomon supports at most 256 - /// parts. - fn num_total_parts(&self) -> usize; - - /// How many Reed-Solomon parts are data parts. - /// - /// That is, fetching this many parts should be enough to reconstruct a - /// chunk, if there are no errors. - 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 genesis_num_block_producer_seats(&self) -> u64; /// Which shard the account belongs to in the given epoch. fn account_id_to_shard_id( @@ -481,30 +468,8 @@ impl EpochManagerAdapter for EpochManagerHandle { Ok(epoch_manager.get_shard_layout(epoch_id)?.shard_ids().collect()) } - fn num_total_parts(&self) -> usize { - let seats = self.read().genesis_num_block_producer_seats; - if seats > 1 { - seats as usize - } else { - 2 - } - } - - fn num_data_parts(&self) -> usize { - let total_parts = self.num_total_parts(); - if total_parts <= 3 { - 1 - } else { - (total_parts - 1) / 3 - } - } - - 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(); - let validator_id = settlement[part_id as usize % settlement.len()]; - Ok(epoch_info.get_validator(validator_id).account_id().clone()) + fn genesis_num_block_producer_seats(&self) -> u64 { + self.read().genesis_num_block_producer_seats } fn account_id_to_shard_id( diff --git a/integration-tests/src/tests/client/challenges.rs b/integration-tests/src/tests/client/challenges.rs index 5402b49db61..15a3ac48b95 100644 --- a/integration-tests/src/tests/client/challenges.rs +++ b/integration-tests/src/tests/client/challenges.rs @@ -1,5 +1,6 @@ use assert_matches::assert_matches; use near_async::time::Clock; +use near_chain::sharding::{num_chunk_data_parts, num_total_chunk_parts}; use near_chain::validate::validate_challenge; use near_chain::{Block, ChainStoreAccess, Error, Provenance}; use near_chain_configs::Genesis; @@ -213,8 +214,9 @@ fn test_verify_chunk_invalid_proofs_challenge_decoded_chunk() { env.produce_block(0, 1); let (ProduceChunkResult { chunk: encoded_chunk, .. }, block) = create_invalid_proofs_chunk(&mut env.clients[0]); - let chunk = - encoded_chunk.decode_chunk(env.clients[0].chain.epoch_manager.num_data_parts()).unwrap(); + let chunk = encoded_chunk + .decode_chunk(num_chunk_data_parts(env.clients[0].chain.epoch_manager.as_ref())) + .unwrap(); let shard_id = chunk.shard_id(); let challenge_result = @@ -364,8 +366,8 @@ fn test_verify_chunk_invalid_state_challenge() { // Invalid chunk & block. let last_block_hash = env.clients[0].chain.head().unwrap().last_block_hash; let last_block = env.clients[0].chain.get_block(&last_block_hash).unwrap(); - let total_parts = env.clients[0].epoch_manager.num_total_parts(); - let data_parts = env.clients[0].epoch_manager.num_data_parts(); + let total_parts = num_total_chunk_parts(env.clients[0].epoch_manager.as_ref()); + let data_parts = num_chunk_data_parts(env.clients[0].epoch_manager.as_ref()); let parity_parts = total_parts - data_parts; let rs = ReedSolomon::new(data_parts, parity_parts).unwrap(); let congestion_info = ProtocolFeature::CongestionControl diff --git a/tools/mock-node/src/lib.rs b/tools/mock-node/src/lib.rs index 7a705419245..8effb90e57f 100644 --- a/tools/mock-node/src/lib.rs +++ b/tools/mock-node/src/lib.rs @@ -2,6 +2,7 @@ //! components of the mock network. use anyhow::{anyhow, Context as AnyhowContext}; +use near_chain::sharding::num_total_chunk_parts; use near_chain::{Block, Chain, ChainStoreAccess, Error}; use near_client::sync::header::MAX_BLOCK_HEADERS; use near_crypto::SecretKey; @@ -463,7 +464,7 @@ fn retrieve_partial_encoded_chunk( chain: &Chain, request: &PartialEncodedChunkRequestMsg, ) -> Result { - let num_total_parts = chain.epoch_manager.num_total_parts(); + let num_total_parts = num_total_chunk_parts(chain.epoch_manager.as_ref()); let partial_chunk = chain.chain_store().get_partial_chunk(&request.chunk_hash)?; let present_parts: HashMap = partial_chunk.parts().iter().map(|part| (part.part_ord, part)).collect();