mirror of
https://github.com/jwinterm/grin-wallet.git
synced 2026-10-17 15:21:39 +02:00
Contracts: emit the lowest slatepack version needed
create_slatepack always serialized to V5, so every slatepack went out V5 and V4-only peers could not read it. Emit V4 unless the slate carries a payment proof: only the (opt-in) proof needs the V5-only fields (timestamp/memo) that V4 cannot represent. The slate's declared version is set to match the emitted structure so readers select the right variant. - packer: V5 when payment_proof is present, else V4. - test: a proof slate round-trips as V5 (memo preserved); a no-proof slate as V4. Addresses PR #754 review (packer.rs).
This commit is contained in:
@@ -267,6 +267,32 @@ pub mod tests {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn create_slatepack_emits_lowest_version() -> Result<(), Error> {
|
||||||
|
set_local_chain_type(ChainTypes::Mainnet);
|
||||||
|
let packer = Slatepacker::new(SlatepackerArgs {
|
||||||
|
sender: None,
|
||||||
|
recipients: vec![],
|
||||||
|
dec_key: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
// A slate carrying a payment proof needs V5 (the proof carries memo/timestamp
|
||||||
|
// that V4 can't represent), and the V5 fields survive the round trip.
|
||||||
|
let slate_with_proof = populate_test_slate()?;
|
||||||
|
assert!(slate_with_proof.payment_proof.is_some());
|
||||||
|
let recovered_v5 = packer.get_slate(&packer.create_slatepack(&slate_with_proof)?)?;
|
||||||
|
assert_eq!(recovered_v5.version_info.version, 5);
|
||||||
|
assert!(recovered_v5.payment_proof.unwrap().memo.is_some());
|
||||||
|
|
||||||
|
// Without a proof, V4 is sufficient and is emitted for interoperability with V4 peers.
|
||||||
|
let mut slate_no_proof = populate_test_slate()?;
|
||||||
|
slate_no_proof.payment_proof = None;
|
||||||
|
let recovered_v4 = packer.get_slate(&packer.create_slatepack(&slate_no_proof)?)?;
|
||||||
|
assert_eq!(recovered_v4.version_info.version, 4);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|||||||
@@ -94,7 +94,19 @@ 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::V5)?;
|
// Emit the lowest version that can represent this slate, for maximum
|
||||||
|
// interoperability. Only the (opt-in) payment proof needs V5 fields
|
||||||
|
// (timestamp/memo) that V4 cannot carry; everything else stays V4.
|
||||||
|
let (version, version_num) = if slate.payment_proof.is_some() {
|
||||||
|
(SlateVersion::V5, 5)
|
||||||
|
} else {
|
||||||
|
(SlateVersion::V4, 4)
|
||||||
|
};
|
||||||
|
// Keep the declared version consistent with the emitted structure so readers
|
||||||
|
// select the right variant.
|
||||||
|
let mut slate = slate.clone();
|
||||||
|
slate.version_info.version = version_num;
|
||||||
|
let out_slate = VersionedSlate::into_version(slate, version)?;
|
||||||
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)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user