Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

introduce separate state-tree versions #4197

Merged
merged 4 commits into from
Oct 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions chain/actors/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
type Version int

const (
Version0 = 0
Version2 = 2
Version0 Version = 0
Version2 Version = 2
)

// Converts a network version into an actors adt version.
Expand Down
3 changes: 1 addition & 2 deletions chain/gen/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"

"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
Expand Down Expand Up @@ -117,7 +116,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
return nil, nil, xerrors.Errorf("putting empty object: %w", err)
}

state, err := state.NewStateTree(cst, actors.Version0)
state, err := state.NewStateTree(cst, types.StateTreeVersion0)
if err != nil {
return nil, nil, xerrors.Errorf("making new state tree: %w", err)
}
Expand Down
56 changes: 40 additions & 16 deletions chain/state/statetree.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/chain/actors"
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
cbg "github.com/whyrusleeping/cbor-gen"
Expand All @@ -26,7 +27,7 @@ var log = logging.Logger("statetree")
// StateTree stores actors state by their ID.
type StateTree struct {
root adt.Map
version actors.Version // TODO
version types.StateTreeVersion
info cid.Cid
Store cbor.IpldStore

Expand Down Expand Up @@ -120,29 +121,49 @@ func (ss *stateSnaps) deleteActor(addr address.Address) {
ss.layers[len(ss.layers)-1].actors[addr] = streeOp{Delete: true}
}

func NewStateTree(cst cbor.IpldStore, version actors.Version) (*StateTree, error) {
// VersionForNetwork returns the state tree version for the given network
// version.
func VersionForNetwork(ver network.Version) types.StateTreeVersion {
if actors.VersionForNetwork(ver) == actors.Version0 {
return types.StateTreeVersion0
}
return types.StateTreeVersion1
}

func adtForSTVersion(ver types.StateTreeVersion) actors.Version {
switch ver {
case types.StateTreeVersion0:
return actors.Version0
case types.StateTreeVersion1:
return actors.Version2
default:
panic("unhandled state tree version")
}
}

func NewStateTree(cst cbor.IpldStore, ver types.StateTreeVersion) (*StateTree, error) {
var info cid.Cid
switch version {
case actors.Version0:
switch ver {
case types.StateTreeVersion0:
// info is undefined
case actors.Version2:
case types.StateTreeVersion1:
var err error
info, err = cst.Put(context.TODO(), new(types.StateInfo))
info, err = cst.Put(context.TODO(), new(types.StateInfo0))
if err != nil {
return nil, err
}
default:
return nil, xerrors.Errorf("unsupported state tree version: %d", version)
return nil, xerrors.Errorf("unsupported state tree version: %d", ver)
}
root, err := adt.NewMap(adt.WrapStore(context.TODO(), cst), version)
root, err := adt.NewMap(adt.WrapStore(context.TODO(), cst), adtForSTVersion(ver))
if err != nil {
return nil, err
}

return &StateTree{
root: root,
info: info,
version: version,
version: ver,
Store: cst,
snaps: newStateSnaps(),
}, nil
Expand All @@ -154,13 +175,16 @@ func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) {
if err := cst.Get(context.TODO(), c, &root); err != nil {
// We failed to decode as the new version, must be an old version.
root.Actors = c
root.Version = actors.Version0
root.Version = types.StateTreeVersion0
}

switch root.Version {
case actors.Version0, actors.Version2:
case types.StateTreeVersion0, types.StateTreeVersion1:
// Load the actual state-tree HAMT.
nd, err := adt.AsMap(adt.WrapStore(context.TODO(), cst), root.Actors, actors.Version(root.Version))
nd, err := adt.AsMap(
adt.WrapStore(context.TODO(), cst), root.Actors,
adtForSTVersion(root.Version),
)
if err != nil {
log.Errorf("loading hamt node %s failed: %s", c, err)
return nil, err
Expand All @@ -169,7 +193,7 @@ func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) {
return &StateTree{
root: nd,
info: root.Info,
version: actors.Version(root.Version),
version: root.Version,
Store: cst,
snaps: newStateSnaps(),
}, nil
Expand Down Expand Up @@ -309,11 +333,11 @@ func (st *StateTree) Flush(ctx context.Context) (cid.Cid, error) {
return cid.Undef, xerrors.Errorf("failed to flush state-tree hamt: %w", err)
}
// If we're version 0, return a raw tree.
if st.version == actors.Version0 {
if st.version == types.StateTreeVersion0 {
return root, nil
}
// Otherwise, return a versioned tree.
return st.Store.Put(ctx, &types.StateRoot{Version: uint64(st.version), Actors: root, Info: st.info})
return st.Store.Put(ctx, &types.StateRoot{Version: st.version, Actors: root, Info: st.info})
}

func (st *StateTree) Snapshot(ctx context.Context) error {
Expand Down Expand Up @@ -400,7 +424,7 @@ func (st *StateTree) ForEach(f func(address.Address, *types.Actor) error) error
}

// Version returns the version of the StateTree data structure in use.
func (st *StateTree) Version() actors.Version {
func (st *StateTree) Version() types.StateTreeVersion {
return st.version
}

Expand Down
13 changes: 6 additions & 7 deletions chain/state/statetree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@ import (
"github.com/filecoin-project/specs-actors/actors/builtin"

"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
)

func BenchmarkStateTreeSet(b *testing.B) {
cst := cbor.NewMemCborStore()
st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion))
st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion))
if err != nil {
b.Fatal(err)
}
Expand All @@ -46,7 +45,7 @@ func BenchmarkStateTreeSet(b *testing.B) {

func BenchmarkStateTreeSetFlush(b *testing.B) {
cst := cbor.NewMemCborStore()
st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion))
st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion))
if err != nil {
b.Fatal(err)
}
Expand Down Expand Up @@ -76,7 +75,7 @@ func BenchmarkStateTreeSetFlush(b *testing.B) {

func BenchmarkStateTree10kGetActor(b *testing.B) {
cst := cbor.NewMemCborStore()
st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion))
st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion))
if err != nil {
b.Fatal(err)
}
Expand Down Expand Up @@ -118,7 +117,7 @@ func BenchmarkStateTree10kGetActor(b *testing.B) {

func TestSetCache(t *testing.T) {
cst := cbor.NewMemCborStore()
st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion))
st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion))
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -155,7 +154,7 @@ func TestSetCache(t *testing.T) {
func TestSnapshots(t *testing.T) {
ctx := context.Background()
cst := cbor.NewMemCborStore()
st, err := NewStateTree(cst, actors.VersionForNetwork(build.NewestNetworkVersion))
st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion))
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -239,7 +238,7 @@ func assertNotHas(t *testing.T, st *StateTree, addr address.Address) {
func TestStateTreeConsistency(t *testing.T) {
cst := cbor.NewMemCborStore()
// TODO: ActorUpgrade: this test tests pre actors v2
st, err := NewStateTree(cst, actors.VersionForNetwork(network.Version3))
st, err := NewStateTree(cst, VersionForNetwork(network.Version3))
if err != nil {
t.Fatal(err)
}
Expand Down
6 changes: 2 additions & 4 deletions chain/stmgr/forks.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
states2 "github.com/filecoin-project/specs-actors/v2/actors/states"

"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/adt"
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
"github.com/filecoin-project/lotus/chain/actors/builtin/multisig"
Expand Down Expand Up @@ -494,7 +493,7 @@ func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, roo

epoch := ts.Height() - 1

info, err := store.Put(ctx, new(types.StateInfo))
info, err := store.Put(ctx, new(types.StateInfo0))
if err != nil {
return cid.Undef, xerrors.Errorf("failed to create new state info for actors v2: %w", err)
}
Expand All @@ -518,8 +517,7 @@ func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, roo
}

newRoot, err := store.Put(ctx, &types.StateRoot{
// TODO: ActorUpgrade: should be state-tree specific, not just the actors version.
Version: actors.Version2,
Version: types.StateTreeVersion1,
Actors: newHamtRoot,
Info: info,
})
Expand Down
16 changes: 8 additions & 8 deletions chain/types/cbor_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 14 additions & 3 deletions chain/types/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,25 @@ package types

import "github.com/ipfs/go-cid"

// StateTreeVersion is the version of the state tree itself, independent of the
// network version or the actors version.
type StateTreeVersion uint64

const (
// StateTreeVersion0 corresponds to actors < v2.
StateTreeVersion0 StateTreeVersion = iota
// StateTreeVersion1 corresponds to actors >= v2.
StateTreeVersion1
)

type StateRoot struct {
// State root version. Versioned along with actors (for now).
Version uint64
// State tree version.
Version StateTreeVersion
// Actors tree. The structure depends on the state root version.
Actors cid.Cid
// Info. The structure depends on the state root version.
Info cid.Cid
}

// TODO: version this.
type StateInfo struct{}
type StateInfo0 struct{}
2 changes: 1 addition & 1 deletion extern/test-vectors
Submodule test-vectors updated 462 files
2 changes: 1 addition & 1 deletion gen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func main() {
types.ExpTipSet{},
types.BeaconEntry{},
types.StateRoot{},
types.StateInfo{},
types.StateInfo0{},
)
if err != nil {
fmt.Println(err)
Expand Down
3 changes: 2 additions & 1 deletion lotuspond/front/src/chain/methods.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@
"CompactPartitions",
"CompactSectorNumbers",
"ConfirmUpdateWorkerKey",
"RepayDebt"
"RepayDebt",
"ChangeOwnerAddress"
],
"fil/2/storagepower": [
"Send",
Expand Down