add some more daemon methods

This commit is contained in:
creating2morrow 2023-05-12 01:13:30 -04:00
parent e9ef5778d1
commit dea7a3a52a
5 changed files with 272 additions and 22 deletions

View file

@ -0,0 +1,5 @@
# cargo +nightly fmt
format_code_in_doc_comments = true
imports_granularity = "Crate"
imports_layout = "Vertical"
wrap_comments = true

View file

@ -1,16 +1,16 @@
pub mod args; // command line arguments
pub mod auth; // internal auth repo/service layer
pub mod contact; // contact repo/service layer
pub mod db; // lmdb interface
pub mod gpg; // gpgme interface
pub mod i2p; // i2p repo/service layer
pub mod message; // message repo/service layer
pub mod models; // db structs
pub mod monero; // monero-wallet-rpc interface
pub mod proof; // external auth/payment proof module
pub mod reqres; // http request/responses
pub mod user;
pub mod utils; // misc. // user rep/service layer
pub mod args; // command line arguments
pub mod auth; // internal auth repo/service layer
pub mod contact; // contact repo/service layer
pub mod db; // lmdb interface
pub mod gpg; // gpgme interface
pub mod i2p; // i2p repo/service layer
pub mod message; // message repo/service layer
pub mod models; // db structs
pub mod monero; // monero-wallet-rpc interface
pub mod proof; // external auth/payment proof module
pub mod reqres; // http request/responses
pub mod user; // misc.
pub mod utils; // user rep/service layer
pub const NEVMES_JWP_SECRET_KEY: &str = "NEVMES_JWP_SECRET_KEY";
pub const NEVMES_JWT_SECRET_KEY: &str = "NEVMES_JWT_SECRET_KEY";

View file

