/// Assert that GTC neurons can be donated by the owner of the GTC account
Assert that GTC neurons can be donated by the owner of the GTC account
Assert that GTC neurons can be donated by the owner of the GTC account
async fn assert_neurons_can_be_donated(
    nns_canisters: &NnsCanisters<'_>,
    custodian_neuron_id: NeuronId,
    custodian_key_pair: &'static Keypair,
    test_identity: &'static TestIdentity,
) {
    let gtc = &nns_canisters.genesis_token;
    let governance = &nns_canisters.governance;
    let ledger = &nns_canisters.ledger;
    let sign_cmd = move |msg: &[u8]| Ok(test_identity.sign(msg));
    let sender = Sender::ExternalHsm {
        pub_key: der_encode(&test_identity.public_key()),
        sign: Arc::new(sign_cmd),
    };
    // Assert that `test_identity` has not yet claimed or donated their neurons
    let get_account_response: Result<Result<AccountState, String>, String> = gtc
        .update_from_sender(
            "get_account",
            candid_one,
            test_identity.gtc_address.to_string(),
            &sender,
        )
        .await;
    let account_before_donation = get_account_response.unwrap().unwrap();
    assert!(!account_before_donation.has_claimed);
    assert!(!account_before_donation.has_donated);
    assert!(!account_before_donation.has_forwarded);
    // Calculate how much ICPT is expected to be donated to the custodian
    // neuron.
    let expected_custodian_account_balance_increase: Tokens = Tokens::from_e8s(
        Tokens::from_tokens(account_before_donation.icpts as u64)
            .unwrap()
            .get_e8s()
            - (TRANSACTION_FEE.get_e8s() * account_before_donation.neuron_ids.len() as u64),
    );
    // Get the custodian neuron and its ledger account, so that we can later
    // assert that the account value has increased (as the result of a
    // donation).
    let get_full_neuron_response: Result<Result<Neuron, GovernanceError>, String> = governance
        .update_from_sender(
            "get_full_neuron",
            candid_one,
            custodian_neuron_id.id,
            &Sender::from_keypair(custodian_key_pair),
        )
        .await;
    let custodian_neuron = get_full_neuron_response.unwrap().unwrap();
    let custodian_subaccount = Subaccount::try_from(&custodian_neuron.account[..]).unwrap();
    let custodian_account =
        AccountIdentifier::new(GOVERNANCE_CANISTER_ID.get(), Some(custodian_subaccount));
    let account_balance_response: Result<Tokens, String> = ledger
        .query_from_sender(
            "account_balance_pb",
            protobuf,
            AccountBalanceArgs {
                account: custodian_account,
            },
            &Sender::from_keypair(custodian_key_pair),
        )
        .await;
    let custodian_account_balance = account_balance_response.unwrap();
    let expected_custodian_account_balance_after_donation =
        (custodian_account_balance + expected_custodian_account_balance_increase).unwrap();
    // Have `test_identity` donate their neurons
    let donate_account_response: Result<Result<(), String>, String> = gtc
        .update_from_sender(
            "donate_account",
            candid_one,
            test_identity.public_key_hex.to_string(),
            &sender,
        )
        .await;
    assert!(donate_account_response.unwrap().is_ok());
    // Assert that `test_identity` has donated their neurons
    let get_account_response: Result<Result<AccountState, String>, String> = gtc
        .update_from_sender(
            "get_account",
            candid_one,
            test_identity.gtc_address.to_string(),
            &sender,
        )
        .await;
    let account_after_donation = get_account_response.unwrap().unwrap();
    assert!(account_after_donation.has_donated);
    assert_eq!(
        account_after_donation.authenticated_principal_id,
        Some(test_identity.principal_id())
    );
    assert_eq!(
        account_after_donation
            .successfully_transferred_neurons
            .len(),
        account_before_donation.neuron_ids.len(),
    );
    // Assert that donated neurons can't be claimed
    let claim_neurons_response: Result<Result<Vec<NeuronId>, String>, String> = gtc
        .update_from_sender(
            "claim_neurons",
            candid,
            (test_identity.public_key_hex,),
            &sender,
        )
        .await;
    assert!(claim_neurons_response.unwrap().is_err());
    // Assert calling donate a second time fails
    let donate_account_response: Result<Result<(), String>, String> = gtc
        .update_from_sender(
            "donate_account",
            candid_one,
            test_identity.public_key_hex.to_string(),
            &sender,
        )
        .await;
    assert!(donate_account_response.unwrap().is_err());
    // Assert that the custodian neuron's ledger account has received the
    // donated funds
    let account_balance_response: Result<Tokens, String> = ledger
        .query_from_sender(
            "account_balance_pb",
            protobuf,
            AccountBalanceArgs {
                account: custodian_account,
            },
            &Sender::from_keypair(custodian_key_pair),
        )
        .await;
    let actual_custodian_account_balance_after_donation = account_balance_response.unwrap();
    assert_eq!(
        expected_custodian_account_balance_after_donation,
        actual_custodian_account_balance_after_donation
    );
    // Assert that the custodian neuron's stake matches its ledger account
    // balance
    let get_full_neuron_response: Result<Result<Neuron, GovernanceError>, String> = governance
        .update_from_sender(
            "get_full_neuron",
            candid_one,
            custodian_neuron_id.id,
            &Sender::from_keypair(custodian_key_pair),
        )
        .await;
    let custodian_neuron = get_full_neuron_response.unwrap().unwrap();
    let custodian_neuron_stake = Tokens::from_e8s(custodian_neuron.cached_neuron_stake_e8s);
    assert_eq!(
        custodian_neuron_stake,
        actual_custodian_account_balance_after_donation
    );
}
async fn assert_neurons_can_be_donated ( nns_canisters : & NnsCanisters < ' _ > , custodian_neuron_id : NeuronId , custodian_key_pair : & ' static Keypair , test_identity : & ' static TestIdentity , ) { let gtc = & nns_canisters . genesis_token ; let governance = & nns_canisters . governance ; let ledger = & nns_canisters . ledger ; let sign_cmd = move | msg : & [ u8 ] | Ok ( test_identity . sign ( msg ) ) ; let sender = Sender :: ExternalHsm { pub_key : der_encode ( & test_identity . public_key ( ) ) , sign : Arc :: new ( sign_cmd ) , } ; // Assert that `test_identity` has not yet claimed or donated their neurons let get_account_response : Result < Result < AccountState , String > , String > = gtc . update_from_sender ( " " , candid_one , test_identity . gtc_address . to_string ( ) , & sender , ) . await ; let account_before_donation = get_account_response . unwrap ( ) . unwrap ( ) ; assert ! ( account_before_donation has_claimed ) ; assert ! ( account_before_donation has_donated ) ; assert ! ( account_before_donation has_forwarded ) ; // Calculate how much ICPT is expected to be donated to the custodian // neuron. let expected_custodian_account_balance_increase : Tokens = Tokens :: from_e8s ( Tokens :: from_tokens ( account_before_donation . icpts as u64 ) . unwrap ( ) . get_e8s ( ) - ( TRANSACTION_FEE . get_e8s ( ) * account_before_donation . neuron_ids . len ( ) as u64 ) , ) ; // Get the custodian neuron and its ledger account, so that we can later // assert that the account value has increased (as the result of a // donation). let get_full_neuron_response : Result < Result < Neuron , GovernanceError > , String > = governance . update_from_sender ( " " , candid_one , custodian_neuron_id . id , & Sender :: from_keypair ( custodian_key_pair ) , ) . await ; let custodian_neuron = get_full_neuron_response . unwrap ( ) . unwrap ( ) ; let custodian_subaccount = Subaccount :: try_from ( & custodian_neuron . account [ .. ] ) . unwrap ( ) ; let custodian_account = AccountIdentifier :: new ( GOVERNANCE_CANISTER_ID . get ( ) , Some ( custodian_subaccount ) ) ; let account_balance_response : Result < Tokens , String > = ledger . query_from_sender ( " " , protobuf , AccountBalanceArgs { account : custodian_account , } , & Sender :: from_keypair ( custodian_key_pair ) , ) . await ; let custodian_account_balance = account_balance_response . unwrap ( ) ; let expected_custodian_account_balance_after_donation = ( custodian_account_balance + expected_custodian_account_balance_increase ) . unwrap ( ) ; // Have `test_identity` donate their neurons let donate_account_response : Result < Result < ( ) , String > , String > = gtc . update_from_sender ( " " , candid_one , test_identity . public_key_hex . to_string ( ) , & sender , ) . await ; assert ! ( donate_account_response unwrap ( ) is_ok ( ) ) ; // Assert that `test_identity` has donated their neurons let get_account_response : Result < Result < AccountState , String > , String > = gtc . update_from_sender ( " " , candid_one , test_identity . gtc_address . to_string ( ) , & sender , ) . await ; let account_after_donation = get_account_response . unwrap ( ) . unwrap ( ) ; assert ! ( account_after_donation has_donated ) ; assert_eq ! ( account_after_donation authenticated_principal_id Some ( test_identity principal_id ( ) ) ) ; assert_eq ! ( account_after_donation successfully_transferred_neurons len ( ) account_before_donation neuron_ids len ( ) ) ; // Assert that donated neurons can't be claimed let claim_neurons_response : Result < Result < Vec < NeuronId > , String > , String > = gtc . update_from_sender ( " " , candid , ( test_identity . public_key_hex , ) , & sender , ) . await ; assert ! ( claim_neurons_response unwrap ( ) is_err ( ) ) ; // Assert calling donate a second time fails let donate_account_response : Result < Result < ( ) , String > , String > = gtc . update_from_sender ( " " , candid_one , test_identity . public_key_hex . to_string ( ) , & sender , ) . await ; assert ! ( donate_account_response unwrap ( ) is_err ( ) ) ; // Assert that the custodian neuron's ledger account has received the // donated funds let account_balance_response : Result < Tokens , String > = ledger . query_from_sender ( " " , protobuf , AccountBalanceArgs { account : custodian_account , } , & Sender :: from_keypair ( custodian_key_pair ) , ) . await ; let actual_custodian_account_balance_after_donation = account_balance_response . unwrap ( ) ; assert_eq ! ( expected_custodian_account_balance_after_donation actual_custodian_account_balance_after_donation ) ; // Assert that the custodian neuron's stake matches its ledger account // balance let get_full_neuron_response : Result < Result < Neuron , GovernanceError > , String > = governance . update_from_sender ( " " , candid_one , custodian_neuron_id . id , & Sender :: from_keypair ( custodian_key_pair ) , ) . await ; let custodian_neuron = get_full_neuron_response . unwrap ( ) . unwrap ( ) ; let custodian_neuron_stake = Tokens :: from_e8s ( custodian_neuron . cached_neuron_stake_e8s ) ; assert_eq ! ( custodian_neuron_stake actual_custodian_account_balance_after_donation ) ; }
Assert that GTC neurons can be donated by the owner of the GTC account
Assert that GTC neurons can be donated by the owner of the GTC account
nns_canisters
&NnsCanisters<'_>
custodian_neuron_id
NeuronId
custodian_key_pair
&'static Keypair
test_identity
&'static TestIdentity