add base64 to hex
This commit is contained in:
parent
28aa4e4650
commit
9d0a21ba5c
100
build.bat
100
build.bat
|
@ -1,100 +0,0 @@
|
||||||
@echo off
|
|
||||||
setlocal enabledelayedexpansion
|
|
||||||
|
|
||||||
REM GBT项目构建脚本 (Windows版本)
|
|
||||||
|
|
||||||
echo 🚀 开始构建GBT项目...
|
|
||||||
|
|
||||||
REM 检查Rust环境
|
|
||||||
where cargo >nul 2>&1
|
|
||||||
if %errorlevel% neq 0 (
|
|
||||||
echo ❌ 错误: 未找到cargo,请先安装Rust
|
|
||||||
echo 访问: https://rustup.rs/
|
|
||||||
pause
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
REM 检查Rust版本
|
|
||||||
for /f "tokens=2" %%i in ('rustc --version') do set RUST_VERSION=%%i
|
|
||||||
echo 📦 Rust版本: %RUST_VERSION%
|
|
||||||
|
|
||||||
REM 检查是否在正确的目录
|
|
||||||
if not exist "Cargo.toml" (
|
|
||||||
echo ❌ 错误: 未找到Cargo.toml,请在gbt目录下运行此脚本
|
|
||||||
pause
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
REM 清理之前的构建
|
|
||||||
echo 🧹 清理之前的构建...
|
|
||||||
cargo clean
|
|
||||||
if %errorlevel% neq 0 (
|
|
||||||
echo ❌ 清理失败
|
|
||||||
pause
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
REM 更新依赖
|
|
||||||
echo 📥 更新依赖...
|
|
||||||
cargo update
|
|
||||||
if %errorlevel% neq 0 (
|
|
||||||
echo ❌ 更新依赖失败
|
|
||||||
pause
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
REM 检查代码
|
|
||||||
echo 🔍 检查代码...
|
|
||||||
cargo check
|
|
||||||
if %errorlevel% neq 0 (
|
|
||||||
echo ❌ 代码检查失败
|
|
||||||
pause
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
REM 运行测试
|
|
||||||
echo 🧪 运行测试...
|
|
||||||
cargo test
|
|
||||||
if %errorlevel% neq 0 (
|
|
||||||
echo ❌ 测试失败
|
|
||||||
pause
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
REM 构建发布版本
|
|
||||||
echo 🔨 构建发布版本...
|
|
||||||
cargo build --release
|
|
||||||
if %errorlevel% neq 0 (
|
|
||||||
echo ❌ 构建失败
|
|
||||||
pause
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
REM 检查构建结果
|
|
||||||
if exist "target\release\gbt.exe" (
|
|
||||||
echo ✅ 构建成功!
|
|
||||||
echo 📁 可执行文件位置: target\release\gbt.exe
|
|
||||||
|
|
||||||
REM 显示文件信息
|
|
||||||
echo 📊 文件信息:
|
|
||||||
dir target\release\gbt.exe
|
|
||||||
|
|
||||||
REM 显示版本信息
|
|
||||||
echo ℹ️ 版本信息:
|
|
||||||
target\release\gbt.exe --version 2>nul || echo 无法获取版本信息
|
|
||||||
|
|
||||||
) else (
|
|
||||||
echo ❌ 构建失败!
|
|
||||||
pause
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
echo 🎉 GBT项目构建完成!
|
|
||||||
echo.
|
|
||||||
echo 📖 使用方法:
|
|
||||||
echo target\release\gbt.exe --wallet-address ^<YOUR_WALLET_ADDRESS^>
|
|
||||||
echo.
|
|
||||||
echo 📖 更多选项:
|
|
||||||
echo target\release\gbt.exe --help
|
|
||||||
echo.
|
|
||||||
pause
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
# GBT Client 日志配置文件
|
||||||
|
# 基于 log4rs 配置,用于GBT客户端的日志管理
|
||||||
|
refresh_rate: 30 seconds
|
||||||
|
|
||||||
|
appenders:
|
||||||
|
# 控制台输出
|
||||||
|
stdout:
|
||||||
|
kind: console
|
||||||
|
encoder:
|
||||||
|
pattern: "{d(%H:%M)} {h({l}):5} {m}{n}"
|
||||||
|
filters:
|
||||||
|
- kind: threshold
|
||||||
|
level: info
|
||||||
|
|
||||||
|
# GBT客户端日志文件
|
||||||
|
gbt:
|
||||||
|
kind: rolling_file
|
||||||
|
path: "{{log_dir}}/log/gbt/gbt.log"
|
||||||
|
policy:
|
||||||
|
kind: compound
|
||||||
|
trigger:
|
||||||
|
kind: size
|
||||||
|
limit: 10mb
|
||||||
|
roller:
|
||||||
|
kind: fixed_window
|
||||||
|
base: 1
|
||||||
|
count: 5
|
||||||
|
pattern: "{{log_dir}}/log/gbt/gbt.{}.log"
|
||||||
|
encoder:
|
||||||
|
pattern: "{d(%Y-%m-%d %H:%M:%S.%f)} [{t}] {l:5} {m}{n}"
|
||||||
|
|
||||||
|
# ZMQ通信日志
|
||||||
|
zmq:
|
||||||
|
kind: rolling_file
|
||||||
|
path: "{{log_dir}}/log/gbt/zmq.log"
|
||||||
|
policy:
|
||||||
|
kind: compound
|
||||||
|
trigger:
|
||||||
|
kind: size
|
||||||
|
limit: 10mb
|
||||||
|
roller:
|
||||||
|
kind: fixed_window
|
||||||
|
base: 1
|
||||||
|
count: 5
|
||||||
|
pattern: "{{log_dir}}/log/gbt/zmq.{}.log"
|
||||||
|
encoder:
|
||||||
|
pattern: "{d(%Y-%m-%d %H:%M:%S.%f)} [{t}] {l:5} {m}{n}"
|
||||||
|
|
||||||
|
# gRPC通信日志
|
||||||
|
grpc:
|
||||||
|
kind: rolling_file
|
||||||
|
path: "{{log_dir}}/log/gbt/grpc.log"
|
||||||
|
policy:
|
||||||
|
kind: compound
|
||||||
|
trigger:
|
||||||
|
kind: size
|
||||||
|
limit: 10mb
|
||||||
|
roller:
|
||||||
|
kind: fixed_window
|
||||||
|
base: 1
|
||||||
|
count: 5
|
||||||
|
pattern: "{{log_dir}}/log/gbt/grpc.{}.log"
|
||||||
|
encoder:
|
||||||
|
pattern: "{d(%Y-%m-%d %H:%M:%S.%f)} [{t}] {l:5} {m}{n}"
|
||||||
|
|
||||||
|
# 根日志配置
|
||||||
|
root:
|
||||||
|
level: warn
|
||||||
|
appenders:
|
||||||
|
- stdout
|
||||||
|
|
||||||
|
loggers:
|
||||||
|
# GBT客户端日志
|
||||||
|
gbt:
|
||||||
|
level: debug
|
||||||
|
appenders:
|
||||||
|
- gbt
|
||||||
|
- stdout
|
||||||
|
additive: false
|
||||||
|
|
||||||
|
# ZMQ相关日志
|
||||||
|
zmq:
|
||||||
|
level: debug
|
||||||
|
appenders:
|
||||||
|
- zmq
|
||||||
|
- stdout
|
||||||
|
additive: false
|
||||||
|
|
||||||
|
# gRPC相关日志
|
||||||
|
tonic:
|
||||||
|
level: debug
|
||||||
|
appenders:
|
||||||
|
- grpc
|
||||||
|
- stdout
|
||||||
|
additive: false
|
||||||
|
|
||||||
|
# 其他第三方库日志
|
||||||
|
tokio_util:
|
||||||
|
level: warn
|
||||||
|
appenders:
|
||||||
|
- gbt
|
||||||
|
additive: false
|
||||||
|
|
||||||
|
h2:
|
||||||
|
level: warn
|
||||||
|
appenders:
|
||||||
|
- grpc
|
||||||
|
additive: false
|
229
src/main.rs
229
src/main.rs
|
@ -56,15 +56,203 @@ use tari_core::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use tari_utilities::hex::Hex;
|
use tari_utilities::hex::Hex;
|
||||||
|
use hex::FromHex;
|
||||||
|
|
||||||
const LOG_TARGET: &str = "gbt::main";
|
const LOG_TARGET: &str = "gbt::main";
|
||||||
|
|
||||||
|
// 自定义的Block结构体,用于16进制序列化
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct HexBlock {
|
||||||
|
header: Option<HexBlockHeader>,
|
||||||
|
body: Option<serde_json::Value>, // 保持原有的body结构
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct HexBlockHeader {
|
||||||
|
#[serde(serialize_with = "serialize_bytes_as_hex")]
|
||||||
|
hash: Vec<u8>,
|
||||||
|
version: u32,
|
||||||
|
height: u64,
|
||||||
|
#[serde(serialize_with = "serialize_bytes_as_hex")]
|
||||||
|
prev_hash: Vec<u8>,
|
||||||
|
timestamp: u64,
|
||||||
|
#[serde(serialize_with = "serialize_bytes_as_hex")]
|
||||||
|
output_mr: Vec<u8>,
|
||||||
|
#[serde(serialize_with = "serialize_bytes_as_hex")]
|
||||||
|
block_output_mr: Vec<u8>,
|
||||||
|
#[serde(serialize_with = "serialize_bytes_as_hex")]
|
||||||
|
kernel_mr: Vec<u8>,
|
||||||
|
#[serde(serialize_with = "serialize_bytes_as_hex")]
|
||||||
|
input_mr: Vec<u8>,
|
||||||
|
#[serde(serialize_with = "serialize_bytes_as_hex")]
|
||||||
|
total_kernel_offset: Vec<u8>,
|
||||||
|
nonce: u64,
|
||||||
|
pow: HexProofOfWork,
|
||||||
|
kernel_mmr_size: u64,
|
||||||
|
output_mmr_size: u64,
|
||||||
|
#[serde(serialize_with = "serialize_bytes_as_hex")]
|
||||||
|
total_script_offset: Vec<u8>,
|
||||||
|
#[serde(serialize_with = "serialize_bytes_as_hex")]
|
||||||
|
validator_node_mr: Vec<u8>,
|
||||||
|
validator_node_size: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct HexProofOfWork {
|
||||||
|
pow_algo: u64,
|
||||||
|
#[serde(serialize_with = "serialize_bytes_as_hex")]
|
||||||
|
pow_data: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自定义序列化函数:将字节数组序列化为16进制字符串
|
||||||
|
fn serialize_bytes_as_hex<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
let hex_string = hex::encode(bytes);
|
||||||
|
serializer.serialize_str(&hex_string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将Block转换为HexBlock
|
||||||
|
fn convert_block_to_hex(block: &Block) -> Result<HexBlock> {
|
||||||
|
let header = if let Some(ref h) = block.header {
|
||||||
|
Some(HexBlockHeader {
|
||||||
|
hash: h.hash.clone(),
|
||||||
|
version: h.version,
|
||||||
|
height: h.height,
|
||||||
|
prev_hash: h.prev_hash.clone(),
|
||||||
|
timestamp: h.timestamp,
|
||||||
|
output_mr: h.output_mr.clone(),
|
||||||
|
block_output_mr: h.block_output_mr.clone(),
|
||||||
|
kernel_mr: h.kernel_mr.clone(),
|
||||||
|
input_mr: h.input_mr.clone(),
|
||||||
|
total_kernel_offset: h.total_kernel_offset.clone(),
|
||||||
|
nonce: h.nonce,
|
||||||
|
pow: HexProofOfWork {
|
||||||
|
pow_algo: h.pow.as_ref().map(|p| p.pow_algo).unwrap_or(0),
|
||||||
|
pow_data: h.pow.as_ref().map(|p| p.pow_data.clone()).unwrap_or_default(),
|
||||||
|
},
|
||||||
|
kernel_mmr_size: h.kernel_mmr_size,
|
||||||
|
output_mmr_size: h.output_mmr_size,
|
||||||
|
total_script_offset: h.total_script_offset.clone(),
|
||||||
|
validator_node_mr: h.validator_node_mr.clone(),
|
||||||
|
validator_node_size: h.validator_node_size,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
// 将body转换为JSON值,保持原有结构
|
||||||
|
let body_json = serde_json::to_value(&block.body).map_err(|e| anyhow!("Body serialization error: {}", e))?;
|
||||||
|
|
||||||
|
Ok(HexBlock {
|
||||||
|
header,
|
||||||
|
body: Some(body_json),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自定义反序列化函数:将16进制字符串反序列化为字节数组
|
||||||
|
fn deserialize_hex_to_bytes<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let hex_string = String::deserialize(deserializer)?;
|
||||||
|
hex::FromHex::from_hex(&hex_string).map_err(|e: hex::FromHexError| serde::de::Error::custom(e.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用于反序列化的结构体
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct HexBlockDeserialize {
|
||||||
|
header: Option<HexBlockHeaderDeserialize>,
|
||||||
|
body: Option<serde_json::Value>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct HexBlockHeaderDeserialize {
|
||||||
|
#[serde(deserialize_with = "deserialize_hex_to_bytes")]
|
||||||
|
hash: Vec<u8>,
|
||||||
|
version: u32,
|
||||||
|
height: u64,
|
||||||
|
#[serde(deserialize_with = "deserialize_hex_to_bytes")]
|
||||||
|
prev_hash: Vec<u8>,
|
||||||
|
timestamp: u64,
|
||||||
|
#[serde(deserialize_with = "deserialize_hex_to_bytes")]
|
||||||
|
output_mr: Vec<u8>,
|
||||||
|
#[serde(deserialize_with = "deserialize_hex_to_bytes")]
|
||||||
|
block_output_mr: Vec<u8>,
|
||||||
|
#[serde(deserialize_with = "deserialize_hex_to_bytes")]
|
||||||
|
kernel_mr: Vec<u8>,
|
||||||
|
#[serde(deserialize_with = "deserialize_hex_to_bytes")]
|
||||||
|
input_mr: Vec<u8>,
|
||||||
|
#[serde(deserialize_with = "deserialize_hex_to_bytes")]
|
||||||
|
total_kernel_offset: Vec<u8>,
|
||||||
|
nonce: u64,
|
||||||
|
pow: HexProofOfWorkDeserialize,
|
||||||
|
kernel_mmr_size: u64,
|
||||||
|
output_mmr_size: u64,
|
||||||
|
#[serde(deserialize_with = "deserialize_hex_to_bytes")]
|
||||||
|
total_script_offset: Vec<u8>,
|
||||||
|
#[serde(deserialize_with = "deserialize_hex_to_bytes")]
|
||||||
|
validator_node_mr: Vec<u8>,
|
||||||
|
validator_node_size: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct HexProofOfWorkDeserialize {
|
||||||
|
pow_algo: u64,
|
||||||
|
#[serde(deserialize_with = "deserialize_hex_to_bytes")]
|
||||||
|
pow_data: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将16进制JSON转换回Block
|
||||||
|
fn convert_hex_to_block(hex_block: &HexBlockDeserialize) -> Result<Block> {
|
||||||
|
let header = if let Some(ref h) = hex_block.header {
|
||||||
|
Some(minotari_app_grpc::tari_rpc::BlockHeader {
|
||||||
|
hash: h.hash.clone(),
|
||||||
|
version: h.version,
|
||||||
|
height: h.height,
|
||||||
|
prev_hash: h.prev_hash.clone(),
|
||||||
|
timestamp: h.timestamp,
|
||||||
|
output_mr: h.output_mr.clone(),
|
||||||
|
block_output_mr: h.block_output_mr.clone(),
|
||||||
|
kernel_mr: h.kernel_mr.clone(),
|
||||||
|
input_mr: h.input_mr.clone(),
|
||||||
|
total_kernel_offset: h.total_kernel_offset.clone(),
|
||||||
|
nonce: h.nonce,
|
||||||
|
pow: Some(minotari_app_grpc::tari_rpc::ProofOfWork {
|
||||||
|
pow_algo: h.pow.pow_algo,
|
||||||
|
pow_data: h.pow.pow_data.clone(),
|
||||||
|
}),
|
||||||
|
kernel_mmr_size: h.kernel_mmr_size,
|
||||||
|
output_mmr_size: h.output_mmr_size,
|
||||||
|
total_script_offset: h.total_script_offset.clone(),
|
||||||
|
validator_node_mr: h.validator_node_mr.clone(),
|
||||||
|
validator_node_size: h.validator_node_size,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
// 将body从JSON值转换回原始结构
|
||||||
|
let body = if let Some(ref body_json) = hex_block.body {
|
||||||
|
serde_json::from_value(body_json.clone()).map_err(|e| anyhow!("Body deserialization error: {}", e))?
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Block {
|
||||||
|
header,
|
||||||
|
body,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// ZMQ消息结构
|
// ZMQ消息结构
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct MiningTask {
|
pub struct MiningTask {
|
||||||
pub coinbase_hash: String,
|
pub coinbase_hash: String,
|
||||||
pub height: u64,
|
pub height: u64,
|
||||||
pub target: u64,
|
pub target: u64,
|
||||||
|
pub output_smt_size: u64, // 新增:output_smt_size
|
||||||
pub block_template: String, // 序列化的区块模板
|
pub block_template: String, // 序列化的区块模板
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,6 +419,13 @@ impl GbtClient {
|
||||||
.ok_or_else(|| anyhow!("No header in block template"))?
|
.ok_or_else(|| anyhow!("No header in block template"))?
|
||||||
.height;
|
.height;
|
||||||
|
|
||||||
|
// 获取output_smt_size
|
||||||
|
let output_smt_size = block_template
|
||||||
|
.header
|
||||||
|
.as_ref()
|
||||||
|
.ok_or_else(|| anyhow!("No header in block template"))?
|
||||||
|
.output_smt_size;
|
||||||
|
|
||||||
// 获取挖矿数据
|
// 获取挖矿数据
|
||||||
let miner_data = template_response
|
let miner_data = template_response
|
||||||
.miner_data
|
.miner_data
|
||||||
|
@ -280,13 +475,15 @@ impl GbtClient {
|
||||||
// 计算coinbase哈希
|
// 计算coinbase哈希
|
||||||
let coinbase_hash = coinbase_output.hash().to_hex();
|
let coinbase_hash = coinbase_output.hash().to_hex();
|
||||||
|
|
||||||
// 序列化区块模板
|
// 使用自定义的16进制序列化
|
||||||
let block_template_json = serde_json::to_string(&block).map_err(|e| anyhow!("Serialization error: {}", e))?;
|
let hex_block = convert_block_to_hex(&block)?;
|
||||||
|
let block_template_json = serde_json::to_string(&hex_block).map_err(|e| anyhow!("Serialization error: {}", e))?;
|
||||||
|
|
||||||
let mining_task = MiningTask {
|
let mining_task = MiningTask {
|
||||||
coinbase_hash,
|
coinbase_hash,
|
||||||
height,
|
height,
|
||||||
target: target_difficulty,
|
target: target_difficulty,
|
||||||
|
output_smt_size,
|
||||||
block_template: block_template_json,
|
block_template: block_template_json,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -307,7 +504,8 @@ impl GbtClient {
|
||||||
.send_multipart(&["mining_task".as_bytes(), task_json.as_bytes()], 0)
|
.send_multipart(&["mining_task".as_bytes(), task_json.as_bytes()], 0)
|
||||||
.map_err(|e| anyhow!("ZMQ send error: {}", e))?;
|
.map_err(|e| anyhow!("ZMQ send error: {}", e))?;
|
||||||
|
|
||||||
info!(target: LOG_TARGET, "Sent mining task for height {} with target {}", task.height, task.target);
|
info!(target: LOG_TARGET, "Sent mining task for height {} with target {} and output_smt_size {}",
|
||||||
|
task.height, task.target, task.output_smt_size);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,9 +541,17 @@ impl GbtClient {
|
||||||
|
|
||||||
// 提交区块到BaseNode
|
// 提交区块到BaseNode
|
||||||
pub async fn submit_block_to_base_node(&mut self, submit_request: &SubmitRequest) -> Result<SubmitBlockResponse> {
|
pub async fn submit_block_to_base_node(&mut self, submit_request: &SubmitRequest) -> Result<SubmitBlockResponse> {
|
||||||
// 反序列化区块数据
|
// 反序列化区块数据(支持16进制格式)
|
||||||
let block: Block = serde_json::from_str(&submit_request.block_data)
|
let block: Block = if submit_request.block_data.contains("\"hash\":") {
|
||||||
.map_err(|e| anyhow!("Block deserialization error: {}", e))?;
|
// 尝试解析为16进制格式
|
||||||
|
let hex_block: HexBlockDeserialize = serde_json::from_str(&submit_request.block_data)
|
||||||
|
.map_err(|e| anyhow!("Hex block deserialization error: {}", e))?;
|
||||||
|
convert_hex_to_block(&hex_block)?
|
||||||
|
} else {
|
||||||
|
// 尝试解析为原始Base64格式(向后兼容)
|
||||||
|
serde_json::from_str(&submit_request.block_data)
|
||||||
|
.map_err(|e| anyhow!("Block deserialization error: {}", e))?
|
||||||
|
};
|
||||||
|
|
||||||
info!(target: LOG_TARGET, "Submitting block to base node for height {}", submit_request.height);
|
info!(target: LOG_TARGET, "Submitting block to base node for height {}", submit_request.height);
|
||||||
|
|
||||||
|
@ -461,8 +667,17 @@ struct Args {
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
// 初始化日志
|
// 初始化日志系统
|
||||||
|
let log_config_path = PathBuf::from("log4rs_gbt.yml");
|
||||||
|
if log_config_path.exists() {
|
||||||
|
// 使用log4rs配置文件
|
||||||
|
let base_path = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
|
||||||
|
tari_common::initialize_logging(&log_config_path, &base_path, "")
|
||||||
|
.map_err(|e| anyhow!("Failed to initialize logging: {}", e))?;
|
||||||
|
} else {
|
||||||
|
// 回退到env_logger
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
}
|
||||||
|
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue