Add a send test

This commit is contained in:
Luke Parker 2022-04-28 20:41:43 -04:00
parent 1d0a0c7c16
commit 777bb3df34
No known key found for this signature in database
GPG key ID: F9F1386DB1E119B6
5 changed files with 75 additions and 25 deletions

View file

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

View file

@ -21,9 +21,9 @@ use serde_json::json;
use reqwest;
#[derive(Deserialize, Debug)]
struct EmptyResponse {}
pub struct EmptyResponse {}
#[derive(Deserialize, Debug)]
struct JsonRpcResponse<T> {
pub struct JsonRpcResponse<T> {
result: T
}
@ -58,7 +58,7 @@ impl Rpc {
Rpc(daemon)
}
async fn rpc_call<
pub async fn rpc_call<
Params: Serialize + Debug,
Response: DeserializeOwned + Debug
>(&self, method: &str, params: Option<Params>) -> Result<Response, RpcError> {
@ -71,7 +71,7 @@ impl Rpc {
self.call_tail(method, builder).await
}
async fn bin_call<
pub async fn bin_call<
Response: DeserializeOwned + Debug
>(&self, method: &str, params: Vec<u8>) -> Result<Response, RpcError> {
let client = reqwest::Client::new();
@ -236,18 +236,4 @@ impl Rpc {
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)],
change: Address,
fee_per_byte: u64
) -> Result<Hash, TransactionError> {
) -> Result<Transaction, TransactionError> {
let (_, mask_sum, mut tx) = prepare_outputs(
&mut Preparation::Leader(rng),
inputs,
@ -386,7 +386,5 @@ pub async fn send<R: RngCore + CryptoRng>(
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();
tx.rct_signatures.p = Some(prunable);
rpc.publish_transaction(&tx).await.map_err(|e| TransactionError::InvalidTransaction(e))?;
Ok(tx.hash())
Ok(tx)
}

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();
}
}