feat: handle errors in protocol-testing
This commit is contained in:
55
protocol-testing/Cargo.lock
generated
55
protocol-testing/Cargo.lock
generated
@@ -596,7 +596,7 @@ dependencies = [
|
|||||||
"alloy-serde",
|
"alloy-serde",
|
||||||
"alloy-sol-types",
|
"alloy-sol-types",
|
||||||
"arbitrary",
|
"arbitrary",
|
||||||
"itertools 0.13.0",
|
"itertools 0.14.0",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
@@ -909,7 +909,7 @@ checksum = "710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anstyle",
|
"anstyle",
|
||||||
"memchr",
|
"memchr",
|
||||||
"unicode-width",
|
"unicode-width 0.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1752,7 +1752,7 @@ dependencies = [
|
|||||||
"strsim",
|
"strsim",
|
||||||
"terminal_size",
|
"terminal_size",
|
||||||
"unicase",
|
"unicase",
|
||||||
"unicode-width",
|
"unicode-width 0.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1870,7 +1870,7 @@ checksum = "4a65ebfec4fb190b6f90e944a817d60499ee0744e582530e2c9900a22e591d9a"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
"unicode-width",
|
"unicode-width 0.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1882,7 +1882,7 @@ dependencies = [
|
|||||||
"encode_unicode",
|
"encode_unicode",
|
||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"unicode-width",
|
"unicode-width 0.2.0",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2382,7 +2382,7 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"option-ext",
|
"option-ext",
|
||||||
"redox_users",
|
"redox_users",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.60.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2919,7 +2919,7 @@ dependencies = [
|
|||||||
"foundry-compilers-core",
|
"foundry-compilers-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"home",
|
"home",
|
||||||
"itertools 0.13.0",
|
"itertools 0.14.0",
|
||||||
"path-slash",
|
"path-slash",
|
||||||
"rayon",
|
"rayon",
|
||||||
"semver 1.0.26",
|
"semver 1.0.26",
|
||||||
@@ -4020,7 +4020,7 @@ dependencies = [
|
|||||||
"console",
|
"console",
|
||||||
"number_prefix",
|
"number_prefix",
|
||||||
"portable-atomic",
|
"portable-atomic",
|
||||||
"unicode-width",
|
"unicode-width 0.2.0",
|
||||||
"web-time",
|
"web-time",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -4493,6 +4493,28 @@ dependencies = [
|
|||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miette"
|
||||||
|
version = "7.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5f98efec8807c63c752b5bd61f862c165c115b0a35685bdcfd9238c7aeb592b7"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"miette-derive",
|
||||||
|
"unicode-width 0.1.14",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miette-derive"
|
||||||
|
version = "7.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.99",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mime"
|
name = "mime"
|
||||||
version = "0.3.17"
|
version = "0.3.17"
|
||||||
@@ -5339,7 +5361,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"
|
checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"itertools 0.13.0",
|
"itertools 0.14.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.99",
|
"syn 2.0.99",
|
||||||
@@ -5376,6 +5398,7 @@ dependencies = [
|
|||||||
"dotenv",
|
"dotenv",
|
||||||
"figment",
|
"figment",
|
||||||
"hex",
|
"hex",
|
||||||
|
"miette",
|
||||||
"postgres",
|
"postgres",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -6723,7 +6746,7 @@ dependencies = [
|
|||||||
"derive_more 2.0.1",
|
"derive_more 2.0.1",
|
||||||
"dunce",
|
"dunce",
|
||||||
"inturn",
|
"inturn",
|
||||||
"itertools 0.13.0",
|
"itertools 0.14.0",
|
||||||
"itoa",
|
"itoa",
|
||||||
"match_cfg",
|
"match_cfg",
|
||||||
"normalize-path",
|
"normalize-path",
|
||||||
@@ -6734,7 +6757,7 @@ dependencies = [
|
|||||||
"solar-macros",
|
"solar-macros",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"tracing",
|
"tracing",
|
||||||
"unicode-width",
|
"unicode-width 0.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -6757,7 +6780,7 @@ dependencies = [
|
|||||||
"alloy-primitives",
|
"alloy-primitives",
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"itertools 0.13.0",
|
"itertools 0.14.0",
|
||||||
"memchr",
|
"memchr",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"num-rational",
|
"num-rational",
|
||||||
@@ -7122,7 +7145,7 @@ dependencies = [
|
|||||||
"getrandom 0.3.1",
|
"getrandom 0.3.1",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix 1.0.1",
|
"rustix 1.0.1",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.60.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -7891,6 +7914,12 @@ version = "1.12.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
miette = "7.6.0"
|
||||||
# Logging & Tracing
|
# Logging & Tracing
|
||||||
tracing = "0.1.37"
|
tracing = "0.1.37"
|
||||||
# Tycho dependencies
|
# Tycho dependencies
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ struct Args {
|
|||||||
vm_traces: bool,
|
vm_traces: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() -> miette::Result<()> {
|
||||||
tracing_subscriber::fmt()
|
tracing_subscriber::fmt()
|
||||||
.with_env_filter(EnvFilter::from_default_env())
|
.with_env_filter(EnvFilter::from_default_env())
|
||||||
.with_target(false)
|
.with_target(false)
|
||||||
@@ -40,5 +40,5 @@ fn main() {
|
|||||||
|
|
||||||
let test_runner = TestRunner::new(args.package, args.tycho_logs, args.db_url, args.vm_traces);
|
let test_runner = TestRunner::new(args.package, args.tycho_logs, args.db_url, args.vm_traces);
|
||||||
|
|
||||||
test_runner.run_tests();
|
test_runner.run_tests()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
use std::{collections::HashMap, env, path::PathBuf, str::FromStr};
|
use std::{collections::HashMap, env, path::PathBuf, str::FromStr};
|
||||||
use alloy::{primitives::U256};
|
|
||||||
|
use alloy::primitives::U256;
|
||||||
use figment::{
|
use figment::{
|
||||||
providers::{Format, Yaml},
|
providers::{Format, Yaml},
|
||||||
Figment,
|
Figment,
|
||||||
};
|
};
|
||||||
|
use miette::{miette, IntoDiagnostic, WrapErr};
|
||||||
use postgres::{Client, Error, NoTls};
|
use postgres::{Client, Error, NoTls};
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
use tracing::{debug, info};
|
use tracing::{debug, info};
|
||||||
use tycho_client::feed::BlockHeader;
|
use tycho_client::feed::BlockHeader;
|
||||||
use tycho_common::{
|
use tycho_common::{
|
||||||
dto::{Chain, ProtocolComponent, ResponseAccount, ResponseProtocolState},
|
dto::{Chain, ProtocolComponent, ResponseAccount, ResponseProtocolState},
|
||||||
|
models::token::Token,
|
||||||
Bytes,
|
Bytes,
|
||||||
models::token::Token
|
|
||||||
};
|
};
|
||||||
use tycho_simulation::{
|
use tycho_simulation::{
|
||||||
evm::{
|
evm::{
|
||||||
@@ -47,7 +49,7 @@ impl TestRunner {
|
|||||||
Self { package, tycho_logs, db_url, vm_traces, substreams_path }
|
Self { package, tycho_logs, db_url, vm_traces, substreams_path }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_tests(&self) {
|
pub fn run_tests(&self) -> miette::Result<()> {
|
||||||
info!("Running tests...");
|
info!("Running tests...");
|
||||||
let config_yaml_path = self
|
let config_yaml_path = self
|
||||||
.substreams_path
|
.substreams_path
|
||||||
@@ -56,20 +58,21 @@ impl TestRunner {
|
|||||||
info!("Config YAML: {}", config_yaml_path.display());
|
info!("Config YAML: {}", config_yaml_path.display());
|
||||||
let figment = Figment::new().merge(Yaml::file(&config_yaml_path));
|
let figment = Figment::new().merge(Yaml::file(&config_yaml_path));
|
||||||
|
|
||||||
match figment.extract::<IntegrationTestsConfig>() {
|
let config = figment
|
||||||
Ok(config) => {
|
.extract::<IntegrationTestsConfig>()
|
||||||
info!("Loaded test configuration:");
|
.into_diagnostic()
|
||||||
info!("Protocol types: {:?}", config.protocol_type_names);
|
.wrap_err("Failed to load test configuration:")?;
|
||||||
info!("Found {} tests to run", config.tests.len());
|
info!("Loaded test configuration:");
|
||||||
|
info!("Protocol types: {:?}", config.protocol_type_names);
|
||||||
|
info!("Found {} tests to run", config.tests.len());
|
||||||
|
|
||||||
for test in &config.tests {
|
for test in &config.tests {
|
||||||
self.run_test(test, &config, config.skip_balance_check);
|
if let Err(e) = self.run_test(test, &config, config.skip_balance_check) {
|
||||||
}
|
eprintln!("Test '{}' failed: {e}", test.name);
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("Failed to load test configuration: {}", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_test(
|
fn run_test(
|
||||||
@@ -77,10 +80,11 @@ impl TestRunner {
|
|||||||
test: &IntegrationTest,
|
test: &IntegrationTest,
|
||||||
config: &IntegrationTestsConfig,
|
config: &IntegrationTestsConfig,
|
||||||
skip_balance_check: bool,
|
skip_balance_check: bool,
|
||||||
) {
|
) -> miette::Result<()> {
|
||||||
info!("Running test: {}", test.name);
|
info!("Running test: {}", test.name);
|
||||||
self.empty_database()
|
self.empty_database()
|
||||||
.expect("Failed to empty the database");
|
.into_diagnostic()
|
||||||
|
.wrap_err("Failed to empty the database")?;
|
||||||
|
|
||||||
let substreams_yaml_path = self
|
let substreams_yaml_path = self
|
||||||
.substreams_path
|
.substreams_path
|
||||||
@@ -98,7 +102,7 @@ impl TestRunner {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let spkg_path =
|
let spkg_path =
|
||||||
build_spkg(&substreams_yaml_path, test.start_block).expect("Failed to build spkg");
|
build_spkg(&substreams_yaml_path, test.start_block).wrap_err("Failed to build spkg")?;
|
||||||
|
|
||||||
let tycho_runner =
|
let tycho_runner =
|
||||||
TychoRunner::new(self.db_url.clone(), initialized_accounts, self.tycho_logs);
|
TychoRunner::new(self.db_url.clone(), initialized_accounts, self.tycho_logs);
|
||||||
@@ -110,15 +114,17 @@ impl TestRunner {
|
|||||||
test.stop_block,
|
test.stop_block,
|
||||||
&config.protocol_type_names,
|
&config.protocol_type_names,
|
||||||
)
|
)
|
||||||
.expect("Failed to run Tycho");
|
.wrap_err("Failed to run Tycho")?;
|
||||||
|
|
||||||
tycho_runner.run_with_rpc_server(
|
let _ = tycho_runner.run_with_rpc_server(
|
||||||
validate_state,
|
validate_state,
|
||||||
&test.expected_components,
|
&test.expected_components,
|
||||||
test.start_block,
|
test.start_block,
|
||||||
test.stop_block,
|
test.stop_block,
|
||||||
skip_balance_check,
|
skip_balance_check,
|
||||||
);
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn empty_database(&self) -> Result<(), Error> {
|
fn empty_database(&self) -> Result<(), Error> {
|
||||||
@@ -144,12 +150,13 @@ fn validate_state(
|
|||||||
start_block: u64,
|
start_block: u64,
|
||||||
stop_block: u64,
|
stop_block: u64,
|
||||||
skip_balance_check: bool,
|
skip_balance_check: bool,
|
||||||
) {
|
) -> miette::Result<()> {
|
||||||
let rt = Runtime::new().unwrap();
|
let rt = Runtime::new().unwrap();
|
||||||
|
|
||||||
// Create Tycho client for the RPC server
|
// Create Tycho client for the RPC server
|
||||||
let tycho_client =
|
let tycho_client = TychoClient::new("http://localhost:4242")
|
||||||
TychoClient::new("http://localhost:4242").expect("Failed to create Tycho client");
|
.into_diagnostic()
|
||||||
|
.wrap_err("Failed to create Tycho client")?;
|
||||||
|
|
||||||
let chain = Chain::Ethereum;
|
let chain = Chain::Ethereum;
|
||||||
let protocol_system = "test_protocol";
|
let protocol_system = "test_protocol";
|
||||||
@@ -158,7 +165,8 @@ fn validate_state(
|
|||||||
// module, in order to simplify debugging
|
// module, in order to simplify debugging
|
||||||
let protocol_components = rt
|
let protocol_components = rt
|
||||||
.block_on(tycho_client.get_protocol_components(protocol_system, chain))
|
.block_on(tycho_client.get_protocol_components(protocol_system, chain))
|
||||||
.expect("Failed to get protocol components");
|
.into_diagnostic()
|
||||||
|
.wrap_err("Failed to get protocol components")?;
|
||||||
|
|
||||||
let expected_ids = expected_components
|
let expected_ids = expected_components
|
||||||
.iter()
|
.iter()
|
||||||
@@ -167,11 +175,13 @@ fn validate_state(
|
|||||||
|
|
||||||
let protocol_states = rt
|
let protocol_states = rt
|
||||||
.block_on(tycho_client.get_protocol_state(protocol_system, expected_ids, chain))
|
.block_on(tycho_client.get_protocol_state(protocol_system, expected_ids, chain))
|
||||||
.expect("Failed to get protocol state");
|
.into_diagnostic()
|
||||||
|
.wrap_err("Failed to get protocol state")?;
|
||||||
|
|
||||||
let vm_storages = rt
|
let vm_storages = rt
|
||||||
.block_on(tycho_client.get_contract_state(protocol_system, chain))
|
.block_on(tycho_client.get_contract_state(protocol_system, chain))
|
||||||
.expect("Failed to get contract state");
|
.into_diagnostic()
|
||||||
|
.wrap_err("Failed to get contract state")?;
|
||||||
|
|
||||||
// Create a map of component IDs to components for easy lookup
|
// Create a map of component IDs to components for easy lookup
|
||||||
let components_by_id: HashMap<String, ProtocolComponent> = protocol_components
|
let components_by_id: HashMap<String, ProtocolComponent> = protocol_components
|
||||||
@@ -210,7 +220,11 @@ fn validate_state(
|
|||||||
.compare(component, true);
|
.compare(component, true);
|
||||||
match diff {
|
match diff {
|
||||||
Some(diff) => {
|
Some(diff) => {
|
||||||
panic!("Component {} does not match the expected state:\n{}", component_id, diff);
|
return Err(miette!(
|
||||||
|
"Component {} does not match the expected state:\n{}",
|
||||||
|
component_id,
|
||||||
|
diff
|
||||||
|
));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
info!("Component {} matches the expected state", component_id);
|
info!("Component {} matches the expected state", component_id);
|
||||||
@@ -222,7 +236,9 @@ fn validate_state(
|
|||||||
// Step 2: Validate Token Balances
|
// Step 2: Validate Token Balances
|
||||||
// In this step, we validate that the token balances of the components match the values
|
// In this step, we validate that the token balances of the components match the values
|
||||||
// on-chain, extracted by querying the token balances using a node.
|
// on-chain, extracted by querying the token balances using a node.
|
||||||
let rpc_url = env::var("RPC_URL").expect("Missing ETH_RPC_URL in environment");
|
let rpc_url = env::var("RPC_URL")
|
||||||
|
.into_diagnostic()
|
||||||
|
.wrap_err("Missing ETH_RPC_URL in environment")?;
|
||||||
let rpc_provider = RPCProvider::new(rpc_url.to_string());
|
let rpc_provider = RPCProvider::new(rpc_url.to_string());
|
||||||
|
|
||||||
for (id, component) in components_by_id.iter() {
|
for (id, component) in components_by_id.iter() {
|
||||||
@@ -280,9 +296,10 @@ fn validate_state(
|
|||||||
let component_id = &id.clone();
|
let component_id = &id.clone();
|
||||||
let state = protocol_states_by_id
|
let state = protocol_states_by_id
|
||||||
.get(component_id)
|
.get(component_id)
|
||||||
.expect("Failed to get state for component")
|
.wrap_err("Failed to get state for component")?
|
||||||
.clone();
|
.clone();
|
||||||
let component_with_state = ComponentWithState { state, component, component_tvl: None, entrypoints: vec![] }; // TODO
|
let component_with_state =
|
||||||
|
ComponentWithState { state, component, component_tvl: None, entrypoints: vec![] }; // TODO
|
||||||
states.insert(component_id.clone(), component_with_state);
|
states.insert(component_id.clone(), component_with_state);
|
||||||
}
|
}
|
||||||
let vm_storage: HashMap<Bytes, ResponseAccount> = vm_storages
|
let vm_storage: HashMap<Bytes, ResponseAccount> = vm_storages
|
||||||
@@ -311,7 +328,8 @@ fn validate_state(
|
|||||||
|
|
||||||
let all_tokens = rt
|
let all_tokens = rt
|
||||||
.block_on(tycho_client.get_tokens(Chain::Ethereum, None, None))
|
.block_on(tycho_client.get_tokens(Chain::Ethereum, None, None))
|
||||||
.expect("Failed to get tokens");
|
.into_diagnostic()
|
||||||
|
.wrap_err("Failed to get tokens")?;
|
||||||
info!("Loaded {} tokens", all_tokens.len());
|
info!("Loaded {} tokens", all_tokens.len());
|
||||||
|
|
||||||
rt.block_on(decoder.set_tokens(all_tokens));
|
rt.block_on(decoder.set_tokens(all_tokens));
|
||||||
@@ -322,7 +340,8 @@ fn validate_state(
|
|||||||
|
|
||||||
let block_msg = rt
|
let block_msg = rt
|
||||||
.block_on(decoder.decode(message))
|
.block_on(decoder.decode(message))
|
||||||
.expect("Failed to decode message");
|
.into_diagnostic()
|
||||||
|
.wrap_err("Failed to decode message")?;
|
||||||
|
|
||||||
for (id, comp) in block_msg.new_pairs.iter() {
|
for (id, comp) in block_msg.new_pairs.iter() {
|
||||||
pairs
|
pairs
|
||||||
@@ -333,8 +352,8 @@ fn validate_state(
|
|||||||
// This is where we get blocked. Currently, Tycho Simulation expects the runtime to be
|
// This is where we get blocked. Currently, Tycho Simulation expects the runtime to be
|
||||||
// prebuild and accessible from TychoSim - we should allow passing it when parsing the block
|
// prebuild and accessible from TychoSim - we should allow passing it when parsing the block
|
||||||
|
|
||||||
// TODO: Since we don't have balances on the VM State, we could try to use Limits, otherwise ask the user
|
// TODO: Since we don't have balances on the VM State, we could try to use Limits, otherwise ask
|
||||||
// to specify a set of values on the YAML file.
|
// the user to specify a set of values on the YAML file.
|
||||||
for (id, state) in block_msg.states.iter() {
|
for (id, state) in block_msg.states.iter() {
|
||||||
if let Some(tokens) = pairs.get(id) {
|
if let Some(tokens) = pairs.get(id) {
|
||||||
let formatted_token_str = format!("{:}/{:}", &tokens[0].symbol, &tokens[1].symbol);
|
let formatted_token_str = format!("{:}/{:}", &tokens[0].symbol, &tokens[1].symbol);
|
||||||
@@ -358,4 +377,5 @@ fn validate_state(
|
|||||||
// e)) .ok();
|
// e)) .ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
|
use miette::{miette, IntoDiagnostic, WrapErr};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::config::ProtocolComponentWithTestConfig;
|
use crate::config::ProtocolComponentWithTestConfig;
|
||||||
@@ -30,7 +31,7 @@ impl TychoRunner {
|
|||||||
start_block: u64,
|
start_block: u64,
|
||||||
end_block: u64,
|
end_block: u64,
|
||||||
protocol_type_names: &[String],
|
protocol_type_names: &[String],
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> miette::Result<()> {
|
||||||
// Expects a .env present in the same folder as package root (where Cargo.toml is)
|
// Expects a .env present in the same folder as package root (where Cargo.toml is)
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
|
|
||||||
@@ -67,28 +68,21 @@ impl TychoRunner {
|
|||||||
cmd.stdout(Stdio::piped())
|
cmd.stdout(Stdio::piped())
|
||||||
.stderr(Stdio::piped());
|
.stderr(Stdio::piped());
|
||||||
|
|
||||||
let mut process = match cmd.spawn() {
|
let mut process = cmd
|
||||||
Ok(p) => p,
|
.spawn()
|
||||||
Err(e) => {
|
.into_diagnostic()
|
||||||
println!("Error running Tycho indexer: {}", e);
|
.wrap_err("Error running Tycho indexer")?;
|
||||||
return Err(e.into());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if self.with_binary_logs {
|
if self.with_binary_logs {
|
||||||
Self::handle_process_output(&mut process);
|
Self::handle_process_output(&mut process);
|
||||||
}
|
}
|
||||||
|
|
||||||
match process.wait() {
|
let status = process
|
||||||
Ok(status) => {
|
.wait()
|
||||||
if !status.success() {
|
.into_diagnostic()
|
||||||
return Err(format!("Process exited with non-zero status: {}", status).into());
|
.wrap_err("Failed to wait on Tycho indexer process")?;
|
||||||
}
|
if !status.success() {
|
||||||
}
|
return Err(miette!("Process exited with non-zero status: {status}"));
|
||||||
Err(e) => {
|
|
||||||
println!("Error waiting for Tycho indexer: {}", e);
|
|
||||||
return Err(e.into());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -101,7 +95,7 @@ impl TychoRunner {
|
|||||||
start_block: u64,
|
start_block: u64,
|
||||||
stop_block: u64,
|
stop_block: u64,
|
||||||
skip_balance_check: bool,
|
skip_balance_check: bool,
|
||||||
) -> R
|
) -> miette::Result<R>
|
||||||
where
|
where
|
||||||
F: FnOnce(&Vec<ProtocolComponentWithTestConfig>, u64, u64, bool) -> R,
|
F: FnOnce(&Vec<ProtocolComponentWithTestConfig>, u64, u64, bool) -> R,
|
||||||
{
|
{
|
||||||
@@ -152,7 +146,7 @@ impl TychoRunner {
|
|||||||
eprintln!("Failed to join RPC thread");
|
eprintln!("Failed to join RPC thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper method to handle process output in separate threads
|
// Helper method to handle process output in separate threads
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use std::{
|
use std::{
|
||||||
error::Error,
|
|
||||||
fs,
|
fs,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process::Command,
|
process::Command,
|
||||||
@@ -10,16 +9,17 @@ use figment::{
|
|||||||
value::Value,
|
value::Value,
|
||||||
Figment,
|
Figment,
|
||||||
};
|
};
|
||||||
|
use miette::IntoDiagnostic;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
/// Build a Substreams package with modifications to the YAML file.
|
/// Build a Substreams package with modifications to the YAML file.
|
||||||
pub fn build_spkg(yaml_file_path: &PathBuf, initial_block: u64) -> Result<String, Box<dyn Error>> {
|
pub fn build_spkg(yaml_file_path: &PathBuf, initial_block: u64) -> miette::Result<String> {
|
||||||
// Create a backup file of the unmodified Substreams protocol YAML config file.
|
// Create a backup file of the unmodified Substreams protocol YAML config file.
|
||||||
let backup_file_path = yaml_file_path.with_extension("backup");
|
let backup_file_path = yaml_file_path.with_extension("backup");
|
||||||
fs::copy(yaml_file_path, &backup_file_path)?;
|
fs::copy(yaml_file_path, &backup_file_path).into_diagnostic()?;
|
||||||
|
|
||||||
let figment = Figment::new().merge(Yaml::file(yaml_file_path));
|
let figment = Figment::new().merge(Yaml::file(yaml_file_path));
|
||||||
let mut data: Value = figment.extract()?;
|
let mut data: Value = figment.extract().into_diagnostic()?;
|
||||||
|
|
||||||
// Apply the modification function to update the YAML files
|
// Apply the modification function to update the YAML files
|
||||||
modify_initial_block(&mut data, initial_block);
|
modify_initial_block(&mut data, initial_block);
|
||||||
@@ -52,8 +52,8 @@ pub fn build_spkg(yaml_file_path: &PathBuf, initial_block: u64) -> Result<String
|
|||||||
let spkg_name = format!("{}/{}-{}.spkg", parent_dir, package_name, package_version);
|
let spkg_name = format!("{}/{}-{}.spkg", parent_dir, package_name, package_version);
|
||||||
|
|
||||||
// Write the modified YAML back to the file
|
// Write the modified YAML back to the file
|
||||||
let yaml_string = serde_yaml::to_string(&data)?;
|
let yaml_string = serde_yaml::to_string(&data).into_diagnostic()?;
|
||||||
fs::write(yaml_file_path, yaml_string)?;
|
fs::write(yaml_file_path, yaml_string).into_diagnostic()?;
|
||||||
|
|
||||||
// Run the substreams pack command to create the spkg
|
// Run the substreams pack command to create the spkg
|
||||||
// WARNING: Ensure substreams is in the PATH
|
// WARNING: Ensure substreams is in the PATH
|
||||||
@@ -71,15 +71,18 @@ pub fn build_spkg(yaml_file_path: &PathBuf, initial_block: u64) -> Result<String
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Error running substreams pack command: {}. \
|
error!(
|
||||||
|
"Error running substreams pack command: {}. \
|
||||||
Ensure that the wasm target was built and that substreams CLI\
|
Ensure that the wasm target was built and that substreams CLI\
|
||||||
is installed and exported on PATH", e);
|
is installed and exported on PATH",
|
||||||
|
e
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore the original YAML from backup
|
// Restore the original YAML from backup
|
||||||
fs::copy(&backup_file_path, yaml_file_path)?;
|
fs::copy(&backup_file_path, yaml_file_path).into_diagnostic()?;
|
||||||
fs::remove_file(&backup_file_path)?;
|
fs::remove_file(&backup_file_path).into_diagnostic()?;
|
||||||
|
|
||||||
Ok(spkg_name)
|
Ok(spkg_name)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user