mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-22 10:44:53 +00:00
Add a notification system for finalizations to serai-client, use in coordinator
This commit is contained in:
parent
e9fca37181
commit
d5a19eca8c
4 changed files with 49 additions and 4 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -8089,6 +8089,7 @@ dependencies = [
|
||||||
"bitcoin",
|
"bitcoin",
|
||||||
"ciphersuite",
|
"ciphersuite",
|
||||||
"frost-schnorrkel",
|
"frost-schnorrkel",
|
||||||
|
"futures",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"modular-frost",
|
"modular-frost",
|
||||||
"monero-serai",
|
"monero-serai",
|
||||||
|
|
|
@ -21,6 +21,7 @@ use serai_client::{primitives::NetworkId, Public, Serai};
|
||||||
|
|
||||||
use message_queue::{Service, client::MessageQueue};
|
use message_queue::{Service, client::MessageQueue};
|
||||||
|
|
||||||
|
use futures::stream::StreamExt;
|
||||||
use tokio::{sync::RwLock, time::sleep};
|
use tokio::{sync::RwLock, time::sleep};
|
||||||
|
|
||||||
use ::tributary::{
|
use ::tributary::{
|
||||||
|
@ -70,7 +71,7 @@ async fn add_tributary<D: Db, P: P2p>(
|
||||||
log::info!("adding tributary {:?}", spec.set());
|
log::info!("adding tributary {:?}", spec.set());
|
||||||
|
|
||||||
let tributary = Tributary::<_, Transaction, _>::new(
|
let tributary = Tributary::<_, Transaction, _>::new(
|
||||||
// TODO2: Use a db on a distinct volume
|
// TODO2: Use a db on a distinct volume to protect against DoS attacks
|
||||||
db,
|
db,
|
||||||
spec.genesis(),
|
spec.genesis(),
|
||||||
spec.start_time(),
|
spec.start_time(),
|
||||||
|
@ -102,7 +103,36 @@ pub async fn scan_substrate<D: Db, Pro: Processors>(
|
||||||
let mut db = substrate::SubstrateDb::new(db);
|
let mut db = substrate::SubstrateDb::new(db);
|
||||||
let mut next_substrate_block = db.next_block();
|
let mut next_substrate_block = db.next_block();
|
||||||
|
|
||||||
|
let new_substrate_block_notifier = {
|
||||||
|
let serai = &serai;
|
||||||
|
move || async move {
|
||||||
|
loop {
|
||||||
|
match serai.newly_finalized_block().await {
|
||||||
|
Ok(sub) => return sub,
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("couldn't communicate with serai node: {e}");
|
||||||
|
sleep(Duration::from_secs(5)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut substrate_block_notifier = new_substrate_block_notifier().await;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
// await the next block, yet if our notifier had an error, re-create it
|
||||||
|
{
|
||||||
|
if substrate_block_notifier
|
||||||
|
.next()
|
||||||
|
.await
|
||||||
|
.and_then(|result| if result.is_err() { None } else { Some(()) })
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
|
substrate_block_notifier = new_substrate_block_notifier().await;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match substrate::handle_new_blocks(
|
match substrate::handle_new_blocks(
|
||||||
&mut db,
|
&mut db,
|
||||||
&key,
|
&key,
|
||||||
|
@ -125,9 +155,7 @@ pub async fn scan_substrate<D: Db, Pro: Processors>(
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
// TODO2: Should this use a notification system for new blocks?
|
Ok(()) => {}
|
||||||
// Right now it's sleeping for half the block time.
|
|
||||||
Ok(()) => sleep(Duration::from_secs(3)).await,
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("couldn't communicate with serai node: {e}");
|
log::error!("couldn't communicate with serai node: {e}");
|
||||||
sleep(Duration::from_secs(5)).await;
|
sleep(Duration::from_secs(5)).await;
|
||||||
|
|
|
@ -16,6 +16,8 @@ rustdoc-args = ["--cfg", "docsrs"]
|
||||||
zeroize = "^1.5"
|
zeroize = "^1.5"
|
||||||
thiserror = { version = "1", optional = true }
|
thiserror = { version = "1", optional = true }
|
||||||
|
|
||||||
|
futures = "0.3"
|
||||||
|
|
||||||
scale = { package = "parity-scale-codec", version = "3" }
|
scale = { package = "parity-scale-codec", version = "3" }
|
||||||
scale-info = { version = "2", optional = true }
|
scale-info = { version = "2", optional = true }
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
use futures::stream::{Stream, StreamExt};
|
||||||
|
|
||||||
use scale::{Encode, Decode, Compact};
|
use scale::{Encode, Decode, Compact};
|
||||||
mod scale_value;
|
mod scale_value;
|
||||||
pub(crate) use scale_value::{Value, Composite, scale_value, scale_composite};
|
pub(crate) use scale_value::{Value, Composite, scale_value, scale_composite};
|
||||||
|
@ -259,6 +261,18 @@ impl Serai {
|
||||||
self.get_block(hash.into()).await
|
self.get_block(hash.into()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A stream which yields whenever new block(s) have been finalized.
|
||||||
|
pub async fn newly_finalized_block(
|
||||||
|
&self,
|
||||||
|
) -> Result<impl Stream<Item = Result<(), SeraiError>>, SeraiError> {
|
||||||
|
Ok(self.0.rpc().subscribe_finalized_block_headers().await.map_err(SeraiError::RpcError)?.map(
|
||||||
|
|next| {
|
||||||
|
next.map_err(SeraiError::RpcError)?;
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_nonce(&self, address: &SeraiAddress) -> Result<u32, SeraiError> {
|
pub async fn get_nonce(&self, address: &SeraiAddress) -> Result<u32, SeraiError> {
|
||||||
self
|
self
|
||||||
.0
|
.0
|
||||||
|
|
Loading…
Reference in a new issue