Add fork choice JSON dumping

This commit is contained in:
Paul Hauner
2020-01-17 09:10:42 +11:00
parent 2df71372d2
commit 9d295b7e95
5 changed files with 31 additions and 2 deletions

1
Cargo.lock generated
View File

@@ -3028,6 +3028,7 @@ dependencies = [
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
"types 0.1.0",
]

View File

@@ -3,13 +3,19 @@ use parking_lot::RwLock;
use proto_array_fork_choice::ProtoArrayForkChoice;
use ssz_derive::{Decode, Encode};
use state_processing::common::get_attesting_indices;
use std::fs::File;
use std::io::Write;
use std::marker::PhantomData;
use std::time::{SystemTime, UNIX_EPOCH};
use store::Error as StoreError;
use types::{
Attestation, BeaconBlock, BeaconState, BeaconStateError, Checkpoint, Epoch, EthSpec, Hash256,
Slot,
};
/// If `true`, fork choice will be dumped to a JSON file in `/tmp` whenever find head fail.
pub const FORK_CHOICE_DEBUGGING: bool = true;
type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, PartialEq)]
@@ -250,6 +256,20 @@ impl<T: BeaconChainTypes> ForkChoice<T> {
metrics::stop_timer(timer);
if FORK_CHOICE_DEBUGGING {
if let Err(e) = &result {
if let Ok(duration) = SystemTime::now().duration_since(UNIX_EPOCH) {
let time = duration.as_millis();
if let Ok(mut file) = File::create(format!("/tmp/fork-choice-{}", time)) {
let _ = write!(file, "{:?}\n", e);
if let Ok(json) = self.backend.as_json() {
let _ = write!(file, "{}", json);
}
}
}
}
}
result
}

View File

@@ -17,3 +17,4 @@ eth2_ssz_derive = "0.1.0"
serde = "1.0.102"
serde_derive = "1.0.102"
serde_yaml = "0.8.11"
serde_json = "1.0"

View File

@@ -1,9 +1,10 @@
use crate::error::Error;
use serde_derive::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode};
use std::collections::HashMap;
use types::{Epoch, Hash256, Slot};
#[derive(Clone, PartialEq, Debug, Encode, Decode)]
#[derive(Clone, PartialEq, Debug, Encode, Decode, Serialize, Deserialize)]
pub struct ProtoNode {
/// The `slot` is not necessary for `ProtoArray`, it just exists so external components can
/// easily query the block slot. This is useful for upstream fork choice logic.
@@ -17,7 +18,7 @@ pub struct ProtoNode {
best_descendant: Option<usize>,
}
#[derive(PartialEq)]
#[derive(PartialEq, Serialize, Deserialize)]
pub struct ProtoArray {
/// Do not attempt to prune the tree unless it has at least this many nodes. Small prunes
/// simply waste time.

View File

@@ -2,6 +2,7 @@ use crate::error::Error;
use crate::proto_array::ProtoArray;
use crate::ssz_container::SszContainer;
use parking_lot::RwLock;
use serde_json;
use ssz::{Decode, Encode};
use ssz_derive::{Decode, Encode};
use std::collections::HashMap;
@@ -220,6 +221,11 @@ impl ProtoArrayForkChoice {
.map(Into::into)
.map_err(|e| format!("Failed to decode ProtoArrayForkChoice: {:?}", e))
}
pub fn as_json(&self) -> Result<String, String> {
serde_json::to_string(&*self.proto_array.read())
.map_err(|e| format!("Failed to JSON encode proto_array: {:?}", e))
}
}
/// Returns a list of `deltas`, where there is one delta for each of the indices in