commit 324a965cc1d702d8ca7dc413596ee7758e025547
parent 9ef4dce283e9c5c6c8fb14ff296692e82a433e5c
Author: Antoine A <>
Date: Tue, 23 Jun 2026 11:29:48 +0200
testbench: user taler-rust repl
Diffstat:
3 files changed, 73 insertions(+), 111 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -21,4 +21,5 @@ tools
debian/depolymerizer-bitcoin
debian/files
debian/*.substvars
-debian/*debhelper*
-\ No newline at end of file
+debian/*debhelper*
+.history
+\ No newline at end of file
diff --git a/testbench/Cargo.toml b/testbench/Cargo.toml
@@ -21,8 +21,8 @@ owo-colors = "4.0.0"
rust-ini = "0.21.0"
# Progress reporting
indicatif = "0.18.0"
-reedline = "0.48.0"
taler-common.workspace = true
+taler-test-utils.workspace = true
tokio.workspace = true
anyhow.workspace = true
tracing-subscriber.workspace = true
diff --git a/testbench/src/main.rs b/testbench/src/main.rs
@@ -15,7 +15,6 @@
*/
use std::{
- borrow::Cow,
panic::UnwindSafe,
path::{Path, PathBuf},
str::FromStr,
@@ -37,7 +36,6 @@ use depolymerizer_bitcoin::{
};
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use owo_colors::OwoColorize;
-use reedline::{Prompt, Reedline, Signal};
use sqlx::PgPool;
use taler_common::{
api::{EddsaPublicKey, HashCode, ShortHashCode, wire::TransferRequest},
@@ -46,8 +44,9 @@ use taler_common::{
log::taler_logger,
types::{amount::amount, payto::FullPayto},
};
+use taler_test_utils::repl::Repl;
use tokio::task::{JoinError, JoinHandle};
-use tracing::{error, info};
+use tracing::info;
use tracing_subscriber::util::SubscriberInitExt as _;
use url::Url;
@@ -155,10 +154,9 @@ impl BtcEnv {
println!("Setup bitcoin {network:?} env in {network_dir}");
let root_dir = PathBuf::from_str("./testbench/env")
.unwrap()
- .join(network_dir)
- .canonicalize()
- .unwrap();
+ .join(network_dir);
std::fs::create_dir_all(root_dir.join("bitcoin")).unwrap();
+ let root_dir = root_dir.canonicalize().unwrap();
// Generate bitcoind config
let cfg = match network {
@@ -290,6 +288,7 @@ impl BtcEnv {
}
#[derive(clap::Parser, Debug)]
+#[command(no_binary_name = true)]
enum Shell {
Setup,
Reset,
@@ -313,99 +312,10 @@ enum Shell {
},
}
-async fn run_cmd(env: &mut BtcEnv, buffer: &str) -> anyhow::Result<bool> {
- if buffer.is_empty() {
- return Ok(false);
- }
- let cmd = Shell::try_parse_from(std::iter::once("shell").chain(buffer.split(' ')))?;
- match cmd {
- Shell::Setup => run(Command::Setup { reset: false }, &env.cfg).await?,
- Shell::Reset => run(Command::Setup { reset: true }, &env.cfg).await?,
- Shell::ResetDb => {
- run(Command::Dbinit { reset: true }, &env.cfg).await?;
- run(Command::Setup { reset: false }, &env.cfg).await?;
- }
- Shell::Sync => run(Command::Worker { transient: true }, &env.cfg).await?,
- Shell::Credit => {
- let reserve_pub = EddsaPublicKey::rand();
- let amount = amount("DEVBTC:0.00011");
- let txid = env
- .client_rpc
- .send_segwit_key(&env.wire_addr, &taler_to_btc(&amount), &reserve_pub)
- .await?;
- env.tracked.push(txid);
- info!(target: "testbench", "Credit {reserve_pub} {amount} {txid} to {}", env.wire_addr);
- }
- Shell::Debit => {
- let creditor = FullPayto::new(BtcWallet(env.client_addr.clone()), "client");
- let wtid = ShortHashCode::rand();
- let amount = amount("DEVBTC:0.0001");
- let transfer = TransferRequest {
- request_uid: HashCode::rand(),
- amount,
- exchange_base_url: Url::parse("https://test.com/").unwrap(),
- wtid: wtid.clone(),
- credit_account: creditor.as_uri(),
- metadata: None,
- };
- db::transfer(&env.pool, &creditor, &transfer).await?;
- info!(target: "testbench", "Debit {wtid} {amount} to {}", env.wire_addr);
- }
- Shell::Mine { amount, addr } => {
- let amount = amount.unwrap_or(1);
- let addr = addr.map(|a| a.assume_checked());
- let addr = addr.as_ref().unwrap_or(&env.client_addr);
- env.client_rpc.mine(amount, addr).await?;
- }
- Shell::Exit => return Ok(true),
- Shell::Tx { txid } => {
- let info = env.client_rpc.get_tx(&txid).await?;
- info!(target: "testbench", "{txid} {} {}", info.amount, info.confirmations);
- }
- Shell::Track { txid } => {
- env.tracked.push(txid);
- }
- Shell::Untrack { txid } => {
- env.tracked.retain(|id| *id != txid);
- }
- }
- Ok(false)
-}
-
-struct TestBenchPrompt {
- name: String,
- progress: String,
-}
-
-impl Prompt for TestBenchPrompt {
- fn render_prompt_left(&self) -> Cow<'_, str> {
- Cow::Borrowed(&self.name)
- }
-
- fn render_prompt_right(&self) -> Cow<'_, str> {
- Cow::Borrowed(&self.progress)
- }
-
- fn render_prompt_indicator(&self, _: reedline::PromptEditMode) -> Cow<'_, str> {
- Cow::Borrowed(">")
- }
-
- fn render_prompt_multiline_indicator(&self) -> Cow<'_, str> {
- Cow::Borrowed(":")
- }
-
- fn render_prompt_history_search_indicator(
- &self,
- _: reedline::PromptHistorySearch,
- ) -> Cow<'_, str> {
- Cow::Borrowed(">")
- }
-}
-
async fn bitcoin(network: Network) {
let mut env = BtcEnv::init(network).await;
- let mut line_editor = Reedline::create();
+ let mut repl = Repl::new(".history");
loop {
let info = env.client_rpc.get_blockchain_info().await.unwrap();
let wire_balance = env.wire_rpc.get_balance().await.unwrap();
@@ -423,20 +333,71 @@ async fn bitcoin(network: Network) {
Err(e) => println!("{} {txid} {}", "tx".cyan(), e.red()),
}
}
- let prompt = TestBenchPrompt {
- name: info.chain,
- progress: format!("{:.6}", info.verification_progress),
- };
- let sig = line_editor.read_line(&prompt).unwrap();
- while let Signal::Success(buffer) = &sig {
- match run_cmd(&mut env, buffer).await {
- Ok(exit) => {
- if exit {
- break;
- }
+ if let Some(cmd) =
+ repl.read_line(&info.chain, &format!("{:.6}", info.verification_progress))
+ {
+ match cmd {
+ Shell::Setup => run(Command::Setup { reset: false }, &env.cfg)
+ .await
+ .unwrap(),
+ Shell::Reset => run(Command::Setup { reset: true }, &env.cfg).await.unwrap(),
+ Shell::ResetDb => {
+ run(Command::Dbinit { reset: true }, &env.cfg)
+ .await
+ .unwrap();
+ run(Command::Setup { reset: false }, &env.cfg)
+ .await
+ .unwrap();
+ }
+ Shell::Sync => run(Command::Worker { transient: true }, &env.cfg)
+ .await
+ .unwrap(),
+ Shell::Credit => {
+ let reserve_pub = EddsaPublicKey::rand();
+ let amount = amount("DEVBTC:0.00011");
+ let txid = env
+ .client_rpc
+ .send_segwit_key(&env.wire_addr, &taler_to_btc(&amount), &reserve_pub)
+ .await
+ .unwrap();
+ env.tracked.push(txid);
+ info!(target: "testbench", "Credit {reserve_pub} {amount} {txid} to {}", env.wire_addr);
+ }
+ Shell::Debit => {
+ let creditor = FullPayto::new(BtcWallet(env.client_addr.clone()), "client");
+ let wtid = ShortHashCode::rand();
+ let amount = amount("DEVBTC:0.0001");
+ let transfer = TransferRequest {
+ request_uid: HashCode::rand(),
+ amount,
+ exchange_base_url: Url::parse("https://test.com/").unwrap(),
+ wtid: wtid.clone(),
+ credit_account: creditor.as_uri(),
+ metadata: None,
+ };
+ db::transfer(&env.pool, &creditor, &transfer).await.unwrap();
+ info!(target: "testbench", "Debit {wtid} {amount} to {}", env.wire_addr);
+ }
+ Shell::Mine { amount, addr } => {
+ let amount = amount.unwrap_or(1);
+ let addr = addr.map(|a| a.assume_checked());
+ let addr = addr.as_ref().unwrap_or(&env.client_addr);
+ env.client_rpc.mine(amount, addr).await.unwrap();
+ }
+ Shell::Exit => break,
+ Shell::Tx { txid } => {
+ let info = env.client_rpc.get_tx(&txid).await.unwrap();
+ info!(target: "testbench", "{txid} {} {}", info.amount, info.confirmations);
+ }
+ Shell::Track { txid } => {
+ env.tracked.push(txid);
+ }
+ Shell::Untrack { txid } => {
+ env.tracked.retain(|id| *id != txid);
}
- Err(e) => error!(target: "testbench", "{e}"),
}
+ } else {
+ break;
}
}
}