Browse Source

genesis: add support for arbitrary initial height (#5191)

Adds a genesis parameter `initial_height` which specifies the initial block height, as well as ABCI `RequestInitChain.InitialHeight` to pass it to the ABCI application, and `State.InitialHeight` to keep track of the initial height throughout the code. Fixes #2543, based on [RFC-002](https://github.com/tendermint/spec/pull/119). Spec changes in https://github.com/tendermint/spec/pull/135.
pull/5231/head
Erik Grinaker 4 years ago
committed by GitHub
parent
commit
cc247c091b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 556 additions and 318 deletions
  1. +3
    -0
      CHANGELOG_PENDING.md
  2. +9
    -0
      UPGRADING.md
  3. +204
    -168
      abci/types/types.pb.go
  4. +4
    -0
      cmd/tendermint/commands/testnet.go
  5. +1
    -0
      config/toml.go
  6. +8
    -5
      consensus/common_test.go
  7. +31
    -3
      consensus/reactor.go
  8. +44
    -3
      consensus/reactor_test.go
  9. +23
    -7
      consensus/replay.go
  10. +2
    -1
      consensus/replay_test.go
  11. +35
    -26
      consensus/state.go
  12. +2
    -2
      consensus/state_test.go
  13. +1
    -0
      evidence/pool_test.go
  14. +2
    -1
      node/node.go
  15. +1
    -0
      proto/tendermint/abci/types.proto
  16. +85
    -49
      proto/tendermint/state/types.pb.go
  17. +2
    -1
      proto/tendermint/state/types.proto
  18. +1
    -1
      rpc/core/env.go
  19. +11
    -6
      state/execution.go
  20. +2
    -2
      state/execution_test.go
  21. +13
    -8
      state/state.go
  22. +13
    -8
      state/store.go
  23. +1
    -0
      state/store_test.go
  24. +15
    -5
      state/validation.go
  25. +16
    -9
      statesync/stateprovider.go
  26. +2
    -4
      types/block.go
  27. +7
    -0
      types/genesis.go
  28. +18
    -9
      types/genesis_test.go

+ 3
- 0
CHANGELOG_PENDING.md View File

@ -16,10 +16,13 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi
- [evidence] [\#5181](https://github.com/tendermint/tendermint/pull/5181) Phantom validator evidence was removed (also from abci) (@cmwaters)
- [merkle] [\#5193](https://github.com/tendermint/tendermint/pull/5193) `HashFromByteSlices` and `ProofsFromByteSlices` now return a hash for empty inputs, following RFC6962 (@erikgrinaker)
- [crypto] [\#5214] Change `GenPrivKeySecp256k1` to `GenPrivKeyFromSecret` to be consistent with other keys
- [state] [\#5191](https://github.com/tendermint/tendermint/pull/5191/files) Add `State.InitialHeight` field to record initial block height, must be `1` (not `0`) to start from 1 (@erikgrinaker)
### FEATURES:
- [abci] [\#5174](https://github.com/tendermint/tendermint/pull/5174) Add amnesia evidence and remove mock and potential amnesia evidence from abci (@cmwaters)
- [abci] [\#5191](https://github.com/tendermint/tendermint/pull/5191/files) Add `InitChain.InitialHeight` field giving the initial block height (@erikgrinaker)
- [genesis] [\#5191](https://github.com/tendermint/tendermint/pull/5191/files) Add `initial_height` field to specify the initial chain height (defaults to `1`) (@erikgrinaker)
### IMPROVEMENTS:


+ 9
- 0
UPGRADING.md View File

@ -32,6 +32,9 @@ if you want to learn more & support it (with cosmos-sdk you get it
`KV.Pair` has been replaced with `abci.EventAttribute`. `EventAttribute.Index`
field allows ABCI applications to dictate which events should be indexed.
The blockchain can now start from an arbitrary initial height, provided to the
application via `RequestInitChain.InitialHeight`.
### P2P Protocol
The default codec is now proto3, not amino. Check out the [TODO]() for
@ -137,6 +140,12 @@ functions) and `Client` object, which represents the complete light client.
RPC client can be found in `/rpc` directory. HTTP(S) proxy is located in
`/proxy` directory.
### State
A field `State.InitialHeight` has been added to record the initial chain height, which must be `1`
(not `0`) if starting from height `1`. This can be configured via the genesis field
`initial_height`.
## v0.33.4
### Go API


+ 204
- 168
abci/types/types.pb.go View File

@ -585,6 +585,7 @@ type RequestInitChain struct {
ConsensusParams *ConsensusParams `protobuf:"bytes,3,opt,name=consensus_params,json=consensusParams,proto3" json:"consensus_params,omitempty"`
Validators []ValidatorUpdate `protobuf:"bytes,4,rep,name=validators,proto3" json:"validators"`
AppStateBytes []byte `protobuf:"bytes,5,opt,name=app_state_bytes,json=appStateBytes,proto3" json:"app_state_bytes,omitempty"`
InitialHeight int64 `protobuf:"varint,6,opt,name=initial_height,json=initialHeight,proto3" json:"initial_height,omitempty"`
}
func (m *RequestInitChain) Reset() { *m = RequestInitChain{} }
@ -655,6 +656,13 @@ func (m *RequestInitChain) GetAppStateBytes() []byte {
return nil
}
func (m *RequestInitChain) GetInitialHeight() int64 {
if m != nil {
return m.InitialHeight
}
return 0
}
type RequestQuery struct {
Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
@ -3162,174 +3170,175 @@ func init() {
func init() { proto.RegisterFile("tendermint/abci/types.proto", fileDescriptor_252557cfdd89a31a) }
var fileDescriptor_252557cfdd89a31a = []byte{
// 2663 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5a, 0x3b, 0x77, 0x1b, 0xc7,
0x15, 0xc6, 0xfb, 0x71, 0x49, 0x3c, 0x38, 0xa2, 0x65, 0x68, 0x25, 0x91, 0xf2, 0xea, 0xd8, 0xb1,
0x64, 0x9b, 0x4c, 0xa8, 0x23, 0x45, 0x8a, 0x9d, 0xd8, 0x04, 0x0c, 0x05, 0xb4, 0x64, 0x92, 0x19,
0x52, 0x72, 0x5e, 0xd6, 0x7a, 0x81, 0x1d, 0x02, 0x6b, 0x01, 0xbb, 0x6b, 0xec, 0x80, 0x22, 0x5d,
0xc6, 0x49, 0xa3, 0x34, 0x4e, 0x97, 0xc6, 0x5d, 0x7e, 0x44, 0xaa, 0x34, 0x69, 0x5c, 0xba, 0x4c,
0xa5, 0xe4, 0x48, 0x27, 0x4d, 0xfe, 0x40, 0xca, 0xe4, 0xcc, 0x63, 0x5f, 0x00, 0x16, 0x00, 0xed,
0x74, 0xe9, 0xe6, 0x71, 0xef, 0x1d, 0xdc, 0xd9, 0xb9, 0xdf, 0xfd, 0xe6, 0x0e, 0xe0, 0x22, 0x25,
0x96, 0x41, 0x86, 0x03, 0xd3, 0xa2, 0x9b, 0x7a, 0xbb, 0x63, 0x6e, 0xd2, 0x53, 0x87, 0xb8, 0x1b,
0xce, 0xd0, 0xa6, 0x36, 0xaa, 0x04, 0x93, 0x1b, 0x6c, 0x52, 0xb9, 0x1c, 0x92, 0xee, 0x0c, 0x4f,
0x1d, 0x6a, 0x6f, 0x3a, 0x43, 0xdb, 0x3e, 0x12, 0xf2, 0xca, 0xa5, 0xd0, 0x34, 0xb7, 0x13, 0xb6,
0x16, 0x99, 0x95, 0xca, 0x8f, 0xc9, 0xa9, 0x37, 0x7b, 0x79, 0x42, 0xd7, 0xd1, 0x87, 0xfa, 0xc0,
0x9b, 0x5e, 0xef, 0xda, 0x76, 0xb7, 0x4f, 0x36, 0x79, 0xaf, 0x3d, 0x3a, 0xda, 0xa4, 0xe6, 0x80,
0xb8, 0x54, 0x1f, 0x38, 0x52, 0x60, 0xb5, 0x6b, 0x77, 0x6d, 0xde, 0xdc, 0x64, 0x2d, 0x31, 0xaa,
0xfe, 0xa1, 0x00, 0x79, 0x4c, 0x3e, 0x1b, 0x11, 0x97, 0xa2, 0x2d, 0xc8, 0x90, 0x4e, 0xcf, 0xae,
0x25, 0xaf, 0x24, 0x5f, 0x5f, 0xda, 0xba, 0xb4, 0x31, 0xe6, 0xdc, 0x86, 0x94, 0x6b, 0x76, 0x7a,
0x76, 0x2b, 0x81, 0xb9, 0x2c, 0xba, 0x09, 0xd9, 0xa3, 0xfe, 0xc8, 0xed, 0xd5, 0x52, 0x5c, 0xe9,
0x72, 0x9c, 0xd2, 0x5d, 0x26, 0xd4, 0x4a, 0x60, 0x21, 0xcd, 0x96, 0x32, 0xad, 0x23, 0xbb, 0x96,
0x9e, 0xbd, 0xd4, 0x8e, 0x75, 0xc4, 0x97, 0x62, 0xb2, 0xa8, 0x0e, 0xe0, 0x12, 0xaa, 0xd9, 0x0e,
0x35, 0x6d, 0xab, 0x96, 0xe1, 0x9a, 0xaf, 0xc4, 0x69, 0x1e, 0x10, 0xba, 0xc7, 0x05, 0x5b, 0x09,
0x5c, 0x74, 0xbd, 0x0e, 0xb3, 0x61, 0x5a, 0x26, 0xd5, 0x3a, 0x3d, 0xdd, 0xb4, 0x6a, 0xd9, 0xd9,
0x36, 0x76, 0x2c, 0x93, 0x36, 0x98, 0x20, 0xb3, 0x61, 0x7a, 0x1d, 0xe6, 0xf2, 0x67, 0x23, 0x32,
0x3c, 0xad, 0xe5, 0x66, 0xbb, 0xfc, 0x33, 0x26, 0xc4, 0x5c, 0xe6, 0xd2, 0xa8, 0x09, 0x4b, 0x6d,
0xd2, 0x35, 0x2d, 0xad, 0xdd, 0xb7, 0x3b, 0x8f, 0x6b, 0x79, 0xae, 0xac, 0xc6, 0x29, 0xd7, 0x99,
0x68, 0x9d, 0x49, 0xb6, 0x12, 0x18, 0xda, 0x7e, 0x0f, 0xbd, 0x03, 0x85, 0x4e, 0x8f, 0x74, 0x1e,
0x6b, 0xf4, 0xa4, 0x56, 0xe0, 0x36, 0xd6, 0xe3, 0x6c, 0x34, 0x98, 0xdc, 0xe1, 0x49, 0x2b, 0x81,
0xf3, 0x1d, 0xd1, 0x64, 0xfe, 0x1b, 0xa4, 0x6f, 0x1e, 0x93, 0x21, 0xd3, 0x2f, 0xce, 0xf6, 0xff,
0x7d, 0x21, 0xc9, 0x2d, 0x14, 0x0d, 0xaf, 0x83, 0xde, 0x85, 0x22, 0xb1, 0x0c, 0xe9, 0x06, 0x70,
0x13, 0x57, 0x62, 0xcf, 0x8a, 0x65, 0x78, 0x4e, 0x14, 0x88, 0x6c, 0xa3, 0xdb, 0x90, 0xeb, 0xd8,
0x83, 0x81, 0x49, 0x6b, 0x4b, 0x5c, 0x7b, 0x2d, 0xd6, 0x01, 0x2e, 0xd5, 0x4a, 0x60, 0x29, 0x8f,
0x76, 0xa1, 0xdc, 0x37, 0x5d, 0xaa, 0xb9, 0x96, 0xee, 0xb8, 0x3d, 0x9b, 0xba, 0xb5, 0x65, 0x6e,
0xe1, 0xd5, 0x38, 0x0b, 0xf7, 0x4d, 0x97, 0x1e, 0x78, 0xc2, 0xad, 0x04, 0x2e, 0xf5, 0xc3, 0x03,
0xcc, 0x9e, 0x7d, 0x74, 0x44, 0x86, 0xbe, 0xc1, 0x5a, 0x69, 0xb6, 0xbd, 0x3d, 0x26, 0xed, 0xe9,
0x33, 0x7b, 0x76, 0x78, 0x00, 0xfd, 0x0a, 0xce, 0xf5, 0x6d, 0xdd, 0xf0, 0xcd, 0x69, 0x9d, 0xde,
0xc8, 0x7a, 0x5c, 0x2b, 0x73, 0xa3, 0xd7, 0x62, 0x7f, 0xa4, 0xad, 0x1b, 0x9e, 0x89, 0x06, 0x53,
0x68, 0x25, 0xf0, 0x4a, 0x7f, 0x7c, 0x10, 0x3d, 0x82, 0x55, 0xdd, 0x71, 0xfa, 0xa7, 0xe3, 0xd6,
0x2b, 0xdc, 0xfa, 0xf5, 0x38, 0xeb, 0xdb, 0x4c, 0x67, 0xdc, 0x3c, 0xd2, 0x27, 0x46, 0xeb, 0x79,
0xc8, 0x1e, 0xeb, 0xfd, 0x11, 0x51, 0xbf, 0x07, 0x4b, 0xa1, 0x50, 0x47, 0x35, 0xc8, 0x0f, 0x88,
0xeb, 0xea, 0x5d, 0xc2, 0x91, 0xa1, 0x88, 0xbd, 0xae, 0x5a, 0x86, 0xe5, 0x70, 0x78, 0xab, 0x03,
0x5f, 0x91, 0x05, 0x2e, 0x53, 0x3c, 0x26, 0x43, 0x97, 0x45, 0xab, 0x54, 0x94, 0x5d, 0x74, 0x15,
0x4a, 0xfc, 0xf8, 0x68, 0xde, 0x3c, 0x43, 0x8f, 0x0c, 0x5e, 0xe6, 0x83, 0x0f, 0xa5, 0xd0, 0x3a,
0x2c, 0x39, 0x5b, 0x8e, 0x2f, 0x92, 0xe6, 0x22, 0xe0, 0x6c, 0x39, 0x52, 0x40, 0xfd, 0x11, 0x54,
0xc7, 0xa3, 0x1d, 0x55, 0x21, 0xfd, 0x98, 0x9c, 0xca, 0xf5, 0x58, 0x13, 0xad, 0x4a, 0xb7, 0xf8,
0x1a, 0x45, 0x2c, 0x7d, 0xfc, 0x53, 0xca, 0x57, 0xf6, 0xc3, 0x1c, 0xdd, 0x86, 0x0c, 0x43, 0x4d,
0x09, 0x80, 0xca, 0x86, 0x80, 0xd4, 0x0d, 0x0f, 0x52, 0x37, 0x0e, 0x3d, 0x48, 0xad, 0x17, 0xbe,
0x7e, 0xb6, 0x9e, 0xf8, 0xf2, 0xef, 0xeb, 0x49, 0xcc, 0x35, 0xd0, 0x05, 0x16, 0x95, 0xba, 0x69,
0x69, 0xa6, 0x21, 0xd7, 0xc9, 0xf3, 0xfe, 0x8e, 0x81, 0xee, 0x41, 0xb5, 0x63, 0x5b, 0x2e, 0xb1,
0xdc, 0x91, 0xab, 0x09, 0xc8, 0x96, 0xb0, 0x37, 0x19, 0x35, 0x0d, 0x4f, 0x70, 0x9f, 0xcb, 0xe1,
0x4a, 0x27, 0x3a, 0x80, 0xee, 0x02, 0x1c, 0xeb, 0x7d, 0xd3, 0xd0, 0xa9, 0x3d, 0x74, 0x6b, 0x99,
0x2b, 0xe9, 0xa9, 0x66, 0x1e, 0x7a, 0x22, 0x0f, 0x1c, 0x43, 0xa7, 0xa4, 0x9e, 0x61, 0xbf, 0x16,
0x87, 0x34, 0xd1, 0x6b, 0x50, 0xd1, 0x1d, 0x47, 0x73, 0xa9, 0x4e, 0x89, 0xd6, 0x3e, 0xa5, 0xc4,
0xe5, 0x60, 0xb8, 0x8c, 0x4b, 0xba, 0xe3, 0x1c, 0xb0, 0xd1, 0x3a, 0x1b, 0x54, 0x0d, 0xff, 0x0b,
0x73, 0x34, 0x43, 0x08, 0x32, 0x86, 0x4e, 0x75, 0xbe, 0x43, 0xcb, 0x98, 0xb7, 0xd9, 0x98, 0xa3,
0xd3, 0x9e, 0xf4, 0x9b, 0xb7, 0xd1, 0x79, 0xc8, 0xf5, 0x88, 0xd9, 0xed, 0x51, 0xee, 0x6a, 0x1a,
0xcb, 0x1e, 0xfb, 0x18, 0xce, 0xd0, 0x3e, 0x26, 0x1c, 0xbe, 0x0b, 0x58, 0x74, 0xd4, 0xdf, 0xa6,
0x60, 0x65, 0x02, 0xf7, 0x98, 0xdd, 0x9e, 0xee, 0xf6, 0xbc, 0xb5, 0x58, 0x1b, 0xdd, 0x62, 0x76,
0x75, 0x83, 0x0c, 0x65, 0xbe, 0xa9, 0x85, 0x7d, 0x17, 0xb9, 0xb4, 0xc5, 0xe7, 0xa5, 0xcf, 0x52,
0x1a, 0xed, 0x41, 0xb5, 0xaf, 0xbb, 0x54, 0x13, 0x38, 0xa2, 0x85, 0x72, 0xcf, 0x24, 0x7a, 0xde,
0xd7, 0x3d, 0xe4, 0x61, 0xa7, 0x58, 0x1a, 0x2a, 0xf7, 0x23, 0xa3, 0x08, 0xc3, 0x6a, 0xfb, 0xf4,
0x73, 0xdd, 0xa2, 0xa6, 0x45, 0xb4, 0x89, 0x4f, 0x72, 0x61, 0xc2, 0x68, 0xf3, 0xd8, 0x34, 0x88,
0xd5, 0xf1, 0xbe, 0xc5, 0x39, 0x5f, 0xd9, 0xff, 0x56, 0xae, 0x8a, 0xa1, 0x1c, 0x45, 0x6e, 0x54,
0x86, 0x14, 0x3d, 0x91, 0x1b, 0x90, 0xa2, 0x27, 0xe8, 0xfb, 0x90, 0x61, 0x4e, 0x72, 0xe7, 0xcb,
0x53, 0xd2, 0xa6, 0xd4, 0x3b, 0x3c, 0x75, 0x08, 0xe6, 0x92, 0xaa, 0xea, 0x1f, 0x73, 0x1f, 0xcd,
0xc7, 0xad, 0xaa, 0xd7, 0xa0, 0x32, 0x06, 0xd7, 0xa1, 0xef, 0x97, 0x0c, 0x7f, 0x3f, 0xb5, 0x02,
0xa5, 0x08, 0x36, 0xab, 0xe7, 0x61, 0x75, 0x1a, 0xd4, 0xaa, 0x3d, 0x7f, 0x3c, 0x02, 0x99, 0xe8,
0x26, 0x14, 0x7c, 0xac, 0x15, 0x61, 0x36, 0xb9, 0x57, 0x9e, 0x30, 0xf6, 0x45, 0x59, 0x7c, 0xb1,
0xf3, 0xca, 0xcf, 0x43, 0x8a, 0xff, 0xf0, 0xbc, 0xee, 0x38, 0x2d, 0xdd, 0xed, 0xa9, 0x9f, 0x40,
0x2d, 0x0e, 0x47, 0xc7, 0xdc, 0xc8, 0xf8, 0xc7, 0xf0, 0x3c, 0xe4, 0x8e, 0xec, 0xe1, 0x40, 0xa7,
0xdc, 0x58, 0x09, 0xcb, 0x1e, 0x3b, 0x9e, 0x02, 0x53, 0xd3, 0x7c, 0x58, 0x74, 0x54, 0x0d, 0x2e,
0xc4, 0x62, 0x29, 0x53, 0x31, 0x2d, 0x83, 0x88, 0xfd, 0x2c, 0x61, 0xd1, 0x09, 0x0c, 0x89, 0x1f,
0x2b, 0x3a, 0x6c, 0x59, 0x97, 0xfb, 0xca, 0xed, 0x17, 0xb1, 0xec, 0xa9, 0xff, 0x2c, 0x40, 0x01,
0x13, 0xd7, 0x61, 0xc1, 0x8e, 0xea, 0x50, 0x24, 0x27, 0x1d, 0x22, 0x58, 0x4e, 0x32, 0x96, 0x25,
0x08, 0xe9, 0xa6, 0x27, 0xc9, 0x52, 0xb4, 0xaf, 0x86, 0x6e, 0x48, 0x26, 0x17, 0x4f, 0xca, 0xa4,
0x7a, 0x98, 0xca, 0xdd, 0xf2, 0xa8, 0x5c, 0x3a, 0x36, 0x2b, 0x0b, 0xad, 0x31, 0x2e, 0x77, 0x43,
0x72, 0xb9, 0xcc, 0x9c, 0xc5, 0x22, 0x64, 0xae, 0x11, 0x21, 0x73, 0xd9, 0x39, 0x6e, 0xc6, 0xb0,
0xb9, 0x46, 0x84, 0xcd, 0xe5, 0xe6, 0x18, 0x89, 0xa1, 0x73, 0xb7, 0x3c, 0x3a, 0x97, 0x9f, 0xe3,
0xf6, 0x18, 0x9f, 0xbb, 0x1b, 0xe5, 0x73, 0x82, 0x8b, 0x5d, 0x8d, 0xd5, 0x8e, 0x25, 0x74, 0x3f,
0x0e, 0x11, 0xba, 0x62, 0x2c, 0x9b, 0x12, 0x46, 0xa6, 0x30, 0xba, 0x46, 0x84, 0xd1, 0xc1, 0x9c,
0x3d, 0x88, 0xa1, 0x74, 0xef, 0x85, 0x29, 0xdd, 0x52, 0x2c, 0x2b, 0x94, 0x87, 0x66, 0x1a, 0xa7,
0xbb, 0xe3, 0x73, 0xba, 0xe5, 0x58, 0x52, 0x2a, 0x7d, 0x18, 0x27, 0x75, 0x7b, 0x13, 0xa4, 0x4e,
0x90, 0xb0, 0xd7, 0x62, 0x4d, 0xcc, 0x61, 0x75, 0x7b, 0x13, 0xac, 0xae, 0x3c, 0xc7, 0xe0, 0x1c,
0x5a, 0xf7, 0xeb, 0xe9, 0xb4, 0x2e, 0x9e, 0x78, 0xc9, 0x9f, 0xb9, 0x18, 0xaf, 0xd3, 0x62, 0x78,
0x5d, 0x95, 0x9b, 0x7f, 0x23, 0xd6, 0xfc, 0xd9, 0x89, 0xdd, 0x35, 0x96, 0x66, 0xc7, 0x80, 0x83,
0x41, 0x15, 0x19, 0x0e, 0xed, 0xa1, 0xe4, 0x4c, 0xa2, 0xa3, 0xbe, 0xce, 0x12, 0x7f, 0x00, 0x12,
0x33, 0x48, 0x20, 0x4f, 0x09, 0x21, 0x60, 0x50, 0xff, 0x9c, 0x0c, 0x74, 0x79, 0xae, 0x0c, 0x93,
0x86, 0xa2, 0x24, 0x0d, 0x21, 0x6e, 0x98, 0x8a, 0x72, 0xc3, 0x75, 0x58, 0x62, 0x50, 0x3f, 0x46,
0xfb, 0x74, 0xc7, 0xa3, 0x7d, 0xe8, 0x3a, 0xac, 0xf0, 0x5c, 0x2e, 0x18, 0xa4, 0xc4, 0xf7, 0x0c,
0x4f, 0x53, 0x15, 0x36, 0x21, 0x0e, 0xa7, 0x00, 0xfa, 0xb7, 0xe0, 0x5c, 0x48, 0xd6, 0x4f, 0x21,
0x82, 0xeb, 0x54, 0x7d, 0xe9, 0x6d, 0x99, 0x4b, 0x3e, 0x0c, 0x36, 0x28, 0xa0, 0x94, 0x08, 0x32,
0x1d, 0xdb, 0x20, 0x12, 0xe0, 0x79, 0x9b, 0xd1, 0xcc, 0xbe, 0xdd, 0x95, 0x30, 0xce, 0x9a, 0x4c,
0xca, 0x47, 0xc1, 0xa2, 0x00, 0x39, 0xf5, 0xaf, 0xc9, 0xc0, 0x5e, 0xc0, 0x32, 0xa7, 0x11, 0xc2,
0xe4, 0xff, 0x86, 0x10, 0xa6, 0xbe, 0x35, 0x21, 0x0c, 0x27, 0xd8, 0x74, 0x34, 0xc1, 0xfe, 0x3b,
0x19, 0x7c, 0x61, 0x9f, 0x05, 0x7e, 0xbb, 0x1d, 0x09, 0xb2, 0x65, 0x96, 0x7f, 0x2f, 0x99, 0x2d,
0x25, 0x69, 0xcf, 0xf1, 0x75, 0xa3, 0xa4, 0x3d, 0x2f, 0xf2, 0x27, 0xef, 0xa0, 0xdb, 0x50, 0xe4,
0xd5, 0x14, 0xcd, 0x76, 0x5c, 0x09, 0xb8, 0x17, 0xc3, 0xbe, 0x8a, 0xa2, 0xc9, 0xc6, 0x3e, 0x93,
0xd9, 0x73, 0x5c, 0x5c, 0x70, 0x64, 0x2b, 0x44, 0x04, 0x8a, 0x11, 0x3e, 0x7a, 0x09, 0x8a, 0xec,
0xd7, 0xbb, 0x8e, 0xde, 0x21, 0x1c, 0x3c, 0x8b, 0x38, 0x18, 0x50, 0x1f, 0x01, 0x9a, 0x84, 0x6f,
0xd4, 0x82, 0x1c, 0x39, 0x26, 0x16, 0x65, 0x5f, 0x8d, 0x6d, 0xf7, 0xf9, 0x29, 0x64, 0x8f, 0x58,
0xb4, 0x5e, 0x63, 0x9b, 0xfc, 0xaf, 0x67, 0xeb, 0x55, 0x21, 0xfd, 0xa6, 0x3d, 0x30, 0x29, 0x19,
0x38, 0xf4, 0x14, 0x4b, 0x7d, 0xf5, 0x8b, 0x14, 0x63, 0x5e, 0x11, 0x68, 0x9f, 0xba, 0xb7, 0x5e,
0x00, 0xa5, 0x42, 0xac, 0x7b, 0xb1, 0xfd, 0x5e, 0x03, 0xe8, 0xea, 0xae, 0xf6, 0x44, 0xb7, 0x28,
0x31, 0xe4, 0xa6, 0x87, 0x46, 0x90, 0x02, 0x05, 0xd6, 0x1b, 0xb9, 0xc4, 0xe0, 0xdb, 0x9f, 0xc6,
0x7e, 0x3f, 0xe4, 0x67, 0xfe, 0xbb, 0xf9, 0x19, 0xdd, 0xe5, 0xc2, 0xf8, 0x2e, 0xff, 0x2e, 0x15,
0x44, 0x49, 0x40, 0x52, 0xff, 0xff, 0xf6, 0xe1, 0xf7, 0xfc, 0x4a, 0x1a, 0xcd, 0xb1, 0xe8, 0x00,
0x56, 0xfc, 0x28, 0xd5, 0x46, 0x3c, 0x7a, 0xbd, 0x73, 0xb7, 0x68, 0x98, 0x57, 0x8f, 0xa3, 0xc3,
0x2e, 0xfa, 0x39, 0xbc, 0x3c, 0x86, 0x40, 0xbe, 0xe9, 0xd4, 0x82, 0x40, 0xf4, 0x52, 0x14, 0x88,
0x3c, 0xcb, 0xc1, 0x5e, 0xa5, 0xbf, 0x63, 0x6c, 0xec, 0xb0, 0xcb, 0x50, 0x98, 0x31, 0x4c, 0xfd,
0xfa, 0x57, 0xa1, 0x34, 0x24, 0x94, 0x5d, 0xbc, 0x23, 0xd7, 0xcd, 0x65, 0x31, 0x28, 0x92, 0x80,
0xba, 0x0f, 0x2f, 0x4d, 0x65, 0x0e, 0xe8, 0x87, 0x50, 0x0c, 0x48, 0x47, 0x32, 0xe6, 0xe6, 0xe6,
0xdf, 0x46, 0x02, 0x59, 0xf5, 0x2f, 0xc9, 0xc0, 0x64, 0xf4, 0x7e, 0xd3, 0x84, 0xdc, 0x90, 0xb8,
0xa3, 0xbe, 0xb8, 0x71, 0x94, 0xb7, 0xde, 0x5a, 0x8c, 0x73, 0xb0, 0xd1, 0x51, 0x9f, 0x62, 0xa9,
0xac, 0x3e, 0x82, 0x9c, 0x18, 0x41, 0x4b, 0x90, 0x7f, 0xb0, 0x7b, 0x6f, 0x77, 0xef, 0xa3, 0xdd,
0x6a, 0x02, 0x01, 0xe4, 0xb6, 0x1b, 0x8d, 0xe6, 0xfe, 0x61, 0x35, 0x89, 0x8a, 0x90, 0xdd, 0xae,
0xef, 0xe1, 0xc3, 0x6a, 0x8a, 0x0d, 0xe3, 0xe6, 0x07, 0xcd, 0xc6, 0x61, 0x35, 0x8d, 0x56, 0xa0,
0x24, 0xda, 0xda, 0xdd, 0x3d, 0xfc, 0xe1, 0xf6, 0x61, 0x35, 0x13, 0x1a, 0x3a, 0x68, 0xee, 0xbe,
0xdf, 0xc4, 0xd5, 0xac, 0xfa, 0x03, 0x76, 0xa5, 0x89, 0x61, 0x29, 0xc1, 0xe5, 0x25, 0x19, 0xba,
0xbc, 0xa8, 0x7f, 0x4c, 0x81, 0x12, 0x4f, 0x3d, 0xd0, 0x07, 0x63, 0x8e, 0x6f, 0x9d, 0x81, 0xb7,
0x8c, 0x79, 0x8f, 0x5e, 0x85, 0xf2, 0x90, 0x1c, 0x11, 0xda, 0xe9, 0x09, 0x2a, 0x24, 0x12, 0x5b,
0x09, 0x97, 0xe4, 0x28, 0x57, 0x72, 0x85, 0xd8, 0xa7, 0xa4, 0x43, 0x35, 0x71, 0x8f, 0x12, 0x87,
0xae, 0xc8, 0xc4, 0xd8, 0xe8, 0x81, 0x18, 0x54, 0x3f, 0x39, 0xd3, 0x5e, 0x16, 0x21, 0x8b, 0x9b,
0x87, 0xf8, 0x17, 0xd5, 0x34, 0x42, 0x50, 0xe6, 0x4d, 0xed, 0x60, 0x77, 0x7b, 0xff, 0xa0, 0xb5,
0xc7, 0xf6, 0xf2, 0x1c, 0x54, 0xbc, 0xbd, 0xf4, 0x06, 0xb3, 0xea, 0x7f, 0x92, 0x50, 0x19, 0x0b,
0x10, 0xb4, 0x05, 0x59, 0x41, 0xa7, 0xe3, 0xaa, 0xe9, 0x3c, 0xbe, 0x65, 0x34, 0x09, 0x51, 0xf4,
0x0e, 0x14, 0x88, 0xac, 0x13, 0x4c, 0x0b, 0x44, 0x51, 0xdf, 0xf0, 0x2a, 0x09, 0x52, 0xd5, 0xd7,
0x40, 0xef, 0x42, 0xd1, 0x8f, 0x74, 0x79, 0x87, 0x7b, 0x65, 0x52, 0xdd, 0xc7, 0x08, 0xa9, 0x1f,
0xe8, 0xa0, 0x3b, 0x01, 0x27, 0xcb, 0x4c, 0x92, 0x78, 0xa9, 0x2e, 0x04, 0xa4, 0xb2, 0x27, 0xaf,
0x36, 0x60, 0x29, 0xe4, 0x0f, 0xba, 0x08, 0xc5, 0x81, 0x7e, 0x22, 0x0b, 0x4b, 0xa2, 0x82, 0x50,
0x18, 0xe8, 0x27, 0xbc, 0xa6, 0x84, 0x5e, 0x86, 0x3c, 0x9b, 0xec, 0xea, 0x02, 0x6d, 0xd2, 0x38,
0x37, 0xd0, 0x4f, 0x7e, 0xaa, 0xbb, 0xea, 0xc7, 0x50, 0x8e, 0xd6, 0x5e, 0xd8, 0x49, 0x1c, 0xda,
0x23, 0xcb, 0xe0, 0x36, 0xb2, 0x58, 0x74, 0xd0, 0x4d, 0xc8, 0x1e, 0xdb, 0x02, 0xac, 0xa6, 0x87,
0xec, 0x43, 0x9b, 0x92, 0x50, 0xed, 0x46, 0x48, 0xab, 0x9f, 0x43, 0x96, 0x83, 0x0f, 0x03, 0x12,
0x5e, 0x45, 0x91, 0x7c, 0x94, 0xb5, 0xd1, 0xc7, 0x00, 0x3a, 0xa5, 0x43, 0xb3, 0x3d, 0x0a, 0x0c,
0xaf, 0x4f, 0x07, 0xaf, 0x6d, 0x4f, 0xae, 0x7e, 0x49, 0xa2, 0xd8, 0x6a, 0xa0, 0x1a, 0x42, 0xb2,
0x90, 0x41, 0x75, 0x17, 0xca, 0x51, 0xdd, 0x70, 0xa1, 0x72, 0x79, 0x4a, 0xa1, 0xd2, 0xe7, 0x3c,
0x3e, 0x63, 0x4a, 0x8b, 0x8a, 0x19, 0xef, 0xa8, 0x4f, 0x93, 0x50, 0x38, 0x3c, 0x91, 0xc7, 0x3a,
0xa6, 0x58, 0x13, 0xa8, 0xa6, 0xc2, 0xa5, 0x09, 0x51, 0xfd, 0x49, 0xfb, 0x35, 0xa5, 0xf7, 0xfc,
0xc0, 0xcd, 0x2c, 0x7a, 0x79, 0xf4, 0x8a, 0x6b, 0x12, 0xac, 0xde, 0x86, 0xa2, 0x7f, 0xaa, 0x18,
0xb1, 0xd7, 0x0d, 0x63, 0x48, 0x5c, 0x57, 0xfa, 0xe6, 0x75, 0x79, 0xed, 0xcf, 0x7e, 0x22, 0x8b,
0x1f, 0x69, 0x2c, 0x3a, 0xaa, 0x01, 0x95, 0xb1, 0xb4, 0x85, 0xde, 0x86, 0xbc, 0x33, 0x6a, 0x6b,
0xde, 0xf6, 0x8c, 0x05, 0x8f, 0x47, 0xf2, 0x46, 0xed, 0xbe, 0xd9, 0xb9, 0x47, 0x4e, 0xbd, 0x1f,
0xe3, 0x8c, 0xda, 0xf7, 0xc4, 0x2e, 0x8a, 0x55, 0x52, 0xe1, 0x55, 0x8e, 0xa1, 0xe0, 0x1d, 0x0a,
0xf4, 0x93, 0x70, 0x9c, 0x78, 0xa5, 0xde, 0xd8, 0x54, 0x2a, 0xcd, 0x87, 0xc2, 0xe4, 0x3a, 0xac,
0xb8, 0x66, 0xd7, 0x22, 0x86, 0x16, 0x5c, 0x2d, 0xf8, 0x6a, 0x05, 0x5c, 0x11, 0x13, 0xf7, 0xbd,
0x7b, 0x85, 0xfa, 0x2c, 0x09, 0x05, 0x2f, 0x60, 0xa7, 0x9e, 0xbb, 0xc8, 0x8f, 0x49, 0x9d, 0xfd,
0xc7, 0xc4, 0x15, 0x5a, 0xbd, 0x52, 0x76, 0xe6, 0xcc, 0xa5, 0xec, 0x37, 0x01, 0x51, 0x9b, 0xea,
0x7d, 0xed, 0xd8, 0xa6, 0xa6, 0xd5, 0xd5, 0xc4, 0x6e, 0x0a, 0xca, 0x54, 0xe5, 0x33, 0x0f, 0xf9,
0xc4, 0x3e, 0xdf, 0xd8, 0xdf, 0x24, 0xa1, 0xe0, 0x27, 0xbf, 0xb3, 0x96, 0xdb, 0xce, 0x43, 0x4e,
0xe2, 0xbb, 0xa8, 0xb7, 0xc9, 0x9e, 0x5f, 0xf9, 0xcd, 0x84, 0x2a, 0xbf, 0x0a, 0x14, 0x06, 0x84,
0xea, 0x9c, 0x01, 0x88, 0xeb, 0x9b, 0xdf, 0xbf, 0x7e, 0x07, 0x96, 0x42, 0x95, 0x4f, 0x16, 0x5a,
0xbb, 0xcd, 0x8f, 0xaa, 0x09, 0x25, 0xff, 0xf4, 0xab, 0x2b, 0xe9, 0x5d, 0xf2, 0x84, 0x1d, 0x4a,
0xdc, 0x6c, 0xb4, 0x9a, 0x8d, 0x7b, 0xd5, 0xa4, 0xb2, 0xf4, 0xf4, 0xab, 0x2b, 0x79, 0x4c, 0x78,
0x01, 0x65, 0xeb, 0x0b, 0x80, 0xca, 0x76, 0xbd, 0xb1, 0xc3, 0x92, 0x92, 0xd9, 0xd1, 0x65, 0x59,
0x29, 0xc3, 0xef, 0xbc, 0x33, 0x5f, 0x40, 0x95, 0xd9, 0x55, 0x35, 0x74, 0x17, 0xb2, 0xfc, 0x3a,
0x8c, 0x66, 0x3f, 0x89, 0x2a, 0x73, 0xca, 0x6c, 0xec, 0xc7, 0xf0, 0x53, 0x3b, 0xf3, 0x8d, 0x54,
0x99, 0x5d, 0x75, 0x43, 0x18, 0x8a, 0xc1, 0x7d, 0x76, 0xfe, 0x9b, 0xa9, 0xb2, 0x40, 0x25, 0x8e,
0xd9, 0x0c, 0xd8, 0xfa, 0xfc, 0x37, 0x44, 0x65, 0x01, 0x5c, 0x41, 0xf7, 0x21, 0xef, 0xdd, 0x83,
0xe6, 0xbd, 0x6a, 0x2a, 0x73, 0xab, 0x64, 0xec, 0x13, 0x88, 0xfb, 0xea, 0xec, 0x27, 0x5a, 0x65,
0x4e, 0xc9, 0x0f, 0xed, 0x40, 0x4e, 0x52, 0xd0, 0x39, 0x2f, 0x95, 0xca, 0xbc, 0xaa, 0x17, 0xdb,
0xb4, 0xa0, 0x10, 0x30, 0xff, 0xe1, 0x59, 0x59, 0xa0, 0x9a, 0x89, 0x1e, 0x00, 0x84, 0x6e, 0xa7,
0x0b, 0xbc, 0x28, 0x2b, 0x8b, 0x54, 0x29, 0xd1, 0x1e, 0x14, 0xfc, 0x5b, 0xc8, 0xdc, 0xf7, 0x5d,
0x65, 0x7e, 0xb9, 0x10, 0x3d, 0x82, 0x52, 0x94, 0x7e, 0x2f, 0xf6, 0x6a, 0xab, 0x2c, 0x58, 0x07,
0x64, 0xf6, 0xa3, 0x5c, 0x7c, 0xb1, 0x57, 0x5c, 0x65, 0xc1, 0xb2, 0x20, 0xfa, 0x14, 0x56, 0x26,
0xb9, 0xf2, 0xe2, 0x8f, 0xba, 0xca, 0x19, 0x0a, 0x85, 0x68, 0x00, 0x68, 0x0a, 0xc7, 0x3e, 0xc3,
0x1b, 0xaf, 0x72, 0x96, 0xba, 0x61, 0xbd, 0xf9, 0xf5, 0xf3, 0xb5, 0xe4, 0x37, 0xcf, 0xd7, 0x92,
0xff, 0x78, 0xbe, 0x96, 0xfc, 0xf2, 0xc5, 0x5a, 0xe2, 0x9b, 0x17, 0x6b, 0x89, 0xbf, 0xbd, 0x58,
0x4b, 0xfc, 0xf2, 0x8d, 0xae, 0x49, 0x7b, 0xa3, 0xf6, 0x46, 0xc7, 0x1e, 0x6c, 0x86, 0xff, 0x80,
0x32, 0xed, 0x4f, 0x31, 0xed, 0x1c, 0x4f, 0x2f, 0x37, 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x5f,
0xba, 0xe8, 0xf8, 0x34, 0x23, 0x00, 0x00,
// 2681 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5a, 0x4b, 0x73, 0x1b, 0xc7,
0x11, 0xc6, 0xfb, 0xd1, 0x24, 0x1e, 0x1c, 0xd1, 0x32, 0xbc, 0x92, 0x48, 0x79, 0x55, 0x72, 0x2c,
0xd9, 0x26, 0x13, 0xaa, 0xa4, 0x48, 0xb1, 0x13, 0x9b, 0x80, 0xa1, 0x80, 0x96, 0x4c, 0x32, 0x4b,
0x4a, 0xce, 0xcb, 0x5a, 0x0f, 0xb0, 0x43, 0x60, 0x2d, 0x60, 0x77, 0x8d, 0x1d, 0x50, 0xa4, 0x8f,
0x71, 0x72, 0x51, 0x2e, 0xce, 0x2d, 0x17, 0xff, 0x8f, 0x9c, 0x72, 0xc9, 0xc5, 0x55, 0xb9, 0xf8,
0x98, 0x93, 0x92, 0x92, 0x2a, 0x97, 0xfc, 0x81, 0x1c, 0x93, 0x9a, 0xc7, 0xbe, 0x00, 0x2c, 0x00,
0xda, 0xb9, 0xe5, 0x36, 0xd3, 0xdb, 0xdd, 0x8b, 0xe9, 0x9d, 0xfe, 0xe6, 0xeb, 0x1e, 0xc0, 0x05,
0x4a, 0x2c, 0x83, 0x0c, 0x07, 0xa6, 0x45, 0x37, 0x71, 0xbb, 0x63, 0x6e, 0xd2, 0x53, 0x87, 0xb8,
0x1b, 0xce, 0xd0, 0xa6, 0x36, 0xaa, 0x04, 0x0f, 0x37, 0xd8, 0x43, 0xe5, 0x52, 0x48, 0xbb, 0x33,
0x3c, 0x75, 0xa8, 0xbd, 0xe9, 0x0c, 0x6d, 0xfb, 0x48, 0xe8, 0x2b, 0x17, 0x43, 0x8f, 0xb9, 0x9f,
0xb0, 0xb7, 0xc8, 0x53, 0x69, 0xfc, 0x98, 0x9c, 0x7a, 0x4f, 0x2f, 0x4d, 0xd8, 0x3a, 0x78, 0x88,
0x07, 0xde, 0xe3, 0xf5, 0xae, 0x6d, 0x77, 0xfb, 0x64, 0x93, 0xcf, 0xda, 0xa3, 0xa3, 0x4d, 0x6a,
0x0e, 0x88, 0x4b, 0xf1, 0xc0, 0x91, 0x0a, 0xab, 0x5d, 0xbb, 0x6b, 0xf3, 0xe1, 0x26, 0x1b, 0x09,
0xa9, 0xfa, 0x87, 0x02, 0xe4, 0x35, 0xf2, 0xd9, 0x88, 0xb8, 0x14, 0x6d, 0x41, 0x86, 0x74, 0x7a,
0x76, 0x2d, 0x79, 0x39, 0xf9, 0xfa, 0xd2, 0xd6, 0xc5, 0x8d, 0xb1, 0xc5, 0x6d, 0x48, 0xbd, 0x66,
0xa7, 0x67, 0xb7, 0x12, 0x1a, 0xd7, 0x45, 0x37, 0x21, 0x7b, 0xd4, 0x1f, 0xb9, 0xbd, 0x5a, 0x8a,
0x1b, 0x5d, 0x8a, 0x33, 0xba, 0xcb, 0x94, 0x5a, 0x09, 0x4d, 0x68, 0xb3, 0x57, 0x99, 0xd6, 0x91,
0x5d, 0x4b, 0xcf, 0x7e, 0xd5, 0x8e, 0x75, 0xc4, 0x5f, 0xc5, 0x74, 0x51, 0x1d, 0xc0, 0x25, 0x54,
0xb7, 0x1d, 0x6a, 0xda, 0x56, 0x2d, 0xc3, 0x2d, 0x5f, 0x8d, 0xb3, 0x3c, 0x20, 0x74, 0x8f, 0x2b,
0xb6, 0x12, 0x5a, 0xd1, 0xf5, 0x26, 0xcc, 0x87, 0x69, 0x99, 0x54, 0xef, 0xf4, 0xb0, 0x69, 0xd5,
0xb2, 0xb3, 0x7d, 0xec, 0x58, 0x26, 0x6d, 0x30, 0x45, 0xe6, 0xc3, 0xf4, 0x26, 0x6c, 0xc9, 0x9f,
0x8d, 0xc8, 0xf0, 0xb4, 0x96, 0x9b, 0xbd, 0xe4, 0x9f, 0x31, 0x25, 0xb6, 0x64, 0xae, 0x8d, 0x9a,
0xb0, 0xd4, 0x26, 0x5d, 0xd3, 0xd2, 0xdb, 0x7d, 0xbb, 0xf3, 0xb8, 0x96, 0xe7, 0xc6, 0x6a, 0x9c,
0x71, 0x9d, 0xa9, 0xd6, 0x99, 0x66, 0x2b, 0xa1, 0x41, 0xdb, 0x9f, 0xa1, 0x77, 0xa0, 0xd0, 0xe9,
0x91, 0xce, 0x63, 0x9d, 0x9e, 0xd4, 0x0a, 0xdc, 0xc7, 0x7a, 0x9c, 0x8f, 0x06, 0xd3, 0x3b, 0x3c,
0x69, 0x25, 0xb4, 0x7c, 0x47, 0x0c, 0xd9, 0xfa, 0x0d, 0xd2, 0x37, 0x8f, 0xc9, 0x90, 0xd9, 0x17,
0x67, 0xaf, 0xff, 0x7d, 0xa1, 0xc9, 0x3d, 0x14, 0x0d, 0x6f, 0x82, 0xde, 0x85, 0x22, 0xb1, 0x0c,
0xb9, 0x0c, 0xe0, 0x2e, 0x2e, 0xc7, 0xee, 0x15, 0xcb, 0xf0, 0x16, 0x51, 0x20, 0x72, 0x8c, 0x6e,
0x43, 0xae, 0x63, 0x0f, 0x06, 0x26, 0xad, 0x2d, 0x71, 0xeb, 0xb5, 0xd8, 0x05, 0x70, 0xad, 0x56,
0x42, 0x93, 0xfa, 0x68, 0x17, 0xca, 0x7d, 0xd3, 0xa5, 0xba, 0x6b, 0x61, 0xc7, 0xed, 0xd9, 0xd4,
0xad, 0x2d, 0x73, 0x0f, 0x57, 0xe3, 0x3c, 0xdc, 0x37, 0x5d, 0x7a, 0xe0, 0x29, 0xb7, 0x12, 0x5a,
0xa9, 0x1f, 0x16, 0x30, 0x7f, 0xf6, 0xd1, 0x11, 0x19, 0xfa, 0x0e, 0x6b, 0xa5, 0xd9, 0xfe, 0xf6,
0x98, 0xb6, 0x67, 0xcf, 0xfc, 0xd9, 0x61, 0x01, 0xfa, 0x15, 0x9c, 0xeb, 0xdb, 0xd8, 0xf0, 0xdd,
0xe9, 0x9d, 0xde, 0xc8, 0x7a, 0x5c, 0x2b, 0x73, 0xa7, 0xd7, 0x62, 0x7f, 0xa4, 0x8d, 0x0d, 0xcf,
0x45, 0x83, 0x19, 0xb4, 0x12, 0xda, 0x4a, 0x7f, 0x5c, 0x88, 0x1e, 0xc1, 0x2a, 0x76, 0x9c, 0xfe,
0xe9, 0xb8, 0xf7, 0x0a, 0xf7, 0x7e, 0x3d, 0xce, 0xfb, 0x36, 0xb3, 0x19, 0x77, 0x8f, 0xf0, 0x84,
0xb4, 0x9e, 0x87, 0xec, 0x31, 0xee, 0x8f, 0x88, 0xfa, 0x3d, 0x58, 0x0a, 0xa5, 0x3a, 0xaa, 0x41,
0x7e, 0x40, 0x5c, 0x17, 0x77, 0x09, 0x47, 0x86, 0xa2, 0xe6, 0x4d, 0xd5, 0x32, 0x2c, 0x87, 0xd3,
0x5b, 0x1d, 0xf8, 0x86, 0x2c, 0x71, 0x99, 0xe1, 0x31, 0x19, 0xba, 0x2c, 0x5b, 0xa5, 0xa1, 0x9c,
0xa2, 0x2b, 0x50, 0xe2, 0xdb, 0x47, 0xf7, 0x9e, 0x33, 0xf4, 0xc8, 0x68, 0xcb, 0x5c, 0xf8, 0x50,
0x2a, 0xad, 0xc3, 0x92, 0xb3, 0xe5, 0xf8, 0x2a, 0x69, 0xae, 0x02, 0xce, 0x96, 0x23, 0x15, 0xd4,
0x1f, 0x41, 0x75, 0x3c, 0xdb, 0x51, 0x15, 0xd2, 0x8f, 0xc9, 0xa9, 0x7c, 0x1f, 0x1b, 0xa2, 0x55,
0xb9, 0x2c, 0xfe, 0x8e, 0xa2, 0x26, 0xd7, 0xf8, 0xd7, 0x94, 0x6f, 0xec, 0xa7, 0x39, 0xba, 0x0d,
0x19, 0x86, 0x9a, 0x12, 0x00, 0x95, 0x0d, 0x01, 0xa9, 0x1b, 0x1e, 0xa4, 0x6e, 0x1c, 0x7a, 0x90,
0x5a, 0x2f, 0x7c, 0xfd, 0x6c, 0x3d, 0xf1, 0xe5, 0xdf, 0xd7, 0x93, 0x1a, 0xb7, 0x40, 0xaf, 0xb0,
0xac, 0xc4, 0xa6, 0xa5, 0x9b, 0x86, 0x7c, 0x4f, 0x9e, 0xcf, 0x77, 0x0c, 0x74, 0x0f, 0xaa, 0x1d,
0xdb, 0x72, 0x89, 0xe5, 0x8e, 0x5c, 0x5d, 0x40, 0xb6, 0x84, 0xbd, 0xc9, 0xac, 0x69, 0x78, 0x8a,
0xfb, 0x5c, 0x4f, 0xab, 0x74, 0xa2, 0x02, 0x74, 0x17, 0xe0, 0x18, 0xf7, 0x4d, 0x03, 0x53, 0x7b,
0xe8, 0xd6, 0x32, 0x97, 0xd3, 0x53, 0xdd, 0x3c, 0xf4, 0x54, 0x1e, 0x38, 0x06, 0xa6, 0xa4, 0x9e,
0x61, 0xbf, 0x56, 0x0b, 0x59, 0xa2, 0xd7, 0xa0, 0x82, 0x1d, 0x47, 0x77, 0x29, 0xa6, 0x44, 0x6f,
0x9f, 0x52, 0xe2, 0x72, 0x30, 0x5c, 0xd6, 0x4a, 0xd8, 0x71, 0x0e, 0x98, 0xb4, 0xce, 0x84, 0xe8,
0x2a, 0x94, 0x19, 0xf0, 0x99, 0xb8, 0xaf, 0xf7, 0x88, 0xd9, 0xed, 0x51, 0x0e, 0x7a, 0x69, 0xad,
0x24, 0xa5, 0x2d, 0x2e, 0x54, 0x0d, 0x7f, 0x23, 0x70, 0xd0, 0x43, 0x08, 0x32, 0x06, 0xa6, 0x98,
0x07, 0x72, 0x59, 0xe3, 0x63, 0x26, 0x73, 0x30, 0xed, 0xc9, 0xf0, 0xf0, 0x31, 0x3a, 0x0f, 0x39,
0xe9, 0x36, 0xcd, 0xdd, 0xca, 0x19, 0xfb, 0x66, 0xce, 0xd0, 0x3e, 0x26, 0x1c, 0xe5, 0x0b, 0x9a,
0x98, 0xa8, 0xbf, 0x4d, 0xc1, 0xca, 0x04, 0x3c, 0x32, 0xbf, 0x3d, 0xec, 0xf6, 0xbc, 0x77, 0xb1,
0x31, 0xba, 0xc5, 0xfc, 0x62, 0x83, 0x0c, 0xe5, 0xb1, 0x54, 0x0b, 0x87, 0x48, 0x1c, 0xb9, 0x2d,
0xfe, 0x5c, 0x86, 0x46, 0x6a, 0xa3, 0x3d, 0xa8, 0xf6, 0xb1, 0x4b, 0x75, 0x01, 0x37, 0x7a, 0xe8,
0x88, 0x9a, 0x04, 0xd9, 0xfb, 0xd8, 0x03, 0x28, 0xb6, 0xd9, 0xa5, 0xa3, 0x72, 0x3f, 0x22, 0x45,
0x1a, 0xac, 0xb6, 0x4f, 0x3f, 0xc7, 0x16, 0x35, 0x2d, 0xa2, 0x4f, 0x7c, 0xb9, 0x57, 0x26, 0x9c,
0x36, 0x8f, 0x4d, 0x83, 0x58, 0x1d, 0xef, 0x93, 0x9d, 0xf3, 0x8d, 0xfd, 0x4f, 0xea, 0xaa, 0x1a,
0x94, 0xa3, 0x00, 0x8f, 0xca, 0x90, 0xa2, 0x27, 0x32, 0x00, 0x29, 0x7a, 0x82, 0xbe, 0x0f, 0x19,
0xb6, 0x48, 0xbe, 0xf8, 0xf2, 0x94, 0xd3, 0x55, 0xda, 0x1d, 0x9e, 0x3a, 0x44, 0xe3, 0x9a, 0xaa,
0xea, 0x67, 0x83, 0x0f, 0xfa, 0xe3, 0x5e, 0xd5, 0x6b, 0x50, 0x19, 0x43, 0xf5, 0xd0, 0xf7, 0x4b,
0x86, 0xbf, 0x9f, 0x5a, 0x81, 0x52, 0x04, 0xc2, 0xd5, 0xf3, 0xb0, 0x3a, 0x0d, 0x91, 0xd5, 0x9e,
0x2f, 0x8f, 0x20, 0x2b, 0xba, 0x09, 0x05, 0x1f, 0x92, 0x45, 0x36, 0x4e, 0xc6, 0xca, 0x53, 0xd6,
0x7c, 0x55, 0x96, 0x86, 0x6c, 0x5b, 0xf3, 0xfd, 0x90, 0xe2, 0x3f, 0x3c, 0x8f, 0x1d, 0xa7, 0x85,
0xdd, 0x9e, 0xfa, 0x09, 0xd4, 0xe2, 0xe0, 0x76, 0x6c, 0x19, 0x19, 0x7f, 0x1b, 0x9e, 0x87, 0xdc,
0x91, 0x3d, 0x1c, 0x60, 0xca, 0x9d, 0x95, 0x34, 0x39, 0x63, 0xdb, 0x53, 0x40, 0x6f, 0x9a, 0x8b,
0xc5, 0x44, 0xd5, 0xe1, 0x95, 0x58, 0xc8, 0x65, 0x26, 0xa6, 0x65, 0x10, 0x11, 0xcf, 0x92, 0x26,
0x26, 0x81, 0x23, 0xf1, 0x63, 0xc5, 0x84, 0xbd, 0xd6, 0xe5, 0x6b, 0xe5, 0xfe, 0x8b, 0x9a, 0x9c,
0xa9, 0xff, 0x2c, 0x40, 0x41, 0x23, 0xae, 0xc3, 0x30, 0x01, 0xd5, 0xa1, 0x48, 0x4e, 0x3a, 0x44,
0x90, 0xa1, 0x64, 0x2c, 0x99, 0x10, 0xda, 0x4d, 0x4f, 0x93, 0x9d, 0xe4, 0xbe, 0x19, 0xba, 0x21,
0x09, 0x5f, 0x3c, 0x77, 0x93, 0xe6, 0x61, 0xc6, 0x77, 0xcb, 0x63, 0x7c, 0xe9, 0xd8, 0xc3, 0x5b,
0x58, 0x8d, 0x51, 0xbe, 0x1b, 0x92, 0xf2, 0x65, 0xe6, 0xbc, 0x2c, 0xc2, 0xf9, 0x1a, 0x11, 0xce,
0x97, 0x9d, 0xb3, 0xcc, 0x18, 0xd2, 0xd7, 0x88, 0x90, 0xbe, 0xdc, 0x1c, 0x27, 0x31, 0xac, 0xef,
0x96, 0xc7, 0xfa, 0xf2, 0x73, 0x96, 0x3d, 0x46, 0xfb, 0xee, 0x46, 0x69, 0x9f, 0xa0, 0x6c, 0x57,
0x62, 0xad, 0x63, 0x79, 0xdf, 0x8f, 0x43, 0xbc, 0xaf, 0x18, 0x4b, 0xba, 0x84, 0x93, 0x29, 0xc4,
0xaf, 0x11, 0x21, 0x7e, 0x30, 0x27, 0x06, 0x31, 0xcc, 0xef, 0xbd, 0x30, 0xf3, 0x5b, 0x8a, 0x25,
0x8f, 0x72, 0xd3, 0x4c, 0xa3, 0x7e, 0x77, 0x7c, 0xea, 0xb7, 0x1c, 0xcb, 0x5d, 0xe5, 0x1a, 0xc6,
0xb9, 0xdf, 0xde, 0x04, 0xf7, 0x13, 0x5c, 0xed, 0xb5, 0x58, 0x17, 0x73, 0xc8, 0xdf, 0xde, 0x04,
0xf9, 0x2b, 0xcf, 0x71, 0x38, 0x87, 0xfd, 0xfd, 0x7a, 0x3a, 0xfb, 0x8b, 0xe7, 0x67, 0xf2, 0x67,
0x2e, 0x46, 0xff, 0xf4, 0x18, 0xfa, 0x57, 0xe5, 0xee, 0xdf, 0x88, 0x75, 0x7f, 0x76, 0xfe, 0x77,
0x8d, 0x1d, 0xb3, 0x63, 0xc0, 0xc1, 0xa0, 0x8a, 0x0c, 0x87, 0xf6, 0x50, 0x52, 0x2b, 0x31, 0x51,
0x5f, 0x67, 0x07, 0x7f, 0x00, 0x12, 0x33, 0xb8, 0x22, 0x3f, 0x12, 0x42, 0xc0, 0xa0, 0xfe, 0x29,
0x19, 0xd8, 0xf2, 0xb3, 0x32, 0x4c, 0x1a, 0x8a, 0x92, 0x34, 0x84, 0x28, 0x64, 0x2a, 0x4a, 0x21,
0xd7, 0x61, 0x89, 0x41, 0xfd, 0x18, 0x3b, 0xc4, 0x8e, 0xc7, 0x0e, 0xd1, 0x75, 0x58, 0xe1, 0x67,
0xb9, 0x20, 0x9a, 0x12, 0xdf, 0x33, 0xfc, 0x98, 0xaa, 0xb0, 0x07, 0x62, 0x73, 0x0a, 0xa0, 0x7f,
0x0b, 0xce, 0x85, 0x74, 0xfd, 0x23, 0x44, 0x50, 0xa2, 0xaa, 0xaf, 0xbd, 0x2d, 0xcf, 0x92, 0x0f,
0x83, 0x00, 0x05, 0xcc, 0x13, 0x41, 0xa6, 0x63, 0x1b, 0x44, 0x02, 0x3c, 0x1f, 0x33, 0x36, 0xda,
0xb7, 0xbb, 0x12, 0xc6, 0xd9, 0x90, 0x69, 0xf9, 0x28, 0x58, 0x14, 0x20, 0xa7, 0xfe, 0x25, 0x19,
0xf8, 0x0b, 0xc8, 0xe8, 0x34, 0xde, 0x98, 0xfc, 0xdf, 0xf0, 0xc6, 0xd4, 0xb7, 0xe6, 0x8d, 0xe1,
0x03, 0x36, 0x1d, 0x3d, 0x60, 0xff, 0x9d, 0x0c, 0xbe, 0xb0, 0xcf, 0x02, 0xbf, 0x5d, 0x44, 0x82,
0xd3, 0x32, 0xcb, 0xbf, 0x97, 0x3c, 0x2d, 0x25, 0xb7, 0xcf, 0xf1, 0xf7, 0x46, 0xb9, 0x7d, 0x5e,
0x9c, 0x9f, 0x7c, 0x82, 0x6e, 0x43, 0x91, 0x37, 0x5d, 0x74, 0xdb, 0x71, 0x25, 0xe0, 0x5e, 0x08,
0xaf, 0x55, 0xf4, 0x56, 0x36, 0xf6, 0x99, 0xce, 0x9e, 0xe3, 0x6a, 0x05, 0x47, 0x8e, 0x42, 0x44,
0xa0, 0x18, 0xe1, 0xa3, 0x17, 0xa1, 0xc8, 0x7e, 0xbd, 0xeb, 0xe0, 0x0e, 0xe1, 0xe0, 0x59, 0xd4,
0x02, 0x81, 0xfa, 0x08, 0xd0, 0x24, 0x7c, 0xa3, 0x16, 0xe4, 0xc8, 0x31, 0xb1, 0x28, 0xfb, 0x6a,
0x2c, 0xdc, 0xe7, 0xa7, 0x90, 0x3d, 0x62, 0xd1, 0x7a, 0x8d, 0x05, 0xf9, 0x5f, 0xcf, 0xd6, 0xab,
0x42, 0xfb, 0x4d, 0x7b, 0x60, 0x52, 0x32, 0x70, 0xe8, 0xa9, 0x26, 0xed, 0xd5, 0x2f, 0x52, 0x8c,
0x79, 0x45, 0xa0, 0x7d, 0x6a, 0x6c, 0xbd, 0x04, 0x4a, 0x85, 0x58, 0xf7, 0x62, 0xf1, 0x5e, 0x03,
0xe8, 0x62, 0x57, 0x7f, 0x82, 0x2d, 0x4a, 0x0c, 0x19, 0xf4, 0x90, 0x04, 0x29, 0x50, 0x60, 0xb3,
0x91, 0x4b, 0x0c, 0x59, 0x00, 0xf8, 0xf3, 0xd0, 0x3a, 0xf3, 0xdf, 0x6d, 0x9d, 0xd1, 0x28, 0x17,
0xc6, 0xa3, 0xfc, 0xbb, 0x54, 0x90, 0x25, 0x01, 0x49, 0xfd, 0xff, 0x8b, 0xc3, 0xef, 0x79, 0xe5,
0x1a, 0x3d, 0x63, 0xd1, 0x01, 0xac, 0xf8, 0x59, 0xaa, 0x8f, 0x78, 0xf6, 0x7a, 0xfb, 0x6e, 0xd1,
0x34, 0xaf, 0x1e, 0x47, 0xc5, 0x2e, 0xfa, 0x39, 0xbc, 0x3c, 0x86, 0x40, 0xbe, 0xeb, 0xd4, 0x82,
0x40, 0xf4, 0x52, 0x14, 0x88, 0x3c, 0xcf, 0x41, 0xac, 0xd2, 0xdf, 0x31, 0x37, 0x76, 0x58, 0x31,
0x14, 0x66, 0x0c, 0x53, 0xbf, 0xfe, 0x15, 0x28, 0x0d, 0x09, 0x65, 0xf5, 0x79, 0xa4, 0xdc, 0x5c,
0x16, 0x42, 0x59, 0xc4, 0xee, 0xc3, 0x4b, 0x53, 0x99, 0x03, 0xfa, 0x21, 0x14, 0x03, 0xd2, 0x91,
0x8c, 0xa9, 0xdc, 0xfc, 0x6a, 0x24, 0xd0, 0x55, 0xff, 0x9c, 0x0c, 0x5c, 0x46, 0xeb, 0x9b, 0x26,
0xe4, 0x86, 0xc4, 0x1d, 0xf5, 0x45, 0xc5, 0x51, 0xde, 0x7a, 0x6b, 0x31, 0xce, 0xc1, 0xa4, 0xa3,
0x3e, 0xd5, 0xa4, 0xb1, 0xfa, 0x08, 0x72, 0x42, 0x82, 0x96, 0x20, 0xff, 0x60, 0xf7, 0xde, 0xee,
0xde, 0x47, 0xbb, 0xd5, 0x04, 0x02, 0xc8, 0x6d, 0x37, 0x1a, 0xcd, 0xfd, 0xc3, 0x6a, 0x12, 0x15,
0x21, 0xbb, 0x5d, 0xdf, 0xd3, 0x0e, 0xab, 0x29, 0x26, 0xd6, 0x9a, 0x1f, 0x34, 0x1b, 0x87, 0xd5,
0x34, 0x5a, 0x81, 0x92, 0x18, 0xeb, 0x77, 0xf7, 0xb4, 0x0f, 0xb7, 0x0f, 0xab, 0x99, 0x90, 0xe8,
0xa0, 0xb9, 0xfb, 0x7e, 0x53, 0xab, 0x66, 0xd5, 0x1f, 0xb0, 0x92, 0x26, 0x86, 0xa5, 0x04, 0xc5,
0x4b, 0x32, 0x54, 0xbc, 0xa8, 0x7f, 0x4c, 0x81, 0x12, 0x4f, 0x3d, 0xd0, 0x07, 0x63, 0x0b, 0xdf,
0x3a, 0x03, 0x6f, 0x19, 0x5b, 0x3d, 0xba, 0x0a, 0xe5, 0x21, 0x39, 0x22, 0xb4, 0xd3, 0x13, 0x54,
0x48, 0x1c, 0x6c, 0x25, 0xad, 0x24, 0xa5, 0xdc, 0xc8, 0x15, 0x6a, 0x9f, 0x92, 0x0e, 0xd5, 0x45,
0x1d, 0x25, 0x36, 0x5d, 0x91, 0xa9, 0x31, 0xe9, 0x81, 0x10, 0xaa, 0x9f, 0x9c, 0x29, 0x96, 0x45,
0xc8, 0x6a, 0xcd, 0x43, 0xed, 0x17, 0xd5, 0x34, 0x42, 0x50, 0xe6, 0x43, 0xfd, 0x60, 0x77, 0x7b,
0xff, 0xa0, 0xb5, 0xc7, 0x62, 0x79, 0x0e, 0x2a, 0x5e, 0x2c, 0x3d, 0x61, 0x56, 0xfd, 0x4f, 0x12,
0x2a, 0x63, 0x09, 0x82, 0xb6, 0x20, 0x2b, 0xe8, 0x74, 0x5c, 0xd3, 0x9d, 0xe7, 0xb7, 0xcc, 0x26,
0xa1, 0x8a, 0xde, 0x81, 0x02, 0x91, 0x7d, 0x82, 0x69, 0x89, 0x28, 0xfa, 0x1b, 0x5e, 0x27, 0x41,
0x9a, 0xfa, 0x16, 0xe8, 0x5d, 0x28, 0xfa, 0x99, 0x2e, 0x6b, 0xb8, 0x57, 0x27, 0xcd, 0x7d, 0x8c,
0x90, 0xf6, 0x81, 0x0d, 0xba, 0x13, 0x70, 0xb2, 0xcc, 0x24, 0x89, 0x97, 0xe6, 0x42, 0x41, 0x1a,
0x7b, 0xfa, 0x6a, 0x03, 0x96, 0x42, 0xeb, 0x41, 0x17, 0xa0, 0x38, 0xc0, 0x27, 0xb2, 0xff, 0x24,
0x3a, 0x08, 0x85, 0x01, 0x3e, 0x11, 0xad, 0xa7, 0x97, 0x21, 0xcf, 0x1e, 0x76, 0xb1, 0x40, 0x9b,
0xb4, 0x96, 0x1b, 0xe0, 0x93, 0x9f, 0x62, 0x57, 0xfd, 0x18, 0xca, 0xd1, 0xde, 0x0b, 0xdb, 0x89,
0x43, 0x7b, 0x64, 0x19, 0xdc, 0x47, 0x56, 0x13, 0x13, 0x74, 0x13, 0xb2, 0xc7, 0xb6, 0x00, 0xab,
0xe9, 0x29, 0xfb, 0xd0, 0xa6, 0x24, 0xd4, 0xbb, 0x11, 0xda, 0xea, 0xe7, 0x90, 0xe5, 0xe0, 0xc3,
0x80, 0x84, 0x77, 0x51, 0x24, 0x1f, 0x65, 0x63, 0xf4, 0x31, 0x00, 0xa6, 0x74, 0x68, 0xb6, 0x47,
0x81, 0xe3, 0xf5, 0xe9, 0xe0, 0xb5, 0xed, 0xe9, 0xd5, 0x2f, 0x4a, 0x14, 0x5b, 0x0d, 0x4c, 0x43,
0x48, 0x16, 0x72, 0xa8, 0xee, 0x42, 0x39, 0x6a, 0x1b, 0xee, 0x67, 0x2e, 0x4f, 0xe9, 0x67, 0xfa,
0x9c, 0xc7, 0x67, 0x4c, 0x69, 0xd1, 0x31, 0xe3, 0x13, 0xf5, 0x69, 0x12, 0x0a, 0x87, 0x27, 0x72,
0x5b, 0xc7, 0x34, 0x6b, 0x02, 0xd3, 0x54, 0xb8, 0x35, 0x21, 0xba, 0x3f, 0x69, 0xbf, 0xa7, 0xf4,
0x9e, 0x9f, 0xb8, 0x99, 0x45, 0x8b, 0x47, 0xaf, 0xb9, 0x26, 0xc1, 0xea, 0x6d, 0x28, 0xfa, 0xbb,
0x8a, 0x11, 0x7b, 0x6c, 0x18, 0x43, 0xe2, 0xba, 0x72, 0x6d, 0xde, 0x94, 0xf7, 0xfe, 0xec, 0x27,
0xb2, 0xf9, 0x91, 0xd6, 0xc4, 0x44, 0x35, 0xa0, 0x32, 0x76, 0x6c, 0xa1, 0xb7, 0x21, 0xef, 0x8c,
0xda, 0xba, 0x17, 0x9e, 0xb1, 0xe4, 0xf1, 0x48, 0xde, 0xa8, 0xdd, 0x37, 0x3b, 0xf7, 0xc8, 0xa9,
0xf7, 0x63, 0x9c, 0x51, 0xfb, 0x9e, 0x88, 0xa2, 0x78, 0x4b, 0x2a, 0xfc, 0x96, 0x63, 0x28, 0x78,
0x9b, 0x02, 0xfd, 0x24, 0x9c, 0x27, 0x5e, 0x47, 0x38, 0xf6, 0x28, 0x95, 0xee, 0x43, 0x69, 0x72,
0x1d, 0x56, 0x5c, 0xb3, 0x6b, 0x11, 0x43, 0x0f, 0x4a, 0x0b, 0xfe, 0xb6, 0x82, 0x56, 0x11, 0x0f,
0xee, 0x7b, 0x75, 0x85, 0xfa, 0x2c, 0x09, 0x05, 0x2f, 0x61, 0xa7, 0xee, 0xbb, 0xc8, 0x8f, 0x49,
0x9d, 0xfd, 0xc7, 0xc4, 0x35, 0x5a, 0xbd, 0x8e, 0x77, 0xe6, 0xcc, 0x1d, 0xef, 0x37, 0x01, 0x51,
0x9b, 0xe2, 0xbe, 0x7e, 0x6c, 0x53, 0xd3, 0xea, 0xea, 0x22, 0x9a, 0x82, 0x32, 0x55, 0xf9, 0x93,
0x87, 0xfc, 0xc1, 0x3e, 0x0f, 0xec, 0x6f, 0x92, 0x50, 0xf0, 0x0f, 0xbf, 0xb3, 0xb6, 0xdb, 0xce,
0x43, 0x4e, 0xe2, 0xbb, 0xe8, 0xb7, 0xc9, 0x99, 0xdf, 0xf9, 0xcd, 0x84, 0x3a, 0xbf, 0x0a, 0x14,
0x06, 0x84, 0x62, 0xce, 0x00, 0x44, 0xf9, 0xe6, 0xcf, 0xaf, 0xdf, 0x81, 0xa5, 0x50, 0xe7, 0x93,
0xa5, 0xd6, 0x6e, 0xf3, 0xa3, 0x6a, 0x42, 0xc9, 0x3f, 0xfd, 0xea, 0x72, 0x7a, 0x97, 0x3c, 0x61,
0x9b, 0x52, 0x6b, 0x36, 0x5a, 0xcd, 0xc6, 0xbd, 0x6a, 0x52, 0x59, 0x7a, 0xfa, 0xd5, 0xe5, 0xbc,
0x46, 0x78, 0x03, 0x65, 0xeb, 0x0b, 0x80, 0xca, 0x76, 0xbd, 0xb1, 0xc3, 0x0e, 0x25, 0xb3, 0x83,
0x65, 0x5b, 0x29, 0xc3, 0x6b, 0xde, 0x99, 0x17, 0xa5, 0xca, 0xec, 0xae, 0x1a, 0xba, 0x0b, 0x59,
0x5e, 0x0e, 0xa3, 0xd9, 0x37, 0xa7, 0xca, 0x9c, 0x36, 0x1b, 0xfb, 0x31, 0x7c, 0xd7, 0xce, 0xbc,
0x4a, 0x55, 0x66, 0x77, 0xdd, 0x90, 0x06, 0xc5, 0xa0, 0x9e, 0x9d, 0x7f, 0xb5, 0xaa, 0x2c, 0xd0,
0x89, 0x63, 0x3e, 0x03, 0xb6, 0x3e, 0xff, 0xaa, 0x51, 0x59, 0x00, 0x57, 0xd0, 0x7d, 0xc8, 0x7b,
0x75, 0xd0, 0xbc, 0xcb, 0x4f, 0x65, 0x6e, 0x97, 0x8c, 0x7d, 0x02, 0x51, 0xaf, 0xce, 0xbe, 0xc9,
0x55, 0xe6, 0xb4, 0xfc, 0xd0, 0x0e, 0xe4, 0x24, 0x05, 0x9d, 0x73, 0xa1, 0xa9, 0xcc, 0xeb, 0x7a,
0xb1, 0xa0, 0x05, 0x8d, 0x80, 0xf9, 0xf7, 0xd3, 0xca, 0x02, 0xdd, 0x4c, 0xf4, 0x00, 0x20, 0x54,
0x9d, 0x2e, 0x70, 0xf1, 0xac, 0x2c, 0xd2, 0xa5, 0x44, 0x7b, 0x50, 0xf0, 0xab, 0x90, 0xb9, 0xd7,
0xc0, 0xca, 0xfc, 0x76, 0x21, 0x7a, 0x04, 0xa5, 0x28, 0xfd, 0x5e, 0xec, 0x72, 0x57, 0x59, 0xb0,
0x0f, 0xc8, 0xfc, 0x47, 0xb9, 0xf8, 0x62, 0x97, 0xbd, 0xca, 0x82, 0x6d, 0x41, 0xf4, 0x29, 0xac,
0x4c, 0x72, 0xe5, 0xc5, 0xef, 0x7e, 0x95, 0x33, 0x34, 0x0a, 0xd1, 0x00, 0xd0, 0x14, 0x8e, 0x7d,
0x86, 0xab, 0x60, 0xe5, 0x2c, 0x7d, 0xc3, 0x7a, 0xf3, 0xeb, 0xe7, 0x6b, 0xc9, 0x6f, 0x9e, 0xaf,
0x25, 0xff, 0xf1, 0x7c, 0x2d, 0xf9, 0xe5, 0x8b, 0xb5, 0xc4, 0x37, 0x2f, 0xd6, 0x12, 0x7f, 0x7b,
0xb1, 0x96, 0xf8, 0xe5, 0x1b, 0x5d, 0x93, 0xf6, 0x46, 0xed, 0x8d, 0x8e, 0x3d, 0xd8, 0x0c, 0xff,
0x4f, 0x65, 0xda, 0x7f, 0x67, 0xda, 0x39, 0x7e, 0xbc, 0xdc, 0xf8, 0x6f, 0x00, 0x00, 0x00, 0xff,
0xff, 0x21, 0x92, 0x34, 0xc9, 0x5b, 0x23, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -4413,6 +4422,11 @@ func (m *RequestInitChain) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.InitialHeight != 0 {
i = encodeVarintTypes(dAtA, i, uint64(m.InitialHeight))
i--
dAtA[i] = 0x30
}
if len(m.AppStateBytes) > 0 {
i -= len(m.AppStateBytes)
copy(dAtA[i:], m.AppStateBytes)
@ -6776,6 +6790,9 @@ func (m *RequestInitChain) Size() (n int) {
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
if m.InitialHeight != 0 {
n += 1 + sovTypes(uint64(m.InitialHeight))
}
return n
}
@ -8862,6 +8879,25 @@ func (m *RequestInitChain) Unmarshal(dAtA []byte) error {
m.AppStateBytes = []byte{}
}
iNdEx = postIndex
case 6:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field InitialHeight", wireType)
}
m.InitialHeight = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.InitialHeight |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:])


+ 4
- 0
cmd/tendermint/commands/testnet.go View File

@ -22,6 +22,7 @@ import (
var (
nValidators int
nNonValidators int
initialHeight int64
configFile string
outputDir string
nodeDirPrefix string
@ -50,6 +51,8 @@ func init() {
"Directory to store initialization data for the testnet")
TestnetFilesCmd.Flags().StringVar(&nodeDirPrefix, "node-dir-prefix", "node",
"Prefix the directory name for each node with (node results in node0, node1, ...)")
TestnetFilesCmd.Flags().Int64Var(&initialHeight, "initial-height", 0,
"Initial height of the first block")
TestnetFilesCmd.Flags().BoolVar(&populatePersistentPeers, "populate-persistent-peers", true,
"Update config of each node with the list of persistent peers build using either"+
@ -175,6 +178,7 @@ func testnetFiles(cmd *cobra.Command, args []string) error {
ChainID: "chain-" + tmrand.Str(6),
ConsensusParams: types.DefaultConsensusParams(),
GenesisTime: tmtime.Now(),
InitialHeight: initialHeight,
Validators: genVals,
}


+ 1
- 0
config/toml.go View File

@ -476,6 +476,7 @@ func ResetTestRootWithChainID(testName string, chainID string) *Config {
var testGenesisFmt = `{
"genesis_time": "2018-10-10T08:20:13.695936996Z",
"chain_id": "%s",
"initial_height": "1",
"validators": [
{
"pub_key": {


+ 8
- 5
consensus/common_test.go View File

@ -430,7 +430,7 @@ func randState(nValidators int) (*State, []*validatorStub) {
return cs, vss
}
func randStateWithEvpool(nValidators int) (*State, []*validatorStub, *evidence.Pool) {
func randStateWithEvpool(t *testing.T, nValidators int) (*State, []*validatorStub, *evidence.Pool) {
state, privVals := randGenesisState(nValidators, false, 10)
vss := make([]*validatorStub, nValidators)
@ -451,7 +451,9 @@ func randStateWithEvpool(nValidators int) (*State, []*validatorStub, *evidence.P
mempool.EnableTxsAvailable()
}
stateDB := dbm.NewMemDB()
evpool, _ := evidence.NewPool(stateDB, evidenceDB, blockStore)
sm.SaveState(stateDB, state)
evpool, err := evidence.NewPool(stateDB, evidenceDB, blockStore)
require.NoError(t, err)
blockExec := sm.NewBlockExecutor(stateDB, log.TestingLogger(), proxyAppConnCon, mempool, evpool)
cs := NewState(config.Consensus, state, blockExec, blockStore, mempool, evpool)
cs.SetLogger(log.TestingLogger().With("module", "consensus"))
@ -821,9 +823,10 @@ func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.G
sort.Sort(types.PrivValidatorsByAddress(privValidators))
return &types.GenesisDoc{
GenesisTime: tmtime.Now(),
ChainID: config.ChainID(),
Validators: validators,
GenesisTime: tmtime.Now(),
InitialHeight: 1,
ChainID: config.ChainID(),
Validators: validators,
}, privValidators
}


+ 31
- 3
consensus/reactor.go View File

@ -249,6 +249,14 @@ func (conR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
case StateChannel:
switch msg := msg.(type) {
case *NewRoundStepMessage:
conR.conS.mtx.Lock()
initialHeight := conR.conS.state.InitialHeight
conR.conS.mtx.Unlock()
if err = msg.ValidateHeight(initialHeight); err != nil {
conR.Logger.Error("Peer sent us invalid msg", "peer", src, "msg", msg, "err", err)
conR.Switch.StopPeerForError(src, err)
return
}
ps.ApplyNewRoundStepMessage(msg)
case *NewValidBlockMessage:
ps.ApplyNewValidBlockMessage(msg)
@ -1435,9 +1443,29 @@ func (m *NewRoundStepMessage) ValidateBasic() error {
// NOTE: SecondsSinceStartTime may be negative
if (m.Height == 1 && m.LastCommitRound != -1) ||
(m.Height > 1 && m.LastCommitRound < 0) {
return errors.New("invalid LastCommitRound (for 1st block: -1, for others: >= 0)")
// LastCommitRound will be -1 for the initial height, but we don't know what height this is
// since it can be specified in genesis. The reactor will have to validate this via
// ValidateHeight().
if m.LastCommitRound < -1 {
return errors.New("invalid LastCommitRound (cannot be < -1)")
}
return nil
}
// ValidateHeight validates the height given the chain's initial height.
func (m *NewRoundStepMessage) ValidateHeight(initialHeight int64) error {
if m.Height < initialHeight {
return fmt.Errorf("invalid Height %v (lower than initial height %v)",
m.Height, initialHeight)
}
if m.Height == initialHeight && m.LastCommitRound != -1 {
return fmt.Errorf("invalid LastCommitRound %v (must be -1 for initial height %v)",
m.LastCommitRound, initialHeight)
}
if m.Height > initialHeight && m.LastCommitRound < 0 {
return fmt.Errorf("LastCommitRound can only be negative for initial height %v", // nolint
initialHeight)
}
return nil
}


+ 44
- 3
consensus/reactor_test.go View File

@ -710,8 +710,9 @@ func TestNewRoundStepMessageValidateBasic(t *testing.T) {
{true, -1, 0, 0, "Negative round", cstypes.RoundStepNewHeight},
{true, 0, 0, -1, "Negative height", cstypes.RoundStepNewHeight},
{true, 0, 0, 0, "Invalid Step", cstypes.RoundStepCommit + 1},
{true, 0, 0, 1, "H == 1 but LCR != -1 ", cstypes.RoundStepNewHeight},
{true, 0, -1, 2, "H > 1 but LCR < 0", cstypes.RoundStepNewHeight},
// The following cases will be handled by ValidateHeight
{false, 0, 0, 1, "H == 1 but LCR != -1 ", cstypes.RoundStepNewHeight},
{false, 0, -1, 2, "H > 1 but LCR < 0", cstypes.RoundStepNewHeight},
}
for _, tc := range testCases {
@ -724,7 +725,47 @@ func TestNewRoundStepMessageValidateBasic(t *testing.T) {
LastCommitRound: tc.messageLastCommitRound,
}
assert.Equal(t, tc.expectErr, message.ValidateBasic() != nil, "Validate Basic had an unexpected result")
err := message.ValidateBasic()
if tc.expectErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestNewRoundStepMessageValidateHeight(t *testing.T) {
initialHeight := int64(10)
testCases := []struct { // nolint: maligned
expectErr bool
messageLastCommitRound int32
messageHeight int64
testName string
}{
{false, 0, 11, "Valid Message"},
{true, 0, -1, "Negative height"},
{true, 0, 0, "Zero height"},
{true, 0, 10, "Initial height but LCR != -1 "},
{true, -1, 11, "Normal height but LCR < 0"},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.testName, func(t *testing.T) {
message := NewRoundStepMessage{
Height: tc.messageHeight,
Round: 0,
Step: cstypes.RoundStepNewHeight,
LastCommitRound: tc.messageLastCommitRound,
}
err := message.ValidateHeight(initialHeight)
if tc.expectErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}


+ 23
- 7
consensus/replay.go View File

@ -120,14 +120,21 @@ func (cs *State) catchupReplay(csHeight int64) error {
// Search for last height marker.
//
// Ignore data corruption errors in previous heights because we only care about last height
gr, found, err = cs.wal.SearchForEndHeight(csHeight-1, &WALSearchOptions{IgnoreDataCorruptionErrors: true})
if csHeight < cs.state.InitialHeight {
return fmt.Errorf("cannot replay height %v, below initial height %v", csHeight, cs.state.InitialHeight)
}
endHeight := csHeight - 1
if csHeight == cs.state.InitialHeight {
endHeight = 0
}
gr, found, err = cs.wal.SearchForEndHeight(endHeight, &WALSearchOptions{IgnoreDataCorruptionErrors: true})
if err == io.EOF {
cs.Logger.Error("Replay: wal.group.Search returned EOF", "#ENDHEIGHT", csHeight-1)
cs.Logger.Error("Replay: wal.group.Search returned EOF", "#ENDHEIGHT", endHeight)
} else if err != nil {
return err
}
if !found {
return fmt.Errorf("cannot replay height %d. WAL does not contain #ENDHEIGHT for %d", csHeight, csHeight-1)
return fmt.Errorf("cannot replay height %d. WAL does not contain #ENDHEIGHT for %d", csHeight, endHeight)
}
defer gr.Close()
@ -254,7 +261,7 @@ func (h *Handshaker) Handshake(proxyApp proxy.AppConns) error {
"protocol-version", res.AppVersion,
)
// Only set the version if we're starting from zero.
// Only set the version if there is no existing state.
if h.initialState.LastBlockHeight == 0 {
h.initialState.Version.Consensus.App = res.AppVersion
}
@ -306,6 +313,7 @@ func (h *Handshaker) ReplayBlocks(
req := abci.RequestInitChain{
Time: h.genDoc.GenesisTime,
ChainId: h.genDoc.ChainID,
InitialHeight: h.genDoc.InitialHeight,
ConsensusParams: csParams,
Validators: nextVals,
AppStateBytes: h.genDoc.AppState,
@ -353,7 +361,11 @@ func (h *Handshaker) ReplayBlocks(
assertAppHashEqualsOneFromState(appHash, state)
return appHash, nil
case appBlockHeight < storeBlockBase-1:
case appBlockHeight == 0 && state.InitialHeight < storeBlockBase:
// the app has no state, and the block store is truncated above the initial height
return appHash, sm.ErrAppBlockHeightTooLow{AppHeight: appBlockHeight, StoreBase: storeBlockBase}
case appBlockHeight > 0 && appBlockHeight < storeBlockBase-1:
// the app is too far behind truncated store (can be 1 behind since we replay the next)
return appHash, sm.ErrAppBlockHeightTooLow{AppHeight: appBlockHeight, StoreBase: storeBlockBase}
@ -444,7 +456,11 @@ func (h *Handshaker) replayBlocks(
if mutateState {
finalBlock--
}
for i := appBlockHeight + 1; i <= finalBlock; i++ {
firstBlock := appBlockHeight + 1
if firstBlock == 1 {
firstBlock = state.InitialHeight
}
for i := firstBlock; i <= finalBlock; i++ {
h.logger.Info("Applying block", "height", i)
block := h.store.LoadBlock(i)
// Extra check to ensure the app was not changed in a way it shouldn't have.
@ -452,7 +468,7 @@ func (h *Handshaker) replayBlocks(
assertAppHashEqualsOneFromBlock(appHash, block)
}
appHash, err = sm.ExecCommitBlock(proxyApp.Consensus(), block, h.logger, h.stateDB)
appHash, err = sm.ExecCommitBlock(proxyApp.Consensus(), block, h.logger, h.stateDB, h.genDoc.InitialHeight)
if err != nil {
return nil, err
}


+ 2
- 1
consensus/replay_test.go View File

@ -153,7 +153,8 @@ LOOP:
logger := log.NewNopLogger()
blockDB := dbm.NewMemDB()
stateDB := blockDB
state, _ := sm.MakeGenesisStateFromFile(consensusReplayConfig.GenesisFile())
state, err := sm.MakeGenesisStateFromFile(consensusReplayConfig.GenesisFile())
require.NoError(t, err)
privValidator := loadPrivValidator(consensusReplayConfig)
cs := newStateWithConfigAndBlockStore(
consensusReplayConfig,


+ 35
- 26
consensus/state.go View File

@ -555,27 +555,33 @@ func (cs *State) updateToState(state sm.State) {
panic(fmt.Sprintf("updateToState() expected state height of %v but found %v",
cs.Height, state.LastBlockHeight))
}
if !cs.state.IsEmpty() && cs.state.LastBlockHeight+1 != cs.Height {
// This might happen when someone else is mutating cs.state.
// Someone forgot to pass in state.Copy() somewhere?!
panic(fmt.Sprintf("Inconsistent cs.state.LastBlockHeight+1 %v vs cs.Height %v",
cs.state.LastBlockHeight+1, cs.Height))
}
// If state isn't further out than cs.state, just ignore.
// This happens when SwitchToConsensus() is called in the reactor.
// We don't want to reset e.g. the Votes, but we still want to
// signal the new round step, because other services (eg. txNotifier)
// depend on having an up-to-date peer state!
if !cs.state.IsEmpty() && (state.LastBlockHeight <= cs.state.LastBlockHeight) {
cs.Logger.Info(
"Ignoring updateToState()",
"newHeight",
state.LastBlockHeight+1,
"oldHeight",
cs.state.LastBlockHeight+1)
cs.newStep()
return
if !cs.state.IsEmpty() {
if cs.state.LastBlockHeight > 0 && cs.state.LastBlockHeight+1 != cs.Height {
// This might happen when someone else is mutating cs.state.
// Someone forgot to pass in state.Copy() somewhere?!
panic(fmt.Sprintf("Inconsistent cs.state.LastBlockHeight+1 %v vs cs.Height %v",
cs.state.LastBlockHeight+1, cs.Height))
}
if cs.state.LastBlockHeight > 0 && cs.Height == cs.state.InitialHeight {
panic(fmt.Sprintf("Inconsistent cs.state.LastBlockHeight %v, expected 0 for initial height %v",
cs.state.LastBlockHeight, cs.state.InitialHeight))
}
// If state isn't further out than cs.state, just ignore.
// This happens when SwitchToConsensus() is called in the reactor.
// We don't want to reset e.g. the Votes, but we still want to
// signal the new round step, because other services (eg. txNotifier)
// depend on having an up-to-date peer state!
if state.LastBlockHeight <= cs.state.LastBlockHeight {
cs.Logger.Info(
"Ignoring updateToState()",
"newHeight",
state.LastBlockHeight+1,
"oldHeight",
cs.state.LastBlockHeight+1)
cs.newStep()
return
}
}
// Reset fields based on state.
@ -595,13 +601,16 @@ func (cs *State) updateToState(state sm.State) {
case cs.LastCommit == nil:
// NOTE: when Tendermint starts, it has no votes. reconstructLastCommit
// must be called to reconstruct LastCommit from SeenCommit.
panic(fmt.Sprintf("LastCommit cannot be empty in heights > 1 (H:%d)",
panic(fmt.Sprintf("LastCommit cannot be empty after initial block (H:%d)",
state.LastBlockHeight+1,
))
}
// Next desired block height
height := state.LastBlockHeight + 1
if height == 1 {
height = state.InitialHeight
}
// RoundState fields
cs.updateHeight(height)
@ -933,7 +942,7 @@ func (cs *State) enterNewRound(height int64, round int32) {
// needProofBlock returns true on the first height (so the genesis app hash is signed right away)
// and where the last block (height-1) caused the app hash to change
func (cs *State) needProofBlock(height int64) bool {
if height == 1 {
if height == cs.state.InitialHeight {
return true
}
@ -1090,7 +1099,7 @@ func (cs *State) createProposalBlock() (block *types.Block, blockParts *types.Pa
var commit *types.Commit
switch {
case cs.Height == 1:
case cs.Height == cs.state.InitialHeight:
// We're creating a proposal for the first block.
// The commit is empty, but not nil.
commit = types.NewCommit(0, 0, types.BlockID{}, nil)
@ -1607,7 +1616,7 @@ func (cs *State) recordMetrics(height int64, block *types.Block) {
// height=0 -> MissingValidators and MissingValidatorsPower are both 0.
// Remember that the first LastCommit is intentionally empty, so it's not
// fair to increment missing validators number.
if height > 1 {
if height > cs.state.InitialHeight {
// Sanity check that commit size matches validator set size - only applies
// after first block.
var (
@ -1818,7 +1827,7 @@ func (cs *State) tryAddVote(vote *types.Vote, peerID p2p.ID) (bool, error) {
return added, err
}
var timestamp time.Time
if voteErr.VoteA.Height == 1 {
if voteErr.VoteA.Height == cs.state.InitialHeight {
timestamp = cs.state.LastBlockTime // genesis time
} else {
timestamp = sm.MedianTime(cs.LastCommit.MakeCommit(), cs.LastValidators)


+ 2
- 2
consensus/state_test.go View File

@ -620,7 +620,7 @@ func TestStateLockPOLRelockThenChangeLock(t *testing.T) {
// 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka
func TestStateLockPOLUnlock(t *testing.T) {
cs1, vss, evpool := randStateWithEvpool(4)
cs1, vss, evpool := randStateWithEvpool(t, 4)
vs2, vs3, vs4 := vss[1], vss[2], vss[3]
height, round := cs1.Height, cs1.Round
@ -723,7 +723,7 @@ func TestStateLockPOLUnlock(t *testing.T) {
// v1 should unlock and precommit nil. In the third round another block is proposed, all vals
// prevote and now v1 can lock onto the third block and precommit that
func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) {
cs1, vss, evpool := randStateWithEvpool(4)
cs1, vss, evpool := randStateWithEvpool(t, 4)
vs2, vs3, vs4 := vss[1], vss[2], vss[3]
height, round := cs1.Height, cs1.Round


+ 1
- 0
evidence/pool_test.go View File

@ -491,6 +491,7 @@ func initializeStateFromValidatorSet(valSet *types.ValidatorSet, height int64) d
stateDB := dbm.NewMemDB()
state := sm.State{
ChainID: evidenceChainID,
InitialHeight: 1,
LastBlockHeight: height,
LastBlockTime: tmtime.Now(),
Validators: valSet,


+ 2
- 1
node/node.go View File

@ -564,7 +564,8 @@ func startStateSync(ssR *statesync.Reactor, bcR fastSyncReactor, conR *cs.Reacto
state := sm.LoadState(stateDB)
if stateProvider == nil {
var err error
stateProvider, err = statesync.NewLightClientStateProvider(state.ChainID, state.Version,
stateProvider, err = statesync.NewLightClientStateProvider(
state.ChainID, state.Version, state.InitialHeight,
config.RPCServers, light.TrustOptions{
Period: config.TrustPeriod,
Height: config.TrustHeight,


+ 1
- 0
proto/tendermint/abci/types.proto View File

@ -64,6 +64,7 @@ message RequestInitChain {
ConsensusParams consensus_params = 3;
repeated ValidatorUpdate validators = 4 [(gogoproto.nullable) = false];
bytes app_state_bytes = 5;
int64 initial_height = 6;
}
message RequestQuery {


+ 85
- 49
proto/tendermint/state/types.pb.go View File

@ -254,7 +254,8 @@ func (m *Version) GetSoftware() string {
type State struct {
Version Version `protobuf:"bytes,1,opt,name=version,proto3" json:"version"`
// immutable
ChainID string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
ChainID string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
InitialHeight int64 `protobuf:"varint,14,opt,name=initial_height,json=initialHeight,proto3" json:"initial_height,omitempty"`
// LastBlockHeight=0 at genesis (ie. block(H=0) does not exist)
LastBlockHeight int64 `protobuf:"varint,3,opt,name=last_block_height,json=lastBlockHeight,proto3" json:"last_block_height,omitempty"`
LastBlockID types1.BlockID `protobuf:"bytes,4,opt,name=last_block_id,json=lastBlockId,proto3" json:"last_block_id"`
@ -326,6 +327,13 @@ func (m *State) GetChainID() string {
return ""
}
func (m *State) GetInitialHeight() int64 {
if m != nil {
return m.InitialHeight
}
return 0
}
func (m *State) GetLastBlockHeight() int64 {
if m != nil {
return m.LastBlockHeight
@ -414,54 +422,55 @@ func init() {
func init() { proto.RegisterFile("tendermint/state/types.proto", fileDescriptor_ccfacf933f22bf93) }
var fileDescriptor_ccfacf933f22bf93 = []byte{
// 750 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x95, 0x4f, 0x6f, 0xd3, 0x3e,
0x18, 0xc7, 0x9b, 0x5f, 0xb7, 0xb5, 0x75, 0xd6, 0x75, 0x3f, 0x8f, 0x43, 0xd7, 0xb1, 0xb4, 0x2b,
0x08, 0x4d, 0x1c, 0x52, 0x69, 0x1c, 0x10, 0x97, 0x49, 0x4b, 0x8b, 0x58, 0xa5, 0x09, 0x81, 0x37,
0xed, 0xc0, 0x25, 0x72, 0x1b, 0x2f, 0x89, 0x68, 0x93, 0x28, 0x76, 0xcb, 0x78, 0x01, 0xdc, 0x77,
0xe5, 0xad, 0xf0, 0x0a, 0x76, 0xdc, 0x11, 0x71, 0x18, 0xa8, 0x7b, 0x23, 0xc8, 0x76, 0xfe, 0xb8,
0x2d, 0x93, 0x86, 0xb8, 0x39, 0x7e, 0x9e, 0xe7, 0xe3, 0xaf, 0x1f, 0x7f, 0x1f, 0x05, 0x3c, 0x66,
0x24, 0x70, 0x48, 0x3c, 0xf6, 0x03, 0xd6, 0xa1, 0x0c, 0x33, 0xd2, 0x61, 0x9f, 0x23, 0x42, 0xcd,
0x28, 0x0e, 0x59, 0x08, 0x37, 0xf3, 0xa8, 0x29, 0xa2, 0x8d, 0x47, 0x6e, 0xe8, 0x86, 0x22, 0xd8,
0xe1, 0x2b, 0x99, 0xd7, 0xd8, 0x51, 0x28, 0x78, 0x30, 0xf4, 0x55, 0x48, 0x43, 0x3d, 0x42, 0xec,
0xcf, 0x45, 0x5b, 0x4b, 0xd1, 0x29, 0x1e, 0xf9, 0x0e, 0x66, 0x61, 0x9c, 0x64, 0xec, 0x2e, 0x65,
0x44, 0x38, 0xc6, 0xe3, 0x14, 0x60, 0x28, 0xe1, 0x29, 0x89, 0xa9, 0x1f, 0x06, 0x73, 0x07, 0x34,
0xdd, 0x30, 0x74, 0x47, 0xa4, 0x23, 0xbe, 0x06, 0x93, 0x8b, 0x0e, 0xf3, 0xc7, 0x84, 0x32, 0x3c,
0x8e, 0x64, 0x42, 0xfb, 0x87, 0x06, 0xaa, 0x47, 0x56, 0xb7, 0x8f, 0x08, 0x8d, 0xc2, 0x80, 0x12,
0x0a, 0xbb, 0x40, 0x77, 0xc8, 0xc8, 0x9f, 0x92, 0xd8, 0x66, 0x97, 0xb4, 0xae, 0xb5, 0x8a, 0xfb,
0xfa, 0x41, 0xdb, 0x54, 0x9a, 0xc1, 0x2f, 0x69, 0xa6, 0x05, 0x3d, 0x99, 0x7b, 0x76, 0x89, 0x80,
0x93, 0x2e, 0x29, 0x3c, 0x04, 0x15, 0x12, 0x38, 0xf6, 0x60, 0x14, 0x0e, 0x3f, 0xd6, 0xff, 0x6b,
0x69, 0xfb, 0xfa, 0xc1, 0xde, 0xbd, 0x88, 0xd7, 0x81, 0x63, 0xf1, 0x44, 0x54, 0x26, 0xc9, 0x0a,
0xf6, 0x80, 0x3e, 0x20, 0xae, 0x1f, 0x24, 0x84, 0xa2, 0x20, 0x3c, 0xb9, 0x97, 0x60, 0xf1, 0x5c,
0xc9, 0x00, 0x83, 0x6c, 0xdd, 0xfe, 0xa2, 0x81, 0x8d, 0xf3, 0xb4, 0xa1, 0xb4, 0x1f, 0x5c, 0x84,
0xb0, 0x0b, 0xaa, 0x59, 0x8b, 0x6d, 0x4a, 0x58, 0x5d, 0x13, 0x68, 0x43, 0x45, 0xcb, 0x06, 0x66,
0x85, 0xa7, 0x84, 0xa1, 0xf5, 0xa9, 0xf2, 0x05, 0x4d, 0xb0, 0x35, 0xc2, 0x94, 0xd9, 0x1e, 0xf1,
0x5d, 0x8f, 0xd9, 0x43, 0x0f, 0x07, 0x2e, 0x71, 0xc4, 0x3d, 0x8b, 0xe8, 0x7f, 0x1e, 0x3a, 0x16,
0x91, 0xae, 0x0c, 0xb4, 0xbf, 0x6a, 0x60, 0xab, 0xcb, 0x75, 0x06, 0x74, 0x42, 0xdf, 0x89, 0xf7,
0x13, 0x62, 0x10, 0xd8, 0x1c, 0xa6, 0xdb, 0xb6, 0x7c, 0xd7, 0x44, 0xcf, 0xde, 0xb2, 0x9e, 0x05,
0x80, 0xb5, 0x72, 0x7d, 0xdb, 0x2c, 0xa0, 0xda, 0x70, 0x7e, 0xfb, 0xaf, 0xb5, 0x79, 0xa0, 0x74,
0x2e, 0x8d, 0x03, 0x8f, 0x40, 0x25, 0xa3, 0x25, 0x3a, 0x76, 0x55, 0x1d, 0x89, 0xc1, 0x72, 0x25,
0x89, 0x86, 0xbc, 0x0a, 0x36, 0x40, 0x99, 0x86, 0x17, 0xec, 0x13, 0x8e, 0x89, 0x38, 0xb2, 0x82,
0xb2, 0xef, 0xf6, 0xb7, 0x35, 0xb0, 0x7a, 0xca, 0xe7, 0x08, 0xbe, 0x02, 0xa5, 0x84, 0x95, 0x1c,
0xb3, 0x6d, 0x2e, 0xce, 0x9a, 0x99, 0x88, 0x4a, 0x8e, 0x48, 0xf3, 0xe1, 0x33, 0x50, 0x1e, 0x7a,
0xd8, 0x0f, 0x6c, 0x5f, 0xde, 0xa9, 0x62, 0xe9, 0xb3, 0xdb, 0x66, 0xa9, 0xcb, 0xf7, 0xfa, 0x3d,
0x54, 0x12, 0xc1, 0xbe, 0x03, 0x9f, 0x03, 0x71, 0x57, 0xe9, 0x9f, 0xa4, 0x19, 0xc2, 0x46, 0x45,
0x54, 0xe3, 0x01, 0x61, 0x10, 0xd9, 0x09, 0x88, 0x40, 0x55, 0xc9, 0xf5, 0x9d, 0xfa, 0xca, 0xb2,
0x28, 0xf9, 0x06, 0xa2, 0xaa, 0xdf, 0xb3, 0xb6, 0xb8, 0xa8, 0xd9, 0x6d, 0x53, 0x3f, 0x49, 0x51,
0xfd, 0x1e, 0xd2, 0x33, 0x6e, 0xdf, 0x81, 0x27, 0xa0, 0xa6, 0x30, 0xf9, 0xd4, 0xd5, 0x57, 0x05,
0xb5, 0x61, 0xca, 0x91, 0x34, 0xd3, 0x91, 0x34, 0xcf, 0xd2, 0x91, 0xb4, 0xca, 0x1c, 0x7b, 0xf5,
0xb3, 0xa9, 0xa1, 0x6a, 0xc6, 0xe2, 0x51, 0xf8, 0x06, 0xd4, 0x02, 0x72, 0xc9, 0xec, 0xcc, 0x85,
0xb4, 0xbe, 0xf6, 0x20, 0xdf, 0x6e, 0xf0, 0xb2, 0x7c, 0x04, 0xe0, 0x21, 0x00, 0x0a, 0xa3, 0xf4,
0x20, 0x86, 0x52, 0xc1, 0x85, 0x88, 0x6b, 0x29, 0x90, 0xf2, 0xc3, 0x84, 0xf0, 0x32, 0x45, 0x48,
0x17, 0x18, 0xaa, 0x4d, 0x73, 0x5e, 0xe6, 0xd8, 0x8a, 0x78, 0xac, 0x9d, 0xdc, 0xb1, 0x79, 0x75,
0xe2, 0xdd, 0x3f, 0xce, 0x0f, 0xf8, 0xc7, 0xf9, 0x79, 0x0b, 0x9e, 0xce, 0xcd, 0xcf, 0x02, 0x3f,
0x93, 0xa7, 0x0b, 0x79, 0x2d, 0x65, 0xa0, 0xe6, 0x41, 0xa9, 0xc6, 0xd4, 0x88, 0x31, 0xa1, 0x93,
0x11, 0xa3, 0xb6, 0x87, 0xa9, 0x57, 0x5f, 0x6f, 0x69, 0xfb, 0xeb, 0xd2, 0x88, 0x48, 0xee, 0x1f,
0x63, 0xea, 0xc1, 0x6d, 0x50, 0xc6, 0x51, 0x24, 0x53, 0xaa, 0x22, 0xa5, 0x84, 0xa3, 0x88, 0x87,
0xac, 0xf7, 0xd7, 0x33, 0x43, 0xbb, 0x99, 0x19, 0xda, 0xaf, 0x99, 0xa1, 0x5d, 0xdd, 0x19, 0x85,
0x9b, 0x3b, 0xa3, 0xf0, 0xfd, 0xce, 0x28, 0x7c, 0x78, 0xe9, 0xfa, 0xcc, 0x9b, 0x0c, 0xcc, 0x61,
0x38, 0xee, 0xa8, 0x3f, 0x8b, 0x7c, 0x29, 0xff, 0x58, 0x8b, 0xff, 0xba, 0xc1, 0x9a, 0xd8, 0x7f,
0xf1, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xcb, 0xd2, 0xe7, 0x00, 0x06, 0x07, 0x00, 0x00,
// 763 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0xcf, 0x6f, 0xd3, 0x30,
0x14, 0x6e, 0xe8, 0xb6, 0xb6, 0xce, 0xda, 0x0e, 0x8f, 0x43, 0xd6, 0xb1, 0xb4, 0x2b, 0x3f, 0x34,
0x71, 0x48, 0xa5, 0x71, 0x40, 0x5c, 0x26, 0x2d, 0x2d, 0x62, 0x95, 0x26, 0x04, 0xd9, 0xb4, 0x03,
0x97, 0xc8, 0x6d, 0xbc, 0x24, 0xa2, 0x4d, 0xa2, 0xd8, 0x2d, 0xe3, 0x0f, 0xe0, 0xbe, 0x2b, 0xff,
0xd1, 0x8e, 0x3b, 0x22, 0x0e, 0x03, 0xba, 0x7f, 0x04, 0xd9, 0xce, 0x0f, 0xb7, 0x65, 0xd2, 0x10,
0x37, 0xfb, 0x7d, 0xdf, 0xfb, 0xfc, 0xf9, 0xf9, 0x3d, 0x19, 0x3c, 0xa6, 0x38, 0x70, 0x70, 0x3c,
0xf6, 0x03, 0xda, 0x21, 0x14, 0x51, 0xdc, 0xa1, 0x5f, 0x22, 0x4c, 0x8c, 0x28, 0x0e, 0x69, 0x08,
0x37, 0x72, 0xd4, 0xe0, 0x68, 0xe3, 0x91, 0x1b, 0xba, 0x21, 0x07, 0x3b, 0x6c, 0x25, 0x78, 0x8d,
0x6d, 0x49, 0x05, 0x0d, 0x86, 0xbe, 0x2c, 0xd2, 0x90, 0x8f, 0xe0, 0xf1, 0x39, 0xb4, 0xb5, 0x84,
0x4e, 0xd1, 0xc8, 0x77, 0x10, 0x0d, 0xe3, 0x84, 0xb1, 0xb3, 0xc4, 0x88, 0x50, 0x8c, 0xc6, 0xa9,
0x80, 0x2e, 0xc1, 0x53, 0x1c, 0x13, 0x3f, 0x0c, 0xe6, 0x0e, 0x68, 0xba, 0x61, 0xe8, 0x8e, 0x70,
0x87, 0xef, 0x06, 0x93, 0xf3, 0x0e, 0xf5, 0xc7, 0x98, 0x50, 0x34, 0x8e, 0x04, 0xa1, 0xfd, 0x43,
0x01, 0xd5, 0x43, 0xb3, 0xdb, 0xb7, 0x30, 0x89, 0xc2, 0x80, 0x60, 0x02, 0xbb, 0x40, 0x75, 0xf0,
0xc8, 0x9f, 0xe2, 0xd8, 0xa6, 0x17, 0x44, 0x53, 0x5a, 0xc5, 0x3d, 0x75, 0xbf, 0x6d, 0x48, 0xc5,
0x60, 0x97, 0x34, 0xd2, 0x84, 0x9e, 0xe0, 0x9e, 0x5e, 0x58, 0xc0, 0x49, 0x97, 0x04, 0x1e, 0x80,
0x0a, 0x0e, 0x1c, 0x7b, 0x30, 0x0a, 0x87, 0x9f, 0xb4, 0x07, 0x2d, 0x65, 0x4f, 0xdd, 0xdf, 0xbd,
0x53, 0xe2, 0x4d, 0xe0, 0x98, 0x8c, 0x68, 0x95, 0x71, 0xb2, 0x82, 0x3d, 0xa0, 0x0e, 0xb0, 0xeb,
0x07, 0x89, 0x42, 0x91, 0x2b, 0x3c, 0xb9, 0x53, 0xc1, 0x64, 0x5c, 0xa1, 0x01, 0x06, 0xd9, 0xba,
0xfd, 0x55, 0x01, 0xb5, 0xb3, 0xb4, 0xa0, 0xa4, 0x1f, 0x9c, 0x87, 0xb0, 0x0b, 0xaa, 0x59, 0x89,
0x6d, 0x82, 0xa9, 0xa6, 0x70, 0x69, 0x5d, 0x96, 0x16, 0x05, 0xcc, 0x12, 0x4f, 0x30, 0xb5, 0xd6,
0xa7, 0xd2, 0x0e, 0x1a, 0x60, 0x73, 0x84, 0x08, 0xb5, 0x3d, 0xec, 0xbb, 0x1e, 0xb5, 0x87, 0x1e,
0x0a, 0x5c, 0xec, 0xf0, 0x7b, 0x16, 0xad, 0x87, 0x0c, 0x3a, 0xe2, 0x48, 0x57, 0x00, 0xed, 0x6f,
0x0a, 0xd8, 0xec, 0x32, 0x9f, 0x01, 0x99, 0x90, 0xf7, 0xfc, 0xfd, 0xb8, 0x19, 0x0b, 0x6c, 0x0c,
0xd3, 0xb0, 0x2d, 0xde, 0x35, 0xf1, 0xb3, 0xbb, 0xec, 0x67, 0x41, 0xc0, 0x5c, 0xb9, 0xba, 0x69,
0x16, 0xac, 0xfa, 0x70, 0x3e, 0xfc, 0xcf, 0xde, 0x3c, 0x50, 0x3a, 0x13, 0x8d, 0x03, 0x0f, 0x41,
0x25, 0x53, 0x4b, 0x7c, 0xec, 0xc8, 0x3e, 0x92, 0x06, 0xcb, 0x9d, 0x24, 0x1e, 0xf2, 0x2c, 0xd8,
0x00, 0x65, 0x12, 0x9e, 0xd3, 0xcf, 0x28, 0xc6, 0xfc, 0xc8, 0x8a, 0x95, 0xed, 0xdb, 0xbf, 0xd7,
0xc0, 0xea, 0x09, 0x9b, 0x23, 0xf8, 0x1a, 0x94, 0x12, 0xad, 0xe4, 0x98, 0x2d, 0x63, 0x71, 0xd6,
0x8c, 0xc4, 0x54, 0x72, 0x44, 0xca, 0x87, 0xcf, 0x41, 0x79, 0xe8, 0x21, 0x3f, 0xb0, 0x7d, 0x71,
0xa7, 0x8a, 0xa9, 0xce, 0x6e, 0x9a, 0xa5, 0x2e, 0x8b, 0xf5, 0x7b, 0x56, 0x89, 0x83, 0x7d, 0x07,
0x3e, 0x03, 0x35, 0x3f, 0xf0, 0xa9, 0x8f, 0x46, 0x49, 0x25, 0xb4, 0x1a, 0xaf, 0x40, 0x35, 0x89,
0x8a, 0x22, 0xc0, 0x17, 0x80, 0x97, 0x44, 0xb4, 0x59, 0xca, 0x2c, 0x72, 0x66, 0x9d, 0x01, 0xbc,
0x8f, 0x12, 0xae, 0x05, 0xaa, 0x12, 0xd7, 0x77, 0xb4, 0x95, 0x65, 0xef, 0xe2, 0xa9, 0x78, 0x56,
0xbf, 0x67, 0x6e, 0x32, 0xef, 0xb3, 0x9b, 0xa6, 0x7a, 0x9c, 0x4a, 0xf5, 0x7b, 0x96, 0x9a, 0xe9,
0xf6, 0x1d, 0x78, 0x0c, 0xea, 0x92, 0x26, 0x1b, 0x4e, 0x6d, 0x95, 0xab, 0x36, 0x0c, 0x31, 0xb9,
0x46, 0x3a, 0xb9, 0xc6, 0x69, 0x3a, 0xb9, 0x66, 0x99, 0xc9, 0x5e, 0xfe, 0x6c, 0x2a, 0x56, 0x35,
0xd3, 0x62, 0x28, 0x7c, 0x0b, 0xea, 0x01, 0xbe, 0xa0, 0x76, 0xd6, 0xac, 0x44, 0x5b, 0xbb, 0x57,
0x7b, 0xd7, 0x58, 0x5a, 0x3e, 0x29, 0xf0, 0x00, 0x00, 0x49, 0xa3, 0x74, 0x2f, 0x0d, 0x29, 0x83,
0x19, 0xe1, 0xd7, 0x92, 0x44, 0xca, 0xf7, 0x33, 0xc2, 0xd2, 0x24, 0x23, 0x5d, 0xa0, 0xcb, 0xdd,
0x9c, 0xeb, 0x65, 0x8d, 0x5d, 0xe1, 0x8f, 0xb5, 0x9d, 0x37, 0x76, 0x9e, 0x9d, 0xb4, 0xf8, 0x5f,
0xc7, 0x0c, 0xfc, 0xe7, 0x98, 0xbd, 0x03, 0x4f, 0xe7, 0xc6, 0x6c, 0x41, 0x3f, 0xb3, 0xa7, 0x72,
0x7b, 0x2d, 0x69, 0xee, 0xe6, 0x85, 0x52, 0x8f, 0x69, 0x23, 0xc6, 0x98, 0x4c, 0x46, 0x94, 0xd8,
0x1e, 0x22, 0x9e, 0xb6, 0xde, 0x52, 0xf6, 0xd6, 0x45, 0x23, 0x5a, 0x22, 0x7e, 0x84, 0x88, 0x07,
0xb7, 0x40, 0x19, 0x45, 0x91, 0xa0, 0x54, 0x39, 0xa5, 0x84, 0xa2, 0x88, 0x41, 0xe6, 0x87, 0xab,
0x99, 0xae, 0x5c, 0xcf, 0x74, 0xe5, 0xd7, 0x4c, 0x57, 0x2e, 0x6f, 0xf5, 0xc2, 0xf5, 0xad, 0x5e,
0xf8, 0x7e, 0xab, 0x17, 0x3e, 0xbe, 0x72, 0x7d, 0xea, 0x4d, 0x06, 0xc6, 0x30, 0x1c, 0x77, 0xe4,
0x3f, 0x25, 0x5f, 0x8a, 0x8f, 0x6d, 0xf1, 0x4b, 0x1c, 0xac, 0xf1, 0xf8, 0xcb, 0x3f, 0x01, 0x00,
0x00, 0xff, 0xff, 0xa5, 0x17, 0xac, 0x23, 0x2d, 0x07, 0x00, 0x00,
}
func (m *ABCIResponses) Marshal() (dAtA []byte, err error) {
@ -663,6 +672,11 @@ func (m *State) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.InitialHeight != 0 {
i = encodeVarintTypes(dAtA, i, uint64(m.InitialHeight))
i--
dAtA[i] = 0x70
}
if len(m.AppHash) > 0 {
i -= len(m.AppHash)
copy(dAtA[i:], m.AppHash)
@ -902,6 +916,9 @@ func (m *State) Size() (n int) {
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
if m.InitialHeight != 0 {
n += 1 + sovTypes(uint64(m.InitialHeight))
}
return n
}
@ -1827,6 +1844,25 @@ func (m *State) Unmarshal(dAtA []byte) error {
m.AppHash = []byte{}
}
iNdEx = postIndex
case 14:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field InitialHeight", wireType)
}
m.InitialHeight = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.InitialHeight |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:])


+ 2
- 1
proto/tendermint/state/types.proto View File

@ -41,7 +41,8 @@ message State {
Version version = 1 [(gogoproto.nullable) = false];
// immutable
string chain_id = 2 [(gogoproto.customname) = "ChainID"];
string chain_id = 2 [(gogoproto.customname) = "ChainID"];
int64 initial_height = 14;
// LastBlockHeight=0 at genesis (ie. block(H=0) does not exist)
int64 last_block_height = 3;


+ 1
- 1
rpc/core/env.go View File

@ -150,7 +150,7 @@ func getHeight(latestHeight int64, heightPtr *int64) (int64, error) {
}
base := env.BlockStore.Base()
if height < base {
return 0, fmt.Errorf("height %v is not available, blocks pruned at height %v",
return 0, fmt.Errorf("height %v is not available, lowest height is %v",
height, base)
}
return height, nil


+ 11
- 6
state/execution.go View File

@ -134,7 +134,8 @@ func (blockExec *BlockExecutor) ApplyBlock(
}
startTime := time.Now().UnixNano()
abciResponses, err := execBlockOnProxyApp(blockExec.logger, blockExec.proxyApp, block, blockExec.db)
abciResponses, err := execBlockOnProxyApp(blockExec.logger, blockExec.proxyApp, block,
blockExec.db, state.InitialHeight)
endTime := time.Now().UnixNano()
blockExec.metrics.BlockProcessingTime.Observe(float64(endTime-startTime) / 1000000)
if err != nil {
@ -254,6 +255,7 @@ func execBlockOnProxyApp(
proxyAppConn proxy.AppConnConsensus,
block *types.Block,
stateDB dbm.DB,
initialHeight int64,
) (*tmstate.ABCIResponses, error) {
var validTxs, invalidTxs = 0, 0
@ -281,7 +283,7 @@ func execBlockOnProxyApp(
}
proxyAppConn.SetResponseCallback(proxyCb)
commitInfo, byzVals := getBeginBlockValidatorInfo(block, stateDB)
commitInfo, byzVals := getBeginBlockValidatorInfo(block, stateDB, initialHeight)
// Begin block
var err error
@ -320,12 +322,13 @@ func execBlockOnProxyApp(
return abciResponses, nil
}
func getBeginBlockValidatorInfo(block *types.Block, stateDB dbm.DB) (abci.LastCommitInfo, []abci.Evidence) {
func getBeginBlockValidatorInfo(block *types.Block, stateDB dbm.DB,
initialHeight int64) (abci.LastCommitInfo, []abci.Evidence) {
voteInfos := make([]abci.VoteInfo, block.LastCommit.Size())
// block.Height=1 -> LastCommitInfo.Votes are empty.
// Initial block -> LastCommitInfo.Votes are empty.
// Remember that the first LastCommit is intentionally empty, so it makes
// sense for LastCommitInfo.Votes to also be empty.
if block.Height > 1 {
if block.Height > initialHeight {
lastValSet, err := LoadValidators(stateDB, block.Height-1)
if err != nil {
panic(err)
@ -445,6 +448,7 @@ func updateState(
return State{
Version: nextVersion,
ChainID: state.ChainID,
InitialHeight: state.InitialHeight,
LastBlockHeight: header.Height,
LastBlockID: blockID,
LastBlockTime: header.Time,
@ -515,8 +519,9 @@ func ExecCommitBlock(
block *types.Block,
logger log.Logger,
stateDB dbm.DB,
initialHeight int64,
) ([]byte, error) {
_, err := execBlockOnProxyApp(logger, appConnConsensus, block, stateDB)
_, err := execBlockOnProxyApp(logger, appConnConsensus, block, stateDB, initialHeight)
if err != nil {
logger.Error("Error executing block on proxy app", "height", block.Height, "err", err)
return nil, err


+ 2
- 2
state/execution_test.go View File

@ -94,7 +94,7 @@ func TestBeginBlockValidators(t *testing.T) {
// block for height 2
block, _ := state.MakeBlock(2, makeTxs(2), lastCommit, nil, state.Validators.GetProposer().Address)
_, err = sm.ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), stateDB)
_, err = sm.ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), stateDB, 1)
require.Nil(t, err, tc.desc)
// -> app receives a list of validators with a bool indicating if they signed
@ -163,7 +163,7 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
block, _ := state.MakeBlock(10, makeTxs(2), lastCommit, nil, state.Validators.GetProposer().Address)
block.Time = now
block.Evidence.Evidence = tc.evidence
_, err = sm.ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), stateDB)
_, err = sm.ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), stateDB, 1)
require.Nil(t, err, tc.desc)
// -> app must receive an index of the byzantine validator


+ 13
- 8
state/state.go View File

@ -49,7 +49,8 @@ type State struct {
Version tmstate.Version
// immutable
ChainID string
ChainID string
InitialHeight int64 // should be 1, not 0, when starting from height 1
// LastBlockHeight=0 at genesis (ie. block(H=0) does not exist)
LastBlockHeight int64
@ -83,8 +84,9 @@ type State struct {
func (state State) Copy() State {
return State{
Version: state.Version,
ChainID: state.ChainID,
Version: state.Version,
ChainID: state.ChainID,
InitialHeight: state.InitialHeight,
LastBlockHeight: state.LastBlockHeight,
LastBlockID: state.LastBlockID,
@ -139,6 +141,7 @@ func (state *State) ToProto() (*tmstate.State, error) {
sm.Version = state.Version
sm.ChainID = state.ChainID
sm.InitialHeight = state.InitialHeight
sm.LastBlockHeight = state.LastBlockHeight
sm.LastBlockID = state.LastBlockID.ToProto()
@ -182,6 +185,7 @@ func StateFromProto(pb *tmstate.State) (*State, error) { //nolint:golint
state.Version = pb.Version
state.ChainID = pb.ChainID
state.InitialHeight = pb.InitialHeight
bi, err := types.BlockIDFromProto(&pb.LastBlockID)
if err != nil {
@ -241,7 +245,7 @@ func (state State) MakeBlock(
// Set time.
var timestamp time.Time
if height == 1 {
if height == state.InitialHeight {
timestamp = state.LastBlockTime // genesis time
} else {
timestamp = MedianTime(commit, state.LastValidators)
@ -331,8 +335,9 @@ func MakeGenesisState(genDoc *types.GenesisDoc) (State, error) {
}
return State{
Version: InitStateVersion,
ChainID: genDoc.ChainID,
Version: InitStateVersion,
ChainID: genDoc.ChainID,
InitialHeight: genDoc.InitialHeight,
LastBlockHeight: 0,
LastBlockID: types.BlockID{},
@ -341,10 +346,10 @@ func MakeGenesisState(genDoc *types.GenesisDoc) (State, error) {
NextValidators: nextValidatorSet,
Validators: validatorSet,
LastValidators: types.NewValidatorSet(nil),
LastHeightValidatorsChanged: 1,
LastHeightValidatorsChanged: genDoc.InitialHeight,
ConsensusParams: *genDoc.ConsensusParams,
LastHeightConsensusParamsChanged: 1,
LastHeightConsensusParamsChanged: genDoc.InitialHeight,
AppHash: genDoc.AppHash,
}, nil


+ 13
- 8
state/store.go View File

@ -110,12 +110,12 @@ func SaveState(db dbm.DB, state State) {
func saveState(db dbm.DB, state State, key []byte) {
nextHeight := state.LastBlockHeight + 1
// If first block, save validators for block 1.
// If first block, save validators for the block.
if nextHeight == 1 {
nextHeight = state.InitialHeight
// This extra logic due to Tendermint validator set changes being delayed 1 block.
// It may get overwritten due to InitChain validator updates.
lastHeightVoteChanged := int64(1)
saveValidatorsInfo(db, nextHeight, lastHeightVoteChanged, state.Validators)
saveValidatorsInfo(db, nextHeight, nextHeight, state.Validators)
}
// Save next validators.
saveValidatorsInfo(db, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
@ -130,11 +130,16 @@ func saveState(db dbm.DB, state State, key []byte) {
// BootstrapState saves a new state, used e.g. by state sync when starting from non-zero height.
func BootstrapState(db dbm.DB, state State) error {
height := state.LastBlockHeight
saveValidatorsInfo(db, height, height, state.LastValidators)
saveValidatorsInfo(db, height+1, height+1, state.Validators)
saveValidatorsInfo(db, height+2, height+2, state.NextValidators)
saveConsensusParamsInfo(db, height+1, height+1, state.ConsensusParams)
height := state.LastBlockHeight + 1
if height == 1 {
height = state.InitialHeight
}
if height > 1 && !state.LastValidators.IsNilOrEmpty() {
saveValidatorsInfo(db, height-1, height-1, state.LastValidators)
}
saveValidatorsInfo(db, height, height, state.Validators)
saveValidatorsInfo(db, height+1, height+1, state.NextValidators)
saveConsensusParamsInfo(db, height, height, state.ConsensusParams)
return db.SetSync(stateKey, state.Bytes())
}


+ 1
- 0
state/store_test.go View File

@ -119,6 +119,7 @@ func TestPruneStates(t *testing.T) {
}
state := sm.State{
InitialHeight: 1,
LastBlockHeight: h - 1,
Validators: validatorSet,
NextValidators: validatorSet,


+ 15
- 5
state/validation.go View File

@ -34,7 +34,11 @@ func validateBlock(evidencePool EvidencePool, stateDB dbm.DB, state State, block
block.ChainID,
)
}
if block.Height != state.LastBlockHeight+1 {
if state.LastBlockHeight == 0 && block.Height != state.InitialHeight {
return fmt.Errorf("wrong Block.Header.Height. Expected %v for initial block, got %v",
block.Height, state.InitialHeight)
}
if state.LastBlockHeight > 0 && block.Height != state.LastBlockHeight+1 {
return fmt.Errorf("wrong Block.Header.Height. Expected %v, got %v",
state.LastBlockHeight+1,
block.Height,
@ -82,9 +86,9 @@ func validateBlock(evidencePool EvidencePool, stateDB dbm.DB, state State, block
}
// Validate block LastCommit.
if block.Height == 1 {
if block.Height == state.InitialHeight {
if len(block.LastCommit.Signatures) != 0 {
return errors.New("block at height 1 can't have LastCommit signatures")
return errors.New("initial block can't have LastCommit signatures")
}
} else {
// LastCommit.Signatures length is checked in VerifyCommit.
@ -110,7 +114,8 @@ func validateBlock(evidencePool EvidencePool, stateDB dbm.DB, state State, block
}
// Validate block Time
if block.Height > 1 {
switch {
case block.Height > state.InitialHeight:
if !block.Time.After(state.LastBlockTime) {
return fmt.Errorf("block time %v not greater than last block time %v",
block.Time,
@ -124,7 +129,8 @@ func validateBlock(evidencePool EvidencePool, stateDB dbm.DB, state State, block
block.Time,
)
}
} else if block.Height == 1 {
case block.Height == state.InitialHeight:
genesisTime := state.LastBlockTime
if !block.Time.Equal(genesisTime) {
return fmt.Errorf("block time %v is not equal to genesis time %v",
@ -132,6 +138,10 @@ func validateBlock(evidencePool EvidencePool, stateDB dbm.DB, state State, block
genesisTime,
)
}
default:
return fmt.Errorf("block height %v lower than initial height %v",
block.Height, state.InitialHeight)
}
// Limit the amount of evidence


+ 16
- 9
statesync/stateprovider.go View File

@ -35,16 +35,18 @@ type StateProvider interface {
// lightClientStateProvider is a state provider using the light client.
type lightClientStateProvider struct {
tmsync.Mutex // light.Client is not concurrency-safe
lc *light.Client
version tmstate.Version
providers map[lightprovider.Provider]string
tmsync.Mutex // light.Client is not concurrency-safe
lc *light.Client
version tmstate.Version
initialHeight int64
providers map[lightprovider.Provider]string
}
// NewLightClientStateProvider creates a new StateProvider using a light client and RPC clients.
func NewLightClientStateProvider(
chainID string,
version tmstate.Version,
initialHeight int64,
servers []string,
trustOptions light.TrustOptions,
logger log.Logger,
@ -73,9 +75,10 @@ func NewLightClientStateProvider(
return nil, err
}
return &lightClientStateProvider{
lc: lc,
version: version,
providers: providerRemotes,
lc: lc,
version: version,
initialHeight: initialHeight,
providers: providerRemotes,
}, nil
}
@ -109,8 +112,12 @@ func (s *lightClientStateProvider) State(height uint64) (sm.State, error) {
defer s.Unlock()
state := sm.State{
ChainID: s.lc.ChainID(),
Version: s.version,
ChainID: s.lc.ChainID(),
Version: s.version,
InitialHeight: s.initialHeight,
}
if state.InitialHeight == 0 {
state.InitialHeight = 1
}
// We need to verify up until h+2, to get the validator set. This also prefetches the headers


+ 2
- 4
types/block.go View File

@ -65,10 +65,8 @@ func (b *Block) ValidateBasic() error {
if b.LastCommit == nil {
return errors.New("nil LastCommit")
}
if b.Header.Height > 1 {
if err := b.LastCommit.ValidateBasic(); err != nil {
return fmt.Errorf("wrong LastCommit: %v", err)
}
if err := b.LastCommit.ValidateBasic(); err != nil {
return fmt.Errorf("wrong LastCommit: %v", err)
}
if !bytes.Equal(b.LastCommitHash, b.LastCommit.Hash()) {


+ 7
- 0
types/genesis.go View File

@ -39,6 +39,7 @@ type GenesisValidator struct {
type GenesisDoc struct {
GenesisTime time.Time `json:"genesis_time"`
ChainID string `json:"chain_id"`
InitialHeight int64 `json:"initial_height"`
ConsensusParams *tmproto.ConsensusParams `json:"consensus_params,omitempty"`
Validators []GenesisValidator `json:"validators,omitempty"`
AppHash tmbytes.HexBytes `json:"app_hash"`
@ -73,6 +74,12 @@ func (genDoc *GenesisDoc) ValidateAndComplete() error {
if len(genDoc.ChainID) > MaxChainIDLen {
return fmt.Errorf("chain_id in genesis doc is too long (max: %d)", MaxChainIDLen)
}
if genDoc.InitialHeight < 0 {
return fmt.Errorf("initial_height cannot be negative (got %v)", genDoc.InitialHeight)
}
if genDoc.InitialHeight == 0 {
genDoc.InitialHeight = 1
}
if genDoc.ConsensusParams == nil {
genDoc.ConsensusParams = DefaultConsensusParams()


+ 18
- 9
types/genesis_test.go View File

@ -19,7 +19,8 @@ func TestGenesisBad(t *testing.T) {
{}, // empty
{1, 1, 1, 1, 1}, // junk
[]byte(`{}`), // empty
[]byte(`{"chain_id":"mychain","validators":[{}]}`), // invalid validator
[]byte(`{"chain_id":"mychain","validators":[{}]}`), // invalid validator
[]byte(`{"chain_id":"chain","initial_height":"-1"}`), // negative initial height
// missing pub_key type
[]byte(
`{"validators":[{"pub_key":{"value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="},"power":"10","name":""}]}`,
@ -59,11 +60,19 @@ func TestGenesisBad(t *testing.T) {
func TestGenesisGood(t *testing.T) {
// test a good one by raw json
genDocBytes := []byte(
`{"genesis_time":"0001-01-01T00:00:00Z","chain_id":"test-chain-QDKdJr","consensus_params":null,"validators":[` +
`{"pub_key":{` +
`"type":"tendermint/PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="` +
`},"power":"10","name":""}` +
`],"app_hash":"","app_state":{"account_owner": "Bob"}}`,
`{
"genesis_time": "0001-01-01T00:00:00Z",
"chain_id": "test-chain-QDKdJr",
"initial_height": "1000",
"consensus_params": null,
"validators": [{
"pub_key":{"type":"tendermint/PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="},
"power":"10",
"name":""
}],
"app_hash":"",
"app_state":{"account_owner": "Bob"}
}`,
)
_, err := GenesisDocFromJSON(genDocBytes)
assert.NoError(t, err, "expected no error for good genDoc json")
@ -133,9 +142,7 @@ func TestGenesisSaveAs(t *testing.T) {
// load
genDoc2, err := GenesisDocFromFile(tmpfile.Name())
require.NoError(t, err)
// fails to unknown reason
// assert.EqualValues(t, genDoc2, genDoc)
assert.EqualValues(t, genDoc2, genDoc)
assert.Equal(t, genDoc2.Validators, genDoc.Validators)
}
@ -149,7 +156,9 @@ func randomGenesisDoc() *GenesisDoc {
return &GenesisDoc{
GenesisTime: tmtime.Now(),
ChainID: "abc",
InitialHeight: 1000,
Validators: []GenesisValidator{{pubkey.Address(), pubkey, 10, "myval"}},
ConsensusParams: DefaultConsensusParams(),
AppHash: []byte{1, 2, 3},
}
}

Loading…
Cancel
Save