Browse Source

evidence: introduce time.Duration to evidence params (#4254)

* evidence: introduce time.Duration to evidence params

- add time.duration to evidence
- this pr is taking pr #2606 and updating it to use both time and height

- closes #2565

Signed-off-by: Marko Baricevic <marbar3778@yahoo.com>

* fix testing and genesis cfg in signer harness

* remove debugging fmt

* change maxageheight to maxagenumblocks, rename other things to block instead of height

* further check of duration

* check duration to not send peers outdated evidence

* change some lines, onward and upward

* refactor evidence package

* add a changelog pending entry

* make mockbadevidence have time and use it

* add what could possibly be called a test case

* remove mockbadevidence and mockgoodevidence in favor of mockevidence

* add a comment for err that is returned

* add a changelog for removal of good & bad evidence

* add a test for adding evidence

* fix test

* add ev to types in testcase

* Update evidence/pool_test.go

Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com>

* Update evidence/pool_test.go

Co-Authored-By: Anton Kaliaev <anton.kalyaev@gmail.com>

* fix tests

* fix linting

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
pull/4292/head
Marko 5 years ago
committed by GitHub
parent
commit
6d91c1faf4
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 537 additions and 379 deletions
  1. +3
    -0
      CHANGELOG_PENDING.md
  2. +1
    -1
      Makefile
  3. +300
    -240
      abci/types/types.pb.go
  4. +3
    -2
      abci/types/types.proto
  5. +1
    -0
      abci/types/typespb_test.go
  6. +1
    -1
      consensus/reactor_test.go
  7. +3
    -2
      docs/tendermint-core/using-tendermint.md
  8. +19
    -11
      evidence/pool.go
  9. +58
    -15
      evidence/pool_test.go
  10. +25
    -13
      evidence/reactor.go
  11. +2
    -2
      evidence/reactor_test.go
  12. +11
    -10
      evidence/store_test.go
  13. +1
    -1
      node/node_test.go
  14. +3
    -1
      rpc/client/rpc_test.go
  15. +2
    -2
      state/execution_test.go
  16. +3
    -1
      state/helpers_test.go
  17. +5
    -3
      state/state_test.go
  18. +13
    -5
      state/validation.go
  19. +2
    -2
      state/validation_test.go
  20. +2
    -1
      tools/tm-signer-harness/internal/test_harness_test.go
  21. +4
    -4
      types/block_test.go
  22. +46
    -48
      types/evidence.go
  23. +3
    -2
      types/evidence_test.go
  24. +16
    -6
      types/params.go
  25. +5
    -2
      types/params_test.go
  26. +5
    -4
      types/protobuf.go

+ 3
- 0
CHANGELOG_PENDING.md View File

@ -58,6 +58,8 @@ program](https://hackerone.com/tendermint).
- [config] \#4046 Rename tag(s) to CompositeKey & places where tag is still present it was renamed to event or events. Find how a compositeKey is constructed [here](https://github.com/tendermint/tendermint/blob/6d05c531f7efef6f0619155cf10ae8557dd7832f/docs/app-dev/indexing-transactions.md) - [config] \#4046 Rename tag(s) to CompositeKey & places where tag is still present it was renamed to event or events. Find how a compositeKey is constructed [here](https://github.com/tendermint/tendermint/blob/6d05c531f7efef6f0619155cf10ae8557dd7832f/docs/app-dev/indexing-transactions.md)
- You will have to generate a new config for your Tendermint node(s) - You will have to generate a new config for your Tendermint node(s)
- [genesis] \#2565 Add `consensus_params.evidence.max_age_duration`. Rename
`consensus_params.evidence.max_age` to `max_age_num_blocks`.
- Apps - Apps
@ -86,6 +88,7 @@ program](https://hackerone.com/tendermint).
- [libs/common] \#4240 Move bit functions out of `libs/common` to `bits` pkg - [libs/common] \#4240 Move bit functions out of `libs/common` to `bits` pkg
- [libs/common] \#4240 Move cmap functions out of `libs/common` to `cmap` pkg - [libs/common] \#4240 Move cmap functions out of `libs/common` to `cmap` pkg
- [libs/common] \#4258 Remove `Rand` from all `rand` pkg functions - [libs/common] \#4258 Remove `Rand` from all `rand` pkg functions
- [types] \#2565 Remove `MockBadEvidence` & `MockGoodEvidence` in favor of `MockEvidence`
- Blockchain Protocol - Blockchain Protocol


+ 1
- 1
Makefile View File

@ -41,7 +41,7 @@ protoc_all: protoc_libs protoc_merkle protoc_abci protoc_grpc protoc_proto3types
## See https://stackoverflow.com/a/25518702 ## See https://stackoverflow.com/a/25518702
## Note the $< here is substituted for the %.proto ## Note the $< here is substituted for the %.proto
## Note the $@ here is substituted for the %.pb.go ## Note the $@ here is substituted for the %.pb.go
protoc $(INCLUDE) $< --gogo_out=Mgoogle/protobuf/timestamp.proto=github.com/golang/protobuf/ptypes/timestamp,plugins=grpc:../../..
protoc $(INCLUDE) $< --gogo_out=Mgoogle/protobuf/timestamp.proto=github.com/golang/protobuf/ptypes/timestamp,Mgoogle/protobuf/duration.proto=github.com/golang/protobuf/ptypes/duration,plugins=grpc:../../..
######################################## ########################################
### Build ABCI ### Build ABCI


+ 300
- 240
abci/types/types.pb.go View File

@ -11,6 +11,7 @@ import (
proto "github.com/gogo/protobuf/proto" proto "github.com/gogo/protobuf/proto"
github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" github_com_gogo_protobuf_types "github.com/gogo/protobuf/types"
golang_proto "github.com/golang/protobuf/proto" golang_proto "github.com/golang/protobuf/proto"
_ "github.com/golang/protobuf/ptypes/duration"
_ "github.com/golang/protobuf/ptypes/timestamp" _ "github.com/golang/protobuf/ptypes/timestamp"
merkle "github.com/tendermint/tendermint/crypto/merkle" merkle "github.com/tendermint/tendermint/crypto/merkle"
kv "github.com/tendermint/tendermint/libs/kv" kv "github.com/tendermint/tendermint/libs/kv"
@ -2032,13 +2033,13 @@ func (m *BlockParams) GetMaxGas() int64 {
return 0 return 0
} }
// EvidenceParams contains limits on the evidence.
type EvidenceParams struct { type EvidenceParams struct {
// Note: must be greater than 0 // Note: must be greater than 0
MaxAge int64 `protobuf:"varint,1,opt,name=max_age,json=maxAge,proto3" json:"max_age,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
MaxAgeNumBlocks int64 `protobuf:"varint,1,opt,name=max_age_num_blocks,json=maxAgeNumBlocks,proto3" json:"max_age_num_blocks,omitempty"`
MaxAgeDuration time.Duration `protobuf:"bytes,2,opt,name=max_age_duration,json=maxAgeDuration,proto3,stdduration" json:"max_age_duration"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *EvidenceParams) Reset() { *m = EvidenceParams{} } func (m *EvidenceParams) Reset() { *m = EvidenceParams{} }
@ -2074,9 +2075,16 @@ func (m *EvidenceParams) XXX_DiscardUnknown() {
var xxx_messageInfo_EvidenceParams proto.InternalMessageInfo var xxx_messageInfo_EvidenceParams proto.InternalMessageInfo
func (m *EvidenceParams) GetMaxAge() int64 {
func (m *EvidenceParams) GetMaxAgeNumBlocks() int64 {
if m != nil { if m != nil {
return m.MaxAge
return m.MaxAgeNumBlocks
}
return 0
}
func (m *EvidenceParams) GetMaxAgeDuration() time.Duration {
if m != nil {
return m.MaxAgeDuration
} }
return 0 return 0
} }
@ -2952,152 +2960,156 @@ func init() { proto.RegisterFile("abci/types/types.proto", fileDescriptor_9f1eaa
func init() { golang_proto.RegisterFile("abci/types/types.proto", fileDescriptor_9f1eaa49c51fa1ac) } func init() { golang_proto.RegisterFile("abci/types/types.proto", fileDescriptor_9f1eaa49c51fa1ac) }
var fileDescriptor_9f1eaa49c51fa1ac = []byte{ var fileDescriptor_9f1eaa49c51fa1ac = []byte{
// 2313 bytes of a gzipped FileDescriptorProto
// 2371 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x59, 0x4d, 0x90, 0x1b, 0x47, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x59, 0x4d, 0x90, 0x1b, 0x47,
0x15, 0xde, 0x91, 0xb4, 0x92, 0xe6, 0x69, 0x7f, 0xe4, 0xb6, 0x93, 0x28, 0xc2, 0xd9, 0x75, 0x8d,
0xff, 0xd6, 0x21, 0x91, 0xc3, 0x42, 0xa8, 0x18, 0xbb, 0x42, 0xad, 0xd6, 0x0e, 0x52, 0xc5, 0x49,
0x36, 0x63, 0x7b, 0x31, 0x50, 0x95, 0xa9, 0x96, 0xa6, 0x2d, 0x4d, 0xad, 0x34, 0x33, 0x99, 0x69,
0xc9, 0xbb, 0x14, 0x77, 0x8a, 0x1b, 0x17, 0x8e, 0xdc, 0x39, 0x72, 0xe0, 0x90, 0x23, 0xc7, 0x1c,
0x38, 0x70, 0xe0, 0x6c, 0x60, 0xe1, 0x44, 0xe5, 0x48, 0x51, 0x1c, 0xa9, 0x7e, 0xdd, 0xf3, 0x27,
0x4b, 0xab, 0x71, 0xf0, 0x2d, 0x97, 0xdd, 0xe9, 0xd6, 0x7b, 0xaf, 0xbb, 0x5f, 0xbf, 0xf7, 0xbe,
0xf7, 0x5e, 0xc3, 0xab, 0xb4, 0xd7, 0x77, 0x6e, 0xf2, 0x13, 0x9f, 0x85, 0xf2, 0x6f, 0xcb, 0x0f,
0x3c, 0xee, 0x91, 0x57, 0x38, 0x73, 0x6d, 0x16, 0x8c, 0x1d, 0x97, 0xb7, 0x04, 0x49, 0x0b, 0x7f,
0x6c, 0xbe, 0x3d, 0x70, 0xf8, 0x70, 0xd2, 0x6b, 0xf5, 0xbd, 0xf1, 0xcd, 0x81, 0x37, 0xf0, 0x6e,
0x22, 0x75, 0x6f, 0xf2, 0x04, 0x47, 0x38, 0xc0, 0x2f, 0x29, 0xa5, 0x79, 0x3b, 0x45, 0x9e, 0x08,
0x4c, 0x7f, 0xf6, 0x83, 0x13, 0x9f, 0x7b, 0x37, 0xc7, 0x2c, 0x38, 0x1a, 0x31, 0xf5, 0x4f, 0x31,
0x7f, 0x6f, 0x29, 0xf3, 0xc8, 0xe9, 0x85, 0x37, 0x8f, 0xa6, 0xe9, 0x8d, 0x37, 0xb7, 0x07, 0x9e,
0x37, 0x18, 0xb1, 0x64, 0x63, 0xdc, 0x19, 0xb3, 0x90, 0xd3, 0xb1, 0x2f, 0x09, 0x8c, 0xff, 0xac,
0x42, 0xc5, 0x64, 0x9f, 0x4f, 0x58, 0xc8, 0xc9, 0x7b, 0x50, 0x62, 0xfd, 0xa1, 0xd7, 0x28, 0x5c,
0xd2, 0x76, 0x6a, 0xbb, 0x46, 0x6b, 0xee, 0xa1, 0x5b, 0x8a, 0xfa, 0x5e, 0x7f, 0xe8, 0x75, 0x56,
0x4c, 0xe4, 0x20, 0xb7, 0x61, 0xf5, 0xc9, 0x68, 0x12, 0x0e, 0x1b, 0x45, 0x64, 0xbd, 0x7c, 0x36,
0xeb, 0x07, 0x82, 0xb4, 0xb3, 0x62, 0x4a, 0x1e, 0xb1, 0xac, 0xe3, 0x3e, 0xf1, 0x1a, 0xa5, 0x3c,
0xcb, 0x76, 0xdd, 0x27, 0xb8, 0xac, 0xe0, 0x20, 0x1d, 0x80, 0x90, 0x71, 0xcb, 0xf3, 0xb9, 0xe3,
0xb9, 0x8d, 0x55, 0xe4, 0xbf, 0x7e, 0x36, 0xff, 0x03, 0xc6, 0x3f, 0x41, 0xf2, 0xce, 0x8a, 0xa9,
0x87, 0xd1, 0x40, 0x48, 0x72, 0x5c, 0x87, 0x5b, 0xfd, 0x21, 0x75, 0xdc, 0x46, 0x39, 0x8f, 0xa4,
0xae, 0xeb, 0xf0, 0x7d, 0x41, 0x2e, 0x24, 0x39, 0xd1, 0x40, 0xa8, 0xe2, 0xf3, 0x09, 0x0b, 0x4e,
0x1a, 0x95, 0x3c, 0xaa, 0xf8, 0x54, 0x90, 0x0a, 0x55, 0x20, 0x0f, 0xf9, 0x10, 0x6a, 0x3d, 0x36,
0x70, 0x5c, 0xab, 0x37, 0xf2, 0xfa, 0x47, 0x8d, 0x2a, 0x8a, 0xd8, 0x39, 0x5b, 0x44, 0x5b, 0x30,
0xb4, 0x05, 0x7d, 0x67, 0xc5, 0x84, 0x5e, 0x3c, 0x22, 0x6d, 0xa8, 0xf6, 0x87, 0xac, 0x7f, 0x64,
0xf1, 0xe3, 0x86, 0x8e, 0x92, 0xae, 0x9e, 0x2d, 0x69, 0x5f, 0x50, 0x3f, 0x3c, 0xee, 0xac, 0x98,
0x95, 0xbe, 0xfc, 0x14, 0x7a, 0xb1, 0xd9, 0xc8, 0x99, 0xb2, 0x40, 0x48, 0x39, 0x9f, 0x47, 0x2f,
0x77, 0x25, 0x3d, 0xca, 0xd1, 0xed, 0x68, 0x40, 0xee, 0x81, 0xce, 0x5c, 0x5b, 0x1d, 0xac, 0x86,
0x82, 0xae, 0x2d, 0xb1, 0x30, 0xd7, 0x8e, 0x8e, 0x55, 0x65, 0xea, 0x9b, 0xbc, 0x0f, 0xe5, 0xbe,
0x37, 0x1e, 0x3b, 0xbc, 0xb1, 0x86, 0x32, 0xae, 0x2c, 0x39, 0x12, 0xd2, 0x76, 0x56, 0x4c, 0xc5,
0xd5, 0xae, 0xc0, 0xea, 0x94, 0x8e, 0x26, 0xcc, 0xb8, 0x0e, 0xb5, 0x94, 0x25, 0x93, 0x06, 0x54,
0xc6, 0x2c, 0x0c, 0xe9, 0x80, 0x35, 0xb4, 0x4b, 0xda, 0x8e, 0x6e, 0x46, 0x43, 0x63, 0x03, 0xd6,
0xd2, 0x76, 0x6b, 0x8c, 0x63, 0x46, 0x61, 0x8b, 0x82, 0x71, 0xca, 0x82, 0x50, 0x18, 0xa0, 0x62,
0x54, 0x43, 0x72, 0x19, 0xd6, 0xf1, 0xb4, 0x56, 0xf4, 0xbb, 0xf0, 0xab, 0x92, 0xb9, 0x86, 0x93,
0x87, 0x8a, 0x68, 0x1b, 0x6a, 0xfe, 0xae, 0x1f, 0x93, 0x14, 0x91, 0x04, 0xfc, 0x5d, 0x5f, 0x11,
0x18, 0x3f, 0x80, 0xfa, 0xac, 0xe9, 0x92, 0x3a, 0x14, 0x8f, 0xd8, 0x89, 0x5a, 0x4f, 0x7c, 0x92,
0x0b, 0xea, 0x58, 0xb8, 0x86, 0x6e, 0xaa, 0x33, 0xfe, 0xbe, 0x10, 0x33, 0xc7, 0xd6, 0x2a, 0xdc,
0x4d, 0x04, 0x01, 0xe4, 0xae, 0xed, 0x36, 0x5b, 0x32, 0x42, 0xb4, 0xa2, 0x08, 0xd1, 0x7a, 0x18,
0x45, 0x88, 0x76, 0xf5, 0xcb, 0x67, 0xdb, 0x2b, 0xbf, 0xfe, 0xeb, 0xb6, 0x66, 0x22, 0x07, 0x79,
0x5d, 0x18, 0x14, 0x75, 0x5c, 0xcb, 0xb1, 0xd5, 0x3a, 0x15, 0x1c, 0x77, 0x6d, 0xf2, 0x29, 0xd4,
0xfb, 0x9e, 0x1b, 0x32, 0x37, 0x9c, 0x84, 0x96, 0x4f, 0x03, 0x3a, 0x0e, 0x55, 0x2c, 0x58, 0x74,
0xc9, 0xfb, 0x11, 0xf9, 0x01, 0x52, 0x9b, 0x9b, 0xfd, 0xec, 0x04, 0xb9, 0x0f, 0x30, 0xa5, 0x23,
0xc7, 0xa6, 0xdc, 0x0b, 0xc2, 0x46, 0xe9, 0x52, 0xf1, 0x0c, 0x61, 0x87, 0x11, 0xe1, 0x23, 0xdf,
0xa6, 0x9c, 0xb5, 0x4b, 0x62, 0xe7, 0x66, 0x8a, 0x9f, 0x5c, 0x83, 0x4d, 0xea, 0xfb, 0x56, 0xc8,
0x29, 0x67, 0x56, 0xef, 0x84, 0xb3, 0x10, 0xe3, 0xc5, 0x9a, 0xb9, 0x4e, 0x7d, 0xff, 0x81, 0x98,
0x6d, 0x8b, 0x49, 0xc3, 0x8e, 0x6f, 0x1b, 0x5d, 0x93, 0x10, 0x28, 0xd9, 0x94, 0x53, 0xd4, 0xd6,
0x9a, 0x89, 0xdf, 0x62, 0xce, 0xa7, 0x7c, 0xa8, 0x74, 0x80, 0xdf, 0xe4, 0x55, 0x28, 0x0f, 0x99,
0x33, 0x18, 0x72, 0x3c, 0x76, 0xd1, 0x54, 0x23, 0x71, 0x31, 0x7e, 0xe0, 0x4d, 0x19, 0x46, 0xb7,
0xaa, 0x29, 0x07, 0xc6, 0x6f, 0x0a, 0x70, 0xee, 0x39, 0xf7, 0x15, 0x72, 0x87, 0x34, 0x1c, 0x46,
0x6b, 0x89, 0x6f, 0x72, 0x5b, 0xc8, 0xa5, 0x36, 0x0b, 0x54, 0x54, 0x7e, 0x63, 0x81, 0x06, 0x3a,
0x48, 0xa4, 0x0e, 0xae, 0x58, 0xc8, 0x23, 0xa8, 0x8f, 0x68, 0xc8, 0x2d, 0x69, 0xfb, 0x16, 0x46,
0xd9, 0xe2, 0x99, 0x91, 0xe0, 0x3e, 0x8d, 0x7c, 0x46, 0x18, 0xb7, 0x12, 0xb7, 0x31, 0xca, 0xcc,
0x92, 0xc7, 0x70, 0xa1, 0x77, 0xf2, 0x73, 0xea, 0x72, 0xc7, 0x65, 0xd6, 0x73, 0x77, 0xb4, 0xbd,
0x40, 0xf4, 0xbd, 0xa9, 0x63, 0x33, 0xb7, 0x1f, 0x5d, 0xce, 0xf9, 0x58, 0x44, 0x7c, 0x79, 0xa1,
0xf1, 0x18, 0x36, 0xb2, 0xb1, 0x88, 0x6c, 0x40, 0x81, 0x1f, 0x2b, 0x8d, 0x14, 0xf8, 0x31, 0xf9,
0x3e, 0x94, 0x84, 0x38, 0xd4, 0xc6, 0xc6, 0x42, 0xb0, 0x50, 0xdc, 0x0f, 0x4f, 0x7c, 0x66, 0x22,
0xbd, 0x61, 0xc4, 0x9e, 0x10, 0xc7, 0xa7, 0x59, 0xd9, 0xc6, 0x0d, 0xd8, 0x9c, 0x09, 0x3d, 0xa9,
0x6b, 0xd5, 0xd2, 0xd7, 0x6a, 0x6c, 0xc2, 0x7a, 0x26, 0xc2, 0x18, 0x7f, 0x2a, 0x43, 0xd5, 0x64,
0xa1, 0x2f, 0x8c, 0x98, 0x74, 0x40, 0x67, 0xc7, 0x7d, 0x26, 0x61, 0x49, 0x5b, 0x12, 0xc4, 0x25,
0xcf, 0xbd, 0x88, 0x5e, 0x44, 0xcd, 0x98, 0x99, 0xdc, 0xca, 0x40, 0xf2, 0xe5, 0x65, 0x42, 0xd2,
0x98, 0x7c, 0x27, 0x8b, 0xc9, 0x57, 0x96, 0xf0, 0xce, 0x80, 0xf2, 0xad, 0x0c, 0x28, 0x2f, 0x5b,
0x38, 0x83, 0xca, 0xdd, 0x39, 0xa8, 0xbc, 0xec, 0xf8, 0x0b, 0x60, 0xb9, 0x3b, 0x07, 0x96, 0x77,
0x96, 0xee, 0x65, 0x2e, 0x2e, 0xdf, 0xc9, 0xe2, 0xf2, 0x32, 0x75, 0xcc, 0x00, 0xf3, 0xfd, 0x79,
0xc0, 0x7c, 0x63, 0x89, 0x8c, 0x85, 0xc8, 0xbc, 0xff, 0x1c, 0x32, 0x5f, 0x5b, 0x22, 0x6a, 0x0e,
0x34, 0x77, 0x33, 0xd0, 0x0c, 0xb9, 0x74, 0xb3, 0x00, 0x9b, 0x3f, 0x78, 0x1e, 0x9b, 0xaf, 0x2f,
0x33, 0xb5, 0x79, 0xe0, 0xfc, 0xc3, 0x19, 0x70, 0xbe, 0xba, 0xec, 0x54, 0x0b, 0xd1, 0xf9, 0x86,
0x88, 0x8f, 0x33, 0x9e, 0x21, 0x62, 0x29, 0x0b, 0x02, 0x2f, 0x50, 0xc0, 0x27, 0x07, 0xc6, 0x8e,
0x88, 0xd8, 0x89, 0xfd, 0x9f, 0x81, 0xe4, 0xe8, 0xb4, 0x29, 0x6b, 0x37, 0xbe, 0xd0, 0x12, 0x5e,
0x8c, 0x6c, 0xe9, 0x68, 0xaf, 0xab, 0x68, 0x9f, 0x02, 0xf8, 0x42, 0x16, 0xe0, 0xb7, 0xa1, 0x26,
0x30, 0x65, 0x06, 0xbb, 0xa9, 0x1f, 0x61, 0x37, 0x79, 0x13, 0xce, 0x61, 0xfc, 0x95, 0x69, 0x80,
0x0a, 0x24, 0x25, 0x0c, 0x24, 0x9b, 0xe2, 0x07, 0xa9, 0x41, 0x09, 0x14, 0x6f, 0xc3, 0xf9, 0x14,
0xad, 0x90, 0x8b, 0x58, 0x20, 0x41, 0xaa, 0x1e, 0x53, 0xef, 0xf9, 0x7e, 0x87, 0x86, 0x43, 0xe3,
0xa3, 0x44, 0x41, 0x49, 0x5e, 0x40, 0xa0, 0xd4, 0xf7, 0x6c, 0x79, 0xee, 0x75, 0x13, 0xbf, 0x45,
0xae, 0x30, 0xf2, 0x06, 0xb8, 0x39, 0xdd, 0x14, 0x9f, 0x82, 0x2a, 0x76, 0x6d, 0x5d, 0xfa, 0xac,
0xf1, 0x07, 0x2d, 0x91, 0x97, 0xa4, 0x0a, 0xf3, 0x50, 0x5d, 0x7b, 0x99, 0xa8, 0x5e, 0xf8, 0xff,
0x50, 0xdd, 0xf8, 0xb7, 0x96, 0x5c, 0x69, 0x8c, 0xd7, 0x5f, 0x4f, 0x05, 0xc2, 0xba, 0x1c, 0xd7,
0x66, 0xc7, 0xa8, 0xf2, 0xa2, 0x29, 0x07, 0x51, 0xaa, 0x55, 0xc6, 0x6b, 0xc8, 0xa6, 0x5a, 0x15,
0x9c, 0x93, 0x03, 0xf2, 0x2e, 0xe2, 0xbc, 0xf7, 0x44, 0x85, 0x86, 0x0c, 0x08, 0xca, 0xaa, 0xae,
0xa5, 0xca, 0xb9, 0x03, 0x41, 0x66, 0x4a, 0xea, 0x14, 0xbe, 0xe8, 0x99, 0xb4, 0xe1, 0x22, 0xe8,
0x62, 0xeb, 0xa1, 0x4f, 0xfb, 0x0c, 0x7d, 0x5b, 0x37, 0x93, 0x09, 0xc3, 0x06, 0xf2, 0x7c, 0x8c,
0x21, 0x1f, 0x43, 0x99, 0x4d, 0x99, 0xcb, 0xc5, 0x1d, 0x09, 0xb5, 0x5e, 0x5c, 0x08, 0xc4, 0xcc,
0xe5, 0xed, 0x86, 0x50, 0xe6, 0xbf, 0x9e, 0x6d, 0xd7, 0x25, 0xcf, 0x5b, 0xde, 0xd8, 0xe1, 0x6c,
0xec, 0xf3, 0x13, 0x53, 0x49, 0x31, 0x7e, 0x59, 0x10, 0x78, 0x98, 0x89, 0x3f, 0x73, 0xd5, 0x1b,
0x39, 0x4d, 0x21, 0x95, 0x22, 0xe5, 0x53, 0xf9, 0x1b, 0x00, 0x03, 0x1a, 0x5a, 0x4f, 0xa9, 0xcb,
0x99, 0xad, 0xf4, 0xae, 0x0f, 0x68, 0xf8, 0x63, 0x9c, 0x10, 0xf9, 0xa6, 0xf8, 0x79, 0x12, 0x32,
0x1b, 0x2f, 0xa0, 0x68, 0x56, 0x06, 0x34, 0x7c, 0x14, 0x32, 0x3b, 0x75, 0xd6, 0xca, 0xcb, 0x38,
0x6b, 0x56, 0xdf, 0xd5, 0x59, 0x7d, 0xff, 0xaa, 0x90, 0x78, 0x47, 0x92, 0x3e, 0x7c, 0x33, 0x75,
0xf1, 0x5b, 0xac, 0x29, 0xb2, 0x20, 0x40, 0x7e, 0x02, 0xe7, 0x62, 0xaf, 0xb4, 0x26, 0xe8, 0xad,
0x91, 0x15, 0xbe, 0x98, 0x73, 0xd7, 0xa7, 0xd9, 0xe9, 0x90, 0x7c, 0x06, 0xaf, 0xcd, 0xc4, 0xa0,
0x78, 0x81, 0xc2, 0x0b, 0x85, 0xa2, 0x57, 0xb2, 0xa1, 0x28, 0x92, 0x9f, 0x68, 0xaf, 0xf8, 0x52,
0xbc, 0xe6, 0x8a, 0x48, 0x61, 0xd3, 0xf0, 0x36, 0xcf, 0x26, 0x8c, 0xbf, 0x68, 0xb0, 0x39, 0xb3,
0x41, 0xf2, 0x1e, 0xac, 0x4a, 0x04, 0xd6, 0xce, 0x6c, 0x84, 0xa0, 0xc6, 0xd5, 0x99, 0x24, 0x03,
0xd9, 0x83, 0x2a, 0x53, 0xd9, 0xb5, 0x52, 0xca, 0xd5, 0x25, 0x49, 0xb8, 0xe2, 0x8f, 0xd9, 0xc8,
0x5d, 0xd0, 0x63, 0xd5, 0x2f, 0xa9, 0xdc, 0xe2, 0x9b, 0x53, 0x42, 0x12, 0x46, 0x63, 0x1f, 0x6a,
0xa9, 0xed, 0x91, 0x6f, 0x81, 0x3e, 0xa6, 0xc7, 0xaa, 0xdc, 0x92, 0x09, 0x74, 0x75, 0x4c, 0x8f,
0xb1, 0xd2, 0x22, 0xaf, 0x41, 0x45, 0xfc, 0x38, 0xa0, 0xf2, 0x22, 0x8b, 0x66, 0x79, 0x4c, 0x8f,
0x7f, 0x44, 0x43, 0xe3, 0x06, 0x6c, 0x64, 0xb7, 0x19, 0x91, 0x46, 0x90, 0x2e, 0x49, 0xf7, 0x06,
0xcc, 0x78, 0x17, 0x36, 0x67, 0x76, 0x43, 0x0c, 0x58, 0xf7, 0x27, 0x3d, 0xeb, 0x88, 0x9d, 0x58,
0xb8, 0x5d, 0x34, 0x43, 0xdd, 0xac, 0xf9, 0x93, 0xde, 0x87, 0xec, 0x44, 0x54, 0x04, 0xa1, 0xd1,
0x87, 0x8d, 0x6c, 0xa1, 0x23, 0x82, 0x7a, 0xe0, 0x4d, 0x5c, 0x1b, 0xe5, 0xaf, 0x9a, 0x72, 0x40,
0x6e, 0xc3, 0xea, 0xd4, 0x93, 0x96, 0x76, 0x56, 0x65, 0x73, 0xe8, 0x71, 0x96, 0x2a, 0x97, 0x24,
0x8f, 0x11, 0xc2, 0x2a, 0xda, 0x8c, 0xb8, 0x7f, 0x2c, 0x59, 0x54, 0x52, 0x21, 0xbe, 0xc9, 0x21,
0x00, 0xe5, 0x3c, 0x70, 0x7a, 0x93, 0x44, 0x7c, 0x23, 0x2d, 0x7e, 0xe4, 0xf4, 0xc2, 0xd6, 0xd1,
0xb4, 0x75, 0x40, 0x9d, 0xa0, 0x7d, 0x51, 0x59, 0xdd, 0x85, 0x84, 0x27, 0x65, 0x79, 0x29, 0x49,
0xc6, 0x57, 0x25, 0x28, 0xcb, 0x52, 0x90, 0xbc, 0x9f, 0x6d, 0x4c, 0xd4, 0x76, 0xb7, 0x16, 0x6d,
0x5f, 0x52, 0xa9, 0xdd, 0xc7, 0xd9, 0xcd, 0xb5, 0xd9, 0x6a, 0xbf, 0x5d, 0x3b, 0x7d, 0xb6, 0x5d,
0xc1, 0xcc, 0xa0, 0x7b, 0x37, 0x29, 0xfd, 0x17, 0x55, 0xbe, 0x51, 0x9f, 0xa1, 0xf4, 0xc2, 0x7d,
0x86, 0x0e, 0xac, 0xa7, 0x52, 0x21, 0xc7, 0x56, 0x35, 0xc4, 0xd6, 0x59, 0x0e, 0xd1, 0xbd, 0xab,
0xf6, 0x5f, 0x8b, 0x53, 0xa5, 0xae, 0x4d, 0x76, 0xb2, 0x05, 0x30, 0x66, 0x54, 0x12, 0xca, 0x53,
0x35, 0xad, 0xc8, 0xa7, 0x84, 0xa9, 0x0a, 0xc7, 0x94, 0x24, 0x12, 0xd9, 0xab, 0x62, 0x02, 0x7f,
0xbc, 0x0e, 0x9b, 0x49, 0xd2, 0x21, 0x49, 0xaa, 0x52, 0x4a, 0x32, 0x8d, 0x84, 0xef, 0xc0, 0x05,
0x97, 0x1d, 0x73, 0x6b, 0x96, 0x5a, 0x47, 0x6a, 0x22, 0x7e, 0x3b, 0xcc, 0x72, 0x5c, 0x85, 0x8d,
0x24, 0xbc, 0x21, 0x2d, 0xc8, 0xb6, 0x44, 0x3c, 0x8b, 0x64, 0xaf, 0x43, 0x35, 0x4e, 0x09, 0x6b,
0x48, 0x50, 0xa1, 0x32, 0x13, 0x8c, 0x93, 0xcc, 0x80, 0x85, 0x93, 0x11, 0x57, 0x42, 0xd6, 0x90,
0x06, 0x93, 0x4c, 0x53, 0xce, 0x23, 0xed, 0x65, 0x58, 0x8f, 0x3c, 0x5e, 0xd2, 0xad, 0x23, 0xdd,
0x5a, 0x34, 0x89, 0x44, 0x37, 0xa0, 0xee, 0x07, 0x9e, 0xef, 0x85, 0x2c, 0xb0, 0xa8, 0x6d, 0x07,
0x2c, 0x0c, 0x1b, 0x1b, 0x52, 0x5e, 0x34, 0xbf, 0x27, 0xa7, 0x8d, 0xef, 0x40, 0x25, 0xca, 0x75,
0x2f, 0xc0, 0x6a, 0x3b, 0x8e, 0x5e, 0x25, 0x53, 0x0e, 0x04, 0xf6, 0xed, 0xf9, 0xbe, 0xea, 0x7c,
0x89, 0x4f, 0x63, 0x04, 0x15, 0x75, 0x61, 0x73, 0xfb, 0x1d, 0x1f, 0xc1, 0x9a, 0x4f, 0x03, 0x71,
0x8c, 0x74, 0xd7, 0x63, 0x51, 0xb5, 0x76, 0x40, 0x03, 0xfe, 0x80, 0xf1, 0x4c, 0xf3, 0xa3, 0x86,
0xfc, 0x72, 0xca, 0xb8, 0x05, 0xeb, 0x19, 0x1a, 0xb1, 0x4d, 0xee, 0x71, 0x3a, 0x8a, 0x1c, 0x1d,
0x07, 0xf1, 0x4e, 0x0a, 0xc9, 0x4e, 0x8c, 0xdb, 0xa0, 0xc7, 0x77, 0x25, 0x8a, 0x80, 0x48, 0x15,
0x9a, 0x52, 0xbf, 0x1c, 0x62, 0x83, 0xc7, 0x7b, 0xca, 0x02, 0x65, 0xfd, 0x72, 0x60, 0xb0, 0x54,
0x60, 0x92, 0x48, 0x43, 0xee, 0x40, 0x45, 0x05, 0x26, 0xe5, 0x8f, 0x8b, 0x5a, 0x39, 0x07, 0x18,
0xa9, 0xa2, 0x56, 0x8e, 0x8c, 0x5b, 0xc9, 0x32, 0x85, 0xf4, 0x32, 0xbf, 0x80, 0x6a, 0x14, 0x7c,
0xb2, 0x11, 0x5c, 0xae, 0x70, 0x69, 0x59, 0x04, 0x57, 0x8b, 0x24, 0x8c, 0xc2, 0x9a, 0x42, 0x67,
0xe0, 0x32, 0xdb, 0x4a, 0x5c, 0x10, 0xd7, 0xac, 0x9a, 0x9b, 0xf2, 0x87, 0xfb, 0x91, 0x7f, 0x19,
0xef, 0x40, 0x59, 0xee, 0x75, 0x6e, 0x88, 0x9b, 0x07, 0x7b, 0xff, 0xd4, 0xa0, 0x1a, 0xc5, 0xf6,
0xb9, 0x4c, 0x99, 0x43, 0x14, 0xbe, 0xee, 0x21, 0x5e, 0x7e, 0x48, 0x7a, 0x0b, 0x08, 0x5a, 0x8a,
0x35, 0xf5, 0xb8, 0xe3, 0x0e, 0x2c, 0x79, 0x17, 0x32, 0x4b, 0xab, 0xe3, 0x2f, 0x87, 0xf8, 0xc3,
0x81, 0x98, 0x7f, 0xf3, 0x32, 0xd4, 0x52, 0x1d, 0x28, 0x52, 0x81, 0xe2, 0xc7, 0xec, 0x69, 0x7d,
0x85, 0xd4, 0xa0, 0x62, 0x32, 0xac, 0xdf, 0xeb, 0xda, 0xee, 0x57, 0x15, 0xd8, 0xdc, 0x6b, 0xef,
0x77, 0xf7, 0x7c, 0x7f, 0xe4, 0xf4, 0x29, 0x16, 0x70, 0x9f, 0x40, 0x09, 0x6b, 0xd8, 0x1c, 0x6f,
0x2f, 0xcd, 0x3c, 0xcd, 0x20, 0x62, 0xc2, 0x2a, 0x96, 0xba, 0x24, 0xcf, 0x93, 0x4c, 0x33, 0x57,
0x8f, 0x48, 0x6c, 0x12, 0x0d, 0x2e, 0xc7, 0x4b, 0x4d, 0x33, 0x4f, 0xe3, 0x88, 0x7c, 0x06, 0x7a,
0x52, 0xc3, 0xe6, 0x7d, 0xbf, 0x69, 0xe6, 0x6e, 0x29, 0x09, 0xf9, 0x49, 0xd6, 0x9e, 0xf7, 0xf5,
0xa2, 0x99, 0xbb, 0x97, 0x42, 0x1e, 0x43, 0x25, 0xaa, 0x8f, 0xf2, 0xbd, 0xb0, 0x34, 0x73, 0xb6,
0x7b, 0xc4, 0xf5, 0xc9, 0xb2, 0x36, 0xcf, 0x33, 0x52, 0x33, 0x57, 0x4f, 0x8b, 0x3c, 0x82, 0xb2,
0x4a, 0x4c, 0x73, 0xbd, 0x9d, 0x34, 0xf3, 0x35, 0x71, 0x84, 0x92, 0x93, 0xc6, 0x41, 0xde, 0xa7,
0xb3, 0x66, 0xee, 0x66, 0x1e, 0xa1, 0x00, 0xa9, 0x5a, 0x37, 0xf7, 0x9b, 0x58, 0x33, 0x7f, 0x93,
0x8e, 0xfc, 0x0c, 0xaa, 0x71, 0x45, 0x93, 0xf3, 0x6d, 0xaa, 0x99, 0xb7, 0x4f, 0xd6, 0xee, 0xfe,
0xf7, 0xef, 0x5b, 0xda, 0xef, 0x4e, 0xb7, 0xb4, 0x2f, 0x4e, 0xb7, 0xb4, 0x2f, 0x4f, 0xb7, 0xb4,
0x3f, 0x9f, 0x6e, 0x69, 0x7f, 0x3b, 0xdd, 0xd2, 0xfe, 0xf8, 0x8f, 0x2d, 0xed, 0xa7, 0xdf, 0x5e,
0xfa, 0xba, 0x9b, 0xbc, 0x4c, 0xf7, 0xca, 0x18, 0xb0, 0xbe, 0xfb, 0xbf, 0x00, 0x00, 0x00, 0xff,
0xff, 0x83, 0x66, 0x2e, 0x0b, 0xae, 0x1e, 0x00, 0x00,
0x15, 0xde, 0xd1, 0x6a, 0xf5, 0xf3, 0xb4, 0xbb, 0x52, 0x3a, 0x4e, 0x22, 0x0b, 0x67, 0xd7, 0x35,
0xfe, 0x5b, 0xe7, 0x47, 0x0e, 0x0b, 0xa1, 0x62, 0xec, 0x0a, 0xb5, 0x5a, 0x3b, 0x48, 0x15, 0xdb,
0xd9, 0x8c, 0xed, 0xc5, 0x40, 0x55, 0xa6, 0x5a, 0x9a, 0xb6, 0x34, 0xb5, 0xd2, 0xcc, 0x64, 0xa6,
0x25, 0x6b, 0x29, 0xee, 0x14, 0x55, 0x1c, 0xb8, 0x50, 0xc5, 0x85, 0x3b, 0x47, 0x0e, 0x1c, 0x72,
0xe4, 0x98, 0x03, 0x07, 0x0e, 0x9c, 0x0d, 0x2c, 0x9c, 0xa8, 0x1c, 0x29, 0x8a, 0x23, 0xd5, 0xaf,
0x7b, 0xfe, 0xb4, 0xd2, 0x6a, 0x1c, 0x7c, 0xe3, 0x22, 0x4d, 0x77, 0xbf, 0xf7, 0xba, 0xfb, 0xf5,
0xeb, 0xf7, 0xbd, 0xf7, 0x1a, 0x5e, 0xa7, 0xdd, 0x9e, 0x7d, 0x83, 0x1f, 0x7b, 0x2c, 0x90, 0xbf,
0x4d, 0xcf, 0x77, 0xb9, 0x4b, 0x5e, 0xe3, 0xcc, 0xb1, 0x98, 0x3f, 0xb2, 0x1d, 0xde, 0x14, 0x24,
0x4d, 0x1c, 0x6c, 0xbc, 0xdb, 0xb7, 0xf9, 0x60, 0xdc, 0x6d, 0xf6, 0xdc, 0xd1, 0x8d, 0xbe, 0xdb,
0x77, 0x6f, 0x20, 0x75, 0x77, 0xfc, 0x14, 0x5b, 0xd8, 0xc0, 0x2f, 0x29, 0xa5, 0x71, 0x2b, 0x41,
0x1e, 0x0b, 0x4c, 0x7e, 0xf6, 0xfc, 0x63, 0x8f, 0xbb, 0x37, 0x46, 0xcc, 0x3f, 0x1a, 0x32, 0xf5,
0xa7, 0x98, 0xbf, 0xbd, 0x94, 0x79, 0x68, 0x77, 0x83, 0x1b, 0x47, 0x93, 0xe4, 0xc2, 0x1b, 0xdb,
0x7d, 0xd7, 0xed, 0x0f, 0x59, 0xbc, 0x30, 0x6e, 0x8f, 0x58, 0xc0, 0xe9, 0xc8, 0x53, 0x04, 0x5b,
0xb3, 0x04, 0xd6, 0xd8, 0xa7, 0xdc, 0x76, 0x1d, 0x39, 0xae, 0xff, 0x7b, 0x0d, 0x8a, 0x06, 0xfb,
0x7c, 0xcc, 0x02, 0x4e, 0x3e, 0x80, 0x3c, 0xeb, 0x0d, 0xdc, 0x7a, 0xee, 0xa2, 0xb6, 0x53, 0xd9,
0xd5, 0x9b, 0x73, 0x95, 0xd2, 0x54, 0xd4, 0x77, 0x7b, 0x03, 0xb7, 0xbd, 0x62, 0x20, 0x07, 0xb9,
0x05, 0x6b, 0x4f, 0x87, 0xe3, 0x60, 0x50, 0x5f, 0x45, 0xd6, 0x4b, 0x67, 0xb3, 0x7e, 0x24, 0x48,
0xdb, 0x2b, 0x86, 0xe4, 0x11, 0xd3, 0xda, 0xce, 0x53, 0xb7, 0x9e, 0xcf, 0x32, 0x6d, 0xc7, 0x79,
0x8a, 0xd3, 0x0a, 0x0e, 0xd2, 0x06, 0x08, 0x18, 0x37, 0x5d, 0x4f, 0x6c, 0xa8, 0xbe, 0x86, 0xfc,
0xd7, 0xce, 0xe6, 0x7f, 0xc8, 0xf8, 0x27, 0x48, 0xde, 0x5e, 0x31, 0xca, 0x41, 0xd8, 0x10, 0x92,
0x6c, 0xc7, 0xe6, 0x66, 0x6f, 0x40, 0x6d, 0xa7, 0x5e, 0xc8, 0x22, 0xa9, 0xe3, 0xd8, 0x7c, 0x5f,
0x90, 0x0b, 0x49, 0x76, 0xd8, 0x10, 0xaa, 0xf8, 0x7c, 0xcc, 0xfc, 0xe3, 0x7a, 0x31, 0x8b, 0x2a,
0x3e, 0x15, 0xa4, 0x42, 0x15, 0xc8, 0x43, 0x3e, 0x86, 0x4a, 0x97, 0xf5, 0x6d, 0xc7, 0xec, 0x0e,
0xdd, 0xde, 0x51, 0xbd, 0x84, 0x22, 0x76, 0xce, 0x16, 0xd1, 0x12, 0x0c, 0x2d, 0x41, 0xdf, 0x5e,
0x31, 0xa0, 0x1b, 0xb5, 0x48, 0x0b, 0x4a, 0xbd, 0x01, 0xeb, 0x1d, 0x99, 0x7c, 0x5a, 0x2f, 0xa3,
0xa4, 0x2b, 0x67, 0x4b, 0xda, 0x17, 0xd4, 0x8f, 0xa6, 0xed, 0x15, 0xa3, 0xd8, 0x93, 0x9f, 0x42,
0x2f, 0x16, 0x1b, 0xda, 0x13, 0xe6, 0x0b, 0x29, 0xaf, 0x66, 0xd1, 0xcb, 0x1d, 0x49, 0x8f, 0x72,
0xca, 0x56, 0xd8, 0x20, 0x77, 0xa1, 0xcc, 0x1c, 0x4b, 0x6d, 0xac, 0x82, 0x82, 0xae, 0x2e, 0xb1,
0x30, 0xc7, 0x0a, 0xb7, 0x55, 0x62, 0xea, 0x9b, 0x7c, 0x08, 0x85, 0x9e, 0x3b, 0x1a, 0xd9, 0xbc,
0xbe, 0x8e, 0x32, 0x2e, 0x2f, 0xd9, 0x12, 0xd2, 0xb6, 0x57, 0x0c, 0xc5, 0xd5, 0x2a, 0xc2, 0xda,
0x84, 0x0e, 0xc7, 0x4c, 0xbf, 0x06, 0x95, 0x84, 0x25, 0x93, 0x3a, 0x14, 0x47, 0x2c, 0x08, 0x68,
0x9f, 0xd5, 0xb5, 0x8b, 0xda, 0x4e, 0xd9, 0x08, 0x9b, 0xfa, 0x26, 0xac, 0x27, 0xed, 0x56, 0x1f,
0x45, 0x8c, 0xc2, 0x16, 0x05, 0xe3, 0x84, 0xf9, 0x81, 0x30, 0x40, 0xc5, 0xa8, 0x9a, 0xe4, 0x12,
0x6c, 0xe0, 0x6e, 0xcd, 0x70, 0x5c, 0xdc, 0xab, 0xbc, 0xb1, 0x8e, 0x9d, 0x87, 0x8a, 0x68, 0x1b,
0x2a, 0xde, 0xae, 0x17, 0x91, 0xac, 0x22, 0x09, 0x78, 0xbb, 0x9e, 0x22, 0xd0, 0xbf, 0x0b, 0xb5,
0x59, 0xd3, 0x25, 0x35, 0x58, 0x3d, 0x62, 0xc7, 0x6a, 0x3e, 0xf1, 0x49, 0xce, 0xa9, 0x6d, 0xe1,
0x1c, 0x65, 0x43, 0xed, 0xf1, 0x77, 0xb9, 0x88, 0x39, 0xb2, 0x56, 0x71, 0xdd, 0x84, 0x93, 0x40,
0xee, 0xca, 0x6e, 0xa3, 0x29, 0x1d, 0x44, 0x33, 0x74, 0x10, 0xcd, 0x47, 0xa1, 0x07, 0x69, 0x95,
0xbe, 0x7c, 0xbe, 0xbd, 0xf2, 0xcb, 0xbf, 0x6c, 0x6b, 0x06, 0x72, 0x90, 0xf3, 0xc2, 0xa0, 0xa8,
0xed, 0x98, 0xb6, 0xa5, 0xe6, 0x29, 0x62, 0xbb, 0x63, 0x91, 0x4f, 0xa1, 0xd6, 0x73, 0x9d, 0x80,
0x39, 0xc1, 0x38, 0x30, 0x3d, 0xea, 0xd3, 0x51, 0xa0, 0x7c, 0xc1, 0xa2, 0x43, 0xde, 0x0f, 0xc9,
0x0f, 0x90, 0xda, 0xa8, 0xf6, 0xd2, 0x1d, 0xe4, 0x1e, 0xc0, 0x84, 0x0e, 0x6d, 0x8b, 0x72, 0xd7,
0x0f, 0xea, 0xf9, 0x8b, 0xab, 0x67, 0x08, 0x3b, 0x0c, 0x09, 0x1f, 0x7b, 0x16, 0xe5, 0xac, 0x95,
0x17, 0x2b, 0x37, 0x12, 0xfc, 0xe4, 0x2a, 0x54, 0xa9, 0xe7, 0x99, 0x01, 0xa7, 0x9c, 0x99, 0xdd,
0x63, 0xce, 0x02, 0xf4, 0x17, 0xeb, 0xc6, 0x06, 0xf5, 0xbc, 0x87, 0xa2, 0xb7, 0x25, 0x3a, 0x75,
0x2b, 0x3a, 0x6d, 0xbc, 0x9a, 0x84, 0x40, 0xde, 0xa2, 0x9c, 0xa2, 0xb6, 0xd6, 0x0d, 0xfc, 0x16,
0x7d, 0x1e, 0xe5, 0x03, 0xa5, 0x03, 0xfc, 0x26, 0xaf, 0x43, 0x61, 0xc0, 0xec, 0xfe, 0x80, 0xe3,
0xb6, 0x57, 0x0d, 0xd5, 0x12, 0x07, 0xe3, 0xf9, 0xee, 0x84, 0xa1, 0x77, 0x2b, 0x19, 0xb2, 0xa1,
0xff, 0x2a, 0x07, 0xaf, 0x9c, 0xba, 0xbe, 0x42, 0xee, 0x80, 0x06, 0x83, 0x70, 0x2e, 0xf1, 0x4d,
0x6e, 0x09, 0xb9, 0xd4, 0x62, 0xbe, 0xf2, 0xca, 0x6f, 0x2e, 0xd0, 0x40, 0x1b, 0x89, 0xd4, 0xc6,
0x15, 0x0b, 0x79, 0x0c, 0xb5, 0x21, 0x0d, 0xb8, 0x29, 0x6d, 0xdf, 0x44, 0x2f, 0xbb, 0x7a, 0xa6,
0x27, 0xb8, 0x47, 0xc3, 0x3b, 0x23, 0x8c, 0x5b, 0x89, 0xdb, 0x1c, 0xa6, 0x7a, 0xc9, 0x13, 0x38,
0xd7, 0x3d, 0xfe, 0x09, 0x75, 0xb8, 0xed, 0x30, 0xf3, 0xd4, 0x19, 0x6d, 0x2f, 0x10, 0x7d, 0x77,
0x62, 0x5b, 0xcc, 0xe9, 0x85, 0x87, 0xf3, 0x6a, 0x24, 0x22, 0x3a, 0xbc, 0x40, 0x7f, 0x02, 0x9b,
0x69, 0x5f, 0x44, 0x36, 0x21, 0xc7, 0xa7, 0x4a, 0x23, 0x39, 0x3e, 0x25, 0xdf, 0x81, 0xbc, 0x10,
0x87, 0xda, 0xd8, 0x5c, 0x08, 0x16, 0x8a, 0xfb, 0xd1, 0xb1, 0xc7, 0x0c, 0xa4, 0xd7, 0xf5, 0xe8,
0x26, 0x44, 0xfe, 0x69, 0x56, 0xb6, 0x7e, 0x1d, 0xaa, 0x33, 0xae, 0x27, 0x71, 0xac, 0x5a, 0xf2,
0x58, 0xf5, 0x2a, 0x6c, 0xa4, 0x3c, 0x8c, 0xfe, 0xc7, 0x02, 0x94, 0x0c, 0x16, 0x78, 0xc2, 0x88,
0x49, 0x1b, 0xca, 0x6c, 0xda, 0x63, 0x12, 0x96, 0xb4, 0x25, 0x4e, 0x5c, 0xf2, 0xdc, 0x0d, 0xe9,
0x85, 0xd7, 0x8c, 0x98, 0xc9, 0xcd, 0x14, 0x24, 0x5f, 0x5a, 0x26, 0x24, 0x89, 0xc9, 0xb7, 0xd3,
0x98, 0x7c, 0x79, 0x09, 0xef, 0x0c, 0x28, 0xdf, 0x4c, 0x81, 0xf2, 0xb2, 0x89, 0x53, 0xa8, 0xdc,
0x99, 0x83, 0xca, 0xcb, 0xb6, 0xbf, 0x00, 0x96, 0x3b, 0x73, 0x60, 0x79, 0x67, 0xe9, 0x5a, 0xe6,
0xe2, 0xf2, 0xed, 0x34, 0x2e, 0x2f, 0x53, 0xc7, 0x0c, 0x30, 0xdf, 0x9b, 0x07, 0xcc, 0xd7, 0x97,
0xc8, 0x58, 0x88, 0xcc, 0xfb, 0xa7, 0x90, 0xf9, 0xea, 0x12, 0x51, 0x73, 0xa0, 0xb9, 0x93, 0x82,
0x66, 0xc8, 0xa4, 0x9b, 0x05, 0xd8, 0xfc, 0xd1, 0x69, 0x6c, 0xbe, 0xb6, 0xcc, 0xd4, 0xe6, 0x81,
0xf3, 0xf7, 0x66, 0xc0, 0xf9, 0xca, 0xb2, 0x5d, 0x2d, 0x44, 0xe7, 0xeb, 0xc2, 0x3f, 0xce, 0xdc,
0x0c, 0xe1, 0x4b, 0x99, 0xef, 0xbb, 0xbe, 0x02, 0x3e, 0xd9, 0xd0, 0x77, 0x84, 0xc7, 0x8e, 0xed,
0xff, 0x0c, 0x24, 0xc7, 0x4b, 0x9b, 0xb0, 0x76, 0xfd, 0x0b, 0x2d, 0xe6, 0x45, 0xcf, 0x96, 0xf4,
0xf6, 0x65, 0xe5, 0xed, 0x13, 0x00, 0x9f, 0x4b, 0x03, 0xfc, 0x36, 0x54, 0x04, 0xa6, 0xcc, 0x60,
0x37, 0xf5, 0x42, 0xec, 0x26, 0x6f, 0xc1, 0x2b, 0xe8, 0x7f, 0x65, 0x18, 0xa0, 0x1c, 0x49, 0x1e,
0x1d, 0x49, 0x55, 0x0c, 0x48, 0x0d, 0x4a, 0xa0, 0x78, 0x17, 0x5e, 0x4d, 0xd0, 0x0a, 0xb9, 0x88,
0x05, 0x12, 0xa4, 0x6a, 0x11, 0xf5, 0x9e, 0xe7, 0xb5, 0x69, 0x30, 0xd0, 0xef, 0xc7, 0x0a, 0x8a,
0xe3, 0x02, 0x02, 0xf9, 0x9e, 0x6b, 0xc9, 0x7d, 0x6f, 0x18, 0xf8, 0x2d, 0x62, 0x85, 0xa1, 0xdb,
0xc7, 0xc5, 0x95, 0x0d, 0xf1, 0x29, 0xa8, 0xa2, 0xab, 0x5d, 0x96, 0x77, 0x56, 0xff, 0xbd, 0x16,
0xcb, 0x8b, 0x43, 0x85, 0x79, 0xa8, 0xae, 0xbd, 0x4c, 0x54, 0xcf, 0xfd, 0x6f, 0xa8, 0xae, 0xff,
0x4b, 0x8b, 0x8f, 0x34, 0xc2, 0xeb, 0xaf, 0xa7, 0x02, 0x61, 0x5d, 0xb6, 0x63, 0xb1, 0x29, 0xaa,
0x7c, 0xd5, 0x90, 0x8d, 0x30, 0xd4, 0x2a, 0xe0, 0x31, 0xa4, 0x43, 0xad, 0x22, 0xf6, 0xc9, 0x06,
0x79, 0x1f, 0x71, 0xde, 0x7d, 0xaa, 0x5c, 0x43, 0x0a, 0x04, 0x65, 0xd6, 0xd7, 0x54, 0xe9, 0xde,
0x81, 0x20, 0x33, 0x24, 0x75, 0x02, 0x5f, 0xca, 0xa9, 0xb0, 0xe1, 0x02, 0x94, 0xc5, 0xd2, 0x03,
0x8f, 0xf6, 0x18, 0xde, 0xed, 0xb2, 0x11, 0x77, 0xe8, 0x16, 0x90, 0xd3, 0x3e, 0x86, 0x3c, 0x80,
0x02, 0x9b, 0x30, 0x87, 0x8b, 0x33, 0x12, 0x6a, 0xbd, 0xb0, 0x10, 0x88, 0x99, 0xc3, 0x5b, 0x75,
0xa1, 0xcc, 0x7f, 0x3e, 0xdf, 0xae, 0x49, 0x9e, 0x77, 0xdc, 0x91, 0xcd, 0xd9, 0xc8, 0xe3, 0xc7,
0x86, 0x92, 0xa2, 0xff, 0x2c, 0x27, 0xf0, 0x30, 0xe5, 0x7f, 0xe6, 0xaa, 0x37, 0xbc, 0x34, 0xb9,
0x44, 0x88, 0x94, 0x4d, 0xe5, 0x6f, 0x02, 0xf4, 0x69, 0x60, 0x3e, 0xa3, 0x0e, 0x67, 0x96, 0xd2,
0x7b, 0xb9, 0x4f, 0x83, 0x1f, 0x60, 0x87, 0x88, 0x37, 0xc5, 0xf0, 0x38, 0x60, 0x16, 0x1e, 0xc0,
0xaa, 0x51, 0xec, 0xd3, 0xe0, 0x71, 0xc0, 0xac, 0xc4, 0x5e, 0x8b, 0x2f, 0x63, 0xaf, 0x69, 0x7d,
0x97, 0x66, 0xf5, 0xfd, 0xf3, 0x5c, 0x7c, 0x3b, 0xe2, 0xf0, 0xe1, 0xff, 0x53, 0x17, 0xbf, 0xc1,
0x9c, 0x22, 0x0d, 0x02, 0xe4, 0x87, 0xf0, 0x4a, 0x74, 0x2b, 0xcd, 0x31, 0xde, 0xd6, 0xd0, 0x0a,
0x5f, 0xec, 0x72, 0xd7, 0x26, 0xe9, 0xee, 0x80, 0x7c, 0x06, 0x6f, 0xcc, 0xf8, 0xa0, 0x68, 0x82,
0xdc, 0x0b, 0xb9, 0xa2, 0xd7, 0xd2, 0xae, 0x28, 0x94, 0x1f, 0x6b, 0x6f, 0xf5, 0xa5, 0xdc, 0x9a,
0xcb, 0x22, 0x84, 0x4d, 0xc2, 0xdb, 0x3c, 0x9b, 0xd0, 0xff, 0xac, 0x41, 0x75, 0x66, 0x81, 0xe4,
0x03, 0x58, 0x93, 0x08, 0xac, 0x9d, 0x59, 0x08, 0x41, 0x8d, 0xab, 0x3d, 0x49, 0x06, 0xb2, 0x07,
0x25, 0xa6, 0xa2, 0x6b, 0xa5, 0x94, 0x2b, 0x4b, 0x82, 0x70, 0xc5, 0x1f, 0xb1, 0x91, 0x3b, 0x50,
0x8e, 0x54, 0xbf, 0x24, 0x73, 0x8b, 0x4e, 0x4e, 0x09, 0x89, 0x19, 0xf5, 0x7d, 0xa8, 0x24, 0x96,
0x47, 0xbe, 0x01, 0xe5, 0x11, 0x9d, 0xaa, 0x74, 0x4b, 0x06, 0xd0, 0xa5, 0x11, 0x9d, 0x62, 0xa6,
0x45, 0xde, 0x80, 0xa2, 0x18, 0xec, 0x53, 0x79, 0x90, 0xab, 0x46, 0x61, 0x44, 0xa7, 0xdf, 0xa7,
0x81, 0xfe, 0x0b, 0x0d, 0x36, 0xd3, 0xeb, 0x24, 0x6f, 0x03, 0x11, 0xb4, 0xb4, 0xcf, 0x4c, 0x67,
0x3c, 0x92, 0x18, 0x19, 0x4a, 0xac, 0x8e, 0xe8, 0x74, 0xaf, 0xcf, 0x1e, 0x8c, 0x47, 0x38, 0x75,
0x40, 0xee, 0x43, 0x2d, 0x24, 0x0e, 0x8b, 0x5d, 0x4a, 0x2b, 0xe7, 0x4f, 0x25, 0xbb, 0x77, 0x14,
0x81, 0xcc, 0x75, 0x7f, 0x2d, 0x72, 0xdd, 0x4d, 0x29, 0x2f, 0x1c, 0xd1, 0xdf, 0x87, 0xea, 0xcc,
0x8e, 0x89, 0x0e, 0x1b, 0xde, 0xb8, 0x6b, 0x1e, 0xb1, 0x63, 0x13, 0x55, 0x82, 0xa6, 0x5e, 0x36,
0x2a, 0xde, 0xb8, 0xfb, 0x31, 0x3b, 0x16, 0x59, 0x47, 0xa0, 0xf7, 0x60, 0x33, 0x9d, 0x4c, 0x09,
0xe0, 0xf0, 0xdd, 0xb1, 0x63, 0xe1, 0xba, 0xd7, 0x0c, 0xd9, 0x20, 0xb7, 0x60, 0x6d, 0xe2, 0x4a,
0x6b, 0x3e, 0x2b, 0x7b, 0x3a, 0x74, 0x39, 0x4b, 0xa4, 0x64, 0x92, 0x47, 0x0f, 0x60, 0x0d, 0xed,
0x52, 0xd8, 0x18, 0xa6, 0x45, 0x2a, 0x70, 0x11, 0xdf, 0xe4, 0x10, 0x80, 0x72, 0xee, 0xdb, 0xdd,
0x71, 0x2c, 0xbe, 0x9e, 0x14, 0x3f, 0xb4, 0xbb, 0x41, 0xf3, 0x68, 0xd2, 0x3c, 0xa0, 0xb6, 0xdf,
0xba, 0xa0, 0x2c, 0xfb, 0x5c, 0xcc, 0x93, 0xb0, 0xee, 0x84, 0x24, 0xfd, 0xab, 0x3c, 0x14, 0x64,
0xba, 0x49, 0x3e, 0x4c, 0x17, 0x3f, 0x2a, 0xbb, 0x5b, 0x8b, 0x96, 0x2f, 0xa9, 0xd4, 0xea, 0xa3,
0x08, 0xea, 0xea, 0x6c, 0x45, 0xa1, 0x55, 0x39, 0x79, 0xbe, 0x5d, 0xc4, 0xe8, 0xa3, 0x73, 0x27,
0x2e, 0x2f, 0x2c, 0xca, 0xae, 0xc3, 0x5a, 0x46, 0xfe, 0x85, 0x6b, 0x19, 0x6d, 0xd8, 0x48, 0x84,
0x5b, 0xb6, 0xa5, 0xf2, 0x94, 0xad, 0xb3, 0x2e, 0x5d, 0xe7, 0x8e, 0x5a, 0x7f, 0x25, 0x0a, 0xc7,
0x3a, 0x16, 0xd9, 0x49, 0x27, 0xd9, 0x18, 0xb5, 0xc9, 0x70, 0x21, 0x91, 0x37, 0x8b, 0x98, 0x4d,
0x5c, 0x07, 0x71, 0xf9, 0x25, 0x89, 0x8c, 0x1e, 0x4a, 0xa2, 0x03, 0x07, 0xaf, 0x41, 0x35, 0x0e,
0x6c, 0x24, 0x49, 0x49, 0x4a, 0x89, 0xbb, 0x91, 0xf0, 0x3d, 0x38, 0xe7, 0xb0, 0x29, 0x37, 0x67,
0xa9, 0xcb, 0x48, 0x4d, 0xc4, 0xd8, 0x61, 0x9a, 0xe3, 0x0a, 0x6c, 0xc6, 0x2e, 0x14, 0x69, 0x41,
0x96, 0x3e, 0xa2, 0x5e, 0x24, 0x3b, 0x0f, 0xa5, 0x28, 0xec, 0xac, 0x20, 0x41, 0x91, 0xca, 0x68,
0x33, 0x0a, 0x64, 0x7d, 0x16, 0x8c, 0x87, 0x5c, 0x09, 0x59, 0x47, 0x1a, 0x0c, 0x64, 0x0d, 0xd9,
0x8f, 0xb4, 0x97, 0x60, 0x23, 0xf4, 0x2a, 0x92, 0x6e, 0x03, 0xe9, 0xd6, 0xc3, 0x4e, 0x24, 0xba,
0x0e, 0x35, 0xcf, 0x77, 0x3d, 0x37, 0x60, 0xbe, 0x49, 0x2d, 0xcb, 0x67, 0x41, 0x50, 0xdf, 0x94,
0xf2, 0xc2, 0xfe, 0x3d, 0xd9, 0xad, 0x7f, 0x13, 0x8a, 0x61, 0x3c, 0x7d, 0x0e, 0xd6, 0x5a, 0x91,
0x87, 0xcc, 0x1b, 0xb2, 0x21, 0xf0, 0x75, 0xcf, 0xf3, 0x54, 0x75, 0x4d, 0x7c, 0xea, 0x43, 0x28,
0xaa, 0x03, 0x9b, 0x5b, 0x53, 0xb9, 0x0f, 0xeb, 0x1e, 0xf5, 0xc5, 0x36, 0x92, 0x95, 0x95, 0x45,
0x19, 0xe1, 0x01, 0xf5, 0xf9, 0x43, 0xc6, 0x53, 0x05, 0x96, 0x0a, 0xf2, 0xcb, 0x2e, 0xfd, 0x26,
0x6c, 0xa4, 0x68, 0xc4, 0x32, 0xb9, 0xcb, 0xe9, 0x30, 0xbc, 0xe8, 0xd8, 0x88, 0x56, 0x92, 0x8b,
0x57, 0xa2, 0xdf, 0x82, 0x72, 0x74, 0x56, 0x22, 0xd1, 0x08, 0x55, 0xa1, 0x29, 0xf5, 0xcb, 0x26,
0x16, 0x91, 0xdc, 0x67, 0xcc, 0x57, 0xd6, 0x2f, 0x1b, 0x3a, 0x4b, 0x38, 0x26, 0x89, 0x66, 0xe4,
0x36, 0x14, 0x95, 0x63, 0x52, 0xf7, 0x71, 0x51, 0xb9, 0xe8, 0x00, 0x3d, 0x55, 0x58, 0x2e, 0x92,
0x7e, 0x2b, 0x9e, 0x26, 0x97, 0x9c, 0xe6, 0xa7, 0x50, 0x0a, 0x9d, 0x4f, 0x1a, 0x25, 0xe4, 0x0c,
0x17, 0x97, 0xa1, 0x84, 0x9a, 0x24, 0x66, 0x14, 0xd6, 0x14, 0xd8, 0x7d, 0x87, 0x59, 0x66, 0x7c,
0x05, 0x71, 0xce, 0x92, 0x51, 0x95, 0x03, 0xf7, 0xc2, 0xfb, 0xa5, 0xbf, 0x07, 0x05, 0xb9, 0xd6,
0xb9, 0x2e, 0x6e, 0x1e, 0xb4, 0xfe, 0x43, 0x83, 0x52, 0x08, 0x1f, 0x73, 0x99, 0x52, 0x9b, 0xc8,
0x7d, 0xdd, 0x4d, 0xbc, 0x7c, 0x97, 0xf4, 0x0e, 0x10, 0xb4, 0x14, 0x73, 0xe2, 0x72, 0xdb, 0xe9,
0x9b, 0xf2, 0x2c, 0x64, 0x24, 0x58, 0xc3, 0x91, 0x43, 0x1c, 0x38, 0x10, 0xfd, 0x6f, 0x5d, 0x82,
0x4a, 0xa2, 0xca, 0x45, 0x8a, 0xb0, 0xfa, 0x80, 0x3d, 0xab, 0xad, 0x90, 0x0a, 0x14, 0x0d, 0x86,
0x35, 0x82, 0x9a, 0xb6, 0xfb, 0x55, 0x11, 0xaa, 0x7b, 0xad, 0xfd, 0xce, 0x9e, 0xe7, 0x0d, 0xed,
0x1e, 0xe2, 0x19, 0xf9, 0x04, 0xf2, 0x98, 0x27, 0x67, 0x78, 0xdf, 0x69, 0x64, 0x29, 0x38, 0x11,
0x03, 0xd6, 0x30, 0x9d, 0x26, 0x59, 0x9e, 0x7d, 0x1a, 0x99, 0xea, 0x50, 0x62, 0x91, 0x68, 0x70,
0x19, 0x5e, 0x83, 0x1a, 0x59, 0x8a, 0x53, 0xe4, 0x33, 0x28, 0xc7, 0x79, 0x72, 0xd6, 0x37, 0xa2,
0x46, 0xe6, 0xb2, 0x95, 0x90, 0x1f, 0x67, 0x06, 0x59, 0x5f, 0x48, 0x1a, 0x99, 0xeb, 0x35, 0xe4,
0x09, 0x14, 0xc3, 0x1c, 0x2c, 0xdb, 0x2b, 0x4e, 0x23, 0x63, 0x49, 0x49, 0x1c, 0x9f, 0x4c, 0x9d,
0xb3, 0x3c, 0x55, 0x35, 0x32, 0xd5, 0xcd, 0xc8, 0x63, 0x28, 0xa8, 0xe0, 0x37, 0xd3, 0xfb, 0x4c,
0x23, 0x5b, 0xa1, 0x48, 0x28, 0x39, 0x2e, 0x4e, 0x64, 0x7d, 0x9e, 0x6b, 0x64, 0x2e, 0x18, 0x12,
0x0a, 0x90, 0xc8, 0xa7, 0x33, 0xbf, 0xbb, 0x35, 0xb2, 0x17, 0x02, 0xc9, 0x8f, 0xa1, 0x14, 0x65,
0x4d, 0x19, 0xdf, 0xbf, 0x1a, 0x59, 0x6b, 0x71, 0xad, 0xce, 0x7f, 0xfe, 0xb6, 0xa5, 0xfd, 0xf6,
0x64, 0x4b, 0xfb, 0xe2, 0x64, 0x4b, 0xfb, 0xf2, 0x64, 0x4b, 0xfb, 0xd3, 0xc9, 0x96, 0xf6, 0xd7,
0x93, 0x2d, 0xed, 0x0f, 0x7f, 0xdf, 0xd2, 0x7e, 0xf4, 0xf6, 0xd2, 0x17, 0xe6, 0xf8, 0x75, 0xbc,
0x5b, 0x40, 0x87, 0xf5, 0xad, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x5a, 0xa5, 0xa9, 0x6d, 0x32,
0x1f, 0x00, 0x00,
} }
func (this *Request) Equal(that interface{}) bool { func (this *Request) Equal(that interface{}) bool {
@ -4587,7 +4599,10 @@ func (this *EvidenceParams) Equal(that interface{}) bool {
} else if this == nil { } else if this == nil {
return false return false
} }
if this.MaxAge != that1.MaxAge {
if this.MaxAgeNumBlocks != that1.MaxAgeNumBlocks {
return false
}
if this.MaxAgeDuration != that1.MaxAgeDuration {
return false return false
} }
if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
@ -7262,8 +7277,16 @@ func (m *EvidenceParams) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i -= len(m.XXX_unrecognized) i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized)
} }
if m.MaxAge != 0 {
i = encodeVarintTypes(dAtA, i, uint64(m.MaxAge))
n34, err34 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.MaxAgeDuration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.MaxAgeDuration):])
if err34 != nil {
return 0, err34
}
i -= n34
i = encodeVarintTypes(dAtA, i, uint64(n34))
i--
dAtA[i] = 0x12
if m.MaxAgeNumBlocks != 0 {
i = encodeVarintTypes(dAtA, i, uint64(m.MaxAgeNumBlocks))
i-- i--
dAtA[i] = 0x8 dAtA[i] = 0x8
} }
@ -7497,12 +7520,12 @@ func (m *Header) MarshalToSizedBuffer(dAtA []byte) (int, error) {
} }
i-- i--
dAtA[i] = 0x2a dAtA[i] = 0x2a
n35, err35 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):])
if err35 != nil {
return 0, err35
n36, err36 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):])
if err36 != nil {
return 0, err36
} }
i -= n35
i = encodeVarintTypes(dAtA, i, uint64(n35))
i -= n36
i = encodeVarintTypes(dAtA, i, uint64(n36))
i-- i--
dAtA[i] = 0x22 dAtA[i] = 0x22
if m.Height != 0 { if m.Height != 0 {
@ -7848,12 +7871,12 @@ func (m *Evidence) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i-- i--
dAtA[i] = 0x28 dAtA[i] = 0x28
} }
n40, err40 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):])
if err40 != nil {
return 0, err40
n41, err41 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):])
if err41 != nil {
return 0, err41
} }
i -= n40
i = encodeVarintTypes(dAtA, i, uint64(n40))
i -= n41
i = encodeVarintTypes(dAtA, i, uint64(n41))
i-- i--
dAtA[i] = 0x22 dAtA[i] = 0x22
if m.Height != 0 { if m.Height != 0 {
@ -8497,21 +8520,23 @@ func NewPopulatedBlockParams(r randyTypes, easy bool) *BlockParams {
func NewPopulatedEvidenceParams(r randyTypes, easy bool) *EvidenceParams { func NewPopulatedEvidenceParams(r randyTypes, easy bool) *EvidenceParams {
this := &EvidenceParams{} this := &EvidenceParams{}
this.MaxAge = int64(r.Int63())
this.MaxAgeNumBlocks = int64(r.Int63())
if r.Intn(2) == 0 { if r.Intn(2) == 0 {
this.MaxAge *= -1
this.MaxAgeNumBlocks *= -1
} }
v31 := github_com_gogo_protobuf_types.NewPopulatedStdDuration(r, easy)
this.MaxAgeDuration = *v31
if !easy && r.Intn(10) != 0 { if !easy && r.Intn(10) != 0 {
this.XXX_unrecognized = randUnrecognizedTypes(r, 2)
this.XXX_unrecognized = randUnrecognizedTypes(r, 3)
} }
return this return this
} }
func NewPopulatedValidatorParams(r randyTypes, easy bool) *ValidatorParams { func NewPopulatedValidatorParams(r randyTypes, easy bool) *ValidatorParams {
this := &ValidatorParams{} this := &ValidatorParams{}
v31 := r.Intn(10)
this.PubKeyTypes = make([]string, v31)
for i := 0; i < v31; i++ {
v32 := r.Intn(10)
this.PubKeyTypes = make([]string, v32)
for i := 0; i < v32; i++ {
this.PubKeyTypes[i] = string(randStringTypes(r)) this.PubKeyTypes[i] = string(randStringTypes(r))
} }
if !easy && r.Intn(10) != 0 { if !easy && r.Intn(10) != 0 {
@ -8527,11 +8552,11 @@ func NewPopulatedLastCommitInfo(r randyTypes, easy bool) *LastCommitInfo {
this.Round *= -1 this.Round *= -1
} }
if r.Intn(5) != 0 { if r.Intn(5) != 0 {
v32 := r.Intn(5)
this.Votes = make([]VoteInfo, v32)
for i := 0; i < v32; i++ {
v33 := NewPopulatedVoteInfo(r, easy)
this.Votes[i] = *v33
v33 := r.Intn(5)
this.Votes = make([]VoteInfo, v33)
for i := 0; i < v33; i++ {
v34 := NewPopulatedVoteInfo(r, easy)
this.Votes[i] = *v34
} }
} }
if !easy && r.Intn(10) != 0 { if !easy && r.Intn(10) != 0 {
@ -8544,11 +8569,11 @@ func NewPopulatedEvent(r randyTypes, easy bool) *Event {
this := &Event{} this := &Event{}
this.Type = string(randStringTypes(r)) this.Type = string(randStringTypes(r))
if r.Intn(5) != 0 { if r.Intn(5) != 0 {
v34 := r.Intn(5)
this.Attributes = make([]kv.Pair, v34)
for i := 0; i < v34; i++ {
v35 := kv.NewPopulatedPair(r, easy)
this.Attributes[i] = *v35
v35 := r.Intn(5)
this.Attributes = make([]kv.Pair, v35)
for i := 0; i < v35; i++ {
v36 := kv.NewPopulatedPair(r, easy)
this.Attributes[i] = *v36
} }
} }
if !easy && r.Intn(10) != 0 { if !easy && r.Intn(10) != 0 {
@ -8559,60 +8584,60 @@ func NewPopulatedEvent(r randyTypes, easy bool) *Event {
func NewPopulatedHeader(r randyTypes, easy bool) *Header { func NewPopulatedHeader(r randyTypes, easy bool) *Header {
this := &Header{} this := &Header{}
v36 := NewPopulatedVersion(r, easy)
this.Version = *v36
v37 := NewPopulatedVersion(r, easy)
this.Version = *v37
this.ChainID = string(randStringTypes(r)) this.ChainID = string(randStringTypes(r))
this.Height = int64(r.Int63()) this.Height = int64(r.Int63())
if r.Intn(2) == 0 { if r.Intn(2) == 0 {
this.Height *= -1 this.Height *= -1
} }
v37 := github_com_gogo_protobuf_types.NewPopulatedStdTime(r, easy)
this.Time = *v37
v38 := NewPopulatedBlockID(r, easy)
this.LastBlockId = *v38
v39 := r.Intn(100)
this.LastCommitHash = make([]byte, v39)
for i := 0; i < v39; i++ {
this.LastCommitHash[i] = byte(r.Intn(256))
}
v38 := github_com_gogo_protobuf_types.NewPopulatedStdTime(r, easy)
this.Time = *v38
v39 := NewPopulatedBlockID(r, easy)
this.LastBlockId = *v39
v40 := r.Intn(100) v40 := r.Intn(100)
this.DataHash = make([]byte, v40)
this.LastCommitHash = make([]byte, v40)
for i := 0; i < v40; i++ { for i := 0; i < v40; i++ {
this.DataHash[i] = byte(r.Intn(256))
this.LastCommitHash[i] = byte(r.Intn(256))
} }
v41 := r.Intn(100) v41 := r.Intn(100)
this.ValidatorsHash = make([]byte, v41)
this.DataHash = make([]byte, v41)
for i := 0; i < v41; i++ { for i := 0; i < v41; i++ {
this.ValidatorsHash[i] = byte(r.Intn(256))
this.DataHash[i] = byte(r.Intn(256))
} }
v42 := r.Intn(100) v42 := r.Intn(100)
this.NextValidatorsHash = make([]byte, v42)
this.ValidatorsHash = make([]byte, v42)
for i := 0; i < v42; i++ { for i := 0; i < v42; i++ {
this.NextValidatorsHash[i] = byte(r.Intn(256))
this.ValidatorsHash[i] = byte(r.Intn(256))
} }
v43 := r.Intn(100) v43 := r.Intn(100)
this.ConsensusHash = make([]byte, v43)
this.NextValidatorsHash = make([]byte, v43)
for i := 0; i < v43; i++ { for i := 0; i < v43; i++ {
this.ConsensusHash[i] = byte(r.Intn(256))
this.NextValidatorsHash[i] = byte(r.Intn(256))
} }
v44 := r.Intn(100) v44 := r.Intn(100)
this.AppHash = make([]byte, v44)
this.ConsensusHash = make([]byte, v44)
for i := 0; i < v44; i++ { for i := 0; i < v44; i++ {
this.AppHash[i] = byte(r.Intn(256))
this.ConsensusHash[i] = byte(r.Intn(256))
} }
v45 := r.Intn(100) v45 := r.Intn(100)
this.LastResultsHash = make([]byte, v45)
this.AppHash = make([]byte, v45)
for i := 0; i < v45; i++ { for i := 0; i < v45; i++ {
this.LastResultsHash[i] = byte(r.Intn(256))
this.AppHash[i] = byte(r.Intn(256))
} }
v46 := r.Intn(100) v46 := r.Intn(100)
this.EvidenceHash = make([]byte, v46)
this.LastResultsHash = make([]byte, v46)
for i := 0; i < v46; i++ { for i := 0; i < v46; i++ {
this.EvidenceHash[i] = byte(r.Intn(256))
this.LastResultsHash[i] = byte(r.Intn(256))
} }
v47 := r.Intn(100) v47 := r.Intn(100)
this.ProposerAddress = make([]byte, v47)
this.EvidenceHash = make([]byte, v47)
for i := 0; i < v47; i++ { for i := 0; i < v47; i++ {
this.EvidenceHash[i] = byte(r.Intn(256))
}
v48 := r.Intn(100)
this.ProposerAddress = make([]byte, v48)
for i := 0; i < v48; i++ {
this.ProposerAddress[i] = byte(r.Intn(256)) this.ProposerAddress[i] = byte(r.Intn(256))
} }
if !easy && r.Intn(10) != 0 { if !easy && r.Intn(10) != 0 {
@ -8633,13 +8658,13 @@ func NewPopulatedVersion(r randyTypes, easy bool) *Version {
func NewPopulatedBlockID(r randyTypes, easy bool) *BlockID { func NewPopulatedBlockID(r randyTypes, easy bool) *BlockID {
this := &BlockID{} this := &BlockID{}
v48 := r.Intn(100)
this.Hash = make([]byte, v48)
for i := 0; i < v48; i++ {
v49 := r.Intn(100)
this.Hash = make([]byte, v49)
for i := 0; i < v49; i++ {
this.Hash[i] = byte(r.Intn(256)) this.Hash[i] = byte(r.Intn(256))
} }
v49 := NewPopulatedPartSetHeader(r, easy)
this.PartsHeader = *v49
v50 := NewPopulatedPartSetHeader(r, easy)
this.PartsHeader = *v50
if !easy && r.Intn(10) != 0 { if !easy && r.Intn(10) != 0 {
this.XXX_unrecognized = randUnrecognizedTypes(r, 3) this.XXX_unrecognized = randUnrecognizedTypes(r, 3)
} }
@ -8652,9 +8677,9 @@ func NewPopulatedPartSetHeader(r randyTypes, easy bool) *PartSetHeader {
if r.Intn(2) == 0 { if r.Intn(2) == 0 {
this.Total *= -1 this.Total *= -1
} }
v50 := r.Intn(100)
this.Hash = make([]byte, v50)
for i := 0; i < v50; i++ {
v51 := r.Intn(100)
this.Hash = make([]byte, v51)
for i := 0; i < v51; i++ {
this.Hash[i] = byte(r.Intn(256)) this.Hash[i] = byte(r.Intn(256))
} }
if !easy && r.Intn(10) != 0 { if !easy && r.Intn(10) != 0 {
@ -8665,9 +8690,9 @@ func NewPopulatedPartSetHeader(r randyTypes, easy bool) *PartSetHeader {
func NewPopulatedValidator(r randyTypes, easy bool) *Validator { func NewPopulatedValidator(r randyTypes, easy bool) *Validator {
this := &Validator{} this := &Validator{}
v51 := r.Intn(100)
this.Address = make([]byte, v51)
for i := 0; i < v51; i++ {
v52 := r.Intn(100)
this.Address = make([]byte, v52)
for i := 0; i < v52; i++ {
this.Address[i] = byte(r.Intn(256)) this.Address[i] = byte(r.Intn(256))
} }
this.Power = int64(r.Int63()) this.Power = int64(r.Int63())
@ -8682,8 +8707,8 @@ func NewPopulatedValidator(r randyTypes, easy bool) *Validator {
func NewPopulatedValidatorUpdate(r randyTypes, easy bool) *ValidatorUpdate { func NewPopulatedValidatorUpdate(r randyTypes, easy bool) *ValidatorUpdate {
this := &ValidatorUpdate{} this := &ValidatorUpdate{}
v52 := NewPopulatedPubKey(r, easy)
this.PubKey = *v52
v53 := NewPopulatedPubKey(r, easy)
this.PubKey = *v53
this.Power = int64(r.Int63()) this.Power = int64(r.Int63())
if r.Intn(2) == 0 { if r.Intn(2) == 0 {
this.Power *= -1 this.Power *= -1
@ -8696,8 +8721,8 @@ func NewPopulatedValidatorUpdate(r randyTypes, easy bool) *ValidatorUpdate {
func NewPopulatedVoteInfo(r randyTypes, easy bool) *VoteInfo { func NewPopulatedVoteInfo(r randyTypes, easy bool) *VoteInfo {
this := &VoteInfo{} this := &VoteInfo{}
v53 := NewPopulatedValidator(r, easy)
this.Validator = *v53
v54 := NewPopulatedValidator(r, easy)
this.Validator = *v54
this.SignedLastBlock = bool(bool(r.Intn(2) == 0)) this.SignedLastBlock = bool(bool(r.Intn(2) == 0))
if !easy && r.Intn(10) != 0 { if !easy && r.Intn(10) != 0 {
this.XXX_unrecognized = randUnrecognizedTypes(r, 3) this.XXX_unrecognized = randUnrecognizedTypes(r, 3)
@ -8708,9 +8733,9 @@ func NewPopulatedVoteInfo(r randyTypes, easy bool) *VoteInfo {
func NewPopulatedPubKey(r randyTypes, easy bool) *PubKey { func NewPopulatedPubKey(r randyTypes, easy bool) *PubKey {
this := &PubKey{} this := &PubKey{}
this.Type = string(randStringTypes(r)) this.Type = string(randStringTypes(r))
v54 := r.Intn(100)
this.Data = make([]byte, v54)
for i := 0; i < v54; i++ {
v55 := r.Intn(100)
this.Data = make([]byte, v55)
for i := 0; i < v55; i++ {
this.Data[i] = byte(r.Intn(256)) this.Data[i] = byte(r.Intn(256))
} }
if !easy && r.Intn(10) != 0 { if !easy && r.Intn(10) != 0 {
@ -8722,14 +8747,14 @@ func NewPopulatedPubKey(r randyTypes, easy bool) *PubKey {
func NewPopulatedEvidence(r randyTypes, easy bool) *Evidence { func NewPopulatedEvidence(r randyTypes, easy bool) *Evidence {
this := &Evidence{} this := &Evidence{}
this.Type = string(randStringTypes(r)) this.Type = string(randStringTypes(r))
v55 := NewPopulatedValidator(r, easy)
this.Validator = *v55
v56 := NewPopulatedValidator(r, easy)
this.Validator = *v56
this.Height = int64(r.Int63()) this.Height = int64(r.Int63())
if r.Intn(2) == 0 { if r.Intn(2) == 0 {
this.Height *= -1 this.Height *= -1
} }
v56 := github_com_gogo_protobuf_types.NewPopulatedStdTime(r, easy)
this.Time = *v56
v57 := github_com_gogo_protobuf_types.NewPopulatedStdTime(r, easy)
this.Time = *v57
this.TotalVotingPower = int64(r.Int63()) this.TotalVotingPower = int64(r.Int63())
if r.Intn(2) == 0 { if r.Intn(2) == 0 {
this.TotalVotingPower *= -1 this.TotalVotingPower *= -1
@ -8759,9 +8784,9 @@ func randUTF8RuneTypes(r randyTypes) rune {
return rune(ru + 61) return rune(ru + 61)
} }
func randStringTypes(r randyTypes) string { func randStringTypes(r randyTypes) string {
v57 := r.Intn(100)
tmps := make([]rune, v57)
for i := 0; i < v57; i++ {
v58 := r.Intn(100)
tmps := make([]rune, v58)
for i := 0; i < v58; i++ {
tmps[i] = randUTF8RuneTypes(r) tmps[i] = randUTF8RuneTypes(r)
} }
return string(tmps) return string(tmps)
@ -8783,11 +8808,11 @@ func randFieldTypes(dAtA []byte, r randyTypes, fieldNumber int, wire int) []byte
switch wire { switch wire {
case 0: case 0:
dAtA = encodeVarintPopulateTypes(dAtA, uint64(key)) dAtA = encodeVarintPopulateTypes(dAtA, uint64(key))
v58 := r.Int63()
v59 := r.Int63()
if r.Intn(2) == 0 { if r.Intn(2) == 0 {
v58 *= -1
v59 *= -1
} }
dAtA = encodeVarintPopulateTypes(dAtA, uint64(v58))
dAtA = encodeVarintPopulateTypes(dAtA, uint64(v59))
case 1: case 1:
dAtA = encodeVarintPopulateTypes(dAtA, uint64(key)) dAtA = encodeVarintPopulateTypes(dAtA, uint64(key))
dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
@ -9694,9 +9719,11 @@ func (m *EvidenceParams) Size() (n int) {
} }
var l int var l int
_ = l _ = l
if m.MaxAge != 0 {
n += 1 + sovTypes(uint64(m.MaxAge))
if m.MaxAgeNumBlocks != 0 {
n += 1 + sovTypes(uint64(m.MaxAgeNumBlocks))
} }
l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.MaxAgeDuration)
n += 1 + l + sovTypes(uint64(l))
if m.XXX_unrecognized != nil { if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized) n += len(m.XXX_unrecognized)
} }
@ -14329,9 +14356,28 @@ func (m *EvidenceParams) Unmarshal(dAtA []byte) error {
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 0 { if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field MaxAge", wireType)
return fmt.Errorf("proto: wrong wireType = %d for field MaxAgeNumBlocks", wireType)
}
m.MaxAgeNumBlocks = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.MaxAgeNumBlocks |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
} }
m.MaxAge = 0
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field MaxAgeDuration", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 { if shift >= 64 {
return ErrIntOverflowTypes return ErrIntOverflowTypes
@ -14341,11 +14387,25 @@ func (m *EvidenceParams) Unmarshal(dAtA []byte) error {
} }
b := dAtA[iNdEx] b := dAtA[iNdEx]
iNdEx++ iNdEx++
m.MaxAge |= int64(b&0x7F) << shift
msglen |= int(b&0x7F) << shift
if b < 0x80 { if b < 0x80 {
break break
} }
} }
if msglen < 0 {
return ErrInvalidLengthTypes
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTypes
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.MaxAgeDuration, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:]) skippy, err := skipTypes(dAtA[iNdEx:])


+ 3
- 2
abci/types/types.proto View File

@ -8,6 +8,7 @@ import "github.com/gogo/protobuf/gogoproto/gogo.proto";
import "github.com/tendermint/tendermint/crypto/merkle/merkle.proto"; import "github.com/tendermint/tendermint/crypto/merkle/merkle.proto";
import "github.com/tendermint/tendermint/libs/kv/types.proto"; import "github.com/tendermint/tendermint/libs/kv/types.proto";
import "google/protobuf/timestamp.proto"; import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";
// This file is copied from http://github.com/tendermint/abci // This file is copied from http://github.com/tendermint/abci
// NOTE: When using custom types, mind the warnings. // NOTE: When using custom types, mind the warnings.
@ -227,10 +228,10 @@ message BlockParams {
int64 max_gas = 2; int64 max_gas = 2;
} }
// EvidenceParams contains limits on the evidence.
message EvidenceParams { message EvidenceParams {
// Note: must be greater than 0 // Note: must be greater than 0
int64 max_age = 1;
int64 max_age_num_blocks = 1;
google.protobuf.Duration max_age_duration = 2 [(gogoproto.nullable)=false, (gogoproto.stdduration)=true];
} }
// ValidatorParams contains limits on validators. // ValidatorParams contains limits on validators.


+ 1
- 0
abci/types/typespb_test.go View File

@ -10,6 +10,7 @@ import (
github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto"
proto "github.com/gogo/protobuf/proto" proto "github.com/gogo/protobuf/proto"
golang_proto "github.com/golang/protobuf/proto" golang_proto "github.com/golang/protobuf/proto"
_ "github.com/golang/protobuf/ptypes/duration"
_ "github.com/golang/protobuf/ptypes/timestamp" _ "github.com/golang/protobuf/ptypes/timestamp"
_ "github.com/tendermint/tendermint/crypto/merkle" _ "github.com/tendermint/tendermint/crypto/merkle"
_ "github.com/tendermint/tendermint/libs/kv" _ "github.com/tendermint/tendermint/libs/kv"


+ 1
- 1
consensus/reactor_test.go View File

@ -202,7 +202,7 @@ type mockEvidencePool struct {
func newMockEvidencePool(val []byte) *mockEvidencePool { func newMockEvidencePool(val []byte) *mockEvidencePool {
return &mockEvidencePool{ return &mockEvidencePool{
ev: []types.Evidence{types.NewMockGoodEvidence(1, 1, val)},
ev: []types.Evidence{types.NewMockEvidence(1, time.Now().UTC(), 1, val)},
} }
} }


+ 3
- 2
docs/tendermint-core/using-tendermint.md View File

@ -56,7 +56,7 @@ definition](https://github.com/tendermint/tendermint/blob/master/types/genesis.g
application, and may be left empty to make explicit that the application, and may be left empty to make explicit that the
application will initialize the validator set with ResponseInitChain. application will initialize the validator set with ResponseInitChain.
- `pub_key`: The first element specifies the `pub_key` type. 1 - `pub_key`: The first element specifies the `pub_key` type. 1
== Ed25519. The second element are the pubkey bytes.
== Ed25519. The second element are the pubkey bytes.
- `power`: The validator's voting power. - `power`: The validator's voting power.
- `name`: Name of the validator (optional). - `name`: Name of the validator (optional).
- `app_hash`: The expected application hash (as returned by the - `app_hash`: The expected application hash (as returned by the
@ -78,7 +78,8 @@ definition](https://github.com/tendermint/tendermint/blob/master/types/genesis.g
"time_iota_ms": "1000" "time_iota_ms": "1000"
}, },
"evidence": { "evidence": {
"max_age": "100000"
"max_age_num_blocks": "100000"
"max_age_duration": "10000"
}, },
"validator": { "validator": {
"pub_key_types": [ "pub_key_types": [


+ 19
- 11
evidence/pool.go View File

@ -3,6 +3,7 @@ package evidence
import ( import (
"fmt" "fmt"
"sync" "sync"
"time"
clist "github.com/tendermint/tendermint/libs/clist" clist "github.com/tendermint/tendermint/libs/clist"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
@ -90,7 +91,7 @@ func (evpool *Pool) Update(block *types.Block, state sm.State) {
evpool.mtx.Unlock() evpool.mtx.Unlock()
// remove evidence from pending and mark committed // remove evidence from pending and mark committed
evpool.MarkEvidenceAsCommitted(block.Height, block.Evidence.Evidence)
evpool.MarkEvidenceAsCommitted(block.Height, block.Time, block.Evidence.Evidence)
} }
// AddEvidence checks the evidence is valid and adds it to the pool. // AddEvidence checks the evidence is valid and adds it to the pool.
@ -124,7 +125,7 @@ func (evpool *Pool) AddEvidence(evidence types.Evidence) (err error) {
} }
// MarkEvidenceAsCommitted marks all the evidence as committed and removes it from the queue. // MarkEvidenceAsCommitted marks all the evidence as committed and removes it from the queue.
func (evpool *Pool) MarkEvidenceAsCommitted(height int64, evidence []types.Evidence) {
func (evpool *Pool) MarkEvidenceAsCommitted(height int64, lastBlockTime time.Time, evidence []types.Evidence) {
// make a map of committed evidence to remove from the clist // make a map of committed evidence to remove from the clist
blockEvidenceMap := make(map[string]struct{}) blockEvidenceMap := make(map[string]struct{})
for _, ev := range evidence { for _, ev := range evidence {
@ -133,9 +134,8 @@ func (evpool *Pool) MarkEvidenceAsCommitted(height int64, evidence []types.Evide
} }
// remove committed evidence from the clist // remove committed evidence from the clist
maxAge := evpool.State().ConsensusParams.Evidence.MaxAge
evpool.removeEvidence(height, maxAge, blockEvidenceMap)
evidenceParams := evpool.State().ConsensusParams.Evidence
evpool.removeEvidence(height, lastBlockTime, evidenceParams, blockEvidenceMap)
} }
// IsCommitted returns true if we have already seen this exact evidence and it is already marked as committed. // IsCommitted returns true if we have already seen this exact evidence and it is already marked as committed.
@ -144,15 +144,23 @@ func (evpool *Pool) IsCommitted(evidence types.Evidence) bool {
return ei.Evidence != nil && ei.Committed return ei.Evidence != nil && ei.Committed
} }
func (evpool *Pool) removeEvidence(height, maxAge int64, blockEvidenceMap map[string]struct{}) {
func (evpool *Pool) removeEvidence(
height int64,
lastBlockTime time.Time,
params types.EvidenceParams,
blockEvidenceMap map[string]struct{}) {
for e := evpool.evidenceList.Front(); e != nil; e = e.Next() { for e := evpool.evidenceList.Front(); e != nil; e = e.Next() {
ev := e.Value.(types.Evidence)
var (
ev = e.Value.(types.Evidence)
ageDuration = lastBlockTime.Sub(ev.Time())
ageNumBlocks = height - ev.Height()
)
// Remove the evidence if it's already in a block
// or if it's now too old.
// Remove the evidence if it's already in a block or if it's now too old.
if _, ok := blockEvidenceMap[evMapKey(ev)]; ok || if _, ok := blockEvidenceMap[evMapKey(ev)]; ok ||
ev.Height() < height-maxAge {
ageNumBlocks > params.MaxAgeNumBlocks ||
ageDuration > params.MaxAgeDuration {
// remove from clist // remove from clist
evpool.evidenceList.Remove(e) evpool.evidenceList.Remove(e)
e.DetachPrev() e.DetachPrev()


+ 58
- 15
evidence/pool_test.go View File

@ -4,6 +4,7 @@ import (
"os" "os"
"sync" "sync"
"testing" "testing"
"time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -37,7 +38,8 @@ func initializeValidatorState(valAddr []byte, height int64) dbm.DB {
LastHeightValidatorsChanged: 1, LastHeightValidatorsChanged: 1,
ConsensusParams: types.ConsensusParams{ ConsensusParams: types.ConsensusParams{
Evidence: types.EvidenceParams{ Evidence: types.EvidenceParams{
MaxAge: 1000000,
MaxAgeNumBlocks: 10000,
MaxAgeDuration: 48 * time.Hour,
}, },
}, },
} }
@ -53,18 +55,22 @@ func initializeValidatorState(valAddr []byte, height int64) dbm.DB {
func TestEvidencePool(t *testing.T) { func TestEvidencePool(t *testing.T) {
valAddr := []byte("val1")
height := int64(5)
stateDB := initializeValidatorState(valAddr, height)
evidenceDB := dbm.NewMemDB()
pool := NewPool(stateDB, evidenceDB)
var (
valAddr = []byte("val1")
height = int64(5)
stateDB = initializeValidatorState(valAddr, height)
evidenceDB = dbm.NewMemDB()
pool = NewPool(stateDB, evidenceDB)
evidenceTime = time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
)
goodEvidence := types.NewMockGoodEvidence(height, 0, valAddr)
badEvidence := types.MockBadEvidence{MockGoodEvidence: goodEvidence}
goodEvidence := types.NewMockEvidence(height, time.Now(), 0, valAddr)
badEvidence := types.NewMockEvidence(height, evidenceTime, 0, valAddr)
// bad evidence // bad evidence
err := pool.AddEvidence(badEvidence) err := pool.AddEvidence(badEvidence)
assert.NotNil(t, err) assert.NotNil(t, err)
// err: evidence created at 2019-01-01 00:00:00 +0000 UTC has expired. Evidence can not be older than: ...
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(1) wg.Add(1)
@ -87,14 +93,17 @@ func TestEvidencePool(t *testing.T) {
func TestEvidencePoolIsCommitted(t *testing.T) { func TestEvidencePoolIsCommitted(t *testing.T) {
// Initialization: // Initialization:
valAddr := []byte("validator_address")
height := int64(42)
stateDB := initializeValidatorState(valAddr, height)
evidenceDB := dbm.NewMemDB()
pool := NewPool(stateDB, evidenceDB)
var (
valAddr = []byte("validator_address")
height = int64(42)
lastBlockTime = time.Now()
stateDB = initializeValidatorState(valAddr, height)
evidenceDB = dbm.NewMemDB()
pool = NewPool(stateDB, evidenceDB)
)
// evidence not seen yet: // evidence not seen yet:
evidence := types.NewMockGoodEvidence(height, 0, valAddr)
evidence := types.NewMockEvidence(height, time.Now(), 0, valAddr)
assert.False(t, pool.IsCommitted(evidence)) assert.False(t, pool.IsCommitted(evidence))
// evidence seen but not yet committed: // evidence seen but not yet committed:
@ -102,6 +111,40 @@ func TestEvidencePoolIsCommitted(t *testing.T) {
assert.False(t, pool.IsCommitted(evidence)) assert.False(t, pool.IsCommitted(evidence))
// evidence seen and committed: // evidence seen and committed:
pool.MarkEvidenceAsCommitted(height, []types.Evidence{evidence})
pool.MarkEvidenceAsCommitted(height, lastBlockTime, []types.Evidence{evidence})
assert.True(t, pool.IsCommitted(evidence)) assert.True(t, pool.IsCommitted(evidence))
} }
func TestAddEvidence(t *testing.T) {
var (
valAddr = []byte("val1")
height = int64(100002)
stateDB = initializeValidatorState(valAddr, height)
evidenceDB = dbm.NewMemDB()
pool = NewPool(stateDB, evidenceDB)
evidenceTime = time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
)
testCases := []struct {
evHeight int64
evTime time.Time
expErr bool
evDescription string
}{
{height, time.Now(), false, "valid evidence"},
{height, evidenceTime, true, "evidence created at 2019-01-01 00:00:00 +0000 UTC has expired"},
{int64(1), time.Now(), true, "evidence from height 1 is too old"},
{int64(1), evidenceTime, true,
"evidence from height 1 is too old & evidence created at 2019-01-01 00:00:00 +0000 UTC has expired"},
}
for _, tc := range testCases {
tc := tc
ev := types.NewMockEvidence(tc.evHeight, tc.evTime, 0, valAddr)
err := pool.AddEvidence(ev)
if tc.expErr {
assert.Error(t, err)
}
}
}

+ 25
- 13
evidence/reactor.go View File

@ -93,14 +93,14 @@ func (evR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
} }
} }
// SetEventSwitch implements events.Eventable.
// SetEventBus implements events.Eventable.
func (evR *Reactor) SetEventBus(b *types.EventBus) { func (evR *Reactor) SetEventBus(b *types.EventBus) {
evR.eventBus = b evR.eventBus = b
} }
// Modeled after the mempool routine. // Modeled after the mempool routine.
// - Evidence accumulates in a clist. // - Evidence accumulates in a clist.
// - Each peer has a routien that iterates through the clist,
// - Each peer has a routine that iterates through the clist,
// sending available evidence to the peer. // sending available evidence to the peer.
// - If we're waiting for new evidence and the list is not empty, // - If we're waiting for new evidence and the list is not empty,
// start iterating from the beginning again. // start iterating from the beginning again.
@ -158,6 +158,7 @@ func (evR Reactor) checkSendEvidenceMessage(
peer p2p.Peer, peer p2p.Peer,
ev types.Evidence, ev types.Evidence,
) (msg Message, retry bool) { ) (msg Message, retry bool) {
// make sure the peer is up to date // make sure the peer is up to date
evHeight := ev.Height() evHeight := ev.Height()
peerState, ok := peer.Get(types.PeerStateKey).(PeerState) peerState, ok := peer.Get(types.PeerStateKey).(PeerState)
@ -172,20 +173,31 @@ func (evR Reactor) checkSendEvidenceMessage(
// NOTE: We only send evidence to peers where // NOTE: We only send evidence to peers where
// peerHeight - maxAge < evidenceHeight < peerHeight // peerHeight - maxAge < evidenceHeight < peerHeight
maxAge := evR.evpool.State().ConsensusParams.Evidence.MaxAge
peerHeight := peerState.GetHeight()
if peerHeight < evHeight {
// peer is behind. sleep while he catches up
// and
// lastBlockTime - maxDuration < evidenceTime
var (
peerHeight = peerState.GetHeight()
params = evR.evpool.State().ConsensusParams.Evidence
ageDuration = evR.evpool.State().LastBlockTime.Sub(ev.Time())
ageNumBlocks = peerHeight - evHeight
)
if peerHeight < evHeight { // peer is behind. sleep while he catches up
return nil, true return nil, true
} else if peerHeight > evHeight+maxAge {
// evidence is too old, skip
// NOTE: if evidence is too old for an honest peer,
// then we're behind and either it already got committed or it never will!
evR.Logger.Info(
"Not sending peer old evidence",
} else if ageNumBlocks > params.MaxAgeNumBlocks ||
ageDuration > params.MaxAgeDuration { // evidence is too old, skip
// NOTE: if evidence is too old for an honest peer, then we're behind and
// either it already got committed or it never will!
evR.Logger.Info("Not sending peer old evidence",
"peerHeight", peerHeight, "peerHeight", peerHeight,
"evHeight", evHeight, "evHeight", evHeight,
"maxAge", maxAge,
"maxAgeNumBlocks", params.MaxAgeNumBlocks,
"lastBlockTime", evR.evpool.State().LastBlockTime,
"evTime", ev.Time(),
"maxAgeDuration", params.MaxAgeDuration,
"peer", peer, "peer", peer,
) )


+ 2
- 2
evidence/reactor_test.go View File

@ -106,7 +106,7 @@ func _waitForEvidence(
func sendEvidence(t *testing.T, evpool *Pool, valAddr []byte, n int) types.EvidenceList { func sendEvidence(t *testing.T, evpool *Pool, valAddr []byte, n int) types.EvidenceList {
evList := make([]types.Evidence, n) evList := make([]types.Evidence, n)
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
ev := types.NewMockGoodEvidence(int64(i+1), 0, valAddr)
ev := types.NewMockEvidence(int64(i+1), time.Now().UTC(), 0, valAddr)
err := evpool.AddEvidence(ev) err := evpool.AddEvidence(ev)
assert.Nil(t, err) assert.Nil(t, err)
evList[i] = ev evList[i] = ev
@ -215,7 +215,7 @@ func TestListMessageValidationBasic(t *testing.T) {
valAddr := []byte("myval") valAddr := []byte("myval")
evListMsg.Evidence = make([]types.Evidence, n) evListMsg.Evidence = make([]types.Evidence, n)
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
evListMsg.Evidence[i] = types.NewMockGoodEvidence(int64(i+1), 0, valAddr)
evListMsg.Evidence[i] = types.NewMockEvidence(int64(i+1), time.Now(), 0, valAddr)
} }
tc.malleateEvListMsg(evListMsg) tc.malleateEvListMsg(evListMsg)
assert.Equal(t, tc.expectErr, evListMsg.ValidateBasic() != nil, "Validate Basic had an unexpected result") assert.Equal(t, tc.expectErr, evListMsg.ValidateBasic() != nil, "Validate Basic had an unexpected result")


+ 11
- 10
evidence/store_test.go View File

@ -2,6 +2,7 @@ package evidence
import ( import (
"testing" "testing"
"time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
@ -17,7 +18,7 @@ func TestStoreAddDuplicate(t *testing.T) {
store := NewStore(db) store := NewStore(db)
priority := int64(10) priority := int64(10)
ev := types.NewMockGoodEvidence(2, 1, []byte("val1"))
ev := types.NewMockEvidence(2, time.Now().UTC(), 1, []byte("val1"))
added := store.AddNewEvidence(ev, priority) added := store.AddNewEvidence(ev, priority)
assert.True(added) assert.True(added)
@ -34,7 +35,7 @@ func TestStoreCommitDuplicate(t *testing.T) {
store := NewStore(db) store := NewStore(db)
priority := int64(10) priority := int64(10)
ev := types.NewMockGoodEvidence(2, 1, []byte("val1"))
ev := types.NewMockEvidence(2, time.Now().UTC(), 1, []byte("val1"))
store.MarkEvidenceAsCommitted(ev) store.MarkEvidenceAsCommitted(ev)
@ -55,7 +56,7 @@ func TestStoreMark(t *testing.T) {
assert.Equal(0, len(pendingEv)) assert.Equal(0, len(pendingEv))
priority := int64(10) priority := int64(10)
ev := types.NewMockGoodEvidence(2, 1, []byte("val1"))
ev := types.NewMockEvidence(2, time.Now().UTC(), 1, []byte("val1"))
added := store.AddNewEvidence(ev, priority) added := store.AddNewEvidence(ev, priority)
assert.True(added) assert.True(added)
@ -102,15 +103,15 @@ func TestStorePriority(t *testing.T) {
// sorted by priority and then height // sorted by priority and then height
cases := []struct { cases := []struct {
ev types.MockGoodEvidence
ev types.MockEvidence
priority int64 priority int64
}{ }{
{types.NewMockGoodEvidence(2, 1, []byte("val1")), 17},
{types.NewMockGoodEvidence(5, 2, []byte("val2")), 15},
{types.NewMockGoodEvidence(10, 2, []byte("val2")), 13},
{types.NewMockGoodEvidence(100, 2, []byte("val2")), 11},
{types.NewMockGoodEvidence(90, 2, []byte("val2")), 11},
{types.NewMockGoodEvidence(80, 2, []byte("val2")), 11},
{types.NewMockEvidence(2, time.Now().UTC(), 1, []byte("val1")), 17},
{types.NewMockEvidence(5, time.Now().UTC(), 2, []byte("val2")), 15},
{types.NewMockEvidence(10, time.Now().UTC(), 2, []byte("val2")), 13},
{types.NewMockEvidence(100, time.Now().UTC(), 2, []byte("val2")), 11},
{types.NewMockEvidence(90, time.Now().UTC(), 2, []byte("val2")), 11},
{types.NewMockEvidence(80, time.Now().UTC(), 2, []byte("val2")), 11},
} }
for _, c := range cases { for _, c := range cases {


+ 1
- 1
node/node_test.go View File

@ -257,7 +257,7 @@ func TestCreateProposalBlock(t *testing.T) {
minEvSize := 12 minEvSize := 12
numEv := (maxBytes / types.MaxEvidenceBytesDenominator) / minEvSize numEv := (maxBytes / types.MaxEvidenceBytesDenominator) / minEvSize
for i := 0; i < numEv; i++ { for i := 0; i < numEv; i++ {
ev := types.NewMockRandomGoodEvidence(1, proposerAddr, tmrand.Bytes(minEvSize))
ev := types.NewMockRandomEvidence(1, time.Now(), proposerAddr, tmrand.Bytes(minEvSize))
err := evidencePool.AddEvidence(ev) err := evidencePool.AddEvidence(ev)
assert.NoError(t, err) assert.NoError(t, err)
} }


+ 3
- 1
rpc/client/rpc_test.go View File

@ -8,6 +8,7 @@ import (
"strings" "strings"
"sync" "sync"
"testing" "testing"
"time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -484,6 +485,7 @@ func deepcpVote(vote *types.Vote) (res *types.Vote) {
Height: vote.Height, Height: vote.Height,
Round: vote.Round, Round: vote.Round,
Type: vote.Type, Type: vote.Type,
Timestamp: vote.Timestamp,
BlockID: types.BlockID{ BlockID: types.BlockID{
Hash: make([]byte, len(vote.BlockID.Hash)), Hash: make([]byte, len(vote.BlockID.Hash)),
PartsHeader: vote.BlockID.PartsHeader, PartsHeader: vote.BlockID.PartsHeader,
@ -522,6 +524,7 @@ func makeEvidences(
Height: 1, Height: 1,
Round: 0, Round: 0,
Type: types.PrevoteType, Type: types.PrevoteType,
Timestamp: time.Now().UTC(),
BlockID: types.BlockID{ BlockID: types.BlockID{
Hash: tmhash.Sum([]byte("blockhash")), Hash: tmhash.Sum([]byte("blockhash")),
PartsHeader: types.PartSetHeader{ PartsHeader: types.PartSetHeader{
@ -584,7 +587,6 @@ func TestBroadcastEvidenceDuplicateVote(t *testing.T) {
pv := privval.LoadOrGenFilePV(pvKeyFile, pvKeyStateFile) pv := privval.LoadOrGenFilePV(pvKeyFile, pvKeyStateFile)
ev, fakes := makeEvidences(t, pv, chainID) ev, fakes := makeEvidences(t, pv, chainID)
t.Logf("evidence %v", ev) t.Logf("evidence %v", ev)
for i, c := range GetClients() { for i, c := range GetClients() {


+ 2
- 2
state/execution_test.go View File

@ -126,8 +126,8 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
height1, idx1, val1 := int64(8), 0, state.Validators.Validators[0].Address height1, idx1, val1 := int64(8), 0, state.Validators.Validators[0].Address
height2, idx2, val2 := int64(3), 1, state.Validators.Validators[1].Address height2, idx2, val2 := int64(3), 1, state.Validators.Validators[1].Address
ev1 := types.NewMockGoodEvidence(height1, idx1, val1)
ev2 := types.NewMockGoodEvidence(height2, idx2, val2)
ev1 := types.NewMockEvidence(height1, time.Now(), idx1, val1)
ev2 := types.NewMockEvidence(height2, time.Now(), idx2, val2)
now := tmtime.Now() now := tmtime.Now()
valSet := state.Validators valSet := state.Validators


+ 3
- 1
state/helpers_test.go View File

@ -3,6 +3,7 @@ package state_test
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"time"
dbm "github.com/tendermint/tm-db" dbm "github.com/tendermint/tm-db"
@ -161,7 +162,8 @@ func makeConsensusParams(
TimeIotaMs: blockTimeIotaMs, TimeIotaMs: blockTimeIotaMs,
}, },
Evidence: types.EvidenceParams{ Evidence: types.EvidenceParams{
MaxAge: evidenceAge,
MaxAgeNumBlocks: evidenceAge,
MaxAgeDuration: time.Duration(evidenceAge),
}, },
} }
} }


+ 5
- 3
state/state_test.go View File

@ -7,6 +7,7 @@ import (
"math/big" "math/big"
"os" "os"
"testing" "testing"
"time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -985,7 +986,7 @@ func TestConsensusParamsChangesSaveLoad(t *testing.T) {
func TestApplyUpdates(t *testing.T) { func TestApplyUpdates(t *testing.T) {
initParams := makeConsensusParams(1, 2, 3, 4) initParams := makeConsensusParams(1, 2, 3, 4)
const maxAge int64 = 66
cases := [...]struct { cases := [...]struct {
init types.ConsensusParams init types.ConsensusParams
updates abci.ConsensusParams updates abci.ConsensusParams
@ -1004,10 +1005,11 @@ func TestApplyUpdates(t *testing.T) {
3: {initParams, 3: {initParams,
abci.ConsensusParams{ abci.ConsensusParams{
Evidence: &abci.EvidenceParams{ Evidence: &abci.EvidenceParams{
MaxAge: 66,
MaxAgeNumBlocks: maxAge,
MaxAgeDuration: time.Duration(maxAge),
}, },
}, },
makeConsensusParams(1, 2, 3, 66)},
makeConsensusParams(1, 2, 3, maxAge)},
} }
for i, tc := range cases { for i, tc := range cases {


+ 13
- 5
state/validation.go View File

@ -158,13 +158,21 @@ func validateBlock(evidencePool EvidencePool, stateDB dbm.DB, state State, block
// - it is internally consistent // - it is internally consistent
// - it was properly signed by the alleged equivocator // - it was properly signed by the alleged equivocator
func VerifyEvidence(stateDB dbm.DB, state State, evidence types.Evidence) error { func VerifyEvidence(stateDB dbm.DB, state State, evidence types.Evidence) error {
height := state.LastBlockHeight
var (
height = state.LastBlockHeight
evidenceParams = state.ConsensusParams.Evidence
)
evidenceAge := height - evidence.Height()
maxAge := state.ConsensusParams.Evidence.MaxAge
if evidenceAge > maxAge {
ageNumBlocks := height - evidence.Height()
if ageNumBlocks > evidenceParams.MaxAgeNumBlocks {
return fmt.Errorf("evidence from height %d is too old. Min height is %d", return fmt.Errorf("evidence from height %d is too old. Min height is %d",
evidence.Height(), height-maxAge)
evidence.Height(), height-evidenceParams.MaxAgeNumBlocks)
}
ageDuration := state.LastBlockTime.Sub(evidence.Time())
if ageDuration > evidenceParams.MaxAgeDuration {
return fmt.Errorf("evidence created at %v has expired. Evidence can not be older than: %v",
evidence.Time(), state.LastBlockTime.Add(evidenceParams.MaxAgeDuration))
} }
valset, err := LoadValidators(stateDB, evidence.Height()) valset, err := LoadValidators(stateDB, evidence.Height())


+ 2
- 2
state/validation_test.go View File

@ -201,7 +201,7 @@ func TestValidateBlockEvidence(t *testing.T) {
for height := int64(1); height < validationTestsStopHeight; height++ { for height := int64(1); height < validationTestsStopHeight; height++ {
proposerAddr := state.Validators.GetProposer().Address proposerAddr := state.Validators.GetProposer().Address
proposerIdx, _ := state.Validators.GetByAddress(proposerAddr) proposerIdx, _ := state.Validators.GetByAddress(proposerAddr)
goodEvidence := types.NewMockGoodEvidence(height, proposerIdx, proposerAddr)
goodEvidence := types.NewMockEvidence(height, time.Now(), proposerIdx, proposerAddr)
if height > 1 { if height > 1 {
/* /*
A block with too much evidence fails A block with too much evidence fails
@ -254,7 +254,7 @@ func TestValidateFailBlockOnCommittedEvidence(t *testing.T) {
// A block with a couple pieces of evidence passes. // A block with a couple pieces of evidence passes.
block := makeBlock(state, height) block := makeBlock(state, height)
addr, _ := state.Validators.GetByIndex(0) addr, _ := state.Validators.GetByIndex(0)
alreadyCommittedEvidence := types.NewMockGoodEvidence(height, 0, addr)
alreadyCommittedEvidence := types.NewMockEvidence(height, time.Now(), 0, addr)
block.Evidence.Evidence = []types.Evidence{alreadyCommittedEvidence} block.Evidence.Evidence = []types.Evidence{alreadyCommittedEvidence}
block.EvidenceHash = block.Evidence.Hash() block.EvidenceHash = block.Evidence.Hash()
err := blockExec.ValidateBlock(state, block) err := blockExec.ValidateBlock(state, block)


+ 2
- 1
tools/tm-signer-harness/internal/test_harness_test.go View File

@ -46,7 +46,8 @@ const (
"time_iota_ms": "1000" "time_iota_ms": "1000"
}, },
"evidence": { "evidence": {
"max_age": "100000"
"max_age_num_blocks": "100000",
"max_age_duration": "172800000000000"
}, },
"validator": { "validator": {
"pub_key_types": [ "pub_key_types": [


+ 4
- 4
types/block_test.go View File

@ -40,7 +40,7 @@ func TestBlockAddEvidence(t *testing.T) {
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals) commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
require.NoError(t, err) require.NoError(t, err)
ev := NewMockGoodEvidence(h, 0, valSet.Validators[0].Address)
ev := NewMockEvidence(h, time.Now(), 0, valSet.Validators[0].Address)
evList := []Evidence{ev} evList := []Evidence{ev}
block := MakeBlock(h, txs, commit, evList) block := MakeBlock(h, txs, commit, evList)
@ -60,7 +60,7 @@ func TestBlockValidateBasic(t *testing.T) {
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals) commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
require.NoError(t, err) require.NoError(t, err)
ev := NewMockGoodEvidence(h, 0, valSet.Validators[0].Address)
ev := NewMockEvidence(h, time.Now(), 0, valSet.Validators[0].Address)
evList := []Evidence{ev} evList := []Evidence{ev}
testCases := []struct { testCases := []struct {
@ -123,7 +123,7 @@ func TestBlockMakePartSetWithEvidence(t *testing.T) {
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals) commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
require.NoError(t, err) require.NoError(t, err)
ev := NewMockGoodEvidence(h, 0, valSet.Validators[0].Address)
ev := NewMockEvidence(h, time.Now(), 0, valSet.Validators[0].Address)
evList := []Evidence{ev} evList := []Evidence{ev}
partSet := MakeBlock(h, []Tx{Tx("Hello World")}, commit, evList).MakePartSet(512) partSet := MakeBlock(h, []Tx{Tx("Hello World")}, commit, evList).MakePartSet(512)
@ -140,7 +140,7 @@ func TestBlockHashesTo(t *testing.T) {
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals) commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
require.NoError(t, err) require.NoError(t, err)
ev := NewMockGoodEvidence(h, 0, valSet.Validators[0].Address)
ev := NewMockEvidence(h, time.Now(), 0, valSet.Validators[0].Address)
evList := []Evidence{ev} evList := []Evidence{ev}
block := MakeBlock(h, []Tx{Tx("Hello World")}, commit, evList) block := MakeBlock(h, []Tx{Tx("Hello World")}, commit, evList)


+ 46
- 48
types/evidence.go View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"strings" "strings"
"time"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/crypto/tmhash"
@ -56,6 +57,7 @@ func (err *ErrEvidenceOverflow) Error() string {
// Evidence represents any provable malicious activity by a validator // Evidence represents any provable malicious activity by a validator
type Evidence interface { type Evidence interface {
Height() int64 // height of the equivocation Height() int64 // height of the equivocation
Time() time.Time // time of the equivocation
Address() []byte // address of the equivocating validator Address() []byte // address of the equivocating validator
Bytes() []byte // bytes which compromise the evidence Bytes() []byte // bytes which compromise the evidence
Hash() []byte // hash of the evidence Hash() []byte // hash of the evidence
@ -72,9 +74,8 @@ func RegisterEvidences(cdc *amino.Codec) {
} }
func RegisterMockEvidences(cdc *amino.Codec) { func RegisterMockEvidences(cdc *amino.Codec) {
cdc.RegisterConcrete(MockGoodEvidence{}, "tendermint/MockGoodEvidence", nil)
cdc.RegisterConcrete(MockRandomGoodEvidence{}, "tendermint/MockRandomGoodEvidence", nil)
cdc.RegisterConcrete(MockBadEvidence{}, "tendermint/MockBadEvidence", nil)
cdc.RegisterConcrete(MockEvidence{}, "tendermint/MockEvidence", nil)
cdc.RegisterConcrete(MockRandomEvidence{}, "tendermint/MockRandomEvidence", nil)
} }
const ( const (
@ -136,6 +137,11 @@ func (dve *DuplicateVoteEvidence) Height() int64 {
return dve.VoteA.Height return dve.VoteA.Height
} }
// Time return the time the evidence was created
func (dve *DuplicateVoteEvidence) Time() time.Time {
return dve.VoteA.Timestamp
}
// Address returns the address of the validator. // Address returns the address of the validator.
func (dve *DuplicateVoteEvidence) Address() []byte { func (dve *DuplicateVoteEvidence) Address() []byte {
return dve.PubKey.Address() return dve.PubKey.Address()
@ -241,72 +247,64 @@ func (dve *DuplicateVoteEvidence) ValidateBasic() error {
//----------------------------------------------------------------- //-----------------------------------------------------------------
// UNSTABLE // UNSTABLE
type MockRandomGoodEvidence struct {
MockGoodEvidence
type MockRandomEvidence struct {
MockEvidence
randBytes []byte randBytes []byte
} }
var _ Evidence = &MockRandomGoodEvidence{}
var _ Evidence = &MockRandomEvidence{}
// UNSTABLE // UNSTABLE
func NewMockRandomGoodEvidence(height int64, address []byte, randBytes []byte) MockRandomGoodEvidence {
return MockRandomGoodEvidence{
MockGoodEvidence{height, address}, randBytes,
func NewMockRandomEvidence(height int64, eTime time.Time, address []byte, randBytes []byte) MockRandomEvidence {
return MockRandomEvidence{
MockEvidence{
EvidenceHeight: height,
EvidenceTime: eTime,
EvidenceAddress: address}, randBytes,
} }
} }
func (e MockRandomGoodEvidence) Hash() []byte {
func (e MockRandomEvidence) Hash() []byte {
return []byte(fmt.Sprintf("%d-%x", e.EvidenceHeight, e.randBytes)) return []byte(fmt.Sprintf("%d-%x", e.EvidenceHeight, e.randBytes))
} }
// UNSTABLE // UNSTABLE
type MockGoodEvidence struct {
type MockEvidence struct {
EvidenceHeight int64 EvidenceHeight int64
EvidenceTime time.Time
EvidenceAddress []byte EvidenceAddress []byte
} }
var _ Evidence = &MockGoodEvidence{}
var _ Evidence = &MockEvidence{}
// UNSTABLE // UNSTABLE
func NewMockGoodEvidence(height int64, idx int, address []byte) MockGoodEvidence {
return MockGoodEvidence{height, address}
}
func (e MockGoodEvidence) Height() int64 { return e.EvidenceHeight }
func (e MockGoodEvidence) Address() []byte { return e.EvidenceAddress }
func (e MockGoodEvidence) Hash() []byte {
return []byte(fmt.Sprintf("%d-%x", e.EvidenceHeight, e.EvidenceAddress))
}
func (e MockGoodEvidence) Bytes() []byte {
return []byte(fmt.Sprintf("%d-%x", e.EvidenceHeight, e.EvidenceAddress))
}
func (e MockGoodEvidence) Verify(chainID string, pubKey crypto.PubKey) error { return nil }
func (e MockGoodEvidence) Equal(ev Evidence) bool {
e2 := ev.(MockGoodEvidence)
return e.EvidenceHeight == e2.EvidenceHeight &&
bytes.Equal(e.EvidenceAddress, e2.EvidenceAddress)
}
func (e MockGoodEvidence) ValidateBasic() error { return nil }
func (e MockGoodEvidence) String() string {
return fmt.Sprintf("GoodEvidence: %d/%s", e.EvidenceHeight, e.EvidenceAddress)
}
// UNSTABLE
type MockBadEvidence struct {
MockGoodEvidence
}
func (e MockBadEvidence) Verify(chainID string, pubKey crypto.PubKey) error {
return fmt.Errorf("mockBadEvidence")
}
func (e MockBadEvidence) Equal(ev Evidence) bool {
e2 := ev.(MockBadEvidence)
func NewMockEvidence(height int64, eTime time.Time, idx int, address []byte) MockEvidence {
return MockEvidence{
EvidenceHeight: height,
EvidenceTime: eTime,
EvidenceAddress: address}
}
func (e MockEvidence) Height() int64 { return e.EvidenceHeight }
func (e MockEvidence) Time() time.Time { return e.EvidenceTime }
func (e MockEvidence) Address() []byte { return e.EvidenceAddress }
func (e MockEvidence) Hash() []byte {
return []byte(fmt.Sprintf("%d-%x-%s",
e.EvidenceHeight, e.EvidenceAddress, e.EvidenceTime))
}
func (e MockEvidence) Bytes() []byte {
return []byte(fmt.Sprintf("%d-%x-%s",
e.EvidenceHeight, e.EvidenceAddress, e.EvidenceTime))
}
func (e MockEvidence) Verify(chainID string, pubKey crypto.PubKey) error { return nil }
func (e MockEvidence) Equal(ev Evidence) bool {
e2 := ev.(MockEvidence)
return e.EvidenceHeight == e2.EvidenceHeight && return e.EvidenceHeight == e2.EvidenceHeight &&
bytes.Equal(e.EvidenceAddress, e2.EvidenceAddress) bytes.Equal(e.EvidenceAddress, e2.EvidenceAddress)
} }
func (e MockBadEvidence) ValidateBasic() error { return nil }
func (e MockBadEvidence) String() string {
return fmt.Sprintf("BadEvidence: %d/%s", e.EvidenceHeight, e.EvidenceAddress)
func (e MockEvidence) ValidateBasic() error { return nil }
func (e MockEvidence) String() string {
return fmt.Sprintf("Evidence: %d/%s/%s", e.EvidenceHeight, e.Time(), e.EvidenceAddress)
} }
//------------------------------------------- //-------------------------------------------


+ 3
- 2
types/evidence_test.go View File

@ -3,6 +3,7 @@ package types
import ( import (
"math" "math"
"testing" "testing"
"time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -164,11 +165,11 @@ func TestDuplicateVoteEvidenceValidation(t *testing.T) {
} }
func TestMockGoodEvidenceValidateBasic(t *testing.T) { func TestMockGoodEvidenceValidateBasic(t *testing.T) {
goodEvidence := NewMockGoodEvidence(int64(1), 1, []byte{1})
goodEvidence := NewMockEvidence(int64(1), time.Now(), 1, []byte{1})
assert.Nil(t, goodEvidence.ValidateBasic()) assert.Nil(t, goodEvidence.ValidateBasic())
} }
func TestMockBadEvidenceValidateBasic(t *testing.T) { func TestMockBadEvidenceValidateBasic(t *testing.T) {
badEvidence := MockBadEvidence{MockGoodEvidence: NewMockGoodEvidence(int64(1), 1, []byte{1})}
badEvidence := NewMockEvidence(int64(1), time.Now(), 1, []byte{1})
assert.Nil(t, badEvidence.ValidateBasic()) assert.Nil(t, badEvidence.ValidateBasic())
} }

+ 16
- 6
types/params.go View File

@ -1,6 +1,8 @@
package types package types
import ( import (
"time"
"github.com/pkg/errors" "github.com/pkg/errors"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
@ -47,7 +49,8 @@ type BlockParams struct {
// EvidenceParams determine how we handle evidence of malfeasance. // EvidenceParams determine how we handle evidence of malfeasance.
type EvidenceParams struct { type EvidenceParams struct {
MaxAge int64 `json:"max_age"` // only accept new evidence more recent than this
MaxAgeNumBlocks int64 `json:"max_age_num_blocks"` // only accept new evidence more recent than this
MaxAgeDuration time.Duration `json:"max_age_duration"`
} }
// ValidatorParams restrict the public key types validators can use. // ValidatorParams restrict the public key types validators can use.
@ -77,7 +80,8 @@ func DefaultBlockParams() BlockParams {
// DefaultEvidenceParams Params returns a default EvidenceParams. // DefaultEvidenceParams Params returns a default EvidenceParams.
func DefaultEvidenceParams() EvidenceParams { func DefaultEvidenceParams() EvidenceParams {
return EvidenceParams{ return EvidenceParams{
MaxAge: 100000, // 27.8 hrs at 1block/s
MaxAgeNumBlocks: 100000, // 27.8 hrs at 1block/s
MaxAgeDuration: 48 * time.Hour,
} }
} }
@ -118,9 +122,14 @@ func (params *ConsensusParams) Validate() error {
params.Block.TimeIotaMs) params.Block.TimeIotaMs)
} }
if params.Evidence.MaxAge <= 0 {
return errors.Errorf("evidenceParams.MaxAge must be greater than 0. Got %d",
params.Evidence.MaxAge)
if params.Evidence.MaxAgeNumBlocks <= 0 {
return errors.Errorf("evidenceParams.MaxAgeNumBlocks must be greater than 0. Got %d",
params.Evidence.MaxAgeNumBlocks)
}
if params.Evidence.MaxAgeDuration <= 0 {
return errors.Errorf("evidenceParams.MaxAgeDuration must be grater than 0 if provided, Got %v",
params.Evidence.MaxAgeDuration)
} }
if len(params.Validator.PubKeyTypes) == 0 { if len(params.Validator.PubKeyTypes) == 0 {
@ -177,7 +186,8 @@ func (params ConsensusParams) Update(params2 *abci.ConsensusParams) ConsensusPar
res.Block.MaxGas = params2.Block.MaxGas res.Block.MaxGas = params2.Block.MaxGas
} }
if params2.Evidence != nil { if params2.Evidence != nil {
res.Evidence.MaxAge = params2.Evidence.MaxAge
res.Evidence.MaxAgeNumBlocks = params2.Evidence.MaxAgeNumBlocks
res.Evidence.MaxAgeDuration = params2.Evidence.MaxAgeDuration
} }
if params2.Validator != nil { if params2.Validator != nil {
// Copy params2.Validator.PubkeyTypes, and set result's value to the copy. // Copy params2.Validator.PubkeyTypes, and set result's value to the copy.


+ 5
- 2
types/params_test.go View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"sort" "sort"
"testing" "testing"
"time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
@ -59,7 +60,8 @@ func makeParams(
TimeIotaMs: blockTimeIotaMs, TimeIotaMs: blockTimeIotaMs,
}, },
Evidence: EvidenceParams{ Evidence: EvidenceParams{
MaxAge: evidenceAge,
MaxAgeNumBlocks: evidenceAge,
MaxAgeDuration: time.Duration(evidenceAge),
}, },
Validator: ValidatorParams{ Validator: ValidatorParams{
PubKeyTypes: pubkeyTypes, PubKeyTypes: pubkeyTypes,
@ -115,7 +117,8 @@ func TestConsensusParamsUpdate(t *testing.T) {
MaxGas: 200, MaxGas: 200,
}, },
Evidence: &abci.EvidenceParams{ Evidence: &abci.EvidenceParams{
MaxAge: 300,
MaxAgeNumBlocks: 300,
MaxAgeDuration: time.Duration(300),
}, },
Validator: &abci.ValidatorParams{ Validator: &abci.ValidatorParams{
PubKeyTypes: valSecp256k1, PubKeyTypes: valSecp256k1,


+ 5
- 4
types/protobuf.go View File

@ -17,7 +17,7 @@ import (
const ( const (
ABCIEvidenceTypeDuplicateVote = "duplicate/vote" ABCIEvidenceTypeDuplicateVote = "duplicate/vote"
ABCIEvidenceTypeMockGood = "mock/good"
ABCIEvidenceTypeMock = "mock/evidence"
) )
const ( const (
@ -136,7 +136,8 @@ func (tm2pb) ConsensusParams(params *ConsensusParams) *abci.ConsensusParams {
MaxGas: params.Block.MaxGas, MaxGas: params.Block.MaxGas,
}, },
Evidence: &abci.EvidenceParams{ Evidence: &abci.EvidenceParams{
MaxAge: params.Evidence.MaxAge,
MaxAgeNumBlocks: params.Evidence.MaxAgeNumBlocks,
MaxAgeDuration: params.Evidence.MaxAgeDuration,
}, },
Validator: &abci.ValidatorParams{ Validator: &abci.ValidatorParams{
PubKeyTypes: params.Validator.PubKeyTypes, PubKeyTypes: params.Validator.PubKeyTypes,
@ -159,9 +160,9 @@ func (tm2pb) Evidence(ev Evidence, valSet *ValidatorSet, evTime time.Time) abci.
switch ev.(type) { switch ev.(type) {
case *DuplicateVoteEvidence: case *DuplicateVoteEvidence:
evType = ABCIEvidenceTypeDuplicateVote evType = ABCIEvidenceTypeDuplicateVote
case MockGoodEvidence:
case MockEvidence:
// XXX: not great to have test types in production paths ... // XXX: not great to have test types in production paths ...
evType = ABCIEvidenceTypeMockGood
evType = ABCIEvidenceTypeMock
default: default:
panic(fmt.Sprintf("Unknown evidence type: %v %v", ev, reflect.TypeOf(ev))) panic(fmt.Sprintf("Unknown evidence type: %v %v", ev, reflect.TypeOf(ev)))
} }


Loading…
Cancel
Save