diff --git a/contracts/evm/contracts/xcall/CallService.sol b/contracts/evm/contracts/xcall/CallService.sol index e4699b18..239c0c8f 100644 --- a/contracts/evm/contracts/xcall/CallService.sol +++ b/contracts/evm/contracts/xcall/CallService.sol @@ -51,6 +51,8 @@ contract CallService is IBSH, ICallService, IFeeManage, Initializable { mapping(uint256 => mapping(string => bool)) private pendingResponses; mapping(string => address) private defaultConnections; + bytes private callReply; + Types.ProxyRequest private replyState; address private owner; address private adminAddress; @@ -125,8 +127,6 @@ contract CallService is IBSH, ICallService, IFeeManage, Initializable { return _sendCallMessage(_to, _data, _rollback, src, dst); } - - function sendCall( string memory _to, bytes memory _data @@ -157,16 +157,21 @@ contract CallService is IBSH, ICallService, IFeeManage, Initializable { bytes memory _msg = req.encodeCSMessageRequest(); require(_msg.length <= MAX_DATA_SIZE, "MaxDataSizeExceeded"); - uint256 sendSn = result.needResponse ? sn : 0; + if (isReply(netTo, envelope.sources) && !result.needResponse) { + delete replyState; + callReply = _msg; + } else { + uint256 sendSn = result.needResponse ? sn : 0; - sendMessage( - envelope.sources, - netTo, - Types.CS_REQUEST, - int(sendSn), - _msg - ); - claimProtocolFee(); + sendMessage( + envelope.sources, + netTo, + Types.CS_REQUEST, + int(sendSn), + _msg + ); + claimProtocolFee(); + } emit CallMessageSent(caller, _to, sn); return sn; } @@ -187,14 +192,7 @@ contract CallService is IBSH, ICallService, IFeeManage, Initializable { for (uint i = 0; i < sources.length; i++) { address conn = sources[i].parseAddress("IllegalArgument"); uint256 requiredFee = _getFee(conn, netTo, sn); - sendToConnection( - conn, - requiredFee, - netTo, - msgType, - sn, - data - ); + sendToConnection(conn, requiredFee, netTo, msgType, sn, data); } } } @@ -245,28 +243,23 @@ contract CallService is IBSH, ICallService, IFeeManage, Initializable { Types.XCallEnvelope memory envelope; if (_rollback.length == 0) { - Types.CallMessage memory _msg = Types.CallMessage(_data); envelope = Types.XCallEnvelope( - Types.CALL_MESSAGE_TYPE, - _msg.data, - sources, - destinations - ); - } else { - - Types.CallMessageWithRollback memory _msg = Types.CallMessageWithRollback( - _data, - _rollback + Types.CALL_MESSAGE_TYPE, + _msg.data, + sources, + destinations ); + } else { + Types.CallMessageWithRollback memory _msg = Types + .CallMessageWithRollback(_data, _rollback); envelope = Types.XCallEnvelope( - Types.CALL_MESSAGE_ROLLBACK_TYPE, - _msg.encodeCallMessageWithRollback(), - sources, - destinations - ); - + Types.CALL_MESSAGE_ROLLBACK_TYPE, + _msg.encodeCallMessageWithRollback(), + sources, + destinations + ); } return sendCall(_to, envelope.encodeXCallEnvelope()); @@ -290,20 +283,34 @@ contract CallService is IBSH, ICallService, IFeeManage, Initializable { else if ( req.messageType == Types.CALL_MESSAGE_ROLLBACK_TYPE ) { - int256 code = tryExecuteCall(_reqId, req.to, req.from, _data, protocols); + replyState = req; + int256 code = tryExecuteCall( + _reqId, + req.to, + req.from, + _data, + protocols + ); + delete replyState; + bytes memory message; + if (callReply.length > 0 && code == Types.CS_RESP_SUCCESS) { + message = callReply; + delete callReply; + } Types.CSMessageResult memory response = Types.CSMessageResult( req.sn, - code + code, + message ); sendMessage( protocols, req.from.nid(), Types.CS_RESULT, - int256(req.sn)*-1, + int256(req.sn) * -1, response.encodeCSMessageResult() - ); + ); } else { revert("Message type is not yet supported"); } @@ -411,7 +418,10 @@ contract CallService is IBSH, ICallService, IFeeManage, Initializable { } function handleError(uint256 _sn) public override { - handleResult(Types.CSMessageResult(_sn, Types.CS_RESP_FAILURE)); + handleResult( + Types.CSMessageResult(_sn, Types.CS_RESP_FAILURE, bytes("")) + ); + } function sendToConnection( @@ -436,8 +446,8 @@ contract CallService is IBSH, ICallService, IFeeManage, Initializable { ) internal { Types.CSMessageRequest memory req = msgPayload.decodeCSMessageRequest(); string memory fromNID = req.from.nid(); - require(netFrom.compareTo(fromNID),"Invalid NID"); - + require(netFrom.compareTo(fromNID), "Invalid NID"); + bytes32 dataHash = keccak256(req.data); if (req.protocols.length > 1) { pendingReqs[dataHash][msg.sender.toString()] = true; @@ -450,7 +460,10 @@ contract CallService is IBSH, ICallService, IFeeManage, Initializable { delete pendingReqs[dataHash][req.protocols[i]]; } } else if (req.protocols.length == 1) { - require(msg.sender == req.protocols[0].parseAddress("IllegalArgument"), "NotAuthorized"); + require( + msg.sender == req.protocols[0].parseAddress("IllegalArgument"), + "NotAuthorized" + ); } else { require(msg.sender == defaultConnections[fromNID], "NotAuthorized"); } @@ -468,40 +481,71 @@ contract CallService is IBSH, ICallService, IFeeManage, Initializable { emit CallMessage(req.from, req.to, req.sn, reqId, req.data); } - function handleResult(Types.CSMessageResult memory res) internal { - Types.RollbackData memory req = rollbacks[res.sn]; + function handleReply( + Types.RollbackData memory rollback, + Types.CSMessageRequest memory reply + ) internal { + require( + keccak256(bytes(rollback.to)) == + keccak256(bytes(reply.from.nid())), + "Invalid Reply" + ); + + uint256 reqId = getNextReqId(); - require(req.from != address(0), "CallRequestNotFound"); + emit CallMessage(reply.from, reply.to, reply.sn, reqId, reply.data); - if (req.sources.length > 1) { + proxyReqs[reqId] = Types.ProxyRequest( + reply.from, + reply.to, + reply.sn, + reply.messageType, + keccak256(reply.data), + rollback.sources + ); + } + + function handleResult(Types.CSMessageResult memory res) internal { + Types.RollbackData memory rollback = rollbacks[res.sn]; + require(rollback.from != address(0), "CallRequestNotFound"); + + if (rollback.sources.length > 1) { pendingResponses[res.sn][msg.sender.toString()] = true; - for (uint i = 0; i < req.sources.length; i++) { - if (!pendingResponses[res.sn][req.sources[i]]) { + for (uint i = 0; i < rollback.sources.length; i++) { + if (!pendingResponses[res.sn][rollback.sources[i]]) { return; } } - for (uint i = 0; i < req.sources.length; i++) { - delete pendingResponses[res.sn][req.sources[i]]; + for (uint i = 0; i < rollback.sources.length; i++) { + delete pendingResponses[res.sn][rollback.sources[i]]; } - } else if (req.sources.length == 1) { + } else if (rollback.sources.length == 1) { require( - msg.sender == req.sources[0].parseAddress("IllegalArgument"), + msg.sender == + rollback.sources[0].parseAddress("IllegalArgument"), "NotAuthorized" ); } else { - require(msg.sender == defaultConnections[req.to], "NotAuthorized"); + require( + msg.sender == defaultConnections[rollback.to], + "NotAuthorized" + ); } emit ResponseMessage(res.sn, res.code); if (res.code == Types.CS_RESP_SUCCESS) { cleanupCallRequest(res.sn); + if (res.message.length > 0) { + handleReply(rollback, res.message.decodeCSMessageRequest()); + } successfulResponses[res.sn] = true; } else { //emit rollback event - require(req.rollback.length > 0, "NoRollbackData"); - req.enabled = true; - rollbacks[res.sn] = req; + require(rollback.rollback.length > 0, "NoRollbackData"); + rollback.enabled = true; + rollbacks[res.sn] = rollback; + emit RollbackMessage(res.sn); } } @@ -592,6 +636,9 @@ contract CallService is IBSH, ICallService, IFeeManage, Initializable { string[] memory _sources ) external view override returns (uint256) { uint256 fee = protocolFee; + if (isReply(_net, _sources) && !_rollback) { + return fee; + } for (uint i = 0; i < _sources.length; i++) { address conn = _sources[i].parseAddress("IllegalArgument"); fee = fee + _getFee(conn, _net, _rollback); @@ -600,6 +647,36 @@ contract CallService is IBSH, ICallService, IFeeManage, Initializable { return fee; } + function isReply( + string memory _net, + string[] memory _sources + ) internal view returns (bool) { + if (keccak256(bytes(replyState.from)) != keccak256(bytes(""))) { + return + keccak256(bytes(replyState.from.nid())) == + keccak256(bytes(_net)) && + areArraysEqual(replyState.protocols, _sources); + } + return false; + } + + function areArraysEqual( + string[] memory array1, + string[] memory array2 + ) internal pure returns (bool) { + if (array1.length != array2.length) { + return false; + } + + for (uint256 i = 0; i < array1.length; i++) { + if (keccak256(bytes(array1[i])) != keccak256(bytes(array2[i]))) { + return false; + } + } + + return true; + } + function verifySuccess(uint256 _sn) external view returns (bool) { return successfulResponses[_sn]; } diff --git a/contracts/evm/library/btp2/interfaces/ICallService.sol b/contracts/evm/library/btp2/interfaces/ICallService.sol index a950073e..f8cd86ab 100644 --- a/contracts/evm/library/btp2/interfaces/ICallService.sol +++ b/contracts/evm/library/btp2/interfaces/ICallService.sol @@ -2,15 +2,9 @@ pragma solidity >=0.8.0; interface ICallService { - function getNetworkAddress( - ) external view returns ( - string memory - ); + function getNetworkAddress() external view returns (string memory); - function getNetworkId( - ) external view returns ( - string memory - ); + function getNetworkId() external view returns (string memory); /** @notice Gets the fee for delivering a message to the _net. @@ -23,17 +17,13 @@ interface ICallService { function getFee( string memory _net, bool _rollback - ) external view returns ( - uint256 - ); + ) external view returns (uint256); function getFee( string memory _net, bool _rollback, string[] memory _sources - ) external view returns ( - uint256 - ); + ) external view returns (uint256); /*======== At the source CALL_BSH ========*/ /** @@ -47,9 +37,7 @@ interface ICallService { string memory _to, bytes memory _data, bytes memory _rollback - ) external payable returns ( - uint256 - ); + ) external payable returns (uint256); function sendCallMessage( string memory _to, @@ -57,9 +45,12 @@ interface ICallService { bytes memory _rollback, string[] memory sources, string[] memory destinations - ) external payable returns ( - uint256 - ); + ) external payable returns (uint256); + + function sendCall( + string memory _to, + bytes memory _data + ) external payable returns (uint256); /** @notice Notifies that the requested call message has been sent. @@ -79,34 +70,25 @@ interface ICallService { @param _code The execution result code (0: Success, -1: Unknown generic failure, >=1: User defined error code) */ - event ResponseMessage( - uint256 indexed _sn, - int _code - ); + event ResponseMessage(uint256 indexed _sn, int _code); /** @notice Notifies the user that a rollback operation is required for the request '_sn'. @param _sn The serial number of the previous request */ - event RollbackMessage( - uint256 indexed _sn - ); + event RollbackMessage(uint256 indexed _sn); /** @notice Rollbacks the caller state of the request '_sn'. @param _sn The serial number of the previous request */ - function executeRollback( - uint256 _sn - ) external; + function executeRollback(uint256 _sn) external; /** @notice Notifies that the rollback has been executed. @param _sn The serial number for the rollback */ - event RollbackExecuted( - uint256 indexed _sn - ); + event RollbackExecuted(uint256 indexed _sn); /*======== At the destination CALL_BSH ========*/ /** @@ -130,10 +112,7 @@ interface ICallService { @param _reqId The request id @param _data The calldata */ - function executeCall( - uint256 _reqId, - bytes memory _data - ) external; + function executeCall(uint256 _reqId, bytes memory _data) external; /** @notice Notifies that the call message has been executed. @@ -142,28 +121,18 @@ interface ICallService { (0: Success, -1: Unknown generic failure) @param _msg The result message if any */ - event CallExecuted( - uint256 indexed _reqId, - int _code, - string _msg - ); + event CallExecuted(uint256 indexed _reqId, int _code, string _msg); - /** + /** @notice BTP Message from other blockchain. @param _from Network Address of source network @param _msg Serialized bytes of ServiceMessage */ - function handleMessage( - string calldata _from, - bytes calldata _msg - ) external; + function handleMessage(string calldata _from, bytes calldata _msg) external; /** @notice Handle the error on delivering the message. @param _sn Serial number of the original message */ - function handleError( - uint256 _sn - ) external; + function handleError(uint256 _sn) external; } - diff --git a/contracts/evm/library/utils/RLPDecodeStruct.sol b/contracts/evm/library/utils/RLPDecodeStruct.sol index 06b6ee65..57a9ccd9 100644 --- a/contracts/evm/library/utils/RLPDecodeStruct.sol +++ b/contracts/evm/library/utils/RLPDecodeStruct.sol @@ -82,6 +82,6 @@ library RLPDecodeStruct { bytes memory _rlp ) internal pure returns (Types.CSMessageResult memory) { RLPDecode.RLPItem[] memory ls = _rlp.toRlpItem().toList(); - return Types.CSMessageResult(ls[0].toUint(), int(ls[1].toInt())); + return Types.CSMessageResult(ls[0].toUint(), ls[1].toInt(), ls[2].toBytes()); } } diff --git a/contracts/evm/library/utils/RLPEncodeStruct.sol b/contracts/evm/library/utils/RLPEncodeStruct.sol index a2fd43fe..6a53e28c 100644 --- a/contracts/evm/library/utils/RLPEncodeStruct.sol +++ b/contracts/evm/library/utils/RLPEncodeStruct.sol @@ -80,7 +80,8 @@ library RLPEncodeStruct { ) internal pure returns (bytes memory) { bytes memory _rlp = abi.encodePacked( _bs.sn.encodeUint(), - _bs.code.encodeInt() + _bs.code.encodeInt(), + _bs.message.encodeBytes() ); return _rlp.encodeList(); } diff --git a/contracts/evm/library/utils/Types.sol b/contracts/evm/library/utils/Types.sol index 7ecc4dd7..18fb4d35 100644 --- a/contracts/evm/library/utils/Types.sol +++ b/contracts/evm/library/utils/Types.sol @@ -52,6 +52,7 @@ library Types { struct CSMessageResult { uint256 sn; int code; + bytes message; } struct PendingResponse { diff --git a/contracts/evm/test/xcall/CallService.t.sol b/contracts/evm/test/xcall/CallService.t.sol index f0d683ad..e699bfce 100644 --- a/contracts/evm/test/xcall/CallService.t.sol +++ b/contracts/evm/test/xcall/CallService.t.sol @@ -17,10 +17,19 @@ import "@iconfoundation/btp2-solidity-library/interfaces/IDefaultCallServiceRece import "@iconfoundation/btp2-solidity-library/interfaces/ICallService.sol"; +contract ResponseContract { + string public to; + bytes public data; + + function handleCallMessage(string memory _from, bytes memory _data, string[] memory protocols) public { + ICallService(msg.sender).sendCall(to, data); + } +} contract CallServiceTest is Test { CallService public callService; DAppProxySample public dapp; + ResponseContract public responseContract; IConnection public baseConnection; IConnection public connection1; @@ -106,6 +115,7 @@ contract CallServiceTest is Test { callService = new CallService(); callService.initialize(ethNid); + responseContract = new ResponseContract(); } function testSetAdmin() public { @@ -200,6 +210,50 @@ contract CallServiceTest is Test { assertEq(sn, 1); } + function testHandleReply() public { + bytes memory data = bytes("test"); + + callService.setDefaultConnection(iconNid, address(baseConnection)); + + vm.expectEmit(); + emit CallMessageSent(address(dapp), iconDapp, 1); + + Types.CSMessageRequest memory request = Types.CSMessageRequest(iconDapp, address(dapp).toString(), 1, 2, data, _baseSource); + Types.CSMessageResult memory result = Types.CSMessageResult(1, Types.CS_RESP_SUCCESS,request.encodeCSMessageRequest()); + Types.CSMessage memory message = Types.CSMessage(Types.CS_RESULT,result.encodeCSMessageResult()); + + vm.prank(address(dapp)); + uint256 sn = callService.sendCallMessage{value: 0 ether}(iconDapp, data, data, _baseSource, _baseDestination); + assertEq(sn, 1); + + vm.expectEmit(); + emit ResponseMessage(1, Types.CS_RESP_SUCCESS); + emit CallMessage(iconDapp, address(dapp).toString(), 1, 1, data); + vm.prank(address(baseConnection)); + callService.handleMessage(iconNid, RLPEncodeStruct.encodeCSMessage(message)); + } + + function testHandleReplyInvalidTo() public { + bytes memory data = bytes("test"); + + callService.setDefaultConnection(iconNid, address(baseConnection)); + + vm.expectEmit(); + emit CallMessageSent(address(dapp), iconDapp, 1); + + Types.CSMessageRequest memory request = Types.CSMessageRequest("otherNid/0x1", address(dapp).toString(), 1, 2, data, _baseSource); + Types.CSMessageResult memory result = Types.CSMessageResult(1, Types.CS_RESP_SUCCESS,request.encodeCSMessageRequest()); + Types.CSMessage memory message = Types.CSMessage(Types.CS_RESULT,result.encodeCSMessageResult()); + + vm.prank(address(dapp)); + uint256 sn = callService.sendCallMessage{value: 0 ether}(iconDapp, data, data, _baseSource, _baseDestination); + assertEq(sn, 1); + + vm.expectRevert("Invalid Reply"); + vm.prank(address(baseConnection)); + callService.handleMessage(iconNid, RLPEncodeStruct.encodeCSMessage(message)); + } + function testSendMessageDefaultProtocol() public { bytes memory data = bytes("test"); bytes memory rollbackData = bytes("rollback"); @@ -406,24 +460,7 @@ contract CallServiceTest is Test { vm.mockCall(address(defaultServiceReceiver), abi.encodeWithSelector(defaultServiceReceiver.handleCallMessage.selector, iconDapp, data), abi.encode(1)); callService.executeCall(1, data); } - - function testExecuteCallPersistent_failedExecution() public { - bytes memory data = bytes("test"); - - defaultServiceReceiver = IDefaultCallServiceReceiver(address(0x5678)); - callService.setDefaultConnection(netTo, address(baseConnection)); - - Types.CSMessageRequest memory request = Types.CSMessageRequest(iconDapp, ParseAddress.toString(address(defaultServiceReceiver)), 1, Types.PERSISTENT_MESSAGE_TYPE, data, _baseSource); - Types.CSMessage memory message = Types.CSMessage(Types.CS_REQUEST,request.encodeCSMessageRequest()); - - vm.prank(address(baseConnection)); - callService.handleMessage(iconNid, RLPEncodeStruct.encodeCSMessage(message)); - - vm.expectRevert(); - vm.prank(user); - callService.executeCall(1, data); - } - + function testExecuteCallPersistent() public { bytes memory data = bytes("test"); @@ -446,7 +483,6 @@ contract CallServiceTest is Test { callService.executeCall(1, data); } - function testExecuteCallMultiProtocol() public { bytes memory data = bytes("test"); @@ -489,7 +525,7 @@ contract CallServiceTest is Test { uint256 sn = callService.sendCallMessage{value: 0 ether}(iconDapp, data, rollbackData, _baseSource, _baseDestination); assertEq(sn, 1); - Types.CSMessageResult memory response = Types.CSMessageResult(1, Types.CS_RESP_FAILURE); + Types.CSMessageResult memory response = Types.CSMessageResult(1, Types.CS_RESP_FAILURE,bytes("")); Types.CSMessage memory message = Types.CSMessage(Types.CS_RESULT, RLPEncodeStruct.encodeCSMessageResult(response)); vm.expectEmit(); @@ -515,7 +551,7 @@ contract CallServiceTest is Test { uint256 sn = callService.sendCallMessage{value: 0 ether}(iconDapp, data, rollbackData, _baseSource, _baseDestination); assertEq(sn, 1); - Types.CSMessageResult memory response = Types.CSMessageResult(1, Types.CS_RESP_FAILURE); + Types.CSMessageResult memory response = Types.CSMessageResult(1, Types.CS_RESP_FAILURE,bytes("")); Types.CSMessage memory message = Types.CSMessage(Types.CS_RESULT, RLPEncodeStruct.encodeCSMessageResult(response)); vm.expectEmit(); @@ -540,7 +576,7 @@ contract CallServiceTest is Test { uint256 sn = callService.sendCallMessage{value: 0 ether}(iconDapp, data, rollbackData, _baseSource, _baseDestination); assertEq(sn, 1); - Types.CSMessageResult memory response = Types.CSMessageResult(1, Types.CS_RESP_FAILURE); + Types.CSMessageResult memory response = Types.CSMessageResult(1, Types.CS_RESP_FAILURE,bytes("")); Types.CSMessage memory message = Types.CSMessage(Types.CS_RESULT, RLPEncodeStruct.encodeCSMessageResult(response)); vm.prank(address(user)); @@ -575,7 +611,7 @@ contract CallServiceTest is Test { uint256 sn = callService.sendCallMessage{value: 0 ether}(iconDapp, data, rollbackData, connections, destinations); assertEq(sn, 1); - Types.CSMessageResult memory response = Types.CSMessageResult(1, Types.CS_RESP_FAILURE); + Types.CSMessageResult memory response = Types.CSMessageResult(1, Types.CS_RESP_FAILURE,bytes("")); Types.CSMessage memory message = Types.CSMessage(Types.CS_RESULT, RLPEncodeStruct.encodeCSMessageResult(response)); vm.prank(address(connection1)); @@ -601,7 +637,7 @@ contract CallServiceTest is Test { uint256 sn = callService.sendCallMessage{value: 0 ether}(iconDapp, data, rollbackData, _baseSource, _baseDestination); assertEq(sn, 1); - Types.CSMessageResult memory response = Types.CSMessageResult(1, Types.CS_RESP_SUCCESS); + Types.CSMessageResult memory response = Types.CSMessageResult(1, Types.CS_RESP_SUCCESS,bytes("")); Types.CSMessage memory message = Types.CSMessage(Types.CS_RESULT, RLPEncodeStruct.encodeCSMessageResult(response)); vm.expectEmit(); @@ -631,7 +667,7 @@ contract CallServiceTest is Test { assertEq(sn, 1); vm.stopPrank(); - Types.CSMessageResult memory msgRes = Types.CSMessageResult(1, Types.CS_RESP_FAILURE); + Types.CSMessageResult memory msgRes = Types.CSMessageResult(1, Types.CS_RESP_FAILURE,bytes("")); Types.CSMessage memory message = Types.CSMessage(Types.CS_RESULT, msgRes.encodeCSMessageResult()); vm.prank(address(baseConnection)); @@ -660,7 +696,7 @@ contract CallServiceTest is Test { uint256 sn = callService.sendCallMessage{value: 0 ether}(iconDapp, data, rollbackData, _baseSource, _baseDestination); assertEq(sn, 1); - Types.CSMessageResult memory msgRes = Types.CSMessageResult(1, Types.CS_RESP_FAILURE); + Types.CSMessageResult memory msgRes = Types.CSMessageResult(1, Types.CS_RESP_FAILURE,bytes("")); Types.CSMessage memory message = Types.CSMessage(Types.CS_RESULT, msgRes.encodeCSMessageResult()); vm.prank(address(baseConnection)); @@ -703,7 +739,7 @@ contract CallServiceTest is Test { uint256 sn = callService.sendCallMessage{value: 0 ether}(iconDapp, data, rollbackData, connections, destinations); assertEq(sn, 1); - Types.CSMessageResult memory response = Types.CSMessageResult(1, Types.CS_RESP_FAILURE); + Types.CSMessageResult memory response = Types.CSMessageResult(1, Types.CS_RESP_FAILURE,bytes("")); Types.CSMessage memory message = Types.CSMessage(Types.CS_RESULT, RLPEncodeStruct.encodeCSMessageResult(response)); vm.prank(address(connection1)); @@ -752,7 +788,7 @@ contract CallServiceTest is Test { vm.prank(user); vm.mockCall(address(receiver), abi.encodeWithSelector(receiver.handleCallMessage.selector, iconDapp, data, connections), abi.encode(1)); - Types.CSMessageResult memory msgResponse = Types.CSMessageResult(1, Types.CS_RESP_SUCCESS); + Types.CSMessageResult memory msgResponse = Types.CSMessageResult(1, Types.CS_RESP_SUCCESS,bytes("")); message = Types.CSMessage(Types.CS_RESULT, RLPEncodeStruct.encodeCSMessageResult(msgResponse)); vm.expectCall(address(connection1), abi.encodeCall(connection1.sendMessage, (iconNid, Types.NAME, -1, message.encodeCSMessage()))); @@ -779,7 +815,7 @@ contract CallServiceTest is Test { vm.prank(user); vm.mockCall(address(defaultServiceReceiver), abi.encodeWithSelector(defaultServiceReceiver.handleCallMessage.selector, iconDapp, data), abi.encode(0)); - Types.CSMessageResult memory msgResponse = Types.CSMessageResult(1, Types.CS_RESP_SUCCESS); + Types.CSMessageResult memory msgResponse = Types.CSMessageResult(1, Types.CS_RESP_SUCCESS,bytes("")); message = Types.CSMessage(Types.CS_RESULT, RLPEncodeStruct.encodeCSMessageResult(msgResponse)); vm.expectCall(address(baseConnection), abi.encodeCall(baseConnection.sendMessage, (iconNid, Types.NAME, -1, message.encodeCSMessage()))); callService.executeCall(1, data); @@ -796,7 +832,7 @@ contract CallServiceTest is Test { vm.mockCallRevert(address(baseConnection), abi.encodeWithSelector(receiver.handleCallMessage.selector, iconDapp, data, _baseSource), bytes("UserRevert")); callService.handleMessage(iconNid, RLPEncodeStruct.encodeCSMessage(message)); - Types.CSMessageResult memory msgResponse = Types.CSMessageResult(1, Types.CS_RESP_FAILURE); + Types.CSMessageResult memory msgResponse = Types.CSMessageResult(1, Types.CS_RESP_FAILURE, bytes("")); message = Types.CSMessage(Types.CS_RESULT, RLPEncodeStruct.encodeCSMessageResult(msgResponse)); vm.expectEmit();