Skip to content

Commit feb1e00

Browse files
authored
Merge pull request #759 from input-output-hk/greg/743/extract_stake_distribution
#743 monitor stake distribution Vs Signer version
2 parents d991b2e + 97ad096 commit feb1e00

File tree

6 files changed

+125
-16
lines changed

6 files changed

+125
-16
lines changed

mithril-aggregator/src/http_server/routes/middlewares.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::{
33
dependency::MultiSignerWrapper, CertificatePendingStore, CertificateStore, Configuration,
44
DependencyManager, ProtocolParametersStore, SignerRegisterer, SnapshotStore,
55
};
6+
use mithril_common::BeaconProvider;
67
use std::convert::Infallible;
78
use std::sync::Arc;
89
use warp::Filter;
@@ -62,3 +63,10 @@ pub fn with_event_transmitter(
6263
) -> impl Filter<Extract = (Arc<TransmitterService<EventMessage>>,), Error = Infallible> + Clone {
6364
warp::any().map(move || dependency_manager.event_transmitter.clone())
6465
}
66+
67+
/// With round_opener middleware
68+
pub fn with_beacon_provider(
69+
dependency_manager: Arc<DependencyManager>,
70+
) -> impl Filter<Extract = (Arc<dyn BeaconProvider>,), Error = Infallible> + Clone {
71+
warp::any().map(move || dependency_manager.beacon_provider.clone())
72+
}

mithril-aggregator/src/http_server/routes/signer_routes.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ fn register_signer(
2424
.and(middlewares::with_signer_registerer(
2525
dependency_manager.clone(),
2626
))
27-
.and(middlewares::with_event_transmitter(dependency_manager))
27+
.and(middlewares::with_event_transmitter(
28+
dependency_manager.clone(),
29+
))
30+
.and(middlewares::with_beacon_provider(dependency_manager))
2831
.and_then(handlers::register_signer)
2932
}
3033

