From 4e5319857cc6aa49041712d1f63f1469b7e4a977 Mon Sep 17 00:00:00 2001 From: Erin Swenson-Healey Date: Tue, 4 Jun 2019 10:47:48 -0700 Subject: [PATCH] [part 3] "miner create" command must accept "sectorsize" flag (#2874) * remove Pledge from storage miner actor * drop pledge from "miner create" + don't require minimum collateral * modify "miner create" to accept a sector size, in bytes --- commands/miner.go | 24 +++++++++++++++--------- commands/miner_daemon_test.go | 16 ++++++++++++++++ commands/opt_sector_size.go | 21 +++++++++++++++++++++ porcelain/protocol.go | 27 +++++++++++++++++++++++---- porcelain/protocol_test.go | 5 +++-- 5 files changed, 78 insertions(+), 15 deletions(-) create mode 100644 commands/opt_sector_size.go diff --git a/commands/miner.go b/commands/miner.go index e16a503116..8b80499908 100644 --- a/commands/miner.go +++ b/commands/miner.go @@ -6,6 +6,7 @@ import ( "io" "math/big" "strconv" + "strings" "github.com/ipfs/go-cid" "github.com/ipfs/go-ipfs-cmdkit" @@ -50,10 +51,11 @@ miner's collateral drops below 0.001FIL, the miner will not be able to commit additional sectors.`, }, Arguments: []cmdkit.Argument{ - cmdkit.StringArg("collateral", true, false, "The amount of collateral, in FIL"), + cmdkit.StringArg("collateral", true, false, "The amount of collateral, in FIL."), }, Options: []cmdkit.Option{ - cmdkit.StringOption("from", "Address to send from"), + cmdkit.StringOption("sectorsize", "size of the sectors which this miner will commit, in bytes"), + cmdkit.StringOption("from", "address to send from"), cmdkit.StringOption("peerid", "Base58-encoded libp2p peer ID that the miner will operate"), priceOption, limitOption, @@ -67,18 +69,22 @@ additional sectors.`, return err } - // TODO: Modify this command to accept a sector size as an argument, - // ensuring that the provided sector size is supported by the network. - // https://github.com/filecoin-project/go-filecoin/issues/2530 - // + sectorSize, err := optionalSectorSizeWithDefault(req.Options["sectorsize"], pp.SupportedSectorSizes[0]) + if err != nil { + return err + } + // TODO: It may become the case that the protocol does not specify an // enumeration of supported sector sizes, but rather that any sector // size for which a miner has Groth parameters and a verifying key is // supported. // https://github.com/filecoin-project/specs/pull/318 - sectorSize := types.OneKiBSectorSize - if pp.ProofsMode == types.LiveProofsMode { - sectorSize = types.TwoHundredFiftySixMiBSectorSize + if !pp.IsSupportedSectorSize(sectorSize) { + supportedStrs := make([]string, len(pp.SupportedSectorSizes)) + for i, ss := range pp.SupportedSectorSizes { + supportedStrs[i] = ss.String() + } + return fmt.Errorf("unsupported sector size: %s (supported sizes: %s)", sectorSize, strings.Join(supportedStrs, ", ")) } fromAddr, err := optionalAddr(req.Options["from"]) diff --git a/commands/miner_daemon_test.go b/commands/miner_daemon_test.go index 0fb37c6a26..c186876d05 100644 --- a/commands/miner_daemon_test.go +++ b/commands/miner_daemon_test.go @@ -149,6 +149,18 @@ func TestMinerCreate(t *testing.T) { tf(testAddr, th.RequireRandomPeerID(t)) }) + t.Run("unsupported sector size", func(t *testing.T) { + d := th.NewDaemon(t).Start() + defer d.ShutdownSuccess() + + d.CreateAddress() + + d.RunFail("unsupported sector size", + "miner", "create", "20", + "--sectorsize", "42", + ) + }) + t.Run("validation failure", func(t *testing.T) { d := th.NewDaemon(t).Start() @@ -156,6 +168,10 @@ func TestMinerCreate(t *testing.T) { d.CreateAddress() + d.RunFail("invalid sector size", + "miner", "create", "20", + "--sectorsize", "ninetybillion", + ) d.RunFail("invalid peer id", "miner", "create", "--from", testAddr.String(), "--gas-price", "1", "--gas-limit", "300", "--peerid", "flarp", "20", diff --git a/commands/opt_sector_size.go b/commands/opt_sector_size.go new file mode 100644 index 0000000000..7b9a79e105 --- /dev/null +++ b/commands/opt_sector_size.go @@ -0,0 +1,21 @@ +package commands + +import ( + "fmt" + "strconv" + + "github.com/filecoin-project/go-filecoin/types" +) + +func optionalSectorSizeWithDefault(o interface{}, def *types.BytesAmount) (*types.BytesAmount, error) { + if o != nil { + n, err := strconv.ParseUint(o.(string), 10, 64) + if err != nil || n == 0 { + return nil, fmt.Errorf("invalid sector size: %s", o.(string)) + } + + return types.NewBytesAmount(n), nil + } + + return def, nil +} diff --git a/porcelain/protocol.go b/porcelain/protocol.go index 174045a347..8db933fc9a 100644 --- a/porcelain/protocol.go +++ b/porcelain/protocol.go @@ -12,8 +12,9 @@ import ( // ProtocolParams TODO(rosa) type ProtocolParams struct { - AutoSealInterval uint - ProofsMode types.ProofsMode + AutoSealInterval uint + ProofsMode types.ProofsMode + SupportedSectorSizes []*types.BytesAmount } type protocolParamsPlumbing interface { @@ -38,12 +39,30 @@ func ProtocolParameters(ctx context.Context, plumbing protocolParamsPlumbing) (* return nil, errors.Wrap(err, "could not retrieve proofs mode") } + supportedSectorSizes := []*types.BytesAmount{types.OneKiBSectorSize} + if proofsMode == types.LiveProofsMode { + supportedSectorSizes[0] = types.TwoHundredFiftySixMiBSectorSize + } + return &ProtocolParams{ - AutoSealInterval: autoSealInterval, - ProofsMode: proofsMode, + AutoSealInterval: autoSealInterval, + ProofsMode: proofsMode, + SupportedSectorSizes: supportedSectorSizes, }, nil } +// IsSupportedSectorSize returns true if the given sector size is supported by +// the network. +func (pp *ProtocolParams) IsSupportedSectorSize(sectorSize *types.BytesAmount) bool { + for _, size := range pp.SupportedSectorSizes { + if size.Equal(sectorSize) { + return true + } + } + + return false +} + func getProofsMode(ctx context.Context, plumbing protocolParamsPlumbing) (types.ProofsMode, error) { var proofsMode types.ProofsMode values, err := plumbing.MessageQuery(ctx, address.Address{}, address.StorageMarketAddress, "getProofsMode") diff --git a/porcelain/protocol_test.go b/porcelain/protocol_test.go index 7abf597bc5..72fb4a27e5 100644 --- a/porcelain/protocol_test.go +++ b/porcelain/protocol_test.go @@ -38,8 +38,9 @@ func TestProtocolParams(t *testing.T) { } expected := &porcelain.ProtocolParams{ - AutoSealInterval: 120, - ProofsMode: types.TestProofsMode, + AutoSealInterval: 120, + ProofsMode: types.TestProofsMode, + SupportedSectorSizes: []*types.BytesAmount{types.OneKiBSectorSize}, } out, err := porcelain.ProtocolParameters(context.TODO(), plumbing)