Skip to content

Commit 888e78a

Browse files
Copilot0xrinegade
andcommitted
Fix deploy command network parsing logic for "all" networks
Co-authored-by: 0xrinegade <[email protected]>
1 parent e59d969 commit 888e78a

File tree

3 files changed

+106
-38
lines changed

3 files changed

+106
-38
lines changed

src/main.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -927,26 +927,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
927927
.map(|s| s.as_str())
928928
.unwrap_or("all");
929929

930-
// Parse network type
931-
let network_type = match network_str.to_lowercase().as_str() {
932-
"mainnet" => ssh_deploy::NetworkType::Mainnet,
933-
"testnet" => ssh_deploy::NetworkType::Testnet,
934-
"devnet" => ssh_deploy::NetworkType::Devnet,
935-
"all" => ssh_deploy::NetworkType::Mainnet, // Default value, will deploy to all
936-
_ => {
937-
eprintln!("Invalid network: {}", network_str);
938-
exit(1);
939-
}
940-
};
941-
942930
// Create deployment configuration
943931
let deploy_config = ebpf_deploy::DeployConfig {
944932
binary_path: binary_path.to_string(),
945933
program_id_path: program_id_path.to_string(),
946934
owner_path: owner_path.to_string(),
947935
fee_payer_path: fee_payer_path.to_string(),
948936
publish_idl,
949-
network_type,
937+
network_filter: network_str.to_string(), // Pass the original network string
950938
};
951939

952940
println!("Deploying eBPF binary to SVM networks...");

