Skip to content

Commit e44db8c

Browse files
akichidismwtian
authored andcommitted
[MFP] allow list for tx submission (#23853)
## Description Set an allow list to submit transactions via transaction driver to specific validators only. The provided list in the configuration is using the validator display names, as this is quite straightforward for someone to setup instead of dealing with serialised keys/addresses etc. The solution does not update the list when the committee updates, but this could be easily done if required. For now opted in for a simpler solution. ## Test plan CI/PT --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] gRPC: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK:
1 parent 5a96471 commit e44db8c

File tree

5 files changed

+52
-13
lines changed

5 files changed

+52
-13
lines changed

crates/sui-config/src/node.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,19 @@ pub struct NodeConfig {
221221
/// Fork recovery configuration for handling validator equivocation after forks
222222
#[serde(skip_serializing_if = "Option::is_none")]
223223
pub fork_recovery: Option<ForkRecoveryConfig>,
224+
225+
/// Configuration for the transaction driver.
226+
#[serde(skip_serializing_if = "Option::is_none")]
227+
pub transaction_driver_config: Option<TransactionDriverConfig>,
228+
}
229+
230+
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
231+
#[serde(rename_all = "kebab-case")]
232+
pub struct TransactionDriverConfig {
233+
/// The list of validators that are allowed to submit MFP transactions to (via the transaction driver).
234+
/// Each entry is a validator display name.
235+
#[serde(skip_serializing_if = "Vec::is_empty")]
236+
pub allowed_submission_validators: Vec<String>,
224237
}
225238

226239
#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize, PartialEq, Eq)]

crates/sui-core/src/transaction_driver/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use mysten_metrics::{monitored_future, spawn_logged_monitored_task};
2424
use parking_lot::Mutex;
2525
use rand::Rng;
2626
use sui_types::{
27-
base_types::AuthorityName,
2827
committee::EpochId,
2928
error::{ErrorCategory, UserInputError},
3029
messages_grpc::{PingType, SubmitTxRequest, SubmitTxResult, TxType},
@@ -55,7 +54,7 @@ pub struct SubmitTransactionOptions {
5554

5655
/// When submitting a transaction, only the validators in the allowed validator list can be used to submit the transaction to.
5756
/// When the allowed validator list is empty, any validator can be used.
58-
pub allowed_validators: Vec<AuthorityName>,
57+
pub allowed_validators: Vec<String>,
5958
}
6059

6160
#[derive(Clone, Debug)]
@@ -189,7 +188,7 @@ where
189188
.drive_transaction(
190189
SubmitTxRequest::new_ping(ping_type),
191190
SubmitTransactionOptions {
192-
allowed_validators: vec![name],
191+
allowed_validators: vec![display_name.clone()],
193192
..Default::default()
194193
},
195194
Some(ping_timeout),

crates/sui-core/src/transaction_driver/request_retrier.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl<A: Clone> RequestRetrier<A> {
4141
auth_agg: &Arc<AuthorityAggregator<A>>,
4242
client_monitor: &Arc<ValidatorClientMonitor<A>>,
4343
tx_type: TxType,
44-
allowed_validators: Vec<AuthorityName>,
44+
allowed_validators: Vec<String>,
4545
) -> Self {
4646
let ranked_validators = client_monitor.select_shuffled_preferred_validators(
4747
&auth_agg.committee,
@@ -50,7 +50,10 @@ impl<A: Clone> RequestRetrier<A> {
5050
);
5151
let ranked_clients = ranked_validators
5252
.into_iter()
53-
.filter(|name| allowed_validators.is_empty() || allowed_validators.contains(name))
53+
.filter(|name| {
54+
let display_name = auth_agg.get_display_name(name);
55+
allowed_validators.is_empty() || allowed_validators.contains(&display_name)
56+
})
5457
.filter_map(|name| {
5558
// There is not guarantee that the `name` are in the `auth_agg.authority_clients` if those are coming from the list
5659
// of `allowed_validators`, as the provided `auth_agg` might have been updated with a new committee that doesn't contain the validator in question.
@@ -139,7 +142,10 @@ impl<A: Clone> RequestRetrier<A> {
139142

140143
#[cfg(test)]
141144
mod tests {
142-
use sui_types::error::{SuiError, UserInputError};
145+
use sui_types::{
146+
base_types::ConciseableName,
147+
error::{SuiError, UserInputError},
148+
};
143149

144150
use crate::{
145151
authority_aggregator::{AuthorityAggregatorBuilder, TimeoutConfig},
@@ -199,9 +205,9 @@ mod tests {
199205
println!("Case 1. Mix of unknown validators and one known validator");
200206
{
201207
let allowed_validators = vec![
202-
unknown_validator1,
203-
unknown_validator2,
204-
authorities[0], // This one exists in auth_agg
208+
unknown_validator1.concise().to_string(),
209+
unknown_validator2.concise().to_string(),
210+
authorities[0].concise().to_string(), // This one exists in auth_agg
205211
];
206212

207213
let retrier = RequestRetrier::new(
@@ -218,7 +224,10 @@ mod tests {
218224

219225
println!("Case 2. Only unknown validators are provided");
220226
{
221-
let allowed_validators = vec![unknown_validator1, unknown_validator2];
227+
let allowed_validators = vec![
228+
unknown_validator1.concise().to_string(),
229+
unknown_validator2.concise().to_string(),
230+
];
222231

223232
let retrier = RequestRetrier::new(
224233
&auth_agg,

crates/sui-core/src/transaction_orchestrator.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ pub struct TransactionOrchestrator<A: Clone> {
7878
metrics: Arc<TransactionOrchestratorMetrics>,
7979
transaction_driver: Option<Arc<TransactionDriver<A>>>,
8080
td_percentage: u8,
81+
td_allowed_submission_list: Vec<String>,
8182
}
8283

8384
impl TransactionOrchestrator<NetworkAuthorityClient> {
@@ -166,6 +167,12 @@ where
166167
None
167168
};
168169

170+
let td_allowed_submission_list = node_config
171+
.transaction_driver_config
172+
.as_ref()
173+
.map(|config| config.allowed_submission_validators.clone())
174+
.unwrap_or_default();
175+
169176
Self {
170177
quorum_driver_handler,
171178
validator_state,
@@ -175,6 +182,7 @@ where
175182
metrics,
176183
transaction_driver,
177184
td_percentage,
185+
td_allowed_submission_list,
178186
}
179187
}
180188
}
@@ -654,8 +662,7 @@ where
654662
SubmitTxRequest::new_transaction(request.transaction.clone()),
655663
SubmitTransactionOptions {
656664
forwarded_client_addr: client_addr,
657-
// TODO: provide a list of validators to submit the transaction via config
658-
allowed_validators: vec![],
665+
allowed_validators: self.td_allowed_submission_list.clone(),
659666
},
660667
timeout_duration,
661668
)

crates/sui-swarm-config/src/node_config_builder.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use sui_config::node::{
1414
ExecutionTimeObserverConfig, ExpensiveSafetyCheckConfig, Genesis, KeyPairWithPath,
1515
StateSnapshotConfig, DEFAULT_GRPC_CONCURRENCY_LIMIT,
1616
};
17-
use sui_config::node::{default_zklogin_oauth_providers, RunWithRange};
17+
use sui_config::node::{default_zklogin_oauth_providers, RunWithRange, TransactionDriverConfig};
1818
use sui_config::p2p::{P2pConfig, SeedPeer, StateSyncConfig};
1919
use sui_config::verifier_signing_config::VerifierSigningConfig;
2020
use sui_config::{
@@ -255,6 +255,7 @@ impl ValidatorConfigBuilder {
255255
chain_override_for_testing: self.chain_override,
256256
validator_client_monitor_config: None,
257257
fork_recovery: None,
258+
transaction_driver_config: None,
258259
}
259260
}
260261

@@ -292,6 +293,7 @@ pub struct FullnodeConfigBuilder {
292293
data_ingestion_dir: Option<PathBuf>,
293294
disable_pruning: bool,
294295
chain_override: Option<Chain>,
296+
transaction_driver_config: Option<TransactionDriverConfig>,
295297
}
296298

297299
impl FullnodeConfigBuilder {
@@ -415,6 +417,14 @@ impl FullnodeConfigBuilder {
415417
self
416418
}
417419

420+
pub fn with_transaction_driver_config(
421+
mut self,
422+
config: Option<TransactionDriverConfig>,
423+
) -> Self {
424+
self.transaction_driver_config = config;
425+
self
426+
}
427+
418428
pub fn build<R: rand::RngCore + rand::CryptoRng>(
419429
self,
420430
rng: &mut R,
@@ -564,6 +574,7 @@ impl FullnodeConfigBuilder {
564574
chain_override_for_testing: self.chain_override,
565575
validator_client_monitor_config: None,
566576
fork_recovery: None,
577+
transaction_driver_config: self.transaction_driver_config,
567578
}
568579
}
569580
}

0 commit comments

Comments
 (0)