make state tree snapshots properly stack based
This commit is contained in:
parent
5076b2b950
commit
4e9e3f3dc3
@ -26,7 +26,7 @@ type StateTree struct {
|
||||
Store cbor.IpldStore
|
||||
|
||||
actorcache map[address.Address]*types.Actor
|
||||
snapshot cid.Cid
|
||||
snapshots []cid.Cid
|
||||
}
|
||||
|
||||
func NewStateTree(cst cbor.IpldStore) (*StateTree, error) {
|
||||
@ -134,7 +134,6 @@ func (st *StateTree) Flush(ctx context.Context) (cid.Cid, error) {
|
||||
return cid.Undef, err
|
||||
}
|
||||
}
|
||||
st.actorcache = make(map[address.Address]*types.Actor)
|
||||
|
||||
if err := st.root.Flush(ctx); err != nil {
|
||||
return cid.Undef, err
|
||||
@ -152,10 +151,14 @@ func (st *StateTree) Snapshot(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
st.snapshot = ss
|
||||
st.snapshots = append(st.snapshots, ss)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *StateTree) ClearSnapshot() {
|
||||
st.snapshots = st.snapshots[:len(st.snapshots)-1]
|
||||
}
|
||||
|
||||
func (st *StateTree) RegisterNewAddress(addr address.Address, act *types.Actor) (address.Address, error) {
|
||||
var out address.Address
|
||||
err := st.MutateActor(builtin.InitActorAddr, func(initact *types.Actor) error {
|
||||
@ -198,10 +201,12 @@ func (a *AdtStore) Context() context.Context {
|
||||
var _ adt.Store = (*AdtStore)(nil)
|
||||
|
||||
func (st *StateTree) Revert() error {
|
||||
nd, err := hamt.LoadNode(context.Background(), st.Store, st.snapshot, hamt.UseTreeBitWidth(5))
|
||||
revTo := st.snapshots[len(st.snapshots)-1]
|
||||
nd, err := hamt.LoadNode(context.Background(), st.Store, revTo, hamt.UseTreeBitWidth(5))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
st.actorcache = make(map[address.Address]*types.Actor)
|
||||
|
||||
st.root = nd
|
||||
return nil
|
||||
|
@ -2,9 +2,10 @@ package state
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
address "github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
@ -144,3 +145,85 @@ func TestSetCache(t *testing.T) {
|
||||
t.Error("nonce didn't match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnapshots(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
cst := cbor.NewMemCborStore()
|
||||
st, err := NewStateTree(cst)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var addrs []address.Address
|
||||
//for _, a := range []string{"t15ocrptbu4i5qucjvvwecihd7fqqgzb27pz5l5zy", "t1dpyvgavvl3f4ujlk6odedss54z6rt5gyuknsuva", "t1feiejbkcvozy7iltt2pxzuoq4d2kpbsusugan7a", "t3rgjfqybjx7bahuhfv7nwfg3tlm4i4zyvldfirjvzm5z5xwjoqbj3rfi2mpmlxpqwxxxafgpkjilqzpg7cefa"} {
|
||||
for _, a := range []string{"t0100", "t0101", "t0102", "t0103"} {
|
||||
addr, err := address.NewFromString(a)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
addrs = append(addrs, addr)
|
||||
}
|
||||
|
||||
if err := st.Snapshot(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := st.SetActor(addrs[0], &types.Actor{Code: builtin.AccountActorCodeID, Head: builtin.AccountActorCodeID, Balance: types.NewInt(55)}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
{ // sub call that will fail
|
||||
if err := st.Snapshot(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := st.SetActor(addrs[1], &types.Actor{Code: builtin.AccountActorCodeID, Head: builtin.AccountActorCodeID, Balance: types.NewInt(77)}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := st.Revert(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
st.ClearSnapshot()
|
||||
}
|
||||
|
||||
// more operations in top level call...
|
||||
if err := st.SetActor(addrs[2], &types.Actor{Code: builtin.AccountActorCodeID, Head: builtin.AccountActorCodeID, Balance: types.NewInt(123)}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
{ // sub call that succeeds
|
||||
if err := st.Snapshot(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := st.SetActor(addrs[3], &types.Actor{Code: builtin.AccountActorCodeID, Head: builtin.AccountActorCodeID, Balance: types.NewInt(5)}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
st.ClearSnapshot()
|
||||
}
|
||||
|
||||
if _, err := st.Flush(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assertHas(t, st, addrs[0])
|
||||
assertNotHas(t, st, addrs[1])
|
||||
assertHas(t, st, addrs[2])
|
||||
assertHas(t, st, addrs[3])
|
||||
}
|
||||
|
||||
func assertHas(t *testing.T, st *StateTree, addr address.Address) {
|
||||
_, err := st.GetActor(addr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func assertNotHas(t *testing.T, st *StateTree, addr address.Address) {
|
||||
_, err := st.GetActor(addr)
|
||||
if err == nil {
|
||||
t.Fatal("shouldnt have found actor", addr)
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
|
||||
suites "github.com/filecoin-project/chain-validation/suites"
|
||||
"github.com/filecoin-project/chain-validation/suites/message"
|
||||
"github.com/filecoin-project/chain-validation/suites/tipset"
|
||||
|
||||
factory "github.com/filecoin-project/lotus/chain/validation"
|
||||
)
|
||||
@ -35,7 +34,6 @@ var TestSuiteSkipper TestSkipper
|
||||
func init() {
|
||||
// initialize the test skipper with tests being skipped
|
||||
TestSuiteSkipper = TestSkipper{testSkips: []suites.TestCase{
|
||||
tipset.TestInternalMessageApplicationFailure,
|
||||
|
||||
// Fails due to gas mismatches
|
||||
message.TestPaych,
|
||||
|
@ -163,7 +163,18 @@ func (vmc *VMContext) Send(to address.Address, method abi.MethodNum, value types
|
||||
GasLimit: vmc.gasAvailable,
|
||||
}
|
||||
|
||||
st := vmc.state
|
||||
if err := st.Snapshot(ctx); err != nil {
|
||||
return nil, aerrors.Fatalf("snapshot failed: %s", err)
|
||||
}
|
||||
defer st.ClearSnapshot()
|
||||
|
||||
ret, err, _ := vmc.vm.send(ctx, msg, vmc, 0)
|
||||
if err != nil {
|
||||
if err := st.Revert(); err != nil {
|
||||
return nil, aerrors.Escalate(err, "failed to revert state tree after failed subcall")
|
||||
}
|
||||
}
|
||||
return ret, err
|
||||
}
|
||||
|
||||
@ -366,6 +377,7 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *VMContext,
|
||||
gasCharge uint64) ([]byte, aerrors.ActorError, *VMContext) {
|
||||
|
||||
st := vm.cstate
|
||||
|
||||
fromActor, err := st.GetActor(msg.From)
|
||||
if err != nil {
|
||||
return nil, aerrors.Absorb(err, 1, "could not find source actor"), nil
|
||||
@ -453,6 +465,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, msg *types.Message) (*ApplyRet,
|
||||
if err := st.Snapshot(ctx); err != nil {
|
||||
return nil, xerrors.Errorf("snapshot failed: %w", err)
|
||||
}
|
||||
defer st.ClearSnapshot()
|
||||
|
||||
fromActor, err := st.GetActor(msg.From)
|
||||
if err != nil {
|
||||
|
2
go.mod
2
go.mod
@ -116,5 +116,3 @@ replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v
|
||||
replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi
|
||||
|
||||
replace github.com/coreos/go-systemd => github.com/coreos/go-systemd/v22 v22.0.0
|
||||
|
||||
replace github.com/filecoin-project/specs-actors => ../specs-actors
|
||||
|
2
go.sum
2
go.sum
@ -133,6 +133,8 @@ github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.m
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200226200336-94c9b92b2775/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200302223606-0eaf97b10aaf h1:3IojVqJAD5IXMxvZ+WYx+LRbfSB/rOXpYBuHh6o3XkY=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200302223606-0eaf97b10aaf/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200304210626-21ee86aadcb9 h1:5/XkV9N7Zlidi2RYY/04BToD/XeQrudUseI7Gx6owl8=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200304210626-21ee86aadcb9/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 h1:EzDjxMg43q1tA2c0MV3tNbaontnHLplHyFF6M5KiVP0=
|
||||
|
Loading…
Reference in New Issue
Block a user