Merge branch 'master' into chore/cleanup-chain
This commit is contained in:
commit
e163d556fb
@ -1,8 +1,16 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/png"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
@ -10,6 +18,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-bitfield"
|
"github.com/filecoin-project/go-bitfield"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
||||||
@ -18,6 +27,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
lcli "github.com/filecoin-project/lotus/cli"
|
lcli "github.com/filecoin-project/lotus/cli"
|
||||||
|
"github.com/filecoin-project/lotus/lib/parmap"
|
||||||
)
|
)
|
||||||
|
|
||||||
var sectorsCmd = &cli.Command{
|
var sectorsCmd = &cli.Command{
|
||||||
@ -27,6 +37,7 @@ var sectorsCmd = &cli.Command{
|
|||||||
Subcommands: []*cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
terminateSectorCmd,
|
terminateSectorCmd,
|
||||||
terminateSectorPenaltyEstimationCmd,
|
terminateSectorPenaltyEstimationCmd,
|
||||||
|
visAllocatedSectorsCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,3 +274,188 @@ var terminateSectorPenaltyEstimationCmd = &cli.Command{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var visAllocatedSectorsCmd = &cli.Command{
|
||||||
|
Name: "vis-allocated",
|
||||||
|
Usage: "Produces a html with visualisation of allocated sectors",
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer()
|
||||||
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
var miners []address.Address
|
||||||
|
if cctx.NArg() == 0 {
|
||||||
|
miners, err = api.StateListMiners(ctx, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
powCache := make(map[address.Address]types.BigInt)
|
||||||
|
var lk sync.Mutex
|
||||||
|
parmap.Par(32, miners, func(a address.Address) {
|
||||||
|
pow, err := api.StateMinerPower(ctx, a, types.EmptyTSK)
|
||||||
|
|
||||||
|
lk.Lock()
|
||||||
|
if err == nil {
|
||||||
|
powCache[a] = pow.MinerPower.QualityAdjPower
|
||||||
|
} else {
|
||||||
|
powCache[a] = types.NewInt(0)
|
||||||
|
}
|
||||||
|
lk.Unlock()
|
||||||
|
})
|
||||||
|
sort.Slice(miners, func(i, j int) bool {
|
||||||
|
return powCache[miners[i]].GreaterThan(powCache[miners[j]])
|
||||||
|
})
|
||||||
|
n := sort.Search(len(miners), func(i int) bool {
|
||||||
|
pow := powCache[miners[i]]
|
||||||
|
log.Infof("pow @%d = %s", i, pow)
|
||||||
|
return pow.IsZero()
|
||||||
|
})
|
||||||
|
miners = miners[:n]
|
||||||
|
} else {
|
||||||
|
for _, mS := range cctx.Args().Slice() {
|
||||||
|
mA, err := address.NewFromString(mS)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("parsing address '%s': %w", mS, err)
|
||||||
|
}
|
||||||
|
miners = append(miners, mA)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pngs := make([][]byte, len(miners))
|
||||||
|
for i := 0; i < len(miners); i++ {
|
||||||
|
func() {
|
||||||
|
state, err := api.StateReadState(ctx, miners[i], types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("getting state: %+v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
allocSString := state.State.(map[string]interface{})["AllocatedSectors"].(map[string]interface{})["/"].(string)
|
||||||
|
|
||||||
|
allocCid, err := cid.Decode(allocSString)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("decoding cid: %+v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rle, err := api.ChainReadObj(ctx, allocCid)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("reading AllocatedSectors: %+v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
png, err := rleToPng(rle)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("converting to png: %+v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pngs[i] = png
|
||||||
|
encoded := base64.StdEncoding.EncodeToString(pngs[i])
|
||||||
|
fmt.Printf(`%s:</br><img src="data:image/png;base64,%s"></br>`+"\n", miners[i], encoded)
|
||||||
|
_ = os.Stdout.Sync()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func rleToPng(rleBytes []byte) ([]byte, error) {
|
||||||
|
var bf bitfield.BitField
|
||||||
|
err := bf.UnmarshalCBOR(bytes.NewReader(rleBytes))
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("decoding bitfield: %w", err)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
last, err := bf.Last()
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("getting last: %w", err)
|
||||||
|
}
|
||||||
|
if last == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ri, err := bf.RunIterator()
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("creating interator: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const width = 1024
|
||||||
|
const skipTh = 64
|
||||||
|
const skipSize = 32
|
||||||
|
|
||||||
|
var size uint64
|
||||||
|
for ri.HasNext() {
|
||||||
|
run, err := ri.NextRun()
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("getting next run: %w", err)
|
||||||
|
}
|
||||||
|
if run.Len > skipTh*width {
|
||||||
|
size += run.Len%(2*width) + skipSize*width
|
||||||
|
} else {
|
||||||
|
size += run.Len
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img := image.NewRGBA(image.Rect(0, 0, width, int((size+width-1)/width)))
|
||||||
|
for i := range img.Pix {
|
||||||
|
img.Pix[i] = 255
|
||||||
|
}
|
||||||
|
|
||||||
|
ri, err = bf.RunIterator()
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("creating interator: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const shade = 15
|
||||||
|
idx := uint64(0)
|
||||||
|
realIdx := uint64(0)
|
||||||
|
for ri.HasNext() {
|
||||||
|
run, err := ri.NextRun()
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("getting next run: %w", err)
|
||||||
|
}
|
||||||
|
var cut = false
|
||||||
|
var oldLen uint64
|
||||||
|
if run.Len > skipTh*width {
|
||||||
|
oldLen = run.Len
|
||||||
|
run.Len = run.Len%(2*width) + skipSize*width
|
||||||
|
cut = true
|
||||||
|
}
|
||||||
|
for i := uint64(0); i < run.Len; i++ {
|
||||||
|
col := color.Gray{0}
|
||||||
|
stripe := (realIdx+i)/width%256 >= 128
|
||||||
|
if cut && i > skipSize*width/2 {
|
||||||
|
stripe = (realIdx+i+(skipSize/2*width))/width%256 >= 128
|
||||||
|
}
|
||||||
|
if !run.Val {
|
||||||
|
col.Y = 255
|
||||||
|
if stripe {
|
||||||
|
col.Y -= shade
|
||||||
|
}
|
||||||
|
} else if stripe {
|
||||||
|
col.Y += shade
|
||||||
|
}
|
||||||
|
img.Set(int((idx+i)%width), int((idx+i)/width), col)
|
||||||
|
}
|
||||||
|
if cut {
|
||||||
|
i := (idx + run.Len/2 + width) &^ (width - 1)
|
||||||
|
iend := i + width
|
||||||
|
col := color.RGBA{255, 0, 0, 255}
|
||||||
|
for ; i < iend; i++ {
|
||||||
|
img.Set(int(i)%width, int(i)/width, col)
|
||||||
|
}
|
||||||
|
realIdx += oldLen
|
||||||
|
idx += run.Len
|
||||||
|
} else {
|
||||||
|
realIdx += run.Len
|
||||||
|
idx += run.Len
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
err = png.Encode(buf, img)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("encoding png: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user