Procházet zdrojové kódy

p2w-client: Move batch state to a new module, harden status access (#205)

* p2w-client: Move batch state to a new module, harden status access

commit-id:8265cb5b

* Trigger CI

commit-id:be75d126
Stanisław Drozd před 3 roky
rodič
revize
7b1dbc1938

+ 66 - 0
solana/pyth2wormhole/client/src/batch_state.rs

@@ -0,0 +1,66 @@
+use solana_sdk::signature::Signature;
+
+use std::time::Instant;
+
+use crate::{
+    AttestationConditions,
+    ErrBox,
+    P2WSymbol,
+};
+
+#[derive(Debug)]
+pub struct BatchState<'a> {
+    pub group_name: String,
+    pub symbols: &'a [P2WSymbol],
+    pub conditions: AttestationConditions,
+    status: BatchTxStatus,
+    status_changed_at: Instant,
+}
+
+impl<'a> BatchState<'a> {
+    pub fn new(
+        group_name: String,
+        symbols: &'a [P2WSymbol],
+        conditions: AttestationConditions,
+    ) -> Self {
+        Self {
+            group_name,
+            symbols,
+            conditions,
+            status: BatchTxStatus::Sending { attempt_no: 1 },
+            status_changed_at: Instant::now(),
+        }
+    }
+    /// Ensure only set_status() alters the timestamp
+    pub fn get_status_changed_at(&self) -> &Instant {
+        &self.status_changed_at
+    }
+    pub fn get_status(&self) -> &BatchTxStatus {
+        &self.status
+    }
+    /// Ensure that status changes are accompanied by a timestamp bump
+    pub fn set_status(&mut self, s: BatchTxStatus) {
+        self.status_changed_at = Instant::now();
+        self.status = s;
+    }
+}
+
+#[derive(Debug)]
+pub enum BatchTxStatus {
+    Sending {
+        attempt_no: usize,
+    },
+    Confirming {
+        attempt_no: usize,
+        signature: Signature,
+    },
+    Success {
+        seqno: String,
+    },
+    FailedSend {
+        last_err: ErrBox,
+    },
+    FailedConfirm {
+        last_err: ErrBox,
+    },
+}

+ 2 - 0
solana/pyth2wormhole/client/src/lib.rs

@@ -1,4 +1,5 @@
 pub mod attestation_cfg;
+pub mod batch_state;
 
 use borsh::{
     BorshDeserialize,
@@ -53,6 +54,7 @@ use pyth2wormhole::{
 };
 
 pub use attestation_cfg::{AttestationConfig, AttestationConditions, P2WSymbol};
+pub use batch_state::{BatchState, BatchTxStatus};
 
 pub fn gen_init_tx(
     payer: Keypair,

+ 13 - 52
solana/pyth2wormhole/client/src/main.rs

@@ -119,43 +119,6 @@ fn main() -> Result<(), ErrBox> {
     Ok(())
 }
 
-#[derive(Debug)]
-pub struct BatchState<'a> {
-    group_name: String,
-    symbols: &'a [P2WSymbol],
-    conditions: AttestationConditions,
-    status: BatchTxStatus,
-    status_changed_at: Instant,
-}
-
-impl BatchState<'_> {
-    /// Helps make state changes one-liners
-    pub fn set_status(&mut self, s: BatchTxStatus) {
-        self.status = s;
-        self.status_changed_at = Instant::now();
-    }
-}
-
-#[derive(Debug)]
-pub enum BatchTxStatus {
-    Sending {
-        attempt_no: usize,
-    },
-    Confirming {
-        attempt_no: usize,
-        signature: Signature,
-    },
-    Success {
-        seqno: String,
-    },
-    FailedSend {
-        last_err: ErrBox,
-    },
-    FailedConfirm {
-        last_err: ErrBox,
-    },
-}
-
 use BatchTxStatus::*;
 
 /// Send a series of batch attestations for symbols of an attestation config.
@@ -202,13 +165,11 @@ fn handle_attest(
                 .map(move |(idx, symbols)| {
                     (
                         idx + 1,
-                        BatchState {
-                            conditions: conditions4closure.clone(),
-                            group_name: name4closure.clone(),
+                        BatchState::new(
+                            name4closure.clone(),
                             symbols,
-                            status: Sending { attempt_no: 1 },
-                            status_changed_at: Instant::now(),
-                        },
+                            conditions4closure.clone(),
+                        ),
                     )
                 })
         })
@@ -223,7 +184,7 @@ fn handle_attest(
     while daemon || finished_count < batches.len() {
         finished_count = 0;
         for (batch_no, state) in batches.iter_mut() {
-            match state.status {
+            match state.get_status().clone() {
                 Sending { attempt_no } => {
                     info!(
                         "Batch {}/{} contents (group {:?}): {:?}",
@@ -268,7 +229,7 @@ fn handle_attest(
                             );
 
                             state.set_status(Confirming {
-                                attempt_no,
+                                attempt_no: *attempt_no,
                                 signature,
                             });
                         }
@@ -284,7 +245,7 @@ fn handle_attest(
                             );
                             warn!("{}", &msg);
 
-                            if attempt_no < n_retries {
+                            if attempt_no < &n_retries {
                                 state.set_status(Sending {
                                     attempt_no: attempt_no + 1,
                                 })
@@ -336,9 +297,9 @@ fn handle_attest(
                             state.set_status(Success { seqno });
                         }
                         Err(e) => {
-                            let elapsed = state.status_changed_at.elapsed();
+                            let elapsed = state.get_status_changed_at().elapsed();
                             let msg = format!(
-                                "Batch {}/{} (groups {:?}) tx confirmation failed ({}.{}/{}.{}): {}",
+                                "Batch {}/{} (group {:?}) tx confirmation failed ({}.{}/{}.{}): {}",
                                 batch_no,
                                 batch_count,
                                 state.group_name,
@@ -365,7 +326,7 @@ fn handle_attest(
 				    msg
                                 );
 
-                                if attempt_no < n_retries {
+                                if attempt_no < &n_retries {
                                     state.set_status(Sending {
                                         attempt_no: attempt_no + 1,
                                     });
@@ -386,12 +347,12 @@ fn handle_attest(
                 Success { .. } | FailedSend { .. } | FailedConfirm { .. } => {
                     // We only try to re-schedule under --daemon
                     if daemon {
-                        if state.status_changed_at.elapsed()
+                        if state.get_status_changed_at().elapsed()
                             > Duration::from_secs(state.conditions.min_freq_secs)
                         {
                             state.set_status(Sending { attempt_no: 1 });
                         } else {
-                            let elapsed = state.status_changed_at.elapsed();
+                            let elapsed = state.get_status_changed_at().elapsed();
                             trace!(
                                 "Batch {}/{} (group {:?}): waiting ({}.{}/{}.{})",
                                 batch_no,
@@ -420,7 +381,7 @@ fn handle_attest(
 
     // Filter out errors
     for (batch_no, state) in batches {
-        match state.status {
+        match state.get_status() {
             Success { .. } => {}
             FailedSend { last_err, .. } | FailedConfirm { last_err, .. } => {
                 errors.push(last_err.to_string())