Skip to content

Commit 9500979

Browse files
authored
feat: integrate blueprint manager in tangle node (#982)
1 parent 877077e commit 9500979

File tree

9 files changed

+5344
-1648
lines changed

9 files changed

+5344
-1648
lines changed

Cargo.lock

Lines changed: 5164 additions & 1636 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ clap = { version = "4.5.16", features = ["derive"] }
7272
parity-scale-codec = { version = "3.6.12", default-features = false, features = ["derive", "max-encoded-len"] }
7373
rlp = { version = "0.5", default-features = false }
7474
tracing = "0.1.40"
75-
tokio = { version = "1.39" }
75+
tokio = { version = "1.44.2" }
7676
futures = { version = "0.3.30" }
7777
futures-timer = { version = "3.0.2" }
7878
rand_core = { version = "0.6", default-features = false }
@@ -398,5 +398,14 @@ subxt = { version = "0.39.0", default-features = false }
398398
subxt-core = { version = "0.39.0", default-features = false }
399399
subxt-signer = { version = "0.39.0", default-features = false }
400400

401+
# Blueprint
402+
blueprint-manager = { default-features = false, git = "https://github.com/tangle-network/blueprint", branch = "polkadot-stable2407" }
403+
blueprint-runner = { default-features = false, git = "https://github.com/tangle-network/blueprint", branch = "polkadot-stable2407" }
404+
blueprint-keystore = { default-features = false, git = "https://github.com/tangle-network/blueprint", branch = "polkadot-stable2407" }
405+
# --
406+
# blueprint-manager = { default-features = false, path = "../gadget/crates/manager" }
407+
# blueprint-runner = { default-features = false, path = "../gadget/crates/runner" }
408+
# blueprint-keystore = { default-features = false, path = "../gadget/crates/keystore" }
409+
401410
[profile.release]
402411
panic = "unwind"

node/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ substrate-prometheus-endpoint = { workspace = true }
7777
sp-session = { workspace = true }
7878
frame-system-rpc-runtime-api = { workspace = true }
7979
sp-io = { workspace = true }
80+
sc-keystore = { workspace = true }
8081

8182
# RPC related dependencies
8283
jsonrpsee = { workspace = true }
@@ -120,6 +121,10 @@ tangle-runtime = { workspace = true, features = ["std"] }
120121
tangle-testnet-runtime = { workspace = true, optional = true }
121122
futures-timer = { workspace = true }
122123

124+
blueprint-manager = { workspace = true, optional = true }
125+
blueprint-runner = { workspace = true, optional = true }
126+
blueprint-keystore = { workspace = true, optional = true }
127+
123128
[dev-dependencies]
124129
tangle-subxt = { workspace = true }
125130
sp-tracing = { workspace = true }
@@ -152,4 +157,5 @@ txpool = ["fc-rpc/txpool"]
152157
fast-runtime = ["tangle-testnet-runtime/fast-runtime", "tangle-runtime/fast-runtime"]
153158
metadata-hash = ["tangle-testnet-runtime?/metadata-hash", "tangle-runtime/metadata-hash"]
154159
manual-seal = ["tangle-testnet-runtime/manual-seal"]
160+
blueprint-manager = ["dep:blueprint-manager", "dep:blueprint-runner", "dep:blueprint-keystore"]
155161
try-runtime = []

node/src/blueprint_service.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use std::path::Path;
2+
use std::sync::Arc;
3+
4+
use blueprint_keystore::{Keystore, KeystoreConfig};
5+
use blueprint_manager::config::BlueprintManagerConfig;
6+
use blueprint_manager::executor::{BlueprintManagerHandle, run_blueprint_manager_with_keystore};
7+
use blueprint_runner::config::BlueprintEnvironment;
8+
use sc_keystore::LocalKeystore;
9+
use sc_service::error::Error as ServiceError;
10+
11+
/// Runs the blueprint manager service.
12+
pub fn create_blueprint_manager_service<P: AsRef<Path>>(
13+
rpc_port: u16,
14+
data_dir: P,
15+
local_keystore: Arc<LocalKeystore>,
16+
) -> Result<BlueprintManagerHandle, ServiceError> {
17+
let config = BlueprintManagerConfig {
18+
gadget_config: None,
19+
keystore_uri: data_dir.as_ref().display().to_string(),
20+
data_dir: data_dir.as_ref().to_path_buf(),
21+
verbose: 2,
22+
pretty: false,
23+
instance_id: None,
24+
test_mode: false,
25+
};
26+
let mut env = BlueprintEnvironment::default();
27+
28+
env.http_rpc_endpoint = format!("http://127.0.0.1:{}", rpc_port);
29+
env.ws_rpc_endpoint = format!("ws://127.0.0.1:{}", rpc_port);
30+
env.keystore_uri = config.keystore_uri.clone();
31+
env.data_dir = Some(config.data_dir.clone());
32+
env.protocol_settings = blueprint_runner::config::ProtocolSettings::None;
33+
env.test_mode = config.test_mode;
34+
35+
let keystore = Keystore::new(KeystoreConfig::new().substrate(local_keystore))
36+
.map_err(|e| ServiceError::Application(e.into()))?;
37+
38+
let shutdown_cmd = futures::future::pending();
39+
let mut handle = match run_blueprint_manager_with_keystore(config, keystore, env, shutdown_cmd)
40+
{
41+
Ok(handle) => handle,
42+
Err(e) => {
43+
log::error!("Failed to start blueprint manager: {}", e);
44+
return Err(ServiceError::Application(e.into()));
45+
},
46+
};
47+
handle.start().map_err(|e| ServiceError::Application(e.into()))?;
48+
log::info!("Blueprint manager started successfully.");
49+
Ok(handle)
50+
}

node/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#[cfg(feature = "blueprint-manager")]
2+
pub mod blueprint_service;
13
pub mod chainspec;
24
pub mod cli;
35
pub mod distributions;

node/src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ mod chainspec;
77
mod service;
88
#[cfg(feature = "runtime-benchmarks")]
99
mod benchmarking;
10+
#[cfg(feature = "blueprint-manager")]
11+
mod blueprint_service;
1012
mod cli;
1113
mod command;
1214
mod distributions;

node/src/manual_seal.rs

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use sc_consensus_babe::BabeWorkerHandle;
3030
use sc_consensus_grandpa::SharedVoterState;
3131
#[allow(deprecated)]
3232
pub use sc_executor::WasmExecutor;
33-
use sc_service::{Configuration, TaskManager, error::Error as ServiceError};
33+
use sc_service::{ChainType, Configuration, TaskManager, error::Error as ServiceError};
3434
use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker};
3535
use sc_transaction_pool_api::OffchainTransactionPoolFactory;
3636
use sp_core::U256;
@@ -98,9 +98,9 @@ where
9898
GrandpaBlockImport,
9999
) -> Result<(BasicQueue<Block>, BoxBlockImport), ServiceError>,
100100
{
101-
println!(" ++++++++++++++++++++++++
102-
+++++++++++++++++++++++++++
103-
+++++++++++++++++++++++++++
101+
println!(" ++++++++++++++++++++++++
102+
+++++++++++++++++++++++++++
103+
+++++++++++++++++++++++++++
104104
+++ ++++++ +++ @%%%%%%%%%%% %%%
105105
++++++ ++++ +++++ %%%%%%%%%%%% %%%@
106106
++++++++++++++++++++++++++ %%%% %%%%@ %%% %%@ @%%%%%%% %%%@ %%%%@
@@ -109,8 +109,8 @@ where
109109
++++++++++++++++++++++++++ %%%% %%%%%%%%% %%% %%%% %%% @%%% %%%@ @%%%%% %%%%%
110110
++++++ ++++ ++++++ %%%% %%%%%%%%% %%% %%%% %%%%%%%%%% %%%@ %%%%%%%%%@
111111
+++ ++++++ +++ %%%% %%%%%%%%% %%% %%%@ %%%%%%%%% %%% %%%%%%%@
112-
++++ +++++++++ +++ %%%% %%%%
113-
++++++++++++++++++++++++++++ %%%%%%%%%
112+
++++ +++++++++ +++ %%%% %%%%
113+
++++++++++++++++++++++++++++ %%%%%%%%%
114114
+++++++++++++++++++++++ %%%%% \n");
115115

116116
let telemetry = config
@@ -337,6 +337,23 @@ pub async fn new_full<Network: sc_network::NetworkBackend<Block, <Block as Block
337337
metrics,
338338
})?;
339339

340+
if config.role.is_authority() {
341+
if config.chain_spec.chain_type() == ChainType::Development
342+
|| config.chain_spec.chain_type() == ChainType::Local
343+
{
344+
if auto_insert_keys {
345+
crate::utils::insert_controller_account_keys_into_keystore(
346+
&config,
347+
Some(keystore_container.local_keystore()),
348+
);
349+
} else {
350+
crate::utils::insert_dev_controller_account_keys_into_keystore(
351+
&config,
352+
Some(keystore_container.local_keystore()),
353+
);
354+
}
355+
}
356+
}
340357
let role = config.role.clone();
341358
let force_authoring = config.force_authoring;
342359
let name = config.network.node_name.clone();
@@ -506,6 +523,10 @@ pub async fn new_full<Network: sc_network::NetworkBackend<Block, <Block as Block
506523
)
507524
.await;
508525

