Merge pull request #1522 from filecoin-project/feat/windowed-post

Windowed PoSt
This commit is contained in:
Łukasz Magiera 2020-04-22 00:15:56 +02:00 committed by GitHub
commit 4d5e3201c3
83 changed files with 2009 additions and 1479 deletions

View File

@ -51,6 +51,9 @@ deps: $(BUILD_DEPS)
debug: GOFLAGS+=-tags=debug
debug: lotus lotus-storage-miner lotus-seal-worker lotus-seed
2k: GOFLAGS+=-tags=2k
2k: lotus lotus-storage-miner lotus-seal-worker lotus-seed
lotus: $(BUILD_DEPS)
rm -f lotus
go build $(GOFLAGS) -o lotus ./cmd/lotus

View File

@ -15,7 +15,7 @@ import (
"github.com/filecoin-project/specs-actors/actors/builtin/market"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/lotus/chain/store"
@ -71,7 +71,7 @@ type FullNode interface {
// miner
MinerGetBaseInfo(context.Context, address.Address, types.TipSetKey) (*MiningBaseInfo, error)
MinerGetBaseInfo(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*MiningBaseInfo, error)
MinerCreateBlock(context.Context, *BlockTemplate) (*types.BlockMsg, error)
// // UX ?
@ -120,13 +120,11 @@ type FullNode interface {
StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error)
StateNetworkName(context.Context) (dtypes.NetworkName, error)
StateMinerSectors(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error)
StateMinerSectors(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*ChainSectorInfo, error)
StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error)
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
StateMinerWorker(context.Context, address.Address, types.TipSetKey) (address.Address, error)
StateMinerPeerID(ctx context.Context, m address.Address, tsk types.TipSetKey) (peer.ID, error)
StateMinerPostState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*miner.PoStState, error)
StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error)
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error)
StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) (*miner.Deadlines, error)
StateMinerFaults(context.Context, address.Address, types.TipSetKey) ([]abi.SectorNumber, error)
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error)
StatePledgeCollateral(context.Context, types.TipSetKey) (types.BigInt, error)
@ -139,10 +137,10 @@ type FullNode interface {
StateMarketDeals(context.Context, types.TipSetKey) (map[string]MarketDeal, error)
StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*MarketDeal, error)
StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error)
StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error)
StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error)
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
StateMinerSectorCount(context.Context, address.Address, types.TipSetKey) (MinerSectors, error)
StateListRewards(context.Context, address.Address, types.TipSetKey) ([]reward.Reward, error)
StateCompute(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*ComputeStateOutput, error)
MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
@ -170,8 +168,8 @@ type FileRef struct {
}
type MinerSectors struct {
Pset uint64
Sset uint64
Pset uint64
}
type Import struct {
@ -257,8 +255,8 @@ type VoucherSpec struct {
}
type MinerPower struct {
MinerPower types.BigInt
TotalPower types.BigInt
MinerPower power.Claim
TotalPower power.Claim
}
type QueryOffer struct {
@ -325,11 +323,11 @@ type MethodCall struct {
}
type StartDealParams struct {
Data *storagemarket.DataRef
Wallet address.Address
Miner address.Address
EpochPrice types.BigInt
BlocksDuration uint64
Data *storagemarket.DataRef
Wallet address.Address
Miner address.Address
EpochPrice types.BigInt
MinBlocksDuration uint64
}
type IpldObject struct {
@ -384,21 +382,22 @@ type ComputeStateOutput struct {
type MiningBaseInfo struct {
MinerPower types.BigInt
NetworkPower types.BigInt
Sectors []*ChainSectorInfo
Worker address.Address
Sectors []abi.SectorInfo
WorkerKey address.Address
SectorSize abi.SectorSize
PrevBeaconEntry types.BeaconEntry
}
type BlockTemplate struct {
Miner address.Address
Parents types.TipSetKey
Ticket *types.Ticket
Eproof *types.ElectionProof
BeaconValues []types.BeaconEntry
Messages []*types.SignedMessage
Epoch abi.ChainEpoch
Timestamp uint64
Miner address.Address
Parents types.TipSetKey
Ticket *types.Ticket
Eproof *types.ElectionProof
BeaconValues []types.BeaconEntry
Messages []*types.SignedMessage
Epoch abi.ChainEpoch
Timestamp uint64
WinningPoStProof []abi.PoStProof
}
type CommPRet struct {

View File

@ -16,7 +16,6 @@ import (
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-storage/storage"
@ -88,8 +87,8 @@ type FullNodeStruct struct {
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
MpoolSub func(context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"`
MinerGetBaseInfo func(context.Context, address.Address, types.TipSetKey) (*api.MiningBaseInfo, error) `perm:"read"`
MinerCreateBlock func(context.Context, *api.BlockTemplate) (*types.BlockMsg, error) `perm:"write"`
MinerGetBaseInfo func(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*api.MiningBaseInfo, error) `perm:"read"`
MinerCreateBlock func(context.Context, *api.BlockTemplate) (*types.BlockMsg, error) `perm:"write"`
WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"`
WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"`
@ -116,13 +115,11 @@ type FullNodeStruct struct {
ClientGenCar func(ctx context.Context, ref api.FileRef, outpath string) error `perm:"write"`
StateNetworkName func(context.Context) (dtypes.NetworkName, error) `perm:"read"`
StateMinerSectors func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
StateMinerSectors func(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
StateMinerProvingSet func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
StateMinerPower func(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) `perm:"read"`
StateMinerWorker func(context.Context, address.Address, types.TipSetKey) (address.Address, error) `perm:"read"`
StateMinerPeerID func(ctx context.Context, m address.Address, tsk types.TipSetKey) (peer.ID, error) `perm:"read"`
StateMinerPostState func(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*miner.PoStState, error) `perm:"read"`
StateMinerSectorSize func(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error) `perm:"read"`
StateMinerInfo func(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) `perm:"read"`
StateMinerDeadlines func(context.Context, address.Address, types.TipSetKey) (*miner.Deadlines, error) `perm:"read"`
StateMinerFaults func(context.Context, address.Address, types.TipSetKey) ([]abi.SectorNumber, error) `perm:"read"`
StateSectorPreCommitInfo func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) `perm:"read"`
StateCall func(context.Context, *types.Message, types.TipSetKey) (*api.InvocResult, error) `perm:"read"`
@ -139,11 +136,11 @@ type FullNodeStruct struct {
StateMarketDeals func(context.Context, types.TipSetKey) (map[string]api.MarketDeal, error) `perm:"read"`
StateMarketStorageDeal func(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error) `perm:"read"`
StateLookupID func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) `perm:"read"`
StateAccountKey func(context.Context, address.Address, types.TipSetKey) (address.Address, error) `perm:"read"`
StateChangedActors func(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) `perm:"read"`
StateGetReceipt func(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) `perm:"read"`
StateMinerSectorCount func(context.Context, address.Address, types.TipSetKey) (api.MinerSectors, error) `perm:"read"`
StateListMessages func(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"`
StateListRewards func(context.Context, address.Address, types.TipSetKey) ([]reward.Reward, error) `perm:"read"`
StateCompute func(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*api.ComputeStateOutput, error) `perm:"read"`
MsigGetAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
@ -335,8 +332,8 @@ func (c *FullNodeStruct) MpoolSub(ctx context.Context) (<-chan api.MpoolUpdate,
return c.Internal.MpoolSub(ctx)
}
func (c *FullNodeStruct) MinerGetBaseInfo(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (*api.MiningBaseInfo, error) {
return c.Internal.MinerGetBaseInfo(ctx, maddr, tsk)
func (c *FullNodeStruct) MinerGetBaseInfo(ctx context.Context, maddr address.Address, epoch abi.ChainEpoch, tsk types.TipSetKey) (*api.MiningBaseInfo, error) {
return c.Internal.MinerGetBaseInfo(ctx, maddr, epoch, tsk)
}
func (c *FullNodeStruct) MinerCreateBlock(ctx context.Context, bt *api.BlockTemplate) (*types.BlockMsg, error) {
@ -491,8 +488,8 @@ func (c *FullNodeStruct) StateNetworkName(ctx context.Context) (dtypes.NetworkNa
return c.Internal.StateNetworkName(ctx)
}
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
return c.Internal.StateMinerSectors(ctx, addr, tsk)
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, filter *abi.BitField, filterOut bool, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
return c.Internal.StateMinerSectors(ctx, addr, filter, filterOut, tsk)
}
func (c *FullNodeStruct) StateMinerProvingSet(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
@ -503,20 +500,12 @@ func (c *FullNodeStruct) StateMinerPower(ctx context.Context, a address.Address,
return c.Internal.StateMinerPower(ctx, a, tsk)
}
func (c *FullNodeStruct) StateMinerWorker(ctx context.Context, m address.Address, tsk types.TipSetKey) (address.Address, error) {
return c.Internal.StateMinerWorker(ctx, m, tsk)
func (c *FullNodeStruct) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) {
return c.Internal.StateMinerInfo(ctx, actor, tsk)
}
func (c *FullNodeStruct) StateMinerPeerID(ctx context.Context, m address.Address, tsk types.TipSetKey) (peer.ID, error) {
return c.Internal.StateMinerPeerID(ctx, m, tsk)
}
func (c *FullNodeStruct) StateMinerPostState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*miner.PoStState, error) {
return c.Internal.StateMinerPostState(ctx, actor, tsk)
}
func (c *FullNodeStruct) StateMinerSectorSize(ctx context.Context, actor address.Address, tsk types.TipSetKey) (abi.SectorSize, error) {
return c.Internal.StateMinerSectorSize(ctx, actor, tsk)
func (c *FullNodeStruct) StateMinerDeadlines(ctx context.Context, m address.Address, tsk types.TipSetKey) (*miner.Deadlines, error) {
return c.Internal.StateMinerDeadlines(ctx, m, tsk)
}
func (c *FullNodeStruct) StateMinerFaults(ctx context.Context, actor address.Address, tsk types.TipSetKey) ([]abi.SectorNumber, error) {
@ -583,6 +572,10 @@ func (c *FullNodeStruct) StateLookupID(ctx context.Context, addr address.Address
return c.Internal.StateLookupID(ctx, addr, tsk)
}
func (c *FullNodeStruct) StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
return c.Internal.StateAccountKey(ctx, addr, tsk)
}
func (c *FullNodeStruct) StateChangedActors(ctx context.Context, olnstate cid.Cid, newstate cid.Cid) (map[string]types.Actor, error) {
return c.Internal.StateChangedActors(ctx, olnstate, newstate)
}
@ -595,10 +588,6 @@ func (c *FullNodeStruct) StateListMessages(ctx context.Context, match *types.Mes
return c.Internal.StateListMessages(ctx, match, tsk, toht)
}
func (c *FullNodeStruct) StateListRewards(ctx context.Context, miner address.Address, tsk types.TipSetKey) ([]reward.Reward, error) {
return c.Internal.StateListRewards(ctx, miner, tsk)
}
func (c *FullNodeStruct) StateCompute(ctx context.Context, height abi.ChainEpoch, msgs []*types.Message, tsk types.TipSetKey) (*api.ComputeStateOutput, error) {
return c.Internal.StateCompute(ctx, height, msgs, tsk)
}

View File

@ -168,9 +168,11 @@ func (t *PaymentInfo) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.Vouchers = make([]*paych.SignedVoucher, extra)
}
for i := 0; i < int(extra); i++ {
var v paych.SignedVoucher
@ -412,9 +414,11 @@ func (t *SealedRefs) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.Refs = make([]SealedRef, extra)
}
for i := 0; i < int(extra); i++ {
var v SealedRef

View File

@ -83,11 +83,11 @@ func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport
t.Fatal(err)
}
deal, err := client.ClientStartDeal(ctx, &api.StartDealParams{
Data: &storagemarket.DataRef{Root: fcid},
Wallet: addr,
Miner: maddr,
EpochPrice: types.NewInt(1000000),
BlocksDuration: 100,
Data: &storagemarket.DataRef{Root: fcid},
Wallet: addr,
Miner: maddr,
EpochPrice: types.NewInt(1000000),
MinBlocksDuration: 100,
})
if err != nil {
t.Fatalf("%+v", err)
@ -107,7 +107,7 @@ loop:
case storagemarket.StorageDealFailing:
t.Fatal("deal failed")
case storagemarket.StorageDealError:
t.Fatal("deal errored")
t.Fatal("deal errored", di.Message)
case storagemarket.StorageDealActive:
fmt.Println("COMPLETE", di)
break loop

Binary file not shown.

29
build/params_2k.go Normal file
View File

@ -0,0 +1,29 @@
// +build debug 2k
package build
import (
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
)
func init() {
power.ConsensusMinerMinPower = big.NewInt(2048)
}
var SectorSizes = []abi.SectorSize{2048}
// Seconds
const BlockDelay = 2
const PropagationDelay = 3
// SlashablePowerDelay is the number of epochs after ElectionPeriodStart, after
// which the miner is slashed
//
// Epochs
const SlashablePowerDelay = 20
// Epochs
const InteractivePoRepConfidence = 6

View File

@ -2,30 +2,8 @@
package build
import (
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
)
func init() {
InsecurePoStValidation = true
power.ConsensusMinerMinPower = big.NewInt(2048)
}
var SectorSizes = []abi.SectorSize{2048}
// Seconds
const BlockDelay = 6
const PropagationDelay = 3
// SlashablePowerDelay is the number of epochs after ElectionPeriodStart, after
// which the miner is slashed
//
// Epochs
const SlashablePowerDelay = 20
// Epochs
const InteractivePoRepConfidence = 6
// NOTE: Also includes settings from params_2k

View File

@ -71,6 +71,8 @@ const MaxSealLookback = SealRandomnessLookbackLimit + 2000 // TODO: Get from spe
// Epochs
const TicketRandomnessLookback = 1
const WinningPoStSectorSetLookback = 10
// /////
// Devnet settings

View File

@ -1,10 +1,10 @@
// +build !debug
// +build !2k
package build
import (
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
)
var SectorSizes = []abi.SectorSize{
@ -16,12 +16,3 @@ var SectorSizes = []abi.SectorSize{
const BlockDelay = 25
const PropagationDelay = 6
// SlashablePowerDelay is the number of epochs after ElectionPeriodStart, after
// which the miner is slashed
//
// Epochs
const SlashablePowerDelay = miner.ProvingPeriod * 3 // TODO: remove
// Epochs
const InteractivePoRepConfidence = 6

View File

@ -1,82 +1,122 @@
{
"v24-proof-of-spacetime-election-PoseidonHasher-0b0b9781bcb153efbb3cab4be3a792c4f555d4ab6f8dd62b27e1dcad08a34f22.params": {
"cid": "QmUonpeUaLD6G4byFdZAMzwXorD4Qs1XDjmdXFbWYCgvjW",
"digest": "19e50903e53c826ff66f360283f324c1",
"sector_size": 34359738368
},
"v24-proof-of-spacetime-election-PoseidonHasher-0b0b9781bcb153efbb3cab4be3a792c4f555d4ab6f8dd62b27e1dcad08a34f22.vk": {
"cid": "QmVXv4Q1T3FbiY5AUgWER11Lsrby9aUVJy2mgWDWrndFbq",
"digest": "223dd87c6161c45daf448ca9eda28298",
"sector_size": 34359738368
},
"v24-proof-of-spacetime-election-PoseidonHasher-0b499a953f1a9dcab420b3ba1e6b1f3952dc7f17cf67ed10406ae9a43e2b8ec5.params": {
"cid": "Qmea7VsrYnkrpdMnutkGKppX5finoDwCA2fP5Zg5bDuBQw",
"digest": "3de5b8738a2cd933c214fa2023e30909",
"sector_size": 8388608
},
"v24-proof-of-spacetime-election-PoseidonHasher-0b499a953f1a9dcab420b3ba1e6b1f3952dc7f17cf67ed10406ae9a43e2b8ec5.vk": {
"cid": "QmavFXmf3jeacHKB6HoJH3gUqzmKnsDn5F5HSYfwPbDHRu",
"digest": "485b7eab4f70031fdda4eaeccfe4f26e",
"sector_size": 8388608
},
"v24-proof-of-spacetime-election-PoseidonHasher-27a7fc680a47e4821f40cf1676fb80b9888820ef6867a71a175b4c9ae068ad3f.params": {
"cid": "QmQrUjB9NSMuThe1JHoHfC7u1xdoLS6WLu15waWcnZ3tQT",
"digest": "7e6adc7cbf73db8c95a54e3c23bea1ae",
"sector_size": 536870912
},
"v24-proof-of-spacetime-election-PoseidonHasher-27a7fc680a47e4821f40cf1676fb80b9888820ef6867a71a175b4c9ae068ad3f.vk": {
"cid": "QmVPPk4fBcEero2GHsYuBoh97yhugTBWUp9yWSPPWjRWQ7",
"digest": "952b352d694d650e912b3b92ad63f7c9",
"sector_size": 536870912
},
"v24-proof-of-spacetime-election-PoseidonHasher-5916054ae98e28fc2f0470d1fb58eb875a6865be86f0b8c4e302d55f13217fef.params": {
"cid": "QmSXMF85mdGLQfAY98zVL4dUBpGPFFUPDmFzdc1NZrVFdh",
"digest": "a93de0f8cfb04af5d21f66ef48ee59a8",
"v25-proof-of-spacetime-fallback-MerkleTree<PoseidonHasher, 8, 0, 0>-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.params": {
"cid": "QmNUKXCEcjMRh8ayFG2X9RYUuc2SK5XRVsSVTqJmNWAgSp",
"digest": "fe10d43b607dd6687f30428476076ebb",
"sector_size": 2048
},
"v24-proof-of-spacetime-election-PoseidonHasher-5916054ae98e28fc2f0470d1fb58eb875a6865be86f0b8c4e302d55f13217fef.vk": {
"cid": "QmaTsAmbdnQtJoSpkWsXmvHPpMJinzFYTe6t5LLm7w5RtQ",
"digest": "e4d0575f119e3e7b42bc3e5b6bb35a0b",
"v25-proof-of-spacetime-fallback-MerkleTree<PoseidonHasher, 8, 0, 0>-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.vk": {
"cid": "QmRyV1DvF57cSnnwUoocKbPiULoLdfnfWpVWi8BSsMN6KR",
"digest": "8aaca32ca9a1c6a431b99e695b443e69",
"sector_size": 2048
},
"v24-stacked-proof-of-replication-PoseidonHasher-Sha256Hasher-49442c8ce7545579cbd689d578301d0cc1e46e94e2499a0ec36de7ff4f4694a2.params": {
"cid": "QmYCFrU4G2LakPngFXayX7afyondQbB9hfnVRz1ffWD9MS",
"digest": "d64e5d1bbb9120bea4c0cd8cdcdfb834",
"sector_size": 8388608
},
"v24-stacked-proof-of-replication-PoseidonHasher-Sha256Hasher-49442c8ce7545579cbd689d578301d0cc1e46e94e2499a0ec36de7ff4f4694a2.vk": {
"cid": "QmfXAPtHKU2MJVJDwLTUCM4W2tYQ8biGq9cZaAnjtaZidZ",
"digest": "572536e8684454a5cd80361e5c952b38",
"sector_size": 8388608
},
"v24-stacked-proof-of-replication-PoseidonHasher-Sha256Hasher-d84aa4581c74190f845596893ebe5b71da32ecf16e1d151b9fff74ee8f94d77c.params": {
"cid": "QmdXtQsLbBFmVxrd6kWKr2FYbQfhEdR6PinwrGBXhHmLdT",
"digest": "77cfafee088bd59411d766621df6de42",
"v25-proof-of-spacetime-fallback-MerkleTree<PoseidonHasher, 8, 0, 0>-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.params": {
"cid": "QmTvwEyFVcjivKUX9AqZrC4mfjLSN2JJTucLJfNaWqCPmD",
"digest": "1cc1bf83c9e3d9b2d994ad2ec946a79f",
"sector_size": 536870912
},
"v24-stacked-proof-of-replication-PoseidonHasher-Sha256Hasher-d84aa4581c74190f845596893ebe5b71da32ecf16e1d151b9fff74ee8f94d77c.vk": {
"cid": "QmdE8oZJofaenThLi2TWXJPk9cExZgTA36TjrHeAC65BGA",
"digest": "30586a2396ef6b60b122ac5a2ba87681",
"v25-proof-of-spacetime-fallback-MerkleTree<PoseidonHasher, 8, 0, 0>-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.vk": {
"cid": "QmVfgowqdh3ruAHqQ8LA6L4VdSYwam5e8VmSEtZXBoAudC",
"digest": "377659f83c6714703b17828f603038fc",
"sector_size": 536870912
},
"v24-stacked-proof-of-replication-PoseidonHasher-Sha256Hasher-fc32be6028c2398175466f36fa36810842ae8948fae15c84454af5b61ca99e15.params": {
"cid": "QmNqcqGxf7pJjipHNwcH44D5KgiTUNo3mK5HiSxBwYcjkx",
"digest": "25ea39db2a003c817113f6f2ea936b3d",
"sector_size": 34359738368
},
"v24-stacked-proof-of-replication-PoseidonHasher-Sha256Hasher-fc32be6028c2398175466f36fa36810842ae8948fae15c84454af5b61ca99e15.vk": {
"cid": "QmWiaqy8hWshv2FsLDoZAtpJKZng5QN3x2X5C7xsPvSbFb",
"digest": "ab1239c802c480cf12f63d13fb2f620a",
"sector_size": 34359738368
},
"v24-stacked-proof-of-replication-PoseidonHasher-Sha256Hasher-fe437922fe766f61b112750506d6be0e4ad5daa85ff9ce96549d99253ba61cbe.params": {
"cid": "QmbPk3fKKLjkm6pD1CzwGyTnMwNSSZVxVSMWEceqSv6LDW",
"digest": "76bd3702312cfe0d69bb5e0891c52615",
"v25-proof-of-spacetime-fallback-MerkleTree<PoseidonHasher, 8, 0, 0>-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.params": {
"cid": "QmQ2HrKCWbtWQNNQiBj3BFE8QrqMyed8P5Vw5vyyzuSMsF",
"digest": "2e15ec3fbff51abf66d241252fb8babd",
"sector_size": 2048
},
"v24-stacked-proof-of-replication-PoseidonHasher-Sha256Hasher-fe437922fe766f61b112750506d6be0e4ad5daa85ff9ce96549d99253ba61cbe.vk": {
"cid": "QmPZ9bGSVs5GHQRRAtC1qv9eQ7GPoH8FWukjxAXtXXcTxg",
"digest": "4edb21b7b6d5787b646f3e336e06303e",
"v25-proof-of-spacetime-fallback-MerkleTree<PoseidonHasher, 8, 0, 0>-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.vk": {
"cid": "QmVZRduda8L1AYsT3u3uk2kqiMnwm5Sx9D8pZbTVHAZG5i",
"digest": "11c74ae0068ca7e4a5fd8cb1eaf5b511",
"sector_size": 2048
},
"v25-proof-of-spacetime-fallback-MerkleTree<PoseidonHasher, 8, 0, 0>-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.params": {
"cid": "QmPQkry7TXuE8nxHFAySp3X8qRXMYj2ArffoFxF2C1hYwf",
"digest": "526edf009176616771af4ba915eb5073",
"sector_size": 8388608
},
"v25-proof-of-spacetime-fallback-MerkleTree<PoseidonHasher, 8, 0, 0>-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.vk": {
"cid": "QmT5bjrKBUpWEfaveWoPCu96EuHN2HuzbRzS9tSxttPCzw",
"digest": "c29e6b2927b8a28593f7c0c035b32cf5",
"sector_size": 8388608
},
"v25-proof-of-spacetime-fallback-MerkleTree<PoseidonHasher, 8, 0, 0>-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.params": {
"cid": "QmXn1v64YTKLAH6yemhotr2dp1ZtjfspT328itKrMfnBW6",
"digest": "66459a78bd5e0225a19f140068620b7f",
"sector_size": 8388608
},
"v25-proof-of-spacetime-fallback-MerkleTree<PoseidonHasher, 8, 0, 0>-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.vk": {
"cid": "QmTax8iBqjyP3EMUSnkSoxpjxh7dWrpE5RbfN2FA4oUgc4",
"digest": "e482988346217c846cecd80dfffef35f",
"sector_size": 8388608
},
"v25-proof-of-spacetime-fallback-MerkleTree<PoseidonHasher, 8, 0, 0>-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.params": {
"cid": "QmdVN2xTAJtKLrUdXfP7JjGpMGnZRmbDT8FHdkzxruRoLQ",
"digest": "4b27a62d2179523a2176ec7a1f2837be",
"sector_size": 536870912
},
"v25-proof-of-spacetime-fallback-MerkleTree<PoseidonHasher, 8, 0, 0>-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.vk": {
"cid": "QmakhHMzRBB85LLniDeRif71prLckqj7RHCc3NSgZsevQF",
"digest": "21271b25537a42e79247bd403e3ba37e",
"sector_size": 536870912
},
"v25-proof-of-spacetime-fallback-MerkleTree<PoseidonHasher, 8, 8, 0>-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.params": {
"cid": "QmZwPa4C5iUKPwGL7pkzZVNpn1Z9QkELneLAX4JFdRc7m5",
"digest": "263b3ee83cfff7c287900346742e363a",
"sector_size": 34359738368
},
"v25-proof-of-spacetime-fallback-MerkleTree<PoseidonHasher, 8, 8, 0>-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.vk": {
"cid": "QmUVAe53gJ4eC7wmDG2K5WWEtTvfQJaAPBstEtfznJrPhR",
"digest": "e6bc2cb5808b6a5cde7b51bfe0543313",
"sector_size": 34359738368
},
"v25-proof-of-spacetime-fallback-MerkleTree<PoseidonHasher, 8, 8, 0>-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.params": {
"cid": "QmXiiXheXvZV8rVkdDCFPdUYJVCNa67THGa7VgQRkqNojy",
"digest": "f031cdaf063c00baa637eae5e4b338c8",
"sector_size": 34359738368
},
"v25-proof-of-spacetime-fallback-MerkleTree<PoseidonHasher, 8, 8, 0>-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.vk": {
"cid": "QmXSzhELrQMBhJgYqpT8qTL9Piwti3eziCYt49EJ77368r",
"digest": "3f7f6e287a32083f131d4948e04e6e5b",
"sector_size": 34359738368
},
"v25-stacked-proof-of-replication-MerkleTree<PoseidonHasher, 8, 0, 0>-Sha256Hasher-840969a6a9533823ecdc37310ef8c99d35991a2145300e10be0b883f1226a0f6.params": {
"cid": "QmbaFhfNtz6TuQdiC5oyL5rWSyUNQzcD68A6PT9mCTbvd7",
"digest": "c0cbe5bd951eb944557784a5a423fd18",
"sector_size": 2048
},
"v25-stacked-proof-of-replication-MerkleTree<PoseidonHasher, 8, 0, 0>-Sha256Hasher-840969a6a9533823ecdc37310ef8c99d35991a2145300e10be0b883f1226a0f6.vk": {
"cid": "QmYfeAWeg7mKQJvoUCVatqa36WFbWYH2B9JMrJTorhJdUu",
"digest": "3ed77a85380eeacfea658fc4b1ad8b95",
"sector_size": 2048
},
"v25-stacked-proof-of-replication-MerkleTree<PoseidonHasher, 8, 0, 0>-Sha256Hasher-e3c3fd959a83bf60522a401dc3bf0e2d48f0e2172bcdf4c0cb3c39fa4deacd87.params": {
"cid": "QmYuGgnRHx9x4DAVtkGYGir8SDvRE17pUMH17riEpWguuN",
"digest": "b59249298e9d1bb9d25891b828e03c94",
"sector_size": 536870912
},
"v25-stacked-proof-of-replication-MerkleTree<PoseidonHasher, 8, 0, 0>-Sha256Hasher-e3c3fd959a83bf60522a401dc3bf0e2d48f0e2172bcdf4c0cb3c39fa4deacd87.vk": {
"cid": "QmUE4Qhd3vUPMQwh1TPJkVxZVisxoLKj93ZDU3zfW7koc4",
"digest": "b4e3e2ea3eba88d2eba3d59472ef4094",
"sector_size": 536870912
},
"v25-stacked-proof-of-replication-MerkleTree<PoseidonHasher, 8, 0, 0>-Sha256Hasher-e4a49558d04647264048879511e843136e4488499e23bc442a341083a19ee79c.params": {
"cid": "QmePVNPMxzDuPF3mQaZ9Ld1hTGhResvGZgZ61NXy5cDQPK",
"digest": "0deb36662833379267609fc4e5f4176b",
"sector_size": 8388608
},
"v25-stacked-proof-of-replication-MerkleTree<PoseidonHasher, 8, 0, 0>-Sha256Hasher-e4a49558d04647264048879511e843136e4488499e23bc442a341083a19ee79c.vk": {
"cid": "QmWLpw8pLwuCGiUQGQiwuXTjKcvPwsaS573gQ6YPc67jVm",
"digest": "1618f598e3a5c26acee17540aa5cd536",
"sector_size": 8388608
},
"v25-stacked-proof-of-replication-MerkleTree<PoseidonHasher, 8, 8, 0>-Sha256Hasher-8a0719d8b9de3605f89b084c73210dfe2a557407c6343f8d32640094f2c9d074.params": {
"cid": "QmdtfjaJpqE8pRt1cmceh8c2Qj8GNwrzmmSmckZr6VDAWR",
"digest": "18796da53b41f23e341d19ce7954f647",
"sector_size": 34359738368
},
"v25-stacked-proof-of-replication-MerkleTree<PoseidonHasher, 8, 8, 0>-Sha256Hasher-8a0719d8b9de3605f89b084c73210dfe2a557407c6343f8d32640094f2c9d074.vk": {
"cid": "QmYF8Y17nHYAvbRA7NCQMs31VsBiMcAbwrViZwyT4Gvb8C",
"digest": "39d80879d4d7353e2ed5771670d97dfc",
"sector_size": 34359738368
}
}

View File

@ -31,7 +31,7 @@ func (ve Version) EqMajorMinor(v2 Version) bool {
}
// APIVersion is a semver version of the rpc api exposed
var APIVersion Version = newVer(0, 2, 0)
var APIVersion Version = newVer(0, 3, 0)
const (
majorMask = 0xff0000

View File

@ -7,7 +7,7 @@ import (
"io"
"github.com/filecoin-project/lotus/chain/types"
"github.com/ipfs/go-cid"
cid "github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
xerrors "golang.org/x/xerrors"
)
@ -81,9 +81,11 @@ func (t *BlockSyncRequest) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.Start = make([]cid.Cid, extra)
}
for i := 0; i < int(extra); i++ {
c, err := cbg.ReadCid(br)
@ -196,9 +198,11 @@ func (t *BlockSyncResponse) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.Chain = make([]*BSTipSet, extra)
}
for i := 0; i < int(extra); i++ {
var v BSTipSet
@ -364,9 +368,11 @@ func (t *BSTipSet) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.Blocks = make([]*types.BlockHeader, extra)
}
for i := 0; i < int(extra); i++ {
var v types.BlockHeader
@ -391,9 +397,11 @@ func (t *BSTipSet) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.BlsMessages = make([]*types.Message, extra)
}
for i := 0; i < int(extra); i++ {
var v types.Message
@ -418,9 +426,11 @@ func (t *BSTipSet) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.BlsMsgIncludes = make([][]uint64, extra)
}
for i := 0; i < int(extra); i++ {
{
var maj byte
@ -439,9 +449,11 @@ func (t *BSTipSet) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.BlsMsgIncludes[i] = make([]uint64, extra)
}
for j := 0; j < int(extra); j++ {
maj, val, err := cbg.CborReadHeader(br)
@ -473,9 +485,11 @@ func (t *BSTipSet) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.SecpkMessages = make([]*types.SignedMessage, extra)
}
for i := 0; i < int(extra); i++ {
var v types.SignedMessage
@ -500,9 +514,11 @@ func (t *BSTipSet) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.SecpkMsgIncludes = make([][]uint64, extra)
}
for i := 0; i < int(extra); i++ {
{
var maj byte
@ -521,9 +537,11 @@ func (t *BSTipSet) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.SecpkMsgIncludes[i] = make([]uint64, extra)
}
for j := 0; j < int(extra); j++ {
maj, val, err := cbg.CborReadHeader(br)

View File

@ -12,7 +12,6 @@ import (
commcid "github.com/filecoin-project/go-fil-commcid"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-storage/storage"
block "github.com/ipfs/go-block-format"
"github.com/ipfs/go-blockservice"
"github.com/ipfs/go-car"
@ -65,7 +64,7 @@ type ChainGen struct {
w *wallet.Wallet
eppProvs map[address.Address]ElectionPoStProver
eppProvs map[address.Address]WinningPoStProver
Miners []address.Address
receivers []address.Address
banker address.Address
@ -205,9 +204,9 @@ func NewGenerator() (*ChainGen, error) {
return nil, xerrors.Errorf("set genesis failed: %w", err)
}
mgen := make(map[address.Address]ElectionPoStProver)
mgen := make(map[address.Address]WinningPoStProver)
for i := range tpl.Miners {
mgen[genesis2.MinerAddress(uint64(i))] = &eppProvider{}
mgen[genesis2.MinerAddress(uint64(i))] = &wppProvider{}
}
sm := stmgr.NewStateManager(cs)
@ -278,9 +277,9 @@ func CarWalkFunc(nd format.Node) (out []*format.Link, err error) {
}
func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m address.Address, round abi.ChainEpoch) ([]types.BeaconEntry, *types.ElectionProof, *types.Ticket, error) {
mc := &mca{w: cg.w, sm: cg.sm}
mc := &mca{w: cg.w, sm: cg.sm, pv: ffiwrapper.ProofVerifier}
mbi, err := mc.MinerGetBaseInfo(ctx, m, pts.Key())
mbi, err := mc.MinerGetBaseInfo(ctx, m, round, pts.Key())
if err != nil {
return nil, nil, nil, xerrors.Errorf("get miner base info: %w", err)
}
@ -325,8 +324,6 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add
return nil, nil, nil, xerrors.Errorf("compute VRF: %w", err)
}
// TODO winning post return?
return entries, eproof, &types.Ticket{VRFProof: vrfout}, nil
}
@ -361,9 +358,13 @@ func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Ad
}
if et != nil {
// TODO: winning post proof
_ = ticket
fblk, err := cg.makeBlock(base, m, ticket, et, bvals, round, msgs)
// TODO: maybe think about passing in more real parameters to this?
wpost, err := cg.eppProvs[m].ComputeProof(context.TODO(), nil, nil)
if err != nil {
return nil, err
}
fblk, err := cg.makeBlock(base, m, ticket, et, bvals, round, wpost, msgs)
if err != nil {
return nil, xerrors.Errorf("making a block for next tipset failed: %w", err)
}
@ -387,7 +388,7 @@ func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Ad
func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticket *types.Ticket,
eticket *types.ElectionProof, bvals []types.BeaconEntry, height abi.ChainEpoch,
msgs []*types.SignedMessage) (*types.FullBlock, error) {
wpost []abi.PoStProof, msgs []*types.SignedMessage) (*types.FullBlock, error) {
var ts uint64
if cg.Timestamper != nil {
@ -397,14 +398,15 @@ func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticke
}
fblk, err := MinerCreateBlock(context.TODO(), cg.sm, cg.w, &api.BlockTemplate{
Miner: m,
Parents: parents.Key(),
Ticket: vrfticket,
Eproof: eticket,
BeaconValues: bvals,
Messages: msgs,
Epoch: height,
Timestamp: ts,
Miner: m,
Parents: parents.Key(),
Ticket: vrfticket,
Eproof: eticket,
BeaconValues: bvals,
Messages: msgs,
Epoch: height,
Timestamp: ts,
WinningPoStProof: wpost,
})
if err != nil {
return nil, err
@ -474,7 +476,7 @@ func (cg *ChainGen) YieldRepo() (repo.Repo, error) {
type MiningCheckAPI interface {
ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
MinerGetBaseInfo(context.Context, address.Address, types.TipSetKey) (*api.MiningBaseInfo, error)
MinerGetBaseInfo(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*api.MiningBaseInfo, error)
WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error)
}
@ -482,6 +484,7 @@ type MiningCheckAPI interface {
type mca struct {
w *wallet.Wallet
sm *stmgr.StateManager
pv ffiwrapper.Verifier
}
func (mca mca) ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
@ -493,47 +496,36 @@ func (mca mca) ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, pers
return mca.sm.ChainStore().GetRandomness(ctx, pts.Cids(), personalization, randEpoch, entropy)
}
func (mca mca) MinerGetBaseInfo(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (*api.MiningBaseInfo, error) {
return stmgr.MinerGetBaseInfo(ctx, mca.sm, tsk, maddr)
func (mca mca) MinerGetBaseInfo(ctx context.Context, maddr address.Address, epoch abi.ChainEpoch, tsk types.TipSetKey) (*api.MiningBaseInfo, error) {
return stmgr.MinerGetBaseInfo(ctx, mca.sm, tsk, epoch, maddr, mca.pv)
}
func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*crypto.Signature, error) {
return mca.w.Sign(ctx, a, v)
}
type ElectionPoStProver interface {
GenerateCandidates(context.Context, []abi.SectorInfo, abi.PoStRandomness) ([]storage.PoStCandidateWithTicket, error)
ComputeProof(context.Context, []abi.SectorInfo, []byte, []storage.PoStCandidateWithTicket) ([]abi.PoStProof, error)
type WinningPoStProver interface {
GenerateCandidates(context.Context, abi.PoStRandomness, uint64) ([]uint64, error)
ComputeProof(context.Context, []abi.SectorInfo, abi.PoStRandomness) ([]abi.PoStProof, error)
}
type eppProvider struct{}
type wppProvider struct{}
func (epp *eppProvider) GenerateCandidates(ctx context.Context, _ []abi.SectorInfo, eprand abi.PoStRandomness) ([]storage.PoStCandidateWithTicket, error) {
return []storage.PoStCandidateWithTicket{
{
Candidate: abi.PoStCandidate{
RegisteredProof: abi.RegisteredProof_StackedDRG2KiBPoSt,
SectorID: abi.SectorID{Number: 1},
PartialTicket: abi.PartialTicket{},
PrivateProof: abi.PrivatePoStCandidateProof{},
ChallengeIndex: 1,
},
},
}, nil
func (wpp *wppProvider) GenerateCandidates(ctx context.Context, _ abi.PoStRandomness, _ uint64) ([]uint64, error) {
return []uint64{0}, nil
}
func (epp *eppProvider) ComputeProof(ctx context.Context, _ []abi.SectorInfo, eprand []byte, winners []storage.PoStCandidateWithTicket) ([]abi.PoStProof, error) {
func (wpp *wppProvider) ComputeProof(context.Context, []abi.SectorInfo, abi.PoStRandomness) ([]abi.PoStProof, error) {
return []abi.PoStProof{{
ProofBytes: []byte("valid proof"),
}}, nil
}
type ProofInput struct {
sectors []abi.SectorInfo
hvrf []byte
winners []storage.PoStCandidateWithTicket
vrfout []byte
sectors []abi.SectorInfo
hvrf []byte
challengedSectors []uint64
vrfout []byte
}
func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch,
@ -549,7 +541,7 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch,
return nil, xerrors.Errorf("failed to draw randomness: %w", err)
}
vrfout, err := ComputeVRF(ctx, a.WalletSign, mbi.Worker, electionRand)
vrfout, err := ComputeVRF(ctx, a.WalletSign, mbi.WorkerKey, electionRand)
if err != nil {
return nil, xerrors.Errorf("failed to compute VRF: %w", err)
}
@ -562,31 +554,6 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch,
return &types.ElectionProof{VRFProof: vrfout}, nil
}
/*
func ComputeProof(ctx context.Context, epp ElectionPoStProver, pi *ProofInput) (*types.EPostProof, error) {
proof, err := epp.ComputeProof(ctx, pi.sectors, pi.hvrf, pi.winners)
if err != nil {
return nil, xerrors.Errorf("failed to compute snark for election proof: %w", err)
}
ept := types.EPostProof{
Proofs: proof,
PostRand: pi.vrfout,
}
for _, win := range pi.winners {
part := make([]byte, 32)
copy(part, win.Candidate.PartialTicket)
ept.Candidates = append(ept.Candidates, types.EPostTicket{
Partial: part,
SectorID: win.Candidate.SectorID.Number,
ChallengeIndex: uint64(win.Candidate.ChallengeIndex),
})
}
return &ept, nil
}
*/
type SignFunc func(context.Context, address.Address, []byte) (*crypto.Signature, error)
func VerifyVRF(ctx context.Context, worker address.Address, vrfBase, vrfproof []byte) error {
@ -622,14 +589,18 @@ type genFakeVerifier struct{}
var _ ffiwrapper.Verifier = (*genFakeVerifier)(nil)
func (m genFakeVerifier) VerifyElectionPost(ctx context.Context, pvi abi.PoStVerifyInfo) (bool, error) {
panic("nyi")
}
func (m genFakeVerifier) VerifySeal(svi abi.SealVerifyInfo) (bool, error) {
return true, nil
}
func (m genFakeVerifier) VerifyFallbackPost(ctx context.Context, pvi abi.PoStVerifyInfo) (bool, error) {
panic("nyi")
func (m genFakeVerifier) VerifyWinningPoSt(ctx context.Context, info abi.WinningPoStVerifyInfo) (bool, error) {
panic("not supported")
}
func (m genFakeVerifier) VerifyWindowPoSt(ctx context.Context, info abi.WindowPoStVerifyInfo) (bool, error) {
panic("not supported")
}
func (m genFakeVerifier) GenerateWinningPoStSectorChallenge(ctx context.Context, proof abi.RegisteredProof, id abi.ActorID, randomness abi.PoStRandomness, u uint64) ([]uint64, error) {
panic("not supported")
}

View File

@ -47,6 +47,7 @@ The process:
- Setup Cron
- Create empty power actor
- Create empty market
- Create verified registry
- Setup burnt fund address
- Initialize account / msig balances
- Instantiate early vm with genesis syscalls
@ -164,6 +165,15 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
return nil, xerrors.Errorf("set market actor: %w", err)
}
// Create verified registry
verifact, err := SetupVerifiedRegistryActor(bs)
if err != nil {
return nil, xerrors.Errorf("setup storage market actor: %w", err)
}
if err := state.SetActor(builtin.VerifiedRegistryActorAddr, verifact); err != nil {
return nil, xerrors.Errorf("set market actor: %w", err)
}
// Setup burnt-funds
err = state.SetActor(builtin.BurntFundsActorAddr, &types.Actor{
Code: builtin.AccountActorCodeID,

View File

@ -6,9 +6,10 @@ import (
"fmt"
"math/rand"
cborutil "github.com/filecoin-project/go-cbor-util"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
@ -16,12 +17,12 @@ import (
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/market"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/genesis"
)
@ -70,7 +71,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
var ma power.CreateMinerReturn
if err := ma.UnmarshalCBOR(bytes.NewReader(rval)); err != nil {
return cid.Undef, err
return cid.Undef, xerrors.Errorf("unmarshaling CreateMinerReturn: %w", err)
}
expma := MinerAddress(uint64(i))
@ -101,50 +102,42 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
var dealIDs []abi.DealID
{
publish := func(params *market.PublishStorageDealsParams) error {
fmt.Printf("publishing %d storage deals on miner %s with worker %s\n", len(params.Deals), params.Deals[0].Proposal.Provider, m.Worker)
ret, err := doExecValue(ctx, vm, builtin.StorageMarketActorAddr, m.Worker, big.Zero(), builtin.MethodsMarket.PublishStorageDeals, mustEnc(params))
if err != nil {
return xerrors.Errorf("failed to create genesis miner: %w", err)
}
var ids market.PublishStorageDealsReturn
if err := ids.UnmarshalCBOR(bytes.NewReader(ret)); err != nil {
return xerrors.Errorf("unmarsahling publishStorageDeals result: %w", err)
}
dealIDs = append(dealIDs, ids.IDs...)
return nil
}
params := &market.PublishStorageDealsParams{}
for _, preseal := range m.Sectors {
params.Deals = append(params.Deals, market.ClientDealProposal{
Proposal: preseal.Deal,
ClientSignature: crypto.Signature{Type: crypto.SigTypeBLS}, // TODO: do we want to sign these? Or do we want to fake signatures for genesis setup?
})
fmt.Printf("calling publish storage deals on miner %s with worker %s\n", preseal.Deal.Provider, m.Worker)
if len(params.Deals) == cbg.MaxLength {
if err := publish(params); err != nil {
return cid.Undef, err
}
params = &market.PublishStorageDealsParams{}
}
}
ret, err := doExecValue(ctx, vm, builtin.StorageMarketActorAddr, m.Worker, big.Zero(), builtin.MethodsMarket.PublishStorageDeals, mustEnc(params))
if err != nil {
return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err)
}
var ids market.PublishStorageDealsReturn
if err := ids.UnmarshalCBOR(bytes.NewReader(ret)); err != nil {
return cid.Undef, err
}
dealIDs = ids.IDs
}
// setup windowed post
{
err = vm.MutateState(ctx, maddr, func(cst cbor.IpldStore, st *miner.State) error {
// TODO: Randomize so all genesis miners don't fall on the same epoch
st.PoStState.ProvingPeriodStart = miner.ProvingPeriod
return nil
})
payload, err := cborutil.Dump(&miner.CronEventPayload{
EventType: miner.CronEventWindowedPoStExpiration,
})
if err != nil {
return cid.Undef, err
}
params := &power.EnrollCronEventParams{
EventEpoch: miner.ProvingPeriod + power.WindowedPostChallengeDuration,
Payload: payload,
}
_, err = doExecValue(ctx, vm, builtin.StoragePowerActorAddr, maddr, big.Zero(), builtin.MethodsPower.EnrollCronEvent, mustEnc(params))
if err != nil {
return cid.Undef, xerrors.Errorf("failed to verify preseal deals miner: %w", err)
if len(params.Deals) > 0 {
if err := publish(params); err != nil {
return cid.Undef, err
}
}
}
@ -153,10 +146,11 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
// TODO: Maybe check seal (Can just be snark inputs, doesn't go into the genesis file)
// check deals, get dealWeight
dealWeight := big.Zero()
var dealWeight market.VerifyDealsOnSectorProveCommitReturn
{
params := &market.VerifyDealsOnSectorProveCommitParams{
DealIDs: []abi.DealID{dealIDs[pi]},
SectorSize: m.SectorSize,
SectorExpiry: preseal.Deal.EndEpoch,
}
@ -165,27 +159,27 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
return cid.Undef, xerrors.Errorf("failed to verify preseal deals miner: %w", err)
}
if err := dealWeight.UnmarshalCBOR(bytes.NewReader(ret)); err != nil {
return cid.Undef, err
return cid.Undef, xerrors.Errorf("unmarshaling market onProveCommit result: %w", err)
}
}
// update power claims
pledge := big.Zero()
{
err = vm.MutateState(ctx, builtin.StoragePowerActorAddr, func(cst cbor.IpldStore, st *power.State) error {
weight := &power.SectorStorageWeightDesc{
SectorSize: m.SectorSize,
Duration: preseal.Deal.Duration(),
DealWeight: dealWeight,
SectorSize: m.SectorSize,
Duration: preseal.Deal.Duration(),
DealWeight: dealWeight.DealWeight,
VerifiedDealWeight: dealWeight.VerifiedDealWeight,
}
spower := power.ConsensusPowerForWeight(weight)
pledge = power.PledgeForWeight(weight, st.TotalNetworkPower)
err := st.AddToClaim(&state.AdtStore{cst}, maddr, spower, pledge)
qapower := power.QAPowerForWeight(weight)
err := st.AddToClaim(&state.AdtStore{cst}, maddr, types.NewInt(uint64(weight.SectorSize)), qapower)
if err != nil {
return xerrors.Errorf("add to claim: %w", err)
}
fmt.Println("Added weight to claim: ", st.TotalNetworkPower)
fmt.Println("Added weight to claim: ", st.TotalRawBytePower, st.TotalQualityAdjPower)
return nil
})
if err != nil {
@ -204,61 +198,43 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
DealIDs: []abi.DealID{dealIDs[pi]},
Expiration: preseal.Deal.EndEpoch,
},
ActivationEpoch: 0,
DealWeight: dealWeight,
PledgeRequirement: pledge,
DeclaredFaultEpoch: -1,
DeclaredFaultDuration: -1,
ActivationEpoch: 0,
DealWeight: dealWeight.DealWeight,
VerifiedDealWeight: dealWeight.VerifiedDealWeight,
}
err = vm.MutateState(ctx, maddr, func(cst cbor.IpldStore, st *miner.State) error {
store := &state.AdtStore{cst}
if err = st.PutSector(store, newSectorInfo); err != nil {
return xerrors.Errorf("failed to prove commit: %v", err)
return xerrors.Errorf("failed to put sector: %v", err)
}
if err := st.AddNewSectors(newSectorInfo.Info.SectorNumber); err != nil {
return xerrors.Errorf("failed to add NewSector: %w", err)
}
st.ProvingSet = st.Sectors
return nil
})
if err != nil {
return cid.Cid{}, xerrors.Errorf("put to sset: %w", err)
}
}
{
sectorBf := abi.NewBitField()
sectorBf.Set(uint64(preseal.SectorID))
payload, err := cborutil.Dump(&miner.CronEventPayload{
EventType: miner.CronEventSectorExpiry,
Sectors: &sectorBf,
})
if err != nil {
return cid.Undef, err
}
params := &power.EnrollCronEventParams{
EventEpoch: preseal.Deal.EndEpoch,
Payload: payload,
}
_, err = doExecValue(ctx, vm, builtin.StoragePowerActorAddr, maddr, big.Zero(), builtin.MethodsPower.EnrollCronEvent, mustEnc(params))
if err != nil {
return cid.Undef, xerrors.Errorf("failed to verify preseal deals miner: %w", err)
}
}
}
}
// TODO: to avoid division by zero, we set the initial power actor power to 1, this adjusts that back down so the accounting is accurate.
err = vm.MutateState(ctx, builtin.StoragePowerActorAddr, func(cst cbor.IpldStore, st *power.State) error {
st.TotalNetworkPower = big.Sub(st.TotalNetworkPower, big.NewInt(1))
st.TotalQualityAdjPower = big.Sub(st.TotalQualityAdjPower, big.NewInt(1))
return nil
})
c, err := vm.Flush(ctx)
return c, err
if err != nil {
return cid.Undef, xerrors.Errorf("flushing vm: %w", err)
}
return c, nil
}
// TODO: copied from actors test harness, deduplicate or remove from here

View File

@ -17,12 +17,14 @@ func SetupRewardActor(bs bstore.Blockstore) (*types.Actor, error) {
cst := cbor.NewCborStore(bs)
as := store.ActorStore(context.TODO(), bs)
emv, err := adt.MakeEmptyMultimap(as)
emv := adt.MakeEmptyMultimap(as)
r, err := emv.Root()
if err != nil {
return nil, err
}
st := reward.ConstructState(emv.Root())
st := reward.ConstructState(r)
hcid, err := cst.Put(context.TODO(), st)
if err != nil {
return nil, err

View File

@ -2,7 +2,6 @@ package genesis
import (
"context"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/abi/big"
@ -24,11 +23,12 @@ func SetupStoragePowerActor(bs bstore.Blockstore) (*types.Actor, error) {
}
sms := &power.State{
TotalNetworkPower: big.NewInt(1), // TODO: has to be 1 initially to avoid div by zero. Kinda annoying, should find a way to fix
TotalRawBytePower: big.NewInt(0),
TotalQualityAdjPower: big.NewInt(1), // TODO: has to be 1 initially to avoid div by zero. Kinda annoying, should find a way to fix
TotalPledgeCollateral: big.NewInt(0),
MinerCount: 0,
EscrowTable: emptyhamt,
CronEventQueue: emptyhamt,
PoStDetectedFaultMiners: emptyhamt,
LastEpochTick: 0,
Claims: emptyhamt,
NumMinersMeetingMinPower: 0,
}

View File

@ -0,0 +1,44 @@
package genesis
import (
"context"
"crypto/rand"
"github.com/filecoin-project/go-address"
"github.com/ipfs/go-hamt-ipld"
bstore "github.com/ipfs/go-ipfs-blockstore"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/filecoin-project/lotus/chain/types"
)
func SetupVerifiedRegistryActor(bs bstore.Blockstore) (*types.Actor, error) {
cst := cbor.NewCborStore(bs)
h, err := cst.Put(context.TODO(), hamt.NewNode(cst, hamt.UseTreeBitWidth(5)))
if err != nil {
return nil, err
}
var r [32]byte // TODO: grab from genesis template
_, _ = rand.Read(r[:])
k, _ := address.NewSecp256k1Address(r[:])
sms := verifreg.ConstructState(h, k)
stcid, err := cst.Put(context.TODO(), sms)
if err != nil {
return nil, err
}
act := &types.Actor{
Code: builtin.VerifiedRegistryActorCodeID,
Head: stcid,
Balance: types.NewInt(0),
}
return act, nil
}

View File

@ -42,10 +42,10 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wal
Ticket: bt.Ticket,
ElectionProof: bt.Eproof,
BeaconEntries: bt.BeaconValues,
Height: bt.Epoch,
Timestamp: bt.Timestamp,
//EPostProof: *proof,
BeaconEntries: bt.BeaconValues,
Height: bt.Epoch,
Timestamp: bt.Timestamp,
WinPoStProof: bt.WinningPoStProof,
ParentStateRoot: st,
ParentMessageReceipts: recpts,
}

View File

@ -130,6 +130,7 @@ type Provider interface {
PutMessage(m types.ChainMsg) (cid.Cid, error)
PubSubPublish(string, []byte) error
StateGetActor(address.Address, *types.TipSet) (*types.Actor, error)
StateAccountKey(context.Context, address.Address, *types.TipSet) (address.Address, error)
MessagesForBlock(*types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error)
MessagesForTipset(*types.TipSet) ([]types.ChainMsg, error)
LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error)
@ -161,6 +162,10 @@ func (mpp *mpoolProvider) StateGetActor(addr address.Address, ts *types.TipSet)
return mpp.sm.GetActor(addr, ts)
}
func (mpp *mpoolProvider) StateAccountKey(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
return mpp.sm.ResolveToKeyAddress(ctx, addr, ts)
}
func (mpp *mpoolProvider) MessagesForBlock(h *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) {
return mpp.sm.ChainStore().MessagesForBlock(h)
}
@ -470,22 +475,28 @@ func (mp *MessagePool) getStateBalance(addr address.Address, ts *types.TipSet) (
return act.Balance, nil
}
func (mp *MessagePool) PushWithNonce(addr address.Address, cb func(uint64) (*types.SignedMessage, error)) (*types.SignedMessage, error) {
func (mp *MessagePool) PushWithNonce(ctx context.Context, addr address.Address, cb func(address.Address, uint64) (*types.SignedMessage, error)) (*types.SignedMessage, error) {
mp.curTsLk.Lock()
defer mp.curTsLk.Unlock()
mp.lk.Lock()
defer mp.lk.Unlock()
if addr.Protocol() == address.ID {
log.Warnf("Called pushWithNonce with ID address (%s) this might not be handled properly yet", addr)
fromKey := addr
if fromKey.Protocol() == address.ID {
var err error
fromKey, err = mp.api.StateAccountKey(ctx, fromKey, mp.curTs)
if err != nil {
return nil, xerrors.Errorf("resolving sender key: %w", err)
}
}
nonce, err := mp.getNonceLocked(addr, mp.curTs)
nonce, err := mp.getNonceLocked(fromKey, mp.curTs)
if err != nil {
return nil, xerrors.Errorf("get nonce locked failed: %w", err)
}
msg, err := cb(nonce)
msg, err := cb(fromKey, nonce)
if err != nil {
return nil, err
}

View File

@ -1,6 +1,7 @@
package messagepool
import (
"context"
"fmt"
"testing"
@ -74,6 +75,13 @@ func (tma *testMpoolApi) StateGetActor(addr address.Address, ts *types.TipSet) (
}, nil
}
func (tma *testMpoolApi) StateAccountKey(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
if addr.Protocol() != address.BLS && addr.Protocol() != address.SECP256K1 {
return address.Undef, fmt.Errorf("given address was not a key addr")
}
return addr, nil
}
func (tma *testMpoolApi) MessagesForBlock(h *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) {
return nil, tma.bmsgs[h.Cid()], nil
}

View File

@ -720,7 +720,10 @@ func (sm *StateManager) MarketBalance(ctx context.Context, addr address.Address,
var out api.MarketBalance
et := adt.AsBalanceTable(sm.cs.Store(ctx), state.EscrowTable)
et, err := adt.AsBalanceTable(sm.cs.Store(ctx), state.EscrowTable)
if err != nil {
return api.MarketBalance{}, err
}
ehas, err := et.Has(addr)
if err != nil {
return api.MarketBalance{}, err
@ -734,7 +737,10 @@ func (sm *StateManager) MarketBalance(ctx context.Context, addr address.Address,
out.Escrow = big.Zero()
}
lt := adt.AsBalanceTable(sm.cs.Store(ctx), state.LockedTable)
lt, err := adt.AsBalanceTable(sm.cs.Store(ctx), state.LockedTable)
if err != nil {
return api.MarketBalance{}, err
}
lhas, err := lt.Has(addr)
if err != nil {
return api.MarketBalance{}, err

View File

@ -2,33 +2,33 @@ package stmgr
import (
"context"
"os"
cid "github.com/ipfs/go-cid"
blockstore "github.com/ipfs/go-ipfs-blockstore"
cbor "github.com/ipfs/go-ipld-cbor"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
amt "github.com/filecoin-project/go-amt-ipld/v2"
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
"github.com/filecoin-project/specs-actors/actors/builtin/market"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/node/modules/dtypes"
cid "github.com/ipfs/go-cid"
blockstore "github.com/ipfs/go-ipfs-blockstore"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/libp2p/go-libp2p-core/peer"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
)
func GetNetworkName(ctx context.Context, sm *StateManager, st cid.Cid) (dtypes.NetworkName, error) {
@ -57,68 +57,36 @@ func GetMinerWorkerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr
return vm.ResolveToKeyAddr(state, cst, mas.Info.Worker)
}
func GetMinerOwner(ctx context.Context, sm *StateManager, st cid.Cid, maddr address.Address) (address.Address, error) {
var mas miner.State
_, err := sm.LoadActorStateRaw(ctx, maddr, &mas, st)
if err != nil {
return address.Undef, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err)
}
cst := cbor.NewCborStore(sm.cs.Blockstore())
state, err := state.LoadStateTree(cst, st)
if err != nil {
return address.Undef, xerrors.Errorf("load state tree: %w", err)
}
return vm.ResolveToKeyAddr(state, cst, mas.Info.Owner)
func GetPower(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (power.Claim, power.Claim, error) {
return GetPowerRaw(ctx, sm, ts.ParentState(), maddr)
}
func GetPower(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (types.BigInt, types.BigInt, error) {
return getPowerRaw(ctx, sm, ts.ParentState(), maddr)
}
func getPowerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr address.Address) (types.BigInt, types.BigInt, error) {
func GetPowerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr address.Address) (power.Claim, power.Claim, error) {
var ps power.State
_, err := sm.LoadActorStateRaw(ctx, builtin.StoragePowerActorAddr, &ps, st)
if err != nil {
return big.Zero(), big.Zero(), xerrors.Errorf("(get sset) failed to load power actor state: %w", err)
return power.Claim{}, power.Claim{}, xerrors.Errorf("(get sset) failed to load power actor state: %w", err)
}
var mpow big.Int
var mpow power.Claim
if maddr != address.Undef {
var claim power.Claim
if _, err := adt.AsMap(sm.cs.Store(ctx), ps.Claims).Get(adt.AddrKey(maddr), &claim); err != nil {
return big.Zero(), big.Zero(), err
cm, err := adt.AsMap(sm.cs.Store(ctx), ps.Claims)
if err != nil {
return power.Claim{}, power.Claim{}, err
}
mpow = claim.Power
var claim power.Claim
if _, err := cm.Get(adt.AddrKey(maddr), &claim); err != nil {
return power.Claim{}, power.Claim{}, err
}
mpow = claim
}
return mpow, ps.TotalNetworkPower, nil
}
func GetMinerPeerID(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (peer.ID, error) {
var mas miner.State
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
if err != nil {
return "", xerrors.Errorf("(get sset) failed to load miner actor state: %w", err)
}
return mas.Info.PeerId, nil
}
func GetMinerWorker(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (address.Address, error) {
return GetMinerWorkerRaw(ctx, sm, sm.parentState(ts), maddr)
}
func GetMinerPostState(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (*miner.PoStState, error) {
var mas miner.State
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
if err != nil {
return nil, xerrors.Errorf("(get eps) failed to load miner actor state: %w", err)
}
return &mas.PoStState, nil
return mpow, power.Claim{
RawBytePower: ps.TotalRawBytePower,
QualityAdjPower: ps.TotalQualityAdjPower,
}, nil
}
func SectorSetSizes(ctx context.Context, sm *StateManager, maddr address.Address, ts *types.TipSet) (api.MinerSectors, error) {
@ -134,13 +102,7 @@ func SectorSetSizes(ctx context.Context, sm *StateManager, maddr address.Address
return api.MinerSectors{}, err
}
ps, err := amt.LoadAMT(ctx, blks, mas.ProvingSet)
if err != nil {
return api.MinerSectors{}, err
}
return api.MinerSectors{
Pset: ps.Count,
Sset: ss.Count,
}, nil
}
@ -163,60 +125,69 @@ func PreCommitInfo(ctx context.Context, sm *StateManager, maddr address.Address,
return *i, nil
}
func GetMinerProvingSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]*api.ChainSectorInfo, error) {
return getMinerProvingSetRaw(ctx, sm, ts.ParentState(), maddr)
}
func getMinerProvingSetRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr address.Address) ([]*api.ChainSectorInfo, error) {
var mas miner.State
_, err := sm.LoadActorStateRaw(ctx, maddr, &mas, st)
if err != nil {
return nil, xerrors.Errorf("(get pset) failed to load miner actor state: %w", err)
}
return LoadSectorsFromSet(ctx, sm.ChainStore().Blockstore(), mas.ProvingSet)
}
func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]*api.ChainSectorInfo, error) {
func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address, filter *abi.BitField, filterOut bool) ([]*api.ChainSectorInfo, error) {
var mas miner.State
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
if err != nil {
return nil, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err)
}
return LoadSectorsFromSet(ctx, sm.ChainStore().Blockstore(), mas.Sectors)
return LoadSectorsFromSet(ctx, sm.ChainStore().Blockstore(), mas.Sectors, filter, filterOut)
}
func GetSectorsForElectionPost(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]abi.SectorInfo, error) {
sectors, err := GetMinerProvingSet(ctx, sm, ts, maddr)
if err != nil {
return nil, xerrors.Errorf("failed to get sector set for miner: %w", err)
}
var uselessOtherArray []abi.SectorInfo
for _, s := range sectors {
uselessOtherArray = append(uselessOtherArray, abi.SectorInfo{
RegisteredProof: s.Info.Info.RegisteredProof,
SectorNumber: s.ID,
SealedCID: s.Info.Info.SealedCID,
})
}
return uselessOtherArray, nil
}
func GetMinerSectorSize(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (abi.SectorSize, error) {
return getMinerSectorSizeRaw(ctx, sm, ts.ParentState(), maddr)
}
func getMinerSectorSizeRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr address.Address) (abi.SectorSize, error) {
func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *StateManager, st cid.Cid, maddr address.Address, rand abi.PoStRandomness) ([]abi.SectorInfo, error) {
var mas miner.State
_, err := sm.LoadActorStateRaw(ctx, maddr, &mas, st)
if err != nil {
return 0, xerrors.Errorf("(get ssize) failed to load miner actor state: %w", err)
return nil, xerrors.Errorf("(get sectors) failed to load miner actor state: %w", err)
}
return mas.Info.SectorSize, nil
// TODO: Optimization: we could avoid loaditg the whole proving set here if we had AMT.GetNth with bitfield filtering
sectorSet, err := GetProvingSetRaw(ctx, sm, mas)
if err != nil {
return nil, xerrors.Errorf("getting proving set: %w", err)
}
spt, err := ffiwrapper.SealProofTypeFromSectorSize(mas.Info.SectorSize)
if err != nil {
return nil, xerrors.Errorf("getting seal proof type: %w", err)
}
wpt, err := spt.RegisteredWinningPoStProof()
if err != nil {
return nil, xerrors.Errorf("getting window proof type: %w", err)
}
mid, err := address.IDFromAddress(maddr)
if err != nil {
return nil, xerrors.Errorf("getting miner ID: %w", err)
}
ids, err := pv.GenerateWinningPoStSectorChallenge(ctx, wpt, abi.ActorID(mid), rand, uint64(len(sectorSet)))
if err != nil {
return nil, xerrors.Errorf("generating winning post challenges: %w", err)
}
out := make([]abi.SectorInfo, len(ids))
for i, n := range ids {
out[i] = abi.SectorInfo{
RegisteredProof: wpt,
SectorNumber: sectorSet[n].ID,
SealedCID: sectorSet[n].Info.Info.SealedCID,
}
}
return out, nil
}
func StateMinerInfo(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (miner.MinerInfo, error) {
var mas miner.State
_, err := sm.LoadActorStateRaw(ctx, maddr, &mas, ts.ParentState())
if err != nil {
return miner.MinerInfo{}, xerrors.Errorf("(get ssize) failed to load miner actor state: %w", err)
}
return mas.Info, nil
}
func GetMinerSlashed(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (bool, error) {
@ -226,10 +197,6 @@ func GetMinerSlashed(ctx context.Context, sm *StateManager, ts *types.TipSet, ma
return false, xerrors.Errorf("(get miner slashed) failed to load miner actor state")
}
if mas.PoStState.HasFailedPost() {
return true, nil
}
var spas power.State
_, err = sm.LoadActorState(ctx, builtin.StoragePowerActorAddr, &spas, ts)
if err != nil {
@ -237,7 +204,12 @@ func GetMinerSlashed(ctx context.Context, sm *StateManager, ts *types.TipSet, ma
}
store := sm.cs.Store(ctx)
claims := adt.AsMap(store, spas.Claims)
claims, err := adt.AsMap(store, spas.Claims)
if err != nil {
return false, err
}
ok, err := claims.Get(power.AddrKey(maddr), nil)
if err != nil {
return false, err
@ -249,6 +221,16 @@ func GetMinerSlashed(ctx context.Context, sm *StateManager, ts *types.TipSet, ma
return false, nil
}
func GetMinerDeadlines(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (*miner.Deadlines, error) {
var mas miner.State
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
if err != nil {
return nil, xerrors.Errorf("(get ssize) failed to load miner actor state: %w", err)
}
return mas.LoadDeadlines(sm.cs.Store(ctx))
}
func GetMinerFaults(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]abi.SectorNumber, error) {
var mas miner.State
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
@ -256,12 +238,7 @@ func GetMinerFaults(ctx context.Context, sm *StateManager, ts *types.TipSet, mad
return nil, xerrors.Errorf("(get ssize) failed to load miner actor state: %w", err)
}
ss, lerr := amt.LoadAMT(ctx, cbor.NewCborStore(sm.cs.Blockstore()), mas.Sectors)
if lerr != nil {
return nil, aerrors.HandleExternalError(lerr, "could not load proving set node")
}
faults, err := mas.FaultSet.All(2 * ss.Count)
faults, err := mas.Faults.All(miner.SectorsMax)
if err != nil {
return nil, xerrors.Errorf("reading fault bit set: %w", err)
}
@ -290,7 +267,11 @@ func GetStorageDeal(ctx context.Context, sm *StateManager, dealId abi.DealID, ts
return nil, err
}
sa := market.AsDealStateArray(sm.ChainStore().Store(ctx), state.States)
sa, err := market.AsDealStateArray(sm.ChainStore().Store(ctx), state.States)
if err != nil {
return nil, err
}
st, err := sa.Get(dealId)
if err != nil {
return nil, err
@ -308,8 +289,13 @@ func ListMinerActors(ctx context.Context, sm *StateManager, ts *types.TipSet) ([
return nil, err
}
m, err := adt.AsMap(sm.cs.Store(ctx), state.Claims)
if err != nil {
return nil, err
}
var miners []address.Address
err := adt.AsMap(sm.cs.Store(ctx), state.Claims).ForEach(nil, func(k string) error {
err = m.ForEach(nil, func(k string) error {
a, err := address.NewFromBytes([]byte(k))
if err != nil {
return err
@ -324,7 +310,7 @@ func ListMinerActors(ctx context.Context, sm *StateManager, ts *types.TipSet) ([
return miners, nil
}
func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.Cid) ([]*api.ChainSectorInfo, error) {
func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.Cid, filter *abi.BitField, filterOut bool) ([]*api.ChainSectorInfo, error) {
a, err := amt.LoadAMT(ctx, cbor.NewCborStore(bs), ssc)
if err != nil {
return nil, err
@ -332,6 +318,16 @@ func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.C
var sset []*api.ChainSectorInfo
if err := a.ForEach(ctx, func(i uint64, v *cbg.Deferred) error {
if filter != nil {
set, err := filter.IsSet(i)
if err != nil {
return xerrors.Errorf("filter check error: %w", err)
}
if set == filterOut {
return nil
}
}
var oci miner.SectorOnChainInfo
if err := cbor.DecodeInto(v.Raw, &oci); err != nil {
return err
@ -388,48 +384,96 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
return root, trace, nil
}
func MinerGetBaseInfo(ctx context.Context, sm *StateManager, tsk types.TipSetKey, maddr address.Address) (*api.MiningBaseInfo, error) {
func GetProvingSetRaw(ctx context.Context, sm *StateManager, mas miner.State) ([]*api.ChainSectorInfo, error) {
notProving, err := abi.BitFieldUnion(mas.Faults, mas.Recoveries)
if err != nil {
return nil, err
}
provset, err := LoadSectorsFromSet(ctx, sm.cs.Blockstore(), mas.Sectors, notProving, true)
if err != nil {
return nil, xerrors.Errorf("failed to get proving set: %w", err)
}
return provset, nil
}
func GetLookbackTipSetForRound(ctx context.Context, sm *StateManager, ts *types.TipSet, round abi.ChainEpoch) (*types.TipSet, error) {
var lbr abi.ChainEpoch
if round > build.WinningPoStSectorSetLookback {
lbr = round - build.WinningPoStSectorSetLookback
}
// more null blocks than our lookback
if lbr > ts.Height() {
return ts, nil
}
lbts, err := sm.ChainStore().GetTipsetByHeight(ctx, lbr, ts)
if err != nil {
return nil, xerrors.Errorf("failed to get lookback tipset: %w", err)
}
return lbts, nil
}
func MinerGetBaseInfo(ctx context.Context, sm *StateManager, tsk types.TipSetKey, round abi.ChainEpoch, maddr address.Address, pv ffiwrapper.Verifier) (*api.MiningBaseInfo, error) {
ts, err := sm.ChainStore().LoadTipSet(tsk)
if err != nil {
return nil, xerrors.Errorf("failed to load tipset for mining base: %w", err)
}
st, _, err := sm.TipSetState(ctx, ts)
lbts, err := GetLookbackTipSetForRound(ctx, sm, ts, round)
if err != nil {
return nil, xerrors.Errorf("getting lookback miner actor state: %w", err)
}
lbst, _, err := sm.TipSetState(ctx, lbts)
if err != nil {
return nil, err
}
provset, err := getMinerProvingSetRaw(ctx, sm, st, maddr)
if err != nil {
return nil, xerrors.Errorf("failed to get proving set: %w", err)
var mas miner.State
if _, err := sm.LoadActorStateRaw(ctx, maddr, &mas, lbst); err != nil {
return nil, err
}
mpow, tpow, err := getPowerRaw(ctx, sm, st, maddr)
// TODO: use the right dst, also NB: not using any 'entropy' in this call because nicola really didnt want it
prand, err := sm.cs.GetRandomness(ctx, ts.Cids(), crypto.DomainSeparationTag_ElectionPoStChallengeSeed, round-1, nil)
if err != nil {
return nil, xerrors.Errorf("failed to get randomness for winning post: %w", err)
}
sectors, err := GetSectorsForWinningPoSt(ctx, pv, sm, lbst, maddr, prand)
if err != nil {
return nil, xerrors.Errorf("getting wpost proving set: %w", err)
}
mpow, tpow, err := GetPowerRaw(ctx, sm, lbst, maddr)
if err != nil {
return nil, xerrors.Errorf("failed to get power: %w", err)
}
worker, err := GetMinerWorkerRaw(ctx, sm, st, maddr)
if err != nil {
return nil, xerrors.Errorf("failed to get miner worker: %w", err)
}
ssize, err := getMinerSectorSizeRaw(ctx, sm, st, maddr)
if err != nil {
return nil, xerrors.Errorf("failed to get miner sector size: %w", err)
}
prev, err := sm.ChainStore().GetLatestBeaconEntry(ts)
if err != nil {
return nil, xerrors.Errorf("failed to get latest beacon entry: %w", err)
if os.Getenv("LOTUS_IGNORE_DRAND") != "_yes_" {
return nil, xerrors.Errorf("failed to get latest beacon entry: %w", err)
}
prev = &types.BeaconEntry{}
}
worker, err := sm.ResolveToKeyAddress(ctx, mas.GetWorker(), ts)
if err != nil {
return nil, xerrors.Errorf("resolving worker address: %w", err)
}
return &api.MiningBaseInfo{
MinerPower: mpow,
NetworkPower: tpow,
Sectors: provset,
Worker: worker,
SectorSize: ssize,
MinerPower: mpow.QualityAdjPower,
NetworkPower: tpow.QualityAdjPower,
Sectors: sectors,
WorkerKey: worker,
SectorSize: mas.Info.SectorSize,
PrevBeaconEntry: *prev,
}, nil
}

View File

@ -6,6 +6,7 @@ import (
"encoding/binary"
"encoding/json"
"io"
"os"
"sync"
"github.com/filecoin-project/specs-actors/actors/crypto"
@ -942,6 +943,10 @@ func (cs *ChainStore) GetTipsetByHeight(ctx context.Context, h abi.ChainEpoch, t
return nil, xerrors.Errorf("looking for tipset with height less than start point")
}
if h == ts.Height() {
return ts, nil
}
if ts.Height()-h > build.ForkLengthThreshold {
log.Warnf("expensive call to GetTipsetByHeight, seeking %d levels", ts.Height()-h)
}
@ -955,6 +960,9 @@ func (cs *ChainStore) GetTipsetByHeight(ctx context.Context, h abi.ChainEpoch, t
if h > pts.Height() {
return ts, nil
}
if h == pts.Height() {
return pts, nil
}
ts = pts
}
@ -1107,6 +1115,12 @@ func (cs *ChainStore) GetLatestBeaconEntry(ts *types.TipSet) (*types.BeaconEntry
cur = next
}
if os.Getenv("LOTUS_IGNORE_DRAND") == "_yes_" {
return &types.BeaconEntry{
Data: []byte{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9},
}, nil
}
return nil, xerrors.Errorf("found NO beacon entries in the 20 blocks prior to given tipset")
}

View File

@ -44,7 +44,7 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn
if err := cst.Get(ctx, act.Head, &st); err != nil {
return types.NewInt(0), xerrors.Errorf("get power actor head: %w", err)
}
tpow = st.TotalNetworkPower
tpow = st.TotalQualityAdjPower // TODO: REVIEW: Is this correct?
}
log2P := int64(0)

View File

@ -5,6 +5,7 @@ import (
"context"
"errors"
"fmt"
"os"
"sort"
"strings"
"sync"
@ -28,6 +29,8 @@ import (
bls "github.com/filecoin-project/filecoin-ffi"
"github.com/filecoin-project/go-address"
amt "github.com/filecoin-project/go-amt-ipld/v2"
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/crypto"
@ -78,9 +81,11 @@ type Syncer struct {
incoming *pubsub.PubSub
receiptTracker *blockReceiptTracker
verifier ffiwrapper.Verifier
}
func NewSyncer(sm *stmgr.StateManager, bsync *blocksync.BlockSync, connmgr connmgr.ConnManager, self peer.ID, beacon beacon.RandomBeacon) (*Syncer, error) {
func NewSyncer(sm *stmgr.StateManager, bsync *blocksync.BlockSync, connmgr connmgr.ConnManager, self peer.ID, beacon beacon.RandomBeacon, verifier ffiwrapper.Verifier) (*Syncer, error) {
gen, err := sm.ChainStore().GetGenesis()
if err != nil {
return nil, err
@ -101,6 +106,7 @@ func NewSyncer(sm *stmgr.StateManager, bsync *blocksync.BlockSync, connmgr connm
self: self,
receiptTracker: newBlockReceiptTracker(),
connmgr: connmgr,
verifier: verifier,
incoming: pubsub.New(50),
}
@ -481,8 +487,13 @@ func (syncer *Syncer) minerIsValid(ctx context.Context, maddr address.Address, b
return err
}
cm, err := adt.AsMap(syncer.store.Store(ctx), spast.Claims)
if err != nil {
return err
}
var claim power.Claim
exist, err := adt.AsMap(syncer.store.Store(ctx), spast.Claims).Get(adt.AddrKey(maddr), &claim)
exist, err := cm.Get(adt.AddrKey(maddr), &claim)
if err != nil {
return err
}
@ -509,6 +520,16 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
return xerrors.Errorf("load parent tipset failed (%s): %w", h.Parents, err)
}
lbts, err := stmgr.GetLookbackTipSetForRound(ctx, syncer.sm, baseTs, h.Height)
if err != nil {
return xerrors.Errorf("failed to get lookback tipset for block: %w", err)
}
lbst, _, err := syncer.sm.TipSetState(ctx, lbts)
if err != nil {
return xerrors.Errorf("failed to compute lookback tipset state: %w", err)
}
prevBeacon, err := syncer.store.GetLatestBeaconEntry(baseTs)
if err != nil {
return xerrors.Errorf("failed to get latest beacon entry: %w", err)
@ -575,7 +596,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
return xerrors.Errorf("parent receipts root did not match computed value (%s != %s)", precp, h.ParentMessageReceipts)
}
waddr, err := stmgr.GetMinerWorkerRaw(ctx, syncer.sm, stateroot, h.Miner)
waddr, err := stmgr.GetMinerWorkerRaw(ctx, syncer.sm, lbst, h.Miner)
if err != nil {
return xerrors.Errorf("GetMinerWorkerRaw failed: %w", err)
}
@ -610,17 +631,15 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
return xerrors.Errorf("received block was from slashed or invalid miner")
}
mpow, tpow, err := stmgr.GetPower(ctx, syncer.sm, baseTs, h.Miner)
mpow, tpow, err := stmgr.GetPowerRaw(ctx, syncer.sm, lbst, h.Miner)
if err != nil {
return xerrors.Errorf("failed getting power: %w", err)
}
if !types.IsTicketWinner(h.ElectionProof.VRFProof, mpow, tpow) {
if !types.IsTicketWinner(h.ElectionProof.VRFProof, mpow.QualityAdjPower, tpow.QualityAdjPower) {
return xerrors.Errorf("miner created a block but was not a winner")
}
log.Warn("TODO: validate winning post proof") // TODO: validate winning post proof
return nil
})
@ -632,6 +651,10 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
})
beaconValuesCheck := async.Err(func() error {
if os.Getenv("LOTUS_IGNORE_DRAND") == "_yes_" {
return nil
}
if err := beacon.ValidateBlockValues(syncer.beacon, h, *prevBeacon); err != nil {
return xerrors.Errorf("failed to validate blocks random beacon values: %w", err)
}
@ -657,19 +680,19 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
return nil
})
//eproofCheck := async.Err(func() error {
//if err := syncer.VerifyElectionPoStProof(ctx, h, waddr); err != nil {
//return xerrors.Errorf("invalid election post: %w", err)
//}
//return nil
//})
wproofCheck := async.Err(func() error {
if err := syncer.VerifyWinningPoStProof(ctx, h, lbst, waddr); err != nil {
return xerrors.Errorf("invalid election post: %w", err)
}
return nil
})
await := []async.ErrorFuture{
minerCheck,
tktsCheck,
blockSigCheck,
beaconValuesCheck,
//eproofCheck,
wproofCheck,
winnerCheck,
msgsCheck,
}
@ -701,29 +724,27 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
return merr
}
/*
func (syncer *Syncer) VerifyElectionPoStProof(ctx context.Context, h *types.BlockHeader, waddr address.Address) error {
func (syncer *Syncer) VerifyWinningPoStProof(ctx context.Context, h *types.BlockHeader, lbst cid.Cid, waddr address.Address) error {
if build.InsecurePoStValidation {
if len(h.WinPoStProof) == 0 {
return xerrors.Errorf("[TESTING] No winning post proof given")
}
if string(h.WinPoStProof[0].ProofBytes) == "valid proof" {
return nil
}
return xerrors.Errorf("[TESTING] winning post was invalid")
}
curTs, err := types.NewTipSet([]*types.BlockHeader{h})
if err != nil {
return err
}
buf := new(bytes.Buffer)
if err := h.Miner.MarshalCBOR(buf); err != nil {
return xerrors.Errorf("failed to marshal miner to cbor: %w", err)
}
rand, err := syncer.sm.ChainStore().GetRandomness(ctx, curTs.Cids(), crypto.DomainSeparationTag_ElectionPoStChallengeSeed, h.Height-build.EcRandomnessLookback, buf.Bytes())
// TODO: use proper DST
rand, err := syncer.sm.ChainStore().GetRandomness(ctx, curTs.Cids(), crypto.DomainSeparationTag_ElectionPoStChallengeSeed, h.Height-1, nil)
if err != nil {
return xerrors.Errorf("failed to get randomness for verifying election proof: %w", err)
}
if err := VerifyElectionPoStVRF(ctx, h.EPostProof.PostRand, rand, waddr); err != nil {
return xerrors.Errorf("checking eproof failed: %w", err)
}
ssize, err := stmgr.GetMinerSectorSize(ctx, syncer.sm, curTs, h.Miner)
if err != nil {
return xerrors.Errorf("failed to get sector size for miner: %w", err)
return xerrors.Errorf("failed to get randomness for verifying winningPost proof: %w", err)
}
mid, err := address.IDFromAddress(h.Miner)
@ -731,79 +752,28 @@ func (syncer *Syncer) VerifyElectionPoStProof(ctx context.Context, h *types.Bloc
return xerrors.Errorf("failed to get ID from miner address %s: %w", h.Miner, err)
}
var winners []abi.PoStCandidate
for _, t := range h.EPostProof.Candidates {
winners = append(winners, abi.PoStCandidate{
PartialTicket: t.Partial,
SectorID: abi.SectorID{
Number: t.SectorID,
Miner: abi.ActorID(mid),
},
ChallengeIndex: int64(t.ChallengeIndex),
})
}
if len(winners) == 0 {
return xerrors.Errorf("no candidates")
}
sectorInfo, err := stmgr.GetSectorsForElectionPost(ctx, syncer.sm, curTs, h.Miner)
sectors, err := stmgr.GetSectorsForWinningPoSt(ctx, syncer.verifier, syncer.sm, lbst, h.Miner, rand)
if err != nil {
return xerrors.Errorf("getting election post sector set: %w", err)
return xerrors.Errorf("getting winning post sector set: %w", err)
}
if build.InsecurePoStValidation {
if len(h.EPostProof.Proofs) == 0 {
return xerrors.Errorf("[TESTING] No election post proof given")
}
if string(h.EPostProof.Proofs[0].ProofBytes) == "valid proof" {
return nil
}
return xerrors.Errorf("[TESTING] election post was invalid")
}
rt, _, err := ffiwrapper.ProofTypeFromSectorSize(ssize)
if err != nil {
return err
}
candidates := make([]abi.PoStCandidate, 0, len(h.EPostProof.Candidates))
for _, c := range h.EPostProof.Candidates {
candidates = append(candidates, abi.PoStCandidate{
RegisteredProof: rt,
PartialTicket: c.Partial,
SectorID: abi.SectorID{Number: c.SectorID}, // this should not be an ID, we already know who the miner is...
ChallengeIndex: int64(c.ChallengeIndex),
})
}
// TODO: why do we need this here?
challengeCount := ffiwrapper.ElectionPostChallengeCount(uint64(len(sectorInfo)), 0)
hvrf := blake2b.Sum256(h.EPostProof.PostRand)
pvi := abi.PoStVerifyInfo{
Randomness: hvrf[:],
Candidates: candidates,
Proofs: h.EPostProof.Proofs,
EligibleSectors: sectorInfo,
Prover: abi.ActorID(mid),
ChallengeCount: challengeCount,
}
ok, err := ffiwrapper.ProofVerifier.VerifyElectionPost(ctx, pvi)
ok, err := ffiwrapper.ProofVerifier.VerifyWinningPoSt(ctx, abi.WinningPoStVerifyInfo{
Randomness: rand,
Proofs: h.WinPoStProof,
ChallengedSectors: sectors,
Prover: abi.ActorID(mid),
})
if err != nil {
return xerrors.Errorf("failed to verify election post: %w", err)
}
if !ok {
log.Errorf("invalid election post (%x; %v)", pvi.Randomness, candidates)
return xerrors.Errorf("election post was invalid")
log.Errorf("invalid winning post (%x; %v)", rand, sectors)
return xerrors.Errorf("winning post was invalid")
}
return nil
}
*/
func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock, baseTs *types.TipSet) error {
{

View File

@ -63,18 +63,34 @@ func BigCmp(a, b BigInt) int {
return a.Int.Cmp(b.Int)
}
var sizeUnits = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB"}
var byteSizeUnits = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB"}
func SizeStr(bi BigInt) string {
r := new(big.Rat).SetInt(bi.Int)
den := big.NewRat(1, 1024)
var i int
for f, _ := r.Float64(); f >= 1024 && i+1 < len(sizeUnits); f, _ = r.Float64() {
for f, _ := r.Float64(); f >= 1024 && i+1 < len(byteSizeUnits); f, _ = r.Float64() {
i++
r = r.Mul(r, den)
}
f, _ := r.Float64()
return fmt.Sprintf("%.3g %s", f, sizeUnits[i])
return fmt.Sprintf("%.3g %s", f, byteSizeUnits[i])
}
var decUnits = []string{"", "K", "M", "G", "T", "P", "E", "Z"}
func DecStr(bi BigInt) string {
r := new(big.Rat).SetInt(bi.Int)
den := big.NewRat(1, 1000)
var i int
for f, _ := r.Float64(); f >= 1000 && i+1 < len(decUnits); f, _ = r.Float64() {
i++
r = r.Mul(r, den)
}
f, _ := r.Float64()
return fmt.Sprintf("%.3g %s", f, decUnits[i])
}

View File

@ -54,6 +54,8 @@ type BlockHeader struct {
BeaconEntries []BeaconEntry
WinPoStProof []abi.PoStProof
Parents []cid.Cid // 3
ParentWeight BigInt // 4

View File

@ -9,7 +9,7 @@ import (
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
"github.com/ipfs/go-cid"
cid "github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
xerrors "golang.org/x/xerrors"
)
@ -21,7 +21,7 @@ func (t *BlockHeader) MarshalCBOR(w io.Writer) error {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write([]byte{142}); err != nil {
if _, err := w.Write([]byte{143}); err != nil {
return err
}
@ -54,6 +54,20 @@ func (t *BlockHeader) MarshalCBOR(w io.Writer) error {
}
}
// t.WinPoStProof ([]abi.PoStProof) (slice)
if len(t.WinPoStProof) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.WinPoStProof was too long")
}
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.WinPoStProof)))); err != nil {
return err
}
for _, v := range t.WinPoStProof {
if err := v.MarshalCBOR(w); err != nil {
return err
}
}
// t.Parents ([]cid.Cid) (slice)
if len(t.Parents) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Parents was too long")
@ -138,7 +152,7 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error {
return fmt.Errorf("cbor input should be of type array")
}
if extra != 14 {
if extra != 15 {
return fmt.Errorf("cbor input had wrong number of fields")
}
@ -207,9 +221,11 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.BeaconEntries = make([]BeaconEntry, extra)
}
for i := 0; i < int(extra); i++ {
var v BeaconEntry
@ -220,6 +236,35 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error {
t.BeaconEntries[i] = v
}
// t.WinPoStProof ([]abi.PoStProof) (slice)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if extra > cbg.MaxLength {
return fmt.Errorf("t.WinPoStProof: array too large (%d)", extra)
}
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.WinPoStProof = make([]abi.PoStProof, extra)
}
for i := 0; i < int(extra); i++ {
var v abi.PoStProof
if err := v.UnmarshalCBOR(br); err != nil {
return err
}
t.WinPoStProof[i] = v
}
// t.Parents ([]cid.Cid) (slice)
maj, extra, err = cbg.CborReadHeader(br)
@ -234,9 +279,11 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.Parents = make([]cid.Cid, extra)
}
for i := 0; i < int(extra); i++ {
c, err := cbg.ReadCid(br)
@ -1141,9 +1188,11 @@ func (t *BlockMsg) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.BlsMessages = make([]cid.Cid, extra)
}
for i := 0; i < int(extra); i++ {
c, err := cbg.ReadCid(br)
@ -1167,9 +1216,11 @@ func (t *BlockMsg) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.SecpkMessages = make([]cid.Cid, extra)
}
for i := 0; i < int(extra); i++ {
c, err := cbg.ReadCid(br)
@ -1261,9 +1312,11 @@ func (t *ExpTipSet) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.Cids = make([]cid.Cid, extra)
}
for i := 0; i < int(extra); i++ {
c, err := cbg.ReadCid(br)
@ -1287,9 +1340,11 @@ func (t *ExpTipSet) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.Blocks = make([]*BlockHeader, extra)
}
for i := 0; i < int(extra); i++ {
var v BlockHeader

View File

@ -1,5 +1,6 @@
package validation
/*
import (
"context"
@ -171,3 +172,4 @@ func toLotusSignedMsg(msg *vtypes.SignedMessage) *types.SignedMessage {
Signature: msg.Signature,
}
}
*/

View File

@ -1,5 +1,6 @@
package validation
/*
import (
"context"
@ -45,3 +46,4 @@ func (f *Factories) NewValidationConfig() vstate.ValidationConfig {
checkState := true
return NewConfig(trackGas, checkExit, checkRet, checkState)
}
*/

View File

@ -1,5 +1,6 @@
package validation
/*
import (
"context"
@ -203,3 +204,4 @@ type contextStore struct {
func (s *contextStore) Context() context.Context {
return s.ctx
}
*/

View File

@ -37,7 +37,7 @@ type Pricelist interface {
OnHashing(dataSize int) int64
OnComputeUnsealedSectorCid(proofType abi.RegisteredProof, pieces []abi.PieceInfo) int64
OnVerifySeal(info abi.SealVerifyInfo) int64
OnVerifyPost(info abi.PoStVerifyInfo) int64
OnVerifyPost(info abi.WindowPoStVerifyInfo) int64
OnVerifyConsensusFault() int64
}
@ -120,7 +120,7 @@ func (ps pricedSyscalls) VerifySeal(vi abi.SealVerifyInfo) error {
}
// Verifies a proof of spacetime.
func (ps pricedSyscalls) VerifyPoSt(vi abi.PoStVerifyInfo) error {
func (ps pricedSyscalls) VerifyPoSt(vi abi.WindowPoStVerifyInfo) error {
ps.chargeGas(ps.pl.OnVerifyPost(vi))
return ps.under.VerifyPoSt(vi)
}
@ -135,7 +135,7 @@ func (ps pricedSyscalls) VerifyPoSt(vi abi.PoStVerifyInfo) error {
// the "parent grinding fault", in which case it must be the sibling of h1 (same parent tipset) and one of the
// blocks in the parent of h2 (i.e. h2's grandparent).
// Returns nil and an error if the headers don't prove a fault.
func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte, earliest abi.ChainEpoch) (*runtime.ConsensusFault, error) {
func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte) (*runtime.ConsensusFault, error) {
ps.chargeGas(ps.pl.OnVerifyConsensusFault())
return ps.under.VerifyConsensusFault(h1, h2, extra, earliest)
return ps.under.VerifyConsensusFault(h1, h2, extra)
}

View File

@ -153,7 +153,7 @@ func (pl *pricelistV0) OnVerifySeal(info abi.SealVerifyInfo) int64 {
}
// OnVerifyPost
func (pl *pricelistV0) OnVerifyPost(info abi.PoStVerifyInfo) int64 {
func (pl *pricelistV0) OnVerifyPost(info abi.WindowPoStVerifyInfo) int64 {
// TODO: this needs more cost tunning, check with @lotus
return pl.verifyPostBase
}

View File

@ -77,7 +77,7 @@ func (inv *invoker) Invoke(codeCid cid.Cid, rt runtime.Runtime, method abi.Metho
func (inv *invoker) Register(c cid.Cid, instance Invokee, state interface{}) {
code, err := inv.transform(instance)
if err != nil {
panic(err)
panic(xerrors.Errorf("%s: %w", string(c.Hash()), err))
}
inv.builtInCode[c] = code
inv.builtInState[c] = reflect.TypeOf(state)

View File

@ -11,6 +11,7 @@ import (
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
sainit "github.com/filecoin-project/specs-actors/actors/builtin/init"
sapower "github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/runtime"
vmr "github.com/filecoin-project/specs-actors/actors/runtime"
@ -23,6 +24,7 @@ import (
"go.opencensus.io/trace"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/types"
@ -52,6 +54,41 @@ type Runtime struct {
numActorsCreated uint64
}
func (rt *Runtime) TotalFilCircSupply() abi.TokenAmount {
total := types.FromFil(build.TotalFilecoin)
rew, err := rt.state.GetActor(builtin.RewardActorAddr)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get reward actor for computing total supply: %s", err)
}
burnt, err := rt.state.GetActor(builtin.BurntFundsActorAddr)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get reward actor for computing total supply: %s", err)
}
market, err := rt.state.GetActor(builtin.StorageMarketActorAddr)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get reward actor for computing total supply: %s", err)
}
power, err := rt.state.GetActor(builtin.StoragePowerActorAddr)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get reward actor for computing total supply: %s", err)
}
total = types.BigSub(total, rew.Balance)
total = types.BigSub(total, burnt.Balance)
total = types.BigSub(total, market.Balance)
var st sapower.State
if err := rt.cst.Get(rt.ctx, power.Head, &st); err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get storage power state: %s", err)
}
return types.BigSub(total, st.TotalPledgeCollateral)
}
func (rt *Runtime) ResolveAddress(addr address.Address) (ret address.Address, ok bool) {
r, err := rt.state.LookupID(addr)
if err != nil {
@ -199,7 +236,7 @@ func (rt *Runtime) CreateActor(codeId cid.Cid, address address.Address) {
}
}
func (rt *Runtime) DeleteActor() {
func (rt *Runtime) DeleteActor(addr address.Address) {
rt.ChargeGas(rt.Pricelist().OnDeleteActor())
act, err := rt.state.GetActor(rt.Message().Receiver())
if err != nil {

View File

@ -63,7 +63,7 @@ func (ss *syscallShim) HashBlake2b(data []byte) [32]byte {
// Checks validity of the submitted consensus fault with the two block headers needed to prove the fault
// and an optional extra one to check common ancestry (as needed).
// Note that the blocks are ordered: the method requires a.Epoch() <= b.Epoch().
func (ss *syscallShim) VerifyConsensusFault(a, b, extra []byte, epoch abi.ChainEpoch) (*runtime.ConsensusFault, error) {
func (ss *syscallShim) VerifyConsensusFault(a, b, extra []byte) (*runtime.ConsensusFault, error) {
// Note that block syntax is not validated. Any validly signed block will be accepted pursuant to the below conditions.
// Whether or not it could ever have been accepted in a chain is not checked/does not matter here.
// for that reason when checking block parent relationships, rather than instantiating a Tipset to do so
@ -190,8 +190,8 @@ func (ss *syscallShim) VerifyBlockSig(blk *types.BlockHeader) error {
return nil
}
func (ss *syscallShim) VerifyPoSt(proof abi.PoStVerifyInfo) error {
ok, err := ss.verifier.VerifyFallbackPost(ss.ctx, proof)
func (ss *syscallShim) VerifyPoSt(proof abi.WindowPoStVerifyInfo) error {
ok, err := ss.verifier.VerifyWindowPoSt(context.TODO(), proof)
if err != nil {
return err
}

View File

@ -1,5 +1,6 @@
package vm_test
/*
import (
"fmt"
"reflect"
@ -33,7 +34,7 @@ var TestSuiteSkipper TestSkipper
func init() {
// initialize the test skipper with tests being skipped
TestSuiteSkipper = TestSkipper{testSkips: []suites.TestCase{
/* tests to skip go here */
// tests to skip go here
}}
}
@ -66,3 +67,4 @@ func caseName(testCase suites.TestCase) string {
toks := strings.Split(fqName, ".")
return toks[len(toks)-1]
}
*/

View File

@ -18,6 +18,7 @@ import (
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/account"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/util/adt"
cid "github.com/ipfs/go-cid"
@ -421,6 +422,10 @@ var chainGetCmd = &cli.Command{
Name: "verbose",
Value: false,
},
&cli.StringFlag{
Name: "tipset",
Usage: "specify tipset for /pstate (pass comma separated array of cids)",
},
},
Description: `Get ipld node under a specified path:
@ -437,6 +442,18 @@ var chainGetCmd = &cli.Command{
- /ipfs/[cid]/@Hu:123 - get uvarint elem 123 from hamt
- /ipfs/[cid]/@Ha:t01 - get element under Addr(t01).Bytes
- /ipfs/[cid]/@A:10 - get 10th amt element
List of --as-type types:
- raw
- block
- message
- smessage, signedmessage
- actor
- amt
- hamt-epoch
- hamt-address
- cronevent
- account-state
`,
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
@ -449,11 +466,19 @@ var chainGetCmd = &cli.Command{
p := path.Clean(cctx.Args().First())
if strings.HasPrefix(p, "/pstate") {
p = p[len("/pstate"):]
head, err := api.ChainHead(ctx)
ts, err := LoadTipSet(ctx, cctx, api)
if err != nil {
return err
}
p = "/ipfs/" + head.ParentState().String() + p
if ts == nil {
ts, err = api.ChainHead(ctx)
if err != nil {
return err
}
}
p = "/ipfs/" + ts.ParentState().String() + p
if cctx.Bool("verbose") {
fmt.Println(p)
}
@ -555,7 +580,11 @@ func (ht *apiIpldStore) Put(ctx context.Context, v interface{}) (cid.Cid, error)
func handleAmt(ctx context.Context, api api.FullNode, r cid.Cid) error {
s := &apiIpldStore{ctx, api}
mp := adt.AsArray(s, r)
mp, err := adt.AsArray(s, r)
if err != nil {
return err
}
return mp.ForEach(nil, func(key int64) error {
fmt.Printf("%d\n", key)
return nil
@ -564,7 +593,11 @@ func handleAmt(ctx context.Context, api api.FullNode, r cid.Cid) error {
func handleHamtEpoch(ctx context.Context, api api.FullNode, r cid.Cid) error {
s := &apiIpldStore{ctx, api}
mp := adt.AsMap(s, r)
mp, err := adt.AsMap(s, r)
if err != nil {
return err
}
return mp.ForEach(nil, func(key string) error {
ik, err := adt.ParseIntKey(key)
if err != nil {
@ -578,7 +611,11 @@ func handleHamtEpoch(ctx context.Context, api api.FullNode, r cid.Cid) error {
func handleHamtAddress(ctx context.Context, api api.FullNode, r cid.Cid) error {
s := &apiIpldStore{ctx, api}
mp := adt.AsMap(s, r)
mp, err := adt.AsMap(s, r)
if err != nil {
return err
}
return mp.ForEach(nil, func(key string) error {
addr, err := address.NewFromBytes([]byte(key))
if err != nil {
@ -770,6 +807,12 @@ var slashConsensusFault = &cli.Command{
Name: "slash-consensus",
Usage: "Report consensus fault",
ArgsUsage: "[blockCid1 blockCid2]",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "miner",
Usage: "Miner address",
},
},
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
@ -813,18 +856,27 @@ var slashConsensusFault = &cli.Command{
return err
}
params, err := actors.SerializeParams(&power.ReportConsensusFaultParams{
params, err := actors.SerializeParams(&miner.ReportConsensusFaultParams{
BlockHeader1: bh1,
BlockHeader2: bh2,
})
if cctx.String("miner") == "" {
return xerrors.Errorf("--miner flag is required")
}
maddr, err := address.NewFromString(cctx.String("miner"))
if err != nil {
return err
}
msg := &types.Message{
To: builtin.StoragePowerActorAddr,
To: maddr,
From: def,
Value: types.NewInt(0),
GasPrice: types.NewInt(1),
GasLimit: 10000000,
Method: builtin.MethodsPower.ReportConsensusFault,
Method: builtin.MethodsMiner.ReportConsensusFault,
Params: params,
}

View File

@ -246,11 +246,11 @@ var clientDealCmd = &cli.Command{
}
proposal, err := api.ClientStartDeal(ctx, &lapi.StartDealParams{
Data: ref,
Wallet: a,
Miner: miner,
EpochPrice: types.BigInt(price),
BlocksDuration: uint64(dur),
Data: ref,
Wallet: a,
Miner: miner,
EpochPrice: types.BigInt(price),
MinBlocksDuration: uint64(dur),
})
if err != nil {
return err
@ -434,16 +434,16 @@ var clientQueryAskCmd = &cli.Command{
}
pid = p
} else {
p, err := api.StateMinerPeerID(ctx, maddr, types.EmptyTSK)
mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK)
if err != nil {
return xerrors.Errorf("failed to get peerID for miner: %w", err)
}
if p == peer.ID("SETME") {
if mi.PeerId == peer.ID("SETME") {
return fmt.Errorf("the miner hasn't initialized yet")
}
pid = p
pid = mi.PeerId
}
ask, err := api.ClientQueryAsk(ctx, pid, maddr)

View File

@ -115,12 +115,7 @@ var stateMinerInfo = &cli.Command{
},
}
func parseTipSetString(cctx *cli.Context) ([]cid.Cid, error) {
ts := cctx.String("tipset")
if ts == "" {
return nil, nil
}
func parseTipSetString(ts string) ([]cid.Cid, error) {
strs := strings.Split(ts, ",")
var cids []cid.Cid
@ -136,7 +131,21 @@ func parseTipSetString(cctx *cli.Context) ([]cid.Cid, error) {
}
func LoadTipSet(ctx context.Context, cctx *cli.Context, api api.FullNode) (*types.TipSet, error) {
cids, err := parseTipSetString(cctx)
tss := cctx.String("tipset")
if tss == "" {
return nil, nil
}
if tss[0] == '@' {
var h uint64
if _, err := fmt.Sscanf(tss, "@%d", &h); err != nil {
return nil, xerrors.Errorf("parsing height tipset ref: %w", err)
}
return api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(h), types.EmptyTSK)
}
cids, err := parseTipSetString(tss)
if err != nil {
return nil, err
}
@ -188,10 +197,10 @@ var statePowerCmd = &cli.Command{
tp := power.TotalPower
if cctx.Args().Present() {
mp := power.MinerPower
percI := types.BigDiv(types.BigMul(mp, types.NewInt(1000000)), tp)
fmt.Printf("%s(%s) / %s(%s) ~= %0.4f%%\n", mp.String(), types.SizeStr(mp), tp.String(), types.SizeStr(tp), float64(percI.Int64())/10000)
percI := types.BigDiv(types.BigMul(mp.QualityAdjPower, types.NewInt(1000000)), tp.QualityAdjPower)
fmt.Printf("%s(%s) / %s(%s) ~= %0.4f%%\n", mp.QualityAdjPower.String(), types.SizeStr(mp.QualityAdjPower), tp.QualityAdjPower.String(), types.SizeStr(tp.QualityAdjPower), float64(percI.Int64())/10000)
} else {
fmt.Printf("%s(%s)\n", tp.String(), types.SizeStr(tp))
fmt.Printf("%s(%s)\n", tp.QualityAdjPower.String(), types.SizeStr(tp.QualityAdjPower))
}
return nil
@ -225,7 +234,7 @@ var stateSectorsCmd = &cli.Command{
return err
}
sectors, err := api.StateMinerSectors(ctx, maddr, ts.Key())
sectors, err := api.StateMinerSectors(ctx, maddr, nil, true, ts.Key())
if err != nil {
return err
}
@ -594,12 +603,12 @@ var stateSectorSizeCmd = &cli.Command{
return err
}
ssize, err := api.StateMinerSectorSize(ctx, addr, ts.Key())
mi, err := api.StateMinerInfo(ctx, addr, ts.Key())
if err != nil {
return err
}
fmt.Printf("%d\n", ssize)
fmt.Printf("%d\n", mi.SectorSize)
return nil
},
}

View File

@ -39,10 +39,15 @@ type BenchResults struct {
SealingResults []SealingResult
PostGenerateCandidates time.Duration
PostEProofCold time.Duration
PostEProofHot time.Duration
VerifyEPostCold time.Duration
VerifyEPostHot time.Duration
PostWinningProofCold time.Duration
PostWinningProofHot time.Duration
VerifyWinningPostCold time.Duration
VerifyWinningPostHot time.Duration
PostWindowProofCold time.Duration
PostWindowProofHot time.Duration
VerifyWindowPostCold time.Duration
VerifyWindowPostHot time.Duration
}
type SealingResult struct {
@ -109,7 +114,7 @@ var sealBenchCmd = &cli.Command{
},
&cli.StringFlag{
Name: "benchmark-existing-sectorbuilder",
Usage: "pass a directory to run election-post timings on an existing sectorbuilder",
Usage: "pass a directory to run post timings on an existing sectorbuilder",
},
&cli.BoolFlag{
Name: "json-out",
@ -127,6 +132,10 @@ var sealBenchCmd = &cli.Command{
Name: "save-commit2-input",
Usage: "Save commit2 input to a file",
},
&cli.IntFlag{
Name: "num-sectors",
Value: 1,
},
},
Action: func(c *cli.Context) error {
if c.Bool("no-gpu") {
@ -174,14 +183,13 @@ var sealBenchCmd = &cli.Command{
}
sectorSize := abi.SectorSize(sectorSizeInt)
ppt, spt, err := ffiwrapper.ProofTypeFromSectorSize(sectorSize)
spt, err := ffiwrapper.SealProofTypeFromSectorSize(sectorSize)
if err != nil {
return err
}
cfg := &ffiwrapper.Config{
SealProofType: spt,
PoStProofType: ppt,
}
if robench == "" {
@ -214,7 +222,7 @@ var sealBenchCmd = &cli.Command{
var sealTimings []SealingResult
var sealedSectors []abi.SectorInfo
numSectors := abi.SectorNumber(1)
numSectors := abi.SectorNumber(c.Int("num-sectors"))
for i := abi.SectorNumber(1); i <= numSectors && robench == ""; i++ {
sid := abi.SectorID{
Miner: mid,
@ -394,47 +402,42 @@ var sealBenchCmd = &cli.Command{
}
if !c.Bool("skip-commit2") {
log.Info("generating election post candidates")
fcandidates, err := sb.GenerateEPostCandidates(context.TODO(), mid, sealedSectors, challenge[:], []abi.SectorNumber{})
log.Info("generating winning post candidates")
fcandidates, err := ffiwrapper.ProofVerifier.GenerateWinningPoStSectorChallenge(context.TODO(), spt, mid, challenge[:], uint64(len(sealedSectors)))
if err != nil {
return err
}
var candidates []abi.PoStCandidate
for _, c := range fcandidates {
c.Candidate.RegisteredProof = ppt
candidates = append(candidates, c.Candidate)
candidates := make([]abi.SectorInfo, len(fcandidates))
for i, fcandidate := range fcandidates {
candidates[i] = sealedSectors[fcandidate]
}
gencandidates := time.Now()
log.Info("computing election post snark (cold)")
proof1, err := sb.ComputeElectionPoSt(context.TODO(), mid, sealedSectors, challenge[:], candidates[:1])
log.Info("computing winning post snark (cold)")
proof1, err := sb.GenerateWinningPoSt(context.TODO(), mid, candidates, challenge[:])
if err != nil {
return err
}
epost1 := time.Now()
winnnigpost1 := time.Now()
log.Info("computing election post snark (hot)")
proof2, err := sb.ComputeElectionPoSt(context.TODO(), mid, sealedSectors, challenge[:], candidates[:1])
log.Info("computing winning post snark (hot)")
proof2, err := sb.GenerateWinningPoSt(context.TODO(), mid, candidates, challenge[:])
if err != nil {
return err
}
epost2 := time.Now()
winnningpost2 := time.Now()
ccount := ffiwrapper.ElectionPostChallengeCount(uint64(len(sealedSectors)), 0)
pvi1 := abi.PoStVerifyInfo{
Randomness: abi.PoStRandomness(challenge[:]),
Candidates: candidates[:1],
Proofs: proof1,
EligibleSectors: sealedSectors,
Prover: mid,
ChallengeCount: ccount,
pvi1 := abi.WinningPoStVerifyInfo{
Randomness: abi.PoStRandomness(challenge[:]),
Proofs: proof1,
ChallengedSectors: candidates,
Prover: mid,
}
ok, err := ffiwrapper.ProofVerifier.VerifyElectionPost(context.TODO(), pvi1)
ok, err := ffiwrapper.ProofVerifier.VerifyWinningPoSt(context.TODO(), pvi1)
if err != nil {
return err
}
@ -442,31 +445,82 @@ var sealBenchCmd = &cli.Command{
log.Error("post verification failed")
}
verifypost1 := time.Now()
verifyWinnnigPost1 := time.Now()
pvi2 := abi.PoStVerifyInfo{
Randomness: abi.PoStRandomness(challenge[:]),
Candidates: candidates[:1],
Proofs: proof2,
EligibleSectors: sealedSectors,
Prover: mid,
ChallengeCount: ccount,
pvi2 := abi.WinningPoStVerifyInfo{
Randomness: abi.PoStRandomness(challenge[:]),
Proofs: proof2,
ChallengedSectors: candidates,
Prover: mid,
}
ok, err = ffiwrapper.ProofVerifier.VerifyElectionPost(context.TODO(), pvi2)
ok, err = ffiwrapper.ProofVerifier.VerifyWinningPoSt(context.TODO(), pvi2)
if err != nil {
return err
}
if !ok {
log.Error("post verification failed")
}
verifypost2 := time.Now()
verifyWinningPost2 := time.Now()
log.Info("computing window post snark (cold)")
wproof1, err := sb.GenerateWindowPoSt(context.TODO(), mid, sealedSectors, challenge[:])
if err != nil {
return err
}
windowpost1 := time.Now()
log.Info("computing window post snark (hot)")
wproof2, err := sb.GenerateWindowPoSt(context.TODO(), mid, sealedSectors, challenge[:])
if err != nil {
return err
}
windowpost2 := time.Now()
wpvi1 := abi.WindowPoStVerifyInfo{
Randomness: challenge[:],
Proofs: wproof1,
ChallengedSectors: sealedSectors,
Prover: mid,
}
ok, err = ffiwrapper.ProofVerifier.VerifyWindowPoSt(context.TODO(), wpvi1)
if err != nil {
return err
}
if !ok {
log.Error("post verification failed")
}
verifyWindowpost1 := time.Now()
wpvi2 := abi.WindowPoStVerifyInfo{
Randomness: challenge[:],
Proofs: wproof2,
ChallengedSectors: sealedSectors,
Prover: mid,
}
ok, err = ffiwrapper.ProofVerifier.VerifyWindowPoSt(context.TODO(), wpvi2)
if err != nil {
return err
}
if !ok {
log.Error("post verification failed")
}
verifyWindowpost2 := time.Now()
bo.PostGenerateCandidates = gencandidates.Sub(beforePost)
bo.PostEProofCold = epost1.Sub(gencandidates)
bo.PostEProofHot = epost2.Sub(epost1)
bo.VerifyEPostCold = verifypost1.Sub(epost2)
bo.VerifyEPostHot = verifypost2.Sub(verifypost1)
bo.PostWinningProofCold = winnnigpost1.Sub(gencandidates)
bo.PostWinningProofHot = winnningpost2.Sub(winnnigpost1)
bo.VerifyWinningPostCold = verifyWinnnigPost1.Sub(winnningpost2)
bo.VerifyWinningPostHot = verifyWinningPost2.Sub(verifyWinnnigPost1)
bo.PostWindowProofCold = windowpost1.Sub(verifyWinningPost2)
bo.PostWindowProofHot = windowpost2.Sub(windowpost1)
bo.VerifyWindowPostCold = verifyWindowpost1.Sub(windowpost2)
bo.VerifyWindowPostHot = verifyWindowpost2.Sub(verifyWindowpost1)
}
if c.Bool("json-out") {
@ -477,7 +531,7 @@ var sealBenchCmd = &cli.Command{
fmt.Println(string(data))
} else {
fmt.Printf("----\nresults (v24) (%d)\n", sectorSize)
fmt.Printf("----\nresults (v25) (%d)\n", sectorSize)
if robench == "" {
fmt.Printf("seal: addPiece: %s (%s)\n", bo.SealingResults[0].AddPiece, bps(bo.SectorSize, bo.SealingResults[0].AddPiece)) // TODO: average across multiple sealings
fmt.Printf("seal: preCommit phase 1: %s (%s)\n", bo.SealingResults[0].PreCommit1, bps(bo.SectorSize, bo.SealingResults[0].PreCommit1))
@ -488,13 +542,19 @@ var sealBenchCmd = &cli.Command{
if !c.Bool("skip-unseal") {
fmt.Printf("unseal: %s (%s)\n", bo.SealingResults[0].Unseal, bps(bo.SectorSize, bo.SealingResults[0].Unseal))
}
fmt.Println("")
}
if !c.Bool("skip-commit2") {
fmt.Printf("generate candidates: %s (%s)\n", bo.PostGenerateCandidates, bps(bo.SectorSize*abi.SectorSize(len(bo.SealingResults)), bo.PostGenerateCandidates))
fmt.Printf("compute epost proof (cold): %s\n", bo.PostEProofCold)
fmt.Printf("compute epost proof (hot): %s\n", bo.PostEProofHot)
fmt.Printf("verify epost proof (cold): %s\n", bo.VerifyEPostCold)
fmt.Printf("verify epost proof (hot): %s\n", bo.VerifyEPostHot)
fmt.Printf("compute winnnig post proof (cold): %s\n", bo.PostWinningProofCold)
fmt.Printf("compute winnnig post proof (hot): %s\n", bo.PostWinningProofHot)
fmt.Printf("verify winnnig post proof (cold): %s\n", bo.VerifyWinningPostCold)
fmt.Printf("verify winnnig post proof (hot): %s\n\n", bo.VerifyWinningPostHot)
fmt.Printf("compute window post proof (cold): %s\n", bo.PostWindowProofCold)
fmt.Printf("compute window post proof (hot): %s\n", bo.PostWindowProofHot)
fmt.Printf("verify window post proof (cold): %s\n", bo.VerifyWindowPostCold)
fmt.Printf("verify window post proof (hot): %s\n", bo.VerifyWindowPostHot)
}
}
return nil
@ -542,14 +602,13 @@ var proveCmd = &cli.Command{
return err
}
ppt, spt, err := ffiwrapper.ProofTypeFromSectorSize(abi.SectorSize(c2in.SectorSize))
spt, err := ffiwrapper.SealProofTypeFromSectorSize(abi.SectorSize(c2in.SectorSize))
if err != nil {
return err
}
cfg := &ffiwrapper.Config{
SealProofType: spt,
PoStProofType: ppt,
}
sb, err := ffiwrapper.New(nil, cfg)

View File

@ -276,7 +276,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
log.Error(err)
// Not sure why this would fail, but its probably worth continuing
}
info.power = pow.MinerPower
info.power = pow.MinerPower.QualityAdjPower
sszs, err := api.StateMinerSectorCount(ctx, k.addr, types.EmptyTSK)
if err != nil {

View File

@ -3,7 +3,6 @@ package main
import (
"context"
"encoding/json"
"github.com/filecoin-project/sector-storage/ffiwrapper"
"io/ioutil"
"net"
"net/http"
@ -17,6 +16,7 @@ import (
"gopkg.in/urfave/cli.v2"
paramfetch "github.com/filecoin-project/go-paramfetch"
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/api/apistruct"
@ -242,7 +242,7 @@ var runCmd = &cli.Command{
}
// Setup remote sector store
_, spt, err := ffiwrapper.ProofTypeFromSectorSize(ssize)
spt, err := ffiwrapper.SealProofTypeFromSectorSize(ssize)
if err != nil {
return xerrors.Errorf("getting proof type: %w", err)
}

View File

@ -120,7 +120,7 @@ var preSealCmd = &cli.Command{
}
sectorSize := abi.SectorSize(sectorSizeInt)
rp, _, err := ffiwrapper.ProofTypeFromSectorSize(sectorSize)
rp, err := ffiwrapper.SealProofTypeFromSectorSize(sectorSize)
if err != nil {
return err
}

View File

@ -13,6 +13,8 @@ import (
"github.com/google/uuid"
logging "github.com/ipfs/go-log/v2"
ic "github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/peer"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
@ -32,11 +34,6 @@ import (
var log = logging.Logger("preseal")
func PreSeal(maddr address.Address, pt abi.RegisteredProof, offset abi.SectorNumber, sectors int, sbroot string, preimage []byte, key *types.KeyInfo) (*genesis.Miner, *types.KeyInfo, error) {
ppt, err := pt.RegisteredPoStProof()
if err != nil {
return nil, nil, err
}
spt, err := pt.RegisteredSealProof()
if err != nil {
return nil, nil, err
@ -49,7 +46,6 @@ func PreSeal(maddr address.Address, pt abi.RegisteredProof, offset abi.SectorNum
cfg := &ffiwrapper.Config{
SealProofType: spt,
PoStProofType: ppt,
}
if err := os.MkdirAll(sbroot, 0775); err != nil {
@ -123,6 +119,20 @@ func PreSeal(maddr address.Address, pt abi.RegisteredProof, offset abi.SectorNum
}
}
var pid peer.ID
{
log.Warn("PeerID not specified, generating dummy")
p, _, err := ic.GenerateEd25519Key(rand.Reader)
if err != nil {
return nil, nil, err
}
pid, err = peer.IDFromPrivateKey(p)
if err != nil {
return nil, nil, err
}
}
miner := &genesis.Miner{
Owner: minerAddr.Address,
Worker: minerAddr.Address,
@ -130,6 +140,7 @@ func PreSeal(maddr address.Address, pt abi.RegisteredProof, offset abi.SectorNum
PowerBalance: big.Zero(),
SectorSize: ssize,
Sectors: sealedSectors,
PeerId: pid,
}
if err := createDeals(miner, minerAddr, maddr, ssize); err != nil {

View File

@ -6,10 +6,7 @@ import (
"gopkg.in/urfave/cli.v2"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
sealing "github.com/filecoin-project/storage-fsm"
@ -41,21 +38,22 @@ var infoCmd = &cli.Command{
fmt.Printf("Miner: %s\n", maddr)
// Sector size
sizeByte, err := api.StateMinerSectorSize(ctx, maddr, types.EmptyTSK)
mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
fmt.Printf("Sector Size: %s\n", types.SizeStr(types.NewInt(uint64(sizeByte))))
fmt.Printf("Sector Size: %s\n", types.SizeStr(types.NewInt(uint64(mi.SectorSize))))
pow, err := api.StateMinerPower(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
percI := types.BigDiv(types.BigMul(pow.MinerPower, types.NewInt(1000000)), pow.TotalPower)
fmt.Printf("Power: %s / %s (%0.4f%%)\n", types.SizeStr(pow.MinerPower), types.SizeStr(pow.TotalPower), float64(percI.Int64())/10000)
rpercI := types.BigDiv(types.BigMul(pow.MinerPower.RawBytePower, types.NewInt(1000000)), pow.TotalPower.RawBytePower)
qpercI := types.BigDiv(types.BigMul(pow.MinerPower.QualityAdjPower, types.NewInt(1000000)), pow.TotalPower.QualityAdjPower)
fmt.Printf("Byte Power: %s / %s (%0.4f%%)\n", types.SizeStr(pow.MinerPower.RawBytePower), types.SizeStr(pow.TotalPower.RawBytePower), float64(rpercI.Int64())/10000)
fmt.Printf("Actual Power: %s / %s (%0.4f%%)\n", types.DecStr(pow.MinerPower.QualityAdjPower), types.DecStr(pow.TotalPower.QualityAdjPower), float64(qpercI.Int64())/10000)
secCounts, err := api.StateMinerSectorCount(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
@ -65,13 +63,13 @@ var infoCmd = &cli.Command{
return err
}
fmt.Printf("\tCommitted: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Sset), types.NewInt(uint64(sizeByte)))))
fmt.Printf("\tCommitted: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Sset), types.NewInt(uint64(mi.SectorSize)))))
if len(faults) == 0 {
fmt.Printf("\tProving: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Pset), types.NewInt(uint64(sizeByte)))))
fmt.Printf("\tProving: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Pset), types.NewInt(uint64(mi.SectorSize)))))
} else {
fmt.Printf("\tProving: %s (%s Faulty, %.2f%%)\n",
types.SizeStr(types.BigMul(types.NewInt(secCounts.Pset-uint64(len(faults))), types.NewInt(uint64(sizeByte)))),
types.SizeStr(types.BigMul(types.NewInt(uint64(len(faults))), types.NewInt(uint64(sizeByte)))),
types.SizeStr(types.BigMul(types.NewInt(secCounts.Pset-uint64(len(faults))), types.NewInt(uint64(mi.SectorSize)))),
types.SizeStr(types.BigMul(types.NewInt(uint64(len(faults))), types.NewInt(uint64(mi.SectorSize)))),
float64(10000*uint64(len(faults))/secCounts.Pset)/100.)
}
@ -91,7 +89,7 @@ var infoCmd = &cli.Command{
fmt.Printf("\tCommit: %d\n", wstat.CommitWait)
fmt.Printf("\tUnseal: %d\n", wstat.UnsealWait)*/
ps, err := api.StateMinerPostState(ctx, maddr, types.EmptyTSK)
/*ps, err := api.StateMinerPostState(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
@ -113,7 +111,7 @@ var infoCmd = &cli.Command{
fmt.Printf("\tConsecutive Failures: %d\n", ps.NumConsecutiveFailures)
} else {
fmt.Printf("Proving Period: Not Proving\n")
}
}*/
sinfo, err := sectorsInfo(ctx, nodeApi)
if err != nil {

View File

@ -420,7 +420,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode,
return err
}
ppt, spt, err := ffiwrapper.ProofTypeFromSectorSize(ssize)
spt, err := ffiwrapper.SealProofTypeFromSectorSize(ssize)
if err != nil {
return err
}
@ -437,12 +437,14 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode,
smgr, err := sectorstorage.New(ctx, lr, stores.NewIndex(), &ffiwrapper.Config{
SealProofType: spt,
PoStProofType: ppt,
}, sectorstorage.SealerConfig{true, true, true}, nil, sa)
if err != nil {
return err
}
epp := storage.NewElectionPoStProver(smgr, dtypes.MinerID(mid))
epp, err := storage.NewWinningPoStProver(api, smgr, ffiwrapper.ProofVerifier, dtypes.MinerID(mid))
if err != nil {
return err
}
gen, err := api.ChainGetGenesis(ctx)
if err != nil {
@ -549,7 +551,7 @@ func makeHostKey(lr repo.LockedRepo) (crypto.PrivKey, error) {
}
func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address.Address, peerid peer.ID, gasPrice types.BigInt) error {
waddr, err := api.StateMinerWorker(ctx, addr, types.EmptyTSK)
mi, err := api.StateMinerInfo(ctx, addr, types.EmptyTSK)
if err != nil {
return xerrors.Errorf("getWorkerAddr returned bad address: %w", err)
}
@ -561,7 +563,7 @@ func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address.
msg := &types.Message{
To: addr,
From: waddr,
From: mi.Worker,
Method: builtin.MethodsMiner.ChangePeerID,
Params: enc,
Value: types.NewInt(0),

View File

@ -31,6 +31,7 @@ func main() {
storageCmd,
setPriceCmd,
workersCmd,
provingCmd,
}
jaeger := tracing.SetupJaegerTracing("lotus")
defer func() {

View File

@ -0,0 +1,137 @@
package main
import (
"fmt"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"golang.org/x/xerrors"
"gopkg.in/urfave/cli.v2"
"time"
)
var provingCmd = &cli.Command{
Name: "proving",
Subcommands: []*cli.Command{
provingInfoCmd,
provingDeadlinesCmd,
},
}
var provingInfoCmd = &cli.Command{
Name: "info",
Action: func(cctx *cli.Context) error {
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return err
}
defer closer()
api, acloser, err := lcli.GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer acloser()
ctx := lcli.ReqContext(cctx)
maddr, err := nodeApi.ActorAddress(ctx)
if err != nil {
return xerrors.Errorf("getting actor address: %w", err)
}
head, err := api.ChainHead(ctx)
if err != nil {
return xerrors.Errorf("getting chain head: %w", err)
}
mi, err := api.StateMinerInfo(ctx, maddr, head.Key())
if err != nil {
return xerrors.Errorf("getting miner info: %w", err)
}
cd, _ := miner.ComputeProvingPeriodDeadline(mi.ProvingPeriodBoundary, head.Height())
deadlines, err := api.StateMinerDeadlines(ctx, maddr, head.Key())
if err != nil {
return xerrors.Errorf("getting miner deadlines: %w", err)
}
curDeadlineSectors, err := deadlines.Due[cd.Index].Count()
if err != nil {
return xerrors.Errorf("counting deadline sectors: %w", err)
}
fmt.Printf("Current Epoch: %d\n", cd.CurrentEpoch)
fmt.Printf("Chain Period: %d\n", cd.CurrentEpoch/miner.WPoStProvingPeriod)
fmt.Printf("Chain Period Start: %s\n", epochTime(cd.CurrentEpoch, (cd.CurrentEpoch/miner.WPoStProvingPeriod)*miner.WPoStProvingPeriod))
fmt.Printf("Chain Period End: %s\n\n", epochTime(cd.CurrentEpoch, (cd.CurrentEpoch/miner.WPoStProvingPeriod+1)*miner.WPoStProvingPeriod))
fmt.Printf("Proving Period Boundary: %d\n", mi.ProvingPeriodBoundary)
fmt.Printf("Proving Period Start: %s\n", epochTime(cd.CurrentEpoch, cd.PeriodStart))
fmt.Printf("Next Period Start: %s\n\n", epochTime(cd.CurrentEpoch, cd.PeriodStart+miner.WPoStProvingPeriod))
fmt.Printf("Deadline Index: %d\n", cd.Index)
fmt.Printf("Deadline Sectors: %d\n", curDeadlineSectors)
fmt.Printf("Deadline Open: %s\n", epochTime(cd.CurrentEpoch, cd.Open))
fmt.Printf("Deadline Close: %s\n", epochTime(cd.CurrentEpoch, cd.Close))
fmt.Printf("Deadline Challenge: %s\n", epochTime(cd.CurrentEpoch, cd.Challenge))
fmt.Printf("Deadline FaultCutoff: %s\n", epochTime(cd.CurrentEpoch, cd.FaultCutoff))
return nil
},
}
func epochTime(curr, e abi.ChainEpoch) string {
switch {
case curr > e:
return fmt.Sprintf("%d (%s ago)", e, time.Second*time.Duration(build.BlockDelay*(curr-e)))
case curr == e:
return fmt.Sprintf("%d (now)", e)
case curr < e:
return fmt.Sprintf("%d (in %s)", e, time.Second*time.Duration(build.BlockDelay*(e-curr)))
}
panic("math broke")
}
var provingDeadlinesCmd = &cli.Command{
Name: "deadlines",
Action: func(cctx *cli.Context) error {
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return err
}
defer closer()
api, acloser, err := lcli.GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer acloser()
ctx := lcli.ReqContext(cctx)
maddr, err := nodeApi.ActorAddress(ctx)
if err != nil {
return xerrors.Errorf("getting actor address: %w", err)
}
deadlines, err := api.StateMinerDeadlines(ctx, maddr, types.EmptyTSK)
if err != nil {
return xerrors.Errorf("getting deadlines: %w", err)
}
for i, field := range deadlines.Due {
c, err := field.Count()
if err != nil {
return err
}
fmt.Printf("%d: %d sectors\n", i, c)
}
return nil
},
}

View File

@ -15,47 +15,10 @@ import (
var rewardsCmd = &cli.Command{
Name: "rewards",
Subcommands: []*cli.Command{
rewardsListCmd,
rewardsRedeemCmd,
},
}
var rewardsListCmd = &cli.Command{
Name: "list",
Usage: "Print unclaimed block rewards earned",
Action: func(cctx *cli.Context) error {
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return err
}
defer closer()
api, acloser, err := lcli.GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer acloser()
ctx := lcli.ReqContext(cctx)
maddr, err := nodeApi.ActorAddress(ctx)
if err != nil {
return err
}
rewards, err := api.StateListRewards(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
for _, r := range rewards {
fmt.Printf("%d\t%d\t%s\n", r.StartEpoch, r.EndEpoch, types.FIL(r.Value))
}
return nil
},
}
var rewardsRedeemCmd = &cli.Command{
Name: "redeem",
Usage: "Redeem block rewards",
@ -79,7 +42,7 @@ var rewardsRedeemCmd = &cli.Command{
return err
}
worker, err := api.StateMinerWorker(ctx, maddr, types.EmptyTSK)
mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
@ -89,19 +52,21 @@ var rewardsRedeemCmd = &cli.Command{
return err
}
workerNonce, err := api.MpoolGetNonce(ctx, worker)
workerNonce, err := api.MpoolGetNonce(ctx, mi.Worker)
if err != nil {
return err
}
smsg, err := api.WalletSignMessage(ctx, worker, &types.Message{
panic("todo correct method; call miner actor")
smsg, err := api.WalletSignMessage(ctx, mi.Worker, &types.Message{
To: builtin.RewardActorAddr,
From: worker,
From: mi.Worker,
Nonce: workerNonce,
Value: types.NewInt(0),
GasPrice: types.NewInt(1),
GasLimit: 100000,
Method: builtin.MethodsReward.WithdrawReward,
Method: 0,
Params: params,
})
if err != nil {

View File

@ -142,7 +142,7 @@ var sectorsListCmd = &cli.Command{
provingIDs[info.ID] = struct{}{}
}
sset, err := fullApi.StateMinerSectors(ctx, maddr, types.EmptyTSK)
sset, err := fullApi.StateMinerSectors(ctx, maddr, nil, true, types.EmptyTSK)
if err != nil {
return err
}

View File

@ -123,13 +123,14 @@ var DaemonCmd = &cli.Command{
return xerrors.Errorf("fetching proof parameters: %w", err)
}
genBytes := build.MaybeGenesis()
var genBytes []byte
if cctx.String("genesis") != "" {
genBytes, err = ioutil.ReadFile(cctx.String("genesis"))
if err != nil {
return xerrors.Errorf("reading genesis: %w", err)
}
} else {
genBytes = build.MaybeGenesis()
}
chainfile := cctx.String("import-chain")

View File

@ -48,7 +48,7 @@ func init() {
addr, _ := address.NewIDAddress(1000)
var ticket *types.Ticket
{
w, err := api.StateMinerWorker(ctx, addr, head.Key())
mi, err := api.StateMinerInfo(ctx, addr, head.Key())
if err != nil {
return xerrors.Errorf("StateMinerWorker: %w", err)
}
@ -58,7 +58,7 @@ func init() {
return xerrors.Errorf("failed to get randomness: %w", err)
}
t, err := gen.ComputeVRF(ctx, api.WalletSign, w, rand)
t, err := gen.ComputeVRF(ctx, api.WalletSign, mi.Worker, rand)
if err != nil {
return xerrors.Errorf("compute vrf failed: %w", err)
}
@ -72,7 +72,7 @@ func init() {
uts := head.MinTimestamp() + uint64(build.BlockDelay)
nheight := head.Height() + 1
blk, err := api.MinerCreateBlock(ctx, &lapi.BlockTemplate{
addr, head.Key(), ticket, nil, nil, msgs, nheight, uts,
addr, head.Key(), ticket, nil, nil, msgs, nheight, uts, nil,
})
if err != nil {
return xerrors.Errorf("creating block: %w", err)

View File

@ -1,9 +1,9 @@
# Setup Local Devnet
Build the Lotus Binaries in debug mode, This enables the use of 1024 byte sectors.
Build the Lotus Binaries in debug mode, This enables the use of 2048 byte sectors.
```sh
make debug
make 2k
```
Download the 2048 byte parameters:

2
extern/filecoin-ffi vendored

@ -1 +1 @@
Subproject commit e899cc1dd0720e0a4d25b0e751b84e3733cbedc5
Subproject commit 870251cd04c54e7a3a08b714f3e71a9edec28445

View File

@ -28,7 +28,7 @@ type PreSeal struct {
type Miner struct {
Owner address.Address
Worker address.Address
PeerId peer.ID `json:",omitempty"`
PeerId peer.ID
MarketBalance abi.TokenAmount
PowerBalance abi.TokenAmount

13
go.mod
View File

@ -12,7 +12,6 @@ require (
github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f // indirect
github.com/docker/go-units v0.4.0
github.com/drand/drand v0.7.2
github.com/filecoin-project/chain-validation v0.0.6-0.20200331143132-15970e639ac2
github.com/filecoin-project/filecoin-ffi v0.0.0-20200326153646-e899cc1dd072
github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be
github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e
@ -20,14 +19,14 @@ require (
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03
github.com/filecoin-project/go-data-transfer v0.0.0-20200408061858-82c58b423ca6
github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5
github.com/filecoin-project/go-fil-markets v0.0.0-20200408062434-d92f329a6428
github.com/filecoin-project/go-fil-markets v0.0.0-20200413201123-731e6ca89984
github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200218225740-47c639bab663
github.com/filecoin-project/go-statestore v0.1.0
github.com/filecoin-project/sector-storage v0.0.0-20200406195014-a6d093838576
github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504
github.com/filecoin-project/specs-storage v0.0.0-20200317225704-7420bc655c38
github.com/filecoin-project/storage-fsm v0.0.0-20200408153957-1c356922353f
github.com/filecoin-project/sector-storage v0.0.0-20200417225459-e75536581a08
github.com/filecoin-project/specs-actors v0.0.0-20200421160610-702cd4b229c4
github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102
github.com/filecoin-project/storage-fsm v0.0.0-20200420183220-1515cffb5d13
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
github.com/google/uuid v1.1.1
github.com/gorilla/mux v1.7.4
@ -94,7 +93,7 @@ require (
github.com/opentracing/opentracing-go v1.1.0
github.com/stretchr/testify v1.4.0
github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba
github.com/whyrusleeping/cbor-gen v0.0.0-20200402171437-3d27c146c105
github.com/whyrusleeping/cbor-gen v0.0.0-20200414195334-429a0b5e922e
github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7
github.com/whyrusleeping/pubsub v0.0.0-20131020042734-02de8aa2db3d
go.opencensus.io v0.22.3

52
go.sum
View File

@ -10,6 +10,7 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
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/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/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
github.com/GeertJohan/go.rice v1.0.0 h1:KkI6O9uMaQU3VEKaj01ulavtF7o1fWT7+pk/4voiMLQ=
github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
@ -25,6 +26,7 @@ github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrU
github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo=
github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw=
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@ -75,7 +77,6 @@ github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0=
github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis=
github.com/daaku/go.zipexe v1.0.0 h1:VSOgZtH418pH9L16hC/JrgSNJbbAL26pj7lmD1+CGdY=
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
github.com/dave/jennifer v1.4.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -121,8 +122,6 @@ 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/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E=
github.com/filecoin-project/chain-validation v0.0.3/go.mod h1:NCEGFjcWRjb8akWFSOXvU6n2efkWIqAeOKU6o5WBGQw=
github.com/filecoin-project/chain-validation v0.0.6-0.20200331143132-15970e639ac2 h1:kRaCruOKzFy5mE5lwPecKD5aztzmazMQDot38NgT6E0=
github.com/filecoin-project/chain-validation v0.0.6-0.20200331143132-15970e639ac2/go.mod h1:mXiAviXMZ2WVGmWNtjGr0JPMpNCNsPU774DawKZCzzM=
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-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0=
github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be h1:TooKBwR/g8jG0hZ3lqe9S5sy2vTUcLOZLlz3M5wGn2E=
@ -132,8 +131,11 @@ github.com/filecoin-project/go-amt-ipld v0.0.0-20191205011053-79efc22d6cdc/go.mo
github.com/filecoin-project/go-amt-ipld/v2 v2.0.0/go.mod h1:PAZ5tvSfMfWE327osqFXKm7cBpCpBk2Nh0qKsJUmjjk=
github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e h1:IOoff6yAZSJ5zHCPY2jzGNwQYQU6ygsRVe/cSnJrY+o=
github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg=
github.com/filecoin-project/go-bitfield v0.0.0-20200309034705-8c7ac40bd550 h1:aockulLU8Qjkdj4FQz53WQpNosAIYk8DxRediRLkE5c=
github.com/filecoin-project/go-bitfield v0.0.0-20200309034705-8c7ac40bd550/go.mod h1:iodsLxOFZnqKtjj2zkgqzoGNrv6vUqj69AT/J8DKXEw=
github.com/filecoin-project/go-bitfield v0.0.0-20200415174627-536a2ee8529d h1:ufxUB1ssNdti7SgDNnHXZ863F8g04/yx+EW4ygvGcSU=
github.com/filecoin-project/go-bitfield v0.0.0-20200415174627-536a2ee8529d/go.mod h1:iodsLxOFZnqKtjj2zkgqzoGNrv6vUqj69AT/J8DKXEw=
github.com/filecoin-project/go-bitfield v0.0.0-20200416002808-b3ee67ec9060 h1:/3qjGMn6ukXgZJHsIbuwGL7ipla8DOV3uHZDBJkBYfU=
github.com/filecoin-project/go-bitfield v0.0.0-20200416002808-b3ee67ec9060/go.mod h1:iodsLxOFZnqKtjj2zkgqzoGNrv6vUqj69AT/J8DKXEw=
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-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus=
@ -141,11 +143,12 @@ github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod
github.com/filecoin-project/go-data-transfer v0.0.0-20191219005021-4accf56bd2ce/go.mod h1:b14UWxhxVCAjrQUYvVGrQRRsjAh79wXYejw9RbUcAww=
github.com/filecoin-project/go-data-transfer v0.0.0-20200408061858-82c58b423ca6 h1:CIQ7RlW7I3E+JBxfKiK0ZWO9HPSBqlI5aeA/sdwyVTc=
github.com/filecoin-project/go-data-transfer v0.0.0-20200408061858-82c58b423ca6/go.mod h1:7b5/sG9Jj33aWqft8XsH8yIdxZBACqS5tx9hv4uj2Ck=
github.com/filecoin-project/go-data-transfer v0.0.0-20200408061858-82c58b423ca6/go.mod h1:7b5/sG9Jj33aWqft8XsH8yIdxZBACqS5tx9hv4uj2Ck=
github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 h1:yvQJCW9mmi9zy+51xA01Ea2X7/dL7r8eKDPuGUjRmbo=
github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5/go.mod h1:JbkIgFF/Z9BDlvrJO1FuKkaWsH673/UdFaiVS6uIHlA=
github.com/filecoin-project/go-fil-markets v0.0.0-20200114015428-74d100f305f8/go.mod h1:c8NTjvFVy1Ud02mmGDjOiMeawY2t6ALfrrdvAB01FQc=
github.com/filecoin-project/go-fil-markets v0.0.0-20200408062434-d92f329a6428 h1:y8P10ZwfmsKMVHrqcU1L8Bgj2q42O6LzaySI+XaogXE=
github.com/filecoin-project/go-fil-markets v0.0.0-20200408062434-d92f329a6428/go.mod h1:NmuTIqaivdyUzmvHOUCsTDGEtNjOZQwC1cgW3W/02m4=
github.com/filecoin-project/go-fil-markets v0.0.0-20200413201123-731e6ca89984 h1:QY5jgd5T4txUEC2k9BPqWRlhDUTdFx5f1z/StOlh92g=
github.com/filecoin-project/go-fil-markets v0.0.0-20200413201123-731e6ca89984/go.mod h1:vcX3y5FVyuclIZgogPG1uIvJxHLSBU54B1ANJ88uMNk=
github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:92PET+sx1Hb4W/8CgFwGuxaKbttwY+UNspYZTvXY0vs=
github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6/go.mod h1:0HgYnrkeSU4lu1p+LEOeDpFsNBssa0OGGriWdA4hvaE=
github.com/filecoin-project/go-paramfetch v0.0.0-20200102181131-b20d579f2878/go.mod h1:40kI2Gv16mwcRsHptI3OAV4nlOEU7wVDc4RgMylNFjU=
@ -154,25 +157,26 @@ github.com/filecoin-project/go-paramfetch v0.0.2-0.20200218225740-47c639bab663 h
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200218225740-47c639bab663/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc=
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.20200203173614-42d67726bb62/go.mod h1:jNGVCDihkMFnraYVLH1xl4ceZQVxx/u4dOORrTKeRi0=
github.com/filecoin-project/go-sectorbuilder v0.0.2-0.20200326160829-51775363aa18 h1:k0lIN4y3JM8aFd02+1h2MdST3cCAFBO4vaZ7PARXyzo=
github.com/filecoin-project/go-sectorbuilder v0.0.2-0.20200326160829-51775363aa18/go.mod h1:xAd/X905Ncgj8kkHsP2pmQUf6MQT2qJTDcOEfkwCjYc=
github.com/filecoin-project/go-statemachine v0.0.0-20200226041606-2074af6d51d9 h1:k9qVR9ItcziSB2rxtlkN/MDWNlbsI6yzec+zjUatLW0=
github.com/filecoin-project/go-statemachine v0.0.0-20200226041606-2074af6d51d9/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIiWBRilQjQ+5IiwdQ=
github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI=
github.com/filecoin-project/lotus v0.2.10/go.mod h1:om5PQA9ZT0lf16qI7Fz/ZGLn4LDCMqPC8ntZA9uncRE=
github.com/filecoin-project/sector-storage v0.0.0-20200406195014-a6d093838576 h1:MzBqbddYp/vdFOC3WNu3tSWfLFwHUP8Orcx2CxjRPyo=
github.com/filecoin-project/sector-storage v0.0.0-20200406195014-a6d093838576/go.mod h1:yT100eeKHGO9xU3rfkeM2/8NcBktxe2nBkDT4WmD1lA=
github.com/filecoin-project/sector-storage v0.0.0-20200411000242-61616264b16d h1:vD83B+dP/YCTVvsnk76auROLjurEOl/VLseRKbmoFYI=
github.com/filecoin-project/sector-storage v0.0.0-20200411000242-61616264b16d/go.mod h1:/yueJueMh0Yc+0G1adS0lhnedcSnjY86EjKsA20+DVY=
github.com/filecoin-project/sector-storage v0.0.0-20200417225459-e75536581a08 h1:X1eeuc6OR0+sDxOMI7p98oWevT5NhB7SZoHMM9+l1Ck=
github.com/filecoin-project/sector-storage v0.0.0-20200417225459-e75536581a08/go.mod h1:m5wM3aqbgDcg+mT2EW0Urv7t/sCok9TmvQqtb7Sf738=
github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA=
github.com/filecoin-project/specs-actors v0.0.0-20200226200336-94c9b92b2775/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
github.com/filecoin-project/specs-actors v0.0.0-20200302223606-0eaf97b10aaf/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
github.com/filecoin-project/specs-actors v0.0.0-20200324235424-aef9b20a9fb1/go.mod h1:5WngRgTN5Eo4+0SjCBqLzEr2l6Mj45DrP2606gBhqI0=
github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504 h1:mwuAaqxKThl70+7FkGdFKVLdwaQZQ8XmscKdhSBBtnc=
github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA=
github.com/filecoin-project/specs-storage v0.0.0-20200317225704-7420bc655c38 h1:ky+rfX3bG1TjOBLn14V674q+iwZpalyKzZxGRNzA11I=
github.com/filecoin-project/specs-storage v0.0.0-20200317225704-7420bc655c38/go.mod h1:dUmzHS7izOD6HW3/JpzFrjxnptxbsHXBlO8puK2UzBk=
github.com/filecoin-project/storage-fsm v0.0.0-20200408153957-1c356922353f h1:ocVYJgS622P5p/LOOPzb875M+wlJHe6in2DcoGcd9J8=
github.com/filecoin-project/storage-fsm v0.0.0-20200408153957-1c356922353f/go.mod h1:9nHIzwfHk6cNXaaNnUJNWNRRytp5QYMBOA+NtcTUKJM=
github.com/filecoin-project/specs-actors v0.0.0-20200415170224-54c7b2a42e71/go.mod h1:M2HNOBpYbgXl/V4GmJFOsY7lQNuAmOtrCQMa6Yfpfrc=
github.com/filecoin-project/specs-actors v0.0.0-20200421160610-702cd4b229c4 h1:RUj2hy/fN+l7VRT0uy034vDA/DEG7rd3+D/wVeVqSoM=
github.com/filecoin-project/specs-actors v0.0.0-20200421160610-702cd4b229c4/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y=
github.com/filecoin-project/specs-storage v0.0.0-20200410185809-9fbaaa08f275 h1:6OTcpsTQBQM0f/A67oEi4E4YtYd6fzkMqbU8cPIWMMs=
github.com/filecoin-project/specs-storage v0.0.0-20200410185809-9fbaaa08f275/go.mod h1:xJ1/xl9+8zZeSSSFmDC3Wr6uusCTxyYPI0VeNVSFmPE=
github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 h1:T3f/zkuvgtgqcXrb0NO3BicuveGOxxUAMPa/Yif2kuE=
github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102/go.mod h1:xJ1/xl9+8zZeSSSFmDC3Wr6uusCTxyYPI0VeNVSFmPE=
github.com/filecoin-project/storage-fsm v0.0.0-20200420183220-1515cffb5d13 h1:Zv0ovLy4nOgMk9bCKOp+Wo6NMSSeuNgPNk0N3aLf5Wg=
github.com/filecoin-project/storage-fsm v0.0.0-20200420183220-1515cffb5d13/go.mod h1:mJtW2Y2qIbZErBoc1MmgVKMFiNHWZ2qqeH6Hl3fHFWU=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 h1:EzDjxMg43q1tA2c0MV3tNbaontnHLplHyFF6M5KiVP0=
@ -279,6 +283,7 @@ github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7s
github.com/ipfs/go-blockservice v0.1.3-0.20190908200855-f22eea50656c/go.mod h1:t+411r7psEUhLueM8C7aPA7cxCclv4O3VsUVxt9kz2I=
github.com/ipfs/go-blockservice v0.1.3 h1:9XgsPMwwWJSC9uVr2pMDsW2qFTBSkxpGMhmna8mIjPM=
github.com/ipfs/go-blockservice v0.1.3/go.mod h1:OTZhFpkgY48kNzbgyvcexW9cHrpjBYIjSR0KoDOFOLU=
github.com/ipfs/go-blockservice v0.1.3/go.mod h1:OTZhFpkgY48kNzbgyvcexW9cHrpjBYIjSR0KoDOFOLU=
github.com/ipfs/go-car v0.0.3-0.20191203022317-23b0a85fd1b1/go.mod h1:rmd887mJxQRDfndfDEY3Liyx8gQVyfFFRSHdsnDSAlk=
github.com/ipfs/go-car v0.0.3-0.20200121013634-f188c0e24291/go.mod h1:AG6sBpd2PWMccpAG7XLFBBQ/4rfBEtzUNeO2GSMesYk=
github.com/ipfs/go-car v0.0.3-0.20200304012825-b6769248bfef h1:Zn2PZSkX8Go+SZpQmjVKNrkcgbNuIxUC/3MOQRDTIVw=
@ -325,7 +330,6 @@ github.com/ipfs/go-hamt-ipld v0.0.15-0.20200204200533-99b8553ef242/go.mod h1:kq3
github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08=
github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw=
github.com/ipfs/go-ipfs-blockstore v0.1.1/go.mod h1:8gZOgIN5e+Xdg2YSGdwTTRbguSVjYyosIDRQCY8E9QM=
github.com/ipfs/go-ipfs-blockstore v0.1.3/go.mod h1:iNWVBoSQ7eMcaGo8+L3pKZABGTdWcqj1/hpoUu5bDps=
github.com/ipfs/go-ipfs-blockstore v0.1.4 h1:2SGI6U1B44aODevza8Rde3+dY30Pb+lbcObe1LETxOQ=
github.com/ipfs/go-ipfs-blockstore v0.1.4/go.mod h1:Jxm3XMVjh6R17WvxFEiyKBLUGr86HgIYJW/D/MwqeYQ=
github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ=
@ -352,6 +356,7 @@ github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqt
github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY=
github.com/ipfs/go-ipfs-pq v0.0.2 h1:e1vOOW6MuOwG2lqxcLA+wEn93i/9laCY8sXAw76jFOY=
github.com/ipfs/go-ipfs-pq v0.0.2/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY=
github.com/ipfs/go-ipfs-pq v0.0.2/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY=
github.com/ipfs/go-ipfs-routing v0.0.1/go.mod h1:k76lf20iKFxQTjcJokbPM9iBXVXVZhcOwc360N4nuKs=
github.com/ipfs/go-ipfs-routing v0.1.0 h1:gAJTT1cEeeLj6/DlLX6t+NxD9fQe2ymTO6qWRDI/HQQ=
github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY=
@ -389,6 +394,7 @@ github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3
github.com/ipfs/go-peertaskqueue v0.1.1/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U=
github.com/ipfs/go-peertaskqueue v0.2.0 h1:2cSr7exUGKYyDeUyQ7P/nHPs9P7Ht/B+ROrpN1EJOjc=
github.com/ipfs/go-peertaskqueue v0.2.0/go.mod h1:5/eNrBEbtSKWCG+kQK8K8fGNixoYUnr+P7jivavs9lY=
github.com/ipfs/go-peertaskqueue v0.2.0/go.mod h1:5/eNrBEbtSKWCG+kQK8K8fGNixoYUnr+P7jivavs9lY=
github.com/ipfs/go-todocounter v0.0.1 h1:kITWA5ZcQZfrUnDNkRn04Xzh0YFaDFXsoO2A81Eb6Lw=
github.com/ipfs/go-todocounter v0.0.1/go.mod h1:l5aErvQc8qKE2r7NDMjmq5UNAvuZy0rC8BHOplkWvZ4=
github.com/ipfs/go-unixfs v0.2.2-0.20190827150610-868af2e9e5cb h1:tmWYgjltxwM7PDmFJgWgLuy5qx24csUvRoIiO+F/zQ4=
@ -422,6 +428,7 @@ github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsj
github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10=
github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4=
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak=
@ -738,6 +745,7 @@ github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c h1:5bFTChQxSKNwy
github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c/go.mod h1:7qN3Y0BvzRUf4LofcoJplQL10lsFDb4PYlePTVwrP28=
github.com/nikkolasg/slog v0.0.0-20170921200349-3c8d441d7a1e h1:07zdEcJ4Fble5uWsqKpjW19699kQWRLXP+RZh1a6ZRg=
github.com/nikkolasg/slog v0.0.0-20170921200349-3c8d441d7a1e/go.mod h1:79GLCU4P87rYvYYACbNwVyc1WmRvkwQbYnybpCmRXzg=
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg=
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@ -841,7 +849,9 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4=
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
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/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830 h1:8kxMKmKzXXL4Ru1nyhvdms/JjWt+3YLpvRb/bAjO/y0=
@ -858,9 +868,11 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20191216205031-b047b6acb3c0/go.mod h1:x
github.com/whyrusleeping/cbor-gen v0.0.0-20200121162646-b63bacf5eaf8/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY=
github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
github.com/whyrusleeping/cbor-gen v0.0.0-20200206220010-03c9665e2a66/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
github.com/whyrusleeping/cbor-gen v0.0.0-20200321164527-9340289d0ca7/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
github.com/whyrusleeping/cbor-gen v0.0.0-20200402171437-3d27c146c105 h1:Sh6UG5dW5xW8Ek2CtRGq4ipdEvvx9hOyBJjEGyTYDl0=
github.com/whyrusleeping/cbor-gen v0.0.0-20200402171437-3d27c146c105/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
github.com/whyrusleeping/cbor-gen v0.0.0-20200402171437-3d27c146c105/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
github.com/whyrusleeping/cbor-gen v0.0.0-20200414195334-429a0b5e922e h1:JY8o/ebUUrCYetWmjRCNghxC59cOEaili83rxPRQCLw=
github.com/whyrusleeping/cbor-gen v0.0.0-20200414195334-429a0b5e922e/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E=
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8=
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k=

View File

@ -35,8 +35,8 @@ func (rpn *retrievalProviderNode) GetMinerWorkerAddress(ctx context.Context, min
return address.Undef, err
}
addr, err := rpn.full.StateMinerWorker(ctx, miner, tsk)
return addr, err
mi, err := rpn.full.StateMinerInfo(ctx, miner, tsk)
return mi.Worker, err
}
func (rpn *retrievalProviderNode) UnsealSector(ctx context.Context, sectorID uint64, offset uint64, length uint64) (io.ReadCloser, error) {

View File

@ -72,21 +72,12 @@ func (n *ClientNodeAdapter) ListStorageProviders(ctx context.Context, encodedTs
var out []*storagemarket.StorageProviderInfo
for _, addr := range addresses {
workerAddr, err := n.StateMinerWorker(ctx, addr, tsk)
mi, err := n.StateMinerInfo(ctx, addr, tsk)
if err != nil {
return nil, err
}
sectorSize, err := n.StateMinerSectorSize(ctx, addr, tsk)
if err != nil {
return nil, err
}
peerID, err := n.StateMinerPeerID(ctx, addr, tsk)
if err != nil {
return nil, err
}
storageProviderInfo := utils.NewStorageProviderInfo(addr, workerAddr, sectorSize, peerID)
storageProviderInfo := utils.NewStorageProviderInfo(addr, mi.Worker, mi.SectorSize, mi.PeerId)
out = append(out, &storageProviderInfo)
}
@ -94,7 +85,12 @@ func (n *ClientNodeAdapter) ListStorageProviders(ctx context.Context, encodedTs
}
func (n *ClientNodeAdapter) VerifySignature(ctx context.Context, sig crypto.Signature, addr address.Address, input []byte, encodedTs shared.TipSetToken) (bool, error) {
err := sigs.Verify(&sig, addr, input)
addr, err := n.StateAccountKey(ctx, addr, types.EmptyTSK)
if err != nil {
return false, err
}
err = sigs.Verify(&sig, addr, input)
return err == nil, err
}
@ -176,12 +172,17 @@ func (c *ClientNodeAdapter) ValidatePublishedDeal(ctx context.Context, deal stor
return 0, xerrors.Errorf("getting deal pubsish message: %w", err)
}
pw, err := stmgr.GetMinerWorker(ctx, c.sm, nil, deal.Proposal.Provider)
mi, err := stmgr.StateMinerInfo(ctx, c.sm, c.cs.GetHeaviestTipSet(), deal.Proposal.Provider)
if err != nil {
return 0, xerrors.Errorf("getting miner worker failed: %w", err)
}
if pubmsg.From != pw {
fromid, err := c.StateLookupID(ctx, pubmsg.From, types.EmptyTSK)
if err != nil {
return 0, xerrors.Errorf("failed to resolve from msg ID addr: %w", err)
}
if fromid != mi.Worker {
return 0, xerrors.Errorf("deal wasn't published by storage provider: from=%s, provider=%s", pubmsg.From, deal.Proposal.Provider)
}
@ -341,6 +342,11 @@ func (n *ClientNodeAdapter) SignProposal(ctx context.Context, signer address.Add
return nil, err
}
signer, err = n.StateAccountKey(ctx, signer, types.EmptyTSK)
if err != nil {
return nil, err
}
sig, err := n.Wallet.Sign(ctx, signer, buf)
if err != nil {
return nil, err
@ -363,7 +369,7 @@ func (n *ClientNodeAdapter) ValidateAskSignature(ctx context.Context, ask *stora
return false, err
}
w, err := n.StateMinerWorker(ctx, ask.Ask.Miner, tsk)
mi, err := n.StateMinerInfo(ctx, ask.Ask.Miner, tsk)
if err != nil {
return false, xerrors.Errorf("failed to get worker for miner in ask", err)
}
@ -373,7 +379,7 @@ func (n *ClientNodeAdapter) ValidateAskSignature(ctx context.Context, ask *stora
return false, xerrors.Errorf("failed to re-serialize ask")
}
err = sigs.Verify(ask.Signature, w, sigb)
err = sigs.Verify(ask.Signature, mi.Worker, sigb)
return err == nil, err
}

View File

@ -56,7 +56,7 @@ func NewProviderNodeAdapter(dag dtypes.StagingDAG, secb *sectorblocks.SectorBloc
func (n *ProviderNodeAdapter) PublishDeals(ctx context.Context, deal storagemarket.MinerDeal) (abi.DealID, cid.Cid, error) {
log.Info("publishing deal")
worker, err := n.StateMinerWorker(ctx, deal.Proposal.Provider, types.EmptyTSK)
mi, err := n.StateMinerInfo(ctx, deal.Proposal.Provider, types.EmptyTSK)
if err != nil {
return 0, cid.Undef, err
}
@ -72,7 +72,7 @@ func (n *ProviderNodeAdapter) PublishDeals(ctx context.Context, deal storagemark
// TODO: We may want this to happen after fetching data
smsg, err := n.MpoolPushMessage(ctx, &types.Message{
To: builtin.StorageMarketActorAddr,
From: worker,
From: mi.Worker,
Value: types.NewInt(0),
GasPrice: types.NewInt(0),
GasLimit: 1000000,
@ -118,7 +118,12 @@ func (n *ProviderNodeAdapter) OnDealComplete(ctx context.Context, deal storagema
}
func (n *ProviderNodeAdapter) VerifySignature(ctx context.Context, sig crypto.Signature, addr address.Address, input []byte, encodedTs shared.TipSetToken) (bool, error) {
err := sigs.Verify(&sig, addr, input)
addr, err := n.StateAccountKey(ctx, addr, types.EmptyTSK)
if err != nil {
return false, err
}
err = sigs.Verify(&sig, addr, input)
return err == nil, err
}
@ -150,10 +155,19 @@ func (n *ProviderNodeAdapter) GetMinerWorkerAddress(ctx context.Context, miner a
return address.Undef, err
}
return n.StateMinerWorker(ctx, miner, tsk)
mi, err := n.StateMinerInfo(ctx, miner, tsk)
if err != nil {
return address.Address{}, err
}
return mi.Worker, nil
}
func (n *ProviderNodeAdapter) SignBytes(ctx context.Context, signer address.Address, b []byte) (*crypto.Signature, error) {
signer, err := n.StateAccountKey(ctx, signer, types.EmptyTSK)
if err != nil {
return nil, err
}
localSignature, err := n.WalletSign(ctx, signer, b)
if err != nil {
return nil, err

View File

@ -27,7 +27,7 @@ var log = logging.Logger("miner")
type waitFunc func(ctx context.Context, baseTime uint64) error
func NewMiner(api api.FullNode, epp gen.ElectionPoStProver, beacon beacon.RandomBeacon) *Miner {
func NewMiner(api api.FullNode, epp gen.WinningPoStProver, beacon beacon.RandomBeacon) *Miner {
arc, err := lru.NewARC(10000)
if err != nil {
panic(err)
@ -51,7 +51,7 @@ func NewMiner(api api.FullNode, epp gen.ElectionPoStProver, beacon beacon.Random
type Miner struct {
api api.FullNode
epp gen.ElectionPoStProver
epp gen.WinningPoStProver
beacon beacon.RandomBeacon
lk sync.Mutex
@ -287,21 +287,22 @@ func (m *Miner) hasPower(ctx context.Context, addr address.Address, ts *types.Ti
return false, err
}
return !power.MinerPower.Equals(types.NewInt(0)), nil
return !power.MinerPower.QualityAdjPower.Equals(types.NewInt(0)), nil
}
func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningBase) (*types.BlockMsg, error) {
log.Debugw("attempting to mine a block", "tipset", types.LogCids(base.ts.Cids()))
start := time.Now()
mbi, err := m.api.MinerGetBaseInfo(ctx, addr, base.ts.Key())
round := base.ts.Height() + base.nullRounds + 1
mbi, err := m.api.MinerGetBaseInfo(ctx, addr, round, base.ts.Key())
if err != nil {
return nil, xerrors.Errorf("failed to get mining base info: %w", err)
}
beaconPrev := mbi.PrevBeaconEntry
round := base.ts.Height() + base.nullRounds + 1
bvals, err := beacon.BeaconEntriesForBlock(ctx, m.beacon, round, beaconPrev)
if err != nil {
return nil, xerrors.Errorf("get beacon entries failed: %w", err)
@ -339,6 +340,19 @@ func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningB
return nil, nil
}
// TODO: use the right dst, also NB: not using any 'entropy' in this call because nicola really didnt want it
rand, err := m.api.ChainGetRandomness(ctx, base.ts.Key(), crypto.DomainSeparationTag_ElectionPoStChallengeSeed, base.ts.Height()+base.nullRounds, nil)
if err != nil {
return nil, xerrors.Errorf("failed to get randomness for winning post: %w", err)
}
prand := abi.PoStRandomness(rand)
postProof, err := m.epp.ComputeProof(ctx, mbi.Sectors, prand)
if err != nil {
return nil, xerrors.Errorf("failed to compute winning post proof: %w", err)
}
// get pending messages early,
pending, err := m.api.MpoolPending(context.TODO(), base.ts.Key())
if err != nil {
@ -346,7 +360,7 @@ func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningB
}
// TODO: winning post proof
b, err := m.createBlock(base, addr, ticket, winner, bvals, pending)
b, err := m.createBlock(base, addr, ticket, winner, bvals, postProof, pending)
if err != nil {
return nil, xerrors.Errorf("failed to create block: %w", err)
}
@ -361,7 +375,11 @@ func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningB
}
func (m *Miner) computeTicket(ctx context.Context, addr address.Address, brand *types.BeaconEntry, base *MiningBase) (*types.Ticket, error) {
w, err := m.api.StateMinerWorker(ctx, addr, types.EmptyTSK)
mi, err := m.api.StateMinerInfo(ctx, addr, types.EmptyTSK)
if err != nil {
return nil, err
}
worker, err := m.api.StateAccountKey(ctx, mi.Worker, types.EmptyTSK)
if err != nil {
return nil, err
}
@ -376,7 +394,7 @@ func (m *Miner) computeTicket(ctx context.Context, addr address.Address, brand *
return nil, err
}
vrfOut, err := gen.ComputeVRF(ctx, m.api.WalletSign, w, input)
vrfOut, err := gen.ComputeVRF(ctx, m.api.WalletSign, worker, input)
if err != nil {
return nil, err
}
@ -387,7 +405,7 @@ func (m *Miner) computeTicket(ctx context.Context, addr address.Address, brand *
}
func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *types.Ticket,
eproof *types.ElectionProof, bvals []types.BeaconEntry, pending []*types.SignedMessage) (*types.BlockMsg, error) {
eproof *types.ElectionProof, bvals []types.BeaconEntry, wpostProof []abi.PoStProof, pending []*types.SignedMessage) (*types.BlockMsg, error) {
msgs, err := SelectMessages(context.TODO(), m.api.StateGetActor, base.ts, pending)
if err != nil {
return nil, xerrors.Errorf("message filtering failed: %w", err)
@ -404,14 +422,15 @@ func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *type
// why even return this? that api call could just submit it for us
return m.api.MinerCreateBlock(context.TODO(), &api.BlockTemplate{
Miner: addr,
Parents: base.ts.Key(),
Ticket: ticket,
Eproof: eproof,
BeaconValues: bvals,
Messages: msgs,
Epoch: nheight,
Timestamp: uts,
Miner: addr,
Parents: base.ts.Key(),
Ticket: ticket,
Eproof: eproof,
BeaconValues: bvals,
Messages: msgs,
Epoch: nheight,
Timestamp: uts,
WinningPoStProof: wpostProof,
})
}

View File

@ -10,8 +10,8 @@ import (
lru "github.com/hashicorp/golang-lru"
)
func NewTestMiner(nextCh <-chan struct{}, addr address.Address) func(api.FullNode, gen.ElectionPoStProver, beacon.RandomBeacon) *Miner {
return func(api api.FullNode, epp gen.ElectionPoStProver, b beacon.RandomBeacon) *Miner {
func NewTestMiner(nextCh <-chan struct{}, addr address.Address) func(api.FullNode, gen.WinningPoStProver, beacon.RandomBeacon) *Miner {
return func(api api.FullNode, epp gen.WinningPoStProver, b beacon.RandomBeacon) *Miner {
arc, err := lru.NewARC(10000)
if err != nil {
panic(err)

View File

@ -299,7 +299,7 @@ func Online() Option {
Override(HandleRetrievalKey, modules.HandleRetrieval),
Override(GetParamsKey, modules.GetParams),
Override(HandleDealsKey, modules.HandleDeals),
Override(new(gen.ElectionPoStProver), storage.NewElectionPoStProver),
Override(new(gen.WinningPoStProver), storage.NewWinningPoStProver),
Override(new(*miner.Miner), modules.SetupBlockProducer),
),
)

View File

@ -7,7 +7,7 @@ import (
"io"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/ipfs/go-cid"
cid "github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
xerrors "golang.org/x/xerrors"
)
@ -91,9 +91,11 @@ func (t *HelloMessage) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.HeaviestTipSet = make([]cid.Cid, extra)
}
for i := 0; i < int(extra); i++ {
c, err := cbg.ReadCid(br)

View File

@ -11,9 +11,6 @@ import (
"io"
"os"
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"golang.org/x/xerrors"
"github.com/ipfs/go-blockservice"
@ -34,7 +31,10 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
"github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
@ -66,6 +66,14 @@ type API struct {
Filestore dtypes.ClientFilestore `optional:"true"`
}
func calcDealExpiration(minDuration uint64, mi miner.MinerInfo, ts *types.TipSet) abi.ChainEpoch {
// Make sure we give some time for the miner to seal
minExp := ts.Height() + dealStartBuffer + abi.ChainEpoch(minDuration)
// Align on miners ProvingPeriodBoundary
return minExp + miner.WPoStProvingPeriod - (minExp % miner.WPoStProvingPeriod) + mi.ProvingPeriodBoundary - 1
}
func (a *API) ClientStartDeal(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) {
exist, err := a.WalletHas(ctx, params.Wallet)
if err != nil {
@ -75,31 +83,21 @@ func (a *API) ClientStartDeal(ctx context.Context, params *api.StartDealParams)
return nil, xerrors.Errorf("provided address doesn't exist in wallet")
}
pid, err := a.StateMinerPeerID(ctx, params.Miner, types.EmptyTSK)
mi, err := a.StateMinerInfo(ctx, params.Miner, types.EmptyTSK)
if err != nil {
return nil, xerrors.Errorf("failed getting peer ID: %w", err)
}
mw, err := a.StateMinerWorker(ctx, params.Miner, types.EmptyTSK)
if err != nil {
return nil, xerrors.Errorf("failed getting miner worker: %w", err)
}
ssize, err := a.StateMinerSectorSize(ctx, params.Miner, types.EmptyTSK)
if err != nil {
return nil, xerrors.Errorf("failed checking miners sector size: %w", err)
}
if uint64(params.Data.PieceSize.Padded()) > uint64(ssize) {
return nil, xerrors.New("data doesn't fit in a sector")
}
rt, _, err := ffiwrapper.ProofTypeFromSectorSize(ssize)
rt, err := ffiwrapper.SealProofTypeFromSectorSize(mi.SectorSize)
if err != nil {
return nil, xerrors.Errorf("bad sector size: %w", err)
}
providerInfo := utils.NewStorageProviderInfo(params.Miner, mw, ssize, pid)
if uint64(params.Data.PieceSize.Padded()) > uint64(mi.SectorSize) {
return nil, xerrors.New("data doesn't fit in a sector")
}
providerInfo := utils.NewStorageProviderInfo(params.Miner, mi.Worker, mi.SectorSize, mi.PeerId)
ts, err := a.ChainHead(ctx)
if err != nil {
return nil, xerrors.Errorf("failed getting chain height: %w", err)
@ -111,7 +109,7 @@ func (a *API) ClientStartDeal(ctx context.Context, params *api.StartDealParams)
&providerInfo,
params.Data,
ts.Height()+dealStartBuffer,
ts.Height()+dealStartBuffer+abi.ChainEpoch(params.BlocksDuration),
calcDealExpiration(params.MinBlocksDuration, mi, ts),
params.EpochPrice,
big.Zero(),
rt,
@ -294,12 +292,12 @@ func (a *API) ClientListImports(ctx context.Context) ([]api.Import, error) {
func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref api.FileRef) error {
if order.MinerPeerID == "" {
pid, err := a.StateMinerPeerID(ctx, order.Miner, types.EmptyTSK)
mi, err := a.StateMinerInfo(ctx, order.Miner, types.EmptyTSK)
if err != nil {
return err
}
order.MinerPeerID = pid
order.MinerPeerID = mi.PeerId
}
if order.Size == 0 {
@ -373,12 +371,12 @@ func (a *API) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Addre
}
func (a *API) ClientCalcCommP(ctx context.Context, inpath string, miner address.Address) (*api.CommPRet, error) {
ssize, err := a.StateMinerSectorSize(ctx, miner, types.EmptyTSK)
mi, err := a.StateMinerInfo(ctx, miner, types.EmptyTSK)
if err != nil {
return nil, xerrors.Errorf("failed checking miners sector size: %w", err)
}
rt, _, err := ffiwrapper.ProofTypeFromSectorSize(ssize)
rt, err := ffiwrapper.SealProofTypeFromSectorSize(mi.SectorSize)
if err != nil {
return nil, xerrors.Errorf("bad sector size: %w", err)
}

View File

@ -91,8 +91,12 @@ func (a *MpoolAPI) MpoolPushMessage(ctx context.Context, msg *types.Message) (*t
return nil, xerrors.Errorf("MpoolPushMessage expects message nonce to be 0, was %d", msg.Nonce)
}
return a.Mpool.PushWithNonce(msg.From, func(nonce uint64) (*types.SignedMessage, error) {
return a.Mpool.PushWithNonce(ctx, msg.From, func(from address.Address, nonce uint64) (*types.SignedMessage, error) {
msg.Nonce = nonce
if msg.From.Protocol() == address.ID {
log.Warnf("Push from ID address (%s), adjusting to %s", msg.From, from)
msg.From = from
}
b, err := a.WalletBalance(ctx, msg.From)
if err != nil {
@ -103,7 +107,7 @@ func (a *MpoolAPI) MpoolPushMessage(ctx context.Context, msg *types.Message) (*t
return nil, xerrors.Errorf("mpool push: not enough funds: %s < %s", b, msg.Value)
}
return a.WalletSignMessage(ctx, msg.From, msg)
return a.WalletSignMessage(ctx, from, msg)
})
}

View File

@ -9,23 +9,12 @@ import (
cid "github.com/ipfs/go-cid"
"github.com/ipfs/go-hamt-ipld"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/libp2p/go-libp2p-core/peer"
cbg "github.com/whyrusleeping/cbor-gen"
"go.uber.org/fx"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-amt-ipld/v2"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/market"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/state"
@ -35,6 +24,14 @@ import (
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/lotus/lib/bufbstore"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/market"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
)
type StateAPI struct {
@ -44,20 +41,21 @@ type StateAPI struct {
// API attached to the state API. It probably should live somewhere better
Wallet *wallet.Wallet
StateManager *stmgr.StateManager
Chain *store.ChainStore
ProofVerifier ffiwrapper.Verifier
StateManager *stmgr.StateManager
Chain *store.ChainStore
}
func (a *StateAPI) StateNetworkName(ctx context.Context) (dtypes.NetworkName, error) {
return stmgr.GetNetworkName(ctx, a.StateManager, a.Chain.GetHeaviestTipSet().ParentState())
}
func (a *StateAPI) StateMinerSectors(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
func (a *StateAPI) StateMinerSectors(ctx context.Context, addr address.Address, filter *abi.BitField, filterOut bool, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
return stmgr.GetMinerSectorSet(ctx, a.StateManager, ts, addr)
return stmgr.GetMinerSectorSet(ctx, a.StateManager, ts, addr, filter, filterOut)
}
func (a *StateAPI) StateMinerProvingSet(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
@ -65,65 +63,30 @@ func (a *StateAPI) StateMinerProvingSet(ctx context.Context, addr address.Addres
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
return stmgr.GetMinerProvingSet(ctx, a.StateManager, ts, addr)
var mas miner.State
_, err = a.StateManager.LoadActorState(ctx, addr, &mas, ts)
if err != nil {
return nil, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err)
}
return stmgr.GetProvingSetRaw(ctx, a.StateManager, mas)
}
func (a *StateAPI) StateMinerPower(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (*api.MinerPower, error) {
func (a *StateAPI) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
if err != nil {
return miner.MinerInfo{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
return stmgr.StateMinerInfo(ctx, a.StateManager, ts, actor)
}
func (a *StateAPI) StateMinerDeadlines(ctx context.Context, m address.Address, tsk types.TipSetKey) (*miner.Deadlines, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
mpow, tpow, err := stmgr.GetPower(ctx, a.StateManager, ts, maddr)
if err != nil {
return nil, err
}
if maddr != address.Undef {
slashed, err := stmgr.GetMinerSlashed(ctx, a.StateManager, ts, maddr)
if err != nil {
return nil, err
}
if slashed {
mpow = types.NewInt(0)
}
}
return &api.MinerPower{
MinerPower: mpow,
TotalPower: tpow,
}, nil
}
func (a *StateAPI) StateMinerWorker(ctx context.Context, m address.Address, tsk types.TipSetKey) (address.Address, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
if err != nil {
return address.Undef, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
return stmgr.GetMinerWorker(ctx, a.StateManager, ts, m)
}
func (a *StateAPI) StateMinerPeerID(ctx context.Context, m address.Address, tsk types.TipSetKey) (peer.ID, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
if err != nil {
return "", xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
return stmgr.GetMinerPeerID(ctx, a.StateManager, ts, m)
}
func (a *StateAPI) StateMinerPostState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*miner.PoStState, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
return stmgr.GetMinerPostState(ctx, a.StateManager, ts, actor)
}
func (a *StateAPI) StateMinerSectorSize(ctx context.Context, actor address.Address, tsk types.TipSetKey) (abi.SectorSize, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
if err != nil {
return 0, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
return stmgr.GetMinerSectorSize(ctx, a.StateManager, ts, actor)
return stmgr.GetMinerDeadlines(ctx, a.StateManager, ts, m)
}
func (a *StateAPI) StateMinerFaults(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]abi.SectorNumber, error) {
@ -134,6 +97,23 @@ func (a *StateAPI) StateMinerFaults(ctx context.Context, addr address.Address, t
return stmgr.GetMinerFaults(ctx, a.StateManager, ts, addr)
}
func (a *StateAPI) StateMinerPower(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*api.MinerPower, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
m, net, err := stmgr.GetPower(ctx, a.StateManager, ts, addr)
if err != nil {
return nil, err
}
return &api.MinerPower{
MinerPower: m,
TotalPower: net,
}, nil
}
func (a *StateAPI) StatePledgeCollateral(ctx context.Context, tsk types.TipSetKey) (types.BigInt, error) {
/*ts, err := a.Chain.GetTipSetFromKey(tsk)
if err != nil {
@ -238,6 +218,15 @@ func (a *StateAPI) StateLookupID(ctx context.Context, addr address.Address, tsk
return state.LookupID(addr)
}
func (a *StateAPI) StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
if err != nil {
return address.Undef, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
return a.StateManager.ResolveToKeyAddress(ctx, addr, ts)
}
func (a *StateAPI) StateReadState(ctx context.Context, act *types.Actor, tsk types.TipSetKey) (*api.ActorState, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
if err != nil {
@ -265,8 +254,8 @@ func (a *StateAPI) StateReadState(ctx context.Context, act *types.Actor, tsk typ
}
// This is on StateAPI because miner.Miner requires this, and MinerAPI requires miner.Miner
func (a *StateAPI) MinerGetBaseInfo(ctx context.Context, maddr address.Address, tsk types.TipSetKey) (*api.MiningBaseInfo, error) {
return stmgr.MinerGetBaseInfo(ctx, a.StateManager, tsk, maddr)
func (a *StateAPI) MinerGetBaseInfo(ctx context.Context, maddr address.Address, epoch abi.ChainEpoch, tsk types.TipSetKey) (*api.MiningBaseInfo, error) {
return stmgr.MinerGetBaseInfo(ctx, a.StateManager, tsk, epoch, maddr, a.ProofVerifier)
}
func (a *StateAPI) MinerCreateBlock(ctx context.Context, bt *api.BlockTemplate) (*types.BlockMsg, error) {
@ -615,40 +604,3 @@ func (a *StateAPI) MsigGetAvailableBalance(ctx context.Context, addr address.Add
minBalance = types.BigMul(minBalance, types.NewInt(uint64(offset)))
return types.BigSub(act.Balance, minBalance), nil
}
func (a *StateAPI) StateListRewards(ctx context.Context, miner address.Address, tsk types.TipSetKey) ([]reward.Reward, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
if err != nil {
return nil, err
}
var st reward.State
if _, err := a.StateManager.LoadActorState(ctx, builtin.RewardActorAddr, &st, ts); err != nil {
return nil, xerrors.Errorf("failed to load reward actor state: %w", err)
}
as := store.ActorStore(ctx, a.Chain.Blockstore())
rmap := adt.AsMultimap(as, st.RewardMap)
rewards, found, err := rmap.Get(adt.AddrKey(miner))
if err != nil {
return nil, xerrors.Errorf("failed to get rewards set for miner: %w", err)
}
if !found {
return nil, xerrors.Errorf("no rewards found for miner")
}
var out []reward.Reward
var r reward.Reward
err = rewards.ForEach(&r, func(i int64) error {
or := r
out = append(out, or)
return nil
})
if err != nil {
return nil, xerrors.Errorf("rewards.ForEach failed: %w", err)
}
return out, nil
}

View File

@ -60,7 +60,11 @@ func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error
}
func (sm *StorageMinerAPI) ActorSectorSize(ctx context.Context, addr address.Address) (abi.SectorSize, error) {
return sm.Full.StateMinerSectorSize(ctx, addr, types.EmptyTSK)
mi, err := sm.Full.StateMinerInfo(ctx, addr, types.EmptyTSK)
if err != nil {
return 0, err
}
return mi.SectorSize, nil
}
func (sm *StorageMinerAPI) PledgeSector(ctx context.Context) error {

View File

@ -4,8 +4,6 @@ import (
"bytes"
"context"
"github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/ipfs/go-bitswap"
"github.com/ipfs/go-bitswap/network"
"github.com/ipfs/go-blockservice"
@ -18,6 +16,9 @@ import (
"go.uber.org/fx"
"golang.org/x/xerrors"
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/filecoin-project/lotus/chain"
"github.com/filecoin-project/lotus/chain/beacon"
"github.com/filecoin-project/lotus/chain/blocksync"
@ -142,8 +143,8 @@ func NetworkName(mctx helpers.MetricsCtx, lc fx.Lifecycle, cs *store.ChainStore,
return netName, err
}
func NewSyncer(lc fx.Lifecycle, sm *stmgr.StateManager, bsync *blocksync.BlockSync, h host.Host, beacon beacon.RandomBeacon) (*chain.Syncer, error) {
syncer, err := chain.NewSyncer(sm, bsync, h.ConnManager(), h.ID(), beacon)
func NewSyncer(lc fx.Lifecycle, sm *stmgr.StateManager, bsync *blocksync.BlockSync, h host.Host, beacon beacon.RandomBeacon, verifier ffiwrapper.Verifier) (*chain.Syncer, error) {
syncer, err := chain.NewSyncer(sm, bsync, h.ConnManager(), h.ID(), beacon, verifier)
if err != nil {
return nil, err
}

View File

@ -1,6 +1,7 @@
package modules
import (
"bytes"
"context"
"net/http"
"reflect"
@ -92,19 +93,18 @@ func StorageNetworkName(ctx helpers.MetricsCtx, a lapi.FullNode) (dtypes.Network
}
func ProofsConfig(maddr dtypes.MinerAddress, fnapi lapi.FullNode) (*ffiwrapper.Config, error) {
ssize, err := fnapi.StateMinerSectorSize(context.TODO(), address.Address(maddr), types.EmptyTSK)
mi, err := fnapi.StateMinerInfo(context.TODO(), address.Address(maddr), types.EmptyTSK)
if err != nil {
return nil, err
}
ppt, spt, err := ffiwrapper.ProofTypeFromSectorSize(ssize)
spt, err := ffiwrapper.SealProofTypeFromSectorSize(mi.SectorSize)
if err != nil {
return nil, xerrors.Errorf("bad sector size: %w", err)
}
sb := &ffiwrapper.Config{
SealProofType: spt,
PoStProofType: ppt,
}
return sb, nil
@ -132,17 +132,20 @@ func StorageMiner(mctx helpers.MetricsCtx, lc fx.Lifecycle, api lapi.FullNode, h
ctx := helpers.LifecycleCtx(mctx, lc)
worker, err := api.StateMinerWorker(ctx, maddr, types.EmptyTSK)
mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK)
if err != nil {
return nil, err
}
ppt, _, err := ffiwrapper.ProofTypeFromSectorSize(sealer.SectorSize())
worker, err := api.StateAccountKey(ctx, mi.Worker, types.EmptyTSK)
if err != nil {
return nil, xerrors.Errorf("bad sector size: %w", err)
return nil, err
}
fps := storage.NewFPoStScheduler(api, sealer, maddr, worker, ppt)
fps, err := storage.NewWindowedPoStScheduler(api, sealer, maddr, worker)
if err != nil {
return nil, err
}
sm, err := storage.NewMiner(api, maddr, worker, h, ds, sealer, sc, verif, tktFn)
if err != nil {
@ -257,7 +260,7 @@ func StagingGraphsync(mctx helpers.MetricsCtx, lc fx.Lifecycle, ibs dtypes.Stagi
return gs
}
func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api lapi.FullNode, epp gen.ElectionPoStProver, beacon beacon.RandomBeacon) (*miner.Miner, error) {
func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api lapi.FullNode, epp gen.WinningPoStProver, beacon beacon.RandomBeacon) (*miner.Miner, error) {
minerAddr, err := minerAddrFromDS(ds)
if err != nil {
return nil, err
@ -280,7 +283,17 @@ func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api lapi.FullNode
return m, nil
}
func SealTicketGen(fapi lapi.FullNode) sealing.TicketFn {
func SealTicketGen(fapi lapi.FullNode, ds dtypes.MetadataDS) (sealing.TicketFn, error) {
minerAddr, err := minerAddrFromDS(ds)
if err != nil {
return nil, err
}
entropy := new(bytes.Buffer)
if err := minerAddr.MarshalCBOR(entropy); err != nil {
return nil, err
}
return func(ctx context.Context, tok sealing.TipSetToken) (abi.SealRandomness, abi.ChainEpoch, error) {
tsk, err := types.TipSetKeyFromBytes(tok)
if err != nil {
@ -292,13 +305,13 @@ func SealTicketGen(fapi lapi.FullNode) sealing.TicketFn {
return nil, 0, xerrors.Errorf("getting TipSet for key failed: %w", err)
}
r, err := fapi.ChainGetRandomness(ctx, ts.Key(), crypto.DomainSeparationTag_SealRandomness, ts.Height()-build.SealRandomnessLookback, nil)
r, err := fapi.ChainGetRandomness(ctx, ts.Key(), crypto.DomainSeparationTag_SealRandomness, ts.Height()-build.SealRandomnessLookback, entropy.Bytes())
if err != nil {
return nil, 0, xerrors.Errorf("getting randomness for SealTicket failed: %w", err)
}
return abi.SealRandomness(r), ts.Height() - build.SealRandomnessLookback, nil
}
}, nil
}
func NewProviderRequestValidator(deals dtypes.ProviderDealStore) *requestvalidation.ProviderRequestValidator {
@ -321,12 +334,12 @@ func StorageProvider(ctx helpers.MetricsCtx, fapi lapi.FullNode, h host.Host, ds
return nil, err
}
ssize, err := fapi.StateMinerSectorSize(ctx, minerAddress, types.EmptyTSK)
mi, err := fapi.StateMinerInfo(ctx, minerAddress, types.EmptyTSK)
if err != nil {
return nil, err
}
rt, _, err := ffiwrapper.ProofTypeFromSectorSize(ssize)
rt, err := ffiwrapper.SealProofTypeFromSectorSize(mi.SectorSize)
if err != nil {
return nil, err
}

View File

@ -208,7 +208,7 @@ func builder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []test.Te
templ := &genesis.Template{
Accounts: genaccs,
Miners: genms,
Timestamp: uint64(time.Now().Unix() - 1000), // some time sufficiently far in the past
Timestamp: uint64(time.Now().Unix() - 10000), // some time sufficiently far in the past
}
// END PRESEAL SECTION
@ -338,7 +338,7 @@ func mockSbBuilder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []t
templ := &genesis.Template{
Accounts: genaccs,
Miners: genms,
Timestamp: uint64(time.Now().Unix() - 1000),
Timestamp: uint64(time.Now().Unix() - 10000),
}
// END PRESEAL SECTION

View File

@ -348,9 +348,11 @@ func (t *ChannelInfo) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.Vouchers = make([]*VoucherInfo, extra)
}
for i := 0; i < int(extra); i++ {
var v VoucherInfo

View File

@ -40,7 +40,35 @@ func (s SealingAPIAdapter) StateMinerSectorSize(ctx context.Context, maddr addre
return 0, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err)
}
return s.delegate.StateMinerSectorSize(ctx, maddr, tsk)
// TODO: update storage-fsm to just StateMinerInfo
mi, err := s.delegate.StateMinerInfo(ctx, maddr, tsk)
if err != nil {
return 0, err
}
return mi.SectorSize, nil
}
func (s SealingAPIAdapter) StateMinerWorkerAddress(ctx context.Context, maddr address.Address, tok sealing.TipSetToken) (address.Address, error) {
tsk, err := types.TipSetKeyFromBytes(tok)
if err != nil {
return address.Undef, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err)
}
// TODO: update storage-fsm to just StateMinerInfo
mi, err := s.delegate.StateMinerInfo(ctx, maddr, tsk)
if err != nil {
return address.Undef, err
}
return mi.Worker, nil
}
func (s SealingAPIAdapter) StateMinerDeadlines(ctx context.Context, maddr address.Address, tok sealing.TipSetToken) (*miner.Deadlines, error) {
tsk, err := types.TipSetKeyFromBytes(tok)
if err != nil {
return nil, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err)
}
return s.delegate.StateMinerDeadlines(ctx, maddr, tsk)
}
func (s SealingAPIAdapter) StateWaitMsg(ctx context.Context, mcid cid.Cid) (sealing.MsgLookup, error) {
@ -120,8 +148,12 @@ func (s SealingAPIAdapter) StateSectorPreCommitInfo(ctx context.Context, maddr a
return nil, xerrors.Errorf("handleSealFailed(%d): temp error: unmarshaling miner state: %+v", sectorNumber, err)
}
precommits, err := adt.AsMap(store.ActorStore(ctx, apibstore.NewAPIBlockstore(s.delegate)), state.PreCommittedSectors)
if err != nil {
return nil, err
}
var pci miner.SectorPreCommitOnChainInfo
precommits := adt.AsMap(store.ActorStore(ctx, apibstore.NewAPIBlockstore(s.delegate)), state.PreCommittedSectors)
if _, err := precommits.Get(adt.UIntKey(uint64(sectorNumber)), &pci); err != nil {
return nil, err
}

View File

@ -1,295 +0,0 @@
package storage
import (
"bytes"
"context"
"github.com/filecoin-project/go-address"
"time"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"go.opencensus.io/trace"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
)
func (s *FPoStScheduler) failPost(eps abi.ChainEpoch) {
s.failLk.Lock()
if eps > s.failed {
s.failed = eps
}
s.failLk.Unlock()
}
func (s *FPoStScheduler) doPost(ctx context.Context, eps abi.ChainEpoch, ts *types.TipSet) {
ctx, abort := context.WithCancel(ctx)
s.abort = abort
s.activeEPS = eps
go func() {
defer abort()
ctx, span := trace.StartSpan(ctx, "FPoStScheduler.doPost")
defer span.End()
proof, err := s.runPost(ctx, eps, ts)
if err != nil {
log.Errorf("runPost failed: %+v", err)
s.failPost(eps)
return
}
if err := s.submitPost(ctx, proof); err != nil {
log.Errorf("submitPost failed: %+v", err)
s.failPost(eps)
return
}
}()
}
func (s *FPoStScheduler) declareFaults(ctx context.Context, fc uint64, params *miner.DeclareTemporaryFaultsParams) error {
log.Warnf("DECLARING %d FAULTS", fc)
enc, aerr := actors.SerializeParams(params)
if aerr != nil {
return xerrors.Errorf("could not serialize declare faults parameters: %w", aerr)
}
msg := &types.Message{
To: s.actor,
From: s.worker,
Method: builtin.MethodsMiner.DeclareTemporaryFaults,
Params: enc,
Value: types.NewInt(0),
GasLimit: 10000000, // i dont know help
GasPrice: types.NewInt(1),
}
sm, err := s.api.MpoolPushMessage(ctx, msg)
if err != nil {
return xerrors.Errorf("pushing faults message to mpool: %w", err)
}
rec, err := s.api.StateWaitMsg(ctx, sm.Cid())
if err != nil {
return xerrors.Errorf("waiting for declare faults: %w", err)
}
if rec.Receipt.ExitCode != 0 {
return xerrors.Errorf("declare faults exit %d", rec.Receipt.ExitCode)
}
log.Infof("Faults declared successfully")
return nil
}
func (s *FPoStScheduler) checkFaults(ctx context.Context, ssi []abi.SectorNumber) ([]abi.SectorNumber, error) {
//faults := s.sb.Scrub(ssi)
log.Warnf("Stub checkFaults")
var faults []struct {
SectorNum abi.SectorNumber
Err error
}
declaredFaults := map[abi.SectorNumber]struct{}{}
{
chainFaults, err := s.api.StateMinerFaults(ctx, s.actor, types.EmptyTSK)
if err != nil {
return nil, xerrors.Errorf("checking on-chain faults: %w", err)
}
for _, fault := range chainFaults {
declaredFaults[fault] = struct{}{}
}
}
var faultIDs []abi.SectorNumber
if len(faults) > 0 {
params := &miner.DeclareTemporaryFaultsParams{
Duration: 900, // TODO: duration is annoying
SectorNumbers: abi.NewBitField(),
}
for _, fault := range faults {
if _, ok := declaredFaults[(fault.SectorNum)]; ok {
continue
}
log.Warnf("new fault detected: sector %d: %s", fault.SectorNum, fault.Err)
declaredFaults[fault.SectorNum] = struct{}{}
}
faultIDs = make([]abi.SectorNumber, 0, len(declaredFaults))
for fault := range declaredFaults {
faultIDs = append(faultIDs, fault)
params.SectorNumbers.Set(uint64(fault))
}
if len(faultIDs) > 0 {
if err := s.declareFaults(ctx, uint64(len(faultIDs)), params); err != nil {
return nil, err
}
}
}
return faultIDs, nil
}
func (s *FPoStScheduler) runPost(ctx context.Context, eps abi.ChainEpoch, ts *types.TipSet) (*abi.OnChainPoStVerifyInfo, error) {
ctx, span := trace.StartSpan(ctx, "storage.runPost")
defer span.End()
challengeRound := eps
buf := new(bytes.Buffer)
if err := s.actor.MarshalCBOR(buf); err != nil {
return nil, xerrors.Errorf("failed to marshal address to cbor: %w", err)
}
rand, err := s.api.ChainGetRandomness(ctx, ts.Key(), crypto.DomainSeparationTag_WindowedPoStChallengeSeed, challengeRound, buf.Bytes())
if err != nil {
return nil, xerrors.Errorf("failed to get chain randomness for fpost (ts=%d; eps=%d): %w", ts.Height(), eps, err)
}
ssi, err := s.sortedSectorInfo(ctx, ts)
if err != nil {
return nil, xerrors.Errorf("getting sorted sector info: %w", err)
}
if len(ssi) == 0 {
log.Warn("attempted to run fpost without any sectors...")
return nil, xerrors.Errorf("no sectors to run fpost on")
}
log.Infow("running fPoSt",
"chain-random", rand,
"eps", eps,
"height", ts.Height())
var snums []abi.SectorNumber
for _, si := range ssi {
snums = append(snums, si.SectorNumber)
}
faults, err := s.checkFaults(ctx, snums)
if err != nil {
log.Errorf("Failed to declare faults: %+v", err)
}
tsStart := time.Now()
log.Infow("generating fPoSt",
"sectors", len(ssi),
"faults", len(faults))
mid, err := address.IDFromAddress(s.actor)
if err != nil {
return nil, err
}
postOut, err := s.sb.GenerateFallbackPoSt(ctx, abi.ActorID(mid), ssi, abi.PoStRandomness(rand), faults)
if err != nil {
return nil, xerrors.Errorf("running post failed: %w", err)
}
if len(postOut.PoStInputs) == 0 {
return nil, xerrors.Errorf("received zero candidates back from generate fallback post")
}
// TODO: until we figure out how fallback post is really supposed to work,
// let's just pass a single candidate...
scandidates := postOut.PoStInputs[:1]
proof := postOut.Proof[:1]
elapsed := time.Since(tsStart)
log.Infow("submitting PoSt", "pLen", len(proof), "elapsed", elapsed)
candidates := make([]abi.PoStCandidate, len(scandidates))
for i, sc := range scandidates {
part := make([]byte, 32)
copy(part, sc.Candidate.PartialTicket[:])
candidates[i] = abi.PoStCandidate{
RegisteredProof: s.proofType,
PartialTicket: part,
SectorID: sc.Candidate.SectorID,
ChallengeIndex: sc.Candidate.ChallengeIndex,
}
}
return &abi.OnChainPoStVerifyInfo{
Proofs: proof,
Candidates: candidates,
}, nil
}
func (s *FPoStScheduler) sortedSectorInfo(ctx context.Context, ts *types.TipSet) ([]abi.SectorInfo, error) {
sset, err := s.api.StateMinerProvingSet(ctx, s.actor, ts.Key())
if err != nil {
return nil, xerrors.Errorf("failed to get proving set for miner (tsH: %d): %w", ts.Height(), err)
}
if len(sset) == 0 {
log.Warn("empty proving set! (ts.H: %d)", ts.Height())
}
sbsi := make([]abi.SectorInfo, len(sset))
for k, sector := range sset {
sbsi[k] = abi.SectorInfo{
SectorNumber: sector.Info.Info.SectorNumber,
SealedCID: sector.Info.Info.SealedCID,
RegisteredProof: sector.Info.Info.RegisteredProof,
}
}
return sbsi, nil
}
func (s *FPoStScheduler) submitPost(ctx context.Context, proof *abi.OnChainPoStVerifyInfo) error {
ctx, span := trace.StartSpan(ctx, "storage.commitPost")
defer span.End()
enc, aerr := actors.SerializeParams(proof)
if aerr != nil {
return xerrors.Errorf("could not serialize submit post parameters: %w", aerr)
}
msg := &types.Message{
To: s.actor,
From: s.worker,
Method: builtin.MethodsMiner.SubmitWindowedPoSt,
Params: enc,
Value: types.NewInt(1000), // currently hard-coded late fee in actor, returned if not late
GasLimit: 10000000, // i dont know help
GasPrice: types.NewInt(1),
}
// TODO: consider maybe caring about the output
sm, err := s.api.MpoolPushMessage(ctx, msg)
if err != nil {
return xerrors.Errorf("pushing message to mpool: %w", err)
}
log.Infof("Submitted fallback post: %s", sm.Cid())
go func() {
rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid())
if err != nil {
log.Error(err)
return
}
if rec.Receipt.ExitCode == 0 {
return
}
log.Errorf("Submitting fallback post %s failed: exit %d", sm.Cid(), rec.Receipt.ExitCode)
}()
return nil
}

View File

@ -1,176 +0,0 @@
package storage
import (
"context"
"sync"
"go.opencensus.io/trace"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-storage/storage"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
)
const Inactive = 0
const StartConfidence = 4 // TODO: config
type FPoStScheduler struct {
api storageMinerApi
sb storage.Prover
proofType abi.RegisteredProof
actor address.Address
worker address.Address
cur *types.TipSet
// if a post is in progress, this indicates for which ElectionPeriodStart
activeEPS abi.ChainEpoch
abort context.CancelFunc
failed abi.ChainEpoch // eps
failLk sync.Mutex
}
func NewFPoStScheduler(api storageMinerApi, sb storage.Prover, actor address.Address, worker address.Address, rt abi.RegisteredProof) *FPoStScheduler {
return &FPoStScheduler{api: api, sb: sb, actor: actor, worker: worker, proofType: rt}
}
func (s *FPoStScheduler) Run(ctx context.Context) {
notifs, err := s.api.ChainNotify(ctx)
if err != nil {
return
}
current := <-notifs
if len(current) != 1 {
panic("expected first notif to have len = 1")
}
if current[0].Type != store.HCCurrent {
panic("expected first notif to tell current ts")
}
if err := s.update(ctx, current[0].Val); err != nil {
panic(err)
}
defer s.abortActivePoSt()
// not fine to panic after this point
for {
select {
case changes, ok := <-notifs:
if !ok {
log.Warn("FPoStScheduler notifs channel closed")
return
}
ctx, span := trace.StartSpan(ctx, "FPoStScheduler.headChange")
var lowest, highest *types.TipSet = s.cur, nil
for _, change := range changes {
if change.Val == nil {
log.Errorf("change.Val was nil")
}
switch change.Type {
case store.HCRevert:
lowest = change.Val
case store.HCApply:
highest = change.Val
}
}
if err := s.revert(ctx, lowest); err != nil {
log.Error("handling head reverts in fallbackPost sched: %+v", err)
}
if err := s.update(ctx, highest); err != nil {
log.Error("handling head updates in fallbackPost sched: %+v", err)
}
span.End()
case <-ctx.Done():
return
}
}
}
func (s *FPoStScheduler) revert(ctx context.Context, newLowest *types.TipSet) error {
if s.cur == newLowest {
return nil
}
s.cur = newLowest
newEPS, _, err := s.shouldFallbackPost(ctx, newLowest)
if err != nil {
return err
}
if newEPS != s.activeEPS {
s.abortActivePoSt()
}
return nil
}
func (s *FPoStScheduler) update(ctx context.Context, new *types.TipSet) error {
if new == nil {
return xerrors.Errorf("no new tipset in FPoStScheduler.update")
}
newEPS, start, err := s.shouldFallbackPost(ctx, new)
if err != nil {
return err
}
s.failLk.Lock()
if s.failed > 0 {
s.failed = 0
s.activeEPS = 0
}
s.failLk.Unlock()
if newEPS == s.activeEPS {
return nil
}
s.abortActivePoSt()
if newEPS != Inactive && start {
s.doPost(ctx, newEPS, new)
}
return nil
}
func (s *FPoStScheduler) abortActivePoSt() {
if s.activeEPS == Inactive {
return // noop
}
if s.abort != nil {
s.abort()
}
log.Warnf("Aborting Fallback PoSt (EPS: %d)", s.activeEPS)
s.activeEPS = Inactive
s.abort = nil
}
func (s *FPoStScheduler) shouldFallbackPost(ctx context.Context, ts *types.TipSet) (abi.ChainEpoch, bool, error) {
ps, err := s.api.StateMinerPostState(ctx, s.actor, ts.Key())
if err != nil {
return 0, false, xerrors.Errorf("getting ElectionPeriodStart: %w", err)
}
if ts.Height() >= ps.ProvingPeriodStart {
return ps.ProvingPeriodStart, ts.Height() >= ps.ProvingPeriodStart+build.FallbackPoStConfidence, nil
}
return 0, false, nil
}

View File

@ -49,12 +49,10 @@ type Miner struct {
type storageMinerApi interface {
// Call a read only method on actors (no interaction with the chain required)
StateCall(context.Context, *types.Message, types.TipSetKey) (*api.InvocResult, error)
StateMinerWorker(context.Context, address.Address, types.TipSetKey) (address.Address, error)
StateMinerPostState(ctx context.Context, actor address.Address, ts types.TipSetKey) (*miner.PoStState, error)
StateMinerSectors(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error)
StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error)
StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error)
StateMinerDeadlines(ctx context.Context, maddr address.Address, tok types.TipSetKey) (*miner.Deadlines, error)
StateMinerSectors(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error)
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error)
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error)
StateWaitMsg(context.Context, cid.Cid) (*api.MsgLookup, error) // TODO: removeme eventually
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
@ -98,10 +96,15 @@ func (m *Miner) Run(ctx context.Context) error {
return xerrors.Errorf("miner preflight checks failed: %w", err)
}
mi, err := m.api.StateMinerInfo(ctx, m.maddr, types.EmptyTSK)
if err != nil {
return xerrors.Errorf("getting miner info: %w", err)
}
evts := events.NewEvents(ctx, m.api)
adaptedAPI := NewSealingAPIAdapter(m.api)
pcp := sealing.NewBasicPreCommitPolicy(adaptedAPI, 10000000)
m.sealing = sealing.New(adaptedAPI, NewEventsAdapter(evts), m.maddr, m.worker, m.ds, m.sealer, m.sc, m.verif, m.tktFn, &pcp)
pcp := sealing.NewBasicPreCommitPolicy(adaptedAPI, 10000000, mi.ProvingPeriodBoundary)
m.sealing = sealing.New(adaptedAPI, NewEventsAdapter(evts), m.maddr, m.ds, m.sealer, m.sc, m.verif, m.tktFn, &pcp)
go m.sealing.Run(ctx)
@ -127,45 +130,63 @@ func (m *Miner) runPreflightChecks(ctx context.Context) error {
return nil
}
type StorageEpp struct {
prover storage.Prover
miner abi.ActorID
type StorageWpp struct {
prover storage.Prover
verifier ffiwrapper.Verifier
miner abi.ActorID
winnRpt abi.RegisteredProof
}
func NewElectionPoStProver(sb storage.Prover, miner dtypes.MinerID) *StorageEpp {
return &StorageEpp{sb, abi.ActorID(miner)}
func NewWinningPoStProver(api api.FullNode, prover storage.Prover, verifier ffiwrapper.Verifier, miner dtypes.MinerID) (*StorageWpp, error) {
ma, err := address.NewIDAddress(uint64(miner))
if err != nil {
return nil, err
}
mi, err := api.StateMinerInfo(context.TODO(), ma, types.EmptyTSK)
if err != nil {
return nil, xerrors.Errorf("getting sector size: %w", err)
}
spt, err := ffiwrapper.SealProofTypeFromSectorSize(mi.SectorSize)
if err != nil {
return nil, err
}
wpt, err := spt.RegisteredWinningPoStProof()
if err != nil {
return nil, err
}
return &StorageWpp{prover, verifier, abi.ActorID(miner), wpt}, nil
}
var _ gen.ElectionPoStProver = (*StorageEpp)(nil)
var _ gen.WinningPoStProver = (*StorageWpp)(nil)
func (epp *StorageEpp) GenerateCandidates(ctx context.Context, ssi []abi.SectorInfo, rand abi.PoStRandomness) ([]storage.PoStCandidateWithTicket, error) {
func (wpp *StorageWpp) GenerateCandidates(ctx context.Context, randomness abi.PoStRandomness, eligibleSectorCount uint64) ([]uint64, error) {
start := time.Now()
var faults []abi.SectorNumber // TODO
cds, err := epp.prover.GenerateEPostCandidates(ctx, epp.miner, ssi, rand, faults)
cds, err := wpp.verifier.GenerateWinningPoStSectorChallenge(ctx, wpp.winnRpt, wpp.miner, randomness, eligibleSectorCount)
if err != nil {
return nil, xerrors.Errorf("failed to generate candidates: %w", err)
}
log.Infof("Generate candidates took %s", time.Since(start))
log.Infof("Generate candidates took %s (C: %+v)", time.Since(start), cds)
return cds, nil
}
func (epp *StorageEpp) ComputeProof(ctx context.Context, ssi []abi.SectorInfo, rand []byte, winners []storage.PoStCandidateWithTicket) ([]abi.PoStProof, error) {
func (wpp *StorageWpp) ComputeProof(ctx context.Context, ssi []abi.SectorInfo, rand abi.PoStRandomness) ([]abi.PoStProof, error) {
if build.InsecurePoStValidation {
log.Warn("Generating fake EPost proof! You should only see this while running tests!")
return []abi.PoStProof{{ProofBytes: []byte("valid proof")}}, nil
}
owins := make([]abi.PoStCandidate, 0, len(winners))
for _, w := range winners {
owins = append(owins, w.Candidate)
}
log.Infof("Computing WinningPoSt ;%+v; %v", ssi, rand)
start := time.Now()
proof, err := epp.prover.ComputeElectionPoSt(ctx, epp.miner, ssi, rand, owins)
proof, err := wpp.prover.GenerateWinningPoSt(ctx, wpp.miner, ssi, rand)
if err != nil {
return nil, err
}
log.Infof("ComputeElectionPost took %s", time.Since(start))
log.Infof("GenerateWinningPoSt took %s", time.Since(start))
return proof, nil
}

View File

@ -31,7 +31,7 @@ func PreSeal(ssize abi.SectorSize, maddr address.Address, sectors int) (*genesis
Sectors: make([]*genesis.PreSeal, sectors),
}
_, st, err := ffiwrapper.ProofTypeFromSectorSize(ssize)
st, err := ffiwrapper.SealProofTypeFromSectorSize(ssize)
if err != nil {
return nil, nil, err
}

241
storage/wdpost_run.go Normal file
View File

@ -0,0 +1,241 @@
package storage
import (
"bytes"
"context"
"time"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/crypto"
"go.opencensus.io/trace"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
)
func (s *WindowPoStScheduler) failPost(deadline *miner.DeadlineInfo) {
log.Errorf("TODO")
/*s.failLk.Lock()
if eps > s.failed {
s.failed = eps
}
s.failLk.Unlock()*/
}
func (s *WindowPoStScheduler) doPost(ctx context.Context, deadline *miner.DeadlineInfo, ts *types.TipSet) {
ctx, abort := context.WithCancel(ctx)
s.abort = abort
s.activeDeadline = deadline
go func() {
defer abort()
ctx, span := trace.StartSpan(ctx, "WindowPoStScheduler.doPost")
defer span.End()
proof, err := s.runPost(ctx, *deadline, ts)
if err != nil {
log.Errorf("runPost failed: %+v", err)
s.failPost(deadline)
return
}
if err := s.submitPost(ctx, proof); err != nil {
log.Errorf("submitPost failed: %+v", err)
s.failPost(deadline)
return
}
}()
}
func (s *WindowPoStScheduler) checkFaults(ctx context.Context, ssi []abi.SectorNumber) ([]abi.SectorNumber, error) {
//faults := s.prover.Scrub(ssi)
log.Warnf("Stub checkFaults")
declaredFaults := map[abi.SectorNumber]struct{}{}
{
chainFaults, err := s.api.StateMinerFaults(ctx, s.actor, types.EmptyTSK)
if err != nil {
return nil, xerrors.Errorf("checking on-chain faults: %w", err)
}
for _, fault := range chainFaults {
declaredFaults[fault] = struct{}{}
}
}
return nil, nil
}
func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo, ts *types.TipSet) (*miner.SubmitWindowedPoStParams, error) {
ctx, span := trace.StartSpan(ctx, "storage.runPost")
defer span.End()
buf := new(bytes.Buffer)
if err := s.actor.MarshalCBOR(buf); err != nil {
return nil, xerrors.Errorf("failed to marshal address to cbor: %w", err)
}
rand, err := s.api.ChainGetRandomness(ctx, ts.Key(), crypto.DomainSeparationTag_WindowedPoStChallengeSeed, di.Challenge, buf.Bytes())
if err != nil {
return nil, xerrors.Errorf("failed to get chain randomness for windowPost (ts=%d; deadline=%d): %w", ts.Height(), di, err)
}
deadlines, err := s.api.StateMinerDeadlines(ctx, s.actor, ts.Key())
if err != nil {
return nil, err
}
firstPartition, _, err := miner.PartitionsForDeadline(deadlines, di.Index)
if err != nil {
return nil, xerrors.Errorf("getting partitions for deadline: %w", err)
}
partitionCount, _, err := miner.DeadlineCount(deadlines, di.Index)
if err != nil {
return nil, xerrors.Errorf("getting deadline partition count: %w", err)
}
dc, err := deadlines.Due[di.Index].Count()
if err != nil {
return nil, xerrors.Errorf("get deadline count: %w", err)
}
log.Infof("di: %+v", di)
log.Infof("dc: %+v", dc)
log.Infof("fp: %+v", firstPartition)
log.Infof("pc: %+v", partitionCount)
log.Infof("ts: %+v (%d)", ts.Key(), ts.Height())
if partitionCount == 0 {
return nil, nil
}
partitions := make([]uint64, partitionCount)
for i := range partitions {
partitions[i] = firstPartition + uint64(i)
}
ssi, err := s.sortedSectorInfo(ctx, deadlines.Due[di.Index], ts)
if err != nil {
return nil, xerrors.Errorf("getting sorted sector info: %w", err)
}
if len(ssi) == 0 {
log.Warn("attempted to run windowPost without any sectors...")
return nil, xerrors.Errorf("no sectors to run windowPost on")
}
log.Infow("running windowPost",
"chain-random", rand,
"deadline", di,
"height", ts.Height())
var snums []abi.SectorNumber
for _, si := range ssi {
snums = append(snums, si.SectorNumber)
}
faults, err := s.checkFaults(ctx, snums)
if err != nil {
log.Errorf("Failed to declare faults: %+v", err)
}
tsStart := time.Now()
log.Infow("generating windowPost",
"sectors", len(ssi),
"faults", len(faults))
mid, err := address.IDFromAddress(s.actor)
if err != nil {
return nil, err
}
// TODO: Faults!
postOut, err := s.prover.GenerateWindowPoSt(ctx, abi.ActorID(mid), ssi, abi.PoStRandomness(rand))
if err != nil {
return nil, xerrors.Errorf("running post failed: %w", err)
}
if len(postOut) == 0 {
return nil, xerrors.Errorf("received proofs back from generate window post")
}
elapsed := time.Since(tsStart)
log.Infow("submitting window PoSt", "elapsed", elapsed)
return &miner.SubmitWindowedPoStParams{
Partitions: partitions,
Proofs: postOut,
Skipped: *abi.NewBitField(), // TODO: Faults here?
}, nil
}
func (s *WindowPoStScheduler) sortedSectorInfo(ctx context.Context, deadlineSectors *abi.BitField, ts *types.TipSet) ([]abi.SectorInfo, error) {
sset, err := s.api.StateMinerSectors(ctx, s.actor, deadlineSectors, false, ts.Key())
if err != nil {
return nil, err
}
sbsi := make([]abi.SectorInfo, len(sset))
for k, sector := range sset {
sbsi[k] = abi.SectorInfo{
SectorNumber: sector.ID,
SealedCID: sector.Info.Info.SealedCID,
RegisteredProof: sector.Info.Info.RegisteredProof,
}
}
return sbsi, nil
}
func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *miner.SubmitWindowedPoStParams) error {
ctx, span := trace.StartSpan(ctx, "storage.commitPost")
defer span.End()
enc, aerr := actors.SerializeParams(proof)
if aerr != nil {
return xerrors.Errorf("could not serialize submit post parameters: %w", aerr)
}
msg := &types.Message{
To: s.actor,
From: s.worker,
Method: builtin.MethodsMiner.SubmitWindowedPoSt,
Params: enc,
Value: types.NewInt(1000), // currently hard-coded late fee in actor, returned if not late
GasLimit: 10000000, // i dont know help
GasPrice: types.NewInt(1),
}
// TODO: consider maybe caring about the output
sm, err := s.api.MpoolPushMessage(ctx, msg)
if err != nil {
return xerrors.Errorf("pushing message to mpool: %w", err)
}
log.Infof("Submitted window post: %s", sm.Cid())
go func() {
rec, err := s.api.StateWaitMsg(context.TODO(), sm.Cid())
if err != nil {
log.Error(err)
return
}
if rec.Receipt.ExitCode == 0 {
return
}
log.Errorf("Submitting window post %s failed: exit %d", sm.Cid(), rec.Receipt.ExitCode)
}()
return nil
}

219
storage/wdpost_sched.go Normal file
View File

@ -0,0 +1,219 @@
package storage
import (
"context"
"time"
"go.opencensus.io/trace"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-storage/storage"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
)
const StartConfidence = 4 // TODO: config
type WindowPoStScheduler struct {
api storageMinerApi
prover storage.Prover
proofType abi.RegisteredProof
actor address.Address
worker address.Address
cur *types.TipSet
// if a post is in progress, this indicates for which ElectionPeriodStart
activeDeadline *miner.DeadlineInfo
abort context.CancelFunc
//failed abi.ChainEpoch // eps
//failLk sync.Mutex
}
func NewWindowedPoStScheduler(api storageMinerApi, sb storage.Prover, actor address.Address, worker address.Address) (*WindowPoStScheduler, error) {
mi, err := api.StateMinerInfo(context.TODO(), actor, types.EmptyTSK)
if err != nil {
return nil, xerrors.Errorf("getting sector size: %w", err)
}
spt, err := ffiwrapper.SealProofTypeFromSectorSize(mi.SectorSize)
if err != nil {
return nil, err
}
rt, err := spt.RegisteredWindowPoStProof()
if err != nil {
return nil, err
}
return &WindowPoStScheduler{api: api, prover: sb, actor: actor, worker: worker, proofType: rt}, nil
}
func deadlineEquals(a, b *miner.DeadlineInfo) bool {
if a == nil || b == nil {
return b == a
}
return a.PeriodStart == b.PeriodStart && a.Index == b.Index && a.Challenge == b.Challenge
}
func (s *WindowPoStScheduler) Run(ctx context.Context) {
defer s.abortActivePoSt()
var notifs <-chan []*store.HeadChange
var err error
var gotCur bool
// not fine to panic after this point
for {
if notifs == nil {
notifs, err = s.api.ChainNotify(ctx)
if err != nil {
log.Errorf("ChainNotify error: %+v")
time.Sleep(10 * time.Second)
continue
}
gotCur = false
}
select {
case changes, ok := <-notifs:
if !ok {
log.Warn("WindowPoStScheduler notifs channel closed")
notifs = nil
continue
}
if !gotCur {
if len(changes) != 1 {
log.Errorf("expected first notif to have len = 1")
continue
}
if changes[0].Type != store.HCCurrent {
log.Errorf("expected first notif to tell current ts")
continue
}
if err := s.update(ctx, changes[0].Val); err != nil {
log.Errorf("%+v", err)
}
gotCur = true
continue
}
ctx, span := trace.StartSpan(ctx, "WindowPoStScheduler.headChange")
var lowest, highest *types.TipSet = s.cur, nil
for _, change := range changes {
if change.Val == nil {
log.Errorf("change.Val was nil")
}
switch change.Type {
case store.HCRevert:
lowest = change.Val
case store.HCApply:
highest = change.Val
}
}
if err := s.revert(ctx, lowest); err != nil {
log.Error("handling head reverts in fallbackPost sched: %+v", err)
}
if err := s.update(ctx, highest); err != nil {
log.Error("handling head updates in fallbackPost sched: %+v", err)
}
span.End()
case <-ctx.Done():
return
}
}
}
func (s *WindowPoStScheduler) revert(ctx context.Context, newLowest *types.TipSet) error {
if s.cur == newLowest {
return nil
}
s.cur = newLowest
mi, err := s.api.StateMinerInfo(ctx, s.actor, newLowest.Key())
if err != nil {
return err
}
newDeadline, _ := deadlineInfo(mi, newLowest)
if !deadlineEquals(s.activeDeadline, newDeadline) {
s.abortActivePoSt()
}
return nil
}
func (s *WindowPoStScheduler) update(ctx context.Context, new *types.TipSet) error {
if new == nil {
return xerrors.Errorf("no new tipset in WindowPoStScheduler.update")
}
mi, err := s.api.StateMinerInfo(ctx, s.actor, new.Key())
if err != nil {
return err
}
di, nn := deadlineInfo(mi, new)
if deadlineEquals(s.activeDeadline, di) {
return nil // already working on this deadline
}
if !nn {
return nil // not proving anything yet
}
s.abortActivePoSt()
if di.Challenge+StartConfidence >= new.Height() {
log.Info("not starting windowPost yet, waiting for startconfidence", di.Challenge, di.Challenge+StartConfidence, new.Height())
return nil
}
/*s.failLk.Lock()
if s.failed > 0 {
s.failed = 0
s.activeEPS = 0
}
s.failLk.Unlock()*/
log.Infof("at %d, doPost for P %d, dd %d", new.Height(), di.PeriodStart, di.Index)
s.doPost(ctx, di, new)
return nil
}
func (s *WindowPoStScheduler) abortActivePoSt() {
if s.activeDeadline == nil {
return // noop
}
if s.abort != nil {
s.abort()
}
log.Warnf("Aborting Fallback PoSt (Deadline: %+v)", s.activeDeadline)
s.activeDeadline = nil
s.abort = nil
}
func deadlineInfo(mi miner.MinerInfo, new *types.TipSet) (*miner.DeadlineInfo, bool) {
return miner.ComputeProvingPeriodDeadline(mi.ProvingPeriodBoundary, new.Height())
}

View File

@ -164,7 +164,7 @@ func RecordTipsetStatePoints(ctx context.Context, api api.FullNode, pl *PointLis
return err
}
p = NewPoint("chain.power", power.TotalPower.Int64())
p = NewPoint("chain.power", power.TotalPower.QualityAdjPower.Int64())
pl.AddPoint(p)
miners, err := api.StateListMiners(ctx, tipset.Key())
@ -174,7 +174,7 @@ func RecordTipsetStatePoints(ctx context.Context, api api.FullNode, pl *PointLis
return err
}
p = NewPoint("chain.miner_power", power.MinerPower.Int64())
p = NewPoint("chain.miner_power", power.MinerPower.QualityAdjPower.Int64())
p.AddTag("miner", miner.String())
pl.AddPoint(p)
}