state tree version 5 scaffolding
This commit is contained in:
parent
046ca3fbb8
commit
674d127701
@ -14,6 +14,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"
|
||||||
|
builtin_types "github.com/filecoin-project/go-state-types/builtin"
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
states0 "github.com/filecoin-project/specs-actors/actors/states"
|
states0 "github.com/filecoin-project/specs-actors/actors/states"
|
||||||
states2 "github.com/filecoin-project/specs-actors/v2/actors/states"
|
states2 "github.com/filecoin-project/specs-actors/v2/actors/states"
|
||||||
@ -168,7 +169,7 @@ func NewStateTree(cst cbor.IpldStore, ver types.StateTreeVersion) (*StateTree, e
|
|||||||
switch ver {
|
switch ver {
|
||||||
case types.StateTreeVersion0:
|
case types.StateTreeVersion0:
|
||||||
// info is undefined
|
// info is undefined
|
||||||
case types.StateTreeVersion1, types.StateTreeVersion2, types.StateTreeVersion3, types.StateTreeVersion4:
|
case types.StateTreeVersion1, types.StateTreeVersion2, types.StateTreeVersion3, types.StateTreeVersion4, types.StateTreeVersion5:
|
||||||
var err error
|
var err error
|
||||||
info, err = cst.Put(context.TODO(), new(types.StateInfo0))
|
info, err = cst.Put(context.TODO(), new(types.StateInfo0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -211,6 +212,13 @@ func NewStateTree(cst cbor.IpldStore, ver types.StateTreeVersion) (*StateTree, e
|
|||||||
return nil, xerrors.Errorf("failed to create state tree: %w", err)
|
return nil, xerrors.Errorf("failed to create state tree: %w", err)
|
||||||
}
|
}
|
||||||
hamt = tree.Map
|
hamt = tree.Map
|
||||||
|
case types.StateTreeVersion5:
|
||||||
|
tree, err := builtin_types.NewTree(store)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to create state tree: %w", err)
|
||||||
|
}
|
||||||
|
hamt = tree.Map
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, xerrors.Errorf("unsupported state tree version: %d", ver)
|
return nil, xerrors.Errorf("unsupported state tree version: %d", ver)
|
||||||
}
|
}
|
||||||
@ -272,6 +280,13 @@ func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) {
|
|||||||
if tree != nil {
|
if tree != nil {
|
||||||
hamt = tree.Map
|
hamt = tree.Map
|
||||||
}
|
}
|
||||||
|
case types.StateTreeVersion5:
|
||||||
|
var tree *builtin_types.ActorTree
|
||||||
|
tree, err = builtin_types.LoadTree(store, root.Actors)
|
||||||
|
if tree != nil {
|
||||||
|
hamt = tree.Map
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, xerrors.Errorf("unsupported state tree version: %d", root.Version)
|
return nil, xerrors.Errorf("unsupported state tree version: %d", root.Version)
|
||||||
}
|
}
|
||||||
@ -370,7 +385,17 @@ func (st *StateTree) GetActor(addr address.Address) (*types.Actor, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var act types.Actor
|
var act types.Actor
|
||||||
if found, err := st.root.Get(abi.AddrKey(addr), &act); err != nil {
|
var found bool
|
||||||
|
if st.version <= types.StateTreeVersion4 {
|
||||||
|
var act4 types.ActorV4
|
||||||
|
found, err = st.root.Get(abi.AddrKey(addr), &act4)
|
||||||
|
if found {
|
||||||
|
act = *types.AsActorV5(&act4)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
found, err = st.root.Get(abi.AddrKey(addr), &act)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("hamt find failed: %w", err)
|
return nil, xerrors.Errorf("hamt find failed: %w", err)
|
||||||
} else if !found {
|
} else if !found {
|
||||||
return nil, types.ErrActorNotFound
|
return nil, types.ErrActorNotFound
|
||||||
@ -419,8 +444,15 @@ func (st *StateTree) Flush(ctx context.Context) (cid.Cid, error) {
|
|||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := st.root.Put(abi.AddrKey(addr), &sto.Act); err != nil {
|
if st.version <= types.StateTreeVersion4 {
|
||||||
return cid.Undef, err
|
act4 := types.AsActorV4(&sto.Act)
|
||||||
|
if err := st.root.Put(abi.AddrKey(addr), act4); err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := st.root.Put(abi.AddrKey(addr), &sto.Act); err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -528,22 +560,41 @@ func (st *StateTree) ForEach(f func(address.Address, *types.Actor) error) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now walk through the saved actors.
|
// Now walk through the saved actors.
|
||||||
var act types.Actor
|
if st.version <= types.StateTreeVersion4 {
|
||||||
return st.root.ForEach(&act, func(k string) error {
|
var act types.ActorV4
|
||||||
act := act // copy
|
return st.root.ForEach(&act, func(k string) error {
|
||||||
addr, err := address.NewFromBytes([]byte(k))
|
act := act // copy
|
||||||
if err != nil {
|
addr, err := address.NewFromBytes([]byte(k))
|
||||||
return xerrors.Errorf("invalid address (%x) found in state tree key: %w", []byte(k), err)
|
if err != nil {
|
||||||
}
|
return xerrors.Errorf("invalid address (%x) found in state tree key: %w", []byte(k), err)
|
||||||
|
}
|
||||||
|
|
||||||
// no need to record anything here, there are no duplicates in the actors HAMT
|
// no need to record anything here, there are no duplicates in the actors HAMT
|
||||||
// iself.
|
// iself.
|
||||||
if _, ok := seen[addr]; ok {
|
if _, ok := seen[addr]; ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return f(addr, &act)
|
return f(addr, types.AsActorV5(&act))
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
var act types.Actor
|
||||||
|
return st.root.ForEach(&act, func(k string) error {
|
||||||
|
act := act // copy
|
||||||
|
addr, err := address.NewFromBytes([]byte(k))
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("invalid address (%x) found in state tree key: %w", []byte(k), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// no need to record anything here, there are no duplicates in the actors HAMT
|
||||||
|
// iself.
|
||||||
|
if _, ok := seen[addr]; ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return f(addr, &act)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version returns the version of the StateTree data structure in use.
|
// Version returns the version of the StateTree data structure in use.
|
||||||
@ -563,8 +614,6 @@ func Diff(ctx context.Context, oldTree, newTree *StateTree) (map[string]types.Ac
|
|||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
default:
|
default:
|
||||||
var act types.Actor
|
|
||||||
|
|
||||||
addr, err := address.NewFromBytes([]byte(k))
|
addr, err := address.NewFromBytes([]byte(k))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("address in state tree was not valid: %w", err)
|
return xerrors.Errorf("address in state tree was not valid: %w", err)
|
||||||
@ -579,16 +628,33 @@ func Diff(ctx context.Context, oldTree, newTree *StateTree) (map[string]types.Ac
|
|||||||
return nil // not changed
|
return nil // not changed
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.Reset(ncval.Raw)
|
if newTree.version <= types.StateTreeVersion4 {
|
||||||
err = act.UnmarshalCBOR(buf)
|
var act types.ActorV4
|
||||||
buf.Reset(nil)
|
|
||||||
|
|
||||||
if err != nil {
|
buf.Reset(ncval.Raw)
|
||||||
return err
|
err = act.UnmarshalCBOR(buf)
|
||||||
|
buf.Reset(nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
out[addr.String()] = *types.AsActorV5(&act)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
var act types.Actor
|
||||||
|
|
||||||
|
buf.Reset(ncval.Raw)
|
||||||
|
err = act.UnmarshalCBOR(buf)
|
||||||
|
buf.Reset(nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
out[addr.String()] = act
|
||||||
}
|
}
|
||||||
|
|
||||||
out[addr.String()] = act
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
@ -4,14 +4,48 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrActorNotFound = errors.New("actor not found")
|
var ErrActorNotFound = errors.New("actor not found")
|
||||||
|
|
||||||
type Actor struct {
|
// Actor State for state tree version up to 4
|
||||||
|
type ActorV4 struct {
|
||||||
// Identifies the type of actor (string coded as a CID), see `chain/actors/actors.go`.
|
// Identifies the type of actor (string coded as a CID), see `chain/actors/actors.go`.
|
||||||
Code cid.Cid
|
Code cid.Cid
|
||||||
Head cid.Cid
|
Head cid.Cid
|
||||||
Nonce uint64
|
Nonce uint64
|
||||||
Balance BigInt
|
Balance BigInt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Actor State for state tree version 5
|
||||||
|
type ActorV5 struct {
|
||||||
|
// Identifies the type of actor (string coded as a CID), see `chain/actors/actors.go`.
|
||||||
|
Code cid.Cid
|
||||||
|
Head cid.Cid
|
||||||
|
Nonce uint64
|
||||||
|
Balance BigInt
|
||||||
|
// Predictable Address
|
||||||
|
Address *address.Address
|
||||||
|
}
|
||||||
|
|
||||||
|
type Actor = ActorV5
|
||||||
|
|
||||||
|
func AsActorV4(a *ActorV5) *ActorV4 {
|
||||||
|
return &ActorV4{
|
||||||
|
Code: a.Code,
|
||||||
|
Head: a.Head,
|
||||||
|
Nonce: a.Nonce,
|
||||||
|
Balance: a.Balance,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AsActorV5(a *ActorV4) *ActorV5 {
|
||||||
|
return &ActorV5{
|
||||||
|
Code: a.Code,
|
||||||
|
Head: a.Head,
|
||||||
|
Nonce: a.Nonce,
|
||||||
|
Balance: a.Balance,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -26,7 +26,8 @@ func main() {
|
|||||||
types.Message{},
|
types.Message{},
|
||||||
types.SignedMessage{},
|
types.SignedMessage{},
|
||||||
types.MsgMeta{},
|
types.MsgMeta{},
|
||||||
types.Actor{},
|
types.ActorV4{},
|
||||||
|
types.ActorV5{},
|
||||||
types.MessageReceipt{},
|
types.MessageReceipt{},
|
||||||
types.BlockMsg{},
|
types.BlockMsg{},
|
||||||
types.ExpTipSet{},
|
types.ExpTipSet{},
|
||||||
|
Loading…
Reference in New Issue
Block a user