mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 12:17:58 +00:00
Mixnet integration (#1346)
See #1345, <https://github.com/paritytech/substrate/pull/14207>. This adds all the necessary mixnet components, and puts them together in the "kitchen-sink" node/runtime. The components added are: - A pallet (`frame/mixnet`). This is responsible for determining the current mixnet session and phase, and the mixnodes to use in each session. It provides a function that validators can call to register a mixnode for the next session. The logic of this pallet is very similar to that of the `im-online` pallet. - A service (`client/mixnet`). This implements the core mixnet logic, building on the `mixnet` crate. The service communicates with other nodes using notifications sent over the "mixnet" protocol. - An RPC interface. This currently only supports sending transactions over the mixnet. --------- Co-authored-by: David Emett <dave@sp4m.net> Co-authored-by: Javier Viola <javier@parity.io>
This commit is contained in:
@@ -33,6 +33,7 @@ use serde::{Deserialize, Serialize};
|
||||
use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
|
||||
use sp_consensus_babe::AuthorityId as BabeId;
|
||||
use sp_core::{crypto::UncheckedInto, sr25519, Pair, Public};
|
||||
use sp_mixnet::types::AuthorityId as MixnetId;
|
||||
use sp_runtime::{
|
||||
traits::{IdentifyAccount, Verify},
|
||||
Perbill,
|
||||
@@ -72,8 +73,9 @@ fn session_keys(
|
||||
babe: BabeId,
|
||||
im_online: ImOnlineId,
|
||||
authority_discovery: AuthorityDiscoveryId,
|
||||
mixnet: MixnetId,
|
||||
) -> SessionKeys {
|
||||
SessionKeys { grandpa, babe, im_online, authority_discovery }
|
||||
SessionKeys { grandpa, babe, im_online, authority_discovery, mixnet }
|
||||
}
|
||||
|
||||
fn staging_testnet_config_genesis() -> RuntimeGenesisConfig {
|
||||
@@ -93,6 +95,7 @@ fn staging_testnet_config_genesis() -> RuntimeGenesisConfig {
|
||||
BabeId,
|
||||
ImOnlineId,
|
||||
AuthorityDiscoveryId,
|
||||
MixnetId,
|
||||
)> = vec![
|
||||
(
|
||||
// 5Fbsd6WXDGiLTxunqeK5BATNiocfCqu9bS1yArVjCgeBLkVy
|
||||
@@ -111,6 +114,9 @@ fn staging_testnet_config_genesis() -> RuntimeGenesisConfig {
|
||||
// 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8
|
||||
array_bytes::hex2array_unchecked("6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106")
|
||||
.unchecked_into(),
|
||||
// 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8
|
||||
array_bytes::hex2array_unchecked("6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106")
|
||||
.unchecked_into(),
|
||||
),
|
||||
(
|
||||
// 5ERawXCzCWkjVq3xz1W5KGNtVx2VdefvZ62Bw1FEuZW4Vny2
|
||||
@@ -129,6 +135,9 @@ fn staging_testnet_config_genesis() -> RuntimeGenesisConfig {
|
||||
// 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ
|
||||
array_bytes::hex2array_unchecked("482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e")
|
||||
.unchecked_into(),
|
||||
// 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ
|
||||
array_bytes::hex2array_unchecked("482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e")
|
||||
.unchecked_into(),
|
||||
),
|
||||
(
|
||||
// 5DyVtKWPidondEu8iHZgi6Ffv9yrJJ1NDNLom3X9cTDi98qp
|
||||
@@ -147,6 +156,9 @@ fn staging_testnet_config_genesis() -> RuntimeGenesisConfig {
|
||||
// 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH
|
||||
array_bytes::hex2array_unchecked("482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a")
|
||||
.unchecked_into(),
|
||||
// 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH
|
||||
array_bytes::hex2array_unchecked("482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a")
|
||||
.unchecked_into(),
|
||||
),
|
||||
(
|
||||
// 5HYZnKWe5FVZQ33ZRJK1rG3WaLMztxWrrNDb1JRwaHHVWyP9
|
||||
@@ -165,6 +177,9 @@ fn staging_testnet_config_genesis() -> RuntimeGenesisConfig {
|
||||
// 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x
|
||||
array_bytes::hex2array_unchecked("00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378")
|
||||
.unchecked_into(),
|
||||
// 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x
|
||||
array_bytes::hex2array_unchecked("00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378")
|
||||
.unchecked_into(),
|
||||
),
|
||||
];
|
||||
|
||||
@@ -217,7 +232,7 @@ where
|
||||
/// Helper function to generate stash, controller and session key from seed.
|
||||
pub fn authority_keys_from_seed(
|
||||
seed: &str,
|
||||
) -> (AccountId, AccountId, GrandpaId, BabeId, ImOnlineId, AuthorityDiscoveryId) {
|
||||
) -> (AccountId, AccountId, GrandpaId, BabeId, ImOnlineId, AuthorityDiscoveryId, MixnetId) {
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>(&format!("{}//stash", seed)),
|
||||
get_account_id_from_seed::<sr25519::Public>(seed),
|
||||
@@ -225,6 +240,7 @@ pub fn authority_keys_from_seed(
|
||||
get_from_seed::<BabeId>(seed),
|
||||
get_from_seed::<ImOnlineId>(seed),
|
||||
get_from_seed::<AuthorityDiscoveryId>(seed),
|
||||
get_from_seed::<MixnetId>(seed),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -237,6 +253,7 @@ pub fn testnet_genesis(
|
||||
BabeId,
|
||||
ImOnlineId,
|
||||
AuthorityDiscoveryId,
|
||||
MixnetId,
|
||||
)>,
|
||||
initial_nominators: Vec<AccountId>,
|
||||
root_key: AccountId,
|
||||
@@ -306,7 +323,13 @@ pub fn testnet_genesis(
|
||||
(
|
||||
x.0.clone(),
|
||||
x.0.clone(),
|
||||
session_keys(x.2.clone(), x.3.clone(), x.4.clone(), x.5.clone()),
|
||||
session_keys(
|
||||
x.2.clone(),
|
||||
x.3.clone(),
|
||||
x.4.clone(),
|
||||
x.5.clone(),
|
||||
x.6.clone(),
|
||||
),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
@@ -367,6 +390,7 @@ pub fn testnet_genesis(
|
||||
..Default::default()
|
||||
},
|
||||
glutton: Default::default(),
|
||||
mixnet: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,7 +499,7 @@ pub(crate) mod tests {
|
||||
|
||||
sc_service_test::connectivity(integration_test_config_with_two_authorities(), |config| {
|
||||
let NewFullBase { task_manager, client, network, sync, transaction_pool, .. } =
|
||||
new_full_base(config, false, |_, _| ())?;
|
||||
new_full_base(config, None, false, |_, _| ())?;
|
||||
Ok(sc_service_test::TestNetComponents::new(
|
||||
task_manager,
|
||||
client,
|
||||
|
||||
@@ -27,6 +27,10 @@ pub struct Cli {
|
||||
#[clap(flatten)]
|
||||
pub run: sc_cli::RunCmd,
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[clap(flatten)]
|
||||
pub mixnet_params: sc_cli::MixnetParams,
|
||||
|
||||
/// Disable automatic hardware benchmarks.
|
||||
///
|
||||
/// By default these benchmarks are automatically ran at startup and measure
|
||||
|
||||
@@ -111,7 +111,7 @@ pub fn run() -> Result<()> {
|
||||
},
|
||||
BenchmarkCmd::Block(cmd) => {
|
||||
// ensure that we keep the task manager alive
|
||||
let partial = new_partial(&config)?;
|
||||
let partial = new_partial(&config, None)?;
|
||||
cmd.run(partial.client)
|
||||
},
|
||||
#[cfg(not(feature = "runtime-benchmarks"))]
|
||||
@@ -122,7 +122,7 @@ pub fn run() -> Result<()> {
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
BenchmarkCmd::Storage(cmd) => {
|
||||
// ensure that we keep the task manager alive
|
||||
let partial = new_partial(&config)?;
|
||||
let partial = new_partial(&config, None)?;
|
||||
let db = partial.backend.expose_db();
|
||||
let storage = partial.backend.expose_storage();
|
||||
|
||||
@@ -130,7 +130,7 @@ pub fn run() -> Result<()> {
|
||||
},
|
||||
BenchmarkCmd::Overhead(cmd) => {
|
||||
// ensure that we keep the task manager alive
|
||||
let partial = new_partial(&config)?;
|
||||
let partial = new_partial(&config, None)?;
|
||||
let ext_builder = RemarkBuilder::new(partial.client.clone());
|
||||
|
||||
cmd.run(
|
||||
@@ -143,7 +143,7 @@ pub fn run() -> Result<()> {
|
||||
},
|
||||
BenchmarkCmd::Extrinsic(cmd) => {
|
||||
// ensure that we keep the task manager alive
|
||||
let partial = service::new_partial(&config)?;
|
||||
let partial = service::new_partial(&config, None)?;
|
||||
// Register the *Remark* and *TKA* builders.
|
||||
let ext_factory = ExtrinsicFactory(vec![
|
||||
Box::new(RemarkBuilder::new(partial.client.clone())),
|
||||
@@ -178,21 +178,21 @@ pub fn run() -> Result<()> {
|
||||
let runner = cli.create_runner(cmd)?;
|
||||
runner.async_run(|config| {
|
||||
let PartialComponents { client, task_manager, import_queue, .. } =
|
||||
new_partial(&config)?;
|
||||
new_partial(&config, None)?;
|
||||
Ok((cmd.run(client, import_queue), task_manager))
|
||||
})
|
||||
},
|
||||
Some(Subcommand::ExportBlocks(cmd)) => {
|
||||
let runner = cli.create_runner(cmd)?;
|
||||
runner.async_run(|config| {
|
||||
let PartialComponents { client, task_manager, .. } = new_partial(&config)?;
|
||||
let PartialComponents { client, task_manager, .. } = new_partial(&config, None)?;
|
||||
Ok((cmd.run(client, config.database), task_manager))
|
||||
})
|
||||
},
|
||||
Some(Subcommand::ExportState(cmd)) => {
|
||||
let runner = cli.create_runner(cmd)?;
|
||||
runner.async_run(|config| {
|
||||
let PartialComponents { client, task_manager, .. } = new_partial(&config)?;
|
||||
let PartialComponents { client, task_manager, .. } = new_partial(&config, None)?;
|
||||
Ok((cmd.run(client, config.chain_spec), task_manager))
|
||||
})
|
||||
},
|
||||
@@ -200,7 +200,7 @@ pub fn run() -> Result<()> {
|
||||
let runner = cli.create_runner(cmd)?;
|
||||
runner.async_run(|config| {
|
||||
let PartialComponents { client, task_manager, import_queue, .. } =
|
||||
new_partial(&config)?;
|
||||
new_partial(&config, None)?;
|
||||
Ok((cmd.run(client, import_queue), task_manager))
|
||||
})
|
||||
},
|
||||
@@ -211,7 +211,8 @@ pub fn run() -> Result<()> {
|
||||
Some(Subcommand::Revert(cmd)) => {
|
||||
let runner = cli.create_runner(cmd)?;
|
||||
runner.async_run(|config| {
|
||||
let PartialComponents { client, task_manager, backend, .. } = new_partial(&config)?;
|
||||
let PartialComponents { client, task_manager, backend, .. } =
|
||||
new_partial(&config, None)?;
|
||||
let aux_revert = Box::new(|client: Arc<FullClient>, backend, blocks| {
|
||||
sc_consensus_babe::revert(client.clone(), backend, blocks)?;
|
||||
grandpa::revert(client, blocks)?;
|
||||
|
||||
@@ -134,6 +134,7 @@ pub fn create_extrinsic(
|
||||
/// Creates a new partial node.
|
||||
pub fn new_partial(
|
||||
config: &Configuration,
|
||||
mixnet_config: Option<&sc_mixnet::Config>,
|
||||
) -> Result<
|
||||
sc_service::PartialComponents<
|
||||
FullClient,
|
||||
@@ -154,6 +155,7 @@ pub fn new_partial(
|
||||
grandpa::SharedVoterState,
|
||||
Option<Telemetry>,
|
||||
Arc<StatementStore>,
|
||||
Option<sc_mixnet::ApiBackend>,
|
||||
),
|
||||
>,
|
||||
ServiceError,
|
||||
@@ -246,6 +248,8 @@ pub fn new_partial(
|
||||
)
|
||||
.map_err(|e| ServiceError::Other(format!("Statement store error: {:?}", e)))?;
|
||||
|
||||
let (mixnet_api, mixnet_api_backend) = mixnet_config.map(sc_mixnet::Api::new).unzip();
|
||||
|
||||
let (rpc_extensions_builder, rpc_setup) = {
|
||||
let (_, grandpa_link, _) = &import_setup;
|
||||
|
||||
@@ -287,6 +291,7 @@ pub fn new_partial(
|
||||
},
|
||||
statement_store: rpc_statement_store.clone(),
|
||||
backend: rpc_backend.clone(),
|
||||
mixnet_api: mixnet_api.as_ref().cloned(),
|
||||
};
|
||||
|
||||
node_rpc::create_full(deps).map_err(Into::into)
|
||||
@@ -303,7 +308,14 @@ pub fn new_partial(
|
||||
select_chain,
|
||||
import_queue,
|
||||
transaction_pool,
|
||||
other: (rpc_extensions_builder, import_setup, rpc_setup, telemetry, statement_store),
|
||||
other: (
|
||||
rpc_extensions_builder,
|
||||
import_setup,
|
||||
rpc_setup,
|
||||
telemetry,
|
||||
statement_store,
|
||||
mixnet_api_backend,
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -326,6 +338,7 @@ pub struct NewFullBase {
|
||||
/// Creates a full service from the configuration.
|
||||
pub fn new_full_base(
|
||||
config: Configuration,
|
||||
mixnet_config: Option<sc_mixnet::Config>,
|
||||
disable_hardware_benchmarks: bool,
|
||||
with_startup_data: impl FnOnce(
|
||||
&sc_consensus_babe::BabeBlockImport<Block, FullClient, FullGrandpaBlockImport>,
|
||||
@@ -347,31 +360,36 @@ pub fn new_full_base(
|
||||
keystore_container,
|
||||
select_chain,
|
||||
transaction_pool,
|
||||
other: (rpc_builder, import_setup, rpc_setup, mut telemetry, statement_store),
|
||||
} = new_partial(&config)?;
|
||||
other:
|
||||
(rpc_builder, import_setup, rpc_setup, mut telemetry, statement_store, mixnet_api_backend),
|
||||
} = new_partial(&config, mixnet_config.as_ref())?;
|
||||
|
||||
let shared_voter_state = rpc_setup;
|
||||
let auth_disc_publish_non_global_ips = config.network.allow_non_globals_in_dht;
|
||||
let mut net_config = sc_network::config::FullNetworkConfiguration::new(&config.network);
|
||||
|
||||
let grandpa_protocol_name = grandpa::protocol_standard_name(
|
||||
&client.block_hash(0).ok().flatten().expect("Genesis block exists; qed"),
|
||||
&config.chain_spec,
|
||||
);
|
||||
let genesis_hash = client.block_hash(0).ok().flatten().expect("Genesis block exists; qed");
|
||||
|
||||
let grandpa_protocol_name = grandpa::protocol_standard_name(&genesis_hash, &config.chain_spec);
|
||||
net_config.add_notification_protocol(grandpa::grandpa_peers_set_config(
|
||||
grandpa_protocol_name.clone(),
|
||||
));
|
||||
|
||||
let statement_handler_proto = sc_network_statement::StatementHandlerPrototype::new(
|
||||
client
|
||||
.block_hash(0u32.into())
|
||||
.ok()
|
||||
.flatten()
|
||||
.expect("Genesis block exists; qed"),
|
||||
genesis_hash,
|
||||
config.chain_spec.fork_id(),
|
||||
);
|
||||
net_config.add_notification_protocol(statement_handler_proto.set_config());
|
||||
|
||||
let mixnet_protocol_name =
|
||||
sc_mixnet::protocol_name(genesis_hash.as_ref(), config.chain_spec.fork_id());
|
||||
if let Some(mixnet_config) = &mixnet_config {
|
||||
net_config.add_notification_protocol(sc_mixnet::peers_set_config(
|
||||
mixnet_protocol_name.clone(),
|
||||
mixnet_config,
|
||||
));
|
||||
}
|
||||
|
||||
let warp_sync = Arc::new(grandpa::warp_proof::NetworkProvider::new(
|
||||
backend.clone(),
|
||||
import_setup.1.shared_authority_set().clone(),
|
||||
@@ -391,6 +409,20 @@ pub fn new_full_base(
|
||||
block_relay: None,
|
||||
})?;
|
||||
|
||||
if let Some(mixnet_config) = mixnet_config {
|
||||
let mixnet = sc_mixnet::run(
|
||||
mixnet_config,
|
||||
mixnet_api_backend.expect("Mixnet API backend created if mixnet enabled"),
|
||||
client.clone(),
|
||||
sync_service.clone(),
|
||||
network.clone(),
|
||||
mixnet_protocol_name,
|
||||
transaction_pool.clone(),
|
||||
Some(keystore_container.keystore()),
|
||||
);
|
||||
task_manager.spawn_handle().spawn("mixnet", None, mixnet);
|
||||
}
|
||||
|
||||
let role = config.role.clone();
|
||||
let force_authoring = config.force_authoring;
|
||||
let backoff_authoring_blocks =
|
||||
@@ -546,7 +578,7 @@ pub fn new_full_base(
|
||||
// and vote data availability than the observer. The observer has not
|
||||
// been tested extensively yet and having most nodes in a network run it
|
||||
// could lead to finality stalls.
|
||||
let grandpa_config = grandpa::GrandpaParams {
|
||||
let grandpa_params = grandpa::GrandpaParams {
|
||||
config: grandpa_config,
|
||||
link: grandpa_link,
|
||||
network: network.clone(),
|
||||
@@ -563,7 +595,7 @@ pub fn new_full_base(
|
||||
task_manager.spawn_essential_handle().spawn_blocking(
|
||||
"grandpa-voter",
|
||||
None,
|
||||
grandpa::run_grandpa_voter(grandpa_config)?,
|
||||
grandpa::run_grandpa_voter(grandpa_params)?,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -623,8 +655,9 @@ pub fn new_full_base(
|
||||
|
||||
/// Builds a new service for a full client.
|
||||
pub fn new_full(config: Configuration, cli: Cli) -> Result<TaskManager, ServiceError> {
|
||||
let mixnet_config = cli.mixnet_params.config(config.role.is_authority());
|
||||
let database_source = config.database.clone();
|
||||
let task_manager = new_full_base(config, cli.no_hardware_benchmarks, |_, _| ())
|
||||
let task_manager = new_full_base(config, mixnet_config, cli.no_hardware_benchmarks, |_, _| ())
|
||||
.map(|NewFullBase { task_manager, .. }| task_manager)?;
|
||||
|
||||
sc_storage_monitor::StorageMonitorService::try_spawn(
|
||||
@@ -702,6 +735,7 @@ mod tests {
|
||||
let NewFullBase { task_manager, client, network, sync, transaction_pool, .. } =
|
||||
new_full_base(
|
||||
config,
|
||||
None,
|
||||
false,
|
||||
|block_import: &sc_consensus_babe::BabeBlockImport<Block, _, _>,
|
||||
babe_link: &sc_consensus_babe::BabeLink<Block>| {
|
||||
@@ -876,7 +910,7 @@ mod tests {
|
||||
crate::chain_spec::tests::integration_test_config_with_two_authorities(),
|
||||
|config| {
|
||||
let NewFullBase { task_manager, client, network, sync, transaction_pool, .. } =
|
||||
new_full_base(config, false, |_, _| ())?;
|
||||
new_full_base(config, None, false, |_, _| ())?;
|
||||
Ok(sc_service_test::TestNetComponents::new(
|
||||
task_manager,
|
||||
client,
|
||||
|
||||
Reference in New Issue
Block a user