526+
#[cfg(feature = "blueprint-manager")]
527+
let config_data_path = config.data_path.clone();
528+
#[cfg(feature = "blueprint-manager")]
529+
let rpc_port = config.rpc_port;
509530
let params = sc_service::SpawnTasksParams {
510531
network: network.clone(),
511532
client: client.clone(),
@@ -600,6 +621,27 @@ pub async fn new_full<Network: sc_network::NetworkBackend<Block, <Block as Block
600621

601622
network_starter.start_network();
602623
log::info!("Manual Seal Ready");
624+
625+
#[cfg(feature = "blueprint-manager")]
626+
{
627+
log::info!("Blueprint Manager is enabled.");
628+
let bp_mngr = crate::blueprint_service::create_blueprint_manager_service(
629+
rpc_port,
630+
config_data_path.join("blueprints"),
631+
keystore_container.local_keystore(),
632+
)?;
633+
634+
task_manager
635+
.spawn_essential_handle()
636+
.spawn("blueprint-manager", None, async move {
637+
match bp_mngr.await {
638+
Ok(()) => (),
639+
Err(e) => {
640+
log::error!("Blueprint manager failed: {}", e);
641+
},
642+
}
643+
});
644+
}
603645
return Ok(task_manager);
604646
}
605647

@@ -644,6 +686,27 @@ pub async fn new_full<Network: sc_network::NetworkBackend<Block, <Block as Block
644686
);
645687
}
646688

