Correct misc TODOs in monero-serai

This commit is contained in:
Luke Parker
2024-07-05 23:30:02 -04:00
parent 90880cc9c8
commit 1f5e5fc7ac
27 changed files with 266 additions and 111 deletions

View File

@@ -155,8 +155,7 @@ async fn select_decoys<R: RngCore + CryptoRng>(
if distribution.len() < height {
// TODO: verify distribution elems are strictly increasing
let extension =
rpc.get_output_distribution(distribution.len(), height.saturating_sub(1)).await?;
let extension = rpc.get_output_distribution(distribution.len() .. height).await?;
distribution.extend(extension);
}
// If asked to use an older height than previously asked, truncate to ensure accuracy

View File

@@ -1,15 +1,12 @@
use std_shims::{vec, vec::Vec};
use rand_core::SeedableRng;
use rand_chacha::ChaCha20Rng;
use curve25519_dalek::{
constants::{ED25519_BASEPOINT_POINT, ED25519_BASEPOINT_TABLE},
Scalar, EdwardsPoint,
};
use crate::{
io::varint_len,
io::{varint_len, write_varint},
primitives::Commitment,
ringct::{
clsag::Clsag, bulletproofs::Bulletproof, EncryptedAmount, RctType, RctBase, RctPrunable,
@@ -138,17 +135,69 @@ impl SignableTransaction {
bp_commitments.push(Commitment::zero());
commitments.push(ED25519_BASEPOINT_POINT);
}
// TODO: Remove this. Deserialize an empty BP?
let bulletproof = (match self.rct_type {
let padded_log2 = {
let mut log2_find = 0;
while (1 << log2_find) < self.payments.len() {
log2_find += 1;
}
log2_find
};
// This is log2 the padded amount of IPA rows
// We have 64 rows per commitment, so we need 64 * c IPA rows
// We rewrite this as 2**6 * c
// By finding the padded log2 of c, we get 2**6 * 2**p
// This declares the log2 to be 6 + p
let lr_len = 6 + padded_log2;
let bulletproof = match self.rct_type {
RctType::ClsagBulletproof => {
Bulletproof::prove(&mut ChaCha20Rng::from_seed([0; 32]), &bp_commitments)
let mut bp = Vec::with_capacity(((9 + (2 * lr_len)) * 32) + 2);
let push_point = |bp: &mut Vec<u8>| {
bp.push(1);
bp.extend([0; 31]);
};
let push_scalar = |bp: &mut Vec<u8>| bp.extend([0; 32]);
for _ in 0 .. 4 {
push_point(&mut bp);
}
for _ in 0 .. 2 {
push_scalar(&mut bp);
}
for _ in 0 .. 2 {
write_varint(&lr_len, &mut bp).unwrap();
for _ in 0 .. lr_len {
push_point(&mut bp);
}
}
for _ in 0 .. 3 {
push_scalar(&mut bp);
}
Bulletproof::read(&mut bp.as_slice()).expect("made an invalid dummy BP")
}
RctType::ClsagBulletproofPlus => {
Bulletproof::prove_plus(&mut ChaCha20Rng::from_seed([0; 32]), bp_commitments)
let mut bp = Vec::with_capacity(((6 + (2 * lr_len)) * 32) + 2);
let push_point = |bp: &mut Vec<u8>| {
bp.push(1);
bp.extend([0; 31]);
};
let push_scalar = |bp: &mut Vec<u8>| bp.extend([0; 32]);
for _ in 0 .. 3 {
push_point(&mut bp);
}
for _ in 0 .. 3 {
push_scalar(&mut bp);
}
for _ in 0 .. 2 {
write_varint(&lr_len, &mut bp).unwrap();
for _ in 0 .. lr_len {
push_point(&mut bp);
}
}
Bulletproof::read_plus(&mut bp.as_slice()).expect("made an invalid dummy BP+")
}
_ => panic!("unsupported RctType"),
})
.expect("couldn't prove BP(+)s for this many payments despite checking in constructor?");
};
// `- 1` to remove the one byte for the 0 fee
Transaction::V2 {

View File

@@ -64,7 +64,11 @@ pub fn random_guaranteed_address() -> (Scalar, GuaranteedViewPair, 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: &SimpleRequestRpc, addr: &str, tx_hash: [u8; 32]) -> Block {
pub async fn mine_until_unlocked(
rpc: &SimpleRequestRpc,
addr: &MoneroAddress,
tx_hash: [u8; 32],
) -> Block {
// mine until tx is in a block
let mut height = rpc.get_height().await.unwrap();
let mut found = false;
@@ -105,7 +109,7 @@ pub async fn get_miner_tx_output(rpc: &SimpleRequestRpc, view: &ViewPair) -> Wal
// Mine 60 blocks to unlock a miner TX
let start = rpc.get_height().await.unwrap();
rpc.generate_blocks(&view.legacy_address(Network::Mainnet).to_string(), 60).await.unwrap();
rpc.generate_blocks(&view.legacy_address(Network::Mainnet), 60).await.unwrap();
let block = rpc.get_block_by_number(start).await.unwrap();
scanner.scan(rpc, &block).await.unwrap().ignore_additional_timelock().swap_remove(0)
@@ -138,8 +142,7 @@ pub async fn rpc() -> SimpleRequestRpc {
AddressType::Legacy,
&Scalar::random(&mut OsRng) * ED25519_BASEPOINT_TABLE,
&Scalar::random(&mut OsRng) * ED25519_BASEPOINT_TABLE,
)
.to_string();
);
// Mine 40 blocks to ensure decoy availability
rpc.generate_blocks(&addr, 40).await.unwrap();
@@ -312,7 +315,7 @@ macro_rules! test {
let signed = sign(tx).await;
rpc.publish_transaction(&signed).await.unwrap();
let block =
mine_until_unlocked(&rpc, &random_address().2.to_string(), signed.hash()).await;
mine_until_unlocked(&rpc, &random_address().2, signed.hash()).await;
let tx = rpc.get_transaction(signed.hash()).await.unwrap();
check_weight_and_fee(&tx, fee_rate);
let scanner = Scanner::new(view.clone());
@@ -333,7 +336,7 @@ macro_rules! test {
let signed = sign(tx).await;
rpc.publish_transaction(&signed).await.unwrap();
let block =
mine_until_unlocked(&rpc, &random_address().2.to_string(), signed.hash()).await;
mine_until_unlocked(&rpc, &random_address().2, signed.hash()).await;
let tx = rpc.get_transaction(signed.hash()).await.unwrap();
if stringify!($name) != "spend_one_input_to_two_outputs_no_change" {
// Skip weight and fee check for the above test because when there is no change,

View File

@@ -41,7 +41,7 @@ async fn make_integrated_address(rpc: &SimpleRequestRpc, payment_id: [u8; 8]) ->
res.integrated_address
}
async fn initialize_rpcs() -> (SimpleRequestRpc, SimpleRequestRpc, String) {
async fn initialize_rpcs() -> (SimpleRequestRpc, SimpleRequestRpc, MoneroAddress) {
let wallet_rpc = SimpleRequestRpc::new("http://127.0.0.1:18082".to_string()).await.unwrap();
let daemon_rpc = runner::rpc().await;
@@ -64,9 +64,10 @@ async fn initialize_rpcs() -> (SimpleRequestRpc, SimpleRequestRpc, String) {
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();
let address = MoneroAddress::from_str(Network::Mainnet, &address.address).unwrap();
daemon_rpc.generate_blocks(&address, 70).await.unwrap();
(wallet_rpc, daemon_rpc, address.address)
(wallet_rpc, daemon_rpc, address)
}
async fn from_wallet_rpc_to_self(spec: AddressSpec) {
@@ -184,8 +185,7 @@ test!(
let (wallet_rpc, _, wallet_rpc_addr) = initialize_rpcs().await;
// add destination
builder
.add_payment(MoneroAddress::from_str(Network::Mainnet, &wallet_rpc_addr).unwrap(), 1000000);
builder.add_payment(wallet_rpc_addr, 1000000);
(builder.build().unwrap(), wallet_rpc)
},
|_, _, tx: Transaction, _, data: SimpleRequestRpc| async move {
@@ -342,8 +342,7 @@ test!(
let (wallet_rpc, _, wallet_rpc_addr) = initialize_rpcs().await;
// add destination
builder
.add_payment(MoneroAddress::from_str(Network::Mainnet, &wallet_rpc_addr).unwrap(), 1000000);
builder.add_payment(wallet_rpc_addr, 1000000);
// Make 2 data that is the full 255 bytes
for _ in 0 .. 2 {