Skip to content

Commit

Permalink
fix: resolved mutate request
Browse files Browse the repository at this point in the history
  • Loading branch information
alenmestrov committed Dec 2, 2024
1 parent 590cdec commit 28a20c5
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 74 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions contracts/icp/context-config/.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# DFX CANISTER ENVIRONMENT VARIABLES
DFX_VERSION='0.24.2'
DFX_NETWORK='local'
CANISTER_ID_CONTEXT_CONTRACT='bw4dl-smaaa-aaaaa-qaacq-cai'
CANISTER_ID='bw4dl-smaaa-aaaaa-qaacq-cai'
CANISTER_ID_CONTEXT_CONTRACT='cpmcr-yeaaa-aaaaa-qaala-cai'
CANISTER_ID='cpmcr-yeaaa-aaaaa-qaala-cai'
CANISTER_CANDID_PATH='/Users/alen/www/calimero/core/contracts/icp/context-config/context_contract.did'
# END DFX CANISTER ENVIRONMENT VARIABLES
2 changes: 1 addition & 1 deletion contracts/icp/context-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ thiserror.workspace = true

[dev-dependencies]
pocket-ic = "6.0.0"
rand = "0.8"
rand.workspace = true
ed25519-dalek = "2.0"
Empty file modified contracts/icp/context-config/deploy_devnet.sh
100644 → 100755
Empty file.
4 changes: 2 additions & 2 deletions contracts/icp/context-config/src/mutate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ pub fn mutate(signed_request: ICPSigned<Request>) -> Result<(), String> {
.map_err(|e| format!("Failed to verify signature: {}", e))?;

// Check request timestamp
let current_time = ic_cdk::api::time();
if current_time.saturating_sub(request.timestamp_ms) > 1000 * 5 {
let current_time_ms = ic_cdk::api::time() / 1_000_000; // Convert nanoseconds to milliseconds
if current_time_ms.saturating_sub(request.timestamp_ms) > 5_000 {
// 5 seconds threshold
return Err("request expired".to_string());
}
Expand Down
35 changes: 26 additions & 9 deletions crates/context/config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@ license.workspace = true
[dependencies]
bs58.workspace = true
borsh = { workspace = true, features = ["derive"] }
candid.workspace = true
ed25519-consensus.workspace = true
candid = { workspace = true, optional = true }
ed25519-consensus = { workspace = true, optional = true }
ed25519-dalek.workspace = true
either = { workspace = true, optional = true }
eyre = { workspace = true, optional = true }
hex.workspace = true
ic-agent.workspace = true
ic-cdk.workspace = true
ic-cdk-macros.workspace = true
rand.workspace = true
hex = { workspace = true, optional = true }
ic-agent = { workspace = true, optional = true }
ic-cdk = { workspace = true, optional = true }
ic-cdk-macros = { workspace = true, optional = true }
near-crypto = { workspace = true, optional = true }
near-jsonrpc-client = { workspace = true, optional = true }
near-jsonrpc-primitives = { workspace = true, optional = true }
Expand All @@ -37,15 +36,33 @@ workspace = true

[features]
client = [
"near",
"icp",
"starknet",
"dep:either",
"dep:eyre",
"reqwest/json",
"url/serde",
]

near = [
"dep:near-crypto",
"dep:near-jsonrpc-client",
"dep:near-jsonrpc-primitives",
"dep:near-primitives",
"reqwest/json",
]

icp = [
"dep:candid",
"dep:ic-agent",
"dep:ic-cdk",
"dep:ic-cdk-macros",
"dep:ed25519-consensus",
]

starknet = [
"dep:hex",
"dep:starknet",
"dep:starknet-crypto",
"dep:starknet-types-core",
"url/serde",
]
19 changes: 9 additions & 10 deletions crates/context/config/src/client/env/config/mutate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,23 +140,22 @@ impl<'a> Method<Icp> for Mutate<'a> {
let request = ICPRequest::new(signer_sk.verifying_key().rt()?, self.kind.into());

let signed = ICPSigned::new(request, |b| signer_sk.sign(b))?;

let encoded2 = Encode!(&signed)?;


let encoded = candid::encode_one(&signed)?;

println!("encoded: {:?}", encoded);
println!("encoded2: {:?}", encoded2);

Ok(encoded)
}

fn decode(response: Vec<u8>) -> eyre::Result<Self::Returns> {
if !response.is_empty() {
eyre::bail!("unexpected response {:?}", response);
if response.is_empty() {
// Empty response means success
Ok(())
} else {
// Non-empty response means there was an error message
let error_msg = String::from_utf8(response)
.map_err(|e| eyre::eyre!("Invalid UTF-8 in error message: {}", e))?;
eyre::bail!("{}", error_msg)
}

Ok(())
}
}

Expand Down
12 changes: 11 additions & 1 deletion crates/context/config/src/client/env/config/types/icp.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::borrow::Cow;
use std::marker::PhantomData;
use std::time;

use bs58::decode::Result as Bs58Result;
use candid::CandidType;
Expand Down Expand Up @@ -283,10 +284,19 @@ pub struct ICPRequest {

impl ICPRequest {
pub fn new(signer_id: ICSignerId, kind: ICPRequestKind) -> Self {
#[expect(
clippy::cast_possible_truncation,
reason = "This is never expected to overflow"
)]
let timestamp_ms = time::SystemTime::now()
.duration_since(time::UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64;

Self {
signer_id,
kind,
timestamp_ms: 0, // Default timestamp for tests
timestamp_ms,
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::collections::BTreeMap;

use hex;
use starknet::core::codec::{Decode, Encode, Error, FeltWriter};
use starknet::core::types::Felt;

Expand Down
67 changes: 20 additions & 47 deletions crates/context/config/src/client/protocol/icp.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
use std::borrow::Cow;
use std::collections::BTreeMap;

use candid::{decode_one, Result as CandidResult};
use ed25519_consensus::SigningKey;
use ed25519_dalek::{Signer, SigningKey as DSigningKey};
use ic_agent::agent::CallResponse;
use ic_agent::export::Principal;
use ic_agent::Agent;
use rand::rngs::OsRng;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use url::Url;

use super::Protocol;
use crate::client::env::config::types::icp::{
ICApplication, ICApplicationId, ICBlobId, ICContextId, ICContextIdentity, ICPContextRequest,
ICPContextRequestKind, ICPRequest, ICPRequestKind, ICPSigned, ICSignerId,
};
use crate::client::transport::{
AssociatedTransport, Operation, ProtocolTransport, TransportRequest,
};
Expand Down Expand Up @@ -218,37 +213,6 @@ impl Network {
method: String,
args: Vec<u8>,
) -> Result<Vec<u8>, IcpError> {
let current_time: u64 = 1733150708000u64;

let sign_key = DSigningKey::from_bytes(&[0u8; 32]);
let context_pk = sign_key.verifying_key();

let context_id = ICContextId::new(context_pk.to_bytes());

let request = ICPRequest {
kind: ICPRequestKind::Context(ICPContextRequest {
context_id: context_id.clone(),
kind: ICPContextRequestKind::Add {
author_id: ICContextIdentity::new([0u8; 32]),
application: ICApplication {
id: ICApplicationId::new([0u8; 32]),
blob: ICBlobId::new([0u8; 32]),
size: 0,
source: String::new(),
metadata: vec![],
},
},
}),
signer_id: ICSignerId::new(context_id.as_bytes()),
timestamp_ms: current_time,
};

let sign_req = ICPSigned::new(request, |bytes| sign_key.sign(bytes))
.expect("Failed to create signed request");

println!("Sign request: {:?}", sign_req);

let args_encoded = candid::encode_one(sign_req).unwrap();
self.client
.fetch_root_key()
.await
Expand All @@ -260,19 +224,28 @@ impl Network {
let response = self
.client
.update(canister_id, method)
.with_arg(args_encoded)
.with_arg(args)
.call()
.await;

match response {
Ok(CallResponse::Response((data, _certificate))) => Ok(data),
Ok(CallResponse::Poll(_)) => Err(IcpError::Custom {
operation: ErrorOperation::Query,
reason: "Unexpected Poll response".to_string(),
}),
Err(err) => Err(IcpError::Custom {
operation: ErrorOperation::Query,
reason: err.to_string(),
}),
Ok(CallResponse::Response((data, _))) => {
// Now try to decode the actual data
match candid::decode_one::<Result<(), String>>(&data) {
Ok(decoded) => {
match decoded {
Ok(()) => Ok(vec![]), // Return empty vec for success
Err(err_msg) => Ok(err_msg.into_bytes()) // Return error message as bytes
}
},
Err(e) => {
println!("Failed to decode: {}", e);
Ok(e.to_string().into_bytes()) // Return decode error as bytes
}
}
},
Ok(CallResponse::Poll(_)) => Ok("Unexpected polling response".as_bytes().to_vec()),
Err(err) => Ok(err.to_string().into_bytes()),
}
}
}

0 comments on commit 28a20c5

Please sign in to comment.