Skip to content
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

[contractstaking]fix vote bug when change delegate #3888

Merged
merged 17 commits into from
Jun 19, 2023
Merged
58 changes: 23 additions & 35 deletions blockindex/contractstaking/delta_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,14 @@ func TestContractStakingDelta_BucketInfoDelta(t *testing.T) {

// add bucket info
bi := &bucketInfo{TypeIndex: 1, CreatedAt: 1, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(1), Owner: identityset.Address(2)}
cache.AddBucketInfo(1, bi)
require.NoError(cache.AddBucketInfo(1, bi))

// modify bucket info
bi = &bucketInfo{TypeIndex: 2, CreatedAt: 2, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(3), Owner: identityset.Address(4)}
cache.UpdateBucketInfo(2, bi)
require.NoError(cache.UpdateBucketInfo(2, bi))

// remove bucket info
cache.DeleteBucketInfo(3)

// add and remove bucket info
bi = &bucketInfo{TypeIndex: 4, CreatedAt: 3, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(5), Owner: identityset.Address(6)}
cache.AddBucketInfo(4, bi)
cache.DeleteBucketInfo(4)
require.NoError(cache.DeleteBucketInfo(3))

// get bucket info delta
delta := cache.BucketInfoDelta()
Expand Down Expand Up @@ -73,12 +68,12 @@ func TestContractStakingDelta_BucketTypeDelta(t *testing.T) {
cache := newContractStakingDelta()

// add bucket type
cache.AddBucketType(1, &BucketType{Amount: big.NewInt(100), Duration: 100, ActivatedAt: 1})
cache.AddBucketType(2, &BucketType{Amount: big.NewInt(200), Duration: 100, ActivatedAt: 1})
require.NoError(cache.AddBucketType(1, &BucketType{Amount: big.NewInt(100), Duration: 100, ActivatedAt: 1}))
require.NoError(cache.AddBucketType(2, &BucketType{Amount: big.NewInt(200), Duration: 100, ActivatedAt: 1}))

// modify bucket type 1 & 3
cache.UpdateBucketType(1, &BucketType{Amount: big.NewInt(100), Duration: 100, ActivatedAt: 3})
cache.UpdateBucketType(3, &BucketType{Amount: big.NewInt(100), Duration: 100, ActivatedAt: 4})
require.NoError(cache.UpdateBucketType(1, &BucketType{Amount: big.NewInt(100), Duration: 100, ActivatedAt: 3}))
require.NoError(cache.UpdateBucketType(3, &BucketType{Amount: big.NewInt(100), Duration: 100, ActivatedAt: 4}))

delta := cache.BucketTypeDelta()
// check added bucket type
Expand Down Expand Up @@ -112,8 +107,8 @@ func TestContractStakingDelta_MatchBucketType(t *testing.T) {
require.Nil(bucketType)

// add bucket types
cache.AddBucketType(1, &BucketType{Amount: big.NewInt(100), Duration: 100, ActivatedAt: 1})
cache.AddBucketType(2, &BucketType{Amount: big.NewInt(200), Duration: 100, ActivatedAt: 1})
require.NoError(cache.AddBucketType(1, &BucketType{Amount: big.NewInt(100), Duration: 100, ActivatedAt: 1}))
require.NoError(cache.AddBucketType(2, &BucketType{Amount: big.NewInt(200), Duration: 100, ActivatedAt: 1}))

// test with amount and duration that match bucket type 1
amount := big.NewInt(100)
Expand Down Expand Up @@ -154,7 +149,7 @@ func TestContractStakingDelta_GetBucketInfo(t *testing.T) {

// add bucket info
bi := &bucketInfo{TypeIndex: 1, CreatedAt: 1, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(1), Owner: identityset.Address(2)}
cache.AddBucketInfo(1, bi)
require.NoError(cache.AddBucketInfo(1, bi))

// get added bucket info
info, state := cache.GetBucketInfo(1)
Expand All @@ -167,16 +162,9 @@ func TestContractStakingDelta_GetBucketInfo(t *testing.T) {
require.EqualValues(identityset.Address(2), info.Owner)
require.EqualValues(deltaStateAdded, state)

// revert bucket info 1
cache.DeleteBucketInfo(1)
// get bucket info
info, state = cache.GetBucketInfo(1)
require.Nil(info)
require.EqualValues(deltaStateUnchanged, state)

// modify bucket info 2
bi = &bucketInfo{TypeIndex: 2, CreatedAt: 2, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(3), Owner: identityset.Address(4)}
cache.UpdateBucketInfo(2, bi)
require.NoError(cache.UpdateBucketInfo(2, bi))
// get modified bucket info
info, state = cache.GetBucketInfo(2)
require.NotNil(info)
Expand All @@ -189,7 +177,7 @@ func TestContractStakingDelta_GetBucketInfo(t *testing.T) {
require.EqualValues(deltaStateModified, state)

// remove bucket info 2
cache.DeleteBucketInfo(2)
require.NoError(cache.DeleteBucketInfo(2))
// get removed bucket info
info, state = cache.GetBucketInfo(2)
require.Nil(info)
Expand All @@ -204,7 +192,7 @@ func TestContractStakingDelta_GetBucketType(t *testing.T) {

// add bucket type
bt := &BucketType{Amount: big.NewInt(100), Duration: 100, ActivatedAt: 1}
cache.AddBucketType(1, bt)
require.NoError(cache.AddBucketType(1, bt))

// get added bucket type
bucketType, state := cache.GetBucketType(1)
Expand All @@ -216,7 +204,7 @@ func TestContractStakingDelta_GetBucketType(t *testing.T) {

// modify bucket type
bt = &BucketType{Amount: big.NewInt(200), Duration: 200, ActivatedAt: 2}
cache.UpdateBucketType(2, bt)
require.NoError(cache.UpdateBucketType(2, bt))
// get modified bucket type
bucketType, state = cache.GetBucketType(2)
require.NotNil(bucketType)
Expand All @@ -238,26 +226,26 @@ func TestContractStakingDelta_AddedBucketCnt(t *testing.T) {
require.EqualValues(0, addedBucketCnt)

// add bucket types
cache.AddBucketType(1, &BucketType{Amount: big.NewInt(100), Duration: 100, ActivatedAt: 1})
cache.AddBucketType(2, &BucketType{Amount: big.NewInt(200), Duration: 100, ActivatedAt: 1})
require.NoError(cache.AddBucketType(1, &BucketType{Amount: big.NewInt(100), Duration: 100, ActivatedAt: 1}))
require.NoError(cache.AddBucketType(2, &BucketType{Amount: big.NewInt(200), Duration: 100, ActivatedAt: 1}))

// add bucket info
bi := &bucketInfo{TypeIndex: 1, CreatedAt: 1, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(1), Owner: identityset.Address(2)}
cache.AddBucketInfo(1, bi)
require.NoError(cache.AddBucketInfo(1, bi))
// add bucket info
bi = &bucketInfo{TypeIndex: 2, CreatedAt: 1, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(1), Owner: identityset.Address(2)}
cache.AddBucketInfo(2, bi)
require.NoError(cache.AddBucketInfo(2, bi))

// test with added bucket info
addedBucketCnt = cache.AddedBucketCnt()
require.EqualValues(2, addedBucketCnt)

// remove bucket info
cache.DeleteBucketInfo(2)
require.NoError(cache.DeleteBucketInfo(3))

// test with removed bucket info
addedBucketCnt = cache.AddedBucketCnt()
require.EqualValues(1, addedBucketCnt)
require.EqualValues(2, addedBucketCnt)
}

func TestContractStakingDelta_AddedBucketTypeCnt(t *testing.T) {
Expand All @@ -271,9 +259,9 @@ func TestContractStakingDelta_AddedBucketTypeCnt(t *testing.T) {
require.EqualValues(0, addedBucketTypeCnt)

// add bucket types
cache.AddBucketType(1, &BucketType{Amount: big.NewInt(100), Duration: 100, ActivatedAt: 1})
cache.AddBucketType(2, &BucketType{Amount: big.NewInt(200), Duration: 100, ActivatedAt: 1})
cache.AddBucketType(3, &BucketType{Amount: big.NewInt(300), Duration: 100, ActivatedAt: 1})
require.NoError(cache.AddBucketType(1, &BucketType{Amount: big.NewInt(100), Duration: 100, ActivatedAt: 1}))
require.NoError(cache.AddBucketType(2, &BucketType{Amount: big.NewInt(200), Duration: 100, ActivatedAt: 1}))
require.NoError(cache.AddBucketType(3, &BucketType{Amount: big.NewInt(300), Duration: 100, ActivatedAt: 1}))

// test with added bucket type
addedBucketTypeCnt = cache.AddedBucketTypeCnt()
Expand Down
46 changes: 46 additions & 0 deletions blockindex/contractstaking/delta_state_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package contractstaking

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestDeltaState_Transfer(t *testing.T) {
require := require.New(t)

cases := []struct {
name string
state deltaState
action deltaAction
expected deltaState
isError bool
dustinxie marked this conversation as resolved.
Show resolved Hide resolved
}{
{"unchanged->add", deltaStateUnchanged, deltaActionAdd, deltaStateAdded, false},
{"unchanged->remove", deltaStateUnchanged, deltaActionRemove, deltaStateRemoved, false},
{"unchanged->modify", deltaStateUnchanged, deltaActionModify, deltaStateModified, false},
{"added->add", deltaStateAdded, deltaActionAdd, deltaStateUnchanged, true},
{"added->remove", deltaStateAdded, deltaActionRemove, deltaStateUnchanged, true},
{"added->modify", deltaStateAdded, deltaActionModify, deltaStateAdded, false},
{"removed->add", deltaStateRemoved, deltaActionAdd, deltaStateUnchanged, true},
{"removed->remove", deltaStateRemoved, deltaActionRemove, deltaStateUnchanged, true},
{"removed->modify", deltaStateRemoved, deltaActionModify, deltaStateUnchanged, true},
{"modified->add", deltaStateModified, deltaActionAdd, deltaStateUnchanged, true},
{"modified->remove", deltaStateModified, deltaActionRemove, deltaStateRemoved, false},
{"modified->modify", deltaStateModified, deltaActionModify, deltaStateModified, false},
{"invalid state", deltaState(100), deltaActionAdd, deltaState(100), true},
{"invalid action", deltaStateUnchanged, deltaAction(100), deltaStateUnchanged, true},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
s, err := c.state.Transfer(c.action)
if c.isError {
require.Error(err)
} else {
require.NoError(err)
require.Equal(c.expected, s)
}
})
}
}
35 changes: 14 additions & 21 deletions blockindex/contractstaking/dirty_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ func TestContractStakingDirty_getBucketInfo(t *testing.T) {
require.Equal(identityset.Address(2), bi.Owner)

// added bucket info
dirty.addBucketType(2, &BucketType{Amount: big.NewInt(200), Duration: 200, ActivatedAt: 2})
dirty.addBucketInfo(2, &bucketInfo{TypeIndex: 2, CreatedAt: 2, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(2), Owner: identityset.Address(3)})
require.NoError(dirty.addBucketType(2, &BucketType{Amount: big.NewInt(200), Duration: 200, ActivatedAt: 2}))
require.NoError(dirty.addBucketInfo(2, &bucketInfo{TypeIndex: 2, CreatedAt: 2, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(2), Owner: identityset.Address(3)}))
bi, ok = dirty.getBucketInfo(2)
require.True(ok)
require.EqualValues(2, bi.TypeIndex)
Expand All @@ -73,7 +73,7 @@ func TestContractStakingDirty_getBucketInfo(t *testing.T) {
require.Equal(identityset.Address(3), bi.Owner)

// modified bucket info
dirty.updateBucketInfo(1, &bucketInfo{TypeIndex: 2, CreatedAt: 3, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(3), Owner: identityset.Address(4)})
require.NoError(dirty.updateBucketInfo(1, &bucketInfo{TypeIndex: 2, CreatedAt: 3, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(3), Owner: identityset.Address(4)}))
bi, ok = dirty.getBucketInfo(1)
require.True(ok)
require.EqualValues(2, bi.TypeIndex)
Expand All @@ -84,7 +84,7 @@ func TestContractStakingDirty_getBucketInfo(t *testing.T) {
require.Equal(identityset.Address(4), bi.Owner)

// removed bucket info
dirty.deleteBucketInfo(1)
require.NoError(dirty.deleteBucketInfo(1))
bi, ok = dirty.getBucketInfo(1)
require.False(ok)
require.Nil(bi)
Expand All @@ -111,7 +111,7 @@ func TestContractStakingDirty_matchBucketType(t *testing.T) {
require.EqualValues(1, id)

// added bucket type
dirty.addBucketType(2, &BucketType{Amount: big.NewInt(200), Duration: 200, ActivatedAt: 2})
require.NoError(dirty.addBucketType(2, &BucketType{Amount: big.NewInt(200), Duration: 200, ActivatedAt: 2}))
id, bt, ok = dirty.matchBucketType(big.NewInt(200), 200)
require.True(ok)
require.EqualValues(200, bt.Amount.Int64())
Expand All @@ -135,7 +135,7 @@ func TestContractStakingDirty_getBucketTypeCount(t *testing.T) {
require.EqualValues(1, count)

// added bucket type
dirty.addBucketType(2, &BucketType{Amount: big.NewInt(200), Duration: 200, ActivatedAt: 2})
require.NoError(dirty.addBucketType(2, &BucketType{Amount: big.NewInt(200), Duration: 200, ActivatedAt: 2}))
count = dirty.getBucketTypeCount()
require.EqualValues(2, count)
}
Expand Down Expand Up @@ -163,7 +163,7 @@ func TestContractStakingDirty_finalize(t *testing.T) {

// added bucket type
bt := &BucketType{Amount: big.NewInt(100), Duration: 100, ActivatedAt: 1}
dirty.addBucketType(1, bt)
require.NoError(dirty.addBucketType(1, bt))
batcher, delta = dirty.finalize()
require.EqualValues(2, batcher.Size())
info, err = batcher.Entry(1)
Expand All @@ -181,7 +181,7 @@ func TestContractStakingDirty_finalize(t *testing.T) {

// add bucket info
bi := &bucketInfo{TypeIndex: 1, CreatedAt: 2, UnlockedAt: 3, UnstakedAt: 4, Delegate: identityset.Address(1), Owner: identityset.Address(2)}
dirty.addBucketInfo(1, bi)
require.NoError(dirty.addBucketInfo(1, bi))
batcher, delta = dirty.finalize()
require.EqualValues(3, batcher.Size())
info, err = batcher.Entry(2)
Expand All @@ -208,35 +208,28 @@ func TestContractStakingDirty_noSideEffectOnClean(t *testing.T) {
dirty := newContractStakingDirty(clean)

// add bucket type to dirty cache
dirty.addBucketType(1, &BucketType{Amount: big.NewInt(100), Duration: 100, ActivatedAt: 1})
require.NoError(dirty.addBucketType(1, &BucketType{Amount: big.NewInt(100), Duration: 100, ActivatedAt: 1}))
// check that clean cache is not affected
bt, ok := clean.getBucketType(1)
require.False(ok)
require.Nil(bt)

// add bucket info to dirty cache
dirty.addBucketInfo(1, &bucketInfo{TypeIndex: 1, CreatedAt: 1, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(1), Owner: identityset.Address(2)})
require.NoError(dirty.addBucketInfo(1, &bucketInfo{TypeIndex: 1, CreatedAt: 1, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(1), Owner: identityset.Address(2)}))
// check that clean cache is not affected
bi, ok := clean.getBucketInfo(1)
require.False(ok)
require.Nil(bi)

// update bucket type in dirty cache
dirty.updateBucketType(1, &BucketType{Amount: big.NewInt(200), Duration: 200, ActivatedAt: 2})
require.NoError(dirty.updateBucketType(1, &BucketType{Amount: big.NewInt(200), Duration: 200, ActivatedAt: 2}))
// check that clean cache is not affected
bt, ok = clean.getBucketType(1)
require.False(ok)
require.Nil(bt)

// update bucket info in dirty cache
dirty.updateBucketInfo(1, &bucketInfo{TypeIndex: 2, CreatedAt: 3, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(3), Owner: identityset.Address(4)})
// check that clean cache is not affected
bi, ok = clean.getBucketInfo(1)
require.False(ok)
require.Nil(bi)

// remove bucket info from dirty cache
dirty.deleteBucketInfo(1)
require.NoError(dirty.updateBucketInfo(1, &bucketInfo{TypeIndex: 2, CreatedAt: 3, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(3), Owner: identityset.Address(4)}))
// check that clean cache is not affected
bi, ok = clean.getBucketInfo(1)
require.False(ok)
Expand All @@ -245,7 +238,7 @@ func TestContractStakingDirty_noSideEffectOnClean(t *testing.T) {
// update bucket info existed in clean cache
clean.PutBucketInfo(2, &bucketInfo{TypeIndex: 1, CreatedAt: 1, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(1), Owner: identityset.Address(2)})
// update bucket info in dirty cache
dirty.updateBucketInfo(2, &bucketInfo{TypeIndex: 1, CreatedAt: 3, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(3), Owner: identityset.Address(4)})
require.NoError(dirty.updateBucketInfo(2, &bucketInfo{TypeIndex: 1, CreatedAt: 3, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(3), Owner: identityset.Address(4)}))
// check that clean cache is not affected
bi, ok = clean.getBucketInfo(2)
require.True(ok)
Expand All @@ -259,7 +252,7 @@ func TestContractStakingDirty_noSideEffectOnClean(t *testing.T) {
// remove bucket info existed in clean cache
clean.PutBucketInfo(3, &bucketInfo{TypeIndex: 1, CreatedAt: 1, UnlockedAt: maxBlockNumber, UnstakedAt: maxBlockNumber, Delegate: identityset.Address(1), Owner: identityset.Address(2)})
// remove bucket info from dirty cache
dirty.deleteBucketInfo(3)
require.NoError(dirty.deleteBucketInfo(3))
// check that clean cache is not affected
bi, ok = clean.getBucketInfo(3)
require.True(ok)
Expand Down