feat(proposals): upgrade in progress notification (#4509)

Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
This commit is contained in:
Art 2023-08-16 16:50:38 +02:00 committed by GitHub
parent 9fcf286e4b
commit c937a9df0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 285 additions and 37 deletions

View File

@ -1,6 +1,4 @@
# App configuration variables # App configuration variables
NX_TENDERMINT_URL=http://localhost:26617
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
NX_VEGA_ENV=CUSTOM NX_VEGA_ENV=CUSTOM
NX_ETHERSCAN_URL=https://sepolia.etherscan.io NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
@ -8,3 +6,6 @@ NX_VEGA_EXPLORER_URL=/
# App flags # App flags
NX_EXPLORER_TXS_LIST=0 NX_EXPLORER_TXS_LIST=0
NX_TENDERMINT_URL=http://localhost:26617
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket

View File

@ -1,6 +1,4 @@
# App configuration variables # App configuration variables
NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/
NX_TENDERMINT_WEBSOCKET_URL=wss://be.devnet1.vega.xyz/websocket
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml
NX_VEGA_ENV=DEVNET NX_VEGA_ENV=DEVNET
NX_BLOCK_EXPLORER=https://be.devnet1.vega.xyz/rest NX_BLOCK_EXPLORER=https://be.devnet1.vega.xyz/rest
@ -10,3 +8,6 @@ NX_VEGA_URL=https://api.devnet1.vega.xyz/graphql
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_EXPLORER_URL=/ NX_VEGA_EXPLORER_URL=/
NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/
NX_TENDERMINT_WEBSOCKET_URL=wss://be.devnet1.vega.xyz/websocket

View File

@ -1,6 +1,4 @@
# App configuration variables # App configuration variables
NX_TENDERMINT_URL=https://be.vega.community
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
NX_SENTRY_DSN=https://b3a56b03eda842faad731f3ea9dfd1bc@o286262.ingest.sentry.io/6242427 NX_SENTRY_DSN=https://b3a56b03eda842faad731f3ea9dfd1bc@o286262.ingest.sentry.io/6242427
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml
NX_VEGA_URL=https://api.vega.community/graphql NX_VEGA_URL=https://api.vega.community/graphql
@ -11,3 +9,6 @@ NX_VEGA_GOVERNANCE_URL=https://governance.vega.xyz
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz/ NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz/
NX_VEGA_CONSOLE_URL=https://console.vega.xyz NX_VEGA_CONSOLE_URL=https://console.vega.xyz
NX_TENDERMINT_URL=https://be.vega.community
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket

View File

@ -1,6 +1,4 @@
# App configuration variables # App configuration variables
NX_TENDERMINT_URL=https://be.mainnet-mirror.vega.rocks
NX_TENDERMINT_WEBSOCKET_URL=wss://be.mainnet-mirror.vega.rocks/websocket
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996 NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/mainnet-mirror/vegawallet-mainnet-mirror.toml NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/mainnet-mirror/vegawallet-mainnet-mirror.toml
NX_VEGA_URL=https://api.mainnet-mirror.vega.rocks/graphql NX_VEGA_URL=https://api.mainnet-mirror.vega.rocks/graphql
@ -10,4 +8,7 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_VEGA_GOVERNANCE_URL=https://governance.mainnet-mirror.vega.rocks NX_VEGA_GOVERNANCE_URL=https://governance.mainnet-mirror.vega.rocks
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
NX_VEGA_EXPLORER_URL=https://explorer.mainnet-mirror.vega.rocks/ NX_VEGA_EXPLORER_URL=https://explorer.mainnet-mirror.vega.rocks/
NX_VEGA_CONSOLE_URL=https://console.mainnet-mirror.vega.rocks NX_VEGA_CONSOLE_URL=https://console.mainnet-mirror.vega.rocks
NX_TENDERMINT_URL=https://be.mainnet-mirror.vega.rocks
NX_TENDERMINT_WEBSOCKET_URL=wss://be.mainnet-mirror.vega.rocks/websocket

View File

@ -1,7 +1,5 @@
# App configuration variables # App configuration variables
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
NX_BLOCK_EXPLORER=https://be.testnet.vega.xyz/rest NX_BLOCK_EXPLORER=https://be.testnet.vega.xyz/rest
NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/fairground/vegawallet-fairground.toml NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/fairground/vegawallet-fairground.toml
NX_VEGA_ENV=TESTNET NX_VEGA_ENV=TESTNET
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
@ -11,3 +9,6 @@ NX_VEGA_GOVERNANCE_URL=https://governance.fairground.wtf
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket

View File

@ -7,9 +7,10 @@ NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9
NX_ETHERSCAN_URL=https://sepolia.etherscan.io NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_TENDERMINT_URL=https://tm.be.validators-testnet.vega.rocks
NX_BLOCK_EXPLORER=https://be.validators-testnet.vega.rocks/rest NX_BLOCK_EXPLORER=https://be.validators-testnet.vega.rocks/rest
NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.xyz/websocket
NX_VEGA_GOVERNANCE_URL=https://governance.validators-testnet.vega.rocks NX_VEGA_GOVERNANCE_URL=https://governance.validators-testnet.vega.rocks
NX_VEGA_EXPLORER_URL=https://explorer.validators-testnet.vega.rocks/ NX_VEGA_EXPLORER_URL=https://explorer.validators-testnet.vega.rocks/
NX_VEGA_CONSOLE_URL=https://trading.validators-testnet.vega.rocks/ NX_VEGA_CONSOLE_URL=https://trading.validators-testnet.vega.rocks/
NX_TENDERMINT_URL=https://tm.be.validators-testnet.vega.rocks
NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.xyz/websocket

View File

@ -22,6 +22,11 @@ import { Footer } from '../components/footer/footer';
import { Header } from '../components/header'; import { Header } from '../components/header';
import { Routes } from './route-names'; import { Routes } from './route-names';
import { useExplorerNodeNamesLazyQuery } from './validators/__generated__/NodeNames'; import { useExplorerNodeNamesLazyQuery } from './validators/__generated__/NodeNames';
import {
ProtocolUpgradeCountdownMode,
ProtocolUpgradeInProgressNotification,
ProtocolUpgradeProposalNotification,
} from '@vegaprotocol/proposals';
const DialogsContainer = () => { const DialogsContainer = () => {
const { isOpen, id, trigger, asJson, setOpen } = useAssetDetailsDialogStore(); const { isOpen, id, trigger, asJson, setOpen } = useAssetDetailsDialogStore();
@ -62,6 +67,10 @@ export const Layout = () => {
/> />
)} )}
<Header /> <Header />
<ProtocolUpgradeProposalNotification
mode={ProtocolUpgradeCountdownMode.IN_ESTIMATED_TIME_REMAINING}
/>
<ProtocolUpgradeInProgressNotification />
</div> </div>
<div className={fixedWidthClasses}> <div className={fixedWidthClasses}>
<main className="p-4"> <main className="p-4">

