Skip to content

Commit 8ec4597

Browse files
solcap: v2 (#7337)
* solcap: v2 * solcap: adding stake hooks * solcap: add integration test * solcap: integration test fix --------- Co-authored-by: Kunal Bhargava <[email protected]>
1 parent c098c50 commit 8ec4597

38 files changed

+2653
-2850
lines changed

.github/workflows/tests.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,10 @@ jobs:
147147
sudo prlimit --pid $$ --memlock=-1:-1
148148
source /opt/${{ matrix.compiler }}/${{ matrix.compiler }}-${{ matrix.compiler-version }}/activate
149149
make run-integration-test
150+
151+
- name: run solcap tests
152+
if: ${{ matrix.run-unit-tests && matrix.test-case == 'native' }}
153+
run: |
154+
sudo prlimit --pid $$ --memlock=-1:-1
155+
source /opt/${{ matrix.compiler }}/${{ matrix.compiler }}-${{ matrix.compiler-version }}/activate
156+
DUMP=../dump make run-solcap-tests

contrib/test/run_solcap_tests.sh

Lines changed: 74 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
#!/bin/bash
2-
set -xeou pipefail
2+
set -eou pipefail
33

44
source contrib/test/ledger_common.sh
55

66
DUMP=${DUMP:="./dump"}
77
OBJDIR=${OBJDIR:-build/native/gcc}
8-
echo $OBJDIR
8+
SKIP_INGEST=${SKIP_INGEST:-0}
99

10-
LEDGER="devnet-398736132-solcap"
10+
LEDGER="mainnet-376969880-solcap"
1111
REDOWNLOAD=1
1212

1313
while [[ $# -gt 0 ]]; do
@@ -49,41 +49,86 @@ else
4949
check_ledger_checksum_and_redownload
5050
fi
5151

52-
rm -rf $DUMP/$LEDGER/devnet-398736132_current.toml
53-
rm -rf $DUMP/$LEDGER/fd.solcap
54-
55-
cp $DUMP/$LEDGER/devnet-398736132.toml $DUMP/$LEDGER/devnet-398736132_current.toml
52+
# Clone and build solcap-tools
53+
ORIG_DIR=$(pwd)
54+
cd $DUMP
55+
if [ ! -d "solcap-tools" ]; then
56+
git clone https://github.com/firedancer-io/solcap-tools.git > /dev/null 2>&1
57+
fi
58+
cd solcap-tools
59+
git fetch origin > /dev/null 2>&1
60+
git checkout nishk/bp-fixes > /dev/null 2>&1
61+
git reset --hard origin/nishk/bp-fixes > /dev/null 2>&1
62+
cargo build --release > /dev/null 2>&1
63+
cd "$ORIG_DIR"
5664

5765
export ledger_dir=$(realpath $DUMP/$LEDGER)
58-
sed -i "s#{ledger_dir}#${ledger_dir}#g" "$DUMP/$LEDGER/devnet-398736132_current.toml"
59-
sed -i "s/max_total_banks = [0-9]*/max_total_banks = 32/g" "$DUMP/$LEDGER/devnet-398736132_current.toml"
60-
sed -i -z "s/\[snapshots\].*\[layout\]/[layout]/" "$DUMP/$LEDGER/devnet-398736132_current.toml"
61-
sed -i "/writer_tile_count/d" "$DUMP/$LEDGER/devnet-398736132_current.toml"
62-
sed -i "/lock_pages/d" "$DUMP/$LEDGER/devnet-398736132_current.toml"
63-
sed -i "/heap_size_gib/d" "$DUMP/$LEDGER/devnet-398736132_current.toml"
64-
sed -i "/max_total_banks/d" "$DUMP/$LEDGER/devnet-398736132_current.toml"
65-
sed -i "/max_fork_width/d" "$DUMP/$LEDGER/devnet-398736132_current.toml"
66-
sed -i "/cluster_version/d" "$DUMP/$LEDGER/devnet-398736132_current.toml"
67-
68-
echo "
69-
[gossip]
70-
entrypoints = [ \"0.0.0.0:1\" ]" >> "$DUMP/$LEDGER/devnet-398736132_current.toml"
7166

72-
echo "
67+
cat > "$DUMP/$LEDGER/mainnet-376969880_current.toml" << EOF
68+
7369
[snapshots]
7470
incremental_snapshots = false
7571
[snapshots.sources]
7672
servers = []
7773
[snapshots.sources.gossip]
7874
allow_any = false
79-
allow_list = []" >> "$DUMP/$LEDGER/devnet-398736132_current.toml"
75+
allow_list = []
76+
[layout]
77+
shred_tile_count = 4
78+
snapla_tile_count = 1
79+
verify_tile_count = 2
80+
exec_tile_count = 6
81+
[tiles]
82+
[tiles.archiver]
83+
enabled = true
84+
end_slot = 376969900
85+
rocksdb_path = "${ledger_dir}/rocksdb"
86+
shredcap_path = "${ledger_dir}/shreds.pcapng.zst"
87+
ingest_mode = "shredcap"
88+
[tiles.replay]
89+
enable_features = [ ]
90+
[tiles.gui]
91+
enabled = false
92+
[tiles.rpc]
93+
enabled = false
94+
[store]
95+
max_completed_shred_sets = 32768
96+
[funk]
97+
heap_size_gib = 1
98+
max_account_records = 2000000
99+
max_database_transactions = 64
100+
[runtime]
101+
max_live_slots = 32
102+
max_fork_width = 4
103+
[log]
104+
level_stderr = "NOTICE"
105+
path = "/tmp/ledger_log_solcap"
106+
107+
[paths]
108+
snapshots = "${ledger_dir}"
80109
81-
$OBJDIR/bin/firedancer-dev configure init all --config $DUMP/$LEDGER/devnet-398736132_current.toml
82-
$OBJDIR/bin/firedancer-dev backtest --config $DUMP/$LEDGER/devnet-398736132_current.toml
83-
$OBJDIR/bin/firedancer-dev configure fini all --config $DUMP/$LEDGER/devnet-398736132_current.toml
110+
[capture]
111+
solcap_capture = "${ledger_dir}/mainnet-376969880-solcap.solcap"
112+
[development]
113+
[development.snapshots]
114+
disable_lthash_verification = true
115+
[gossip]
116+
entrypoints = [ "0.0.0.0:1" ]
117+
EOF
118+
119+
$OBJDIR/bin/firedancer-dev backtest --config $DUMP/$LEDGER/mainnet-376969880_current.toml
120+
121+
# Run solcap-tools diff and check the summary for zero differences
122+
DIFF_OUTPUT=$($DUMP/solcap-tools/target/release/solcap-tools diff $DUMP/$LEDGER/mainnet-376969880-solcap.solcap $DUMP/$LEDGER/ledger_tool/bank_hash_details/ -v 5)
123+
echo "$DIFF_OUTPUT"
84124

85-
$OBJDIR/bin/fd_solcap_import $DUMP/$LEDGER/bank_hash_details/ $DUMP/$LEDGER/solana.solcap
86-
$OBJDIR/bin/fd_solcap_diff $DUMP/$LEDGER/solana.solcap $DUMP/$LEDGER/fd.solcap -v 4
125+
SUMMARY=$(echo "$DIFF_OUTPUT" | tail -3) > /dev/null 2>&1
126+
DIFFERING_SLOTS=$(echo "$SUMMARY" | grep -ioP 'Differing Slots: \K\d+' || echo "") > /dev/null 2>&1
127+
DIFFERING_ACCOUNTS=$(echo "$SUMMARY" | grep -ioP 'Differing Accounts: \K\d+' || echo "") > /dev/null 2>&1
128+
129+
if [[ "$DIFFERING_SLOTS" != "0" || "$DIFFERING_ACCOUNTS" != "0" ]]; then
130+
echo -e "\033[0;31mFAIL\033[0m Solcap diff found mismatches! Differing Slots: $DIFFERING_SLOTS, Differing Accounts: $DIFFERING_ACCOUNTS" >&2
131+
exit 1
132+
fi
87133

88-
# check that the ledger is not corrupted after a run
89-
check_ledger_checksum
134+
exit 0

src/app/firedancer-dev/commands/backtest.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include "../../../discof/tower/fd_tower_tile.h"
2828
#include "../../../discof/replay/fd_exec.h"
2929
#include "../../../ballet/lthash/fd_lthash.h"
30-
#include "../../../flamenco/runtime/context/fd_capture_ctx.h"
30+
#include "../../../flamenco/capture/fd_capture_ctx.h"
3131
#include "../../../disco/pack/fd_pack_cost.h"
3232
#include "../../../flamenco/progcache/fd_progcache_admin.h"
3333

@@ -102,6 +102,14 @@ backtest_topo( config_t * config ) {
102102
#define FOR(cnt) for( ulong i=0UL; i<cnt; i++ )
103103
FOR(exec_tile_cnt) fd_topob_tile( topo, "exec", "exec", "metric_in", cpu_idx++, 0, 0 );
104104
105+
/**********************************************************************/
106+
/* Add the capture tile to topo */
107+
/**********************************************************************/
108+
if( solcap_enabled ) {
109+
fd_topob_wksp( topo, "solcap" );
110+
fd_topob_tile( topo, "solcap", "solcap", "metric_in", cpu_idx++, 0, 0 );
111+
}
112+
105113
/**********************************************************************/
106114
/* Add the snapshot tiles to topo */
107115
/**********************************************************************/
@@ -313,15 +321,7 @@ backtest_topo( config_t * config ) {
313321
/**********************************************************************/
314322
fd_topob_wksp( topo, "exec_replay" );
315323

316-
/* If solcap is enabled, we need to overload this link to also send
317-
solcap account updates to the replay tile. We can't use a separate
318-
link for this without introducing a race. This will get removed with solcap V2. */
319-
if( FD_UNLIKELY( solcap_enabled ) ) {
320-
/* TODO: remove this with solcap V2 */
321-
FOR(exec_tile_cnt) fd_topob_link( topo, "exec_replay", "exec_replay", 1024UL, FD_CAPTURE_CTX_ACCOUNT_UPDATE_MSG_FOOTPRINT, 1UL );
322-
} else {
323-
FOR(exec_tile_cnt) fd_topob_link( topo, "exec_replay", "exec_replay", 16384UL, sizeof(fd_exec_task_done_msg_t), 1UL );
324-
}
324+
FOR(exec_tile_cnt) fd_topob_link( topo, "exec_replay", "exec_replay", 16384UL, sizeof(fd_exec_task_done_msg_t), 1UL );
325325

326326
FOR(exec_tile_cnt) fd_topob_tile_out( topo, "exec", i, "exec_replay", i );
327327
FOR(exec_tile_cnt) fd_topob_tile_in( topo, "replay", 0UL, "metric_in", "exec_replay", i, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
@@ -330,6 +330,18 @@ backtest_topo( config_t * config ) {
330330
/* Setup the shared objs used by replay and exec tiles */
331331
/**********************************************************************/
332332

333+
if( FD_UNLIKELY( solcap_enabled ) ) {
334+
/* 32 sections of SOLCAP_WRITE_ACCOUNT_DATA_MTU bytes each ≈ 4MB.
335+
This is done to ideally avoid cache thrashing and allow for all
336+
the links to sit on L3 cache. */
337+
fd_topob_link( topo, "cap_repl", "solcap", 32UL, SOLCAP_WRITE_ACCOUNT_DATA_MTU, 1UL );
338+
fd_topob_tile_out( topo, "replay", 0UL, "cap_repl", 0UL );
339+
fd_topob_tile_in( topo, "solcap", 0UL, "metric_in", "cap_repl", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
340+
FOR(exec_tile_cnt) fd_topob_link( topo, "cap_exec", "solcap", 32UL, SOLCAP_WRITE_ACCOUNT_DATA_MTU, 1UL );
341+
FOR(exec_tile_cnt) fd_topob_tile_out( topo, "exec", i, "cap_exec", i );
342+
FOR(exec_tile_cnt) fd_topob_tile_in( topo, "solcap", 0UL, "metric_in", "cap_exec", i, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
343+
}
344+
333345
fd_topob_wksp( topo, "store" );
334346
fd_topo_obj_t * store_obj = setup_topo_store( topo, "store", config->firedancer.store.max_completed_shred_sets, 1 );
335347
fd_topob_tile_uses( topo, backt_tile, store_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );

src/app/firedancer-dev/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ extern fd_topo_run_tile_t fd_tile_archiver_writer;
108108
extern fd_topo_run_tile_t fd_tile_archiver_playback;
109109
extern fd_topo_run_tile_t fd_tile_shredcap;
110110
extern fd_topo_run_tile_t fd_tile_vinyl;
111+
extern fd_topo_run_tile_t fd_tile_solcap;
111112

112113
extern fd_topo_run_tile_t fd_tile_snapct;
113114
extern fd_topo_run_tile_t fd_tile_snapld;
@@ -168,6 +169,7 @@ fd_topo_run_tile_t * TILES[] = {
168169
&fd_tile_genesi,
169170
&fd_tile_ipecho,
170171
&fd_tile_vinyl,
172+
&fd_tile_solcap,
171173
NULL,
172174
};
173175

src/app/firedancer/topology.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "../../util/tile/fd_tile_private.h"
2323
#include "../../discof/restore/utils/fd_ssctrl.h"
2424
#include "../../discof/restore/utils/fd_ssmsg.h"
25+
#include "../../flamenco/capture/fd_solcap_writer.h"
2526
#include "../../flamenco/progcache/fd_progcache_admin.h"
2627
#include "../../vinyl/meta/fd_vinyl_meta.h"
2728
#include "../../vinyl/io/fd_vinyl_io.h" /* FD_VINYL_IO_TYPE_* */
@@ -344,6 +345,8 @@ fd_topo_initialize( config_t * config ) {
344345
topo->max_page_size = fd_cstr_to_shmem_page_sz( config->hugetlbfs.max_page_size );
345346
topo->gigantic_page_threshold = config->hugetlbfs.gigantic_page_threshold_mib << 20;
346347

348+
int solcap_enabled = strlen( config->capture.solcap_capture ) > 0;
349+
347350
/* topo, name */
348351
fd_topob_wksp( topo, "metric" );
349352
fd_topob_wksp( topo, "genesi" );
@@ -619,6 +622,11 @@ fd_topo_initialize( config_t * config ) {
619622
/**/ fd_topob_tile( topo, "poh", "poh", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 1 );
620623
FOR(sign_tile_cnt) fd_topob_tile( topo, "sign", "sign", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 1 );
621624

625+
if( FD_UNLIKELY( solcap_enabled ) ) {
626+
fd_topob_wksp( topo, "solcap" );
627+
fd_topob_tile( topo, "solcap", "solcap", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 0 );
628+
}
629+
622630
/* topo, tile_name, tile_kind_id, fseq_wksp, link_name, link_kind_id, reliable, polled */
623631
FOR(gossvf_tile_cnt) for( ulong j=0UL; j<net_tile_cnt; j++ )
624632
fd_topob_tile_in( topo, "gossvf", i, "metric_in", "net_gossvf", j, FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED ); /* No reliable consumers of networking fragments, may be dropped or overrun */
@@ -898,6 +906,15 @@ fd_topo_initialize( config_t * config ) {
898906
fd_topob_tile_in( topo, "replay", 0UL, "metric_in", "rpc_replay", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
899907
}
900908

909+
if( FD_UNLIKELY( solcap_enabled ) ) {
910+
fd_topob_link( topo, "cap_repl", "solcap", 32UL, SOLCAP_WRITE_ACCOUNT_DATA_MTU, 1UL );
911+
fd_topob_tile_out( topo, "replay", 0UL, "cap_repl", 0UL );
912+
fd_topob_tile_in( topo, "solcap", 0UL, "metric_in", "cap_repl", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
913+
FOR(exec_tile_cnt) fd_topob_link( topo, "cap_exec", "solcap", 32UL, SOLCAP_WRITE_ACCOUNT_DATA_MTU, 1UL );
914+
FOR(exec_tile_cnt) fd_topob_tile_out( topo, "exec", i, "cap_exec", i );
915+
FOR(exec_tile_cnt) fd_topob_tile_in( topo, "solcap", 0UL, "metric_in", "cap_exec", i, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
916+
}
917+
901918
if( FD_LIKELY( !is_auto_affinity ) ) {
902919
if( FD_UNLIKELY( affinity_tile_cnt<topo->tile_cnt ) )
903920
FD_LOG_ERR(( "The topology you are using has %lu tiles, but the CPU affinity specified in the config tile as [layout.affinity] only provides for %lu cores. "
@@ -1480,6 +1497,13 @@ fd_topo_configure_tile( fd_topo_tile_t * tile,
14801497
FD_VINYL_IO_TYPE_UR : FD_VINYL_IO_TYPE_BD;
14811498
tile->vinyl.uring_depth = config->firedancer.vinyl.io_uring.queue_depth;
14821499

1500+
} else if( FD_UNLIKELY( !strcmp( tile->name, "solcap" ) ) ) {
1501+
1502+
tile->capctx.capture_start_slot = config->capture.capture_start_slot;
1503+
strncpy( tile->capctx.solcap_capture, config->capture.solcap_capture, sizeof(tile->capctx.solcap_capture) );
1504+
tile->capctx.recent_only = config->capture.recent_only;
1505+
tile->capctx.recent_slots_per_file = config->capture.recent_slots_per_file;
1506+
14831507
} else {
14841508
FD_LOG_ERR(( "unknown tile name `%s`", tile->name ));
14851509
}

src/app/shared/fd_config.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,10 @@ struct fd_configf {
167167
struct {
168168
ulong max_completed_shred_sets;
169169
} store;
170+
171+
struct {
172+
char path[ PATH_MAX ];
173+
} capctx;
170174
};
171175

172176
typedef struct fd_configf fd_configf_t;
@@ -496,6 +500,8 @@ struct fd_config {
496500
ulong capture_start_slot;
497501
char dump_proto_dir[ PATH_MAX ];
498502
char solcap_capture[ PATH_MAX ];
503+
int recent_only;
504+
ulong recent_slots_per_file;
499505
int dump_elf_to_pb;
500506
int dump_syscall_to_pb;
501507
int dump_instr_to_pb;

src/app/shared/fd_config_parse.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,8 @@ fd_config_extract_pod( uchar * pod,
247247

248248
CFG_POP ( ulong, capture.capture_start_slot );
249249
CFG_POP ( cstr, capture.solcap_capture );
250+
CFG_POP ( bool, capture.recent_only );
251+
CFG_POP ( ulong, capture.recent_slots_per_file );
250252
CFG_POP ( cstr, capture.dump_proto_dir );
251253
CFG_POP ( bool, capture.dump_elf_to_pb );
252254
CFG_POP ( bool, capture.dump_syscall_to_pb );

src/disco/topo/fd_topo.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,13 @@ struct fd_topo_tile {
628628
int io_type; /* FD_VINYL_IO_TYPE_* */
629629
uint uring_depth;
630630
} vinyl;
631+
632+
struct {
633+
ulong capture_start_slot;
634+
char solcap_capture[ PATH_MAX ];
635+
int recent_only;
636+
ulong recent_slots_per_file;
637+
} capctx;
631638
};
632639
};
633640

src/discof/capture/Local.mk

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ifdef FD_HAS_INT128
2+
ifdef FD_HAS_ALLOCA
3+
$(call add-objs,fd_solcap_tile,fd_discof)
4+
endif
5+
endif

0 commit comments

Comments
 (0)