Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions src/app/firedancer/config/default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,8 @@ user = ""
# present.
#
# TODO: implement the "at most one downloaded " logic. "
download = true
# TODO: default to true once integrated with gossip
download = false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should keep this as true because the snapshot loader has no way of knowing whether the snapshots on disk are recent right now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having download as true involves setting an initial peer in the default config, which assumes a cluster. This needs to be a trusted peer too. This is partly the reason we removed hardcoded entrypoints in the first place. The user knows the target cluster and should set this field.

Second, I believe the download option isn't actually used anywhere in snapshot code apart from the config check I added.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh you are right, but we should check the download config option in the snapshot tiles.


# A snapshot hash must be published in gossip by one of the
# validator identities listed here for it to be accepted. The list
Expand Down Expand Up @@ -324,10 +325,11 @@ user = ""
# completing snapshot download.
maximum_download_retry_abort = 5

# The cluster to download snapshots from. This is a temporary
# config option that will be removed once the snapshot tiles
# are integrated with gossip
cluster = "testnet"
# List of initial peer addresses for snapshot download. These peers
# should be highly trusted. This list must not be empty when snapshot
# download is enabled. This is a temporary config option that will be
# removed once the snapshot tiles are integrated with gossip.
initial_peers = []

[rpc]
# If nonzero, enable JSON RPC on this port, and use the next port
Expand Down
50 changes: 49 additions & 1 deletion src/app/firedancer/topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,22 +176,70 @@ resolve_gossip_entrypoints( config_t * config ) {
config->gossip.resolved_entrypoints_cnt = resolved_entrypoints;
}

static int
resolve_initial_peer( char const * host_port,
fd_ip4_port_t * ip4_port ) {

/* Split host:port */

char const * colon = strrchr( host_port, ':' );
if( FD_UNLIKELY( !colon ) ) {
FD_LOG_ERR(( "invalid [snapshots.initial_peers] entry \"%s\": no port number", host_port ));
}

char fqdn[ 255 ];
ulong fqdn_len = (ulong)( colon-host_port );
if( FD_UNLIKELY( fqdn_len>254 ) ) {
FD_LOG_ERR(( "invalid [snapshots.initial_peers] entry \"%s\": hostname too long", host_port ));
}
fd_memcpy( fqdn, host_port, fqdn_len );
fqdn[ fqdn_len ] = '\0';

/* Parse port number */

char const * port_str = colon+1;
char const * endptr = NULL;
ulong port = strtoul( port_str, (char **)&endptr, 10 );
if( FD_UNLIKELY( !endptr || !port || port>USHORT_MAX || *endptr!='\0' ) ) {
FD_LOG_ERR(( "invalid [snapshots.initial_peers] entry \"%s\": invalid port number", host_port ));
}
ip4_port->port = (ushort)port;

/* Resolve hostname */
int resolved = resolve_address( fqdn, &ip4_port->addr );
return resolved;
}

static void
resolve_initial_peers( config_t * config ) {
ulong initial_peers_cnt = config->firedancer.snapshots.initial_peers_cnt;
ulong resolved_initial_peers = 0UL;
for( ulong j=0UL; j<initial_peers_cnt; j++ ) {
if( resolve_initial_peer( config->firedancer.snapshots.initial_peers[j], &config->firedancer.snapshots.resolved_initial_peers[resolved_initial_peers] ) ) {
resolved_initial_peers++;
}
}
config->firedancer.snapshots.resolved_initial_peers_cnt = resolved_initial_peers;
}

static void
setup_snapshots( config_t * config,
fd_topo_tile_t * tile ) {
fd_memcpy( tile->snaprd.snapshots_path, config->paths.snapshots, PATH_MAX );
fd_memcpy( tile->snaprd.cluster, config->firedancer.snapshots.cluster, sizeof(tile->snaprd.cluster) );
tile->snaprd.incremental_snapshot_fetch = config->firedancer.snapshots.incremental_snapshots;
tile->snaprd.do_download = config->firedancer.snapshots.download;
tile->snaprd.maximum_local_snapshot_age = config->firedancer.snapshots.maximum_local_snapshot_age;
tile->snaprd.minimum_download_speed_mib = config->firedancer.snapshots.minimum_download_speed_mib;
tile->snaprd.maximum_download_retry_abort = config->firedancer.snapshots.maximum_download_retry_abort;
tile->snaprd.initial_peers_cnt = fd_ulong_min( config->firedancer.snapshots.resolved_initial_peers_cnt, 16UL );
fd_memcpy( tile->snaprd.initial_peers, config->firedancer.snapshots.resolved_initial_peers, tile->snaprd.initial_peers_cnt * sizeof(fd_ip4_port_t) );
/* TODO: set up known validators and known validators cnt */
}

