Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
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.

7 changes: 3 additions & 4 deletions executor/evm/src/block_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
use std::sync::Arc;

use casper_storage::block_store::{
lmdb::IndexedLmdbBlockStore, types::BlockHeight, BlockStoreError, BlockStoreProvider,
DataReader,
lmdb::LmdbBlockStore, types::BlockHeight, BlockStoreError, BlockStoreProvider, DataReader,
};
use casper_types::{BlockHash, BlockHeader};

Expand Down Expand Up @@ -42,12 +41,12 @@ impl BlockHashProvider for NoBlockHashProvider {
/// Block hash provider backed by Casper's indexed LMDB block store.
#[derive(Clone, Debug)]
pub struct IndexedLmdbBlockHashProvider {
block_store: Arc<IndexedLmdbBlockStore>,
block_store: Arc<LmdbBlockStore>,
}

impl IndexedLmdbBlockHashProvider {
/// Creates a block hash provider backed by `block_store`.
pub fn new(block_store: Arc<IndexedLmdbBlockStore>) -> Self {
pub fn new(block_store: Arc<LmdbBlockStore>) -> Self {
Self { block_store }
}
}
Expand Down
17 changes: 14 additions & 3 deletions node/src/components/block_accumulator/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,20 @@ impl Reactor for MockReactor {
)
.unwrap();

let storage = Storage::new(
let protocol_version = ProtocolVersion::from_parts(1, 0, 0);
let (storage_root, mut storage_block_store) =
storage::open_block_store(&storage_withdir, "test").unwrap();
storage::prune_block_store(
&mut storage_block_store,
chainspec.hard_reset_to_start_of_era(),
protocol_version,
)
.unwrap();
let mut storage = Storage::new(
&storage_withdir,
None,
ProtocolVersion::from_parts(1, 0, 0),
storage_root,
storage_block_store,
protocol_version,
EraId::default(),
"test",
chainspec.transaction_config.max_ttl.into(),
Expand All @@ -200,6 +210,7 @@ impl Reactor for MockReactor {
TransactionConfig::default(),
)
.unwrap();
storage.initialize_for_test();

let reactor = MockReactor {
storage,
Expand Down
144 changes: 50 additions & 94 deletions node/src/components/contract_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ mod utils;

use std::{
cmp::Ordering,
collections::BTreeMap,
convert::TryInto,
fmt::{self, Debug, Formatter},
path::Path,
Expand All @@ -33,7 +32,7 @@ use casper_storage::{
data_access_layer::{
AddressableEntityRequest, AddressableEntityResult, BlockStore, DataAccessLayer,
EntryPointExistsRequest, ExecutionResultsChecksumRequest, FlushRequest, FlushResult,
GenesisRequest, GenesisResult, TrieRequest,
GenesisRequest, GenesisResult, ProtocolUpgradeRequest, ProtocolUpgradeResult, TrieRequest,
},
global_state::{
state::{lmdb::LmdbGlobalState, CommitProvider, StateProvider},
Expand All @@ -44,13 +43,13 @@ use casper_storage::{
tracking_copy::TrackingCopyError,
};
use casper_types::{
account::AccountHash, ActivationPoint, Chainspec, ChainspecRawBytes, ChainspecRegistry,
EntityAddr, EraId, Key, PublicKey,
account::AccountHash, ActivationPoint, Chainspec, ChainspecRawBytes, ChainspecRegistry, Digest,
EntityAddr, EraId, Key, ProtocolUpgradeConfig,
};

use crate::{
components::{fetcher::FetchResponse, Component, ComponentState},
contract_runtime::{types::EraPrice, utils::handle_protocol_upgrade},
contract_runtime::types::EraPrice,
effect::{
announcements::{
ContractRuntimeAnnouncement, FatalAnnouncement, MetaBlockAnnouncement,
Expand All @@ -62,10 +61,7 @@ use crate::{
},
fatal,
protocol::Message,
types::{
BlockPayload, ExecutableBlock, FinalizedBlock, InternalEraReport, MetaBlockState,
TrieOrChunk, TrieOrChunkId,
},
types::{TrieOrChunk, TrieOrChunkId},
NodeRng,
};
pub(crate) use config::Config;
Expand Down Expand Up @@ -307,6 +303,47 @@ impl ContractRuntime {
result
}

/// Commits a protocol upgrade against global state and flushes it to disk.
///
/// The commit itself runs on the blocking thread-pool (via `run_intensive_task`), since it
/// can take a long time; this lets the caller bound the wait with a timeout instead of
/// stalling its task indefinitely.
pub(crate) async fn commit_protocol_upgrade(
&self,
upgrade_config: ProtocolUpgradeConfig,
) -> Result<Digest, String> {
debug!(?upgrade_config, "upgrade");
let start = Instant::now();
let upgrade_request = ProtocolUpgradeRequest::new(upgrade_config);

let data_access_layer = Arc::clone(&self.data_access_layer);
let metrics = Arc::clone(&self.metrics);
run_intensive_task(move || {
let result = data_access_layer.protocol_upgrade(upgrade_request);
if result.is_success() {
info!("committed upgrade");
metrics
.commit_upgrade
.observe(start.elapsed().as_secs_f64());
let flush_req = FlushRequest::new();
if let FlushResult::Failure(err) = data_access_layer.flush(flush_req) {
return Err(format!("{:?}", err));
}
}

match result {
ProtocolUpgradeResult::RootNotFound => {
Err("Root not found for protocol upgrade".to_string())
}
ProtocolUpgradeResult::Failure(err) => Err(format!("{:?}", err)),
ProtocolUpgradeResult::Success {
post_state_hash, ..
} => Ok(post_state_hash),
}
})
.await
}

/// Handles a contract runtime request.
fn handle_contract_runtime_request<REv>(
&mut self,
Expand Down Expand Up @@ -546,91 +583,6 @@ impl ContractRuntime {
}
.ignore()
}
ContractRuntimeRequest::UpdatePreState { new_pre_state } => {
let next_block_height = new_pre_state.next_block_height();
self.set_execution_pre_state(new_pre_state);
let current_price = self.current_gas_price.gas_price();
async move {
let block_header = match effect_builder
.get_highest_complete_block_header_from_storage()
.await
{
Some(header)
if header.is_switch_block()
&& (header.height() + 1 == next_block_height) =>
{
header
}
Some(_) => {
return fatal!(
effect_builder,
"Latest complete block is not a switch block to update state"
)
.await;
}
None => {
return fatal!(
effect_builder,
"No complete block header found to update post upgrade state"
)
.await;
}
};

let payload = BlockPayload::new(
BTreeMap::new(),
vec![],
Default::default(),
false,
current_price,
);

let finalized_block = FinalizedBlock::new(
payload,
Some(InternalEraReport::default()),
block_header.timestamp(),
block_header.next_block_era_id(),
next_block_height,
PublicKey::System,
);

info!("Enqueuing block for execution post state refresh");

effect_builder
.enqueue_block_for_execution(
ExecutableBlock::from_finalized_block_and_transactions(
finalized_block,
vec![],
),
MetaBlockState::new_not_to_be_gossiped(),
)
.await;
}
.ignore()
}
ContractRuntimeRequest::DoProtocolUpgrade {
protocol_upgrade_config,
next_block_height,
parent_hash,
parent_seed,
} => {
let mut effects = Effects::new();
let data_access_layer = Arc::clone(&self.data_access_layer);
let metrics = Arc::clone(&self.metrics);
effects.extend(
handle_protocol_upgrade(
effect_builder,
data_access_layer,
metrics,
*protocol_upgrade_config,
next_block_height,
parent_hash,
parent_seed,
)
.ignore(),
);
effects
}
ContractRuntimeRequest::EnqueueBlockForExecution {
executable_block,
key_block_height_for_activation_point,
Expand Down Expand Up @@ -847,6 +799,10 @@ impl ContractRuntime {
pub(crate) fn current_era_price(&self) -> EraPrice {
self.current_gas_price
}

pub(crate) fn current_gas_price(&self) -> u8 {
self.current_gas_price.gas_price()
}
}

impl<REv> Component<REv> for ContractRuntime
Expand Down
14 changes: 12 additions & 2 deletions node/src/components/contract_runtime/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,18 @@ impl reactor::Reactor for Reactor {
}

let storage_withdir = WithDir::new(storage_tempdir.path(), storage_config);
let storage = Storage::new(
let (storage_root, mut storage_block_store) =
storage::open_block_store(&storage_withdir, "test").unwrap();
storage::prune_block_store(
&mut storage_block_store,
chainspec.hard_reset_to_start_of_era(),
chainspec.protocol_version(),
)
.unwrap();
let mut storage = Storage::new(
&storage_withdir,
None,
storage_root,
storage_block_store,
chainspec.protocol_version(),
EraId::default(),
"test",
Expand All @@ -137,6 +146,7 @@ impl reactor::Reactor for Reactor {
TransactionConfig::default(),
)
.unwrap();
storage.initialize_for_test();

let contract_runtime =
ContractRuntime::new(storage.root_path(), &config.config, chainspec, registry)?;
Expand Down
81 changes: 3 additions & 78 deletions node/src/components/contract_runtime/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use std::{
fmt::Debug,
ops::Range,
sync::{Arc, Mutex},
time::Instant,
};
use tracing::{debug, error, info};

Expand All @@ -36,15 +35,10 @@ use crate::{
use casper_binary_port::SpeculativeExecutionResult;
use casper_execution_engine::engine_state::{ExecutionEngineV1, WasmV1Result};
use casper_storage::{
data_access_layer::{
DataAccessLayer, FlushRequest, FlushResult, ProtocolUpgradeRequest, ProtocolUpgradeResult,
TransferResult,
},
global_state::state::{lmdb::LmdbGlobalState, CommitProvider, StateProvider},
};
use casper_types::{
BlockHash, Chainspec, Digest, EraId, Gas, Key, ProtocolUpgradeConfig, Transaction,
data_access_layer::{DataAccessLayer, TransferResult},
global_state::state::lmdb::LmdbGlobalState,
};
use casper_types::{BlockHash, Chainspec, EraId, Gas, Key, Transaction};

/// Maximum number of resource intensive tasks that can be run in parallel.
///
Expand Down Expand Up @@ -493,75 +487,6 @@ pub(super) async fn exec_and_check_next<REv>(
}
}

pub(super) async fn handle_protocol_upgrade<REv>(
effect_builder: EffectBuilder<REv>,
data_access_layer: Arc<DataAccessLayer<LmdbGlobalState>>,
metrics: Arc<Metrics>,
upgrade_config: ProtocolUpgradeConfig,
next_block_height: u64,
parent_hash: BlockHash,
parent_seed: Digest,
) where
REv: From<ContractRuntimeRequest>
+ From<ContractRuntimeAnnouncement>
+ From<StorageRequest>
+ From<MetaBlockAnnouncement>
+ From<FatalAnnouncement>
+ Send,
{
debug!(?upgrade_config, "upgrade");
let start = Instant::now();
let upgrade_request = ProtocolUpgradeRequest::new(upgrade_config);

let result = run_intensive_task(move || {
let result = data_access_layer.protocol_upgrade(upgrade_request);
if result.is_success() {
info!("committed upgrade");
metrics
.commit_upgrade
.observe(start.elapsed().as_secs_f64());
let flush_req = FlushRequest::new();
if let FlushResult::Failure(err) = data_access_layer.flush(flush_req) {
return Err(format!("{:?}", err));
}
}

Ok(result)
})
.await;

match result {
Err(error_msg) => {
// The only way this happens is if there is a problem in the flushing.
error!(%error_msg, ":Error in post upgrade flush");
fatal!(effect_builder, "{}", error_msg).await;
}
Ok(result) => match result {
ProtocolUpgradeResult::RootNotFound => {
let error_msg = "Root not found for protocol upgrade";
fatal!(effect_builder, "{}", error_msg).await;
}
ProtocolUpgradeResult::Failure(err) => {
fatal!(effect_builder, "{:?}", err).await;
}
ProtocolUpgradeResult::Success {
post_state_hash, ..
} => {
let post_upgrade_state = ExecutionPreState::new(
next_block_height,
post_state_hash,
parent_hash,
parent_seed,
);

effect_builder
.update_contract_runtime_state(post_upgrade_state)
.await
}
},
}
}

fn generate_range_by_index(
highest_era: u64,
batch_size: u64,
Expand Down
Loading
Loading