From d3e5bdcb59eed212b5c80a4ee5beaf0f0f017fa4 Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Thu, 27 May 2021 10:22:00 +1000 Subject: [PATCH] Spend from wallet that does not pick up transactions The code on this branch was used to publish a transaction that spends from a wallet that was created during a swap using `generate_from_keys` but did not pick up the lock transaction of the swap correctly. The transaction could be decoded properly with the view-key, so for now we assume there must be a problem in the `monero-wallet-rpc` when handling certain wallets. Further investigation is needed to reproduce this problem. This branch was used to spend them the lock transaction, to validate that the transaction can be spent. This was successfully achieved, however, the spending transaction that was published is unfortunately faulty (there is a problem with the outputs). The monero daemon accepted and included the transaction, but the monero wallet (through `monero-wallet-rpc`) is unable to process the transaction properly. Original Monero Stagenet lock transaction ID: `09e361acb3e6e71d627a945a30672776a6f8fec7c97f4cae5e09b0780b75c158` Stagenet Transaction ID that spends from the lock tx (the tx published through the integration test on this branch): `f111e906fd4ea3c25ae34d5c8ec68342bbed258c546ce74a839e14f34b591641` --- monero-rpc/src/monerod.rs | 2 +- monero-wallet/src/lib.rs | 10 ++--- monero-wallet/tests/integration_test.rs | 59 ++++++++++++------------- 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/monero-rpc/src/monerod.rs b/monero-rpc/src/monerod.rs index 7c0f8942..12bdcd31 100644 --- a/monero-rpc/src/monerod.rs +++ b/monero-rpc/src/monerod.rs @@ -30,7 +30,7 @@ impl Client { Self::new("127.0.0.1".to_owned(), port) } - fn new(host: String, port: u16) -> Result { + pub fn new(host: String, port: u16) -> Result { Ok(Self { inner: reqwest::ClientBuilder::new() .connection_verbose(true) diff --git a/monero-wallet/src/lib.rs b/monero-wallet/src/lib.rs index 1ba1ef41..a58de28d 100644 --- a/monero-wallet/src/lib.rs +++ b/monero-wallet/src/lib.rs @@ -90,7 +90,7 @@ impl ConfidentialTransactionBuilder { to.public_spend.decompress().unwrap(), ecdh_key, ) - .one_time_key(dbg!(next_index)), + .one_time_key(next_index), }, }; @@ -227,7 +227,7 @@ impl ConfidentialTransactionBuilder { let fake_responses = random_array(|| Scalar::random(rng)); let message = transaction.signature_hash().unwrap(); - let sig = monero::clsag::sign( + let (sig, _) = monero::clsag::sign( message.as_fixed_bytes(), self.actual_signing_key, signing_index, @@ -245,7 +245,7 @@ impl ConfidentialTransactionBuilder { transaction.rct_signatures.p.as_mut().unwrap().Clsags = vec![sig]; - dbg!(transaction) + transaction } } @@ -293,7 +293,7 @@ impl CalculateKeyOffsetBoundaries for monerod::Client { /// possible. async fn calculate_key_offset_boundaries(&self) -> Result<(VarInt, VarInt)> { let latest_block = self.get_block_count().await?; - let latest_spendable_block = latest_block.count - 100; + let latest_spendable_block = latest_block.count - 10; let block: GetBlockResponse = self.get_block(latest_spendable_block).await?; @@ -314,7 +314,7 @@ impl CalculateKeyOffsetBoundaries for monerod::Client { // let oldest_index = last_index - (last_index / 100) * 40; // oldest index must // be within last 40% TODO: CONFIRM THIS - Ok((VarInt(0), VarInt(last_index))) + Ok((VarInt(1000000), VarInt(last_index))) } } diff --git a/monero-wallet/tests/integration_test.rs b/monero-wallet/tests/integration_test.rs index ee8b716b..b0481058 100644 --- a/monero-wallet/tests/integration_test.rs +++ b/monero-wallet/tests/integration_test.rs @@ -2,7 +2,7 @@ use monero::ViewPair; use monero_harness::Monero; -use monero_rpc::monerod::MonerodRpc; +use monero_rpc::monerod::{Client, MonerodRpc}; use monero_wallet::{ CalculateKeyOffsetBoundaries, ConfidentialTransactionBuilder, FetchDecoyInputs, }; @@ -14,40 +14,31 @@ use testcontainers::clients::Cli; async fn monerod_integration_test() { let mut rng = rand::rngs::StdRng::from_seed([0u8; 32]); - let cli = Cli::default(); - let (monero, _monerod_container, _monero_wallet_rpc_containers) = - Monero::new(&cli, vec![]).await.unwrap(); + let s_a = monero::PrivateKey::from_canonical_bytes([ + 146, 74, 223, 240, 209, 247, 144, 163, 20, 194, 1, 57, 226, 43, 37, 91, 207, 19, 121, 71, + 156, 217, 25, 138, 86, 22, 4, 40, 160, 103, 146, 1, + ]) + .unwrap(); + let s_b = monero::PrivateKey::from_canonical_bytes([ + 172, 121, 31, 191, 236, 27, 215, 81, 213, 34, 185, 248, 161, 212, 138, 11, 73, 79, 251, + 205, 128, 70, 58, 232, 37, 71, 1, 110, 72, 114, 47, 6, + ]) + .unwrap(); let lock_kp = monero::KeyPair { - view: monero::PrivateKey::random(&mut rng), - spend: monero::PrivateKey::random(&mut rng), + view: monero::PrivateKey::from_canonical_bytes([ + 167, 4, 78, 117, 31, 113, 199, 197, 193, 40, 228, 194, 1, 190, 82, 210, 4, 141, 166, + 109, 55, 64, 127, 65, 181, 248, 126, 146, 224, 241, 111, 13, + ]) + .unwrap(), + spend: s_a + s_b, }; - let spend_amount = 999600000000; + let client = Client::new("localhost".to_string(), 38081).unwrap(); - let lock_address = monero::Address::from_keypair(monero::Network::Mainnet, &lock_kp); - - monero.init_miner().await.unwrap(); - let wallet = monero.wallet("miner").expect("wallet to exist"); - - let transfer = wallet - .transfer(&lock_address.to_string(), 1_000_000_000_000) - .await - .expect("lock to succeed"); - - let client = monero.monerod().client(); - - let miner_address = wallet - .address() - .await - .expect("miner address to exist") - .address; - client - .generateblocks(10, miner_address) - .await - .expect("can generate blocks"); - - let lock_tx_hash = transfer.tx_hash.parse().unwrap(); + let lock_tx_hash = "09e361acb3e6e71d627a945a30672776a6f8fec7c97f4cae5e09b0780b75c158" + .parse() + .unwrap(); let lock_tx = client .get_transactions(&[lock_tx_hash]) @@ -55,6 +46,7 @@ async fn monerod_integration_test() { .unwrap() .pop() .unwrap(); + let output_indices = client.get_o_indexes(lock_tx_hash).await.unwrap().o_indexes; let lock_vp = ViewPair::from(&lock_kp); @@ -64,6 +56,9 @@ async fn monerod_integration_test() { .unwrap() .pop() .unwrap(); + + dbg!(input_to_spend.amount().unwrap()); + let global_output_index = output_indices[input_to_spend.index()]; let (lower, upper) = client.calculate_key_offset_boundaries().await.unwrap(); @@ -87,7 +82,9 @@ async fn monerod_integration_test() { .await .unwrap(); - let target_address = "498AVruCDWgP9Az9LjMm89VWjrBrSZ2W2K3HFBiyzzrRjUJWUcCVxvY1iitfuKoek2FdX6MKGAD9Qb1G1P8QgR5jPmmt3Vj".parse().unwrap(); + let target_address = "58hKkN5JrirdNehmTXaHhTEg3N5zRYZ6Wb5g5jwDk3wRC4rtNCJvx7hENsbLmfPakC3spGhciosagdVbSqq9vfXsV3zusCn".parse().unwrap(); + + let spend_amount = 149720581473; let transaction = ConfidentialTransactionBuilder::new( input_to_spend,