1
1
use async_trait:: async_trait;
2
2
use serde:: { Deserialize , Serialize } ;
3
+ use sha2:: { Digest , Sha256 } ;
3
4
use std:: sync:: Arc ;
4
5
use tokio:: sync:: RwLock ;
5
6
@@ -15,17 +16,37 @@ use mithril_common::{
15
16
#[ derive( Debug , PartialEq , Serialize , Deserialize , Clone ) ]
16
17
pub struct MithrilStakeDistribution {
17
18
signers_with_stake : Vec < SignerWithStake > ,
19
+ hash : String ,
18
20
}
19
21
20
22
impl MithrilStakeDistribution {
21
23
/// MithrilStakeDistribution artifact factory
22
24
pub fn new ( signers_with_stake : Vec < SignerWithStake > ) -> Self {
23
- Self { signers_with_stake }
25
+ let mut signers_with_stake_sorted = signers_with_stake;
26
+ signers_with_stake_sorted. sort ( ) ;
27
+ let mut mithril_stake_distribution = Self {
28
+ signers_with_stake : signers_with_stake_sorted,
29
+ hash : "" . to_string ( ) ,
30
+ } ;
31
+ mithril_stake_distribution. hash = mithril_stake_distribution. compute_hash ( ) ;
32
+ mithril_stake_distribution
33
+ }
34
+
35
+ fn compute_hash ( & self ) -> String {
36
+ let mut hasher = Sha256 :: new ( ) ;
37
+ for signer_with_stake in & self . signers_with_stake {
38
+ hasher. update ( signer_with_stake. compute_hash ( ) . as_bytes ( ) ) ;
39
+ }
40
+ hex:: encode ( hasher. finalize ( ) )
24
41
}
25
42
}
26
43
27
44
#[ typetag:: serde]
28
- impl Artifact for MithrilStakeDistribution { }
45
+ impl Artifact for MithrilStakeDistribution {
46
+ fn get_id ( & self ) -> String {
47
+ self . hash . clone ( )
48
+ }
49
+ }
29
50
30
51
/// A [MithrilStakeDistributionArtifact] builder
31
52
pub struct MithrilStakeDistributionArtifactBuilder {
@@ -79,4 +100,24 @@ mod tests {
79
100
let artifact_expected = MithrilStakeDistribution :: new ( signers_with_stake) ;
80
101
assert_eq ! ( artifact_expected, artifact) ;
81
102
}
103
+
104
+ #[ test]
105
+ fn sort_given_signers_when_created ( ) {
106
+ let signers_with_stake = fake_data:: signers_with_stakes ( 5 ) ;
107
+
108
+ assert_eq ! (
109
+ MithrilStakeDistribution :: new( signers_with_stake. clone( ) ) ,
110
+ MithrilStakeDistribution :: new( signers_with_stake. into_iter( ) . rev( ) . collect( ) )
111
+ ) ;
112
+ }
113
+
114
+ #[ test]
115
+ fn hash_value_doesnt_change_if_signers_order_change ( ) {
116
+ let signers_with_stake = fake_data:: signers_with_stakes ( 5 ) ;
117
+
118
+ let sd = MithrilStakeDistribution :: new ( signers_with_stake. clone ( ) ) ;
119
+ let sd2 = MithrilStakeDistribution :: new ( signers_with_stake. into_iter ( ) . rev ( ) . collect ( ) ) ;
120
+
121
+ assert_eq ! ( sd. hash, sd2. hash) ;
122
+ }
82
123
}
0 commit comments