Correct Serai header on genesis

Includes a couple misc fixes for the RPC as well.
This commit is contained in:
Luke Parker
2025-11-14 07:22:59 -05:00
parent 6ff0ef7aa6
commit cde0f753c2
11 changed files with 148 additions and 56 deletions

View File

@@ -62,6 +62,7 @@ jsonrpsee = { version = "0.24", features = ["server"] }
sc-transaction-pool = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "71fa60b900c8ad068f1b9ce8100508506377fbf5" }
sc-transaction-pool-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "71fa60b900c8ad068f1b9ce8100508506377fbf5" }
sc-basic-authorship = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "71fa60b900c8ad068f1b9ce8100508506377fbf5" }
sc-client-db = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "71fa60b900c8ad068f1b9ce8100508506377fbf5" }
sc-executor = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "71fa60b900c8ad068f1b9ce8100508506377fbf5" }
sc-service = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "71fa60b900c8ad068f1b9ce8100508506377fbf5" }
sc-client-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "71fa60b900c8ad068f1b9ce8100508506377fbf5" }

View File

@@ -1,7 +1,15 @@
use core::marker::PhantomData;
use std::sync::Arc;
use sp_core::Pair as PairTrait;
use sp_core::{Decode, storage::Storage, Pair as PairTrait};
use sp_runtime::{
traits::{Block as _, Header as _},
BuildStorage,
};
use sc_client_db::Backend;
use sc_executor::RuntimeVersionOf;
use sc_chain_spec::{BuildGenesisBlock, GenesisBlockBuilder, ChainSpec as ChainSpecTrait};
use sc_client_api::BlockImportOperation;
use sc_service::ChainType;
use rand_core::OsRng;
@@ -201,3 +209,45 @@ pub fn bootnode_multiaddrs(id: &str) -> Vec<libp2p::Multiaddr> {
_ => panic!("unrecognized network ID"),
}
}
struct GenesisBlock<Executor>(
GenesisBlockBuilder<Block, Backend<Block>, Executor>,
sp_runtime::Digest,
);
impl<Executor: RuntimeVersionOf> BuildGenesisBlock<Block> for GenesisBlock<Executor> {
type BlockImportOperation = sc_client_db::BlockImportOperation<Block>;
fn build_genesis_block(self) -> sp_blockchain::Result<(Block, Self::BlockImportOperation)> {
let (genesis_block, op) = self.0.build_genesis_block()?;
let mut header = genesis_block.header().clone();
*header.digest_mut() = self.1;
let genesis_block = Block::new(header, genesis_block.extrinsics().to_vec());
Ok((genesis_block, op))
}
}
pub(super) fn genesis_block(
chain_spec: &dyn ChainSpecTrait,
backend: Arc<Backend<Block>>,
executor: impl RuntimeVersionOf,
) -> Result<
impl BuildGenesisBlock<Block, BlockImportOperation = sc_client_db::BlockImportOperation<Block>>,
sc_service::error::Error,
> {
let storage = chain_spec.as_storage_builder().build_storage()?;
let digest = {
let digest_key = [sp_core::twox_128(b"System"), sp_core::twox_128(b"Digest")].concat();
sp_runtime::Digest::decode(
&mut storage.top.get(&digest_key).expect("System Digest not set").as_slice(),
)
.expect("failed to decode System Digest")
};
let commit_genesis_state = true;
Ok(GenesisBlock(
GenesisBlockBuilder::new_with_storage(storage, commit_genesis_state, backend, executor)?,
digest,
))
}

View File

@@ -1,4 +1,4 @@
use std::{sync::Arc, ops::Deref, collections::HashSet};
use std::{sync::Arc, ops::Deref, convert::AsRef, collections::HashSet};
use rand_core::{RngCore, OsRng};
@@ -17,6 +17,16 @@ use jsonrpsee::RpcModule;
use super::utils::{Error, block_hash};
fn network_from_str(network: impl AsRef<str>) -> Result<NetworkId, Error> {
Ok(match network.as_ref().to_lowercase().as_str() {
"serai" => NetworkId::Serai,
"bitcoin" => NetworkId::External(ExternalNetworkId::Bitcoin),
"ethereum" => NetworkId::External(ExternalNetworkId::Ethereum),
"monero" => NetworkId::External(ExternalNetworkId::Monero),
_ => Err(Error::InvalidRequest("unrecognized network requested"))?,
})
}
pub(super) fn network(params: &jsonrpsee::types::params::Params) -> Result<NetworkId, Error> {
#[derive(sp_core::serde::Deserialize)]
#[serde(crate = "sp_core::serde")]
@@ -28,13 +38,7 @@ pub(super) fn network(params: &jsonrpsee::types::params::Params) -> Result<Netwo
Err(Error::InvalidRequest(r#"missing `string` "network" field"#))?
};
Ok(match network.network.to_lowercase().as_str() {
"serai" => NetworkId::Serai,
"bitcoin" => NetworkId::External(ExternalNetworkId::Bitcoin),
"ethereum" => NetworkId::External(ExternalNetworkId::Ethereum),
"monero" => NetworkId::External(ExternalNetworkId::Monero),
_ => Err(Error::InvalidRequest("unrecognized network requested"))?,
})
network_from_str(network.network)
}
pub(super) fn set(params: &jsonrpsee::types::params::Params) -> Result<ValidatorSet, Error> {
@@ -49,15 +53,7 @@ pub(super) fn set(params: &jsonrpsee::types::params::Params) -> Result<Validator
Err(Error::InvalidRequest(r#"missing `object` "set" field"#))?
};
let network = match set.network.to_lowercase().as_str() {
"serai" => NetworkId::Serai,
"bitcoin" => NetworkId::External(ExternalNetworkId::Bitcoin),
"ethereum" => NetworkId::External(ExternalNetworkId::Ethereum),
"monero" => NetworkId::External(ExternalNetworkId::Monero),
_ => Err(Error::InvalidRequest("unrecognized network requested"))?,
};
Ok(ValidatorSet { network, session: Session(set.session) })
Ok(ValidatorSet { network: network_from_str(set.network)?, session: Session(set.session) })
}
pub(crate) fn module<

View File

@@ -95,12 +95,19 @@ pub fn new_partial(
config.executor.runtime_cache_size,
);
let (client, backend, keystore_container, task_manager) =
sc_service::new_full_parts::<Block, RuntimeApi, _>(
let (client, backend, keystore_container, task_manager) = {
let telemetry = telemetry.as_ref().map(|(_, telemetry)| telemetry.handle());
let backend = sc_service::new_db_backend(config.db_config())?;
sc_service::new_full_parts_with_genesis_builder::<Block, RuntimeApi, _, _>(
config,
telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),
executor,
)?;
telemetry,
executor.clone(),
backend.clone(),
super::chain_spec::genesis_block(&*config.chain_spec, backend, executor)?,
false,
)?
};
let client = Arc::new(client);
let keystore: Arc<dyn sp_keystore::Keystore> =