@@ -2,20 +2,25 @@ package settings
2
2
3
3
import (
4
4
"crypto/ed25519"
5
- "crypto/tls"
6
5
"errors"
7
6
"fmt"
8
7
"net"
8
+ "strconv"
9
9
"strings"
10
10
"sync"
11
11
"time"
12
12
13
13
"go.sia.tech/core/consensus"
14
+ proto2 "go.sia.tech/core/rhp/v2"
15
+ proto3 "go.sia.tech/core/rhp/v3"
14
16
"go.sia.tech/core/types"
15
17
"go.sia.tech/hostd/alerts"
18
+ "go.sia.tech/hostd/build"
16
19
"go.sia.tech/hostd/internal/threadgroup"
20
+ rhp2 "go.sia.tech/hostd/rhp/v2"
17
21
"go.uber.org/zap"
18
22
"golang.org/x/time/rate"
23
+ "lukechampine.com/frand"
19
24
)
20
25
21
26
const (
@@ -67,6 +72,11 @@ type (
67
72
BroadcastV2TransactionSet (types.ChainIndex , []types.V2Transaction )
68
73
}
69
74
75
+ // Storage provides information about the host's storage capacity
76
+ Storage interface {
77
+ Usage () (used , total uint64 , _ error )
78
+ }
79
+
70
80
// A Wallet manages Siacoins and funds transactions
71
81
Wallet interface {
72
82
Address () types.Address
@@ -135,9 +145,10 @@ type (
135
145
a Alerts
136
146
log * zap.Logger
137
147
138
- chain ChainManager
139
- syncer Syncer
140
- wallet Wallet
148
+ chain ChainManager
149
+ syncer Syncer
150
+ storage Storage
151
+ wallet Wallet
141
152
142
153
mu sync.Mutex // guards the following fields
143
154
settings Settings // in-memory cache of the host's settings
@@ -150,7 +161,7 @@ type (
150
161
lastIPv4 net.IP
151
162
lastIPv6 net.IP
152
163
153
- rhp3WSTLS * tls. Config
164
+ rhp3Port uint16
154
165
155
166
tg * threadgroup.ThreadGroup
156
167
}
@@ -258,18 +269,138 @@ func (m *ConfigManager) BandwidthLimiters() (ingress, egress *rate.Limiter) {
258
269
return m .ingressLimit , m .egressLimit
259
270
}
260
271
272
+ // AcceptingContracts returns true if the host is currently accepting contracts
273
+ func (m * ConfigManager ) AcceptingContracts () bool {
274
+ s := m .Settings ()
275
+ return s .AcceptingContracts
276
+ }
277
+
278
+ // RHP2Settings returns the host's current RHP2 settings
279
+ func (m * ConfigManager ) RHP2Settings () (proto2.HostSettings , error ) {
280
+ usedSectors , totalSectors , err := m .storage .Usage ()
281
+ if err != nil {
282
+ return proto2.HostSettings {}, fmt .Errorf ("failed to get storage usage: %w" , err )
283
+ }
284
+ settings := m .Settings ()
285
+
286
+ return proto2.HostSettings {
287
+ // build info
288
+ Release : "hostd " + build .Version (),
289
+ // protocol version
290
+ Version : rhp2 .Version ,
291
+
292
+ // host info
293
+ Address : m .wallet .Address (),
294
+ SiaMuxPort : strconv .FormatUint (uint64 (m .rhp3Port ), 10 ),
295
+ NetAddress : settings .NetAddress ,
296
+ TotalStorage : totalSectors * proto2 .SectorSize ,
297
+ RemainingStorage : (totalSectors - usedSectors ) * proto2 .SectorSize ,
298
+
299
+ // network defaults
300
+ MaxDownloadBatchSize : rhp2 .DefaultBatchSize ,
301
+ MaxReviseBatchSize : rhp2 .DefaultBatchSize ,
302
+ SectorSize : proto2 .SectorSize ,
303
+ WindowSize : settings .WindowSize ,
304
+
305
+ // contract formation
306
+ AcceptingContracts : settings .AcceptingContracts ,
307
+ MaxDuration : settings .MaxContractDuration ,
308
+ ContractPrice : settings .ContractPrice ,
309
+
310
+ // rpc prices
311
+ BaseRPCPrice : settings .BaseRPCPrice ,
312
+ SectorAccessPrice : settings .SectorAccessPrice ,
313
+ Collateral : settings .StoragePrice .Mul64 (uint64 (settings .CollateralMultiplier * 1000 )).Div64 (1000 ),
314
+ MaxCollateral : settings .MaxCollateral ,
315
+ StoragePrice : settings .StoragePrice ,
316
+ DownloadBandwidthPrice : settings .EgressPrice ,
317
+ UploadBandwidthPrice : settings .IngressPrice ,
318
+
319
+ // ea settings
320
+ MaxEphemeralAccountBalance : settings .MaxAccountBalance ,
321
+ EphemeralAccountExpiry : settings .AccountExpiry ,
322
+
323
+ RevisionNumber : settings .Revision ,
324
+ }, nil
325
+ }
326
+
327
+ // RHP3PriceTable returns the host's current RHP3 price table
328
+ func (m * ConfigManager ) RHP3PriceTable () (proto3.HostPriceTable , error ) {
329
+ settings := m .Settings ()
330
+
331
+ fee := m .chain .RecommendedFee ()
332
+ currentHeight := m .chain .TipState ().Index .Height
333
+ oneHasting := types .NewCurrency64 (1 )
334
+
335
+ return proto3.HostPriceTable {
336
+ UID : frand .Entropy128 (),
337
+ HostBlockHeight : currentHeight ,
338
+ Validity : settings .PriceTableValidity ,
339
+
340
+ // ephemeral account costs
341
+ AccountBalanceCost : oneHasting ,
342
+ FundAccountCost : oneHasting ,
343
+ UpdatePriceTableCost : oneHasting ,
344
+
345
+ // MDM costs
346
+ HasSectorBaseCost : oneHasting ,
347
+ MemoryTimeCost : oneHasting ,
348
+ DropSectorsBaseCost : oneHasting ,
349
+ DropSectorsUnitCost : oneHasting ,
350
+ SwapSectorBaseCost : oneHasting ,
351
+
352
+ ReadBaseCost : settings .SectorAccessPrice ,
353
+ ReadLengthCost : oneHasting ,
354
+ WriteBaseCost : settings .SectorAccessPrice ,
355
+ WriteLengthCost : oneHasting ,
356
+ WriteStoreCost : settings .StoragePrice ,
357
+ InitBaseCost : settings .BaseRPCPrice ,
358
+
359
+ // bandwidth costs
360
+ DownloadBandwidthCost : settings .EgressPrice ,
361
+ UploadBandwidthCost : settings .IngressPrice ,
362
+
363
+ // LatestRevisionCost is set to a reasonable base + the estimated
364
+ // bandwidth cost of downloading a filecontract. This isn't perfect but
365
+ // at least scales a bit as the host updates their download bandwidth
366
+ // prices.
367
+ LatestRevisionCost : settings .BaseRPCPrice .Add (settings .EgressPrice .Mul64 (2048 )),
368
+
369
+ // Contract Formation/Renewal related fields
370
+ ContractPrice : settings .ContractPrice ,
371
+ CollateralCost : settings .StoragePrice .Mul64 (uint64 (settings .CollateralMultiplier * 1000 )).Div64 (1000 ),
372
+ MaxCollateral : settings .MaxCollateral ,
373
+ MaxDuration : settings .MaxContractDuration ,
374
+ WindowSize : settings .WindowSize ,
375
+ RenewContractCost : types .Siacoins (100 ).Div64 (1e9 ),
376
+
377
+ // Registry related fields.
378
+ RegistryEntriesLeft : 0 ,
379
+ RegistryEntriesTotal : 0 ,
380
+
381
+ // Subscription related fields.
382
+ SubscriptionMemoryCost : oneHasting ,
383
+ SubscriptionNotificationCost : oneHasting ,
384
+
385
+ // TxnFee related fields.
386
+ TxnFeeMinRecommended : fee .Div64 (3 ),
387
+ TxnFeeMaxRecommended : fee ,
388
+ }, nil
389
+ }
390
+
261
391
// NewConfigManager initializes a new config manager
262
- func NewConfigManager (hostKey types.PrivateKey , store Store , cm ChainManager , s Syncer , wm Wallet , opts ... Option ) (* ConfigManager , error ) {
392
+ func NewConfigManager (hostKey types.PrivateKey , store Store , cm ChainManager , s Syncer , sm Storage , wm Wallet , opts ... Option ) (* ConfigManager , error ) {
263
393
m := & ConfigManager {
264
394
announceInterval : 144 * 90 , // 90 days
265
395
validateNetAddress : true ,
266
396
hostKey : hostKey ,
267
397
initialSettings : DefaultSettings ,
268
398
269
- store : store ,
270
- chain : cm ,
271
- syncer : s ,
272
- wallet : wm ,
399
+ store : store ,
400
+ chain : cm ,
401
+ syncer : s ,
402
+ storage : sm ,
403
+ wallet : wm ,
273
404
274
405
log : zap .NewNop (),
275
406
a : alerts .NewNop (),
@@ -279,8 +410,7 @@ func NewConfigManager(hostKey types.PrivateKey, store Store, cm ChainManager, s
279
410
ingressLimit : rate .NewLimiter (rate .Inf , defaultBurstSize ),
280
411
egressLimit : rate .NewLimiter (rate .Inf , defaultBurstSize ),
281
412
282
- // rhp3 WebSocket TLS
283
- rhp3WSTLS : & tls.Config {},
413
+ rhp3Port : 9983 ,
284
414
}
285
415
286
416
for _ , opt := range opts {
0 commit comments