Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
36 changed files
with
2,654 additions
and
177 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
pragma solidity 0.4.24; | ||
|
||
import "../interfaces/IBridgeValidators.sol"; | ||
import "./Message.sol"; | ||
|
||
library ArbitraryMessage { | ||
// layout of message :: bytes: | ||
// offset 0: 32 bytes :: uint256 - message length | ||
// offset 32: 32 bytes :: bytes32 txHash | ||
// offset 52: 20 bytes :: address - sender address | ||
// offset 72: 20 bytes :: address - executor contract | ||
// offset 104: 32 bytes :: uint256 - gasLimit | ||
// offset 136: 1 bytes :: bytes1 - dataType | ||
// (optional) 137: 32 bytes :: uint256 - gasPrice | ||
// (optional) 137: 1 bytes :: bytes1 - gasPriceSpeed | ||
|
||
// bytes 1 to 32 are 0 because message length is stored as little endian. | ||
// mload always reads 32 bytes. | ||
// so we can and have to start reading recipient at offset 20 instead of 32. | ||
// if we were to read at 32 the address would contain part of value and be corrupted. | ||
// when reading from offset 20 mload will read 12 zero bytes followed | ||
// by the 20 recipient address bytes and correctly convert it into an address. | ||
// this saves some storage/gas over the alternative solution | ||
// which is padding address to 32 bytes and reading recipient at offset 32. | ||
// for more details see discussion in: | ||
// https://github.com/paritytech/parity-bridge/issues/61 | ||
|
||
function unpackData(bytes _data, bool applyDataOffset) | ||
internal | ||
pure | ||
returns ( | ||
address sender, | ||
address executor, | ||
bytes32 txHash, | ||
uint256 gasLimit, | ||
bytes1 dataType, | ||
uint256 gasPrice, | ||
bytes memory data | ||
) | ||
{ | ||
uint256 dataOffset = 0; | ||
uint256 datasize; | ||
// 32 (tx hash) + 20 (sender) + 20 (executor) + 32 (gasLimit) + 1 (dataType) | ||
uint256 srcdataptr = 32 + 20 + 20 + 32 + 1; | ||
assembly { | ||
txHash := mload(add(_data, 32)) | ||
sender := mload(add(_data, 52)) | ||
executor := mload(add(_data, 72)) | ||
gasLimit := mload(add(_data, 104)) | ||
dataType := and(mload(add(_data, 136)), 0xFF00000000000000000000000000000000000000000000000000000000000000) | ||
switch dataType | ||
case 0x0000000000000000000000000000000000000000000000000000000000000000 { | ||
gasPrice := 0 | ||
} | ||
case 0x0100000000000000000000000000000000000000000000000000000000000000 { | ||
gasPrice := mload(add(_data, 137)) // 32 | ||
srcdataptr := add(srcdataptr, 0x20) | ||
} | ||
case 0x0200000000000000000000000000000000000000000000000000000000000000 { | ||
gasPrice := 0 | ||
srcdataptr := add(srcdataptr, 0x01) | ||
} | ||
datasize := sub(mload(_data), srcdataptr) | ||
} | ||
data = new bytes(datasize); | ||
assembly { | ||
// BYTES_HEADER_SIZE | ||
let dataptr := add(data, 32) | ||
if eq(applyDataOffset, 1) { | ||
dataOffset := 32 | ||
} | ||
// 68 = 4 (selector) + 32 (bytes header) + 32 (bytes length) | ||
calldatacopy(dataptr, add(add(68, srcdataptr), dataOffset), datasize) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
pragma solidity 0.4.24; | ||
|
||
import "./IAMB.sol"; | ||
|
||
contract Box { | ||
uint256 public value; | ||
address public lastSender; | ||
bytes32 public txHash; | ||
|
||
function setValue(uint256 _value) public { | ||
value = _value; | ||
lastSender = IAMB(msg.sender).messageSender(); | ||
txHash = IAMB(msg.sender).transactionHash(); | ||
} | ||
|
||
function methodWillFail() public { | ||
revert(); | ||
} | ||
|
||
function methodOutOfGas() public { | ||
uint256 a = 0; | ||
for (uint256 i = 0; i < 1000; i++) { | ||
a = a + i; | ||
} | ||
} | ||
|
||
function methodWillFailOnOtherNetwork(address _bridge, address _executor) public { | ||
bytes4 methodSelector = this.methodWillFail.selector; | ||
bytes memory encodedData = abi.encodeWithSelector(methodSelector); | ||
IAMB(_bridge).requireToPassMessage(_executor, encodedData, 141647); | ||
} | ||
|
||
function methodOutOfGasOnOtherNetwork(address _bridge, address _executor) public { | ||
bytes4 methodSelector = this.methodOutOfGas.selector; | ||
bytes memory encodedData = abi.encodeWithSelector(methodSelector); | ||
IAMB(_bridge).requireToPassMessage(_executor, encodedData, 1000); | ||
} | ||
|
||
function setValueOnOtherNetwork(uint256 _i, address _bridge, address _executor) public { | ||
bytes4 methodSelector = this.setValue.selector; | ||
bytes memory encodedData = abi.encodeWithSelector(methodSelector, _i); | ||
IAMB(_bridge).requireToPassMessage(_executor, encodedData, 141647); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
pragma solidity 0.4.24; | ||
|
||
interface IAMB { | ||
function messageSender() external view returns (address); | ||
function transactionHash() external view returns (bytes32); | ||
function withdrawFromDeposit(address _recipient) external; | ||
function requireToPassMessage(address _contract, bytes _data, uint256 _gas) public; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
pragma solidity 0.4.24; | ||
|
||
import "../libraries/ArbitraryMessage.sol"; | ||
|
||
contract MessageTest { | ||
function unpackData(bytes _data) | ||
public | ||
pure | ||
returns ( | ||
address sender, | ||
address executor, | ||
bytes32 txHash, | ||
uint256 gasLimit, | ||
bytes1 dataType, | ||
uint256 gasPrice, | ||
bytes memory data | ||
) | ||
{ | ||
(sender, executor, txHash, gasLimit, dataType, gasPrice, data) = ArbitraryMessage.unpackData(_data, false); | ||
} | ||
|
||
function unpackDataWithExtraParams( | ||
bytes _data, | ||
bytes /*signatures*/ | ||
) | ||
public | ||
pure | ||
returns ( | ||
address sender, | ||
address executor, | ||
bytes32 txHash, | ||
uint256 gasLimit, | ||
bytes1 dataType, | ||
uint256 gasPrice, | ||
bytes memory data | ||
) | ||
{ | ||
(sender, executor, txHash, gasLimit, dataType, gasPrice, data) = ArbitraryMessage.unpackData(_data, true); | ||
} | ||
|
||
} |
Oops, something went wrong.