feat!(avm-server): Per-call current_peer_id (#381)

The current peer ID is passed as a new field of `TestRunParameters` named
`current_peer_id: String`, instead of creating an AVM with peer ID.

This is a breaking API change of `avm-interface` and `avm-server`.
This commit is contained in:
Ivan Boldyrev 2022-11-25 10:59:09 +03:00 committed by GitHub
parent 4e86da7eda
commit becdedc364
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 206 additions and 85 deletions

7
Cargo.lock generated
View File

@ -176,13 +176,14 @@ dependencies = [
[[package]] [[package]]
name = "air-test-utils" name = "air-test-utils"
version = "0.3.0" version = "0.4.0"
dependencies = [ dependencies = [
"air", "air",
"air-interpreter-interface", "air-interpreter-interface",
"avm-interface", "avm-interface",
"avm-server", "avm-server",
"fstrings", "fstrings",
"maplit",
"marine-rs-sdk", "marine-rs-sdk",
"object-pool", "object-pool",
"once_cell", "once_cell",
@ -319,7 +320,7 @@ dependencies = [
[[package]] [[package]]
name = "avm-interface" name = "avm-interface"
version = "0.26.1" version = "0.27.0"
dependencies = [ dependencies = [
"air-interpreter-interface", "air-interpreter-interface",
"air-utils", "air-utils",
@ -335,7 +336,7 @@ dependencies = [
[[package]] [[package]]
name = "avm-server" name = "avm-server"
version = "0.26.1" version = "0.27.0"
dependencies = [ dependencies = [
"air-interpreter-interface", "air-interpreter-interface",
"air-utils", "air-utils",

View File

@ -45,7 +45,7 @@ fn issue_177() {
// client 1: demand result for (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) // client 1: demand result for (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
let client_result_1 = client let client_result_1 = client
.runner .runner
.call(script, "", "", client_peer_id, 0, 0, HashMap::new()) .call(script, "", "", client_peer_id, 0, 0, None, HashMap::new())
.expect("call should be success"); .expect("call should be success");
let expected_call_requests = maplit::hashmap! { let expected_call_requests = maplit::hashmap! {
1 => CallRequestParams::new("getDataSrv", "-relay-", vec![], vec![]), 1 => CallRequestParams::new("getDataSrv", "-relay-", vec![], vec![]),
@ -59,7 +59,16 @@ fn issue_177() {
// client 2: send result to the specified relay // client 2: send result to the specified relay
let client_result_2 = client let client_result_2 = client
.runner .runner
.call(script, client_result_1.data, "", client_peer_id, 0, 0, call_results) .call(
script,
client_result_1.data,
"",
client_peer_id,
0,
0,
None,
call_results,
)
.expect("call should be success"); .expect("call should be success");
assert!(client_result_2.call_requests.is_empty()); assert!(client_result_2.call_requests.is_empty());
assert_eq!(client_result_2.next_peer_pks, vec![relay_peer_id.to_string()]); assert_eq!(client_result_2.next_peer_pks, vec![relay_peer_id.to_string()]);
@ -74,6 +83,7 @@ fn issue_177() {
client_peer_id, client_peer_id,
0, 0,
0, 0,
None,
HashMap::new(), HashMap::new(),
) )
.expect("call should be success"); .expect("call should be success");
@ -96,6 +106,7 @@ fn issue_177() {
client_peer_id, client_peer_id,
0, 0,
0, 0,
None,
call_results, call_results,
) )
.expect("call should be success"); .expect("call should be success");
@ -114,6 +125,7 @@ fn issue_177() {
client_peer_id, client_peer_id,
0, 0,
0, 0,
None,
call_results, call_results,
) )
.expect("call should be success"); .expect("call should be success");
@ -132,6 +144,7 @@ fn issue_177() {
client_peer_id, client_peer_id,
0, 0,
0, 0,
None,
call_results, call_results,
) )
.expect("call should be success"); .expect("call should be success");
@ -147,6 +160,7 @@ fn issue_177() {
client_peer_id, client_peer_id,
0, 0,
0, 0,
None,
HashMap::new(), HashMap::new(),
) )
.expect("call should be success"); .expect("call should be success");
@ -163,7 +177,16 @@ fn issue_177() {
// demand a result for (call %init_peer_id% ("peer" "timeout") [1000 "timeout"]) // demand a result for (call %init_peer_id% ("peer" "timeout") [1000 "timeout"])
let client_result_4 = client let client_result_4 = client
.runner .runner
.call(script, client_result_3.data, "", client_peer_id, 0, 0, call_results) .call(
script,
client_result_3.data,
"",
client_peer_id,
0,
0,
None,
call_results,
)
.expect("call should be success"); .expect("call should be success");
let expected_call_requests = maplit::hashmap! { let expected_call_requests = maplit::hashmap! {
3 => CallRequestParams::new("peer", "timeout", vec![json!(1000u64), json!("timeout")], vec![ 3 => CallRequestParams::new("peer", "timeout", vec![json!(1000u64), json!("timeout")], vec![
@ -178,9 +201,16 @@ fn issue_177() {
}; };
// timeout requests provided // timeout requests provided
let client_result_5 = client let client_result_5 = client.runner.call(
.runner script,
.call(script, client_result_4.data, "", client_peer_id, 0, 0, call_results); client_result_4.data,
"",
client_peer_id,
0,
0,
None,
call_results,
);
// before patch the interpreter crashed here // before patch the interpreter crashed here
assert!(client_result_5.is_ok()); assert!(client_result_5.is_ok());
} }

View File

@ -6,6 +6,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [0.27.0] - 2022-11-22
### Added
- Add `current_peer_id` field to the `ParticleParameters`
### Changed
- `ParticleParameters` now has only single lifetime parameter
## [0.26.1] - 2022-09-13 ## [0.26.1] - 2022-09-13
### Fixed ### Fixed

View File

@ -1,7 +1,7 @@
[package] [package]
name = "avm-interface" name = "avm-interface"
description = "Fluence AIR VM interfacing" description = "Fluence AIR VM interfacing"
version = "0.26.1" version = "0.27.0"
authors = ["Fluence Labs"] authors = ["Fluence Labs"]
edition = "2018" edition = "2018"
license = "Apache-2.0" license = "Apache-2.0"

View File

@ -20,25 +20,28 @@ use std::borrow::Cow;
/// Represents parameters obtained from a particle. /// Represents parameters obtained from a particle.
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ParticleParameters<'init_peer_id, 'particle_id> { pub struct ParticleParameters<'ctx> {
pub init_peer_id: Cow<'init_peer_id, str>, pub init_peer_id: Cow<'ctx, str>,
pub particle_id: Cow<'particle_id, str>, pub particle_id: Cow<'ctx, str>,
pub timestamp: u64, pub timestamp: u64,
pub ttl: u32, pub ttl: u32,
pub current_peer_id: Cow<'ctx, str>,
} }
impl<'init_peer_id, 'particle_id> ParticleParameters<'init_peer_id, 'particle_id> { impl<'ctx> ParticleParameters<'ctx> {
pub fn new( pub fn new(
init_peer_id: Cow<'init_peer_id, str>, init_peer_id: Cow<'ctx, str>,
particle_id: Cow<'particle_id, str>, particle_id: Cow<'ctx, str>,
timestamp: u64, timestamp: u64,
ttl: u32, ttl: u32,
current_peer_id: Cow<'ctx, str>,
) -> Self { ) -> Self {
Self { Self {
init_peer_id, init_peer_id,
particle_id, particle_id,
timestamp, timestamp,
ttl, ttl,
current_peer_id,
} }
} }
} }

View File

@ -6,6 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [0.27.0] - 2022-11-22
### Changed
- Move `current_peer_id` field/argument to the `ParticleParameters`.
It is removed from both `AVMConfig` and `AVMRunner::new`, but added to `AVMRunner::call`/`AVMRunner::call_tracing`.
- `ParticleParameters` now has only single lifetime parameter
- Update `avm-interface` version
## [0.26.1] - 2022-09-13 ## [0.26.1] - 2022-09-13
### Other ### Other

View File

@ -1,7 +1,7 @@
[package] [package]
name = "avm-server" name = "avm-server"
description = "Fluence AIR VM" description = "Fluence AIR VM"
version = "0.26.1" version = "0.27.0"
authors = ["Fluence Labs"] authors = ["Fluence Labs"]
edition = "2018" edition = "2018"
license = "Apache-2.0" license = "Apache-2.0"
@ -20,7 +20,7 @@ air-utils = { version = "0.1.0", path = "../../crates/air-lib/utils" }
avm-data-store = { version = "0.4.1", path = "../../crates/data-store" } avm-data-store = { version = "0.4.1", path = "../../crates/data-store" }
marine-runtime = "0.23.1" marine-runtime = "0.23.1"
polyplets = { version = "0.3.2", path = "../../crates/air-lib/polyplets" } polyplets = { version = "0.3.2", path = "../../crates/air-lib/polyplets" }
avm-interface = { version = "0.26.1", path = "../../avm/interface" } avm-interface = { version = "0.27.0", path = "../../avm/interface" }
eyre = "0.6.8" eyre = "0.6.8"
thiserror = "1.0.37" thiserror = "1.0.37"

View File

@ -62,7 +62,6 @@ impl<E> AVM<E> {
pub fn new(config: AVMConfig<E>) -> AVMResult<Self, E> { pub fn new(config: AVMConfig<E>) -> AVMResult<Self, E> {
let AVMConfig { let AVMConfig {
air_wasm_path, air_wasm_path,
current_peer_id,
max_heap_size, max_heap_size,
logging_mask, logging_mask,
mut data_store, mut data_store,
@ -70,7 +69,7 @@ impl<E> AVM<E> {
data_store.initialize()?; data_store.initialize()?;
let runner = AVMRunner::new(air_wasm_path, current_peer_id, max_heap_size, logging_mask) let runner = AVMRunner::new(air_wasm_path, max_heap_size, logging_mask)
.map_err(AVMError::RunnerError)?; .map_err(AVMError::RunnerError)?;
let runner = SendSafeRunner(runner); let runner = SendSafeRunner(runner);
let avm = Self { runner, data_store }; let avm = Self { runner, data_store };
@ -83,7 +82,7 @@ impl<E> AVM<E> {
&mut self, &mut self,
air: impl Into<String>, air: impl Into<String>,
data: impl Into<Vec<u8>>, data: impl Into<Vec<u8>>,
particle_parameters: ParticleParameters<'_, '_>, particle_parameters: ParticleParameters<'_>,
call_results: CallResults, call_results: CallResults,
) -> AVMResult<AVMOutcome, E> { ) -> AVMResult<AVMOutcome, E> {
let air = air.into(); let air = air.into();
@ -102,6 +101,7 @@ impl<E> AVM<E> {
particle_parameters.init_peer_id.clone().into_owned(), particle_parameters.init_peer_id.clone().into_owned(),
particle_parameters.timestamp, particle_parameters.timestamp,
particle_parameters.ttl, particle_parameters.ttl,
particle_parameters.current_peer_id.clone(),
call_results, call_results,
) )
.map_err(AVMError::RunnerError)?; .map_err(AVMError::RunnerError)?;
@ -144,7 +144,7 @@ impl<E> AVM<E> {
&mut self, &mut self,
air_script: &str, air_script: &str,
current_data: &[u8], current_data: &[u8],
particle_parameters: &ParticleParameters<'_, '_>, particle_parameters: &ParticleParameters<'_>,
avm_outcome: &RawAVMOutcome, avm_outcome: &RawAVMOutcome,
execution_time: Duration, execution_time: Duration,
memory_delta: usize, memory_delta: usize,

View File

@ -22,9 +22,6 @@ pub struct AVMConfig<E> {
/// Path to a AIR interpreter Wasm file. /// Path to a AIR interpreter Wasm file.
pub air_wasm_path: PathBuf, pub air_wasm_path: PathBuf,
/// Current peer id.
pub current_peer_id: String,
/// Maximum heap size in bytes available for the interpreter. /// Maximum heap size in bytes available for the interpreter.
pub max_heap_size: Option<u64>, pub max_heap_size: Option<u64>,

View File

@ -30,7 +30,6 @@ use std::path::PathBuf;
pub struct AVMRunner { pub struct AVMRunner {
marine: Marine, marine: Marine,
current_peer_id: String,
/// file name of the AIR interpreter .wasm /// file name of the AIR interpreter .wasm
wasm_filename: String, wasm_filename: String,
} }
@ -48,7 +47,6 @@ impl AVMRunner {
/// Create AVM with the provided config. /// Create AVM with the provided config.
pub fn new( pub fn new(
air_wasm_path: PathBuf, air_wasm_path: PathBuf,
current_peer_id: impl Into<String>,
max_heap_size: Option<u64>, max_heap_size: Option<u64>,
logging_mask: i32, logging_mask: i32,
) -> RunnerResult<Self> { ) -> RunnerResult<Self> {
@ -57,11 +55,9 @@ impl AVMRunner {
let marine_config = let marine_config =
make_marine_config(wasm_dir, &wasm_filename, max_heap_size, logging_mask); make_marine_config(wasm_dir, &wasm_filename, max_heap_size, logging_mask);
let marine = Marine::with_raw_config(marine_config)?; let marine = Marine::with_raw_config(marine_config)?;
let current_peer_id = current_peer_id.into();
let avm = Self { let avm = Self {
marine, marine,
current_peer_id,
wasm_filename, wasm_filename,
}; };
@ -78,13 +74,14 @@ impl AVMRunner {
init_peer_id: impl Into<String>, init_peer_id: impl Into<String>,
timestamp: u64, timestamp: u64,
ttl: u32, ttl: u32,
current_peer_id: impl Into<String>,
call_results: CallResults, call_results: CallResults,
) -> RunnerResult<RawAVMOutcome> { ) -> RunnerResult<RawAVMOutcome> {
let args = prepare_args( let args = prepare_args(
air, air,
prev_data, prev_data,
data, data,
self.current_peer_id.clone(), current_peer_id.into(),
init_peer_id.into(), init_peer_id.into(),
timestamp, timestamp,
ttl, ttl,
@ -117,6 +114,7 @@ impl AVMRunner {
init_peer_id: impl Into<String>, init_peer_id: impl Into<String>,
timestamp: u64, timestamp: u64,
ttl: u32, ttl: u32,
current_peer_id: impl Into<String>,
call_results: CallResults, call_results: CallResults,
tracing_params: String, tracing_params: String,
tracing_output_mode: u8, tracing_output_mode: u8,
@ -125,7 +123,7 @@ impl AVMRunner {
air, air,
prev_data, prev_data,
data, data,
self.current_peer_id.clone(), current_peer_id.into(),
init_peer_id.into(), init_peer_id.into(),
timestamp, timestamp,
ttl, ttl,
@ -165,11 +163,6 @@ impl AVMRunner {
max_memory_size: stats[0].max_memory_size, max_memory_size: stats[0].max_memory_size,
} }
} }
#[inline]
pub fn set_peer_id(&mut self, current_peer_id: impl Into<String>) {
self.current_peer_id = current_peer_id.into();
}
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]

View File

@ -1,6 +1,6 @@
[package] [package]
name = "air-test-utils" name = "air-test-utils"
version = "0.3.0" version = "0.4.0"
description = "Test utils for the AIR interpreter" description = "Test utils for the AIR interpreter"
authors = ["Fluence Labs"] authors = ["Fluence Labs"]
edition = "2018" edition = "2018"
@ -26,5 +26,8 @@ once_cell = "1.16.0"
semver = "1.0.14" semver = "1.0.14"
serde_json = "1.0.89" serde_json = "1.0.89"
[dev-dependencies]
maplit = "1.0.2"
[features] [features]
test_with_native_code = [] test_with_native_code = []

View File

@ -38,19 +38,23 @@ impl AirRunner for NativeAirRunner {
init_peer_id: impl Into<String>, init_peer_id: impl Into<String>,
timestamp: u64, timestamp: u64,
ttl: u32, ttl: u32,
override_current_peer_id: Option<String>,
call_results: avm_server::CallResults, call_results: avm_server::CallResults,
) -> Result<RawAVMOutcome, Box<dyn std::error::Error>> { ) -> Result<RawAVMOutcome, Box<dyn std::error::Error>> {
// some inner parts transformations // some inner parts transformations
let raw_call_results = into_raw_result(call_results); let raw_call_results = into_raw_result(call_results);
let raw_call_results = serde_json::to_vec(&raw_call_results).unwrap(); let raw_call_results = serde_json::to_vec(&raw_call_results).unwrap();
let current_peer_id =
override_current_peer_id.unwrap_or_else(|| self.current_peer_id.clone());
let outcome = air::execute_air( let outcome = air::execute_air(
air.into(), air.into(),
prev_data.into(), prev_data.into(),
data.into(), data.into(),
RunParameters { RunParameters {
init_peer_id: init_peer_id.into(), init_peer_id: init_peer_id.into(),
current_peer_id: self.current_peer_id.clone(), current_peer_id,
timestamp, timestamp,
ttl, ttl,
}, },

View File

@ -37,6 +37,7 @@ pub trait AirRunner {
init_peer_id: impl Into<String>, init_peer_id: impl Into<String>,
timestamp: u64, timestamp: u64,
ttl: u32, ttl: u32,
override_current_peer_id: Option<String>,
call_results: avm_server::CallResults, call_results: avm_server::CallResults,
) -> Result<RawAVMOutcome, Box<dyn std::error::Error>>; ) -> Result<RawAVMOutcome, Box<dyn std::error::Error>>;
} }
@ -51,6 +52,7 @@ pub struct TestRunParameters {
pub init_peer_id: String, pub init_peer_id: String,
pub timestamp: u64, pub timestamp: u64,
pub ttl: u32, pub ttl: u32,
pub override_current_peer_id: Option<String>,
} }
impl<R: AirRunner> TestRunner<R> { impl<R: AirRunner> TestRunner<R> {
@ -69,6 +71,7 @@ impl<R: AirRunner> TestRunner<R> {
init_peer_id, init_peer_id,
timestamp, timestamp,
ttl, ttl,
override_current_peer_id,
} = test_run_params; } = test_run_params;
let mut call_results = HashMap::new(); let mut call_results = HashMap::new();
@ -84,6 +87,7 @@ impl<R: AirRunner> TestRunner<R> {
init_peer_id.clone(), init_peer_id.clone(),
timestamp, timestamp,
ttl, ttl,
override_current_peer_id.clone(),
call_results, call_results,
) )
.map_err(|e| e.to_string())?; .map_err(|e| e.to_string())?;
@ -128,6 +132,7 @@ impl TestRunParameters {
init_peer_id: init_peer_id.into(), init_peer_id: init_peer_id.into(),
timestamp, timestamp,
ttl, ttl,
override_current_peer_id: None,
} }
} }
@ -136,6 +141,7 @@ impl TestRunParameters {
init_peer_id: init_peer_id.into(), init_peer_id: init_peer_id.into(),
timestamp: 0, timestamp: 0,
ttl: 0, ttl: 0,
override_current_peer_id: None,
} }
} }
@ -144,6 +150,7 @@ impl TestRunParameters {
init_peer_id: String::new(), init_peer_id: String::new(),
timestamp, timestamp,
ttl: 0, ttl: 0,
override_current_peer_id: None,
} }
} }
@ -152,6 +159,73 @@ impl TestRunParameters {
init_peer_id: String::new(), init_peer_id: String::new(),
timestamp: 0, timestamp: 0,
ttl, ttl,
override_current_peer_id: None,
} }
} }
} }
#[cfg(test)]
mod tests {
use super::*;
use crate::call_services::{set_variables_call_service, VariableOptionSource};
use avm_interface::CallRequestParams;
use fstrings::f;
use fstrings::format_args_f;
use serde_json::json;
#[test]
fn test_override_current_peer_id() {
let spell_id = "spell_id";
let host_peer_id = "host_peer_id";
let script = f!(r#"(call "{}" ("service" "func") [])"#, spell_id);
let variables = maplit::hashmap! {
"func".to_owned() => json!("success"),
};
let mut client = create_avm(
set_variables_call_service(variables, VariableOptionSource::FunctionName),
host_peer_id,
);
let current_result_1 = client
.runner
.call(&script, "", "", spell_id, 0, 0, None, HashMap::new())
.expect("call should be success");
let expected_current_call_requests = HashMap::new();
let expected_current_next_peers_pks = vec![spell_id.to_owned()];
assert_eq!(
current_result_1.call_requests,
expected_current_call_requests
);
assert_eq!(
current_result_1.next_peer_pks,
expected_current_next_peers_pks
);
let spell_result_1 = client
.runner
.call(
script,
"",
"",
spell_id,
0,
0,
Some(spell_id.to_owned()),
HashMap::new(),
)
.expect("call should be success");
let expected_spell_call_requests = maplit::hashmap! {
1 => CallRequestParams::new("service", "func", vec![], vec![]),
};
let expected_spell_next_peers_pks = Vec::<String>::new();
assert_eq!(spell_result_1.call_requests, expected_spell_call_requests);
assert_eq!(spell_result_1.next_peer_pks, expected_spell_next_peers_pks);
}
}

View File

@ -24,15 +24,16 @@ use std::path::PathBuf;
const AVM_MAX_HEAP_SIZE: u64 = 10 * 1024 * 1024; const AVM_MAX_HEAP_SIZE: u64 = 10 * 1024 * 1024;
const AIR_WASM_PATH: &str = "../target/wasm32-wasi/debug/air_interpreter_server.wasm"; const AIR_WASM_PATH: &str = "../target/wasm32-wasi/debug/air_interpreter_server.wasm";
pub struct WasmAirRunner(object_pool::Reusable<'static, AVMRunner>); pub struct WasmAirRunner {
current_peer_id: String,
runner: object_pool::Reusable<'static, AVMRunner>,
}
fn make_pooled_avm_runner() -> AVMRunner { fn make_pooled_avm_runner() -> AVMRunner {
let fake_current_peer_id = "";
let logging_mask = i32::MAX; let logging_mask = i32::MAX;
AVMRunner::new( AVMRunner::new(
PathBuf::from(AIR_WASM_PATH), PathBuf::from(AIR_WASM_PATH),
fake_current_peer_id,
Some(AVM_MAX_HEAP_SIZE), Some(AVM_MAX_HEAP_SIZE),
logging_mask, logging_mask,
) )
@ -51,10 +52,12 @@ impl AirRunner for WasmAirRunner {
) )
}); });
let mut runner = pool.pull(make_pooled_avm_runner); let runner = pool.pull(make_pooled_avm_runner);
runner.set_peer_id(current_peer_id);
Self(runner) Self {
current_peer_id: current_peer_id.into(),
runner,
}
} }
fn call( fn call(
@ -65,15 +68,20 @@ impl AirRunner for WasmAirRunner {
init_peer_id: impl Into<String>, init_peer_id: impl Into<String>,
timestamp: u64, timestamp: u64,
ttl: u32, ttl: u32,
override_current_peer_id: Option<String>,
call_results: avm_server::CallResults, call_results: avm_server::CallResults,
) -> Result<RawAVMOutcome, Box<dyn std::error::Error>> { ) -> Result<RawAVMOutcome, Box<dyn std::error::Error>> {
Ok(self.0.call( let current_peer_id =
override_current_peer_id.unwrap_or_else(|| self.current_peer_id.clone());
Ok(self.runner.call(
air, air,
prev_data, prev_data,
data, data,
init_peer_id, init_peer_id,
timestamp, timestamp,
ttl, ttl,
current_peer_id,
call_results, call_results,
)?) )?)
} }

View File

@ -10,7 +10,6 @@ Executes an AIR script with data in WASM AquaVM. It has two modes of parameter
All common parameters are optional. Their position is before the mode selector (`--plain` or `--anomaly`). All common parameters are optional. Their position is before the mode selector (`--plain` or `--anomaly`).
+ `--call-results PATH` parameter allows you to provide call results for current execution. + `--call-results PATH` parameter allows you to provide call results for current execution.
+ `--current-peer-id STR` by default is "some_id".
+ `--max-heap-size N` defines maximum heap size for WASM runtime. + `--max-heap-size N` defines maximum heap size for WASM runtime.
+ `--interpreter PATH` option defines the AquaVM WASM binary to be executed. By default, it is "target/wasm32-wasi/release/air_interpreter_server.wasm", but you can define a global value with the `AIR_INTERPRETER_WASM_PATH` environment variable. The default presumes that the tool is run from the root of this repository. Feel free to use option or environment variable to run from any location. + `--interpreter PATH` option defines the AquaVM WASM binary to be executed. By default, it is "target/wasm32-wasi/release/air_interpreter_server.wasm", but you can define a global value with the `AIR_INTERPRETER_WASM_PATH` environment variable. The default presumes that the tool is run from the root of this repository. Feel free to use option or environment variable to run from any location.
+ with the `--json` option, tracing info is output (to stderr) in machine-readable JSON format. The output can be later processed with `air-trace stats` subcommand. + with the `--json` option, tracing info is output (to stderr) in machine-readable JSON format. The output can be later processed with `air-trace stats` subcommand.

View File

@ -31,9 +31,6 @@ use std::path::{Path, PathBuf};
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[clap(about = "Run AIR script with AquaVM")] #[clap(about = "Run AIR script with AquaVM")]
pub(crate) struct Args { pub(crate) struct Args {
#[clap(long)]
current_peer_id: Option<String>,
#[clap(long = "call-results")] #[clap(long = "call-results")]
call_results_path: Option<PathBuf>, call_results_path: Option<PathBuf>,
@ -82,13 +79,7 @@ pub(crate) fn run(args: Args) -> anyhow::Result<()> {
let global_tracing_params = args.tracing_params.clone(); let global_tracing_params = args.tracing_params.clone();
init_tracing(global_tracing_params, tracing_json); init_tracing(global_tracing_params, tracing_json);
let current_peer_id = args.current_peer_id.as_deref().unwrap_or("some_id"); let mut runner = get_runner(args.native, &args.air_interpreter_path, args.max_heap_size)?;
let mut runner = get_runner(
args.native,
current_peer_id,
&args.air_interpreter_path,
args.max_heap_size,
)?;
let execution_data = match &args.source { let execution_data = match &args.source {
Source::Anomaly(anomaly) => data::anomaly::load(anomaly)?, Source::Anomaly(anomaly) => data::anomaly::load(anomaly)?,
@ -108,6 +99,7 @@ pub(crate) fn run(args: Args) -> anyhow::Result<()> {
particle.init_peer_id.clone().into_owned(), particle.init_peer_id.clone().into_owned(),
particle.timestamp, particle.timestamp,
particle.ttl, particle.ttl,
particle.current_peer_id.clone().into(),
call_results.clone(), call_results.clone(),
args.tracing_params.clone(), args.tracing_params.clone(),
tracing_json, tracing_json,
@ -124,20 +116,14 @@ pub(crate) fn run(args: Args) -> anyhow::Result<()> {
#[cfg(feature = "wasm")] #[cfg(feature = "wasm")]
fn get_runner( fn get_runner(
native: bool, native: bool,
current_peer_id: impl Into<String>,
air_interpreter_wasm_path: &Path, air_interpreter_wasm_path: &Path,
max_heap_size: Option<u64>, max_heap_size: Option<u64>,
) -> anyhow::Result<Box<dyn AirRunner>> { ) -> anyhow::Result<Box<dyn AirRunner>> {
if native { if native {
self::native::create_native_avm_runner(current_peer_id) self::native::create_native_avm_runner().context("Failed to instantiate a native AVM")
.context("Failed to instantiate a native AVM")
} else { } else {
self::wasm::create_wasm_avm_runner( self::wasm::create_wasm_avm_runner(air_interpreter_wasm_path, max_heap_size)
current_peer_id, .context("Failed to instantiate WASM AVM")
air_interpreter_wasm_path,
max_heap_size,
)
.context("Failed to instantiate WASM AVM")
} }
} }

View File

@ -39,7 +39,7 @@ pub(crate) fn load(args: &AnomalyDataArgs) -> anyhow::Result<super::ExecutionDat
.context("Anomaly current_data is not a valid string")?; .context("Anomaly current_data is not a valid string")?;
let current_data = String::from_utf8(anomaly_data.current_data.to_vec()) let current_data = String::from_utf8(anomaly_data.current_data.to_vec())
.context("Anomaly current_data is not a valid string")?; .context("Anomaly current_data is not a valid string")?;
let particle: ParticleParameters<'static, 'static> = let particle: ParticleParameters<'static> =
serde_json::from_reader(&*anomaly_data.particle.to_vec()) serde_json::from_reader(&*anomaly_data.particle.to_vec())
.context("Anomaly particle is not a valid JSON")?; .context("Anomaly particle is not a valid JSON")?;

View File

@ -23,5 +23,5 @@ pub(crate) struct ExecutionData<'ctx> {
pub(crate) air_script: String, pub(crate) air_script: String,
pub(crate) current_data: String, pub(crate) current_data: String,
pub(crate) prev_data: String, pub(crate) prev_data: String,
pub(crate) particle: ParticleParameters<'ctx, 'ctx>, pub(crate) particle: ParticleParameters<'ctx>,
} }

View File

@ -26,12 +26,14 @@ const DEFAULT_DATA: &str = "";
#[derive(clap::Args, Debug)] #[derive(clap::Args, Debug)]
pub(crate) struct PlainDataArgs { pub(crate) struct PlainDataArgs {
#[clap(long)] #[clap(long, default_value = "some_id")]
init_peer_id: Option<String>, init_peer_id: String,
#[clap(long, help = "default: current time")] #[clap(long, help = "default: current time")]
timestamp: Option<u64>, timestamp: Option<u64>,
#[clap(long, help = "default: max possible ttl")] #[clap(long, help = "default: max possible ttl")]
ttl: Option<u32>, ttl: Option<u32>,
#[clap(long, default_value = "some_id")]
current_peer_id: String,
#[clap(long = "script", help = "read from stdin by default")] #[clap(long = "script", help = "read from stdin by default")]
air_script_path: Option<PathBuf>, air_script_path: Option<PathBuf>,
@ -54,9 +56,17 @@ pub(crate) fn load(args: &PlainDataArgs) -> anyhow::Result<ExecutionData<'_>> {
let timestamp = args.timestamp.unwrap_or_else(unix_timestamp_now); let timestamp = args.timestamp.unwrap_or_else(unix_timestamp_now);
let ttl = args.ttl.unwrap_or(u32::MAX); let ttl = args.ttl.unwrap_or(u32::MAX);
let init_peer_id = args.init_peer_id.as_deref().unwrap_or("some_id"); let init_peer_id = &args.init_peer_id;
let current_peer_id = &args.current_peer_id;
let particle = ParticleParameters::new(
init_peer_id.into(),
"".into(),
timestamp,
ttl,
current_peer_id.into(),
);
let particle = ParticleParameters::new(init_peer_id.into(), "".into(), timestamp, ttl);
Ok(ExecutionData { Ok(ExecutionData {
air_script, air_script,
prev_data, prev_data,

View File

@ -18,9 +18,7 @@ use super::runner::AirRunner;
use air_interpreter_interface::RunParameters; use air_interpreter_interface::RunParameters;
use avm_interface::raw_outcome::RawAVMOutcome; use avm_interface::raw_outcome::RawAVMOutcome;
struct NativeAvmRunner { struct NativeAvmRunner {}
current_peer_id: String,
}
impl AirRunner for NativeAvmRunner { impl AirRunner for NativeAvmRunner {
fn call_tracing( fn call_tracing(
@ -31,6 +29,7 @@ impl AirRunner for NativeAvmRunner {
init_peer_id: String, init_peer_id: String,
timestamp: u64, timestamp: u64,
ttl: u32, ttl: u32,
current_peer_id: String,
call_results: avm_interface::CallResults, call_results: avm_interface::CallResults,
// We use externally configured logger. // We use externally configured logger.
_tracing_params: String, _tracing_params: String,
@ -48,7 +47,7 @@ impl AirRunner for NativeAvmRunner {
data, data,
RunParameters { RunParameters {
init_peer_id, init_peer_id,
current_peer_id: self.current_peer_id.clone(), current_peer_id,
timestamp, timestamp,
ttl, ttl,
}, },
@ -60,10 +59,6 @@ impl AirRunner for NativeAvmRunner {
} }
} }
pub(crate) fn create_native_avm_runner( pub(crate) fn create_native_avm_runner() -> anyhow::Result<Box<dyn AirRunner>> {
current_peer_id: impl Into<String>, Ok(Box::new(NativeAvmRunner {}))
) -> anyhow::Result<Box<dyn AirRunner>> {
Ok(Box::new(NativeAvmRunner {
current_peer_id: current_peer_id.into(),
}))
} }

View File

@ -27,6 +27,7 @@ pub(crate) trait AirRunner {
init_peer_id: String, init_peer_id: String,
timestamp: u64, timestamp: u64,
ttl: u32, ttl: u32,
current_peer_id: String,
call_results: CallResults, call_results: CallResults,
tracing_params: String, tracing_params: String,
tracing_output_mode: u8, tracing_output_mode: u8,

View File

@ -28,6 +28,7 @@ impl AirRunner for WasmAvmRunner {
init_peer_id: String, init_peer_id: String,
timestamp: u64, timestamp: u64,
ttl: u32, ttl: u32,
current_peer_id: String,
call_results: avm_interface::CallResults, call_results: avm_interface::CallResults,
tracing_params: String, tracing_params: String,
tracing_output_mode: u8, tracing_output_mode: u8,
@ -39,6 +40,7 @@ impl AirRunner for WasmAvmRunner {
init_peer_id, init_peer_id,
timestamp, timestamp,
ttl, ttl,
current_peer_id,
call_results, call_results,
tracing_params, tracing_params,
tracing_output_mode, tracing_output_mode,
@ -47,15 +49,11 @@ impl AirRunner for WasmAvmRunner {
} }
pub(crate) fn create_wasm_avm_runner( pub(crate) fn create_wasm_avm_runner(
current_peer_id: impl Into<String>,
air_interpreter_wasm_path: &Path, air_interpreter_wasm_path: &Path,
max_heap_size: Option<u64>, max_heap_size: Option<u64>,
) -> anyhow::Result<Box<dyn AirRunner>> { ) -> anyhow::Result<Box<dyn AirRunner>> {
let current_peer_id = current_peer_id.into();
Ok(Box::new(WasmAvmRunner(AVMRunner::new( Ok(Box::new(WasmAvmRunner(AVMRunner::new(
air_interpreter_wasm_path.to_owned(), air_interpreter_wasm_path.to_owned(),
current_peer_id,
max_heap_size, max_heap_size,
0, 0,
)?))) )?)))