Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restore receipts after recent fix #4248

Merged
merged 125 commits into from
May 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
125 commits
Select commit Hold shift + click to select a range
d7c8fd6
Fix storage usage bug with migration
EgorKulikov May 4, 2021
c24c930
Sanity test
EgorKulikov May 4, 2021
f61efed
Merge branch 'master' into migration-fix-storage-usage
EgorKulikov May 4, 2021
4e762c7
Compilation fix, added description to migration cause
EgorKulikov May 4, 2021
91d6ef8
Added feature to root cargo
EgorKulikov May 4, 2021
3299762
Compilation fix
EgorKulikov May 4, 2021
45a9802
Compilation fix
EgorKulikov May 4, 2021
8c42e7a
Compilation fix
EgorKulikov May 5, 2021
4f8363b
Update core/primitives/src/views.rs
EgorKulikov May 5, 2021
3a7426d
Suggestions by matklad
EgorKulikov May 5, 2021
3817c08
Suggestions by matklad
EgorKulikov May 5, 2021
d7e903f
Removing unneeded trait
EgorKulikov May 5, 2021
af8d2fe
Additional comment
EgorKulikov May 5, 2021
f32b999
Take receipts from stub file
May 5, 2021
4449613
Fix import
Apr 29, 2021
50a8da2
Add script for verifying receipts
May 5, 2021
4920661
Fix condition for re-introducing receipts
Apr 29, 2021
7a244c9
Remove condition for saving outcomes
Apr 29, 2021
db2b915
Fix port from 1.18.3 to master
Apr 29, 2021
0e5bce2
Set exact upper bound on height
May 5, 2021
033da25
Minor fixes
May 5, 2021
a66d7d9
Set test height start
Apr 29, 2021
81af983
Revert
Apr 29, 2021
ab98d81
Set feature flag
May 5, 2021
11e8363
Take restored receipts from RuntimeConfig instead of raw data
Apr 30, 2021
501632c
Update utils/restored-receipts-verifier/src/main.rs
Apr 30, 2021
68a04f9
Refactor condition
Apr 30, 2021
261de4d
Fix clap
Apr 30, 2021
1a9e945
Update utils/restored-receipts-verifier/src/main.rs
Apr 30, 2021
dda95c2
Update utils/restored-receipts-verifier/src/main.rs
Apr 30, 2021
6cc80fb
Update utils/restored-receipts-verifier/src/main.rs
Apr 30, 2021
4257dea
Update utils/restored-receipts-verifier/src/main.rs
Apr 30, 2021
c4cd340
Apply suggestion
Apr 30, 2021
f26d30f
Minor fix
Apr 30, 2021
904837d
Minor fix
Apr 30, 2021
122c12e
Compilation fix
Apr 30, 2021
5d00c98
Minor fix
Apr 30, 2021
a95e4d0
cargo fmt
Apr 30, 2021
4861cdf
Add comments
Apr 30, 2021
ee37269
Fix unused imports
Apr 30, 2021
8f9197d
Rename json file
May 1, 2021
10c6b7a
Output to stderr
May 1, 2021
5d039f3
Put receipts directly to apply_transactions
May 4, 2021
36ac694
Minor fix
May 4, 2021
f20ca3a
Add stub test
May 5, 2021
fdcff6f
Display is needed after all
EgorKulikov May 5, 2021
4a7309b
Add restored receipts to migration data
May 5, 2021
d4c0dc4
minor fix
May 5, 2021
3a2b50e
Getting read of EMPTY
EgorKulikov May 5, 2021
dc414bf
take restored receipts from migration data
May 5, 2021
cbc0211
Merge branch 'migration-fix-storage-usage' into restore-receipts
May 5, 2021
907ee3e
Merge branch 'master' into migration-fix-storage-usage
EgorKulikov May 5, 2021
771530e
Merge branch 'master' into migration-fix-storage-usage
EgorKulikov May 5, 2021
48d8065
Merge branch 'master' into migration-fix-storage-usage
EgorKulikov May 5, 2021
ea5b0d0
Addressing comments
EgorKulikov May 6, 2021
df7ea6b
Merge remote-tracking branch 'origin/migration-fix-storage-usage' int…
EgorKulikov May 6, 2021
d99d161
Integration test
EgorKulikov May 6, 2021
0de9c82
Unused imports
EgorKulikov May 6, 2021
39bcd10
Fix dependencies
EgorKulikov May 6, 2021
ae0b5e9
implement test_restoring_receipts_mainnet
May 6, 2021
5d7664d
Merge branch 'migration-fix-storage-usage' into restore-receipts
May 6, 2021
84ffc12
solve case when first block may not contain a chunk
May 6, 2021
0a4ea03
Merge branch 'master' into migration-fix-storage-usage
EgorKulikov May 7, 2021
9cc6ca7
Renamed argument for clarity
EgorKulikov May 7, 2021
1d68796
Merge remote-tracking branch 'origin/migration-fix-storage-usage' int…
EgorKulikov May 7, 2021
2b98daa
Refactoring apply_migrations
EgorKulikov May 7, 2021
acb9d13
Merge branch 'migration-fix-storage-usage' into restore-receipts
May 7, 2021
13b6471
introduce filtering by the first epoch only
May 7, 2021
e90faf7
move getting protocol version to separate method
May 7, 2021
496c9cb
fix comment
May 7, 2021
0a7d2cc
Merge branch 'master' into migration-fix-storage-usage
EgorKulikov May 7, 2021
7479882
update clap version
May 7, 2021
c3d3e16
Merge branch 'migration-fix-storage-usage' into restore-receipts
May 7, 2021
518e5f8
test restored-receipts-verifier
May 7, 2021
39d215a
cargo fmt
May 7, 2021
f3c8f91
rename
May 7, 2021
3ebed4b
Gas should not be spent for transition for non-mainnet
EgorKulikov May 10, 2021
f8aa99e
Merge remote-tracking branch 'origin/migration-fix-storage-usage' int…
EgorKulikov May 10, 2021
11b6b02
Compilation fix
EgorKulikov May 10, 2021
921d96e
Compilation fix
EgorKulikov May 10, 2021
ec1f41c
Compilation fix
EgorKulikov May 10, 2021
4c7e883
Update chain/rosetta-rpc/src/adapters/mod.rs
EgorKulikov May 10, 2021
43511a2
MigrationId no longer used
EgorKulikov May 10, 2021
571c082
MigrationId no longer used
EgorKulikov May 10, 2021
23e1319
Compilation fix
EgorKulikov May 10, 2021
f54b1f8
Compilation fix
EgorKulikov May 10, 2021
57cd4f3
remove unnecessary code
May 11, 2021
d223802
separate tests
May 11, 2021
6330623
Merge branch 'migration-fix-storage-usage' into restore-receipts
May 11, 2021
b857627
introduce is_valid_block_for_migration
May 12, 2021
edbb264
add migration argument to all apply_transaction calls
May 12, 2021
55d85f0
remove get_migration_data
May 12, 2021
0edc887
add more comments
May 12, 2021
d9877bf
temporary change
May 13, 2021
851d1f4
implement get_prev_epoch_id_from_prev_block
May 13, 2021
41d7467
Merge branch 'master' into restore-receipts
May 13, 2021
a1fef60
finish merge
May 13, 2021
32a4a3a
fix merge
May 13, 2021
1ccf96c
fix tests
May 13, 2021
0c2d79e
minor fix
May 13, 2021
2d06f3e
remove old changes
May 13, 2021
481933b
add is_valid_block arg to state-viewer
May 13, 2021
d8c1e83
fix unused variable warning
May 13, 2021
109b9a9
compilation fix
May 13, 2021
921dd04
compilation fix
May 13, 2021
a925407
minor fix
May 13, 2021
32b0116
compilation fix
May 13, 2021
82e1e18
implement getting prev epoch id for KeyValueRuntime
May 14, 2021
f7b6e15
set struct for flags needed for migration
May 17, 2021
1a98485
fix toml files
May 17, 2021
8bb156b
extend vector outside of apply_migrations
May 18, 2021
24a6209
make call of get_prev_epoch_id_from_prev_block more clear
May 18, 2021
ed93b0d
minor fix
May 18, 2021
6a595bf
minor fix
May 18, 2021
3062682
minor fix
May 18, 2021
faa5065
cargo fmt
May 18, 2021
a60a69e
address new comments
May 18, 2021
1f57640
minor fix
May 18, 2021
64841ff
remove shard_id = 0 optimization
May 18, 2021
4ff65a0
process error from get_prev_epoch_id correctly
May 18, 2021
3d530bd
minor fix
May 18, 2021
eaf5575
get rid of test method
May 19, 2021
0011ad2
minor fix
May 19, 2021
faf5519
minor fix
May 19, 2021
b9cfc74
Merge branch 'master' into restore-receipts
olonho May 24, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ members = [
"tools/restaked",
"tools/indexer/example",
"tools/delay_detector",
"tools/storage-usage-delta-calculator"
"tools/storage-usage-delta-calculator",
"tools/restored-receipts-verifier"
]

