Skip to content

Commit 6d69496

Browse files
Refactor Aptos module and utility functions for improved message handling
- Renamed `DecodedMessage` struct to `ReceiveData` for clarity. - Simplified message parsing logic in `parse_message` function. - Updated `lz_receive_impl` to utilize the new `ReceiveData` struct. - Removed unused utility functions and constants from `utils.move`. - Added unit tests for `parse_message` to ensure correct functionality.
1 parent 079695f commit 6d69496

3 files changed

Lines changed: 105 additions & 128 deletions

File tree

examples/oapp-aptos-move/sources/oapp.move

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ module oapp::oapp {
3232
value: u64
3333
}
3434

35-
struct DecodedMessage has key {
35+
struct ReceiveData has key {
3636
address1: address,
3737
address2: address,
3838
number: u256,
@@ -42,7 +42,7 @@ module oapp::oapp {
4242

4343
fun init_module(account: &signer) {
4444
move_to(account, Counter { value: 0 });
45-
move_to(account, DecodedMessage {
45+
move_to(account, ReceiveData {
4646
address1: @0x0,
4747
address2: @0x0,
4848
number: 0,
@@ -51,36 +51,20 @@ module oapp::oapp {
5151
});
5252
}
5353

54-
public(friend) fun lz_receive_impl(
55-
_src_eid: u32,
56-
_sender: Bytes32,
57-
_nonce: u64,
58-
_guid: Bytes32,
59-
_message: vector<u8>,
60-
_extra_data: vector<u8>,
61-
receive_value: Option<FungibleAsset>,
62-
) acquires Counter, DecodedMessage {
63-
option::destroy(receive_value, |value| primary_fungible_store::deposit(OAPP_ADDRESS(), value));
64-
65-
let counter = borrow_global_mut<Counter>(OAPP_ADDRESS());
66-
counter.value = counter.value + 1;
67-
54+
public fun parse_message(message: vector<u8>): (address, address, u256) {
6855
let string_length = (
69-
(*vector::borrow(&_message, 60) as u64) << 24 |
70-
(*vector::borrow(&_message, 61) as u64) << 16 |
71-
(*vector::borrow(&_message, 62) as u64) << 8 |
72-
(*vector::borrow(&_message, 63) as u64)
56+
(*vector::borrow(&message, 60) as u64) << 24 |
57+
(*vector::borrow(&message, 61) as u64) << 16 |
58+
(*vector::borrow(&message, 62) as u64) << 8 |
59+
(*vector::borrow(&message, 63) as u64)
7360
);
7461

7562
let string_start = 64;
7663
let string_end = string_start + string_length;
77-
let string_bytes = vector::slice(&_message, string_start, string_end);
78-
let decoded_string = bytes_to_string(string_bytes);
79-
80-
let string_content_bytes = *string::bytes(&decoded_string);
81-
let hex_part_bytes = vector::slice(&string_content_bytes, 2, vector::length(&string_content_bytes));
82-
let hex_part_string = bytes_to_string(hex_part_bytes);
83-
let hex_content = hex_string_to_bytes(hex_part_string);
64+
let string_bytes = vector::slice(&message, string_start, string_end);
65+
66+
let hex_bytes = vector::slice(&string_bytes, 2, vector::length(&string_bytes));
67+
let hex_content = hex_string_to_bytes(string::utf8(hex_bytes));
8468

8569
let addr1_bytes = vector::slice(&hex_content, 0, 32);
8670
let decoded_addr1 = from_bcs::to_address(addr1_bytes);
@@ -104,12 +88,31 @@ module oapp::oapp {
10488
j = j + 1;
10589
};
10690

107-
let decoded_message = borrow_global_mut<DecodedMessage>(OAPP_ADDRESS());
108-
decoded_message.address1 = decoded_addr1;
109-
decoded_message.address2 = decoded_addr2;
110-
decoded_message.number = number_u256;
111-
decoded_message.counter = counter.value;
112-
decoded_message.raw_message = _message;
91+
(decoded_addr1, decoded_addr2, number_u256)
92+
}
93+
94+
public(friend) fun lz_receive_impl(
95+
_src_eid: u32,
96+
_sender: Bytes32,
97+
_nonce: u64,
98+
_guid: Bytes32,
99+
_message: vector<u8>,
100+
_extra_data: vector<u8>,
101+
receive_value: Option<FungibleAsset>,
102+
) acquires Counter, ReceiveData {
103+
option::destroy(receive_value, |value| primary_fungible_store::deposit(OAPP_ADDRESS(), value));
104+
105+
let counter = borrow_global_mut<Counter>(OAPP_ADDRESS());
106+
counter.value = counter.value + 1;
107+
108+
let (decoded_addr1, decoded_addr2, number_u256) = parse_message(_message);
109+
110+
let receive_data = borrow_global_mut<ReceiveData>(OAPP_ADDRESS());
111+
receive_data.address1 = decoded_addr1;
112+
receive_data.address2 = decoded_addr2;
113+
receive_data.number = number_u256;
114+
receive_data.counter = counter.value;
115+
receive_data.raw_message = _message;
113116
}
114117

115118
// todo: replicate the logic in here where sending a message must happen
@@ -188,18 +191,18 @@ module oapp::oapp {
188191
// ================================================== View Functions ===========================================
189192

190193
#[view]
191-
public fun get_decoded_address1(): address acquires DecodedMessage {
192-
borrow_global<DecodedMessage>(OAPP_ADDRESS()).address1
194+
public fun get_decoded_address1(): address acquires ReceiveData {
195+
borrow_global<ReceiveData>(OAPP_ADDRESS()).address1
193196
}
194197

195198
#[view]
196-
public fun get_decoded_address2(): address acquires DecodedMessage {
197-
borrow_global<DecodedMessage>(OAPP_ADDRESS()).address2
199+
public fun get_decoded_address2(): address acquires ReceiveData {
200+
borrow_global<ReceiveData>(OAPP_ADDRESS()).address2
198201
}
199202

200203
#[view]
201-
public fun get_decoded_number(): u256 acquires DecodedMessage {
202-
borrow_global<DecodedMessage>(OAPP_ADDRESS()).number
204+
public fun get_decoded_number(): u256 acquires ReceiveData {
205+
borrow_global<ReceiveData>(OAPP_ADDRESS()).number
203206
}
204207

205208
#[view]
@@ -208,8 +211,8 @@ module oapp::oapp {
208211
}
209212

210213
#[view]
211-
public fun get_raw_message(): vector<u8> acquires DecodedMessage {
212-
borrow_global<DecodedMessage>(OAPP_ADDRESS()).raw_message
214+
public fun get_raw_message(): vector<u8> acquires ReceiveData {
215+
borrow_global<ReceiveData>(OAPP_ADDRESS()).raw_message
213216
}
214217

215218
// ================================================== Error Codes =================================================
@@ -218,4 +221,6 @@ module oapp::oapp {
218221
const EINSUFFICIENT_BALANCE: u64 = 2;
219222
const EINVALID_HEX_CHAR: u64 = 3;
220223
const EINVALID_LENGTH: u64 = 4;
224+
225+
221226
}

examples/oapp-aptos-move/sources/utils.move

Lines changed: 17 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,17 @@ module oapp::utils {
1515
*string::bytes(&str)
1616
}
1717

18-
/// Safely converts a vector of bytes to a UTF-8 string
19-
/// Returns an Option: Some(string) if valid UTF-8, None if invalid
20-
public fun try_bytes_to_string(bytes: vector<u8>): std::option::Option<String> {
21-
if (string::try_utf8(bytes) != std::option::none()) {
22-
std::option::some(string::utf8(bytes))
23-
} else {
24-
std::option::none()
25-
}
26-
}
27-
2818
/// Converts a hex string (without 0x prefix) to a vector of bytes
2919
/// Example: "48656c6c6f" -> b"Hello"
3020
/// Automatically pads odd-length strings with a leading zero
3121
public fun hex_string_to_bytes(hex_str: String): vector<u8> {
3222
let hex_bytes = string::bytes(&hex_str);
3323
let len = vector::length(hex_bytes);
3424

25+
// If the hex string is odd length, pad with leading zero
3526
let padded_hex = if (len % 2 == 1) {
3627
let padded = vector::empty<u8>();
37-
vector::push_back(&mut padded, 48);
28+
vector::push_back(&mut padded, ASCII_ZERO);
3829
vector::append(&mut padded, *hex_bytes);
3930
padded
4031
} else {
@@ -54,27 +45,6 @@ module oapp::utils {
5445
result
5546
}
5647

57-
/// Converts a hex string to an Aptos address
58-
/// Supports both with and without 0x prefix
59-
/// The hex string should represent exactly 32 bytes (64 hex characters)
60-
public fun hex_string_to_address(hex_str: String): address {
61-
let clean_hex = strip_hex_prefix(hex_str);
62-
let hex_bytes = hex_string_to_bytes(clean_hex);
63-
64-
let padded_bytes = pad_to_32_bytes(hex_bytes);
65-
from_bcs::to_address(padded_bytes)
66-
}
67-
68-
/// Converts an address to a hex string with 0x prefix
69-
public fun address_to_hex_string(addr: address): String {
70-
let addr_bytes = bcs::to_bytes(&addr);
71-
let hex_str = bytes_to_hex_string(addr_bytes);
72-
let prefix = b"0x";
73-
let hex_bytes = string::bytes(&hex_str);
74-
vector::append(&mut prefix, *hex_bytes);
75-
string::utf8(prefix)
76-
}
77-
7848
/// Converts bytes to a hex string (lowercase)
7949
public fun bytes_to_hex_string(bytes: vector<u8>): String {
8050
let hex_chars = b"0123456789abcdef";
@@ -94,66 +64,26 @@ module oapp::utils {
9464
string::utf8(result)
9565
}
9666

97-
/// Helper function to strip 0x or 0X prefix from hex string
98-
fun strip_hex_prefix(hex_str: String): String {
99-
let bytes = string::bytes(&hex_str);
100-
let len = vector::length(bytes);
101-
102-
if (len >= 2) {
103-
let first = *vector::borrow(bytes, 0);
104-
let second = *vector::borrow(bytes, 1);
105-
106-
if (first == 48 && (second == 120 || second == 88)) {
107-
let remaining = vector::empty<u8>();
108-
let i = 2;
109-
while (i < len) {
110-
vector::push_back(&mut remaining, *vector::borrow(bytes, i));
111-
i = i + 1;
112-
};
113-
return string::utf8(remaining)
114-
}
115-
};
116-
117-
hex_str
118-
}
119-
120-
/// Helper function to pad bytes to 32 bytes (left-padded with zeros)
121-
fun pad_to_32_bytes(bytes: vector<u8>): vector<u8> {
122-
let len = vector::length(&bytes);
123-
assert!(len <= 32, EINVALID_ADDRESS_LENGTH);
124-
125-
if (len == 32) {
126-
return bytes
127-
};
128-
129-
let result = vector::empty<u8>();
130-
let padding_needed = 32 - len;
131-
let i = 0;
132-
133-
while (i < padding_needed) {
134-
vector::push_back(&mut result, 0);
135-
i = i + 1;
136-
};
137-
138-
vector::append(&mut result, bytes);
139-
result
140-
}
141-
14267
/// Helper function to convert a hex character to u8
14368
fun hex_char_to_u8(char: u8): u8 {
144-
if (char >= 48 && char <= 57) {
145-
char - 48
146-
} else if (char >= 65 && char <= 70) {
147-
char - 65 + 10
148-
} else if (char >= 97 && char <= 102) {
149-
char - 97 + 10
69+
if (char >= ASCII_ZERO && char <= ASCII_NINE) {
70+
char - ASCII_ZERO
71+
} else if (char >= ASCII_UPPERCASE_A && char <= ASCII_UPPERCASE_F) {
72+
char - ASCII_UPPERCASE_A + 10
73+
} else if (char >= ASCII_LOWERCASE_A && char <= ASCII_LOWERCASE_F) {
74+
char - ASCII_LOWERCASE_A + 10
15075
} else {
15176
abort EINVALID_HEX_CHARACTER
15277
}
15378
}
15479

155-
const EINVALID_LENGTH: u64 = 1;
156-
const EINVALID_HEX_LENGTH: u64 = 2;
157-
const EINVALID_HEX_CHARACTER: u64 = 3;
158-
const EINVALID_ADDRESS_LENGTH: u64 = 4;
80+
const ASCII_ZERO: u8 = 48;
81+
const ASCII_NINE: u8 = 57;
82+
const ASCII_UPPERCASE_A: u8 = 65;
83+
const ASCII_UPPERCASE_F: u8 = 70;
84+
const ASCII_LOWERCASE_A: u8 = 97;
85+
const ASCII_LOWERCASE_F: u8 = 102;
86+
87+
const EINVALID_HEX_CHARACTER: u64 = 1;
88+
const EINVALID_ADDRESS_LENGTH: u64 = 2;
15989
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#[test_only]
2+
module oapp::oapp_tests {
3+
use std::string;
4+
use std::vector;
5+
use aptos_std::from_bcs;
6+
use oapp::utils::hex_string_to_bytes;
7+
use oapp::oapp::parse_message;
8+
9+
#[test]
10+
fun test_parse_message() {
11+
let expected_addr1 = @0x1234567890123456789012345678901234567890;
12+
let expected_addr2 = @0x9876543210987654321098765432109876543210;
13+
let expected_number: u256 = 123456789012345678901234567890;
14+
15+
let encoded_data = x"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c23078303030303030303030303030303030303030303030303030313233343536373839303132333435363738393031323334353637383930313233343536373839303030303030303030303030303030303030303030303030303938373635343332313039383736353433323130393837363534333231303938373635343332313030303030303030303030303030303030303030303030303030303030303030303030303030303031386565393066663663333733653065653465336630616432000000000000000000000000000000000000000000000000000000000000";
16+
17+
let (actual_addr1, actual_addr2, actual_number) = parse_message(encoded_data);
18+
19+
assert!(actual_addr1 == expected_addr1, 1);
20+
assert!(actual_addr2 == expected_addr2, 2);
21+
assert!(actual_number == expected_number, 3);
22+
}
23+
24+
#[test]
25+
fun test_parse_message_with_prefix() {
26+
let expected_addr1 = @0x58b730d07e98a22f2b357bee721115c986e4dc873c1884763708ee3d4006f74e;
27+
let expected_addr2 = @0x58b730d07e98a22f2b357bee721115c986e4dc873c1884763708ee3d4006f74e;
28+
let expected_number: u256 = 123456789012345678901234567890;
29+
30+
let encoded_data = x"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c23078353862373330643037653938613232663262333537626565373231313135633938366534646338373363313838343736333730386565336434303036663734653538623733306430376539386132326632623335376265653732313131356339383665346463383733633138383437363337303865653364343030366637346530303030303030303030303030303030303030303030303030303030303030303030303030303031386565393066663663333733653065653465336630616432000000000000000000000000000000000000000000000000000000000000";
31+
32+
let (actual_addr1, actual_addr2, actual_number) = parse_message(encoded_data);
33+
34+
std::debug::print(&actual_addr1);
35+
std::debug::print(&actual_addr2);
36+
std::debug::print(&actual_number);
37+
38+
assert!(actual_addr1 == expected_addr1, 1);
39+
assert!(actual_addr2 == expected_addr2, 2);
40+
assert!(actual_number == expected_number, 3);
41+
}
42+
}

0 commit comments

Comments
 (0)