De-duplicate compact Sapling output creation in `TestState`
This commit is contained in:
parent
f306a0a78a
commit
bc0b1aed07
|
@ -7,7 +7,7 @@ use std::fs::File;
|
||||||
|
|
||||||
use nonempty::NonEmpty;
|
use nonempty::NonEmpty;
|
||||||
use prost::Message;
|
use prost::Message;
|
||||||
use rand_core::{OsRng, RngCore};
|
use rand_core::{CryptoRng, OsRng, RngCore};
|
||||||
use rusqlite::{params, Connection};
|
use rusqlite::{params, Connection};
|
||||||
use secrecy::{Secret, SecretVec};
|
use secrecy::{Secret, SecretVec};
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
|
@ -18,7 +18,6 @@ use tempfile::TempDir;
|
||||||
use sapling::{
|
use sapling::{
|
||||||
note_encryption::{sapling_note_encryption, SaplingDomain},
|
note_encryption::{sapling_note_encryption, SaplingDomain},
|
||||||
util::generate_random_rseed,
|
util::generate_random_rseed,
|
||||||
value::NoteValue,
|
|
||||||
zip32::DiversifiableFullViewingKey,
|
zip32::DiversifiableFullViewingKey,
|
||||||
Note, Nullifier, PaymentAddress,
|
Note, Nullifier, PaymentAddress,
|
||||||
};
|
};
|
||||||
|
@ -765,6 +764,49 @@ pub(crate) enum AddressType {
|
||||||
Internal,
|
Internal,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a `CompactSaplingOutput` at the given height paying the given recipient.
|
||||||
|
///
|
||||||
|
/// Returns the `CompactSaplingOutput` and the new note.
|
||||||
|
fn compact_sapling_output<P: consensus::Parameters, R: RngCore + CryptoRng>(
|
||||||
|
params: &P,
|
||||||
|
height: BlockHeight,
|
||||||
|
recipient: sapling::PaymentAddress,
|
||||||
|
value: NonNegativeAmount,
|
||||||
|
ovk: sapling::keys::OutgoingViewingKey,
|
||||||
|
rng: &mut R,
|
||||||
|
) -> (CompactSaplingOutput, sapling::Note) {
|
||||||
|
let rseed = generate_random_rseed(zip212_enforcement(params, height), rng);
|
||||||
|
let note = Note::from_parts(
|
||||||
|
recipient,
|
||||||
|
sapling::value::NoteValue::from_raw(value.into_u64()),
|
||||||
|
rseed,
|
||||||
|
);
|
||||||
|
let encryptor =
|
||||||
|
sapling_note_encryption(Some(ovk), note.clone(), *MemoBytes::empty().as_array(), rng);
|
||||||
|
let cmu = note.cmu().to_bytes().to_vec();
|
||||||
|
let ephemeral_key = SaplingDomain::epk_bytes(encryptor.epk()).0.to_vec();
|
||||||
|
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
||||||
|
|
||||||
|
(
|
||||||
|
CompactSaplingOutput {
|
||||||
|
cmu,
|
||||||
|
ephemeral_key,
|
||||||
|
ciphertext: enc_ciphertext.as_ref()[..52].to_vec(),
|
||||||
|
},
|
||||||
|
note,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a fake `CompactTx` with a random transaction ID and no spends or outputs.
|
||||||
|
fn fake_compact_tx<R: RngCore + CryptoRng>(rng: &mut R) -> CompactTx {
|
||||||
|
let mut ctx = CompactTx::default();
|
||||||
|
let mut txid = vec![0; 32];
|
||||||
|
rng.fill_bytes(&mut txid);
|
||||||
|
ctx.hash = txid;
|
||||||
|
|
||||||
|
ctx
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a fake CompactBlock at the given height, containing a single output paying
|
/// Create a fake CompactBlock at the given height, containing a single output paying
|
||||||
/// an address. Returns the CompactBlock and the nullifier for the new note.
|
/// an address. Returns the CompactBlock and the nullifier for the new note.
|
||||||
fn fake_compact_block<P: consensus::Parameters>(
|
fn fake_compact_block<P: consensus::Parameters>(
|
||||||
|
@ -784,45 +826,14 @@ fn fake_compact_block<P: consensus::Parameters>(
|
||||||
|
|
||||||
// Create a fake Note for the account
|
// Create a fake Note for the account
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
let rseed = generate_random_rseed(zip212_enforcement(params, height), &mut rng);
|
let (cout, note) = compact_sapling_output(params, height, to, value, dfvk.fvk().ovk, &mut rng);
|
||||||
let note = Note::from_parts(to, NoteValue::from_raw(value.into_u64()), rseed);
|
|
||||||
let encryptor = sapling_note_encryption(
|
|
||||||
Some(dfvk.fvk().ovk),
|
|
||||||
note.clone(),
|
|
||||||
*MemoBytes::empty().as_array(),
|
|
||||||
&mut rng,
|
|
||||||
);
|
|
||||||
let cmu = note.cmu().to_bytes().to_vec();
|
|
||||||
let ephemeral_key = SaplingDomain::epk_bytes(encryptor.epk()).0.to_vec();
|
|
||||||
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
|
||||||
|
|
||||||
// Create a fake CompactBlock containing the note
|
// Create a fake CompactBlock containing the note
|
||||||
let cout = CompactSaplingOutput {
|
let mut ctx = fake_compact_tx(&mut rng);
|
||||||
cmu,
|
|
||||||
ephemeral_key,
|
|
||||||
ciphertext: enc_ciphertext.as_ref()[..52].to_vec(),
|
|
||||||
};
|
|
||||||
let mut ctx = CompactTx::default();
|
|
||||||
let mut txid = vec![0; 32];
|
|
||||||
rng.fill_bytes(&mut txid);
|
|
||||||
ctx.hash = txid;
|
|
||||||
ctx.outputs.push(cout);
|
ctx.outputs.push(cout);
|
||||||
let mut cb = CompactBlock {
|
|
||||||
hash: {
|
let cb =
|
||||||
let mut hash = vec![0; 32];
|
fake_compact_block_from_compact_tx(ctx, height, prev_hash, initial_sapling_tree_size, 0);
|
||||||
rng.fill_bytes(&mut hash);
|
|
||||||
hash
|
|
||||||
},
|
|
||||||
height: height.into(),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
cb.prev_hash.extend_from_slice(&prev_hash.0);
|
|
||||||
cb.vtx.push(ctx);
|
|
||||||
cb.chain_metadata = Some(compact::ChainMetadata {
|
|
||||||
sapling_commitment_tree_size: initial_sapling_tree_size
|
|
||||||
+ cb.vtx.iter().map(|tx| tx.outputs.len() as u32).sum::<u32>(),
|
|
||||||
..Default::default()
|
|
||||||
});
|
|
||||||
(cb, note.nf(&dfvk.fvk().vk.nk, 0))
|
(cb, note.nf(&dfvk.fvk().vk.nk, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -880,67 +891,29 @@ fn fake_compact_block_spending<P: consensus::Parameters>(
|
||||||
value: NonNegativeAmount,
|
value: NonNegativeAmount,
|
||||||
initial_sapling_tree_size: u32,
|
initial_sapling_tree_size: u32,
|
||||||
) -> CompactBlock {
|
) -> CompactBlock {
|
||||||
let zip212_enforcement = zip212_enforcement(params, height);
|
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
let rseed = generate_random_rseed(zip212_enforcement, &mut rng);
|
let mut ctx = fake_compact_tx(&mut rng);
|
||||||
|
|
||||||
// Create a fake CompactBlock containing the note
|
// Create a fake spend
|
||||||
let cspend = CompactSaplingSpend { nf: nf.to_vec() };
|
let cspend = CompactSaplingSpend { nf: nf.to_vec() };
|
||||||
let mut ctx = CompactTx::default();
|
|
||||||
let mut txid = vec![0; 32];
|
|
||||||
rng.fill_bytes(&mut txid);
|
|
||||||
ctx.hash = txid;
|
|
||||||
ctx.spends.push(cspend);
|
ctx.spends.push(cspend);
|
||||||
|
|
||||||
// Create a fake Note for the payment
|
// Create a fake Note for the payment
|
||||||
ctx.outputs.push({
|
ctx.outputs
|
||||||
let note = Note::from_parts(
|
.push(compact_sapling_output(params, height, to, value, dfvk.fvk().ovk, &mut rng).0);
|
||||||
to,
|
|
||||||
sapling::value::NoteValue::from_raw(value.into_u64()),
|
|
||||||
rseed,
|
|
||||||
);
|
|
||||||
let encryptor = sapling_note_encryption(
|
|
||||||
Some(dfvk.fvk().ovk),
|
|
||||||
note.clone(),
|
|
||||||
*MemoBytes::empty().as_array(),
|
|
||||||
&mut rng,
|
|
||||||
);
|
|
||||||
let cmu = note.cmu().to_bytes().to_vec();
|
|
||||||
let ephemeral_key = SaplingDomain::epk_bytes(encryptor.epk()).0.to_vec();
|
|
||||||
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
|
||||||
|
|
||||||
CompactSaplingOutput {
|
|
||||||
cmu,
|
|
||||||
ephemeral_key,
|
|
||||||
ciphertext: enc_ciphertext.as_ref()[..52].to_vec(),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create a fake Note for the change
|
// Create a fake Note for the change
|
||||||
ctx.outputs.push({
|
ctx.outputs.push(
|
||||||
let change_addr = dfvk.default_address().1;
|
compact_sapling_output(
|
||||||
let rseed = generate_random_rseed(zip212_enforcement, &mut rng);
|
params,
|
||||||
let note = Note::from_parts(
|
height,
|
||||||
change_addr,
|
dfvk.default_address().1,
|
||||||
NoteValue::from_raw((in_value - value).unwrap().into_u64()),
|
(in_value - value).unwrap(),
|
||||||
rseed,
|
dfvk.fvk().ovk,
|
||||||
);
|
|
||||||
let encryptor = sapling_note_encryption(
|
|
||||||
Some(dfvk.fvk().ovk),
|
|
||||||
note.clone(),
|
|
||||||
*MemoBytes::empty().as_array(),
|
|
||||||
&mut rng,
|
&mut rng,
|
||||||
);
|
)
|
||||||
let cmu = note.cmu().to_bytes().to_vec();
|
.0,
|
||||||
let ephemeral_key = SaplingDomain::epk_bytes(encryptor.epk()).0.to_vec();
|
);
|
||||||
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
|
||||||
|
|
||||||
CompactSaplingOutput {
|
|
||||||
cmu,
|
|
||||||
ephemeral_key,
|
|
||||||
ciphertext: enc_ciphertext.as_ref()[..52].to_vec(),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
fake_compact_block_from_compact_tx(ctx, height, prev_hash, initial_sapling_tree_size, 0)
|
fake_compact_block_from_compact_tx(ctx, height, prev_hash, initial_sapling_tree_size, 0)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue