Skip to content

Commit

Permalink
refactor(renterd): migrate hosts apis
Browse files Browse the repository at this point in the history
  • Loading branch information
alexfreska committed Sep 17, 2024
1 parent 4737ed2 commit 3bb9752
Show file tree
Hide file tree
Showing 23 changed files with 375 additions and 279 deletions.
6 changes: 6 additions & 0 deletions .changeset/early-bobcats-fry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'renterd': patch
'@siafoundation/renterd-react': patch
---

Fixed a bug optimistically updating last scan information when initiating a host scan.
5 changes: 5 additions & 0 deletions .changeset/eighty-eagles-taste.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'renterd': minor
---

The hosts explorer now uses the new combined hosts API.
7 changes: 7 additions & 0 deletions .changeset/fair-carrots-reflect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@siafoundation/renterd-js': minor
'@siafoundation/renterd-react': minor
'@siafoundation/renterd-types': minor
---

Added the bus list autopilots API.
7 changes: 7 additions & 0 deletions .changeset/late-onions-hammer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@siafoundation/renterd-js': minor
'@siafoundation/renterd-react': minor
'@siafoundation/renterd-types': minor
---

Added new combined hosts API.
7 changes: 7 additions & 0 deletions .changeset/tiny-mails-guess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@siafoundation/renterd-js': minor
'@siafoundation/renterd-react': minor
'@siafoundation/renterd-types': minor
---

Removed deprecated search hosts and autopilot hosts APIs.
25 changes: 25 additions & 0 deletions apps/renterd-e2e/src/specs/hosts.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { test, expect } from '@playwright/test'
import { navigateToHosts } from '../fixtures/navigate'
import { afterTest, beforeTest } from '../fixtures/beforeTest'
import { getHostRowByIndex } from '../fixtures/hosts'

test.beforeEach(async ({ page }) => {
await beforeTest(page, {
hostdCount: 3,
})
})

test.afterEach(async () => {
await afterTest()
})

test('hosts explorer shows all hosts', async ({ page }) => {
await navigateToHosts({ page })

const row1 = await getHostRowByIndex(page, 0)
const row2 = await getHostRowByIndex(page, 1)
const row3 = await getHostRowByIndex(page, 2)
await expect(row1).toBeVisible()
await expect(row2).toBeVisible()
await expect(row3).toBeVisible()
})
6 changes: 3 additions & 3 deletions apps/renterd/contexts/config/useOnValid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { transformUp } from './transformUp'
import { delay, useMutate } from '@siafoundation/react-core'
import { Resources } from './resources'
import { useSyncContractSet } from './useSyncContractSet'
import { autopilotHostsRoute } from '@siafoundation/renterd-types'
import { busHostsRoute } from '@siafoundation/renterd-types'

