mirror of
https://github.com/akula-bft/akula.git
synced 2026-04-19 03:00:13 -04:00
Custom chainspec support
This commit is contained in:
44
bin/akula.rs
44
bin/akula.rs
@@ -9,7 +9,7 @@ use akula::{
|
||||
models::*,
|
||||
rpc::eth::EthApiServerImpl,
|
||||
sentry_connector::{
|
||||
sentry_client_connector::SentryClientConnectorImpl,
|
||||
chain_config::ChainConfig, sentry_client_connector::SentryClientConnectorImpl,
|
||||
sentry_client_reactor::SentryClientReactor,
|
||||
},
|
||||
stagedsync::{self, stage::*, stages::*, util::*},
|
||||
@@ -24,6 +24,7 @@ use fastrlp::*;
|
||||
use jsonrpsee::http_server::HttpServerBuilder;
|
||||
use rayon::prelude::*;
|
||||
use std::{
|
||||
fs::File,
|
||||
future::pending,
|
||||
net::SocketAddr,
|
||||
panic,
|
||||
@@ -46,13 +47,13 @@ pub struct Opt {
|
||||
#[clap(long = "datadir", help = "Database directory path", default_value_t)]
|
||||
pub data_dir: AkulaDataDir,
|
||||
|
||||
/// Name of the testnet to join
|
||||
#[clap(
|
||||
long = "chain",
|
||||
help = "Name of the testnet to join",
|
||||
default_value = "mainnet"
|
||||
)]
|
||||
pub chain_name: String,
|
||||
/// Name of the network to join
|
||||
#[clap(long)]
|
||||
pub chain: Option<String>,
|
||||
|
||||
/// Chain spec file to use
|
||||
#[clap(long)]
|
||||
pub chain_spec_file: Option<PathBuf>,
|
||||
|
||||
/// Sentry GRPC service URL
|
||||
#[clap(
|
||||
@@ -626,8 +627,15 @@ fn main() -> anyhow::Result<()> {
|
||||
rt.block_on(async move {
|
||||
info!("Starting Akula ({})", version_string());
|
||||
|
||||
let chains_config = akula::sentry_connector::chain_config::ChainsConfig::new()?;
|
||||
let chain_config = chains_config.get(&opt.chain_name)?;
|
||||
let chain_config = if let Some(chain) = opt.chain {
|
||||
let chains_config = akula::sentry_connector::chain_config::ChainsConfig::new()?;
|
||||
let chain_config = chains_config.get(&chain)?;
|
||||
Some(chain_config.chain_spec().clone())
|
||||
} else if let Some(chain_path) = opt.chain_spec_file {
|
||||
Some(ron::de::from_reader(File::open(chain_path)?)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// database setup
|
||||
let erigon_db = if let Some(erigon_data_dir) = opt.erigon_data_dir {
|
||||
@@ -652,18 +660,20 @@ fn main() -> anyhow::Result<()> {
|
||||
.context("failed to create ETL temp dir")?,
|
||||
);
|
||||
let db = Arc::new(akula::kv::new_database(&akula_chain_data_dir)?);
|
||||
{
|
||||
let chainspec = {
|
||||
let span = span!(Level::INFO, "", " Genesis initialization ");
|
||||
let _g = span.enter();
|
||||
let txn = db.begin_mutable()?;
|
||||
if akula::genesis::initialize_genesis(
|
||||
&txn,
|
||||
&*etl_temp_dir,
|
||||
chain_config.chain_spec().clone(),
|
||||
)? {
|
||||
let (chainspec, initialized) =
|
||||
akula::genesis::initialize_genesis(&txn, &*etl_temp_dir, chain_config)?;
|
||||
if initialized {
|
||||
txn.commit()?;
|
||||
}
|
||||
}
|
||||
|
||||
chainspec
|
||||
};
|
||||
|
||||
let chain_config = ChainConfig::new(chainspec);
|
||||
|
||||
if let Some(listen_address) = opt.rpc_listen_address {
|
||||
let db = db.clone();
|
||||
|
||||
@@ -13,7 +13,7 @@ pub struct ChainConfig {
|
||||
}
|
||||
|
||||
impl ChainConfig {
|
||||
fn new(chain_spec: ChainSpec) -> Self {
|
||||
pub fn new(chain_spec: ChainSpec) -> Self {
|
||||
let genesis = GenesisState::new(chain_spec.clone());
|
||||
let genesis_header = genesis.header(&genesis.initial_state());
|
||||
let genesis_block_hash = genesis_header.hash();
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
use crate::{
|
||||
kv::{mdbx::*, tables},
|
||||
models::*,
|
||||
res::chainspec::MAINNET,
|
||||
state::*,
|
||||
};
|
||||
use anyhow::format_err;
|
||||
use tempfile::TempDir;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -62,15 +64,24 @@ impl GenesisState {
|
||||
pub fn initialize_genesis<'db, E>(
|
||||
txn: &MdbxTransaction<'db, RW, E>,
|
||||
etl_temp_dir: &TempDir,
|
||||
chainspec: ChainSpec,
|
||||
) -> anyhow::Result<bool>
|
||||
chainspec: Option<ChainSpec>,
|
||||
) -> anyhow::Result<(ChainSpec, bool)>
|
||||
where
|
||||
E: EnvironmentKind,
|
||||
{
|
||||
if txn.get(tables::Config, ())?.is_some() {
|
||||
return Ok(false);
|
||||
if let Some(existing_chainspec) = txn.get(tables::Config, ())? {
|
||||
if let Some(chainspec) = chainspec {
|
||||
if chainspec != existing_chainspec {
|
||||
return Err(format_err!(
|
||||
"Genesis initialized, but chainspec does not match one in database"
|
||||
));
|
||||
}
|
||||
}
|
||||
return Ok((existing_chainspec, false));
|
||||
}
|
||||
|
||||
let chainspec = chainspec.unwrap_or_else(|| MAINNET.clone());
|
||||
|
||||
let genesis = chainspec.genesis.number;
|
||||
let mut state_buffer = Buffer::new(txn, None);
|
||||
state_buffer.begin_block(genesis);
|
||||
@@ -139,9 +150,9 @@ where
|
||||
|
||||
txn.set(tables::LastHeader, (), block_hash)?;
|
||||
|
||||
txn.set(tables::Config, (), chainspec)?;
|
||||
txn.set(tables::Config, (), chainspec.clone())?;
|
||||
|
||||
Ok(true)
|
||||
Ok((chainspec, true))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -178,9 +189,7 @@ mod tests {
|
||||
let tx = db.begin_mutable().unwrap();
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
assert!(
|
||||
initialize_genesis(&tx, &temp_dir, crate::res::chainspec::MAINNET.clone()).unwrap()
|
||||
);
|
||||
assert!(initialize_genesis(&tx, &temp_dir, None).unwrap().1);
|
||||
|
||||
let genesis_hash = tx.get(tables::CanonicalHeader, 0.into()).unwrap().unwrap();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user