serai/networks/monero/rpc/simple-request/tests/tests.rs
Luke Parker 880565cb81
Some checks failed
Coordinator Tests / build (push) Has been cancelled
crypto/ Tests / test-crypto (push) Has been cancelled
Full Stack Tests / build (push) Has been cancelled
Lint / clippy (macos-13) (push) Has been cancelled
Lint / clippy (macos-14) (push) Has been cancelled
Lint / clippy (ubuntu-latest) (push) Has been cancelled
Lint / clippy (windows-latest) (push) Has been cancelled
Lint / deny (push) Has been cancelled
Lint / fmt (push) Has been cancelled
Lint / machete (push) Has been cancelled
Message Queue Tests / build (push) Has been cancelled
Monero Tests / unit-tests (push) Has been cancelled
Reproducible Runtime / build (push) Has been cancelled
Tests / test-infra (push) Has been cancelled
common/ Tests / test-common (push) Has been cancelled
Monero Tests / integration-tests (v0.17.3.2) (push) Has been cancelled
Monero Tests / integration-tests (v0.18.2.0) (push) Has been cancelled
networks/ Tests / test-networks (push) Has been cancelled
no-std build / build (push) Has been cancelled
Processor Tests / build (push) Has been cancelled
Tests / test-substrate (push) Has been cancelled
Tests / test-serai-client (push) Has been cancelled
Rust 1.80
Preserves the fn accessors within the Monero crates so that we can use statics
in some cfgs yet not all (in order to provide support for more low-memory
devices) with the exception of `H` (which truly should be cached).
2024-07-26 19:28:10 -07:00

144 lines
4.4 KiB
Rust

use std::sync::LazyLock;
use tokio::sync::Mutex;
use monero_address::{Network, MoneroAddress};
// monero-rpc doesn't include a transport
// We can't include the simple-request crate there as then we'd have a cyclical dependency
// Accordingly, we test monero-rpc here (implicitly testing the simple-request transport)
use monero_simple_request_rpc::*;
static SEQUENTIAL: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
const ADDRESS: &str =
"4B33mFPMq6mKi7Eiyd5XuyKRVMGVZz1Rqb9ZTyGApXW5d1aT7UBDZ89ewmnWFkzJ5wPd2SFbn313vCT8a4E2Qf4KQH4pNey";
#[tokio::test]
async fn test_rpc() {
use monero_rpc::Rpc;
let guard = SEQUENTIAL.lock().await;
let rpc =
SimpleRequestRpc::new("http://serai:seraidex@127.0.0.1:18081".to_string()).await.unwrap();
{
// Test get_height
let height = rpc.get_height().await.unwrap();
// The height should be the amount of blocks on chain
// The number of a block should be its zero-indexed position
// Accordingly, there should be no block whose number is the height
assert!(rpc.get_block_by_number(height).await.is_err());
let block_number = height - 1;
// There should be a block just prior
let block = rpc.get_block_by_number(block_number).await.unwrap();
// Also test the block RPC routes are consistent
assert_eq!(block.number().unwrap(), block_number);
assert_eq!(rpc.get_block(block.hash()).await.unwrap(), block);
assert_eq!(rpc.get_block_hash(block_number).await.unwrap(), block.hash());
// And finally the hardfork version route
assert_eq!(rpc.get_hardfork_version().await.unwrap(), block.header.hardfork_version);
}
// Test generate_blocks
for amount_of_blocks in [1, 5] {
let (blocks, number) = rpc
.generate_blocks(
&MoneroAddress::from_str(Network::Mainnet, ADDRESS).unwrap(),
amount_of_blocks,
)
.await
.unwrap();
let height = rpc.get_height().await.unwrap();
assert_eq!(number, height - 1);
let mut actual_blocks = Vec::with_capacity(amount_of_blocks);
for i in (height - amount_of_blocks) .. height {
actual_blocks.push(rpc.get_block_by_number(i).await.unwrap().hash());
}
assert_eq!(blocks, actual_blocks);
}
drop(guard);
}
#[tokio::test]
async fn test_decoy_rpc() {
use monero_rpc::{Rpc, DecoyRpc};
let guard = SEQUENTIAL.lock().await;
let rpc =
SimpleRequestRpc::new("http://serai:seraidex@127.0.0.1:18081".to_string()).await.unwrap();
// Ensure there's blocks on-chain
rpc
.generate_blocks(&MoneroAddress::from_str(Network::Mainnet, ADDRESS).unwrap(), 100)
.await
.unwrap();
// Test get_output_distribution
// Our documentation for our Rust fn defines it as taking two block numbers
{
let distribution_len = rpc.get_output_distribution_end_height().await.unwrap();
assert_eq!(distribution_len, rpc.get_height().await.unwrap());
rpc.get_output_distribution(0 ..= distribution_len).await.unwrap_err();
assert_eq!(
rpc.get_output_distribution(0 .. distribution_len).await.unwrap().len(),
distribution_len
);
assert_eq!(
rpc.get_output_distribution(.. distribution_len).await.unwrap().len(),
distribution_len
);
assert_eq!(
rpc.get_output_distribution(.. (distribution_len - 1)).await.unwrap().len(),
distribution_len - 1
);
assert_eq!(
rpc.get_output_distribution(1 .. distribution_len).await.unwrap().len(),
distribution_len - 1
);
assert_eq!(rpc.get_output_distribution(0 ..= 0).await.unwrap().len(), 1);
assert_eq!(rpc.get_output_distribution(0 ..= 1).await.unwrap().len(), 2);
assert_eq!(rpc.get_output_distribution(1 ..= 1).await.unwrap().len(), 1);
rpc.get_output_distribution(0 .. 0).await.unwrap_err();
#[allow(clippy::reversed_empty_ranges)]
rpc.get_output_distribution(1 .. 0).await.unwrap_err();
}
drop(guard);
}
// This test passes yet requires a mainnet node, which we don't have reliable access to in CI.
/*
#[tokio::test]
async fn test_zero_out_tx_o_indexes() {
use monero_rpc::Rpc;
let guard = SEQUENTIAL.lock().await;
let rpc = SimpleRequestRpc::new("https://node.sethforprivacy.com".to_string()).await.unwrap();
assert_eq!(
rpc
.get_o_indexes(
hex::decode("17ce4c8feeb82a6d6adaa8a89724b32bf4456f6909c7f84c8ce3ee9ebba19163")
.unwrap()
.try_into()
.unwrap()
)
.await
.unwrap(),
Vec::<u64>::new()
);
drop(guard);
}
*/