Skip to content

Commit ce6af9b

Browse files
authored
fix(auth_context): serialization uses TypeName instead of TypeInput (#8577)
# Description of change Given that the `AuthContext` Move representation makes use of the `TypeName`, i.e., the string representation of the type, its serializer was implemented to support the conversion from `TypeInput` to `TypeName`. ## Links to any relevant issues Fixes #8455 issue 3 ## How the change has been tested - [ ] Basic tests (linting, compilation, formatting, unit/integration tests) - [ ] Patch-specific tests (correctness, functionality coverage) - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] I have checked that new and existing unit tests pass locally with my changes ### Release Notes - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API:
1 parent 4a412dc commit ce6af9b

File tree

2 files changed

+97
-2
lines changed

2 files changed

+97
-2
lines changed

crates/iota-types/src/auth_context.rs

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@
44
use move_binary_format::{CompiledModule, file_format::SignatureToken};
55
use move_bytecode_utils::resolve_struct;
66
use move_core_types::{account_address::AccountAddress, ident_str, identifier::IdentStr};
7-
use serde::{Deserialize, Serialize};
7+
use serde::{
8+
Serialize, Serializer,
9+
ser::{SerializeStruct, SerializeStructVariant, SerializeTupleVariant},
10+
};
811

912
use crate::{
1013
IOTA_FRAMEWORK_ADDRESS,
1114
digests::MoveAuthenticatorDigest,
1215
transaction::{CallArg, Command, ProgrammableTransaction},
16+
type_input::TypeName,
1317
};
1418

1519
pub const AUTH_CONTEXT_MODULE_NAME: &IdentStr = ident_str!("auth_context");
@@ -40,7 +44,7 @@ pub const AUTH_CONTEXT_STRUCT_NAME: &IdentStr = ident_str!("AuthContext");
4044
/// ```
4145
// Conceptually similar to `TxContext`, but designed specifically for use in the authentication
4246
// flow.
43-
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
47+
#[derive(Clone, Debug, PartialEq, Eq)]
4448
pub struct AuthContext {
4549
/// The digest of the MoveAuthenticator
4650
auth_digest: MoveAuthenticatorDigest,
@@ -103,6 +107,66 @@ impl AuthContext {
103107
}
104108
}
105109

110+
// TODO: add a deserializer that can handle the Command::MoveCall and
111+
// Command::MakeMoveVec variants properly. For now, we only need serialization
112+
// for inclusion in the tx authenticator input, so we implement Serialize only.
113+
// Alternatively, a custom Command struct could be created for de/serialization
114+
// purposes or to add new functionalities.
115+
impl Serialize for AuthContext {
116+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
117+
where
118+
S: Serializer,
119+
{
120+
let mut state = serializer.serialize_struct("AuthContext", 3)?;
121+
state.serialize_field("auth_digest", &self.auth_digest)?;
122+
state.serialize_field("tx_inputs", &self.tx_inputs)?;
123+
124+
// Serialize tx_commands as a Vec of enums, matching the original logic
125+
struct CommandSer<'a>(&'a Command);
126+
127+
impl<'a> Serialize for CommandSer<'a> {
128+
fn serialize<SC>(&self, serializer: SC) -> Result<SC::Ok, SC::Error>
129+
where
130+
SC: Serializer,
131+
{
132+
match self.0 {
133+
Command::MoveCall(m) => {
134+
let mut s =
135+
serializer.serialize_struct_variant("Command", 0, "MoveCall", 5)?;
136+
s.serialize_field("package", &m.package)?;
137+
s.serialize_field("module", &m.module)?;
138+
s.serialize_field("function", &m.function)?;
139+
s.serialize_field(
140+
"type_arguments",
141+
&m.type_arguments
142+
.iter()
143+
.map(|ty| TypeName::from(ty))
144+
.collect::<Vec<_>>(),
145+
)?;
146+
s.serialize_field("arguments", &m.arguments)?;
147+
s.end()
148+
}
149+
Command::MakeMoveVec(ty_opt, vals) => {
150+
let mut s =
151+
serializer.serialize_tuple_variant("Command", 5, "MakeMoveVec", 2)?;
152+
s.serialize_field(&ty_opt.as_ref().map(|ty| TypeName::from(ty)))?;
153+
s.serialize_field(vals)?;
154+
s.end()
155+
}
156+
_ => self.0.serialize(serializer),
157+
}
158+
}
159+
}
160+
161+
state.serialize_field(
162+
"tx_commands",
163+
&self.tx_commands.iter().map(CommandSer).collect::<Vec<_>>(),
164+
)?;
165+
166+
state.end()
167+
}
168+
}
169+
106170
#[derive(PartialEq, Eq, Clone, Copy)]
107171
pub enum AuthContextKind {
108172
// Not AuthContext

crates/iota-types/src/type_input.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,37 @@ use move_core_types::{
1313
};
1414
use serde::{Deserialize, Serialize};
1515

16+
use crate::parse_iota_type_tag;
17+
18+
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
19+
pub struct TypeName {
20+
/// String representation of the type. All types are represented
21+
/// using their source syntax:
22+
/// "u8", "u64", "bool", "address", "vector", and so on for primitive types.
23+
/// Struct types are represented as fully qualified type names; e.g.
24+
/// `00000000000000000000000000000001::string::String` or
25+
/// `0000000000000000000000000000000a::module_name1::type_name1<0000000000000000000000000000000a::module_name2::type_name2<u64>>`
26+
/// Addresses are hex-encoded lowercase values of length ADDRESS_LENGTH (16,
27+
/// 20, or 32 depending on the Move platform)
28+
pub name: String,
29+
}
30+
31+
impl From<&TypeInput> for TypeName {
32+
fn from(value: &TypeInput) -> Self {
33+
TypeName {
34+
name: value.to_canonical_string(false /* with_prefix */),
35+
}
36+
}
37+
}
38+
39+
impl TryFrom<TypeName> for TypeInput {
40+
type Error = anyhow::Error;
41+
42+
fn try_from(value: TypeName) -> Result<Self, Self::Error> {
43+
parse_iota_type_tag(&value.name).map(|tag| tag.into())
44+
}
45+
}
46+
1647
#[derive(Serialize, Deserialize, Debug, PartialEq, Hash, Eq, Clone, PartialOrd, Ord)]
1748
pub struct StructInput {
1849
pub address: AccountAddress,

0 commit comments

Comments
 (0)