Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions data/account/participationRegistry.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ type ParticipationRegistry interface {
// once, an error will occur when the data is flushed when inserting a duplicate key.
AppendKeys(id ParticipationID, keys StateProofKeys) error

// DeleteStateProofKeys removes all stateproof keys preceding a given round (including)
// DeleteStateProofKeys removes all stateproof keys preceding a given round (excluded)
Comment thread
id-ms marked this conversation as resolved.
Outdated
DeleteStateProofKeys(id ParticipationID, round basics.Round) error

// Delete removes a record from storage.
Expand Down Expand Up @@ -347,7 +347,7 @@ const (
insertKeysetQuery = `INSERT INTO Keysets (participationID, account, firstValidRound, lastValidRound, keyDilution, vrf, stateProof) VALUES (?, ?, ?, ?, ?, ?, ?)`
insertRollingQuery = `INSERT INTO Rolling (pk, voting) VALUES (?, ?)`
appendStateProofKeysQuery = `INSERT INTO StateProofKeys (pk, round, key) VALUES(?, ?, ?)`
deleteStateProofKeysQuery = `DELETE FROM StateProofKeys WHERE pk=? AND round<=?`
deleteStateProofKeysQuery = `DELETE FROM StateProofKeys WHERE pk=? AND round<?`

// SELECT pk FROM Keysets WHERE participationID = ?
selectPK = `SELECT pk FROM Keysets WHERE participationID = ? LIMIT 1`
Expand Down
3 changes: 2 additions & 1 deletion data/accountManager.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ type AccountManager struct {
log logging.Logger
}

// DeleteStateProofKey deletes all keys connected to ParticipationID that came before (including) the given round.
// DeleteStateProofKey deletes all keys connected to ParticipationID that came before the given round.
Comment thread
id-ms marked this conversation as resolved.
Outdated
// The round is excluded.
func (manager *AccountManager) DeleteStateProofKey(id account.ParticipationID, round basics.Round) error {
return manager.registry.DeleteStateProofKeys(id, round)
}
Expand Down
21 changes: 21 additions & 0 deletions stateproof/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ func (spw *Worker) builder(latest basics.Round) {
}

spw.deleteOldSigs(&hdr)
spw.deleteOldKeys(&hdr)
spw.deleteOldBuilders(&hdr)

// Broadcast signatures based on the previous block(s) that
Expand Down Expand Up @@ -461,6 +462,26 @@ func (spw *Worker) deleteOldSigs(currentHdr *bookkeeping.BlockHeader) {
}
}

func (spw *Worker) deleteOldKeys(currentHdr *bookkeeping.BlockHeader) {
proto := config.Consensus[currentHdr.CurrentProtocol]
stateProofNextRound := currentHdr.StateProofTracking[protocol.StateProofBasic].StateProofNextRound
if proto.StateProofInterval == 0 || stateProofNextRound == 0 {
return
}

keys := spw.accts.StateProofKeys(stateProofNextRound)
for _, key := range keys {
roundToRemove, err := key.StateProofSecrets.FirstRoundInKeyLifetime()
if err != nil {
spw.log.Warnf("deleteOldKeys: could not calculate keylifetime for account %v on round %s: %v", key.ParticipationID, roundToRemove, err)
Comment thread
id-ms marked this conversation as resolved.
Outdated
Comment thread
algonathan marked this conversation as resolved.
Outdated
}
err = spw.accts.DeleteStateProofKey(key.ParticipationID, basics.Round(roundToRemove))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to use roundToRemove? Why not latestRoundToKeep instead?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we delete roundToRemove we might delete a key that should be used for a later state proof.

if err != nil {
spw.log.Warnf("deleteOldKeys: could not remove key for account %v on round %s: %v", key.ParticipationID, roundToRemove, err)
}
}
}

func (spw *Worker) deleteOldBuilders(currentHdr *bookkeeping.BlockHeader) {
oldestRoundToRemove := GetOldestExpectedStateProof(currentHdr)

Expand Down
20 changes: 1 addition & 19 deletions stateproof/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (

"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto/merklesignature"
"github.com/algorand/go-algorand/data/account"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/bookkeeping"
"github.com/algorand/go-algorand/protocol"
Expand Down Expand Up @@ -117,8 +116,6 @@ func (spw *Worker) signStateProof(hdr bookkeeping.BlockHeader) {
}

sigs := make([]sigFromAddr, 0, len(keys))
ids := make([]account.ParticipationID, 0, len(keys))
usedSigners := make([]*merklesignature.Signer, 0, len(keys))

stateproofMessage, err := GenerateStateProofMessage(spw.ledger, uint64(votersHdr.Round), hdr)
if err != nil {
Expand Down Expand Up @@ -155,30 +152,15 @@ func (spw *Worker) signStateProof(hdr bookkeeping.BlockHeader) {
Round: hdr.Round,
Sig: sig,
})
ids = append(ids, key.ParticipationID)
usedSigners = append(usedSigners, key.StateProofSecrets)
}

// any error in handle sig indicates the signature wasn't stored in disk, thus we cannot delete the key.
for i, sfa := range sigs {
for _, sfa := range sigs {
if _, err := spw.handleSig(sfa, nil); err != nil {
spw.log.Warnf("spw.signBlock(%d): handleSig: %v", hdr.Round, err)
continue
}

spw.log.Infof("spw.signBlock(%d): sp message was signed with address %v", hdr.Round, sfa.SignerAddress)
firstRoundInKeyLifetime, err := usedSigners[i].FirstRoundInKeyLifetime() // Calculate first round of the key in order to delete all previous keys (and keep the current one for now)
if err != nil {
spw.log.Warnf("spw.signBlock(%d): Signer.FirstRoundInKeyLifetime: %v", hdr.Round, err)
continue
}
if firstRoundInKeyLifetime == 0 {
continue // No previous keys to delete (also underflows when subtracting 1)
}

// Safe to delete key for sfa.Round because the signature is now stored in the disk.
if err := spw.accts.DeleteStateProofKey(ids[i], basics.Round(firstRoundInKeyLifetime-1)); err != nil { // Subtract 1 to delete all keys up to this one
spw.log.Warnf("spw.signBlock(%d): DeleteStateProofKey: %v", hdr.Round, err)
}
}
}
Loading