98 lines
1.9 KiB
Go
98 lines
1.9 KiB
Go
|
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
|
||
|
}
|