Skip to content

Commit

Permalink
compare the genesis in storage and code when server start, then sugge…
Browse files Browse the repository at this point in the history
…st users clean the storage (#682)

* compare the genesis in storage and code when server start

* fixed genesis match and and suggest user

* revert coin doc changes

* remove redundent clone call

* remove docs in geneis crate
  • Loading branch information
baichuan3 authored Aug 23, 2023
1 parent 3f9bfc8 commit bd9ad8e
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 18 deletions.
4 changes: 4 additions & 0 deletions crates/rooch-executor/src/actor/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,14 @@ impl ExecutorActor {
pub fn new(moveos_store: MoveOSStore, rooch_store: RoochStore) -> Result<Self> {
let genesis: &RoochGenesis = &rooch_genesis::ROOCH_GENESIS;

let config_store_ref = moveos_store.get_config_store().clone();
let mut moveos = MoveOS::new(moveos_store, genesis.all_natives(), genesis.config.clone())?;
if moveos.state().is_genesis() {
moveos.init_genesis(genesis.genesis_txs())?;
} else {
genesis.check_genesis(&config_store_ref)?;
}

Ok(Self {
moveos,
rooch_store,
Expand Down
3 changes: 2 additions & 1 deletion crates/rooch-genesis/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,5 @@ moveos-stdlib-builder = { workspace = true }
moveos = { workspace = true }
moveos-store = { workspace = true }

rooch-framework = { workspace = true }
rooch-framework = { workspace = true }
rooch-types = { workspace = true }
42 changes: 42 additions & 0 deletions crates/rooch-genesis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ use move_core_types::{account_address::AccountAddress, identifier::Identifier};
use move_vm_runtime::{config::VMConfig, native_functions::NativeFunction};
use moveos::moveos::MoveOSConfig;
use moveos_stdlib_builder::BuildOptions;
use moveos_store::config_store::ConfigDBStore;
use moveos_types::h256;
use moveos_types::h256::H256;
use moveos_types::transaction::{MoveAction, MoveOSTransaction};
use once_cell::sync::Lazy;
use rooch_types::error::GenesisError;
use serde::{Deserialize, Serialize};
use std::{
fs::File,
Expand Down Expand Up @@ -82,6 +86,38 @@ impl RoochGenesis {
pub fn all_natives(&self) -> Vec<(AccountAddress, Identifier, Identifier, NativeFunction)> {
rooch_framework::natives::all_natives(self.gas_params.clone())
}

pub fn genesis_hash(&self) -> H256 {
h256::sha3_256_of(
bcs::to_bytes(&self.genesis_txs())
.expect("genesis txs bcs to_bytes should success")
.as_slice(),
)
}

pub fn check_genesis(&self, config_store: &ConfigDBStore) -> Result<()> {
let genesis_hash_result = config_store.get_genesis();
match genesis_hash_result {
Ok(Some(genesis_hash_store)) => {
let genesis_hash = self.genesis_hash();
if genesis_hash_store != genesis_hash {
return Err(GenesisError::GenesisVersionMismatch {
expect: genesis_hash_store,
real: genesis_hash,
}
.into());
}
}
Err(e) => return Err(GenesisError::GenesisLoadFailure(e.to_string()).into()),
Ok(None) => {
return Err(GenesisError::GenesisNotExist(
"genesis hash from store is none".to_string(),
)
.into())
}
}
Ok(())
}
}

static GENESIS_PACKAGE_BYTES: &[u8] = include_bytes!("../genesis/genesis");
Expand Down Expand Up @@ -187,6 +223,12 @@ mod tests {
assert_eq!(genesis.genesis_package.genesis_txs.len(), 3);
}

#[test]
fn test_genesis_hash() {
let genesis = super::RoochGenesis::build().expect("build rooch framework failed");
genesis.genesis_hash();
}

#[test]
fn test_genesis_init() {
let genesis = super::RoochGenesis::build().expect("build rooch framework failed");
Expand Down
1 change: 1 addition & 0 deletions crates/rooch-rpc-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ serde_with = { workspace = true }
rand = { workspace = true }
fastcrypto = { workspace = true }
hyper = { workspace = true }
log = { workspace = true }

move-core-types = { workspace = true }
move-resource-viewer = { workspace = true }
Expand Down
22 changes: 21 additions & 1 deletion crates/rooch-rpc-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use jsonrpsee::http_client::{HttpClient, HttpClientBuilder};
use jsonrpsee::server::ServerBuilder;
use jsonrpsee::RpcModule;
use moveos_config::store_config::RocksdbConfig;
use moveos_store::config_store::ConfigStore;
use moveos_store::{MoveOSDB, MoveOSStore};
use raw_store::rocks::RocksDB;
use raw_store::StoreInstance;
Expand All @@ -31,6 +30,7 @@ use rooch_sequencer::actor::sequencer::SequencerActor;
use rooch_sequencer::proxy::SequencerProxy;
use rooch_store::RoochStore;
use rooch_types::chain_id::ChainID;
use rooch_types::error::GenesisError;
use serde_json::json;
use std::env;
use std::fmt::Debug;
Expand All @@ -42,6 +42,9 @@ use tracing::info;
pub mod server;
pub mod service;

/// This exit code means is that the server failed to start and required human intervention.
static R_EXIT_CODE_NEED_HELP: i32 = 120;

pub fn http_client(url: impl AsRef<str>) -> Result<HttpClient> {
let client = HttpClientBuilder::default().build(url)?;
Ok(client)
Expand Down Expand Up @@ -115,6 +118,23 @@ impl RpcModuleBuilder {

// Start json-rpc server
pub async fn start_server(is_mock_storage: bool) -> Result<ServerHandle> {
match run_start_server(is_mock_storage).await {
Ok(server_handle) => Ok(server_handle),
Err(e) => match e.downcast::<GenesisError>() {
Ok(e) => {
log::error!("{:?}, please clean your data dir.", e);
std::process::exit(R_EXIT_CODE_NEED_HELP);
}
Err(e) => {
log::error!("{:?}, server start fail. ", e);
std::process::exit(R_EXIT_CODE_NEED_HELP);
}
},
}
}

// run json-rpc server
pub async fn run_start_server(is_mock_storage: bool) -> Result<ServerHandle> {
// We may call `start_server` multiple times in testing scenarios
// tracing_subscriber can only be inited once.
let _ = tracing_subscriber::fmt::try_init();
Expand Down
11 changes: 11 additions & 0 deletions crates/rooch-types/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) RoochNetwork
// SPDX-License-Identifier: Apache-2.0

use moveos_types::h256::H256;
use serde::{Deserialize, Serialize};
use std::io;
use thiserror::Error;
Expand Down Expand Up @@ -114,3 +115,13 @@ impl From<io::Error> for RoochError {
RoochError::IOError(e.to_string())
}
}

#[derive(Debug, Error, Eq, PartialEq)]
pub enum GenesisError {
#[error("Genesis version mismatch expect: {expect:?}, real: {real:?}.")]
GenesisVersionMismatch { expect: H256, real: H256 },
#[error("Genesis load fail {0}")]
GenesisLoadFailure(String),
#[error("Genesis block not exist in {0}.")]
GenesisNotExist(String),
}
51 changes: 43 additions & 8 deletions moveos/moveos-store/src/config_store/mod.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,63 @@
// Copyright (c) RoochNetwork
// SPDX-License-Identifier: Apache-2.0

use crate::CONFIG_PREFIX_NAME;
use crate::{CONFIG_GENESIS_PREFIX_NAME, CONFIG_STARTUP_INFO_PREFIX_NAME};
use anyhow::Result;
use moveos_types::h256::H256;
use moveos_types::startup_info::StartupInfo;
use raw_store::{derive_store, CodecKVStore};
use raw_store::{derive_store, CodecKVStore, StoreInstance};
use std::string::ToString;

pub const STARTUP_INFO_KEY: &str = "startup_info";
pub const GENESIS_KEY: &str = "genesis";

derive_store!(StartupInfoDBStore, String, StartupInfo, CONFIG_PREFIX_NAME);
derive_store!(
StartupInfoStore,
String,
StartupInfo,
CONFIG_STARTUP_INFO_PREFIX_NAME
);
derive_store!(GenesisStore, String, H256, CONFIG_GENESIS_PREFIX_NAME);

pub trait ConfigStore {
fn get_startup_info(&self) -> Result<Option<StartupInfo>>;

fn save_startup_info(&self, startup_info: StartupInfo) -> Result<()>;

fn get_genesis(&self) -> Result<Option<H256>>;

fn save_genesis(&self, genesis_hash: H256) -> Result<()>;
}

impl ConfigStore for StartupInfoDBStore {
fn get_startup_info(&self) -> Result<Option<StartupInfo>> {
self.kv_get(STARTUP_INFO_KEY.to_string())
#[derive(Clone)]
pub struct ConfigDBStore {
startup_store: StartupInfoStore,
genesis_store: GenesisStore,
}

impl ConfigDBStore {
pub fn new(instance: StoreInstance) -> Self {
ConfigDBStore {
startup_store: StartupInfoStore::new(instance.clone()),
genesis_store: GenesisStore::new(instance),
}
}

pub fn get_startup_info(&self) -> Result<Option<StartupInfo>> {
self.startup_store.kv_get(STARTUP_INFO_KEY.to_string())
}

pub fn save_startup_info(&self, startup_info: StartupInfo) -> Result<()> {
self.startup_store
.put_sync(STARTUP_INFO_KEY.to_string(), startup_info)
}

pub fn get_genesis(&self) -> Result<Option<H256>> {
self.genesis_store.kv_get(GENESIS_KEY.to_string())
}

fn save_startup_info(&self, startup_info: StartupInfo) -> Result<()> {
self.put_sync(STARTUP_INFO_KEY.to_string(), startup_info)
pub fn save_genesis(&self, genesis_hash: H256) -> Result<()> {
self.genesis_store
.put_sync(GENESIS_KEY.to_string(), genesis_hash)
}
}
22 changes: 16 additions & 6 deletions moveos/moveos-store/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::collections::BTreeMap;
use std::fmt::{Debug, Display, Formatter};
use std::sync::Arc;

use crate::config_store::{ConfigStore, StartupInfoDBStore};
use crate::config_store::{ConfigDBStore, ConfigStore};
use crate::event_store::{EventDBStore, EventStore};
use crate::state_store::statedb::StateDBStore;
use crate::state_store::NodeDBStore;
Expand Down Expand Up @@ -42,7 +42,8 @@ pub const STATE_NODE_PREFIX_NAME: ColumnFamilyName = "state_node";
pub const TRANSACTION_PREFIX_NAME: ColumnFamilyName = "transaction";
pub const EVENT_PREFIX_NAME: ColumnFamilyName = "event";
pub const EVENT_INDEX_PREFIX_NAME: ColumnFamilyName = "event_index";
pub const CONFIG_PREFIX_NAME: ColumnFamilyName = "config";
pub const CONFIG_STARTUP_INFO_PREFIX_NAME: ColumnFamilyName = "config_startup_info";
pub const CONFIG_GENESIS_PREFIX_NAME: ColumnFamilyName = "config_genesis";

///db store use prefix_name vec to init
/// Please note that adding a prefix needs to be added in vec simultaneously, remember!!
Expand All @@ -52,7 +53,8 @@ static VEC_PREFIX_NAME: Lazy<Vec<ColumnFamilyName>> = Lazy::new(|| {
TRANSACTION_PREFIX_NAME,
EVENT_PREFIX_NAME,
EVENT_INDEX_PREFIX_NAME,
CONFIG_PREFIX_NAME,
CONFIG_STARTUP_INFO_PREFIX_NAME,
CONFIG_GENESIS_PREFIX_NAME,
]
});

Expand All @@ -69,7 +71,7 @@ pub struct MoveOSDB {
pub node_store: NodeDBStore,
pub event_store: EventDBStore,
pub transaction_store: TransactionDBStore,
pub config_store: StartupInfoDBStore,
pub config_store: ConfigDBStore,
}

impl MoveOSDB {
Expand All @@ -95,7 +97,7 @@ impl MoveOSDB {
node_store: NodeDBStore::new(instance.clone()),
event_store: EventDBStore::new(instance.clone()),
transaction_store: TransactionDBStore::new(instance.clone()),
config_store: StartupInfoDBStore::new(instance),
config_store: ConfigDBStore::new(instance),
};
Ok(store)
}
Expand Down Expand Up @@ -140,7 +142,7 @@ impl MoveOSStore {
&self.moveosdb.node_store
}

pub fn get_config_store(&self) -> &StartupInfoDBStore {
pub fn get_config_store(&self) -> &ConfigDBStore {
&self.moveosdb.config_store
}

Expand Down Expand Up @@ -242,6 +244,14 @@ impl ConfigStore for MoveOSStore {
fn save_startup_info(&self, startup_info: StartupInfo) -> Result<()> {
self.get_config_store().save_startup_info(startup_info)
}

fn get_genesis(&self) -> Result<Option<H256>> {
self.get_config_store().get_genesis()
}

fn save_genesis(&self, genesis_hash: H256) -> Result<()> {
self.get_config_store().save_genesis(genesis_hash)
}
}

/// Moveos store define
Expand Down
14 changes: 12 additions & 2 deletions moveos/moveos/src/moveos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use move_core_types::{
};
use move_vm_runtime::config::VMConfig;
use move_vm_runtime::native_functions::NativeFunction;
use moveos_store::config_store::ConfigStore;
use moveos_store::event_store::EventDBStore;
use moveos_store::state_store::statedb::StateDBStore;
use moveos_store::transaction_store::TransactionDBStore;
Expand All @@ -22,7 +21,7 @@ use moveos_types::startup_info::StartupInfo;
use moveos_types::state_resolver::MoveOSResolverProxy;
use moveos_types::transaction::{MoveOSTransaction, TransactionOutput, VerifiedMoveOSTransaction};
use moveos_types::tx_context::TxContext;
use moveos_types::{h256::H256, transaction::FunctionCall};
use moveos_types::{h256, h256::H256, transaction::FunctionCall};

pub struct MoveOSConfig {
pub vm_config: VMConfig,
Expand Down Expand Up @@ -81,9 +80,20 @@ impl MoveOS {
"genesis already initialized"
);

let genesis_hash = h256::sha3_256_of(bcs::to_bytes(&genesis_txs)?.as_slice());
for genesis_tx in genesis_txs {
self.verify_and_execute_genesis_tx(genesis_tx)?;
}

self.db
.0
.get_config_store()
.save_genesis(genesis_hash)
.map_err(|e| {
PartialVMError::new(StatusCode::STORAGE_ERROR)
.with_message(e.to_string())
.finish(Location::Undefined)
})?;
//TODO return the state root genesis TransactionExecutionInfo
Ok(())
}
Expand Down

0 comments on commit bd9ad8e

Please sign in to comment.