Documentation ¶
Index ¶
- Variables
- func NewContractRequest(rss *sessions.RenterSession, signedContracts []*escrowpb.SignedEscrowContract, ...) (*escrowpb.EscrowContractRequest, error)
- func NewFileStatus(contracts []*guardpb.Contract, configuration *config.Config, renterId string, ...) (*guardpb.FileStoreStatus, error)
- func RenterSignGuardContract(rss *sessions.RenterSession, params *ContractParams, offlineSigning bool, ...) ([]byte, error)
- func ResumeWaitUploadOnSigning(rss *sessions.RenterSession) error
- func Submit(rss *sessions.RenterSession, fileSize int64, offlineSigning bool) error
- func UploadShard(rss *sessions.RenterSession, hp helper.IHostsProvider, price int64, ...)
- type ContractParams
- type Count
- type HostManager
- type ICount
- type RepairContractParams
- type RepairParams
- type Res
- type ShardStatus
- type StatusRes
Constants ¶
This section is empty.
Variables ¶
View Source
var HostRepairResponseCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Host responds to repair jobs.", ShortDescription: ` This command enquires the repairer with the contract, if agrees with the contract after negotiation, returns the repairer's signed contract to the invoker.`, }, Arguments: []cmds.Argument{ cmds.StringArg("file-hash", true, false, "File hash for the host prepares to repair."), cmds.StringArg("repair-shard-hash", true, false, "Shard hash for the host prepares to repair."), cmds.StringArg("file-size", true, false, "Size of the repair file."), cmds.StringArg("download-reward-amount", true, false, "Reward amount for download workload."), cmds.StringArg("repair-reward-amount", true, false, "Reward amount for repair workload."), }, RunTimeout: 1 * time.Minute, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { ctxParams, err := uh.ExtractContextParams(req, env) repairId := ctxParams.N.Identity.Pretty() fileHash := req.Arguments[0] if requestFileHash == fileHash { return fmt.Errorf("file {%s} has been repairing on the host {%s}", fileHash, repairId) } requestFileHash = fileHash lostShardHashes := strings.Split(req.Arguments[1], ",") fileSize, err := strconv.ParseInt(req.Arguments[2], 10, 64) if err != nil { log.Errorf("file size parse error: [%v]", err) return err } downloadRewardAmount, err := strconv.ParseInt(req.Arguments[3], 10, 64) if err != nil { log.Errorf("download reward amount parse error: [%v]", err) return err } repairRewardAmount, err := strconv.ParseInt(req.Arguments[4], 10, 64) if err != nil { log.Errorf("repair reward amount parse error: [%v]", err) return err } err = emptyCheck(fileHash, lostShardHashes, fileSize, downloadRewardAmount, repairRewardAmount) if err != nil { log.Errorf("required field is empty: [%v]", err) return err } if !ctxParams.Cfg.Experimental.StorageHostEnabled { return fmt.Errorf("storage host api not enabled") } if !ctxParams.Cfg.Experimental.HostRepairEnabled { return fmt.Errorf("storage repair api not enabled") } sizeStat, err := corerepo.RepoSize(req.Context, ctxParams.N) if err != nil { return err } remainStorage := sizeStat.StorageMax - sizeStat.RepoSize if fileSize > int64(remainStorage) { errMsg := fmt.Sprintf("remaining storage space [%d] is less than required storage size [%d]", remainStorage, fileSize) log.Errorf(errMsg) return fmt.Errorf(errMsg) } ns, err := helper.GetHostStorageConfig(ctxParams.Ctx, ctxParams.N) if err != nil { log.Errorf("get host storage config error: [%v]", err) return err } var price uint64 if ns.RepairCustomizedPricing { price = ns.RepairPriceCustomized } else { price = ns.RepairPriceDefault } totalPrice := uint64(float64(fileSize) / float64(units.GiB) * float64(price)) if totalPrice <= 0 { totalPrice = 1 } if totalPrice > uint64(repairRewardAmount) { errMsg := fmt.Sprintf("host desired price [%d] is greater than request price [%d]", totalPrice, repairRewardAmount) log.Errorf(errMsg) return fmt.Errorf(errMsg) } err = doRepair(ctxParams, &RepairContractParams{ FileHash: fileHash, FileSize: fileSize, RepairPid: repairId, LostShardHashes: lostShardHashes, RepairRewardAmount: repairRewardAmount, DownloadRewardAmount: downloadRewardAmount, }) if err != nil { log.Errorf("repair job failed for peer id [%s]: [%v]", repairId, err) return err } log.Info("repair lost shards done", zap.String("peerId", ctxParams.N.Identity.Pretty())) return nil }, }
View Source
var (
ShardErrChanMap = cmap.New()
)
View Source
var StorageDcRepairRouterCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Interact with Host repair requests and responses for negotiation of decentralized shards repair.", ShortDescription: ` Guard broadcasts repair request to potential nodes, after negotiation, nodes prepare the contracts for such repair job, sign and send to the guard for confirmation `, }, Subcommands: map[string]*cmds.Command{ "request": hostRepairRequestCmd, "response": HostRepairResponseCmd, }, }
View Source
var StorageUploadCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Store files on BTFS network nodes through BTT payment.", ShortDescription: ` By default, BTFS selects hosts based on overall score according to the current client's environment. To upload a file, <file-hash> must refer to a reed-solomon encoded file. To create a reed-solomon encoded file from a normal file: $ btfs add --chunker=reed-solomon <file> added <file-hash> <file> Run command to upload: $ btfs storage upload <file-hash> To custom upload and storage a file on specific hosts: Use -m with 'custom' mode, and put host identifiers in -s, with multiple hosts separated by ','. # Upload a file to a set of hosts # Total # of hosts (N) must match # of shards in the first DAG level of root file hash $ btfs storage upload <file-hash> -m=custom -s=<host1-peer-id>,<host2-peer-id>,...,<hostN-peer-id> # Upload specific shards to a set of hosts # Total # of hosts (N) must match # of shards given $ btfs storage upload <shard-hash1> <shard-hash2> ... <shard-hashN> -l -m=custom -s=<host1-peer-id>,<host2-peer-id>,...,<hostN-peer-id> Use status command to check for completion: $ btfs storage upload status <session-id> | jq`, }, Subcommands: map[string]*cmds.Command{ "init": StorageUploadInitCmd, "recvcontract": StorageUploadRecvContractCmd, "status": StorageUploadStatusCmd, "repair": StorageUploadRepairCmd, "getcontractbatch": offline.StorageUploadGetContractBatchCmd, "signcontractbatch": offline.StorageUploadSignContractBatchCmd, "getunsigned": offline.StorageUploadGetUnsignedCmd, "sign": offline.StorageUploadSignCmd, }, Arguments: []cmds.Argument{ cmds.StringArg("file-hash", true, false, "Hash of file to upload."), cmds.StringArg("upload-peer-id", false, false, "Peer id when upload upload."), cmds.StringArg("upload-nonce-ts", false, false, "Nounce timestamp when upload upload."), cmds.StringArg("upload-signature", false, false, "Session signature when upload upload."), }, Options: []cmds.Option{ cmds.Int64Option(uploadPriceOptionName, "p", "Max price per GiB per day of storage in µBTT (=0.000001BTT)."), cmds.IntOption(replicationFactorOptionName, "r", "Replication factor for the file with erasure coding built-in.").WithDefault(defaultRepFactor), cmds.StringOption(hostSelectModeOptionName, "m", "Based on this mode to select hosts and upload automatically. Default: mode set in config option Experimental.HostsSyncMode."), cmds.StringOption(hostSelectionOptionName, "s", "Use only these selected hosts in order on 'custom' mode. Use ',' as delimiter."), cmds.BoolOption(testOnlyOptionName, "t", "Enable host search under all domains 0.0.0.0 (useful for local test)."), cmds.IntOption(storageLengthOptionName, "len", "File storage period on hosts in days.").WithDefault(defaultStorageLength), cmds.BoolOption(customizedPayoutOptionName, "Enable file storage customized payout schedule.").WithDefault(false), cmds.IntOption(customizedPayoutPeriodOptionName, "Period of customized payout schedule.").WithDefault(1), }, RunTimeout: 15 * time.Minute, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { ssId := uuid.New().String() ctxParams, err := helper.ExtractContextParams(req, env) if err != nil { return err } renterId := ctxParams.N.Identity offlineSigning := false if len(req.Arguments) > 1 { if len(req.Arguments) < 4 { return fmt.Errorf("not enough arguments, expect: %v, actual:%v", 4, len(req.Arguments)) } renterId, err = peer.IDB58Decode(req.Arguments[1]) if err != nil { return err } offlineSigning = true } err = backoff.Retry(func() error { peersLen := len(ctxParams.N.PeerHost.Network().Peers()) if peersLen <= 0 { err = errors.New("failed to find any peer in table") log.Error(err) return err } return nil }, helper.WaitingForPeersBo) fileHash := req.Arguments[0] shardHashes, fileSize, shardSize, err := helper.GetShardHashes(ctxParams, fileHash) if err != nil { return err } price, storageLength, err := helper.GetPriceAndMinStorageLength(ctxParams) if err != nil { return err } hp := helper.GetHostsProvider(ctxParams, make([]string, 0)) if mode, ok := req.Options[hostSelectModeOptionName].(string); ok { var hostIDs []string if mode == "custom" { if hosts, ok := req.Options[hostSelectionOptionName].(string); ok { hostIDs = strings.Split(hosts, ",") } if len(hostIDs) != len(shardHashes) { return fmt.Errorf("custom mode hosts length must match shard hashes length") } hp = helper.GetCustomizedHostsProvider(ctxParams, hostIDs) } } rss, err := sessions.GetRenterSession(ctxParams, ssId, fileHash, shardHashes) if err != nil { return err } if offlineSigning { offNonceTimestamp, err := strconv.ParseUint(req.Arguments[2], 10, 64) if err != nil { return err } err = rss.SaveOfflineMeta(&renterpb.OfflineMeta{ OfflinePeerId: req.Arguments[1], OfflineNonceTs: offNonceTimestamp, OfflineSignature: req.Arguments[3], }) if err != nil { return err } } shardIndexes := make([]int, 0) for i, _ := range rss.ShardHashes { shardIndexes = append(shardIndexes, i) } UploadShard(rss, hp, price, shardSize, storageLength, offlineSigning, renterId, fileSize, shardIndexes, nil) seRes := &Res{ ID: ssId, } return res.Emit(seRes) }, Type: Res{}, }
View Source
var StorageUploadInitCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Initialize storage handshake with inquiring client.", ShortDescription: ` Storage host opens this endpoint to accept incoming upload/storage requests, If current host is interested and all validation checks out, host downloads the shard and replies back to client for the next challenge step.`, }, Arguments: []cmds.Argument{ cmds.StringArg("session-id", true, false, "ID for the entire storage upload session."), cmds.StringArg("file-hash", true, false, "Root file storage node should fetch (the DAG)."), cmds.StringArg("shard-hash", true, false, "Shard the storage node should fetch."), cmds.StringArg("price", true, false, "Per GiB per day in µBTT (=0.000001BTT) for storing this shard offered by client."), cmds.StringArg("escrow-contract", true, false, "Client's initial escrow contract data."), cmds.StringArg("guard-contract-meta", true, false, "Client's initial guard contract meta."), cmds.StringArg("storage-length", true, false, "Store file for certain length in days."), cmds.StringArg("shard-size", true, false, "Size of each shard received in bytes."), cmds.StringArg("shard-index", true, false, "Index of shard within the encoding scheme."), cmds.StringArg("upload-peer-id", false, false, "Peer id when upload sign is used."), }, RunTimeout: 5 * time.Minute, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { ctxParams, err := uh.ExtractContextParams(req, env) if err != nil { return err } if !ctxParams.Cfg.Experimental.StorageHostEnabled { return fmt.Errorf("storage host api not enabled") } hm := NewHostManager(ctxParams.Cfg) shardSize, err := strconv.ParseInt(req.Arguments[7], 10, 64) if err != nil { return err } accept, err := hm.AcceptContract(ctxParams.N.Repo.Datastore(), ctxParams.N.Identity.String(), shardSize) if err != nil { return err } if !accept { return errors.New("too many initialized contracts") } price, err := strconv.ParseInt(req.Arguments[3], 10, 64) if err != nil { return err } settings, err := helper.GetHostStorageConfig(ctxParams.Ctx, ctxParams.N) if err != nil { return err } if uint64(price) < settings.StoragePriceAsk { return fmt.Errorf("price invalid: want: >=%d, got: %d", settings.StoragePriceAsk, price) } requestPid, ok := remote.GetStreamRequestRemotePeerID(req, ctxParams.N) if !ok { return fmt.Errorf("fail to get peer ID from request") } storeLen, err := strconv.Atoi(req.Arguments[6]) if err != nil { return err } if uint64(storeLen) < settings.StorageTimeMin { return fmt.Errorf("storage length invalid: want: >=%d, got: %d", settings.StorageTimeMin, storeLen) } ssId := req.Arguments[0] shardHash := req.Arguments[2] shardIndex, err := strconv.Atoi(req.Arguments[8]) if err != nil { return err } halfSignedEscrowContString := req.Arguments[4] halfSignedGuardContString := req.Arguments[5] var halfSignedGuardContBytes []byte halfSignedGuardContBytes = []byte(halfSignedGuardContString) halfSignedGuardContract := &guardpb.Contract{} err = proto.Unmarshal(halfSignedGuardContBytes, halfSignedGuardContract) if err != nil { return err } guardContractMeta := halfSignedGuardContract.ContractMeta pid, ok := remote.GetStreamRequestRemotePeerID(req, ctxParams.N) if !ok { return fmt.Errorf("fail to get peer ID from request") } var peerId string if peerId = pid.String(); len(req.Arguments) >= 10 { peerId = req.Arguments[9] } payerPubKey, err := crypto.GetPubKeyFromPeerId(peerId) if err != nil { return err } s := halfSignedGuardContract.GetRenterSignature() if s == nil { s = halfSignedGuardContract.GetPreparerSignature() } ok, err = crypto.Verify(payerPubKey, &guardContractMeta, s) if !ok || err != nil { return fmt.Errorf("can't verify guard contract: %v", err) } var signedEscrowContractBytes []byte if halfSignedEscrowContString != "" { var halfSignedEscrowContBytes []byte halfSignedEscrowContBytes = []byte(halfSignedEscrowContString) halfSignedEscrowContract := &escrowpb.SignedEscrowContract{} err = proto.Unmarshal(halfSignedEscrowContBytes, halfSignedEscrowContract) if err != nil { return err } escrowContract := halfSignedEscrowContract.GetContract() ok, err = crypto.Verify(payerPubKey, escrowContract, halfSignedEscrowContract.GetBuyerSignature()) if !ok || err != nil { return fmt.Errorf("can't verify escrow contract: %v", err) } storageLength := guardContractMeta.RentEnd.Sub(guardContractMeta.RentStart).Hours() / 24 totalPay := uh.TotalPay(guardContractMeta.ShardFileSize, guardContractMeta.Price, int(storageLength)) if escrowContract.Amount != guardContractMeta.Amount || totalPay != guardContractMeta.Amount { return errors.New("invalid contract") } signedEscrowContractBytes, err = signEscrowContractAndMarshal(escrowContract, halfSignedEscrowContract, ctxParams.N.PrivateKey) if err != nil { return err } } signedGuardContract, err := signGuardContract(&guardContractMeta, halfSignedGuardContract, ctxParams.N.PrivateKey) if err != nil { return err } signedGuardContractBytes, err := proto.Marshal(signedGuardContract) if err != nil { return err } go func() { tmp := func() error { shard, err := sessions.GetHostShard(ctxParams, signedGuardContract.ContractId) if err != nil { return err } _, err = remote.P2PCall(ctxParams.Ctx, ctxParams.N, ctxParams.Api, requestPid, "/storage/upload/recvcontract", ssId, shardHash, shardIndex, signedEscrowContractBytes, signedGuardContractBytes, ) if err != nil { return err } signedContractID, err := signContractID(signedGuardContract.ContractId, ctxParams.N.PrivateKey) if err != nil { return err } if halfSignedEscrowContString != "" { paidIn := make(chan bool) go checkPaymentFromClient(ctxParams, paidIn, signedContractID) paid := <-paidIn if !paid { return fmt.Errorf("contract is not paid: %s", signedGuardContract.ContractId) } } tmp := new(guardpb.Contract) err = proto.Unmarshal(signedGuardContractBytes, tmp) if err != nil { return err } err = shard.Contract(signedEscrowContractBytes, tmp) if err != nil { return err } fileHash := req.Arguments[1] err = downloadShardFromClient(ctxParams, halfSignedGuardContract, fileHash, shardHash) if err != nil { return err } err = challengeShard(ctxParams, fileHash, false, &guardContractMeta) if err != nil { return err } if err := shard.Complete(); err != nil { return err } return nil }() if tmp != nil { log.Debug(tmp) } }() return nil }, }
View Source
var StorageUploadRecvContractCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "For renter client to receive half signed contracts.", }, Arguments: []cmds.Argument{ cmds.StringArg("session-id", true, false, "Session ID which renter uses to storage all shards information."), cmds.StringArg("shard-hash", true, false, "Shard the storage node should fetch."), cmds.StringArg("shard-index", true, false, "Index of shard within the encoding scheme."), cmds.StringArg("escrow-contract", true, false, "Signed Escrow contract."), cmds.StringArg("guard-contract", true, false, "Signed Guard contract."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { contractId, err := doRecv(req, env) if contractId != "" { if ch, ok := ShardErrChanMap.Get(contractId); ok { go func() { ch.(chan error) <- err }() } if err != nil { return err } } return nil }, }
View Source
var StorageUploadRepairCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Repair specific shards of a file.", ShortDescription: ` This command repairs the given shards of a file.`, }, Arguments: []cmds.Argument{ cmds.StringArg("file-hash", true, false, "Hash of file to upload."), cmds.StringArg("repair-shards", true, false, "Shard hashes to repair."), cmds.StringArg("renter-pid", true, false, "Original renter peer ID."), cmds.StringArg("blacklist", true, false, "Blacklist of hosts during upload."), }, RunTimeout: 5 * time.Minute, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { ctxParams, err := uh.ExtractContextParams(req, env) if err != nil { return err } fileHash := req.Arguments[0] metaReq := &guardpb.CheckFileStoreMetaRequest{ FileHash: fileHash, RenterPid: ctxParams.N.Identity.String(), RequesterPid: ctxParams.N.Identity.String(), RequestTime: time.Now().UTC(), } sig, err := crypto.Sign(ctxParams.N.PrivateKey, metaReq) if err != nil { return err } metaReq.Signature = sig ctx, _ := helper.NewGoContext(req.Context) var meta *guardpb.FileStoreStatus err = grpc.GuardClient(ctxParams.Cfg.Services.GuardDomain).WithContext(ctx, func(ctx context.Context, client guardpb.GuardServiceClient) error { meta, err = client.CheckFileStoreMeta(ctx, metaReq) if err != nil { return err } return nil }) if err != nil { return err } contracts := meta.Contracts if len(contracts) <= 0 { return errors.New("length of contracts is 0") } ssId, _ := uh.SplitContractId(contracts[0].ContractId) shardIndexes := make([]int, 0) i := 0 shardHashes := strings.Split(req.Arguments[1], ",") for _, contract := range contracts { if contract.ShardHash == shardHashes[i] { shardIndexes = append(shardIndexes, int(contract.ShardIndex)) i++ } } rss, err := sessions.GetRenterSession(ctxParams, ssId, fileHash, shardHashes) if err != nil { return err } hp := uh.GetHostsProvider(ctxParams, strings.Split(req.Arguments[3], ",")) m := contracts[0].ContractMeta renterPid, err := peer.IDB58Decode(req.Arguments[2]) if err != nil { return err } UploadShard(rss, hp, m.Price, m.ShardFileSize, -1, false, renterPid, -1, shardIndexes, &RepairParams{ RenterStart: m.RentStart, RenterEnd: m.RentEnd, }) seRes := &Res{ ID: ssId, } return res.Emit(seRes) }, Type: Res{}, }
View Source
var StorageUploadStatusCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Check storage upload and payment status (From client's perspective).", ShortDescription: ` This command print upload and payment status by the time queried.`, }, Arguments: []cmds.Argument{ cmds.StringArg("session-id", true, false, "ID for the entire storage upload session.").EnableStdin(), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { status := &StatusRes{} ssId := req.Arguments[0] ctxParams, err := helper.ExtractContextParams(req, env) if err != nil { return err } if !ctxParams.Cfg.Experimental.StorageClientEnabled && !ctxParams.Cfg.Experimental.StorageHostEnabled { return fmt.Errorf("storage client/host api not enabled") } session, err := sessions.GetRenterSession(ctxParams, ssId, "", make([]string, 0)) if err != nil { return err } sessionStatus, err := session.Status() if err != nil { return err } status.Status = sessionStatus.Status status.Message = sessionStatus.Message info, err := session.GetAdditionalInfo() if err == nil { status.AdditionalInfo = info.Info } else { } shards := make(map[string]*ShardStatus) status.FileHash = session.Hash fullyCompleted := true for i, h := range session.ShardHashes { shard, err := sessions.GetRenterShard(ctxParams, ssId, h, i) if err != nil { return err } st, err := shard.Status() if err != nil { return err } contracts, err := shard.Contracts() if err != nil { return err } additionalInfo, err := shard.GetAdditionalInfo() if err != nil && err != datastore.ErrNotFound { return err } switch additionalInfo.Info { case guardpb.Contract_UPLOADED.String(), guardpb.Contract_CANCELED.String(), guardpb.Contract_CLOSED.String(): default: fullyCompleted = false } c := &ShardStatus{ ContractID: "", Price: 0, Host: "", Status: st.Status, Message: st.Message, AdditionalInfo: additionalInfo.Info, } if contracts.SignedGuardContract != nil { c.ContractID = contracts.SignedGuardContract.ContractId c.Price = contracts.SignedGuardContract.Price c.Host = contracts.SignedGuardContract.HostPid } shards[sessions.GetShardId(ssId, h, i)] = c } if (status.Status == sessions.RssWaitUploadReqSignedStatus || status.Status == sessions.RssCompleteStatus) && !fullyCompleted { if err := grpc.GuardClient(ctxParams.Cfg.Services.GuardDomain). WithContext(req.Context, func(ctx context.Context, client guardpb.GuardServiceClient) error { req := &guardpb.CheckFileStoreMetaRequest{ FileHash: session.Hash, RenterPid: session.PeerId, RequesterPid: session.CtxParams.N.Identity.String(), RequestTime: time.Now(), } sig, err := crypto.Sign(ctxParams.N.PrivateKey, req) if err != nil { return err } req.Signature = sig meta, err := client.CheckFileStoreMeta(ctx, req) if err != nil { return err } for _, c := range meta.Contracts { shards[sessions.GetShardId(ssId, c.ShardHash, int(c.ShardIndex))].AdditionalInfo = c.State.String() } return nil }); err != nil { log.Debug(err) } } status.Shards = shards if len(status.Shards) == 0 && status.Status == sessions.RssInitStatus { status.Message = "session not found" } return res.Emit(status) }, Type: StatusRes{}, }
Functions ¶
func NewContractRequest ¶
func NewContractRequest(rss *sessions.RenterSession, signedContracts []*escrowpb.SignedEscrowContract, totalPrice int64, offlineSigning bool) (*escrowpb.EscrowContractRequest, error)
func NewFileStatus ¶
func RenterSignGuardContract ¶
func RenterSignGuardContract(rss *sessions.RenterSession, params *ContractParams, offlineSigning bool, rp *RepairParams) ([]byte, error)
func ResumeWaitUploadOnSigning ¶
func ResumeWaitUploadOnSigning(rss *sessions.RenterSession) error
func UploadShard ¶
func UploadShard(rss *sessions.RenterSession, hp helper.IHostsProvider, price int64, shardSize int64, storageLength int, offlineSigning bool, renterId peer.ID, fileSize int64, shardIndexes []int, rp *RepairParams)
Types ¶
type ContractParams ¶
type HostManager ¶
type HostManager struct {
// contains filtered or unexported fields
}
func NewHostManager ¶
func NewHostManager(cfg *config.Config) *HostManager
func (*HostManager) AcceptContract ¶
func (h *HostManager) AcceptContract(ds datastore.Datastore, peerId string, shardSize int64) (bool, error)
type ICount ¶
type ICount interface {
Count(ds datastore.Datastore, peerId string, status guardpb.Contract_ContractState) (int, error)
}
type RepairContractParams ¶
type ShardStatus ¶
Click to show internal directories.
Click to hide internal directories.