Skip to content

Commit ca2bd31

Browse files
committed
apollo_consensus_orchestrator: use the config manager client to update consensus context config
1 parent 63c6c8f commit ca2bd31

File tree

13 files changed

+213
-4
lines changed

13 files changed

+213
-4
lines changed

Cargo.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/apollo_config_manager/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ apollo_config.workspace = true
1616
apollo_config_manager_config.workspace = true
1717
apollo_config_manager_types.workspace = true
1818
apollo_consensus_config.workspace = true
19+
apollo_consensus_orchestrator_config.workspace = true
1920
apollo_infra.workspace = true
2021
apollo_mempool_config.workspace = true
2122
apollo_metrics.workspace = true

crates/apollo_config_manager/src/config_manager.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use apollo_config_manager_config::config::ConfigManagerConfig;
22
use apollo_config_manager_types::communication::{ConfigManagerRequest, ConfigManagerResponse};
33
use apollo_config_manager_types::config_manager_types::ConfigManagerResult;
44
use apollo_consensus_config::config::ConsensusDynamicConfig;
5+
use apollo_consensus_orchestrator_config::config::ContextDynamicConfig;
56
use apollo_infra::component_definitions::{ComponentRequestHandler, ComponentStarter};
67
use apollo_mempool_config::config::MempoolDynamicConfig;
78
use apollo_node_config::node_config::NodeDynamicConfig;
@@ -38,6 +39,10 @@ impl ConfigManager {
3839
Ok(self.latest_node_dynamic_config.consensus_dynamic_config.as_ref().unwrap().clone())
3940
}
4041

42+
pub(crate) fn get_context_dynamic_config(&self) -> ConfigManagerResult<ContextDynamicConfig> {
43+
Ok(self.latest_node_dynamic_config.context_dynamic_config.as_ref().unwrap().clone())
44+
}
45+
4146
pub(crate) fn get_mempool_dynamic_config(&self) -> ConfigManagerResult<MempoolDynamicConfig> {
4247
Ok(self.latest_node_dynamic_config.mempool_dynamic_config.as_ref().unwrap().clone())
4348
}
@@ -54,6 +59,9 @@ impl ComponentRequestHandler<ConfigManagerRequest, ConfigManagerResponse> for Co
5459
self.get_consensus_dynamic_config(),
5560
)
5661
}
62+
ConfigManagerRequest::GetContextDynamicConfig => {
63+
ConfigManagerResponse::GetContextDynamicConfig(self.get_context_dynamic_config())
64+
}
5765
ConfigManagerRequest::GetMempoolDynamicConfig => {
5866
ConfigManagerResponse::GetMempoolDynamicConfig(self.get_mempool_dynamic_config())
5967
}

crates/apollo_config_manager_types/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ workspace = true
1010

1111
[dependencies]
1212
apollo_consensus_config.workspace = true
13+
apollo_consensus_orchestrator_config.workspace = true
1314
apollo_infra.workspace = true
1415
apollo_mempool_config.workspace = true
1516
apollo_metrics.workspace = true

crates/apollo_config_manager_types/src/communication.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::sync::Arc;
22

33
use apollo_consensus_config::config::ConsensusDynamicConfig;
4+
use apollo_consensus_orchestrator_config::config::ContextDynamicConfig;
45
use apollo_infra::component_client::{ClientError, LocalComponentClient, RemoteComponentClient};
56
use apollo_infra::component_definitions::{ComponentClient, PrioritizedRequest, RequestWrapper};
67
use apollo_infra::{impl_debug_for_infra_requests_and_responses, impl_labeled_request};
@@ -32,6 +33,8 @@ pub trait ConfigManagerClient: Send + Sync {
3233
&self,
3334
) -> ConfigManagerClientResult<ConsensusDynamicConfig>;
3435

