summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntoine A <>2023-01-31 09:09:24 +0100
committerAntoine A <>2023-01-31 15:29:13 +0100
commit88b8c4d62424ccb1804cfea8bbf4d686226261b3 (patch)
tree55bd8091ed859472ed05c38de2f0e6446a3c938c
parent67c682100c7efcf58d53418c45e6611e5f6eab82 (diff)
downloaddepolymerization-88b8c4d62424ccb1804cfea8bbf4d686226261b3.tar.gz
depolymerization-88b8c4d62424ccb1804cfea8bbf4d686226261b3.tar.bz2
depolymerization-88b8c4d62424ccb1804cfea8bbf4d686226261b3.zip
Run integration tests in parallel
-rw-r--r--Cargo.lock68
-rw-r--r--instrumentation/Cargo.toml3
-rw-r--r--instrumentation/src/btc.rs286
-rw-r--r--instrumentation/src/eth.rs255
-rw-r--r--instrumentation/src/gateway.rs33
-rw-r--r--instrumentation/src/main.rs120
-rw-r--r--instrumentation/src/utils.rs332
-rw-r--r--makefile2
-rwxr-xr-xscript/prepare.sh4
9 files changed, 617 insertions, 486 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 6ee38be..816e6e2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -54,9 +54,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]]
name = "async-trait"
-version = "0.1.63"
+version = "0.1.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eff18d764974428cf3a9328e23fc5c986f5fbed46e6cd4cdf42544df5d297ec1"
+checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2"
dependencies = [
"proc-macro2",
"quote",
@@ -212,9 +212,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "cc"
-version = "1.0.78"
+version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
[[package]]
name = "cfg-if"
@@ -513,9 +513,9 @@ dependencies = [
[[package]]
name = "cxx"
-version = "1.0.87"
+version = "1.0.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b61a7545f753a88bcbe0a70de1fcc0221e10bfc752f576754fa91e663db1622e"
+checksum = "322296e2f2e5af4270b54df9e85a02ff037e271af20ba3e7fe1575515dc840b8"
dependencies = [
"cc",
"cxxbridge-flags",
@@ -525,9 +525,9 @@ dependencies = [
[[package]]
name = "cxx-build"
-version = "1.0.87"
+version = "1.0.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f464457d494b5ed6905c63b0c4704842aba319084a0a3561cdc1359536b53200"
+checksum = "017a1385b05d631e7875b1f151c9f012d37b53491e2a87f65bff5c262b2111d8"
dependencies = [
"cc",
"codespan-reporting",
@@ -540,15 +540,15 @@ dependencies = [
[[package]]
name = "cxxbridge-flags"
-version = "1.0.87"
+version = "1.0.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43c7119ce3a3701ed81aca8410b9acf6fc399d2629d057b87e2efa4e63a3aaea"
+checksum = "c26bbb078acf09bc1ecda02d4223f03bdd28bd4874edcb0379138efc499ce971"
[[package]]
name = "cxxbridge-macro"
-version = "1.0.87"
+version = "1.0.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65e07508b90551e610910fa648a1878991d367064997a596135b86df30daf07e"
+checksum = "357f40d1f06a24b60ae1fe122542c1fb05d28d32acb2aed064e84bc2ad1e252e"
dependencies = [
"proc-macro2",
"quote",
@@ -605,9 +605,9 @@ dependencies = [
[[package]]
name = "deadpool-postgres"
-version = "0.10.4"
+version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "051c50d234dab03bd29a537859bb7f50cca718c90b05e5c5746b9ae2a73f7278"
+checksum = "836a24a9d49deefe610b8b60c767a7412e9a931d79a89415cd2d2d71630ca8d7"
dependencies = [
"deadpool",
"log",
@@ -643,9 +643,9 @@ checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257"
[[package]]
name = "either"
-version = "1.8.0"
+version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
+checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
[[package]]
name = "env_logger"
@@ -784,9 +784,9 @@ dependencies = [
[[package]]
name = "futures-channel"
-version = "0.3.25"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
+checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5"
dependencies = [
"futures-core",
"futures-sink",
@@ -794,15 +794,15 @@ dependencies = [
[[package]]
name = "futures-core"
-version = "0.3.25"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
+checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608"
[[package]]
name = "futures-macro"
-version = "0.3.25"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
+checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70"
dependencies = [
"proc-macro2",
"quote",
@@ -811,21 +811,21 @@ dependencies = [
[[package]]
name = "futures-sink"
-version = "0.3.25"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
+checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364"
[[package]]
name = "futures-task"
-version = "0.3.25"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
+checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366"
[[package]]
name = "futures-util"
-version = "0.3.25"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
+checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1"
dependencies = [
"futures-core",
"futures-macro",
@@ -1079,8 +1079,10 @@ dependencies = [
"hex",
"libdeflater",
"owo-colors",
+ "rust-ini",
"signal-child",
"tempfile",
+ "thread-local-panic-hook",
"ureq",
]
@@ -2009,6 +2011,12 @@ dependencies = [
]
[[package]]
+name = "thread-local-panic-hook"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e70399498abd3ec85f99a2f2d765c8638588e20361678af93a9f47de96719743"
+
+[[package]]
name = "time"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2071,9 +2079,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
-version = "1.24.2"
+version = "1.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb"
+checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af"
dependencies = [
"autocfg",
"bytes",
diff --git a/instrumentation/Cargo.toml b/instrumentation/Cargo.toml
index 2887084..6e6e70c 100644
--- a/instrumentation/Cargo.toml
+++ b/instrumentation/Cargo.toml
@@ -31,6 +31,9 @@ owo-colors = "3.5.0"
color-backtrace = "0.5.1"
# Send signal to child processes
signal-child = "1.0.5"
+# Edit toml files
+rust-ini = "0.18.0"
+thread-local-panic-hook = "0.1.0"
[build-dependencies]
diff --git a/instrumentation/src/btc.rs b/instrumentation/src/btc.rs
index cfe113a..b9b9fc6 100644
--- a/instrumentation/src/btc.rs
+++ b/instrumentation/src/btc.rs
@@ -31,10 +31,11 @@ use btc_wire::{
WireState,
};
use common::{currency::CurrencyBtc, metadata::OutMetadata, postgres::NoTls, rand_slice};
+use tempfile::TempDir;
use crate::utils::{
check_incoming, check_outgoing, cmd_redirect, cmd_redirect_ok, print_now, retry, retry_opt,
- transfer, ChildGuard, CommonCtx, Dirs,
+ transfer, unused_port, ChildGuard, TalerCtx, TestCtx,
};
pub const CLIENT: &str = "client";
@@ -228,48 +229,42 @@ pub struct BtcCtx {
reserve_addr: Address,
state: WireState,
conf: u16,
- common: CommonCtx,
+ ctx: TalerCtx,
+ node2_addr: String,
}
impl Deref for BtcCtx {
- type Target = CommonCtx;
+ type Target = TalerCtx;
fn deref(&self) -> &Self::Target {
- &self.common
+ &self.ctx
}
}
impl DerefMut for BtcCtx {
fn deref_mut(&mut self) -> &mut Self::Target {
- &mut self.common
+ &mut self.ctx
}
}
impl BtcCtx {
- pub fn setup(config: &str, stressed: bool) -> Self {
- Self::_setup(config, stressed)
- }
-
- pub fn config(config: &str) {
- std::fs::create_dir_all("log").unwrap();
- for file in std::fs::read_dir("log").unwrap() {
- std::fs::write(file.unwrap().path(), "").unwrap();
- }
+ pub fn config(test_name: &str, config: &str) {
// Generate temporary dirs
- let dirs = Dirs::generate();
+ let ctx = TestCtx::new(test_name);
// Bitcoin config
let config = PathBuf::from_str("instrumentation/conf")
.unwrap()
.join(config);
- std::fs::copy(config, dirs.wire_dir.join("bitcoin.conf")).unwrap();
+ let wire_dir = TempDir::new().unwrap();
+ let wire_dir = wire_dir.path();
+ std::fs::copy(config, wire_dir.join("bitcoin.conf")).unwrap();
// Load config
- let config =
- BitcoinConfig::load(dirs.wire_dir.join("bitcoin.conf"), CurrencyBtc::Dev).unwrap();
+ let config = BitcoinConfig::load(wire_dir.join("bitcoin.conf"), CurrencyBtc::Dev).unwrap();
// Start bitcoin nodes
let _btc_node = cmd_redirect(
"bitcoind",
- &[&format!("-datadir={}", dirs.wire_dir.to_string_lossy())],
- "log/node.log",
+ &[&format!("-datadir={}", wire_dir.to_string_lossy())],
+ &ctx.log("bitcoind"),
);
// Connect
retry(|| {
@@ -280,52 +275,65 @@ impl BtcCtx {
})
}
- fn _setup(taler_config: &str, stressed: bool) -> Self {
- let dirs = CommonCtx::setup_dirs(taler_config);
- // Prepare config
- let (btc_config2, state) = {
- // Bitcoin config
- let config = PathBuf::from_str("instrumentation/conf")
- .unwrap()
- .join("bitcoin.conf");
- std::fs::copy(config, dirs.wire_dir.join("bitcoin.conf")).unwrap();
- std::fs::copy(
- "instrumentation/conf/bitcoin2.conf",
- dirs.wire_dir2.join("bitcoin.conf"),
- )
- .unwrap();
- // Load config
- let state = WireState::load_taler_config(Some(&dirs.conf));
- (
- BitcoinConfig::load(dirs.wire_dir2.join("bitcoin.conf"), state.currency).unwrap(),
- state,
- )
- };
+ fn patch_config(from: &str, to: PathBuf, port: u16, rpc_port: u16) {
+ let mut config = ini::Ini::load_from_file(from).unwrap();
+ config
+ .with_section(Some("regtest"))
+ .set("port", port.to_string())
+ .set("rpcport", rpc_port.to_string());
+ config.write_to_file(to).unwrap();
+ }
+
+ pub fn setup(ctx: &TestCtx, taler_config: &str, stressed: bool) -> Self {
+ let mut ctx = TalerCtx::new(ctx, "btc-wire", taler_config, stressed);
+ // Choose unused port
+ let btc_port = unused_port();
+ let btc_rpc_port = unused_port();
+ let btc2_port = unused_port();
+ let btc2_rpc_port = unused_port();
+ // Bitcoin config
+ Self::patch_config(
+ "instrumentation/conf/bitcoin.conf",
+ ctx.wire_dir.join("bitcoin.conf"),
+ btc_port,
+ btc_rpc_port,
+ );
+ Self::patch_config(
+ "instrumentation/conf/bitcoin2.conf",
+ ctx.wire2_dir.join("bitcoin.conf"),
+ btc2_port,
+ btc2_rpc_port,
+ );
+ // Load config
+ let state = WireState::load_taler_config(Some(&ctx.conf));
+ let btc_config2 =
+ BitcoinConfig::load(ctx.wire2_dir.join("bitcoin.conf"), state.currency).unwrap();
// Start bitcoin nodes
let btc_node = cmd_redirect(
"bitcoind",
- &[&format!("-datadir={}", dirs.wire_dir.to_string_lossy())],
- "log/node.log",
+ &[&format!("-datadir={}", ctx.wire_dir.to_string_lossy())],
+ &ctx.log("bitcoind"),
);
- let btc_node2 = cmd_redirect(
+ let _btc_node2 = cmd_redirect(
"bitcoind",
- &[&format!("-datadir={}", dirs.wire_dir2.to_string_lossy())],
- "log/node2.log",
+ &[&format!("-datadir={}", ctx.wire2_dir.to_string_lossy())],
+ &ctx.log("bitcoind2"),
);
- let common = CommonCtx::setup(dirs, "btc-wire", stressed, |dirs| {
- // Generate wallet
- cmd_redirect_ok(
- "btc-wire",
- &["-c", dirs.conf.to_str().unwrap(), "initwallet"],
- "log/cmd.log",
- "wire initwallet",
- );
- });
+ ctx.init_db();
+ // Generate wallet
+ cmd_redirect_ok(
+ "btc-wire",
+ &["-c", ctx.conf.to_str().unwrap(), "initwallet"],
+ &ctx.log("cmd"),
+ "wire initwallet",
+ );
+ ctx.run();
// Setup wallets
let mut common_rpc = retry_opt(|| Rpc::common(&state.btc_config).ok());
- common_rpc.add_node("127.0.0.1:8346").unwrap();
+ let node2_addr = format!("127.0.0.1:{btc2_port}");
+ common_rpc.add_node(&node2_addr).unwrap();
for name in ["client", "reserve"] {
common_rpc.create_wallet(name, "").unwrap();
@@ -346,7 +354,7 @@ impl BtcCtx {
common_rpc.mine(1, &reserve_addr).unwrap();
Self {
- common,
+ ctx,
btc_node,
common_rpc,
wire_rpc,
@@ -357,14 +365,15 @@ impl BtcCtx {
reserve_addr,
conf: state.confirmation as u16,
state,
- _btc_node2: btc_node2,
+ _btc_node2,
common_rpc2,
+ node2_addr,
}
}
pub fn reset_db(&mut self) {
let hash: BlockHash = self.common_rpc.get_genesis().unwrap();
- let mut db = self.common.taler_conf.db_config().connect(NoTls).unwrap();
+ let mut db = self.ctx.taler_conf.db_config().connect(NoTls).unwrap();
let mut tx = db.transaction().unwrap();
// Clear transaction tables and reset state
tx.batch_execute("DELETE FROM tx_in;DELETE FROM tx_out;DELETE FROM bounce;")
@@ -392,12 +401,12 @@ impl BtcCtx {
}
pub fn cluster_deco(&mut self) {
- self.common_rpc.disconnect_node("127.0.0.1:8346").unwrap();
+ self.common_rpc.disconnect_node(&self.node2_addr).unwrap();
}
pub fn cluster_fork(&mut self, length: u16) {
self.common_rpc2.mine(length, &self.reserve_addr).unwrap();
- self.common_rpc.add_node("127.0.0.1:8346").unwrap();
+ self.common_rpc.add_node(&self.node2_addr).unwrap();
}
pub fn restart_node(&mut self, additional_args: &[&str]) {
@@ -406,12 +415,12 @@ impl BtcCtx {
}
pub fn resume_node(&mut self, additional_args: &[&str]) {
- let datadir = format!("-datadir={}", self.common.dirs.wire_dir.to_string_lossy());
+ let datadir = format!("-datadir={}", self.ctx.wire_dir.to_string_lossy());
let mut args = vec![datadir.as_str()];
args.extend_from_slice(additional_args);
- self.btc_node = cmd_redirect("bitcoind", &args, "log/node.log");
+ self.btc_node = cmd_redirect("bitcoind", &args, &self.ctx.log("bitcoind"));
self.common_rpc = retry_opt(|| Rpc::common(&self.state.btc_config).ok());
- self.common_rpc.add_node("127.0.0.1:8346").unwrap();
+ self.common_rpc.add_node(&self.node2_addr).unwrap();
for name in ["client", "reserve", "wire"] {
self.common_rpc.load_wallet(name).ok();
}
@@ -431,7 +440,7 @@ impl BtcCtx {
pub fn debit(&mut self, amount: Amount, metadata: [u8; 32]) {
transfer(
- &self.common.gateway_url,
+ &self.ctx.gateway_url,
&metadata,
&self.state.base_url,
btc_payto_url(&self.client_addr),
@@ -524,7 +533,7 @@ impl BtcCtx {
)
})
.collect();
- self.common.expect_credits(&txs)
+ self.ctx.expect_credits(&txs)
}
pub fn expect_debits(&self, txs: &[([u8; 32], Amount)]) {
@@ -537,30 +546,16 @@ impl BtcCtx {
)
})
.collect();
- self.common.expect_debits(&self.state.base_url, &txs)
+ self.ctx.expect_debits(&self.state.base_url, &txs)
}
}
-pub const TESTS: &[(fn(), &str)] = &[
- (wire, "btc_wire"),
- (lifetime, "btc_lifetime"),
- (reconnect, "btc_reconnect"),
- (stress, "btc_stress"),
- (conflict, "btc_conflict"),
- (reorg, "btc_reorg"),
- (hell, "btc_hell"),
- (analysis, "btc_analysis"),
- (bumpfee, "btc_bumpfee"),
- (maxfee, "btc_maxfee"),
- (config, "btc_config"),
-];
-
/// Test btc-wire correctly receive and send transactions on the blockchain
-fn wire() {
- println!("Setup");
- let mut ctx = BtcCtx::setup("taler_btc.conf", false);
+pub fn wire(ctx: TestCtx) {
+ ctx.step("Setup");
+ let mut ctx = BtcCtx::setup(&ctx, "taler_btc.conf", false);
- println!("Credit");
+ ctx.step("Credit");
{
// Send transactions
let mut balance = ctx.wire_balance();
@@ -578,7 +573,7 @@ fn wire() {
ctx.expect_wire_balance(balance, true);
};
- println!("Debit");
+ ctx.step("Debit");
{
let mut balance = ctx.client_balance();
let mut txs = Vec::new();
@@ -594,7 +589,7 @@ fn wire() {
ctx.expect_client_balance(balance, true);
}
- println!("Bounce");
+ ctx.step("Bounce");
{
ctx.reset_wallet();
// Send bad transactions
@@ -609,10 +604,10 @@ fn wire() {
}
/// Check btc-wire and wire-gateway correctly stop when a lifetime limit is configured
-fn lifetime() {
- println!("Setup");
- let mut ctx = BtcCtx::setup("taler_btc_lifetime.conf", false);
- println!("Check lifetime");
+pub fn lifetime(ctx: TestCtx) {
+ ctx.step("Setup");
+ let mut ctx = BtcCtx::setup(&ctx, "taler_btc_lifetime.conf", false);
+ ctx.step("Check lifetime");
// Start up
retry(|| ctx.wire_running() && ctx.gateway_running());
// Consume lifetime
@@ -629,14 +624,14 @@ fn lifetime() {
}
/// Check the capacity of wire-gateway and btc-wire to recover from database and node loss
-fn reconnect() {
- println!("Setup");
- let mut ctx = BtcCtx::setup("taler_btc.conf", false);
+pub fn reconnect(ctx: TestCtx) {
+ ctx.step("Setup");
+ let mut ctx = BtcCtx::setup(&ctx, "taler_btc.conf", false);
let mut credits = Vec::new();
let mut debits = Vec::new();
- println!("With DB");
+ ctx.step("With DB");
{
let metadata = rand_slice();
let amount = Amount::from_sat(42000);
@@ -647,7 +642,7 @@ fn reconnect() {
ctx.expect_credits(&credits);
};
- println!("Without DB");
+ ctx.step("Without DB");
{
ctx.stop_db();
ctx.malformed_credit(&Amount::from_sat(24000));
@@ -659,7 +654,7 @@ fn reconnect() {
ctx.expect_error();
}
- println!("Reconnect DB");
+ ctx.step("Reconnect DB");
{
ctx.resume_db();
ctx.resume_node(&[]);
@@ -676,7 +671,7 @@ fn reconnect() {
ctx.expect_credits(&credits);
}
- println!("Recover DB");
+ ctx.step("Recover DB");
{
let balance = ctx.wire_balance();
ctx.reset_db();
@@ -688,14 +683,14 @@ fn reconnect() {
}
/// Test btc-wire ability to recover from errors in correctness critical paths and prevent concurrent sending
-fn stress() {
- println!("Setup");
- let mut ctx = BtcCtx::setup("taler_btc.conf", true);
+pub fn stress(ctx: TestCtx) {
+ ctx.step("Setup");
+ let mut ctx = BtcCtx::setup(&ctx, "taler_btc.conf", true);
let mut credits = Vec::new();
let mut debits = Vec::new();
- println!("Credit");
+ ctx.step("Credit");
{
let mut balance = ctx.wire_balance();
for n in 10..30 {
@@ -711,7 +706,7 @@ fn stress() {
ctx.expect_wire_balance(balance, true);
};
- println!("Debit");
+ ctx.step("Debit");
{
let mut balance = ctx.client_balance();
for n in 10..30 {
@@ -726,7 +721,7 @@ fn stress() {
ctx.expect_client_balance(balance, true);
}
- println!("Bounce");
+ ctx.step("Bounce");
{
ctx.reset_wallet();
let mut balance = ctx.wire_balance();
@@ -738,7 +733,7 @@ fn stress() {
ctx.expect_wire_balance(balance, true);
}
- println!("Recover DB");
+ ctx.step("Recover DB");
{
let balance = ctx.wire_balance();
ctx.reset_db();
@@ -750,11 +745,11 @@ fn stress() {
}
/// Test btc-wire ability to handle conflicting outgoing transactions
-fn conflict() {
- println!("Setup");
- let mut ctx = BtcCtx::setup("taler_btc.conf", false);
+pub fn conflict(tctx: TestCtx) {
+ tctx.step("Setup");
+ let mut ctx = BtcCtx::setup(&tctx, "taler_btc.conf", false);
- println!("Conflict send");
+ ctx.step("Conflict send");
{
// Perform credit
let amount = Amount::from_sat(4200000);
@@ -785,13 +780,13 @@ fn conflict() {
retry(|| ctx.wire_balance() < wire);
}
- println!("Setup");
+ ctx.step("Setup");
drop(ctx);
- let mut ctx = BtcCtx::setup("taler_btc.conf", false);
+ let mut ctx = BtcCtx::setup(&tctx, "taler_btc.conf", false);
ctx.credit(Amount::from_sat(3000000), rand_slice());
ctx.next_block();
- println!("Conflict bounce");
+ ctx.step("Conflict bounce");
{
// Perform bounce
let wire = ctx.wire_balance();
@@ -820,11 +815,11 @@ fn conflict() {
}
/// Test btc-wire correctness when a blockchain reorganization occurs
-fn reorg() {
- println!("Setup");
- let mut ctx = BtcCtx::setup("taler_btc.conf", false);
+pub fn reorg(ctx: TestCtx) {
+ ctx.step("Setup");
+ let mut ctx = BtcCtx::setup(&ctx, "taler_btc.conf", false);
- println!("Handle reorg incoming transactions");
+ ctx.step("Handle reorg incoming transactions");
{
// Loose second bitcoin node
ctx.cluster_deco();
@@ -849,7 +844,7 @@ fn reorg() {
ctx.expect_gateway_up();
}
- println!("Handle reorg outgoing transactions");
+ ctx.step("Handle reorg outgoing transactions");
{
// Loose second bitcoin node
ctx.cluster_deco();
@@ -876,7 +871,7 @@ fn reorg() {
ctx.expect_client_balance(after, false);
}
- println!("Handle reorg bounce");
+ ctx.step("Handle reorg bounce");
{
ctx.reset_wallet();
@@ -907,11 +902,11 @@ fn reorg() {
}
/// Test btc-wire correctness when a blockchain reorganization occurs leading to past incoming transaction conflict
-fn hell() {
- fn step(name: &str, action: impl FnOnce(&mut BtcCtx)) {
- println!("Setup");
- let mut ctx = BtcCtx::setup("taler_btc.conf", false);
- println!("{}", name);
+pub fn hell(ctx: TestCtx) {
+ fn step(ctx: &TestCtx, name: &str, action: impl FnOnce(&mut BtcCtx)) {
+ ctx.step("Setup");
+ let mut ctx = BtcCtx::setup(ctx, "taler_btc.conf", false);
+ ctx.step(name);
// Loose second bitcoin node
ctx.cluster_deco();
@@ -939,14 +934,14 @@ fn hell() {
ctx.expect_gateway_down();
}
- step("Handle reorg conflicting incoming credit", |ctx| {
+ step(&ctx, "Handle reorg conflicting incoming credit", |ctx| {
let amount = Amount::from_sat(420000);
ctx.credit(amount, rand_slice());
ctx.next_conf();
ctx.expect_wire_balance(amount, true);
});
- step("Handle reorg conflicting incoming bounce", |ctx| {
+ step(&ctx, "Handle reorg conflicting incoming bounce", |ctx| {
let amount = Amount::from_sat(420000);
ctx.malformed_credit(&amount);
ctx.next_conf();
@@ -956,11 +951,11 @@ fn hell() {
}
/// Test btc-wire ability to learn and protect itself from blockchain behavior
-fn analysis() {
- println!("Setup");
- let mut ctx = BtcCtx::setup("taler_btc.conf", false);
+pub fn analysis(ctx: TestCtx) {
+ ctx.step("Setup");
+ let mut ctx = BtcCtx::setup(&ctx, "taler_btc.conf", false);
- println!("Learn from reorg");
+ ctx.step("Learn from reorg");
// Loose second bitcoin node
ctx.cluster_deco();
@@ -1000,9 +995,9 @@ fn analysis() {
}
/// Test btc-wire ability to handle stuck transaction correctly
-fn bumpfee() {
- println!("Setup");
- let mut ctx = BtcCtx::setup("taler_btc_bump.conf", false);
+pub fn bumpfee(tctx: TestCtx) {
+ tctx.step("Setup");
+ let mut ctx = BtcCtx::setup(&tctx, "taler_btc_bump.conf", false);
// Perform credits to allow wire to perform debits latter
for n in 10..13 {
@@ -1011,7 +1006,7 @@ fn bumpfee() {
}
ctx.next_conf();
- println!("Bump fee");
+ ctx.step("Bump fee");
{
// Perform debit
let mut client = ctx.client_balance();
@@ -1028,7 +1023,7 @@ fn bumpfee() {
ctx.expect_client_balance(client, true);
}
- println!("Bump fee reorg");
+ ctx.step("Bump fee reorg");
{
// Loose second bitcoin node
ctx.cluster_deco();
@@ -1048,10 +1043,9 @@ fn bumpfee() {
client += amount;
ctx.expect_client_balance(client, true);
}
-
- println!("Setup");
+ ctx.step("Setup");
drop(ctx);
- let mut ctx = BtcCtx::setup("taler_btc_bump.conf", true);
+ let mut ctx = BtcCtx::setup(&tctx, "taler_btc_bump.conf", true);
// Perform credits to allow wire to perform debits latter
for n in 10..61 {
@@ -1060,7 +1054,7 @@ fn bumpfee() {
}
ctx.next_conf();
- println!("Bump fee stress");
+ ctx.step("Bump fee stress");
{
// Loose second bitcoin node
ctx.cluster_deco();
@@ -1085,9 +1079,9 @@ fn bumpfee() {
}
/// Test btc-wire handle transaction fees exceeding limits
-fn maxfee() {
- println!("Setup");
- let mut ctx = BtcCtx::setup("taler_btc.conf", false);
+pub fn maxfee(ctx: TestCtx) {
+ ctx.step("Setup");
+ let mut ctx = BtcCtx::setup(&ctx, "taler_btc.conf", false);
// Perform credits to allow wire to perform debits latter
for n in 10..31 {
@@ -1100,7 +1094,7 @@ fn maxfee() {
let wire = ctx.wire_balance();
let mut total_amount = Amount::ZERO;
- println!("Too high fee");
+ ctx.step("Too high fee");
{
// Change fee config
ctx.restart_node(&["-maxtxfee=0.0000001", "-minrelaytxfee=0.0000001"]);
@@ -1118,7 +1112,7 @@ fn maxfee() {
ctx.expect_client_balance(client, true);
}
- println!("Good feed");
+ ctx.step("Good feed");
{
// Restore default config
ctx.restart_node(&[]);
@@ -1129,10 +1123,10 @@ fn maxfee() {
}
/// Test btc-wire ability to configure itself from bitcoin configuration
-fn config() {
+pub fn config(ctx: TestCtx) {
for n in 0..5 {
let config_name = format!("bitcoin_auth{}.conf", n);
- println!("Config {}", config_name);
- BtcCtx::config(&config_name);
+ ctx.step(format!("Config {}", config_name));
+ BtcCtx::config(&format!("config/{config_name}"), &config_name);
}
}
diff --git a/instrumentation/src/eth.rs b/instrumentation/src/eth.rs
index 265c43c..ab44106 100644
--- a/instrumentation/src/eth.rs
+++ b/instrumentation/src/eth.rs
@@ -15,7 +15,6 @@
*/
use std::{
- io::Write,
ops::{Deref, DerefMut},
path::Path,
thread::sleep,
@@ -32,7 +31,7 @@ use ethereum_types::{H160, H256, U256};
use crate::utils::{
check_incoming, check_outgoing, cmd_out, cmd_redirect, cmd_redirect_ok, print_now, retry,
- retry_opt, transfer, ChildGuard, CommonCtx,
+ retry_opt, transfer, unused_port, ChildGuard, TalerCtx, TestCtx,
};
fn wait_for_pending(rpc: &mut Rpc) {
@@ -208,43 +207,43 @@ struct EthCtx {
reserve_addr: H160,
state: WireState,
conf: u16,
- common: CommonCtx,
+ ctx: TalerCtx,
passwd: String,
}
impl Deref for EthCtx {
- type Target = CommonCtx;
+ type Target = TalerCtx;
fn deref(&self) -> &Self::Target {
- &self.common
+ &self.ctx
}
}
impl DerefMut for EthCtx {
fn deref_mut(&mut self) -> &mut Self::Target {
- &mut self.common
+ &mut self.ctx
}
}
impl EthCtx {
- pub fn setup(config: &str, stressed: bool) -> Self {
- let dirs = CommonCtx::setup_dirs(config);
+ pub fn setup(ctx: &TestCtx, config: &str, stressed: bool) -> Self {
+ let mut ctx = TalerCtx::new(ctx, "eth-wire", config, stressed);
// Init chain
let passwd = std::env::var("PASSWORD").unwrap();
- let pswd_path = dirs.dir.path().join("pswd");
+ let pswd_path = ctx.dir.path().join("pswd");
std::fs::write(&pswd_path, passwd.as_bytes()).unwrap();
for _ in ["reserve", "client"] {
cmd_redirect_ok(
"geth",
&[
"--datadir",
- dirs.wire_dir.to_str().unwrap(),
+ ctx.wire_dir.to_str().unwrap(),
"account",
"new",
"--password",
pswd_path.to_str().unwrap(),
],
- "log/node.log",
+ &ctx.log("geth"),
"create account",
)
}
@@ -252,20 +251,20 @@ impl EthCtx {
"geth",
&[
"--datadir",
- dirs.wire_dir2.to_str().unwrap(),
+ ctx.wire2_dir.to_str().unwrap(),
"account",
"new",
"--password",
pswd_path.to_str().unwrap(),
],
- "log/node2.log",
+ &ctx.log("geth2"),
"create account",
);
let list = cmd_out(
"geth",
&[
"--datadir",
- dirs.wire_dir.to_str().unwrap(),
+ ctx.wire_dir.to_str().unwrap(),
"account",
"list",
],
@@ -296,58 +295,63 @@ impl EthCtx {
}}",
addr
);
- std::fs::write(dirs.wire_dir.join("genesis.json"), genesis.as_bytes()).unwrap();
+ std::fs::write(ctx.wire_dir.join("genesis.json"), genesis.as_bytes()).unwrap();
cmd_redirect_ok(
"geth",
&[
"--datadir",
- dirs.wire_dir.to_str().unwrap(),
+ ctx.wire_dir.to_str().unwrap(),
"init",
- dirs.wire_dir.join("genesis.json").to_str().unwrap(),
+ ctx.wire_dir.join("genesis.json").to_str().unwrap(),
],
- "log/node.log",
+ &ctx.log("geth"),
"init chain",
);
cmd_redirect_ok(
"geth",
&[
"--datadir",
- dirs.wire_dir2.to_str().unwrap(),
+ ctx.wire2_dir.to_str().unwrap(),
"init",
- dirs.wire_dir.join("genesis.json").to_str().unwrap(),
+ ctx.wire_dir.join("genesis.json").to_str().unwrap(),
],
- "log/node2.log",
+ &ctx.log("geth2"),
"init chain2",
);
-
let node = cmd_redirect(
"geth",
&[
"--datadir",
- dirs.wire_dir.to_str().unwrap(),
+ ctx.wire_dir.to_str().unwrap(),
"--miner.gasprice",
"10",
+ "--authrpc.port",
+ &unused_port().to_string(),
+ "--port",
+ &unused_port().to_string(),
],
- "log/node.log",
+ &ctx.log("geth"),
);
- let mut rpc = retry_opt(|| Rpc::new(&dirs.wire_dir).ok());
+ let mut rpc = retry_opt(|| Rpc::new(&ctx.wire_dir).ok());
+ ctx.init_db();
- let common = CommonCtx::setup(dirs, "eth-wire", stressed, |dirs| {
- // Generate wallet
- let out = cmd_out(
- "eth-wire",
- &["-c", dirs.conf.to_str().unwrap(), "initwallet"],
- );
- let payto = format!("\n{}", out.lines().nth(6).unwrap());
- std::fs::OpenOptions::new()
- .append(true)
- .open(&dirs.conf)
- .unwrap()
- .write_all(payto.as_bytes())
- .unwrap();
- });
- let state = WireState::load_taler_config(Some(&common.dirs.conf));
+ // Generate wallet
+ let out = cmd_out(
+ "eth-wire",
+ &["-c", ctx.conf.to_str().unwrap(), "initwallet"],
+ );
+
+ let mut config = ini::Ini::load_from_file(&ctx.conf).unwrap();
+ config.with_section(Some("depolymerizer-ethereum")).set(
+ "PAYTO",
+ out.lines().nth(6).unwrap().split(" = ").last().unwrap(),
+ );
+ config.write_to_file(&ctx.conf).unwrap();
+
+ ctx.run();
+
+ let state = WireState::load_taler_config(Some(&ctx.conf));
let accounts = rpc.list_accounts().unwrap();
let reserve_addr = accounts[0];
let client_addr = accounts[1];
@@ -364,14 +368,14 @@ impl EthCtx {
wire_addr,
conf: state.confirmation as u16,
state,
- common,
+ ctx,
passwd,
}
}
pub fn reset_db(&mut self) {
let block = self.rpc.earliest_block().unwrap();
- let mut db = self.common.taler_conf.db_config().connect(NoTls).unwrap();
+ let mut db = self.ctx.taler_conf.db_config().connect(NoTls).unwrap();
let mut tx = db.transaction().unwrap();
// Clear transaction tables and reset state
tx.batch_execute("DELETE FROM tx_in;DELETE FROM tx_out;DELETE FROM bounce;")
@@ -414,18 +418,18 @@ impl EthCtx {
}
pub fn cluster_deco(&mut self) {
- let path = self.dirs.dir.path().join("chain");
+ let path = self.ctx.dir.path().join("chain");
let path = path.to_str().unwrap();
Self::export(&mut self.rpc, path);
cmd_redirect_ok(
"geth",
&[
"--datadir",
- self.dirs.wire_dir2.to_str().unwrap(),
+ self.ctx.wire2_dir.to_str().unwrap(),
"import",
path,
],
- "log/node2.log",
+ &self.ctx.log("geth2"),
"import chain",
);
}
@@ -435,19 +439,19 @@ impl EthCtx {
"geth",
&[
"--datadir",
- self.dirs.wire_dir2.to_str().unwrap(),
- "--authrpc.port",
- "8552",
- "--port",
- "30305",
+ self.ctx.wire2_dir.to_str().unwrap(),
"--miner.gasprice",
"10",
+ "--authrpc.port",
+ &unused_port().to_string(),
+ "--port",
+ &unused_port().to_string(),
],
- "log/node2.log",
+ &self.ctx.log("geth2"),
);
- let mut rpc = retry_opt(|| Rpc::new(&self.dirs.wire_dir2).ok());
+ let mut rpc = retry_opt(|| Rpc::new(&self.ctx.wire2_dir).ok());
Self::_mine(&mut rpc, &self.reserve_addr, length, &self.passwd);
- let path = self.dirs.dir.path().join("chain");
+ let path = self.ctx.dir.path().join("chain");
let path = path.to_str().unwrap();
Self::export(&mut rpc, path);
drop(node2);
@@ -456,11 +460,11 @@ impl EthCtx {
"geth",
&[
"--datadir",
- self.dirs.wire_dir.to_str().unwrap(),
+ self.ctx.wire_dir.to_str().unwrap(),
"import",
path,
],
- "log/node.log",
+ &self.ctx.log("geth"),
"import chain",
);
self.resume_node(&[]);
@@ -472,15 +476,22 @@ impl EthCtx {
}
pub fn resume_node(&mut self, additional_args: &[&str]) {
- let datadir = format!("-datadir={}", self.dirs.wire_dir.to_string_lossy());
+ let datadir = format!("-datadir={}", self.ctx.wire_dir.to_string_lossy());
let mut args = vec![datadir.as_str()];
args.extend_from_slice(additional_args);
self.node = cmd_redirect(
"geth",
- &["--datadir", self.dirs.wire_dir.to_str().unwrap()],
- "log/node.log",
+ &[
+ "--datadir",
+ self.ctx.wire_dir.to_str().unwrap(),
+ "--authrpc.port",
+ &unused_port().to_string(),
+ "--port",
+ &unused_port().to_string(),
+ ],
+ &self.ctx.log("geth"),
);
- self.rpc = retry_opt(|| Rpc::new(&self.dirs.wire_dir).ok());
+ self.rpc = retry_opt(|| Rpc::new(&self.ctx.wire_dir).ok());
for addr in [&self.wire_addr, &self.client_addr, &self.reserve_addr] {
self.rpc.unlock_account(addr, &self.passwd).unwrap();
}
@@ -500,7 +511,7 @@ impl EthCtx {
pub fn debit(&mut self, amount: U256, metadata: [u8; 32]) {
transfer(
- &self.common.gateway_url,
+ &self.ctx.gateway_url,
&metadata,
&self.state.base_url,
eth_payto_url(&self.client_addr),
@@ -609,7 +620,7 @@ impl EthCtx {
.iter()
.map(|(metadata, amount)| (*metadata, eth_to_taler(amount, self.state.currency)))
.collect();
- self.common.expect_credits(&txs)
+ self.ctx.expect_credits(&txs)
}
pub fn expect_debits(&self, txs: &[([u8; 32], U256)]) {
@@ -617,28 +628,16 @@ impl EthCtx {
.iter()
.map(|(metadata, amount)| (*metadata, eth_to_taler(amount, self.state.currency)))
.collect();
- self.common.expect_debits(&self.state.base_url, &txs)
+ self.ctx.expect_debits(&self.state.base_url, &txs)
}
}
-pub const TESTS: &[(fn(), &str)] = &[
- (wire, "eth_wire"),
- (lifetime, "eth_lifetime"),
- (reconnect, "eth_reconnect"),
- (stress, "eth_stress"),
- (reorg, "eth_reorg"),
- (hell, "eth_hell"),
- (analysis, "eth_analysis"),
- (bumpfee, "eth_bumpfee"),
- (maxfee, "eth_maxfee"),
-];
-
/// Test eth-wire correctly receive and send transactions on the blockchain
-fn wire() {
- println!("Setup");
- let mut ctx = EthCtx::setup("taler_eth.conf", false);
+pub fn wire(ctx: TestCtx) {
+ ctx.step("Setup");
+ let mut ctx = EthCtx::setup(&ctx, "taler_eth.conf", false);
- println!("Credit");
+ ctx.step("Credit");
{
// Send transactions
let mut balance = ctx.wire_balance();
@@ -655,7 +654,7 @@ fn wire() {
ctx.expect_wire_balance(balance, true);
};
- println!("Debit");
+ ctx.step("Debit");
{
let mut balance = ctx.client_balance();
let mut txs = Vec::new();
@@ -671,7 +670,7 @@ fn wire() {
ctx.expect_client_balance(balance, true);
}
- println!("Bounce");
+ ctx.step("Bounce");
{
// Send bad transactions
let mut balance = ctx.wire_balance();
@@ -685,10 +684,10 @@ fn wire() {
}
/// Test eth-wire and wire-gateway correctly stop when a lifetime limit is configured
-fn lifetime() {
- println!("Setup");
- let mut ctx = EthCtx::setup("taler_eth_lifetime.conf", false);
- println!("Check lifetime");
+pub fn lifetime(ctx: TestCtx) {
+ ctx.step("Setup");
+ let mut ctx = EthCtx::setup(&ctx, "taler_eth_lifetime.conf", false);
+ ctx.step("Check lifetime");
// Start up
retry(|| ctx.wire_running() && ctx.gateway_running());
// Consume lifetime
@@ -704,14 +703,14 @@ fn lifetime() {
}
/// Check the capacity of wire-gateway and eth-wire to recover from database and node loss
-fn reconnect() {
- println!("Setup");
- let mut ctx = EthCtx::setup("taler_eth.conf", false);
+pub fn reconnect(ctx: TestCtx) {
+ ctx.step("Setup");
+ let mut ctx = EthCtx::setup(&ctx, "taler_eth.conf", false);
let mut credits = Vec::new();
let mut debits = Vec::new();
- println!("With DB");
+ ctx.step("With DB");
{
let metadata = rand_slice();
let amount = ctx.amount(42000);
@@ -722,7 +721,7 @@ fn reconnect() {
ctx.expect_credits(&credits);
};
- println!("Without DB");
+ ctx.step("Without DB");
{
ctx.stop_db();
ctx.malformed_credit(ctx.amount(24000));
@@ -734,7 +733,7 @@ fn reconnect() {
ctx.expect_error();
}
- println!("Reconnect DB");
+ ctx.step("Reconnect DB");
{
ctx.resume_db();
ctx.resume_node(&[]);
@@ -751,7 +750,7 @@ fn reconnect() {
ctx.expect_credits(&credits);
}
- println!("Recover DB");
+ ctx.step("Recover DB");
{
ctx.next_block();
sleep(Duration::from_secs(3));
@@ -767,14 +766,14 @@ fn reconnect() {
}
/// Test eth-wire ability to recover from errors in correctness critical paths and prevent concurrent sending
-fn stress() {
- println!("Setup");
- let mut ctx = EthCtx::setup("taler_eth.conf", true);
+pub fn stress(ctx: TestCtx) {
+ ctx.step("Setup");
+ let mut ctx = EthCtx::setup(&ctx, "taler_eth.conf", true);
let mut credits = Vec::new();
let mut debits = Vec::new();
- println!("Credit");
+ ctx.step("Credit");
{
let mut balance = ctx.wire_balance();
for n in 10..30 {
@@ -789,7 +788,7 @@ fn stress() {
ctx.expect_wire_balance(balance, true);
};
- println!("Debit");
+ ctx.step("Debit");
{
let mut balance = ctx.client_balance();
for n in 10..30 {
@@ -804,7 +803,7 @@ fn stress() {
ctx.expect_client_balance(balance, true);
}
- println!("Bounce");
+ ctx.step("Bounce");
{
let mut balance = ctx.wire_balance();
for n in 10..30 {
@@ -815,7 +814,7 @@ fn stress() {
ctx.expect_wire_balance(balance, true);
}
- println!("Recover DB");
+ ctx.step("Recover DB");
{
let balance = ctx.wire_balance();
ctx.reset_db();
@@ -827,11 +826,11 @@ fn stress() {
}
/// Test eth-wire correctness when a blockchain reorganization occurs
-fn reorg() {
- println!("Setup");
- let mut ctx = EthCtx::setup("taler_eth.conf", false);
+pub fn reorg(ctx: TestCtx) {
+ ctx.step("Setup");
+ let mut ctx = EthCtx::setup(&ctx, "taler_eth.conf", false);
- println!("Handle reorg incoming transactions");
+ ctx.step("Handle reorg incoming transactions");
{
// Loose second node
ctx.cluster_deco();
@@ -856,7 +855,7 @@ fn reorg() {
ctx.expect_gateway_up();
}
- println!("Handle reorg outgoing transactions");
+ ctx.step("Handle reorg outgoing transactions");
{
// Loose second node
ctx.cluster_deco();
@@ -883,7 +882,7 @@ fn reorg() {
ctx.expect_client_balance(after, false);
}
- println!("Handle reorg bounce");
+ ctx.step("Handle reorg bounce");
{
// Loose second node
ctx.cluster_deco();
@@ -914,11 +913,11 @@ fn reorg() {
}
/// Test eth-wire correctness when a blockchain reorganization occurs leading to past incoming transaction conflict
-fn hell() {
- fn step(name: &str, action: impl FnOnce(&mut EthCtx)) {
- println!("Setup");
- let mut ctx = EthCtx::setup("taler_eth.conf", false);
- println!("{}", name);
+pub fn hell(ctx: TestCtx) {
+ fn step(ctx: &TestCtx, name: &str, action: impl FnOnce(&mut EthCtx)) {
+ ctx.step("Setup");
+ let mut ctx = EthCtx::setup(ctx, "taler_eth.conf", false);
+ ctx.step(name);
// Loose second node
ctx.cluster_deco();
@@ -946,14 +945,14 @@ fn hell() {
ctx.expect_gateway_down();
}
- step("Handle reorg conflicting incoming credit", |ctx| {
+ step(&ctx, "Handle reorg conflicting incoming credit", |ctx| {
let amount = ctx.amount(420000);
ctx.credit(amount, rand_slice());
ctx.next_conf();
ctx.expect_wire_balance(amount, true);
});
- step("Handle reorg conflicting incoming bounce", |ctx| {
+ step(&ctx, "Handle reorg conflicting incoming bounce", |ctx| {
let amount = ctx.amount(420000);
ctx.malformed_credit(amount);
ctx.next_conf();
@@ -962,11 +961,11 @@ fn hell() {
}
/// Test eth-wire ability to learn and protect itself from blockchain behavior
-fn analysis() {
- println!("Setup");
- let mut ctx = EthCtx::setup("taler_eth.conf", false);
+pub fn analysis(ctx: TestCtx) {
+ ctx.step("Setup");
+ let mut ctx = EthCtx::setup(&ctx, "taler_eth.conf", false);
- println!("Learn from reorg");
+ ctx.step("Learn from reorg");
// Loose second node
ctx.cluster_deco();
@@ -1005,15 +1004,15 @@ fn analysis() {
}
/// Test eth-wire ability to handle stuck transaction correctly
-fn bumpfee() {
- println!("Setup");
- let mut ctx = EthCtx::setup("taler_eth_bump.conf", false);
+pub fn bumpfee(tctx: TestCtx) {
+ tctx.step("Setup");
+ let mut ctx = EthCtx::setup(&tctx, "taler_eth_bump.conf", false);
// Perform credits to allow wire to perform debits latter
ctx.credit(ctx.amount(90000000), rand_slice());
ctx.next_conf();
- println!("Bump fee");
+ ctx.step("Bump fee");
{
// Perform debit
let mut client = ctx.client_balance();
@@ -1030,7 +1029,7 @@ fn bumpfee() {
ctx.expect_client_balance(client, true);
}
- println!("Bump fee reorg");
+ ctx.step("Bump fee reorg");
{
// Loose second node
ctx.cluster_deco();
@@ -1051,15 +1050,15 @@ fn bumpfee() {
ctx.expect_client_balance(client, true);
}
- println!("Setup");
+ ctx.step("Setup");
drop(ctx);
- let mut ctx = EthCtx::setup("taler_eth_bump.conf", true);
+ let mut ctx = EthCtx::setup(&tctx, "taler_eth_bump.conf", true);
// Perform credit to allow wire to perform debits latter
ctx.credit(ctx.amount(9000000), rand_slice());
ctx.next_conf();
- println!("Bump fee stress");
+ ctx.step("Bump fee stress");
{
// Loose second node
ctx.cluster_deco();
@@ -1084,9 +1083,9 @@ fn bumpfee() {
}
/// Test eth-wire handle transaction fees exceeding limits
-fn maxfee() {
- println!("Setup");
- let mut ctx = EthCtx::setup("taler_eth.conf", false);
+pub fn maxfee(ctx: TestCtx) {
+ ctx.step("Setup");
+ let mut ctx = EthCtx::setup(&ctx, "taler_eth.conf", false);
// Perform credit to allow wire to perform debits latter
ctx.credit(ctx.amount(9000000), rand_slice());
@@ -1096,7 +1095,7 @@ fn maxfee() {
let wire = ctx.wire_balance();
let mut total_amount = U256::zero();
- println!("Too high fee");
+ ctx.step("Too high fee");
{
// Change fee config
ctx.restart_node(&["--rpc.txfeecap", "0.00001"]);
@@ -1114,7 +1113,7 @@ fn maxfee() {
ctx.expect_client_balance(client, true);
}
- println!("Good feed");
+ ctx.step("Good feed");
{
// Restore default config
ctx.restart_node(&[""]);
diff --git a/instrumentation/src/gateway.rs b/instrumentation/src/gateway.rs
index ad58a21..3f24dab 100644
--- a/instrumentation/src/gateway.rs
+++ b/instrumentation/src/gateway.rs
@@ -28,11 +28,9 @@ use ureq::Response;
use crate::{
btc::BtcCtx,
- utils::{cmd_out, cmd_redirect_ok, gateway_error},
+ utils::{cmd_out, cmd_redirect_ok, gateway_error, TestCtx},
};
-pub const TESTS: &[(fn(), &str)] = &[(api, "api"), (auth, "auth")];
-
fn client_transfer(gateway_url: &str, payto_url: &str, amount: &str) -> String {
cmd_out(
"taler-exchange-wire-gateway-client",
@@ -51,11 +49,11 @@ fn http_code(response: Result<Response, ureq::Error>) -> u16 {
}
/// Test wire-gateway conformance to documentation and its security
-fn api() {
- println!("Setup");
- let ctx = BtcCtx::setup("taler_btc.conf", false);
+pub fn api(ctx: TestCtx) {
+ ctx.step("Setup");
+ let ctx = BtcCtx::setup(&ctx, "taler_btc.conf", false);
- println!("Gateway API");
+ ctx.step("Gateway API");
{
// Perform debits
let mut amounts = Vec::new();
@@ -106,7 +104,7 @@ fn api() {
}
};
- println!("Endpoint & Method");
+ ctx.step("Endpoint & Method");
{
// Unknown endpoint
gateway_error(&format!("{}test", ctx.gateway_url), 404);
@@ -117,7 +115,7 @@ fn api() {
let amount = &format!("{}:0.00042", ctx.taler_conf.currency.to_str());
let payto = btc_payto_url(&ctx.client_addr).to_string();
- println!("Request format");
+ ctx.step("Request format");
{
// Bad payto_url
for url in [
@@ -149,7 +147,7 @@ fn api() {
}
}
- println!("Transfer idempotence");
+ ctx.step("Transfer idempotence");
{
let mut request = TransferRequest {
request_uid: Base32::from(rand_slice()),
@@ -175,7 +173,7 @@ fn api() {
);
}
- println!("Security");
+ ctx.step("Security");
{
let big_hello: String = (0..1000).map(|_| "Hello_world").collect();
// Huge body
@@ -214,11 +212,12 @@ fn api() {
}
/// Check btc-wire and wire-gateway correctly stop when a lifetime limit is configured
-fn auth() {
- println!("Setup");
- let ctx = BtcCtx::setup("taler_btc_auth.conf", false);
+pub fn auth(ctx: TestCtx) {
+ ctx.step("Setup");
+ let ctx = BtcCtx::setup(&ctx, "taler_btc_auth.conf", false);
+
+ ctx.step("Authentication");
- println!("Authentication");
// No auth
assert_eq!(
http_code(ureq::get(&format!("{}history.outgoing", ctx.gateway_url)).call()),
@@ -230,7 +229,7 @@ fn auth() {
"taler-exchange-wire-gateway-client",
&[
"--config",
- ctx.dirs.conf.to_str().unwrap(),
+ ctx.conf.to_str().unwrap(),
"-s",
"exchange-accountcredentials-admin",
"-C",
@@ -238,7 +237,7 @@ fn auth() {
"-a",
&format!("{}:0.00042", ctx.taler_conf.currency.to_str()),
],
- "log/client.log",
+ &ctx.log("client"),
"",
);
}
diff --git a/instrumentation/src/main.rs b/instrumentation/src/main.rs
index 14a261f..c33b981 100644
--- a/instrumentation/src/main.rs
+++ b/instrumentation/src/main.rs
@@ -14,11 +14,15 @@
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-use std::{path::PathBuf, time::Instant};
+use std::{panic::catch_unwind, path::PathBuf, time::Instant};
use clap::Parser;
+use color_backtrace::termcolor::NoColor;
use common::{config::TalerConfig, currency::Currency};
use owo_colors::OwoColorize;
+use thread_local_panic_hook::set_hook;
+
+use crate::utils::TestCtx;
mod btc;
mod eth;
@@ -43,17 +47,10 @@ enum Cmd {
/// Perform offline tests on local private blockchain
Offline {
/// With tests to run
- #[clap(value_enum, global = true, default_value = "all")]
- kind: TestKind,
+ #[clap(global = true, default_value = "")]
+ filters: Vec<String>,
},
}
-#[derive(clap::ValueEnum, Clone, Debug, PartialEq, Eq)]
-enum TestKind {
- All,
- Gateway,
- Btc,
- Eth,
-}
pub fn main() {
common::log::init();
@@ -71,29 +68,90 @@ pub fn main() {
}
println!("Instrumentation test successful");
}
- Cmd::Offline { kind } => {
- let mut tests = Vec::new();
- if kind == TestKind::All || kind == TestKind::Gateway {
- tests.extend_from_slice(gateway::TESTS);
- }
- if kind == TestKind::All || kind == TestKind::Btc {
- tests.extend_from_slice(btc::TESTS);
- }
- if kind == TestKind::All || kind == TestKind::Eth {
- tests.extend_from_slice(eth::TESTS);
- }
+ Cmd::Offline { filters } => {
+ std::fs::remove_dir_all("log").ok();
+ std::fs::create_dir_all("log").unwrap();
+
let start = Instant::now();
- for (test, name) in &tests {
- let start = Instant::now();
- println!("{}", name.magenta());
- test();
- println!(
- "{} {}",
- "OK".green(),
- format_args!("{:?}", start.elapsed()).bright_black()
- );
+ let tests: Vec<_> = TESTS
+ .iter()
+ .filter(|(_, name)| {
+ filters.is_empty() || filters.iter().any(|f| name.starts_with(f))
+ })
+ .map(|(action, name)| {
+ let n = name.to_string();
+ let join = std::thread::spawn(move || {
+ let start = Instant::now();
+ let ctx = TestCtx::new(&n);
+ let tmp = ctx.clone();
+ set_hook(Box::new(move |info| {
+ let mut buf = Vec::new();
+ color_backtrace::BacktracePrinter::new()
+ .print_panic_info(info, &mut NoColor::new(&mut buf))
+ .ok();
+ let str = String::from_utf8(buf).unwrap_or_default();
+ tmp.out.lock().unwrap().push_str(&str);
+ }));
+ let tmp = ctx.clone();
+ let result = catch_unwind(|| {
+ action(tmp);
+ });
+ let lock = ctx.out.lock().unwrap();
+ (result, start.elapsed(), lock.clone())
+ });
+ (join, name)
+ })
+ .collect();
+
+ let len = tests.len();
+ for (handle, name) in tests {
+ let (result, time, out) = handle.join().unwrap();
+ match result {
+ Ok(_) => {
+ println!(
+ "{} {} {}",
+ name.magenta(),
+ "OK".green(),
+ format_args!("{}s", time.as_secs()).bright_black()
+ );
+ }
+ Err(_) => {
+ println!(
+ "{} {} {}",
+ name.magenta(),
+ "ERR".red(),
+ format_args!("{}s", time.as_secs()).bright_black()
+ );
+ println!("{}", out.bright_black());
+ }
+ }
}
- println!("{} tests in {:?}", tests.len(), start.elapsed());
+ println!("{} tests in {}s", len, start.elapsed().as_secs());
}
}
}
+
+pub const TESTS: &[(fn(TestCtx), &str)] = &[
+ (gateway::api, "gateway_api"),
+ (gateway::auth, "gateway_auth"),
+ (btc::wire, "btc_wire"),
+ (btc::lifetime, "btc_lifetime"),
+ (btc::reconnect, "btc_reconnect"),
+ (btc::stress, "btc_stress"),
+ (btc::conflict, "btc_conflict"),
+ (btc::reorg, "btc_reorg"),
+ (btc::hell, "btc_hell"),
+ (btc::analysis, "btc_analysis"),
+ (btc::bumpfee, "btc_bumpfee"),
+ (btc::maxfee, "btc_maxfee"),
+ (btc::config, "btc_config"),
+ (eth::wire, "eth_wire"),
+ (eth::lifetime, "eth_lifetime"),
+ (eth::reconnect, "eth_reconnect"),
+ (eth::stress, "eth_stress"),
+ (eth::reorg, "eth_reorg"),
+ (eth::hell, "eth_hell"),
+ (eth::analysis, "eth_analysis"),
+ (eth::bumpfee, "eth_bumpfee"),
+ (eth::maxfee, "eth_maxfee"),
+];
diff --git a/instrumentation/src/utils.rs b/instrumentation/src/utils.rs
index f35eefc..8377f5a 100644
--- a/instrumentation/src/utils.rs
+++ b/instrumentation/src/utils.rs
@@ -18,9 +18,12 @@ use std::{
fmt::Display,
fmt::Write as _,
io::Write as _,
- path::{Path, PathBuf},
+ net::{Ipv4Addr, SocketAddrV4, TcpListener, TcpStream},
+ ops::{Deref, DerefMut},
+ path::PathBuf,
process::{Child, Command, Stdio},
str::FromStr,
+ sync::{Arc, Mutex},
thread::sleep,
time::{Duration, Instant},
};
@@ -127,35 +130,6 @@ pub fn check_outgoing(base_url: &str, url: &Url, txs: &[([u8; 32], Amount)]) ->
})
})
}
-
-pub struct Dirs {
- pub dir: TempDir,
- pub wire_dir: PathBuf,
- pub wire_dir2: PathBuf,
- pub db_dir: PathBuf,
- pub conf: PathBuf,
-}
-
-impl Dirs {
- pub fn generate() -> Self {
- let dir = TempDir::new().unwrap();
- let wire_dir = dir.path().join("wire");
- let wire_dir2 = dir.path().join("wire2");
- let db_dir = dir.path().join("db");
- for dir in [&wire_dir, &wire_dir2, &db_dir] {
- std::fs::create_dir_all(dir).unwrap();
- }
- let conf = dir.path().join("taler.conf");
- Self {
- wire_dir,
- wire_dir2,
- db_dir,
- conf,
- dir,
- }
- }
-}
-
pub struct ChildGuard(pub Child);
impl Drop for ChildGuard {
@@ -211,7 +185,7 @@ pub fn retry_opt<T>(mut lambda: impl FnMut() -> Option<T>) -> T {
let start = Instant::now();
loop {
let result = lambda();
- if result.is_none() && start.elapsed() < Duration::from_secs(20) {
+ if result.is_none() && start.elapsed() < Duration::from_secs(60) {
sleep(Duration::from_millis(500));
} else {
return result.unwrap();
@@ -223,84 +197,135 @@ pub fn retry(mut lambda: impl FnMut() -> bool) {
retry_opt(|| lambda().then(|| ()))
}
-pub struct CommonCtx {
- pub dirs: Dirs,
- gateway: ChildGuard,
- pub gateway_url: String,
- pub taler_conf: TalerConfig,
- db: ChildGuard,
- wire: ChildGuard,
- _wire2: Option<ChildGuard>,
+#[derive(Clone)]
+pub struct TestCtx {
+ pub log_dir: String,
+ pub out: Arc<Mutex<String>>,
}
-impl CommonCtx {
- pub fn setup_dirs(config: &str) -> Dirs {
- // Setup logs
- {
- // Create log dir if no exist
- std::fs::create_dir_all("log").unwrap();
- // Clear all previous logs file
- for file in std::fs::read_dir("log").unwrap() {
- std::fs::write(file.unwrap().path(), "").unwrap();
- }
- }
- // Generate temporary dirs
- let dirs = Dirs::generate();
- // Prepare config
- {
- // Generate taler config from base
- let config = PathBuf::from_str("instrumentation/conf")
- .unwrap()
- .join(config);
- let mut config = std::fs::read_to_string(config).unwrap();
- write!(
- &mut config,
- "\nCONF_PATH = {}\nIPC_PATH={}",
- dirs.wire_dir.to_string_lossy(),
- dirs.wire_dir.to_string_lossy()
- )
- .unwrap();
- std::fs::write(&dirs.conf, config).unwrap();
- }
-
+impl TestCtx {
+ pub fn new(name: &str) -> Self {
+ // Create log dir
+ let log_dir = format!("log/{name}").into();
+ std::fs::remove_dir_all(&log_dir).ok();
+ std::fs::create_dir_all(&log_dir).unwrap();
// Generate password
let pwd: String = (0..30).map(|_| fastrand::alphanumeric()).collect();
std::env::set_var("PASSWORD", &pwd);
- dirs
+ Self {
+ log_dir,
+ out: Arc::new(Mutex::new(String::new())),
+ }
+ }
+
+ pub fn log(&self, name: &str) -> String {
+ format!("{}/{name}.log", self.log_dir)
}
- pub fn setup(dirs: Dirs, name: &str, stressed: bool, init_wallet: impl FnOnce(&Dirs)) -> Self {
- let taler_conf = TalerConfig::load(Some(&dirs.conf));
+ pub fn step(&self, disp: impl Display) {
+ let it: &mut String = &mut self.out.lock().unwrap();
+ writeln!(it, "{disp}").unwrap();
+ }
+}
+
+pub struct TalerCtx {
+ pub dir: TempDir,
+ pub wire_dir: PathBuf,
+ pub wire2_dir: PathBuf,
+ pub db_dir: PathBuf,
+ pub conf: PathBuf,
+ pub taler_conf: TalerConfig,
+ ctx: TestCtx,
+ db: ChildGuard,
+ wire_name: String,
+ stressed: bool,
+ gateway: Option<ChildGuard>,
+ pub gateway_url: String,
+ wire: Option<ChildGuard>,
+ wire2: Option<ChildGuard>,
+ pub gateway_port: u16,
+}
+
+impl TalerCtx {
+ pub fn new(ctx: &TestCtx, wire_name: impl Into<String>, config: &str, stressed: bool) -> Self {
+ // Create temporary dir
+ let dir = TempDir::new().unwrap();
+ let conf = dir.path().join("taler.conf");
+
+ // Create common dirs
+ let wire_dir = dir.path().join("wire");
+ let wire2_dir = dir.path().join("wire2");
+ let db_dir = dir.path().join("db");
+ for dir in [&wire_dir, &wire2_dir, &db_dir] {
+ std::fs::create_dir_all(dir).unwrap();
+ }
+
+ // Find unused port
+ let gateway_port = unused_port();
+ let db_port = unused_port();
+
+ // Generate taler config from base
+ let config = PathBuf::from_str("instrumentation/conf")
+ .unwrap()
+ .join(config);
+ let mut config = ini::Ini::load_from_file(config).unwrap();
+ let section = config
+ .sections()
+ .find(|it| {
+ it.map(|it| it.starts_with("depolymerizer-"))
+ .unwrap_or(false)
+ })
+ .unwrap_or_default()
+ .map(|it| it.to_string());
+ config
+ .with_section(Some("exchange-accountcredentials-admin"))
+ .set(
+ "WIRE_GATEWAY_URL",
+ format!("http://localhost:{gateway_port}/"),
+ );
+ config
+ .with_section(section)
+ .set("CONF_PATH", wire_dir.to_string_lossy())
+ .set("IPC_PATH", wire_dir.to_string_lossy())
+ .set(
+ "DB_URL",
+ format!("postgres://localhost:{db_port}/postgres?user=postgres&password=password"),
+ )
+ .set("PORT", gateway_port.to_string());
+
+ config.write_to_file(&conf).unwrap();
+ let taler_conf = TalerConfig::load(Some(&conf));
+
// Setup database
let db = {
// Init databases files
cmd_redirect_ok(
"initdb",
- &[dirs.db_dir.to_string_lossy().as_ref()],
- "log/postgres.log",
+ &[db_dir.to_string_lossy().as_ref()],
+ &ctx.log("postgres"),
"init_db",
);
// Generate database config
std::fs::write(
- dirs.db_dir.join("postgresql.conf"),
+ db_dir.join("postgresql.conf"),
format!(
- "port=5454\nunix_socket_directories='{}'\n",
- dirs.db_dir.to_string_lossy().as_ref()
+ "port={db_port}\nunix_socket_directories='{}'\n",
+ db_dir.to_string_lossy().as_ref()
),
)
.unwrap();
- let db = Self::_start_db(&dirs.db_dir);
+ let db = TalerCtx::start_db(&db_dir, &ctx);
retry(|| {
let mut psql = ChildGuard(
Command::new("psql")
- .args(["-h", "localhost", "-p", "5454", "postgres"])
+ .args(["-h", "localhost", "-p", &db_port.to_string(), "postgres"])
.stderr(Stdio::null())
.stdout(
std::fs::File::options()
.append(true)
.create(true)
- .open("log/postgres.log")
+ .open(&ctx.log("postgres"))
.unwrap(),
)
.stdin(Stdio::piped())
@@ -321,93 +346,116 @@ impl CommonCtx {
db
};
- // Wire
- let wire_path = format!("target/release/{}", name);
- let mut args = vec!["build", "--bin", name, "--release"];
- if stressed {
- args.extend_from_slice(&["--features", "fail"]);
+ Self {
+ ctx: ctx.clone(),
+ gateway_url: format!("http://localhost:{}/", taler_conf.port()),
+ dir,
+ wire_dir,
+ wire2_dir,
+ db_dir,
+ conf,
+ taler_conf,
+ db,
+ wire_name: wire_name.into(),
+ stressed,
+ gateway: None,
+ wire: None,
+ wire2: None,
+ gateway_port,
}
- cmd_redirect_ok("cargo", &args, "log/cargo.log", "build wire");
- cmd_redirect_ok(
- &wire_path,
- &["-c", dirs.conf.to_string_lossy().as_ref(), "initdb"],
- "log/cmd.log",
- "wire initdb",
- );
+ }
+
+ fn wire_args<'a>(&'a self, args: &[&'a str]) -> Vec<&'a str> {
+ let mut tmp = vec!["run", "--bin", &self.wire_name, "--release"];
+ if self.stressed {
+ tmp.extend_from_slice(&["--features", "fail"]);
+ }
+ tmp.push("--");
+ tmp.extend_from_slice(args);
+ return tmp;
+ }
- init_wallet(&dirs);
+ pub fn init_db(&self) {
+ // Init db
+ retry(|| {
+ cmd_redirect(
+ "cargo",
+ &self.wire_args(&["-c", self.conf.to_string_lossy().as_ref(), "initdb"]),
+ &self.log("cmd"),
+ )
+ .0
+ .wait()
+ .unwrap()
+ .success()
+ })
+ }
+ pub fn run(&mut self) {
// Start wires
- let wire = cmd_redirect(
- &wire_path,
- &["-c", dirs.conf.to_string_lossy().as_ref()],
- "log/wire.log",
- );
- let wire2 = stressed.then(|| {
+ self.wire = Some(cmd_redirect(
+ "cargo",
+ &self.wire_args(&["-c", self.conf.to_string_lossy().as_ref()]),
+ &self.log("wire"),
+ ));
+ self.wire2 = self.stressed.then(|| {
cmd_redirect(
- &wire_path,
- &["-c", dirs.conf.to_string_lossy().as_ref()],
- "log/wire2.log",
+ "cargo",
+ &self.wire_args(&["-c", self.conf.to_string_lossy().as_ref()]),
+ &self.log("wire1"),
)
});
- // Gateway
- cmd_redirect_ok(
+ // Run gateway
+ self.gateway = Some(cmd_redirect(
"cargo",
&[
- "build",
+ "run",
"--bin",
"wire-gateway",
"--release",
"--features",
"test",
+ "--",
+ "-c",
+ self.conf.to_string_lossy().as_ref(),
],
- "log/cargo.log",
- "build gateway",
- );
- let gateway = cmd_redirect(
- "target/release/wire-gateway",
- &["-c", dirs.conf.to_string_lossy().as_ref()],
- "log/gateway.log",
- );
-
- let gateway_url = format!("http://localhost:{}/", taler_conf.port());
-
- Self {
- dirs,
- gateway,
- gateway_url,
- taler_conf,
- wire,
- db,
- _wire2: wire2,
- }
+ &self.log("gateway"),
+ ));
+ retry(|| {
+ TcpStream::connect(SocketAddrV4::new(Ipv4Addr::LOCALHOST, self.gateway_port)).is_ok()
+ });
}
/* ----- Process ----- */
#[must_use]
pub fn wire_running(&mut self) -> bool {
- self.wire.0.try_wait().unwrap().is_none()
+ self.wire.as_mut().unwrap().0.try_wait().unwrap().is_none()
}
#[must_use]
pub fn gateway_running(&mut self) -> bool {
- self.gateway.0.try_wait().unwrap().is_none()
+ self.gateway
+ .as_mut()
+ .unwrap()
+ .0
+ .try_wait()
+ .unwrap()
+ .is_none()
}
/* ----- Database ----- */
- fn _start_db(path: &Path) -> ChildGuard {
+ fn start_db(db_dir: &PathBuf, ctx: &TestCtx) -> ChildGuard {
cmd_redirect(
"postgres",
- &["-D", path.to_string_lossy().as_ref()],
- "log/postgres.log",
+ &["-D", db_dir.to_string_lossy().as_ref()],
+ &ctx.log("postgres"),
)
}
pub fn resume_db(&mut self) {
- self.db = Self::_start_db(&self.dirs.db_dir);
+ self.db = Self::start_db(&self.db_dir, &self.ctx);
}
pub fn stop_db(&mut self) {
@@ -436,3 +484,25 @@ impl CommonCtx {
retry(|| check_gateway_down(&self.gateway_url));
}
}
+
+impl Deref for TalerCtx {
+ type Target = TestCtx;
+
+ fn deref(&self) -> &Self::Target {
+ &self.ctx
+ }
+}
+
+impl DerefMut for TalerCtx {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.ctx
+ }
+}
+
+pub fn unused_port() -> u16 {
+ TcpListener::bind(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0))
+ .unwrap()
+ .local_addr()
+ .unwrap()
+ .port()
+}
diff --git a/makefile b/makefile
index acacd8e..0367d14 100644
--- a/makefile
+++ b/makefile
@@ -7,7 +7,7 @@ segwit_demo:
cargo run --release --bin segwit-demo
test:
- cargo run --bin instrumentation -- offline
+ RUST_BACKTRACE=full cargo run -r --bin instrumentation -- offline
msrv:
cargo msrv --min 1.63.0 --max 1.63.0 --linear \ No newline at end of file
diff --git a/script/prepare.sh b/script/prepare.sh
index 137dff5..c2466b4 100755
--- a/script/prepare.sh
+++ b/script/prepare.sh
@@ -22,11 +22,11 @@ echo "Found version $PG_VER"
echo "Ⅱ - Install bitcoind version 0.23"
cd $DIR
-curl -L https://bitcoincore.org/bin/bitcoin-core-23.0/bitcoin-23.0-x86_64-linux-gnu.tar.gz -o btc.tar.gz
+curl -L https://bitcoincore.org/bin/bitcoin-core-23.1/bitcoin-23.1-x86_64-linux-gnu.tar.gz -o btc.tar.gz
tar xvzf btc.tar.gz
rm -rfv ~/bitcoin
mkdir -pv ~/bitcoin
-mv -v bitcoin-23.0/* ~/bitcoin
+mv -v bitcoin-23.1/* ~/bitcoin
echo "Ⅲ - Install Go Ethereum (Geth) v1.10.24"
cd $DIR