Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update unbonding period calculation #1034

Merged
merged 7 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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...");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

lint was complaining about the console.log

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
Loading