mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-10-01 01:45:40 -04:00
[WIP] Make test self-contained
This commit is contained in:
parent
46d0eaedea
commit
64cd618aea
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -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",
|
||||||
]
|
]
|
||||||
|
@ -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"
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
@ -128,15 +155,20 @@ async fn monerod_integration_test() {
|
|||||||
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,7 +179,8 @@ async fn monerod_integration_test() {
|
|||||||
key_offsets: relative_key_offsets,
|
key_offsets: relative_key_offsets,
|
||||||
k_image,
|
k_image,
|
||||||
}],
|
}],
|
||||||
outputs: vec![TxOut {
|
outputs: vec![
|
||||||
|
TxOut {
|
||||||
amount: VarInt(0),
|
amount: VarInt(0),
|
||||||
target: TxOutTarget::ToKey {
|
target: TxOutTarget::ToKey {
|
||||||
key: KeyGenerator::from_random(
|
key: KeyGenerator::from_random(
|
||||||
@ -155,9 +188,10 @@ async fn monerod_integration_test() {
|
|||||||
target_address.public_spend,
|
target_address.public_spend,
|
||||||
ecdh_key_0,
|
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(
|
||||||
@ -167,17 +201,22 @@ async fn monerod_integration_test() {
|
|||||||
)
|
)
|
||||||
.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(
|
],
|
||||||
&ecdh_key_0,
|
extra: ExtraField(vec![
|
||||||
)), SubField::TxPublicKey(PublicKey::from_private_key(
|
SubField::TxPublicKey(PublicKey::from_private_key(&ecdh_key_0)),
|
||||||
&ecdh_key_1,
|
SubField::TxPublicKey(PublicKey::from_private_key(&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,9 +342,7 @@ 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(78),
|
||||||
VarInt(3),
|
VarInt(3),
|
||||||
VarInt(10),
|
VarInt(10),
|
||||||
@ -312,7 +354,6 @@ mod tests {
|
|||||||
VarInt(1),
|
VarInt(1),
|
||||||
VarInt(1),
|
VarInt(1),
|
||||||
VarInt(3),
|
VarInt(3),
|
||||||
]
|
])
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user