Skip to content

Commit

Permalink
iota-indexer: Add tests for TransactionBuilder api
Browse files Browse the repository at this point in the history
  • Loading branch information
tomxey committed Oct 30, 2024
1 parent d08f374 commit 8d74379
Show file tree
Hide file tree
Showing 2 changed files with 280 additions and 0 deletions.
3 changes: 3 additions & 0 deletions crates/iota-indexer/tests/rpc-tests/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@ mod move_utils;
#[cfg(feature = "shared_test_runtime")]
mod read_api;

#[cfg(feature = "shared_test_runtime")]
mod transaction_builder;

#[cfg(feature = "shared_test_runtime")]
mod write_api;
277 changes: 277 additions & 0 deletions crates/iota-indexer/tests/rpc-tests/transaction_builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use iota_json_rpc_api::{
CoinReadApiClient, GovernanceReadApiClient, IndexerApiClient, ReadApiClient,
TransactionBuilderClient, WriteApiClient,
};
use iota_json_rpc_types::{
CoinPage, DelegatedStake, IotaObjectDataOptions, IotaObjectResponseQuery,
IotaTransactionBlockResponseOptions, ObjectsPage, StakeStatus, TransactionBlockBytes,
};
use iota_test_transaction_builder::TestTransactionBuilder;
use iota_types::{
balance::Balance,
base_types::{IotaAddress, ObjectID, ObjectRef},
crypto::{AccountKeyPair, get_key_pair},
object::Owner,
programmable_transaction_builder::ProgrammableTransactionBuilder,
utils::to_sender_signed_transaction,
};
use jsonrpsee::http_client::HttpClient;
use test_cluster::TestCluster;

use crate::common::{
ApiTestSetup, indexer_wait_for_checkpoint, indexer_wait_for_object,
indexer_wait_for_transaction,
};

const FUNDED_BALANCE_PER_COIN: u64 = 10_000_000_000;

#[test]
fn transfer_object() {
let ApiTestSetup {
runtime,
store,
client,
cluster,
} = ApiTestSetup::get_or_init();

runtime.block_on(async move {
indexer_wait_for_checkpoint(store, 1).await;

let (sender, keypair): (_, AccountKeyPair) = get_key_pair();
let (receiver, _): (_, AccountKeyPair) = get_key_pair();

let sender_coins = create_coins_for_addr(cluster, client, sender, 2).await;
let gas = sender_coins[0];
let object_to_send = sender_coins[1];

let tx_bytes = client
.transfer_object(
sender,
object_to_send,
Some(gas),
100_000_000.into(),
receiver,
)
.await
.unwrap();

let txn = to_sender_signed_transaction(tx_bytes.to_data().unwrap(), &keypair);
let res = cluster.wallet.execute_transaction_must_succeed(txn).await;
indexer_wait_for_transaction(res.digest, store, client).await;

let transferred_object = client
.get_object(object_to_send, Some(IotaObjectDataOptions::full_content()))
.await
.unwrap();

assert_eq!(
transferred_object.owner(),
Some(Owner::AddressOwner(receiver))
);
});
}

#[test]
fn transfer_iota() {
let ApiTestSetup {
runtime,
store,
client,
cluster,
} = ApiTestSetup::get_or_init();

runtime.block_on(async move {
indexer_wait_for_checkpoint(store, 1).await;

let (sender, keypair): (_, AccountKeyPair) = get_key_pair();
let (receiver, _): (_, AccountKeyPair) = get_key_pair();

let sender_coins = create_coins_for_addr(cluster, client, sender, 1).await;
let gas = sender_coins[0];
let transferred_balance = 100_000;

let tx_bytes = client
.transfer_iota(
sender,
gas,
100_000_000.into(),
receiver,
Some(transferred_balance.into()),
)
.await
.unwrap();

let txn = to_sender_signed_transaction(tx_bytes.to_data().unwrap(), &keypair);
let res = cluster.wallet.execute_transaction_must_succeed(txn).await;
indexer_wait_for_transaction(res.digest, store, client).await;

let receiver_balances = get_address_balances(client, receiver).await;

assert_eq!(receiver_balances, [transferred_balance]);
});
}

#[test]
fn pay() {
let ApiTestSetup {
runtime,
store,
client,
cluster,
} = ApiTestSetup::get_or_init();

runtime.block_on(async move {
indexer_wait_for_checkpoint(store, 1).await;

let (sender, keypair): (_, AccountKeyPair) = get_key_pair();
let (receiver_1, _): (_, AccountKeyPair) = get_key_pair();
let (receiver_2, _): (_, AccountKeyPair) = get_key_pair();

let input_coins: u64 = 3;
let sender_coins =
create_coins_for_addr(cluster, client, sender, input_coins as u32 + 1).await;
let total_input_coins_balance = FUNDED_BALANCE_PER_COIN * input_coins;
let transferred_balance_1 = total_input_coins_balance / 2 - 100;
let transferred_balance_2 = total_input_coins_balance / 2 - 700;

let tx_bytes = client
.pay(
sender,
sender_coins[0..input_coins as usize].into(),
[receiver_1, receiver_2].into(),
[transferred_balance_1.into(), transferred_balance_2.into()].into(),
None, // let node find the gas automatically
100_000_000.into(),
)
.await
.unwrap();

let txn = to_sender_signed_transaction(tx_bytes.to_data().unwrap(), &keypair);
let res = cluster.wallet.execute_transaction_must_succeed(txn).await;
indexer_wait_for_transaction(res.digest, store, client).await;

let receiver_1_balances = get_address_balances(client, receiver_1).await;
let receiver_2_balances = get_address_balances(client, receiver_2).await;

assert_eq!(receiver_1_balances, [transferred_balance_1]);
assert_eq!(receiver_2_balances, [transferred_balance_2]);
});
}

