From 06246618ab31d59e37daec8a04b75fd7a814f253 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 1 Jul 2024 18:48:10 -0400 Subject: [PATCH] Sync rest of repo with monero-serai changes --- coins/monero/wallet/src/send/mod.rs | 13 +- coins/monero/wallet/src/send/tx_keys.rs | 12 +- coins/monero/wallet/tests/runner/builder.rs | 10 +- coins/monero/wallet/tests/runner/mod.rs | 6 +- coins/monero/wallet/tests/scan.rs | 2 - coins/monero/wallet/tests/send.rs | 8 +- processor/src/networks/monero.rs | 134 +++++++++++--------- tests/full-stack/src/tests/mint_and_burn.rs | 35 ++--- tests/processor/src/lib.rs | 2 +- tests/processor/src/networks.rs | 42 +++--- 10 files changed, 140 insertions(+), 124 deletions(-) diff --git a/coins/monero/wallet/src/send/mod.rs b/coins/monero/wallet/src/send/mod.rs index eec719cc..88a93e2a 100644 --- a/coins/monero/wallet/src/send/mod.rs +++ b/coins/monero/wallet/src/send/mod.rs @@ -33,6 +33,7 @@ pub use eventuality::Eventuality; #[cfg(feature = "multisig")] mod multisig; +pub use multisig::TransactionMachine; pub(crate) fn key_image_sort(x: &EdwardsPoint, y: &EdwardsPoint) -> core::cmp::Ordering { x.compress().to_bytes().cmp(&y.compress().to_bytes()).reverse() @@ -164,8 +165,6 @@ pub enum SendError { error("not enough funds (inputs {inputs}, outputs {outputs}, fee {fee:?})") )] NotEnoughFunds { inputs: u64, outputs: u64, fee: Option }, - #[cfg_attr(feature = "std", error("invalid amount of key images specified"))] - InvalidAmountOfKeyImages, #[cfg_attr(feature = "std", error("wrong spend private key"))] WrongPrivateKey, #[cfg_attr( @@ -183,7 +182,7 @@ pub enum SendError { #[derive(Clone, PartialEq, Eq, Debug, Zeroize)] pub struct SignableTransaction { rct_type: RctType, - sender_view_key: Zeroizing, + outgoing_view_key: Zeroizing<[u8; 32]>, inputs: Vec<(SpendableOutput, Decoys)>, payments: Vec, data: Vec>, @@ -301,7 +300,7 @@ impl SignableTransaction { pub fn new( rct_type: RctType, - sender_view_key: Zeroizing, + outgoing_view_key: Zeroizing<[u8; 32]>, inputs: Vec<(SpendableOutput, Decoys)>, payments: Vec<(MoneroAddress, u64)>, change: Change, @@ -322,7 +321,7 @@ impl SignableTransaction { } let mut res = - SignableTransaction { rct_type, sender_view_key, inputs, payments, data, fee_rate }; + SignableTransaction { rct_type, outgoing_view_key, inputs, payments, data, fee_rate }; res.validate()?; // Shuffle the payments @@ -369,7 +368,7 @@ impl SignableTransaction { } write_byte(&u8::from(self.rct_type), w)?; - write_scalar(&self.sender_view_key, w)?; + w.write_all(self.outgoing_view_key.as_slice())?; write_vec(write_input, &self.inputs, w)?; write_vec(write_payment, &self.payments, w)?; write_vec(|data, w| write_vec(write_byte, data, w), &self.data, w)?; @@ -412,7 +411,7 @@ impl SignableTransaction { let res = SignableTransaction { rct_type: RctType::try_from(read_byte(r)?) .map_err(|()| io::Error::other("unsupported/invalid RctType"))?, - sender_view_key: Zeroizing::new(read_scalar(r)?), + outgoing_view_key: Zeroizing::new(read_bytes(r)?), inputs: read_vec(read_input, r)?, payments: read_vec(read_payment, r)?, data: read_vec(|r| read_vec(read_byte, r), r)?, diff --git a/coins/monero/wallet/src/send/tx_keys.rs b/coins/monero/wallet/src/send/tx_keys.rs index 458bf796..3568eb89 100644 --- a/coins/monero/wallet/src/send/tx_keys.rs +++ b/coins/monero/wallet/src/send/tx_keys.rs @@ -16,14 +16,14 @@ use crate::{ fn seeded_rng( dst: &'static [u8], - view_key: &Zeroizing, + outgoing_view_key: &Zeroizing<[u8; 32]>, output_keys: impl Iterator, ) -> ChaCha20Rng { // Apply the DST let mut transcript = Zeroizing::new(vec![u8::try_from(dst.len()).unwrap()]); transcript.extend(dst); - // Bind to the private view key to prevent foreign entities from rebuilding the transcript - transcript.extend(view_key.to_bytes()); + // Bind to the outgoing view key to prevent foreign entities from rebuilding the transcript + transcript.extend(outgoing_view_key.as_slice()); // Ensure uniqueness across transactions by binding to a use-once object // The output key is also binding to the output's key image, making this use-once for key in output_keys { @@ -34,7 +34,11 @@ fn seeded_rng( impl SignableTransaction { pub(crate) fn seeded_rng(&self, dst: &'static [u8]) -> ChaCha20Rng { - seeded_rng(dst, &self.sender_view_key, self.inputs.iter().map(|(input, _)| input.output.key())) + seeded_rng( + dst, + &self.outgoing_view_key, + self.inputs.iter().map(|(input, _)| input.output.key()), + ) } fn has_payments_to_subaddresses(&self) -> bool { diff --git a/coins/monero/wallet/tests/runner/builder.rs b/coins/monero/wallet/tests/runner/builder.rs index 9994f64d..713113c6 100644 --- a/coins/monero/wallet/tests/runner/builder.rs +++ b/coins/monero/wallet/tests/runner/builder.rs @@ -1,7 +1,5 @@ use zeroize::{Zeroize, Zeroizing}; -use curve25519_dalek::Scalar; - use monero_wallet::{ primitives::Decoys, ringct::RctType, @@ -16,7 +14,7 @@ use monero_wallet::{ #[derive(Clone, PartialEq, Eq, Zeroize, Debug)] pub struct SignableTransactionBuilder { rct_type: RctType, - sender_view_key: Zeroizing, + outgoing_view_key: Zeroizing<[u8; 32]>, inputs: Vec<(SpendableOutput, Decoys)>, payments: Vec<(MoneroAddress, u64)>, change: Change, @@ -27,13 +25,13 @@ pub struct SignableTransactionBuilder { impl SignableTransactionBuilder { pub fn new( rct_type: RctType, - sender_view_key: Zeroizing, + outgoing_view_key: Zeroizing<[u8; 32]>, change: Change, fee_rate: FeeRate, ) -> Self { Self { rct_type, - sender_view_key, + outgoing_view_key, inputs: vec![], payments: vec![], change, @@ -74,7 +72,7 @@ impl SignableTransactionBuilder { pub fn build(self) -> Result { SignableTransaction::new( self.rct_type, - self.sender_view_key, + self.outgoing_view_key, self.inputs, self.payments, self.change, diff --git a/coins/monero/wallet/tests/runner/mod.rs b/coins/monero/wallet/tests/runner/mod.rs index 1a91dd3f..7ee7af17 100644 --- a/coins/monero/wallet/tests/runner/mod.rs +++ b/coins/monero/wallet/tests/runner/mod.rs @@ -169,7 +169,7 @@ macro_rules! test { use std::collections::HashMap; use zeroize::Zeroizing; - use rand_core::OsRng; + use rand_core::{RngCore, OsRng}; use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar}; @@ -223,6 +223,8 @@ macro_rules! test { let rpc = rpc().await; let view_priv = Zeroizing::new(Scalar::random(&mut OsRng)); + let mut outgoing_view = Zeroizing::new([0; 32]); + OsRng.fill_bytes(outgoing_view.as_mut()); let view = ViewPair::new(spend_pub, view_priv.clone()); let addr = view.address(Network::Mainnet, AddressSpec::Legacy); @@ -236,7 +238,7 @@ macro_rules! test { let builder = SignableTransactionBuilder::new( rct_type, - view_priv, + outgoing_view, Change::new( &ViewPair::new( &Scalar::random(&mut OsRng) * ED25519_BASEPOINT_TABLE, diff --git a/coins/monero/wallet/tests/scan.rs b/coins/monero/wallet/tests/scan.rs index e0025976..d16ef62d 100644 --- a/coins/monero/wallet/tests/scan.rs +++ b/coins/monero/wallet/tests/scan.rs @@ -1,5 +1,3 @@ -use rand_core::RngCore; - use monero_serai::transaction::Transaction; use monero_wallet::{rpc::Rpc, address::SubaddressIndex, extra::PaymentId}; diff --git a/coins/monero/wallet/tests/send.rs b/coins/monero/wallet/tests/send.rs index 65163efd..4939757c 100644 --- a/coins/monero/wallet/tests/send.rs +++ b/coins/monero/wallet/tests/send.rs @@ -107,12 +107,14 @@ test!( use monero_wallet::rpc::FeePriority; let view_priv = Zeroizing::new(Scalar::random(&mut OsRng)); + let mut outgoing_view = Zeroizing::new([0; 32]); + OsRng.fill_bytes(outgoing_view.as_mut()); let change_view = ViewPair::new(&Scalar::random(&mut OsRng) * ED25519_BASEPOINT_TABLE, view_priv.clone()); let mut builder = SignableTransactionBuilder::new( rct_type, - view_priv, + outgoing_view, Change::new(&change_view, false), rpc.get_fee_rate(FeePriority::Unimportant).await.unwrap(), ); @@ -295,9 +297,11 @@ test!( |rct_type, rpc: SimpleRequestRpc, _, addr, outputs: Vec| async move { use monero_wallet::rpc::FeePriority; + let mut outgoing_view = Zeroizing::new([0; 32]); + OsRng.fill_bytes(outgoing_view.as_mut()); let mut builder = SignableTransactionBuilder::new( rct_type, - Zeroizing::new(Scalar::random(&mut OsRng)), + outgoing_view, Change::fingerprintable(None), rpc.get_fee_rate(FeePriority::Unimportant).await.unwrap(), ); diff --git a/processor/src/networks/monero.rs b/processor/src/networks/monero.rs index 626396ce..c2376282 100644 --- a/processor/src/networks/monero.rs +++ b/processor/src/networks/monero.rs @@ -15,14 +15,16 @@ use frost::{curve::Ed25519, ThresholdKeys}; use monero_simple_request_rpc::SimpleRequestRpc; use monero_wallet::{ + ringct::RctType, transaction::Transaction, block::Block, - Protocol, - rpc::{RpcError, Rpc}, - ViewPair, Scanner, + rpc::{FeeRate, RpcError, Rpc}, address::{Network as MoneroNetwork, SubaddressIndex, AddressSpec}, - FeeRate, SpendableOutput, Change, DecoySelection, Decoys, TransactionError, - SignableTransaction as MSignableTransaction, Eventuality, TransactionMachine, + ViewPair, DecoySelection, Decoys, + scan::{SpendableOutput, Scanner}, + send::{ + SendError, Change, SignableTransaction as MSignableTransaction, Eventuality, TransactionMachine, + }, }; use tokio::time::sleep; @@ -135,7 +137,7 @@ impl EventualityTrait for Eventuality { // Extra includess the one time keys which are derived from the plan ID, so a collision here is a // hash collision fn lookup(&self) -> Vec { - self.extra().to_vec() + self.extra() } fn read(reader: &mut R) -> io::Result { @@ -157,13 +159,10 @@ impl EventualityTrait for Eventuality { } #[derive(Clone, Debug)] -pub struct SignableTransaction { - transcript: RecommendedTranscript, - actual: MSignableTransaction, -} +pub struct SignableTransaction(MSignableTransaction); impl SignableTransactionTrait for SignableTransaction { fn fee(&self) -> u64 { - self.actual.fee() + self.0.fee() } } @@ -307,7 +306,7 @@ impl Monero { payments: &[Payment], change: &Option
, calculating_fee: bool, - ) -> Result, NetworkError> { + ) -> Result, NetworkError> { for payment in payments { assert_eq!(payment.balance.coin, Coin::Monero); } @@ -316,15 +315,13 @@ impl Monero { let block_for_fee = self.get_block(block_number).await?; let fee_rate = self.median_fee(&block_for_fee).await?; - // Get the protocol for the specified block number - #[cfg(not(test))] - let protocol = Protocol::try_from(block_for_fee.header.hardfork_version) - .map_err(|()| NetworkError::ConnectionError)?; - // If this is a test, we won't be using a mainnet node and need a distinct protocol - // determination - // Just use whatever the node expects - #[cfg(test)] - let protocol = Protocol::try_from(self.rpc.get_protocol().await.unwrap()).unwrap(); + // Determine the RCT proofs to make based off the hard fork + // TODO: Make a fn for this block which is duplicated with tests + let rct_type = match block_for_fee.header.hardfork_version { + 14 => RctType::ClsagBulletproof, + 15 | 16 => RctType::ClsagBulletproofPlus, + _ => panic!("Monero hard forked and the processor wasn't updated for it"), + }; let spendable_outputs = inputs.iter().map(|input| input.0.clone()).collect::>(); @@ -337,7 +334,12 @@ impl Monero { let decoys = Decoys::fingerprintable_canonical_select( &mut ChaCha20Rng::from_seed(transcript.rng_seed(b"decoys")), &self.rpc, - protocol.ring_len(), + // TODO: Have Decoys take RctType + match rct_type { + RctType::ClsagBulletproof => 11, + RctType::ClsagBulletproofPlus => 16, + _ => panic!("selecting decoys for an unsupported RctType"), + }, block_number + 1, &spendable_outputs, ) @@ -356,7 +358,7 @@ impl Monero { payments.push(Payment { address: Address::new( ViewPair::new(EdwardsPoint::generator().0, Zeroizing::new(Scalar::ONE.0)) - .address(MoneroNetwork::Mainnet, AddressSpec::Standard), + .address(MoneroNetwork::Mainnet, AddressSpec::Legacy), ) .unwrap(), balance: Balance { coin: Coin::Monero, amount: Amount(0) }, @@ -374,48 +376,43 @@ impl Monero { .collect::>(); match MSignableTransaction::new( - protocol, - // Use the plan ID as the r_seed - // This perfectly binds the plan while simultaneously allowing verifying the plan was - // executed with no additional communication - Some(Zeroizing::new(*plan_id)), + rct_type, + // Use the plan ID as the outgoing view key + Zeroizing::new(*plan_id), inputs.clone(), payments, - &Change::fingerprintable(change.as_ref().map(|change| change.clone().into())), + Change::fingerprintable(change.as_ref().map(|change| change.clone().into())), vec![], fee_rate, ) { - Ok(signable) => Ok(Some((transcript, signable))), + Ok(signable) => Ok(Some(signable)), Err(e) => match e { - TransactionError::MultiplePaymentIds => { - panic!("multiple payment IDs despite not supporting integrated addresses"); + SendError::UnsupportedRctType => { + panic!("trying to use an RctType unsupported by monero-wallet") } - TransactionError::NoInputs | - TransactionError::NoOutputs | - TransactionError::InvalidDecoyQuantity | - TransactionError::NoChange | - TransactionError::TooManyOutputs | - TransactionError::TooMuchData | - TransactionError::TooLargeTransaction | - TransactionError::WrongPrivateKey => { + SendError::NoInputs | + SendError::InvalidDecoyQuantity | + SendError::NoOutputs | + SendError::TooManyOutputs | + SendError::NoChange | + SendError::TooMuchData | + SendError::TooLargeTransaction | + SendError::WrongPrivateKey => { panic!("created an Monero invalid transaction: {e}"); } - TransactionError::ClsagError(_) | - TransactionError::InvalidTransaction(_) | - TransactionError::FrostError(_) => { - panic!("supposedly unreachable (at this time) Monero error: {e}"); + SendError::MultiplePaymentIds => { + panic!("multiple payment IDs despite not supporting integrated addresses"); } - TransactionError::NotEnoughFunds { inputs, outputs, fee } => { + SendError::NotEnoughFunds { inputs, outputs, fee } => { log::debug!( - "Monero NotEnoughFunds. inputs: {:?}, outputs: {:?}, fee: {fee}", + "Monero NotEnoughFunds. inputs: {:?}, outputs: {:?}, fee: {fee:?}", inputs, outputs ); Ok(None) } - TransactionError::RpcError(e) => { - log::error!("RpcError when preparing transaction: {e:?}"); - Err(map_rpc_err(e)) + SendError::MaliciousSerialization | SendError::ClsagError(_) | SendError::FrostError(_) => { + panic!("supposedly unreachable (at this time) Monero error: {e}"); } }, } @@ -433,7 +430,7 @@ impl Monero { #[cfg(test)] fn test_address() -> Address { - Address::new(Self::test_view_pair().address(MoneroNetwork::Mainnet, AddressSpec::Standard)) + Address::new(Self::test_view_pair().address(MoneroNetwork::Mainnet, AddressSpec::Legacy)) .unwrap() } } @@ -627,7 +624,7 @@ impl Network for Monero { self .make_signable_transaction(block_number, &[0; 32], inputs, payments, change, true) .await? - .map(|(_, signable)| signable.fee()), + .map(|signable| signable.fee()), ) } @@ -645,9 +642,9 @@ impl Network for Monero { self .make_signable_transaction(block_number, plan_id, inputs, payments, change, false) .await? - .map(|(transcript, signable)| { - let signable = SignableTransaction { transcript, actual: signable }; - let eventuality = signable.actual.eventuality().unwrap(); + .map(|signable| { + let signable = SignableTransaction(signable); + let eventuality = signable.0.clone().into(); (signable, eventuality) }), ) @@ -658,7 +655,7 @@ impl Network for Monero { keys: ThresholdKeys, transaction: SignableTransaction, ) -> Result { - match transaction.actual.clone().multisig(&keys, transaction.transcript) { + match transaction.0.clone().multisig(&keys) { Ok(machine) => Ok(machine), Err(e) => panic!("failed to create a multisig machine for TX: {e}"), } @@ -746,16 +743,17 @@ impl Network for Monero { #[cfg(test)] async fn test_send(&self, address: Address) -> Block { use zeroize::Zeroizing; - use rand_core::OsRng; - use monero_wallet::FeePriority; + use rand_core::{RngCore, OsRng}; + use monero_wallet::rpc::FeePriority; let new_block = self.get_latest_block_number().await.unwrap() + 1; for _ in 0 .. 80 { self.mine_block().await; } + let new_block = self.rpc.get_block_by_number(new_block).await.unwrap(); let outputs = Self::test_scanner() - .scan(&self.rpc, &self.rpc.get_block_by_number(new_block).await.unwrap()) + .scan(&self.rpc, &new_block) .await .unwrap() .swap_remove(0) @@ -765,12 +763,20 @@ impl Network for Monero { // The dust should always be sufficient for the fee let fee = Monero::DUST; - let protocol = Protocol::try_from(self.rpc.get_protocol().await.unwrap()).unwrap(); + let rct_type = match new_block.header.hardfork_version { + 14 => RctType::ClsagBulletproof, + 15 | 16 => RctType::ClsagBulletproofPlus, + _ => panic!("Monero hard forked and the processor wasn't updated for it"), + }; let decoys = Decoys::fingerprintable_canonical_select( &mut OsRng, &self.rpc, - protocol.ring_len(), + match rct_type { + RctType::ClsagBulletproof => 11, + RctType::ClsagBulletproofPlus => 16, + _ => panic!("selecting decoys for an unsupported RctType"), + }, self.rpc.get_height().await.unwrap(), &outputs, ) @@ -779,12 +785,14 @@ impl Network for Monero { let inputs = outputs.into_iter().zip(decoys).collect::>(); + let mut outgoing_view_key = Zeroizing::new([0; 32]); + OsRng.fill_bytes(outgoing_view_key.as_mut()); let tx = MSignableTransaction::new( - protocol, - None, + rct_type, + outgoing_view_key, inputs, vec![(address.into(), amount - fee)], - &Change::fingerprintable(Some(Self::test_address().into())), + Change::fingerprintable(Some(Self::test_address().into())), vec![], self.rpc.get_fee_rate(FeePriority::Unimportant).await.unwrap(), ) diff --git a/tests/full-stack/src/tests/mint_and_burn.rs b/tests/full-stack/src/tests/mint_and_burn.rs index be9224ac..77515a9a 100644 --- a/tests/full-stack/src/tests/mint_and_burn.rs +++ b/tests/full-stack/src/tests/mint_and_burn.rs @@ -95,7 +95,7 @@ async fn mint_and_burn_test() { }; let addr = ViewPair::new(ED25519_BASEPOINT_POINT, Zeroizing::new(Scalar::ONE)) - .address(Network::Mainnet, AddressSpec::Standard) + .address(Network::Mainnet, AddressSpec::Legacy) .to_string(); let rpc = producer_handles.monero(ops).await; @@ -350,11 +350,13 @@ async fn mint_and_burn_test() { use curve25519_dalek::{constants::ED25519_BASEPOINT_POINT, scalar::Scalar}; use monero_wallet::{ io::decompress_point, + ringct::RctType, transaction::Timelock, - Protocol, - rpc::Rpc, - ViewPair, Scanner, DecoySelection, Decoys, Change, FeePriority, SignableTransaction, - address::{Network, AddressType, AddressMeta, MoneroAddress}, + rpc::{FeePriority, Rpc}, + ViewPair, DecoySelection, Decoys, + address::{Network, AddressType, MoneroAddress}, + scan::Scanner, + send::{Change, SignableTransaction}, }; // Grab the first output on the chain @@ -373,7 +375,7 @@ async fn mint_and_burn_test() { let decoys = Decoys::fingerprintable_canonical_select( &mut OsRng, &rpc, - Protocol::v16.ring_len(), + 16, rpc.get_height().await.unwrap(), &[output.clone()], ) @@ -381,23 +383,23 @@ async fn mint_and_burn_test() { .unwrap() .swap_remove(0); + let mut outgoing_view_key = Zeroizing::new([0; 32]); + OsRng.fill_bytes(outgoing_view_key.as_mut()); let tx = SignableTransaction::new( - Protocol::v16, - None, + RctType::ClsagBulletproofPlus, + outgoing_view_key, vec![(output, decoys)], vec![( MoneroAddress::new( - AddressMeta::new( - Network::Mainnet, - AddressType::Featured { guaranteed: true, subaddress: false, payment_id: None }, - ), + Network::Mainnet, + AddressType::Featured { guaranteed: true, subaddress: false, payment_id: None }, decompress_point(monero_key_pair.1.to_vec().try_into().unwrap()).unwrap(), ED25519_BASEPOINT_POINT * processor::additional_key::(0).0, ), 1_100_000_000_000, )], - &Change::new(&view_pair, false), + Change::new(&view_pair, false), vec![Shorthand::transfer(None, serai_addr).encode()], rpc.get_fee_rate(FeePriority::Unimportant).await.unwrap(), ) @@ -475,9 +477,10 @@ async fn mint_and_burn_test() { let spend = ED25519_BASEPOINT_TABLE * &Scalar::random(&mut OsRng); let view = Scalar::random(&mut OsRng); - use monero_wallet::address::{Network, AddressType, AddressMeta, MoneroAddress}; + use monero_wallet::address::{Network, AddressType, MoneroAddress}; let addr = MoneroAddress::new( - AddressMeta::new(Network::Mainnet, AddressType::Standard), + Network::Mainnet, + AddressType::Legacy, spend, ED25519_BASEPOINT_TABLE * &view, ); @@ -583,7 +586,7 @@ async fn mint_and_burn_test() { // Verify the received Monero TX { - use monero_wallet::{transaction::Transaction, rpc::Rpc, ViewPair, Scanner}; + use monero_wallet::{transaction::Transaction, rpc::Rpc, ViewPair, scan::Scanner}; let rpc = handles[0].monero(&ops).await; let mut scanner = Scanner::from_view( ViewPair::new(monero_spend, Zeroizing::new(monero_view)), diff --git a/tests/processor/src/lib.rs b/tests/processor/src/lib.rs index 431b5609..1273af21 100644 --- a/tests/processor/src/lib.rs +++ b/tests/processor/src/lib.rs @@ -419,7 +419,7 @@ impl Coordinator { "wallet_address": ViewPair::new( ED25519_BASEPOINT_POINT, Zeroizing::new(Scalar::ONE), - ).address(Network::Mainnet, AddressSpec::Standard).to_string(), + ).address(Network::Mainnet, AddressSpec::Legacy).to_string(), "amount_of_blocks": 1, })), ) diff --git a/tests/processor/src/networks.rs b/tests/processor/src/networks.rs index 2bb23067..38af993d 100644 --- a/tests/processor/src/networks.rs +++ b/tests/processor/src/networks.rs @@ -104,7 +104,7 @@ pub enum Wallet { handle: String, spend_key: Zeroizing, view_pair: monero_wallet::ViewPair, - inputs: Vec, + inputs: Vec, }, } @@ -192,8 +192,9 @@ impl Wallet { use monero_simple_request_rpc::SimpleRequestRpc; use monero_wallet::{ rpc::Rpc, - ViewPair, Scanner, address::{Network, AddressSpec}, + ViewPair, + scan::Scanner, }; let mut bytes = [0; 64]; @@ -215,7 +216,7 @@ impl Wallet { Some(serde_json::json!({ "wallet_address": view_pair.address( Network::Mainnet, - AddressSpec::Standard + AddressSpec::Legacy ).to_string(), "amount_of_blocks": 200, })), @@ -438,11 +439,12 @@ impl Wallet { use monero_simple_request_rpc::SimpleRequestRpc; use monero_wallet::{ io::decompress_point, - rpc::Rpc, - Protocol, - address::{Network, AddressType, AddressMeta, Address}, - SpendableOutput, DecoySelection, Decoys, Change, FeePriority, Scanner, - SignableTransaction, + ringct::RctType, + rpc::{FeePriority, Rpc}, + address::{Network, AddressType, Address}, + DecoySelection, Decoys, + scan::{SpendableOutput, Scanner}, + send::{Change, SignableTransaction}, }; use processor::{additional_key, networks::Monero}; @@ -462,7 +464,7 @@ impl Wallet { let mut decoys = Decoys::fingerprintable_canonical_select( &mut OsRng, &rpc, - Protocol::v16.ring_len(), + 16, rpc.get_height().await.unwrap(), &these_inputs, ) @@ -472,10 +474,8 @@ impl Wallet { let to_spend_key = decompress_point(<[u8; 32]>::try_from(to.as_ref()).unwrap()).unwrap(); let to_view_key = additional_key::(0); let to_addr = Address::new( - AddressMeta::new( - Network::Mainnet, - AddressType::Featured { subaddress: false, payment_id: None, guaranteed: true }, - ), + Network::Mainnet, + AddressType::Featured { subaddress: false, payment_id: None, guaranteed: true }, to_spend_key, ED25519_BASEPOINT_POINT * to_view_key.0, ); @@ -486,12 +486,14 @@ impl Wallet { if let Some(instruction) = instruction { data.push(Shorthand::Raw(RefundableInInstruction { origin: None, instruction }).encode()); } + let mut outgoing_view_key = Zeroizing::new([0; 32]); + OsRng.fill_bytes(outgoing_view_key.as_mut()); let tx = SignableTransaction::new( - Protocol::v16, - None, + RctType::ClsagBulletproofPlus, + outgoing_view_key, these_inputs.drain(..).zip(decoys.drain(..)).collect(), vec![(to_addr, AMOUNT)], - &Change::new(view_pair, false), + Change::new(view_pair, false), data, rpc.get_fee_rate(FeePriority::Unimportant).await.unwrap(), ) @@ -532,11 +534,9 @@ impl Wallet { Wallet::Monero { view_pair, .. } => { use monero_wallet::address::{Network, AddressSpec}; ExternalAddress::new( - networks::monero::Address::new( - view_pair.address(Network::Mainnet, AddressSpec::Standard), - ) - .unwrap() - .into(), + networks::monero::Address::new(view_pair.address(Network::Mainnet, AddressSpec::Legacy)) + .unwrap() + .into(), ) .unwrap() }