Compare commits
No commits in common. "3018e64fb731aeb9f3600bc81f8e2c9721ceeacf" and "fe1c4ee2c8d9eb6a6a3e845d7597afd62170c712" have entirely different histories.
3018e64fb7
...
fe1c4ee2c8
1059
Cargo.lock
generated
1059
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -5,7 +5,6 @@ edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[dependencies]
|
||||
base64 = "0.22.1"
|
||||
bs58 = "0.4.0"
|
||||
bytes = "1.2"
|
||||
bitcoin = { version = "0.32.5" }
|
||||
@ -21,13 +20,11 @@ hyper = { version = "1.3.1", features = ["http1","server"] }
|
||||
hyper-util = { version = "0.1.3", features = ["tokio"] }
|
||||
http-body-util = "0.1"
|
||||
log = "0.4.21"
|
||||
openssl = { version = "0.10.74", features = ["vendored"] }
|
||||
sha2 = "0.10.8"
|
||||
serde = { version = "1.0.152", features = ["derive"] }
|
||||
serde_json = "1.0.116"
|
||||
sqlite = "0.34.0"
|
||||
regex = "1.10.4"
|
||||
reqwest = { version = "0.12.24", features = ["json","socks"] }
|
||||
tokio = { version = "1", features = ["rt", "net","macros","rt-multi-thread"] } # Keep only necessary runtime components
|
||||
zmq = "0.10.0"
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@ use bitcoincore_rpc_json::GetBlockchainInfoResult;
|
||||
use sqlite::{Value};
|
||||
use serde::Serialize;
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
use std::env;
|
||||
use log::{info,warn,error,trace,debug};
|
||||
use zmq::{Context, Socket};
|
||||
@ -20,18 +19,8 @@ use std::collections::HashMap;
|
||||
use hex;
|
||||
use std::error::Error as StdError;
|
||||
|
||||
use reqwest::Client as rClient;
|
||||
use openssl::hash::MessageDigest;
|
||||
use openssl::pkey::{PKey};
|
||||
use openssl::sign::Signer;
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
use std::fs;
|
||||
|
||||
|
||||
|
||||
|
||||
const LOCKTIME_THRESHOLD:i64 = 5000000;
|
||||
const VERSION:&str = "0.0.1";
|
||||
|
||||
#[derive(Debug, Clone,Serialize, Deserialize)]
|
||||
struct MyConfig {
|
||||
zmq_listener: String,
|
||||
@ -42,10 +31,8 @@ struct MyConfig {
|
||||
testnet: NetworkParams,
|
||||
signet: NetworkParams,
|
||||
mainnet: NetworkParams,
|
||||
send_stats: bool,
|
||||
url: String,
|
||||
secret_code: String,
|
||||
ssl_key_path: String
|
||||
|
||||
|
||||
}
|
||||
|
||||
impl Default for MyConfig {
|
||||
@ -59,10 +46,6 @@ impl Default for MyConfig {
|
||||
testnet: get_network_params_default(Network::Testnet),
|
||||
signet: get_network_params_default(Network::Signet),
|
||||
mainnet: get_network_params_default(Network::Bitcoin),
|
||||
send_stats: false,
|
||||
url: "http://localhost/".to_string(),
|
||||
secret_code: "xxx".to_string(),
|
||||
ssl_key_path: "privkey.pem".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -164,9 +147,7 @@ fn get_client_from_cookie(url: &String,network: &NetworkParams)->Result<(Client,
|
||||
match Client::new(&url[..], Auth::CookieFile(cookie.into())) {
|
||||
Ok(client) => {
|
||||
match client.get_blockchain_info(){
|
||||
Ok(bcinfo) => {
|
||||
Ok((client,bcinfo))
|
||||
},
|
||||
Ok(bcinfo) => Ok((client,bcinfo)),
|
||||
Err(err) => {
|
||||
Err(err.into())
|
||||
}
|
||||
@ -193,7 +174,7 @@ fn get_client(network: &NetworkParams) -> Result<(Client,GetBlockchainInfoResult
|
||||
}
|
||||
}
|
||||
}
|
||||
async fn main_result(cfg: &MyConfig, network_params: &NetworkParams) -> Result<(), Error> {
|
||||
fn main_result(cfg: &MyConfig, network_params: &NetworkParams) -> Result<(), Error> {
|
||||
|
||||
|
||||
/*let url = args.next().expect("Usage: <rpc_url> <username> <password>");
|
||||
@ -220,7 +201,6 @@ async fn main_result(cfg: &MyConfig, network_params: &NetworkParams) -> Result<(
|
||||
//}
|
||||
//let average_time = time_sum/11;
|
||||
info!("median time: {}",bcinfo.median_time);
|
||||
//info!("height time: {}",bcinfo.median_time);
|
||||
info!("blocks: {}",bcinfo.blocks);
|
||||
debug!("best block hash: {}",bcinfo.best_block_hash);
|
||||
|
||||
@ -296,60 +276,13 @@ async fn main_result(cfg: &MyConfig, network_params: &NetworkParams) -> Result<(
|
||||
let _ = db.execute(&sql);
|
||||
}
|
||||
}
|
||||
let _ = send_stats_report(cfg, bcinfo).await;
|
||||
}
|
||||
Err(erx)=>{
|
||||
panic!("impossible to get client {}",erx)
|
||||
Err(_)=>{
|
||||
panic!("impossible to get client")
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
async fn send_stats_report(cfg: &MyConfig, bcinfo: GetBlockchainInfoResult) -> Result<(),reqwest::Error>{
|
||||
if cfg.send_stats {
|
||||
debug!("sending report to welist");
|
||||
let welist_url=env::var("WELIST_SERVER_URL").unwrap_or("https://welist.bitcoin-after.life".to_string());
|
||||
|
||||
let client = rClient::new();
|
||||
let url = format!("{}/ping",welist_url);
|
||||
let chain=bcinfo.chain.to_string().to_lowercase();
|
||||
let message = format!("{0}{1}{2}{3}{4}",cfg.url,chain,bcinfo.blocks,bcinfo.median_time,bcinfo.best_block_hash);
|
||||
let sign = sign_message(cfg.ssl_key_path.as_str(),&message.as_str());
|
||||
let response = client.post(url)
|
||||
.header("User-Agent", format!("bal-pusher/{}",VERSION))
|
||||
.json(&json!(
|
||||
{
|
||||
"url": cfg.url,
|
||||
"chain": chain,
|
||||
"height": bcinfo.blocks,
|
||||
"median_time": bcinfo.median_time,
|
||||
"last_block_hash": bcinfo.best_block_hash,
|
||||
"signature": sign,
|
||||
}))
|
||||
.send().await?;
|
||||
let body = &(response.text().await?);
|
||||
println!("Body: {}", body);
|
||||
}else {
|
||||
debug!("Not sending stats");
|
||||
}
|
||||
Ok(())
|
||||
|
||||
|
||||
}
|
||||
fn sign_message(private_key_path: &str, message: &str) -> String {
|
||||
let key_data = fs::read(private_key_path).unwrap();
|
||||
|
||||
let private_key = PKey::private_key_from_pem(&key_data).unwrap();
|
||||
|
||||
let mut signer = Signer::new(MessageDigest::sha256(), &private_key).unwrap();
|
||||
|
||||
signer.update(message.as_bytes()).unwrap();
|
||||
|
||||
let firma = signer.sign_to_vec().unwrap();
|
||||
|
||||
let firma_b64 = general_purpose::STANDARD.encode(&firma);
|
||||
|
||||
firma_b64
|
||||
}
|
||||
|
||||
fn parse_env(cfg: &mut MyConfig){
|
||||
match env::var("BAL_PUSHER_ZMQ_LISTENER") {
|
||||
@ -372,27 +305,6 @@ fn parse_env(cfg: &mut MyConfig){
|
||||
cfg.bitcoin_dir = value;},
|
||||
Err(_) => {},
|
||||
}
|
||||
match env::var("BAL_PUSHER_SEND_STATS") {
|
||||
Ok(value) => {
|
||||
cfg.send_stats = value.parse::<bool>().unwrap();
|
||||
},
|
||||
Err(_) => {},
|
||||
}
|
||||
match env::var("BAL_SERVER_URL") {
|
||||
Ok(value) => {
|
||||
cfg.url= value;},
|
||||
Err(_) => {},
|
||||
}
|
||||
match env::var("WELIST_SECRET_CODE") {
|
||||
Ok(value) => {
|
||||
cfg.secret_code = value;},
|
||||
Err(_) => {},
|
||||
}
|
||||
match env::var("SSL_KEY_PATH") {
|
||||
Ok(value) => {
|
||||
cfg.ssl_key_path = value;},
|
||||
Err(_) => {},
|
||||
}
|
||||
cfg.regtest = parse_env_netconfig(cfg,"regtest");
|
||||
cfg.signet = parse_env_netconfig(cfg,"signet");
|
||||
cfg.testnet = parse_env_netconfig(cfg,"testnet");
|
||||
@ -449,8 +361,8 @@ fn get_default_config()-> MyConfig {
|
||||
info!("Default configuration file path is: {:#?}", file);
|
||||
confy::load("bal-pusher",None).expect("cant_load")
|
||||
}
|
||||
#[tokio::main]
|
||||
async fn main()-> std::io::Result<()>{
|
||||
|
||||
fn main(){
|
||||
env_logger::init();
|
||||
let mut cfg: MyConfig = match env::var("BAL_PUSHER_CONFIG_FILE") {
|
||||
Ok(value) => {
|
||||
@ -499,7 +411,7 @@ async fn main()-> std::io::Result<()>{
|
||||
|
||||
socket.set_subscribe(b"").unwrap();
|
||||
|
||||
let _ = main_result(&cfg,network_params).await;
|
||||
let _ = main_result(&cfg,network_params);
|
||||
info!("waiting new blocks..");
|
||||
let mut last_seq:Vec<u8>=[0;4].to_vec();
|
||||
loop {
|
||||
@ -522,7 +434,7 @@ async fn main()-> std::io::Result<()>{
|
||||
if topic == b"hashblock" {
|
||||
info!("NEW BLOCK: {}", hex::encode(&body));
|
||||
//let cfg = cfg.clone();
|
||||
let _ = main_result(&cfg,network_params).await;
|
||||
let _ = main_result(&cfg,network_params);
|
||||
}
|
||||
thread::sleep(Duration::from_millis(100)); // Sleep for 100ms
|
||||
}
|
||||
|
||||
@ -117,13 +117,13 @@ async fn echo_info(
|
||||
info!("echo info!!!{}",param);
|
||||
let netconfig=MyConfig::get_net_config(cfg,param);
|
||||
if !netconfig.enabled {
|
||||
debug!("network disabled {}",param);
|
||||
trace!("network disabled");
|
||||
return Ok(Response::new(full("network disabled")));
|
||||
}
|
||||
let address = match netconfig.xpub{
|
||||
false => {
|
||||
let address = netconfig.address.to_string();
|
||||
trace!("is address: {}",&address);
|
||||
info!("is address: {}",&address);
|
||||
address
|
||||
},
|
||||
true => {
|
||||
@ -134,8 +134,8 @@ async fn echo_info(
|
||||
let next = get_next_address_index(&db,&netconfig.name,&netconfig.address);
|
||||
let address = new_address_from_xpub(&netconfig.address,next.1,netconfig.network).unwrap();
|
||||
save_new_address(&db,next.0,&address.0,&address.1,&remote_addr);
|
||||
debug!("save new address {} {}",address.0,address.1);
|
||||
trace!("next {} {}",next.0,next.1);
|
||||
debug!("address {} {}",address.0,address.1);
|
||||
debug!("next {} {}",next.0,next.1);
|
||||
address.0
|
||||
}
|
||||
}
|
||||
@ -151,10 +151,7 @@ async fn echo_info(
|
||||
};
|
||||
trace!("address: {:#?}",info);
|
||||
match serde_json::to_string(&info){
|
||||
Ok(json_data) => {
|
||||
debug!("echo info reply: {}", json_data);
|
||||
return Ok(Response::new(full(json_data)));
|
||||
},
|
||||
Ok(json_data) => Ok(Response::new(full(json_data))),
|
||||
Err(err) => Ok(Response::new(full(format!("error:{}",err))))
|
||||
}
|
||||
|
||||
@ -461,30 +458,23 @@ fn full<T: Into<Bytes>>(chunk: T) -> BoxBody<Bytes, hyper::Error> {
|
||||
.boxed()
|
||||
}
|
||||
fn parse_env(cfg: &Arc<Mutex<MyConfig>>){
|
||||
for (key, value) in std::env::vars() {
|
||||
debug!("ENVIRONMENT {key}: {value}");
|
||||
}
|
||||
let mut cfg_lock = cfg.lock().unwrap();
|
||||
if let Ok(value) = env::var("BAL_SERVER_DB_FILE") {
|
||||
debug!("BAL_SERVER_DB_FILE: {}",value);
|
||||
cfg_lock.db_file = value;
|
||||
}
|
||||
if let Ok(value) = env::var("BAL_SERVER_BIND_ADDRESS") {
|
||||
debug!("BAL_SERVER_BIND_ADDRESS: {}",value);
|
||||
cfg_lock.bind_address= value;
|
||||
}
|
||||
if let Ok(value) = env::var("BAL_SERVER_BIND_PORT") {
|
||||
debug!("BAL_SERVER_BIND_PORT: {}",value);
|
||||
if let Ok(v) = value.parse::<u16>(){
|
||||
cfg_lock.bind_port = v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if let Ok(value) = env::var("BAL_SERVER_INFO"){
|
||||
debug!("BAL_SERVER_INFO: {}",value);
|
||||
cfg_lock.info = value;
|
||||
}
|
||||
|
||||
cfg_lock = parse_env_netconfig(cfg_lock,"regtest");
|
||||
cfg_lock = parse_env_netconfig(cfg_lock,"signet");
|
||||
cfg_lock = parse_env_netconfig(cfg_lock,"testnet");
|
||||
@ -499,7 +489,6 @@ fn parse_env_netconfig<'a>(mut cfg_lock: MutexGuard<'a, MyConfig>, chain: &'a st
|
||||
&_ => &mut cfg_lock.mainnet,
|
||||
};
|
||||
if let Ok(value) = env::var(format!("BAL_SERVER_{}_ADDRESS",chain.to_uppercase())) {
|
||||
debug!("BAL_SERVER_{}_ADDRESS: {}",chain.to_uppercase(),value);
|
||||
cfg.address = value;
|
||||
if cfg.address.len() > 5 {
|
||||
if cfg.address[1..4] == *"pub" {
|
||||
@ -511,7 +500,6 @@ fn parse_env_netconfig<'a>(mut cfg_lock: MutexGuard<'a, MyConfig>, chain: &'a st
|
||||
}
|
||||
|
||||
if let Ok(value) = env::var(format!("BAL_SERVER_{}_FIXED_FEE",chain.to_uppercase())) {
|
||||
debug!("BAL_SERVER_{}_FIXED_FEE: {}",chain.to_uppercase(),value);
|
||||
if let Ok(v) = value.parse::<u64>(){
|
||||
cfg.fixed_fee = v;
|
||||
}
|
||||
|
||||
13
src/db.rs
13
src/db.rs
@ -131,17 +131,4 @@ pub fn execute_insert(db: &Connection,
|
||||
Ok(())
|
||||
|
||||
}
|
||||
pub fn get_total_transaction_number(db: Connection, network: &String) -> Result<i64,Error> {
|
||||
let mut stmt = db.prepare("SELECT COUNT(*) as total_number FROM tbl_tx where network = ?;").unwrap();
|
||||
stmt.bind((1,Value::String(network.to_string()))).unwrap();
|
||||
match stmt.next(){
|
||||
Ok(State::Row)=>{
|
||||
Ok(stmt.read::<i64,_>("total_number").unwrap())
|
||||
},
|
||||
Ok(sqlite::State::Done) => todo!(),
|
||||
Err(err)=>Err(err)
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user