From 0467f20883f66782ac04dc6a43c093589db4dac7 Mon Sep 17 00:00:00 2001 From: Michael McGee Date: Fri, 18 Aug 2023 18:56:25 +0000 Subject: [PATCH] fddev: add debugging wrapper --- .rustfmt.toml | 10 -- .vscode/launch.json | 37 +++++++ Cargo.toml | 10 -- config/with-optimization.mk | 6 +- deny.toml | 22 ----- ffi/rust/firedancer-sys/build.rs | 5 +- ffi/rust/firedancer-sys/src/tango/cnc.rs | 2 + ffi/rust/firedancer-sys/src/tango/fctl.rs | 6 ++ ffi/rust/firedancer-sys/src/tango/fseq.rs | 1 + ffi/rust/firedancer-sys/src/tango/mod.rs | 3 + ffi/rust/firedancer-sys/src/util/mod.rs | 4 + ffi/rust/firedancer-sys/src/util/pod.rs | 2 + ffi/rust/firedancer-sys/src/util/wksp.rs | 1 + ffi/rust/firedancer-sys/wrapper_util.h | 1 + src/app/fdctl/config.c | 55 +++++++---- src/app/fdctl/config.h | 1 + src/app/fdctl/config/default.toml | 6 +- src/app/fdctl/configure/workspace.c | 9 +- src/app/fdctl/fdctl.h | 10 ++ src/app/fdctl/monitor/monitor.c | 13 ++- src/app/fdctl/run.c | 3 + src/app/fddbg/Local.mk | 3 + src/app/fddbg/main.c | 113 ++++++++++++++++++++++ src/app/fddev/Local.mk | 3 +- src/app/fddev/configure/cluster.c | 3 +- src/app/fddev/dev.c | 9 ++ src/app/fddev/fddev.h | 14 +++ src/app/fddev/main.c | 1 + src/app/frank/fd_frank.h | 2 + src/app/frank/fd_frank_dedup.c | 1 + src/app/frank/fd_frank_pack.c | 20 ++-- src/app/frank/fd_frank_quic.c | 3 +- src/app/frank/fd_frank_verify.c | 34 +------ 33 files changed, 298 insertions(+), 115 deletions(-) delete mode 100644 .rustfmt.toml create mode 100644 .vscode/launch.json delete mode 100644 Cargo.toml delete mode 100644 deny.toml create mode 100644 src/app/fddbg/Local.mk create mode 100644 src/app/fddbg/main.c diff --git a/.rustfmt.toml b/.rustfmt.toml deleted file mode 100644 index 1bb00dfdf8..0000000000 --- a/.rustfmt.toml +++ /dev/null @@ -1,10 +0,0 @@ -max_width = 100 -comment_width = 100 -wrap_comments = true -format_code_in_doc_comments = true -format_strings = true -imports_granularity = "Module" -normalize_comments = true -normalize_doc_attributes = true -group_imports = "StdExternalCrate" -imports_layout = "Vertical" diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..5a3262759d --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,37 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "fddev", + "type": "cppdbg", + "request": "launch", + "cwd": "${workspaceFolder}/build/native/gcc/bin", + "program": "${workspaceFolder}/build/native/gcc/bin/fddev", + "args": ["--no-sandbox"], + "miDebuggerPath": "${workspaceFolder}/build/native/gcc/bin/fddbg", + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + }, + { + "description": "Don't detach on fork", + "text": "-gdb-set detach-on-fork off", + "ignoreFailures": false + }, + { + "description": "Stay parent after fork", + "text": "-gdb-set follow-fork-mode parent", + "ignoreFailures": false + } + ] + } + ] +} diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index 6fe709b2a3..0000000000 --- a/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[workspace] -members = ["ffi/rust/firedancer-sys", "ffi/rust/firedancer-diff"] -resolver = "2" - -[profile.dev] -panic = "abort" - -[profile.release] -panic = "abort" -lto = true diff --git a/config/with-optimization.mk b/config/with-optimization.mk index 74cf43babc..bd0dd8fe5d 100644 --- a/config/with-optimization.mk +++ b/config/with-optimization.mk @@ -1,3 +1,3 @@ -CPPFLAGS+=-O3 -ffast-math -fno-associative-math -fno-reciprocal-math -CPPFLAGS+=-DFD_HAS_OPTIMIZATION=1 -FD_HAS_OPTIMIZATION:=1 +# CPPFLAGS+=-O3 -ffast-math -fno-associative-math -fno-reciprocal-math +# CPPFLAGS+=-DFD_HAS_OPTIMIZATION=1 +# FD_HAS_OPTIMIZATION:=1 diff --git a/deny.toml b/deny.toml deleted file mode 100644 index 3c19e7ce84..0000000000 --- a/deny.toml +++ /dev/null @@ -1,22 +0,0 @@ -[licenses] -unlicensed = "deny" -default = "deny" -unused-allowed-license = "deny" -allow = [ - "MIT", - "Apache-2.0", - "BSD-2-Clause", - "BSD-3-Clause", - "0BSD", - "ISC", - "Unicode-DFS-2016", - "MPL-2.0", - "OpenSSL", -] - -[[licenses.clarify]] -name = "ring" -expression = "MIT AND ISC AND OpenSSL" -license-files = [ - { path = "LICENSE", hash = 0xbd0eed23 }, -] diff --git a/ffi/rust/firedancer-sys/build.rs b/ffi/rust/firedancer-sys/build.rs index a9295b239c..002caed55c 100644 --- a/ffi/rust/firedancer-sys/build.rs +++ b/ffi/rust/firedancer-sys/build.rs @@ -47,7 +47,10 @@ fn main() { // // We would need to `cargo clean` if any Makefile changes, which // isn't possible now. - println!("cargo:rerun-if-changed=../../../src"); + println!("cargo:rerun-if-changed=../../../src/util"); + println!("cargo:rerun-if-changed=../../../src/ballet"); + println!("cargo:rerun-if-changed=../../../src/tango"); + println!("cargo:rerun-if-changed=../../../src/disco"); "../../../" }; diff --git a/ffi/rust/firedancer-sys/src/tango/cnc.rs b/ffi/rust/firedancer-sys/src/tango/cnc.rs index fe4bdfa29a..17d19c1033 100644 --- a/ffi/rust/firedancer-sys/src/tango/cnc.rs +++ b/ffi/rust/firedancer-sys/src/tango/cnc.rs @@ -13,7 +13,9 @@ pub use crate::generated::{ fd_cnc_leave, fd_cnc_new, fd_cnc_open, + fd_cnc_signal, fd_cnc_signal_cstr, + fd_cnc_signal_query, fd_cnc_strerror, fd_cnc_t, fd_cnc_type, diff --git a/ffi/rust/firedancer-sys/src/tango/fctl.rs b/ffi/rust/firedancer-sys/src/tango/fctl.rs index eb32ef5094..654a6b4719 100644 --- a/ffi/rust/firedancer-sys/src/tango/fctl.rs +++ b/ffi/rust/firedancer-sys/src/tango/fctl.rs @@ -1,8 +1,14 @@ pub use crate::generated::{ fd_fctl_cfg_done, fd_fctl_cfg_rx_add, + fd_fctl_delete, + fd_fctl_join, + fd_fctl_leave, fd_fctl_new, + fd_fctl_private_rx_t, + fd_fctl_rx_cr_return, fd_fctl_t, + fd_fctl_tx_cr_update, FD_FCTL_ALIGN, FD_FCTL_RX_MAX_MAX, }; diff --git a/ffi/rust/firedancer-sys/src/tango/fseq.rs b/ffi/rust/firedancer-sys/src/tango/fseq.rs index fbdbc34290..605d620b94 100644 --- a/ffi/rust/firedancer-sys/src/tango/fseq.rs +++ b/ffi/rust/firedancer-sys/src/tango/fseq.rs @@ -1,5 +1,6 @@ pub use crate::generated::{ fd_fseq_align, + fd_fseq_app_laddr, fd_fseq_app_laddr_const, fd_fseq_delete, fd_fseq_footprint, diff --git a/ffi/rust/firedancer-sys/src/tango/mod.rs b/ffi/rust/firedancer-sys/src/tango/mod.rs index 77d451c0a7..5a9762ef9f 100644 --- a/ffi/rust/firedancer-sys/src/tango/mod.rs +++ b/ffi/rust/firedancer-sys/src/tango/mod.rs @@ -13,3 +13,6 @@ pub use fseq::*; pub use mcache::*; pub use tcache::*; pub use xdp::*; + +pub use crate::generated::fd_chunk_to_laddr; +pub use crate::generated::fd_chunk_to_laddr_const; diff --git a/ffi/rust/firedancer-sys/src/util/mod.rs b/ffi/rust/firedancer-sys/src/util/mod.rs index 3d99fc0fbb..dbfd9e5ee7 100644 --- a/ffi/rust/firedancer-sys/src/util/mod.rs +++ b/ffi/rust/firedancer-sys/src/util/mod.rs @@ -1,14 +1,18 @@ mod bits; mod log; mod pod; +mod rng; mod shmem; +mod tempo; mod tile; mod wksp; pub use bits::*; pub use log::*; pub use pod::*; +pub use rng::*; pub use shmem::*; +pub use tempo::*; pub use tile::*; pub use wksp::*; diff --git a/ffi/rust/firedancer-sys/src/util/pod.rs b/ffi/rust/firedancer-sys/src/util/pod.rs index 16687f7bf8..44a9150bf2 100644 --- a/ffi/rust/firedancer-sys/src/util/pod.rs +++ b/ffi/rust/firedancer-sys/src/util/pod.rs @@ -1,6 +1,8 @@ pub use crate::generated::{ fd_pod_cnt_subpod, fd_pod_info_t, + fd_pod_join, + fd_pod_leave, fd_pod_query, fd_pod_query_buf, fd_pod_query_char, diff --git a/ffi/rust/firedancer-sys/src/util/wksp.rs b/ffi/rust/firedancer-sys/src/util/wksp.rs index f43cad4483..83da7cc153 100644 --- a/ffi/rust/firedancer-sys/src/util/wksp.rs +++ b/ffi/rust/firedancer-sys/src/util/wksp.rs @@ -27,5 +27,6 @@ pub use crate::generated::{ fd_wksp_pod_map, fd_wksp_pod_unmap, fd_wksp_t, + fd_wksp_private, fd_wksp_unmap, }; diff --git a/ffi/rust/firedancer-sys/wrapper_util.h b/ffi/rust/firedancer-sys/wrapper_util.h index 01c6b72bc2..948fcfea45 100644 --- a/ffi/rust/firedancer-sys/wrapper_util.h +++ b/ffi/rust/firedancer-sys/wrapper_util.h @@ -1,4 +1,5 @@ #include "src/util/fd_util.h" +#include "src/util/wksp/fd_wksp_private.h" #if FD_MCACHE_LG_INTERLEAVE #error "FD_MCACHE_LG_INTERLEAVE unsupported" diff --git a/src/app/fdctl/config.c b/src/app/fdctl/config.c index ddaf4c4e80..591152e99c 100644 --- a/src/app/fdctl/config.c +++ b/src/app/fdctl/config.c @@ -26,8 +26,9 @@ find_wksp( config_t * const config, /* partial frank_bank definition since the tile doesn't really exist */ static fd_frank_task_t frank_bank = { - .in_wksp = "pack_bank", - .out_wksp = "bank_shred", + .in_wksp = "pack_bank", + .out_wksp = "bank_shred", + .extra_wksp = NULL, }; ulong @@ -36,21 +37,29 @@ memlock_max_bytes( config_t * const config ) { for( ulong j=0; jshmem.workspaces_cnt; j++ ) { workspace_config_t * wksp = &config->shmem.workspaces[ j ]; -#define TILE_MAX( tile ) do { \ - ulong in_bytes = 0, out_bytes = 0; \ - if( FD_LIKELY( tile.in_wksp ) ) { \ - workspace_config_t * in_wksp = find_wksp( config, tile.in_wksp ); \ - in_bytes = in_wksp->num_pages * in_wksp->page_size; \ - } \ - if( FD_LIKELY( tile.out_wksp ) ) { \ - workspace_config_t * out_wksp = find_wksp( config, tile.out_wksp ); \ - out_bytes = out_wksp->num_pages * out_wksp->page_size; \ - } \ - memlock_max_bytes = fd_ulong_max( memlock_max_bytes, \ - wksp->page_size * wksp->num_pages + in_bytes + out_bytes ); \ +#define TILE_MAX( tile ) do { \ + ulong in_bytes = 0, out_bytes = 0, extra_bytes = 0; \ + if( FD_LIKELY( tile.in_wksp ) ) { \ + workspace_config_t * in_wksp = find_wksp( config, tile.in_wksp ); \ + in_bytes = in_wksp->num_pages * in_wksp->page_size; \ + } \ + if( FD_LIKELY( tile.out_wksp ) ) { \ + workspace_config_t * out_wksp = find_wksp( config, tile.out_wksp ); \ + out_bytes = out_wksp->num_pages * out_wksp->page_size; \ + } \ + if( FD_LIKELY( tile.extra_wksp ) ) { \ + workspace_config_t * extra_wksp = find_wksp( config, tile.extra_wksp ); \ + extra_bytes = extra_wksp->num_pages * extra_wksp->page_size; \ + } \ + memlock_max_bytes = fd_ulong_max( memlock_max_bytes, \ + wksp->page_size * wksp->num_pages + \ + in_bytes + \ + out_bytes + \ + extra_bytes ); \ } while(0) switch ( wksp->kind ) { + case wksp_tpu_txn_data: case wksp_quic_verify: case wksp_verify_dedup: case wksp_dedup_pack: @@ -461,21 +470,27 @@ static void init_workspaces( config_t * config ) { ulong idx = 0; - config->shmem.workspaces[ idx ].kind = wksp_quic_verify; - config->shmem.workspaces[ idx ].name = "quic_verify"; + config->shmem.workspaces[ idx ].kind = wksp_tpu_txn_data; + config->shmem.workspaces[ idx ].name = "tpu_txn_data"; config->shmem.workspaces[ idx ].page_size = FD_SHMEM_GIGANTIC_PAGE_SZ; config->shmem.workspaces[ idx ].num_pages = 1; idx++; + config->shmem.workspaces[ idx ].kind = wksp_quic_verify; + config->shmem.workspaces[ idx ].name = "quic_verify"; + config->shmem.workspaces[ idx ].page_size = FD_SHMEM_HUGE_PAGE_SZ; + config->shmem.workspaces[ idx ].num_pages = 2; + idx++; + config->shmem.workspaces[ idx ].kind = wksp_verify_dedup; config->shmem.workspaces[ idx ].name = "verify_dedup"; - config->shmem.workspaces[ idx ].page_size = FD_SHMEM_GIGANTIC_PAGE_SZ; - config->shmem.workspaces[ idx ].num_pages = 1; + config->shmem.workspaces[ idx ].page_size = FD_SHMEM_HUGE_PAGE_SZ; + config->shmem.workspaces[ idx ].num_pages = 2; idx++; config->shmem.workspaces[ idx ].kind = wksp_dedup_pack; config->shmem.workspaces[ idx ].name = "dedup_pack"; - config->shmem.workspaces[ idx ].page_size = FD_SHMEM_GIGANTIC_PAGE_SZ; + config->shmem.workspaces[ idx ].page_size = FD_SHMEM_HUGE_PAGE_SZ; config->shmem.workspaces[ idx ].num_pages = 1; idx++; @@ -517,7 +532,7 @@ init_workspaces( config_t * config ) { config->shmem.workspaces[ idx ].kind = wksp_pack; config->shmem.workspaces[ idx ].name = "pack"; - config->shmem.workspaces[ idx ].page_size = FD_SHMEM_HUGE_PAGE_SZ; + config->shmem.workspaces[ idx ].page_size = FD_SHMEM_GIGANTIC_PAGE_SZ; config->shmem.workspaces[ idx ].num_pages = 1; idx++; diff --git a/src/app/fdctl/config.h b/src/app/fdctl/config.h index b09f8bd777..4ba40671b2 100644 --- a/src/app/fdctl/config.h +++ b/src/app/fdctl/config.h @@ -14,6 +14,7 @@ typedef struct { enum { + wksp_tpu_txn_data, wksp_quic_verify, wksp_verify_dedup, wksp_dedup_pack, diff --git a/src/app/fdctl/config/default.toml b/src/app/fdctl/config/default.toml index 348615455d..83cc82da4b 100644 --- a/src/app/fdctl/config/default.toml +++ b/src/app/fdctl/config/default.toml @@ -112,13 +112,13 @@ dynamic_port_range = "8000-10000" # If nonzero, enable JSON RPC on this port, and use the next port for the # RPC websocket. If zero, disable JSON RPC. This option is passed to the # Solana Labs client with the `--rpc-port` argument. - port = 0 + port = 8899 # If true, all RPC operations are enabled on this validator, including # non-default RPC methods for querying chain state and transaction history. # This option is passed to the Solana Labs client with the `--full-rpc-api` # argument. - full_api = false + full_api = true # If the RPC is private, the valdiator's open RPC port is not published in # the `solana gossip` command for use by others. This option is passed to @@ -129,7 +129,7 @@ dynamic_port_range = "8000-10000" # `getConfirmedBlock` API. This will cause an increase in disk usage and # IOPS. This option is passed to the Solana Labs client with the # `--enable-rpc-transaction-history` argument. - transaction_history = false + transaction_history = true # If enabled, include CPI inner instructions, logs, and return data in the # historical transaction info stored. This option is passed to the Solana diff --git a/src/app/fdctl/configure/workspace.c b/src/app/fdctl/configure/workspace.c index 3e174c5491..394ca5f6a2 100644 --- a/src/app/fdctl/configure/workspace.c +++ b/src/app/fdctl/configure/workspace.c @@ -216,10 +216,14 @@ init( config_t * const config ) { WKSP_BEGIN( config, wksp1, 0 ); switch( wksp1->kind ) { + case wksp_tpu_txn_data: + for( ulong i=0; ilayout.verify_tile_count; i++ ) { + dcache( pod, "dcache%lu", config->tiles.verify.mtu, config->tiles.verify.receive_buffer_size, config->tiles.verify.receive_buffer_size * 32, i ); + } + break; case wksp_quic_verify: for( ulong i=0; ilayout.verify_tile_count; i++ ) { mcache( pod, "mcache%lu", config->tiles.verify.receive_buffer_size, i ); - dcache( pod, "dcache%lu", config->tiles.verify.mtu, config->tiles.verify.receive_buffer_size, config->tiles.verify.receive_buffer_size * 32, i ); fseq ( pod, "fseq%lu", i ); } break; @@ -227,7 +231,6 @@ init( config_t * const config ) { ulong1( pod, "cnt", config->layout.verify_tile_count ); for( ulong i=0; ilayout.verify_tile_count; i++ ) { mcache( pod, "mcache%lu", config->tiles.verify.receive_buffer_size, i ); - dcache( pod, "dcache%lu", config->tiles.verify.mtu, config->tiles.verify.receive_buffer_size, 0, i ); fseq ( pod, "fseq%lu", i ); } break; @@ -241,6 +244,8 @@ init( config_t * const config ) { mcache( pod, "mcache%lu", config->tiles.bank.receive_buffer_size, i ); dcache( pod, "dcache%lu", USHORT_MAX, config->layout.bank_tile_count * (ulong)config->tiles.bank.receive_buffer_size, 0, i ); fseq ( pod, "fseq%lu", i ); + mcache( pod, "mcache-back%lu", config->tiles.bank.receive_buffer_size, i ); + fseq ( pod, "fseq-back%lu", i ); } break; case wksp_bank_shred: diff --git a/src/app/fdctl/fdctl.h b/src/app/fdctl/fdctl.h index cc91437ea2..589e8a25c3 100644 --- a/src/app/fdctl/fdctl.h +++ b/src/app/fdctl/fdctl.h @@ -33,6 +33,16 @@ typedef union { struct { int monitor; } dev; + struct { + const char * payload_base64; + ulong count; + const char * dst_ip; + ushort dst_port; + } txn; + struct { + int setcap; + int withcap; + } gdb; } args_t; typedef struct security security_t; diff --git a/src/app/fdctl/monitor/monitor.c b/src/app/fdctl/monitor/monitor.c index b3bf1d0a15..e91db61826 100644 --- a/src/app/fdctl/monitor/monitor.c +++ b/src/app/fdctl/monitor/monitor.c @@ -206,7 +206,8 @@ run_monitor( config_t * const config, config->layout.verify_tile_count + // quic <-> verify config->layout.verify_tile_count + // verify <-> dedup 1 + // dedup <-> pack - config->layout.bank_tile_count; // pack <-> bank + config->layout.bank_tile_count + // pack <-> bank + config->layout.bank_tile_count; // bank <-> pack tile_t * tiles = fd_alloca( alignof(tile_t *), sizeof(tile_t)*tile_cnt ); link_t * links = fd_alloca( alignof(link_t *), sizeof(link_t)*link_cnt ); @@ -220,6 +221,8 @@ run_monitor( config_t * const config, char buf[ 64 ]; switch( wksp->kind ) { + case wksp_tpu_txn_data: + break; case wksp_quic_verify: for( ulong i=0; ilayout.verify_tile_count; i++ ) { links[ link_idx ].src_name = "quic"; @@ -260,6 +263,14 @@ run_monitor( config_t * const config, links[ link_idx ].fseq = fd_fseq_join( fd_wksp_pod_map( pods[ j ], snprintf1( buf, 64, "fseq%lu", i ) ) ); if( FD_UNLIKELY( !links[ link_idx ].fseq ) ) FD_LOG_ERR(( "fd_fseq_join failed" )); link_idx++; + + links[ link_idx ].src_name = "bank"; + links[ link_idx ].dst_name = "pack"; + links[ link_idx ].mcache = fd_mcache_join( fd_wksp_pod_map( pods[ j ], snprintf1( buf, 64, "mcache-back%lu", i ) ) ); + if( FD_UNLIKELY( !links[ link_idx ].mcache ) ) FD_LOG_ERR(( "fd_mcache_join failed" )); + links[ link_idx ].fseq = fd_fseq_join( fd_wksp_pod_map( pods[ j ], snprintf1( buf, 64, "fseq-back%lu", i ) ) ); + if( FD_UNLIKELY( !links[ link_idx ].fseq ) ) FD_LOG_ERR(( "fd_fseq_join failed" )); + link_idx++; } break; case wksp_bank_shred: diff --git a/src/app/fdctl/run.c b/src/app/fdctl/run.c index 7015ac4804..01f2892e3f 100644 --- a/src/app/fdctl/run.c +++ b/src/app/fdctl/run.c @@ -111,6 +111,7 @@ tile_main( void * _args ) { .tile_name = args->tile->name, .in_pod = NULL, .out_pod = NULL, + .extra_pod = NULL, .tick_per_ns = args->tick_per_ns, }; @@ -119,6 +120,8 @@ tile_main( void * _args ) { frank_args.in_pod = workspace_pod_join( args->app_name, args->tile->in_wksp, 0 ); if( FD_LIKELY( args->tile->out_wksp ) ) frank_args.out_pod = workspace_pod_join( args->app_name, args->tile->out_wksp, 0 ); + if( FD_LIKELY( args->tile->extra_wksp ) ) + frank_args.extra_pod = workspace_pod_join( args->app_name, args->tile->extra_wksp, 0 ); if( FD_UNLIKELY( args->tile->init ) ) args->tile->init( &frank_args ); diff --git a/src/app/fddbg/Local.mk b/src/app/fddbg/Local.mk new file mode 100644 index 0000000000..4f5efd6914 --- /dev/null +++ b/src/app/fddbg/Local.mk @@ -0,0 +1,3 @@ +ifdef FD_HAS_HOSTED +$(call make-bin,fddbg,main,fd_util) +endif diff --git a/src/app/fddbg/main.c b/src/app/fddbg/main.c new file mode 100644 index 0000000000..219035c255 --- /dev/null +++ b/src/app/fddbg/main.c @@ -0,0 +1,113 @@ +#define _GNU_SOURCE + +#include "../../util/fd_util.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int +has_all_capabilities( void ) { + struct __user_cap_header_struct capheader; + struct __user_cap_data_struct capdata[2]; + + capheader.version = _LINUX_CAPABILITY_VERSION_3; + capheader.pid = 0; + FD_TEST( syscall( SYS_capget, &capheader, &capdata ) >= 0 ); + return + capdata[0].permitted == 0xFFFFFFFF && + ( capdata[1].permitted & 0x000001FF ) == 0x000001FF; +} + +static void +raise_all_capabilities( void ) { + struct __user_cap_header_struct capheader; + struct __user_cap_data_struct capdata[2]; + + capheader.version = _LINUX_CAPABILITY_VERSION_3; + capheader.pid = 0; + FD_TEST( syscall( SYS_capget, &capheader, &capdata ) >= 0 ); + + capdata[0].effective = 0xFFFFFFFF; + capdata[0].inheritable = 0xFFFFFFFF; + capdata[1].effective = 0xFFFFFFFF; + capdata[1].inheritable = 0xFFFFFFFF; + FD_TEST( syscall(SYS_capset, &capheader, &capdata) >= 0 ); + + for ( int cap = 0; cap <= CAP_LAST_CAP; cap++ ) + FD_TEST( !prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0) ); +} + +static void +self_exe( char * path ) { + long count = readlink( "/proc/self/exe", path, PATH_MAX ); + FD_TEST( count >= 0 && count < PATH_MAX ); + path[ count ] = '\0'; +} + +int +main( int argc, + char ** argv ) { + fd_boot( &argc, &argv ); + + for( int i=0; i 1 && !strcmp( argv[1], "--setcap" ) ) ) { + struct vfs_cap_data { + __le32 magic_etc; + struct { + __le32 permitted; + __le32 inheritable; + } data[2]; + } cap_data; + + cap_data.magic_etc = VFS_CAP_REVISION_2; + cap_data.data[0].permitted = 0xFFFFFFFF; + cap_data.data[0].inheritable = 0xFFFFFFFF; + cap_data.data[1].permitted = 0xFFFFFFFF; + cap_data.data[1].inheritable = 0xFFFFFFFF; + + char self_path[ PATH_MAX ]; + self_exe( self_path ); + FD_TEST( !setxattr( self_path, "security.capability", &cap_data, sizeof(cap_data), 0) ); + } else { + if( FD_UNLIKELY( !has_all_capabilities() ) ) { + if ( FD_UNLIKELY( argc > 1 && !strcmp( argv[1], "--withcap" ) ) ) FD_LOG_ERR(( "missing capabilities" )); + + char self_path[ PATH_MAX ]; + self_exe( self_path ); + + pid_t child = fork(); + FD_TEST( child >= 0 ); + if( child == 0 ) execv( "/bin/sudo", (char *[]){ "sudo", self_path, "--setcap", NULL } ); + else { + int wstatus; + FD_TEST( waitpid( child, &wstatus, 0 ) >= 0 ); + FD_TEST( WIFEXITED( wstatus ) && !WEXITSTATUS( wstatus ) ); + char self_path[ PATH_MAX ]; + self_exe( self_path ); + FD_TEST( execv( self_path, (char *[]){ "fddbg", "--withcap", NULL } ) >= 0 ); + } + } else { + raise_all_capabilities(); + + char * args[ 32 ]; + int start = argc > 1 && !strcmp( argv[1], "--withcap" ) ? 2 : 1; + args[0] = "/bin/gdb"; + for( int i=start; i= 0 ); + } + } +} diff --git a/src/app/fddev/Local.mk b/src/app/fddev/Local.mk index c3be981c5e..8444707d9e 100644 --- a/src/app/fddev/Local.mk +++ b/src/app/fddev/Local.mk @@ -2,8 +2,7 @@ ifdef FD_HAS_HOSTED ifdef FD_HAS_ALLOCA ifdef FD_HAS_X86 ifdef FD_HAS_DOUBLE -$(call make-bin,fddev,main dev dev1 configure/netns configure/cluster,fd_fdctl fd_frank fd_disco fd_ballet fd_tango fd_util fd_quic solana_validator_fd) -$(OBJDIR)/bin/fddev: src/app/fdctl/config/default.toml +$(call make-bin,fddev,main dev dev1 txn configure/netns configure/cluster,fd_fdctl fd_frank fd_disco fd_ballet fd_tango fd_util fd_quic solana_validator_fd) endif endif endif diff --git a/src/app/fddev/configure/cluster.c b/src/app/fddev/configure/cluster.c index 5adbb1e4d5..3d0ff2051f 100644 --- a/src/app/fddev/configure/cluster.c +++ b/src/app/fddev/configure/cluster.c @@ -53,6 +53,7 @@ init( config_t * const config ) { ADD( "--bootstrap-validator", config->consensus.identity_path ); ADD1( vote ); ADD1( stake ); + ADD( "--bootstrap-stake-authorized-pubkey", config->consensus.identity_path ); ADD( "--ledger", config->ledger.path ); ADD( "--faucet-pubkey", faucet ); @@ -153,7 +154,7 @@ check( config_t * const config ) { configure_stage_t cluster = { .name = NAME, - .always_recreate = 0, + .always_recreate = 1, .enabled = enabled, .init_perm = NULL, .fini_perm = NULL, diff --git a/src/app/fddev/dev.c b/src/app/fddev/dev.c index 2cca23ce6e..f47346bcaf 100644 --- a/src/app/fddev/dev.c +++ b/src/app/fddev/dev.c @@ -74,6 +74,15 @@ dev_cmd_fn( args_t * args, validator will get stuck forever. */ config->consensus.wait_for_vote_to_start_leader = 0; + config->consensus.genesis_fetch = 0; + config->consensus.snapshot_fetch = 0; + + if( FD_LIKELY( !strcmp( config->consensus.vote_account_path, "" ) ) ) + snprintf1( config->consensus.vote_account_path, + sizeof( config->consensus.vote_account_path ), + "%s/vote-account.json", + config->scratch_directory ); + if( FD_UNLIKELY( config->development.netns.enabled ) ) { /* if we entered a network namespace during configuration, leave it so that `run_firedancer` starts from a clean namespace */ diff --git a/src/app/fddev/fddev.h b/src/app/fddev/fddev.h index a8858ee0a7..a8a2ccb840 100644 --- a/src/app/fddev/fddev.h +++ b/src/app/fddev/fddev.h @@ -26,4 +26,18 @@ void dev1_cmd_fn( args_t * args, config_t * const config ); +void +txn_cmd_perm( args_t * args, + security_t * security, + config_t * const config ); + +void +txn_cmd_args( int * pargc, + char *** pargv, + args_t * args); + +void +txn_cmd_fn( args_t * args, + config_t * const config ); + #endif /* HEADER_fd_src_app_fddev_fddev_h */ diff --git a/src/app/fddev/main.c b/src/app/fddev/main.c index 0288964056..c51b94798b 100644 --- a/src/app/fddev/main.c +++ b/src/app/fddev/main.c @@ -26,6 +26,7 @@ configure_stage_t * STAGES[ CONFIGURE_STAGE_COUNT ] = { static action_t DEV_ACTIONS[] = { { .name = "dev", .args = dev_cmd_args, .fn = dev_cmd_fn, .perm = dev_cmd_perm }, { .name = "dev1", .args = dev1_cmd_args, .fn = dev1_cmd_fn, .perm = dev_cmd_perm }, + { .name = "txn", .args = txn_cmd_args, .fn = txn_cmd_fn, .perm = txn_cmd_perm }, }; #define MAX_ARGC 32 diff --git a/src/app/frank/fd_frank.h b/src/app/frank/fd_frank.h index 063fbe5d7d..e0488848e6 100644 --- a/src/app/frank/fd_frank.h +++ b/src/app/frank/fd_frank.h @@ -35,6 +35,7 @@ typedef struct { uchar const * tile_pod; uchar const * in_pod; uchar const * out_pod; + uchar const * extra_pod; fd_xsk_t * xsk; double tick_per_ns; } fd_frank_args_t; @@ -43,6 +44,7 @@ typedef struct { char * name; char * in_wksp; char * out_wksp; + char * extra_wksp; ushort allow_syscalls_sz; long * allow_syscalls; ulong (*allow_fds)( fd_frank_args_t * args, ulong out_fds_sz, int * out_fds ); diff --git a/src/app/frank/fd_frank_dedup.c b/src/app/frank/fd_frank_dedup.c index 4e1c598078..38be9d1877 100644 --- a/src/app/frank/fd_frank_dedup.c +++ b/src/app/frank/fd_frank_dedup.c @@ -101,6 +101,7 @@ fd_frank_task_t frank_dedup = { .name = "dedup", .in_wksp = "verify_dedup", .out_wksp = "dedup_pack", + .extra_wksp = NULL, .allow_syscalls_sz = sizeof(allow_syscalls)/sizeof(allow_syscalls[ 0 ]), .allow_syscalls = allow_syscalls, .allow_fds = allow_fds, diff --git a/src/app/frank/fd_frank_pack.c b/src/app/frank/fd_frank_pack.c index 22ec94f435..0db7b2f3a3 100644 --- a/src/app/frank/fd_frank_pack.c +++ b/src/app/frank/fd_frank_pack.c @@ -108,9 +108,9 @@ run( fd_frank_args_t * args ) { FD_LOG_INFO(( "joining dcache%lu", args->tile_idx )); /* Note (chunks are referenced relative to the containing workspace - currently and there is just one workspace). (FIXME: VALIDATE - COMMON WORKSPACE FOR THESE) */ - fd_wksp_t * wksp = fd_wksp_containing( mcache ); + currently and there is just one workspace). */ + uchar * dcache = fd_dcache_join( fd_wksp_pod_map( args->extra_pod, "dcache0" ) ); + fd_wksp_t * wksp = fd_wksp_containing( dcache ); if( FD_UNLIKELY( !wksp ) ) FD_LOG_ERR(( "fd_wksp_containing failed" )); FD_LOG_INFO(( "joining fseq" )); @@ -140,12 +140,12 @@ run( fd_frank_args_t * args ) { out_state out[ FD_FRANK_PACK_MAX_OUT ]; /* FIXME: Plumb this through properly: */ - ulong bank_cnt = fd_pod_cnt( args->out_pod ) / 3UL - 1UL; /* Skip bank 0 */ + ulong bank_cnt = fd_pod_query_ulong( args->out_pod, "num_tiles", 0UL ); + if( FD_UNLIKELY( !bank_cnt ) ) FD_LOG_ERR(( "pack.num_tiles unset or set to zero" )); if( FD_UNLIKELY( bank_cnt>FD_FRANK_PACK_MAX_OUT ) ) FD_LOG_ERR(( "pack tile connects to too many banking tiles" )); - /* Skip bank 0 */ - for( ulong i=0UL; iout_pod, i+1UL ); - + for( ulong i=0UL; iout_pod, i ); + fd_wksp_t * out_wksp = fd_wksp_containing( args->out_pod ); ulong max_txn_per_microblock = MAX_MICROBLOCK_SZ/sizeof(fd_txn_p_t); @@ -169,8 +169,7 @@ run( fd_frank_args_t * args ) { fd_rng_t * rng = fd_rng_join( fd_rng_new( _rng, seed, 0UL ) ); if( FD_UNLIKELY( !rng ) ) FD_LOG_ERR(( "fd_rng_join failed" )); - - void * pack_laddr = fd_wksp_alloc_laddr( wksp, fd_pack_align(), pack_footprint, FD_PACK_TAG ); + void * pack_laddr = fd_wksp_alloc_laddr( fd_wksp_containing( args->tile_pod ), fd_pack_align(), pack_footprint, FD_PACK_TAG ); if( FD_UNLIKELY( !pack_laddr ) ) FD_LOG_ERR(( "allocating memory for pack object failed" )); @@ -254,7 +253,7 @@ run( fd_frank_args_t * args ) { for( ulong i=0UL; iout_cr_avail>0UL ) ) { /* optimize for the case we send a microblock */ - void * microblock_dst = fd_chunk_to_laddr( wksp, o->out_chunk ); + void * microblock_dst = fd_chunk_to_laddr( out_wksp, o->out_chunk ); ulong schedule_cnt = fd_pack_schedule_next_microblock( pack, cus_per_microblock, vote_fraction, microblock_dst ); if( FD_LIKELY( schedule_cnt ) ) { ulong tspub = (ulong)fd_frag_meta_ts_comp( fd_tickcount() ); @@ -362,6 +361,7 @@ fd_frank_task_t frank_pack = { .name = "pack", .in_wksp = "dedup_pack", .out_wksp = "pack_bank", + .extra_wksp = "tpu_txn_data", .allow_syscalls_sz = sizeof(allow_syscalls)/sizeof(allow_syscalls[ 0 ]), .allow_syscalls = allow_syscalls, .allow_fds = allow_fds, diff --git a/src/app/frank/fd_frank_quic.c b/src/app/frank/fd_frank_quic.c index 98153aa8b6..1229c532b6 100644 --- a/src/app/frank/fd_frank_quic.c +++ b/src/app/frank/fd_frank_quic.c @@ -53,7 +53,7 @@ run( fd_frank_args_t * args ) { FD_LOG_INFO(( "joining dcache" )); snprintf( path, sizeof(path), "dcache%lu", args->tile_idx ); - uchar * dcache = fd_dcache_join( fd_wksp_pod_map( args->out_pod, path ) ); + uchar * dcache = fd_dcache_join( fd_wksp_pod_map( args->extra_pod, path ) ); if( FD_UNLIKELY( !dcache ) ) FD_LOG_ERR(( "fd_dcache_join failed" )); FD_LOG_INFO(( "loading quic" )); @@ -154,6 +154,7 @@ fd_frank_task_t frank_quic = { .name = "quic", .in_wksp = NULL, .out_wksp = "quic_verify", + .extra_wksp = "tpu_txn_data", .allow_syscalls_sz = sizeof(allow_syscalls)/sizeof(allow_syscalls[ 0 ]), .allow_syscalls = allow_syscalls, .allow_fds = allow_fds, diff --git a/src/app/frank/fd_frank_verify.c b/src/app/frank/fd_frank_verify.c index f964d04be2..0820969651 100644 --- a/src/app/frank/fd_frank_verify.c +++ b/src/app/frank/fd_frank_verify.c @@ -33,7 +33,7 @@ run( fd_frank_args_t * args ) { FD_LOG_INFO(( "joining dcache%lu", args->tile_idx )); snprintf( path, sizeof(path), "dcache%lu", args->tile_idx ); - uchar * vin_dcache = fd_dcache_join( fd_wksp_pod_map( args->in_pod, path ) ); + uchar * vin_dcache = fd_dcache_join( fd_wksp_pod_map( args->extra_pod, path ) ); if( FD_UNLIKELY( !vin_dcache ) ) FD_LOG_ERR(( "fd_dcache_join failed" )); fd_wksp_t * vin_wksp = fd_wksp_containing( vin_dcache ); /* chunks are referenced relative to the containing workspace */ if( FD_UNLIKELY( !vin_wksp ) ) FD_LOG_ERR(( "fd_wksp_containing failed" )); @@ -104,16 +104,6 @@ run( fd_frank_args_t * args ) { ulong * sync = fd_mcache_seq_laddr( mcache ); ulong seq = fd_mcache_seq_query( sync ); - FD_LOG_INFO(( "joining dcache%lu", args->tile_idx )); - snprintf( path, sizeof(path), "dcache%lu", args->tile_idx ); - uchar * dcache = fd_dcache_join( fd_wksp_pod_map( args->out_pod, path ) ); - if( FD_UNLIKELY( !dcache ) ) FD_LOG_ERR(( "fd_dcache_join failed" )); - fd_wksp_t * wksp = fd_wksp_containing( dcache ); /* chunks are referenced relative to the containing workspace */ - if( FD_UNLIKELY( !wksp ) ) FD_LOG_ERR(( "fd_wksp_containing failed" )); - ulong chunk0 = fd_dcache_compact_chunk0( wksp, dcache ); - ulong wmark = fd_dcache_compact_wmark ( wksp, dcache, 1542UL ); /* FIXME: MTU? SAFETY CHECK THE FOOTPRINT? */ - ulong chunk = chunk0; - FD_LOG_INFO(( "joining fseq%lu", args->tile_idx )); snprintf( path, sizeof(path), "fseq%lu", args->tile_idx ); ulong * fseq = fd_fseq_join( fd_wksp_pod_map( args->out_pod, path ) ); @@ -290,27 +280,13 @@ run( fd_frank_args_t * args ) { continue; } - now = fd_tickcount(); + uint chunk = vin_mline->chunk; - /* At this point, we have started receiving frag seq with details in - mline at time now. Speculatively processs it here. */ ulong vin_data_sz = (ulong)vin_mline->sz; - uchar * vin_dcache_chunk_laddr = (uchar *)fd_chunk_to_laddr( vin_wksp, vin_mline->chunk ); - uchar * udp_payload = (uchar *)fd_chunk_to_laddr( wksp, chunk ); - memcpy(udp_payload, vin_dcache_chunk_laddr, vin_data_sz); - - /* Check that we weren't overrun while processing */ - vin_seq_found = fd_frag_meta_seq_query( vin_mline ); - if( FD_UNLIKELY( fd_seq_ne( vin_seq_found, vin_mcache_seq ) ) ) { - vin_accum_ovrnr_cnt++; - FD_LOG_INFO(( "verifyin.%lu ovrnr encountered: vin_mcache_seq=%lu vin_seq_found=%lu vin_accum_ovrnr_cnt=%lu", args->tile_idx, vin_mcache_seq, vin_seq_found, vin_accum_ovrnr_cnt )); - vin_mcache_seq = vin_seq_found; - now = fd_tickcount(); - continue; - } + uchar * udp_payload = (uchar *)fd_chunk_to_laddr( vin_wksp, chunk ); vin_accum_pub_cnt++; - vin_accum_pub_sz += vin_data_sz; + vin_accum_pub_sz += (ulong)vin_mline->sz; /* Wind up for the next iteration for verifyin */ vin_mcache_seq = fd_seq_inc( vin_mcache_seq, 1UL ); @@ -393,7 +369,6 @@ run( fd_frank_args_t * args ) { ulong tsorig = tspub; fd_mcache_publish( mcache, depth, seq, ha_tag, chunk, vin_data_sz, ctl, tsorig, tspub ); - chunk = fd_dcache_compact_next( chunk, vin_data_sz, chunk0, wmark ); seq = fd_seq_inc( seq, 1UL ); cr_avail--; @@ -424,6 +399,7 @@ fd_frank_task_t frank_verify = { .name = "verify", .in_wksp = "quic_verify", .out_wksp = "verify_dedup", + .extra_wksp = "tpu_txn_data", .allow_syscalls_sz = sizeof(allow_syscalls)/sizeof(allow_syscalls[ 0 ]), .allow_syscalls = allow_syscalls, .allow_fds = allow_fds,