Fix State Generator (#2010)

This commit is contained in:
Nishant Das
2019-03-19 10:15:50 +08:00
committed by terence tsao
parent 7a83acf46d
commit f801bfedcf
14 changed files with 539 additions and 217 deletions

View File

@@ -162,6 +162,9 @@ func (c *ChainService) runStateTransition(
}
func (c *ChainService) saveFinalizedState(beaconState *pb.BeaconState) error {
if err := c.beaconDB.SaveHistoricalState(beaconState); err != nil {
return err
}
// check if the finalized epoch has changed, if it
// has we save the finalized state.
if c.finalizedEpoch != beaconState.FinalizedEpoch {

View File

@@ -9,7 +9,9 @@ go_library(
"//beacon-chain/core/state:go_default_library",
"//beacon-chain/db:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/hashutil:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
],
)
@@ -20,7 +22,6 @@ go_test(
deps = [
"//beacon-chain/chaintest/backend:go_default_library",
"//beacon-chain/db:go_default_library",
"//shared/params:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
],
)

View File

@@ -7,40 +7,52 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/hashutil"
"github.com/sirupsen/logrus"
)
// GenerateStateFromSlot generates state from the last finalized epoch till the specified slot.
func GenerateStateFromSlot(ctx context.Context, db *db.BeaconDB, slot uint64) (*pb.BeaconState, error) {
fState, err := db.FinalizedState()
var log = logrus.WithField("prefix", "stategenerator")
// GenerateStateFromBlock generates state from the historical state at the
// given block's slot.
func GenerateStateFromBlock(ctx context.Context, db *db.BeaconDB, block *pb.BeaconBlock) (*pb.BeaconState, error) {
hState, err := db.HistoricalStateFromSlot(block.Slot)
if err != nil {
return nil, err
}
if fState.Slot > slot {
if hState.Slot > block.Slot {
return nil, fmt.Errorf(
"requested slot %d < current slot %d in the finalized beacon state",
fState.Slot,
slot,
"requested slot %d < current slot %d in the historical beacon state",
hState.Slot,
block,
)
}
pBlock, err := db.BlockBySlot(fState.Slot)
root, err := hashutil.HashBeaconBlock(hState.LatestBlock)
if err != nil {
return nil, fmt.Errorf("could not retrieve block: %v", err)
}
root, err := hashutil.HashBeaconBlock(pBlock)
if err != nil {
return nil, fmt.Errorf("could not tree hash parent block: %v", err)
return nil, fmt.Errorf("unable to get block root %v", err)
}
// run N state transitions to generate state
for i := fState.Slot + 1; i <= slot; i++ {
exists, blk, err := db.HasBlockBySlot(i)
if !exists {
fState, err = state.ExecuteStateTransition(
ancestorSet, err := ancestersToLastFinalizedBlock(db, block, root)
if err != nil {
return nil, fmt.Errorf("unable to look up block ancestors %v", err)
}
log.Debugf("Start: Current slot %d and Finalized Epoch %d", hState.Slot, hState.FinalizedEpoch)
for i := len(ancestorSet); i > 0; i-- {
block := ancestorSet[i-1]
if block.Slot <= hState.Slot {
continue
}
// Running state transitions for skipped slots.
for block.Slot != hState.Slot+1 {
hState, err = state.ExecuteStateTransition(
ctx,
fState,
hState,
nil,
root,
&state.TransitionConfig{
@@ -51,13 +63,12 @@ func GenerateStateFromSlot(ctx context.Context, db *db.BeaconDB, slot uint64) (*
if err != nil {
return nil, fmt.Errorf("could not execute state transition %v", err)
}
continue
}
fState, err = state.ExecuteStateTransition(
hState, err = state.ExecuteStateTransition(
ctx,
fState,
blk,
hState,
block,
root,
&state.TransitionConfig{
VerifySignatures: true,
@@ -68,11 +79,36 @@ func GenerateStateFromSlot(ctx context.Context, db *db.BeaconDB, slot uint64) (*
return nil, fmt.Errorf("could not execute state transition %v", err)
}
root, err = hashutil.HashBeaconBlock(blk)
root, err = hashutil.HashBeaconBlock(block)
if err != nil {
return nil, fmt.Errorf("could not tree hash parent block: %v", err)
return nil, fmt.Errorf("unable to get block root %v", err)
}
}
return fState, nil
log.Debugf("End: Current slot %d and Finalized Epoch %d", hState.Slot, hState.FinalizedEpoch)
return hState, nil
}
// ancestersToLastFinalizedBlock will return a list of all block ancesters
// between the given block and the most recent finalized block in the db.
// The given block is also returned in the list of ancesters.
func ancestersToLastFinalizedBlock(db *db.BeaconDB, block *pb.BeaconBlock,
finalizedBlockRoot [32]byte) ([]*pb.BeaconBlock, error) {
blockAncestors := make([]*pb.BeaconBlock, 0)
blockAncestors = append(blockAncestors, block)
parentRoot := bytesutil.ToBytes32(block.ParentRootHash32)
// looking up ancestors, till it gets the last finalized block.
for parentRoot != finalizedBlockRoot {
retblock, err := db.Block(parentRoot)
if err != nil {
return nil, err
}
blockAncestors = append(blockAncestors, retblock)
parentRoot = bytesutil.ToBytes32(retblock.ParentRootHash32)
}
return blockAncestors, nil
}

View File

@@ -1,13 +1,13 @@
package stategenerator
package stategenerator_test
import (
"context"
"testing"
"github.com/gogo/protobuf/proto"
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain/stategenerator"
"github.com/prysmaticlabs/prysm/beacon-chain/chaintest/backend"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/shared/params"
)
func TestGenerateState_OK(t *testing.T) {
@@ -23,7 +23,6 @@ func TestGenerateState_OK(t *testing.T) {
defer bd.Shutdown()
defer db.TeardownDB(beaconDb)
genesisSlot := params.BeaconConfig().GenesisSlot
slotLimit := uint64(30)
// Run the simulated chain for 30 slots, to get a state that we can save as finalized.
@@ -31,6 +30,13 @@ func TestGenerateState_OK(t *testing.T) {
if err := bd.GenerateBlockAndAdvanceChain(&backend.SimulatedObjects{}, privKeys); err != nil {
t.Fatalf("Could not generate block and transition state successfully %v for slot %d", err, bd.State().Slot+1)
}
inMemBlocks := bd.InMemoryBlocks()
if err := beaconDb.SaveBlock(inMemBlocks[len(inMemBlocks)-1]); err != nil {
t.Fatalf("Unable to save block %v", err)
}
if err := beaconDb.UpdateChainHead(inMemBlocks[len(inMemBlocks)-1], bd.State()); err != nil {
t.Fatalf("Unable to save block %v", err)
}
}
if err := beaconDb.SaveFinalizedState(bd.State()); err != nil {
@@ -42,24 +48,18 @@ func TestGenerateState_OK(t *testing.T) {
if err := bd.GenerateBlockAndAdvanceChain(&backend.SimulatedObjects{}, privKeys); err != nil {
t.Fatalf("Could not generate block and transition state successfully %v for slot %d", err, bd.State().Slot+1)
}
}
// Save all in memory blocks
for _, v := range bd.InMemoryBlocks() {
if err := beaconDb.SaveBlock(v); err != nil {
inMemBlocks := bd.InMemoryBlocks()
if err := beaconDb.SaveBlock(inMemBlocks[len(inMemBlocks)-1]); err != nil {
t.Fatalf("Unable to save block %v", err)
}
if err := beaconDb.UpdateChainHead(v, bd.State()); err != nil {
if err := beaconDb.UpdateChainHead(inMemBlocks[len(inMemBlocks)-1], bd.State()); err != nil {
t.Fatalf("Unable to save block %v", err)
}
}
if err := beaconDb.SaveState(bd.State()); err != nil {
t.Fatalf("Unable to save state in chain %v", err)
}
slotToGenerate := genesisSlot + 2*(slotLimit)
newState, err := GenerateStateFromSlot(context.Background(), beaconDb, slotToGenerate)
inMemBlocks := bd.InMemoryBlocks()
blockToGenerateTill := inMemBlocks[len(inMemBlocks)-1]
newState, err := stategenerator.GenerateStateFromBlock(context.Background(), beaconDb, blockToGenerateTill)
if err != nil {
t.Fatalf("Unable to generate new state from previous finalized state %v", err)
}
@@ -87,7 +87,6 @@ func TestGenerateState_WithNilBlocksOK(t *testing.T) {
defer bd.Shutdown()
defer db.TeardownDB(beaconDb)
genesisSlot := params.BeaconConfig().GenesisSlot
slotLimit := uint64(30)
// Run the simulated chain for 30 slots, to get a state that we can save as finalized.
@@ -95,6 +94,13 @@ func TestGenerateState_WithNilBlocksOK(t *testing.T) {
if err := bd.GenerateBlockAndAdvanceChain(&backend.SimulatedObjects{}, privKeys); err != nil {
t.Fatalf("Could not generate block and transition state successfully %v for slot %d", err, bd.State().Slot+1)
}
inMemBlocks := bd.InMemoryBlocks()
if err := beaconDb.SaveBlock(inMemBlocks[len(inMemBlocks)-1]); err != nil {
t.Fatalf("Unable to save block %v", err)
}
if err := beaconDb.UpdateChainHead(inMemBlocks[len(inMemBlocks)-1], bd.State()); err != nil {
t.Fatalf("Unable to save block %v", err)
}
}
if err := beaconDb.SaveFinalizedState(bd.State()); err != nil {
@@ -114,24 +120,18 @@ func TestGenerateState_WithNilBlocksOK(t *testing.T) {
if err := bd.GenerateBlockAndAdvanceChain(&backend.SimulatedObjects{}, privKeys); err != nil {
t.Fatalf("Could not generate block and transition state successfully %v for slot %d", err, bd.State().Slot+1)
}
}
// Save all in memory blocks.
for _, v := range bd.InMemoryBlocks() {
if err := beaconDb.SaveBlock(v); err != nil {
inMemBlocks := bd.InMemoryBlocks()
if err := beaconDb.SaveBlock(inMemBlocks[len(inMemBlocks)-1]); err != nil {
t.Fatalf("Unable to save block %v", err)
}
if err := beaconDb.UpdateChainHead(v, bd.State()); err != nil {
if err := beaconDb.UpdateChainHead(inMemBlocks[len(inMemBlocks)-1], bd.State()); err != nil {
t.Fatalf("Unable to save block %v", err)
}
}
if err := beaconDb.SaveState(bd.State()); err != nil {
t.Fatalf("Unable to save state in chain %v", err)
}
slotToGenerate := genesisSlot + 2*(slotLimit)
newState, err := GenerateStateFromSlot(context.Background(), beaconDb, slotToGenerate)
inMemBlocks := bd.InMemoryBlocks()
blockToGenerateTill := inMemBlocks[len(inMemBlocks)-1]
newState, err := stategenerator.GenerateStateFromBlock(context.Background(), beaconDb, blockToGenerateTill)
if err != nil {
t.Fatalf("Unable to generate new state from previous finalized state %v", err)
}

View File

@@ -133,6 +133,9 @@ func ProcessBlock(
}
}
// Save latest block.
state.LatestBlock = block
// Verify block RANDAO.
state, err = b.ProcessBlockRandao(ctx, state, block, config.VerifySignatures, config.Logging)
if err != nil {

View File

@@ -24,6 +24,8 @@ go_library(
"//proto/beacon/p2p/v1:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/mathutil:go_default_library",
"//shared/params:go_default_library",
"@com_github_boltdb_bolt//:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",

View File

@@ -73,7 +73,7 @@ func NewDB(dirPath string) (*BeaconDB, error) {
db := &BeaconDB{db: boltDB, DatabasePath: dirPath}
if err := db.update(func(tx *bolt.Tx) error {
return createBuckets(tx, blockBucket, attestationBucket, mainChainBucket,
return createBuckets(tx, blockBucket, attestationBucket, mainChainBucket, histStateBucket,
chainInfoBucket, cleanupHistoryBucket, blockOperationsBucket, validatorBucket)
}); err != nil {

View File

@@ -19,6 +19,7 @@ var (
blockOperationsBucket = []byte("block-operations-bucket")
blockBucket = []byte("block-bucket")
mainChainBucket = []byte("main-chain-bucket")
histStateBucket = []byte("historical-state-bucket")
chainInfoBucket = []byte("chain-info")
validatorBucket = []byte("validator")

View File

@@ -13,6 +13,8 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/hashutil"
"github.com/prysmaticlabs/prysm/shared/mathutil"
"github.com/prysmaticlabs/prysm/shared/params"
"go.opencensus.io/trace"
)
@@ -155,6 +157,10 @@ func (db *BeaconDB) SaveJustifiedState(beaconState *pb.BeaconState) error {
// SaveFinalizedState saves the last finalized state in the db.
func (db *BeaconDB) SaveFinalizedState(beaconState *pb.BeaconState) error {
// Delete historical states if we are saving a new finalized state.
if err := db.deleteHistoricalStates(); err != nil {
return err
}
return db.update(func(tx *bolt.Tx) error {
chainInfo := tx.Bucket(chainInfoBucket)
beaconStateEnc, err := proto.Marshal(beaconState)
@@ -165,6 +171,37 @@ func (db *BeaconDB) SaveFinalizedState(beaconState *pb.BeaconState) error {
})
}
// SaveHistoricalState saves the last finalized state in the db.
func (db *BeaconDB) SaveHistoricalState(beaconState *pb.BeaconState) error {
finalizedSlot := beaconState.FinalizedEpoch * params.BeaconConfig().SlotsPerEpoch
slotDiff := beaconState.Slot - finalizedSlot
// Do not save state, if slot diff is not
// a power of 2.
if !mathutil.IsPowerOf2(slotDiff) {
return nil
}
slotBinary := encodeSlotNumber(slotDiff)
stateHash, err := hashutil.HashProto(beaconState)
if err != nil {
return err
}
return db.update(func(tx *bolt.Tx) error {
histState := tx.Bucket(histStateBucket)
chainInfo := tx.Bucket(chainInfoBucket)
if err := histState.Put(slotBinary, stateHash[:]); err != nil {
return err
}
beaconStateEnc, err := proto.Marshal(beaconState)
if err != nil {
return err
}
return chainInfo.Put(stateHash[:], beaconStateEnc)
})
}
// SaveCurrentAndFinalizedState saves the state as both the current and last finalized state.
func (db *BeaconDB) SaveCurrentAndFinalizedState(beaconState *pb.BeaconState) error {
// Clone to prevent mutations of the cached copy
@@ -178,12 +215,21 @@ func (db *BeaconDB) SaveCurrentAndFinalizedState(beaconState *pb.BeaconState) er
}
db.currentState = currentState
// Delete historical states if we are saving a new finalized state.
if err := db.deleteHistoricalStates(); err != nil {
return err
}
return db.update(func(tx *bolt.Tx) error {
chainInfo := tx.Bucket(chainInfoBucket)
beaconStateEnc, err := proto.Marshal(beaconState)
if err != nil {
return err
}
// Putting in historical state.
if err := chainInfo.Put(stateLookupKey, beaconStateEnc); err != nil {
return err
}
return chainInfo.Put(finalizedStateLookupKey, beaconStateEnc)
})
@@ -223,6 +269,55 @@ func (db *BeaconDB) FinalizedState() (*pb.BeaconState, error) {
return beaconState, err
}
// HistoricalStateFromSlot retrieves the closest historical state to a slot.
func (db *BeaconDB) HistoricalStateFromSlot(slot uint64) (*pb.BeaconState, error) {
state, err := db.FinalizedState()
if err != nil {
return nil, fmt.Errorf("unable to retrieve finalized state %v", err)
}
finalizedSlot := state.FinalizedEpoch * params.BeaconConfig().SlotsPerEpoch
slotDiff := slot - finalizedSlot
closestSlot := mathutil.ClosestPowerOf2(slotDiff)
var beaconState *pb.BeaconState
err = db.view(func(tx *bolt.Tx) error {
var err error
var highestStateSlot uint64
histStateKey := make([]byte, 32)
chainInfo := tx.Bucket(chainInfoBucket)
histState := tx.Bucket(histStateBucket)
hsCursor := histState.Cursor()
for k, v := hsCursor.First(); k != nil; k, v = hsCursor.Next() {
slotNumber := decodeToSlotNumber(k)
if slotNumber > highestStateSlot && closestSlot >= slotNumber {
highestStateSlot = slotNumber
histStateKey = v
}
}
// If no state exists send the finalized state to be unencoded.
if highestStateSlot == 0 {
encState := chainInfo.Get(finalizedStateLookupKey)
if encState == nil {
return errors.New("no finalized state saved")
}
beaconState, err = createState(encState)
return err
}
// retrieve the stored historical state.
encState := chainInfo.Get(histStateKey)
if encState == nil {
return errors.New("no historical state saved")
}
beaconState, err = createState(encState)
return err
})
return beaconState, err
}
func createState(enc []byte) (*pb.BeaconState, error) {
protoState := &pb.BeaconState{}
err := proto.Unmarshal(enc, protoState)
@@ -244,3 +339,21 @@ func (db *BeaconDB) GenesisTime(ctx context.Context) (time.Time, error) {
genesisTime := time.Unix(int64(state.GenesisTime), int64(0))
return genesisTime, nil
}
func (db *BeaconDB) deleteHistoricalStates() error {
return db.update(func(tx *bolt.Tx) error {
histState := tx.Bucket(histStateBucket)
chainInfo := tx.Bucket(chainInfoBucket)
hsCursor := histState.Cursor()
for k, v := hsCursor.First(); k != nil; k, v = hsCursor.Next() {
if err := histState.Delete(k); err != nil {
return err
}
if err := chainInfo.Delete(v); err != nil {
return err
}
}
return nil
})
}

View File

@@ -281,3 +281,61 @@ func TestFinalizedState_CanSaveRetrieve(t *testing.T) {
stateSlot, finalizedState.Slot)
}
}
func TestHistoricalState_CanSaveRetrieve(t *testing.T) {
db := setupDB(t)
defer teardownDB(t, db)
tests := []struct {
state *pb.BeaconState
}{
{
state: &pb.BeaconState{
Slot: 66,
FinalizedEpoch: 1,
},
},
{
state: &pb.BeaconState{
Slot: 72,
FinalizedEpoch: 1,
},
},
{
state: &pb.BeaconState{
Slot: 96,
FinalizedEpoch: 1,
},
},
{
state: &pb.BeaconState{
Slot: 130,
FinalizedEpoch: 2,
},
},
{
state: &pb.BeaconState{
Slot: 300,
FinalizedEpoch: 4,
},
},
}
for _, tt := range tests {
if err := db.SaveFinalizedState(tt.state); err != nil {
t.Fatalf("could not save finalized state: %v", err)
}
if err := db.SaveHistoricalState(tt.state); err != nil {
t.Fatalf("could not save historical state: %v", err)
}
retState, err := db.HistoricalStateFromSlot(tt.state.Slot)
if err != nil {
t.Fatalf("Unable to retrieve state %v", err)
}
if !proto.Equal(tt.state, retState) {
t.Errorf("Saved and retrieved states are not equal got\n %v but wanted\n %v", proto.MarshalTextString(retState), proto.MarshalTextString(tt.state))
}
}
}

View File

@@ -72,6 +72,7 @@ type BeaconState struct {
LatestSlashedBalances []uint64 `protobuf:"varint,3005,rep,packed,name=latest_slashed_balances,json=latestSlashedBalances,proto3" json:"latest_slashed_balances,omitempty"`
LatestAttestations []*PendingAttestation `protobuf:"bytes,3006,rep,name=latest_attestations,json=latestAttestations,proto3" json:"latest_attestations,omitempty"`
LatestIndexRootHash32S [][]byte `protobuf:"bytes,3007,rep,name=latest_index_root_hash32s,json=latestIndexRootHash32s,proto3" json:"latest_index_root_hash32s,omitempty"`
LatestBlock *BeaconBlock `protobuf:"bytes,3008,opt,name=latest_block,json=latestBlock,proto3" json:"latest_block,omitempty"`
LatestEth1Data *Eth1Data `protobuf:"bytes,4001,opt,name=latest_eth1_data,json=latestEth1Data,proto3" json:"latest_eth1_data,omitempty"`
Eth1DataVotes []*Eth1DataVote `protobuf:"bytes,4002,rep,name=eth1_data_votes,json=eth1DataVotes,proto3" json:"eth1_data_votes,omitempty"`
GenesisTime uint64 `protobuf:"varint,5001,opt,name=genesis_time,json=genesisTime,proto3" json:"genesis_time,omitempty"`
@@ -255,6 +256,13 @@ func (m *BeaconState) GetLatestIndexRootHash32S() [][]byte {
return nil
}
func (m *BeaconState) GetLatestBlock() *BeaconBlock {
if m != nil {
return m.LatestBlock
}
return nil
}
func (m *BeaconState) GetLatestEth1Data() *Eth1Data {
if m != nil {
return m.LatestEth1Data
@@ -1698,129 +1706,130 @@ func init() {
func init() { proto.RegisterFile("proto/beacon/p2p/v1/types.proto", fileDescriptor_e719e7d82cfa7b0d) }
var fileDescriptor_e719e7d82cfa7b0d = []byte{
// 1939 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x58, 0xcb, 0x6f, 0x23, 0x49,
0x19, 0xa7, 0xed, 0x3c, 0x3f, 0x3b, 0xb1, 0x53, 0x99, 0xc4, 0xcd, 0xbc, 0x92, 0xe9, 0xd9, 0xd5,
0x64, 0x86, 0x5d, 0x07, 0x7b, 0x25, 0x46, 0x30, 0xac, 0x44, 0x3c, 0xc9, 0xb2, 0x81, 0xd9, 0xdd,
0x51, 0x3b, 0xcc, 0x70, 0x00, 0x5a, 0x65, 0x77, 0xd9, 0xee, 0x49, 0xbb, 0xab, 0xd5, 0x55, 0xf6,
0x26, 0x88, 0x7f, 0x80, 0x87, 0xb8, 0x71, 0x80, 0x1b, 0x88, 0x7f, 0x82, 0xf7, 0x09, 0x89, 0x23,
0x2f, 0x21, 0x21, 0x21, 0x84, 0xe6, 0xcc, 0xfb, 0xca, 0x05, 0xd5, 0xa3, 0x1f, 0x7e, 0x74, 0x32,
0xc3, 0x72, 0xd9, 0x93, 0xd5, 0xdf, 0xf7, 0xfb, 0x7d, 0x55, 0xf5, 0xd5, 0xf7, 0x2a, 0xc3, 0x4e,
0x18, 0x51, 0x4e, 0xf7, 0x3b, 0x04, 0x77, 0x69, 0xb0, 0x1f, 0x36, 0xc3, 0xfd, 0x71, 0x63, 0x9f,
0x9f, 0x87, 0x84, 0xd5, 0xa5, 0x06, 0x6d, 0x13, 0x3e, 0x20, 0x11, 0x19, 0x0d, 0xeb, 0x0a, 0x53,
0x0f, 0x9b, 0x61, 0x7d, 0xdc, 0xb8, 0x7a, 0x4d, 0x11, 0xbb, 0x74, 0x38, 0xa4, 0xc1, 0xfe, 0x90,
0x30, 0x86, 0xfb, 0x31, 0xc9, 0xfa, 0x4f, 0x09, 0x4a, 0x2d, 0x09, 0x6f, 0x73, 0xcc, 0x09, 0x7a,
0x0c, 0x68, 0x8c, 0x7d, 0xcf, 0xc5, 0x9c, 0x46, 0x4e, 0x44, 0xfa, 0x1e, 0xe3, 0xd1, 0xb9, 0x69,
0xec, 0x16, 0xf7, 0x4a, 0xcd, 0x5b, 0xf5, 0xf9, 0x2b, 0xd4, 0x9f, 0xc4, 0x0c, 0x7b, 0x23, 0x21,
0xdb, 0x9a, 0x8b, 0x8e, 0x60, 0x67, 0xd6, 0xa2, 0x33, 0x0a, 0x5d, 0xcc, 0x89, 0x43, 0x42, 0xda,
0x1d, 0x98, 0x85, 0x5d, 0x63, 0x6f, 0xc1, 0xbe, 0x3e, 0xc3, 0xfd, 0x82, 0x04, 0x1d, 0x09, 0x0c,
0x7a, 0x3d, 0xbb, 0xb1, 0x0e, 0xf6, 0x71, 0xd0, 0x25, 0xcc, 0x2c, 0xee, 0x16, 0xf7, 0x16, 0x32,
0xab, 0xb6, 0xb4, 0x02, 0xed, 0xc3, 0xa6, 0x8f, 0x39, 0x61, 0xdc, 0x89, 0x70, 0xe0, 0x62, 0xea,
0x0c, 0xbd, 0x33, 0xc2, 0xcc, 0xbf, 0x2e, 0xef, 0x16, 0xf7, 0xca, 0xf6, 0x86, 0xd2, 0xd9, 0x52,
0xf5, 0x8e, 0xd0, 0xa0, 0x43, 0xb8, 0x19, 0x46, 0x64, 0xec, 0xd1, 0x11, 0x73, 0xd8, 0x60, 0xd4,
0xeb, 0xf9, 0x5e, 0xd0, 0x77, 0x18, 0xc7, 0x11, 0x77, 0xd8, 0x00, 0x47, 0xae, 0xf9, 0xb7, 0x65,
0xb9, 0xcd, 0x6b, 0x31, 0xac, 0x1d, 0xa3, 0xda, 0x02, 0xd4, 0x16, 0x18, 0xd4, 0x82, 0x1b, 0xdd,
0x51, 0x14, 0x91, 0x80, 0xe7, 0x18, 0xf9, 0xbb, 0x32, 0x72, 0x55, 0xa3, 0xe6, 0xd9, 0xf8, 0x24,
0x98, 0x73, 0x76, 0xa2, 0x3c, 0xf5, 0x0f, 0x45, 0xdf, 0x9e, 0xd9, 0x83, 0x72, 0xd2, 0x7d, 0xa8,
0xcd, 0x2e, 0xaf, 0x98, 0xff, 0x54, 0xcc, 0xad, 0xe9, 0x85, 0x15, 0x31, 0xe7, 0xf4, 0x84, 0xb8,
0xce, 0x00, 0xb3, 0xc1, 0x1b, 0x4d, 0xf3, 0x5f, 0x82, 0x5f, 0x9e, 0x77, 0x7a, 0x42, 0xdc, 0xb7,
0x25, 0x26, 0xe7, 0xf4, 0x19, 0x23, 0xff, 0x56, 0x46, 0x66, 0x4f, 0x9f, 0xda, 0xc8, 0x9e, 0xfe,
0xd9, 0x88, 0x71, 0xaf, 0xe7, 0x11, 0x57, 0x9f, 0xe1, 0x37, 0x95, 0xc9, 0xd3, 0x7f, 0x2e, 0xd6,
0xab, 0x43, 0xec, 0x41, 0x65, 0x9a, 0xf1, 0x5b, 0xc5, 0x58, 0x7f, 0x36, 0x89, 0xfc, 0x04, 0x6c,
0x6b, 0x49, 0x17, 0x73, 0x8f, 0x06, 0x4e, 0xc7, 0xe3, 0x3d, 0x8f, 0xf8, 0xae, 0xf9, 0x3b, 0x45,
0xd8, 0x9a, 0x50, 0xb7, 0xb4, 0x56, 0xac, 0xd0, 0xf3, 0x02, 0xec, 0x7b, 0x5f, 0x4d, 0x56, 0xf8,
0xbd, 0x5e, 0x21, 0x91, 0xab, 0x15, 0xde, 0x03, 0x1d, 0x63, 0x4e, 0x37, 0xa2, 0x8c, 0xf9, 0x5e,
0x70, 0xca, 0xcc, 0x1f, 0xd5, 0x2e, 0xce, 0xa3, 0x87, 0x31, 0xd4, 0xae, 0x2a, 0x72, 0x22, 0x60,
0xe8, 0x53, 0xf0, 0x51, 0x6d, 0xb0, 0xe3, 0xd3, 0xee, 0xa9, 0x13, 0x51, 0xca, 0xb5, 0x5b, 0x99,
0xf9, 0x93, 0x9a, 0x0c, 0xeb, 0x6d, 0x85, 0x68, 0x09, 0x80, 0x4d, 0x29, 0x57, 0x2e, 0x65, 0xe8,
0xd3, 0x70, 0xb5, 0x83, 0x79, 0x77, 0x40, 0xdc, 0x79, 0xe4, 0x9f, 0x2a, 0x72, 0x4d, 0x43, 0x66,
0xd8, 0xf7, 0xa1, 0xa6, 0x57, 0x66, 0x3e, 0x66, 0xd2, 0x48, 0x9c, 0x7e, 0x3f, 0xab, 0xc9, 0xfc,
0xdb, 0x52, 0xfa, 0xb6, 0x52, 0x27, 0x39, 0xf8, 0xa5, 0x24, 0x07, 0x31, 0x17, 0x3f, 0xd2, 0x97,
0xcc, 0xfc, 0xb9, 0xf2, 0xc2, 0xbd, 0x3c, 0x2f, 0x3c, 0x26, 0x81, 0xeb, 0x05, 0xfd, 0x83, 0x94,
0x63, 0x23, 0x65, 0x27, 0x23, 0xca, 0x3a, 0xc4, 0x0b, 0x5c, 0x72, 0x36, 0x79, 0xa6, 0x5f, 0x4c,
0x38, 0xe4, 0x58, 0x00, 0xb2, 0x47, 0xfa, 0x3c, 0x68, 0x07, 0x3b, 0x84, 0x0f, 0x1a, 0x8e, 0x8b,
0x39, 0x36, 0xbf, 0xbf, 0xb3, 0x6b, 0xec, 0x95, 0x9a, 0xbb, 0x79, 0xdb, 0x3a, 0xe2, 0x83, 0xc6,
0x21, 0xe6, 0xd8, 0x5e, 0x57, 0xd4, 0xf8, 0x1b, 0xbd, 0x03, 0x95, 0xc4, 0x8a, 0x33, 0xa6, 0x9c,
0x30, 0xf3, 0x07, 0x3b, 0xf2, 0x88, 0xaf, 0x5c, 0x66, 0xeb, 0x09, 0xe5, 0xc4, 0x5e, 0x23, 0x99,
0x2f, 0x86, 0x2c, 0x28, 0xf7, 0x49, 0x40, 0x98, 0xc7, 0x1c, 0xee, 0x0d, 0x89, 0xf9, 0xf5, 0x3b,
0x32, 0xc0, 0x4a, 0x5a, 0x78, 0xe2, 0x0d, 0x09, 0x6a, 0xc0, 0x42, 0x8f, 0x46, 0xa7, 0xe6, 0x37,
0xee, 0xc8, 0x3d, 0x5f, 0xcf, 0x5b, 0xe7, 0x2d, 0x1a, 0x9d, 0xda, 0x12, 0x8a, 0x36, 0x61, 0x81,
0xf9, 0x94, 0x9b, 0xdf, 0x54, 0xe6, 0xe4, 0x87, 0x15, 0xc2, 0x82, 0x80, 0xa0, 0xbb, 0x50, 0x4d,
0x92, 0x6e, 0x4c, 0x22, 0xe6, 0xd1, 0xc0, 0x34, 0x24, 0xae, 0x12, 0xcb, 0x9f, 0x28, 0x31, 0xba,
0x03, 0x95, 0x38, 0xc7, 0x63, 0xa4, 0x2a, 0xdf, 0xeb, 0x5a, 0x1c, 0x03, 0xaf, 0xc0, 0xa2, 0xca,
0x90, 0xa2, 0x54, 0xab, 0x0f, 0xeb, 0x0f, 0x06, 0xa0, 0xd9, 0x0b, 0x46, 0x0f, 0x60, 0x41, 0x5e,
0x82, 0x21, 0xcf, 0x73, 0x27, 0xef, 0x3c, 0x19, 0x8a, 0xbc, 0x0a, 0x49, 0x42, 0x0d, 0xb8, 0x82,
0xfb, 0xfd, 0x88, 0xf4, 0xa7, 0x72, 0xb9, 0x20, 0x8b, 0xcd, 0x66, 0x46, 0x97, 0x24, 0xf2, 0x5d,
0xa8, 0x76, 0x47, 0x8c, 0x53, 0xf7, 0x3c, 0x85, 0x17, 0x25, 0xbc, 0xa2, 0xe5, 0x09, 0xf4, 0x55,
0x58, 0xf7, 0x82, 0xae, 0x3f, 0x12, 0x87, 0x72, 0xa4, 0x0b, 0x17, 0xe4, 0x81, 0xd6, 0x12, 0x69,
0x5b, 0xb8, 0xf2, 0x8f, 0x06, 0x94, 0x3e, 0x24, 0x27, 0xda, 0x87, 0xc4, 0x02, 0x71, 0x98, 0xd7,
0x0f, 0x30, 0x1f, 0x45, 0x44, 0x1e, 0xab, 0x6c, 0xa3, 0x44, 0xd5, 0x8e, 0x35, 0xd6, 0x0f, 0x8b,
0x50, 0x99, 0xda, 0x28, 0x42, 0x3a, 0x9e, 0x8c, 0x34, 0x9c, 0xc4, 0x95, 0xab, 0x2e, 0xa7, 0x22,
0x42, 0x7d, 0xa0, 0xfb, 0x60, 0xaa, 0x33, 0xcf, 0x16, 0x1f, 0xbd, 0xc3, 0x2d, 0xa5, 0x9f, 0xaa,
0x3c, 0xe8, 0x01, 0x5c, 0x95, 0x41, 0xe3, 0x74, 0xe8, 0x28, 0x70, 0x71, 0x74, 0x3e, 0x41, 0x55,
0xdb, 0xad, 0x49, 0x44, 0x4b, 0x03, 0x26, 0xc9, 0x49, 0xe5, 0x55, 0xa9, 0x99, 0x25, 0x2f, 0x2a,
0x72, 0x82, 0x90, 0xbe, 0x4f, 0xc9, 0x8f, 0x92, 0xfa, 0x90, 0x20, 0xcc, 0x25, 0x79, 0x91, 0x2f,
0x50, 0xbb, 0x2b, 0x53, 0xb5, 0x5b, 0xa4, 0xcc, 0x74, 0x5f, 0x5a, 0x9e, 0xdb, 0x96, 0xde, 0x84,
0x6b, 0x29, 0x70, 0xd6, 0x59, 0x2b, 0x72, 0xd3, 0x66, 0x02, 0x99, 0xf2, 0x97, 0xf5, 0x35, 0xb8,
0x3e, 0x75, 0x4b, 0x07, 0x81, 0xfb, 0x30, 0xb9, 0xfc, 0x0f, 0x16, 0x92, 0x3b, 0x50, 0xca, 0xc4,
0x97, 0xbc, 0xe1, 0x15, 0x1b, 0xd2, 0xd0, 0xb2, 0xbe, 0x53, 0x84, 0xd5, 0x64, 0x10, 0x44, 0xdb,
0xb0, 0x14, 0x8e, 0x3a, 0xa7, 0xe4, 0x5c, 0xae, 0x56, 0xb6, 0xf5, 0x97, 0x18, 0x11, 0xde, 0xf7,
0xf8, 0xc0, 0x8d, 0xf0, 0xfb, 0xd8, 0x77, 0xba, 0x11, 0x71, 0x49, 0xc0, 0x3d, 0xec, 0xb3, 0xf8,
0x90, 0x2a, 0xc4, 0xaf, 0xa5, 0xa0, 0x87, 0x29, 0x46, 0xdf, 0xce, 0x5d, 0xa8, 0xe2, 0x2e, 0xf7,
0xc6, 0x2a, 0x39, 0x94, 0x43, 0x17, 0x55, 0xb5, 0x4a, 0xe5, 0xca, 0xa3, 0x37, 0x00, 0xc8, 0x99,
0xc7, 0x35, 0x68, 0x49, 0x82, 0x56, 0x85, 0x44, 0xa9, 0xef, 0x42, 0x35, 0xb3, 0x9b, 0xec, 0xd5,
0x54, 0x52, 0xb9, 0x82, 0xde, 0x86, 0xb5, 0xb8, 0xfd, 0x29, 0xdc, 0x8a, 0xc4, 0x95, 0xb5, 0x50,
0x81, 0x1e, 0x43, 0x59, 0x78, 0x6e, 0xc4, 0x9c, 0x9e, 0x8f, 0xfb, 0xcc, 0x5c, 0xdd, 0x35, 0xf6,
0xd6, 0x9b, 0xaf, 0x5f, 0x3a, 0x37, 0xd7, 0xdb, 0x92, 0xf5, 0x96, 0x20, 0xd9, 0x25, 0x96, 0x7e,
0x58, 0x9f, 0x81, 0x52, 0x46, 0x87, 0x4a, 0xb0, 0x7c, 0xfc, 0xee, 0xf1, 0xc9, 0xf1, 0xc1, 0xa3,
0xea, 0x47, 0x10, 0x82, 0x75, 0xf5, 0x71, 0x72, 0x74, 0xe8, 0x1c, 0x7d, 0xf1, 0xf8, 0xa4, 0x6a,
0xa0, 0x2a, 0x94, 0x9f, 0x1e, 0x9f, 0xbc, 0x7d, 0x68, 0x1f, 0x3c, 0x3d, 0x68, 0x3d, 0x3a, 0xaa,
0x16, 0x2c, 0x1f, 0x6a, 0x72, 0xae, 0xb4, 0x09, 0x66, 0x22, 0xd9, 0x87, 0x24, 0xe0, 0x36, 0xe9,
0xd2, 0xc8, 0x15, 0x81, 0x99, 0xce, 0xd4, 0xb2, 0x8b, 0xea, 0x74, 0x5e, 0x4f, 0xc4, 0xb2, 0x75,
0xe6, 0x24, 0x76, 0x5c, 0x02, 0x8a, 0x99, 0x8e, 0xf2, 0x15, 0x58, 0x4d, 0x03, 0x3f, 0x69, 0x01,
0x46, 0xa6, 0x05, 0x5c, 0x92, 0x99, 0x85, 0x0b, 0x33, 0xd3, 0xfa, 0x71, 0x21, 0x7e, 0xaf, 0xc8,
0xe8, 0x9f, 0x5b, 0x86, 0x5e, 0x03, 0x14, 0x62, 0xd9, 0xa1, 0x66, 0x0d, 0x57, 0x95, 0x26, 0x93,
0xeb, 0xf7, 0x60, 0x43, 0x38, 0x9c, 0xcc, 0xa9, 0x4b, 0x15, 0xa9, 0xc8, 0x60, 0x6f, 0xc3, 0x9a,
0x7e, 0x4e, 0x44, 0x64, 0x4c, 0xb0, 0xaf, 0x8b, 0x50, 0x59, 0x09, 0x6d, 0x29, 0x43, 0x6f, 0xc2,
0x6a, 0x3a, 0x55, 0x2c, 0xbe, 0xe0, 0x50, 0xb1, 0x12, 0x0f, 0x01, 0xe8, 0x3a, 0xac, 0xa6, 0x35,
0x79, 0x49, 0xda, 0x4f, 0x05, 0x22, 0x87, 0x3b, 0xd4, 0x3d, 0x97, 0x51, 0x7a, 0x41, 0x0e, 0x67,
0x5c, 0xd4, 0xa2, 0xee, 0xb9, 0x2d, 0x49, 0xd6, 0x77, 0x8b, 0x50, 0x99, 0xd2, 0xa0, 0xcf, 0x42,
0x79, 0x62, 0x3a, 0x53, 0x4f, 0xbd, 0xdb, 0x2f, 0x50, 0x1c, 0xec, 0x09, 0x22, 0x7a, 0x0a, 0x28,
0x8c, 0x68, 0x48, 0x19, 0x89, 0xd4, 0xa0, 0xe8, 0x05, 0x7d, 0x66, 0x16, 0xa4, 0xb9, 0xbd, 0xdc,
0x59, 0x4f, 0x33, 0xda, 0x9a, 0x60, 0x6f, 0x84, 0x53, 0x12, 0x69, 0x58, 0x2d, 0x34, 0x61, 0xb8,
0x78, 0xb1, 0xe1, 0x03, 0xcd, 0x48, 0x0d, 0xe3, 0x29, 0x09, 0x43, 0x0f, 0x60, 0xc5, 0x25, 0x21,
0x65, 0x1e, 0x67, 0xe6, 0x82, 0x34, 0xb7, 0x93, 0x67, 0xee, 0x50, 0xe1, 0xec, 0x84, 0x80, 0xde,
0x85, 0xca, 0x98, 0xfa, 0xa3, 0x80, 0x8b, 0xbe, 0x24, 0x2a, 0x0a, 0x33, 0x17, 0xa5, 0x8d, 0x57,
0x73, 0xb3, 0x3d, 0x86, 0x1f, 0x9d, 0x79, 0xdc, 0x5e, 0x1f, 0x67, 0x3f, 0x99, 0xf5, 0x3d, 0x03,
0xca, 0x7a, 0x95, 0xe3, 0x20, 0x1c, 0xf1, 0xdc, 0x0a, 0x5a, 0x87, 0xcd, 0x30, 0xa2, 0xb4, 0xe7,
0xd0, 0x9e, 0x13, 0x52, 0xc6, 0x08, 0x4b, 0x86, 0xb0, 0xb2, 0x74, 0x1f, 0xed, 0xbd, 0xd7, 0x7b,
0x9c, 0x28, 0x2e, 0xaf, 0xb8, 0xc5, 0x4b, 0x2b, 0xae, 0xf5, 0x0c, 0x90, 0xba, 0x29, 0xec, 0x8b,
0xa9, 0x80, 0xb8, 0x2f, 0x39, 0x02, 0xdc, 0x83, 0x8d, 0xbc, 0xde, 0x5f, 0xe9, 0x4c, 0x75, 0xb1,
0x3f, 0x19, 0x70, 0x45, 0xde, 0x11, 0xee, 0xf8, 0x24, 0x3b, 0x51, 0x7d, 0x0c, 0x36, 0x26, 0xaa,
0x95, 0x27, 0x5e, 0x20, 0x86, 0x7c, 0x80, 0x54, 0xb3, 0xf5, 0x4a, 0xc8, 0xe7, 0x8e, 0x43, 0x85,
0xf9, 0xe3, 0x50, 0xdc, 0x16, 0x8b, 0xff, 0x4b, 0x5b, 0x7c, 0xe9, 0x59, 0xea, 0xdb, 0x06, 0x94,
0xf4, 0x3d, 0x4b, 0x27, 0x1e, 0xc3, 0x9a, 0x8e, 0x29, 0xc7, 0x13, 0xf7, 0xae, 0xbb, 0xf3, 0x2b,
0x97, 0x44, 0xa2, 0x8c, 0x11, 0xbb, 0xec, 0x4e, 0x45, 0x0c, 0x1e, 0xd2, 0x51, 0xc0, 0xb5, 0xf3,
0xf5, 0x97, 0xa8, 0x28, 0xe2, 0x25, 0xc1, 0x38, 0x1e, 0x86, 0xba, 0x58, 0xa7, 0x02, 0xeb, 0x97,
0x05, 0xa8, 0x4e, 0xa7, 0xa1, 0x18, 0x7a, 0x93, 0x64, 0xce, 0x36, 0x86, 0xb5, 0x58, 0xaa, 0xfa,
0x82, 0x0d, 0x95, 0x50, 0xc7, 0x85, 0xaa, 0xe4, 0x0d, 0xb9, 0xf4, 0x45, 0x8f, 0xbb, 0x99, 0x30,
0x8a, 0x6d, 0x62, 0x5f, 0x7c, 0x35, 0xd0, 0xc7, 0xe1, 0x4a, 0x62, 0x33, 0x71, 0xa8, 0xd3, 0xd0,
0xe1, 0x82, 0xc2, 0x8c, 0x01, 0xa9, 0x6a, 0xcc, 0xee, 0x42, 0x0d, 0x87, 0x1f, 0x60, 0x17, 0xcd,
0x9c, 0x5d, 0xc4, 0x83, 0xe3, 0xec, 0x2e, 0x9a, 0xd6, 0x9f, 0x0d, 0xa8, 0x4e, 0x57, 0x1d, 0xe4,
0x42, 0x8d, 0xc5, 0xb1, 0x9c, 0x7d, 0x05, 0x3b, 0x0d, 0x7d, 0xcf, 0xaf, 0xe5, 0x6d, 0x71, 0x5e,
0x0a, 0xd8, 0x5b, 0x6c, 0x8e, 0xb4, 0x91, 0xbf, 0x4a, 0x53, 0x5f, 0xc7, 0xff, 0x61, 0x95, 0xa6,
0xf5, 0x2d, 0x03, 0x96, 0x75, 0xf4, 0xa1, 0x26, 0x6c, 0x0d, 0x49, 0x74, 0xea, 0x13, 0xa7, 0x13,
0xe1, 0xa0, 0x3b, 0x48, 0x1e, 0xde, 0x86, 0x7c, 0x77, 0x6f, 0x2a, 0x65, 0x4b, 0xea, 0xe2, 0x47,
0xf7, 0x3d, 0xd8, 0xd0, 0x1c, 0x1e, 0x11, 0xa2, 0xc3, 0x4a, 0x45, 0x6a, 0x45, 0x29, 0x4e, 0x22,
0x42, 0x54, 0x60, 0xdd, 0x82, 0x38, 0xb4, 0x9d, 0x24, 0x37, 0xcb, 0x76, 0xc9, 0x4d, 0x13, 0xc7,
0xf2, 0x61, 0x6d, 0xa2, 0xa2, 0xe6, 0x4c, 0x1b, 0x73, 0x66, 0x9c, 0xc2, 0xdc, 0x19, 0x67, 0xa2,
0xef, 0x16, 0xa7, 0xfa, 0xae, 0xf5, 0x65, 0x58, 0x49, 0x1e, 0xfc, 0x75, 0xd8, 0x8c, 0x37, 0x97,
0xad, 0x67, 0xaa, 0x4c, 0x6f, 0x68, 0x55, 0x66, 0x6a, 0xb8, 0x05, 0x65, 0x55, 0xfd, 0x26, 0x26,
0x91, 0x92, 0x94, 0xe9, 0xa2, 0xe7, 0x43, 0x39, 0xfb, 0x9f, 0xc0, 0xe4, 0x0c, 0x61, 0xbc, 0xf4,
0x0c, 0x71, 0x03, 0x60, 0x4c, 0x39, 0x71, 0xba, 0x99, 0x6a, 0xb0, 0x2a, 0x24, 0x0f, 0x85, 0xa0,
0x55, 0xfe, 0xd5, 0xf3, 0x9b, 0xc6, 0xaf, 0x9f, 0xdf, 0x34, 0xfe, 0xf2, 0xfc, 0xa6, 0xd1, 0x59,
0x92, 0xff, 0x04, 0xbf, 0xf1, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x85, 0x9b, 0xdf, 0xdc, 0x61,
0x16, 0x00, 0x00,
// 1962 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x58, 0x5b, 0x6f, 0x23, 0x49,
0x15, 0xa6, 0xe3, 0x4c, 0x2e, 0xc7, 0x9d, 0xd8, 0xa9, 0x4c, 0xe2, 0x66, 0x6e, 0xc9, 0xf4, 0xec,
0x6a, 0x32, 0xc3, 0xae, 0x83, 0xbd, 0x12, 0x23, 0x18, 0x56, 0x22, 0x9e, 0x64, 0xd9, 0xc0, 0xec,
0xee, 0xa8, 0x1d, 0x66, 0x78, 0x00, 0x5a, 0x65, 0x77, 0xd9, 0xee, 0x49, 0xbb, 0xab, 0xd5, 0x55,
0xf6, 0x4e, 0x10, 0x7f, 0x80, 0x8b, 0x78, 0xe3, 0x01, 0xde, 0x40, 0xfc, 0x09, 0xee, 0x3c, 0x80,
0xc4, 0x23, 0x37, 0x21, 0x21, 0x21, 0x84, 0xe6, 0x99, 0xfb, 0x2f, 0x40, 0x75, 0xe9, 0x8b, 0x2f,
0x9d, 0xcc, 0xb0, 0xbc, 0xf0, 0x64, 0xf5, 0x39, 0xdf, 0x77, 0xaa, 0xea, 0xd4, 0xb9, 0x95, 0x61,
0x27, 0x8a, 0x29, 0xa7, 0xfb, 0x1d, 0x82, 0xbb, 0x34, 0xdc, 0x8f, 0x9a, 0xd1, 0xfe, 0xb8, 0xb1,
0xcf, 0xcf, 0x22, 0xc2, 0xea, 0x52, 0x83, 0xb6, 0x09, 0x1f, 0x90, 0x98, 0x8c, 0x86, 0x75, 0x85,
0xa9, 0x47, 0xcd, 0xa8, 0x3e, 0x6e, 0x5c, 0xb9, 0xaa, 0x88, 0x5d, 0x3a, 0x1c, 0xd2, 0x70, 0x7f,
0x48, 0x18, 0xc3, 0xfd, 0x84, 0x64, 0xff, 0xc2, 0x84, 0x72, 0x4b, 0xc2, 0xdb, 0x1c, 0x73, 0x82,
0x1e, 0x01, 0x1a, 0xe3, 0xc0, 0xf7, 0x30, 0xa7, 0xb1, 0x1b, 0x93, 0xbe, 0xcf, 0x78, 0x7c, 0x66,
0x19, 0xbb, 0xa5, 0xbd, 0x72, 0xf3, 0x66, 0x7d, 0xfe, 0x0a, 0xf5, 0xc7, 0x09, 0xc3, 0xd9, 0x48,
0xc9, 0x8e, 0xe6, 0xa2, 0x23, 0xd8, 0x99, 0xb5, 0xe8, 0x8e, 0x22, 0x0f, 0x73, 0xe2, 0x92, 0x88,
0x76, 0x07, 0xd6, 0xc2, 0xae, 0xb1, 0xb7, 0xe8, 0x5c, 0x9b, 0xe1, 0x7e, 0x4e, 0x82, 0x8e, 0x04,
0x06, 0xbd, 0x9e, 0xdf, 0x58, 0x07, 0x07, 0x38, 0xec, 0x12, 0x66, 0x95, 0x76, 0x4b, 0x7b, 0x8b,
0xb9, 0x55, 0x5b, 0x5a, 0x81, 0xf6, 0x61, 0x33, 0xc0, 0x9c, 0x30, 0xee, 0xc6, 0x38, 0xf4, 0x30,
0x75, 0x87, 0xfe, 0x33, 0xc2, 0xac, 0xbf, 0x2e, 0xef, 0x96, 0xf6, 0x4c, 0x67, 0x43, 0xe9, 0x1c,
0xa9, 0x7a, 0x47, 0x68, 0xd0, 0x21, 0xdc, 0x88, 0x62, 0x32, 0xf6, 0xe9, 0x88, 0xb9, 0x6c, 0x30,
0xea, 0xf5, 0x02, 0x3f, 0xec, 0xbb, 0x8c, 0xe3, 0x98, 0xbb, 0x6c, 0x80, 0x63, 0xcf, 0xfa, 0xdb,
0xb2, 0xdc, 0xe6, 0xd5, 0x04, 0xd6, 0x4e, 0x50, 0x6d, 0x01, 0x6a, 0x0b, 0x0c, 0x6a, 0xc1, 0xf5,
0xee, 0x28, 0x8e, 0x49, 0xc8, 0x0b, 0x8c, 0xfc, 0x5d, 0x19, 0xb9, 0xa2, 0x51, 0xf3, 0x6c, 0x7c,
0x1c, 0xac, 0x39, 0x3b, 0x51, 0x9e, 0xfa, 0x87, 0xa2, 0x6f, 0xcf, 0xec, 0x41, 0x39, 0xe9, 0x1e,
0xd4, 0x66, 0x97, 0x57, 0xcc, 0x7f, 0x2a, 0xe6, 0xd6, 0xf4, 0xc2, 0x8a, 0x58, 0x70, 0x7a, 0x42,
0x3c, 0x77, 0x80, 0xd9, 0xe0, 0x8d, 0xa6, 0xf5, 0x2f, 0xc1, 0x37, 0xe7, 0x9d, 0x9e, 0x10, 0xef,
0x6d, 0x89, 0x29, 0x38, 0x7d, 0xce, 0xc8, 0xbf, 0x95, 0x91, 0xd9, 0xd3, 0x67, 0x36, 0xf2, 0xa7,
0x7f, 0x3a, 0x62, 0xdc, 0xef, 0xf9, 0xc4, 0xd3, 0x67, 0xf8, 0x4d, 0x65, 0xf2, 0xf4, 0x9f, 0x49,
0xf4, 0xea, 0x10, 0x7b, 0x50, 0x99, 0x66, 0xfc, 0x56, 0x31, 0xd6, 0x9f, 0x4e, 0x22, 0x3f, 0x06,
0xdb, 0x5a, 0xd2, 0xc5, 0xdc, 0xa7, 0xa1, 0xdb, 0xf1, 0x79, 0xcf, 0x27, 0x81, 0x67, 0xfd, 0x4e,
0x11, 0xb6, 0x26, 0xd4, 0x2d, 0xad, 0x15, 0x2b, 0xf4, 0xfc, 0x10, 0x07, 0xfe, 0x97, 0xd3, 0x15,
0x7e, 0xaf, 0x57, 0x48, 0xe5, 0x6a, 0x85, 0xf7, 0x40, 0xc7, 0x98, 0xdb, 0x8d, 0x29, 0x63, 0x81,
0x1f, 0x9e, 0x32, 0xeb, 0x07, 0xb5, 0xf3, 0xf3, 0xe8, 0x41, 0x02, 0x75, 0xaa, 0x8a, 0x9c, 0x0a,
0x18, 0xfa, 0x04, 0x7c, 0x58, 0x1b, 0xec, 0x04, 0xb4, 0x7b, 0xea, 0xc6, 0x94, 0x72, 0xed, 0x56,
0x66, 0xfd, 0xa8, 0x26, 0xc3, 0x7a, 0x5b, 0x21, 0x5a, 0x02, 0xe0, 0x50, 0xca, 0x95, 0x4b, 0x19,
0xfa, 0x24, 0x5c, 0xe9, 0x60, 0xde, 0x1d, 0x10, 0x6f, 0x1e, 0xf9, 0xc7, 0x8a, 0x5c, 0xd3, 0x90,
0x19, 0xf6, 0x3d, 0xa8, 0xe9, 0x95, 0x59, 0x80, 0x99, 0x34, 0x92, 0xa4, 0xdf, 0x4f, 0x6a, 0x32,
0xff, 0xb6, 0x94, 0xbe, 0xad, 0xd4, 0x69, 0x0e, 0x7e, 0x21, 0xcd, 0x41, 0xcc, 0xc5, 0x8f, 0xf4,
0x25, 0xb3, 0x7e, 0xaa, 0xbc, 0x70, 0xb7, 0xc8, 0x0b, 0x8f, 0x48, 0xe8, 0xf9, 0x61, 0xff, 0x20,
0xe3, 0x38, 0x48, 0xd9, 0xc9, 0x89, 0xf2, 0x0e, 0xf1, 0x43, 0x8f, 0x3c, 0x9b, 0x3c, 0xd3, 0xcf,
0x26, 0x1c, 0x72, 0x2c, 0x00, 0xf9, 0x23, 0x7d, 0x1a, 0xcc, 0xbc, 0x33, 0xad, 0x9f, 0xd7, 0x76,
0x8d, 0xbd, 0x72, 0xf3, 0x56, 0xd1, 0x96, 0x54, 0x85, 0x54, 0x9e, 0x29, 0xe7, 0x9c, 0x8c, 0x3e,
0x0b, 0xfa, 0xa6, 0x5c, 0xc2, 0x07, 0x0d, 0xd7, 0xc3, 0x1c, 0x5b, 0xdf, 0xdd, 0x91, 0xc6, 0x76,
0x8b, 0x8c, 0x1d, 0xf1, 0x41, 0xe3, 0x10, 0x73, 0xec, 0xac, 0x2b, 0x6a, 0xf2, 0x8d, 0xde, 0x81,
0x4a, 0x6a, 0xc5, 0x1d, 0x53, 0x4e, 0x98, 0xf5, 0xbd, 0x1d, 0xe9, 0xab, 0x57, 0x2e, 0xb2, 0xf5,
0x98, 0x72, 0xe2, 0xac, 0x91, 0xdc, 0x17, 0x43, 0x36, 0x98, 0x7d, 0x12, 0x12, 0xe6, 0x33, 0x97,
0xfb, 0x43, 0x62, 0x7d, 0xf5, 0xb6, 0x8c, 0xd4, 0xb2, 0x16, 0x9e, 0xf8, 0x43, 0x82, 0x1a, 0xb0,
0xd8, 0xa3, 0xf1, 0xa9, 0xf5, 0xb5, 0xdb, 0x72, 0xcf, 0xd7, 0x8a, 0xd6, 0x79, 0x8b, 0xc6, 0xa7,
0x8e, 0x84, 0xa2, 0x4d, 0x58, 0x64, 0x01, 0xe5, 0xd6, 0xd7, 0x95, 0x39, 0xf9, 0x61, 0x47, 0xb0,
0x28, 0x20, 0xe8, 0x0e, 0x54, 0xd3, 0xec, 0x1d, 0x93, 0x98, 0xf9, 0x34, 0xb4, 0x0c, 0x89, 0xab,
0x24, 0xf2, 0xc7, 0x4a, 0x8c, 0x6e, 0x43, 0x25, 0x29, 0x16, 0x09, 0x52, 0xf5, 0x81, 0x75, 0x2d,
0x4e, 0x80, 0x97, 0xe1, 0x92, 0x4a, 0xb5, 0x92, 0x54, 0xab, 0x0f, 0xfb, 0x0f, 0x06, 0xa0, 0xd9,
0x48, 0x41, 0xf7, 0x61, 0x51, 0x5e, 0x82, 0x21, 0xcf, 0x73, 0xbb, 0xe8, 0x3c, 0x39, 0x8a, 0xbc,
0x0a, 0x49, 0x42, 0x0d, 0xb8, 0x8c, 0xfb, 0xfd, 0x98, 0xf4, 0xa7, 0x8a, 0xc2, 0x82, 0xac, 0x5a,
0x9b, 0x39, 0x5d, 0x5a, 0x11, 0xee, 0x40, 0xb5, 0x3b, 0x62, 0x9c, 0x7a, 0x67, 0x19, 0xbc, 0x24,
0xe1, 0x15, 0x2d, 0x4f, 0xa1, 0xaf, 0xc2, 0xba, 0x1f, 0x76, 0x83, 0x91, 0x38, 0x94, 0x2b, 0x5d,
0xb8, 0x28, 0x0f, 0xb4, 0x96, 0x4a, 0xdb, 0xc2, 0x95, 0x7f, 0x34, 0xa0, 0xfc, 0x7f, 0x72, 0xa2,
0x7d, 0x48, 0x2d, 0x10, 0x97, 0xf9, 0xfd, 0x10, 0xf3, 0x51, 0x4c, 0xe4, 0xb1, 0x4c, 0x07, 0xa5,
0xaa, 0x76, 0xa2, 0xb1, 0xbf, 0x5f, 0x82, 0xca, 0xd4, 0x46, 0x11, 0xd2, 0xf1, 0x64, 0x64, 0xe1,
0x24, 0xae, 0x5c, 0xb5, 0x4b, 0x15, 0x11, 0xea, 0x03, 0xdd, 0x03, 0x4b, 0x9d, 0x79, 0xb6, 0x8a,
0xe9, 0x1d, 0x6e, 0x75, 0x72, 0x89, 0x9a, 0xe6, 0x3b, 0xba, 0x0f, 0x57, 0x64, 0xd0, 0xb8, 0x1d,
0x3a, 0x0a, 0x3d, 0x1c, 0x9f, 0x4d, 0x50, 0xd5, 0x76, 0x6b, 0x12, 0xd1, 0xd2, 0x80, 0x49, 0x72,
0x5a, 0xc2, 0x55, 0x6a, 0xe6, 0xc9, 0x97, 0x14, 0x39, 0x45, 0x48, 0xdf, 0x67, 0xe4, 0x87, 0x69,
0x7d, 0x48, 0x11, 0xd6, 0x92, 0xbc, 0xc8, 0x17, 0x68, 0x02, 0x95, 0xa9, 0x26, 0x20, 0x52, 0x66,
0xba, 0xc1, 0x2d, 0xcf, 0xed, 0x6f, 0x6f, 0xc2, 0xd5, 0x0c, 0x38, 0xeb, 0xac, 0x15, 0xb9, 0x69,
0x2b, 0x85, 0x4c, 0xf9, 0xcb, 0xfe, 0x0a, 0x5c, 0x9b, 0xba, 0xa5, 0x83, 0xd0, 0x7b, 0x90, 0x5e,
0xfe, 0x07, 0x0b, 0xc9, 0x1d, 0x28, 0xe7, 0xe2, 0x4b, 0xde, 0xf0, 0x8a, 0x03, 0x59, 0x68, 0xd9,
0xdf, 0x2a, 0xc1, 0x6a, 0x3a, 0x51, 0xa2, 0x6d, 0x58, 0x8a, 0x46, 0x9d, 0x53, 0x72, 0x26, 0x57,
0x33, 0x1d, 0xfd, 0x25, 0x66, 0x8d, 0xf7, 0x7d, 0x3e, 0xf0, 0x62, 0xfc, 0x3e, 0x0e, 0xdc, 0x6e,
0x4c, 0x3c, 0x12, 0x72, 0x1f, 0x07, 0x2c, 0x39, 0xa4, 0x0a, 0xf1, 0xab, 0x19, 0xe8, 0x41, 0x86,
0xd1, 0xb7, 0x73, 0x07, 0xaa, 0xb8, 0xcb, 0xfd, 0xb1, 0x4a, 0x0e, 0xe5, 0xd0, 0x4b, 0xaa, 0x5a,
0x65, 0x72, 0xe5, 0xd1, 0xeb, 0x00, 0xe4, 0x99, 0xcf, 0x35, 0x68, 0x49, 0x82, 0x56, 0x85, 0x44,
0xa9, 0xef, 0x40, 0x35, 0xb7, 0x9b, 0xfc, 0xd5, 0x54, 0x32, 0xb9, 0x82, 0xde, 0x82, 0xb5, 0xa4,
0x8f, 0x2a, 0xdc, 0x8a, 0xc4, 0x99, 0x5a, 0xa8, 0x40, 0x8f, 0xc0, 0x14, 0x9e, 0x1b, 0x31, 0xb7,
0x17, 0xe0, 0x3e, 0xb3, 0x56, 0x77, 0x8d, 0xbd, 0xf5, 0xe6, 0xeb, 0x17, 0x0e, 0xe0, 0xf5, 0xb6,
0x64, 0xbd, 0x25, 0x48, 0x4e, 0x99, 0x65, 0x1f, 0xf6, 0xa7, 0xa0, 0x9c, 0xd3, 0xa1, 0x32, 0x2c,
0x1f, 0xbf, 0x7b, 0x7c, 0x72, 0x7c, 0xf0, 0xb0, 0xfa, 0x21, 0x84, 0x60, 0x5d, 0x7d, 0x9c, 0x1c,
0x1d, 0xba, 0x47, 0x9f, 0x3f, 0x3e, 0xa9, 0x1a, 0xa8, 0x0a, 0xe6, 0x93, 0xe3, 0x93, 0xb7, 0x0f,
0x9d, 0x83, 0x27, 0x07, 0xad, 0x87, 0x47, 0xd5, 0x05, 0x3b, 0x80, 0x9a, 0x1c, 0x50, 0x1d, 0x82,
0x99, 0x48, 0xf6, 0x21, 0x09, 0xb9, 0x43, 0xba, 0x34, 0xf6, 0x44, 0x60, 0x66, 0xc3, 0xb9, 0x6c,
0xc7, 0x3a, 0x9d, 0xd7, 0x53, 0xb1, 0xec, 0xc1, 0x05, 0x89, 0x9d, 0x94, 0x80, 0x52, 0xae, 0xa3,
0x7c, 0x09, 0x56, 0xb3, 0xc0, 0x4f, 0x5b, 0x80, 0x91, 0x6b, 0x01, 0x17, 0x64, 0xe6, 0xc2, 0xb9,
0x99, 0x69, 0xff, 0x70, 0x21, 0x79, 0xf8, 0xa8, 0x4e, 0x3e, 0xaf, 0x0c, 0xbd, 0x06, 0x28, 0xc2,
0xb2, 0x43, 0xcd, 0x1a, 0xae, 0x2a, 0x4d, 0x2e, 0xd7, 0xef, 0xc2, 0x86, 0x70, 0x38, 0x99, 0x53,
0x97, 0x2a, 0x52, 0x91, 0xc3, 0xde, 0x82, 0x35, 0xfd, 0x2e, 0x89, 0xc9, 0x98, 0xe0, 0x40, 0x17,
0x21, 0x53, 0x09, 0x1d, 0x29, 0x43, 0x6f, 0xc2, 0x6a, 0x36, 0x55, 0x5c, 0x7a, 0xc1, 0xa1, 0x62,
0x25, 0x19, 0x02, 0xd0, 0x35, 0x58, 0xcd, 0x6a, 0xf2, 0x92, 0xb4, 0x9f, 0x09, 0x44, 0x0e, 0x77,
0xa8, 0x77, 0x26, 0xa3, 0xf4, 0x9c, 0x1c, 0xce, 0xb9, 0xa8, 0x45, 0xbd, 0x33, 0x47, 0x92, 0xec,
0x6f, 0x97, 0xa0, 0x32, 0xa5, 0x11, 0x33, 0xd5, 0xc4, 0x98, 0xa7, 0xde, 0x8c, 0xb7, 0x5e, 0xa0,
0x38, 0x38, 0x13, 0x44, 0xf4, 0x04, 0x50, 0x14, 0xd3, 0x88, 0x32, 0x12, 0xab, 0x89, 0xd3, 0x0f,
0xfb, 0xcc, 0x5a, 0x90, 0xe6, 0xf6, 0x0a, 0x87, 0x46, 0xcd, 0x68, 0x6b, 0x82, 0xb3, 0x11, 0x4d,
0x49, 0xa4, 0x61, 0xb5, 0xd0, 0x84, 0xe1, 0xd2, 0xf9, 0x86, 0x0f, 0x34, 0x23, 0x33, 0x8c, 0xa7,
0x24, 0x0c, 0xdd, 0x87, 0x15, 0x8f, 0x44, 0x94, 0xf9, 0x9c, 0x59, 0x8b, 0xd2, 0xdc, 0x4e, 0x91,
0xb9, 0x43, 0x85, 0x73, 0x52, 0x02, 0x7a, 0x17, 0x2a, 0x63, 0x1a, 0x8c, 0x42, 0x2e, 0xfa, 0x92,
0xa8, 0x28, 0xcc, 0xba, 0x24, 0x6d, 0xbc, 0x5a, 0x98, 0xed, 0x09, 0xfc, 0xe8, 0x99, 0xcf, 0x9d,
0xf5, 0x71, 0xfe, 0x93, 0xd9, 0xdf, 0x31, 0xc0, 0xd4, 0xab, 0x1c, 0x87, 0xd1, 0x88, 0x17, 0x56,
0xd0, 0x3a, 0x6c, 0x46, 0x31, 0xa5, 0x3d, 0x97, 0xf6, 0xdc, 0x88, 0x32, 0x46, 0x58, 0x3a, 0x84,
0x99, 0xd2, 0x7d, 0xb4, 0xf7, 0x5e, 0xef, 0x51, 0xaa, 0xb8, 0xb8, 0xe2, 0x96, 0x2e, 0xac, 0xb8,
0xf6, 0x53, 0x40, 0xea, 0xa6, 0x70, 0x20, 0xa6, 0x02, 0xe2, 0xbd, 0xe4, 0x08, 0x70, 0x17, 0x36,
0x8a, 0x7a, 0x7f, 0xa5, 0x33, 0xd5, 0xc5, 0xfe, 0x64, 0xc0, 0x65, 0x79, 0x47, 0xb8, 0x13, 0x90,
0xfc, 0x44, 0xf5, 0x11, 0xd8, 0x98, 0xa8, 0x56, 0xbe, 0x78, 0xca, 0x18, 0xf2, 0x25, 0x53, 0xcd,
0xd7, 0x2b, 0x21, 0x9f, 0x3b, 0x0e, 0x2d, 0xcc, 0x1f, 0x87, 0x92, 0xb6, 0x58, 0xfa, 0x6f, 0xda,
0xe2, 0x4b, 0xcf, 0x52, 0xdf, 0x34, 0xa0, 0xac, 0xef, 0x59, 0x3a, 0xf1, 0x18, 0xd6, 0x74, 0x4c,
0xb9, 0xbe, 0xb8, 0x77, 0xdd, 0x9d, 0x5f, 0xb9, 0x20, 0x12, 0x65, 0x8c, 0x38, 0xa6, 0x37, 0x15,
0x31, 0x78, 0x48, 0x47, 0x21, 0xd7, 0xce, 0xd7, 0x5f, 0xa2, 0xa2, 0x88, 0x97, 0x04, 0xe3, 0x78,
0x18, 0xe9, 0x62, 0x9d, 0x09, 0xec, 0x5f, 0x2e, 0x40, 0x75, 0x3a, 0x0d, 0xc5, 0xd0, 0x9b, 0x26,
0x73, 0xbe, 0x31, 0xac, 0x25, 0x52, 0xd5, 0x17, 0x1c, 0xa8, 0x44, 0x3a, 0x2e, 0x54, 0x25, 0x6f,
0xc8, 0xa5, 0xcf, 0x7b, 0x25, 0xce, 0x84, 0x51, 0x62, 0x13, 0x07, 0xe2, 0xab, 0x81, 0x3e, 0x0a,
0x97, 0x53, 0x9b, 0xa9, 0x43, 0xdd, 0x86, 0x0e, 0x17, 0x14, 0xe5, 0x0c, 0x48, 0x55, 0x63, 0x76,
0x17, 0x6a, 0x38, 0xfc, 0x00, 0xbb, 0x68, 0x16, 0xec, 0x22, 0x19, 0x1c, 0x67, 0x77, 0xd1, 0xb4,
0xff, 0x6c, 0x40, 0x75, 0xba, 0xea, 0x20, 0x0f, 0x6a, 0x2c, 0x89, 0xe5, 0xfc, 0x73, 0xda, 0x6d,
0xe8, 0x7b, 0x7e, 0xad, 0x68, 0x8b, 0xf3, 0x52, 0xc0, 0xd9, 0x62, 0x73, 0xa4, 0x8d, 0xe2, 0x55,
0x9a, 0xfa, 0x3a, 0xfe, 0x07, 0xab, 0x34, 0xed, 0x6f, 0x18, 0xb0, 0xac, 0xa3, 0x0f, 0x35, 0x61,
0x6b, 0x48, 0xe2, 0xd3, 0x80, 0xb8, 0x9d, 0x18, 0x87, 0xdd, 0x41, 0xfa, 0x82, 0x37, 0xe4, 0x03,
0x7e, 0x53, 0x29, 0x5b, 0x52, 0x97, 0xbc, 0xde, 0xef, 0xc2, 0x86, 0xe6, 0xf0, 0x98, 0x10, 0x1d,
0x56, 0x2a, 0x52, 0x2b, 0x4a, 0x71, 0x12, 0x13, 0xa2, 0x02, 0xeb, 0x26, 0x24, 0xa1, 0xed, 0xa6,
0xb9, 0x69, 0x3a, 0x65, 0x2f, 0x4b, 0x1c, 0x3b, 0x80, 0xb5, 0x89, 0x8a, 0x5a, 0x30, 0x6d, 0xcc,
0x99, 0x71, 0x16, 0xe6, 0xce, 0x38, 0x13, 0x7d, 0xb7, 0x34, 0xd5, 0x77, 0xed, 0x2f, 0xc2, 0x4a,
0xfa, 0xe0, 0xaf, 0xc3, 0x66, 0xb2, 0xb9, 0x7c, 0x3d, 0x53, 0x65, 0x7a, 0x43, 0xab, 0x72, 0x53,
0xc3, 0x4d, 0x30, 0x55, 0xf5, 0x9b, 0x98, 0x44, 0xca, 0x52, 0xa6, 0x8b, 0x5e, 0x00, 0x66, 0xfe,
0x3f, 0x81, 0xc9, 0x19, 0xc2, 0x78, 0xe9, 0x19, 0xe2, 0x3a, 0xc0, 0x98, 0x72, 0xe2, 0x76, 0x73,
0xd5, 0x60, 0x55, 0x48, 0x1e, 0x08, 0x41, 0xcb, 0xfc, 0xd5, 0xf3, 0x1b, 0xc6, 0xaf, 0x9f, 0xdf,
0x30, 0xfe, 0xf2, 0xfc, 0x86, 0xd1, 0x59, 0x92, 0x7f, 0x29, 0xbf, 0xf1, 0x9f, 0x00, 0x00, 0x00,
0xff, 0xff, 0xea, 0x7a, 0x6c, 0xc3, 0xaa, 0x16, 0x00, 0x00,
}
func (m *BeaconState) Marshal() (dAtA []byte, err error) {
@@ -2043,6 +2052,20 @@ func (m *BeaconState) MarshalTo(dAtA []byte) (int, error) {
i += copy(dAtA[i:], b)
}
}
if m.LatestBlock != nil {
dAtA[i] = 0x82
i++
dAtA[i] = 0xbc
i++
dAtA[i] = 0x1
i++
i = encodeVarintTypes(dAtA, i, uint64(m.LatestBlock.Size()))
n5, err := m.LatestBlock.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n5
}
if m.LatestEth1Data != nil {
dAtA[i] = 0x8a
i++
@@ -2051,11 +2074,11 @@ func (m *BeaconState) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x1
i++
i = encodeVarintTypes(dAtA, i, uint64(m.LatestEth1Data.Size()))
n5, err := m.LatestEth1Data.MarshalTo(dAtA[i:])
n6, err := m.LatestEth1Data.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n5
i += n6
}
if len(m.Eth1DataVotes) > 0 {
for _, msg := range m.Eth1DataVotes {
@@ -2090,11 +2113,11 @@ func (m *BeaconState) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x2
i++
i = encodeVarintTypes(dAtA, i, uint64(m.Fork.Size()))
n6, err := m.Fork.MarshalTo(dAtA[i:])
n7, err := m.Fork.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n6
i += n7
}
if m.Slot != 0 {
dAtA[i] = 0xd8
@@ -2166,11 +2189,11 @@ func (m *PendingAttestation) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa
i++
i = encodeVarintTypes(dAtA, i, uint64(m.Data.Size()))
n7, err := m.Data.MarshalTo(dAtA[i:])
n8, err := m.Data.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n7
i += n8
}
if len(m.AggregationBitfield) > 0 {
dAtA[i] = 0x12
@@ -2214,11 +2237,11 @@ func (m *Attestation) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa
i++
i = encodeVarintTypes(dAtA, i, uint64(m.Data.Size()))
n8, err := m.Data.MarshalTo(dAtA[i:])
n9, err := m.Data.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n8
i += n9
}
if len(m.AggregationBitfield) > 0 {
dAtA[i] = 0x12
@@ -2291,11 +2314,11 @@ func (m *AttestationData) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x32
i++
i = encodeVarintTypes(dAtA, i, uint64(m.LatestCrosslink.Size()))
n9, err := m.LatestCrosslink.MarshalTo(dAtA[i:])
n10, err := m.LatestCrosslink.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n9
i += n10
}
if m.JustifiedEpoch != 0 {
dAtA[i] = 0x38
@@ -2333,11 +2356,11 @@ func (m *AttestationDataAndCustodyBit) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa
i++
i = encodeVarintTypes(dAtA, i, uint64(m.Data.Size()))
n10, err := m.Data.MarshalTo(dAtA[i:])
n11, err := m.Data.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n10
i += n11
}
if m.CustodyBit {
dAtA[i] = 0x10
@@ -2523,11 +2546,11 @@ func (m *BeaconBlock) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x2a
i++
i = encodeVarintTypes(dAtA, i, uint64(m.Eth1Data.Size()))
n11, err := m.Eth1Data.MarshalTo(dAtA[i:])
n12, err := m.Eth1Data.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n11
i += n12
}
if len(m.Signature) > 0 {
dAtA[i] = 0x32
@@ -2539,11 +2562,11 @@ func (m *BeaconBlock) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x3a
i++
i = encodeVarintTypes(dAtA, i, uint64(m.Body.Size()))
n12, err := m.Body.MarshalTo(dAtA[i:])
n13, err := m.Body.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n12
i += n13
}
if m.XXX_unrecognized != nil {
i += copy(dAtA[i:], m.XXX_unrecognized)
@@ -2724,21 +2747,21 @@ func (m *SlashableAttestation) MarshalTo(dAtA []byte) (int, error) {
var l int
_ = l
if len(m.ValidatorIndices) > 0 {
dAtA14 := make([]byte, len(m.ValidatorIndices)*10)
var j13 int
dAtA15 := make([]byte, len(m.ValidatorIndices)*10)
var j14 int
for _, num := range m.ValidatorIndices {
for num >= 1<<7 {
dAtA14[j13] = uint8(uint64(num)&0x7f | 0x80)
dAtA15[j14] = uint8(uint64(num)&0x7f | 0x80)
num >>= 7
j13++
j14++
}
dAtA14[j13] = uint8(num)
j13++
dAtA15[j14] = uint8(num)
j14++
}
dAtA[i] = 0xa
i++
i = encodeVarintTypes(dAtA, i, uint64(j13))
i += copy(dAtA[i:], dAtA14[:j13])
i = encodeVarintTypes(dAtA, i, uint64(j14))
i += copy(dAtA[i:], dAtA15[:j14])
}
if len(m.CustodyBitfield) > 0 {
dAtA[i] = 0x12
@@ -2750,11 +2773,11 @@ func (m *SlashableAttestation) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x1a
i++
i = encodeVarintTypes(dAtA, i, uint64(m.Data.Size()))
n15, err := m.Data.MarshalTo(dAtA[i:])
n16, err := m.Data.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n15
i += n16
}
if len(m.AggregateSignature) > 0 {
dAtA[i] = 0x22
@@ -2787,11 +2810,11 @@ func (m *DepositData) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa
i++
i = encodeVarintTypes(dAtA, i, uint64(m.DepositInput.Size()))
n16, err := m.DepositInput.MarshalTo(dAtA[i:])
n17, err := m.DepositInput.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n16
i += n17
}
if m.Amount != 0 {
dAtA[i] = 0x10
@@ -2833,11 +2856,11 @@ func (m *ProposerSlashing) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x12
i++
i = encodeVarintTypes(dAtA, i, uint64(m.ProposalData_1.Size()))
n17, err := m.ProposalData_1.MarshalTo(dAtA[i:])
n18, err := m.ProposalData_1.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n17
i += n18
}
if len(m.ProposalSignature_1) > 0 {
dAtA[i] = 0x1a
@@ -2849,11 +2872,11 @@ func (m *ProposerSlashing) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x22
i++
i = encodeVarintTypes(dAtA, i, uint64(m.ProposalData_2.Size()))
n18, err := m.ProposalData_2.MarshalTo(dAtA[i:])
n19, err := m.ProposalData_2.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n18
i += n19
}
if len(m.ProposalSignature_2) > 0 {
dAtA[i] = 0x2a
@@ -2886,21 +2909,21 @@ func (m *AttesterSlashing) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa
i++
i = encodeVarintTypes(dAtA, i, uint64(m.SlashableAttestation_1.Size()))
n19, err := m.SlashableAttestation_1.MarshalTo(dAtA[i:])
n20, err := m.SlashableAttestation_1.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n19
i += n20
}
if m.SlashableAttestation_2 != nil {
dAtA[i] = 0x12
i++
i = encodeVarintTypes(dAtA, i, uint64(m.SlashableAttestation_2.Size()))
n20, err := m.SlashableAttestation_2.MarshalTo(dAtA[i:])
n21, err := m.SlashableAttestation_2.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n20
i += n21
}
if m.XXX_unrecognized != nil {
i += copy(dAtA[i:], m.XXX_unrecognized)
@@ -3037,11 +3060,11 @@ func (m *Eth1DataVote) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa
i++
i = encodeVarintTypes(dAtA, i, uint64(m.Eth1Data.Size()))
n21, err := m.Eth1Data.MarshalTo(dAtA[i:])
n22, err := m.Eth1Data.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n21
i += n22
}
if m.VoteCount != 0 {
dAtA[i] = 0x10
@@ -3160,6 +3183,10 @@ func (m *BeaconState) Size() (n int) {
n += 3 + l + sovTypes(uint64(l))
}
}
if m.LatestBlock != nil {
l = m.LatestBlock.Size()
n += 3 + l + sovTypes(uint64(l))
}
if m.LatestEth1Data != nil {
l = m.LatestEth1Data.Size()
n += 3 + l + sovTypes(uint64(l))
@@ -4377,6 +4404,42 @@ func (m *BeaconState) Unmarshal(dAtA []byte) error {
m.LatestIndexRootHash32S = append(m.LatestIndexRootHash32S, make([]byte, postIndex-iNdEx))
copy(m.LatestIndexRootHash32S[len(m.LatestIndexRootHash32S)-1], dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3008:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field LatestBlock", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTypes
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTypes
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.LatestBlock == nil {
m.LatestBlock = &BeaconBlock{}
}
if err := m.LatestBlock.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 4001:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field LatestEth1Data", wireType)

View File

@@ -32,6 +32,7 @@ message BeaconState {
repeated uint64 latest_slashed_balances = 3005;
repeated PendingAttestation latest_attestations = 3006;
repeated bytes latest_index_root_hash32s = 3007;
BeaconBlock latest_block = 3008;
// Ethereum 1.0 chain data [4001-5000]
Eth1Data latest_eth1_data = 4001;

View File

@@ -1,5 +1,7 @@
package mathutil
import "math"
// IntegerSquareRoot defines a function that returns the
// largest possible integer root of a number.
func IntegerSquareRoot(n uint64) uint64 {
@@ -39,3 +41,13 @@ func PowerOf2(n uint64) uint64 {
}
return 1 << n
}
// ClosestPowerOf2 returns an integer that is the closest
// power of 2 that is less than or equal to the argument.
func ClosestPowerOf2(n uint64) uint64 {
if n == 0 {
return uint64(1)
}
exponent := math.Floor(math.Log2(float64(n)))
return PowerOf2(uint64(exponent))
}

View File

@@ -135,3 +135,32 @@ func TestPowerOf2(t *testing.T) {
}
}
}
func TestClosestPowerOf2(t *testing.T) {
tests := []struct {
a uint64
b uint64
}{
{
a: 10,
b: 8,
},
{
a: 300,
b: 256,
},
{
a: 1200,
b: 1024,
},
{
a: 4500,
b: 4096,
},
}
for _, tt := range tests {
if tt.b != ClosestPowerOf2(tt.a) {
t.Fatalf("ClosestPowerOf2(%d) = %d, wanted: %d", tt.a, ClosestPowerOf2(tt.a), tt.b)
}
}
}