Skip to content

Commit

Permalink
feat: update unbonding period calculation (#1034)
Browse files Browse the repository at this point in the history
  • Loading branch information
euharrison authored Sep 3, 2024
1 parent 9d8711e commit 2e65ae8
Show file tree
Hide file tree
Showing 12 changed files with 56 additions and 72 deletions.
2 changes: 1 addition & 1 deletion apps/extension/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@
},
"include": ["src/**/*.ts", "src/**/*.tsx"],
"exclude": ["node_modules"],
"typeRoots": ["./node_modules/@types"],
"typeRoots": ["./node_modules/@types"]
}
8 changes: 5 additions & 3 deletions apps/namadillo/src/App/Staking/IncrementBonding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { NamCurrency } from "App/Common/NamCurrency";
import { TableRowLoading } from "App/Common/TableRowLoading";
import { TransactionFees } from "App/Common/TransactionFees";
import { accountBalanceAtom, defaultAccountAtom } from "atoms/accounts";
import { chainParametersAtom } from "atoms/chain";
import { defaultGasConfigFamily } from "atoms/fees";
import {
createNotificationId,
Expand All @@ -33,6 +34,7 @@ const IncrementBonding = (): JSX.Element => {
const [filter, setFilter] = useState<string>("");
const [onlyMyValidators, setOnlyMyValidators] = useState(false);
const navigate = useNavigate();
const { data: chainParameters } = useAtomValue(chainParametersAtom);
const accountBalance = useAtomValue(accountBalanceAtom);

const { data: account } = useAtomValue(defaultAccountAtom);
Expand Down Expand Up @@ -204,9 +206,9 @@ const IncrementBonding = (): JSX.Element => {
<GoAlert />
</i>
<p className="text-balance">
Staking will lock and bind your assets to the TODO
unbonding schedule. To make your NAM liquid again, you
will need to unstake.
Staking will lock and bind your assets to an unbonding
schedule of {chainParameters?.unbondingPeriod}. To make
your NAM liquid again, you will need to unstake.
</p>
</div>
</Alert>
Expand Down
14 changes: 2 additions & 12 deletions apps/namadillo/src/App/Staking/Unstake.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ActionButton, Alert, Modal, Panel, Stack } from "@namada/components";
import { UnbondMsgValue, UnbondProps } from "@namada/types";
import { singleUnitDurationFromInterval } from "@namada/utils/helpers";
import { AtomErrorBoundary } from "App/Common/AtomErrorBoundary";
import { Info } from "App/Common/Info";
import { ModalContainer } from "App/Common/ModalContainer";
Expand All @@ -24,19 +23,11 @@ import { useAtomValue, useSetAtom } from "jotai";
import { TransactionPair, broadcastTx } from "lib/query";
import { FormEvent, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { EpochInfo, MyValidator } from "types";
import { MyValidator } from "types";
import { BondingAmountOverview } from "./BondingAmountOverview";
import { UnstakeBondingTable } from "./UnstakeBondingTable";
import StakingRoutes from "./routes";

const getUnbondPeriod = ({
unbondingPeriodInEpochs,
minEpochDuration,
}: EpochInfo): string => {
const duration = unbondingPeriodInEpochs * minEpochDuration;
return singleUnitDurationFromInterval(0, duration);
};

const Unstake = (): JSX.Element => {
const navigate = useNavigate();
const { data: account } = useAtomValue(defaultAccountAtom);
Expand Down Expand Up @@ -161,8 +152,7 @@ const Unstake = (): JSX.Element => {
return "";
})();

const unbondPeriod =
chainParameters ? getUnbondPeriod(chainParameters.epochInfo) : "N/A";
const unbondPeriod = chainParameters?.unbondingPeriod;

return (
<Modal onClose={onCloseModal}>
Expand Down
14 changes: 11 additions & 3 deletions apps/namadillo/src/atoms/chain/atoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import {
rpcUrlAtom,
} from "atoms/settings";
import { queryDependentFn } from "atoms/utils";
import BigNumber from "bignumber.js";
import { atomWithQuery } from "jotai-tanstack-query";
import { ChainParameters, ChainSettings } from "types";
import { calculateUnbondingPeriod } from "./functions";
import { fetchChainParameters, fetchRpcUrlFromIndexer } from "./services";

export const chainAtom = atomWithQuery<ChainSettings>((get) => {
Expand All @@ -30,8 +32,7 @@ export const chainAtom = atomWithQuery<ChainSettings>((get) => {
bench32Prefix: namada.bech32Prefix,
rpcUrl,
chainId: chainParameters.data!.chainId,
unbondingPeriodInEpochs:
chainParameters.data!.epochInfo.unbondingPeriodInEpochs,
unbondingPeriod: chainParameters.data!.unbondingPeriod,
nativeTokenAddress: chainParameters.data!.nativeTokenAddress,
checksums: chainParameters.data!.checksums,
};
Expand Down Expand Up @@ -70,6 +71,13 @@ export const chainParametersAtom = atomWithQuery<ChainParameters>((get) => {
queryKey: ["chain-parameters", indexerUrl],
staleTime: Infinity,
enabled: !!indexerUrl,
queryFn: async () => fetchChainParameters(api),
queryFn: async () => {
const parameters = await fetchChainParameters(api);
return {
...parameters,
apr: BigNumber(parameters.apr),
unbondingPeriod: calculateUnbondingPeriod(parameters),
};
},
};
});
21 changes: 21 additions & 0 deletions apps/namadillo/src/atoms/chain/functions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Parameters } from "@anomaorg/namada-indexer-client";
import { singleUnitDurationFromInterval } from "@namada/utils/helpers";

export const calculateUnbondingPeriod = (parameters: Parameters): string => {
const unbondingPeriodInEpochs =
Number(parameters.unbondingLength) +
Number(parameters.pipelineLength) +
// + 1 because we unbonding period starts from the next epoch
1;
const minEpochDuration = Number(parameters.minDuration);
const maxBlockTime = Number(parameters.maxBlockTime);
const epochSwitchBlocksDelay = Number(parameters.epochSwitchBlocksDelay);

const realMinEpochDuration =
minEpochDuration + maxBlockTime * epochSwitchBlocksDelay;

return singleUnitDurationFromInterval(
0,
unbondingPeriodInEpochs * realMinEpochDuration
);
};
25 changes: 3 additions & 22 deletions apps/namadillo/src/atoms/chain/services.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { DefaultApi } from "@anomaorg/namada-indexer-client";
import BigNumber from "bignumber.js";
import { ChainParameters } from "types";
import { DefaultApi, Parameters } from "@anomaorg/namada-indexer-client";

export const fetchRpcUrlFromIndexer = async (
api: DefaultApi
Expand All @@ -11,24 +9,7 @@ export const fetchRpcUrlFromIndexer = async (

export const fetchChainParameters = async (
api: DefaultApi
): Promise<ChainParameters> => {
): Promise<Parameters> => {
const parametersResponse = await api.apiV1ChainParametersGet();
const parameters = parametersResponse.data;
return {
epochInfo: {
unbondingPeriodInEpochs:
Number(parameters.unbondingLength) +
Number(parameters.pipelineLength) +
// + 1 because we unbonding period starts from the next epoch
1,
minEpochDuration: Number(parameters.minDuration),
minNumOfBlocks: Number(parameters.minNumOfBlocks),
maxBlockTime: Number(parameters.maxBlockTime),
epochSwitchBlocksDelay: Number(parameters.epochSwitchBlocksDelay),
},
apr: BigNumber(parameters.apr),
chainId: parameters.chainId,
nativeTokenAddress: parameters.nativeTokenAddress,
checksums: parameters.checksums,
};
return parametersResponse.data;
};
2 changes: 1 addition & 1 deletion apps/namadillo/src/atoms/validators/atoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export const myValidatorsAtom = atomWithQuery((get) => {
bondedAmounts,
unbondedAmounts,
votingPower.data!,
chainParameters.data!.epochInfo,
chainParameters.data!.unbondingPeriod,
chainParameters.data!.apr
);
}, [account, chainParameters, votingPower]),
Expand Down
23 changes: 9 additions & 14 deletions apps/namadillo/src/atoms/validators/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,17 @@ import {
} from "@anomaorg/namada-indexer-client";
import { singleUnitDurationFromInterval } from "@namada/utils";
import BigNumber from "bignumber.js";
import { Address, EpochInfo, MyValidator, UnbondEntry, Validator } from "types";
import { Address, MyValidator, UnbondEntry, Validator } from "types";

export const toValidator = (
indexerValidator: IndexerValidator,
indexerVotingPower: IndexerVotingPower,
epochInfo: EpochInfo,
unbondingPeriod: string,
nominalApr: BigNumber
): Validator => {
const commission = BigNumber(indexerValidator.commission);
const expectedApr = nominalApr.times(1 - commission.toNumber());

// Because epoch duration is in reality longer by epochSwitchBlocksDelay we have to account for that
const realMinEpochDuration =
epochInfo.minEpochDuration +
epochInfo.maxBlockTime * epochInfo.epochSwitchBlocksDelay;

const unbondingPeriod = singleUnitDurationFromInterval(
0,
epochInfo.unbondingPeriodInEpochs * realMinEpochDuration
);

return {
uuid: indexerValidator.address,
alias: indexerValidator.name,
Expand Down Expand Up @@ -65,7 +55,7 @@ export const toMyValidators = (
indexerBonds: IndexerBond[] | IndexerMergedBond[],
indexerUnbonds: IndexerUnbond[],
totalVotingPower: IndexerVotingPower,
epochInfo: EpochInfo,
unbondingPeriod: string,
apr: BigNumber
): MyValidator[] => {
const myValidators: Record<Address, MyValidator> = {};
Expand All @@ -78,7 +68,12 @@ export const toMyValidators = (
unbondedAmount: new BigNumber(0),
bondItems: [],
unbondItems: [],
validator: toValidator(validator, totalVotingPower, epochInfo, apr),
validator: toValidator(
validator,
totalVotingPower,
unbondingPeriod,
apr
),
};
}
};
Expand Down
3 changes: 1 addition & 2 deletions apps/namadillo/src/atoms/validators/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@ export const fetchAllValidators = async (
chainParameters: ChainParameters,
votingPower: IndexerVotingPower
): Promise<Validator[]> => {
const epochInfo = chainParameters.epochInfo;
const nominalApr = chainParameters.apr;
const validatorsResponse = await api.apiV1PosValidatorAllGet([
IndexerValidatorStatus.Consensus,
]);

const validators = validatorsResponse.data;
return validators.map((v) =>
toValidator(v, votingPower, epochInfo, nominalApr)
toValidator(v, votingPower, chainParameters.unbondingPeriod, nominalApr)
);
};

Expand Down
11 changes: 1 addition & 10 deletions apps/namadillo/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export type ChainSettings = {
nativeTokenAddress: Address;
rpcUrl: string;
chainId: string;
unbondingPeriodInEpochs: number;
extensionId: ExtensionKey;
checksums: Record<string, string>;
};
Expand All @@ -43,19 +42,11 @@ export type SettingsTomlOptions = {
rpc_url?: string;
};

export type EpochInfo = {
unbondingPeriodInEpochs: number;
minEpochDuration: number;
minNumOfBlocks: number;
maxBlockTime: number;
epochSwitchBlocksDelay: number;
};

export type ChainParameters = {
apr: BigNumber;
chainId: string;
nativeTokenAddress: Address;
epochInfo: EpochInfo;
unbondingPeriod: string;
checksums: Record<string, string>;
};

Expand Down
3 changes: 0 additions & 3 deletions packages/sdk/examples/submitTransfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,12 @@ export const submitTransfer = async (
const { cryptoMemory } = initSync();
const sdk = getSdk(cryptoMemory, nodeUrl, "storage path", nativeToken);

console.log("Building transfer transaction...");
const encodedTx = await sdk.tx.buildTransparentTransfer(wrapperTxProps, {
data: [transparentTransferMsgValue],
});

console.log("Signing transaction...");
const signedTx = await sdk.signing.sign(encodedTx, signingKey);

console.log("Broadcasting transaction...");
await sdk.rpc.broadcastTx(signedTx, wrapperTxProps);
process.exit(0);
} catch (error) {
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/src/signing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class Signing {

/**
* Sign Namada transaction
* @param txProps - TxProps
* @param txProps - TxProps
* @param signingKey - private key
* @param [chainId] - optional chain ID, will enforce validation if present
* @returns signed tx bytes - Promise resolving to Uint8Array
Expand Down

1 comment on commit 2e65ae8

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.