export function useOnValid({
resources,
Expand Down Expand Up @@ -133,9 +133,9 @@ export function useOnValid({
if (firstTimeSettingConfig) {
const refreshHostsAfterDelay = async () => {
await delay(5_000)
mutate((key) => key.startsWith(autopilotHostsRoute))
mutate((key) => key.startsWith(busHostsRoute))
await delay(5_000)
mutate((key) => key.startsWith(autopilotHostsRoute))
mutate((key) => key.startsWith(busHostsRoute))
}
refreshHostsAfterDelay()
}
Expand Down
21 changes: 10 additions & 11 deletions apps/renterd/contexts/hosts/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import { format, formatDistance, formatRelative } from 'date-fns'
import { HostContextMenu } from '../../components/Hosts/HostContextMenu'
import { useWorkflows } from '@siafoundation/react-core'
import {
AutopilotHost,
HostPriceTable,
HostSettings,
RhpScanPayload,
workerRhpScanRoute,
} from '@siafoundation/renterd-types'
Expand Down Expand Up @@ -135,15 +136,15 @@ export const columns: HostsTableColumn[] = (
return (
<Tooltip
side="right"
content={data.usable ? 'Host is usable' : 'Host is not usable'}
content={data.isUsable ? 'Host is usable' : 'Host is not usable'}
>
<div className="flex gap-2 items-center">
<div className="mt-[5px]">
<Text
aria-label={data.usable ? 'usable' : 'not usable'}
color={data.usable ? 'green' : 'red'}
aria-label={data.isUsable ? 'usable' : 'not usable'}
color={data.isUsable ? 'green' : 'red'}
>
{data.usable ? (
{data.isUsable ? (
<CheckboxCheckedFilled16 />
) : (
<WarningSquareFilled16 />
Expand Down Expand Up @@ -182,15 +183,15 @@ export const columns: HostsTableColumn[] = (
<Tooltip
side="right"
content={
data.gouging
data.isGouging
? 'Host is price gouging'
: 'Host is not price gouging'
}
>
<div className="flex gap-2 items-center">
<div className="mt-[5px]">
<Text color={!data.gouging ? 'subtle' : 'red'}>
{!data.gouging ? (
<Text color={!data.isGouging ? 'subtle' : 'red'}>
{!data.isGouging ? (
<UndefinedFilled16 />
) : (
<WarningSquareFilled16 />
Expand Down Expand Up @@ -1078,9 +1079,7 @@ function getFullLabelAndTip(col: HostsTableColumn): {
}
}

type Key =
| keyof AutopilotHost['host']['priceTable']
| keyof AutopilotHost['host']['settings']
type Key = keyof HostPriceTable | keyof HostSettings

function makeRenderSc(section: 'priceTable' | 'settings', name: Key) {
return memo(function RenderPriceTableNumber({ data }: { data: HostData }) {
Expand Down
188 changes: 122 additions & 66 deletions apps/renterd/contexts/hosts/dataset.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
import { useMemo } from 'react'
import BigNumber from 'bignumber.js'
import { HostData } from './types'
import { Host } from '@siafoundation/renterd-types'
import { Host, HostAutopilotChecks } from '@siafoundation/renterd-types'
import {
useAutopilotHostsSearch,
useHostsAllowlist,
useHostsBlocklist,
useHostsSearch,
useHosts,
} from '@siafoundation/renterd-react'
import { ContractData } from '../contracts/types'
import { useApp } from '../app'
import { SiaCentralHost } from '@siafoundation/sia-central-types'
import { objectEntries } from '@siafoundation/design-system'

export function useDataset({
autopilotStatus,
regularResponse,
autopilotResponse,
response,
allContracts,
autopilotID,
allowlist,
blocklist,
isAllowlistActive,
geoHosts,
onHostSelect,
}: {
autopilotStatus: ReturnType<typeof useApp>['autopilot']['status']
regularResponse: ReturnType<typeof useHostsSearch>
autopilotResponse: ReturnType<typeof useAutopilotHostsSearch>
response: ReturnType<typeof useHosts>
autopilotID: string
allContracts: ContractData[]
allowlist: ReturnType<typeof useHostsAllowlist>
blocklist: ReturnType<typeof useHostsBlocklist>
Expand All @@ -34,51 +31,28 @@ export function useDataset({
onHostSelect: (publicKey: string, location?: [number, number]) => void
}) {
return useMemo<HostData[] | null>(() => {
if (autopilotStatus === 'off') {
return (
regularResponse.data?.map((host) => {
const sch = geoHosts.find((gh) => gh.public_key === host.publicKey)
return {
onClick: () => onHostSelect(host.publicKey, sch?.location),
...getHostFields(host, allContracts),
...getAllowedFields({
host,
allowlist: allowlist.data,
blocklist: blocklist.data,
isAllowlistActive,
}),
...getAutopilotFields(),
location: sch?.location,
countryCode: sch?.country_code,
}
}) || null
)
} else if (autopilotStatus === 'on') {
return (
autopilotResponse.data?.map((ah) => {
const sch = geoHosts.find((gh) => gh.public_key === ah.host.publicKey)
return {
onClick: () => onHostSelect(ah.host.publicKey, sch?.location),
...getHostFields(ah.host, allContracts),
...getAllowedFields({
host: ah.host,
allowlist: allowlist.data,
blocklist: blocklist.data,
isAllowlistActive,
}),
...getAutopilotFields(ah.checks),
location: sch?.location,
countryCode: sch?.country_code,
}
}) || null
)
}
return null
return (
response.data?.map((host) => {
const sch = geoHosts.find((gh) => gh.public_key === host.publicKey)
return {
onClick: () => onHostSelect(host.publicKey, sch?.location),
...getHostFields(host, allContracts),
...getAllowedFields({
host,
allowlist: allowlist.data,
blocklist: blocklist.data,
isAllowlistActive,
}),
...getAutopilotFields(host.checks?.[autopilotID]),
location: sch?.location,
countryCode: sch?.country_code,
}
}) || null
)
}, [
onHostSelect,
autopilotStatus,
regularResponse.data,
autopilotResponse.data,
autopilotID,
response.data,
allContracts,
allowlist.data,
blocklist.data,
Expand Down Expand Up @@ -160,25 +134,65 @@ function getAllowedFields({

function getAutopilotFields(ahc?: {
score: number
gougingBreakdown: {
contractErr?: string
downloadErr?: string
gougingErr?: string
uploadErr?: string
}
gouging: boolean
usable: boolean
scoreBreakdown: {
age: number
collateral: number
interactions: number
prices: number
storageRemaining: number
prices: number
uptime: number
version: number
}
gougingBreakdown: {
contractErr?: string
downloadErr?: string
gougingErr?: string
uploadErr?: string
pruneErr?: string
}
usabilityBreakdown: {
blocked: boolean
gouging: boolean
lowScore: boolean
notAcceptingContracts: boolean
notAnnounced: boolean
notCompletingScan: boolean
offline: boolean
redundantIP: boolean
}
}): {
score: BigNumber
scoreBreakdown: {
age: BigNumber
collateral: BigNumber
interactions: BigNumber
prices: BigNumber
storageRemaining: BigNumber
uptime: BigNumber
version: BigNumber
}
isGouging: boolean
isUsable: boolean
gougingBreakdown: {
contractErr?: string
downloadErr?: string
gougingErr?: string
uploadErr?: string
pruneErr?: string
}
usabilityBreakdown: {
blocked: boolean
gouging: boolean
lowScore: boolean
notAcceptingContracts: boolean
notAnnounced: boolean
notCompletingScan: boolean
offline: boolean
redundantIP: boolean
}
unusableReasons: string[]
usable: boolean
}) {
} {
return {
score: new BigNumber(ahc?.score || 0),
scoreBreakdown: {
Expand All @@ -192,9 +206,51 @@ function getAutopilotFields(ahc?: {
uptime: new BigNumber(ahc?.scoreBreakdown.uptime || 0),
version: new BigNumber(ahc?.scoreBreakdown.version || 0),
},
isGouging: Object.values(ahc?.gougingBreakdown || {}).some((v) => v),
isUsable: !!ahc?.usable,
gougingBreakdown: ahc?.gougingBreakdown || {},
gouging: ahc?.gouging,
unusableReasons: ahc?.unusableReasons || [],
usable: ahc?.usable,
usabilityBreakdown: ahc?.usabilityBreakdown || {
blocked: false,
gouging: false,
lowScore: false,
notAcceptingContracts: false,
notAnnounced: false,
notCompletingScan: false,
offline: false,
redundantIP: false,
},
unusableReasons: ahc
? objectEntries(ahc.usabilityBreakdown).reduce((acc, [key, value]) => {
if (value) {
return acc.concat(getUnusableReasonLabel(key))
}
return acc
}, [])
: [],
}
}

function getUnusableReasonLabel(
key: keyof HostAutopilotChecks['usabilityBreakdown']
): string {
switch (key) {
case 'blocked':
return 'Host is blocked'
case 'gouging':
return 'Host is gouging'
case 'lowScore':
return 'Host has low score'
case 'notAcceptingContracts':
return 'Host is not accepting contracts'
case 'notAnnounced':
return 'Host is not announced'
case 'notCompletingScan':
return 'Host is not completing scan'
case 'offline':
return 'Host is offline'
case 'redundantIP':
return 'Host has redundant IP'
default:
return 'Unknown'
}
}
Loading

0 comments on commit 3bb9752

Please sign in to comment.