Skip to content

Commit 6a193c2

Browse files
feat: protocol param for max deposits per epoch (#156)
This adds a protocol parameter for limiting the maximum number of deposits per epoch. This replaces a constant value that was set to 3. The new max_deposits_per_epoch protocol param defaults to 3 and can be set to any value between 0 and 256.
1 parent f1a4409 commit 6a193c2

23 files changed

Lines changed: 457 additions & 25 deletions

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ members = [ "application", "node", "rpc", "types", "finalizer", "orchestrator",
33
resolver = "3"
44

55
[workspace.package]
6-
version = "0.0.1-alpha"
6+
version = "0.0.2-alpha"
77
edition = "2024"
88

99
[workspace.dependencies]

example_genesis.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ validator_minimum_stake = 32000000000
1010
validator_maximum_stake = 32000000000
1111
blocks_per_epoch = 10000
1212
allowed_timestamp_future_ms = 10000
13+
max_deposits_per_epoch = 3
1314

1415
[[validators]]
1516
node_public_key = "1be3cb06d7cc347602421fb73838534e4b54934e28959de98906d120d0799ef2"

finalizer/src/actor.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,10 @@ impl<
10101010
let address = self.canonical_state.get_treasury_address();
10111011
let _ = sender.send(ConsensusStateResponse::TreasuryAddress(address));
10121012
}
1013+
ConsensusStateRequest::GetMaxDepositsPerEpoch => {
1014+
let value = self.canonical_state.get_max_deposits_per_epoch();
1015+
let _ = sender.send(ConsensusStateResponse::MaxDepositsPerEpoch(value));
1016+
}
10131017
ConsensusStateRequest::GetEpochBounds(epoch) => {
10141018
let bounds = self
10151019
.canonical_state
@@ -1649,7 +1653,7 @@ async fn process_execution_requests<
16491653
consts: &ProtocolConsts,
16501654
) {
16511655
if is_penultimate_block_of_epoch(state.get_epocher(), new_height) {
1652-
for _ in 0..consts.validator_onboarding_limit_per_block {
1656+
for _ in 0..state.get_max_deposits_per_epoch() as usize {
16531657
if let Some(request) = state.pop_deposit() {
16541658
let node_pubkey_bytes: [u8; 32] = request.node_pubkey.as_ref().try_into().unwrap();
16551659

finalizer/src/config.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ use tokio_util::sync::CancellationToken;
77

88
/// Fixed protocol-level constants governing validator lifecycle.
99
pub struct ProtocolConsts {
10-
/// The maximum number of validators that will be onboarded at the same time.
11-
pub validator_onboarding_limit_per_block: usize,
1210
/// Number of epochs to wait before activating validators after deposit.
1311
pub validator_num_warm_up_epochs: u64,
1412
/// Number of epochs after a withdrawal request until the payout.

finalizer/src/ingress.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,24 @@ impl<S: Scheme<B::Digest>, B: ConsensusBlock> FinalizerMailbox<S, B> {
315315
address
316316
}
317317

318+
pub async fn get_max_deposits_per_epoch(&self) -> u64 {
319+
let (response, rx) = oneshot::channel();
320+
let request = ConsensusStateRequest::GetMaxDepositsPerEpoch;
321+
let _ = self
322+
.sender
323+
.clone()
324+
.send(FinalizerMessage::QueryState { request, response })
325+
.await;
326+
327+
let res = rx
328+
.await
329+
.expect("consensus state query response sender dropped");
330+
let ConsensusStateResponse::MaxDepositsPerEpoch(value) = res else {
331+
unreachable!("request and response variants must match");
332+
};
333+
value
334+
}
335+
318336
pub async fn get_epoch_bounds(&self, epoch: u64) -> Option<(u64, u64)> {
319337
let (response, rx) = oneshot::channel();
320338
let request = ConsensusStateRequest::GetEpochBounds(epoch);

finalizer/src/tests/fork_handling.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ fn create_test_initial_state(genesis_hash: [u8; 32], epoch_length: NonZeroU64) -
120120
epoch_length,
121121
10_000,
122122
Address::ZERO,
123+
10,
123124
);
124125
state.set_validator_accounts(validator_accounts);
125126
state
@@ -147,7 +148,6 @@ fn test_orphaned_block_processed_when_parent_arrives() {
147148
engine_client: MockEngineClient::new(),
148149
oracle: MockNetworkOracle,
149150
protocol_consts: ProtocolConsts {
150-
validator_onboarding_limit_per_block: 10,
151151
validator_num_warm_up_epochs: 2,
152152
validator_withdrawal_num_epochs: 2,
153153
},
@@ -229,7 +229,6 @@ fn test_multiple_forks_tracked() {
229229
engine_client: MockEngineClient::new(),
230230
oracle: MockNetworkOracle,
231231
protocol_consts: ProtocolConsts {
232-
validator_onboarding_limit_per_block: 10,
233232
validator_num_warm_up_epochs: 2,
234233
validator_withdrawal_num_epochs: 2,
235234
},
@@ -312,7 +311,6 @@ fn test_dead_fork_block_discarded() {
312311
engine_client: MockEngineClient::new(),
313312
oracle: MockNetworkOracle,
314313
protocol_consts: ProtocolConsts {
315-
validator_onboarding_limit_per_block: 10,
316314
validator_num_warm_up_epochs: 2,
317315
validator_withdrawal_num_epochs: 2,
318316
},
@@ -411,7 +409,6 @@ fn test_fork_states_pruned_after_finalization() {
411409
engine_client: MockEngineClient::new(),
412410
oracle: MockNetworkOracle,
413411
protocol_consts: ProtocolConsts {
414-
validator_onboarding_limit_per_block: 10,
415412
validator_num_warm_up_epochs: 2,
416413
validator_withdrawal_num_epochs: 2,
417414
},
@@ -529,7 +526,6 @@ fn test_orphaned_blocks_pruned_after_finalization() {
529526
engine_client: MockEngineClient::new(),
530527
oracle: MockNetworkOracle,
531528
protocol_consts: ProtocolConsts {
532-
validator_onboarding_limit_per_block: 10,
533529
validator_num_warm_up_epochs: 2,
534530
validator_withdrawal_num_epochs: 2,
535531
},
@@ -639,7 +635,6 @@ fn test_fork_state_reused_when_notarized_then_finalized() {
639635
engine_client: MockEngineClient::new(),
640636
oracle: MockNetworkOracle,
641637
protocol_consts: ProtocolConsts {
642-
validator_onboarding_limit_per_block: 10,
643638
validator_num_warm_up_epochs: 2,
644639
validator_withdrawal_num_epochs: 2,
645640
},
@@ -745,7 +740,6 @@ fn test_competing_fork_pruned_on_finalization() {
745740
engine_client: MockEngineClient::new(),
746741
oracle: MockNetworkOracle,
747742
protocol_consts: ProtocolConsts {
748-
validator_onboarding_limit_per_block: 10,
749743
validator_num_warm_up_epochs: 2,
750744
validator_withdrawal_num_epochs: 2,
751745
},

finalizer/src/tests/state_queries.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ fn create_test_initial_state(genesis_hash: [u8; 32], epoch_length: NonZeroU64) -
126126
epoch_length,
127127
10_000,
128128
Address::ZERO,
129+
10,
129130
);
130131
state.set_validator_accounts(validator_accounts);
131132
state
@@ -156,7 +157,6 @@ fn test_get_latest_epoch() {
156157
engine_client: MockEngineClient::new(),
157158
oracle: MockNetworkOracle,
158159
protocol_consts: ProtocolConsts {
159-
validator_onboarding_limit_per_block: 10,
160160
validator_num_warm_up_epochs: 2,
161161
validator_withdrawal_num_epochs: 2,
162162
},
@@ -266,7 +266,6 @@ fn test_get_epoch_genesis_hash() {
266266
engine_client: MockEngineClient::new(),
267267
oracle: MockNetworkOracle,
268268
protocol_consts: ProtocolConsts {
269-
validator_onboarding_limit_per_block: 10,
270269
validator_num_warm_up_epochs: 2,
271270
validator_withdrawal_num_epochs: 2,
272271
},
@@ -364,7 +363,6 @@ fn test_get_aux_data_from_canonical_chain() {
364363
engine_client: MockEngineClient::new(),
365364
oracle: MockNetworkOracle,
366365
protocol_consts: ProtocolConsts {
367-
validator_onboarding_limit_per_block: 10,
368366
validator_num_warm_up_epochs: 2,
369367
validator_withdrawal_num_epochs: 2,
370368
},
@@ -436,7 +434,6 @@ fn test_get_aux_data_returns_none_for_invalid_parent() {
436434
engine_client: MockEngineClient::new(),
437435
oracle: MockNetworkOracle,
438436
protocol_consts: ProtocolConsts {
439-
validator_onboarding_limit_per_block: 10,
440437
validator_num_warm_up_epochs: 2,
441438
validator_withdrawal_num_epochs: 2,
442439
},

finalizer/src/tests/syncing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ fn create_test_initial_state(genesis_hash: [u8; 32], epoch_length: NonZeroU64) -
120120
epoch_length,
121121
10_000,
122122
Address::ZERO,
123+
10,
123124
);
124125
state.set_validator_accounts(validator_accounts);
125126
state
@@ -146,7 +147,6 @@ fn create_checkpoint_initial_state(
146147

147148
fn default_protocol_consts() -> ProtocolConsts {
148149
ProtocolConsts {
149-
validator_onboarding_limit_per_block: 10,
150150
validator_num_warm_up_epochs: 2,
151151
validator_withdrawal_num_epochs: 2,
152152
}

finalizer/src/tests/validator_lifecycle.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ fn create_test_initial_state(genesis_hash: [u8; 32], epoch_length: NonZeroU64) -
126126
epoch_length,
127127
10_000,
128128
Address::ZERO,
129+
10,
129130
);
130131
state.set_validator_accounts(validator_accounts);
131132
state
@@ -165,7 +166,6 @@ fn test_validator_exit_triggers_cancellation() {
165166
engine_client: MockEngineClient::new(),
166167
oracle: MockNetworkOracle,
167168
protocol_consts: ProtocolConsts {
168-
validator_onboarding_limit_per_block: 10,
169169
validator_num_warm_up_epochs: 2,
170170
validator_withdrawal_num_epochs: 2,
171171
},

node/src/args.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,7 @@ fn get_initial_state(
665665
epoch_length,
666666
genesis.allowed_timestamp_future_ms,
667667
treasury_address,
668+
genesis.max_deposits_per_epoch,
668669
);
669670
// Add the genesis nodes to the consensus state with the minimum stake balance.
670671
for validator in genesis_committee {

0 commit comments

Comments
 (0)