Skip to content

Commit

Permalink
[cli] compile command support dir and deploy command support package. (
Browse files Browse the repository at this point in the history
…#2619)

* [compiler] move some utils function from stdlib to compiler.

* [txn-builder] Remove stdlib version argument from encode_transfer_script_function.

* [cli] compile command support dir and deploy command support package.

1. Unify the transaction options.
2. Refactor transaction dry run and execute logic, omit repeat code.

* [log] Change sync log level in test and dev chain.
  • Loading branch information
jolestar authored Jun 23, 2021
1 parent c94c29d commit e48ca93
Show file tree
Hide file tree
Showing 33 changed files with 614 additions and 1,222 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

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

128 changes: 7 additions & 121 deletions cmd/starcoin/src/account/execute_script_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,14 @@
// SPDX-License-Identifier: Apache-2.0

use crate::cli_state::CliState;
use crate::view::{ExecuteResultView, ExecutionOutputView};
use crate::view::{ExecuteResultView, TransactionOptions};
use crate::StarcoinOpt;
use anyhow::{bail, Result};
use scmd::{CommandAction, ExecContext};
use starcoin_dev::playground;
use starcoin_move_compiler::load_bytecode_file;
use starcoin_rpc_api::types::{TransactionOutputView, TransactionVMStatus};
use starcoin_rpc_client::RemoteStateReader;
use starcoin_state_api::AccountStateReader;
use starcoin_types::transaction::{
parse_transaction_argument, DryRunTransaction, RawUserTransaction, Script, TransactionArgument,
TransactionPayload,
parse_transaction_argument, Script, TransactionArgument, TransactionPayload,
};
use starcoin_vm_types::account_address::AccountAddress;
use starcoin_vm_types::transaction_argument::convert_txn_args;
use starcoin_vm_types::{language_storage::TypeTag, parser::parse_type_tag};
use std::path::PathBuf;
Expand All @@ -25,10 +19,6 @@ use structopt::StructOpt;
#[derive(Debug, StructOpt)]
#[structopt(name = "execute-script")]
pub struct ExecuteScriptOpt {
#[structopt(short = "s", long)]
/// hex encoded string, like 0x1, 0x12
sender: Option<AccountAddress>,

#[structopt(
short = "t",
long = "type_tag",
Expand All @@ -41,40 +31,8 @@ pub struct ExecuteScriptOpt {
#[structopt(long = "arg", name = "transaction-args", help = "can specify multi arg", parse(try_from_str = parse_transaction_argument))]
args: Option<Vec<TransactionArgument>>,

#[structopt(
name = "expiration_time",
long = "timeout",
default_value = "3000",
help = "how long(in seconds) the txn stay alive"
)]
expiration_time: u64,

#[structopt(
short = "g",
long = "max-gas",
name = "max-gas-amount",
default_value = "10000000",
help = "max gas used to execute the script"
)]
max_gas_amount: u64,
#[structopt(
short = "p",
long = "gas-price",
name = "price of gas",
default_value = "1",
help = "gas price used to execute the script"
)]
gas_price: u64,
#[structopt(
short = "b",
name = "blocking-mode",
long = "blocking",
help = "blocking wait txn mined"
)]
blocking: bool,
#[structopt(long = "dry-run")]
/// dry-run script, only get transaction output, no state change to chain
dry_run: bool,
#[structopt(flatten)]
transaction_opts: TransactionOptions,

