Skip to content

Redefine view #4668

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Aug 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions action/protocol/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ type (
DepositGas func(context.Context, StateManager, *big.Int, ...DepositOption) ([]*action.TransactionLog, error)

View interface {
Clone() View
Fork() View
Snapshot() int
Revert(int) error
Commit(context.Context, StateReader) error
Expand All @@ -130,12 +130,12 @@ func NewViews() *Views {
}
}

func (views *Views) Clone() *Views {
clone := NewViews()
func (views *Views) Fork() *Views {
fork := NewViews()
for key, view := range views.vm {
clone.vm[key] = view.Clone()
fork.vm[key] = view.Fork()
}
return clone
return fork
}

func (views *Views) Commit(ctx context.Context, sr StateReader) error {
Expand Down
1 change: 0 additions & 1 deletion action/protocol/staking/bucket_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ func TestBucketPool(t *testing.T) {
}

view, _, err := CreateBaseView(sm, false)
view.contractsStake = &contractStakeView{}
r.NoError(err)
r.NoError(sm.WriteView(_protocolID, view))
pool = view.bucketPool
Expand Down
43 changes: 37 additions & 6 deletions action/protocol/staking/candidate_center.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
package staking

import (
"context"
"sync"

"github.com/iotexproject/iotex-address/address"

"github.com/iotexproject/iotex-core/v2/action"
"github.com/iotexproject/iotex-core/v2/action/protocol"
)

type (
Expand Down Expand Up @@ -69,7 +71,7 @@ func NewCandidateCenter(all CandidateList) (*CandidateCenter, error) {
return &c, nil
}

if err := c.Commit(); err != nil {
if err := c.commit(); err != nil {
return nil, err
}
return &c, nil
Expand Down Expand Up @@ -112,8 +114,7 @@ func (m CandidateCenter) Base() *CandidateCenter {
}
}

// Commit writes the change into base
func (m *CandidateCenter) Commit() error {
func (m *CandidateCenter) commit() error {
size, err := m.base.commit(m.change, false)
if err != nil {
return err
Expand All @@ -124,8 +125,20 @@ func (m *CandidateCenter) Commit() error {
return nil
}

// LegacyCommit writes the change into base with legacy logic
func (m *CandidateCenter) LegacyCommit() error {
// Commit writes the change into base
func (m *CandidateCenter) Commit(ctx context.Context, sr protocol.StateReader) error {
height, err := sr.Height()
if err != nil {
return err
}
if featureWithHeightCtx, ok := protocol.GetFeatureWithHeightCtx(ctx); ok && featureWithHeightCtx.CandCenterHasAlias(height) {
return m.legacyCommit()
}
return m.commit()
}

// legacyCommit writes the change into base with legacy logic
func (m *CandidateCenter) legacyCommit() error {
size, err := m.base.commit(m.change, true)
if err != nil {
return err
Expand Down Expand Up @@ -270,10 +283,28 @@ func (m *CandidateCenter) Upsert(d *Candidate) error {
if _, hit := m.base.getByIdentifier(d.GetIdentifier().String()); !hit {
m.size++
}
// fmt.Printf("upsert done %+v\n", d)
return nil
}

// WriteToStateDB writes the candidate center to stateDB
func (m *CandidateCenter) WriteToStateDB(sm protocol.StateManager) error {
// persist nameMap/operatorMap and ownerList to stateDB
name := m.base.candsInNameMap()
op := m.base.candsInOperatorMap()
owners := m.base.ownersList()
if len(name) == 0 || len(op) == 0 {
return ErrNilParameters
}
if _, err := sm.PutState(name, protocol.NamespaceOption(CandsMapNS), protocol.KeyOption(_nameKey)); err != nil {
return err
}
if _, err := sm.PutState(op, protocol.NamespaceOption(CandsMapNS), protocol.KeyOption(_operatorKey)); err != nil {
return err
}
_, err := sm.PutState(owners, protocol.NamespaceOption(CandsMapNS), protocol.KeyOption(_ownerKey))
return err
}

func (m *CandidateCenter) collision(d *Candidate) error {
if err := m.change.collision(d); err != nil {
return err
Expand Down
26 changes: 13 additions & 13 deletions action/protocol/staking/candidate_center_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ func testEqualAllCommit(r *require.Assertions, m *CandidateCenter, old Candidate
r.True(testEqual(m, list))

// test commit
r.NoError(m.LegacyCommit())
r.NoError(m.LegacyCommit()) // commit is idempotent
r.NoError(m.legacyCommit())
r.NoError(m.legacyCommit()) // commit is idempotent
r.Equal(size+increase, m.Size())
// m equal to current list, not equal to old
r.True(testEqual(m, list))
Expand Down Expand Up @@ -95,7 +95,7 @@ func TestCandCenter(t *testing.T) {
r.Equal(len(testCandidates), m.Size())

// test export changes and commit
r.NoError(m.LegacyCommit())
r.NoError(m.legacyCommit())
r.Equal(len(testCandidates), m.Size())
old := m.All()
r.True(testEqual(m, old))
Expand Down Expand Up @@ -197,7 +197,7 @@ func TestCandCenter(t *testing.T) {

r.Equal(len(list), m.Size())
r.True(testEqual(m, list))
r.NoError(m.LegacyCommit())
r.NoError(m.legacyCommit())
r.Equal(len(list), m.Size())
r.True(testEqual(m, list))

Expand Down Expand Up @@ -321,9 +321,9 @@ func TestFixAlias(t *testing.T) {
r.Equal(v.d, m.GetByName(v.d.Name))
}
if hasAlias {
r.NoError(m.LegacyCommit())
r.NoError(m.legacyCommit())
} else {
r.NoError(m.Commit())
r.NoError(m.commit())
}
views.Write(_protocolID, &ViewData{
candCenter: m,
Expand Down Expand Up @@ -372,9 +372,9 @@ func TestFixAlias(t *testing.T) {
// cand center Commit()
{
if hasAlias {
r.NoError(center.LegacyCommit())
r.NoError(center.legacyCommit())
} else {
r.NoError(center.Commit())
r.NoError(center.commit())
}
views.Write(_protocolID, &ViewData{
candCenter: center,
Expand Down Expand Up @@ -472,7 +472,7 @@ func TestMultipleNonStakingCandidate(t *testing.T) {
checkCandidates := func(candcenter *CandidateCenter, cands []*Candidate) {
r.True(testEqual(candcenter, CandidateList(cands)))
// commit
r.NoError(candcenter.Commit())
r.NoError(candcenter.commit())
r.True(testEqual(candcenter, CandidateList(cands)))
// from state manager
views := protocol.NewViews()
Expand Down Expand Up @@ -561,7 +561,7 @@ func TestCandidateUpsert(t *testing.T) {
r.Equal(len(tests), m.Size())

// test export changes and commit
r.NoError(m.LegacyCommit())
r.NoError(m.legacyCommit())
r.Equal(len(tests), m.Size())
old := m.All()
r.True(testEqual(m, old))
Expand Down Expand Up @@ -594,7 +594,7 @@ func TestCandidateUpsert(t *testing.T) {
})
t.Run("upsert the same candidate", func(t *testing.T) {
r.NoError(m.Upsert(tests[0]))
r.NoError(m.Commit())
r.NoError(m.commit())
r.Equal(len(tests), m.Size())
testEqual(m, old)
})
Expand All @@ -608,7 +608,7 @@ func TestCandidateUpsert(t *testing.T) {
ownerChange := tests[0].Clone()
ownerChange.Owner = identityset.Address(28)
r.NoError(m.Upsert(ownerChange))
r.NoError(m.Commit())
r.NoError(m.commit())
r.Equal(ownerChange, m.GetByName(ownerChange.Name))
r.Equal(ownerChange, m.GetByOwner(ownerChange.Owner))
r.Equal(ownerChange, m.GetBySelfStakingIndex(ownerChange.SelfStakeBucketIdx))
Expand Down Expand Up @@ -640,7 +640,7 @@ func TestCandidateUpsert(t *testing.T) {
cand.Identifier = identityset.Address2(100)
cand.Owner = identityset.Address2(104)
r.NoError(m.Upsert(cand))
r.NoError(m.Commit())
r.NoError(m.commit())
r.Equal(len(tests)+1, m.Size())
r.Equal(cand, m.GetByIdentifier(cand.GetIdentifier()))
})
Expand Down
5 changes: 2 additions & 3 deletions action/protocol/staking/candidate_statereader.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,8 @@ func CreateBaseView(sr protocol.StateReader, enableSMStorage bool) (*ViewData, u
}

return &ViewData{
candCenter: center,
bucketPool: pool,
contractsStake: &contractStakeView{},
candCenter: center,
bucketPool: pool,
}, height, nil
}

Expand Down
19 changes: 6 additions & 13 deletions action/protocol/staking/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -483,21 +483,11 @@ func (p *Protocol) PreCommit(ctx context.Context, sm protocol.StateManager) erro
if !vd.IsDirty() {
return nil
}
vd = vd.Clone().(*ViewData)
if err := vd.Commit(ctx, sm); err != nil {
clone := vd.candCenter.Clone()
if err := clone.Commit(ctx, sm); err != nil {
return err
}
// persist nameMap/operatorMap and ownerList to stateDB
name := vd.candCenter.base.candsInNameMap()
op := vd.candCenter.base.candsInOperatorMap()
owners := vd.candCenter.base.ownersList()
if len(name) == 0 || len(op) == 0 {
return ErrNilParameters
}
if err := writeCandCenterStateToStateDB(sm, name, op, owners); err != nil {
return errors.Wrap(err, "failed to write name/operator map to stateDB")
}
return nil
return clone.WriteToStateDB(sm)
}

// Commit commits the last change
Expand Down Expand Up @@ -695,6 +685,9 @@ func (p *Protocol) ActiveCandidates(ctx context.Context, sr protocol.StateReader
var csVotes *big.Int
if protocol.MustGetFeatureCtx(ctx).CreatePostActionStates {
csVotes, err = p.contractStakingVotesFromView(ctx, list[i].GetIdentifier(), c.BaseView())
if err != nil {
return nil, err
}
} else {
// specifying the height param instead of query latest from indexer directly, aims to cause error when indexer falls behind.
// the reason of using srHeight-1 is contract indexer is not updated before the block is committed.
Expand Down
Loading