Skip to content

Commit 937367b

Browse files
committed
refactor: renterd hosts apis
1 parent 1c94a60 commit 937367b

File tree

17 files changed

+238
-259
lines changed

17 files changed

+238
-259
lines changed

.changeset/early-bobcats-fry.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'renterd': patch
3+
'@siafoundation/renterd-react': patch
4+
---
5+
6+
Fixed a bug optimistically updating last scan information when initiating a host scan.

.changeset/eighty-eagles-taste.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'renterd': minor
3+
---
4+
5+
The hosts explorer now uses the new combined hosts API.

.changeset/fair-carrots-reflect.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@siafoundation/renterd-js': minor
3+
'@siafoundation/renterd-react': minor
4+
'@siafoundation/renterd-types': minor
5+
---
6+
7+
Added the bus list autopilots API.

.changeset/tiny-mails-guess.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@siafoundation/renterd-js': minor
3+
'@siafoundation/renterd-react': minor
4+
'@siafoundation/renterd-types': minor
5+
---
6+
7+
Removed the search hosts and autopilot hosts APIs and added the new combined hosts API.

apps/renterd/contexts/app/useAutopilot.tsx

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
11
import { secondsInMilliseconds } from '@siafoundation/units'
2-
import { useAutopilotState } from '@siafoundation/renterd-react'
2+
import { useAutopilotState, useAutopilots } from '@siafoundation/renterd-react'
33
import { useEffect, useState } from 'react'
44

