Skip to content
This repository has been archived by the owner on Jun 12, 2024. It is now read-only.

Commit

Permalink
execute all future coin reward events at 2280000 (#453)
Browse files Browse the repository at this point in the history
* execute all future coin reward events at 1930000

* set update height to 2280000
  • Loading branch information
Stumble authored Feb 3, 2020
1 parent 1cf8ec4 commit 9a805f7
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 0 deletions.
3 changes: 3 additions & 0 deletions types/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ const (
// Migration
Upgrade5Update2 = 1670000

// Execute future unstake events once.
Upgrade5Update3 = 2280000

// TxSigLimit - max number of sigs in one transaction
// XXX(yumin): This will actually limit the number of msg per tx to at most 2.
TxSigLimit = 2
Expand Down
57 changes: 57 additions & 0 deletions x/global/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/lino-network/lino/utils"
"github.com/lino-network/lino/x/global/model"
"github.com/lino-network/lino/x/global/types"

accmn "github.com/lino-network/lino/x/account/manager"
)

const (
Expand Down Expand Up @@ -163,6 +165,61 @@ func (gm GlobalManager) ExecuteEvents(ctx sdk.Context, exec linotypes.EventExec)
}
gm.storage.RemoveTimeEventList(ctx, i)
}

// upgrade-3 unlock all.
if ctx.BlockHeight() == linotypes.Upgrade5Update3 {
gm.execFutureEvents(ctx, exec, func(ts int64, event linotypes.Event) bool {
if ts < currentTime {
return false
}
switch event.(type) {
case accmn.ReturnCoinEvent:
return true
default:
return false
}
})
}
}

// resolveFutureEvents does not return err. Events are executed in an isolated env,
// so it's fine to ignore errors but leave them in the store.
func (gm GlobalManager) execFutureEvents(
ctx sdk.Context, exec linotypes.EventExec,
filter func(ts int64, event linotypes.Event) bool) {
eventLists := make(map[int64]*linotypes.TimeEventList)
store := gm.storage.PartialStoreMap(ctx)
// change store will invalidate the iterator, so copy first.
store[string(model.TimeEventListSubStore)].Iterate(func(key []byte, val interface{}) bool {
ts, err := strconv.ParseInt(string(key), 10, 64)
if err != nil {
return false
}
eventLists[ts] = val.(*linotypes.TimeEventList)
return false
})

for ts, eventList := range eventLists {
if eventList == nil {
continue
}
left := linotypes.TimeEventList{}
for _, event := range eventList.Events {
if filter(ts, event) {
err := gm.runEventIsolated(ctx, exec, event)
if err != nil {
left.Events = append(left.Events, event)
}
} else {
left.Events = append(left.Events, event)
}
}
if len(left.Events) == 0 {
gm.storage.RemoveTimeEventList(ctx, ts)
} else {
gm.storage.SetTimeEventList(ctx, ts, &left)
}
}
}

// GetLastBlockTime - get last block time from KVStore
Expand Down
90 changes: 90 additions & 0 deletions x/global/manager/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,19 @@ type testEvent struct {
Id int64 `json:"id"`
}

type testBadEvent struct {
Id int64 `json:"id"`
}

type testIgnoredEvent struct {
Id int64 `json:"id"`
}

func regTestCodec(c *wire.Codec) {
c.RegisterInterface((*linotypes.Event)(nil), nil)
c.RegisterConcrete(testEvent{}, "lino/testevent", nil)
c.RegisterConcrete(testBadEvent{}, "lino/testbadevent", nil)
c.RegisterConcrete(testIgnoredEvent{}, "lino/testignoredevent", nil)
}

func testCodec() *wire.Codec {
Expand Down Expand Up @@ -239,6 +249,86 @@ func (suite *globalManagerTestSuite) TestEventErrIsolation() {
suite.Golden()
}

func (suite *globalManagerTestSuite) TestExecFutureEvents() {
suite.NextBlock(time.Unix(0, 0))
suite.global.InitGenesis(suite.Ctx)

init := int64(123456)
t0 := init - 1
t1 := init + 1
t2 := init + 30

id := int64(0)
for _, t := range []int64{t0, t1, t2} {
err := suite.global.RegisterEventAtTime(suite.Ctx, t, testEvent{Id: id})
suite.Nil(err)
err = suite.global.RegisterEventAtTime(suite.Ctx, t, testEvent{Id: id})
suite.Nil(err)
err = suite.global.RegisterEventAtTime(suite.Ctx, t, testBadEvent{Id: id})
suite.Nil(err)
err = suite.global.RegisterEventAtTime(suite.Ctx, t, testIgnoredEvent{Id: id})
suite.Nil(err)

}

suite.NextBlock(time.Unix(init, 0))

count := 0
filter := func(ts int64, event linotypes.Event) bool {
if ts < init {
return false
}
switch event.(type) {
case testEvent, testBadEvent:
return true
default:
return false
}
}
suite.global.execFutureEvents(suite.Ctx,
func(ctx sdk.Context, event linotypes.Event) sdk.Error {
switch event.(type) {
case testEvent:
count++
return nil
case testBadEvent:
return linotypes.ErrTestDummyError()
default:
suite.FailNow("executing events that should be ignored")
return nil
}
},
filter,
)
suite.Equal(4, count)

// bad is no longer bad.
suite.global.execFutureEvents(suite.Ctx,
func(ctx sdk.Context, event linotypes.Event) sdk.Error {
switch event.(type) {
case testEvent, testBadEvent:
count++
return nil
default:
suite.FailNow("executing events that should be ignored")
return nil
}
},
filter,
)
suite.Equal(6, count)

// ignored is not ignored.
suite.global.execFutureEvents(suite.Ctx,
func(ctx sdk.Context, event linotypes.Event) sdk.Error {
count++
return nil
},
func(ts int64, event linotypes.Event) bool { return ts > init },
)
suite.Equal(8, count)
}

func (suite *globalManagerTestSuite) TestImportExport() {
init := int64(123456)
suite.NextBlock(time.Unix(init, 0))
Expand Down

0 comments on commit 9a805f7

Please sign in to comment.