Merge branch 'master' into feat/event-states
This commit is contained in:
commit
1e782b3de2
2
Makefile
2
Makefile
@ -124,7 +124,7 @@ BINS+=townhall
|
|||||||
fountain:
|
fountain:
|
||||||
rm -f fountain
|
rm -f fountain
|
||||||
go build -o fountain ./cmd/lotus-fountain
|
go build -o fountain ./cmd/lotus-fountain
|
||||||
go run github.com/GeertJohan/go.rice/rice append --exec fountain -i ./cmd/lotus-fountain
|
go run github.com/GeertJohan/go.rice/rice append --exec fountain -i ./cmd/lotus-fountain -i ./build
|
||||||
.PHONY: fountain
|
.PHONY: fountain
|
||||||
BINS+=fountain
|
BINS+=fountain
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ type FullNode interface {
|
|||||||
ChainTipSetWeight(context.Context, *types.TipSet) (types.BigInt, error)
|
ChainTipSetWeight(context.Context, *types.TipSet) (types.BigInt, error)
|
||||||
ChainGetNode(ctx context.Context, p string) (interface{}, error)
|
ChainGetNode(ctx context.Context, p string) (interface{}, error)
|
||||||
ChainGetMessage(context.Context, cid.Cid) (*types.Message, error)
|
ChainGetMessage(context.Context, cid.Cid) (*types.Message, error)
|
||||||
|
ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*store.HeadChange, error)
|
||||||
|
|
||||||
// syncer
|
// syncer
|
||||||
SyncState(context.Context) (*SyncState, error)
|
SyncState(context.Context) (*SyncState, error)
|
||||||
@ -118,6 +119,7 @@ type FullNode interface {
|
|||||||
StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error)
|
StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error)
|
||||||
StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error)
|
StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error)
|
||||||
StateMinerSectorCount(context.Context, address.Address, *types.TipSet) (MinerSectors, error)
|
StateMinerSectorCount(context.Context, address.Address, *types.TipSet) (MinerSectors, error)
|
||||||
|
StateCompute(context.Context, uint64, []*types.Message, *types.TipSet) (cid.Cid, error)
|
||||||
|
|
||||||
MarketEnsureAvailable(context.Context, address.Address, types.BigInt) error
|
MarketEnsureAvailable(context.Context, address.Address, types.BigInt) error
|
||||||
// MarketFreeBalance
|
// MarketFreeBalance
|
||||||
|
@ -40,21 +40,22 @@ type FullNodeStruct struct {
|
|||||||
CommonStruct
|
CommonStruct
|
||||||
|
|
||||||
Internal struct {
|
Internal struct {
|
||||||
ChainNotify func(context.Context) (<-chan []*store.HeadChange, error) `perm:"read"`
|
ChainNotify func(context.Context) (<-chan []*store.HeadChange, error) `perm:"read"`
|
||||||
ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"`
|
ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"`
|
||||||
ChainGetRandomness func(context.Context, types.TipSetKey, int64) ([]byte, error) `perm:"read"`
|
ChainGetRandomness func(context.Context, types.TipSetKey, int64) ([]byte, error) `perm:"read"`
|
||||||
ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"`
|
ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"`
|
||||||
ChainGetTipSet func(context.Context, types.TipSetKey) (*types.TipSet, error) `perm:"read"`
|
ChainGetTipSet func(context.Context, types.TipSetKey) (*types.TipSet, error) `perm:"read"`
|
||||||
ChainGetBlockMessages func(context.Context, cid.Cid) (*api.BlockMessages, error) `perm:"read"`
|
ChainGetBlockMessages func(context.Context, cid.Cid) (*api.BlockMessages, error) `perm:"read"`
|
||||||
ChainGetParentReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"`
|
ChainGetParentReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"`
|
||||||
ChainGetParentMessages func(context.Context, cid.Cid) ([]api.Message, error) `perm:"read"`
|
ChainGetParentMessages func(context.Context, cid.Cid) ([]api.Message, error) `perm:"read"`
|
||||||
ChainGetTipSetByHeight func(context.Context, uint64, *types.TipSet) (*types.TipSet, error) `perm:"read"`
|
ChainGetTipSetByHeight func(context.Context, uint64, *types.TipSet) (*types.TipSet, error) `perm:"read"`
|
||||||
ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"`
|
ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"`
|
||||||
ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"`
|
ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"`
|
||||||
ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"`
|
ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"`
|
||||||
ChainTipSetWeight func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"`
|
ChainTipSetWeight func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"`
|
||||||
ChainGetNode func(ctx context.Context, p string) (interface{}, error) `perm:"read"`
|
ChainGetNode func(ctx context.Context, p string) (interface{}, error) `perm:"read"`
|
||||||
ChainGetMessage func(context.Context, cid.Cid) (*types.Message, error) `perm:"read"`
|
ChainGetMessage func(context.Context, cid.Cid) (*types.Message, error) `perm:"read"`
|
||||||
|
ChainGetPath func(context.Context, types.TipSetKey, types.TipSetKey) ([]*store.HeadChange, error) `perm:"read"`
|
||||||
|
|
||||||
SyncState func(context.Context) (*api.SyncState, error) `perm:"read"`
|
SyncState func(context.Context) (*api.SyncState, error) `perm:"read"`
|
||||||
SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"`
|
SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"`
|
||||||
@ -114,6 +115,7 @@ type FullNodeStruct struct {
|
|||||||
StateGetReceipt func(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"`
|
StateGetReceipt func(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"`
|
||||||
StateMinerSectorCount func(context.Context, address.Address, *types.TipSet) (api.MinerSectors, error) `perm:"read"`
|
StateMinerSectorCount func(context.Context, address.Address, *types.TipSet) (api.MinerSectors, error) `perm:"read"`
|
||||||
StateListMessages func(ctx context.Context, match *types.Message, ts *types.TipSet, toht uint64) ([]cid.Cid, error) `perm:"read"`
|
StateListMessages func(ctx context.Context, match *types.Message, ts *types.TipSet, toht uint64) ([]cid.Cid, error) `perm:"read"`
|
||||||
|
StateCompute func(context.Context, uint64, []*types.Message, *types.TipSet) (cid.Cid, error) `perm:"read"`
|
||||||
|
|
||||||
MarketEnsureAvailable func(context.Context, address.Address, types.BigInt) error `perm:"sign"`
|
MarketEnsureAvailable func(context.Context, address.Address, types.BigInt) error `perm:"sign"`
|
||||||
|
|
||||||
@ -355,6 +357,10 @@ func (c *FullNodeStruct) ChainGetMessage(ctx context.Context, mc cid.Cid) (*type
|
|||||||
return c.Internal.ChainGetMessage(ctx, mc)
|
return c.Internal.ChainGetMessage(ctx, mc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *FullNodeStruct) ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*store.HeadChange, error) {
|
||||||
|
return c.Internal.ChainGetPath(ctx, from, to)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) SyncState(ctx context.Context) (*api.SyncState, error) {
|
func (c *FullNodeStruct) SyncState(ctx context.Context) (*api.SyncState, error) {
|
||||||
return c.Internal.SyncState(ctx)
|
return c.Internal.SyncState(ctx)
|
||||||
}
|
}
|
||||||
@ -462,6 +468,10 @@ func (c *FullNodeStruct) StateListMessages(ctx context.Context, match *types.Mes
|
|||||||
return c.Internal.StateListMessages(ctx, match, ts, toht)
|
return c.Internal.StateListMessages(ctx, match, ts, toht)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *FullNodeStruct) StateCompute(ctx context.Context, height uint64, msgs []*types.Message, ts *types.TipSet) (cid.Cid, error) {
|
||||||
|
return c.Internal.StateCompute(ctx, height, msgs, ts)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) MarketEnsureAvailable(ctx context.Context, addr address.Address, amt types.BigInt) error {
|
func (c *FullNodeStruct) MarketEnsureAvailable(ctx context.Context, addr address.Address, amt types.BigInt) error {
|
||||||
return c.Internal.MarketEnsureAvailable(ctx, addr, amt)
|
return c.Internal.MarketEnsureAvailable(ctx, addr, amt)
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
package build
|
package build
|
||||||
|
|
||||||
// No forks yet \o/
|
const ForkBlizzardHeight = 6288
|
||||||
|
|
||||||
|
const ForkFrigidHeight = 7950
|
||||||
|
@ -105,3 +105,4 @@ const BlsSignatureCacheSize = 40000
|
|||||||
// Limits
|
// Limits
|
||||||
|
|
||||||
const BlockMessageLimit = 512
|
const BlockMessageLimit = 512
|
||||||
|
const MinerMaxSectors = 1 << 48
|
||||||
|
@ -5,7 +5,7 @@ import "fmt"
|
|||||||
var CurrentCommit string
|
var CurrentCommit string
|
||||||
|
|
||||||
// BuildVersion is the local build version, set by build system
|
// BuildVersion is the local build version, set by build system
|
||||||
const BuildVersion = "0.2.2"
|
const BuildVersion = "0.2.4"
|
||||||
|
|
||||||
var UserVersion = BuildVersion + CurrentCommit
|
var UserVersion = BuildVersion + CurrentCommit
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ func (ia InitActor) Exec(act *types.Actor, vmctx types.VMContext, p *ExecParams)
|
|||||||
|
|
||||||
func IsBuiltinActor(code cid.Cid) bool {
|
func IsBuiltinActor(code cid.Cid) bool {
|
||||||
switch code {
|
switch code {
|
||||||
case StorageMarketCodeCid, StoragePowerCodeCid, StorageMinerCodeCid, AccountCodeCid, InitCodeCid, MultisigCodeCid, PaymentChannelCodeCid:
|
case StorageMarketCodeCid, StoragePowerCodeCid, StorageMinerCodeCid, StorageMiner2CodeCid, AccountCodeCid, InitCodeCid, MultisigCodeCid, PaymentChannelCodeCid:
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
|
@ -22,8 +22,6 @@ import (
|
|||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const MaxSectors = 1 << 48
|
|
||||||
|
|
||||||
type StorageMinerActor struct{}
|
type StorageMinerActor struct{}
|
||||||
|
|
||||||
type StorageMinerActorState struct {
|
type StorageMinerActorState struct {
|
||||||
@ -571,7 +569,7 @@ func SectorIsUnique(ctx context.Context, s types.Storage, sroot cid.Cid, sid uin
|
|||||||
}
|
}
|
||||||
|
|
||||||
func AddToSectorSet(ctx context.Context, blks amt.Blocks, ss cid.Cid, sectorID uint64, commR, commD []byte) (cid.Cid, ActorError) {
|
func AddToSectorSet(ctx context.Context, blks amt.Blocks, ss cid.Cid, sectorID uint64, commR, commD []byte) (cid.Cid, ActorError) {
|
||||||
if sectorID >= MaxSectors {
|
if sectorID >= build.MinerMaxSectors {
|
||||||
return cid.Undef, aerrors.Newf(25, "sector ID out of range: %d", sectorID)
|
return cid.Undef, aerrors.Newf(25, "sector ID out of range: %d", sectorID)
|
||||||
}
|
}
|
||||||
ssr, err := amt.LoadAMT(blks, ss)
|
ssr, err := amt.LoadAMT(blks, ss)
|
||||||
@ -594,7 +592,7 @@ func AddToSectorSet(ctx context.Context, blks amt.Blocks, ss cid.Cid, sectorID u
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetFromSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, sectorID uint64) (bool, []byte, []byte, ActorError) {
|
func GetFromSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, sectorID uint64) (bool, []byte, []byte, ActorError) {
|
||||||
if sectorID >= MaxSectors {
|
if sectorID >= build.MinerMaxSectors {
|
||||||
return false, nil, nil, aerrors.Newf(25, "sector ID out of range: %d", sectorID)
|
return false, nil, nil, aerrors.Newf(25, "sector ID out of range: %d", sectorID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
784
chain/actors/actor_miner2.go
Normal file
784
chain/actors/actor_miner2.go
Normal file
@ -0,0 +1,784 @@
|
|||||||
|
package actors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
ffi "github.com/filecoin-project/filecoin-ffi"
|
||||||
|
amt2 "github.com/filecoin-project/go-amt-ipld/v2"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-sectorbuilder"
|
||||||
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StorageMinerActor2 struct{}
|
||||||
|
|
||||||
|
func (sma StorageMinerActor2) Exports() []interface{} {
|
||||||
|
return []interface{}{
|
||||||
|
1: sma.StorageMinerConstructor,
|
||||||
|
2: sma.PreCommitSector,
|
||||||
|
3: sma.ProveCommitSector,
|
||||||
|
4: sma.SubmitFallbackPoSt,
|
||||||
|
//5: sma.SlashStorageFault,
|
||||||
|
//6: sma.GetCurrentProvingSet,
|
||||||
|
//7: sma.ArbitrateDeal,
|
||||||
|
//8: sma.DePledge,
|
||||||
|
9: sma.GetOwner,
|
||||||
|
10: sma.GetWorkerAddr,
|
||||||
|
11: sma.GetPower, // TODO: Remove
|
||||||
|
12: sma.GetPeerID,
|
||||||
|
13: sma.GetSectorSize,
|
||||||
|
14: sma.UpdatePeerID,
|
||||||
|
//15: sma.ChangeWorker,
|
||||||
|
16: sma.IsSlashed,
|
||||||
|
17: sma.CheckMiner,
|
||||||
|
18: sma.DeclareFaults,
|
||||||
|
19: sma.SlashConsensusFault,
|
||||||
|
20: sma.SubmitElectionPoSt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sma StorageMinerActor2) StorageMinerConstructor(act *types.Actor, vmctx types.VMContext, params *StorageMinerConstructorParams) ([]byte, ActorError) {
|
||||||
|
minerInfo := &MinerInfo{
|
||||||
|
Owner: params.Owner,
|
||||||
|
Worker: params.Worker,
|
||||||
|
PeerID: params.PeerID,
|
||||||
|
SectorSize: params.SectorSize,
|
||||||
|
}
|
||||||
|
|
||||||
|
minfocid, err := vmctx.Storage().Put(minerInfo)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var self StorageMinerActorState
|
||||||
|
sectors := amt2.NewAMT(types.WrapStorage(vmctx.Storage()))
|
||||||
|
scid, serr := sectors.Flush()
|
||||||
|
if serr != nil {
|
||||||
|
return nil, aerrors.HandleExternalError(serr, "initializing AMT")
|
||||||
|
}
|
||||||
|
|
||||||
|
self.Sectors = scid
|
||||||
|
self.ProvingSet = scid
|
||||||
|
self.Info = minfocid
|
||||||
|
|
||||||
|
storage := vmctx.Storage()
|
||||||
|
c, err := storage.Put(&self)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := storage.Commit(EmptyCBOR, c); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sma StorageMinerActor2) PreCommitSector(act *types.Actor, vmctx types.VMContext, params *SectorPreCommitInfo) ([]byte, ActorError) {
|
||||||
|
|
||||||
|
ctx := vmctx.Context()
|
||||||
|
oldstate, self, err := loadState(vmctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.SealEpoch >= vmctx.BlockHeight()+build.SealRandomnessLookback {
|
||||||
|
return nil, aerrors.Newf(1, "sector commitment must be based off past randomness (%d >= %d)", params.SealEpoch, vmctx.BlockHeight()+build.SealRandomnessLookback)
|
||||||
|
}
|
||||||
|
|
||||||
|
if vmctx.BlockHeight()-params.SealEpoch+build.SealRandomnessLookback > build.SealRandomnessLookbackLimit {
|
||||||
|
return nil, aerrors.Newf(2, "sector commitment must be recent enough (was %d)", vmctx.BlockHeight()-params.SealEpoch+build.SealRandomnessLookback)
|
||||||
|
}
|
||||||
|
|
||||||
|
mi, err := loadMinerInfo(vmctx, self)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if vmctx.Message().From != mi.Worker {
|
||||||
|
return nil, aerrors.New(1, "not authorized to precommit sector for miner")
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure the miner isnt trying to submit a pre-existing sector
|
||||||
|
unique, err := SectorIsUnique(ctx, vmctx.Storage(), self.Sectors, params.SectorNumber)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !unique {
|
||||||
|
return nil, aerrors.New(3, "sector already committed!")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Power of the miner after adding this sector
|
||||||
|
futurePower := types.BigAdd(self.Power, types.NewInt(mi.SectorSize))
|
||||||
|
collateralRequired := CollateralForPower(futurePower)
|
||||||
|
|
||||||
|
// TODO: grab from market?
|
||||||
|
if act.Balance.LessThan(collateralRequired) {
|
||||||
|
return nil, aerrors.New(4, "not enough collateral")
|
||||||
|
}
|
||||||
|
|
||||||
|
self.PreCommittedSectors[uintToStringKey(params.SectorNumber)] = &PreCommittedSector{
|
||||||
|
Info: *params,
|
||||||
|
ReceivedEpoch: vmctx.BlockHeight(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(self.PreCommittedSectors) > 4096 {
|
||||||
|
return nil, aerrors.New(5, "too many precommitted sectors")
|
||||||
|
}
|
||||||
|
|
||||||
|
nstate, err := vmctx.Storage().Put(self)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := vmctx.Storage().Commit(oldstate, nstate); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sma StorageMinerActor2) ProveCommitSector(act *types.Actor, vmctx types.VMContext, params *SectorProveCommitInfo) ([]byte, ActorError) {
|
||||||
|
ctx := vmctx.Context()
|
||||||
|
oldstate, self, err := loadState(vmctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mi, err := loadMinerInfo(vmctx, self)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if vmctx.Message().From != mi.Worker {
|
||||||
|
return nil, aerrors.New(1, "not authorized to submit sector proof for miner")
|
||||||
|
}
|
||||||
|
|
||||||
|
us, ok := self.PreCommittedSectors[uintToStringKey(params.SectorID)]
|
||||||
|
if !ok {
|
||||||
|
return nil, aerrors.New(1, "no pre-commitment found for sector")
|
||||||
|
}
|
||||||
|
|
||||||
|
if us.ReceivedEpoch+build.InteractivePoRepDelay >= vmctx.BlockHeight() {
|
||||||
|
return nil, aerrors.New(2, "too early for proof submission")
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(self.PreCommittedSectors, uintToStringKey(params.SectorID))
|
||||||
|
|
||||||
|
// TODO: ensure normalization to ID address
|
||||||
|
maddr := vmctx.Message().To
|
||||||
|
|
||||||
|
if vmctx.BlockHeight()-us.Info.SealEpoch > build.MaxSealLookback {
|
||||||
|
return nil, aerrors.Newf(5, "source randomness for sector SealEpoch too far in past (epoch %d)", us.Info.SealEpoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
if vmctx.BlockHeight()-us.ReceivedEpoch > build.MaxSealLookback {
|
||||||
|
return nil, aerrors.Newf(6, "source randomness for sector ReceivedEpoch too far in past (epoch %d)", us.ReceivedEpoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
ticket, err := vmctx.GetRandomness(us.Info.SealEpoch - build.SealRandomnessLookback)
|
||||||
|
if err != nil {
|
||||||
|
return nil, aerrors.Wrap(err, "failed to get ticket randomness")
|
||||||
|
}
|
||||||
|
|
||||||
|
seed, err := vmctx.GetRandomness(us.ReceivedEpoch + build.InteractivePoRepDelay)
|
||||||
|
if err != nil {
|
||||||
|
return nil, aerrors.Wrap(err, "failed to get randomness for prove sector commitment")
|
||||||
|
}
|
||||||
|
|
||||||
|
enc, err := SerializeParams(&ComputeDataCommitmentParams{
|
||||||
|
DealIDs: params.DealIDs,
|
||||||
|
SectorSize: mi.SectorSize,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, aerrors.Wrap(err, "failed to serialize ComputeDataCommitmentParams")
|
||||||
|
}
|
||||||
|
|
||||||
|
commD, err := vmctx.Send(StorageMarketAddress, SMAMethods.ComputeDataCommitment, types.NewInt(0), enc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, aerrors.Wrapf(err, "failed to compute data commitment (sector %d, deals: %v)", params.SectorID, params.DealIDs)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok, err := vmctx.Sys().ValidatePoRep(ctx, maddr, mi.SectorSize, commD, us.Info.CommR, ticket, params.Proof, seed, params.SectorID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if !ok {
|
||||||
|
return nil, aerrors.Newf(2, "porep proof was invalid (t:%x; s:%x(%d); p:%s)", ticket, seed, us.ReceivedEpoch+build.InteractivePoRepDelay, truncateHexPrint(params.Proof))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: There must exist a unique index in the miner's sector set for each
|
||||||
|
// sector ID. The `faults`, `recovered`, and `done` parameters of the
|
||||||
|
// SubmitPoSt method express indices into this sector set.
|
||||||
|
nssroot, err := AddToSectorSet2(ctx, types.WrapStorage(vmctx.Storage()), self.Sectors, params.SectorID, us.Info.CommR, commD)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
self.Sectors = nssroot
|
||||||
|
|
||||||
|
// if miner is not mining, start their proving period now
|
||||||
|
// Note: As written here, every miners first PoSt will only be over one sector.
|
||||||
|
// We could set up a 'grace period' for starting mining that would allow miners
|
||||||
|
// to submit several sectors for their first proving period. Alternatively, we
|
||||||
|
// could simply make the 'PreCommitSector' call take multiple sectors at a time.
|
||||||
|
//
|
||||||
|
// Note: Proving period is a function of sector size; small sectors take less
|
||||||
|
// time to prove than large sectors do. Sector size is selected when pledging.
|
||||||
|
pss, lerr := amt2.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet)
|
||||||
|
if lerr != nil {
|
||||||
|
return nil, aerrors.HandleExternalError(lerr, "could not load proving set node")
|
||||||
|
}
|
||||||
|
|
||||||
|
if pss.Count == 0 && !self.Active {
|
||||||
|
self.ProvingSet = self.Sectors
|
||||||
|
// TODO: probably want to wait until the miner is above a certain
|
||||||
|
// threshold before starting this
|
||||||
|
self.ElectionPeriodStart = vmctx.BlockHeight()
|
||||||
|
}
|
||||||
|
|
||||||
|
nstate, err := vmctx.Storage().Put(self)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := vmctx.Storage().Commit(oldstate, nstate); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
activateParams, err := SerializeParams(&ActivateStorageDealsParams{
|
||||||
|
Deals: params.DealIDs,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = vmctx.Send(StorageMarketAddress, SMAMethods.ActivateStorageDeals, types.NewInt(0), activateParams)
|
||||||
|
return nil, aerrors.Wrapf(err, "calling ActivateStorageDeals failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sma StorageMinerActor2) SubmitFallbackPoSt(act *types.Actor, vmctx types.VMContext, params *SubmitFallbackPoStParams) ([]byte, ActorError) {
|
||||||
|
oldstate, self, err := loadState(vmctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mi, err := loadMinerInfo(vmctx, self)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if vmctx.Message().From != mi.Worker {
|
||||||
|
return nil, aerrors.New(1, "not authorized to submit post for miner")
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// TODO: handle fees
|
||||||
|
msgVal := vmctx.Message().Value
|
||||||
|
if msgVal.LessThan(feesRequired) {
|
||||||
|
return nil, aerrors.New(2, "not enough funds to pay post submission fees")
|
||||||
|
}
|
||||||
|
|
||||||
|
if msgVal.GreaterThan(feesRequired) {
|
||||||
|
_, err := vmctx.Send(vmctx.Message().From, 0,
|
||||||
|
types.BigSub(msgVal, feesRequired), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, aerrors.Wrap(err, "could not refund excess fees")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
var seed [sectorbuilder.CommLen]byte
|
||||||
|
{
|
||||||
|
randHeight := self.ElectionPeriodStart + build.FallbackPoStDelay
|
||||||
|
if vmctx.BlockHeight() <= randHeight {
|
||||||
|
// TODO: spec, retcode
|
||||||
|
return nil, aerrors.Newf(1, "submit fallback PoSt called too early (%d < %d)", vmctx.BlockHeight(), randHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
rand, err := vmctx.GetRandomness(randHeight)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, aerrors.Wrap(err, "could not get randomness for PoST")
|
||||||
|
}
|
||||||
|
if len(rand) < len(seed) {
|
||||||
|
return nil, aerrors.Escalate(fmt.Errorf("randomness too small (%d < %d)",
|
||||||
|
len(rand), len(seed)), "improper randomness")
|
||||||
|
}
|
||||||
|
copy(seed[:], rand)
|
||||||
|
}
|
||||||
|
|
||||||
|
pss, lerr := amt2.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet)
|
||||||
|
if lerr != nil {
|
||||||
|
return nil, aerrors.HandleExternalError(lerr, "could not load proving set node")
|
||||||
|
}
|
||||||
|
|
||||||
|
ss, lerr := amt2.LoadAMT(types.WrapStorage(vmctx.Storage()), self.Sectors)
|
||||||
|
if lerr != nil {
|
||||||
|
return nil, aerrors.HandleExternalError(lerr, "could not load proving set node")
|
||||||
|
}
|
||||||
|
|
||||||
|
faults, nerr := self.FaultSet.AllMap(2 * ss.Count)
|
||||||
|
if nerr != nil {
|
||||||
|
return nil, aerrors.Absorb(err, 5, "RLE+ invalid")
|
||||||
|
}
|
||||||
|
|
||||||
|
activeFaults := uint64(0)
|
||||||
|
var sectorInfos []ffi.PublicSectorInfo
|
||||||
|
if err := pss.ForEach(func(id uint64, v *cbg.Deferred) error {
|
||||||
|
if faults[id] {
|
||||||
|
activeFaults++
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var comms [][]byte
|
||||||
|
if err := cbor.DecodeInto(v.Raw, &comms); err != nil {
|
||||||
|
return xerrors.New("could not decode comms")
|
||||||
|
}
|
||||||
|
si := ffi.PublicSectorInfo{
|
||||||
|
SectorID: id,
|
||||||
|
}
|
||||||
|
commR := comms[0]
|
||||||
|
if len(commR) != len(si.CommR) {
|
||||||
|
return xerrors.Errorf("commR length is wrong: %d", len(commR))
|
||||||
|
}
|
||||||
|
copy(si.CommR[:], commR)
|
||||||
|
|
||||||
|
sectorInfos = append(sectorInfos, si)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, aerrors.Absorb(err, 3, "could not decode sectorset")
|
||||||
|
}
|
||||||
|
|
||||||
|
proverID := vmctx.Message().To // TODO: normalize to ID address
|
||||||
|
|
||||||
|
var candidates []sectorbuilder.EPostCandidate
|
||||||
|
for _, t := range params.Candidates {
|
||||||
|
var partial [32]byte
|
||||||
|
copy(partial[:], t.Partial)
|
||||||
|
candidates = append(candidates, sectorbuilder.EPostCandidate{
|
||||||
|
PartialTicket: partial,
|
||||||
|
SectorID: t.SectorID,
|
||||||
|
SectorChallengeIndex: t.ChallengeIndex,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok, lerr := vmctx.Sys().VerifyFallbackPost(vmctx.Context(), mi.SectorSize,
|
||||||
|
sectorbuilder.NewSortedPublicSectorInfo(sectorInfos), seed[:], params.Proof, candidates, proverID, activeFaults); !ok || lerr != nil {
|
||||||
|
if lerr != nil {
|
||||||
|
// TODO: study PoST errors
|
||||||
|
return nil, aerrors.Absorb(lerr, 4, "PoST error")
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
return nil, aerrors.New(4, "PoST invalid")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post submission is successful!
|
||||||
|
if err := onSuccessfulPoSt(self, vmctx, activeFaults); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := vmctx.Storage().Put(self)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := vmctx.Storage().Commit(oldstate, c); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sma StorageMinerActor2) GetPower(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) {
|
||||||
|
_, self, err := loadState(vmctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return self.Power.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SectorIsUnique2(ctx context.Context, s types.Storage, sroot cid.Cid, sid uint64) (bool, ActorError) {
|
||||||
|
found, _, _, err := GetFromSectorSet2(ctx, s, sroot, sid)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return !found, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddToSectorSet2(ctx context.Context, blks amt2.Blocks, ss cid.Cid, sectorID uint64, commR, commD []byte) (cid.Cid, ActorError) {
|
||||||
|
if sectorID >= build.MinerMaxSectors {
|
||||||
|
return cid.Undef, aerrors.Newf(25, "sector ID out of range: %d", sectorID)
|
||||||
|
}
|
||||||
|
ssr, err := amt2.LoadAMT(blks, ss)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, aerrors.HandleExternalError(err, "could not load sector set node")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Spec says to use SealCommitment, and construct commD from deals each time,
|
||||||
|
// but that would make SubmitPoSt way, way more expensive
|
||||||
|
if err := ssr.Set(sectorID, [][]byte{commR, commD}); err != nil {
|
||||||
|
return cid.Undef, aerrors.HandleExternalError(err, "failed to set commitment in sector set")
|
||||||
|
}
|
||||||
|
|
||||||
|
ncid, err := ssr.Flush()
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, aerrors.HandleExternalError(err, "failed to flush sector set")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ncid, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFromSectorSet2(ctx context.Context, s types.Storage, ss cid.Cid, sectorID uint64) (bool, []byte, []byte, ActorError) {
|
||||||
|
if sectorID >= build.MinerMaxSectors {
|
||||||
|
return false, nil, nil, aerrors.Newf(25, "sector ID out of range: %d", sectorID)
|
||||||
|
}
|
||||||
|
|
||||||
|
ssr, err := amt2.LoadAMT(types.WrapStorage(s), ss)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil, nil, aerrors.HandleExternalError(err, "could not load sector set node")
|
||||||
|
}
|
||||||
|
|
||||||
|
var comms [][]byte
|
||||||
|
err = ssr.Get(sectorID, &comms)
|
||||||
|
if err != nil {
|
||||||
|
if _, ok := err.(*amt2.ErrNotFound); ok {
|
||||||
|
return false, nil, nil, nil
|
||||||
|
}
|
||||||
|
return false, nil, nil, aerrors.HandleExternalError(err, "failed to find sector in sector set")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(comms) != 2 {
|
||||||
|
return false, nil, nil, aerrors.Newf(20, "sector set entry should only have 2 elements")
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, comms[0], comms[1], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemoveFromSectorSet2(ctx context.Context, s types.Storage, ss cid.Cid, ids []uint64) (cid.Cid, aerrors.ActorError) {
|
||||||
|
|
||||||
|
ssr, err := amt2.LoadAMT(types.WrapStorage(s), ss)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, aerrors.HandleExternalError(err, "could not load sector set node")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, id := range ids {
|
||||||
|
if err := ssr.Delete(id); err != nil {
|
||||||
|
log.Warnf("failed to delete sector %d from set: %s", id, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ncid, err := ssr.Flush()
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, aerrors.HandleExternalError(err, "failed to flush sector set")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ncid, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sma StorageMinerActor2) GetWorkerAddr(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) {
|
||||||
|
_, self, err := loadState(vmctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mi, err := loadMinerInfo(vmctx, self)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return mi.Worker.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sma StorageMinerActor2) GetOwner(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) {
|
||||||
|
_, self, err := loadState(vmctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mi, err := loadMinerInfo(vmctx, self)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return mi.Owner.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sma StorageMinerActor2) GetPeerID(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) {
|
||||||
|
_, self, err := loadState(vmctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mi, err := loadMinerInfo(vmctx, self)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return []byte(mi.PeerID), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sma StorageMinerActor2) UpdatePeerID(act *types.Actor, vmctx types.VMContext, params *UpdatePeerIDParams) ([]byte, ActorError) {
|
||||||
|
oldstate, self, err := loadState(vmctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mi, err := loadMinerInfo(vmctx, self)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if vmctx.Message().From != mi.Worker {
|
||||||
|
return nil, aerrors.New(2, "only the mine worker may update the peer ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
mi.PeerID = params.PeerID
|
||||||
|
|
||||||
|
mic, err := vmctx.Storage().Put(mi)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
self.Info = mic
|
||||||
|
|
||||||
|
c, err := vmctx.Storage().Put(self)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := vmctx.Storage().Commit(oldstate, c); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sma StorageMinerActor2) GetSectorSize(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) {
|
||||||
|
_, self, err := loadState(vmctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mi, err := loadMinerInfo(vmctx, self)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return types.NewInt(mi.SectorSize).Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sma StorageMinerActor2) IsSlashed(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) {
|
||||||
|
_, self, err := loadState(vmctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return cbg.EncodeBool(self.SlashedAt != 0), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: better name
|
||||||
|
func (sma StorageMinerActor2) CheckMiner(act *types.Actor, vmctx types.VMContext, params *CheckMinerParams) ([]byte, ActorError) {
|
||||||
|
if vmctx.Message().From != StoragePowerAddress {
|
||||||
|
return nil, aerrors.New(2, "only the storage power actor can check miner")
|
||||||
|
}
|
||||||
|
|
||||||
|
oldstate, self, err := loadState(vmctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isLate(vmctx.BlockHeight(), self) {
|
||||||
|
// Everything's fine
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.SlashedAt != 0 {
|
||||||
|
// Don't slash more than necessary
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.NetworkPower.Equals(self.Power) {
|
||||||
|
// Don't break the network when there's only one miner left
|
||||||
|
|
||||||
|
log.Warnf("can't slash miner %s for missed PoSt, no power would be left in the network", vmctx.Message().To)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slash for being late
|
||||||
|
|
||||||
|
self.SlashedAt = vmctx.BlockHeight()
|
||||||
|
|
||||||
|
nstate, err := vmctx.Storage().Put(self)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := vmctx.Storage().Commit(oldstate, nstate); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var out bytes.Buffer
|
||||||
|
if err := self.Power.MarshalCBOR(&out); err != nil {
|
||||||
|
return nil, aerrors.HandleExternalError(err, "marshaling return value")
|
||||||
|
}
|
||||||
|
return out.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sma StorageMinerActor2) DeclareFaults(act *types.Actor, vmctx types.VMContext, params *DeclareFaultsParams) ([]byte, ActorError) {
|
||||||
|
oldstate, self, aerr := loadState(vmctx)
|
||||||
|
if aerr != nil {
|
||||||
|
return nil, aerr
|
||||||
|
}
|
||||||
|
|
||||||
|
mi, aerr := loadMinerInfo(vmctx, self)
|
||||||
|
if aerr != nil {
|
||||||
|
return nil, aerr
|
||||||
|
}
|
||||||
|
|
||||||
|
if vmctx.Message().From != mi.Worker {
|
||||||
|
return nil, aerrors.New(1, "not authorized to declare faults for miner")
|
||||||
|
}
|
||||||
|
|
||||||
|
nfaults, err := types.MergeBitFields(params.Faults, self.FaultSet)
|
||||||
|
if err != nil {
|
||||||
|
return nil, aerrors.Absorb(err, 1, "failed to merge bitfields")
|
||||||
|
}
|
||||||
|
|
||||||
|
ss, nerr := amt2.LoadAMT(types.WrapStorage(vmctx.Storage()), self.Sectors)
|
||||||
|
if nerr != nil {
|
||||||
|
return nil, aerrors.HandleExternalError(nerr, "failed to load sector set")
|
||||||
|
}
|
||||||
|
|
||||||
|
cf, nerr := nfaults.Count()
|
||||||
|
if nerr != nil {
|
||||||
|
return nil, aerrors.Absorb(nerr, 2, "could not decode RLE+")
|
||||||
|
}
|
||||||
|
|
||||||
|
if cf > 2*ss.Count {
|
||||||
|
return nil, aerrors.Newf(3, "too many declared faults: %d > %d", cf, 2*ss.Count)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.FaultSet = nfaults
|
||||||
|
|
||||||
|
self.LastFaultSubmission = vmctx.BlockHeight()
|
||||||
|
|
||||||
|
nstate, aerr := vmctx.Storage().Put(self)
|
||||||
|
if aerr != nil {
|
||||||
|
return nil, aerr
|
||||||
|
}
|
||||||
|
if err := vmctx.Storage().Commit(oldstate, nstate); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sma StorageMinerActor2) SlashConsensusFault(act *types.Actor, vmctx types.VMContext, params *MinerSlashConsensusFault) ([]byte, ActorError) {
|
||||||
|
if vmctx.Message().From != StoragePowerAddress {
|
||||||
|
return nil, aerrors.New(1, "SlashConsensusFault may only be called by the storage market actor")
|
||||||
|
}
|
||||||
|
|
||||||
|
slashedCollateral := params.SlashedCollateral
|
||||||
|
if slashedCollateral.LessThan(act.Balance) {
|
||||||
|
slashedCollateral = act.Balance
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some of the slashed collateral should be paid to the slasher
|
||||||
|
// GROWTH_RATE determines how fast the slasher share of slashed collateral will increase as block elapses
|
||||||
|
// current GROWTH_RATE results in SLASHER_SHARE reaches 1 after 30 blocks
|
||||||
|
// TODO: define arithmetic precision and rounding for this operation
|
||||||
|
blockElapsed := vmctx.BlockHeight() - params.AtHeight
|
||||||
|
|
||||||
|
slasherShare := slasherShare(params.SlashedCollateral, blockElapsed)
|
||||||
|
|
||||||
|
burnPortion := types.BigSub(slashedCollateral, slasherShare)
|
||||||
|
|
||||||
|
_, err := vmctx.Send(vmctx.Message().From, 0, slasherShare, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, aerrors.Wrap(err, "failed to pay slasher")
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = vmctx.Send(BurntFundsAddress, 0, burnPortion, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, aerrors.Wrap(err, "failed to burn funds")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: this still allows the miner to commit sectors and submit posts,
|
||||||
|
// their users could potentially be unaffected, but the miner will never be
|
||||||
|
// able to mine a block again
|
||||||
|
// One potential issue: the miner will have to pay back the slashed
|
||||||
|
// collateral to continue submitting PoSts, which includes pledge
|
||||||
|
// collateral that they no longer really 'need'
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sma StorageMinerActor2) SubmitElectionPoSt(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, aerrors.ActorError) {
|
||||||
|
if vmctx.Message().From != NetworkAddress {
|
||||||
|
return nil, aerrors.Newf(1, "submit election post can only be called by the storage power actor")
|
||||||
|
}
|
||||||
|
|
||||||
|
oldstate, self, aerr := loadState(vmctx)
|
||||||
|
if aerr != nil {
|
||||||
|
return nil, aerr
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.SlashedAt != 0 {
|
||||||
|
return nil, aerrors.New(1, "slashed miners can't perform election PoSt")
|
||||||
|
}
|
||||||
|
|
||||||
|
pss, nerr := amt2.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet)
|
||||||
|
if nerr != nil {
|
||||||
|
return nil, aerrors.HandleExternalError(nerr, "failed to load proving set")
|
||||||
|
}
|
||||||
|
|
||||||
|
ss, nerr := amt2.LoadAMT(types.WrapStorage(vmctx.Storage()), self.Sectors)
|
||||||
|
if nerr != nil {
|
||||||
|
return nil, aerrors.HandleExternalError(nerr, "failed to load proving set")
|
||||||
|
}
|
||||||
|
|
||||||
|
faults, nerr := self.FaultSet.AllMap(2 * ss.Count)
|
||||||
|
if nerr != nil {
|
||||||
|
return nil, aerrors.Absorb(nerr, 1, "invalid bitfield (fatal?)")
|
||||||
|
}
|
||||||
|
|
||||||
|
activeFaults := uint64(0)
|
||||||
|
for f := range faults {
|
||||||
|
if f > amt2.MaxIndex {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var comms [][]byte
|
||||||
|
err := pss.Get(f, &comms)
|
||||||
|
if err != nil {
|
||||||
|
var notfound *amt2.ErrNotFound
|
||||||
|
if !xerrors.As(err, ¬found) {
|
||||||
|
return nil, aerrors.HandleExternalError(err, "failed to find sector in sector set")
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
activeFaults++
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := onSuccessfulPoSt(self, vmctx, activeFaults); err != nil { // TODO
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ncid, err := vmctx.Storage().Put(self)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := vmctx.Storage().Commit(oldstate, ncid); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
@ -85,7 +85,13 @@ func (spa StoragePowerActor) CreateStorageMiner(act *types.Actor, vmctx types.VM
|
|||||||
return nil, aerrors.Newf(1, "not enough funds passed to cover required miner collateral (needed %s, got %s)", reqColl, vmctx.Message().Value)
|
return nil, aerrors.Newf(1, "not enough funds passed to cover required miner collateral (needed %s, got %s)", reqColl, vmctx.Message().Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
encoded, err := CreateExecParams(StorageMinerCodeCid, &StorageMinerConstructorParams{
|
// FORK
|
||||||
|
minerCid := StorageMinerCodeCid
|
||||||
|
if vmctx.BlockHeight() > build.ForkFrigidHeight {
|
||||||
|
minerCid = StorageMiner2CodeCid
|
||||||
|
}
|
||||||
|
|
||||||
|
encoded, err := CreateExecParams(minerCid, &StorageMinerConstructorParams{
|
||||||
Owner: params.Owner,
|
Owner: params.Owner,
|
||||||
Worker: params.Worker,
|
Worker: params.Worker,
|
||||||
SectorSize: params.SectorSize,
|
SectorSize: params.SectorSize,
|
||||||
@ -138,6 +144,21 @@ func (spa StoragePowerActor) ArbitrateConsensusFault(act *types.Actor, vmctx typ
|
|||||||
return nil, aerrors.New(2, "blocks must be from the same miner")
|
return nil, aerrors.New(2, "blocks must be from the same miner")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FORK
|
||||||
|
if vmctx.BlockHeight() > build.ForkBlizzardHeight {
|
||||||
|
if params.Block1.Height <= build.ForkBlizzardHeight {
|
||||||
|
return nil, aerrors.New(10, "cannot slash miners with blocks from before blizzard")
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Block2.Height <= build.ForkBlizzardHeight {
|
||||||
|
return nil, aerrors.New(11, "cannot slash miners with blocks from before blizzard")
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Block1.Cid() == params.Block2.Cid() {
|
||||||
|
return nil, aerrors.New(3, "blocks must be different")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rval, err := vmctx.Send(params.Block1.Miner, MAMethods.GetWorkerAddr, types.NewInt(0), nil)
|
rval, err := vmctx.Send(params.Block1.Miner, MAMethods.GetWorkerAddr, types.NewInt(0), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, aerrors.Wrap(err, "failed to get miner worker")
|
return nil, aerrors.Wrap(err, "failed to get miner worker")
|
||||||
|
@ -93,7 +93,15 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
|
|||||||
signBlock(t, h.w, workerAddr, b1)
|
signBlock(t, h.w, workerAddr, b1)
|
||||||
signBlock(t, h.w, workerAddr, b2)
|
signBlock(t, h.w, workerAddr, b2)
|
||||||
|
|
||||||
|
h.BlockHeight = build.ForkBlizzardHeight + 1
|
||||||
ret, _ := h.Invoke(t, ownerAddr, StoragePowerAddress, SPAMethods.ArbitrateConsensusFault,
|
ret, _ := h.Invoke(t, ownerAddr, StoragePowerAddress, SPAMethods.ArbitrateConsensusFault,
|
||||||
|
&ArbitrateConsensusFaultParams{
|
||||||
|
Block1: b1,
|
||||||
|
Block2: b1,
|
||||||
|
})
|
||||||
|
assert.Equal(t, uint8(3), ret.ExitCode, "should have failed with exit 3")
|
||||||
|
|
||||||
|
ret, _ = h.Invoke(t, ownerAddr, StoragePowerAddress, SPAMethods.ArbitrateConsensusFault,
|
||||||
&ArbitrateConsensusFaultParams{
|
&ArbitrateConsensusFaultParams{
|
||||||
Block1: b1,
|
Block1: b1,
|
||||||
Block2: b2,
|
Block2: b2,
|
||||||
@ -145,7 +153,7 @@ func cheatStorageMarketTotal(t *testing.T, vm *vm.VM, bs bstore.Blockstore) {
|
|||||||
|
|
||||||
func fakeBlock(t *testing.T, minerAddr address.Address, ts uint64) *types.BlockHeader {
|
func fakeBlock(t *testing.T, minerAddr address.Address, ts uint64) *types.BlockHeader {
|
||||||
c := fakeCid(t, 1)
|
c := fakeCid(t, 1)
|
||||||
return &types.BlockHeader{Height: 5, Miner: minerAddr, Timestamp: ts, ParentStateRoot: c, Messages: c, ParentMessageReceipts: c, BLSAggregate: types.Signature{Type: types.KTBLS}}
|
return &types.BlockHeader{Height: 8000, Miner: minerAddr, Timestamp: ts, ParentStateRoot: c, Messages: c, ParentMessageReceipts: c, BLSAggregate: types.Signature{Type: types.KTBLS}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func fakeCid(t *testing.T, s int) cid.Cid {
|
func fakeCid(t *testing.T, s int) cid.Cid {
|
||||||
|
@ -12,6 +12,7 @@ var CronCodeCid cid.Cid
|
|||||||
var StoragePowerCodeCid cid.Cid
|
var StoragePowerCodeCid cid.Cid
|
||||||
var StorageMarketCodeCid cid.Cid
|
var StorageMarketCodeCid cid.Cid
|
||||||
var StorageMinerCodeCid cid.Cid
|
var StorageMinerCodeCid cid.Cid
|
||||||
|
var StorageMiner2CodeCid cid.Cid
|
||||||
var MultisigCodeCid cid.Cid
|
var MultisigCodeCid cid.Cid
|
||||||
var InitCodeCid cid.Cid
|
var InitCodeCid cid.Cid
|
||||||
var PaymentChannelCodeCid cid.Cid
|
var PaymentChannelCodeCid cid.Cid
|
||||||
@ -46,6 +47,7 @@ func init() {
|
|||||||
StoragePowerCodeCid = mustSum("fil/1/power")
|
StoragePowerCodeCid = mustSum("fil/1/power")
|
||||||
StorageMarketCodeCid = mustSum("fil/1/market")
|
StorageMarketCodeCid = mustSum("fil/1/market")
|
||||||
StorageMinerCodeCid = mustSum("fil/1/miner")
|
StorageMinerCodeCid = mustSum("fil/1/miner")
|
||||||
|
StorageMiner2CodeCid = mustSum("fil/1/miner/2")
|
||||||
MultisigCodeCid = mustSum("fil/1/multisig")
|
MultisigCodeCid = mustSum("fil/1/multisig")
|
||||||
InitCodeCid = mustSum("fil/1/init")
|
InitCodeCid = mustSum("fil/1/init")
|
||||||
PaymentChannelCodeCid = mustSum("fil/1/paych")
|
PaymentChannelCodeCid = mustSum("fil/1/paych")
|
||||||
|
@ -94,7 +94,7 @@ func (ms *msgSet) add(m *types.SignedMessage) error {
|
|||||||
if _, has := ms.msgs[m.Message.Nonce]; has {
|
if _, has := ms.msgs[m.Message.Nonce]; has {
|
||||||
if m.Cid() != ms.msgs[m.Message.Nonce].Cid() {
|
if m.Cid() != ms.msgs[m.Message.Nonce].Cid() {
|
||||||
log.Error("Add with duplicate nonce")
|
log.Error("Add with duplicate nonce")
|
||||||
return xerrors.Errorf("message to %s with nonce %d already in mpool")
|
return xerrors.Errorf("message to %s with nonce %d already in mpool", m.Message.To, m.Message.Nonce)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ms.msgs[m.Message.Nonce] = m
|
ms.msgs[m.Message.Nonce] = m
|
||||||
|
@ -3,14 +3,147 @@ package stmgr
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
amt "github.com/filecoin-project/go-amt-ipld/v2"
|
||||||
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
|
"github.com/filecoin-project/lotus/chain/state"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
hamt "github.com/ipfs/go-hamt-ipld"
|
||||||
|
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (sm *StateManager) handleStateForks(ctx context.Context, pstate cid.Cid, height, parentH uint64) (_ cid.Cid, err error) {
|
func (sm *StateManager) handleStateForks(ctx context.Context, pstate cid.Cid, height, parentH uint64) (_ cid.Cid, err error) {
|
||||||
for i := parentH; i < height; i++ {
|
for i := parentH; i < height; i++ {
|
||||||
switch i {
|
switch i {
|
||||||
|
case build.ForkBlizzardHeight:
|
||||||
|
log.Warnw("Executing blizzard fork logic", "height", i)
|
||||||
|
npstate, err := fixBlizzardAMTBug(ctx, sm, pstate)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("blizzard bug fix failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return npstate, nil
|
||||||
|
case build.ForkFrigidHeight:
|
||||||
|
log.Warnw("Executing frigid fork logic", "height", i)
|
||||||
|
npstate, err := fixBlizzardAMTBug(ctx, sm, pstate)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("frigid bug fix failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return npstate, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pstate, nil
|
return pstate, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
1) Iterate through each miner in the chain:
|
||||||
|
1.1) Fixup their sector set and proving set
|
||||||
|
1.2) Change their code cid to point to the new miner actor code
|
||||||
|
*/
|
||||||
|
func fixBlizzardAMTBug(ctx context.Context, sm *StateManager, pstate cid.Cid) (cid.Cid, error) {
|
||||||
|
cst := hamt.CSTFromBstore(sm.cs.Blockstore())
|
||||||
|
st, err := state.LoadStateTree(cst, pstate)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
|
}
|
||||||
|
|
||||||
|
spa, err := st.GetActor(actors.StoragePowerAddress)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("failed to get storage power actor: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var spast actors.StoragePowerState
|
||||||
|
if err := cst.Get(ctx, spa.Head, &spast); err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
|
}
|
||||||
|
|
||||||
|
miners, err := actors.MinerSetList(ctx, cst, spast.Miners)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, m := range miners {
|
||||||
|
mact, err := st.GetActor(m)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("getting miner actor to fix: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nhead, err := fixMiner(ctx, cst, sm.cs.Blockstore(), mact.Head)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("fixing miner: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if nhead != mact.Head {
|
||||||
|
log.Warnf("Miner %s had changes", m)
|
||||||
|
}
|
||||||
|
|
||||||
|
mact.Head = nhead
|
||||||
|
mact.Code = actors.StorageMiner2CodeCid
|
||||||
|
|
||||||
|
if err := st.SetActor(m, mact); err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return st.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
func fixMiner(ctx context.Context, cst *hamt.CborIpldStore, bs blockstore.Blockstore, mscid cid.Cid) (cid.Cid, error) {
|
||||||
|
var mstate actors.StorageMinerActorState
|
||||||
|
if err := cst.Get(ctx, mscid, &mstate); err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("failed to load miner actor state: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
amts := amt.WrapBlockstore(bs)
|
||||||
|
|
||||||
|
nsectors, err := amtFsck(amts, mstate.Sectors)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("error fsck'ing sector set: %w", err)
|
||||||
|
}
|
||||||
|
mstate.Sectors = nsectors
|
||||||
|
|
||||||
|
nproving, err := amtFsck(amts, mstate.ProvingSet)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("error fsck'ing proving set: %w", err)
|
||||||
|
}
|
||||||
|
mstate.ProvingSet = nproving
|
||||||
|
|
||||||
|
nmcid, err := cst.Put(ctx, &mstate)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("failed to put modified miner state: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nmcid, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func amtFsck(s amt.Blocks, ss cid.Cid) (cid.Cid, error) {
|
||||||
|
a, err := amt.LoadAMT(s, ss)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("could not load AMT: %w", a)
|
||||||
|
}
|
||||||
|
|
||||||
|
b := amt.NewAMT(s)
|
||||||
|
|
||||||
|
err = a.ForEach(func(id uint64, data *cbg.Deferred) error {
|
||||||
|
err := b.Set(id, data)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("could not copy at idx (%d): %w", id, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("could not copy: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nss, err := b.Flush()
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("could not flush: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nss, nil
|
||||||
|
}
|
||||||
|
@ -10,7 +10,9 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/chain/vm"
|
||||||
|
|
||||||
amt "github.com/filecoin-project/go-amt-ipld"
|
amt "github.com/filecoin-project/go-amt-ipld"
|
||||||
cid "github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
@ -311,3 +313,37 @@ func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.C
|
|||||||
|
|
||||||
return sset, nil
|
return sset, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ComputeState(ctx context.Context, sm *StateManager, height uint64, msgs []*types.Message, ts *types.TipSet) (cid.Cid, error) {
|
||||||
|
if ts == nil {
|
||||||
|
ts = sm.cs.GetHeaviestTipSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
base, _, err := sm.TipSetState(ctx, ts)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fstate, err := sm.handleStateForks(ctx, base, height, ts.Height())
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := store.NewChainRand(sm.cs, ts.Cids(), height)
|
||||||
|
vmi, err := vm.NewVM(fstate, height, r, actors.NetworkAddress, sm.cs.Blockstore(), sm.cs.VMSys())
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, msg := range msgs {
|
||||||
|
ret, err := vmi.ApplyMessage(ctx, msg)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("applying message %s: %w", msg.Cid(), err)
|
||||||
|
}
|
||||||
|
if ret.ExitCode != 0 {
|
||||||
|
log.Infof("compute state apply message %d failed (exit: %d): %s", i, ret.ExitCode, ret.ActorErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vmi.Flush(ctx)
|
||||||
|
}
|
||||||
|
@ -730,6 +730,30 @@ func (cs *ChainStore) readMsgMetaCids(mmc cid.Cid) ([]cid.Cid, []cid.Cid, error)
|
|||||||
return blscids, secpkcids, nil
|
return blscids, secpkcids, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cs *ChainStore) GetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*HeadChange, error) {
|
||||||
|
fts, err := cs.LoadTipSet(from)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("loading from tipset %s: %w", from, err)
|
||||||
|
}
|
||||||
|
tts, err := cs.LoadTipSet(to)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("loading to tipset %s: %w", to, err)
|
||||||
|
}
|
||||||
|
revert, apply, err := cs.ReorgOps(fts, tts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("error getting tipset branches: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
path := make([]*HeadChange, len(revert)+len(apply))
|
||||||
|
for i, r := range revert {
|
||||||
|
path[i] = &HeadChange{Type: HCRevert, Val: r}
|
||||||
|
}
|
||||||
|
for j, i := 0, len(apply)-1; i >= 0; j, i = j+1, i-1 {
|
||||||
|
path[j+len(revert)] = &HeadChange{Type: HCApply, Val: apply[i]}
|
||||||
|
}
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) MessagesForBlock(b *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) {
|
func (cs *ChainStore) MessagesForBlock(b *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) {
|
||||||
blscids, secpkcids, err := cs.readMsgMetaCids(b.Messages)
|
blscids, secpkcids, err := cs.readMsgMetaCids(b.Messages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -35,6 +35,7 @@ func newInvoker() *invoker {
|
|||||||
inv.register(actors.StoragePowerCodeCid, actors.StoragePowerActor{}, actors.StoragePowerState{})
|
inv.register(actors.StoragePowerCodeCid, actors.StoragePowerActor{}, actors.StoragePowerState{})
|
||||||
inv.register(actors.StorageMarketCodeCid, actors.StorageMarketActor{}, actors.StorageMarketState{})
|
inv.register(actors.StorageMarketCodeCid, actors.StorageMarketActor{}, actors.StorageMarketState{})
|
||||||
inv.register(actors.StorageMinerCodeCid, actors.StorageMinerActor{}, actors.StorageMinerActorState{})
|
inv.register(actors.StorageMinerCodeCid, actors.StorageMinerActor{}, actors.StorageMinerActorState{})
|
||||||
|
inv.register(actors.StorageMiner2CodeCid, actors.StorageMinerActor2{}, actors.StorageMinerActorState{})
|
||||||
inv.register(actors.MultisigCodeCid, actors.MultiSigActor{}, actors.MultiSigActorState{})
|
inv.register(actors.MultisigCodeCid, actors.MultiSigActor{}, actors.MultiSigActorState{})
|
||||||
inv.register(actors.PaymentChannelCodeCid, actors.PaymentChannelActor{}, actors.PaymentChannelActorState{})
|
inv.register(actors.PaymentChannelCodeCid, actors.PaymentChannelActor{}, actors.PaymentChannelActorState{})
|
||||||
|
|
||||||
|
@ -467,7 +467,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, msg *types.Message) (*ApplyRet,
|
|||||||
return nil, xerrors.Errorf("[from=%s,to=%s,n=%d,m=%d,h=%d] fatal error: %w", msg.From, msg.To, msg.Nonce, msg.Method, vm.blockHeight, actorErr)
|
return nil, xerrors.Errorf("[from=%s,to=%s,n=%d,m=%d,h=%d] fatal error: %w", msg.From, msg.To, msg.Nonce, msg.Method, vm.blockHeight, actorErr)
|
||||||
}
|
}
|
||||||
if actorErr != nil {
|
if actorErr != nil {
|
||||||
log.Warnf("[from=%s,to=%s,n=%d,m=%d,h=%d] Send actor error: %+v", msg.From, msg.To, msg.Nonce, msg.Method, vm.blockHeight, actorErr)
|
log.Warnw("Send actor error", "from", msg.From, "to", msg.To, "nonce", msg.Nonce, "method", msg.Method, "height", vm.blockHeight, "error", fmt.Sprintf("%+v", actorErr))
|
||||||
}
|
}
|
||||||
|
|
||||||
var errcode uint8
|
var errcode uint8
|
||||||
|
68
cli/state.go
68
cli/state.go
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/miner"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
@ -37,6 +38,7 @@ var stateCmd = &cli.Command{
|
|||||||
stateSectorSizeCmd,
|
stateSectorSizeCmd,
|
||||||
stateReadStateCmd,
|
stateReadStateCmd,
|
||||||
stateListMessagesCmd,
|
stateListMessagesCmd,
|
||||||
|
stateComputeStateCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -580,3 +582,69 @@ var stateListMessagesCmd = &cli.Command{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var stateComputeStateCmd = &cli.Command{
|
||||||
|
Name: "compute-state",
|
||||||
|
Usage: "Perform state computations",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.Uint64Flag{
|
||||||
|
Name: "height",
|
||||||
|
Usage: "set the height to compute state at",
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "apply-mpool-messages",
|
||||||
|
Usage: "apply messages from the mempool to the computed state",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer()
|
||||||
|
|
||||||
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
|
ts, err := loadTipSet(ctx, cctx, api)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
h := cctx.Uint64("height")
|
||||||
|
if h == 0 {
|
||||||
|
if ts == nil {
|
||||||
|
head, err := api.ChainHead(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ts = head
|
||||||
|
}
|
||||||
|
h = ts.Height()
|
||||||
|
}
|
||||||
|
|
||||||
|
var msgs []*types.Message
|
||||||
|
if cctx.Bool("apply-mpool-messages") {
|
||||||
|
pmsgs, err := api.MpoolPending(ctx, ts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pmsgs, err = miner.SelectMessages(ctx, api.StateGetActor, ts, pmsgs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sm := range pmsgs {
|
||||||
|
msgs = append(msgs, &sm.Message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nstate, err := api.StateCompute(ctx, h, msgs, ts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("computed state cid: ", nstate)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -221,7 +221,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
|
|||||||
|
|
||||||
for addr, m := range actors {
|
for addr, m := range actors {
|
||||||
for actor, c := range m {
|
for actor, c := range m {
|
||||||
if actor.Code != actors2.StorageMinerCodeCid {
|
if !(actor.Code == actors2.StorageMinerCodeCid || actor.Code == actors2.StorageMiner2CodeCid) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) {
|
|||||||
createStorageMinerMsg := &types.Message{
|
createStorageMinerMsg := &types.Message{
|
||||||
To: actors.StoragePowerAddress,
|
To: actors.StoragePowerAddress,
|
||||||
From: h.from,
|
From: h.from,
|
||||||
Value: collateral,
|
Value: types.BigAdd(collateral, types.BigDiv(collateral, types.NewInt(100))),
|
||||||
|
|
||||||
Method: actors.SPAMethods.CreateStorageMiner,
|
Method: actors.SPAMethods.CreateStorageMiner,
|
||||||
Params: params,
|
Params: params,
|
||||||
|
1
go.mod
1
go.mod
@ -14,6 +14,7 @@ require (
|
|||||||
github.com/filecoin-project/filecoin-ffi v0.0.0-20191219131535-bb699517a590
|
github.com/filecoin-project/filecoin-ffi v0.0.0-20191219131535-bb699517a590
|
||||||
github.com/filecoin-project/go-address v0.0.0-20191219011437-af739c490b4f
|
github.com/filecoin-project/go-address v0.0.0-20191219011437-af739c490b4f
|
||||||
github.com/filecoin-project/go-amt-ipld v0.0.0-20191205011053-79efc22d6cdc
|
github.com/filecoin-project/go-amt-ipld v0.0.0-20191205011053-79efc22d6cdc
|
||||||
|
github.com/filecoin-project/go-amt-ipld/v2 v2.0.0
|
||||||
github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2
|
github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2
|
||||||
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03
|
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03
|
||||||
github.com/filecoin-project/go-data-transfer v0.0.0-20191219005021-4accf56bd2ce
|
github.com/filecoin-project/go-data-transfer v0.0.0-20191219005021-4accf56bd2ce
|
||||||
|
29
go.sum
29
go.sum
@ -3,14 +3,12 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
|||||||
contrib.go.opencensus.io/exporter/jaeger v0.1.0 h1:WNc9HbA38xEQmsI40Tjd/MNU/g8byN2Of7lwIjv0Jdc=
|
contrib.go.opencensus.io/exporter/jaeger v0.1.0 h1:WNc9HbA38xEQmsI40Tjd/MNU/g8byN2Of7lwIjv0Jdc=
|
||||||
contrib.go.opencensus.io/exporter/jaeger v0.1.0/go.mod h1:VYianECmuFPwU37O699Vc1GOcy+y8kOsfaxHRImmjbA=
|
contrib.go.opencensus.io/exporter/jaeger v0.1.0/go.mod h1:VYianECmuFPwU37O699Vc1GOcy+y8kOsfaxHRImmjbA=
|
||||||
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
||||||
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9 h1:HD8gA2tkByhMAwYaFAX9w2l7vxvBQ5NMoxDrkhqhtn4=
|
|
||||||
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM=
|
github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM=
|
||||||
github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||||
github.com/GeertJohan/go.incremental v1.0.0 h1:7AH+pY1XUgQE4Y1HcXYaMqAI0m9yrFqo/jt0CW30vsg=
|
github.com/GeertJohan/go.incremental v1.0.0 h1:7AH+pY1XUgQE4Y1HcXYaMqAI0m9yrFqo/jt0CW30vsg=
|
||||||
github.com/GeertJohan/go.incremental v1.0.0 h1:7AH+pY1XUgQE4Y1HcXYaMqAI0m9yrFqo/jt0CW30vsg=
|
|
||||||
github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
|
github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
|
||||||
github.com/GeertJohan/go.rice v1.0.0 h1:KkI6O9uMaQU3VEKaj01ulavtF7o1fWT7+pk/4voiMLQ=
|
github.com/GeertJohan/go.rice v1.0.0 h1:KkI6O9uMaQU3VEKaj01ulavtF7o1fWT7+pk/4voiMLQ=
|
||||||
github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
|
github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
|
||||||
@ -93,7 +91,6 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn
|
|||||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY=
|
github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY=
|
||||||
github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8=
|
github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8=
|
||||||
@ -104,6 +101,8 @@ github.com/filecoin-project/go-address v0.0.0-20191219011437-af739c490b4f h1:L2j
|
|||||||
github.com/filecoin-project/go-address v0.0.0-20191219011437-af739c490b4f/go.mod h1:rCbpXPva2NKF9/J4X6sr7hbKBgQCxyFtRj7KOZqoIms=
|
github.com/filecoin-project/go-address v0.0.0-20191219011437-af739c490b4f/go.mod h1:rCbpXPva2NKF9/J4X6sr7hbKBgQCxyFtRj7KOZqoIms=
|
||||||
github.com/filecoin-project/go-amt-ipld v0.0.0-20191205011053-79efc22d6cdc h1:cODZD2YzpTUtrOSxbEnWFcQHidNRZiRdvLxySjGvG/M=
|
github.com/filecoin-project/go-amt-ipld v0.0.0-20191205011053-79efc22d6cdc h1:cODZD2YzpTUtrOSxbEnWFcQHidNRZiRdvLxySjGvG/M=
|
||||||
github.com/filecoin-project/go-amt-ipld v0.0.0-20191205011053-79efc22d6cdc/go.mod h1:KsFPWjF+UUYl6n9A+qbg4bjFgAOneicFZtDH/LQEX2U=
|
github.com/filecoin-project/go-amt-ipld v0.0.0-20191205011053-79efc22d6cdc/go.mod h1:KsFPWjF+UUYl6n9A+qbg4bjFgAOneicFZtDH/LQEX2U=
|
||||||
|
github.com/filecoin-project/go-amt-ipld/v2 v2.0.0 h1:rQ7GTJbWE5XqUCPiBgs4gbTKD2wC7MynZhSaf7ZzlUM=
|
||||||
|
github.com/filecoin-project/go-amt-ipld/v2 v2.0.0/go.mod h1:PAZ5tvSfMfWE327osqFXKm7cBpCpBk2Nh0qKsJUmjjk=
|
||||||
github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8=
|
github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8=
|
||||||
github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2/go.mod h1:pqTiPHobNkOVM5thSRsHYjyQfq7O5QSCMhvuu9JoDlg=
|
github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2/go.mod h1:pqTiPHobNkOVM5thSRsHYjyQfq7O5QSCMhvuu9JoDlg=
|
||||||
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus=
|
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus=
|
||||||
@ -131,7 +130,6 @@ github.com/filecoin-project/go-paramfetch v0.0.0-20200102181131-b20d579f2878/go.
|
|||||||
github.com/filecoin-project/go-paramfetch v0.0.0-20200102181131-b20d579f2878/go.mod h1:40kI2Gv16mwcRsHptI3OAV4nlOEU7wVDc4RgMylNFjU=
|
github.com/filecoin-project/go-paramfetch v0.0.0-20200102181131-b20d579f2878/go.mod h1:40kI2Gv16mwcRsHptI3OAV4nlOEU7wVDc4RgMylNFjU=
|
||||||
github.com/filecoin-project/go-paramfetch v0.0.1 h1:gV7bs5YaqlgpGFMiLxInGK2L1FyCXUE0rimz4L7ghoE=
|
github.com/filecoin-project/go-paramfetch v0.0.1 h1:gV7bs5YaqlgpGFMiLxInGK2L1FyCXUE0rimz4L7ghoE=
|
||||||
github.com/filecoin-project/go-paramfetch v0.0.1/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc=
|
github.com/filecoin-project/go-paramfetch v0.0.1/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc=
|
||||||
github.com/filecoin-project/go-sectorbuilder v0.0.1 h1:yiLSEprWA1E43DFTSCXLSuCstYuDKiI6RCXiYz4GaRs=
|
|
||||||
github.com/filecoin-project/go-sectorbuilder v0.0.1/go.mod h1:3OZ4E3B2OuwhJjtxR4r7hPU9bCfB+A+hm4alLEsaeDc=
|
github.com/filecoin-project/go-sectorbuilder v0.0.1/go.mod h1:3OZ4E3B2OuwhJjtxR4r7hPU9bCfB+A+hm4alLEsaeDc=
|
||||||
github.com/filecoin-project/go-sectorbuilder v0.0.2-0.20200114015900-4103afa82689 h1:2cT5bhm/5I0RY+HBIPdRRrtjCwLj33Qx6DHRs9TCslY=
|
github.com/filecoin-project/go-sectorbuilder v0.0.2-0.20200114015900-4103afa82689 h1:2cT5bhm/5I0RY+HBIPdRRrtjCwLj33Qx6DHRs9TCslY=
|
||||||
github.com/filecoin-project/go-sectorbuilder v0.0.2-0.20200114015900-4103afa82689/go.mod h1:3OZ4E3B2OuwhJjtxR4r7hPU9bCfB+A+hm4alLEsaeDc=
|
github.com/filecoin-project/go-sectorbuilder v0.0.2-0.20200114015900-4103afa82689/go.mod h1:3OZ4E3B2OuwhJjtxR4r7hPU9bCfB+A+hm4alLEsaeDc=
|
||||||
@ -240,7 +238,6 @@ github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj
|
|||||||
github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
|
github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
|
||||||
github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
|
github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
|
||||||
github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
|
github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
|
||||||
github.com/ipfs/go-datastore v0.1.1 h1:F4k0TkTAZGLFzBOrVKDAvch6JZtuN4NHkfdcEZL50aI=
|
|
||||||
github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw=
|
github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw=
|
||||||
github.com/ipfs/go-datastore v0.3.1 h1:SS1t869a6cctoSYmZXUk8eL6AzVXgASmKIWFNQkQ1jU=
|
github.com/ipfs/go-datastore v0.3.1 h1:SS1t869a6cctoSYmZXUk8eL6AzVXgASmKIWFNQkQ1jU=
|
||||||
github.com/ipfs/go-datastore v0.3.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw=
|
github.com/ipfs/go-datastore v0.3.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw=
|
||||||
@ -248,7 +245,6 @@ github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ
|
|||||||
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
|
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
|
||||||
github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8=
|
github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8=
|
||||||
github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s=
|
github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s=
|
||||||
github.com/ipfs/go-ds-badger v0.0.7 h1:NMyh88Q50HG6/S2YD58DLkq0c0/ZQPMbSojONH+PRf4=
|
|
||||||
github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk=
|
github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk=
|
||||||
github.com/ipfs/go-ds-badger2 v0.0.0-20200108185345-7f650e6b2521 h1:GSygNXXIRXFVntMR3Yr30imf40H9cYDAw72Qb0za2nE=
|
github.com/ipfs/go-ds-badger2 v0.0.0-20200108185345-7f650e6b2521 h1:GSygNXXIRXFVntMR3Yr30imf40H9cYDAw72Qb0za2nE=
|
||||||
github.com/ipfs/go-ds-badger2 v0.0.0-20200108185345-7f650e6b2521/go.mod h1:oDKWqmQbLyyml3mgMtHgB7qAf6cQOEsJPRLFzfwKQ5Q=
|
github.com/ipfs/go-ds-badger2 v0.0.0-20200108185345-7f650e6b2521/go.mod h1:oDKWqmQbLyyml3mgMtHgB7qAf6cQOEsJPRLFzfwKQ5Q=
|
||||||
@ -299,15 +295,9 @@ github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dC
|
|||||||
github.com/ipfs/go-ipld-format v0.0.2 h1:OVAGlyYT6JPZ0pEfGntFPS40lfrDmaDbQwNHEY2G9Zs=
|
github.com/ipfs/go-ipld-format v0.0.2 h1:OVAGlyYT6JPZ0pEfGntFPS40lfrDmaDbQwNHEY2G9Zs=
|
||||||
github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k=
|
github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k=
|
||||||
github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM=
|
github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM=
|
||||||
github.com/ipfs/go-log v1.0.0 h1:BW3LQIiZzpNyolt84yvKNCd3FU+AK4VDw1hnHR+1aiI=
|
|
||||||
github.com/ipfs/go-log v1.0.0/go.mod h1:JO7RzlMK6rA+CIxFMLOuB6Wf5b81GDiKElL7UPSIKjA=
|
github.com/ipfs/go-log v1.0.0/go.mod h1:JO7RzlMK6rA+CIxFMLOuB6Wf5b81GDiKElL7UPSIKjA=
|
||||||
github.com/ipfs/go-log v1.0.1 h1:5lIEEOQTk/vd1WuPFBRqz2mcp+5G1fMVcW+Ib/H5Hfo=
|
github.com/ipfs/go-log v1.0.1 h1:5lIEEOQTk/vd1WuPFBRqz2mcp+5G1fMVcW+Ib/H5Hfo=
|
||||||
github.com/ipfs/go-log v1.0.1 h1:5lIEEOQTk/vd1WuPFBRqz2mcp+5G1fMVcW+Ib/H5Hfo=
|
|
||||||
github.com/ipfs/go-log v1.0.1/go.mod h1:HuWlQttfN6FWNHRhlY5yMk/lW7evQC0HHGOxEwMRR8I=
|
github.com/ipfs/go-log v1.0.1/go.mod h1:HuWlQttfN6FWNHRhlY5yMk/lW7evQC0HHGOxEwMRR8I=
|
||||||
github.com/ipfs/go-log v1.0.1/go.mod h1:HuWlQttfN6FWNHRhlY5yMk/lW7evQC0HHGOxEwMRR8I=
|
|
||||||
github.com/ipfs/go-log/v2 v2.0.1 h1:mnR9XFltezAtO8A6tj5U7nKkRzhEQNEw/wT11U2HhPM=
|
|
||||||
github.com/ipfs/go-log/v2 v2.0.1 h1:mnR9XFltezAtO8A6tj5U7nKkRzhEQNEw/wT11U2HhPM=
|
|
||||||
github.com/ipfs/go-log/v2 v2.0.1/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0=
|
|
||||||
github.com/ipfs/go-log/v2 v2.0.1/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0=
|
github.com/ipfs/go-log/v2 v2.0.1/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0=
|
||||||
github.com/ipfs/go-log/v2 v2.0.2 h1:xguurydRdfKMJjKyxNXNU8lYP0VZH1NUwJRwUorjuEw=
|
github.com/ipfs/go-log/v2 v2.0.2 h1:xguurydRdfKMJjKyxNXNU8lYP0VZH1NUwJRwUorjuEw=
|
||||||
github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0=
|
github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0=
|
||||||
@ -467,7 +457,6 @@ github.com/libp2p/go-libp2p-peerstore v0.0.1/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4T
|
|||||||
github.com/libp2p/go-libp2p-peerstore v0.0.6/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20=
|
github.com/libp2p/go-libp2p-peerstore v0.0.6/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20=
|
||||||
github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY=
|
github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY=
|
||||||
github.com/libp2p/go-libp2p-peerstore v0.1.2/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI=
|
github.com/libp2p/go-libp2p-peerstore v0.1.2/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI=
|
||||||
github.com/libp2p/go-libp2p-peerstore v0.1.3 h1:wMgajt1uM2tMiqf4M+4qWKVyyFc8SfA+84VV9glZq1M=
|
|
||||||
github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI=
|
github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI=
|
||||||
github.com/libp2p/go-libp2p-peerstore v0.1.4 h1:d23fvq5oYMJ/lkkbO4oTwBp/JP+I/1m5gZJobNXCE/k=
|
github.com/libp2p/go-libp2p-peerstore v0.1.4 h1:d23fvq5oYMJ/lkkbO4oTwBp/JP+I/1m5gZJobNXCE/k=
|
||||||
github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs=
|
github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs=
|
||||||
@ -489,7 +478,6 @@ github.com/libp2p/go-libp2p-routing-helpers v0.1.0/go.mod h1:oUs0h39vNwYtYXnQWOT
|
|||||||
github.com/libp2p/go-libp2p-secio v0.0.3/go.mod h1:hS7HQ00MgLhRO/Wyu1bTX6ctJKhVpm+j2/S2A5UqYb0=
|
github.com/libp2p/go-libp2p-secio v0.0.3/go.mod h1:hS7HQ00MgLhRO/Wyu1bTX6ctJKhVpm+j2/S2A5UqYb0=
|
||||||
github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8=
|
github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8=
|
||||||
github.com/libp2p/go-libp2p-secio v0.1.1/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8=
|
github.com/libp2p/go-libp2p-secio v0.1.1/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8=
|
||||||
github.com/libp2p/go-libp2p-secio v0.2.0 h1:ywzZBsWEEz2KNTn5RtzauEDq5RFEefPsttXYwAWqHng=
|
|
||||||
github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g=
|
github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g=
|
||||||
github.com/libp2p/go-libp2p-secio v0.2.1 h1:eNWbJTdyPA7NxhP7J3c5lT97DC5d+u+IldkgCYFTPVA=
|
github.com/libp2p/go-libp2p-secio v0.2.1 h1:eNWbJTdyPA7NxhP7J3c5lT97DC5d+u+IldkgCYFTPVA=
|
||||||
github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8=
|
github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8=
|
||||||
@ -540,7 +528,6 @@ github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FW
|
|||||||
github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA=
|
github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA=
|
||||||
github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4=
|
github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4=
|
||||||
github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs=
|
github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs=
|
||||||
github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw=
|
|
||||||
github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14=
|
github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14=
|
||||||
github.com/libp2p/go-stream-muxer v0.1.0/go.mod h1:8JAVsjeRBCWwPoZeH0W1imLOcriqXJyFvB0mR4A04sQ=
|
github.com/libp2p/go-stream-muxer v0.1.0/go.mod h1:8JAVsjeRBCWwPoZeH0W1imLOcriqXJyFvB0mR4A04sQ=
|
||||||
github.com/libp2p/go-stream-muxer-multistream v0.1.1/go.mod h1:zmGdfkQ1AzOECIAcccoL8L//laqawOsO03zX8Sa+eGw=
|
github.com/libp2p/go-stream-muxer-multistream v0.1.1/go.mod h1:zmGdfkQ1AzOECIAcccoL8L//laqawOsO03zX8Sa+eGw=
|
||||||
@ -568,7 +555,6 @@ github.com/marten-seemann/qtls v0.2.3 h1:0yWJ43C62LsZt08vuQJDK1uC1czUc3FJeCLPoNA
|
|||||||
github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk=
|
github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||||
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
|
||||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
@ -726,7 +712,6 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
|
|||||||
github.com/urfave/cli/v2 v2.0.0 h1:+HU9SCbu8GnEUFtIBfuUNXN39ofWViIEJIp6SURMpCg=
|
github.com/urfave/cli/v2 v2.0.0 h1:+HU9SCbu8GnEUFtIBfuUNXN39ofWViIEJIp6SURMpCg=
|
||||||
github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
|
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
|
||||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||||
@ -769,12 +754,10 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:
|
|||||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||||
go.opencensus.io v0.22.1 h1:8dP3SGL7MPB94crU3bEPplMPe83FI4EouesJUeFHv50=
|
|
||||||
go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA=
|
go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA=
|
||||||
go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs=
|
go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs=
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
|
|
||||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
go.uber.org/atomic v1.5.1 h1:rsqfU5vBkVknbhUGbAUwQKR2H4ItV8tjJ+6kJX4cxHM=
|
go.uber.org/atomic v1.5.1 h1:rsqfU5vBkVknbhUGbAUwQKR2H4ItV8tjJ+6kJX4cxHM=
|
||||||
go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
@ -790,7 +773,6 @@ go.uber.org/multierr v1.4.0 h1:f3WCSC2KzAcBXGATIxAB1E2XuCpNU255wNKZ505qi3E=
|
|||||||
go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU=
|
go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU=
|
||||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||||
@ -811,7 +793,6 @@ golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
|
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
|
||||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
@ -820,7 +801,6 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk
|
|||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE=
|
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE=
|
||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||||
@ -841,12 +821,10 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
|
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@ -877,7 +855,6 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ=
|
|
||||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200107162124-548cf772de50 h1:YvQ10rzcqWXLlJZ3XCUoO25savxmscf4+SC+ZqiCHhA=
|
golang.org/x/sys v0.0.0-20200107162124-548cf772de50 h1:YvQ10rzcqWXLlJZ3XCUoO25savxmscf4+SC+ZqiCHhA=
|
||||||
golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@ -900,7 +877,6 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw
|
|||||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361 h1:RIIXAeV6GvDBuADKumTODatUqANFZ+5BPMnzsy4hulY=
|
|
||||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20200108195415-316d2f248479 h1:csuS+MHeEA2eWhyjQCMaPMq4z1+/PohkBSjJZHSIbOE=
|
golang.org/x/tools v0.0.0-20200108195415-316d2f248479 h1:csuS+MHeEA2eWhyjQCMaPMq4z1+/PohkBSjJZHSIbOE=
|
||||||
golang.org/x/tools v0.0.0-20200108195415-316d2f248479/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200108195415-316d2f248479/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
@ -920,7 +896,6 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn
|
|||||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU=
|
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
|
@ -2,6 +2,7 @@ package miner
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -11,6 +12,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/lotus/chain/gen"
|
"github.com/filecoin-project/lotus/chain/gen"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
lru "github.com/hashicorp/golang-lru"
|
||||||
|
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
@ -22,6 +24,11 @@ var log = logging.Logger("miner")
|
|||||||
type waitFunc func(ctx context.Context, baseTime uint64) error
|
type waitFunc func(ctx context.Context, baseTime uint64) error
|
||||||
|
|
||||||
func NewMiner(api api.FullNode, epp gen.ElectionPoStProver) *Miner {
|
func NewMiner(api api.FullNode, epp gen.ElectionPoStProver) *Miner {
|
||||||
|
arc, err := lru.NewARC(10000)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
return &Miner{
|
return &Miner{
|
||||||
api: api,
|
api: api,
|
||||||
epp: epp,
|
epp: epp,
|
||||||
@ -32,6 +39,7 @@ func NewMiner(api api.FullNode, epp gen.ElectionPoStProver) *Miner {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
minedBlockHeights: arc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +56,8 @@ type Miner struct {
|
|||||||
waitFunc waitFunc
|
waitFunc waitFunc
|
||||||
|
|
||||||
lastWork *MiningBase
|
lastWork *MiningBase
|
||||||
|
|
||||||
|
minedBlockHeights *lru.ARCCache
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Miner) Addresses() ([]address.Address, error) {
|
func (m *Miner) Addresses() ([]address.Address, error) {
|
||||||
@ -200,6 +210,17 @@ eventLoop:
|
|||||||
mWon[b.Header.Miner] = struct{}{}
|
mWon[b.Header.Miner] = struct{}{}
|
||||||
}
|
}
|
||||||
for _, b := range blks {
|
for _, b := range blks {
|
||||||
|
// TODO: this code was written to handle creating blocks for multiple miners.
|
||||||
|
// However, we don't use that, and we probably never will. So even though this code will
|
||||||
|
// never see different miners, i'm going to handle the caching as if it was going to.
|
||||||
|
// We can clean it up later when we remove all the multiple miner logic.
|
||||||
|
blkKey := fmt.Sprintf("%s-%d", b.Header.Miner, b.Header.Height)
|
||||||
|
if _, ok := m.minedBlockHeights.Get(blkKey); ok {
|
||||||
|
log.Warnw("Created a block at the same height as another block we've created", "height", b.Header.Height, "miner", b.Header.Miner, "parents", b.Header.Parents)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
m.minedBlockHeights.Add(blkKey, true)
|
||||||
if err := m.api.SyncSubmitBlock(ctx, b); err != nil {
|
if err := m.api.SyncSubmitBlock(ctx, b); err != nil {
|
||||||
log.Errorf("failed to submit newly mined block: %s", err)
|
log.Errorf("failed to submit newly mined block: %s", err)
|
||||||
}
|
}
|
||||||
@ -356,13 +377,13 @@ func (m *Miner) computeTicket(ctx context.Context, addr address.Address, base *M
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *types.Ticket, proof *types.EPostProof, pending []*types.SignedMessage) (*types.BlockMsg, error) {
|
func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *types.Ticket, proof *types.EPostProof, pending []*types.SignedMessage) (*types.BlockMsg, error) {
|
||||||
msgs, err := selectMessages(context.TODO(), m.api.StateGetActor, base, pending)
|
msgs, err := SelectMessages(context.TODO(), m.api.StateGetActor, base.ts, pending)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("message filtering failed: %w", err)
|
return nil, xerrors.Errorf("message filtering failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(msgs) > build.BlockMessageLimit {
|
if len(msgs) > build.BlockMessageLimit {
|
||||||
log.Error("selectMessages returned too many messages: ", len(msgs))
|
log.Error("SelectMessages returned too many messages: ", len(msgs))
|
||||||
msgs = msgs[:build.BlockMessageLimit]
|
msgs = msgs[:build.BlockMessageLimit]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,7 +395,7 @@ func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *type
|
|||||||
return m.api.MinerCreateBlock(context.TODO(), addr, base.ts, ticket, proof, msgs, nheight, uint64(uts))
|
return m.api.MinerCreateBlock(context.TODO(), addr, base.ts, ticket, proof, msgs, nheight, uint64(uts))
|
||||||
}
|
}
|
||||||
|
|
||||||
type actorLookup func(context.Context, address.Address, *types.TipSet) (*types.Actor, error)
|
type ActorLookup func(context.Context, address.Address, *types.TipSet) (*types.Actor, error)
|
||||||
|
|
||||||
func countFrom(msgs []*types.SignedMessage, from address.Address) (out int) {
|
func countFrom(msgs []*types.SignedMessage, from address.Address) (out int) {
|
||||||
for _, msg := range msgs {
|
for _, msg := range msgs {
|
||||||
@ -385,7 +406,7 @@ func countFrom(msgs []*types.SignedMessage, from address.Address) (out int) {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func selectMessages(ctx context.Context, al actorLookup, base *MiningBase, msgs []*types.SignedMessage) ([]*types.SignedMessage, error) {
|
func SelectMessages(ctx context.Context, al ActorLookup, ts *types.TipSet, msgs []*types.SignedMessage) ([]*types.SignedMessage, error) {
|
||||||
out := make([]*types.SignedMessage, 0, build.BlockMessageLimit)
|
out := make([]*types.SignedMessage, 0, build.BlockMessageLimit)
|
||||||
inclNonces := make(map[address.Address]uint64)
|
inclNonces := make(map[address.Address]uint64)
|
||||||
inclBalances := make(map[address.Address]types.BigInt)
|
inclBalances := make(map[address.Address]types.BigInt)
|
||||||
@ -401,7 +422,7 @@ func selectMessages(ctx context.Context, al actorLookup, base *MiningBase, msgs
|
|||||||
from := msg.Message.From
|
from := msg.Message.From
|
||||||
|
|
||||||
if _, ok := inclNonces[from]; !ok {
|
if _, ok := inclNonces[from]; !ok {
|
||||||
act, err := al(ctx, from, base.ts)
|
act, err := al(ctx, from, ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("failed to check message sender balance, skipping message: %+v", err)
|
log.Warnf("failed to check message sender balance, skipping message: %+v", err)
|
||||||
continue
|
continue
|
||||||
|
@ -80,7 +80,7 @@ func TestMessageFiltering(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
outmsgs, err := selectMessages(ctx, af, &MiningBase{}, wrapMsgs(msgs))
|
outmsgs, err := SelectMessages(ctx, af, nil, wrapMsgs(msgs))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,21 @@ import (
|
|||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/chain/gen"
|
"github.com/filecoin-project/lotus/chain/gen"
|
||||||
|
lru "github.com/hashicorp/golang-lru"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewTestMiner(nextCh <-chan struct{}, addr address.Address) func(api.FullNode, gen.ElectionPoStProver) *Miner {
|
func NewTestMiner(nextCh <-chan struct{}, addr address.Address) func(api.FullNode, gen.ElectionPoStProver) *Miner {
|
||||||
return func(api api.FullNode, epp gen.ElectionPoStProver) *Miner {
|
return func(api api.FullNode, epp gen.ElectionPoStProver) *Miner {
|
||||||
|
arc, err := lru.NewARC(10000)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
m := &Miner{
|
m := &Miner{
|
||||||
api: api,
|
api: api,
|
||||||
waitFunc: chanWaiter(nextCh),
|
waitFunc: chanWaiter(nextCh),
|
||||||
epp: epp,
|
epp: epp,
|
||||||
|
minedBlockHeights: arc,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := m.Register(addr); err != nil {
|
if err := m.Register(addr); err != nil {
|
||||||
|
@ -83,6 +83,10 @@ func (a *ChainAPI) ChainGetBlockMessages(ctx context.Context, msg cid.Cid) (*api
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *ChainAPI) ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*store.HeadChange, error) {
|
||||||
|
return a.Chain.GetPath(ctx, from, to)
|
||||||
|
}
|
||||||
|
|
||||||
func (a *ChainAPI) ChainGetParentMessages(ctx context.Context, bcid cid.Cid) ([]api.Message, error) {
|
func (a *ChainAPI) ChainGetParentMessages(ctx context.Context, bcid cid.Cid) ([]api.Message, error) {
|
||||||
b, err := a.Chain.GetBlock(bcid)
|
b, err := a.Chain.GetBlock(bcid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -400,3 +400,7 @@ func (a *StateAPI) StateListMessages(ctx context.Context, match *types.Message,
|
|||||||
|
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *StateAPI) StateCompute(ctx context.Context, height uint64, msgs []*types.Message, ts *types.TipSet) (cid.Cid, error) {
|
||||||
|
return stmgr.ComputeState(ctx, a.StateManager, height, msgs, ts)
|
||||||
|
}
|
||||||
|
@ -212,9 +212,7 @@ func (m *Sealing) handleFaulty(ctx statemachine.Context, sector SectorInfo) erro
|
|||||||
bf := types.NewBitField()
|
bf := types.NewBitField()
|
||||||
bf.Set(sector.SectorID)
|
bf.Set(sector.SectorID)
|
||||||
|
|
||||||
fp := &actors.DeclareFaultsParams{bf}
|
enc, aerr := actors.SerializeParams(&actors.DeclareFaultsParams{bf})
|
||||||
_ = fp
|
|
||||||
enc, aerr := actors.SerializeParams(nil)
|
|
||||||
if aerr != nil {
|
if aerr != nil {
|
||||||
return xerrors.Errorf("failed to serialize declare fault params: %w", aerr)
|
return xerrors.Errorf("failed to serialize declare fault params: %w", aerr)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user