Skip to content

Commit 4f5e3c4

Browse files
authored
Merge the develop branch to the master branch, preparation to v3.0.0
This merge contains the following set of changes: * [Oracle, Improvement] Async calls error codes (#587) * [Oracle, Improvement] Refactor/async call serializers (#588)
2 parents c92f80c + 4c06329 commit 4f5e3c4

15 files changed

+200
-79
lines changed

Dockerfile.e2e

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ COPY --from=contracts /mono/contracts/build ./contracts/build
1919
COPY commons/package.json ./commons/
2020
COPY oracle-e2e/package.json ./oracle-e2e/
2121
COPY monitor-e2e/package.json ./monitor-e2e/
22+
COPY oracle/src/utils/constants.js ./oracle/src/utils/constants.js
2223

2324
COPY yarn.lock .
2425
RUN NOYARNPOSTINSTALL=1 yarn install --frozen-lockfile --production

oracle-e2e/test/amb.js

+67-52
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const Web3 = require('web3')
22
const assert = require('assert')
3+
const { ASYNC_CALL_ERRORS } = require('../../oracle/src/utils/constants')
34
const { user, homeRPC, foreignRPC, amb, validator } = require('../../e2e-commons/constants.json')
45
const { uniformRetry } = require('../../e2e-commons/utils')
56
const { BOX_ABI, HOME_AMB_ABI, FOREIGN_AMB_ABI, ambInformationSignatures } = require('../../commons')
@@ -26,6 +27,45 @@ const foreignBox = new foreignWeb3.eth.Contract(BOX_ABI, amb.foreignBox, opts)
2627
const homeBridge = new homeWeb3.eth.Contract(HOME_AMB_ABI, amb.home, opts)
2728
const foreignBridge = new foreignWeb3.eth.Contract(FOREIGN_AMB_ABI, amb.foreign, opts)
2829

30+
function validateBlock(web3, serialized, block) {
31+
assert.strictEqual(serialized.length, 2 + 64 * 12)
32+
const values = web3.eth.abi.decodeParameter(
33+
'(uint256,bytes32,address,uint256,uint256,bytes32,bytes32,bytes32,bytes32,uint256,uint256,uint256)',
34+
serialized
35+
)
36+
assert.strictEqual(values[0], block.number.toString(), 'wrong block number returned')
37+
assert.strictEqual(values[1], block.hash, 'wrong block hash returned')
38+
assert.strictEqual(values[2], block.miner, 'wrong block miner returned')
39+
assert.strictEqual(values[3], block.gasUsed.toString(), 'wrong block gasUsed returned')
40+
assert.strictEqual(values[4], block.gasLimit.toString(), 'wrong block gasLimit returned')
41+
assert.strictEqual(values[5], block.parentHash, 'wrong block parentHash returned')
42+
assert.strictEqual(values[6], block.receiptsRoot, 'wrong block receiptsRoot returned')
43+
assert.strictEqual(values[7], block.stateRoot, 'wrong block stateRoot returned')
44+
assert.strictEqual(values[8], block.transactionsRoot, 'wrong block transactionsRoot returned')
45+
assert.strictEqual(values[9], block.timestamp.toString(), 'wrong block timestamp returned')
46+
assert.strictEqual(values[10], block.difficulty, 'wrong block difficulty returned')
47+
assert.strictEqual(values[11], block.totalDifficulty, 'wrong block totalDifficulty returned')
48+
}
49+
50+
function validateTransaction(web3, serialized, tx) {
51+
assert.strictEqual(serialized.length, 64 * 13 + tx.input.length + 56)
52+
const values = web3.eth.abi.decodeParameter(
53+
'(bytes32,uint256,bytes32,uint256,address,address,uint256,uint256,uint256,uint256,bytes)',
54+
serialized
55+
)
56+
assert.strictEqual(values[0], tx.hash, 'wrong txHash returned')
57+
assert.strictEqual(values[1], tx.blockNumber.toString(), 'wrong tx blockNumber returned')
58+
assert.strictEqual(values[2], tx.blockHash.toString(), 'wrong tx blockHash returned')
59+
assert.strictEqual(values[3], tx.transactionIndex.toString(), 'wrong tx transactionIndex returned')
60+
assert.strictEqual(values[4], tx.from, 'wrong tx from returned')
61+
assert.strictEqual(values[5], tx.to, 'wrong tx to returned')
62+
assert.strictEqual(values[6], tx.value, 'wrong tx value returned')
63+
assert.strictEqual(values[7], tx.nonce.toString(), 'wrong tx nonce returned')
64+
assert.strictEqual(values[8], tx.gas.toString(), 'wrong tx gas returned')
65+
assert.strictEqual(values[9], tx.gasPrice, 'wrong tx gasPrice returned')
66+
assert.strictEqual(values[10], tx.input, 'wrong tx data returned')
67+
}
68+
2969
describe('arbitrary message bridging', () => {
3070
let requiredSignatures = 1
3171
before(async () => {
@@ -264,7 +304,7 @@ describe('arbitrary message bridging', () => {
264304
await makeAsyncCall(selector, data2)
265305

266306
assert(!(await homeBox.methods.status().call()), 'status is true')
267-
assert.strictEqual(await homeBox.methods.data().call(), null, 'returned data is incorrect')
307+
assert.strictEqual(await homeBox.methods.data().call(), ASYNC_CALL_ERRORS.REVERT, 'returned data is incorrect')
268308

269309
const data3 = homeWeb3.eth.abi.encodeParameters(
270310
['address', 'address', 'uint256', 'bytes'],
@@ -274,7 +314,7 @@ describe('arbitrary message bridging', () => {
274314
await makeAsyncCall(selector, data3)
275315

276316
assert(!(await homeBox.methods.status().call()), 'status is true')
277-
assert.strictEqual(await homeBox.methods.data().call(), null, 'returned data is incorrect')
317+
assert.strictEqual(await homeBox.methods.data().call(), ASYNC_CALL_ERRORS.REVERT, 'returned data is incorrect')
278318
})
279319

280320
it('should make async eth_call for specific block', async () => {
@@ -315,6 +355,11 @@ describe('arbitrary message bridging', () => {
315355
await makeAsyncCall(selector, data3)
316356

317357
assert(!(await homeBox.methods.status().call()), 'status is true')
358+
assert.strictEqual(
359+
await homeBox.methods.data().call(),
360+
ASYNC_CALL_ERRORS.BLOCK_IS_IN_THE_FUTURE,
361+
'returned data is incorrect'
362+
)
318363
})
319364

320365
it('should make async eth_blockNumber', async () => {
@@ -334,15 +379,8 @@ describe('arbitrary message bridging', () => {
334379

335380
assert(await homeBox.methods.status().call(), 'status is false')
336381
const data = await homeBox.methods.data().call()
337-
assert.strictEqual(data.length, 2 + 64 * 3)
338-
const { 0: number, 1: hash, 2: miner } = homeWeb3.eth.abi.decodeParameters(
339-
['uint256', 'bytes32', 'address'],
340-
data
341-
)
342382
const block = await foreignWeb3.eth.getBlock(blockNumber)
343-
assert.strictEqual(number, blockNumber, 'wrong block number returned')
344-
assert.strictEqual(hash, block.hash, 'wrong block hash returned')
345-
assert.strictEqual(miner, block.miner, 'wrong block miner returned')
383+
validateBlock(homeWeb3, data, block)
346384
})
347385

348386
it('should make async eth_getBlockByNumber and return latest block', async () => {
@@ -352,7 +390,7 @@ describe('arbitrary message bridging', () => {
352390

353391
assert(await homeBox.methods.status().call(), 'status is false')
354392
const data = await homeBox.methods.data().call()
355-
assert.strictEqual(data.length, 2 + 64 * 3)
393+
assert.strictEqual(data.length, 2 + 64 * 12)
356394
})
357395

358396
it('should make async eth_getBlockByHash', async () => {
@@ -364,16 +402,7 @@ describe('arbitrary message bridging', () => {
364402

365403
assert(await homeBox.methods.status().call(), 'status is false')
366404
const data = await homeBox.methods.data().call()
367-
assert.strictEqual(data.length, 2 + 64 * 3)
368-
369-
const { 0: number, 1: hash, 2: miner } = homeWeb3.eth.abi.decodeParameters(
370-
['uint256', 'bytes32', 'address'],
371-
data
372-
)
373-
374-
assert.strictEqual(number, blockNumber, 'wrong block number returned')
375-
assert.strictEqual(hash, block.hash, 'wrong block hash returned')
376-
assert.strictEqual(miner, block.miner, 'wrong block miner returned')
405+
validateBlock(homeWeb3, data, block)
377406
})
378407

379408
it('should make async eth_getBalance', async () => {
@@ -469,28 +498,7 @@ describe('arbitrary message bridging', () => {
469498

470499
assert(await homeBox.methods.status().call(), 'status is false')
471500
const data = await homeBox.methods.data().call()
472-
const dataTypes = [
473-
'bytes32',
474-
'uint256',
475-
'address',
476-
'address',
477-
'uint256',
478-
'uint256',
479-
'uint256',
480-
'uint256',
481-
'bytes'
482-
]
483-
const values = homeWeb3.eth.abi.decodeParameters(dataTypes, data)
484-
485-
assert.strictEqual(values[0], txHash, 'wrong txHash returned')
486-
assert.strictEqual(values[1], tx.blockNumber.toString(), 'wrong tx blockNumber returned')
487-
assert.strictEqual(values[2], tx.from, 'wrong tx from returned')
488-
assert.strictEqual(values[3], tx.to, 'wrong tx to returned')
489-
assert.strictEqual(values[4], tx.value, 'wrong tx value returned')
490-
assert.strictEqual(values[5], tx.nonce.toString(), 'wrong tx nonce returned')
491-
assert.strictEqual(values[6], tx.gas.toString(), 'wrong tx gas returned')
492-
assert.strictEqual(values[7], tx.gasPrice, 'wrong tx gasPrice returned')
493-
assert.strictEqual(values[8], tx.input, 'wrong tx data returned')
501+
validateTransaction(homeWeb3, data, tx)
494502
})
495503

496504
it('should make async eth_getTransactionReceipt', async () => {
@@ -502,18 +510,25 @@ describe('arbitrary message bridging', () => {
502510

503511
assert(await homeBox.methods.status().call(), 'status is false')
504512
const data = await homeBox.methods.data().call()
505-
const dataTypes = ['bytes32', 'uint256', 'bool', '(address,bytes32[],bytes)[]']
506-
const values = homeWeb3.eth.abi.decodeParameters(dataTypes, data)
513+
const values = homeWeb3.eth.abi.decodeParameter(
514+
'(bytes32,uint256,bytes32,uint256,address,address,uint256,bool,(address,bytes32[],bytes)[])',
515+
data
516+
)
507517

508518
assert.strictEqual(values[0], txHash, 'wrong txHash returned')
509519
assert.strictEqual(values[1], receipt.blockNumber.toString(), 'wrong tx blockNumber returned')
510-
assert.strictEqual(values[2], receipt.status, 'wrong tx status returned')
511-
assert.strictEqual(values[3].length, 1, 'wrong logs length returned')
512-
assert.strictEqual(values[3][0][0], receipt.logs[0].address, 'wrong log address returned')
513-
assert.strictEqual(values[3][0][1].length, 2, 'wrong log topics length returned')
514-
assert.strictEqual(values[3][0][1][0], receipt.logs[0].topics[0], 'wrong event signature returned')
515-
assert.strictEqual(values[3][0][1][1], receipt.logs[0].topics[1], 'wrong message id returned')
516-
assert.strictEqual(values[3][0][2], receipt.logs[0].data, 'wrong log data returned')
520+
assert.strictEqual(values[2], receipt.blockHash, 'wrong tx blockHash returned')
521+
assert.strictEqual(values[3], receipt.transactionIndex.toString(), 'wrong tx transactionIndex returned')
522+
assert.strictEqual(values[4].toLowerCase(), receipt.from, 'wrong tx from returned')
523+
assert.strictEqual(values[5].toLowerCase(), receipt.to, 'wrong tx to returned')
524+
assert.strictEqual(values[6], receipt.gasUsed.toString(), 'wrong gasUsed to returned')
525+
assert.strictEqual(values[7], receipt.status, 'wrong tx status returned')
526+
assert.strictEqual(values[8].length, 1, 'wrong logs length returned')
527+
assert.strictEqual(values[8][0][0], receipt.logs[0].address, 'wrong log address returned')
528+
assert.strictEqual(values[8][0][1].length, 2, 'wrong log topics length returned')
529+
assert.strictEqual(values[8][0][1][0], receipt.logs[0].topics[0], 'wrong event signature returned')
530+
assert.strictEqual(values[8][0][1][1], receipt.logs[0].topics[1], 'wrong message id returned')
531+
assert.strictEqual(values[8][0][2], receipt.logs[0].data, 'wrong log data returned')
517532
})
518533

519534
it('should make async eth_getStorageAt', async () => {

oracle/src/events/processAMBInformationRequests/calls/ethCall.js

+16-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const { toBN } = require('web3').utils
22

3-
const { zipToObject } = require('../../../utils/utils')
3+
const { ASYNC_CALL_ERRORS, ASYNC_ETH_CALL_MAX_GAS_LIMIT } = require('../../../utils/constants')
4+
const { zipToObject, isRevertError } = require('../../../utils/utils')
45

56
const argTypes = {
67
to: 'address',
@@ -17,14 +18,23 @@ function makeCall(argNames) {
1718
const { blockNumber, ...opts } = zipToObject(argNames, args)
1819

1920
if (blockNumber && toBN(blockNumber).gt(toBN(foreignBlock.number))) {
20-
return [false, '0x']
21+
return [false, ASYNC_CALL_ERRORS.BLOCK_IS_IN_THE_FUTURE]
2122
}
2223

23-
const [status, result] = await web3.eth
24-
.call(opts, blockNumber || foreignBlock.number)
25-
.then(result => [true, result], err => [false, err.data])
24+
// different clients might use different default gas limits, so it makes sense to limit it by some large number
25+
if (!opts.gas || toBN(opts.gas).gt(toBN(ASYNC_ETH_CALL_MAX_GAS_LIMIT))) {
26+
opts.gas = ASYNC_ETH_CALL_MAX_GAS_LIMIT
27+
}
2628

27-
return [status, web3.eth.abi.encodeParameter('bytes', result)]
29+
return web3.eth
30+
.call(opts, blockNumber || foreignBlock.number)
31+
.then(result => [true, web3.eth.abi.encodeParameter('bytes', result)])
32+
.catch(e => {
33+
if (isRevertError(e)) {
34+
return [false, ASYNC_CALL_ERRORS.REVERT]
35+
}
36+
throw e
37+
})
2838
}
2939
}
3040

oracle/src/events/processAMBInformationRequests/calls/ethGetBalance.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
const { toBN } = require('web3').utils
22

3+
const { ASYNC_CALL_ERRORS } = require('../../../utils/constants')
4+
35
async function call(web3, data, foreignBlock) {
46
const address = web3.eth.abi.decodeParameter('address', data)
57

@@ -12,7 +14,7 @@ async function callArchive(web3, data, foreignBlock) {
1214
const { 0: address, 1: blockNumber } = web3.eth.abi.decodeParameters(['address', 'uint256'], data)
1315

1416
if (toBN(blockNumber).gt(toBN(foreignBlock.number))) {
15-
return [false, '0x']
17+
return [false, ASYNC_CALL_ERRORS.BLOCK_IS_IN_THE_FUTURE]
1618
}
1719

1820
const balance = await web3.eth.getBalance(address, blockNumber)

oracle/src/events/processAMBInformationRequests/calls/ethGetBlockByHash.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
const { ASYNC_CALL_ERRORS } = require('../../../utils/constants')
12
const { serializeBlock } = require('./serializers')
23

34
async function call(web3, data, foreignBlock) {
@@ -6,7 +7,7 @@ async function call(web3, data, foreignBlock) {
67
const block = await web3.eth.getBlock(blockHash)
78

89
if (block === null || block.number > foreignBlock.number) {
9-
return [false, '0x']
10+
return [false, ASYNC_CALL_ERRORS.NOT_FOUND]
1011
}
1112

1213
return [true, serializeBlock(web3, block)]

oracle/src/events/processAMBInformationRequests/calls/ethGetBlockByNumber.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
const { toBN } = require('web3').utils
22

3+
const { ASYNC_CALL_ERRORS } = require('../../../utils/constants')
34
const { serializeBlock } = require('./serializers')
45

56
async function call(web3, data, foreignBlock) {
67
const blockNumber = web3.eth.abi.decodeParameter('uint256', data)
78

89
if (toBN(blockNumber).gt(toBN(foreignBlock.number))) {
9-
return [false, '0x']
10+
return [false, ASYNC_CALL_ERRORS.BLOCK_IS_IN_THE_FUTURE]
1011
}
1112

1213
const block = await web3.eth.getBlock(blockNumber)

oracle/src/events/processAMBInformationRequests/calls/ethGetStorageAt.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
const { toBN } = require('web3').utils
22

3+
const { ASYNC_CALL_ERRORS } = require('../../../utils/constants')
4+
35
async function call(web3, data, foreignBlock) {
46
const { 0: address, 1: slot } = web3.eth.abi.decodeParameters(['address', 'bytes32'], data)
57

@@ -12,7 +14,7 @@ async function callArchive(web3, data, foreignBlock) {
1214
const { 0: address, 1: slot, 2: blockNumber } = web3.eth.abi.decodeParameters(['address', 'bytes32', 'uint256'], data)
1315

1416
if (toBN(blockNumber).gt(toBN(foreignBlock.number))) {
15-
return [false, '0x']
17+
return [false, ASYNC_CALL_ERRORS.BLOCK_IS_IN_THE_FUTURE]
1618
}
1719

1820
const value = await web3.eth.getStorageAt(address, slot, blockNumber)

oracle/src/events/processAMBInformationRequests/calls/ethGetTransactionByHash.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
const { ASYNC_CALL_ERRORS } = require('../../../utils/constants')
12
const { serializeTx } = require('./serializers')
23

34
async function call(web3, data, foreignBlock) {
@@ -6,7 +7,7 @@ async function call(web3, data, foreignBlock) {
67
const tx = await web3.eth.getTransaction(hash)
78

89
if (tx === null || tx.blockNumber > foreignBlock.number) {
9-
return [false, '0x']
10+
return [false, ASYNC_CALL_ERRORS.NOT_FOUND]
1011
}
1112

1213
return [true, serializeTx(web3, tx)]

oracle/src/events/processAMBInformationRequests/calls/ethGetTransactionCount.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
const { toBN } = require('web3').utils
22

3+
const { ASYNC_CALL_ERRORS } = require('../../../utils/constants')
4+
35
async function call(web3, data, foreignBlock) {
46
const address = web3.eth.abi.decodeParameter('address', data)
57

@@ -12,7 +14,7 @@ async function callArchive(web3, data, foreignBlock) {
1214
const { 0: address, 1: blockNumber } = web3.eth.abi.decodeParameters(['address', 'uint256'], data)
1315

1416
if (toBN(blockNumber).gt(toBN(foreignBlock.number))) {
15-
return [false, '0x']
17+
return [false, ASYNC_CALL_ERRORS.BLOCK_IS_IN_THE_FUTURE]
1618
}
1719

1820
const nonce = await web3.eth.getTransactionCount(address, blockNumber)

oracle/src/events/processAMBInformationRequests/calls/ethGetTransactionReceipt.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
const { ASYNC_CALL_ERRORS } = require('../../../utils/constants')
12
const { serializeReceipt } = require('./serializers')
23

34
async function call(web3, data, foreignBlock) {
@@ -6,7 +7,7 @@ async function call(web3, data, foreignBlock) {
67
const receipt = await web3.eth.getTransactionReceipt(hash)
78

89
if (receipt === null || receipt.blockNumber > foreignBlock.number) {
9-
return [false, '0x']
10+
return [false, ASYNC_CALL_ERRORS.NOT_FOUND]
1011
}
1112

1213
return [true, serializeReceipt(web3, receipt)]

0 commit comments

Comments
 (0)