Add fee handling code to Monero

Updates how change outputs are handled, with a far more logical 
construction offering greater flexibility.

prepare_outputs can not longer error. SignaableTransaction::new will.
This commit is contained in:
Luke Parker
2022-06-19 12:03:01 -04:00
parent 71fca06120
commit f50f249468
11 changed files with 231 additions and 107 deletions

View File

@@ -9,7 +9,7 @@ use serde_json::json;
use reqwest;
use crate::{transaction::{Input, Timelock, Transaction}, block::Block};
use crate::{transaction::{Input, Timelock, Transaction}, block::Block, wallet::Fee};
#[derive(Deserialize, Debug)]
pub struct EmptyResponse {}
@@ -34,9 +34,6 @@ pub enum RpcError {
InvalidTransaction([u8; 32])
}
#[derive(Clone, Debug)]
pub struct Rpc(String);
fn rpc_hex(value: &str) -> Result<Vec<u8>, RpcError> {
hex::decode(value).map_err(|_| RpcError::InternalError("Monero returned invalid hex".to_string()))
}
@@ -47,6 +44,9 @@ fn rpc_point(point: &str) -> Result<EdwardsPoint, RpcError> {
).decompress().ok_or(RpcError::InvalidPoint(point.to_string()))
}
#[derive(Clone, Debug)]
pub struct Rpc(String);
impl Rpc {
pub fn new(daemon: String) -> Rpc {
Rpc(daemon)
@@ -233,6 +233,32 @@ impl Rpc {
Ok(indexes.o_indexes)
}
pub async fn get_output_distribution(&self, height: usize) -> Result<Vec<u64>, RpcError> {
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
pub struct Distribution {
distribution: Vec<u64>
}
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
struct Distributions {
distributions: Vec<Distribution>
}
let mut distributions: JsonRpcResponse<Distributions> = self.rpc_call("json_rpc", Some(json!({
"method": "get_output_distribution",
"params": {
"binary": false,
"amounts": [0],
"cumulative": true,
"to_height": height
}
}))).await?;
Ok(distributions.result.distributions.swap_remove(0).distribution)
}
pub async fn get_outputs(
&self,
indexes: &[u64],
@@ -278,30 +304,19 @@ impl Rpc {
).collect()
}
pub async fn get_output_distribution(&self, height: usize) -> Result<Vec<u64>, RpcError> {
pub async fn get_fee(&self) -> Result<Fee, RpcError> {
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
pub struct Distribution {
distribution: Vec<u64>
struct FeeResponse {
fee: u64,
quantization_mask: u64
}
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
struct Distributions {
distributions: Vec<Distribution>
}
let mut distributions: JsonRpcResponse<Distributions> = self.rpc_call("json_rpc", Some(json!({
"method": "get_output_distribution",
"params": {
"binary": false,
"amounts": [0],
"cumulative": true,
"to_height": height
}
let res: JsonRpcResponse<FeeResponse> = self.rpc_call("json_rpc", Some(json!({
"method": "get_fee_estimate"
}))).await?;
Ok(distributions.result.distributions.swap_remove(0).distribution)
Ok(Fee { per_weight: res.result.fee, mask: res.result.quantization_mask })
}
pub async fn publish_transaction(&self, tx: &Transaction) -> Result<(), RpcError> {