Skip to content

Commit 15e7a44

Browse files
authored
Merge branch 'master' into forkchain
2 parents 8372b72 + a04b48c commit 15e7a44

25 files changed

+2192
-125
lines changed

action/protocol/context.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ type (
153153
UnstakedButNotClearSelfStakeAmount bool
154154
CheckStakingDurationUpperLimit bool
155155
FixRevertSnapshot bool
156+
TimestampedStakingContract bool
156157
}
157158

158159
// FeatureWithHeightCtx provides feature check functions.
@@ -311,6 +312,7 @@ func WithFeatureCtx(ctx context.Context) context.Context {
311312
UnstakedButNotClearSelfStakeAmount: !g.IsVanuatu(height),
312313
CheckStakingDurationUpperLimit: g.IsVanuatu(height),
313314
FixRevertSnapshot: g.IsVanuatu(height),
315+
TimestampedStakingContract: g.IsToBeEnabled(height),
314316
},
315317
)
316318
}

action/protocol/staking/handler_stake_migrate.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package staking
88
import (
99
"context"
1010
"math/big"
11+
"time"
1112

1213
"github.com/ethereum/go-ethereum/common"
1314
"github.com/pkg/errors"
@@ -50,8 +51,7 @@ func (p *Protocol) handleStakeMigrate(ctx context.Context, elp action.Envelope,
5051
if candidate == nil {
5152
return nil, nil, gasConsumed, gasToBeDeducted, errCandNotExist
5253
}
53-
duration := uint64(bucket.StakedDuration / p.helperCtx.BlockInterval(protocol.MustGetBlockCtx(ctx).BlockHeight))
54-
exec, err := p.constructExecution(candidate.GetIdentifier(), bucket.StakedAmount, duration, elp.Nonce(), elp.Gas(), elp.GasPrice())
54+
exec, err := p.constructExecution(ctx, candidate.GetIdentifier(), bucket.StakedAmount, bucket.StakedDuration, elp.Nonce(), elp.Gas(), elp.GasPrice())
5555
if err != nil {
5656
return nil, nil, gasConsumed, gasToBeDeducted, errors.Wrap(err, "failed to construct execution")
5757
}
@@ -179,13 +179,16 @@ func (p *Protocol) ConstructExecution(ctx context.Context, act *action.MigrateSt
179179
if candidate == nil {
180180
return nil, errCandNotExist
181181
}
182-
duration := uint64(bucket.StakedDuration / p.helperCtx.BlockInterval(protocol.MustGetBlockCtx(ctx).BlockHeight))
183-
184-
return p.constructExecution(candidate.GetIdentifier(), bucket.StakedAmount, duration, nonce, gas, gasPrice)
182+
return p.constructExecution(ctx, candidate.GetIdentifier(), bucket.StakedAmount, bucket.StakedDuration, nonce, gas, gasPrice)
185183
}
186184

187-
func (p *Protocol) constructExecution(candidate address.Address, amount *big.Int, duration uint64, nonce uint64, gasLimit uint64, gasPrice *big.Int) (action.Envelope, error) {
188-
contractAddress := p.config.MigrateContractAddress
185+
func (p *Protocol) constructExecution(ctx context.Context, candidate address.Address, amount *big.Int, durationTime time.Duration, nonce uint64, gasLimit uint64, gasPrice *big.Int) (action.Envelope, error) {
186+
contractAddress := p.config.TimestampedMigrateContractAddress
187+
duration := uint64(durationTime.Seconds())
188+
if !protocol.MustGetFeatureCtx(ctx).TimestampedStakingContract {
189+
contractAddress = p.config.MigrateContractAddress
190+
duration = uint64(durationTime / p.helperCtx.BlockInterval(protocol.MustGetBlockCtx(ctx).BlockHeight))
191+
}
189192
data, err := StakingContractABI.Pack(
190193
"stake0",
191194
big.NewInt(int64(duration)),

action/protocol/staking/protocol.go

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,30 +81,43 @@ type (
8181
candBucketsIndexer *CandidatesBucketsIndexer
8282
contractStakingIndexer ContractStakingIndexerWithBucketType
8383
contractStakingIndexerV2 ContractStakingIndexer
84+
contractStakingIndexerV3 ContractStakingIndexer
8485
voteReviser *VoteReviser
8586
patch *PatchStore
8687
helperCtx HelperCtx
8788
}
8889

8990
// Configuration is the staking protocol configuration.
9091
Configuration struct {
91-
VoteWeightCalConsts genesis.VoteWeightCalConsts
92-
RegistrationConsts RegistrationConsts
93-
WithdrawWaitingPeriod time.Duration
94-
MinStakeAmount *big.Int
95-
BootstrapCandidates []genesis.BootstrapCandidate
96-
PersistStakingPatchBlock uint64
97-
FixAliasForNonStopHeight uint64
98-
EndorsementWithdrawWaitingBlocks uint64
99-
MigrateContractAddress string
92+
VoteWeightCalConsts genesis.VoteWeightCalConsts
93+
RegistrationConsts RegistrationConsts
94+
WithdrawWaitingPeriod time.Duration
95+
MinStakeAmount *big.Int
96+
BootstrapCandidates []genesis.BootstrapCandidate
97+
PersistStakingPatchBlock uint64
98+
FixAliasForNonStopHeight uint64
99+
EndorsementWithdrawWaitingBlocks uint64
100+
MigrateContractAddress string
101+
TimestampedMigrateContractAddress string
100102
}
101103
// HelperCtx is the helper context for staking protocol
102104
HelperCtx struct {
103105
BlockInterval func(uint64) time.Duration
104106
DepositGas protocol.DepositGas
105107
}
108+
// Option is the option to create a protocol
109+
Option func(*Protocol)
106110
)
107111

112+
// WithContractStakingIndexerV3 sets the contract staking indexer v3
113+
func WithContractStakingIndexerV3(indexer ContractStakingIndexer) Option {
114+
return func(p *Protocol) {
115+
p.contractStakingIndexerV3 = indexer
116+
p.config.TimestampedMigrateContractAddress = indexer.ContractAddress()
117+
return
118+
}
119+
}
120+
108121
// FindProtocol return a registered protocol from registry
109122
func FindProtocol(registry *protocol.Registry) *Protocol {
110123
if registry == nil {
@@ -128,6 +141,7 @@ func NewProtocol(
128141
candBucketsIndexer *CandidatesBucketsIndexer,
129142
contractStakingIndexer ContractStakingIndexerWithBucketType,
130143
contractStakingIndexerV2 ContractStakingIndexer,
144+
opts ...Option,
131145
) (*Protocol, error) {
132146
h := hash.Hash160b([]byte(_protocolID))
133147
addr, err := address.FromBytes(h[:])
@@ -156,7 +170,7 @@ func NewProtocol(
156170
if contractStakingIndexerV2 != nil {
157171
migrateContractAddress = contractStakingIndexerV2.ContractAddress()
158172
}
159-
return &Protocol{
173+
p := &Protocol{
160174
addr: addr,
161175
config: Configuration{
162176
VoteWeightCalConsts: cfg.Staking.VoteWeightCalConsts,
@@ -178,7 +192,11 @@ func NewProtocol(
178192
contractStakingIndexer: contractStakingIndexer,
179193
helperCtx: helperCtx,
180194
contractStakingIndexerV2: contractStakingIndexerV2,
181-
}, nil
195+
}
196+
for _, opt := range opts {
197+
opt(p)
198+
}
199+
return p, nil
182200
}
183201

184202
// ProtocolAddr returns the address generated from protocol id
@@ -600,6 +618,9 @@ func (p *Protocol) ReadState(ctx context.Context, sr protocol.StateReader, metho
600618
if p.contractStakingIndexerV2 != nil {
601619
indexers = append(indexers, NewDelayTolerantIndexer(p.contractStakingIndexerV2, time.Second))
602620
}
621+
if p.contractStakingIndexerV3 != nil {
622+
indexers = append(indexers, NewDelayTolerantIndexer(p.contractStakingIndexerV3, time.Second))
623+
}
603624
stakeSR, err := newCompositeStakingStateReader(p.candBucketsIndexer, sr, p.calculateVoteWeight, indexers...)
604625
if err != nil {
605626
return nil, 0, err
@@ -771,6 +792,9 @@ func (p *Protocol) contractStakingVotes(ctx context.Context, candidate address.A
771792
if p.contractStakingIndexerV2 != nil && !featureCtx.LimitedStakingContract {
772793
indexers = append(indexers, p.contractStakingIndexerV2)
773794
}
795+
if p.contractStakingIndexerV3 != nil && featureCtx.TimestampedStakingContract {
796+
indexers = append(indexers, p.contractStakingIndexerV3)
797+
}
774798
for _, indexer := range indexers {
775799
btks, err := indexer.BucketsByCandidate(candidate, height)
776800
if err != nil {

action/protocol/staking/vote_bucket.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ type (
4444
CreateBlockHeight uint64
4545
StakeStartBlockHeight uint64
4646
UnstakeStartBlockHeight uint64
47+
Timestamped bool
4748
}
4849

4950
// totalBucketCount stores the total bucket count
@@ -186,7 +187,7 @@ func (vb *VoteBucket) Serialize() ([]byte, error) {
186187
}
187188

188189
func (vb *VoteBucket) isUnstaked() bool {
189-
if vb.isNative() {
190+
if vb.isNative() || vb.Timestamped {
190191
return vb.UnstakeStartTime.After(vb.StakeStartTime)
191192
}
192193
return vb.UnstakeStartBlockHeight < maxBlockNumber

actpool/actpool.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ func (ap *actPool) ReceiveBlock(*block.Block) error {
248248
return nil
249249
}
250250

251-
// PendingActionMap returns an action interator with all accepted actions
251+
// PendingActionMap returns an action iterator with all accepted actions
252252
func (ap *actPool) PendingActionMap() map[string][]*action.SealedEnvelope {
253253
var (
254254
wg sync.WaitGroup

api/coreservice.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1633,6 +1633,7 @@ func (core *coreService) EstimateMigrateStakeGasConsumption(ctx context.Context,
16331633
BaseFee: protocol.CalcBaseFee(g.Blockchain, &tip),
16341634
ExcessBlobGas: protocol.CalcExcessBlobGas(header.ExcessBlobGas(), header.BlobGasUsed()),
16351635
})
1636+
ctx = protocol.WithFeatureCtx(ctx)
16361637
exec, err := staking.FindProtocol(core.registry).ConstructExecution(ctx, ms, 0, 0, new(big.Int), core.sf)
16371638
if err != nil {
16381639
return 0, nil, err

blockchain/genesis/genesis.go

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,18 @@ func defaultConfig() Genesis {
121121
SystemStakingContractHeight: 24486464,
122122
SystemStakingContractV2Address: "io13mjjr5shj4mte39axwsqjp8fdggk0qzjhatprp", // https://iotexscan.io/tx/b838b7a7c95e511fd8b256c5cbafde0547a72215d682eb60668d1b475a1beb70
123123
SystemStakingContractV2Height: 30934838,
124-
NativeStakingContractAddress: "io1xpq62aw85uqzrccg9y5hnryv8ld2nkpycc3gza",
125-
VoteThreshold: "100000000000000000000",
126-
StakingContractAddress: "0x87c9dbff0016af23f5b1ab9b8e072124ab729193",
127-
SelfStakingThreshold: "1200000000000000000000000",
128-
ScoreThreshold: "2000000000000000000000000",
129-
RegisterContractAddress: "0x95724986563028deb58f15c5fac19fa09304f32d",
130-
GravityChainStartHeight: 7614500,
131-
GravityChainHeightInterval: 100,
132-
Delegates: []Delegate{},
124+
// TODO: update the address and height after the v3 contract is deployed
125+
SystemStakingContractV3Address: "",
126+
SystemStakingContractV3Height: 90934838,
127+
NativeStakingContractAddress: "io1xpq62aw85uqzrccg9y5hnryv8ld2nkpycc3gza",
128+
VoteThreshold: "100000000000000000000",
129+
StakingContractAddress: "0x87c9dbff0016af23f5b1ab9b8e072124ab729193",
130+
SelfStakingThreshold: "1200000000000000000000000",
131+
ScoreThreshold: "2000000000000000000000000",
132+
RegisterContractAddress: "0x95724986563028deb58f15c5fac19fa09304f32d",
133+
GravityChainStartHeight: 7614500,
134+
GravityChainHeightInterval: 100,
135+
Delegates: []Delegate{},
133136
},
134137
Rewarding: Rewarding{
135138
InitBalanceStr: unit.ConvertIotxToRau(200000000).String(),
@@ -411,6 +414,10 @@ type (
411414
SystemStakingContractV2Address string `yaml:"systemStakingContractV2Address"`
412415
// SystemStakingContractV2Height is the height of system staking contract
413416
SystemStakingContractV2Height uint64 `yaml:"systemStakingContractV2Height"`
417+
// SystemStakingContractV3Address is the address of system staking contract
418+
SystemStakingContractV3Address string `yaml:"systemStakingContractV3Address"`
419+
// SystemStakingContractV3Height is the height of system staking contract
420+
SystemStakingContractV3Height uint64 `yaml:"systemStakingContractV3Height"`
414421
}
415422
// Delegate defines a delegate with address and votes
416423
Delegate struct {

chainservice/builder.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,9 @@ func (builder *Builder) buildBlockDAO(forTest bool) error {
296296
if builder.cs.contractStakingIndexerV2 != nil {
297297
synchronizedIndexers = append(synchronizedIndexers, builder.cs.contractStakingIndexerV2)
298298
}
299+
if builder.cs.contractStakingIndexerV3 != nil {
300+
synchronizedIndexers = append(synchronizedIndexers, builder.cs.contractStakingIndexerV3)
301+
}
299302
if len(synchronizedIndexers) > 1 {
300303
indexers = append(indexers, blockindex.NewSyncIndexers(synchronizedIndexers...))
301304
} else {
@@ -359,6 +362,7 @@ func (builder *Builder) buildContractStakingIndexer(forTest bool) error {
359362
if forTest {
360363
builder.cs.contractStakingIndexer = nil
361364
builder.cs.contractStakingIndexerV2 = nil
365+
builder.cs.contractStakingIndexerV3 = nil
362366
return nil
363367
}
364368
dbConfig := builder.cfg.DB
@@ -396,7 +400,18 @@ func (builder *Builder) buildContractStakingIndexer(forTest bool) error {
396400
)
397401
builder.cs.contractStakingIndexerV2 = indexer
398402
}
399-
403+
// build contract staking indexer v3
404+
if builder.cs.contractStakingIndexerV3 == nil && len(builder.cfg.Genesis.SystemStakingContractV3Address) > 0 {
405+
indexer := stakingindex.NewIndexer(
406+
kvstore,
407+
builder.cfg.Genesis.SystemStakingContractV3Address,
408+
builder.cfg.Genesis.SystemStakingContractV3Height, func(start uint64, end uint64) time.Duration {
409+
return time.Duration(end-start) * blockInterval
410+
},
411+
stakingindex.EnableTimestamped(),
412+
)
413+
builder.cs.contractStakingIndexerV3 = indexer
414+
}
400415
return nil
401416
}
402417

@@ -668,6 +683,10 @@ func (builder *Builder) registerStakingProtocol() error {
668683
return nil
669684
}
670685
consensusCfg := consensusfsm.NewConsensusConfig(builder.cfg.Consensus.RollDPoS.FSM, builder.cfg.DardanellesUpgrade, builder.cfg.Genesis, builder.cfg.Consensus.RollDPoS.Delay)
686+
opts := []staking.Option{}
687+
if builder.cs.contractStakingIndexerV3 != nil {
688+
opts = append(opts, staking.WithContractStakingIndexerV3(builder.cs.contractStakingIndexerV3))
689+
}
671690
stakingProtocol, err := staking.NewProtocol(
672691
staking.HelperCtx{
673692
DepositGas: rewarding.DepositGas,
@@ -689,6 +708,7 @@ func (builder *Builder) registerStakingProtocol() error {
689708
builder.cs.candBucketsIndexer,
690709
builder.cs.contractStakingIndexer,
691710
builder.cs.contractStakingIndexerV2,
711+
opts...,
692712
)
693713
if err != nil {
694714
return err

chainservice/chainservice.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ type ChainService struct {
7373
candBucketsIndexer *staking.CandidatesBucketsIndexer
7474
contractStakingIndexer *contractstaking.Indexer
7575
contractStakingIndexerV2 stakingindex.StakingIndexer
76+
contractStakingIndexerV3 stakingindex.StakingIndexer
7677
registry *protocol.Registry
7778
nodeInfoManager *nodeinfo.InfoManager
7879
apiStats *nodestats.APILocalStats

0 commit comments

Comments
 (0)