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
This commit is contained in:
Stanisław Drozd 2022-05-11 18:02:59 +02:00 committed by GitHub
parent 1a3d8f211e
commit 7b1dbc1938
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 81 additions and 52 deletions

View File

@ -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,
},
}

View File

@ -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,

View File

@ -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())