use blvm_node::node::mempool::MempoolManager;
use blvm_node::rpc::rawtx::RawTxRpc;
use blvm_node::storage::Storage;
use serde_json::json;
use std::sync::Arc;
use tempfile::TempDir;
fn create_test_rawtx_rpc() -> RawTxRpc {
let temp_dir = TempDir::new().unwrap();
let storage = Arc::new(Storage::new(temp_dir.path()).unwrap());
let mempool = Arc::new(MempoolManager::new());
RawTxRpc::with_dependencies(storage, mempool, None, None)
}
fn create_simple_tx_hex() -> String {
"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08044c86041b020602ffffffff0100f2052a010000004341041b0e8c2567c12536aa13357b79a073dc4443acf83e08e2c1252d0efcb9a4ba20b4e93f883d634390d26ed65f763194ea3273f11a6718b3615b4d94e82801b0eaac00000000".to_string()
}
#[tokio::test]
async fn test_sendrawtransaction_no_maxfeerate() {
let rawtx = create_test_rawtx_rpc();
let tx_hex = create_simple_tx_hex();
let params = json!([tx_hex]);
let result = rawtx.sendrawtransaction(¶ms).await;
if let Err(e) = result {
let error_str = e.to_string();
assert!(
!error_str.contains("fee_rate") && !error_str.contains("maxfeerate"),
"Should not fail due to fee rate when maxfeerate not specified"
);
}
}
#[tokio::test]
async fn test_sendrawtransaction_maxfeerate_pass() {
let rawtx = create_test_rawtx_rpc();
let tx_hex = create_simple_tx_hex();
let params = json!([tx_hex, 1.0]);
let result = rawtx.sendrawtransaction(¶ms).await;
if let Err(e) = result {
let error_str = e.to_string();
assert!(
!error_str.contains("fee_rate_too_high") && !error_str.contains("exceeds maximum"),
"Should not fail due to fee rate when maxfeerate is high enough"
);
}
}
#[tokio::test]
async fn test_sendrawtransaction_maxfeerate_fail() {
let rawtx = create_test_rawtx_rpc();
let tx_hex = create_simple_tx_hex();
let params = json!([tx_hex, 0.00000001]);
let result = rawtx.sendrawtransaction(¶ms).await;
assert!(
result.is_err(),
"Should fail when fee rate exceeds maxfeerate or UTXOs are absent"
);
if let Err(e) = result {
let error_str = e.to_string();
assert!(
!error_str.contains("even-length") && !error_str.contains("invalid hex"),
"Should not fail at hex format level: {}",
error_str
);
}
}
#[tokio::test]
async fn test_sendrawtransaction_allowhighfees() {
let rawtx = create_test_rawtx_rpc();
let tx_hex = create_simple_tx_hex();
let params = json!([tx_hex, 0.00000001, true]);
let result = rawtx.sendrawtransaction(¶ms).await;
if let Err(e) = result {
let error_str = e.to_string();
assert!(
!error_str.contains("fee_rate_too_high") && !error_str.contains("exceeds maximum"),
"Should not fail due to fee rate when allowhighfees=true: {}",
error_str
);
}
}
#[tokio::test]
async fn test_sendrawtransaction_parameter_parsing() {
let rawtx = create_test_rawtx_rpc();
let tx_hex = create_simple_tx_hex();
let params_str = json!([tx_hex, "0.001"]);
let result_str = rawtx.sendrawtransaction(¶ms_str).await;
assert!(
result_str.is_err() || result_str.is_ok(),
"Should parse maxfeerate as string"
);
let params_num = json!([tx_hex, 0.001]);
let result_num = rawtx.sendrawtransaction(¶ms_num).await;
assert!(
result_num.is_err() || result_num.is_ok(),
"Should parse maxfeerate as number"
);
let params_bool = json!([tx_hex, 0.001, true]);
let result_bool = rawtx.sendrawtransaction(¶ms_bool).await;
assert!(
result_bool.is_err() || result_bool.is_ok(),
"Should parse allowhighfees as boolean"
);
}
#[tokio::test]
async fn test_sendrawtransaction_error_format() {
let rawtx = create_test_rawtx_rpc();
let tx_hex = create_simple_tx_hex();
let params = json!([tx_hex, 0.00000001]);
let result = rawtx.sendrawtransaction(¶ms).await;
if let Err(e) = result {
let error_str = e.to_string();
assert!(error_str.len() > 10, "Error message should be descriptive");
}
}