Get required block confirmation at the moment of the transaction (#379)
This commit is contained in:
parent
691e4294ae
commit
ab814f831c
@ -11,6 +11,7 @@ import { getConfirmationsStatusDescription } from '../utils/networks'
|
|||||||
import { useStateProvider } from '../state/StateProvider'
|
import { useStateProvider } from '../state/StateProvider'
|
||||||
import { ExecutionConfirmation } from './ExecutionConfirmation'
|
import { ExecutionConfirmation } from './ExecutionConfirmation'
|
||||||
import { useValidatorContract } from '../hooks/useValidatorContract'
|
import { useValidatorContract } from '../hooks/useValidatorContract'
|
||||||
|
import { useBlockConfirmations } from '../hooks/useBlockConfirmations'
|
||||||
|
|
||||||
const StatusLabel = styled.label`
|
const StatusLabel = styled.label`
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -45,13 +46,15 @@ export const ConfirmationsContainer = ({ message, receipt, fromHome, timestamp }
|
|||||||
foreign: { name: foreignName }
|
foreign: { name: foreignName }
|
||||||
} = useStateProvider()
|
} = useStateProvider()
|
||||||
const { requiredSignatures, validatorList } = useValidatorContract({ fromHome, receipt })
|
const { requiredSignatures, validatorList } = useValidatorContract({ fromHome, receipt })
|
||||||
|
const { blockConfirmations } = useBlockConfirmations({ fromHome, receipt })
|
||||||
const { confirmations, status, executionData, signatureCollected } = useMessageConfirmations({
|
const { confirmations, status, executionData, signatureCollected } = useMessageConfirmations({
|
||||||
message,
|
message,
|
||||||
receipt,
|
receipt,
|
||||||
fromHome,
|
fromHome,
|
||||||
timestamp,
|
timestamp,
|
||||||
requiredSignatures,
|
requiredSignatures,
|
||||||
validatorList
|
validatorList,
|
||||||
|
blockConfirmations
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
38
alm/src/hooks/useBlockConfirmations.ts
Normal file
38
alm/src/hooks/useBlockConfirmations.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { TransactionReceipt } from 'web3-eth'
|
||||||
|
import { useStateProvider } from '../state/StateProvider'
|
||||||
|
import { Contract } from 'web3-eth-contract'
|
||||||
|
import { getRequiredBlockConfirmations } from '../utils/contract'
|
||||||
|
|
||||||
|
export interface UseBlockConfirmationsParams {
|
||||||
|
fromHome: boolean
|
||||||
|
receipt: Maybe<TransactionReceipt>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useBlockConfirmations = ({ receipt, fromHome }: UseBlockConfirmationsParams) => {
|
||||||
|
const [blockConfirmations, setBlockConfirmations] = useState(0)
|
||||||
|
|
||||||
|
const { home, foreign } = useStateProvider()
|
||||||
|
|
||||||
|
const callRequireBlockConfirmations = async (
|
||||||
|
contract: Contract,
|
||||||
|
receipt: TransactionReceipt,
|
||||||
|
setResult: Function
|
||||||
|
) => {
|
||||||
|
const result = await getRequiredBlockConfirmations(contract, receipt.blockNumber)
|
||||||
|
setResult(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(
|
||||||
|
() => {
|
||||||
|
const bridgeContract = fromHome ? home.bridgeContract : foreign.bridgeContract
|
||||||
|
if (!bridgeContract || !receipt) return
|
||||||
|
callRequireBlockConfirmations(bridgeContract, receipt, setBlockConfirmations)
|
||||||
|
},
|
||||||
|
[home.bridgeContract, foreign.bridgeContract, receipt, fromHome]
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
blockConfirmations
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,6 @@ import { HOME_AMB_ABI, FOREIGN_AMB_ABI } from '../abis'
|
|||||||
import { FOREIGN_BRIDGE_ADDRESS, HOME_BRIDGE_ADDRESS } from '../config/constants'
|
import { FOREIGN_BRIDGE_ADDRESS, HOME_BRIDGE_ADDRESS } from '../config/constants'
|
||||||
import { Contract } from 'web3-eth-contract'
|
import { Contract } from 'web3-eth-contract'
|
||||||
import Web3 from 'web3'
|
import Web3 from 'web3'
|
||||||
import { getRequiredBlockConfirmations } from '../utils/contract'
|
|
||||||
|
|
||||||
export interface useBridgeContractsParams {
|
export interface useBridgeContractsParams {
|
||||||
homeWeb3: Web3
|
homeWeb3: Web3
|
||||||
@ -13,20 +12,11 @@ export interface useBridgeContractsParams {
|
|||||||
export const useBridgeContracts = ({ homeWeb3, foreignWeb3 }: useBridgeContractsParams) => {
|
export const useBridgeContracts = ({ homeWeb3, foreignWeb3 }: useBridgeContractsParams) => {
|
||||||
const [homeBridge, setHomeBridge] = useState<Maybe<Contract>>(null)
|
const [homeBridge, setHomeBridge] = useState<Maybe<Contract>>(null)
|
||||||
const [foreignBridge, setForeignBridge] = useState<Maybe<Contract>>(null)
|
const [foreignBridge, setForeignBridge] = useState<Maybe<Contract>>(null)
|
||||||
const [homeBlockConfirmations, setHomeBlockConfirmations] = useState(0)
|
|
||||||
const [foreignBlockConfirmations, setForeignBlockConfirmations] = useState(0)
|
|
||||||
|
|
||||||
const callRequireBlockConfirmations = async (contract: Maybe<Contract>, setResult: Function) => {
|
|
||||||
if (!contract) return
|
|
||||||
const result = await getRequiredBlockConfirmations(contract)
|
|
||||||
setResult(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
() => {
|
() => {
|
||||||
if (!homeWeb3) return
|
if (!homeWeb3) return
|
||||||
const homeContract = new homeWeb3.eth.Contract(HOME_AMB_ABI, HOME_BRIDGE_ADDRESS)
|
const homeContract = new homeWeb3.eth.Contract(HOME_AMB_ABI, HOME_BRIDGE_ADDRESS)
|
||||||
callRequireBlockConfirmations(homeContract, setHomeBlockConfirmations)
|
|
||||||
setHomeBridge(homeContract)
|
setHomeBridge(homeContract)
|
||||||
},
|
},
|
||||||
[homeWeb3]
|
[homeWeb3]
|
||||||
@ -36,7 +26,6 @@ export const useBridgeContracts = ({ homeWeb3, foreignWeb3 }: useBridgeContracts
|
|||||||
() => {
|
() => {
|
||||||
if (!foreignWeb3) return
|
if (!foreignWeb3) return
|
||||||
const foreignContract = new foreignWeb3.eth.Contract(FOREIGN_AMB_ABI, FOREIGN_BRIDGE_ADDRESS)
|
const foreignContract = new foreignWeb3.eth.Contract(FOREIGN_AMB_ABI, FOREIGN_BRIDGE_ADDRESS)
|
||||||
callRequireBlockConfirmations(foreignContract, setForeignBlockConfirmations)
|
|
||||||
setForeignBridge(foreignContract)
|
setForeignBridge(foreignContract)
|
||||||
},
|
},
|
||||||
[foreignWeb3]
|
[foreignWeb3]
|
||||||
@ -44,8 +33,6 @@ export const useBridgeContracts = ({ homeWeb3, foreignWeb3 }: useBridgeContracts
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
homeBridge,
|
homeBridge,
|
||||||
foreignBridge,
|
foreignBridge
|
||||||
homeBlockConfirmations,
|
|
||||||
foreignBlockConfirmations
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ export interface useMessageConfirmationsParams {
|
|||||||
timestamp: number
|
timestamp: number
|
||||||
requiredSignatures: number
|
requiredSignatures: number
|
||||||
validatorList: string[]
|
validatorList: string[]
|
||||||
|
blockConfirmations: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BasicConfirmationParam {
|
export interface BasicConfirmationParam {
|
||||||
@ -58,7 +59,8 @@ export const useMessageConfirmations = ({
|
|||||||
fromHome,
|
fromHome,
|
||||||
timestamp,
|
timestamp,
|
||||||
requiredSignatures,
|
requiredSignatures,
|
||||||
validatorList
|
validatorList,
|
||||||
|
blockConfirmations
|
||||||
}: useMessageConfirmationsParams) => {
|
}: useMessageConfirmationsParams) => {
|
||||||
const { home, foreign } = useStateProvider()
|
const { home, foreign } = useStateProvider()
|
||||||
const [confirmations, setConfirmations] = useState<Array<ConfirmationParam>>([])
|
const [confirmations, setConfirmations] = useState<Array<ConfirmationParam>>([])
|
||||||
@ -84,7 +86,7 @@ export const useMessageConfirmations = ({
|
|||||||
// Check if the validators are waiting for block confirmations to verify the message
|
// Check if the validators are waiting for block confirmations to verify the message
|
||||||
useEffect(
|
useEffect(
|
||||||
() => {
|
() => {
|
||||||
if (!receipt) return
|
if (!receipt || !blockConfirmations) return
|
||||||
|
|
||||||
const subscriptions: Array<number> = []
|
const subscriptions: Array<number> = []
|
||||||
|
|
||||||
@ -99,8 +101,7 @@ export const useMessageConfirmations = ({
|
|||||||
const web3 = fromHome ? home.web3 : foreign.web3
|
const web3 = fromHome ? home.web3 : foreign.web3
|
||||||
blockProvider.start(web3)
|
blockProvider.start(web3)
|
||||||
|
|
||||||
const requiredBlockConfirmations = fromHome ? home.blockConfirmations : foreign.blockConfirmations
|
const targetBlock = receipt.blockNumber + blockConfirmations
|
||||||
const targetBlock = receipt.blockNumber + requiredBlockConfirmations
|
|
||||||
|
|
||||||
checkSignaturesWaitingForBLocks(
|
checkSignaturesWaitingForBLocks(
|
||||||
targetBlock,
|
targetBlock,
|
||||||
@ -118,7 +119,7 @@ export const useMessageConfirmations = ({
|
|||||||
blockProvider.stop()
|
blockProvider.stop()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[foreign.blockConfirmations, foreign.web3, fromHome, home.blockConfirmations, validatorList, home.web3, receipt]
|
[blockConfirmations, foreign.web3, fromHome, validatorList, home.web3, receipt]
|
||||||
)
|
)
|
||||||
|
|
||||||
// The collected signature event is only fetched once the signatures are collected on tx from home to foreign, to calculate if
|
// The collected signature event is only fetched once the signatures are collected on tx from home to foreign, to calculate if
|
||||||
@ -164,7 +165,7 @@ export const useMessageConfirmations = ({
|
|||||||
// This is executed if the message is in Home to Foreign direction only
|
// This is executed if the message is in Home to Foreign direction only
|
||||||
useEffect(
|
useEffect(
|
||||||
() => {
|
() => {
|
||||||
if (!fromHome || !home.web3 || !receipt || !collectedSignaturesEvent) return
|
if (!fromHome || !home.web3 || !receipt || !collectedSignaturesEvent || !blockConfirmations) return
|
||||||
|
|
||||||
const subscriptions: Array<number> = []
|
const subscriptions: Array<number> = []
|
||||||
|
|
||||||
@ -175,7 +176,7 @@ export const useMessageConfirmations = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
homeBlockNumberProvider.start(home.web3)
|
homeBlockNumberProvider.start(home.web3)
|
||||||
const targetBlock = collectedSignaturesEvent.blockNumber + home.blockConfirmations
|
const targetBlock = collectedSignaturesEvent.blockNumber + blockConfirmations
|
||||||
|
|
||||||
checkWaitingBlocksForExecution(
|
checkWaitingBlocksForExecution(
|
||||||
homeBlockNumberProvider,
|
homeBlockNumberProvider,
|
||||||
@ -193,7 +194,7 @@ export const useMessageConfirmations = ({
|
|||||||
homeBlockNumberProvider.stop()
|
homeBlockNumberProvider.stop()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[collectedSignaturesEvent, fromHome, home.blockConfirmations, home.web3, receipt]
|
[collectedSignaturesEvent, fromHome, blockConfirmations, home.web3, receipt]
|
||||||
)
|
)
|
||||||
|
|
||||||
// Checks if validators verified the message
|
// Checks if validators verified the message
|
||||||
|
@ -18,7 +18,6 @@ export interface BaseNetworkParams {
|
|||||||
web3: Maybe<Web3>
|
web3: Maybe<Web3>
|
||||||
bridgeAddress: string
|
bridgeAddress: string
|
||||||
bridgeContract: Maybe<Contract>
|
bridgeContract: Maybe<Contract>
|
||||||
blockConfirmations: number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StateContext {
|
export interface StateContext {
|
||||||
@ -33,16 +32,14 @@ const initialState = {
|
|||||||
name: '',
|
name: '',
|
||||||
web3: null,
|
web3: null,
|
||||||
bridgeAddress: HOME_BRIDGE_ADDRESS,
|
bridgeAddress: HOME_BRIDGE_ADDRESS,
|
||||||
bridgeContract: null,
|
bridgeContract: null
|
||||||
blockConfirmations: 0
|
|
||||||
},
|
},
|
||||||
foreign: {
|
foreign: {
|
||||||
chainId: 0,
|
chainId: 0,
|
||||||
name: '',
|
name: '',
|
||||||
web3: null,
|
web3: null,
|
||||||
bridgeAddress: FOREIGN_BRIDGE_ADDRESS,
|
bridgeAddress: FOREIGN_BRIDGE_ADDRESS,
|
||||||
bridgeContract: null,
|
bridgeContract: null
|
||||||
blockConfirmations: 0
|
|
||||||
},
|
},
|
||||||
loading: true
|
loading: true
|
||||||
}
|
}
|
||||||
@ -52,7 +49,7 @@ const StateContext = createContext<StateContext>(initialState)
|
|||||||
export const StateProvider = ({ children }: { children: ReactNode }) => {
|
export const StateProvider = ({ children }: { children: ReactNode }) => {
|
||||||
const homeNetwork = useNetwork(HOME_RPC_URL)
|
const homeNetwork = useNetwork(HOME_RPC_URL)
|
||||||
const foreignNetwork = useNetwork(FOREIGN_RPC_URL)
|
const foreignNetwork = useNetwork(FOREIGN_RPC_URL)
|
||||||
const { homeBridge, foreignBridge, homeBlockConfirmations, foreignBlockConfirmations } = useBridgeContracts({
|
const { homeBridge, foreignBridge } = useBridgeContracts({
|
||||||
homeWeb3: homeNetwork.web3,
|
homeWeb3: homeNetwork.web3,
|
||||||
foreignWeb3: foreignNetwork.web3
|
foreignWeb3: foreignNetwork.web3
|
||||||
})
|
})
|
||||||
@ -62,14 +59,12 @@ export const StateProvider = ({ children }: { children: ReactNode }) => {
|
|||||||
bridgeAddress: HOME_BRIDGE_ADDRESS,
|
bridgeAddress: HOME_BRIDGE_ADDRESS,
|
||||||
name: HOME_NETWORK_NAME,
|
name: HOME_NETWORK_NAME,
|
||||||
bridgeContract: homeBridge,
|
bridgeContract: homeBridge,
|
||||||
blockConfirmations: homeBlockConfirmations,
|
|
||||||
...homeNetwork
|
...homeNetwork
|
||||||
},
|
},
|
||||||
foreign: {
|
foreign: {
|
||||||
bridgeAddress: FOREIGN_BRIDGE_ADDRESS,
|
bridgeAddress: FOREIGN_BRIDGE_ADDRESS,
|
||||||
name: FOREIGN_NETWORK_NAME,
|
name: FOREIGN_NETWORK_NAME,
|
||||||
bridgeContract: foreignBridge,
|
bridgeContract: foreignBridge,
|
||||||
blockConfirmations: foreignBlockConfirmations,
|
|
||||||
...foreignNetwork
|
...foreignNetwork
|
||||||
},
|
},
|
||||||
loading: homeNetwork.loading || foreignNetwork.loading
|
loading: homeNetwork.loading || foreignNetwork.loading
|
||||||
|
@ -1,7 +1,21 @@
|
|||||||
import { Contract } from 'web3-eth-contract'
|
import { Contract } from 'web3-eth-contract'
|
||||||
|
|
||||||
export const getRequiredBlockConfirmations = async (contract: Contract) => {
|
export const getRequiredBlockConfirmations = async (contract: Contract, blockNumber: number) => {
|
||||||
const blockConfirmations = await contract.methods.requiredBlockConfirmations().call()
|
const events = await contract.getPastEvents('RequiredBlockConfirmationChanged', {
|
||||||
|
fromBlock: 0,
|
||||||
|
toBlock: blockNumber
|
||||||
|
})
|
||||||
|
|
||||||
|
let blockConfirmations
|
||||||
|
if (events.length > 0) {
|
||||||
|
// Use the value from last event before the transaction
|
||||||
|
const event = events[events.length - 1]
|
||||||
|
blockConfirmations = event.returnValues.requiredBlockConfirmations
|
||||||
|
} else {
|
||||||
|
// This is a special case where RequiredBlockConfirmationChanged was not emitted during initialization in early versions of AMB
|
||||||
|
// of Sokol - Kovan. In this case the current value is used.
|
||||||
|
blockConfirmations = await contract.methods.requiredBlockConfirmations().call()
|
||||||
|
}
|
||||||
return parseInt(blockConfirmations)
|
return parseInt(blockConfirmations)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user