-
Notifications
You must be signed in to change notification settings - Fork 18
feat: oracle signed context - full stack (Phases 3-7) #2503
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
Changes from all commits
e9f2afb
f0e1adf
f2566dc
d4339cb
263d233
faa6fdc
63e3282
f29d775
7f98109
1609cc1
c1391fe
f7e519b
f628b79
0275c3a
026a106
aec3e74
63ea51f
2ac0d9b
d5f6698
5963780
b8e8baa
3266868
3e96b73
4d23ec9
dd752c5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| // Re-export oracle types and functions from the quote crate. | ||
| // This maintains backward compatibility for code in common that uses oracle functionality. | ||
| pub use rain_orderbook_quote::oracle::*; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -272,6 +272,14 @@ impl RaindexOrder { | |
| _ => None, | ||
| }) | ||
| } | ||
| /// Returns the signed context oracle URL if this order has oracle metadata. | ||
| #[wasm_bindgen(getter = oracleUrl)] | ||
| pub fn oracle_url(&self) -> Option<String> { | ||
| self.parsed_meta().into_iter().find_map(|meta| match meta { | ||
| ParsedMeta::RaindexSignedContextOracleV1(oracle) => Some(oracle.0), | ||
| _ => None, | ||
| }) | ||
| } | ||
| #[wasm_bindgen(getter)] | ||
| pub fn transaction(&self) -> Option<RaindexTransaction> { | ||
| self.transaction.clone() | ||
|
|
@@ -300,6 +308,16 @@ impl RaindexOrder { | |
| pub fn inputs_outputs_list(&self) -> RaindexVaultsList { | ||
| RaindexVaultsList::new(get_io_by_type(self, RaindexVaultType::InputOutput)) | ||
| } | ||
|
|
||
| /// Extract oracle URL from raw meta bytes. | ||
| /// | ||
| /// Takes raw meta bytes, CBOR decodes them as RainMetaDocumentV1Items, | ||
| /// and finds RaindexSignedContextOracleV1 by magic number. | ||
| /// Returns the oracle URL if found, None otherwise. | ||
| #[wasm_bindgen(js_name = extractOracleUrl)] | ||
| pub fn extract_oracle_url_wasm(meta_bytes: &[u8]) -> Option<String> { | ||
| RaindexOrder::extract_oracle_url(meta_bytes) | ||
|
Comment on lines
+317
to
+319
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n -C2 'extract_oracle_url(_wasm)?' crates/common/src/raindex_client/orders.rs
rg -n -C1 '#\[cfg\(target_family = "wasm"\)\]|#\[cfg\(not\(target_family = "wasm"\)\)\]' \
crates/common/src/raindex_client/orders.rsRepository: rainlanguage/rain.orderbook Length of output: 2116 Fix the wasm-only call to a non-wasm helper. Line 319 calls 🧰 Tools🪛 GitHub Actions: GitHub Actions Vercel Docs Preview Deployment[error] 319-319: RaindexOrder::extract_oracle_url not found. The code calls an associated function 'extract_oracle_url', but only 'extract_oracle_url_wasm' (or other variants) may exist. Consider using the correct function name or add the missing function. 🪛 GitHub Actions: GitHub Actions Vercel Preview Deployment[error] 319-319: RaindexOrder::extract_oracle_url(meta_bytes) not found for struct RaindexOrder. Use associated function RaindexOrder::extract_oracle_url_wasm(meta_bytes) or ensure the correct method exists in this version. 🪛 GitHub Actions: Rainix CI[error] 319-319: no function or associated item named 🪛 GitHub Actions: Test ui-components[error] 319-319: RaindexOrder::extract_oracle_url not found. The log suggests a similarly named function (extract_oracle_url_wasm) may exist. This indicates a API/API-name mismatch or refactor. Update call to a valid associated function. 🪛 GitHub Actions: Test webapp[error] 319-319: RaindexOrder::extract_oracle_url(meta_bytes) not found. Suggests using RaindexOrder::extract_oracle_url_wasm(meta_bytes) or other existing associated constructors. [error] 319-319: Compilation failed due to the above error while building rain_orderbook_common (lib). 🤖 Prompt for AI Agents |
||
| } | ||
| } | ||
| #[cfg(not(target_family = "wasm"))] | ||
| impl RaindexOrder { | ||
|
|
@@ -348,6 +366,13 @@ impl RaindexOrder { | |
| _ => None, | ||
| }) | ||
| } | ||
| /// Returns the signed context oracle URL if this order has oracle metadata. | ||
| pub fn oracle_url(&self) -> Option<String> { | ||
| self.parsed_meta().into_iter().find_map(|meta| match meta { | ||
| ParsedMeta::RaindexSignedContextOracleV1(oracle) => Some(oracle.0), | ||
| _ => None, | ||
| }) | ||
| } | ||
| pub fn transaction(&self) -> Option<RaindexTransaction> { | ||
| self.transaction.clone() | ||
| } | ||
|
|
@@ -369,6 +394,19 @@ impl RaindexOrder { | |
| pub fn inputs_outputs_list(&self) -> RaindexVaultsList { | ||
| RaindexVaultsList::new(get_io_by_type(self, RaindexVaultType::InputOutput)) | ||
| } | ||
|
|
||
| /// Extract oracle URL from raw meta bytes. | ||
| /// | ||
| /// Takes raw meta bytes, CBOR decodes them as RainMetaDocumentV1Items, | ||
| /// and finds RaindexSignedContextOracleV1 by magic number. | ||
| /// Returns the oracle URL if found, None otherwise. | ||
| pub fn extract_oracle_url(meta_bytes: &[u8]) -> Option<String> { | ||
| use rain_metadata::{types::raindex_signed_context_oracle::RaindexSignedContextOracleV1, RainMetaDocumentV1Item}; | ||
|
|
||
| let items = RainMetaDocumentV1Item::cbor_decode(meta_bytes).ok()?; | ||
| let oracle = RaindexSignedContextOracleV1::find_in_items(&items).ok()??; | ||
| Some(oracle.url().to_string()) | ||
| } | ||
| } | ||
|
|
||
| fn get_vaults_with_type( | ||
|
|
@@ -661,6 +699,7 @@ impl RaindexOrder { | |
| &rpc_urls, | ||
| Some(block_number), | ||
| sell_token, | ||
| self.oracle_url(), | ||
| ) | ||
| .await | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -54,6 +54,7 @@ pub fn build_candidate_from_quote( | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| output_io_index, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| max_output: data.max_output, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ratio: data.ratio, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| signed_context: vec![], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -102,6 +103,7 @@ pub fn estimate_take_order( | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| )) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #[allow(clippy::too_many_arguments)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub async fn execute_single_take( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| candidate: TakeOrderCandidate, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| mode: ParsedTakeOrdersMode, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -110,7 +112,25 @@ pub async fn execute_single_take( | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| rpc_urls: &[Url], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| block_number: Option<u64>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sell_token: Address, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| oracle_url: Option<String>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> Result<TakeOrdersCalldataResult, RaindexError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Fetch signed context from oracle if URL provided | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut candidate = candidate; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if let Some(url) = oracle_url { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let body = crate::oracle::encode_oracle_body( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| &candidate.order, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| candidate.input_io_index, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| candidate.output_io_index, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| taker, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| match crate::oracle::fetch_signed_context(&url, body).await { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(ctx) => candidate.signed_context = vec![ctx], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Err(e) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tracing::warn!("Failed to fetch oracle data from {}: {}", url, e); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+119
to
+130
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't emit raw oracle URLs in warning logs. Oracle endpoints can carry credentials or signed query params, and this branch logs the URL verbatim on every fetch failure. Avoid logging the raw URL here; even the formatted error can repeat it. 💡 Proposed fix match crate::oracle::fetch_signed_context(&url, body).await {
Ok(ctx) => candidate.signed_context = vec![ctx],
- Err(e) => {
- tracing::warn!("Failed to fetch oracle data from {}: {}", url, e);
- }
+ Err(_) => {
+ tracing::warn!("Failed to fetch oracle data");
+ }
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let zero = Float::zero()?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if candidate.ratio.gt(price_cap)? { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deduplicate oracle metadata when the deployment already specifies an oracle URL.
new_from_deployment()now blindly appends aRaindexSignedContextOracleV1item. Ifadditional_metaalready contains one, downstream extractors usefind_in_items(), so the effective URL becomes order-dependent instead of lettingdeployment.order.oracle_urlwin.💡 Proposed fix
let mut meta = additional_meta.unwrap_or_default(); if let Some(ref oracle_url) = deployment.order.oracle_url { + meta.retain(|item| item.magic != KnownMagic::RaindexSignedContextOracleV1); let oracle = RaindexSignedContextOracleV1::parse(oracle_url) .map_err(AddOrderArgsError::RainMetaError)?; meta.push(oracle.to_meta_item()); }🤖 Prompt for AI Agents