Skip to content

Commit b30d55a

Browse files
committed
txn args
1 parent 41858a6 commit b30d55a

File tree

27 files changed

+3382
-81
lines changed

27 files changed

+3382
-81
lines changed

api/src/tests/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ mod modules;
1414
mod multisig_transactions_test;
1515
mod objects;
1616
mod option_test;
17+
mod public_struct_enum_negative_test;
18+
mod public_struct_enum_test;
1719
mod resource_groups;
1820
mod secp256k1_ecdsa;
1921
mod signed_int_test;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "public_struct_enum_test"
3+
version = "0.0.0"
4+
5+
[addresses]
6+
account = "_"
7+
8+
[dependencies]
9+
AptosFramework = { local = "../../../../../aptos-move/framework/aptos-framework" }
10+
AptosStdlib = { local = "../../../../../aptos-move/framework/aptos-stdlib" }
11+
MoveStdlib = { local = "../../../../../aptos-move/framework/move-stdlib" }
Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
/// Module to test public structs and enums with copy ability as transaction arguments
2+
module account::public_struct_test {
3+
use std::string::String;
4+
5+
/// Result resource to store test outcomes
6+
struct TestResult has key {
7+
value: u64,
8+
message: String,
9+
}
10+
11+
/// A public struct with copy ability - should be allowed as txn arg
12+
public struct Point has copy, drop {
13+
x: u64,
14+
y: u64,
15+
}
16+
17+
/// A public struct with nested public copy struct
18+
public struct Rectangle has copy, drop {
19+
top_left: Point,
20+
bottom_right: Point,
21+
}
22+
23+
/// A public struct with vector of primitives
24+
public struct Data has copy, drop {
25+
values: vector<u64>,
26+
name: String,
27+
}
28+
29+
/// A public enum with copy ability - should be allowed as txn arg
30+
public enum Color has copy, drop {
31+
Red,
32+
Green,
33+
Blue,
34+
Custom { r: u8, g: u8, b: u8 },
35+
}
36+
37+
/// A public enum with struct fields
38+
public enum Shape has copy, drop {
39+
Circle { center: Point, radius: u64 },
40+
Rect { rect: Rectangle },
41+
}
42+
43+
/// A generic container struct - for testing generic structs with enum type arguments
44+
public struct Container<T> has copy, drop {
45+
value: T,
46+
}
47+
48+
/// A private (non-public) struct with copy ability - should NOT be allowed as txn arg
49+
struct PrivatePoint has copy, drop {
50+
x: u64,
51+
y: u64,
52+
}
53+
54+
/// Entry function that takes a Point as argument
55+
public entry fun test_point(sender: &signer, p: Point) acquires TestResult {
56+
if (!exists<TestResult>(std::signer::address_of(sender))) {
57+
move_to(sender, TestResult {
58+
value: 0,
59+
message: std::string::utf8(b"")
60+
});
61+
};
62+
let result = borrow_global_mut<TestResult>(std::signer::address_of(sender));
63+
result.value = p.x + p.y;
64+
result.message = std::string::utf8(b"point_received");
65+
}
66+
67+
/// Entry function that takes a Rectangle as argument
68+
public entry fun test_rectangle(sender: &signer, r: Rectangle) acquires TestResult {
69+
if (!exists<TestResult>(std::signer::address_of(sender))) {
70+
move_to(sender, TestResult {
71+
value: 0,
72+
message: std::string::utf8(b"")
73+
});
74+
};
75+
let result = borrow_global_mut<TestResult>(std::signer::address_of(sender));
76+
result.value = r.top_left.x + r.top_left.y + r.bottom_right.x + r.bottom_right.y;
77+
result.message = std::string::utf8(b"rectangle_received");
78+
}
79+
80+
/// Entry function that takes a Data struct as argument
81+
public entry fun test_data(sender: &signer, d: Data) acquires TestResult {
82+
if (!exists<TestResult>(std::signer::address_of(sender))) {
83+
move_to(sender, TestResult {
84+
value: 0,
85+
message: std::string::utf8(b"")
86+
});
87+
};
88+
let result = borrow_global_mut<TestResult>(std::signer::address_of(sender));
89+
let sum = 0u64;
90+
let i = 0;
91+
let len = std::vector::length(&d.values);
92+
while (i < len) {
93+
sum = sum + *std::vector::borrow(&d.values, i);
94+
i = i + 1;
95+
};
96+
result.value = sum;
97+
result.message = d.name;
98+
}
99+
100+
/// Entry function that takes a Color enum as argument
101+
public entry fun test_color(sender: &signer, c: Color) acquires TestResult {
102+
if (!exists<TestResult>(std::signer::address_of(sender))) {
103+
move_to(sender, TestResult {
104+
value: 0,
105+
message: std::string::utf8(b"")
106+
});
107+
};
108+
let result = borrow_global_mut<TestResult>(std::signer::address_of(sender));
109+
let (value, msg) = match (c) {
110+
Color::Red => (1, b"red"),
111+
Color::Green => (2, b"green"),
112+
Color::Blue => (3, b"blue"),
113+
Color::Custom { r, g, b } => ((r as u64) + (g as u64) + (b as u64), b"custom"),
114+
};
115+
result.value = value;
116+
result.message = std::string::utf8(msg);
117+
}
118+
119+
/// Entry function that takes a Shape enum as argument
120+
public entry fun test_shape(sender: &signer, s: Shape) acquires TestResult {
121+
if (!exists<TestResult>(std::signer::address_of(sender))) {
122+
move_to(sender, TestResult {
123+
value: 0,
124+
message: std::string::utf8(b"")
125+
});
126+
};
127+
let result = borrow_global_mut<TestResult>(std::signer::address_of(sender));
128+
let (value, msg) = match (s) {
129+
Shape::Circle { center, radius } => (center.x + center.y + radius, b"circle"),
130+
Shape::Rect { rect } => (
131+
rect.top_left.x + rect.top_left.y + rect.bottom_right.x + rect.bottom_right.y,
132+
b"rect"
133+
),
134+
};
135+
result.value = value;
136+
result.message = std::string::utf8(msg);
137+
}
138+
139+
/// Entry function that takes a vector of Points
140+
public entry fun test_point_vector(sender: &signer, points: vector<Point>) acquires TestResult {
141+
if (!exists<TestResult>(std::signer::address_of(sender))) {
142+
move_to(sender, TestResult {
143+
value: 0,
144+
message: std::string::utf8(b"")
145+
});
146+
};
147+
let result = borrow_global_mut<TestResult>(std::signer::address_of(sender));
148+
let sum = 0u64;
149+
let i = 0;
150+
let len = std::vector::length(&points);
151+
while (i < len) {
152+
let p = std::vector::borrow(&points, i);
153+
sum = sum + p.x + p.y;
154+
i = i + 1;
155+
};
156+
result.value = sum;
157+
result.message = std::string::utf8(b"point_vector_received");
158+
}
159+
160+
/// Entry function using whitelisted String type - should always work
161+
public entry fun test_string(sender: &signer, s: String) acquires TestResult {
162+
if (!exists<TestResult>(std::signer::address_of(sender))) {
163+
move_to(sender, TestResult {
164+
value: 0,
165+
message: std::string::utf8(b"")
166+
});
167+
};
168+
let result = borrow_global_mut<TestResult>(std::signer::address_of(sender));
169+
result.value = std::string::length(&s);
170+
result.message = s;
171+
}
172+
173+
/// Entry function that takes Option<Point>
174+
public entry fun test_option_point(sender: &signer, opt_point: std::option::Option<Point>) acquires TestResult {
175+
if (!exists<TestResult>(std::signer::address_of(sender))) {
176+
move_to(sender, TestResult {
177+
value: 0,
178+
message: std::string::utf8(b"")
179+
});
180+
};
181+
let result = borrow_global_mut<TestResult>(std::signer::address_of(sender));
182+
if (std::option::is_some(&opt_point)) {
183+
let p = std::option::destroy_some(opt_point);
184+
result.value = p.x + p.y;
185+
result.message = std::string::utf8(b"some_point");
186+
} else {
187+
std::option::destroy_none(opt_point);
188+
result.value = 0;
189+
result.message = std::string::utf8(b"none_point");
190+
}
191+
}
192+
193+
/// Entry function that takes Option<Color>
194+
public entry fun test_option_color(sender: &signer, opt_color: std::option::Option<Color>) acquires TestResult {
195+
if (!exists<TestResult>(std::signer::address_of(sender))) {
196+
move_to(sender, TestResult {
197+
value: 0,
198+
message: std::string::utf8(b"")
199+
});
200+
};
201+
let result = borrow_global_mut<TestResult>(std::signer::address_of(sender));
202+
if (std::option::is_some(&opt_color)) {
203+
let color = std::option::destroy_some(opt_color);
204+
let (value, msg) = match (color) {
205+
Color::Red => (1, b"some_red"),
206+
Color::Green => (2, b"some_green"),
207+
Color::Blue => (3, b"some_blue"),
208+
Color::Custom { r, g, b } => ((r as u64) + (g as u64) + (b as u64), b"some_custom"),
209+
};
210+
result.value = value;
211+
result.message = std::string::utf8(msg);
212+
} else {
213+
std::option::destroy_none(opt_color);
214+
result.value = 0;
215+
result.message = std::string::utf8(b"none_color");
216+
}
217+
}
218+
219+
/// Entry function that takes Container<Color> as argument
220+
public entry fun test_container_color(sender: &signer, container: Container<Color>) acquires TestResult {
221+
if (!exists<TestResult>(std::signer::address_of(sender))) {
222+
move_to(sender, TestResult {
223+
value: 0,
224+
message: std::string::utf8(b"")
225+
});
226+
};
227+
let result = borrow_global_mut<TestResult>(std::signer::address_of(sender));
228+
let (value, msg) = match (container.value) {
229+
Color::Red => (100, b"container_red"),
230+
Color::Green => (200, b"container_green"),
231+
Color::Blue => (300, b"container_blue"),
232+
Color::Custom { r, g, b } => ((r as u64) * 100 + (g as u64) * 10 + (b as u64), b"container_custom"),
233+
};
234+
result.value = value;
235+
result.message = std::string::utf8(msg);
236+
}
237+
238+
/// Generic entry function that takes Container<T> with any type T that has copy + drop
239+
/// This is used to test that Container with non-public type arguments is rejected
240+
public entry fun test_generic_container<T: copy + drop>(sender: &signer, _container: Container<T>) acquires TestResult {
241+
if (!exists<TestResult>(std::signer::address_of(sender))) {
242+
move_to(sender, TestResult {
243+
value: 0,
244+
message: std::string::utf8(b"")
245+
});
246+
};
247+
let result = borrow_global_mut<TestResult>(std::signer::address_of(sender));
248+
result.value = 999;
249+
result.message = std::string::utf8(b"generic_container_received");
250+
}
251+
252+
#[view]
253+
public fun get_result(addr: address): (u64, String) acquires TestResult {
254+
let result = borrow_global<TestResult>(addr);
255+
(result.value, result.message)
256+
}
257+
}

0 commit comments

Comments
 (0)