void
fd_topo_initialize( config_t * config ) {
resolve_gossip_entrypoints( config );
resolve_initial_peers( config );

ulong net_tile_cnt = config->layout.net_tile_count;
ulong shred_tile_cnt = config->layout.shred_tile_count;
Expand Down
19 changes: 11 additions & 8 deletions src/app/shared/fd_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,17 @@ struct fd_configf {
} runtime;

struct {
int incremental_snapshots;
uint maximum_local_snapshot_age;
int download;
ulong known_validators_cnt;
char known_validators[ 16 ][ 256 ];
uint minimum_download_speed_mib;
uint maximum_download_retry_abort;
char cluster[ 8UL ];
int incremental_snapshots;
uint maximum_local_snapshot_age;
int download;
ulong known_validators_cnt;
char known_validators[ 16 ][ 256 ];
uint minimum_download_speed_mib;
uint maximum_download_retry_abort;
ulong initial_peers_cnt;
char initial_peers[ 16 ][ 256 ];
ulong resolved_initial_peers_cnt;
fd_ip4_port_t resolved_initial_peers[ 16 ];
} snapshots;

struct {
Expand Down
11 changes: 9 additions & 2 deletions src/app/shared/fd_config_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@
static void
fd_config_check_configf( fd_config_t * config,
fd_configf_t * config_f ) {
(void)config_f;
if( FD_UNLIKELY( strlen( config->paths.snapshots )>PATH_MAX-1UL ) ) {
FD_LOG_ERR(( "[config->paths.snapshots] is too long (max %lu)", PATH_MAX-1UL ));
}
if( FD_UNLIKELY( config->paths.snapshots[ 0 ]!='\0' && config->paths.snapshots[ 0 ]!='/' ) ) {
FD_LOG_ERR(( "[config->paths.snapshots] must be an absolute path and hence start with a '/'"));
}
if( FD_UNLIKELY( config_f->snapshots.download && config_f->snapshots.initial_peers_cnt==0UL ) ) {
FD_LOG_ERR(( "[configf->snapshots.download] is true but [configf->snapshots.initial_peers] is not set. "
"Must specify at least one initial peer to download from if download is enabled" ));
}
if( FD_UNLIKELY( config_f->snapshots.initial_peers_cnt!=0UL && !config_f->snapshots.download ) ) {
FD_LOG_NOTICE(( "[configf->snapshots.initial_peers] is set but [configf->snapshots.download] is false. "
"This will not download snapshots from the initial peers" ));
}
}

fd_configh_t *
Expand Down Expand Up @@ -109,7 +116,7 @@ fd_config_extract_podf( uchar * pod,
CFG_POP_ARRAY( cstr, snapshots.known_validators );
CFG_POP ( uint, snapshots.minimum_download_speed_mib );
CFG_POP ( uint, snapshots.maximum_download_retry_abort );
CFG_POP ( cstr, snapshots.cluster );
CFG_POP_ARRAY( cstr, snapshots.initial_peers );

return config;
}
Expand Down
3 changes: 2 additions & 1 deletion src/disco/topo/fd_topo.h
Original file line number Diff line number Diff line change
Expand Up @@ -479,12 +479,13 @@ struct fd_topo_tile {

struct {
char snapshots_path[ PATH_MAX ];
char cluster[ 8UL ];
int incremental_snapshot_fetch;
int do_download;
uint maximum_local_snapshot_age;
uint minimum_download_speed_mib;
uint maximum_download_retry_abort;
ulong initial_peers_cnt;
fd_ip4_port_t initial_peers[ 16 ];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: alignment, also 16UL

} snaprd;

struct {
Expand Down
23 changes: 2 additions & 21 deletions src/discof/restore/fd_snaprd_tile.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,27 +646,8 @@ unprivileged_init( fd_topo_t * topo,
ctx->sshttp = fd_sshttp_join( fd_sshttp_new( _sshttp ) );
FD_TEST( ctx->sshttp );

if( FD_LIKELY( !strcmp( tile->snaprd.cluster, "testnet" ) ) ) {
fd_ip4_port_t initial_peers[ 2UL ] = {
{ .addr = FD_IP4_ADDR( 35 , 214, 172, 227 ), .port = 8899 },
{ .addr = FD_IP4_ADDR( 145, 40 , 95 , 69 ), .port = 8899 }, /* Solana testnet peer */
};
for( ulong i=0UL; i<2UL; i++ ) fd_ssping_add( ctx->ssping, initial_peers[ i ] );
} else if( FD_LIKELY( !strcmp( tile->snaprd.cluster, "private" ) ) ) {
fd_ip4_port_t initial_peers[ 1UL ] = {
{ .addr = FD_IP4_ADDR( 147, 28, 185, 47 ), .port = 8899 } /* A private cluster peer */
};
for( ulong i=0UL; i<1UL; i++ ) fd_ssping_add( ctx->ssping, initial_peers[ i ] );
} else if (FD_LIKELY( !strcmp( tile->snaprd.cluster, "mainnet" ) ) ) {
fd_ip4_port_t initial_peers[ 3UL ] = {
{ .addr = FD_IP4_ADDR( 149, 255, 37 , 130 ), .port = 8899 },
{ .addr = FD_IP4_ADDR( 34 , 1 , 238, 227 ), .port = 8899 },
{ .addr = FD_IP4_ADDR( 34 , 1 , 139, 131 ), .port = 8899 }
};
for( ulong i=0UL; i<3UL; i++ ) fd_ssping_add( ctx->ssping, initial_peers[ i ] );
}
else {
FD_LOG_ERR(( "unexpected cluster %s", tile->snaprd.cluster ));
for( ulong i=0UL; i<tile->snaprd.initial_peers_cnt; i++ ) {
fd_ssping_add( ctx->ssping, tile->snaprd.initial_peers[ i ] );
}

if( FD_UNLIKELY( tile->out_cnt!=1UL ) ) FD_LOG_ERR(( "tile `" NAME "` has %lu outs, expected 1", tile->out_cnt ));
Expand Down
Loading