Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: response message solidity #234

Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e29e98b
feat: xcall upgradeable (#179)
gcranju Dec 15, 2023
d2995c1
fix: network address validation fixed (#212)
gcranju Dec 15, 2023
a0de612
fix: not authorized issue by making handleMessage public (#202)
gcranju Dec 15, 2023
7a8de78
ci: add job to update CHANGELOG.md (#207)
DeepakBomjan Dec 15, 2023
048a65a
fix: added rpsc in foundry.toml
gcranju Dec 22, 2023
3c33770
fix: fix env.example
gcranju Dec 22, 2023
1b64d8d
Merge pull request #221 from icon-project/deploy-script-fix
izyak Dec 22, 2023
9694787
fix: new message type added in solidity
gcranju Dec 27, 2023
5972a5c
Merge remote-tracking branch 'origin/main' into 182-solidity-implemen…
gcranju Dec 27, 2023
d703295
feat: add centralized connections in solidity and java (#196)
gcranju Dec 28, 2023
6729816
fix: unnecessary event log removed
gcranju Dec 29, 2023
b8dc3a8
fix: sendBTPMessage renamed to sendToConnection
gcranju Dec 29, 2023
d0d8f54
fix: unnecessary event log removed
gcranju Dec 29, 2023
99f68b6
feat: add centralized connections in solidity and java (#196)
gcranju Dec 28, 2023
dea884d
fix: centralized-connection test fixed
gcranju Dec 29, 2023
4206ef6
fix: proxy request structure with data hash added
gcranju Dec 29, 2023
396c2da
Merge branch 'main' into 182-solidity-implement-new-message-flow
gcranju Jan 3, 2024
239e025
fix: getFee method
gcranju Jan 4, 2024
c6a8f07
fix: message encoding decoding fixed
gcranju Jan 4, 2024
5beac56
fix: logs removed
gcranju Jan 4, 2024
c891144
feat: response message solidity
gcranju Jan 14, 2024
8e7676d
Merge branch 'development/177-xcall-future-proof-messaging' into feat…
gcranju Jan 15, 2024
a8c8495
fix: review changes
gcranju Jan 15, 2024
0ef234b
feat: tests added
gcranju Jan 15, 2024
d72a678
Merge branch 'development/177-xcall-future-proof-messaging' into feat…
gcranju Jan 18, 2024
5bb2a6c
fix merge issues
gcranju Jan 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
200 changes: 138 additions & 62 deletions contracts/evm/contracts/xcall/CallService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
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;
Expand Down Expand Up @@ -125,8 +127,6 @@
return _sendCallMessage(_to, _data, _rollback, src, dst);
}



function sendCall(
string memory _to,
bytes memory _data
Expand Down Expand Up @@ -157,16 +157,21 @@
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;

Check warning on line 162 in contracts/evm/contracts/xcall/CallService.sol

View check run for this annotation

Codecov / codecov/patch

contracts/evm/contracts/xcall/CallService.sol#L161-L162

Added lines #L161 - L162 were not covered by tests
} 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;
}
Expand All @@ -187,14 +192,7 @@
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);
}
}
}
Expand Down Expand Up @@ -245,28 +243,23 @@
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());
Expand All @@ -283,23 +276,36 @@

if (req.messageType == Types.CALL_MESSAGE_TYPE) {
tryExecuteCall(_reqId, req.to, req.from, _data, protocols);
} else if (
req.messageType == Types.CALL_MESSAGE_ROLLBACK_TYPE
) {
int256 code = tryExecuteCall(_reqId, req.to, req.from, _data, protocols);
} else if (req.messageType == Types.CALL_MESSAGE_ROLLBACK_TYPE) {
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;

Check warning on line 294 in contracts/evm/contracts/xcall/CallService.sol

View check run for this annotation

Codecov / codecov/patch

contracts/evm/contracts/xcall/CallService.sol#L293-L294

Added lines #L293 - L294 were not covered by tests
}
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");
}
Expand Down Expand Up @@ -397,7 +403,7 @@
if (csMsg.msgType == Types.CS_REQUEST) {
handleRequest(_from, csMsg.payload);
} else if (csMsg.msgType == Types.CS_RESULT) {
handlResult(csMsg.payload.decodeCSMessageResult());
handleResult(csMsg.payload.decodeCSMessageResult());
} else {
string memory errMsg = string("UnknownMsgType(")
.concat(uint(csMsg.msgType).toString())
Expand All @@ -407,7 +413,9 @@
}

function handleError(uint256 _sn) public override {
handlResult(Types.CSMessageResult(_sn, Types.CS_RESP_FAILURE));
handleResult(
Types.CSMessageResult(_sn, Types.CS_RESP_FAILURE, bytes(""))
);
}

function sendToConnection(
Expand All @@ -432,8 +440,8 @@
) 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;
Expand All @@ -446,7 +454,10 @@
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");
}
Expand All @@ -463,41 +474,73 @@
emit CallMessage(req.from, req.to, req.sn, reqId, req.data);
}

function handlResult(Types.CSMessageResult memory res) internal {
Types.RollbackData memory req = rollbacks[res.sn];
if (req.from == address(0)) {
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();

emit CallMessage(reply.from, reply.to, reply.sn, reqId, reply.data);

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];
if (rollback.from == address(0)) {
return;
}

if (req.sources.length > 1) {
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);
}
}
Expand Down Expand Up @@ -588,6 +631,9 @@
string[] memory _sources
) external view override returns (uint256) {
uint256 fee = protocolFee;
if (isReply(_net, _sources) && !_rollback) {
return fee;

Check warning on line 635 in contracts/evm/contracts/xcall/CallService.sol

View check run for this annotation

Codecov / codecov/patch

contracts/evm/contracts/xcall/CallService.sol#L634-L635

Added lines #L634 - L635 were not covered by tests
}
for (uint i = 0; i < _sources.length; i++) {
address conn = _sources[i].parseAddress("IllegalArgument");
fee = fee + _getFee(conn, _net, _rollback);
Expand All @@ -596,6 +642,36 @@
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);

Check warning on line 653 in contracts/evm/contracts/xcall/CallService.sol

View check run for this annotation

Codecov / codecov/patch

contracts/evm/contracts/xcall/CallService.sol#L650-L653

Added lines #L650 - L653 were not covered by tests
}
return false;
}

function areArraysEqual(
string[] memory array1,
string[] memory array2
) internal pure returns (bool) {
if (array1.length != array2.length) {
return false;

Check warning on line 663 in contracts/evm/contracts/xcall/CallService.sol

View check run for this annotation

Codecov / codecov/patch

contracts/evm/contracts/xcall/CallService.sol#L662-L663

Added lines #L662 - L663 were not covered by tests
}

for (uint256 i = 0; i < array1.length; i++) {
if (keccak256(bytes(array1[i])) != keccak256(bytes(array2[i]))) {
return false;

Check warning on line 668 in contracts/evm/contracts/xcall/CallService.sol

View check run for this annotation

Codecov / codecov/patch

contracts/evm/contracts/xcall/CallService.sol#L666-L668

Added lines #L666 - L668 were not covered by tests
}
}

return true;

Check warning on line 672 in contracts/evm/contracts/xcall/CallService.sol

View check run for this annotation

Codecov / codecov/patch

contracts/evm/contracts/xcall/CallService.sol#L672

Added line #L672 was not covered by tests
}

function verifySuccess(uint256 _sn) external view returns (bool) {
return successfulResponses[_sn];
}
Expand Down
Loading
Loading