When writing tests for client module I'm having troubles instantiating gadget for the client with the error:
the trait
module_primitives::ModuleApi<sp_runtime::generic::Block<sp_runtime::generic::Header<u64, BlakeTwo256>, sc_network_test::Extrinsic>>
is not implemented forRuntimeApiImpl<sp_runtime::generic::Block<sp_runtime::generic::Header<u64, BlakeTwo256>, sc_network_test::Extrinsic>, substrate_test_runtime_client::client::Client<substrate_test_runtime_client::sc_client_db::Backend<sp_runtime::generic::Block<sp_runtime::generic::Header<u64, BlakeTwo256>, sc_network_test::Extrinsic>>, LocalCallExecutor<sp_runtime::generic::Block<sp_runtime::generic::Header<u64, BlakeTwo256>, sc_network_test::Extrinsic>, substrate_test_runtime_client::sc_client_db::Backend<sp_runtime::generic::Block<sp_runtime::generic::Header<u64, BlakeTwo256>, sc_network_test::Extrinsic>>, NativeElseWasmExecutor<LocalExecutorDispatch>>, sp_runtime::generic::Block<sp_runtime::generic::Header<u64, BlakeTwo256>, sc_network_test::Extrinsic>, substrate_test_runtime_client::substrate_test_runtime::RuntimeApi>>
Implementation:
pub(crate) type ModuleTestParams = ModuleParams<PeersFullClient, Backend>;
pub(crate) type PeerData = Option<ModuleTestParams>;
pub(crate) type ModulePeer = Peer<PeerData, PeersClient>;
pub(crate) struct ModuleTestNet {
peers: Vec<ModulePeer>,
}
impl ModuleTestNet {
pub(crate) fn new(n_authority: usize, n_full: usize) -> Self {
let mut net = ModuleTestNet { peers: Vec::with_capacity(n_authority + n_full) };
for _ in 0..n_authority {
net.add_authority_peer();
}
for _ in 0..n_full {
net.add_full_peer();
}
net
}
pub(crate) fn add_authority_peer(&mut self) {
self.add_full_peer_with_config(FullPeerConfig {
notifications_protocols: vec!["module/1".into()],
is_authority: true,
..Default::default()
})
}
pub(crate) fn add_full_peer(&mut self) {
todo!()
}
pub(crate) fn generate_blocks(
&mut self,
count: usize,
session_length: u64,
validator_set: &ValidatorSet<AuthorityId>,
) {
self.peer(0).generate_blocks(count, BlockOrigin::File, |builder| {
let mut block = builder.build().unwrap().block;
if *block.header.number() % session_length == 0 {
add_auth_change_digest(&mut block.header, validator_set.clone());
}
block
});
}
}
TestNetFactory is implemented.
Then trait:
pub(crate) struct RuntimeApi {
inner: TestApi,
}
impl ProvideRuntimeApi<Block> for TestApi {
type Api = RuntimeApi;
fn runtime_api<'a>(&'a self) -> ApiRef<'a, Self::Api> {
RuntimeApi { inner: self.clone() }.into()
}
}
sp_api::mock_impl_runtime_apis! {
impl ModuleApi<Block> for RuntimeApi {}
}
And instantiation (where error comes from):
fn initialize_module(
net: &mut ModuleTestNet,
peers: Vec<(usize, &ModuleKeyring, ModuleTestParams)>,
) -> impl Future<Output = ()> {
let voters = FuturesUnordered::new();
for (peer_id, key, module_params) in peers.into_iter() {
let gadget = start_module_gadget::<_, _, _>(module_params);
fn assert_send<T: Send>(_: &T) {}
assert_send(&gadget);
voters.push(gadget);
}
voters.for_each(|_| async move {})
}
Declaration of gadget starting function:
pub async fn start_module_gadget<B, BE, C>(module_params: ModuleParams<C, BE>)
where
B: Block,
BE: Backend<B>,
C: Client<B, BE>,
C::Api: ModuleApi<B>,
{
let ModuleParams { client, backend, key_store, rpc_send } = module_params;
let worker_params = worker::WorkerParams { client, backend, key_store, rpc_send };
let mut worker = worker::ModuleWorker::<_, _, _>::new(worker_params);
worker.run().await
}