Skip to content

Commit

Permalink
Merge branch 'FI-1026' into 'master'
Browse files Browse the repository at this point in the history
fix: make the ICP Archive did file match the ICP Ledger did file

Closes FI-1026 

Closes FI-1026

See merge request dfinity-lab/public/ic!15649
  • Loading branch information
MarioDfinity committed Oct 25, 2023
2 parents ecc13a9 + a9851c1 commit f7835d7
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 15 deletions.
4 changes: 2 additions & 2 deletions rs/rosetta-api/icp_ledger/archive/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,9 @@ fn check_archive_candid_interface_compatibility() {
let expected_interface_path =
std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../ledger_archive.did");

candid::utils::service_compatible(
candid::utils::service_equal(
CandidSource::Text(&actual_interface),
CandidSource::File(&expected_interface_path),
)
.expect("ledger archive canister interface is not compatible with the ledger_archive.did file");
.expect("ledger archive canister interface is not equal with the ledger_archive.did file");
}
2 changes: 1 addition & 1 deletion rs/rosetta-api/icp_ledger/ledger/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ rust_test(
name = "ledger_canister_unit_test",
compile_data = LEDGER_CANISTER_DATA,
crate = ":_wasm_ledger-canister-wasm",
data = LEDGER_CANISTER_DATA,
data = LEDGER_CANISTER_DATA + ["//rs/rosetta-api/icp_ledger:ledger_archive.did"],
env = {
"CARGO_MANIFEST_DIR": "rs/rosetta-api/icp_ledger/ledger",
},
Expand Down
28 changes: 28 additions & 0 deletions rs/rosetta-api/icp_ledger/ledger/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1533,4 +1533,32 @@ mod tests {
)
});
}

