Merge branch 'master' into lotus-fountain-add-datacap
This commit is contained in:
@@ -35,6 +35,7 @@ import (
|
||||
badgerbs "github.com/filecoin-project/lotus/blockstore/badger"
|
||||
"github.com/filecoin-project/lotus/chain/consensus"
|
||||
"github.com/filecoin-project/lotus/chain/consensus/filcns"
|
||||
"github.com/filecoin-project/lotus/chain/index"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@@ -228,7 +229,7 @@ var importBenchCmd = &cli.Command{
|
||||
defer cs.Close() //nolint:errcheck
|
||||
|
||||
// TODO: We need to supply the actual beacon after v14
|
||||
stm, err := stmgr.NewStateManager(cs, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(verifier), filcns.DefaultUpgradeSchedule(), nil, metadataDs)
|
||||
stm, err := stmgr.NewStateManager(cs, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(verifier), filcns.DefaultUpgradeSchedule(), nil, metadataDs, index.DummyMsgIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
rice "github.com/GeertJohan/go.rice"
|
||||
@@ -22,6 +23,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
)
|
||||
|
||||
@@ -217,18 +219,34 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
to, err := address.NewFromString(r.FormValue("address"))
|
||||
if err != nil {
|
||||
addressInput := r.FormValue("address")
|
||||
|
||||
var filecoinAddress address.Address
|
||||
var decodeError error
|
||||
|
||||
if strings.HasPrefix(addressInput, "0x") {
|
||||
ethAddress, err := ethtypes.ParseEthAddress(addressInput)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
filecoinAddress, decodeError = ethAddress.ToFilecoinAddress()
|
||||
} else {
|
||||
filecoinAddress, decodeError = address.NewFromString(addressInput)
|
||||
}
|
||||
|
||||
if decodeError != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if to == address.Undef {
|
||||
if filecoinAddress == address.Undef {
|
||||
http.Error(w, "empty address", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Limit based on wallet address
|
||||
limiter := h.limiter.GetWalletLimiter(to.String())
|
||||
limiter := h.limiter.GetWalletLimiter(filecoinAddress.String())
|
||||
if !limiter.Allow() {
|
||||
http.Error(w, http.StatusText(http.StatusTooManyRequests)+": wallet limit", http.StatusTooManyRequests)
|
||||
return
|
||||
@@ -282,6 +300,7 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<div class="Index">
|
||||
<div class="Index-nodes">
|
||||
<div class="Index-node">
|
||||
[SENDING FUNDS]
|
||||
SENDING FUNDS
|
||||
</div>
|
||||
<div class="Index-node">
|
||||
<form action='/send' method='post' id='funds-form'>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<div class="Index">
|
||||
<div class="Index-nodes">
|
||||
<div class="Index-node">
|
||||
[LOTUS DEVNET FAUCET]
|
||||
LOTUS DEVNET FAUCET
|
||||
</div>
|
||||
<div class="Index-node">
|
||||
<a href="funds.html">[Send Funds]</a>
|
||||
<a href="funds.html">Send Funds</a>
|
||||
</div>
|
||||
<div class="Index-node">
|
||||
[LOTUS DEVNET GRANT DATACAP]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
body {
|
||||
font-family: 'monospace';
|
||||
background: #1f1f1f;
|
||||
color: #f0f0f0;
|
||||
font-family: 'Helvetica Neue', sans-serif;
|
||||
background-color: #f0f0f0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
@@ -9,21 +8,22 @@ body {
|
||||
.Index {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: #1a1a1a;
|
||||
color: #f0f0f0;
|
||||
font-family: monospace;
|
||||
background-color: #f0f0f0;
|
||||
color: #333;
|
||||
font-family: 'Helvetica Neue', sans-serif;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: auto 40vw auto;
|
||||
grid-template-rows: auto auto auto 3em;
|
||||
grid-template-areas:
|
||||
". . . ."
|
||||
". main main ."
|
||||
". . . ."
|
||||
"footer footer footer footer";
|
||||
". . . ."
|
||||
". main main ."
|
||||
". . . ."
|
||||
"footer footer footer footer";
|
||||
}
|
||||
|
||||
.Index-footer {
|
||||
background: #2a2a2a;
|
||||
background-color: #333;
|
||||
grid-area: footer;
|
||||
}
|
||||
|
||||
@@ -34,23 +34,49 @@ body {
|
||||
|
||||
.Index-nodes {
|
||||
grid-area: main;
|
||||
background: #2a2a2a;
|
||||
}
|
||||
|
||||
.Index-node {
|
||||
margin: 5px;
|
||||
padding: 15px;
|
||||
background: #1f1f1f;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #ccc;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #4c9aff;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
padding: 10px 20px;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #555;
|
||||
}
|
||||
|
||||
a:link {
|
||||
color: #50f020;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #50f020;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #30a00a;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
@@ -1166,7 +1166,7 @@ var actorConfirmChangeWorker = &cli.Command{
|
||||
var actorConfirmChangeBeneficiary = &cli.Command{
|
||||
Name: "confirm-change-beneficiary",
|
||||
Usage: "Confirm a beneficiary address change",
|
||||
ArgsUsage: "[minerAddress]",
|
||||
ArgsUsage: "[minerID]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "really-do-it",
|
||||
|
||||
@@ -325,14 +325,12 @@ func handleMiningInfo(ctx context.Context, cctx *cli.Context, fullapi v1api.Full
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
fmt.Println()
|
||||
|
||||
ws, err := nodeApi.WorkerStats(ctx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting worker stats: %w", err)
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
ws, err := nodeApi.WorkerStats(ctx)
|
||||
if err != nil {
|
||||
fmt.Printf("ERROR: getting worker stats: %s\n", err)
|
||||
} else {
|
||||
workersByType := map[string]int{
|
||||
sealtasks.WorkerSealing: 0,
|
||||
sealtasks.WorkerWindowPoSt: 0,
|
||||
|
||||
+16
-9
@@ -43,16 +43,16 @@ func main() {
|
||||
backupCmd,
|
||||
lcli.WithCategory("chain", actorCmd),
|
||||
lcli.WithCategory("chain", infoCmd),
|
||||
lcli.WithCategory("market", storageDealsCmd),
|
||||
lcli.WithCategory("market", retrievalDealsCmd),
|
||||
lcli.WithCategory("market", dataTransfersCmd),
|
||||
lcli.WithCategory("market", dagstoreCmd),
|
||||
lcli.WithCategory("market", indexProvCmd),
|
||||
lcli.WithCategory("market", setHidden(storageDealsCmd)),
|
||||
lcli.WithCategory("market", setHidden(retrievalDealsCmd)),
|
||||
lcli.WithCategory("market", setHidden(dataTransfersCmd)),
|
||||
lcli.WithCategory("market", setHidden(dagstoreCmd)),
|
||||
lcli.WithCategory("market", setHidden(indexProvCmd)),
|
||||
lcli.WithCategory("storage", sectorsCmd),
|
||||
lcli.WithCategory("storage", provingCmd),
|
||||
lcli.WithCategory("storage", storageCmd),
|
||||
lcli.WithCategory("storage", sealingCmd),
|
||||
lcli.WithCategory("retrieval", piecesCmd),
|
||||
lcli.WithCategory("retrieval", setHidden(piecesCmd)),
|
||||
}
|
||||
|
||||
jaeger := tracing.SetupJaegerTracing("lotus")
|
||||
@@ -86,6 +86,7 @@ func main() {
|
||||
// adapt the Net* commands to always hit the node running the markets
|
||||
// subsystem, as that is the only one that runs a libp2p node.
|
||||
netCmd := *lcli.NetCmd // make a copy.
|
||||
netCmd.Hidden = true
|
||||
prev := netCmd.Before
|
||||
netCmd.Before = func(c *cli.Context) error {
|
||||
if prev != nil {
|
||||
@@ -137,11 +138,12 @@ func main() {
|
||||
&cli.StringFlag{
|
||||
Name: FlagMarketsRepo,
|
||||
EnvVars: []string{"LOTUS_MARKETS_PATH"},
|
||||
Usage: fmt.Sprintf("Markets repo path"),
|
||||
Hidden: true,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "call-on-markets",
|
||||
Usage: "(experimental; may be removed) call this command against a markets node; use only with common commands like net, auth, pprof, etc. whose target may be ambiguous",
|
||||
Name: "call-on-markets",
|
||||
Usage: "(experimental; may be removed) call this command against a markets node; use only with common commands like net, auth, pprof, etc. whose target may be ambiguous",
|
||||
Hidden: true,
|
||||
},
|
||||
cliutil.FlagVeryVerbose,
|
||||
},
|
||||
@@ -190,3 +192,8 @@ func getActorAddress(ctx context.Context, cctx *cli.Context) (maddr address.Addr
|
||||
|
||||
return maddr, nil
|
||||
}
|
||||
|
||||
func setHidden(cmd *cli.Command) *cli.Command {
|
||||
cmd.Hidden = true
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ var sectorsCmd = &cli.Command{
|
||||
sectorsBatching,
|
||||
sectorsRefreshPieceMatchingCmd,
|
||||
sectorsCompactPartitionsCmd,
|
||||
sectorsUnsealCmd,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1392,6 +1393,12 @@ var sectorsRemoveCmd = &cli.Command{
|
||||
return xerrors.Errorf("could not parse sector number: %w", err)
|
||||
}
|
||||
|
||||
// Check if the sector exists
|
||||
_, err = minerAPI.SectorsStatus(ctx, abi.SectorNumber(id), false)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("sectorID %d has not been created yet: %w", id, err)
|
||||
}
|
||||
|
||||
return minerAPI.SectorRemove(ctx, abi.SectorNumber(id))
|
||||
},
|
||||
}
|
||||
@@ -1915,10 +1922,31 @@ var sectorsBatchingPendingCommit = &cli.Command{
|
||||
for _, sector := range pending {
|
||||
fmt.Println(sector.Number)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println("No sectors queued to be committed")
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
fmt.Print("Do you want to publish these sectors now? (yes/no): ")
|
||||
userInput, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return xerrors.Errorf("reading user input: %w", err)
|
||||
}
|
||||
userInput = strings.ToLower(strings.TrimSpace(userInput))
|
||||
|
||||
if userInput == "yes" {
|
||||
err := cctx.Set("publish-now", "true")
|
||||
if err != nil {
|
||||
return xerrors.Errorf("setting publish-now flag: %w", err)
|
||||
}
|
||||
return cctx.Command.Action(cctx)
|
||||
} else if userInput == "no" {
|
||||
return nil
|
||||
} else {
|
||||
fmt.Println("Invalid input. Please answer with 'yes' or 'no'.")
|
||||
return nil
|
||||
}
|
||||
|
||||
} else {
|
||||
fmt.Println("No sectors queued to be committed")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
@@ -1973,10 +2001,31 @@ var sectorsBatchingPendingPreCommit = &cli.Command{
|
||||
for _, sector := range pending {
|
||||
fmt.Println(sector.Number)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println("No sectors queued to be committed")
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
fmt.Print("Do you want to publish these sectors now? (yes/no): ")
|
||||
userInput, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return xerrors.Errorf("reading user input: %w", err)
|
||||
}
|
||||
userInput = strings.ToLower(strings.TrimSpace(userInput))
|
||||
|
||||
if userInput == "yes" {
|
||||
err := cctx.Set("publish-now", "true")
|
||||
if err != nil {
|
||||
return xerrors.Errorf("setting publish-now flag: %w", err)
|
||||
}
|
||||
return cctx.Command.Action(cctx)
|
||||
} else if userInput == "no" {
|
||||
return nil
|
||||
} else {
|
||||
fmt.Println("Invalid input. Please answer with 'yes' or 'no'.")
|
||||
return nil
|
||||
}
|
||||
|
||||
} else {
|
||||
fmt.Println("No sectors queued to be committed")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
@@ -2248,3 +2297,27 @@ var sectorsNumbersFreeCmd = &cli.Command{
|
||||
return minerAPI.SectorNumFree(ctx, cctx.Args().First())
|
||||
},
|
||||
}
|
||||
|
||||
var sectorsUnsealCmd = &cli.Command{
|
||||
Name: "unseal",
|
||||
Usage: "unseal a sector",
|
||||
ArgsUsage: "[sector number]",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
minerAPI, closer, err := lcli.GetStorageMinerAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
if cctx.NArg() != 1 {
|
||||
return lcli.IncorrectNumArgs(cctx)
|
||||
}
|
||||
|
||||
sectorNum, err := strconv.ParseUint(cctx.Args().Get(0), 10, 64)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("could not parse sector number: %w", err)
|
||||
}
|
||||
|
||||
return minerAPI.SectorUnseal(ctx, abi.SectorNumber(sectorNum))
|
||||
},
|
||||
}
|
||||
|
||||
@@ -968,7 +968,7 @@ var actorProposeChangeBeneficiary = &cli.Command{
|
||||
var actorConfirmChangeBeneficiary = &cli.Command{
|
||||
Name: "confirm-change-beneficiary",
|
||||
Usage: "Confirm a beneficiary address change",
|
||||
ArgsUsage: "[minerAddress]",
|
||||
ArgsUsage: "[minerID]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "really-do-it",
|
||||
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/consensus"
|
||||
"github.com/filecoin-project/lotus/chain/consensus/filcns"
|
||||
"github.com/filecoin-project/lotus/chain/gen/genesis"
|
||||
"github.com/filecoin-project/lotus/chain/index"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
@@ -513,7 +514,7 @@ var chainBalanceStateCmd = &cli.Command{
|
||||
cst := cbor.NewCborStore(bs)
|
||||
store := adt.WrapStore(ctx, cst)
|
||||
|
||||
sm, err := stmgr.NewStateManager(cs, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), nil, mds)
|
||||
sm, err := stmgr.NewStateManager(cs, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), nil, mds, index.DummyMsgIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -737,7 +738,7 @@ var chainPledgeCmd = &cli.Command{
|
||||
cst := cbor.NewCborStore(bs)
|
||||
store := adt.WrapStore(ctx, cst)
|
||||
|
||||
sm, err := stmgr.NewStateManager(cs, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), nil, mds)
|
||||
sm, err := stmgr.NewStateManager(cs, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), nil, mds, index.DummyMsgIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -0,0 +1,383 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
cliutil "github.com/filecoin-project/lotus/cli/util"
|
||||
)
|
||||
|
||||
var chainwatchCmd = &cli.Command{
|
||||
Name: "chainwatch",
|
||||
Usage: "lotus chainwatch",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "db",
|
||||
EnvVars: []string{"CHAINWATCH_DB"},
|
||||
Value: "./chainwatch.db",
|
||||
},
|
||||
},
|
||||
Subcommands: []*cli.Command{
|
||||
chainwatchRunCmd,
|
||||
chainwatchDotCmd,
|
||||
},
|
||||
}
|
||||
|
||||
var chainwatchDotCmd = &cli.Command{
|
||||
Name: "dot",
|
||||
Usage: "generate dot graphs",
|
||||
ArgsUsage: "<minHeight> <toseeHeight>",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
st, err := cwOpenStorage(cctx.String("db"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
minH, err := strconv.ParseInt(cctx.Args().Get(0), 10, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tosee, err := strconv.ParseInt(cctx.Args().Get(1), 10, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
maxH := minH + tosee
|
||||
|
||||
res, err := st.db.Query(`select block, parent, b.miner, b.height, p.height from block_parents
|
||||
inner join blocks b on block_parents.block = b.cid
|
||||
inner join blocks p on block_parents.parent = p.cid
|
||||
where b.height > ? and b.height < ?`, minH, maxH)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("digraph D {")
|
||||
|
||||
for res.Next() {
|
||||
var block, parent, miner string
|
||||
var height, ph uint64
|
||||
if err := res.Scan(&block, &parent, &miner, &height, &ph); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bc, err := cid.Parse(block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
has := st.hasBlock(bc)
|
||||
|
||||
col := crc32.Checksum([]byte(miner), crc32.MakeTable(crc32.Castagnoli))&0xc0c0c0c0 + 0x30303030
|
||||
|
||||
hasstr := ""
|
||||
if !has {
|
||||
//col = 0xffffffff
|
||||
hasstr = " UNSYNCED"
|
||||
}
|
||||
|
||||
nulls := height - ph - 1
|
||||
for i := uint64(0); i < nulls; i++ {
|
||||
name := block + "NP" + fmt.Sprint(i)
|
||||
|
||||
fmt.Printf("%s [label = \"NULL:%d\", fillcolor = \"#ffddff\", style=filled, forcelabels=true]\n%s -> %s\n",
|
||||
name, height-nulls+i, name, parent)
|
||||
|
||||
parent = name
|
||||
}
|
||||
|
||||
fmt.Printf("%s [label = \"%s:%d%s\", fillcolor = \"#%06x\", style=filled, forcelabels=true]\n%s -> %s\n", block, miner, height, hasstr, col, block, parent)
|
||||
}
|
||||
if res.Err() != nil {
|
||||
return res.Err()
|
||||
}
|
||||
|
||||
fmt.Println("}")
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var chainwatchRunCmd = &cli.Command{
|
||||
Name: "run",
|
||||
Usage: "Start lotus chainwatch",
|
||||
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := cliutil.GetFullNodeAPIV1(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := cliutil.ReqContext(cctx)
|
||||
|
||||
v, err := api.Version(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("Remote version: %s", v.Version)
|
||||
|
||||
st, err := cwOpenStorage(cctx.String("db")) // todo flag
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer st.close() // nolint:errcheck
|
||||
|
||||
cwRunSyncer(ctx, api, st)
|
||||
go cwSubBlocks(ctx, api, st)
|
||||
|
||||
<-ctx.Done()
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func cwSubBlocks(ctx context.Context, api api.FullNode, st *cwStorage) {
|
||||
sub, err := api.SyncIncomingBlocks(ctx)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for bh := range sub {
|
||||
err := st.storeHeaders(map[cid.Cid]*types.BlockHeader{
|
||||
bh.Cid(): bh,
|
||||
}, false)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cwRunSyncer(ctx context.Context, api api.FullNode, st *cwStorage) {
|
||||
notifs, err := api.ChainNotify(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go func() {
|
||||
for notif := range notifs {
|
||||
for _, change := range notif {
|
||||
switch change.Type {
|
||||
case store.HCCurrent:
|
||||
fallthrough
|
||||
case store.HCApply:
|
||||
syncHead(ctx, api, st, change.Val)
|
||||
case store.HCRevert:
|
||||
log.Warnf("revert todo")
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func syncHead(ctx context.Context, api api.FullNode, st *cwStorage, ts *types.TipSet) {
|
||||
log.Infof("Getting headers / actors")
|
||||
|
||||
toSync := map[cid.Cid]*types.BlockHeader{}
|
||||
toVisit := list.New()
|
||||
|
||||
for _, header := range ts.Blocks() {
|
||||
toVisit.PushBack(header)
|
||||
}
|
||||
|
||||
for toVisit.Len() > 0 {
|
||||
bh := toVisit.Remove(toVisit.Back()).(*types.BlockHeader)
|
||||
|
||||
if _, seen := toSync[bh.Cid()]; seen || st.hasBlock(bh.Cid()) {
|
||||
continue
|
||||
}
|
||||
|
||||
toSync[bh.Cid()] = bh
|
||||
|
||||
if len(toSync)%500 == 10 {
|
||||
log.Infof("todo: (%d) %s", len(toSync), bh.Cid())
|
||||
}
|
||||
|
||||
if len(bh.Parents) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if bh.Height <= 530000 {
|
||||
continue
|
||||
}
|
||||
|
||||
pts, err := api.ChainGetTipSet(ctx, types.NewTipSetKey(bh.Parents...))
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, header := range pts.Blocks() {
|
||||
toVisit.PushBack(header)
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("Syncing %d blocks", len(toSync))
|
||||
|
||||
log.Infof("Persisting headers")
|
||||
if err := st.storeHeaders(toSync, true); err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Infof("Sync done")
|
||||
}
|
||||
|
||||
type cwStorage struct {
|
||||
db *sql.DB
|
||||
|
||||
headerLk sync.Mutex
|
||||
}
|
||||
|
||||
func cwOpenStorage(dbSource string) (*cwStorage, error) {
|
||||
db, err := sql.Open("sqlite3", dbSource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
st := &cwStorage{db: db}
|
||||
|
||||
return st, st.setup()
|
||||
}
|
||||
|
||||
func (st *cwStorage) setup() error {
|
||||
tx, err := st.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = tx.Exec(`
|
||||
create table if not exists blocks
|
||||
(
|
||||
cid text not null
|
||||
constraint blocks_pk
|
||||
primary key,
|
||||
parentWeight numeric not null,
|
||||
parentStateRoot text not null,
|
||||
height int not null,
|
||||
miner text not null
|
||||
constraint blocks_id_address_map_miner_fk
|
||||
references id_address_map (address),
|
||||
timestamp int not null,
|
||||
vrfproof blob
|
||||
);
|
||||
|
||||
create unique index if not exists block_cid_uindex
|
||||
on blocks (cid);
|
||||
|
||||
create table if not exists blocks_synced
|
||||
(
|
||||
cid text not null
|
||||
constraint blocks_synced_pk
|
||||
primary key
|
||||
constraint blocks_synced_blocks_cid_fk
|
||||
references blocks,
|
||||
add_ts int not null
|
||||
);
|
||||
|
||||
create unique index if not exists blocks_synced_cid_uindex
|
||||
on blocks_synced (cid);
|
||||
|
||||
create table if not exists block_parents
|
||||
(
|
||||
block text not null
|
||||
constraint block_parents_blocks_cid_fk
|
||||
references blocks,
|
||||
parent text not null
|
||||
constraint block_parents_blocks_cid_fk_2
|
||||
references blocks
|
||||
);
|
||||
|
||||
create unique index if not exists block_parents_block_parent_uindex
|
||||
on block_parents (block, parent);
|
||||
|
||||
create unique index if not exists blocks_cid_uindex
|
||||
on blocks (cid);
|
||||
`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (st *cwStorage) hasBlock(bh cid.Cid) bool {
|
||||
var exitsts bool
|
||||
err := st.db.QueryRow(`select exists (select 1 FROM blocks_synced where cid=?)`, bh.String()).Scan(&exitsts)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return false
|
||||
}
|
||||
return exitsts
|
||||
}
|
||||
|
||||
func (st *cwStorage) storeHeaders(bhs map[cid.Cid]*types.BlockHeader, sync bool) error {
|
||||
st.headerLk.Lock()
|
||||
defer st.headerLk.Unlock()
|
||||
|
||||
tx, err := st.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stmt, err := tx.Prepare(`insert into blocks (cid, parentWeight, parentStateRoot, height, miner, "timestamp", vrfproof) values (?, ?, ?, ?, ?, ?, ?) on conflict do nothing`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer stmt.Close() // nolint:errcheck
|
||||
for _, bh := range bhs {
|
||||
if _, err := stmt.Exec(bh.Cid().String(),
|
||||
bh.ParentWeight.String(),
|
||||
bh.ParentStateRoot.String(),
|
||||
bh.Height,
|
||||
bh.Miner.String(),
|
||||
bh.Timestamp,
|
||||
bh.Ticket.VRFProof,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
stmt2, err := tx.Prepare(`insert into block_parents (block, parent) values (?, ?) on conflict do nothing`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer stmt2.Close() // nolint:errcheck
|
||||
for _, bh := range bhs {
|
||||
for _, parent := range bh.Parents {
|
||||
if _, err := stmt2.Exec(bh.Cid().String(), parent.String()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if sync {
|
||||
stmt, err := tx.Prepare(`insert into blocks_synced (cid, add_ts) values (?, ?) on conflict do nothing`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer stmt.Close() // nolint:errcheck
|
||||
now := time.Now().Unix()
|
||||
|
||||
for _, bh := range bhs {
|
||||
if _, err := stmt.Exec(bh.Cid().String(), now); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (st *cwStorage) close() error {
|
||||
return st.db.Close()
|
||||
}
|
||||
@@ -12,8 +12,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/dgraph-io/badger/v2/y"
|
||||
block "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-cid"
|
||||
block "github.com/ipfs/go-libipfs/blocks"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/multiformats/go-base32"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
@@ -15,11 +15,11 @@ import (
|
||||
"github.com/dgraph-io/badger/v2"
|
||||
"github.com/dgraph-io/badger/v2/pb"
|
||||
"github.com/dustin/go-humanize"
|
||||
block "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-blockservice"
|
||||
"github.com/ipfs/go-cid"
|
||||
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
||||
ipld "github.com/ipfs/go-ipld-format"
|
||||
block "github.com/ipfs/go-libipfs/blocks"
|
||||
"github.com/ipfs/go-merkledag"
|
||||
"github.com/ipld/go-car"
|
||||
"github.com/multiformats/go-base32"
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/net/context"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
|
||||
badgerbs "github.com/filecoin-project/lotus/blockstore/badger"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
evm2 "github.com/filecoin-project/lotus/chain/actors/builtin/evm"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/node/repo"
|
||||
)
|
||||
|
||||
var FevmAnalyticsCmd = &cli.Command{
|
||||
Name: "evm-analytics",
|
||||
Usage: "Get FEVM related metrics",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "repo",
|
||||
Value: "~/.lotus",
|
||||
},
|
||||
},
|
||||
Subcommands: []*cli.Command{
|
||||
FevmBalanceCmd,
|
||||
FevmActorsCmd,
|
||||
},
|
||||
}
|
||||
|
||||
var FevmBalanceCmd = &cli.Command{
|
||||
Name: "evm-balance",
|
||||
Usage: "Balances in eth accounts, evm contracts and placeholders",
|
||||
ArgsUsage: "[state root]",
|
||||
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if cctx.NArg() != 1 {
|
||||
return xerrors.New("only needs state root")
|
||||
}
|
||||
|
||||
if !cctx.Args().Present() {
|
||||
return fmt.Errorf("must pass state root")
|
||||
}
|
||||
|
||||
sroot, err := cid.Decode(cctx.Args().First())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse input: %w", err)
|
||||
}
|
||||
|
||||
fsrepo, err := repo.NewFS(cctx.String("repo"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lkrepo, err := fsrepo.Lock(repo.FullNode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer lkrepo.Close() //nolint:errcheck
|
||||
|
||||
path, err := lkrepo.SplitstorePath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path = filepath.Join(path, "hot.badger")
|
||||
if err := os.MkdirAll(path, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
opts, err := repo.BadgerBlockstoreOptions(repo.HotBlockstore, path, lkrepo.Readonly())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bs, err := badgerbs.Open(opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cst := cbor.NewCborStore(bs)
|
||||
st, err := state.LoadStateTree(cst, sroot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("iterating over all actors")
|
||||
count := 0
|
||||
balanceEvm := abi.NewTokenAmount(0)
|
||||
balanceEthAccount := abi.NewTokenAmount(0)
|
||||
balancePlaceholder := abi.NewTokenAmount(0)
|
||||
|
||||
err = st.ForEach(func(addr address.Address, act *types.Actor) error {
|
||||
if count%200000 == 0 {
|
||||
fmt.Println("processed /n", count)
|
||||
}
|
||||
count++
|
||||
|
||||
if builtin.IsEvmActor(act.Code) {
|
||||
balanceEvm = types.BigAdd(balanceEvm, act.Balance)
|
||||
}
|
||||
|
||||
if builtin.IsEthAccountActor(act.Code) {
|
||||
balanceEthAccount = types.BigAdd(balanceEthAccount, act.Balance)
|
||||
}
|
||||
|
||||
if builtin.IsPlaceholderActor(act.Code) {
|
||||
balancePlaceholder = types.BigAdd(balancePlaceholder, act.Balance)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("balances in Eth contracts: ", balanceEvm)
|
||||
fmt.Println("balances in Eth accounts: ", balanceEthAccount)
|
||||
fmt.Println("balances in placeholder: ", balancePlaceholder)
|
||||
fmt.Println("Total balances: ", big.Add(big.Add(balanceEthAccount, balancePlaceholder), balanceEvm))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var FevmActorsCmd = &cli.Command{
|
||||
Name: "evm-actors",
|
||||
Usage: "actors # in eth accounts, evm contracts and placeholders",
|
||||
ArgsUsage: "[state root]",
|
||||
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if cctx.NArg() != 1 {
|
||||
return xerrors.New("only needs state root")
|
||||
}
|
||||
|
||||
if !cctx.Args().Present() {
|
||||
return fmt.Errorf("must pass state root")
|
||||
}
|
||||
|
||||
sroot, err := cid.Decode(cctx.Args().First())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse input: %w", err)
|
||||
}
|
||||
|
||||
fsrepo, err := repo.NewFS(cctx.String("repo"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lkrepo, err := fsrepo.Lock(repo.FullNode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer lkrepo.Close() //nolint:errcheck
|
||||
|
||||
path, err := lkrepo.SplitstorePath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path = filepath.Join(path, "hot.badger")
|
||||
if err := os.MkdirAll(path, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
opts, err := repo.BadgerBlockstoreOptions(repo.HotBlockstore, path, lkrepo.Readonly())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bs, err := badgerbs.Open(opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
cst := cbor.NewCborStore(bs)
|
||||
store := adt.WrapStore(ctx, cst)
|
||||
|
||||
st, err := state.LoadStateTree(cst, sroot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("iterating over all actors")
|
||||
count := 0
|
||||
EvmCount := 0
|
||||
EthAccountCount := 0
|
||||
PlaceholderCount := 0
|
||||
ea := []cid.Cid{}
|
||||
|
||||
err = st.ForEach(func(addr address.Address, act *types.Actor) error {
|
||||
if count%200000 == 0 {
|
||||
fmt.Println("processed /n", count)
|
||||
}
|
||||
count++
|
||||
|
||||
if builtin.IsEvmActor(act.Code) {
|
||||
EvmCount++
|
||||
e, err := evm2.Load(store, act)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fail to load evm actor: %w", err)
|
||||
}
|
||||
bcid, err := e.GetBytecodeCID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ea = append(ea, bcid)
|
||||
}
|
||||
|
||||
if builtin.IsEthAccountActor(act.Code) {
|
||||
EthAccountCount++
|
||||
}
|
||||
|
||||
if builtin.IsPlaceholderActor(act.Code) {
|
||||
PlaceholderCount++
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
uniquesa := unique(ea)
|
||||
fmt.Println("# of EVM contracts: ", EvmCount)
|
||||
fmt.Println("# of unqiue EVM contracts: ", len(uniquesa))
|
||||
fmt.Println("b# of Eth accounts: ", EthAccountCount)
|
||||
fmt.Println("# of placeholder: ", PlaceholderCount)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func unique(intSlice []cid.Cid) []cid.Cid {
|
||||
keys := make(map[cid.Cid]bool)
|
||||
list := []cid.Cid{}
|
||||
for _, entry := range intSlice {
|
||||
if _, value := keys[entry]; !value {
|
||||
keys[entry] = true
|
||||
list = append(list, entry)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/beacon/drand"
|
||||
"github.com/filecoin-project/lotus/chain/consensus"
|
||||
"github.com/filecoin-project/lotus/chain/consensus/filcns"
|
||||
"github.com/filecoin-project/lotus/chain/index"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@@ -111,7 +112,7 @@ var gasTraceCmd = &cli.Command{
|
||||
cs := store.NewChainStore(bs, bs, mds, filcns.Weight, nil)
|
||||
defer cs.Close() //nolint:errcheck
|
||||
|
||||
sm, err := stmgr.NewStateManager(cs, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), shd, mds)
|
||||
sm, err := stmgr.NewStateManager(cs, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), shd, mds, index.DummyMsgIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -212,7 +213,7 @@ var replayOfflineCmd = &cli.Command{
|
||||
cs := store.NewChainStore(bs, bs, mds, filcns.Weight, nil)
|
||||
defer cs.Close() //nolint:errcheck
|
||||
|
||||
sm, err := stmgr.NewStateManager(cs, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), shd, mds)
|
||||
sm, err := stmgr.NewStateManager(cs, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), shd, mds, index.DummyMsgIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
block "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-cid"
|
||||
block "github.com/ipfs/go-libipfs/blocks"
|
||||
"github.com/ipld/go-car"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/consensus"
|
||||
"github.com/filecoin-project/lotus/chain/consensus/filcns"
|
||||
"github.com/filecoin-project/lotus/chain/index"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@@ -90,7 +91,7 @@ var invariantsCmd = &cli.Command{
|
||||
cs := store.NewChainStore(bs, bs, mds, filcns.Weight, nil)
|
||||
defer cs.Close() //nolint:errcheck
|
||||
|
||||
sm, err := stmgr.NewStateManager(cs, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), nil, mds)
|
||||
sm, err := stmgr.NewStateManager(cs, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), nil, mds, index.DummyMsgIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ func main() {
|
||||
base32Cmd,
|
||||
base16Cmd,
|
||||
bitFieldCmd,
|
||||
chainwatchCmd,
|
||||
cronWcCmd,
|
||||
frozenMinersCmd,
|
||||
dealLabelCmd,
|
||||
@@ -83,6 +84,9 @@ func main() {
|
||||
invariantsCmd,
|
||||
gasTraceCmd,
|
||||
replayOfflineCmd,
|
||||
msgindexCmd,
|
||||
FevmAnalyticsCmd,
|
||||
mismatchesCmd,
|
||||
}
|
||||
|
||||
app := &cli.App{
|
||||
|
||||
+15
-20
@@ -7,7 +7,6 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-datastore"
|
||||
dsq "github.com/ipfs/go-datastore/query"
|
||||
levelds "github.com/ipfs/go-ds-leveldb"
|
||||
@@ -65,26 +64,22 @@ var marketCronStateCmd = &cli.Command{
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a, err := api.StateReadState(ctx, builtin.StorageMarketActorAddr, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
st, ok := a.State.(map[string]interface{})
|
||||
if !ok {
|
||||
return xerrors.Errorf("failed to cast state map to expected form")
|
||||
}
|
||||
dealOpsRaw, ok := st["DealOpsByEpoch"].(map[string]interface{})
|
||||
if !ok {
|
||||
return xerrors.Errorf("failed to read sectors root from state")
|
||||
}
|
||||
// string is of the form "/:bafy.." so [2:] to drop the path
|
||||
dealOpsRoot, err := cid.Parse(dealOpsRaw["/"])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bs := ReadOnlyAPIBlockstore{api}
|
||||
adtStore := adt.WrapStore(ctx, ipldcbor.NewCborStore(&bs))
|
||||
dealOpsEpochSet, err := adt.AsMap(adtStore, dealOpsRoot, builtin.DefaultHamtBitwidth)
|
||||
|
||||
mAct, err := api.StateGetActor(ctx, builtin.StorageMarketActorAddr, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var mSt market11.State
|
||||
err = adtStore.Get(ctx, mAct.Head, &mSt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dealOpsEpochSet, err := adt.AsMap(adtStore, mSt.DealOpsByEpoch, builtin.DefaultHamtBitwidth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -100,7 +95,7 @@ var marketCronStateCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
dealOpsMultiMap, err := market11.AsSetMultimap(adtStore, dealOpsRoot, builtin.DefaultHamtBitwidth, builtin.DefaultHamtBitwidth)
|
||||
dealOpsMultiMap, err := market11.AsSetMultimap(adtStore, mSt.DealOpsByEpoch, builtin.DefaultHamtBitwidth, builtin.DefaultHamtBitwidth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/lotus/chain/consensus"
|
||||
"github.com/filecoin-project/lotus/chain/consensus/filcns"
|
||||
"github.com/filecoin-project/lotus/chain/index"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
@@ -72,6 +73,7 @@ var migrationsCmd = &cli.Command{
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
fmt.Println("REMINDER: If you are running this, you likely want to ALSO run the continuity testing tool!")
|
||||
ctx := context.TODO()
|
||||
|
||||
if cctx.NArg() != 2 {
|
||||
@@ -155,7 +157,7 @@ var migrationsCmd = &cli.Command{
|
||||
defer cs.Close() //nolint:errcheck
|
||||
|
||||
// Note: we use a map datastore for the metadata to avoid writing / using cached migration results in the metadata store
|
||||
sm, err := stmgr.NewStateManager(cs, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), nil, datastore.NewMapDatastore())
|
||||
sm, err := stmgr.NewStateManager(cs, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), nil, datastore.NewMapDatastore(), index.DummyMsgIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/go-units"
|
||||
block "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-cid"
|
||||
ipldcbor "github.com/ipfs/go-ipld-cbor"
|
||||
block "github.com/ipfs/go-libipfs/blocks"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/urfave/cli/v2"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
)
|
||||
|
||||
var mismatchesCmd = &cli.Command{
|
||||
Name: "mismatches",
|
||||
Description: "Walk up the chain, recomputing state, and reporting any mismatches",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
srv, err := lcli.GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
api := srv.FullNodeAPI()
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
checkTs, err := api.ChainHead(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for checkTs.Height() != 0 {
|
||||
if checkTs.Height()%10000 == 0 {
|
||||
fmt.Println("Reached height ", checkTs.Height())
|
||||
}
|
||||
|
||||
execTsk := checkTs.Parents()
|
||||
execTs, err := api.ChainGetTipSet(ctx, execTsk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
st, err := api.StateCompute(ctx, execTs.Height(), nil, execTsk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if st.Root != checkTs.ParentState() {
|
||||
fmt.Println("consensus mismatch found at height ", execTs.Height())
|
||||
}
|
||||
|
||||
checkTs = execTs
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
)
|
||||
|
||||
var msgindexCmd = &cli.Command{
|
||||
Name: "msgindex",
|
||||
Usage: "Tools for managing the message index",
|
||||
Subcommands: []*cli.Command{
|
||||
msgindexBackfillCmd,
|
||||
msgindexPruneCmd,
|
||||
},
|
||||
}
|
||||
|
||||
var msgindexBackfillCmd = &cli.Command{
|
||||
Name: "backfill",
|
||||
Usage: "Backfill the message index for a number of epochs starting from a specified height",
|
||||
Flags: []cli.Flag{
|
||||
&cli.IntFlag{
|
||||
Name: "from",
|
||||
Value: 0,
|
||||
Usage: "height to start the backfill; uses the current head if omitted",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "epochs",
|
||||
Value: 1800,
|
||||
Usage: "number of epochs to backfill; defaults to 1800 (2 finalities)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "repo",
|
||||
Value: "~/.lotus",
|
||||
Usage: "path to the repo",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer closer()
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
curTs, err := api.ChainHead(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
startHeight := int64(cctx.Int("from"))
|
||||
if startHeight == 0 {
|
||||
startHeight = int64(curTs.Height()) - 1
|
||||
}
|
||||
epochs := cctx.Int("epochs")
|
||||
|
||||
basePath, err := homedir.Expand(cctx.String("repo"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dbPath := path.Join(basePath, "sqlite", "msgindex.db")
|
||||
db, err := sql.Open("sqlite3", dbPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
err := db.Close()
|
||||
if err != nil {
|
||||
fmt.Printf("ERROR: closing db: %s", err)
|
||||
}
|
||||
}()
|
||||
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
insertStmt, err := tx.Prepare("INSERT INTO messages VALUES (?, ?, ?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
insertMsg := func(cid, tsCid cid.Cid, epoch abi.ChainEpoch) error {
|
||||
key := cid.String()
|
||||
tskey := tsCid.String()
|
||||
if _, err := insertStmt.Exec(key, tskey, int64(epoch)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
rollback := func() {
|
||||
if err := tx.Rollback(); err != nil {
|
||||
fmt.Printf("ERROR: rollback: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < epochs; i++ {
|
||||
epoch := abi.ChainEpoch(startHeight - int64(i))
|
||||
|
||||
ts, err := api.ChainGetTipSetByHeight(ctx, epoch, curTs.Key())
|
||||
if err != nil {
|
||||
rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
tsCid, err := ts.Key().Cid()
|
||||
if err != nil {
|
||||
rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
msgs, err := api.ChainGetMessagesInTipset(ctx, ts.Key())
|
||||
if err != nil {
|
||||
rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
for _, msg := range msgs {
|
||||
if err := insertMsg(msg.Cid, tsCid, epoch); err != nil {
|
||||
rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var msgindexPruneCmd = &cli.Command{
|
||||
Name: "prune",
|
||||
Usage: "Prune the message index for messages included before a given epoch",
|
||||
Flags: []cli.Flag{
|
||||
&cli.IntFlag{
|
||||
Name: "from",
|
||||
Usage: "height to start the prune; if negative it indicates epochs from current head",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "repo",
|
||||
Value: "~/.lotus",
|
||||
Usage: "path to the repo",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer closer()
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
startHeight := int64(cctx.Int("from"))
|
||||
if startHeight < 0 {
|
||||
curTs, err := api.ChainHead(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
startHeight += int64(curTs.Height())
|
||||
|
||||
if startHeight < 0 {
|
||||
return xerrors.Errorf("bogus start height %d", startHeight)
|
||||
}
|
||||
}
|
||||
|
||||
basePath, err := homedir.Expand(cctx.String("repo"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dbPath := path.Join(basePath, "sqlite", "msgindex.db")
|
||||
db, err := sql.Open("sqlite3", dbPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
err := db.Close()
|
||||
if err != nil {
|
||||
fmt.Printf("ERROR: closing db: %s", err)
|
||||
}
|
||||
}()
|
||||
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := tx.Exec("DELETE FROM messages WHERE epoch < ?", startHeight); err != nil {
|
||||
if err := tx.Rollback(); err != nil {
|
||||
fmt.Printf("ERROR: rollback: %s", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/consensus"
|
||||
"github.com/filecoin-project/lotus/chain/consensus/filcns"
|
||||
"github.com/filecoin-project/lotus/chain/index"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@@ -308,7 +309,7 @@ to reduce the number of decode operations performed by caching the decoded objec
|
||||
}
|
||||
|
||||
tsExec := consensus.NewTipSetExecutor(filcns.RewardFunc)
|
||||
sm, err := stmgr.NewStateManager(cs, tsExec, vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), nil, mds)
|
||||
sm, err := stmgr.NewStateManager(cs, tsExec, vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), nil, mds, index.DummyMsgIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ func (sim *Simulation) makeTipSet(ctx context.Context, messages []*types.Message
|
||||
return nil, xerrors.Errorf("failed to create new tipset: %w", err)
|
||||
}
|
||||
|
||||
err = sim.Node.Chainstore.PersistTipset(ctx, newTipSet)
|
||||
err = sim.Node.Chainstore.PersistTipsets(ctx, []*types.TipSet{newTipSet})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to persist block headers: %w", err)
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/blockstore"
|
||||
"github.com/filecoin-project/lotus/chain/consensus"
|
||||
"github.com/filecoin-project/lotus/chain/consensus/filcns"
|
||||
"github.com/filecoin-project/lotus/chain/index"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@@ -106,7 +107,7 @@ func (nd *Node) LoadSim(ctx context.Context, name string) (*Simulation, error) {
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to create upgrade schedule for simulation %s: %w", name, err)
|
||||
}
|
||||
sim.StateManager, err = stmgr.NewStateManager(nd.Chainstore, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(mock.Verifier), us, nil, nd.MetadataDS)
|
||||
sim.StateManager, err = stmgr.NewStateManager(nd.Chainstore, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(mock.Verifier), us, nil, nd.MetadataDS, index.DummyMsgIndex)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to create state manager for simulation %s: %w", name, err)
|
||||
}
|
||||
@@ -125,7 +126,7 @@ func (nd *Node) CreateSim(ctx context.Context, name string, head *types.TipSet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sm, err := stmgr.NewStateManager(nd.Chainstore, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(mock.Verifier), filcns.DefaultUpgradeSchedule(), nil, nd.MetadataDS)
|
||||
sm, err := stmgr.NewStateManager(nd.Chainstore, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(mock.Verifier), filcns.DefaultUpgradeSchedule(), nil, nd.MetadataDS, index.DummyMsgIndex)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("creating state manager: %w", err)
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/consensus"
|
||||
"github.com/filecoin-project/lotus/chain/consensus/filcns"
|
||||
"github.com/filecoin-project/lotus/chain/index"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
@@ -201,7 +202,7 @@ func (sim *Simulation) SetUpgradeHeight(nv network.Version, epoch abi.ChainEpoch
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sm, err := stmgr.NewStateManager(sim.Node.Chainstore, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(mock.Verifier), newUpgradeSchedule, nil, sim.Node.MetadataDS)
|
||||
sm, err := stmgr.NewStateManager(sim.Node.Chainstore, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(mock.Verifier), newUpgradeSchedule, nil, sim.Node.MetadataDS, index.DummyMsgIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -275,6 +275,12 @@ var runCmd = &cli.Command{
|
||||
Name: "http-server-timeout",
|
||||
Value: "30s",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "data-cid",
|
||||
Usage: "Run the data-cid task. true|false",
|
||||
Value: true,
|
||||
DefaultText: "inherits --addpiece",
|
||||
},
|
||||
},
|
||||
Before: func(cctx *cli.Context) error {
|
||||
if cctx.IsSet("address") {
|
||||
@@ -295,6 +301,13 @@ var runCmd = &cli.Command{
|
||||
}
|
||||
}
|
||||
|
||||
// ensure tmpdir exists
|
||||
td := os.TempDir()
|
||||
if err := os.MkdirAll(td, 0755); err != nil {
|
||||
return xerrors.Errorf("ensuring temp dir %s exists: %w", td, err)
|
||||
}
|
||||
|
||||
// Check file descriptor limit
|
||||
limit, _, err := ulimit.GetLimit()
|
||||
switch {
|
||||
case err == ulimit.ErrUnsupported:
|
||||
@@ -379,8 +392,19 @@ var runCmd = &cli.Command{
|
||||
}
|
||||
}
|
||||
|
||||
ttDataCidDefault := false
|
||||
if (workerType == sealtasks.WorkerSealing || cctx.IsSet("addpiece")) && cctx.Bool("addpiece") {
|
||||
taskTypes = append(taskTypes, sealtasks.TTAddPiece, sealtasks.TTDataCid)
|
||||
taskTypes = append(taskTypes, sealtasks.TTAddPiece)
|
||||
ttDataCidDefault = true
|
||||
}
|
||||
if workerType == sealtasks.WorkerSealing {
|
||||
if cctx.IsSet("data-cid") {
|
||||
if cctx.Bool("data-cid") {
|
||||
taskTypes = append(taskTypes, sealtasks.TTDataCid)
|
||||
}
|
||||
} else if ttDataCidDefault {
|
||||
taskTypes = append(taskTypes, sealtasks.TTDataCid)
|
||||
}
|
||||
}
|
||||
if (workerType == sealtasks.WorkerSealing || cctx.IsSet("sector-download")) && cctx.Bool("sector-download") {
|
||||
taskTypes = append(taskTypes, sealtasks.TTDownloadSector)
|
||||
|
||||
+27
-11
@@ -10,8 +10,8 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"runtime/pprof"
|
||||
"strings"
|
||||
|
||||
@@ -34,6 +34,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/consensus"
|
||||
"github.com/filecoin-project/lotus/chain/consensus/filcns"
|
||||
"github.com/filecoin-project/lotus/chain/index"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@@ -41,10 +42,12 @@ import (
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
"github.com/filecoin-project/lotus/journal"
|
||||
"github.com/filecoin-project/lotus/journal/fsjournal"
|
||||
"github.com/filecoin-project/lotus/lib/httpreader"
|
||||
"github.com/filecoin-project/lotus/lib/peermgr"
|
||||
"github.com/filecoin-project/lotus/lib/ulimit"
|
||||
"github.com/filecoin-project/lotus/metrics"
|
||||
"github.com/filecoin-project/lotus/node"
|
||||
"github.com/filecoin-project/lotus/node/config"
|
||||
"github.com/filecoin-project/lotus/node/modules"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
"github.com/filecoin-project/lotus/node/modules/testing"
|
||||
@@ -431,18 +434,13 @@ func ImportChain(ctx context.Context, r repo.Repo, fname string, snapshot bool)
|
||||
var rd io.Reader
|
||||
var l int64
|
||||
if strings.HasPrefix(fname, "http://") || strings.HasPrefix(fname, "https://") {
|
||||
resp, err := http.Get(fname) //nolint:gosec
|
||||
rrd, err := httpreader.NewResumableReader(ctx, fname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close() //nolint:errcheck
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return xerrors.Errorf("fetching chain CAR failed with non-200 response: %d", resp.StatusCode)
|
||||
return xerrors.Errorf("fetching chain CAR failed: setting up resumable reader: %w", err)
|
||||
}
|
||||
|
||||
rd = resp.Body
|
||||
l = resp.ContentLength
|
||||
rd = rrd
|
||||
l = rrd.ContentLength()
|
||||
} else {
|
||||
fname, err = homedir.Expand(fname)
|
||||
if err != nil {
|
||||
@@ -539,7 +537,7 @@ func ImportChain(ctx context.Context, r repo.Repo, fname string, snapshot bool)
|
||||
}
|
||||
|
||||
// TODO: We need to supply the actual beacon after v14
|
||||
stm, err := stmgr.NewStateManager(cst, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), nil, mds)
|
||||
stm, err := stmgr.NewStateManager(cst, consensus.NewTipSetExecutor(filcns.RewardFunc), vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), nil, mds, index.DummyMsgIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -556,5 +554,23 @@ func ImportChain(ctx context.Context, r repo.Repo, fname string, snapshot bool)
|
||||
return err
|
||||
}
|
||||
|
||||
// populate the message index if user has EnableMsgIndex enabled
|
||||
//
|
||||
c, err := lr.Config()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg, ok := c.(*config.FullNode)
|
||||
if !ok {
|
||||
return xerrors.Errorf("invalid config for repo, got: %T", c)
|
||||
}
|
||||
if cfg.Index.EnableMsgIndex {
|
||||
log.Info("populating message index...")
|
||||
if err := index.PopulateAfterSnapshot(ctx, path.Join(lr.Path(), "sqlite"), cst); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info("populating message index done")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
+20
-6
@@ -7,18 +7,20 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/multiformats/go-multihash"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
actorstypes "github.com/filecoin-project/go-state-types/actors"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/consensus"
|
||||
)
|
||||
|
||||
@@ -67,6 +69,8 @@ var extractManyCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var actorCodeRegex = regexp.MustCompile(`^fil/(?P<version>\d+)/(?P<name>\w+)$`)
|
||||
|
||||
func runExtractMany(c *cli.Context) error {
|
||||
// LOTUS_DISABLE_VM_BUF disables what's called "VM state tree buffering",
|
||||
// which stashes write operations in a BufferedBlockstore
|
||||
@@ -114,8 +118,6 @@ func runExtractMany(c *cli.Context) error {
|
||||
log.Println(color.GreenString("csv sanity check succeeded; header contains fields: %v", header))
|
||||
}
|
||||
|
||||
codeCidBuilder := cid.V1Builder{Codec: cid.Raw, MhType: multihash.IDENTITY}
|
||||
|
||||
var (
|
||||
generated []string
|
||||
merr = new(multierror.Error)
|
||||
@@ -153,9 +155,21 @@ func runExtractMany(c *cli.Context) error {
|
||||
return fmt.Errorf("invalid method number: %s", methodnumstr)
|
||||
}
|
||||
|
||||
codeCid, err := codeCidBuilder.Sum([]byte(actorcode))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to compute actor code CID")
|
||||
// Lookup the code CID.
|
||||
var codeCid cid.Cid
|
||||
if matches := actorCodeRegex.FindStringSubmatch(actorcode); len(matches) == 3 {
|
||||
av, err := strconv.Atoi(matches[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid actor version %q in actor code %q", matches[1], actorcode)
|
||||
}
|
||||
an := matches[2]
|
||||
if k, ok := actors.GetActorCodeID(actorstypes.Version(av), an); ok {
|
||||
codeCid = k
|
||||
} else {
|
||||
return fmt.Errorf("unknown actor code %q", actorcode)
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("invalid actor code %q", actorcode)
|
||||
}
|
||||
|
||||
// Lookup the method in actor method table.
|
||||
|
||||
+1
-1
@@ -6,6 +6,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/fatih/color"
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-blockservice"
|
||||
"github.com/ipfs/go-cid"
|
||||
ds "github.com/ipfs/go-datastore"
|
||||
@@ -14,7 +15,6 @@ import (
|
||||
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
format "github.com/ipfs/go-ipld-format"
|
||||
blocks "github.com/ipfs/go-libipfs/blocks"
|
||||
"github.com/ipfs/go-merkledag"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user