55
export function useAutopilot() {
6+
// Assume there is only one autopilot.
7+
const autopilots = useAutopilots({
8+
config: {
9+
swr: {
10+
revalidateOnFocus: false,
11+
},
12+
},
13+
})
14+
const id = autopilots.data?.[0]?.id
615
const state = useAutopilotState({
716
config: {
817
swr: {
@@ -31,6 +40,7 @@ export function useAutopilot() {
3140
}, [state])
3241

3342
return {
43+
id: id || 'autopilot',
3444
status,
3545
state,
3646
}

apps/renterd/contexts/hosts/columns.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { format, formatDistance, formatRelative } from 'date-fns'
2121
import { HostContextMenu } from '../../components/Hosts/HostContextMenu'
2222
import { useWorkflows } from '@siafoundation/react-core'
2323
import {
24-
AutopilotHost,
24+
HostItem,
2525
RhpScanPayload,
2626
workerRhpScanRoute,
2727
} from '@siafoundation/renterd-types'
@@ -1079,8 +1079,8 @@ function getFullLabelAndTip(col: HostsTableColumn): {
10791079
}
10801080

10811081
type Key =
1082-
| keyof AutopilotHost['host']['priceTable']
1083-
| keyof AutopilotHost['host']['settings']
1082+
| keyof HostItem['host']['priceTable']
1083+
| keyof HostItem['host']['settings']
10841084

10851085
function makeRenderSc(section: 'priceTable' | 'settings', name: Key) {
10861086
return memo(function RenderPriceTableNumber({ data }: { data: HostData }) {

apps/renterd/contexts/hosts/dataset.ts

+62-79
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,25 @@ import BigNumber from 'bignumber.js'
33
import { HostData } from './types'
44
import { Host } from '@siafoundation/renterd-types'
55
import {
6-
useAutopilotHostsSearch,
76
useHostsAllowlist,
87
useHostsBlocklist,
9-
useHostsSearch,
8+
useHosts,
109
} from '@siafoundation/renterd-react'
1110
import { ContractData } from '../contracts/types'
12-
import { useApp } from '../app'
1311
import { SiaCentralHost } from '@siafoundation/sia-central-types'
1412

1513
export function useDataset({
16-
autopilotStatus,
17-
regularResponse,
18-
autopilotResponse,
14+
response,
1915
allContracts,
16+
autopilotID,
2017
allowlist,
2118
blocklist,
2219
isAllowlistActive,
2320
geoHosts,
2421
onHostSelect,
2522
}: {
26-
autopilotStatus: ReturnType<typeof useApp>['autopilot']['status']
27-
regularResponse: ReturnType<typeof useHostsSearch>
28-
autopilotResponse: ReturnType<typeof useAutopilotHostsSearch>
23+
response: ReturnType<typeof useHosts>
24+
autopilotID: string
2925
allContracts: ContractData[]
3026
allowlist: ReturnType<typeof useHostsAllowlist>
3127
blocklist: ReturnType<typeof useHostsBlocklist>
@@ -34,51 +30,28 @@ export function useDataset({
3430
onHostSelect: (publicKey: string, location?: [number, number]) => void
3531
}) {
3632
return useMemo<HostData[] | null>(() => {
37-
if (autopilotStatus === 'off') {
38-
return (
39-
regularResponse.data?.map((host) => {
40-
const sch = geoHosts.find((gh) => gh.public_key === host.publicKey)
41-
return {
42-
onClick: () => onHostSelect(host.publicKey, sch?.location),
43-
...getHostFields(host, allContracts),
44-
...getAllowedFields({
45-
host,
46-
allowlist: allowlist.data,
47-
blocklist: blocklist.data,
48-
isAllowlistActive,
49-
}),
50-
...getAutopilotFields(),
51-
location: sch?.location,
52-
countryCode: sch?.country_code,
53-
}
54-
}) || null
55-
)
56-
} else if (autopilotStatus === 'on') {
57-
return (
58-
autopilotResponse.data?.map((ah) => {
59-
const sch = geoHosts.find((gh) => gh.public_key === ah.host.publicKey)
60-
return {
61-
onClick: () => onHostSelect(ah.host.publicKey, sch?.location),
62-
...getHostFields(ah.host, allContracts),
63-
...getAllowedFields({
64-
host: ah.host,
65-
allowlist: allowlist.data,
66-
blocklist: blocklist.data,
67-
isAllowlistActive,
68-
}),
69-
...getAutopilotFields(ah.checks),
70-
location: sch?.location,
71-
countryCode: sch?.country_code,
72-
}
73-
}) || null
74-
)
75-
}
76-
return null
33+
return (
34+
response.data?.map((host) => {
35+
const sch = geoHosts.find((gh) => gh.public_key === host.publicKey)
36+
return {
37+
onClick: () => onHostSelect(host.publicKey, sch?.location),
38+
...getHostFields(host, allContracts),
39+
...getAllowedFields({
40+
host,
41+
allowlist: allowlist.data,
42+
blocklist: blocklist.data,
43+
isAllowlistActive,
44+
}),
45+
...getAutopilotFields(host.checks?.[autopilotID]),
46+
location: sch?.location,
47+
countryCode: sch?.country_code,
48+
}
49+
}) || null
50+
)
7751
}, [
7852
onHostSelect,
79-
autopilotStatus,
80-
regularResponse.data,
81-
autopilotResponse.data,
53+
autopilotID,
54+
response.data,
8255
allContracts,
8356
allowlist.data,
8457
blocklist.data,
@@ -159,42 +132,52 @@ function getAllowedFields({
159132
}
160133

161134
function getAutopilotFields(ahc?: {
162-
score: number
163-
gougingBreakdown: {
164-
contractErr?: string
165-
downloadErr?: string
166-
gougingErr?: string
167-
uploadErr?: string
168-
}
169-
gouging: boolean
170-
scoreBreakdown: {
135+
score: {
171136
age: number
172137
collateral: number
173138
interactions: number
174-
prices: number
175139
storageRemaining: number
140+
prices: number
176141
uptime: number
177142
version: number
178143
}
179-
unusableReasons: string[]
180-
usable: boolean
144+
gouging: {
145+
contractErr?: string
146+
downloadErr?: string
147+
gougingErr?: string
148+
uploadErr?: string
149+
pruneErr?: string
150+
}
151+
usability: {
152+
blocked: boolean
153+
gouging: boolean
154+
lowScore: boolean
155+
notAcceptingContracts: boolean
156+
notAnnounced: boolean
157+
notCompletingScan: boolean
158+
offline: boolean
159+
redundantIP: boolean
160+
}
181161
}) {
182162
return {
183-
score: new BigNumber(ahc?.score || 0),
184-
scoreBreakdown: {
185-
age: new BigNumber(ahc?.scoreBreakdown.age || 0),
186-
collateral: new BigNumber(ahc?.scoreBreakdown.collateral || 0),
187-
interactions: new BigNumber(ahc?.scoreBreakdown.interactions || 0),
188-
prices: new BigNumber(ahc?.scoreBreakdown.prices || 0),
189-
storageRemaining: new BigNumber(
190-
ahc?.scoreBreakdown.storageRemaining || 0
191-
),
192-
uptime: new BigNumber(ahc?.scoreBreakdown.uptime || 0),
193-
version: new BigNumber(ahc?.scoreBreakdown.version || 0),
194-
},
195-
gougingBreakdown: ahc?.gougingBreakdown || {},
163+
score: ahc
164+
? {
165+
age: new BigNumber(ahc?.score.age || 0),
166+
collateral: new BigNumber(ahc?.score.collateral || 0),
167+
interactions: new BigNumber(ahc?.score.interactions || 0),
168+
prices: new BigNumber(ahc?.score.prices || 0),
169+
storageRemaining: new BigNumber(ahc?.score.storageRemaining || 0),
170+
uptime: new BigNumber(ahc?.score.uptime || 0),
171+
version: new BigNumber(ahc?.score.version || 0),
172+
}
173+
: undefined,
174+
isGouging: ahc
175+
? Object.values(ahc.gouging || {}).some((v) => v)
176+
: undefined,
177+
isUsable: ahc
178+
? Object.values(ahc.usability || {}).every((v) => !v)
179+
: undefined,
196180
gouging: ahc?.gouging,
197-
unusableReasons: ahc?.unusableReasons || [],
198-
usable: ahc?.usable,
181+
usability: ahc?.usability,
199182
}
200183
}

apps/renterd/contexts/hosts/index.tsx

+9-40
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ import {
66
truncate,
77
} from '@siafoundation/design-system'
88
import {
9-
HostsSearchFilterMode,
9+
HostsFilterMode,
1010
HostsUsabilityMode,
1111
} from '@siafoundation/renterd-types'
1212
import {
13-
useAutopilotHostsSearch,
1413
useHostsAllowlist,
1514
useHostsBlocklist,
16-
useHostsSearch,
15+
useHosts as useHostsSearch,
1716
} from '@siafoundation/renterd-react'
1817
import {
1918
createContext,
@@ -66,43 +65,18 @@ function useHostsMain() {
6665
return keyIn.length ? keyIn : undefined
6766
}, [filters, allContracts])
6867

69-
const autopilotResponse = useAutopilotHostsSearch({
70-
disabled:
71-
// prevents an extra fetch when allContracts is null
72-
(filters.find((f) => f.id === 'hasActiveContracts') && !allContracts) ||
73-
autopilot.status !== 'on',
68+
const response = useHostsSearch({
7469
payload: {
70+
autopilotID: autopilot.id,
7571
limit,
7672
offset,
7773
usabilityMode: (filters.find((f) => f.id === 'usabilityMode')?.value ||
7874
'all') as HostsUsabilityMode,
7975
filterMode: (filters.find((f) => f.id === 'filterMode')?.value ||
80-
'all') as HostsSearchFilterMode,
76+
'all') as HostsFilterMode,
8177
addressContains: filters.find((f) => f.id === 'addressContains')?.value,
8278
keyIn,
8379
},
84-
config: {
85-
swr: {
86-
// before autopilot is configured this will repeatedly 500
87-
errorRetryInterval: 20_000,
88-
refreshInterval: defaultDatasetRefreshInterval,
89-
},
90-
},
91-
})
92-
93-
const regularResponse = useHostsSearch({
94-
disabled: autopilot.status !== 'off',
95-
payload: {
96-
limit,
97-
offset,
98-
filterMode: (filters.find((f) => f.id === 'filterMode')?.value ||
99-
'all') as HostsSearchFilterMode,
100-
addressContains: filters.find((f) => f.id === 'addressContains')?.value,
101-
keyIn:
102-
filters.find((f) => f.id === 'hasActiveContracts') && allContracts
103-
? allContracts.map((c) => c.hostKey)
104-
: undefined,
105-
},
10680
config: {
10781
swr: {
10882
refreshInterval: defaultDatasetRefreshInterval,
@@ -197,10 +171,9 @@ function useHostsMain() {
197171
)
198172

199173
const dataset = useDataset({
200-
autopilotStatus: autopilot.status,
201-
autopilotResponse,
202-
regularResponse,
174+
response,
203175
allContracts,
176+
autopilotID: autopilot.id,
204177
allowlist,
205178
blocklist,
206179
isAllowlistActive,
@@ -236,12 +209,8 @@ function useHostsMain() {
236209
[enabledColumns]
237210
)
238211

239-
const isValidating =
240-
autopilot.status === 'on'
241-
? autopilotResponse.isValidating
242-
: regularResponse.isValidating
243-
const error =
244-
autopilot.status === 'on' ? autopilotResponse.error : regularResponse.error
212+
const isValidating = response.isValidating
213+
const error = response.error
245214
const dataState = useDatasetEmptyState(dataset, isValidating, error, filters)
246215

247216
const siascanUrl = useSiascanUrl()

0 commit comments

Comments
 (0)