Files
pezkuwi-subxt/substrate/client/authority-discovery/src/interval.rs
T
Alexandru Vasile 5ac32ee2bd authority-discovery: Set intervals to start when authority keys changes (#3764)
The authority-discovery mechanism has implemented a few exponential
timers for:
- publishing the authority records
- goes from 2 seconds (when freshly booted) to 1 hour if the node is
long-running
  - set to 1 hour after successfully publishing the authority record
- discovering other authority records
- goes from 2 seconds (when freshly booted) to 10 minutes if the node is
long-running

This PR resets the exponential publishing and discovery interval to
defaults ensuring that long-running nodes:
- will retry publishing the authority records as aggressively as freshly
booted nodes
- Currently, if a long-running node fails to publish the DHT record when
the keys change (ie DhtEvent::ValuePutFailed), it will only retry after
1 hour
- will rediscover other authorities faster (since there is a chance that
other authority keys changed)

The subp2p-explorer has difficulties discovering the authorities when
the authority set changes in the first few hours. This might be entirely
due to the recursive nature of the DHT and the needed time to propagate
the records. However, there is a small chance that the authority
publishing failed and is only retried in 1h.

Let me know if this makes sense 🙏 

cc @paritytech/networking

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Co-authored-by: Dmitry Markin <dmitry@markin.tech>
2024-03-27 09:49:10 +00:00

77 lines
2.1 KiB
Rust

// This file is part of Substrate.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use futures::{future::FutureExt, ready, stream::Stream};
use futures_timer::Delay;
use std::{
pin::Pin,
task::{Context, Poll},
time::Duration,
};
/// Exponentially increasing interval
///
/// Doubles interval duration on each tick until the configured maximum is reached.
pub struct ExpIncInterval {
start: Duration,
max: Duration,
next: Duration,
delay: Delay,
}
impl ExpIncInterval {
/// Create a new [`ExpIncInterval`].
pub fn new(start: Duration, max: Duration) -> Self {
let delay = Delay::new(start);
Self { start, max, next: start * 2, delay }
}
/// Fast forward the exponentially increasing interval to the configured maximum, if not already
/// set.
pub fn set_to_max(&mut self) {
if self.next == self.max {
return;
}
self.next = self.max;
self.delay = Delay::new(self.next);
}
/// Rewind the exponentially increasing interval to the configured start, if not already set.
pub fn set_to_start(&mut self) {
if self.next == self.start * 2 {
return;
}
self.next = self.start * 2;
self.delay = Delay::new(self.start);
}
}
impl Stream for ExpIncInterval {
type Item = ();
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
ready!(self.delay.poll_unpin(cx));
self.delay = Delay::new(self.next);
self.next = std::cmp::min(self.max, self.next * 2);
Poll::Ready(Some(()))
}
}