Conversation
New metadata type for signed context oracle endpoint discovery. - Register KnownMagic::SignedContextOracleV1 (0xff7a1507ba4419ca) - Add KnownMeta::SignedContextOracleV1 variant - Add signed_context_oracle module with encode/decode/find helpers - Payload is a simple URL string (CBOR text) identifying a GET endpoint that returns SignedContextV1 data for Rain order evaluation - 7 new tests (magic roundtrip + oracle encode/decode/find)
WalkthroughThis PR introduces a new metadata type for Raindex Signed Context Oracle V1, adding magic number recognition, enum variants across meta modules, URL validation and serialization utilities, and extending error handling for URL validation failures. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@crates/cli/src/meta/types/signed_context_oracle/mod.rs`:
- Around line 36-45: Update the doc comment for
KnownMagic::SignedContextOracleV1 to state the payload is a raw UTF-8 string
(not a CBOR text string); the surrounding implementation (SignedContextOracleV1
handling in to_meta_item and the TryFrom that uses String::from_utf8)
encodes/decodes raw UTF-8 bytes, so change the comment in magic.rs to "raw UTF-8
string" to match the behavior.
- Around line 25-29: SignedContextOracleV1::new currently accepts any String
(including empty) which is invalid for a GET endpoint; update new to validate
the URL (e.g., check !url.trim().is_empty()) and reject empty values instead of
silently accepting them: either change the signature to return
Result<SignedContextOracleV1, YourErrorType> and return an Err when the URL is
empty, or keep the constructor but add a clear panic/assert with a descriptive
message; ensure you reference SignedContextOracleV1::new and the URL parameter
when implementing the check and choose an existing error type (or create a small
one) for the Result variant.
- Around line 65-74: The TryFrom implementation for SignedContextOracleV1
currently returns Error::UnsupportedMeta when the RainMetaDocumentV1Item magic
mismatches; change this to return Error::InvalidMetaMagic(expected, actual) to
match peer implementations (e.g., DotrainGuiStateV1, DotrainSourceV1). In the
TryFrom<RainMetaDocumentV1Item> for SignedContextOracleV1 function, replace the
early-return Err(Error::UnsupportedMeta) with
Err(Error::InvalidMetaMagic(KnownMagic::SignedContextOracleV1, value.magic)) so
the error reports both the expected KnownMagic (SignedContextOracleV1) and the
actual value.
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Find the Error enum definition and InvalidMetaMagic variant
rg -n 'enum Error|InvalidMetaMagic' --type rust | head -30Repository: rainlanguage/rain.metadata
Length of output: 1152
🏁 Script executed:
# Check the DotrainGuiStateV1 TryFrom implementation
rg -B5 -A10 'impl TryFrom<RainMetaDocumentV1Item> for DotrainGuiStateV1' --type rustRepository: rainlanguage/rain.metadata
Length of output: 1336
🏁 Script executed:
# Check the DotrainSourceV1 TryFrom implementation
rg -B5 -A10 'impl TryFrom<RainMetaDocumentV1Item> for DotrainSourceV1' --type rustRepository: rainlanguage/rain.metadata
Length of output: 1349
🏁 Script executed:
# Check all TryFrom implementations for RainMetaDocumentV1Item to see error handling patterns
rg -B2 -A8 'impl TryFrom<RainMetaDocumentV1Item>' --type rustRepository: rainlanguage/rain.metadata
Length of output: 8562
Use Error::InvalidMetaMagic for consistency with peer implementations.
Other TryFrom<RainMetaDocumentV1Item> implementations in this codebase (DotrainGuiStateV1 and DotrainSourceV1) return Error::InvalidMetaMagic(expected, actual) on magic mismatch, providing diagnostic context about which magic value was expected versus received. This implementation returns the less informative Error::UnsupportedMeta.
♻️ Proposed fix
fn try_from(value: RainMetaDocumentV1Item) -> Result<Self, Self::Error> {
- if !matches!(value.magic, KnownMagic::SignedContextOracleV1) {
- return Err(Error::UnsupportedMeta);
+ if value.magic != KnownMagic::SignedContextOracleV1 {
+ return Err(Error::InvalidMetaMagic(
+ KnownMagic::SignedContextOracleV1,
+ value.magic,
+ ));
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| impl TryFrom<RainMetaDocumentV1Item> for SignedContextOracleV1 { | |
| type Error = Error; | |
| fn try_from(value: RainMetaDocumentV1Item) -> Result<Self, Self::Error> { | |
| if !matches!(value.magic, KnownMagic::SignedContextOracleV1) { | |
| return Err(Error::UnsupportedMeta); | |
| } | |
| let bytes = value.unpack()?; | |
| let url = String::from_utf8(bytes)?; | |
| Ok(Self(url)) | |
| } | |
| impl TryFrom<RainMetaDocumentV1Item> for SignedContextOracleV1 { | |
| type Error = Error; | |
| fn try_from(value: RainMetaDocumentV1Item) -> Result<Self, Self::Error> { | |
| if value.magic != KnownMagic::SignedContextOracleV1 { | |
| return Err(Error::InvalidMetaMagic( | |
| KnownMagic::SignedContextOracleV1, | |
| value.magic, | |
| )); | |
| } | |
| let bytes = value.unpack()?; | |
| let url = String::from_utf8(bytes)?; | |
| Ok(Self(url)) | |
| } | |
| } |
🤖 Prompt for AI Agents
In `@crates/cli/src/meta/types/signed_context_oracle/mod.rs` around lines 65 - 74,
The TryFrom implementation for SignedContextOracleV1 currently returns
Error::UnsupportedMeta when the RainMetaDocumentV1Item magic mismatches; change
this to return Error::InvalidMetaMagic(expected, actual) to match peer
implementations (e.g., DotrainGuiStateV1, DotrainSourceV1). In the
TryFrom<RainMetaDocumentV1Item> for SignedContextOracleV1 function, replace the
early-return Err(Error::UnsupportedMeta) with
Err(Error::InvalidMetaMagic(KnownMagic::SignedContextOracleV1, value.magic)) so
the error reports both the expected KnownMagic (SignedContextOracleV1) and the
actual value.
There was a problem hiding this comment.
might be better to return an error if we find the magic but can't decode the item. None makes sense if the magic wasn't found
- Validate URL on construction using url::Url (Gleb's suggestion) - new() takes Url, parse() takes &str and validates - Invalid/empty URLs are rejected with Error::InvalidUrl - find_in_items() now returns Result<Option<Self>, Error> (Gleb's suggestion) - Returns Err if magic found but decode fails - Returns Ok(None) only if magic not found - Fix doc comment: payload is raw UTF-8 bytes, not CBOR text string - Added Error::InvalidUrl variant - 10 tests (up from 7): added tests for URL validation, empty URL, decode error propagation, parsed_url accessor
The metadata type is specific to the Raindex calculateOrderIO entrypoint, not a generic oracle standard. Rename to reflect this.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@crates/cli/src/meta/types/raindex_signed_context_oracle/mod.rs`:
- Around line 46-48: The parsed_url() method exists only because the newtype
stores a String; change the inner type from String to url::Url so URL parsing
happens at construction and parsed_url() can become a simple infallible accessor
returning &Url (or expose the inner Url directly). Update the newtype definition
(the tuple struct holding self.0), constructors/parsers that currently accept
strings to parse into Url at creation, and replace calls to parsed_url() with
the new accessor to remove the needless Result handling.
- Line 21: The struct RaindexSignedContextOracleV1 currently exposes its inner
String as pub which allows callers to construct invalid instances and break the
URL validation invariant; make the inner field private (remove pub) so instances
can only be created through the validated constructors (new() and parse()),
update any call sites to use those constructors, and if deserialization/wasm
needs require construction add a custom serde::Deserialize impl or use
#[serde(try_from = "String")] that calls Url::parse (or wrap Url directly) so
parsed_url() can never fail at runtime.
| /// directly to `SignedContextV1`. | ||
| #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] | ||
| #[cfg_attr(target_family = "wasm", derive(Tsify))] | ||
| pub struct RaindexSignedContextOracleV1(pub String); |
There was a problem hiding this comment.
The pub inner field breaks the URL validation invariant.
new() and parse() ensure only valid URLs are stored, but pub String lets callers bypass this entirely:
// Compiles fine, no validation
let bad = RaindexSignedContextOracleV1("not a url".into());This also means parsed_url() can unexpectedly fail on an instance that was "successfully" constructed.
Make the field private to enforce the invariant:
Proposed fix
-pub struct RaindexSignedContextOracleV1(pub String);
+pub struct RaindexSignedContextOracleV1(String);If WASM/serde deserialization needs to construct this type, add a custom Deserialize impl (or a #[serde(try_from = "String")]) that validates via Url::parse. Based on learnings, the url crate is already a dependency and Url provides validation, type safety, and serde support — consider wrapping Url directly if Tsify/WASM constraints allow it.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@crates/cli/src/meta/types/raindex_signed_context_oracle/mod.rs` at line 21,
The struct RaindexSignedContextOracleV1 currently exposes its inner String as
pub which allows callers to construct invalid instances and break the URL
validation invariant; make the inner field private (remove pub) so instances can
only be created through the validated constructors (new() and parse()), update
any call sites to use those constructors, and if deserialization/wasm needs
require construction add a custom serde::Deserialize impl or use
#[serde(try_from = "String")] that calls Url::parse (or wrap Url directly) so
parsed_url() can never fail at runtime.
| pub fn parsed_url(&self) -> Result<Url, Error> { | ||
| Url::parse(&self.0).map_err(|e| Error::InvalidUrl(e.to_string())) | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
parsed_url() would be unnecessary if Url were stored directly.
If you keep String internally, this method is fine but its fallibility is misleading when the struct is properly constructed. If you switch the inner type to url::Url, this becomes a simple accessor and cannot fail. Based on learnings, in the rain.metadata crate, prefer wrapping url::Url instead of String for types that represent URLs.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@crates/cli/src/meta/types/raindex_signed_context_oracle/mod.rs` around lines
46 - 48, The parsed_url() method exists only because the newtype stores a
String; change the inner type from String to url::Url so URL parsing happens at
construction and parsed_url() can become a simple infallible accessor returning
&Url (or expose the inner Url directly). Update the newtype definition (the
tuple struct holding self.0), constructors/parsers that currently accept strings
to parse into Url at creation, and replace calls to parsed_url() with the new
accessor to remove the needless Result handling.
Motivation
Rain orders can consume
SignedContextV1data passed by takers, but there is no standard way for an order to advertise where takers should fetch that data. This metadata type solves the discovery problem.Solution
Registers a new
KnownMagic::SignedContextOracleV1(0xff7a1507ba4419ca) for order metadata. The payload is a single CBOR text string containing the oracle endpoint URL.KnownMagic::SignedContextOracleV1added to magic enum +TryFromKnownMeta::SignedContextOracleV1variant addedsigned_context_oraclemodule withSignedContextOracleV1struct:new(url)/url()— construct and readto_meta_item()— encode asRainMetaDocumentV1Itemcbor_encode()— encode as complete Rain meta documentfind_in_items()— extract from decoded meta itemsTryFrom<RainMetaDocumentV1Item>— decode from meta itemChecks
By submitting this for review, I'm confirming I've done the following:
Summary by CodeRabbit