diff --git a/alm/src/abis/ForeignAMB.ts b/alm/src/abis/ForeignAMB.ts index d49572e6..e72b7e81 100644 --- a/alm/src/abis/ForeignAMB.ts +++ b/alm/src/abis/ForeignAMB.ts @@ -123,6 +123,24 @@ const abi: AbiItem[] = [ stateMutability: 'nonpayable', type: 'function' }, + { + constant: false, + inputs: [ + { + name: '_data', + type: 'bytes' + }, + { + name: '_signatures', + type: 'bytes' + } + ], + name: 'safeExecuteSignaturesWithAutoGasLimit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, { constant: true, inputs: [ diff --git a/alm/src/components/ExecutionConfirmation.tsx b/alm/src/components/ExecutionConfirmation.tsx index 0ee1ff88..c8ddced0 100644 --- a/alm/src/components/ExecutionConfirmation.tsx +++ b/alm/src/components/ExecutionConfirmation.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useEffect, useState } from 'react' import { formatTimestamp, formatTxHash, getExplorerTxUrl } from '../utils/networks' import { useWindowWidth } from '@react-hook/window-size' import { SEARCHING_TX, VALIDATOR_CONFIRMATION_STATUS, ALM_HOME_TO_FOREIGN_MANUAL_EXECUTION } from '../config/constants' @@ -9,6 +9,7 @@ import { GreyLabel, RedLabel, SuccessLabel } from './commons/Labels' import { ExplorerTxLink } from './commons/ExplorerTxLink' import { Thead, AgeTd, StatusTd } from './commons/Table' import { ManualExecutionButton } from './ManualExecutionButton' +import { useStateProvider } from '../state/StateProvider' const StyledExecutionConfirmation = styled.div` margin-top: 30px; @@ -33,6 +34,8 @@ export const ExecutionConfirmation = ({ executionEventsFetched, setPendingExecution }: ExecutionConfirmationParams) => { + const { foreign } = useStateProvider() + const [safeExecutionAvailable, setSafeExecutionAvailable] = useState(false) const availableManualExecution = !isHome && (executionData.status === VALIDATOR_CONFIRMATION_STATUS.WAITING || @@ -48,6 +51,22 @@ export const ExecutionConfirmation = ({ const formattedValidator = windowWidth < 850 && executionData.validator ? formatTxHash(executionData.validator) : executionData.validator + useEffect( + () => { + if (!availableManualExecution || !foreign.bridgeContract) return + + const p = foreign.bridgeContract.methods.getBridgeInterfacesVersion().call() + p.then(({ major, minor }: any) => { + major = parseInt(major, 10) + minor = parseInt(minor, 10) + if (major < 5 || (major === 5 && minor < 7)) return + + setSafeExecutionAvailable(true) + }) + }, + [availableManualExecution, foreign.bridgeContract] + ) + const getExecutionStatusElement = (validatorStatus = '') => { switch (validatorStatus) { case VALIDATOR_CONFIRMATION_STATUS.SUCCESS: @@ -105,6 +124,7 @@ export const ExecutionConfirmation = ({ {availableManualExecution && ( { @@ -72,7 +77,11 @@ export const ManualExecutionButton = ({ const signatures = packSignatures(signatureCollected.map(signatureToVRS)) const messageId = messageData.slice(0, 66) const bridge = foreign.bridgeContract - const data = bridge.methods.executeSignatures(messageData, signatures).encodeABI() + const executeMethod = + safeExecutionAvailable && !allowFailures + ? bridge.methods.safeExecuteSignaturesWithAutoGasLimit + : bridge.methods.executeSignatures + const data = executeMethod(messageData, signatures).encodeABI() setManualExecution(false) library.eth @@ -132,15 +141,35 @@ export const ManualExecutionButton = ({ messageData, signatureCollected, setExecutionData, - setPendingExecution + setPendingExecution, + safeExecutionAvailable, + allowFailures ] ) return ( -
- setManualExecution(true)}> - Execute - +
+
+ setManualExecution(true)}> + Execute + +
+ {safeExecutionAvailable && ( +
+ setAllowFailures(e.target.checked)} + /> + +
+ )}
) }