Skip to content

Commit

Permalink
[shuffle] replace json rpc with api
Browse files Browse the repository at this point in the history
  • Loading branch information
Avinash Sivakumar authored and bors-libra committed Nov 22, 2021
1 parent 5b0eb32 commit e57c040
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 221 deletions.
73 changes: 38 additions & 35 deletions shuffle/cli/src/account.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::shared::{send_transaction, Home, Network, NetworkHome, LOCALHOST_NAME};
use crate::shared::{DevApiClient, Home, Network, NetworkHome, LOCALHOST_NAME};
use anyhow::{anyhow, Result};
use diem_crypto::PrivateKey;

use diem_infallible::duration_since_epoch;
use diem_sdk::{
client::{BlockingClient, FaucetClient},
client::FaucetClient,
transaction_builder::{Currency, TransactionFactory},
types::LocalAccount,
};
Expand Down Expand Up @@ -49,15 +49,18 @@ pub async fn handle(home: &Home, root: Option<PathBuf>, network: Network) -> Res
}
None => {
println!("Connecting to {}...", network.get_json_rpc_url());
let client = BlockingClient::new(network.get_json_rpc_url());
let client = DevApiClient::new(reqwest::Client::new(), network.get_dev_api_url())?;
let factory = TransactionFactory::new(ChainId::test());

if let Some(input_root_key) = root {
network_home.copy_key_to_latest(input_root_key.as_path())?
}
let mut treasury_account = get_treasury_account(&client, home.get_root_key_path())?;
create_account_via_dev_api(&mut treasury_account, &new_account, &factory, &client)?;
let mut treasury_account =
get_treasury_account(&client, home.get_root_key_path()).await?;
create_account_via_dev_api(&mut treasury_account, &new_account, &factory, &client)
.await?;
create_account_via_dev_api(&mut treasury_account, &test_account, &factory, &client)
.await
}
}
}
Expand Down Expand Up @@ -134,49 +137,49 @@ fn generate_test_account(network_home: &NetworkHome) -> Result<LocalAccount> {
))
}

pub fn get_treasury_account(client: &BlockingClient, root_key_path: &Path) -> Result<LocalAccount> {
pub async fn get_treasury_account(
client: &DevApiClient,
root_key_path: &Path,
) -> Result<LocalAccount> {
let treasury_account_key = load_key(root_key_path);
let treasury_seq_num = client
.get_account(account_config::treasury_compliance_account_address())?
.into_inner()
.unwrap()
.sequence_number;
.get_account_sequence_number(account_config::treasury_compliance_account_address())
.await?;
Ok(LocalAccount::new(
account_config::treasury_compliance_account_address(),
treasury_account_key,
treasury_seq_num,
))
}

pub fn create_account_via_dev_api(
pub async fn create_account_via_dev_api(
treasury_account: &mut LocalAccount,
new_account: &LocalAccount,
factory: &TransactionFactory,
client: &BlockingClient,
client: &DevApiClient,
) -> Result<()> {
println!("Creating a new account onchain...");
if client
.get_account(new_account.address())
.unwrap()
.into_inner()
.is_some()
{
println!("Account already exists: {}", new_account.address());
} else {
let create_new_account_txn = treasury_account.sign_with_transaction_builder(
factory.payload(encode_create_parent_vasp_account_script_function(
Currency::XUS.type_tag(),
0,
new_account.address(),
new_account.authentication_key().prefix().to_vec(),
vec![],
false,
)),
);
send_transaction(client, create_new_account_txn)?;
println!("Successfully created account {}", new_account.address());
}
println!("Public key: {}", new_account.public_key());
match client.get_account_resources(new_account.address()).await {
Ok(_) => println!("Account already exists: {}", new_account.address()),
Err(_) => {
println!("Creating a new account onchain...");
let create_new_account_txn = treasury_account.sign_with_transaction_builder(
factory.payload(encode_create_parent_vasp_account_script_function(
Currency::XUS.type_tag(),
0,
new_account.address(),
new_account.authentication_key().prefix().to_vec(),
vec![],
false,
)),
);
let bytes = bcs::to_bytes(&create_new_account_txn)?;
let json = client.post_transactions(bytes).await?;
let hash = DevApiClient::get_hash_from_post_txn(json)?;
client.check_txn_executed_from_hash(hash.as_str()).await?;
println!("Successfully created account {}", new_account.address());
println!("Public key: {}", new_account.public_key());
}
};
Ok(())
}

Expand Down
151 changes: 3 additions & 148 deletions shuffle/cli/src/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,7 @@ use diem_sdk::{
};
use diem_types::{chain_id::ChainId, transaction::authenticator::AuthenticationKey};
use generate_key::load_key;
use serde_json::Value;
use std::{
io,
io::Write,
path::Path,
thread, time,
time::{Duration, Instant},
};
use std::path::Path;
use url::Url;

/// Deploys shuffle's main Move Package to the sender's address.
Expand Down Expand Up @@ -63,7 +56,7 @@ pub async fn deploy(
module.serialize(&mut binary)?;

let hash = send_module_transaction(&client, account, binary).await?;
check_txn_executed_from_hash(&client, hash.as_str()).await?;
client.check_txn_executed_from_hash(hash.as_str()).await?;
}

Ok(())
Expand All @@ -80,144 +73,6 @@ async fn send_module_transaction(
));
let bytes = bcs::to_bytes(&publish_txn)?;
let json = client.post_transactions(bytes).await?;
let hash = get_hash_from_post_txn(json)?;
let hash = DevApiClient::get_hash_from_post_txn(json)?;
Ok(hash)
}

