package config import ( "encoding" "time" "github.com/ipfs/go-cid" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" miner5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/types" sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" ) const ( // RetrievalPricingDefault configures the node to use the default retrieval pricing policy. RetrievalPricingDefaultMode = "default" // RetrievalPricingExternal configures the node to use the external retrieval pricing script // configured by the user. RetrievalPricingExternalMode = "external" ) // Common is common config between full node and miner type Common struct { API API Backup Backup Libp2p Libp2p Pubsub Pubsub } // FullNode is a full node config type FullNode struct { Common Client Client Metrics Metrics Wallet Wallet Fees FeeConfig Chainstore Chainstore } // // Common type Backup struct { DisableMetadataLog bool } // StorageMiner is a miner config type StorageMiner struct { Common Subsystems MinerSubsystemConfig Dealmaking DealmakingConfig Sealing SealingConfig Storage sectorstorage.SealerConfig Fees MinerFeeConfig Addresses MinerAddressConfig } type MinerSubsystemConfig struct { EnableMining bool EnableSealing bool EnableSectorStorage bool EnableMarkets bool SealerApiInfo string // if EnableSealing == false SectorIndexApiInfo string // if EnableSectorStorage == false } type DealmakingConfig struct { ConsiderOnlineStorageDeals bool ConsiderOfflineStorageDeals bool ConsiderOnlineRetrievalDeals bool ConsiderOfflineRetrievalDeals bool ConsiderVerifiedStorageDeals bool ConsiderUnverifiedStorageDeals bool PieceCidBlocklist []cid.Cid ExpectedSealDuration Duration // Maximum amount of time proposed deal StartEpoch can be in future MaxDealStartDelay Duration // The amount of time to wait for more deals to arrive before // publishing PublishMsgPeriod Duration // The maximum number of deals to include in a single PublishStorageDeals // message MaxDealsPerPublishMsg uint64 // The maximum collateral that the provider will put up against a deal, // as a multiplier of the minimum collateral bound MaxProviderCollateralMultiplier uint64 // The maximum number of parallel online data transfers (storage+retrieval) SimultaneousTransfers uint64 Filter string RetrievalFilter string RetrievalPricing *RetrievalPricing } type RetrievalPricing struct { Strategy string // possible values: "default", "external" Default *RetrievalPricingDefault External *RetrievalPricingExternal } type RetrievalPricingExternal struct { // Path of the external script that will be run to price a retrieval deal. // This parameter is ONLY applicable if the retrieval pricing policy strategy has been configured to "external". Path string } type RetrievalPricingDefault struct { // VerifiedDealsFreeTransfer configures zero fees for data transfer for a retrieval deal // of a payloadCid that belongs to a verified storage deal. // This parameter is ONLY applicable if the retrieval pricing policy strategy has been configured to "default". // default value is true VerifiedDealsFreeTransfer bool } type SealingConfig struct { // 0 = no limit MaxWaitDealsSectors uint64 // includes failed, 0 = no limit MaxSealingSectors uint64 // includes failed, 0 = no limit MaxSealingSectorsForDeals uint64 WaitDealsDelay Duration AlwaysKeepUnsealedCopy bool // Run sector finalization before submitting sector proof to the chain FinalizeEarly bool // Whether to use available miner balance for sector collateral instead of sending it with each message CollateralFromMinerBalance bool // Minimum available balance to keep in the miner actor before sending it with messages AvailableBalanceBuffer types.FIL // Don't send collateral with messages even if there is no available balance in the miner actor DisableCollateralFallback bool // enable / disable precommit batching (takes effect after nv13) BatchPreCommits bool // maximum precommit batch size - batches will be sent immediately above this size MaxPreCommitBatch int // how long to wait before submitting a batch after crossing the minimum batch size PreCommitBatchWait Duration // time buffer for forceful batch submission before sectors/deal in batch would start expiring PreCommitBatchSlack Duration // enable / disable commit aggregation (takes effect after nv13) AggregateCommits bool // maximum batched commit size - batches will be sent immediately above this size MinCommitBatch int MaxCommitBatch int // how long to wait before submitting a batch after crossing the minimum batch size CommitBatchWait Duration // time buffer for forceful batch submission before sectors/deals in batch would start expiring CommitBatchSlack Duration // network BaseFee below which to stop doing commit aggregation, instead // submitting proofs to the chain individually AggregateAboveBaseFee types.FIL TerminateBatchMax uint64 TerminateBatchMin uint64 TerminateBatchWait Duration // Keep this many sectors in sealing pipeline, start CC if needed // todo TargetSealingSectors uint64 // todo TargetSectors - stop auto-pleding new sectors after this many sectors are sealed, default CC upgrade for deals sectors if above } type BatchFeeConfig struct { Base types.FIL PerSector types.FIL } func (b *BatchFeeConfig) FeeForSectors(nSectors int) abi.TokenAmount { return big.Add(big.Int(b.Base), big.Mul(big.NewInt(int64(nSectors)), big.Int(b.PerSector))) } type MinerFeeConfig struct { MaxPreCommitGasFee types.FIL MaxCommitGasFee types.FIL // maxBatchFee = maxBase + maxPerSector * nSectors MaxPreCommitBatchGasFee BatchFeeConfig MaxCommitBatchGasFee BatchFeeConfig MaxTerminateGasFee types.FIL MaxWindowPoStGasFee types.FIL MaxPublishDealsFee types.FIL MaxMarketBalanceAddFee types.FIL } type MinerAddressConfig struct { PreCommitControl []string CommitControl []string TerminateControl []string DealPublishControl []string // DisableOwnerFallback disables usage of the owner address for messages // sent automatically DisableOwnerFallback bool // DisableWorkerFallback disables usage of the worker address for messages // sent automatically, if control addresses are configured. // A control address that doesn't have enough funds will still be chosen // over the worker address if this flag is set. DisableWorkerFallback bool } // API contains configs for API endpoint type API struct { ListenAddress string RemoteListenAddress string Timeout Duration } // Libp2p contains configs for libp2p type Libp2p struct { ListenAddresses []string AnnounceAddresses []string NoAnnounceAddresses []string BootstrapPeers []string ProtectedPeers []string ConnMgrLow uint ConnMgrHigh uint ConnMgrGrace Duration } type Pubsub struct { Bootstrapper bool DirectPeers []string IPColocationWhitelist []string RemoteTracer string } type Chainstore struct { EnableSplitstore bool Splitstore Splitstore } type Splitstore struct { ColdStoreType string HotStoreType string MarkSetType string } // // Full Node type Metrics struct { Nickname string HeadNotifs bool } type Client struct { UseIpfs bool IpfsOnlineMode bool IpfsMAddr string IpfsUseForRetrieval bool SimultaneousTransfers uint64 } type Wallet struct { RemoteBackend string EnableLedger bool DisableLocal bool } type FeeConfig struct { DefaultMaxFee types.FIL } func defCommon() Common { return Common{ API: API{ ListenAddress: "/ip4/127.0.0.1/tcp/1234/http", Timeout: Duration(30 * time.Second), }, Libp2p: Libp2p{ ListenAddresses: []string{ "/ip4/0.0.0.0/tcp/0", "/ip6/::/tcp/0", }, AnnounceAddresses: []string{}, NoAnnounceAddresses: []string{}, ConnMgrLow: 150, ConnMgrHigh: 180, ConnMgrGrace: Duration(20 * time.Second), }, Pubsub: Pubsub{ Bootstrapper: false, DirectPeers: nil, RemoteTracer: "/dns4/pubsub-tracer.filecoin.io/tcp/4001/p2p/QmTd6UvR47vUidRNZ1ZKXHrAFhqTJAD27rKL9XYghEKgKX", }, } } var DefaultDefaultMaxFee = types.MustParseFIL("0.07") var DefaultSimultaneousTransfers = uint64(20) // DefaultFullNode returns the default config func DefaultFullNode() *FullNode { return &FullNode{ Common: defCommon(), Fees: FeeConfig{ DefaultMaxFee: DefaultDefaultMaxFee, }, Client: Client{ SimultaneousTransfers: DefaultSimultaneousTransfers, }, Chainstore: Chainstore{ EnableSplitstore: false, Splitstore: Splitstore{ ColdStoreType: "universal", HotStoreType: "badger", MarkSetType: "map", }, }, } } func DefaultStorageMiner() *StorageMiner { cfg := &StorageMiner{ Common: defCommon(), Sealing: SealingConfig{ MaxWaitDealsSectors: 2, // 64G with 32G sectors MaxSealingSectors: 0, MaxSealingSectorsForDeals: 0, WaitDealsDelay: Duration(time.Hour * 6), AlwaysKeepUnsealedCopy: true, FinalizeEarly: false, CollateralFromMinerBalance: false, AvailableBalanceBuffer: types.FIL(big.Zero()), DisableCollateralFallback: false, BatchPreCommits: true, MaxPreCommitBatch: miner5.PreCommitSectorBatchMaxSize, // up to 256 sectors PreCommitBatchWait: Duration(24 * time.Hour), // this should be less than 31.5 hours, which is the expiration of a precommit ticket PreCommitBatchSlack: Duration(3 * time.Hour), // time buffer for forceful batch submission before sectors/deals in batch would start expiring, higher value will lower the chances for message fail due to expiration AggregateCommits: true, MinCommitBatch: miner5.MinAggregatedSectors, // per FIP13, we must have at least four proofs to aggregate, where 4 is the cross over point where aggregation wins out on single provecommit gas costs MaxCommitBatch: miner5.MaxAggregatedSectors, // maximum 819 sectors, this is the maximum aggregation per FIP13 CommitBatchWait: Duration(24 * time.Hour), // this can be up to 30 days CommitBatchSlack: Duration(1 * time.Hour), // time buffer for forceful batch submission before sectors/deals in batch would start expiring, higher value will lower the chances for message fail due to expiration AggregateAboveBaseFee: types.FIL(types.BigMul(types.PicoFil, types.NewInt(150))), // 0.15 nFIL TerminateBatchMin: 1, TerminateBatchMax: 100, TerminateBatchWait: Duration(5 * time.Minute), }, Storage: sectorstorage.SealerConfig{ AllowAddPiece: true, AllowPreCommit1: true, AllowPreCommit2: true, AllowCommit: true, AllowUnseal: true, // Default to 10 - tcp should still be able to figure this out, and // it's the ratio between 10gbit / 1gbit ParallelFetchLimit: 10, // By default use the hardware resource filtering strategy. ResourceFiltering: sectorstorage.ResourceFilteringHardware, }, Dealmaking: DealmakingConfig{ ConsiderOnlineStorageDeals: true, ConsiderOfflineStorageDeals: true, ConsiderOnlineRetrievalDeals: true, ConsiderOfflineRetrievalDeals: true, ConsiderVerifiedStorageDeals: true, ConsiderUnverifiedStorageDeals: true, PieceCidBlocklist: []cid.Cid{}, // TODO: It'd be nice to set this based on sector size MaxDealStartDelay: Duration(time.Hour * 24 * 14), ExpectedSealDuration: Duration(time.Hour * 24), PublishMsgPeriod: Duration(time.Hour), MaxDealsPerPublishMsg: 8, MaxProviderCollateralMultiplier: 2, SimultaneousTransfers: DefaultSimultaneousTransfers, RetrievalPricing: &RetrievalPricing{ Strategy: RetrievalPricingDefaultMode, Default: &RetrievalPricingDefault{ VerifiedDealsFreeTransfer: true, }, External: &RetrievalPricingExternal{ Path: "", }, }, }, Subsystems: MinerSubsystemConfig{ EnableMining: true, EnableSealing: true, EnableSectorStorage: true, EnableMarkets: true, }, Fees: MinerFeeConfig{ MaxPreCommitGasFee: types.MustParseFIL("0.025"), MaxCommitGasFee: types.MustParseFIL("0.05"), MaxPreCommitBatchGasFee: BatchFeeConfig{ Base: types.MustParseFIL("0"), PerSector: types.MustParseFIL("0.02"), }, MaxCommitBatchGasFee: BatchFeeConfig{ Base: types.MustParseFIL("0"), PerSector: types.MustParseFIL("0.03"), // enough for 6 agg and 1nFIL base fee }, MaxTerminateGasFee: types.MustParseFIL("0.5"), MaxWindowPoStGasFee: types.MustParseFIL("5"), MaxPublishDealsFee: types.MustParseFIL("0.05"), MaxMarketBalanceAddFee: types.MustParseFIL("0.007"), }, Addresses: MinerAddressConfig{ PreCommitControl: []string{}, CommitControl: []string{}, TerminateControl: []string{}, DealPublishControl: []string{}, }, } cfg.Common.API.ListenAddress = "/ip4/127.0.0.1/tcp/2345/http" cfg.Common.API.RemoteListenAddress = "127.0.0.1:2345" return cfg } var _ encoding.TextMarshaler = (*Duration)(nil) var _ encoding.TextUnmarshaler = (*Duration)(nil) // Duration is a wrapper type for time.Duration // for decoding and encoding from/to TOML type Duration time.Duration // UnmarshalText implements interface for TOML decoding func (dur *Duration) UnmarshalText(text []byte) error { d, err := time.ParseDuration(string(text)) if err != nil { return err } *dur = Duration(d) return err } func (dur Duration) MarshalText() ([]byte, error) { d := time.Duration(dur) return []byte(d.String()), nil }