Skip to content

Commit

Permalink
feat: fee error types
Browse files Browse the repository at this point in the history
  • Loading branch information
Shadouts committed Jan 4, 2024
1 parent 8abffab commit efd7262
Show file tree
Hide file tree
Showing 4 changed files with 257 additions and 92 deletions.
184 changes: 135 additions & 49 deletions src/fees.test.ts
Original file line number Diff line number Diff line change
@@ -1,93 +1,179 @@
import BigNumber from "bignumber.js";

import { FeeValidationError } from "./types";
import {
validateFeeRate,
validateFee,
estimateMultisigTransactionFee,
estimateMultisigTransactionFeeRate,
checkFeeError,
checkFeeRateError,
} from "./fees";
import { P2SH } from "./p2sh";
import { P2SH_P2WSH } from "./p2sh_p2wsh";
import { P2WSH } from "./p2wsh";

describe("fees", () => {
describe("validateFeeRate", () => {
it("should return an error message for an unparseable fee rate", () => {
it("should return an error and message for an unparseable fee rate", () => {
BigNumber.DEBUG = true;
expect(validateFeeRate(null)).toMatch(/invalid fee rate/i);
const feeRateSatsPerVbyte = null;
expect(checkFeeRateError(feeRateSatsPerVbyte)).toBe(
FeeValidationError.INVALID_FEE_RATE
);
expect(validateFeeRate(feeRateSatsPerVbyte)).toMatch(/invalid fee rate/i);
BigNumber.DEBUG = false;
});

it("should return an error message for an unparseable fee rate", () => {
expect(validateFeeRate("foo")).toMatch(/invalid fee rate/i);
it("should return an error and message for an unparseable fee rate", () => {
const feeRateSatsPerVbyte = "foo";
expect(checkFeeRateError(feeRateSatsPerVbyte)).toBe(
FeeValidationError.INVALID_FEE_RATE
);
expect(validateFeeRate(feeRateSatsPerVbyte)).toMatch(/invalid fee rate/i);
});

it("should return an error message for a negative fee rate", () => {
expect(validateFeeRate(-1)).toMatch(/cannot be negative/i);
it("should return an error and message for a negative fee rate", () => {
const feeRateSatsPerVbyte = -1;
expect(checkFeeRateError(feeRateSatsPerVbyte)).toBe(
FeeValidationError.FEE_RATE_CANNOT_BE_NEGATIVE
);
expect(validateFeeRate(feeRateSatsPerVbyte)).toMatch(
/cannot be negative/i
);
});

it("should return an empty string for a zero fee rate", () => {
expect(validateFeeRate(0)).toBe("");
const feeRateSatsPerVbyte = 0;
expect(checkFeeRateError(feeRateSatsPerVbyte)).toBe(null);
expect(validateFeeRate(feeRateSatsPerVbyte)).toBe("");
});

it("should return an error message when the fee rate is too high", () => {
expect(validateFeeRate(10000)).toMatch(/too high/i);
it("should return an error and message when the fee rate is too high", () => {
const feeRateSatsPerVbyte = 10000;
expect(checkFeeRateError(feeRateSatsPerVbyte)).toBe(
FeeValidationError.FEE_RATE_TOO_HIGH
);
expect(validateFeeRate(feeRateSatsPerVbyte)).toMatch(/too high/i);
});

it("return an empty string for an acceptable fee rate", () => {
expect(validateFeeRate(100)).toBe("");
it("return an empty string and no error for an acceptable fee rate", () => {
const feeRateSatsPerVbyte = 100;
expect(checkFeeRateError(feeRateSatsPerVbyte)).toBe(null);
expect(validateFeeRate(feeRateSatsPerVbyte)).toBe("");
});
});

describe("validateFee", () => {
it("should return an error message for an unparseable fee", () => {
it("should return an error and message for an unparseable fee", () => {
// If BigNumber.DEBUG is set true then an error will be thrown if this BigNumber constructor receives an invalid value
// see https://mikemcl.github.io/bignumber.js/#debug
BigNumber.DEBUG = true;
expect(validateFee(null, 1000000)).toMatch(/invalid fee/i);
const feeSats = null;
const inputsTotalSats = 1000000;
expect(checkFeeError(feeSats, inputsTotalSats)).toBe(
FeeValidationError.INVALID_FEE
);
expect(validateFee(feeSats, inputsTotalSats)).toMatch(/invalid fee/i);
BigNumber.DEBUG = false;
});

it("should return an error message for an unparseable inputTotalSats", () => {
it("should return an error and message for an unparseable inputTotalSats", () => {
BigNumber.DEBUG = true;
expect(validateFee(10000, null)).toMatch(/invalid total input amount/i);
const feeSats = 10000;
const inputsTotalSats = null;
expect(checkFeeError(feeSats, inputsTotalSats)).toBe(
FeeValidationError.INVALID_INPUT_AMOUNT
);
expect(validateFee(feeSats, inputsTotalSats)).toMatch(
/invalid total input amount/i
);
BigNumber.DEBUG = false;
});

it("should return an error message for an unparseable fee", () => {
expect(validateFee("foo", 1000000)).toMatch(/invalid fee/i);
});

it("should return an error message for an unparseable total input amount", () => {
expect(validateFee(10000, "foo")).toMatch(/invalid total input amount/i);
});

it("should return an error message for a negative fee", () => {
expect(validateFee(-1, 1000000)).toMatch(/cannot be negative/i);
});

it("should return an error message for a negative total input amount", () => {
expect(validateFee(10000, -1)).toMatch(/must be positive/i);
});

it("should return an error message for a zero total linput amount", () => {
expect(validateFee(10000, 0)).toMatch(/must be positive/i);
});

it("should return an empty string for a zero fee", () => {
expect(validateFee(0, 1000000)).toBe("");
});

it("should return an error message when the fee is too high", () => {
expect(validateFee(2500001, 10000000)).toMatch(/too high/i);
});

it("should return an error message when the fee higher than the total input amount", () => {
expect(validateFee(100001, 100000)).toMatch(/too high/i);
});

it("should return an empty string for an acceptable fee", () => {
expect(validateFee(10000, 1000000)).toBe("");
it("should return an error and message for an unparseable fee", () => {
const feeSats = "foo";
const inputsTotalSats = 1000000;
expect(checkFeeError(feeSats, inputsTotalSats)).toBe(
FeeValidationError.INVALID_FEE
);
expect(validateFee(feeSats, inputsTotalSats)).toMatch(/invalid fee/i);
});

it("should return an error and message for an unparseable total input amount", () => {
const feeSats = 10000;
const inputsTotalSats = "foo";
expect(checkFeeError(feeSats, inputsTotalSats)).toBe(
FeeValidationError.INVALID_INPUT_AMOUNT
);
expect(validateFee(feeSats, inputsTotalSats)).toMatch(
/invalid total input amount/i
);
});

it("should return an error and message for a negative fee", () => {
const feeSats = -1;
const inputsTotalSats = 1000000;
expect(checkFeeError(feeSats, inputsTotalSats)).toBe(
FeeValidationError.FEE_CANNOT_BE_NEGATIVE
);
expect(validateFee(feeSats, inputsTotalSats)).toMatch(
/cannot be negative/i
);
});

it("should return an error and message for a negative total input amount", () => {
const feeSats = 10000;
const inputsTotalSats = -1;
expect(checkFeeError(feeSats, inputsTotalSats)).toBe(
FeeValidationError.INPUT_AMOUNT_MUST_BE_POSITIVE
);
expect(validateFee(feeSats, inputsTotalSats)).toMatch(
/must be positive/i
);
});

it("should return an error and message for a zero total linput amount", () => {
const feeSats = 10000;
const inputsTotalSats = 0;
expect(checkFeeError(feeSats, inputsTotalSats)).toBe(
FeeValidationError.INPUT_AMOUNT_MUST_BE_POSITIVE
);
expect(validateFee(feeSats, inputsTotalSats)).toMatch(
/must be positive/i
);
});

it("should return an empty string and not error for a zero fee", () => {
const feeSats = 0;
const inputsTotalSats = 1000000;
expect(checkFeeError(feeSats, inputsTotalSats)).toBe(null);
expect(validateFee(feeSats, inputsTotalSats)).toBe("");
});

it("should return an error and message when the fee is too high", () => {
const feeSats = 2500001;
const inputsTotalSats = 10000000;
expect(checkFeeError(feeSats, inputsTotalSats)).toBe(
FeeValidationError.FEE_TOO_HIGH
);
expect(validateFee(feeSats, inputsTotalSats)).toMatch(/too high/i);
});

it("should return an error and message when the fee higher than the total input amount", () => {
const feeSats = 100001;
const inputsTotalSats = 100000;
expect(checkFeeError(feeSats, inputsTotalSats)).toBe(
FeeValidationError.FEE_TOO_HIGH
);
expect(validateFee(feeSats, inputsTotalSats)).toMatch(/too high/i);
});

it("should return an empty string and no error for an acceptable fee", () => {
const feeSats = 10000;
const inputsTotalSats = 1000000;
expect(checkFeeError(feeSats, inputsTotalSats)).toBe(null);
expect(validateFee(feeSats, inputsTotalSats)).toBe("");
});
});

Expand Down
Loading

0 comments on commit efd7262

Please sign in to comment.