async fn check_txn_executed_from_hash(client: &DevApiClient, hash: &str) -> Result<()> {
let mut json = client.get_transactions_by_hash(hash).await?;
let start = Instant::now();
while json["type"] == "pending_transaction" {
thread::sleep(time::Duration::from_secs(1));
json = client.get_transactions_by_hash(hash).await?;
let duration = start.elapsed();
if duration > Duration::from_secs(10) {
break;
}
}
confirm_successful_execution(&mut io::stdout(), &json, hash)
}

fn confirm_successful_execution<W>(writer: &mut W, json: &Value, hash: &str) -> Result<()>
where
W: Write,
{
if is_execution_successful(json)? {
return Ok(());
}
writeln!(writer, "{:#?}", json)?;
Err(anyhow!(format!(
"Transaction with hash {} didn't execute successfully",
hash
)))
}

fn is_execution_successful(json: &Value) -> Result<bool> {
json["success"]
.as_bool()
.ok_or_else(|| anyhow!("Unable to access success key"))
}

fn get_hash_from_post_txn(json: Value) -> Result<String> {
Ok(json["hash"].as_str().unwrap().to_string())
}

#[cfg(test)]
mod test {
use super::*;
use serde_json::json;

fn post_txn_json_output() -> Value {
json!({
"type":"pending_transaction",
"hash":"0xbca2738726dc456f23762372ab0dd2f450ec3ec20271e5318ae37e9d42ee2bb8",
"sender":"0x24163afcc6e33b0a9473852e18327fa9",
"sequence_number":"10",
"max_gas_amount":"1000000",
"gas_unit_price":"0",
"gas_currency_code":"XUS",
"expiration_timestamp_secs":"1635872777",
"payload":{}
})
}

fn get_transactions_by_hash_json_output_success() -> Value {
json!({
"type":"user_transaction",
"version":"3997",
"hash":"0x89e59bb50521334a69c06a315b6dd191a8da4c1c7a40ce27a8f96f12959496eb",
"state_root_hash":"0x7a0b81379ab8786f34fcff804e5fb413255467c28f09672e8d22bfaa4e029102",
"event_root_hash":"0x414343554d554c41544f525f504c414345484f4c4445525f4841534800000000",
"gas_used":"8",
"success":true,
"vm_status":"Executed successfully",
"sender":"0x24163afcc6e33b0a9473852e18327fa9",
"sequence_number":"14",
"max_gas_amount":"1000000",
"gas_unit_price":"0",
"gas_currency_code":"XUS",
"expiration_timestamp_secs":"1635873470",
"payload":{}
})
}

fn get_transactions_by_hash_json_output_fail() -> Value {
json!({
"type":"user_transaction",
"version":"3997",
"hash":"0xbad59bb50521334a69c06a315b6dd191a8da4c1c7a40ce27a8f96f12959496eb",
"state_root_hash":"0x7a0b81379ab8786f34fcff804e5fb413255467c28f09672e8d22bfaa4e029102",
"event_root_hash":"0x414343554d554c41544f525f504c414345484f4c4445525f4841534800000000",
"gas_used":"8",
"success":false,
"vm_status":"miscellaneous error",
"sender":"0x24163afcc6e33b0a9473852e18327fa9",
"sequence_number":"14",
"max_gas_amount":"1000000",
"gas_unit_price":"0",
"gas_currency_code":"XUS",
"expiration_timestamp_secs":"1635873470",
"payload":{}
})
}

#[test]
fn test_confirm_is_execution_successful() {
let successful_txn = get_transactions_by_hash_json_output_success();
assert_eq!(is_execution_successful(&successful_txn).unwrap(), true);

let failed_txn = get_transactions_by_hash_json_output_fail();
assert_eq!(is_execution_successful(&failed_txn).unwrap(), false);
}

#[test]
fn test_get_hash_from_post_txn() {
let txn = post_txn_json_output();
let hash = get_hash_from_post_txn(txn).unwrap();
assert_eq!(
hash,
"0xbca2738726dc456f23762372ab0dd2f450ec3ec20271e5318ae37e9d42ee2bb8"
);
}

#[test]
fn test_print_confirmation_with_success_value() {
let successful_txn = get_transactions_by_hash_json_output_success();
let mut stdout = Vec::new();
let good_hash = "0xbca2738726dc456f23762372ab0dd2f450ec3ec20271e5318ae37e9d42ee2bb8";

confirm_successful_execution(&mut stdout, &successful_txn, good_hash).unwrap();
assert_eq!(String::from_utf8(stdout).unwrap().as_str(), "".to_string());

let failed_txn = get_transactions_by_hash_json_output_fail();
let mut stdout = Vec::new();
let bad_hash = "0xbad59bb50521334a69c06a315b6dd191a8da4c1c7a40ce27a8f96f12959496eb";
assert_eq!(
confirm_successful_execution(&mut stdout, &failed_txn, bad_hash).is_err(),
true
);

let fail_string = format!("{:#?}\n", &failed_txn);
assert_eq!(String::from_utf8(stdout).unwrap().as_str(), fail_string)
}
}
Loading

0 comments on commit e57c040

Please sign in to comment.