lotus/tvx/state_delta.go

98 lines
1.9 KiB
Go
Raw Normal View History

package main
import (
"context"
"fmt"
"github.com/filecoin-project/lotus/chain/types"
"github.com/ipfs/go-cid"
"github.com/urfave/cli/v2"
)
var deltaFlags struct {
from string
to string
}
var deltaCmd = &cli.Command{
Name: "state-delta",
Description: "collect affected state between two tipsets, addressed by blocks",
Action: runStateDelta,
Flags: []cli.Flag{
&apiFlag,
&cli.StringFlag{
Name: "from",
Usage: "block CID of initial state",
Required: true,
Destination: &deltaFlags.from,
},
&cli.StringFlag{
Name: "to",
Usage: "block CID of ending state",
Required: true,
Destination: &deltaFlags.to,
},
},
}
func runStateDelta(c *cli.Context) error {
node, err := makeClient(c)
if err != nil {
return err
}
from, err := cid.Decode(deltaFlags.from)
if err != nil {
return err
}
to, err := cid.Decode(deltaFlags.to)
if err != nil {
return err
}
currBlock, err := node.ChainGetBlock(context.TODO(), to)
if err != nil {
return err
}
srcBlock, err := node.ChainGetBlock(context.TODO(), from)
if err != nil {
return err
}
allMsgs := make(map[uint64][]*types.Message)
epochs := currBlock.Height - srcBlock.Height - 1
for epochs > 0 {
msgs, err := node.ChainGetBlockMessages(context.TODO(), to)
if err != nil {
return err
}
allMsgs[uint64(currBlock.Height)] = msgs.BlsMessages
currBlock, err = node.ChainGetBlock(context.TODO(), currBlock.Parents[0])
epochs--
}
if !hasParent(currBlock, from) {
return fmt.Errorf("from block was not a parent of `to` as expected")
}
m := 0
for _, msgs := range allMsgs {
m += len(msgs)
}
fmt.Printf("messages: %d\n", m)
fmt.Printf("initial state root: %v\n", currBlock.ParentStateRoot)
return nil
}
func hasParent(block *types.BlockHeader, parent cid.Cid) bool {
for _, p := range block.Parents {
if p.Equals(parent) {
return true
}
}
return false
}