Skip to content

Commit 50c43d8

Browse files
Ubuntuyewman
authored andcommitted
refactor(core): consolidate Cluster and ClusterType into single enum
- Merge sig.core.Cluster into ClusterType in genesis_config.zig - Move entrypoints and RPC URLs to ClusterType methods - Rename localnet to development to match Agave naming - Lift cluster config from gossip to top-level Cmd config - Fix duplicate rpc_client.deinit() call in cmd.zig
1 parent 7ca50bc commit 50c43d8

File tree

9 files changed

+83
-101
lines changed

9 files changed

+83
-101
lines changed

src/accountsdb/db.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3305,7 +3305,7 @@ pub fn indexAndValidateAccountFile(
33053305
}
33063306

33073307
pub fn getAccountPerFileEstimateFromCluster(
3308-
cluster: sig.core.Cluster,
3308+
cluster: sig.core.ClusterType,
33093309
) error{NotImplementedYet}!u64 {
33103310
return switch (cluster) {
33113311
.testnet => 500,
@@ -4178,7 +4178,7 @@ pub const BenchmarkAccountsDBSnapshotLoad = struct {
41784178
use_disk: bool,
41794179
n_threads: u32,
41804180
name: []const u8,
4181-
cluster: sig.core.Cluster,
4181+
cluster: sig.core.ClusterType,
41824182
};
41834183

41844184
pub const inputs = [_]BenchInputs{.{

src/cmd.zig

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ pub fn main() !void {
209209
);
210210
current_config.genesis_file_path = params.genesis_file_path;
211211
params.accountsdb_base.apply(&current_config);
212-
current_config.gossip.cluster = params.gossip_cluster;
212+
current_config.cluster = params.gossip_cluster;
213213
params.geyser.apply(&current_config);
214214
current_config.geyser.pipe_path = try current_config.derivePathFromValidatorDir(
215215
gpa,
@@ -556,7 +556,7 @@ const Cmd = struct {
556556
cfg.gossip.host = args.host;
557557
cfg.gossip.port = args.port;
558558
cfg.gossip.entrypoints = args.entrypoints;
559-
cfg.gossip.cluster = args.network;
559+
cfg.cluster = args.network;
560560
}
561561
};
562562
const GossipArgumentsNode = struct {
@@ -1356,7 +1356,7 @@ fn ensureGenesis(
13561356
allocator.free(existing_path);
13571357

13581358
// Determine cluster for genesis
1359-
const cluster = try cfg.gossip.getCluster() orelse {
1359+
const cluster = try cfg.getCluster() orelse {
13601360
logger.err().log(
13611361
\\No genesis file path provided and no cluster specified.
13621362
\\Use --genesis-file-path or --cluster"
@@ -1366,12 +1366,7 @@ fn ensureGenesis(
13661366

13671367
// Otherwise, download genesis from network
13681368
logger.info().logf("Downloading genesis from {s} cluster...", .{@tagName(cluster)});
1369-
const cluster_url = switch (cluster) {
1370-
.mainnet => "https://api.mainnet-beta.solana.com",
1371-
.testnet => "https://api.testnet.solana.com",
1372-
.devnet => "https://api.devnet.solana.com",
1373-
.localnet => unreachable,
1374-
};
1369+
const cluster_url = cluster.getRpcUrl();
13751370
const genesis_path = downloadAndExtractGenesis(
13761371
allocator,
13771372
cluster_url,
@@ -2127,18 +2122,12 @@ fn printLeaderSchedule(allocator: std.mem.Allocator, cfg: config.Cmd) !void {
21272122

21282123
const leader_schedule //
21292124
= try getLeaderScheduleFromCli(allocator, cfg) orelse b: {
2130-
const cluster = try cfg.gossip.getCluster() orelse
2125+
const cluster_type = try cfg.getCluster() orelse
21312126
return error.ClusterNotProvided;
21322127

2133-
const cluster_type: ClusterType = switch (cluster) {
2134-
.mainnet => .MainnetBeta,
2135-
.devnet => .Devnet,
2136-
.testnet => .Testnet,
2137-
.localnet => .LocalHost,
2138-
};
2139-
21402128
var rpc_client = try sig.rpc.Client.init(allocator, cluster_type, .{});
21412129
defer rpc_client.deinit();
2130+
defer rpc_client.deinit();
21422131

21432132
const slot = blk: {
21442133
const response = try rpc_client.getSlot(.{});
@@ -2210,12 +2199,7 @@ fn testTransactionSenderService(
22102199
}
22112200

22122201
// define cluster of where to land transactions
2213-
const rpc_cluster: ClusterType = if (try cfg.gossip.getCluster()) |n| switch (n) {
2214-
.mainnet => .MainnetBeta,
2215-
.devnet => .Devnet,
2216-
.testnet => .Testnet,
2217-
.localnet => .LocalHost,
2218-
} else {
2202+
const rpc_cluster: ClusterType = try cfg.getCluster() orelse {
22192203
@panic("cluster option (-c) not provided");
22202204
};
22212205
app_base.logger.warn().logf(
@@ -2464,7 +2448,7 @@ const AppBase = struct {
24642448
const my_keypair = try sig.identity.getOrInit(allocator, .from(logger));
24652449
const my_pubkey = Pubkey.fromPublicKey(&my_keypair.public_key);
24662450

2467-
const entrypoints = try cfg.gossip.getEntrypointAddrs(allocator);
2451+
const entrypoints = try cfg.gossip.getEntrypointAddrs(try cfg.getCluster(), allocator);
24682452

24692453
const echo_data = try getShredAndIPFromEchoServer(.from(logger), entrypoints);
24702454

src/config.zig

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub const Cmd = struct {
1919
max_shreds: u64 = 5_000_000,
2020
leader_schedule_path: ?[]const u8 = null,
2121
genesis_file_path: ?[]const u8 = null,
22+
cluster: ?[]const u8 = null,
2223
// general config
2324
log_filters: sig.trace.Filters = .debug,
2425
log_file: ?[]const u8 = null,
@@ -32,15 +33,22 @@ pub const Cmd = struct {
3233
vote_account: ?[]const u8 = null,
3334
stop_at_slot: ?sig.core.Slot = null,
3435

35-
pub fn genesisFilePath(self: Cmd) error{UnknownCluster}!?[]const u8 {
36+
pub fn getCluster(self: Cmd) error{UnknownCluster}!?sig.core.ClusterType {
37+
return if (self.cluster) |cluster_str|
38+
std.meta.stringToEnum(sig.core.ClusterType, cluster_str) orelse error.UnknownCluster
39+
else
40+
null;
41+
}
42+
43+
pub fn genesisFilePath(self: Cmd) !?[]const u8 {
3644
if (self.genesis_file_path) |provided_path|
3745
return provided_path;
3846

39-
const local_path = if (try self.gossip.getCluster()) |n| switch (n) {
47+
const local_path = if (try self.getCluster()) |cluster| switch (cluster) {
4048
.mainnet => "data/genesis-files/mainnet_genesis.bin",
4149
.devnet => "data/genesis-files/devnet_genesis.bin",
4250
.testnet => "data/genesis-files/testnet_genesis.bin",
43-
.localnet => return error.MustProvideGenesisFileForLocalHost,
51+
.development => return null,
4452
} else return null;
4553

4654
const genesis_file = std.fs.cwd().openFile(local_path, .{}) catch {
@@ -146,7 +154,6 @@ pub const Gossip = struct {
146154
host: ?[]const u8 = null,
147155
port: u16 = 8001,
148156
entrypoints: []const []const u8 = &.{},
149-
cluster: ?[]const u8 = null,
150157
spy_node: bool = false,
151158
dump: bool = false,
152159
trusted_validators: []const []const u8 = &.{},
@@ -169,30 +176,23 @@ pub const Gossip = struct {
169176
};
170177
}
171178

172-
pub fn getCluster(self: Gossip) error{UnknownCluster}!?sig.core.Cluster {
173-
return if (self.cluster) |cluster_str|
174-
std.meta.stringToEnum(sig.core.Cluster, cluster_str) orelse
175-
error.UnknownCluster
176-
else
177-
null;
178-
}
179-
180179
pub fn getEntrypointAddrs(
181180
self: Gossip,
181+
cluster: ?sig.core.ClusterType,
182182
allocator: std.mem.Allocator,
183183
) ![]sig.net.SocketAddr {
184184
var entrypoint_set = std.AutoArrayHashMap(sig.net.SocketAddr, void).init(allocator);
185185
defer entrypoint_set.deinit();
186186

187-
// add cluster entrypoints
188-
if (try self.getCluster()) |cluster| {
189-
for (sig.gossip.getClusterEntrypoints(cluster)) |entrypoint| {
187+
// add cluster entrypoints (only for public clusters)
188+
if (cluster) |c| {
189+
for (c.getEntrypoints()) |entrypoint| {
190190
const socket_addr = try resolveSocketAddr(allocator, entrypoint);
191191
try entrypoint_set.put(socket_addr, {});
192192
}
193193
}
194194

195-
// add config entrypoints
195+
// add user-provided entrypoints
196196
for (self.entrypoints) |entrypoint| {
197197
const socket_addr = sig.net.SocketAddr.parse(entrypoint) catch brk: {
198198
break :brk try resolveSocketAddr(allocator, entrypoint);

src/core/genesis_config.zig

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -250,17 +250,50 @@ pub const Inflation = struct {
250250
}
251251
};
252252

253-
/// Analogous to [ClusterType](https://github.com/anza-xyz/agave/blob/cadba689cb44db93e9c625770cafd2fc0ae89e33/sdk/src/genesis_config.rs#L46)
253+
/// Analogous to [ClusterType](https://github.com/anza-xyz/solana-sdk/blob/a467058aabc453c7d749a4993c56df293d1d75c3/cluster-type/src/lib.rs#L19)
254254
/// Explicit numbers are added to ensure we don't mess up the order of the fields and break bincode reading.
255-
pub const ClusterType = union(enum(u8)) {
256-
Testnet = 0,
257-
MainnetBeta = 1,
258-
Devnet = 2,
259-
Development = 3,
260-
LocalHost,
261-
Custom: struct {
262-
url: []const u8,
263-
},
255+
pub const ClusterType = enum(u8) {
256+
testnet = 0,
257+
mainnet = 1,
258+
devnet = 2,
259+
development = 3,
260+
261+
/// Returns entrypoints for public clusters, null for development.
262+
/// For development, the caller must provide entrypoints manually.
263+
pub fn getEntrypoints(self: ClusterType) []const []const u8 {
264+
return switch (self) {
265+
.mainnet => &.{
266+
"entrypoint.mainnet-beta.solana.com:8001",
267+
"entrypoint2.mainnet-beta.solana.com:8001",
268+
"entrypoint3.mainnet-beta.solana.com:8001",
269+
"entrypoint4.mainnet-beta.solana.com:8001",
270+
"entrypoint5.mainnet-beta.solana.com:8001",
271+
},
272+
.testnet => &.{
273+
"entrypoint.testnet.solana.com:8001",
274+
"entrypoint2.testnet.solana.com:8001",
275+
"entrypoint3.testnet.solana.com:8001",
276+
},
277+
.devnet => &.{
278+
"entrypoint.devnet.solana.com:8001",
279+
"entrypoint2.devnet.solana.com:8001",
280+
"entrypoint3.devnet.solana.com:8001",
281+
"entrypoint4.devnet.solana.com:8001",
282+
"entrypoint5.devnet.solana.com:8001",
283+
},
284+
.development => @panic("TODO: should development require custom entrypoints?"),
285+
};
286+
}
287+
288+
/// Returns the RPC URL for this cluster.
289+
pub fn getRpcUrl(self: ClusterType) []const u8 {
290+
return switch (self) {
291+
.mainnet => "https://api.mainnet-beta.solana.com",
292+
.testnet => "https://api.testnet.solana.com",
293+
.devnet => "https://api.devnet.solana.com",
294+
.development => @panic("TODO: should development require custom rpc urls?"),
295+
};
296+
}
264297
};
265298

266299
/// Analogous to [GenesisConfig](https://github.com/anza-xyz/agave/blob/cadba689cb44db93e9c625770cafd2fc0ae89e33/sdk/src/genesis_config.rs#L93)
@@ -312,7 +345,7 @@ pub const GenesisConfig = struct {
312345
.fee_rate_governor = .DEFAULT,
313346
.rent = .INIT,
314347
.epoch_schedule = .INIT,
315-
.cluster_type = .Development,
348+
.cluster_type = .development,
316349
};
317350
}
318351

@@ -352,7 +385,7 @@ test "genesis_config deserialize development config" {
352385
const config = try GenesisConfig.init(allocator, genesis_path);
353386
defer config.deinit(allocator);
354387

355-
try std.testing.expectEqual(ClusterType.Development, config.cluster_type);
388+
try std.testing.expectEqual(ClusterType.development, config.cluster_type);
356389
}
357390

358391
test "genesis_config deserialize testnet config" {
@@ -362,7 +395,7 @@ test "genesis_config deserialize testnet config" {
362395
const config = try GenesisConfig.init(allocator, genesis_path);
363396
defer config.deinit(allocator);
364397

365-
try std.testing.expectEqual(ClusterType.Testnet, config.cluster_type);
398+
try std.testing.expectEqual(ClusterType.testnet, config.cluster_type);
366399
}
367400

368401
test "genesis_config deserialize devnet config" {
@@ -372,7 +405,7 @@ test "genesis_config deserialize devnet config" {
372405
const config = try GenesisConfig.init(allocator, genesis_path);
373406
defer config.deinit(allocator);
374407

375-
try std.testing.expectEqual(ClusterType.Devnet, config.cluster_type);
408+
try std.testing.expectEqual(ClusterType.devnet, config.cluster_type);
376409
}
377410

378411
test "genesis_config deserialize mainnet config" {
@@ -382,7 +415,7 @@ test "genesis_config deserialize mainnet config" {
382415
const config = try GenesisConfig.init(allocator, genesis_path);
383416
defer config.deinit(allocator);
384417

385-
try std.testing.expectEqual(ClusterType.MainnetBeta, config.cluster_type);
418+
try std.testing.expectEqual(ClusterType.mainnet, config.cluster_type);
386419
}
387420

388421
test "inflation" {

src/core/lib.zig

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,3 @@ pub const Transaction = transaction.Transaction;
7777
pub const Epoch = time.Epoch;
7878
pub const Slot = time.Slot;
7979
pub const UnixTimestamp = time.UnixTimestamp;
80-
81-
pub const Cluster = enum { mainnet, testnet, devnet, localnet };

src/gossip/helpers.zig

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,28 @@ const sig = @import("../sig.zig");
33

44
const Pubkey = sig.core.Pubkey;
55
const ContactInfo = sig.gossip.ContactInfo;
6-
const Cluster = sig.core.Cluster;
6+
const ClusterType = sig.core.ClusterType;
77
const GossipService = sig.gossip.GossipService;
88
const SocketAddr = sig.net.SocketAddr;
99
const IpAddr = sig.net.IpAddr;
1010

1111
const resolveSocketAddr = sig.net.net.resolveSocketAddr;
1212
const getShredAndIPFromEchoServer = sig.net.echo.getShredAndIPFromEchoServer;
1313
const getWallclockMs = sig.time.getWallclockMs;
14-
const getClusterEntrypoints = sig.gossip.service.getClusterEntrypoints;
1514

1615
/// inits a gossip client with the minimum required configuration
1716
/// relying on the cluster to provide the entrypoints
1817
pub fn initGossipFromCluster(
1918
allocator: std.mem.Allocator,
2019
logger: sig.trace.Logger("gossip"),
21-
cluster: Cluster,
20+
cluster: ClusterType,
2221
my_port: u16,
2322
) !*GossipService {
2423
// gather entrypoints
2524
var entrypoints = std.ArrayList(SocketAddr).init(allocator);
2625
defer entrypoints.deinit();
2726

28-
const entrypoints_strs = getClusterEntrypoints(cluster);
27+
const entrypoints_strs = cluster.getEntrypoints();
2928
for (entrypoints_strs) |entrypoint_str| {
3029
const socket_addr = try resolveSocketAddr(allocator, entrypoint_str);
3130
try entrypoints.append(socket_addr);

src/gossip/lib.zig

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,3 @@ pub const Ping = ping_pong.Ping;
2424
pub const Pong = ping_pong.Pong;
2525
pub const SocketTag = data.SocketTag;
2626
pub const PruneData = prune.PruneData;
27-
28-
pub const getClusterEntrypoints = service.getClusterEntrypoints;

src/gossip/service.zig

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2256,34 +2256,6 @@ pub fn chunkValuesIntoPacketIndexes(
22562256
return packet_indexs;
22572257
}
22582258

2259-
pub fn getClusterEntrypoints(cluster: sig.core.Cluster) []const []const u8 {
2260-
return switch (cluster) {
2261-
.mainnet => &.{
2262-
"entrypoint.mainnet-beta.solana.com:8001",
2263-
"entrypoint2.mainnet-beta.solana.com:8001",
2264-
"entrypoint3.mainnet-beta.solana.com:8001",
2265-
"entrypoint4.mainnet-beta.solana.com:8001",
2266-
"entrypoint5.mainnet-beta.solana.com:8001",
2267-
},
2268-
.testnet => &.{
2269-
"entrypoint.testnet.solana.com:8001",
2270-
"entrypoint2.testnet.solana.com:8001",
2271-
"entrypoint3.testnet.solana.com:8001",
2272-
},
2273-
.devnet => &.{
2274-
"entrypoint.devnet.solana.com:8001",
2275-
"entrypoint2.devnet.solana.com:8001",
2276-
"entrypoint3.devnet.solana.com:8001",
2277-
"entrypoint4.devnet.solana.com:8001",
2278-
"entrypoint5.devnet.solana.com:8001",
2279-
},
2280-
.localnet => &.{
2281-
"127.0.0.1:1024", // agave test-validator default
2282-
"127.0.0.1:8001", // sig validator default
2283-
},
2284-
};
2285-
}
2286-
22872259
test "general coverage" {
22882260
const allocator = std.testing.allocator;
22892261

src/rpc/client.zig

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ pub const Client = struct {
2323
cluster_type: ClusterType,
2424
options: HttpPostFetcher.Options,
2525
) Allocator.Error!Client {
26-
return .{ .fetcher = try HttpPostFetcher.init(allocator, rpcUrl(cluster_type), options) };
26+
return .{ .fetcher = try HttpPostFetcher.init(
27+
allocator,
28+
cluster_type.getRpcUrl(),
29+
options,
30+
) };
2731
}
2832

2933
pub fn deinit(self: *Client) void {
@@ -198,11 +202,5 @@ pub const Client = struct {
198202
};
199203

200204
pub fn rpcUrl(cluster_type: ClusterType) []const u8 {
201-
return switch (cluster_type) {
202-
.MainnetBeta => "https://api.mainnet-beta.solana.com",
203-
.Testnet => "https://api.testnet.solana.com",
204-
.Devnet => "https://api.devnet.solana.com",
205-
.Custom => |cluster| cluster.url,
206-
else => "http://localhost:8899",
207-
};
205+
return cluster_type.getRpcUrl();
208206
}

0 commit comments

Comments
 (0)