Skip to content

Commit 559575e

Browse files
envestccCoderZhi
andauthored
[staking] Mute v2 contract stakes (#4635)
* mute v2 contract stakes * always handle receipt * add tests for mute * add tests for not mute --------- Co-authored-by: CoderZhi <thecoderzhi@gmail.com>
1 parent 75dce36 commit 559575e

File tree

9 files changed

+478
-119
lines changed

9 files changed

+478
-119
lines changed

action/protocol/staking/protocol.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,15 @@ func (p *Protocol) CreatePreStates(ctx context.Context, sm protocol.StateManager
359359
return err
360360
}
361361
}
362+
// create pre-states for contract staking
363+
v, err := sm.ReadView(_protocolID)
364+
if err != nil {
365+
return err
366+
}
367+
if err = v.(*ViewData).contractsStake.CreatePreStates(ctx); err != nil {
368+
return err
369+
}
370+
362371
if p.candBucketsIndexer == nil {
363372
return nil
364373
}
@@ -374,16 +383,6 @@ func (p *Protocol) CreatePreStates(ctx context.Context, sm protocol.StateManager
374383
if epochStartHeight != blkCtx.BlockHeight || featureCtx.SkipStakingIndexer {
375384
return nil
376385
}
377-
378-
if featureCtx.CreatePostActionStates {
379-
v, err := sm.ReadView(_protocolID)
380-
if err != nil {
381-
return err
382-
}
383-
if err = v.(*ViewData).contractsStake.CreatePreStates(ctx); err != nil {
384-
return err
385-
}
386-
}
387386
return p.handleStakingIndexer(ctx, rp.GetEpochHeight(currentEpochNum-1), sm)
388387
}
389388

chainservice/builder.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ func (builder *Builder) buildContractStakingIndexer(forTest bool) error {
387387
builder.cfg.Genesis.SystemStakingContractV2Address,
388388
builder.cfg.Genesis.SystemStakingContractV2Height,
389389
blockDurationFn,
390+
stakingindex.WithMuteHeight(builder.cfg.Genesis.WakeBlockHeight),
390391
)
391392
builder.cs.contractStakingIndexerV2 = indexer
392393
}

e2etest/contract_staking_v2_test.go

Lines changed: 385 additions & 6 deletions
Large diffs are not rendered by default.

e2etest/e2etest.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7+
"math/big"
78
"os"
89
"slices"
910
"testing"
1011
"time"
1112

13+
"github.com/ethereum/go-ethereum/common"
1214
"github.com/ethereum/go-ethereum/common/hexutil"
1315
"github.com/ethereum/go-ethereum/ethclient"
1416
"github.com/go-resty/resty/v2"
@@ -22,12 +24,14 @@ import (
2224

2325
"github.com/iotexproject/iotex-core/v2/action"
2426
"github.com/iotexproject/iotex-core/v2/action/protocol"
27+
"github.com/iotexproject/iotex-core/v2/action/protocol/staking"
2528
"github.com/iotexproject/iotex-core/v2/actpool"
2629
apitypes "github.com/iotexproject/iotex-core/v2/api/types"
2730
"github.com/iotexproject/iotex-core/v2/blockchain"
2831
"github.com/iotexproject/iotex-core/v2/blockchain/block"
2932
"github.com/iotexproject/iotex-core/v2/chainservice"
3033
"github.com/iotexproject/iotex-core/v2/config"
34+
"github.com/iotexproject/iotex-core/v2/pkg/util/abiutil"
3135
"github.com/iotexproject/iotex-core/v2/server/itx"
3236
"github.com/iotexproject/iotex-core/v2/testutil"
3337
)
@@ -253,6 +257,20 @@ func (e *e2etest) getBlobs(height uint64) ([]*apitypes.BlobSidecarResult, error)
253257
return result.Result, nil
254258
}
255259

