Skip to content

Commit 78564af

Browse files
authored
Merge the develop branch to the master branch, preparation to v3.1.0
This merge contains the following set of changes: * [Oracle, Improvement] Try to detect unsynced node state (#592) * [Oracle, Improvement] Allow to override JSON RPC error codes (#603) * [Oracle, Fix] Fix handling of Compound related Transfer events (#595) * [Oracle, Fix] Add new nonce-related error messages (#599) * [Deployment, Fix] .env template includes latest changes related to the oracle configuration (#601) * [Deployment, Fix] Improvements for the local logs configuration (#602) * [Common, Other] Update the contract's submodule to the release 6.0.0 (#600)
2 parents 4f5e3c4 + 70a2c30 commit 78564af

File tree

27 files changed

+1017
-1594
lines changed

27 files changed

+1017
-1594
lines changed

.github/workflows/main.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ jobs:
7777
- name: Rebuild and push updated images
7878
run: |
7979
function check_if_image_exists() {
80-
curl -fsSlL -H 'Authorization: bearer ${{ github.token }}' "https://${DOCKER_REGISTRY}/v2/${DOCKER_REPO}/tokenbridge-e2e-$1/manifests/$2" > /dev/null
80+
curl -fsSlL "https://${{ github.actor }}:${{ github.token }}@${DOCKER_REGISTRY}/v2/${DOCKER_REPO}/tokenbridge-e2e-$1/manifests/$2" > /dev/null
8181
}
8282
updated=()
8383
if ! check_if_image_exists e2e ${E2E_TAG}; then updated+=("e2e"); fi
@@ -104,7 +104,7 @@ jobs:
104104
- name: Rebuild and push molecule runner e2e image
105105
run: |
106106
function check_if_image_exists() {
107-
curl -fsSlL -H 'Authorization: bearer ${{ github.token }}' "https://${DOCKER_REGISTRY}/v2/${DOCKER_REPO}/tokenbridge-e2e-$1/manifests/$2" > /dev/null
107+
curl -fsSlL "https://${{ github.actor }}:${{ github.token }}@${DOCKER_REGISTRY}/v2/${DOCKER_REPO}/tokenbridge-e2e-$1/manifests/$2" > /dev/null
108108
}
109109
if check_if_image_exists molecule_runner ${MOLECULE_RUNNER_TAG}; then
110110
echo "Image already exists"

CONFIGURATION.md

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ ORACLE_SHUTDOWN_CONTRACT_ADDRESS | Optional contract address in the side chain a
5252
ORACLE_SHUTDOWN_CONTRACT_METHOD | Method signature to be used in the side chain to identify the current shutdown status. Method should return boolean. Default value is `isShutdown()`. | `function signature`
5353
ORACLE_FOREIGN_RPC_BLOCK_POLLING_LIMIT | Max length for the block range used in `eth_getLogs` requests for polling contract events for the Foreign chain. Infinite, if not provided. | `integer`
5454
ORACLE_HOME_RPC_BLOCK_POLLING_LIMIT | Max length for the block range used in `eth_getLogs` requests for polling contract events for the Home chain. Infinite, if not provided. | `integer`
55+
ORACLE_JSONRPC_ERROR_CODES | Override default JSON rpc error codes that can trigger RPC fallback to the next URL from the list (or a retry in case of a single RPC URL). Default is `-32603,-32002,-32005`. Should be a comma-separated list of negative integers. | `string`
5556

5657

5758
## Monitor configuration

commons/abis.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const HOME_ERC_TO_NATIVE_ABI = require('../contracts/build/contracts/HomeBridgeErcToNative').abi
2-
const FOREIGN_ERC_TO_NATIVE_ABI = require('../contracts/build/contracts/ForeignBridgeErcToNative').abi
2+
const FOREIGN_ERC_TO_NATIVE_ABI = require('../contracts/build/contracts/XDaiForeignBridge.json').abi
33
const ERC20_ABI = require('../contracts/build/contracts/ERC20').abi
44
const BLOCK_REWARD_ABI = require('../contracts/build/contracts/BlockRewardMock').abi
55
const BRIDGE_VALIDATORS_ABI = require('../contracts/build/contracts/BridgeValidators').abi

contracts

deployment/roles/common/templates/docker-logs.j2

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
/var/log/docker/*/docker.log {
22
rotate 5
3-
size 1G
3+
size 100M
44
compress
55
missingok
66
delaycompress
77
copytruncate
88
}
99
/var/log/docker/*.log {
1010
rotate 5
11-
size 1G
11+
size 100M
1212
compress
1313
missingok
1414
delaycompress

deployment/roles/oracle/tasks/logging.yml

+17-1
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,30 @@
77
loop_control:
88
loop_var: file
99

10-
- name: Set the local container logs configuration file
10+
- name: Set the oracle's containers local logs configuration file
1111
template:
1212
src: 31-oracle-docker.conf.j2
1313
dest: /etc/rsyslog.d/31-oracle-docker.conf
1414
owner: root
1515
group: root
1616
mode: 0644
1717

18+
- name: Set the redis container local logs configuration file
19+
template:
20+
src: 32-redis-docker.conf.j2
21+
dest: /etc/rsyslog.d/32-redis-docker.conf
22+
owner: root
23+
group: root
24+
mode: 0644
25+
26+
- name: Set the rabbit MQ container local logs configuration file
27+
template:
28+
src: 33-rabbit-docker.conf.j2
29+
dest: /etc/rsyslog.d/33-rabbit-docker.conf
30+
owner: root
31+
group: root
32+
mode: 0644
33+
1834
- name: Set the log configuration file to send container logs to remote server
1935
template:
2036
src: 36-oracle-remote-logging.conf.j2

deployment/roles/oracle/templates/.env.j2

+29-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,16 @@ ORACLE_HOME_RPC_POLLING_INTERVAL={{ ORACLE_HOME_RPC_POLLING_INTERVAL }}
1111

1212
## Foreign contract
1313
COMMON_FOREIGN_RPC_URL={{ COMMON_FOREIGN_RPC_URL }}
14+
{% if ORACLE_FOREIGN_ARCHIVE_RPC_URL | default('') != '' %}
15+
ORACLE_FOREIGN_ARCHIVE_RPC_URL={{ ORACLE_FOREIGN_ARCHIVE_RPC_URL }}
16+
{% endif %}
1417
COMMON_FOREIGN_BRIDGE_ADDRESS={{ COMMON_FOREIGN_BRIDGE_ADDRESS }}
1518
ORACLE_FOREIGN_RPC_POLLING_INTERVAL={{ ORACLE_FOREIGN_RPC_POLLING_INTERVAL }}
1619

20+
{% if ORACLE_TX_REDUNDANCY | default('') != '' %}
21+
ORACLE_TX_REDUNDANCY={{ ORACLE_TX_REDUNDANCY }}
22+
{% endif %}
23+
1724
## Gasprice
1825
{% if COMMON_HOME_GAS_PRICE_SUPPLIER_URL | default('') != '' %}
1926
COMMON_HOME_GAS_PRICE_SUPPLIER_URL={{ COMMON_HOME_GAS_PRICE_SUPPLIER_URL }}
@@ -47,8 +54,28 @@ COMMON_FOREIGN_GAS_PRICE_FACTOR={{ COMMON_FOREIGN_GAS_PRICE_FACTOR }}
4754
ORACLE_ALLOW_HTTP_FOR_RPC={{ "yes" if ORACLE_ALLOW_HTTP_FOR_RPC else "no" }}
4855
ORACLE_QUEUE_URL={{ ORACLE_QUEUE_URL }}
4956
ORACLE_REDIS_URL={{ ORACLE_REDIS_URL }}
50-
{% if ORACLE_TX_REDUNDANCY | default('') != '' %}
51-
ORACLE_TX_REDUNDANCY={{ ORACLE_TX_REDUNDANCY }}
57+
{% if ORACLE_FOREIGN_TX_RESEND_INTERVAL | default('') != '' %}
58+
ORACLE_FOREIGN_TX_RESEND_INTERVAL={{ ORACLE_FOREIGN_TX_RESEND_INTERVAL }}
59+
{% endif %}
60+
{% if ORACLE_HOME_TX_RESEND_INTERVAL | default('') != '' %}
61+
ORACLE_HOME_TX_RESEND_INTERVAL={{ ORACLE_HOME_TX_RESEND_INTERVAL }}
62+
{% endif %}
63+
64+
## Emergency shutdown configuration
65+
{% if ORACLE_SHUTDOWN_SERVICE_URL | default('') != '' %}
66+
ORACLE_SHUTDOWN_SERVICE_URL={{ ORACLE_SHUTDOWN_SERVICE_URL }}
67+
{% endif %}
68+
{% if ORACLE_SHUTDOWN_SERVICE_POLLING_INTERVAL | default('') != '' %}
69+
ORACLE_SHUTDOWN_SERVICE_POLLING_INTERVAL={{ ORACLE_SHUTDOWN_SERVICE_POLLING_INTERVAL }}
70+
{% endif %}
71+
{% if ORACLE_SIDE_RPC_URL | default('') != '' %}
72+
ORACLE_SIDE_RPC_URL={{ ORACLE_SIDE_RPC_URL }}
73+
{% endif %}
74+
{% if ORACLE_SHUTDOWN_CONTRACT_ADDRESS | default('') != '' %}
75+
ORACLE_SHUTDOWN_CONTRACT_ADDRESS={{ ORACLE_SHUTDOWN_CONTRACT_ADDRESS }}
76+
{% endif %}
77+
{% if ORACLE_SHUTDOWN_CONTRACT_METHOD | default('') != '' %}
78+
ORACLE_SHUTDOWN_CONTRACT_METHOD={{ ORACLE_SHUTDOWN_CONTRACT_METHOD }}
5279
{% endif %}
5380

5481
{% if ORACLE_HOME_START_BLOCK | default('') != '' %}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
$FileCreateMode 0644
2+
template(name="DockerLogFileName_Redis" type="list") {
3+
constant(value="/var/log/docker/")
4+
property(name="syslogtag" securepath="replace" regex.type="ERE" regex.submatch="1" regex.expression="oracle_(.*redis.*)\\/[a-zA-Z0-9]+\\[")
5+
constant(value="/docker.log")
6+
}
7+
8+
if $programname contains 'oracle' and $programname contains 'redis' then \
9+
?DockerLogFileName_Redis
10+
11+
$FileCreateMode 0600
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
$FileCreateMode 0644
2+
template(name="DockerLogFileName_Rabbit" type="list") {
3+
constant(value="/var/log/docker/")
4+
property(name="syslogtag" securepath="replace" regex.type="ERE" regex.submatch="1" regex.expression="oracle_(.*rabbit.*)\\/[a-zA-Z0-9]+\\[")
5+
constant(value="/docker.log")
6+
}
7+
8+
if $programname contains 'oracle' and $programname contains 'rabbit' then \
9+
?DockerLogFileName_Rabbit
10+
11+
$FileCreateMode 0600

e2e-commons/constants.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"ercToNativeBridge": {
3939
"home": "0x5118AC62AE912Dd5B51EEfF7338c4fcb0248Ba8c",
4040
"foreign": "0x32198D570fffC7033641F8A9094FFDCaAEF42624",
41-
"foreignToken": "0x7cc4b1851c35959d34e635a470f6b5c43ba3c9c9",
41+
"foreignToken": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
4242
"monitor": "http://monitor-erc20-native:3012/bridge"
4343
},
4444
"amb": {

e2e-commons/contracts-envs/erc-to-native.env

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ FOREIGN_GAS_PRICE=10000000000
3232
FOREIGN_REWARDABLE=false
3333

3434
BLOCK_REWARD_ADDRESS=0xdbeE25CbE97e4A5CC6c499875774dc7067E9426B
35-
ERC20_TOKEN_ADDRESS=0x7cc4b1851c35959d34e635a470f6b5c43ba3c9c9
35+
ERC20_TOKEN_ADDRESS=0x6B175474E89094C44Da98b954EedeAC495271d0F
3636

3737
REQUIRED_NUMBER_OF_VALIDATORS=1
3838
VALIDATORS="0xaaB52d66283F7A1D5978bcFcB55721ACB467384b 0xdCC784657C78054aa61FbcFFd2605F32374816A4 0xDcef88209a20D52165230104B245803C3269454d"

monitor/getBalances.js

+4-35
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,6 @@ async function main(bridgeMode, eventsInfo) {
4646
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_ERC_TO_NATIVE_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
4747
const erc20Address = await foreignBridge.methods.erc20token().call()
4848
const erc20Contract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
49-
let investedAmountInDai = 0
50-
let bridgeDsrBalance = 0
51-
let displayChaiToken = false
52-
53-
try {
54-
logger.debug('calling foreignBridge.methods.isChaiTokenEnabled')
55-
if (await foreignBridge.methods.isChaiTokenEnabled().call()) {
56-
displayChaiToken = true
57-
logger.debug('calling foreignBridge.methods.investedAmountInDai')
58-
investedAmountInDai = await foreignBridge.methods.investedAmountInDai().call()
59-
logger.debug('calling foreignBridge.methods.dsrBalance')
60-
bridgeDsrBalance = await foreignBridge.methods.dsrBalance().call()
61-
} else {
62-
logger.debug('Chai token is currently disabled')
63-
}
64-
} catch (e) {
65-
logger.debug('Methods for chai token are not present')
66-
}
6749

6850
logger.debug('calling erc20Contract.methods.balanceOf')
6951
const foreignErc20Balance = await erc20Contract.methods
@@ -85,29 +67,16 @@ async function main(bridgeMode, eventsInfo) {
8567
const burntCoinsBN = new BN(burntCoins)
8668
const totalSupplyBN = mintedCoinsBN.minus(burntCoinsBN)
8769
const foreignErc20BalanceBN = new BN(foreignErc20Balance).plus(lateForeignConfirmationsTotalValue)
88-
const investedAmountInDaiBN = new BN(investedAmountInDai)
89-
const bridgeDsrBalanceBN = new BN(bridgeDsrBalance)
90-
91-
const diff = foreignErc20BalanceBN
92-
.plus(investedAmountInDaiBN)
93-
.minus(totalSupplyBN)
94-
.toFixed()
95-
96-
const foreign = {
97-
erc20Balance: Web3Utils.fromWei(foreignErc20Balance)
98-
}
99-
100-
if (displayChaiToken) {
101-
foreign.investedErc20Balance = Web3Utils.fromWei(investedAmountInDai)
102-
foreign.accumulatedInterest = Web3Utils.fromWei(bridgeDsrBalanceBN.minus(investedAmountInDaiBN).toString(10))
103-
}
10470

71+
const diff = foreignErc20BalanceBN.minus(totalSupplyBN).toFixed()
10572
logger.debug('Done')
10673
return {
10774
home: {
10875
totalSupply: Web3Utils.fromWei(totalSupplyBN.toFixed())
10976
},
110-
foreign,
77+
foreign: {
78+
erc20Balance: Web3Utils.fromWei(foreignErc20Balance)
79+
},
11180
balanceDiff: Number(Web3Utils.fromWei(diff)),
11281
...blockRanges,
11382
lastChecked: Math.floor(Date.now() / 1000)

monitor/utils/events.js

+22-71
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ const {
1111
OLD_AMB_USER_REQUEST_FOR_AFFIRMATION_ABI
1212
} = require('../../commons')
1313
const { normalizeEventInformation } = require('./message')
14-
const { filterTransferBeforeES } = require('./tokenUtils')
1514
const { writeFile, readCacheFile } = require('./file')
1615
const { web3Home, web3Foreign, getHomeBlockNumber, getForeignBlockNumber } = require('./web3')
1716
const { getPastEvents } = require('./web3Cache')
@@ -160,80 +159,32 @@ async function main(mode) {
160159
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
161160
},
162161
chain: 'foreign'
162+
}))
163+
.map(normalizeEvent)
164+
.filter(e => e.recipient !== ZERO_ADDRESS) // filter mint operation during SCD-to-MCD swaps
165+
.filter(e => e.recipient.toLowerCase() !== '0x5d3a536e4d6dbd6114cc1ead35777bab948e3643') // filter cDai withdraws during compounding
166+
167+
// Get transfer events for each previously used Sai token
168+
const saiTokenAddress = '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359'
169+
const halfDuplexTokenContract = new web3Foreign.eth.Contract(ERC20_ABI, saiTokenAddress)
170+
logger.debug('Half duplex token:', saiTokenAddress)
171+
logger.debug("calling halfDuplexTokenContract.getPastEvents('Transfer')")
172+
// https://etherscan.io/tx/0xd0c3c92c94e05bc71256055ce8c4c993e047f04e04f3283a04e4cb077b71f6c6
173+
const blockNumberHalfDuplexDisabled = 9884448
174+
const halfDuplexTransferEvents = (await getPastEvents(halfDuplexTokenContract, {
175+
event: 'Transfer',
176+
fromBlock: MONITOR_FOREIGN_START_BLOCK,
177+
toBlock: Math.min(blockNumberHalfDuplexDisabled, foreignDelayedBlockNumber),
178+
options: {
179+
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
180+
},
181+
chain: 'foreign'
163182
})).map(normalizeEvent)
164183

165-
let directTransfers = transferEvents
166-
const tokensSwappedAbiExists = FOREIGN_ABI.filter(e => e.type === 'event' && e.name === 'TokensSwapped')[0]
167-
if (tokensSwappedAbiExists) {
168-
logger.debug('collecting half duplex tokens participated in the bridge balance')
169-
logger.debug("calling foreignBridge.getPastEvents('TokensSwapped')")
170-
const tokensSwappedEvents = await getPastEvents(foreignBridge, {
171-
event: 'TokensSwapped',
172-
fromBlock: MONITOR_FOREIGN_START_BLOCK,
173-
toBlock: foreignBlockNumber,
174-
chain: 'foreign',
175-
safeToBlock: foreignDelayedBlockNumber
176-
})
177-
178-
// Get token swap events emitted by foreign bridge
179-
const bridgeTokensSwappedEvents = tokensSwappedEvents.filter(e => e.address === COMMON_FOREIGN_BRIDGE_ADDRESS)
180-
181-
// Get transfer events for each previous erc20
182-
const uniqueTokenAddressesSet = new Set(bridgeTokensSwappedEvents.map(e => e.returnValues.from))
183-
184-
// Exclude chai token from previous erc20
185-
try {
186-
logger.debug('calling foreignBridge.chaiToken() to remove it from half duplex tokens list')
187-
const chaiToken = await foreignBridge.methods.chaiToken().call()
188-
uniqueTokenAddressesSet.delete(chaiToken)
189-
} catch (e) {
190-
logger.debug('call to foreignBridge.chaiToken() failed')
191-
}
192-
// Exclude dai token from previous erc20
193-
try {
194-
logger.debug('calling foreignBridge.erc20token() to remove it from half duplex tokens list')
195-
const daiToken = await foreignBridge.methods.erc20token().call()
196-
uniqueTokenAddressesSet.delete(daiToken)
197-
} catch (e) {
198-
logger.debug('call to foreignBridge.erc20token() failed')
199-
}
200-
201-
const uniqueTokenAddresses = [...uniqueTokenAddressesSet]
202-
await Promise.all(
203-
uniqueTokenAddresses.map(async tokenAddress => {
204-
const halfDuplexTokenContract = new web3Foreign.eth.Contract(ERC20_ABI, tokenAddress)
205-
206-
logger.debug('Half duplex token:', tokenAddress)
207-
logger.debug("calling halfDuplexTokenContract.getPastEvents('Transfer')")
208-
const halfDuplexTransferEvents = (await getPastEvents(halfDuplexTokenContract, {
209-
event: 'Transfer',
210-
fromBlock: MONITOR_FOREIGN_START_BLOCK,
211-
toBlock: foreignDelayedBlockNumber,
212-
options: {
213-
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
214-
},
215-
chain: 'foreign'
216-
})).map(normalizeEvent)
217-
218-
// Remove events after the ES
219-
logger.debug('filtering half duplex transfers happened before ES')
220-
const validHalfDuplexTransfers = await filterTransferBeforeES(halfDuplexTransferEvents)
221-
222-
transferEvents = [...validHalfDuplexTransfers, ...transferEvents]
223-
})
224-
)
225-
226-
// filter transfer that is part of a token swap
227-
directTransfers = transferEvents.filter(
228-
e =>
229-
bridgeTokensSwappedEvents.findIndex(
230-
t => t.transactionHash === e.referenceTx && e.recipient === ZERO_ADDRESS
231-
) === -1
232-
)
233-
}
184+
transferEvents = [...halfDuplexTransferEvents, ...transferEvents]
234185

235186
// Get transfer events that didn't have a UserRequestForAffirmation event in the same transaction
236-
directTransfers = directTransfers.filter(
187+
const directTransfers = transferEvents.filter(
237188
e => foreignToHomeRequests.findIndex(t => t.referenceTx === e.referenceTx) === -1
238189
)
239190

monitor/utils/tokenUtils.js

-27
This file was deleted.

oracle-e2e/test/ercToNative.js

+5
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ const homeBridge = new homeWeb3.eth.Contract(HOME_ERC_TO_NATIVE_ABI, COMMON_HOME
3333

3434
describe('erc to native', () => {
3535
before(async () => {
36+
console.log('Initializing interest')
37+
await foreignBridge.methods
38+
.initializeInterest(ercToNativeBridge.foreignToken, 1, 1, validator.address)
39+
.send({ from: validator.address, gas: '4000000' })
3640
if (process.env.ULTIMATE === 'true') {
3741
return
3842
}
@@ -112,6 +116,7 @@ describe('erc to native', () => {
112116
.catch(e => {
113117
console.error(e)
114118
})
119+
await foreignBridge.methods.investDai().send({ from: validator.address, gas: '4000000' })
115120

116121
// check that balance increases
117122
await uniformRetry(async retry => {

0 commit comments

Comments
 (0)