Commit f4306021 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Optimism and Arbitrum rollups updates (#2414)

* OP rollups: add ENV to show/hide "Output roots" page

* Rename status labels for Arbitrum blocks and transactions
parent 9a08b89a
...@@ -16,15 +16,23 @@ const L2WithdrawalUrl = getEnvValue('NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL'); ...@@ -16,15 +16,23 @@ const L2WithdrawalUrl = getEnvValue('NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL');
const title = 'Rollup (L2) chain'; const title = 'Rollup (L2) chain';
const config: Feature<{ type: RollupType; L1BaseUrl: string; L2WithdrawalUrl?: string; homepage: { showLatestBlocks: boolean } }> = (() => { const config: Feature<{
type: RollupType;
L1BaseUrl: string;
homepage: { showLatestBlocks: boolean };
outputRootsEnabled: boolean;
L2WithdrawalUrl: string | undefined;
parentChainName: string | undefined;
}> = (() => {
if (type && L1BaseUrl) { if (type && L1BaseUrl) {
return Object.freeze({ return Object.freeze({
title, title,
isEnabled: true, isEnabled: true,
type, type,
L1BaseUrl: stripTrailingSlash(L1BaseUrl), L1BaseUrl: stripTrailingSlash(L1BaseUrl),
L2WithdrawalUrl, L2WithdrawalUrl: type === 'optimistic' ? L2WithdrawalUrl : undefined,
outputRootsEnabled: type === 'optimistic' && getEnvValue('NEXT_PUBLIC_ROLLUP_OUTPUT_ROOTS_ENABLED') !== 'false',
parentChainName: type === 'arbitrum' ? getEnvValue('NEXT_PUBLIC_ROLLUP_PARENT_CHAIN_NAME') : undefined,
homepage: { homepage: {
showLatestBlocks: getEnvValue('NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS') === 'true', showLatestBlocks: getEnvValue('NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS') === 'true',
}, },
......
...@@ -287,6 +287,28 @@ const rollupSchema = yup ...@@ -287,6 +287,28 @@ const rollupSchema = yup
then: (schema) => schema.test(urlTest).required(), then: (schema) => schema.test(urlTest).required(),
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL can be used only if NEXT_PUBLIC_ROLLUP_TYPE is set to \'optimistic\' '), otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL can be used only if NEXT_PUBLIC_ROLLUP_TYPE is set to \'optimistic\' '),
}), }),
NEXT_PUBLIC_ROLLUP_OUTPUT_ROOTS_ENABLED: yup
.boolean()
.when('NEXT_PUBLIC_ROLLUP_TYPE', {
is: 'optimistic',
then: (schema) => schema,
otherwise: (schema) => schema.test(
'not-exist',
'NEXT_PUBLIC_ROLLUP_OUTPUT_ROOTS_ENABLED can only be used if NEXT_PUBLIC_ROLLUP_TYPE is set to \'optimistic\' ',
value => value === undefined,
),
}),
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN_NAME: yup
.string()
.when('NEXT_PUBLIC_ROLLUP_TYPE', {
is: 'arbitrum',
then: (schema) => schema,
otherwise: (schema) => schema.test(
'not-exist',
'NEXT_PUBLIC_ROLLUP_PARENT_CHAIN_NAME can only be used if NEXT_PUBLIC_ROLLUP_TYPE is set to \'arbitrum\' ',
value => value === undefined,
),
}),
NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS: yup NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS: yup
.boolean() .boolean()
.when('NEXT_PUBLIC_ROLLUP_TYPE', { .when('NEXT_PUBLIC_ROLLUP_TYPE', {
......
NEXT_PUBLIC_ROLLUP_TYPE=arbitrum
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://example.com
NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS=true
NEXT_PUBLIC_ROLLUP_PARENT_CHAIN_NAME=DuckChain
\ No newline at end of file
...@@ -3,3 +3,4 @@ NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://example.com ...@@ -3,3 +3,4 @@ NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://example.com
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://example.com NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://example.com
NEXT_PUBLIC_FAULT_PROOF_ENABLED=true NEXT_PUBLIC_FAULT_PROOF_ENABLED=true
NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS=true NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS=true
NEXT_PUBLIC_ROLLUP_OUTPUT_ROOTS_ENABLED=false
\ No newline at end of file
...@@ -439,6 +439,8 @@ This feature is **enabled by default** with the `coinzilla` ads provider. To swi ...@@ -439,6 +439,8 @@ This feature is **enabled by default** with the `coinzilla` ads provider. To swi
| NEXT_PUBLIC_FAULT_PROOF_ENABLED | `boolean` | Set to `true` for chains with fault proof system enabled (Optimistic stack only) | - | - | `true` | v1.31.0+ | | NEXT_PUBLIC_FAULT_PROOF_ENABLED | `boolean` | Set to `true` for chains with fault proof system enabled (Optimistic stack only) | - | - | `true` | v1.31.0+ |
| NEXT_PUBLIC_HAS_MUD_FRAMEWORK | `boolean` | Set to `true` for instances that use MUD framework (Optimistic stack only) | - | - | `true` | v1.33.0+ | | NEXT_PUBLIC_HAS_MUD_FRAMEWORK | `boolean` | Set to `true` for instances that use MUD framework (Optimistic stack only) | - | - | `true` | v1.33.0+ |
| NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS | `boolean` | Set to `true` to display "Latest blocks" widget instead of "Latest batches" on the home page | - | - | `true` | v1.36.0+ | | NEXT_PUBLIC_ROLLUP_HOMEPAGE_SHOW_LATEST_BLOCKS | `boolean` | Set to `true` to display "Latest blocks" widget instead of "Latest batches" on the home page | - | - | `true` | v1.36.0+ |
| NEXT_PUBLIC_ROLLUP_OUTPUT_ROOTS_ENABLED | `boolean` | Enables "Output roots" page (Optimistic stack only) | - | `true` | `false` | v1.37.0+ |
| NEXT_PUBLIC_ROLLUP_PARENT_CHAIN_NAME | `string` | Set to customize L1 transaction status labels in the UI (e.g., "Sent to <chain-name>"). This setting is applicable only for Arbitrum-based chains. | - | - | `DuckChain` | v1.37.0+ |
&nbsp; &nbsp;
......
...@@ -120,7 +120,7 @@ export default function useNavItems(): ReturnType { ...@@ -120,7 +120,7 @@ export default function useNavItems(): ReturnType {
blocks, blocks,
rollupTxnBatches, rollupTxnBatches,
rollupDisputeGames, rollupDisputeGames,
rollupFeature.type === 'optimistic' ? rollupOutputRoots : undefined, rollupFeature.outputRootsEnabled ? rollupOutputRoots : undefined,
].filter(Boolean), ].filter(Boolean),
[ [
userOps, userOps,
......
import type { ArbitrumBatchStatus, ArbitrumL2TxData } from 'types/api/arbitrumL2'; import { ARBITRUM_L2_TX_BATCH_STATUSES, type ArbitrumBatchStatus, type ArbitrumL2TxData } from 'types/api/arbitrumL2';
import config from 'configs/app';
const rollupFeature = config.features.rollup;
type Args = { type Args = {
status: ArbitrumBatchStatus; status: ArbitrumBatchStatus;
...@@ -6,7 +10,19 @@ type Args = { ...@@ -6,7 +10,19 @@ type Args = {
confirmation_transaction: ArbitrumL2TxData; confirmation_transaction: ArbitrumL2TxData;
}; };
export default function getArbitrumVerificationStepStatus({ export const VERIFICATION_STEPS_MAP: Record<ArbitrumBatchStatus, string> = {
'Processed on rollup': 'Processed on rollup',
'Sent to base': rollupFeature.isEnabled && rollupFeature.parentChainName ? `Sent to ${ rollupFeature.parentChainName }` : 'Sent to parent chain',
'Confirmed on base': rollupFeature.isEnabled && rollupFeature.parentChainName ?
`Confirmed on ${ rollupFeature.parentChainName }` :
'Confirmed on parent chain',
};
export const verificationSteps = (() => {
return ARBITRUM_L2_TX_BATCH_STATUSES.map((status) => VERIFICATION_STEPS_MAP[status]);
})();
export function getVerificationStepStatus({
status, status,
commitment_transaction: commitTx, commitment_transaction: commitTx,
confirmation_transaction: confirmTx, confirmation_transaction: confirmTx,
......
...@@ -340,6 +340,33 @@ export const celoTxn: Transaction = { ...@@ -340,6 +340,33 @@ export const celoTxn: Transaction = {
}, },
}; };
export const arbitrumTxn: Transaction = {
...base,
arbitrum: {
batch_number: 743991,
commitment_transaction: {
hash: '0x71a25e01dde129a308704de217d200ea42e0f5b8c221c8ba8b2b680ff347f708',
status: 'unfinalized',
timestamp: '2024-11-19T14:26:23.000000Z',
},
confirmation_transaction: {
hash: null,
status: null,
timestamp: null,
},
contains_message: null,
gas_used_for_l1: '129773',
gas_used_for_l2: '128313',
message_related_info: {
associated_l1_transaction: null,
message_status: 'Relayed',
},
network_fee: '1283130000000',
poster_fee: '1297730000000',
status: 'Sent to base',
},
};
export const base2 = { export const base2 = {
...base, ...base,
hash: '0x02d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3193', hash: '0x02d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3193',
......
...@@ -102,8 +102,8 @@ export const rollup: GetServerSideProps<Props> = async(context) => { ...@@ -102,8 +102,8 @@ export const rollup: GetServerSideProps<Props> = async(context) => {
return base(context); return base(context);
}; };
export const optimisticRollup: GetServerSideProps<Props> = async(context) => { export const outputRoots: GetServerSideProps<Props> = async(context) => {
if (!(rollupFeature.isEnabled && rollupFeature.type === 'optimistic')) { if (!(rollupFeature.isEnabled && rollupFeature.outputRootsEnabled)) {
return { return {
notFound: true, notFound: true,
}; };
......
...@@ -16,4 +16,4 @@ const Page: NextPage = () => { ...@@ -16,4 +16,4 @@ const Page: NextPage = () => {
export default Page; export default Page;
export { optimisticRollup as getServerSideProps } from 'nextjs/getServerSideProps'; export { outputRoots as getServerSideProps } from 'nextjs/getServerSideProps';
...@@ -25,6 +25,7 @@ export const ENVS_MAP: Record<string, Array<[string, string]>> = { ...@@ -25,6 +25,7 @@ export const ENVS_MAP: Record<string, Array<[string, string]>> = {
arbitrumRollup: [ arbitrumRollup: [
[ 'NEXT_PUBLIC_ROLLUP_TYPE', 'arbitrum' ], [ 'NEXT_PUBLIC_ROLLUP_TYPE', 'arbitrum' ],
[ 'NEXT_PUBLIC_ROLLUP_L1_BASE_URL', 'https://localhost:3101' ], [ 'NEXT_PUBLIC_ROLLUP_L1_BASE_URL', 'https://localhost:3101' ],
[ 'NEXT_PUBLIC_ROLLUP_PARENT_CHAIN_NAME', 'DuckChain' ],
], ],
shibariumRollup: [ shibariumRollup: [
[ 'NEXT_PUBLIC_ROLLUP_TYPE', 'shibarium' ], [ 'NEXT_PUBLIC_ROLLUP_TYPE', 'shibarium' ],
......
...@@ -5,7 +5,6 @@ import { useRouter } from 'next/router'; ...@@ -5,7 +5,6 @@ import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import { scroller, Element } from 'react-scroll'; import { scroller, Element } from 'react-scroll';
import { ARBITRUM_L2_TX_BATCH_STATUSES } from 'types/api/arbitrumL2';
import { ZKSYNC_L2_TX_BATCH_STATUSES } from 'types/api/zkSyncL2'; import { ZKSYNC_L2_TX_BATCH_STATUSES } from 'types/api/zkSyncL2';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
...@@ -13,10 +12,10 @@ import { route } from 'nextjs-routes'; ...@@ -13,10 +12,10 @@ import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import getBlockReward from 'lib/block/getBlockReward'; import getBlockReward from 'lib/block/getBlockReward';
import { GWEI, WEI, WEI_IN_GWEI, ZERO } from 'lib/consts'; import { GWEI, WEI, WEI_IN_GWEI, ZERO } from 'lib/consts';
import getArbitrumVerificationStepStatus from 'lib/getArbitrumVerificationStepStatus';
import { space } from 'lib/html-entities'; import { space } from 'lib/html-entities';
import getNetworkValidationActionText from 'lib/networks/getNetworkValidationActionText'; import getNetworkValidationActionText from 'lib/networks/getNetworkValidationActionText';
import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle'; import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle';
import * as arbitrum from 'lib/rollups/arbitrum';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
import { currencyUnits } from 'lib/units'; import { currencyUnits } from 'lib/units';
import OptimisticL2TxnBatchDA from 'ui/shared/batch/OptimisticL2TxnBatchDA'; import OptimisticL2TxnBatchDA from 'ui/shared/batch/OptimisticL2TxnBatchDA';
...@@ -318,9 +317,9 @@ const BlockDetails = ({ query }: Props) => { ...@@ -318,9 +317,9 @@ const BlockDetails = ({ query }: Props) => {
<VerificationSteps steps={ ZKSYNC_L2_TX_BATCH_STATUSES } currentStep={ data.zksync.status } isLoading={ isPlaceholderData }/> } <VerificationSteps steps={ ZKSYNC_L2_TX_BATCH_STATUSES } currentStep={ data.zksync.status } isLoading={ isPlaceholderData }/> }
{ rollupFeature.type === 'arbitrum' && data.arbitrum && ( { rollupFeature.type === 'arbitrum' && data.arbitrum && (
<VerificationSteps <VerificationSteps
steps={ ARBITRUM_L2_TX_BATCH_STATUSES } steps={ arbitrum.verificationSteps }
currentStep={ data.arbitrum.status } currentStep={ arbitrum.VERIFICATION_STEPS_MAP[data.arbitrum.status] }
currentStepPending={ getArbitrumVerificationStepStatus(data.arbitrum) === 'pending' } currentStepPending={ arbitrum.getVerificationStepStatus(data.arbitrum) === 'pending' }
isLoading={ isPlaceholderData } isLoading={ isPlaceholderData }
/> />
) } ) }
......
...@@ -117,3 +117,12 @@ test('stability customization', async({ render, page, mockEnvs }) => { ...@@ -117,3 +117,12 @@ test('stability customization', async({ render, page, mockEnvs }) => {
maskColor: pwConfig.maskColor, maskColor: pwConfig.maskColor,
}); });
}); });
test('arbitrum L1 status', async({ render, mockEnvs }) => {
await mockEnvs(ENVS_MAP.arbitrumRollup);
const component = await render(<TxInfo data={ txMock.arbitrumTxn } isLoading={ false }/>);
const statusElement = component.locator('div').filter({ hasText: 'Processed on rollup' }).nth(2);
await expect(statusElement).toHaveScreenshot();
});
...@@ -16,7 +16,6 @@ import BigNumber from 'bignumber.js'; ...@@ -16,7 +16,6 @@ import BigNumber from 'bignumber.js';
import React from 'react'; import React from 'react';
import { scroller, Element } from 'react-scroll'; import { scroller, Element } from 'react-scroll';
import { ARBITRUM_L2_TX_BATCH_STATUSES } from 'types/api/arbitrumL2';
import type { Transaction } from 'types/api/transaction'; import type { Transaction } from 'types/api/transaction';
import { ZKEVM_L2_TX_STATUSES } from 'types/api/transaction'; import { ZKEVM_L2_TX_STATUSES } from 'types/api/transaction';
import { ZKSYNC_L2_TX_BATCH_STATUSES } from 'types/api/zkSyncL2'; import { ZKSYNC_L2_TX_BATCH_STATUSES } from 'types/api/zkSyncL2';
...@@ -25,8 +24,8 @@ import { route } from 'nextjs-routes'; ...@@ -25,8 +24,8 @@ import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import { WEI, WEI_IN_GWEI } from 'lib/consts'; import { WEI, WEI_IN_GWEI } from 'lib/consts';
import getArbitrumVerificationStepStatus from 'lib/getArbitrumVerificationStepStatus';
import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle'; import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle';
import * as arbitrum from 'lib/rollups/arbitrum';
import { MESSAGE_DESCRIPTIONS } from 'lib/tx/arbitrumMessageStatusDescription'; import { MESSAGE_DESCRIPTIONS } from 'lib/tx/arbitrumMessageStatusDescription';
import getConfirmationDuration from 'lib/tx/getConfirmationDuration'; import getConfirmationDuration from 'lib/tx/getConfirmationDuration';
import { currencyUnits } from 'lib/units'; import { currencyUnits } from 'lib/units';
...@@ -239,9 +238,9 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => { ...@@ -239,9 +238,9 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
</DetailsInfoItem.Label> </DetailsInfoItem.Label>
<DetailsInfoItem.Value> <DetailsInfoItem.Value>
<VerificationSteps <VerificationSteps
currentStep={ data.arbitrum.status } currentStep={ arbitrum.VERIFICATION_STEPS_MAP[data.arbitrum.status] }
currentStepPending={ getArbitrumVerificationStepStatus(data.arbitrum) === 'pending' } currentStepPending={ arbitrum.getVerificationStepStatus(data.arbitrum) === 'pending' }
steps={ ARBITRUM_L2_TX_BATCH_STATUSES } steps={ arbitrum.verificationSteps }
isLoading={ isLoading } isLoading={ isLoading }
/> />
</DetailsInfoItem.Value> </DetailsInfoItem.Value>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment