11// Copyright © Aptos Foundation
22// SPDX-License-Identifier: Apache-2.0
33
4- use super :: types:: { CertifiedAck , CertifiedNode } ;
4+ use super :: {
5+ storage:: DAGStorage ,
6+ types:: { CertifiedAck , CertifiedNode } ,
7+ NodeId ,
8+ } ;
59use crate :: {
610 dag:: {
711 dag_network:: { DAGNetworkSender , RpcHandler } ,
@@ -13,9 +17,10 @@ use crate::{
1317use anyhow:: { bail, ensure} ;
1418use aptos_consensus_types:: common:: { Author , Round } ;
1519use aptos_infallible:: RwLock ;
16- use aptos_types:: { validator_signer:: ValidatorSigner , validator_verifier:: ValidatorVerifier } ;
20+ use aptos_logger:: error;
21+ use aptos_types:: { epoch_state:: EpochState , validator_signer:: ValidatorSigner } ;
1722use futures:: { stream:: FuturesUnordered , StreamExt } ;
18- use std:: { collections:: BTreeMap , future:: Future , sync:: Arc , time:: Duration } ;
23+ use std:: { collections:: BTreeMap , future:: Future , mem , sync:: Arc , time:: Duration } ;
1924use thiserror:: Error as ThisError ;
2025
2126pub trait BroadcastStatus {
@@ -96,25 +101,42 @@ pub struct NodeBroadcastHandler {
96101 dag : Arc < RwLock < Dag > > ,
97102 signatures_by_round_peer : BTreeMap < Round , BTreeMap < Author , NodeDigestSignature > > ,
98103 signer : ValidatorSigner ,
99- verifier : ValidatorVerifier ,
104+ epoch_state : Arc < EpochState > ,
105+ storage : Arc < dyn DAGStorage > ,
100106}
101107
102108impl NodeBroadcastHandler {
103109 pub fn new (
104110 dag : Arc < RwLock < Dag > > ,
105111 signer : ValidatorSigner ,
106- verifier : ValidatorVerifier ,
112+ epoch_state : Arc < EpochState > ,
113+ storage : Arc < dyn DAGStorage > ,
107114 ) -> Self {
115+ let epoch = epoch_state. epoch ;
116+ let signatures_by_round_peer = read_signatures_from_storage ( & storage, epoch) ;
117+
108118 Self {
109119 dag,
110- signatures_by_round_peer : BTreeMap :: new ( ) ,
120+ signatures_by_round_peer,
111121 signer,
112- verifier,
122+ epoch_state,
123+ storage,
113124 }
114125 }
115126
116- pub fn gc_before_round ( & mut self , min_round : Round ) {
117- self . signatures_by_round_peer . retain ( |r, _| r >= & min_round) ;
127+ pub fn gc_before_round ( & mut self , min_round : Round ) -> anyhow:: Result < ( ) > {
128+ let to_retain = self . signatures_by_round_peer . split_off ( & min_round) ;
129+ let to_delete = mem:: replace ( & mut self . signatures_by_round_peer , to_retain) ;
130+
131+ let to_delete = to_delete
132+ . iter ( )
133+ . flat_map ( |( r, peer_and_digest) | {
134+ peer_and_digest
135+ . iter ( )
136+ . map ( |( author, _) | NodeId :: new ( self . epoch_state . epoch , * r, * author) )
137+ } )
138+ . collect ( ) ;
139+ self . storage . delete_node_signatures ( to_delete)
118140 }
119141
120142 fn validate ( & self , node : & Node ) -> anyhow:: Result < ( ) > {
@@ -146,7 +168,8 @@ impl NodeBroadcastHandler {
146168 ensure ! (
147169 missing_parents. iter( ) . all( |parent| {
148170 let node_digest = NodeDigest :: new( * parent. metadata( ) . digest( ) ) ;
149- self . verifier
171+ self . epoch_state
172+ . verifier
150173 . verify_multi_signatures( & node_digest, parent. signatures( ) )
151174 . is_ok( )
152175 } ) ,
@@ -160,6 +183,31 @@ impl NodeBroadcastHandler {
160183 }
161184}
162185
186+ fn read_signatures_from_storage (
187+ storage : & Arc < dyn DAGStorage > ,
188+ epoch : u64 ,
189+ ) -> BTreeMap < u64 , BTreeMap < Author , NodeDigestSignature > > {
190+ let mut signatures_by_round_peer = BTreeMap :: new ( ) ;
191+
192+ let all_node_signatures = storage. get_node_signatures ( ) . unwrap_or_default ( ) ;
193+ let mut to_delete = vec ! [ ] ;
194+ for ( node_id, node_sig) in all_node_signatures {
195+ if node_id. epoch ( ) == epoch {
196+ signatures_by_round_peer
197+ . entry ( node_id. round ( ) )
198+ . or_insert_with ( BTreeMap :: new)
199+ . insert ( node_id. author ( ) , node_sig) ;
200+ } else {
201+ to_delete. push ( node_id) ;
202+ }
203+ }
204+ if let Err ( err) = storage. delete_node_signatures ( to_delete) {
205+ error ! ( "unable to clear old signatures: {}" , err) ;
206+ }
207+
208+ signatures_by_round_peer
209+ }
210+
163211impl RpcHandler for NodeBroadcastHandler {
164212 type Request = Node ;
165213 type Response = NodeDigestSignature ;
@@ -171,13 +219,16 @@ impl RpcHandler for NodeBroadcastHandler {
171219 . signatures_by_round_peer
172220 . entry ( node. metadata ( ) . round ( ) )
173221 . or_insert ( BTreeMap :: new ( ) ) ;
174- // TODO(ibalajiarun): persist node before voting
175222 match signatures_by_peer. get ( node. metadata ( ) . author ( ) ) {
176223 None => {
177224 let signature = node. sign ( & self . signer ) ?;
178225 let digest_signature =
179226 NodeDigestSignature :: new ( node. metadata ( ) . epoch ( ) , node. digest ( ) , signature) ;
227+
228+ self . storage
229+ . save_node_signature ( & NodeId :: from ( & node) , & digest_signature) ?;
180230 signatures_by_peer. insert ( * node. metadata ( ) . author ( ) , digest_signature. clone ( ) ) ;
231+
181232 Ok ( digest_signature)
182233 } ,
183234 Some ( ack) => Ok ( ack. clone ( ) ) ,
0 commit comments