From 8c1f5a082b27f8c4c26208d55c43d70256466028 Mon Sep 17 00:00:00 2001 From: envestcc Date: Mon, 22 May 2023 17:37:49 +0800 Subject: [PATCH] address comments --- .../staking/contractstaking/bucket.go | 4 +- .../protocol/staking/contractstaking/cache.go | 54 +++++++++---------- .../staking/contractstaking/indexer.go | 35 +++++------- 3 files changed, 42 insertions(+), 51 deletions(-) diff --git a/action/protocol/staking/contractstaking/bucket.go b/action/protocol/staking/contractstaking/bucket.go index b663c8dd92..f83edb4d4f 100644 --- a/action/protocol/staking/contractstaking/bucket.go +++ b/action/protocol/staking/contractstaking/bucket.go @@ -25,7 +25,7 @@ type Bucket struct { ContractAddress string // contract address for the bucket } -func assembleBucket(token uint64, bi *bucketInfo, bt *BucketType) (*Bucket, error) { +func assembleBucket(token uint64, bi *bucketInfo, bt *BucketType, contractAddr string) (*Bucket, error) { vb := Bucket{ Index: token, StakedAmount: bt.Amount, @@ -36,7 +36,7 @@ func assembleBucket(token uint64, bi *bucketInfo, bt *BucketType) (*Bucket, erro AutoStake: bi.UnlockedAt == maxBlockNumber, Candidate: bi.Delegate, Owner: bi.Owner, - ContractAddress: StakingContractAddress, + ContractAddress: contractAddr, } if bi.UnlockedAt != maxBlockNumber { vb.StakeStartBlockHeight = bi.UnlockedAt diff --git a/action/protocol/staking/contractstaking/cache.go b/action/protocol/staking/contractstaking/cache.go index b3e1de5348..43ed459b56 100644 --- a/action/protocol/staking/contractstaking/cache.go +++ b/action/protocol/staking/contractstaking/cache.go @@ -14,12 +14,13 @@ import ( type ( contractStakingCache struct { - idBucketMap map[uint64]*bucketInfo // map[token]bucketInfo + bucketInfoMap map[uint64]*bucketInfo // map[token]bucketInfo candidateBucketMap map[string]map[uint64]bool // map[candidate]bucket - idBucketTypeMap map[uint64]*BucketType // map[token]BucketType + bucketTypeMap map[uint64]*BucketType // map[bucketTypeId]BucketType propertyBucketTypeMap map[int64]map[uint64]uint64 // map[amount][duration]index height uint64 totalBucketCount uint64 // total number of buckets including burned buckets + contractAddress string // contract address for the bucket } ) @@ -28,21 +29,22 @@ var ( ErrBucketNotExist = errors.New("bucket does not exist") ) -func newContractStakingCache() *contractStakingCache { +func newContractStakingCache(contractAddr string) *contractStakingCache { cache := &contractStakingCache{ - idBucketMap: make(map[uint64]*bucketInfo), - idBucketTypeMap: make(map[uint64]*BucketType), + bucketInfoMap: make(map[uint64]*bucketInfo), + bucketTypeMap: make(map[uint64]*BucketType), propertyBucketTypeMap: make(map[int64]map[uint64]uint64), candidateBucketMap: make(map[string]map[uint64]bool), + contractAddress: contractAddr, } return cache } -func (s *contractStakingCache) GetHeight() uint64 { +func (s *contractStakingCache) Height() uint64 { return s.height } -func (s *contractStakingCache) GetCandidateVotes(candidate address.Address) *big.Int { +func (s *contractStakingCache) CandidateVotes(candidate address.Address) *big.Int { votes := big.NewInt(0) m, ok := s.candidateBucketMap[candidate.String()] if !ok { @@ -52,10 +54,8 @@ func (s *contractStakingCache) GetCandidateVotes(candidate address.Address) *big if !existed { continue } - bi, ok := s.idBucketMap[id] - if !ok { - continue - } + bi := s.mustGetBucketInfo(id) + // only count the bucket that is not unstaked if bi.UnstakedAt != maxBlockNumber { continue } @@ -65,11 +65,11 @@ func (s *contractStakingCache) GetCandidateVotes(candidate address.Address) *big return votes } -func (s *contractStakingCache) GetBuckets() ([]*Bucket, error) { +func (s *contractStakingCache) Buckets() ([]*Bucket, error) { vbs := []*Bucket{} for id, bi := range s.getAllBucketInfo() { bt := s.mustGetBucketType(bi.TypeIndex) - vb, err := assembleBucket(id, bi, bt) + vb, err := assembleBucket(id, bi, bt, s.contractAddress) if err != nil { return nil, err } @@ -78,11 +78,11 @@ func (s *contractStakingCache) GetBuckets() ([]*Bucket, error) { return vbs, nil } -func (s *contractStakingCache) GetBucket(id uint64) (*Bucket, error) { +func (s *contractStakingCache) Bucket(id uint64) (*Bucket, error) { return s.getBucket(id) } -func (s *contractStakingCache) GetBucketsByCandidate(candidate address.Address) ([]*Bucket, error) { +func (s *contractStakingCache) BucketsByCandidate(candidate address.Address) ([]*Bucket, error) { bucketMap := s.getBucketInfoByCandidate(candidate) vbs := make([]*Bucket, 0, len(bucketMap)) for id := range bucketMap { @@ -95,7 +95,7 @@ func (s *contractStakingCache) GetBucketsByCandidate(candidate address.Address) return vbs, nil } -func (s *contractStakingCache) GetBucketsByIndices(indices []uint64) ([]*Bucket, error) { +func (s *contractStakingCache) BucketsByIndices(indices []uint64) ([]*Bucket, error) { vbs := make([]*Bucket, 0, len(indices)) for _, id := range indices { vb, err := s.getBucket(id) @@ -107,13 +107,13 @@ func (s *contractStakingCache) GetBucketsByIndices(indices []uint64) ([]*Bucket, return vbs, nil } -func (s *contractStakingCache) GetTotalBucketCount() uint64 { +func (s *contractStakingCache) TotalBucketCount() uint64 { return s.totalBucketCount } -func (s *contractStakingCache) GetActiveBucketTypes() map[uint64]*BucketType { +func (s *contractStakingCache) ActiveBucketTypes() map[uint64]*BucketType { m := make(map[uint64]*BucketType) - for k, v := range s.idBucketTypeMap { + for k, v := range s.bucketTypeMap { if v.ActivatedAt != maxBlockNumber { m[k] = v } @@ -131,12 +131,12 @@ func (s *contractStakingCache) getBucketTypeIndex(amount *big.Int, duration uint } func (s *contractStakingCache) getBucketType(id uint64) (*BucketType, bool) { - bt, ok := s.idBucketTypeMap[id] + bt, ok := s.bucketTypeMap[id] return bt, ok } func (s *contractStakingCache) mustGetBucketType(id uint64) *BucketType { - bt, ok := s.idBucketTypeMap[id] + bt, ok := s.bucketTypeMap[id] if !ok { panic("bucket type not found") } @@ -144,12 +144,12 @@ func (s *contractStakingCache) mustGetBucketType(id uint64) *BucketType { } func (s *contractStakingCache) getBucketInfo(id uint64) (*bucketInfo, bool) { - bi, ok := s.idBucketMap[id] + bi, ok := s.bucketInfoMap[id] return bi, ok } func (s *contractStakingCache) mustGetBucketInfo(id uint64) *bucketInfo { - bt, ok := s.idBucketMap[id] + bt, ok := s.bucketInfoMap[id] if !ok { panic("bucket info not found") } @@ -162,16 +162,16 @@ func (s *contractStakingCache) getBucket(id uint64) (*Bucket, error) { return nil, errors.Wrapf(ErrBucketNotExist, "id %d", id) } bt := s.mustGetBucketType(bi.TypeIndex) - return assembleBucket(id, bi, bt) + return assembleBucket(id, bi, bt, s.contractAddress) } func (s *contractStakingCache) getTotalBucketTypeCount() uint64 { - return uint64(len(s.idBucketTypeMap)) + return uint64(len(s.bucketTypeMap)) } func (s *contractStakingCache) getAllBucketInfo() map[uint64]*bucketInfo { m := make(map[uint64]*bucketInfo) - for k, v := range s.idBucketMap { + for k, v := range s.bucketInfoMap { m[k] = v } return m @@ -181,7 +181,7 @@ func (s *contractStakingCache) getBucketInfoByCandidate(candidate address.Addres m := make(map[uint64]*bucketInfo) for k, v := range s.candidateBucketMap[candidate.String()] { if v { - m[k] = s.idBucketMap[k] + m[k] = s.bucketInfoMap[k] } } return m diff --git a/action/protocol/staking/contractstaking/indexer.go b/action/protocol/staking/contractstaking/indexer.go index 3a4c3164e4..876f99b178 100644 --- a/action/protocol/staking/contractstaking/indexer.go +++ b/action/protocol/staking/contractstaking/indexer.go @@ -15,10 +15,6 @@ import ( ) const ( - // StakingContractAddress is the address of system staking contract - // TODO (iip-13): replace with the real system staking contract address - StakingContractAddress = "io19ys8f4uhwms6lq6ulexr5fwht9gsjes8mvuugd" - maxBlockNumber uint64 = math.MaxUint64 ) @@ -27,64 +23,59 @@ type ( // Main functions: // 1. handle contract staking contract events when new block comes to generate index data // 2. provide query interface for contract staking index data - // Generate index data flow: - // block comes -> new dirty cache -> handle contract events -> update dirty cache -> merge dirty to clean cache - // Main Object: - // kvstore: persistent storage, used to initialize index cache at startup - // cache: in-memory index for clean data, used to query index data - // dirty: the cache to update during event processing, will be merged to clean cache after all events are processed. If errors occur during event processing, dirty cache will be discarded. Indexer struct { - kvstore db.KVStore // persistent storage - cache *contractStakingCache // in-memory index for clean data + kvstore db.KVStore // persistent storage, used to initialize index cache at startup + cache *contractStakingCache // in-memory index for clean data, used to query index data + contractAddress string // stake contract address } ) // NewContractStakingIndexer creates a new contract staking indexer -func NewContractStakingIndexer(kvStore db.KVStore) *Indexer { +func NewContractStakingIndexer(kvStore db.KVStore, contractAddr string) *Indexer { return &Indexer{ kvstore: kvStore, - cache: newContractStakingCache(), + cache: newContractStakingCache(contractAddr), } } // Height returns the tip block height func (s *Indexer) Height() (uint64, error) { - return s.cache.GetHeight(), nil + return s.cache.Height(), nil } // CandidateVotes returns the candidate votes func (s *Indexer) CandidateVotes(candidate address.Address) *big.Int { - return s.cache.GetCandidateVotes(candidate) + return s.cache.CandidateVotes(candidate) } // Buckets returns the buckets func (s *Indexer) Buckets() ([]*Bucket, error) { - return s.cache.GetBuckets() + return s.cache.Buckets() } // Bucket returns the bucket func (s *Indexer) Bucket(id uint64) (*Bucket, error) { - return s.cache.GetBucket(id) + return s.cache.Bucket(id) } // BucketsByIndices returns the buckets by indices func (s *Indexer) BucketsByIndices(indices []uint64) ([]*Bucket, error) { - return s.cache.GetBucketsByIndices(indices) + return s.cache.BucketsByIndices(indices) } // BucketsByCandidate returns the buckets by candidate func (s *Indexer) BucketsByCandidate(candidate address.Address) ([]*Bucket, error) { - return s.cache.GetBucketsByCandidate(candidate) + return s.cache.BucketsByCandidate(candidate) } // TotalBucketCount returns the total bucket count including active and burnt buckets func (s *Indexer) TotalBucketCount() uint64 { - return s.cache.GetTotalBucketCount() + return s.cache.TotalBucketCount() } // BucketTypes returns the active bucket types func (s *Indexer) BucketTypes() ([]*BucketType, error) { - btMap := s.cache.GetActiveBucketTypes() + btMap := s.cache.ActiveBucketTypes() bts := make([]*BucketType, 0, len(btMap)) for _, bt := range btMap { bts = append(bts, bt)