689+
#[cfg(feature = "blueprint-manager")]
690+
{
691+
log::info!("Blueprint Manager is enabled.");
692+
let bp_mngr = crate::blueprint_service::create_blueprint_manager_service(
693+
rpc_port,
694+
config_data_path.join("blueprints"),
695+
keystore_container.local_keystore(),
696+
)?;
697+
698+
task_manager
699+
.spawn_essential_handle()
700+
.spawn("blueprint-manager", None, async move {
701+
match bp_mngr.await {
702+
Ok(()) => (),
703+
Err(e) => {
704+
log::error!("Blueprint manager failed: {}", e);
705+
},
706+
}
707+
});
708+
}
709+
647710
network_starter.start_network();
648711
Ok(task_manager)
649712
}

node/src/service.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,10 @@ pub async fn new_full<Network: sc_network::NetworkBackend<Block, <Block as Block
526526
)
527527
.await;
528528

529+
#[cfg(feature = "blueprint-manager")]
530+
let config_data_path = config.data_path.clone();
531+
#[cfg(feature = "blueprint-manager")]
532+
let rpc_port = config.rpc_port;
529533
let params = sc_service::SpawnTasksParams {
530534
network: network.clone(),
531535
client: client.clone(),
@@ -647,6 +651,26 @@ pub async fn new_full<Network: sc_network::NetworkBackend<Block, <Block as Block
647651
);
648652
}
649653

