Provide lcli tooling for attestation packing analysis (#2480)

## Proposed Changes

Add tooling to lcli to provide a way to measure the attestation packing efficiency of historical blocks by querying a beacon node API endpoint.

## Additional Info

Since block rewards are proportional to the number of unique attestations included in the block, a measure of efficiency can be calculated by comparing the number of unique attestations that could have been included into a block vs the number of unique attestations that were actually included.

This lcli tool provides the following data per block:
- Slot Number
- Proposer Index and Grafitti (if any)
- Available Unique Attestations
- Included Unique Attestations
- Best-effort estimate of the number of offline validators for the epoch. This means we can normalize the calculated efficiency, removing offline validators from the available attestation set.

The data is outputted as a csv file.

## Usage
Install lcli:
```
make install-lcli
```
Alternatively install with the `fake_crypto` feature to skip signature verification which improves performance:
```
cargo install --path lcli --features=fake_crypto --force --locked
```

Ensure a Lighthouse beacon node is running and synced. A non-default API endpoint can be passed with the `--endpoint` flag.

Run:
```
lcli etl-block-efficiency --output /path/to/output.csv --start-epoch 40 --end-epoch 80
```
This commit is contained in:
Mac L
2021-09-25 07:53:56 +00:00
parent 924a1345b1
commit 440badd973
5 changed files with 445 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ mod change_genesis_time;
mod check_deposit_data;
mod deploy_deposit_contract;
mod eth1_genesis;
mod etl;
mod generate_bootnode_enr;
mod insecure_validators;
mod interop_genesis;
@@ -499,6 +500,63 @@ fn main() {
.help("The number of nodes to divide the validator keys to"),
)
)
.subcommand(
SubCommand::with_name("etl-block-efficiency")
.about(
"Performs ETL analysis of block efficiency. Requires a Beacon Node API to \
extract data from.",
)
.arg(
Arg::with_name("endpoint")
.long("endpoint")
.short("e")
.takes_value(true)
.default_value("http://localhost:5052")
.help(
"The endpoint of the Beacon Node API."
),
)
.arg(
Arg::with_name("output")
.long("output")
.short("o")
.takes_value(true)
.help("The path of the output data in CSV file.")
.required(true),
)
.arg(
Arg::with_name("start-epoch")
.long("start-epoch")
.takes_value(true)
.help(
"The first epoch in the range of epochs to be evaluated. Use with \
--end-epoch.",
)
.required(true),
)
.arg(
Arg::with_name("end-epoch")
.long("end-epoch")
.takes_value(true)
.help(
"The last epoch in the range of epochs to be evaluated. Use with \
--start-epoch.",
)
.required(true),
)
.arg(
Arg::with_name("offline-window")
.long("offline-window")
.takes_value(true)
.default_value("3")
.help(
"If a validator does not submit an attestion within this many epochs, \
they are deemed offline. For example, for a offline window of 3, if a \
validator does not attest in epochs 4, 5 or 6, it is deemed offline \
during epoch 6. A value of 0 will skip these checks."
)
)
)
.get_matches();
let result = matches
@@ -569,6 +627,10 @@ fn run<T: EthSpec>(
.map_err(|e| format!("Failed to run generate-bootnode-enr command: {}", e)),
("insecure-validators", Some(matches)) => insecure_validators::run(matches)
.map_err(|e| format!("Failed to run insecure-validators command: {}", e)),
("etl-block-efficiency", Some(matches)) => env
.runtime()
.block_on(etl::block_efficiency::run::<T>(matches))
.map_err(|e| format!("Failed to run etl-block_efficiency: {}", e)),
(other, _) => Err(format!("Unknown subcommand {}. See --help.", other)),
}
}