Skip to content

Commit

Permalink
Reuse TransactionBuilder in Fullnode (MystenLabs#5090)
Browse files Browse the repository at this point in the history
* reuse transaction builder in fullnode

* remove unused func and unused doc
  • Loading branch information
longbowlu authored Oct 11, 2022
1 parent e9e6678 commit 7d8a146
Show file tree
Hide file tree
Showing 23 changed files with 1,232 additions and 834 deletions.
21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ members = [
"crates/sui-telemetry",
"crates/sui-test-validator",
"crates/sui-tool",
"crates/sui-transaction-builder",
"crates/sui-transactional-test-runner",
"crates/sui-types",
"crates/sui-verifier",
Expand Down
3 changes: 3 additions & 0 deletions crates/sui-cluster-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ futures = "0.3.24"
serde_json = "1.0.83"
tempfile = "3.3.0"
tokio = { version = "1.20.1", features = ["full"] }
jsonrpsee = { version = "0.15.1", features = ["full"] }
tracing = { version = "0.1.36", features = ["log"] }
clap = { version = "3.1.14", features = ["derive"] }
reqwest = { version = "0.11.11", features = ["blocking", "json"] }
Expand All @@ -31,5 +32,7 @@ sui-types = { path = "../sui-types" }
sui-core = { path = "../sui-core" }
sui-json = { path = "../sui-json" }
sui-config = { path = "../sui-config" }
sui-transaction-builder = { path = "../sui-transaction-builder" }
test-utils = { path = "../test-utils" }
workspace-hack.workspace = true
move-core-types.workspace = true
28 changes: 26 additions & 2 deletions crates/sui-cluster-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ use cluster::{Cluster, ClusterFactory};
use config::ClusterTestOpt;
use futures::{stream::FuturesUnordered, StreamExt};
use helper::ObjectChecker;
use jsonrpsee::types::ParamsSer;
use jsonrpsee::{core::client::ClientT, http_client::HttpClientBuilder};
use std::sync::Arc;
use sui::client_commands::WalletContext;
use sui_faucet::CoinInfo;
use sui_json_rpc_types::{SuiCertifiedTransaction, SuiTransactionEffects};
use sui_json_rpc_types::{
SuiCertifiedTransaction, SuiExecutionStatus, SuiTransactionEffects, TransactionBytes,
};
use sui_types::base_types::TransactionDigest;
use sui_types::messages::ExecuteTransactionRequestType;
use sui_types::object::Owner;
Expand All @@ -24,6 +28,7 @@ use sui_types::{
};
use test_case::{
call_contract_test::CallContractTest, coin_merge_split_test::CoinMergeSplitTest,
fullnode_build_publish_transaction_test::FullNodeBuildPublishTransactionTest,
fullnode_execute_transaction_test::FullNodeExecuteTransactionTest,
native_transfer_test::NativeTransferTest, shared_object_test::SharedCounterTest,
};
Expand Down Expand Up @@ -85,6 +90,10 @@ impl TestContext {
self.client.get_fullnode_client()
}

fn get_fullnode_rpc_url(&self) -> &str {
self.cluster.fullnode_url()
}

fn get_wallet(&self) -> &WalletContext {
self.client.get_wallet()
}
Expand All @@ -103,6 +112,18 @@ impl TestContext {
make_transactions_with_wallet_context(self.get_wallet_mut(), max_txn_num).await
}

pub async fn build_transaction_remotely(
&self,
method: &str,
params: Option<ParamsSer<'_>>,
) -> anyhow::Result<TransactionData> {
let fn_rpc_url = self.get_fullnode_rpc_url();
// TODO cache this?
let rpc_client = HttpClientBuilder::default().build(fn_rpc_url)?;

TransactionBytes::to_data(rpc_client.request(method, params).await?)
}

async fn sign_and_execute(
&self,
txn_data: TransactionData,
Expand All @@ -118,7 +139,9 @@ impl TestContext {
)
.await
.unwrap_or_else(|e| panic!("Failed to execute transaction for {}. {}", desc, e));
(resp.tx_cert.unwrap(), resp.effects.unwrap())
let (tx_cert, effects) = (resp.tx_cert.unwrap(), resp.effects.unwrap());
assert!(matches!(effects.status, SuiExecutionStatus::Success));
(tx_cert, effects)
}

pub async fn setup(options: ClusterTestOpt) -> Result<Self, anyhow::Error> {
Expand Down Expand Up @@ -255,6 +278,7 @@ impl ClusterTest {
TestCase::new(CallContractTest {}),
TestCase::new(SharedCounterTest {}),
TestCase::new(FullNodeExecuteTransactionTest {}),
TestCase::new(FullNodeBuildPublishTransactionTest {}),
];

// TODO: improve the runner parallelism for efficiency
Expand Down
1 change: 1 addition & 0 deletions crates/sui-cluster-test/src/test_case.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

pub mod call_contract_test;
pub mod coin_merge_split_test;
pub mod fullnode_build_publish_transaction_test;
pub mod fullnode_execute_transaction_test;
pub mod native_transfer_test;
pub mod shared_object_test;
26 changes: 15 additions & 11 deletions crates/sui-cluster-test/src/test_case/call_contract_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@

use crate::helper::ObjectChecker;
use crate::{TestCaseImpl, TestContext};
use anyhow::bail;
use async_trait::async_trait;
use jsonrpsee::rpc_params;
use move_core_types::language_storage::TypeTag;
use serde::Deserialize;
use serde_json::json;
use sui::client_commands::{call_move, EXAMPLE_NFT_DESCRIPTION, EXAMPLE_NFT_NAME, EXAMPLE_NFT_URL};
use sui::client_commands::{EXAMPLE_NFT_DESCRIPTION, EXAMPLE_NFT_NAME, EXAMPLE_NFT_URL};
use sui_json::SuiJsonValue;
use sui_json_rpc_types::SuiEvent;
use sui_types::base_types::SequenceNumber;
Expand Down Expand Up @@ -37,24 +38,27 @@ impl TestCaseImpl for CallContractTest {
let mut sui_objs = ctx.get_sui_from_faucet(Some(1)).await;
let gas_obj = sui_objs.swap_remove(0);

let wallet_context = ctx.get_wallet_mut();
let args_json = json!([EXAMPLE_NFT_NAME, EXAMPLE_NFT_DESCRIPTION, EXAMPLE_NFT_URL,]);
let mut args = vec![];
for a in args_json.as_array().unwrap() {
args.push(SuiJsonValue::new(a.clone()).unwrap());
}
let (_, effects) = call_move(
let type_args: Vec<TypeTag> = vec![];
let params = rpc_params![
signer,
ObjectID::from(SUI_FRAMEWORK_ADDRESS),
"devnet_nft",
"mint",
vec![],
Some(*gas_obj.id()),
5000,
type_args,
args,
wallet_context,
)
.await
.or_else(|e| bail!("Failed to call move contract: {e}"))?;
Some(*gas_obj.id()),
5000
];

let data = ctx
.build_transaction_remotely("sui_moveCall", params)
.await?;
let (_, effects) = ctx.sign_and_execute(data, "call contract").await;

// Retrieve created nft
let nft_id = effects
Expand Down
44 changes: 25 additions & 19 deletions crates/sui-cluster-test/src/test_case/coin_merge_split_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// SPDX-License-Identifier: Apache-2.0

use crate::{helper::ObjectChecker, TestCaseImpl, TestContext};
use anyhow::bail;
use async_trait::async_trait;
use jsonrpsee::rpc_params;
use sui_json_rpc_types::{SuiCertifiedTransaction, SuiTransactionEffects};
use sui_types::base_types::{ObjectID, SuiAddress};
use sui_types::object::Owner;
Expand Down Expand Up @@ -34,20 +34,8 @@ impl TestCaseImpl for CoinMergeSplitTest {
info!("Testing coin split.");
let amounts = vec![1, (original_value - 2) / 2];

let data = ctx
.get_fullnode_client()
.transaction_builder()
.split_coin(
signer,
*primary_coin.id(),
amounts,
Some(*gas_obj.id()),
5000,
)
.await
.or_else(|e| bail!("Failed to get transaction data for coin split: {}", e))?;

let (tx_cert, effects) = ctx.sign_and_execute(data, "coin split").await;
let (tx_cert, effects) =
Self::split_coin(ctx, signer, *primary_coin.id(), amounts, *gas_obj.id()).await;
let tx_digest = tx_cert.transaction_digest;
let new_coins = effects.created;

Expand Down Expand Up @@ -130,12 +118,30 @@ impl CoinMergeSplitTest {
coin_to_merge: ObjectID,
gas_obj_id: ObjectID,
) -> (SuiCertifiedTransaction, SuiTransactionEffects) {
let params = rpc_params![signer, primary_coin, coin_to_merge, Some(gas_obj_id), 5000];

let data = ctx
.get_fullnode_client()
.transaction_builder()
.merge_coins(signer, primary_coin, coin_to_merge, Some(gas_obj_id), 5000)
.build_transaction_remotely("sui_mergeCoins", params)
.await
.expect("Failed to get transaction data for coin merge");
.unwrap();

ctx.sign_and_execute(data, "coin merge").await
}

async fn split_coin(
ctx: &TestContext,
signer: SuiAddress,
primary_coin: ObjectID,
amounts: Vec<u64>,
gas_obj_id: ObjectID,
) -> (SuiCertifiedTransaction, SuiTransactionEffects) {
let params = rpc_params![signer, primary_coin, amounts, Some(gas_obj_id), 5000];

let data = ctx
.build_transaction_remotely("sui_splitCoin", params)
.await
.unwrap();

ctx.sign_and_execute(data, "coin merge").await
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use crate::{TestCaseImpl, TestContext};
use async_trait::async_trait;
use jsonrpsee::rpc_params;
use sui_types::sui_serde::Base64;
use sui_types::{base_types::ObjectID, object::Owner};
use test_utils::transaction::compile_basics_package;

pub struct FullNodeBuildPublishTransactionTest;

#[async_trait]
impl TestCaseImpl for FullNodeBuildPublishTransactionTest {
fn name(&self) -> &'static str {
"FullNodeBuildPublishTransaction"
}

fn description(&self) -> &'static str {
"Test building publish transaction via full node"
}

async fn run(&self, ctx: &mut TestContext) -> Result<(), anyhow::Error> {
let all_module_bytes = compile_basics_package()
.iter()
.map(|bytes| Base64::from_bytes(bytes))
.collect::<Vec<_>>();
let params = rpc_params![
ctx.get_wallet_address(),
all_module_bytes,
None::<ObjectID>,
50000
];

let data = ctx
.build_transaction_remotely("sui_publish", params)
.await?;
let (_, effects) = ctx.sign_and_execute(data, "publish basics package").await;
effects
.created
.iter()
.find(|obj_ref| obj_ref.owner == Owner::Immutable)
.unwrap();

Ok(())
}
}
Loading

0 comments on commit 7d8a146

Please sign in to comment.