Document the RPC

This commit is contained in:
Luke Parker
2024-06-16 19:59:25 -04:00
parent d740bd2924
commit 08b95abdd8
20 changed files with 289 additions and 197 deletions

View File

@@ -1,5 +1,5 @@
use monero_serai::transaction::Transaction;
use monero_wallet::{TransactionError, extra::MAX_ARBITRARY_DATA_SIZE};
use monero_wallet::{rpc::Rpc, TransactionError, extra::MAX_ARBITRARY_DATA_SIZE};
mod runner;

View File

@@ -1,6 +1,9 @@
use monero_rpc::{Rpc, OutputResponse};
use monero_serai::{transaction::Transaction, Protocol, DEFAULT_LOCK_WINDOW};
use monero_wallet::SpendableOutput;
use monero_simple_request_rpc::SimpleRequestRpc;
use monero_wallet::{
monero::{transaction::Transaction, Protocol, DEFAULT_LOCK_WINDOW},
rpc::{OutputResponse, Rpc},
SpendableOutput,
};
mod runner;
@@ -12,7 +15,7 @@ test!(
builder.add_payment(addr, 2000000000000);
(builder.build().unwrap(), ())
},
|rpc: Rpc<_>, tx: Transaction, mut scanner: Scanner, ()| async move {
|rpc: SimpleRequestRpc, tx: Transaction, mut scanner: Scanner, ()| async move {
let output = scanner.scan_transaction(&tx).not_locked().swap_remove(0);
assert_eq!(output.commitment().amount, 2000000000000);
SpendableOutput::from(&rpc, output).await.unwrap()
@@ -20,7 +23,7 @@ test!(
),
(
// Then make a second tx1
|protocol: Protocol, rpc: Rpc<_>, mut builder: Builder, addr, state: _| async move {
|protocol: Protocol, rpc: SimpleRequestRpc, mut builder: Builder, addr, state: _| async move {
let output_tx0: SpendableOutput = state;
let decoys = Decoys::fingerprintable_canonical_select(
&mut OsRng,
@@ -39,7 +42,7 @@ test!(
(builder.build().unwrap(), (protocol, output_tx0))
},
// Then make sure DSA selects freshly unlocked output from tx1 as a decoy
|rpc: Rpc<_>, tx: Transaction, mut scanner: Scanner, state: (_, _)| async move {
|rpc: SimpleRequestRpc, tx: Transaction, mut scanner: Scanner, state: (_, _)| async move {
use rand_core::OsRng;
let height = rpc.get_height().await.unwrap();
@@ -89,7 +92,7 @@ test!(
builder.add_payment(addr, 2000000000000);
(builder.build().unwrap(), ())
},
|rpc: Rpc<_>, tx: Transaction, mut scanner: Scanner, ()| async move {
|rpc: SimpleRequestRpc, tx: Transaction, mut scanner: Scanner, ()| async move {
let output = scanner.scan_transaction(&tx).not_locked().swap_remove(0);
assert_eq!(output.commitment().amount, 2000000000000);
SpendableOutput::from(&rpc, output).await.unwrap()
@@ -97,7 +100,7 @@ test!(
),
(
// Then make a second tx1
|protocol: Protocol, rpc: Rpc<_>, mut builder: Builder, addr, state: _| async move {
|protocol: Protocol, rpc: SimpleRequestRpc, mut builder: Builder, addr, state: _| async move {
let output_tx0: SpendableOutput = state;
let decoys = Decoys::select(
&mut OsRng,
@@ -116,7 +119,7 @@ test!(
(builder.build().unwrap(), (protocol, output_tx0))
},
// Then make sure DSA selects freshly unlocked output from tx1 as a decoy
|rpc: Rpc<_>, tx: Transaction, mut scanner: Scanner, state: (_, _)| async move {
|rpc: SimpleRequestRpc, tx: Transaction, mut scanner: Scanner, state: (_, _)| async move {
use rand_core::OsRng;
let height = rpc.get_height().await.unwrap();

View File

@@ -2,6 +2,7 @@ use curve25519_dalek::constants::ED25519_BASEPOINT_POINT;
use monero_serai::transaction::Transaction;
use monero_wallet::{
rpc::Rpc,
Eventuality,
address::{AddressType, AddressMeta, MoneroAddress},
};

View File

@@ -8,13 +8,13 @@ use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar};
use tokio::sync::Mutex;
use monero_rpc::Rpc;
use monero_simple_request_rpc::SimpleRequestRpc;
use monero_serai::{transaction::Transaction, DEFAULT_LOCK_WINDOW};
use monero_wallet::{
monero::transaction::Transaction,
rpc::Rpc,
ViewPair, Scanner,
address::{Network, AddressType, AddressSpec, AddressMeta, MoneroAddress},
SpendableOutput, Fee,
SpendableOutput, FeeRate,
};
pub fn random_address() -> (Scalar, ViewPair, MoneroAddress) {
@@ -34,7 +34,7 @@ pub fn random_address() -> (Scalar, ViewPair, MoneroAddress) {
// TODO: Support transactions already on-chain
// TODO: Don't have a side effect of mining blocks more blocks than needed under race conditions
pub async fn mine_until_unlocked(rpc: &Rpc<SimpleRequestRpc>, addr: &str, tx_hash: [u8; 32]) {
pub async fn mine_until_unlocked(rpc: &SimpleRequestRpc, addr: &str, tx_hash: [u8; 32]) {
// mine until tx is in a block
let mut height = rpc.get_height().await.unwrap();
let mut found = false;
@@ -52,11 +52,11 @@ pub async fn mine_until_unlocked(rpc: &Rpc<SimpleRequestRpc>, addr: &str, tx_has
// Mine until tx's outputs are unlocked
let o_indexes: Vec<u64> = rpc.get_o_indexes(tx_hash).await.unwrap();
while rpc
.get_outs(&o_indexes)
.get_unlocked_outputs(&o_indexes, height, false)
.await
.unwrap()
.into_iter()
.all(|o| (!(o.unlocked && height >= (o.height + DEFAULT_LOCK_WINDOW))))
.all(|output| output.is_some())
{
height = rpc.generate_blocks(addr, 1).await.unwrap().1 + 1;
}
@@ -64,7 +64,7 @@ pub async fn mine_until_unlocked(rpc: &Rpc<SimpleRequestRpc>, addr: &str, tx_has
// Mines 60 blocks and returns an unlocked miner TX output.
#[allow(dead_code)]
pub async fn get_miner_tx_output(rpc: &Rpc<SimpleRequestRpc>, view: &ViewPair) -> SpendableOutput {
pub async fn get_miner_tx_output(rpc: &SimpleRequestRpc, view: &ViewPair) -> SpendableOutput {
let mut scanner = Scanner::from_view(view.clone(), Some(HashSet::new()));
// Mine 60 blocks to unlock a miner TX
@@ -79,7 +79,7 @@ pub async fn get_miner_tx_output(rpc: &Rpc<SimpleRequestRpc>, view: &ViewPair) -
}
/// Make sure the weight and fee match the expected calculation.
pub fn check_weight_and_fee(tx: &Transaction, fee_rate: Fee) {
pub fn check_weight_and_fee(tx: &Transaction, fee_rate: FeeRate) {
let fee = tx.rct_signatures.base.fee;
let weight = tx.weight();
@@ -90,7 +90,7 @@ pub fn check_weight_and_fee(tx: &Transaction, fee_rate: Fee) {
assert_eq!(fee, expected_fee);
}
pub async fn rpc() -> Rpc<SimpleRequestRpc> {
pub async fn rpc() -> SimpleRequestRpc {
let rpc =
SimpleRequestRpc::new("http://serai:seraidex@127.0.0.1:18081".to_string()).await.unwrap();
@@ -216,7 +216,7 @@ macro_rules! test {
let builder = SignableTransactionBuilder::new(
protocol,
rpc.get_fee(protocol, FeePriority::Unimportant).await.unwrap(),
rpc.get_fee_rate(protocol, FeePriority::Unimportant).await.unwrap(),
Change::new(
&ViewPair::new(
&Scalar::random(&mut OsRng) * ED25519_BASEPOINT_TABLE,

View File

@@ -1,7 +1,7 @@
use rand_core::RngCore;
use monero_serai::transaction::Transaction;
use monero_wallet::{address::SubaddressIndex, extra::PaymentId};
use monero_wallet::{rpc::Rpc, address::SubaddressIndex, extra::PaymentId};
mod runner;

View File

@@ -1,11 +1,12 @@
use rand_core::OsRng;
use monero_serai::{transaction::Transaction, Protocol};
use monero_rpc::Rpc;
use monero_simple_request_rpc::SimpleRequestRpc;
use monero_wallet::{
extra::Extra, address::SubaddressIndex, ReceivedOutput, SpendableOutput, DecoySelection, Decoys,
SignableTransactionBuilder,
monero::{transaction::Transaction, Protocol},
rpc::Rpc,
extra::Extra,
address::SubaddressIndex,
ReceivedOutput, SpendableOutput, DecoySelection, Decoys, SignableTransactionBuilder,
};
mod runner;
@@ -13,7 +14,7 @@ mod runner;
// Set up inputs, select decoys, then add them to the TX builder
async fn add_inputs(
protocol: Protocol,
rpc: &Rpc<SimpleRequestRpc>,
rpc: &SimpleRequestRpc,
outputs: Vec<ReceivedOutput>,
builder: &mut SignableTransactionBuilder,
) {
@@ -98,7 +99,7 @@ test!(
},
),
(
|protocol, rpc: Rpc<_>, _, _, outputs: Vec<ReceivedOutput>| async move {
|protocol, rpc: SimpleRequestRpc, _, _, outputs: Vec<ReceivedOutput>| async move {
use monero_wallet::FeePriority;
let change_view = ViewPair::new(
@@ -108,7 +109,7 @@ test!(
let mut builder = SignableTransactionBuilder::new(
protocol,
rpc.get_fee(protocol, FeePriority::Unimportant).await.unwrap(),
rpc.get_fee_rate(protocol, FeePriority::Unimportant).await.unwrap(),
Change::new(&change_view, false),
);
add_inputs(protocol, &rpc, vec![outputs.first().unwrap().clone()], &mut builder).await;
@@ -287,12 +288,12 @@ test!(
},
),
(
|protocol, rpc: Rpc<_>, _, addr, outputs: Vec<ReceivedOutput>| async move {
|protocol, rpc: SimpleRequestRpc, _, addr, outputs: Vec<ReceivedOutput>| async move {
use monero_wallet::FeePriority;
let mut builder = SignableTransactionBuilder::new(
protocol,
rpc.get_fee(protocol, FeePriority::Unimportant).await.unwrap(),
rpc.get_fee_rate(protocol, FeePriority::Unimportant).await.unwrap(),
Change::fingerprintable(None),
);
add_inputs(protocol, &rpc, vec![outputs.first().unwrap().clone()], &mut builder).await;

View File

@@ -5,10 +5,10 @@ use rand_core::{OsRng, RngCore};
use serde::Deserialize;
use serde_json::json;
use monero_serai::transaction::Transaction;
use monero_rpc::{EmptyResponse, Rpc};
use monero_simple_request_rpc::SimpleRequestRpc;
use monero_wallet::{
monero::transaction::Transaction,
rpc::Rpc,
address::{Network, AddressSpec, SubaddressIndex, MoneroAddress},
extra::{MAX_TX_EXTRA_NONCE_SIZE, Extra, PaymentId},
Scanner,
@@ -16,7 +16,10 @@ use monero_wallet::{
mod runner;
async fn make_integrated_address(rpc: &Rpc<SimpleRequestRpc>, payment_id: [u8; 8]) -> String {
#[derive(Deserialize, Debug)]
struct EmptyResponse {}
async fn make_integrated_address(rpc: &SimpleRequestRpc, payment_id: [u8; 8]) -> String {
#[derive(Debug, Deserialize)]
struct IntegratedAddressResponse {
integrated_address: String,
@@ -33,7 +36,7 @@ async fn make_integrated_address(rpc: &Rpc<SimpleRequestRpc>, payment_id: [u8; 8
res.integrated_address
}
async fn initialize_rpcs() -> (Rpc<SimpleRequestRpc>, Rpc<SimpleRequestRpc>, String) {
async fn initialize_rpcs() -> (SimpleRequestRpc, SimpleRequestRpc, String) {
let wallet_rpc = SimpleRequestRpc::new("http://127.0.0.1:18082".to_string()).await.unwrap();
let daemon_rpc = runner::rpc().await;
@@ -89,7 +92,7 @@ async fn from_wallet_rpc_to_self(spec: AddressSpec) {
// TODO: Needs https://github.com/monero-project/monero/pull/9260
// let fee_rate = daemon_rpc
// .get_fee(daemon_rpc.get_protocol().await.unwrap(), FeePriority::Unimportant)
// .get_fee_rate(daemon_rpc.get_protocol().await.unwrap(), FeePriority::Unimportant)
// .await
// .unwrap();
@@ -173,7 +176,7 @@ test!(
.add_payment(MoneroAddress::from_str(Network::Mainnet, &wallet_rpc_addr).unwrap(), 1000000);
(builder.build().unwrap(), wallet_rpc)
},
|_, tx: Transaction, _, data: Rpc<SimpleRequestRpc>| async move {
|_, tx: Transaction, _, data: SimpleRequestRpc| async move {
// confirm receipt
let _: EmptyResponse = data.json_rpc_call("refresh", None).await.unwrap();
let transfer: TransfersResponse = data
@@ -207,7 +210,7 @@ test!(
.add_payment(MoneroAddress::from_str(Network::Mainnet, &addr.address).unwrap(), 1000000);
(builder.build().unwrap(), (wallet_rpc, addr.account_index))
},
|_, tx: Transaction, _, data: (Rpc<SimpleRequestRpc>, u32)| async move {
|_, tx: Transaction, _, data: (SimpleRequestRpc, u32)| async move {
// confirm receipt
let _: EmptyResponse = data.0.json_rpc_call("refresh", None).await.unwrap();
let transfer: TransfersResponse = data
@@ -259,7 +262,7 @@ test!(
]);
(builder.build().unwrap(), (wallet_rpc, daemon_rpc, addrs.address_index))
},
|_, tx: Transaction, _, data: (Rpc<SimpleRequestRpc>, Rpc<SimpleRequestRpc>, u32)| async move {
|_, tx: Transaction, _, data: (SimpleRequestRpc, SimpleRequestRpc, u32)| async move {
// confirm receipt
let _: EmptyResponse = data.0.json_rpc_call("refresh", None).await.unwrap();
let transfer: TransfersResponse = data
@@ -304,7 +307,7 @@ test!(
builder.add_payment(MoneroAddress::from_str(Network::Mainnet, &addr).unwrap(), 1000000);
(builder.build().unwrap(), (wallet_rpc, payment_id))
},
|_, tx: Transaction, _, data: (Rpc<SimpleRequestRpc>, [u8; 8])| async move {
|_, tx: Transaction, _, data: (SimpleRequestRpc, [u8; 8])| async move {
// confirm receipt
let _: EmptyResponse = data.0.json_rpc_call("refresh", None).await.unwrap();
let transfer: TransfersResponse = data
@@ -339,7 +342,7 @@ test!(
(builder.build().unwrap(), wallet_rpc)
},
|_, tx: Transaction, _, data: Rpc<SimpleRequestRpc>| async move {
|_, tx: Transaction, _, data: SimpleRequestRpc| async move {
// confirm receipt
let _: EmptyResponse = data.json_rpc_call("refresh", None).await.unwrap();
let transfer: TransfersResponse = data