@@ -33,6 +36,7 @@ mod handlers {
3336
use crate::FromRegisterSignerAdapter;
3437
use crate::{http_server::routes::reply, SignerRegisterer, SignerRegistrationError};
3538
use mithril_common::messages::RegisterSignerMessage;
39+
use mithril_common::BeaconProvider;
3640
use slog_scope::{debug, warn};
3741
use std::convert::Infallible;
3842
use std::sync::Arc;
@@ -44,34 +48,43 @@ mod handlers {
4448
register_signer_message: RegisterSignerMessage,
4549
signer_registerer: Arc<dyn SignerRegisterer>,
4650
event_transmitter: Arc<TransmitterService<EventMessage>>,
51+
beacon_provider: Arc<dyn BeaconProvider>,
4752
) -> Result<impl warp::Reply, Infallible> {
4853
debug!(
4954
"⇄ HTTP SERVER: register_signer/{:?}",
5055
register_signer_message
5156
);
5257
let signer = FromRegisterSignerAdapter::adapt(register_signer_message);
53-
let headers: Vec<(&str, &str)> = match signer_node_version.as_ref() {
58+
let mut headers: Vec<(&str, &str)> = match signer_node_version.as_ref() {
5459
Some(version) => vec![("signer-node-version", version)],
5560
None => Vec::new(),
5661
};
62+
let epoch_str = if let Ok(beacon) = beacon_provider.get_current_beacon().await {
63+
format!("{}", beacon.epoch)
64+
} else {
65+
String::new()
66+
};
5767

68+
if epoch_str.is_empty() {
69+
headers.push(("epoch", epoch_str.as_str()));
70+
}
5871
match signer_registerer.register_signer(&signer).await {
59-
Ok(()) => {
72+
Ok(signer_with_stake) => {
6073
let _ = event_transmitter.send_event_message(
6174
"HTTP::signer_register",
6275
"register_signer",
63-
&signer,
76+
&signer_with_stake,
6477
headers,
6578
);
6679

6780
Ok(reply::empty(StatusCode::CREATED))
6881
}
69-
Err(SignerRegistrationError::ExistingSigner()) => {
82+
Err(SignerRegistrationError::ExistingSigner(signer_with_stake)) => {
7083
debug!("register_signer::already_registered");
7184
let _ = event_transmitter.send_event_message(
7285
"HTTP::signer_register",
7386
"register_signer",
74-
&signer,
87+
&signer_with_stake,
7588
headers,
7689
);
7790
Ok(reply::empty(StatusCode::CREATED))
@@ -105,6 +118,7 @@ mod tests {
105118
use mithril_common::crypto_helper::ProtocolRegistrationError;
106119
use mithril_common::messages::RegisterSignerMessage;
107120
use mithril_common::test_utils::apispec::APISpec;
121+
use mithril_common::test_utils::fake_data;
108122
use warp::http::Method;
109123
use warp::test::request;
110124

@@ -128,10 +142,11 @@ mod tests {
128142

129143
#[tokio::test]
130144
async fn test_register_signer_post_ok() {
145+
let signer_with_stake = fake_data::signers_with_stakes(1).pop().unwrap();
131146
let mut mock_signer_registerer = MockSignerRegisterer::new();
132147
mock_signer_registerer
133148
.expect_register_signer()
134-
.return_once(|_| Ok(()));
149+
.return_once(|_| Ok(signer_with_stake));
135150
let (mut dependency_manager, _) = initialize_dependencies().await;
136151
dependency_manager.signer_registerer = Arc::new(mock_signer_registerer);
137152

@@ -158,10 +173,11 @@ mod tests {
158173

159174
#[tokio::test]
160175
async fn test_register_signer_post_ok_existing() {
176+
let signer_with_stake = fake_data::signers_with_stakes(1).pop().unwrap();
161177
let mut mock_signer_registerer = MockSignerRegisterer::new();
162178
mock_signer_registerer
163179
.expect_register_signer()
164-
.return_once(|_| Err(SignerRegistrationError::ExistingSigner()));
180+
.return_once(|_| Err(SignerRegistrationError::ExistingSigner(signer_with_stake)));
165181
let (mut dependency_manager, _) = initialize_dependencies().await;
166182
dependency_manager.signer_registerer = Arc::new(mock_signer_registerer);
167183

mithril-aggregator/src/signer_registerer.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use mithril_common::{
99
crypto_helper::{
1010
key_decode_hex, KESPeriod, ProtocolKeyRegistration, ProtocolRegistrationError,
1111
},
12-
entities::{Epoch, Signer, StakeDistribution},
12+
entities::{Epoch, Signer, SignerWithStake, StakeDistribution},
1313
store::StoreError,
1414
};
1515

@@ -33,7 +33,7 @@ pub enum SignerRegistrationError {
3333

3434
/// Signer is already registered.
3535
#[error("signer already registered")]
36-
ExistingSigner(),
36+
ExistingSigner(SignerWithStake),
3737

3838
/// Store error.
3939
#[error("store error: {0}")]
@@ -66,7 +66,10 @@ impl SignerRegistrationRound {
6666
#[async_trait]
6767
pub trait SignerRegisterer: Sync + Send {
6868
/// Register a signer
69-
async fn register_signer(&self, signer: &Signer) -> Result<(), SignerRegistrationError>;
69+
async fn register_signer(
70+
&self,
71+
signer: &Signer,
72+
) -> Result<SignerWithStake, SignerRegistrationError>;
7073
}
7174

7275
/// Trait to open a signer registration round
@@ -141,7 +144,10 @@ impl SignerRegistrationRoundOpener for MithrilSignerRegisterer {
141144

142145
#[async_trait]
143146
impl SignerRegisterer for MithrilSignerRegisterer {
144-
async fn register_signer(&self, signer: &Signer) -> Result<(), SignerRegistrationError> {
147+
async fn register_signer(
148+
&self,
149+
signer: &Signer,
150+
) -> Result<SignerWithStake, SignerRegistrationError> {
145151
let registration_round = self.current_round.read().await;
146152
let registration_round = registration_round
147153
.as_ref()
@@ -191,16 +197,22 @@ impl SignerRegisterer for MithrilSignerRegisterer {
191197
kes_period,
192198
verification_key,
193199
)?;
194-
let mut signer_save = signer.to_owned();
200+
let mut signer_save = SignerWithStake::from_signer(
201+
signer.to_owned(),
202+
*registration_round
203+
.stake_distribution
204+
.get(&party_id_save)
205+
.unwrap(),
206+
);
195207
signer_save.party_id = party_id_save;
196208

197209
match self
198210
.verification_key_store
199-
.save_verification_key(registration_round.epoch, signer_save)
211+
.save_verification_key(registration_round.epoch, signer_save.clone().into())
200212
.await?
201213
{
202-
Some(_) => Err(SignerRegistrationError::ExistingSigner()),
203-
None => Ok(()),
214+
Some(_) => Err(SignerRegistrationError::ExistingSigner(signer_save)),
215+
None => Ok(signer_save),
204216
}
205217
}
206218
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Monitoring
2+
3+
## Stakes vs Signer Version distribution
4+
5+
In order to set the epoch of Era changes, it is required to know the
6+
distribution of the stakes that run a compatible Signer node. There is a SQL
7+
query for that.
8+
9+
```sh
10+
$> sqlite3 -table -batch \
11+
$DATA_STORES_DIRECTORY/monitoring.sqlite3 \
12+
< mithril-aggregator/utils/monitoring/stake_signer_version.sql
13+
```
14+
15+
The variable `$DATA_STORES_DIRECTORY` should point to the directory where the
16+
databases files are stored (see files in `mithril-aggregator/config` using the
17+
key `data_stores_directory` to know where they are).
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
with
2+
signer_version as (
3+
select
4+
content->>'$.content.party_id' as party_id,
5+
content->>'$.headers.signer-node-version' as node_version,
6+
content->>'$.headers.epoch' as epoch,
7+
content->>'$.content.stake' as stakes
8+
from event
9+
order by created_at desc
10+
),
11+
stakes_version as (
12+
select
13+
party_id,
14+
case
15+
when instr(signer_version.node_version, '+') > 0
16+
then substr(signer_version.node_version, 0, instr(signer_version.node_version, '+'))
17+
else signer_version.node_version
18+
end as version,
19+
stakes,
20+
cast(epoch as int) as epoch
21+
from signer_version
22+
group by party_id, epoch
23+
),
24+
summed_stakes_version as (
25+
select
26+
epoch,
27+
version,
28+
party_id,
29+
sum(stakes) over (partition by epoch) as total_epoch_stakes,
30+
sum(stakes) over (partition by epoch, version) as stakes_version
31+
from stakes_version
32+
order by epoch desc
33+
)
34+
select
35+
epoch,
36+
version,
37+
total_epoch_stakes,
38+
stakes_version,
39+
printf("%02d %%", round((stakes_version * 100) / (total_epoch_stakes * 1.0))) as stakes_ratio,
40+
count(party_id) as pool_count
41+
from summed_stakes_version
42+
group by epoch, version
43+
order by epoch desc, version desc
44+
;

mithril-common/src/entities/signer.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,18 @@ impl SignerWithStake {
129129
}
130130
}
131131

132+
/// Turn a [Signer] into a [SignerWithStake].
133+
pub fn from_signer(signer: Signer, stake: Stake) -> Self {
134+
Self {
135+
party_id: signer.party_id,
136+
verification_key: signer.verification_key,
137+
verification_key_signature: signer.verification_key_signature,
138+
operational_certificate: signer.operational_certificate,
139+
kes_period: signer.kes_period,
140+
stake,
141+
}
142+
}
143+
132144
/// Computes the hash of SignerWithStake
133145
pub fn compute_hash(&self) -> String {
134146
let mut hasher = Sha256::new();

0 commit comments

Comments
 (0)