Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Longarithm authored Jan 15, 2024
2 parents e517fa1 + 75d4c60 commit c72b4ec
Show file tree
Hide file tree
Showing 100 changed files with 1,825 additions and 1,324 deletions.
1 change: 1 addition & 0 deletions .github/workflows/issue-metrics.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:

permissions:
issues: write
pull-requests: read

jobs:
monthly-issue-metrics:
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

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

10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,18 @@ members = [
warnings = "deny"

[workspace.lints.clippy]
all = { level = "allow", priority = -1 }
all = { level = "allow", priority = -100 }
correctness = { level = "deny", priority = -50 }
suspicious = { level = "deny", priority = -50 }
perf = { level = "deny", priority = -50 }
# overrides clippy::perf = "deny": https://github.com/rust-lang/rust-clippy/issues/8111
single_char_pattern = "allow"
clone_on_copy = "deny"
correctness = "deny"
derivable_impls = "deny"
redundant_clone = "deny"
suspicious = "deny"
len_zero = "deny"


[workspace.dependencies]
actix = "0.13.0"
actix-cors = "0.6.1"
Expand Down
6 changes: 3 additions & 3 deletions chain/chain-primitives/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ pub enum Error {
#[error("Invalid Chunk State")]
InvalidChunkState(Box<ChunkState>),
#[error("Invalid Chunk State Witness")]
InvalidChunkStateWitness,
InvalidChunkStateWitness(String),
/// Invalid chunk mask
#[error("Invalid Chunk Mask")]
InvalidChunkMask,
Expand Down Expand Up @@ -270,7 +270,7 @@ impl Error {
| Error::InvalidChunk
| Error::InvalidChunkProofs(_)
| Error::InvalidChunkState(_)
| Error::InvalidChunkStateWitness
| Error::InvalidChunkStateWitness(_)
| Error::InvalidChunkMask
| Error::InvalidStateRoot
| Error::InvalidTxRoot
Expand Down Expand Up @@ -343,7 +343,7 @@ impl Error {
Error::InvalidChunk => "invalid_chunk",
Error::InvalidChunkProofs(_) => "invalid_chunk_proofs",
Error::InvalidChunkState(_) => "invalid_chunk_state",
Error::InvalidChunkStateWitness => "invalid_chunk_state_witness",
Error::InvalidChunkStateWitness(_) => "invalid_chunk_state_witness",
Error::InvalidChunkMask => "invalid_chunk_mask",
Error::InvalidStateRoot => "invalid_state_root",
Error::InvalidTxRoot => "invalid_tx_root",
Expand Down
437 changes: 75 additions & 362 deletions chain/chain/src/chain.rs

Large diffs are not rendered by default.

56 changes: 24 additions & 32 deletions chain/chain/src/chain_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use crate::metrics::{SHARD_LAYOUT_NUM_SHARDS, SHARD_LAYOUT_VERSION};
use crate::store::{ChainStore, ChainStoreAccess, ChainStoreUpdate};

use crate::types::{
ApplyTransactionResult, ApplyTransactionsBlockContext, ApplyTransactionsChunkContext,
ReshardingResults, RuntimeAdapter, RuntimeStorageConfig,
ApplyChunkBlockContext, ApplyChunkResult, ApplyChunkShardContext, ReshardingResults,
RuntimeAdapter, RuntimeStorageConfig,
};
use crate::update_shard::{
NewChunkResult, OldChunkResult, ReshardingResult, ShardBlockUpdateResult, ShardUpdateResult,
Expand Down Expand Up @@ -149,25 +149,8 @@ impl<'a> ChainUpdate<'a> {
apply_results: Vec<ShardUpdateResult>,
) -> Result<(), Error> {
let _span = tracing::debug_span!(target: "chain", "apply_chunk_postprocessing").entered();
for result in apply_results {
match result {
ShardUpdateResult::Stateful(result) => {
self.process_apply_chunk_result(block, result)?
}
ShardUpdateResult::Stateless(results) => {
for (block_hash, shard_uid, chunk_extra) in results {
let expected_chunk_extra =
self.chain_store_update.get_chunk_extra(&block_hash, &shard_uid)?;
assert_eq!(
&chunk_extra,
expected_chunk_extra.as_ref(),
"For stateless validation, chunk extras for block {} and shard {} do not match",
block_hash,
shard_uid
);
}
}
}
for ShardUpdateResult::Stateful(result) in apply_results {
self.process_apply_chunk_result(block, result)?;
}
Ok(())
}
Expand Down Expand Up @@ -330,7 +313,7 @@ impl<'a> ChainUpdate<'a> {
resharding_results,
}) => {
let (outcome_root, outcome_paths) =
ApplyTransactionResult::compute_outcomes_proof(&apply_result.outcomes);
ApplyChunkResult::compute_outcomes_proof(&apply_result.outcomes);
let shard_id = shard_uid.shard_id();

// Save state root after applying transactions.
Expand Down Expand Up @@ -370,6 +353,12 @@ impl<'a> ChainUpdate<'a> {
apply_result.outcomes,
outcome_paths,
);
self.chain_store_update.save_state_transition_data(
*block_hash,
shard_id,
apply_result.proof,
apply_result.applied_receipts_hash,
);
if let Some(resharding_results) = resharding_results {
self.process_resharding_results(block, &shard_uid, resharding_results)?;
}
Expand All @@ -396,6 +385,12 @@ impl<'a> ChainUpdate<'a> {

self.chain_store_update.save_chunk_extra(block_hash, &shard_uid, new_extra);
self.chain_store_update.save_trie_changes(apply_result.trie_changes);
self.chain_store_update.save_state_transition_data(
*block_hash,
shard_uid.shard_id(),
apply_result.proof,
apply_result.applied_receipts_hash,
);

if let Some(resharding_config) = resharding_results {
self.process_resharding_results(block, &shard_uid, resharding_config)?;
Expand Down Expand Up @@ -732,16 +727,16 @@ impl<'a> ChainUpdate<'a> {
// TODO(nikurt): Determine the value correctly.
let is_first_block_with_chunk_of_version = false;

let apply_result = self.runtime_adapter.apply_transactions(
let apply_result = self.runtime_adapter.apply_chunk(
RuntimeStorageConfig::new(chunk_header.prev_state_root(), true),
ApplyTransactionsChunkContext {
ApplyChunkShardContext {
shard_id,
gas_limit,
last_validator_proposals: chunk_header.prev_validator_proposals(),
is_first_block_with_chunk_of_version,
is_new_chunk: true,
},
ApplyTransactionsBlockContext {
ApplyChunkBlockContext {
height: chunk_header.height_included(),
block_hash: *block_header.hash(),
prev_block_hash: *chunk_header.prev_block_hash(),
Expand All @@ -755,7 +750,7 @@ impl<'a> ChainUpdate<'a> {
)?;

let (outcome_root, outcome_proofs) =
ApplyTransactionResult::compute_outcomes_proof(&apply_result.outcomes);
ApplyChunkResult::compute_outcomes_proof(&apply_result.outcomes);

self.chain_store_update.save_chunk(chunk);

Expand Down Expand Up @@ -829,19 +824,16 @@ impl<'a> ChainUpdate<'a> {
let chunk_extra =
self.chain_store_update.get_chunk_extra(prev_block_header.hash(), &shard_uid)?;

let apply_result = self.runtime_adapter.apply_transactions(
let apply_result = self.runtime_adapter.apply_chunk(
RuntimeStorageConfig::new(*chunk_extra.state_root(), true),
ApplyTransactionsChunkContext {
ApplyChunkShardContext {
shard_id,
last_validator_proposals: chunk_extra.validator_proposals(),
gas_limit: chunk_extra.gas_limit(),
is_new_chunk: false,
is_first_block_with_chunk_of_version: false,
},
ApplyTransactionsBlockContext::from_header(
&block_header,
prev_block_header.next_gas_price(),
),
ApplyChunkBlockContext::from_header(&block_header, prev_block_header.next_gas_price()),
&[],
&[],
)?;
Expand Down
3 changes: 3 additions & 0 deletions chain/chain/src/garbage_collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,9 @@ impl<'a> ChainStoreUpdate<'a> {
DBCol::HeaderHashesByHeight => {
store_update.delete(col, key);
}
DBCol::StateTransitionData => {
store_update.delete(col, key);
}
DBCol::DbVersion
| DBCol::BlockMisc
| DBCol::_GCCount
Expand Down
1 change: 1 addition & 0 deletions chain/chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub mod test_utils;
pub mod types;
pub mod validate;

pub mod sharding;
#[cfg(test)]
mod tests;
mod update_shard;
Expand Down
28 changes: 28 additions & 0 deletions chain/chain/src/sharding.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use near_primitives::hash::CryptoHash;
use rand::seq::SliceRandom;
use rand::SeedableRng;
use rand_chacha::ChaCha20Rng;

pub fn shuffle_receipt_proofs<ReceiptProofType>(
receipt_proofs: &mut Vec<ReceiptProofType>,
block_hash: &CryptoHash,
) {
let mut slice = [0u8; 32];
slice.copy_from_slice(block_hash.as_ref());
let mut rng: ChaCha20Rng = SeedableRng::from_seed(slice);
receipt_proofs.shuffle(&mut rng);
}

#[cfg(test)]
mod tests {
use crate::sharding::shuffle_receipt_proofs;
use near_primitives::hash::CryptoHash;

#[test]
pub fn receipt_randomness_reproducibility() {
// Sanity check that the receipt shuffling implementation does not change.
let mut receipt_proofs = vec![0, 1, 2, 3, 4, 5, 6];
shuffle_receipt_proofs(&mut receipt_proofs, &CryptoHash::hash_bytes(&[1, 2, 3, 4, 5]));
assert_eq!(receipt_proofs, vec![2, 3, 1, 4, 0, 5, 6],);
}
}
36 changes: 31 additions & 5 deletions chain/chain/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,15 @@ use near_primitives::utils::{
use near_primitives::version::ProtocolVersion;
use near_primitives::views::LightClientBlockView;
use near_store::{
DBCol, KeyForStateChanges, Store, StoreUpdate, WrappedTrieChanges, CHUNK_TAIL_KEY,
FINAL_HEAD_KEY, FORK_TAIL_KEY, HEADER_HEAD_KEY, HEAD_KEY, LARGEST_TARGET_HEIGHT_KEY,
LATEST_KNOWN_KEY, TAIL_KEY,
DBCol, KeyForStateChanges, PartialStorage, Store, StoreUpdate, WrappedTrieChanges,
CHUNK_TAIL_KEY, FINAL_HEAD_KEY, FORK_TAIL_KEY, HEADER_HEAD_KEY, HEAD_KEY,
LARGEST_TARGET_HEIGHT_KEY, LATEST_KNOWN_KEY, TAIL_KEY,
};

use crate::byzantine_assert;
use crate::chunks_store::ReadOnlyChunksStore;
use crate::types::{Block, BlockHeader, LatestKnown};
use near_primitives::chunk_validation::StoredChunkStateTransitionData;
use near_store::db::{StoreStatistics, STATE_SYNC_DUMP_KEY};
use std::sync::Arc;

Expand Down Expand Up @@ -1438,11 +1439,10 @@ pub struct ChainStoreUpdate<'a> {
final_head: Option<Tip>,
largest_target_height: Option<BlockHeight>,
trie_changes: Vec<WrappedTrieChanges>,

state_transition_data: HashMap<(CryptoHash, ShardId), StoredChunkStateTransitionData>,
// All state changes made by a chunk, this is only used for resharding.
add_state_changes_for_resharding: HashMap<(CryptoHash, ShardId), StateChangesForResharding>,
remove_state_changes_for_resharding: HashSet<(CryptoHash, ShardId)>,

add_blocks_to_catchup: Vec<(CryptoHash, CryptoHash)>,
// A pair (prev_hash, hash) to be removed from blocks to catchup
remove_blocks_to_catchup: Vec<(CryptoHash, CryptoHash)>,
Expand All @@ -1467,6 +1467,7 @@ impl<'a> ChainStoreUpdate<'a> {
final_head: None,
largest_target_height: None,
trie_changes: vec![],
state_transition_data: Default::default(),
add_state_changes_for_resharding: HashMap::new(),
remove_state_changes_for_resharding: HashSet::new(),
add_blocks_to_catchup: vec![],
Expand Down Expand Up @@ -2077,6 +2078,24 @@ impl<'a> ChainStoreUpdate<'a> {
self.trie_changes.push(trie_changes);
}

pub fn save_state_transition_data(
&mut self,
block_hash: CryptoHash,
shard_id: ShardId,
partial_storage: Option<PartialStorage>,
applied_receipts_hash: CryptoHash,
) {
if let Some(partial_storage) = partial_storage {
self.state_transition_data.insert(
(block_hash, shard_id),
StoredChunkStateTransitionData {
base_state: partial_storage.nodes,
receipts_hash: applied_receipts_hash,
},
);
}
}

pub fn add_state_changes_for_resharding(
&mut self,
block_hash: CryptoHash,
Expand Down Expand Up @@ -2526,6 +2545,13 @@ impl<'a> ChainStoreUpdate<'a> {
}
}

for ((block_hash, shard_id), state_transition_data) in self.state_transition_data.drain() {
store_update.set_ser(
DBCol::StateTransitionData,
&get_block_shard_id(&block_hash, shard_id),
&state_transition_data,
)?;
}
for ((block_hash, shard_id), state_changes) in self.add_state_changes_for_resharding.drain()
{
store_update.set_ser(
Expand Down
15 changes: 8 additions & 7 deletions chain/chain/src/test_utils/kv_runtime.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::ValidatorSchedule;
use crate::types::{
ApplyResultForResharding, ApplyTransactionResult, ApplyTransactionsBlockContext,
ApplyTransactionsChunkContext, RuntimeAdapter, RuntimeStorageConfig,
ApplyChunkBlockContext, ApplyChunkResult, ApplyChunkShardContext, ApplyResultForResharding,
RuntimeAdapter, RuntimeStorageConfig,
};
use crate::BlockHeader;
use borsh::{BorshDeserialize, BorshSerialize};
Expand Down Expand Up @@ -1040,14 +1040,14 @@ impl RuntimeAdapter for KeyValueRuntime {
Ok(res)
}

fn apply_transactions(
fn apply_chunk(
&self,
storage_config: RuntimeStorageConfig,
chunk: ApplyTransactionsChunkContext,
block: ApplyTransactionsBlockContext,
chunk: ApplyChunkShardContext,
block: ApplyChunkBlockContext,
receipts: &[Receipt],
transactions: &[SignedTransaction],
) -> Result<ApplyTransactionResult, Error> {
) -> Result<ApplyChunkResult, Error> {
assert!(!storage_config.record_storage);
let mut tx_results = vec![];
let shard_id = chunk.shard_id;
Expand Down Expand Up @@ -1181,7 +1181,7 @@ impl RuntimeAdapter for KeyValueRuntime {
self.state.write().unwrap().insert(state_root, state);
self.state_size.write().unwrap().insert(state_root, state_size);

Ok(ApplyTransactionResult {
Ok(ApplyChunkResult {
trie_changes: WrappedTrieChanges::new(
self.get_tries(),
ShardUId { version: 0, shard_id: shard_id as u32 },
Expand All @@ -1198,6 +1198,7 @@ impl RuntimeAdapter for KeyValueRuntime {
total_balance_burnt: 0,
proof: None,
processed_delayed_receipts: vec![],
applied_receipts_hash: hash(&borsh::to_vec(receipts).unwrap()),
})
}

Expand Down
2 changes: 1 addition & 1 deletion chain/chain/src/tests/doomslug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn one_iter(
delta: Duration,
height_goal: BlockHeight,
) -> (Duration, BlockHeight) {
let account_ids = vec!["test1", "test2", "test3", "test4", "test5", "test6", "test7", "test8"];
let account_ids = ["test1", "test2", "test3", "test4", "test5", "test6", "test7", "test8"];
let stakes = account_ids
.iter()
.map(|account_id| ApprovalStake {
Expand Down
Loading

0 comments on commit c72b4ec

Please sign in to comment.