2020-08-05 12:20:13 +00:00
|
|
|
package state
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"compress/gzip"
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/filecoin-project/lotus/chain/state"
|
|
|
|
bs "github.com/filecoin-project/lotus/lib/blockstore"
|
2020-08-05 14:52:57 +00:00
|
|
|
"github.com/ipfs/go-cid"
|
2020-08-05 12:20:13 +00:00
|
|
|
"github.com/ipfs/go-hamt-ipld"
|
|
|
|
cbor "github.com/ipfs/go-ipld-cbor"
|
|
|
|
"github.com/ipfs/go-ipld-format"
|
|
|
|
"github.com/ipld/go-car"
|
|
|
|
)
|
|
|
|
|
|
|
|
// RecoverStateTree parses a car encoding of a state tree back to a structured format
|
2020-08-05 14:52:57 +00:00
|
|
|
func RecoverStateTree(ctx context.Context, raw []byte, root cid.Cid) (*state.StateTree, error) {
|
2020-08-05 12:20:13 +00:00
|
|
|
buf := bytes.NewBuffer(raw)
|
|
|
|
store := bs.NewTemporary()
|
|
|
|
gr, err := gzip.NewReader(buf)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer gr.Close()
|
|
|
|
|
|
|
|
ch, err := car.LoadCar(store, gr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-08-05 14:52:57 +00:00
|
|
|
|
2020-08-05 12:20:13 +00:00
|
|
|
cborstore := cbor.NewCborStore(store)
|
|
|
|
|
2020-08-05 14:52:57 +00:00
|
|
|
fmt.Printf("roots are %v\n", ch.Roots)
|
2020-08-05 12:20:13 +00:00
|
|
|
|
2020-08-05 14:52:57 +00:00
|
|
|
nd, err := hamt.LoadNode(ctx, cborstore, root, hamt.UseTreeBitWidth(5))
|
2020-08-05 12:20:13 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if err := nd.ForEach(ctx, func(k string, val interface{}) error {
|
|
|
|
n, ok := val.(format.Node)
|
|
|
|
if !ok {
|
|
|
|
fmt.Printf("hampt %s (not node): %+v\n", k, val)
|
|
|
|
} else {
|
|
|
|
fmt.Printf("%s: %#v\n", k, n)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-08-05 14:52:57 +00:00
|
|
|
return state.LoadStateTree(cborstore, root)
|
2020-08-05 12:20:13 +00:00
|
|
|
}
|