Explorer: replace usages of bn.js with BigInt (#28040)

This commit is contained in:
Justin Starry 2022-09-24 13:05:41 +08:00 committed by GitHub
parent b9f4c8e3c0
commit 22b966be76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 59 additions and 58 deletions

View File

@ -1,28 +1,28 @@
import { expect } from "chai"; import { expect } from "chai";
import { lamportsToSol, LAMPORTS_PER_SOL } from "utils"; import { lamportsToSol, LAMPORTS_PER_SOL } from "utils";
import BN from "bn.js";
describe("lamportsToSol", () => { describe("lamportsToSol", () => {
it("0 lamports", () => { it("0 lamports", () => {
expect(lamportsToSol(new BN(0))).to.eq(0.0); expect(lamportsToSol(0)).to.eq(0.0);
expect(lamportsToSol(BigInt(0))).to.eq(0.0);
}); });
it("1 lamport", () => { it("1 lamport", () => {
expect(lamportsToSol(new BN(1))).to.eq(0.000000001); expect(lamportsToSol(1)).to.eq(0.000000001);
expect(lamportsToSol(new BN(-1))).to.eq(-0.000000001); expect(lamportsToSol(BigInt(1))).to.eq(0.000000001);
expect(lamportsToSol(-1)).to.eq(-0.000000001);
expect(lamportsToSol(BigInt(-1))).to.eq(-0.000000001);
}); });
it("1 SOL", () => { it("1 SOL", () => {
expect(lamportsToSol(new BN(LAMPORTS_PER_SOL))).to.eq(1.0); expect(lamportsToSol(LAMPORTS_PER_SOL)).to.eq(1.0);
expect(lamportsToSol(new BN(-LAMPORTS_PER_SOL))).to.eq(-1.0); expect(lamportsToSol(BigInt(LAMPORTS_PER_SOL))).to.eq(1.0);
expect(lamportsToSol(-LAMPORTS_PER_SOL)).to.eq(-1.0);
expect(lamportsToSol(BigInt(-LAMPORTS_PER_SOL))).to.eq(-1.0);
}); });
it("u64::MAX lamports", () => { it("u64::MAX lamports", () => {
expect(lamportsToSol(new BN(2).pow(new BN(64)))).to.eq( expect(lamportsToSol(2n ** 64n)).to.eq(18446744073.709551615);
18446744073.709551615 expect(lamportsToSol(-(2n ** 64n))).to.eq(-18446744073.709551615);
);
expect(lamportsToSol(new BN(2).pow(new BN(64)).neg())).to.eq(
-18446744073.709551615
);
}); });
}); });

View File

@ -9,11 +9,10 @@ import {
StakeMeta, StakeMeta,
StakeAccountType, StakeAccountType,
} from "validators/accounts/stake"; } from "validators/accounts/stake";
import BN from "bn.js";
import { StakeActivationData } from "@solana/web3.js"; import { StakeActivationData } from "@solana/web3.js";
import { Epoch } from "components/common/Epoch"; import { Epoch } from "components/common/Epoch";
const MAX_EPOCH = new BN(2).pow(new BN(64)).sub(new BN(1)); const U64_MAX = BigInt("0xffffffffffffffff");
export function StakeAccountSection({ export function StakeAccountSection({
account, account,
@ -163,11 +162,11 @@ function DelegationCard({
const delegation = stakeAccount?.stake?.delegation; const delegation = stakeAccount?.stake?.delegation;
if (delegation) { if (delegation) {
voterPubkey = delegation.voter; voterPubkey = delegation.voter;
if (!delegation.activationEpoch.eq(MAX_EPOCH)) { if (delegation.activationEpoch !== U64_MAX) {
activationEpoch = delegation.activationEpoch.toNumber(); activationEpoch = delegation.activationEpoch;
} }
if (!delegation.deactivationEpoch.eq(MAX_EPOCH)) { if (delegation.deactivationEpoch !== U64_MAX) {
deactivationEpoch = delegation.deactivationEpoch.toNumber(); deactivationEpoch = delegation.deactivationEpoch;
} }
} }
const { stake } = stakeAccount; const { stake } = stakeAccount;
@ -297,10 +296,10 @@ function isFullyInactivated(
} }
const delegatedStake = stake.delegation.stake; const delegatedStake = stake.delegation.stake;
const inactiveStake = new BN(activation.inactive); const inactiveStake = BigInt(activation.inactive);
return ( return (
!stake.delegation.deactivationEpoch.eq(MAX_EPOCH) && stake.delegation.deactivationEpoch !== U64_MAX &&
delegatedStake.eq(inactiveStake) delegatedStake === inactiveStake
); );
} }

View File

@ -4,7 +4,7 @@ import { clusterPath } from "utils/url";
import { Copyable } from "./Copyable"; import { Copyable } from "./Copyable";
type Props = { type Props = {
epoch: number; epoch: number | bigint;
link?: boolean; link?: boolean;
}; };
export function Epoch({ epoch, link }: Props) { export function Epoch({ epoch, link }: Props) {

View File

@ -7,7 +7,7 @@ import {
TransactionInstruction, TransactionInstruction,
} from "@solana/web3.js"; } from "@solana/web3.js";
import { enums, number, type, Infer, create } from "superstruct"; import { enums, number, type, Infer, create } from "superstruct";
import { BigNumFromString } from "validators/bignum"; import { BigIntFromString } from "validators/number";
const SERUM_PROGRAM_IDS = [ const SERUM_PROGRAM_IDS = [
"4ckmDgGdxQoPDLUkDT3vHgSAkzA3QRdNq5ywwY4sUSJn", "4ckmDgGdxQoPDLUkDT3vHgSAkzA3QRdNq5ywwY4sUSJn",
@ -60,11 +60,11 @@ export type InitializeMarket = {
}; };
export const InitializeMarketInstruction = type({ export const InitializeMarketInstruction = type({
baseLotSize: BigNumFromString, baseLotSize: BigIntFromString,
quoteLotSize: BigNumFromString, quoteLotSize: BigIntFromString,
feeRateBps: number(), feeRateBps: number(),
quoteDustThreshold: BigNumFromString, quoteDustThreshold: BigIntFromString,
vaultSignerNonce: BigNumFromString, vaultSignerNonce: BigIntFromString,
}); });
export function decodeInitializeMarket( export function decodeInitializeMarket(
@ -110,10 +110,10 @@ export type NewOrder = {
export const NewOrderInstruction = type({ export const NewOrderInstruction = type({
side: Side, side: Side,
limitPrice: BigNumFromString, limitPrice: BigIntFromString,
maxQuantity: BigNumFromString, maxQuantity: BigIntFromString,
orderType: OrderType, orderType: OrderType,
clientId: BigNumFromString, clientId: BigIntFromString,
}); });
export function decodeNewOrder(ix: TransactionInstruction): NewOrder { export function decodeNewOrder(ix: TransactionInstruction): NewOrder {
@ -208,7 +208,7 @@ export type CancelOrder = {
export const CancelOrderInstruction = type({ export const CancelOrderInstruction = type({
side: Side, side: Side,
orderId: BigNumFromString, orderId: BigIntFromString,
openOrdersSlot: number(), openOrdersSlot: number(),
}); });
@ -272,7 +272,7 @@ export type CancelOrderByClientId = {
}; };
export const CancelOrderByClientIdInstruction = type({ export const CancelOrderByClientIdInstruction = type({
clientId: BigNumFromString, clientId: BigIntFromString,
}); });
export function decodeCancelOrderByClientId( export function decodeCancelOrderByClientId(
@ -355,12 +355,12 @@ export type NewOrderV3 = {
export const NewOrderV3Instruction = type({ export const NewOrderV3Instruction = type({
side: Side, side: Side,
limitPrice: BigNumFromString, limitPrice: BigIntFromString,
maxBaseQuantity: BigNumFromString, maxBaseQuantity: BigIntFromString,
maxQuoteQuantity: BigNumFromString, maxQuoteQuantity: BigIntFromString,
selfTradeBehavior: SelfTradeBehavior, selfTradeBehavior: SelfTradeBehavior,
orderType: OrderType, orderType: OrderType,
clientId: BigNumFromString, clientId: BigIntFromString,
limit: number(), limit: number(),
}); });
@ -399,7 +399,7 @@ export type CancelOrderV2 = {
export const CancelOrderV2Instruction = type({ export const CancelOrderV2Instruction = type({
side: Side, side: Side,
orderId: BigNumFromString, orderId: BigIntFromString,
}); });
export function decodeCancelOrderV2(ix: TransactionInstruction): CancelOrderV2 { export function decodeCancelOrderV2(ix: TransactionInstruction): CancelOrderV2 {
@ -434,7 +434,7 @@ export type CancelOrderByClientIdV2 = {
}; };
export const CancelOrderByClientIdV2Instruction = type({ export const CancelOrderByClientIdV2Instruction = type({
clientId: BigNumFromString, clientId: BigIntFromString,
}); });
export function decodeCancelOrderByClientIdV2( export function decodeCancelOrderByClientIdV2(

View File

@ -1,4 +1,3 @@
import BN from "bn.js";
import { import {
HumanizeDuration, HumanizeDuration,
HumanizeDurationLanguage, HumanizeDurationLanguage,
@ -36,7 +35,6 @@ export function microLamportsToLamports(
return microLamports / MICRO_LAMPORTS_PER_LAMPORT; return microLamports / MICRO_LAMPORTS_PER_LAMPORT;
} }
console.log(microLamports);
const microLamportsString = microLamports.toString().padStart(7, "0"); const microLamportsString = microLamports.toString().padStart(7, "0");
const splitIndex = microLamportsString.length - 6; const splitIndex = microLamportsString.length - 6;
const lamportString = const lamportString =
@ -56,17 +54,17 @@ export function microLamportsToLamportsString(
); );
} }
export function lamportsToSol(lamports: number | BN): number { export function lamportsToSol(lamports: number | bigint): number {
if (typeof lamports === "number") { if (typeof lamports === "number") {
return Math.abs(lamports) / LAMPORTS_PER_SOL; return lamports / LAMPORTS_PER_SOL;
} }
let signMultiplier = 1; let signMultiplier = 1;
if (lamports.isNeg()) { if (lamports < 0) {
signMultiplier = -1; signMultiplier = -1;
} }
const absLamports = lamports.abs(); const absLamports = lamports < 0 ? -lamports : lamports;
const lamportsString = absLamports.toString(10).padStart(10, "0"); const lamportsString = absLamports.toString(10).padStart(10, "0");
const splitIndex = lamportsString.length - 9; const splitIndex = lamportsString.length - 9;
const solString = const solString =
@ -77,7 +75,7 @@ export function lamportsToSol(lamports: number | BN): number {
} }
export function lamportsToSolString( export function lamportsToSolString(
lamports: number | BN, lamports: number | bigint,
maximumFractionDigits: number = 9 maximumFractionDigits: number = 9
): string { ): string {
const sol = lamportsToSol(lamports); const sol = lamportsToSol(lamports);
@ -92,7 +90,7 @@ export function SolBalance({
lamports, lamports,
maximumFractionDigits = 9, maximumFractionDigits = 9,
}: { }: {
lamports: number | BN; lamports: number | bigint;
maximumFractionDigits?: number; maximumFractionDigits?: number;
}) { }) {
return ( return (

View File

@ -2,7 +2,7 @@
import { Infer, number, nullable, enums, type } from "superstruct"; import { Infer, number, nullable, enums, type } from "superstruct";
import { PublicKeyFromString } from "validators/pubkey"; import { PublicKeyFromString } from "validators/pubkey";
import { BigNumFromString } from "validators/bignum"; import { BigIntFromString } from "validators/number";
export type StakeAccountType = Infer<typeof StakeAccountType>; export type StakeAccountType = Infer<typeof StakeAccountType>;
export const StakeAccountType = enums([ export const StakeAccountType = enums([
@ -14,7 +14,7 @@ export const StakeAccountType = enums([
export type StakeMeta = Infer<typeof StakeMeta>; export type StakeMeta = Infer<typeof StakeMeta>;
export const StakeMeta = type({ export const StakeMeta = type({
rentExemptReserve: BigNumFromString, rentExemptReserve: BigIntFromString,
authorized: type({ authorized: type({
staker: PublicKeyFromString, staker: PublicKeyFromString,
withdrawer: PublicKeyFromString, withdrawer: PublicKeyFromString,
@ -33,9 +33,9 @@ export const StakeAccountInfo = type({
type({ type({
delegation: type({ delegation: type({
voter: PublicKeyFromString, voter: PublicKeyFromString,
stake: BigNumFromString, stake: BigIntFromString,
activationEpoch: BigNumFromString, activationEpoch: BigIntFromString,
deactivationEpoch: BigNumFromString, deactivationEpoch: BigIntFromString,
warmupCooldownRate: number(), warmupCooldownRate: number(),
}), }),
creditsObserved: number(), creditsObserved: number(),

View File

@ -1,7 +0,0 @@
import { coerce, instance, string } from "superstruct";
import BN from "bn.js";
export const BigNumFromString = coerce(instance(BN), string(), (value) => {
if (typeof value === "string") return new BN(value, 10);
throw new Error("invalid big num");
});

View File

@ -0,0 +1,11 @@
import { bigint, coerce, number, string } from "superstruct";
export const BigIntFromString = coerce(bigint(), string(), (value): bigint => {
if (typeof value === "string") return BigInt(value);
throw new Error("invalid bigint");
});
export const NumberFromString = coerce(number(), string(), (value): number => {
if (typeof value === "string") return Number(value);
throw new Error("invalid number");
});