Skip to content

Commit 9beb289

Browse files
committed
refactor: staking queue config now includes max value
1 parent b9a62d5 commit 9beb289

File tree

18 files changed

+1891
-57
lines changed

18 files changed

+1891
-57
lines changed

l1-contracts/.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,3 @@ gas_benchmark.diff
3636
/bench-out
3737

3838
/coverage
39-
40-
/script/registration_data.json

l1-contracts/foundry.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ gas_reports = [
2929
"RollupWithPreheating",
3030
"EmpireSlashingProposer",
3131
"TallySlashingProposer",
32+
"MultiAdder"
3233
]
3334

3435
remappings = [

l1-contracts/script/Migration.s.sol

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ import {TestERC20} from "@aztec/mock/TestERC20.sol";
1212

1313
struct RegistrationData {
1414
address attester;
15+
G1Point proofOfPossession;
1516
G1Point publicKeyInG1;
1617
G2Point publicKeyInG2;
17-
G1Point proofOfPossession;
1818
}
1919

2020
contract MigrationScript is Test {
@@ -46,7 +46,7 @@ contract MigrationScript is Test {
4646
function emulate() public {
4747
// If emulating we will deploy a rollup and other components ahead of time, otherwise
4848
// you should provide them by updating the values above.
49-
RollupBuilder builder = new RollupBuilder(ME).setUpdateOwnerships(false).deploy();
49+
RollupBuilder builder = new RollupBuilder(ME).setUpdateOwnerships(false).setCheckProofOfPossession(true).deploy();
5050

5151
INSTANCE = IInstance(address(builder.getConfig().rollup));
5252
STAKING_ASSET = builder.getConfig().testERC20;
@@ -57,6 +57,20 @@ contract MigrationScript is Test {
5757
migrate();
5858
}
5959

60+
function print() public {
61+
RegistrationData memory r = $registrations[0];
62+
emit log_named_address("Attester", r.attester);
63+
emit log_named_address("Withdrawer", WITHDRAWER);
64+
emit log_named_bytes32("PublicKeyInG1.x", bytes32(r.publicKeyInG1.x));
65+
emit log_named_bytes32("PublicKeyInG1.y", bytes32(r.publicKeyInG1.y));
66+
emit log_named_bytes32("PublicKeyInG2.x0", bytes32(r.publicKeyInG2.x0));
67+
emit log_named_bytes32("PublicKeyInG2.x1", bytes32(r.publicKeyInG2.x1));
68+
emit log_named_bytes32("PublicKeyInG2.y0", bytes32(r.publicKeyInG2.y0));
69+
emit log_named_bytes32("PublicKeyInG2.y1", bytes32(r.publicKeyInG2.y1));
70+
emit log_named_bytes32("ProofOfPossession.x", bytes32(r.proofOfPossession.x));
71+
emit log_named_bytes32("ProofOfPossession.y", bytes32(r.proofOfPossession.y));
72+
}
73+
6074
function migrate() public {
6175
uint256 activationThreshold = INSTANCE.getActivationThreshold();
6276

@@ -69,6 +83,8 @@ contract MigrationScript is Test {
6983
uint256 end = $registrations.length;
7084
uint256 batchSize = 10;
7185

86+
uint256 sizeBefore = INSTANCE.getActiveAttesterCount() + INSTANCE.getEntryQueueLength();
87+
7288
while (start < end) {
7389
uint256 batchEnd = start + batchSize;
7490
if (batchEnd > end) {
@@ -91,8 +107,11 @@ contract MigrationScript is Test {
91107
vm.startBroadcast(ME);
92108
ADDER.addValidators(args);
93109
vm.stopBroadcast();
94-
95110
start = batchEnd;
96111
}
112+
113+
uint256 sizeAfter = INSTANCE.getActiveAttesterCount() + INSTANCE.getEntryQueueLength();
114+
115+
assertGe(sizeAfter, sizeBefore + end);
97116
}
98117
}

l1-contracts/script/registration_data.json

Lines changed: 1702 additions & 0 deletions
Large diffs are not rendered by default.

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@ struct StakingQueue {
3131
}
3232

3333
library StakingQueueLib {
34-
// This is a HARD CAP. We will never attempt to flush more than this number of validators,
35-
// because it starts to butt up against the block gas limit.
36-
uint256 public constant MAX_QUEUE_FLUSH_SIZE = 150;
37-
3834
function init(StakingQueue storage self) internal {
3935
self.first = 1;
4036
self.last = 1;

l1-contracts/src/core/libraries/compressed-data/StakingQueueConfig.sol

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,30 @@ type CompressedStakingQueueConfig is uint256;
2222
* possible to add validators. This can close the queue even if there are members in the validator set if a very high
2323
* `normalFlushSizeQuotient` is used.
2424
*
25-
* NOTE: We will NEVER flush more than `MAX_QUEUE_FLUSH_SIZE` validators: it is applied as a Max at the end of every
25+
* NOTE: We will NEVER flush more than `maxQueueFlushSize` validators: it is applied as a Max at the end of every
2626
* calculation.
27-
* This is to prevent a situation where flushing the queue would exceed the block gas limit.
27+
* This can be used to prevent a situation where flushing the queue would exceed the block gas limit.
2828
*/
2929
struct StakingQueueConfig {
3030
uint256 bootstrapValidatorSetSize;
3131
uint256 bootstrapFlushSize;
3232
uint256 normalFlushSizeMin;
3333
uint256 normalFlushSizeQuotient;
34+
uint256 maxQueueFlushSize;
3435
}
3536

3637
library StakingQueueConfigLib {
3738
using SafeCast for uint256;
3839

39-
uint256 private constant MASK_64BIT = 0xFFFFFFFFFFFFFFFF;
40+
uint256 private constant MASK_32BIT = 0xFFFFFFFF;
4041

4142
function compress(StakingQueueConfig memory _config) internal pure returns (CompressedStakingQueueConfig) {
4243
uint256 value = 0;
43-
value |= uint256(_config.normalFlushSizeQuotient.toUint64());
44-
value |= uint256(_config.normalFlushSizeMin.toUint64()) << 64;
45-
value |= uint256(_config.bootstrapFlushSize.toUint64()) << 128;
46-
value |= uint256(_config.bootstrapValidatorSetSize.toUint64()) << 192;
44+
value |= uint256(_config.maxQueueFlushSize.toUint32());
45+
value |= uint256(_config.normalFlushSizeQuotient.toUint32()) << 32;
46+
value |= uint256(_config.normalFlushSizeMin.toUint32()) << 64;
47+
value |= uint256(_config.bootstrapFlushSize.toUint32()) << 96;
48+
value |= uint256(_config.bootstrapValidatorSetSize.toUint32()) << 128;
4749

4850
return CompressedStakingQueueConfig.wrap(value);
4951
}
@@ -52,10 +54,11 @@ library StakingQueueConfigLib {
5254
uint256 value = CompressedStakingQueueConfig.unwrap(_compressedConfig);
5355

5456
return StakingQueueConfig({
55-
bootstrapValidatorSetSize: (value >> 192) & MASK_64BIT,
56-
bootstrapFlushSize: (value >> 128) & MASK_64BIT,
57-
normalFlushSizeMin: (value >> 64) & MASK_64BIT,
58-
normalFlushSizeQuotient: (value) & MASK_64BIT
57+
bootstrapValidatorSetSize: (value >> 128) & MASK_32BIT,
58+
bootstrapFlushSize: (value >> 96) & MASK_32BIT,
59+
normalFlushSizeMin: (value >> 64) & MASK_32BIT,
60+
normalFlushSizeQuotient: (value >> 32) & MASK_32BIT,
61+
maxQueueFlushSize: value & MASK_32BIT
5962
});
6063
}
6164
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ library StakingLib {
303303
* The function will revert if:
304304
* - The current epoch is before nextFlushableEpoch (max 1 flush per epoch). This limit:
305305
* 1. Controls validator set growth by only allowing a fixed number of additions per epoch (we can flush at
306-
* most MAX_QUEUE_FLUSH_SIZE validators at once - hence the limit)
306+
* most maxQueueFlushSize validators at once - hence the limit)
307307
* 2. Aligns with committee selection which happens once per epoch anyway
308308
* 3. Groups validator additions into epoch-sized chunks for efficient binary searches (fewer snapshots in
309309
* GSE)
@@ -509,7 +509,7 @@ library StakingLib {
509509
* 3. Normal phase: After the initial bootstrap and growth phases, returns a number proportional to the current
510510
* set size for conservative steady-state growth, unless constrained by configuration (`normalFlushSizeMin`).
511511
*
512-
* All phases are subject to a hard cap of `MAX_QUEUE_FLUSH_SIZE`.
512+
* All phases are subject to a hard cap of `maxQueueFlushSize`.
513513
*
514514
* The motivation for floodgates is that the whole system starts producing blocks with what is considered
515515
* a sufficiently decentralized set of validators.
@@ -536,14 +536,14 @@ library StakingLib {
536536

537537
// If growth:
538538
if (activeAttesterCount < config.bootstrapValidatorSetSize) {
539-
return Math.min(config.bootstrapFlushSize, StakingQueueLib.MAX_QUEUE_FLUSH_SIZE);
539+
return Math.min(config.bootstrapFlushSize, config.maxQueueFlushSize);
540540
}
541541
}
542542

543543
// If normal:
544544
return Math.min(
545545
Math.max(activeAttesterCount / config.normalFlushSizeQuotient, config.normalFlushSizeMin),
546-
StakingQueueLib.MAX_QUEUE_FLUSH_SIZE
546+
config.maxQueueFlushSize
547547
);
548548
}
549549

l1-contracts/src/mock/MultiAdder.sol

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct CheatDepositArgs {
1616

1717
interface IMultiAdder {
1818
function addValidators(CheatDepositArgs[] memory _args) external;
19+
function addValidators(CheatDepositArgs[] memory _args, bool _skipFlush) external;
1920
}
2021

2122
contract MultiAdder is IMultiAdder {
@@ -32,7 +33,11 @@ contract MultiAdder is IMultiAdder {
3233
stakingAsset.approve(address(STAKING), type(uint256).max);
3334
}
3435

35-
function addValidators(CheatDepositArgs[] memory _args) external override(IMultiAdder) {
36+
function addValidators(CheatDepositArgs[] memory _args) public override(IMultiAdder) {
37+
addValidators(_args, false);
38+
}
39+
40+
function addValidators(CheatDepositArgs[] memory _args, bool _skipFlush) public override(IMultiAdder) {
3641
require(msg.sender == OWNER, NotOwner());
3742
for (uint256 i = 0; i < _args.length; i++) {
3843
STAKING.deposit(
@@ -45,7 +50,7 @@ contract MultiAdder is IMultiAdder {
4550
);
4651
}
4752

48-
if (STAKING.getCurrentEpoch() >= STAKING.getNextFlushableEpoch()) {
53+
if (!_skipFlush && STAKING.getCurrentEpoch() >= STAKING.getNextFlushableEpoch()) {
4954
STAKING.flushEntryQueue();
5055
}
5156
}

l1-contracts/test/compression/StakingQueueConfig.t.sol

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,18 @@ contract StakingQueueConfigTest is Test {
1414
using StakingQueueConfigLib for CompressedStakingQueueConfig;
1515

1616
function test_compressAndDecompress(
17-
uint64 _bootstrapValidatorSetSize,
18-
uint64 _bootstrapFlushSize,
19-
uint64 _normalFlushSizeMin,
20-
uint64 _normalFlushSizeQuotient
17+
uint32 _bootstrapValidatorSetSize,
18+
uint32 _bootstrapFlushSize,
19+
uint32 _normalFlushSizeMin,
20+
uint32 _normalFlushSizeQuotient,
21+
uint32 _maxQueueFlushSize
2122
) public pure {
2223
StakingQueueConfig memory a = StakingQueueConfig({
2324
bootstrapValidatorSetSize: _bootstrapValidatorSetSize,
2425
bootstrapFlushSize: _bootstrapFlushSize,
2526
normalFlushSizeMin: _normalFlushSizeMin,
26-
normalFlushSizeQuotient: _normalFlushSizeQuotient
27+
normalFlushSizeQuotient: _normalFlushSizeQuotient,
28+
maxQueueFlushSize: _maxQueueFlushSize
2729
});
2830

2931
CompressedStakingQueueConfig b = a.compress();
@@ -33,5 +35,6 @@ contract StakingQueueConfigTest is Test {
3335
assertEq(c.bootstrapFlushSize, a.bootstrapFlushSize, "Bootstrap flush size");
3436
assertEq(c.normalFlushSizeMin, a.normalFlushSizeMin, "Normal flush size min");
3537
assertEq(c.normalFlushSizeQuotient, a.normalFlushSizeQuotient, "Normal flush size quotient");
38+
assertEq(c.maxQueueFlushSize, a.maxQueueFlushSize, "Max queue flush size");
3639
}
3740
}

l1-contracts/test/harnesses/TestConstants.sol

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ library TestConstants {
3131
uint256 internal constant AZTEC_ENTRY_QUEUE_FLUSH_SIZE_QUOTIENT = 2;
3232
uint256 internal constant AZTEC_ENTRY_QUEUE_BOOTSTRAP_VALIDATOR_SET_SIZE = 0;
3333
uint256 internal constant AZTEC_ENTRY_QUEUE_BOOTSTRAP_FLUSH_SIZE = 0;
34+
uint256 internal constant AZTEC_ENTRY_QUEUE_MAX_FLUSH_SIZE = 480;
3435
uint256 internal constant AZTEC_EXIT_DELAY_SECONDS = 2 * 24 * 60 * 60; // 2 days
3536
EthValue internal constant AZTEC_PROVING_COST_PER_MANA = EthValue.wrap(100);
3637

@@ -81,7 +82,8 @@ library TestConstants {
8182
bootstrapValidatorSetSize: AZTEC_ENTRY_QUEUE_BOOTSTRAP_VALIDATOR_SET_SIZE,
8283
bootstrapFlushSize: AZTEC_ENTRY_QUEUE_BOOTSTRAP_FLUSH_SIZE,
8384
normalFlushSizeMin: AZTEC_ENTRY_QUEUE_FLUSH_SIZE_MIN,
84-
normalFlushSizeQuotient: AZTEC_ENTRY_QUEUE_FLUSH_SIZE_QUOTIENT
85+
normalFlushSizeQuotient: AZTEC_ENTRY_QUEUE_FLUSH_SIZE_QUOTIENT,
86+
maxQueueFlushSize: AZTEC_ENTRY_QUEUE_MAX_FLUSH_SIZE
8587
});
8688
}
8789

0 commit comments

Comments
 (0)