mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-07-01 10:06:54 -04:00
WIP - Refactor monerod to use @thomaseizinger rust-jsonrpc-client
This commit is contained in:
parent
0ce3c54f13
commit
ffb9d0e000
9 changed files with 76 additions and 101 deletions
24
Cargo.lock
generated
24
Cargo.lock
generated
|
@ -1550,6 +1550,28 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonrpc_client"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/thomaseizinger/rust-jsonrpc-client?rev=c7010817e0f86ab24b3dc10d6bb0463faa0aace4#c7010817e0f86ab24b3dc10d6bb0463faa0aace4"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"jsonrpc_client_macro",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonrpc_client_macro"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/thomaseizinger/rust-jsonrpc-client?rev=c7010817e0f86ab24b3dc10d6bb0463faa0aace4#c7010817e0f86ab24b3dc10d6bb0463faa0aace4"
|
||||
dependencies = [
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "keccak"
|
||||
version = "0.1.0"
|
||||
|
@ -2000,8 +2022,10 @@ name = "monero-harness"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"digest_auth",
|
||||
"futures",
|
||||
"jsonrpc_client",
|
||||
"port_check",
|
||||
"rand 0.7.3",
|
||||
"reqwest",
|
||||
|
|
|
@ -5,9 +5,11 @@ authors = ["CoBloX Team <team@coblox.tech>"]
|
|||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1"
|
||||
anyhow = "1"
|
||||
digest_auth = "0.2.3"
|
||||
futures = "0.3"
|
||||
jsonrpc_client = { git = "https://github.com/thomaseizinger/rust-jsonrpc-client", rev = "c7010817e0f86ab24b3dc10d6bb0463faa0aace4", features = ["reqwest"] }
|
||||
port_check = "0.1"
|
||||
rand = "0.7"
|
||||
reqwest = { version = "0.10", default-features = false, features = ["json", "native-tls"] }
|
||||
|
|
|
@ -118,7 +118,10 @@ impl<'c> Monero {
|
|||
|
||||
// generate the first 70 as bulk
|
||||
let monerod = &self.monerod;
|
||||
let block = monerod.client().generate_blocks(70, &miner_address).await?;
|
||||
let block = monerod
|
||||
.client()?
|
||||
.generate_blocks(70, &miner_address)
|
||||
.await?;
|
||||
tracing::info!("Generated {:?} blocks", block);
|
||||
miner_wallet.refresh().await?;
|
||||
|
||||
|
@ -128,7 +131,10 @@ impl<'c> Monero {
|
|||
let address = wallet.address().await?.address;
|
||||
miner_wallet.transfer(&address, *amount).await?;
|
||||
tracing::info!("Funded {} wallet with {}", wallet.name, amount);
|
||||
monerod.client().generate_blocks(10, &miner_address).await?;
|
||||
monerod
|
||||
.client()?
|
||||
.generate_blocks(10, &miner_address)
|
||||
.await?;
|
||||
wallet.refresh().await?;
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +142,7 @@ impl<'c> Monero {
|
|||
monerod.start_miner(&miner_address).await?;
|
||||
|
||||
tracing::info!("Waiting for miner wallet to catch up...");
|
||||
let block_height = monerod.client().get_block_count().await?;
|
||||
let block_height = monerod.client()?.get_block_count_rpc().await?;
|
||||
miner_wallet
|
||||
.wait_for_wallet_height(block_height)
|
||||
.await
|
||||
|
@ -204,14 +210,14 @@ impl<'c> Monerod {
|
|||
))
|
||||
}
|
||||
|
||||
pub fn client(&self) -> monerod::Client {
|
||||
monerod::Client::localhost(self.rpc_port)
|
||||
pub fn client(&self) -> anyhow::Result<monerod::Client> {
|
||||
Ok(monerod::Client::localhost(self.rpc_port)?)
|
||||
}
|
||||
|
||||
/// Spawns a task to mine blocks in a regular interval to the provided
|
||||
/// address
|
||||
pub async fn start_miner(&self, miner_wallet_address: &str) -> Result<()> {
|
||||
let monerod = self.client();
|
||||
let monerod = self.client()?;
|
||||
let _ = tokio::spawn(mine(monerod, miner_wallet_address.to_string()));
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//! JSON RPC clients for `monerd` and `monero-wallet-rpc`.
|
||||
pub mod monerod;
|
||||
pub mod monerod_api;
|
||||
pub mod wallet;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
|
@ -1,106 +1,41 @@
|
|||
use crate::rpc::{Request, Response};
|
||||
|
||||
use anyhow::Result;
|
||||
use reqwest::Url;
|
||||
use crate::rpc::monerod_api::MonerodRpcApi;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::debug;
|
||||
|
||||
/// RPC client for monerod and monero-wallet-rpc.
|
||||
#[jsonrpc_client::implement(MonerodRpcApi)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Client {
|
||||
pub inner: reqwest::Client,
|
||||
pub url: Url,
|
||||
inner: reqwest::Client,
|
||||
base_url: reqwest::Url,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
/// New local host monerod RPC client.
|
||||
pub fn localhost(port: u16) -> Self {
|
||||
let url = format!("http://127.0.0.1:{}/json_rpc", port);
|
||||
let url = Url::parse(&url).expect("url is well formed");
|
||||
|
||||
Self {
|
||||
pub fn localhost(port: u16) -> anyhow::Result<Self> {
|
||||
Ok(Client {
|
||||
inner: reqwest::Client::new(),
|
||||
url,
|
||||
}
|
||||
base_url: reqwest::Url::parse(format!("http://127.0.0.1:{}/json_rpc", port).as_str())?,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn generate_blocks(
|
||||
&self,
|
||||
amount_of_blocks: u32,
|
||||
wallet_address: &str,
|
||||
) -> Result<GenerateBlocks> {
|
||||
let params = GenerateBlocksParams {
|
||||
amount_of_blocks,
|
||||
wallet_address: wallet_address.to_owned(),
|
||||
};
|
||||
let url = self.url.clone();
|
||||
// // Step 1: Get the auth header
|
||||
// let res = self.inner.get(url.clone()).send().await?;
|
||||
// let headers = res.headers();
|
||||
// let wwwauth = headers["www-authenticate"].to_str()?;
|
||||
//
|
||||
// // Step 2: Given the auth header, sign the digest for the real req.
|
||||
// let tmp_url = url.clone();
|
||||
// let context = AuthContext::new("username", "password", tmp_url.path());
|
||||
// let mut prompt = digest_auth::parse(wwwauth)?;
|
||||
// let answer = prompt.respond(&context)?.to_header_string();
|
||||
|
||||
let request = Request::new("generateblocks", params);
|
||||
|
||||
let response = self
|
||||
.inner
|
||||
.post(url)
|
||||
.json(&request)
|
||||
.send()
|
||||
.await?
|
||||
.text()
|
||||
) -> anyhow::Result<GenerateBlocks> {
|
||||
let res: GenerateBlocks = self
|
||||
.generateblocks(amount_of_blocks, wallet_address)
|
||||
.await?;
|
||||
|
||||
debug!("generate blocks response: {}", response);
|
||||
|
||||
let res: Response<GenerateBlocks> = serde_json::from_str(&response)?;
|
||||
|
||||
Ok(res.result)
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
// $ curl http://127.0.0.1:18081/json_rpc -d '{"jsonrpc":"2.0","id":"0","method":"get_block_header_by_height","params":{"height":1}}' -H 'Content-Type: application/json'
|
||||
pub async fn get_block_header_by_height(&self, height: u32) -> Result<BlockHeader> {
|
||||
let params = GetBlockHeaderByHeightParams { height };
|
||||
let request = Request::new("get_block_header_by_height", params);
|
||||
|
||||
let response = self
|
||||
.inner
|
||||
.post(self.url.clone())
|
||||
.json(&request)
|
||||
.send()
|
||||
.await?
|
||||
.text()
|
||||
.await?;
|
||||
|
||||
debug!("get block header by height response: {}", response);
|
||||
|
||||
let res: Response<GetBlockHeaderByHeight> = serde_json::from_str(&response)?;
|
||||
|
||||
Ok(res.result.block_header)
|
||||
// TODO: We should not need wrapper functions, why does it not compile without?
|
||||
pub async fn get_block_header_by_height_rpc(&self, height: u32) -> anyhow::Result<BlockHeader> {
|
||||
let res: BlockHeader = self.get_block_header_by_height(height).await?;
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
pub async fn get_block_count(&self) -> Result<u32> {
|
||||
let request = Request::new("get_block_count", "");
|
||||
|
||||
let response = self
|
||||
.inner
|
||||
.post(self.url.clone())
|
||||
.json(&request)
|
||||
.send()
|
||||
.await?
|
||||
.text()
|
||||
.await?;
|
||||
|
||||
debug!("get block count response: {}", response);
|
||||
|
||||
let res: Response<BlockCount> = serde_json::from_str(&response)?;
|
||||
|
||||
Ok(res.result.count)
|
||||
pub async fn get_block_count_rpc(&self) -> anyhow::Result<u32> {
|
||||
let res: u32 = self.get_block_count().await?;
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
11
monero-harness/src/rpc/monerod_api.rs
Normal file
11
monero-harness/src/rpc/monerod_api.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
use crate::rpc::monerod::{BlockHeader, GenerateBlocks};
|
||||
|
||||
#[jsonrpc_client::api(version = "1.0")]
|
||||
#[async_trait::async_trait]
|
||||
pub trait MonerodRpcApi {
|
||||
async fn generateblocks(&self, amount_of_blocks: u32, wallet_address: &str) -> GenerateBlocks;
|
||||
|
||||
async fn get_block_header_by_height(&self, height: u32) -> BlockHeader;
|
||||
|
||||
async fn get_block_count(&self) -> u32;
|
||||
}
|
|
@ -20,7 +20,12 @@ async fn init_miner_and_mine_to_miner_address() {
|
|||
time::delay_for(Duration::from_millis(1010)).await;
|
||||
|
||||
// after a bit more than 1 sec another block should have been mined
|
||||
let block_height = monerod.client().get_block_count().await.unwrap();
|
||||
let block_height = monerod
|
||||
.client()
|
||||
.unwrap()
|
||||
.get_block_count_rpc()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_that(&block_height).is_greater_than(70);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ async fn fund_transfer_and_check_tx_key() {
|
|||
monero
|
||||
.monerod()
|
||||
.client()
|
||||
.unwrap()
|
||||
.generate_blocks(10, &miner_address)
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
|
@ -38,16 +38,6 @@ impl Wallet {
|
|||
pub async fn new_address(&self) -> Result<Address> {
|
||||
self.0.new_address().await.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub async fn transaction_fee(&self, txid: Txid) -> Result<Amount> {
|
||||
let fee = self
|
||||
.0
|
||||
.get_wallet_transaction(txid)
|
||||
.await
|
||||
.map(|res| bitcoin::Amount::from_btc(-res.fee))??;
|
||||
|
||||
Ok(fee)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue