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:
David Emett
2023-10-09 15:56:30 +02:00
committed by GitHub
parent 1dc935c715
commit a808a3a091
52 changed files with 3010 additions and 109 deletions
+50 -16
View File
@@ -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,