3232 AccountId ,
3333 Gas ,
3434 Promise ,
35+ PromiseOrValue ,
3536 } ,
3637 num_traits:: FromPrimitive ,
3738 strum:: EnumDiscriminants ,
@@ -256,7 +257,7 @@ impl Pyth {
256257 /// done in a callback handler, see `process_vaa_callback`.
257258 #[ payable]
258259 #[ handle_result]
259- pub fn execute_governance_instruction ( & mut self , vaa : String ) -> Result < ( ) , Error > {
260+ pub fn execute_governance_instruction ( & mut self , vaa : String ) -> Result < Promise , Error > {
260261 // Verify the VAA is coming from a trusted source chain before attempting to verify VAA
261262 // signatures. Avoids a cross-contract call early.
262263 {
@@ -285,22 +286,20 @@ impl Pyth {
285286 }
286287
287288 // Verify VAA and refund the caller in case of failure.
288- ext_wormhole:: ext ( self . wormhole . clone ( ) )
289+ Ok ( ext_wormhole:: ext ( self . wormhole . clone ( ) )
289290 . with_static_gas ( Gas ( 30_000_000_000_000 ) )
290291 . verify_vaa ( vaa. clone ( ) )
291292 . then (
292293 Self :: ext ( env:: current_account_id ( ) )
293- . with_static_gas ( Gas ( 30_000_000_000_000 ) )
294+ . with_static_gas ( Gas ( 10_000_000_000_000 ) )
294295 . with_attached_deposit ( env:: attached_deposit ( ) )
295296 . verify_gov_vaa_callback ( env:: predecessor_account_id ( ) , vaa) ,
296297 )
297298 . then (
298299 Self :: ext ( env:: current_account_id ( ) )
299- . with_static_gas ( Gas ( 30_000_000_000_000 ) )
300+ . with_static_gas ( Gas ( 10_000_000_000_000 ) )
300301 . refund_vaa ( env:: predecessor_account_id ( ) , env:: attached_deposit ( ) ) ,
301- ) ;
302-
303- Ok ( ( ) )
302+ ) )
304303 }
305304
306305 /// Invoke handler upon successful verification of a VAA action.
@@ -316,7 +315,7 @@ impl Pyth {
316315 account_id : AccountId ,
317316 vaa : String ,
318317 #[ callback_result] _result : Result < u32 , near_sdk:: PromiseError > ,
319- ) -> Result < ( ) , Error > {
318+ ) -> Result < PromiseOrValue < ( ) > , Error > {
320319 use GovernanceAction :: * ;
321320
322321 ensure ! ( is_promise_success( ) , VaaVerificationFailed ) ;
@@ -345,9 +344,6 @@ impl Pyth {
345344 SetFee { base, expo } => self . set_update_fee ( base, expo) ?,
346345 SetValidPeriod { valid_seconds } => self . set_valid_period ( valid_seconds) ,
347346 RequestGovernanceDataSourceTransfer { .. } => Err ( InvalidPayload ) ?,
348- AuthorizeGovernanceDataSourceTransfer { claim_vaa } => {
349- self . authorize_gov_source_transfer ( claim_vaa) ?
350- }
351347 UpgradeContract { codehash } => {
352348 // Additionally restrict to only Near for upgrades. This is a safety measure to
353349 // prevent accidental upgrades to the wrong contract.
@@ -357,6 +353,35 @@ impl Pyth {
357353 ) ;
358354 self . set_upgrade_hash ( codehash)
359355 }
356+
357+ // In the case of AuthorizeGovernanceDataSourceTransfer we need to verify the VAA
358+ // contained within the action. This implies another async call so we return here and
359+ // allow the refund / gov processing to happen in the callback.
360+ AuthorizeGovernanceDataSourceTransfer { claim_vaa } => {
361+ let claim_vaa = hex:: encode ( claim_vaa) ;
362+
363+ // Return early, the callback has to perform the rest of the processing.
364+ return Ok ( PromiseOrValue :: Promise (
365+ ext_wormhole:: ext ( self . wormhole . clone ( ) )
366+ . with_static_gas ( Gas ( 30_000_000_000_000 ) )
367+ . verify_vaa ( claim_vaa. clone ( ) )
368+ . then (
369+ Self :: ext ( env:: current_account_id ( ) )
370+ . with_static_gas ( Gas ( 10_000_000_000_000 ) )
371+ . with_attached_deposit ( env:: attached_deposit ( ) )
372+ . authorize_gov_source_transfer (
373+ env:: predecessor_account_id ( ) ,
374+ claim_vaa,
375+ storage,
376+ ) ,
377+ )
378+ . then (
379+ Self :: ext ( env:: current_account_id ( ) )
380+ . with_static_gas ( Gas ( 10_000_000_000_000 ) )
381+ . refund_vaa ( env:: predecessor_account_id ( ) , env:: attached_deposit ( ) ) ,
382+ ) ,
383+ ) ) ;
384+ }
360385 }
361386
362387 self . executed_governance_vaa = vaa. sequence ;
@@ -368,6 +393,7 @@ impl Pyth {
368393 env:: storage_usage ( ) ,
369394 env:: attached_deposit ( ) ,
370395 )
396+ . map ( |v| PromiseOrValue :: Value ( v) )
371397 }
372398
373399 /// If submitting an action fails then this callback will refund the caller.
@@ -381,10 +407,18 @@ impl Pyth {
381407 }
382408
383409 #[ private]
410+ #[ payable]
384411 #[ handle_result]
385- pub fn authorize_gov_source_transfer ( & mut self , claim_vaa : Vec < u8 > ) -> Result < ( ) , Error > {
412+ pub fn authorize_gov_source_transfer (
413+ & mut self ,
414+ account_id : AccountId ,
415+ claim_vaa : String ,
416+ storage : u64 ,
417+ #[ callback_result] _result : Result < u32 , near_sdk:: PromiseError > ,
418+ ) -> Result < ( ) , Error > {
419+ let vaa = hex:: decode ( claim_vaa) . map_err ( |_| InvalidPayload ) ?;
386420 let ( vaa, rest) : ( wormhole:: Vaa < ( ) > , _ ) =
387- serde_wormhole:: from_slice_with_payload ( & claim_vaa ) . expect ( "Failed to deserialize VAA" ) ;
421+ serde_wormhole:: from_slice_with_payload ( & vaa ) . expect ( "Failed to deserialize VAA" ) ;
388422
389423 // Convert to local VAA type to catch API changes.
390424 let vaa = Vaa :: from ( vaa) ;
@@ -410,7 +444,9 @@ impl Pyth {
410444 InvalidPayload
411445 ) ;
412446
447+ // Update executed VAA indices, prevents replay on both the VAA.
413448 self . executed_governance_change_vaa = governance_data_source_index as u64 ;
449+ self . executed_governance_vaa = vaa. sequence ;
414450
415451 // Update Governance Source
416452 self . gov_source = Source {
@@ -422,35 +458,13 @@ impl Pyth {
422458 _ => Err ( Unknown ) ?,
423459 }
424460
425- Ok ( ( ) )
426- }
427-
428- #[ private]
429- pub fn set_valid_period ( & mut self , threshold : u64 ) {
430- self . stale_threshold = threshold;
431- }
432-
433- #[ private]
434- #[ handle_result]
435- pub fn set_update_fee ( & mut self , fee : u64 , expo : u64 ) -> Result < ( ) , Error > {
436- self . update_fee = ( fee as u128 )
437- . checked_mul (
438- 10_u128
439- . checked_pow ( u32:: try_from ( expo) . map_err ( |_| ArithmeticOverflow ) ?)
440- . ok_or ( ArithmeticOverflow ) ?,
441- )
442- . ok_or ( ArithmeticOverflow ) ?;
443-
444- Ok ( ( ) )
445- }
446-
447- #[ private]
448- #[ handle_result]
449- pub fn set_sources ( & mut self , sources : Vec < Source > ) {
450- self . sources . clear ( ) ;
451- sources. iter ( ) . for_each ( |s| {
452- self . sources . insert ( s) ;
453- } ) ;
461+ // Refund storage difference to `account_id` after storage execution.
462+ self . refund_storage_usage (
463+ account_id,
464+ storage,
465+ env:: storage_usage ( ) ,
466+ env:: attached_deposit ( ) ,
467+ )
454468 }
455469
456470 /// This method allows self-upgrading the contract to a new implementation.
@@ -501,6 +515,29 @@ impl Pyth {
501515 . ok_or ( UnknownSource ( source. emitter ) )
502516 }
503517
518+ pub fn set_valid_period ( & mut self , threshold : u64 ) {
519+ self . stale_threshold = threshold;
520+ }
521+
522+ pub fn set_update_fee ( & mut self , fee : u64 , expo : u64 ) -> Result < ( ) , Error > {
523+ self . update_fee = ( fee as u128 )
524+ . checked_mul (
525+ 10_u128
526+ . checked_pow ( u32:: try_from ( expo) . map_err ( |_| ArithmeticOverflow ) ?)
527+ . ok_or ( ArithmeticOverflow ) ?,
528+ )
529+ . ok_or ( ArithmeticOverflow ) ?;
530+
531+ Ok ( ( ) )
532+ }
533+
534+ pub fn set_sources ( & mut self , sources : Vec < Source > ) {
535+ self . sources . clear ( ) ;
536+ sources. iter ( ) . for_each ( |s| {
537+ self . sources . insert ( s) ;
538+ } ) ;
539+ }
540+
504541 pub fn set_upgrade_hash ( & mut self , codehash : [ u8 ; 32 ] ) {
505542 self . codehash = codehash;
506543 }
0 commit comments