Skip to content

Commit

Permalink
add UCH logging + new to/from UCHPacket encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
RnkSngh authored and nicopernas committed Mar 21, 2024
1 parent 7029199 commit c7f7df2
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 12 deletions.
3 changes: 3 additions & 0 deletions contracts/base/GeneralMiddleware.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ contract GeneralMiddleware is IbcMwUser, IbcMiddleware, IbcMwEventsEmitter {
*/
uint256 public MW_ID;

Check warning on line 25 in contracts/base/GeneralMiddleware.sol

View workflow job for this annotation

GitHub Actions / lint

Variable name must be in mixedCase

event UCHPacketSent(address source, bytes32 destination);
/**
* @param _middleware The middleware contract address this contract sends packets to and receives packets from.
*/

constructor(uint256 mwId, address _middleware) IbcMwUser(_middleware) {
MW_ID = mwId;
}
Expand All @@ -37,6 +39,7 @@ contract GeneralMiddleware is IbcMwUser, IbcMiddleware, IbcMwEventsEmitter {
bytes calldata appData,
uint64 timeoutTimestamp
) external override {
emit UCHPacketSent(msg.sender, destPortAddr);
_sendPacket(channelId, IbcUtils.toBytes32(msg.sender), destPortAddr, 0, appData, timeoutTimestamp);

Check warning on line 43 in contracts/base/GeneralMiddleware.sol

View workflow job for this annotation

GitHub Actions / lint

Named parameters missing. MIN unnamed argumenst is 4
}

Expand Down
3 changes: 3 additions & 0 deletions contracts/core/UniversalChannelHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ contract UniversalChannelHandler is IbcReceiverBase, IbcUniversalChannelMW {
// Key: middleware bitmap, Value: middleware address from receiver(chain B)'s perspective
mapping(uint256 => address[]) public mwStackAddrs;

event UCHPacketSent(address source, bytes32 destination);

constructor(IbcDispatcher _dispatcher) IbcReceiverBase(_dispatcher) {}
/**
* @dev Close a universal channel.
Expand Down Expand Up @@ -55,6 +57,7 @@ contract UniversalChannelHandler is IbcReceiverBase, IbcUniversalChannelMW {
bytes memory packetData = IbcUtils.toUniversalPacketBytes(
UniversalPacket(IbcUtils.toBytes32(msg.sender), MW_ID, destPortAddr, appData)
);
emit UCHPacketSent(msg.sender, destPortAddr);
dispatcher.sendPacket(channelId, packetData, timeoutTimestamp);
}

Expand Down
34 changes: 22 additions & 12 deletions contracts/libs/Ibc.sol
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,27 @@ library IBCErrors {
library IbcUtils {
error StringTooLong();

// fromUniversalPacketBytes converts UniversalPacketDataBytes to UniversalPacketData, per how its packed into bytes
function fromUniversalPacketBytes(bytes calldata data)
external
pure
returns (UniversalPacket memory universalPacketData)
{
bytes32 srcPortAddr;
uint256 mwBitmap;
bytes32 destPortAddr;
assembly {
// Keep reusing 0x0 to move from calldata to return vars
calldatacopy(0x0, data.offset, 32)
srcPortAddr := mload(0x0)
calldatacopy(0x0, add(data.offset, 32), 32)
mwBitmap := mload(0x0)
calldatacopy(0x0, add(data.offset, 64), 32)
destPortAddr := mload(0x0)
}
universalPacketData = UniversalPacket(srcPortAddr, uint256(mwBitmap), destPortAddr, data[96:data.length]);
}

/**
* Convert a non-0x-prefixed hex string to an address
* @param hexStr hex string to convert to address. Note that the hex string must not include a 0x prefix.
Expand Down Expand Up @@ -218,19 +239,8 @@ library IbcUtils {
}
}

// convert params to UniversalPacketBytes with optimal gas cost

function toUniversalPacketBytes(UniversalPacket memory data) internal pure returns (bytes memory packetBytes) {
packetBytes = abi.encode(data);
}

// fromUniversalPacketBytes converts UniversalPacketDataBytes to UniversalPacketData, per how its packed into bytes
function fromUniversalPacketBytes(bytes memory data)
internal
pure
returns (UniversalPacket memory universalPacketData)
{
universalPacketData = abi.decode(data, (UniversalPacket));
packetBytes = bytes.concat(data.srcPortAddr, bytes32(data.mwBitmap), data.destPortAddr, data.appData);
}

// addressToPortId converts an address to a port ID
Expand Down
29 changes: 29 additions & 0 deletions test/Ibc.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,33 @@ contract IbcTest is Test {
assertFalse(parsederr.success);
assertEq(bytes("this is an error message"), parsederr.data);
}

function assert_Equal_Before_and_After_Encoding(address a1, uint256 mwBitmap, address a2, bytes memory appData)
internal
{
bytes memory afterEncoding = IbcUtils.toUniversalPacketBytes(
UniversalPacket(IbcUtils.toBytes32(a1), mwBitmap, IbcUtils.toBytes32(a2), appData)
);

UniversalPacket memory afterDecoding = IbcUtils.fromUniversalPacketBytes(afterEncoding);
assertEq(a1, IbcUtils.toAddress(afterDecoding.srcPortAddr));
assertEq(mwBitmap, afterDecoding.mwBitmap);
assertEq(a2, IbcUtils.toAddress(afterDecoding.destPortAddr));
assertEq(appData, afterDecoding.appData);
}

function test_To_From_UniversalPacketBytes() public {
// Standard
assert_Equal_Before_and_After_Encoding(vm.addr(1), uint256(123), vm.addr(2), "helloooo decode this for me ");
// empty string
assert_Equal_Before_and_After_Encoding(vm.addr(1), uint256(123), vm.addr(2), ""); // empty string

// Really long string:
assert_Equal_Before_and_After_Encoding(
vm.addr(1),
uint256(123),
vm.addr(2),
"daf;lkdsajflkasjdv;lkjzdljga;lkgfjda;iocjvz;lkjval;dsjkf;alkdj;zlkjv;lkjaeg;ijafd;lkjzvc,mnb.kahgd;ajkfaj;dgoij;zlckjv;lzkjv;kaldfjg;alkjgf;lkzvjcx;lkvja;lkjg;aslgjdz;adf;kasjg;lkjwaea;lkjg;io1j;4kjrda;lkfjaleot8ywp89yz;dvhlsdkj"
);
}
}
10 changes: 10 additions & 0 deletions test/universal.channel.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {IbcEventsEmitter} from "../contracts/interfaces/IbcDispatcher.sol";
import {IbcReceiver} from "../contracts/interfaces/IbcReceiver.sol";
import "../contracts/core/UniversalChannelHandler.sol";
import "../contracts/examples/Mars.sol";
import "../contracts/interfaces/IbcMiddleware.sol";
import "../contracts/core/OpLightClient.sol";
import "./Dispatcher.base.t.sol";
import "./VirtualChain.sol";
Expand Down Expand Up @@ -91,6 +92,8 @@ struct UcPacket {
}

contract UniversalChannelPacketTest is Base, IbcMwEventsEmitter {
event UCHPacketSent(address source, bytes32 destination);

VirtualChain eth1;
VirtualChain eth2;
VirtualChainData v1;
Expand Down Expand Up @@ -239,6 +242,9 @@ contract UniversalChannelPacketTest is Base, IbcMwEventsEmitter {
IbcUtils.toBytes32(address(v1.earth)), mwBitmap, IbcUtils.toBytes32(address(v2.earth)), appData
);
packetData = IbcUtils.toUniversalPacketBytes(ucPacket);
// Verify event emitted by UCH
vm.expectEmit(true, true, true, true);
emit UCHPacketSent(address(v1.earth), IbcUtils.toBytes32(address(v2.earth)));

// iterate over sending middleware contracts to verify each MW has witnessed the packet
for (uint256 i = 0; i < senderMws.length; i++) {
Expand All @@ -258,6 +264,7 @@ contract UniversalChannelPacketTest is Base, IbcMwEventsEmitter {
// Verify event emitted by Dispatcher
vm.expectEmit(true, true, true, true);
emit SendPacket(address(v1.ucHandler), channelId1, packetData, packetSeq, timeout);

v1.earth.greet(address(v2.earth), channelId1, appData, timeout);

// simulate relayer calling dispatcherProxy.recvPacket on chain B
Expand Down Expand Up @@ -325,6 +332,8 @@ contract UniversalChannelPacketTest is Base, IbcMwEventsEmitter {
IbcUtils.toBytes32(address(v1.earth)), mwBitmap, IbcUtils.toBytes32(address(v2.earth)), appData
);
packetData = IbcUtils.toUniversalPacketBytes(ucPacket);
vm.expectEmit(true, true, true, true);
emit UCHPacketSent(address(v1.earth), IbcUtils.toBytes32(address(v2.earth)));

// iterate over sending middleware contracts to verify each MW has witnessed the packet
for (uint256 i = 0; i < senderMws.length; i++) {
Expand All @@ -341,6 +350,7 @@ contract UniversalChannelPacketTest is Base, IbcMwEventsEmitter {
);
}
}

// Verify event emitted by Dispatcher
vm.expectEmit(true, true, true, true);
emit SendPacket(address(v1.ucHandler), channelId1, packetData, packetSeq, timeout);
Expand Down

0 comments on commit c7f7df2

Please sign in to comment.