Skip to content

Commit

Permalink
feat: extend peer identify with spell service version and allowed mou…
Browse files Browse the repository at this point in the history
…nted binaries list [fixes NET-429 NET-381] (#1540)

* extend peer identify with spell service version and allowed mounted binaries list
* add module hashes as version for spell services from disk
  • Loading branch information
kmd-fl authored Mar 31, 2023
1 parent d023865 commit 30eff87
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 31 deletions.
6 changes: 0 additions & 6 deletions particle-builtins/src/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ use crate::debug::fmt_custom_services;
use crate::error::HostClosureCallError;
use crate::error::HostClosureCallError::{DecodeBase58, DecodeUTF8};
use crate::func::{binary, unary};
use crate::identify::NodeInfo;
use crate::outcome::{ok, wrap, wrap_unit};
use crate::{json, math};

Expand Down Expand Up @@ -87,8 +86,6 @@ pub struct Builtins<C> {

pub modules: ModuleRepository,
pub services: ParticleAppServices,
pub node_info: NodeInfo,

#[derivative(Debug(format_with = "fmt_custom_services"))]
pub custom_services: RwLock<HashMap<String, CustomService>>,

Expand All @@ -105,7 +102,6 @@ where
pub fn new(
connectivity: C,
script_storage: ScriptStorageApi,
node_info: NodeInfo,
config: ServicesConfig,
services_metrics: ServicesMetrics,
key_manager: KeyManager,
Expand Down Expand Up @@ -135,7 +131,6 @@ where
local_peer_id,
modules,
services,
node_info,
particles_vault_dir,
custom_services: <_>::default(),
key_manager,
Expand Down Expand Up @@ -191,7 +186,6 @@ where

#[rustfmt::skip]
match (args.service_id.as_str(), args.function_name.as_str()) {
("peer", "identify") => ok(json!(self.node_info)),
("peer", "timestamp_ms") => ok(json!(now_ms() as u64)),
("peer", "timestamp_sec") => ok(json!(now_sec())),
("peer", "is_connected") => wrap(self.is_connected(args).await),
Expand Down
2 changes: 2 additions & 0 deletions particle-builtins/src/identify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ pub struct NodeInfo {
pub external_addresses: Vec<Multiaddr>,
pub node_version: &'static str,
pub air_version: &'static str,
pub spell_version: String,
pub allowed_binaries: Vec<String>,
}
1 change: 1 addition & 0 deletions particle-node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ sorcerer = { workspace = true }
dhat = { version = "0.3.2", optional = true }


serde_json = { workspace = true }
fluence-libp2p = { workspace = true }
server-config = { workspace = true }
config-utils = { workspace = true }
Expand Down
36 changes: 36 additions & 0 deletions particle-node/src/builtins.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2023 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

use futures::FutureExt;
use particle_builtins::{ok, CustomService, NodeInfo};
use particle_execution::ServiceFunction;
use serde_json::json;

pub fn make_peer_builtin(node_info: NodeInfo) -> (String, CustomService) {
(
"peer".to_string(),
CustomService::new(
vec![("identify", make_peer_identify_closure(node_info))],
None,
),
)
}
fn make_peer_identify_closure(node_info: NodeInfo) -> ServiceFunction {
ServiceFunction::Immut(Box::new(move |_args, _params| {
let node_info = node_info.clone();
async move { ok(json!(node_info)) }.boxed()
}))
}
2 changes: 2 additions & 0 deletions particle-node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#![feature(extend_one)]
#![feature(try_blocks)]
#![feature(drain_filter)]
#![feature(ip)]
Expand All @@ -28,6 +29,7 @@
unreachable_patterns
)]

mod builtins;
mod connectivity;
mod dispatcher;
mod effectors;
Expand Down
29 changes: 18 additions & 11 deletions particle-node/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ use spell_event_bus::bus::SpellEventBus;
use tokio::sync::{mpsc, oneshot};
use tokio::task;

use crate::builtins::make_peer_builtin;
use crate::dispatcher::Dispatcher;
use crate::effectors::Effectors;
use crate::metrics::start_metrics_endpoint;
Expand Down Expand Up @@ -192,9 +193,14 @@ impl<RT: AquaRuntime> Node<RT> {
)
};

let allowed_binaries = services_config
.allowed_binaries
.iter()
.map(|s| s.to_string_lossy().to_string())
.collect::<_>();

let builtins = Arc::new(Self::builtins(
connectivity.clone(),
config.external_addresses(),
services_config,
script_storage_api,
services_metrics,
Expand Down Expand Up @@ -244,7 +250,7 @@ impl<RT: AquaRuntime> Node<RT> {
let (spell_event_bus, spell_event_bus_api, spell_events_receiver) =
SpellEventBus::new(sources);

let (sorcerer, spell_service_functions) = Sorcerer::new(
let (sorcerer, mut custom_service_functions, spell_version) = Sorcerer::new(
builtins.services.clone(),
builtins.modules.clone(),
aquamarine_api.clone(),
Expand All @@ -253,7 +259,16 @@ impl<RT: AquaRuntime> Node<RT> {
key_manager.clone(),
);

spell_service_functions.into_iter().for_each(
let node_info = NodeInfo {
external_addresses: config.external_addresses(),
node_version: env!("CARGO_PKG_VERSION"),
air_version: air_interpreter_wasm::VERSION,
spell_version,
allowed_binaries,
};
custom_service_functions.extend_one(make_peer_builtin(node_info));

custom_service_functions.into_iter().for_each(
move |(
service_id,
CustomService {
Expand Down Expand Up @@ -319,22 +334,14 @@ impl<RT: AquaRuntime> Node<RT> {

pub fn builtins(
connectivity: Connectivity,
external_addresses: Vec<Multiaddr>,
services_config: ServicesConfig,
script_storage_api: ScriptStorageApi,
services_metrics: ServicesMetrics,
key_manager: KeyManager,
) -> Builtins<Connectivity> {
let node_info = NodeInfo {
external_addresses,
node_version: env!("CARGO_PKG_VERSION"),
air_version: air_interpreter_wasm::VERSION,
};

Builtins::new(
connectivity,
script_storage_api,
node_info,
services_config,
services_metrics,
key_manager,
Expand Down
6 changes: 3 additions & 3 deletions sorcerer/src/sorcerer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ impl Sorcerer {
config: ResolvedConfig,
spell_event_bus_api: SpellEventBusApi,
key_manager: KeyManager,
) -> (Self, HashMap<String, CustomService>) {
let spell_storage =
) -> (Self, HashMap<String, CustomService>, String) {
let (spell_storage, spell_version) =
SpellStorage::create(&config.dir_config.spell_base_dir, &services, &modules)
.expect("Spell storage creation");

Expand All @@ -76,7 +76,7 @@ impl Sorcerer {
let mut builtin_functions = sorcerer.make_spell_builtins();
builtin_functions.extend_one(sorcerer.make_worker_builtin());

(sorcerer, builtin_functions)
(sorcerer, builtin_functions, spell_version)
}

async fn resubscribe_spells(&self) {
Expand Down
35 changes: 24 additions & 11 deletions spell-storage/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,26 @@ impl SpellStorage {
spells_base_dir: &Path,
services: &ParticleAppServices,
modules: &ModuleRepository,
) -> eyre::Result<Self> {
) -> eyre::Result<(Self, String)> {
let spell_config_path = spell_config_path(spells_base_dir);
let spell_blueprint_id = if spell_config_path.exists() {
let (spell_blueprint_id, spell_version) = if spell_config_path.exists() {
let cfg = TomlMarineConfig::load(spell_config_path)?;
Self::load_spell_service(cfg, spells_base_dir, modules)?
} else {
Self::load_spell_service_from_crate(modules)?
};
let registered_spells = Self::restore_spells(services, modules);

Ok(Self {
spell_blueprint_id,
registered_spells: Arc::new(RwLock::new(registered_spells)),
})
Ok((
Self {
spell_blueprint_id,
registered_spells: Arc::new(RwLock::new(registered_spells)),
},
spell_version,
))
}

fn load_spell_service_from_crate(modules: &ModuleRepository) -> eyre::Result<String> {
fn load_spell_service_from_crate(modules: &ModuleRepository) -> eyre::Result<(String, String)> {
use fluence_spell_distro::{modules as spell_modules, CONFIG};

log::info!(
Expand All @@ -70,15 +73,19 @@ impl SpellStorage {
hashes.push(Dependency::Hash(hash))
}

Ok(modules.add_blueprint(AddBlueprint::new("spell".to_string(), hashes))?)
Ok((
modules.add_blueprint(AddBlueprint::new("spell".to_string(), hashes))?,
fluence_spell_distro::VERSION.to_string(),
))
}

fn load_spell_service(
cfg: TomlMarineConfig,
spells_base_dir: &Path,
modules: &ModuleRepository,
) -> eyre::Result<String> {
) -> eyre::Result<(String, String)> {
let mut hashes = Vec::new();
let mut versions = Vec::new();
for config in cfg.module {
let load_from = config
.load_from
Expand All @@ -89,10 +96,16 @@ impl SpellStorage {
let module_path = spells_base_dir.join(load_from);
let module = load_module_by_path(module_path.as_ref())?;
let hash = modules.add_module(module, config)?;
let hex = hash.to_hex();
let hex = hex.as_ref();
versions.push(String::from(&hex[..8]));
hashes.push(Dependency::Hash(hash));
}

Ok(modules.add_blueprint(AddBlueprint::new("spell".to_string(), hashes))?)
let spell_disk_version = format!("wasm hashes {}", versions.join(" "));
Ok((
modules.add_blueprint(AddBlueprint::new("spell".to_string(), hashes))?,
spell_disk_version,
))
}

fn restore_spells(
Expand Down

0 comments on commit 30eff87

Please sign in to comment.