fix: postage stamp price and TTL calculation (#305)
* fix: postage stamp price and TTL calculation * chore: removed logs and fixed linter issues
This commit is contained in:
@@ -57,4 +57,25 @@ export class Token {
|
||||
toFixedDecimal(digits = 7): string {
|
||||
return this.toDecimal.toFixed(digits)
|
||||
}
|
||||
|
||||
toSignificantDigits(digits = 4): string {
|
||||
const asString = this.toDecimal.toFixed(16)
|
||||
|
||||
let indexOfSignificantDigit = -1
|
||||
let reachedDecimalPoint = false
|
||||
|
||||
for (let i = 0; i < asString.length; i++) {
|
||||
const char = asString[i]
|
||||
|
||||
if (char === '.') {
|
||||
reachedDecimalPoint = true
|
||||
indexOfSignificantDigit = i + 1
|
||||
} else if (reachedDecimalPoint && char !== '0') {
|
||||
indexOfSignificantDigit = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return asString.slice(0, indexOfSignificantDigit + digits)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,20 +2,14 @@ import { Box, Grid, Typography } from '@material-ui/core'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import { Form, Formik, FormikHelpers } from 'formik'
|
||||
import { useSnackbar } from 'notistack'
|
||||
import React, { ReactElement, useContext } from 'react'
|
||||
import { ReactElement, useContext } from 'react'
|
||||
import { Check } from 'react-feather'
|
||||
import { SwarmButton } from '../../components/SwarmButton'
|
||||
import { SwarmTextInput } from '../../components/SwarmTextInput'
|
||||
import { Context as BeeContext } from '../../providers/Bee'
|
||||
import { Context as SettingsContext } from '../../providers/Settings'
|
||||
import { Context as StampsContext } from '../../providers/Stamps'
|
||||
import {
|
||||
calculateStampPrice,
|
||||
convertAmountToSeconds,
|
||||
convertDepthToBytes,
|
||||
formatBzz,
|
||||
secondsToTimeString,
|
||||
} from '../../utils'
|
||||
import { calculateStampPrice, convertAmountToSeconds, convertDepthToBytes, secondsToTimeString } from '../../utils'
|
||||
import { getHumanReadableFileSize } from '../../utils/file'
|
||||
|
||||
interface FormValues {
|
||||
@@ -50,24 +44,27 @@ export function PostageStampCreation({ onFinished }: Props): ReactElement {
|
||||
}
|
||||
|
||||
function getTtl(amount: number): string {
|
||||
if (isNaN(amount) || amount <= 0) {
|
||||
return '-'
|
||||
}
|
||||
|
||||
return secondsToTimeString(convertAmountToSeconds(amount))
|
||||
}
|
||||
|
||||
function getPrice(depth: number, amount: number): string {
|
||||
const hasInvalidInput = isNaN(amount) || amount <= 0 || isNaN(depth) || depth < 17 || depth > 255
|
||||
const isCurrentPriceAvailable = chainState && chainState.currentPrice
|
||||
|
||||
if (hasInvalidInput || !isCurrentPriceAvailable) {
|
||||
if (amount <= 0 || !isCurrentPriceAvailable) {
|
||||
return '-'
|
||||
}
|
||||
|
||||
const price = calculateStampPrice(depth, amount, chainState.currentPrice)
|
||||
const pricePerBlock = Number.parseInt(chainState.currentPrice, 10)
|
||||
|
||||
return `${formatBzz(price)} BZZ`
|
||||
return `${secondsToTimeString(convertAmountToSeconds(amount, pricePerBlock))} (with price of 0 per block)`
|
||||
}
|
||||
|
||||
function getPrice(depth: number, amount: bigint): string {
|
||||
const hasInvalidInput = amount <= 0 || isNaN(depth) || depth < 17 || depth > 255
|
||||
|
||||
if (hasInvalidInput) {
|
||||
return '-'
|
||||
}
|
||||
|
||||
const price = calculateStampPrice(depth, amount)
|
||||
|
||||
return `${price.toSignificantDigits()} BZZ`
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -136,7 +133,7 @@ export function PostageStampCreation({ onFinished }: Props): ReactElement {
|
||||
<Box mt={0.25} sx={{ bgcolor: '#f6f6f6' }} p={2}>
|
||||
<Grid container justifyContent="space-between">
|
||||
<Typography>Corresponding TTL (Time to live)</Typography>
|
||||
<Typography>{getTtl(parseInt(values.amount || '0', 10))}</Typography>
|
||||
<Typography>{getTtl(Number.parseInt(values.amount || '0', 10))}</Typography>
|
||||
</Grid>
|
||||
</Box>
|
||||
</Box>
|
||||
@@ -146,7 +143,7 @@ export function PostageStampCreation({ onFinished }: Props): ReactElement {
|
||||
<Box mb={4} sx={{ bgcolor: '#fcf2e8' }} p={2}>
|
||||
<Grid container justifyContent="space-between">
|
||||
<Typography>Indicative Price</Typography>
|
||||
<Typography>{getPrice(parseInt(values.depth || '0', 10), parseInt(values.amount || '0', 10))}</Typography>
|
||||
<Typography>{getPrice(parseInt(values.depth || '0', 10), BigInt(values.amount || '0'))}</Typography>
|
||||
</Grid>
|
||||
</Box>
|
||||
<SwarmButton
|
||||
|
||||
+10
-27
@@ -1,5 +1,5 @@
|
||||
import { NumberString } from '@ethersphere/bee-js'
|
||||
import { BigNumber } from 'bignumber.js'
|
||||
import { Token } from '../models/Token'
|
||||
|
||||
/**
|
||||
* Test if value is an integer
|
||||
@@ -159,38 +159,21 @@ export function secondsToTimeString(seconds: number): string {
|
||||
return `${unit.toFixed(1)} years`
|
||||
}
|
||||
|
||||
export function formatBzz(amount: number): string {
|
||||
const asString = amount.toFixed(16)
|
||||
|
||||
let indexOfSignificantDigit = -1
|
||||
let reachedDecimalPoint = false
|
||||
|
||||
for (let i = 0; i < asString.length; i++) {
|
||||
const char = asString[i]
|
||||
|
||||
if (char === '.') {
|
||||
reachedDecimalPoint = true
|
||||
} else if (reachedDecimalPoint && char !== '0') {
|
||||
indexOfSignificantDigit = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return asString.slice(0, indexOfSignificantDigit + 4)
|
||||
}
|
||||
|
||||
export function convertDepthToBytes(depth: number): number {
|
||||
return 2 ** depth * 4096
|
||||
}
|
||||
|
||||
export function convertAmountToSeconds(amount: number): number {
|
||||
return amount / 10 / 1
|
||||
export function convertAmountToSeconds(amount: number, pricePerBlock: number): number {
|
||||
// TODO: blocktime should come directly from the blockchain as it may differ between different networks
|
||||
const blockTime = 5 // On mainnet there is 5 seconds between blocks
|
||||
|
||||
// See https://github.com/ethersphere/bee/blob/66f079930d739182c4c79eb6008784afeeba1096/pkg/debugapi/postage.go#L410-L413
|
||||
return (amount * blockTime) / pricePerBlock
|
||||
}
|
||||
|
||||
export function calculateStampPrice(depth: number, amount: number, currentPrice: NumberString): number {
|
||||
const price = parseInt(currentPrice, 10)
|
||||
|
||||
return (amount * 2 ** (depth - 16) * price) / 1e16
|
||||
export function calculateStampPrice(depth: number, amount: bigint): Token {
|
||||
// See https://github.com/ethersphere/bee/blob/66f079930d739182c4c79eb6008784afeeba1096/pkg/debugapi/postage.go#L410-L413
|
||||
return new Token(amount * BigInt(2 ** depth)) // FIXME: the 2 ** depth should be performed on bigint already
|
||||
}
|
||||
|
||||
export function shortenText(text: string, length = 20, separator = '[…]'): string {
|
||||
|
||||
Reference in New Issue
Block a user