From a0ebc99fa1b3f3438c6c0429142adc34d965dcd4 Mon Sep 17 00:00:00 2001 From: David Meister Date: Mon, 29 Jun 2026 17:41:53 +0000 Subject: [PATCH 1/2] perf: eliminate redundant read_dispair calls in try_into_call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit try_into_call previously called read_dispair 3 times (once directly and once inside each try_parse_rainlang call), totalling 12 sequential RPC round-trips just to read 4 immutable deployer addresses. Add parse_bytecode_with_dispair, which takes a pre-fetched DISPaiR and skips the read_dispair step. try_parse_rainlang becomes a wrapper around read_dispair + parse_bytecode_with_dispair. try_into_call now calls read_dispair once and passes the result to both parse calls via clone/move. RPC calls for a single deposit+addOrder submission: 14 → 6 (saves 8 sequential round-trips, ~2.4s at 300ms RTT). Adds assertions to test_into_add_order_call verifying both config.evaluable and tasks[0].evaluable carry the correct interpreter and store addresses from the single shared dispair read. Closes https://github.com/rainlanguage/raindex/issues/2776 Co-Authored-By: Claude --- crates/common/src/add_order.rs | 63 +++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/crates/common/src/add_order.rs b/crates/common/src/add_order.rs index e73069fb79..7f0320bf8a 100644 --- a/crates/common/src/add_order.rs +++ b/crates/common/src/add_order.rs @@ -177,14 +177,14 @@ impl AddOrderArgs { Ok(DISPaiR::new(deployer, interpreter, store, parser)) } - /// Call parser to parse rainlang into bytecode and constants. - async fn try_parse_rainlang( + /// Parse rainlang into bytecode using a pre-fetched DISPaiR. + /// Called by try_into_call to avoid redundant read_dispair round-trips. + async fn parse_bytecode_with_dispair( &self, - rpcs: Vec, - rainlang: String, + rpcs: &[String], + rainlang: &str, + dispair: DISPaiR, ) -> Result, AddOrderArgsError> { - let dispair = self.read_dispair(&rpcs).await?; - let urls = rpcs .iter() .map(|rpc| rpc.parse::()) @@ -193,13 +193,23 @@ impl AddOrderArgs { let provider = mk_read_provider(&urls)?; let parser: ParserV2 = dispair.into(); let rainlang_parsed: parse2Return = parser - .parse_text(rainlang.as_str(), &provider) + .parse_text(rainlang, &provider) .await .map_err(AddOrderArgsError::ParserError)?; - Ok(rainlang_parsed.bytecode.into()) } + /// Call parser to parse rainlang into bytecode and constants. + async fn try_parse_rainlang( + &self, + rpcs: Vec, + rainlang: String, + ) -> Result, AddOrderArgsError> { + let dispair = self.read_dispair(&rpcs).await?; + self.parse_bytecode_with_dispair(&rpcs, &rainlang, dispair) + .await + } + /// Generate RainlangSource meta fn try_generate_meta(&self, rainlang: String) -> Result, AddOrderArgsError> { let mut meta_docs = Vec::new(); @@ -252,24 +262,26 @@ impl AddOrderArgs { &self, rpcs: Vec, ) -> Result { + let dispair = self.read_dispair(&rpcs).await?; + let interpreter = dispair.interpreter; + let store = dispair.store; + let rainlang = self.compose_to_rainlang()?; let bytecode = self - .try_parse_rainlang(rpcs.clone(), rainlang.clone()) + .parse_bytecode_with_dispair(&rpcs, &rainlang, dispair.clone()) .await?; let meta = self.try_generate_meta(rainlang)?; - let dispair = self.read_dispair(&rpcs).await?; - // get the evaluable for the post action let post_rainlang = self.compose_addorder_post_task()?; let post_bytecode = self - .try_parse_rainlang(rpcs.clone(), post_rainlang.clone()) + .parse_bytecode_with_dispair(&rpcs, &post_rainlang, dispair) .await?; let post_evaluable = EvaluableV4 { - interpreter: dispair.interpreter, - store: dispair.store, + interpreter, + store, bytecode: post_bytecode.into(), }; @@ -283,8 +295,8 @@ impl AddOrderArgs { validInputs: self.inputs.clone(), validOutputs: self.outputs.clone(), evaluable: EvaluableV4 { - interpreter: dispair.interpreter, - store: dispair.store, + interpreter, + store, bytecode: bytecode.into(), }, meta: meta.into(), @@ -921,6 +933,25 @@ _ _: 0 0; assert_eq!(add_order_call.tasks[0].evaluable.bytecode.len(), 111); assert_eq!(add_order_call.tasks[0].signedContext.len(), 0); + + // Both config.evaluable and tasks[0].evaluable must use the same + // interpreter/store from one shared read_dispair call. + assert_eq!( + add_order_call.config.evaluable.interpreter, + *local_evm.interpreter.address() + ); + assert_eq!( + add_order_call.config.evaluable.store, + *local_evm.store.address() + ); + assert_eq!( + add_order_call.config.evaluable.interpreter, + add_order_call.tasks[0].evaluable.interpreter + ); + assert_eq!( + add_order_call.config.evaluable.store, + add_order_call.tasks[0].evaluable.store + ); } #[tokio::test] From 85559f506f7f8e83155743c9bf11491fccdbad07 Mon Sep 17 00:00:00 2001 From: David Meister Date: Mon, 29 Jun 2026 17:49:46 +0000 Subject: [PATCH 2/2] fix(ci): rs-static dead_code try_parse_rainlang [3b-attempt] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mark try_parse_rainlang as #[cfg(test)] — after the try_into_call refactor it is only called from tests, so the production build flags it as dead code under -D warnings. Co-Authored-By: Claude --- crates/common/src/add_order.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/common/src/add_order.rs b/crates/common/src/add_order.rs index 7f0320bf8a..4a18ffa39b 100644 --- a/crates/common/src/add_order.rs +++ b/crates/common/src/add_order.rs @@ -199,7 +199,7 @@ impl AddOrderArgs { Ok(rainlang_parsed.bytecode.into()) } - /// Call parser to parse rainlang into bytecode and constants. + #[cfg(test)] async fn try_parse_rainlang( &self, rpcs: Vec,