2022-06-07 03:14:16 +00:00
|
|
|
package itests
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/ipfs/go-cid"
|
|
|
|
mh "github.com/multiformats/go-multihash"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
|
|
|
"github.com/filecoin-project/go-address"
|
2022-09-06 15:49:29 +00:00
|
|
|
actorstypes "github.com/filecoin-project/go-state-types/actors"
|
2022-06-29 15:46:51 +00:00
|
|
|
system8 "github.com/filecoin-project/go-state-types/builtin/v8/system"
|
2022-06-07 03:14:16 +00:00
|
|
|
"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/specs-actors/v8/actors/util/adt"
|
|
|
|
|
|
|
|
"github.com/filecoin-project/lotus/blockstore"
|
2022-11-16 01:57:23 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/actors"
|
2022-06-29 15:46:51 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/actors/builtin/system"
|
2022-06-07 03:14:16 +00:00
|
|
|
"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/itests/kit"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestLiteMigration(t *testing.T) {
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
kit.QuietMiningLogs()
|
|
|
|
|
|
|
|
client16, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.GenesisNetworkVersion(network.Version16))
|
|
|
|
ens.InterconnectAll().BeginMining(10 * time.Millisecond)
|
|
|
|
|
|
|
|
client16.WaitTillChain(ctx, func(set *types.TipSet) bool {
|
|
|
|
return set.Height() > 100
|
|
|
|
})
|
|
|
|
|
|
|
|
bs := blockstore.NewAPIBlockstore(client16)
|
|
|
|
ctxStore := gstStore.WrapBlockStore(ctx, bs)
|
|
|
|
|
|
|
|
ts, err := client16.ChainHead(ctx)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
stateRoot := ts.ParentState()
|
|
|
|
oldStateTree, err := state.LoadStateTree(ctxStore, stateRoot)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-06-28 22:42:58 +00:00
|
|
|
oldManifestData, err := stmgr.GetManifestData(ctx, oldStateTree)
|
2022-06-07 03:14:16 +00:00
|
|
|
require.NoError(t, err)
|
2022-11-16 01:57:23 +00:00
|
|
|
newManifestCid := makeTestManifest(t, ctxStore, actorstypes.Version9)
|
2022-06-29 15:46:51 +00:00
|
|
|
// Use the Cid we generated to get the new manifest instead of loading it from the store, so as to confirm it's in the store
|
|
|
|
var newManifest manifest.Manifest
|
|
|
|
require.NoError(t, ctxStore.Get(ctx, newManifestCid, &newManifest), "error getting new manifest")
|
|
|
|
|
|
|
|
// populate the entries field of the manifest
|
|
|
|
require.NoError(t, newManifest.Load(ctx, ctxStore), "error loading new manifest")
|
2022-06-07 03:14:16 +00:00
|
|
|
|
2022-11-16 01:57:23 +00:00
|
|
|
newStateRoot, err := filcns.LiteMigration(ctx, bs, newManifestCid, stateRoot, actorstypes.Version8, actorstypes.Version9, types.StateTreeVersion4, types.StateTreeVersion4)
|
2022-06-07 03:14:16 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
newStateTree, err := state.LoadStateTree(ctxStore, newStateRoot)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
migrations := make(map[cid.Cid]cid.Cid)
|
2022-06-29 15:46:51 +00:00
|
|
|
for _, entry := range oldManifestData.Entries {
|
|
|
|
newCodeCid, ok := newManifest.Get(entry.Name)
|
|
|
|
require.True(t, ok)
|
|
|
|
migrations[entry.Code] = newCodeCid
|
2022-06-07 03:14:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
err = newStateTree.ForEach(func(addr address.Address, newActorState *types.Actor) error {
|
|
|
|
oldActor, err := oldStateTree.GetActor(addr)
|
|
|
|
require.NoError(t, err)
|
|
|
|
newCodeCid, ok := migrations[oldActor.Code]
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, newCodeCid, newActorState.Code)
|
2022-06-29 15:46:51 +00:00
|
|
|
|
|
|
|
if addr == system.Address {
|
|
|
|
var systemSt system8.State
|
|
|
|
require.NoError(t, ctxStore.Get(ctx, newActorState.Head, &systemSt))
|
|
|
|
require.Equal(t, systemSt.BuiltinActors, newManifest.Data)
|
|
|
|
}
|
|
|
|
|
2022-06-07 03:14:16 +00:00
|
|
|
return nil
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
2022-11-16 01:57:23 +00:00
|
|
|
func makeTestManifest(t *testing.T, ctxStore adt.Store, av actorstypes.Version) cid.Cid {
|
2022-06-07 03:14:16 +00:00
|
|
|
builder := cid.V1Builder{Codec: cid.Raw, MhType: mh.IDENTITY}
|
|
|
|
|
|
|
|
manifestData := manifest.ManifestData{}
|
2022-11-16 01:57:23 +00:00
|
|
|
for _, name := range actors.GetBuiltinActorsKeys(av) {
|
2022-06-07 03:14:16 +00:00
|
|
|
codeCid, err := builder.Sum([]byte(fmt.Sprintf("fil/8/%s", name)))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
manifestData.Entries = append(manifestData.Entries,
|
|
|
|
manifest.ManifestEntry{
|
|
|
|
Name: name,
|
|
|
|
Code: codeCid,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
manifestDataCid, err := ctxStore.Put(ctxStore.Context(), &manifestData)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
mf := manifest.Manifest{
|
|
|
|
Version: 1,
|
|
|
|
Data: manifestDataCid,
|
|
|
|
}
|
|
|
|
|
|
|
|
manifestCid, err := ctxStore.Put(ctxStore.Context(), &mf)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return manifestCid
|
|
|
|
}
|