diff --git a/.gitignore b/.gitignore index a9d37c5..110d010 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ target Cargo.lock +.vscode \ No newline at end of file diff --git a/client/Cargo.toml b/client/Cargo.toml index 4cf66a2..987de94 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -24,7 +24,6 @@ defichain-rpc-json = { version = "0.18.0", path = "../json" } log = "0.4.5" jsonrpc-async = "2.0.2" async-trait = "0.1.42" - # Used for deserialization of JSON. serde = "1" serde_json = "1" diff --git a/client/src/client.rs b/client/src/client.rs index 7a75b1c..6c854ef 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -15,21 +15,20 @@ use std::iter::FromIterator; use std::path::PathBuf; use std::{fmt, result}; -use crate::{bitcoin, deserialize_hex}; -use async_trait::async_trait; -use bitcoin::hex::DisplayHex; -use json::bitcoin::Txid; -use jsonrpc_async; -use serde::{self, Serialize}; -use serde_json::{self, Map}; - use crate::bitcoin::address::{NetworkChecked, NetworkUnchecked}; use crate::bitcoin::hashes::hex::FromHex; use crate::bitcoin::secp256k1::ecdsa::Signature; use crate::bitcoin::{ Address, Amount, Block, OutPoint, PrivateKey, PublicKey, Script, Transaction, }; +use crate::{bitcoin, deserialize_hex}; +use async_trait::async_trait; +use bitcoin::hex::DisplayHex; +use json::bitcoin::Txid; +use jsonrpc_async; use log::Level::{Debug, Trace, Warn}; +use serde::{self, Serialize}; +use serde_json::{self, json, Map}; use crate::error::*; use crate::json; @@ -889,10 +888,12 @@ pub trait RpcApi: Sized { async fn test_mempool_accept( &self, rawtxs: &[R], + max_fee_rate: Option, ) -> Result> { let hexes: Vec = rawtxs.to_vec().into_iter().map(|r| r.raw_hex().into()).collect(); - self.call("testmempoolaccept", &[hexes.into()]).await + let mut args = [into_json(hexes)?, opt_into_json(max_fee_rate)?]; + self.call("testmempoolaccept", &args).await } async fn stop(&self) -> Result { @@ -1115,8 +1116,13 @@ pub trait RpcApi: Sized { self.call("ping", &[]).await } - async fn send_raw_transaction(&self, tx: R) -> Result { - self.call("sendrawtransaction", &[tx.raw_hex().into()]).await + async fn send_raw_transaction( + &self, + tx: R, + max_fee_rate: Option, + ) -> Result { + let mut args = [into_json(tx.raw_hex())?, opt_into_json(max_fee_rate)?]; + self.call("sendrawtransaction", &args).await } async fn estimate_smart_fee( @@ -1409,17 +1415,22 @@ mod tests { use super::*; use crate::bitcoin; use serde_json; - #[tokio::test] async fn test_raw_tx() { use crate::bitcoin::consensus::encode; let client = Client::new("http://localhost/".into(), Auth::None).await.unwrap(); let tx: bitcoin::Transaction = encode::deserialize(&Vec::::from_hex("0200000001586bd02815cf5faabfec986a4e50d25dbee089bd2758621e61c5fab06c334af0000000006b483045022100e85425f6d7c589972ee061413bcf08dc8c8e589ce37b217535a42af924f0e4d602205c9ba9cb14ef15513c9d946fa1c4b797883e748e8c32171bdf6166583946e35c012103dae30a4d7870cd87b45dd53e6012f71318fdd059c1c2623b8cc73f8af287bb2dfeffffff021dc4260c010000001976a914f602e88b2b5901d8aab15ebe4a97cf92ec6e03b388ac00e1f505000000001976a914687ffeffe8cf4e4c038da46a9b1d37db385a472d88acfd211500").unwrap()).unwrap(); - - assert!(client.send_raw_transaction(&tx).await.is_err()); - assert!(client.send_raw_transaction(&encode::serialize(&tx)).await.is_err()); - assert!(client.send_raw_transaction("deadbeef").await.is_err()); - assert!(client.send_raw_transaction("deadbeef".to_owned()).await.is_err()); + let FEE: Amount = Amount::from_btc(0.001).unwrap(); + assert!(client.send_raw_transaction(&tx, Some(FEE.to_sat())).await.is_err()); + assert!(client + .send_raw_transaction(&encode::serialize(&tx), Some(FEE.to_sat())) + .await + .is_err()); + assert!(client.send_raw_transaction("deadbeef", Some(FEE.to_sat())).await.is_err()); + assert!(client + .send_raw_transaction("deadbeef".to_owned(), Some(FEE.to_sat())) + .await + .is_err()); } async fn test_handle_defaults_inner() -> Result<()> { diff --git a/client/src/traits/rawtx.rs b/client/src/traits/rawtx.rs index 2713d8a..f31b162 100644 --- a/client/src/traits/rawtx.rs +++ b/client/src/traits/rawtx.rs @@ -2,7 +2,7 @@ pub trait RawTxRPC: RpcApi { fn create_raw_transaction(&self, outputs: CreateRawTxOut) -> Result; fn decode_raw_transaction(&self, hexstring: String, iswitness: bool) -> Result; fn get_raw_transaction(&self, txid: bitcoin::Txid) -> Result; - fn send_raw_transaction(&self, signed_tx: String) -> Result; + fn send_raw_transaction(&self, signed_tx: String,max_fee_rate:Option) -> Result; fn sign_raw_transaction_with_key(&self, raw_tx: String) -> Result; - fn test_mempool_accept(&self, signed_tx: String) -> Result; + fn test_mempool_accept(&self, signed_tx: String,max_fee_rate:Option) -> Result; } diff --git a/integration_test/src/main.rs b/integration_test/src/main.rs index 9768a32..46c0121 100644 --- a/integration_test/src/main.rs +++ b/integration_test/src/main.rs @@ -16,13 +16,9 @@ extern crate lazy_static; use std::collections::HashMap; use std::str::FromStr; +use crate::json::BlockStatsFields as BsFields; use bitcoin::absolute::LockTime; use bitcoin::address::{NetworkChecked, NetworkUnchecked}; -use defichain_rpc::json; -use defichain_rpc::jsonrpc_async::error::Error as JsonRpcError; -use defichain_rpc::{Auth, Client, Error, RpcApi}; - -use crate::json::BlockStatsFields as BsFields; use bitcoin::consensus::encode::{deserialize, serialize_hex}; use bitcoin::hashes::hex::FromHex; use bitcoin::hashes::Hash; @@ -34,6 +30,9 @@ use bitcoin::{ use defichain_rpc::defichain_rpc_json::{ GetBlockTemplateModes, GetBlockTemplateRules, ScanTxOutRequest, }; +use defichain_rpc::json; +use defichain_rpc::jsonrpc_async::error::Error as JsonRpcError; +use defichain_rpc::{Auth, Client, Error, RpcApi}; lazy_static! { static ref SECP: secp256k1::Secp256k1 = secp256k1::Secp256k1::new(); @@ -134,7 +133,6 @@ async fn new_wallet_client(wallet_name: &str) -> Client { #[tokio::main] async fn main() { log::set_logger(&LOGGER).map(|()| log::set_max_level(log::LevelFilter::max())).unwrap(); - let cl = new_wallet_client("testwallet").await; test_get_network_info(&cl).await; @@ -673,7 +671,8 @@ async fn test_sign_raw_transaction_with_send_raw_transaction(cl: &Client) { }; let res = cl.sign_raw_transaction_with_wallet(&tx, Some(&[input]), None).await.unwrap(); assert!(res.complete); - let txid = cl.send_raw_transaction(&res.transaction().unwrap()).await.unwrap(); + let txid = + cl.send_raw_transaction(&res.transaction().unwrap(), Some(FEE.to_sat())).await.unwrap(); let tx = Transaction { version: transaction::Version::ONE, @@ -703,7 +702,7 @@ async fn test_sign_raw_transaction_with_send_raw_transaction(cl: &Client) { .await .unwrap(); assert!(res.complete); - let _ = cl.send_raw_transaction(&res.transaction().unwrap()).await.unwrap(); + let _ = cl.send_raw_transaction(&res.transaction().unwrap(), Some(FEE.to_sat())).await.unwrap(); } async fn test_invalidate_block_reconsider_block(cl: &Client) { @@ -835,12 +834,12 @@ async fn test_test_mempool_accept(cl: &Client) { .create_raw_transaction(&[input.clone()], &output, Some(500_000), Some(false)) .await .unwrap(); - let res = cl.test_mempool_accept(&[&tx]).await.unwrap(); + let res = cl.test_mempool_accept(&[&tx], Some(FEE.to_sat())).await.unwrap(); assert!(!res[0].allowed); assert!(res[0].reject_reason.is_some()); let signed = cl.sign_raw_transaction_with_wallet(&tx, None, None).await.unwrap().transaction().unwrap(); - let res = cl.test_mempool_accept(&[&signed]).await.unwrap(); + let res = cl.test_mempool_accept(&[&signed], Some(FEE.to_sat())).await.unwrap(); assert!(res[0].allowed, "not allowed: {:?}", res[0].reject_reason); }