From 55700b2157f457b315c68d5c3820c775a3797e8b Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 30 Jan 2020 08:42:42 +0100 Subject: [PATCH 1/5] Simplify some code --- packages/faucet/src/actions/generate.ts | 2 +- packages/faucet/src/faucet.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/faucet/src/actions/generate.ts b/packages/faucet/src/actions/generate.ts index 3ca673d2..898fc385 100644 --- a/packages/faucet/src/actions/generate.ts +++ b/packages/faucet/src/actions/generate.ts @@ -12,7 +12,7 @@ export async function generate(args: ReadonlyArray): Promise { const codecName = codecFromString(args[0]); const chainId = args[1] as ChainId; - const mnemonic = Bip39.encode(await Random.getBytes(16)).toString(); + const mnemonic = Bip39.encode(Random.getBytes(16)).toString(); console.info(`FAUCET_MNEMONIC="${mnemonic}"`); const profile = new UserProfile(); diff --git a/packages/faucet/src/faucet.ts b/packages/faucet/src/faucet.ts index 3587566a..ff5d111c 100644 --- a/packages/faucet/src/faucet.ts +++ b/packages/faucet/src/faucet.ts @@ -4,7 +4,6 @@ export function main(args: ReadonlyArray): void { if (args.length < 1) { help(); process.exit(1); - return; } const action = args[0]; From d52f69afffdd5885c9b18b23c81336914e4fa05a Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 30 Jan 2020 08:43:08 +0100 Subject: [PATCH 2/5] Implement Amount debugging using Decimal class --- packages/faucet/src/debugging.ts | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/packages/faucet/src/debugging.ts b/packages/faucet/src/debugging.ts index 5b5adc09..1fb4c9ab 100644 --- a/packages/faucet/src/debugging.ts +++ b/packages/faucet/src/debugging.ts @@ -1,38 +1,18 @@ import { Account, Amount } from "@iov/bcp"; +import { Decimal } from "@iov/encoding"; import { MultiChainSigner } from "@iov/multichain"; import { SendJob } from "./types"; -export function amountToNumber(amount: Amount): number { - const { quantity, fractionalDigits } = amount; - if (!quantity.match(/^[0-9]+$/)) { - throw new Error(`quantity must be a number, got ${quantity}`); - } - if (fractionalDigits < 0) { - throw new Error(`invalid fractional digits: ${fractionalDigits}`); - } - // let's remove those leading zeros... - const temp = quantity.replace(/^0+/, ""); - // unless we need them to reach a decimal point - const pad = fractionalDigits - temp.length; - const trimmed = pad > 0 ? "0".repeat(pad) + temp : temp; - - const cut = trimmed.length - fractionalDigits; - const whole = cut === 0 ? "0" : trimmed.slice(0, cut); - const decimal = fractionalDigits === 0 ? "" : `.${trimmed.slice(cut)}`; - const value = `${whole}${decimal}`; - - return Number(value); -} - /** A string representation of a coin in a human-readable format that can change at any time */ -export function debugCoin(coin: Amount): string { - return `${amountToNumber(coin)} ${coin.tokenTicker}`; +function debugAmount(amount: Amount): string { + const value = Decimal.fromAtomics(amount.quantity, amount.fractionalDigits).toString(); + return `${value} ${amount.tokenTicker}`; } /** A string representation of a balance in a human-readable format that can change at any time */ export function debugBalance(data: ReadonlyArray): string { - return `[${data.map(debugCoin).join(", ")}]`; + return `[${data.map(debugAmount).join(", ")}]`; } /** A string representation of an account in a human-readable format that can change at any time */ @@ -53,6 +33,6 @@ export function logAccountsState(accounts: ReadonlyArray): void { export function logSendJob(signer: MultiChainSigner, job: SendJob): void { const from = signer.identityToAddress(job.sender); const to = job.recipient; - const amount = debugCoin(job.amount); + const amount = debugAmount(job.amount); console.info(`Sending ${amount} from ${from} to ${to} ...`); } From 3b10f4e78333b6203429a5651d124b7d4eed0618 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 30 Jan 2020 08:52:26 +0100 Subject: [PATCH 3/5] Implement creditAmount without BN --- packages/faucet/src/cashflow.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/faucet/src/cashflow.ts b/packages/faucet/src/cashflow.ts index 987b34e1..73a1957c 100644 --- a/packages/faucet/src/cashflow.ts +++ b/packages/faucet/src/cashflow.ts @@ -1,7 +1,7 @@ import BN = require("bn.js"); import { Account, Amount, TokenTicker } from "@iov/bcp"; -import { Int53 } from "@iov/encoding"; +import { Uint53 } from "@iov/encoding"; /** Send `factor` times credit amount on refilling */ const defaultRefillFactor = 20; @@ -24,15 +24,14 @@ export function getFractionalDigits(): number { } /** The amount of tokens that will be sent to the user */ -export function creditAmount(token: TokenTicker, factor = 1): Amount { +export function creditAmount(token: TokenTicker, factor: Uint53 = new Uint53(1)): Amount { const amountFromEnv = process.env[`FAUCET_CREDIT_AMOUNT_${token}`]; - const wholeNumber = amountFromEnv ? Int53.fromString(amountFromEnv).toNumber() : 10; - const total = wholeNumber * factor; + const amount = amountFromEnv ? Uint53.fromString(amountFromEnv).toNumber() : 10; + const value = new Uint53(amount * factor.toNumber()); + const fractionalDigits = getFractionalDigits(); - // replace BN with BigInt with TypeScript 3.2 and node 11 - const quantity = new BN(total).imul(new BN(10).pow(new BN(fractionalDigits))).toString(); return { - quantity: quantity, + quantity: value.toString() + "0".repeat(fractionalDigits), fractionalDigits: fractionalDigits, tokenTicker: token, }; @@ -40,13 +39,13 @@ export function creditAmount(token: TokenTicker, factor = 1): Amount { export function refillAmount(token: TokenTicker): Amount { const factorFromEnv = Number.parseInt(process.env.FAUCET_REFILL_FACTOR || "0", 10) || undefined; - const factor = factorFromEnv || defaultRefillFactor; + const factor = new Uint53(factorFromEnv || defaultRefillFactor); return creditAmount(token, factor); } export function refillThreshold(token: TokenTicker): Amount { const factorFromEnv = Number.parseInt(process.env.FAUCET_REFILL_THRESHOLD || "0", 10) || undefined; - const factor = factorFromEnv || defaultRefillThresholdFactor; + const factor = new Uint53(factorFromEnv || defaultRefillThresholdFactor); return creditAmount(token, factor); } From e737884aa306c54a2c119246b56b52c4a26feb5b Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 30 Jan 2020 08:57:00 +0100 Subject: [PATCH 4/5] Implement needsRefill without BN --- packages/faucet/src/cashflow.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/faucet/src/cashflow.ts b/packages/faucet/src/cashflow.ts index 73a1957c..e95116fe 100644 --- a/packages/faucet/src/cashflow.ts +++ b/packages/faucet/src/cashflow.ts @@ -1,7 +1,5 @@ -import BN = require("bn.js"); - import { Account, Amount, TokenTicker } from "@iov/bcp"; -import { Uint53 } from "@iov/encoding"; +import { Decimal, Uint53 } from "@iov/encoding"; /** Send `factor` times credit amount on refilling */ const defaultRefillFactor = 20; @@ -51,9 +49,16 @@ export function refillThreshold(token: TokenTicker): Amount { /** true iff the distributor account needs a refill */ export function needsRefill(account: Account, token: TokenTicker): boolean { - const coin = account.balance.find(balance => balance.tokenTicker === token); + const balanceAmount = account.balance.find(b => b.tokenTicker === token); - const tokenBalance = coin ? coin.quantity : "0"; - const refillQty = new BN(refillThreshold(token).quantity); - return new BN(tokenBalance).lt(refillQty); + const balance = balanceAmount + ? Decimal.fromAtomics(balanceAmount.quantity, balanceAmount.fractionalDigits) + : Decimal.fromAtomics("0", 0); + + const thresholdAmount = refillThreshold(token); + const threshold = Decimal.fromAtomics(thresholdAmount.quantity, thresholdAmount.fractionalDigits); + + // TODO: perform < operation on Decimal type directly + // https://github.com/iov-one/iov-core/issues/1375 + return balance.toFloatApproximation() < threshold.toFloatApproximation(); } From 3085f6eaa53e1770912be9f0e8a50da927b93803 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 30 Jan 2020 09:06:11 +0100 Subject: [PATCH 5/5] Remove bn.js dependency --- packages/faucet/package.json | 2 -- yarn.lock | 12 ------------ 2 files changed, 14 deletions(-) diff --git a/packages/faucet/package.json b/packages/faucet/package.json index 4c234aee..272fb6ee 100644 --- a/packages/faucet/package.json +++ b/packages/faucet/package.json @@ -40,7 +40,6 @@ "@iov/multichain": "^2.0.0-alpha.7", "@koa/cors": "^3.0.0", "axios": "^0.19.0", - "bn.js": "^5.1.1", "fast-deep-equal": "^3.1.1", "koa": "^2.11.0", "koa-bodyparser": "^4.2.1", @@ -48,7 +47,6 @@ "xstream": "^11.11.0" }, "devDependencies": { - "@types/bn.js": "^4.11.6", "@types/koa": "^2.11.0", "@types/koa-bodyparser": "^4.3.0", "@types/koa__cors": "^3.0.1" diff --git a/yarn.lock b/yarn.lock index 61271131..c0fb6f1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1002,13 +1002,6 @@ dependencies: "@types/node" "*" -"@types/bn.js@^4.11.6": - version "4.11.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" - integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== - dependencies: - "@types/node" "*" - "@types/body-parser@*": version "1.17.1" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.1.tgz#18fcf61768fb5c30ccc508c21d6fd2e8b3bf7897" @@ -1854,11 +1847,6 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.8, bn.js@^4.4.0: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== -bn.js@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.1.tgz#48efc4031a9c4041b9c99c6941d903463ab62eb5" - integrity sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA== - body-parser@^1.16.1: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"