Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(renterd): remove allowance #808

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/big-sloths-wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@siafoundation/design-system': minor
---

SiacoinField border is no longer blue in readOnly state.
5 changes: 5 additions & 0 deletions .changeset/happy-scissors-approve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@siafoundation/design-system': minor
---

SiacoinField now has a unitsFiatPostfix prop.
5 changes: 5 additions & 0 deletions .changeset/selfish-books-jog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@siafoundation/renterd-types': minor
---

Allowance was removed from autopilot contracts config API.
5 changes: 5 additions & 0 deletions .changeset/silent-llamas-explode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'renterd': minor
---

The allowance fitting and price fitting features were removed.
5 changes: 5 additions & 0 deletions .changeset/sixty-fireants-kick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'renterd': minor
---

The configuration page has a new spending estimate widget that includes an option to rebalance prices within the current estimate.
5 changes: 5 additions & 0 deletions .changeset/wet-planets-pull.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@siafoundation/renterd-types': minor
---

The autopilots key was removed from the pinned settings API.
5 changes: 5 additions & 0 deletions .changeset/wise-rabbits-film.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'renterd': minor
---

The allowance concept was removed.
36 changes: 26 additions & 10 deletions apps/renterd-e2e/src/fixtures/configResetSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ export const configResetAllSettings = step(
await fillTextInputByName(page, 'storageTB', '1')
await fillTextInputByName(page, 'uploadTBMonth', '1')
await fillTextInputByName(page, 'downloadTBMonth', '1')
await setSwitchByLabel(page, 'shouldPinAllowance', true)
await fillTextInputByName(page, 'allowanceMonthPinned', '10')
await setSwitchByLabel(page, 'shouldPinAllowance', false)
await fillTextInputByName(page, 'allowanceMonth', '21000')
await fillTextInputByName(page, 'periodWeeks', '6')
await fillTextInputByName(page, 'renewWindowWeeks', '2')
await fillTextInputByName(page, 'amountHosts', '3')
Expand Down Expand Up @@ -85,18 +81,20 @@ export const configResetAllSettings = step(

export const configResetBasicSettings = step(
'config reset basic settings',
async ({ page }: { page: Page }) => {
async (page: Page) => {
await navigateToConfig({ page })
await setViewMode({ page, state: 'basic' })
await setViewMode({ page, state: 'advanced' })

await fillTextInputByName(page, 'storageTB', '7')
await fillTextInputByName(page, 'uploadTBMonth', '7')
await fillTextInputByName(page, 'downloadTBMonth', '7')
await fillTextInputByName(page, 'allowanceMonth', '1000')

await fillTextInputByName(page, 'maxStoragePriceTBMonth', '3000')
await fillTextInputByName(page, 'maxUploadPriceTB', '3000')
await fillTextInputByName(page, 'maxDownloadPriceTB', '3000')
await configFillEstimatesSiacoin(page)

await fillTextInputByName(page, 'minShards', '1')
await fillTextInputByName(page, 'totalShards', '3')

await setViewMode({ page, state: 'basic' })

// save
await clickIfEnabledAndWait(
Expand All @@ -106,3 +104,21 @@ export const configResetBasicSettings = step(
await clearToasts({ page })
}
)

export const configFillEstimatesSiacoin = step(
'config fill estimates and prices',
async (page: Page) => {
await fillTextInputByName(page, 'maxStoragePriceTBMonth', '3000')
await fillTextInputByName(page, 'maxUploadPriceTB', '3000')
await fillTextInputByName(page, 'maxDownloadPriceTB', '3000')
}
)

export const configFillEstimatesFiat = step(
'config fill estimates fiat',
async (page: Page) => {
await fillTextInputByName(page, 'maxStoragePriceTBMonthPinned', '11.832136')
await fillTextInputByName(page, 'maxUploadPriceTBPinned', '11.832136')
await fillTextInputByName(page, 'maxDownloadPriceTBPinned', '11.832136')
}
)
209 changes: 64 additions & 145 deletions apps/renterd-e2e/src/specs/config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,11 @@ test('field change and save behaviours', async ({ page }) => {
await fillTextInputByName(page, 'maxStoragePriceTBMonth', '7000')
await fillTextInputByName(page, 'maxUploadPriceTB', '7000')
await fillTextInputByName(page, 'maxDownloadPriceTB', '7000')
await fillTextInputByName(page, 'allowanceMonth', '7000')

// Correct number of changes is shown.
await expect(page.getByText('7 changes')).toBeVisible()
await expect(page.getByText('6 changes')).toBeVisible()
await page.getByText('Save changes').click()
await expect(page.getByText('7 changes')).toBeHidden()
await expect(page.getByText('6 changes')).toBeHidden()

// Values are the same after save.
await expectTextInputByName(page, 'storageTB', '7')
Expand All @@ -47,70 +46,58 @@ test('field change and save behaviours', async ({ page }) => {
await expectTextInputByName(page, 'maxStoragePriceTBMonth', '7,000')
await expectTextInputByName(page, 'maxUploadPriceTB', '7,000')
await expectTextInputByName(page, 'maxDownloadPriceTB', '7,000')
await expectTextInputByName(page, 'allowanceMonth', '7,000')

// Estimate is based off the allowance.
const estimateParts = [
'Estimate',
'1,000 SC',
'($3.94)',
'per TB/month with 3.0x redundancy',
'7,000 SC',
'($27.61)',
'to store 7.00 TB/month with 3.0x redundancy',
]
await expect(
page
.getByTestId('spendingEstimate')
.locator('input[name=estimatedSpendingPerMonth]')
).toHaveValue('228,667')
await expect(
page
.getByTestId('spendingEstimate')
.locator('input[name=estimatedSpendingPerMonth-fiat]')
).toHaveValue('$902')

await fillSelectInputByName(page, 'spendingEstimateMode', 'tb')

for (const part of estimateParts) {
await expect(page.getByText(part)).toBeVisible()
}
await expect(
page
.getByTestId('spendingEstimate')
.locator('input[name=estimatedSpendingPerTBPerMonth]')
).toHaveValue('32,667')
await expect(
page
.getByTestId('spendingEstimate')
.locator('input[name=estimatedSpendingPerTBPerMonth-fiat]')
).toHaveValue('$129')
})

test('set max prices to fit current allowance', async ({ page }) => {
test('set max prices to fit current spending estimate', async ({ page }) => {
// Reset state.
await navigateToConfig({ page })
await setViewMode({ page, state: 'basic' })

// Set all values that affect the pricing calculation.
await fillTextInputByName(page, 'storageTB', '10')
await fillTextInputByName(page, 'uploadTBMonth', '10')
await fillTextInputByName(page, 'downloadTBMonth', '4')
await fillTextInputByName(page, 'allowanceMonth', '95,000')
await page.getByText('Set max prices to fit current allowance').click()

// The following values are fit to the allowance.
await expectTextInputByName(page, 'maxStoragePriceTBMonth', '3,352.941176')
await expectTextInputByName(page, 'maxUploadPriceTB', '838.235294')
await expectTextInputByName(page, 'maxDownloadPriceTB', '4,191.176471')
const spendingEstimate = page.getByTestId('spendingEstimate')
const rebalanceButton = spendingEstimate.getByLabel('rebalance prices')

// If a component of the fit calculation is missing, it should not be shown.
await fillTextInputByName(page, 'storageTB', '')
await expect(
page.getByText('Set max prices to fit current allowance')
).toBeDisabled()
})

test('set allowance to fit current max prices', async ({ page }) => {
// Reset state.
await navigateToConfig({ page })
await setViewMode({ page, state: 'basic' })
await expect(spendingEstimate).toBeHidden()

// Set all values that affect the allowance calculation.
// Set all values that affect the pricing calculation.
await fillTextInputByName(page, 'storageTB', '10')
await fillTextInputByName(page, 'uploadTBMonth', '10')
await fillTextInputByName(page, 'downloadTBMonth', '4')
await fillTextInputByName(page, 'maxStoragePriceTBMonth', '1500')
await fillTextInputByName(page, 'maxUploadPriceTB', '1000')
await fillTextInputByName(page, 'maxDownloadPriceTB', '5000')
await page.getByText('Set allowance to fit current max prices').click()

// The following allowance is fit to the max prices.
await expectTextInputByName(page, 'allowanceMonth', '63,333')
await rebalanceButton.click()

// If a component of the fit calculation is missing, it should not be shown.
await fillTextInputByName(page, 'storageTB', '')
await expect(
page.getByText('Set allowance to fit current max prices')
).toBeDisabled()
// The following values are fit to the estimated spending.
await expectTextInputByName(page, 'maxStoragePriceTBMonth', '4,517.647059')
await expectTextInputByName(page, 'maxUploadPriceTB', '1,129.411765')
await expectTextInputByName(page, 'maxDownloadPriceTB', '5,647.058824')

// If the prices fit the estimate the button should be disabled.
await expect(rebalanceButton).toBeDisabled()
})

test('should show warning if pinning is not fully configured', async ({
Expand All @@ -120,132 +107,64 @@ test('should show warning if pinning is not fully configured', async ({
await navigateToConfig({ page })
await setViewMode({ page, state: 'basic' })

await setSwitchByLabel(page, 'shouldPinAllowance', true)
await setSwitchByLabel(page, 'shouldPinMaxStoragePrice', true)
await setSwitchByLabel(page, 'shouldPinMaxUploadPrice', true)
await setSwitchByLabel(page, 'shouldPinMaxDownloadPrice', true)
await fillSelectInputByName(page, 'pinnedCurrency', '')

await expect(
page
.getByTestId('allowanceMonthGroup')
.getByTestId('maxStoragePriceTBMonthGroup')
.getByText('Select a pinned currency')
).toBeVisible()
await expect(
page
.getByTestId('maxStoragePriceTBMonthGroup')
.getByTestId('maxUploadPriceTBGroup')
.getByText('Select a pinned currency')
).toBeVisible()
})

test('set max prices with pinned fields to fit current allowance', async ({
page,
}) => {
// Reset state.
await navigateToConfig({ page })
await setViewMode({ page, state: 'basic' })
await setSwitchByLabel(page, 'shouldPinMaxStoragePrice', true)
await setSwitchByLabel(page, 'shouldPinMaxUploadPrice', true)
await setSwitchByLabel(page, 'shouldPinMaxDownloadPrice', true)

// Set all values that affect the pricing calculation.
await fillTextInputByName(page, 'storageTB', '10')
await fillTextInputByName(page, 'uploadTBMonth', '10')
await fillTextInputByName(page, 'downloadTBMonth', '4')
await fillTextInputByName(page, 'allowanceMonth', '95,000')
await expect(
page.getByText('Current pricing may not fit allowance')
).toBeVisible()
await page.getByText('Set max prices to fit current allowance').click()
await expect(page.getByText('Current pricing fits allowance')).toBeVisible()

// The following values are fit to the allowance.
await expectTextInputByName(page, 'maxStoragePriceTBMonthPinned', '$13.22')
await expectTextInputByName(page, 'maxUploadPriceTBPinned', '$3.31')
await expectTextInputByName(page, 'maxDownloadPriceTBPinned', '$16.53')

await setSwitchByLabel(page, 'shouldPinMaxDownloadPrice', false)
await expect(
page.getByText('Current pricing may not fit allowance')
page
.getByTestId('maxDownloadPriceTBGroup')
.getByText('Select a pinned currency')
).toBeVisible()
await page.getByText('Set max prices to fit current allowance').click()
await expect(page.getByText('Current pricing fits allowance')).toBeVisible()

await expectTextInputByName(page, 'maxStoragePriceTBMonthPinned', '$13.22')
await expectTextInputByName(page, 'maxUploadPriceTBPinned', '$3.31')
await expectTextInputByName(page, 'maxDownloadPriceTB', '4,191.176471')
})

test('set max prices with pinned fields to fit pinned allowance', async ({
test('set max prices with pinned fields to fit current spending estimate', async ({
page,
}) => {
// Reset state.
await navigateToConfig({ page })
await setViewMode({ page, state: 'basic' })
await setSwitchByLabel(page, 'shouldPinAllowance', true)
await setSwitchByLabel(page, 'shouldPinMaxStoragePrice', true)
await setSwitchByLabel(page, 'shouldPinMaxUploadPrice', true)
await setSwitchByLabel(page, 'shouldPinMaxDownloadPrice', true)

// Set all values that affect the pricing calculation.
await fillTextInputByName(page, 'storageTB', '10')
await fillTextInputByName(page, 'uploadTBMonth', '10')
await fillTextInputByName(page, 'downloadTBMonth', '4')
await fillTextInputByName(page, 'allowanceMonthPinned', '100')
await expect(
page.getByText('Current pricing may not fit allowance')
).toBeVisible()
await page.getByText('Set max prices to fit current allowance').click()
await expect(page.getByText('Current pricing fits allowance')).toBeVisible()

// The following values are fit to the allowance.
await expectTextInputByName(page, 'maxStoragePriceTBMonthPinned', '$3.53')
await expectTextInputByName(page, 'maxUploadPriceTBPinned', '$0.88')
await expectTextInputByName(page, 'maxDownloadPriceTB', '1,118.588756')
})
const spendingEstimate = page.getByTestId('spendingEstimate')
const rebalanceButton = spendingEstimate.getByLabel('rebalance prices')

test('set max prices via individual field tips', async ({ page }) => {
// Reset state.
await navigateToConfig({ page })
await setViewMode({ page, state: 'basic' })
await setSwitchByLabel(page, 'shouldPinAllowance', true)
await setSwitchByLabel(page, 'shouldPinMaxStoragePrice', true)
await setSwitchByLabel(page, 'shouldPinMaxUploadPrice', true)
await expect(rebalanceButton).toBeEnabled()
await rebalanceButton.click()
await expect(rebalanceButton).toBeDisabled()

// Set all values that affect the pricing calculation.
await fillTextInputByName(page, 'storageTB', '10')
await fillTextInputByName(page, 'uploadTBMonth', '10')
await fillTextInputByName(page, 'downloadTBMonth', '4')
await fillTextInputByName(page, 'allowanceMonthPinned', '100')
await expect(
page.getByText('Current pricing may not fit allowance')
).toBeVisible()
const fitButton = page
.getByTestId('maxStoragePriceTBMonthGroup')
.getByLabel('Fit current allowance')
// TODO: remove the need to click twice, there is some sort of glitch after toggling the pinning switch.
await clickTwice(fitButton)
await page
.getByTestId('maxStoragePriceTBMonthGroup')
.getByLabel('Fit current allowance')
.click()
await expect(
page.getByText('Current pricing may not fit allowance')
).toBeVisible()
await page
.getByTestId('maxUploadPriceTBGroup')
.getByLabel('Fit current allowance')
.click()
await expect(
page.getByText('Current pricing may not fit allowance')
).toBeVisible()
await page
.getByTestId('maxDownloadPriceTBGroup')
.getByLabel('Fit current allowance')
.click()
await expect(page.getByText('Current pricing fits allowance')).toBeVisible()
// The following values are fit to the spending estimate.
await expectTextInputByName(page, 'maxStoragePriceTBMonthPinned', '$7.53')
await expectTextInputByName(page, 'maxUploadPriceTBPinned', '$1.88')
await expectTextInputByName(page, 'maxDownloadPriceTBPinned', '$9.41')

// Unpin one field while leaving the other two pinned.
await setSwitchByLabel(page, 'shouldPinMaxDownloadPrice', false)
await expect(rebalanceButton).toBeEnabled()
await rebalanceButton.click()
await expect(rebalanceButton).toBeDisabled()

// The following values are fit to the allowance.
await expectTextInputByName(page, 'maxStoragePriceTBMonthPinned', '$3.53')
await expectTextInputByName(page, 'maxUploadPriceTBPinned', '$0.88')
await expectTextInputByName(page, 'maxDownloadPriceTB', '1,118.588756')
await expectTextInputByName(page, 'maxStoragePriceTBMonthPinned', '$7.76')
await expectTextInputByName(page, 'maxUploadPriceTBPinned', '$1.94')
await expectTextInputByName(page, 'maxDownloadPriceTB', '2,458.147059')
})

test('pinned currency and app display currency can be different', async ({
Expand Down
Loading
Loading