Implement Epoch Processing Helpers - Attestations Matching (#2379)

This commit is contained in:
terence tsao
2019-04-26 07:11:07 -07:00
committed by GitHub
parent 4318d21872
commit f9dbbb8496
7 changed files with 404 additions and 132 deletions

View File

@@ -5,6 +5,7 @@
package epoch
import (
"bytes"
"encoding/binary"
"fmt"
@@ -22,6 +23,14 @@ import (
var log = logrus.WithField("prefix", "core/state")
// MatchedAttestations is an object that contains the correctly
// voted attestations based on source, target and head criteria.
type MatchedAttestations struct {
source []*pb.PendingAttestation
target []*pb.PendingAttestation
head []*pb.PendingAttestation
}
// CanProcessEpoch checks the eligibility to process epoch.
// The epoch can be processed at the end of the last slot of every epoch
//
@@ -388,3 +397,75 @@ func UpdateLatestRandaoMixes(state *pb.BeaconState) (*pb.BeaconState, error) {
state.LatestRandaoMixes[nextEpoch] = randaoMix
return state, nil
}
// MatchAttestations matches the attestations gathered in a span of an epoch
// and categorize them whether they correctly voted for source, target and head.
// We combined the individual helpers from spec for efficiency and to achieve O(N) run time.
//
// Spec pseudocode definition:
// def get_matching_source_attestations(state: BeaconState, epoch: Epoch) -> List[PendingAttestation]:
// assert epoch in (get_current_epoch(state), get_previous_epoch(state))
// return state.current_epoch_attestations if epoch == get_current_epoch(state) else state.previous_epoch_attestations
//
// def get_matching_target_attestations(state: BeaconState, epoch: Epoch) -> List[PendingAttestation]:
// return [
// a for a in get_matching_source_attestations(state, epoch)
// if a.data.target_root == get_block_root(state, epoch)
// ]
//
// def get_matching_head_attestations(state: BeaconState, epoch: Epoch) -> List[PendingAttestation]:
// return [
// a for a in get_matching_source_attestations(state, epoch)
// if a.data.beacon_block_root == get_block_root_at_slot(state, a.data.slot)
// ]
func MatchAttestations(state *pb.BeaconState, epoch uint64) (*MatchedAttestations, error) {
currentEpoch := helpers.CurrentEpoch(state)
previousEpoch := helpers.PrevEpoch(state)
// Input epoch for matching the source attestations has to be within range
// of current epoch & previous epoch.
if epoch != currentEpoch && epoch != previousEpoch {
return nil, fmt.Errorf("input epoch: %d != current epoch: %d or previous epoch: %d",
epoch, currentEpoch, previousEpoch)
}
// Decide if the source attestations are coming from current or previous epoch.
var srcAtts []*pb.PendingAttestation
if epoch == currentEpoch {
srcAtts = state.CurrentEpochAttestations
} else {
srcAtts = state.PreviousEpochAttestations
}
targetRoot, err := helpers.BlockRoot(state, epoch)
if err != nil {
return nil, fmt.Errorf("could not get block root for epoch %d: %v", epoch, err)
}
//var tgtAtts []*pb.PendingAttestation
tgtAtts := make([]*pb.PendingAttestation, 0, len(srcAtts))
headAtts := make([]*pb.PendingAttestation, 0, len(srcAtts))
for _, srcAtt := range srcAtts {
// If the target root matches attestation's target root,
// then we know this attestation has correctly voted for target.
if bytes.Equal(srcAtt.Data.TargetRoot, targetRoot) {
tgtAtts = append(tgtAtts, srcAtt)
}
// If the block root at slot matches attestation's block root at slot,
// then we know this attestation has correctly voted for head.
headRoot, err := helpers.BlockRootAtSlot(state, srcAtt.Data.Slot)
if err != nil {
return nil, fmt.Errorf("could not get block root for slot %d: %v", srcAtt.Data.Slot, err)
}
if bytes.Equal(srcAtt.Data.BeaconBlockRoot, headRoot) {
headAtts = append(headAtts, srcAtt)
}
}
return &MatchedAttestations{
source: srcAtts,
target: tgtAtts,
head: headAtts,
}, nil
}

View File

@@ -599,3 +599,149 @@ func TestUpdateLatestActiveIndexRoots_UpdatesActiveIndexRoots(t *testing.T) {
)
}
}
func TestMatchAttestations_PrevEpoch(t *testing.T) {
e := params.BeaconConfig().SlotsPerEpoch
s := params.BeaconConfig().GenesisSlot
// The correct epoch for source is the first epoch
// The correct vote for target is '1'
// The correct vote for head is '2'
prevAtts := []*pb.PendingAttestation{
{Data: &pb.AttestationData{Slot: s + 1}}, // source
{Data: &pb.AttestationData{Slot: s + 1, TargetRoot: []byte{1}}}, // source, target
{Data: &pb.AttestationData{Slot: s + 1, TargetRoot: []byte{3}}}, // source
{Data: &pb.AttestationData{Slot: s + 1, TargetRoot: []byte{1}}}, // source, target
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{2}}}, // source, head
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{4}}}, // source
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{2}, TargetRoot: []byte{1}}}, // source, target, head
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{5}, TargetRoot: []byte{1}}}, // source, target
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{2}, TargetRoot: []byte{6}}}, // source, head
}
currentAtts := []*pb.PendingAttestation{
{Data: &pb.AttestationData{Slot: s + e + 1}}, // none
{Data: &pb.AttestationData{Slot: s + e + 1, BeaconBlockRoot: []byte{2}, TargetRoot: []byte{1}}}, // none
}
blockRoots := make([][]byte, 128)
for i := 0; i < len(blockRoots); i++ {
blockRoots[i] = []byte{byte(i + 1)}
}
state := &pb.BeaconState{
Slot: s + e + 2,
CurrentEpochAttestations: currentAtts,
PreviousEpochAttestations: prevAtts,
LatestBlockRoots: blockRoots,
}
mAtts, err := MatchAttestations(state, params.BeaconConfig().GenesisEpoch)
if err != nil {
t.Fatal(err)
}
wantedSrcAtts := []*pb.PendingAttestation{
{Data: &pb.AttestationData{Slot: s + 1}},
{Data: &pb.AttestationData{Slot: s + 1, TargetRoot: []byte{1}}},
{Data: &pb.AttestationData{Slot: s + 1, TargetRoot: []byte{3}}},
{Data: &pb.AttestationData{Slot: s + 1, TargetRoot: []byte{1}}},
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{2}}},
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{4}}},
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{2}, TargetRoot: []byte{1}}},
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{5}, TargetRoot: []byte{1}}},
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{2}, TargetRoot: []byte{6}}},
}
if !reflect.DeepEqual(mAtts.source, wantedSrcAtts) {
t.Error("source attestations don't match")
}
wantedTgtAtts := []*pb.PendingAttestation{
{Data: &pb.AttestationData{Slot: s + 1, TargetRoot: []byte{1}}},
{Data: &pb.AttestationData{Slot: s + 1, TargetRoot: []byte{1}}},
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{2}, TargetRoot: []byte{1}}},
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{5}, TargetRoot: []byte{1}}},
}
if !reflect.DeepEqual(mAtts.target, wantedTgtAtts) {
t.Error("target attestations don't match")
}
wantedHeadAtts := []*pb.PendingAttestation{
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{2}}},
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{2}, TargetRoot: []byte{1}}},
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{2}, TargetRoot: []byte{6}}},
}
if !reflect.DeepEqual(mAtts.head, wantedHeadAtts) {
t.Error("head attestations don't match")
}
}
func TestMatchAttestations_CurrentEpoch(t *testing.T) {
e := params.BeaconConfig().SlotsPerEpoch
s := params.BeaconConfig().GenesisSlot
// The correct epoch for source is the first epoch
// The correct vote for target is '65'
// The correct vote for head is '66'
prevAtts := []*pb.PendingAttestation{
{Data: &pb.AttestationData{Slot: s + 1}}, // none
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{2}, TargetRoot: []byte{1}}}, // none
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{5}, TargetRoot: []byte{1}}}, // none
{Data: &pb.AttestationData{Slot: s + 1, BeaconBlockRoot: []byte{2}, TargetRoot: []byte{6}}}, // none
}
currentAtts := []*pb.PendingAttestation{
{Data: &pb.AttestationData{Slot: s + e + 1}}, // source
{Data: &pb.AttestationData{Slot: s + e + 1, BeaconBlockRoot: []byte{66}, TargetRoot: []byte{65}}}, // source, target, head
{Data: &pb.AttestationData{Slot: s + e + 1, BeaconBlockRoot: []byte{69}, TargetRoot: []byte{65}}}, // source, target
{Data: &pb.AttestationData{Slot: s + e + 1, BeaconBlockRoot: []byte{66}, TargetRoot: []byte{68}}}, // source, head
}
blockRoots := make([][]byte, 128)
for i := 0; i < len(blockRoots); i++ {
blockRoots[i] = []byte{byte(i + 1)}
}
state := &pb.BeaconState{
Slot: s + e + 2,
CurrentEpochAttestations: currentAtts,
PreviousEpochAttestations: prevAtts,
LatestBlockRoots: blockRoots,
}
mAtts, err := MatchAttestations(state, params.BeaconConfig().GenesisEpoch+1)
if err != nil {
t.Fatal(err)
}
wantedSrcAtts := []*pb.PendingAttestation{
{Data: &pb.AttestationData{Slot: s + e + 1}},
{Data: &pb.AttestationData{Slot: s + e + 1, BeaconBlockRoot: []byte{66}, TargetRoot: []byte{65}}},
{Data: &pb.AttestationData{Slot: s + e + 1, BeaconBlockRoot: []byte{69}, TargetRoot: []byte{65}}},
{Data: &pb.AttestationData{Slot: s + e + 1, BeaconBlockRoot: []byte{66}, TargetRoot: []byte{68}}},
}
if !reflect.DeepEqual(mAtts.source, wantedSrcAtts) {
t.Error("source attestations don't match")
}
wantedTgtAtts := []*pb.PendingAttestation{
{Data: &pb.AttestationData{Slot: s + e + 1, BeaconBlockRoot: []byte{66}, TargetRoot: []byte{65}}},
{Data: &pb.AttestationData{Slot: s + e + 1, BeaconBlockRoot: []byte{69}, TargetRoot: []byte{65}}},
}
if !reflect.DeepEqual(mAtts.target, wantedTgtAtts) {
t.Error("target attestations don't match")
}
wantedHeadAtts := []*pb.PendingAttestation{
{Data: &pb.AttestationData{Slot: s + e + 1, BeaconBlockRoot: []byte{66}, TargetRoot: []byte{65}}},
{Data: &pb.AttestationData{Slot: s + e + 1, BeaconBlockRoot: []byte{66}, TargetRoot: []byte{68}}},
}
if !reflect.DeepEqual(mAtts.head, wantedHeadAtts) {
t.Error("head attestations don't match")
}
}
func TestMatchAttestations_EpochOutOfBound(t *testing.T) {
_, err := MatchAttestations(&pb.BeaconState{Slot: 1}, 2 /* epoch */)
if !strings.Contains(err.Error(), "input epoch: 2 != current epoch: 0") {
t.Fatal("Did not receive wanted error")
}
}

