mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-30 12:47:05 +00:00
Passing 3/6 compliance tests, but a bit sketchy
This commit is contained in:
@@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use ssz::{Decode, Encode};
|
use ssz::{Decode, Encode};
|
||||||
use ssz_derive::{Decode, Encode};
|
use ssz_derive::{Decode, Encode};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeSet, HashMap},
|
collections::{BTreeSet, HashMap, HashSet},
|
||||||
fmt,
|
fmt,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
@@ -1110,80 +1110,74 @@ impl ProtoArrayForkChoice {
|
|||||||
justified_checkpoint,
|
justified_checkpoint,
|
||||||
finalized_checkpoint,
|
finalized_checkpoint,
|
||||||
);
|
);
|
||||||
|
let viable_indices = viable.iter().copied().collect::<HashSet<_>>();
|
||||||
|
|
||||||
let apply_proposer_boost = self
|
let apply_proposer_boost = self
|
||||||
.proto_array
|
.proto_array
|
||||||
.should_apply_proposer_boost::<E>(proposer_boost_root, justified_balances, spec)
|
.should_apply_proposer_boost::<E>(proposer_boost_root, justified_balances, spec)
|
||||||
.map_err(|e| format!("should_apply_proposer_boost failed: {e:?}"))?;
|
.map_err(|e| format!("should_apply_proposer_boost failed: {e:?}"))?;
|
||||||
|
|
||||||
let mut leaves = Vec::with_capacity(viable.len());
|
let mut leaves = Vec::new();
|
||||||
for &i in &viable {
|
let mut stack = vec![IndexedForkChoiceNode {
|
||||||
let has_viable_child = viable
|
root: *justified_root,
|
||||||
.iter()
|
proto_node_index: start_index,
|
||||||
.any(|&j| self.proto_array.nodes.get(j).and_then(|n| n.parent()) == Some(i));
|
payload_status: PayloadStatus::Pending,
|
||||||
if has_viable_child {
|
}];
|
||||||
continue;
|
|
||||||
}
|
while let Some(fc_node) = stack.pop() {
|
||||||
let node = self
|
let proto_node = self
|
||||||
.proto_array
|
.proto_array
|
||||||
.nodes
|
.nodes
|
||||||
.get(i)
|
.get(fc_node.proto_node_index)
|
||||||
.ok_or_else(|| format!("invalid viable node index {i}"))?;
|
.ok_or_else(|| format!("invalid viable node index {}", fc_node.proto_node_index))?;
|
||||||
|
|
||||||
let is_gloas = node.payload_received().is_ok();
|
let children = if proto_node.payload_received().is_ok() {
|
||||||
if is_gloas {
|
if fc_node.payload_status == PayloadStatus::Pending {
|
||||||
// Gloas: expand into Empty/Full virtual children.
|
let mut children = vec![fc_node.with_status(PayloadStatus::Empty)];
|
||||||
let empty_fc = IndexedForkChoiceNode {
|
if proto_node.payload_received().is_ok_and(|received| received) {
|
||||||
root: node.root(),
|
children.push(fc_node.with_status(PayloadStatus::Full));
|
||||||
proto_node_index: i,
|
}
|
||||||
payload_status: PayloadStatus::Empty,
|
children
|
||||||
};
|
} else {
|
||||||
let empty_weight = self
|
self.proto_array
|
||||||
.proto_array
|
.nodes
|
||||||
.get_weight::<E>(
|
.iter()
|
||||||
&empty_fc,
|
.enumerate()
|
||||||
node,
|
.filter(|(child_index, child_node)| {
|
||||||
apply_proposer_boost,
|
viable_indices.contains(child_index)
|
||||||
proposer_boost_root,
|
&& child_node.parent() == Some(fc_node.proto_node_index)
|
||||||
current_slot,
|
&& child_node.get_parent_payload_status() == fc_node.payload_status
|
||||||
justified_balances,
|
})
|
||||||
spec,
|
.map(|(child_index, child_node)| IndexedForkChoiceNode {
|
||||||
)
|
root: child_node.root(),
|
||||||
.map_err(|e| format!("get_weight failed: {e:?}"))?;
|
proto_node_index: child_index,
|
||||||
leaves.push((node.root(), PayloadStatus::Empty, empty_weight));
|
payload_status: PayloadStatus::Pending,
|
||||||
|
})
|
||||||
if node.payload_received().is_ok_and(|r| r) {
|
.collect()
|
||||||
let full_fc = IndexedForkChoiceNode {
|
|
||||||
root: node.root(),
|
|
||||||
proto_node_index: i,
|
|
||||||
payload_status: PayloadStatus::Full,
|
|
||||||
};
|
|
||||||
let full_weight = self
|
|
||||||
.proto_array
|
|
||||||
.get_weight::<E>(
|
|
||||||
&full_fc,
|
|
||||||
node,
|
|
||||||
apply_proposer_boost,
|
|
||||||
proposer_boost_root,
|
|
||||||
current_slot,
|
|
||||||
justified_balances,
|
|
||||||
spec,
|
|
||||||
)
|
|
||||||
.map_err(|e| format!("get_weight failed: {e:?}"))?;
|
|
||||||
leaves.push((node.root(), PayloadStatus::Full, full_weight));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Pre-Gloas: use Pending status (no payload split).
|
self.proto_array
|
||||||
let fc_node = IndexedForkChoiceNode {
|
.nodes
|
||||||
root: node.root(),
|
.iter()
|
||||||
proto_node_index: i,
|
.enumerate()
|
||||||
|
.filter(|(child_index, child_node)| {
|
||||||
|
viable_indices.contains(child_index)
|
||||||
|
&& child_node.parent() == Some(fc_node.proto_node_index)
|
||||||
|
})
|
||||||
|
.map(|(child_index, child_node)| IndexedForkChoiceNode {
|
||||||
|
root: child_node.root(),
|
||||||
|
proto_node_index: child_index,
|
||||||
payload_status: PayloadStatus::Pending,
|
payload_status: PayloadStatus::Pending,
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if children.is_empty() {
|
||||||
let weight = self
|
let weight = self
|
||||||
.proto_array
|
.proto_array
|
||||||
.get_weight::<E>(
|
.get_weight::<E>(
|
||||||
&fc_node,
|
&fc_node,
|
||||||
node,
|
proto_node,
|
||||||
apply_proposer_boost,
|
apply_proposer_boost,
|
||||||
proposer_boost_root,
|
proposer_boost_root,
|
||||||
current_slot,
|
current_slot,
|
||||||
@@ -1191,9 +1185,12 @@ impl ProtoArrayForkChoice {
|
|||||||
spec,
|
spec,
|
||||||
)
|
)
|
||||||
.map_err(|e| format!("get_weight failed: {e:?}"))?;
|
.map_err(|e| format!("get_weight failed: {e:?}"))?;
|
||||||
leaves.push((node.root(), PayloadStatus::Pending, weight));
|
leaves.push((fc_node.root, fc_node.payload_status, weight));
|
||||||
|
} else {
|
||||||
|
stack.extend(children);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(leaves)
|
Ok(leaves)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user