#[structopt(name = "mv_file", parse(from_os_str))]
/// bytecode file of the script to execute.
Expand All @@ -94,19 +52,10 @@ impl CommandAction for ExecuteScriptCommand {
ctx: &ExecContext<Self::State, Self::GlobalOpt, Self::Opt>,
) -> Result<Self::ReturnItem> {
let opt = ctx.opt();
let client = ctx.state().client();
let sender = if let Some(sender) = ctx.opt().sender {
sender
} else {
ctx.state().default_account()?.address
};
let type_tags = opt.type_tags.clone().unwrap_or_default();
let args = opt.args.clone().unwrap_or_default();

let bytedata = {
let move_file_path = opt.mv_file.clone();
load_bytecode_file(move_file_path.as_path())?
};
let bytedata = { load_bytecode_file(opt.mv_file.as_path())? };

let txn_payload = match bytedata {
// script
Expand All @@ -119,70 +68,7 @@ impl CommandAction for ExecuteScriptCommand {
}
};

let raw_txn = {
let account_resource = {
let chain_state_reader = RemoteStateReader::new(client)?;
let account_state_reader = AccountStateReader::new(&chain_state_reader);
account_state_reader.get_account_resource(&sender)?
};

if account_resource.is_none() {
bail!("address {} not exists on chain", &sender);
}
let account_resource = account_resource.unwrap();

let expiration_time = {
let node_info = client.node_info()?;
opt.expiration_time + node_info.now_seconds
};
RawUserTransaction::new_with_default_gas_token(
sender,
account_resource.sequence_number(),
txn_payload,
opt.max_gas_amount,
opt.gas_price,
expiration_time,
ctx.state().net().chain_id(),
)
};

let signed_txn = client.account_sign_txn(raw_txn)?;
let txn_hash = signed_txn.id();
let output: TransactionOutputView = {
let state_view = RemoteStateReader::new(client)?;
playground::dry_run(
&state_view,
DryRunTransaction {
public_key: signed_txn.authenticator().public_key(),
raw_txn: signed_txn.raw_txn().clone(),
},
)
.map(|(_, b)| b.into())?
};
match output.status {
TransactionVMStatus::Discard { status_code } => {
bail!("TransactionStatus is discard: {:?}", status_code)
}
TransactionVMStatus::Executed => {}
s => {
bail!("pre-run failed, status: {:?}", s);
}
}
if !opt.dry_run {
client.submit_transaction(signed_txn)?;

eprintln!("txn {:#x} submitted.", txn_hash);

let mut output_view = ExecutionOutputView::new(txn_hash);

if opt.blocking {
let block = ctx.state().watch_txn(txn_hash)?.0;
output_view.block_number = Some(block.header.number.0);
output_view.block_id = Some(block.header.block_hash);
}
Ok(ExecuteResultView::Run(output_view))
} else {
Ok(ExecuteResultView::DryRun(output.into()))
}
ctx.state()
.build_and_execute_transaction(opt.transaction_opts.clone(), txn_payload)
}
}
123 changes: 12 additions & 111 deletions cmd/starcoin/src/account/execute_script_function_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,13 @@
// SPDX-License-Identifier: Apache-2.0

use crate::cli_state::CliState;
use crate::view::{ExecuteResultView, ExecutionOutputView};
use crate::view::{ExecuteResultView, TransactionOptions};
use crate::StarcoinOpt;
use anyhow::{bail, format_err, Result};
use anyhow::Result;
use scmd::{CommandAction, ExecContext};
use starcoin_dev::playground;
use starcoin_rpc_api::types::{FunctionIdView, TransactionOutputView, TransactionVMStatus};
use starcoin_rpc_client::RemoteStateReader;
use starcoin_state_api::AccountStateReader;
use starcoin_types::transaction::{
parse_transaction_argument, DryRunTransaction, RawUserTransaction, TransactionArgument,
};
use starcoin_vm_types::account_address::AccountAddress;
use starcoin_vm_types::transaction::ScriptFunction;
use starcoin_rpc_api::types::FunctionIdView;
use starcoin_types::transaction::{parse_transaction_argument, TransactionArgument};
use starcoin_vm_types::transaction::{ScriptFunction, TransactionPayload};
use starcoin_vm_types::transaction_argument::convert_txn_args;
use starcoin_vm_types::{language_storage::TypeTag, parser::parse_type_tag};
use structopt::StructOpt;
Expand All @@ -23,10 +17,6 @@ use structopt::StructOpt;
#[derive(Debug, StructOpt)]
#[structopt(name = "execute-function")]
pub struct ExecuteScriptFunctionOpt {
#[structopt(short = "s")]
/// if `sender` is absent, use default account.
sender: Option<AccountAddress>,

#[structopt(
short = "t",
long = "type_tag",
Expand All @@ -40,41 +30,8 @@ pub struct ExecuteScriptFunctionOpt {
/// args for the script.
args: Option<Vec<TransactionArgument>>,

#[structopt(
name = "expiration_time",
long = "timeout",
default_value = "3000",
help = "how long(in seconds) the txn stay alive"
)]
expiration_time: u64,

