Skip to content

Commit fb6672f

Browse files
authored
Aptos accumulators (#904)
* Pin dependency versions * Implement accumulator support on aptos * Fix formatting on error.move in aptos * Add CI workflow for aptos * Upgrade to aptos cli 1.0.4
1 parent 919f71e commit fb6672f

File tree

11 files changed

+741
-62
lines changed

11 files changed

+741
-62
lines changed

.github/workflows/aptos-contract.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
on:
2+
pull_request:
3+
paths:
4+
- target_chains/aptos/contracts/**
5+
push:
6+
branches:
7+
- main
8+
paths:
9+
- target_chains/aptos/contracts/**
10+
11+
name: Aptos Contract
12+
13+
jobs:
14+
aptos-tests:
15+
name: Aptos tests
16+
runs-on: ubuntu-latest
17+
defaults:
18+
run:
19+
working-directory: target_chains/aptos/contracts/
20+
steps:
21+
- uses: actions/checkout@v3
22+
23+
- name: Download CLI
24+
run: wget https://github.com/aptos-labs/aptos-core/releases/download/aptos-cli-v1.0.4/aptos-cli-1.0.4-Ubuntu-22.04-x86_64.zip
25+
26+
- name: Unzip CLI
27+
run: unzip aptos-cli-1.0.4-Ubuntu-22.04-x86_64.zip
28+
29+
- name: Run tests
30+
run: ./aptos move test

target_chains/aptos/contracts/Move.toml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@ version = "0.0.1"
44
upgrade_policy = "compatible"
55

66
[dependencies]
7-
# TODO: pin versions before mainnet release
8-
AptosFramework = { git = "https://github.com/aptos-labs/aptos-core.git", subdir = "aptos-move/framework/aptos-framework/", rev = "main" }
9-
MoveStdlib = { git = "https://github.com/aptos-labs/aptos-core.git", subdir = "aptos-move/framework/move-stdlib/", rev = "main" }
10-
AptosStdlib = { git = "https://github.com/aptos-labs/aptos-core.git", subdir = "aptos-move/framework/aptos-stdlib/", rev = "main" }
11-
AptosToken = { git = "https://github.com/aptos-labs/aptos-core.git", subdir = "aptos-move/framework/aptos-token/", rev = "main" }
7+
AptosFramework = { git = "https://github.com/aptos-labs/aptos-core.git", subdir = "aptos-move/framework/aptos-framework/", rev = "2c74a456298fcd520241a562119b6fe30abdaae2" }
8+
MoveStdlib = { git = "https://github.com/aptos-labs/aptos-core.git", subdir = "aptos-move/framework/move-stdlib/", rev = "2c74a456298fcd520241a562119b6fe30abdaae2" }
9+
AptosStdlib = { git = "https://github.com/aptos-labs/aptos-core.git", subdir = "aptos-move/framework/aptos-stdlib/", rev = "2c74a456298fcd520241a562119b6fe30abdaae2" }
10+
AptosToken = { git = "https://github.com/aptos-labs/aptos-core.git", subdir = "aptos-move/framework/aptos-token/", rev = "2c74a456298fcd520241a562119b6fe30abdaae2" }
1211
Wormhole = { git = "https://github.com/wormhole-foundation/wormhole.git", subdir = "aptos/wormhole", rev = "aptos/integration" }
1312
Deployer = { git = "https://github.com/wormhole-foundation/wormhole.git", subdir = "aptos/deployer", rev = "aptos/integration" }
1413

target_chains/aptos/contracts/sources/batch_price_attestation.move

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ module pyth::batch_price_attestation {
159159
}
160160

161161
#[test]
162-
#[expected_failure(abort_code = 65560)]
162+
#[expected_failure(abort_code = 65560, location = pyth::batch_price_attestation)]
163163
fun test_deserialize_batch_price_attestation_invalid_magic() {
164164
// A batch price attestation with a magic number of 0x50325749
165165
let bytes = x"5032574900030000000102000400951436e0be37536be96f0896366089506a59763d036728332d3e3038047851aea7c6c75c89f14810ec1c54c03ab8f1864a4c4032791f05747f560faec380a695d1000000000000049a0000000000000008fffffffb00000000000005dc0000000000000003000000000100000001000000006329c0eb000000006329c0e9000000006329c0e400000000000006150000000000000007215258d81468614f6b7e194c5d145609394f67b041e93e6695dcc616faadd0603b9551a68d01d954d6387aff4df1529027ffb2fee413082e509feb29cc4904fe000000000000041a0000000000000003fffffffb00000000000005cb0000000000000003010000000100000001000000006329c0eb000000006329c0e9000000006329c0e4000000000000048600000000000000078ac9cf3ab299af710d735163726fdae0db8465280502eb9f801f74b3c1bd190333832fad6e36eb05a8972fe5f219b27b5b2bb2230a79ce79beb4c5c5e7ecc76d00000000000003f20000000000000002fffffffb00000000000005e70000000000000003010000000100000001000000006329c0eb000000006329c0e9000000006329c0e40000000000000685000000000000000861db714e9ff987b6fedf00d01f9fea6db7c30632d6fc83b7bc9459d7192bc44a21a28b4c6619968bd8c20e95b0aaed7df2187fd310275347e0376a2cd7427db800000000000006cb0000000000000001fffffffb00000000000005e40000000000000003010000000100000001000000006329c0eb000000006329c0e9000000006329c0e400000000000007970000000000000001";

target_chains/aptos/contracts/sources/error.move

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,27 +79,47 @@ module pyth::error {
7979
error::invalid_state(19)
8080
}
8181

82-
public fun invalid_governance_magic_value(): u64 {
82+
public fun invalid_governance_magic_value(): u64 {
8383
error::invalid_argument(20)
84-
}
84+
}
8585

86-
public fun magnitude_too_large(): u64 {
86+
public fun magnitude_too_large(): u64 {
8787
error::invalid_argument(21)
88-
}
88+
}
8989

90-
public fun governance_contract_upgrade_chain_id_zero(): u64 {
90+
public fun governance_contract_upgrade_chain_id_zero(): u64 {
9191
error::invalid_argument(22)
92-
}
92+
}
9393

94-
public fun invalid_price_status(): u64 {
94+
public fun invalid_price_status(): u64 {
9595
error::invalid_argument(23)
96-
}
96+
}
9797

98-
public fun invalid_attestation_magic_value(): u64 {
98+
public fun invalid_attestation_magic_value(): u64 {
9999
error::invalid_argument(24)
100-
}
100+
}
101101

102-
public fun data_source_emitter_address_and_chain_ids_different_lengths(): u64 {
102+
public fun data_source_emitter_address_and_chain_ids_different_lengths(): u64 {
103103
error::invalid_argument(25)
104-
}
104+
}
105+
106+
public fun invalid_accumulator_payload(): u64 {
107+
error::invalid_argument(26)
108+
}
109+
110+
public fun invalid_accumulator_message(): u64 {
111+
error::invalid_argument(27)
112+
}
113+
114+
public fun invalid_wormhole_message(): u64 {
115+
error::invalid_argument(28)
116+
}
117+
118+
public fun invalid_proof(): u64 {
119+
error::invalid_argument(29)
120+
}
121+
122+
public fun invalid_keccak160_length(): u64 {
123+
error::invalid_argument(30)
124+
}
105125
}

target_chains/aptos/contracts/sources/governance/governance.move

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,15 @@ module pyth::governance_test {
8585
}
8686

8787
#[test]
88-
#[expected_failure(abort_code = 6)]
88+
#[expected_failure(abort_code = 6, location = wormhole::vaa)]
8989
fun test_execute_governance_instruction_invalid_vaa() {
9090
setup_test(50, 24, x"f06413c0148c78916554f134dcd17a7c8029a3a2bda475a4a1182305c53078bf", 100);
9191
let vaa_bytes = x"6c436741b108";
9292
governance::execute_governance_instruction(vaa_bytes);
9393
}
9494

9595
#[test]
96-
#[expected_failure(abort_code = 65550)]
96+
#[expected_failure(abort_code = 65550, location = pyth::governance)]
9797
fun test_execute_governance_instruction_invalid_data_source() {
9898
setup_test(100, 50, x"f06413c0148c78916554f134dcd17a7c8029a3a2bda475a4a1182305c53078bf", 100);
9999

@@ -105,7 +105,7 @@ module pyth::governance_test {
105105
}
106106

107107
#[test]
108-
#[expected_failure(abort_code = 65551)]
108+
#[expected_failure(abort_code = 65551, location = pyth::governance)]
109109
fun test_execute_governance_instruction_invalid_sequence_number_0() {
110110
setup_test(100, 50, x"f06413c0148c78916554f134dcd17a7c8029a3a2bda475a4a1182305c53078bf", 100);
111111
assert!(state::get_last_executed_governance_sequence() == 0, 1);
@@ -119,7 +119,7 @@ module pyth::governance_test {
119119
}
120120

121121
#[test]
122-
#[expected_failure(abort_code = 65556)]
122+
#[expected_failure(abort_code = 65556, location = pyth::governance_instruction)]
123123
fun test_execute_governance_instruction_invalid_instruction_magic() {
124124
setup_test(100, 50, x"f06413c0148c78916554f134dcd17a7c8029a3a2bda475a4a1182305c53078bf", 100);
125125

@@ -133,7 +133,7 @@ module pyth::governance_test {
133133
}
134134

135135
#[test]
136-
#[expected_failure(abort_code = 65548)]
136+
#[expected_failure(abort_code = 65548, location = pyth::governance_instruction)]
137137
fun test_execute_governance_instruction_invalid_module() {
138138
setup_test(100, 50, x"f06413c0148c78916554f134dcd17a7c8029a3a2bda475a4a1182305c53078bf", 100);
139139

@@ -148,7 +148,7 @@ module pyth::governance_test {
148148
}
149149

150150
#[test]
151-
#[expected_failure(abort_code = 65549)]
151+
#[expected_failure(abort_code = 65549, location = pyth::governance_instruction)]
152152
fun test_execute_governance_instruction_invalid_target_chain() {
153153
setup_test(100, 50, x"f06413c0148c78916554f134dcd17a7c8029a3a2bda475a4a1182305c53078bf", 100);
154154

@@ -164,7 +164,7 @@ module pyth::governance_test {
164164
}
165165

166166
#[test]
167-
#[expected_failure(abort_code = 65552)]
167+
#[expected_failure(abort_code = 65552, location = pyth::governance_action)]
168168
fun test_execute_governance_instruction_invalid_action() {
169169
setup_test(100, 50, x"f06413c0148c78916554f134dcd17a7c8029a3a2bda475a4a1182305c53078bf", 100);
170170

@@ -204,7 +204,7 @@ module pyth::governance_test {
204204
}
205205

206206
#[test]
207-
#[expected_failure(abort_code = 65558)]
207+
#[expected_failure(abort_code = 65558, location = pyth::governance)]
208208
fun test_execute_governance_instruction_upgrade_contract_chain_id_zero() {
209209
setup_test(100, 50, x"f06413c0148c78916554f134dcd17a7c8029a3a2bda475a4a1182305c53078bf", 100);
210210

@@ -280,7 +280,7 @@ module pyth::governance_test {
280280
}
281281

282282
#[test]
283-
#[expected_failure(abort_code = 65550)]
283+
#[expected_failure(abort_code = 65550, location = pyth::governance)]
284284
fun test_execute_governance_instruction_set_governance_data_source_old_source_invalid() {
285285
let initial_governance_emitter_chain_id = 50;
286286
let initial_governance_emitter_address = x"f06413c0148c78916554f134dcd17a7c8029a3a2bda475a4a1182305c53078bf";

target_chains/aptos/contracts/sources/governance/governance_instruction.move

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,21 +64,21 @@ module pyth::governance_instruction {
6464
}
6565

6666
#[test]
67-
#[expected_failure(abort_code = 65556)]
67+
#[expected_failure(abort_code = 65556, location = pyth::governance_instruction)]
6868
fun test_from_byte_vec_invalid_magic() {
6969
let bytes = x"5054474eb01087a85361f738f19454e66664d3c9";
7070
destroy(from_byte_vec(bytes));
7171
}
7272

7373
#[test]
74-
#[expected_failure(abort_code = 65548)]
74+
#[expected_failure(abort_code = 65548, location = pyth::governance_instruction)]
7575
fun test_from_byte_vec_invalid_module() {
7676
let bytes = x"5054474db00187a85361f738f19454e66664d3c9";
7777
destroy(from_byte_vec(bytes));
7878
}
7979

8080
#[test]
81-
#[expected_failure(abort_code = 65548)]
81+
#[expected_failure(abort_code = 65548, location = pyth::governance_instruction)]
8282
fun test_from_byte_vec_invalid_target_chain_id() {
8383
let bytes = x"5054474db00187a85361f738f19454e66664d3c9";
8484
destroy(from_byte_vec(bytes));

target_chains/aptos/contracts/sources/i64.move

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ module pyth::i64 {
7676
}
7777

7878
#[test]
79-
#[expected_failure(abort_code = 65557)]
79+
#[expected_failure(abort_code = 65557, location = pyth::i64)]
8080
fun test_magnitude_too_large_positive() {
8181
new(0x8000000000000000, false);
8282
}
@@ -88,7 +88,7 @@ module pyth::i64 {
8888
}
8989

9090
#[test]
91-
#[expected_failure(abort_code = 65557)]
91+
#[expected_failure(abort_code = 65557, location = pyth::i64)]
9292
fun test_magnitude_too_large_negative() {
9393
new(0x8000000000000001, true);
9494
}
@@ -115,7 +115,7 @@ module pyth::i64 {
115115
}
116116

117117
#[test]
118-
#[expected_failure(abort_code = 196609)]
118+
#[expected_failure(abort_code = 196609, location = pyth::i64)]
119119
fun test_get_magnitude_if_positive_negative() {
120120
assert!(get_magnitude_if_positive(&new(7686, true)) == 7686, 1);
121121
}
@@ -126,7 +126,7 @@ module pyth::i64 {
126126
}
127127

128128
#[test]
129-
#[expected_failure(abort_code = 196627)]
129+
#[expected_failure(abort_code = 196627, location = pyth::i64)]
130130
fun test_get_magnitude_if_negative_positive() {
131131
assert!(get_magnitude_if_negative(&new(7686, false)) == 7686, 1);
132132
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
module pyth::keccak160 {
2+
use std::vector;
3+
use pyth::error;
4+
use std::aptos_hash;
5+
6+
struct Hash has drop {
7+
data: vector<u8>,
8+
}
9+
10+
const HASH_LENGTH: u64 = 20;
11+
12+
public fun get_data(hash: &Hash): vector<u8> {
13+
hash.data
14+
}
15+
16+
public fun get_hash_length(): u64 {
17+
HASH_LENGTH
18+
}
19+
20+
public fun new(data: vector<u8>): Hash {
21+
assert!(vector::length(&data) == HASH_LENGTH, error::invalid_keccak160_length());
22+
Hash { data }
23+
}
24+
25+
public fun from_data(data: vector<u8>): Hash {
26+
let hash = aptos_hash::keccak256(data);
27+
while (vector::length(&hash) > HASH_LENGTH) {
28+
vector::pop_back(&mut hash);
29+
};
30+
new(hash)
31+
}
32+
33+
public fun is_smaller(lhs: &Hash, rhs: &Hash): bool {
34+
let i = 0;
35+
while (i < vector::length(&get_data(lhs))) {
36+
let lhs_val: u8 = *vector::borrow(&get_data(lhs), i);
37+
let rhs_val: u8 = *vector::borrow(&get_data(rhs), i);
38+
if (lhs_val != rhs_val) {
39+
return lhs_val < rhs_val
40+
};
41+
i = i + 1;
42+
};
43+
false
44+
}
45+
46+
47+
#[test]
48+
fun test_from_data() {
49+
let hash = from_data(vector[0]);
50+
let expected = new(x"bc36789e7a1e281436464229828f817d6612f7b4");
51+
assert!(&hash == &expected, 1);
52+
}
53+
54+
#[test]
55+
fun test_is_smaller() {
56+
let h1 = new(x"0000000000000000010000000000000000000000");
57+
let h2 = new(x"0000000000000000000300000000000000000000");
58+
let h3 = new(x"0000000000000000000200000000000000000000");
59+
assert!(is_smaller(&h3, &h2), 1);
60+
assert!(!is_smaller(&h2, &h3), 1);
61+
62+
assert!(is_smaller(&h2, &h1), 1);
63+
assert!(!is_smaller(&h1, &h2), 1);
64+
65+
assert!(is_smaller(&h3, &h1), 1);
66+
assert!(!is_smaller(&h1, &h3), 1);
67+
68+
assert!(!is_smaller(&h1, &h1), 1);
69+
assert!(!is_smaller(&h2, &h2), 1);
70+
assert!(!is_smaller(&h3, &h3), 1);
71+
}
72+
73+
#[test]
74+
fun test_new_success() {
75+
new(x"05c51b04b820c0f704e3fdd2e4fc1e70aff26dff");
76+
}
77+
78+
#[test]
79+
#[expected_failure(abort_code = 65566, location = pyth::keccak160)]
80+
fun test_new_wrong_size() {
81+
new(vector[1, 2, 3]);
82+
}
83+
}

0 commit comments

Comments
 (0)