diff --git a/proto/ibc/client/client.proto b/proto/ibc/client/client.proto index 15be107ea..12b311d08 100644 --- a/proto/ibc/client/client.proto +++ b/proto/ibc/client/client.proto @@ -21,3 +21,20 @@ message ClientConsensusStates { // consensus states associated with the client repeated google.protobuf.Any consensus_states = 2 [(gogoproto.moretags) = "yaml:\"consensus_states\""]; } + +// Height is a monotonically increasing data type +// that can be compared against another Height for the purposes of updating and freezing clients +// +// Normally the EpochHeight is incremented at each height while keeping epoch number the same +// However some consensus algorithms may choose to reset the height in certain conditions +// e.g. hard forks, state-machine breaking changes +// In these cases, the epoch number is incremented so that height continues to be monitonically increasing +// even as the EpochHeight gets reset +message Height { + option (gogoproto.goproto_stringer) = false; + + // the epoch that the client is currently on + uint64 epoch_number = 1 [(gogoproto.moretags) = "yaml:\"epoch_number\""]; + // the height within the given epoch + uint64 epoch_height = 2 [(gogoproto.moretags) = "yaml:\"epoch_height\""]; +} diff --git a/proto/ibc/localhost/localhost.proto b/proto/ibc/localhost/localhost.proto index 33732aa2c..f1490895c 100644 --- a/proto/ibc/localhost/localhost.proto +++ b/proto/ibc/localhost/localhost.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package ibc.localhost; import "gogoproto/gogo.proto"; +import "ibc/client/client.proto"; option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/09-localhost/types"; @@ -24,5 +25,7 @@ message ClientState { (gogoproto.moretags) = "yaml:\"chain_id\"" ]; // self latest block height - uint64 height = 3; + ibc.client.Height height = 3 [ + (gogoproto.nullable) = false + ]; } diff --git a/proto/ibc/tendermint/tendermint.proto b/proto/ibc/tendermint/tendermint.proto index dc7f0345d..7bba91b30 100644 --- a/proto/ibc/tendermint/tendermint.proto +++ b/proto/ibc/tendermint/tendermint.proto @@ -8,6 +8,7 @@ import "tendermint/types/types.proto"; import "confio/proofs.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; +import "ibc/client/client.proto"; import "ibc/commitment/commitment.proto"; import "gogoproto/gogo.proto"; @@ -41,9 +42,15 @@ message ClientState { (gogoproto.moretags) = "yaml:\"max_clock_drift\"" ]; // Block height when the client was frozen due to a misbehaviour - uint64 frozen_height = 6 [(gogoproto.moretags) = "yaml:\"frozen_height\""]; + ibc.client.Height frozen_height = 6 [ + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"frozen_height\"" + ]; // Latest height the client was updated to - uint64 latest_height = 7 [(gogoproto.moretags) = "yaml:\"latest_height\""]; + ibc.client.Height latest_height = 7 [ + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"latest_height\"" + ]; // Proof specifications used in verifying counterparty state repeated ics23.ProofSpec proof_specs = 8 [(gogoproto.moretags) = "yaml:\"proof_specs\""]; @@ -60,7 +67,9 @@ message ConsensusState { // commitment root (i.e app hash) ibc.commitment.MerkleRoot root = 2 [(gogoproto.nullable) = false]; // height at which the consensus state was stored. - uint64 height = 3; + ibc.client.Height height = 3 [ + (gogoproto.nullable) = false + ]; bytes next_validators_hash = 4 [ (gogoproto.casttype) = "github.com/tendermint/tendermint/libs/bytes.HexBytes", @@ -106,7 +115,10 @@ message Header { .tendermint.types.ValidatorSet validator_set = 2 [(gogoproto.moretags) = "yaml:\"validator_set\""]; - uint64 trusted_height = 3 [(gogoproto.moretags) = "yaml:\"trusted_height\""]; + ibc.client.Height trusted_height = 3 [ + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"trusted_height\"" + ]; .tendermint.types.ValidatorSet trusted_validators = 4 [(gogoproto.moretags) = "yaml:\"trusted_validators\""]; } diff --git a/x/ibc/02-client/exported/exported.go b/x/ibc/02-client/exported/exported.go index 8af91a4a9..2e1d4b315 100644 --- a/x/ibc/02-client/exported/exported.go +++ b/x/ibc/02-client/exported/exported.go @@ -182,6 +182,17 @@ type MsgSubmitMisbehaviour interface { GetMisbehaviour() Misbehaviour } +// Height is a wrapper interface over clienttypes.Height +// all clients must use the concrete implementation in types +type Height interface { + IsZero() bool + LT(Height) bool + LTE(Height) bool + EQ(Height) bool + GT(Height) bool + GTE(Height) bool +} + // ClientType defines the type of the consensus algorithm type ClientType byte diff --git a/x/ibc/02-client/genesis.go b/x/ibc/02-client/genesis.go index 8977c4e37..031673806 100644 --- a/x/ibc/02-client/genesis.go +++ b/x/ibc/02-client/genesis.go @@ -43,7 +43,11 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) { } // client id is always "localhost" - clientState := localhosttypes.NewClientState(ctx.ChainID(), ctx.BlockHeight()) + // Hardcode 0 as epoch number for now + // TODO: Retrieve epoch from chain-id + clientState := localhosttypes.NewClientState( + ctx.ChainID(), types.NewHeight(0, uint64(ctx.BlockHeight())), + ) _, err := k.CreateClient(ctx, exported.ClientTypeLocalHost, clientState, nil) if err != nil { diff --git a/x/ibc/02-client/handler.go b/x/ibc/02-client/handler.go index cf9cbcf78..66e08bf39 100644 --- a/x/ibc/02-client/handler.go +++ b/x/ibc/02-client/handler.go @@ -22,7 +22,8 @@ func HandleMsgCreateClient(ctx sdk.Context, k keeper.Keeper, msg exported.MsgCre // localhost is a special case that must initialize client state // from context and not from msg case *localhosttypes.MsgCreateClient: - clientState = localhosttypes.NewClientState(ctx.ChainID(), ctx.BlockHeight()) + selfHeight := types.NewHeight(0, uint64(ctx.BlockHeight())) + clientState = localhosttypes.NewClientState(ctx.ChainID(), selfHeight) // Localhost consensus height is chain's blockheight consensusHeight = uint64(ctx.BlockHeight()) default: diff --git a/x/ibc/02-client/keeper/client_test.go b/x/ibc/02-client/keeper/client_test.go index ed4997eb8..5056ad1a8 100644 --- a/x/ibc/02-client/keeper/client_test.go +++ b/x/ibc/02-client/keeper/client_test.go @@ -7,6 +7,7 @@ import ( tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" localhosttypes "github.com/cosmos/cosmos-sdk/x/ibc/09-localhost/types" commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" @@ -80,14 +81,15 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { _, err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState) // store intermediate consensus state to check that trustedHeight does not need to be highest consensus state before header height + incrementedClientHeight := testClientHeight.Increment() intermediateConsState := &ibctmtypes.ConsensusState{ - Height: testClientHeight + 1, + Height: incrementedClientHeight, Timestamp: suite.now.Add(time.Minute), NextValidatorsHash: suite.valSetHash, } - suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight+1, intermediateConsState) + suite.keeper.SetClientConsensusState(suite.ctx, testClientID, incrementedClientHeight.EpochHeight, intermediateConsState) - clientState.LatestHeight = testClientHeight + 1 + clientState.LatestHeight = incrementedClientHeight suite.keeper.SetClientState(suite.ctx, testClientID, clientState) updateHeader = createFutureUpdateFn(suite) @@ -100,7 +102,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { // store previous consensus state prevConsState := &ibctmtypes.ConsensusState{ - Height: 1, + Height: types.NewHeight(0, 1), Timestamp: suite.past, NextValidatorsHash: suite.valSetHash, } @@ -108,7 +110,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { // store intermediate consensus state to check that trustedHeight does not need to be hightest consensus state before header height intermediateConsState := &ibctmtypes.ConsensusState{ - Height: 2, + Height: types.NewHeight(0, 2), Timestamp: suite.past.Add(time.Minute), NextValidatorsHash: suite.valSetHash, } @@ -145,7 +147,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { return nil }, false}, {"frozen client before update", func() error { - clientState = &ibctmtypes.ClientState{FrozenHeight: 1, LatestHeight: testClientHeight} + clientState = &ibctmtypes.ClientState{FrozenHeight: types.NewHeight(0, 1), LatestHeight: testClientHeight} suite.keeper.SetClientState(suite.ctx, testClientID, clientState) suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint) updateHeader = createFutureUpdateFn(suite) @@ -154,13 +156,13 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { }, false}, {"valid past update before client was frozen", func() error { clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs()) - clientState.FrozenHeight = testClientHeight - 1 + clientState.FrozenHeight = types.NewHeight(0, testClientHeight.EpochHeight-1) _, err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState) suite.Require().NoError(err) // store previous consensus state prevConsState := &ibctmtypes.ConsensusState{ - Height: 1, + Height: types.NewHeight(0, 1), Timestamp: suite.past, NextValidatorsHash: suite.valSetHash, } @@ -198,7 +200,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { suite.Require().NoError(err, err) expConsensusState := &ibctmtypes.ConsensusState{ - Height: updateHeader.GetHeight(), + Height: types.NewHeight(0, updateHeader.GetHeight()), Timestamp: updateHeader.GetTime(), Root: commitmenttypes.NewMerkleRoot(updateHeader.Header.GetAppHash()), NextValidatorsHash: updateHeader.Header.NextValidatorsHash, @@ -231,7 +233,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { } func (suite *KeeperTestSuite) TestUpdateClientLocalhost() { - var localhostClient exported.ClientState = localhosttypes.NewClientState(suite.header.Header.GetChainID(), suite.ctx.BlockHeight()) + var localhostClient exported.ClientState = localhosttypes.NewClientState(suite.header.Header.GetChainID(), types.NewHeight(0, uint64(suite.ctx.BlockHeight()))) suite.ctx = suite.ctx.WithBlockHeight(suite.ctx.BlockHeight() + 1) @@ -274,8 +276,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "trusting period misbehavior should pass", &ibctmtypes.Misbehaviour{ - Header1: ibctmtypes.CreateTestHeader(testChainID, testClientHeight, testClientHeight, altTime, bothValSet, bothValSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(testChainID, testClientHeight, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: ibctmtypes.CreateTestHeader(testChainID, height, height, altTime, bothValSet, bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testChainID, height, height, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), ChainId: testChainID, ClientId: testClientID, }, @@ -291,8 +293,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "misbehavior at later height should pass", &ibctmtypes.Misbehaviour{ - Header1: ibctmtypes.CreateTestHeader(testChainID, testClientHeight+5, testClientHeight, altTime, bothValSet, valSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(testChainID, testClientHeight+5, testClientHeight, suite.ctx.BlockTime(), bothValSet, valSet, bothSigners), + Header1: ibctmtypes.CreateTestHeader(testChainID, height+5, height, altTime, bothValSet, valSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testChainID, height+5, height, suite.ctx.BlockTime(), bothValSet, valSet, bothSigners), ChainId: testChainID, ClientId: testClientID, }, @@ -303,13 +305,13 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { // store intermediate consensus state to check that trustedHeight does not need to be highest consensus state before header height intermediateConsState := &ibctmtypes.ConsensusState{ - Height: testClientHeight + 3, + Height: types.NewHeight(0, height+3), Timestamp: suite.now.Add(time.Minute), NextValidatorsHash: suite.valSetHash, } - suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight+3, intermediateConsState) + suite.keeper.SetClientConsensusState(suite.ctx, testClientID, height+3, intermediateConsState) - clientState.LatestHeight = testClientHeight + 3 + clientState.LatestHeight = types.NewHeight(0, height+3) suite.keeper.SetClientState(suite.ctx, testClientID, clientState) return err @@ -319,8 +321,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "misbehavior at later height with different trusted heights should pass", &ibctmtypes.Misbehaviour{ - Header1: ibctmtypes.CreateTestHeader(testChainID, testClientHeight+5, testClientHeight, altTime, bothValSet, valSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(testChainID, testClientHeight+5, testClientHeight+3, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: ibctmtypes.CreateTestHeader(testChainID, height+5, height, altTime, bothValSet, valSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testChainID, height+5, height+3, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), ChainId: testChainID, ClientId: testClientID, }, @@ -331,13 +333,13 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { // store trusted consensus state for Header2 intermediateConsState := &ibctmtypes.ConsensusState{ - Height: testClientHeight + 3, + Height: types.NewHeight(0, height+3), Timestamp: suite.now.Add(time.Minute), NextValidatorsHash: bothValsHash, } - suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight+3, intermediateConsState) + suite.keeper.SetClientConsensusState(suite.ctx, testClientID, height+3, intermediateConsState) - clientState.LatestHeight = testClientHeight + 3 + clientState.LatestHeight = types.NewHeight(0, height+3) suite.keeper.SetClientState(suite.ctx, testClientID, clientState) return err @@ -347,8 +349,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "misbehaviour fails validatebasic", &ibctmtypes.Misbehaviour{ - Header1: ibctmtypes.CreateTestHeader(testChainID, testClientHeight+1, testClientHeight, altTime, bothValSet, bothValSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(testChainID, testClientHeight, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: ibctmtypes.CreateTestHeader(testChainID, height+1, height, altTime, bothValSet, bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testChainID, height, height, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), ChainId: testChainID, ClientId: testClientID, }, @@ -364,8 +366,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "trusted ConsensusState1 not found", &ibctmtypes.Misbehaviour{ - Header1: ibctmtypes.CreateTestHeader(testChainID, testClientHeight+5, testClientHeight+3, altTime, bothValSet, bothValSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(testChainID, testClientHeight+5, testClientHeight, suite.ctx.BlockTime(), bothValSet, valSet, bothSigners), + Header1: ibctmtypes.CreateTestHeader(testChainID, height+5, height+3, altTime, bothValSet, bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testChainID, height+5, height, suite.ctx.BlockTime(), bothValSet, valSet, bothSigners), ChainId: testChainID, ClientId: testClientID, }, @@ -381,8 +383,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "trusted ConsensusState2 not found", &ibctmtypes.Misbehaviour{ - Header1: ibctmtypes.CreateTestHeader(testChainID, testClientHeight+5, testClientHeight, altTime, bothValSet, valSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(testChainID, testClientHeight+5, testClientHeight+3, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: ibctmtypes.CreateTestHeader(testChainID, height+5, height, altTime, bothValSet, valSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testChainID, height+5, height+3, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), ChainId: testChainID, ClientId: testClientID, }, @@ -405,8 +407,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "client already frozen at earlier height", &ibctmtypes.Misbehaviour{ - Header1: ibctmtypes.CreateTestHeader(testChainID, testClientHeight, testClientHeight, altTime, bothValSet, bothValSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(testChainID, testClientHeight, testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: ibctmtypes.CreateTestHeader(testChainID, height, height, altTime, bothValSet, bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testChainID, height, height, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), ChainId: testChainID, ClientId: testClientID, }, @@ -415,7 +417,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs()) _, err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState) - clientState.FrozenHeight = 1 + clientState.FrozenHeight = types.NewHeight(0, 1) suite.keeper.SetClientState(suite.ctx, testClientID, clientState) return err @@ -426,8 +428,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "misbehaviour check failed", &ibctmtypes.Misbehaviour{ - Header1: ibctmtypes.CreateTestHeader(testChainID, testClientHeight, testClientHeight, altTime, bothValSet, bothValSet, bothSigners), - Header2: ibctmtypes.CreateTestHeader(testChainID, testClientHeight, testClientHeight, suite.ctx.BlockTime(), altValSet, bothValSet, altSigners), + Header1: ibctmtypes.CreateTestHeader(testChainID, height, height, altTime, bothValSet, bothValSet, bothSigners), + Header2: ibctmtypes.CreateTestHeader(testChainID, height, height, suite.ctx.BlockTime(), altValSet, bothValSet, altSigners), ChainId: testChainID, ClientId: testClientID, }, diff --git a/x/ibc/02-client/keeper/grpc_query_test.go b/x/ibc/02-client/keeper/grpc_query_test.go index dcc8c4c43..14283a5d5 100644 --- a/x/ibc/02-client/keeper/grpc_query_test.go +++ b/x/ibc/02-client/keeper/grpc_query_test.go @@ -42,7 +42,7 @@ func (suite *KeeperTestSuite) TestQueryClientState() { { "success", func() { - clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()) + clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.Height{}, commitmenttypes.GetSDKSpecs()) suite.keeper.SetClientState(suite.ctx, testClientID, clientState) var err error @@ -209,7 +209,7 @@ func (suite *KeeperTestSuite) TestQueryConsensusState() { func() { clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs()) cs := ibctmtypes.NewConsensusState( - suite.consensusState.Timestamp, commitmenttypes.NewMerkleRoot([]byte("hash1")), suite.consensusState.GetHeight(), nil, + suite.consensusState.Timestamp, commitmenttypes.NewMerkleRoot([]byte("hash1")), suite.consensusState.Height, nil, ) suite.keeper.SetClientState(suite.ctx, testClientID, clientState) suite.keeper.SetClientConsensusState(suite.ctx, testClientID, suite.consensusState.GetHeight(), cs) @@ -229,9 +229,9 @@ func (suite *KeeperTestSuite) TestQueryConsensusState() { "success with height", func() { cs := ibctmtypes.NewConsensusState( - suite.consensusState.Timestamp, commitmenttypes.NewMerkleRoot([]byte("hash1")), suite.consensusState.GetHeight(), nil, + suite.consensusState.Timestamp, commitmenttypes.NewMerkleRoot([]byte("hash1")), suite.consensusState.Height, nil, ) - suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight, cs) + suite.keeper.SetClientConsensusState(suite.ctx, testClientID, height, cs) var err error expConsensusState, err = types.PackConsensusState(cs) @@ -239,7 +239,7 @@ func (suite *KeeperTestSuite) TestQueryConsensusState() { req = &types.QueryConsensusStateRequest{ ClientId: testClientID, - Height: testClientHeight, + Height: height, } }, true, @@ -311,14 +311,14 @@ func (suite *KeeperTestSuite) TestQueryConsensusStates() { "success", func() { cs := ibctmtypes.NewConsensusState( - suite.consensusState.Timestamp, commitmenttypes.NewMerkleRoot([]byte("hash1")), suite.consensusState.GetHeight(), nil, + suite.consensusState.Timestamp, commitmenttypes.NewMerkleRoot([]byte("hash1")), suite.consensusState.Height, nil, ) cs2 := ibctmtypes.NewConsensusState( - suite.consensusState.Timestamp.Add(time.Second), commitmenttypes.NewMerkleRoot([]byte("hash2")), suite.consensusState.GetHeight(), nil, + suite.consensusState.Timestamp.Add(time.Second), commitmenttypes.NewMerkleRoot([]byte("hash2")), suite.consensusState.Height, nil, ) - suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight, cs) - suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight+1, cs2) + suite.keeper.SetClientConsensusState(suite.ctx, testClientID, height, cs) + suite.keeper.SetClientConsensusState(suite.ctx, testClientID, height+1, cs2) any, err := types.PackConsensusState(cs) suite.Require().NoError(err) diff --git a/x/ibc/02-client/keeper/keeper.go b/x/ibc/02-client/keeper/keeper.go index fac2b3735..29a6ae033 100644 --- a/x/ibc/02-client/keeper/keeper.go +++ b/x/ibc/02-client/keeper/keeper.go @@ -185,6 +185,7 @@ func (k Keeper) GetClientConsensusStateLTE(ctx sdk.Context, clientID string, max // GetSelfConsensusState introspects the (self) past historical info at a given height // and returns the expected consensus state at that height. +// TODO: Replace height with *clienttypes.Height once interfaces change func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height uint64) (exported.ConsensusState, bool) { histInfo, found := k.stakingKeeper.GetHistoricalInfo(ctx, int64(height)) if !found { @@ -192,7 +193,7 @@ func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height uint64) (exported. } consensusState := &ibctmtypes.ConsensusState{ - Height: height, + Height: types.NewHeight(0, height), Timestamp: histInfo.Header.Time, Root: commitmenttypes.NewMerkleRoot(histInfo.Header.GetAppHash()), NextValidatorsHash: histInfo.Header.NextValidatorsHash, @@ -218,7 +219,10 @@ func (k Keeper) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientS ctx.ChainID(), tmClient.ChainId) } - if tmClient.LatestHeight > uint64(ctx.BlockHeight()) { + // For now, assume epoch number is zero + // TODO: Retrieve epoch number from chain-id + selfHeight := types.NewHeight(0, uint64(ctx.BlockHeight())) + if tmClient.LatestHeight.GT(selfHeight) { return sdkerrors.Wrapf(types.ErrInvalidClient, "client has LatestHeight %d greater than chain height %d", tmClient.LatestHeight, ctx.BlockHeight()) } diff --git a/x/ibc/02-client/keeper/keeper_test.go b/x/ibc/02-client/keeper/keeper_test.go index 423fb3136..af87b5eb1 100644 --- a/x/ibc/02-client/keeper/keeper_test.go +++ b/x/ibc/02-client/keeper/keeper_test.go @@ -32,13 +32,15 @@ const ( testClientID2 = "ethbridge" testClientID3 = "ethermint" - testClientHeight = 5 + height = 5 trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 maxClockDrift time.Duration = time.Second * 10 ) +var testClientHeight = types.NewHeight(0, 5) + type KeeperTestSuite struct { suite.Suite @@ -74,7 +76,7 @@ func (suite *KeeperTestSuite) SetupTest() { app := simapp.Setup(isCheckTx) suite.cdc = app.AppCodec() - suite.ctx = app.BaseApp.NewContext(isCheckTx, tmproto.Header{Height: testClientHeight, ChainID: testClientID, Time: now2}) + suite.ctx = app.BaseApp.NewContext(isCheckTx, tmproto.Header{Height: height, ChainID: testClientID, Time: now2}) suite.keeper = &app.IBCKeeper.ClientKeeper suite.privVal = tmtypes.NewMockPV() @@ -84,7 +86,7 @@ func (suite *KeeperTestSuite) SetupTest() { validator := tmtypes.NewValidator(pubKey, 1) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) suite.valSetHash = suite.valSet.Hash() - suite.header = ibctmtypes.CreateTestHeader(testChainID, testClientHeight, testClientHeight-1, now2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.header = ibctmtypes.CreateTestHeader(testChainID, height, height-1, now2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) suite.consensusState = ibctmtypes.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot([]byte("hash")), testClientHeight, suite.valSetHash) var validators stakingtypes.Validators @@ -110,7 +112,7 @@ func TestKeeperTestSuite(t *testing.T) { } func (suite *KeeperTestSuite) TestSetClientState() { - clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()) + clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.Height{}, commitmenttypes.GetSDKSpecs()) suite.keeper.SetClientState(suite.ctx, testClientID, clientState) retrievedState, found := suite.keeper.GetClientState(suite.ctx, testClientID) @@ -127,9 +129,9 @@ func (suite *KeeperTestSuite) TestSetClientType() { } func (suite *KeeperTestSuite) TestSetClientConsensusState() { - suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight, suite.consensusState) + suite.keeper.SetClientConsensusState(suite.ctx, testClientID, height, suite.consensusState) - retrievedConsState, found := suite.keeper.GetClientConsensusState(suite.ctx, testClientID, testClientHeight) + retrievedConsState, found := suite.keeper.GetClientConsensusState(suite.ctx, testClientID, height) suite.Require().True(found, "GetConsensusState failed") tmConsState, ok := retrievedConsState.(*ibctmtypes.ConsensusState) @@ -145,7 +147,7 @@ func (suite *KeeperTestSuite) TestValidateSelfClient() { }{ { "success", - ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, uint64(testClientHeight), commitmenttypes.GetSDKSpecs()), + ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs()), true, }, { @@ -155,43 +157,43 @@ func (suite *KeeperTestSuite) TestValidateSelfClient() { }, { "frozen client", - &ibctmtypes.ClientState{testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, uint64(testClientHeight), uint64(testClientHeight), commitmenttypes.GetSDKSpecs()}, + &ibctmtypes.ClientState{testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, testClientHeight, commitmenttypes.GetSDKSpecs()}, false, }, { "incorrect chainID", - ibctmtypes.NewClientState("gaiatestnet", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, uint64(testClientHeight), commitmenttypes.GetSDKSpecs()), + ibctmtypes.NewClientState("gaiatestnet", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs()), false, }, { "invalid client height", - ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, uint64(testClientHeight)+10, commitmenttypes.GetSDKSpecs()), + ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.NewHeight(0, testClientHeight.EpochHeight+10), commitmenttypes.GetSDKSpecs()), false, }, { "invalid proof specs", - ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, uint64(testClientHeight), nil), + ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, nil), false, }, { "invalid trust level", - ibctmtypes.NewClientState(testChainID, ibctmtypes.Fraction{0, 1}, trustingPeriod, ubdPeriod, maxClockDrift, uint64(testClientHeight), commitmenttypes.GetSDKSpecs()), + ibctmtypes.NewClientState(testChainID, ibctmtypes.Fraction{0, 1}, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs()), false, }, { "invalid unbonding period", - ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+10, maxClockDrift, uint64(testClientHeight), commitmenttypes.GetSDKSpecs()), + ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+10, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs()), false, }, { "invalid trusting period", - ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, ubdPeriod+10, ubdPeriod, maxClockDrift, uint64(testClientHeight), commitmenttypes.GetSDKSpecs()), + ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, ubdPeriod+10, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs()), false, }, } ctx := suite.ctx.WithChainID(testChainID) - ctx = ctx.WithBlockHeight(testClientHeight) + ctx = ctx.WithBlockHeight(height) for _, tc := range testCases { err := suite.keeper.ValidateSelfClient(ctx, tc.clientState) @@ -208,9 +210,9 @@ func (suite KeeperTestSuite) TestGetAllClients() { testClientID2, testClientID3, testClientID, } expClients := []exported.ClientState{ - ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()), - ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()), - ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()), + ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.Height{}, commitmenttypes.GetSDKSpecs()), + ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.Height{}, commitmenttypes.GetSDKSpecs()), + ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.Height{}, commitmenttypes.GetSDKSpecs()), } for i := range expClients { @@ -232,9 +234,9 @@ func (suite KeeperTestSuite) TestGetAllGenesisClients() { testClientID2, testClientID3, testClientID, } expClients := []exported.ClientState{ - ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()), - ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()), - ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()), + ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.Height{}, commitmenttypes.GetSDKSpecs()), + ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.Height{}, commitmenttypes.GetSDKSpecs()), + ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.Height{}, commitmenttypes.GetSDKSpecs()), } expGenClients := make([]types.IdentifiedClientState, len(expClients)) @@ -285,16 +287,16 @@ func (suite KeeperTestSuite) TestConsensusStateHelpers() { clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs()) suite.keeper.SetClientState(suite.ctx, testClientID, clientState) - suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight, suite.consensusState) + suite.keeper.SetClientConsensusState(suite.ctx, testClientID, height, suite.consensusState) - nextState := ibctmtypes.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot([]byte("next")), testClientHeight+5, suite.valSetHash) + nextState := ibctmtypes.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot([]byte("next")), types.NewHeight(0, height+5), suite.valSetHash) - header := ibctmtypes.CreateTestHeader(testClientID, testClientHeight+5, testClientHeight, suite.header.Header.Time.Add(time.Minute), + header := ibctmtypes.CreateTestHeader(testClientID, height+5, height, suite.header.Header.Time.Add(time.Minute), suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) // mock update functionality - clientState.LatestHeight = header.GetHeight() - suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight+5, nextState) + clientState.LatestHeight = types.NewHeight(0, header.GetHeight()) + suite.keeper.SetClientConsensusState(suite.ctx, testClientID, height+5, nextState) suite.keeper.SetClientState(suite.ctx, testClientID, clientState) latest, ok := suite.keeper.GetLatestClientConsensusState(suite.ctx, testClientID) @@ -302,24 +304,24 @@ func (suite KeeperTestSuite) TestConsensusStateHelpers() { suite.Require().Equal(nextState, latest, "Latest client not returned correctly") // Should return existing consensusState at latestClientHeight - lte, ok := suite.keeper.GetClientConsensusStateLTE(suite.ctx, testClientID, testClientHeight+3) + lte, ok := suite.keeper.GetClientConsensusStateLTE(suite.ctx, testClientID, height+3) suite.Require().True(ok) - suite.Require().Equal(suite.consensusState, lte, "LTE helper function did not return latest client state below height: %d", testClientHeight+3) + suite.Require().Equal(suite.consensusState, lte, "LTE helper function did not return latest client state below height: %d", height+3) } func (suite KeeperTestSuite) TestGetAllConsensusStates() { expConsensus := []exported.ConsensusState{ ibctmtypes.NewConsensusState( - suite.consensusState.Timestamp, commitmenttypes.NewMerkleRoot([]byte("hash")), suite.consensusState.GetHeight(), nil, + suite.consensusState.Timestamp, commitmenttypes.NewMerkleRoot([]byte("hash")), suite.consensusState.Height, nil, ), ibctmtypes.NewConsensusState( - suite.consensusState.Timestamp.Add(time.Minute), commitmenttypes.NewMerkleRoot([]byte("app_hash")), suite.consensusState.GetHeight()+1, nil, + suite.consensusState.Timestamp.Add(time.Minute), commitmenttypes.NewMerkleRoot([]byte("app_hash")), suite.consensusState.Height.Increment(), nil, ), } expConsensus2 := []exported.ConsensusState{ ibctmtypes.NewConsensusState( - suite.consensusState.Timestamp.Add(2*time.Minute), commitmenttypes.NewMerkleRoot([]byte("app_hash_2")), suite.consensusState.GetHeight()+2, nil, + suite.consensusState.Timestamp.Add(2*time.Minute), commitmenttypes.NewMerkleRoot([]byte("app_hash_2")), types.NewHeight(0, suite.consensusState.GetHeight()+2), nil, ), } diff --git a/x/ibc/02-client/simulation/decoder_test.go b/x/ibc/02-client/simulation/decoder_test.go index f016d0f15..b0cae2a12 100644 --- a/x/ibc/02-client/simulation/decoder_test.go +++ b/x/ibc/02-client/simulation/decoder_test.go @@ -11,6 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/kv" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/02-client/simulation" + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) @@ -20,11 +21,11 @@ func TestDecodeStore(t *testing.T) { clientID := "clientidone" clientState := &ibctmtypes.ClientState{ - FrozenHeight: 10, + FrozenHeight: types.NewHeight(0, 10), } consState := &ibctmtypes.ConsensusState{ - Height: 10, + Height: types.NewHeight(0, 10), Timestamp: time.Now().UTC(), } diff --git a/x/ibc/02-client/types/client.pb.go b/x/ibc/02-client/types/client.pb.go index a380e095e..639a9e52f 100644 --- a/x/ibc/02-client/types/client.pb.go +++ b/x/ibc/02-client/types/client.pb.go @@ -134,15 +134,77 @@ func (m *ClientConsensusStates) GetConsensusStates() []*types.Any { return nil } +// Height is a monotonically increasing data type +// that can be compared against another Height for the purposes of updating and freezing clients +// +// Normally the EpochHeight is incremented at each height while keeping epoch number the same +// However some consensus algorithms may choose to reset the height in certain conditions +// e.g. hard forks, state-machine breaking changes +// In these cases, the epoch number is incremented so that height continues to be monitonically increasing +// even as the EpochHeight gets reset +type Height struct { + // the epoch that the client is currently on + EpochNumber uint64 `protobuf:"varint,1,opt,name=epoch_number,json=epochNumber,proto3" json:"epoch_number,omitempty" yaml:"epoch_number"` + // the height within the given epoch + EpochHeight uint64 `protobuf:"varint,2,opt,name=epoch_height,json=epochHeight,proto3" json:"epoch_height,omitempty" yaml:"epoch_height"` +} + +func (m *Height) Reset() { *m = Height{} } +func (*Height) ProtoMessage() {} +func (*Height) Descriptor() ([]byte, []int) { + return fileDescriptor_226f80e576f20abd, []int{2} +} +func (m *Height) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Height) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Height.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Height) XXX_Merge(src proto.Message) { + xxx_messageInfo_Height.Merge(m, src) +} +func (m *Height) XXX_Size() int { + return m.Size() +} +func (m *Height) XXX_DiscardUnknown() { + xxx_messageInfo_Height.DiscardUnknown(m) +} + +var xxx_messageInfo_Height proto.InternalMessageInfo + +func (m *Height) GetEpochNumber() uint64 { + if m != nil { + return m.EpochNumber + } + return 0 +} + +func (m *Height) GetEpochHeight() uint64 { + if m != nil { + return m.EpochHeight + } + return 0 +} + func init() { proto.RegisterType((*IdentifiedClientState)(nil), "ibc.client.IdentifiedClientState") proto.RegisterType((*ClientConsensusStates)(nil), "ibc.client.ClientConsensusStates") + proto.RegisterType((*Height)(nil), "ibc.client.Height") } func init() { proto.RegisterFile("ibc/client/client.proto", fileDescriptor_226f80e576f20abd) } var fileDescriptor_226f80e576f20abd = []byte{ - // 314 bytes of a gzipped FileDescriptorProto + // 378 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xcf, 0x4c, 0x4a, 0xd6, 0x4f, 0xce, 0xc9, 0x4c, 0xcd, 0x2b, 0x81, 0x52, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x5c, 0x99, 0x49, 0xc9, 0x7a, 0x10, 0x11, 0x29, 0x91, 0xf4, 0xfc, 0xf4, 0x7c, 0xb0, 0xb0, 0x3e, 0x88, @@ -157,12 +219,16 @@ var fileDescriptor_226f80e576f20abd = []byte{ 0xc8, 0x25, 0x0a, 0x71, 0x94, 0x73, 0x7e, 0x5e, 0x71, 0x6a, 0x5e, 0x71, 0x69, 0x31, 0x58, 0xa2, 0x98, 0x1c, 0xe7, 0xc5, 0x70, 0x09, 0x24, 0xc3, 0x4c, 0x81, 0xd8, 0x56, 0x2c, 0xc1, 0xa4, 0xc0, 0x8c, 0xd3, 0x89, 0xd2, 0x9f, 0xee, 0xc9, 0x8b, 0x43, 0xcd, 0x43, 0xd3, 0xa7, 0x14, 0xc4, 0x9f, - 0x8c, 0xea, 0x20, 0x27, 0x9f, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, - 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x32, - 0x4a, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0xce, 0xcd, - 0x2f, 0x86, 0x52, 0xba, 0xc5, 0x29, 0xd9, 0xfa, 0x15, 0xfa, 0xa0, 0x88, 0x35, 0x30, 0xd2, 0x85, - 0xc6, 0x6d, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x25, 0xc6, 0x80, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x38, 0x45, 0x52, 0x5c, 0xf6, 0x01, 0x00, 0x00, + 0x8c, 0xea, 0x20, 0xa5, 0x36, 0x46, 0x2e, 0x36, 0x8f, 0xd4, 0xcc, 0xf4, 0x8c, 0x12, 0x21, 0x2b, + 0x2e, 0x9e, 0xd4, 0x82, 0xfc, 0xe4, 0x8c, 0xf8, 0xbc, 0xd2, 0xdc, 0xa4, 0xd4, 0x22, 0xb0, 0xf3, + 0x58, 0x90, 0x7d, 0x8c, 0x2c, 0xab, 0x14, 0xc4, 0x0d, 0xe6, 0xfa, 0x81, 0x79, 0x08, 0xbd, 0x19, + 0x60, 0xb3, 0xc0, 0x61, 0x88, 0x45, 0x2f, 0x44, 0x16, 0xa6, 0x17, 0x62, 0xaf, 0x15, 0xcb, 0x8c, + 0x05, 0xf2, 0x0c, 0x4e, 0x3e, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, + 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0x65, + 0x94, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x9f, 0x9c, 0x5f, 0x9c, 0x9b, + 0x5f, 0x0c, 0xa5, 0x74, 0x8b, 0x53, 0xb2, 0xf5, 0x2b, 0xf4, 0x41, 0x29, 0xcc, 0xc0, 0x48, 0x17, + 0x9a, 0xc8, 0x4a, 0x2a, 0x0b, 0x52, 0x8b, 0x93, 0xd8, 0xc0, 0x41, 0x62, 0x0c, 0x08, 0x00, 0x00, + 0xff, 0xff, 0x55, 0xfb, 0xf5, 0xfb, 0x7f, 0x02, 0x00, 0x00, } func (m *IdentifiedClientState) Marshal() (dAtA []byte, err error) { @@ -251,6 +317,39 @@ func (m *ClientConsensusStates) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *Height) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Height) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Height) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.EpochHeight != 0 { + i = encodeVarintClient(dAtA, i, uint64(m.EpochHeight)) + i-- + dAtA[i] = 0x10 + } + if m.EpochNumber != 0 { + i = encodeVarintClient(dAtA, i, uint64(m.EpochNumber)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func encodeVarintClient(dAtA []byte, offset int, v uint64) int { offset -= sovClient(v) base := offset @@ -298,6 +397,21 @@ func (m *ClientConsensusStates) Size() (n int) { return n } +func (m *Height) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.EpochNumber != 0 { + n += 1 + sovClient(uint64(m.EpochNumber)) + } + if m.EpochHeight != 0 { + n += 1 + sovClient(uint64(m.EpochHeight)) + } + return n +} + func sovClient(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -544,6 +658,97 @@ func (m *ClientConsensusStates) Unmarshal(dAtA []byte) error { } return nil } +func (m *Height) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClient + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Height: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Height: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EpochNumber", wireType) + } + m.EpochNumber = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClient + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EpochNumber |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EpochHeight", wireType) + } + m.EpochHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClient + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EpochHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipClient(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthClient + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthClient + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipClient(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/ibc/02-client/types/codec_test.go b/x/ibc/02-client/types/codec_test.go index 0264f26d2..d0de10127 100644 --- a/x/ibc/02-client/types/codec_test.go +++ b/x/ibc/02-client/types/codec_test.go @@ -12,7 +12,7 @@ import ( ) func TestPackClientState(t *testing.T) { - clientState := localhosttypes.NewClientState(chainID, height) + clientState := localhosttypes.NewClientState(chainID, clientHeight) clientAny, err := types.PackClientState(clientState) require.NoError(t, err, "pack clientstate should not return error") @@ -27,7 +27,7 @@ func TestPackClientState(t *testing.T) { } func TestPackConsensusState(t *testing.T) { - consensusState := ibctmtypes.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("root")), height, []byte("nextvalshash")) + consensusState := ibctmtypes.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("root")), clientHeight, []byte("nextvalshash")) consensusAny, err := types.PackConsensusState(consensusState) require.NoError(t, err, "pack consensusstate should not return error") diff --git a/x/ibc/02-client/types/genesis_test.go b/x/ibc/02-client/types/genesis_test.go index e7471bc57..892cb5a46 100644 --- a/x/ibc/02-client/types/genesis_test.go +++ b/x/ibc/02-client/types/genesis_test.go @@ -22,6 +22,8 @@ const ( height = 10 ) +var clientHeight = types.NewHeight(0, 10) + func TestValidateGenesis(t *testing.T) { privVal := tmtypes.NewMockPV() pubKey, err := privVal.GetPubKey() @@ -49,10 +51,10 @@ func TestValidateGenesis(t *testing.T) { genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - clientID, ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, height, commitmenttypes.GetSDKSpecs()), + clientID, ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs()), ), types.NewIdentifiedClientState( - exported.ClientTypeLocalHost, localhosttypes.NewClientState("chainID", 10), + exported.ClientTypeLocalHost, localhosttypes.NewClientState("chainID", clientHeight), ), }, []types.ClientConsensusStates{ @@ -60,7 +62,7 @@ func TestValidateGenesis(t *testing.T) { clientID, []exported.ConsensusState{ ibctmtypes.NewConsensusState( - header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.GetHeight(), header.Header.NextValidatorsHash, + header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), types.NewHeight(0, header.GetHeight()), header.Header.NextValidatorsHash, ), }, ), @@ -74,10 +76,10 @@ func TestValidateGenesis(t *testing.T) { genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - "/~@$*", ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, height, commitmenttypes.GetSDKSpecs()), + "/~@$*", ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs()), ), types.NewIdentifiedClientState( - exported.ClientTypeLocalHost, localhosttypes.NewClientState("chainID", 10), + exported.ClientTypeLocalHost, localhosttypes.NewClientState("chainID", clientHeight), ), }, []types.ClientConsensusStates{ @@ -85,7 +87,7 @@ func TestValidateGenesis(t *testing.T) { clientID, []exported.ConsensusState{ ibctmtypes.NewConsensusState( - header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.GetHeight(), header.Header.NextValidatorsHash, + header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), types.NewHeight(0, header.GetHeight()), header.Header.NextValidatorsHash, ), }, ), @@ -99,9 +101,9 @@ func TestValidateGenesis(t *testing.T) { genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, height, commitmenttypes.GetSDKSpecs()), + clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs()), ), - types.NewIdentifiedClientState(exported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", 0)), + types.NewIdentifiedClientState(exported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", types.Height{})), }, nil, true, @@ -113,10 +115,10 @@ func TestValidateGenesis(t *testing.T) { genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, height, commitmenttypes.GetSDKSpecs()), + clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs()), ), types.NewIdentifiedClientState( - exported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", 10), + exported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", clientHeight), ), }, []types.ClientConsensusStates{ @@ -124,7 +126,7 @@ func TestValidateGenesis(t *testing.T) { "(CLIENTID2)", []exported.ConsensusState{ ibctmtypes.NewConsensusState( - header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), 0, header.Header.NextValidatorsHash, + header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), types.Height{}, header.Header.NextValidatorsHash, ), }, ), @@ -138,10 +140,10 @@ func TestValidateGenesis(t *testing.T) { genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, height, commitmenttypes.GetSDKSpecs()), + clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs()), ), types.NewIdentifiedClientState( - exported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", 10), + exported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", clientHeight), ), }, []types.ClientConsensusStates{ @@ -149,7 +151,7 @@ func TestValidateGenesis(t *testing.T) { clientID, []exported.ConsensusState{ ibctmtypes.NewConsensusState( - header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), 0, header.Header.NextValidatorsHash, + header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), types.Height{}, header.Header.NextValidatorsHash, ), }, ), diff --git a/x/ibc/02-client/types/height.go b/x/ibc/02-client/types/height.go new file mode 100644 index 000000000..d640df98a --- /dev/null +++ b/x/ibc/02-client/types/height.go @@ -0,0 +1,99 @@ +package types + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" +) + +var _ exported.Height = (*Height)(nil) + +// NewHeight is a constructor for the IBC height type +func NewHeight(epochNumber, epochHeight uint64) Height { + return Height{ + EpochNumber: epochNumber, + EpochHeight: epochHeight, + } +} + +/// Compare implements a method to compare two heights. When comparing two heights a, b +// we can call a.Compare(b) which will return +// -1 if a < b +// 0 if a = b +// 1 if a > b +// +// It first compares based on epoch numbers, whichever has the higher epoch number is the higher height +// If epoch number is the same, then the epoch height is compared +func (h Height) Compare(other exported.Height) int64 { + height, ok := other.(Height) + if !ok { + panic(fmt.Sprintf("cannot compare against invalid height type: %T. expected height type: %T", other, h)) + } + var cmp int64 + if h.EpochNumber != height.EpochNumber { + cmp = int64(h.EpochNumber) - int64(height.EpochNumber) + } else { + cmp = int64(h.EpochHeight) - int64(height.EpochHeight) + } + if cmp < 0 { + return -1 + } else if cmp > 0 { + return 1 + } + return 0 +} + +// LT Helper comparison function returns true if h < other +func (h Height) LT(other exported.Height) bool { + return h.Compare(other) == -1 +} + +// LTE Helper comparison function returns true if h <= other +func (h Height) LTE(other exported.Height) bool { + cmp := h.Compare(other) + return cmp <= 0 +} + +// GT Helper comparison function returns true if h > other +func (h Height) GT(other exported.Height) bool { + return h.Compare(other) == 1 +} + +// GTE Helper comparison function returns true if h >= other +func (h Height) GTE(other exported.Height) bool { + cmp := h.Compare(other) + return cmp >= 0 +} + +// EQ Helper comparison function returns true if h == other +func (h Height) EQ(other exported.Height) bool { + return h.Compare(other) == 0 +} + +// String returns a string representation of Height +func (h Height) String() string { + return fmt.Sprintf("epoch-%d-height-%d", h.EpochNumber, h.EpochHeight) +} + +// Decrement will return a decremented height from the given height. If this is not possible, +// an error is returned +// Decrement will return a new height with the EpochHeight decremented +// If the EpochHeight is already at lowest value (1), then false success flag is returend +func (h Height) Decrement() (decremented Height, success bool) { + if h.EpochHeight == 0 { + return Height{}, false + } + return NewHeight(h.EpochNumber, h.EpochHeight-1), true +} + +// Increment will return an incremented height from the given height. +// Increment will return a height with the same epoch number but an +// incremented epoch height +func (h Height) Increment() Height { + return NewHeight(h.EpochNumber, h.EpochHeight+1) +} + +// IsZero returns true if height epoch and epoch-height are both 0 +func (h Height) IsZero() bool { + return h.EpochNumber == 0 && h.EpochHeight == 0 +} diff --git a/x/ibc/02-client/types/height_test.go b/x/ibc/02-client/types/height_test.go new file mode 100644 index 000000000..89fa0c8ea --- /dev/null +++ b/x/ibc/02-client/types/height_test.go @@ -0,0 +1,55 @@ +package types_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + "github.com/stretchr/testify/require" +) + +func TestCompareHeights(t *testing.T) { + testCases := []struct { + name string + height1 types.Height + height2 types.Height + compareSign int64 + }{ + {"epoch number 1 is lesser", types.NewHeight(1, 3), types.NewHeight(3, 4), -1}, + {"epoch number 1 is greater", types.NewHeight(7, 5), types.NewHeight(4, 5), 1}, + {"epoch height 1 is lesser", types.NewHeight(3, 4), types.NewHeight(3, 9), -1}, + {"epoch height 1 is greater", types.NewHeight(3, 8), types.NewHeight(3, 3), 1}, + {"height is equal", types.NewHeight(4, 4), types.NewHeight(4, 4), 0}, + } + + for i, tc := range testCases { + compare := tc.height1.Compare(tc.height2) + + switch tc.compareSign { + case -1: + require.True(t, compare == -1, "case %d: %s should return negative value on comparison, got: %d", + i, tc.name, compare) + case 0: + require.True(t, compare == 0, "case %d: %s should return zero on comparison, got: %d", + i, tc.name, compare) + case 1: + require.True(t, compare == 1, "case %d: %s should return positive value on comparison, got: %d", + i, tc.name, compare) + } + } +} + +func TestDecrement(t *testing.T) { + validDecrement := types.NewHeight(3, 3) + expected := types.NewHeight(3, 2) + + actual, success := validDecrement.Decrement() + require.Equal(t, expected, actual, "decrementing %s did not return expected height: %s. got %s", + validDecrement, expected, actual) + require.True(t, success, "decrement failed unexpectedly") + + invalidDecrement := types.NewHeight(3, 0) + actual, success = invalidDecrement.Decrement() + + require.Equal(t, types.Height{}, actual, "invalid decrement returned non-zero height: %s", actual) + require.False(t, success, "invalid decrement passed") +} diff --git a/x/ibc/03-connection/keeper/handshake_test.go b/x/ibc/03-connection/keeper/handshake_test.go index bbb2e1289..c00936eaf 100644 --- a/x/ibc/03-connection/keeper/handshake_test.go +++ b/x/ibc/03-connection/keeper/handshake_test.go @@ -155,7 +155,7 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { // modify counterparty client without setting in store so it still passes validate but fails proof verification tmClient, ok := counterpartyClient.(*ibctmtypes.ClientState) suite.Require().True(ok) - tmClient.LatestHeight++ + tmClient.LatestHeight = tmClient.LatestHeight.Increment() }, false}, {"consensus state verification failed", func() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, clientexported.Tendermint) @@ -171,7 +171,7 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { suite.Require().True(ok) tmConsState.Timestamp = time.Now() - suite.chainA.App.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), clientA, tmConsState.Height, tmConsState) + suite.chainA.App.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), clientA, tmConsState.GetHeight(), tmConsState) _, _, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) suite.Require().NoError(err) @@ -413,7 +413,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { // modify counterparty client without setting in store so it still passes validate but fails proof verification tmClient, ok := counterpartyClient.(*ibctmtypes.ClientState) suite.Require().True(ok) - tmClient.LatestHeight++ + tmClient.LatestHeight = tmClient.LatestHeight.Increment() err = suite.coordinator.ConnOpenTry(suite.chainB, suite.chainA, connB, connA) suite.Require().NoError(err) @@ -434,7 +434,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { suite.Require().True(ok) tmConsState.Timestamp = time.Now() - suite.chainB.App.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.chainB.GetContext(), clientB, tmConsState.Height, tmConsState) + suite.chainB.App.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.chainB.GetContext(), clientB, tmConsState.GetHeight(), tmConsState) err = suite.coordinator.ConnOpenTry(suite.chainB, suite.chainA, connB, connA) suite.Require().NoError(err) diff --git a/x/ibc/03-connection/keeper/verify_test.go b/x/ibc/03-connection/keeper/verify_test.go index 90d4abfc3..8dce5b279 100644 --- a/x/ibc/03-connection/keeper/verify_test.go +++ b/x/ibc/03-connection/keeper/verify_test.go @@ -103,7 +103,7 @@ func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { suite.Require().True(ok) tmConsState.Timestamp = time.Now() - suite.chainB.App.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.chainB.GetContext(), clientB, tmConsState.Height, tmConsState) + suite.chainB.App.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.chainB.GetContext(), clientB, tmConsState.GetHeight(), tmConsState) suite.coordinator.CommitBlock(suite.chainB) }, false}, diff --git a/x/ibc/03-connection/types/connection_test.go b/x/ibc/03-connection/types/connection_test.go index 8f0f2fd52..07eb366ee 100644 --- a/x/ibc/03-connection/types/connection_test.go +++ b/x/ibc/03-connection/types/connection_test.go @@ -5,6 +5,7 @@ import ( "github.com/stretchr/testify/require" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing" @@ -16,7 +17,7 @@ var ( clientID = "clientidone" connectionID2 = "connectionidtwo" clientID2 = "clientidtwo" - clientHeight = uint64(6) + clientHeight = clienttypes.NewHeight(0, 6) ) func TestConnectionValidateBasic(t *testing.T) { diff --git a/x/ibc/03-connection/types/msgs_test.go b/x/ibc/03-connection/types/msgs_test.go index 42d36e7bd..724220881 100644 --- a/x/ibc/03-connection/types/msgs_test.go +++ b/x/ibc/03-connection/types/msgs_test.go @@ -119,7 +119,7 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { // invalidClientState fails validateBasic invalidClient := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, 0, commitmenttypes.GetSDKSpecs(), + chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), ) testMsgs := []*types.MsgConnectionOpenTry{ @@ -190,7 +190,7 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenAck() { // invalidClientState fails validateBasic invalidClient := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, 0, commitmenttypes.GetSDKSpecs(), + chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), ) testMsgs := []*types.MsgConnectionOpenAck{ diff --git a/x/ibc/07-tendermint/types/client_state.go b/x/ibc/07-tendermint/types/client_state.go index 22e1a8845..4c1f07a0a 100644 --- a/x/ibc/07-tendermint/types/client_state.go +++ b/x/ibc/07-tendermint/types/client_state.go @@ -27,7 +27,7 @@ var _ clientexported.ClientState = (*ClientState)(nil) func NewClientState( chainID string, trustLevel Fraction, trustingPeriod, ubdPeriod, maxClockDrift time.Duration, - latestHeight uint64, specs []*ics23.ProofSpec, + latestHeight clienttypes.Height, specs []*ics23.ProofSpec, ) *ClientState { return &ClientState{ ChainId: chainID, @@ -36,7 +36,7 @@ func NewClientState( UnbondingPeriod: ubdPeriod, MaxClockDrift: maxClockDrift, LatestHeight: latestHeight, - FrozenHeight: 0, + FrozenHeight: clienttypes.Height{}, ProofSpecs: specs, } } @@ -52,19 +52,21 @@ func (cs ClientState) ClientType() clientexported.ClientType { } // GetLatestHeight returns latest block height. +// TODO: return clienttypes.Height once interface has changed func (cs ClientState) GetLatestHeight() uint64 { - return cs.LatestHeight + return cs.LatestHeight.EpochHeight } // IsFrozen returns true if the frozen height has been set. func (cs ClientState) IsFrozen() bool { - return cs.FrozenHeight != 0 + return !cs.FrozenHeight.IsZero() } -// FrozenHeight returns the height at which client is frozen +// GetFrozenHeight returns the height at which client is frozen // NOTE: FrozenHeight is 0 if client is unfrozen +// TODO: return clienttypes.Height once interface has changed func (cs ClientState) GetFrozenHeight() uint64 { - return cs.FrozenHeight + return cs.FrozenHeight.EpochHeight } // Validate performs a basic validation of the client state fields. @@ -84,8 +86,8 @@ func (cs ClientState) Validate() error { if cs.MaxClockDrift == 0 { return sdkerrors.Wrap(ErrInvalidMaxClockDrift, "max clock drift cannot be zero") } - if cs.LatestHeight == 0 { - return sdkerrors.Wrap(ErrInvalidHeaderHeight, "tendermint height cannot be zero") + if cs.LatestHeight.EpochHeight == 0 { + return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "tendermint epoch height cannot be zero") } if cs.TrustingPeriod >= cs.UnbondingPeriod { return sdkerrors.Wrapf( @@ -413,7 +415,7 @@ func produceVerificationArgs( ) } - if cs.IsFrozen() && cs.FrozenHeight <= height { + if cs.IsFrozen() && !cs.FrozenHeight.GT(clienttypes.NewHeight(0, height)) { return commitmenttypes.MerkleProof{}, nil, clienttypes.ErrClientFrozen } diff --git a/x/ibc/07-tendermint/types/client_state_test.go b/x/ibc/07-tendermint/types/client_state_test.go index 574f9f8f5..d89875f89 100644 --- a/x/ibc/07-tendermint/types/client_state_test.go +++ b/x/ibc/07-tendermint/types/client_state_test.go @@ -4,6 +4,7 @@ import ( ics23 "github.com/confio/ics23/go" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" @@ -61,7 +62,7 @@ func (suite *TendermintTestSuite) TestValidate() { }, { name: "invalid height", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, 0, commitmenttypes.GetSDKSpecs()), + clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.Height{}, commitmenttypes.GetSDKSpecs()), expPass: false, }, { @@ -130,7 +131,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { }, { name: "client is frozen", - clientState: &types.ClientState{LatestHeight: height, FrozenHeight: height - 1}, + clientState: &types.ClientState{LatestHeight: height, FrozenHeight: clienttypes.NewHeight(height.EpochNumber, height.EpochHeight-1)}, consensusState: types.ConsensusState{ Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), }, @@ -154,7 +155,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { tc := tc err := tc.clientState.VerifyClientConsensusState( - nil, suite.cdc, tc.consensusState.Root, height, "chainA", tc.consensusState.GetHeight(), tc.prefix, tc.proof, tc.consensusState, + nil, suite.cdc, tc.consensusState.Root, height.EpochHeight, "chainA", tc.consensusState.GetHeight(), tc.prefix, tc.proof, tc.consensusState, ) if tc.expPass { @@ -190,12 +191,12 @@ func (suite *TendermintTestSuite) TestVerifyConnectionState() { }, { "latest client height < height", func() { - proofHeight = clientState.LatestHeight + 1 + proofHeight = clientState.LatestHeight.EpochHeight + 1 }, false, }, { "client is frozen", func() { - clientState.FrozenHeight = 1 + clientState.FrozenHeight = clienttypes.NewHeight(0, 1) }, false, }, { @@ -268,12 +269,12 @@ func (suite *TendermintTestSuite) TestVerifyChannelState() { }, { "latest client height < height", func() { - proofHeight = clientState.LatestHeight + 1 + proofHeight = clientState.LatestHeight.EpochHeight + 1 }, false, }, { "client is frozen", func() { - clientState.FrozenHeight = 1 + clientState.FrozenHeight = clienttypes.NewHeight(0, 1) }, false, }, { @@ -347,12 +348,12 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { }, { "latest client height < height", func() { - proofHeight = clientState.LatestHeight + 1 + proofHeight = clientState.LatestHeight.EpochHeight + 1 }, false, }, { "client is frozen", func() { - clientState.FrozenHeight = 1 + clientState.FrozenHeight = clienttypes.NewHeight(0, 1) }, false, }, { @@ -429,12 +430,12 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { }, { "latest client height < height", func() { - proofHeight = clientState.LatestHeight + 1 + proofHeight = clientState.LatestHeight.EpochHeight + 1 }, false, }, { "client is frozen", func() { - clientState.FrozenHeight = 1 + clientState.FrozenHeight = clienttypes.NewHeight(0, 1) }, false, }, { @@ -517,12 +518,12 @@ func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgementAbsence() { }, { "latest client height < height", func() { - proofHeight = clientState.LatestHeight + 1 + proofHeight = clientState.LatestHeight.EpochHeight + 1 }, false, }, { "client is frozen", func() { - clientState.FrozenHeight = 1 + clientState.FrozenHeight = clienttypes.NewHeight(0, 1) }, false, }, { @@ -604,12 +605,12 @@ func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() { }, { "latest client height < height", func() { - proofHeight = clientState.LatestHeight + 1 + proofHeight = clientState.LatestHeight.EpochHeight + 1 }, false, }, { "client is frozen", func() { - clientState.FrozenHeight = 1 + clientState.FrozenHeight = clienttypes.NewHeight(0, 1) }, false, }, { diff --git a/x/ibc/07-tendermint/types/consensus_state.go b/x/ibc/07-tendermint/types/consensus_state.go index 6f5b6a390..365f60e2d 100644 --- a/x/ibc/07-tendermint/types/consensus_state.go +++ b/x/ibc/07-tendermint/types/consensus_state.go @@ -15,7 +15,7 @@ import ( // NewConsensusState creates a new ConsensusState instance. func NewConsensusState( - timestamp time.Time, root commitmenttypes.MerkleRoot, height uint64, + timestamp time.Time, root commitmenttypes.MerkleRoot, height clienttypes.Height, nextValsHash tmbytes.HexBytes, ) *ConsensusState { return &ConsensusState{ @@ -38,7 +38,7 @@ func (cs ConsensusState) GetRoot() commitmentexported.Root { // GetHeight returns the height for the specific consensus state func (cs ConsensusState) GetHeight() uint64 { - return cs.Height + return cs.Height.EpochHeight } // GetTimestamp returns block time in nanoseconds at which the consensus state was stored @@ -54,8 +54,8 @@ func (cs ConsensusState) ValidateBasic() error { if err := tmtypes.ValidateHash(cs.NextValidatorsHash); err != nil { return sdkerrors.Wrap(err, "next validators hash is invalid") } - if cs.Height == 0 { - return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "height cannot be 0") + if cs.Height.EpochHeight == 0 { + return sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "tendermint epoch height cannot be zero") } if cs.Timestamp.IsZero() { return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "timestamp cannot be zero Unix time") diff --git a/x/ibc/07-tendermint/types/consensus_state_test.go b/x/ibc/07-tendermint/types/consensus_state_test.go index 3bb0a2d5b..d43f8b707 100644 --- a/x/ibc/07-tendermint/types/consensus_state_test.go +++ b/x/ibc/07-tendermint/types/consensus_state_test.go @@ -4,6 +4,7 @@ import ( "time" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) @@ -50,7 +51,7 @@ func (suite *TendermintTestSuite) TestConsensusStateValidateBasic() { {"height is 0", &types.ConsensusState{ Timestamp: suite.now, - Height: 0, + Height: clienttypes.NewHeight(0, 0), Root: commitmenttypes.NewMerkleRoot([]byte("app_hash")), NextValidatorsHash: suite.valsHash, }, diff --git a/x/ibc/07-tendermint/types/header.go b/x/ibc/07-tendermint/types/header.go index d69361eda..bfd8eb070 100644 --- a/x/ibc/07-tendermint/types/header.go +++ b/x/ibc/07-tendermint/types/header.go @@ -22,7 +22,7 @@ func (h Header) ClientType() clientexported.ClientType { // ConsensusState returns the updated consensus state associated with the header func (h Header) ConsensusState() *ConsensusState { return &ConsensusState{ - Height: h.GetHeight(), + Height: clienttypes.NewHeight(0, h.GetHeight()), Timestamp: h.GetTime(), Root: commitmenttypes.NewMerkleRoot(h.Header.GetAppHash()), NextValidatorsHash: h.Header.NextValidatorsHash, @@ -33,6 +33,7 @@ func (h Header) ConsensusState() *ConsensusState { // header is nil. // // NOTE: also referred as `sequence` +// TODO: return clienttypes.Height once interface changes func (h Header) GetHeight() uint64 { if h.Header == nil { return 0 @@ -71,9 +72,10 @@ func (h Header) ValidateBasic(chainID string) error { // TrustedHeight is less than Header for updates // and less than or equal to Header for misbehaviour - if h.TrustedHeight > h.GetHeight() { + height := clienttypes.NewHeight(0, h.GetHeight()) + if h.TrustedHeight.GT(height) { return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "TrustedHeight %d must be less than or equal to header height %d", - h.TrustedHeight, h.GetHeight()) + h.TrustedHeight, height) } if h.ValidatorSet == nil { diff --git a/x/ibc/07-tendermint/types/header_test.go b/x/ibc/07-tendermint/types/header_test.go index bd8dd2221..833191e08 100644 --- a/x/ibc/07-tendermint/types/header_test.go +++ b/x/ibc/07-tendermint/types/header_test.go @@ -4,6 +4,7 @@ import ( "time" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" ) @@ -45,7 +46,7 @@ func (suite *TendermintTestSuite) TestHeaderValidateBasic() { chainID = "chainid" }, false}, {"trusted height is greater than header height", func() { - header.TrustedHeight = header.GetHeight() + 1 + header.TrustedHeight = clienttypes.NewHeight(0, header.GetHeight()+1) }, false}, {"validator set nil", func() { header.ValidatorSet = nil diff --git a/x/ibc/07-tendermint/types/misbehaviour.go b/x/ibc/07-tendermint/types/misbehaviour.go index 7d57ff6b9..2bf6b9beb 100644 --- a/x/ibc/07-tendermint/types/misbehaviour.go +++ b/x/ibc/07-tendermint/types/misbehaviour.go @@ -73,11 +73,11 @@ func (misbehaviour Misbehaviour) ValidateBasic() error { if misbehaviour.Header2 == nil { return sdkerrors.Wrap(ErrInvalidHeader, "misbehaviour Header2 cannot be nil") } - if misbehaviour.Header1.TrustedHeight == 0 { - return sdkerrors.Wrap(ErrInvalidHeaderHeight, "misbehaviour Header1 must have non-zero trusted height") + if misbehaviour.Header1.TrustedHeight.EpochHeight == 0 { + return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "misbehaviour Header1 cannot have zero epoch height") } - if misbehaviour.Header2.TrustedHeight == 0 { - return sdkerrors.Wrap(ErrInvalidHeaderHeight, "misbehaviour Header2 must have non-zero trusted height") + if misbehaviour.Header2.TrustedHeight.EpochHeight == 0 { + return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "misbehaviour Header2 cannot have zero epoch height") } if misbehaviour.Header1.TrustedValidators == nil { return sdkerrors.Wrap(ErrInvalidValidatorSet, "trusted validator set in Header1 cannot be empty") diff --git a/x/ibc/07-tendermint/types/misbehaviour_handle.go b/x/ibc/07-tendermint/types/misbehaviour_handle.go index 4c0586514..bc49cdca2 100644 --- a/x/ibc/07-tendermint/types/misbehaviour_handle.go +++ b/x/ibc/07-tendermint/types/misbehaviour_handle.go @@ -25,38 +25,38 @@ func (cs ClientState) CheckMisbehaviourAndUpdateState( clientStore sdk.KVStore, misbehaviour clientexported.Misbehaviour, ) (clientexported.ClientState, error) { - - // If client is already frozen at earlier height than misbehaviour, return with error - if cs.IsFrozen() && cs.FrozenHeight <= misbehaviour.GetHeight() { - return nil, sdkerrors.Wrapf(clienttypes.ErrInvalidMisbehaviour, - "client is already frozen at earlier height %d than misbehaviour height %d", cs.FrozenHeight, misbehaviour.GetHeight()) - } - - tmEvidence, ok := misbehaviour.(*Misbehaviour) + tmMisbehaviour, ok := misbehaviour.(*Misbehaviour) if !ok { return nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "expected type %T, got %T", misbehaviour, &Misbehaviour{}) } + // If client is already frozen at earlier height than misbehaviour, return with error + height := clienttypes.NewHeight(0, misbehaviour.GetHeight()) + if cs.IsFrozen() && cs.FrozenHeight.LTE(height) { + return nil, sdkerrors.Wrapf(clienttypes.ErrInvalidMisbehaviour, + "client is already frozen at earlier height %d than misbehaviour height %d", cs.FrozenHeight, misbehaviour.GetHeight()) + } + // Retrieve trusted consensus states for each Header in misbehaviour // and unmarshal from clientStore // Get consensus bytes from clientStore - tmConsensusState1, err := GetConsensusState(clientStore, cdc, tmEvidence.Header1.TrustedHeight) + tmConsensusState1, err := GetConsensusState(clientStore, cdc, tmMisbehaviour.Header1.TrustedHeight.EpochHeight) if err != nil { - return nil, sdkerrors.Wrapf(err, "could not get trusted consensus state from clientStore for Header1 at TrustedHeight: %d", tmEvidence.Header1.TrustedHeight) + return nil, sdkerrors.Wrapf(err, "could not get trusted consensus state from clientStore for Header1 at TrustedHeight: %d", tmMisbehaviour.Header1.TrustedHeight) } // Get consensus bytes from clientStore - tmConsensusState2, err := GetConsensusState(clientStore, cdc, tmEvidence.Header2.TrustedHeight) + tmConsensusState2, err := GetConsensusState(clientStore, cdc, tmMisbehaviour.Header2.TrustedHeight.EpochHeight) if err != nil { - return nil, sdkerrors.Wrapf(err, "could not get trusted consensus state from clientStore for Header2 at TrustedHeight: %d", tmEvidence.Header2.TrustedHeight) + return nil, sdkerrors.Wrapf(err, "could not get trusted consensus state from clientStore for Header2 at TrustedHeight: %d", tmMisbehaviour.Header2.TrustedHeight) } // calculate the age of the misbehaviour - infractionHeight := tmEvidence.GetHeight() - infractionTime := tmEvidence.GetTime() + infractionHeight := tmMisbehaviour.GetHeight() + infractionTime := tmMisbehaviour.GetTime() ageDuration := ctx.BlockTime().Sub(infractionTime) - ageBlocks := int64(cs.LatestHeight - infractionHeight) + ageBlocks := int64(cs.LatestHeight.EpochHeight - infractionHeight) // TODO: Retrieve consensusparams from client state and not context // Issue #6516: https://github.com/cosmos/cosmos-sdk/issues/6516 @@ -86,17 +86,18 @@ func (cs ClientState) CheckMisbehaviourAndUpdateState( // misbehaviour.ValidateBasic by the client keeper and msg.ValidateBasic // by the base application. if err := checkMisbehaviourHeader( - &cs, tmConsensusState1, tmEvidence.Header1, ctx.BlockTime(), + &cs, tmConsensusState1, tmMisbehaviour.Header1, ctx.BlockTime(), ); err != nil { return nil, sdkerrors.Wrap(err, "verifying Header1 in Misbehaviour failed") } if err := checkMisbehaviourHeader( - &cs, tmConsensusState2, tmEvidence.Header2, ctx.BlockTime(), + &cs, tmConsensusState2, tmMisbehaviour.Header2, ctx.BlockTime(), ); err != nil { return nil, sdkerrors.Wrap(err, "verifying Header2 in Misbehaviour failed") } - cs.FrozenHeight = tmEvidence.GetHeight() + frozenHeight := clienttypes.NewHeight(0, tmMisbehaviour.GetHeight()) + cs.FrozenHeight = frozenHeight return &cs, nil } diff --git a/x/ibc/07-tendermint/types/misbehaviour_handle_test.go b/x/ibc/07-tendermint/types/misbehaviour_handle_test.go index 47bb06c4b..b5b662844 100644 --- a/x/ibc/07-tendermint/types/misbehaviour_handle_test.go +++ b/x/ibc/07-tendermint/types/misbehaviour_handle_test.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) @@ -33,6 +34,10 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { altSigners := []tmtypes.PrivValidator{altPrivVal} + epochHeight := int64(height.EpochHeight) + heightMinus1 := clienttypes.NewHeight(height.EpochNumber, height.EpochHeight-1) + heightMinus3 := clienttypes.NewHeight(height.EpochNumber, height.EpochHeight-3) + testCases := []struct { name string clientState clientexported.ClientState @@ -48,8 +53,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height, suite.now, bothValSet, bothValSet, bothSigners), - Header2: types.CreateTestHeader(chainID, height, height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now, bothValSet, bothValSet, bothSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ChainId: chainID, ClientId: chainID, }, @@ -59,11 +64,11 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { { "valid misbehavior at height greater than last consensusState", types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height-1, bothValsHash), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height-1, bothValsHash), + types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), heightMinus1, bothValsHash), + types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), heightMinus1, bothValsHash), &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height-1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: types.CreateTestHeader(chainID, height, height-1, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ChainId: chainID, ClientId: chainID, }, @@ -73,11 +78,11 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { { "valid misbehavior misbehaviour with different trusted heights", types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height-1, bothValsHash), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height-3, suite.valsHash), + types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), heightMinus1, bothValsHash), + types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), heightMinus3, suite.valsHash), &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height-1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: types.CreateTestHeader(chainID, height, height-3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight-3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ChainId: chainID, ClientId: chainID, }, @@ -90,8 +95,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, suite.valsHash), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, suite.valsHash), &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height, suite.now, bothValSet, suite.valSet, bothSigners), - Header2: types.CreateTestHeader(chainID, height, height, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now, bothValSet, suite.valSet, bothSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ChainId: chainID, ClientId: chainID, }, @@ -101,11 +106,11 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { { "invalid misbehavior misbehaviour with trusted height different from trusted consensus state", types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height-1, bothValsHash), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height-3, suite.valsHash), + types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), heightMinus1, bothValsHash), + types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), heightMinus3, suite.valsHash), &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height-1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: types.CreateTestHeader(chainID, height, height, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ChainId: chainID, ClientId: chainID, }, @@ -115,11 +120,11 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { { "invalid misbehavior misbehaviour with trusted validators different from trusted consensus state", types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height-1, bothValsHash), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height-3, suite.valsHash), + types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), heightMinus1, bothValsHash), + types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), heightMinus3, suite.valsHash), &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height-1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: types.CreateTestHeader(chainID, height, height-3, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight-3, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ChainId: chainID, ClientId: chainID, }, @@ -128,12 +133,12 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { }, { "already frozen client state", - types.ClientState{FrozenHeight: 1}, + types.ClientState{FrozenHeight: clienttypes.NewHeight(0, 1)}, types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height, suite.now, bothValSet, bothValSet, bothSigners), - Header2: types.CreateTestHeader(chainID, height, height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now, bothValSet, bothValSet, bothSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ChainId: chainID, ClientId: chainID, }, @@ -146,8 +151,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { nil, // consensus state for trusted height - 1 does not exist in store types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height-1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: types.CreateTestHeader(chainID, height, height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ChainId: chainID, ClientId: chainID, }, @@ -155,7 +160,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { false, }, { - "invalid tendermint misbehaviour misbehaviour", + "invalid tendermint misbehaviour", types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), @@ -169,8 +174,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height, suite.now, bothValSet, bothValSet, bothSigners), - Header2: types.CreateTestHeader(chainID, height, height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now, bothValSet, bothValSet, bothSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ChainId: chainID, ClientId: chainID, }, @@ -179,12 +184,12 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { }, { "rejected misbehaviour due to expired block duration", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, uint64(height+simapp.DefaultConsensusParams.Evidence.MaxAgeNumBlocks+1), commitmenttypes.GetSDKSpecs()), + types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(0, uint64(epochHeight+simapp.DefaultConsensusParams.Evidence.MaxAgeNumBlocks+1)), commitmenttypes.GetSDKSpecs()), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height, suite.now, bothValSet, bothValSet, bothSigners), - Header2: types.CreateTestHeader(chainID, height, height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now, bothValSet, bothValSet, bothSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ChainId: chainID, ClientId: chainID, }, @@ -197,8 +202,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height-1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: types.CreateTestHeader(chainID, height, height-1, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ChainId: chainID, ClientId: chainID, }, @@ -208,11 +213,11 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { { "unbonding period expired", types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()), - &types.ConsensusState{Timestamp: time.Time{}, Root: commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), NextValidatorsHash: bothValsHash}, + types.NewConsensusState(time.Time{}, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), heightMinus1, bothValsHash), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height, suite.now, bothValSet, bothValSet, bothSigners), - Header2: types.CreateTestHeader(chainID, height, height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ChainId: chainID, ClientId: chainID, }, @@ -225,8 +230,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height, suite.now, bothValSet, suite.valSet, bothSigners), - Header2: types.CreateTestHeader(chainID, height, height, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now, bothValSet, suite.valSet, bothSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ChainId: chainID, ClientId: chainID, }, @@ -239,8 +244,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height, suite.now, altValSet, bothValSet, altSigners), - Header2: types.CreateTestHeader(chainID, height, height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now, altValSet, bothValSet, altSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ChainId: chainID, ClientId: chainID, }, @@ -253,8 +258,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height, suite.now, bothValSet, bothValSet, bothSigners), - Header2: types.CreateTestHeader(chainID, height, height, suite.now.Add(time.Minute), altValSet, bothValSet, altSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now, bothValSet, bothValSet, bothSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now.Add(time.Minute), altValSet, bothValSet, altSigners), ChainId: chainID, ClientId: chainID, }, @@ -267,8 +272,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), height, bothValsHash), &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height, suite.now, altValSet, bothValSet, altSigners), - Header2: types.CreateTestHeader(chainID, height, height, suite.now.Add(time.Minute), altValSet, bothValSet, altSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now, altValSet, bothValSet, altSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight, suite.now.Add(time.Minute), altValSet, bothValSet, altSigners), ChainId: chainID, ClientId: chainID, }, diff --git a/x/ibc/07-tendermint/types/misbehaviour_test.go b/x/ibc/07-tendermint/types/misbehaviour_test.go index ab313c275..8eb23ac03 100644 --- a/x/ibc/07-tendermint/types/misbehaviour_test.go +++ b/x/ibc/07-tendermint/types/misbehaviour_test.go @@ -13,17 +13,18 @@ import ( func (suite *TendermintTestSuite) TestMisbehaviour() { signers := []tmtypes.PrivValidator{suite.privVal} + epochHeight := int64(height.EpochHeight) misbehaviour := &types.Misbehaviour{ Header1: suite.header, - Header2: types.CreateTestHeader(chainID, height, height-1, suite.now, suite.valSet, suite.valSet, signers), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now, suite.valSet, suite.valSet, signers), ChainId: chainID, ClientId: clientID, } suite.Require().Equal(clientexported.Tendermint, misbehaviour.ClientType()) suite.Require().Equal(clientID, misbehaviour.GetClientID()) - suite.Require().Equal(uint64(height), misbehaviour.GetHeight()) + suite.Require().Equal(height.EpochHeight, misbehaviour.GetHeight()) } func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { @@ -31,7 +32,9 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { altPubKey, err := altPrivVal.GetPubKey() suite.Require().NoError(err) - altVal := tmtypes.NewValidator(altPubKey, height) + epochHeight := int64(height.EpochHeight) + + altVal := tmtypes.NewValidator(altPubKey, epochHeight) // Create bothValSet with both suite validator and altVal bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) @@ -56,7 +59,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "valid misbehaviour", &types.Misbehaviour{ Header1: suite.header, - Header2: types.CreateTestHeader(chainID, height, height-1, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), ChainId: chainID, ClientId: clientID, }, @@ -79,7 +82,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "valid misbehaviour with different trusted headers", &types.Misbehaviour{ Header1: suite.header, - Header2: types.CreateTestHeader(chainID, height, height-3, suite.now.Add(time.Minute), suite.valSet, bothValSet, signers), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight-3, suite.now.Add(time.Minute), suite.valSet, bothValSet, signers), ChainId: chainID, ClientId: clientID, }, @@ -89,7 +92,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { { "trusted height is 0 in Header1", &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, 0, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), + Header1: types.CreateTestHeader(chainID, epochHeight, 0, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), Header2: suite.header, ChainId: chainID, ClientId: clientID, @@ -101,7 +104,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "trusted height is 0 in Header2", &types.Misbehaviour{ Header1: suite.header, - Header2: types.CreateTestHeader(chainID, height, 0, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), + Header2: types.CreateTestHeader(chainID, epochHeight, 0, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), ChainId: chainID, ClientId: clientID, }, @@ -111,7 +114,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { { "trusted valset is nil in Header1", &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height-1, suite.now.Add(time.Minute), suite.valSet, nil, signers), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now.Add(time.Minute), suite.valSet, nil, signers), Header2: suite.header, ChainId: chainID, ClientId: clientID, @@ -123,7 +126,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "trusted valset is nil in Header2", &types.Misbehaviour{ Header1: suite.header, - Header2: types.CreateTestHeader(chainID, height, height-1, suite.now.Add(time.Minute), suite.valSet, nil, signers), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now.Add(time.Minute), suite.valSet, nil, signers), ChainId: chainID, ClientId: clientID, }, @@ -134,7 +137,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "invalid client ID ", &types.Misbehaviour{ Header1: suite.header, - Header2: types.CreateTestHeader(chainID, height, height-1, suite.now, suite.valSet, suite.valSet, signers), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now, suite.valSet, suite.valSet, signers), ChainId: chainID, ClientId: "GAIA", }, @@ -145,7 +148,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "wrong chainID on header1", &types.Misbehaviour{ Header1: suite.header, - Header2: types.CreateTestHeader("ethermint", height, height-1, suite.now, suite.valSet, suite.valSet, signers), + Header2: types.CreateTestHeader("ethermint", epochHeight, epochHeight-1, suite.now, suite.valSet, suite.valSet, signers), ChainId: "ethermint", ClientId: clientID, }, @@ -156,7 +159,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "wrong chainID on header2", &types.Misbehaviour{ Header1: suite.header, - Header2: types.CreateTestHeader("ethermint", height, height-1, suite.now, suite.valSet, suite.valSet, signers), + Header2: types.CreateTestHeader("ethermint", epochHeight, epochHeight-1, suite.now, suite.valSet, suite.valSet, signers), ChainId: chainID, ClientId: clientID, }, @@ -188,7 +191,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { { "header 1 doesn't have 2/3 majority", &types.Misbehaviour{ - Header1: types.CreateTestHeader(chainID, height, height-1, suite.now, bothValSet, suite.valSet, bothSigners), + Header1: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now, bothValSet, suite.valSet, bothSigners), Header2: suite.header, ChainId: chainID, ClientId: clientID, @@ -211,7 +214,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "header 2 doesn't have 2/3 majority", &types.Misbehaviour{ Header1: suite.header, - Header2: types.CreateTestHeader(chainID, height, height-1, suite.now, bothValSet, suite.valSet, bothSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now, bothValSet, suite.valSet, bothSigners), ChainId: chainID, ClientId: clientID, }, @@ -233,7 +236,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "validators sign off on wrong commit", &types.Misbehaviour{ Header1: suite.header, - Header2: types.CreateTestHeader(chainID, height, height-1, suite.now, bothValSet, suite.valSet, bothSigners), + Header2: types.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now, bothValSet, suite.valSet, bothSigners), ChainId: chainID, ClientId: clientID, }, diff --git a/x/ibc/07-tendermint/types/msgs.go b/x/ibc/07-tendermint/types/msgs.go index 3348aeb1a..c01e07618 100644 --- a/x/ibc/07-tendermint/types/msgs.go +++ b/x/ibc/07-tendermint/types/msgs.go @@ -10,6 +10,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) @@ -113,10 +114,12 @@ func (msg MsgCreateClient) GetClientType() string { func (msg MsgCreateClient) GetConsensusState() clientexported.ConsensusState { // Construct initial consensus state from provided Header root := commitmenttypes.NewMerkleRoot(msg.Header.Header.GetAppHash()) + // NOTE: Using 0 for epoch number for now + // TODO: Use clienttypes.Height in Header once Header.GetHeight returns *clienttypes.Height return &ConsensusState{ Timestamp: msg.Header.GetTime(), Root: root, - Height: msg.Header.GetHeight(), + Height: clienttypes.NewHeight(0, msg.Header.GetHeight()), NextValidatorsHash: msg.Header.Header.NextValidatorsHash, } } @@ -125,7 +128,7 @@ func (msg MsgCreateClient) GetConsensusState() clientexported.ConsensusState { func (msg MsgCreateClient) InitializeClientState() clientexported.ClientState { return NewClientState(msg.Header.Header.GetChainID(), msg.TrustLevel, msg.TrustingPeriod, msg.UnbondingPeriod, msg.MaxClockDrift, - msg.Header.GetHeight(), msg.ProofSpecs, + clienttypes.NewHeight(0, msg.Header.GetHeight()), msg.ProofSpecs, ) } diff --git a/x/ibc/07-tendermint/types/msgs_test.go b/x/ibc/07-tendermint/types/msgs_test.go index 6cfc111b5..7d22b8b24 100644 --- a/x/ibc/07-tendermint/types/msgs_test.go +++ b/x/ibc/07-tendermint/types/msgs_test.go @@ -15,7 +15,7 @@ import ( func (suite *TendermintTestSuite) TestMsgCreateClientValidateBasic() { privKey := secp256k1.GenPrivKey() signer := sdk.AccAddress(privKey.PubKey().Address()) - invalidHeader := types.CreateTestHeader(suite.header.Header.GetChainID(), height, 0, suite.now, suite.valSet, nil, []tmtypes.PrivValidator{suite.privVal}) + invalidHeader := types.CreateTestHeader(suite.header.Header.GetChainID(), int64(height.EpochHeight), 0, suite.now, suite.valSet, nil, []tmtypes.PrivValidator{suite.privVal}) invalidHeader.ValidatorSet = nil cases := []struct { diff --git a/x/ibc/07-tendermint/types/tendermint.pb.go b/x/ibc/07-tendermint/types/tendermint.pb.go index 355d0acb7..f6fbadf94 100644 --- a/x/ibc/07-tendermint/types/tendermint.pb.go +++ b/x/ibc/07-tendermint/types/tendermint.pb.go @@ -7,14 +7,15 @@ import ( fmt "fmt" _go "github.com/confio/ics23/go" github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" - types "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" + types "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + types1 "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" _ "github.com/golang/protobuf/ptypes/duration" _ "github.com/golang/protobuf/ptypes/timestamp" github_com_tendermint_tendermint_libs_bytes "github.com/tendermint/tendermint/libs/bytes" - types1 "github.com/tendermint/tendermint/proto/tendermint/types" + types2 "github.com/tendermint/tendermint/proto/tendermint/types" io "io" math "math" math_bits "math/bits" @@ -46,9 +47,9 @@ type ClientState struct { // defines how much new (untrusted) header's Time can drift into the future. MaxClockDrift time.Duration `protobuf:"bytes,5,opt,name=max_clock_drift,json=maxClockDrift,proto3,stdduration" json:"max_clock_drift" yaml:"max_clock_drift"` // Block height when the client was frozen due to a misbehaviour - FrozenHeight uint64 `protobuf:"varint,6,opt,name=frozen_height,json=frozenHeight,proto3" json:"frozen_height,omitempty" yaml:"frozen_height"` + FrozenHeight types.Height `protobuf:"bytes,6,opt,name=frozen_height,json=frozenHeight,proto3" json:"frozen_height" yaml:"frozen_height"` // Latest height the client was updated to - LatestHeight uint64 `protobuf:"varint,7,opt,name=latest_height,json=latestHeight,proto3" json:"latest_height,omitempty" yaml:"latest_height"` + LatestHeight types.Height `protobuf:"bytes,7,opt,name=latest_height,json=latestHeight,proto3" json:"latest_height" yaml:"latest_height"` // Proof specifications used in verifying counterparty state ProofSpecs []*_go.ProofSpec `protobuf:"bytes,8,rep,name=proof_specs,json=proofSpecs,proto3" json:"proof_specs,omitempty" yaml:"proof_specs"` } @@ -92,9 +93,9 @@ type ConsensusState struct { // was stored. Timestamp time.Time `protobuf:"bytes,1,opt,name=timestamp,proto3,stdtime" json:"timestamp"` // commitment root (i.e app hash) - Root types.MerkleRoot `protobuf:"bytes,2,opt,name=root,proto3" json:"root"` + Root types1.MerkleRoot `protobuf:"bytes,2,opt,name=root,proto3" json:"root"` // height at which the consensus state was stored. - Height uint64 `protobuf:"varint,3,opt,name=height,proto3" json:"height,omitempty"` + Height types.Height `protobuf:"bytes,3,opt,name=height,proto3" json:"height"` NextValidatorsHash github_com_tendermint_tendermint_libs_bytes.HexBytes `protobuf:"bytes,4,opt,name=next_validators_hash,json=nextValidatorsHash,proto3,casttype=github.com/tendermint/tendermint/libs/bytes.HexBytes" json:"next_validators_hash,omitempty" yaml:"next_validators_hash"` } @@ -185,10 +186,10 @@ var xxx_messageInfo_Misbehaviour proto.InternalMessageInfo // hash to TrustedConsensusState.NextValidatorsHash since that is the last // trusted validator set at the TrustedHeight. type Header struct { - *types1.SignedHeader `protobuf:"bytes,1,opt,name=signed_header,json=signedHeader,proto3,embedded=signed_header" json:"signed_header,omitempty" yaml:"signed_header"` - ValidatorSet *types1.ValidatorSet `protobuf:"bytes,2,opt,name=validator_set,json=validatorSet,proto3" json:"validator_set,omitempty" yaml:"validator_set"` - TrustedHeight uint64 `protobuf:"varint,3,opt,name=trusted_height,json=trustedHeight,proto3" json:"trusted_height,omitempty" yaml:"trusted_height"` - TrustedValidators *types1.ValidatorSet `protobuf:"bytes,4,opt,name=trusted_validators,json=trustedValidators,proto3" json:"trusted_validators,omitempty" yaml:"trusted_validators"` + *types2.SignedHeader `protobuf:"bytes,1,opt,name=signed_header,json=signedHeader,proto3,embedded=signed_header" json:"signed_header,omitempty" yaml:"signed_header"` + ValidatorSet *types2.ValidatorSet `protobuf:"bytes,2,opt,name=validator_set,json=validatorSet,proto3" json:"validator_set,omitempty" yaml:"validator_set"` + TrustedHeight types.Height `protobuf:"bytes,3,opt,name=trusted_height,json=trustedHeight,proto3" json:"trusted_height" yaml:"trusted_height"` + TrustedValidators *types2.ValidatorSet `protobuf:"bytes,4,opt,name=trusted_validators,json=trustedValidators,proto3" json:"trusted_validators,omitempty" yaml:"trusted_validators"` } func (m *Header) Reset() { *m = Header{} } @@ -224,21 +225,21 @@ func (m *Header) XXX_DiscardUnknown() { var xxx_messageInfo_Header proto.InternalMessageInfo -func (m *Header) GetValidatorSet() *types1.ValidatorSet { +func (m *Header) GetValidatorSet() *types2.ValidatorSet { if m != nil { return m.ValidatorSet } return nil } -func (m *Header) GetTrustedHeight() uint64 { +func (m *Header) GetTrustedHeight() types.Height { if m != nil { return m.TrustedHeight } - return 0 + return types.Height{} } -func (m *Header) GetTrustedValidators() *types1.ValidatorSet { +func (m *Header) GetTrustedValidators() *types2.ValidatorSet { if m != nil { return m.TrustedValidators } @@ -438,75 +439,76 @@ func init() { func init() { proto.RegisterFile("ibc/tendermint/tendermint.proto", fileDescriptor_76a953d5a747dd66) } var fileDescriptor_76a953d5a747dd66 = []byte{ - // 1088 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x4f, 0x4f, 0xe3, 0x46, - 0x14, 0xc7, 0x21, 0x84, 0x30, 0x09, 0x7f, 0xea, 0xa5, 0x34, 0xb0, 0x34, 0x8e, 0xdc, 0x0b, 0x17, - 0x9c, 0x92, 0x5d, 0xb5, 0x12, 0x52, 0xa5, 0x5d, 0xb3, 0xaa, 0xa0, 0x2a, 0x12, 0x1d, 0xba, 0xad, - 0x54, 0xa9, 0xb2, 0x1c, 0x7b, 0x92, 0x8c, 0xb0, 0x3d, 0x91, 0x67, 0x82, 0xa0, 0x9f, 0x60, 0x7b, - 0xdb, 0xe3, 0x1e, 0xbb, 0xdf, 0xa0, 0x87, 0x7e, 0x85, 0x4a, 0x7b, 0xe4, 0xd8, 0x93, 0x5b, 0xc1, - 0x37, 0xc8, 0x91, 0x53, 0xe5, 0x99, 0xb1, 0x3d, 0x09, 0x68, 0xb7, 0x5d, 0xb1, 0x5c, 0x60, 0xde, - 0x9f, 0xdf, 0x7b, 0x33, 0x2f, 0xbf, 0xf7, 0x9e, 0x81, 0x81, 0xbb, 0x5e, 0x9b, 0xa1, 0xc8, 0x47, - 0x71, 0x88, 0x23, 0xa6, 0x1c, 0xad, 0x61, 0x4c, 0x18, 0xd1, 0x97, 0x70, 0xd7, 0xb3, 0x0a, 0xed, - 0x46, 0x4b, 0x75, 0x3e, 0x1f, 0x22, 0xda, 0x3e, 0x75, 0x03, 0xec, 0xbb, 0x8c, 0xc4, 0x02, 0xb1, - 0xb1, 0x79, 0xc3, 0x83, 0xff, 0x95, 0xd6, 0x07, 0x1e, 0x89, 0x7a, 0x98, 0xb4, 0x87, 0x31, 0x21, - 0xbd, 0x4c, 0xd9, 0xec, 0x13, 0xd2, 0x0f, 0x50, 0x9b, 0x4b, 0xdd, 0x51, 0xaf, 0xed, 0x8f, 0x62, - 0x97, 0x61, 0x12, 0x49, 0xbb, 0x31, 0x6d, 0x67, 0x38, 0x44, 0x94, 0xb9, 0xe1, 0x30, 0x73, 0x48, - 0x9f, 0xe1, 0x91, 0x30, 0xc4, 0x2c, 0x44, 0x11, 0x53, 0x8e, 0xd2, 0x61, 0xb5, 0x4f, 0xfa, 0x84, - 0x1f, 0xdb, 0xe9, 0x49, 0x68, 0xcd, 0x17, 0x73, 0xa0, 0xb6, 0x17, 0x60, 0x14, 0xb1, 0x63, 0xe6, - 0x32, 0xa4, 0xaf, 0x83, 0xaa, 0x37, 0x70, 0x71, 0xe4, 0x60, 0xbf, 0xa1, 0xb5, 0xb4, 0xad, 0x05, - 0x38, 0xcf, 0xe5, 0x03, 0x5f, 0x7f, 0x0e, 0x6a, 0x2c, 0x1e, 0x51, 0xe6, 0x04, 0xe8, 0x14, 0x05, - 0x8d, 0x52, 0x4b, 0xdb, 0xaa, 0x75, 0x1a, 0xd6, 0x64, 0x75, 0xac, 0xaf, 0x63, 0xd7, 0x4b, 0xef, - 0x6d, 0x6f, 0xbc, 0x49, 0x8c, 0x99, 0x71, 0x62, 0xe8, 0xe7, 0x6e, 0x18, 0xec, 0x9a, 0x0a, 0xd4, - 0x84, 0x80, 0x4b, 0xdf, 0xa6, 0x82, 0xde, 0x03, 0xcb, 0x5c, 0xc2, 0x51, 0xdf, 0x19, 0xa2, 0x18, - 0x13, 0xbf, 0x31, 0xcb, 0x43, 0xaf, 0x5b, 0xe2, 0xcd, 0x56, 0xf6, 0x66, 0xeb, 0x99, 0xac, 0x89, - 0x6d, 0xca, 0xd8, 0x6b, 0x4a, 0xec, 0x02, 0x6f, 0xbe, 0xfa, 0xdb, 0xd0, 0xe0, 0x52, 0xa6, 0x3d, - 0xe2, 0x4a, 0x1d, 0x83, 0x95, 0x51, 0xd4, 0x25, 0x91, 0xaf, 0x24, 0x2a, 0xbf, 0x2b, 0xd1, 0x67, - 0x32, 0xd1, 0x27, 0x22, 0xd1, 0x74, 0x00, 0x91, 0x69, 0x39, 0x57, 0xcb, 0x54, 0x08, 0x2c, 0x87, - 0xee, 0x99, 0xe3, 0x05, 0xc4, 0x3b, 0x71, 0xfc, 0x18, 0xf7, 0x58, 0x63, 0xee, 0x7f, 0x3e, 0x69, - 0x0a, 0x2f, 0x12, 0x2d, 0x86, 0xee, 0xd9, 0x5e, 0xaa, 0x7c, 0x96, 0xea, 0xf4, 0xaf, 0xc0, 0x62, - 0x2f, 0x26, 0xbf, 0xa0, 0xc8, 0x19, 0x20, 0xdc, 0x1f, 0xb0, 0x46, 0xa5, 0xa5, 0x6d, 0x95, 0xed, - 0xc6, 0x38, 0x31, 0x56, 0x45, 0x94, 0x09, 0xb3, 0x09, 0xeb, 0x42, 0xde, 0xe7, 0x62, 0x0a, 0x0f, - 0x5c, 0x86, 0x28, 0xcb, 0xe0, 0xf3, 0xd3, 0xf0, 0x09, 0xb3, 0x09, 0xeb, 0x42, 0x96, 0xf0, 0x03, - 0x50, 0xe3, 0x0c, 0x76, 0xe8, 0x10, 0x79, 0xb4, 0x51, 0x6d, 0xcd, 0x6e, 0xd5, 0x3a, 0x2b, 0x16, - 0xf6, 0x68, 0xe7, 0x91, 0x75, 0x94, 0x5a, 0x8e, 0x87, 0xc8, 0xb3, 0xd7, 0x0a, 0x0a, 0x28, 0xee, - 0x26, 0x04, 0xc3, 0xcc, 0x85, 0xee, 0x96, 0x5f, 0xfc, 0x66, 0xcc, 0x98, 0x7f, 0x94, 0xc0, 0xd2, - 0x1e, 0x89, 0x28, 0x8a, 0xe8, 0x88, 0x0a, 0x36, 0xda, 0x60, 0x21, 0xe7, 0x39, 0xa7, 0x63, 0xad, - 0xb3, 0x71, 0xa3, 0x84, 0xdf, 0x67, 0x1e, 0x76, 0x35, 0xad, 0xe1, 0xcb, 0xb4, 0x52, 0x05, 0x4c, - 0x7f, 0x0c, 0xca, 0x31, 0x21, 0x4c, 0xf2, 0x75, 0x83, 0xf3, 0x55, 0x69, 0x8e, 0x43, 0x14, 0x9f, - 0x04, 0x08, 0x12, 0xc2, 0xec, 0x72, 0x0a, 0x87, 0xdc, 0x5b, 0x5f, 0x03, 0x15, 0x59, 0x95, 0x94, - 0x8c, 0x65, 0x28, 0x25, 0xfd, 0x57, 0x0d, 0xac, 0x46, 0xe8, 0x8c, 0x39, 0x79, 0xcf, 0x53, 0x67, - 0xe0, 0xd2, 0x01, 0xa7, 0x52, 0xdd, 0xfe, 0x71, 0x9c, 0x18, 0x0f, 0xc5, 0x6b, 0x6f, 0xf3, 0x32, - 0xaf, 0x13, 0xe3, 0x71, 0x1f, 0xb3, 0xc1, 0xa8, 0x9b, 0xde, 0xe1, 0xf6, 0xb1, 0xd3, 0x0e, 0x70, - 0x97, 0xb6, 0xbb, 0xe7, 0x0c, 0x51, 0x6b, 0x1f, 0x9d, 0xd9, 0xe9, 0x01, 0xea, 0x69, 0xb8, 0x1f, - 0xf2, 0x68, 0xfb, 0x2e, 0x1d, 0xc8, 0xb2, 0xbd, 0x2e, 0x81, 0xfa, 0x21, 0xa6, 0x5d, 0x34, 0x70, - 0x4f, 0x31, 0x19, 0xc5, 0xfa, 0x0e, 0x58, 0xf0, 0x78, 0x47, 0xe7, 0x3d, 0x6c, 0xaf, 0x8e, 0x13, - 0x63, 0x45, 0x5c, 0x2b, 0x37, 0x99, 0xb0, 0x2a, 0xce, 0x07, 0xbe, 0x6e, 0x29, 0x5d, 0x5f, 0xe2, - 0x88, 0x07, 0xe3, 0xc4, 0x58, 0x96, 0x08, 0x69, 0x31, 0x8b, 0x51, 0xf0, 0x1d, 0xa8, 0x0e, 0x90, - 0xeb, 0xa3, 0xd8, 0xd9, 0x91, 0xcd, 0xba, 0x36, 0x3d, 0x07, 0xf6, 0xb9, 0xdd, 0x6e, 0x5e, 0x26, - 0xc6, 0xbc, 0x38, 0xef, 0x14, 0x21, 0x33, 0xb0, 0x09, 0xe7, 0xc5, 0x71, 0x47, 0x09, 0xd9, 0x91, - 0x6d, 0xf9, 0x1f, 0x42, 0x76, 0x6e, 0x84, 0xec, 0xe4, 0x21, 0x3b, 0xbb, 0xd5, 0xb4, 0x3e, 0xaf, - 0xd2, 0x1a, 0x5d, 0x97, 0x40, 0x45, 0x20, 0x74, 0x17, 0x2c, 0x52, 0xdc, 0x8f, 0x90, 0xef, 0x08, - 0x37, 0x49, 0xab, 0xa6, 0x9a, 0x48, 0x4c, 0xeb, 0x63, 0xee, 0x26, 0x93, 0x6e, 0x5e, 0x24, 0x86, - 0x56, 0x74, 0xc6, 0x44, 0x08, 0x13, 0xd6, 0xa9, 0xe2, 0xab, 0xff, 0x0c, 0x16, 0xf3, 0xdf, 0xdd, - 0xa1, 0x28, 0xa3, 0xde, 0x2d, 0x29, 0xf2, 0x1f, 0xf4, 0x18, 0x31, 0xb5, 0xf1, 0x26, 0xe0, 0x26, - 0xac, 0x9f, 0x2a, 0x7e, 0xfa, 0x13, 0x20, 0x46, 0x1b, 0xcf, 0x5f, 0x50, 0xd4, 0x5e, 0x1f, 0x27, - 0xc6, 0xc7, 0xca, 0x40, 0xcc, 0xed, 0x26, 0x5c, 0x94, 0x0a, 0xd9, 0xba, 0x01, 0xd0, 0x33, 0x8f, - 0x82, 0xa0, 0xb2, 0xea, 0xef, 0xba, 0xe5, 0xa7, 0xe3, 0xc4, 0x58, 0x9f, 0xcc, 0x52, 0xc4, 0x30, - 0xe1, 0x47, 0x52, 0x59, 0x50, 0xd5, 0xfc, 0x06, 0x54, 0xb3, 0xa5, 0xa0, 0x6f, 0x82, 0x85, 0x68, - 0x14, 0xa2, 0x38, 0xb5, 0xf0, 0xca, 0xcf, 0xc2, 0x42, 0xa1, 0xb7, 0x40, 0xcd, 0x47, 0x11, 0x09, - 0x71, 0xc4, 0xed, 0x25, 0x6e, 0x57, 0x55, 0xe6, 0xeb, 0x39, 0xb0, 0x7c, 0x48, 0xfb, 0x7b, 0x31, - 0x72, 0x19, 0x12, 0x7b, 0xeb, 0xfd, 0xf8, 0x5e, 0x91, 0xbf, 0x7e, 0xe9, 0x6d, 0x54, 0x83, 0xd2, - 0x6b, 0x7a, 0xf5, 0xcd, 0x7e, 0xb8, 0xd5, 0x57, 0xbe, 0xaf, 0xd5, 0x37, 0x77, 0x6f, 0xab, 0xaf, - 0xf2, 0x01, 0x56, 0xdf, 0xdd, 0x2d, 0x1f, 0xfd, 0x00, 0x54, 0x78, 0xf7, 0xc6, 0x7c, 0xff, 0xd5, - 0xed, 0x9d, 0xeb, 0xc4, 0xd8, 0x56, 0x66, 0xb4, 0x47, 0x68, 0x48, 0xa8, 0xfc, 0xb7, 0x4d, 0xfd, - 0x13, 0xf9, 0x31, 0xf7, 0xd4, 0xf3, 0x9e, 0xfa, 0x7e, 0x8c, 0x28, 0x85, 0x32, 0x80, 0x1c, 0xc8, - 0x7f, 0x6a, 0x9c, 0xa3, 0xcf, 0x87, 0xfe, 0xbd, 0x72, 0xb4, 0x78, 0xc7, 0xec, 0xdd, 0xbc, 0xe3, - 0x77, 0x0d, 0x3c, 0x3c, 0xa4, 0xfd, 0xe3, 0x51, 0x37, 0xc4, 0x4c, 0xbc, 0x63, 0x62, 0xcf, 0x3c, - 0x01, 0xf5, 0x50, 0x91, 0xe5, 0x20, 0xdd, 0x9c, 0xbe, 0xa6, 0x8a, 0x81, 0x13, 0x08, 0xe5, 0xca, - 0xa5, 0x3b, 0xb9, 0xb2, 0x7d, 0xf4, 0xe6, 0xb2, 0xa9, 0x5d, 0x5c, 0x36, 0xb5, 0x7f, 0x2e, 0x9b, - 0xda, 0xcb, 0xab, 0xe6, 0xcc, 0xc5, 0x55, 0x73, 0xe6, 0xaf, 0xab, 0xe6, 0xcc, 0x4f, 0x5f, 0xbc, - 0x35, 0xec, 0x59, 0x3b, 0xfd, 0x7a, 0xfe, 0xfc, 0xcb, 0xed, 0xe9, 0x0f, 0xf7, 0x6e, 0x85, 0xd3, - 0xf5, 0xd1, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xcb, 0x3c, 0xee, 0xf6, 0x26, 0x0c, 0x00, 0x00, + // 1103 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0x4f, 0x4f, 0x1b, 0x47, + 0x14, 0x67, 0x6d, 0x30, 0x66, 0x6c, 0x02, 0x9d, 0x50, 0x62, 0x08, 0xf1, 0xa2, 0xed, 0x85, 0x0b, + 0xeb, 0xe0, 0x44, 0xad, 0xc4, 0xa9, 0x59, 0xa2, 0x0a, 0xaa, 0x22, 0xd1, 0xa5, 0xb4, 0x55, 0xa5, + 0x6a, 0xb5, 0x7f, 0xc6, 0xeb, 0x11, 0xbb, 0x3b, 0xd6, 0xce, 0x18, 0x41, 0x3f, 0x41, 0x7b, 0x8b, + 0x7a, 0xca, 0xb1, 0xf9, 0x06, 0x3d, 0xf6, 0x0b, 0x54, 0xca, 0xa9, 0xe2, 0xd8, 0xd3, 0xb6, 0x82, + 0x6f, 0xe0, 0x63, 0x4e, 0xd5, 0xce, 0xcc, 0xfe, 0xb1, 0xa1, 0x21, 0xad, 0x08, 0x17, 0x3c, 0xf3, + 0xde, 0xef, 0xfd, 0xde, 0xcc, 0x9b, 0xf7, 0x67, 0x01, 0x2a, 0x76, 0xdc, 0x0e, 0x43, 0x91, 0x87, + 0xe2, 0x10, 0x47, 0xac, 0xb4, 0xd4, 0x07, 0x31, 0x61, 0x04, 0xde, 0xc3, 0x8e, 0xab, 0x17, 0xd2, + 0xd5, 0xf5, 0x32, 0xf8, 0x6c, 0x80, 0x68, 0xe7, 0xc4, 0x0e, 0xb0, 0x67, 0x33, 0x12, 0x0b, 0x8b, + 0xd5, 0xb5, 0x2b, 0x08, 0xfe, 0x57, 0x6a, 0xef, 0xbb, 0x24, 0xea, 0x61, 0xd2, 0x19, 0xc4, 0x84, + 0xf4, 0x32, 0x61, 0xdb, 0x27, 0xc4, 0x0f, 0x50, 0x87, 0xef, 0x9c, 0x61, 0xaf, 0xe3, 0x0d, 0x63, + 0x9b, 0x61, 0x12, 0x49, 0xbd, 0x3a, 0xa9, 0x67, 0x38, 0x44, 0x94, 0xd9, 0xe1, 0x40, 0x02, 0x1e, + 0xa4, 0xd7, 0x70, 0x03, 0x8c, 0x22, 0x26, 0x7f, 0x32, 0x4b, 0xae, 0x20, 0x61, 0x88, 0x59, 0xc8, + 0x95, 0xf9, 0x52, 0x02, 0x96, 0x7c, 0xe2, 0x13, 0xbe, 0xec, 0xa4, 0x2b, 0x21, 0xd5, 0x7e, 0x9b, + 0x01, 0x8d, 0x1d, 0xce, 0x73, 0xc8, 0x6c, 0x86, 0xe0, 0x0a, 0xa8, 0xbb, 0x7d, 0x1b, 0x47, 0x16, + 0xf6, 0x5a, 0xca, 0xba, 0xb2, 0x31, 0x67, 0xce, 0xf2, 0xfd, 0x9e, 0x07, 0x8f, 0x40, 0x83, 0xc5, + 0x43, 0xca, 0xac, 0x00, 0x9d, 0xa0, 0xa0, 0x55, 0x59, 0x57, 0x36, 0x1a, 0xdd, 0x96, 0x3e, 0x1e, + 0x36, 0xfd, 0xb3, 0xd8, 0x76, 0xd3, 0x0b, 0x19, 0xab, 0xaf, 0x13, 0x75, 0x6a, 0x94, 0xa8, 0xf0, + 0xcc, 0x0e, 0x83, 0x6d, 0xad, 0x64, 0xaa, 0x99, 0x80, 0xef, 0xbe, 0x48, 0x37, 0xb0, 0x07, 0x16, + 0xf8, 0x0e, 0x47, 0xbe, 0x35, 0x40, 0x31, 0x26, 0x5e, 0xab, 0xca, 0xa9, 0x57, 0x74, 0x11, 0x0c, + 0x3d, 0x0b, 0x86, 0xfe, 0x5c, 0x06, 0xcb, 0xd0, 0x24, 0xf7, 0x72, 0x89, 0xbb, 0xb0, 0xd7, 0x5e, + 0xfe, 0xa5, 0x2a, 0xe6, 0xbd, 0x4c, 0x7a, 0xc0, 0x85, 0x10, 0x83, 0xc5, 0x61, 0xe4, 0x90, 0xc8, + 0x2b, 0x39, 0x9a, 0xbe, 0xc9, 0xd1, 0x47, 0xd2, 0xd1, 0x03, 0xe1, 0x68, 0x92, 0x40, 0x78, 0x5a, + 0xc8, 0xc5, 0xd2, 0x15, 0x02, 0x0b, 0xa1, 0x7d, 0x6a, 0xb9, 0x01, 0x71, 0x8f, 0x2d, 0x2f, 0xc6, + 0x3d, 0xd6, 0x9a, 0xf9, 0x8f, 0x57, 0x9a, 0xb0, 0x17, 0x8e, 0xe6, 0x43, 0xfb, 0x74, 0x27, 0x15, + 0x3e, 0x4f, 0x65, 0xf0, 0x08, 0xcc, 0xf7, 0x62, 0xf2, 0x03, 0x8a, 0xac, 0x3e, 0xc2, 0x7e, 0x9f, + 0xb5, 0x6a, 0xdc, 0x09, 0xe4, 0x4f, 0x22, 0x93, 0x63, 0x97, 0x6b, 0x8c, 0x35, 0xc9, 0xbe, 0x24, + 0xd8, 0xc7, 0xcc, 0x34, 0xb3, 0x29, 0xf6, 0x02, 0x9b, 0xd2, 0x06, 0x36, 0x43, 0x94, 0x65, 0xb4, + 0xb3, 0xef, 0x4a, 0x3b, 0x66, 0xa6, 0x99, 0x4d, 0xb1, 0x97, 0xb4, 0x7b, 0xa0, 0xc1, 0x4b, 0xc1, + 0xa2, 0x03, 0xe4, 0xd2, 0x56, 0x7d, 0xbd, 0xba, 0xd1, 0xe8, 0x2e, 0xea, 0xd8, 0xa5, 0xdd, 0x27, + 0xfa, 0x41, 0xaa, 0x39, 0x1c, 0x20, 0xd7, 0x58, 0x2e, 0x52, 0xa6, 0x04, 0xd7, 0x4c, 0x30, 0xc8, + 0x20, 0x74, 0x7b, 0xfa, 0xc7, 0x5f, 0xd4, 0x29, 0xed, 0x8f, 0x0a, 0xb8, 0xb7, 0x43, 0x22, 0x8a, + 0x22, 0x3a, 0xa4, 0x22, 0x7b, 0x0d, 0x30, 0x97, 0x17, 0x0c, 0x4f, 0xdf, 0x46, 0x77, 0xf5, 0x4a, + 0xc8, 0xbf, 0xca, 0x10, 0x46, 0x3d, 0x3d, 0xfe, 0x8b, 0x34, 0xb2, 0x85, 0x19, 0x7c, 0x0a, 0xa6, + 0x63, 0x42, 0x98, 0xcc, 0xef, 0x55, 0x71, 0xeb, 0xa2, 0x98, 0xf6, 0x51, 0x7c, 0x1c, 0x20, 0x93, + 0x10, 0x66, 0x4c, 0xa7, 0xe6, 0x26, 0x47, 0xc3, 0xc7, 0xa0, 0x26, 0xa3, 0x55, 0xfd, 0xd7, 0x68, + 0x09, 0xbc, 0xc4, 0xc1, 0x9f, 0x14, 0xb0, 0x14, 0xa1, 0x53, 0x66, 0xe5, 0x6d, 0x85, 0x5a, 0x7d, + 0x9b, 0xf6, 0x79, 0x52, 0x36, 0x8d, 0x6f, 0x46, 0x89, 0xfa, 0x50, 0xc4, 0xe1, 0x3a, 0x94, 0xf6, + 0x26, 0x51, 0x9f, 0xfa, 0x98, 0xf5, 0x87, 0x4e, 0x7a, 0xba, 0xeb, 0x3b, 0x5b, 0x27, 0xc0, 0x0e, + 0xed, 0x38, 0x67, 0x0c, 0x51, 0x7d, 0x17, 0x9d, 0x1a, 0xe9, 0xc2, 0x84, 0x29, 0xdd, 0xd7, 0x39, + 0xdb, 0xae, 0x4d, 0xfb, 0x32, 0xa0, 0xaf, 0x2a, 0xa0, 0xb9, 0x8f, 0xa9, 0x83, 0xfa, 0xf6, 0x09, + 0x26, 0xc3, 0x18, 0x6e, 0x81, 0x39, 0x71, 0x83, 0xbc, 0x1b, 0x18, 0x4b, 0xa3, 0x44, 0x5d, 0x14, + 0xc7, 0xca, 0x55, 0x9a, 0x59, 0x17, 0xeb, 0x3d, 0x0f, 0xea, 0xa5, 0xfe, 0x51, 0xe1, 0x16, 0xf7, + 0x47, 0x89, 0xba, 0x20, 0x2d, 0xa4, 0x46, 0x2b, 0x9a, 0xca, 0x97, 0xa0, 0xde, 0x47, 0xb6, 0x87, + 0x62, 0x6b, 0x4b, 0x46, 0x6e, 0x79, 0xb2, 0xa3, 0xec, 0x72, 0xbd, 0xd1, 0xbe, 0x48, 0xd4, 0x59, + 0xb1, 0xde, 0x2a, 0x28, 0x33, 0x63, 0xcd, 0x9c, 0x15, 0xcb, 0xad, 0x12, 0x65, 0x57, 0x16, 0xf8, + 0x3b, 0x50, 0x76, 0xaf, 0x50, 0x76, 0x73, 0xca, 0xee, 0x76, 0x3d, 0x8d, 0xcf, 0xcb, 0x34, 0x46, + 0x3f, 0x57, 0x41, 0x4d, 0x58, 0x40, 0x1b, 0xcc, 0x53, 0xec, 0x47, 0xc8, 0xb3, 0x04, 0x4c, 0x26, + 0x5c, 0xbb, 0xec, 0x48, 0x0c, 0x84, 0x43, 0x0e, 0x93, 0x4e, 0xd7, 0xce, 0x13, 0x55, 0x29, 0x6a, + 0x66, 0x8c, 0x42, 0x33, 0x9b, 0xb4, 0x84, 0x85, 0xdf, 0x83, 0xf9, 0xfc, 0xdd, 0x2d, 0x8a, 0xb2, + 0xa4, 0xbc, 0xc6, 0x45, 0xfe, 0xa0, 0x87, 0x88, 0x19, 0xad, 0x82, 0x7e, 0xcc, 0x5c, 0x33, 0x9b, + 0x27, 0x25, 0x1c, 0xfc, 0x16, 0x88, 0x26, 0xc9, 0xfd, 0xdf, 0x90, 0xbc, 0x8f, 0x64, 0xa9, 0x7f, + 0x58, 0x6a, 0xb9, 0xb9, 0x9d, 0x66, 0xce, 0x4b, 0x81, 0x2c, 0xf6, 0x00, 0xc0, 0x0c, 0x51, 0x24, + 0xae, 0x7c, 0x8d, 0x9b, 0x4e, 0xff, 0x68, 0x94, 0xa8, 0x2b, 0xe3, 0x5e, 0x0a, 0x0e, 0xcd, 0xfc, + 0x40, 0x0a, 0x8b, 0x14, 0xd6, 0x3e, 0x07, 0xf5, 0x6c, 0xec, 0xc0, 0x35, 0x30, 0x17, 0x0d, 0x43, + 0x14, 0xa7, 0x1a, 0xfe, 0x22, 0x55, 0xb3, 0x10, 0xc0, 0x75, 0xd0, 0xf0, 0x50, 0x44, 0x42, 0x1c, + 0x71, 0x7d, 0x85, 0xeb, 0xcb, 0x22, 0xed, 0xd5, 0x0c, 0x58, 0xd8, 0xa7, 0xfe, 0x4e, 0x8c, 0x6c, + 0x86, 0xc4, 0x64, 0xfc, 0x7f, 0x75, 0x50, 0x93, 0x59, 0x51, 0x79, 0x5b, 0x0a, 0x9a, 0x12, 0x35, + 0x39, 0x5c, 0xab, 0xef, 0x6f, 0xb8, 0x4e, 0xdf, 0xd5, 0x70, 0x9d, 0xb9, 0xb3, 0xe1, 0x5a, 0x7b, + 0x0f, 0xc3, 0xf5, 0xf6, 0xc6, 0x15, 0xdc, 0x03, 0x35, 0x5e, 0xd5, 0x31, 0x9f, 0xa4, 0x4d, 0x63, + 0xeb, 0x4d, 0xa2, 0x6e, 0x96, 0x7a, 0xb7, 0x4b, 0x68, 0x48, 0xa8, 0xfc, 0xd9, 0xa4, 0xde, 0xb1, + 0xfc, 0x8e, 0x7c, 0xe6, 0xba, 0xcf, 0x3c, 0x2f, 0x46, 0x94, 0x9a, 0x92, 0x40, 0x36, 0xea, 0xdf, + 0x15, 0x9e, 0xa3, 0x47, 0x03, 0xef, 0x4e, 0x73, 0xb4, 0xb8, 0x47, 0xf5, 0x76, 0xee, 0xf1, 0xab, + 0x02, 0x1e, 0xee, 0x53, 0xff, 0x70, 0xe8, 0x84, 0x98, 0x89, 0x7b, 0x8c, 0xcd, 0x9f, 0x4f, 0x41, + 0x33, 0x2c, 0xed, 0x65, 0x83, 0x5d, 0x9b, 0x3c, 0x66, 0xd9, 0xc6, 0x1c, 0xb3, 0x28, 0x1d, 0xb9, + 0x72, 0x2b, 0x47, 0x36, 0x0e, 0x5e, 0x5f, 0xb4, 0x95, 0xf3, 0x8b, 0xb6, 0xf2, 0xf7, 0x45, 0x5b, + 0x79, 0x71, 0xd9, 0x9e, 0x3a, 0xbf, 0x6c, 0x4f, 0xfd, 0x79, 0xd9, 0x9e, 0xfa, 0xee, 0xe3, 0xb7, + 0xd2, 0x9e, 0x76, 0xd2, 0xef, 0xf3, 0xc7, 0x9f, 0x6c, 0x4e, 0xfe, 0xcf, 0xe0, 0xd4, 0x78, 0xba, + 0x3e, 0xf9, 0x27, 0x00, 0x00, 0xff, 0xff, 0xe8, 0xb0, 0x57, 0x1e, 0xa1, 0x0c, 0x00, 0x00, } func (m *ClientState) Marshal() (dAtA []byte, err error) { @@ -543,39 +545,49 @@ func (m *ClientState) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x42 } } - if m.LatestHeight != 0 { - i = encodeVarintTendermint(dAtA, i, uint64(m.LatestHeight)) - i-- - dAtA[i] = 0x38 + { + size, err := m.LatestHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTendermint(dAtA, i, uint64(size)) } - if m.FrozenHeight != 0 { - i = encodeVarintTendermint(dAtA, i, uint64(m.FrozenHeight)) - i-- - dAtA[i] = 0x30 - } - n1, err1 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.MaxClockDrift, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.MaxClockDrift):]) - if err1 != nil { - return 0, err1 - } - i -= n1 - i = encodeVarintTendermint(dAtA, i, uint64(n1)) i-- - dAtA[i] = 0x2a - n2, err2 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.UnbondingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.UnbondingPeriod):]) - if err2 != nil { - return 0, err2 + dAtA[i] = 0x3a + { + size, err := m.FrozenHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTendermint(dAtA, i, uint64(size)) } - i -= n2 - i = encodeVarintTendermint(dAtA, i, uint64(n2)) i-- - dAtA[i] = 0x22 - n3, err3 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.TrustingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.TrustingPeriod):]) + dAtA[i] = 0x32 + n3, err3 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.MaxClockDrift, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.MaxClockDrift):]) if err3 != nil { return 0, err3 } i -= n3 i = encodeVarintTendermint(dAtA, i, uint64(n3)) i-- + dAtA[i] = 0x2a + n4, err4 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.UnbondingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.UnbondingPeriod):]) + if err4 != nil { + return 0, err4 + } + i -= n4 + i = encodeVarintTendermint(dAtA, i, uint64(n4)) + i-- + dAtA[i] = 0x22 + n5, err5 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.TrustingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.TrustingPeriod):]) + if err5 != nil { + return 0, err5 + } + i -= n5 + i = encodeVarintTendermint(dAtA, i, uint64(n5)) + i-- dAtA[i] = 0x1a { size, err := m.TrustLevel.MarshalToSizedBuffer(dAtA[:i]) @@ -624,11 +636,16 @@ func (m *ConsensusState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x22 } - if m.Height != 0 { - i = encodeVarintTendermint(dAtA, i, uint64(m.Height)) - i-- - dAtA[i] = 0x18 + { + size, err := m.Height.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTendermint(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0x1a { size, err := m.Root.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -639,12 +656,12 @@ func (m *ConsensusState) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x12 - n6, err6 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) - if err6 != nil { - return 0, err6 + n9, err9 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) + if err9 != nil { + return 0, err9 } - i -= n6 - i = encodeVarintTendermint(dAtA, i, uint64(n6)) + i -= n9 + i = encodeVarintTendermint(dAtA, i, uint64(n9)) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -743,11 +760,16 @@ func (m *Header) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x22 } - if m.TrustedHeight != 0 { - i = encodeVarintTendermint(dAtA, i, uint64(m.TrustedHeight)) - i-- - dAtA[i] = 0x18 + { + size, err := m.TrustedHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTendermint(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0x1a if m.ValidatorSet != nil { { size, err := m.ValidatorSet.MarshalToSizedBuffer(dAtA[:i]) @@ -849,28 +871,28 @@ func (m *MsgCreateClient) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x3a } - n12, err12 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.MaxClockDrift, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.MaxClockDrift):]) - if err12 != nil { - return 0, err12 + n16, err16 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.MaxClockDrift, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.MaxClockDrift):]) + if err16 != nil { + return 0, err16 } - i -= n12 - i = encodeVarintTendermint(dAtA, i, uint64(n12)) + i -= n16 + i = encodeVarintTendermint(dAtA, i, uint64(n16)) i-- dAtA[i] = 0x32 - n13, err13 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.UnbondingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.UnbondingPeriod):]) - if err13 != nil { - return 0, err13 + n17, err17 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.UnbondingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.UnbondingPeriod):]) + if err17 != nil { + return 0, err17 } - i -= n13 - i = encodeVarintTendermint(dAtA, i, uint64(n13)) + i -= n17 + i = encodeVarintTendermint(dAtA, i, uint64(n17)) i-- dAtA[i] = 0x2a - n14, err14 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.TrustingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.TrustingPeriod):]) - if err14 != nil { - return 0, err14 + n18, err18 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.TrustingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.TrustingPeriod):]) + if err18 != nil { + return 0, err18 } - i -= n14 - i = encodeVarintTendermint(dAtA, i, uint64(n14)) + i -= n18 + i = encodeVarintTendermint(dAtA, i, uint64(n18)) i-- dAtA[i] = 0x22 { @@ -1025,12 +1047,10 @@ func (m *ClientState) Size() (n int) { n += 1 + l + sovTendermint(uint64(l)) l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.MaxClockDrift) n += 1 + l + sovTendermint(uint64(l)) - if m.FrozenHeight != 0 { - n += 1 + sovTendermint(uint64(m.FrozenHeight)) - } - if m.LatestHeight != 0 { - n += 1 + sovTendermint(uint64(m.LatestHeight)) - } + l = m.FrozenHeight.Size() + n += 1 + l + sovTendermint(uint64(l)) + l = m.LatestHeight.Size() + n += 1 + l + sovTendermint(uint64(l)) if len(m.ProofSpecs) > 0 { for _, e := range m.ProofSpecs { l = e.Size() @@ -1050,9 +1070,8 @@ func (m *ConsensusState) Size() (n int) { n += 1 + l + sovTendermint(uint64(l)) l = m.Root.Size() n += 1 + l + sovTendermint(uint64(l)) - if m.Height != 0 { - n += 1 + sovTendermint(uint64(m.Height)) - } + l = m.Height.Size() + n += 1 + l + sovTendermint(uint64(l)) l = len(m.NextValidatorsHash) if l > 0 { n += 1 + l + sovTendermint(uint64(l)) @@ -1099,9 +1118,8 @@ func (m *Header) Size() (n int) { l = m.ValidatorSet.Size() n += 1 + l + sovTendermint(uint64(l)) } - if m.TrustedHeight != 0 { - n += 1 + sovTendermint(uint64(m.TrustedHeight)) - } + l = m.TrustedHeight.Size() + n += 1 + l + sovTendermint(uint64(l)) if m.TrustedValidators != nil { l = m.TrustedValidators.Size() n += 1 + l + sovTendermint(uint64(l)) @@ -1397,10 +1415,10 @@ func (m *ClientState) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 6: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field FrozenHeight", wireType) } - m.FrozenHeight = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTendermint @@ -1410,16 +1428,30 @@ func (m *ClientState) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.FrozenHeight |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthTendermint + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTendermint + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.FrozenHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 7: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field LatestHeight", wireType) } - m.LatestHeight = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTendermint @@ -1429,11 +1461,25 @@ func (m *ClientState) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.LatestHeight |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthTendermint + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTendermint + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.LatestHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 8: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofSpecs", wireType) @@ -1588,10 +1634,10 @@ func (m *ConsensusState) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 3: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) } - m.Height = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTendermint @@ -1601,11 +1647,25 @@ func (m *ConsensusState) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Height |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthTendermint + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTendermint + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Height.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field NextValidatorsHash", wireType) @@ -1912,7 +1972,7 @@ func (m *Header) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.SignedHeader == nil { - m.SignedHeader = &types1.SignedHeader{} + m.SignedHeader = &types2.SignedHeader{} } if err := m.SignedHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1948,17 +2008,17 @@ func (m *Header) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.ValidatorSet == nil { - m.ValidatorSet = &types1.ValidatorSet{} + m.ValidatorSet = &types2.ValidatorSet{} } if err := m.ValidatorSet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field TrustedHeight", wireType) } - m.TrustedHeight = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTendermint @@ -1968,11 +2028,25 @@ func (m *Header) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.TrustedHeight |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthTendermint + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTendermint + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TrustedHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field TrustedValidators", wireType) @@ -2003,7 +2077,7 @@ func (m *Header) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.TrustedValidators == nil { - m.TrustedValidators = &types1.ValidatorSet{} + m.TrustedValidators = &types2.ValidatorSet{} } if err := m.TrustedValidators.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/ibc/07-tendermint/types/tendermint_test.go b/x/ibc/07-tendermint/types/tendermint_test.go index 894a589e5..e974de008 100644 --- a/x/ibc/07-tendermint/types/tendermint_test.go +++ b/x/ibc/07-tendermint/types/tendermint_test.go @@ -12,6 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing" ) @@ -19,12 +20,13 @@ import ( const ( chainID = "gaia" clientID = "gaiamainnet" - height = 4 trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 maxClockDrift time.Duration = time.Second * 10 ) +var height = clienttypes.NewHeight(0, 4) + type TendermintTestSuite struct { suite.Suite @@ -69,10 +71,12 @@ func (suite *TendermintTestSuite) SetupTest() { pubKey, err := suite.privVal.GetPubKey() suite.Require().NoError(err) + epochHeight := int64(height.EpochHeight) + val := tmtypes.NewValidator(pubKey, 10) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) suite.valsHash = suite.valSet.Hash() - suite.header = ibctmtypes.CreateTestHeader(chainID, height, height-1, suite.now, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.header = ibctmtypes.CreateTestHeader(chainID, epochHeight, epochHeight-1, suite.now, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) suite.ctx = app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1, Time: suite.now}) } diff --git a/x/ibc/07-tendermint/types/test_utils.go b/x/ibc/07-tendermint/types/test_utils.go index b06461ea2..38a2fa924 100644 --- a/x/ibc/07-tendermint/types/test_utils.go +++ b/x/ibc/07-tendermint/types/test_utils.go @@ -4,6 +4,7 @@ import ( "bytes" "time" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" "github.com/tendermint/tendermint/crypto/tmhash" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/proto/tendermint/version" @@ -75,7 +76,7 @@ func CreateTestHeader(chainID string, height, trustedHeight int64, timestamp tim return &Header{ SignedHeader: &signedHeader, ValidatorSet: valSet, - TrustedHeight: uint64(trustedHeight), + TrustedHeight: clienttypes.NewHeight(0, uint64(trustedHeight)), TrustedValidators: trustedVals, } } diff --git a/x/ibc/07-tendermint/types/update.go b/x/ibc/07-tendermint/types/update.go index 911b65b82..6d1612b17 100644 --- a/x/ibc/07-tendermint/types/update.go +++ b/x/ibc/07-tendermint/types/update.go @@ -46,7 +46,7 @@ func (cs ClientState) CheckHeaderAndUpdateState( } // Get consensus bytes from clientStore - tmConsState, err := GetConsensusState(clientStore, cdc, tmHeader.TrustedHeight) + tmConsState, err := GetConsensusState(clientStore, cdc, tmHeader.TrustedHeight.EpochHeight) if err != nil { return nil, nil, sdkerrors.Wrapf( err, "could not get consensus state from clientstore at TrustedHeight: %d", tmHeader.TrustedHeight, @@ -63,7 +63,7 @@ func (cs ClientState) CheckHeaderAndUpdateState( // checkTrustedHeader checks that consensus state matches trusted fields of Header func checkTrustedHeader(header *Header, consState *ConsensusState) error { - if header.TrustedHeight != consState.Height { + if !header.TrustedHeight.EQ(consState.Height) { return sdkerrors.Wrapf( ErrInvalidHeaderHeight, "trusted header height %d does not match consensus state height %d", @@ -115,7 +115,8 @@ func checkValidity( } // assert header height is newer than consensus state - if header.GetHeight() <= consState.Height { + height := clienttypes.NewHeight(0, header.GetHeight()) + if height.LTE(consState.Height) { return sdkerrors.Wrapf( clienttypes.ErrInvalidHeader, "header height ≤ consensus state height (%d ≤ %d)", header.GetHeight(), consState.Height, @@ -125,7 +126,7 @@ func checkValidity( // Construct a trusted header using the fields in consensus state // Only Height, Time, and NextValidatorsHash are necessary for verification trustedHeader := tmtypes.Header{ - Height: int64(consState.Height), + Height: int64(consState.Height.EpochHeight), Time: consState.Timestamp, NextValidatorsHash: consState.NextValidatorsHash, } @@ -151,11 +152,12 @@ func checkValidity( // update the consensus state from a new header func update(clientState *ClientState, header *Header) (*ClientState, *ConsensusState) { - if header.GetHeight() > clientState.LatestHeight { - clientState.LatestHeight = header.GetHeight() + height := clienttypes.NewHeight(0, header.GetHeight()) + if height.GT(clientState.LatestHeight) { + clientState.LatestHeight = height } consensusState := &ConsensusState{ - Height: header.GetHeight(), + Height: height, Timestamp: header.GetTime(), Root: commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), NextValidatorsHash: header.Header.NextValidatorsHash, diff --git a/x/ibc/07-tendermint/types/update_test.go b/x/ibc/07-tendermint/types/update_test.go index 505e812e5..de80166b2 100644 --- a/x/ibc/07-tendermint/types/update_test.go +++ b/x/ibc/07-tendermint/types/update_test.go @@ -5,6 +5,7 @@ import ( tmtypes "github.com/tendermint/tendermint/types" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" types "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types" ) @@ -22,7 +23,11 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { altPubKey, err := altPrivVal.GetPubKey() suite.Require().NoError(err) - altVal := tmtypes.NewValidator(altPubKey, height) + epochHeight := int64(height.EpochHeight) + heightMinus3 := clienttypes.NewHeight(height.EpochNumber, height.EpochHeight-3) + heightPlus5 := clienttypes.NewHeight(height.EpochNumber, height.EpochHeight+5) + + altVal := tmtypes.NewValidator(altPubKey, epochHeight) // Create bothValSet with both suite validator and altVal. Would be valid update bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) @@ -47,7 +52,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { setup: func() { clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash) - newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = types.CreateTestHeader(chainID, epochHeight+1, epochHeight, suite.headerTime, suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: true, @@ -57,7 +62,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { setup: func() { clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash) - newHeader = types.CreateTestHeader(chainID, height+5, height, suite.headerTime, bothValSet, suite.valSet, bothSigners) + newHeader = types.CreateTestHeader(chainID, epochHeight+5, epochHeight, suite.headerTime, bothValSet, suite.valSet, bothSigners) currentTime = suite.now }, expPass: true, @@ -67,7 +72,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { setup: func() { clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, bothValSet.Hash()) - newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, bothValSet, bothValSet, bothSigners) + newHeader = types.CreateTestHeader(chainID, epochHeight+1, epochHeight, suite.headerTime, bothValSet, bothValSet, bothSigners) currentTime = suite.now }, expPass: true, @@ -76,8 +81,8 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { name: "successful update for a previous height", setup: func() { clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height-3, suite.valsHash) - newHeader = types.CreateTestHeader(chainID, height-1, height-3, suite.headerTime, bothValSet, suite.valSet, bothSigners) + consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), heightMinus3, suite.valsHash) + newHeader = types.CreateTestHeader(chainID, epochHeight-1, epochHeight-3, suite.headerTime, bothValSet, suite.valSet, bothSigners) currentTime = suite.now }, expPass: true, @@ -87,7 +92,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { setup: func() { clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash) - newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, bothValSet, suite.valSet, bothSigners) + newHeader = types.CreateTestHeader(chainID, epochHeight+1, epochHeight, suite.headerTime, bothValSet, suite.valSet, bothSigners) currentTime = suite.now }, expPass: false, @@ -97,7 +102,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { setup: func() { clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, bothValSet.Hash()) - newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, suite.valSet, bothValSet, signers) + newHeader = types.CreateTestHeader(chainID, epochHeight+1, epochHeight, suite.headerTime, suite.valSet, bothValSet, signers) currentTime = suite.now }, expPass: false, @@ -107,7 +112,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { setup: func() { clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash) - newHeader = types.CreateTestHeader(chainID, height+5, height, suite.headerTime, altValSet, suite.valSet, altSigners) + newHeader = types.CreateTestHeader(chainID, epochHeight+5, epochHeight, suite.headerTime, altValSet, suite.valSet, altSigners) currentTime = suite.now }, expPass: false, @@ -117,7 +122,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { setup: func() { clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash) - newHeader = types.CreateTestHeader(chainID, height+5, height, suite.headerTime, bothValSet, bothValSet, bothSigners) + newHeader = types.CreateTestHeader(chainID, epochHeight+5, epochHeight, suite.headerTime, bothValSet, bothValSet, bothSigners) currentTime = suite.now }, expPass: false, @@ -127,7 +132,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { setup: func() { clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash) - newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = types.CreateTestHeader(chainID, epochHeight+1, epochHeight, suite.headerTime, suite.valSet, suite.valSet, signers) // make current time pass trusting period from last timestamp on clientstate currentTime = suite.now.Add(trustingPeriod) }, @@ -138,7 +143,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { setup: func() { clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash) - newHeader = types.CreateTestHeader(chainID, height+1, height, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers) + newHeader = types.CreateTestHeader(chainID, epochHeight+1, epochHeight, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: false, @@ -148,7 +153,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { setup: func() { clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash) - newHeader = types.CreateTestHeader(chainID, height+1, height, suite.clientTime, suite.valSet, suite.valSet, signers) + newHeader = types.CreateTestHeader(chainID, epochHeight+1, epochHeight, suite.clientTime, suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: false, @@ -158,9 +163,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { setup: func() { clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash) - newHeader = types.CreateTestHeader(chainID, height+1, height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = types.CreateTestHeader(chainID, epochHeight+1, epochHeight, suite.headerTime, suite.valSet, suite.valSet, signers) // cause new header to fail validatebasic by changing commit height to mismatch header height - newHeader.SignedHeader.Commit.Height = height - 1 + newHeader.SignedHeader.Commit.Height = epochHeight - 1 currentTime = suite.now }, expPass: false, @@ -168,10 +173,10 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "header height < consensus height", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height+5, commitmenttypes.GetSDKSpecs()) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, heightPlus5, commitmenttypes.GetSDKSpecs()) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), height, suite.valsHash) // Make new header at height less than latest client state - newHeader = types.CreateTestHeader(chainID, height-1, height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = types.CreateTestHeader(chainID, epochHeight-1, epochHeight, suite.headerTime, suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: false, @@ -189,8 +194,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { // Set trusted consensus state in client store suite.chainA.App.IBCKeeper.ClientKeeper.SetClientConsensusState(ctx, clientID, consensusState.GetHeight(), consensusState) + height := clienttypes.NewHeight(0, newHeader.GetHeight()) expectedConsensus := &types.ConsensusState{ - Height: uint64(newHeader.GetHeight()), + Height: height, Timestamp: newHeader.GetTime(), Root: commitmenttypes.NewMerkleRoot(newHeader.Header.GetAppHash()), NextValidatorsHash: newHeader.Header.NextValidatorsHash, @@ -207,12 +213,13 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) // Determine if clientState should be updated or not - if uint64(newHeader.GetHeight()) > clientState.LatestHeight { + // TODO: check the entire Height struct once GetLatestHeight returns clienttypes.Height + if height.GT(clientState.LatestHeight) { // Header Height is greater than clientState latest Height, clientState should be updated with header.GetHeight() - suite.Require().Equal(uint64(newHeader.GetHeight()), newClientState.GetLatestHeight(), "clientstate height did not update") + suite.Require().Equal(height.EpochHeight, newClientState.GetLatestHeight(), "clientstate height did not update") } else { // Update will add past consensus state, clientState should not be updated at all - suite.Require().Equal(clientState.LatestHeight, newClientState.GetLatestHeight(), "client state height updated for past header") + suite.Require().Equal(clientState.LatestHeight.EpochHeight, newClientState.GetLatestHeight(), "client state height updated for past header") } suite.Require().Equal(expectedConsensus, consensusState, "valid test case %d failed: %s", i, tc.name) diff --git a/x/ibc/09-localhost/types/client_state.go b/x/ibc/09-localhost/types/client_state.go index 74e4b1a6f..acf04de1b 100644 --- a/x/ibc/09-localhost/types/client_state.go +++ b/x/ibc/09-localhost/types/client_state.go @@ -24,10 +24,10 @@ import ( var _ clientexported.ClientState = (*ClientState)(nil) // NewClientState creates a new ClientState instance -func NewClientState(chainID string, height int64) *ClientState { +func NewClientState(chainID string, height clienttypes.Height) *ClientState { return &ClientState{ ChainId: chainID, - Height: uint64(height), + Height: height, } } @@ -43,7 +43,7 @@ func (cs ClientState) ClientType() clientexported.ClientType { // GetLatestHeight returns the latest height stored. func (cs ClientState) GetLatestHeight() uint64 { - return cs.Height + return cs.Height.EpochHeight } // IsFrozen returns false. @@ -61,8 +61,8 @@ func (cs ClientState) Validate() error { if strings.TrimSpace(cs.ChainId) == "" { return sdkerrors.Wrap(sdkerrors.ErrInvalidChainID, "chain id cannot be blank") } - if cs.Height <= 0 { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "height must be positive: %d", cs.Height) + if cs.Height.EpochHeight == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "local epoch height cannot be zero") } return nil } @@ -76,9 +76,11 @@ func (cs ClientState) GetProofSpecs() []*ics23.ProofSpec { func (cs ClientState) CheckHeaderAndUpdateState( ctx sdk.Context, _ codec.BinaryMarshaler, _ sdk.KVStore, _ clientexported.Header, ) (clientexported.ClientState, clientexported.ConsensusState, error) { + // Hardcode 0 for epoch number for now + // TODO: Retrieve epoch number from chain-id return NewClientState( ctx.ChainID(), // use the chain ID from context since the client is from the running chain (i.e self). - ctx.BlockHeight(), + clienttypes.NewHeight(0, uint64(ctx.BlockHeight())), ), nil, nil } diff --git a/x/ibc/09-localhost/types/client_state_test.go b/x/ibc/09-localhost/types/client_state_test.go index f5edebc4a..327153b86 100644 --- a/x/ibc/09-localhost/types/client_state_test.go +++ b/x/ibc/09-localhost/types/client_state_test.go @@ -25,17 +25,17 @@ func (suite *LocalhostTestSuite) TestValidate() { }{ { name: "valid client", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clienttypes.NewHeight(3, 10)), expPass: true, }, { name: "invalid chain id", - clientState: types.NewClientState(" ", 10), + clientState: types.NewClientState(" ", clienttypes.NewHeight(3, 10)), expPass: false, }, { name: "invalid height", - clientState: types.NewClientState("chainID", 0), + clientState: types.NewClientState("chainID", clienttypes.Height{}), expPass: false, }, } @@ -51,8 +51,8 @@ func (suite *LocalhostTestSuite) TestValidate() { } func (suite *LocalhostTestSuite) TestVerifyClientState() { - clientState := types.NewClientState("chainID", 10) - invalidClient := types.NewClientState("chainID", 12) + clientState := types.NewClientState("chainID", clientHeight) + invalidClient := types.NewClientState("chainID", clienttypes.NewHeight(0, 12)) testCases := []struct { name string @@ -112,7 +112,7 @@ func (suite *LocalhostTestSuite) TestVerifyClientState() { } func (suite *LocalhostTestSuite) TestVerifyClientConsensusState() { - clientState := types.NewClientState("chainID", 10) + clientState := types.NewClientState("chainID", clientHeight) err := clientState.VerifyClientConsensusState( nil, nil, nil, 0, "", 0, nil, nil, nil, ) @@ -133,7 +133,7 @@ func (suite *LocalhostTestSuite) TestVerifyConnectionState() { }{ { name: "proof verification success", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() { bz, err := suite.cdc.MarshalBinaryBare(&conn1) suite.Require().NoError(err) @@ -144,14 +144,14 @@ func (suite *LocalhostTestSuite) TestVerifyConnectionState() { }, { name: "proof verification failed: connection not stored", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() {}, connection: conn1, expPass: false, }, { name: "proof verification failed: unmarshal error", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() { suite.store.Set(host.KeyConnection(testConnectionID), []byte("connection")) }, @@ -160,7 +160,7 @@ func (suite *LocalhostTestSuite) TestVerifyConnectionState() { }, { name: "proof verification failed: different connection stored", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() { bz, err := suite.cdc.MarshalBinaryBare(&conn2) suite.Require().NoError(err) @@ -205,7 +205,7 @@ func (suite *LocalhostTestSuite) TestVerifyChannelState() { }{ { name: "proof verification success", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() { bz, err := suite.cdc.MarshalBinaryBare(&ch1) suite.Require().NoError(err) @@ -216,14 +216,14 @@ func (suite *LocalhostTestSuite) TestVerifyChannelState() { }, { name: "proof verification failed: channel not stored", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() {}, channel: ch1, expPass: false, }, { name: "proof verification failed: unmarshal failed", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() { suite.store.Set(host.KeyChannel(testPortID, testChannelID), []byte("channel")) @@ -233,7 +233,7 @@ func (suite *LocalhostTestSuite) TestVerifyChannelState() { }, { name: "proof verification failed: different channel stored", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() { bz, err := suite.cdc.MarshalBinaryBare(&ch2) suite.Require().NoError(err) @@ -275,7 +275,7 @@ func (suite *LocalhostTestSuite) TestVerifyPacketCommitment() { }{ { name: "proof verification success", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() { suite.store.Set( host.KeyPacketCommitment(testPortID, testChannelID, testSequence), []byte("commitment"), @@ -286,7 +286,7 @@ func (suite *LocalhostTestSuite) TestVerifyPacketCommitment() { }, { name: "proof verification failed: different commitment stored", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() { suite.store.Set( host.KeyPacketCommitment(testPortID, testChannelID, testSequence), []byte("different"), @@ -297,7 +297,7 @@ func (suite *LocalhostTestSuite) TestVerifyPacketCommitment() { }, { name: "proof verification failed: no commitment stored", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() {}, commitment: []byte{}, expPass: false, @@ -334,7 +334,7 @@ func (suite *LocalhostTestSuite) TestVerifyPacketAcknowledgement() { }{ { name: "proof verification success", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() { suite.store.Set( host.KeyPacketAcknowledgement(testPortID, testChannelID, testSequence), []byte("acknowledgement"), @@ -345,7 +345,7 @@ func (suite *LocalhostTestSuite) TestVerifyPacketAcknowledgement() { }, { name: "proof verification failed: different ack stored", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() { suite.store.Set( host.KeyPacketAcknowledgement(testPortID, testChannelID, testSequence), []byte("different"), @@ -356,7 +356,7 @@ func (suite *LocalhostTestSuite) TestVerifyPacketAcknowledgement() { }, { name: "proof verification failed: no commitment stored", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() {}, ack: []byte{}, expPass: false, @@ -384,7 +384,7 @@ func (suite *LocalhostTestSuite) TestVerifyPacketAcknowledgement() { } func (suite *LocalhostTestSuite) TestVerifyPacketAcknowledgementAbsence() { - clientState := types.NewClientState("chainID", 10) + clientState := types.NewClientState("chainID", clientHeight) err := clientState.VerifyPacketAcknowledgementAbsence( suite.store, suite.cdc, height, nil, nil, testPortID, testChannelID, testSequence, @@ -412,7 +412,7 @@ func (suite *LocalhostTestSuite) TestVerifyNextSeqRecv() { }{ { name: "proof verification success", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() { suite.store.Set( host.KeyNextSequenceRecv(testPortID, testChannelID), @@ -424,7 +424,7 @@ func (suite *LocalhostTestSuite) TestVerifyNextSeqRecv() { }, { name: "proof verification failed: different nextSeqRecv stored", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() { suite.store.Set( host.KeyNextSequenceRecv(testPortID, testChannelID), @@ -436,7 +436,7 @@ func (suite *LocalhostTestSuite) TestVerifyNextSeqRecv() { }, { name: "proof verification failed: no nextSeqRecv stored", - clientState: types.NewClientState("chainID", 10), + clientState: types.NewClientState("chainID", clientHeight), malleate: func() {}, nextSeqRecv: nextSeqRecv, expPass: false, diff --git a/x/ibc/09-localhost/types/localhost.pb.go b/x/ibc/09-localhost/types/localhost.pb.go index fb7907bc7..35dbef2f1 100644 --- a/x/ibc/09-localhost/types/localhost.pb.go +++ b/x/ibc/09-localhost/types/localhost.pb.go @@ -6,6 +6,7 @@ package types import ( fmt "fmt" github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + types "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" io "io" @@ -70,7 +71,7 @@ type ClientState struct { // self chain ID ChainId string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty" yaml:"chain_id"` // self latest block height - Height uint64 `protobuf:"varint,3,opt,name=height,proto3" json:"height,omitempty"` + Height types.Height `protobuf:"bytes,3,opt,name=height,proto3" json:"height"` } func (m *ClientState) Reset() { *m = ClientState{} } @@ -114,26 +115,27 @@ func init() { func init() { proto.RegisterFile("ibc/localhost/localhost.proto", fileDescriptor_6a04d924e6f8a88e) } var fileDescriptor_6a04d924e6f8a88e = []byte{ - // 289 bytes of a gzipped FileDescriptorProto + // 317 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcd, 0x4c, 0x4a, 0xd6, 0xcf, 0xc9, 0x4f, 0x4e, 0xcc, 0xc9, 0xc8, 0x2f, 0x2e, 0x41, 0xb0, 0xf4, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, 0x85, 0x78, 0x33, 0x93, 0x92, 0xf5, 0xe0, 0x82, 0x52, 0x22, 0xe9, 0xf9, 0xe9, 0xf9, 0x60, - 0x19, 0x7d, 0x10, 0x0b, 0xa2, 0x48, 0x29, 0x89, 0x8b, 0xdf, 0xb7, 0x38, 0xdd, 0xb9, 0x28, 0x35, - 0xb1, 0x24, 0xd5, 0x39, 0x27, 0x33, 0x35, 0xaf, 0x44, 0xc8, 0x93, 0x8b, 0xad, 0x38, 0x33, 0x3d, - 0x2f, 0xb5, 0x48, 0x82, 0x51, 0x81, 0x51, 0x83, 0xc7, 0xc9, 0xf0, 0xd7, 0x3d, 0x79, 0xdd, 0xf4, - 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0xfd, 0xe4, 0xfc, 0xe2, 0xdc, 0xfc, 0x62, - 0x28, 0xa5, 0x5b, 0x9c, 0x92, 0xad, 0x5f, 0x52, 0x59, 0x90, 0x5a, 0xac, 0xe7, 0x98, 0x9c, 0xec, - 0x98, 0x92, 0x52, 0x94, 0x5a, 0x5c, 0x1c, 0x04, 0x35, 0xc0, 0x8a, 0xa5, 0x63, 0x81, 0x3c, 0x83, - 0x52, 0x36, 0x17, 0x37, 0xc4, 0xe8, 0xe0, 0x92, 0xc4, 0x92, 0x54, 0x21, 0x3e, 0x2e, 0xa6, 0xcc, - 0x14, 0xb0, 0xd9, 0x9c, 0x41, 0x4c, 0x99, 0x29, 0x42, 0x7a, 0x5c, 0x1c, 0xc9, 0x19, 0x89, 0x99, - 0x79, 0xf1, 0x99, 0x29, 0x12, 0x4c, 0x20, 0x51, 0x27, 0xe1, 0x4f, 0xf7, 0xe4, 0xf9, 0x2b, 0x13, - 0x73, 0x73, 0xac, 0x94, 0x60, 0x32, 0x4a, 0x41, 0xec, 0x60, 0xa6, 0x67, 0x8a, 0x90, 0x18, 0x17, - 0x5b, 0x46, 0x6a, 0x66, 0x7a, 0x46, 0x89, 0x04, 0xb3, 0x02, 0xa3, 0x06, 0x4b, 0x10, 0x94, 0x07, - 0xb1, 0xcc, 0xc9, 0xff, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, - 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0x4c, 0xf1, - 0xfa, 0xa1, 0x42, 0x1f, 0x14, 0x9a, 0x06, 0x96, 0xba, 0x88, 0x00, 0x05, 0x7b, 0x2b, 0x89, 0x0d, - 0x1c, 0x50, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcc, 0x40, 0xad, 0xb8, 0x6e, 0x01, 0x00, - 0x00, + 0x19, 0x7d, 0x10, 0x0b, 0xa2, 0x48, 0x4a, 0x1c, 0x64, 0x46, 0x72, 0x4e, 0x66, 0x6a, 0x5e, 0x09, + 0x94, 0x82, 0x48, 0x28, 0x25, 0x71, 0xf1, 0xfb, 0x16, 0xa7, 0x3b, 0x17, 0xa5, 0x26, 0x96, 0xa4, + 0x3a, 0x83, 0x25, 0x84, 0x3c, 0xb9, 0xd8, 0x8a, 0x33, 0xd3, 0xf3, 0x52, 0x8b, 0x24, 0x18, 0x15, + 0x18, 0x35, 0x78, 0x9c, 0x0c, 0x7f, 0xdd, 0x93, 0xd7, 0x4d, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, + 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0x86, 0x52, 0xba, 0xc5, 0x29, 0xd9, + 0xfa, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x7a, 0x8e, 0xc9, 0xc9, 0x8e, 0x29, 0x29, 0x45, 0xa9, 0xc5, + 0xc5, 0x41, 0x50, 0x03, 0xac, 0x58, 0x3a, 0x16, 0xc8, 0x33, 0x28, 0xb5, 0x32, 0x72, 0x71, 0x43, + 0xcc, 0x0e, 0x2e, 0x49, 0x2c, 0x49, 0x15, 0xe2, 0xe3, 0x62, 0xca, 0x4c, 0x01, 0x1b, 0xce, 0x19, + 0xc4, 0x94, 0x99, 0x22, 0xa4, 0xc7, 0xc5, 0x91, 0x9c, 0x91, 0x98, 0x99, 0x17, 0x9f, 0x99, 0x22, + 0xc1, 0x04, 0x12, 0x75, 0x12, 0xfe, 0x74, 0x4f, 0x9e, 0xbf, 0x32, 0x31, 0x37, 0xc7, 0x4a, 0x09, + 0x26, 0xa3, 0x14, 0xc4, 0x0e, 0x66, 0x7a, 0xa6, 0x08, 0x19, 0x70, 0xb1, 0x65, 0xa4, 0x66, 0xa6, + 0x67, 0x94, 0x48, 0x30, 0x2b, 0x30, 0x6a, 0x70, 0x1b, 0x09, 0xe9, 0x81, 0x82, 0x00, 0xea, 0x2d, + 0x0f, 0xb0, 0x8c, 0x13, 0xcb, 0x89, 0x7b, 0xf2, 0x0c, 0x41, 0x50, 0x75, 0x10, 0x77, 0x38, 0xf9, + 0x9f, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, 0x1e, 0xcb, + 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x29, 0x5e, 0xef, 0x55, 0xe8, + 0x83, 0x42, 0xcf, 0xc0, 0x52, 0x17, 0x11, 0x09, 0x60, 0x1f, 0x27, 0xb1, 0x81, 0xc3, 0xd0, 0x18, + 0x10, 0x00, 0x00, 0xff, 0xff, 0x8d, 0x4e, 0x4d, 0x60, 0xa2, 0x01, 0x00, 0x00, } func (m *MsgCreateClient) Marshal() (dAtA []byte, err error) { @@ -186,11 +188,16 @@ func (m *ClientState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.Height != 0 { - i = encodeVarintLocalhost(dAtA, i, uint64(m.Height)) - i-- - dAtA[i] = 0x18 + { + size, err := m.Height.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintLocalhost(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0x1a if len(m.ChainId) > 0 { i -= len(m.ChainId) copy(dAtA[i:], m.ChainId) @@ -246,9 +253,8 @@ func (m *ClientState) Size() (n int) { if l > 0 { n += 1 + l + sovLocalhost(uint64(l)) } - if m.Height != 0 { - n += 1 + sovLocalhost(uint64(m.Height)) - } + l = m.Height.Size() + n += 1 + l + sovLocalhost(uint64(l)) return n } @@ -439,10 +445,10 @@ func (m *ClientState) Unmarshal(dAtA []byte) error { m.ChainId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) } - m.Height = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowLocalhost @@ -452,11 +458,25 @@ func (m *ClientState) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Height |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthLocalhost + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLocalhost + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Height.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipLocalhost(dAtA[iNdEx:]) diff --git a/x/ibc/09-localhost/types/localhost_test.go b/x/ibc/09-localhost/types/localhost_test.go index 4f3416927..febdf46a9 100644 --- a/x/ibc/09-localhost/types/localhost_test.go +++ b/x/ibc/09-localhost/types/localhost_test.go @@ -10,12 +10,17 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" ) const ( height = 4 ) +var ( + clientHeight = clienttypes.NewHeight(0, 10) +) + type LocalhostTestSuite struct { suite.Suite diff --git a/x/ibc/genesis_test.go b/x/ibc/genesis_test.go index 26666d33a..79fac2403 100644 --- a/x/ibc/genesis_test.go +++ b/x/ibc/genesis_test.go @@ -37,10 +37,10 @@ func (suite *IBCTestSuite) TestValidateGenesis() { ClientGenesis: clienttypes.NewGenesisState( []clienttypes.IdentifiedClientState{ clienttypes.NewIdentifiedClientState( - clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()), + clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs()), ), clienttypes.NewIdentifiedClientState( - clientexported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", 10), + clientexported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", clientHeight), ), }, []clienttypes.ClientConsensusStates{ @@ -48,7 +48,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { clientID, []clientexported.ConsensusState{ ibctmtypes.NewConsensusState( - suite.header.GetTime(), commitmenttypes.NewMerkleRoot(suite.header.Header.AppHash), suite.header.GetHeight(), suite.header.Header.NextValidatorsHash, + suite.header.GetTime(), commitmenttypes.NewMerkleRoot(suite.header.Header.AppHash), clienttypes.NewHeight(0, suite.header.GetHeight()), suite.header.Header.NextValidatorsHash, ), }, ), @@ -97,10 +97,10 @@ func (suite *IBCTestSuite) TestValidateGenesis() { ClientGenesis: clienttypes.NewGenesisState( []clienttypes.IdentifiedClientState{ clienttypes.NewIdentifiedClientState( - clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()), + clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs()), ), clienttypes.NewIdentifiedClientState( - clientexported.ClientTypeLocalHost, localhosttypes.NewClientState("(chaindID)", 0), + clientexported.ClientTypeLocalHost, localhosttypes.NewClientState("(chaindID)", clienttypes.Height{}), ), }, nil, @@ -166,10 +166,10 @@ func (suite *IBCTestSuite) TestInitGenesis() { ClientGenesis: clienttypes.NewGenesisState( []clienttypes.IdentifiedClientState{ clienttypes.NewIdentifiedClientState( - clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()), + clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs()), ), clienttypes.NewIdentifiedClientState( - clientexported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", 10), + clientexported.ClientTypeLocalHost, localhosttypes.NewClientState("chaindID", clientHeight), ), }, []clienttypes.ClientConsensusStates{ @@ -177,7 +177,7 @@ func (suite *IBCTestSuite) TestInitGenesis() { clientID, []clientexported.ConsensusState{ ibctmtypes.NewConsensusState( - suite.header.GetTime(), commitmenttypes.NewMerkleRoot(suite.header.Header.AppHash), suite.header.GetHeight(), suite.header.Header.NextValidatorsHash, + suite.header.GetTime(), commitmenttypes.NewMerkleRoot(suite.header.Header.AppHash), clienttypes.NewHeight(0, suite.header.GetHeight()), suite.header.Header.NextValidatorsHash, ), }, ), diff --git a/x/ibc/ibc_test.go b/x/ibc/ibc_test.go index 9458691ad..c0cff249c 100644 --- a/x/ibc/ibc_test.go +++ b/x/ibc/ibc_test.go @@ -10,6 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" ) @@ -38,6 +39,8 @@ const ( maxClockDrift time.Duration = time.Second * 10 ) +var clientHeight = clienttypes.NewHeight(0, 10) + type IBCTestSuite struct { suite.Suite diff --git a/x/ibc/simulation/decoder_test.go b/x/ibc/simulation/decoder_test.go index 8061b751e..a26315689 100644 --- a/x/ibc/simulation/decoder_test.go +++ b/x/ibc/simulation/decoder_test.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" "github.com/cosmos/cosmos-sdk/types/kv" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types" @@ -25,7 +26,7 @@ func TestDecodeStore(t *testing.T) { portID := "portidone" clientState := &ibctmtypes.ClientState{ - FrozenHeight: 10, + FrozenHeight: clienttypes.NewHeight(0, 10), } connection := connectiontypes.ConnectionEnd{ ClientId: "clientidone", diff --git a/x/ibc/testing/chain.go b/x/ibc/testing/chain.go index aecab44fd..534cd3dfc 100644 --- a/x/ibc/testing/chain.go +++ b/x/ibc/testing/chain.go @@ -25,6 +25,7 @@ import ( capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" ibctransfertypes "github.com/cosmos/cosmos-sdk/x/ibc-transfer/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" @@ -409,7 +410,9 @@ func (chain *TestChain) UpdateTMClient(counterparty *TestChain, clientID string) } } // inject trusted fields into last header - header.TrustedHeight = trustedHeight + // for now assume epoch number is 0 + // TODO: use clienttypes.Height once Header.GetHeight is updated + header.TrustedHeight = clienttypes.NewHeight(0, trustedHeight) trustedVals, err := tmTrustedVals.ToProto() if err != nil { diff --git a/x/staking/types/staking.pb.go b/x/staking/types/staking.pb.go index 9baecc95c..c0c875fb7 100644 --- a/x/staking/types/staking.pb.go +++ b/x/staking/types/staking.pb.go @@ -1265,570 +1265,569 @@ func (this *Pool) Description() (desc *github_com_gogo_protobuf_protoc_gen_gogo_ func StakingDescription() (desc *github_com_gogo_protobuf_protoc_gen_gogo_descriptor.FileDescriptorSet) { d := &github_com_gogo_protobuf_protoc_gen_gogo_descriptor.FileDescriptorSet{} var gzipped = []byte{ - // 9000 bytes of a gzipped FileDescriptorSet - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6b, 0x74, 0x1c, 0xe7, - 0x75, 0x18, 0x67, 0x1f, 0xc0, 0xee, 0xc5, 0x6b, 0xf1, 0x01, 0xa4, 0x96, 0x4b, 0x0a, 0x80, 0x46, - 0xb2, 0x44, 0x51, 0xd2, 0x42, 0xa2, 0x28, 0x92, 0x5a, 0xda, 0x96, 0xb1, 0xc0, 0x12, 0x04, 0x89, - 0x97, 0x06, 0x20, 0x25, 0xdb, 0x49, 0xe7, 0x0c, 0x66, 0x3f, 0x2c, 0x46, 0x9c, 0x9d, 0x19, 0xcd, - 0xcc, 0x92, 0x00, 0x6d, 0x9f, 0xa3, 0xc4, 0x8f, 0xc6, 0x6a, 0x53, 0x3b, 0x8f, 0xd3, 0xda, 0x8e, - 0xe5, 0xfa, 0xd1, 0xd6, 0xa9, 0xd3, 0x36, 0x49, 0x9d, 0xa6, 0x4d, 0xd3, 0xd3, 0x3a, 0xad, 0x93, - 0x38, 0x6d, 0xd3, 0x63, 0x9f, 0xba, 0x6d, 0x9a, 0xd3, 0xd2, 0xa9, 0xec, 0xd3, 0x3a, 0xae, 0xdb, - 0xa4, 0xac, 0xfa, 0xd4, 0x8f, 0xe4, 0x7c, 0xaf, 0x79, 0xec, 0x03, 0xbb, 0x0b, 0x51, 0xb2, 0x75, - 0xa2, 0x5f, 0x98, 0xb9, 0x73, 0xef, 0xfd, 0xee, 0xbd, 0xdf, 0xbd, 0xf7, 0xbb, 0xdf, 0x6b, 0x01, - 0x5f, 0x4d, 0xc0, 0x49, 0xdd, 0xf6, 0xea, 0xb6, 0x37, 0xbb, 0xa5, 0x79, 0x78, 0xf6, 0xf9, 0x06, - 0x76, 0xf7, 0x66, 0xaf, 0x3f, 0xb6, 0x85, 0x7d, 0xed, 0xb1, 0x59, 0x47, 0xab, 0x19, 0x96, 0xe6, - 0x1b, 0xb6, 0x55, 0x74, 0x5c, 0xdb, 0xb7, 0xd1, 0x51, 0x86, 0x5b, 0x24, 0xb8, 0x45, 0x8a, 0x5b, - 0xe4, 0xb8, 0xb2, 0x05, 0x43, 0xeb, 0x5a, 0x0d, 0x2b, 0xf8, 0xf9, 0x06, 0xf6, 0x7c, 0x94, 0x83, - 0xe4, 0x35, 0xbc, 0x97, 0x97, 0x66, 0xa4, 0x13, 0xc3, 0x0a, 0x79, 0x44, 0x47, 0x60, 0xc0, 0xde, - 0xde, 0xf6, 0xb0, 0x9f, 0x4f, 0xcc, 0x48, 0x27, 0x52, 0x0a, 0x7f, 0x43, 0x93, 0x90, 0x36, 0x8d, - 0xba, 0xe1, 0xe7, 0x93, 0x14, 0xcc, 0x5e, 0xd0, 0x34, 0x0c, 0xe9, 0x76, 0xc3, 0xf2, 0x55, 0xdf, - 0xf6, 0x35, 0x33, 0x9f, 0x9a, 0x91, 0x4e, 0x64, 0x14, 0xa0, 0xa0, 0x4d, 0x02, 0x91, 0x9f, 0x82, - 0x61, 0xd6, 0x9e, 0xe7, 0xd8, 0x96, 0x87, 0xd1, 0x51, 0xc8, 0x58, 0x78, 0xd7, 0x57, 0xc3, 0x56, - 0x07, 0xc9, 0xfb, 0x65, 0xbc, 0x47, 0x5a, 0x60, 0x5c, 0x58, 0xc3, 0xec, 0xa5, 0x5c, 0xfe, 0xda, - 0xcb, 0x53, 0xd2, 0xd7, 0x5f, 0x9e, 0x92, 0xfe, 0xe0, 0xe5, 0x29, 0xe9, 0xe3, 0xdf, 0x9e, 0x3a, - 0xf4, 0xf5, 0x6f, 0x4f, 0x1d, 0xfa, 0xbd, 0x6f, 0x4f, 0x1d, 0x7a, 0xcf, 0x89, 0x9a, 0xe1, 0xef, - 0x34, 0xb6, 0x8a, 0xba, 0x5d, 0x9f, 0xe5, 0xc6, 0x61, 0x7f, 0x1e, 0xf1, 0xaa, 0xd7, 0x66, 0xfd, - 0x3d, 0x07, 0x7b, 0xcc, 0x50, 0x5b, 0x03, 0xd4, 0x2c, 0x8f, 0xc3, 0xcf, 0x9d, 0x87, 0x99, 0x9a, - 0x6d, 0xd7, 0x4c, 0x3c, 0x4b, 0x21, 0x5b, 0x8d, 0xed, 0xd9, 0x2a, 0xf6, 0x74, 0xd7, 0x70, 0x7c, - 0xdb, 0xe5, 0xc6, 0x1b, 0x63, 0x18, 0x45, 0x81, 0x21, 0xaf, 0xc0, 0xf8, 0x05, 0xc3, 0xc4, 0x0b, - 0x01, 0xe2, 0x06, 0xf6, 0xd1, 0x39, 0x48, 0x6d, 0x1b, 0x26, 0xce, 0x4b, 0x33, 0xc9, 0x13, 0x43, - 0xa7, 0xee, 0x2b, 0x36, 0x11, 0x15, 0xe3, 0x14, 0xeb, 0x04, 0xac, 0x50, 0x0a, 0xf9, 0x3b, 0x29, - 0x98, 0x68, 0xf3, 0x15, 0x21, 0x48, 0x59, 0x5a, 0x1d, 0x53, 0xab, 0x64, 0x15, 0xfa, 0x8c, 0xf2, - 0x30, 0xe8, 0x68, 0xfa, 0x35, 0xad, 0x86, 0xa9, 0x51, 0xb2, 0x8a, 0x78, 0x45, 0x53, 0x00, 0x55, - 0xec, 0x60, 0xab, 0x8a, 0x2d, 0x7d, 0x2f, 0x9f, 0x9c, 0x49, 0x9e, 0xc8, 0x2a, 0x11, 0x08, 0x7a, - 0x08, 0xc6, 0x9d, 0xc6, 0x96, 0x69, 0xe8, 0x6a, 0x04, 0x0d, 0x66, 0x92, 0x27, 0xd2, 0x4a, 0x8e, - 0x7d, 0x58, 0x08, 0x91, 0x1f, 0x80, 0xb1, 0x1b, 0x58, 0xbb, 0x16, 0x45, 0x1d, 0xa2, 0xa8, 0xa3, - 0x04, 0x1c, 0x41, 0x9c, 0x87, 0xe1, 0x3a, 0xf6, 0x3c, 0xad, 0x86, 0x55, 0x62, 0xdf, 0x7c, 0x8a, - 0x6a, 0x3f, 0xd3, 0xa2, 0x7d, 0xb3, 0xe6, 0x43, 0x9c, 0x6a, 0x73, 0xcf, 0xc1, 0x68, 0x0e, 0xb2, - 0xd8, 0x6a, 0xd4, 0x19, 0x87, 0x74, 0x07, 0xfb, 0x55, 0xac, 0x46, 0xbd, 0x99, 0x4b, 0x86, 0x90, - 0x71, 0x16, 0x83, 0x1e, 0x76, 0xaf, 0x1b, 0x3a, 0xce, 0x0f, 0x50, 0x06, 0x0f, 0xb4, 0x30, 0xd8, - 0x60, 0xdf, 0x9b, 0x79, 0x08, 0x3a, 0x34, 0x0f, 0x59, 0xbc, 0xeb, 0x63, 0xcb, 0x33, 0x6c, 0x2b, - 0x3f, 0x48, 0x99, 0xbc, 0xad, 0x4d, 0x2f, 0x62, 0xb3, 0xda, 0xcc, 0x22, 0xa4, 0x43, 0x67, 0x60, - 0xd0, 0x76, 0x48, 0xe0, 0x79, 0xf9, 0xcc, 0x8c, 0x74, 0x62, 0xe8, 0xd4, 0xf1, 0xb6, 0x8e, 0xb0, - 0xc6, 0x70, 0x14, 0x81, 0x8c, 0x96, 0x20, 0xe7, 0xd9, 0x0d, 0x57, 0xc7, 0xaa, 0x6e, 0x57, 0xb1, - 0x6a, 0x58, 0xdb, 0x76, 0x3e, 0x4b, 0x19, 0x4c, 0xb7, 0x2a, 0x42, 0x11, 0xe7, 0xed, 0x2a, 0x5e, - 0xb2, 0xb6, 0x6d, 0x65, 0xd4, 0x8b, 0xbd, 0x93, 0x78, 0xf5, 0xf6, 0x2c, 0x5f, 0xdb, 0xcd, 0x0f, - 0x53, 0x0f, 0xe1, 0x6f, 0xf2, 0xaf, 0x0d, 0xc0, 0x58, 0x2f, 0x2e, 0x76, 0x1e, 0xd2, 0xdb, 0x44, - 0xcb, 0x7c, 0xa2, 0x1f, 0x1b, 0x30, 0x9a, 0xb8, 0x11, 0x07, 0x0e, 0x68, 0xc4, 0x39, 0x18, 0xb2, - 0xb0, 0xe7, 0xe3, 0x2a, 0xf3, 0x88, 0x64, 0x8f, 0x3e, 0x05, 0x8c, 0xa8, 0xd5, 0xa5, 0x52, 0x07, - 0x72, 0xa9, 0x67, 0x61, 0x2c, 0x10, 0x49, 0x75, 0x35, 0xab, 0x26, 0x7c, 0x73, 0xb6, 0x9b, 0x24, - 0xc5, 0x8a, 0xa0, 0x53, 0x08, 0x99, 0x32, 0x8a, 0x63, 0xef, 0x68, 0x01, 0xc0, 0xb6, 0xb0, 0xbd, - 0xad, 0x56, 0xb1, 0x6e, 0xe6, 0x33, 0x1d, 0xac, 0xb4, 0x46, 0x50, 0x5a, 0xac, 0x64, 0x33, 0xa8, - 0x6e, 0xa2, 0x27, 0x43, 0x57, 0x1b, 0xec, 0xe0, 0x29, 0x2b, 0x2c, 0xc8, 0x5a, 0xbc, 0xed, 0x0a, - 0x8c, 0xba, 0x98, 0xf8, 0x3d, 0xae, 0x72, 0xcd, 0xb2, 0x54, 0x88, 0x62, 0x57, 0xcd, 0x14, 0x4e, - 0xc6, 0x14, 0x1b, 0x71, 0xa3, 0xaf, 0xe8, 0x5e, 0x08, 0x00, 0x2a, 0x75, 0x2b, 0xa0, 0x59, 0x68, - 0x58, 0x00, 0x57, 0xb5, 0x3a, 0x2e, 0xdc, 0x84, 0xd1, 0xb8, 0x79, 0x48, 0x9a, 0xf7, 0x7c, 0xcd, - 0xf5, 0xa9, 0x17, 0xa6, 0x15, 0xf6, 0x42, 0x06, 0x22, 0x6c, 0x55, 0x69, 0x96, 0x4b, 0x2b, 0xe4, - 0x11, 0xbd, 0x2b, 0x54, 0x38, 0x49, 0x15, 0xbe, 0xbf, 0xb5, 0x47, 0x63, 0x9c, 0x9b, 0xf5, 0x2e, - 0x9c, 0x85, 0x91, 0x98, 0x02, 0xbd, 0x36, 0x2d, 0xbf, 0x1f, 0x0e, 0xb7, 0x65, 0x8d, 0x9e, 0x85, - 0xc9, 0x86, 0x65, 0x58, 0x3e, 0x76, 0x1d, 0x17, 0x13, 0x8f, 0x65, 0x4d, 0xe5, 0xff, 0xcb, 0x60, - 0x07, 0x9f, 0xbb, 0x12, 0xc5, 0x66, 0x5c, 0x94, 0x89, 0x46, 0x2b, 0xf0, 0x64, 0x36, 0xf3, 0xdd, - 0xc1, 0xdc, 0x0b, 0x2f, 0xbc, 0xf0, 0x42, 0x42, 0xfe, 0xc4, 0x00, 0x4c, 0xb6, 0x8b, 0x99, 0xb6, - 0xe1, 0x7b, 0x04, 0x06, 0xac, 0x46, 0x7d, 0x0b, 0xbb, 0xd4, 0x48, 0x69, 0x85, 0xbf, 0xa1, 0x39, - 0x48, 0x9b, 0xda, 0x16, 0x66, 0x43, 0xf2, 0xe8, 0xa9, 0x87, 0x7a, 0x8a, 0xca, 0xe2, 0x32, 0x21, - 0x51, 0x18, 0x25, 0x7a, 0x27, 0xa4, 0x78, 0x8a, 0x26, 0x1c, 0x4e, 0xf6, 0xc6, 0x81, 0xc4, 0x92, - 0x42, 0xe9, 0xd0, 0x31, 0xc8, 0x92, 0xbf, 0xcc, 0x37, 0x06, 0xa8, 0xcc, 0x19, 0x02, 0x20, 0x7e, - 0x81, 0x0a, 0x90, 0xa1, 0x61, 0x52, 0xc5, 0x62, 0x68, 0x0b, 0xde, 0x89, 0x63, 0x55, 0xf1, 0xb6, - 0xd6, 0x30, 0x7d, 0xf5, 0xba, 0x66, 0x36, 0x30, 0x75, 0xf8, 0xac, 0x32, 0xcc, 0x81, 0x57, 0x09, - 0x8c, 0x54, 0x1e, 0x2c, 0xaa, 0x0c, 0xab, 0x8a, 0x77, 0x69, 0xf6, 0x4c, 0x2b, 0x2c, 0xd0, 0x96, - 0x08, 0x84, 0x34, 0xff, 0x9c, 0x67, 0x5b, 0xc2, 0x35, 0x69, 0x13, 0x04, 0x40, 0x9b, 0x3f, 0xdb, - 0x9c, 0xb8, 0xef, 0x6e, 0xaf, 0x5e, 0xb3, 0x4f, 0xc9, 0xbf, 0x9a, 0x80, 0x14, 0xcd, 0x17, 0x63, - 0x30, 0xb4, 0xf9, 0xee, 0xf5, 0x8a, 0xba, 0xb0, 0x76, 0xa5, 0xbc, 0x5c, 0xc9, 0x49, 0x68, 0x14, - 0x80, 0x02, 0x2e, 0x2c, 0xaf, 0xcd, 0x6d, 0xe6, 0x12, 0xc1, 0xfb, 0xd2, 0xea, 0xe6, 0x99, 0xd3, - 0xb9, 0x64, 0x40, 0x70, 0x85, 0x01, 0x52, 0x51, 0x84, 0xc7, 0x4f, 0xe5, 0xd2, 0x28, 0x07, 0xc3, - 0x8c, 0xc1, 0xd2, 0xb3, 0x95, 0x85, 0x33, 0xa7, 0x73, 0x03, 0x71, 0xc8, 0xe3, 0xa7, 0x72, 0x83, - 0x68, 0x04, 0xb2, 0x14, 0x52, 0x5e, 0x5b, 0x5b, 0xce, 0x65, 0x02, 0x9e, 0x1b, 0x9b, 0xca, 0xd2, - 0xea, 0x62, 0x2e, 0x1b, 0xf0, 0x5c, 0x54, 0xd6, 0xae, 0xac, 0xe7, 0x20, 0xe0, 0xb0, 0x52, 0xd9, - 0xd8, 0x98, 0x5b, 0xac, 0xe4, 0x86, 0x02, 0x8c, 0xf2, 0xbb, 0x37, 0x2b, 0x1b, 0xb9, 0xe1, 0x98, - 0x58, 0x8f, 0x9f, 0xca, 0x8d, 0x04, 0x4d, 0x54, 0x56, 0xaf, 0xac, 0xe4, 0x46, 0xd1, 0x38, 0x8c, - 0xb0, 0x26, 0x84, 0x10, 0x63, 0x4d, 0xa0, 0x33, 0xa7, 0x73, 0xb9, 0x50, 0x10, 0xc6, 0x65, 0x3c, - 0x06, 0x38, 0x73, 0x3a, 0x87, 0xe4, 0x79, 0x48, 0x53, 0xef, 0x42, 0x08, 0x46, 0x97, 0xe7, 0xca, - 0x95, 0x65, 0x75, 0x6d, 0x7d, 0x73, 0x69, 0x6d, 0x75, 0x6e, 0x39, 0x27, 0x85, 0x30, 0xa5, 0xf2, - 0xf4, 0x95, 0x25, 0xa5, 0xb2, 0x90, 0x4b, 0x44, 0x61, 0xeb, 0x95, 0xb9, 0xcd, 0xca, 0x42, 0x2e, - 0x29, 0xeb, 0x30, 0xd9, 0x2e, 0x4f, 0xb6, 0x8d, 0x8c, 0x48, 0x17, 0x27, 0x3a, 0x74, 0x31, 0xe5, - 0xd5, 0xd2, 0xc5, 0xdf, 0x4e, 0xc0, 0x44, 0x9b, 0xb1, 0xa2, 0x6d, 0x23, 0x4f, 0x41, 0x9a, 0xb9, - 0x28, 0x1b, 0x3d, 0x1f, 0x6c, 0x3b, 0xe8, 0x50, 0x87, 0x6d, 0x19, 0x41, 0x29, 0x5d, 0xb4, 0x82, - 0x48, 0x76, 0xa8, 0x20, 0x08, 0x8b, 0x96, 0x9c, 0xfe, 0xa3, 0x2d, 0x39, 0x9d, 0x0d, 0x7b, 0x67, - 0x7a, 0x19, 0xf6, 0x28, 0xac, 0xbf, 0xdc, 0x9e, 0x6e, 0x93, 0xdb, 0xcf, 0xc3, 0x78, 0x0b, 0xa3, - 0x9e, 0x73, 0xec, 0x07, 0x25, 0xc8, 0x77, 0x32, 0x4e, 0x97, 0x4c, 0x97, 0x88, 0x65, 0xba, 0xf3, - 0xcd, 0x16, 0xbc, 0xa7, 0x73, 0x27, 0xb4, 0xf4, 0xf5, 0x17, 0x25, 0x38, 0xd2, 0xbe, 0x52, 0x6c, - 0x2b, 0xc3, 0x3b, 0x61, 0xa0, 0x8e, 0xfd, 0x1d, 0x5b, 0x54, 0x4b, 0xf7, 0xb7, 0x19, 0x83, 0xc9, - 0xe7, 0xe6, 0xce, 0xe6, 0x54, 0xd1, 0x41, 0x3c, 0xd9, 0xa9, 0xdc, 0x63, 0xd2, 0xb4, 0x48, 0xfa, - 0xd1, 0x04, 0x1c, 0x6e, 0xcb, 0xbc, 0xad, 0xa0, 0x77, 0x03, 0x18, 0x96, 0xd3, 0xf0, 0x59, 0x45, - 0xc4, 0x12, 0x6c, 0x96, 0x42, 0x68, 0xf2, 0x22, 0xc9, 0xb3, 0xe1, 0x07, 0xdf, 0x93, 0xf4, 0x3b, - 0x30, 0x10, 0x45, 0x38, 0x17, 0x0a, 0x9a, 0xa2, 0x82, 0x4e, 0x75, 0xd0, 0xb4, 0xc5, 0x31, 0x1f, - 0x85, 0x9c, 0x6e, 0x1a, 0xd8, 0xf2, 0x55, 0xcf, 0x77, 0xb1, 0x56, 0x37, 0xac, 0x1a, 0x1d, 0x41, - 0x32, 0xa5, 0xf4, 0xb6, 0x66, 0x7a, 0x58, 0x19, 0x63, 0x9f, 0x37, 0xc4, 0x57, 0x42, 0x41, 0x1d, - 0xc8, 0x8d, 0x50, 0x0c, 0xc4, 0x28, 0xd8, 0xe7, 0x80, 0x42, 0xfe, 0xe9, 0x2c, 0x0c, 0x45, 0xea, - 0x6a, 0x74, 0x0f, 0x0c, 0x3f, 0xa7, 0x5d, 0xd7, 0x54, 0x31, 0x57, 0x62, 0x96, 0x18, 0x22, 0xb0, - 0x75, 0x3e, 0x5f, 0x7a, 0x14, 0x26, 0x29, 0x8a, 0xdd, 0xf0, 0xb1, 0xab, 0xea, 0xa6, 0xe6, 0x79, - 0xd4, 0x68, 0x19, 0x8a, 0x8a, 0xc8, 0xb7, 0x35, 0xf2, 0x69, 0x5e, 0x7c, 0x41, 0x4f, 0xc0, 0x04, - 0xa5, 0xa8, 0x37, 0x4c, 0xdf, 0x70, 0x4c, 0xac, 0x92, 0xd9, 0x9b, 0x47, 0x47, 0x92, 0x40, 0xb2, - 0x71, 0x82, 0xb1, 0xc2, 0x11, 0x88, 0x44, 0x1e, 0x5a, 0x80, 0xbb, 0x29, 0x59, 0x0d, 0x5b, 0xd8, - 0xd5, 0x7c, 0xac, 0xe2, 0xe7, 0x1b, 0x9a, 0xe9, 0xa9, 0x9a, 0x55, 0x55, 0x77, 0x34, 0x6f, 0x27, - 0x3f, 0x49, 0x18, 0x94, 0x13, 0x79, 0x49, 0x39, 0x4a, 0x10, 0x17, 0x39, 0x5e, 0x85, 0xa2, 0xcd, - 0x59, 0xd5, 0x8b, 0x9a, 0xb7, 0x83, 0x4a, 0x70, 0x84, 0x72, 0xf1, 0x7c, 0xd7, 0xb0, 0x6a, 0xaa, - 0xbe, 0x83, 0xf5, 0x6b, 0x6a, 0xc3, 0xdf, 0x3e, 0x97, 0x3f, 0x16, 0x6d, 0x9f, 0x4a, 0xb8, 0x41, - 0x71, 0xe6, 0x09, 0xca, 0x15, 0x7f, 0xfb, 0x1c, 0xda, 0x80, 0x61, 0xd2, 0x19, 0x75, 0xe3, 0x26, - 0x56, 0xb7, 0x6d, 0x97, 0x0e, 0x8d, 0xa3, 0x6d, 0x52, 0x53, 0xc4, 0x82, 0xc5, 0x35, 0x4e, 0xb0, - 0x62, 0x57, 0x71, 0x29, 0xbd, 0xb1, 0x5e, 0xa9, 0x2c, 0x28, 0x43, 0x82, 0xcb, 0x05, 0xdb, 0x25, - 0x0e, 0x55, 0xb3, 0x03, 0x03, 0x0f, 0x31, 0x87, 0xaa, 0xd9, 0xc2, 0xbc, 0x4f, 0xc0, 0x84, 0xae, - 0x33, 0x9d, 0x0d, 0x5d, 0xe5, 0x73, 0x2c, 0x2f, 0x9f, 0x8b, 0x19, 0x4b, 0xd7, 0x17, 0x19, 0x02, - 0xf7, 0x71, 0x0f, 0x3d, 0x09, 0x87, 0x43, 0x63, 0x45, 0x09, 0xc7, 0x5b, 0xb4, 0x6c, 0x26, 0x7d, - 0x02, 0x26, 0x9c, 0xbd, 0x56, 0x42, 0x14, 0x6b, 0xd1, 0xd9, 0x6b, 0x26, 0x3b, 0x0b, 0x93, 0xce, - 0x8e, 0xd3, 0x4a, 0x77, 0x32, 0x4a, 0x87, 0x9c, 0x1d, 0xa7, 0x99, 0xf0, 0x6d, 0x74, 0xc2, 0xed, - 0x62, 0x5d, 0xf3, 0x71, 0x35, 0x7f, 0x57, 0x14, 0x3d, 0xf2, 0x01, 0xcd, 0x42, 0x4e, 0xd7, 0x55, - 0x6c, 0x69, 0x5b, 0x26, 0x56, 0x35, 0x17, 0x5b, 0x9a, 0x97, 0x9f, 0x8e, 0x22, 0x8f, 0xea, 0x7a, - 0x85, 0x7e, 0x9d, 0xa3, 0x1f, 0xd1, 0x49, 0x18, 0xb7, 0xb7, 0x9e, 0xd3, 0x99, 0x4b, 0xaa, 0x8e, - 0x8b, 0xb7, 0x8d, 0xdd, 0xfc, 0x7d, 0xd4, 0xbe, 0x63, 0xe4, 0x03, 0x75, 0xc8, 0x75, 0x0a, 0x46, - 0x0f, 0x42, 0x4e, 0xf7, 0x76, 0x34, 0xd7, 0xa1, 0x39, 0xd9, 0x73, 0x34, 0x1d, 0xe7, 0xdf, 0xc6, - 0x50, 0x19, 0x7c, 0x55, 0x80, 0x49, 0x48, 0x78, 0x37, 0x8c, 0x6d, 0x5f, 0x70, 0x7c, 0x80, 0x85, - 0x04, 0x85, 0x71, 0x6e, 0x27, 0x20, 0x47, 0x4c, 0x11, 0x6b, 0xf8, 0x04, 0x45, 0x1b, 0x75, 0x76, - 0x9c, 0x68, 0xbb, 0xf7, 0xc2, 0x08, 0xc1, 0x0c, 0x1b, 0x7d, 0x90, 0x15, 0x64, 0xce, 0x4e, 0xa4, - 0xc5, 0xd3, 0x70, 0x84, 0x20, 0xd5, 0xb1, 0xaf, 0x55, 0x35, 0x5f, 0x8b, 0x60, 0x3f, 0x4c, 0xb1, - 0x89, 0xdd, 0x57, 0xf8, 0xc7, 0x98, 0x9c, 0x6e, 0x63, 0x6b, 0x2f, 0xf0, 0xac, 0x47, 0x98, 0x9c, - 0x04, 0x26, 0x7c, 0xeb, 0x75, 0x2b, 0xba, 0xe5, 0x12, 0x0c, 0x47, 0x1d, 0x1f, 0x65, 0x81, 0xb9, - 0x7e, 0x4e, 0x22, 0x55, 0xd0, 0xfc, 0xda, 0x02, 0xa9, 0x5f, 0xde, 0x53, 0xc9, 0x25, 0x48, 0x1d, - 0xb5, 0xbc, 0xb4, 0x59, 0x51, 0x95, 0x2b, 0xab, 0x9b, 0x4b, 0x2b, 0x95, 0x5c, 0x32, 0x52, 0xb0, - 0x5f, 0x4a, 0x65, 0xee, 0xcf, 0x3d, 0x20, 0x7f, 0x23, 0x01, 0xa3, 0xf1, 0x19, 0x18, 0x7a, 0x3b, - 0xdc, 0x25, 0x96, 0x4b, 0x3c, 0xec, 0xab, 0x37, 0x0c, 0x97, 0x46, 0x64, 0x5d, 0x63, 0xa3, 0x63, - 0xe0, 0x13, 0x93, 0x1c, 0x6b, 0x03, 0xfb, 0xcf, 0x18, 0x2e, 0x89, 0xb7, 0xba, 0xe6, 0xa3, 0x65, - 0x98, 0xb6, 0x6c, 0xd5, 0xf3, 0x35, 0xab, 0xaa, 0xb9, 0x55, 0x35, 0x5c, 0xa8, 0x52, 0x35, 0x5d, - 0xc7, 0x9e, 0x67, 0xb3, 0x91, 0x30, 0xe0, 0x72, 0xdc, 0xb2, 0x37, 0x38, 0x72, 0x38, 0x44, 0xcc, - 0x71, 0xd4, 0x26, 0xff, 0x4d, 0x76, 0xf2, 0xdf, 0x63, 0x90, 0xad, 0x6b, 0x8e, 0x8a, 0x2d, 0xdf, - 0xdd, 0xa3, 0x75, 0x77, 0x46, 0xc9, 0xd4, 0x35, 0xa7, 0x42, 0xde, 0xdf, 0x90, 0xe9, 0xcf, 0xa5, - 0x54, 0x26, 0x93, 0xcb, 0x5e, 0x4a, 0x65, 0xb2, 0x39, 0x90, 0x5f, 0x4e, 0xc2, 0x70, 0xb4, 0x0e, - 0x27, 0xd3, 0x1a, 0x9d, 0x0e, 0x59, 0x12, 0x4d, 0x6a, 0xf7, 0xee, 0x5b, 0xb5, 0x17, 0xe7, 0xc9, - 0x58, 0x56, 0x1a, 0x60, 0xd5, 0xb1, 0xc2, 0x28, 0x49, 0x1d, 0x41, 0x9c, 0x0d, 0xb3, 0x6a, 0x24, - 0xa3, 0xf0, 0x37, 0xb4, 0x08, 0x03, 0xcf, 0x79, 0x94, 0xf7, 0x00, 0xe5, 0x7d, 0xdf, 0xfe, 0xbc, - 0x2f, 0x6d, 0x50, 0xe6, 0xd9, 0x4b, 0x1b, 0xea, 0xea, 0x9a, 0xb2, 0x32, 0xb7, 0xac, 0x70, 0x72, - 0x74, 0x14, 0x52, 0xa6, 0x76, 0x73, 0x2f, 0x3e, 0xea, 0x51, 0x50, 0xaf, 0x9d, 0x70, 0x14, 0x52, - 0x37, 0xb0, 0x76, 0x2d, 0x3e, 0xd6, 0x50, 0xd0, 0xeb, 0x18, 0x0c, 0xb3, 0x90, 0xa6, 0xf6, 0x42, - 0x00, 0xdc, 0x62, 0xb9, 0x43, 0x28, 0x03, 0xa9, 0xf9, 0x35, 0x85, 0x04, 0x44, 0x0e, 0x86, 0x19, - 0x54, 0x5d, 0x5f, 0xaa, 0xcc, 0x57, 0x72, 0x09, 0xf9, 0x09, 0x18, 0x60, 0x46, 0x20, 0xc1, 0x12, - 0x98, 0x21, 0x77, 0x88, 0xbf, 0x72, 0x1e, 0x92, 0xf8, 0x7a, 0x65, 0xa5, 0x5c, 0x51, 0x72, 0x89, - 0x78, 0x57, 0xa7, 0x72, 0x69, 0xd9, 0x83, 0xe1, 0x68, 0x21, 0xfe, 0xc6, 0x4c, 0xb2, 0xbf, 0x22, - 0xc1, 0x50, 0xa4, 0xb0, 0x26, 0x15, 0x91, 0x66, 0x9a, 0xf6, 0x0d, 0x55, 0x33, 0x0d, 0xcd, 0xe3, - 0xae, 0x01, 0x14, 0x34, 0x47, 0x20, 0xbd, 0x76, 0xdd, 0x1b, 0x14, 0x22, 0xe9, 0xdc, 0x80, 0xfc, - 0x19, 0x09, 0x72, 0xcd, 0x95, 0x6d, 0x93, 0x98, 0xd2, 0x0f, 0x52, 0x4c, 0xf9, 0xd3, 0x12, 0x8c, - 0xc6, 0xcb, 0xd9, 0x26, 0xf1, 0xee, 0xf9, 0x81, 0x8a, 0xf7, 0x07, 0x09, 0x18, 0x89, 0x15, 0xb1, - 0xbd, 0x4a, 0xf7, 0x3c, 0x8c, 0x1b, 0x55, 0x5c, 0x77, 0x6c, 0x1f, 0x5b, 0xfa, 0x9e, 0x6a, 0xe2, - 0xeb, 0xd8, 0xcc, 0xcb, 0x34, 0x69, 0xcc, 0xee, 0x5f, 0x26, 0x17, 0x97, 0x42, 0xba, 0x65, 0x42, - 0x56, 0x9a, 0x58, 0x5a, 0xa8, 0xac, 0xac, 0xaf, 0x6d, 0x56, 0x56, 0xe7, 0xdf, 0xad, 0x5e, 0x59, - 0xbd, 0xbc, 0xba, 0xf6, 0xcc, 0xaa, 0x92, 0x33, 0x9a, 0xd0, 0x5e, 0xc7, 0xb0, 0x5f, 0x87, 0x5c, - 0xb3, 0x50, 0xe8, 0x2e, 0x68, 0x27, 0x56, 0xee, 0x10, 0x9a, 0x80, 0xb1, 0xd5, 0x35, 0x75, 0x63, - 0x69, 0xa1, 0xa2, 0x56, 0x2e, 0x5c, 0xa8, 0xcc, 0x6f, 0x6e, 0xb0, 0x85, 0x8f, 0x00, 0x7b, 0x33, - 0x16, 0xe0, 0xf2, 0xa7, 0x92, 0x30, 0xd1, 0x46, 0x12, 0x34, 0xc7, 0xa7, 0x2c, 0x6c, 0x16, 0xf5, - 0x48, 0x2f, 0xd2, 0x17, 0x49, 0xcd, 0xb0, 0xae, 0xb9, 0x3e, 0x9f, 0xe1, 0x3c, 0x08, 0xc4, 0x4a, - 0x96, 0x6f, 0x6c, 0x1b, 0xd8, 0xe5, 0xeb, 0x44, 0x6c, 0x1e, 0x33, 0x16, 0xc2, 0xd9, 0x52, 0xd1, - 0xc3, 0x80, 0x1c, 0xdb, 0x33, 0x7c, 0xe3, 0x3a, 0x56, 0x0d, 0x4b, 0x2c, 0x2a, 0xa5, 0xe8, 0x2e, - 0x53, 0x4e, 0x7c, 0x59, 0xb2, 0xfc, 0x00, 0xdb, 0xc2, 0x35, 0xad, 0x09, 0x9b, 0x24, 0xf3, 0xa4, - 0x92, 0x13, 0x5f, 0x02, 0xec, 0x7b, 0x60, 0xb8, 0x6a, 0x37, 0x48, 0xb1, 0xc7, 0xf0, 0xc8, 0xd8, - 0x21, 0x29, 0x43, 0x0c, 0x16, 0xa0, 0xf0, 0x32, 0x3e, 0x5c, 0xcd, 0x1a, 0x56, 0x86, 0x18, 0x8c, - 0xa1, 0x3c, 0x00, 0x63, 0x5a, 0xad, 0xe6, 0x12, 0xe6, 0x82, 0x11, 0x9b, 0x98, 0x8c, 0x06, 0x60, - 0x8a, 0x58, 0xb8, 0x04, 0x19, 0x61, 0x07, 0x32, 0x54, 0x13, 0x4b, 0xa8, 0x0e, 0x9b, 0x6d, 0x27, - 0x4e, 0x64, 0x95, 0x8c, 0x25, 0x3e, 0xde, 0x03, 0xc3, 0x86, 0xa7, 0x86, 0x8b, 0xf3, 0x89, 0x99, - 0xc4, 0x89, 0x8c, 0x32, 0x64, 0x78, 0xc1, 0xc2, 0xa6, 0xfc, 0xc5, 0x04, 0x8c, 0xc6, 0x37, 0x17, - 0xd0, 0x02, 0x64, 0x4c, 0x5b, 0xa7, 0x5b, 0x89, 0x7c, 0x67, 0xeb, 0x44, 0x97, 0xfd, 0x88, 0xe2, - 0x32, 0xc7, 0x57, 0x02, 0xca, 0xc2, 0xbf, 0x92, 0x20, 0x23, 0xc0, 0xe8, 0x08, 0xa4, 0x1c, 0xcd, - 0xdf, 0xa1, 0xec, 0xd2, 0xe5, 0x44, 0x4e, 0x52, 0xe8, 0x3b, 0x81, 0x7b, 0x8e, 0x66, 0x51, 0x17, - 0xe0, 0x70, 0xf2, 0x4e, 0xfa, 0xd5, 0xc4, 0x5a, 0x95, 0xce, 0x7a, 0xec, 0x7a, 0x1d, 0x5b, 0xbe, - 0x27, 0xfa, 0x95, 0xc3, 0xe7, 0x39, 0x18, 0x3d, 0x04, 0xe3, 0xbe, 0xab, 0x19, 0x66, 0x0c, 0x37, - 0x45, 0x71, 0x73, 0xe2, 0x43, 0x80, 0x5c, 0x82, 0xa3, 0x82, 0x6f, 0x15, 0xfb, 0x9a, 0xbe, 0x83, - 0xab, 0x21, 0xd1, 0x00, 0x5d, 0xdd, 0xb8, 0x8b, 0x23, 0x2c, 0xf0, 0xef, 0x82, 0x56, 0xfe, 0x86, - 0x04, 0xe3, 0x62, 0x9e, 0x56, 0x0d, 0x8c, 0xb5, 0x02, 0xa0, 0x59, 0x96, 0xed, 0x47, 0xcd, 0xd5, - 0xea, 0xca, 0x2d, 0x74, 0xc5, 0xb9, 0x80, 0x48, 0x89, 0x30, 0x28, 0xd4, 0x01, 0xc2, 0x2f, 0x1d, - 0xcd, 0x36, 0x0d, 0x43, 0x7c, 0xe7, 0x88, 0x6e, 0x3f, 0xb2, 0x99, 0x3d, 0x30, 0x10, 0x99, 0xd0, - 0xa1, 0x49, 0x48, 0x6f, 0xe1, 0x9a, 0x61, 0xf1, 0xf5, 0x60, 0xf6, 0x22, 0xd6, 0x5f, 0x52, 0xc1, - 0xfa, 0x4b, 0xf9, 0x63, 0x12, 0x4c, 0xe8, 0x76, 0xbd, 0x59, 0xde, 0x72, 0xae, 0x69, 0x79, 0xc1, - 0xbb, 0x28, 0xbd, 0xe7, 0x9d, 0x91, 0x9d, 0xd6, 0x9a, 0x6d, 0x6a, 0x56, 0x2d, 0xdc, 0x3f, 0xa5, - 0x0f, 0xfa, 0x23, 0x35, 0x6c, 0x3d, 0x52, 0xb3, 0x23, 0xbb, 0xa9, 0xe7, 0xc3, 0xc7, 0xff, 0x2b, - 0x49, 0x9f, 0x4f, 0x24, 0x17, 0xd7, 0xcb, 0x5f, 0x4a, 0x14, 0x16, 0x59, 0x73, 0xeb, 0xc2, 0x3c, - 0x0a, 0xde, 0x36, 0xb1, 0x4e, 0x54, 0x86, 0xef, 0x3d, 0x04, 0x93, 0x35, 0xbb, 0x66, 0x53, 0x8e, - 0xb3, 0xe4, 0x89, 0xef, 0xc8, 0x66, 0x03, 0x68, 0xa1, 0xeb, 0xf6, 0x6d, 0x69, 0x15, 0x26, 0x38, - 0xb2, 0x4a, 0xb7, 0x84, 0xd8, 0xc4, 0x06, 0xed, 0xbb, 0xac, 0x96, 0xff, 0xe5, 0xef, 0xd0, 0x01, - 0x5d, 0x19, 0xe7, 0xa4, 0xe4, 0x1b, 0x9b, 0xfb, 0x94, 0x14, 0x38, 0x1c, 0xe3, 0xc7, 0xc2, 0x16, - 0xbb, 0x5d, 0x38, 0xfe, 0x26, 0xe7, 0x38, 0x11, 0xe1, 0xb8, 0xc1, 0x49, 0x4b, 0xf3, 0x30, 0xd2, - 0x0f, 0xaf, 0xdf, 0xe2, 0xbc, 0x86, 0x71, 0x94, 0xc9, 0x22, 0x8c, 0x51, 0x26, 0x7a, 0xc3, 0xf3, - 0xed, 0x3a, 0xcd, 0x89, 0xfb, 0xb3, 0xf9, 0xed, 0xef, 0xb0, 0x38, 0x1a, 0x25, 0x64, 0xf3, 0x01, - 0x55, 0xa9, 0x04, 0x74, 0x17, 0xac, 0x8a, 0x75, 0xb3, 0x0b, 0x87, 0xaf, 0x71, 0x41, 0x02, 0xfc, - 0xd2, 0x55, 0x98, 0x24, 0xcf, 0x34, 0x65, 0x45, 0x25, 0xe9, 0xbe, 0x06, 0x97, 0xff, 0xc6, 0x07, - 0x59, 0xa8, 0x4e, 0x04, 0x0c, 0x22, 0x32, 0x45, 0x7a, 0xb1, 0x86, 0x7d, 0x1f, 0xbb, 0x9e, 0xaa, - 0x99, 0xed, 0xc4, 0x8b, 0x2c, 0x62, 0xe4, 0x3f, 0xf9, 0xfd, 0x78, 0x2f, 0x2e, 0x32, 0xca, 0x39, - 0xd3, 0x2c, 0x5d, 0x81, 0xbb, 0xda, 0x78, 0x45, 0x0f, 0x3c, 0x3f, 0xc5, 0x79, 0x4e, 0xb6, 0x78, - 0x06, 0x61, 0xbb, 0x0e, 0x02, 0x1e, 0xf4, 0x65, 0x0f, 0x3c, 0x7f, 0x8e, 0xf3, 0x44, 0x9c, 0x56, - 0x74, 0x29, 0xe1, 0x78, 0x09, 0xc6, 0xaf, 0x63, 0x77, 0xcb, 0xf6, 0xf8, 0xc2, 0x51, 0x0f, 0xec, - 0x3e, 0xcd, 0xd9, 0x8d, 0x71, 0x42, 0xba, 0x92, 0x44, 0x78, 0x3d, 0x09, 0x99, 0x6d, 0x4d, 0xc7, - 0x3d, 0xb0, 0x78, 0x89, 0xb3, 0x18, 0x24, 0xf8, 0x84, 0x74, 0x0e, 0x86, 0x6b, 0x36, 0x1f, 0xb5, - 0xba, 0x93, 0x7f, 0x86, 0x93, 0x0f, 0x09, 0x1a, 0xce, 0xc2, 0xb1, 0x9d, 0x86, 0x49, 0x86, 0xb4, - 0xee, 0x2c, 0xfe, 0xaa, 0x60, 0x21, 0x68, 0x38, 0x8b, 0x3e, 0xcc, 0xfa, 0x59, 0xc1, 0xc2, 0x8b, - 0xd8, 0xf3, 0x29, 0x18, 0xb2, 0x2d, 0x73, 0xcf, 0xb6, 0x7a, 0x11, 0xe2, 0x73, 0x9c, 0x03, 0x70, - 0x12, 0xc2, 0xe0, 0x3c, 0x64, 0x7b, 0xed, 0x88, 0xbf, 0xfe, 0x7d, 0x11, 0x1e, 0xa2, 0x07, 0x16, - 0x61, 0x4c, 0x24, 0x28, 0xc3, 0xb6, 0x7a, 0x60, 0xf1, 0x37, 0x38, 0x8b, 0xd1, 0x08, 0x19, 0x57, - 0xc3, 0xc7, 0x9e, 0x5f, 0xc3, 0xbd, 0x30, 0xf9, 0xa2, 0x50, 0x83, 0x93, 0x70, 0x53, 0x6e, 0x61, - 0x4b, 0xdf, 0xe9, 0x8d, 0xc3, 0xcf, 0x0b, 0x53, 0x0a, 0x1a, 0xc2, 0x62, 0x1e, 0x46, 0xea, 0x9a, - 0xeb, 0xed, 0x68, 0x66, 0x4f, 0xdd, 0xf1, 0x37, 0x39, 0x8f, 0xe1, 0x80, 0x88, 0x5b, 0xa4, 0x61, - 0xf5, 0xc3, 0xe6, 0x4b, 0xc2, 0x22, 0x11, 0x32, 0x1e, 0x7a, 0x9e, 0x4f, 0x57, 0xd9, 0xfa, 0xe1, - 0xf6, 0x0b, 0x22, 0xf4, 0x18, 0xed, 0x4a, 0x94, 0xe3, 0x79, 0xc8, 0x7a, 0xc6, 0xcd, 0x9e, 0xd8, - 0xfc, 0x2d, 0xd1, 0xd3, 0x94, 0x80, 0x10, 0xbf, 0x1b, 0x8e, 0xb6, 0x1d, 0x26, 0x7a, 0x60, 0xf6, - 0xb7, 0x39, 0xb3, 0x23, 0x6d, 0x86, 0x0a, 0x9e, 0x12, 0xfa, 0x65, 0xf9, 0x77, 0x44, 0x4a, 0xc0, - 0x4d, 0xbc, 0xd6, 0xc9, 0x3c, 0xc2, 0xd3, 0xb6, 0xfb, 0xb3, 0xda, 0x2f, 0x0a, 0xab, 0x31, 0xda, - 0x98, 0xd5, 0x36, 0xe1, 0x08, 0xe7, 0xd8, 0x5f, 0xbf, 0xfe, 0x92, 0x48, 0xac, 0x8c, 0xfa, 0x4a, - 0xbc, 0x77, 0xdf, 0x0b, 0x85, 0xc0, 0x9c, 0xa2, 0x60, 0xf5, 0xd4, 0xba, 0xe6, 0xf4, 0xc0, 0xf9, - 0x97, 0x39, 0x67, 0x91, 0xf1, 0x83, 0x8a, 0xd7, 0x5b, 0xd1, 0x1c, 0xc2, 0xfc, 0x59, 0xc8, 0x0b, - 0xe6, 0x0d, 0xcb, 0xc5, 0xba, 0x5d, 0xb3, 0x8c, 0x9b, 0xb8, 0xda, 0x03, 0xeb, 0xbf, 0xdb, 0xd4, - 0x55, 0x57, 0x22, 0xe4, 0x84, 0xf3, 0x12, 0xe4, 0x82, 0x5a, 0x45, 0x35, 0xea, 0x8e, 0xed, 0xfa, - 0x5d, 0x38, 0x7e, 0x59, 0xf4, 0x54, 0x40, 0xb7, 0x44, 0xc9, 0x4a, 0x15, 0x18, 0xa5, 0xaf, 0xbd, - 0xba, 0xe4, 0xaf, 0x70, 0x46, 0x23, 0x21, 0x15, 0x4f, 0x1c, 0xba, 0x5d, 0x77, 0x34, 0xb7, 0x97, - 0xfc, 0xf7, 0xf7, 0x44, 0xe2, 0xe0, 0x24, 0x3c, 0x71, 0xf8, 0x7b, 0x0e, 0x26, 0xa3, 0x7d, 0x0f, - 0x1c, 0x7e, 0x55, 0x24, 0x0e, 0x41, 0xc3, 0x59, 0x88, 0x82, 0xa1, 0x07, 0x16, 0x7f, 0x5f, 0xb0, - 0x10, 0x34, 0x84, 0xc5, 0xd3, 0xe1, 0x40, 0xeb, 0xe2, 0x9a, 0xe1, 0xf9, 0x2e, 0x2b, 0x93, 0xf7, - 0x67, 0xf5, 0x0f, 0xbe, 0x1f, 0x2f, 0xc2, 0x94, 0x08, 0x29, 0xc9, 0x44, 0x7c, 0xd9, 0x95, 0xce, - 0xa2, 0xba, 0x0b, 0xf6, 0x6b, 0x22, 0x13, 0x45, 0xc8, 0x88, 0x6c, 0x91, 0x0a, 0x91, 0x98, 0x5d, - 0x27, 0x73, 0x87, 0x1e, 0xd8, 0xfd, 0xc3, 0x26, 0xe1, 0x36, 0x04, 0x2d, 0xe1, 0x19, 0xa9, 0x7f, - 0x1a, 0xd6, 0x35, 0xbc, 0xd7, 0x93, 0x77, 0xfe, 0x7a, 0x53, 0xfd, 0x73, 0x85, 0x51, 0xb2, 0x1c, - 0x32, 0xd6, 0x54, 0x4f, 0xa1, 0x6e, 0xe7, 0x87, 0xf2, 0x3f, 0xf6, 0x0a, 0xd7, 0x37, 0x5e, 0x4e, - 0x95, 0x96, 0x89, 0x93, 0xc7, 0x8b, 0x9e, 0xee, 0xcc, 0x3e, 0xf8, 0x4a, 0xe0, 0xe7, 0xb1, 0x9a, - 0xa7, 0x74, 0x01, 0x46, 0x62, 0x05, 0x4f, 0x77, 0x56, 0x1f, 0xe2, 0xac, 0x86, 0xa3, 0xf5, 0x4e, - 0xe9, 0x09, 0x48, 0x91, 0xe2, 0xa5, 0x3b, 0xf9, 0x87, 0x39, 0x39, 0x45, 0x2f, 0xbd, 0x03, 0x32, - 0xa2, 0x68, 0xe9, 0x4e, 0xfa, 0x11, 0x4e, 0x1a, 0x90, 0x10, 0x72, 0x51, 0xb0, 0x74, 0x27, 0xff, - 0xf3, 0x82, 0x5c, 0x90, 0x10, 0xf2, 0xde, 0x4d, 0xf8, 0x95, 0xbf, 0x90, 0xe2, 0x83, 0x8e, 0xb0, - 0xdd, 0x79, 0x18, 0xe4, 0x95, 0x4a, 0x77, 0xea, 0x8f, 0xf2, 0xc6, 0x05, 0x45, 0xe9, 0x2c, 0xa4, - 0x7b, 0x34, 0xf8, 0x4f, 0x72, 0x52, 0x86, 0x5f, 0x9a, 0x87, 0xa1, 0x48, 0x75, 0xd2, 0x9d, 0xfc, - 0x2f, 0x71, 0xf2, 0x28, 0x15, 0x11, 0x9d, 0x57, 0x27, 0xdd, 0x19, 0x7c, 0x4c, 0x88, 0xce, 0x29, - 0x88, 0xd9, 0x44, 0x61, 0xd2, 0x9d, 0xfa, 0xe3, 0xc2, 0xea, 0x82, 0xa4, 0xf4, 0x14, 0x64, 0x83, - 0xc1, 0xa6, 0x3b, 0xfd, 0x4f, 0x71, 0xfa, 0x90, 0x86, 0x58, 0x20, 0x32, 0xd8, 0x75, 0x67, 0xf1, - 0xd3, 0xc2, 0x02, 0x11, 0x2a, 0x12, 0x46, 0xcd, 0x05, 0x4c, 0x77, 0x4e, 0x3f, 0x23, 0xc2, 0xa8, - 0xa9, 0x7e, 0x21, 0xbd, 0x49, 0x73, 0x7e, 0x77, 0x16, 0x3f, 0x2b, 0x7a, 0x93, 0xe2, 0x13, 0x31, - 0x9a, 0x2b, 0x82, 0xee, 0x3c, 0xfe, 0x8a, 0x10, 0xa3, 0xa9, 0x20, 0x28, 0xad, 0x03, 0x6a, 0xad, - 0x06, 0xba, 0xf3, 0xfb, 0x04, 0xe7, 0x37, 0xde, 0x52, 0x0c, 0x94, 0x9e, 0x81, 0x23, 0xed, 0x2b, - 0x81, 0xee, 0x5c, 0x3f, 0xf9, 0x4a, 0xd3, 0xdc, 0x2d, 0x5a, 0x08, 0x94, 0x36, 0xc3, 0x21, 0x25, - 0x5a, 0x05, 0x74, 0x67, 0xfb, 0xa9, 0x57, 0xe2, 0x89, 0x3b, 0x5a, 0x04, 0x94, 0xe6, 0x00, 0xc2, - 0x01, 0xb8, 0x3b, 0xaf, 0x4f, 0x73, 0x5e, 0x11, 0x22, 0x12, 0x1a, 0x7c, 0xfc, 0xed, 0x4e, 0xff, - 0x92, 0x08, 0x0d, 0x4e, 0x41, 0x42, 0x43, 0x0c, 0xbd, 0xdd, 0xa9, 0x3f, 0x23, 0x42, 0x43, 0x90, - 0x10, 0xcf, 0x8e, 0x8c, 0x6e, 0xdd, 0x39, 0x7c, 0x4e, 0x78, 0x76, 0x84, 0xaa, 0xb4, 0x0a, 0xe3, - 0x2d, 0x03, 0x62, 0x77, 0x56, 0x9f, 0xe7, 0xac, 0x72, 0xcd, 0xe3, 0x61, 0x74, 0xf0, 0xe2, 0x83, - 0x61, 0x77, 0x6e, 0x5f, 0x68, 0x1a, 0xbc, 0xf8, 0x58, 0x58, 0x3a, 0x0f, 0x19, 0xab, 0x61, 0x9a, - 0x24, 0x78, 0xd0, 0xfe, 0x67, 0xfe, 0xf2, 0x7f, 0xf8, 0x2a, 0xb7, 0x8e, 0x20, 0x28, 0x3d, 0x01, - 0x69, 0x5c, 0xdf, 0xc2, 0xd5, 0x6e, 0x94, 0xdf, 0x7b, 0x55, 0x24, 0x4c, 0x82, 0x5d, 0x7a, 0x0a, - 0x80, 0x2d, 0x8d, 0xd0, 0xed, 0xc1, 0x2e, 0xb4, 0xff, 0xf5, 0x55, 0x7e, 0x1a, 0x27, 0x24, 0x09, - 0x19, 0xb0, 0xb3, 0x3d, 0xfb, 0x33, 0xf8, 0x7e, 0x9c, 0x01, 0xed, 0x91, 0x27, 0x61, 0xf0, 0x39, - 0xcf, 0xb6, 0x7c, 0xad, 0xd6, 0x8d, 0xfa, 0xbf, 0x71, 0x6a, 0x81, 0x4f, 0x0c, 0x56, 0xb7, 0x5d, - 0xec, 0x6b, 0x35, 0xaf, 0x1b, 0xed, 0x7f, 0xe7, 0xb4, 0x01, 0x01, 0x21, 0xd6, 0x35, 0xcf, 0xef, - 0x45, 0xef, 0x3f, 0x12, 0xc4, 0x82, 0x80, 0x08, 0x4d, 0x9e, 0xaf, 0xe1, 0xbd, 0x6e, 0xb4, 0x7f, - 0x2c, 0x84, 0xe6, 0xf8, 0xa5, 0x77, 0x40, 0x96, 0x3c, 0xb2, 0x23, 0x76, 0x5d, 0x88, 0xff, 0x07, - 0x27, 0x0e, 0x29, 0x48, 0xcb, 0x9e, 0x5f, 0xf5, 0x8d, 0xee, 0xc6, 0xbe, 0xcd, 0x7b, 0x5a, 0xe0, - 0x97, 0xe6, 0x60, 0xc8, 0xf3, 0xab, 0xd5, 0x06, 0xaf, 0x4f, 0xbb, 0x90, 0xff, 0xcf, 0x57, 0x83, - 0x25, 0x8b, 0x80, 0x86, 0xf4, 0xf6, 0x8d, 0x6b, 0xbe, 0x63, 0xd3, 0x2d, 0x90, 0x6e, 0x1c, 0x5e, - 0xe1, 0x1c, 0x22, 0x24, 0xa5, 0x79, 0x18, 0x26, 0xba, 0xb8, 0xd8, 0xc1, 0x74, 0xbf, 0xaa, 0x0b, - 0x8b, 0xff, 0xc5, 0x0d, 0x10, 0x23, 0x2a, 0xff, 0x68, 0xa7, 0x7b, 0x37, 0xed, 0x97, 0x8d, 0x61, - 0xd1, 0x5e, 0xb4, 0xd9, 0x82, 0xf1, 0x7b, 0xe4, 0xd8, 0x72, 0x71, 0xcd, 0x0e, 0x57, 0x6b, 0x83, - 0x49, 0x0e, 0xfc, 0x66, 0x9a, 0x54, 0xcd, 0x74, 0x2d, 0x57, 0x73, 0x8c, 0xd9, 0x1d, 0xdf, 0x77, - 0xf8, 0x6a, 0x2f, 0x70, 0xd6, 0x9a, 0x63, 0xc8, 0x7b, 0x90, 0xba, 0xe8, 0xfb, 0x0e, 0x3a, 0x09, - 0x69, 0xb7, 0x61, 0x62, 0x8f, 0xaf, 0xb2, 0x4f, 0x16, 0x43, 0x9c, 0x22, 0x41, 0x50, 0x1a, 0x26, - 0x56, 0x18, 0x0a, 0xaa, 0xc0, 0xf4, 0x76, 0xc3, 0x34, 0xf7, 0xd4, 0x2a, 0xa6, 0x97, 0x2b, 0x82, - 0x73, 0x8c, 0x78, 0xd7, 0xd1, 0xc4, 0x66, 0x08, 0x31, 0xd9, 0x71, 0x8a, 0xb6, 0x40, 0xb1, 0xc4, - 0x19, 0xc6, 0x8a, 0xc0, 0x91, 0x7f, 0x3f, 0x01, 0x19, 0xc1, 0x1a, 0x15, 0x20, 0xe3, 0x61, 0x13, - 0xeb, 0xbe, 0xed, 0xf2, 0xc3, 0x65, 0xc1, 0x3b, 0x42, 0x90, 0xac, 0xf1, 0xdb, 0x52, 0xd9, 0x8b, - 0x87, 0x14, 0xf2, 0x42, 0x60, 0x4e, 0x83, 0x5d, 0x95, 0xa2, 0x30, 0xa7, 0xe1, 0xa3, 0x49, 0x48, - 0x39, 0xb6, 0xe7, 0xb3, 0x0d, 0x8a, 0x8b, 0x87, 0x14, 0xfa, 0x86, 0xf2, 0x30, 0x50, 0xc5, 0x26, - 0xf6, 0xd9, 0x0e, 0x13, 0x81, 0xf3, 0x77, 0x74, 0x04, 0xd2, 0x8e, 0xe6, 0xeb, 0x3b, 0xec, 0xe8, - 0xf4, 0xc5, 0x43, 0x0a, 0x7b, 0x45, 0x08, 0x52, 0x5b, 0x76, 0x75, 0x8f, 0x1f, 0x8a, 0xa6, 0xcf, - 0xe8, 0x2c, 0x0c, 0xb0, 0x68, 0x6f, 0x3e, 0xcd, 0x4c, 0x0c, 0xc4, 0x96, 0x55, 0x89, 0x2e, 0xeb, - 0x1a, 0xa9, 0xe0, 0x2d, 0xd2, 0x08, 0x43, 0x47, 0x15, 0x98, 0xd0, 0xaa, 0x55, 0x83, 0x38, 0x82, - 0x66, 0xaa, 0x5b, 0x86, 0x55, 0x35, 0xac, 0x9a, 0x47, 0x6f, 0xff, 0x74, 0x32, 0x33, 0x0a, 0x09, - 0xca, 0x1c, 0x9f, 0x1f, 0x17, 0xa5, 0x37, 0xbc, 0x54, 0x2a, 0x1c, 0xbb, 0x8b, 0x32, 0x2c, 0x80, - 0x65, 0xbb, 0xba, 0x57, 0xce, 0xc2, 0xa0, 0xc3, 0x04, 0x90, 0xcf, 0xc3, 0x78, 0x8b, 0x54, 0x44, - 0xb1, 0x6b, 0x86, 0x55, 0x15, 0xe7, 0x18, 0xc9, 0x33, 0x81, 0xd1, 0x6d, 0x10, 0xb6, 0xcf, 0x41, - 0x9f, 0xcb, 0x3f, 0x2e, 0x75, 0x74, 0xcd, 0xd1, 0x88, 0x6b, 0x6a, 0x8e, 0x51, 0xce, 0x52, 0xfe, - 0xc4, 0xad, 0xd6, 0xa5, 0xf7, 0xcc, 0xf1, 0x0f, 0x6c, 0x07, 0xa3, 0x68, 0xbb, 0xb5, 0xd9, 0x1a, - 0xb6, 0xc4, 0x6e, 0x03, 0xf9, 0xa4, 0x39, 0x86, 0x47, 0xdd, 0x31, 0xdc, 0x96, 0xf1, 0xce, 0x47, - 0x9e, 0xe9, 0x46, 0x46, 0x6a, 0x71, 0x6e, 0x7d, 0x29, 0xb8, 0x52, 0xf6, 0x1b, 0x09, 0x38, 0x1e, - 0xf1, 0xe3, 0x08, 0x72, 0xab, 0x3b, 0x17, 0xda, 0x7b, 0x7c, 0x0f, 0x9b, 0x1a, 0x97, 0x21, 0x45, - 0xf0, 0x51, 0x97, 0x53, 0x98, 0xf9, 0x5f, 0xfa, 0xe7, 0xff, 0x48, 0xa6, 0x0e, 0xd0, 0xbe, 0xeb, - 0x28, 0x93, 0xf2, 0x47, 0x7a, 0xb7, 0x5f, 0x2e, 0xdc, 0x91, 0xf2, 0xee, 0x9c, 0x19, 0x9b, 0x6d, - 0xf8, 0xf1, 0x04, 0x4c, 0x37, 0x9b, 0x80, 0x24, 0x53, 0xcf, 0xd7, 0xea, 0x4e, 0xa7, 0x5b, 0x79, - 0xe7, 0x21, 0xbb, 0x29, 0x70, 0x50, 0x1e, 0x06, 0x3d, 0xac, 0xdb, 0x56, 0xd5, 0xa3, 0xde, 0x93, - 0x54, 0xc4, 0x2b, 0x9a, 0x84, 0xb4, 0xa5, 0x59, 0xb6, 0xc7, 0x0f, 0x0d, 0xb3, 0x97, 0xf2, 0x5f, - 0x96, 0xfa, 0xcb, 0x6e, 0xa3, 0x41, 0x53, 0xc2, 0x0a, 0x0f, 0xed, 0xb7, 0x25, 0xc6, 0xee, 0x1e, - 0x06, 0x2a, 0x44, 0xf6, 0xbf, 0xa6, 0x9a, 0xf7, 0xbf, 0x9e, 0xc1, 0xa6, 0x79, 0xd9, 0xb2, 0x6f, - 0x58, 0x9b, 0x84, 0x26, 0x30, 0xc9, 0xef, 0x4a, 0x30, 0x43, 0x6f, 0x43, 0xb8, 0x75, 0xc3, 0xf2, - 0x67, 0x4d, 0x63, 0xcb, 0x9b, 0xdd, 0x32, 0x7c, 0x8f, 0x5d, 0x6b, 0xe4, 0x36, 0x99, 0x0c, 0x31, - 0x8a, 0x04, 0xa3, 0x48, 0x30, 0xe4, 0xd3, 0x90, 0x29, 0x1b, 0xfe, 0x9c, 0xeb, 0x6a, 0x7b, 0x34, - 0x57, 0x18, 0xbe, 0x30, 0x0a, 0x7d, 0x26, 0x16, 0xc1, 0x26, 0xae, 0x7b, 0x74, 0xe7, 0x35, 0xa5, - 0xb0, 0x97, 0xf2, 0x95, 0x8e, 0xd7, 0x2c, 0xcf, 0x47, 0x34, 0x8d, 0x88, 0x14, 0x79, 0x64, 0x7d, - 0xdf, 0x4e, 0xdc, 0x40, 0x9f, 0x2f, 0xa5, 0xe0, 0xee, 0x08, 0x82, 0xee, 0xee, 0x39, 0x3e, 0x1d, - 0x17, 0xec, 0x6d, 0xae, 0xcc, 0x78, 0x44, 0x19, 0xf6, 0xb9, 0xd0, 0x76, 0x37, 0x50, 0xde, 0x86, - 0xf4, 0x3a, 0xa1, 0x0b, 0xef, 0x8b, 0x32, 0xed, 0xd8, 0x0b, 0x81, 0xb2, 0x1b, 0x21, 0x09, 0x06, - 0x35, 0xc4, 0x65, 0x10, 0x13, 0x6b, 0xdb, 0xec, 0x04, 0x6e, 0x92, 0x6e, 0xc0, 0x67, 0x08, 0x80, - 0x1e, 0xb6, 0x9d, 0x84, 0xb4, 0xd6, 0x60, 0x7b, 0xc7, 0xc9, 0x13, 0xc3, 0x0a, 0x7b, 0x91, 0x2f, - 0xc3, 0x20, 0xdf, 0xaf, 0x6a, 0x73, 0x4b, 0xb6, 0x08, 0x69, 0x2a, 0x3c, 0xbf, 0x5a, 0x90, 0x2f, - 0xb6, 0x48, 0x5f, 0xa4, 0x42, 0x2a, 0x0c, 0x4d, 0xbe, 0x04, 0x99, 0x05, 0xbb, 0x6e, 0x58, 0x76, - 0x9c, 0x5b, 0x96, 0x71, 0xa3, 0x32, 0x93, 0x01, 0x83, 0xa5, 0x39, 0xf6, 0x42, 0x6f, 0xe2, 0xd2, - 0x13, 0xd9, 0x7c, 0xff, 0x9b, 0xbf, 0xc9, 0xf3, 0x30, 0x48, 0x79, 0xaf, 0x39, 0xa4, 0x7f, 0x83, - 0xd3, 0x70, 0x59, 0x7e, 0xed, 0x86, 0xb3, 0x4f, 0x84, 0xc2, 0x22, 0x48, 0x55, 0x35, 0x5f, 0xe3, - 0x7a, 0xd3, 0x67, 0xf9, 0x9d, 0x90, 0xe1, 0x4c, 0x3c, 0x74, 0x0a, 0x92, 0xb6, 0x23, 0xc6, 0xd6, - 0x42, 0x27, 0x55, 0xd6, 0x9c, 0x72, 0xea, 0x6b, 0xb7, 0xa6, 0x0f, 0x29, 0x04, 0xb9, 0xac, 0x74, - 0xf4, 0x97, 0x73, 0xfd, 0xfb, 0x0b, 0x6b, 0x26, 0x70, 0x96, 0xcf, 0x25, 0x60, 0x2a, 0xf2, 0xf5, - 0x3a, 0x76, 0xc9, 0x88, 0x1c, 0x73, 0x7d, 0x14, 0x11, 0x92, 0x7f, 0xef, 0xe0, 0x2e, 0xef, 0x80, - 0xe4, 0x9c, 0xe3, 0x90, 0x11, 0x9c, 0xed, 0x54, 0xdb, 0xcc, 0x5f, 0x52, 0x4a, 0xf0, 0x4e, 0x47, - 0x77, 0x7b, 0xdb, 0xbf, 0xa1, 0xb9, 0xc1, 0x5d, 0x24, 0xf1, 0x2e, 0x3f, 0x09, 0xd9, 0x79, 0x32, - 0x82, 0x59, 0x5e, 0x83, 0x86, 0xce, 0x96, 0x69, 0xeb, 0xd7, 0x38, 0x07, 0xf6, 0x42, 0x0c, 0xae, - 0x39, 0x0e, 0xbf, 0xb5, 0x4c, 0x1e, 0x4b, 0xa9, 0xef, 0x7e, 0x76, 0x5a, 0x2a, 0x6f, 0x74, 0x34, - 0xd1, 0x93, 0xfd, 0x9b, 0x88, 0x2b, 0x19, 0xd8, 0xe8, 0xd7, 0x8f, 0xc2, 0xf1, 0x28, 0x29, 0xcb, - 0x38, 0x11, 0x0b, 0xe5, 0x22, 0x16, 0xa2, 0xf0, 0xf6, 0xf6, 0x29, 0x74, 0xcb, 0xbc, 0x85, 0xae, - 0x79, 0xa8, 0xb0, 0x7f, 0x64, 0x17, 0xba, 0xf4, 0xa5, 0xfc, 0x24, 0x8c, 0xac, 0x6b, 0xae, 0xbf, - 0x81, 0xfd, 0x8b, 0x58, 0xab, 0x62, 0x37, 0x1e, 0xd8, 0x23, 0x22, 0xb0, 0x11, 0xa4, 0x68, 0xf4, - 0x32, 0xc7, 0xa6, 0xcf, 0xf2, 0x0e, 0xa4, 0xe8, 0x69, 0x97, 0x20, 0xe8, 0x39, 0x05, 0x0b, 0x7a, - 0xd2, 0x5d, 0x7b, 0x3e, 0xf6, 0x38, 0x09, 0x7b, 0x41, 0xa7, 0x45, 0xe8, 0x26, 0xf7, 0x0f, 0x5d, - 0xee, 0xed, 0x3c, 0x80, 0x4d, 0x18, 0x2c, 0x93, 0xde, 0x5e, 0x5a, 0x08, 0x04, 0x91, 0x42, 0x41, - 0xd0, 0x0a, 0x8c, 0x39, 0x9a, 0xeb, 0xd3, 0x63, 0xbe, 0x3b, 0x54, 0x0b, 0x9e, 0x19, 0xa6, 0x8b, - 0xcd, 0xfd, 0x50, 0x8c, 0x29, 0xcb, 0x5b, 0x19, 0x71, 0xa2, 0x40, 0xf9, 0x3f, 0xa7, 0x60, 0x80, - 0x1b, 0xe3, 0x1d, 0x30, 0xc8, 0x8d, 0x46, 0x1b, 0x24, 0xb5, 0x5d, 0xab, 0xef, 0x17, 0x03, 0x1f, - 0xe5, 0xfc, 0x04, 0x0d, 0xba, 0x1f, 0x32, 0xfa, 0x8e, 0x66, 0x58, 0xaa, 0xc1, 0xce, 0xbb, 0x66, - 0xcb, 0x43, 0x2f, 0xdf, 0x9a, 0x1e, 0x9c, 0x27, 0xb0, 0xa5, 0x05, 0x65, 0x90, 0x7e, 0x5c, 0xaa, - 0x92, 0x64, 0xb3, 0x83, 0x8d, 0xda, 0x0e, 0x4b, 0x36, 0x49, 0x85, 0xbf, 0xa1, 0x73, 0x90, 0x22, - 0x0e, 0xc1, 0x6f, 0x81, 0x14, 0x5a, 0xea, 0x8f, 0x60, 0x60, 0x2c, 0x67, 0x48, 0xc3, 0x1f, 0xff, - 0xd6, 0xb4, 0xa4, 0x50, 0x0a, 0x34, 0x0f, 0x23, 0xa6, 0xe6, 0xf9, 0x2a, 0x0d, 0x12, 0xd2, 0x7c, - 0x9a, 0xb2, 0x38, 0xda, 0x6a, 0x10, 0x6e, 0x58, 0x2e, 0xfa, 0x10, 0xa1, 0x62, 0xa0, 0x2a, 0x3a, - 0x01, 0x39, 0xca, 0x44, 0xb7, 0xeb, 0x75, 0xc3, 0x67, 0xe9, 0x7b, 0x80, 0xda, 0x7d, 0x94, 0xc0, - 0xe7, 0x29, 0x98, 0x26, 0xf1, 0x63, 0x90, 0xa5, 0xc7, 0xce, 0x29, 0x0a, 0x3b, 0x62, 0x95, 0x21, - 0x00, 0xfa, 0xf1, 0x01, 0x18, 0xbb, 0xae, 0x99, 0x46, 0x55, 0xf3, 0x6d, 0xd7, 0x63, 0x28, 0x19, - 0xc6, 0x25, 0x04, 0x53, 0xc4, 0x47, 0x61, 0x92, 0xfe, 0x3c, 0x41, 0x33, 0x76, 0x96, 0x62, 0x23, - 0xf2, 0xed, 0x6a, 0x9c, 0xe2, 0x6d, 0xa4, 0x68, 0xe2, 0xc6, 0x67, 0xb8, 0x40, 0x71, 0x47, 0x02, - 0x28, 0x45, 0x3b, 0x0a, 0x19, 0xcd, 0x71, 0x18, 0xc2, 0x10, 0xfb, 0xdd, 0x03, 0xcd, 0x71, 0xe8, - 0xa7, 0x93, 0x30, 0x4e, 0x75, 0x74, 0xb1, 0xd7, 0x30, 0x7d, 0xce, 0x64, 0x98, 0xe2, 0x8c, 0x91, - 0x0f, 0x0a, 0x83, 0x53, 0xdc, 0x7b, 0x61, 0x04, 0x5f, 0x37, 0xaa, 0xd8, 0xd2, 0x31, 0xc3, 0x1b, - 0xa1, 0x78, 0xc3, 0x02, 0x48, 0x91, 0x1e, 0x84, 0x9c, 0xe3, 0xda, 0x8e, 0xed, 0x61, 0x57, 0xd5, - 0xaa, 0x55, 0x17, 0x7b, 0x5e, 0x7e, 0x94, 0xf1, 0x13, 0xf0, 0x39, 0x06, 0x96, 0x1f, 0x86, 0xd4, - 0x82, 0xe6, 0x6b, 0x24, 0x87, 0xf9, 0xbb, 0x6c, 0x08, 0x18, 0x56, 0xc8, 0x63, 0xdb, 0x70, 0xfb, - 0x6e, 0x02, 0x52, 0x57, 0x6d, 0x1f, 0xa3, 0xc7, 0x23, 0xe3, 0xce, 0x68, 0x3b, 0x1f, 0xdf, 0x30, - 0x6a, 0x16, 0xae, 0xae, 0x78, 0xb5, 0xc8, 0x7d, 0xd0, 0xd0, 0xc5, 0x12, 0x31, 0x17, 0x9b, 0x84, - 0xb4, 0x6b, 0x37, 0xac, 0xaa, 0x38, 0xb1, 0x44, 0x5f, 0x50, 0x05, 0x32, 0x81, 0xe7, 0xa4, 0xba, - 0x79, 0xce, 0x18, 0xf1, 0x1c, 0xe2, 0xd7, 0x1c, 0xa0, 0x0c, 0x6e, 0x71, 0x07, 0x2a, 0x43, 0x36, - 0x48, 0x68, 0xdc, 0x03, 0x7b, 0x73, 0xe2, 0x90, 0x0c, 0x3d, 0x04, 0xe3, 0x81, 0x3f, 0x04, 0x06, - 0x65, 0x5e, 0x98, 0x0b, 0x3e, 0x70, 0x8b, 0xc6, 0x5c, 0x8d, 0xdf, 0x4d, 0x1d, 0xa4, 0x7a, 0x85, - 0xae, 0xc6, 0xee, 0xa7, 0x1e, 0x87, 0xac, 0x67, 0xd4, 0x2c, 0xcd, 0x6f, 0xb8, 0x98, 0x7b, 0x63, - 0x08, 0x90, 0x7f, 0x2a, 0x01, 0x03, 0xcc, 0xbb, 0x23, 0x76, 0x93, 0xda, 0xdb, 0x2d, 0xd1, 0xc9, - 0x6e, 0xc9, 0x83, 0xdb, 0x6d, 0x0e, 0x20, 0x10, 0xc6, 0xe3, 0x77, 0x0b, 0x8f, 0xb5, 0x32, 0x62, - 0x22, 0x6e, 0x18, 0x35, 0x1e, 0xbc, 0x11, 0xa2, 0xc0, 0x83, 0xd2, 0x91, 0x3c, 0x79, 0x1e, 0xb2, - 0x5b, 0x86, 0xaf, 0x6a, 0xa4, 0x3a, 0xa5, 0x26, 0x1c, 0x3a, 0x35, 0x55, 0x6c, 0x57, 0xc6, 0x16, - 0x45, 0x0d, 0xab, 0x64, 0xb6, 0xf8, 0x93, 0xfc, 0x1f, 0x25, 0x32, 0x18, 0xf3, 0x06, 0xd1, 0x1c, - 0x8c, 0x08, 0x45, 0xd5, 0x6d, 0x53, 0xab, 0x71, 0x67, 0xbc, 0xbb, 0xa3, 0xb6, 0x17, 0x4c, 0xad, - 0xa6, 0x0c, 0x71, 0x05, 0xc9, 0x4b, 0xfb, 0x8e, 0x4d, 0x74, 0xe8, 0xd8, 0x98, 0x27, 0x25, 0x0f, - 0xe6, 0x49, 0xb1, 0x3e, 0x4f, 0x35, 0xf7, 0xf9, 0x97, 0x13, 0xb4, 0x28, 0x73, 0x6c, 0x4f, 0x33, - 0xdf, 0x88, 0x10, 0x3b, 0x06, 0x59, 0xc7, 0x36, 0x55, 0xf6, 0x85, 0x1d, 0x0d, 0xcc, 0x38, 0xb6, - 0xa9, 0xb4, 0xf8, 0x51, 0xfa, 0x0e, 0xc5, 0xdf, 0xc0, 0x1d, 0xb0, 0xda, 0x60, 0xb3, 0xd5, 0x5c, - 0x18, 0x66, 0xa6, 0xe0, 0x03, 0xe6, 0xa3, 0xc4, 0x06, 0x74, 0x04, 0x96, 0x5a, 0x07, 0x78, 0x26, - 0x36, 0xc3, 0x54, 0x38, 0x1e, 0xa1, 0x60, 0xe3, 0x4b, 0xbb, 0x6a, 0x3e, 0xea, 0xe7, 0x0a, 0xc7, - 0x93, 0xff, 0xa9, 0x04, 0x59, 0xaa, 0xea, 0x0a, 0xf6, 0xb5, 0x98, 0xa9, 0xa4, 0x83, 0x9b, 0xea, - 0x6e, 0x00, 0xc6, 0xc6, 0x33, 0x6e, 0x62, 0xde, 0x81, 0x59, 0x0a, 0xd9, 0x30, 0x6e, 0x62, 0x74, - 0x26, 0xd0, 0x2b, 0xb9, 0xbf, 0x5e, 0x3c, 0x14, 0x85, 0x76, 0x77, 0xc1, 0x20, 0xfd, 0x69, 0x8c, - 0x5d, 0x76, 0x36, 0x36, 0x49, 0x2f, 0xce, 0x6e, 0xee, 0x7a, 0xf2, 0x73, 0x30, 0xb8, 0xb9, 0xcb, - 0xa6, 0x52, 0xc7, 0x20, 0xeb, 0xda, 0x36, 0x1f, 0x5f, 0x59, 0x5d, 0x93, 0x21, 0x00, 0x3a, 0x9c, - 0x88, 0xe9, 0x43, 0x22, 0x9c, 0x3e, 0x84, 0xf3, 0x9f, 0x64, 0x4f, 0xf3, 0x9f, 0x93, 0xff, 0x4e, - 0x82, 0xa1, 0x48, 0x18, 0xa2, 0xc7, 0xe0, 0x70, 0x79, 0x79, 0x6d, 0xfe, 0xb2, 0xba, 0xb4, 0xa0, - 0x5e, 0x58, 0x9e, 0x5b, 0x0c, 0xcf, 0x98, 0x17, 0x8e, 0xbc, 0xf8, 0xd2, 0x0c, 0x8a, 0xe0, 0x5e, - 0xb1, 0xae, 0x91, 0xf9, 0x31, 0x9a, 0x85, 0xc9, 0x38, 0xc9, 0x5c, 0x79, 0xa3, 0xb2, 0xba, 0x99, - 0x93, 0x0a, 0x87, 0x5f, 0x7c, 0x69, 0x66, 0x3c, 0x42, 0x31, 0xb7, 0xe5, 0x61, 0xcb, 0x6f, 0x25, - 0x98, 0x5f, 0x5b, 0x59, 0x59, 0xda, 0xcc, 0x25, 0x5a, 0x08, 0x78, 0xa2, 0x7d, 0x10, 0xc6, 0xe3, - 0x04, 0xab, 0x4b, 0xcb, 0xb9, 0x64, 0x01, 0xbd, 0xf8, 0xd2, 0xcc, 0x68, 0x04, 0x7b, 0xd5, 0x30, - 0x0b, 0x99, 0x9f, 0xf8, 0xc2, 0xd4, 0xa1, 0x9f, 0xff, 0x6b, 0x53, 0x12, 0xd1, 0x6c, 0x24, 0x16, - 0x8a, 0xe8, 0x61, 0xb8, 0x6b, 0x63, 0x69, 0x71, 0xb5, 0xb2, 0xa0, 0xae, 0x6c, 0x2c, 0xaa, 0xec, - 0x72, 0x7d, 0xa0, 0xdd, 0xd8, 0x8b, 0x2f, 0xcd, 0x0c, 0x71, 0x95, 0x3a, 0x61, 0xaf, 0x2b, 0x95, - 0xab, 0x6b, 0x9b, 0x95, 0x9c, 0xc4, 0xb0, 0xd7, 0x5d, 0x7c, 0xdd, 0xf6, 0xd9, 0x6f, 0xe7, 0x3c, - 0x0a, 0x47, 0xdb, 0x60, 0x07, 0x8a, 0x8d, 0xbf, 0xf8, 0xd2, 0xcc, 0xc8, 0xba, 0x8b, 0x99, 0x9b, - 0x52, 0x8a, 0x22, 0xe4, 0x5b, 0x29, 0xd6, 0xd6, 0xd7, 0x36, 0xe6, 0x96, 0x73, 0x33, 0x85, 0xdc, - 0x8b, 0x2f, 0xcd, 0x0c, 0x8b, 0x9c, 0x43, 0xf0, 0x43, 0xcd, 0xca, 0x4f, 0x77, 0x9c, 0xbf, 0x9c, - 0xed, 0x7f, 0xfe, 0xe2, 0xc7, 0x96, 0x37, 0xfe, 0x62, 0x02, 0xa6, 0x5a, 0x16, 0xbd, 0xf8, 0xfa, - 0x77, 0xa7, 0x05, 0x9f, 0x12, 0x64, 0x16, 0xc4, 0xb2, 0x7a, 0xbf, 0xeb, 0x3d, 0x3f, 0xdb, 0xe7, - 0x7a, 0xcf, 0x88, 0x68, 0x49, 0x2c, 0xf7, 0x9c, 0xec, 0xbe, 0xdc, 0x23, 0xe4, 0x3f, 0xc0, 0x6a, - 0xcf, 0x87, 0x92, 0x30, 0x15, 0xfd, 0x79, 0x2f, 0xf1, 0xc3, 0x5e, 0xba, 0x6d, 0x08, 0x73, 0x4c, - 0x44, 0x7f, 0xd2, 0x8b, 0x7f, 0xef, 0x30, 0xe3, 0x5d, 0x84, 0xd4, 0xbc, 0x6d, 0x58, 0xc4, 0x14, - 0x55, 0x6c, 0xd9, 0x75, 0xbe, 0x3a, 0xc0, 0x5e, 0xd0, 0xbd, 0x30, 0xa0, 0xd5, 0xed, 0x86, 0xe5, - 0x8b, 0xe9, 0x00, 0x49, 0x16, 0xbf, 0x7f, 0x6b, 0x3a, 0xb9, 0x64, 0xf9, 0x0a, 0xff, 0xc4, 0x26, - 0xb0, 0xf2, 0x25, 0x18, 0x5c, 0xc0, 0xfa, 0x41, 0x78, 0x2d, 0x60, 0xbd, 0x89, 0xd7, 0x83, 0x90, - 0x59, 0xb2, 0x7c, 0x76, 0x61, 0xfd, 0x6e, 0x48, 0x1a, 0x16, 0xab, 0x66, 0x9a, 0xda, 0x27, 0x70, - 0x82, 0xba, 0x80, 0xf5, 0x00, 0xb5, 0x8a, 0xf5, 0x66, 0x54, 0xc2, 0x9e, 0xc0, 0xcb, 0x0b, 0xbf, - 0xf7, 0x9f, 0xa6, 0x0e, 0xbd, 0xf0, 0xf2, 0xd4, 0xa1, 0x8e, 0xae, 0x2a, 0x77, 0xff, 0x91, 0xb0, - 0xa0, 0x1b, 0x3e, 0xfc, 0x18, 0xdc, 0xc7, 0x71, 0x3c, 0x5f, 0xbb, 0x66, 0x58, 0xb5, 0xa0, 0x27, - 0xf8, 0x3b, 0xef, 0x8c, 0x23, 0xbc, 0x33, 0x04, 0x74, 0xdf, 0xfe, 0x28, 0xec, 0x3b, 0x4f, 0xef, - 0x3e, 0xff, 0xee, 0x12, 0x28, 0x85, 0x2e, 0x9e, 0x23, 0x7f, 0x54, 0x82, 0xd1, 0x8b, 0x86, 0xe7, - 0xdb, 0xae, 0xa1, 0x6b, 0x26, 0xbd, 0xb9, 0x70, 0xa6, 0xd7, 0x21, 0xb2, 0x69, 0x28, 0x79, 0x0a, - 0x06, 0xae, 0x6b, 0x26, 0xfb, 0x6d, 0xb8, 0x24, 0xfd, 0xa5, 0x85, 0xf6, 0x86, 0x28, 0x06, 0x73, - 0x24, 0xc1, 0x80, 0x91, 0xc9, 0xbf, 0x98, 0x80, 0x31, 0x9a, 0x6c, 0x3d, 0xf6, 0xd3, 0x3a, 0x64, - 0x3e, 0x5e, 0x86, 0x94, 0xab, 0xf9, 0x7c, 0x0d, 0xab, 0x5c, 0xe4, 0x7d, 0x7c, 0x7f, 0xf7, 0x7e, - 0x2b, 0x12, 0x37, 0xa0, 0xb4, 0xe8, 0x47, 0x20, 0x53, 0xd7, 0x76, 0x55, 0xca, 0x87, 0xb9, 0xe2, - 0x5c, 0x7f, 0x7c, 0x6e, 0xdf, 0x9a, 0x1e, 0xdb, 0xd3, 0xea, 0x66, 0x49, 0x16, 0x7c, 0x64, 0x65, - 0xb0, 0xae, 0xed, 0x12, 0x11, 0x91, 0x03, 0x63, 0x04, 0xaa, 0xef, 0x68, 0x56, 0x0d, 0xb3, 0x46, - 0xe8, 0x8a, 0x5c, 0xf9, 0x62, 0xdf, 0x8d, 0x1c, 0x09, 0x1b, 0x89, 0xb0, 0x93, 0x95, 0x91, 0xba, - 0xb6, 0x3b, 0x4f, 0x01, 0xa4, 0xc5, 0x52, 0xe6, 0x13, 0x9f, 0x9d, 0x3e, 0x44, 0xe3, 0xe6, 0x1b, - 0x12, 0x40, 0x68, 0x31, 0xf4, 0x23, 0x90, 0xd3, 0x83, 0x37, 0x4a, 0xeb, 0xf1, 0x3e, 0x7c, 0xa0, - 0x53, 0x5f, 0x34, 0xd9, 0x9b, 0x95, 0x58, 0x5f, 0xbf, 0x35, 0x2d, 0x29, 0x63, 0x7a, 0x53, 0x57, - 0xbc, 0x17, 0x86, 0x1a, 0x4e, 0x55, 0xf3, 0xb1, 0x4a, 0xe7, 0xfc, 0x89, 0xae, 0xe5, 0xda, 0x14, - 0xe1, 0x75, 0xfb, 0xd6, 0x34, 0x62, 0x6a, 0x45, 0x88, 0x65, 0x5a, 0xc4, 0x01, 0x83, 0x10, 0x82, - 0x88, 0x4e, 0xbf, 0x23, 0xc1, 0xd0, 0x42, 0xe4, 0x04, 0x51, 0x1e, 0x06, 0xeb, 0xb6, 0x65, 0x5c, - 0xc3, 0x62, 0x73, 0x4d, 0xbc, 0xa2, 0x02, 0x64, 0xd8, 0x65, 0x2e, 0x7f, 0x4f, 0xac, 0xcc, 0x89, - 0x77, 0x42, 0x75, 0x03, 0x6f, 0x79, 0x86, 0xe8, 0x0d, 0x45, 0xbc, 0xa2, 0x0b, 0x90, 0xf3, 0xb0, - 0xde, 0x70, 0x0d, 0x7f, 0x4f, 0xd5, 0x6d, 0xcb, 0xd7, 0x74, 0xbe, 0xeb, 0x56, 0x3e, 0x76, 0xfb, - 0xd6, 0xf4, 0x5d, 0x4c, 0xd6, 0x66, 0x0c, 0x59, 0x19, 0x13, 0xa0, 0x79, 0x06, 0x21, 0x2d, 0x54, - 0xb1, 0xaf, 0x19, 0xa6, 0xc7, 0x36, 0xe7, 0x14, 0xf1, 0x1a, 0xd1, 0xe5, 0x1f, 0x0f, 0x42, 0x36, - 0xf0, 0x76, 0x74, 0x03, 0x72, 0xb6, 0x83, 0xdd, 0xd8, 0x7c, 0x82, 0x96, 0x53, 0xe5, 0xe5, 0xb0, - 0xe5, 0x66, 0x0c, 0xf9, 0xff, 0xdf, 0x9a, 0x7e, 0xa4, 0x07, 0x0f, 0xba, 0xaa, 0x99, 0x7c, 0x2e, - 0xa2, 0x8c, 0x09, 0x1e, 0x62, 0x72, 0x72, 0x81, 0xf8, 0x85, 0x58, 0x85, 0x70, 0x1a, 0x5b, 0x62, - 0x05, 0x38, 0xa6, 0x72, 0x33, 0x86, 0x4c, 0x3c, 0x80, 0x83, 0xd6, 0x29, 0x84, 0x4c, 0x20, 0x9e, - 0xd3, 0x0c, 0x53, 0xdc, 0x70, 0x55, 0xf8, 0x1b, 0x5a, 0x82, 0x01, 0xcf, 0xd7, 0xfc, 0x06, 0xab, - 0x21, 0xd3, 0xe5, 0xc7, 0x7a, 0x94, 0xb9, 0x6c, 0x5b, 0xd5, 0x0d, 0x4a, 0xa8, 0x70, 0x06, 0xe8, - 0x02, 0x0c, 0xf8, 0xf6, 0x35, 0x6c, 0x71, 0xa3, 0xf6, 0x15, 0xf1, 0x74, 0x8c, 0x62, 0xd4, 0xc8, - 0x87, 0x5c, 0x15, 0x9b, 0xb8, 0x46, 0x4d, 0xe9, 0xed, 0x68, 0x64, 0x9e, 0x4a, 0xb7, 0x4a, 0xcb, - 0x4b, 0x7d, 0x87, 0x25, 0x37, 0x50, 0x33, 0x3f, 0x59, 0x19, 0x0b, 0x40, 0x1b, 0x14, 0x82, 0x2e, - 0xc7, 0x0e, 0xbf, 0xf1, 0x9f, 0x62, 0xbb, 0xb7, 0x53, 0xec, 0x45, 0xbc, 0x5c, 0xac, 0x6e, 0x45, - 0x8f, 0xce, 0x5d, 0x80, 0x5c, 0xc3, 0xda, 0xb2, 0xe9, 0x26, 0xaa, 0xca, 0x27, 0x6e, 0x19, 0x52, - 0xcf, 0x44, 0x7b, 0xad, 0x19, 0x43, 0x56, 0xc6, 0x02, 0xd0, 0x45, 0x36, 0xbd, 0xab, 0xc2, 0x68, - 0x88, 0x45, 0x43, 0x37, 0xdb, 0x35, 0x74, 0xef, 0xe1, 0xa1, 0x7b, 0xb8, 0xb9, 0x95, 0x30, 0x7a, - 0x47, 0x02, 0x20, 0x21, 0x43, 0x17, 0x01, 0xc2, 0x84, 0x41, 0x57, 0xb9, 0x86, 0x4e, 0xc9, 0xdd, - 0xb3, 0x8e, 0x58, 0x19, 0x08, 0x69, 0xd1, 0xfb, 0x61, 0xa2, 0x6e, 0x58, 0xaa, 0x87, 0xcd, 0x6d, - 0x95, 0x1b, 0x98, 0xb0, 0xa4, 0xbf, 0x2a, 0x52, 0x5e, 0xee, 0xcf, 0x1f, 0x6e, 0xdf, 0x9a, 0x2e, - 0xf0, 0xa4, 0xda, 0xca, 0x52, 0x56, 0xc6, 0xeb, 0x86, 0xb5, 0x81, 0xcd, 0xed, 0x85, 0x00, 0x56, - 0x1a, 0xfe, 0x89, 0xcf, 0x4e, 0x1f, 0x0a, 0x02, 0xd8, 0x80, 0xe1, 0x30, 0xb0, 0xb0, 0x87, 0xd6, - 0x20, 0xab, 0x89, 0x17, 0xb6, 0x1e, 0xd6, 0xb3, 0xb3, 0x47, 0x02, 0x34, 0xe4, 0xc1, 0x72, 0xc5, - 0x0b, 0xff, 0x61, 0x46, 0x92, 0x5f, 0x4c, 0xc0, 0xc0, 0xc2, 0xd5, 0x75, 0xcd, 0x70, 0xd1, 0x4d, - 0x18, 0x0f, 0x9d, 0x2d, 0x9e, 0x29, 0x56, 0x6e, 0xdf, 0x9a, 0xce, 0x37, 0xfb, 0x63, 0x9f, 0xa9, - 0x62, 0x4e, 0xd7, 0x85, 0x24, 0x61, 0x90, 0x88, 0x5c, 0x71, 0xb3, 0xe3, 0xaa, 0x47, 0xb4, 0xed, - 0x16, 0x94, 0x03, 0xa4, 0xa9, 0x96, 0x45, 0x94, 0x48, 0xe2, 0xac, 0xc0, 0x20, 0xb3, 0x85, 0x87, - 0x4a, 0x90, 0x76, 0xc8, 0x03, 0xdf, 0x81, 0x9a, 0xea, 0x18, 0x4d, 0x14, 0x3f, 0x58, 0x97, 0x27, - 0x24, 0xf2, 0xe7, 0x93, 0x00, 0x0b, 0x57, 0xaf, 0x6e, 0xba, 0x86, 0x63, 0x62, 0xff, 0x07, 0x6a, - 0xd7, 0x0f, 0x4b, 0x70, 0x38, 0xb4, 0x9a, 0xe7, 0xea, 0x4d, 0xc6, 0x7d, 0xfa, 0xf6, 0xad, 0xe9, - 0xe3, 0xcd, 0xc6, 0x8d, 0xa0, 0x1d, 0xc0, 0xc0, 0x13, 0x01, 0xa3, 0x0d, 0x57, 0x6f, 0x2f, 0x47, - 0xd5, 0xf3, 0x03, 0x39, 0x92, 0x9d, 0xe5, 0x88, 0xa0, 0xbd, 0x26, 0x39, 0x16, 0x3c, 0xbf, 0xb5, - 0xaf, 0x37, 0x60, 0x28, 0xec, 0x23, 0x0f, 0x2d, 0x40, 0xc6, 0xe7, 0xcf, 0xbc, 0xcb, 0xe5, 0xce, - 0x5d, 0x2e, 0xc8, 0x78, 0xb7, 0x07, 0x94, 0xf2, 0xbf, 0x4d, 0x00, 0x84, 0x51, 0xfd, 0x67, 0x35, - 0xa2, 0xc8, 0x70, 0xca, 0x07, 0xbf, 0xe4, 0x81, 0x0a, 0x68, 0x4e, 0x1d, 0xe9, 0xad, 0x3f, 0x4c, - 0xc0, 0xc4, 0x15, 0x91, 0xf9, 0xdf, 0xb2, 0x30, 0x5a, 0x87, 0x41, 0x6c, 0xf9, 0xae, 0x41, 0x4d, - 0x4c, 0xbc, 0xf5, 0xd1, 0x4e, 0xde, 0xda, 0xc6, 0x6a, 0xf4, 0x87, 0x73, 0xc4, 0xa6, 0x1c, 0x67, - 0x13, 0xb1, 0xf5, 0xc7, 0x92, 0x90, 0xef, 0x44, 0x85, 0xe6, 0x61, 0x4c, 0x77, 0x31, 0x05, 0xa8, - 0xd1, 0x1d, 0x80, 0x72, 0x21, 0x9c, 0x49, 0x34, 0x21, 0xc8, 0xca, 0xa8, 0x80, 0xf0, 0xda, 0xa0, - 0x06, 0xa4, 0xcc, 0x27, 0x21, 0x43, 0xb0, 0x7a, 0xac, 0xeb, 0x65, 0x5e, 0x1c, 0x88, 0x46, 0xe2, - 0x0c, 0x58, 0x75, 0x30, 0x1a, 0x42, 0x69, 0x79, 0xf0, 0x3c, 0x8c, 0x19, 0x96, 0xe1, 0x1b, 0x9a, - 0xa9, 0x6e, 0x69, 0xa6, 0x66, 0xe9, 0x07, 0x99, 0x25, 0xb1, 0x01, 0x9d, 0x37, 0xdb, 0xc4, 0x4e, - 0x56, 0x46, 0x39, 0xa4, 0xcc, 0x00, 0xe8, 0x22, 0x0c, 0x8a, 0xa6, 0x52, 0x07, 0xaa, 0x25, 0x05, - 0x79, 0xa4, 0x47, 0x7e, 0x32, 0x09, 0xe3, 0x0a, 0xae, 0xbe, 0xd5, 0x15, 0xfd, 0x75, 0xc5, 0x0a, - 0x00, 0x4b, 0x24, 0x64, 0x24, 0x39, 0x40, 0x6f, 0x90, 0x54, 0x94, 0x65, 0x1c, 0x16, 0x3c, 0x3f, - 0xd2, 0x1f, 0x7f, 0x94, 0x84, 0xe1, 0x68, 0x7f, 0xbc, 0x35, 0xc4, 0xff, 0xf0, 0x0c, 0xf1, 0x68, - 0x29, 0x4c, 0x8d, 0x29, 0xfe, 0x03, 0xa8, 0x1d, 0x52, 0x63, 0x4b, 0x48, 0x75, 0xce, 0x89, 0xff, - 0x3b, 0x01, 0x03, 0xeb, 0x9a, 0xab, 0xd5, 0x3d, 0xa4, 0xb7, 0x4c, 0x6c, 0xc4, 0xfe, 0x4a, 0xcb, - 0x2f, 0x57, 0xf3, 0x45, 0xb1, 0x2e, 0xf3, 0x9a, 0x4f, 0xb4, 0x99, 0xd7, 0xbc, 0x0b, 0x46, 0xeb, - 0xda, 0x6e, 0x64, 0xcb, 0x9f, 0x76, 0xe6, 0x48, 0xf9, 0x68, 0xc8, 0x25, 0xfe, 0x9d, 0x2d, 0xd7, - 0x84, 0xe7, 0x00, 0xd0, 0x59, 0x18, 0x22, 0x18, 0xe1, 0x28, 0x41, 0xc8, 0x8f, 0x84, 0xeb, 0x22, - 0x91, 0x8f, 0xb2, 0x02, 0x75, 0x6d, 0xb7, 0xc2, 0x5e, 0xd0, 0x32, 0xa0, 0x9d, 0x60, 0x69, 0x4e, - 0x0d, 0x4d, 0x49, 0xe8, 0xef, 0xbe, 0x7d, 0x6b, 0xfa, 0x28, 0xa3, 0x6f, 0xc5, 0x91, 0x95, 0xf1, - 0x10, 0x28, 0xb8, 0x9d, 0x06, 0x20, 0x7a, 0xa9, 0x6c, 0xa5, 0x96, 0xcd, 0xae, 0x0f, 0xdf, 0xbe, - 0x35, 0x3d, 0xce, 0xb8, 0x84, 0xdf, 0x64, 0x25, 0x4b, 0x5e, 0x16, 0xc8, 0x73, 0xc4, 0xf0, 0x5f, - 0x90, 0x00, 0x85, 0x63, 0x50, 0xf0, 0x2f, 0x1b, 0x2e, 0x02, 0x44, 0x26, 0x69, 0xd2, 0xfe, 0xf3, - 0xbe, 0x90, 0x5e, 0xcc, 0xfb, 0x22, 0xa1, 0xfb, 0x64, 0x98, 0xaf, 0x13, 0xbc, 0x1f, 0xdb, 0x2c, - 0x6b, 0x17, 0xe7, 0x6d, 0x43, 0x50, 0xb7, 0x49, 0xd0, 0xff, 0x42, 0x82, 0xa3, 0x2d, 0xde, 0x14, - 0x08, 0xfb, 0xe7, 0x00, 0xb9, 0x91, 0x8f, 0xfc, 0x87, 0xec, 0x98, 0xd0, 0x7d, 0x3b, 0xe7, 0xb8, - 0xdb, 0x32, 0x10, 0xdc, 0xb9, 0x21, 0x87, 0xad, 0x8b, 0xff, 0x13, 0x09, 0x26, 0xa3, 0xcd, 0x07, - 0x8a, 0xac, 0xc2, 0x70, 0xb4, 0x75, 0xae, 0xc2, 0x7d, 0xbd, 0xa8, 0xc0, 0xa5, 0x8f, 0xd1, 0xa3, - 0xa7, 0xc3, 0x50, 0x65, 0x8b, 0xb7, 0x8f, 0xf5, 0x6c, 0x0d, 0x21, 0x53, 0x73, 0xc8, 0x32, 0x0d, - 0xfe, 0x44, 0x82, 0xd4, 0xba, 0x6d, 0x9b, 0xc8, 0x86, 0x71, 0xcb, 0xf6, 0x55, 0xe2, 0x59, 0xb8, - 0xaa, 0xf2, 0x35, 0x1e, 0xb6, 0xaa, 0x3b, 0xdf, 0x9f, 0x91, 0xbe, 0x77, 0x6b, 0xba, 0x95, 0x95, - 0x32, 0x66, 0xd9, 0x7e, 0x99, 0x42, 0x36, 0xd9, 0x0a, 0xd0, 0xfb, 0x61, 0x24, 0xde, 0x18, 0x5b, - 0xf1, 0x7a, 0xa6, 0xef, 0xc6, 0xe2, 0x6c, 0x6e, 0xdf, 0x9a, 0x9e, 0x0c, 0x23, 0x26, 0x00, 0xcb, - 0xca, 0xf0, 0x56, 0xa4, 0xf5, 0x52, 0x86, 0x68, 0xff, 0xc7, 0x9f, 0x9d, 0x96, 0xca, 0x17, 0x3a, - 0xee, 0x3e, 0x3c, 0xbc, 0xaf, 0x08, 0xbb, 0xc1, 0x36, 0x43, 0x7c, 0x1f, 0xe2, 0x33, 0xe7, 0x41, - 0xee, 0xb0, 0x0f, 0xc1, 0xfe, 0x99, 0xcb, 0xfe, 0xbb, 0x10, 0x7d, 0xfc, 0xa7, 0x98, 0x4e, 0x3b, - 0x16, 0xfb, 0x9d, 0x68, 0x2f, 0xf4, 0xb4, 0x47, 0x22, 0xef, 0xc2, 0x91, 0xa7, 0x49, 0xdb, 0x61, - 0x9a, 0x14, 0xff, 0x73, 0xe6, 0x48, 0xb0, 0x96, 0x28, 0xf1, 0xff, 0x58, 0x21, 0x16, 0x06, 0x21, - 0x94, 0x8f, 0x27, 0x88, 0xfb, 0x8b, 0x1d, 0xff, 0x95, 0x4d, 0x31, 0xf2, 0x7f, 0x6c, 0x94, 0x08, - 0xa5, 0xfc, 0x0b, 0x12, 0xdc, 0xd5, 0xd2, 0x34, 0x8f, 0xaa, 0x45, 0x80, 0x48, 0x9e, 0x97, 0xfa, - 0xdb, 0xc5, 0x88, 0x90, 0x12, 0x46, 0x2d, 0xc2, 0x3e, 0xd0, 0x55, 0x58, 0x26, 0x45, 0x4c, 0xda, - 0xe7, 0xe1, 0x70, 0x5c, 0x58, 0x61, 0xa6, 0x67, 0x61, 0x34, 0x3e, 0x9f, 0xe1, 0x45, 0xce, 0x01, - 0x56, 0xa3, 0x46, 0x62, 0x73, 0x1a, 0x59, 0x6d, 0xee, 0x9a, 0xc0, 0x3c, 0x15, 0xc8, 0x06, 0xa8, - 0x3c, 0xe3, 0xf4, 0x6c, 0x9d, 0x90, 0x52, 0xfe, 0xaa, 0x04, 0x33, 0xf1, 0x16, 0xc2, 0x61, 0xc1, - 0x7b, 0xdd, 0xf5, 0xbb, 0x63, 0x8e, 0xf4, 0x5d, 0x09, 0xee, 0xd9, 0x47, 0x0d, 0x6e, 0xb3, 0x9b, - 0x30, 0x19, 0x19, 0x6f, 0xc4, 0x8d, 0x17, 0xe1, 0x5c, 0x27, 0xbb, 0x0f, 0x94, 0x41, 0x7a, 0x3d, - 0x46, 0xec, 0xf8, 0xa5, 0x6f, 0x4d, 0x4f, 0xb4, 0x7e, 0xf3, 0x94, 0x89, 0xd6, 0x31, 0xe2, 0x0e, - 0x7a, 0xe1, 0xef, 0x4a, 0xf0, 0x60, 0x5c, 0xd5, 0x36, 0xb3, 0xd2, 0x37, 0x51, 0xd7, 0xfd, 0x7b, - 0x09, 0x4e, 0xf6, 0xa2, 0x0f, 0xef, 0xc3, 0x2d, 0x98, 0x08, 0x0b, 0xc5, 0xe6, 0x2e, 0x7c, 0xa8, - 0x8f, 0xe9, 0x3e, 0x8f, 0x05, 0x14, 0x70, 0x7b, 0x1d, 0xfa, 0xea, 0x5f, 0x4a, 0x3c, 0x7e, 0xa3, - 0x6e, 0x12, 0x74, 0x4c, 0x7c, 0xe2, 0xd3, 0x67, 0xc7, 0x44, 0x26, 0x3f, 0x23, 0xb1, 0xc9, 0x4f, - 0x9b, 0x2e, 0x4f, 0xdc, 0xa1, 0x6c, 0x74, 0x9d, 0x67, 0xeb, 0x36, 0x95, 0xe7, 0x7b, 0x61, 0xa2, - 0x4d, 0x68, 0xf1, 0xc4, 0xd4, 0x47, 0x64, 0x29, 0xa8, 0x35, 0x78, 0xe4, 0x7f, 0x23, 0xc1, 0x34, - 0x6d, 0xb8, 0x4d, 0x37, 0xbe, 0x99, 0xed, 0x59, 0xe7, 0xb9, 0xb7, 0xad, 0x5a, 0xdc, 0xb0, 0x4b, - 0x30, 0xc0, 0x3c, 0x94, 0xdb, 0xf2, 0x00, 0x2e, 0xce, 0x19, 0x84, 0xb9, 0x7e, 0x41, 0xe8, 0xd7, - 0x3e, 0x61, 0xbc, 0x4e, 0x76, 0xbc, 0x53, 0x09, 0xe3, 0x1b, 0x22, 0xd7, 0xb7, 0x57, 0x83, 0xdb, - 0x4d, 0xbf, 0x63, 0xb9, 0x9e, 0x19, 0xf1, 0x0d, 0x4a, 0xea, 0x81, 0x4e, 0x5d, 0x92, 0xfa, 0x0f, - 0x79, 0x1f, 0x05, 0x49, 0xbd, 0x8b, 0x3e, 0x6f, 0xc6, 0xa4, 0xfe, 0x27, 0x09, 0x38, 0x4a, 0x75, - 0x8b, 0xce, 0xbe, 0xde, 0x80, 0xbe, 0x51, 0x01, 0x79, 0xae, 0xae, 0xde, 0xa9, 0x5c, 0x94, 0xf3, - 0x5c, 0xfd, 0x6a, 0x6c, 0x44, 0x57, 0x01, 0x55, 0x3d, 0xbf, 0xb9, 0x81, 0xe4, 0x81, 0x1b, 0xa8, - 0x7a, 0xfe, 0xd5, 0x7d, 0x4a, 0x86, 0xd4, 0x81, 0xbd, 0xeb, 0xeb, 0x12, 0x14, 0xda, 0xf5, 0x00, - 0xf7, 0x26, 0x03, 0x8e, 0xc4, 0x16, 0x16, 0x9a, 0x1d, 0xea, 0xe1, 0x5e, 0xa6, 0xd3, 0x4d, 0xe1, - 0x7f, 0xd8, 0xc5, 0xaf, 0x6b, 0x02, 0xf8, 0x67, 0x62, 0x88, 0x0b, 0x02, 0xa6, 0x75, 0x36, 0xf6, - 0xc3, 0x1f, 0xf6, 0xbf, 0xd2, 0x32, 0xc2, 0xbc, 0x29, 0x26, 0x76, 0xdf, 0x94, 0x60, 0xaa, 0x83, - 0xd8, 0x6f, 0xe6, 0xf2, 0x62, 0xa7, 0xa3, 0x4b, 0xdd, 0xe9, 0x59, 0xe4, 0x69, 0x1e, 0x8f, 0xf1, - 0xc3, 0x8b, 0x91, 0x55, 0x84, 0x76, 0xb7, 0x62, 0xe4, 0x77, 0xc3, 0xb1, 0xb6, 0x54, 0x5c, 0xb6, - 0x12, 0xa4, 0x76, 0x0c, 0xcf, 0xe7, 0x62, 0xdd, 0xdf, 0x49, 0xac, 0x26, 0x6a, 0x4a, 0x23, 0x23, - 0xc8, 0x51, 0xd6, 0xeb, 0xb6, 0x6d, 0x72, 0x31, 0xe4, 0xcb, 0x30, 0x1e, 0x81, 0xf1, 0x46, 0xce, - 0x40, 0xca, 0xb1, 0xf9, 0x45, 0xd3, 0xa1, 0x53, 0xc7, 0x3b, 0x35, 0x42, 0x68, 0xb8, 0xda, 0x14, - 0x5f, 0x9e, 0x04, 0xc4, 0x98, 0xd1, 0xd5, 0x6f, 0xd1, 0xc4, 0x06, 0x4c, 0xc4, 0xa0, 0xbc, 0x91, - 0xb7, 0xc3, 0x80, 0x43, 0x21, 0xbc, 0x99, 0x8e, 0xc7, 0x26, 0x18, 0x9d, 0x28, 0xdb, 0x18, 0xcd, - 0xa9, 0xef, 0x1d, 0x86, 0x34, 0xe5, 0x8a, 0x3e, 0x29, 0x01, 0x44, 0xd6, 0xb2, 0x8b, 0x9d, 0xd8, - 0xb4, 0x5f, 0xcd, 0x29, 0xcc, 0xf6, 0x8c, 0xcf, 0xeb, 0xee, 0x93, 0x3f, 0xfe, 0xaf, 0xbf, 0xf3, - 0x33, 0x89, 0xfb, 0x90, 0x3c, 0xdb, 0x61, 0x1d, 0x29, 0x12, 0x8c, 0x5f, 0x94, 0xa2, 0xa7, 0xeb, - 0x1e, 0xe9, 0xad, 0x29, 0x21, 0x59, 0xb1, 0x57, 0x74, 0x2e, 0xd8, 0x79, 0x2a, 0xd8, 0x13, 0xe8, - 0xf1, 0xee, 0x82, 0xcd, 0xbe, 0x2f, 0x1e, 0x5d, 0x1f, 0x40, 0xdf, 0x94, 0x60, 0xb2, 0xdd, 0x32, - 0x01, 0x3a, 0xd7, 0x9b, 0x14, 0xad, 0x05, 0x59, 0xe1, 0xc9, 0x03, 0x50, 0x72, 0x55, 0x16, 0xa9, - 0x2a, 0x73, 0xe8, 0xa9, 0x03, 0xa8, 0x32, 0x1b, 0x19, 0xfd, 0xd0, 0xff, 0x93, 0xe0, 0xee, 0x7d, - 0xa7, 0xd0, 0x68, 0xae, 0x37, 0x29, 0xf7, 0xa9, 0x3c, 0x0b, 0xe5, 0xd7, 0xc2, 0x82, 0x6b, 0xfc, - 0x34, 0xd5, 0xf8, 0x32, 0x5a, 0x3a, 0x88, 0xc6, 0x61, 0x99, 0x18, 0xd5, 0xfd, 0xb7, 0xa5, 0xd8, - 0x01, 0x93, 0xfd, 0xdd, 0xa9, 0x65, 0xee, 0xd8, 0x25, 0x30, 0x5a, 0xa7, 0x04, 0xf2, 0xb3, 0x54, - 0x05, 0x05, 0xad, 0xbf, 0xc6, 0x4e, 0x9b, 0x7d, 0x5f, 0x7c, 0x50, 0xf9, 0x00, 0xfa, 0x3f, 0x52, - 0xfb, 0x13, 0x1d, 0x67, 0xf7, 0x15, 0xb1, 0xf3, 0xbc, 0xb8, 0x70, 0xae, 0x7f, 0x42, 0xae, 0x64, - 0x9d, 0x2a, 0x59, 0x43, 0xf8, 0x4e, 0x2b, 0xd9, 0xb6, 0x13, 0xd1, 0xef, 0x48, 0x30, 0xd9, 0x6e, - 0x46, 0xd7, 0x25, 0x2c, 0xf7, 0x99, 0xcb, 0x76, 0x09, 0xcb, 0xfd, 0xa6, 0x8f, 0xf2, 0xdb, 0xa9, - 0xf2, 0x67, 0xd0, 0xe9, 0x4e, 0xca, 0xef, 0xdb, 0x8b, 0x24, 0x16, 0xf7, 0x9d, 0xf9, 0x74, 0x89, - 0xc5, 0x5e, 0x66, 0x81, 0x5d, 0x62, 0xb1, 0xa7, 0x89, 0x57, 0xf7, 0x58, 0x0c, 0x34, 0xeb, 0xb1, - 0x1b, 0x3d, 0xf4, 0x1b, 0x12, 0x8c, 0xc4, 0xea, 0x72, 0xf4, 0xd8, 0xbe, 0x82, 0xb6, 0x9b, 0x45, - 0x15, 0x4e, 0xf5, 0x43, 0xc2, 0x75, 0x59, 0xa2, 0xba, 0xcc, 0xa3, 0xb9, 0x83, 0xe8, 0xe2, 0xc6, - 0x24, 0xfe, 0xba, 0x04, 0x13, 0x6d, 0x4a, 0xd8, 0x2e, 0x51, 0xd8, 0xb9, 0x74, 0x2f, 0x9c, 0xeb, - 0x9f, 0x90, 0x6b, 0x75, 0x81, 0x6a, 0xf5, 0x2e, 0xf4, 0xce, 0x83, 0x68, 0x15, 0x19, 0x9f, 0x6f, - 0x85, 0x3b, 0xc6, 0x91, 0x76, 0xd0, 0x99, 0x3e, 0x05, 0x13, 0x0a, 0x9d, 0xed, 0x9b, 0x8e, 0xeb, - 0xf3, 0x0c, 0xd5, 0xe7, 0x69, 0xb4, 0xf6, 0xda, 0xf4, 0x69, 0x1d, 0xd6, 0xbf, 0xdc, 0x7a, 0x79, - 0x66, 0x7f, 0x2f, 0x6a, 0x5b, 0xac, 0x16, 0x1e, 0xef, 0x8b, 0x86, 0x2b, 0x75, 0x8e, 0x2a, 0x75, - 0x0a, 0x3d, 0xda, 0x49, 0xa9, 0xc8, 0xb1, 0x00, 0xc3, 0xda, 0xb6, 0x67, 0xdf, 0xc7, 0x4a, 0xe0, - 0x0f, 0xa0, 0x1f, 0x13, 0x5b, 0xb2, 0x27, 0xf6, 0x6d, 0x37, 0x52, 0xc7, 0x16, 0x1e, 0xec, 0x01, - 0x93, 0xcb, 0x75, 0x1f, 0x95, 0x6b, 0x0a, 0x1d, 0xef, 0x24, 0x17, 0xa9, 0x65, 0xd1, 0x47, 0xa5, - 0xe0, 0x14, 0xc7, 0xc9, 0xfd, 0x79, 0x47, 0x8b, 0xdd, 0xc2, 0x43, 0x3d, 0xe1, 0x72, 0x49, 0xee, - 0xa7, 0x92, 0xcc, 0xa0, 0xa9, 0x8e, 0x92, 0xb0, 0xd2, 0xf7, 0x4e, 0x6f, 0xd0, 0x7e, 0x62, 0x02, - 0xa6, 0x3b, 0xb4, 0xe8, 0xef, 0x1e, 0xe8, 0x8e, 0x58, 0x97, 0x4b, 0x5c, 0x3d, 0xee, 0xb9, 0xbe, - 0x9a, 0x02, 0xb4, 0xe2, 0xd5, 0xe6, 0x5d, 0xcc, 0xfe, 0x61, 0x10, 0x0f, 0xc7, 0xa6, 0x3b, 0x0b, - 0xd2, 0x6b, 0xba, 0xb3, 0xb0, 0x12, 0xbb, 0x05, 0x90, 0xe8, 0xef, 0xee, 0x51, 0xcf, 0x57, 0x01, - 0x92, 0x6f, 0xc8, 0x55, 0x80, 0xf6, 0x67, 0xc9, 0x52, 0x3f, 0xc0, 0x23, 0xad, 0xe9, 0x37, 0xe6, - 0x48, 0xeb, 0x11, 0x18, 0xe0, 0x97, 0x84, 0xd8, 0xff, 0x65, 0xe7, 0x6f, 0xe8, 0x09, 0xf1, 0xef, - 0xac, 0x07, 0x7b, 0x3b, 0x9e, 0xc3, 0xb0, 0xf9, 0x41, 0x90, 0xaf, 0x24, 0x21, 0xb7, 0xe2, 0xd5, - 0x2a, 0x55, 0xc3, 0x7f, 0x9d, 0x7c, 0xcf, 0xe9, 0x7c, 0x0a, 0x78, 0xfe, 0xf6, 0xad, 0xe9, 0x51, - 0x66, 0xb2, 0x3b, 0x69, 0xa8, 0x3a, 0x8c, 0x35, 0xdd, 0xb7, 0xe3, 0xae, 0xb9, 0x70, 0x90, 0x6b, - 0x7f, 0x4d, 0xac, 0x64, 0x7a, 0x70, 0x33, 0x12, 0x20, 0x68, 0xb7, 0x7d, 0x34, 0xb0, 0x93, 0x46, - 0x17, 0x5f, 0xcf, 0x4b, 0x31, 0xac, 0x0b, 0xbf, 0x9a, 0x80, 0xa1, 0x15, 0x4f, 0x14, 0x75, 0xf8, - 0xcf, 0xec, 0x91, 0xef, 0xb3, 0xc1, 0xc5, 0xe6, 0x64, 0x6f, 0x81, 0x10, 0xbf, 0xec, 0xfc, 0xad, - 0x24, 0xcd, 0xc3, 0x65, 0x5c, 0x33, 0xac, 0xa0, 0xac, 0xc4, 0x6f, 0x9d, 0x5c, 0xfd, 0x21, 0x3a, - 0xb9, 0x1a, 0xf6, 0x70, 0xea, 0x20, 0x3d, 0xfc, 0x5b, 0x09, 0x18, 0x59, 0xf1, 0x6a, 0x57, 0xac, - 0xea, 0x5b, 0xa1, 0xf2, 0x5a, 0x42, 0xe5, 0x8e, 0x97, 0x66, 0x9f, 0xca, 0x74, 0xbc, 0xc3, 0x5f, - 0xc3, 0x16, 0xf6, 0x0c, 0xef, 0x40, 0xf5, 0x59, 0x6f, 0xf5, 0xd7, 0x37, 0xd3, 0x30, 0xbc, 0xc8, - 0x5a, 0xd9, 0xf0, 0x89, 0x53, 0xbc, 0xa6, 0x35, 0x5a, 0xe4, 0xf1, 0x1f, 0x3f, 0xa3, 0xbf, 0x7f, - 0xa7, 0x3a, 0xf6, 0x0d, 0x2c, 0x96, 0xf1, 0x97, 0xfa, 0x2e, 0x8c, 0xf8, 0x65, 0xd2, 0x66, 0x7e, - 0x32, 0xfb, 0x1d, 0xb5, 0x4d, 0x02, 0x59, 0x27, 0x00, 0xf4, 0x21, 0x09, 0x0e, 0x53, 0xac, 0xd0, - 0x5d, 0x28, 0xa6, 0xb8, 0xfc, 0xd2, 0xb1, 0x98, 0x5f, 0xd6, 0x22, 0x3b, 0x73, 0x94, 0x57, 0xf9, - 0x3e, 0x7e, 0x16, 0xfb, 0x78, 0xa4, 0xf1, 0x66, 0xb6, 0xb2, 0x32, 0x61, 0xb6, 0x50, 0x7a, 0x4d, - 0xfb, 0x39, 0xa9, 0x83, 0xef, 0xe7, 0x5c, 0x22, 0x05, 0x48, 0x30, 0x09, 0xcf, 0xa7, 0xbb, 0xdc, - 0x37, 0x6b, 0xde, 0xf4, 0x8d, 0x12, 0xa3, 0x8f, 0x48, 0x70, 0xb8, 0xed, 0xfa, 0x04, 0xfd, 0x07, - 0x92, 0x7d, 0x6e, 0x2a, 0x37, 0x19, 0xa7, 0x2d, 0x5f, 0x59, 0x99, 0x6c, 0xb4, 0x5b, 0xe8, 0x59, - 0x87, 0x91, 0xd8, 0xda, 0x42, 0x5e, 0xfc, 0x1b, 0xd8, 0xde, 0x4f, 0x07, 0xc7, 0x19, 0xa0, 0x02, - 0x64, 0xf0, 0xae, 0x63, 0xbb, 0x3e, 0xae, 0xd2, 0x2b, 0xc8, 0x19, 0x25, 0x78, 0x97, 0x6f, 0x00, - 0x6a, 0xed, 0x5c, 0x74, 0x19, 0x06, 0xe3, 0x69, 0xee, 0x00, 0x7b, 0x4b, 0x82, 0x03, 0x9a, 0x84, - 0x74, 0xe8, 0xdf, 0x49, 0x85, 0xbd, 0xdc, 0xe9, 0xe4, 0xf0, 0xa7, 0x01, 0x00, 0x00, 0xff, 0xff, - 0x36, 0x66, 0xc7, 0xfd, 0x47, 0x91, 0x00, 0x00, + // 8985 bytes of a gzipped FileDescriptorSet + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x74, 0x1c, 0xd7, + 0x75, 0x18, 0x67, 0x3f, 0x80, 0xdd, 0xbb, 0xf8, 0x58, 0x3c, 0x80, 0xd0, 0x72, 0x49, 0x02, 0xd4, + 0x48, 0x96, 0x28, 0x4a, 0x5a, 0x48, 0x14, 0x45, 0x51, 0x4b, 0xdb, 0x32, 0x16, 0x58, 0x82, 0x20, + 0xf1, 0xa5, 0x01, 0x40, 0xc9, 0x76, 0xd2, 0x3d, 0x83, 0xd9, 0x87, 0xc5, 0x88, 0xb3, 0x33, 0xa3, + 0x99, 0x59, 0x12, 0xa0, 0xed, 0x73, 0x94, 0xf8, 0xa3, 0xb1, 0xda, 0xd4, 0xce, 0xc7, 0x69, 0x65, + 0xc7, 0x72, 0x65, 0xbb, 0xad, 0x53, 0xa7, 0x6d, 0x92, 0x3a, 0x4d, 0x9b, 0xa6, 0xa7, 0x75, 0x5a, + 0x27, 0x71, 0xda, 0xa6, 0x47, 0x3a, 0x75, 0xdb, 0x34, 0xa7, 0xa5, 0x53, 0xd9, 0xa7, 0x75, 0x5c, + 0xb7, 0x49, 0x59, 0xf5, 0x53, 0x3f, 0x92, 0xf3, 0xbe, 0xe6, 0x63, 0x3f, 0xb0, 0xbb, 0x10, 0x25, + 0x5b, 0x27, 0xfa, 0x85, 0x7d, 0xf7, 0xdd, 0x7b, 0xdf, 0xbd, 0xf7, 0xdd, 0x7b, 0xdf, 0x7d, 0x6f, + 0xde, 0x0c, 0xe0, 0xe7, 0xce, 0xc3, 0x89, 0x9a, 0x65, 0xd5, 0x0c, 0x3c, 0x63, 0x3b, 0x96, 0x67, + 0x6d, 0x35, 0xb6, 0x67, 0xaa, 0xd8, 0xd5, 0x1c, 0xdd, 0xf6, 0x2c, 0xa7, 0x40, 0x61, 0x68, 0x94, + 0x61, 0x14, 0x04, 0x86, 0xbc, 0x0c, 0x63, 0x17, 0x74, 0x03, 0xcf, 0xfb, 0x88, 0xeb, 0xd8, 0x43, + 0xe7, 0x20, 0xb1, 0xad, 0x1b, 0x38, 0x27, 0x9d, 0x88, 0x9f, 0xcc, 0x9c, 0xbe, 0xbb, 0xd0, 0x44, + 0x54, 0x88, 0x52, 0xac, 0x11, 0xb0, 0x42, 0x29, 0xe4, 0xef, 0x24, 0x60, 0xbc, 0x4d, 0x2f, 0x42, + 0x90, 0x30, 0xd5, 0x3a, 0xe1, 0x28, 0x9d, 0x4c, 0x2b, 0xf4, 0x37, 0xca, 0xc1, 0xa0, 0xad, 0x6a, + 0x57, 0xd5, 0x1a, 0xce, 0xc5, 0x28, 0x58, 0x34, 0xd1, 0x14, 0x40, 0x15, 0xdb, 0xd8, 0xac, 0x62, + 0x53, 0xdb, 0xcb, 0xc5, 0x4f, 0xc4, 0x4f, 0xa6, 0x95, 0x10, 0x04, 0xdd, 0x0f, 0x63, 0x76, 0x63, + 0xcb, 0xd0, 0xb5, 0x4a, 0x08, 0x0d, 0x4e, 0xc4, 0x4f, 0x26, 0x95, 0x2c, 0xeb, 0x98, 0x0f, 0x90, + 0xef, 0x85, 0xd1, 0xeb, 0x58, 0xbd, 0x1a, 0x46, 0xcd, 0x50, 0xd4, 0x11, 0x02, 0x0e, 0x21, 0xce, + 0xc1, 0x50, 0x1d, 0xbb, 0xae, 0x5a, 0xc3, 0x15, 0x6f, 0xcf, 0xc6, 0xb9, 0x04, 0xd5, 0xfe, 0x44, + 0x8b, 0xf6, 0xcd, 0x9a, 0x67, 0x38, 0xd5, 0xc6, 0x9e, 0x8d, 0xd1, 0x2c, 0xa4, 0xb1, 0xd9, 0xa8, + 0x33, 0x0e, 0xc9, 0x0e, 0xf6, 0x2b, 0x9b, 0x8d, 0x7a, 0x33, 0x97, 0x14, 0x21, 0xe3, 0x2c, 0x06, + 0x5d, 0xec, 0x5c, 0xd3, 0x35, 0x9c, 0x1b, 0xa0, 0x0c, 0xee, 0x6d, 0x61, 0xb0, 0xce, 0xfa, 0x9b, + 0x79, 0x08, 0x3a, 0x34, 0x07, 0x69, 0xbc, 0xeb, 0x61, 0xd3, 0xd5, 0x2d, 0x33, 0x37, 0x48, 0x99, + 0xbc, 0xab, 0xcd, 0x2c, 0x62, 0xa3, 0xda, 0xcc, 0x22, 0xa0, 0x43, 0x67, 0x61, 0xd0, 0xb2, 0x3d, + 0xdd, 0x32, 0xdd, 0x5c, 0xea, 0x84, 0x74, 0x32, 0x73, 0xfa, 0x58, 0x5b, 0x47, 0x58, 0x65, 0x38, + 0x8a, 0x40, 0x46, 0x8b, 0x90, 0x75, 0xad, 0x86, 0xa3, 0xe1, 0x8a, 0x66, 0x55, 0x71, 0x45, 0x37, + 0xb7, 0xad, 0x5c, 0x9a, 0x32, 0x98, 0x6e, 0x55, 0x84, 0x22, 0xce, 0x59, 0x55, 0xbc, 0x68, 0x6e, + 0x5b, 0xca, 0x88, 0x1b, 0x69, 0xa3, 0x49, 0x18, 0x70, 0xf7, 0x4c, 0x4f, 0xdd, 0xcd, 0x0d, 0x51, + 0x0f, 0xe1, 0x2d, 0xf9, 0xd7, 0x06, 0x60, 0xb4, 0x17, 0x17, 0x3b, 0x0f, 0xc9, 0x6d, 0xa2, 0x65, + 0x2e, 0xd6, 0x8f, 0x0d, 0x18, 0x4d, 0xd4, 0x88, 0x03, 0x07, 0x34, 0xe2, 0x2c, 0x64, 0x4c, 0xec, + 0x7a, 0xb8, 0xca, 0x3c, 0x22, 0xde, 0xa3, 0x4f, 0x01, 0x23, 0x6a, 0x75, 0xa9, 0xc4, 0x81, 0x5c, + 0xea, 0x69, 0x18, 0xf5, 0x45, 0xaa, 0x38, 0xaa, 0x59, 0x13, 0xbe, 0x39, 0xd3, 0x4d, 0x92, 0x42, + 0x59, 0xd0, 0x29, 0x84, 0x4c, 0x19, 0xc1, 0x91, 0x36, 0x9a, 0x07, 0xb0, 0x4c, 0x6c, 0x6d, 0x57, + 0xaa, 0x58, 0x33, 0x72, 0xa9, 0x0e, 0x56, 0x5a, 0x25, 0x28, 0x2d, 0x56, 0xb2, 0x18, 0x54, 0x33, + 0xd0, 0xe3, 0x81, 0xab, 0x0d, 0x76, 0xf0, 0x94, 0x65, 0x16, 0x64, 0x2d, 0xde, 0xb6, 0x09, 0x23, + 0x0e, 0x26, 0x7e, 0x8f, 0xab, 0x5c, 0xb3, 0x34, 0x15, 0xa2, 0xd0, 0x55, 0x33, 0x85, 0x93, 0x31, + 0xc5, 0x86, 0x9d, 0x70, 0x13, 0xdd, 0x05, 0x3e, 0xa0, 0x42, 0xdd, 0x0a, 0x68, 0x16, 0x1a, 0x12, + 0xc0, 0x15, 0xb5, 0x8e, 0xf3, 0x37, 0x60, 0x24, 0x6a, 0x1e, 0x34, 0x01, 0x49, 0xd7, 0x53, 0x1d, + 0x8f, 0x7a, 0x61, 0x52, 0x61, 0x0d, 0x94, 0x85, 0x38, 0x36, 0xab, 0x34, 0xcb, 0x25, 0x15, 0xf2, + 0x13, 0xbd, 0x2f, 0x50, 0x38, 0x4e, 0x15, 0xbe, 0xa7, 0x75, 0x46, 0x23, 0x9c, 0x9b, 0xf5, 0xce, + 0x3f, 0x06, 0xc3, 0x11, 0x05, 0x7a, 0x1d, 0x5a, 0xfe, 0x30, 0x1c, 0x6e, 0xcb, 0x1a, 0x3d, 0x0d, + 0x13, 0x0d, 0x53, 0x37, 0x3d, 0xec, 0xd8, 0x0e, 0x26, 0x1e, 0xcb, 0x86, 0xca, 0xfd, 0x97, 0xc1, + 0x0e, 0x3e, 0xb7, 0x19, 0xc6, 0x66, 0x5c, 0x94, 0xf1, 0x46, 0x2b, 0xf0, 0x54, 0x3a, 0xf5, 0xdd, + 0xc1, 0xec, 0x73, 0xcf, 0x3d, 0xf7, 0x5c, 0x4c, 0x7e, 0x61, 0x00, 0x26, 0xda, 0xc5, 0x4c, 0xdb, + 0xf0, 0x9d, 0x84, 0x01, 0xb3, 0x51, 0xdf, 0xc2, 0x0e, 0x35, 0x52, 0x52, 0xe1, 0x2d, 0x34, 0x0b, + 0x49, 0x43, 0xdd, 0xc2, 0x46, 0x2e, 0x71, 0x42, 0x3a, 0x39, 0x72, 0xfa, 0xfe, 0x9e, 0xa2, 0xb2, + 0xb0, 0x44, 0x48, 0x14, 0x46, 0x89, 0xde, 0x0b, 0x09, 0x9e, 0xa2, 0x09, 0x87, 0x53, 0xbd, 0x71, + 0x20, 0xb1, 0xa4, 0x50, 0x3a, 0x74, 0x14, 0xd2, 0xe4, 0x2f, 0xf3, 0x8d, 0x01, 0x2a, 0x73, 0x8a, + 0x00, 0x88, 0x5f, 0xa0, 0x3c, 0xa4, 0x68, 0x98, 0x54, 0xb1, 0x58, 0xda, 0xfc, 0x36, 0x71, 0xac, + 0x2a, 0xde, 0x56, 0x1b, 0x86, 0x57, 0xb9, 0xa6, 0x1a, 0x0d, 0x4c, 0x1d, 0x3e, 0xad, 0x0c, 0x71, + 0xe0, 0x15, 0x02, 0x43, 0xd3, 0x90, 0x61, 0x51, 0xa5, 0x9b, 0x55, 0xbc, 0x4b, 0xb3, 0x67, 0x52, + 0x61, 0x81, 0xb6, 0x48, 0x20, 0x64, 0xf8, 0x67, 0x5c, 0xcb, 0x14, 0xae, 0x49, 0x87, 0x20, 0x00, + 0x3a, 0xfc, 0x63, 0xcd, 0x89, 0xfb, 0x78, 0x7b, 0xf5, 0x9a, 0x7d, 0x4a, 0xfe, 0xd5, 0x18, 0x24, + 0x68, 0xbe, 0x18, 0x85, 0xcc, 0xc6, 0xfb, 0xd7, 0xca, 0x95, 0xf9, 0xd5, 0xcd, 0xd2, 0x52, 0x39, + 0x2b, 0xa1, 0x11, 0x00, 0x0a, 0xb8, 0xb0, 0xb4, 0x3a, 0xbb, 0x91, 0x8d, 0xf9, 0xed, 0xc5, 0x95, + 0x8d, 0xb3, 0x67, 0xb2, 0x71, 0x9f, 0x60, 0x93, 0x01, 0x12, 0x61, 0x84, 0x47, 0x4e, 0x67, 0x93, + 0x28, 0x0b, 0x43, 0x8c, 0xc1, 0xe2, 0xd3, 0xe5, 0xf9, 0xb3, 0x67, 0xb2, 0x03, 0x51, 0xc8, 0x23, + 0xa7, 0xb3, 0x83, 0x68, 0x18, 0xd2, 0x14, 0x52, 0x5a, 0x5d, 0x5d, 0xca, 0xa6, 0x7c, 0x9e, 0xeb, + 0x1b, 0xca, 0xe2, 0xca, 0x42, 0x36, 0xed, 0xf3, 0x5c, 0x50, 0x56, 0x37, 0xd7, 0xb2, 0xe0, 0x73, + 0x58, 0x2e, 0xaf, 0xaf, 0xcf, 0x2e, 0x94, 0xb3, 0x19, 0x1f, 0xa3, 0xf4, 0xfe, 0x8d, 0xf2, 0x7a, + 0x76, 0x28, 0x22, 0xd6, 0x23, 0xa7, 0xb3, 0xc3, 0xfe, 0x10, 0xe5, 0x95, 0xcd, 0xe5, 0xec, 0x08, + 0x1a, 0x83, 0x61, 0x36, 0x84, 0x10, 0x62, 0xb4, 0x09, 0x74, 0xf6, 0x4c, 0x36, 0x1b, 0x08, 0xc2, + 0xb8, 0x8c, 0x45, 0x00, 0x67, 0xcf, 0x64, 0x91, 0x3c, 0x07, 0x49, 0xea, 0x5d, 0x08, 0xc1, 0xc8, + 0xd2, 0x6c, 0xa9, 0xbc, 0x54, 0x59, 0x5d, 0xdb, 0x58, 0x5c, 0x5d, 0x99, 0x5d, 0xca, 0x4a, 0x01, + 0x4c, 0x29, 0x3f, 0xb9, 0xb9, 0xa8, 0x94, 0xe7, 0xb3, 0xb1, 0x30, 0x6c, 0xad, 0x3c, 0xbb, 0x51, + 0x9e, 0xcf, 0xc6, 0x65, 0x0d, 0x26, 0xda, 0xe5, 0xc9, 0xb6, 0x91, 0x11, 0x9a, 0xe2, 0x58, 0x87, + 0x29, 0xa6, 0xbc, 0x5a, 0xa6, 0xf8, 0xdb, 0x31, 0x18, 0x6f, 0xb3, 0x56, 0xb4, 0x1d, 0xe4, 0x09, + 0x48, 0x32, 0x17, 0x65, 0xab, 0xe7, 0x7d, 0x6d, 0x17, 0x1d, 0xea, 0xb0, 0x2d, 0x2b, 0x28, 0xa5, + 0x0b, 0x57, 0x10, 0xf1, 0x0e, 0x15, 0x04, 0x61, 0xd1, 0x92, 0xd3, 0x7f, 0xb4, 0x25, 0xa7, 0xb3, + 0x65, 0xef, 0x6c, 0x2f, 0xcb, 0x1e, 0x85, 0xf5, 0x97, 0xdb, 0x93, 0x6d, 0x72, 0xfb, 0x79, 0x18, + 0x6b, 0x61, 0xd4, 0x73, 0x8e, 0xfd, 0xa8, 0x04, 0xb9, 0x4e, 0xc6, 0xe9, 0x92, 0xe9, 0x62, 0x91, + 0x4c, 0x77, 0xbe, 0xd9, 0x82, 0x77, 0x76, 0x9e, 0x84, 0x96, 0xb9, 0xfe, 0xb2, 0x04, 0x93, 0xed, + 0x2b, 0xc5, 0xb6, 0x32, 0xbc, 0x17, 0x06, 0xea, 0xd8, 0xdb, 0xb1, 0x44, 0xb5, 0x74, 0x4f, 0x9b, + 0x35, 0x98, 0x74, 0x37, 0x4f, 0x36, 0xa7, 0x0a, 0x2f, 0xe2, 0xf1, 0x4e, 0xe5, 0x1e, 0x93, 0xa6, + 0x45, 0xd2, 0x4f, 0xc6, 0xe0, 0x70, 0x5b, 0xe6, 0x6d, 0x05, 0x3d, 0x0e, 0xa0, 0x9b, 0x76, 0xc3, + 0x63, 0x15, 0x11, 0x4b, 0xb0, 0x69, 0x0a, 0xa1, 0xc9, 0x8b, 0x24, 0xcf, 0x86, 0xe7, 0xf7, 0xc7, + 0x69, 0x3f, 0x30, 0x10, 0x45, 0x38, 0x17, 0x08, 0x9a, 0xa0, 0x82, 0x4e, 0x75, 0xd0, 0xb4, 0xc5, + 0x31, 0x1f, 0x82, 0xac, 0x66, 0xe8, 0xd8, 0xf4, 0x2a, 0xae, 0xe7, 0x60, 0xb5, 0xae, 0x9b, 0x35, + 0xba, 0x82, 0xa4, 0x8a, 0xc9, 0x6d, 0xd5, 0x70, 0xb1, 0x32, 0xca, 0xba, 0xd7, 0x45, 0x2f, 0xa1, + 0xa0, 0x0e, 0xe4, 0x84, 0x28, 0x06, 0x22, 0x14, 0xac, 0xdb, 0xa7, 0x90, 0x7f, 0x3a, 0x0d, 0x99, + 0x50, 0x5d, 0x8d, 0xee, 0x84, 0xa1, 0x67, 0xd4, 0x6b, 0x6a, 0x45, 0xec, 0x95, 0x98, 0x25, 0x32, + 0x04, 0xb6, 0xc6, 0xf7, 0x4b, 0x0f, 0xc1, 0x04, 0x45, 0xb1, 0x1a, 0x1e, 0x76, 0x2a, 0x9a, 0xa1, + 0xba, 0x2e, 0x35, 0x5a, 0x8a, 0xa2, 0x22, 0xd2, 0xb7, 0x4a, 0xba, 0xe6, 0x44, 0x0f, 0x7a, 0x14, + 0xc6, 0x29, 0x45, 0xbd, 0x61, 0x78, 0xba, 0x6d, 0xe0, 0x0a, 0xd9, 0xbd, 0xb9, 0x74, 0x25, 0xf1, + 0x25, 0x1b, 0x23, 0x18, 0xcb, 0x1c, 0x81, 0x48, 0xe4, 0xa2, 0x79, 0x38, 0x4e, 0xc9, 0x6a, 0xd8, + 0xc4, 0x8e, 0xea, 0xe1, 0x0a, 0x7e, 0xb6, 0xa1, 0x1a, 0x6e, 0x45, 0x35, 0xab, 0x95, 0x1d, 0xd5, + 0xdd, 0xc9, 0x4d, 0x10, 0x06, 0xa5, 0x58, 0x4e, 0x52, 0x8e, 0x10, 0xc4, 0x05, 0x8e, 0x57, 0xa6, + 0x68, 0xb3, 0x66, 0xf5, 0xa2, 0xea, 0xee, 0xa0, 0x22, 0x4c, 0x52, 0x2e, 0xae, 0xe7, 0xe8, 0x66, + 0xad, 0xa2, 0xed, 0x60, 0xed, 0x6a, 0xa5, 0xe1, 0x6d, 0x9f, 0xcb, 0x1d, 0x0d, 0x8f, 0x4f, 0x25, + 0x5c, 0xa7, 0x38, 0x73, 0x04, 0x65, 0xd3, 0xdb, 0x3e, 0x87, 0xd6, 0x61, 0x88, 0x4c, 0x46, 0x5d, + 0xbf, 0x81, 0x2b, 0xdb, 0x96, 0x43, 0x97, 0xc6, 0x91, 0x36, 0xa9, 0x29, 0x64, 0xc1, 0xc2, 0x2a, + 0x27, 0x58, 0xb6, 0xaa, 0xb8, 0x98, 0x5c, 0x5f, 0x2b, 0x97, 0xe7, 0x95, 0x8c, 0xe0, 0x72, 0xc1, + 0x72, 0x88, 0x43, 0xd5, 0x2c, 0xdf, 0xc0, 0x19, 0xe6, 0x50, 0x35, 0x4b, 0x98, 0xf7, 0x51, 0x18, + 0xd7, 0x34, 0xa6, 0xb3, 0xae, 0x55, 0xf8, 0x1e, 0xcb, 0xcd, 0x65, 0x23, 0xc6, 0xd2, 0xb4, 0x05, + 0x86, 0xc0, 0x7d, 0xdc, 0x45, 0x8f, 0xc3, 0xe1, 0xc0, 0x58, 0x61, 0xc2, 0xb1, 0x16, 0x2d, 0x9b, + 0x49, 0x1f, 0x85, 0x71, 0x7b, 0xaf, 0x95, 0x10, 0x45, 0x46, 0xb4, 0xf7, 0x9a, 0xc9, 0x1e, 0x83, + 0x09, 0x7b, 0xc7, 0x6e, 0xa5, 0x3b, 0x15, 0xa6, 0x43, 0xf6, 0x8e, 0xdd, 0x4c, 0xf8, 0x2e, 0xba, + 0xe1, 0x76, 0xb0, 0xa6, 0x7a, 0xb8, 0x9a, 0xbb, 0x23, 0x8c, 0x1e, 0xea, 0x40, 0x33, 0x90, 0xd5, + 0xb4, 0x0a, 0x36, 0xd5, 0x2d, 0x03, 0x57, 0x54, 0x07, 0x9b, 0xaa, 0x9b, 0x9b, 0x0e, 0x23, 0x8f, + 0x68, 0x5a, 0x99, 0xf6, 0xce, 0xd2, 0x4e, 0x74, 0x0a, 0xc6, 0xac, 0xad, 0x67, 0x34, 0xe6, 0x92, + 0x15, 0xdb, 0xc1, 0xdb, 0xfa, 0x6e, 0xee, 0x6e, 0x6a, 0xdf, 0x51, 0xd2, 0x41, 0x1d, 0x72, 0x8d, + 0x82, 0xd1, 0x7d, 0x90, 0xd5, 0xdc, 0x1d, 0xd5, 0xb1, 0x69, 0x4e, 0x76, 0x6d, 0x55, 0xc3, 0xb9, + 0x77, 0x31, 0x54, 0x06, 0x5f, 0x11, 0x60, 0x12, 0x12, 0xee, 0x75, 0x7d, 0xdb, 0x13, 0x1c, 0xef, + 0x65, 0x21, 0x41, 0x61, 0x9c, 0xdb, 0x49, 0xc8, 0x12, 0x53, 0x44, 0x06, 0x3e, 0x49, 0xd1, 0x46, + 0xec, 0x1d, 0x3b, 0x3c, 0xee, 0x5d, 0x30, 0x4c, 0x30, 0x83, 0x41, 0xef, 0x63, 0x05, 0x99, 0xbd, + 0x13, 0x1a, 0xf1, 0x0c, 0x4c, 0x12, 0xa4, 0x3a, 0xf6, 0xd4, 0xaa, 0xea, 0xa9, 0x21, 0xec, 0x07, + 0x28, 0x36, 0xb1, 0xfb, 0x32, 0xef, 0x8c, 0xc8, 0xe9, 0x34, 0xb6, 0xf6, 0x7c, 0xcf, 0x7a, 0x90, + 0xc9, 0x49, 0x60, 0xc2, 0xb7, 0xde, 0xb4, 0xa2, 0x5b, 0x2e, 0xc2, 0x50, 0xd8, 0xf1, 0x51, 0x1a, + 0x98, 0xeb, 0x67, 0x25, 0x52, 0x05, 0xcd, 0xad, 0xce, 0x93, 0xfa, 0xe5, 0x03, 0xe5, 0x6c, 0x8c, + 0xd4, 0x51, 0x4b, 0x8b, 0x1b, 0xe5, 0x8a, 0xb2, 0xb9, 0xb2, 0xb1, 0xb8, 0x5c, 0xce, 0xc6, 0x43, + 0x05, 0xfb, 0xa5, 0x44, 0xea, 0x9e, 0xec, 0xbd, 0xf2, 0x2b, 0x31, 0x18, 0x89, 0xee, 0xc0, 0xd0, + 0xbb, 0xe1, 0x0e, 0x71, 0x5c, 0xe2, 0x62, 0xaf, 0x72, 0x5d, 0x77, 0x68, 0x44, 0xd6, 0x55, 0xb6, + 0x3a, 0xfa, 0x3e, 0x31, 0xc1, 0xb1, 0xd6, 0xb1, 0xf7, 0x94, 0xee, 0x90, 0x78, 0xab, 0xab, 0x1e, + 0x5a, 0x82, 0x69, 0xd3, 0xaa, 0xb8, 0x9e, 0x6a, 0x56, 0x55, 0xa7, 0x5a, 0x09, 0x0e, 0xaa, 0x2a, + 0xaa, 0xa6, 0x61, 0xd7, 0xb5, 0xd8, 0x4a, 0xe8, 0x73, 0x39, 0x66, 0x5a, 0xeb, 0x1c, 0x39, 0x58, + 0x22, 0x66, 0x39, 0x6a, 0x93, 0xff, 0xc6, 0x3b, 0xf9, 0xef, 0x51, 0x48, 0xd7, 0x55, 0xbb, 0x82, + 0x4d, 0xcf, 0xd9, 0xa3, 0x75, 0x77, 0x4a, 0x49, 0xd5, 0x55, 0xbb, 0x4c, 0xda, 0x6f, 0xc9, 0xf6, + 0xe7, 0x52, 0x22, 0x95, 0xca, 0xa6, 0x2f, 0x25, 0x52, 0xe9, 0x2c, 0xc8, 0xaf, 0xc6, 0x61, 0x28, + 0x5c, 0x87, 0x93, 0x6d, 0x8d, 0x46, 0x97, 0x2c, 0x89, 0x26, 0xb5, 0xbb, 0xf6, 0xad, 0xda, 0x0b, + 0x73, 0x64, 0x2d, 0x2b, 0x0e, 0xb0, 0xea, 0x58, 0x61, 0x94, 0xa4, 0x8e, 0x20, 0xce, 0x86, 0x59, + 0x35, 0x92, 0x52, 0x78, 0x0b, 0x2d, 0xc0, 0xc0, 0x33, 0x2e, 0xe5, 0x3d, 0x40, 0x79, 0xdf, 0xbd, + 0x3f, 0xef, 0x4b, 0xeb, 0x94, 0x79, 0xfa, 0xd2, 0x7a, 0x65, 0x65, 0x55, 0x59, 0x9e, 0x5d, 0x52, + 0x38, 0x39, 0x3a, 0x02, 0x09, 0x43, 0xbd, 0xb1, 0x17, 0x5d, 0xf5, 0x28, 0xa8, 0xd7, 0x49, 0x38, + 0x02, 0x89, 0xeb, 0x58, 0xbd, 0x1a, 0x5d, 0x6b, 0x28, 0xe8, 0x4d, 0x0c, 0x86, 0x19, 0x48, 0x52, + 0x7b, 0x21, 0x00, 0x6e, 0xb1, 0xec, 0x21, 0x94, 0x82, 0xc4, 0xdc, 0xaa, 0x42, 0x02, 0x22, 0x0b, + 0x43, 0x0c, 0x5a, 0x59, 0x5b, 0x2c, 0xcf, 0x95, 0xb3, 0x31, 0xf9, 0x51, 0x18, 0x60, 0x46, 0x20, + 0xc1, 0xe2, 0x9b, 0x21, 0x7b, 0x88, 0x37, 0x39, 0x0f, 0x49, 0xf4, 0x6e, 0x2e, 0x97, 0xca, 0x4a, + 0x36, 0x16, 0x9d, 0xea, 0x44, 0x36, 0x29, 0xbb, 0x30, 0x14, 0x2e, 0xc4, 0xdf, 0x9a, 0x4d, 0xf6, + 0xd7, 0x24, 0xc8, 0x84, 0x0a, 0x6b, 0x52, 0x11, 0xa9, 0x86, 0x61, 0x5d, 0xaf, 0xa8, 0x86, 0xae, + 0xba, 0xdc, 0x35, 0x80, 0x82, 0x66, 0x09, 0xa4, 0xd7, 0xa9, 0x7b, 0x8b, 0x42, 0x24, 0x99, 0x1d, + 0x90, 0x3f, 0x2f, 0x41, 0xb6, 0xb9, 0xb2, 0x6d, 0x12, 0x53, 0xfa, 0x41, 0x8a, 0x29, 0x7f, 0x4e, + 0x82, 0x91, 0x68, 0x39, 0xdb, 0x24, 0xde, 0x9d, 0x3f, 0x50, 0xf1, 0xfe, 0x20, 0x06, 0xc3, 0x91, + 0x22, 0xb6, 0x57, 0xe9, 0x9e, 0x85, 0x31, 0xbd, 0x8a, 0xeb, 0xb6, 0xe5, 0x61, 0x53, 0xdb, 0xab, + 0x18, 0xf8, 0x1a, 0x36, 0x72, 0x32, 0x4d, 0x1a, 0x33, 0xfb, 0x97, 0xc9, 0x85, 0xc5, 0x80, 0x6e, + 0x89, 0x90, 0x15, 0xc7, 0x17, 0xe7, 0xcb, 0xcb, 0x6b, 0xab, 0x1b, 0xe5, 0x95, 0xb9, 0xf7, 0x57, + 0x36, 0x57, 0x2e, 0xaf, 0xac, 0x3e, 0xb5, 0xa2, 0x64, 0xf5, 0x26, 0xb4, 0x37, 0x31, 0xec, 0xd7, + 0x20, 0xdb, 0x2c, 0x14, 0xba, 0x03, 0xda, 0x89, 0x95, 0x3d, 0x84, 0xc6, 0x61, 0x74, 0x65, 0xb5, + 0xb2, 0xbe, 0x38, 0x5f, 0xae, 0x94, 0x2f, 0x5c, 0x28, 0xcf, 0x6d, 0xac, 0xb3, 0x83, 0x0f, 0x1f, + 0x7b, 0x23, 0x12, 0xe0, 0xf2, 0x67, 0xe3, 0x30, 0xde, 0x46, 0x12, 0x34, 0xcb, 0xb7, 0x2c, 0x6c, + 0x17, 0xf5, 0x60, 0x2f, 0xd2, 0x17, 0x48, 0xcd, 0xb0, 0xa6, 0x3a, 0x1e, 0xdf, 0xe1, 0xdc, 0x07, + 0xc4, 0x4a, 0xa6, 0xa7, 0x6f, 0xeb, 0xd8, 0xe1, 0xe7, 0x44, 0x6c, 0x1f, 0x33, 0x1a, 0xc0, 0xd9, + 0x51, 0xd1, 0x03, 0x80, 0x6c, 0xcb, 0xd5, 0x3d, 0xfd, 0x1a, 0xae, 0xe8, 0xa6, 0x38, 0x54, 0x22, + 0xfb, 0x9a, 0x84, 0x92, 0x15, 0x3d, 0x8b, 0xa6, 0xe7, 0x63, 0x9b, 0xb8, 0xa6, 0x36, 0x61, 0x93, + 0x64, 0x1e, 0x57, 0xb2, 0xa2, 0xc7, 0xc7, 0xbe, 0x13, 0x86, 0xaa, 0x56, 0x83, 0x14, 0x7b, 0x0c, + 0x8f, 0xac, 0x1d, 0x92, 0x92, 0x61, 0x30, 0x1f, 0x85, 0x97, 0xf1, 0xc1, 0x69, 0xd6, 0x90, 0x92, + 0x61, 0x30, 0x86, 0x72, 0x2f, 0x8c, 0xaa, 0xb5, 0x9a, 0x43, 0x98, 0x0b, 0x46, 0x6c, 0x63, 0x32, + 0xe2, 0x83, 0x29, 0x62, 0xfe, 0x12, 0xa4, 0x84, 0x1d, 0xc8, 0x52, 0x4d, 0x2c, 0x51, 0xb1, 0xd9, + 0x6e, 0x3b, 0x76, 0x32, 0xad, 0xa4, 0x4c, 0xd1, 0x79, 0x27, 0x0c, 0xe9, 0x6e, 0x25, 0x38, 0x9c, + 0x8f, 0x9d, 0x88, 0x9d, 0x4c, 0x29, 0x19, 0xdd, 0xf5, 0x0f, 0x36, 0xe5, 0x2f, 0xc7, 0x60, 0x24, + 0xfa, 0x70, 0x01, 0xcd, 0x43, 0xca, 0xb0, 0x34, 0x95, 0xba, 0x16, 0x7b, 0xb2, 0x75, 0xb2, 0xcb, + 0xf3, 0x88, 0xc2, 0x12, 0xc7, 0x57, 0x7c, 0xca, 0xfc, 0xbf, 0x92, 0x20, 0x25, 0xc0, 0x68, 0x12, + 0x12, 0xb6, 0xea, 0xed, 0x50, 0x76, 0xc9, 0x52, 0x2c, 0x2b, 0x29, 0xb4, 0x4d, 0xe0, 0xae, 0xad, + 0x9a, 0xd4, 0x05, 0x38, 0x9c, 0xb4, 0xc9, 0xbc, 0x1a, 0x58, 0xad, 0xd2, 0x5d, 0x8f, 0x55, 0xaf, + 0x63, 0xd3, 0x73, 0xc5, 0xbc, 0x72, 0xf8, 0x1c, 0x07, 0xa3, 0xfb, 0x61, 0xcc, 0x73, 0x54, 0xdd, + 0x88, 0xe0, 0x26, 0x28, 0x6e, 0x56, 0x74, 0xf8, 0xc8, 0x45, 0x38, 0x22, 0xf8, 0x56, 0xb1, 0xa7, + 0x6a, 0x3b, 0xb8, 0x1a, 0x10, 0x0d, 0xd0, 0xd3, 0x8d, 0x3b, 0x38, 0xc2, 0x3c, 0xef, 0x17, 0xb4, + 0xf2, 0x2b, 0x12, 0x8c, 0x89, 0x7d, 0x5a, 0xd5, 0x37, 0xd6, 0x32, 0x80, 0x6a, 0x9a, 0x96, 0x17, + 0x36, 0x57, 0xab, 0x2b, 0xb7, 0xd0, 0x15, 0x66, 0x7d, 0x22, 0x25, 0xc4, 0x20, 0x5f, 0x07, 0x08, + 0x7a, 0x3a, 0x9a, 0x6d, 0x1a, 0x32, 0xfc, 0xc9, 0x11, 0x7d, 0xfc, 0xc8, 0x76, 0xf6, 0xc0, 0x40, + 0x64, 0x43, 0x87, 0x26, 0x20, 0xb9, 0x85, 0x6b, 0xba, 0xc9, 0xcf, 0x83, 0x59, 0x43, 0x9c, 0xbf, + 0x24, 0xfc, 0xf3, 0x97, 0xd2, 0xa7, 0x24, 0x18, 0xd7, 0xac, 0x7a, 0xb3, 0xbc, 0xa5, 0x6c, 0xd3, + 0xf1, 0x82, 0x7b, 0x51, 0xfa, 0xc0, 0x7b, 0x6b, 0xba, 0xb7, 0xd3, 0xd8, 0x2a, 0x68, 0x56, 0x7d, + 0xa6, 0x66, 0x19, 0xaa, 0x59, 0x0b, 0x9e, 0x9f, 0xd2, 0x1f, 0xda, 0x83, 0x35, 0x6c, 0x3e, 0x58, + 0xb3, 0x42, 0x4f, 0x53, 0xcf, 0x07, 0x3f, 0xff, 0xaf, 0x24, 0x7d, 0x31, 0x16, 0x5f, 0x58, 0x2b, + 0x7d, 0x25, 0x96, 0x5f, 0x60, 0xc3, 0xad, 0x09, 0xf3, 0x28, 0x78, 0xdb, 0xc0, 0x1a, 0x51, 0x19, + 0xbe, 0x77, 0x3f, 0x4c, 0xd4, 0xac, 0x9a, 0x45, 0x39, 0xce, 0x90, 0x5f, 0xfc, 0x89, 0x6c, 0xda, + 0x87, 0xe6, 0xbb, 0x3e, 0xbe, 0x2d, 0xae, 0xc0, 0x38, 0x47, 0xae, 0xd0, 0x47, 0x42, 0x6c, 0x63, + 0x83, 0xf6, 0x3d, 0x56, 0xcb, 0xfd, 0xf2, 0x77, 0xe8, 0x82, 0xae, 0x8c, 0x71, 0x52, 0xd2, 0xc7, + 0xf6, 0x3e, 0x45, 0x05, 0x0e, 0x47, 0xf8, 0xb1, 0xb0, 0xc5, 0x4e, 0x17, 0x8e, 0xbf, 0xc9, 0x39, + 0x8e, 0x87, 0x38, 0xae, 0x73, 0xd2, 0xe2, 0x1c, 0x0c, 0xf7, 0xc3, 0xeb, 0xb7, 0x38, 0xaf, 0x21, + 0x1c, 0x66, 0xb2, 0x00, 0xa3, 0x94, 0x89, 0xd6, 0x70, 0x3d, 0xab, 0x4e, 0x73, 0xe2, 0xfe, 0x6c, + 0x7e, 0xfb, 0x3b, 0x2c, 0x8e, 0x46, 0x08, 0xd9, 0x9c, 0x4f, 0x55, 0x2c, 0x02, 0x7d, 0x0a, 0x56, + 0xc5, 0x9a, 0xd1, 0x85, 0xc3, 0x37, 0xb8, 0x20, 0x3e, 0x7e, 0xf1, 0x0a, 0x4c, 0x90, 0xdf, 0x34, + 0x65, 0x85, 0x25, 0xe9, 0x7e, 0x06, 0x97, 0x7b, 0xe5, 0xa3, 0x2c, 0x54, 0xc7, 0x7d, 0x06, 0x21, + 0x99, 0x42, 0xb3, 0x58, 0xc3, 0x9e, 0x87, 0x1d, 0xb7, 0xa2, 0x1a, 0xed, 0xc4, 0x0b, 0x1d, 0x62, + 0xe4, 0x3e, 0xf3, 0xfd, 0xe8, 0x2c, 0x2e, 0x30, 0xca, 0x59, 0xc3, 0x28, 0x6e, 0xc2, 0x1d, 0x6d, + 0xbc, 0xa2, 0x07, 0x9e, 0x9f, 0xe5, 0x3c, 0x27, 0x5a, 0x3c, 0x83, 0xb0, 0x5d, 0x03, 0x01, 0xf7, + 0xe7, 0xb2, 0x07, 0x9e, 0x3f, 0xc7, 0x79, 0x22, 0x4e, 0x2b, 0xa6, 0x94, 0x70, 0xbc, 0x04, 0x63, + 0xd7, 0xb0, 0xb3, 0x65, 0xb9, 0xfc, 0xe0, 0xa8, 0x07, 0x76, 0x9f, 0xe3, 0xec, 0x46, 0x39, 0x21, + 0x3d, 0x49, 0x22, 0xbc, 0x1e, 0x87, 0xd4, 0xb6, 0xaa, 0xe1, 0x1e, 0x58, 0xbc, 0xc8, 0x59, 0x0c, + 0x12, 0x7c, 0x42, 0x3a, 0x0b, 0x43, 0x35, 0x8b, 0xaf, 0x5a, 0xdd, 0xc9, 0x3f, 0xcf, 0xc9, 0x33, + 0x82, 0x86, 0xb3, 0xb0, 0x2d, 0xbb, 0x61, 0x90, 0x25, 0xad, 0x3b, 0x8b, 0xbf, 0x2a, 0x58, 0x08, + 0x1a, 0xce, 0xa2, 0x0f, 0xb3, 0xbe, 0x24, 0x58, 0xb8, 0x21, 0x7b, 0x3e, 0x01, 0x19, 0xcb, 0x34, + 0xf6, 0x2c, 0xb3, 0x17, 0x21, 0xbe, 0xc0, 0x39, 0x00, 0x27, 0x21, 0x0c, 0xce, 0x43, 0xba, 0xd7, + 0x89, 0xf8, 0xeb, 0xdf, 0x17, 0xe1, 0x21, 0x66, 0x60, 0x01, 0x46, 0x45, 0x82, 0xd2, 0x2d, 0xb3, + 0x07, 0x16, 0x7f, 0x83, 0xb3, 0x18, 0x09, 0x91, 0x71, 0x35, 0x3c, 0xec, 0x7a, 0x35, 0xdc, 0x0b, + 0x93, 0x2f, 0x0b, 0x35, 0x38, 0x09, 0x37, 0xe5, 0x16, 0x36, 0xb5, 0x9d, 0xde, 0x38, 0xfc, 0xbc, + 0x30, 0xa5, 0xa0, 0x21, 0x2c, 0xe6, 0x60, 0xb8, 0xae, 0x3a, 0xee, 0x8e, 0x6a, 0xf4, 0x34, 0x1d, + 0x7f, 0x93, 0xf3, 0x18, 0xf2, 0x89, 0xb8, 0x45, 0x1a, 0x66, 0x3f, 0x6c, 0xbe, 0x22, 0x2c, 0x12, + 0x22, 0xe3, 0xa1, 0xe7, 0x7a, 0xf4, 0x94, 0xad, 0x1f, 0x6e, 0xbf, 0x20, 0x42, 0x8f, 0xd1, 0x2e, + 0x87, 0x39, 0x9e, 0x87, 0xb4, 0xab, 0xdf, 0xe8, 0x89, 0xcd, 0xdf, 0x12, 0x33, 0x4d, 0x09, 0x08, + 0xf1, 0xfb, 0xe1, 0x48, 0xdb, 0x65, 0xa2, 0x07, 0x66, 0x7f, 0x9b, 0x33, 0x9b, 0x6c, 0xb3, 0x54, + 0xf0, 0x94, 0xd0, 0x2f, 0xcb, 0xbf, 0x23, 0x52, 0x02, 0x6e, 0xe2, 0xb5, 0x46, 0xf6, 0x11, 0xae, + 0xba, 0xdd, 0x9f, 0xd5, 0x7e, 0x51, 0x58, 0x8d, 0xd1, 0x46, 0xac, 0xb6, 0x01, 0x93, 0x9c, 0x63, + 0x7f, 0xf3, 0xfa, 0x4b, 0x22, 0xb1, 0x32, 0xea, 0xcd, 0xe8, 0xec, 0x7e, 0x10, 0xf2, 0xbe, 0x39, + 0x45, 0xc1, 0xea, 0x56, 0xea, 0xaa, 0xdd, 0x03, 0xe7, 0x5f, 0xe6, 0x9c, 0x45, 0xc6, 0xf7, 0x2b, + 0x5e, 0x77, 0x59, 0xb5, 0x09, 0xf3, 0xa7, 0x21, 0x27, 0x98, 0x37, 0x4c, 0x07, 0x6b, 0x56, 0xcd, + 0xd4, 0x6f, 0xe0, 0x6a, 0x0f, 0xac, 0xff, 0x6e, 0xd3, 0x54, 0x6d, 0x86, 0xc8, 0x09, 0xe7, 0x45, + 0xc8, 0xfa, 0xb5, 0x4a, 0x45, 0xaf, 0xdb, 0x96, 0xe3, 0x75, 0xe1, 0xf8, 0x55, 0x31, 0x53, 0x3e, + 0xdd, 0x22, 0x25, 0x2b, 0x96, 0x61, 0x84, 0x36, 0x7b, 0x75, 0xc9, 0x5f, 0xe1, 0x8c, 0x86, 0x03, + 0x2a, 0x9e, 0x38, 0x34, 0xab, 0x6e, 0xab, 0x4e, 0x2f, 0xf9, 0xef, 0xef, 0x89, 0xc4, 0xc1, 0x49, + 0x78, 0xe2, 0xf0, 0xf6, 0x6c, 0x4c, 0x56, 0xfb, 0x1e, 0x38, 0xfc, 0xaa, 0x48, 0x1c, 0x82, 0x86, + 0xb3, 0x10, 0x05, 0x43, 0x0f, 0x2c, 0xfe, 0xbe, 0x60, 0x21, 0x68, 0x08, 0x8b, 0x27, 0x83, 0x85, + 0xd6, 0xc1, 0x35, 0xdd, 0xf5, 0x1c, 0x56, 0x26, 0xef, 0xcf, 0xea, 0x1f, 0x7c, 0x3f, 0x5a, 0x84, + 0x29, 0x21, 0x52, 0x92, 0x89, 0xf8, 0xb1, 0x2b, 0xdd, 0x45, 0x75, 0x17, 0xec, 0xd7, 0x44, 0x26, + 0x0a, 0x91, 0x11, 0xd9, 0x42, 0x15, 0x22, 0x31, 0xbb, 0x46, 0xf6, 0x0e, 0x3d, 0xb0, 0xfb, 0x87, + 0x4d, 0xc2, 0xad, 0x0b, 0x5a, 0xc2, 0x33, 0x54, 0xff, 0x34, 0xcc, 0xab, 0x78, 0xaf, 0x27, 0xef, + 0xfc, 0xf5, 0xa6, 0xfa, 0x67, 0x93, 0x51, 0xb2, 0x1c, 0x32, 0xda, 0x54, 0x4f, 0xa1, 0x6e, 0xf7, + 0x87, 0x72, 0x3f, 0xf6, 0x1a, 0xd7, 0x37, 0x5a, 0x4e, 0x15, 0x97, 0x88, 0x93, 0x47, 0x8b, 0x9e, + 0xee, 0xcc, 0x3e, 0xfa, 0x9a, 0xef, 0xe7, 0x91, 0x9a, 0xa7, 0x78, 0x01, 0x86, 0x23, 0x05, 0x4f, + 0x77, 0x56, 0x1f, 0xe3, 0xac, 0x86, 0xc2, 0xf5, 0x4e, 0xf1, 0x51, 0x48, 0x90, 0xe2, 0xa5, 0x3b, + 0xf9, 0xc7, 0x39, 0x39, 0x45, 0x2f, 0xbe, 0x07, 0x52, 0xa2, 0x68, 0xe9, 0x4e, 0xfa, 0x09, 0x4e, + 0xea, 0x93, 0x10, 0x72, 0x51, 0xb0, 0x74, 0x27, 0xff, 0xf3, 0x82, 0x5c, 0x90, 0x10, 0xf2, 0xde, + 0x4d, 0xf8, 0xb5, 0xbf, 0x90, 0xe0, 0x8b, 0x8e, 0xb0, 0xdd, 0x79, 0x18, 0xe4, 0x95, 0x4a, 0x77, + 0xea, 0x4f, 0xf2, 0xc1, 0x05, 0x45, 0xf1, 0x31, 0x48, 0xf6, 0x68, 0xf0, 0x9f, 0xe4, 0xa4, 0x0c, + 0xbf, 0x38, 0x07, 0x99, 0x50, 0x75, 0xd2, 0x9d, 0xfc, 0x2f, 0x71, 0xf2, 0x30, 0x15, 0x11, 0x9d, + 0x57, 0x27, 0xdd, 0x19, 0x7c, 0x4a, 0x88, 0xce, 0x29, 0x88, 0xd9, 0x44, 0x61, 0xd2, 0x9d, 0xfa, + 0xd3, 0xc2, 0xea, 0x82, 0xa4, 0xf8, 0x04, 0xa4, 0xfd, 0xc5, 0xa6, 0x3b, 0xfd, 0x4f, 0x71, 0xfa, + 0x80, 0x86, 0x58, 0x20, 0xb4, 0xd8, 0x75, 0x67, 0xf1, 0xd3, 0xc2, 0x02, 0x21, 0x2a, 0x12, 0x46, + 0xcd, 0x05, 0x4c, 0x77, 0x4e, 0x3f, 0x23, 0xc2, 0xa8, 0xa9, 0x7e, 0x21, 0xb3, 0x49, 0x73, 0x7e, + 0x77, 0x16, 0x3f, 0x2b, 0x66, 0x93, 0xe2, 0x13, 0x31, 0x9a, 0x2b, 0x82, 0xee, 0x3c, 0xfe, 0x8a, + 0x10, 0xa3, 0xa9, 0x20, 0x28, 0xae, 0x01, 0x6a, 0xad, 0x06, 0xba, 0xf3, 0x7b, 0x81, 0xf3, 0x1b, + 0x6b, 0x29, 0x06, 0x8a, 0x4f, 0xc1, 0x64, 0xfb, 0x4a, 0xa0, 0x3b, 0xd7, 0xcf, 0xbc, 0xd6, 0xb4, + 0x77, 0x0b, 0x17, 0x02, 0xc5, 0x8d, 0x60, 0x49, 0x09, 0x57, 0x01, 0xdd, 0xd9, 0x7e, 0xf6, 0xb5, + 0x68, 0xe2, 0x0e, 0x17, 0x01, 0xc5, 0x59, 0x80, 0x60, 0x01, 0xee, 0xce, 0xeb, 0x73, 0x9c, 0x57, + 0x88, 0x88, 0x84, 0x06, 0x5f, 0x7f, 0xbb, 0xd3, 0xbf, 0x28, 0x42, 0x83, 0x53, 0x90, 0xd0, 0x10, + 0x4b, 0x6f, 0x77, 0xea, 0xcf, 0x8b, 0xd0, 0x10, 0x24, 0xc4, 0xb3, 0x43, 0xab, 0x5b, 0x77, 0x0e, + 0x5f, 0x10, 0x9e, 0x1d, 0xa2, 0x2a, 0xae, 0xc0, 0x58, 0xcb, 0x82, 0xd8, 0x9d, 0xd5, 0x17, 0x39, + 0xab, 0x6c, 0xf3, 0x7a, 0x18, 0x5e, 0xbc, 0xf8, 0x62, 0xd8, 0x9d, 0xdb, 0x97, 0x9a, 0x16, 0x2f, + 0xbe, 0x16, 0x16, 0xcf, 0x43, 0xca, 0x6c, 0x18, 0x06, 0x09, 0x1e, 0xb4, 0xff, 0x9d, 0xbf, 0xdc, + 0x1f, 0xbe, 0xce, 0xad, 0x23, 0x08, 0x8a, 0x8f, 0x42, 0x12, 0xd7, 0xb7, 0x70, 0xb5, 0x1b, 0xe5, + 0xf7, 0x5e, 0x17, 0x09, 0x93, 0x60, 0x17, 0x9f, 0x00, 0x60, 0x47, 0x23, 0xf4, 0xf1, 0x60, 0x17, + 0xda, 0xff, 0xfa, 0x3a, 0xbf, 0x8d, 0x13, 0x90, 0x04, 0x0c, 0xd8, 0xdd, 0x9e, 0xfd, 0x19, 0x7c, + 0x3f, 0xca, 0x80, 0xce, 0xc8, 0xe3, 0x30, 0xf8, 0x8c, 0x6b, 0x99, 0x9e, 0x5a, 0xeb, 0x46, 0xfd, + 0xdf, 0x38, 0xb5, 0xc0, 0x27, 0x06, 0xab, 0x5b, 0x0e, 0xf6, 0xd4, 0x9a, 0xdb, 0x8d, 0xf6, 0xbf, + 0x73, 0x5a, 0x9f, 0x80, 0x10, 0x6b, 0xaa, 0xeb, 0xf5, 0xa2, 0xf7, 0x1f, 0x09, 0x62, 0x41, 0x40, + 0x84, 0x26, 0xbf, 0xaf, 0xe2, 0xbd, 0x6e, 0xb4, 0x7f, 0x2c, 0x84, 0xe6, 0xf8, 0xc5, 0xf7, 0x40, + 0x9a, 0xfc, 0x64, 0x57, 0xec, 0xba, 0x10, 0xff, 0x0f, 0x4e, 0x1c, 0x50, 0x90, 0x91, 0x5d, 0xaf, + 0xea, 0xe9, 0xdd, 0x8d, 0x7d, 0x8b, 0xcf, 0xb4, 0xc0, 0x2f, 0xce, 0x42, 0xc6, 0xf5, 0xaa, 0xd5, + 0x06, 0xaf, 0x4f, 0xbb, 0x90, 0xff, 0xcf, 0xd7, 0xfd, 0x23, 0x0b, 0x9f, 0x86, 0xcc, 0xf6, 0xf5, + 0xab, 0x9e, 0x6d, 0xd1, 0x47, 0x20, 0xdd, 0x38, 0xbc, 0xc6, 0x39, 0x84, 0x48, 0x8a, 0x73, 0x30, + 0x44, 0x74, 0x71, 0xb0, 0x8d, 0xe9, 0xf3, 0xaa, 0x2e, 0x2c, 0xfe, 0x17, 0x37, 0x40, 0x84, 0xa8, + 0xf4, 0xa3, 0xdf, 0x78, 0x75, 0x4a, 0x7a, 0xf9, 0xd5, 0x29, 0xe9, 0x0f, 0x5e, 0x9d, 0x92, 0x3e, + 0xfd, 0xed, 0xa9, 0x43, 0x2f, 0x7f, 0x7b, 0xea, 0xd0, 0xef, 0x7d, 0x7b, 0xea, 0x50, 0xfb, 0x63, + 0x63, 0x58, 0xb0, 0x16, 0x2c, 0x76, 0x60, 0xfc, 0x01, 0x39, 0x72, 0x5c, 0x5c, 0xb3, 0x82, 0xd3, + 0x5a, 0x7f, 0x93, 0x03, 0x1f, 0x8b, 0xc3, 0x94, 0x66, 0xb9, 0x75, 0xcb, 0x9d, 0xd9, 0x52, 0x5d, + 0x3c, 0x73, 0xed, 0xe1, 0x2d, 0xec, 0xa9, 0x0f, 0xcf, 0x68, 0x96, 0x6e, 0xf2, 0x63, 0xdf, 0x71, + 0xd6, 0x5f, 0x20, 0xfd, 0x05, 0xde, 0x9f, 0x6f, 0x7b, 0x42, 0x2c, 0x2f, 0x40, 0x62, 0xce, 0xd2, + 0x4d, 0x34, 0x01, 0xc9, 0x2a, 0x36, 0xad, 0x3a, 0xbf, 0x01, 0xc6, 0x1a, 0xe8, 0x2e, 0x18, 0x50, + 0xeb, 0x56, 0xc3, 0xf4, 0xd8, 0x71, 0x79, 0x29, 0xf3, 0x8d, 0x9b, 0xd3, 0x87, 0x7e, 0xff, 0xe6, + 0x74, 0x7c, 0xd1, 0xf4, 0x14, 0xde, 0x55, 0x4c, 0x7c, 0xf7, 0xa5, 0x69, 0x49, 0xbe, 0x04, 0x83, + 0xf3, 0x58, 0x3b, 0x08, 0xaf, 0x79, 0xac, 0x35, 0xf1, 0xba, 0x0f, 0x52, 0x8b, 0xa6, 0xc7, 0xee, + 0xe8, 0x1d, 0x87, 0xb8, 0x6e, 0xb2, 0x5b, 0x1f, 0x4d, 0xe3, 0x13, 0x38, 0x41, 0x9d, 0xc7, 0x9a, + 0x8f, 0x5a, 0xc5, 0x5a, 0x33, 0x2a, 0x61, 0x4f, 0xe0, 0xa5, 0xf9, 0xdf, 0xfb, 0x4f, 0x53, 0x87, + 0x9e, 0x7b, 0x75, 0xea, 0x50, 0xa7, 0xf9, 0x89, 0x98, 0x9f, 0x9b, 0x98, 0xfd, 0x79, 0xd0, 0xad, + 0x5e, 0x9d, 0x21, 0xa1, 0xe5, 0x6e, 0x0d, 0x50, 0xbb, 0x3d, 0x02, 0x9f, 0x8e, 0xc1, 0x74, 0xf3, + 0x91, 0x3a, 0xf1, 0x63, 0xd7, 0x53, 0xeb, 0x76, 0xa7, 0x17, 0xa2, 0xce, 0x43, 0x7a, 0x43, 0xe0, + 0xa0, 0x1c, 0x0c, 0xba, 0x58, 0xb3, 0xcc, 0xaa, 0x4b, 0x45, 0x8e, 0x2b, 0xa2, 0x49, 0x0c, 0x68, + 0xaa, 0xa6, 0xe5, 0xf2, 0xfb, 0x9a, 0xac, 0x51, 0xfa, 0xcb, 0x52, 0x7f, 0x8e, 0x35, 0xe2, 0x0f, + 0x45, 0xcd, 0xb3, 0x26, 0x7d, 0xe0, 0xfe, 0xfd, 0x9e, 0x46, 0x50, 0xf5, 0x02, 0x15, 0x42, 0x8f, + 0x1e, 0xa6, 0x9a, 0x1f, 0x3d, 0x3c, 0x85, 0x0d, 0xe3, 0xb2, 0x69, 0x5d, 0x37, 0x37, 0x22, 0x26, + 0xf9, 0x5d, 0x09, 0x4e, 0xd0, 0x8b, 0xe8, 0x4e, 0x5d, 0x37, 0xbd, 0x19, 0x43, 0xdf, 0x72, 0x67, + 0xb6, 0x74, 0xcf, 0x65, 0x96, 0xe3, 0x36, 0x99, 0x08, 0x30, 0x0a, 0x04, 0xa3, 0x40, 0x30, 0xe4, + 0x33, 0x90, 0x2a, 0xe9, 0xde, 0xac, 0xe3, 0xa8, 0x7b, 0x08, 0x41, 0x82, 0xc0, 0xb8, 0x51, 0xe8, + 0x6f, 0x62, 0x11, 0x6c, 0xe0, 0xba, 0x4b, 0x1f, 0x7a, 0x25, 0x14, 0xd6, 0x28, 0x6d, 0x76, 0x9c, + 0xc9, 0xf3, 0x21, 0x4d, 0x43, 0x22, 0x85, 0x7e, 0xb2, 0x48, 0x68, 0x27, 0xae, 0xaf, 0xcf, 0x57, + 0x12, 0x70, 0x3c, 0x84, 0xa0, 0x39, 0x7b, 0xb6, 0x47, 0x43, 0xd2, 0xda, 0xe6, 0xca, 0x8c, 0x85, + 0x94, 0x61, 0xdd, 0x1d, 0xc2, 0x6c, 0x1b, 0x92, 0x6b, 0x84, 0x8e, 0x28, 0xe2, 0x59, 0x9e, 0x6a, + 0x70, 0xed, 0x58, 0x83, 0x40, 0xd9, 0x65, 0xfc, 0x18, 0x83, 0xea, 0xe2, 0x1e, 0xbe, 0x81, 0xd5, + 0x6d, 0x76, 0xf9, 0x31, 0x4e, 0x9f, 0x7d, 0xa6, 0x08, 0x80, 0xde, 0x73, 0x9c, 0x80, 0xa4, 0xda, + 0x60, 0x8f, 0xed, 0xe2, 0x27, 0x87, 0x14, 0xd6, 0x90, 0x2f, 0xc3, 0x20, 0x7f, 0x54, 0x80, 0xb2, + 0x10, 0xbf, 0x8a, 0xf7, 0xe8, 0x38, 0x43, 0x0a, 0xf9, 0x89, 0x0a, 0x90, 0xa4, 0xc2, 0xf3, 0x5b, + 0xdd, 0xb9, 0x42, 0x8b, 0xf4, 0x05, 0x2a, 0xa4, 0xc2, 0xd0, 0xe4, 0x4b, 0x90, 0x9a, 0xb7, 0xea, + 0xba, 0x69, 0x45, 0xb9, 0xa5, 0x19, 0x37, 0x2a, 0xb3, 0xdd, 0xe0, 0xe1, 0xac, 0xb0, 0x06, 0x9a, + 0x84, 0x01, 0x76, 0x19, 0x96, 0x3f, 0x7a, 0xe4, 0x2d, 0x79, 0x0e, 0x06, 0x29, 0xef, 0x55, 0x9b, + 0xcc, 0xaf, 0x7f, 0x11, 0x29, 0xcd, 0xdf, 0x78, 0xe0, 0xec, 0x63, 0x81, 0xb0, 0x08, 0x12, 0x55, + 0xd5, 0x53, 0xb9, 0xde, 0xf4, 0xb7, 0xfc, 0x5e, 0x48, 0x71, 0x26, 0x2e, 0x3a, 0x0d, 0x71, 0xcb, + 0x76, 0xf9, 0xc3, 0xc3, 0x7c, 0x27, 0x55, 0x56, 0xed, 0x52, 0x82, 0x24, 0x02, 0x85, 0x20, 0x97, + 0x94, 0x8e, 0xfe, 0x72, 0xae, 0x7f, 0x7f, 0x61, 0xc3, 0xf8, 0xce, 0xf2, 0x85, 0x18, 0x4c, 0x85, + 0x7a, 0xaf, 0x61, 0x87, 0xd4, 0xcb, 0x11, 0xd7, 0x47, 0x21, 0x21, 0x79, 0x7f, 0x07, 0x77, 0x79, + 0x0f, 0xc4, 0x67, 0x6d, 0x1b, 0xe5, 0x21, 0xc5, 0x1e, 0x12, 0x5a, 0xcc, 0x5f, 0x12, 0x8a, 0xdf, + 0x26, 0x7d, 0xae, 0xb5, 0xed, 0x5d, 0x57, 0x1d, 0xff, 0x35, 0x10, 0xd1, 0x96, 0x1f, 0x87, 0xf4, + 0x9c, 0x65, 0xba, 0xd8, 0x74, 0x1b, 0x34, 0x74, 0xb6, 0x0c, 0x4b, 0xbb, 0xca, 0x39, 0xb0, 0x06, + 0x31, 0xb8, 0x6a, 0xdb, 0x94, 0x32, 0xa1, 0x90, 0x9f, 0x2c, 0xf5, 0x96, 0xd6, 0x3b, 0x9a, 0xe8, + 0xf1, 0xfe, 0x4d, 0xc4, 0x95, 0xf4, 0x6d, 0xf4, 0xeb, 0x47, 0xe0, 0x58, 0x98, 0x94, 0x65, 0x9c, + 0x90, 0x85, 0xb2, 0x21, 0x0b, 0x51, 0x78, 0x7b, 0xfb, 0xe4, 0xbb, 0x65, 0xde, 0x7c, 0xd7, 0x3c, + 0x94, 0xdf, 0x3f, 0xb2, 0xf3, 0x5d, 0xe6, 0x52, 0x7e, 0x1c, 0x86, 0xd7, 0x54, 0xc7, 0x5b, 0xc7, + 0xde, 0x45, 0xac, 0x56, 0xb1, 0x13, 0x0d, 0xec, 0x61, 0x11, 0xd8, 0x08, 0x12, 0x34, 0x7a, 0x99, + 0x63, 0xd3, 0xdf, 0xf2, 0x0e, 0x24, 0xe8, 0x45, 0x03, 0x3f, 0xe8, 0x39, 0x05, 0x0b, 0x7a, 0x32, + 0x5d, 0x7b, 0x1e, 0x76, 0x39, 0x09, 0x6b, 0xa0, 0x33, 0x22, 0x74, 0xe3, 0xfb, 0x87, 0x2e, 0xf7, + 0x76, 0x1e, 0xc0, 0x06, 0x0c, 0x96, 0xc8, 0x6c, 0x2f, 0xce, 0xfb, 0x82, 0x48, 0x81, 0x20, 0x68, + 0x19, 0x46, 0x6d, 0xd5, 0xf1, 0xe8, 0x0d, 0xcb, 0x1d, 0xaa, 0x05, 0xcf, 0x0c, 0xd3, 0x85, 0xe6, + 0x79, 0x28, 0x44, 0x94, 0xe5, 0xa3, 0x0c, 0xdb, 0x61, 0xa0, 0xfc, 0x9f, 0x13, 0x30, 0xc0, 0x8d, + 0xf1, 0x1e, 0x18, 0xe4, 0x46, 0xa3, 0x03, 0x66, 0x4e, 0x1f, 0x2f, 0xb4, 0xfa, 0x7e, 0xc1, 0xf7, + 0x51, 0xce, 0x4f, 0xd0, 0xa0, 0x7b, 0x20, 0xa5, 0xed, 0xa8, 0xba, 0x59, 0xd1, 0xab, 0xa2, 0x58, + 0x78, 0xf5, 0xe6, 0xf4, 0xe0, 0x1c, 0x81, 0x2d, 0xce, 0x2b, 0x83, 0xb4, 0x73, 0xb1, 0x4a, 0x92, + 0xcd, 0x0e, 0xd6, 0x6b, 0x3b, 0x2c, 0xd9, 0xc4, 0x15, 0xde, 0x42, 0xe7, 0x20, 0x41, 0x1c, 0x82, + 0x5f, 0xc0, 0xcf, 0xb7, 0x14, 0x71, 0xfe, 0xc2, 0x58, 0x4a, 0x91, 0x81, 0x3f, 0xfd, 0xad, 0x69, + 0x49, 0xa1, 0x14, 0x68, 0x0e, 0x86, 0x0d, 0xd5, 0xf5, 0x2a, 0x34, 0x48, 0xc8, 0xf0, 0x49, 0xca, + 0xe2, 0x48, 0xab, 0x41, 0xb8, 0x61, 0xb9, 0xe8, 0x19, 0x42, 0xc5, 0x40, 0x55, 0x74, 0x12, 0xb2, + 0x94, 0x89, 0x66, 0xd5, 0xeb, 0xba, 0xc7, 0xd2, 0xf7, 0x00, 0xb5, 0xfb, 0x08, 0x81, 0xcf, 0x51, + 0x30, 0x4d, 0xe2, 0x47, 0x21, 0x4d, 0x6f, 0xfc, 0x52, 0x14, 0x76, 0xbb, 0x25, 0x45, 0x00, 0xb4, + 0xf3, 0x5e, 0x18, 0xbd, 0xa6, 0x1a, 0x7a, 0x55, 0xf5, 0x2c, 0xc7, 0x65, 0x28, 0x29, 0xc6, 0x25, + 0x00, 0x53, 0xc4, 0x87, 0x60, 0xc2, 0xc4, 0xbb, 0xf4, 0xbe, 0x4d, 0x04, 0x3b, 0x4d, 0xb1, 0x11, + 0xe9, 0xbb, 0x12, 0xa5, 0x78, 0x17, 0x8c, 0x68, 0xc2, 0xf8, 0x0c, 0x17, 0x28, 0xee, 0xb0, 0x0f, + 0xa5, 0x68, 0x47, 0x20, 0xa5, 0xda, 0x36, 0x43, 0xc8, 0x50, 0x84, 0x41, 0xd5, 0xb6, 0x69, 0xd7, + 0x29, 0x18, 0xa3, 0x3a, 0x3a, 0xd8, 0x6d, 0x18, 0x1e, 0x67, 0x32, 0x44, 0x71, 0x46, 0x49, 0x87, + 0xc2, 0xe0, 0x14, 0xf7, 0x2e, 0x18, 0xc6, 0xd7, 0xf4, 0x2a, 0x36, 0x35, 0xcc, 0xf0, 0x86, 0x29, + 0xde, 0x90, 0x00, 0x52, 0xa4, 0xfb, 0x20, 0x6b, 0x3b, 0x96, 0x6d, 0xb9, 0xd8, 0xa9, 0xa8, 0xd5, + 0xaa, 0x83, 0x5d, 0x37, 0x37, 0xc2, 0xf8, 0x09, 0xf8, 0x2c, 0x03, 0xcb, 0x0f, 0x40, 0x62, 0x5e, + 0xf5, 0x54, 0x92, 0xc3, 0xbc, 0x5d, 0xb6, 0x04, 0x0c, 0x29, 0xe4, 0x67, 0xdb, 0x70, 0xfb, 0x6e, + 0x0c, 0x12, 0x57, 0x2c, 0x0f, 0xa3, 0x47, 0x42, 0xeb, 0xce, 0x48, 0x3b, 0x1f, 0x5f, 0xd7, 0x6b, + 0x26, 0xae, 0x2e, 0xbb, 0xb5, 0xd0, 0xab, 0x78, 0x81, 0x8b, 0xc5, 0x22, 0x2e, 0x36, 0x01, 0x49, + 0xc7, 0x6a, 0x98, 0x55, 0x71, 0x59, 0x84, 0x36, 0x50, 0x19, 0x52, 0xbe, 0xe7, 0x24, 0xba, 0x79, + 0xce, 0x28, 0xf1, 0x1c, 0xe2, 0xd7, 0x1c, 0xa0, 0x0c, 0x6e, 0x71, 0x07, 0x2a, 0x41, 0xda, 0x4f, + 0x68, 0xdc, 0x03, 0x7b, 0x73, 0xe2, 0x80, 0x0c, 0xdd, 0x0f, 0x63, 0xbe, 0x3f, 0xf8, 0x06, 0x65, + 0x5e, 0x98, 0xf5, 0x3b, 0xb8, 0x45, 0x23, 0xae, 0xc6, 0x5f, 0x0b, 0x1c, 0xa4, 0x7a, 0x05, 0xae, + 0xc6, 0x5e, 0x0d, 0x3c, 0x06, 0x69, 0x57, 0xaf, 0x99, 0xaa, 0xd7, 0x70, 0x30, 0xf7, 0xc6, 0x00, + 0x20, 0xff, 0x54, 0x0c, 0x06, 0x98, 0x77, 0x87, 0xec, 0x26, 0xb5, 0xb7, 0x5b, 0xac, 0x93, 0xdd, + 0xe2, 0x07, 0xb7, 0xdb, 0x2c, 0x80, 0x2f, 0x8c, 0xcb, 0x5f, 0xeb, 0x3a, 0xda, 0xca, 0x88, 0x89, + 0xb8, 0xae, 0xd7, 0x78, 0xf0, 0x86, 0x88, 0x7c, 0x0f, 0x4a, 0x86, 0xf2, 0xe4, 0x79, 0x48, 0x6f, + 0xe9, 0x5e, 0x45, 0x25, 0xd5, 0x29, 0x35, 0x61, 0xe6, 0xf4, 0x54, 0xa1, 0x5d, 0x19, 0x5b, 0x10, + 0x35, 0xac, 0x92, 0xda, 0xe2, 0xbf, 0xe4, 0xff, 0x28, 0x91, 0xc5, 0x98, 0x0f, 0x88, 0x66, 0x61, + 0x58, 0x28, 0x5a, 0xd9, 0x36, 0xd4, 0x1a, 0x77, 0xc6, 0xe3, 0x1d, 0xb5, 0xbd, 0x60, 0xa8, 0x35, + 0x25, 0xc3, 0x15, 0x24, 0x8d, 0xf6, 0x13, 0x1b, 0xeb, 0x30, 0xb1, 0x11, 0x4f, 0x8a, 0x1f, 0xcc, + 0x93, 0x22, 0x73, 0x9e, 0x68, 0x9e, 0xf3, 0xaf, 0xc6, 0x68, 0x51, 0x66, 0x5b, 0xae, 0x6a, 0xbc, + 0x15, 0x21, 0x76, 0x14, 0xd2, 0xb6, 0x65, 0x54, 0x58, 0x0f, 0xbb, 0x95, 0x95, 0xb2, 0x2d, 0x43, + 0x69, 0xf1, 0xa3, 0xe4, 0x6d, 0x8a, 0xbf, 0x81, 0xdb, 0x60, 0xb5, 0xc1, 0x66, 0xab, 0x39, 0x30, + 0xc4, 0x4c, 0xc1, 0x17, 0xcc, 0x87, 0x88, 0x0d, 0xe8, 0x0a, 0x2c, 0xb5, 0x2e, 0xf0, 0x4c, 0x6c, + 0x86, 0xa9, 0x70, 0x3c, 0x42, 0xc1, 0xd6, 0x97, 0x76, 0xd5, 0x7c, 0xd8, 0xcf, 0x15, 0x8e, 0x27, + 0xff, 0x53, 0x09, 0xd2, 0x54, 0xd5, 0x65, 0xec, 0xa9, 0x11, 0x53, 0x49, 0x07, 0x37, 0xd5, 0x71, + 0x00, 0xc6, 0xc6, 0xd5, 0x6f, 0x60, 0x3e, 0x81, 0x69, 0x0a, 0x59, 0xd7, 0x6f, 0x60, 0x74, 0xd6, + 0xd7, 0x2b, 0xbe, 0xbf, 0x5e, 0x3c, 0x14, 0x85, 0x76, 0x77, 0xc0, 0x20, 0xfd, 0x2a, 0xc1, 0x2e, + 0xbb, 0x96, 0x18, 0xa7, 0xef, 0x2c, 0x6e, 0xec, 0xba, 0xf2, 0x33, 0x30, 0xb8, 0xb1, 0xcb, 0xb6, + 0x52, 0x47, 0x21, 0xed, 0x58, 0x16, 0x5f, 0x5f, 0x59, 0x5d, 0x93, 0x22, 0x00, 0xba, 0x9c, 0x88, + 0xed, 0x43, 0x2c, 0xd8, 0x3e, 0x04, 0xfb, 0x9f, 0x78, 0x4f, 0xfb, 0x9f, 0x53, 0xff, 0x4e, 0x82, + 0x4c, 0x28, 0x0c, 0xd1, 0xc3, 0x70, 0xb8, 0xb4, 0xb4, 0x3a, 0x77, 0xb9, 0xb2, 0x38, 0x5f, 0xb9, + 0xb0, 0x34, 0xbb, 0x10, 0x5c, 0xef, 0xcd, 0x4f, 0x3e, 0xff, 0xe2, 0x09, 0x14, 0xc2, 0xdd, 0x34, + 0xaf, 0x92, 0xfd, 0x31, 0x9a, 0x81, 0x89, 0x28, 0xc9, 0x6c, 0x69, 0xbd, 0xbc, 0xb2, 0x91, 0x95, + 0xf2, 0x87, 0x9f, 0x7f, 0xf1, 0xc4, 0x58, 0x88, 0x62, 0x76, 0xcb, 0xc5, 0xa6, 0xd7, 0x4a, 0x30, + 0xb7, 0xba, 0xbc, 0xbc, 0xb8, 0x91, 0x8d, 0xb5, 0x10, 0xf0, 0x44, 0x7b, 0x1f, 0x8c, 0x45, 0x09, + 0x56, 0x16, 0x97, 0xb2, 0xf1, 0x3c, 0x7a, 0xfe, 0xc5, 0x13, 0x23, 0x21, 0xec, 0x15, 0xdd, 0xc8, + 0xa7, 0x7e, 0xe2, 0x4b, 0x53, 0x87, 0x7e, 0xfe, 0xaf, 0x4d, 0x49, 0x44, 0xb3, 0xe1, 0x48, 0x28, + 0xa2, 0x07, 0xe0, 0x8e, 0xf5, 0xc5, 0x85, 0x95, 0xf2, 0x7c, 0x65, 0x79, 0x7d, 0xa1, 0xc2, 0xde, + 0x6b, 0xf6, 0xb5, 0x1b, 0x7d, 0xfe, 0xc5, 0x13, 0x19, 0xae, 0x52, 0x27, 0xec, 0x35, 0xa5, 0x7c, + 0x65, 0x75, 0xa3, 0x9c, 0x95, 0x18, 0xf6, 0x9a, 0x83, 0xaf, 0x59, 0x1e, 0xfb, 0x6c, 0xc9, 0x43, + 0x70, 0xa4, 0x0d, 0xb6, 0xaf, 0xd8, 0xd8, 0xf3, 0x2f, 0x9e, 0x18, 0x5e, 0x73, 0x30, 0x73, 0x53, + 0x4a, 0x51, 0x80, 0x5c, 0x2b, 0xc5, 0xea, 0xda, 0xea, 0xfa, 0xec, 0x52, 0xf6, 0x44, 0x3e, 0xfb, + 0xfc, 0x8b, 0x27, 0x86, 0x44, 0xce, 0x21, 0xf8, 0x81, 0x66, 0xa5, 0x27, 0x3b, 0xee, 0x5f, 0x1e, + 0xeb, 0x7f, 0xff, 0x12, 0x3d, 0xf1, 0xf9, 0x8b, 0x31, 0x98, 0x6a, 0xb9, 0x44, 0xc9, 0x8f, 0x1e, + 0x3b, 0x1d, 0xf8, 0x14, 0x21, 0x35, 0x2f, 0x4e, 0x34, 0xfb, 0x3d, 0xef, 0xf9, 0xd9, 0x3e, 0xcf, + 0x7b, 0x86, 0xc5, 0x48, 0xe2, 0xb8, 0xe7, 0x54, 0xf7, 0xe3, 0x1e, 0x21, 0xff, 0x01, 0x4e, 0x7b, + 0x3e, 0xfe, 0x30, 0xdc, 0xcd, 0x0f, 0xc9, 0x5c, 0x4f, 0xbd, 0xaa, 0x9b, 0x35, 0xff, 0x28, 0x92, + 0xb7, 0xb9, 0x51, 0x26, 0xf9, 0x69, 0xa4, 0x80, 0xee, 0x7b, 0x20, 0x99, 0xdf, 0x77, 0x83, 0xd8, + 0x7d, 0xe3, 0xd7, 0x65, 0x86, 0xf2, 0x5d, 0x8e, 0x4e, 0xe5, 0x4f, 0x4a, 0x30, 0x72, 0x51, 0x77, + 0x3d, 0xcb, 0xd1, 0x35, 0xd5, 0xa0, 0xb7, 0x95, 0xcf, 0xf6, 0x9a, 0x9b, 0x9b, 0x72, 0xd8, 0x13, + 0x30, 0x70, 0x4d, 0x35, 0x5c, 0xec, 0xf1, 0xcb, 0xfa, 0x77, 0x16, 0xda, 0x1b, 0xa2, 0xe0, 0x17, + 0xe7, 0x82, 0x01, 0x23, 0x93, 0x7f, 0x31, 0x06, 0xa3, 0x34, 0xca, 0x5d, 0xf6, 0x39, 0x0d, 0xb2, + 0x11, 0x2c, 0x41, 0xc2, 0x51, 0x3d, 0x7e, 0x78, 0x52, 0x2a, 0xf0, 0x43, 0xce, 0x7b, 0xba, 0x1f, + 0x5c, 0x16, 0xe6, 0xb1, 0xa6, 0x50, 0x5a, 0xf4, 0x23, 0x90, 0xaa, 0xab, 0xbb, 0x15, 0xca, 0x87, + 0x6d, 0xaf, 0x66, 0xfb, 0xe3, 0x73, 0xeb, 0xe6, 0xf4, 0xe8, 0x9e, 0x5a, 0x37, 0x8a, 0xb2, 0xe0, + 0x23, 0x2b, 0x83, 0x75, 0x75, 0x97, 0x88, 0x88, 0x6c, 0x18, 0x25, 0x50, 0x6d, 0x47, 0x35, 0x6b, + 0x98, 0x0d, 0x42, 0x8f, 0x82, 0x4a, 0x17, 0xfb, 0x1e, 0x64, 0x32, 0x18, 0x24, 0xc4, 0x4e, 0x56, + 0x86, 0xeb, 0xea, 0xee, 0x1c, 0x05, 0x90, 0x11, 0x8b, 0xa9, 0x17, 0x5e, 0x9a, 0x3e, 0x44, 0x0f, + 0x8e, 0x5f, 0x91, 0x00, 0x02, 0x8b, 0xa1, 0x1f, 0x81, 0xac, 0xe6, 0xb7, 0x28, 0xad, 0xcb, 0xe7, + 0xf0, 0xde, 0x4e, 0x73, 0xd1, 0x64, 0x6f, 0xb6, 0xb6, 0xbf, 0x7c, 0x73, 0x5a, 0x52, 0x46, 0xb5, + 0xa6, 0xa9, 0xf8, 0x20, 0x64, 0x1a, 0x76, 0x55, 0xf5, 0x70, 0x85, 0x6e, 0x36, 0x63, 0x5d, 0xeb, + 0x84, 0x29, 0xc2, 0xeb, 0xd6, 0xcd, 0x69, 0xc4, 0xd4, 0x0a, 0x11, 0xcb, 0xb4, 0x7a, 0x00, 0x06, + 0x21, 0x04, 0x21, 0x9d, 0x7e, 0x47, 0x82, 0xcc, 0x7c, 0xe8, 0xd6, 0x40, 0x0e, 0x06, 0xeb, 0x96, + 0xa9, 0x5f, 0xe5, 0xfe, 0x98, 0x56, 0x44, 0x13, 0xe5, 0x21, 0xc5, 0x5e, 0xe0, 0xf0, 0xf6, 0xc4, + 0x91, 0x90, 0x68, 0x13, 0xaa, 0xeb, 0x78, 0xcb, 0xd5, 0xc5, 0x6c, 0x28, 0xa2, 0x89, 0x2e, 0x40, + 0xd6, 0xc5, 0x5a, 0xc3, 0xd1, 0xbd, 0xbd, 0x8a, 0x66, 0x99, 0x9e, 0xaa, 0x79, 0xec, 0x55, 0x80, + 0xd2, 0xd1, 0x5b, 0x37, 0xa7, 0xef, 0x60, 0xb2, 0x36, 0x63, 0xc8, 0xca, 0xa8, 0x00, 0xcd, 0x31, + 0x08, 0x19, 0xa1, 0x8a, 0x3d, 0x55, 0x37, 0x5c, 0x5a, 0x7a, 0xa5, 0x15, 0xd1, 0x0c, 0xe9, 0xf2, + 0x8f, 0x07, 0x21, 0xed, 0x7b, 0x3b, 0xba, 0x0e, 0x59, 0xcb, 0xc6, 0x4e, 0xa4, 0x90, 0xa5, 0xeb, + 0x78, 0x69, 0x29, 0x18, 0xb9, 0x19, 0x43, 0xfe, 0xff, 0x37, 0xa7, 0x1f, 0xec, 0xc1, 0x83, 0xae, + 0xa8, 0x06, 0x2f, 0x82, 0x95, 0x51, 0xc1, 0x43, 0x54, 0xc5, 0x17, 0x88, 0x5f, 0x88, 0xed, 0xaf, + 0xdd, 0xd8, 0x12, 0x47, 0x8f, 0x11, 0x95, 0x9b, 0x31, 0x64, 0xe2, 0x01, 0x1c, 0xb4, 0x46, 0x21, + 0xa4, 0x72, 0x7d, 0x46, 0xd5, 0x0d, 0xf1, 0x56, 0x9b, 0xc2, 0x5b, 0x68, 0x11, 0x06, 0x5c, 0x4f, + 0xf5, 0x1a, 0xac, 0x78, 0x49, 0x96, 0x1e, 0xee, 0x51, 0xe6, 0x92, 0x65, 0x56, 0xd7, 0x29, 0xa1, + 0xc2, 0x19, 0xa0, 0x0b, 0x30, 0xe0, 0x59, 0x57, 0xb1, 0xc9, 0x8d, 0xda, 0x57, 0xc4, 0xd3, 0x87, + 0x34, 0x8c, 0x1a, 0x79, 0x90, 0xad, 0x62, 0x03, 0xd7, 0xa8, 0x29, 0xdd, 0x1d, 0x95, 0x6c, 0x90, + 0xe8, 0x97, 0x65, 0x4a, 0x8b, 0x7d, 0x87, 0x25, 0x37, 0x50, 0x33, 0x3f, 0x59, 0x19, 0xf5, 0x41, + 0xeb, 0x14, 0x82, 0x2e, 0x47, 0x2e, 0xbc, 0xf0, 0xcf, 0x2f, 0xdd, 0xd5, 0x29, 0xf6, 0x42, 0x5e, + 0x2e, 0x8e, 0x55, 0xc2, 0xd7, 0x65, 0x2e, 0x40, 0xb6, 0x61, 0x6e, 0x59, 0x26, 0x7d, 0x13, 0x85, + 0xef, 0x18, 0xc8, 0x16, 0x34, 0x1e, 0x9e, 0xb5, 0x66, 0x0c, 0x59, 0x19, 0xf5, 0x41, 0x17, 0xd9, + 0xbe, 0xa2, 0x0a, 0x23, 0x01, 0x16, 0x0d, 0xdd, 0x74, 0xd7, 0xd0, 0xbd, 0x93, 0x87, 0xee, 0xe1, + 0xe6, 0x51, 0x82, 0xe8, 0x1d, 0xf6, 0x81, 0x84, 0x0c, 0x5d, 0x04, 0x08, 0x12, 0x06, 0x3d, 0x5e, + 0xc9, 0x9c, 0x96, 0xbb, 0x67, 0x1d, 0xb1, 0x25, 0x0d, 0x68, 0xd1, 0x87, 0x61, 0xbc, 0xae, 0x9b, + 0x15, 0x17, 0x1b, 0xdb, 0x15, 0x6e, 0x60, 0xc2, 0x92, 0x7e, 0x49, 0xa0, 0xb4, 0xd4, 0x9f, 0x3f, + 0xdc, 0xba, 0x39, 0x9d, 0xe7, 0x49, 0xb5, 0x95, 0xa5, 0xac, 0x8c, 0xd5, 0x75, 0x73, 0x1d, 0x1b, + 0xdb, 0xf3, 0x3e, 0xac, 0x38, 0xf4, 0x13, 0x2f, 0x4d, 0x1f, 0xf2, 0x03, 0x58, 0x87, 0xa1, 0x20, + 0xb0, 0xb0, 0x8b, 0x56, 0x21, 0xad, 0x8a, 0x06, 0x3b, 0x88, 0xe9, 0xd9, 0xd9, 0x43, 0x01, 0x1a, + 0xf0, 0x60, 0xb9, 0xe2, 0xb9, 0xff, 0x70, 0x42, 0x92, 0x9f, 0x8f, 0xc1, 0xc0, 0xfc, 0x95, 0x35, + 0x55, 0x77, 0xd0, 0x0d, 0x18, 0x0b, 0x9c, 0x2d, 0x9a, 0x29, 0x96, 0x6f, 0xdd, 0x9c, 0xce, 0x35, + 0xfb, 0x63, 0x9f, 0xa9, 0x62, 0x56, 0xd3, 0x84, 0x24, 0x41, 0x90, 0x88, 0x5c, 0x71, 0xa3, 0xe3, + 0x76, 0x3b, 0x3c, 0x76, 0x0b, 0xca, 0x01, 0xd2, 0x54, 0xcb, 0xee, 0x3d, 0x94, 0x38, 0xcb, 0x30, + 0xc8, 0x6c, 0xe1, 0xa2, 0x22, 0x24, 0x6d, 0xf2, 0x83, 0x3f, 0xfa, 0x98, 0xea, 0x18, 0x4d, 0x14, + 0xdf, 0x3f, 0x10, 0x26, 0x24, 0xf2, 0x17, 0xe3, 0x00, 0xf3, 0x57, 0xae, 0x6c, 0x38, 0xba, 0x6d, + 0x60, 0xef, 0x07, 0x6a, 0xd7, 0x8f, 0x4b, 0x70, 0x38, 0xb0, 0x9a, 0xeb, 0x68, 0x4d, 0xc6, 0x7d, + 0xf2, 0xd6, 0xcd, 0xe9, 0x63, 0xcd, 0xc6, 0x0d, 0xa1, 0x1d, 0xc0, 0xc0, 0xe3, 0x3e, 0xa3, 0x75, + 0x47, 0x6b, 0x2f, 0x47, 0xd5, 0xf5, 0x7c, 0x39, 0xe2, 0x9d, 0xe5, 0x08, 0xa1, 0xbd, 0x21, 0x39, + 0xe6, 0x5d, 0xaf, 0x75, 0xae, 0xd7, 0x21, 0x13, 0xcc, 0x91, 0x8b, 0xe6, 0x21, 0xe5, 0xf1, 0xdf, + 0x7c, 0xca, 0xe5, 0xce, 0x53, 0x2e, 0xc8, 0xf8, 0xb4, 0xfb, 0x94, 0xf2, 0xbf, 0x8d, 0x01, 0x04, + 0x51, 0xfd, 0x67, 0x35, 0xa2, 0xc8, 0x72, 0xca, 0x17, 0xbf, 0xf8, 0x81, 0x0a, 0x68, 0x4e, 0x1d, + 0x9a, 0xad, 0x3f, 0x8c, 0xc1, 0xf8, 0xa6, 0xc8, 0xfc, 0xef, 0x58, 0x18, 0xad, 0xc1, 0x20, 0x36, + 0x3d, 0x47, 0xa7, 0x26, 0x26, 0xde, 0xfa, 0x50, 0x27, 0x6f, 0x6d, 0x63, 0x35, 0xfa, 0xb1, 0x0c, + 0xf1, 0x34, 0x88, 0xb3, 0x09, 0xd9, 0xfa, 0x53, 0x71, 0xc8, 0x75, 0xa2, 0x42, 0x73, 0x30, 0xaa, + 0x39, 0x98, 0x02, 0x2a, 0xe1, 0xa3, 0xe7, 0x52, 0x3e, 0xd8, 0x49, 0x34, 0x21, 0xc8, 0xca, 0x88, + 0x80, 0xf0, 0xda, 0xa0, 0x06, 0xa4, 0xcc, 0x27, 0x21, 0x43, 0xb0, 0x7a, 0xac, 0xeb, 0x65, 0x5e, + 0x1c, 0x88, 0x41, 0xa2, 0x0c, 0x58, 0x75, 0x30, 0x12, 0x40, 0x69, 0x79, 0xf0, 0x2c, 0x8c, 0xea, + 0xa6, 0xee, 0xe9, 0xaa, 0x51, 0xd9, 0x52, 0x0d, 0xd5, 0xd4, 0x0e, 0xb2, 0x4b, 0x62, 0x0b, 0x3a, + 0x1f, 0xb6, 0x89, 0x9d, 0xac, 0x8c, 0x70, 0x48, 0x89, 0x01, 0xd0, 0x45, 0x18, 0x14, 0x43, 0x25, + 0x0e, 0x54, 0x4b, 0x0a, 0xf2, 0xd0, 0x8c, 0xfc, 0x64, 0x1c, 0xc6, 0x14, 0x5c, 0x7d, 0x67, 0x2a, + 0xfa, 0x9b, 0x8a, 0x65, 0x00, 0x96, 0x48, 0xc8, 0x4a, 0x72, 0x80, 0xd9, 0x20, 0xa9, 0x28, 0xcd, + 0x38, 0xcc, 0xbb, 0x5e, 0x68, 0x3e, 0xfe, 0x28, 0x0e, 0x43, 0xe1, 0xf9, 0x78, 0x67, 0x89, 0xff, + 0xe1, 0x59, 0xe2, 0xd1, 0x62, 0x90, 0x1a, 0x13, 0xfc, 0xa3, 0x87, 0x1d, 0x52, 0x63, 0x4b, 0x48, + 0x75, 0xce, 0x89, 0xff, 0x3b, 0x06, 0x03, 0x6b, 0xaa, 0xa3, 0xd6, 0x5d, 0xa4, 0xb5, 0x6c, 0x6c, + 0xc4, 0xc1, 0x7e, 0xcb, 0xd7, 0x6a, 0xf9, 0xa1, 0x58, 0x97, 0x7d, 0xcd, 0x0b, 0x6d, 0xf6, 0x35, + 0xef, 0x83, 0x91, 0xba, 0xba, 0x1b, 0x7a, 0xd6, 0x4c, 0x27, 0x73, 0xb8, 0x74, 0x24, 0xe0, 0x12, + 0xed, 0x67, 0xc7, 0x35, 0xc1, 0x03, 0x68, 0xf4, 0x18, 0x64, 0x08, 0x46, 0xb0, 0x4a, 0x10, 0xf2, + 0xc9, 0xe0, 0x5c, 0x24, 0xd4, 0x29, 0x2b, 0x50, 0x57, 0x77, 0xcb, 0xac, 0x81, 0x96, 0x00, 0xed, + 0xf8, 0x47, 0x73, 0x95, 0xc0, 0x94, 0x84, 0xfe, 0xf8, 0xad, 0x9b, 0xd3, 0x47, 0x18, 0x7d, 0x2b, + 0x8e, 0xac, 0x8c, 0x05, 0x40, 0xc1, 0xed, 0x0c, 0x00, 0xd1, 0xab, 0xc2, 0xae, 0x2a, 0xb2, 0xdd, + 0xf5, 0xe1, 0x5b, 0x37, 0xa7, 0xc7, 0x18, 0x97, 0xa0, 0x4f, 0x56, 0xd2, 0xa4, 0x31, 0x4f, 0x7e, + 0x87, 0x0c, 0xff, 0x25, 0x09, 0x50, 0xb0, 0x06, 0x29, 0xd8, 0xb5, 0x2d, 0xd3, 0xa5, 0xfb, 0xbe, + 0xd0, 0x26, 0x4d, 0xda, 0x7f, 0xdf, 0x17, 0xd0, 0x8b, 0x7d, 0x5f, 0x28, 0x74, 0x1f, 0x0f, 0xf2, + 0x75, 0x8c, 0xcf, 0x63, 0x9b, 0x7b, 0x9d, 0x85, 0x39, 0x4b, 0x17, 0xd4, 0x6d, 0x12, 0xf4, 0xbf, + 0x90, 0xe0, 0x48, 0x8b, 0x37, 0xf9, 0xc2, 0xfe, 0x39, 0x40, 0x4e, 0xa8, 0x93, 0x7f, 0xbc, 0x8a, + 0x09, 0xdd, 0xb7, 0x73, 0x8e, 0x39, 0x2d, 0x0b, 0xc1, 0xed, 0x5b, 0x72, 0xd8, 0xc5, 0xd0, 0x7f, + 0x22, 0xc1, 0x44, 0x78, 0x78, 0x5f, 0x91, 0x15, 0x18, 0x0a, 0x8f, 0xce, 0x55, 0xb8, 0xbb, 0x17, + 0x15, 0xb8, 0xf4, 0x11, 0x7a, 0xf4, 0x64, 0x10, 0xaa, 0xec, 0xf0, 0xf6, 0xe1, 0x9e, 0xad, 0x21, + 0x64, 0x6a, 0x0e, 0x59, 0xa6, 0xc1, 0x9f, 0x48, 0x90, 0x58, 0xb3, 0x2c, 0x03, 0x59, 0x30, 0x66, + 0x5a, 0x5e, 0x85, 0x78, 0x16, 0xae, 0x56, 0xf8, 0x19, 0x0f, 0x3b, 0xd5, 0x9d, 0xeb, 0xcf, 0x48, + 0xdf, 0xbb, 0x39, 0xdd, 0xca, 0x4a, 0x19, 0x35, 0x2d, 0xaf, 0x44, 0x21, 0x1b, 0xec, 0x04, 0xe8, + 0xc3, 0x30, 0x1c, 0x1d, 0x8c, 0x9d, 0x78, 0x3d, 0xd5, 0xf7, 0x60, 0x51, 0x36, 0xb7, 0x6e, 0x4e, + 0x4f, 0x04, 0x11, 0xe3, 0x83, 0x65, 0x65, 0x68, 0x2b, 0x34, 0x7a, 0x31, 0x45, 0xb4, 0xff, 0xe3, + 0x97, 0xa6, 0xa5, 0xd2, 0x85, 0x8e, 0x4f, 0x68, 0x1e, 0xd8, 0x57, 0x84, 0x5d, 0xff, 0x31, 0x43, + 0xf4, 0xb1, 0xcc, 0x0b, 0xe3, 0x30, 0xdd, 0xe1, 0x39, 0x84, 0xb7, 0x7b, 0xa0, 0x47, 0x10, 0x5d, + 0x9e, 0x11, 0xe4, 0x7b, 0x7a, 0xec, 0x21, 0xbf, 0x9e, 0x00, 0xb4, 0xec, 0xd6, 0xe6, 0x48, 0x55, + 0x83, 0x83, 0x43, 0xcf, 0xa6, 0x23, 0x31, 0xe9, 0x0d, 0x1d, 0x89, 0x2d, 0x47, 0x0e, 0x99, 0x62, + 0xfd, 0x1d, 0x6d, 0xf7, 0x7c, 0xd2, 0x14, 0x7f, 0x4b, 0x4e, 0x9a, 0xda, 0x97, 0x2a, 0x89, 0x1f, + 0xe0, 0x8e, 0x29, 0xf9, 0xd6, 0xec, 0x98, 0x26, 0x61, 0x80, 0x9f, 0x41, 0xb3, 0x4f, 0x7d, 0xf3, + 0x16, 0x7a, 0x54, 0x7c, 0x21, 0x79, 0xb0, 0xb7, 0xec, 0xcf, 0xb0, 0x79, 0x9e, 0xf9, 0x5a, 0x1c, + 0xb2, 0xcb, 0x6e, 0xad, 0x5c, 0xd5, 0xbd, 0x37, 0xc9, 0xf7, 0xec, 0xce, 0x9b, 0xcc, 0xb9, 0x5b, + 0x37, 0xa7, 0x47, 0x98, 0xc9, 0x6e, 0xa7, 0xa1, 0xea, 0x30, 0xda, 0xf4, 0x38, 0x87, 0xbb, 0xe6, + 0xfc, 0x41, 0x9e, 0x2a, 0x35, 0xb1, 0x92, 0xe9, 0xbe, 0x20, 0x14, 0x20, 0x68, 0xb7, 0x7d, 0x34, + 0xb0, 0x85, 0xec, 0xe2, 0x9b, 0x79, 0xe6, 0xca, 0xa6, 0xf0, 0xeb, 0x31, 0xc8, 0x2c, 0xbb, 0x62, + 0x9f, 0x8b, 0xff, 0xcc, 0x9e, 0x28, 0x3c, 0xe6, 0xbf, 0x38, 0x12, 0xef, 0x2d, 0x10, 0xa2, 0x2f, + 0x93, 0x7c, 0x2b, 0x4e, 0xf3, 0x70, 0x09, 0xd7, 0x74, 0xd3, 0x5f, 0xac, 0xf1, 0x3b, 0x1b, 0xa3, + 0x1f, 0xa2, 0x8d, 0x51, 0x30, 0xc3, 0x89, 0x83, 0xcc, 0xf0, 0x6f, 0xc5, 0x60, 0x78, 0xd9, 0xad, + 0x6d, 0x9a, 0xd5, 0x77, 0x42, 0xe5, 0x8d, 0x84, 0xca, 0x6d, 0x2f, 0xcd, 0xbe, 0x1e, 0x83, 0x53, + 0xe1, 0x5a, 0xea, 0xd9, 0x06, 0x76, 0xf6, 0xfc, 0x72, 0xc9, 0x56, 0x6b, 0xba, 0x19, 0xbe, 0x3d, + 0x73, 0x24, 0x2c, 0x2c, 0xc5, 0x15, 0x22, 0xcb, 0x26, 0x64, 0xd6, 0xd4, 0x1a, 0x56, 0xf0, 0xb3, + 0x0d, 0xec, 0x7a, 0x6d, 0xde, 0x6d, 0x99, 0x84, 0x01, 0x6b, 0x7b, 0x9b, 0x5d, 0xb6, 0x90, 0x4e, + 0x26, 0x14, 0xde, 0x42, 0x13, 0x90, 0x34, 0xf4, 0xba, 0xce, 0x0c, 0x92, 0x50, 0x58, 0x03, 0x4d, + 0x43, 0x46, 0x23, 0x7a, 0x57, 0xd8, 0x95, 0xfd, 0x84, 0xf8, 0x76, 0x47, 0xc3, 0xf4, 0x36, 0x08, + 0x44, 0x7e, 0x02, 0x86, 0xd8, 0x78, 0x7c, 0x7f, 0x71, 0x04, 0x52, 0xf4, 0x8a, 0x75, 0x30, 0xea, + 0x20, 0x69, 0x5f, 0x66, 0xef, 0xc1, 0x30, 0x2e, 0x6c, 0x60, 0xd6, 0x28, 0x95, 0x3a, 0x9a, 0xf2, + 0x64, 0xf7, 0x49, 0x66, 0x86, 0xf2, 0xcd, 0xf8, 0x9b, 0x49, 0x38, 0xcc, 0xaf, 0xb5, 0xa8, 0xb6, + 0x3e, 0xb3, 0xe3, 0x79, 0xe2, 0x05, 0x33, 0xe0, 0x1b, 0x7b, 0xd5, 0xd6, 0xe5, 0x3d, 0x48, 0x5c, + 0xf4, 0x3c, 0x1b, 0x9d, 0x82, 0xa4, 0xd3, 0x30, 0xb0, 0x78, 0x58, 0x30, 0x51, 0x08, 0x70, 0x0a, + 0x04, 0x41, 0x69, 0x18, 0x58, 0x61, 0x28, 0xa8, 0x0c, 0xd3, 0xdb, 0x0d, 0xc3, 0xd8, 0xab, 0x54, + 0x31, 0xfd, 0x77, 0x4a, 0xfe, 0x7f, 0x2e, 0xc0, 0xbb, 0xb6, 0x6a, 0xfa, 0x45, 0x65, 0x4a, 0x39, + 0x46, 0xd1, 0xe6, 0x29, 0x96, 0xf8, 0xaf, 0x05, 0x65, 0x81, 0x23, 0xff, 0x7e, 0x0c, 0x52, 0x82, + 0x35, 0x7d, 0x31, 0x05, 0x1b, 0x58, 0xf3, 0x2c, 0x71, 0x41, 0xc1, 0x6f, 0x23, 0x04, 0xf1, 0x1a, + 0x9f, 0xa2, 0xf4, 0xc5, 0x43, 0x0a, 0x69, 0x10, 0x98, 0xff, 0xba, 0x10, 0x81, 0xd9, 0x0d, 0x32, + 0x6b, 0x09, 0xdb, 0x12, 0x27, 0x63, 0x17, 0x0f, 0x29, 0xb4, 0x85, 0x72, 0x30, 0x40, 0xa2, 0xcd, + 0x63, 0xdf, 0x94, 0x24, 0x70, 0xde, 0x46, 0x93, 0x90, 0xb4, 0x55, 0x4f, 0x63, 0xd7, 0xec, 0x49, + 0x07, 0x6b, 0x92, 0x78, 0x60, 0xef, 0xf2, 0x36, 0xff, 0xaf, 0x12, 0x62, 0x0c, 0xf6, 0xd1, 0x34, + 0x22, 0xf7, 0x9a, 0xea, 0x79, 0xd8, 0x31, 0x09, 0x43, 0x86, 0x4e, 0xdf, 0x41, 0xb3, 0xaa, 0x7b, + 0xfc, 0xff, 0xa7, 0xd0, 0xdf, 0xfc, 0x3f, 0x3b, 0x50, 0x7f, 0xa8, 0xd0, 0x4e, 0xf6, 0x6f, 0xa3, + 0x86, 0x04, 0xb0, 0x44, 0x90, 0xca, 0x30, 0xae, 0x56, 0xab, 0x3a, 0xf1, 0x6a, 0xd5, 0xa8, 0x6c, + 0xe9, 0xf4, 0xe0, 0xc4, 0xa5, 0xff, 0x14, 0xac, 0xd3, 0x5c, 0xa0, 0x80, 0xa0, 0xc4, 0xf1, 0x4b, + 0x69, 0x18, 0xb4, 0x99, 0x50, 0xf2, 0x79, 0x18, 0x6b, 0x91, 0x94, 0xc8, 0x77, 0x55, 0x37, 0xab, + 0xe2, 0x1d, 0x2a, 0xf2, 0x9b, 0xc0, 0xe8, 0x87, 0x0f, 0xd9, 0xd5, 0x0f, 0xfa, 0xbb, 0xf4, 0xe3, + 0x9d, 0xef, 0x90, 0x8d, 0x84, 0xee, 0x90, 0xa9, 0xb6, 0x5e, 0x4a, 0x53, 0xfe, 0xfc, 0xea, 0xd8, + 0x2c, 0xef, 0x60, 0xd7, 0xc6, 0x0a, 0x96, 0x53, 0x9b, 0xa9, 0x61, 0x53, 0xec, 0x94, 0x48, 0x97, + 0x6a, 0xeb, 0x2e, 0x75, 0xc7, 0xe0, 0x43, 0x8c, 0xee, 0xf9, 0xd0, 0x6f, 0x7a, 0xa3, 0x2c, 0xb1, + 0x30, 0xbb, 0xb6, 0xe8, 0xfb, 0xf1, 0x6f, 0xc4, 0xe0, 0x58, 0xc8, 0x8f, 0x43, 0xc8, 0xad, 0xee, + 0x9c, 0x6f, 0xef, 0xf1, 0x3d, 0x7c, 0xc6, 0xf0, 0x32, 0x24, 0x08, 0x3e, 0xea, 0xf2, 0x7f, 0x17, + 0x72, 0xbf, 0xf4, 0xcf, 0xff, 0x91, 0x4c, 0x9d, 0xa2, 0xfd, 0xac, 0x50, 0x26, 0xa5, 0x4f, 0xf4, + 0x6e, 0xbf, 0x6c, 0xf0, 0x0d, 0x4a, 0xf7, 0xf6, 0x99, 0xb1, 0xd9, 0x86, 0x9f, 0x3f, 0x0f, 0x72, + 0x87, 0xed, 0x27, 0xcb, 0x98, 0xfb, 0x6f, 0x78, 0xfb, 0x48, 0xc7, 0x9d, 0xee, 0xe7, 0xed, 0x37, + 0x83, 0x3d, 0x6e, 0x8d, 0x77, 0x61, 0xf2, 0x49, 0x32, 0x76, 0x70, 0x28, 0x28, 0x12, 0xfb, 0xa4, + 0x7f, 0x73, 0x46, 0xe2, 0xff, 0x93, 0x4d, 0x5c, 0x83, 0x81, 0x40, 0x3e, 0xbe, 0xd1, 0xbd, 0xa7, + 0xd0, 0x71, 0xbd, 0x28, 0x84, 0x16, 0x0b, 0x25, 0x44, 0x29, 0xff, 0x82, 0x04, 0x77, 0xb4, 0x0c, + 0xcd, 0x73, 0xfc, 0x02, 0x40, 0xe8, 0x54, 0x53, 0xea, 0xef, 0xce, 0x5e, 0x88, 0x94, 0x30, 0x6a, + 0x11, 0xf6, 0xde, 0xae, 0xc2, 0x32, 0x29, 0x22, 0xd2, 0x3e, 0x0b, 0x87, 0xa3, 0xc2, 0x0a, 0x33, + 0x3d, 0x0d, 0x23, 0xd1, 0x02, 0x82, 0x17, 0x37, 0x07, 0xb8, 0x7b, 0x31, 0x1c, 0x29, 0x22, 0xe4, + 0x4a, 0xf3, 0xd4, 0xf8, 0xe6, 0x29, 0x43, 0xda, 0x47, 0xe5, 0x5b, 0xc7, 0x9e, 0xad, 0x13, 0x50, + 0xca, 0x5f, 0x97, 0xe0, 0x44, 0x74, 0x84, 0x60, 0xe3, 0xe3, 0xbe, 0xe9, 0xfa, 0xdd, 0x36, 0x47, + 0xfa, 0xae, 0x04, 0x77, 0xee, 0xa3, 0x06, 0xb7, 0xd9, 0x0d, 0x98, 0x08, 0x9d, 0xae, 0x8a, 0x85, + 0x42, 0x38, 0xd7, 0xa9, 0xee, 0xc7, 0xc2, 0xfe, 0x61, 0xe2, 0x51, 0x62, 0xc7, 0xaf, 0x7c, 0x6b, + 0x7a, 0xbc, 0xb5, 0xcf, 0x55, 0xc6, 0x5b, 0x4f, 0x44, 0x6f, 0xa3, 0x17, 0xfe, 0xae, 0x04, 0xf7, + 0x45, 0x55, 0x6d, 0xf3, 0x0c, 0xf6, 0x6d, 0x34, 0x75, 0xff, 0x5e, 0x82, 0x53, 0xbd, 0xe8, 0xc3, + 0xe7, 0x70, 0x0b, 0xc6, 0x83, 0xc7, 0x22, 0xcd, 0x53, 0x78, 0x7f, 0x1f, 0x0f, 0xb7, 0x79, 0x2c, + 0x20, 0x9f, 0xdb, 0x9b, 0x30, 0x57, 0xff, 0x52, 0xe2, 0xf1, 0x1b, 0x76, 0x13, 0x7f, 0x62, 0xa2, + 0x1b, 0x9e, 0x3e, 0x27, 0x26, 0xb4, 0xe9, 0x19, 0x8e, 0x6c, 0x7a, 0xda, 0x4c, 0x79, 0xec, 0x36, + 0x65, 0xa3, 0x6b, 0x3c, 0x5b, 0xb7, 0x79, 0xce, 0xf2, 0x41, 0x18, 0x6f, 0x13, 0x5a, 0x3c, 0x31, + 0xf5, 0x11, 0x59, 0x0a, 0x6a, 0x0d, 0x1e, 0xf9, 0xdf, 0x48, 0x30, 0x4d, 0x07, 0x6e, 0x33, 0x8d, + 0x6f, 0x67, 0x7b, 0xd6, 0x79, 0xee, 0x6d, 0xab, 0x16, 0x37, 0xec, 0x22, 0x0c, 0x30, 0x0f, 0xe5, + 0xb6, 0x3c, 0x80, 0x8b, 0x73, 0x06, 0x41, 0xae, 0x9f, 0x17, 0xfa, 0xb5, 0x4f, 0x18, 0x6f, 0x92, + 0x1d, 0x6f, 0x57, 0xc2, 0x78, 0x45, 0xe4, 0xfa, 0xf6, 0x6a, 0x70, 0xbb, 0x69, 0xb7, 0x2d, 0xd7, + 0x33, 0x23, 0xbe, 0x45, 0x49, 0xdd, 0xd7, 0xa9, 0x4b, 0x52, 0xff, 0x21, 0x9f, 0x23, 0x3f, 0xa9, + 0x77, 0xd1, 0xe7, 0xed, 0x98, 0xd4, 0xff, 0x24, 0x06, 0x47, 0xa8, 0x6e, 0xe1, 0x67, 0x8d, 0x6f, + 0xc1, 0xdc, 0x54, 0x00, 0xb9, 0x8e, 0x56, 0xb9, 0x5d, 0xb9, 0x28, 0xeb, 0x3a, 0xda, 0x95, 0xc8, + 0x8a, 0x5e, 0x01, 0x54, 0x75, 0xbd, 0xe6, 0x01, 0xe2, 0x07, 0x1e, 0xa0, 0xea, 0x7a, 0x57, 0xf6, + 0x29, 0x19, 0x12, 0x07, 0xf6, 0xae, 0x97, 0x25, 0xc8, 0xb7, 0x9b, 0x01, 0xee, 0x4d, 0x3a, 0x4c, + 0x46, 0x1e, 0xa3, 0x37, 0x3b, 0xd4, 0x03, 0xbd, 0x3c, 0x3c, 0x6e, 0x0a, 0xff, 0xc3, 0x0e, 0x7e, + 0x53, 0x13, 0xc0, 0x3f, 0x13, 0x4b, 0x9c, 0x1f, 0x30, 0xad, 0xbb, 0xb1, 0x1f, 0xfe, 0xb0, 0xff, + 0x95, 0x96, 0x15, 0xe6, 0x6d, 0xb1, 0xb1, 0xfb, 0xa6, 0x04, 0x53, 0x1d, 0xc4, 0x7e, 0x3b, 0x97, + 0x17, 0x3b, 0x1d, 0x5d, 0xea, 0x76, 0xef, 0x22, 0xcf, 0xf0, 0x78, 0x8c, 0xbe, 0xaa, 0x17, 0x3a, + 0x45, 0x68, 0xf7, 0xf1, 0x01, 0xf9, 0xfd, 0x70, 0xb4, 0x2d, 0x15, 0x97, 0xad, 0x08, 0x89, 0x1d, + 0xdd, 0xf5, 0xb8, 0x58, 0xf7, 0x74, 0x12, 0xab, 0x89, 0x9a, 0xd2, 0xc8, 0x08, 0xb2, 0x94, 0xf5, + 0x9a, 0x65, 0x19, 0x5c, 0x0c, 0xf9, 0x32, 0x8c, 0x85, 0x60, 0x7c, 0x90, 0xb3, 0x90, 0xb0, 0x2d, + 0xfe, 0x3d, 0x9f, 0xcc, 0xe9, 0x63, 0x9d, 0x06, 0x21, 0x34, 0x5c, 0x6d, 0x8a, 0x2f, 0x4f, 0x00, + 0x62, 0xcc, 0xe8, 0x5d, 0x2f, 0x31, 0xc4, 0x3a, 0x8c, 0x47, 0xa0, 0x7c, 0x90, 0x77, 0xc3, 0x80, + 0x4d, 0x21, 0x7c, 0x98, 0x8e, 0x2f, 0x09, 0x30, 0x3a, 0x51, 0xb6, 0x31, 0x9a, 0xd3, 0xdf, 0x3b, + 0x0c, 0x49, 0xca, 0x15, 0x7d, 0x46, 0x02, 0x08, 0xdd, 0xdc, 0x2a, 0x74, 0x62, 0xd3, 0xfe, 0x34, + 0x27, 0x3f, 0xd3, 0x33, 0x3e, 0xaf, 0xbb, 0x4f, 0xfd, 0xf8, 0xbf, 0xfe, 0xce, 0xcf, 0xc4, 0xee, + 0x46, 0xf2, 0x4c, 0x87, 0x73, 0xa4, 0x50, 0x30, 0x7e, 0x59, 0x0a, 0xbf, 0x4b, 0xf6, 0x60, 0x6f, + 0x43, 0x09, 0xc9, 0x0a, 0xbd, 0xa2, 0x73, 0xc1, 0xce, 0x53, 0xc1, 0x1e, 0x45, 0x8f, 0x74, 0x17, + 0x6c, 0xe6, 0x43, 0xd1, 0xe8, 0xfa, 0x08, 0xfa, 0xa6, 0x04, 0x13, 0xed, 0x8e, 0x09, 0xd0, 0xb9, + 0xde, 0xa4, 0x68, 0x2d, 0xc8, 0xf2, 0x8f, 0x1f, 0x80, 0x92, 0xab, 0xb2, 0x40, 0x55, 0x99, 0x45, + 0x4f, 0x1c, 0x40, 0x95, 0x99, 0xd0, 0xea, 0x87, 0xfe, 0x9f, 0x04, 0xc7, 0xf7, 0xdd, 0x42, 0xa3, + 0xd9, 0xde, 0xa4, 0xdc, 0xa7, 0xf2, 0xcc, 0x97, 0xde, 0x08, 0x0b, 0xae, 0xf1, 0x93, 0x54, 0xe3, + 0xcb, 0x68, 0xf1, 0x20, 0x1a, 0x07, 0x65, 0x62, 0x58, 0xf7, 0xdf, 0x96, 0x22, 0xaf, 0x53, 0xec, + 0xef, 0x4e, 0x2d, 0x7b, 0xc7, 0x2e, 0x81, 0xd1, 0xba, 0x25, 0x90, 0x9f, 0xa6, 0x2a, 0x28, 0x68, + 0xed, 0x0d, 0x4e, 0xda, 0xcc, 0x87, 0xa2, 0x8b, 0xca, 0x47, 0xd0, 0xff, 0x91, 0xda, 0xbf, 0xbf, + 0xf0, 0xd8, 0xbe, 0x22, 0x76, 0xde, 0x17, 0xe7, 0xcf, 0xf5, 0x4f, 0xc8, 0x95, 0xac, 0x53, 0x25, + 0x6b, 0x08, 0xdf, 0x6e, 0x25, 0xdb, 0x4e, 0x22, 0xfa, 0x1d, 0x09, 0x26, 0xda, 0xed, 0xe8, 0xba, + 0x84, 0xe5, 0x3e, 0x7b, 0xd9, 0x2e, 0x61, 0xb9, 0xdf, 0xf6, 0x51, 0x7e, 0x37, 0x55, 0xfe, 0x2c, + 0x3a, 0xd3, 0x49, 0xf9, 0x7d, 0x67, 0x91, 0xc4, 0xe2, 0xbe, 0x3b, 0x9f, 0x2e, 0xb1, 0xd8, 0xcb, + 0x2e, 0xb0, 0x4b, 0x2c, 0xf6, 0xb4, 0xf1, 0xea, 0x1e, 0x8b, 0xbe, 0x66, 0x3d, 0x4e, 0xa3, 0x8b, + 0x7e, 0x43, 0x82, 0xe1, 0x48, 0x5d, 0x8e, 0x1e, 0xde, 0x57, 0xd0, 0x76, 0xbb, 0xa8, 0xfc, 0xe9, + 0x7e, 0x48, 0xb8, 0x2e, 0x8b, 0x54, 0x97, 0x39, 0x34, 0x7b, 0x10, 0x5d, 0x9c, 0x88, 0xc4, 0x2f, + 0x4b, 0x30, 0xde, 0xa6, 0x84, 0xed, 0x12, 0x85, 0x9d, 0x4b, 0xf7, 0xfc, 0xb9, 0xfe, 0x09, 0xb9, + 0x56, 0x17, 0xa8, 0x56, 0xef, 0x43, 0xef, 0x3d, 0x88, 0x56, 0xa1, 0xf5, 0xf9, 0x66, 0x70, 0x3f, + 0x3a, 0x34, 0x0e, 0x3a, 0xdb, 0xa7, 0x60, 0x42, 0xa1, 0xc7, 0xfa, 0xa6, 0xe3, 0xfa, 0x3c, 0x45, + 0xf5, 0x79, 0x12, 0xad, 0xbe, 0x31, 0x7d, 0x5a, 0x97, 0xf5, 0xaf, 0xb6, 0x7e, 0x2a, 0x62, 0x7f, + 0x2f, 0x6a, 0x5b, 0xac, 0xe6, 0x1f, 0xe9, 0x8b, 0x86, 0x2b, 0x75, 0x8e, 0x2a, 0x75, 0x1a, 0x3d, + 0xd4, 0x49, 0xa9, 0xd0, 0x25, 0x78, 0xdd, 0xdc, 0xb6, 0x66, 0x3e, 0xc4, 0x4a, 0xe0, 0x8f, 0xa0, + 0x1f, 0x13, 0x17, 0x90, 0x4f, 0xee, 0x3b, 0x6e, 0xa8, 0x8e, 0xcd, 0xdf, 0xd7, 0x03, 0x26, 0x97, + 0xeb, 0x6e, 0x2a, 0xd7, 0x14, 0x3a, 0xd6, 0x49, 0x2e, 0x52, 0xcb, 0xa2, 0x4f, 0x4a, 0xfe, 0x3b, + 0x0b, 0xa7, 0xf6, 0xe7, 0x1d, 0x2e, 0x76, 0xf3, 0xf7, 0xf7, 0x84, 0xcb, 0x25, 0xb9, 0x87, 0x4a, + 0x72, 0x02, 0x4d, 0x75, 0x94, 0x84, 0x95, 0xbe, 0xb7, 0xfb, 0xce, 0xcb, 0x67, 0x53, 0x1d, 0x3f, + 0x8b, 0x52, 0xc3, 0x26, 0x76, 0x75, 0xf7, 0x40, 0x77, 0x92, 0x7b, 0x7b, 0xb0, 0xfa, 0xcd, 0x24, + 0x0c, 0x2d, 0xb0, 0x51, 0xd6, 0x3d, 0xd5, 0x7b, 0x83, 0x1b, 0x01, 0xe4, 0xf2, 0x0f, 0x19, 0xd2, + 0x2b, 0x2d, 0x15, 0xdb, 0xba, 0x8e, 0xc5, 0x5e, 0x71, 0xb1, 0xef, 0xcb, 0xc0, 0xfc, 0xfd, 0xfc, + 0x66, 0x7e, 0x32, 0xfb, 0x26, 0x22, 0xbd, 0x75, 0xb3, 0x46, 0x00, 0xe8, 0x63, 0x12, 0x1c, 0xa6, + 0x58, 0x41, 0xbc, 0x51, 0x4c, 0xf1, 0x3e, 0x61, 0x47, 0x8f, 0x59, 0x52, 0x43, 0xc7, 0x3f, 0x94, + 0x57, 0xe9, 0x6e, 0xfe, 0x7a, 0xcb, 0xb1, 0xd0, 0xe0, 0xcd, 0x6c, 0x65, 0x65, 0xdc, 0x68, 0xa1, + 0x74, 0x9b, 0x0e, 0x0d, 0x12, 0x07, 0x3f, 0x34, 0xb8, 0x04, 0x99, 0x50, 0xa6, 0xcf, 0x25, 0xbb, + 0xbc, 0xc2, 0xdb, 0x7c, 0xb2, 0x18, 0x26, 0x46, 0x9f, 0x90, 0xe0, 0x70, 0xdb, 0x45, 0x90, 0xfe, + 0x1f, 0xce, 0x3e, 0x4f, 0x2e, 0x9b, 0x8c, 0xd3, 0x96, 0xaf, 0xac, 0x4c, 0x34, 0xda, 0x55, 0x13, + 0x6b, 0x30, 0x1c, 0x59, 0xc0, 0x72, 0xe2, 0xbf, 0xe9, 0xf6, 0xfe, 0xc2, 0x45, 0x94, 0x01, 0xca, + 0x43, 0x0a, 0xef, 0xda, 0x96, 0xe3, 0xe1, 0x2a, 0xbd, 0xac, 0x93, 0x52, 0xfc, 0xb6, 0x7c, 0x1d, + 0x50, 0xeb, 0xe4, 0xa2, 0xcb, 0x30, 0x18, 0xbd, 0xda, 0x77, 0x80, 0x03, 0x0c, 0xc1, 0x01, 0x4d, + 0x40, 0x32, 0xf0, 0xef, 0xb8, 0xc2, 0x1a, 0xb7, 0x3b, 0x39, 0xfc, 0x69, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x75, 0x0a, 0xea, 0x1f, 0x47, 0x91, 0x00, 0x00, } r := bytes.NewReader(gzipped) gzipr, err := compress_gzip.NewReader(r)