feat: fix test runner. Working version to get_amount_out

This commit is contained in:
Thales
2025-05-04 23:12:44 -03:00
committed by Tamara
parent afd5527b15
commit def49e7ddf
5 changed files with 178 additions and 62 deletions

View File

@@ -3,7 +3,7 @@ use std::collections::HashMap;
use colored::Colorize;
use serde::{Deserialize, Serialize};
use similar::{ChangeTag, TextDiff};
use tycho_core::{dto::ProtocolComponent, Bytes};
use tycho_common::{dto::ProtocolComponent, Bytes};
/// Represents a ProtocolComponent with its main attributes
#[derive(Debug, Clone, Deserialize, Serialize)]

View File

@@ -8,7 +8,7 @@ use figment::{
use postgres::{Client, Error, NoTls};
use tokio::runtime::Runtime;
use tracing::{debug, info};
use tycho_core::{
use tycho_common::{
dto::{Chain, ProtocolComponent, ResponseAccount, ResponseProtocolState},
Bytes,
};
@@ -162,12 +162,17 @@ fn validate_state(
.block_on(tycho_client.get_protocol_components(protocol_system, chain))
.expect("Failed to get protocol components");
let expected_ids = expected_components
.iter()
.map(|c| c.base.id.clone())
.collect::<Vec<String>>();
let protocol_states = rt
.block_on(tycho_client.get_protocol_state(protocol_system, chain))
.block_on(tycho_client.get_protocol_state(protocol_system, expected_ids, chain))
.expect("Failed to get protocol state");
let vm_storages = rt
.block_on(tycho_client.get_contract_state(Vec::new(), protocol_system, chain))
.block_on(tycho_client.get_contract_state(protocol_system, chain))
.expect("Failed to get contract state");
// Create a map of component IDs to components for easy lookup
@@ -200,7 +205,7 @@ fn validate_state(
let component = components_by_id
.get(&component_id)
.unwrap();
.expect("Failed to get component from Tycho");
let diff = expected_component
.base
@@ -269,7 +274,7 @@ fn validate_state(
// Step 3: Run Tycho Simulation
let mut decoder = TychoStreamDecoder::new();
decoder.register_decoder::<EVMPoolState<PreCachedDB>>("test_protocol", None);
decoder.register_decoder::<EVMPoolState<PreCachedDB>>("test_protocol");
// Mock a stream message, with only a Snapshot and no deltas
let mut states: HashMap<String, ComponentWithState> = HashMap::new();
@@ -286,16 +291,17 @@ fn validate_state(
.into_iter()
.map(|x| (x.address.clone(), x))
.collect();
let snapshot = Snapshot { states, vm_storage };
let bytes = [0u8; 32];
let state_msgs: HashMap<String, StateSyncMessage> = HashMap::from([(
String::from("test_protocol"),
StateSyncMessage {
header: Header {
hash: Default::default(),
hash: Bytes::from(bytes),
number: stop_block,
parent_hash: Default::default(),
parent_hash: Bytes::from(bytes),
revert: false,
},
snapshots: snapshot,
@@ -304,14 +310,12 @@ fn validate_state(
},
)]);
let all_tokens = rt.block_on(load_all_tokens(
"localhost:4242",
true,
None,
Chain::Ethereum.into(),
None,
None,
));
let all_tokens = rt
.block_on(tycho_client.get_tokens(Chain::Ethereum, None, None))
.expect("Failed to get tokens");
info!("Loaded {} tokens", all_tokens.len());
rt.block_on(decoder.set_tokens(all_tokens));
let mut pairs: HashMap<String, Vec<Token>> = HashMap::new();
@@ -329,6 +333,9 @@ fn validate_state(
// 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
// TODO: Since we don't have balances on the VM State, we could try to use Limits, otherwise ask the user
// to specify a set of values on the YAML file.
for (id, state) in block_msg.states.iter() {
if let Some(tokens) = pairs.get(id) {
let formatted_token_str = format!("{:}/{:}", &tokens[0].symbol, &tokens[1].symbol);
@@ -338,18 +345,18 @@ fn validate_state(
.map(|price| println!("Spot price {:?}: {:?}", formatted_token_str, price))
.map_err(|e| eprintln!("Error calculating spot price for Pool {:?}: {:?}", id, e))
.ok();
let amount_in =
BigUint::from(1u32) * BigUint::from(10u32).pow(tokens[0].decimals as u32);
state
.get_amount_out(amount_in, &tokens[0], &tokens[1])
.map(|result| {
println!(
"Amount out for trading 1 {:?} -> {:?}: {:?} (takes {:?} gas)",
&tokens[0].symbol, &tokens[1].symbol, result.amount, result.gas
)
})
.map_err(|e| eprintln!("Error calculating amount out for Pool {:?}: {:?}", id, e))
.ok();
// let amount_in =
// BigUint::from(1u32) * BigUint::from(10u32).pow(tokens[0].decimals as u32);
// state
// .get_amount_out(amount_in, &tokens[0], &tokens[1])
// .map(|result| {
// println!(
// "Amount out for trading 1 {:?} -> {:?}: {:?} (takes {:?} gas)",
// &tokens[0].symbol, &tokens[1].symbol, result.amount, result.gas
// )
// })
// .map_err(|e| eprintln!("Error calculating amount out for Pool {:?}: {:?}", id,
// e)) .ok();
}
}
}

View File

@@ -1,13 +1,17 @@
use std::{error::Error as StdError, fmt};
use std::{collections::HashMap, error::Error as StdError, fmt};
use tracing::info;
use tycho_client::{rpc::RPCClient, HttpRPCClient};
use tycho_core::{
use tycho_common::{
dto::{
Chain, ProtocolComponent, ProtocolComponentsRequestBody, ResponseAccount,
ResponseProtocolState, VersionParam,
Chain, PaginationParams, ProtocolComponent, ProtocolComponentsRequestBody, ResponseAccount,
ResponseProtocolState, StateRequestBody, VersionParam,
},
models::Address,
Bytes,
};
use tycho_common::dto::ResponseToken;
use tycho_simulation::models::Token;
/// Custom error type for RPC operations
#[derive(Debug)]
@@ -74,18 +78,18 @@ impl TychoClient {
pub async fn get_protocol_state(
&self,
protocol_system: &str,
component_ids: Vec<String>,
chain: Chain,
) -> Result<Vec<ResponseProtocolState>, RpcError> {
let chunk_size = 100;
let concurrency = 1;
let ids: &[String] = &[];
let version: tycho_core::dto::VersionParam = VersionParam::default();
let version: tycho_common::dto::VersionParam = VersionParam::default();
let protocol_states = self
.http_client
.get_protocol_states_paginated(
chain,
ids,
&component_ids,
protocol_system,
true,
&version,
@@ -100,27 +104,53 @@ impl TychoClient {
/// Gets contract state from the RPC server
pub async fn get_contract_state(
&self,
contract_ids: Vec<Address>,
protocol_system: &str,
chain: Chain,
) -> Result<Vec<ResponseAccount>, RpcError> {
// Pagination parameters
let chunk_size = 100;
let concurrency = 1;
let version: tycho_core::dto::VersionParam = VersionParam::default();
let request_body = StateRequestBody {
contract_ids: None,
protocol_system: protocol_system.to_string(),
version: Default::default(),
chain,
pagination: PaginationParams { page: 0, page_size: 100 },
};
let contract_states = self
.http_client
.get_contract_state_paginated(
chain,
&contract_ids,
protocol_system,
&version,
chunk_size,
concurrency,
)
.get_contract_state(&request_body)
.await?;
Ok(contract_states.accounts)
}
pub async fn get_tokens(
&self,
chain: Chain,
min_quality: Option<i32>,
max_days_since_last_trade: Option<u64>,
) -> Result<HashMap<Bytes, Token>, RpcError> {
info!("Loading tokens from Tycho...");
#[allow(clippy::mutable_key_type)]
let res = self
.http_client
.get_all_tokens(chain, min_quality, max_days_since_last_trade, 3_000)
.await?
.into_iter()
.map(|token| {
let mut token_clone: ResponseToken = token.clone();
// Set default gas if empty
// TODO: Check if this interferes with simulation logic
if token_clone.gas.is_empty() {
token_clone.gas = vec![Some(44000_u64)];
}
(
token_clone.address.clone(),
token_clone.try_into().expect("Failed to convert token"),
)
})
.collect::<HashMap<_, Token>>();
Ok(res)
}
}