Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/koni/dev/issue-2830…
Browse files Browse the repository at this point in the history
…' into subwallet-dev

# Conflicts:
#	packages/extension-base/src/services/earning-service/handlers/native-staking/relay-chain.ts
  • Loading branch information
saltict committed Apr 18, 2024
2 parents d961833 + 1f26603 commit dccfeca
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 21 deletions.
14 changes: 12 additions & 2 deletions packages/extension-base/src/services/chain-service/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const _STAKING_ERA_LENGTH_MAP: Record<string, number> = { // in hours
shiden: 24,
shibuya: 24,
bifrost_testnet: 0.5,
bifrost: 2,
bifrost: 13 * 600 / 3600, // real blocktime of bifros ksm = 13s
bifrost_dot: 24,
ternoa: 24,
calamari: 6,
Expand Down Expand Up @@ -108,7 +108,17 @@ export const _EXPECTED_BLOCK_TIME: Record<string, number> = { // in seconds
creditcoin: 12,
vara_network: 3,
goldberg_testnet: 20,
polimec: 12
polimec: 12,
bifrost: 13, // expect 12 but actual 13
moonbeam: 12,
moonriver: 12,
moonbase: 6,
turing: 12,
turingStaging: 12,
bifrost_testnet: 3,
calamari: 12,
calamari_test: 12,
manta_network: 12
};

export const _PARACHAIN_INFLATION_DISTRIBUTION: Record<string, Record<string, number>> = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chai
import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
import { _STAKING_CHAIN_GROUP } from '@subwallet/extension-base/services/earning-service/constants';
import { parseIdentity } from '@subwallet/extension-base/services/earning-service/utils';
import { BaseYieldPositionInfo, BlockHeader, EarningRewardItem, EarningStatus, NativeYieldPoolInfo, ParachainStakingStakeOption, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, TransactionData, UnstakingStatus, ValidatorInfo, YieldPoolInfo, YieldPositionInfo, YieldStepBaseInfo, YieldStepType, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
import { BaseYieldPositionInfo, EarningRewardItem, EarningStatus, NativeYieldPoolInfo, ParachainStakingStakeOption, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, TransactionData, UnstakingStatus, ValidatorInfo, YieldPoolInfo, YieldPositionInfo, YieldStepBaseInfo, YieldStepType, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
import { balanceFormatter, formatNumber, parseRawNumber, reformatAddress } from '@subwallet/extension-base/utils';

import { SubmittableExtrinsic } from '@polkadot/api/types';
Expand Down Expand Up @@ -186,22 +186,25 @@ export default class AmplitudeNativeStakingPoolHandler extends BaseParaNativeSta
}

if (hasUnstakingInfo) {
const _currentBlockInfo = await substrateApi.api.rpc.chain.getHeader();
const [_currentBlock, _currentTimestamp] = await Promise.all([
substrateApi.api.query.system.number(),
substrateApi.api.query.timestamp.now()
]);

const currentBlockInfo = _currentBlockInfo.toPrimitive() as unknown as BlockHeader;
const currentBlockNumber = currentBlockInfo.number;
const currentBlock = _currentBlock.toPrimitive() as number;
const currentTimestamp = _currentTimestamp.toPrimitive() as number;

const _blockPerRound = substrateApi.api.consts.parachainStaking.defaultBlocksPerRound.toString();
const blockPerRound = parseFloat(_blockPerRound);

for (const [unstakingBlock, unstakingAmount] of Object.entries(unstakingInfo)) {
const blockDuration = (_STAKING_ERA_LENGTH_MAP[chainInfo.slug] || _STAKING_ERA_LENGTH_MAP.default) / blockPerRound; // in hours

const isClaimable = parseInt(unstakingBlock) - currentBlockNumber < 0;
const remainingBlock = parseInt(unstakingBlock) - currentBlockNumber;
const isClaimable = parseInt(unstakingBlock) - currentBlock <= 0;
const remainingBlock = parseInt(unstakingBlock) - currentBlock;
const waitingTime = remainingBlock * blockDuration;
// const currentTimestampMs = Date.now();
// const targetTimestampMs = currentTimestampMs + waitingTime * 60 * 60 * 1000;

const targetTimestampMs = remainingBlock * blockDuration * 3600 * 1000 + currentTimestamp;

unstakingBalance = unstakingAmount.toString();

Expand All @@ -210,7 +213,7 @@ export default class AmplitudeNativeStakingPoolHandler extends BaseParaNativeSta
status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
claimable: unstakingAmount.toString(),
waitingTime,
// targetTimestampMs: targetTimestampMs,
targetTimestampMs: targetTimestampMs,
validatorAddress: undefined
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { _ChainInfo } from '@subwallet/chain-list/types';
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
import { BasicTxErrorType, ExtrinsicType, NominationInfo, UnstakingInfo } from '@subwallet/extension-base/background/KoniTypes';
import { getBondedValidators, getEarningStatusByNominations, getParaCurrentInflation, InflationConfig, isUnstakeAll } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
import { _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chain-service/constants';
import { _EXPECTED_BLOCK_TIME, _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chain-service/constants';
import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
import { _STAKING_CHAIN_GROUP, MANTA_MIN_DELEGATION, MANTA_VALIDATOR_POINTS_PER_BLOCK } from '@subwallet/extension-base/services/earning-service/constants';
import { parseIdentity } from '@subwallet/extension-base/services/earning-service/utils';
Expand Down Expand Up @@ -198,16 +198,20 @@ export default class ParaNativeStakingPoolHandler extends BaseParaNativeStakingP
let bnTotalUnstaking = BN_ZERO;

const _roundInfo = await substrateApi.api.query.parachainStaking.round();
const roundInfo = _roundInfo.toPrimitive() as Record<string, number>;
const roundInfo = _roundInfo.toPrimitive() as unknown as PalletParachainStakingRoundInfo;
const currentRound = roundInfo.current;

await Promise.all(delegatorState.delegations.map(async (delegation) => {
const [_delegationScheduledRequests, [identity], _collatorInfo] = await Promise.all([
const [_delegationScheduledRequests, [identity], _collatorInfo, _currentBlock, _currentTimestamp] = await Promise.all([
substrateApi.api.query.parachainStaking.delegationScheduledRequests(delegation.owner),
parseIdentity(substrateApi, delegation.owner),
substrateApi.api.query.parachainStaking.candidateInfo(delegation.owner)
substrateApi.api.query.parachainStaking.candidateInfo(delegation.owner),
substrateApi.api.query.system.number(),
substrateApi.api.query.timestamp.now()
]);

const currentBlock = _currentBlock.toPrimitive() as number;
const currentTimestamp = _currentTimestamp.toPrimitive() as number;
const collatorInfo = _collatorInfo.toPrimitive() as unknown as ParachainStakingCandidateMetadata;
const minDelegation = collatorInfo?.lowestTopDelegationAmount.toString();
const delegationScheduledRequests = _delegationScheduledRequests.toPrimitive() as unknown as PalletParachainStakingDelegationRequestsScheduledRequest[];
Expand All @@ -219,20 +223,23 @@ export default class ParaNativeStakingPoolHandler extends BaseParaNativeStakingP
if (delegationScheduledRequests) {
for (const scheduledRequest of delegationScheduledRequests) {
if (reformatAddress(scheduledRequest.delegator, 0) === reformatAddress(address, 0)) { // add network prefix
const isClaimable = scheduledRequest.whenExecutable - currentRound <= 0;
const remainingEra = scheduledRequest.whenExecutable - currentRound;
const isClaimable = scheduledRequest.whenExecutable - parseInt(currentRound) <= 0;
const remainingEra = scheduledRequest.whenExecutable - parseInt(currentRound);
const waitingTime = remainingEra * _STAKING_ERA_LENGTH_MAP[chainInfo.slug];
const claimable = Object.values(scheduledRequest.action)[0];
// const currentTimestampMs = Date.now();
// const targetTimestampMs = currentTimestampMs + waitingTime * 60 * 60 * 1000;

// noted: target timestamp in parachainStaking easily volatile if block time volatile
const targetBlock = remainingEra * parseInt(roundInfo.length) + parseInt(roundInfo.first);
const remainingBlock = targetBlock - currentBlock;
const targetTimestampMs = remainingBlock * _EXPECTED_BLOCK_TIME[chainInfo.slug] * 1000 + currentTimestamp;

unstakingMap[delegation.owner] = {
chain: chainInfo.slug,
status: isClaimable ? UnstakingStatus.CLAIMABLE : UnstakingStatus.UNLOCKING,
validatorAddress: delegation.owner,
claimable: claimable.toString(),
waitingTime
// targetTimestampMs: targetTimestampMs
waitingTime,
targetTimestampMs: targetTimestampMs
} as UnstakingInfo;

hasUnstaking = true;
Expand Down

1 comment on commit dccfeca

@saltict
Copy link
Author

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.