260+
func (e *e2etest) calculateWeightedVotes(bkt *iotextypes.VoteBucket, selfstake bool, blockInterval time.Duration) (*big.Int, error) {
261+
stakeAmount, ok := new(big.Int).SetString(bkt.StakedAmount, 10)
262+
if !ok {
263+
return nil, errors.Errorf("failed to set staked amount %s", bkt.StakedAmount)
264+
}
265+
stakeDurationSeconds := bkt.StakedDuration * 24 * 3600
266+
if bkt.StakedDurationBlockNumber > 0 {
267+
stakeDurationSeconds = uint32(bkt.StakedDurationBlockNumber) * uint32(blockInterval.Seconds())
268+
}
269+
return staking.CalculateVoteWeight(e.cfg.Genesis.VoteWeightCalConsts,
270+
&staking.VoteBucket{AutoStake: bkt.AutoStake, StakedDuration: time.Duration(stakeDurationSeconds) * (time.Second), StakedAmount: stakeAmount, Timestamped: true},
271+
selfstake), nil
272+
}
273+
256274
func runTxs(ctx context.Context, ap actpool.ActPool, bc blockchain.Blockchain, txs []*actionWithTime) ([]*action.SealedEnvelope, []*action.Receipt, *block.Block, error) {
257275
for _, tx := range txs {
258276
if err := ap.Add(ctx, tx.act); err != nil {
@@ -388,3 +406,33 @@ func clearDBPaths(cfg *config.Config) {
388406
testutil.CleanupPath(cfg.ActPool.Store.Datadir)
389407
}
390408
}
409+
410+
func parseV2StakedBucketIdx(contract string, receipt *action.Receipt) ([]uint64, error) {
411+
if uint64(iotextypes.ReceiptStatus_Success) != receipt.Status {
412+
return nil, nil
413+
}
414+
var idxs []uint64
415+
for _, log := range receipt.Logs() {
416+
if log.Address != contract {
417+
continue
418+
}
419+
abiEvent, err := staking.StakingContractABI.EventByID(common.Hash(log.Topics[0]))
420+
if err != nil {
421+
return nil, errors.Wrapf(err, "get event abi from topic %v failed", log.Topics[0])
422+
}
423+
if abiEvent.Name != "Staked" {
424+
continue
425+
}
426+
// unpack event data
427+
event, err := abiutil.UnpackEventParam(abiEvent, log)
428+
if err != nil {
429+
return nil, err
430+
}
431+
tokenIDParam, err := event.FieldByIDUint256(0)
432+
if err != nil {
433+
return nil, err
434+
}
435+
idxs = append(idxs, tokenIDParam.Uint64())
436+
}
437+
return idxs, nil
438+
}

state/factory/workingset.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,10 @@ func (ws *workingSet) runAction(
203203
return nil, err
204204
}
205205
}
206-
if fCtx.CreatePostActionStates {
207-
for _, p := range reg.All() {
208-
if pp, ok := p.(protocol.PostActionHandler); ok {
209-
if err := pp.HandleReceipt(ctx, selp.Envelope, ws, receipt); err != nil {
210-
return nil, errors.Wrapf(err, "error when handle action %x receipt", selpHash)
211-
}
206+
for _, p := range reg.All() {
207+
if pp, ok := p.(protocol.PostActionHandler); ok {
208+
if err := pp.HandleReceipt(ctx, selp.Envelope, ws, receipt); err != nil {
209+
return nil, errors.Wrapf(err, "error when handle action %x receipt", selpHash)
212210
}
213211
}
214212
}

systemcontractindex/stakingindex/event_handler.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ type eventHandler struct {
3838
// context for event handler
3939
blockCtx protocol.BlockCtx
4040
timestamped bool
41+
muted bool
4142
}
4243

4344
func init() {
@@ -48,14 +49,15 @@ func init() {
4849
}
4950
}
5051

51-
func newEventHandler(bucketNS string, dirty *cache, blkCtx protocol.BlockCtx, timestamped bool) *eventHandler {
52+
func newEventHandler(bucketNS string, dirty *cache, blkCtx protocol.BlockCtx, timestamped, muted bool) *eventHandler {
5253
return &eventHandler{
5354
stakingBucketNS: bucketNS,
5455
dirty: dirty,
5556
delta: batch.NewBatch(),
5657
tokenOwner: make(map[uint64]address.Address),
5758
blockCtx: blkCtx,
5859
timestamped: timestamped,
60+
muted: muted,
5961
}
6062
}
6163

@@ -93,6 +95,7 @@ func (eh *eventHandler) HandleStakedEvent(event *abiutil.EventParam) error {
9395
UnlockedAt: maxStakingNumber,
9496
UnstakedAt: maxStakingNumber,
9597
Timestamped: eh.timestamped,
98+
Muted: eh.muted,
9699
}
97100
eh.putBucket(tokenIDParam.Uint64(), bucket)
98101
return nil
@@ -114,6 +117,7 @@ func (eh *eventHandler) HandleLockedEvent(event *abiutil.EventParam) error {
114117
}
115118
bkt.StakedDuration = durationParam.Uint64()
116119
bkt.UnlockedAt = maxStakingNumber
120+
bkt.Muted = eh.muted
117121
eh.putBucket(tokenIDParam.Uint64(), bkt)
118122
return nil
119123
}
@@ -227,6 +231,7 @@ func (eh *eventHandler) HandleMergedEvent(event *abiutil.EventParam) error {
227231
b.StakedAmount = amountParam
228232
b.StakedDuration = durationParam.Uint64()
229233
b.UnlockedAt = maxStakingNumber
234+
b.Muted = eh.muted
230235
for i := 1; i < len(tokenIDsParam); i++ {
231236
eh.delBucket(tokenIDsParam[i].Uint64())
232237
}
@@ -254,6 +259,7 @@ func (eh *eventHandler) HandleBucketExpandedEvent(event *abiutil.EventParam) err
254259
}
255260
b.StakedAmount = amountParam
256261
b.StakedDuration = durationParam.Uint64()
262+
b.Muted = eh.muted
257263
eh.putBucket(tokenIDParam.Uint64(), b)
258264
return nil
259265
}
@@ -273,6 +279,7 @@ func (eh *eventHandler) HandleDonatedEvent(event *abiutil.EventParam) error {
273279
return errors.Wrapf(ErrBucketNotExist, "token id %d", tokenIDParam.Uint64())
274280
}
275281
b.StakedAmount.Sub(b.StakedAmount, amountParam)
282+
b.Muted = eh.muted
276283
eh.putBucket(tokenIDParam.Uint64(), b)
277284
return nil
278285
}

systemcontractindex/stakingindex/index.go

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -270,30 +270,32 @@ func (s *Indexer) PutBlock(ctx context.Context, blk *block.Block) error {
270270
return nil
271271
}
272272
// handle events of block
273-
var handler stakingEventHandler
274-
eventHandler := newEventHandler(s.bucketNS, s.cache.Copy(), protocol.MustGetBlockCtx(ctx), s.timestamped)
275-
if s.muteHeight > 0 && blk.Height() >= s.muteHeight {
276-
handler = newEventMuteHandler(eventHandler)
277-
} else {
278-
handler = eventHandler
279-
}
273+
muted := s.muteHeight > 0 && blk.Height() >= s.muteHeight
274+
handler := newEventHandler(s.bucketNS, s.cache.Copy(), protocol.MustGetBlockCtx(ctx), s.timestamped, muted)
280275
for _, receipt := range blk.Receipts {
281-
if receipt.Status != uint64(iotextypes.ReceiptStatus_Success) {
282-
continue
283-
}
284-
for _, log := range receipt.Logs() {
285-
if log.Address != s.common.ContractAddress() {
286-
continue
287-
}
288-
if err := s.handleEvent(ctx, handler, log); err != nil {
289-
return err
290-
}
276+
if err := s.handleReceipt(ctx, handler, receipt); err != nil {
277+
return errors.Wrapf(err, "handle receipt %x failed", receipt.ActionHash)
291278
}
292279
}
293280
// commit
294281
return s.commit(handler, blk.Height())
295282
}
296283

284+
func (s *Indexer) handleReceipt(ctx context.Context, eh stakingEventHandler, receipt *action.Receipt) error {
285+
if receipt.Status != uint64(iotextypes.ReceiptStatus_Success) {
286+
return nil
287+
}
288+
for _, log := range receipt.Logs() {
289+
if log.Address != s.common.ContractAddress() {
290+
continue
291+
}
292+
if err := s.handleEvent(ctx, eh, log); err != nil {
293+
return err
294+
}
295+
}
296+
return nil
297+
}
298+
297299
func (s *Indexer) handleEvent(ctx context.Context, eh stakingEventHandler, actLog *action.Log) error {
298300
// get event abi
299301
abiEvent, err := StakingContractABI.EventByID(common.Hash(actLog.Topics[0]))

systemcontractindex/stakingindex/mute_handler.go

Lines changed: 0 additions & 59 deletions
This file was deleted.

systemcontractindex/stakingindex/stakeview.go

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import (
44
"context"
55

66
"github.com/iotexproject/iotex-address/address"
7+
78
"github.com/iotexproject/iotex-core/v2/action"
89
"github.com/iotexproject/iotex-core/v2/action/protocol"
910
"github.com/iotexproject/iotex-core/v2/action/protocol/staking"
10-
"github.com/iotexproject/iotex-proto/golang/iotextypes"
1111
)
1212

1313
type stakeView struct {
@@ -47,23 +47,7 @@ func (s *stakeView) CreatePreStates(ctx context.Context) error {
4747

4848
func (s *stakeView) Handle(ctx context.Context, receipt *action.Receipt) error {
4949
blkCtx := protocol.MustGetBlockCtx(ctx)
50-
var handler stakingEventHandler
51-
eventHandler := newEventHandler(s.helper.bucketNS, s.cache, blkCtx, s.helper.timestamped)
52-
if s.helper.muteHeight > 0 && blkCtx.BlockHeight >= s.helper.muteHeight {
53-
handler = newEventMuteHandler(eventHandler)
54-
} else {
55-
handler = eventHandler
56-
}
57-
if receipt.Status != uint64(iotextypes.ReceiptStatus_Success) {
58-
return nil
59-
}
60-
for _, log := range receipt.Logs() {
61-
if log.Address != s.helper.common.ContractAddress() {
62-
continue
63-
}
64-
if err := s.helper.handleEvent(ctx, handler, log); err != nil {
65-
return err
66-
}
67-
}
68-
return nil
50+
muted := s.helper.muteHeight > 0 && blkCtx.BlockHeight >= s.helper.muteHeight
51+
handler := newEventHandler(s.helper.bucketNS, s.cache, blkCtx, s.helper.timestamped, muted)
52+
return s.helper.handleReceipt(ctx, handler, receipt)
6953
}

0 commit comments

Comments
 (0)