-
Notifications
You must be signed in to change notification settings - Fork 27
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
Manually pack initialValidators for subnetConversion ID hash-preimage #564
Changes from 4 commits
49636c1
0c7b3eb
fd20c84
bc4de86
627f47b
5048225
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,8 @@ | |
// SPDX-License-Identifier: Ecosystem | ||
pragma solidity 0.8.25; | ||
|
||
import {SubnetConversionData} from "./interfaces/IValidatorManager.sol"; | ||
|
||
library ValidatorMessages { | ||
// The information that uniquely identifies a subnet validation period. | ||
// The validationID is the SHA-256 hash of the concatenation of the CODEC_ID, | ||
|
@@ -65,21 +67,7 @@ library ValidatorMessages { | |
pure | ||
returns (bytes memory) | ||
{ | ||
bytes memory res = new bytes(38); | ||
// Pack the codec ID | ||
for (uint256 i; i < 2; ++i) { | ||
res[i] = bytes1(uint8(CODEC_ID >> uint8((8 * (1 - i))))); | ||
} | ||
// Pack the type ID | ||
for (uint256 i; i < 4; ++i) { | ||
res[i + 2] = bytes1(uint8(SUBNET_CONVERSION_MESSAGE_TYPE_ID >> uint8((8 * (3 - i))))); | ||
} | ||
// Pack the subnetConversionID | ||
for (uint256 i; i < 32; ++i) { | ||
res[i + 6] = bytes1(uint8(uint256(subnetConversionID >> (8 * (31 - i))))); | ||
} | ||
|
||
return res; | ||
return abi.encodePacked(CODEC_ID, SUBNET_CONVERSION_MESSAGE_TYPE_ID, subnetConversionID); | ||
} | ||
|
||
/** | ||
|
@@ -117,6 +105,85 @@ library ValidatorMessages { | |
return subnetConversionID; | ||
} | ||
|
||
/** | ||
* @notice Packs SubnetConversionData into a byte array. | ||
* This byte array is the SHA256 pre-image of the subnetConversionID hash | ||
* The message format specification is: | ||
* | ||
* +-------------------+---------------+---------------------------------------------------------+ | ||
* | convertSubnetTxID : [32]byte | 32 bytes | | ||
* +-------------------+-----------------+-------------------------------------------------------+ | ||
* | managerChainID : [32]byte | 32 bytes | | ||
* +-------------------+-----------------+-------------------------------------------------------+ | ||
* | managerAddress : []byte | 4 + len(managerAddress) bytes | | ||
* +-------------------+-----------------+-------------------------------------------------------+ | ||
* | validators : []ValidatorData | 4 + len(validators) * 88 bytes | | ||
* +-------------------+-----------------+-------------------------------------------------------+ | ||
* | 72 + len(managerAddress) + len(validators) * 88 bytes | | ||
* +-------------------------------------------------------+ | ||
* And ValidatorData: | ||
* +--------------+----------+-----------+ | ||
* | nodeID : [32]byte | 32 bytes | | ||
* +--------------+----------+-----------+ | ||
* | weight : uint64 | 8 bytes | | ||
* +--------------+----------+-----------+ | ||
* | blsPublicKey : [48]byte | 48 bytes | | ||
* +--------------+----------+-----------+ | ||
* | 88 bytes | | ||
* +-----------+ | ||
* | ||
* @param subnetConversionData The struct representing data to pack into the message. | ||
* @return The packed message. | ||
*/ | ||
function packSubnetConversionData(SubnetConversionData calldata subnetConversionData) | ||
internal | ||
pure | ||
returns (bytes memory) | ||
{ | ||
bytes memory res = new bytes(92 + subnetConversionData.initialValidators.length * 88); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From the comment above, it wasn't immediately clear to me why the constant was 92 here rather than 72. Mind adding a comment explaining the address is known to be 20 bytes long? |
||
// Pack the convertSubnetTx ID | ||
for (uint256 i; i < 32; ++i) { | ||
res[i] = subnetConversionData.convertSubnetTxID[i]; | ||
} | ||
// Pack the validatorManagerBlockchainID | ||
for (uint256 i; i < 32; ++i) { | ||
res[i + 32] = subnetConversionData.validatorManagerBlockchainID[i]; | ||
} | ||
// Pack the ADDRESS_LENGTH | ||
for (uint256 i; i < 4; ++i) { | ||
res[i + 64] = bytes1(uint8(20 >> (8 * (3 - i)))); | ||
} | ||
// Pack the address | ||
bytes20 addrBytes = bytes20(subnetConversionData.validatorManagerAddress); | ||
for (uint256 i = 0; i < 20; i++) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Lets use pre-increment like each of the other loops here. |
||
res[i + 68] = addrBytes[i]; | ||
} | ||
|
||
// Pack the initial validators length | ||
uint32 ivLength = uint32(subnetConversionData.initialValidators.length); | ||
for (uint256 i; i < 4; ++i) { | ||
res[i + 88] = bytes1(uint8(ivLength >> (8 * (3 - i)))); | ||
} | ||
|
||
for (uint256 i = 0; i < subnetConversionData.initialValidators.length; i++) { | ||
uint256 offset = 92 + i * 88; | ||
// Pack the nodeID | ||
for (uint256 j; j < 32; ++j) { | ||
res[offset + j] = subnetConversionData.initialValidators[i].nodeID[j]; | ||
} | ||
// Pack the weight | ||
for (uint256 j; j < 8; ++j) { | ||
res[offset + 32 + j] = | ||
bytes1(uint8(subnetConversionData.initialValidators[i].weight >> (8 * (7 - j)))); | ||
} | ||
// Pack the blsPublicKey | ||
for (uint256 j; j < 48; ++j) { | ||
res[offset + 40 + j] = subnetConversionData.initialValidators[i].blsPublicKey[j]; | ||
} | ||
} | ||
return res; | ||
} | ||
|
||
/** | ||
* @notice Packs a RegisterSubnetValidatorMessage message into a byte array. | ||
* The message format specification is: | ||
|
@@ -149,38 +216,17 @@ library ValidatorMessages { | |
require( | ||
validationPeriod.blsPublicKey.length == 48, "StakingMessages: invalid signature length" | ||
); | ||
bytes memory res = new bytes(134); | ||
// Pack the codec ID | ||
for (uint256 i; i < 2; ++i) { | ||
res[i] = bytes1(uint8(CODEC_ID >> uint8((8 * (1 - i))))); | ||
} | ||
// Pack the type ID | ||
for (uint256 i; i < 4; ++i) { | ||
res[i + 2] = | ||
bytes1(uint8(REGISTER_SUBNET_VALIDATOR_MESSAGE_TYPE_ID >> uint8((8 * (3 - i))))); | ||
} | ||
|
||
// Pack the subnetID | ||
for (uint256 i; i < 32; ++i) { | ||
res[i + 6] = validationPeriod.subnetID[i]; | ||
} | ||
// Pack the nodeID | ||
for (uint256 i; i < 32; ++i) { | ||
res[i + 38] = validationPeriod.nodeID[i]; | ||
} | ||
// Pack the weight | ||
for (uint256 i; i < 8; ++i) { | ||
res[i + 70] = bytes1(uint8(validationPeriod.weight >> uint8((8 * (7 - i))))); | ||
} | ||
// Pack the blsPublicKey | ||
for (uint256 i; i < 48; ++i) { | ||
res[i + 78] = validationPeriod.blsPublicKey[i]; | ||
} | ||
// Pack the registration expiry | ||
for (uint256 i; i < 8; ++i) { | ||
res[i + 126] = | ||
bytes1(uint8(validationPeriod.registrationExpiry >> uint64((8 * (7 - i))))); | ||
} | ||
// solhint-disable-next-line func-named-parameters | ||
bytes memory res = abi.encodePacked( | ||
CODEC_ID, | ||
REGISTER_SUBNET_VALIDATOR_MESSAGE_TYPE_ID, | ||
validationPeriod.subnetID, | ||
validationPeriod.nodeID, | ||
validationPeriod.weight, | ||
validationPeriod.blsPublicKey, | ||
validationPeriod.registrationExpiry | ||
); | ||
return (sha256(res), res); | ||
} | ||
|
||
|
@@ -278,23 +324,9 @@ library ValidatorMessages { | |
bytes32 validationID, | ||
bool valid | ||
) internal pure returns (bytes memory) { | ||
bytes memory res = new bytes(39); | ||
// Pack the codec ID. | ||
for (uint256 i; i < 2; ++i) { | ||
res[i] = bytes1(uint8(CODEC_ID >> (8 * (1 - i)))); | ||
} | ||
// Pack the type ID. | ||
for (uint256 i; i < 4; ++i) { | ||
res[i + 2] = | ||
bytes1(uint8(SUBNET_VALIDATOR_REGISTRATION_MESSAGE_TYPE_ID >> (8 * (3 - i)))); | ||
} | ||
// Pack the validation ID. | ||
for (uint256 i; i < 32; ++i) { | ||
res[i + 6] = bytes1(uint8(uint256(validationID >> (8 * (31 - i))))); | ||
} | ||
// Pack the validity. | ||
res[38] = bytes1(valid ? 1 : 0); | ||
return res; | ||
return abi.encodePacked( | ||
CODEC_ID, SUBNET_VALIDATOR_REGISTRATION_MESSAGE_TYPE_ID, validationID, valid | ||
); | ||
} | ||
|
||
/** | ||
|
@@ -367,28 +399,9 @@ library ValidatorMessages { | |
uint64 nonce, | ||
uint64 weight | ||
) internal pure returns (bytes memory) { | ||
bytes memory res = new bytes(54); | ||
// Pack the codec ID. | ||
for (uint256 i; i < 2; ++i) { | ||
res[i] = bytes1(uint8(CODEC_ID >> (8 * (1 - i)))); | ||
} | ||
// Pack the type ID. | ||
for (uint256 i; i < 4; ++i) { | ||
res[i + 2] = bytes1(uint8(SET_SUBNET_VALIDATOR_WEIGHT_MESSAGE_TYPE_ID >> (8 * (3 - i)))); | ||
} | ||
// Pack the validation ID. | ||
for (uint256 i; i < 32; ++i) { | ||
res[i + 6] = bytes1(uint8(uint256(validationID >> (8 * (31 - i))))); | ||
} | ||
// Pack the nonce. | ||
for (uint256 i; i < 8; ++i) { | ||
res[i + 38] = bytes1(uint8(nonce >> (8 * (7 - i)))); | ||
} | ||
// Pack the weight. | ||
for (uint256 i; i < 8; ++i) { | ||
res[i + 46] = bytes1(uint8(weight >> (8 * (7 - i)))); | ||
} | ||
return res; | ||
return abi.encodePacked( | ||
CODEC_ID, SET_SUBNET_VALIDATOR_WEIGHT_MESSAGE_TYPE_ID, validationID, nonce, weight | ||
); | ||
} | ||
|
||
/** | ||
|
@@ -465,29 +478,9 @@ library ValidatorMessages { | |
uint64 nonce, | ||
uint64 weight | ||
) internal pure returns (bytes memory) { | ||
bytes memory res = new bytes(54); | ||
// Pack the codec ID. | ||
for (uint256 i; i < 2; ++i) { | ||
res[i] = bytes1(uint8(CODEC_ID >> (8 * (1 - i)))); | ||
} | ||
// Pack the type ID. | ||
for (uint256 i; i < 4; ++i) { | ||
res[i + 2] = | ||
bytes1(uint8(SUBNET_VALIDATOR_WEIGHT_UPDATE_MESSAGE_TYPE_ID >> (8 * (3 - i)))); | ||
} | ||
// Pack the validation ID. | ||
for (uint256 i; i < 32; ++i) { | ||
res[i + 6] = bytes1(uint8(uint256(validationID >> (8 * (31 - i))))); | ||
} | ||
// Pack the nonce. | ||
for (uint256 i; i < 8; ++i) { | ||
res[i + 38] = bytes1(uint8(nonce >> (8 * (7 - i)))); | ||
} | ||
// Pack the weight. | ||
for (uint256 i; i < 8; ++i) { | ||
res[i + 46] = bytes1(uint8(weight >> (8 * (7 - i)))); | ||
} | ||
return res; | ||
return abi.encodePacked( | ||
CODEC_ID, SUBNET_VALIDATOR_WEIGHT_UPDATE_MESSAGE_TYPE_ID, validationID, nonce, weight | ||
); | ||
} | ||
|
||
/** | ||
|
@@ -565,25 +558,7 @@ library ValidatorMessages { | |
bytes32 validationID, | ||
uint64 uptime | ||
) internal pure returns (bytes memory) { | ||
bytes memory res = new bytes(46); | ||
|
||
// Pack the codec ID. | ||
for (uint256 i; i < 2; ++i) { | ||
res[i] = bytes1(uint8(CODEC_ID >> (8 * (1 - i)))); | ||
} | ||
// Pack the type ID. | ||
for (uint256 i; i < 4; ++i) { | ||
res[i + 2] = bytes1(uint8(VALIDATION_UPTIME_MESSAGE_TYPE_ID >> (8 * (3 - i)))); | ||
} | ||
// Pack the validation ID. | ||
for (uint256 i; i < 32; ++i) { | ||
res[i + 6] = bytes1(uint8(uint256(validationID >> (8 * (31 - i))))); | ||
} | ||
// Pack the uptime. | ||
for (uint256 i; i < 8; ++i) { | ||
res[i + 38] = bytes1(uint8(uptime >> (8 * (7 - i)))); | ||
} | ||
return res; | ||
return abi.encodePacked(CODEC_ID, VALIDATION_UPTIME_MESSAGE_TYPE_ID, validationID, uptime); | ||
} | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While we're here, would you mind removing the TODO from line 46 above?