Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion rs/ethereum/cketh/minter/cketh_minter.did
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,38 @@ type EthereumNetwork = variant {

type Subaccount = blob;

type environment_variable = record {
name: text;
value: text;
};

type CanisterStatusResponse = record {
query_stats : QueryStats;
status : CanisterStatusType;
ready_for_migration : bool;
version : nat64;
memory_size : nat;
cycles : nat;
settings : DefiniteCanisterSettings;
idle_cycles_burned_per_day : nat;
module_hash : opt vec nat8;
query_stats : QueryStats;
reserved_cycles : nat;
memory_metrics : MemoryMetrics;
};

type CanisterStatusType = variant { stopped; stopping; running };

type MemoryMetrics = record {
wasm_memory_size : nat;
stable_memory_size : nat;
global_memory_size : nat;
wasm_binary_size : nat;
custom_sections_size : nat;
canister_history_size : nat;
wasm_chunk_store_size : nat;
snapshots_size : nat;
};

type DefiniteCanisterSettings = record {
freezing_threshold : nat;
controllers : vec principal;
Expand All @@ -28,6 +47,8 @@ type DefiniteCanisterSettings = record {
reserved_cycles_limit : nat;
log_visibility: LogVisibility;
wasm_memory_limit : nat;
wasm_memory_threshold : nat;
environment_variables : vec environment_variable;
};

type LogVisibility = variant {
Expand Down
20 changes: 8 additions & 12 deletions rs/ethereum/cketh/minter/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![allow(deprecated)]
use crate::dashboard::DashboardPaginationParameters;
use candid::Nat;
use dashboard::DashboardTemplate;
Expand Down Expand Up @@ -60,7 +59,7 @@ pub const SEPOLIA_TEST_CHAIN_ID: u64 = 11155111;
pub const CKETH_LEDGER_TRANSACTION_FEE: Wei = Wei::new(2_000_000_000_000_u128);

fn validate_caller_not_anonymous() -> candid::Principal {
let principal = ic_cdk::caller();
let principal = ic_cdk::api::msg_caller();
if principal == candid::Principal::anonymous() {
panic!("anonymous principal is not allowed");
}
Expand Down Expand Up @@ -564,7 +563,7 @@ fn is_address_blocked(address_string: String) -> bool {
async fn add_ckerc20_token(erc20_token: AddCkErc20Token) {
let orchestrator_id = read_state(|s| s.ledger_suite_orchestrator_id)
.unwrap_or_else(|| ic_cdk::trap("ERROR: ERC-20 feature is not activated"));
if orchestrator_id != ic_cdk::caller() {
if orchestrator_id != ic_cdk::api::msg_caller() {
ic_cdk::trap(format!(
"ERROR: only the orchestrator {orchestrator_id} can add ERC-20 tokens"
));
Expand All @@ -575,15 +574,12 @@ async fn add_ckerc20_token(erc20_token: AddCkErc20Token) {
}

#[update]
async fn get_canister_status() -> ic_cdk::api::management_canister::main::CanisterStatusResponse {
ic_cdk::api::management_canister::main::canister_status(
ic_cdk::api::management_canister::main::CanisterIdRecord {
canister_id: ic_cdk::id(),
},
)
async fn get_canister_status() -> ic_cdk::management_canister::CanisterStatusResult {
ic_cdk::management_canister::canister_status(&ic_cdk::management_canister::CanisterStatusArgs {
canister_id: ic_cdk::api::canister_self(),
})
.await
.expect("failed to fetch canister status")
.0
}

#[query]
Expand Down Expand Up @@ -919,7 +915,7 @@ fn http_request(req: HttpRequest) -> HttpResponse {
read_state(|s| {
w.encode_gauge(
"stable_memory_bytes",
ic_cdk::api::stable::stable_size() as f64 * WASM_PAGE_SIZE_IN_BYTES,
ic_cdk::stable::stable_size() as f64 * WASM_PAGE_SIZE_IN_BYTES,
"Size of the stable memory allocated by this canister.",
)?;

Expand All @@ -932,7 +928,7 @@ fn http_request(req: HttpRequest) -> HttpResponse {
w.gauge_vec("cycle_balance", "Cycle balance of this canister.")?
.value(
&[("canister", "cketh-minter")],
ic_cdk::api::canister_balance128() as f64,
ic_cdk::api::canister_cycle_balance() as f64,
)?;

w.encode_gauge(
Expand Down
60 changes: 40 additions & 20 deletions rs/ethereum/cketh/minter/src/management.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![allow(deprecated)]
use ic_cdk::api::call::RejectionCode;
use ic_cdk::call::{CallFailed, RejectCode};
use ic_cdk::management_canister::SignCallError;
use ic_management_canister_types_private::DerivationPath;
use std::fmt;

Expand Down Expand Up @@ -64,17 +64,39 @@ impl fmt::Display for Reason {
}

impl Reason {
fn from_reject(reject_code: RejectionCode, reject_message: String) -> Self {
match reject_code {
RejectionCode::SysTransient => Self::TransientInternalError(reject_message),
RejectionCode::CanisterError => Self::CanisterError(reject_message),
RejectionCode::CanisterReject => Self::Rejected(reject_message),
RejectionCode::NoError
| RejectionCode::SysFatal
| RejectionCode::DestinationInvalid
| RejectionCode::Unknown => Self::InternalError(format!(
"rejection code: {reject_code:?}, rejection message: {reject_message}"
)),
fn from_sign_call_error(error: SignCallError) -> Self {
match error {
SignCallError::CallFailed(failed) => Self::from_call_failed(failed),
SignCallError::SignCostError(e) => {
Self::InternalError(format!("signature cost calculation failed: {e}"))
}
SignCallError::CandidDecodeFailed(e) => {
Self::InternalError(format!("candid decode failed: {e}"))
}
}
}

fn from_call_failed(failed: CallFailed) -> Self {
match failed {
CallFailed::CallRejected(rejected) => {
let message = rejected.reject_message().to_string();
match rejected.reject_code() {
Ok(RejectCode::SysTransient) => Self::TransientInternalError(message),
Ok(RejectCode::CanisterError) => Self::CanisterError(message),
Ok(RejectCode::CanisterReject) => Self::Rejected(message),
Ok(code) => Self::InternalError(format!(
"rejection code: {code:?}, rejection message: {message}"
)),
Err(_) => Self::InternalError(format!(
"unrecognized rejection code: {}, rejection message: {message}",
rejected.raw_reject_code()
)),
}
}
CallFailed::InsufficientLiquidCycleBalance(_) => Self::OutOfCycles,
CallFailed::CallPerformFailed(_) => {
Self::InternalError("call_perform failed".to_string())
Comment on lines +97 to +98
}
}
}
}
Expand All @@ -85,11 +107,9 @@ pub async fn sign_with_ecdsa(
derivation_path: DerivationPath,
message_hash: [u8; 32],
) -> Result<[u8; 64], CallError> {
use ic_cdk::api::management_canister::ecdsa::{
EcdsaCurve, EcdsaKeyId, SignWithEcdsaArgument, sign_with_ecdsa,
};
use ic_cdk::management_canister::{EcdsaCurve, EcdsaKeyId, SignWithEcdsaArgs, sign_with_ecdsa};

let result = sign_with_ecdsa(SignWithEcdsaArgument {
let result = sign_with_ecdsa(&SignWithEcdsaArgs {
message_hash: message_hash.to_vec(),
derivation_path: derivation_path.into_inner(),
key_id: EcdsaKeyId {
Expand All @@ -100,17 +120,17 @@ pub async fn sign_with_ecdsa(
.await;

match result {
Ok((reply,)) => {
Ok(reply) => {
let signature_length = reply.signature.len();
Ok(<[u8; 64]>::try_from(reply.signature).unwrap_or_else(|_| {
panic!(
"BUG: invalid signature from management canister. Expected 64 bytes but got {signature_length} bytes"
)
}))
}
Err((code, msg)) => Err(CallError {
Err(error) => Err(CallError {
method: "sign_with_ecdsa".to_string(),
reason: Reason::from_reject(code, msg),
reason: Reason::from_sign_call_error(error),
}),
}
}
19 changes: 7 additions & 12 deletions rs/ethereum/cketh/minter/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![allow(deprecated)]
use crate::address::ecdsa_public_key_to_address;
use crate::endpoints::CandidBlockTag;
use crate::erc20::{CkErc20Token, CkTokenSymbol};
Expand All @@ -16,7 +15,7 @@ use crate::state::transactions::{Erc20WithdrawalRequest, TransactionCallData, Wi
use crate::tx::GasFeeEstimate;
use candid::Principal;
use ic_canister_log::log;
use ic_cdk::api::management_canister::ecdsa::EcdsaPublicKeyResponse;
use ic_cdk::management_canister::EcdsaPublicKeyResult;
use ic_ethereum_types::Address;
use ic_secp256k1::PublicKey;
use std::cell::RefCell;
Expand Down Expand Up @@ -57,7 +56,7 @@ pub struct State {
pub ecdsa_key_name: String,
pub cketh_ledger_id: Principal,
pub log_scrapings: LogScrapings,
pub ecdsa_public_key: Option<EcdsaPublicKeyResponse>,
pub ecdsa_public_key: Option<EcdsaPublicKeyResult>,
pub cketh_minimum_withdrawal_amount: Wei,
pub ethereum_block_height: CandidBlockTag,
pub first_scraped_block_number: BlockNumber,
Expand Down Expand Up @@ -609,11 +608,11 @@ where
}

pub async fn lazy_call_ecdsa_public_key() -> PublicKey {
use ic_cdk::api::management_canister::ecdsa::{
EcdsaCurve, EcdsaKeyId, EcdsaPublicKeyArgument, ecdsa_public_key,
use ic_cdk::management_canister::{
EcdsaCurve, EcdsaKeyId, EcdsaPublicKeyArgs, ecdsa_public_key,
};

fn to_public_key(response: &EcdsaPublicKeyResponse) -> PublicKey {
fn to_public_key(response: &EcdsaPublicKeyResult) -> PublicKey {
PublicKey::deserialize_sec1(&response.public_key).unwrap_or_else(|e| {
ic_cdk::trap(format!("failed to decode minter's public key: {e:?}"))
})
Expand All @@ -624,7 +623,7 @@ pub async fn lazy_call_ecdsa_public_key() -> PublicKey {
}
let key_name = read_state(|s| s.ecdsa_key_name.clone());
log!(DEBUG, "Fetching the ECDSA public key {key_name}");
let (response,) = ecdsa_public_key(EcdsaPublicKeyArgument {
let response = ecdsa_public_key(&EcdsaPublicKeyArgs {
canister_id: None,
derivation_path: crate::MAIN_DERIVATION_PATH
.into_iter()
Expand All @@ -636,11 +635,7 @@ pub async fn lazy_call_ecdsa_public_key() -> PublicKey {
},
})
.await
.unwrap_or_else(|(error_code, message)| {
ic_cdk::trap(format!(
"failed to get minter's public key: {message} (error code = {error_code:?})",
))
});
.unwrap_or_else(|err| ic_cdk::trap(format!("failed to get minter's public key: {err}")));
mutate_state(|s| s.ecdsa_public_key = Some(response.clone()));
to_public_key(&response)
}
Expand Down
5 changes: 2 additions & 3 deletions rs/ethereum/cketh/minter/src/state/tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![allow(deprecated)]
use crate::endpoints::CandidBlockTag;
use crate::eth_logs::{EventSource, ReceivedErc20Event, ReceivedEthEvent, ReceivedEvent};
use crate::eth_rpc_client::responses::{TransactionReceipt, TransactionStatus};
Expand Down Expand Up @@ -807,7 +806,7 @@ fn state_equivalence() {
use crate::tx::{
Eip1559Signature, Eip1559TransactionRequest, SignedTransactionRequest, TransactionRequest,
};
use ic_cdk::api::management_canister::ecdsa::EcdsaPublicKeyResponse;
use ic_cdk::management_canister::EcdsaPublicKeyResult;
use maplit::{btreemap, btreeset};

fn source(txhash: &str, index: u64) -> EventSource {
Expand Down Expand Up @@ -994,7 +993,7 @@ fn state_equivalence() {
ecdsa_key_name: "test_key".to_string(),
cketh_ledger_id: "apia6-jaaaa-aaaar-qabma-cai".parse().unwrap(),
log_scrapings: log_scrapings.clone(),
ecdsa_public_key: Some(EcdsaPublicKeyResponse {
ecdsa_public_key: Some(EcdsaPublicKeyResult {
public_key: vec![1; 32],
chain_code: vec![2; 32],
}),
Expand Down
5 changes: 1 addition & 4 deletions rs/ethereum/cketh/test_utils/src/mock.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#![allow(deprecated)]
use crate::{CkEthSetup, JsonRpcProvider, MAX_TICKS, assert_reply};
use candid::{Decode, Encode};
use ic_cdk::api::management_canister::http_request::{
HttpResponse as OutCallHttpResponse, TransformArgs,
};
use ic_cdk::management_canister::{HttpRequestResult as OutCallHttpResponse, TransformArgs};
use ic_error_types::RejectCode;
use ic_management_canister_types_private::CanisterHttpResponsePayload;
use ic_state_machine_tests::{PayloadBuilder, StateMachine};
Expand Down
Loading