From fd585d496c31d689d84fc7de51632f958917a321 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 24 Jul 2023 04:53:59 -0400 Subject: [PATCH] Resolve #321 --- Cargo.lock | 160 ++-------------- coins/monero/Cargo.toml | 4 - coins/monero/tests/wallet2_compatibility.rs | 199 ++++++++++++-------- 3 files changed, 131 insertions(+), 232 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ed302be..9457a3dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -511,15 +511,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" -[[package]] -name = "base58-monero" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d079cdf47e1ca75554200bb2f30bff5a5af16964cac4a566b18de9a5d48db2b" -dependencies = [ - "thiserror", -] - [[package]] name = "base58-monero" version = "1.1.0" @@ -1048,7 +1039,6 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", - "serde", "time 0.1.45", "wasm-bindgen", "winapi", @@ -1159,7 +1149,7 @@ version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", "syn 2.0.26", @@ -1583,7 +1573,6 @@ dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", - "serde", "subtle", "zeroize", ] @@ -2055,7 +2044,7 @@ dependencies = [ "ff 0.13.0", "flexible-transcript", "group 0.13.0", - "hex-literal 0.4.1", + "hex-literal", "k256", "multiexp", "rand_core 0.6.4", @@ -2283,7 +2272,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", "syn 1.0.109", @@ -2381,7 +2370,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" dependencies = [ "crunchy", - "fixed-hash 0.8.0", + "fixed-hash", "impl-codec", "impl-rlp", "impl-serde", @@ -2415,7 +2404,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" dependencies = [ "ethbloom", - "fixed-hash 0.8.0", + "fixed-hash", "impl-codec", "impl-rlp", "impl-serde", @@ -2808,18 +2797,6 @@ dependencies = [ "scale-info", ] -[[package]] -name = "fixed-hash" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" -dependencies = [ - "byteorder", - "rand 0.8.5", - "rustc-hex", - "static_assertions", -] - [[package]] name = "fixed-hash" version = "0.8.0" @@ -3538,15 +3515,6 @@ dependencies = [ "fxhash", ] -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "heck" version = "0.4.1" @@ -3565,12 +3533,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hex-literal" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" - [[package]] name = "hex-literal" version = "0.4.1" @@ -4049,21 +4011,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "jsonrpc-core" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" -dependencies = [ - "futures", - "futures-executor", - "futures-util", - "log", - "serde", - "serde_derive", - "serde_json", -] - [[package]] name = "jsonrpsee" version = "0.16.2" @@ -4153,7 +4100,7 @@ version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baa6da1e4199c10d7b1d0a6e5e8bd8e55f351163b6f4b3cbb044672a69bd4c1c" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro-crate", "proc-macro2", "quote", @@ -4631,7 +4578,7 @@ version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fba456131824ab6acd4c7bf61e9c0f0a3014b5fc9868ccb8e10d344594cdc4f" dependencies = [ - "heck 0.4.1", + "heck", "quote", "syn 1.0.109", ] @@ -5194,24 +5141,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "monero" -version = "0.17.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403883d12972e916dd9754cdb90c25441a9abcf435f8e09c3146de100150eeb0" -dependencies = [ - "base58-monero 1.0.0", - "curve25519-dalek 3.2.0", - "fixed-hash 0.7.0", - "hex", - "hex-literal 0.3.4", - "sealed", - "serde", - "serde-big-array", - "thiserror", - "tiny-keccak", -] - [[package]] name = "monero-generators" version = "0.3.0" @@ -5224,32 +5153,12 @@ dependencies = [ "subtle", ] -[[package]] -name = "monero-rpc" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e016b5ed7dbf76e123516b22f35653a95d8c4b784d2ce2113395863dfd9f482f" -dependencies = [ - "anyhow", - "chrono", - "fixed-hash 0.8.0", - "hex", - "http", - "jsonrpc-core", - "monero", - "reqwest", - "serde", - "serde_json", - "tracing", - "uuid 1.4.1", -] - [[package]] name = "monero-serai" version = "0.1.4-alpha" dependencies = [ "async-trait", - "base58-monero 1.1.0", + "base58-monero", "crc", "curve25519-dalek 3.2.0", "dalek-ff-group", @@ -5259,10 +5168,9 @@ dependencies = [ "futures", "group 0.13.0", "hex", - "hex-literal 0.4.1", + "hex-literal", "modular-frost", "monero-generators", - "monero-rpc", "multiexp", "pbkdf2 0.12.2", "rand 0.8.5", @@ -6525,7 +6433,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" dependencies = [ - "fixed-hash 0.8.0", + "fixed-hash", "impl-codec", "impl-rlp", "impl-serde", @@ -6641,7 +6549,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ "bytes", - "heck 0.4.1", + "heck", "itertools", "lazy_static", "log", @@ -7046,7 +6954,6 @@ dependencies = [ "tokio", "tokio-native-tls", "tokio-rustls 0.24.1", - "tokio-socks", "tower-service", "url", "wasm-bindgen", @@ -8550,18 +8457,6 @@ dependencies = [ "url", ] -[[package]] -name = "sealed" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b5e421024b5e5edfbaa8e60ecf90bda9dbffc602dbb230e6028763f85f0c68c" -dependencies = [ - "heck 0.3.3", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "sec1" version = "0.3.0" @@ -9066,15 +8961,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-big-array" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3323f09a748af288c3dc2474ea6803ee81f118321775bffa3ac8f7e65c5e90e7" -dependencies = [ - "serde", -] - [[package]] name = "serde_bytes" version = "0.11.12" @@ -10149,7 +10035,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", "rustversion", @@ -10162,7 +10048,7 @@ version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6069ca09d878a33f883cc06aaa9718ede171841d3832450354410b718b097232" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", "rustversion", @@ -10314,7 +10200,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e2f231d97c145c564bd544212c0cc0c29c09ff516af199f4ce00c8e055f8138" dependencies = [ "frame-metadata 15.1.0", - "heck 0.4.1", + "heck", "hex", "jsonrpsee", "parity-scale-codec", @@ -10699,18 +10585,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-socks" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0" -dependencies = [ - "either", - "futures-util", - "thiserror", - "tokio", -] - [[package]] name = "tokio-stream" version = "0.1.14" @@ -11089,12 +10963,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" - [[package]] name = "unicode-width" version = "0.1.10" diff --git a/coins/monero/Cargo.toml b/coins/monero/Cargo.toml index 2e4020b1..fa2ade8b 100644 --- a/coins/monero/Cargo.toml +++ b/coins/monero/Cargo.toml @@ -68,10 +68,6 @@ monero-generators = { path = "generators", version = "0.3", default-features = f [dev-dependencies] tokio = { version = "1", features = ["full"] } -# TODO: Remove when https://github.com/monero-rs/monero-rs/issues/162 is solved -serde = { version = "=1.0.167", default-features = false, features = ["derive", "alloc"] } -monero-rpc = "0.3" - frost = { package = "modular-frost", path = "../../crypto/frost", version = "0.7", features = ["tests"] } [features] diff --git a/coins/monero/tests/wallet2_compatibility.rs b/coins/monero/tests/wallet2_compatibility.rs index ed41a12e..592a4d92 100644 --- a/coins/monero/tests/wallet2_compatibility.rs +++ b/coins/monero/tests/wallet2_compatibility.rs @@ -1,25 +1,13 @@ -use std::{ - collections::{HashSet, HashMap}, - str::FromStr, -}; +use std::collections::HashSet; use rand_core::{OsRng, RngCore}; use serde::Deserialize; use serde_json::json; -use monero_rpc::{ - monero::{ - Amount, Address, - cryptonote::{hash::Hash, subaddress::Index}, - util::address::PaymentId, - }, - TransferOptions, WalletClient, -}; - use monero_serai::{ transaction::Transaction, - rpc::{HttpRpc, Rpc}, + rpc::{EmptyResponse, HttpRpc, Rpc}, wallet::{ address::{Network, AddressSpec, SubaddressIndex, MoneroAddress}, extra::{MAX_TX_EXTRA_NONCE_SIZE, Extra}, @@ -29,13 +17,12 @@ use monero_serai::{ mod runner; -async fn make_integrated_address(payment_id: [u8; 8]) -> String { - #[derive(Deserialize, Debug)] +async fn make_integrated_address(rpc: &Rpc, payment_id: [u8; 8]) -> String { + #[derive(Debug, Deserialize)] struct IntegratedAddressResponse { integrated_address: String, } - let rpc = HttpRpc::new("http://127.0.0.1:6061".to_string()).unwrap(); let res = rpc .json_rpc_call::( "make_integrated_address", @@ -47,21 +34,32 @@ async fn make_integrated_address(payment_id: [u8; 8]) -> String { res.integrated_address } -async fn initialize_rpcs() -> (WalletClient, Rpc, monero_rpc::monero::Address) { - let wallet_rpc = - monero_rpc::RpcClientBuilder::new().build("http://127.0.0.1:6061").unwrap().wallet(); +async fn initialize_rpcs() -> (Rpc, Rpc, String) { + let wallet_rpc = HttpRpc::new("http://127.0.0.1:6061".to_string()).unwrap(); let daemon_rpc = runner::rpc().await; - let address_resp = wallet_rpc.get_address(0, None).await; - let wallet_rpc_addr = if address_resp.is_ok() { - address_resp.unwrap().address - } else { - wallet_rpc.create_wallet("wallet".to_string(), None, "English".to_string()).await.unwrap(); - let addr = wallet_rpc.get_address(0, None).await.unwrap().address; - daemon_rpc.generate_blocks(&addr.to_string(), 70).await.unwrap(); - addr - }; - (wallet_rpc, daemon_rpc, wallet_rpc_addr) + #[derive(Debug, Deserialize)] + struct AddressResponse { + address: String, + } + + let mut wallet_id = [0; 8]; + OsRng.fill_bytes(&mut wallet_id); + let _: EmptyResponse = wallet_rpc + .json_rpc_call( + "create_wallet", + Some(json!({ "filename": hex::encode(wallet_id), "language": "English" })), + ) + .await + .unwrap(); + + let address: AddressResponse = + wallet_rpc.json_rpc_call("get_address", Some(json!({ "account_index": 0 }))).await.unwrap(); + + // Fund the new wallet + daemon_rpc.generate_blocks(&address.address, 70).await.unwrap(); + + (wallet_rpc, daemon_rpc, address.address) } async fn from_wallet_rpc_to_self(spec: AddressSpec) { @@ -70,19 +68,25 @@ async fn from_wallet_rpc_to_self(spec: AddressSpec) { // make an addr let (_, view_pair, _) = runner::random_address(); - let addr = Address::from_str(&view_pair.address(Network::Mainnet, spec).to_string()).unwrap(); + let addr = view_pair.address(Network::Mainnet, spec); // refresh & make a tx - wallet_rpc.refresh(None).await.unwrap(); - let tx = wallet_rpc - .transfer( - HashMap::from([(addr, Amount::ONE_XMR)]), - monero_rpc::TransferPriority::Default, - TransferOptions::default(), + let _: EmptyResponse = wallet_rpc.json_rpc_call("refresh", None).await.unwrap(); + + #[derive(Debug, Deserialize)] + struct TransferResponse { + tx_hash: String, + } + let tx: TransferResponse = wallet_rpc + .json_rpc_call( + "transfer", + Some(json!({ + "destinations": [{"address": addr.to_string(), "amount": 1_000_000_000_000u64 }], + })), ) .await .unwrap(); - let tx_hash: [u8; 32] = tx.tx_hash.0.try_into().unwrap(); + let tx_hash = hex::decode(tx.tx_hash).unwrap().try_into().unwrap(); // TODO: Needs https://github.com/monero-project/monero/pull/8882 // let fee_rate = daemon_rpc @@ -93,7 +97,7 @@ async fn from_wallet_rpc_to_self(spec: AddressSpec) { // .unwrap(); // unlock it - runner::mine_until_unlocked(&daemon_rpc, &wallet_rpc_addr.to_string(), tx_hash).await; + runner::mine_until_unlocked(&daemon_rpc, &wallet_rpc_addr, tx_hash).await; // Create the scanner let mut scanner = Scanner::from_view(view_pair, Some(HashSet::new())); @@ -137,6 +141,24 @@ async_sequential!( } ); +#[derive(PartialEq, Eq, Debug, Deserialize)] +struct Index { + major: u32, + minor: u32, +} + +#[derive(Debug, Deserialize)] +struct Transfer { + payment_id: String, + subaddr_index: Index, + amount: u64, +} + +#[derive(Debug, Deserialize)] +struct TransfersResponse { + transfer: Transfer, +} + test!( send_to_wallet_rpc_standard, ( @@ -145,19 +167,19 @@ test!( let (wallet_rpc, _, wallet_rpc_addr) = initialize_rpcs().await; // add destination - builder.add_payment( - MoneroAddress::from_str(Network::Mainnet, &wallet_rpc_addr.to_string()).unwrap(), - 1000000, - ); - (builder.build().unwrap(), (wallet_rpc,)) + builder + .add_payment(MoneroAddress::from_str(Network::Mainnet, &wallet_rpc_addr).unwrap(), 1000000); + (builder.build().unwrap(), wallet_rpc) }, - |_, tx: Transaction, _, data: (WalletClient,)| async move { + |_, tx: Transaction, _, data: Rpc| async move { // confirm receipt - data.0.refresh(None).await.unwrap(); - let transfer = - data.0.get_transfer(Hash::from_slice(&tx.hash()), None).await.unwrap().unwrap(); - assert_eq!(transfer.amount.as_pico(), 1000000); - assert_eq!(transfer.subaddr_index, Index { major: 0, minor: 0 }); + let _: EmptyResponse = data.json_rpc_call("refresh", None).await.unwrap(); + let transfer: TransfersResponse = data + .json_rpc_call("get_transfer_by_txid", Some(json!({ "txid": hex::encode(tx.hash()) }))) + .await + .unwrap(); + assert_eq!(transfer.transfer.subaddr_index, Index { major: 0, minor: 0 }); + assert_eq!(transfer.transfer.amount, 1000000); }, ), ); @@ -169,22 +191,32 @@ test!( // initialize rpc let (wallet_rpc, _, _) = initialize_rpcs().await; - // make the addr - let (subaddress, index) = wallet_rpc.create_address(0, None).await.unwrap(); + // make the subaddress + #[derive(Debug, Deserialize)] + struct AccountResponse { + address: String, + account_index: u32, + } + let addr: AccountResponse = wallet_rpc.json_rpc_call("create_account", None).await.unwrap(); + assert!(addr.account_index != 0); - builder.add_payment( - MoneroAddress::from_str(Network::Mainnet, &subaddress.to_string()).unwrap(), - 1000000, - ); - (builder.build().unwrap(), (wallet_rpc, index)) + builder + .add_payment(MoneroAddress::from_str(Network::Mainnet, &addr.address).unwrap(), 1000000); + (builder.build().unwrap(), (wallet_rpc, addr.account_index)) }, - |_, tx: Transaction, _, data: (WalletClient, u32)| async move { + |_, tx: Transaction, _, data: (Rpc, u32)| async move { // confirm receipt - data.0.refresh(None).await.unwrap(); - let transfer = - data.0.get_transfer(Hash::from_slice(&tx.hash()), None).await.unwrap().unwrap(); - assert_eq!(transfer.amount.as_pico(), 1000000); - assert_eq!(transfer.subaddr_index, Index { major: 0, minor: data.1 }); + let _: EmptyResponse = data.0.json_rpc_call("refresh", None).await.unwrap(); + let transfer: TransfersResponse = data + .0 + .json_rpc_call( + "get_transfer_by_txid", + Some(json!({ "txid": hex::encode(tx.hash()), "account_index": data.1 })), + ) + .await + .unwrap(); + assert_eq!(transfer.transfer.subaddr_index, Index { major: data.1, minor: 0 }); + assert_eq!(transfer.transfer.amount, 1000000); // Make sure only one R was included in TX extra assert!(Extra::read::<&[u8]>(&mut tx.prefix.extra.as_ref()) @@ -207,19 +239,22 @@ test!( // make the addr let mut payment_id = [0u8; 8]; OsRng.fill_bytes(&mut payment_id); - let addr = make_integrated_address(payment_id).await; + let addr = make_integrated_address(&wallet_rpc, payment_id).await; builder.add_payment(MoneroAddress::from_str(Network::Mainnet, &addr).unwrap(), 1000000); (builder.build().unwrap(), (wallet_rpc, payment_id)) }, - |_, tx: Transaction, _, data: (WalletClient, [u8; 8])| async move { + |_, tx: Transaction, _, data: (Rpc, [u8; 8])| async move { // confirm receipt - data.0.refresh(None).await.unwrap(); - let transfer = - data.0.get_transfer(Hash::from_slice(&tx.hash()), None).await.unwrap().unwrap(); - assert_eq!(transfer.amount.as_pico(), 1000000); - assert_eq!(transfer.subaddr_index, Index { major: 0, minor: 0 }); - assert_eq!(transfer.payment_id.0, PaymentId::from_slice(&data.1)); + let _: EmptyResponse = data.0.json_rpc_call("refresh", None).await.unwrap(); + let transfer: TransfersResponse = data + .0 + .json_rpc_call("get_transfer_by_txid", Some(json!({ "txid": hex::encode(tx.hash()) }))) + .await + .unwrap(); + assert_eq!(transfer.transfer.subaddr_index, Index { major: 0, minor: 0 }); + assert_eq!(transfer.transfer.payment_id, hex::encode(data.1)); + assert_eq!(transfer.transfer.amount, 1000000); }, ), ); @@ -232,10 +267,8 @@ test!( let (wallet_rpc, _, wallet_rpc_addr) = initialize_rpcs().await; // add destination - builder.add_payment( - MoneroAddress::from_str(Network::Mainnet, &wallet_rpc_addr.to_string()).unwrap(), - 1000000, - ); + builder + .add_payment(MoneroAddress::from_str(Network::Mainnet, &wallet_rpc_addr).unwrap(), 1000000); // Make 2 data that is the full 255 bytes for _ in 0 .. 2 { @@ -244,15 +277,17 @@ test!( builder.add_data(data).unwrap(); } - (builder.build().unwrap(), (wallet_rpc,)) + (builder.build().unwrap(), wallet_rpc) }, - |_, tx: Transaction, _, data: (WalletClient,)| async move { + |_, tx: Transaction, _, data: Rpc| async move { // confirm receipt - data.0.refresh(None).await.unwrap(); - let transfer = - data.0.get_transfer(Hash::from_slice(&tx.hash()), None).await.unwrap().unwrap(); - assert_eq!(transfer.amount.as_pico(), 1000000); - assert_eq!(transfer.subaddr_index, Index { major: 0, minor: 0 }); + let _: EmptyResponse = data.json_rpc_call("refresh", None).await.unwrap(); + let transfer: TransfersResponse = data + .json_rpc_call("get_transfer_by_txid", Some(json!({ "txid": hex::encode(tx.hash()) }))) + .await + .unwrap(); + assert_eq!(transfer.transfer.subaddr_index, Index { major: 0, minor: 0 }); + assert_eq!(transfer.transfer.amount, 1000000); }, ), );