diff --git a/.circleci/config.yml b/.circleci/config.yml index 79b445459..9bdac8762 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -829,6 +829,11 @@ workflows: suite: itest-migration_nv17 target: "./itests/migration_nv17_test.go" + - test: + name: test-itest-migration_nv18 + suite: itest-migration_nv18 + target: "./itests/migration_nv18_test.go" + - test: name: test-itest-mpool_msg_uuid suite: itest-mpool_msg_uuid diff --git a/api/types.go b/api/types.go index 5cbe0edef..e67903436 100644 --- a/api/types.go +++ b/api/types.go @@ -338,6 +338,7 @@ type ForkUpgradeParams struct { UpgradeOhSnapHeight abi.ChainEpoch UpgradeSkyrHeight abi.ChainEpoch UpgradeSharkHeight abi.ChainEpoch + UpgradeHyggeHeight abi.ChainEpoch } type NonceMapType map[address.Address]uint64 diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index c3b955b3d..0f3947499 100644 Binary files a/build/openrpc/full.json.gz and b/build/openrpc/full.json.gz differ diff --git a/build/params_2k.go b/build/params_2k.go index cdcaaa832..081007dd1 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -59,6 +59,8 @@ var UpgradeSkyrHeight = abi.ChainEpoch(-19) var UpgradeSharkHeight = abi.ChainEpoch(-20) +var UpgradeHyggeHeight = abi.ChainEpoch(-21) + var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, } @@ -111,6 +113,7 @@ func init() { UpgradeOhSnapHeight = getUpgradeHeight("LOTUS_OHSNAP_HEIGHT", UpgradeOhSnapHeight) UpgradeSkyrHeight = getUpgradeHeight("LOTUS_SKYR_HEIGHT", UpgradeSkyrHeight) UpgradeSharkHeight = getUpgradeHeight("LOTUS_SHARK_HEIGHT", UpgradeSharkHeight) + UpgradeHyggeHeight = getUpgradeHeight("LOTUS_HYGGE_HEIGHT", UpgradeHyggeHeight) BuildType |= Build2k diff --git a/build/params_butterfly.go b/build/params_butterfly.go index ffd5b043b..7cd02bce9 100644 --- a/build/params_butterfly.go +++ b/build/params_butterfly.go @@ -50,7 +50,8 @@ const UpgradeHyperdriveHeight = -16 const UpgradeChocolateHeight = -17 const UpgradeOhSnapHeight = -18 const UpgradeSkyrHeight = -19 -const UpgradeSharkHeight = abi.ChainEpoch(600) +const UpgradeSharkHeight = abi.ChainEpoch(-20) +const UpgradeHyggeHeight = abi.ChainEpoch(600) var SupportedProofTypes = []abi.RegisteredSealProof{ abi.RegisteredSealProof_StackedDrg512MiBV1, diff --git a/build/params_calibnet.go b/build/params_calibnet.go index 52e2d2ecc..0661bb839 100644 --- a/build/params_calibnet.go +++ b/build/params_calibnet.go @@ -4,6 +4,7 @@ package build import ( + "math" "os" "strconv" @@ -70,6 +71,8 @@ const UpgradeSkyrHeight = 510 const UpgradeSharkHeight = 16800 // 6 days after genesis +const UpgradeHyggeHeight = math.MaxInt64 + var SupportedProofTypes = []abi.RegisteredSealProof{ abi.RegisteredSealProof_StackedDrg32GiBV1, abi.RegisteredSealProof_StackedDrg64GiBV1, diff --git a/build/params_interop.go b/build/params_interop.go index 94da3464a..4d94de049 100644 --- a/build/params_interop.go +++ b/build/params_interop.go @@ -50,7 +50,9 @@ var UpgradeChocolateHeight = abi.ChainEpoch(-17) var UpgradeOhSnapHeight = abi.ChainEpoch(-18) var UpgradeSkyrHeight = abi.ChainEpoch(-19) -const UpgradeSharkHeight = abi.ChainEpoch(99999999999999) +const UpgradeSharkHeight = abi.ChainEpoch(-20) + +const UpgradeHyggeHeight = abi.ChainEpoch(99999999999999) var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, @@ -105,6 +107,7 @@ func init() { UpgradeOhSnapHeight = getUpgradeHeight("LOTUS_OHSNAP_HEIGHT", UpgradeOhSnapHeight) UpgradeSkyrHeight = getUpgradeHeight("LOTUS_SKYR_HEIGHT", UpgradeSkyrHeight) UpgradeSharkHeight = getUpgradeHeight("LOTUS_SHARK_HEIGHT", UpgradeSharkHeight) + UpgradeHyggeHeight = getUpgradeHeight("LOTUS_HYGGE_HEIGHT", UpgradeHyggeHeight) BuildType |= BuildInteropnet SetAddressNetwork(address.Testnet) diff --git a/build/params_mainnet.go b/build/params_mainnet.go index f5c395e24..c65c5d19a 100644 --- a/build/params_mainnet.go +++ b/build/params_mainnet.go @@ -59,6 +59,7 @@ const UpgradePersianHeight = UpgradeCalicoHeight + (builtin2.EpochsInHour * 60) const UpgradeOrangeHeight = 336458 // 2020-12-22T02:00:00Z +// var because of wdpost_test.go var UpgradeClausHeight = abi.ChainEpoch(343200) // 2021-03-04T00:00:30Z @@ -83,7 +84,10 @@ const UpgradeOhSnapHeight = 1594680 const UpgradeSkyrHeight = 1960320 // 2022-11-30T14:00:00Z -var UpgradeSharkHeight = abi.ChainEpoch(2383680) +const UpgradeSharkHeight = 2383680 + +// ?????????????? +var UpgradeHyggeHeight = abi.ChainEpoch(math.MaxInt64) var SupportedProofTypes = []abi.RegisteredSealProof{ abi.RegisteredSealProof_StackedDrg32GiBV1, @@ -98,8 +102,8 @@ func init() { SetAddressNetwork(address.Mainnet) } - if os.Getenv("LOTUS_DISABLE_SHARK") == "1" { - UpgradeSharkHeight = math.MaxInt64 + if os.Getenv("LOTUS_DISABLE_HYGGE") == "1" { + UpgradeHyggeHeight = math.MaxInt64 } // NOTE: DO NOT change this unless you REALLY know what you're doing. This is not consensus critical, however, diff --git a/build/params_testground.go b/build/params_testground.go index 6cf87bee2..ed818f4a5 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -108,6 +108,7 @@ var ( UpgradeOhSnapHeight abi.ChainEpoch = -17 UpgradeSkyrHeight abi.ChainEpoch = -18 UpgradeSharkHeight abi.ChainEpoch = -19 + UpgradeHyggeHeight abi.ChainEpoch = -20 DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, diff --git a/build/params_wallaby.go b/build/params_wallaby.go index 916111d72..98231672b 100644 --- a/build/params_wallaby.go +++ b/build/params_wallaby.go @@ -53,6 +53,7 @@ var UpgradeChocolateHeight = abi.ChainEpoch(-17) var UpgradeOhSnapHeight = abi.ChainEpoch(-18) var UpgradeSkyrHeight = abi.ChainEpoch(-19) var UpgradeSharkHeight = abi.ChainEpoch(-20) +var UpgradeHyggeHeight = abi.ChainEpoch(-21) var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, diff --git a/chain/consensus/filcns/upgrades.go b/chain/consensus/filcns/upgrades.go index 83c560aa4..5a268c8a6 100644 --- a/chain/consensus/filcns/upgrades.go +++ b/chain/consensus/filcns/upgrades.go @@ -18,8 +18,10 @@ import ( "github.com/filecoin-project/go-state-types/abi" actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" + nv18 "github.com/filecoin-project/go-state-types/builtin/v10/migration" nv17 "github.com/filecoin-project/go-state-types/builtin/v9/migration" "github.com/filecoin-project/go-state-types/manifest" + "github.com/filecoin-project/go-state-types/migration" "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/go-state-types/rt" gstStore "github.com/filecoin-project/go-state-types/store" @@ -232,8 +234,18 @@ func DefaultUpgradeSchedule() stmgr.UpgradeSchedule { StopWithin: 5, }}, Expensive: true, + }, { + Height: build.UpgradeHyggeHeight, + Network: network.Version18, + Migration: UpgradeActorsV10, + PreMigrations: []stmgr.PreMigration{{ + PreMigration: PreUpgradeActorsV10, + StartWithin: 180, + DontStartWithin: 60, + StopWithin: 5, + }}, + Expensive: true, }, - // TODO v10 upgrade } for _, u := range updates { @@ -1580,12 +1592,110 @@ func upgradeActorsV9Common( func UpgradeActorsV10(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, cb stmgr.ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { + // Use all the CPUs except 3. + workerCount := MigrationMaxWorkerCount - 3 + if workerCount <= 0 { + workerCount = 1 + } - // TODO migration - // - state tree migration to v5; must set predictable addresses for all account actors - // - create EAM actor - // - create ETH address 0x00..., defined by spec. - return cid.Undef, fmt.Errorf("IMPLEMENTME: v10 migration") + config := migration.Config{ + MaxWorkers: uint(workerCount), + JobQueueSize: 1000, + ResultQueueSize: 100, + ProgressLogPeriod: 10 * time.Second, + } + + newRoot, err := upgradeActorsV10Common(ctx, sm, cache, root, epoch, ts, config) + if err != nil { + return cid.Undef, xerrors.Errorf("migrating actors v10 state: %w", err) + } + + return newRoot, nil +} + +func PreUpgradeActorsV10(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) error { + // Use half the CPUs for pre-migration, but leave at least 3. + workerCount := MigrationMaxWorkerCount + if workerCount <= 4 { + workerCount = 1 + } else { + workerCount /= 2 + } + + lbts, lbRoot, err := stmgr.GetLookbackTipSetForRound(ctx, sm, ts, epoch) + if err != nil { + return xerrors.Errorf("error getting lookback ts for premigration: %w", err) + } + + config := migration.Config{ + MaxWorkers: uint(workerCount), + ProgressLogPeriod: time.Minute * 5, + } + + _, err = upgradeActorsV10Common(ctx, sm, cache, lbRoot, epoch, lbts, config) + return err +} + +func upgradeActorsV10Common( + ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, + root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet, + config migration.Config, +) (cid.Cid, error) { + buf := blockstore.NewTieredBstore(sm.ChainStore().StateBlockstore(), blockstore.NewMemorySync()) + store := store.ActorStore(ctx, buf) + + // ensure that the manifest is loaded in the blockstore + if err := bundle.LoadBundles(ctx, sm.ChainStore().StateBlockstore(), actorstypes.Version10); err != nil { + return cid.Undef, xerrors.Errorf("failed to load manifest bundle: %w", err) + } + + // Load the state root. + var stateRoot types.StateRoot + if err := store.Get(ctx, root, &stateRoot); err != nil { + return cid.Undef, xerrors.Errorf("failed to decode state root: %w", err) + } + + if stateRoot.Version != types.StateTreeVersion4 { + return cid.Undef, xerrors.Errorf( + "expected state root version 4 for actors v9 upgrade, got %d", + stateRoot.Version, + ) + } + + manifest, ok := actors.GetManifest(actorstypes.Version10) + if !ok { + return cid.Undef, xerrors.Errorf("no manifest CID for v9 upgrade") + } + + // Perform the migration + newHamtRoot, err := nv18.MigrateStateTree(ctx, store, manifest, stateRoot.Actors, epoch, config, + migrationLogger{}, cache) + if err != nil { + return cid.Undef, xerrors.Errorf("upgrading to actors v10: %w", err) + } + + // Persist the result. + newRoot, err := store.Put(ctx, &types.StateRoot{ + Version: types.StateTreeVersion5, + Actors: newHamtRoot, + Info: stateRoot.Info, + }) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) + } + + // Persist the new tree. + + { + from := buf + to := buf.Read() + + if err := vm.Copy(ctx, from, to, newRoot); err != nil { + return cid.Undef, xerrors.Errorf("copying migrated tree: %w", err) + } + } + + return newRoot, nil } // Example upgrade function if upgrade requires only code changes diff --git a/chain/gen/genesis/fevm.go b/chain/gen/genesis/fevm.go index 5cbf200ce..3de5e7cf9 100644 --- a/chain/gen/genesis/fevm.go +++ b/chain/gen/genesis/fevm.go @@ -99,9 +99,7 @@ func SetupFEVM(ctx context.Context, cs *store.ChainStore, sys vm.SyscallBuilder, SubAddress: make([]byte, 20), } - // TODO method 3 is Exec4; we have to name the methods in go-state-types and avoid using the number - // directly. - if _, err := doExecValue(ctx, genesisVm, builtintypes.InitActorAddr, builtintypes.EthereumAddressManagerActorAddr, big.Zero(), 3, mustEnc(params)); err != nil { + if _, err := doExecValue(ctx, genesisVm, builtintypes.InitActorAddr, builtintypes.EthereumAddressManagerActorAddr, big.Zero(), builtintypes.MethodsInit.Exec4, mustEnc(params)); err != nil { return cid.Undef, fmt.Errorf("creating ETH0 actor: %w", err) } diff --git a/cmd/lotus-shed/migrations.go b/cmd/lotus-shed/migrations.go index ce570c6ac..a7e0ee34f 100644 --- a/cmd/lotus-shed/migrations.go +++ b/cmd/lotus-shed/migrations.go @@ -4,10 +4,10 @@ import ( "context" "fmt" "io" + "strconv" "time" "github.com/ipfs/go-cid" - logging "github.com/ipfs/go-log/v2" "github.com/urfave/cli/v2" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -25,6 +25,8 @@ import ( adt9 "github.com/filecoin-project/go-state-types/builtin/v9/util/adt" verifreg9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" "github.com/filecoin-project/go-state-types/manifest" + mutil "github.com/filecoin-project/go-state-types/migration" + "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/specs-actors/v7/actors/migration/nv15" "github.com/filecoin-project/lotus/blockstore" @@ -47,9 +49,9 @@ import ( ) var migrationsCmd = &cli.Command{ - Name: "migrate-nv17", - Description: "Run the nv17 migration", - ArgsUsage: "[block to look back from]", + Name: "migrate-state", + Description: "Run a network upgrade migration", + ArgsUsage: "[new network version, block to look back from]", Flags: []cli.Flag{ &cli.StringFlag{ Name: "repo", @@ -65,16 +67,21 @@ var migrationsCmd = &cli.Command{ Action: func(cctx *cli.Context) error { ctx := context.TODO() - err := logging.SetLogLevelRegex("badger*", "ERROR") + if cctx.NArg() != 2 { + return lcli.IncorrectNumArgs(cctx) + } + + nv, err := strconv.ParseUint(cctx.Args().Get(0), 10, 32) + if err != nil { + return fmt.Errorf("failed to parse network version: %w", err) + } + + upgradeActorsFunc, preUpgradeActorsFunc, checkInvariantsFunc, err := getMigrationFuncsForNetwork(network.Version(nv)) if err != nil { return err } - if cctx.NArg() != 1 { - return lcli.IncorrectNumArgs(cctx) - } - - blkCid, err := cid.Decode(cctx.Args().First()) + blkCid, err := cid.Decode(cctx.Args().Get(1)) if err != nil { return fmt.Errorf("failed to parse input: %w", err) } @@ -129,7 +136,7 @@ var migrationsCmd = &cli.Command{ startTime := time.Now() - newCid2, err := filcns.UpgradeActorsV9(ctx, sm, nv15.NewMemMigrationCache(), nil, blk.ParentStateRoot, blk.Height-1, migrationTs) + newCid2, err := upgradeActorsFunc(ctx, sm, nv15.NewMemMigrationCache(), nil, blk.ParentStateRoot, blk.Height-1, migrationTs) if err != nil { return err } @@ -142,7 +149,7 @@ var migrationsCmd = &cli.Command{ fmt.Println("completed round actual (without cache), took ", uncachedMigrationTime) if !cctx.IsSet("skip-pre-migration") { - cache := nv15.NewMemMigrationCache() + cache := mutil.NewMemMigrationCache() ts1, err := cs.GetTipsetByHeight(ctx, blk.Height-240, migrationTs, false) if err != nil { @@ -151,7 +158,7 @@ var migrationsCmd = &cli.Command{ startTime = time.Now() - err = filcns.PreUpgradeActorsV9(ctx, sm, cache, ts1.ParentState(), ts1.Height()-1, ts1) + err = preUpgradeActorsFunc(ctx, sm, cache, ts1.ParentState(), ts1.Height()-1, ts1) if err != nil { return err } @@ -165,7 +172,7 @@ var migrationsCmd = &cli.Command{ startTime = time.Now() - err = filcns.PreUpgradeActorsV9(ctx, sm, cache, ts2.ParentState(), ts2.Height()-1, ts2) + err = preUpgradeActorsFunc(ctx, sm, cache, ts2.ParentState(), ts2.Height()-1, ts2) if err != nil { return err } @@ -174,7 +181,7 @@ var migrationsCmd = &cli.Command{ startTime = time.Now() - newCid1, err := filcns.UpgradeActorsV9(ctx, sm, cache, nil, blk.ParentStateRoot, blk.Height-1, migrationTs) + newCid1, err := upgradeActorsFunc(ctx, sm, cache, nil, blk.ParentStateRoot, blk.Height-1, migrationTs) if err != nil { return err } @@ -191,7 +198,10 @@ var migrationsCmd = &cli.Command{ } if cctx.Bool("check-invariants") { - err = checkMigrationInvariants(ctx, blk.ParentStateRoot, newCid2, bs, blk.Height-1) + if checkInvariantsFunc == nil { + return xerrors.Errorf("check invariants not implemented for nv%d", nv) + } + err = checkInvariantsFunc(ctx, blk.ParentStateRoot, newCid2, bs, blk.Height-1) if err != nil { return err } @@ -201,7 +211,22 @@ var migrationsCmd = &cli.Command{ }, } -func checkMigrationInvariants(ctx context.Context, v8StateRootCid cid.Cid, v9StateRootCid cid.Cid, bs blockstore.Blockstore, epoch abi.ChainEpoch) error { +func getMigrationFuncsForNetwork(nv network.Version) (UpgradeActorsFunc, PreUpgradeActorsFunc, CheckInvariantsFunc, error) { + switch nv { + case network.Version17: + return filcns.UpgradeActorsV9, filcns.PreUpgradeActorsV9, checkNv17Invariants, nil + case network.Version18: + return filcns.UpgradeActorsV10, filcns.PreUpgradeActorsV10, nil, nil + default: + return nil, nil, nil, xerrors.Errorf("migration not implemented for nv%d", nv) + } +} + +type UpgradeActorsFunc = func(context.Context, *stmgr.StateManager, stmgr.MigrationCache, stmgr.ExecMonitor, cid.Cid, abi.ChainEpoch, *types.TipSet) (cid.Cid, error) +type PreUpgradeActorsFunc = func(context.Context, *stmgr.StateManager, stmgr.MigrationCache, cid.Cid, abi.ChainEpoch, *types.TipSet) error +type CheckInvariantsFunc = func(context.Context, cid.Cid, cid.Cid, blockstore.Blockstore, abi.ChainEpoch) error + +func checkNv17Invariants(ctx context.Context, v8StateRootCid cid.Cid, v9StateRootCid cid.Cid, bs blockstore.Blockstore, epoch abi.ChainEpoch) error { actorStore := store.ActorStore(ctx, bs) startTime := time.Now() diff --git a/documentation/en/api-v0-methods.md b/documentation/en/api-v0-methods.md index 090f667d6..dc8e6ffc5 100644 --- a/documentation/en/api-v0-methods.md +++ b/documentation/en/api-v0-methods.md @@ -4890,7 +4890,8 @@ Response: "UpgradeChocolateHeight": 0, "UpgradeOhSnapHeight": 0, "UpgradeSkyrHeight": 0, - "UpgradeSharkHeight": 0 + "UpgradeSharkHeight": 0, + "UpgradeHyggeHeight": 0 } } ``` diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 025c4356c..48adcc9fe 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -6426,7 +6426,8 @@ Response: "UpgradeChocolateHeight": 0, "UpgradeOhSnapHeight": 0, "UpgradeSkyrHeight": 0, - "UpgradeSharkHeight": 0 + "UpgradeSharkHeight": 0, + "UpgradeHyggeHeight": 0 } } ``` diff --git a/go.mod b/go.mod index 5a0bfa6b5..dbbe917ab 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( github.com/filecoin-project/go-legs v0.4.4 github.com/filecoin-project/go-padreader v0.0.1 github.com/filecoin-project/go-paramfetch v0.0.4 - github.com/filecoin-project/go-state-types v0.10.0-alpha-5 + github.com/filecoin-project/go-state-types v0.10.0-alpha.7 github.com/filecoin-project/go-statemachine v1.0.2 github.com/filecoin-project/go-statestore v0.2.0 github.com/filecoin-project/go-storedcounter v0.1.0 diff --git a/go.sum b/go.sum index 3ae66f5f1..b56b27cca 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/filecoin-project/go-state-types v0.1.0/go.mod h1:ezYnPf0bNkTsDibL/psS github.com/filecoin-project/go-state-types v0.1.6/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= github.com/filecoin-project/go-state-types v0.1.8/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= github.com/filecoin-project/go-state-types v0.1.10/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= -github.com/filecoin-project/go-state-types v0.10.0-alpha-5 h1:k5yLpgqTns8OFjPwMWfDCmSDd+BqpFhsQEQKIquM3cM= -github.com/filecoin-project/go-state-types v0.10.0-alpha-5/go.mod h1:FPgQE05BFwZxKw/vCuIaIrzfJKo4RPQQMMPGd43dAFI= +github.com/filecoin-project/go-state-types v0.10.0-alpha.7 h1:CnHwzDJpeixx1FLHtlp3iDv2j346qFDYa0w99mSt9A4= +github.com/filecoin-project/go-state-types v0.10.0-alpha.7/go.mod h1:FPgQE05BFwZxKw/vCuIaIrzfJKo4RPQQMMPGd43dAFI= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statemachine v1.0.2 h1:421SSWBk8GIoCoWYYTE/d+qCWccgmRH0uXotXRDjUbc= github.com/filecoin-project/go-statemachine v1.0.2/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54= diff --git a/itests/migration_nv18_test.go b/itests/migration_nv18_test.go new file mode 100644 index 000000000..44bf3806c --- /dev/null +++ b/itests/migration_nv18_test.go @@ -0,0 +1,98 @@ +package itests + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" + "github.com/filecoin-project/go-state-types/builtin" + "github.com/filecoin-project/go-state-types/manifest" + "github.com/filecoin-project/go-state-types/network" + gstStore "github.com/filecoin-project/go-state-types/store" + + "github.com/filecoin-project/lotus/blockstore" + "github.com/filecoin-project/lotus/chain/actors" + builtin2 "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/consensus/filcns" + "github.com/filecoin-project/lotus/chain/state" + "github.com/filecoin-project/lotus/chain/stmgr" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/types/ethtypes" + "github.com/filecoin-project/lotus/chain/vm" + "github.com/filecoin-project/lotus/itests/kit" + "github.com/filecoin-project/lotus/node/impl" +) + +func TestMigrationNV18(t *testing.T) { + kit.QuietMiningLogs() + + nv18epoch := abi.ChainEpoch(100) + testClient, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), + kit.UpgradeSchedule(stmgr.Upgrade{ + Network: network.Version17, + Height: -1, + }, stmgr.Upgrade{ + Network: network.Version18, + Height: nv18epoch, + Migration: filcns.UpgradeActorsV10, + }, + )) + + ens.InterconnectAll().BeginMining(10 * time.Millisecond) + + clientApi := testClient.FullNode.(*impl.FullNodeAPI) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + testClient.WaitTillChain(ctx, kit.HeightAtLeast(nv18epoch+5)) + + // Now that we have upgraded, we need to: + // - the EAM exists, has "empty" state + // - the EthZeroAddress exists + // - all actors have nil Address fields + + bs := blockstore.NewAPIBlockstore(testClient) + ctxStore := gstStore.WrapBlockStore(ctx, bs) + + currTs, err := clientApi.ChainHead(ctx) + require.NoError(t, err) + + newStateTree, err := state.LoadStateTree(ctxStore, currTs.Blocks()[0].ParentStateRoot) + require.NoError(t, err) + + require.Equal(t, types.StateTreeVersion5, newStateTree.Version()) + + codeIDsv10, ok := actors.GetActorCodeIDsFromManifest(actorstypes.Version10) + require.True(t, ok) + + // check the EAM actor + EAMActor, err := newStateTree.GetActor(builtin.EthereumAddressManagerActorAddr) + require.NoError(t, err) + require.Equal(t, vm.EmptyObjectCid, EAMActor.Head) + EAMCodeID, ok := codeIDsv10[manifest.EamKey] + require.True(t, ok) + require.Equal(t, EAMCodeID, EAMActor.Code) + + // check the EthZeroAddress + ethZeroAddr, err := (ethtypes.EthAddress{}).ToFilecoinAddress() + require.NoError(t, err) + ethZeroAddrID, err := newStateTree.LookupID(ethZeroAddr) + require.NoError(t, err) + ethZeroActor, err := newStateTree.GetActor(ethZeroAddrID) + require.NoError(t, err) + require.True(t, builtin2.IsEthAccountActor(ethZeroActor.Code)) + require.Equal(t, vm.EmptyObjectCid, ethZeroActor.Head) + + // check all actor's Address fields + require.NoError(t, newStateTree.ForEach(func(address address.Address, actor *types.Actor) error { + if address != ethZeroAddrID { + require.Nil(t, actor.Address) + } + return nil + })) +} diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 8898c9c56..f364b0f9f 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -1809,6 +1809,7 @@ func (a *StateAPI) StateGetNetworkParams(ctx context.Context) (*api.NetworkParam UpgradeOhSnapHeight: build.UpgradeOhSnapHeight, UpgradeSkyrHeight: build.UpgradeSkyrHeight, UpgradeSharkHeight: build.UpgradeSharkHeight, + UpgradeHyggeHeight: build.UpgradeHyggeHeight, }, }, nil }