iota_rpc_loadgen/payload/
pay_iota.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use async_trait::async_trait;
6use futures::future::join_all;
7use iota_types::{
8    base_types::IotaAddress,
9    crypto::{EncodeDecodeBase64, IotaKeyPair},
10    quorum_driver_types::ExecuteTransactionRequestType,
11    transaction::TransactionData,
12};
13use tracing::debug;
14
15use crate::payload::{
16    PayIota, ProcessPayload, RpcCommandProcessor, SignerInfo,
17    rpc_command_processor::DEFAULT_GAS_BUDGET,
18};
19
20#[async_trait]
21impl<'a> ProcessPayload<'a, &'a PayIota> for RpcCommandProcessor {
22    async fn process(
23        &'a self,
24        _op: &'a PayIota,
25        signer_info: &Option<SignerInfo>,
26    ) -> anyhow::Result<()> {
27        let clients = self.get_clients().await?;
28        let SignerInfo {
29            encoded_keypair,
30            gas_budget,
31            gas_payment,
32        } = signer_info.clone().unwrap();
33        let recipient = IotaAddress::random_for_testing_only();
34        let amount = 1;
35        let gas_budget = gas_budget.unwrap_or(DEFAULT_GAS_BUDGET);
36        let gas_payments = gas_payment.unwrap();
37
38        let keypair =
39            IotaKeyPair::decode_base64(&encoded_keypair).expect("Decoding keypair should not fail");
40
41        debug!(
42            "Transfer IOTA {} time to {recipient} with {amount} NANOS with {gas_payments:?}",
43            gas_payments.len()
44        );
45
46        let sender = IotaAddress::from(&keypair.public());
47        // TODO: For write operations, we usually just want to submit the transaction to
48        // fullnode Let's figure out what's the best way to support other mode
49        // later
50        let client = clients.first().unwrap();
51        let gas_price = client
52            .governance_api()
53            .get_reference_gas_price()
54            .await
55            .expect("Unable to fetch gas price");
56        join_all(gas_payments.iter().map(|gas| async {
57            let tx = TransactionData::new_transfer_iota(
58                recipient,
59                sender,
60                Some(amount),
61                self.get_object_ref(client, gas).await,
62                gas_budget,
63                gas_price,
64            );
65            self.sign_and_execute(
66                client,
67                &keypair,
68                tx,
69                ExecuteTransactionRequestType::WaitForEffectsCert,
70            )
71            .await
72        }))
73        .await;
74
75        Ok(())
76    }
77}