mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-08 13:37:22 +00:00
Initial: Offchain Workers (#1942)
* Refactor state-machine stuff. * Fix tests. * WiP * WiP2 * Service support for offchain workers. * Service support for offchain workers. * Testing offchain worker. * Initial version working. * Pass side effects in call. * Pass OffchainExt in context. * Submit extrinsics to the pool. * Support inherents. * Insert to inherents pool. * Inserting to the pool asynchronously. * Add test to offchain worker. * Implement convenience syntax for modules. * Dispatching offchain worker through executive. * Fix offchain test. * Remove offchain worker from timestamp. * Update Cargo.lock. * Address review comments. * Use latest patch version for futures. * Add CLI parameter for offchain worker. * Fix compilation. * Fix test. * Fix extrinsics format for tests. * Fix RPC test. * Bump spec version. * Fix executive. * Fix support macro. * Address grumbles. * Bump runtime
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
//! Substrate service. Starts a thread that spins up the network, client, and extrinsic pool.
|
||||
//! Manages communication between them.
|
||||
|
||||
#![warn(unused_extern_crates)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
mod components;
|
||||
mod error;
|
||||
@@ -28,20 +28,18 @@ pub mod chain_ops;
|
||||
use std::io;
|
||||
use std::net::SocketAddr;
|
||||
use std::collections::HashMap;
|
||||
#[doc(hidden)]
|
||||
pub use std::{ops::Deref, result::Result, sync::Arc};
|
||||
use log::{info, warn, debug};
|
||||
use futures::prelude::*;
|
||||
use keystore::Store as Keystore;
|
||||
|
||||
use client::BlockchainEvents;
|
||||
use exit_future::Signal;
|
||||
use futures::prelude::*;
|
||||
use inherents::pool::InherentsPool;
|
||||
use keystore::Store as Keystore;
|
||||
use log::{info, warn, debug};
|
||||
use parity_codec::{Encode, Decode};
|
||||
use primitives::Pair;
|
||||
use runtime_primitives::generic::BlockId;
|
||||
use runtime_primitives::traits::{Header, As};
|
||||
use exit_future::Signal;
|
||||
#[doc(hidden)]
|
||||
pub use tokio::runtime::TaskExecutor;
|
||||
use substrate_executor::NativeExecutor;
|
||||
use parity_codec::{Encode, Decode};
|
||||
use tel::{telemetry, SUBSTRATE_INFO};
|
||||
|
||||
pub use self::error::{ErrorKind, Error};
|
||||
@@ -59,9 +57,13 @@ pub use components::{ServiceFactory, FullBackend, FullExecutor, LightBackend,
|
||||
FactoryFullConfiguration, RuntimeGenesis, FactoryGenesis,
|
||||
ComponentExHash, ComponentExtrinsic, FactoryExtrinsic
|
||||
};
|
||||
use components::{StartRPC, MaintainTransactionPool};
|
||||
use components::{StartRPC, MaintainTransactionPool, OffchainWorker};
|
||||
#[doc(hidden)]
|
||||
pub use std::{ops::Deref, result::Result, sync::Arc};
|
||||
#[doc(hidden)]
|
||||
pub use network::OnDemand;
|
||||
#[doc(hidden)]
|
||||
pub use tokio::runtime::TaskExecutor;
|
||||
|
||||
const DEFAULT_PROTOCOL_ID: &str = "sup";
|
||||
|
||||
@@ -70,6 +72,7 @@ pub struct Service<Components: components::Components> {
|
||||
client: Arc<ComponentClient<Components>>,
|
||||
network: Option<Arc<components::NetworkService<Components::Factory>>>,
|
||||
transaction_pool: Arc<TransactionPool<Components::TransactionPoolApi>>,
|
||||
inherents_pool: Arc<InherentsPool<ComponentExtrinsic<Components>>>,
|
||||
keystore: Keystore,
|
||||
exit: ::exit_future::Exit,
|
||||
signal: Option<Signal>,
|
||||
@@ -77,6 +80,7 @@ pub struct Service<Components: components::Components> {
|
||||
pub config: FactoryFullConfiguration<Components::Factory>,
|
||||
_rpc: Box<::std::any::Any + Send + Sync>,
|
||||
_telemetry: Option<Arc<tel::Telemetry>>,
|
||||
_offchain_workers: Option<Arc<offchain::OffchainWorkers<ComponentClient<Components>, ComponentBlock<Components>>>>,
|
||||
}
|
||||
|
||||
/// Creates bare client without any networking.
|
||||
@@ -96,9 +100,7 @@ impl<Components: components::Components> Service<Components> {
|
||||
pub fn new(
|
||||
mut config: FactoryFullConfiguration<Components::Factory>,
|
||||
task_executor: TaskExecutor,
|
||||
)
|
||||
-> Result<Self, error::Error>
|
||||
{
|
||||
) -> Result<Self, error::Error> {
|
||||
let (signal, exit) = ::exit_future::signal();
|
||||
|
||||
// Create client
|
||||
@@ -169,24 +171,48 @@ impl<Components: components::Components> Service<Components> {
|
||||
)?;
|
||||
on_demand.map(|on_demand| on_demand.set_network_sender(network_chan));
|
||||
|
||||
let inherents_pool = Arc::new(InherentsPool::default());
|
||||
let offchain_workers = if config.offchain_worker {
|
||||
Some(Arc::new(offchain::OffchainWorkers::new(
|
||||
client.clone(),
|
||||
inherents_pool.clone(),
|
||||
task_executor.clone(),
|
||||
)))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
{
|
||||
// block notifications
|
||||
let network = Arc::downgrade(&network);
|
||||
let txpool = Arc::downgrade(&transaction_pool);
|
||||
let wclient = Arc::downgrade(&client);
|
||||
let offchain = offchain_workers.as_ref().map(Arc::downgrade);
|
||||
|
||||
let events = client.import_notification_stream()
|
||||
.for_each(move |notification| {
|
||||
let number = *notification.header.number();
|
||||
|
||||
if let Some(network) = network.upgrade() {
|
||||
network.on_block_imported(notification.hash, notification.header);
|
||||
}
|
||||
|
||||
if let (Some(txpool), Some(client)) = (txpool.upgrade(), wclient.upgrade()) {
|
||||
Components::TransactionPool::on_block_imported(
|
||||
Components::RuntimeServices::maintain_transaction_pool(
|
||||
&BlockId::hash(notification.hash),
|
||||
&*client,
|
||||
&*txpool,
|
||||
).map_err(|e| warn!("Pool error processing new block: {:?}", e))?;
|
||||
}
|
||||
|
||||
if let (Some(txpool), Some(offchain)) = (txpool.upgrade(), offchain.as_ref().and_then(|o| o.upgrade())) {
|
||||
Components::RuntimeServices::offchain_workers(
|
||||
&number,
|
||||
&offchain,
|
||||
&txpool,
|
||||
).map_err(|e| warn!("Offchain workers error processing new block: {:?}", e))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.select(exit.clone())
|
||||
@@ -264,7 +290,7 @@ impl<Components: components::Components> Service<Components> {
|
||||
impl_version: config.impl_version.into(),
|
||||
properties: config.chain_spec.properties(),
|
||||
};
|
||||
let rpc = Components::RPC::start_rpc(
|
||||
let rpc = Components::RuntimeServices::start_rpc(
|
||||
client.clone(), network.clone(), has_bootnodes, system_info, config.rpc_http,
|
||||
config.rpc_ws, task_executor.clone(), transaction_pool.clone(),
|
||||
)?;
|
||||
@@ -299,12 +325,14 @@ impl<Components: components::Components> Service<Components> {
|
||||
client,
|
||||
network: Some(network),
|
||||
transaction_pool,
|
||||
inherents_pool,
|
||||
signal: Some(signal),
|
||||
keystore,
|
||||
config,
|
||||
exit,
|
||||
_rpc: Box::new(rpc),
|
||||
_telemetry: telemetry,
|
||||
_offchain_workers: offchain_workers,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -321,6 +349,7 @@ impl<Components: components::Components> Service<Components> {
|
||||
}
|
||||
}
|
||||
|
||||
/// return a shared instance of Telemtry (if enabled)
|
||||
pub fn telemetry(&self) -> Option<Arc<tel::Telemetry>> {
|
||||
self._telemetry.as_ref().map(|t| t.clone())
|
||||
}
|
||||
@@ -337,11 +366,16 @@ impl<Components> Service<Components> where Components: components::Components {
|
||||
self.network.as_ref().expect("self.network always Some").clone()
|
||||
}
|
||||
|
||||
/// Get shared extrinsic pool instance.
|
||||
/// Get shared transaction pool instance.
|
||||
pub fn transaction_pool(&self) -> Arc<TransactionPool<Components::TransactionPoolApi>> {
|
||||
self.transaction_pool.clone()
|
||||
}
|
||||
|
||||
/// Get shared inherents pool instance.
|
||||
pub fn inherents_pool(&self) -> Arc<InherentsPool<ComponentExtrinsic<Components>>> {
|
||||
self.inherents_pool.clone()
|
||||
}
|
||||
|
||||
/// Get shared keystore.
|
||||
pub fn keystore(&self) -> &Keystore {
|
||||
&self.keystore
|
||||
|
||||
Reference in New Issue
Block a user