#[structopt(
short = "g",
name = "max-gas-amount",
default_value = "10000000",
help = "max gas used to deploy the module"
)]
max_gas_amount: u64,
#[structopt(
short = "p",
long = "gas-price",
name = "price of gas",
default_value = "1",
help = "gas price used to deploy the module"
)]
gas_price: u64,

#[structopt(
short = "b",
name = "blocking-mode",
long = "blocking",
help = "blocking wait txn mined"
)]
blocking: bool,

#[structopt(long = "dry-run")]
/// dry-run script, only get transaction output, no state change to chain
dry_run: bool,
#[structopt(flatten)]
transaction_opts: TransactionOptions,

#[structopt(long = "function", name = "script-function")]
/// script function to execute, example: 0x1::TransferScripts::peer_to_peer
Expand All @@ -94,73 +51,17 @@ impl CommandAction for ExecuteScriptFunctionCmd {
ctx: &ExecContext<Self::State, Self::GlobalOpt, Self::Opt>,
) -> Result<Self::ReturnItem> {
let opt = ctx.opt();
let client = ctx.state().client();
let node_info = client.node_info()?;

let sender = ctx.state().get_account_or_default(opt.sender)?;
let chain_state_reader = RemoteStateReader::new(client)?;
let account_state_reader = AccountStateReader::new(&chain_state_reader);
let account_resource = account_state_reader.get_account_resource(&sender.address)?;
let account_resource = account_resource.ok_or_else(|| {
format_err!("account of address {} not exists on chain", sender.address)
})?;
let expiration_time = opt.expiration_time + node_info.now_seconds;

let type_tags = opt.type_tags.clone().unwrap_or_default();
let args = opt.args.clone().unwrap_or_default();
let script_function = opt.script_function.clone().0;
let script_txn = RawUserTransaction::new_script_function(
sender.address,
account_resource.sequence_number(),
ScriptFunction::new(
ctx.state().build_and_execute_transaction(
opt.transaction_opts.clone(),
TransactionPayload::ScriptFunction(ScriptFunction::new(
script_function.module,
script_function.function,
type_tags,
convert_txn_args(&args),
),
opt.max_gas_amount,
opt.gas_price,
expiration_time,
ctx.state().net().chain_id(),
);

let signed_txn = client.account_sign_txn(script_txn)?;
let txn_hash = signed_txn.id();
let output: TransactionOutputView = {
let state_view = RemoteStateReader::new(client)?;
playground::dry_run(
&state_view,
DryRunTransaction {
public_key: signed_txn.authenticator().public_key(),
raw_txn: signed_txn.raw_txn().clone(),
},
)
.map(|(_, b)| b.into())?
};
match output.status {
TransactionVMStatus::Discard { status_code } => {
bail!("TransactionStatus is discard: {:?}", status_code)
}
TransactionVMStatus::Executed => {}
s => {
bail!("pre-run failed, status: {:?}", s);
}
}
if !opt.dry_run {
client.submit_transaction(signed_txn)?;

eprintln!("txn {:#x} submitted.", txn_hash);

let mut output_view = ExecutionOutputView::new(txn_hash);

if opt.blocking {
let block = ctx.state().watch_txn(txn_hash)?.0;
output_view.block_number = Some(block.header.number.0);
output_view.block_id = Some(block.header.block_hash);
}
Ok(ExecuteResultView::Run(output_view))
} else {
Ok(ExecuteResultView::DryRun(output.into()))
}
)),
)
}
}
Loading

0 comments on commit e48ca93

Please sign in to comment.