@@ -26,6 +26,7 @@ import (
2626
2727 "github.com/algorand/go-deadlock"
2828
29+ "github.com/algorand/go-algorand/config"
2930 "github.com/algorand/go-algorand/crypto"
3031 "github.com/algorand/go-algorand/crypto/merklesignature"
3132 "github.com/algorand/go-algorand/data/basics"
@@ -234,8 +235,8 @@ type ParticipationRegistry interface {
234235 // Delete removes a record from storage.
235236 Delete (id ParticipationID ) error
236237
237- // DeleteExpired removes all records from storage which are expired on the given round.
238- DeleteExpired (round basics.Round ) error
238+ // DeleteExpired removes all records and ephemeral voting keys from storage that are expired on the given round.
239+ DeleteExpired (latestRound basics.Round , proto config. ConsensusParams ) error
239240
240241 // Get a participation record.
241242 Get (id ParticipationID ) ParticipationRecord
@@ -318,6 +319,7 @@ const (
318319 stateProof BLOB --* msgpack encoding of merklesignature.SignerContext
319320 )`
320321
322+ // Rolling maintains a 1-to-1 relationship with Keysets by primary key
321323 createRolling = `CREATE TABLE Rolling (
322324 pk INTEGER PRIMARY KEY NOT NULL,
323325
@@ -363,7 +365,8 @@ const (
363365 lastBlockProposalRound=?,
364366 lastStateProofRound=?,
365367 effectiveFirstRound=?,
366- effectiveLastRound=?
368+ effectiveLastRound=?,
369+ voting=?
367370 WHERE pk IN (SELECT pk FROM Keysets WHERE participationID=?)`
368371)
369372
@@ -394,7 +397,7 @@ func dbSchemaUpgrade0(ctx context.Context, tx *sql.Tx, newDatabase bool) error {
394397type participationDB struct {
395398 cache map [ParticipationID ]ParticipationRecord
396399
397- // dirty marked on Record(), cleared on Register(), Delete(), Flush()
400+ // dirty marked on Record(), DeleteExpired(), cleared on Register(), Delete(), Flush()
398401 dirty map [ParticipationID ]struct {}
399402
400403 log logging.Logger
@@ -557,16 +560,35 @@ func (db *participationDB) Delete(id ParticipationID) error {
557560 return nil
558561}
559562
560- func (db * participationDB ) DeleteExpired (round basics.Round ) error {
561- // This could be optimized to delete everything with one query.
563+ func (db * participationDB ) DeleteExpired (latestRound basics.Round , agreementProto config.ConsensusParams ) error {
564+ // We need a key for round r+1 for agreement.
565+ nextRound := latestRound + 1
566+ var updated []ParticipationRecord
567+
562568 for _ , v := range db .GetAll () {
563- if v .LastValid < round {
569+ if v .LastValid < latestRound { // this participation key is no longer valid; delete it
570+ // This could be optimized to delete everything with one query.
564571 err := db .Delete (v .ParticipationID )
565572 if err != nil {
566573 return err
567574 }
575+ } else if v .FirstValid <= latestRound { // this key is valid; update it
576+ keyDilution := v .KeyDilution
577+ if keyDilution == 0 {
578+ keyDilution = agreementProto .DefaultKeyDilution
579+ }
580+ v .Voting .DeleteBeforeFineGrained (basics .OneTimeIDForRound (nextRound , keyDilution ), keyDilution )
581+ updated = append (updated , v )
568582 }
569583 }
584+
585+ // mark updated records as dirty, so they will be flushed by a call to FlushRegistry after each round
586+ db .mutex .Lock ()
587+ for _ , r := range updated {
588+ db .dirty [r .ParticipationID ] = struct {}{}
589+ db .cache [r .ParticipationID ] = r
590+ }
591+ db .mutex .Unlock ()
570592 return nil
571593}
572594
@@ -784,13 +806,18 @@ func (db *participationDB) GetForRound(id ParticipationID, round basics.Round) (
784806
785807// updateRollingFields sets all of the rolling fields according to the record object.
786808func updateRollingFields (ctx context.Context , tx * sql.Tx , record ParticipationRecord ) error {
809+ voting := record .Voting .Snapshot ()
810+ encodedVotingSecrets := protocol .Encode (& voting )
811+
787812 result , err := tx .ExecContext (ctx , updateRollingFieldsSQL ,
788813 record .LastVote ,
789814 record .LastBlockProposal ,
790815 record .LastStateProof ,
791816 record .EffectiveFirst ,
792817 record .EffectiveLast ,
818+ encodedVotingSecrets ,
793819 record .ParticipationID [:])
820+
794821 if err != nil {
795822 return err
796823 }
0 commit comments