src/utils/ebpf_deploy.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use {
3030
/// owner_path: "owner_keypair.json".to_string(),
3131
/// fee_payer_path: "fee_payer.json".to_string(),
3232
/// publish_idl: true,
33-
/// network_type: NetworkType::Mainnet,
33+
/// network_filter: "all".to_string(),
3434
/// };
3535
///
3636
/// let results = deploy_to_all_networks(config, CommitmentConfig::confirmed()).await;
@@ -86,8 +86,8 @@ pub struct DeployConfig {
8686
pub fee_payer_path: String,
8787
/// Whether to publish IDL
8888
pub publish_idl: bool,
89-
/// Network to deploy on
90-
pub network_type: NetworkType,
89+
/// Network filter (mainnet, testnet, devnet, or all)
90+
pub network_filter: String,
9191
}
9292

9393
/// Result of a deployment operation
@@ -149,11 +149,7 @@ pub async fn deploy_to_network(
149149
let program_data = load_program(&config.binary_path)?;
150150

151151
// Get network name for result
152-
let network_name = match config.network_type {
153-
NetworkType::Mainnet => "mainnet".to_string(),
154-
NetworkType::Testnet => "testnet".to_string(),
155-
NetworkType::Devnet => "devnet".to_string(),
156-
};
152+
let network_name = config.network_filter.clone();
157153

158154
println!("Deploying to {} network...", network_name);
159155
println!(" Program ID: {}", program_id);
@@ -244,21 +240,23 @@ pub async fn deploy_to_all_networks(
244240
) -> Vec<Result<DeploymentResult, EbpfDeployError>> {
245241
let mut results = Vec::new();
246242

247-
// List of networks to deploy to
248-
// In a real implementation, this would query available networks dynamically
249-
let networks = match config.network_type {
250-
NetworkType::Mainnet => vec![NetworkType::Mainnet],
251-
NetworkType::Testnet => vec![NetworkType::Testnet],
252-
NetworkType::Devnet => vec![NetworkType::Devnet],
253-
// Handle the case when "all" networks are specified
254-
// In reality NetworkType doesn't have a variant for "all", but we handle it here for completeness
255-
#[allow(unreachable_patterns)]
256-
_ => vec![NetworkType::Mainnet, NetworkType::Testnet, NetworkType::Devnet],
243+
// Determine which networks to deploy to based on the filter
244+
let networks = match config.network_filter.to_lowercase().as_str() {
245+
"mainnet" => vec![NetworkType::Mainnet],
246+
"testnet" => vec![NetworkType::Testnet],
247+
"devnet" => vec![NetworkType::Devnet],
248+
"all" => vec![NetworkType::Mainnet, NetworkType::Testnet, NetworkType::Devnet],
249+
_ => {
250+
// Invalid network filter, return error
251+
let error = EbpfDeployError::NetworkNotAvailable(
252+
format!("Invalid network filter: {}", config.network_filter)
253+
);
254+
return vec![Err(error)];
255+
}
257256
};
258257

259258
for network in networks {
260259
// Create client for the specific network
261-
// In a real implementation, this would use the appropriate RPC URL for each network
262260
let client_url = match network {
263261
NetworkType::Mainnet => "https://api.mainnet-beta.solana.com",
264262
NetworkType::Testnet => "https://api.testnet.solana.com",
@@ -269,7 +267,11 @@ pub async fn deploy_to_all_networks(
269267

270268
// Create network-specific config
271269
let network_config = DeployConfig {
272-
network_type: network,
270+
network_filter: match network {
271+
NetworkType::Mainnet => "mainnet".to_string(),
272+
NetworkType::Testnet => "testnet".to_string(),
273+
NetworkType::Devnet => "devnet".to_string(),
274+
},
273275
..config.clone()
274276
};
275277

tests/ebpf_deploy_tests.rs

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
use osvm::utils::ebpf_deploy::{DeployConfig, load_program_id, load_keypair, load_program};
2-
use osvm::utils::ssh_deploy::NetworkType;
3-
use std::fs::{self, File};
1+
use osvm::utils::ebpf_deploy::{DeployConfig, load_program_id, load_program, deploy_to_all_networks};
2+
use solana_sdk::commitment_config::CommitmentConfig;
3+
use std::fs::File;
44
use std::io::Write;
5-
use std::path::Path;
65
use tempfile::tempdir;
76

87
#[test]
@@ -47,7 +46,7 @@ fn test_create_deploy_config() {
4746
owner_path: "path/to/owner.json".to_string(),
4847
fee_payer_path: "path/to/fee_payer.json".to_string(),
4948
publish_idl: true,
50-
network_type: NetworkType::Devnet,
49+
network_filter: "devnet".to_string(),
5150
};
5251

5352
// Verify config fields
@@ -56,8 +55,87 @@ fn test_create_deploy_config() {
5655
assert_eq!(config.owner_path, "path/to/owner.json");
5756
assert_eq!(config.fee_payer_path, "path/to/fee_payer.json");
5857
assert!(config.publish_idl);
58+
assert_eq!(config.network_filter, "devnet");
5959

6060
// Clone the config and verify the clone
6161
let config_clone = config.clone();
6262
assert_eq!(config_clone.binary_path, config.binary_path);
63+
}
64+
65+
#[tokio::test]
66+
async fn test_network_filter_logic() {
67+
// This test only validates the network filtering logic without actually making network calls
68+
let dir = tempdir().unwrap();
69+
70+
// Create test files
71+
let program_file = dir.path().join("program.so");
72+
let mut file = File::create(&program_file).unwrap();
73+
file.write_all(b"dummy program").unwrap();
74+
75+
let program_id_file = dir.path().join("program_id.json");
76+
let mut file = File::create(&program_id_file).unwrap();
77+
file.write_all(br#"{"programId": "HN4tEEGheziD9dqcWg4xZd29htcerjXKGoGiQXM5hxiS"}"#).unwrap();
78+
79+
let owner_file = dir.path().join("owner.json");
80+
let mut file = File::create(&owner_file).unwrap();
81+
// Valid Ed25519 keypair (64 bytes)
82+
let keypair = [
83+
74, 97, 123, 217, 156, 17, 153, 238, 153, 193, 31, 227, 15, 68, 138, 151,
84+
87, 14, 66, 179, 187, 149, 171, 224, 24, 176, 206, 49, 225, 173, 85, 69,
85+
35, 85, 76, 4, 41, 56, 193, 80, 141, 162, 202, 35, 90, 29, 138, 14,
86+
176, 85, 191, 245, 106, 196, 149, 53, 180, 252, 241, 119, 54, 11, 141, 223
87+
];
88+
file.write_all(format!("{:?}", keypair.to_vec()).as_bytes()).unwrap();
89+
90+
let fee_payer_file = dir.path().join("fee_payer.json");
91+
let mut file = File::create(&fee_payer_file).unwrap();
92+
file.write_all(format!("{:?}", keypair.to_vec()).as_bytes()).unwrap();
93+
94+
// Test "all" network filter
95+
let config_all = DeployConfig {
96+
binary_path: program_file.to_string_lossy().to_string(),
97+
program_id_path: program_id_file.to_string_lossy().to_string(),
98+
owner_path: owner_file.to_string_lossy().to_string(),
99+
fee_payer_path: fee_payer_file.to_string_lossy().to_string(),
100+
publish_idl: false,
101+
network_filter: "all".to_string(),
102+
};
103+
104+
// This would attempt network calls in a real scenario, but we're just testing the logic
105+
// The function should handle "all" and try to deploy to 3 networks (mainnet, testnet, devnet)
106+
let results = deploy_to_all_networks(config_all, CommitmentConfig::confirmed()).await;
107+
108+
// Should return 3 results (one for each network)
109+
assert_eq!(results.len(), 3);
110+
111+
// Test single network filter
112+
let config_single = DeployConfig {
113+
binary_path: program_file.to_string_lossy().to_string(),
114+
program_id_path: program_id_file.to_string_lossy().to_string(),
115+
owner_path: owner_file.to_string_lossy().to_string(),
116+
fee_payer_path: fee_payer_file.to_string_lossy().to_string(),
117+
publish_idl: false,
118+
network_filter: "devnet".to_string(),
119+
};
120+
121+
let results = deploy_to_all_networks(config_single, CommitmentConfig::confirmed()).await;
122+
123+
// Should return 1 result (devnet only)
124+
assert_eq!(results.len(), 1);
125+
126+
// Test invalid network filter
127+
let config_invalid = DeployConfig {
128+
binary_path: program_file.to_string_lossy().to_string(),
129+
program_id_path: program_id_file.to_string_lossy().to_string(),
130+
owner_path: owner_file.to_string_lossy().to_string(),
131+
fee_payer_path: fee_payer_file.to_string_lossy().to_string(),
132+
publish_idl: false,
133+
network_filter: "invalid".to_string(),
134+
};
135+
136+
let results = deploy_to_all_networks(config_invalid, CommitmentConfig::confirmed()).await;
137+
138+
// Should return 1 error result
139+
assert_eq!(results.len(), 1);
140+
assert!(results[0].is_err());
63141
}

0 commit comments

Comments
 (0)