mirror of
https://github.com/fluencelabs/aquavm
synced 2025-04-24 14:52:15 +00:00
feat(air,air-cli): pretty-printing binary interpreter data (#794)
Add new interpreter method `to_human_readable_data` and `air data` subcommand to convert binary data to JSON with indentation.
This commit is contained in:
parent
0a680f8d2e
commit
d6b1da9bdc
102
Cargo.lock
generated
102
Cargo.lock
generated
@ -40,7 +40,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -61,7 +61,7 @@ checksum = "7c7db3d5a9718568e4cf4a537cfd7070e6e6ff7481510d0237fb529ac850f6d3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -192,7 +192,7 @@ dependencies = [
|
||||
"polyplets",
|
||||
"rkyv",
|
||||
"rmp-serde",
|
||||
"semver 1.0.20",
|
||||
"semver 1.0.21",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"serde_json",
|
||||
@ -285,7 +285,7 @@ dependencies = [
|
||||
"object-pool",
|
||||
"once_cell",
|
||||
"rand_chacha 0.3.1",
|
||||
"semver 1.0.20",
|
||||
"semver 1.0.21",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.8",
|
||||
@ -455,7 +455,7 @@ dependencies = [
|
||||
"polyplets",
|
||||
"pretty_assertions 0.6.1",
|
||||
"rkyv",
|
||||
"semver 1.0.20",
|
||||
"semver 1.0.21",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum",
|
||||
@ -470,6 +470,7 @@ name = "aquavm-air-cli"
|
||||
version = "0.6.1"
|
||||
dependencies = [
|
||||
"air-beautifier",
|
||||
"air-interpreter-data",
|
||||
"air-interpreter-interface",
|
||||
"air-interpreter-sede",
|
||||
"air-test-utils",
|
||||
@ -483,6 +484,7 @@ dependencies = [
|
||||
"fluence-keypair",
|
||||
"itertools",
|
||||
"near-sdk",
|
||||
"semver 1.0.21",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"termcolor",
|
||||
@ -701,7 +703,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -718,7 +720,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1060,7 +1062,7 @@ dependencies = [
|
||||
"proc-macro-crate 2.0.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
"syn_derive",
|
||||
]
|
||||
|
||||
@ -1411,7 +1413,7 @@ dependencies = [
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1452,7 +1454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f76990911f2267d837d9d0ad060aa63aaad170af40904b29461734c339030d4d"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1878,7 +1880,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1902,7 +1904,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1913,7 +1915,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1981,7 +1983,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2202,7 +2204,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3405,7 +3407,7 @@ dependencies = [
|
||||
"multimap 0.8.3",
|
||||
"once_cell",
|
||||
"paste",
|
||||
"semver 1.0.20",
|
||||
"semver 1.0.21",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"wasmer-interface-types-fl",
|
||||
@ -3450,7 +3452,7 @@ dependencies = [
|
||||
"marine-module-interface",
|
||||
"marine-wasm-backend-traits",
|
||||
"nom",
|
||||
"semver 1.0.20",
|
||||
"semver 1.0.21",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"walrus 0.20.3",
|
||||
@ -3500,7 +3502,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a84be3c30abaa13df50cdaceb6b62ca806ac8a10fd5bacfeb4371ec1bd0f5101"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"semver 1.0.20",
|
||||
"semver 1.0.21",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3514,7 +3516,7 @@ dependencies = [
|
||||
"derivative",
|
||||
"marine-rs-sdk-main",
|
||||
"marine-wasm-backend-traits",
|
||||
"semver 1.0.20",
|
||||
"semver 1.0.21",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"walrus 0.20.3",
|
||||
@ -3530,7 +3532,7 @@ dependencies = [
|
||||
"itertools",
|
||||
"marine-it-interfaces",
|
||||
"nom",
|
||||
"semver 1.0.20",
|
||||
"semver 1.0.21",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"walrus 0.19.0",
|
||||
@ -3863,7 +3865,7 @@ checksum = "e4ac4e2d843390b1a007ad206022b4252d0fe3756d8b6609bc025cce07949bc5"
|
||||
dependencies = [
|
||||
"borsh 1.1.2",
|
||||
"schemars",
|
||||
"semver 1.0.20",
|
||||
"semver 1.0.21",
|
||||
"serde",
|
||||
]
|
||||
|
||||
@ -4188,7 +4190,7 @@ checksum = "84c1eda300e2e78f4f945ae58117d49e806899f4a51ee2faa09eda5ebc2e6571"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"serde",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4211,7 +4213,7 @@ dependencies = [
|
||||
"fs2",
|
||||
"near-rpc-error-core 0.17.0",
|
||||
"serde",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4269,7 +4271,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4524,7 +4526,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4716,7 +4718,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4944,9 +4946,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.70"
|
||||
version = "1.0.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
|
||||
checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@ -5071,9 +5073,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@ -5467,7 +5469,7 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver 1.0.20",
|
||||
"semver 1.0.21",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5654,18 +5656,18 @@ checksum = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.20"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
|
||||
checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.193"
|
||||
version = "1.0.195"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
|
||||
checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
@ -5691,13 +5693,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.193"
|
||||
version = "1.0.195"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
||||
checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5730,7 +5732,7 @@ checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5787,7 +5789,7 @@ dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5799,7 +5801,7 @@ dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -6079,9 +6081,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.41"
|
||||
version = "2.0.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269"
|
||||
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -6097,7 +6099,7 @@ dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -6231,7 +6233,7 @@ checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -6355,7 +6357,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -6562,7 +6564,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -7035,7 +7037,7 @@ dependencies = [
|
||||
"log",
|
||||
"nom",
|
||||
"safe-transmute",
|
||||
"semver 1.0.20",
|
||||
"semver 1.0.21",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
@ -7764,7 +7766,7 @@ checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -7784,7 +7786,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -88,3 +88,12 @@ pub fn invoke_tracing(
|
||||
pub fn ast(script: String) -> String {
|
||||
ast::ast(script)
|
||||
}
|
||||
|
||||
/// Like ast, this function is intended to be run localy by tools.
|
||||
#[marine]
|
||||
pub fn to_human_readable_data(data: Vec<u8>) -> String {
|
||||
match air::to_human_readable_data(data) {
|
||||
Ok(text) => text,
|
||||
Err(err) => err.to_string(),
|
||||
}
|
||||
}
|
||||
|
41
air/src/human_readable_data.rs
Normal file
41
air/src/human_readable_data.rs
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2024 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 crate::preparation_step::check_version_compatibility;
|
||||
|
||||
use air_interpreter_data::InterpreterData;
|
||||
use air_interpreter_data::InterpreterDataEnvelope;
|
||||
use serde_json::json;
|
||||
|
||||
use std::error::Error as StdError;
|
||||
|
||||
pub fn to_human_readable_data(data: Vec<u8>) -> Result<String, Box<dyn StdError>> {
|
||||
let envelope = InterpreterDataEnvelope::try_from_slice(&data)?;
|
||||
|
||||
check_version_compatibility(&envelope.versions)?;
|
||||
|
||||
let data = InterpreterData::try_from_slice(&envelope.inner_data)?;
|
||||
|
||||
// TODO convert value store strings to JSON
|
||||
let envelope_json = json!({
|
||||
"versions": envelope.versions,
|
||||
"data": data,
|
||||
});
|
||||
|
||||
// it may produce quite a big string (whitespaces, escaping, etc), but this function
|
||||
// is intended to be executed on user machine, not on chain or in a cloud.
|
||||
Ok(serde_json::to_string_pretty(&envelope_json)?)
|
||||
}
|
@ -28,6 +28,7 @@
|
||||
|
||||
mod execution_step;
|
||||
mod farewell_step;
|
||||
mod human_readable_data;
|
||||
mod preparation_step;
|
||||
mod runner;
|
||||
mod signing_step;
|
||||
@ -63,6 +64,7 @@ pub use preparation_step::min_supported_version;
|
||||
pub use preparation_step::PreparationError;
|
||||
pub use utils::ToErrorCode;
|
||||
|
||||
pub use crate::human_readable_data::to_human_readable_data;
|
||||
pub use crate::runner::execute_air;
|
||||
|
||||
pub mod interpreter_data {
|
||||
|
@ -22,6 +22,7 @@ pub use errors::PreparationError;
|
||||
pub use interpreter_versions::interpreter_version;
|
||||
pub use interpreter_versions::min_supported_version;
|
||||
|
||||
pub(crate) use preparation::check_version_compatibility;
|
||||
pub(crate) use preparation::parse_data;
|
||||
pub(crate) use preparation::prepare;
|
||||
pub(crate) use preparation::ParsedDataPair;
|
||||
|
@ -76,4 +76,8 @@ pub enum RunnerError {
|
||||
/// Invalid secret key.
|
||||
#[error(transparent)]
|
||||
KeyError(eyre::Error),
|
||||
|
||||
/// Errors from auxiliary calls.
|
||||
#[error("{0}")]
|
||||
Aux(String),
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
use crate::RunnerError;
|
||||
use crate::RunnerResult;
|
||||
|
||||
use air_interpreter_interface::try_as_string;
|
||||
use air_interpreter_interface::CallResultsRepr;
|
||||
use air_interpreter_interface::InterpreterOutcome;
|
||||
use air_interpreter_sede::ToSerialized;
|
||||
@ -171,6 +172,20 @@ impl AVMRunner {
|
||||
Ok(outcome)
|
||||
}
|
||||
|
||||
pub fn to_human_readable_data(&mut self, data: Vec<u8>) -> RunnerResult<String> {
|
||||
let args = vec![IValue::ByteArray(data)];
|
||||
|
||||
let result = self.marine.call_with_ivalues(
|
||||
&self.wasm_filename,
|
||||
"to_human_readable_data",
|
||||
&args,
|
||||
<_>::default(),
|
||||
)?;
|
||||
let result = try_as_one_value_vec(result)?;
|
||||
let outcome = try_as_string(result, "result").map_err(RunnerError::Aux)?;
|
||||
Ok(outcome)
|
||||
}
|
||||
|
||||
pub fn memory_stats(&self) -> AVMMemoryStats {
|
||||
let stats = self.marine.module_memory_stats();
|
||||
|
||||
|
@ -116,7 +116,7 @@ fn try_as_i64(ivalue: IValue, field_name: &str) -> Result<i64, String> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "marine")]
|
||||
fn try_as_string(ivalue: IValue, field_name: &str) -> Result<String, String> {
|
||||
pub fn try_as_string(ivalue: IValue, field_name: &str) -> Result<String, String> {
|
||||
match ivalue {
|
||||
IValue::String(value) => Ok(value),
|
||||
v => Err(format!("expected a string for {field_name}, got {v:?}")),
|
||||
|
@ -15,12 +15,14 @@ air-beautifier = { version = "0.4.1", path = "../../../crates/beautifier" }
|
||||
avm-data-store = { version = "0.7.5", path = "../../../crates/data-store" }
|
||||
avm-interface = { version = "0.31.0", path = "../../../avm/interface" }
|
||||
air-interpreter-interface = { version = "0.17.0", path = "../../../crates/air-lib/interpreter-interface", default-features = false }
|
||||
air-interpreter-data = { version = "0.16.0", path = "../../../crates/air-lib/interpreter-data" }
|
||||
air-interpreter-sede = { version = "0.1.0", path = "../../../crates/air-lib/interpreter-sede", default-features = false }
|
||||
air-test-utils = { version = "0.14.1",path = "../../../crates/air-lib/test-utils", optional = true }
|
||||
|
||||
anyhow = "1.0.79"
|
||||
clap = { version = "4.4.7", features = ["derive", "env"] }
|
||||
itertools = "0.10.5"
|
||||
semver = "1.0.21"
|
||||
serde = { version = "1.0.190", features = ["derive"] }
|
||||
serde_json = "1.0.108"
|
||||
tracing = "0.1.40"
|
||||
|
119
tools/cli/air/src/data.rs
Normal file
119
tools/cli/air/src/data.rs
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2024 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 anyhow::Context;
|
||||
use clap::Parser;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::trace::run::load_data;
|
||||
use crate::trace::run::runner::DataToHumanReadable;
|
||||
|
||||
#[derive(clap::Args, Debug, Copy, Clone)]
|
||||
#[group(multiple = false)]
|
||||
struct ModeArgs {
|
||||
#[arg(long)]
|
||||
native: bool,
|
||||
|
||||
#[cfg(feature = "wasm")]
|
||||
#[arg(long)]
|
||||
wasm: bool,
|
||||
}
|
||||
|
||||
enum Mode {
|
||||
Native,
|
||||
|
||||
#[cfg(feature = "wasm")]
|
||||
Wasm,
|
||||
}
|
||||
|
||||
impl From<ModeArgs> for Option<Mode> {
|
||||
fn from(value: ModeArgs) -> Self {
|
||||
if value.native {
|
||||
return Some(Mode::Native);
|
||||
}
|
||||
|
||||
#[cfg(feature = "wasm")]
|
||||
if value.wasm {
|
||||
return Some(Mode::Wasm);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(about = "Print human-readable AquaVM data")]
|
||||
pub(crate) struct Args {
|
||||
#[clap(
|
||||
long = "interpreter",
|
||||
env = "AIR_INTERPRETER_WASM_PATH",
|
||||
default_value = "target/wasm32-wasi/release/air_interpreter_server.wasm"
|
||||
)]
|
||||
air_interpreter_path: PathBuf,
|
||||
|
||||
#[clap(flatten)]
|
||||
mode: ModeArgs,
|
||||
// TODO be able to read from stdin
|
||||
#[arg(help = "Input path")]
|
||||
input: PathBuf,
|
||||
}
|
||||
|
||||
pub(crate) fn to_human_readable_data(args: Args) -> Result<(), Box<dyn std::error::Error>> {
|
||||
init_tracing("warn");
|
||||
|
||||
let data: Vec<u8> = load_data(&args.input)?;
|
||||
|
||||
if data.is_empty() {
|
||||
Err(anyhow::anyhow!("empty input data: {:?}", args.input))?;
|
||||
}
|
||||
|
||||
let mut runner = create_runner(args.mode.into(), &args.air_interpreter_path)?;
|
||||
let out = runner.to_human_readable(data)?;
|
||||
println!("{out}");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn init_tracing(tracing_params: &str) {
|
||||
let builder = tracing_subscriber::fmt()
|
||||
.with_env_filter(tracing_params)
|
||||
.with_writer(std::io::stderr);
|
||||
builder.init();
|
||||
}
|
||||
|
||||
fn create_runner(
|
||||
mode: Option<Mode>,
|
||||
_air_interpreter_wasm_path: &Path,
|
||||
) -> anyhow::Result<Box<dyn DataToHumanReadable>> {
|
||||
#[cfg(not(feature = "wasm"))]
|
||||
let default_mode = Mode::Native;
|
||||
#[cfg(feature = "wasm")]
|
||||
let default_mode = Mode::Wasm;
|
||||
|
||||
let mode = mode.unwrap_or(default_mode);
|
||||
let runner = match mode {
|
||||
Mode::Native => crate::trace::run::native::create_native_avm_runner()
|
||||
.context("Failed to instantiate a native AVM")? as _,
|
||||
#[cfg(feature = "wasm")]
|
||||
Mode::Wasm => {
|
||||
crate::trace::run::wasm::create_wasm_avm_runner(_air_interpreter_wasm_path, None)
|
||||
.context("Failed to instantiate WASM AVM")? as _
|
||||
}
|
||||
};
|
||||
|
||||
Ok(runner)
|
||||
}
|
@ -27,6 +27,7 @@
|
||||
)]
|
||||
|
||||
mod beautify;
|
||||
mod data;
|
||||
mod trace;
|
||||
|
||||
use clap::Parser;
|
||||
@ -42,17 +43,21 @@ struct Cli {
|
||||
enum Subcommand {
|
||||
#[clap(alias = "b")]
|
||||
Beautify(self::beautify::Args),
|
||||
#[clap(alias = "d")]
|
||||
Data(self::data::Args),
|
||||
#[clap(alias = "r")]
|
||||
Run(self::trace::run::Args),
|
||||
#[clap(alias = "s")]
|
||||
Stats(self::trace::stats::Args),
|
||||
}
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let args = Cli::parse();
|
||||
match args.subcommand {
|
||||
Subcommand::Run(args) => self::trace::run::run(args),
|
||||
Subcommand::Stats(args) => self::trace::stats::stats(args),
|
||||
Subcommand::Beautify(args) => self::beautify::beautify(args),
|
||||
Subcommand::Beautify(args) => self::beautify::beautify(args)?,
|
||||
Subcommand::Data(args) => self::data::to_human_readable_data(args)?,
|
||||
Subcommand::Run(args) => self::trace::run::run(args)?,
|
||||
Subcommand::Stats(args) => self::trace::stats::stats(args)?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -15,27 +15,28 @@
|
||||
*/
|
||||
|
||||
mod data;
|
||||
mod native;
|
||||
pub(crate) mod native;
|
||||
#[cfg(feature = "near")]
|
||||
mod near;
|
||||
#[cfg(feature = "risc0")]
|
||||
mod risc0;
|
||||
mod runner;
|
||||
#[cfg(feature = "wasm")]
|
||||
mod wasm;
|
||||
pub(crate) mod wasm;
|
||||
|
||||
pub(crate) mod runner;
|
||||
|
||||
use self::runner::AirRunner;
|
||||
use avm_interface::CallResults;
|
||||
|
||||
use anyhow::Context as _;
|
||||
use clap::{Parser, Subcommand};
|
||||
use clap::Parser;
|
||||
use clap::Subcommand;
|
||||
use fluence_keypair::KeyPair;
|
||||
use zeroize::Zeroize;
|
||||
|
||||
use std::{
|
||||
io::Read,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use std::io::Read;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[clap(about = "Run AIR script with AquaVM")]
|
||||
@ -241,21 +242,21 @@ fn create_runner(
|
||||
let default_mode = Mode::Wasm;
|
||||
|
||||
let mode = mode.unwrap_or(default_mode);
|
||||
match mode {
|
||||
Mode::Native => {
|
||||
self::native::create_native_avm_runner().context("Failed to instantiate a native AVM")
|
||||
}
|
||||
let runner = match mode {
|
||||
Mode::Native => self::native::create_native_avm_runner()
|
||||
.context("Failed to instantiate a native AVM")? as _,
|
||||
#[cfg(feature = "wasm")]
|
||||
Mode::Wasm => {
|
||||
self::wasm::create_wasm_avm_runner(_air_interpreter_wasm_path, _max_heap_size)
|
||||
.context("Failed to instantiate WASM AVM")
|
||||
.context("Failed to instantiate WASM AVM")? as _
|
||||
}
|
||||
#[cfg(feature = "near")]
|
||||
Mode::Near => self::near::create_near_runner(_air_contract_wasm_path)
|
||||
.context("Failed to instantiate NEAR AVM"),
|
||||
.context("Failed to instantiate NEAR AVM")?,
|
||||
#[cfg(feature = "risc0")]
|
||||
Mode::Risc0 => Ok(Box::new(self::risc0::Risc0Runner::new())),
|
||||
}
|
||||
Mode::Risc0 => Box::new(self::risc0::Risc0Runner::new()),
|
||||
};
|
||||
Ok(runner)
|
||||
}
|
||||
|
||||
// TODO This is a copy of function from air_interpreter/marine.rs. It should be moved to the marine_rs_sdk.
|
||||
@ -297,8 +298,8 @@ fn load_data_or_default(
|
||||
}
|
||||
}
|
||||
|
||||
fn load_data(data_path: &Path) -> anyhow::Result<Vec<u8>> {
|
||||
Ok(std::fs::read(data_path)?)
|
||||
pub(crate) fn load_data(data_path: &Path) -> anyhow::Result<Vec<u8>> {
|
||||
std::fs::read(data_path).with_context(|| data_path.to_string_lossy().into_owned())
|
||||
}
|
||||
|
||||
fn load_keypair_ed25519(path: &PathBuf) -> Result<KeyPair, anyhow::Error> {
|
||||
|
@ -15,12 +15,15 @@
|
||||
*/
|
||||
|
||||
use super::runner::AirRunner;
|
||||
use super::runner::DataToHumanReadable;
|
||||
use air_interpreter_interface::CallResultsRepr;
|
||||
use air_interpreter_interface::RunParameters;
|
||||
use avm_interface::raw_outcome::RawAVMOutcome;
|
||||
use fluence_keypair::KeyPair;
|
||||
|
||||
struct NativeAvmRunner {}
|
||||
use std::error::Error as StdError;
|
||||
|
||||
pub(crate) struct NativeAvmRunner {}
|
||||
|
||||
impl AirRunner for NativeAvmRunner {
|
||||
fn call_tracing(
|
||||
@ -70,6 +73,12 @@ impl AirRunner for NativeAvmRunner {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create_native_avm_runner() -> anyhow::Result<Box<dyn AirRunner>> {
|
||||
impl DataToHumanReadable for NativeAvmRunner {
|
||||
fn to_human_readable(&mut self, data: Vec<u8>) -> Result<String, Box<dyn StdError>> {
|
||||
air::to_human_readable_data(data)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create_native_avm_runner() -> anyhow::Result<Box<NativeAvmRunner>> {
|
||||
Ok(Box::new(NativeAvmRunner {}))
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ use avm_interface::raw_outcome::RawAVMOutcome;
|
||||
use avm_interface::CallResults;
|
||||
use fluence_keypair::KeyPair;
|
||||
|
||||
use std::error::Error as StdError;
|
||||
|
||||
pub(crate) trait AirRunner {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn call_tracing(
|
||||
@ -36,3 +38,7 @@ pub(crate) trait AirRunner {
|
||||
particle_id: String,
|
||||
) -> anyhow::Result<RawAVMOutcome>;
|
||||
}
|
||||
|
||||
pub(crate) trait DataToHumanReadable {
|
||||
fn to_human_readable(&mut self, data: Vec<u8>) -> Result<String, Box<dyn StdError>>;
|
||||
}
|
||||
|
@ -13,9 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::runner::AirRunner;
|
||||
use super::runner::DataToHumanReadable;
|
||||
use air_test_utils::avm_runner::AVMRunner;
|
||||
use fluence_keypair::KeyPair;
|
||||
|
||||
use std::error::Error as StdError;
|
||||
use std::path::Path;
|
||||
|
||||
pub(crate) struct WasmAvmRunner(AVMRunner);
|
||||
@ -58,10 +62,16 @@ impl AirRunner for WasmAvmRunner {
|
||||
}
|
||||
}
|
||||
|
||||
impl DataToHumanReadable for WasmAvmRunner {
|
||||
fn to_human_readable(&mut self, data: Vec<u8>) -> Result<String, Box<dyn StdError>> {
|
||||
Ok(self.0.to_human_readable_data(data)?)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create_wasm_avm_runner(
|
||||
air_interpreter_wasm_path: &Path,
|
||||
max_heap_size: Option<u64>,
|
||||
) -> anyhow::Result<Box<dyn AirRunner>> {
|
||||
) -> anyhow::Result<Box<WasmAvmRunner>> {
|
||||
Ok(Box::new(WasmAvmRunner(AVMRunner::new(
|
||||
air_interpreter_wasm_path.to_owned(),
|
||||
max_heap_size,
|
||||
|
Loading…
x
Reference in New Issue
Block a user