From b300dab62e0bd77ff9a6341dab4988459dcaed78 Mon Sep 17 00:00:00 2001 From: JesseAbram <33698952+JesseAbram@users.noreply.github.com> Date: Fri, 15 Nov 2024 10:37:12 -0500 Subject: [PATCH] Add an example of oracle data use (#93) * Add an example of oracle use * fix oracle example * Update examples/oracle-example/Cargo.toml Co-authored-by: peg * Update examples/oracle-example/src/lib.rs Co-authored-by: peg --------- Co-authored-by: peg --- examples/oracle-example/Cargo.toml | 31 +++++++++++ examples/oracle-example/src/lib.rs | 84 ++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 examples/oracle-example/Cargo.toml create mode 100644 examples/oracle-example/src/lib.rs diff --git a/examples/oracle-example/Cargo.toml b/examples/oracle-example/Cargo.toml new file mode 100644 index 0000000..4baa1d0 --- /dev/null +++ b/examples/oracle-example/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "oracle-example" +version = "0.1.0" +authors = ["Entropy Cryptography "] +homepage = "https://entropy.xyz/" +license = "Unlicense" +repository = "https://github.com/entropyxyz/programs" +edition = "2021" + + +# This is required to compile programs to a wasm module and for use in rust libs +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +entropy-programs-core = { workspace = true } +schemars = {version = "0.8.16", optional = true} +serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] } +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } +# These are used by `cargo component` +[package.metadata.component] +package = "entropy:oracle-example" + +[package.metadata.component.target] +path = "../../wit" + +[package.metadata.component.dependencies] + + +[features] +std = ["schemars"] \ No newline at end of file diff --git a/examples/oracle-example/src/lib.rs b/examples/oracle-example/src/lib.rs new file mode 100644 index 0000000..169fa4f --- /dev/null +++ b/examples/oracle-example/src/lib.rs @@ -0,0 +1,84 @@ +//! This example shows how to write a contrieved and basic program: checking the length of the data to be signed. + +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; + +use alloc::{string::ToString, vec::Vec}; +use codec::Decode; +use entropy_programs_core::{bindgen::Error, bindgen::*, export_program, prelude::*}; +use serde::{Deserialize, Serialize}; +/// JSON-deserializable struct that will be used to derive the program-JSON interface. +#[cfg_attr(feature = "std", derive(schemars::JsonSchema))] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +pub struct UserConfig {} + +/// JSON representation of the auxiliary data +#[cfg_attr(feature = "std", derive(schemars::JsonSchema))] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +pub struct AuxData {} + +// TODO confirm this isn't an issue for audit +register_custom_getrandom!(always_fail); + +pub struct OracleExample; + +impl Program for OracleExample { + fn evaluate( + _signature_request: SignatureRequest, + _config: Option>, + oracle_data: Option>>, + ) -> Result<(), Error> { + let data = oracle_data.ok_or(Error::Evaluation("No oracle data provided.".to_string()))?; + let block_number = u32::decode(&mut data[0].as_ref()) + .map_err(|_| Error::Evaluation("Unable to decode oracle data".to_string()))?; + // our program just checks that the block number is greater than 100 + if block_number > 100 { + return Err(Error::Evaluation("Block Number too large".to_string())); + } + + Ok(()) + } + + /// Since we don't use a custom hash function, we can just return `None` here. + fn custom_hash(_data: Vec) -> Option> { + None + } +} + +export_program!(OracleExample); + +// write a test that calls evaluate and passes it the proper parameters +#[cfg(test)] +mod tests { + use super::*; + use alloc::vec; + use codec::Encode; + + #[test] + fn test_should_sign() { + let signature_request = SignatureRequest { + message: "".to_string().into_bytes(), + auxilary_data: None, + }; + + assert!( + OracleExample::evaluate(signature_request, None, Some(vec![99u32.encode()])).is_ok() + ); + } + + #[test] + fn test_should_error() { + let signature_request = SignatureRequest { + message: "".to_string().into_bytes(), + auxilary_data: None, + }; + + assert_eq!( + OracleExample::evaluate(signature_request, None, Some(vec![101u32.encode()])) + .unwrap_err() + .to_string(), + "Error::Evaluation(\"Block Number too large\")" + ); + } +}