commit 80c10274b5cc5e2f16c1e92ba0de930eacbaa2fb
parent e959a7a45578cd8815461d9a250bd3c0a782cad2
Author: Antoine A <>
Date: Mon, 15 Nov 2021 12:30:28 +0100
Network agnostic
Diffstat:
3 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
@@ -6,12 +6,18 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+# Typed bitcoin json-rpc library
bitcoincore-rpc = "0.14.0"
-fastrand = "1.5.0"
+# Cli args
argh = "0.1.6"
+# Readline
rustyline = "9.0.0"
+# Bech32 encoding and decoding
bech32 = "0.8.1"
+# Secure random
rand = { version = "0.8.4", features = ["getrandom"] }
+# Fast unsecure random
+fastrand = "1.5.0"
[dev-dependencies]
# statistics-driven micro-benchmarks
diff --git a/src/lib.rs b/src/lib.rs
@@ -6,6 +6,7 @@ use rand::{rngs::OsRng, RngCore};
pub enum Network {
MainNet,
TestNet,
+
RegTest,
}
@@ -17,6 +18,14 @@ impl Network {
Network::RegTest => "bcrt",
}
}
+
+ pub fn dir(&self) -> &'static str {
+ match self {
+ Network::MainNet => "mainnet",
+ Network::TestNet => "testnet",
+ Network::RegTest => "regtest",
+ }
+ }
}
pub fn segwit_min_amount() -> Amount {
diff --git a/src/main.rs b/src/main.rs
@@ -5,13 +5,13 @@ use bitcoincore_rpc::{
jsonrpc::serde_json::Value,
Auth, Client, RpcApi,
};
-use depolymerization::{decode_segwit_msg, encode_segwit_msg, segwit_min_amount, Network};
+use depolymerization::{Network, decode_segwit_msg, encode_segwit_msg, segwit_min_amount, utils::rand_key};
const CLIENT: &str = "client";
const WIRE: &str = "wire";
const RPC_URL: &str = "http://localhost:18443";
-fn get_data_path() -> PathBuf {
+fn data_dir_path() -> PathBuf {
// https://github.com/bitcoin/bitcoin/blob/master/doc/bitcoin-conf.md#:~:text=By%20default%2C%20the%20configuration%20file,file%3E%20option%20in%20the%20bitcoin.
if cfg!(target_os = "windows") {
PathBuf::from_str(&std::env::var("APPDATA").unwrap())
@@ -30,6 +30,10 @@ fn get_data_path() -> PathBuf {
}
}
+fn network_dir_path(network: Network) -> PathBuf {
+ data_dir_path().join(network.dir())
+}
+
#[derive(argh::FromArgs)]
/// Bitcoin metadata tester
struct Args {
@@ -41,17 +45,17 @@ struct Args {
#[argh(switch, short = 'w')]
wire: bool,
}
-fn common_rpc() -> Client {
+fn common_rpc(network: Network) -> Client {
Client::new(
RPC_URL,
- Auth::CookieFile(get_data_path().join("regtest").join(".cookie")),
+ Auth::CookieFile(network_dir_path(network).join(".cookie")),
)
.expect("Failed to open common client")
}
-fn wallet_rpc(wallet: &str) -> Client {
+fn wallet_rpc(network: Network, wallet: &str) -> Client {
Client::new(
&format!("{}/wallet/{}", RPC_URL, wallet),
- Auth::CookieFile(get_data_path().join("regtest").join(".cookie")),
+ Auth::CookieFile(network_dir_path(network).join(".cookie")),
)
.expect(&format!("Failed to open wallet '{}' client", wallet))
}
@@ -81,12 +85,13 @@ fn send_many(client: &Client, recipients: Vec<(String, Amount)>) -> bitcoincore_
}
fn send_with_metadata(
+ network: Network,
rpc: &Client,
to: &Address,
amount: Amount,
metadata: &[u8],
) -> bitcoincore_rpc::Result<Txid> {
- let addresses = encode_segwit_msg(Network::RegTest, &metadata.try_into().unwrap());
+ let addresses = encode_segwit_msg(network, &metadata.try_into().unwrap());
let mut recipients = vec![(to.to_string(), amount)];
recipients.extend(
addresses
@@ -120,22 +125,23 @@ fn last_metadata(rpc: &Client) -> bitcoincore_rpc::Result<Vec<u8>> {
}
fn main() {
+ let network = Network::RegTest;
{
let existing_wallets: HashSet<String> =
- std::fs::read_dir(get_data_path().join("regtest").join("wallets"))
+ std::fs::read_dir(network_dir_path(network).join("wallets"))
.unwrap()
.filter_map(|it| it.ok())
.map(|it| it.file_name().to_string_lossy().to_string())
.collect();
- let rpc = common_rpc();
+ let rpc = common_rpc(network);
if !existing_wallets.contains(CLIENT) || !existing_wallets.contains(WIRE) {
println!("Generate new wallets");
// Create wallets
rpc.create_wallet(&WIRE, None, None, None, None).unwrap();
rpc.create_wallet(&CLIENT, None, None, None, None).unwrap();
// Add 50 BTC to client wallet
- let rpc = wallet_rpc(CLIENT);
+ let rpc = wallet_rpc(network, CLIENT);
let addr = rpc.get_new_address(None, None).unwrap();
rpc.generate_to_address(101 /* Need 100 blocks to validate */, &addr)
.unwrap();
@@ -146,8 +152,8 @@ fn main() {
}
println!("Initial state:");
- let client_rpc = wallet_rpc(CLIENT);
- let wire_rpc = wallet_rpc(WIRE);
+ let client_rpc = wallet_rpc(network, CLIENT);
+ let wire_rpc = wallet_rpc(network, WIRE);
let client_addr = client_rpc.get_new_address(None, None).unwrap();
let wire_addr = wire_rpc.get_new_address(None, None).unwrap();
println!(
@@ -173,6 +179,7 @@ fn main() {
match rl {
Ok(line) => {
send_with_metadata(
+ network,
&client_rpc,
&wire_addr,
Amount::from_sat(4200),
@@ -193,12 +200,12 @@ fn main() {
}
} else {
// Send metadata
- let metadata: Vec<u8> = repeat_with(|| fastrand::u8(..)).take(32).collect();
- send_with_metadata(&client_rpc, &wire_addr, Amount::from_sat(4200), &metadata).unwrap();
+ let key = rand_key();
+ send_with_metadata(network, &client_rpc, &wire_addr, Amount::from_sat(4200), &key).unwrap();
// Mine one block
client_rpc.generate_to_address(1, &client_addr).unwrap();
// Read metadata
let decoded = last_metadata(&wire_rpc).unwrap();
- assert_eq!(metadata, decoded);
+ assert_eq!(&key, &decoded);
}
}