[WIP] Make test self-contained

This commit is contained in:
Lucas Soriano del Pino 2021-05-10 13:21:40 +10:00
parent 46d0eaedea
commit 64cd618aea
No known key found for this signature in database
GPG Key ID: EE611E973A1530E7
4 changed files with 127 additions and 83 deletions

1
Cargo.lock generated
View File

@ -2298,6 +2298,7 @@ dependencies = [
"monero-rpc", "monero-rpc",
"monero-wallet", "monero-wallet",
"rand 0.7.3", "rand 0.7.3",
"testcontainers 0.12.0",
"tiny-keccak", "tiny-keccak",
"tokio", "tokio",
] ]

View File

@ -17,5 +17,6 @@ hex = "0.4"
monero-harness = { path = "../monero-harness" } monero-harness = { path = "../monero-harness" }
monero-rpc = { path = "../monero-rpc" } monero-rpc = { path = "../monero-rpc" }
monero-wallet = { path = "../monero-wallet" } monero-wallet = { path = "../monero-wallet" }
testcontainers = "0.12"
tokio = { version = "1", features = ["full"] } tokio = { version = "1", features = ["full"] }
itertools = "0.10" itertools = "0.10"

View File

@ -7,9 +7,9 @@ use curve25519_dalek::constants::ED25519_BASEPOINT_POINT;
use curve25519_dalek::edwards::EdwardsPoint; use curve25519_dalek::edwards::EdwardsPoint;
use curve25519_dalek::scalar::Scalar; use curve25519_dalek::scalar::Scalar;
use hash_edwards_to_edwards::hash_point_to_point; use hash_edwards_to_edwards::hash_point_to_point;
use rand::{CryptoRng, Rng};
use std::convert::TryInto; use std::convert::TryInto;
use tiny_keccak::{Hasher, Keccak}; use tiny_keccak::{Hasher, Keccak};
use rand::{Rng, CryptoRng};
pub const RING_SIZE: usize = 11; pub const RING_SIZE: usize = 11;
const DOMAIN_TAG: &str = "CSLAG_c"; const DOMAIN_TAG: &str = "CSLAG_c";
@ -195,7 +195,7 @@ impl Alice0 {
R_a: EdwardsPoint, R_a: EdwardsPoint,
R_prime_a: EdwardsPoint, R_prime_a: EdwardsPoint,
s_prime_a: Scalar, s_prime_a: Scalar,
rng: &mut (impl Rng + CryptoRng) rng: &mut (impl Rng + CryptoRng),
) -> Result<Self> { ) -> Result<Self> {
let mut fake_responses = [Scalar::zero(); RING_SIZE - 1]; let mut fake_responses = [Scalar::zero(); RING_SIZE - 1];
for response in fake_responses.iter_mut().take(RING_SIZE - 1) { for response in fake_responses.iter_mut().take(RING_SIZE - 1) {
@ -233,7 +233,7 @@ impl Alice0 {
self.H_p_pk, self.H_p_pk,
self.I_hat_a, self.I_hat_a,
self.alpha_a, self.alpha_a,
rng rng,
), ),
c_a: Commitment::new(self.fake_responses, self.I_a, self.I_hat_a, self.T_a), c_a: Commitment::new(self.fake_responses, self.I_a, self.I_hat_a, self.T_a),
} }
@ -329,7 +329,7 @@ impl Bob0 {
R_a: EdwardsPoint, R_a: EdwardsPoint,
R_prime_a: EdwardsPoint, R_prime_a: EdwardsPoint,
s_b: Scalar, s_b: Scalar,
rng: &mut (impl Rng + CryptoRng) rng: &mut (impl Rng + CryptoRng),
) -> Result<Self> { ) -> Result<Self> {
let alpha_b = Scalar::random(rng); let alpha_b = Scalar::random(rng);
@ -403,7 +403,7 @@ impl Bob1 {
self.H_p_pk, self.H_p_pk,
self.I_hat_b, self.I_hat_b,
self.alpha_b, self.alpha_b,
rng rng,
), ),
} }
} }
@ -464,7 +464,7 @@ impl DleqProof {
H: EdwardsPoint, H: EdwardsPoint,
xH: EdwardsPoint, xH: EdwardsPoint,
x: Scalar, x: Scalar,
rng: &mut (impl Rng + CryptoRng) rng: &mut (impl Rng + CryptoRng),
) -> Self { ) -> Self {
let r = Scalar::random(rng); let r = Scalar::random(rng);
let rG = r * G; let rG = r * G;
@ -621,6 +621,7 @@ pub struct Message3 {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use rand::rngs::OsRng;
#[test] #[test]
fn sign_and_verify_success() { fn sign_and_verify_success() {
@ -651,13 +652,13 @@ mod tests {
x * ED25519_BASEPOINT_POINT x * ED25519_BASEPOINT_POINT
}); });
let alice = Alice0::new(ring, *msg_to_sign, R_a, R_prime_a, s_prime_a).unwrap(); let alice = Alice0::new(ring, *msg_to_sign, R_a, R_prime_a, s_prime_a, &mut OsRng).unwrap();
let bob = Bob0::new(ring, *msg_to_sign, R_a, R_prime_a, s_b).unwrap(); let bob = Bob0::new(ring, *msg_to_sign, R_a, R_prime_a, s_b, &mut OsRng).unwrap();
let msg = alice.next_message(); let msg = alice.next_message(&mut OsRng);
let bob = bob.receive(msg); let bob = bob.receive(msg);
let msg = bob.next_message(); let msg = bob.next_message(&mut OsRng);
let alice = alice.receive(msg).unwrap(); let alice = alice.receive(msg).unwrap();
let msg = alice.next_message(); let msg = alice.next_message();

View File

@ -1,40 +1,60 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
use monero::blockdata::transaction::KeyImage;
use monero::util::key::H;
use monero::ViewPair;
use curve25519_dalek::constants::ED25519_BASEPOINT_POINT; use curve25519_dalek::constants::ED25519_BASEPOINT_POINT;
use curve25519_dalek::edwards::{EdwardsPoint}; use curve25519_dalek::edwards::EdwardsPoint;
use curve25519_dalek::scalar::Scalar; use curve25519_dalek::scalar::Scalar;
use hash_edwards_to_edwards::hash_point_to_point; use hash_edwards_to_edwards::hash_point_to_point;
use monero::blockdata::transaction::{ExtraField, SubField, TxOutTarget}; use monero::blockdata::transaction::{ExtraField, KeyImage, SubField, TxOutTarget};
use monero::cryptonote::hash::Hashable; use monero::cryptonote::hash::Hashable;
use monero::cryptonote::onetime_key::{KeyGenerator, MONERO_MUL_FACTOR}; use monero::cryptonote::onetime_key::{KeyGenerator, MONERO_MUL_FACTOR};
use monero::util::key::H;
use monero::util::ringct::{EcdhInfo, RctSig, RctSigBase, RctSigPrunable, RctType}; use monero::util::ringct::{EcdhInfo, RctSig, RctSigBase, RctSigPrunable, RctType};
use monero::{PrivateKey, PublicKey}; use monero::{
use monero::{Transaction, TransactionPrefix, TxIn, TxOut, VarInt}; PrivateKey, PublicKey, Transaction, TransactionPrefix, TxIn, TxOut, VarInt, ViewPair,
};
use monero_harness::Monero;
use monero_rpc::monerod; use monero_rpc::monerod;
use monero_rpc::monerod::{GetOutputsOut, MonerodRpc}; use monero_rpc::monerod::{GetOutputsOut, MonerodRpc};
use monero_wallet::{MonerodClientExt}; use monero_wallet::MonerodClientExt;
use rand::rngs::OsRng; use rand::rngs::OsRng;
use rand::{Rng, SeedableRng, thread_rng, CryptoRng}; use rand::{thread_rng, CryptoRng, Rng, SeedableRng};
use std::convert::TryInto; use std::convert::TryInto;
use std::iter; use std::iter;
use testcontainers::clients::Cli;
// [0u8; 32] = 466iKkx7MqVGD46dje3kwvSQRMfhNCvGaXTRATbQgz7kS8XTMmRmoTw9oJRRj523kTdQj8gXnF2xU9fmEPy9WXTr6pwetQj async fn prepare_nodes(address: monero::Address, amount: u64) -> (monerod::Client, monero::Hash) {
// [1u8; 32] = 47HCnKkBEeYfX5pScvBETAKdjBEPN7FcXEJPUqDPzWGCc6wC8VAdS8CjdtgKuSaY72K8fkoswjp176vbSPS8hzS17EZv8gj let cli = Cli::default();
#[tokio::test] let (monero, _monerod_container, _monero_wallet_rpc_containers) =
async fn make_blocks() { Monero::new(&cli, vec![]).await.unwrap();
let client = monerod::Client::localhost(18081).unwrap();
// client.generateblocks(110, "498AVruCDWgP9Az9LjMm89VWjrBrSZ2W2K3HFBiyzzrRjUJWUcCVxvY1iitfuKoek2FdX6MKGAD9Qb1G1P8QgR5jPmmt3Vj".to_owned()).await.unwrap(); monero.init_miner().await.unwrap();
client.generateblocks(10, "498AVruCDWgP9Az9LjMm89VWjrBrSZ2W2K3HFBiyzzrRjUJWUcCVxvY1iitfuKoek2FdX6MKGAD9Qb1G1P8QgR5jPmmt3Vj".to_owned()).await.unwrap();
let wallet = monero.wallet("miner").expect("wallet to exist");
let transfer = wallet
.transfer(&address.to_string(), amount)
.await
.expect("lock to succeed");
let monerod = monero.monerod().client();
let miner_address = wallet
.address()
.await
.expect("miner address to exist")
.address;
monerod
.generateblocks(10, miner_address)
.await
.expect("can generate blocks");
let lock_tx_hash = transfer.tx_hash.parse().unwrap();
(monerod.clone(), lock_tx_hash)
} }
#[tokio::test] #[tokio::test]
async fn monerod_integration_test() { async fn monerod_integration_test() {
let client = monerod::Client::localhost(18081).unwrap();
let mut rng = rand::rngs::StdRng::from_seed([0u8; 32]); let mut rng = rand::rngs::StdRng::from_seed([0u8; 32]);
let s_a = curve25519_dalek::scalar::Scalar::random(&mut rng); let s_a = curve25519_dalek::scalar::Scalar::random(&mut rng);
@ -52,19 +72,26 @@ async fn monerod_integration_test() {
dbg!(lock_address.to_string()); // 45BcRKAHaA4b5A9SdamF2f1w7zk1mKkBPhaqVoDWzuAtMoSAytzm5A6b2fE6ruupkAFmStrQzdojUExt96mR3oiiSKp8Exf dbg!(lock_address.to_string()); // 45BcRKAHaA4b5A9SdamF2f1w7zk1mKkBPhaqVoDWzuAtMoSAytzm5A6b2fE6ruupkAFmStrQzdojUExt96mR3oiiSKp8Exf
let lock_tx = "c73c42dbd9082639fd475ea570c04eeddf068c3897ceae1b501beae7571779de" let (client, lock_tx) = prepare_nodes(lock_address, lock_amount).await;
.parse()
.unwrap();
let o_indexes_response = client.get_o_indexes(lock_tx).await.unwrap(); let o_indexes_response = client.get_o_indexes(lock_tx).await.unwrap();
let transaction = client.get_transactions(&[lock_tx]).await.unwrap().pop().unwrap(); let transaction = client
.get_transactions(&[lock_tx])
.await
.unwrap()
.pop()
.unwrap();
dbg!(&transaction.prefix.inputs); dbg!(&transaction.prefix.inputs);
let viewpair = ViewPair::from(&lock_kp); let viewpair = ViewPair::from(&lock_kp);
let our_output = transaction.check_outputs(&viewpair, 0..1, 0..1).expect("to have outputs in this transaction").pop().expect("to own at least one output"); let our_output = transaction
.check_outputs(&viewpair, 0..1, 0..1)
.expect("to have outputs in this transaction")
.pop()
.expect("to own at least one output");
let actual_lock_amount = transaction.get_amount(&viewpair, &our_output).unwrap(); let actual_lock_amount = transaction.get_amount(&viewpair, &our_output).unwrap();
assert_eq!(actual_lock_amount, lock_amount); assert_eq!(actual_lock_amount, lock_amount);
@ -124,19 +151,24 @@ async fn monerod_integration_test() {
let ecdh_key_0 = PrivateKey::random(&mut rng); let ecdh_key_0 = PrivateKey::random(&mut rng);
let (ecdh_info_0, out_blinding_0) = EcdhInfo::new_bulletproof(spend_amount, ecdh_key_0.scalar); let (ecdh_info_0, out_blinding_0) = EcdhInfo::new_bulletproof(spend_amount, ecdh_key_0.scalar);
let ecdh_key_1 = PrivateKey::random(&mut rng); let ecdh_key_1 = PrivateKey::random(&mut rng);
let (ecdh_info_1, out_blinding_1) = EcdhInfo::new_bulletproof(spend_amount, ecdh_key_1.scalar); let (ecdh_info_1, out_blinding_1) = EcdhInfo::new_bulletproof(spend_amount, ecdh_key_1.scalar);
let (bulletproof, out_pk) = let (bulletproof, out_pk) = monero::make_bulletproof(&mut rng, &[spend_amount, 0], &[
monero::make_bulletproof(&mut rng, &[spend_amount, 0], &[out_blinding_0, out_blinding_1]).unwrap(); out_blinding_0,
out_blinding_1,
])
.unwrap();
let k_image = { let k_image = {
let k = lock_kp.spend.scalar; let k = lock_kp.spend.scalar;
let K = ViewPair::from(&lock_kp).spend.point; let K = ViewPair::from(&lock_kp).spend.point;
let k_image = k * hash_point_to_point(K.decompress().unwrap()); let k_image = k * hash_point_to_point(K.decompress().unwrap());
KeyImage { image: monero::cryptonote::hash::Hash(k_image.compress().to_bytes()) } KeyImage {
image: monero::cryptonote::hash::Hash(k_image.compress().to_bytes()),
}
}; };
let prefix = TransactionPrefix { let prefix = TransactionPrefix {
@ -147,37 +179,44 @@ async fn monerod_integration_test() {
key_offsets: relative_key_offsets, key_offsets: relative_key_offsets,
k_image, k_image,
}], }],
outputs: vec![TxOut { outputs: vec![
amount: VarInt(0), TxOut {
target: TxOutTarget::ToKey { amount: VarInt(0),
key: KeyGenerator::from_random( target: TxOutTarget::ToKey {
target_address.public_view, key: KeyGenerator::from_random(
target_address.public_spend, target_address.public_view,
ecdh_key_0, target_address.public_spend,
) ecdh_key_0,
.one_time_key(0)// TODO: This must be the output index )
.one_time_key(0), // TODO: This must be the output index
},
}, },
}, TxOut { TxOut {
amount: VarInt(0), amount: VarInt(0),
target: TxOutTarget::ToKey { target: TxOutTarget::ToKey {
key: KeyGenerator::from_random( key: KeyGenerator::from_random(
target_address.public_view, target_address.public_view,
target_address.public_spend, target_address.public_spend,
ecdh_key_1, ecdh_key_1,
) )
.one_time_key(1), // TODO: This must be the output index .one_time_key(1), // TODO: This must be the output index
},
}, },
}], ],
extra: ExtraField(vec![SubField::TxPublicKey(PublicKey::from_private_key( extra: ExtraField(vec![
&ecdh_key_0, SubField::TxPublicKey(PublicKey::from_private_key(&ecdh_key_0)),
)), SubField::TxPublicKey(PublicKey::from_private_key( SubField::TxPublicKey(PublicKey::from_private_key(&ecdh_key_1)),
&ecdh_key_1, ]),
))]),
}; };
// assert_eq!(prefix.hash(), "c3ded4d1a8cddd4f76c09b63edff4e312e759b3afc46beda4e1fd75c9c68d997".parse().unwrap()); // assert_eq!(prefix.hash(),
// "c3ded4d1a8cddd4f76c09b63edff4e312e759b3afc46beda4e1fd75c9c68d997".parse().
// unwrap());
let s_prime_a = s_a + KeyGenerator::from_key(&viewpair, our_output.tx_pubkey).get_rvn_scalar(our_output.index).scalar; let s_prime_a = s_a
+ KeyGenerator::from_key(&viewpair, our_output.tx_pubkey)
.get_rvn_scalar(our_output.index)
.scalar;
let (adaptor_sig, adaptor) = let (adaptor_sig, adaptor) =
single_party_adaptor_sig(s_prime_a, s_b, ring, &prefix.hash().to_bytes(), &mut rng); single_party_adaptor_sig(s_prime_a, s_b, ring, &prefix.hash().to_bytes(), &mut rng);
@ -187,12 +226,15 @@ async fn monerod_integration_test() {
// let pseudo_out = { // let pseudo_out = {
// let lock_amount = Scalar::from(lock_amount); // let lock_amount = Scalar::from(lock_amount);
// //
// (out_blinding * ED25519_BASEPOINT_POINT) + (lock_amount * H.point.decompress().unwrap()) // (out_blinding * ED25519_BASEPOINT_POINT) + (lock_amount *
// }; // H.point.decompress().unwrap()) };
monero::verify_bulletproof(&mut thread_rng(), bulletproof.clone(), out_pk.clone()).unwrap(); monero::verify_bulletproof(&mut thread_rng(), bulletproof.clone(), out_pk.clone()).unwrap();
let out_pk = out_pk.into_iter().map(|p| (p.decompress().unwrap() * Scalar::from(MONERO_MUL_FACTOR)).compress()).collect::<Vec<_>>(); let out_pk = out_pk
.into_iter()
.map(|p| (p.decompress().unwrap() * Scalar::from(MONERO_MUL_FACTOR)).compress())
.collect::<Vec<_>>();
let fee_key = Scalar::from(fee) * H.point.decompress().unwrap(); let fee_key = Scalar::from(fee) * H.point.decompress().unwrap();
@ -221,7 +263,9 @@ async fn monerod_integration_test() {
bulletproofs: vec![bulletproof], bulletproofs: vec![bulletproof],
MGs: Vec::new(), MGs: Vec::new(),
Clsags: vec![sig.into()], Clsags: vec![sig.into()],
pseudo_outs: vec![monero::util::ringct::Key { key: pseudo_out.compress().0 }], pseudo_outs: vec![monero::util::ringct::Key {
key: pseudo_out.compress().0,
}],
}), }),
}, },
}; };
@ -245,7 +289,7 @@ fn single_party_adaptor_sig(
s_b: Scalar, s_b: Scalar,
ring: [EdwardsPoint; monero_adaptor::RING_SIZE], ring: [EdwardsPoint; monero_adaptor::RING_SIZE],
msg: &[u8; 32], msg: &[u8; 32],
rng: &mut (impl Rng + CryptoRng) rng: &mut (impl Rng + CryptoRng),
) -> (monero_adaptor::AdaptorSignature, Scalar) { ) -> (monero_adaptor::AdaptorSignature, Scalar) {
let (r_a, R_a, R_prime_a) = { let (r_a, R_a, R_prime_a) = {
let r_a = Scalar::random(&mut OsRng); let r_a = Scalar::random(&mut OsRng);
@ -298,21 +342,18 @@ mod tests {
let relative_offsets = to_relative_offsets(&key_offsets); let relative_offsets = to_relative_offsets(&key_offsets);
assert_eq!( assert_eq!(&relative_offsets, &[
&relative_offsets, VarInt(78),
&[ VarInt(3),
VarInt(78), VarInt(10),
VarInt(3), VarInt(0),
VarInt(10), VarInt(5),
VarInt(0), VarInt(2),
VarInt(5), VarInt(3),
VarInt(2), VarInt(11),
VarInt(3), VarInt(1),
VarInt(11), VarInt(1),
VarInt(1), VarInt(3),
VarInt(1), ])
VarInt(3),
]
)
} }
} }