From cd17f7ba2611ee694c46add33de5c29cfbe9d71e Mon Sep 17 00:00:00 2001 From: Alex Freska Date: Tue, 7 Nov 2023 15:59:19 -0500 Subject: [PATCH] fix: renterd onboarding, host setting --- .changeset/few-steaks-fail.md | 5 + .changeset/funny-crabs-vanish.md | 5 + .changeset/hot-humans-cover.md | 5 + .changeset/itchy-lizards-speak.md | 7 ++ .changeset/tender-crabs-peel.md | 5 + .../components/Files/EmptyState/index.tsx | 11 ++- .../FilesStatsMenu/FilesStatsMenuWarnings.tsx | 96 +------------------ apps/renterd/components/OnboardingBar.tsx | 4 +- apps/renterd/contexts/config/fields.tsx | 22 +++++ apps/renterd/contexts/config/index.tsx | 15 ++- .../renterd/contexts/config/transform.spec.ts | 11 +++ apps/renterd/contexts/config/transform.ts | 2 + apps/renterd/contexts/config/types.ts | 4 +- apps/website/components/HostMap/Globe.tsx | 36 ++++--- libs/design-system/src/components/ValueSc.tsx | 4 +- libs/react-renterd/src/siaTypes.ts | 1 + 16 files changed, 113 insertions(+), 120 deletions(-) create mode 100644 .changeset/few-steaks-fail.md create mode 100644 .changeset/funny-crabs-vanish.md create mode 100644 .changeset/hot-humans-cover.md create mode 100644 .changeset/itchy-lizards-speak.md create mode 100644 .changeset/tender-crabs-peel.md diff --git a/.changeset/few-steaks-fail.md b/.changeset/few-steaks-fail.md new file mode 100644 index 000000000..b354e5e82 --- /dev/null +++ b/.changeset/few-steaks-fail.md @@ -0,0 +1,5 @@ +--- +'renterd': minor +--- + +The maxDowntimeHours setting default value is now 336. diff --git a/.changeset/funny-crabs-vanish.md b/.changeset/funny-crabs-vanish.md new file mode 100644 index 000000000..f73f47e5c --- /dev/null +++ b/.changeset/funny-crabs-vanish.md @@ -0,0 +1,5 @@ +--- +'renterd': minor +--- + +Added support for the minRecentScanFailures autopilot hosts setting. diff --git a/.changeset/hot-humans-cover.md b/.changeset/hot-humans-cover.md new file mode 100644 index 000000000..eeae6b150 --- /dev/null +++ b/.changeset/hot-humans-cover.md @@ -0,0 +1,5 @@ +--- +'website': minor +--- + +The navbar now includes the logo and "sia" as text. diff --git a/.changeset/itchy-lizards-speak.md b/.changeset/itchy-lizards-speak.md new file mode 100644 index 000000000..a31de8463 --- /dev/null +++ b/.changeset/itchy-lizards-speak.md @@ -0,0 +1,7 @@ +--- +'hostd': minor +'renterd': minor +'@siafoundation/design-system': minor +--- + +Extremely small siacoin values will now show as hastings by default rather than 0SC. diff --git a/.changeset/tender-crabs-peel.md b/.changeset/tender-crabs-peel.md new file mode 100644 index 000000000..cb32e1a7c --- /dev/null +++ b/.changeset/tender-crabs-peel.md @@ -0,0 +1,5 @@ +--- +'renterd': minor +--- + +Refined the warnings in the files feature navbar and file explorer empty states. diff --git a/apps/renterd/components/Files/EmptyState/index.tsx b/apps/renterd/components/Files/EmptyState/index.tsx index 96c6c20ee..6ef9378ed 100644 --- a/apps/renterd/components/Files/EmptyState/index.tsx +++ b/apps/renterd/components/Files/EmptyState/index.tsx @@ -1,4 +1,4 @@ -import { LinkButton, Text } from '@siafoundation/design-system' +import { Code, LinkButton, Text } from '@siafoundation/design-system' import { CloudUpload32 } from '@siafoundation/react-icons' import { routes } from '../../../config/routes' import { useFiles } from '../../../contexts/files' @@ -35,12 +35,13 @@ export function EmptyState() {
- Before you can upload files you must configure autopilot. Autopilot - finds contracts with hosts based on the settings you choose. - Autopilot also repairs your data as hosts come and go. + Before you can upload files you must configure your settings. Once + configured, renterd will find contracts with hosts + based on the settings you choose. renterd will also + repair your data as hosts come and go. - Configure autopilot → + Configure
diff --git a/apps/renterd/components/Files/FilesStatsMenu/FilesStatsMenuWarnings.tsx b/apps/renterd/components/Files/FilesStatsMenu/FilesStatsMenuWarnings.tsx index 4d4ca657c..ad2f80658 100644 --- a/apps/renterd/components/Files/FilesStatsMenu/FilesStatsMenuWarnings.tsx +++ b/apps/renterd/components/Files/FilesStatsMenu/FilesStatsMenuWarnings.tsx @@ -1,42 +1,9 @@ -import { Link, Text, Tooltip } from '@siafoundation/design-system' +import { Text, Tooltip } from '@siafoundation/design-system' import { Warning16 } from '@siafoundation/react-icons' -import { useFiles } from '../../../contexts/files' -import { routes } from '../../../config/routes' import { useContractSetMismatch } from '../checks/useContractSetMismatch' -import { useDefaultContractSetNotSet } from '../checks/useDefaultContractSetNotSet' -import { useAutopilotNotConfigured } from '../checks/useAutopilotNotConfigured' -import { useNotEnoughContracts } from '../checks/useNotEnoughContracts' export function FilesStatsMenuWarnings() { - const { dataState, isViewingRootOfABucket, isViewingBuckets } = useFiles() const contractSetMismatch = useContractSetMismatch() - const defaultContractSetNotSet = useDefaultContractSetNotSet() - const autopilotNotConfigured = useAutopilotNotConfigured() - const notEnoughContracts = useNotEnoughContracts() - - // onboard/warn about default contract set - if (defaultContractSetNotSet.active) { - return ( -
- - - - - Configure a default contract set to get started.{' '} - - Configuration → - - -
- ) - } // warn about contract set mismatch if (contractSetMismatch.active) { @@ -65,66 +32,5 @@ export function FilesStatsMenuWarnings() { ) } - const autopilotNotConfiguredViewingBuckets = - autopilotNotConfigured.active && isViewingBuckets - const autopilotNotConfiguredRootDirectory = - autopilotNotConfigured.active && - isViewingRootOfABucket && - dataState !== 'noneYet' - const autopilotNotConfiguredNotRootDirectory = - autopilotNotConfigured.active && !isViewingRootOfABucket - if ( - autopilotNotConfiguredViewingBuckets || - autopilotNotConfiguredRootDirectory || - autopilotNotConfiguredNotRootDirectory - ) { - return ( -
- - - - - Configure autopilot to get started.{' '} - - Autopilot → - - -
- ) - } - - const notEnoughContractsViewingBuckets = - notEnoughContracts.active && isViewingBuckets - const notEnoughContractsRootDirectoryAndExistingFiles = - notEnoughContracts.active && - isViewingRootOfABucket && - dataState !== 'noneYet' - const notEnoughContractsNotRootDirectory = - notEnoughContracts.active && !isViewingRootOfABucket - if ( - notEnoughContractsViewingBuckets || - notEnoughContractsRootDirectoryAndExistingFiles || - notEnoughContractsNotRootDirectory - ) { - return ( -
- - - - - Not enought contracts to upload files. {notEnoughContracts.count}/ - {notEnoughContracts.required} - -
- ) - } - return null } diff --git a/apps/renterd/components/OnboardingBar.tsx b/apps/renterd/components/OnboardingBar.tsx index 64459fc7d..4a493ded8 100644 --- a/apps/renterd/components/OnboardingBar.tsx +++ b/apps/renterd/components/OnboardingBar.tsx @@ -51,7 +51,9 @@ export function OnboardingBar() { return null } - const walletBalance = new BigNumber(wallet.data?.confirmed || 0) + const walletBalance = new BigNumber( + wallet.data ? wallet.data.confirmed + wallet.data.unconfirmed : 0 + ) const allowance = new BigNumber(autopilot.data?.contracts.allowance || 0) const step1Configured = app.autopilot.state.data?.configured diff --git a/apps/renterd/contexts/config/fields.tsx b/apps/renterd/contexts/config/fields.tsx index 0ea009b6d..83dbcaa2c 100644 --- a/apps/renterd/contexts/config/fields.tsx +++ b/apps/renterd/contexts/config/fields.tsx @@ -244,6 +244,28 @@ export function getFields({ } : {}, }, + minRecentScanFailures: { + type: 'number', + category: 'hosts', + title: 'Min recent scan failures', + description: ( + <> + The minimum number of recent scan failures that autopilot will + tolerate. + + ), + units: 'scans', + decimalsLimit: 0, + suggestion: advancedDefaultAutopilot.minRecentScanFailures, + suggestionTip: `Defaults to ${advancedDefaultAutopilot.minRecentScanFailures.toNumber()}.`, + hidden: !isAutopilotEnabled || !showAdvanced, + validation: + isAutopilotEnabled && showAdvanced + ? { + required: 'required', + } + : {}, + }, // wallet defragThreshold: { diff --git a/apps/renterd/contexts/config/index.tsx b/apps/renterd/contexts/config/index.tsx index 4d4d465b5..36ae3862d 100644 --- a/apps/renterd/contexts/config/index.tsx +++ b/apps/renterd/contexts/config/index.tsx @@ -473,17 +473,26 @@ export function useConfigMain() { throw Error(configAppResponse.error) } - triggerSuccessToast('Configuration has been saved.') if (isAutopilotEnabled) { + // Sync default contract set if necessary. Only syncs if the setting + // is enabled in case the user changes in advanced mode and then + // goes back to simple mode. + // Might be simpler nice to just override in simple mode without a + // special setting since this is how other settings like allowance + // behave - but leaving for now. syncDefaultContractSet(finalValues.autopilotContractSet) + + // Trigger the autopilot loop with new settings applied. autopilotTrigger.post({ payload: { - forceScan: false, + forceScan: true, }, }) } - // if autopilot is being configured for the first time, + triggerSuccessToast('Configuration has been saved.') + + // If autopilot is being configured for the first time, // revalidate the empty hosts list. if (firstTimeSettingConfig) { const refreshHostsAfterDelay = async () => { diff --git a/apps/renterd/contexts/config/transform.spec.ts b/apps/renterd/contexts/config/transform.spec.ts index 942ee5c46..184215dc7 100644 --- a/apps/renterd/contexts/config/transform.spec.ts +++ b/apps/renterd/contexts/config/transform.spec.ts @@ -28,6 +28,7 @@ describe('tansforms', () => { hosts: { allowRedundantIPs: false, maxDowntimeHours: 1440, + minRecentScanFailures: 10, scoreOverrides: null, }, contracts: { @@ -75,6 +76,7 @@ describe('tansforms', () => { storageTB: new BigNumber('1'), allowRedundantIPs: false, maxDowntimeHours: new BigNumber('1440'), + minRecentScanFailures: new BigNumber('10'), defragThreshold: new BigNumber('1000'), defaultContractSet: 'myset', uploadPackingEnabled: true, @@ -105,6 +107,7 @@ describe('tansforms', () => { hosts: { allowRedundantIPs: false, maxDowntimeHours: 1440, + minRecentScanFailures: 10, scoreOverrides: null, }, contracts: { @@ -152,6 +155,7 @@ describe('tansforms', () => { storageTB: new BigNumber('1'), allowRedundantIPs: false, maxDowntimeHours: new BigNumber('1440'), + minRecentScanFailures: new BigNumber('10'), defragThreshold: new BigNumber('1000'), defaultContractSet: 'myset', uploadPackingEnabled: true, @@ -188,6 +192,7 @@ describe('tansforms', () => { storageTB: new BigNumber('1'), allowRedundantIPs: false, maxDowntimeHours: new BigNumber('1440'), + minRecentScanFailures: new BigNumber('10'), defragThreshold: new BigNumber('1000'), }, undefined @@ -199,6 +204,7 @@ describe('tansforms', () => { hosts: { allowRedundantIPs: false, maxDowntimeHours: 1440, + minRecentScanFailures: 10, scoreOverrides: null, }, contracts: { @@ -228,6 +234,7 @@ describe('tansforms', () => { storageTB: new BigNumber('1'), allowRedundantIPs: false, maxDowntimeHours: new BigNumber('1440'), + minRecentScanFailures: new BigNumber('10'), defragThreshold: new BigNumber('1000'), }, { @@ -255,6 +262,7 @@ describe('tansforms', () => { foobar: 'value', allowRedundantIPs: false, maxDowntimeHours: 1440, + minRecentScanFailures: 10, scoreOverrides: null, }, contracts: { @@ -303,6 +311,7 @@ describe('tansforms', () => { storageTB: new BigNumber('1'), allowRedundantIPs: false, maxDowntimeHours: new BigNumber('1440'), + minRecentScanFailures: new BigNumber('10'), defragThreshold: new BigNumber('1000'), defaultContractSet: 'myset', uploadPackingEnabled: false, @@ -356,6 +365,7 @@ describe('tansforms', () => { storageTB: new BigNumber('1'), allowRedundantIPs: false, maxDowntimeHours: new BigNumber('1440'), + minRecentScanFailures: new BigNumber('10'), defragThreshold: new BigNumber('1000'), defaultContractSet: 'myset', uploadPackingEnabled: false, @@ -514,6 +524,7 @@ function buildAllResponses() { hosts: { allowRedundantIPs: false, maxDowntimeHours: 1440, + minRecentScanFailures: 10, scoreOverrides: null, }, contracts: { diff --git a/apps/renterd/contexts/config/transform.ts b/apps/renterd/contexts/config/transform.ts index 95eab430a..25f7ab56d 100644 --- a/apps/renterd/contexts/config/transform.ts +++ b/apps/renterd/contexts/config/transform.ts @@ -85,6 +85,7 @@ export function transformUpAutopilot( hosts: { ...existingValues?.hosts, maxDowntimeHours: v.maxDowntimeHours.toNumber(), + minRecentScanFailures: v.minRecentScanFailures.toNumber(), allowRedundantIPs: v.allowRedundantIPs, scoreOverrides: existingValues?.hosts.scoreOverrides || null, }, @@ -241,6 +242,7 @@ export function transformDownAutopilot( // hosts allowRedundantIPs: config.hosts.allowRedundantIPs, maxDowntimeHours: new BigNumber(config.hosts.maxDowntimeHours), + minRecentScanFailures: new BigNumber(config.hosts.minRecentScanFailures), // wallet defragThreshold: new BigNumber(config.wallet.defragThreshold), } diff --git a/apps/renterd/contexts/config/types.ts b/apps/renterd/contexts/config/types.ts index 148316812..88c886d51 100644 --- a/apps/renterd/contexts/config/types.ts +++ b/apps/renterd/contexts/config/types.ts @@ -16,6 +16,7 @@ export const defaultAutopilot = { // hosts allowRedundantIPs: false, maxDowntimeHours: undefined as BigNumber | undefined, + minRecentScanFailures: undefined as BigNumber | undefined, // wallet defragThreshold: undefined as BigNumber | undefined, } @@ -84,7 +85,8 @@ export const advancedDefaultAutopilot: AutopilotData = { amountHosts: new BigNumber(50), autopilotContractSet: 'autopilot', allowRedundantIPs: false, - maxDowntimeHours: new BigNumber(1440), + maxDowntimeHours: new BigNumber(336), + minRecentScanFailures: new BigNumber(10), defragThreshold: new BigNumber(1000), } diff --git a/apps/website/components/HostMap/Globe.tsx b/apps/website/components/HostMap/Globe.tsx index 34c18ad83..96eee6506 100644 --- a/apps/website/components/HostMap/Globe.tsx +++ b/apps/website/components/HostMap/Globe.tsx @@ -11,15 +11,15 @@ import dynamic from 'next/dynamic' import { GlobeMethods } from 'react-globe.gl' import { random, sortBy } from 'lodash' import { getHostLabel } from './utils' -import { Host } from '../../content/geoHosts' +import { SiaCentralPartialHost } from '../../content/geoHosts' import { getAssetUrl } from '../../content/assets' import { useTheme } from 'next-themes' import { useElementSize } from 'usehooks-ts' type Props = { - activeHost: Host + activeHost: SiaCentralPartialHost selectActiveHost: (public_key: string) => void - hosts: Host[] + hosts: SiaCentralPartialHost[] rates: { usd: string } @@ -27,8 +27,8 @@ type Props = { type Route = { distance: number - src: Host - dst: Host + src: SiaCentralPartialHost + dst: SiaCentralPartialHost } const GlobeGl = dynamic(() => import('./GlobeGl'), { @@ -44,7 +44,7 @@ const ReactGlobe = forwardRef(function ReactGlobe( function GlobeComponent({ activeHost, hosts, rates, selectActiveHost }: Props) { const globeEl = useRef(null) - const moveToHost = useCallback((host: Host) => { + const moveToHost = useCallback((host: SiaCentralPartialHost) => { globeEl.current?.pointOfView( { lat: host.location[0] - 8, @@ -175,19 +175,21 @@ function GlobeComponent({ activeHost, hosts, rates, selectActiveHost }: Props) { }} arcsTransitionDuration={0} pointsData={hosts} - pointLat={(h: Host) => h.location[0]} - pointLng={(h: Host) => h.location[1]} - pointLabel={(h: Host) => getHostLabel({ host: h, rates })} + pointLat={(h: SiaCentralPartialHost) => h.location[0]} + pointLng={(h: SiaCentralPartialHost) => h.location[1]} + pointLabel={(h: SiaCentralPartialHost) => + getHostLabel({ host: h, rates }) + } pointAltitude={0} - pointColor={(h: Host) => + pointColor={(h: SiaCentralPartialHost) => h.public_key === activeHost.public_key ? 'rgba(0,255,0,1)' : 'rgba(0,255,0,1)' } - pointRadius={(h: Host) => + pointRadius={(h: SiaCentralPartialHost) => h.public_key === activeHost.public_key ? 0.6 : 0.2 } - onPointClick={(h: Host) => { + onPointClick={(h: SiaCentralPartialHost) => { selectActiveHost(h.public_key) }} pointsMerge={false} @@ -198,14 +200,20 @@ function GlobeComponent({ activeHost, hosts, rates, selectActiveHost }: Props) { export const Globe = memo(GlobeComponent) -function distanceBetweenHosts(h1: Host, h2: Host) { +function distanceBetweenHosts( + h1: SiaCentralPartialHost, + h2: SiaCentralPartialHost +) { return Math.sqrt( Math.pow(h1.location[0] - h2.location[0], 2) + Math.pow(h1.location[1] - h2.location[1], 2) ) } -function doesIncludeActiveHost(route: Route, activeHost: Host) { +function doesIncludeActiveHost( + route: Route, + activeHost: SiaCentralPartialHost +) { return ( route.dst.public_key === activeHost.public_key || route.src.public_key === activeHost.public_key diff --git a/libs/design-system/src/components/ValueSc.tsx b/libs/design-system/src/components/ValueSc.tsx index 5813d0eb4..54e20093f 100644 --- a/libs/design-system/src/components/ValueSc.tsx +++ b/libs/design-system/src/components/ValueSc.tsx @@ -13,6 +13,7 @@ type Props = { tooltip?: string fixed?: number dynamicUnits?: boolean + hastingUnits?: boolean extendedSuffix?: string showTooltip?: boolean } @@ -25,6 +26,7 @@ export function ValueSc({ variant = 'change', fixed = 3, dynamicUnits = true, + hastingUnits = true, extendedSuffix, showTooltip = true, }: Props) { @@ -52,7 +54,7 @@ export function ValueSc({ fixed, dynamicUnits, })}` - : humanSiacoin(value, { fixed, dynamicUnits })} + : humanSiacoin(value, { fixed, dynamicUnits, hastingUnits })} {extendedSuffix ? `${extendedSuffix}` : ''} diff --git a/libs/react-renterd/src/siaTypes.ts b/libs/react-renterd/src/siaTypes.ts index e4e38ff42..06cda247f 100644 --- a/libs/react-renterd/src/siaTypes.ts +++ b/libs/react-renterd/src/siaTypes.ts @@ -346,6 +346,7 @@ export interface AutopilotHostsConfig { allowRedundantIPs: boolean scoreOverrides: { [key: PublicKey]: number } maxDowntimeHours: number + minRecentScanFailures: number } export interface AutopilotContractsConfig {