[dev-dependencies]
Expand All @@ -60,6 +61,7 @@ near-crypto = { path = "./core/crypto" }
near-primitives = { path = "./core/primitives" }
near-store = { path = "./core/store" }
runtime-params-estimator = { path = "./runtime/runtime-params-estimator", default_features = false }
restored-receipts-verifier = { path = "./tools/restored-receipts-verifier"}
near-chain = { path = "./chain/chain" }

node-runtime = { path = "./runtime/runtime" }
Expand Down Expand Up @@ -113,14 +115,15 @@ metric_recorder = ["neard/metric_recorder"]
delay_detector = ["neard/delay_detector"]
rosetta_rpc = ["neard/rosetta_rpc"]
nightly_protocol = ["near-primitives/nightly_protocol", "near-jsonrpc/nightly_protocol", "testlib/nightly_protocol", "neard/nightly_protocol"]
nightly_protocol_features = ["nightly_protocol", "neard/nightly_protocol_features", "protocol_feature_evm", "protocol_feature_block_header_v3", "protocol_feature_alt_bn128", "protocol_feature_add_account_versions", "protocol_feature_tx_size_limit", "protocol_feature_allow_create_account_on_delete", "testlib/nightly_protocol_features", "protocol_feature_fix_storage_usage"]
nightly_protocol_features = ["nightly_protocol", "neard/nightly_protocol_features", "protocol_feature_evm", "protocol_feature_block_header_v3", "protocol_feature_alt_bn128", "protocol_feature_add_account_versions", "protocol_feature_tx_size_limit", "protocol_feature_allow_create_account_on_delete", "testlib/nightly_protocol_features", "protocol_feature_fix_storage_usage", "protocol_feature_restore_receipts_after_fix"]
protocol_feature_evm = ["neard/protocol_feature_evm", "testlib/protocol_feature_evm", "runtime-params-estimator/protocol_feature_evm"]
protocol_feature_alt_bn128 = ["neard/protocol_feature_alt_bn128", "testlib/protocol_feature_alt_bn128", "runtime-params-estimator/protocol_feature_alt_bn128"]
protocol_feature_block_header_v3 = ["near-primitives/protocol_feature_block_header_v3", "near-chain/protocol_feature_block_header_v3", "neard/protocol_feature_block_header_v3"]
protocol_feature_tx_size_limit = ["near-primitives/protocol_feature_tx_size_limit", "node-runtime/protocol_feature_tx_size_limit", "neard/protocol_feature_tx_size_limit"]
protocol_feature_allow_create_account_on_delete = ["testlib/protocol_feature_allow_create_account_on_delete", "near-primitives/protocol_feature_allow_create_account_on_delete", "node-runtime/protocol_feature_allow_create_account_on_delete", "neard/protocol_feature_allow_create_account_on_delete"]
protocol_feature_add_account_versions = ["near-primitives/protocol_feature_add_account_versions"]
protocol_feature_fix_storage_usage = ["near-primitives/protocol_feature_fix_storage_usage", "neard/protocol_feature_fix_storage_usage", "node-runtime/protocol_feature_fix_storage_usage"]
protocol_feature_restore_receipts_after_fix = ["near-primitives/protocol_feature_restore_receipts_after_fix", "near-chain/protocol_feature_restore_receipts_after_fix", "neard/protocol_feature_restore_receipts_after_fix", "node-runtime/protocol_feature_restore_receipts_after_fix", "restored-receipts-verifier/protocol_feature_restore_receipts_after_fix"]

