Skip to content

Commit c92f80c

Browse files
authored
Merge the develop branch to the master branch, preparation to v3.0.0-rc1
This merge contains the following set of changes: * [Monitor, Improvement] Add statistics about used AMB information requests (#577) * [ALM, Improvement] Add safe-execute button in ALM (#580), closes #573, closes #551 * [Oracle, Improvement] Improve confirm-relay feature (#582), closes #569 * [Monitor, Fix] Prune print of long error messages about missing file (#579), closes #578 * [Oracle, Fix] Use safe approach for eth_getLogs requests (#581) * [Oracle, Fix] Fix logging in gas price service (#583), closes #552 * [Oracle, Fix] Fix oracle error patterns and oracle e2e tests (#585) * [Common, Other] Fix dependencies versions and update example.yml (#566) * [Common, Other] Upload services logs in e2e and ultimate tests (#568) * [Oracle, Other] added example of emergency shutdown controller contract (#572) * [Oracle, Other] Refactor oracle configuration (#584)
2 parents 3b95977 + 5e95b5d commit c92f80c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+971
-2479
lines changed

.github/workflows/main.yml

+16-1
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ jobs:
149149
run: docker login ${DOCKER_REGISTRY} -u ${{ github.actor }} -p ${{ github.token }}
150150
- name: yarn run ${{ matrix.task }}
151151
run: ${{ !matrix.use-cache || steps.cache-repo.outputs.cache-hit }} && yarn run ${{ matrix.task }}
152+
- name: Upload logs
153+
if: always()
154+
uses: actions/upload-artifact@v2
155+
with:
156+
name: logs-${{ matrix.task }}
157+
path: e2e-commons/logs
152158
deployment:
153159
runs-on: ubuntu-latest
154160
needs:
@@ -199,7 +205,7 @@ jobs:
199205
- name: Login to docker registry
200206
run: docker login ${DOCKER_REGISTRY} -u ${{ github.actor }} -p ${{ github.token }}
201207
- name: Deploy contracts
202-
run: ${{ steps.cache-repo.outputs.cache-hit }} && e2e-commons/up.sh deploy blocks
208+
run: ${{ steps.cache-repo.outputs.cache-hit }} && e2e-commons/up.sh deploy generate-amb-tx blocks
203209
- name: Pull e2e oracle image
204210
run: |
205211
docker-compose -f ./e2e-commons/docker-compose.yml pull oracle-amb
@@ -210,3 +216,12 @@ jobs:
210216
run: sudo chown -R $USER:docker /var/run/docker.sock
211217
- name: Run oracle e2e tests
212218
run: docker-compose -f ./e2e-commons/docker-compose.yml run -e ULTIMATE=true e2e yarn workspace oracle-e2e run ${{ matrix.task }}
219+
- name: Save logs
220+
if: always()
221+
run: e2e-commons/down.sh
222+
- name: Upload logs
223+
if: always()
224+
uses: actions/upload-artifact@v2
225+
with:
226+
name: logs-ultimate-${{ matrix.task }}
227+
path: e2e-commons/logs

alm-e2e/run-tests.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env bash
22
cd $(dirname $0)
33

4-
../e2e-commons/up.sh deploy blocks alm alm-e2e
4+
../e2e-commons/up.sh deploy generate-amb-tx blocks alm alm-e2e
55

66
# run oracle amb e2e tests to generate transactions for alm
77
docker-compose -f ../e2e-commons/docker-compose.yml run e2e yarn workspace oracle-e2e run alm

alm-e2e/src/test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ jest.setTimeout(60000)
66
const statusText = 'Success'
77
const statusSelector = 'label[data-id="status"]'
88

9-
const homeToForeignTxURL = 'http://localhost:3004/77/0xbc83d43bdc675a615a2b820e43e52d25857aa5fdd77acf2dd92cd247af2c693c'
10-
const foreignToHomeTxURL = 'http://localhost:3004/42/0x09dfb947dbd17e27bcc117773b6e133829f7cef9646199a93ef019c4f7c0fec6'
9+
const homeToForeignTxURL = 'http://localhost:3004/77/0x295efbe6ae98937ef35d939376c9bd752b4dc6f6899a9d5ddd6a57cea3d76c89'
10+
const foreignToHomeTxURL = 'http://localhost:3004/42/0x7262f7dbe6c30599edded2137fbbe93c271b37f5c54dd27f713f0cf510e3b4dd'
1111

1212
describe('ALM', () => {
1313
let browser

alm/src/abis/ForeignAMB.ts

+18
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,24 @@ const abi: AbiItem[] = [
123123
stateMutability: 'nonpayable',
124124
type: 'function'
125125
},
126+
{
127+
constant: false,
128+
inputs: [
129+
{
130+
name: '_data',
131+
type: 'bytes'
132+
},
133+
{
134+
name: '_signatures',
135+
type: 'bytes'
136+
}
137+
],
138+
name: 'safeExecuteSignaturesWithAutoGasLimit',
139+
outputs: [],
140+
payable: false,
141+
stateMutability: 'nonpayable',
142+
type: 'function'
143+
},
126144
{
127145
constant: true,
128146
inputs: [

alm/src/components/ExecutionConfirmation.tsx

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react'
1+
import React, { useEffect, useState } from 'react'
22
import { formatTimestamp, formatTxHash, getExplorerTxUrl } from '../utils/networks'
33
import { useWindowWidth } from '@react-hook/window-size'
44
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'
99
import { ExplorerTxLink } from './commons/ExplorerTxLink'
1010
import { Thead, AgeTd, StatusTd } from './commons/Table'
1111
import { ManualExecutionButton } from './ManualExecutionButton'
12+
import { useStateProvider } from '../state/StateProvider'
1213

1314
const StyledExecutionConfirmation = styled.div`
1415
margin-top: 30px;
@@ -33,6 +34,8 @@ export const ExecutionConfirmation = ({
3334
executionEventsFetched,
3435
setPendingExecution
3536
}: ExecutionConfirmationParams) => {
37+
const { foreign } = useStateProvider()
38+
const [safeExecutionAvailable, setSafeExecutionAvailable] = useState(false)
3639
const availableManualExecution =
3740
!isHome &&
3841
(executionData.status === VALIDATOR_CONFIRMATION_STATUS.WAITING ||
@@ -48,6 +51,22 @@ export const ExecutionConfirmation = ({
4851
const formattedValidator =
4952
windowWidth < 850 && executionData.validator ? formatTxHash(executionData.validator) : executionData.validator
5053

54+
useEffect(
55+
() => {
56+
if (!availableManualExecution || !foreign.bridgeContract) return
57+
58+
const p = foreign.bridgeContract.methods.getBridgeInterfacesVersion().call()
59+
p.then(({ major, minor }: any) => {
60+
major = parseInt(major, 10)
61+
minor = parseInt(minor, 10)
62+
if (major < 5 || (major === 5 && minor < 7)) return
63+
64+
setSafeExecutionAvailable(true)
65+
})
66+
},
67+
[availableManualExecution, foreign.bridgeContract]
68+
)
69+
5170
const getExecutionStatusElement = (validatorStatus = '') => {
5271
switch (validatorStatus) {
5372
case VALIDATOR_CONFIRMATION_STATUS.SUCCESS:
@@ -105,6 +124,7 @@ export const ExecutionConfirmation = ({
105124
{availableManualExecution && (
106125
<td>
107126
<ManualExecutionButton
127+
safeExecutionAvailable={safeExecutionAvailable}
108128
messageData={messageData}
109129
setExecutionData={setExecutionData}
110130
signatureCollected={signatureCollected as string[]}

alm/src/components/ManualExecutionButton.tsx

+36-7
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,27 @@ import { signatureToVRS, packSignatures } from '../utils/signatures'
1515
import { getSuccessExecutionData } from '../utils/getFinalizationEvent'
1616
import { TransactionReceipt } from 'web3-eth'
1717

18-
const StyledButton = styled.button`
18+
const ActionButton = styled.button`
1919
color: var(--button-color);
2020
border-color: var(--font-color);
2121
margin-top: 10px;
22+
min-width: 120px;
23+
padding: 1rem;
2224
&:focus {
2325
outline: var(--button-color);
2426
}
2527
`
2628

2729
interface ManualExecutionButtonParams {
30+
safeExecutionAvailable: boolean
2831
messageData: string
2932
setExecutionData: Function
3033
signatureCollected: string[]
3134
setPendingExecution: Function
3235
}
3336

3437
export const ManualExecutionButton = ({
38+
safeExecutionAvailable,
3539
messageData,
3640
setExecutionData,
3741
signatureCollected,
@@ -40,6 +44,7 @@ export const ManualExecutionButton = ({
4044
const { foreign, setError } = useStateProvider()
4145
const { library, activate, account, active } = useWeb3React()
4246
const [manualExecution, setManualExecution] = useState(false)
47+
const [allowFailures, setAllowFailures] = useState(false)
4348

4449
useEffect(
4550
() => {
@@ -72,7 +77,11 @@ export const ManualExecutionButton = ({
7277
const signatures = packSignatures(signatureCollected.map(signatureToVRS))
7378
const messageId = messageData.slice(0, 66)
7479
const bridge = foreign.bridgeContract
75-
const data = bridge.methods.executeSignatures(messageData, signatures).encodeABI()
80+
const executeMethod =
81+
safeExecutionAvailable && !allowFailures
82+
? bridge.methods.safeExecuteSignaturesWithAutoGasLimit
83+
: bridge.methods.executeSignatures
84+
const data = executeMethod(messageData, signatures).encodeABI()
7685
setManualExecution(false)
7786

7887
library.eth
@@ -132,15 +141,35 @@ export const ManualExecutionButton = ({
132141
messageData,
133142
signatureCollected,
134143
setExecutionData,
135-
setPendingExecution
144+
setPendingExecution,
145+
safeExecutionAvailable,
146+
allowFailures
136147
]
137148
)
138149

139150
return (
140-
<div className="is-center">
141-
<StyledButton className="button outline" onClick={() => setManualExecution(true)}>
142-
Execute
143-
</StyledButton>
151+
<div>
152+
<div className="is-center">
153+
<ActionButton className="button outline" onClick={() => setManualExecution(true)}>
154+
Execute
155+
</ActionButton>
156+
</div>
157+
{safeExecutionAvailable && (
158+
<div
159+
title="Allow executed message to fail and record its failure on-chain without reverting the whole transaction.
160+
Use fixed gas limit for execution."
161+
className="is-center"
162+
style={{ paddingTop: 10 }}
163+
>
164+
<input
165+
type="checkbox"
166+
id="allow-failures"
167+
checked={allowFailures}
168+
onChange={e => setAllowFailures(e.target.checked)}
169+
/>
170+
<label htmlFor="allow-failures">Unsafe mode</label>
171+
</div>
172+
)}
144173
</div>
145174
)
146175
}

commons/message.js

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
const { soliditySha3 } = require('web3-utils')
2+
13
function strip0x(input) {
24
return input.replace(/^0x/, '')
35
}
@@ -39,8 +41,35 @@ const normalizeAMBMessageEvent = e => {
3941
return parseAMBMessage(msgData)
4042
}
4143

44+
const ambInformationSignatures = [
45+
'eth_call(address,bytes)',
46+
'eth_call(address,bytes,uint256)',
47+
'eth_call(address,address,uint256,bytes)',
48+
'eth_blockNumber()',
49+
'eth_getBlockByNumber()',
50+
'eth_getBlockByNumber(uint256)',
51+
'eth_getBlockByHash(bytes32)',
52+
'eth_getBalance(address)',
53+
'eth_getBalance(address,uint256)',
54+
'eth_getTransactionCount(address)',
55+
'eth_getTransactionCount(address,uint256)',
56+
'eth_getTransactionByHash(bytes32)',
57+
'eth_getTransactionReceipt(bytes32)',
58+
'eth_getStorageAt(address,bytes32)',
59+
'eth_getStorageAt(address,bytes32,uint256)'
60+
]
61+
const ambInformationSelectors = Object.fromEntries(ambInformationSignatures.map(sig => [soliditySha3(sig), sig]))
62+
const normalizeAMBInfoRequest = e => ({
63+
messageId: e.returnValues.messageId,
64+
sender: e.returnValues.sender,
65+
requestSelector: ambInformationSelectors[e.returnValues.requestSelector] || 'unknown',
66+
data: e.returnValues.data
67+
})
68+
4269
module.exports = {
4370
strip0x,
4471
parseAMBMessage,
45-
normalizeAMBMessageEvent
72+
normalizeAMBMessageEvent,
73+
ambInformationSignatures,
74+
normalizeAMBInfoRequest
4675
}

commons/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
},
1010
"dependencies": {
1111
"gas-price-oracle": "^0.1.5",
12-
"web3-utils": "^1.3.0"
12+
"web3-utils": "^1.3.0",
13+
"node-fetch": "^2.1.2"
1314
},
1415
"devDependencies": {
1516
"bn-chai": "^1.0.1",

commons/utils.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const { toWei, toBN, BN } = require('web3-utils')
22
const { GasPriceOracle } = require('gas-price-oracle')
3+
const fetch = require('node-fetch')
34
const { BRIDGE_MODES } = require('./constants')
45
const { REWARDABLE_VALIDATORS_ABI } = require('./abis')
56

@@ -178,17 +179,16 @@ const normalizeGasPrice = (oracleGasPrice, factor, limits = null) => {
178179
return toBN(toWei(gasPrice.toFixed(2).toString(), 'gwei'))
179180
}
180181

181-
// fetchFn has to be supplied (instead of just url to oracle),
182-
// because this utility function is shared between Browser and Node,
183-
// we use built-in 'fetch' on browser side, and `node-fetch` package in Node.
184-
const gasPriceFromSupplier = async (fetchFn, options = {}) => {
182+
const gasPriceFromSupplier = async (url, options = {}) => {
185183
try {
186184
let json
187-
if (fetchFn) {
188-
const response = await fetchFn()
185+
if (url === 'gas-price-oracle') {
186+
json = await gasPriceOracle.fetchGasPricesOffChain()
187+
} else if (url) {
188+
const response = await fetch(url, { timeout: 2000 })
189189
json = await response.json()
190190
} else {
191-
json = await gasPriceOracle.fetchGasPricesOffChain()
191+
return null
192192
}
193193
const oracleGasPrice = json[options.speedType]
194194

deployment-e2e/molecule/multiple/molecule.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ provisioner:
3434
inventory:
3535
host_vars:
3636
multiple-host:
37-
ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY: "8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9"
37+
ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY: "6c48435bd464a53ed66ed62127c4dba8af75cf1a99a8ebe2680599948fbfbc6d"
3838
MONITOR_PORT: 3003
3939
syslog_server_port: "udp://127.0.0.1:514"
4040
verifier:

deployment-e2e/molecule/oracle/molecule.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ provisioner:
3333
inventory:
3434
host_vars:
3535
oracle-host:
36-
ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY: "8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9"
36+
ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY: "6c48435bd464a53ed66ed62127c4dba8af75cf1a99a8ebe2680599948fbfbc6d"
3737
syslog_server_port: "udp://127.0.0.1:514"
3838
verifier:
3939
name: testinfra

deployment/group_vars/example.yml

+6-6
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ ORACLE_LOG_LEVEL: debug
55

66
## Home contract
77
COMMON_HOME_RPC_URL: "https://sokol.poa.network"
8-
COMMON_HOME_BRIDGE_ADDRESS: "0x98aFdE294f1C46aA0a27Cc4049ED337F879d8976"
8+
COMMON_HOME_BRIDGE_ADDRESS: "0x59ba90A588ce732AB33FD32Aab1b58c21400A0f6"
99
ORACLE_HOME_RPC_POLLING_INTERVAL: 5000
1010

1111
## Foreign contract
12-
COMMON_FOREIGN_RPC_URL: "https://sokol.poa.network"
13-
COMMON_FOREIGN_BRIDGE_ADDRESS: "0x5a584f4C30B36f282848dAc9a2b20E7BEF481981"
14-
ORACLE_FOREIGN_RPC_POLLING_INTERVAL: 1000
12+
COMMON_FOREIGN_RPC_URL: "https://kovan.infura.io/v3/5d7bd94c50ed43fab1cb8e74f58678b0"
13+
COMMON_FOREIGN_BRIDGE_ADDRESS: "0xdA4a49a00F4fF4A5988b9AceE95f99e3b2c208b6"
14+
ORACLE_FOREIGN_RPC_POLLING_INTERVAL: 5000
1515

1616
## Home Gasprice
1717
COMMON_HOME_GAS_PRICE_SUPPLIER_URL: "https://gasprice.poa.network/"
@@ -31,8 +31,8 @@ ORACLE_FOREIGN_GAS_PRICE_UPDATE_INTERVAL: 600000
3131
MONITOR_BRIDGE_NAME: "bridge"
3232
MONITOR_PORT: 3003
3333
MONITOR_CACHE_EVENTS: "false"
34-
MONITOR_HOME_START_BLOCK: 0
35-
MONITOR_FOREIGN_START_BLOCK: 0
34+
MONITOR_HOME_START_BLOCK: 20821049
35+
MONITOR_FOREIGN_START_BLOCK: 24773297
3636
MONITOR_VALIDATOR_HOME_TX_LIMIT: 300000
3737
MONITOR_VALIDATOR_FOREIGN_TX_LIMIT: 300000
3838
MONITOR_TX_NUMBER_THRESHOLD: 100

deployment/roles/oracle/tasks/post_config.yml

-11
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,6 @@
2727
set_fact:
2828
ORACLE_VALIDATOR_ADDRESS: "{{ VADDRESS.stdout }}"
2929

30-
- name: Get foreign erc type
31-
become_user: "{{ compose_service_user }}"
32-
shell: docker-compose run --rm --entrypoint "node scripts/initialChecks.js" bridge_affirmation
33-
args:
34-
chdir: "{{ bridge_path }}/oracle"
35-
register: ERCTYPE
36-
37-
- name: Set FOREIGN_ERC_TYPE variable
38-
set_fact:
39-
FOREIGN_ERC_TYPE: "{{ (ERCTYPE.stdout).foreignERC | default('') }}"
40-
4130
- name: Extend docker compose file for erc to native
4231
set_fact: composefileoverride="-f docker-compose-transfer.yml"
4332
when: ORACLE_BRIDGE_MODE == "ERC_TO_NATIVE"

e2e-commons/components-envs/oracle-amb.env

+2-4
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@ COMMON_HOME_RPC_URL=http://parity1:8545
66
COMMON_FOREIGN_RPC_URL=http://parity2:8545
77
COMMON_HOME_BRIDGE_ADDRESS=0x8397be90BCF57b0B71219f555Fe121b22e5a994C
88
COMMON_FOREIGN_BRIDGE_ADDRESS=0x1feB40aD9420b186F019A717c37f5546165d411E
9-
ORACLE_VALIDATOR_ADDRESS=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
10-
ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY=8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9
11-
COMMON_HOME_GAS_PRICE_SUPPLIER_URL=https://gasprice.poa.network/
9+
COMMON_HOME_GAS_PRICE_SUPPLIER_URL=
1210
COMMON_HOME_GAS_PRICE_SPEED_TYPE=standard
1311
COMMON_HOME_GAS_PRICE_FALLBACK=1000000000
1412
ORACLE_HOME_GAS_PRICE_UPDATE_INTERVAL=600000
1513
COMMON_HOME_GAS_PRICE_FACTOR=1
16-
COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL=https://gasprice.poa.network/
14+
COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL=
1715
COMMON_FOREIGN_GAS_PRICE_SPEED_TYPE=standard
1816
COMMON_FOREIGN_GAS_PRICE_FALLBACK=10000000000
1917
ORACLE_FOREIGN_GAS_PRICE_UPDATE_INTERVAL=600000

e2e-commons/components-envs/oracle-erc20-native.env

-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ COMMON_HOME_RPC_URL=http://parity1:8545
66
COMMON_FOREIGN_RPC_URL=http://parity2:8545
77
COMMON_HOME_BRIDGE_ADDRESS=0x5118AC62AE912Dd5B51EEfF7338c4fcb0248Ba8c
88
COMMON_FOREIGN_BRIDGE_ADDRESS=0x32198D570fffC7033641F8A9094FFDCaAEF42624
9-
ORACLE_VALIDATOR_ADDRESS=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
10-
ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY=8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9
119
COMMON_HOME_GAS_PRICE_SUPPLIER_URL=https://gasprice.poa.network/
1210
COMMON_HOME_GAS_PRICE_SPEED_TYPE=standard
1311
COMMON_HOME_GAS_PRICE_FALLBACK=1

0 commit comments

Comments
 (0)