654+
#[cfg(feature = "blueprint-manager")]
655+
{
656+
let bp_mngr = crate::blueprint_service::create_blueprint_manager_service(
657+
rpc_port,
658+
config_data_path.join("blueprints"),
659+
keystore_container.local_keystore(),
660+
)?;
661+
662+
task_manager
663+
.spawn_essential_handle()
664+
.spawn("blueprint-manager", None, async move {
665+
match bp_mngr.await {
666+
Ok(()) => (),
667+
Err(e) => {
668+
log::error!("Blueprint manager failed: {}", e);
669+
},
670+
}
671+
});
672+
}
673+
650674
network_starter.start_network();
651675
Ok(task_manager)
652676
}

node/src/utils.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
use rand::Rng;
22
use sc_service::{ChainType, Configuration};
3-
use sp_core::{ByteArray, Pair, Public, ed25519, sr25519};
3+
use sp_core::{ByteArray, Pair, Public, ecdsa, ed25519, sr25519};
44
use sp_keystore::{Keystore, KeystorePtr};
55
use sp_runtime::{
66
KeyTypeId,
77
key_types::{ACCOUNT, BABE, GRANDPA, IM_ONLINE},
88
};
99

10+
pub const ROLE: KeyTypeId = KeyTypeId(*b"role");
11+
1012
/// Helper function to generate a crypto pair from seed.
1113
pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
1214
TPublic::Pair::from_string(&format!("//{seed}"), None)
@@ -38,6 +40,8 @@ pub fn insert_controller_account_keys_into_keystore(
3840
key_store.clone(),
3941
"ImOnline",
4042
);
43+
insert_account_keys_into_keystore::<ecdsa::Public>(config, ROLE, key_store.clone(), "role");
44+
insert_account_keys_into_keystore::<ed25519::Public>(config, ROLE, key_store.clone(), "role");
4145
}
4246

4347
/// Inserts keys of specified type into the keystore.
@@ -77,14 +81,19 @@ fn insert_account_keys_into_keystore<TPublic: Public>(
7781
if let Some(keystore) = key_store {
7882
let _ = Keystore::insert(&*keystore, key_type, &seed_hex, &pub_key);
7983
}
80-
println!("++++++++++++++++++++++++++++++++++++++++++++++++
81-
AUTO GENERATED KEYS
84+
println!(
85+
"++++++++++++++++++++++++++++++++++++++++++++++++
86+
AUTO GENERATED KEYS
8287
'{}' key inserted to keystore
8388
Seed: {}
8489
PublicKey: 0x{}
8590
STORE THE KEYS SAFELY, NOT TO BE SHARED WITH ANYONE ELSE.
86-
++++++++++++++++++++++++++++++++++++++++++++++++
87-
\n", key_name, seed_hex, hex::encode(pub_key));
91+
++++++++++++++++++++++++++++++++++++++++++++++++
92+
\n",
93+
key_name,
94+
seed_hex,
95+
hex::encode(pub_key)
96+
);
8897
}
8998

9099
/// Inserts a key of type `ACCOUNT` into the keystore for development/testing.
@@ -96,6 +105,9 @@ pub fn insert_dev_controller_account_keys_into_keystore(
96105
key_store: Option<KeystorePtr>,
97106
) {
98107
insert_dev_account_keys_into_keystore::<sr25519::Public>(config, ACCOUNT, key_store.clone());
108+
insert_dev_account_keys_into_keystore::<ed25519::Public>(config, ROLE, key_store.clone());
109+
110+
insert_dev_account_keys_into_keystore::<ecdsa::Public>(config, ROLE, key_store.clone());
99111
}
100112

101113
/// Inserts keys of specified type into the keystore for predefined nodes in development mode.

0 commit comments

Comments
 (0)