# enable this to build neard with wasmer 1.0 runner
# now if none of wasmer0_default, wasmer1_default or wasmtime_default is enabled, wasmer0 would be default
Expand Down
3 changes: 2 additions & 1 deletion chain/chain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@ delay_detector = ["delay-detector"]
no_cache = ["near-store/no_cache"]
protocol_feature_evm = ["near-primitives/protocol_feature_evm", "near-chain-configs/protocol_feature_evm"]
protocol_feature_block_header_v3 = []
nightly_protocol_features = ["nightly_protocol", "protocol_feature_block_header_v3"]
protocol_feature_restore_receipts_after_fix = []
nightly_protocol_features = ["nightly_protocol", "protocol_feature_block_header_v3", "protocol_feature_restore_receipts_after_fix"]
nightly_protocol = []
77 changes: 46 additions & 31 deletions chain/chain/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,8 @@ use rand::seq::SliceRandom;
use rand::SeedableRng;
use tracing::{debug, error, info, warn};

use crate::lightclient::get_epoch_block_producers_view;
use crate::missing_chunks::{BlockLike, MissingChunksPool};
use crate::store::{ChainStore, ChainStoreAccess, ChainStoreUpdate, GCMode};
use crate::types::{
AcceptedBlock, ApplyTransactionResult, Block, BlockEconomicsConfig, BlockHeader,
BlockHeaderInfo, BlockStatus, ChainGenesis, Provenance, RuntimeAdapter,
};
use crate::validate::{
validate_challenge, validate_chunk_proofs, validate_chunk_with_chunk_extra,
validate_transactions_order,
};
use crate::{byzantine_assert, create_light_client_block_view, Doomslug};
use crate::{metrics, DoomslugThresholdMode};

