Merge branch 'master' into feat/chaos-inspect-runtime
This commit is contained in:
commit
4fbb322fa2
1
.gitignore
vendored
1
.gitignore
vendored
@ -11,6 +11,7 @@
|
||||
/lotus-stats
|
||||
/lotus-bench
|
||||
/lotus-gateway
|
||||
/lotus-pcr
|
||||
/bench.json
|
||||
/lotuspond/front/node_modules
|
||||
/lotuspond/front/build
|
||||
|
@ -354,6 +354,8 @@ type FullNode interface {
|
||||
StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*SectorLocation, error)
|
||||
// StateSearchMsg searches for a message in the chain, and returns its receipt and the tipset where it was executed
|
||||
StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error)
|
||||
// StateMsgGasCost searches for a message in the chain, and returns details of the messages gas costs, including the penalty and miner tip
|
||||
StateMsgGasCost(context.Context, cid.Cid, types.TipSetKey) (*MsgGasCost, error)
|
||||
// StateWaitMsg looks back in the chain for a message. If not found, it blocks until the
|
||||
// message arrives on chain, and gets to the indicated confidence depth.
|
||||
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*MsgLookup, error)
|
||||
@ -531,6 +533,17 @@ type MsgLookup struct {
|
||||
Height abi.ChainEpoch
|
||||
}
|
||||
|
||||
type MsgGasCost struct {
|
||||
Message cid.Cid // Can be different than requested, in case it was replaced, but only gas values changed
|
||||
GasUsed abi.TokenAmount
|
||||
BaseFeeBurn abi.TokenAmount
|
||||
OverEstimationBurn abi.TokenAmount
|
||||
MinerPenalty abi.TokenAmount
|
||||
MinerTip abi.TokenAmount
|
||||
Refund abi.TokenAmount
|
||||
TotalCost abi.TokenAmount
|
||||
}
|
||||
|
||||
type BlockMessages struct {
|
||||
BlsMessages []*types.Message
|
||||
SecpkMessages []*types.SignedMessage
|
||||
|
@ -183,6 +183,7 @@ type FullNodeStruct struct {
|
||||
StateReplay func(context.Context, types.TipSetKey, cid.Cid) (*api.InvocResult, error) `perm:"read"`
|
||||
StateGetActor func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) `perm:"read"`
|
||||
StateReadState func(context.Context, address.Address, types.TipSetKey) (*api.ActorState, error) `perm:"read"`
|
||||
StateMsgGasCost func(context.Context, cid.Cid, types.TipSetKey) (*api.MsgGasCost, error) `perm:"read"`
|
||||
StateWaitMsg func(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) `perm:"read"`
|
||||
StateSearchMsg func(context.Context, cid.Cid) (*api.MsgLookup, error) `perm:"read"`
|
||||
StateListMiners func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"`
|
||||
@ -816,6 +817,10 @@ func (c *FullNodeStruct) StateReadState(ctx context.Context, addr address.Addres
|
||||
return c.Internal.StateReadState(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMsgGasCost(ctx context.Context, msgc cid.Cid, tsk types.TipSetKey) (*api.MsgGasCost, error) {
|
||||
return c.Internal.StateMsgGasCost(ctx, msgc, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateWaitMsg(ctx context.Context, msgc cid.Cid, confidence uint64) (*api.MsgLookup, error) {
|
||||
return c.Internal.StateWaitMsg(ctx, msgc, confidence)
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ func init() {
|
||||
BuildType |= Build2k
|
||||
}
|
||||
|
||||
const BlockDelaySecs = uint64(30)
|
||||
const BlockDelaySecs = uint64(4)
|
||||
|
||||
const PropagationDelaySecs = uint64(1)
|
||||
|
||||
|
@ -233,8 +233,8 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
|
||||
}
|
||||
|
||||
receipts = append(receipts, &r.MessageReceipt)
|
||||
gasReward = big.Add(gasReward, r.MinerTip)
|
||||
penalty = big.Add(penalty, r.Penalty)
|
||||
gasReward = big.Add(gasReward, r.GasCosts.MinerTip)
|
||||
penalty = big.Add(penalty, r.GasCosts.MinerPenalty)
|
||||
|
||||
if cb != nil {
|
||||
if err := cb(cm.Cid(), m, r); err != nil {
|
||||
|
@ -554,7 +554,7 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule
|
||||
|
||||
sectors, err := GetSectorsForWinningPoSt(ctx, pv, sm, lbst, maddr, prand)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting wpost proving set: %w", err)
|
||||
return nil, xerrors.Errorf("getting winning post proving set: %w", err)
|
||||
}
|
||||
|
||||
if len(sectors) == 0 {
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
"github.com/filecoin-project/lotus/journal"
|
||||
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
||||
@ -767,32 +766,16 @@ type BlockMessages struct {
|
||||
func (cs *ChainStore) BlockMsgsForTipset(ts *types.TipSet) ([]BlockMessages, error) {
|
||||
applied := make(map[address.Address]uint64)
|
||||
|
||||
cst := cbor.NewCborStore(cs.bs)
|
||||
st, err := state.LoadStateTree(cst, ts.Blocks()[0].ParentStateRoot)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to load state tree")
|
||||
}
|
||||
|
||||
preloadAddr := func(a address.Address) error {
|
||||
if _, ok := applied[a]; !ok {
|
||||
act, err := st.GetActor(a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
applied[a] = act.Nonce
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
selectMsg := func(m *types.Message) (bool, error) {
|
||||
if err := preloadAddr(m.From); err != nil {
|
||||
return false, err
|
||||
// The first match for a sender is guaranteed to have correct nonce -- the block isn't valid otherwise
|
||||
if _, ok := applied[m.From]; !ok {
|
||||
applied[m.From] = m.Nonce
|
||||
}
|
||||
|
||||
if applied[m.From] != m.Nonce {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
applied[m.From]++
|
||||
|
||||
return true, nil
|
||||
|
@ -991,7 +991,7 @@ func (syncer *Syncer) VerifyWinningPoStProof(ctx context.Context, h *types.Block
|
||||
|
||||
rand, err := store.DrawRandomness(rbase.Data, crypto.DomainSeparationTag_WinningPoStChallengeSeed, h.Height, buf.Bytes())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get randomness for verifying winningPost proof: %w", err)
|
||||
return xerrors.Errorf("failed to get randomness for verifying winning post proof: %w", err)
|
||||
}
|
||||
|
||||
mid, err := address.IDFromAddress(h.Miner)
|
||||
|
@ -662,6 +662,49 @@ func TestDuplicateNonce(t *testing.T) {
|
||||
require.Equal(t, includedMsg, mft[0].VMMessage().Cid(), "messages for tipset didn't contain expected message")
|
||||
}
|
||||
|
||||
// This test asserts that a block that includes a message with bad nonce can't be synced. A nonce is "bad" if it can't
|
||||
// be applied on the parent state.
|
||||
func TestBadNonce(t *testing.T) {
|
||||
H := 10
|
||||
tu := prepSyncTest(t, H)
|
||||
|
||||
base := tu.g.CurTipset
|
||||
|
||||
// Produce a message from the banker with a bad nonce
|
||||
makeBadMsg := func() *types.SignedMessage {
|
||||
|
||||
ba, err := tu.nds[0].StateGetActor(context.TODO(), tu.g.Banker(), base.TipSet().Key())
|
||||
require.NoError(t, err)
|
||||
msg := types.Message{
|
||||
To: tu.g.Banker(),
|
||||
From: tu.g.Banker(),
|
||||
|
||||
Nonce: ba.Nonce + 5,
|
||||
|
||||
Value: types.NewInt(1),
|
||||
|
||||
Method: 0,
|
||||
|
||||
GasLimit: 100_000_000,
|
||||
GasFeeCap: types.NewInt(0),
|
||||
GasPremium: types.NewInt(0),
|
||||
}
|
||||
|
||||
sig, err := tu.g.Wallet().Sign(context.TODO(), tu.g.Banker(), msg.Cid().Bytes())
|
||||
require.NoError(t, err)
|
||||
|
||||
return &types.SignedMessage{
|
||||
Message: msg,
|
||||
Signature: *sig,
|
||||
}
|
||||
}
|
||||
|
||||
msgs := make([][]*types.SignedMessage, 1)
|
||||
msgs[0] = []*types.SignedMessage{makeBadMsg()}
|
||||
|
||||
tu.mineOnBlock(base, 0, []int{0}, true, true, msgs)
|
||||
}
|
||||
|
||||
func BenchmarkSyncBasic(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
runSyncBenchLength(b, 100)
|
||||
|
@ -22,6 +22,17 @@ type GasOutputs struct {
|
||||
GasBurned int64
|
||||
}
|
||||
|
||||
// ZeroGasOutputs returns a logically zeroed GasOutputs.
|
||||
func ZeroGasOutputs() GasOutputs {
|
||||
return GasOutputs{
|
||||
BaseFeeBurn: big.Zero(),
|
||||
OverEstimationBurn: big.Zero(),
|
||||
MinerPenalty: big.Zero(),
|
||||
MinerTip: big.Zero(),
|
||||
Refund: big.Zero(),
|
||||
}
|
||||
}
|
||||
|
||||
// ComputeGasOverestimationBurn computes amount of gas to be refunded and amount of gas to be burned
|
||||
// Result is (refund, burn)
|
||||
func ComputeGasOverestimationBurn(gasUsed, gasLimit int64) (int64, int64) {
|
||||
@ -58,13 +69,7 @@ func ComputeGasOverestimationBurn(gasUsed, gasLimit int64) (int64, int64) {
|
||||
|
||||
func ComputeGasOutputs(gasUsed, gasLimit int64, baseFee, feeCap, gasPremium abi.TokenAmount) GasOutputs {
|
||||
gasUsedBig := big.NewInt(gasUsed)
|
||||
out := GasOutputs{
|
||||
BaseFeeBurn: big.Zero(),
|
||||
OverEstimationBurn: big.Zero(),
|
||||
MinerPenalty: big.Zero(),
|
||||
MinerTip: big.Zero(),
|
||||
Refund: big.Zero(),
|
||||
}
|
||||
out := ZeroGasOutputs()
|
||||
|
||||
baseFeeToPay := baseFee
|
||||
if baseFee.Cmp(feeCap.Int) > 0 {
|
||||
|
@ -201,10 +201,9 @@ type Rand interface {
|
||||
type ApplyRet struct {
|
||||
types.MessageReceipt
|
||||
ActorErr aerrors.ActorError
|
||||
Penalty types.BigInt
|
||||
MinerTip types.BigInt
|
||||
ExecutionTrace types.ExecutionTrace
|
||||
Duration time.Duration
|
||||
GasCosts GasOutputs
|
||||
}
|
||||
|
||||
func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime,
|
||||
@ -328,8 +327,7 @@ func (vm *VM) ApplyImplicitMessage(ctx context.Context, msg *types.Message) (*Ap
|
||||
},
|
||||
ActorErr: actorErr,
|
||||
ExecutionTrace: rt.executionTrace,
|
||||
Penalty: types.NewInt(0),
|
||||
MinerTip: types.NewInt(0),
|
||||
GasCosts: GasOutputs{},
|
||||
Duration: time.Since(start),
|
||||
}, actorErr
|
||||
}
|
||||
@ -357,14 +355,15 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
msgGasCost := msgGas.Total()
|
||||
// this should never happen, but is currently still exercised by some tests
|
||||
if msgGasCost > msg.GasLimit {
|
||||
gasOutputs := ZeroGasOutputs()
|
||||
gasOutputs.MinerPenalty = types.BigMul(vm.baseFee, abi.NewTokenAmount(msgGasCost))
|
||||
return &ApplyRet{
|
||||
MessageReceipt: types.MessageReceipt{
|
||||
ExitCode: exitcode.SysErrOutOfGas,
|
||||
GasUsed: 0,
|
||||
},
|
||||
Penalty: types.BigMul(vm.baseFee, abi.NewTokenAmount(msgGasCost)),
|
||||
GasCosts: gasOutputs,
|
||||
Duration: time.Since(start),
|
||||
MinerTip: big.Zero(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -375,15 +374,16 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
// this should never happen, but is currently still exercised by some tests
|
||||
if err != nil {
|
||||
if xerrors.Is(err, types.ErrActorNotFound) {
|
||||
gasOutputs := ZeroGasOutputs()
|
||||
gasOutputs.MinerPenalty = minerPenaltyAmount
|
||||
return &ApplyRet{
|
||||
MessageReceipt: types.MessageReceipt{
|
||||
ExitCode: exitcode.SysErrSenderInvalid,
|
||||
GasUsed: 0,
|
||||
},
|
||||
ActorErr: aerrors.Newf(exitcode.SysErrSenderInvalid, "actor not found: %s", msg.From),
|
||||
Penalty: minerPenaltyAmount,
|
||||
GasCosts: gasOutputs,
|
||||
Duration: time.Since(start),
|
||||
MinerTip: big.Zero(),
|
||||
}, nil
|
||||
}
|
||||
return nil, xerrors.Errorf("failed to look up from actor: %w", err)
|
||||
@ -391,19 +391,22 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
|
||||
// this should never happen, but is currently still exercised by some tests
|
||||
if !fromActor.Code.Equals(builtin.AccountActorCodeID) {
|
||||
gasOutputs := ZeroGasOutputs()
|
||||
gasOutputs.MinerPenalty = minerPenaltyAmount
|
||||
return &ApplyRet{
|
||||
MessageReceipt: types.MessageReceipt{
|
||||
ExitCode: exitcode.SysErrSenderInvalid,
|
||||
GasUsed: 0,
|
||||
},
|
||||
ActorErr: aerrors.Newf(exitcode.SysErrSenderInvalid, "send from not account actor: %s", fromActor.Code),
|
||||
Penalty: minerPenaltyAmount,
|
||||
GasCosts: gasOutputs,
|
||||
Duration: time.Since(start),
|
||||
MinerTip: big.Zero(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
if msg.Nonce != fromActor.Nonce {
|
||||
gasOutputs := ZeroGasOutputs()
|
||||
gasOutputs.MinerPenalty = minerPenaltyAmount
|
||||
return &ApplyRet{
|
||||
MessageReceipt: types.MessageReceipt{
|
||||
ExitCode: exitcode.SysErrSenderStateInvalid,
|
||||
@ -411,14 +414,16 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
},
|
||||
ActorErr: aerrors.Newf(exitcode.SysErrSenderStateInvalid,
|
||||
"actor nonce invalid: msg:%d != state:%d", msg.Nonce, fromActor.Nonce),
|
||||
Penalty: minerPenaltyAmount,
|
||||
|
||||
GasCosts: gasOutputs,
|
||||
Duration: time.Since(start),
|
||||
MinerTip: big.Zero(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
gascost := types.BigMul(types.NewInt(uint64(msg.GasLimit)), msg.GasFeeCap)
|
||||
if fromActor.Balance.LessThan(gascost) {
|
||||
gasOutputs := ZeroGasOutputs()
|
||||
gasOutputs.MinerPenalty = minerPenaltyAmount
|
||||
return &ApplyRet{
|
||||
MessageReceipt: types.MessageReceipt{
|
||||
ExitCode: exitcode.SysErrSenderStateInvalid,
|
||||
@ -426,9 +431,8 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
},
|
||||
ActorErr: aerrors.Newf(exitcode.SysErrSenderStateInvalid,
|
||||
"actor balance less than needed: %s < %s", types.FIL(fromActor.Balance), types.FIL(gascost)),
|
||||
Penalty: minerPenaltyAmount,
|
||||
GasCosts: gasOutputs,
|
||||
Duration: time.Since(start),
|
||||
MinerTip: big.Zero(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -521,8 +525,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
},
|
||||
ActorErr: actorErr,
|
||||
ExecutionTrace: rt.executionTrace,
|
||||
Penalty: gasOutputs.MinerPenalty,
|
||||
MinerTip: gasOutputs.MinerTip,
|
||||
GasCosts: gasOutputs,
|
||||
Duration: time.Since(start),
|
||||
}, nil
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ import (
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
tm "github.com/buger/goterm"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/fatih/color"
|
||||
@ -527,6 +529,11 @@ func interactiveDeal(cctx *cli.Context) error {
|
||||
continue
|
||||
}
|
||||
|
||||
if days < int(build.MinDealDuration/builtin.EpochsInDay) {
|
||||
printErr(xerrors.Errorf("minimum duration is %d days", int(build.MinDealDuration/builtin.EpochsInDay)))
|
||||
continue
|
||||
}
|
||||
|
||||
state = "miner"
|
||||
case "miner":
|
||||
fmt.Print("Miner Address (t0..): ")
|
||||
|
55
cli/state.go
55
cli/state.go
@ -66,6 +66,7 @@ var stateCmd = &cli.Command{
|
||||
stateGetDealSetCmd,
|
||||
stateWaitMsgCmd,
|
||||
stateSearchMsgCmd,
|
||||
stateMsgCostCmd,
|
||||
stateMinerInfo,
|
||||
stateMarketCmd,
|
||||
},
|
||||
@ -1312,6 +1313,60 @@ var stateSearchMsgCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateMsgCostCmd = &cli.Command{
|
||||
Name: "msg-cost",
|
||||
Usage: "Get the detailed gas costs of a message",
|
||||
ArgsUsage: "[messageCid]",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if !cctx.Args().Present() {
|
||||
return fmt.Errorf("must specify message cid to get gas costs for")
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msg, err := cid.Decode(cctx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tsk := types.EmptyTSK
|
||||
|
||||
ts, err := LoadTipSet(ctx, cctx, api)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ts != nil {
|
||||
tsk = ts.Key()
|
||||
}
|
||||
|
||||
mgc, err := api.StateMsgGasCost(ctx, msg, tsk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if mgc != nil {
|
||||
fmt.Printf("Message CID: %s", mgc.Message)
|
||||
fmt.Printf("\nGas Used: %d", mgc.GasUsed)
|
||||
fmt.Printf("\nBase Fee Burn: %d", mgc.BaseFeeBurn)
|
||||
fmt.Printf("\nOverestimation Burn: %d", mgc.OverEstimationBurn)
|
||||
fmt.Printf("\nMiner Tip: %d", mgc.MinerTip)
|
||||
fmt.Printf("\nRefund: %d", mgc.Refund)
|
||||
fmt.Printf("\nTotal Cost: %d", mgc.TotalCost)
|
||||
fmt.Printf("\nMiner Penalty: %d", mgc.MinerPenalty)
|
||||
} else {
|
||||
fmt.Print("message was not found on chain")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var stateCallCmd = &cli.Command{
|
||||
Name: "call",
|
||||
Usage: "Invoke a method on an actor locally",
|
||||
|
@ -56,6 +56,10 @@ var importBenchCmd = &cli.Command{
|
||||
Usage: "set the parallelism factor for batch seal verification",
|
||||
Value: runtime.NumCPU(),
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "repodir",
|
||||
Usage: "set the repo directory for the lotus bench run (defaults to /tmp)",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
vm.BatchSealVerifyParallelism = cctx.Int("batch-seal-verify-threads")
|
||||
@ -70,9 +74,15 @@ var importBenchCmd = &cli.Command{
|
||||
}
|
||||
defer cfi.Close() //nolint:errcheck // read only file
|
||||
|
||||
tdir, err := ioutil.TempDir("", "lotus-import-bench")
|
||||
if err != nil {
|
||||
return err
|
||||
var tdir string
|
||||
if rdir := cctx.String("repodir"); rdir != "" {
|
||||
tdir = rdir
|
||||
} else {
|
||||
tmp, err := ioutil.TempDir("", "lotus-import-bench")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tdir = tmp
|
||||
}
|
||||
|
||||
bds, err := badger.NewDatastore(tdir, nil)
|
||||
|
@ -387,7 +387,7 @@ var sealBenchCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
log.Error("post verification failed")
|
||||
log.Error("window post verification failed")
|
||||
}
|
||||
|
||||
verifyWindowpost1 := time.Now()
|
||||
@ -403,7 +403,7 @@ var sealBenchCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
log.Error("post verification failed")
|
||||
log.Error("window post verification failed")
|
||||
}
|
||||
|
||||
verifyWindowpost2 := time.Now()
|
||||
|
@ -148,6 +148,7 @@
|
||||
* [StateMinerRecoveries](#StateMinerRecoveries)
|
||||
* [StateMinerSectorCount](#StateMinerSectorCount)
|
||||
* [StateMinerSectors](#StateMinerSectors)
|
||||
* [StateMsgGasCost](#StateMsgGasCost)
|
||||
* [StateNetworkName](#StateNetworkName)
|
||||
* [StateReadState](#StateReadState)
|
||||
* [StateReplay](#StateReplay)
|
||||
@ -3737,6 +3738,45 @@ Inputs:
|
||||
|
||||
Response: `null`
|
||||
|
||||
### StateMsgGasCost
|
||||
StateMsgGasCost searches for a message in the chain, and returns details of the messages gas costs, including the penalty and miner tip
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
},
|
||||
[
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
},
|
||||
{
|
||||
"/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve"
|
||||
}
|
||||
]
|
||||
]
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"Message": {
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
},
|
||||
"GasUsed": "0",
|
||||
"BaseFeeBurn": "0",
|
||||
"OverEstimationBurn": "0",
|
||||
"MinerPenalty": "0",
|
||||
"MinerTip": "0",
|
||||
"Refund": "0",
|
||||
"TotalCost": "0"
|
||||
}
|
||||
```
|
||||
|
||||
### StateNetworkName
|
||||
StateNetworkName returns the name of the network the node is synced to
|
||||
|
||||
|
2
extern/storage-sealing/upgrade_queue.go
vendored
2
extern/storage-sealing/upgrade_queue.go
vendored
@ -67,6 +67,8 @@ func (m *Sealing) tryUpgradeSector(ctx context.Context, params *miner.SectorPreC
|
||||
params.ReplaceSectorDeadline = loc.Deadline
|
||||
params.ReplaceSectorPartition = loc.Partition
|
||||
|
||||
log.Infof("replacing sector %d with %d", *replace, params.SectorNumber)
|
||||
|
||||
ri, err := m.api.StateSectorGetInfo(ctx, m.maddr, *replace, nil)
|
||||
if err != nil {
|
||||
log.Errorf("error calling StateSectorGetInfo for replaced sector: %+v", err)
|
||||
|
@ -382,7 +382,7 @@ func StorageMiner(out *api.StorageMiner) Option {
|
||||
|
||||
func(s *Settings) error {
|
||||
resAPI := &impl.StorageMinerAPI{}
|
||||
s.invokes[ExtractApiKey] = fx.Extract(resAPI)
|
||||
s.invokes[ExtractApiKey] = fx.Populate(resAPI)
|
||||
*out = resAPI
|
||||
return nil
|
||||
},
|
||||
@ -509,7 +509,7 @@ func FullAPI(out *api.FullNode) Option {
|
||||
},
|
||||
func(s *Settings) error {
|
||||
resAPI := &impl.FullNodeAPI{}
|
||||
s.invokes[ExtractApiKey] = fx.Extract(resAPI)
|
||||
s.invokes[ExtractApiKey] = fx.Populate(resAPI)
|
||||
*out = resAPI
|
||||
return nil
|
||||
},
|
||||
|
@ -1225,3 +1225,52 @@ func (a *StateAPI) StateCirculatingSupply(ctx context.Context, tsk types.TipSetK
|
||||
|
||||
return a.StateManager.GetCirculatingSupplyDetailed(ctx, ts.Height(), sTree)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMsgGasCost(ctx context.Context, inputMsg cid.Cid, tsk types.TipSetKey) (*api.MsgGasCost, error) {
|
||||
var msg cid.Cid
|
||||
var ts *types.TipSet
|
||||
var err error
|
||||
if tsk != types.EmptyTSK {
|
||||
msg = inputMsg
|
||||
ts, err = a.Chain.LoadTipSet(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
} else {
|
||||
mlkp, err := a.StateSearchMsg(ctx, inputMsg)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("searching for msg %s: %w", inputMsg, err)
|
||||
}
|
||||
if mlkp == nil {
|
||||
return nil, xerrors.Errorf("didn't find msg %s", inputMsg)
|
||||
}
|
||||
|
||||
executionTs, err := a.Chain.GetTipSetFromKey(mlkp.TipSet)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", mlkp.TipSet, err)
|
||||
}
|
||||
|
||||
ts, err = a.Chain.LoadTipSet(executionTs.Parents())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading parent tipset %s: %w", mlkp.TipSet, err)
|
||||
}
|
||||
|
||||
msg = mlkp.Message
|
||||
}
|
||||
|
||||
m, r, err := a.StateManager.Replay(ctx, ts, msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &api.MsgGasCost{
|
||||
Message: msg,
|
||||
GasUsed: big.NewInt(r.GasUsed),
|
||||
BaseFeeBurn: r.GasCosts.BaseFeeBurn,
|
||||
OverEstimationBurn: r.GasCosts.OverEstimationBurn,
|
||||
MinerPenalty: r.GasCosts.MinerPenalty,
|
||||
MinerTip: r.GasCosts.MinerTip,
|
||||
Refund: r.GasCosts.Refund,
|
||||
TotalCost: big.Sub(m.RequiredFunds(), r.GasCosts.Refund),
|
||||
}, nil
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ func AddressFor(ctx context.Context, a addrSelectApi, mi api.MinerInfo, use Addr
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
log.Warnw("control address didn't have enough funds for PoSt message", "address", addr, "required", types.FIL(minFunds), "balance", types.FIL(b))
|
||||
log.Warnw("control address didn't have enough funds for window post message", "address", addr, "required", types.FIL(minFunds), "balance", types.FIL(b))
|
||||
}
|
||||
|
||||
// Try to use the owner account if we can, fallback to worker if we can't
|
||||
|
@ -78,7 +78,7 @@ func (s *WindowPoStScheduler) doPost(ctx context.Context, deadline *dline.Info,
|
||||
|
||||
posts, err := s.runPost(ctx, *deadline, ts)
|
||||
if err != nil {
|
||||
log.Errorf("runPost failed: %+v", err)
|
||||
log.Errorf("run window post failed: %+v", err)
|
||||
s.failPost(err, deadline)
|
||||
return
|
||||
}
|
||||
@ -92,7 +92,7 @@ func (s *WindowPoStScheduler) doPost(ctx context.Context, deadline *dline.Info,
|
||||
post := &posts[i]
|
||||
sm, err := s.submitPost(ctx, post)
|
||||
if err != nil {
|
||||
log.Errorf("submitPost failed: %+v", err)
|
||||
log.Errorf("submit window post failed: %+v", err)
|
||||
s.failPost(err, deadline)
|
||||
} else {
|
||||
recordProofsEvent(post.Partitions, sm.Cid())
|
||||
@ -397,7 +397,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *ty
|
||||
|
||||
rand, err := s.api.ChainGetRandomnessFromBeacon(ctx, ts.Key(), crypto.DomainSeparationTag_WindowedPoStChallengeSeed, di.Challenge, buf.Bytes())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get chain randomness for windowPost (ts=%d; deadline=%d): %w", ts.Height(), di, err)
|
||||
return nil, xerrors.Errorf("failed to get chain randomness for window post (ts=%d; deadline=%d): %w", ts.Height(), di, err)
|
||||
}
|
||||
|
||||
// Get the partitions for the given deadline
|
||||
@ -490,7 +490,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *ty
|
||||
}
|
||||
|
||||
// Generate proof
|
||||
log.Infow("running windowPost",
|
||||
log.Infow("running window post",
|
||||
"chain-random", rand,
|
||||
"deadline", di,
|
||||
"height", ts.Height(),
|
||||
@ -507,7 +507,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *ty
|
||||
postOut, ps, err = s.prover.GenerateWindowPoSt(ctx, abi.ActorID(mid), sinfos, abi.PoStRandomness(rand))
|
||||
elapsed := time.Since(tsStart)
|
||||
|
||||
log.Infow("computing window PoSt", "batch", batchIdx, "elapsed", elapsed)
|
||||
log.Infow("computing window post", "batch", batchIdx, "elapsed", elapsed)
|
||||
|
||||
if err == nil {
|
||||
// Proof generation successful, stop retrying
|
||||
@ -517,10 +517,10 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *ty
|
||||
// Proof generation failed, so retry
|
||||
|
||||
if len(ps) == 0 {
|
||||
return nil, xerrors.Errorf("running post failed: %w", err)
|
||||
return nil, xerrors.Errorf("running window post failed: %w", err)
|
||||
}
|
||||
|
||||
log.Warnw("generate window PoSt skipped sectors", "sectors", ps, "error", err, "try", retries)
|
||||
log.Warnw("generate window post skipped sectors", "sectors", ps, "error", err, "try", retries)
|
||||
|
||||
skipCount += uint64(len(ps))
|
||||
for _, sector := range ps {
|
||||
@ -547,7 +547,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *ty
|
||||
commEpoch := di.Open
|
||||
commRand, err := s.api.ChainGetRandomnessFromTickets(ctx, ts.Key(), crypto.DomainSeparationTag_PoStChainCommit, commEpoch, nil)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get chain randomness for windowPost (ts=%d; deadline=%d): %w", ts.Height(), commEpoch, err)
|
||||
return nil, xerrors.Errorf("failed to get chain randomness for window post (ts=%d; deadline=%d): %w", ts.Height(), commEpoch, err)
|
||||
}
|
||||
|
||||
for i := range posts {
|
||||
@ -644,7 +644,7 @@ func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *miner.Submi
|
||||
|
||||
enc, aerr := actors.SerializeParams(proof)
|
||||
if aerr != nil {
|
||||
return nil, xerrors.Errorf("could not serialize submit post parameters: %w", aerr)
|
||||
return nil, xerrors.Errorf("could not serialize submit window post parameters: %w", aerr)
|
||||
}
|
||||
|
||||
msg := &types.Message{
|
||||
@ -705,7 +705,7 @@ func (s *WindowPoStScheduler) setSender(ctx context.Context, msg *types.Message,
|
||||
|
||||
pa, err := AddressFor(ctx, s.api, mi, PoStAddr, minFunds)
|
||||
if err != nil {
|
||||
log.Errorw("error selecting address for post", "error", err)
|
||||
log.Errorw("error selecting address for window post", "error", err)
|
||||
msg.From = s.worker
|
||||
return
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ func (s *WindowPoStScheduler) Run(ctx context.Context) {
|
||||
select {
|
||||
case changes, ok := <-notifs:
|
||||
if !ok {
|
||||
log.Warn("WindowPoStScheduler notifs channel closed")
|
||||
log.Warn("window post scheduler notifs channel closed")
|
||||
notifs = nil
|
||||
continue
|
||||
}
|
||||
@ -151,10 +151,10 @@ func (s *WindowPoStScheduler) Run(ctx context.Context) {
|
||||
}
|
||||
|
||||
if err := s.revert(ctx, lowest); err != nil {
|
||||
log.Error("handling head reverts in windowPost sched: %+v", err)
|
||||
log.Error("handling head reverts in window post sched: %+v", err)
|
||||
}
|
||||
if err := s.update(ctx, highest); err != nil {
|
||||
log.Error("handling head updates in windowPost sched: %+v", err)
|
||||
log.Error("handling head updates in window post sched: %+v", err)
|
||||
}
|
||||
|
||||
span.End()
|
||||
@ -184,7 +184,7 @@ func (s *WindowPoStScheduler) revert(ctx context.Context, newLowest *types.TipSe
|
||||
|
||||
func (s *WindowPoStScheduler) update(ctx context.Context, new *types.TipSet) error {
|
||||
if new == nil {
|
||||
return xerrors.Errorf("no new tipset in WindowPoStScheduler.update")
|
||||
return xerrors.Errorf("no new tipset in window post sched update")
|
||||
}
|
||||
|
||||
di, err := s.api.StateMinerProvingDeadline(ctx, s.actor, new.Key())
|
||||
@ -206,7 +206,7 @@ func (s *WindowPoStScheduler) update(ctx context.Context, new *types.TipSet) err
|
||||
// (Need to get correct deadline above, which is tricky)
|
||||
|
||||
if di.Open+StartConfidence >= new.Height() {
|
||||
log.Info("not starting windowPost yet, waiting for startconfidence", di.Open, di.Open+StartConfidence, new.Height())
|
||||
log.Info("not starting window post yet, waiting for startconfidence", di.Open, di.Open+StartConfidence, new.Height())
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -216,7 +216,7 @@ func (s *WindowPoStScheduler) update(ctx context.Context, new *types.TipSet) err
|
||||
s.activeEPS = 0
|
||||
}
|
||||
s.failLk.Unlock()*/
|
||||
log.Infof("at %d, doPost for P %d, dd %d", new.Height(), di.PeriodStart, di.Index)
|
||||
log.Infof("at %d, do window post for P %d, dd %d", new.Height(), di.PeriodStart, di.Index)
|
||||
|
||||
s.doPost(ctx, di, new)
|
||||
|
||||
@ -238,7 +238,7 @@ func (s *WindowPoStScheduler) abortActivePoSt() {
|
||||
}
|
||||
})
|
||||
|
||||
log.Warnf("Aborting Window PoSt (Deadline: %+v)", s.activeDeadline)
|
||||
log.Warnf("Aborting window post (Deadline: %+v)", s.activeDeadline)
|
||||
}
|
||||
|
||||
s.activeDeadline = nil
|
||||
|
Loading…
Reference in New Issue
Block a user