Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat introduced icp nonces for context contract #1031

Open
wants to merge 28 commits into
base: feat--add-near-calls-nonce
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
945be8f
fix: remove timestamp from contracts
frdomovic Dec 20, 2024
bbd07ee
fix: tests 2
frdomovic Dec 20, 2024
964fa46
fix: removed prints in mock contract, optimized proxy contract deploy…
alenmestrov Dec 20, 2024
9bbc038
feat: introduced nonces in icp context contract
alenmestrov Dec 20, 2024
545b72d
fix: lint
alenmestrov Dec 20, 2024
39e5c26
fix: check the transfer result before doing cross contract call
alenmestrov Dec 20, 2024
2fa86ac
fix: resolved PR comments
alenmestrov Dec 20, 2024
d3d22a7
fix:lint
alenmestrov Dec 20, 2024
fcd5b3a
fix: reverted back grouping of members and nonces
alenmestrov Dec 20, 2024
14db1bb
fix: lint
alenmestrov Dec 20, 2024
bc99546
fix: resolved PR comments
alenmestrov Dec 20, 2024
244aab0
simplify nonce validation
miraclx Dec 20, 2024
0182e26
prevent spurious proxy deployment for existing context
miraclx Dec 20, 2024
647192c
pulled latest changes
alenmestrov Dec 23, 2024
f440214
fix: removed mock_ledger from Cargo
alenmestrov Dec 23, 2024
dcac961
fix: lint
alenmestrov Dec 23, 2024
d73e5e5
merged feat--add-near-calls-nonce
alenmestrov Dec 23, 2024
af88a83
fix: removed mock_ledger build process
alenmestrov Dec 23, 2024
ba80769
feat: added automated script for devnet deployment
alenmestrov Dec 23, 2024
a5f839d
fix: resolved issue with NEAR nonce
alenmestrov Dec 23, 2024
42a9528
feat: added container_ids.json file to gitignore
alenmestrov Dec 23, 2024
df5b56f
fix: check if canister_ids.json file exists before trying to delete it
alenmestrov Dec 23, 2024
84ff731
fix: fixed getting proxy contract wasm content
alenmestrov Dec 23, 2024
f99d909
fix: fixed fetching nonce encoding
alenmestrov Dec 24, 2024
95d0d1d
fix: updated script for devnet deployment, adjusted initial context c…
alenmestrov Dec 26, 2024
5fb103d
feat: implemented endpoint for fetching proxy contract ID
alenmestrov Dec 26, 2024
5ee39c9
fix: lint
alenmestrov Dec 26, 2024
8912db4
fix: cleaned deployment script and created test recipient account
alenmestrov Dec 26, 2024
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
679 changes: 485 additions & 194 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ members = [

"./contracts/icp/context-config",
"./contracts/icp/context-proxy",
"./contracts/icp/context-proxy/mock/ledger",
"./contracts/icp/context-proxy/mock/external",

"./e2e-tests",
Expand Down
1 change: 1 addition & 0 deletions contracts/icp/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ dist/
pocket-ic

!**/res/*.did
**/canister_ids.json
3 changes: 2 additions & 1 deletion contracts/icp/context-config/.env
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@

# DFX CANISTER ENVIRONMENT VARIABLES
DFX_VERSION='0.24.2'
DFX_VERSION='0.24.3'
DFX_NETWORK='local'
CANISTER_ID_LEDGER='bd3sg-teaaa-aaaaa-qaaba-cai'
CANISTER_ID_CONTEXT_CONTRACT='bkyz2-fmaaa-aaaaa-qaaaq-cai'
CANISTER_ID='bkyz2-fmaaa-aaaaa-qaaaq-cai'
CANISTER_CANDID_PATH='/Users/alen/www/calimero/core/contracts/icp/context-config/./res/calimero_context_config_icp.did'
Expand Down
126 changes: 119 additions & 7 deletions contracts/icp/context-config/deploy_devnet.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,125 @@
#!/bin/bash
set -e

# Build the contract
./build.sh
# Function to generate a new identity and return its principal
generate_identity() {
local name=$1
dfx identity new "$name" --storage-mode=plaintext || true
dfx identity use "$name"
dfx identity get-principal
}

# Function to get account ID from principal
get_account_id() {
local principal=$1
dfx ledger account-id --of-principal "$principal"
}

# Generate minting account
dfx identity new minting --storage-mode=plaintext || true
dfx identity use minting
MINTING_PRINCIPAL=$(dfx identity get-principal)
MINTING_ACCOUNT=$(get_account_id "$MINTING_PRINCIPAL")

# Generate initial account
dfx identity new initial --storage-mode=plaintext || true
dfx identity use initial
INITIAL_PRINCIPAL=$(dfx identity get-principal)
INITIAL_ACCOUNT=$(get_account_id "$INITIAL_PRINCIPAL")

# Generate archive controller account
dfx identity new archive --storage-mode=plaintext || true
dfx identity use archive
ARCHIVE_PRINCIPAL=$(dfx identity get-principal)

# Stop the replica
# Switch back to default identity
dfx identity use default

# Stop dfx and clean up all state
dfx stop
rm -rf .dfx
rm -rf ~/.config/dfx/replica-configuration/
rm -rf ~/.cache/dfinity/
# Remove canister_ids.json if it exists
if [ -f "canister_ids.json" ]; then
rm canister_ids.json
fi

# Start dfx with clean state
dfx start --clean --background

# Define canister IDs
CONTEXT_ID="br5f7-7uaaa-aaaaa-qaaca-cai"
LEDGER_ID="be2us-64aaa-aaaaa-qaabq-cai"

# Create canisters
echo "Creating canisters..."
dfx canister create context_contract --specified-id "$CONTEXT_ID"
dfx canister create ledger --specified-id "$LEDGER_ID"

# Build contracts
echo "Building contracts..."
cd "$(dirname $0)"
./build.sh
cd ../context-proxy
./build.sh
cd ../context-config

# Prepare ledger initialization argument
LEDGER_INIT_ARG="(variant { Init = record {
minting_account = \"${MINTING_ACCOUNT}\";
initial_values = vec {
record { \"${INITIAL_ACCOUNT}\"; record { e8s = 100_000_000_000 } }
};
send_whitelist = vec {};
transfer_fee = opt record { e8s = 10_000 };
token_symbol = opt \"LICP\";
token_name = opt \"Local Internet Computer Protocol Token\";
archive_options = opt record {
trigger_threshold = 2000;
num_blocks_to_archive = 1000;
controller_id = principal \"${ARCHIVE_PRINCIPAL}\"
};
} })"

