@@ -16,7 +16,7 @@ use ssz::Encode;
1616use state_processing:: per_block_processing:: {
1717 errors:: {
1818 AttestationValidationError , AttesterSlashingValidationError , DepositValidationError ,
19- ExitValidationError , ProposerSlashingValidationError , TransferValidationError ,
19+ ExitValidationError , ProposerSlashingValidationError ,
2020 } ,
2121 verify_attestation_for_state, VerifySignatures ,
2222} ;
@@ -218,6 +218,44 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
218218 ReverseBlockRootIterator :: new ( ( head. beacon_block_root , head. beacon_block . slot ) , iter)
219219 }
220220
221+ /// Traverse backwards from `block_root` to find the block roots of its ancestors.
222+ ///
223+ /// ## Notes
224+ ///
225+ /// `slot` always decreases by `1`.
226+ /// - Skipped slots contain the root of the closest prior
227+ /// non-skipped slot (identical to the way they are stored in `state.block_roots`) .
228+ /// - Iterator returns `(Hash256, Slot)`.
229+ /// - The provided `block_root` is included as the first item in the iterator.
230+ pub fn rev_iter_block_roots_from (
231+ & self ,
232+ block_root : Hash256 ,
233+ ) -> Result < ReverseBlockRootIterator < T :: EthSpec , T :: Store > , Error > {
234+ let block = self
235+ . get_block ( & block_root) ?
236+ . ok_or_else ( || Error :: MissingBeaconBlock ( block_root) ) ?;
237+ let state = self
238+ . get_state ( & block. state_root ) ?
239+ . ok_or_else ( || Error :: MissingBeaconState ( block. state_root ) ) ?;
240+ let iter = BlockRootsIterator :: owned ( self . store . clone ( ) , state) ;
241+ Ok ( ReverseBlockRootIterator :: new (
242+ ( block_root, block. slot ) ,
243+ iter,
244+ ) )
245+ }
246+
247+ /// Traverse backwards from `block_root` to find the root of the ancestor block at `slot`.
248+ pub fn get_ancestor_block_root (
249+ & self ,
250+ block_root : Hash256 ,
251+ slot : Slot ,
252+ ) -> Result < Option < Hash256 > , Error > {
253+ Ok ( self
254+ . rev_iter_block_roots_from ( block_root) ?
255+ . find ( |( _, ancestor_slot) | * ancestor_slot == slot)
256+ . map ( |( ancestor_block_root, _) | ancestor_block_root) )
257+ }
258+
221259 /// Iterates across all `(state_root, slot)` pairs from the head of the chain (inclusive) to
222260 /// the earliest reachable ancestor (may or may not be genesis).
223261 ///
@@ -248,6 +286,18 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
248286 Ok ( self . store . get ( block_root) ?)
249287 }
250288
289+ /// Returns the state at the given root, if any.
290+ ///
291+ /// ## Errors
292+ ///
293+ /// May return a database error.
294+ pub fn get_state (
295+ & self ,
296+ state_root : & Hash256 ,
297+ ) -> Result < Option < BeaconState < T :: EthSpec > > , Error > {
298+ Ok ( self . store . get ( state_root) ?)
299+ }
300+
251301 /// Returns a `Checkpoint` representing the head block and state. Contains the "best block";
252302 /// the head of the canonical `BeaconChain`.
253303 ///
@@ -385,15 +435,15 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
385435 }
386436
387437 state
388- . get_beacon_proposer_index ( slot, RelativeEpoch :: Current , & self . spec )
438+ . get_beacon_proposer_index ( slot, & self . spec )
389439 . map_err ( Into :: into)
390440 }
391441
392- /// Returns the attestation slot and shard for a given validator index.
442+ /// Returns the attestation slot and committee index for a given validator index.
393443 ///
394444 /// Information is read from the current state, so only information from the present and prior
395445 /// epoch is available.
396- pub fn validator_attestation_slot_and_shard (
446+ pub fn validator_attestation_slot_and_index (
397447 & self ,
398448 validator_index : usize ,
399449 epoch : Epoch ,
@@ -420,25 +470,25 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
420470 if let Some ( attestation_duty) =
421471 state. get_attestation_duties ( validator_index, RelativeEpoch :: Current ) ?
422472 {
423- Ok ( Some ( ( attestation_duty. slot , attestation_duty. shard ) ) )
473+ Ok ( Some ( ( attestation_duty. slot , attestation_duty. index ) ) )
424474 } else {
425475 Ok ( None )
426476 }
427477 }
428478
429- /// Produce an `AttestationData` that is valid for the given `slot` `shard `.
479+ /// Produce an `AttestationData` that is valid for the given `slot`, `index `.
430480 ///
431481 /// Always attests to the canonical chain.
432482 pub fn produce_attestation_data (
433483 & self ,
434- shard : u64 ,
435484 slot : Slot ,
485+ index : CommitteeIndex ,
436486 ) -> Result < AttestationData , Error > {
437487 let state = self . state_at_slot ( slot) ?;
438488 let head = self . head ( ) ;
439489
440490 self . produce_attestation_data_for_block (
441- shard ,
491+ index ,
442492 head. beacon_block_root ,
443493 head. beacon_block . slot ,
444494 & state,
@@ -451,7 +501,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
451501 /// function should be used as it attests to the canonical chain.
452502 pub fn produce_attestation_data_for_block (
453503 & self ,
454- shard : u64 ,
504+ index : CommitteeIndex ,
455505 head_block_root : Hash256 ,
456506 head_block_slot : Slot ,
457507 state : & BeaconState < T :: EthSpec > ,
@@ -492,18 +542,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
492542 root : target_root,
493543 } ;
494544
495- let parent_crosslink = state. get_current_crosslink ( shard) ?;
496- let crosslink = Crosslink {
497- shard,
498- parent_root : Hash256 :: from_slice ( & parent_crosslink. tree_hash_root ( ) ) ,
499- start_epoch : parent_crosslink. end_epoch ,
500- end_epoch : std:: cmp:: min (
501- target. epoch ,
502- parent_crosslink. end_epoch + self . spec . max_epochs_per_crosslink ,
503- ) ,
504- data_root : Hash256 :: zero ( ) ,
505- } ;
506-
507545 // Collect some metrics.
508546 metrics:: inc_counter ( & metrics:: ATTESTATION_PRODUCTION_SUCCESSES ) ;
509547 metrics:: stop_timer ( timer) ;
@@ -512,15 +550,16 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
512550 self . log,
513551 "Produced beacon attestation data" ;
514552 "beacon_block_root" => format!( "{}" , head_block_root) ,
515- "shard " => shard ,
516- "slot " => state . slot
553+ "slot " => state . slot ,
554+ "index " => index
517555 ) ;
518556
519557 Ok ( AttestationData {
558+ slot : state. slot ,
559+ index,
520560 beacon_block_root : head_block_root,
521561 source : state. current_justified_checkpoint . clone ( ) ,
522562 target,
523- crosslink,
524563 } )
525564 }
526565
@@ -549,7 +588,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
549588 self . log,
550589 "Beacon attestation imported" ;
551590 "target_epoch" => attestation. data. target. epoch,
552- "shard " => attestation. data. crosslink . shard ,
591+ "index " => attestation. data. index ,
553592 ) ;
554593 let _ = self
555594 . event_handler
@@ -668,16 +707,14 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
668707
669708 state. build_committee_cache ( RelativeEpoch :: Current , & self . spec ) ?;
670709
671- let attestation_slot = state. get_attestation_data_slot ( & attestation. data ) ?;
672-
673710 // Reject any attestation where the `state` loaded from `data.beacon_block_root`
674711 // has a higher slot than the attestation.
675712 //
676713 // Permitting this would allow for attesters to vote on _future_ slots.
677- if state. slot > attestation_slot {
714+ if state. slot > attestation . data . slot {
678715 Ok ( AttestationProcessingOutcome :: AttestsToFutureState {
679716 state : state. slot ,
680- attestation : attestation_slot ,
717+ attestation : attestation . data . slot ,
681718 } )
682719 } else {
683720 self . process_attestation_for_state_and_block (
@@ -776,20 +813,27 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
776813
777814 Ok ( AttestationProcessingOutcome :: Invalid ( e) )
778815 } else {
779- // Provide the attestation to fork choice, updating the validator latest messages but
780- // _without_ finding and updating the head .
781- if let Err ( e ) = self
782- . fork_choice
783- . process_attestation ( & state , & attestation, block )
816+ // If the attestation is from the current or previous epoch, supply it to the fork
817+ // choice. This is FMD GHOST .
818+ let current_epoch = self . epoch ( ) ? ;
819+ if attestation . data . target . epoch == current_epoch
820+ || attestation. data . target . epoch == current_epoch - 1
784821 {
785- error ! (
786- self . log,
787- "Add attestation to fork choice failed" ;
788- "fork_choice_integrity" => format!( "{:?}" , self . fork_choice. verify_integrity( ) ) ,
789- "beacon_block_root" => format!( "{}" , attestation. data. beacon_block_root) ,
790- "error" => format!( "{:?}" , e)
791- ) ;
792- return Err ( e. into ( ) ) ;
822+ // Provide the attestation to fork choice, updating the validator latest messages but
823+ // _without_ finding and updating the head.
824+ if let Err ( e) = self
825+ . fork_choice
826+ . process_attestation ( & state, & attestation, block)
827+ {
828+ error ! (
829+ self . log,
830+ "Add attestation to fork choice failed" ;
831+ "fork_choice_integrity" => format!( "{:?}" , self . fork_choice. verify_integrity( ) ) ,
832+ "beacon_block_root" => format!( "{}" , attestation. data. beacon_block_root) ,
833+ "error" => format!( "{:?}" , e)
834+ ) ;
835+ return Err ( e. into ( ) ) ;
836+ }
793837 }
794838
795839 // Provide the valid attestation to op pool, which may choose to retain the
@@ -829,22 +873,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
829873 }
830874 }
831875
832- /// Accept some transfer and queue it for inclusion in an appropriate block.
833- pub fn process_transfer ( & self , transfer : Transfer ) -> Result < ( ) , TransferValidationError > {
834- match self . wall_clock_state ( ) {
835- Ok ( state) => self . op_pool . insert_transfer ( transfer, & state, & self . spec ) ,
836- Err ( e) => {
837- error ! (
838- & self . log,
839- "Unable to process transfer" ;
840- "error" => format!( "{:?}" , e) ,
841- "reason" => "no state"
842- ) ;
843- Ok ( ( ) )
844- }
845- }
846- }
847-
848876 /// Accept some proposer slashing and queue it for inclusion in an appropriate block.
849877 pub fn process_proposer_slashing (
850878 & self ,
@@ -905,7 +933,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
905933 self . log,
906934 "Beacon block imported" ;
907935 "block_root" => format!( "{:?}" , block_root) ,
908- "block_slot" => format!( "{:?}" , block_root ) ,
936+ "block_slot" => format!( "{:?}" , block . slot . as_u64 ( ) ) ,
909937 ) ;
910938 let _ = self . event_handler . register ( EventKind :: BeaconBlockImported {
911939 block_root : * block_root,
@@ -1115,7 +1143,10 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
11151143 metrics:: start_timer ( & metrics:: BLOCK_PROCESSING_FORK_CHOICE_REGISTER ) ;
11161144
11171145 // Register the new block with the fork choice service.
1118- if let Err ( e) = self . fork_choice . process_block ( & state, & block, block_root) {
1146+ if let Err ( e) = self
1147+ . fork_choice
1148+ . process_block ( self , & state, & block, block_root)
1149+ {
11191150 error ! (
11201151 self . log,
11211152 "Add block to fork choice failed" ;
@@ -1230,7 +1261,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
12301261 . deposits_for_block_inclusion ( & state, & self . spec ) ?
12311262 . into ( ) ,
12321263 voluntary_exits : self . op_pool . get_voluntary_exits ( & state, & self . spec ) . into ( ) ,
1233- transfers : self . op_pool . get_transfers ( & state, & self . spec ) . into ( ) ,
12341264 } ,
12351265 } ;
12361266
0 commit comments