Fetch signatures from RPC endpoint immediatly after enough signatures are collected (#499)
This commit is contained in:
parent
04f66b243c
commit
6ce98ff3dd
@ -44,12 +44,13 @@ export interface ConfirmationsContainerParams {
|
||||
|
||||
export const ConfirmationsContainer = ({ message, receipt, fromHome, timestamp }: ConfirmationsContainerParams) => {
|
||||
const {
|
||||
home: { name: homeName, confirmations },
|
||||
home: { name: homeName },
|
||||
foreign: { name: foreignName }
|
||||
} = useStateProvider()
|
||||
const { requiredSignatures, validatorList } = useValidatorContract({ fromHome, receipt })
|
||||
const { blockConfirmations } = useBlockConfirmations({ fromHome, receipt })
|
||||
const {
|
||||
confirmations,
|
||||
status,
|
||||
executionData,
|
||||
signatureCollected,
|
||||
@ -115,7 +116,7 @@ export const ConfirmationsContainer = ({ message, receipt, fromHome, timestamp }
|
||||
messageData={message.data}
|
||||
executionData={executionData}
|
||||
isHome={!fromHome}
|
||||
requiredSignatures={requiredSignatures}
|
||||
signatureCollected={signatureCollected}
|
||||
setExecutionData={setExecutionData}
|
||||
executionEventsFetched={executionEventsFetched}
|
||||
setPendingExecution={setPendingExecution}
|
||||
|
@ -18,7 +18,7 @@ export interface ExecutionConfirmationParams {
|
||||
messageData: string
|
||||
executionData: ExecutionData
|
||||
setExecutionData: Function
|
||||
requiredSignatures: number
|
||||
signatureCollected: boolean | string[]
|
||||
isHome: boolean
|
||||
executionEventsFetched: boolean
|
||||
setPendingExecution: Function
|
||||
@ -28,7 +28,7 @@ export const ExecutionConfirmation = ({
|
||||
messageData,
|
||||
executionData,
|
||||
setExecutionData,
|
||||
requiredSignatures,
|
||||
signatureCollected,
|
||||
isHome,
|
||||
executionEventsFetched,
|
||||
setPendingExecution
|
||||
@ -105,7 +105,7 @@ export const ExecutionConfirmation = ({
|
||||
<ManualExecutionButton
|
||||
messageData={messageData}
|
||||
setExecutionData={setExecutionData}
|
||||
requiredSignatures={requiredSignatures}
|
||||
signatureCollected={signatureCollected as string[]}
|
||||
setPendingExecution={setPendingExecution}
|
||||
/>
|
||||
</td>
|
||||
|
@ -18,21 +18,19 @@ const StyledButton = styled.button`
|
||||
interface ManualExecutionButtonParams {
|
||||
messageData: string
|
||||
setExecutionData: Function
|
||||
requiredSignatures: number
|
||||
signatureCollected: string[]
|
||||
setPendingExecution: Function
|
||||
}
|
||||
|
||||
export const ManualExecutionButton = ({
|
||||
messageData,
|
||||
setExecutionData,
|
||||
requiredSignatures,
|
||||
signatureCollected,
|
||||
setPendingExecution
|
||||
}: ManualExecutionButtonParams) => {
|
||||
const { home, foreign, setError } = useStateProvider()
|
||||
const { foreign, setError } = useStateProvider()
|
||||
const { library, activate, account, active } = useWeb3React()
|
||||
const [manualExecution, setManualExecution] = useState(false)
|
||||
const disabled =
|
||||
home.confirmations.filter(({ signature }) => signature && signature.startsWith('0x')).length < requiredSignatures
|
||||
|
||||
useEffect(
|
||||
() => {
|
||||
@ -60,12 +58,9 @@ export const ManualExecutionButton = ({
|
||||
return
|
||||
}
|
||||
|
||||
if (!library || !foreign.bridgeContract || !home.confirmations) return
|
||||
if (!library || !foreign.bridgeContract) return
|
||||
|
||||
const collectedSignatures = home.confirmations
|
||||
.map(confirmation => confirmation.signature!)
|
||||
.filter(signature => signature && signature.startsWith('0x'))
|
||||
const signatures = packSignatures(collectedSignatures.map(signatureToVRS))
|
||||
const signatures = packSignatures(signatureCollected.map(signatureToVRS))
|
||||
const data = foreign.bridgeContract.methods.executeSignatures(messageData, signatures).encodeABI()
|
||||
setManualExecution(false)
|
||||
|
||||
@ -98,7 +93,7 @@ export const ManualExecutionButton = ({
|
||||
foreign.bridgeContract,
|
||||
setError,
|
||||
messageData,
|
||||
home.confirmations,
|
||||
signatureCollected,
|
||||
setExecutionData,
|
||||
setPendingExecution
|
||||
]
|
||||
@ -106,7 +101,7 @@ export const ManualExecutionButton = ({
|
||||
|
||||
return (
|
||||
<div className="is-center">
|
||||
<StyledButton disabled={disabled} className="button outline" onClick={() => setManualExecution(true)}>
|
||||
<StyledButton className="button outline" onClick={() => setManualExecution(true)}>
|
||||
Execute
|
||||
</StyledButton>
|
||||
</div>
|
||||
|
@ -63,7 +63,7 @@ export const useMessageConfirmations = ({
|
||||
blockConfirmations
|
||||
}: useMessageConfirmationsParams) => {
|
||||
const { home, foreign } = useStateProvider()
|
||||
const { confirmations, setConfirmations } = home
|
||||
const [confirmations, setConfirmations] = useState([])
|
||||
const [status, setStatus] = useState(CONFIRMATIONS_STATUS.UNDEFINED)
|
||||
const [waitingBlocks, setWaitingBlocks] = useState(false)
|
||||
const [waitingBlocksResolved, setWaitingBlocksResolved] = useState(false)
|
||||
@ -94,7 +94,7 @@ export const useMessageConfirmations = ({
|
||||
// Check if the validators are waiting for block confirmations to verify the message
|
||||
useEffect(
|
||||
() => {
|
||||
if (!receipt || !blockConfirmations) return
|
||||
if (!receipt || !blockConfirmations || waitingBlocksResolved) return
|
||||
|
||||
const subscriptions: Array<number> = []
|
||||
|
||||
@ -127,7 +127,16 @@ export const useMessageConfirmations = ({
|
||||
blockProvider.stop()
|
||||
}
|
||||
},
|
||||
[blockConfirmations, foreign.web3, fromHome, validatorList, home.web3, receipt, setConfirmations]
|
||||
[
|
||||
blockConfirmations,
|
||||
foreign.web3,
|
||||
fromHome,
|
||||
validatorList,
|
||||
home.web3,
|
||||
receipt,
|
||||
setConfirmations,
|
||||
waitingBlocksResolved
|
||||
]
|
||||
)
|
||||
|
||||
// The collected signature event is only fetched once the signatures are collected on tx from home to foreign, to calculate if
|
||||
@ -174,6 +183,7 @@ export const useMessageConfirmations = ({
|
||||
useEffect(
|
||||
() => {
|
||||
if (!fromHome || !home.web3 || !receipt || !collectedSignaturesEvent || !blockConfirmations) return
|
||||
if (waitingBlocksForExecutionResolved) return
|
||||
|
||||
const subscriptions: Array<number> = []
|
||||
|
||||
@ -202,7 +212,7 @@ export const useMessageConfirmations = ({
|
||||
homeBlockNumberProvider.stop()
|
||||
}
|
||||
},
|
||||
[collectedSignaturesEvent, fromHome, blockConfirmations, home.web3, receipt]
|
||||
[collectedSignaturesEvent, fromHome, blockConfirmations, home.web3, receipt, waitingBlocksForExecutionResolved]
|
||||
)
|
||||
|
||||
// Checks if validators verified the message
|
||||
@ -366,6 +376,7 @@ export const useMessageConfirmations = ({
|
||||
)
|
||||
|
||||
return {
|
||||
confirmations,
|
||||
status,
|
||||
signatureCollected,
|
||||
executionData,
|
||||
|
@ -12,7 +12,6 @@ import Web3 from 'web3'
|
||||
import { useBridgeContracts } from '../hooks/useBridgeContracts'
|
||||
import { Contract } from 'web3-eth-contract'
|
||||
import { foreignSnapshotProvider, homeSnapshotProvider } from '../services/SnapshotProvider'
|
||||
import { ConfirmationParam } from '../hooks/useMessageConfirmations'
|
||||
|
||||
export interface BaseNetworkParams {
|
||||
chainId: number
|
||||
@ -22,13 +21,8 @@ export interface BaseNetworkParams {
|
||||
bridgeContract: Maybe<Contract>
|
||||
}
|
||||
|
||||
export interface HomeNetworkParams extends BaseNetworkParams {
|
||||
confirmations: Array<ConfirmationParam>
|
||||
setConfirmations: Function
|
||||
}
|
||||
|
||||
export interface StateContext {
|
||||
home: HomeNetworkParams
|
||||
home: BaseNetworkParams
|
||||
foreign: BaseNetworkParams
|
||||
loading: boolean
|
||||
error: string
|
||||
@ -41,9 +35,7 @@ const initialState = {
|
||||
name: '',
|
||||
web3: null,
|
||||
bridgeAddress: HOME_BRIDGE_ADDRESS,
|
||||
bridgeContract: null,
|
||||
confirmations: [],
|
||||
setConfirmations: () => null
|
||||
bridgeContract: null
|
||||
},
|
||||
foreign: {
|
||||
chainId: 0,
|
||||
@ -66,7 +58,6 @@ export const StateProvider = ({ children }: { children: ReactNode }) => {
|
||||
homeWeb3: homeNetwork.web3,
|
||||
foreignWeb3: foreignNetwork.web3
|
||||
})
|
||||
const [confirmations, setConfirmations] = useState([])
|
||||
const [error, setError] = useState('')
|
||||
|
||||
const value = {
|
||||
@ -74,8 +65,6 @@ export const StateProvider = ({ children }: { children: ReactNode }) => {
|
||||
bridgeAddress: HOME_BRIDGE_ADDRESS,
|
||||
name: HOME_NETWORK_NAME,
|
||||
bridgeContract: homeBridge,
|
||||
confirmations,
|
||||
setConfirmations,
|
||||
...homeNetwork
|
||||
},
|
||||
foreign: {
|
||||
|
@ -24,7 +24,15 @@ const validator1 = '0x45b96809336A8b714BFbdAB3E4B5e0fe5d839908'
|
||||
const validator2 = '0xAe8bFfc8BBc6AAa9E21ED1E4e4957fe798BEA25f'
|
||||
const validator3 = '0x285A6eB779be4db94dA65e2F3518B1c5F0f71244'
|
||||
const validatorList = [validator1, validator2, validator3]
|
||||
const bridgeContract = {} as Contract
|
||||
const signature =
|
||||
'0x519d704bceed17423daa79c20531cc34fc27a4be6e53fc5069a8023019188ca4519d704bceed17423daa79c20531cc34fc27a4be6e53fc5069a8023019188ca4'
|
||||
const bridgeContract = {
|
||||
methods: {
|
||||
signature: () => ({
|
||||
call: () => signature
|
||||
})
|
||||
}
|
||||
} as Contract
|
||||
const requiredSignatures = 2
|
||||
const waitingBlocksResolved = true
|
||||
let subscriptions: Array<number> = []
|
||||
@ -103,7 +111,7 @@ describe('getConfirmationsForTx', () => {
|
||||
expect(getValidatorConfirmation).toBeCalledTimes(1)
|
||||
expect(getSuccessExecutionTransaction).toBeCalledTimes(1)
|
||||
expect(setSignatureCollected).toBeCalledTimes(1)
|
||||
expect(setSignatureCollected.mock.calls[0][0]).toEqual(true)
|
||||
expect(setSignatureCollected.mock.calls[0][0]).toEqual([signature, signature])
|
||||
|
||||
expect(getValidatorFailedTransaction).toBeCalledTimes(1)
|
||||
expect(setFailedConfirmations).toBeCalledTimes(1)
|
||||
@ -247,7 +255,7 @@ describe('getConfirmationsForTx', () => {
|
||||
expect(getValidatorConfirmation).toBeCalledTimes(1)
|
||||
expect(getSuccessExecutionTransaction).toBeCalledTimes(1)
|
||||
expect(setSignatureCollected).toBeCalledTimes(1)
|
||||
expect(setSignatureCollected.mock.calls[0][0]).toEqual(true)
|
||||
expect(setSignatureCollected.mock.calls[0][0]).toEqual([signature, signature])
|
||||
|
||||
expect(getValidatorFailedTransaction).toBeCalledTimes(1)
|
||||
expect(setFailedConfirmations).toBeCalledTimes(1)
|
||||
@ -335,7 +343,7 @@ describe('getConfirmationsForTx', () => {
|
||||
expect(getValidatorConfirmation).toBeCalledTimes(1)
|
||||
expect(getSuccessExecutionTransaction).toBeCalledTimes(1)
|
||||
expect(setSignatureCollected).toBeCalledTimes(1)
|
||||
expect(setSignatureCollected.mock.calls[0][0]).toEqual(true)
|
||||
expect(setSignatureCollected.mock.calls[0][0]).toEqual([signature, signature])
|
||||
|
||||
expect(getValidatorFailedTransaction).toBeCalledTimes(1)
|
||||
expect(setFailedConfirmations).toBeCalledTimes(1)
|
||||
@ -674,7 +682,7 @@ describe('getConfirmationsForTx', () => {
|
||||
expect(getSuccessExecutionTransaction).toBeCalledTimes(2)
|
||||
expect(setSignatureCollected).toBeCalledTimes(2)
|
||||
expect(setSignatureCollected.mock.calls[0][0]).toEqual(false)
|
||||
expect(setSignatureCollected.mock.calls[1][0]).toEqual(true)
|
||||
expect(setSignatureCollected.mock.calls[1][0]).toEqual([signature, signature])
|
||||
|
||||
expect(getValidatorFailedTransaction).toBeCalledTimes(2)
|
||||
expect(setFailedConfirmations).toBeCalledTimes(2)
|
||||
|
@ -15,13 +15,19 @@ export const checkWaitingBlocksForExecution = async (
|
||||
const currentBlock = blockProvider.get()
|
||||
|
||||
if (currentBlock && currentBlock >= targetBlock) {
|
||||
setExecutionData({
|
||||
const undefinedExecutionState = {
|
||||
status: VALIDATOR_CONFIRMATION_STATUS.UNDEFINED,
|
||||
validator: collectedSignaturesEvent.returnValues.authorityResponsibleForRelay,
|
||||
txHash: '',
|
||||
timestamp: 0,
|
||||
executionResult: false
|
||||
})
|
||||
}
|
||||
setExecutionData(
|
||||
(data: any) =>
|
||||
data.status === VALIDATOR_CONFIRMATION_STATUS.UNDEFINED || data.status === VALIDATOR_CONFIRMATION_STATUS.WAITING
|
||||
? undefinedExecutionState
|
||||
: data
|
||||
)
|
||||
setWaitingBlocksForExecutionResolved(true)
|
||||
setWaitingBlocksForExecution(false)
|
||||
blockProvider.stop()
|
||||
@ -31,13 +37,20 @@ export const checkWaitingBlocksForExecution = async (
|
||||
nextInterval = 500
|
||||
} else {
|
||||
setWaitingBlocksForExecution(true)
|
||||
setExecutionData({
|
||||
const waitingExecutionState = {
|
||||
status: VALIDATOR_CONFIRMATION_STATUS.WAITING,
|
||||
validator: collectedSignaturesEvent.returnValues.authorityResponsibleForRelay,
|
||||
txHash: '',
|
||||
timestamp: 0,
|
||||
executionResult: false
|
||||
})
|
||||
}
|
||||
setExecutionData(
|
||||
(data: any) =>
|
||||
data.status === VALIDATOR_CONFIRMATION_STATUS.UNDEFINED ||
|
||||
data.status === VALIDATOR_CONFIRMATION_STATUS.WAITING
|
||||
? waitingExecutionState
|
||||
: data
|
||||
)
|
||||
}
|
||||
const timeoutId = setTimeout(
|
||||
() =>
|
||||
|
@ -113,7 +113,7 @@ export const getConfirmationsForTx = async (
|
||||
shouldRetry = true
|
||||
}
|
||||
|
||||
let signatureCollectedResult = false
|
||||
let signatureCollectedResult: boolean | string[] = false
|
||||
if (successConfirmations.length === requiredSignatures) {
|
||||
// If signatures collected, it should set other signatures not found as not required
|
||||
const notRequiredConfirmations = missingConfirmations.map(c => ({
|
||||
@ -126,6 +126,12 @@ export const getConfirmationsForTx = async (
|
||||
validatorConfirmations[index] = validatorData
|
||||
})
|
||||
signatureCollectedResult = true
|
||||
|
||||
if (fromHome) {
|
||||
signatureCollectedResult = await Promise.all(
|
||||
Array.from(Array(requiredSignatures).keys()).map(i => bridgeContract.methods.signature(hashMsg, i).call())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// get transactions from success signatures
|
||||
|
@ -71,24 +71,18 @@ export const getSuccessExecutionTransaction = (
|
||||
|
||||
let txHashTimestamp = 0
|
||||
let txHash = ''
|
||||
let signature = ''
|
||||
const status = VALIDATOR_CONFIRMATION_STATUS.SUCCESS
|
||||
|
||||
if (transactions.length > 0) {
|
||||
const tx = transactions[0]
|
||||
txHashTimestamp = parseInt(tx.timeStamp)
|
||||
txHash = tx.hash
|
||||
if (fromHome) {
|
||||
const decoded = web3.eth.abi.decodeParameters(['bytes', 'bytes'], `0x${tx.input.substr(10)}`)
|
||||
signature = decoded[0]
|
||||
}
|
||||
|
||||
// cache the result
|
||||
validatorsCache.setData(validatorCacheKey, {
|
||||
validator,
|
||||
status,
|
||||
txHash,
|
||||
signature,
|
||||
timestamp: txHashTimestamp
|
||||
})
|
||||
}
|
||||
@ -97,7 +91,6 @@ export const getSuccessExecutionTransaction = (
|
||||
validator,
|
||||
status,
|
||||
txHash,
|
||||
signature,
|
||||
timestamp: txHashTimestamp
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user