Skip to content

Commit 25f2bc5

Browse files
committed
replace stakeview with voteview
1 parent 4138dad commit 25f2bc5

File tree

18 files changed

+1049
-450
lines changed

18 files changed

+1049
-450
lines changed

action/protocol/staking/contractstake_indexer.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313

1414
"github.com/ethereum/go-ethereum/accounts/abi"
1515
"github.com/iotexproject/iotex-address/address"
16+
1617
"github.com/iotexproject/iotex-core/v2/action"
1718
"github.com/iotexproject/iotex-core/v2/action/protocol"
1819
"github.com/iotexproject/iotex-core/v2/action/protocol/staking/contractstaking"
@@ -56,6 +57,10 @@ type (
5657
LoadStakeView(context.Context, protocol.StateReader) (ContractStakeView, error)
5758
// CreateEventProcessor creates a new event processor
5859
CreateEventProcessor(context.Context, EventHandler) EventProcessor
60+
// ContractStakingBuckets returns all the contract staking buckets
61+
ContractStakingBuckets() (uint64, map[uint64]*contractstaking.Bucket, error)
62+
63+
BucketReader
5964
}
6065
// ContractStakingIndexerWithBucketType defines the interface of contract staking reader with bucket type
6166
ContractStakingIndexerWithBucketType interface {

action/protocol/staking/contractstake_indexer_mock.go

Lines changed: 62 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

action/protocol/staking/protocol.go

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,16 @@ func (p *Protocol) CreatePreStates(ctx context.Context, sm protocol.StateManager
441441
return err
442442
}
443443
vd := v.(*viewData)
444+
indexers := []ContractStakingIndexer{}
445+
if p.contractStakingIndexer != nil {
446+
indexers = append(indexers, p.contractStakingIndexer)
447+
}
448+
if p.contractStakingIndexerV2 != nil {
449+
indexers = append(indexers, p.contractStakingIndexerV2)
450+
}
451+
if p.contractStakingIndexerV3 != nil {
452+
indexers = append(indexers, p.contractStakingIndexerV3)
453+
}
444454
if blkCtx.BlockHeight == g.ToBeEnabledBlockHeight {
445455
handler, err := newNFTBucketEventHandler(sm, func(bucket *contractstaking.Bucket, height uint64) *big.Int {
446456
vb := p.convertToVoteBucket(bucket, height)
@@ -449,14 +459,43 @@ func (p *Protocol) CreatePreStates(ctx context.Context, sm protocol.StateManager
449459
if err != nil {
450460
return err
451461
}
452-
if err := vd.contractsStake.Migrate(handler); err != nil {
462+
buckets := make([]map[uint64]*contractstaking.Bucket, 3)
463+
for i, indexer := range indexers {
464+
h, bs, err := indexer.ContractStakingBuckets()
465+
if err != nil {
466+
return err
467+
}
468+
if h != blkCtx.BlockHeight-1 {
469+
return errors.Errorf("bucket cache height %d does not match current height %d", h, blkCtx.BlockHeight-1)
470+
}
471+
buckets[i] = bs
472+
}
473+
if err := vd.contractsStake.Migrate(handler, buckets); err != nil {
453474
return errors.Wrap(err, "failed to flush buckets for contract staking")
454475
}
455476
}
456477
if featureCtx.StoreVoteOfNFTBucketIntoView {
457-
if err := vd.contractsStake.CreatePreStates(ctx); err != nil {
478+
brs := make([]BucketReader, len(indexers))
479+
for i, indexer := range indexers {
480+
brs[i] = indexer
481+
}
482+
if err := vd.contractsStake.CreatePreStates(ctx, brs); err != nil {
458483
return err
459484
}
485+
if blkCtx.BlockHeight == g.WakeBlockHeight {
486+
buckets := make([]map[uint64]*contractstaking.Bucket, 3)
487+
for i, indexer := range indexers {
488+
h, bs, err := indexer.ContractStakingBuckets()
489+
if err != nil {
490+
return err
491+
}
492+
if h != blkCtx.BlockHeight-1 {
493+
return errors.Errorf("bucket cache height %d does not match current height %d", h, blkCtx.BlockHeight-1)
494+
}
495+
buckets[i] = bs
496+
}
497+
vd.contractsStake.Revise(buckets)
498+
}
460499
}
461500

462501
if p.candBucketsIndexer == nil {
@@ -741,10 +780,6 @@ func (p *Protocol) isActiveCandidate(ctx context.Context, csr CandidiateStateCom
741780

742781
// ActiveCandidates returns all active candidates in candidate center
743782
func (p *Protocol) ActiveCandidates(ctx context.Context, sr protocol.StateReader, height uint64) (state.CandidateList, error) {
744-
srHeight, err := sr.Height()
745-
if err != nil {
746-
return nil, errors.Wrap(err, "failed to get StateReader height")
747-
}
748783
c, err := ConstructBaseView(sr)
749784
if err != nil {
750785
return nil, errors.Wrap(err, "failed to get ActiveCandidates")
@@ -754,20 +789,10 @@ func (p *Protocol) ActiveCandidates(ctx context.Context, sr protocol.StateReader
754789
for i := range list {
755790
if protocol.MustGetFeatureCtx(ctx).StoreVoteOfNFTBucketIntoView {
756791
var csVotes *big.Int
757-
if protocol.MustGetFeatureCtx(ctx).CreatePostActionStates {
758-
csVotes, err = p.contractStakingVotesFromView(ctx, list[i].GetIdentifier(), c.BaseView())
759-
if err != nil {
760-
return nil, err
761-
}
762-
} else {
763-
// specifying the height param instead of query latest from indexer directly, aims to cause error when indexer falls behind.
764-
// the reason of using srHeight-1 is contract indexer is not updated before the block is committed.
765-
csVotes, err = p.contractStakingVotesFromIndexer(ctx, list[i].GetIdentifier(), srHeight-1)
766-
if err != nil {
767-
return nil, err
768-
}
792+
csVotes, err = p.contractStakingVotesFromView(ctx, list[i].GetIdentifier(), c.BaseView())
793+
if err != nil {
794+
return nil, err
769795
}
770-
771796
list[i].Votes.Add(list[i].Votes, csVotes)
772797
}
773798
active, err := p.isActiveCandidate(ctx, c, list[i])
@@ -1049,13 +1074,11 @@ func (p *Protocol) contractStakingVotesFromView(ctx context.Context, candidate a
10491074
views = append(views, view.contractsStake.v3)
10501075
}
10511076
for _, cv := range views {
1052-
btks, err := cv.BucketsByCandidate(candidate)
1053-
if err != nil {
1054-
return nil, errors.Wrap(err, "failed to get BucketsByCandidate from contractStakingIndexer")
1055-
}
1056-
for _, b := range btks {
1057-
votes.Add(votes, p.contractBucketVotes(featureCtx, b))
1077+
v := cv.CandidateStakeVotes(ctx, candidate)
1078+
if v == nil {
1079+
continue
10581080
}
1081+
votes.Add(votes, v)
10591082
}
10601083
return votes, nil
10611084
}

action/protocol/staking/viewdata.go

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,19 @@ import (
1010
"math/big"
1111

1212
"github.com/iotexproject/iotex-address/address"
13+
"github.com/pkg/errors"
14+
1315
"github.com/iotexproject/iotex-core/v2/action"
1416
"github.com/iotexproject/iotex-core/v2/action/protocol"
15-
"github.com/pkg/errors"
17+
"github.com/iotexproject/iotex-core/v2/action/protocol/staking/contractstaking"
1618
)
1719

1820
type (
21+
// BucketReader defines the interface to read bucket info
22+
BucketReader interface {
23+
DeductBucket(address.Address, uint64) (*contractstaking.Bucket, error)
24+
}
25+
1926
// ContractStakeView is the interface for contract stake view
2027
ContractStakeView interface {
2128
// Wrap wraps the contract stake view
@@ -27,13 +34,15 @@ type (
2734
// Commit commits the contract stake view
2835
Commit(context.Context, protocol.StateManager) error
2936
// CreatePreStates creates pre states for the contract stake view
30-
CreatePreStates(ctx context.Context) error
37+
CreatePreStates(ctx context.Context, br BucketReader) error
3138
// Handle handles the receipt for the contract stake view
3239
Handle(ctx context.Context, receipt *action.Receipt) error
3340
// Migrate writes the bucket types and buckets to the state manager
34-
Migrate(EventHandler) error
41+
Migrate(EventHandler, map[uint64]*contractstaking.Bucket) error
42+
// Revise updates the contract stake view with the latest bucket data
43+
Revise(map[uint64]*contractstaking.Bucket)
3544
// BucketsByCandidate returns the buckets by candidate address
36-
BucketsByCandidate(ownerAddr address.Address) ([]*VoteBucket, error)
45+
CandidateStakeVotes(ctx context.Context, id address.Address) *big.Int
3746
AddBlockReceipts(ctx context.Context, receipts []*action.Receipt) error
3847
}
3948
// viewData is the data that need to be stored in protocol's view
@@ -126,19 +135,37 @@ func (v *viewData) Revert(snapshot int) error {
126135
return nil
127136
}
128137

129-
func (csv *contractStakeView) Migrate(nftHandler EventHandler) error {
138+
func (csv *contractStakeView) Revise(buckets []map[uint64]*contractstaking.Bucket) {
139+
idx := 0
140+
if csv.v1 != nil {
141+
csv.v1.Revise(buckets[idx])
142+
idx++
143+
}
144+
if csv.v2 != nil {
145+
csv.v2.Revise(buckets[idx])
146+
idx++
147+
}
148+
if csv.v3 != nil {
149+
csv.v3.Revise(buckets[idx])
150+
}
151+
}
152+
153+
func (csv *contractStakeView) Migrate(nftHandler EventHandler, buckets []map[uint64]*contractstaking.Bucket) error {
154+
idx := 0
130155
if csv.v1 != nil {
131-
if err := csv.v1.Migrate(nftHandler); err != nil {
156+
if err := csv.v1.Migrate(nftHandler, buckets[idx]); err != nil {
132157
return err
133158
}
159+
idx++
134160
}
135161
if csv.v2 != nil {
136-
if err := csv.v2.Migrate(nftHandler); err != nil {
162+
if err := csv.v2.Migrate(nftHandler, buckets[idx]); err != nil {
137163
return err
138164
}
165+
idx++
139166
}
140167
if csv.v3 != nil {
141-
if err := csv.v3.Migrate(nftHandler); err != nil {
168+
if err := csv.v3.Migrate(nftHandler, buckets[idx]); err != nil {
142169
return err
143170
}
144171
}
@@ -179,19 +206,22 @@ func (csv *contractStakeView) Fork() *contractStakeView {
179206
return clone
180207
}
181208

182-
func (csv *contractStakeView) CreatePreStates(ctx context.Context) error {
209+
func (csv *contractStakeView) CreatePreStates(ctx context.Context, brs []BucketReader) error {
210+
idx := 0
183211
if csv.v1 != nil {
184-
if err := csv.v1.CreatePreStates(ctx); err != nil {
212+
if err := csv.v1.CreatePreStates(ctx, brs[idx]); err != nil {
185213
return err
186214
}
215+
idx++
187216
}
188217
if csv.v2 != nil {
189-
if err := csv.v2.CreatePreStates(ctx); err != nil {
218+
if err := csv.v2.CreatePreStates(ctx, brs[idx]); err != nil {
190219
return err
191220
}
221+
idx++
192222
}
193223
if csv.v3 != nil {
194-
if err := csv.v3.CreatePreStates(ctx); err != nil {
224+
if err := csv.v3.CreatePreStates(ctx, brs[idx]); err != nil {
195225
return err
196226
}
197227
}

blockindex/contractstaking/bucket.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package contractstaking
77

88
import (
99
"github.com/iotexproject/iotex-core/v2/action/protocol/staking"
10+
"github.com/iotexproject/iotex-core/v2/action/protocol/staking/contractstaking"
1011
)
1112

1213
// Bucket defines the bucket struct for contract staking
@@ -31,3 +32,28 @@ func assembleBucket(token uint64, bi *bucketInfo, bt *BucketType, contractAddr s
3132
}
3233
return &vb
3334
}
35+
36+
func assembleContractBucket(bi *bucketInfo, bt *BucketType) *contractstaking.Bucket {
37+
return &contractstaking.Bucket{
38+
Candidate: bi.Delegate,
39+
Owner: bi.Owner,
40+
StakedAmount: bt.Amount,
41+
StakedDuration: bt.Duration,
42+
CreatedAt: bi.CreatedAt,
43+
UnlockedAt: bi.UnlockedAt,
44+
UnstakedAt: bi.UnstakedAt,
45+
}
46+
}
47+
48+
func contractBucketToVoteBucket(token uint64, b *contractstaking.Bucket, contractAddr string, blocksToDurationFn blocksDurationFn) *Bucket {
49+
return assembleBucket(token, &bucketInfo{
50+
Owner: b.Owner,
51+
Delegate: b.Candidate,
52+
CreatedAt: b.CreatedAt,
53+
UnlockedAt: b.UnlockedAt,
54+
UnstakedAt: b.UnstakedAt,
55+
}, &BucketType{
56+
Amount: b.StakedAmount,
57+
Duration: b.StakedDuration,
58+
}, contractAddr, blocksToDurationFn)
59+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package contractstaking
2+
3+
import (
4+
"context"
5+
6+
"github.com/iotexproject/iotex-address/address"
7+
8+
"github.com/iotexproject/iotex-core/v2/action/protocol/staking"
9+
)
10+
11+
type eventProcessorBuilder struct {
12+
contractAddr address.Address
13+
}
14+
15+
func newEventProcessorBuilder(contractAddr address.Address) *eventProcessorBuilder {
16+
return &eventProcessorBuilder{
17+
contractAddr: contractAddr,
18+
}
19+
}
20+
21+
func (b *eventProcessorBuilder) Build(ctx context.Context, handler staking.EventHandler) staking.EventProcessor {
22+
return newContractStakingEventProcessor(b.contractAddr, handler)
23+
}

0 commit comments

Comments
 (0)