36+
async fn get_context_dynamic_config(&self) -> ConfigManagerClientResult<ContextDynamicConfig>;
37+
3538
async fn get_mempool_dynamic_config(&self) -> ConfigManagerClientResult<MempoolDynamicConfig>;
3639

3740
async fn set_node_dynamic_config(
@@ -48,6 +51,7 @@ pub trait ConfigManagerClient: Send + Sync {
4851
)]
4952
pub enum ConfigManagerRequest {
5053
GetConsensusDynamicConfig,
54+
GetContextDynamicConfig,
5155
GetMempoolDynamicConfig,
5256
SetNodeDynamicConfig(NodeDynamicConfig),
5357
}
@@ -65,6 +69,7 @@ generate_permutation_labels! {
6569
#[derive(Clone, Serialize, Deserialize, AsRefStr)]
6670
pub enum ConfigManagerResponse {
6771
GetConsensusDynamicConfig(ConfigManagerResult<ConsensusDynamicConfig>),
72+
GetContextDynamicConfig(ConfigManagerResult<ContextDynamicConfig>),
6873
GetMempoolDynamicConfig(ConfigManagerResult<MempoolDynamicConfig>),
6974
SetNodeDynamicConfig(ConfigManagerResult<()>),
7075
}
@@ -96,6 +101,17 @@ where
96101
)
97102
}
98103

