diff --git a/crates/iota-indexer/tests/data/dummy_modules_publish/Move.toml b/crates/iota-indexer/tests/data/dummy_modules_publish/Move.toml new file mode 100644 index 00000000000..e518fc169a9 --- /dev/null +++ b/crates/iota-indexer/tests/data/dummy_modules_publish/Move.toml @@ -0,0 +1,9 @@ +[package] +name = "Examples" +version = "0.0.1" + +[dependencies] +Iota = { local = "../../../../iota-framework/packages/iota-framework" } + +[addresses] +examples = "0x0" diff --git a/crates/iota-indexer/tests/data/dummy_modules_publish/sources/trusted_coin.move b/crates/iota-indexer/tests/data/dummy_modules_publish/sources/trusted_coin.move new file mode 100644 index 00000000000..1a53fb598a5 --- /dev/null +++ b/crates/iota-indexer/tests/data/dummy_modules_publish/sources/trusted_coin.move @@ -0,0 +1,40 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +/// Example coin with a trusted owner responsible for minting/burning (e.g., a stablecoin) +module examples::trusted_coin { + use std::option; + use iota::coin::{Self, TreasuryCap}; + use iota::transfer; + use iota::tx_context::{Self, TxContext}; + + /// Name of the coin + struct TRUSTED_COIN has drop {} + + /// Register the trusted currency to acquire its `TreasuryCap`. Because + /// this is a module initializer, it ensures the currency only gets + /// registered once. + fun init(witness: TRUSTED_COIN, ctx: &mut TxContext) { + // Get a treasury cap for the coin and give it to the transaction + // sender + let (treasury_cap, metadata) = coin::create_currency(witness, 2, b"TRUSTED", b"Trusted Coin", b"Trusted Coin for test", option::none(), ctx); + transfer::public_freeze_object(metadata); + transfer::public_transfer(treasury_cap, tx_context::sender(ctx)) + } + + public entry fun mint(treasury_cap: &mut TreasuryCap, amount: u64, ctx: &mut TxContext) { + let coin = coin::mint(treasury_cap, amount, ctx); + transfer::public_transfer(coin, tx_context::sender(ctx)); + } + + public entry fun transfer(treasury_cap: TreasuryCap, recipient: address) { + transfer::public_transfer(treasury_cap, recipient); + } + + #[test_only] + /// Wrapper of module initializer for testing + public fun test_init(ctx: &mut TxContext) { + init(TRUSTED_COIN {}, ctx) + } +} diff --git a/crates/iota-indexer/tests/rpc-tests/coin_api.rs b/crates/iota-indexer/tests/rpc-tests/coin_api.rs new file mode 100644 index 00000000000..208d0b166fd --- /dev/null +++ b/crates/iota-indexer/tests/rpc-tests/coin_api.rs @@ -0,0 +1,539 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use std::{path::PathBuf, str::FromStr}; + +use iota_json::{call_args, type_args}; +use iota_json_rpc_api::{CoinReadApiClient, TransactionBuilderClient, WriteApiClient}; +use iota_json_rpc_types::{ + Balance, CoinPage, IotaCoinMetadata, IotaExecutionStatus, IotaObjectRef, + IotaTransactionBlockEffectsAPI, IotaTransactionBlockResponse, + IotaTransactionBlockResponseOptions, ObjectChange, TransactionBlockBytes, +}; +use iota_move_build::BuildConfig; +use iota_types::{ + IOTA_FRAMEWORK_ADDRESS, + balance::Supply, + base_types::{IotaAddress, ObjectID}, + coin::{COIN_MODULE_NAME, TreasuryCap}, + crypto::{AccountKeyPair, get_key_pair}, + parse_iota_struct_tag, + quorum_driver_types::ExecuteTransactionRequestType, + utils::to_sender_signed_transaction, +}; +use jsonrpsee::http_client::HttpClient; +use test_cluster::TestCluster; +use tokio::sync::OnceCell; + +use crate::common::{ApiTestSetup, indexer_wait_for_object}; + +static COMMON_TESTING_ADDR_AND_CUSTOM_COIN_NAME: OnceCell<(IotaAddress, String)> = + OnceCell::const_new(); + +async fn get_or_init_addr_and_custom_coins( + cluster: &TestCluster, + indexer_client: &HttpClient, +) -> &'static (IotaAddress, String) { + COMMON_TESTING_ADDR_AND_CUSTOM_COIN_NAME + .get_or_init(|| async { + let (address, keypair): (_, AccountKeyPair) = get_key_pair(); + + for _ in 0..5 { + cluster + .fund_address_and_return_gas( + cluster.get_reference_gas_price().await, + Some(500_000_000), + address, + ) + .await; + } + + let (coin_name, coin_object_ref) = + create_and_mint_trusted_coin(cluster, address, keypair, 100_000) + .await + .unwrap(); + + indexer_wait_for_object( + indexer_client, + coin_object_ref.object_id, + coin_object_ref.version, + ) + .await; + + (address, coin_name) + }) + .await +} + +#[test] +fn get_coins_basic_scenario() { + let ApiTestSetup { + runtime, + client, + cluster, + .. + } = ApiTestSetup::get_or_init(); + runtime.block_on(async move { + let (owner, _) = get_or_init_addr_and_custom_coins(cluster, client).await; + + let (result_fullnode, result_indexer) = + get_coins_fullnode_indexer(cluster, client, *owner, None, None, None).await; + + assert!(!result_indexer.data.is_empty()); + assert_eq!(result_fullnode, result_indexer); + }); +} + +#[test] +fn get_coins_with_cursor() { + let ApiTestSetup { + runtime, + client, + cluster, + .. + } = ApiTestSetup::get_or_init(); + runtime.block_on(async move { + let (owner, _) = get_or_init_addr_and_custom_coins(cluster, client).await; + let all_coins = cluster + .rpc_client() + .get_coins(*owner, None, None, None) + .await + .unwrap(); + let cursor = all_coins.data[3].coin_object_id; // get some coin from the middle + + let (result_fullnode, result_indexer) = + get_coins_fullnode_indexer(cluster, client, *owner, None, Some(cursor), None).await; + + assert!(!result_indexer.data.is_empty()); + assert_eq!(result_fullnode, result_indexer); + }); +} + +#[test] +fn get_coins_with_limit() { + let ApiTestSetup { + runtime, + client, + cluster, + .. + } = ApiTestSetup::get_or_init(); + runtime.block_on(async move { + let (owner, _) = get_or_init_addr_and_custom_coins(cluster, client).await; + + let (result_fullnode, result_indexer) = + get_coins_fullnode_indexer(cluster, client, *owner, None, None, Some(2)).await; + + assert!(!result_indexer.data.is_empty()); + assert_eq!(result_fullnode, result_indexer); + }); +} + +#[test] +fn get_coins_custom_coin() { + let ApiTestSetup { + runtime, + client, + cluster, + .. + } = ApiTestSetup::get_or_init(); + runtime.block_on(async move { + let (owner, coin_name) = get_or_init_addr_and_custom_coins(cluster, client).await; + + let (result_fullnode, result_indexer) = get_coins_fullnode_indexer( + cluster, + client, + *owner, + Some(coin_name.clone()), + None, + None, + ) + .await; + + assert_eq!(result_indexer.data.len(), 1); + assert_eq!(result_fullnode, result_indexer); + }); +} + +#[test] +fn get_all_coins_basic_scenario() { + let ApiTestSetup { + runtime, + client, + cluster, + .. + } = ApiTestSetup::get_or_init(); + runtime.block_on(async move { + let (owner, _) = get_or_init_addr_and_custom_coins(cluster, client).await; + + let (result_fullnode, result_indexer) = + get_all_coins_fullnode_indexer(cluster, client, *owner, None, None).await; + + assert!(!result_indexer.data.is_empty()); + assert_eq!(result_fullnode, result_indexer); + }); +} + +#[ignore = "https://github.com/iotaledger/iota/issues/3588"] +#[test] +fn get_all_coins_with_cursor() { + let ApiTestSetup { + runtime, + client, + cluster, + .. + } = ApiTestSetup::get_or_init(); + runtime.block_on(async move { + let (owner, _) = get_or_init_addr_and_custom_coins(cluster, client).await; + + let all_coins = cluster + .rpc_client() + .get_coins(*owner, None, None, None) + .await + .unwrap(); + let cursor = all_coins.data[3].coin_object_id; // get some coin from the middle + + let (result_fullnode_all, result_indexer_all) = + get_all_coins_fullnode_indexer(cluster, client, *owner, None, None).await; + + let (result_fullnode, result_indexer) = + get_all_coins_fullnode_indexer(cluster, client, *owner, Some(cursor), None).await; + + println!("Fullnode all: {:#?}", result_fullnode_all); + println!("Indexer all: {:#?}", result_indexer_all); + println!("Fullnode: {:#?}", result_fullnode); + println!("Indexer: {:#?}", result_indexer); + println!("Cursor: {:#?}", cursor); + + assert!(!result_indexer.data.is_empty()); + assert_eq!(result_fullnode, result_indexer); + }); +} + +#[test] +fn get_all_coins_with_limit() { + let ApiTestSetup { + runtime, + client, + cluster, + .. + } = ApiTestSetup::get_or_init(); + runtime.block_on(async move { + let (owner, _) = get_or_init_addr_and_custom_coins(cluster, client).await; + + let (result_fullnode, result_indexer) = + get_all_coins_fullnode_indexer(cluster, client, *owner, None, Some(2)).await; + + assert!(!result_indexer.data.is_empty()); + assert_eq!(result_fullnode, result_indexer); + }); +} + +#[test] +fn get_balance_iota_coin() { + let ApiTestSetup { + runtime, + client, + cluster, + .. + } = ApiTestSetup::get_or_init(); + runtime.block_on(async move { + let (owner, _) = get_or_init_addr_and_custom_coins(cluster, client).await; + + let (result_fullnode, result_indexer) = + get_balance_fullnode_indexer(cluster, client, *owner, None).await; + + assert_eq!(result_fullnode, result_indexer); + }); +} + +#[test] +fn get_balance_custom_coin() { + let ApiTestSetup { + runtime, + client, + cluster, + .. + } = ApiTestSetup::get_or_init(); + runtime.block_on(async move { + let (owner, coin_name) = get_or_init_addr_and_custom_coins(cluster, client).await; + + let (result_fullnode, result_indexer) = + get_balance_fullnode_indexer(cluster, client, *owner, Some(coin_name.to_string())) + .await; + + assert_eq!(result_fullnode, result_indexer); + }); +} + +#[test] +fn get_all_balances() { + let ApiTestSetup { + runtime, + client, + cluster, + .. + } = ApiTestSetup::get_or_init(); + runtime.block_on(async move { + let (owner, _) = get_or_init_addr_and_custom_coins(cluster, client).await; + + let (mut result_fullnode, mut result_indexer) = + get_all_balances_fullnode_indexer(cluster, client, *owner).await; + + result_fullnode.sort_by_key(|balance: &Balance| balance.coin_type.clone()); + result_indexer.sort_by_key(|balance: &Balance| balance.coin_type.clone()); + + assert_eq!(result_fullnode, result_indexer); + }); +} + +#[test] +fn get_coin_metadata() { + let ApiTestSetup { + runtime, + client, + cluster, + .. + } = ApiTestSetup::get_or_init(); + runtime.block_on(async move { + let (_, coin_name) = get_or_init_addr_and_custom_coins(cluster, client).await; + + let (result_fullnode, result_indexer) = + get_coin_metadata_fullnode_indexer(cluster, client, coin_name.to_string()).await; + + assert!(result_indexer.is_some()); + assert_eq!(result_fullnode, result_indexer); + }); +} + +#[test] +fn get_total_supply() { + let ApiTestSetup { + runtime, + client, + cluster, + .. + } = ApiTestSetup::get_or_init(); + runtime.block_on(async move { + let (_, coin_name) = get_or_init_addr_and_custom_coins(cluster, client).await; + + let (result_fullnode, result_indexer) = + get_total_supply_fullnode_indexer(cluster, client, coin_name.to_string()).await; + + assert_eq!(result_fullnode, result_indexer); + }); +} + +async fn get_coins_fullnode_indexer( + cluster: &TestCluster, + client: &HttpClient, + owner: IotaAddress, + coin_type: Option, + cursor: Option, + limit: Option, +) -> (CoinPage, CoinPage) { + let result_fullnode = cluster + .rpc_client() + .get_coins(owner, coin_type.clone(), cursor, limit) + .await + .unwrap(); + let result_indexer = client + .get_coins(owner, coin_type, cursor, limit) + .await + .unwrap(); + (result_fullnode, result_indexer) +} + +async fn get_all_coins_fullnode_indexer( + cluster: &TestCluster, + client: &HttpClient, + owner: IotaAddress, + cursor: Option, + limit: Option, +) -> (CoinPage, CoinPage) { + let result_fullnode = cluster + .rpc_client() + .get_all_coins(owner, cursor, limit) + .await + .unwrap(); + let result_indexer = client.get_all_coins(owner, cursor, limit).await.unwrap(); + (result_fullnode, result_indexer) +} + +async fn get_balance_fullnode_indexer( + cluster: &TestCluster, + client: &HttpClient, + owner: IotaAddress, + coin_type: Option, +) -> (Balance, Balance) { + let result_fullnode = cluster + .rpc_client() + .get_balance(owner, coin_type.clone()) + .await + .unwrap(); + let result_indexer = client.get_balance(owner, coin_type).await.unwrap(); + (result_fullnode, result_indexer) +} + +async fn get_all_balances_fullnode_indexer( + cluster: &TestCluster, + client: &HttpClient, + owner: IotaAddress, +) -> (Vec, Vec) { + let result_fullnode = cluster.rpc_client().get_all_balances(owner).await.unwrap(); + let result_indexer = client.get_all_balances(owner).await.unwrap(); + (result_fullnode, result_indexer) +} + +async fn get_coin_metadata_fullnode_indexer( + cluster: &TestCluster, + client: &HttpClient, + coin_type: String, +) -> (Option, Option) { + let result_fullnode = cluster + .rpc_client() + .get_coin_metadata(coin_type.clone()) + .await + .unwrap(); + let result_indexer = client.get_coin_metadata(coin_type).await.unwrap(); + (result_fullnode, result_indexer) +} + +async fn get_total_supply_fullnode_indexer( + cluster: &TestCluster, + client: &HttpClient, + coin_type: String, +) -> (Supply, Supply) { + let result_fullnode = cluster + .rpc_client() + .get_total_supply(coin_type.clone()) + .await + .unwrap(); + let result_indexer = client.get_total_supply(coin_type).await.unwrap(); + (result_fullnode, result_indexer) +} + +async fn create_and_mint_trusted_coin( + cluster: &TestCluster, + address: IotaAddress, + account_keypair: AccountKeyPair, + amount: u64, +) -> Result<(String, IotaObjectRef), anyhow::Error> { + let http_client = cluster.rpc_client(); + let coins = http_client + .get_coins(address, None, None, Some(1)) + .await + .unwrap() + .data; + let gas = &coins[0]; + + // Publish test coin package + let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + path.extend(["tests", "data", "dummy_modules_publish"]); + let compiled_package = BuildConfig::default().build(&path).unwrap(); + let with_unpublished_deps = false; + let compiled_modules_bytes = compiled_package.get_package_base64(with_unpublished_deps); + let dependencies = compiled_package.get_dependency_storage_package_ids(); + + let transaction_bytes: TransactionBlockBytes = http_client + .publish( + address, + compiled_modules_bytes, + dependencies, + Some(gas.coin_object_id), + 100_000_000.into(), + ) + .await + .unwrap(); + + let signed_transaction = + to_sender_signed_transaction(transaction_bytes.to_data().unwrap(), &account_keypair); + let (tx_bytes, signatures) = signed_transaction.to_tx_bytes_and_signatures(); + + let tx_response: IotaTransactionBlockResponse = http_client + .execute_transaction_block( + tx_bytes, + signatures, + Some( + IotaTransactionBlockResponseOptions::new() + .with_object_changes() + .with_events(), + ), + Some(ExecuteTransactionRequestType::WaitForLocalExecution), + ) + .await + .unwrap(); + + let object_changes = tx_response.object_changes.as_ref().unwrap(); + let package_id = object_changes + .iter() + .find_map(|change| match change { + ObjectChange::Published { package_id, .. } => Some(package_id), + _ => None, + }) + .unwrap(); + + let coin_name = format!("{package_id}::trusted_coin::TRUSTED_COIN"); + let result: Supply = http_client + .get_total_supply(coin_name.clone()) + .await + .unwrap(); + + assert_eq!(0, result.value); + + let object_changes = tx_response.object_changes.as_ref().unwrap(); + let treasury_cap = object_changes + .iter() + .filter_map(|change| match change { + ObjectChange::Created { + object_id, + object_type, + .. + } => Some((object_id, object_type)), + _ => None, + }) + .find_map(|(object_id, object_type)| { + let coin_type = parse_iota_struct_tag(&coin_name).unwrap(); + (&TreasuryCap::type_(coin_type) == object_type).then_some(object_id) + }) + .unwrap(); + + let transaction_bytes: TransactionBlockBytes = http_client + .move_call( + address, + IOTA_FRAMEWORK_ADDRESS.into(), + COIN_MODULE_NAME.to_string(), + "mint_and_transfer".into(), + type_args![coin_name.clone()].unwrap(), + call_args![treasury_cap, amount, address].unwrap(), + Some(gas.coin_object_id), + 10_000_000.into(), + None, + ) + .await + .unwrap(); + + let signed_transaction = + to_sender_signed_transaction(transaction_bytes.to_data().unwrap(), &account_keypair); + let (tx_bytes, signatures) = signed_transaction.to_tx_bytes_and_signatures(); + + let tx_response = http_client + .execute_transaction_block( + tx_bytes, + signatures, + Some(IotaTransactionBlockResponseOptions::new().with_effects()), + Some(ExecuteTransactionRequestType::WaitForLocalExecution), + ) + .await + .unwrap(); + + let IotaTransactionBlockResponse { effects, .. } = tx_response; + + assert_eq!( + IotaExecutionStatus::Success, + *effects.as_ref().unwrap().status() + ); + + let created_coin_obj_ref = effects.unwrap().created()[0].reference.clone(); + + Ok((coin_name, created_coin_obj_ref)) +} diff --git a/crates/iota-indexer/tests/rpc-tests/extended_api.rs b/crates/iota-indexer/tests/rpc-tests/extended_api.rs index f77c156b3d4..8198a7ef044 100644 --- a/crates/iota-indexer/tests/rpc-tests/extended_api.rs +++ b/crates/iota-indexer/tests/rpc-tests/extended_api.rs @@ -19,7 +19,6 @@ use iota_types::{ storage::ReadStore, }; use simulacrum::Simulacrum; -use tempfile::tempdir; use test_cluster::TestCluster; use crate::common::{ApiTestSetup, SimulacrumTestSetup, indexer_wait_for_checkpoint}; @@ -62,7 +61,7 @@ fn get_epochs() { runtime.block_on(async move { let last_checkpoint = sim.get_latest_checkpoint().unwrap(); - indexer_wait_for_checkpoint(&store, last_checkpoint.sequence_number).await; + indexer_wait_for_checkpoint(store, last_checkpoint.sequence_number).await; let epochs = client.get_epochs(None, None, None).await.unwrap(); @@ -99,7 +98,7 @@ fn get_epochs_descending() { runtime.block_on(async move { let last_checkpoint = sim.get_latest_checkpoint().unwrap(); - indexer_wait_for_checkpoint(&store, last_checkpoint.sequence_number).await; + indexer_wait_for_checkpoint(store, last_checkpoint.sequence_number).await; let epochs = client.get_epochs(None, None, Some(true)).await.unwrap(); @@ -126,7 +125,7 @@ fn get_epochs_paging() { runtime.block_on(async move { let last_checkpoint = sim.get_latest_checkpoint().unwrap(); - indexer_wait_for_checkpoint(&store, last_checkpoint.sequence_number).await; + indexer_wait_for_checkpoint(store, last_checkpoint.sequence_number).await; let epochs = client.get_epochs(None, Some(2), None).await.unwrap(); let actual_epochs_order = epochs @@ -168,7 +167,7 @@ fn get_epoch_metrics() { runtime.block_on(async move { let last_checkpoint = sim.get_latest_checkpoint().unwrap(); - indexer_wait_for_checkpoint(&store, last_checkpoint.sequence_number).await; + indexer_wait_for_checkpoint(store, last_checkpoint.sequence_number).await; let epoch_metrics = client.get_epoch_metrics(None, None, None).await.unwrap(); @@ -205,7 +204,7 @@ fn get_epoch_metrics_descending() { runtime.block_on(async move { let last_checkpoint = sim.get_latest_checkpoint().unwrap(); - indexer_wait_for_checkpoint(&store, last_checkpoint.sequence_number).await; + indexer_wait_for_checkpoint(store, last_checkpoint.sequence_number).await; let epochs = client .get_epoch_metrics(None, None, Some(true)) @@ -235,7 +234,7 @@ fn get_epoch_metrics_paging() { runtime.block_on(async move { let last_checkpoint = sim.get_latest_checkpoint().unwrap(); - indexer_wait_for_checkpoint(&store, last_checkpoint.sequence_number).await; + indexer_wait_for_checkpoint(store, last_checkpoint.sequence_number).await; let epochs = client.get_epoch_metrics(None, Some(2), None).await.unwrap(); let actual_epochs_order = epochs @@ -277,7 +276,7 @@ fn get_current_epoch() { runtime.block_on(async move { let last_checkpoint = sim.get_latest_checkpoint().unwrap(); - indexer_wait_for_checkpoint(&store, last_checkpoint.sequence_number).await; + indexer_wait_for_checkpoint(store, last_checkpoint.sequence_number).await; let current_epoch = client.get_current_epoch().await.unwrap(); @@ -299,7 +298,7 @@ fn get_network_metrics() { } = ApiTestSetup::get_or_init(); runtime.block_on(async move { - indexer_wait_for_checkpoint(&store, 10).await; + indexer_wait_for_checkpoint(store, 10).await; let network_metrics = client.get_network_metrics().await.unwrap(); @@ -319,14 +318,14 @@ fn get_move_call_metrics() { } = ApiTestSetup::get_or_init(); runtime.block_on(async move { - execute_move_fn(&cluster).await.unwrap(); + execute_move_fn(cluster).await.unwrap(); let latest_checkpoint_sn = cluster .rpc_client() .get_latest_checkpoint_sequence_number() .await .unwrap(); - indexer_wait_for_checkpoint(&store, latest_checkpoint_sn.into_inner()).await; + indexer_wait_for_checkpoint(store, latest_checkpoint_sn.into_inner()).await; let move_call_metrics = client.get_move_call_metrics().await.unwrap(); @@ -348,7 +347,7 @@ fn get_latest_address_metrics() { } = ApiTestSetup::get_or_init(); runtime.block_on(async move { - indexer_wait_for_checkpoint(&store, 10).await; + indexer_wait_for_checkpoint(store, 10).await; let address_metrics = client.get_latest_address_metrics().await.unwrap(); @@ -367,7 +366,7 @@ fn get_checkpoint_address_metrics() { } = ApiTestSetup::get_or_init(); runtime.block_on(async move { - indexer_wait_for_checkpoint(&store, 10).await; + indexer_wait_for_checkpoint(store, 10).await; let address_metrics = client.get_checkpoint_address_metrics(0).await.unwrap(); @@ -386,7 +385,7 @@ fn get_all_epoch_address_metrics() { } = ApiTestSetup::get_or_init(); runtime.block_on(async move { - indexer_wait_for_checkpoint(&store, 10).await; + indexer_wait_for_checkpoint(store, 10).await; let address_metrics = client.get_all_epoch_address_metrics(None).await.unwrap(); @@ -406,7 +405,7 @@ fn get_total_transactions() { runtime.block_on(async move { let latest_checkpoint = sim.get_latest_checkpoint().unwrap(); let total_transactions_count = latest_checkpoint.network_total_transactions; - indexer_wait_for_checkpoint(&store, latest_checkpoint.sequence_number).await; + indexer_wait_for_checkpoint(store, latest_checkpoint.sequence_number).await; let transactions_cnt = client.get_total_transactions().await.unwrap(); assert_eq!(transactions_cnt.into_inner(), total_transactions_count); diff --git a/crates/iota-indexer/tests/rpc-tests/main.rs b/crates/iota-indexer/tests/rpc-tests/main.rs index bd1a3788c89..3c95735c5ad 100644 --- a/crates/iota-indexer/tests/rpc-tests/main.rs +++ b/crates/iota-indexer/tests/rpc-tests/main.rs @@ -1,6 +1,9 @@ // Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +#[cfg(feature = "shared_test_runtime")] +mod coin_api; + #[allow(dead_code)] #[path = "../common/mod.rs"] mod common; diff --git a/crates/iota/src/iota_commands.rs b/crates/iota/src/iota_commands.rs index 002478a8aa4..ea33ca93d87 100644 --- a/crates/iota/src/iota_commands.rs +++ b/crates/iota/src/iota_commands.rs @@ -757,6 +757,7 @@ async fn start( fullnode_url.clone(), ReaderWriterConfig::writer_mode(None), data_ingestion_path.clone(), + None, ) .await; info!("Indexer in writer mode started"); @@ -767,6 +768,7 @@ async fn start( fullnode_url.clone(), ReaderWriterConfig::reader_mode(indexer_address.to_string()), data_ingestion_path, + None, ) .await; info!("Indexer in reader mode started");