@@ -24,7 +24,7 @@ use futures::{future, FutureExt, Stream, StreamExt};
24
24
use log:: { debug, error, info, trace, warn} ;
25
25
use parking_lot:: Mutex ;
26
26
27
- use beefy_primitives:: { BeefyApi , Commitment , SignedCommitment , KEY_TYPE } ;
27
+ use beefy_primitives:: { BeefyApi , Commitment , ConsensusLog , MmrRootHash , SignedCommitment , BEEFY_ENGINE_ID , KEY_TYPE } ;
28
28
29
29
use sc_client_api:: { Backend as BackendT , BlockchainEvents , FinalityNotification , Finalizer } ;
30
30
use sc_network_gossip:: {
@@ -36,7 +36,10 @@ use sp_application_crypto::{AppPublic, Public};
36
36
use sp_blockchain:: HeaderBackend ;
37
37
use sp_consensus:: SyncOracle as SyncOracleT ;
38
38
use sp_keystore:: { SyncCryptoStore , SyncCryptoStorePtr } ;
39
- use sp_runtime:: traits:: { Block as BlockT , Hash as HashT , Header as HeaderT , NumberFor , Zero } ;
39
+ use sp_runtime:: {
40
+ generic:: OpaqueDigestItemId ,
41
+ traits:: { Block as BlockT , Hash as HashT , Header as HeaderT , NumberFor , Zero } ,
42
+ } ;
40
43
41
44
pub mod notification;
42
45
@@ -165,7 +168,7 @@ struct BeefyWorker<Block: BlockT, Id, Signature, FinalityNotifications> {
165
168
local_id : Id ,
166
169
key_store : SyncCryptoStorePtr ,
167
170
min_interval : u32 ,
168
- rounds : Rounds < Block :: Hash , NumberFor < Block > , Id , Signature > ,
171
+ rounds : Rounds < MmrRootHash , NumberFor < Block > , Id , Signature > ,
169
172
finality_notifications : FinalityNotifications ,
170
173
gossip_engine : Arc < Mutex < GossipEngine < Block > > > ,
171
174
signed_commitment_sender : BeefySignedCommitmentSender < Block , Signature > ,
@@ -231,13 +234,20 @@ where
231
234
}
232
235
233
236
fn handle_finality_notification ( & mut self , notification : FinalityNotification < Block > ) {
234
- debug ! ( target: "beefy" , "🥩 Finality notification: {:?}" , notification) ;
237
+ debug ! ( target: "beefy" , "Finality notification: {:?}" , notification) ;
235
238
236
239
if self . should_vote_on ( * notification. header . number ( ) ) {
237
- // TODO: this needs to be properly populated by signing an MMR root as the payload
238
- // (and/or abstracting the "thing to sign") and with support for validator set changes.
240
+ let mmr_root = if let Some ( hash) = find_mmr_root_digest :: < Block , Id > ( & notification. header ) {
241
+ hash
242
+ } else {
243
+ warn ! ( target: "beefy" , "🥩 No MMR root digest found for: {:?}" , notification. header. hash( ) ) ;
244
+ return ;
245
+ } ;
246
+
247
+ // TODO: this needs added support for validator set changes (and abstracting the
248
+ // "thing to sign" would be nice).
239
249
let commitment = Commitment {
240
- payload : notification . header . hash ( ) ,
250
+ payload : mmr_root ,
241
251
block_number : notification. header . number ( ) ,
242
252
validator_set_id : 0 ,
243
253
is_set_transition_block : false ,
@@ -282,14 +292,14 @@ where
282
292
self . best_finalized_block = * notification. header . number ( ) ;
283
293
}
284
294
285
- fn handle_vote ( & mut self , round : ( Block :: Hash , NumberFor < Block > ) , vote : ( Id , Signature ) ) {
295
+ fn handle_vote ( & mut self , round : ( MmrRootHash , NumberFor < Block > ) , vote : ( Id , Signature ) ) {
286
296
// TODO: validate signature
287
297
let vote_added = self . rounds . add_vote ( round, vote) ;
288
298
289
299
if vote_added && self . rounds . is_done ( & round) {
290
300
if let Some ( signatures) = self . rounds . drop ( & round) {
291
- // TODO: this needs to be properly populated by signing an MMR root as the payload
292
- // (and/or abstracting the "thing to sign") and with support for validator set changes .
301
+ // TODO: this needs added support for validator set changes (and abstracting the
302
+ // "thing to sign" would be nice) .
293
303
let commitment = Commitment {
294
304
payload : round. 0 ,
295
305
block_number : round. 1 ,
@@ -311,7 +321,7 @@ where
311
321
|notification| async move {
312
322
debug ! ( target: "beefy" , "Got vote message: {:?}" , notification) ;
313
323
314
- VoteMessage :: < Block :: Hash , NumberFor < Block > , Id , Signature > :: decode ( & mut & notification. message [ ..] ) . ok ( )
324
+ VoteMessage :: < MmrRootHash , NumberFor < Block > , Id , Signature > :: decode ( & mut & notification. message [ ..] ) . ok ( )
315
325
} ,
316
326
) ) ;
317
327
@@ -413,6 +423,19 @@ pub async fn start_beefy_gadget<Block, Pair, Backend, Client, Network, SyncOracl
413
423
worker. run ( ) . await
414
424
}
415
425
426
+ /// Extract the MMR root hash from a digest in the given header, if it exists.
427
+ fn find_mmr_root_digest < Block : BlockT , Id > ( header : & Block :: Header ) -> Option < MmrRootHash >
428
+ where
429
+ Id : Codec ,
430
+ {
431
+ header. digest ( ) . logs ( ) . iter ( ) . find_map ( |log| {
432
+ match log. try_to :: < ConsensusLog < Id > > ( OpaqueDigestItemId :: Consensus ( & BEEFY_ENGINE_ID ) ) {
433
+ Some ( ConsensusLog :: MmrRoot ( root) ) => Some ( root) ,
434
+ _ => None ,
435
+ }
436
+ } )
437
+ }
438
+
416
439
#[ cfg( test) ]
417
440
mod tests {
418
441
#[ test]
0 commit comments