104+
async fn get_context_dynamic_config(&self) -> ConfigManagerClientResult<ContextDynamicConfig> {
105+
let request = ConfigManagerRequest::GetContextDynamicConfig;
106+
handle_all_response_variants!(
107+
ConfigManagerResponse,
108+
GetContextDynamicConfig,
109+
ConfigManagerClientError,
110+
ConfigManagerError,
111+
Direct
112+
)
113+
}
114+
99115
async fn get_mempool_dynamic_config(&self) -> ConfigManagerClientResult<MempoolDynamicConfig> {
100116
let request = ConfigManagerRequest::GetMempoolDynamicConfig;
101117
handle_all_response_variants!(

crates/apollo_consensus_manager/src/consensus_manager.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ impl ConsensusManager {
144144
let consensus_context = self.create_sequencer_consensus_context(
145145
&votes_broadcast_channels,
146146
outbound_internal_sender,
147+
self.config_manager_client.clone(),
147148
);
148149

149150
let current_height =
@@ -264,6 +265,7 @@ impl ConsensusManager {
264265
&self,
265266
votes_broadcast_channels: &BroadcastTopicChannels<Vote>,
266267
outbound_internal_sender: mpsc::Sender<(HeightAndRound, mpsc::Receiver<ProposalPart>)>,
268+
config_manager_client: SharedConfigManagerClient,
267269
) -> SequencerConsensusContext {
268270
SequencerConsensusContext::new(
269271
self.config.context_config.clone(),
@@ -282,6 +284,7 @@ impl ConsensusManager {
282284
clock: Arc::new(DefaultClock),
283285
outbound_proposal_sender: outbound_internal_sender,
284286
vote_broadcast_client: votes_broadcast_channels.broadcast_topic_client.clone(),
287+
config_manager_client: Some(Arc::clone(&config_manager_client)),
285288
},
286289
)
287290
}

crates/apollo_consensus_orchestrator/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ apollo_batcher.workspace = true
1111
apollo_batcher_types.workspace = true
1212
apollo_class_manager_types.workspace = true
1313
apollo_config.workspace = true
14+
apollo_config_manager_types.workspace = true
1415
apollo_consensus.workspace = true
1516
apollo_consensus_orchestrator_config.workspace = true
1617
apollo_infra_utils.workspace = true
@@ -52,6 +53,7 @@ apollo_batcher.workspace = true
5253
apollo_batcher_types = { workspace = true, features = ["testing"] }
5354
apollo_class_manager_types = { workspace = true, features = ["testing"] }
5455
apollo_config.workspace = true
56+
apollo_config_manager_types = { workspace = true, features = ["testing"] }
5557
apollo_infra = { workspace = true, features = ["testing"] }
5658
apollo_infra_utils = { workspace = true, features = ["testing"] }
5759
apollo_l1_gas_price_types = { workspace = true, features = ["testing"] }

crates/apollo_consensus_orchestrator/src/sequencer_consensus_context.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use apollo_batcher_types::batcher_types::{
1818
};
1919
use apollo_batcher_types::communication::BatcherClient;
2020
use apollo_class_manager_types::transaction_converter::TransactionConverterTrait;
21+
use apollo_config_manager_types::communication::SharedConfigManagerClient;
2122
use apollo_consensus::types::{
2223
ConsensusContext,
2324
ConsensusError,
@@ -177,6 +178,7 @@ pub struct SequencerConsensusContextDeps {
177178
pub outbound_proposal_sender: mpsc::Sender<(HeightAndRound, mpsc::Receiver<ProposalPart>)>,
178179
// Used to broadcast votes to other consensus nodes.
179180
pub vote_broadcast_client: BroadcastTopicClient<Vote>,
181+
pub config_manager_client: Option<SharedConfigManagerClient>,
180182
}
181183

182184
impl SequencerConsensusContext {
@@ -711,6 +713,10 @@ impl ConsensusContext for SequencerConsensusContext {
711713
}
712714

713715
async fn set_height_and_round(&mut self, height: BlockNumber, round: Round) {
716+
if let Some(config_manager_client) = self.deps.config_manager_client.clone() {
717+
self.config.dynamic_config =
718+
config_manager_client.get_context_dynamic_config().await.unwrap();
719+
}
714720
if self.current_height.map(|h| height > h).unwrap_or(true) {
715721
self.current_height = Some(height);
716722
assert_eq!(round, 0);
@@ -723,13 +729,25 @@ impl ConsensusContext for SequencerConsensusContext {
723729
self.batcher_start_height(height).await;
724730
return;
725731
}
726-
assert_eq!(Some(height), self.current_height);
732+
assert_eq!(
733+
Some(height),
734+
self.current_height,
735+
"height {} is not equal to current height {:?}",
736+
height,
737+
self.current_height
738+
);
727739
if round == self.current_round {
728740
return;
729741
}
730-
assert!(round > self.current_round);
742+
assert!(
743+
round > self.current_round,
744+
"round {} is not greater than current round {}",
745+
round,
746+
self.current_round
747+
);
731748
self.interrupt_active_proposal().await;
732749
self.current_round = round;
750+
733751
let mut to_process = None;
734752
while let Some(entry) = self.queued_proposals.first_entry() {
735753
match self.current_round.cmp(entry.key()) {

crates/apollo_consensus_orchestrator/src/sequencer_consensus_context_test.rs

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::sync::Arc;
44
use apollo_batcher_types::batcher_types::{CentralObjects, DecisionReachedResponse};
55
use apollo_batcher_types::communication::BatcherClientError;
66
use apollo_batcher_types::errors::BatcherError;
7+
use apollo_config_manager_types::communication::MockConfigManagerClient;
78
use apollo_consensus::types::{ConsensusContext, Round};
89
use apollo_consensus_orchestrator_config::config::{ContextConfig, ContextDynamicConfig};
910
use apollo_infra::component_client::ClientError;
@@ -1024,3 +1025,121 @@ async fn override_prices_behavior(
10241025
);
10251026
}
10261027
}
1028+
1029+
#[tokio::test]
1030+
async fn change_gas_price_overrides() {
1031+
let (mut deps, mut network) = create_test_and_network_deps();
1032+
1033+
// Validate two blocks, between the first and the second we will change the gas price overrides.
1034+
// After the second block we will do another round with another dynamic config change.
1035+
deps.setup_deps_for_validate(BlockNumber(0), INTERNAL_TX_BATCH.len(), 3);
1036+
deps.setup_deps_for_build(BlockNumber(2), INTERNAL_TX_BATCH.len(), 1);
1037+
1038+
// set up batcher decision_reached
1039+
deps.batcher.expect_decision_reached().times(2).returning(|_| {
1040+
Ok(DecisionReachedResponse {
1041+
state_diff: ThinStateDiff::default(),
1042+
l2_gas_used: GasAmount::default(),
1043+
central_objects: CentralObjects::default(),
1044+
block_header_commitments: BlockHeaderCommitments::default(),
1045+
})
1046+
});
1047+
1048+
// required for decision reached flow
1049+
deps.state_sync_client.expect_add_new_block().times(2).returning(|_| Ok(()));
1050+
// We never wrote block 0.
1051+
deps.state_sync_client.expect_get_latest_block_number().returning(|| Ok(None));
1052+
deps.cende_ambassador.expect_prepare_blob_for_next_height().times(2).returning(|_| Ok(()));
1053+
1054+
let mut context = deps.build_context();
1055+
1056+
// Validate block number 0.
1057+
context.set_height_and_round(BlockNumber(0), 0).await;
1058+
1059+
let content_receiver =
1060+
send_proposal_to_validator_context(&mut context, block_info(BlockNumber(0))).await;
1061+
let fin_receiver =
1062+
context.validate_proposal(ProposalInit::default(), TIMEOUT, content_receiver).await;
1063+
1064+
let proposal_commitment = fin_receiver.await.unwrap();
1065+
assert_eq!(proposal_commitment.0, STATE_DIFF_COMMITMENT.0.0);
1066+
1067+
// Decision reached
1068+
context.decision_reached(BlockNumber(0), proposal_commitment).await.unwrap();
1069+
1070+
let new_dynamic_config = ContextDynamicConfig {
1071+
override_l2_gas_price_fri: Some(ODDLY_SPECIFIC_L2_GAS_PRICE),
1072+
..Default::default()
1073+
};
1074+
let mut config_manager_client = MockConfigManagerClient::new();
1075+
config_manager_client
1076+
.expect_get_context_dynamic_config()
1077+
.returning(move || Ok(new_dynamic_config.clone()));
1078+
config_manager_client.expect_set_node_dynamic_config().returning(|_| Ok(()));
1079+
context.deps.config_manager_client = Some(Arc::new(config_manager_client));
1080+
1081+
let mut modified_block_info = block_info(BlockNumber(1));
1082+
modified_block_info.l2_gas_price_fri = GasPrice(ODDLY_SPECIFIC_L2_GAS_PRICE);
1083+
1084+
// Validate block number 1.
1085+
context.set_height_and_round(BlockNumber(1), 0).await;
1086+
let init = ProposalInit { height: BlockNumber(1), ..Default::default() };
1087+
1088+
let content_receiver =
1089+
send_proposal_to_validator_context(&mut context, modified_block_info).await;
1090+
let fin_receiver = context.validate_proposal(init, TIMEOUT, content_receiver).await;
1091+
let proposal_commitment = fin_receiver.await.unwrap();
1092+
assert_eq!(proposal_commitment.0, STATE_DIFF_COMMITMENT.0.0);
1093+
1094+
// Validate block number 1, round 1.
1095+
let new_dynamic_config = ContextDynamicConfig {
1096+
min_l1_data_gas_price_wei: ODDLY_SPECIFIC_L1_DATA_GAS_PRICE,
1097+
..Default::default()
1098+
};
1099+
let mut config_manager_client = MockConfigManagerClient::new();
1100+
config_manager_client
1101+
.expect_get_context_dynamic_config()
1102+
.returning(move || Ok(new_dynamic_config.clone()));
1103+
config_manager_client.expect_set_node_dynamic_config().returning(|_| Ok(()));
1104+
context.deps.config_manager_client = Some(Arc::new(config_manager_client));
1105+
1106+
let mut modified_block_info = block_info(BlockNumber(1));
1107+
modified_block_info.l1_data_gas_price_wei = GasPrice(ODDLY_SPECIFIC_L1_DATA_GAS_PRICE);
1108+
1109+
context.set_height_and_round(BlockNumber(1), 1).await;
1110+
let init = ProposalInit { height: BlockNumber(1), round: 1, ..Default::default() };
1111+
1112+
let content_receiver =
1113+
send_proposal_to_validator_context(&mut context, modified_block_info).await;
1114+
let fin_receiver = context.validate_proposal(init, TIMEOUT, content_receiver).await;
1115+
let proposal_commitment = fin_receiver.await.unwrap();
1116+
assert_eq!(proposal_commitment.0, STATE_DIFF_COMMITMENT.0.0);
1117+
1118+
context.decision_reached(BlockNumber(1), proposal_commitment).await.unwrap();
1119+
1120+
// Now build a proposal for height 2.
1121+
let new_dynamic_config = ContextDynamicConfig {
1122+
override_eth_to_fri_rate: Some(ODDLY_SPECIFIC_CONVERSION_RATE),
1123+
..Default::default()
1124+
};
1125+
let mut config_manager_client = MockConfigManagerClient::new();
1126+
config_manager_client
1127+
.expect_get_context_dynamic_config()
1128+
.returning(move || Ok(new_dynamic_config.clone()));
1129+
config_manager_client.expect_set_node_dynamic_config().returning(|_| Ok(()));
1130+
context.deps.config_manager_client = Some(Arc::new(config_manager_client));
1131+
1132+
let init = ProposalInit { height: BlockNumber(2), ..Default::default() };
1133+
1134+
let fin_receiver = context.build_proposal(init, TIMEOUT).await;
1135+
1136+
assert_eq!(fin_receiver.await.unwrap().0, STATE_DIFF_COMMITMENT.0.0);
1137+
let (_, mut receiver) = network.outbound_proposal_receiver.next().await.unwrap();
1138+
1139+
assert_eq!(receiver.next().await.unwrap(), init.into());
1140+
let info = receiver.next().await.unwrap();
1141+
let ProposalPart::BlockInfo(info) = info else {
1142+
panic!("Expected ProposalPart::BlockInfo");
1143+
};
1144+
assert_eq!(info.eth_to_fri_rate, ODDLY_SPECIFIC_CONVERSION_RATE);
1145+
}

crates/apollo_consensus_orchestrator/src/test_utils.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ impl From<TestDeps> for SequencerConsensusContextDeps {
117117
clock: deps.clock,
118118
outbound_proposal_sender: deps.outbound_proposal_sender,
119119
vote_broadcast_client: deps.vote_broadcast_client,
120+
config_manager_client: None,
120121
}
121122
}
122123
}
@@ -146,7 +147,6 @@ impl TestDeps {
146147
);
147148
self.batcher
148149
.expect_start_height()
149-
.times(1)
150150
.withf(move |input| input.height == block_number)
151151
.return_const(Ok(()));
152152
let proposal_id_clone = Arc::clone(&proposal_id);
@@ -183,6 +183,7 @@ impl TestDeps {
183183
assert!(final_n_executed_txs <= INTERNAL_TX_BATCH.len());
184184
self.setup_default_expectations();
185185
let mut seq = Sequence::new();
186+
186187
for _ in 0..number_of_times {
187188
let proposal_id = Arc::new(OnceLock::new());
188189
let proposal_id_clone = Arc::clone(&proposal_id);
@@ -196,6 +197,7 @@ impl TestDeps {
196197
.expect_start_height()
197198
.withf(move |input| input.height == block_number)
198199
.return_const(Ok(()));
200+
199201
let proposal_id_clone = Arc::clone(&proposal_id);
200202
self.batcher
201203
.expect_send_proposal_content()

0 commit comments

Comments
 (0)