Skip to content

Commit 54c69b6

Browse files
authored
Reverse endianness for Solana integer (#203)
* Reverse endianness for Solana
1 parent 0ebdc42 commit 54c69b6

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

evm/src/HubSolanaSpokeVoteDecoder.sol

+18-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ contract HubSolanaSpokeVoteDecoder is ISpokeVoteDecoder, QueryResponse, ERC165 {
156156
// Verify the total length of the data (72 bytes)
157157
_data.checkLength(_offset);
158158

159-
return (_proposalIdBytes, _againstVotes, _forVotes, _abstainVotes, _voteStart);
159+
return
160+
(_proposalIdBytes, _reverse(_againstVotes), _reverse(_forVotes), _reverse(_abstainVotes), _reverse(_voteStart));
160161
}
161162

162163
/// @notice Scales an amount from original decimals to target decimals
@@ -170,4 +171,20 @@ contract HubSolanaSpokeVoteDecoder is ISpokeVoteDecoder, QueryResponse, ERC165 {
170171
if (_fromDecimals > _toDecimals) return _amount / (10 ** (_fromDecimals - _toDecimals));
171172
else return _amount * (10 ** (_toDecimals - _fromDecimals));
172173
}
174+
175+
/// @notice Reverse the endianness of the passed in integer.
176+
/// @param _input The integer for which to reverse the endianess.
177+
/// @return An integer with the endianness reversed.
178+
/// @dev This code was copied from
179+
/// https://github.com/wormholelabs-xyz/example-queries-solana-pda/blob/4a01a0a6018b36a1d38d326362bfb672c5061c5f/src/OwnerVerifier.sol#L52.
180+
function _reverse(uint64 _input) internal pure returns (uint64) {
181+
uint64 v = _input;
182+
// swap bytes
183+
v = ((v & 0xFF00FF00FF00FF00) >> 8) | ((v & 0x00FF00FF00FF00FF) << 8);
184+
// swap 2-byte long pairs
185+
v = ((v & 0xFFFF0000FFFF0000) >> 16) | ((v & 0x0000FFFF0000FFFF) << 16);
186+
// swap 4-byte long pairs
187+
v = (v >> 32) | (v << 32);
188+
return v;
189+
}
173190
}

evm/test/HubSolanaSpokeVoteDecoder.t.sol

+13-3
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,16 @@ contract Decode is HubSolanaSpokeVoteDecoderTest, ProposalTest {
238238
* (10 ** (hubSolanaSpokeVoteDecoder.HUB_TOKEN_DECIMALS() - hubSolanaSpokeVoteDecoder.SOLANA_TOKEN_DECIMALS()));
239239
}
240240

241+
function _reverse(uint64 input) internal pure returns (uint64 v) {
242+
v = input;
243+
// swap bytes
244+
v = ((v & 0xFF00FF00FF00FF00) >> 8) | ((v & 0x00FF00FF00FF00FF) << 8);
245+
// swap 2-byte long pairs
246+
v = ((v & 0xFFFF0000FFFF0000) >> 16) | ((v & 0x0000FFFF0000FFFF) << 16);
247+
// swap 4-byte long pairs
248+
v = (v >> 32) | (v << 32);
249+
}
250+
241251
function testFuzz_CorrectlyParseChainResponse(
242252
uint64 _againstVotes,
243253
uint64 _forVotes,
@@ -261,9 +271,9 @@ contract Decode is HubSolanaSpokeVoteDecoderTest, ProposalTest {
261271

262272
assertEq(queryVote.proposalId, proposalId, "Proposal ID mismatch");
263273
assertEq(queryVote.spokeProposalId, keccak256(abi.encode(SPOKE_CHAIN_ID, proposalId)), "Spoke proposal ID mismatch");
264-
assertEq(queryVote.proposalVote.abstainVotes, _scale(_abstainVotes), "Abstain votes mismatch");
265-
assertEq(queryVote.proposalVote.againstVotes, _scale(_againstVotes), "Against votes mismatch");
266-
assertEq(queryVote.proposalVote.forVotes, _scale(_forVotes), "For votes mismatch");
274+
assertEq(queryVote.proposalVote.abstainVotes, _scale(_reverse(_abstainVotes)), "Abstain votes mismatch");
275+
assertEq(queryVote.proposalVote.againstVotes, _scale(_reverse(_againstVotes)), "Against votes mismatch");
276+
assertEq(queryVote.proposalVote.forVotes, _scale(_reverse(_forVotes)), "For votes mismatch");
267277
assertEq(queryVote.chainId, SPOKE_CHAIN_ID, "Chain ID mismatch");
268278
}
269279

0 commit comments

Comments
 (0)