mirror of
https://github.com/mimblewimble/grin-wallet.git
synced 2025-01-21 11:31:09 +03:00
[Contracts] Slatepack v5 Deserialization fix (#698)
* add V5 deserialization test + fixes * clarify comment * upwrap fix during v4 deserialization * further unwrap removal
This commit is contained in:
parent
febffd4c68
commit
b3d90c92e8
5 changed files with 58 additions and 10 deletions
|
@ -27,7 +27,7 @@ use grin_wallet_libwallet as libwallet;
|
||||||
use impls::test_framework::{self};
|
use impls::test_framework::{self};
|
||||||
use libwallet::contract::my_fee_contribution;
|
use libwallet::contract::my_fee_contribution;
|
||||||
use libwallet::contract::types::{ContractNewArgsAPI, ContractSetupArgsAPI};
|
use libwallet::contract::types::{ContractNewArgsAPI, ContractSetupArgsAPI};
|
||||||
use libwallet::{Slate, SlateState, TxLogEntryType};
|
use libwallet::{Slate, SlateState, Slatepack, Slatepacker, SlatepackerArgs, TxLogEntryType};
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -66,12 +66,27 @@ fn contract_early_proofs_rsr_test_impl(test_dir: &'static str) -> Result<(), lib
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
args.setup_args.proof_args.sender_address = sender_address;
|
args.setup_args.proof_args.sender_address = sender_address;
|
||||||
|
println!("SENDER ADDRESS: {:?}", sender_address);
|
||||||
slate = api.contract_new(m, args)?;
|
slate = api.contract_new(m, args)?;
|
||||||
recipient_address = Some(api.get_slatepack_address(recv_mask, 0)?.pub_key);
|
recipient_address = Some(api.get_slatepack_address(recv_mask, 0)?.pub_key);
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
assert_eq!(slate.state, SlateState::Invoice1);
|
assert_eq!(slate.state, SlateState::Invoice1);
|
||||||
|
println!("I1 State slate: {}", slate);
|
||||||
|
|
||||||
|
// Serialize slate into slatepack
|
||||||
|
let slatepacker_args = SlatepackerArgs {
|
||||||
|
sender: None,
|
||||||
|
recipients: vec![],
|
||||||
|
dec_key: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let slate_packer = Slatepacker::new(slatepacker_args);
|
||||||
|
let slate_packed = slate_packer.create_slatepack(&slate).unwrap();
|
||||||
|
|
||||||
|
let slate_unpacked = slate_packer.get_slate(&slate_packed).unwrap();
|
||||||
|
println!("I2 Slate unpacked: {}", slate_unpacked);
|
||||||
|
|
||||||
wallet::controller::owner_single_use(Some(send_wallet.clone()), send_mask, None, |api, m| {
|
wallet::controller::owner_single_use(Some(send_wallet.clone()), send_mask, None, |api, m| {
|
||||||
// Sending wallet (invoice) signs
|
// Sending wallet (invoice) signs
|
||||||
|
@ -79,9 +94,10 @@ fn contract_early_proofs_rsr_test_impl(test_dir: &'static str) -> Result<(), lib
|
||||||
net_change: Some(-5_000_000_000),
|
net_change: Some(-5_000_000_000),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
slate = api.contract_sign(m, &slate, args)?;
|
slate = api.contract_sign(m, &slate_unpacked, args)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
println!("I2 State slate: {}", slate);
|
||||||
|
|
||||||
assert_eq!(slate.state, SlateState::Invoice2);
|
assert_eq!(slate.state, SlateState::Invoice2);
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ pub struct PaymentMemo {
|
||||||
pub memo: [u8; 32],
|
pub memo: [u8; 32],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub struct PaymentInfo {
|
pub struct PaymentInfo {
|
||||||
/// Sender address
|
/// Sender address
|
||||||
pub sender_address: Option<DalekPublicKey>,
|
pub sender_address: Option<DalekPublicKey>,
|
||||||
|
|
|
@ -94,11 +94,13 @@ impl From<VersionedSlate> for Slate {
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
/// Binary versions, can only be parsed 1:1 into the appropriate
|
/// Binary versions, can only be parsed 1:1 into the appropriate
|
||||||
/// version, and VersionedSlate can up/downgrade from there
|
/// version, and VersionedSlate can up/downgrade from there
|
||||||
|
/// NB (IMPORTANT): Ensure the slates are listed in reverse chronological
|
||||||
|
/// order (latest first)
|
||||||
pub enum VersionedBinSlate {
|
pub enum VersionedBinSlate {
|
||||||
/// Version 4, binary
|
|
||||||
V4(SlateV4Bin),
|
|
||||||
/// Version 5, binary
|
/// Version 5, binary
|
||||||
V5(SlateV5Bin),
|
V5(SlateV5Bin),
|
||||||
|
/// Version 4, binary
|
||||||
|
V4(SlateV4Bin),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<VersionedSlate> for VersionedBinSlate {
|
impl TryFrom<VersionedSlate> for VersionedBinSlate {
|
||||||
|
@ -149,7 +151,9 @@ pub mod tests {
|
||||||
use crate::grin_util::secp::Signature;
|
use crate::grin_util::secp::Signature;
|
||||||
use crate::slate::{KernelFeaturesArgs, ParticipantData, PaymentInfo, PaymentMemo};
|
use crate::slate::{KernelFeaturesArgs, ParticipantData, PaymentInfo, PaymentMemo};
|
||||||
use crate::slate_versions::v5::{CommitsV5, SlateV5};
|
use crate::slate_versions::v5::{CommitsV5, SlateV5};
|
||||||
use crate::{slate, Error, Slate, VersionedBinSlate, VersionedSlate};
|
use crate::{
|
||||||
|
slate, Error, Slate, Slatepacker, SlatepackerArgs, VersionedBinSlate, VersionedSlate,
|
||||||
|
};
|
||||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||||
use ed25519_dalek::PublicKey as DalekPublicKey;
|
use ed25519_dalek::PublicKey as DalekPublicKey;
|
||||||
use ed25519_dalek::Signature as DalekSignature;
|
use ed25519_dalek::Signature as DalekSignature;
|
||||||
|
@ -242,6 +246,27 @@ pub mod tests {
|
||||||
Ok(slate_internal)
|
Ok(slate_internal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ser_deser_current_slate() -> Result<(), Error> {
|
||||||
|
let slate_internal = populate_test_slate()?;
|
||||||
|
// Serialize slate into slatepack
|
||||||
|
let slatepacker_args = SlatepackerArgs {
|
||||||
|
sender: None,
|
||||||
|
recipients: vec![],
|
||||||
|
dec_key: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let slate_packer = Slatepacker::new(slatepacker_args);
|
||||||
|
let slate_packed = slate_packer.create_slatepack(&slate_internal).unwrap();
|
||||||
|
|
||||||
|
let slate_unpacked = slate_packer.get_slate(&slate_packed).unwrap();
|
||||||
|
|
||||||
|
// Just verifying payment proof for now, extend later to cover EQ for full slate if needs
|
||||||
|
// be
|
||||||
|
assert_eq!(slate_internal.payment_proof, slate_unpacked.payment_proof);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn slatepack_version_v4_v5() -> Result<(), Error> {
|
fn slatepack_version_v4_v5() -> Result<(), Error> {
|
||||||
set_local_chain_type(ChainTypes::Mainnet);
|
set_local_chain_type(ChainTypes::Mainnet);
|
||||||
|
|
|
@ -25,6 +25,7 @@ use chrono::{DateTime, NaiveDateTime, Utc};
|
||||||
use ed25519_dalek::PublicKey as DalekPublicKey;
|
use ed25519_dalek::PublicKey as DalekPublicKey;
|
||||||
use ed25519_dalek::Signature as DalekSignature;
|
use ed25519_dalek::Signature as DalekSignature;
|
||||||
use std::convert::{TryFrom, TryInto};
|
use std::convert::{TryFrom, TryInto};
|
||||||
|
use std::f64::consts::E;
|
||||||
|
|
||||||
use crate::slate_versions::v5::{
|
use crate::slate_versions::v5::{
|
||||||
CommitsV5, KernelFeaturesArgsV5, ParticipantDataV5, PaymentInfoV5, PaymentMemoV5, SlateStateV5,
|
CommitsV5, KernelFeaturesArgsV5, ParticipantDataV5, PaymentInfoV5, PaymentMemoV5, SlateStateV5,
|
||||||
|
@ -246,9 +247,15 @@ impl Readable for ProofWrap {
|
||||||
fn read<R: Reader>(reader: &mut R) -> Result<ProofWrap, grin_ser::Error> {
|
fn read<R: Reader>(reader: &mut R) -> Result<ProofWrap, grin_ser::Error> {
|
||||||
let saddr = DalekPublicKey::from_bytes(&reader.read_fixed_bytes(32)?).unwrap();
|
let saddr = DalekPublicKey::from_bytes(&reader.read_fixed_bytes(32)?).unwrap();
|
||||||
let raddr = DalekPublicKey::from_bytes(&reader.read_fixed_bytes(32)?).unwrap();
|
let raddr = DalekPublicKey::from_bytes(&reader.read_fixed_bytes(32)?).unwrap();
|
||||||
let ts_raw: i64 = reader.read_i64().unwrap();
|
let ts_raw: i64 = match reader.read_i64() {
|
||||||
let ts =
|
Ok(v) => v,
|
||||||
DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp_opt(ts_raw, 0).unwrap(), Utc);
|
Err(_) => return Err(grin_ser::Error::CorruptedData),
|
||||||
|
};
|
||||||
|
let ts_opt = match NaiveDateTime::from_timestamp_opt(ts_raw, 0) {
|
||||||
|
Some(o) => o,
|
||||||
|
None => return Err(grin_ser::Error::CorruptedData),
|
||||||
|
};
|
||||||
|
let ts = DateTime::<Utc>::from_utc(ts_opt, Utc);
|
||||||
let psig = match reader.read_u8()? {
|
let psig = match reader.read_u8()? {
|
||||||
0 => None,
|
0 => None,
|
||||||
1 | _ => Some(DalekSignature::try_from(&reader.read_fixed_bytes(64)?[..]).unwrap()),
|
1 | _ => Some(DalekSignature::try_from(&reader.read_fixed_bytes(64)?[..]).unwrap()),
|
||||||
|
|
|
@ -94,7 +94,7 @@ impl<'a> Slatepacker<'a> {
|
||||||
|
|
||||||
/// Create slatepack from slate and args
|
/// Create slatepack from slate and args
|
||||||
pub fn create_slatepack(&self, slate: &Slate) -> Result<Slatepack, Error> {
|
pub fn create_slatepack(&self, slate: &Slate) -> Result<Slatepack, Error> {
|
||||||
let out_slate = VersionedSlate::into_version(slate.clone(), SlateVersion::V4)?;
|
let out_slate = VersionedSlate::into_version(slate.clone(), SlateVersion::V5)?;
|
||||||
let bin_slate = VersionedBinSlate::try_from(out_slate).map_err(|_| Error::SlatepackSer)?;
|
let bin_slate = VersionedBinSlate::try_from(out_slate).map_err(|_| Error::SlatepackSer)?;
|
||||||
let mut slatepack = Slatepack::default();
|
let mut slatepack = Slatepack::default();
|
||||||
slatepack.payload = byte_ser::to_bytes(&bin_slate).map_err(|_| Error::SlatepackSer)?;
|
slatepack.payload = byte_ser::to_bytes(&bin_slate).map_err(|_| Error::SlatepackSer)?;
|
||||||
|
|
Loading…
Reference in a new issue