View File

@ -6,6 +6,7 @@ import { Nav } from '../nav';
import { Networks, useEnvironment } from '@vegaprotocol/environment'; import { Networks, useEnvironment } from '@vegaprotocol/environment';
import { import {
ProtocolUpgradeCountdownMode, ProtocolUpgradeCountdownMode,
ProtocolUpgradeInProgressNotification,
ProtocolUpgradeProposalNotification, ProtocolUpgradeProposalNotification,
} from '@vegaprotocol/proposals'; } from '@vegaprotocol/proposals';
import { ViewingAsBanner } from '@vegaprotocol/ui-toolkit'; import { ViewingAsBanner } from '@vegaprotocol/ui-toolkit';
@ -49,6 +50,7 @@ const NotificationsContainer = () => {
<ProtocolUpgradeProposalNotification <ProtocolUpgradeProposalNotification
mode={ProtocolUpgradeCountdownMode.IN_ESTIMATED_TIME_REMAINING} mode={ProtocolUpgradeCountdownMode.IN_ESTIMATED_TIME_REMAINING}
/> />
<ProtocolUpgradeInProgressNotification />
{isReadOnly ? ( {isReadOnly ? (
<ViewingAsBanner pubKey={pubKey} disconnect={disconnect} /> <ViewingAsBanner pubKey={pubKey} disconnect={disconnect} />
) : null} ) : null}

View File

@ -20,3 +20,6 @@ NX_SUCCESSOR_MARKETS=true
NX_STOP_ORDERS=true NX_STOP_ORDERS=true
# NX_ICEBERG_ORDERS # NX_ICEBERG_ORDERS
# NX_PRODUCT_PERPETUALS # NX_PRODUCT_PERPETUALS
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.rocks
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket

View File

@ -20,4 +20,7 @@ NX_ETH_WALLET_MNEMONIC="ozone access unlock valid olympic save include omit supp
NX_SUCCESSOR_MARKETS=false NX_SUCCESSOR_MARKETS=false
NX_STOP_ORDERS=false NX_STOP_ORDERS=false
# NX_ICEBERG_ORDERS # NX_ICEBERG_ORDERS
# NX_PRODUCT_PERPETUALS # NX_PRODUCT_PERPETUALS
NX_TENDERMINT_URL=http://localhost:26617
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket

View File

@ -18,4 +18,7 @@ NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
NX_SUCCESSOR_MARKETS=true NX_SUCCESSOR_MARKETS=true
NX_STOP_ORDERS=true NX_STOP_ORDERS=true
# NX_ICEBERG_ORDERS # NX_ICEBERG_ORDERS
# NX_PRODUCT_PERPETUALS # NX_PRODUCT_PERPETUALS
NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/
NX_TENDERMINT_WEBSOCKET_URL=wss://be.devnet1.vega.xyz/websocket

View File

@ -21,3 +21,6 @@ NX_SUCCESSOR_MARKETS=false
NX_STOP_ORDERS=false NX_STOP_ORDERS=false
# NX_ICEBERG_ORDERS # NX_ICEBERG_ORDERS
# NX_PRODUCT_PERPETUALS # NX_PRODUCT_PERPETUALS
NX_TENDERMINT_URL=https://be.vega.community
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket

View File

@ -20,4 +20,7 @@ NX_APP_VERSION=v0.20.19-core-0.71.6
NX_SUCCESSOR_MARKETS=false NX_SUCCESSOR_MARKETS=false
NX_STOP_ORDERS=false NX_STOP_ORDERS=false
# NX_ICEBERG_ORDERS # NX_ICEBERG_ORDERS
# NX_PRODUCT_PERPETUALS # NX_PRODUCT_PERPETUALS
NX_TENDERMINT_URL=https://be.mainnet-mirror.vega.rocks
NX_TENDERMINT_WEBSOCKET_URL=wss://be.mainnet-mirror.vega.rocks/websocket

View File

@ -19,4 +19,7 @@ NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
NX_SUCCESSOR_MARKETS=true NX_SUCCESSOR_MARKETS=true
NX_STOP_ORDERS=true NX_STOP_ORDERS=true
NX_ICEBERG_ORDERS=true NX_ICEBERG_ORDERS=true
# NX_PRODUCT_PERPETUALS # NX_PRODUCT_PERPETUALS
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket

View File

@ -19,4 +19,7 @@ NX_VEGA_CONSOLE_URL=https://trading.validators-testnet.vega.rocks
NX_SUCCESSOR_MARKETS=false NX_SUCCESSOR_MARKETS=false
NX_STOP_ORDERS=false NX_STOP_ORDERS=false
# NX_ICEBERG_ORDERS # NX_ICEBERG_ORDERS
# NX_PRODUCT_PERPETUALS # NX_PRODUCT_PERPETUALS
NX_TENDERMINT_URL=https://tm.be.validators-testnet.vega.rocks
NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.xyz/websocket

View File

@ -43,6 +43,7 @@ import { Navbar } from '../components/navbar';
import classNames from 'classnames'; import classNames from 'classnames';
import { import {
ProtocolUpgradeCountdownMode, ProtocolUpgradeCountdownMode,
ProtocolUpgradeInProgressNotification,
ProtocolUpgradeProposalNotification, ProtocolUpgradeProposalNotification,
} from '@vegaprotocol/proposals'; } from '@vegaprotocol/proposals';
import { ViewingBanner } from '../components/viewing-banner'; import { ViewingBanner } from '../components/viewing-banner';
@ -111,6 +112,7 @@ function AppBody({ Component }: AppProps) {
<ProtocolUpgradeProposalNotification <ProtocolUpgradeProposalNotification
mode={ProtocolUpgradeCountdownMode.IN_ESTIMATED_TIME_REMAINING} mode={ProtocolUpgradeCountdownMode.IN_ESTIMATED_TIME_REMAINING}
/> />
<ProtocolUpgradeInProgressNotification />
<ViewingBanner /> <ViewingBanner />
<UpgradeBanner showVersionChange={true} /> <UpgradeBanner showVersionChange={true} />
</div> </div>

View File

@ -121,9 +121,12 @@ export function createClient({
// called on startup, NodeCheck and NodeCheckTimeUpdate are called // called on startup, NodeCheck and NodeCheckTimeUpdate are called
// by the NodeSwitcher component and the useNodeHealth hook // by the NodeSwitcher component and the useNodeHealth hook
if ( if (
['NodeGuard', 'NodeCheck', 'NodeCheckTimeUpdate'].includes( [
operation.operationName 'NodeGuard',
) 'NodeCheck',
'NodeCheckTimeUpdate',
'BlockStatistics',
].includes(operation.operationName)
) { ) {
return; return;
} }

View File

@ -29,6 +29,7 @@ const EmptyLinks: DAppLinks = {
const ExplorerLinks = { const ExplorerLinks = {
...EmptyLinks, ...EmptyLinks,
[Networks.STAGNET1]: 'https://explorer.stagnet1.vega.rocks',
[Networks.TESTNET]: 'https://explorer.fairground.wtf', [Networks.TESTNET]: 'https://explorer.fairground.wtf',
[Networks.VALIDATOR_TESTNET]: [Networks.VALIDATOR_TESTNET]:
'https://explorer.validators-testnet.vega.rocks', 'https://explorer.validators-testnet.vega.rocks',
@ -40,17 +41,18 @@ const ConsoleLinks = {
...EmptyLinks, ...EmptyLinks,
[Networks.STAGNET1]: 'https://trading.stagnet1.vega.rocks', [Networks.STAGNET1]: 'https://trading.stagnet1.vega.rocks',
[Networks.TESTNET]: 'https://console.fairground.wtf', [Networks.TESTNET]: 'https://console.fairground.wtf',
[Networks.MAINNET]: 'https://console.vega.xyz', [Networks.MAINNET]: 'https://vega.trading',
[Networks.MAINNET_MIRROR]: 'https://console.mainnet-mirror.vega.rocks/', [Networks.MAINNET_MIRROR]: 'https://console.mainnet-mirror.vega.rocks',
}; };
const TokenLinks = { const TokenLinks = {
...EmptyLinks, ...EmptyLinks,
[Networks.DEVNET]: 'https://dev.governance.vega.xyz', [Networks.DEVNET]: 'https://dev.governance.vega.xyz',
[Networks.STAGNET1]: 'https://governance.stagnet1.vega.rocks',
[Networks.TESTNET]: 'https://governance.fairground.wtf', [Networks.TESTNET]: 'https://governance.fairground.wtf',
[Networks.VALIDATOR_TESTNET]: [Networks.VALIDATOR_TESTNET]:
'https://governance.validators-testnet.vega.rocks', 'https://governance.validators-testnet.vega.rocks',
[Networks.MAINNET_MIRROR]: 'https://governance.mainnet-mirror.vega.rocks/', [Networks.MAINNET_MIRROR]: 'https://governance.mainnet-mirror.vega.rocks',
[Networks.MAINNET]: 'https://governance.vega.xyz', [Networks.MAINNET]: 'https://governance.vega.xyz',
}; };

View File

@ -1,6 +1,7 @@
export * from './asset-proposal-notification'; export * from './asset-proposal-notification';
export * from './market-proposal-notification'; export * from './market-proposal-notification';
export * from './protocol-upgrade-countdown';
export * from './protocol-upgrade-proposal-notification';
export * from './proposals-list'; export * from './proposals-list';
export * from './protocol-upgrade-countdown';
export * from './protocol-upgrade-in-progress-notification';
export * from './protocol-upgrade-proposal-notification';
export * from './voting-progress'; export * from './voting-progress';

View File

@ -0,0 +1,77 @@
import { useProtocolUpgradeProposalLink } from '@vegaprotocol/environment';
import { t } from '@vegaprotocol/i18n';
import {
ExternalLink,
Intent,
NotificationBanner,
SHORT,
} from '@vegaprotocol/ui-toolkit';
import type { StoredNextProtocolUpgradeData } from '../lib';
import {
NEXT_PROTOCOL_UPGRADE_PROPOSAL_SNAPSHOT,
useNextProtocolUpgradeProposal,
} from '../lib';
import { useLocalStorageSnapshot } from '@vegaprotocol/react-helpers';
import { useBlockRising } from '../lib/protocol-upgrade-proposals/use-block-rising';
/**
* A flag determining whether to get the upgrade proposal data from local
* storage if `useNextProtocolUpgradeProposal` fails.
*/
const ALLOW_STORED_PROPOSAL_DATA = true;
export const ProtocolUpgradeInProgressNotification = () => {
const { data, error } = useNextProtocolUpgradeProposal(undefined, true);
const [nextUpgrade] = useLocalStorageSnapshot(
NEXT_PROTOCOL_UPGRADE_PROPOSAL_SNAPSHOT
);
const { blocksRising, block } = useBlockRising();
const detailsLink = useProtocolUpgradeProposalLink();
let vegaReleaseTag: string | undefined;
let upgradeBlockHeight: string | undefined;
if (error && !data && nextUpgrade && ALLOW_STORED_PROPOSAL_DATA) {
try {
const stored = JSON.parse(nextUpgrade) as StoredNextProtocolUpgradeData;
vegaReleaseTag = stored.vegaReleaseTag;
upgradeBlockHeight = stored.upgradeBlockHeight;
} catch {
// no op
}
}
/**
* If upgrade is in progress then none of the nodes should produce blocks,
* same should be with the tendermint block info otherwise it's a network
* issue and not an upgrade. The upgrade usually lasts for couple of minutes.
*
* Once the networks is back then the notification disappears.
*/
const upgradeInProgress =
vegaReleaseTag &&
upgradeBlockHeight &&
!blocksRising &&
block <= Number(upgradeBlockHeight);
if (!upgradeInProgress) return null;
return (
<NotificationBanner intent={Intent.Danger} className={SHORT}>
<div className="uppercase">
{t('The network is being upgraded to %s', vegaReleaseTag)}
</div>
<div>
{t(
'Trading and other network activity has stopped until the upgrade is complete.'
)}{' '}
{vegaReleaseTag && (
<ExternalLink href={detailsLink(vegaReleaseTag)}>
{t('View details')}
</ExternalLink>
)}
</div>
</NotificationBanner>
);
};

View File

@ -29,27 +29,32 @@ export const ProtocolUpgradeProposalNotification = ({
const { vegaReleaseTag, upgradeBlockHeight } = data; const { vegaReleaseTag, upgradeBlockHeight } = data;
let timeLeft = time;
let blocksLeft = Number(upgradeBlockHeight) - Number(lastBlockHeight);
if (blocksLeft < 0) {
blocksLeft = 0;
timeLeft = 0;
}
let countdown; let countdown;
switch (mode) { switch (mode) {
case ProtocolUpgradeCountdownMode.IN_BLOCKS: case ProtocolUpgradeCountdownMode.IN_BLOCKS:
countdown = ( countdown = (
<> <>
<span className="text-vega-orange-500"> <span className="text-vega-orange-500">{blocksLeft}</span>{' '}
{Number(upgradeBlockHeight) - Number(lastBlockHeight)}
</span>{' '}
{t('blocks')} {t('blocks')}
</> </>
); );
break; break;
case ProtocolUpgradeCountdownMode.IN_ESTIMATED_TIME_REMAINING: case ProtocolUpgradeCountdownMode.IN_ESTIMATED_TIME_REMAINING:
countdown = countdown =
time !== undefined ? ( timeLeft !== undefined ? (
<span <span
title={t('estimated time to protocol upgrade')} title={t('estimated time to protocol upgrade')}
className="text-vega-orange-500" className="text-vega-orange-500"
data-testid="upgrade-proposal-estimate" data-testid="upgrade-proposal-estimate"
> >
{convertToCountdownString(time, '0:00:00:00')} {convertToCountdownString(timeLeft, '0:00:00:00')}
</span> </span>
) : ( ) : (
<span className="text-vega-orange-600 lowercase italic"> <span className="text-vega-orange-600 lowercase italic">

View File

@ -1,3 +1,4 @@
export * from './__generated__/ProtocolUpgradeProposals'; export * from './__generated__/ProtocolUpgradeProposals';
export * from './use-block-rising';
export * from './use-next-protocol-upgrade-proposals'; export * from './use-next-protocol-upgrade-proposals';
export * from './use-time-to-upgrade'; export * from './use-time-to-upgrade';

View File

@ -0,0 +1,92 @@
import { createClient } from '@vegaprotocol/apollo-client';
import { useEnvironment } from '@vegaprotocol/environment';
import { useBlockInfo } from '@vegaprotocol/tendermint';
import { useEffect, useMemo, useState } from 'react';
import type { BlockStatisticsQuery } from './__generated__/BlockStatistics';
import { BlockStatisticsDocument } from './__generated__/BlockStatistics';
import compact from 'lodash/compact';
import max from 'lodash/max';
const CHECK_INTERVAL = 5000; // ms
/**
* Allows stale block height for given number of times. If stale count is
* greater than this number then it is marked as not rising (producing blocks).
*/
const ALLOW_STALE = 2; // times -> MAX(this, 1) * CHECK_INTERVAL ~> min check time
export const useBlockRising = () => {
const [blocksRising, setBlocksRising] = useState(true);
const [block, setBlock] = useState(0);
const nodes = useEnvironment((state) => state.nodes);
const clients = useMemo(() => {
return nodes.map(
(n) =>
n &&
n.length > 0 &&
createClient({
url: n,
cacheConfig: undefined,
retry: false,
connectToDevTools: false,
connectToHeaderStore: true,
})
);
}, [nodes]);
const { refetch: fetchBlockInfo } = useBlockInfo();
useEffect(() => {
let stale = 0;
let prev = 0;
const check = async () => {
const queries = clients.map((client, index) =>
client
? client
.query<BlockStatisticsQuery>({
query: BlockStatisticsDocument,
fetchPolicy: 'network-only',
errorPolicy: 'ignore',
})
.catch((err) =>
Promise.reject(
`could not retrieve statistics from ${nodes[index]}`
)
)
: undefined
);
const blockInfo = await fetchBlockInfo();
const results = (await Promise.allSettled(compact(queries))).map(
(res) => {
if (res && res.status === 'fulfilled') {
return res.value.data.statistics;
} else {
return undefined;
}
}
);
const heights = compact([
...results.map((r) => r?.blockHeight),
blockInfo?.result.block.header.height,
]);
const current = max(heights);
if (current && Number(current) > prev) {
setBlock(Number(current));
prev = Number(current);
stale = 0;
if (!blocksRising) setBlocksRising(true);
} else {
if (stale > ALLOW_STALE) setBlocksRising(false);
stale++;
}
};
const interval = setInterval(check, CHECK_INTERVAL);
check();
return () => {
clearInterval(interval);
};
}, [clients, fetchBlockInfo, blocksRising, nodes]);
return { blocksRising, block };
};

View File

@ -2,6 +2,13 @@ import { useMemo, useEffect } from 'react';
import * as Schema from '@vegaprotocol/types'; import * as Schema from '@vegaprotocol/types';
import { removePaginationWrapper, isTestEnv } from '@vegaprotocol/utils'; import { removePaginationWrapper, isTestEnv } from '@vegaprotocol/utils';
import { useProtocolUpgradeProposalsQuery } from './__generated__/ProtocolUpgradeProposals'; import { useProtocolUpgradeProposalsQuery } from './__generated__/ProtocolUpgradeProposals';
import { useLocalStorageSnapshot } from '@vegaprotocol/react-helpers';
import pick from 'lodash/pick';
const POLL_INTERVAL = 5000; // ms
export const NEXT_PROTOCOL_UPGRADE_PROPOSAL_SNAPSHOT =
'next_protocol_upgrade_proposal';
export const useNextProtocolUpgradeProposals = (since?: number) => { export const useNextProtocolUpgradeProposals = (since?: number) => {
const { data, loading, error, startPolling, stopPolling } = const { data, loading, error, startPolling, stopPolling } =
@ -22,7 +29,7 @@ export const useNextProtocolUpgradeProposals = (since?: number) => {
} }
if (!isTestEnv() && window.location.hostname !== 'localhost') { if (!isTestEnv() && window.location.hostname !== 'localhost') {
startPolling(5000); startPolling(POLL_INTERVAL);
} }
}, [error, startPolling, stopPolling]); }, [error, startPolling, stopPolling]);
@ -51,10 +58,28 @@ export const useNextProtocolUpgradeProposals = (since?: number) => {
}; };
}; };
export const useNextProtocolUpgradeProposal = (since?: number) => { export type StoredNextProtocolUpgradeData = {
vegaReleaseTag: string;
upgradeBlockHeight: string;
};
export const useNextProtocolUpgradeProposal = (
since?: number,
persist = false
) => {
const { data, lastBlockHeight, loading, error } = const { data, lastBlockHeight, loading, error } =
useNextProtocolUpgradeProposals(since); useNextProtocolUpgradeProposals(since);
const [, setNextUpgrade] = useLocalStorageSnapshot(
NEXT_PROTOCOL_UPGRADE_PROPOSAL_SNAPSHOT
);
useEffect(() => {
if (data && persist) {
setNextUpgrade(
JSON.stringify(pick(data, 'upgradeBlockHeight', 'vegaReleaseTag'))
);
}
}, [data, persist, setNextUpgrade]);
return { return {
data: !data ? undefined : data[0], data: !data ? undefined : data[0],
lastBlockHeight, lastBlockHeight,

View File

@ -1,4 +1,4 @@
{ {
"name": "tendermint", "name": "@vegaprotocol/tendermint",
"version": "0.0.1" "version": "0.0.1"
} }

View File

@ -5,7 +5,7 @@ import type { TendermintBlockResponse } from '../types';
export const useBlockInfo = (blockHeight?: number, canFetch = true) => { export const useBlockInfo = (blockHeight?: number, canFetch = true) => {
const { TENDERMINT_URL } = useEnvironment(); const { TENDERMINT_URL } = useEnvironment();
const url = `${TENDERMINT_URL}/block?height=${blockHeight}`; const url = `${TENDERMINT_URL}/block?height=${blockHeight || ''}`;
const canFetchData = Boolean( const canFetchData = Boolean(
TENDERMINT_URL && blockHeight && !isNaN(blockHeight) && canFetch TENDERMINT_URL && blockHeight && !isNaN(blockHeight) && canFetch
); );

View File

@ -4,6 +4,8 @@ import { Intent } from '../../utils/intent';
import { Icon } from '../icon'; import { Icon } from '../icon';
import type { HTMLAttributes } from 'react'; import type { HTMLAttributes } from 'react';
export const SHORT = '!px-1 !py-1 min-h-fit';
interface NotificationBannerProps { interface NotificationBannerProps {
intent?: Intent; intent?: Intent;
children?: React.ReactNode; children?: React.ReactNode;

View File

@ -1,5 +1,5 @@
import { t } from '@vegaprotocol/i18n'; import { t } from '@vegaprotocol/i18n';
import { NotificationBanner } from '../notification-banner'; import { NotificationBanner, SHORT } from '../notification-banner';
import { Intent } from '../../utils/intent'; import { Intent } from '../../utils/intent';
import { TradingButton } from '../trading-button'; import { TradingButton } from '../trading-button';
@ -25,7 +25,7 @@ export const ViewingAsBanner = ({
<NotificationBanner <NotificationBanner
data-testid="view-banner" data-testid="view-banner"
intent={Intent.None} intent={Intent.None}
className="!px-1 !py-1 min-h-fit" className={SHORT}
> >
<div className="flex justify-between items-baseline"> <div className="flex justify-between items-baseline">
<span> <span>