make the upgrade schedule fully configurable
This should help with testing.
This commit is contained in:
parent
3d91633699
commit
1cc0f74744
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
@ -33,17 +34,27 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/vm"
|
"github.com/filecoin-project/lotus/chain/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ForksAtHeight = map[abi.ChainEpoch]func(context.Context, *StateManager, ExecCallback, cid.Cid, *types.TipSet) (cid.Cid, error){
|
type UpgradeFunc func(context.Context, *StateManager, ExecCallback, cid.Cid, *types.TipSet) (cid.Cid, error)
|
||||||
build.UpgradeBreezeHeight: UpgradeFaucetBurnRecovery,
|
|
||||||
build.UpgradeIgnitionHeight: UpgradeIgnition,
|
type Upgrade struct {
|
||||||
build.UpgradeActorsV2Height: UpgradeActorsV2,
|
Height abi.ChainEpoch
|
||||||
build.UpgradeLiftoffHeight: UpgradeLiftoff,
|
Migration UpgradeFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpgradeSchedule map[network.Version]Upgrade
|
||||||
|
|
||||||
|
var DefaultUpgradeSchedule = UpgradeSchedule{
|
||||||
|
network.Version1: {build.UpgradeBreezeHeight, UpgradeFaucetBurnRecovery},
|
||||||
|
network.Version2: {build.UpgradeSmokeHeight, nil},
|
||||||
|
network.Version3: {build.UpgradeIgnitionHeight, UpgradeIgnition},
|
||||||
|
network.Version4: {build.UpgradeActorsV2Height, UpgradeActorsV2},
|
||||||
|
network.Version5: {build.UpgradeLiftoffHeight, UpgradeLiftoff},
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) handleStateForks(ctx context.Context, root cid.Cid, height abi.ChainEpoch, cb ExecCallback, ts *types.TipSet) (cid.Cid, error) {
|
func (sm *StateManager) handleStateForks(ctx context.Context, root cid.Cid, height abi.ChainEpoch, cb ExecCallback, ts *types.TipSet) (cid.Cid, error) {
|
||||||
retCid := root
|
retCid := root
|
||||||
var err error
|
var err error
|
||||||
f, ok := ForksAtHeight[height]
|
f, ok := sm.stateMigrations[height]
|
||||||
if ok {
|
if ok {
|
||||||
retCid, err = f(ctx, sm, cb, root, ts)
|
retCid, err = f(ctx, sm, cb, root, ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -19,7 +19,6 @@ import (
|
|||||||
lotusinit "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
lotusinit "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||||
"github.com/filecoin-project/lotus/chain/gen"
|
"github.com/filecoin-project/lotus/chain/gen"
|
||||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
|
||||||
. "github.com/filecoin-project/lotus/chain/stmgr"
|
. "github.com/filecoin-project/lotus/chain/stmgr"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/chain/vm"
|
"github.com/filecoin-project/lotus/chain/vm"
|
||||||
@ -110,51 +109,54 @@ func TestForkHeightTriggers(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sm := NewStateManager(cg.ChainStore())
|
|
||||||
|
|
||||||
inv := vm.NewActorRegistry()
|
|
||||||
|
|
||||||
// predicting the address here... may break if other assumptions change
|
// predicting the address here... may break if other assumptions change
|
||||||
taddr, err := address.NewIDAddress(1002)
|
taddr, err := address.NewIDAddress(1002)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
stmgr.ForksAtHeight[testForkHeight] = func(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) {
|
sm := NewStateManager(cg.ChainStore(),
|
||||||
cst := ipldcbor.NewCborStore(sm.ChainStore().Blockstore())
|
WithUpgradeSchedule(UpgradeSchedule{
|
||||||
|
1: {Height: testForkHeight, Migration: func(ctx context.Context, sm *StateManager, cb ExecCallback,
|
||||||
|
root cid.Cid, ts *types.TipSet) (cid.Cid, error) {
|
||||||
|
cst := ipldcbor.NewCborStore(sm.ChainStore().Blockstore())
|
||||||
|
|
||||||
st, err := sm.StateTree(root)
|
st, err := sm.StateTree(root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("getting state tree: %w", err)
|
return cid.Undef, xerrors.Errorf("getting state tree: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
act, err := st.GetActor(taddr)
|
act, err := st.GetActor(taddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tas testActorState
|
var tas testActorState
|
||||||
if err := cst.Get(ctx, act.Head, &tas); err != nil {
|
if err := cst.Get(ctx, act.Head, &tas); err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("in fork handler, failed to run get: %w", err)
|
return cid.Undef, xerrors.Errorf("in fork handler, failed to run get: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tas.HasUpgraded = 55
|
tas.HasUpgraded = 55
|
||||||
|
|
||||||
ns, err := cst.Put(ctx, &tas)
|
ns, err := cst.Put(ctx, &tas)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
act.Head = ns
|
act.Head = ns
|
||||||
|
|
||||||
if err := st.SetActor(taddr, act); err != nil {
|
if err := st.SetActor(taddr, act); err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return st.Flush(ctx)
|
return st.Flush(ctx)
|
||||||
}
|
}},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
inv := vm.NewActorRegistry()
|
||||||
inv.Register(nil, testActor{})
|
inv.Register(nil, testActor{})
|
||||||
|
|
||||||
sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (*vm.VM, error) {
|
sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (*vm.VM, error) {
|
||||||
nvm, err := vm.NewVM(ctx, vmopt)
|
nvm, err := vm.NewVM(ctx, vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
23
chain/stmgr/options.go
Normal file
23
chain/stmgr/options.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package stmgr
|
||||||
|
|
||||||
|
type Option func(*config)
|
||||||
|
|
||||||
|
type config struct {
|
||||||
|
upgradeSchedule UpgradeSchedule
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseOptions(opts ...Option) *config {
|
||||||
|
cfg := &config{
|
||||||
|
upgradeSchedule: DefaultUpgradeSchedule,
|
||||||
|
}
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(cfg)
|
||||||
|
}
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithUpgradeSchedule(schedule UpgradeSchedule) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.upgradeSchedule = schedule
|
||||||
|
}
|
||||||
|
}
|
@ -42,6 +42,12 @@ var log = logging.Logger("statemgr")
|
|||||||
type StateManager struct {
|
type StateManager struct {
|
||||||
cs *store.ChainStore
|
cs *store.ChainStore
|
||||||
|
|
||||||
|
// Sorted network upgrade epochs (starting at version 1).
|
||||||
|
// -1 means the version is skipped.
|
||||||
|
networkVersions []abi.ChainEpoch
|
||||||
|
// Maps chain epochs to upgrade functions.
|
||||||
|
stateMigrations map[abi.ChainEpoch]UpgradeFunc
|
||||||
|
|
||||||
stCache map[string][]cid.Cid
|
stCache map[string][]cid.Cid
|
||||||
compWait map[string]chan struct{}
|
compWait map[string]chan struct{}
|
||||||
stlk sync.Mutex
|
stlk sync.Mutex
|
||||||
@ -51,12 +57,36 @@ type StateManager struct {
|
|||||||
postIgnitionGenInfos *genesisInfo
|
postIgnitionGenInfos *genesisInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStateManager(cs *store.ChainStore) *StateManager {
|
func NewStateManager(cs *store.ChainStore, options ...Option) *StateManager {
|
||||||
|
cfg := parseOptions(options...)
|
||||||
|
stateMigrations := make(map[abi.ChainEpoch]UpgradeFunc, len(cfg.upgradeSchedule))
|
||||||
|
networkVersions := make([]abi.ChainEpoch, 0, len(stateMigrations))
|
||||||
|
|
||||||
|
// Iterate version by version, to make sure we handle skipped version numbers.
|
||||||
|
// Always skip version 0.
|
||||||
|
for i, version := 0, network.Version(1); i < len(cfg.upgradeSchedule); version++ {
|
||||||
|
upgrade, ok := cfg.upgradeSchedule[version]
|
||||||
|
if ok {
|
||||||
|
// We've processed an upgrade.
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
epoch := abi.ChainEpoch(-1)
|
||||||
|
if ok && upgrade.Height >= 0 {
|
||||||
|
epoch = upgrade.Height
|
||||||
|
stateMigrations[epoch] = upgrade.Migration
|
||||||
|
}
|
||||||
|
|
||||||
|
networkVersions = append(networkVersions, epoch)
|
||||||
|
}
|
||||||
|
|
||||||
return &StateManager{
|
return &StateManager{
|
||||||
newVM: vm.NewVM,
|
networkVersions: networkVersions,
|
||||||
cs: cs,
|
stateMigrations: stateMigrations,
|
||||||
stCache: make(map[string][]cid.Cid),
|
newVM: vm.NewVM,
|
||||||
compWait: make(map[string]chan struct{}),
|
cs: cs,
|
||||||
|
stCache: make(map[string][]cid.Cid),
|
||||||
|
compWait: make(map[string]chan struct{}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1259,29 +1289,12 @@ func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.Cha
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) network.Version {
|
func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) network.Version {
|
||||||
// TODO: move hard fork epoch checks to a schedule defined in build/
|
for v, epoch := range sm.networkVersions {
|
||||||
|
if epoch >= 0 && height <= epoch {
|
||||||
if build.UseNewestNetwork() {
|
return network.Version(v + 1) // we've skipped version 0
|
||||||
return build.NewestNetworkVersion
|
}
|
||||||
}
|
}
|
||||||
|
return network.Version(len(sm.networkVersions))
|
||||||
if height <= build.UpgradeBreezeHeight {
|
|
||||||
return network.Version0
|
|
||||||
}
|
|
||||||
|
|
||||||
if height <= build.UpgradeSmokeHeight {
|
|
||||||
return network.Version1
|
|
||||||
}
|
|
||||||
|
|
||||||
if height <= build.UpgradeIgnitionHeight {
|
|
||||||
return network.Version2
|
|
||||||
}
|
|
||||||
|
|
||||||
if height <= build.UpgradeActorsV2Height {
|
|
||||||
return network.Version3
|
|
||||||
}
|
|
||||||
|
|
||||||
return build.NewestNetworkVersion
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) GetPaychState(ctx context.Context, addr address.Address, ts *types.TipSet) (*types.Actor, paych.State, error) {
|
func (sm *StateManager) GetPaychState(ctx context.Context, addr address.Address, ts *types.TipSet) (*types.Actor, paych.State, error) {
|
||||||
|
2
go.mod
2
go.mod
@ -33,7 +33,7 @@ require (
|
|||||||
github.com/filecoin-project/go-multistore v0.0.3
|
github.com/filecoin-project/go-multistore v0.0.3
|
||||||
github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20
|
github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20
|
||||||
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261
|
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261
|
||||||
github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab
|
github.com/filecoin-project/go-state-types v0.0.0-20201001162932-93a412d8e9fa
|
||||||
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe
|
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe
|
||||||
github.com/filecoin-project/go-statestore v0.1.0
|
github.com/filecoin-project/go-statestore v0.1.0
|
||||||
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b
|
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b
|
||||||
|
2
go.sum
2
go.sum
@ -263,6 +263,8 @@ github.com/filecoin-project/go-state-types v0.0.0-20200904021452-1883f36ca2f4/go
|
|||||||
github.com/filecoin-project/go-state-types v0.0.0-20200905071437-95828685f9df/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I=
|
github.com/filecoin-project/go-state-types v0.0.0-20200905071437-95828685f9df/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I=
|
||||||
github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab h1:cEDC5Ei8UuT99hPWhCjA72SM9AuRtnpvdSTIYbnzN8I=
|
github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab h1:cEDC5Ei8UuT99hPWhCjA72SM9AuRtnpvdSTIYbnzN8I=
|
||||||
github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g=
|
github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g=
|
||||||
|
github.com/filecoin-project/go-state-types v0.0.0-20201001162932-93a412d8e9fa h1:WVxLrmc6w5naeX3QikfRvc1G7EFfBZbhXuzM8Lj2J+o=
|
||||||
|
github.com/filecoin-project/go-state-types v0.0.0-20201001162932-93a412d8e9fa/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g=
|
||||||
github.com/filecoin-project/go-statemachine v0.0.0-20200714194326-a77c3ae20989/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
|
github.com/filecoin-project/go-statemachine v0.0.0-20200714194326-a77c3ae20989/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
|
||||||
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe h1:dF8u+LEWeIcTcfUcCf3WFVlc81Fr2JKg8zPzIbBDKDw=
|
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe h1:dF8u+LEWeIcTcfUcCf3WFVlc81Fr2JKg8zPzIbBDKDw=
|
||||||
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
|
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
|
||||||
|
Loading…
Reference in New Issue
Block a user