# Build and install canisters
dfx build
dfx canister install context_contract --mode=install
dfx canister install ledger --mode=install --argument "$LEDGER_INIT_ARG"

# Get the directory where the script is located
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"

# Build path relative to the script location
WASM_FILE="${SCRIPT_DIR}/../context-proxy/res/calimero_context_proxy_icp.wasm"

# Verify file exists
if [ ! -f "$WASM_FILE" ]; then
echo "Error: WASM file not found at: $WASM_FILE"
exit 1
fi

# Then modify the script to use a consistent reading method
WASM_CONTENTS=$(xxd -p "$WASM_FILE" | tr -d '\n' | sed 's/\(..\)/\\\1/g')

TEMP_CMD=$(mktemp)
echo "(
blob \"${WASM_CONTENTS}\",
principal \"${LEDGER_ID}\"
)" > "$TEMP_CMD"

# Execute the command using the temporary file
dfx canister call context_contract set_proxy_code --argument-file "$TEMP_CMD"

# Start the replica
dfx start --background
# Clean up
rm "$TEMP_CMD"

# Deploy the contract
dfx deploy
# Print all relevant information at the end
echo -e "\n=== Deployment Summary ==="
echo "Context Contract ID: ${CONTEXT_ID}"
echo "Ledger Contract ID: ${LEDGER_ID}"
echo -e "\nAccount Information:"
echo "Minting Account: ${MINTING_ACCOUNT}"
echo "Initial Account: ${INITIAL_ACCOUNT}"
echo "Archive Principal: ${ARCHIVE_PRINCIPAL}"
echo -e "\nDeployment completed successfully!"
16 changes: 14 additions & 2 deletions contracts/icp/context-config/dfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@
"context_contract": {
"package": "calimero-context-config-icp",
"candid": "./res/calimero_context_config_icp.did",
"type": "rust"
"type": "rust",
"id": "br5f7-7uaaa-aaaaa-qaaca-cai"
},
"ledger": {
"type": "custom",
"wasm": "https://download.dfinity.systems/ic/aba60ffbc46acfc8990bf4d5685c1360bd7026b9/canisters/ledger-canister.wasm.gz",
"candid": "https://raw.githubusercontent.com/dfinity/ic/aba60ffbc46acfc8990bf4d5685c1360bd7026b9/rs/ledger_suite/icp/ledger.did",
"id": "be2us-64aaa-aaaaa-qaabq-cai"
}
},
"defaults": {
Expand All @@ -12,6 +19,11 @@
"packtool": ""
}
},
"output_env_file": ".env",
"networks": {
"local": {
"bind": "127.0.0.1:4943",
"type": "persistent"
}
},
"version": 1
}
6 changes: 4 additions & 2 deletions contracts/icp/context-config/src/mutate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,10 @@ fn add_members(
let mut ctx_members = guard_ref.get_mut();

for member in members {
ctx_members.insert(member);
let _ignored = context.member_nonces.entry(member).or_default();
if ctx_members.insert(member) {
// returns true if the value was newly inserted
let _ignored = context.member_nonces.entry(member).or_default();
}
}

Ok(())
Expand Down
2 changes: 2 additions & 0 deletions contracts/icp/context-proxy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ thiserror.workspace = true
[dev-dependencies]
pocket-ic = "6.0.0"
rand = "0.8"
reqwest = { version = "0.10.10", features = ["blocking"] }
flate2 = "1.0.35"
3 changes: 0 additions & 3 deletions contracts/icp/context-proxy/build_contracts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ cd "$(dirname $0)"
echo "Building proxy contract..."
./build.sh

echo "Building mock ledger contract..."
./mock/ledger/build.sh

echo "Building mock external contract..."
./mock/external/build.sh

Expand Down
12 changes: 6 additions & 6 deletions contracts/icp/context-proxy/dfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,6 @@
"candid": "./res/calimero_context_proxy_icp.did",
"type": "rust"
},
"mock_ledger": {
"type": "rust",
"package": "calimero-mock-ledger-icp",
"candid": "./mock/ledger/res/calimero_mock_ledger_icp.did",
"path": "mock/ledger"
},
"mock_external": {
"type": "rust",
"package": "calimero-mock-external-icp",
Expand All @@ -24,6 +18,12 @@
"packtool": ""
}
},
"networks": {
"local": {
"bind": "127.0.0.1:4943",
"type": "persistent"
}
},
"output_env_file": ".env",
"version": 1
}
1 change: 1 addition & 0 deletions contracts/icp/context-proxy/mock/external/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ crate-type = ["cdylib"]
candid = "0.10"
ic-cdk = "0.16"
ic-cdk-macros = "0.16"
ic-ledger-types = "0.14.0"
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
service : { get_calls : () -> (vec blob) query; test_method : (blob) -> (blob) }
service : (principal) -> {
clear_state : () -> ();
get_calls : () -> (vec blob) query;
test_method : (blob) -> (blob);
test_method_no_transfer : (blob) -> (blob);
}
62 changes: 59 additions & 3 deletions contracts/icp/context-proxy/mock/external/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,76 @@
use std::cell::RefCell;

