From 7f0c43dfdf41e5af243622149847fc161a7f8b35 Mon Sep 17 00:00:00 2001 From: wiesche Date: Sun, 6 Sep 2026 20:06:49 +0200 Subject: [PATCH] decoded slate version --- api/src/owner_rpc.rs | 44 +++++++++++++++++++++++- libwallet/src/contract/actions/README.md | 1 - libwallet/src/slate_versions/mod.rs | 23 +++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/api/src/owner_rpc.rs b/api/src/owner_rpc.rs index da00fd5..5ef472b 100644 --- a/api/src/owner_rpc.rs +++ b/api/src/owner_rpc.rs @@ -2537,7 +2537,8 @@ where message, secret_indices, )?; - let version = SlateVersion::V4; + // Keep the decoded version; lowest_for would downgrade a plain V5 slate + let version = SlateVersion::try_from(slate.version_info.version)?; VersionedSlate::into_version(slate, version) } @@ -2891,3 +2892,44 @@ macro_rules! doctest_helper_json_rpc_owner_assert_response { } }; } + +#[cfg(test)] +mod tests { + use super::*; + use crate::libwallet::{SlatepackArmor, VersionedBinSlate}; + use grin_wallet_util::byte_ser; + use tempfile::tempdir; + + #[test] + fn slatepack_keeps_v5() { + let slate = VersionedSlate::into_version(Slate::blank(2, false), SlateVersion::V5).unwrap(); + let slate = VersionedBinSlate::try_from(slate).unwrap(); + let mut slatepack = Slatepack::default(); + slatepack.payload = byte_ser::to_bytes(&slate).unwrap(); + let message = SlatepackArmor::encode(&slatepack).unwrap(); + let request = serde_json::json!({ + "jsonrpc": "2.0", + "method": "slate_from_slatepack_message", + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "secret_indices": [], + "message": message + }, + "id": 1 + }); + let dir = tempdir().unwrap(); + let response = run_doctest_owner( + request, + dir.path().to_str().unwrap(), + 0, + false, + false, + false, + false, + ) + .unwrap() + .unwrap(); + + assert_eq!(response["result"]["Ok"]["ver"], "5:3"); + } +} diff --git a/libwallet/src/contract/actions/README.md b/libwallet/src/contract/actions/README.md index 88acbca..cbc3c55 100644 --- a/libwallet/src/contract/actions/README.md +++ b/libwallet/src/contract/actions/README.md @@ -43,7 +43,6 @@ Separating side effects until the 'save_step' part would make these functions mu of searching by commitment. - Move payment-proof creation and verification onto `Slate` so it can also be used outside contracts and is versioned with the slate format. - - Keep V5 when decoding Slatepacks through Owner RPC. - Preserve kernel features and their arguments across V4 and V5; see #793. - Choose the sender derivation path explicitly and keep encrypted outgoing files identifiable locally. diff --git a/libwallet/src/slate_versions/mod.rs b/libwallet/src/slate_versions/mod.rs index 0b8f6b4..1d6a9ff 100644 --- a/libwallet/src/slate_versions/mod.rs +++ b/libwallet/src/slate_versions/mod.rs @@ -52,6 +52,18 @@ pub enum SlateVersion { V4, } +impl TryFrom for SlateVersion { + type Error = Error; + + fn try_from(version: u16) -> Result { + match version { + 4 => Ok(Self::V4), + 5 => Ok(Self::V5), + version => Err(Error::SlateVersion(version)), + } + } +} + impl SlateVersion { /// The lowest version that can represent this slate without losing data, so a slate /// is only sent as V5 when it has to be. V4 carries the payment proof's sender and @@ -479,4 +491,15 @@ pub mod tests { Ok(()) } + + #[test] + fn slate_version_numbers() { + for (number, version) in [(4, SlateVersion::V4), (5, SlateVersion::V5)] { + assert_eq!(SlateVersion::try_from(number).unwrap(), version); + } + assert!(matches!( + SlateVersion::try_from(6), + Err(Error::SlateVersion(6)) + )); + } }