upload

package
v1.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 11, 2021 License: Apache-2.0, MIT Imports: 47 Imported by: 0

Documentation

Index

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 NewFileStatus(contracts []*guardpb.Contract, configuration *config.Config,
	renterId string, fileHash string, fileSize int64) (*guardpb.FileStoreStatus, error)

func RenterSignGuardContract

func RenterSignGuardContract(rss *sessions.RenterSession, params *ContractParams, offlineSigning bool,
	rp *RepairParams) ([]byte,
	error)

func ResumeWaitUploadOnSigning

func ResumeWaitUploadOnSigning(rss *sessions.RenterSession) error

func Submit

func Submit(rss *sessions.RenterSession, fileSize int64, offlineSigning bool) 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 ContractParams struct {
	ContractId    string
	RenterPid     string
	HostPid       string
	ShardIndex    int32
	ShardHash     string
	ShardSize     int64
	FileHash      string
	StartTime     time.Time
	StorageLength int64
	Price         int64
	TotalPay      int64
}

type Count

type Count struct{}

func (*Count) Count

func (h *Count) Count(ds datastore.Datastore, peerId string, status guardpb.Contract_ContractState) (int, error)

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 RepairContractParams struct {
	FileHash             string
	FileSize             int64
	RepairPid            string
	LostShardHashes      []string
	RepairRewardAmount   int64
	DownloadRewardAmount int64
}

type RepairParams

type RepairParams struct {
	RenterStart time.Time
	RenterEnd   time.Time
}

type Res

type Res struct {
	ID string
}

type ShardStatus

type ShardStatus struct {
	ContractID     string
	Price          int64
	Host           string
	Status         string
	Message        string
	AdditionalInfo string
}

type StatusRes

type StatusRes struct {
	Status         string
	Message        string
	AdditionalInfo string
	FileHash       string
	Shards         map[string]*ShardStatus
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL