-
Notifications
You must be signed in to change notification settings - Fork 43
Add additional checks to consensus contracts #382
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@cartesi/rollups": minor | ||
--- | ||
|
||
Make `Authority` and `Quorum` validate last processed block number |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@cartesi/rollups": major | ||
--- | ||
|
||
Avoid conflicting claims in Quorum |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@cartesi/rollups": patch | ||
--- | ||
|
||
Bump solc from 0.8.23 to 0.8.29 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[profile.default] | ||
libs = [] | ||
solc_version = "0.8.23" | ||
solc_version = "0.8.29" | ||
via_ir = true | ||
optimizer = true | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,12 @@ contract Quorum is IQuorum, AbstractConsensus { | |
BitMaps.BitMap inFavorById; | ||
} | ||
|
||
/// @notice Votes indexed by application contract address, | ||
/// and last processed block number. | ||
/// @dev See the `numOfValidatorsInFavorOfAnyClaimInEpoch` | ||
/// and `isValidatorInFavorOfAnyClaimInEpoch` functions. | ||
mapping(address => mapping(uint256 => Votes)) private _allVotes; | ||
|
||
/// @notice Votes indexed by application contract address, | ||
/// last processed block number and outputs Merkle root. | ||
/// @dev See the `numOfValidatorsInFavorOf` and `isValidatorInFavorOf` functions. | ||
|
@@ -68,14 +74,32 @@ contract Quorum is IQuorum, AbstractConsensus { | |
uint256 id = _validatorId[msg.sender]; | ||
require(id > 0, "Quorum: caller is not validator"); | ||
|
||
_validateLastProcessedBlockNumber(lastProcessedBlockNumber); | ||
|
||
emit ClaimSubmitted( | ||
msg.sender, appContract, lastProcessedBlockNumber, outputsMerkleRoot | ||
); | ||
|
||
Votes storage votes = | ||
_getVotes(appContract, lastProcessedBlockNumber, outputsMerkleRoot); | ||
|
||
Votes storage allVotes = _getAllVotes(appContract, lastProcessedBlockNumber); | ||
|
||
// Skip storage changes if validator already voted | ||
// for the same exact claim before | ||
if (!votes.inFavorById.get(id)) { | ||
// Revert if validator has submitted another claim for the same epoch | ||
require( | ||
!allVotes.inFavorById.get(id), | ||
NotFirstClaim(appContract, lastProcessedBlockNumber) | ||
); | ||
|
||
// Register vote (for any claim in the epoch) | ||
allVotes.inFavorById.set(id); | ||
++allVotes.inFavorCount; | ||
|
||
// Register vote (for the specific claim) | ||
// and accept the claim if a majority has been reached | ||
votes.inFavorById.set(id); | ||
if (++votes.inFavorCount == 1 + _numOfValidators / 2) { | ||
_acceptClaim(appContract, lastProcessedBlockNumber, outputsMerkleRoot); | ||
|
@@ -95,6 +119,21 @@ contract Quorum is IQuorum, AbstractConsensus { | |
return _validatorById[id]; | ||
} | ||
|
||
function numOfValidatorsInFavorOfAnyClaimInEpoch( | ||
address appContract, | ||
uint256 lastProcessedBlockNumber | ||
) external view override returns (uint256) { | ||
return _getAllVotes(appContract, lastProcessedBlockNumber).inFavorCount; | ||
} | ||
|
||
function isValidatorInFavorOfAnyClaimInEpoch( | ||
address appContract, | ||
uint256 lastProcessedBlockNumber, | ||
uint256 id | ||
) external view override returns (bool) { | ||
return _getAllVotes(appContract, lastProcessedBlockNumber).inFavorById.get(id); | ||
} | ||
|
||
Comment on lines
+122
to
+136
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. then we can change naming of the functions to |
||
function numOfValidatorsInFavorOf( | ||
address appContract, | ||
uint256 lastProcessedBlockNumber, | ||
|
@@ -115,6 +154,18 @@ contract Quorum is IQuorum, AbstractConsensus { | |
.get(id); | ||
} | ||
|
||
/// @notice Get a `Votes` structure from storage from a given epoch. | ||
/// @param appContract The application contract address | ||
/// @param lastProcessedBlockNumber The number of the last processed block | ||
/// @return The `Votes` structure related to all claims in a given epoch | ||
function _getAllVotes(address appContract, uint256 lastProcessedBlockNumber) | ||
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. I have a thought about changing the naming of 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. I wanted to keep the diff as small as possible, without cosmetic changes, to make the PR review as easy as possible. Renamings can be applied in a later PR. |
||
internal | ||
view | ||
returns (Votes storage) | ||
{ | ||
return _allVotes[appContract][lastProcessedBlockNumber]; | ||
} | ||
|
||
/// @notice Get a `Votes` structure from storage from a given claim. | ||
/// @param appContract The application contract address | ||
/// @param lastProcessedBlockNumber The number of the last processed block | ||
|
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.
not sure if we should change the naming of variables inside the
Votes
struct to something likevoteCount
votedBy
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.
What is the problem with
inFavorCount
andinFavorById
?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.
The voteCount seems to be more suitable for this all votes scenario. But I’m ok with what it currently is too :)