Optimize attestation processing (#841)

* Start updating types

* WIP

* Signature hacking

* Existing EF tests passing with fake_crypto

* Updates

* Delete outdated API spec

* The refactor continues

* It compiles

* WIP test fixes

* All release tests passing bar genesis state parsing

* Update and test YamlConfig

* Update to spec v0.10 compatible BLS

* Updates to BLS EF tests

* Add EF test for AggregateVerify

And delete unused hash2curve tests for uncompressed points

* Update EF tests to v0.10.1

* Use optional block root correctly in block proc

* Use genesis fork in deposit domain. All tests pass

* Cargo fmt

* Fast aggregate verify test

* Update REST API docs

* Cargo fmt

* Fix unused import

* Bump spec tags to v0.10.1

* Add `seconds_per_eth1_block` to chainspec

* Update to timestamp based eth1 voting scheme

* Return None from `get_votes_to_consider` if block cache is empty

* Handle overflows in `is_candidate_block`

* Revert to failing tests

* Fix eth1 data sets test

* Choose default vote according to spec

* Fix collect_valid_votes tests

* Fix `get_votes_to_consider` to choose all eligible blocks

* Uncomment winning_vote tests

* Add comments; remove unused code

* Reduce seconds_per_eth1_block for simulation

* Addressed review comments

* Add test for default vote case

* Fix logs

* Remove unused functions

* Meter default eth1 votes

* Fix comments

* Address review comments; remove unused dependency

* Add first attempt at attestation proc. re-write

* Add version 2 of attestation processing

* Minor fixes

* Add validator pubkey cache

* Make get_indexed_attestation take a committee

* Link signature processing into new attn verification

* First working version

* Ensure pubkey cache is updated

* Add more metrics, slight optimizations

* Clone committee cache during attestation processing

* Update shuffling cache during block processing

* Remove old commented-out code

* Fix shuffling cache insert bug

* Used indexed attestation in fork choice

* Restructure attn processing, add metrics

* Add more detailed metrics

* Tidy, fix failing tests

* Fix failing tests, tidy

* Disable/delete two outdated tests

* Tidy

* Add pubkey cache persistence file

* Add more comments

* Integrate persistence file into builder

* Add pubkey cache tests

* Add data_dir to beacon chain builder

* Remove Option in pubkey cache persistence file

* Ensure consistency between datadir/data_dir

* Fix failing network test

* Tidy

* Fix todos

* Add attestation processing tests

* Add another test

* Only run attestation tests in release

* Make attestation tests MainnetEthSpec

* Address Michael's comments

* Remove redundant check

* Fix warning

* Fix failing test

Co-authored-by: Michael Sproul <micsproul@gmail.com>
Co-authored-by: Pawan Dhananjay <pawandhananjay@gmail.com>
This commit is contained in:
Paul Hauner
2020-03-05 17:19:35 +11:00
committed by GitHub
parent c141f1cc03
commit 6656cb00e4
38 changed files with 1226 additions and 344 deletions

View File

@@ -57,6 +57,7 @@ impl ForkChoiceTestDefinition {
pub fn run(self) {
let fork_choice = ProtoArrayForkChoice::new(
self.finalized_block_slot,
Hash256::zero(),
self.justified_epoch,
self.finalized_epoch,
self.finalized_root,
@@ -120,7 +121,14 @@ impl ForkChoiceTestDefinition {
finalized_epoch,
} => {
fork_choice
.process_block(slot, root, parent_root, justified_epoch, finalized_epoch)
.process_block(
slot,
root,
parent_root,
Hash256::zero(),
justified_epoch,
finalized_epoch,
)
.expect(&format!(
"process_block op at index {} returned error",
op_index

View File

@@ -9,6 +9,9 @@ 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.
pub slot: Slot,
/// The `state_root` is not necessary for `ProtoArray` either, it also just exists for upstream
/// components (namely attestation verification).
pub state_root: Hash256,
root: Hash256,
parent: Option<usize>,
justified_epoch: Epoch,
@@ -126,6 +129,7 @@ impl ProtoArray {
slot: Slot,
root: Hash256,
parent_opt: Option<Hash256>,
state_root: Hash256,
justified_epoch: Epoch,
finalized_epoch: Epoch,
) -> Result<(), Error> {
@@ -138,6 +142,7 @@ impl ProtoArray {
let node = ProtoNode {
slot,
state_root,
root,
parent: parent_opt.and_then(|parent| self.indices.get(&parent).copied()),
justified_epoch,

View File

@@ -60,6 +60,7 @@ impl PartialEq for ProtoArrayForkChoice {
impl ProtoArrayForkChoice {
pub fn new(
finalized_block_slot: Slot,
finalized_block_state_root: Hash256,
justified_epoch: Epoch,
finalized_epoch: Epoch,
finalized_root: Hash256,
@@ -77,6 +78,7 @@ impl ProtoArrayForkChoice {
finalized_block_slot,
finalized_root,
None,
finalized_block_state_root,
justified_epoch,
finalized_epoch,
)
@@ -111,6 +113,7 @@ impl ProtoArrayForkChoice {
slot: Slot,
block_root: Hash256,
parent_root: Hash256,
state_root: Hash256,
justified_epoch: Epoch,
finalized_epoch: Epoch,
) -> Result<(), String> {
@@ -120,6 +123,7 @@ impl ProtoArrayForkChoice {
slot,
block_root,
Some(parent_root),
state_root,
justified_epoch,
finalized_epoch,
)
@@ -186,6 +190,15 @@ impl ProtoArrayForkChoice {
Some(block.slot)
}
pub fn block_slot_and_state_root(&self, block_root: &Hash256) -> Option<(Slot, Hash256)> {
let proto_array = self.proto_array.read();
let i = proto_array.indices.get(block_root)?;
let block = proto_array.nodes.get(*i)?;
Some((block.slot, block.state_root))
}
pub fn latest_message(&self, validator_index: usize) -> Option<(Hash256, Epoch)> {
let votes = self.votes.read();