-
Notifications
You must be signed in to change notification settings - Fork 31
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
Votes should be hashed according to EIP-712 #335 #399
Merged
Merged
Changes from 3 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
b2f2f25
Added VoteMessage and Vote struct, VoteMessage is hashed according to…
4bab481
Removed voteHash from Vote struct
b24f4d9
Merge remote-tracking branch 'upstream/develop' into gh_335
1b8e15d
Passing voteHash as param
8259658
Review changes
7774af9
Added comment for coreIdentifier
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -70,6 +70,52 @@ contract PollingPlace is PollingPlaceInterface { | |||||||
uint256 endHeight; | ||||||||
} | ||||||||
|
||||||||
/** Vote message */ | ||||||||
struct VoteMessage { | ||||||||
|
||||||||
/** A unique identifier that identifies what chain this vote is about. */ | ||||||||
bytes20 coreIdentifier; | ||||||||
|
||||||||
/** | ||||||||
* The hash of the transition object of the meta-block that would | ||||||||
* result from the source block being finalised and proposed to origin. | ||||||||
*/ | ||||||||
bytes32 transitionHash; | ||||||||
|
||||||||
/** The hash of the source block. */ | ||||||||
bytes32 source; | ||||||||
|
||||||||
/** The hash of the target block. */ | ||||||||
bytes32 target; | ||||||||
|
||||||||
/** The height of the source block. */ | ||||||||
uint256 sourceHeight; | ||||||||
|
||||||||
/** The height of the target block. */ | ||||||||
uint256 targetHeight; | ||||||||
} | ||||||||
|
||||||||
/** Vote object */ | ||||||||
struct Vote { | ||||||||
|
||||||||
/** Vote message. */ | ||||||||
VoteMessage voteMessage; | ||||||||
|
||||||||
/** v component of signature */ | ||||||||
uint8 v; | ||||||||
|
||||||||
/** r component of signature */ | ||||||||
bytes32 r; | ||||||||
|
||||||||
/** s component of signature */ | ||||||||
bytes32 s; | ||||||||
} | ||||||||
|
||||||||
/** To hash vote message according to EIP-712, a type hash is required. */ | ||||||||
bytes32 constant VOTE_MESSAGE_TYPEHASH = keccak256( | ||||||||
"VoteMessage(bytes20 coreIdentifier,bytes32 transitionHash,bytes32 source,bytes32 target,uint256 sourceHeight,uint256 targetHeight)" | ||||||||
); | ||||||||
|
||||||||
/* Public Variables */ | ||||||||
|
||||||||
/** | ||||||||
|
@@ -300,28 +346,27 @@ contract PollingPlace is PollingPlaceInterface { | |||||||
BlockStoreInterface blockStore = blockStores[_coreIdentifier]; | ||||||||
require( | ||||||||
address(blockStore) != address(0), | ||||||||
"The providede core identifier must be known to the PollingPlace." | ||||||||
"The provided core identifier must be known to the PollingPlace." | ||||||||
); | ||||||||
|
||||||||
require( | ||||||||
blockStore.isVoteValid(_transitionHash, _source, _target), | ||||||||
"The provided vote is not valid according to the block store." | ||||||||
); | ||||||||
|
||||||||
bytes32 voteHash = hashVote( | ||||||||
Vote memory voteObject = getVoteObject( | ||||||||
_coreIdentifier, | ||||||||
_transitionHash, | ||||||||
_source, | ||||||||
_target, | ||||||||
_sourceHeight, | ||||||||
_targetHeight | ||||||||
); | ||||||||
Validator storage validator = getValidatorFromVote( | ||||||||
voteHash, | ||||||||
_targetHeight, | ||||||||
_v, | ||||||||
_r, | ||||||||
_s | ||||||||
); | ||||||||
_s); | ||||||||
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.
Suggested change
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. Done! |
||||||||
|
||||||||
Validator storage validator = getValidatorFromVote(voteObject); | ||||||||
|
||||||||
require(validator.auxiliaryAddress != address(0), "Vote by unknown validator."); | ||||||||
|
||||||||
require( | ||||||||
|
@@ -330,10 +375,7 @@ contract PollingPlace is PollingPlaceInterface { | |||||||
); | ||||||||
|
||||||||
storeVote( | ||||||||
voteHash, | ||||||||
_source, | ||||||||
_target, | ||||||||
_targetHeight, | ||||||||
voteObject, | ||||||||
validator, | ||||||||
blockStore | ||||||||
); | ||||||||
|
@@ -428,35 +470,29 @@ contract PollingPlace is PollingPlaceInterface { | |||||||
* @dev All requirement checks must have been made before calling this | ||||||||
* method. | ||||||||
* | ||||||||
* @param _voteHash The hash of the vote object. The hash is used to | ||||||||
* identify the vote. | ||||||||
* @param _source The hash of the source checkpoint of the vote. | ||||||||
* @param _target The hash of the target checkpoint of the vote. | ||||||||
* @param _targetHeight The height of the target block of the vote. | ||||||||
* @param _validator The validator that signed the vote. | ||||||||
* @param _blockStore The block store that this vote is about. | ||||||||
* @param _voteObject Vote object. | ||||||||
*/ | ||||||||
function storeVote( | ||||||||
bytes32 _voteHash, | ||||||||
bytes32 _source, | ||||||||
bytes32 _target, | ||||||||
uint256 _targetHeight, | ||||||||
Vote memory _voteObject, | ||||||||
Validator storage _validator, | ||||||||
BlockStoreInterface _blockStore | ||||||||
) | ||||||||
private | ||||||||
{ | ||||||||
validatorTargetHeights[_validator.auxiliaryAddress] = _targetHeight; | ||||||||
votesWeights[_voteHash] += validatorWeight(_validator, currentMetaBlockHeight); | ||||||||
VoteMessage memory voteMessage = _voteObject.voteMessage; | ||||||||
bytes32 voteHash = hashVote(_voteObject.voteMessage); | ||||||||
|
||||||||
validatorTargetHeights[_validator.auxiliaryAddress] = voteMessage.targetHeight; | ||||||||
votesWeights[voteHash] += validatorWeight(_validator, currentMetaBlockHeight); | ||||||||
|
||||||||
/* | ||||||||
* Because the target must be within the currently open meta-block, the | ||||||||
* required weight must also be from the currently open meta-block. | ||||||||
*/ | ||||||||
uint256 required = requiredWeight(currentMetaBlockHeight); | ||||||||
|
||||||||
if (votesWeights[_voteHash] >= required) { | ||||||||
_blockStore.justify(_source, _target); | ||||||||
if (votesWeights[voteHash] >= required) { | ||||||||
_blockStore.justify(voteMessage.source, voteMessage.target); | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
|
@@ -482,25 +518,23 @@ contract PollingPlace is PollingPlaceInterface { | |||||||
* @notice Uses the signature of a vote to recover the public address of | ||||||||
* the signer. | ||||||||
* | ||||||||
* @param _voteHash The hashed vote. It is the message that was signed. | ||||||||
* @param _v V of the signature. | ||||||||
* @param _r R of teh signature. | ||||||||
* @param _s S of the signature. | ||||||||
* @param _voteObject Vote object. | ||||||||
* | ||||||||
* @return The `Validator` that signed the given message with the given | ||||||||
* signature. | ||||||||
*/ | ||||||||
function getValidatorFromVote( | ||||||||
bytes32 _voteHash, | ||||||||
uint8 _v, | ||||||||
bytes32 _r, | ||||||||
bytes32 _s | ||||||||
) | ||||||||
function getValidatorFromVote(Vote memory _voteObject) | ||||||||
private | ||||||||
view | ||||||||
returns (Validator storage validator_) | ||||||||
{ | ||||||||
address signer = ecrecover(_voteHash, _v, _r, _s); | ||||||||
bytes32 voteHash = hashVote(_voteObject.voteMessage); | ||||||||
address signer = ecrecover( | ||||||||
voteHash, | ||||||||
_voteObject.v, | ||||||||
_voteObject.r, | ||||||||
_voteObject.s | ||||||||
); | ||||||||
validator_ = validators[signer]; | ||||||||
} | ||||||||
|
||||||||
|
@@ -564,35 +598,24 @@ contract PollingPlace is PollingPlaceInterface { | |||||||
* @notice Creates the hash of o vote object. This is the same hash that | ||||||||
* the validator has signed. | ||||||||
* | ||||||||
* @param _coreIdentifier Core identifier of the vote object. | ||||||||
* @param _transitionHash Transition hash of the vote object. | ||||||||
* @param _source Source block hash of the vote object. | ||||||||
* @param _target Target block hash of the vote object. | ||||||||
* @param _sourceHeight Source height of the vote object. | ||||||||
* @param _targetHeight Target height of the vote object. | ||||||||
* @param _voteMessage Vote message object. | ||||||||
* | ||||||||
* @return The hash of the given vote. | ||||||||
*/ | ||||||||
function hashVote( | ||||||||
bytes20 _coreIdentifier, | ||||||||
bytes32 _transitionHash, | ||||||||
bytes32 _source, | ||||||||
bytes32 _target, | ||||||||
uint256 _sourceHeight, | ||||||||
uint256 _targetHeight | ||||||||
) | ||||||||
function hashVote(VoteMessage memory _voteMessage) | ||||||||
private | ||||||||
pure | ||||||||
returns (bytes32 hashed_) | ||||||||
{ | ||||||||
hashed_ = keccak256( | ||||||||
abi.encodePacked( | ||||||||
_coreIdentifier, | ||||||||
_transitionHash, | ||||||||
_source, | ||||||||
_target, | ||||||||
_sourceHeight, | ||||||||
_targetHeight | ||||||||
VOTE_MESSAGE_TYPEHASH, | ||||||||
_voteMessage.coreIdentifier, | ||||||||
_voteMessage.transitionHash, | ||||||||
_voteMessage.source, | ||||||||
_voteMessage.target, | ||||||||
_voteMessage.sourceHeight, | ||||||||
_voteMessage.targetHeight | ||||||||
) | ||||||||
); | ||||||||
|
||||||||
|
@@ -605,4 +628,53 @@ contract PollingPlace is PollingPlaceInterface { | |||||||
) | ||||||||
); | ||||||||
} | ||||||||
|
||||||||
/** | ||||||||
* @notice Creates a vote object | ||||||||
* | ||||||||
* @param _coreIdentifier A unique identifier that identifies what chain | ||||||||
* this vote is about. | ||||||||
* @param _transitionHash The hash of the transition object of the | ||||||||
* meta-block that would result from the source | ||||||||
* block being finalised and proposed to origin. | ||||||||
* @param _source The hash of the source block. | ||||||||
* @param _target The hash of the target block. | ||||||||
* @param _sourceHeight The height of the source block. | ||||||||
* @param _targetHeight The height of the target block. | ||||||||
* @param _v V of the signature. | ||||||||
* @param _r R of the signature. | ||||||||
* @param _s S of the signature. | ||||||||
* | ||||||||
* @return vote object | ||||||||
*/ | ||||||||
function getVoteObject( | ||||||||
bytes20 _coreIdentifier, | ||||||||
bytes32 _transitionHash, | ||||||||
bytes32 _source, | ||||||||
bytes32 _target, | ||||||||
uint256 _sourceHeight, | ||||||||
uint256 _targetHeight, | ||||||||
uint8 _v, | ||||||||
bytes32 _r, | ||||||||
bytes32 _s | ||||||||
) | ||||||||
private | ||||||||
returns (Vote memory voteObject_) | ||||||||
{ | ||||||||
VoteMessage memory voteMessage = VoteMessage( | ||||||||
_coreIdentifier, | ||||||||
_transitionHash, | ||||||||
_source, | ||||||||
_target, | ||||||||
_sourceHeight, | ||||||||
_targetHeight | ||||||||
); | ||||||||
|
||||||||
voteObject_ = Vote( | ||||||||
voteMessage, | ||||||||
_v, | ||||||||
_r, | ||||||||
_s | ||||||||
); | ||||||||
} | ||||||||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Please also explain here why it has to be part of the struct.
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.
Added the comment 👍