View File

@@ -7,17 +7,17 @@ import (
"github.com/prysmaticlabs/prysm/shared/params"
)
// BlockRoot returns the block root stored in the BeaconState for a recent slot.
// BlockRootAtSlot returns the block root stored in the BeaconState for a recent slot.
// It returns an error if the requested block root is not within the slot range.
// Spec pseudocode definition:
// def get_block_root(state: BeaconState,
// slot: Slot) -> Bytes32:
// def get_block_root_at_slot(state: BeaconState,
// slot: Slot) -> Bytes32:
// """
// Return the block root at a recent ``slot``.
// """
// assert slot < state.slot <= slot + SLOTS_PER_HISTORICAL_ROOT
// return state.latest_block_roots[slot % SLOTS_PER_HISTORICAL_ROOT]
func BlockRoot(state *pb.BeaconState, slot uint64) ([]byte, error) {
func BlockRootAtSlot(state *pb.BeaconState, slot uint64) ([]byte, error) {
earliestSlot := state.Slot - params.BeaconConfig().SlotsPerHistoricalRoot
if slot < earliestSlot || slot >= state.Slot {
@@ -30,5 +30,17 @@ func BlockRoot(state *pb.BeaconState, slot uint64) ([]byte, error) {
state.Slot-params.BeaconConfig().GenesisSlot,
)
}
return state.LatestBlockRoots[slot%params.BeaconConfig().SlotsPerHistoricalRoot], nil
}
// BlockRoot returns the block root stored in the BeaconState for epoch start slot.
// def get_block_root(state: BeaconState,
// epoch: Epoch) -> Bytes32:
// """
// Return the block root at a recent ``epoch``.
// """
// return get_block_root_at_slot(state, get_epoch_start_slot(epoch))
func BlockRoot(state *pb.BeaconState, epoch uint64) ([]byte, error) {
return BlockRootAtSlot(state, StartSlot(epoch))
}

View File

@@ -51,7 +51,7 @@ func TestBlockRootAtSlot_CorrectBlockRoot(t *testing.T) {
for _, tt := range tests {
s.Slot = tt.stateSlot + params.BeaconConfig().GenesisSlot
wantedSlot := tt.slot + params.BeaconConfig().GenesisSlot
result, err := BlockRoot(s, wantedSlot)
result, err := BlockRootAtSlot(s, wantedSlot)
if err != nil {
t.Fatalf("failed to get block root at slot %d: %v",
wantedSlot-params.BeaconConfig().GenesisSlot, err)
@@ -97,7 +97,7 @@ func TestBlockRootAtSlot_OutOfBounds(t *testing.T) {
}
for _, tt := range tests {
state.Slot = tt.stateSlot
_, err := BlockRoot(state, tt.slot)
_, err := BlockRootAtSlot(state, tt.slot)
if err != nil && err.Error() != tt.expectedErr {
t.Errorf("Expected error \"%s\" got \"%v\"", tt.expectedErr, err)
}

View File

@@ -650,8 +650,8 @@ type AttestationData struct {
Slot uint64 `protobuf:"varint,1,opt,name=slot,proto3" json:"slot,omitempty"`
BeaconBlockRoot []byte `protobuf:"bytes,2,opt,name=beacon_block_root,json=beaconBlockRoot,proto3" json:"beacon_block_root,omitempty"`
SourceEpoch uint64 `protobuf:"varint,3,opt,name=source_epoch,json=sourceEpoch,proto3" json:"source_epoch,omitempty"`
SourceRoot uint64 `protobuf:"varint,4,opt,name=source_root,json=sourceRoot,proto3" json:"source_root,omitempty"`
TargetRoot uint64 `protobuf:"varint,5,opt,name=target_root,json=targetRoot,proto3" json:"target_root,omitempty"`
SourceRoot []byte `protobuf:"bytes,4,opt,name=source_root,json=sourceRoot,proto3" json:"source_root,omitempty"`
TargetRoot []byte `protobuf:"bytes,5,opt,name=target_root,json=targetRoot,proto3" json:"target_root,omitempty"`
Shard uint64 `protobuf:"varint,6,opt,name=shard,proto3" json:"shard,omitempty"`
PreviousCrosslinkRoot []byte `protobuf:"bytes,7,opt,name=previous_crosslink_root,json=previousCrosslinkRoot,proto3" json:"previous_crosslink_root,omitempty"`
CrosslinkDataRoot []byte `protobuf:"bytes,8,opt,name=crosslink_data_root,json=crosslinkDataRoot,proto3" json:"crosslink_data_root,omitempty"`
@@ -720,18 +720,18 @@ func (m *AttestationData) GetSourceEpoch() uint64 {
return 0
}
func (m *AttestationData) GetSourceRoot() uint64 {
func (m *AttestationData) GetSourceRoot() []byte {
if m != nil {
return m.SourceRoot
}
return 0
return nil
}
func (m *AttestationData) GetTargetRoot() uint64 {
func (m *AttestationData) GetTargetRoot() []byte {
if m != nil {
return m.TargetRoot
}
return 0
return nil
}
func (m *AttestationData) GetShard() uint64 {
@@ -2561,106 +2561,106 @@ var fileDescriptor_e719e7d82cfa7b0d = []byte{
0x65, 0x60, 0x24, 0x66, 0x6d, 0x29, 0x4e, 0xe5, 0xfb, 0xe3, 0x50, 0x4c, 0x39, 0x4a, 0x88, 0x1c,
0x1b, 0x32, 0xc6, 0xd4, 0x70, 0x15, 0xca, 0x18, 0x9d, 0x91, 0x93, 0xd2, 0xe7, 0x62, 0x43, 0xdf,
0x43, 0x01, 0x20, 0xe7, 0xa0, 0xc0, 0x82, 0x7e, 0xd8, 0x54, 0x35, 0x07, 0xf7, 0x3f, 0x8f, 0x34,
0xc4, 0xa3, 0x65, 0x90, 0x9f, 0x68, 0x68, 0x4c, 0x48, 0x00, 0x92, 0x84, 0x8d, 0x65, 0xc8, 0x47,
0x6e, 0xd8, 0xa6, 0x11, 0x0a, 0x8c, 0xa3, 0x00, 0x92, 0x84, 0xc0, 0x1c, 0x8c, 0x63, 0xf5, 0x38,
0x81, 0x77, 0x50, 0x7c, 0x90, 0xc7, 0x8c, 0x06, 0x36, 0xce, 0x7d, 0x34, 0x31, 0x91, 0xec, 0x5f,
0x75, 0x9b, 0xc5, 0xad, 0x55, 0x61, 0x56, 0x8b, 0x8b, 0x9a, 0x2d, 0x74, 0x26, 0x85, 0x4e, 0x39,
0x66, 0x89, 0x73, 0xe4, 0xf2, 0xd7, 0x60, 0x09, 0xfb, 0xff, 0x46, 0xd0, 0xef, 0x7a, 0x6e, 0x78,
0x60, 0x82, 0x94, 0xf5, 0xd7, 0x89, 0x18, 0x5b, 0x17, 0x85, 0xd8, 0xba, 0x94, 0xd2, 0x20, 0x45,
0x5e, 0x8e, 0xbb, 0x8d, 0xd8, 0x3a, 0x8e, 0x7d, 0x47, 0x86, 0xa8, 0x62, 0x0a, 0xa2, 0x86, 0x95,
0x04, 0x31, 0x2c, 0x0e, 0x2f, 0x09, 0xeb, 0x70, 0x52, 0x4b, 0x0f, 0x00, 0x2d, 0xce, 0x8c, 0x18,
0x83, 0x15, 0xcb, 0xa5, 0x90, 0x96, 0xfc, 0x2f, 0x58, 0x03, 0xb7, 0x42, 0x19, 0xf8, 0x50, 0x1b,
0x98, 0x4f, 0xdd, 0x10, 0xa9, 0x7d, 0x0d, 0x96, 0x86, 0x6c, 0xba, 0xd2, 0xff, 0xbb, 0xb1, 0x89,
0x03, 0x07, 0x80, 0x16, 0x2a, 0x6d, 0x28, 0x1b, 0x97, 0x77, 0x5b, 0xdc, 0x8e, 0xa1, 0xd7, 0xf7,
0x34, 0xc0, 0xc0, 0xbd, 0x9d, 0x6a, 0xc4, 0x37, 0x76, 0x19, 0xf2, 0x3d, 0x57, 0x00, 0x9f, 0xe0,
0x63, 0x72, 0x01, 0x92, 0xb8, 0x40, 0xe5, 0x33, 0x70, 0x2a, 0x95, 0x25, 0x6b, 0x5d, 0xef, 0x7a,
0x9c, 0x7c, 0x1f, 0x0f, 0x12, 0x96, 0x21, 0x6f, 0xe4, 0xb7, 0xf0, 0x6e, 0xd2, 0x06, 0x9d, 0xda,
0x95, 0x3f, 0x64, 0x80, 0x88, 0x32, 0x4b, 0xbd, 0x24, 0xb2, 0xce, 0x1b, 0x7a, 0xce, 0xc3, 0xbc,
0x5e, 0xfb, 0xbc, 0xdf, 0xce, 0x88, 0x76, 0x9b, 0x68, 0x0b, 0x0f, 0x6f, 0x22, 0x27, 0xad, 0x52,
0x8b, 0x55, 0xb2, 0x69, 0x95, 0x9a, 0x52, 0x51, 0xa1, 0xe5, 0x3e, 0x4a, 0x68, 0xa7, 0x60, 0x2a,
0x8d, 0x42, 0x9a, 0x50, 0x79, 0x6b, 0x1c, 0xa6, 0xe2, 0x87, 0x05, 0xb2, 0x00, 0x27, 0x7a, 0xfd,
0xc6, 0x2e, 0x3d, 0x90, 0xa5, 0x41, 0x7e, 0xf1, 0xd9, 0xf2, 0x35, 0x3f, 0xda, 0xf1, 0x42, 0xf7,
0x35, 0xb7, 0xe3, 0x34, 0x43, 0xea, 0xd1, 0x6e, 0xe4, 0xbb, 0x1d, 0x26, 0xcf, 0x71, 0x5e, 0x73,
0xaf, 0x6b, 0x26, 0xb9, 0x06, 0xa7, 0xc4, 0x10, 0x83, 0x38, 0x4b, 0x3b, 0x7e, 0xdb, 0x6f, 0xf8,
0x1d, 0x3f, 0x3a, 0x48, 0xa0, 0xd2, 0x92, 0x96, 0xd9, 0xd0, 0x22, 0x98, 0x21, 0x57, 0xa0, 0x64,
0x5a, 0x10, 0x5a, 0x88, 0x54, 0x45, 0x43, 0x4b, 0x88, 0x9e, 0x06, 0xa0, 0x77, 0x7c, 0xf9, 0x28,
0x20, 0xd1, 0x6a, 0x8a, 0x53, 0x90, 0xfd, 0x10, 0x90, 0xd8, 0xc9, 0x46, 0x47, 0xe1, 0x22, 0x22,
0x57, 0xd9, 0xe4, 0xa0, 0xb8, 0x05, 0x13, 0x72, 0x86, 0x12, 0xa8, 0x35, 0x69, 0xab, 0x4f, 0xf2,
0x00, 0x94, 0x69, 0xab, 0x45, 0x71, 0x38, 0x93, 0xf3, 0x95, 0x40, 0xa9, 0x31, 0xbb, 0x14, 0x33,
0xe4, 0x64, 0x45, 0xaa, 0x50, 0x32, 0x36, 0x0e, 0xd7, 0xbc, 0xab, 0x01, 0xa1, 0xa8, 0x99, 0xb8,
0xec, 0x65, 0x98, 0x56, 0xa3, 0xdb, 0x00, 0x7a, 0x14, 0x24, 0x07, 0x25, 0x5f, 0x81, 0x02, 0x3f,
0xeb, 0x3e, 0x73, 0x5a, 0x1d, 0xb7, 0xcd, 0x10, 0x2c, 0x66, 0xea, 0x0f, 0xdd, 0xf3, 0xf5, 0xa8,
0xba, 0x25, 0xd4, 0x9e, 0xe2, 0x5a, 0xd8, 0xb3, 0x30, 0x4d, 0x20, 0x4f, 0xc3, 0xe9, 0xe1, 0x27,
0x3d, 0x04, 0x53, 0x4e, 0x0e, 0x3d, 0x75, 0x89, 0x0b, 0xcf, 0x41, 0xde, 0x58, 0x88, 0x14, 0x61,
0x62, 0xf3, 0x85, 0xcd, 0xed, 0xcd, 0xb5, 0xe7, 0x4a, 0xff, 0xb5, 0x94, 0x9d, 0xcc, 0x90, 0x05,
0x98, 0x41, 0xc2, 0xf6, 0xc6, 0x0d, 0x67, 0xe3, 0xff, 0x36, 0xb7, 0x4b, 0x19, 0x41, 0x9f, 0x83,
0xc2, 0xad, 0xcd, 0xed, 0x9b, 0x37, 0xec, 0xb5, 0x5b, 0x6b, 0xeb, 0xcf, 0x6d, 0x94, 0xb2, 0x9c,
0x5a, 0xe9, 0xc0, 0xa2, 0x98, 0x40, 0x6c, 0xea, 0x32, 0x7e, 0x79, 0xf7, 0x38, 0x2a, 0xd0, 0x66,
0x10, 0x7a, 0xbc, 0x65, 0xd2, 0x13, 0x17, 0x4e, 0x66, 0x08, 0x3b, 0x33, 0x31, 0x19, 0x47, 0xb3,
0xb8, 0x5c, 0x65, 0xcd, 0x72, 0xa5, 0xa0, 0x2a, 0xa7, 0xa1, 0xaa, 0xf2, 0x66, 0x06, 0xa6, 0x34,
0xa6, 0xc7, 0xad, 0x56, 0xc6, 0x68, 0xb5, 0xc8, 0x75, 0x63, 0x1c, 0x49, 0x96, 0x39, 0xb5, 0x53,
0x98, 0x1a, 0x27, 0x87, 0x56, 0x3b, 0x09, 0xbf, 0x4f, 0x1c, 0x0a, 0xbf, 0x88, 0x81, 0x23, 0x91,
0xf7, 0xf5, 0x9c, 0x7a, 0xc1, 0x14, 0xa8, 0x3e, 0xaa, 0x67, 0x90, 0xa8, 0x3a, 0xd8, 0x33, 0x20,
0x43, 0xf7, 0x0c, 0xa7, 0x01, 0xf4, 0x0b, 0x85, 0x5c, 0x7c, 0x8a, 0xa9, 0x97, 0x09, 0x0e, 0x42,
0x8d, 0xc0, 0x3b, 0x10, 0xe9, 0x77, 0x08, 0x08, 0x99, 0x1d, 0x71, 0xe0, 0x1d, 0xd8, 0x42, 0x29,
0x09, 0x42, 0xe3, 0x29, 0x10, 0xe2, 0xb9, 0x69, 0x60, 0xbf, 0x0a, 0xff, 0x2e, 0xb6, 0x0b, 0x25,
0x5d, 0x03, 0xe4, 0xae, 0x3d, 0x00, 0x65, 0xed, 0xa8, 0x92, 0xfe, 0x00, 0xa5, 0x8b, 0xb1, 0xc3,
0x52, 0xf8, 0x02, 0x4c, 0xcb, 0x47, 0xcf, 0x90, 0xee, 0x53, 0xb7, 0x23, 0xab, 0xaa, 0x5d, 0x40,
0xaa, 0x2d, 0x88, 0x64, 0x15, 0xa6, 0xf4, 0x8b, 0xc3, 0x87, 0x13, 0x47, 0x7c, 0x71, 0x98, 0x54,
0x2f, 0x04, 0x95, 0x1f, 0x8e, 0x41, 0x31, 0x15, 0x39, 0x39, 0x9f, 0x5e, 0x39, 0x33, 0x64, 0xe1,
0x27, 0xcd, 0x85, 0xb3, 0xc7, 0x5d, 0x97, 0x3c, 0x0d, 0x85, 0xc4, 0x28, 0x94, 0x13, 0x93, 0xd0,
0xf9, 0x23, 0x54, 0x08, 0x3b, 0xa1, 0x48, 0x6e, 0x01, 0xe9, 0x85, 0x41, 0x2f, 0x60, 0x34, 0xc4,
0xc7, 0x23, 0xbf, 0xdb, 0x66, 0xd6, 0x98, 0x30, 0x77, 0x79, 0xe4, 0x60, 0x25, 0x35, 0xb6, 0xa4,
0x82, 0x5d, 0xee, 0xa5, 0x28, 0xc2, 0x30, 0x2e, 0x94, 0x30, 0x3c, 0x7e, 0xb8, 0xe1, 0x35, 0xa9,
0xa1, 0x0d, 0xbb, 0x29, 0x0a, 0x2f, 0x8a, 0x93, 0xf2, 0xe5, 0x85, 0x59, 0x27, 0x84, 0xb9, 0xe5,
0x51, 0xe6, 0x6e, 0xa0, 0x9c, 0x1d, 0x2b, 0x90, 0x17, 0xa0, 0xb8, 0x1f, 0x74, 0xfa, 0xdd, 0x88,
0xf7, 0x8d, 0xbc, 0x48, 0x30, 0x6b, 0x42, 0xd8, 0xb8, 0x7f, 0x24, 0x7e, 0x2a, 0xf1, 0x8d, 0x3b,
0x7e, 0x64, 0xcf, 0xec, 0x9b, 0x9f, 0x7c, 0xe0, 0x9e, 0x8a, 0x42, 0xb7, 0xcb, 0x5a, 0x34, 0x64,
0xd6, 0xa4, 0xb0, 0x34, 0xf2, 0x18, 0xb7, 0xa5, 0xa0, 0xad, 0x55, 0x2a, 0x5f, 0xc9, 0x40, 0xe1,
0x86, 0x7a, 0x47, 0xea, 0xf5, 0xa3, 0x91, 0x95, 0xb8, 0x0a, 0xb3, 0xbd, 0x30, 0x08, 0x5a, 0x4e,
0xd0, 0x72, 0x7a, 0x01, 0x63, 0x94, 0xc5, 0x43, 0x62, 0x41, 0x6c, 0x7f, 0xd0, 0x7a, 0xb1, 0xf5,
0x52, 0xcc, 0x20, 0xeb, 0xf7, 0xc2, 0x73, 0xcc, 0xf3, 0x43, 0xa1, 0xfc, 0x36, 0x10, 0x3c, 0x69,
0xb7, 0xc3, 0xa7, 0x16, 0xea, 0x8d, 0x1c, 0x51, 0x86, 0x43, 0x2c, 0x1f, 0x5c, 0x06, 0x7a, 0x53,
0x39, 0x3d, 0x35, 0x92, 0x0d, 0x69, 0xe5, 0xcf, 0x19, 0x98, 0x13, 0x67, 0xcc, 0x4b, 0xb1, 0xd9,
0x69, 0x3d, 0x00, 0xe5, 0x04, 0xcc, 0x1b, 0x5d, 0x56, 0xc9, 0x04, 0x7a, 0xd1, 0x30, 0x0d, 0x1b,
0xd7, 0xb2, 0xc3, 0xc7, 0xb5, 0x8f, 0xd5, 0x5b, 0x1d, 0x7b, 0xd6, 0xfb, 0x6c, 0x16, 0xf2, 0xf2,
0x9c, 0xc5, 0x26, 0x7e, 0xc2, 0x0d, 0xd7, 0x02, 0x9c, 0x70, 0xf7, 0x82, 0x7e, 0x57, 0x95, 0x33,
0xf9, 0x75, 0x78, 0x0f, 0x48, 0x5e, 0x30, 0x5f, 0x36, 0x7b, 0xfd, 0x48, 0x0d, 0x41, 0x17, 0xee,
0x91, 0x4f, 0xe2, 0xa6, 0x62, 0x6b, 0xe2, 0x99, 0x77, 0xf7, 0x1c, 0x4c, 0x45, 0xfe, 0x1e, 0xdf,
0xae, 0xbd, 0x9e, 0xd9, 0xc0, 0x68, 0x6a, 0xe5, 0x2f, 0x39, 0x28, 0xa5, 0xd1, 0x83, 0xdc, 0x0f,
0x33, 0x31, 0x06, 0x99, 0x85, 0x7c, 0x5a, 0x51, 0xb1, 0x8e, 0xdf, 0x80, 0x49, 0x7c, 0x9f, 0x76,
0x6a, 0x12, 0x31, 0x8f, 0xf1, 0x40, 0x3d, 0x81, 0xaa, 0x35, 0xc3, 0x4a, 0x5d, 0x9e, 0xfd, 0xf1,
0xad, 0xd4, 0xc9, 0x2d, 0x28, 0xf6, 0x64, 0x6a, 0x60, 0xfd, 0xae, 0xa9, 0xcd, 0xbb, 0x7a, 0x38,
0x68, 0x9a, 0xa9, 0x84, 0x2f, 0x80, 0xca, 0x0e, 0xa7, 0xd4, 0xc8, 0xa3, 0x30, 0x17, 0x1b, 0x8e,
0x4f, 0xca, 0xa9, 0xc9, 0x32, 0x87, 0xef, 0x57, 0x3d, 0xc3, 0x92, 0xe0, 0xd7, 0x06, 0xfd, 0x91,
0x53, 0xe4, 0xc7, 0xf4, 0xa7, 0x3e, 0xc2, 0x9f, 0x44, 0x3b, 0x38, 0xe8, 0x4f, 0xbd, 0xf2, 0x46,
0x0e, 0x4a, 0x69, 0x30, 0x27, 0x2f, 0xc2, 0xb4, 0x51, 0x7b, 0x9c, 0x9a, 0x1c, 0xd9, 0x46, 0x7a,
0x38, 0x38, 0x77, 0x25, 0x8a, 0x57, 0x2d, 0x6d, 0xb0, 0x2e, 0xaf, 0xc5, 0x47, 0x35, 0x58, 0x27,
0x3e, 0x2c, 0x32, 0x05, 0x42, 0x4e, 0xd2, 0x57, 0x79, 0xbc, 0x0f, 0x8e, 0xb2, 0x3d, 0x0c, 0xbc,
0x70, 0x02, 0x67, 0x43, 0x38, 0xb5, 0xd1, 0x4b, 0xd5, 0xd5, 0xcf, 0xcc, 0x9f, 0xd0, 0x52, 0xf5,
0xca, 0xbf, 0x33, 0x30, 0x21, 0x53, 0x97, 0x23, 0xb5, 0x28, 0x16, 0x02, 0x42, 0x0b, 0x36, 0x7e,
0x70, 0x2a, 0x26, 0x9e, 0xc4, 0x6f, 0xf1, 0x41, 0x1e, 0x4f, 0x40, 0xe4, 0xf9, 0x7b, 0xa0, 0x82,
0x01, 0x8f, 0x8f, 0xc2, 0xdc, 0x1e, 0x0d, 0x77, 0x3b, 0xd4, 0xc1, 0x9a, 0xa5, 0x1e, 0x90, 0xef,
0x4e, 0xc4, 0x0f, 0xc8, 0x04, 0x05, 0x5e, 0xe2, 0x7c, 0xf5, 0x76, 0xbc, 0x02, 0x65, 0xa9, 0x16,
0x85, 0x54, 0xfe, 0x00, 0x66, 0xe2, 0x48, 0x11, 0xb9, 0xdb, 0x21, 0xc5, 0x1f, 0xbf, 0xc8, 0x45,
0x50, 0x00, 0x84, 0x7d, 0x94, 0xf1, 0x70, 0x92, 0xf7, 0xb4, 0x57, 0x95, 0x0e, 0x4c, 0x27, 0xca,
0xf8, 0x88, 0xd6, 0x7e, 0xc8, 0x44, 0x91, 0x1d, 0x3a, 0x51, 0x24, 0x60, 0x35, 0x97, 0x1e, 0xad,
0xbf, 0x93, 0x81, 0x49, 0x55, 0xeb, 0x39, 0x32, 0x33, 0xda, 0xf5, 0x68, 0x28, 0x97, 0x92, 0x5f,
0xdc, 0x44, 0x48, 0x9b, 0x7e, 0xcf, 0xa7, 0xdd, 0x48, 0xae, 0xa2, 0x09, 0x23, 0xf1, 0xbc, 0x04,
0xb9, 0x16, 0xa5, 0x72, 0x12, 0xe6, 0x7f, 0xc6, 0xd5, 0x78, 0xdc, 0xa8, 0xc6, 0xba, 0xb8, 0x9c,
0x48, 0x14, 0x97, 0x84, 0xdb, 0x13, 0x69, 0xb7, 0xdf, 0xc9, 0xc0, 0x64, 0xfc, 0x1b, 0xda, 0x39,
0xbd, 0xb3, 0x62, 0x2a, 0xc0, 0x2a, 0xa5, 0x36, 0x55, 0xcc, 0x05, 0xe7, 0x75, 0xf5, 0x68, 0x0a,
0x57, 0xb3, 0x89, 0x9f, 0xc5, 0xae, 0x0b, 0x87, 0x93, 0x8f, 0x3f, 0xb9, 0xf4, 0xe3, 0xcf, 0x23,
0x30, 0x6b, 0x2e, 0x33, 0xe4, 0x11, 0xaf, 0x6c, 0x2c, 0x29, 0x3b, 0xfb, 0x8b, 0x50, 0x90, 0xbf,
0x56, 0x9a, 0xf3, 0x02, 0x9e, 0xba, 0x60, 0xc8, 0x96, 0xa2, 0x03, 0x05, 0xf3, 0x77, 0xbd, 0x64,
0xcb, 0x9d, 0x39, 0x76, 0xcb, 0x7d, 0x1a, 0x60, 0x3f, 0x88, 0x68, 0x22, 0xd8, 0x29, 0x4e, 0x11,
0x91, 0x56, 0xb6, 0xa0, 0x78, 0x33, 0xfe, 0x55, 0x73, 0xdd, 0x8d, 0xf0, 0xa5, 0xd5, 0xfc, 0xa5,
0x18, 0x33, 0x0e, 0x1a, 0xfa, 0x27, 0xe2, 0x65, 0xc8, 0x9b, 0xbf, 0x0d, 0x67, 0x51, 0x20, 0x9e,
0x64, 0x58, 0xe5, 0x07, 0x19, 0x28, 0x0f, 0x54, 0xa1, 0xa1, 0x1d, 0x58, 0xd5, 0xf8, 0xc5, 0x7b,
0x60, 0xe4, 0x2b, 0x2b, 0xd6, 0x91, 0x87, 0xbe, 0x8b, 0x80, 0x1d, 0x9a, 0xc3, 0xa7, 0x38, 0xfd,
0x50, 0x5c, 0xb0, 0xa7, 0x1b, 0xf1, 0x84, 0xc7, 0xe5, 0x0e, 0x9d, 0xef, 0xd6, 0x0b, 0x6f, 0xbf,
0x7f, 0x26, 0xf3, 0xee, 0xfb, 0x67, 0x32, 0xef, 0xbd, 0x7f, 0x26, 0xd3, 0x38, 0x21, 0xfe, 0x01,
0xe7, 0x91, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0xee, 0x27, 0x24, 0x41, 0xd8, 0x23, 0x00, 0x00,
0xc4, 0xa3, 0x65, 0x90, 0x9f, 0x68, 0x08, 0xfd, 0x03, 0x24, 0x09, 0x1b, 0xcb, 0x90, 0x8f, 0xdc,
0xb0, 0x4d, 0x23, 0x14, 0x18, 0x47, 0x01, 0x24, 0x09, 0x81, 0x39, 0x18, 0xc7, 0xea, 0x71, 0x02,
0xef, 0xa0, 0xf8, 0x20, 0x8f, 0x19, 0x0d, 0x6c, 0x9c, 0xfb, 0x68, 0x62, 0x22, 0xd9, 0xbf, 0xea,
0x36, 0x8b, 0x5b, 0xab, 0xc2, 0xac, 0x16, 0x17, 0x35, 0x5b, 0xe8, 0x4c, 0x0a, 0x9d, 0x72, 0xcc,
0x12, 0xe7, 0xc8, 0xe5, 0xaf, 0xc1, 0x12, 0xf6, 0xff, 0x8d, 0xa0, 0xdf, 0xf5, 0xdc, 0xf0, 0xc0,
0x04, 0x29, 0xeb, 0xaf, 0x13, 0x31, 0xb6, 0x2e, 0x0a, 0xb1, 0x75, 0x29, 0xa5, 0x41, 0x8a, 0xbc,
0x1c, 0x77, 0x1b, 0xb1, 0x75, 0x1c, 0xfb, 0x8e, 0x0c, 0x51, 0xc5, 0x14, 0x44, 0x0d, 0x2b, 0x09,
0x62, 0x58, 0x1c, 0x5e, 0x12, 0xd6, 0xe1, 0xa4, 0x96, 0x1e, 0x00, 0x5a, 0x9c, 0x19, 0x31, 0x06,
0x2b, 0x96, 0x4b, 0x21, 0x2d, 0xf9, 0x5f, 0xb0, 0x06, 0x6e, 0x85, 0x32, 0xf0, 0xa1, 0x36, 0x30,
0x9f, 0xba, 0x21, 0x52, 0xfb, 0x1a, 0x2c, 0x0d, 0xd9, 0x74, 0xa5, 0xff, 0x77, 0x63, 0x13, 0x07,
0x0e, 0x00, 0x2d, 0x54, 0xda, 0x50, 0x36, 0x2e, 0xef, 0xb6, 0xb8, 0x1d, 0x43, 0xaf, 0xef, 0x69,
0x80, 0x81, 0x7b, 0x3b, 0xd5, 0x88, 0x6f, 0xec, 0x32, 0xe4, 0x7b, 0xae, 0x00, 0x3e, 0xc1, 0xc7,
0xe4, 0x02, 0x24, 0x71, 0x81, 0xca, 0x67, 0xe0, 0x54, 0x2a, 0x4b, 0xd6, 0xba, 0xde, 0xf5, 0x38,
0xf9, 0x3e, 0x1e, 0x24, 0x2c, 0x43, 0xde, 0xc8, 0x6f, 0xe1, 0xdd, 0xa4, 0x0d, 0x3a, 0xb5, 0x2b,
0x7f, 0xc8, 0x00, 0x11, 0x65, 0x96, 0x7a, 0x49, 0x64, 0x9d, 0x37, 0xf4, 0x9c, 0x87, 0x79, 0xbd,
0xf6, 0x79, 0xbf, 0x9d, 0x11, 0xed, 0x36, 0xd1, 0x16, 0x1e, 0xde, 0x44, 0x4e, 0x5a, 0xa5, 0x16,
0xab, 0x64, 0xd3, 0x2a, 0x35, 0xa5, 0xa2, 0x42, 0xcb, 0x7d, 0x94, 0xd0, 0x4e, 0xc1, 0x54, 0x1a,
0x85, 0x34, 0xa1, 0xf2, 0xd6, 0x38, 0x4c, 0xc5, 0x0f, 0x0b, 0x64, 0x01, 0x4e, 0xf4, 0xfa, 0x8d,
0x5d, 0x7a, 0x20, 0x4b, 0x83, 0xfc, 0xe2, 0xb3, 0xe5, 0x6b, 0x7e, 0xb4, 0xe3, 0x85, 0xee, 0x6b,
0x6e, 0xc7, 0x69, 0x86, 0xd4, 0xa3, 0xdd, 0xc8, 0x77, 0x3b, 0x4c, 0x9e, 0xe3, 0xbc, 0xe6, 0x5e,
0xd7, 0x4c, 0x72, 0x0d, 0x4e, 0x89, 0x21, 0x06, 0x71, 0x96, 0x76, 0xfc, 0xb6, 0xdf, 0xf0, 0x3b,
0x7e, 0x74, 0x90, 0x40, 0xa5, 0x25, 0x2d, 0xb3, 0xa1, 0x45, 0x30, 0x43, 0xae, 0x40, 0xc9, 0xb4,
0x20, 0xb4, 0xc6, 0xb0, 0x74, 0x1a, 0x5a, 0x42, 0xf4, 0x34, 0x00, 0xbd, 0xe3, 0xcb, 0x47, 0x01,
0x81, 0x56, 0x63, 0xf6, 0x14, 0xa7, 0x20, 0xfb, 0x21, 0x20, 0xb1, 0x93, 0x8d, 0x8e, 0xc2, 0x45,
0x44, 0xae, 0xb2, 0xc9, 0x41, 0x71, 0x0b, 0x26, 0xe4, 0x0c, 0x25, 0x50, 0x6b, 0xd2, 0x56, 0x9f,
0xe4, 0x01, 0x28, 0xd3, 0x56, 0x8b, 0xe2, 0x70, 0x26, 0xe7, 0x2b, 0x81, 0x52, 0x63, 0x76, 0x29,
0x66, 0xc8, 0xc9, 0x8a, 0x54, 0xa1, 0x64, 0x6c, 0x1c, 0xae, 0x79, 0x57, 0x03, 0x42, 0x51, 0x33,
0x71, 0xd9, 0xcb, 0x30, 0xad, 0x46, 0xb7, 0x01, 0xf4, 0x28, 0x48, 0x0e, 0x4a, 0xbe, 0x02, 0x05,
0x7e, 0xd6, 0x7d, 0xe6, 0xb4, 0x3a, 0x6e, 0x9b, 0x21, 0x58, 0xcc, 0xd4, 0x1f, 0xba, 0xe7, 0xeb,
0x51, 0x75, 0x4b, 0xa8, 0x3d, 0xc5, 0xb5, 0xb0, 0x67, 0x61, 0x9a, 0x40, 0x9e, 0x86, 0xd3, 0xc3,
0x4f, 0x7a, 0x08, 0xa6, 0x9c, 0x1c, 0x7a, 0xea, 0x12, 0x17, 0x9e, 0x83, 0xbc, 0xb1, 0x10, 0x29,
0xc2, 0xc4, 0xe6, 0x0b, 0x9b, 0xdb, 0x9b, 0x6b, 0xcf, 0x95, 0xfe, 0x6b, 0x29, 0x3b, 0x99, 0x21,
0x0b, 0x30, 0x83, 0x84, 0xed, 0x8d, 0x1b, 0xce, 0xc6, 0xff, 0x6d, 0x6e, 0x97, 0x32, 0x82, 0x3e,
0x07, 0x85, 0x5b, 0x9b, 0xdb, 0x37, 0x6f, 0xd8, 0x6b, 0xb7, 0xd6, 0xd6, 0x9f, 0xdb, 0x28, 0x65,
0x39, 0xb5, 0xd2, 0x81, 0x45, 0x31, 0x81, 0xd8, 0xd4, 0x65, 0xfc, 0xf2, 0xee, 0x71, 0x54, 0xa0,
0xcd, 0x20, 0xf4, 0x78, 0xcb, 0xa4, 0x27, 0x2e, 0x9c, 0xcc, 0x10, 0x76, 0x66, 0x62, 0x32, 0x8e,
0x66, 0x71, 0xb9, 0xca, 0x9a, 0xe5, 0x4a, 0x41, 0x55, 0x4e, 0x43, 0x55, 0xe5, 0xcd, 0x0c, 0x4c,
0x69, 0x4c, 0x8f, 0x5b, 0xad, 0x8c, 0xd1, 0x6a, 0x91, 0xeb, 0xc6, 0x38, 0x92, 0x2c, 0x73, 0x6a,
0xa7, 0x30, 0x35, 0x4e, 0x0e, 0xad, 0x76, 0x12, 0x7e, 0x9f, 0x38, 0x14, 0x7e, 0x11, 0x03, 0x47,
0x22, 0xef, 0xeb, 0x39, 0xf5, 0x82, 0x29, 0x50, 0x7d, 0x54, 0xcf, 0x20, 0x51, 0x75, 0xb0, 0x67,
0x40, 0x86, 0xee, 0x19, 0x4e, 0x03, 0xe8, 0x17, 0x0a, 0xb9, 0xf8, 0x14, 0x53, 0x2f, 0x13, 0x1c,
0x84, 0x1a, 0x81, 0x77, 0x20, 0xd2, 0xef, 0x10, 0x10, 0x32, 0x3b, 0xe2, 0xc0, 0x3b, 0xb0, 0x85,
0x52, 0x12, 0x84, 0xc6, 0x53, 0x20, 0xc4, 0x73, 0xd3, 0xc0, 0x7e, 0x15, 0xfe, 0x5d, 0x6c, 0x17,
0x4a, 0xba, 0x06, 0xc8, 0x5d, 0x7b, 0x00, 0xca, 0xda, 0x51, 0x25, 0xfd, 0x01, 0x4a, 0x17, 0x63,
0x87, 0xa5, 0xf0, 0x05, 0x98, 0x96, 0x8f, 0x9e, 0x21, 0xdd, 0xa7, 0x6e, 0x47, 0x56, 0x55, 0xbb,
0x80, 0x54, 0x5b, 0x10, 0xc9, 0x2a, 0x4c, 0xe9, 0x17, 0x87, 0x0f, 0x27, 0x8e, 0xf8, 0xe2, 0x30,
0xa9, 0x5e, 0x08, 0x2a, 0x3f, 0x1c, 0x83, 0x62, 0x2a, 0x72, 0x72, 0x3e, 0xbd, 0x72, 0x66, 0xc8,
0xc2, 0x4f, 0x9a, 0x0b, 0x67, 0x8f, 0xbb, 0x2e, 0x79, 0x1a, 0x0a, 0x89, 0x51, 0x28, 0x27, 0x26,
0xa1, 0xf3, 0x47, 0xa8, 0x10, 0x76, 0x42, 0x91, 0xdc, 0x02, 0xd2, 0x0b, 0x83, 0x5e, 0xc0, 0x68,
0x88, 0x8f, 0x47, 0x7e, 0xb7, 0xcd, 0xac, 0x31, 0x61, 0xee, 0xf2, 0xc8, 0xc1, 0x4a, 0x6a, 0x6c,
0x49, 0x05, 0xbb, 0xdc, 0x4b, 0x51, 0x84, 0x61, 0x5c, 0x28, 0x61, 0x78, 0xfc, 0x70, 0xc3, 0x6b,
0x52, 0x43, 0x1b, 0x76, 0x53, 0x14, 0x5e, 0x14, 0x27, 0xe5, 0xcb, 0x0b, 0xb3, 0x4e, 0x08, 0x73,
0xcb, 0xa3, 0xcc, 0xdd, 0x40, 0x39, 0x3b, 0x56, 0x20, 0x2f, 0x40, 0x71, 0x3f, 0xe8, 0xf4, 0xbb,
0x11, 0xef, 0x1b, 0x79, 0x91, 0x60, 0xd6, 0x84, 0xb0, 0x71, 0xff, 0x48, 0xfc, 0x54, 0xe2, 0x1b,
0x77, 0xfc, 0xc8, 0x9e, 0xd9, 0x37, 0x3f, 0xf9, 0xc0, 0x3d, 0x15, 0x85, 0x6e, 0x97, 0xb5, 0x68,
0xc8, 0xac, 0x49, 0x61, 0x69, 0xe4, 0x31, 0x6e, 0x4b, 0x41, 0x5b, 0xab, 0x54, 0xbe, 0x92, 0x81,
0xc2, 0x0d, 0xf5, 0x8e, 0xd4, 0xeb, 0x47, 0x23, 0x2b, 0x71, 0x15, 0x66, 0x7b, 0x61, 0x10, 0xb4,
0x9c, 0xa0, 0xe5, 0xf4, 0x02, 0xc6, 0x28, 0x8b, 0x87, 0xc4, 0x82, 0xd8, 0xfe, 0xa0, 0xf5, 0x62,
0xeb, 0xa5, 0x98, 0x41, 0xd6, 0xef, 0x85, 0xe7, 0x98, 0xe7, 0x87, 0x42, 0xf9, 0x6d, 0x20, 0x78,
0xd2, 0x6e, 0x87, 0x4f, 0x2d, 0xd4, 0x1b, 0x39, 0xa2, 0x0c, 0x87, 0x58, 0x3e, 0xb8, 0x0c, 0xf4,
0xa6, 0x72, 0x7a, 0x6a, 0x24, 0x1b, 0xd2, 0xca, 0x9f, 0x33, 0x30, 0x27, 0xce, 0x98, 0x97, 0x62,
0xb3, 0xd3, 0x7a, 0x00, 0xca, 0x09, 0x98, 0x37, 0xba, 0xac, 0x92, 0x09, 0xf4, 0xa2, 0x61, 0x1a,
0x36, 0xae, 0x65, 0x87, 0x8f, 0x6b, 0x1f, 0xab, 0xb7, 0x3a, 0xf6, 0xac, 0xf7, 0xd9, 0x2c, 0xe4,
0xe5, 0x39, 0x8b, 0x4d, 0xfc, 0x84, 0x1b, 0xae, 0x05, 0x38, 0xe1, 0xee, 0x05, 0xfd, 0xae, 0x2a,
0x67, 0xf2, 0xeb, 0xf0, 0x1e, 0x90, 0xbc, 0x60, 0xbe, 0x6c, 0xf6, 0xfa, 0x91, 0x1a, 0x82, 0x2e,
0xdc, 0x23, 0x9f, 0xc4, 0x4d, 0xc5, 0xd6, 0xc4, 0x33, 0xef, 0xee, 0x39, 0x98, 0x8a, 0xfc, 0x3d,
0xbe, 0x5d, 0x7b, 0x3d, 0xb3, 0x81, 0xd1, 0xd4, 0xca, 0x5f, 0x72, 0x50, 0x4a, 0xa3, 0x07, 0xb9,
0x1f, 0x66, 0x62, 0x0c, 0x32, 0x0b, 0xf9, 0xb4, 0xa2, 0x62, 0x1d, 0xbf, 0x01, 0x93, 0xf8, 0x3e,
0xed, 0xd4, 0x24, 0x62, 0x1e, 0xe3, 0x81, 0x7a, 0x02, 0x55, 0x6b, 0x86, 0x95, 0xba, 0x3c, 0xfb,
0xe3, 0x5b, 0xa9, 0x93, 0x5b, 0x50, 0xec, 0xc9, 0xd4, 0xc0, 0xfa, 0x5d, 0x53, 0x9b, 0x77, 0xf5,
0x70, 0xd0, 0x34, 0x53, 0x09, 0x5f, 0x00, 0x95, 0x1d, 0x4e, 0xa9, 0x91, 0x47, 0x61, 0x2e, 0x36,
0x1c, 0x9f, 0x94, 0x53, 0x93, 0x65, 0x0e, 0xdf, 0xaf, 0x7a, 0x86, 0x25, 0xc1, 0xaf, 0x0d, 0xfa,
0x23, 0xa7, 0xc8, 0x8f, 0xe9, 0x4f, 0x7d, 0x84, 0x3f, 0x89, 0x76, 0x70, 0xd0, 0x9f, 0x7a, 0xe5,
0x8d, 0x1c, 0x94, 0xd2, 0x60, 0x4e, 0x5e, 0x84, 0x69, 0xa3, 0xf6, 0x38, 0x35, 0x39, 0xb2, 0x8d,
0xf4, 0x70, 0x70, 0xee, 0x4a, 0x14, 0xaf, 0x5a, 0xda, 0x60, 0x5d, 0x5e, 0x8b, 0x8f, 0x6a, 0xb0,
0x4e, 0x7c, 0x58, 0x64, 0x0a, 0x84, 0x9c, 0xa4, 0xaf, 0xf2, 0x78, 0x1f, 0x1c, 0x65, 0x7b, 0x18,
0x78, 0xe1, 0x04, 0xce, 0x86, 0x70, 0x6a, 0xa3, 0x97, 0xaa, 0xab, 0x9f, 0x99, 0x3f, 0xa1, 0xa5,
0xea, 0x95, 0x7f, 0x67, 0x60, 0x42, 0xa6, 0x2e, 0x47, 0x6a, 0x51, 0x2c, 0x04, 0x84, 0x16, 0x6c,
0xfc, 0xe0, 0x54, 0x4c, 0x3c, 0x89, 0xdf, 0xe2, 0x83, 0x3c, 0x9e, 0x80, 0xc8, 0xf3, 0xf7, 0x40,
0x05, 0x03, 0x1e, 0x1f, 0x85, 0xb9, 0x3d, 0x1a, 0xee, 0x76, 0xa8, 0x83, 0x35, 0x4b, 0x3d, 0x20,
0xdf, 0x9d, 0x88, 0x1f, 0x90, 0x09, 0x0a, 0xbc, 0xc4, 0xf9, 0xea, 0xed, 0x78, 0x05, 0xca, 0x52,
0x2d, 0x0a, 0xa9, 0xfc, 0x01, 0xcc, 0xc4, 0x91, 0x22, 0x72, 0xb7, 0x43, 0x8a, 0x3f, 0x7e, 0x91,
0x8b, 0xa0, 0x00, 0x08, 0xfb, 0x28, 0xe3, 0xe1, 0x24, 0xef, 0x69, 0xaf, 0x2a, 0x1d, 0x98, 0x4e,
0x94, 0xf1, 0x11, 0xad, 0xfd, 0x90, 0x89, 0x22, 0x3b, 0x74, 0xa2, 0x48, 0xc0, 0x6a, 0x2e, 0x3d,
0x5a, 0x7f, 0x27, 0x03, 0x93, 0xaa, 0xd6, 0x73, 0x64, 0x66, 0xb4, 0xeb, 0xd1, 0x50, 0x2e, 0x25,
0xbf, 0xb8, 0x89, 0x90, 0x36, 0xfd, 0x9e, 0x4f, 0xbb, 0x91, 0x5c, 0x45, 0x13, 0x46, 0xe2, 0x79,
0x09, 0x72, 0x2d, 0x4a, 0xe5, 0x24, 0xcc, 0xff, 0x8c, 0xab, 0xf1, 0xb8, 0x51, 0x8d, 0x75, 0x71,
0x39, 0x91, 0x28, 0x2e, 0x09, 0xb7, 0x27, 0xd2, 0x6e, 0xbf, 0x93, 0x81, 0xc9, 0xf8, 0x37, 0xb4,
0x73, 0x7a, 0x67, 0xc5, 0x54, 0x80, 0x55, 0x4a, 0x6d, 0xaa, 0x98, 0x0b, 0xce, 0xeb, 0xea, 0xd1,
0x14, 0xae, 0x66, 0x13, 0x3f, 0x8b, 0x5d, 0x17, 0x0e, 0x27, 0x1f, 0x7f, 0x72, 0xe9, 0xc7, 0x9f,
0x47, 0x60, 0xd6, 0x5c, 0x66, 0xc8, 0x23, 0x5e, 0xd9, 0x58, 0x52, 0x76, 0xf6, 0x17, 0xa1, 0x20,
0x7f, 0xad, 0x34, 0xe7, 0x05, 0x3c, 0x75, 0xc1, 0x90, 0x2d, 0x45, 0x07, 0x0a, 0xe6, 0xef, 0x7a,
0xc9, 0x96, 0x3b, 0x73, 0xec, 0x96, 0xfb, 0x34, 0xc0, 0x7e, 0x10, 0xd1, 0x44, 0xb0, 0x53, 0x9c,
0x22, 0x22, 0xad, 0x6c, 0x41, 0xf1, 0x66, 0xfc, 0xab, 0xe6, 0xba, 0x1b, 0xe1, 0x4b, 0xab, 0xf9,
0x4b, 0x31, 0x66, 0x1c, 0x34, 0xf4, 0x4f, 0xc4, 0xcb, 0x90, 0x37, 0x7f, 0x1b, 0xce, 0xa2, 0x40,
0x3c, 0xc9, 0xb0, 0xca, 0x0f, 0x32, 0x50, 0x1e, 0xa8, 0x42, 0x43, 0x3b, 0xb0, 0xaa, 0xf1, 0x8b,
0xf7, 0xc0, 0xc8, 0x57, 0x56, 0xac, 0x23, 0x0f, 0x7d, 0x17, 0x01, 0x3b, 0x34, 0x87, 0x4f, 0x71,
0xe6, 0x43, 0xf1, 0x74, 0x23, 0x9e, 0xf0, 0xb8, 0xdc, 0xa1, 0xf3, 0xdd, 0x7a, 0xe1, 0xed, 0xf7,
0xcf, 0x64, 0xde, 0x7d, 0xff, 0x4c, 0xe6, 0xbd, 0xf7, 0xcf, 0x64, 0x1a, 0x27, 0xc4, 0x3f, 0xe0,
0x3c, 0xf2, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x41, 0x47, 0xc2, 0x10, 0xd8, 0x23, 0x00, 0x00,
}
func (m *BeaconState) Marshal() (dAtA []byte, err error) {
@@ -3346,15 +3346,17 @@ func (m *AttestationData) MarshalTo(dAtA []byte) (int, error) {
i++
i = encodeVarintTypes(dAtA, i, uint64(m.SourceEpoch))
}
if m.SourceRoot != 0 {
dAtA[i] = 0x20
if len(m.SourceRoot) > 0 {
dAtA[i] = 0x22
i++
i = encodeVarintTypes(dAtA, i, uint64(m.SourceRoot))
i = encodeVarintTypes(dAtA, i, uint64(len(m.SourceRoot)))
i += copy(dAtA[i:], m.SourceRoot)
}
if m.TargetRoot != 0 {
dAtA[i] = 0x28
if len(m.TargetRoot) > 0 {
dAtA[i] = 0x2a
i++
i = encodeVarintTypes(dAtA, i, uint64(m.TargetRoot))
i = encodeVarintTypes(dAtA, i, uint64(len(m.TargetRoot)))
i += copy(dAtA[i:], m.TargetRoot)
}
if m.Shard != 0 {
dAtA[i] = 0x30
@@ -4946,11 +4948,13 @@ func (m *AttestationData) Size() (n int) {
if m.SourceEpoch != 0 {
n += 1 + sovTypes(uint64(m.SourceEpoch))
}
if m.SourceRoot != 0 {
n += 1 + sovTypes(uint64(m.SourceRoot))
l = len(m.SourceRoot)
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
if m.TargetRoot != 0 {
n += 1 + sovTypes(uint64(m.TargetRoot))
l = len(m.TargetRoot)
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
if m.Shard != 0 {
n += 1 + sovTypes(uint64(m.Shard))
@@ -7587,10 +7591,10 @@ func (m *AttestationData) Unmarshal(dAtA []byte) error {
}
}
case 4:
if wireType != 0 {
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field SourceRoot", wireType)
}
m.SourceRoot = 0
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
@@ -7600,16 +7604,31 @@ func (m *AttestationData) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.SourceRoot |= uint64(b&0x7F) << shift
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthTypes
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthTypes
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.SourceRoot = append(m.SourceRoot[:0], dAtA[iNdEx:postIndex]...)
if m.SourceRoot == nil {
m.SourceRoot = []byte{}
}
iNdEx = postIndex
case 5:
if wireType != 0 {
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field TargetRoot", wireType)
}
m.TargetRoot = 0
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
@@ -7619,11 +7638,26 @@ func (m *AttestationData) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.TargetRoot |= uint64(b&0x7F) << shift
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthTypes
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthTypes
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.TargetRoot = append(m.TargetRoot[:0], dAtA[iNdEx:postIndex]...)
if m.TargetRoot == nil {
m.TargetRoot = []byte{}
}
iNdEx = postIndex
case 6:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Shard", wireType)

View File

@@ -90,8 +90,8 @@ message AttestationData {
// FFG vote
uint64 source_epoch = 3;
uint64 source_root = 4;
uint64 target_root = 5;
bytes source_root = 4;
bytes target_root = 5;
// Crosslink vote
uint64 shard = 6;

View File

@@ -5,10 +5,9 @@ package ethereum_sharding_p2p_v1
import (
fmt "fmt"
proto "github.com/gogo/protobuf/proto"
io "io"
math "math"
proto "github.com/gogo/protobuf/proto"
)
// Reference imports to suppress errors if they are not otherwise used.