2
2
super :: Bank ,
3
3
crate :: accounts_index:: { ScanConfig , ScanError } ,
4
4
byteorder:: LittleEndian ,
5
+ byteorder:: ReadBytesExt ,
5
6
itertools:: Itertools ,
6
7
log:: * ,
7
8
pyth_oracle:: validator:: AggregationError ,
9
+ pythnet_sdk:: {
10
+ accumulators:: { merkle:: MerkleAccumulator , Accumulator } ,
11
+ hashers:: keccak256_160:: Keccak160 ,
12
+ wormhole:: { AccumulatorSequenceTracker , MessageData , PostedMessageUnreliableData } ,
13
+ } ,
8
14
solana_sdk:: {
9
15
account:: { AccountSharedData , ReadableAccount } ,
10
- feature_set,
16
+ borsh , feature_set,
11
17
hash:: hashv,
12
18
pubkey:: Pubkey ,
13
19
} ,
14
- std:: {
15
- env:: { self , VarError } ,
16
- str:: FromStr ,
17
- } ,
20
+ std:: env:: { self , VarError } ,
18
21
} ;
19
22
20
23
pub const ACCUMULATOR_RING_SIZE : u32 = 10_000 ;
21
24
22
25
lazy_static ! {
23
- pub static ref ORACLE_PUBKEY : Pubkey = match env:: var( "PYTH_ORACLE_PUBKEY" ) {
24
- Ok ( value) => value
26
+ pub static ref MESSAGE_BUFFER_PID : Pubkey = env_pubkey_or(
27
+ "MESSAGE_BUFFER_PID" ,
28
+ Pubkey :: new_from_array( pythnet_sdk:: MESSAGE_BUFFER_PID ) ,
29
+ ) ;
30
+ pub static ref ACCUMULATOR_EMITTER_ADDR : Pubkey = env_pubkey_or(
31
+ "ACCUMULATOR_EMITTER_ADDR" ,
32
+ Pubkey :: new_from_array( pythnet_sdk:: ACCUMULATOR_EMITTER_ADDRESS ) ,
33
+ ) ;
34
+ pub static ref ACCUMULATOR_SEQUENCE_ADDR : Pubkey = env_pubkey_or(
35
+ "ACCUMULATOR_SEQUENCE_ADDR" ,
36
+ Pubkey :: new_from_array( pythnet_sdk:: pythnet:: ACCUMULATOR_SEQUENCE_ADDR ) ,
37
+ ) ;
38
+ pub static ref WORMHOLE_PID : Pubkey = env_pubkey_or(
39
+ "WORMHOLE_PID" ,
40
+ Pubkey :: new_from_array( pythnet_sdk:: pythnet:: WORMHOLE_PID ) ,
41
+ ) ;
42
+ pub static ref ORACLE_PID : Pubkey = env_pubkey_or(
43
+ "ORACLE_PID" ,
44
+ "FsJ3A3u2vn5cTVofAjvy6y5kwABJAqYWpe4975bi2epH"
25
45
. parse( )
26
- . expect( "invalid value of PYTH_ORACLE_PUBKEY env var" ) ,
27
- Err ( VarError :: NotPresent ) => {
28
- // Pythnet oracle program address
29
- "FsJ3A3u2vn5cTVofAjvy6y5kwABJAqYWpe4975bi2epH" . parse( ) . unwrap( )
30
- }
31
- Err ( VarError :: NotUnicode ( err) ) => {
32
- panic!( "invalid value of PYTH_ORACLE_PUBKEY env var: {err:?}" ) ;
33
- }
34
- } ;
46
+ . unwrap( ) ,
47
+ ) ;
35
48
}
36
49
37
50
/// Accumulator specific error type. It would be nice to use `transaction::Error` but it does
@@ -82,16 +95,19 @@ pub fn update_accumulator(bank: &Bank) {
82
95
83
96
/// Read the pubkey from the environment variable `var` or return `default`
84
97
/// if the variable is not set.
85
- fn env_pubkey_or (
86
- var : & str ,
87
- default : Pubkey ,
88
- ) -> std:: result:: Result < Pubkey , AccumulatorUpdateErrorV1 > {
89
- Ok ( std:: env:: var ( var)
90
- . as_deref ( )
91
- . map ( Pubkey :: from_str)
92
- . ok ( )
93
- . transpose ( ) ?
94
- . unwrap_or ( default) )
98
+ fn env_pubkey_or ( var : & str , default : Pubkey ) -> Pubkey {
99
+ match env:: var ( var) {
100
+ Ok ( value) => value. parse ( ) . unwrap_or_else ( |err| {
101
+ panic ! (
102
+ "failed to parse env var {}={:?} as pubkey: {}" ,
103
+ var, value, err
104
+ )
105
+ } ) ,
106
+ Err ( VarError :: NotPresent ) => default,
107
+ Err ( VarError :: NotUnicode ( value) ) => {
108
+ panic ! ( "invalid value of env var {}={:?}: not unicode" , var, value) ;
109
+ }
110
+ }
95
111
}
96
112
97
113
/// Get all accumulator related pubkeys from environment variables
@@ -100,64 +116,30 @@ pub fn get_accumulator_keys() -> Vec<(
100
116
& ' static str ,
101
117
std:: result:: Result < Pubkey , AccumulatorUpdateErrorV1 > ,
102
118
) > {
103
- use pythnet_sdk:: { pythnet, ACCUMULATOR_EMITTER_ADDRESS , MESSAGE_BUFFER_PID } ;
104
- let accumulator_keys = vec ! [
105
- (
106
- "MESSAGE_BUFFER_PID" ,
107
- Pubkey :: new_from_array( MESSAGE_BUFFER_PID ) ,
108
- ) ,
109
- // accumulator emitter address should always be the same regardless
110
- // of environment but checking here for completeness
111
- (
112
- "ACCUMULATOR_EMITTER_ADDR" ,
113
- Pubkey :: new_from_array( ACCUMULATOR_EMITTER_ADDRESS ) ,
114
- ) ,
115
- (
116
- "ACCUMULATOR_SEQUENCE_ADDR" ,
117
- Pubkey :: new_from_array( pythnet:: ACCUMULATOR_SEQUENCE_ADDR ) ,
118
- ) ,
119
- (
120
- "WORMHOLE_PID" ,
121
- Pubkey :: new_from_array( pythnet:: WORMHOLE_PID ) ,
122
- ) ,
123
- ] ;
124
- let accumulator_pubkeys: Vec < ( & str , std:: result:: Result < Pubkey , AccumulatorUpdateErrorV1 > ) > =
125
- accumulator_keys
126
- . iter ( )
127
- . map ( |( k, d) | ( * k, env_pubkey_or ( k, * d) ) )
128
- . collect ( ) ;
129
- accumulator_pubkeys
119
+ vec ! [
120
+ ( "MESSAGE_BUFFER_PID" , Ok ( * MESSAGE_BUFFER_PID ) ) ,
121
+ ( "ACCUMULATOR_EMITTER_ADDR" , Ok ( * ACCUMULATOR_EMITTER_ADDR ) ) ,
122
+ ( "ACCUMULATOR_SEQUENCE_ADDR" , Ok ( * ACCUMULATOR_SEQUENCE_ADDR ) ) ,
123
+ ( "WORMHOLE_PID" , Ok ( * WORMHOLE_PID ) ) ,
124
+ ( "ORACLE_PID" , Ok ( * ORACLE_PID ) ) ,
125
+ ]
130
126
}
131
127
132
128
pub fn update_v1 < ' a > (
133
129
bank : & Bank ,
134
130
v2_messages : & [ Vec < u8 > ] ,
135
131
use_message_buffers : bool ,
136
132
) -> std:: result:: Result < ( ) , AccumulatorUpdateErrorV1 > {
137
- use {
138
- byteorder:: ReadBytesExt ,
139
- pythnet_sdk:: {
140
- accumulators:: { merkle:: MerkleAccumulator , Accumulator } ,
141
- hashers:: keccak256_160:: Keccak160 ,
142
- MESSAGE_BUFFER_PID ,
143
- } ,
144
- solana_sdk:: borsh,
145
- } ;
146
-
147
133
// Use the current Clock to determine the index into the accumulator ring buffer.
148
134
let ring_index = ( bank. slot ( ) % 10_000 ) as u32 ;
149
135
150
136
// Find all accounts owned by the Message Buffer program using get_program_accounts, and
151
137
// extract the account data.
152
- let message_buffer_pid = env_pubkey_or (
153
- "MESSAGE_BUFFER_PID" ,
154
- Pubkey :: new_from_array ( MESSAGE_BUFFER_PID ) ,
155
- ) ?;
156
138
157
139
let message_buffer_accounts;
158
140
let v1_messages = if use_message_buffers {
159
141
message_buffer_accounts = bank
160
- . get_program_accounts ( & message_buffer_pid , & ScanConfig :: new ( true ) )
142
+ . get_program_accounts ( & MESSAGE_BUFFER_PID , & ScanConfig :: new ( true ) )
161
143
. map_err ( AccumulatorUpdateErrorV1 :: GetProgramAccounts ) ?;
162
144
163
145
let preimage = b"account:MessageBuffer" ;
@@ -266,28 +248,12 @@ fn post_accumulator_attestation(
266
248
> ,
267
249
ring_index : u32 ,
268
250
) -> std:: result:: Result < ( ) , AccumulatorUpdateErrorV1 > {
269
- use pythnet_sdk:: {
270
- pythnet,
271
- wormhole:: { AccumulatorSequenceTracker , MessageData , PostedMessageUnreliableData } ,
272
- ACCUMULATOR_EMITTER_ADDRESS ,
273
- } ;
274
-
275
- let accumulator_sequence_addr = env_pubkey_or (
276
- "ACCUMULATOR_SEQUENCE_ADDR" ,
277
- Pubkey :: new_from_array ( pythnet:: ACCUMULATOR_SEQUENCE_ADDR ) ,
278
- ) ?;
279
-
280
- let accumulator_emitter_addr = env_pubkey_or (
281
- "ACCUMULATOR_EMITTER_ADDR" ,
282
- Pubkey :: new_from_array ( ACCUMULATOR_EMITTER_ADDRESS ) ,
283
- ) ?;
284
-
285
251
// Wormhole uses a Sequence account that is incremented each time a message is posted. As
286
252
// we aren't calling Wormhole we need to bump this ourselves. If it doesn't exist, we just
287
253
// create it instead.
288
254
let mut sequence: AccumulatorSequenceTracker = {
289
255
let data = bank
290
- . get_account_with_fixed_root ( & accumulator_sequence_addr )
256
+ . get_account_with_fixed_root ( & ACCUMULATOR_SEQUENCE_ADDR )
291
257
. unwrap_or_default ( ) ;
292
258
let data = data. data ( ) ;
293
259
solana_sdk:: borsh:: try_from_slice_unchecked ( data)
@@ -311,7 +277,7 @@ fn post_accumulator_attestation(
311
277
nonce : 0 ,
312
278
sequence : sequence. sequence ,
313
279
emitter_chain : 26 ,
314
- emitter_address : accumulator_emitter_addr . to_bytes ( ) ,
280
+ emitter_address : ACCUMULATOR_EMITTER_ADDR . to_bytes ( ) ,
315
281
payload : acc. serialize ( bank. slot ( ) , ACCUMULATOR_RING_SIZE ) ,
316
282
}
317
283
} else {
@@ -322,26 +288,21 @@ fn post_accumulator_attestation(
322
288
submission_time : bank. clock ( ) . unix_timestamp as u32 ,
323
289
sequence : sequence. sequence ,
324
290
emitter_chain : 26 ,
325
- emitter_address : accumulator_emitter_addr . to_bytes ( ) ,
291
+ emitter_address : ACCUMULATOR_EMITTER_ADDR . to_bytes ( ) ,
326
292
payload : acc. serialize ( bank. slot ( ) , ACCUMULATOR_RING_SIZE ) ,
327
293
..Default :: default ( )
328
294
}
329
295
} ,
330
296
} ;
331
297
332
298
debug ! ( "Accumulator: Wormhole message data: {:?}" , message. message) ;
333
- let wormhole_pid = env_pubkey_or (
334
- "WORMHOLE_PID" ,
335
- Pubkey :: new_from_array ( pythnet:: WORMHOLE_PID ) ,
336
- ) ?;
337
-
338
299
// Now we can bump and write the Sequence account.
339
300
sequence. sequence += 1 ;
340
301
let sequence = solana_sdk:: borsh:: BorshSerialize :: try_to_vec ( & sequence)
341
302
. map_err ( |_| AccumulatorUpdateErrorV1 :: FailedSequenceSerialization ) ?;
342
303
let sequence_balance = bank. get_minimum_balance_for_rent_exemption ( sequence. len ( ) ) ;
343
304
let sequence_account = {
344
- let owner = & wormhole_pid ;
305
+ let owner = & WORMHOLE_PID ;
345
306
let mut account = AccountSharedData :: new ( sequence_balance, sequence. len ( ) , owner) ;
346
307
account. set_data ( sequence) ;
347
308
account
@@ -352,7 +313,7 @@ fn post_accumulator_attestation(
352
313
. map_err ( |_| AccumulatorUpdateErrorV1 :: FailedMessageSerialization ) ?;
353
314
let message_balance = bank. get_minimum_balance_for_rent_exemption ( message. len ( ) ) ;
354
315
let message_account = {
355
- let owner = & wormhole_pid ;
316
+ let owner = & WORMHOLE_PID ;
356
317
let mut account = AccountSharedData :: new ( message_balance, message. len ( ) , owner) ;
357
318
account. set_data ( message) ;
358
319
account
@@ -362,10 +323,10 @@ fn post_accumulator_attestation(
362
323
// for RPC users to select the message for an associated VAA.
363
324
let ( message_pda, _) = Pubkey :: find_program_address (
364
325
& [ b"AccumulatorMessage" , & ring_index. to_be_bytes ( ) ] ,
365
- & wormhole_pid ,
326
+ & WORMHOLE_PID ,
366
327
) ;
367
328
368
- bank. store_account_and_update_capitalization ( & accumulator_sequence_addr , & sequence_account) ;
329
+ bank. store_account_and_update_capitalization ( & ACCUMULATOR_SEQUENCE_ADDR , & sequence_account) ;
369
330
370
331
info ! ( "Accumulator: Writing wormhole message to {:?}" , message_pda) ;
371
332
bank. store_account_and_update_capitalization ( & message_pda, & message_account) ;
@@ -375,7 +336,7 @@ fn post_accumulator_attestation(
375
336
376
337
pub fn update_v2 ( bank : & Bank ) -> std:: result:: Result < ( ) , AccumulatorUpdateErrorV1 > {
377
338
let accounts = bank
378
- . get_program_accounts ( & ORACLE_PUBKEY , & ScanConfig :: new ( true ) )
339
+ . get_program_accounts ( & ORACLE_PID , & ScanConfig :: new ( true ) )
379
340
. map_err ( AccumulatorUpdateErrorV1 :: GetProgramAccounts ) ?;
380
341
381
342
let mut any_v1_aggregations = false ;
0 commit comments