-
Notifications
You must be signed in to change notification settings - Fork 6
Introduce new rollback strategy #423
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c8bdaea
bb922e1
072e47c
e5174b1
081cd94
6f0b25d
b4fc28c
a41d394
0566222
ff13036
318b61a
8592f5c
f14aba2
2374fe5
3ec902f
5e35bd7
3db893b
ae2fe9b
6f88664
d8832c0
48d0c2a
61cd082
a763b47
3b39b87
605e6e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| use std::sync::Arc; | ||
|
|
||
| use anyhow::Result; | ||
| use caryatid_sdk::{async_trait, Context, MessageBounds, Subscription}; | ||
|
|
||
| use crate::messages::{CardanoMessage, Message, StateTransitionMessage}; | ||
|
|
||
| #[async_trait] | ||
| pub trait SubscriptionExt<M: MessageBounds> { | ||
| async fn read_ignoring_rollbacks(&mut self) -> Result<(String, Arc<M>)>; | ||
| } | ||
|
|
||
| #[async_trait] | ||
| impl SubscriptionExt<Message> for Box<dyn Subscription<Message>> { | ||
| async fn read_ignoring_rollbacks(&mut self) -> Result<(String, Arc<Message>)> { | ||
| loop { | ||
| let (stream, message) = self.read().await?; | ||
| if matches!( | ||
| message.as_ref(), | ||
| Message::Cardano(( | ||
| _, | ||
| CardanoMessage::StateTransition(StateTransitionMessage::Rollback(_)) | ||
| )) | ||
| ) { | ||
| continue; | ||
| } | ||
| break Ok((stream, message)); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// A utility to publish messages, which will only publish rollback messages if some work has been rolled back | ||
| pub struct RollbackAwarePublisher<M: MessageBounds> { | ||
| /// Module context | ||
| context: Arc<Context<M>>, | ||
|
|
||
| /// Topic to publish on | ||
| topic: String, | ||
|
|
||
| // At which slot did we publish our last non-rollback message | ||
| last_activity_at: Option<u64>, | ||
| } | ||
|
|
||
| impl RollbackAwarePublisher<Message> { | ||
| pub fn new(context: Arc<Context<Message>>, topic: String) -> Self { | ||
| Self { | ||
| context, | ||
| topic, | ||
| last_activity_at: None, | ||
| } | ||
| } | ||
|
|
||
| pub async fn publish(&mut self, message: Arc<Message>) -> Result<()> { | ||
| match message.as_ref() { | ||
| Message::Cardano(( | ||
| block, | ||
| CardanoMessage::StateTransition(StateTransitionMessage::Rollback(_)), | ||
| )) => { | ||
| if self.last_activity_at.is_some_and(|slot| slot >= block.slot) { | ||
| self.last_activity_at = None; | ||
| self.context.publish(&self.topic, message).await?; | ||
| } | ||
| Ok(()) | ||
| } | ||
| Message::Cardano((block, _)) => { | ||
| self.last_activity_at = Some(block.slot); | ||
| self.context.publish(&self.topic, message).await | ||
| } | ||
| _ => self.context.publish(&self.topic, message).await, | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| use crate::{BlockHash, Slot}; | ||
| use crate::Point; | ||
|
|
||
| #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] | ||
| pub enum ChainSyncCommand { | ||
| FindIntersect { slot: Slot, hash: BlockHash }, | ||
| FindIntersect(Point), | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,22 +1,17 @@ | ||
| use acropolis_common::caryatid::RollbackAwarePublisher; | ||
| use acropolis_common::messages::{CardanoMessage, Message, SPOStakeDistributionMessage}; | ||
| use acropolis_common::{BlockInfo, DelegatedStake, PoolId}; | ||
| use caryatid_sdk::Context; | ||
| use std::collections::BTreeMap; | ||
| use std::sync::Arc; | ||
|
|
||
| /// Message publisher for Stake Pool Delegation Distribution (SPDD) | ||
| pub struct SPODistributionPublisher { | ||
| /// Module context | ||
| context: Arc<Context<Message>>, | ||
|
|
||
| /// Topic to publish on | ||
| topic: String, | ||
| } | ||
| pub struct SPODistributionPublisher(RollbackAwarePublisher<Message>); | ||
|
|
||
| impl SPODistributionPublisher { | ||
| /// Construct with context and topic to publish on | ||
| pub fn new(context: Arc<Context<Message>>, topic: String) -> Self { | ||
| Self { context, topic } | ||
| Self(RollbackAwarePublisher::new(context, topic)) | ||
| } | ||
|
|
||
| /// Publish the SPDD | ||
|
|
@@ -25,18 +20,19 @@ impl SPODistributionPublisher { | |
| block: &BlockInfo, | ||
| spos: BTreeMap<PoolId, DelegatedStake>, | ||
| ) -> anyhow::Result<()> { | ||
| self.context | ||
| .message_bus | ||
| .publish( | ||
| &self.topic, | ||
| Arc::new(Message::Cardano(( | ||
| block.clone(), | ||
| CardanoMessage::SPOStakeDistribution(SPOStakeDistributionMessage { | ||
| epoch: block.epoch - 1, // End of the previous epoch | ||
| spos: spos.into_iter().collect(), | ||
| }), | ||
| ))), | ||
| ) | ||
| self.0 | ||
| .publish(Arc::new(Message::Cardano(( | ||
| block.clone(), | ||
| CardanoMessage::SPOStakeDistribution(SPOStakeDistributionMessage { | ||
| epoch: block.epoch - 1, // End of the previous epoch | ||
| spos: spos.into_iter().collect(), | ||
| }), | ||
| )))) | ||
| .await | ||
| } | ||
|
|
||
| /// Publish a rollback message, if we have anything to roll back | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there some trick to make this common across all publishers? In C++ it would just be a RollbackEnabledPublisher superclass (I miss inheritance sometimes!)
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no formal concept of a "publisher" in this codebase at all, just a bunch of existing structs named Publisher with similar logic. I moved that logic into a |
||
| pub async fn publish_rollback(&mut self, message: Arc<Message>) -> anyhow::Result<()> { | ||
| self.0.publish(message).await | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see you're cleaning this up too, nice!