Skip to content

Commit f768a23

Browse files
committed
sui: initial commit
1 parent 13db910 commit f768a23

File tree

8 files changed

+561
-1
lines changed

8 files changed

+561
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Provide an execution framework and proof-of-concept (PoC) service for [Wormhole]
88

99
- [x] [EVM](./evm/)
1010
- [x] [SVM](./svm/)
11-
- [ ] Sui Move
11+
- [x] Sui Move
1212
- [ ] Aptos Move
1313

1414
## Background

sui/executor/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build/*

sui/executor/Move.lock

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# @generated by Move, please check-in and do not edit manually.
2+
3+
[move]
4+
version = 3
5+
manifest_digest = "FD655AA2017BCDC2BE9BFC9C9A9D9E5E751C2C64258FFA7FB25E2DC0F287E4CA"
6+
deps_digest = "F9B494B64F0615AED0E98FC12A85B85ECD2BC5185C22D30E7F67786BB52E507C"
7+
dependencies = [
8+
{ id = "Bridge", name = "Bridge" },
9+
{ id = "MoveStdlib", name = "MoveStdlib" },
10+
{ id = "Sui", name = "Sui" },
11+
{ id = "SuiSystem", name = "SuiSystem" },
12+
]
13+
14+
[[move.package]]
15+
id = "Bridge"
16+
source = { git = "https://github.com/MystenLabs/sui.git", rev = "04f11afaf5e0", subdir = "crates/sui-framework/packages/bridge" }
17+
18+
dependencies = [
19+
{ id = "MoveStdlib", name = "MoveStdlib" },
20+
{ id = "Sui", name = "Sui" },
21+
{ id = "SuiSystem", name = "SuiSystem" },
22+
]
23+
24+
[[move.package]]
25+
id = "MoveStdlib"
26+
source = { git = "https://github.com/MystenLabs/sui.git", rev = "04f11afaf5e0", subdir = "crates/sui-framework/packages/move-stdlib" }
27+
28+
[[move.package]]
29+
id = "Sui"
30+
source = { git = "https://github.com/MystenLabs/sui.git", rev = "04f11afaf5e0", subdir = "crates/sui-framework/packages/sui-framework" }
31+
32+
dependencies = [
33+
{ id = "MoveStdlib", name = "MoveStdlib" },
34+
]
35+
36+
[[move.package]]
37+
id = "SuiSystem"
38+
source = { git = "https://github.com/MystenLabs/sui.git", rev = "04f11afaf5e0", subdir = "crates/sui-framework/packages/sui-system" }
39+
40+
dependencies = [
41+
{ id = "MoveStdlib", name = "MoveStdlib" },
42+
{ id = "Sui", name = "Sui" },
43+
]
44+
45+
[move.toolchain-version]
46+
compiler-version = "1.46.1"
47+
edition = "2024.beta"
48+
flavor = "sui"

sui/executor/Move.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[package]
2+
name = "executor"
3+
edition = "2024.beta"
4+
license = "Apache 2.0"
5+
authors = ["Wormhole Labs"]
6+
7+
[dependencies]
8+
9+
[addresses]
10+
executor = "0x0"
11+
12+
[dev-dependencies]
13+
14+
[dev-addresses]

sui/executor/sources/executor.move

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
module executor::executor {
4+
use executor::bytes;
5+
use executor::cursor;
6+
use sui::clock::Clock;
7+
use sui::coin::{Coin};
8+
use sui::event;
9+
use sui::sui::{SUI};
10+
11+
const CHAIN_ID: u16 = 21;
12+
13+
const E_QUOTE_SRC_CHAIN_MISMATCH: u64 = 0;
14+
const E_QUOTE_DST_CHAIN_MISMATCH: u64 = 1;
15+
const E_QUOTE_EXPIRED: u64 = 2;
16+
17+
public struct RequestForExecution has copy, drop {
18+
quoter_address: vector<u8>,
19+
amt_paid: u64,
20+
dst_chain: u16,
21+
dst_addr: vector<u8>,
22+
refund_addr: address,
23+
signed_quote: vector<u8>,
24+
request_bytes: vector<u8>,
25+
relay_instructions: vector<u8>,
26+
}
27+
28+
public fun request_execution(
29+
amount: Coin<SUI>,
30+
clock: &Clock,
31+
dst_chain: u16,
32+
dst_addr: vector<u8>,
33+
refund_addr: address,
34+
signed_quote_bytes: vector<u8>,
35+
request_bytes: vector<u8>,
36+
relay_instructions: vector<u8>
37+
) {
38+
let mut cursor = cursor::new(signed_quote_bytes);
39+
bytes::take_bytes(&mut cursor, 4); // prefix
40+
let quoter_address = bytes::take_bytes(&mut cursor, 20);
41+
let payee_address = sui::address::from_bytes(bytes::take_bytes(&mut cursor, 32));
42+
let quote_src_chain = bytes::take_u16_be(&mut cursor);
43+
assert!(quote_src_chain == CHAIN_ID, E_QUOTE_SRC_CHAIN_MISMATCH);
44+
let quote_dst_chain = bytes::take_u16_be(&mut cursor);
45+
assert!(quote_dst_chain == dst_chain, E_QUOTE_DST_CHAIN_MISMATCH);
46+
let expiry_time = bytes::take_u64_be(&mut cursor);
47+
assert!(expiry_time > clock.timestamp_ms() / 1000, E_QUOTE_EXPIRED);
48+
cursor.take_rest();
49+
let amt_paid = amount.value();
50+
transfer::public_transfer(amount, payee_address);
51+
event::emit(RequestForExecution {
52+
quoter_address,
53+
amt_paid,
54+
dst_chain,
55+
dst_addr,
56+
refund_addr,
57+
signed_quote: signed_quote_bytes,
58+
request_bytes,
59+
relay_instructions
60+
});
61+
}
62+
}
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Adapted from https://github.com/wormhole-foundation/wormhole/blob/cc9d8222858827afa9f4780164fcce32ba0dfb3a/sui/wormhole/sources/utils/bytes.move
3+
4+
/// This module implements a library that serializes and deserializes specific
5+
/// types into a buffer (i.e. `vector<u8>`). For serialization, the first
6+
/// argument will be of `&mut vector<u8>`. For deserialization, the first
7+
/// argument will be of `&mut Cursor<u8>` (see `executor::cursor` for more
8+
/// details).
9+
module executor::bytes {
10+
use std::bcs::{Self};
11+
use executor::cursor::{Self, Cursor};
12+
13+
public fun push_u8(buf: &mut vector<u8>, v: u8) {
14+
vector::push_back<u8>(buf, v);
15+
}
16+
17+
public fun push_u16_be(buf: &mut vector<u8>, value: u16) {
18+
push_reverse(buf, value);
19+
}
20+
21+
public fun push_u32_be(buf: &mut vector<u8>, value: u32) {
22+
push_reverse(buf, value);
23+
}
24+
25+
public fun push_u64_be(buf: &mut vector<u8>, value: u64) {
26+
push_reverse(buf, value);
27+
}
28+
29+
public fun push_u128_be(buf: &mut vector<u8>, value: u128) {
30+
push_reverse(buf, value);
31+
}
32+
33+
public fun push_u256_be(buf: &mut vector<u8>, value: u256) {
34+
push_reverse(buf, value);
35+
}
36+
37+
public fun take_u8(cur: &mut Cursor<u8>): u8 {
38+
cursor::poke(cur)
39+
}
40+
41+
public fun take_u16_be(cur: &mut Cursor<u8>): u16 {
42+
let mut out = 0;
43+
let mut i = 0;
44+
while (i < 2) {
45+
out = (out << 8) + (cursor::poke(cur) as u16);
46+
i = i + 1;
47+
};
48+
out
49+
}
50+
51+
public fun take_u32_be(cur: &mut Cursor<u8>): u32 {
52+
let mut out = 0;
53+
let mut i = 0;
54+
while (i < 4) {
55+
out = (out << 8) + (cursor::poke(cur) as u32);
56+
i = i + 1;
57+
};
58+
out
59+
}
60+
61+
public fun take_u64_be(cur: &mut Cursor<u8>): u64 {
62+
let mut out = 0;
63+
let mut i =0;
64+
while (i < 8) {
65+
out = (out << 8) + (cursor::poke(cur) as u64);
66+
i = i + 1;
67+
};
68+
out
69+
}
70+
71+
public fun take_u128_be(cur: &mut Cursor<u8>): u128 {
72+
let mut out = 0;
73+
let mut i = 0;
74+
while (i < 16) {
75+
out = (out << 8) + (cursor::poke(cur) as u128);
76+
i = i + 1;
77+
};
78+
out
79+
}
80+
81+
public fun take_u256_be(cur: &mut Cursor<u8>): u256 {
82+
let mut out = 0;
83+
let mut i = 0;
84+
while (i < 32) {
85+
out = (out << 8) + (cursor::poke(cur) as u256);
86+
i = i + 1;
87+
};
88+
out
89+
}
90+
91+
public fun take_bytes(cur: &mut Cursor<u8>, num_bytes: u64): vector<u8> {
92+
let mut out = vector::empty();
93+
let mut i = 0;
94+
while (i < num_bytes) {
95+
vector::push_back(&mut out, cursor::poke(cur));
96+
i = i + 1;
97+
};
98+
out
99+
}
100+
101+
fun push_reverse<T: drop>(buf: &mut vector<u8>, v: T) {
102+
let mut data = bcs::to_bytes(&v);
103+
vector::reverse(&mut data);
104+
vector::append(buf, data);
105+
}
106+
}
107+
108+
#[test_only]
109+
module executor::bytes_tests {
110+
use executor::bytes::{Self};
111+
use executor::cursor::{Self};
112+
113+
#[test]
114+
fun test_push_u8(){
115+
let u = 0x12;
116+
let mut s = vector::empty();
117+
bytes::push_u8(&mut s, u);
118+
let mut cur = cursor::new(s);
119+
let p = bytes::take_u8(&mut cur);
120+
cursor::destroy_empty(cur);
121+
assert!(p==u, 0);
122+
}
123+
124+
#[test]
125+
fun test_push_u16_be(){
126+
let u = 0x1234;
127+
let mut s = vector::empty();
128+
bytes::push_u16_be(&mut s, u);
129+
let mut cur = cursor::new(s);
130+
let p = bytes::take_u16_be(&mut cur);
131+
cursor::destroy_empty(cur);
132+
assert!(p==u, 0);
133+
}
134+
135+
#[test]
136+
fun test_push_u32_be(){
137+
let u = 0x12345678;
138+
let mut s = vector::empty();
139+
bytes::push_u32_be(&mut s, u);
140+
let mut cur = cursor::new(s);
141+
let p = bytes::take_u32_be(&mut cur);
142+
cursor::destroy_empty(cur);
143+
assert!(p==u, 0);
144+
}
145+
146+
#[test]
147+
fun test_push_u64_be(){
148+
let u = 0x1234567812345678;
149+
let mut s = vector::empty();
150+
bytes::push_u64_be(&mut s, u);
151+
let mut cur = cursor::new(s);
152+
let p = bytes::take_u64_be(&mut cur);
153+
cursor::destroy_empty(cur);
154+
assert!(p==u, 0);
155+
}
156+
157+
#[test]
158+
fun test_push_u128_be(){
159+
let u = 0x12345678123456781234567812345678;
160+
let mut s = vector::empty();
161+
bytes::push_u128_be(&mut s, u);
162+
let mut cur = cursor::new(s);
163+
let p = bytes::take_u128_be(&mut cur);
164+
cursor::destroy_empty(cur);
165+
assert!(p==u, 0);
166+
}
167+
168+
#[test]
169+
fun test_push_u256_be(){
170+
let u =
171+
0x4738691759099793746170047375612500000000000000000000000000009876;
172+
let mut s = vector::empty();
173+
bytes::push_u256_be(&mut s, u);
174+
assert!(
175+
s == x"4738691759099793746170047375612500000000000000000000000000009876",
176+
0
177+
);
178+
}
179+
180+
#[test]
181+
fun test_take_u8() {
182+
let mut cursor = cursor::new(x"99");
183+
let byte = bytes::take_u8(&mut cursor);
184+
assert!(byte==0x99, 0);
185+
cursor::destroy_empty(cursor);
186+
}
187+
188+
#[test]
189+
fun test_take_u16_be() {
190+
let mut cursor = cursor::new(x"9987");
191+
let u = bytes::take_u16_be(&mut cursor);
192+
assert!(u == 0x9987, 0);
193+
cursor::destroy_empty(cursor);
194+
}
195+
196+
#[test]
197+
fun test_take_u32_be() {
198+
let mut cursor = cursor::new(x"99876543");
199+
let u = bytes::take_u32_be(&mut cursor);
200+
assert!(u == 0x99876543, 0);
201+
cursor::destroy_empty(cursor);
202+
}
203+
204+
#[test]
205+
fun test_take_u64_be() {
206+
let mut cursor = cursor::new(x"1300000025000001");
207+
let u = bytes::take_u64_be(&mut cursor);
208+
assert!(u == 0x1300000025000001, 0);
209+
cursor::destroy_empty(cursor);
210+
}
211+
212+
#[test]
213+
fun test_take_u128_be() {
214+
let mut cursor = cursor::new(x"130209AB2500FA0113CD00AE25000001");
215+
let u = bytes::take_u128_be(&mut cursor);
216+
assert!(u == 0x130209AB2500FA0113CD00AE25000001, 0);
217+
cursor::destroy_empty(cursor);
218+
}
219+
220+
#[test]
221+
fun test_to_bytes() {
222+
let mut cursor = cursor::new(b"hello world");
223+
let hello = bytes::take_bytes(&mut cursor, 5);
224+
bytes::take_u8(&mut cursor);
225+
let world = bytes::take_bytes(&mut cursor, 5);
226+
assert!(hello == b"hello", 0);
227+
assert!(world == b"world", 0);
228+
cursor::destroy_empty(cursor);
229+
}
230+
231+
}

0 commit comments

Comments
 (0)