Implement function to migrate actors with only code changes
This commit is contained in:
parent
e899f73800
commit
b7010c9e60
@ -868,6 +868,11 @@ workflows:
|
||||
suite: itest-get_messages_in_ts
|
||||
target: "./itests/get_messages_in_ts_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-lite_migration
|
||||
suite: itest-lite_migration
|
||||
target: "./itests/lite_migration_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-lookup_robust_address
|
||||
suite: itest-lookup_robust_address
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
|
||||
@ -38,6 +39,7 @@ import (
|
||||
type ChainIO interface {
|
||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||
ChainPutObj(context.Context, blocks.Block) error
|
||||
}
|
||||
|
||||
const LookbackNoLimit = abi.ChainEpoch(-1)
|
||||
@ -123,6 +125,9 @@ type FullNode interface {
|
||||
// ChainHasObj checks if a given CID exists in the chain blockstore.
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error) //perm:read
|
||||
|
||||
// ChainPutObj puts a given object into the block store
|
||||
ChainPutObj(context.Context, blocks.Block) error //perm:admin
|
||||
|
||||
// ChainStatObj returns statistics about the graph referenced by 'obj'.
|
||||
// If 'base' is also specified, then the returned stat will be a diff
|
||||
// between the two objects.
|
||||
|
@ -3,6 +3,7 @@ package api
|
||||
import (
|
||||
"context"
|
||||
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@ -30,6 +31,7 @@ import (
|
||||
|
||||
type Gateway interface {
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||
ChainPutObj(context.Context, blocks.Block) error
|
||||
ChainHead(ctx context.Context) (*types.TipSet, error)
|
||||
ChainGetParentMessages(context.Context, cid.Cid) ([]Message, error)
|
||||
ChainGetParentReceipts(context.Context, cid.Cid) ([]*types.MessageReceipt, error)
|
||||
|
@ -28,6 +28,7 @@ import (
|
||||
filestore "github.com/filecoin-project/go-fil-markets/filestore"
|
||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
textselector "github.com/ipld/go-ipld-selector-text-lite"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
@ -95,6 +96,9 @@ func init() {
|
||||
apiSelExample := api.Selector("Links/21/Hash/Links/42/Hash")
|
||||
clientEvent := retrievalmarket.ClientEventDealAccepted
|
||||
|
||||
block := blocks.Block(&blocks.BasicBlock{})
|
||||
ExampleValues[reflect.TypeOf(&block).Elem()] = block
|
||||
|
||||
addExample(bitfield.NewFromSet([]uint64{5}))
|
||||
addExample(abi.RegisteredSealProof_StackedDrg32GiBV1_1)
|
||||
addExample(abi.RegisteredPoStProof_StackedDrgWindow32GiBV1)
|
||||
|
@ -31,6 +31,7 @@ import (
|
||||
imports "github.com/filecoin-project/lotus/node/repo/imports"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
uuid "github.com/google/uuid"
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
||||
network0 "github.com/libp2p/go-libp2p-core/network"
|
||||
@ -374,6 +375,20 @@ func (mr *MockFullNodeMockRecorder) ChainNotify(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainNotify", reflect.TypeOf((*MockFullNode)(nil).ChainNotify), arg0)
|
||||
}
|
||||
|
||||
// ChainPutObj mocks base method.
|
||||
func (m *MockFullNode) ChainPutObj(arg0 context.Context, arg1 blocks.Block) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ChainPutObj", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ChainPutObj indicates an expected call of ChainPutObj.
|
||||
func (mr *MockFullNodeMockRecorder) ChainPutObj(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainPutObj", reflect.TypeOf((*MockFullNode)(nil).ChainPutObj), arg0, arg1)
|
||||
}
|
||||
|
||||
// ChainReadObj mocks base method.
|
||||
func (m *MockFullNode) ChainReadObj(arg0 context.Context, arg1 cid.Cid) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/node/repo/imports"
|
||||
"github.com/filecoin-project/specs-storage/storage"
|
||||
"github.com/google/uuid"
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-cid"
|
||||
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
@ -48,6 +49,8 @@ type ChainIOStruct struct {
|
||||
Internal struct {
|
||||
ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) ``
|
||||
|
||||
ChainPutObj func(p0 context.Context, p1 blocks.Block) error ``
|
||||
|
||||
ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) ``
|
||||
}
|
||||
}
|
||||
@ -141,6 +144,8 @@ type FullNodeStruct struct {
|
||||
|
||||
ChainNotify func(p0 context.Context) (<-chan []*HeadChange, error) `perm:"read"`
|
||||
|
||||
ChainPutObj func(p0 context.Context, p1 blocks.Block) error `perm:"admin"`
|
||||
|
||||
ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `perm:"read"`
|
||||
|
||||
ChainSetHead func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"`
|
||||
@ -511,6 +516,8 @@ type GatewayStruct struct {
|
||||
|
||||
ChainNotify func(p0 context.Context) (<-chan []*HeadChange, error) ``
|
||||
|
||||
ChainPutObj func(p0 context.Context, p1 blocks.Block) error ``
|
||||
|
||||
ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) ``
|
||||
|
||||
Discover func(p0 context.Context) (apitypes.OpenRPCDocument, error) ``
|
||||
@ -981,6 +988,17 @@ func (s *ChainIOStub) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error)
|
||||
return false, ErrNotSupported
|
||||
}
|
||||
|
||||
func (s *ChainIOStruct) ChainPutObj(p0 context.Context, p1 blocks.Block) error {
|
||||
if s.Internal.ChainPutObj == nil {
|
||||
return ErrNotSupported
|
||||
}
|
||||
return s.Internal.ChainPutObj(p0, p1)
|
||||
}
|
||||
|
||||
func (s *ChainIOStub) ChainPutObj(p0 context.Context, p1 blocks.Block) error {
|
||||
return ErrNotSupported
|
||||
}
|
||||
|
||||
func (s *ChainIOStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) {
|
||||
if s.Internal.ChainReadObj == nil {
|
||||
return *new([]byte), ErrNotSupported
|
||||
@ -1311,6 +1329,17 @@ func (s *FullNodeStub) ChainNotify(p0 context.Context) (<-chan []*HeadChange, er
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ChainPutObj(p0 context.Context, p1 blocks.Block) error {
|
||||
if s.Internal.ChainPutObj == nil {
|
||||
return ErrNotSupported
|
||||
}
|
||||
return s.Internal.ChainPutObj(p0, p1)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) ChainPutObj(p0 context.Context, p1 blocks.Block) error {
|
||||
return ErrNotSupported
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) {
|
||||
if s.Internal.ChainReadObj == nil {
|
||||
return *new([]byte), ErrNotSupported
|
||||
@ -3291,6 +3320,17 @@ func (s *GatewayStub) ChainNotify(p0 context.Context) (<-chan []*HeadChange, err
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
func (s *GatewayStruct) ChainPutObj(p0 context.Context, p1 blocks.Block) error {
|
||||
if s.Internal.ChainPutObj == nil {
|
||||
return ErrNotSupported
|
||||
}
|
||||
return s.Internal.ChainPutObj(p0, p1)
|
||||
}
|
||||
|
||||
func (s *GatewayStub) ChainPutObj(p0 context.Context, p1 blocks.Block) error {
|
||||
return ErrNotSupported
|
||||
}
|
||||
|
||||
func (s *GatewayStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) {
|
||||
if s.Internal.ChainReadObj == nil {
|
||||
return *new([]byte), ErrNotSupported
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-cid"
|
||||
textselector "github.com/ipld/go-ipld-selector-text-lite"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
@ -110,6 +111,9 @@ type FullNode interface {
|
||||
// ChainDeleteObj deletes node referenced by the given CID
|
||||
ChainDeleteObj(context.Context, cid.Cid) error //perm:admin
|
||||
|
||||
// ChainPutObj puts and object into the blockstore
|
||||
ChainPutObj(context.Context, blocks.Block) error
|
||||
|
||||
// ChainHasObj checks if a given CID exists in the chain blockstore.
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error) //perm:read
|
||||
|
||||
|
@ -3,6 +3,7 @@ package v0api
|
||||
import (
|
||||
"context"
|
||||
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@ -34,6 +35,7 @@ import (
|
||||
|
||||
type Gateway interface {
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||
ChainPutObj(context.Context, blocks.Block) error
|
||||
ChainHead(ctx context.Context) (*types.TipSet, error)
|
||||
ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error)
|
||||
ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error)
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
marketevents "github.com/filecoin-project/lotus/markets/loggers"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
"github.com/filecoin-project/lotus/node/repo/imports"
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"golang.org/x/xerrors"
|
||||
@ -74,6 +75,8 @@ type FullNodeStruct struct {
|
||||
|
||||
ChainNotify func(p0 context.Context) (<-chan []*api.HeadChange, error) `perm:"read"`
|
||||
|
||||
ChainPutObj func(p0 context.Context, p1 blocks.Block) error ``
|
||||
|
||||
ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `perm:"read"`
|
||||
|
||||
ChainSetHead func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"`
|
||||
@ -420,6 +423,8 @@ type GatewayStruct struct {
|
||||
|
||||
ChainNotify func(p0 context.Context) (<-chan []*api.HeadChange, error) ``
|
||||
|
||||
ChainPutObj func(p0 context.Context, p1 blocks.Block) error ``
|
||||
|
||||
ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) ``
|
||||
|
||||
GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) ``
|
||||
@ -682,6 +687,17 @@ func (s *FullNodeStub) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ChainPutObj(p0 context.Context, p1 blocks.Block) error {
|
||||
if s.Internal.ChainPutObj == nil {
|
||||
return ErrNotSupported
|
||||
}
|
||||
return s.Internal.ChainPutObj(p0, p1)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) ChainPutObj(p0 context.Context, p1 blocks.Block) error {
|
||||
return ErrNotSupported
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) {
|
||||
if s.Internal.ChainReadObj == nil {
|
||||
return *new([]byte), ErrNotSupported
|
||||
@ -2530,6 +2546,17 @@ func (s *GatewayStub) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange,
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
func (s *GatewayStruct) ChainPutObj(p0 context.Context, p1 blocks.Block) error {
|
||||
if s.Internal.ChainPutObj == nil {
|
||||
return ErrNotSupported
|
||||
}
|
||||
return s.Internal.ChainPutObj(p0, p1)
|
||||
}
|
||||
|
||||
func (s *GatewayStub) ChainPutObj(p0 context.Context, p1 blocks.Block) error {
|
||||
return ErrNotSupported
|
||||
}
|
||||
|
||||
func (s *GatewayStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) {
|
||||
if s.Internal.ChainReadObj == nil {
|
||||
return *new([]byte), ErrNotSupported
|
||||
|
@ -33,6 +33,7 @@ import (
|
||||
imports "github.com/filecoin-project/lotus/node/repo/imports"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
uuid "github.com/google/uuid"
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
||||
network0 "github.com/libp2p/go-libp2p-core/network"
|
||||
@ -377,6 +378,20 @@ func (mr *MockFullNodeMockRecorder) ChainNotify(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainNotify", reflect.TypeOf((*MockFullNode)(nil).ChainNotify), arg0)
|
||||
}
|
||||
|
||||
// ChainPutObj mocks base method.
|
||||
func (m *MockFullNode) ChainPutObj(arg0 context.Context, arg1 blocks.Block) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ChainPutObj", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ChainPutObj indicates an expected call of ChainPutObj.
|
||||
func (mr *MockFullNodeMockRecorder) ChainPutObj(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainPutObj", reflect.TypeOf((*MockFullNode)(nil).ChainPutObj), arg0, arg1)
|
||||
}
|
||||
|
||||
// ChainReadObj mocks base method.
|
||||
func (m *MockFullNode) ChainReadObj(arg0 context.Context, arg1 cid.Cid) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
type ChainIO interface {
|
||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||
ChainPutObj(context.Context, blocks.Block) error
|
||||
}
|
||||
|
||||
type apiBlockstore struct {
|
||||
@ -49,12 +50,18 @@ func (a *apiBlockstore) GetSize(ctx context.Context, c cid.Cid) (int, error) {
|
||||
return len(bb), nil
|
||||
}
|
||||
|
||||
func (a *apiBlockstore) Put(context.Context, blocks.Block) error {
|
||||
return xerrors.New("not supported")
|
||||
func (a *apiBlockstore) Put(ctx context.Context, block blocks.Block) error {
|
||||
return a.api.ChainPutObj(ctx, block)
|
||||
}
|
||||
|
||||
func (a *apiBlockstore) PutMany(context.Context, []blocks.Block) error {
|
||||
return xerrors.New("not supported")
|
||||
func (a *apiBlockstore) PutMany(ctx context.Context, blocks []blocks.Block) error {
|
||||
for _, block := range blocks {
|
||||
err := a.api.ChainPutObj(ctx, block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *apiBlockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -4,6 +4,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
@ -48,11 +49,11 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
func MakeState(store adt.Store, av actors.Version) (State, error) {
|
||||
func MakeState(store adt.Store, av actors.Version, builtinActors cid.Cid) (State, error) {
|
||||
switch av {
|
||||
{{range .versions}}
|
||||
case actors.Version{{.}}:
|
||||
return make{{.}}(store)
|
||||
return make{{.}}(store{{if (ge . 8)}}, builtinActors{{end}})
|
||||
{{end}}
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor version %d", av)
|
||||
@ -60,4 +61,5 @@ func MakeState(store adt.Store, av actors.Version) (State, error) {
|
||||
|
||||
type State interface {
|
||||
GetState() interface{}
|
||||
GetBuiltinActors() cid.Cid
|
||||
}
|
||||
|
@ -23,9 +23,11 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func make{{.v}}(store adt.Store) (State, error) {
|
||||
func make{{.v}}(store adt.Store{{if (ge .v 8)}}, builtinActors cid.Cid{{end}}) (State, error) {
|
||||
out := state{{.v}}{store: store}
|
||||
out.State = system{{.v}}.State{}
|
||||
out.State = system{{.v}}.State{
|
||||
{{if (ge .v 8)}}BuiltinActors: builtinActors,{{end}}
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
@ -37,3 +39,11 @@ type state{{.v}} struct {
|
||||
func (s *state{{.v}}) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) GetBuiltinActors() cid.Cid {
|
||||
{{if (le .v 7)}}
|
||||
return cid.Undef
|
||||
{{else}}
|
||||
return s.State.BuiltinActors
|
||||
{{end}}
|
||||
}
|
@ -4,6 +4,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
@ -70,7 +71,7 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
func MakeState(store adt.Store, av actors.Version) (State, error) {
|
||||
func MakeState(store adt.Store, av actors.Version, builtinActors cid.Cid) (State, error) {
|
||||
switch av {
|
||||
|
||||
case actors.Version0:
|
||||
@ -95,7 +96,7 @@ func MakeState(store adt.Store, av actors.Version) (State, error) {
|
||||
return make7(store)
|
||||
|
||||
case actors.Version8:
|
||||
return make8(store)
|
||||
return make8(store, builtinActors)
|
||||
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor version %d", av)
|
||||
@ -103,4 +104,5 @@ func MakeState(store adt.Store, av actors.Version) (State, error) {
|
||||
|
||||
type State interface {
|
||||
GetState() interface{}
|
||||
GetBuiltinActors() cid.Cid
|
||||
}
|
||||
|
@ -33,3 +33,9 @@ type state0 struct {
|
||||
func (s *state0) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
|
||||
func (s *state0) GetBuiltinActors() cid.Cid {
|
||||
|
||||
return cid.Undef
|
||||
|
||||
}
|
||||
|
@ -33,3 +33,9 @@ type state2 struct {
|
||||
func (s *state2) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
|
||||
func (s *state2) GetBuiltinActors() cid.Cid {
|
||||
|
||||
return cid.Undef
|
||||
|
||||
}
|
||||
|
@ -33,3 +33,9 @@ type state3 struct {
|
||||
func (s *state3) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
|
||||
func (s *state3) GetBuiltinActors() cid.Cid {
|
||||
|
||||
return cid.Undef
|
||||
|
||||
}
|
||||
|
@ -33,3 +33,9 @@ type state4 struct {
|
||||
func (s *state4) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
|
||||
func (s *state4) GetBuiltinActors() cid.Cid {
|
||||
|
||||
return cid.Undef
|
||||
|
||||
}
|
||||
|
@ -33,3 +33,9 @@ type state5 struct {
|
||||
func (s *state5) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
|
||||
func (s *state5) GetBuiltinActors() cid.Cid {
|
||||
|
||||
return cid.Undef
|
||||
|
||||
}
|
||||
|
@ -33,3 +33,9 @@ type state6 struct {
|
||||
func (s *state6) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
|
||||
func (s *state6) GetBuiltinActors() cid.Cid {
|
||||
|
||||
return cid.Undef
|
||||
|
||||
}
|
||||
|
@ -33,3 +33,9 @@ type state7 struct {
|
||||
func (s *state7) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
|
||||
func (s *state7) GetBuiltinActors() cid.Cid {
|
||||
|
||||
return cid.Undef
|
||||
|
||||
}
|
||||
|
@ -19,9 +19,11 @@ func load8(store adt.Store, root cid.Cid) (State, error) {
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func make8(store adt.Store) (State, error) {
|
||||
func make8(store adt.Store, builtinActors cid.Cid) (State, error) {
|
||||
out := state8{store: store}
|
||||
out.State = system8.State{}
|
||||
out.State = system8.State{
|
||||
BuiltinActors: builtinActors,
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
@ -33,3 +35,9 @@ type state8 struct {
|
||||
func (s *state8) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
|
||||
func (s *state8) GetBuiltinActors() cid.Cid {
|
||||
|
||||
return s.State.BuiltinActors
|
||||
|
||||
}
|
||||
|
@ -5,13 +5,7 @@ import (
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/v8/actors/migration/nv16"
|
||||
|
||||
"github.com/docker/go-units"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/v6/actors/migration/nv14"
|
||||
"github.com/filecoin-project/specs-actors/v7/actors/migration/nv15"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"golang.org/x/xerrors"
|
||||
@ -19,8 +13,10 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
"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"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
@ -33,12 +29,16 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/v3/actors/migration/nv10"
|
||||
"github.com/filecoin-project/specs-actors/v4/actors/migration/nv12"
|
||||
"github.com/filecoin-project/specs-actors/v5/actors/migration/nv13"
|
||||
"github.com/filecoin-project/specs-actors/v6/actors/migration/nv14"
|
||||
"github.com/filecoin-project/specs-actors/v7/actors/migration/nv15"
|
||||
"github.com/filecoin-project/specs-actors/v8/actors/migration/nv16"
|
||||
|
||||
"github.com/filecoin-project/lotus/blockstore"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/multisig"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/system"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
@ -1431,6 +1431,155 @@ func upgradeActorsV8Common(
|
||||
return newRoot, nil
|
||||
}
|
||||
|
||||
// Example upgrade function if upgrade requires only code changes
|
||||
//func UpgradeActorsV9(ctx context.Context, sm *stmgr.StateManager, _ stmgr.MigrationCache, _ stmgr.ExecMonitor, root cid.Cid, _ abi.ChainEpoch, _ *types.TipSet) (cid.Cid, error) {
|
||||
// buf := blockstore.NewTieredBstore(sm.ChainStore().StateBlockstore(), blockstore.NewMemorySync())
|
||||
//
|
||||
// av := actors.Version9
|
||||
// // This may change for upgrade
|
||||
// newStateTreeVersion := types.StateTreeVersion4
|
||||
//
|
||||
// // ensure that the manifest is loaded in the blockstore
|
||||
// if err := bundle.FetchAndLoadBundles(ctx, buf, map[actors.Version]build.Bundle{
|
||||
// av: build.BuiltinActorReleases[av],
|
||||
// }); err != nil {
|
||||
// return cid.Undef, xerrors.Errorf("failed to load manifest bundle: %w", err)
|
||||
// }
|
||||
//
|
||||
// newActorsManifestCid, ok := actors.GetManifest(av)
|
||||
// if !ok {
|
||||
// return cid.Undef, xerrors.Errorf("no manifest CID for v8 upgrade")
|
||||
// }
|
||||
//
|
||||
// bstore := sm.ChainStore().StateBlockstore()
|
||||
// return LiteMigration(ctx, bstore, newActorsManifestCid, root, av, types.StateTreeVersion4, newStateTreeVersion)
|
||||
//}
|
||||
|
||||
func LiteMigration(ctx context.Context, bstore blockstore.Blockstore, newActorsManifestCid cid.Cid, root cid.Cid, av actors.Version, oldStateTreeVersion types.StateTreeVersion, newStateTreeVersion types.StateTreeVersion) (cid.Cid, error) {
|
||||
buf := blockstore.NewTieredBstore(bstore, blockstore.NewMemorySync())
|
||||
store := store.ActorStore(ctx, buf)
|
||||
adtStore := gstStore.WrapStore(ctx, store)
|
||||
|
||||
// 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 != oldStateTreeVersion {
|
||||
return cid.Undef, xerrors.Errorf(
|
||||
"expected state tree version %d for actors code upgrade, got %d",
|
||||
oldStateTreeVersion,
|
||||
stateRoot.Version,
|
||||
)
|
||||
}
|
||||
|
||||
st, err := state.LoadStateTree(store, root)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to load state tree: %w", err)
|
||||
}
|
||||
|
||||
oldManifest, err := stmgr.GetManifest(ctx, st)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("error loading old actor manifest: %w", err)
|
||||
}
|
||||
oldManifestData := manifest.ManifestData{}
|
||||
if err := store.Get(ctx, oldManifest.Data, &oldManifestData); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("error loading old manifest data: %w", err)
|
||||
}
|
||||
|
||||
// load new manifest
|
||||
newManifest := manifest.Manifest{}
|
||||
if err := store.Get(ctx, newActorsManifestCid, &newManifest); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("error loading new manifest: %w", err)
|
||||
}
|
||||
newManifestData := manifest.ManifestData{}
|
||||
if err := store.Get(ctx, newManifest.Data, &newManifestData); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("error loading new manifest data: %w", err)
|
||||
}
|
||||
|
||||
if len(oldManifestData.Entries) != len(actors.GetBuiltinActorsKeys()) {
|
||||
return cid.Undef, xerrors.Errorf("incomplete old manifest with %d code CIDs", len(oldManifestData.Entries))
|
||||
}
|
||||
if len(newManifestData.Entries) != len(actors.GetBuiltinActorsKeys()) {
|
||||
return cid.Undef, xerrors.Errorf("incomplete new manifest with %d code CIDs", len(newManifestData.Entries))
|
||||
}
|
||||
|
||||
// Maps prior version code CIDs to migration functions.
|
||||
migrations := make(map[cid.Cid]cid.Cid)
|
||||
|
||||
for _, entry := range newManifestData.Entries {
|
||||
oldCodeCid, ok := oldManifest.Get(entry.Name)
|
||||
if !ok {
|
||||
return cid.Undef, xerrors.Errorf("code cid for %s actor not found in old manifest", entry.Name)
|
||||
}
|
||||
migrations[oldCodeCid] = entry.Code
|
||||
}
|
||||
|
||||
startTime := time.Now()
|
||||
|
||||
// Load output state tree
|
||||
actorsOut, err := state.NewStateTree(adtStore, newStateTreeVersion)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
// Insert migrated records in output state tree.
|
||||
err = st.ForEach(func(addr address.Address, actorIn *types.Actor) error {
|
||||
newCid, ok := migrations[actorIn.Code]
|
||||
if !ok {
|
||||
return xerrors.Errorf("new code cid not found in migrations for actor %s", addr)
|
||||
}
|
||||
var head cid.Cid
|
||||
if addr == system.Address {
|
||||
newSystemState, err := system.MakeState(store, av, newManifest.Data)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("could not make system actor state: %w", err)
|
||||
}
|
||||
head, err = store.Put(ctx, newSystemState)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("could not set system actor state head: %w", err)
|
||||
}
|
||||
} else {
|
||||
head = actorIn.Head
|
||||
}
|
||||
newActor := types.Actor{
|
||||
Code: newCid,
|
||||
Head: head,
|
||||
Nonce: actorIn.Nonce,
|
||||
Balance: actorIn.Balance,
|
||||
}
|
||||
err = actorsOut.SetActor(addr, &newActor)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("could not set actor at address %s: %w", addr, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed update actor states: %w", err)
|
||||
}
|
||||
|
||||
elapsed := time.Since(startTime)
|
||||
log.Infof("All done after %v. Flushing state tree root.", elapsed)
|
||||
newRoot, err := actorsOut.Flush(ctx)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to flush new actors: %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
|
||||
}
|
||||
|
||||
type migrationLogger struct{}
|
||||
|
||||
func (ml migrationLogger) Log(level rt.LogLevel, msg string, args ...interface{}) {
|
||||
|
@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/blockstore"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@ -39,6 +41,10 @@ func (m *MockAPI) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) {
|
||||
return blk.RawData(), nil
|
||||
}
|
||||
|
||||
func (m *MockAPI) ChainPutObj(ctx context.Context, block blocks.Block) error {
|
||||
return m.bs.Put(ctx, block)
|
||||
}
|
||||
|
||||
func (m *MockAPI) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||
m.lk.Lock()
|
||||
defer m.lk.Unlock()
|
||||
|
@ -3,6 +3,8 @@ package genesis
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
systemtypes "github.com/filecoin-project/go-state-types/builtin/v8/system"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
@ -25,7 +27,8 @@ import (
|
||||
func SetupSystemActor(ctx context.Context, bs bstore.Blockstore, av actors.Version) (*types.Actor, error) {
|
||||
|
||||
cst := cbor.NewCborStore(bs)
|
||||
st, err := system.MakeState(adt.WrapStore(ctx, cst), av)
|
||||
// TODO pass in built-in actors cid for V8 and later
|
||||
st, err := system.MakeState(adt.WrapStore(ctx, cst), av, cid.Undef)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/rand"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
@ -15,8 +15,6 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
miner_types "github.com/filecoin-project/go-state-types/builtin/v8/miner"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
@ -25,6 +23,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
|
||||
"github.com/filecoin-project/lotus/chain/beacon"
|
||||
"github.com/filecoin-project/lotus/chain/rand"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
|
@ -5,18 +5,21 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/rand"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
gstStore "github.com/filecoin-project/go-state-types/store"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/system"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
"github.com/filecoin-project/lotus/chain/rand"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@ -211,3 +214,42 @@ func (sm *StateManager) ListAllActors(ctx context.Context, ts *types.TipSet) ([]
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func GetManifest(ctx context.Context, st *state.StateTree) (*manifest.Manifest, error) {
|
||||
wrapStore := gstStore.WrapStore(ctx, st.Store)
|
||||
|
||||
systemActor, err := st.GetActor(system.Address)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get system actor: %w", err)
|
||||
}
|
||||
systemActorState, err := system.Load(wrapStore, systemActor)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to load system actor state: %w", err)
|
||||
}
|
||||
actorsManifestCid := systemActorState.GetBuiltinActors()
|
||||
|
||||
mf := manifest.Manifest{
|
||||
Version: 1,
|
||||
Data: actorsManifestCid,
|
||||
}
|
||||
if err := mf.Load(ctx, wrapStore); err != nil {
|
||||
return nil, xerrors.Errorf("failed to load actor manifest: %w", err)
|
||||
}
|
||||
manifestData := manifest.ManifestData{}
|
||||
if err := st.Store.Get(ctx, mf.Data, &manifestData); err != nil {
|
||||
return nil, xerrors.Errorf("failed to load manifest data: %w", err)
|
||||
}
|
||||
return &mf, nil
|
||||
}
|
||||
|
||||
func GetManifestEntries(ctx context.Context, st *state.StateTree) ([]manifest.ManifestEntry, error) {
|
||||
mf, err := GetManifest(ctx, st)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get manifest: %w", err)
|
||||
}
|
||||
manifestData := manifest.ManifestData{}
|
||||
if err := st.Store.Get(ctx, mf.Data, &manifestData); err != nil {
|
||||
return nil, xerrors.Errorf("filed to load manifest data: %w", err)
|
||||
}
|
||||
return manifestData.Entries, nil
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
* [ChainHasObj](#ChainHasObj)
|
||||
* [ChainHead](#ChainHead)
|
||||
* [ChainNotify](#ChainNotify)
|
||||
* [ChainPutObj](#ChainPutObj)
|
||||
* [ChainReadObj](#ChainReadObj)
|
||||
* [ChainSetHead](#ChainSetHead)
|
||||
* [ChainStatObj](#ChainStatObj)
|
||||
@ -971,6 +972,21 @@ Response:
|
||||
]
|
||||
```
|
||||
|
||||
### ChainPutObj
|
||||
ChainPutObj puts and object into the blockstore
|
||||
|
||||
|
||||
Perms:
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
{}
|
||||
]
|
||||
```
|
||||
|
||||
Response: `{}`
|
||||
|
||||
### ChainReadObj
|
||||
ChainReadObj reads ipld nodes referenced by the specified CID from chain
|
||||
blockstore and returns raw bytes.
|
||||
|
@ -28,6 +28,7 @@
|
||||
* [ChainHasObj](#ChainHasObj)
|
||||
* [ChainHead](#ChainHead)
|
||||
* [ChainNotify](#ChainNotify)
|
||||
* [ChainPutObj](#ChainPutObj)
|
||||
* [ChainReadObj](#ChainReadObj)
|
||||
* [ChainSetHead](#ChainSetHead)
|
||||
* [ChainStatObj](#ChainStatObj)
|
||||
@ -959,6 +960,21 @@ Response:
|
||||
]
|
||||
```
|
||||
|
||||
### ChainPutObj
|
||||
ChainPutObj puts a given object into the block store
|
||||
|
||||
|
||||
Perms: admin
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
{}
|
||||
]
|
||||
```
|
||||
|
||||
Response: `{}`
|
||||
|
||||
### ChainReadObj
|
||||
ChainReadObj reads ipld nodes referenced by the specified CID from chain
|
||||
blockstore and returns raw bytes.
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-cid"
|
||||
"go.opencensus.io/stats"
|
||||
"golang.org/x/time/rate"
|
||||
@ -55,6 +56,7 @@ type TargetAPI interface {
|
||||
ChainNotify(context.Context) (<-chan []*api.HeadChange, error)
|
||||
ChainGetPath(ctx context.Context, from, to types.TipSetKey) ([]*api.HeadChange, error)
|
||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||
ChainPutObj(context.Context, blocks.Block) error
|
||||
ChainGetGenesis(context.Context) (*types.TipSet, error)
|
||||
GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
|
||||
MpoolPushUntrusted(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
|
||||
@ -332,6 +334,10 @@ func (gw *Node) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) {
|
||||
return gw.target.ChainReadObj(ctx, c)
|
||||
}
|
||||
|
||||
func (gw *Node) ChainPutObj(context.Context, blocks.Block) error {
|
||||
return xerrors.New("not supported")
|
||||
}
|
||||
|
||||
func (gw *Node) GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) {
|
||||
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||
return nil, err
|
||||
|
4
go.mod
4
go.mod
@ -41,7 +41,7 @@ require (
|
||||
github.com/filecoin-project/go-legs v0.3.10
|
||||
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.1.7
|
||||
github.com/filecoin-project/go-state-types v0.1.9
|
||||
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
|
||||
@ -54,7 +54,7 @@ require (
|
||||
github.com/filecoin-project/specs-actors/v5 v5.0.6
|
||||
github.com/filecoin-project/specs-actors/v6 v6.0.2
|
||||
github.com/filecoin-project/specs-actors/v7 v7.0.1
|
||||
github.com/filecoin-project/specs-actors/v8 v8.0.0
|
||||
github.com/filecoin-project/specs-actors/v8 v8.0.1
|
||||
github.com/filecoin-project/specs-storage v0.4.1
|
||||
github.com/filecoin-project/test-vectors/schema v0.0.5
|
||||
github.com/gbrlsnchs/jwt/v3 v3.0.1
|
||||
|
8
go.sum
8
go.sum
@ -372,8 +372,8 @@ github.com/filecoin-project/go-state-types v0.1.3/go.mod h1:ezYnPf0bNkTsDibL/psS
|
||||
github.com/filecoin-project/go-state-types v0.1.4/go.mod h1:xCA/WfKlC2zcn3fUmDv4IrzznwS98X5XW/irUP3Lhxg=
|
||||
github.com/filecoin-project/go-state-types v0.1.5/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q=
|
||||
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.7 h1:r/ZzyUA+CqY8IXyHsLtliqRgPFaON+aC2MmWKm1nl98=
|
||||
github.com/filecoin-project/go-state-types v0.1.7/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q=
|
||||
github.com/filecoin-project/go-state-types v0.1.9 h1:7ffQu+arDAiW5dphWTl8WdgWTo9Kt3BsjGcNYr99crI=
|
||||
github.com/filecoin-project/go-state-types v0.1.9/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q=
|
||||
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-0.20220322104818-27f8fbb86dfd/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54=
|
||||
github.com/filecoin-project/go-statemachine v1.0.2 h1:421SSWBk8GIoCoWYYTE/d+qCWccgmRH0uXotXRDjUbc=
|
||||
@ -411,8 +411,8 @@ github.com/filecoin-project/specs-actors/v6 v6.0.2/go.mod h1:wnfVvPnYmzPZilNvSqC
|
||||
github.com/filecoin-project/specs-actors/v7 v7.0.0/go.mod h1:TA5FwCna+Yi36POaT7SLKXsgEDvJwc0V/L6ZsO19B9M=
|
||||
github.com/filecoin-project/specs-actors/v7 v7.0.1 h1:w72xCxijK7xs1qzmJiw+WYJaVt2EPHN8oiwpA1Ay3/4=
|
||||
github.com/filecoin-project/specs-actors/v7 v7.0.1/go.mod h1:tPLEYXoXhcpyLh69Ccq91SOuLXsPWjHiY27CzawjUEk=
|
||||
github.com/filecoin-project/specs-actors/v8 v8.0.0 h1:c6NztoE4J5j7KvIfGmx9XW9o5aszPl6DU0M4xDqAJVU=
|
||||
github.com/filecoin-project/specs-actors/v8 v8.0.0/go.mod h1:UYIPg65iPWoFw5NEftREdJwv9b/5yaLKdCgTvNI/2FA=
|
||||
github.com/filecoin-project/specs-actors/v8 v8.0.1 h1:4u0tIRJeT5G7F05lwLRIsDnsrN+bJ5Ixj6h49Q7uE2Y=
|
||||
github.com/filecoin-project/specs-actors/v8 v8.0.1/go.mod h1:UYIPg65iPWoFw5NEftREdJwv9b/5yaLKdCgTvNI/2FA=
|
||||
github.com/filecoin-project/specs-storage v0.4.1 h1:yvLEaLZj8f+uByhNC4mFOtCUyL2wQku+NGBp6hjTe9M=
|
||||
github.com/filecoin-project/specs-storage v0.4.1/go.mod h1:Z2eK6uMwAOSLjek6+sy0jNV2DSsMEENziMUz0GHRFBw=
|
||||
github.com/filecoin-project/storetheindex v0.3.5 h1:KoS9TvjPm6zIZfUH8atAHJbVHOO7GTP1MdTG+v0eE+Q=
|
||||
|
120
itests/lite_migration_test.go
Normal file
120
itests/lite_migration_test.go
Normal file
@ -0,0 +1,120 @@
|
||||
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"
|
||||
"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"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"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)
|
||||
|
||||
oldManifest, err := stmgr.GetManifest(ctx, oldStateTree)
|
||||
require.NoError(t, err)
|
||||
newManifestCid := makeTestManifest(t, ctxStore)
|
||||
// Use the Cid we generated to get the new manifest instead of loading it from the state tree, because that would not test that we have the correct manifest in the state
|
||||
var newManifest manifest.Manifest
|
||||
err = ctxStore.Get(ctx, newManifestCid, &newManifest)
|
||||
require.NoError(t, err)
|
||||
err = newManifest.Load(ctx, ctxStore)
|
||||
require.NoError(t, err)
|
||||
newManifestData := manifest.ManifestData{}
|
||||
err = ctxStore.Get(ctx, newManifest.Data, &newManifestData)
|
||||
require.NoError(t, err)
|
||||
|
||||
newStateRoot, err := filcns.LiteMigration(ctx, bs, newManifestCid, stateRoot, actors.Version8, types.StateTreeVersion4, types.StateTreeVersion4)
|
||||
require.NoError(t, err)
|
||||
|
||||
newStateTree, err := state.LoadStateTree(ctxStore, newStateRoot)
|
||||
require.NoError(t, err)
|
||||
|
||||
migrations := make(map[cid.Cid]cid.Cid)
|
||||
for _, entry := range newManifestData.Entries {
|
||||
oldCodeCid, ok := oldManifest.Get(entry.Name)
|
||||
require.True(t, ok)
|
||||
migrations[oldCodeCid] = entry.Code
|
||||
}
|
||||
|
||||
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)
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func makeTestManifest(t *testing.T, ctxStore adt.Store) cid.Cid {
|
||||
builder := cid.V1Builder{Codec: cid.Raw, MhType: mh.IDENTITY}
|
||||
|
||||
manifestData := manifest.ManifestData{}
|
||||
for _, name := range []string{"system", "init", "cron", "account", "storagepower", "storageminer", "storagemarket", "paymentchannel", "multisig", "reward", "verifiedregistry"} {
|
||||
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
|
||||
}
|
@ -3,6 +3,7 @@ package storageadapter
|
||||
import (
|
||||
"context"
|
||||
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"golang.org/x/xerrors"
|
||||
@ -20,6 +21,7 @@ type apiWrapper struct {
|
||||
StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error)
|
||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||
ChainPutObj(context.Context, blocks.Block) error
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-blockservice"
|
||||
"github.com/ipfs/go-cid"
|
||||
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
||||
@ -261,6 +262,10 @@ func (m *ChainModule) ChainReadObj(ctx context.Context, obj cid.Cid) ([]byte, er
|
||||
return blk.RawData(), nil
|
||||
}
|
||||
|
||||
func (a *ChainAPI) ChainPutObj(ctx context.Context, obj blocks.Block) error {
|
||||
return a.ExposedBlockstore.Put(ctx, obj)
|
||||
}
|
||||
|
||||
func (a *ChainAPI) ChainDeleteObj(ctx context.Context, obj cid.Cid) error {
|
||||
return a.ExposedBlockstore.DeleteBlock(ctx, obj)
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-datastore"
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
@ -122,6 +123,7 @@ type fullNodeFilteredAPI interface {
|
||||
ChainGetPath(ctx context.Context, from, to types.TipSetKey) ([]*api.HeadChange, error)
|
||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||
ChainPutObj(context.Context, blocks.Block) error
|
||||
ChainGetTipSet(ctx context.Context, key types.TipSetKey) (*types.TipSet, error)
|
||||
|
||||
WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error)
|
||||
|
Loading…
Reference in New Issue
Block a user