#[cfg(feature = "delay_detector")]
use delay_detector::DelayDetector;
use near_chain_primitives::error::{Error, ErrorKind, LogTransientStorageError};
use near_primitives::block::{genesis_chunks, Tip};
use near_primitives::challenge::{
Expand Down Expand Up @@ -62,8 +50,20 @@ use near_primitives::views::{
};
use near_store::{ColState, ColStateHeaders, ColStateParts, ShardTries, StoreUpdate};

#[cfg(feature = "delay_detector")]
use delay_detector::DelayDetector;
use crate::lightclient::get_epoch_block_producers_view;
use crate::migrations::check_if_block_is_first_with_chunk_of_version;
use crate::missing_chunks::{BlockLike, MissingChunksPool};
use crate::store::{ChainStore, ChainStoreAccess, ChainStoreUpdate, GCMode};
use crate::types::{
AcceptedBlock, ApplyTransactionResult, Block, BlockEconomicsConfig, BlockHeader,
BlockHeaderInfo, BlockStatus, ChainGenesis, Provenance, RuntimeAdapter,
};
use crate::validate::{
validate_challenge, validate_chunk_proofs, validate_chunk_with_chunk_extra,
validate_transactions_order,
};
use crate::{byzantine_assert, create_light_client_block_view, Doomslug};
use crate::{metrics, DoomslugThresholdMode};

/// Maximum number of orphans chain can store.
pub const MAX_ORPHAN_SIZE: usize = 1024;
Expand Down Expand Up @@ -2688,6 +2688,12 @@ impl<'a> ChainUpdate<'a> {
Some(&block.hash()),
)?;
let prev_chunk_inner = prev_chunk.cloned_header().take_inner();
let is_first_block_with_chunk_of_version = check_if_block_is_first_with_chunk_of_version(
&mut self.chain_store_update,
self.runtime_adapter.as_ref(),
&prev_block.hash(),
chunk_shard_id,
)?;
let apply_result = self
.runtime_adapter
.apply_transactions_with_optional_storage_proof(
Expand All @@ -2706,6 +2712,7 @@ impl<'a> ChainUpdate<'a> {
*block.header().random_value(),
true,
true,
is_first_block_with_chunk_of_version,
)
.unwrap();
let partial_state = apply_result.proof.unwrap().nodes;
Expand Down Expand Up @@ -2792,15 +2799,13 @@ impl<'a> ChainUpdate<'a> {
Err(err) => err,
}
})?;

let receipt_proof_response: Vec<ReceiptProofResponse> =
self.chain_store_update.get_incoming_receipts_for_shard(
shard_id,
*block.hash(),
prev_chunk_header.height_included(),
)?;
let receipts = collect_receipts_from_response(&receipt_proof_response);

