Skip to content

Commit

Permalink
add oracle data to programs (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
JesseAbram authored Apr 25, 2024
1 parent 0e9d393 commit 38393c1
Show file tree
Hide file tree
Showing 15 changed files with 143 additions and 77 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ This will compile your program and put the `.wasm` binary file in `./binary-dir`
Before running the runtime tests, you need to build the `template-barebones`, `infinite-loop` and `example-custom-hash` components. To do this, execute:

```bash
cargo component build --release -p template-barebones -p infinite-loop -p example-custom-hash --target wasm32-unknown-unknown`
cargo component build --release -p template-barebones -p infinite-loop -p example-custom-hash --target wasm32-unknown-unknown
```

This will create the components in `target/wasm32-unknown-unknown/release/`.
Expand Down
12 changes: 8 additions & 4 deletions examples/barebones-with-auxilary/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ pub struct BarebonesWithAuxilary;
impl Program for BarebonesWithAuxilary {
/// This is the only function required by the program runtime. `signature_request` includes the message to be
/// signed, eg. RLP-serialized Ethereum transaction request, raw x86_64 executable, etc.
fn evaluate(signature_request: SignatureRequest, _config: Option<Vec<u8>>) -> Result<(), Error> {
fn evaluate(
signature_request: SignatureRequest,
_config: Option<Vec<u8>>,
_oracle_data: Option<Vec<u8>>,
) -> Result<(), Error> {
let SignatureRequest {
message,
auxilary_data,
Expand Down Expand Up @@ -57,7 +61,7 @@ mod tests {
auxilary_data: Some(vec![0x00]),
};

assert!(BarebonesWithAuxilary::evaluate(signature_request, None).is_ok());
assert!(BarebonesWithAuxilary::evaluate(signature_request, None, None).is_ok());
}

/// Note, the program is written s.t. if `message` is less than 10 bytes, the program will error.
Expand All @@ -69,7 +73,7 @@ mod tests {
auxilary_data: Some(vec![0x00]),
};

assert!(BarebonesWithAuxilary::evaluate(signature_request, None).is_err());
assert!(BarebonesWithAuxilary::evaluate(signature_request, None, None).is_err());
}

/// Note, the program is written s.t. if `auxilary_data` is `None`, the program will error.
Expand All @@ -81,6 +85,6 @@ mod tests {
auxilary_data: None,
};

assert!(BarebonesWithAuxilary::evaluate(signature_request, None).is_err());
assert!(BarebonesWithAuxilary::evaluate(signature_request, None, None).is_err());
}
}
10 changes: 7 additions & 3 deletions examples/barebones/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ pub struct BarebonesProgram;
impl Program for BarebonesProgram {
/// This is the only function required by the program runtime. `message` is the preimage of the curve element to be
/// signed, eg. RLP-serialized Ethereum transaction request, raw x86_64 executable, etc.
fn evaluate(signature_request: SignatureRequest, _config: Option<Vec<u8>>) -> Result<(), Error> {
fn evaluate(
signature_request: SignatureRequest,
_config: Option<Vec<u8>>,
_oracle_data: Option<Vec<u8>>,
) -> Result<(), Error> {
let message: Vec<u8> = signature_request.message;

// our program just checks that the length of the message is greater than 10
Expand Down Expand Up @@ -49,7 +53,7 @@ mod tests {
auxilary_data: None,
};

assert!(BarebonesProgram::evaluate(signature_request, None).is_ok());
assert!(BarebonesProgram::evaluate(signature_request, None, None).is_ok());
}

#[test]
Expand All @@ -60,6 +64,6 @@ mod tests {
auxilary_data: None,
};

assert!(BarebonesProgram::evaluate(signature_request, None).is_err());
assert!(BarebonesProgram::evaluate(signature_request, None, None).is_err());
}
}
52 changes: 33 additions & 19 deletions examples/basic-transaction/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ use entropy_programs::{
programs::acl::*,
};

use alloc::{vec::Vec, string::{String, ToString}, format};
use alloc::{
format,
string::{String, ToString},
vec::Vec,
};

use serde::{Deserialize, Serialize};
use serde_json;
use serde::{Serialize, Deserialize};

pub struct BasicTransaction;

Expand All @@ -26,22 +30,29 @@ impl Program for BasicTransaction {
/// This is the function that the programs engine will runtime esecute. signature_request is the preimage of the curve element to be
/// signed, eg. RLP-serialized Ethereum transaction request, raw x86_64 executable, etc.
// #[no_mangle]
fn evaluate(signature_request: SignatureRequest, config: Option<Vec<u8>>) -> Result<(), CoreError> {
fn evaluate(
signature_request: SignatureRequest,
config: Option<Vec<u8>>,
_oracle_data: Option<Vec<u8>>,
) -> Result<(), CoreError> {
// parse the raw tx into some type supported by the Acl check
let parsed_tx =
<Evm as Architecture>::TransactionRequest::try_parse(signature_request.message.as_slice())?;
let parsed_tx = <Evm as Architecture>::TransactionRequest::try_parse(
signature_request.message.as_slice(),
)?;

// construct a allowlist ACL from the config
let typed_config = serde_json::from_slice::<BasicTransactionConfig>(
config.ok_or(CoreError::Evaluation("No config provided.".to_string()))?.as_slice()
).map_err(|e| CoreError::Evaluation(format!("Failed to parse config: {}", e)))?;

let addresses: Vec<<Evm as Architecture>::AddressRaw> =
typed_config
.allowlisted_addresses
.iter()
.map(|a| hex::decode(a).unwrap().try_into().unwrap())
.collect();
config
.ok_or(CoreError::Evaluation("No config provided.".to_string()))?
.as_slice(),
)
.map_err(|e| CoreError::Evaluation(format!("Failed to parse config: {}", e)))?;

let addresses: Vec<<Evm as Architecture>::AddressRaw> = typed_config
.allowlisted_addresses
.iter()
.map(|a| hex::decode(a).unwrap().try_into().unwrap())
.collect();

let allowlisted_acl = Acl::<<Evm as Architecture>::AddressRaw> {
addresses,
Expand Down Expand Up @@ -75,27 +86,30 @@ mod tests {
"772b9a9e8aa1c9db861c6611a82d251db4fac990"
]
}
"#.as_bytes();
"#
.as_bytes();

#[test]
fn test_evaluate() {
let signature_request = SignatureRequest {
// `data` is an RLP serialized ETH transaction with the recipient set to `0x772b9a9e8aa1c9db861c6611a82d251db4fac990`
message: EVM_TX_WITH_ALLOWLISTED_RECIPIENT.to_vec(),
auxilary_data: None
auxilary_data: None,
};

assert!(BasicTransaction::evaluate(signature_request, Some(CONFIG.to_vec())).is_ok());
assert!(BasicTransaction::evaluate(signature_request, Some(CONFIG.to_vec()), None).is_ok());
}

#[test]
fn test_start_fail() {
let signature_request = SignatureRequest {
// `data` is the same as previous test, but recipient address ends in `1` instead of `0`, so it should fail
message: EVM_TX_WITH_NONALLOWLISTED_RECIPIENT.to_vec(),
auxilary_data: None
auxilary_data: None,
};

assert!(BasicTransaction::evaluate(signature_request, Some(CONFIG.to_vec())).is_err());
assert!(
BasicTransaction::evaluate(signature_request, Some(CONFIG.to_vec()), None).is_err()
);
}
}
6 changes: 5 additions & 1 deletion examples/custom-hash/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ register_custom_getrandom!(always_fail);
pub struct CustomHashExample;

impl Program for CustomHashExample {
fn evaluate(signature_request: SignatureRequest, _config: Option<Vec<u8>>) -> Result<(), Error> {
fn evaluate(
signature_request: SignatureRequest,
_config: Option<Vec<u8>>,
_oracle_data: Option<Vec<u8>>,
) -> Result<(), Error> {
if signature_request.message.len() < 1 {
return Err(Error::Evaluation(
"You need to give me SOME data to sign!".to_string(),
Expand Down
1 change: 1 addition & 0 deletions examples/device-key-proxy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ impl Program for DeviceKeyProxy {
fn evaluate(
signature_request: SignatureRequest,
raw_config: Option<Vec<u8>>,
_oracle_data: Option<Vec<u8>>,
) -> Result<(), Error> {
let config_json = serde_json::from_slice::<UserConfig>(
raw_config
Expand Down
67 changes: 43 additions & 24 deletions examples/device-key-proxy/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,12 @@ fn test_ok_for_only_device_key_signatures() {

let config_bytes = serde_json::to_vec(&json_config).unwrap();
// positive for edcsa
assert!(
DeviceKeyProxy::evaluate(request_from_device_key.clone(), Some(config_bytes.clone()))
.is_ok()
);
assert!(DeviceKeyProxy::evaluate(
request_from_device_key.clone(),
Some(config_bytes.clone()),
None
)
.is_ok());
// positive for sr25519
let context = signing_context(b"");

Expand All @@ -83,10 +85,12 @@ fn test_ok_for_only_device_key_signatures() {
.unwrap()
.into_bytes(),
);
assert!(
DeviceKeyProxy::evaluate(request_from_device_key.clone(), Some(config_bytes.clone()))
.is_ok()
);
assert!(DeviceKeyProxy::evaluate(
request_from_device_key.clone(),
Some(config_bytes.clone()),
None
)
.is_ok());
// positive for ed25519
let ed25519_device_key_signature: Ed25519Signature =
device_keys.ed25519_keys[0].sign(message.as_bytes());
Expand All @@ -101,7 +105,7 @@ fn test_ok_for_only_device_key_signatures() {
.unwrap()
.into_bytes(),
);
DeviceKeyProxy::evaluate(request_from_device_key, Some(config_bytes.clone())).unwrap();
DeviceKeyProxy::evaluate(request_from_device_key, Some(config_bytes.clone()), None).unwrap();
}

#[test]
Expand Down Expand Up @@ -159,9 +163,13 @@ fn test_fail_bad_signatures() {
let config_bytes = serde_json::to_vec(&json_config).unwrap();
// fail for edcsa
assert_eq!(
DeviceKeyProxy::evaluate(request_from_device_key.clone(), Some(config_bytes.clone()))
.unwrap_err()
.to_string(),
DeviceKeyProxy::evaluate(
request_from_device_key.clone(),
Some(config_bytes.clone()),
None
)
.unwrap_err()
.to_string(),
"Error::InvalidSignatureRequest(\"Unable to verify ecdsa signature\")"
);
let sr25519_non_device_key_signature: Sr25519Signature =
Expand All @@ -179,9 +187,13 @@ fn test_fail_bad_signatures() {
.into_bytes(),
);
assert_eq!(
DeviceKeyProxy::evaluate(request_from_device_key.clone(), Some(config_bytes.clone()))
.unwrap_err()
.to_string(),
DeviceKeyProxy::evaluate(
request_from_device_key.clone(),
Some(config_bytes.clone()),
None
)
.unwrap_err()
.to_string(),
"Error::InvalidSignatureRequest(\"Unable to verify sr25519 signature\")"
);
// fail for ed25519
Expand All @@ -199,9 +211,13 @@ fn test_fail_bad_signatures() {
.into_bytes(),
);
assert_eq!(
DeviceKeyProxy::evaluate(request_from_device_key.clone(), Some(config_bytes.clone()))
.unwrap_err()
.to_string(),
DeviceKeyProxy::evaluate(
request_from_device_key.clone(),
Some(config_bytes.clone()),
None
)
.unwrap_err()
.to_string(),
"Error::InvalidSignatureRequest(\"Unable to verify ed25519 signature\")"
);
}
Expand Down Expand Up @@ -258,7 +274,8 @@ fn test_fails_pub_key_not_found() {
assert_eq!(
DeviceKeyProxy::evaluate(
request_from_non_device_key.clone(),
Some(config_bytes.clone())
Some(config_bytes.clone()),
None
)
.unwrap_err()
.to_string(),
Expand All @@ -284,7 +301,8 @@ fn test_fails_pub_key_not_found() {
assert_eq!(
DeviceKeyProxy::evaluate(
request_from_non_device_key.clone(),
Some(config_bytes.clone())
Some(config_bytes.clone()),
None
)
.unwrap_err()
.to_string(),
Expand All @@ -306,7 +324,7 @@ fn test_fails_pub_key_not_found() {
.into_bytes(),
);
assert_eq!(
DeviceKeyProxy::evaluate(request_from_non_device_key, Some(config_bytes))
DeviceKeyProxy::evaluate(request_from_non_device_key, Some(config_bytes), None)
.unwrap_err()
.to_string(),
"Error::InvalidSignatureRequest(\"Ed25519 Public key not in config\")"
Expand Down Expand Up @@ -347,7 +365,8 @@ fn test_fails_with_no_aux_or_config() {
assert_eq!(
DeviceKeyProxy::evaluate(
request_from_device_key_no_aux.clone(),
Some(config_bytes.clone())
Some(config_bytes.clone()),
None
)
.unwrap_err()
.to_string(),
Expand Down Expand Up @@ -378,7 +397,7 @@ fn test_fails_with_no_aux_or_config() {
),
};
assert_eq!(
DeviceKeyProxy::evaluate(request_from_device_key.clone(), None)
DeviceKeyProxy::evaluate(request_from_device_key.clone(), None, None)
.unwrap_err()
.to_string(),
"Error::Evaluation(\"No config provided.\")"
Expand All @@ -391,7 +410,7 @@ fn test_fails_with_no_aux_or_config() {
.into_bytes(),
);
assert_eq!(
DeviceKeyProxy::evaluate(request_from_device_key, Some(config_bytes.clone()))
DeviceKeyProxy::evaluate(request_from_device_key, Some(config_bytes.clone()), None)
.unwrap_err()
.to_string(),
"Error::InvalidSignatureRequest(\"Invalid public key type\")"
Expand Down
6 changes: 5 additions & 1 deletion examples/infinite-loop/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ pub struct InfiniteLoop;
impl Program for InfiniteLoop {
/// This is the only function required by the program runtime. `message` is the preimage of the curve element to be
/// signed, eg. RLP-serialized Ethereum transaction request, raw x86_64 executable, etc.
fn evaluate(_signature_request: SignatureRequest, _config: Option<Vec<u8>>) -> Result<(), Error> {
fn evaluate(
_signature_request: SignatureRequest,
_config: Option<Vec<u8>>,
_oracle_data: Option<Vec<u8>>,
) -> Result<(), Error> {
loop {}
#[allow(unreachable_code)]
Ok(())
Expand Down
10 changes: 7 additions & 3 deletions examples/private-acl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ register_custom_getrandom!(always_fail);
impl Program for PrivateTransactionAcl {
/// Allow any address given in the pre-defined list (addresses.txt)
// #[no_mangle]
fn evaluate(signature_request: SignatureRequest, _config: Option<Vec<u8>>) -> Result<(), CoreError> {
fn evaluate(
signature_request: SignatureRequest,
_config: Option<Vec<u8>>,
_oracle_data: Option<Vec<u8>>,
) -> Result<(), CoreError> {
// parse the raw tx into some type
let parsed_tx = <Evm as Architecture>::TransactionRequest::try_parse(
signature_request.message.as_slice(),
Expand Down Expand Up @@ -72,7 +76,7 @@ mod tests {
auxilary_data: None,
};

assert!(PrivateTransactionAcl::evaluate(signature_request, None).is_ok());
assert!(PrivateTransactionAcl::evaluate(signature_request, None, None).is_ok());
}

#[test]
Expand All @@ -83,6 +87,6 @@ mod tests {
auxilary_data: None,
};

assert!(PrivateTransactionAcl::evaluate(signature_request, None).is_err());
assert!(PrivateTransactionAcl::evaluate(signature_request, None, None).is_err());
}
}
Loading

0 comments on commit 38393c1

Please sign in to comment.