Allow to make new AMB requests while processing other messages (#572)
This commit is contained in:
parent
11d5ec35ef
commit
a85d9ab343
|
@ -10,6 +10,7 @@ contract BasicAMB is BasicBridge, VersionableAMB {
|
|||
bytes32 internal constant SOURCE_CHAIN_ID_LENGTH = 0xe504ae1fd6471eea80f18b8532a61a9bb91fba4f5b837f80a1cfb6752350af44; // keccak256(abi.encodePacked("sourceChainIdLength"))
|
||||
bytes32 internal constant DESTINATION_CHAIN_ID = 0xbbd454018e72a3f6c02bbd785bacc49e46292744f3f6761276723823aa332320; // keccak256(abi.encodePacked("destinationChainId"))
|
||||
bytes32 internal constant DESTINATION_CHAIN_ID_LENGTH = 0xfb792ae4ad11102b93f26a51b3749c2b3667f8b561566a4806d4989692811594; // keccak256(abi.encodePacked("destinationChainIdLength"))
|
||||
bytes32 internal constant ALLOW_REENTRANT_REQUESTS = 0xffa3a5a0e192028fc343362a39c5688e5a60819a4dc5ab3ee70c25bc25b78dd6; // keccak256(abi.encodePacked("allowReentrantRequests"))
|
||||
|
||||
/**
|
||||
* Initializes AMB contract
|
||||
|
@ -82,6 +83,24 @@ contract BasicAMB is BasicBridge, VersionableAMB {
|
|||
_setChainIds(_sourceChainId, _destinationChainId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the flag to allow passing new AMB requests in the opposite direction,
|
||||
* while other AMB message is being processed.
|
||||
* Only owner can call this method.
|
||||
* @param _enable true, if reentrant requests are allowed.
|
||||
*/
|
||||
function setAllowReentrantRequests(bool _enable) external onlyOwner {
|
||||
boolStorage[ALLOW_REENTRANT_REQUESTS] = _enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if passing reentrant requests is allowed.
|
||||
* @return true, if reentrant requests are allowed.
|
||||
*/
|
||||
function allowReentrantRequests() public view returns (bool) {
|
||||
return boolStorage[ALLOW_REENTRANT_REQUESTS];
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function for retrieving current nonce value
|
||||
* @return nonce value
|
||||
|
|
|
@ -30,8 +30,8 @@ contract MessageDelivery is BasicAMB, MessageProcessor {
|
|||
*/
|
||||
function _sendMessage(address _contract, bytes _data, uint256 _gas, uint256 _dataType) public returns (bytes32) {
|
||||
// it is not allowed to pass messages while other messages are processed
|
||||
require(messageId() == bytes32(0));
|
||||
|
||||
// if other is not explicitly configured
|
||||
require(messageId() == bytes32(0) || allowReentrantRequests());
|
||||
require(_gas >= getMinimumGasUsage(_data) && _gas <= maxGasPerTx());
|
||||
|
||||
bytes32 _messageId;
|
||||
|
|
|
@ -736,6 +736,33 @@ contract('ForeignAMB', async accounts => {
|
|||
// means that call to requireToPassMessage inside MessageProcessor reverted, since messageId flag was set up
|
||||
expect(await foreignBridge.messageCallStatus(messageId)).to.be.equal(false)
|
||||
})
|
||||
it('should allow to pass message back through the bridge if configured', async () => {
|
||||
const user = accounts[8]
|
||||
await foreignBridge.setAllowReentrantRequests(true, { from: user }).should.be.rejected
|
||||
await foreignBridge.setAllowReentrantRequests(true, { from: owner }).should.be.fulfilled
|
||||
expect(await foreignBridge.allowReentrantRequests()).to.be.equal(true)
|
||||
|
||||
const data = await foreignBridge.contract.methods
|
||||
.requireToPassMessage(box.address, setValueData, 100000)
|
||||
.encodeABI()
|
||||
// Use these calls to simulate home bridge on home network
|
||||
const resultPassMessageTx = await homeBridge.requireToPassMessage(foreignBridge.address, data, 821254, {
|
||||
from: user
|
||||
})
|
||||
|
||||
const { encodedData: message, messageId } = resultPassMessageTx.logs[0].args
|
||||
|
||||
const signature = await sign(authorities[0], message)
|
||||
const vrs = signatureToVRS(signature)
|
||||
const signatures = packSignatures([vrs])
|
||||
|
||||
await foreignBridge.executeSignatures(message, signatures, {
|
||||
from: authorities[0],
|
||||
gasPrice
|
||||
}).should.be.fulfilled
|
||||
|
||||
expect(await foreignBridge.messageCallStatus(messageId)).to.be.equal(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('gasToken functionality', async () => {
|
||||
|
|
|
@ -666,6 +666,27 @@ contract('HomeAMB', async accounts => {
|
|||
// means that call to requireToPassMessage inside MessageProcessor reverted, since messageId flag was set up
|
||||
expect(await homeBridge.messageCallStatus(messageId)).to.be.equal(false)
|
||||
})
|
||||
it('should allow to pass message back through the bridge if configured', async () => {
|
||||
const user = accounts[8]
|
||||
await homeBridge.setAllowReentrantRequests(true, { from: user }).should.be.rejected
|
||||
await homeBridge.setAllowReentrantRequests(true, { from: owner }).should.be.fulfilled
|
||||
expect(await homeBridge.allowReentrantRequests()).to.be.equal(true)
|
||||
|
||||
const data = await homeBridge.contract.methods.requireToPassMessage(box.address, setValueData, 100000).encodeABI()
|
||||
// Use these calls to simulate home bridge on home network
|
||||
const resultPassMessageTx = await foreignBridge.requireToPassMessage(homeBridge.address, data, 821254, {
|
||||
from: user
|
||||
})
|
||||
|
||||
const { encodedData: message, messageId } = resultPassMessageTx.logs[0].args
|
||||
|
||||
await homeBridge.executeAffirmation(message, {
|
||||
from: authorities[0],
|
||||
gasPrice
|
||||
}).should.be.fulfilled
|
||||
|
||||
expect(await homeBridge.messageCallStatus(messageId)).to.be.equal(true)
|
||||
})
|
||||
})
|
||||
describe('submitSignature', () => {
|
||||
let homeBridge
|
||||
|
|
Loading…
Reference in New Issue