let chunk = self
.chain_store_update
.get_chunk_clone_from_header(&chunk_header.clone())?;
Expand Down Expand Up @@ -2836,6 +2841,18 @@ impl<'a> ChainUpdate<'a> {
let chunk_inner = chunk.cloned_header().take_inner();
let gas_limit = chunk_inner.gas_limit();

// This variable is responsible for checking to which block we can apply receipts previously lost in apply_chunks
// (see https://github.com/near/nearcore/pull/4248/)
// We take the first block with existing chunk in the first epoch in which protocol feature
// RestoreReceiptsAfterFix was enabled, and put the restored receipts there.
let is_first_block_with_chunk_of_version =
check_if_block_is_first_with_chunk_of_version(
&mut self.chain_store_update,
self.runtime_adapter.as_ref(),
&prev_block.hash(),
shard_id,
)?;

// Apply transactions and receipts.
let apply_result = self
.runtime_adapter
Expand All @@ -2854,6 +2871,7 @@ impl<'a> ChainUpdate<'a> {
&block.header().challenges_result(),
*block.header().random_value(),
true,
is_first_block_with_chunk_of_version,
)
.map_err(|e| ErrorKind::Other(e.to_string()))?;

Expand Down Expand Up @@ -2909,26 +2927,14 @@ impl<'a> ChainUpdate<'a> {
&block.header().challenges_result(),
*block.header().random_value(),
false,
false,
)
.map_err(|e| ErrorKind::Other(e.to_string()))?;

self.chain_store_update.save_trie_changes(apply_result.trie_changes);
*new_extra.state_root_mut() = apply_result.new_root;

self.chain_store_update.save_chunk_extra(&block.hash(), shard_id, new_extra);

if !apply_result.outcomes.is_empty() {
// debug_assert!(false);
// Remove in next release
let (_, outcome_paths) =
ApplyTransactionResult::compute_outcomes_proof(&apply_result.outcomes);
self.chain_store_update.save_outcomes_with_proofs(
&block.hash(),
shard_id,
apply_result.outcomes,
outcome_paths,
);
}
}
}
}
Expand Down Expand Up @@ -3602,6 +3608,13 @@ impl<'a> ChainUpdate<'a> {

let chunk_header = chunk.cloned_header();
let gas_limit = chunk_header.gas_limit();
let is_first_block_with_chunk_of_version = check_if_block_is_first_with_chunk_of_version(
&mut self.chain_store_update,
self.runtime_adapter.as_ref(),
&chunk_header.prev_block_hash(),
shard_id,
)?;

let apply_result = self.runtime_adapter.apply_transactions(
shard_id,
&chunk_header.prev_state_root(),
Expand All @@ -3617,6 +3630,7 @@ impl<'a> ChainUpdate<'a> {
&block_header.challenges_result(),
*block_header.random_value(),
true,
is_first_block_with_chunk_of_version,
)?;

let (outcome_root, outcome_proofs) =
Expand Down Expand Up @@ -3696,6 +3710,7 @@ impl<'a> ChainUpdate<'a> {
&block_header.challenges_result(),
*block_header.random_value(),
false,
false,
)?;

self.chain_store_update.save_trie_changes(apply_result.trie_changes);
Expand Down
6 changes: 3 additions & 3 deletions chain/chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ pub use chain::{collect_receipts, Chain, MAX_ORPHAN_SIZE};
pub use doomslug::{Doomslug, DoomslugBlockProductionReadiness, DoomslugThresholdMode};
pub use lightclient::{create_light_client_block_view, get_epoch_block_producers_view};
pub use near_chain_primitives::{self, Error, ErrorKind};
pub use near_primitives::receipt::ReceiptResult;
pub use store::{ChainStore, ChainStoreAccess, ChainStoreUpdate};
pub use store_validator::{ErrorMessage, StoreValidator};
pub use types::{
Block, BlockHeader, BlockStatus, ChainGenesis, Provenance, ReceiptResult, RuntimeAdapter,
};
pub use types::{Block, BlockHeader, BlockStatus, ChainGenesis, Provenance, RuntimeAdapter};

pub mod chain;
mod doomslug;
mod lightclient;
mod metrics;
pub mod migrations;
pub mod missing_chunks;
mod store;
pub mod store_validator;
Expand Down
38 changes: 38 additions & 0 deletions chain/chain/src/migrations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use crate::store::ChainStoreAccess;
use crate::types::RuntimeAdapter;
use near_chain_primitives::error::Error;
use near_primitives::hash::CryptoHash;
use near_primitives::types::ShardId;

/// Check that epoch of block with given prev_block_hash is the first one with current protocol version.
fn is_first_epoch_with_protocol_version(
runtime_adapter: &dyn RuntimeAdapter,
prev_block_hash: &CryptoHash,
) -> Result<bool, Error> {
let prev_epoch_id = runtime_adapter.get_prev_epoch_id_from_prev_block(prev_block_hash)?;
let epoch_id = runtime_adapter.get_epoch_id_from_prev_block(prev_block_hash)?;
let protocol_version = runtime_adapter.get_epoch_protocol_version(&epoch_id)?;
let prev_epoch_protocol_version = runtime_adapter.get_epoch_protocol_version(&prev_epoch_id)?;
Ok(protocol_version != prev_epoch_protocol_version)
}

/// Check that block is the first one with existing chunk for the given shard in the chain with its protocol version.
/// We assume that current block contain the chunk for shard with the given id.
pub fn check_if_block_is_first_with_chunk_of_version(
chain_store: &mut dyn ChainStoreAccess,
runtime_adapter: &dyn RuntimeAdapter,
prev_block_hash: &CryptoHash,
shard_id: ShardId,
) -> Result<bool, Error> {
// Check that block belongs to the first epoch with current protocol version
// to avoid get_epoch_id_of_last_block_with_chunk call in the opposite case
if is_first_epoch_with_protocol_version(runtime_adapter, prev_block_hash)? {
// Compare only epochs because we already know that current epoch is the first one with current protocol version
let prev_epoch_id =
chain_store.get_epoch_id_of_last_block_with_chunk(prev_block_hash, shard_id)?;
let epoch_id = runtime_adapter.get_epoch_id_from_prev_block(prev_block_hash)?;
Ok(prev_epoch_id != epoch_id)
} else {
Ok(false)
}
}
20 changes: 18 additions & 2 deletions chain/chain/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use near_primitives::block::{Approval, Tip};
use near_primitives::errors::InvalidTxError;
use near_primitives::hash::CryptoHash;
use near_primitives::merkle::{MerklePath, PartialMerkleTree};
use near_primitives::receipt::Receipt;
use near_primitives::receipt::{Receipt, ReceiptResult};
use near_primitives::sharding::{
ChunkHash, EncodedShardChunk, PartialEncodedChunk, ReceiptProof, ShardChunk, ShardChunkHeader,
StateSyncInfo,
Expand Down Expand Up @@ -48,8 +48,8 @@ use near_store::{
TAIL_KEY,
};

use crate::byzantine_assert;
use crate::types::{Block, BlockHeader, LatestKnown};
use crate::{byzantine_assert, ReceiptResult};

/// lru cache size
#[cfg(not(feature = "no_cache"))]
Expand Down Expand Up @@ -278,6 +278,22 @@ pub trait ChainStoreAccess {
Ok(self.get_block_header(hash)?.height())
}
}

/// Get epoch id of the last block with existing chunk for the given shard id.
fn get_epoch_id_of_last_block_with_chunk(
&mut self,
hash: &CryptoHash,
shard_id: ShardId,
) -> Result<EpochId, Error> {
let mut candidate_hash = *hash;
loop {
let block_header = self.get_block_header(&candidate_hash)?;
if block_header.chunk_mask()[shard_id as usize] {
break Ok(block_header.epoch_id().clone());
}
candidate_hash = *block_header.prev_hash();
}
}
}

/// All chain-related database operations.
Expand Down
18 changes: 18 additions & 0 deletions chain/chain/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,7 @@ impl RuntimeAdapter for KeyValueRuntime {
_random_seed: CryptoHash,
generate_storage_proof: bool,
_is_new_chunk: bool,
_is_first_block_with_chunk_of_version: bool,
) -> Result<ApplyTransactionResult, Error> {
assert!(!generate_storage_proof);
let mut tx_results = vec![];
Expand Down Expand Up @@ -783,6 +784,7 @@ impl RuntimeAdapter for KeyValueRuntime {
_challenges: &ChallengesResult,
_random_value: CryptoHash,
_is_new_chunk: bool,
_is_first_block_with_chunk_of_version: bool,
) -> Result<ApplyTransactionResult, Error> {
unimplemented!();
}
Expand Down Expand Up @@ -1098,6 +1100,22 @@ impl RuntimeAdapter for KeyValueRuntime {
fn get_protocol_config(&self, _epoch_id: &EpochId) -> Result<ProtocolConfig, Error> {
unreachable!("get_protocol_config should not be called in KeyValueRuntime");
}

fn get_prev_epoch_id_from_prev_block(
&self,
prev_block_hash: &CryptoHash,
) -> Result<EpochId, Error> {
let mut candidate_hash = prev_block_hash.clone();
loop {
let header = self
.get_block_header(&candidate_hash)?
.ok_or_else(|| ErrorKind::DBNotFoundErr(to_base(&candidate_hash)))?;
candidate_hash = header.prev_hash().clone();
if self.is_next_block_epoch_start(&candidate_hash)? {
break Ok(self.get_epoch_and_valset(candidate_hash)?.0);
}
}
}
}

pub fn setup() -> (Chain, Arc<KeyValueRuntime>, Arc<InMemoryValidatorSigner>) {
Expand Down
Loading