use candid::Principal;
use ic_ledger_types::{AccountIdentifier, Memo, Subaccount, Tokens, TransferArgs, TransferError};

thread_local! {
static CALLS: RefCell<Vec<Vec<u8>>> = RefCell::new(Vec::new());
static LEDGER_ID: RefCell<Option<Principal>> = RefCell::new(None);
}

#[ic_cdk::init]
fn init(ledger_id: Principal) {
LEDGER_ID.with(|id| {
*id.borrow_mut() = Some(ledger_id);
});
}

#[ic_cdk::update]
fn test_method(args: Vec<u8>) -> Vec<u8> {
async fn test_method(args: Vec<u8>) -> Vec<u8> {
let self_id = ic_cdk::id();
let caller = ic_cdk::caller();

let ledger_id = LEDGER_ID.with(|id| id.borrow().expect("Ledger ID not initialized"));

// Prepare transfer args to move the approved tokens
let transfer_args = TransferArgs {
memo: Memo(0),
amount: Tokens::from_e8s(100_000_000), // Example amount, in practice this would be parsed from args
fee: Tokens::from_e8s(10_000),
from_subaccount: Some(Subaccount::from(caller)),
to: AccountIdentifier::new(&self_id, &Subaccount([0; 32])),
created_at_time: None,
};

// Execute the transfer with proper type annotations
let transfer_result: Result<(Result<u64, TransferError>,), _> =
ic_cdk::call(ledger_id, "transfer", (transfer_args,)).await;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

icrc2's transfer_from? or does this work too


match transfer_result {
Ok((Ok(_block_height),)) => {
// Transfer successful, record the call
CALLS.with(|calls| {
calls.borrow_mut().push(args.clone());
});
args // Return the same args back
}
Ok((Err(transfer_error),)) => {
ic_cdk::trap(&format!("Transfer failed: {:?}", transfer_error));
}
Err(e) => {
ic_cdk::trap(&format!("Call to ledger failed: {:?}", e));
}
}
}

#[ic_cdk::update]
async fn test_method_no_transfer(args: Vec<u8>) -> Vec<u8> {
// Simply record the call and return
CALLS.with(|calls| {
calls.borrow_mut().push(args.clone());
args // Return the same args back
})
});
args
}

#[ic_cdk::query]
fn get_calls() -> Vec<Vec<u8>> {
CALLS.with(|calls| calls.borrow().clone())
}

// Clear state (useful for testing)
#[ic_cdk::update]
fn clear_state() {
CALLS.with(|calls| calls.borrow_mut().clear());
}

ic_cdk::export_candid!();
14 changes: 0 additions & 14 deletions contracts/icp/context-proxy/mock/ledger/Cargo.toml

This file was deleted.

22 changes: 0 additions & 22 deletions contracts/icp/context-proxy/mock/ledger/build.sh

This file was deleted.

This file was deleted.

Loading
Loading