summaryrefslogtreecommitdiff
path: root/data/accountManager.go
diff options
context:
space:
mode:
Diffstat (limited to 'data/accountManager.go')
-rw-r--r--data/accountManager.go96
1 files changed, 75 insertions, 21 deletions
diff --git a/data/accountManager.go b/data/accountManager.go
index 79a57287b..b615a211f 100644
--- a/data/accountManager.go
+++ b/data/accountManager.go
@@ -18,11 +18,11 @@ package data
import (
"fmt"
+ "time"
"github.com/algorand/go-deadlock"
"github.com/algorand/go-algorand/config"
- "github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/data/account"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/bookkeeping"
@@ -31,37 +31,27 @@ import (
"github.com/algorand/go-algorand/protocol"
)
-// A ParticipationKeyIdentity defines the parameters that makes a pariticpation key unique.
-type ParticipationKeyIdentity struct {
- basics.Address // the address this participation key is used to vote for.
-
- // FirstValid and LastValid are inclusive.
- FirstValid basics.Round
- LastValid basics.Round
-
- VoteID crypto.OneTimeSignatureVerifier
- SelectionID crypto.VrfPubkey
-}
-
// AccountManager loads and manages accounts for the node
type AccountManager struct {
mu deadlock.Mutex
- partKeys map[ParticipationKeyIdentity]account.PersistedParticipation
+ partKeys map[account.ParticipationKeyIdentity]account.PersistedParticipation
// Map to keep track of accounts for which we've sent
// AccountRegistered telemetry events
registeredAccounts map[string]bool
- log logging.Logger
+ registry account.ParticipationRegistry
+ log logging.Logger
}
// MakeAccountManager creates a new AccountManager with a custom logger
-func MakeAccountManager(log logging.Logger) *AccountManager {
+func MakeAccountManager(log logging.Logger, registry account.ParticipationRegistry) *AccountManager {
manager := &AccountManager{}
manager.log = log
- manager.partKeys = make(map[ParticipationKeyIdentity]account.PersistedParticipation)
+ manager.partKeys = make(map[account.ParticipationKeyIdentity]account.PersistedParticipation)
manager.registeredAccounts = make(map[string]bool)
+ manager.registry = registry
return manager
}
@@ -77,6 +67,31 @@ func (manager *AccountManager) Keys(rnd basics.Round) (out []account.Participati
}
}
return out
+
+ // PKI TODO: source keys from the registry.
+ // This kinda works, but voting keys are not updated.
+ /*
+ for _, record := range manager.registry.GetAll() {
+ part := account.Participation{
+ Parent: record.Account,
+ VRF: record.VRF,
+ Voting: record.Voting,
+ FirstValid: record.FirstValid,
+ LastValid: record.LastValid,
+ KeyDilution: record.KeyDilution,
+ }
+
+ if part.OverlapsInterval(rnd, rnd) {
+ out = append(out, part)
+
+ id := part.ID()
+ if !bytes.Equal(id[:], record.ParticipationID[:]) {
+ manager.log.Warnf("Participation IDs do not equal while fetching keys... %s != %s\n", id, record.ParticipationID)
+ }
+ }
+ }
+ return out
+ */
}
// HasLiveKeys returns true if we have any Participation
@@ -97,18 +112,28 @@ func (manager *AccountManager) HasLiveKeys(from, to basics.Round) bool {
// The return value indicates if the key has been added (true) or
// if this is a duplicate key (false).
func (manager *AccountManager) AddParticipation(participation account.PersistedParticipation) bool {
+ // Tell the ParticipationRegistry about the Participation. Duplicate entries
+ // are ignored.
+ pid, err := manager.registry.Insert(participation.Participation)
+ if err != nil && err != account.ErrAlreadyInserted {
+ manager.log.Warnf("Failed to insert participation key.")
+ }
+ manager.log.Infof("Inserted key (%s) for account (%s) first valid (%d) last valid (%d)\n",
+ pid, participation.Parent, participation.FirstValid, participation.LastValid)
+
manager.mu.Lock()
defer manager.mu.Unlock()
address := participation.Address()
first, last := participation.ValidInterval()
- partkeyID := ParticipationKeyIdentity{
- Address: address,
+ partkeyID := account.ParticipationKeyIdentity{
+ Parent: address,
FirstValid: first,
LastValid: last,
+ VRFSK: participation.VRF.SK,
VoteID: participation.Voting.OneTimeSignatureVerifier,
- SelectionID: participation.VRF.PK,
+ KeyDilution: participation.KeyDilution,
}
// Check if we already have participation keys for this address in this interval
@@ -177,11 +202,40 @@ func (manager *AccountManager) DeleteOldKeys(latestHdr bookkeeping.BlockHeader,
}
}()
- // wait all all disk flushes, and report errors as they appear.
+ // wait for all disk flushes, and report errors as they appear.
for errString, errCh := range pendingItems {
err := <-errCh
if err != nil {
logging.Base().Warnf("%s: %v", errString, err)
}
}
+
+ // PKI TODO: This needs to update the partkeys also, see the 'DeleteOldKeys' function above, it's part
+ // is part of PersistedParticipation, but just calls 'part.Voting.DeleteBeforeFineGrained'
+ // Delete expired records from participation registry.
+ if err := manager.registry.DeleteExpired(latestHdr.Round); err != nil {
+ manager.log.Warnf("error while deleting expired records from participation registry: %w", err)
+ }
+}
+
+// Registry fetches the ParticipationRegistry.
+func (manager *AccountManager) Registry() account.ParticipationRegistry {
+ return manager.registry
+}
+
+// FlushRegistry tells the underlying participation registry to flush it's change cache to the DB.
+func (manager *AccountManager) FlushRegistry(timeout time.Duration) {
+ err := manager.registry.Flush(timeout)
+ if err != nil {
+ manager.log.Warnf("error while flushing the registry: %w", err)
+ }
+}
+
+// Record asynchronously records a participation key usage event.
+func (manager *AccountManager) Record(account basics.Address, round basics.Round, participationType account.ParticipationAction) {
+ // This function updates a cache in the ParticipationRegistry, we must call Flush to persist the changes.
+ err := manager.registry.Record(account, round, participationType)
+ if err != nil {
+ manager.log.Warnf("node.Record: Account %v not able to record participation (%d) on round %d: %w", account, participationType, round, err)
+ }
}