/
types.go
475 lines (399 loc) · 15.8 KB
/
types.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
// Copyright 2019 DxChain, All rights reserved.
// Use of this source code is governed by an Apache
// License 2.0 that can be found in the LICENSE file.
package storage
import (
"errors"
"fmt"
"reflect"
"time"
"github.com/DxChainNetwork/godx/common"
"github.com/DxChainNetwork/godx/common/hexutil"
"github.com/DxChainNetwork/godx/core/types"
"github.com/DxChainNetwork/godx/internal/ethapi"
"github.com/DxChainNetwork/godx/p2p/enode"
"github.com/DxChainNetwork/godx/rpc"
"github.com/DxChainNetwork/godx/storage/storageclient/erasurecode"
)
var (
// ENV define the program running environment: test, prod
ENV = EnvProd
// DefaultMinSectors define the default minimum sectors needed to recovery
DefaultMinSectors uint32 = 1
// DefaultNumSectors define the default total sectors needed to recovery
DefaultNumSectors uint32 = 2
)
// Defines the download mode
const (
Override = iota
Append
Normal
)
const (
// EnvProd marks the production execution environment
EnvProd = "prod"
// EnvTest marks the test execution environment
EnvTest = "test"
// DxFileExt is the extension of DxFile
DxFileExt = ".dxfile"
// ConfigVersion is the version of host config
ConfigVersion = "1.0.1"
)
type (
// HostIntConfig make group of host setting as object
HostIntConfig struct {
AcceptingContracts bool `json:"acceptingContracts"`
MaxDownloadBatchSize uint64 `json:"maxDownloadBatchSize"`
MaxDuration uint64 `json:"maxDuration"`
MaxReviseBatchSize uint64 `json:"maxReviseBatchSize"`
WindowSize uint64 `json:"windowSize"`
PaymentAddress common.Address `json:"paymentAddress"`
Deposit common.BigInt `json:"deposit"`
DepositBudget common.BigInt `json:"depositBudget"`
MaxDeposit common.BigInt `json:"maxDeposit"`
BaseRPCPrice common.BigInt `json:"baseRPCPrice"`
ContractPrice common.BigInt `json:"contractPrice"`
DownloadBandwidthPrice common.BigInt `json:"downloadBandwidthPrice"`
SectorAccessPrice common.BigInt `json:"sectorAccessPrice"`
StoragePrice common.BigInt `json:"storagePrice"`
UploadBandwidthPrice common.BigInt `json:"uploadBandwidthPrice"`
}
// HostIntConfigForDisplay is the host internal config for displayed
HostIntConfigForDisplay struct {
AcceptingContracts string `json:"acceptingContracts"`
MaxDownloadBatchSize string `json:"maxDownloadBatchSize"`
MaxDuration string `json:"maxDuration"`
MaxReviseBatchSize string `json:"maxReviseBatchSize"`
WindowSize string `json:"windowSize"`
PaymentAddress string `json:"paymentAddress"`
Deposit string `json:"deposit"`
DepositBudget string `json:"depositBudget"`
MaxDeposit string `json:"maxDeposit"`
BaseRPCPrice string `json:"baseRPCPrice"`
ContractPrice string `json:"contractPrice"`
DownloadBandwidthPrice string `json:"downloadBandwidthPrice"`
SectorAccessPrice string `json:"sectorAccessPrice"`
StoragePrice string `json:"storagePrice"`
UploadBandwidthPrice string `json:"uploadBandwidthPrice"`
}
// HostExtConfig make group of host setting to broadcast as object
HostExtConfig struct {
AcceptingContracts bool `json:"acceptingContracts"`
MaxDownloadBatchSize uint64 `json:"maxDownloadBatchSize"`
MaxDuration uint64 `json:"maxDuration"`
MaxReviseBatchSize uint64 `json:"maxReviseBatchSize"`
PaymentAddress common.Address `json:"paymentAddress"`
RemainingStorage uint64 `json:"remainingStorage"`
SectorSize uint64 `json:"sectorSize"`
TotalStorage uint64 `json:"totalStorage"`
WindowSize uint64 `json:"windowSize"`
Deposit common.BigInt `json:"deposit"`
MaxDeposit common.BigInt `json:"maxDeposit"`
BaseRPCPrice common.BigInt `json:"baseRPCPrice"`
ContractPrice common.BigInt `json:"contractPrice"`
DownloadBandwidthPrice common.BigInt `json:"downloadBandwidthPrice"`
SectorAccessPrice common.BigInt `json:"sectorAccessPrice"`
StoragePrice common.BigInt `json:"storagePrice"`
UploadBandwidthPrice common.BigInt `json:"uploadBandwidthPrice"`
Version string `json:"version"`
}
// HostInfo storage storage host information
HostInfo struct {
HostExtConfig
FirstSeen uint64 `json:"firstseen"`
// TODO: refactor this into an interface: host interactions
SuccessfulInteractionFactor float64 `json:"successfulInteractionFactor"`
FailedInteractionFactor float64 `json:"FailedInteractionFactor"`
LastInteractionTime uint64 `json:"lastInteractionTime"`
InteractionRecords []HostInteractionRecord `json:"interactionRecords"`
// TODO: refactor this into an interface: host scans
AccumulatedUptime float64 `json:"accumulated_uptime"`
AccumulatedDowntime float64 `json:"accumulated_downtime"`
LastCheckTime uint64 `json:"last_check_time"`
ScanRecords HostPoolScans `json:"scan_records"`
// IP will be decoded from the enode URL
IP string `json:"ip"`
IPNetwork string `json:"ip_network"`
LastIPNetWorkChange time.Time `json:"last_ipnetwork_change"`
EnodeID enode.ID `json:"enodeid"`
EnodeURL string `json:"enodeurl"`
NodePubKey []byte `json:"nodepubkey"`
Filtered bool `json:"filtered"`
}
// HostPoolScans stores a list of host pool scan records
HostPoolScans []HostPoolScan
// HostPoolScan recorded the scan details, including the time a storage host got scanned
// and whether the host is online or not
HostPoolScan struct {
Timestamp time.Time `json:"timestamp"`
Success bool `json:"success"`
}
// HostInteractionRecord is the interaction record for client-host interactions
// which is used in hostManager
HostInteractionRecord struct {
Time time.Time `json:"time"`
InteractionType string `json:"interactionType"`
Success bool `json:"success"`
}
// MarketPrice is the market price metrics from HostMarket
MarketPrice struct {
ContractPrice common.BigInt
StoragePrice common.BigInt
UploadPrice common.BigInt
DownloadPrice common.BigInt
Deposit common.BigInt
MaxDeposit common.BigInt
}
)
// ContractParams is the drafted contract sent by the storage client.
type ContractParams struct {
RentPayment RentPayment
HostEnodeURL string
Funding common.BigInt
StartHeight uint64
EndHeight uint64
ClientPaymentAddress common.Address
Host HostInfo
}
// RentPayment stores the StorageClient payment settings for renting the storage space from the host
type RentPayment struct {
Fund common.BigInt `json:"fund"`
StorageHosts uint64 `json:"storageHosts"`
Period uint64 `json:"period"`
// ExpectedStorage is amount of data expected to be stored
ExpectedStorage uint64 `json:"expectedStorage"`
// ExpectedUpload is expected amount of data upload before redundancy / block
ExpectedUpload uint64 `json:"expectedUpload"`
// ExpectedDownload is expected amount of data downloaded / block
ExpectedDownload uint64 `json:"expectedDownload"`
// ExpectedRedundancy is the average redundancy of files uploaded
ExpectedRedundancy float64 `json:"expectedRedundancy"`
}
// ClientSetting defines the settings that client used to create contract with other peers,
// where EnableIPViolation specifies if the host with same network IP addresses will be filtered
// out or not
type ClientSetting struct {
RentPayment RentPayment `json:"rentPayment"`
EnableIPViolation bool `json:"enableIPViolation"`
MaxUploadSpeed int64 `json:"maxUploadSpeed"`
MaxDownloadSpeed int64 `json:"maxDownloadSpeed"`
}
type (
// RentPaymentAPIDisplay is used for API Configurations Display
RentPaymentAPIDisplay struct {
Fund string `json:"Fund"`
StorageHosts string `json:"Number of Storage Hosts"`
Period string `json:"Storage Time"`
// ExpectedStorage is amount of data expected to be stored
ExpectedStorage string `json:"Expected Storage"`
// ExpectedUpload is expected amount of data upload before redundancy / block
ExpectedUpload string `json:"Expected Upload"`
// ExpectedDownload is expected amount of data downloaded / block
ExpectedDownload string `json:"Expected Download"`
// ExpectedRedundancy is the average redundancy of files uploaded
ExpectedRedundancy string `json:"Expected Redundancy"`
}
// ClientSettingAPIDisplay is used for API Configurations Display
ClientSettingAPIDisplay struct {
RentPayment RentPaymentAPIDisplay `json:"RentPayment Setting"`
EnableIPViolation string `json:"IP Violation Check Status"`
MaxUploadSpeed string `json:"Max Upload Speed"`
MaxDownloadSpeed string `json:"Max Download Speed"`
}
)
type (
// ContractID is used to define the contract ID data type
ContractID common.Hash
// ContractStatus is used to define the contract status data type. There
// are three status in total: able to upload, able to renew, and if the contract
// has been canceled
ContractStatus struct {
UploadAbility bool
RenewAbility bool
Canceled bool
}
// ContractMetaData defines read-only detailed contract information
ContractMetaData struct {
ID ContractID
EnodeID enode.ID
LatestContractRevision types.StorageContractRevision
StartHeight uint64
EndHeight uint64
ContractBalance common.BigInt
UploadCost common.BigInt
DownloadCost common.BigInt
StorageCost common.BigInt
// contract available fund
TotalCost common.BigInt
GasCost common.BigInt
ContractFee common.BigInt
Status ContractStatus
}
// PeriodCost specifies cost storage client needs to pay within one
// period cycle. It includes cost for all contracts
PeriodCost struct {
// ContractFees = ContractFee + GasFee
ContractFees common.BigInt `json:"contractFees"`
UploadCost common.BigInt `json:"uploadCost"`
DownloadCost common.BigInt `json:"downloadCost"`
StorageCost common.BigInt `json:"storageCost"`
PrevContractCost common.BigInt `json:"prevContractCost"`
ContractFund common.BigInt `json:"contractFund"`
UnspentFund common.BigInt `json:"unspentFund"`
WithheldFund common.BigInt `json:"withheldFund"`
WithheldFundReleaseBlock uint64 `json:"withheldFundReleaseBlock"`
}
)
// String method is used to convert the contractID into string format
func (ci ContractID) String() string {
return hexutil.Encode(ci[:])
}
// StringToContractID convert string to ContractID
func StringToContractID(s string) (id ContractID, err error) {
// decode the string to byte slice
decodedString, err := hexutil.Decode(s)
if err != nil {
err = fmt.Errorf("failed to convert the string %s back to contractID: %s", s, err.Error())
return
}
// convert the byte slice to ContractID
copy(id[:], decodedString)
return
}
type (
// FileUploadParams contains the information used by the Client to upload a file
FileUploadParams struct {
Source string
DxPath DxPath
ErasureCode erasurecode.ErasureCoder
Mode int
}
// UploadFileInfo provides information about a file
UploadFileInfo struct {
AccessTime time.Time `json:"accessTime"`
Available bool `json:"available"`
ChangeTime time.Time `json:"changeTime"`
CipherType string `json:"cipherType"`
CreateTime time.Time `json:"createTime"`
Expiration uint64 `json:"expiration"`
FileSize uint64 `json:"fileSize"`
Health float64 `json:"health"`
LocalPath string `json:"localPath"`
MaxHealth float64 `json:"maxHealth"`
MaxHealthPercent float64 `json:"maxHealthPercent"`
ModTime time.Time `json:"modTime"`
NumStuckChunks uint64 `json:"numStuckChunks"`
OnDisk bool `json:"onDisk"`
Recoverable bool `json:"recoverable"`
Redundancy float64 `json:"redundancy"`
Renewing bool `json:"renewing"`
DxPath string `json:"dxpath"`
Stuck bool `json:"stuck"`
StuckHealth float64 `json:"stuckHealth"`
UploadedBytes uint64 `json:"uploadedBytes"`
UploadProgress float64 `json:"uploadProgress"`
}
// DirectoryInfo provides information about a dxdir
DirectoryInfo struct {
NumFiles uint64 `json:"numFiles"`
TotalSize uint64 `json:"totalSize"`
Health uint32 `json:"health"`
StuckHealth uint32 `json:"stuckHealth"`
MinRedundancy uint32 `json:"minRedundancy"`
TimeLastHealthCheck time.Time `json:"timeLastHealthCheck"`
TimeModify time.Time `json:"timeModify"`
NumStuckSegments uint32 `json:"numStuckSegments"`
DxPath DxPath `json:"dxPath"`
}
// HostHealthInfo is the file structure used for DxFile health update.
// It has two fields, one indicating whether the host if offline or not,
// One indicating whether the contract with the host is good for renew.
HostHealthInfo struct {
Offline bool
GoodForRenew bool
}
// HostHealthInfoTable is the map the is passed into DxFile health update.
// It is a map from host id to HostHealthInfo
HostHealthInfoTable map[enode.ID]HostHealthInfo
// FileInfo is the structure containing file info to be displayed
FileInfo struct {
DxPath string `json:"dxpath"`
Status string `json:"status"`
SourcePath string `json:"sourcePath"`
FileSize uint64 `json:"fileSize"`
Redundancy uint32 `json:"redundancy"`
StoredOnDisk bool `json:"storedOnDisk"`
UploadProgress float64 `json:"uploadProgress"`
}
// FileBriefInfo is the brief info about a DxFile
FileBriefInfo struct {
Path string `json:"dxpath"`
Status string `json:"status"`
UploadProgress float64 `json:"uploadProgress"`
}
)
type (
// HostFolder is the host folder structure
HostFolder struct {
Path string `json:"path"`
TotalSectors uint64 `json:"totalSectors"`
UsedSectors uint64 `json:"usedSectors"`
}
// HostSpace is the
HostSpace struct {
TotalSectors uint64 `json:"totalSectors"`
UsedSectors uint64 `json:"usedSectors"`
FreeSectors uint64 `json:"freeSectors"`
}
)
const (
// SectorSize is 4 MB
SectorSize = uint64(1 << 22)
// HashSize is 32 bits
HashSize = 32
// SegmentSize is the segment size is used when taking the Merkle root of a file.
SegmentSize = 64
)
// ParsedAPI will parse the APIs saved in the Ethereum
// and get the ones needed
type ParsedAPI struct {
NetInfo *ethapi.PublicNetAPI
Account *ethapi.PrivateAccountAPI
EthInfo *ethapi.PublicEthereumAPI
StorageTx *ethapi.PrivateStorageContractTxAPI
}
// FilterAPIs will filter the APIs saved in the Ethereum and
// save them into ParsedAPI data structure
func FilterAPIs(apis []rpc.API, parseAPI *ParsedAPI) error {
for _, api := range apis {
switch typ := reflect.TypeOf(api.Service); typ {
case reflect.TypeOf(ðapi.PublicNetAPI{}):
netAPI := api.Service.(*ethapi.PublicNetAPI)
if netAPI == nil {
return errors.New("failed to acquire netInfo information")
}
parseAPI.NetInfo = netAPI
case reflect.TypeOf(ðapi.PrivateAccountAPI{}):
accountAPI := api.Service.(*ethapi.PrivateAccountAPI)
if accountAPI == nil {
return errors.New("failed to acquire account information")
}
parseAPI.Account = accountAPI
case reflect.TypeOf(ðapi.PublicEthereumAPI{}):
ethAPI := api.Service.(*ethapi.PublicEthereumAPI)
if ethAPI == nil {
return errors.New("failed to acquire eth information")
}
parseAPI.EthInfo = ethAPI
case reflect.TypeOf(ðapi.PrivateStorageContractTxAPI{}):
storageTx := api.Service.(*ethapi.PrivateStorageContractTxAPI)
if storageTx == nil {
return errors.New("failed to acquire storage tx sending API")
}
parseAPI.StorageTx = storageTx
default:
continue
}
}
return nil
}