cross-version state tree diff
This commit is contained in:
parent
4cf0c105eb
commit
24ae9205fe
@ -1,6 +1,7 @@
|
|||||||
package state
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -391,3 +393,44 @@ func (st *StateTree) ForEach(f func(address.Address, *types.Actor) error) error
|
|||||||
return f(addr, &act)
|
return f(addr, &act)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Diff(oldTree, newTree *StateTree) (map[string]types.Actor, error) {
|
||||||
|
out := map[string]types.Actor{}
|
||||||
|
|
||||||
|
var (
|
||||||
|
ncval, ocval cbg.Deferred
|
||||||
|
buf = bytes.NewReader(nil)
|
||||||
|
)
|
||||||
|
if err := newTree.root.ForEach(&ncval, func(k string) error {
|
||||||
|
var act types.Actor
|
||||||
|
|
||||||
|
addr, err := address.NewFromBytes([]byte(k))
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("address in state tree was not valid: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
found, err := oldTree.root.Get(abi.AddrKey(addr), &ocval)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if found && bytes.Equal(ocval.Raw, ncval.Raw) {
|
||||||
|
return nil // not changed
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.Reset(ncval.Raw)
|
||||||
|
err = act.UnmarshalCBOR(buf)
|
||||||
|
buf.Reset(nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
out[addr.String()] = act
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
@ -16,7 +16,6 @@ import (
|
|||||||
|
|
||||||
cid "github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
@ -27,7 +26,6 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||||
@ -618,58 +616,19 @@ func (a *StateAPI) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *StateAPI) StateChangedActors(ctx context.Context, old cid.Cid, new cid.Cid) (map[string]types.Actor, error) {
|
func (a *StateAPI) StateChangedActors(ctx context.Context, old cid.Cid, new cid.Cid) (map[string]types.Actor, error) {
|
||||||
store := adt.WrapStore(ctx, cbor.NewCborStore(a.Chain.Blockstore()))
|
store := a.Chain.Store(ctx)
|
||||||
|
|
||||||
nh, err := adt.AsMap(store, new)
|
oldTree, err := state.LoadStateTree(store, old)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, xerrors.Errorf("failed to load old state tree: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
oh, err := adt.AsMap(store, old)
|
newTree, err := state.LoadStateTree(store, new)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, xerrors.Errorf("failed to load new state tree: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
out := map[string]types.Actor{}
|
state.Diff(oldTree, newTree)
|
||||||
|
|
||||||
var (
|
|
||||||
ncval, ocval cbg.Deferred
|
|
||||||
buf = bytes.NewReader(nil)
|
|
||||||
)
|
|
||||||
err = nh.ForEach(&ncval, func(k string) error {
|
|
||||||
var act types.Actor
|
|
||||||
|
|
||||||
addr, err := address.NewFromBytes([]byte(k))
|
|
||||||
if err != nil {
|
|
||||||
return xerrors.Errorf("address in state tree was not valid: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
found, err := oh.Get(abi.AddrKey(addr), &ocval)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if found && bytes.Equal(ocval.Raw, ncval.Raw) {
|
|
||||||
return nil // not changed
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.Reset(ncval.Raw)
|
|
||||||
err = act.UnmarshalCBOR(buf)
|
|
||||||
buf.Reset(nil)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
out[addr.String()] = act
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return out, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *StateAPI) StateMinerSectorCount(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MinerSectors, error) {
|
func (a *StateAPI) StateMinerSectorCount(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MinerSectors, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user