diff options
Diffstat (limited to 'data/accountManager.go')
-rw-r--r-- | data/accountManager.go | 96 |
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) + } } |