setup.rs (3428B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2025 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU Affero General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 12 13 You should have received a copy of the GNU Affero General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 17 use anyhow::bail; 18 use taler_common::{config::Config, db::pool}; 19 use tokio::try_join; 20 use tracing::{info, warn}; 21 22 use crate::{ 23 DB_SCHEMA, 24 config::{WorkerCfg, parse_db_cfg}, 25 db, 26 payto::BtcWallet, 27 rpc::Rpc, 28 }; 29 30 pub async fn setup(cfg: &Config, reset: bool) -> anyhow::Result<()> { 31 info!(target: "setup", "Check bitcoind RPC connection"); 32 let worker_cfg = WorkerCfg::parse(cfg)?; 33 let mut rpc = Rpc::wallet(&worker_cfg.rpc_cfg, &worker_cfg.wallet_cfg.name).await?; 34 let info = rpc.get_blockchain_info().await?; 35 info!(target: "setup", "Running on {} chain", info.chain); 36 37 #[cfg(feature = "fail")] 38 if info.chain != "regtest" { 39 anyhow::bail!("Running with random failures is unsuitable for production"); 40 } 41 let genesis_hash = rpc.get_genesis().await.unwrap(); 42 43 info!(target: "setup", "Check wallet"); 44 rpc.load_wallet(&worker_cfg.wallet_cfg.name).await?; 45 if let Some(password) = &worker_cfg.wallet_cfg.password { 46 rpc.unlock_wallet(password).await?; 47 } 48 49 info!(target: "setup", "Check address"); 50 let wallet: BtcWallet = cfg 51 .section("depolymerizer-bitcoin") 52 .parse("bitcoin wallet address", "WALLET") 53 .require()?; 54 let addr_info = rpc.addr_info(&wallet.0).await?; 55 if !addr_info.ismine { 56 bail!( 57 "Address {} does not belong to wallet '{}'", 58 wallet.0, 59 worker_cfg.wallet_cfg.name 60 ); 61 } else if addr_info.iswatchonly { 62 bail!("Address {} is watchonly", wallet.0); 63 } else if !addr_info.solvable { 64 bail!("Address {} is not solvable", wallet.0); 65 } 66 67 info!(target: "setup", "Setup database state"); 68 let db_cfg = parse_db_cfg(cfg)?; 69 let pool = pool(db_cfg.cfg, DB_SCHEMA).await?; 70 71 // Init status to true 72 try_join!( 73 db::init_status(&pool), 74 db::init_sync_state(&pool, &genesis_hash, reset) 75 )?; 76 77 let info = rpc.get_blockchain_info().await?; 78 79 if info.verification_progress < 1.0 { 80 if info.initial_block_download { 81 warn!(target: "setup", "node is initializing behind at {:.2}% of validation, you should wait for the validation to end before starting the worker", info.verification_progress); 82 } else { 83 warn!(target: "setup", "node is lagging behind at {:.2}% of validation, you should wait for the validation to end before starting the worker", info.verification_progress); 84 } 85 } else { 86 let wallet = rpc.get_wallet_info().await?; 87 if let Some(sync) = wallet.scanning { 88 warn!(target: "setup", "worker wallet is scanning at {:.2}%", sync.progress) 89 } 90 } 91 92 info!(target: "setup", "Worker setup"); 93 Ok(()) 94 }