Skip to content

Commit 303f30f

Browse files
[NONEVM-3390] [CL86-07] Multiple Struct CRC32 Mismatches (#482)
* feat: script to validate opcodes comply with crc32 of the message name * fix: skip opcode lint * feat: expose via nix * cicd: check opcodes on commit * feat: detect duplicate opcodes * fix: router opcodes * fix: skip opcode lint for extra args * fix: feequoter opcodes * fix: opcodes in receiver * feat: use nolint: comment * ref: reuse file descriptor * ref: run oplint from nix
1 parent 61bbbbd commit 303f30f

File tree

20 files changed

+590
-34
lines changed

20 files changed

+590
-34
lines changed

.github/workflows/contracts-build.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ jobs:
1818
with:
1919
nix_path: nixpkgs=channel:nixos-unstable
2020

21+
- name: Run oplint
22+
run: |
23+
pushd contracts/contracts
24+
nix run .#oplint -- ccip deployable lib mcms
2125
- name: Run build
2226
run: |
2327
pushd contracts

contracts/contracts/ccip/common/messages.tolk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// nolint:opcode
12
struct (0x7362d09c) Common_JettonTransferNotification {
23
queryId: uint64;
34
amount: coins;

contracts/contracts/ccip/common/types.tolk

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@ struct RampMessageHeader { // 512
3030

3131
const LEAF_DOMAIN_SEPARATOR: slice = stringHexToSlice("0000000000000000000000000000000000000000000000000000000000000000");
3232

33+
// nolint:opcode : hex encoded bytes4(keccak256("CCIP EVMExtraArgsV2"))
3334
struct (0x181dcf10) GenericExtraArgsV2 {
3435
gasLimit: uint256?;
3536
allowOutOfOrderExecution: bool;
3637
}
3738

39+
// nolint:opcode : hex encoded bytes4(keccak256("CCIP SVMExtraArgsV1"))
3840
struct (0x1f3b3aba) SVMExtraArgsV1 {
3941
computeUnits: uint32;
4042
accountIsWritableBitmap: uint64;
@@ -43,6 +45,7 @@ struct (0x1f3b3aba) SVMExtraArgsV1 {
4345
accounts: SnakedCell<uint256>; // vec<slice>
4446
}
4547

48+
// nolint:opcode : hex encoded bytes4(keccak256("CCIP SuiExtraArgsV1"))
4649
struct (0x21ea4ca9) SuiExtraArgsV1 {
4750
gasLimit: uint256;
4851
allowOutOfOrderExecution: bool;

contracts/contracts/ccip/fee_quoter/messages.tolk

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ type FeeQuoter_InMessage =
1717
| Upgradeable_Upgrade;
1818
;
1919

20-
struct (0x20000001) FeeQuoter_UpdatePrices {
20+
struct (0xde852b1b) FeeQuoter_UpdatePrices {
2121
updates: PriceUpdates
2222
sendExcessesTo: address?;
2323
}
@@ -54,7 +54,7 @@ struct (0xB2826316) FeeQuoter_UpdateTokenTransferFeeConfigs {
5454
updates: map<uint64, UpdateTokenTransferFeeConfig>; // destChainSelector -> updates
5555
}
5656

57-
struct (0x29950BAA) FeeQuoter_UpdateDestChainConfigs {
57+
struct (0x2d2410f6) FeeQuoter_UpdateDestChainConfigs {
5858
updates: SnakedCell<FeeQuoter_UpdateDestChainConfig>;
5959
}
6060

contracts/contracts/ccip/router/messages.tolk

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ struct (0x7db6745d) Router_ApplyRampUpdates {
4040
// TODO should separate CCIPSend msg (with opcode) from CCIPSend data
4141

4242
// Answers with Router_CCIPReceive
43-
struct (0x38a69e3b) Router_CCIPSend {
43+
struct (0x31768d95) Router_CCIPSend {
4444
queryID: uint64;
4545
destChainSelector: uint64;
4646
receiver: CrossChainAddress;
@@ -57,28 +57,28 @@ struct (0xfc69c50b) Router_RouteMessage {
5757
gasLimit: coins;
5858
}
5959

60-
struct (0xaf0cccef) Router_CCIPReceiveConfirm {
60+
struct (0x1e55bbf6) Router_CCIPReceiveConfirm {
6161
execId: ReceiveExecutorId;
6262
}
6363

6464
// curse/uncurse/verify uncursed (also as getter)
65-
struct (0xe6bf1813) Router_RMNRemoteCurse {
65+
struct (0xf3388046) Router_RMNRemoteCurse {
6666
queryId: uint64
6767
subjects: SnakedCell<uint128>
6868
}
6969

70-
struct (0x060d9dd1) Router_RMNRemoteUncurse {
70+
struct (0x3f153a31) Router_RMNRemoteUncurse {
7171
queryId: uint64
7272
subjects: SnakedCell<uint128>
7373
}
7474

7575
// Internal contracts can have their own cache, but external contracts will need to fetch the curse status via this method.
76-
struct (0x49fd38ce) Router_RMNRemoteVerifyNotCursed {
76+
struct (0x0b95aa4e) Router_RMNRemoteVerifyNotCursed {
7777
queryId: uint64
7878
subject: uint128
7979
}
8080

81-
struct (0x0d9368a9) Router_RMNRemoteVerifyNotCursedResponse {
81+
struct (0x22ba83b3) Router_RMNRemoteVerifyNotCursedResponse {
8282
queryId: uint64
8383
result: bool
8484
}

contracts/contracts/ccip/test/receiver/messages.tolk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ type Receiver_InMessage =
66
| Receiver_UpdateBehavior
77
| Receiver_UpdateAuthorizedCaller;
88

9-
struct (0x14d52e7b) Receiver_UpdateBehavior {
9+
struct (0x14d3fadb) Receiver_UpdateBehavior {
1010
behavior: ReceiverBehavior
1111
}
1212

contracts/contracts/lib/jetton/messages.tolk

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import "storage"
33

44
type ForwardPayloadRemainder = RemainingBitsAndRefs
55

6+
// nolint:opcode
67
struct (0x0f8a7ea5) AskToTransfer {
78
queryId: uint64
89
jettonAmount: coins
@@ -13,13 +14,15 @@ struct (0x0f8a7ea5) AskToTransfer {
1314
forwardPayload: ForwardPayloadRemainder
1415
}
1516

17+
// nolint:opcode
1618
struct (0x7362d09c) TransferNotificationForRecipient {
1719
queryId: uint64
1820
jettonAmount: coins
1921
transferInitiator: address
2022
forwardPayload: ForwardPayloadRemainder
2123
}
2224

25+
// nolint:opcode
2326
struct (0x178d4519) InternalTransferStep {
2427
queryId: uint64
2528
jettonAmount: coins
@@ -29,67 +32,79 @@ struct (0x178d4519) InternalTransferStep {
2932
forwardPayload: ForwardPayloadRemainder
3033
}
3134

35+
// nolint:opcode
3236
struct (0xd53276db) ReturnExcessesBack {
3337
queryId: uint64
3438
}
3539

40+
// nolint:opcode
3641
struct (0x595f07bc) AskToBurn {
3742
queryId: uint64
3843
jettonAmount: coins
3944
sendExcessesTo: address
4045
customPayload: cell?
4146
}
4247

48+
// nolint:opcode
4349
struct (0x7bdd97de) BurnNotificationForMinter {
4450
queryId: uint64
4551
jettonAmount: coins
4652
burnInitiator: address
4753
sendExcessesTo: address
4854
}
4955

56+
// nolint:opcode
5057
struct (0x2c76b973) RequestWalletAddress {
5158
queryId: uint64
5259
ownerAddress: address
5360
includeOwnerAddress: bool
5461
}
5562

63+
// nolint:opcode
5664
struct (0xd1735400) ResponseWalletAddress {
5765
queryId: uint64
5866
jettonWalletAddress: address
5967
ownerAddress: Cell<address>?
6068
}
6169

70+
// nolint:opcode
6271
struct (0x00000015) MintNewJettons {
6372
queryId: uint64
6473
mintRecipient: address
6574
tonAmount: coins
6675
internalTransferMsg: Cell<InternalTransferStep>
6776
}
6877

78+
// nolint:opcode
6979
struct (0x6501f354) ChangeMinterAdmin {
7080
queryId: uint64
7181
newAdminAddress: address
7282
}
7383

84+
// nolint:opcode
7485
struct (0xfb88e119) ClaimMinterAdmin {
7586
queryId: uint64
7687
}
7788

89+
// nolint:opcode
7890
struct (0x7431f221) DropMinterAdmin {
7991
queryId: uint64
8092
}
8193

94+
// nolint:opcode
8295
struct (0x2508d66a) UpgradeMinterCode {
8396
queryId: uint64
8497
newData: cell
8598
newCode: cell
8699
}
87100

101+
// nolint:opcode
88102
struct (0xcb862902) ChangeMinterMetadataUri {
89103
queryId: uint64
90104
newMetadataUri: SnakeString
91105
}
92106

107+
// nolint:opcode
93108
struct (0xd372158c) TopUpTons {}
94109

95110
// "forward payload" is TL/B `(Either Cell ^Cell)`;

contracts/default.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
pkgs,
33
rev,
4+
oplint,
45
}: let
56
lock = pkgs.callPackage ./lock.nix {inherit pkgs;};
67

@@ -73,6 +74,7 @@ in {
7374
contracts = pkgs.callPackage ./shell.nix {
7475
inherit pkgs;
7576
jetton-contracts = packages.contracts-jetton-func;
77+
inherit oplint;
7678
};
7779
};
7880

contracts/shell.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
pkgs,
44
lib,
55
jetton-contracts,
6+
oplint,
67
}:
78
pkgs.mkShell {
89
buildInputs = with pkgs; [
@@ -20,6 +21,7 @@ pkgs.mkShell {
2021
# Extra tools
2122
git
2223
jq
24+
oplint
2325
];
2426

2527
PATH_CONTRACTS_JETTON = "${jetton-contracts}/lib/node_modules/jetton/build/";

contracts/tests/ccip/router/Router.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,12 @@ describe('Router - Ownable Tests', () => {
166166
describe('Router - Opcodes', () => {
167167
it('should match in opcodes', () => {
168168
expect(rt.opcodes.in.applyRampUpdates).toBe(crc32('Router_ApplyRampUpdates'))
169-
expect(rt.opcodes.in.ccipSend).toBe(crc32('Router_CcipSend'))
170-
expect(rt.opcodes.in.ccipReceiveConfirm).toBe(crc32('Router_CcipReceiveConfirm'))
169+
expect(rt.opcodes.in.ccipSend).toBe(crc32('Router_CCIPSend'))
170+
expect(rt.opcodes.in.ccipReceiveConfirm).toBe(crc32('Router_CCIPReceiveConfirm'))
171171
expect(rt.opcodes.in.routeMessage).toBe(crc32('Router_RouteMessage'))
172-
expect(rt.opcodes.in.rmnRemoteCurse).toBe(crc32('Router_Curse'))
173-
expect(rt.opcodes.in.rmnRemoteUncurse).toBe(crc32('Router_Uncurse'))
174-
expect(rt.opcodes.in.verifyNotCursed).toBe(crc32('Router_VerifyNotCursed'))
172+
expect(rt.opcodes.in.rmnRemoteCurse).toBe(crc32('Router_RMNRemoteCurse'))
173+
expect(rt.opcodes.in.rmnRemoteUncurse).toBe(crc32('Router_RMNRemoteUncurse'))
174+
expect(rt.opcodes.in.verifyNotCursed).toBe(crc32('Router_RMNRemoteVerifyNotCursed'))
175175
expect(rt.opcodes.in.messageSent).toBe(crc32('Router_MessageSent'))
176176
expect(rt.opcodes.in.messageRejected).toBe(crc32('Router_MessageRejected'))
177177
expect(rt.opcodes.in.getValidatedFee).toBe(crc32('Router_GetValidatedFee'))

0 commit comments

Comments
 (0)