#[test]
fn check_archive_and_ledger_interface_compatibility() {
// check that ledger.did and ledger_archive.did agree on the block format
let manifest_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
let ledger_did_file = manifest_dir.join("../ledger.did");
let archive_did_file = manifest_dir.join("../ledger_archive.did");
let mut ledger_env = CandidSource::File(ledger_did_file.as_path())
.load()
.unwrap()
.0;
let archive_env = CandidSource::File(archive_did_file.as_path())
.load()
.unwrap()
.0;
let ledger_block_type = ledger_env.find_type("Block").unwrap().to_owned();
let archive_block_type = archive_env.find_type("Block").unwrap().to_owned();

let mut gamma = std::collections::HashSet::new();
let archive_block_type = ledger_env.merge_type(archive_env, archive_block_type.clone());
candid::types::subtype::equal(
&mut gamma,
&ledger_env,
&ledger_block_type,
&archive_block_type,
)
.expect("Ledger and Archive Block type are different");
}
}
149 changes: 145 additions & 4 deletions rs/rosetta-api/icp_ledger/ledger/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,22 @@ use ic_icrc1_ledger_sm_tests::{
use ic_ledger_core::{block::BlockType, Tokens};
use ic_state_machine_tests::{ErrorCode, PrincipalId, StateMachine, UserError};
use icp_ledger::{
AccountIdBlob, AccountIdentifier, ArchiveOptions, Block, CandidBlock, FeatureFlags,
GetBlocksArgs, GetBlocksRes, InitArgs, LedgerCanisterInitPayload, LedgerCanisterPayload,
Operation, QueryBlocksResponse, QueryEncodedBlocksResponse, UpgradeArgs,
AccountIdBlob, AccountIdentifier, ArchiveOptions, ArchivedBlocksRange, Block, CandidBlock,
CandidOperation, CandidTransaction, FeatureFlags, GetBlocksArgs, GetBlocksRes, GetBlocksResult,
InitArgs, LedgerCanisterInitPayload, LedgerCanisterPayload, Operation, QueryBlocksResponse,
QueryEncodedBlocksResponse, TimeStamp, UpgradeArgs, DEFAULT_TRANSFER_FEE,
};
use icrc_ledger_types::icrc1::{
account::Account,
transfer::{Memo, TransferArg, TransferError},
};
use icrc_ledger_types::icrc2::allowance::AllowanceArgs;
use icrc_ledger_types::icrc2::approve::ApproveArgs;
use num_traits::cast::ToPrimitive;
use on_wire::{FromWire, IntoWire};
use serde_bytes::ByteBuf;
use std::collections::{HashMap, HashSet};
use std::time::SystemTime;

fn ledger_wasm() -> Vec<u8> {
ic_test_utilities_load_wasm::load_wasm(
Expand Down Expand Up @@ -74,7 +77,7 @@ fn query_blocks(
.bytes(),
QueryBlocksResponse
)
.expect("failed to decode transfer response")
.expect("failed to decode query blocks")
}

fn query_encoded_blocks(
Expand Down Expand Up @@ -714,3 +717,141 @@ fn account_identifier_test() {
let account_id = account_identifier(&env, ledger, Account { owner, subaccount });
assert_eq!(expected_account_id, account_id);
}

#[test]
fn test_query_archived_blocks() {
let env = StateMachine::new();
let payload = LedgerCanisterInitPayload::builder()
.minting_account(MINTER.into())
.icrc1_minting_account(MINTER)
.transfer_fee(Tokens::from_e8s(10_000))
.token_symbol_and_name("ICP", "Internet Computer")
.archive_options(ArchiveOptions {
trigger_threshold: 4,
num_blocks_to_archive: 4usize,
node_max_memory_size_bytes: None,
max_message_size_bytes: None,
controller_id: PrincipalId::new_anonymous(),
cycles_for_archive_creation: None,
max_transactions_per_response: None,
})
.feature_flags(FeatureFlags { icrc2: true })
.build()
.unwrap();
let ledger = env
.install_canister(ledger_wasm(), Encode!(&payload).unwrap(), None)
.expect("Unable to install the Ledger canister with the new init");

let user1 = Principal::from_slice(&[1]);
let user2 = Principal::from_slice(&[2]);

// mint block
transfer(&env, ledger, MINTER, user1, 2_000_000_000).unwrap();
// burn block
transfer(&env, ledger, user1, MINTER, 1_000_000_000).unwrap();
// xfer block
transfer(&env, ledger, user1, user2, 100_000_000).unwrap();
// approve block
send_approval(
&env,
ledger,
user2,
&ApproveArgs {
from_subaccount: None,
spender: user1.into(),
amount: 100_000_000.into(),
expected_allowance: None,
expires_at: None,
fee: None,
memo: None,
created_at_time: None,
},
)
.unwrap();

let res = query_blocks(&env, user1, ledger, 0, 1000);
assert_eq!(res.chain_length, 4);
assert_eq!(res.first_block_index, 4);
assert_eq!(res.archived_blocks.len(), 1);
let ArchivedBlocksRange {
start,
length,
callback,
} = res.archived_blocks.get(0).unwrap();
// query the archive
let block_range = Decode!(
&env.query(
CanisterId::new(callback.canister_id.into()).unwrap(),
callback.method.to_owned(),
Encode!(&GetBlocksArgs {
start: *start,
length: *length as usize
})
.unwrap()
)
.unwrap()
.bytes(),
GetBlocksResult
)
.unwrap()
.unwrap();
let time = env
.time()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_nanos() as u64;
assert_eq!(
block_range
.blocks
.iter()
.map(|b| b.transaction.to_owned())
.collect::<Vec<_>>(),
vec![
CandidTransaction {
memo: icp_ledger::Memo(0),
created_at_time: TimeStamp::from_nanos_since_unix_epoch(time),
icrc1_memo: None,
operation: Some(CandidOperation::Mint {
to: AccountIdentifier::from(user1).to_address(),
amount: Tokens::from_e8s(2_000_000_000)
}),
},
CandidTransaction {
memo: icp_ledger::Memo(0),
created_at_time: TimeStamp::from_nanos_since_unix_epoch(time),
icrc1_memo: None,
operation: Some(CandidOperation::Burn {
from: AccountIdentifier::from(user1).to_address(),
amount: Tokens::from_e8s(1_000_000_000),
spender: None
}),
},
CandidTransaction {
memo: icp_ledger::Memo(0),
created_at_time: TimeStamp::from_nanos_since_unix_epoch(time),
icrc1_memo: None,
operation: Some(CandidOperation::Transfer {
from: AccountIdentifier::from(user1).to_address(),
to: AccountIdentifier::from(user2).to_address(),
amount: Tokens::from_e8s(100_000_000),
fee: DEFAULT_TRANSFER_FEE,
spender: None,
}),
},
CandidTransaction {
memo: icp_ledger::Memo(0),
created_at_time: TimeStamp::from_nanos_since_unix_epoch(time),
icrc1_memo: None,
operation: Some(CandidOperation::Approve {
from: AccountIdentifier::from(user2).to_address(),
spender: AccountIdentifier::from(user1).to_address(),
allowance: Tokens::from_e8s(100_000_000),
allowance_e8s: 100_000_000i128,
expected_allowance: None,
expires_at: None,
fee: DEFAULT_TRANSFER_FEE,
}),
},
]
);
}
12 changes: 5 additions & 7 deletions rs/rosetta-api/icp_ledger/ledger_archive.did
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,25 @@ type Operation = variant {
};
Burn : record {
from : AccountIdentifier;
spender : opt AccountIdentifier;
amount : Tokens;
};
Transfer : record {
from : AccountIdentifier;
to : AccountIdentifier;
amount : Tokens;
fee : Tokens;
spender : opt vec nat8;
};
Approve : record {
from : AccountIdentifier;
spender : AccountIdentifier;
// This field is deprecated and should not be used.
allowance_e8s : int;
allowance: Tokens;
fee : Tokens;
expires_at : opt Timestamp;
};
TransferFrom : record {
from : AccountIdentifier;
to : AccountIdentifier;
spender : AccountIdentifier;
amount : Tokens;
fee : Tokens;
expected_allowance : opt Tokens;
};
};

Expand Down
8 changes: 7 additions & 1 deletion rs/rosetta-api/icp_ledger/src/account_identifier.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use candid::CandidType;
use candid::{CandidType, Principal};
use dfn_core::CanisterId;
use ic_base_types::{CanisterIdError, PrincipalId, PrincipalIdError};
use ic_crypto_sha2::Sha224;
Expand Down Expand Up @@ -170,6 +170,12 @@ impl<'de> Deserialize<'de> for AccountIdentifier {
}
}

impl From<Principal> for AccountIdentifier {
fn from(pid: Principal) -> Self {
AccountIdentifier::new(PrincipalId(pid), None)
}
}

impl From<PrincipalId> for AccountIdentifier {
fn from(pid: PrincipalId) -> Self {
AccountIdentifier::new(pid, None)
Expand Down

0 comments on commit f7835d7

Please sign in to comment.