Add a send test

This commit is contained in:
Luke Parker
2022-04-28 20:41:43 -04:00
parent 1d0a0c7c16
commit 777bb3df34
5 changed files with 75 additions and 25 deletions

View File

@@ -22,9 +22,6 @@ pub mod clsag;
pub mod rpc; pub mod rpc;
pub mod transaction; pub mod transaction;
#[cfg(test)]
mod tests;
#[link(name = "wrapper")] #[link(name = "wrapper")]
extern "C" { extern "C" {
pub(crate) fn free(ptr: *const u8); pub(crate) fn free(ptr: *const u8);

View File

@@ -21,9 +21,9 @@ use serde_json::json;
use reqwest; use reqwest;
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
struct EmptyResponse {} pub struct EmptyResponse {}
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
struct JsonRpcResponse<T> { pub struct JsonRpcResponse<T> {
result: T result: T
} }
@@ -58,7 +58,7 @@ impl Rpc {
Rpc(daemon) Rpc(daemon)
} }
async fn rpc_call< pub async fn rpc_call<
Params: Serialize + Debug, Params: Serialize + Debug,
Response: DeserializeOwned + Debug Response: DeserializeOwned + Debug
>(&self, method: &str, params: Option<Params>) -> Result<Response, RpcError> { >(&self, method: &str, params: Option<Params>) -> Result<Response, RpcError> {
@@ -71,7 +71,7 @@ impl Rpc {
self.call_tail(method, builder).await self.call_tail(method, builder).await
} }
async fn bin_call< pub async fn bin_call<
Response: DeserializeOwned + Debug Response: DeserializeOwned + Debug
>(&self, method: &str, params: Vec<u8>) -> Result<Response, RpcError> { >(&self, method: &str, params: Vec<u8>) -> Result<Response, RpcError> {
let client = reqwest::Client::new(); let client = reqwest::Client::new();
@@ -236,18 +236,4 @@ impl Rpc {
Ok(()) Ok(())
} }
#[cfg(test)]
pub async fn mine_block(&self, address: String) -> Result<(), RpcError> {
let _: EmptyResponse = self.rpc_call("json_rpc", Some(json!({
"jsonrpc": "2.0",
"id": (),
"method": "generateblocks",
"params": {
"wallet_address": address,
"amount_of_blocks": 10
},
}))).await?;
Ok(())
}
} }

View File

@@ -365,7 +365,7 @@ pub async fn send<R: RngCore + CryptoRng>(
payments: &[(Address, u64)], payments: &[(Address, u64)],
change: Address, change: Address,
fee_per_byte: u64 fee_per_byte: u64
) -> Result<Hash, TransactionError> { ) -> Result<Transaction, TransactionError> {
let (_, mask_sum, mut tx) = prepare_outputs( let (_, mask_sum, mut tx) = prepare_outputs(
&mut Preparation::Leader(rng), &mut Preparation::Leader(rng),
inputs, inputs,
@@ -386,7 +386,5 @@ pub async fn send<R: RngCore + CryptoRng>(
prunable.Clsags = clsags.iter().map(|clsag| clsag.0.clone()).collect(); prunable.Clsags = clsags.iter().map(|clsag| clsag.0.clone()).collect();
prunable.pseudo_outs = clsags.iter().map(|clsag| Key { key: clsag.1.compress().to_bytes() }).collect(); prunable.pseudo_outs = clsags.iter().map(|clsag| Key { key: clsag.1.compress().to_bytes() }).collect();
tx.rct_signatures.p = Some(prunable); tx.rct_signatures.p = Some(prunable);
Ok(tx)
rpc.publish_transaction(&tx).await.map_err(|e| TransactionError::InvalidTransaction(e))?;
Ok(tx.hash())
} }

13
coins/monero/tests/rpc.rs Normal file
View File

@@ -0,0 +1,13 @@
use serde_json::json;
use monero_serai::rpc::{EmptyResponse, RpcError, Rpc};
pub async fn mine_block(rpc: &Rpc, address: String) -> Result<EmptyResponse, RpcError> {
rpc.rpc_call("json_rpc", Some(json!({
"method": "generateblocks",
"params": {
"wallet_address": address,
"amount_of_blocks": 10
},
}))).await
}

View File

@@ -0,0 +1,56 @@
use rand::rngs::OsRng;
use curve25519_dalek::constants::ED25519_BASEPOINT_TABLE;
use monero::{
network::Network,
util::{key::PublicKey, address::Address}
};
use monero_serai::{
random_scalar,
transaction,
rpc::Rpc
};
mod rpc;
use crate::rpc::mine_block;
#[tokio::test]
pub async fn send() {
let rpc = Rpc::new("http://127.0.0.1:18081".to_string());
// Generate an address
let view = random_scalar(&mut OsRng);
let spend = random_scalar(&mut OsRng);
let spend_pub = &spend * &ED25519_BASEPOINT_TABLE;
let addr = Address::standard(
Network::Mainnet,
PublicKey { point: spend_pub.compress() },
PublicKey { point: (&view * &ED25519_BASEPOINT_TABLE).compress() }
);
let fee_per_byte = 50000000;
let fee = fee_per_byte * 2000;
let mut tx;
let mut output;
let mut amount;
for i in 0 .. 2 {
let start = rpc.get_height().await.unwrap();
for _ in 0 .. 7 {
mine_block(&rpc, addr.to_string()).await.unwrap();
}
// Test both a miner output and a normal output
tx = rpc.get_block_transactions(start).await.unwrap().swap_remove(i);
output = transaction::scan(&tx, view, spend_pub).swap_remove(0);
// Test creating a zero change output and a non-zero change output
amount = output.commitment.amount - fee - u64::try_from(i).unwrap();
let tx = transaction::send(
&mut OsRng, &rpc, &spend, &vec![output], &vec![(addr, amount)], addr, fee_per_byte
).await.unwrap();
rpc.publish_transaction(&tx).await.unwrap();
}
}