commit 1864e66bb6fe34de7e9777dc7c9e6cf2854c7f6b
parent 641d31b40b5e6bd9552bd34e3202303f70fdf7eb
Author: Antoine A <>
Date: Tue, 18 Jan 2022 19:19:47 +0100
Improve bootstrap cli
Diffstat:
6 files changed, 74 insertions(+), 31 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -805,9 +805,9 @@ checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
[[package]]
name = "listenfd"
-version = "0.3.5"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "809e514e2cb8a9624701346ea3e694c1766d76778e343e537d873c1c366e79a7"
+checksum = "fe05ca4da1db151e4cfed8dfd45438047aee112e43656c0963b6579e443bf22a"
dependencies = [
"libc",
"uuid",
@@ -1345,9 +1345,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.74"
+version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142"
+checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79"
dependencies = [
"itoa 1.0.1",
"ryu",
@@ -1367,12 +1367,12 @@ dependencies = [
[[package]]
name = "serde_urlencoded"
-version = "0.7.0"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
"form_urlencoded",
- "itoa 0.4.8",
+ "itoa 1.0.1",
"ryu",
"serde",
]
@@ -1413,9 +1413,9 @@ dependencies = [
[[package]]
name = "siphasher"
-version = "0.3.7"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b"
+checksum = "a86232ab60fa71287d7f2ddae4a7073f6b7aac33631c3015abb556f08c6d0a3e"
[[package]]
name = "slab"
diff --git a/btc-wire/Cargo.toml b/btc-wire/Cargo.toml
@@ -23,7 +23,7 @@ rand = { version = "0.8.4", features = ["getrandom"] }
fastrand = "1.6.0"
# Serialization library
serde = { version = "1.0.133", features = ["derive"] }
-serde_json = "1.0.74"
+serde_json = "1.0.75"
serde_repr = "0.1.7"
# Error macros
thiserror = "1.0.30"
diff --git a/btc-wire/src/bin/btc-wire-cli.rs b/btc-wire/src/bin/btc-wire-cli.rs
@@ -10,29 +10,46 @@ fn main() {
// Parse taler config
let config = taler_common::config::InitConfig::load_from_file(&args[2]);
// Connect to database
- let mut client = Client::connect(&config.db_url, NoTls).unwrap();
+ let mut db = Client::connect(&config.db_url, NoTls).expect("Failed to connect to database");
match args[1].as_str() {
"initdb" => {
// Load schema
- client
- .batch_execute(include_str!("../../../db/btc.sql"))
- .unwrap();
+ db.batch_execute(include_str!("../../../db/btc.sql"))
+ .expect("Failed to load database schema");
// Init status to true
- client
+ db
.execute(
- "INSERT INTO state (name, value) VALUES ('status', $1)",
+ "INSERT INTO state (name, value) VALUES ('status', $1) ON CONFLICT (name) DO NOTHING",
&[&[1u8].as_ref()],
)
- .unwrap();
+ .expect("Failed to initialise database state");
println!("Database initialised");
}
"initwallet" => {
// Parse bitcoin config
let btc_conf =
- BitcoinConfig::load(config.btc_data_dir.unwrap_or_else(default_data_dir)).unwrap();
+ BitcoinConfig::load(config.btc_data_dir.unwrap_or_else(default_data_dir))
+ .expect("Failed to load bitcoin configuration");
// Connect to bitcoin node
- let mut rpc = BtcRpc::common(&btc_conf).unwrap();
+ let mut rpc =
+ BtcRpc::common(&btc_conf).expect("Failed to connect to bitcoin RPC server");
+
+ // Skip previous blocks
+ let info = rpc
+ .get_blockchain_info()
+ .expect("Failed to get blockchain info");
+ let nb_row = db
+ .execute(
+ "INSERT INTO state (name, value) VALUES ('last_hash', $1) ON CONFLICT (name) DO NOTHING",
+ &[&info.best_block_hash.as_ref()],
+ )
+ .expect("Failed to update database state");
+ if nb_row > 0 {
+ println!("Skip previous block until now");
+ }
+
+ // Create wallet
let created = match rpc.create_wallet(WIRE_WALLET_NAME) {
Err(Error::RPC { code, .. }) if code == ErrorCode::RpcWalletError => false,
Err(e) => panic!("{}", e),
@@ -40,22 +57,37 @@ fn main() {
};
rpc.load_wallet(WIRE_WALLET_NAME).ok();
- // TODO idempotent (store address in database ?)
- // TODO init last_hash to skip previous database sync
- let address = BtcRpc::wallet(&btc_conf, WIRE_WALLET_NAME)
- .unwrap()
- .get_new_address()
- .unwrap();
+
+ // Load previous address
+ let prev_addr = db
+ .query_opt("SELECT value FROM state WHERE name = 'addr'", &[])
+ .expect("Failed to query database state");
+ let addr = if let Some(row) = prev_addr {
+ String::from_utf8(row.get(0)).expect("Stored address is not a valid string")
+ } else {
+ // Or generate a new one
+ let new = BtcRpc::wallet(&btc_conf, WIRE_WALLET_NAME)
+ .expect("Failed to connect to wallet bitcoin RPC server")
+ .get_new_address()
+ .expect("Failed to generate new address")
+ .to_string();
+ db.execute(
+ "INSERT INTO state (name, value) VALUES ('addr', $1)",
+ &[&new.as_bytes()],
+ )
+ .expect("Failed to update database state");
+ new
+ };
if created {
println!("Created new wallet");
} else {
println!("Found already existing wallet")
}
- println!("Address is {}", &address);
+ println!("Address is {}", &addr);
println!("Add the following line into taler.conf:");
println!("[depolymerizer-bitcoin]");
- println!("PAYTO = payto://bitcoin/{}", address);
+ println!("PAYTO = payto://bitcoin/{}", addr);
}
cmd => panic!("Unknown command {}", cmd),
}
diff --git a/btc-wire/src/rpc.rs b/btc-wire/src/rpc.rs
@@ -194,6 +194,10 @@ impl BtcRpc {
Ok(Amount::from_btc(btc).unwrap())
}
+ pub fn get_blockchain_info(&mut self) -> Result<BlockchainInfo> {
+ self.call("getblockchaininfo", &EMPTY)
+ }
+
pub fn send(&mut self, address: &Address, amount: &Amount, subtract_fee: bool) -> Result<Txid> {
let btc = amount.as_btc();
self.call("sendtoaddress", &(address, btc, (), (), subtract_fee))
@@ -313,6 +317,13 @@ pub struct Vout {
pub script_pub_key: VoutScriptPubKey,
}
+#[derive(Clone, Debug, serde::Deserialize)]
+pub struct BlockchainInfo {
+ pub blocks: u64,
+ #[serde(rename = "bestblockhash")]
+ pub best_block_hash: BlockHash,
+}
+
#[derive(Debug, serde::Deserialize)]
pub struct Vin {
pub sequence: u32,
diff --git a/taler-common/Cargo.toml b/taler-common/Cargo.toml
@@ -11,7 +11,7 @@ serde = { version = "1.0.133", features = ["derive"] }
# Serialization helper
serde_with = "1.11.0"
# JSON serialization
-serde_json = "1.0.74"
+serde_json = "1.0.75"
# Url format
url = { version = "2.2.2", features = ["serde"] }
# Crockford’s base32
diff --git a/wire-gateway/Cargo.toml b/wire-gateway/Cargo.toml
@@ -19,9 +19,9 @@ serde = { version = "1.0.133", features = ["derive"] }
# Serialization helper
serde_with = "1.11.0"
# JSON serialization
-serde_json = "1.0.74"
+serde_json = "1.0.75"
# Url query serialization
-serde_urlencoded = "0.7.0"
+serde_urlencoded = "0.7.1"
# Error macros
thiserror = "1.0.30"
# Deflate compression
@@ -33,7 +33,7 @@ tokio-postgres = { version = "0.7.5" }
postgres = { version = "0.19.2" }
deadpool-postgres = "0.10.1"
# Socket activation
-listenfd = "0.3.5"
+listenfd = "0.4.0"
# Taler libs
taler-common = { path = "../taler-common" }