Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quote debugging #807

Merged
merged 11 commits into from
Sep 3, 2024
Merged
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 0 additions & 6 deletions crates/common/src/add_order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,6 @@ impl AddOrderArgs {
dotrain: String,
deployment: Deployment,
) -> Result<AddOrderArgs, AddOrderArgsError> {
// check the raindex version of the dotrain
DotrainOrder::new(dotrain.clone(), None)
.await?
.validate_raindex_version()
.await?;

let random_vault_id: U256 = rand::random();
let mut inputs = vec![];
for input in &deployment.order.inputs {
Expand Down
6 changes: 1 addition & 5 deletions crates/common/src/dotrain_order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,7 @@ impl DotrainOrder {
pub async fn validate_raindex_version(&self) -> Result<(), DotrainOrderError> {
let app_sha = GH_COMMIT_SHA.to_string();

let frontmatter = RainDocument::get_front_matter(&self.dotrain).unwrap();
let frontmatter_config = ConfigSource::try_from_string(frontmatter.to_string()).await?;
let config: Config = frontmatter_config.try_into()?;

if let Some(raindex_version) = config.raindex_version {
if let Some(raindex_version) = &self.config.raindex_version {
if app_sha != *raindex_version {
return Err(DotrainOrderError::RaindexVersionMismatch(
app_sha,
Expand Down
6 changes: 5 additions & 1 deletion crates/quote/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ typeshare = { workspace = true }

[target.'cfg(not(target_family = "wasm"))'.dependencies]
tokio = { workspace = true, features = ["full"] }
rain-interpreter-eval = { workspace = true }

[target.'cfg(target_family = "wasm")'.dependencies]
js-sys = { version = "0.3.69" }
Expand All @@ -44,4 +45,7 @@ tokio = { workspace = true, features = ["sync", "macros", "io-util", "rt", "time
httpmock = "0.7.0"

[target.'cfg(target_family = "wasm")'.dev-dependencies]
wasm-bindgen-test = "0.3.42"
wasm-bindgen-test = "0.3.42"

[dev-dependencies]
rain-orderbook-env = { workspace = true }
4 changes: 3 additions & 1 deletion crates/quote/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use alloy::primitives::hex::FromHexError;
use alloy::primitives::{hex::FromHexError, U256};
use alloy_ethers_typecast::transaction::ReadableClientError;
use rain_error_decoding::{AbiDecodeFailedErrors, AbiDecodedErrorType};
use rain_orderbook_subgraph_client::OrderbookSubgraphClientError;
Expand Down Expand Up @@ -38,6 +38,8 @@ pub enum Error {
#[cfg(target_family = "wasm")]
#[error(transparent)]
SerdeWasmBindgenError(#[from] serde_wasm_bindgen::Error),
#[error("Invalid quote target: index {0} is out of bounds for this Order")]
InvalidQuoteTarget(U256),
}

#[cfg(target_family = "wasm")]
Expand Down
5 changes: 5 additions & 0 deletions crates/quote/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
pub mod cli;
pub mod error;
mod quote;
#[cfg(not(target_family = "wasm"))]
mod quote_debug;
pub mod rpc;

#[cfg(target_family = "wasm")]
pub mod js_api;

pub use quote::*;

#[cfg(not(target_family = "wasm"))]
pub use quote_debug::*;
13 changes: 13 additions & 0 deletions crates/quote/src/quote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,19 @@ impl QuoteTarget {
.unwrap(),
)
}

/// Validate the quote target
/// Checks if the requested input and output indexes are valid
pub fn validate(&self) -> Result<(), Error> {
if self.quote_config.inputIOIndex >= U256::from(self.quote_config.order.validInputs.len()) {
return Err(Error::InvalidQuoteTarget(self.quote_config.inputIOIndex));
}
if self.quote_config.outputIOIndex >= U256::from(self.quote_config.order.validOutputs.len())
{
return Err(Error::InvalidQuoteTarget(self.quote_config.outputIOIndex));
}
Ok(())
}
}

/// Specifies a batch of [QuoteTarget]s
Expand Down
98 changes: 98 additions & 0 deletions crates/quote/src/quote_debug.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use crate::QuoteTarget;

use alloy::primitives::Address;
use rain_interpreter_eval::{
error::ForkCallError,
fork::{Forker, NewForkedEvm},
trace::RainEvalResult,
};
use rain_orderbook_bindings::IOrderBookV4::quoteCall;
use url::Url;

pub struct NewQuoteDebugger {
pub fork_url: Url,
}
pub struct QuoteDebugger {
forker: Forker,
}

#[derive(Debug, thiserror::Error)]
pub enum QuoteDebuggerError {
#[error("Forker error: {0}")]
ForkerError(#[from] ForkCallError),
#[error("Quote error: {0}")]
QuoteError(#[from] crate::error::Error),
}

impl QuoteDebugger {
pub async fn new(args: NewQuoteDebugger) -> Result<Self, QuoteDebuggerError> {
let forker = Forker::new_with_fork(
NewForkedEvm {
fork_url: args.fork_url.to_string(),
fork_block_number: None,
},
None,
None,
)
.await?;

Ok(Self { forker })
}

pub async fn debug(
&mut self,
quote_target: QuoteTarget,
) -> Result<RainEvalResult, QuoteDebuggerError> {
quote_target.validate()?;

let quote_call = quoteCall {
quoteConfig: quote_target.quote_config.clone(),
};

let res = self
.forker
.alloy_call(Address::default(), quote_target.orderbook, quote_call, true)
.await?;

Ok(res.raw.into())
}
}

#[cfg(test)]
mod tests {
use super::*;
use alloy::sol_types::SolType;
use alloy::{hex, primitives::U256};
use rain_orderbook_bindings::IOrderBookV4::{OrderV3, Quote};
use rain_orderbook_env::CI_DEPLOY_POLYGON_RPC_URL;
use std::str::FromStr;

#[tokio::test(flavor = "multi_thread", worker_threads = 10)]
async fn test_quote_debugger() {
let mut debugger = QuoteDebugger::new(NewQuoteDebugger {
fork_url: Url::from_str(CI_DEPLOY_POLYGON_RPC_URL).unwrap(),
})
.await
.unwrap();

let order_bytes = "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000008e4bdeec7ceb9570d440676345da1dce10329f5b00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000076000000000000000000000000000000000000000000000000000000000000007e0eccd7aa9a9f8af012d11a874253fdd8b48fd35c63f21cf97d0c33f6d141268db0000000000000000000000006352593f4018c99df731de789e2a147c7fb29370000000000000000000000000de38ad4b13d5258a5653e530ecdf0ca71b4e8a51000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000006250000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000001158e460913d000000000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000000000000000000000000000340aad21b3b7000008d5061727469616c2074726164650000000000000000000000000000000000008c636f6f6c646f776e2d6b65790000000000000000000000000000000000000088636f6f6c646f776e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000029a2241af62c00000000000000000000000000000000000000000000000000003782dace9d90000000000000000000000000000000000000000000000000000003782dace9d900008764656661756c7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000e1b3eb06806601828976e491914e3de18b5d6b280000000000000000000000003c499c542cef5e3811e1192ce70d8cc03d5c33590000000000000000000000005757371414417b8c6caad45baef941abc7d3ab3296e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f00000000000000000000000000000000000000000000000000b1a2bc2ec50000896d696e20726174696f000000000000000000000000000000000000000000008d5072696365206368616e67652e000000000000000000000000000000000000000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000470de4df8200000000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000000214e8348c4f0000000000000000000000010001bc609623f5020f6fc7481024862cd5ee3fff52d700000000000000000000000000000000000000000000000000000000000002c50c00000060008000c801b401e00204021c0220026c02840288170900070b200002001000000b1100030010000201100001011000003d1200003d120000001000030b11000401100002001000012b120000001000004812000100100004001000030b230005001000060b01000600100006001000050b020007070300000110000303100002031001044412000003100404211200001d020000110500021a10000001100004031000010c120000491100000110000501100002001000012b12000000100000211200001d0200000010000001100004031000010c1200004a0200003a14010701100006001000000b12000801100007001000000b12000801100001001000000b12000801100008001000000b12000801100009001000000b1200080110000c0110000b001000050110000700100005251200000110000a00100005211200001f120000001000040110000700100004251200000110000a00100004211200001f120000001000030110000700100003251200000110000a00100003211200001f120000001000020110000700100002251200000110000a00100002211200001f120000001000010110000700100001251200000110000a00100001211200001f1200001c1c00000a060104011000100110000f001000000110000e0110000d02250018001000020b010009001000010b11000a0806030600100000001000020b11000b00100001481200012e120000001000000010000305040101011000120110001100100000201200001d020000000202021207020600100001001000000c12000007111400061100000110000701100006001000000c1200003c12000000100003001000022b12000001100000011000072b120000001000042e12000005040101011000131a10000000100000241200001d0200000001010108050102011000170010000001100016011000152e12000001100014271300003b12000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000003c499c542cef5e3811e1192ce70d8cc03d5c33590000000000000000000000000000000000000000000000000000000000000006d302fedcbf6b3ea84812cde736439a97478b93fce4b546bc445f837f255893840000000000000000000000000000000000000000000000000000000000000001000000000000000000000000e1b3eb06806601828976e491914e3de18b5d6b280000000000000000000000000000000000000000000000000000000000000012d302fedcbf6b3ea84812cde736439a97478b93fce4b546bc445f837f25589384";

let order = OrderV3::abi_decode(&hex::decode(order_bytes).unwrap(), true).unwrap();

let quote_target = QuoteTarget {
orderbook: "0x2f209e5b67a33b8fe96e28f24628df6da301c8eb"
.parse()
.unwrap(),
quote_config: Quote {
order,
inputIOIndex: U256::from(0),
outputIOIndex: U256::from(0),
signedContext: vec![],
},
};

let res = debugger.debug(quote_target).await.unwrap();

assert_eq!(res.traces.len(), 15);
}
}
2 changes: 2 additions & 0 deletions tauri-app/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions tauri-app/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ rain_orderbook_common = { path = "../../crates/common" }
rain_orderbook_quote = { path = "../../crates/quote" }
rain_orderbook_subgraph_client = { path = "../../crates/subgraph" }
rain_orderbook_app_settings = { path = "../../crates/settings" }
rain_orderbook_bindings = { path = "../../crates/bindings" }
alloy-ethers-typecast = { git = "https://github.com/rainlanguage/alloy-ethers-typecast", rev = "0881930a22e84db49ba955c5b88e790e1266ac66" }
rain-orderbook-env = { path = "../../crates/env" }
alloy = { version = "0.1.4", features = ["full", "node-bindings"] }
Expand Down
Loading
Loading