#[test]
fn pay_iota() {
let ApiTestSetup {
runtime,
store,
client,
cluster,
} = ApiTestSetup::get_or_init();

runtime.block_on(async move {
indexer_wait_for_checkpoint(store, 1).await;

let (sender, keypair): (_, AccountKeyPair) = get_key_pair();
let (receiver_1, _): (_, AccountKeyPair) = get_key_pair();
let (receiver_2, _): (_, AccountKeyPair) = get_key_pair();

let input_coins: u64 = 3;
let sender_coins = create_coins_for_addr(cluster, client, sender, input_coins as u32).await;
let gas_budget = 100_000_000;
let total_available_input_coins_balance: u64 =
FUNDED_BALANCE_PER_COIN * input_coins - gas_budget;
let transferred_balance_1 = total_available_input_coins_balance / 2 - 100;
let transferred_balance_2 = total_available_input_coins_balance / 2 - 700;

let tx_bytes = client
.pay_iota(
sender,
sender_coins.into(),
[receiver_1, receiver_2].into(),
[transferred_balance_1.into(), transferred_balance_2.into()].into(),
gas_budget.into(),
)
.await
.unwrap();

let txn = to_sender_signed_transaction(tx_bytes.to_data().unwrap(), &keypair);
let res = cluster.wallet.execute_transaction_must_succeed(txn).await;
indexer_wait_for_transaction(res.digest, store, client).await;

let receiver_1_balances = get_address_balances(client, receiver_1).await;
let receiver_2_balances = get_address_balances(client, receiver_2).await;

assert_eq!(receiver_1_balances, [transferred_balance_1]);
assert_eq!(receiver_2_balances, [transferred_balance_2]);
});
}

#[test]
fn pay_all_iota() {
let ApiTestSetup {
runtime,
store,
client,
cluster,
} = ApiTestSetup::get_or_init();

runtime.block_on(async move {
indexer_wait_for_checkpoint(store, 1).await;

let (sender, keypair): (_, AccountKeyPair) = get_key_pair();
let (receiver, _): (_, AccountKeyPair) = get_key_pair();

let input_coins: u64 = 3;
let sender_coins = create_coins_for_addr(cluster, client, sender, input_coins as u32).await;
let gas_budget = 100_000_000;

let tx_bytes = client
.pay_all_iota(sender, sender_coins.into(), receiver, gas_budget.into())
.await
.unwrap();

let txn = to_sender_signed_transaction(tx_bytes.to_data().unwrap(), &keypair);
let res = cluster.wallet.execute_transaction_must_succeed(txn).await;
indexer_wait_for_transaction(res.digest, store, client).await;

let receiver_balances = get_address_balances(client, receiver).await;
let expected_minimum_reciver_balance = FUNDED_BALANCE_PER_COIN * input_coins - gas_budget;

Check warning on line 240 in crates/iota-indexer/tests/rpc-tests/transaction_builder.rs

View workflow job for this annotation

GitHub Actions / typos / Spell Check with Typos

"reciver" should be "receiver".

assert_eq!(receiver_balances.len(), 1);
assert!(receiver_balances[0] >= expected_minimum_reciver_balance);

Check warning on line 243 in crates/iota-indexer/tests/rpc-tests/transaction_builder.rs

View workflow job for this annotation

GitHub Actions / typos / Spell Check with Typos

"reciver" should be "receiver".
});
}

async fn get_address_balances(indexer_client: &HttpClient, address: IotaAddress) -> Vec<u64> {
indexer_client
.get_coins(address, None, None, None)
.await
.unwrap()
.data
.iter()
.map(|coin| coin.balance)
.collect()
}

async fn create_coins_for_addr(
cluster: &TestCluster,
indexer_client: &HttpClient,
address: IotaAddress,
objects_count: u32,
) -> Vec<ObjectID> {
let mut coins: Vec<ObjectID> = Vec::new();
for _ in 0..objects_count {
let coin = cluster
.fund_address_and_return_gas(
cluster.get_reference_gas_price().await,
Some(FUNDED_BALANCE_PER_COIN),
address,
)
.await;
indexer_wait_for_object(indexer_client, coin.0, coin.1).await;
coins.push(coin.0);
}
coins
}

0 comments on commit 8d74379

Please sign in to comment.