Skip to content

Commit 3d60871

Browse files
committed
No msg.sender checks in validator selection
1 parent da69a1b commit 3d60871

File tree

8 files changed

+37
-25
lines changed

8 files changed

+37
-25
lines changed

l1-contracts/src/core/Rollup.sol

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,16 +183,17 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore {
183183
*
184184
* @param _ts - The timestamp to check
185185
* @param _archive - The archive to check (should be the latest archive)
186+
* @param _who - The address to check
186187
*
187188
* @return uint256 - The slot at the given timestamp
188189
* @return uint256 - The block number at the given timestamp
189190
*/
190-
function canProposeAtTime(Timestamp _ts, bytes32 _archive)
191+
function canProposeAtTime(Timestamp _ts, bytes32 _archive, address _who)
191192
external
192193
override(IRollup)
193194
returns (Slot, uint256)
194195
{
195-
return ExtRollupLib2.canProposeAtTime(_ts, _archive);
196+
return ExtRollupLib2.canProposeAtTime(_ts, _archive, _who);
196197
}
197198

198199
function getTargetCommitteeSize() external view override(IValidatorSelection) returns (uint256) {

l1-contracts/src/core/interfaces/IRollup.sol

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,9 @@ interface IRollup is IRollupCore, IHaveVersion {
155155
BlockHeaderValidationFlags memory _flags
156156
) external;
157157

158-
function canProposeAtTime(Timestamp _ts, bytes32 _archive) external returns (Slot, uint256);
158+
function canProposeAtTime(Timestamp _ts, bytes32 _archive, address _who)
159+
external
160+
returns (Slot, uint256);
159161

160162
function getTips() external view returns (ChainTips memory);
161163

l1-contracts/src/core/libraries/Errors.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ library Errors {
102102
// Sequencer Selection (ValidatorSelection)
103103
error ValidatorSelection__EpochNotSetup(); // 0x10816cae
104104
error ValidatorSelection__InvalidProposer(address expected, address actual); // 0xa8843a68
105+
error ValidatorSelection__MissingProposerSignature(address proposer, uint256 index);
105106
error ValidatorSelection__InvalidDeposit(address attester, address proposer); // 0x533169bd
106107
error ValidatorSelection__InsufficientAttestations(uint256 minimumNeeded, uint256 provided); // 0xaf47297f
107108
error ValidatorSelection__InvalidCommitteeCommitment(bytes32 reconstructed, bytes32 expected); // 0xca8d5954

l1-contracts/src/core/libraries/rollup/ExtRollupLib2.sol

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,11 @@ library ExtRollupLib2 {
7676
return StakingLib.trySlash(_attester, _amount);
7777
}
7878

79-
function canProposeAtTime(Timestamp _ts, bytes32 _archive) external returns (Slot, uint256) {
80-
return ValidatorSelectionLib.canProposeAtTime(_ts, _archive);
79+
function canProposeAtTime(Timestamp _ts, bytes32 _archive, address _who)
80+
external
81+
returns (Slot, uint256)
82+
{
83+
return ValidatorSelectionLib.canProposeAtTime(_ts, _archive, _who);
8184
}
8285

8386
function getCommitteeAt(Epoch _epoch) external returns (address[] memory) {

l1-contracts/src/core/libraries/rollup/ValidatorSelectionLib.sol

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,15 +130,10 @@ library ValidatorSelectionLib {
130130
setCachedProposer(_slot, proposer, proposerIndex);
131131
}
132132

133-
// If the proposer is who sent the tx, we're good
134-
if (proposer == msg.sender) {
135-
return;
136-
}
137-
138133
// Check if the proposer has signed, if not, fail
139134
bool hasProposerSignature = _attestations.isSignature(proposerIndex);
140135
if (!hasProposerSignature) {
141-
revert Errors.ValidatorSelection__InvalidProposer(proposer, msg.sender);
136+
revert Errors.ValidatorSelection__MissingProposerSignature(proposer, proposerIndex);
142137
}
143138

144139
// Check if the signature is correct
@@ -358,7 +353,10 @@ library ValidatorSelectionLib {
358353
}
359354
}
360355

361-
function canProposeAtTime(Timestamp _ts, bytes32 _archive) internal returns (Slot, uint256) {
356+
function canProposeAtTime(Timestamp _ts, bytes32 _archive, address _who)
357+
internal
358+
returns (Slot, uint256)
359+
{
362360
Slot slot = _ts.slotFromTimestamp();
363361
RollupStore storage rollupStore = STFLib.getStorage();
364362

@@ -373,9 +371,7 @@ library ValidatorSelectionLib {
373371
require(tipArchive == _archive, Errors.Rollup__InvalidArchive(tipArchive, _archive));
374372

375373
(address proposer,) = getProposerAt(slot);
376-
require(
377-
proposer == msg.sender, Errors.ValidatorSelection__InvalidProposer(proposer, msg.sender)
378-
);
374+
require(proposer == _who, Errors.ValidatorSelection__InvalidProposer(proposer, _who));
379375

380376
return (slot, pendingBlockNumber + 1);
381377
}

l1-contracts/test/RollupGetters.t.sol

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,7 @@ contract RollupShouldBeGetters is ValidatorSelectionTestBase {
153153

154154
vm.record();
155155

156-
vm.prank(proposer);
157-
rollup.canProposeAtTime(t, log.archive);
156+
rollup.canProposeAtTime(t, log.archive, proposer);
158157

159158
(, bytes32[] memory writes) = vm.accesses(address(rollup));
160159
assertEq(writes.length, 0, "No writes should be done");

l1-contracts/test/validator-selection/ValidatorSelection.t.sol

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ contract ValidatorSelectionTest is ValidatorSelectionTestBase {
307307
function testProposerAttestationNotProvided() public setup(4, 4) progressEpochs(2) {
308308
_testBlock(
309309
"mixed_block_1",
310-
Errors.ValidatorSelection__InvalidProposer.selector,
310+
Errors.ValidatorSelection__MissingProposerSignature.selector,
311311
3,
312312
4,
313313
TestFlags({
@@ -498,17 +498,26 @@ contract ValidatorSelectionTest is ValidatorSelectionTestBase {
498498
bytes32 digest = ProposeLib.digest(ree.proposePayload);
499499

500500
{
501-
uint256 signaturesCollected = 0;
501+
uint256 signersIndex = 0;
502+
uint256 signaturesCollected = _flags.proposerAttestationNotProvided ? 0 : 1;
502503
for (uint256 i = 0; i < ree.attestationsCount; i++) {
503-
if (
504-
(signaturesCollected >= _signatureCount)
505-
|| (ree.committee[i] == ree.proposer && _flags.proposerAttestationNotProvided)
506-
) {
504+
if ((ree.committee[i] == ree.proposer && _flags.proposerAttestationNotProvided)) {
505+
// If the proposer is not providing an attestation, we skip it
506+
ree.attestations[i] = _createEmptyAttestation(ree.committee[i]);
507+
} else if ((ree.committee[i] == ree.proposer)) {
508+
// If the proposer is providing an attestation, set it
509+
ree.attestations[i] = _createAttestation(ree.committee[i], digest);
510+
ree.signers[signersIndex] = ree.committee[i];
511+
signersIndex++;
512+
} else if ((signaturesCollected >= _signatureCount)) {
513+
// No need to create more signatures if we have collected enough
507514
ree.attestations[i] = _createEmptyAttestation(ree.committee[i]);
508515
} else {
516+
// Create an attestation for the committee member and add them to the signers
509517
ree.attestations[i] = _createAttestation(ree.committee[i], digest);
510-
ree.signers[signaturesCollected] = ree.committee[i];
518+
ree.signers[signersIndex] = ree.committee[i];
511519
signaturesCollected++;
520+
signersIndex++;
512521
}
513522
}
514523
}

yarn-project/ethereum/src/contracts/rollup.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,7 @@ export class RollupContract {
500500
}
501501
const latestBlock = await this.client.getBlock();
502502
const timeOfNextL1Slot = latestBlock.timestamp + slotDuration;
503+
const who = typeof account === 'string' ? account : account.address;
503504

504505
try {
505506
const {
@@ -508,7 +509,7 @@ export class RollupContract {
508509
address: this.address,
509510
abi: RollupAbi,
510511
functionName: 'canProposeAtTime',
511-
args: [timeOfNextL1Slot, `0x${archive.toString('hex')}`],
512+
args: [timeOfNextL1Slot, `0x${archive.toString('hex')}`, who],
512513
account,
513514
});
514515

0 commit comments

Comments
 (0)