Merge branch 'unstable' into deneb-merge-from-unstable-20230613
This commit is contained in:
commit
801bf5951c
3
.github/workflows/test-suite.yml
vendored
3
.github/workflows/test-suite.yml
vendored
@ -79,7 +79,8 @@ jobs:
|
||||
choco install python protoc visualstudio2019-workload-vctools -y
|
||||
npm config set msvs_version 2019
|
||||
- name: Install anvil
|
||||
run: cargo install --git https://github.com/foundry-rs/foundry --locked anvil
|
||||
# Extra feature to work around https://github.com/foundry-rs/foundry/issues/5115
|
||||
run: cargo install --git https://github.com/foundry-rs/foundry --locked anvil --features ethers/ipc
|
||||
- name: Install make
|
||||
run: choco install -y make
|
||||
- uses: KyleMayes/install-llvm-action@v1
|
||||
|
5
Makefile
5
Makefile
@ -145,8 +145,9 @@ test-op-pool-%:
|
||||
|
||||
# Run the tests in the `slasher` crate for all supported database backends.
|
||||
test-slasher:
|
||||
cargo test --release -p slasher --features mdbx
|
||||
cargo test --release -p slasher --no-default-features --features lmdb
|
||||
cargo test --release -p slasher --features lmdb
|
||||
cargo test --release -p slasher --no-default-features --features mdbx
|
||||
cargo test --release -p slasher --features lmdb,mdbx # both backends enabled
|
||||
|
||||
# Runs only the tests/state_transition_vectors tests.
|
||||
run-state-transition-tests:
|
||||
|
@ -38,7 +38,7 @@ clap_utils = { path = "../common/clap_utils" }
|
||||
hyper = "0.14.4"
|
||||
lighthouse_version = { path = "../common/lighthouse_version" }
|
||||
hex = "0.4.2"
|
||||
slasher = { path = "../slasher", default-features = false }
|
||||
slasher = { path = "../slasher" }
|
||||
monitoring_api = { path = "../common/monitoring_api" }
|
||||
sensitive_url = { path = "../common/sensitive_url" }
|
||||
http_api = { path = "http_api" }
|
||||
|
@ -58,7 +58,7 @@ fork_choice = { path = "../../consensus/fork_choice" }
|
||||
task_executor = { path = "../../common/task_executor" }
|
||||
derivative = "2.1.1"
|
||||
itertools = "0.10.0"
|
||||
slasher = { path = "../../slasher", default-features = false }
|
||||
slasher = { path = "../../slasher" }
|
||||
eth2 = { path = "../../common/eth2" }
|
||||
strum = { version = "0.24.0", features = ["derive"] }
|
||||
logging = { path = "../../common/logging" }
|
||||
|
@ -39,7 +39,7 @@ time = "0.3.5"
|
||||
directory = {path = "../../common/directory"}
|
||||
http_api = { path = "../http_api" }
|
||||
http_metrics = { path = "../http_metrics" }
|
||||
slasher = { path = "../../slasher", default-features = false }
|
||||
slasher = { path = "../../slasher" }
|
||||
slasher_service = { path = "../../slasher/service" }
|
||||
monitoring_api = {path = "../../common/monitoring_api"}
|
||||
execution_layer = { path = "../execution_layer" }
|
||||
|
@ -911,16 +911,23 @@ impl<T: EthSpec> ExecutionLayer<T> {
|
||||
|
||||
let relay_value = relay.data.message.value;
|
||||
let local_value = *local.block_value();
|
||||
if !self.inner.always_prefer_builder_payload
|
||||
&& local_value >= relay_value
|
||||
{
|
||||
info!(
|
||||
self.log(),
|
||||
"Local block is more profitable than relay block";
|
||||
"local_block_value" => %local_value,
|
||||
"relay_value" => %relay_value
|
||||
);
|
||||
return Ok(ProvenancedPayload::Local(local));
|
||||
if !self.inner.always_prefer_builder_payload {
|
||||
if local_value >= relay_value {
|
||||
info!(
|
||||
self.log(),
|
||||
"Local block is more profitable than relay block";
|
||||
"local_block_value" => %local_value,
|
||||
"relay_value" => %relay_value
|
||||
);
|
||||
return Ok(ProvenancedPayload::Local(local));
|
||||
} else {
|
||||
info!(
|
||||
self.log(),
|
||||
"Relay block is more profitable than local block";
|
||||
"local_block_value" => %local_value,
|
||||
"relay_value" => %relay_value
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
match verify_builder_bid(
|
||||
|
@ -834,8 +834,9 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
||||
Arg::with_name("slasher-broadcast")
|
||||
.long("slasher-broadcast")
|
||||
.help("Broadcast slashings found by the slasher to the rest of the network \
|
||||
[disabled by default].")
|
||||
.requires("slasher")
|
||||
[Enabled by default].")
|
||||
.takes_value(true)
|
||||
.default_value("true")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("slasher-backend")
|
||||
|
@ -670,7 +670,9 @@ pub fn get_config<E: EthSpec>(
|
||||
slasher_config.validator_chunk_size = validator_chunk_size;
|
||||
}
|
||||
|
||||
slasher_config.broadcast = cli_args.is_present("slasher-broadcast");
|
||||
if let Some(broadcast) = clap_utils::parse_optional(cli_args, "slasher-broadcast")? {
|
||||
slasher_config.broadcast = broadcast;
|
||||
}
|
||||
|
||||
if let Some(backend) = clap_utils::parse_optional(cli_args, "slasher-backend")? {
|
||||
slasher_config.backend = backend;
|
||||
|
@ -16,7 +16,7 @@ pub use client::{Client, ClientBuilder, ClientConfig, ClientGenesis};
|
||||
pub use config::{get_config, get_data_dir, get_slots_per_restore_point, set_network_config};
|
||||
use environment::RuntimeContext;
|
||||
pub use eth2_config::Eth2Config;
|
||||
use slasher::Slasher;
|
||||
use slasher::{DatabaseBackendOverride, Slasher};
|
||||
use slog::{info, warn};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::sync::Arc;
|
||||
@ -93,7 +93,27 @@ impl<E: EthSpec> ProductionBeaconNode<E> {
|
||||
log.clone(),
|
||||
)?;
|
||||
|
||||
let builder = if let Some(slasher_config) = client_config.slasher.clone() {
|
||||
let builder = if let Some(mut slasher_config) = client_config.slasher.clone() {
|
||||
match slasher_config.override_backend() {
|
||||
DatabaseBackendOverride::Success(old_backend) => {
|
||||
info!(
|
||||
log,
|
||||
"Slasher backend overriden";
|
||||
"reason" => "database exists",
|
||||
"configured_backend" => %old_backend,
|
||||
"override_backend" => %slasher_config.backend,
|
||||
);
|
||||
}
|
||||
DatabaseBackendOverride::Failure(path) => {
|
||||
warn!(
|
||||
log,
|
||||
"Slasher backend override failed";
|
||||
"advice" => "delete old MDBX database or enable MDBX backend",
|
||||
"path" => path.display()
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let slasher = Arc::new(
|
||||
Slasher::open(slasher_config, log.new(slog::o!("service" => "slasher")))
|
||||
.map_err(|e| format!("Slasher open error: {:?}", e))?,
|
||||
|
@ -10,7 +10,7 @@ beacon_chain = {path = "../beacon_chain"}
|
||||
|
||||
[dependencies]
|
||||
db-key = "0.0.5"
|
||||
leveldb = { version = "0.8.6", default-features = false }
|
||||
leveldb = { version = "0.8.6" }
|
||||
parking_lot = "0.12.0"
|
||||
itertools = "0.10.0"
|
||||
ethereum_ssz = "0.5.0"
|
||||
|
BIN
book/src/imgs/ui-dash-logs.png
Normal file
BIN
book/src/imgs/ui-dash-logs.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 51 KiB |
BIN
book/src/imgs/ui-logs.png
Normal file
BIN
book/src/imgs/ui-logs.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 196 KiB |
@ -5,7 +5,7 @@ the instructions below, and then proceed to [Building Lighthouse](#build-lightho
|
||||
|
||||
## Dependencies
|
||||
|
||||
First, **install Rust** using [rustup](https://rustup.rs/):
|
||||
First, **install Rust** using [rustup](https://rustup.rs/):
|
||||
|
||||
```bash
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
@ -64,10 +64,10 @@ After this, you are ready to [build Lighthouse](#build-lighthouse).
|
||||
|
||||
1. Install [Git](https://git-scm.com/download/win).
|
||||
1. Install the [Chocolatey](https://chocolatey.org/install) package manager for Windows.
|
||||
> Tips:
|
||||
> Tips:
|
||||
> - Use PowerShell to install. In Windows, search for PowerShell and run as administrator.
|
||||
> - You must ensure `Get-ExecutionPolicy` is not Restricted. To test this, run `Get-ExecutionPolicy` in PowerShell. If it returns `restricted`, then run `Set-ExecutionPolicy AllSigned`, and then run
|
||||
```bash
|
||||
```bash
|
||||
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
|
||||
```
|
||||
> - To verify that Chocolatey is ready, run `choco` and it should return the version.
|
||||
@ -159,13 +159,13 @@ Commonly used features include:
|
||||
* `gnosis`: support for the Gnosis Beacon Chain.
|
||||
* `portable`: support for legacy hardware.
|
||||
* `modern`: support for exclusively modern hardware.
|
||||
* `slasher-mdbx`: support for the MDBX slasher backend. Enabled by default.
|
||||
* `slasher-lmdb`: support for the LMDB slasher backend.
|
||||
* `slasher-lmdb`: support for the LMDB slasher backend. Enabled by default.
|
||||
* `slasher-mdbx`: support for the MDBX slasher backend.
|
||||
* `jemalloc`: use [`jemalloc`][jemalloc] to allocate memory. Enabled by default on Linux and macOS.
|
||||
Not supported on Windows.
|
||||
* `spec-minimal`: support for the minimal preset (useful for testing).
|
||||
|
||||
Default features (e.g. `slasher-mdbx`) may be opted out of using the `--no-default-features`
|
||||
Default features (e.g. `slasher-lmdb`) may be opted out of using the `--no-default-features`
|
||||
argument for `cargo`, which can be plumbed in via the `CARGO_INSTALL_EXTRA_FLAGS` environment variable.
|
||||
E.g.
|
||||
|
||||
|
@ -46,23 +46,49 @@ directory.
|
||||
|
||||
* Flag: `--slasher-backend NAME`
|
||||
* Argument: one of `mdbx`, `lmdb` or `disabled`
|
||||
* Default: `mdbx`
|
||||
* Default: `lmdb` for new installs, `mdbx` if an MDBX database already exists
|
||||
|
||||
Since Lighthouse v2.6.0 it is possible to use one of several database backends with the slasher:
|
||||
It is possible to use one of several database backends with the slasher:
|
||||
|
||||
- MDBX (default)
|
||||
- LMDB
|
||||
- LMDB (default)
|
||||
- MDBX
|
||||
|
||||
The advantage of MDBX is that it performs compaction, resulting in less disk usage over time. The
|
||||
disadvantage is that upstream MDBX has removed support for Windows and macOS, so Lighthouse is stuck
|
||||
on an older version. If bugs are found in our pinned version of MDBX it may be deprecated in future.
|
||||
disadvantage is that upstream MDBX is unstable, so Lighthouse is pinned to a specific version.
|
||||
If bugs are found in our pinned version of MDBX it may be deprecated in future.
|
||||
|
||||
LMDB does not have compaction but is more stable upstream than MDBX. It is not currently recommended
|
||||
to use the LMDB backend on Windows.
|
||||
LMDB does not have compaction but is more stable upstream than MDBX. If running with the LMDB
|
||||
backend on Windows it is recommended to allow extra space due to this issue:
|
||||
[sigp/lighthouse#2342](https://github.com/sigp/lighthouse/issues/2342).
|
||||
|
||||
More backends may be added in future.
|
||||
|
||||
### Switching Backends
|
||||
#### Backend Override
|
||||
|
||||
The default backend was changed from MDBX to LMDB in Lighthouse v4.3.0.
|
||||
|
||||
If an MDBX database is already found on disk, then Lighthouse will try to use it. This will result
|
||||
in a log at start-up:
|
||||
|
||||
```
|
||||
INFO Slasher backend overriden reason: database exists, configured_backend: lmdb, overriden_backend: mdbx
|
||||
```
|
||||
|
||||
If the running Lighthouse binary doesn't have the MDBX backend enabled but an existing database is
|
||||
found, then a warning will be logged and Lighthouse will use the LMDB backend and create a new database:
|
||||
|
||||
```
|
||||
WARN Slasher backend override failed advice: delete old MDBX database or enable MDBX backend, path: /home/user/.lighthouse/mainnet/beacon/slasher_db/mdbx.dat
|
||||
```
|
||||
|
||||
In this case you should either obtain a Lighthouse binary with the MDBX backend enabled, or delete
|
||||
the files for the old backend. The pre-built Lighthouse binaries and Docker images have MDBX enabled,
|
||||
or if you're [building from source](./installation-source.md) you can enable the `slasher-mdbx` feature.
|
||||
|
||||
To delete the files, use the `path` from the `WARN` log, and then delete the `mbdx.dat` and
|
||||
`mdbx.lck` files.
|
||||
|
||||
#### Switching Backends
|
||||
|
||||
If you change database backends and want to reclaim the space used by the old backend you can
|
||||
delete the following files from your `slasher_db` directory:
|
||||
|
@ -14,3 +14,13 @@ Once you have successfully arrived to the main dashboard, use the sidebar to acc
|
||||
|
||||
## 5. Why doesn't my validator balance graph show any data?
|
||||
If your graph is not showing data, it usually means your validator node is still caching data. The application must wait at least 3 epochs before it can render any graphical visualizations. This could take up to 20min.
|
||||
|
||||
## 4. Does Siren support reverse proxy or DNS named addresses?
|
||||
Yes, if you need to access your beacon or validator from an address such as `https://merp-server:9909/eth2-vc` you should follow the following steps for configuration:
|
||||
1. Toggle `https` as your protocol
|
||||
2. Add your address as `merp-server/eth2-vc`
|
||||
3. Add your Beacon and Validator ports as `9909`
|
||||
|
||||
If you have configured it correctly you should see a green checkmark indicating Siren is now connected to your Validator Client and Beacon Node.
|
||||
|
||||
If you have separate address setups for your Validator Client and Beacon Node respectively you should access the `Advance Settings` on the configuration and repeat the steps above for each address.
|
||||
|
@ -33,6 +33,7 @@ By clicking on the chart component you can filter selected validators in the ren
|
||||
<img src="imgs/ui-validator-balance2.png" width="48%"/>
|
||||
|
||||
|
||||
|
||||
## Hardware Usage and Device Diagnostics
|
||||
|
||||
The hardware usage component gathers information about the device the Beacon Node is currently running. It displays the Disk usage, CPU metrics and memory usage of the Beacon Node device. The device diagnostics component provides the sync status of the execution client and beacon node.
|
||||
@ -42,6 +43,12 @@ The hardware usage component gathers information about the device the Beacon Nod
|
||||
<img height="350" src="imgs/ui-device.png"/>
|
||||
|
||||
|
||||
## Log Statistics
|
||||
|
||||
The log statistics present an hourly combined rate of critical, warning, and error logs from the validator client and beacon node. This analysis enables informed decision-making, troubleshooting, and proactive maintenance for optimal system performance.
|
||||
|
||||
<img height="350" src="imgs/ui-dash-logs.png"/>
|
||||
|
||||
# Validator Management
|
||||
|
||||
Siren's validator management view provides a detailed overview of all validators with options to deposit to and/or add new validators. Each validator table row displays the validator name, index, balance, rewards, status and all available actions per validator.
|
||||
@ -59,3 +66,12 @@ Clicking the validator icon activates a detailed validator modal component. This
|
||||
Siren's settings view provides access to the application theme, version, name, device name and important external links. From the settings page users can also access the configuration screen to adjust any beacon or validator node parameters.
|
||||
|
||||
![](imgs/ui-settings.png)
|
||||
|
||||
|
||||
# Validator and Beacon Logs
|
||||
|
||||
The logs page provides users with the functionality to access and review recorded logs for both validators and beacons. Users can conveniently observe log severity, messages, timestamps, and any additional data associated with each log entry. The interface allows for seamless switching between validator and beacon log outputs, and incorporates useful features such as built-in text search and the ability to pause log feeds.
|
||||
|
||||
Additionally, users can obtain log statistics, which are also available on the main dashboard, thereby facilitating a comprehensive overview of the system's log data. Please note that Siren is limited to storing and displaying only the previous 1000 log messages. This also means the text search is limited to the logs that are currently stored within Siren's limit.
|
||||
|
||||
![](imgs/ui-logs.png)
|
@ -7,7 +7,7 @@ autotests = false
|
||||
rust-version = "1.68.2"
|
||||
|
||||
[features]
|
||||
default = ["slasher-mdbx"]
|
||||
default = ["slasher-lmdb"]
|
||||
# Writes debugging .ssz files to /tmp during block processing.
|
||||
write_ssz_files = ["beacon_node/write_ssz_files"]
|
||||
# Compiles the BLS crypto code so that the binary is portable across machines.
|
||||
@ -55,7 +55,7 @@ malloc_utils = { path = "../common/malloc_utils" }
|
||||
directory = { path = "../common/directory" }
|
||||
unused_port = { path = "../common/unused_port" }
|
||||
database_manager = { path = "../database_manager" }
|
||||
slasher = { path = "../slasher", default-features = false }
|
||||
slasher = { path = "../slasher" }
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3.1.0"
|
||||
|
@ -1806,10 +1806,12 @@ fn no_reconstruct_historic_states_flag() {
|
||||
}
|
||||
|
||||
// Tests for Slasher flags.
|
||||
// Using `--slasher-max-db-size` to work around https://github.com/sigp/lighthouse/issues/2342
|
||||
#[test]
|
||||
fn slasher_flag() {
|
||||
CommandLineTest::new()
|
||||
.flag("slasher", None)
|
||||
.flag("slasher-max-db-size", Some("1"))
|
||||
.run_with_zero_port()
|
||||
.with_config_and_dir(|config, dir| {
|
||||
if let Some(slasher_config) = &config.slasher {
|
||||
@ -1827,6 +1829,7 @@ fn slasher_dir_flag() {
|
||||
let dir = TempDir::new().expect("Unable to create temporary directory");
|
||||
CommandLineTest::new()
|
||||
.flag("slasher", None)
|
||||
.flag("slasher-max-db-size", Some("1"))
|
||||
.flag("slasher-dir", dir.path().as_os_str().to_str())
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
@ -1841,6 +1844,7 @@ fn slasher_dir_flag() {
|
||||
fn slasher_update_period_flag() {
|
||||
CommandLineTest::new()
|
||||
.flag("slasher", None)
|
||||
.flag("slasher-max-db-size", Some("1"))
|
||||
.flag("slasher-update-period", Some("100"))
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
@ -1855,6 +1859,7 @@ fn slasher_update_period_flag() {
|
||||
fn slasher_slot_offset_flag() {
|
||||
CommandLineTest::new()
|
||||
.flag("slasher", None)
|
||||
.flag("slasher-max-db-size", Some("1"))
|
||||
.flag("slasher-slot-offset", Some("11.25"))
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
@ -1867,6 +1872,7 @@ fn slasher_slot_offset_flag() {
|
||||
fn slasher_slot_offset_nan_flag() {
|
||||
CommandLineTest::new()
|
||||
.flag("slasher", None)
|
||||
.flag("slasher-max-db-size", Some("1"))
|
||||
.flag("slasher-slot-offset", Some("NaN"))
|
||||
.run_with_zero_port();
|
||||
}
|
||||
@ -1874,6 +1880,7 @@ fn slasher_slot_offset_nan_flag() {
|
||||
fn slasher_history_length_flag() {
|
||||
CommandLineTest::new()
|
||||
.flag("slasher", None)
|
||||
.flag("slasher-max-db-size", Some("1"))
|
||||
.flag("slasher-history-length", Some("2048"))
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
@ -1888,20 +1895,21 @@ fn slasher_history_length_flag() {
|
||||
fn slasher_max_db_size_flag() {
|
||||
CommandLineTest::new()
|
||||
.flag("slasher", None)
|
||||
.flag("slasher-max-db-size", Some("10"))
|
||||
.flag("slasher-max-db-size", Some("2"))
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
let slasher_config = config
|
||||
.slasher
|
||||
.as_ref()
|
||||
.expect("Unable to parse Slasher config");
|
||||
assert_eq!(slasher_config.max_db_size_mbs, 10240);
|
||||
assert_eq!(slasher_config.max_db_size_mbs, 2048);
|
||||
});
|
||||
}
|
||||
#[test]
|
||||
fn slasher_attestation_cache_size_flag() {
|
||||
CommandLineTest::new()
|
||||
.flag("slasher", None)
|
||||
.flag("slasher-max-db-size", Some("1"))
|
||||
.flag("slasher-att-cache-size", Some("10000"))
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
@ -1916,6 +1924,7 @@ fn slasher_attestation_cache_size_flag() {
|
||||
fn slasher_chunk_size_flag() {
|
||||
CommandLineTest::new()
|
||||
.flag("slasher", None)
|
||||
.flag("slasher-max-db-size", Some("1"))
|
||||
.flag("slasher-chunk-size", Some("32"))
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
@ -1930,6 +1939,7 @@ fn slasher_chunk_size_flag() {
|
||||
fn slasher_validator_chunk_size_flag() {
|
||||
CommandLineTest::new()
|
||||
.flag("slasher", None)
|
||||
.flag("slasher-max-db-size", Some("1"))
|
||||
.flag("slasher-validator-chunk-size", Some("512"))
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
@ -1941,9 +1951,10 @@ fn slasher_validator_chunk_size_flag() {
|
||||
});
|
||||
}
|
||||
#[test]
|
||||
fn slasher_broadcast_flag() {
|
||||
fn slasher_broadcast_flag_no_args() {
|
||||
CommandLineTest::new()
|
||||
.flag("slasher", None)
|
||||
.flag("slasher-max-db-size", Some("1"))
|
||||
.flag("slasher-broadcast", None)
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
@ -1954,29 +1965,62 @@ fn slasher_broadcast_flag() {
|
||||
assert!(slasher_config.broadcast);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slasher_backend_default() {
|
||||
fn slasher_broadcast_flag_no_default() {
|
||||
CommandLineTest::new()
|
||||
.flag("slasher", None)
|
||||
.flag("slasher-max-db-size", Some("1"))
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
let slasher_config = config.slasher.as_ref().unwrap();
|
||||
assert_eq!(slasher_config.backend, slasher::DatabaseBackend::Mdbx);
|
||||
let slasher_config = config
|
||||
.slasher
|
||||
.as_ref()
|
||||
.expect("Unable to parse Slasher config");
|
||||
assert!(slasher_config.broadcast);
|
||||
});
|
||||
}
|
||||
#[test]
|
||||
fn slasher_broadcast_flag_true() {
|
||||
CommandLineTest::new()
|
||||
.flag("slasher", None)
|
||||
.flag("slasher-max-db-size", Some("1"))
|
||||
.flag("slasher-broadcast", Some("true"))
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
let slasher_config = config
|
||||
.slasher
|
||||
.as_ref()
|
||||
.expect("Unable to parse Slasher config");
|
||||
assert!(slasher_config.broadcast);
|
||||
});
|
||||
}
|
||||
#[test]
|
||||
fn slasher_broadcast_flag_false() {
|
||||
CommandLineTest::new()
|
||||
.flag("slasher", None)
|
||||
.flag("slasher-max-db-size", Some("1"))
|
||||
.flag("slasher-broadcast", Some("false"))
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
let slasher_config = config
|
||||
.slasher
|
||||
.as_ref()
|
||||
.expect("Unable to parse Slasher config");
|
||||
assert!(!slasher_config.broadcast);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slasher_backend_override_to_default() {
|
||||
// Hard to test this flag because all but one backend is disabled by default and the backend
|
||||
// called "disabled" results in a panic.
|
||||
CommandLineTest::new()
|
||||
.flag("slasher", None)
|
||||
.flag("slasher-backend", Some("mdbx"))
|
||||
.flag("slasher-max-db-size", Some("1"))
|
||||
.flag("slasher-backend", Some("lmdb"))
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
let slasher_config = config.slasher.as_ref().unwrap();
|
||||
assert_eq!(slasher_config.backend, slasher::DatabaseBackend::Mdbx);
|
||||
assert_eq!(slasher_config.backend, slasher::DatabaseBackend::Lmdb);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ authors = ["Michael Sproul <michael@sigmaprime.io>"]
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
default = ["mdbx"]
|
||||
default = ["lmdb"]
|
||||
mdbx = ["dep:mdbx"]
|
||||
lmdb = ["lmdb-rkv", "lmdb-rkv-sys"]
|
||||
|
||||
|
@ -9,7 +9,7 @@ beacon_chain = { path = "../../beacon_node/beacon_chain" }
|
||||
directory = { path = "../../common/directory" }
|
||||
lighthouse_network = { path = "../../beacon_node/lighthouse_network" }
|
||||
network = { path = "../../beacon_node/network" }
|
||||
slasher = { path = "..", default-features = false }
|
||||
slasher = { path = ".." }
|
||||
slog = "2.5.2"
|
||||
slot_clock = { path = "../../common/slot_clock" }
|
||||
state_processing = { path = "../../consensus/state_processing" }
|
||||
|
@ -13,15 +13,16 @@ pub const DEFAULT_MAX_DB_SIZE: usize = 256 * 1024; // 256 GiB
|
||||
pub const DEFAULT_ATTESTATION_ROOT_CACHE_SIZE: usize = 100_000;
|
||||
pub const DEFAULT_BROADCAST: bool = false;
|
||||
|
||||
#[cfg(feature = "mdbx")]
|
||||
#[cfg(all(feature = "mdbx", not(feature = "lmdb")))]
|
||||
pub const DEFAULT_BACKEND: DatabaseBackend = DatabaseBackend::Mdbx;
|
||||
#[cfg(all(feature = "lmdb", not(feature = "mdbx")))]
|
||||
#[cfg(feature = "lmdb")]
|
||||
pub const DEFAULT_BACKEND: DatabaseBackend = DatabaseBackend::Lmdb;
|
||||
#[cfg(not(any(feature = "mdbx", feature = "lmdb")))]
|
||||
pub const DEFAULT_BACKEND: DatabaseBackend = DatabaseBackend::Disabled;
|
||||
|
||||
pub const MAX_HISTORY_LENGTH: usize = 1 << 16;
|
||||
pub const MEGABYTE: usize = 1 << 20;
|
||||
pub const MDBX_DATA_FILENAME: &str = "mdbx.dat";
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Config {
|
||||
@ -64,6 +65,13 @@ pub enum DatabaseBackend {
|
||||
Disabled,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum DatabaseBackendOverride {
|
||||
Success(DatabaseBackend),
|
||||
Failure(PathBuf),
|
||||
Noop,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new(database_path: PathBuf) -> Self {
|
||||
Self {
|
||||
@ -161,4 +169,28 @@ impl Config {
|
||||
.filter(move |v| self.validator_chunk_index(**v) == validator_chunk_index)
|
||||
.copied()
|
||||
}
|
||||
|
||||
pub fn override_backend(&mut self) -> DatabaseBackendOverride {
|
||||
let mdbx_path = self.database_path.join(MDBX_DATA_FILENAME);
|
||||
|
||||
#[cfg(feature = "mdbx")]
|
||||
let already_mdbx = self.backend == DatabaseBackend::Mdbx;
|
||||
#[cfg(not(feature = "mdbx"))]
|
||||
let already_mdbx = false;
|
||||
|
||||
if !already_mdbx && mdbx_path.exists() {
|
||||
#[cfg(feature = "mdbx")]
|
||||
{
|
||||
let old_backend = self.backend;
|
||||
self.backend = DatabaseBackend::Mdbx;
|
||||
DatabaseBackendOverride::Success(old_backend)
|
||||
}
|
||||
#[cfg(not(feature = "mdbx"))]
|
||||
{
|
||||
DatabaseBackendOverride::Failure(mdbx_path)
|
||||
}
|
||||
} else {
|
||||
DatabaseBackendOverride::Noop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ pub use crate::slasher::Slasher;
|
||||
pub use attestation_queue::{AttestationBatch, AttestationQueue, SimpleBatch};
|
||||
pub use attester_record::{AttesterRecord, CompactAttesterRecord, IndexedAttesterRecord};
|
||||
pub use block_queue::BlockQueue;
|
||||
pub use config::{Config, DatabaseBackend};
|
||||
pub use config::{Config, DatabaseBackend, DatabaseBackendOverride};
|
||||
pub use database::{
|
||||
interface::{Database, Environment, RwTransaction},
|
||||
IndexedAttestationId, SlasherDB,
|
||||
|
57
slasher/tests/backend.rs
Normal file
57
slasher/tests/backend.rs
Normal file
@ -0,0 +1,57 @@
|
||||
#![cfg(all(feature = "lmdb"))]
|
||||
|
||||
use slasher::{config::MDBX_DATA_FILENAME, Config, DatabaseBackend, DatabaseBackendOverride};
|
||||
use std::fs::File;
|
||||
use tempfile::tempdir;
|
||||
|
||||
#[test]
|
||||
#[cfg(all(feature = "mdbx", feature = "lmdb"))]
|
||||
fn override_no_existing_db() {
|
||||
let tempdir = tempdir().unwrap();
|
||||
let mut config = Config::new(tempdir.path().into());
|
||||
assert_eq!(config.override_backend(), DatabaseBackendOverride::Noop);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(feature = "mdbx", feature = "lmdb"))]
|
||||
fn override_with_existing_mdbx_db() {
|
||||
let tempdir = tempdir().unwrap();
|
||||
let mut config = Config::new(tempdir.path().into());
|
||||
|
||||
File::create(config.database_path.join(MDBX_DATA_FILENAME)).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
config.override_backend(),
|
||||
DatabaseBackendOverride::Success(DatabaseBackend::Lmdb)
|
||||
);
|
||||
assert_eq!(config.backend, DatabaseBackend::Mdbx);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(feature = "mdbx", feature = "lmdb"))]
|
||||
fn no_override_with_existing_mdbx_db() {
|
||||
let tempdir = tempdir().unwrap();
|
||||
let mut config = Config::new(tempdir.path().into());
|
||||
config.backend = DatabaseBackend::Mdbx;
|
||||
|
||||
File::create(config.database_path.join(MDBX_DATA_FILENAME)).unwrap();
|
||||
|
||||
assert_eq!(config.override_backend(), DatabaseBackendOverride::Noop);
|
||||
assert_eq!(config.backend, DatabaseBackend::Mdbx);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(not(feature = "mdbx"), feature = "lmdb"))]
|
||||
fn failed_override_with_existing_mdbx_db() {
|
||||
let tempdir = tempdir().unwrap();
|
||||
let mut config = Config::new(tempdir.path().into());
|
||||
|
||||
let filename = config.database_path.join(MDBX_DATA_FILENAME);
|
||||
File::create(&filename).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
config.override_backend(),
|
||||
DatabaseBackendOverride::Failure(filename)
|
||||
);
|
||||
assert_eq!(config.backend, DatabaseBackend::Lmdb);
|
||||
}
|
@ -340,35 +340,61 @@ impl<T: SlotClock + 'static, E: EthSpec> BlockService<T, E> {
|
||||
let log = log.clone();
|
||||
self.inner.context.executor.spawn(
|
||||
async move {
|
||||
let publish_result = if builder_proposals {
|
||||
let mut result = service.clone()
|
||||
if builder_proposals {
|
||||
let result = service
|
||||
.clone()
|
||||
.publish_block::<BlindedPayload<E>>(slot, validator_pubkey)
|
||||
.await;
|
||||
match result.as_ref() {
|
||||
match result {
|
||||
Err(BlockError::Recoverable(e)) => {
|
||||
error!(log, "Error whilst producing a blinded block, attempting to \
|
||||
publish full block"; "error" => ?e);
|
||||
result = service
|
||||
error!(
|
||||
log,
|
||||
"Error whilst producing block";
|
||||
"error" => ?e,
|
||||
"block_slot" => ?slot,
|
||||
"info" => "blinded proposal failed, attempting full block"
|
||||
);
|
||||
if let Err(e) = service
|
||||
.publish_block::<FullPayload<E>>(slot, validator_pubkey)
|
||||
.await;
|
||||
},
|
||||
Err(BlockError::Irrecoverable(e)) => {
|
||||
error!(log, "Error whilst producing a blinded block, cannot fallback \
|
||||
because the block was signed"; "error" => ?e);
|
||||
},
|
||||
_ => {},
|
||||
.await
|
||||
{
|
||||
// Log a `crit` since a full block
|
||||
// (non-builder) proposal failed.
|
||||
crit!(
|
||||
log,
|
||||
"Error whilst producing block";
|
||||
"error" => ?e,
|
||||
"block_slot" => ?slot,
|
||||
"info" => "full block attempted after a blinded failure",
|
||||
);
|
||||
}
|
||||
}
|
||||
Err(BlockError::Irrecoverable(e)) => {
|
||||
// Only log an `error` since it's common for
|
||||
// builders to timeout on their response, only
|
||||
// to publish the block successfully themselves.
|
||||
error!(
|
||||
log,
|
||||
"Error whilst producing block";
|
||||
"error" => ?e,
|
||||
"block_slot" => ?slot,
|
||||
"info" => "this error may or may not result in a missed block",
|
||||
)
|
||||
}
|
||||
Ok(_) => {}
|
||||
};
|
||||
result
|
||||
} else {
|
||||
service
|
||||
.publish_block::<FullPayload<E>>(slot, validator_pubkey)
|
||||
.await
|
||||
};
|
||||
if let Err(e) = publish_result {
|
||||
} else if let Err(e) = service
|
||||
.publish_block::<FullPayload<E>>(slot, validator_pubkey)
|
||||
.await
|
||||
{
|
||||
// Log a `crit` since a full block (non-builder)
|
||||
// proposal failed.
|
||||
crit!(
|
||||
log,
|
||||
"Error whilst producing block";
|
||||
"message" => ?e
|
||||
"message" => ?e,
|
||||
"block_slot" => ?slot,
|
||||
"info" => "proposal did not use a builder",
|
||||
);
|
||||
}
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user