@@ -46,22 +46,26 @@ func (as *AttesterServer) AttestationDataAtSlot(ctx context.Context, req *pb.Att
46
46
if err != nil {
47
47
return nil , fmt .Errorf ("failed to retrieve chain head: %v" , err )
48
48
}
49
- blockRoot , err := hashutil .HashBeaconBlock (head )
49
+ headRoot , err := hashutil .HashBeaconBlock (head )
50
50
if err != nil {
51
51
return nil , fmt .Errorf ("could not tree hash beacon block: %v" , err )
52
52
}
53
- beaconState , err := as .beaconDB .State (ctx )
53
+
54
+ // Let head state be the state of head block processed through empty slots up to assigned slot.
55
+ headState , err := as .beaconDB .HeadState (ctx )
54
56
if err != nil {
55
- return nil , fmt .Errorf ("could not fetch beacon state: %v" , err )
57
+ return nil , fmt .Errorf ("could not fetch head state: %v" , err )
56
58
}
57
- for beaconState .Slot < req .Slot {
58
- beaconState , err = state .ExecuteStateTransition (
59
- ctx , beaconState , nil /* block */ , blockRoot , state .DefaultConfig (),
59
+
60
+ for headState .Slot < req .Slot {
61
+ headState , err = state .ExecuteStateTransition (
62
+ ctx , headState , nil /* block */ , headRoot , state .DefaultConfig (),
60
63
)
61
64
if err != nil {
62
65
return nil , fmt .Errorf ("could not execute head transition: %v" , err )
63
66
}
64
67
}
68
+
65
69
// Fetch the epoch boundary root = hash_tree_root(epoch_boundary)
66
70
// where epoch_boundary is the block at the most recent epoch boundary in the
67
71
// chain defined by head -- i.e. the BeaconBlock where block.slot == get_epoch_start_slot(head.slot).
@@ -70,15 +74,12 @@ func (as *AttesterServer) AttestationDataAtSlot(ctx context.Context, req *pb.Att
70
74
epochBoundaryRoot := make ([]byte , 32 )
71
75
epochStartSlot := helpers .StartSlot (helpers .SlotToEpoch (head .Slot ))
72
76
if epochStartSlot == head .Slot {
73
- hash , err := hashutil .HashBeaconBlock (head )
74
- if err != nil {
75
- return nil , fmt .Errorf ("could not tree hash head block: %v" , err )
76
- }
77
- epochBoundaryRoot = hash [:]
77
+ epochBoundaryRoot = headRoot [:]
78
78
} else {
79
- epochBoundaryRoot , err = blocks .BlockRoot (beaconState , epochStartSlot )
79
+ epochBoundaryRoot , err = blocks .BlockRoot (headState , epochStartSlot )
80
80
if err != nil {
81
- return nil , fmt .Errorf ("could not get epoch boundary block: %v" , err )
81
+ return nil , fmt .Errorf ("could not get epoch boundary block for slot %d: %v" ,
82
+ epochStartSlot , err )
82
83
}
83
84
}
84
85
// epoch_start_slot = get_epoch_start_slot(slot_to_epoch(head.slot))
@@ -87,15 +88,12 @@ func (as *AttesterServer) AttestationDataAtSlot(ctx context.Context, req *pb.Att
87
88
// On the server side, this is fetched by calling get_block_root(state, justified_epoch).
88
89
// If the last justified boundary slot is the same as state current slot (ex: slot 0),
89
90
// we set justified block root to an empty root.
90
- lastJustifiedSlot := helpers .StartSlot (beaconState .JustifiedEpoch )
91
+ lastJustifiedSlot := helpers .StartSlot (headState .JustifiedEpoch )
91
92
justifiedBlockRoot := make ([]byte , 32 )
92
- if lastJustifiedSlot != beaconState .Slot {
93
- var justifiedBlock * pbp2p.BeaconBlock
94
- for i := uint64 (0 ); justifiedBlock == nil && i < params .BeaconConfig ().SlotsPerEpoch ; i ++ {
95
- justifiedBlock , err = as .beaconDB .BlockBySlot (lastJustifiedSlot - i )
96
- if err != nil {
97
- return nil , fmt .Errorf ("could not get justified block: %v" , err )
98
- }
93
+ if lastJustifiedSlot != headState .Slot {
94
+ justifiedBlock , err := as .beaconDB .BlockBySlot (lastJustifiedSlot )
95
+ if err != nil {
96
+ return nil , fmt .Errorf ("could not get justified block: %v" , err )
99
97
}
100
98
101
99
justifiedBlockRoot32 , err := hashutil .HashBeaconBlock (justifiedBlock )
@@ -105,15 +103,18 @@ func (as *AttesterServer) AttestationDataAtSlot(ctx context.Context, req *pb.Att
105
103
justifiedBlockRoot = justifiedBlockRoot32 [:]
106
104
}
107
105
108
- if beaconState .Slot == params .BeaconConfig ().GenesisSlot {
109
- epochBoundaryRoot = blockRoot [:]
110
- justifiedBlockRoot = blockRoot [:]
106
+ // If an attester has to attest for gensis block.
107
+ if headState .Slot == params .BeaconConfig ().GenesisSlot {
108
+ epochBoundaryRoot = headRoot [:]
109
+ justifiedBlockRoot = headRoot [:]
111
110
}
111
+
112
112
return & pb.AttestationDataResponse {
113
- BeaconBlockRootHash32 : blockRoot [:],
113
+ HeadSlot : headState .Slot ,
114
+ BeaconBlockRootHash32 : headRoot [:],
114
115
EpochBoundaryRootHash32 : epochBoundaryRoot ,
115
- JustifiedEpoch : beaconState .JustifiedEpoch ,
116
+ JustifiedEpoch : headState .JustifiedEpoch ,
116
117
JustifiedBlockRootHash32 : justifiedBlockRoot ,
117
- LatestCrosslink : beaconState .LatestCrosslinks [req .Shard ],
118
+ LatestCrosslink : headState .LatestCrosslinks [req .Shard ],
118
119
}, nil
119
120
}
0 commit comments