Skip to content

Commit 68ed0d1

Browse files
authored
fix abi for option (#17955)
1 parent 97e7151 commit 68ed0d1

3 files changed

Lines changed: 49 additions & 5 deletions

File tree

api/src/tests/modules.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,19 @@ async fn test_abi(use_txn_payload_v2_format: bool, use_orderless_transactions: b
106106

107107
// Confirm that State is not considered an enum.
108108
assert_eq!(my_struct["is_enum"], false);
109+
110+
let test_option = structs
111+
.iter()
112+
.find(|s| s["name"].as_str().unwrap() == "TestOption")
113+
.unwrap();
114+
assert_eq!(test_option["fields"][0]["name"], "o");
115+
116+
let option_module = context.get("/accounts/0x1/module/option").await;
117+
118+
let option_structs = option_module["abi"]["structs"].as_array().unwrap();
119+
120+
assert_eq!(option_structs[0]["name"], "Option");
121+
assert_eq!(option_structs[0]["fields"][0]["name"], "vec");
122+
assert_eq!(option_structs[0]["is_enum"], false);
123+
assert_eq!(option_structs[0]["fields"][0]["type"], "vector<T0>");
109124
}

api/src/tests/move/pack_abi/sources/test.move

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
module abi::test {
2+
use std::option;
23

34
struct State has key {
45
value: u64
@@ -14,6 +15,10 @@ module abi::test {
1415
value: u64
1516
}
1617

18+
struct TestOption has drop, copy {
19+
o: option::Option<u64>
20+
}
21+
1722
public fun public_function(s: &signer, state: State) {
1823
move_to(s, state)
1924
}

api/types/src/bytecode.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ use move_binary_format::{
2020
StructFieldInformation, StructHandle, StructHandleIndex,
2121
},
2222
};
23-
use move_core_types::{account_address::AccountAddress, identifier::IdentStr};
23+
use move_core_types::{
24+
account_address::AccountAddress,
25+
identifier::{IdentStr, Identifier},
26+
language_storage::{ModuleId, LEGACY_OPTION_VEC},
27+
};
2428
use std::borrow::Borrow;
2529

2630
pub trait Bytecode {
@@ -133,6 +137,7 @@ pub trait Bytecode {
133137

134138
fn new_move_struct(&self, def: &StructDefinition) -> MoveStruct {
135139
let handle = self.struct_handle_at(def.struct_handle);
140+
let mut is_enum = self.struct_is_enum(def);
136141
let (is_native, fields) = match &def.field_information {
137142
StructFieldInformation::Native => (true, vec![]),
138143
StructFieldInformation::Declared(fields) => (
@@ -142,14 +147,33 @@ pub trait Bytecode {
142147
.map(|f| self.new_move_struct_field(f))
143148
.collect(),
144149
),
145-
StructFieldInformation::DeclaredVariants(..) => {
146-
// TODO(#13806): implement for enums. Currently we pretend they don't have fields
147-
(false, vec![])
150+
StructFieldInformation::DeclaredVariants(variant_defs) => {
151+
// For `Option`, we want to keep it backwards compatible with the old representation
152+
// instead of enum representation, we convert it to a struct with `vec` field.
153+
let module_handle = self.module_handle_at(handle.module);
154+
let mid = ModuleId {
155+
address: *self.address_identifier_at(module_handle.address),
156+
name: self.identifier_at(module_handle.name).to_owned(),
157+
};
158+
if mid.is_option() && variant_defs.len() == 2 {
159+
is_enum = false;
160+
let variant = &variant_defs[1];
161+
let field_type = MoveType::Vector {
162+
items: Box::new(self.new_move_type(&variant.fields[0].signature.0)),
163+
};
164+
let field = MoveStructField {
165+
name: Identifier::new(LEGACY_OPTION_VEC).unwrap().into(),
166+
typ: field_type,
167+
};
168+
(false, vec![field])
169+
} else {
170+
// TODO(#13806): implement for enums. Currently we pretend they don't have fields
171+
(false, vec![])
172+
}
148173
},
149174
};
150175
let name = self.identifier_at(handle.name).to_owned();
151176
let is_event = self.struct_is_event(&name);
152-
let is_enum = self.struct_is_enum(def);
153177
let abilities = handle
154178
.abilities
155179
.into_iter()

0 commit comments

Comments
 (0)