mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-07 22:04:03 -05:00
drk/interactive: added missing tx-from-calls subcommand
This commit is contained in:
@@ -55,22 +55,6 @@ pub async fn parse_tx_from_stdin() -> Result<Transaction> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Auxiliary function to parse base64-encoded contract calls from stdin.
|
|
||||||
pub async fn parse_calls_from_stdin() -> Result<Vec<ContractCallImport>> {
|
|
||||||
let lines = stdin().lines();
|
|
||||||
|
|
||||||
let mut calls = vec![];
|
|
||||||
|
|
||||||
for line in lines {
|
|
||||||
let Some(line) = base64::decode(&line?) else {
|
|
||||||
return Err(Error::ParseFailed("Failed to decode base64"))
|
|
||||||
};
|
|
||||||
calls.push(deserialize_async(&line).await?);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(calls)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Auxiliary function to parse a base64 encoded transaction from
|
/// Auxiliary function to parse a base64 encoded transaction from
|
||||||
/// provided input or fallback to stdin if its empty.
|
/// provided input or fallback to stdin if its empty.
|
||||||
pub async fn parse_tx_from_input(input: &[String]) -> Result<Transaction> {
|
pub async fn parse_tx_from_input(input: &[String]) -> Result<Transaction> {
|
||||||
@@ -84,6 +68,36 @@ pub async fn parse_tx_from_input(input: &[String]) -> Result<Transaction> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Auxiliary function to parse base64 encoded contract calls from stdin.
|
||||||
|
pub async fn parse_calls_from_stdin() -> Result<Vec<ContractCallImport>> {
|
||||||
|
let lines = stdin().lines();
|
||||||
|
let mut calls = vec![];
|
||||||
|
for line in lines {
|
||||||
|
let Some(line) = base64::decode(&line?) else {
|
||||||
|
return Err(Error::ParseFailed("Failed to decode base64"))
|
||||||
|
};
|
||||||
|
calls.push(deserialize_async(&line).await?);
|
||||||
|
}
|
||||||
|
Ok(calls)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Auxiliary function to parse base64 encoded contract calls from
|
||||||
|
/// provided input or fallback to stdin if its empty.
|
||||||
|
pub async fn parse_calls_from_input(input: &[String]) -> Result<Vec<ContractCallImport>> {
|
||||||
|
if input.is_empty() {
|
||||||
|
return parse_calls_from_stdin().await
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut calls = vec![];
|
||||||
|
for line in input {
|
||||||
|
let Some(line) = base64::decode(line) else {
|
||||||
|
return Err(Error::ParseFailed("Failed to decode base64"))
|
||||||
|
};
|
||||||
|
calls.push(deserialize_async(&line).await?);
|
||||||
|
}
|
||||||
|
Ok(calls)
|
||||||
|
}
|
||||||
|
|
||||||
/// Auxiliary function to parse provided string into a values pair.
|
/// Auxiliary function to parse provided string into a values pair.
|
||||||
pub fn parse_value_pair(s: &str) -> Result<(u64, u64)> {
|
pub fn parse_value_pair(s: &str) -> Result<(u64, u64)> {
|
||||||
let v: Vec<&str> = s.split(':').collect();
|
let v: Vec<&str> = s.split(':').collect();
|
||||||
@@ -391,8 +405,12 @@ pub fn generate_completions(shell: &str) -> Result<String> {
|
|||||||
.about("Attach the fee call to a transaction given from stdin");
|
.about("Attach the fee call to a transaction given from stdin");
|
||||||
|
|
||||||
// TxFromCalls
|
// TxFromCalls
|
||||||
|
let calls_map =
|
||||||
|
Arg::with_name("calls-map").help("Optional parent/children dependency map for the calls");
|
||||||
|
|
||||||
let tx_from_calls = SubCommand::with_name("tx-from-calls")
|
let tx_from_calls = SubCommand::with_name("tx-from-calls")
|
||||||
.about("Create a transaction from newline-separated calls from stdin");
|
.about("Create a transaction from newline-separated calls from stdin")
|
||||||
|
.args(&[calls_map]);
|
||||||
|
|
||||||
// Inspect
|
// Inspect
|
||||||
let inspect = SubCommand::with_name("inspect").about("Inspect a transaction from stdin");
|
let inspect = SubCommand::with_name("inspect").about("Inspect a transaction from stdin");
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ use darkfi_serial::{deserialize_async, serialize_async};
|
|||||||
use crate::{
|
use crate::{
|
||||||
cli_util::{
|
cli_util::{
|
||||||
append_or_print, display_mining_config, generate_completions, kaching,
|
append_or_print, display_mining_config, generate_completions, kaching,
|
||||||
parse_mining_config_from_input, parse_token_pair, parse_tx_from_input, parse_value_pair,
|
parse_calls_from_input, parse_mining_config_from_input, parse_token_pair, parse_tree,
|
||||||
print_output,
|
parse_tx_from_input, parse_value_pair, print_output, tx_from_calls_mapped,
|
||||||
},
|
},
|
||||||
common::*,
|
common::*,
|
||||||
dao::{DaoParams, ProposalRecord},
|
dao::{DaoParams, ProposalRecord},
|
||||||
@@ -94,6 +94,9 @@ fn help(output: &mut Vec<String>) {
|
|||||||
output.push(String::from("\tdao: DAO functionalities"));
|
output.push(String::from("\tdao: DAO functionalities"));
|
||||||
output
|
output
|
||||||
.push(String::from("\tattach-fee: Attach the fee call to a transaction given from stdin"));
|
.push(String::from("\tattach-fee: Attach the fee call to a transaction given from stdin"));
|
||||||
|
output.push(String::from(
|
||||||
|
"\ttx-from-calls: Create a transaction from newline-separated calls from stdin",
|
||||||
|
));
|
||||||
output.push(String::from("\tinspect: Inspect a transaction from stdin"));
|
output.push(String::from("\tinspect: Inspect a transaction from stdin"));
|
||||||
output.push(String::from("\tbroadcast: Read a transaction from stdin and broadcast it"));
|
output.push(String::from("\tbroadcast: Read a transaction from stdin and broadcast it"));
|
||||||
output.push(String::from(
|
output.push(String::from(
|
||||||
@@ -207,6 +210,11 @@ fn completion(buffer: &str, lc: &mut Vec<String>) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if last.starts_with("tx") {
|
||||||
|
lc.push(prefix + "tx-from-calls");
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if last.starts_with("i") {
|
if last.starts_with("i") {
|
||||||
lc.push(prefix + "inspect");
|
lc.push(prefix + "inspect");
|
||||||
return
|
return
|
||||||
@@ -378,6 +386,7 @@ fn hints(buffer: &str) -> Option<(String, i32, bool)> {
|
|||||||
"contract export-data " => Some(("<tx-hash>".to_string(), color, bold)),
|
"contract export-data " => Some(("<tx-hash>".to_string(), color, bold)),
|
||||||
"contract deploy " => Some(("<deploy-auth> <wasm-path> [deploy-ix]".to_string(), color, bold)),
|
"contract deploy " => Some(("<deploy-auth> <wasm-path> [deploy-ix]".to_string(), color, bold)),
|
||||||
"contract lock " => Some(("<deploy-auth>".to_string(), color, bold)),
|
"contract lock " => Some(("<deploy-auth>".to_string(), color, bold)),
|
||||||
|
"tx-from-calls " => Some(("[calls-map]".to_string(), color, bold)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -536,6 +545,7 @@ pub async fn interactive(
|
|||||||
"otc" => handle_otc(drk, &parts, &input, &mut output).await,
|
"otc" => handle_otc(drk, &parts, &input, &mut output).await,
|
||||||
"dao" => handle_dao(drk, &parts, &input, &mut output).await,
|
"dao" => handle_dao(drk, &parts, &input, &mut output).await,
|
||||||
"attach-fee" => handle_attach_fee(drk, &input, &mut output).await,
|
"attach-fee" => handle_attach_fee(drk, &input, &mut output).await,
|
||||||
|
"tx-from-calls" => handle_tx_from_calls(&parts, &input, &mut output).await,
|
||||||
"inspect" => handle_inspect(&input, &mut output).await,
|
"inspect" => handle_inspect(&input, &mut output).await,
|
||||||
"broadcast" => handle_broadcast(drk, &input, &mut output).await,
|
"broadcast" => handle_broadcast(drk, &input, &mut output).await,
|
||||||
"subscribe" => {
|
"subscribe" => {
|
||||||
@@ -2341,6 +2351,79 @@ async fn handle_attach_fee(drk: &DrkPtr, input: &[String], output: &mut Vec<Stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Auxiliary function to define the tx from calls command handling.
|
||||||
|
async fn handle_tx_from_calls(parts: &[&str], input: &[String], output: &mut Vec<String>) {
|
||||||
|
// Check correct subcommand structure
|
||||||
|
if parts.len() != 1 && parts.len() != 2 {
|
||||||
|
output.push(String::from("Malformed `tx-from-calls` subcommand"));
|
||||||
|
output.push(String::from("Usage: tx-from-calls [calls-map]"));
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse calls
|
||||||
|
let calls = match parse_calls_from_input(input).await {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(e) => {
|
||||||
|
output.push(format!("Error while parsing transaction calls: {e}"));
|
||||||
|
return
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if calls.is_empty() {
|
||||||
|
output.push(String::from("No calls were parsed"));
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is a given map, parse it, otherwise construct a
|
||||||
|
// linear map.
|
||||||
|
let calls_map = if parts.len() == 2 {
|
||||||
|
match parse_tree(parts[1]) {
|
||||||
|
Ok(m) => m,
|
||||||
|
Err(e) => {
|
||||||
|
output.push(format!("Failed parsing calls map: {e}"));
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let mut calls_map = Vec::with_capacity(calls.len());
|
||||||
|
for (i, _) in calls.iter().enumerate() {
|
||||||
|
calls_map.push((i, vec![]));
|
||||||
|
}
|
||||||
|
calls_map
|
||||||
|
};
|
||||||
|
if calls_map.len() != calls.len() {
|
||||||
|
output.push(String::from("Calls map size not equal to parsed calls"));
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a transaction from the mapped calls.
|
||||||
|
let (mut tx_builder, signature_secrets) = match tx_from_calls_mapped(&calls, &calls_map) {
|
||||||
|
Ok(pair) => pair,
|
||||||
|
Err(e) => {
|
||||||
|
output.push(format!("Failed to create a transaction from the mapped calls: {e}"));
|
||||||
|
return
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Now build and sign the tx
|
||||||
|
let mut tx = match tx_builder.build() {
|
||||||
|
Ok(tx) => tx,
|
||||||
|
Err(e) => {
|
||||||
|
output.push(format!("Failed to build the transaction: {e}"));
|
||||||
|
return
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let sigs = match tx.create_sigs(&signature_secrets) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => {
|
||||||
|
output.push(format!("Failed to create the transaction signatures: {e}"));
|
||||||
|
return
|
||||||
|
}
|
||||||
|
};
|
||||||
|
tx.signatures.push(sigs);
|
||||||
|
|
||||||
|
output.push(base64::encode(&serialize_async(&tx).await));
|
||||||
|
}
|
||||||
|
|
||||||
/// Auxiliary function to define the inspect command handling.
|
/// Auxiliary function to define the inspect command handling.
|
||||||
async fn handle_inspect(input: &[String], output: &mut Vec<String>) {
|
async fn handle_inspect(input: &[String], output: &mut Vec<String>) {
|
||||||
match parse_tx_from_input(input).await {
|
match parse_tx_from_input(input).await {
|
||||||
|
|||||||
@@ -180,8 +180,7 @@ enum Subcmd {
|
|||||||
|
|
||||||
/// Create a transaction from newline-separated calls from stdin
|
/// Create a transaction from newline-separated calls from stdin
|
||||||
TxFromCalls {
|
TxFromCalls {
|
||||||
#[structopt(long = "map")]
|
/// Optional parent/children dependency map for the calls
|
||||||
/// The parent/children dependency map for the calls
|
|
||||||
calls_map: Option<String>,
|
calls_map: Option<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -2024,8 +2023,12 @@ async fn realmain(args: Args, ex: ExecutorPtr) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Subcmd::TxFromCalls { calls_map } => {
|
Subcmd::TxFromCalls { calls_map } => {
|
||||||
|
// Parse calls
|
||||||
let calls = parse_calls_from_stdin().await?;
|
let calls = parse_calls_from_stdin().await?;
|
||||||
assert!(!calls.is_empty());
|
if calls.is_empty() {
|
||||||
|
eprintln!("No calls were parsed");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
// If there is a given map, parse it, otherwise construct a
|
// If there is a given map, parse it, otherwise construct a
|
||||||
// linear map.
|
// linear map.
|
||||||
@@ -2033,7 +2036,7 @@ async fn realmain(args: Args, ex: ExecutorPtr) -> Result<()> {
|
|||||||
Some(cmap) => match parse_tree(&cmap) {
|
Some(cmap) => match parse_tree(&cmap) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Failed parsing calls map: {}", e);
|
eprintln!("Failed parsing calls map: {e}");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user