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(FI-866) add support for ICRC-2 standard #143

Merged
merged 5 commits into from
Aug 2, 2023
Merged
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
4 changes: 2 additions & 2 deletions test/ref/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ async fn test_replica() {
// We need to set the identity of the agent to that of what a user would parse
agent.set_identity(p1);
let env = ReplicaLedger::new(agent, canister_id);
let tests = icrc1_test_suite::test_suite(env);
let tests = icrc1_test_suite::test_suite(env).await;

if !icrc1_test_suite::execute_tests(tests).await {
std::process::exit(1);
Expand Down Expand Up @@ -221,7 +221,7 @@ async fn test_state_machine() {

let env = SMLedger::new(Arc::new(sm_env), canister_id, p1.sender().unwrap());

let tests = icrc1_test_suite::test_suite(env);
let tests = icrc1_test_suite::test_suite(env).await;

if !icrc1_test_suite::execute_tests(tests).await {
std::process::exit(1);
Expand Down
2 changes: 1 addition & 1 deletion test/runner/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ async fn main() {
.expect("agent failed to fetch the root key");

let env = ReplicaLedger::new(agent, canister_id);
let tests = icrc1_test_suite::test_suite(env);
let tests = icrc1_test_suite::test_suite(env).await;

if !icrc1_test_suite::execute_tests(tests).await {
std::process::exit(1);
Expand Down
87 changes: 67 additions & 20 deletions test/suite/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ async fn setup_test_account(

/// Checks whether the ledger supports token transfers and handles
/// default sub accounts correctly.
pub async fn test_transfer(ledger_env: impl LedgerEnv + LedgerEnv) -> TestResult {
pub async fn icrc1_test_transfer(ledger_env: impl LedgerEnv + LedgerEnv) -> TestResult {
let p1_env = setup_test_account(&ledger_env, Nat::from(20_000)).await?;
let p2_env = setup_test_account(&ledger_env, Nat::from(20_000)).await?;
let transfer_amount = 10_000;
Expand Down Expand Up @@ -146,7 +146,7 @@ pub async fn test_transfer(ledger_env: impl LedgerEnv + LedgerEnv) -> TestResult

/// Checks whether the ledger supports token burns.
/// Skips the checks if the ledger does not have a minting account.
pub async fn test_burn(ledger_env: impl LedgerEnv) -> TestResult {
pub async fn icrc1_test_burn(ledger_env: impl LedgerEnv) -> TestResult {
let minting_account = match minting_account(&ledger_env).await? {
Some(account) => account,
None => {
Expand Down Expand Up @@ -184,7 +184,7 @@ pub async fn test_burn(ledger_env: impl LedgerEnv) -> TestResult {
}

/// Checks whether the ledger metadata entries agree with named methods.
pub async fn test_metadata(ledger: impl LedgerEnv) -> TestResult {
pub async fn icrc1_test_metadata(ledger: impl LedgerEnv) -> TestResult {
let mut metadata = metadata(&ledger).await?;
metadata.sort_by(|l, r| l.0.cmp(&r.0));

Expand Down Expand Up @@ -215,7 +215,7 @@ pub async fn test_metadata(ledger: impl LedgerEnv) -> TestResult {
}

/// Checks whether the ledger advertizes support for ICRC-1 standard.
pub async fn test_supported_standards(ledger: impl LedgerEnv) -> anyhow::Result<Outcome> {
pub async fn icrc1_test_supported_standards(ledger: impl LedgerEnv) -> anyhow::Result<Outcome> {
let stds = supported_standards(&ledger).await?;
if !stds.iter().any(|std| std.name == "ICRC-1") {
bail!("The ledger does not claim support for ICRC-1: {:?}", stds);
Expand All @@ -224,8 +224,23 @@ pub async fn test_supported_standards(ledger: impl LedgerEnv) -> anyhow::Result<
Ok(Outcome::Passed)
}

/// Checks whether the ledger advertizes support for ICRC-2 standard.
pub async fn icrc2_test_supported_standards(ledger: impl LedgerEnv) -> anyhow::Result<Outcome> {
let stds = supported_standards(&ledger).await?;
// If the ledger claims to support ICRC-2 it also needs to support ICRC-1
if !(stds.iter().any(|std| std.name == "ICRC-2") && stds.iter().any(|std| std.name == "ICRC-1"))
{
bail!(
"The ledger does not claim support for ICRC-1 and ICRC-2: {:?}",
stds
);
}

Ok(Outcome::Passed)
}

/// Checks whether the ledger applies deduplication of transactions correctly
pub async fn test_tx_deduplication(ledger_env: impl LedgerEnv) -> anyhow::Result<Outcome> {
pub async fn icrc1_test_tx_deduplication(ledger_env: impl LedgerEnv) -> anyhow::Result<Outcome> {
// Create two test accounts and transfer some tokens to the first account
let p1_env = setup_test_account(&ledger_env, 200_000.into()).await?;
let p2_env = p1_env.fork();
Expand Down Expand Up @@ -369,7 +384,7 @@ pub async fn test_tx_deduplication(ledger_env: impl LedgerEnv) -> anyhow::Result
Ok(Outcome::Passed)
}

pub async fn test_bad_fee(ledger_env: impl LedgerEnv) -> anyhow::Result<Outcome> {
pub async fn icrc1_test_bad_fee(ledger_env: impl LedgerEnv) -> anyhow::Result<Outcome> {
// Create two test accounts and transfer some tokens to the first account
let p1_env = setup_test_account(&ledger_env, 200_000.into()).await?;
let p2_env = p1_env.fork();
Expand All @@ -395,7 +410,7 @@ pub async fn test_bad_fee(ledger_env: impl LedgerEnv) -> anyhow::Result<Outcome>
Ok(Outcome::Passed)
}

pub async fn test_future_transfer(ledger_env: impl LedgerEnv) -> anyhow::Result<Outcome> {
pub async fn icrc1_test_future_transfer(ledger_env: impl LedgerEnv) -> anyhow::Result<Outcome> {
// Create two test accounts and transfer some tokens to the first account
let p1_env = setup_test_account(&ledger_env, 200_000.into()).await?;
let p2_env = p1_env.fork();
Expand All @@ -414,7 +429,7 @@ pub async fn test_future_transfer(ledger_env: impl LedgerEnv) -> anyhow::Result<
}
}

pub async fn test_memo_bytes_length(ledger_env: impl LedgerEnv) -> anyhow::Result<Outcome> {
pub async fn icrc1_test_memo_bytes_length(ledger_env: impl LedgerEnv) -> anyhow::Result<Outcome> {
// Create two test accounts and transfer some tokens to the first account
let p1_env = setup_test_account(&ledger_env, 200_000.into()).await?;
let p2_env = p1_env.fork();
Expand All @@ -430,26 +445,58 @@ pub async fn test_memo_bytes_length(ledger_env: impl LedgerEnv) -> anyhow::Resul
}
}

/// Returns the entire list of tests.
pub fn test_suite(env: impl LedgerEnv + 'static + Clone) -> Vec<Test> {
/// Returns the entire list of icrc1 tests.
pub fn icrc1_test_suite(env: impl LedgerEnv + 'static + Clone) -> Vec<Test> {
vec![
test("basic:transfer", test_transfer(env.clone())),
test("basic:burn", test_burn(env.clone())),
test("basic:metadata", test_metadata(env.clone())),
test("icrc1:transfer", icrc1_test_transfer(env.clone())),
test("icrc1:burn", icrc1_test_burn(env.clone())),
test("icrc1:metadata", icrc1_test_metadata(env.clone())),
test(
"icrc1:supported_standards",
icrc1_test_supported_standards(env.clone()),
),
test(
"basic:supported_standards",
test_supported_standards(env.clone()),
"icrc1:tx_deduplication",
icrc1_test_tx_deduplication(env.clone()),
),
test("basic:tx_deduplication", test_tx_deduplication(env.clone())),
test(
"basic:memo_bytes_length",
test_memo_bytes_length(env.clone()),
"icrc1:memo_bytes_length",
icrc1_test_memo_bytes_length(env.clone()),
),
test("basic:future_transfers", test_future_transfer(env.clone())),
test("basic:bad_fee", test_bad_fee(env)),
test(
"icrc1:future_transfers",
icrc1_test_future_transfer(env.clone()),
),
test("icrc1:bad_fee", icrc1_test_bad_fee(env)),
]
}

/// Returns the entire list of icrc2 tests.
pub fn icrc2_test_suite(env: impl LedgerEnv + 'static + Clone) -> Vec<Test> {
vec![test(
"icrc2:supported_standards",
icrc2_test_supported_standards(env.clone()),
)]
}

pub async fn test_suite(env: impl LedgerEnv + 'static + Clone) -> Vec<Test> {
match supported_standards(&env).await {
Ok(standard) => {
let mut tests = vec![];
if standard.iter().any(|std| std.name == "ICRC-1") {
tests.append(&mut icrc1_test_suite(env.clone()));
}
if standard.iter().any(|std| std.name == "ICRC-2") {
tests.append(&mut icrc2_test_suite(env));
}
tests
}
Err(_) => {
println!("No standard is supported by the given ledger: Is the endpoint 'icrc1_supported_standards' implemented correctly?");
vec![]
}
}
}
/// Executes the list of tests concurrently and prints results using
/// the TAP protocol (https://testanything.org/).
pub async fn execute_tests(tests: Vec<Test>) -> bool {
Expand Down
Loading