@ -2,11 +2,7 @@ use crate::{
args,
proof,
reqres,
utils::{
self,
get_release_env,
ReleaseEnvironment,
},
utils,
};
use clap::Parser;
use diqwest::WithDigestAuth;
@ -80,7 +76,10 @@ impl RpcFields {
}
enum DaemonFields {
GetBlock,
GetHeight,
GetInfo,
GetTransactions,
Id,
Version,
}
@ -88,7 +87,10 @@ enum DaemonFields {
impl DaemonFields {
pub fn value(&self) -> String {
match *self {
DaemonFields::GetBlock => String::from("get_block"),
DaemonFields::GetHeight => String::from("get_height"),
DaemonFields::GetInfo => String::from("get_info"),
DaemonFields::GetTransactions => String::from("get_transactions"),
DaemonFields::Id => String::from("0"),
DaemonFields::Version => String::from("2.0"),
}
@ -114,8 +116,8 @@ pub fn start_daemon() {
info!("starting monerod");
let blockchain_dir = get_blockchain_dir();
let bin_dir = get_monero_location();
let release_env = get_release_env();
if release_env == ReleaseEnvironment::Development {
let release_env = utils::get_release_env();
if release_env == utils::ReleaseEnvironment::Development {
let args = ["--data-dir", &blockchain_dir, "--stagenet", "--detach"];
let output = Command::new(format!("{}/monerod", bin_dir))
.args(args)
@ -144,8 +146,8 @@ pub fn start_rpc() {
"/home/{}/.nevmes/stagenet/wallet/",
std::env::var("USER").unwrap_or(String::from("user")),
);
let release_env = get_release_env();
if release_env == ReleaseEnvironment::Development {
let release_env = utils::get_release_env();
if release_env == utils::ReleaseEnvironment::Development {
let args = [
"--rpc-bind-port",
&port,
@ -942,3 +944,73 @@ pub async fn get_info() -> reqres::XmrDaemonGetInfoResponse {
Err(_) => Default::default(),
}
}
/// Performs the xmr daemon 'get_height' method
pub async fn get_height() -> reqres::XmrDaemonGetHeightResponse {
info!("fetching daemon height");
let client = reqwest::Client::new();
let host = get_rpc_daemon();
let req = reqres::XmrRpcRequest {
jsonrpc: DaemonFields::Version.value(),
id: DaemonFields::Id.value(),
method: DaemonFields::GetHeight.value(),
};
match client.post(host).json(&req).send().await {
Ok(response) => {
let res = response.json::<reqres::XmrDaemonGetHeightResponse>().await;
debug!("{} response: {:?}", DaemonFields::GetHeight.value(), res);
match res {
Ok(res) => res,
_ => Default::default(),
}
}
Err(_) => Default::default(),
}
}
/// Performs the xmr daemon 'get_block' method
pub async fn get_block(height: u64) -> reqres::XmrDaemonGetBlockResponse {
info!("fetching block at height: {}", height);
let client = reqwest::Client::new();
let host = get_rpc_daemon();
let params: reqres::XmrDaemonGetBlockParams = reqres::XmrDaemonGetBlockParams { height };
let req = reqres::XmrDaemonGetBlockRequest {
jsonrpc: DaemonFields::Version.value(),
id: DaemonFields::Id.value(),
method: DaemonFields::GetBlock.value(),
params,
};
match client.post(host).json(&req).send().await {
Ok(response) => {
let res = response.json::<reqres::XmrDaemonGetBlockResponse>().await;
debug!("{} response: {:?}", DaemonFields::GetBlock.value(), res);
match res {
Ok(res) => res,
_ => Default::default(),
}
}
Err(_) => Default::default(),
}
}
/// Performs the xmr daemon 'get_transactions' method
pub async fn get_transactions(txs_hashes: Vec<String>) -> reqres::XmrDaemonGetTransactionsResponse {
info!("fetching {} transactions", txs_hashes.len());
let client = reqwest::Client::new();
let host = get_rpc_daemon();
let req = reqres::XmrDaemonGetTransactionsRequest {
txs_hashes,
decode_as_json: true,
};
match client.post(host).json(&req).send().await {
Ok(response) => {
let res = response.json::<reqres::XmrDaemonGetTransactionsResponse>().await;
debug!("{} response: {:?}", DaemonFields::GetTransactions.value(), res);
match res {
Ok(res) => res,
_ => Default::default(),
}
}
Err(_) => Default::default(),
}
}

View file

@ -7,6 +7,8 @@ use serde::{
// All http requests and responses are here
// START XMR Structs
// Reference: https://www.getmonero.org/resources/developer-guides/wallet-rpc.html
// https://www.getmonero.org/resources/developer-guides/daemon-rpc.html
// params
#[derive(Deserialize, Serialize, Debug)]
@ -121,6 +123,11 @@ pub struct XmrRpcCreateAddressParams {
pub account_index: u8,
}
#[derive(Deserialize, Serialize, Debug)]
pub struct XmrDaemonGetBlockParams {
pub height: u64,
}
// requests
#[derive(Deserialize, Serialize, Debug)]
pub struct XmrRpcValidateAddressRequest {
@ -153,6 +160,20 @@ pub struct XmrRpcRequest {
pub method: String,
}
#[derive(Deserialize, Serialize, Debug)]
pub struct XmrDaemonGetBlockRequest {
pub jsonrpc: String,
pub id: String,
pub method: String,
pub params: XmrDaemonGetBlockParams,
}
#[derive(Deserialize, Serialize, Debug)]
pub struct XmrDaemonGetTransactionsRequest {
pub txs_hashes: Vec<String>,
pub decode_as_json: bool,
}
#[derive(Deserialize, Serialize, Debug)]
pub struct XmrRpcAddressRequest {
pub jsonrpc: String,
@ -478,7 +499,94 @@ pub struct XmrDaemonGetInfoResult {
pub wide_difficulty: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct BlockHeader {
pub block_size: u32,
pub block_weight: u32,
pub cumulative_difficulty: u128,
pub cumulative_difficulty_top64: u128,
pub depth: u32,
pub difficulty: u128,
pub difficulty_top64: u128,
pub hash: String,
pub height: u64,
pub long_term_weight: u64,
pub major_version: u32,
pub miner_tx_hash: String,
pub minor_version: u32,
pub nonce: u32,
pub num_txes: u64,
pub orphan_status: bool,
pub pow_hash: String,
pub prev_hash: String,
pub reward: u64,
pub timestamp: u64,
pub wide_cumulative_difficulty: String,
pub wide_difficulty: String,
}
impl Default for BlockHeader {
fn default() -> Self {
BlockHeader {
block_size: 0,
block_weight: 0,
cumulative_difficulty: 0,
cumulative_difficulty_top64: 0,
depth: 0,
difficulty: 0,
difficulty_top64: 0,
hash: utils::empty_string(),
height: 0,
long_term_weight: 0,
major_version: 0,
miner_tx_hash: utils::empty_string(),
minor_version: 0,
nonce: 0,
num_txes: 0,
orphan_status: false,
pow_hash: utils::empty_string(),
prev_hash: utils::empty_string(),
reward: 0,
timestamp: 0,
wide_cumulative_difficulty: utils::empty_string(),
wide_difficulty: utils::empty_string(),
}
}
}
#[derive(Deserialize, Debug)]
pub struct XmrDaemonGetBlockResult {
pub blob: String,
pub block_header: BlockHeader,
pub credits: u64,
pub json: String,
pub miner_tx_hash: String,
pub status: String,
pub top_hash: String,
pub tx_hashes: Vec<String>,
pub untrusted: bool,
}
// responses
#[derive(Deserialize, Debug)]
pub struct XmrDaemonGetHeightResponse {
pub hash: String,
pub height: u64,
pub status: String,
pub untrusted: bool,
}
impl Default for XmrDaemonGetHeightResponse {
fn default() -> Self {
XmrDaemonGetHeightResponse {
hash: utils::empty_string(),
height: 0,
status: utils::empty_string(),
untrusted: false,
}
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct XmrDaemonGetInfoResponse {
pub result: XmrDaemonGetInfoResult,
@ -535,6 +643,42 @@ impl Default for XmrDaemonGetInfoResponse {
}
}
#[derive(Deserialize, Debug)]
pub struct XmrDaemonGetBlockResponse {
pub result: XmrDaemonGetBlockResult,
}
impl Default for XmrDaemonGetBlockResponse {
fn default() -> Self {
XmrDaemonGetBlockResponse {
result: XmrDaemonGetBlockResult {
blob: utils::empty_string(),
block_header: Default::default(),
credits: 0,
json: utils::empty_string(),
miner_tx_hash: utils::empty_string(),
status: utils::empty_string(),
top_hash: utils::empty_string(),
tx_hashes: Vec::new(),
untrusted: false,
}
}
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct XmrDaemonGetTransactionsResponse {
pub txs_as_json: Vec<String>,
}
impl Default for XmrDaemonGetTransactionsResponse {
fn default() -> Self {
XmrDaemonGetTransactionsResponse {
txs_as_json: Vec::new(),
}
}
}
#[derive(Deserialize, Debug)]
pub struct XmrRpcVerifyResponse {
pub result: XmrRpcVerifyResult,

View file

@ -592,3 +592,32 @@ fn validate_installation_hash(sw: ExternalSoftware, filename: &String) -> bool {
debug!("expected hash: {}", expected_hash);
actual_hash == expected_hash
}
/// The highly ineffecient fee estimator.
///
/// Get the current height. Start fetching blocks
///
/// and checking the number of transactions. If
///
/// there were non-coinbase transactions in the block
///
/// extract the `txnFee` from the `as_json` field.
///
/// Once we have accumulated n=30 fees paid return the
///
/// average fee paid from the most recent 30 transactions.
///
/// Note, it may take more than one block to do this,
///
/// especially on stagenet.
pub fn estimate_fee() -> u128 {
0
}
/// Combine the results `estimate_fee()` and `get_balance()` to
///
/// determine whether or not a transfer is possible.
pub fn can_transfer() -> bool {
false
}