From 97ddbd9d7e4e3847f27b7a6e4a3aa94a392748a4 Mon Sep 17 00:00:00 2001 From: jinmannwong Date: Thu, 1 Oct 2020 09:43:43 +0100 Subject: [PATCH 1/7] Beacon evidence message and params in genesis --- abci/types/types.pb.go | 418 +++++++++++++++++++------------ abci/types/types.proto | 2 + privval/file.go | 11 + privval/messages.go | 11 + privval/retry_signer_client.go | 12 + privval/signer_client.go | 20 ++ privval/signer_requestHandler.go | 8 + proto/types/evidence.pb.go | 206 +++++++++++---- proto/types/evidence.proto | 12 + types/evidence.go | 151 +++++++++++ types/params.go | 16 +- types/params_test.go | 6 +- types/priv_validator.go | 15 ++ types/protobuf.go | 4 +- 14 files changed, 670 insertions(+), 222 deletions(-) diff --git a/abci/types/types.pb.go b/abci/types/types.pb.go index abbfaa0ec..a2acf8d6a 100644 --- a/abci/types/types.pb.go +++ b/abci/types/types.pb.go @@ -2164,10 +2164,12 @@ func (m *ValidatorParams) GetPubKeyTypes() []string { // EntropyParams contains config for DKG and entropy generation type EntropyParams struct { // Note: must be greater than 0 - AeonLength int64 `protobuf:"varint,1,opt,name=aeon_length,json=aeonLength,proto3" json:"aeon_length,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + AeonLength int64 `protobuf:"varint,1,opt,name=aeon_length,json=aeonLength,proto3" json:"aeon_length,omitempty"` + InactivityWindowSize int64 `protobuf:"varint,2,opt,name=inactivity_window_size,json=inactivityWindowSize,proto3" json:"inactivity_window_size,omitempty"` + RequiredActivityPercentage int64 `protobuf:"varint,3,opt,name=required_activity_percentage,json=requiredActivityPercentage,proto3" json:"required_activity_percentage,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *EntropyParams) Reset() { *m = EntropyParams{} } @@ -2210,6 +2212,20 @@ func (m *EntropyParams) GetAeonLength() int64 { return 0 } +func (m *EntropyParams) GetInactivityWindowSize() int64 { + if m != nil { + return m.InactivityWindowSize + } + return 0 +} + +func (m *EntropyParams) GetRequiredActivityPercentage() int64 { + if m != nil { + return m.RequiredActivityPercentage + } + return 0 +} + type LastCommitInfo struct { Round int32 `protobuf:"varint,1,opt,name=round,proto3" json:"round,omitempty"` Votes []VoteInfo `protobuf:"bytes,2,rep,name=votes,proto3" json:"votes"` @@ -3124,166 +3140,170 @@ func init() { proto.RegisterFile("abci/types/types.proto", fileDescriptor_9f1eaa func init() { golang_proto.RegisterFile("abci/types/types.proto", fileDescriptor_9f1eaa49c51fa1ac) } var fileDescriptor_9f1eaa49c51fa1ac = []byte{ - // 2543 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5a, 0xcd, 0x8f, 0x1b, 0x49, - 0x15, 0x9f, 0xf6, 0xb7, 0x9f, 0xc7, 0x63, 0xa7, 0x32, 0xd9, 0xf5, 0x9a, 0xec, 0x4c, 0xd4, 0xb3, - 0x99, 0x4c, 0xb2, 0x8b, 0x27, 0x0c, 0x5a, 0xb4, 0x21, 0xd1, 0xa2, 0xf1, 0x24, 0xcb, 0x58, 0x9b, - 0x64, 0x67, 0x3b, 0xc9, 0x10, 0x40, 0xda, 0xa6, 0xec, 0xae, 0xb4, 0x5b, 0x63, 0x77, 0xf7, 0x76, - 0x97, 0x9d, 0x31, 0xe2, 0x8e, 0x90, 0x38, 0x70, 0x00, 0x89, 0x3f, 0x81, 0x0b, 0x12, 0x48, 0x1c, - 0xf6, 0xc8, 0x71, 0x0f, 0x1c, 0xf8, 0x0b, 0x02, 0x0c, 0x9c, 0x10, 0x47, 0x84, 0xb8, 0x81, 0xea, - 0xa3, 0xbf, 0x3c, 0xfe, 0xe8, 0x84, 0xdc, 0xb8, 0x24, 0x5d, 0xd5, 0xef, 0xbd, 0xea, 0x7a, 0xf5, - 0xea, 0xf7, 0x7b, 0xef, 0x79, 0xe0, 0x0d, 0xdc, 0xed, 0x59, 0xbb, 0x74, 0xe2, 0x12, 0x5f, 0xfc, - 0xdb, 0x72, 0x3d, 0x87, 0x3a, 0xe8, 0x12, 0x25, 0xb6, 0x41, 0xbc, 0xa1, 0x65, 0xd3, 0x16, 0x13, - 0x69, 0xf1, 0x97, 0xcd, 0x6d, 0xda, 0xb7, 0x3c, 0x43, 0x77, 0xb1, 0x47, 0x27, 0xbb, 0x5c, 0x72, - 0xd7, 0x74, 0x4c, 0x27, 0x7a, 0x12, 0xea, 0xcd, 0x66, 0xcf, 0x9b, 0xb8, 0xd4, 0xd9, 0x1d, 0x12, - 0xef, 0x64, 0x40, 0xe4, 0x7f, 0xf2, 0xdd, 0xc5, 0x81, 0xd5, 0xf5, 0x77, 0x4f, 0xc6, 0xf1, 0xf5, - 0x9a, 0x9b, 0xa6, 0xe3, 0x98, 0x03, 0x22, 0x6c, 0x76, 0x47, 0xcf, 0x76, 0xa9, 0x35, 0x24, 0x3e, - 0xc5, 0x43, 0x57, 0x0a, 0x6c, 0x4c, 0x0b, 0x18, 0x23, 0x0f, 0x53, 0xcb, 0xb1, 0xc5, 0x7b, 0xf5, - 0x5f, 0x79, 0x28, 0x6a, 0xe4, 0xf3, 0x11, 0xf1, 0x29, 0xfa, 0x00, 0x72, 0xa4, 0xd7, 0x77, 0x1a, - 0x99, 0x2b, 0xca, 0x4e, 0x65, 0x4f, 0x6d, 0xcd, 0xdc, 0x4b, 0x4b, 0x4a, 0xdf, 0xeb, 0xf5, 0x9d, - 0xc3, 0x15, 0x8d, 0x6b, 0xa0, 0xdb, 0x90, 0x7f, 0x36, 0x18, 0xf9, 0xfd, 0x46, 0x96, 0xab, 0x6e, - 0x2d, 0x56, 0xfd, 0x88, 0x89, 0x1e, 0xae, 0x68, 0x42, 0x87, 0x2d, 0x6b, 0xd9, 0xcf, 0x9c, 0x46, - 0x2e, 0xcd, 0xb2, 0x1d, 0xfb, 0x19, 0x5f, 0x96, 0x69, 0xa0, 0x43, 0x00, 0x9f, 0x50, 0xdd, 0x71, - 0xd9, 0x86, 0x1a, 0x79, 0xae, 0x7f, 0x6d, 0xb1, 0xfe, 0x23, 0x42, 0x3f, 0xe1, 0xe2, 0x87, 0x2b, - 0x5a, 0xd9, 0x0f, 0x06, 0xcc, 0x92, 0x65, 0x5b, 0x54, 0xef, 0xf5, 0xb1, 0x65, 0x37, 0x0a, 0x69, - 0x2c, 0x75, 0x6c, 0x8b, 0x1e, 0x30, 0x71, 0x66, 0xc9, 0x0a, 0x06, 0xcc, 0x15, 0x9f, 0x8f, 0x88, - 0x37, 0x69, 0x14, 0xd3, 0xb8, 0xe2, 0x53, 0x26, 0xca, 0x5c, 0xc1, 0x75, 0xd0, 0xc7, 0x50, 0xe9, - 0x12, 0xd3, 0xb2, 0xf5, 0xee, 0xc0, 0xe9, 0x9d, 0x34, 0x4a, 0xdc, 0xc4, 0xce, 0x62, 0x13, 0x6d, - 0xa6, 0xd0, 0x66, 0xf2, 0x87, 0x2b, 0x1a, 0x74, 0xc3, 0x11, 0x6a, 0x43, 0xa9, 0xd7, 0x27, 0xbd, - 0x13, 0x9d, 0x9e, 0x36, 0xca, 0xdc, 0xd2, 0xd5, 0xc5, 0x96, 0x0e, 0x98, 0xf4, 0xe3, 0xd3, 0xc3, - 0x15, 0xad, 0xd8, 0x13, 0x8f, 0xcc, 0x2f, 0x06, 0x19, 0x58, 0x63, 0xe2, 0x31, 0x2b, 0x17, 0xd3, - 0xf8, 0xe5, 0xae, 0x90, 0xe7, 0x76, 0xca, 0x46, 0x30, 0x40, 0xf7, 0xa0, 0x4c, 0x6c, 0x43, 0x6e, - 0xac, 0xc2, 0x0d, 0x6d, 0x2f, 0x89, 0x30, 0xdb, 0x08, 0xb6, 0x55, 0x22, 0xf2, 0x19, 0x7d, 0x08, - 0x85, 0x9e, 0x33, 0x1c, 0x5a, 0xb4, 0xb1, 0xca, 0x6d, 0xbc, 0xb3, 0x64, 0x4b, 0x5c, 0xf6, 0x70, - 0x45, 0x93, 0x5a, 0xed, 0x22, 0xe4, 0xc7, 0x78, 0x30, 0x22, 0xea, 0x35, 0xa8, 0xc4, 0x22, 0x19, - 0x35, 0xa0, 0x38, 0x24, 0xbe, 0x8f, 0x4d, 0xd2, 0x50, 0xae, 0x28, 0x3b, 0x65, 0x2d, 0x18, 0xaa, - 0x6b, 0xb0, 0x1a, 0x8f, 0x5b, 0x75, 0x18, 0x2a, 0xb2, 0x58, 0x64, 0x8a, 0x63, 0xe2, 0xf9, 0x2c, - 0x00, 0xa5, 0xa2, 0x1c, 0xa2, 0x2d, 0xa8, 0xf2, 0xdd, 0xea, 0xc1, 0x7b, 0x76, 0xaf, 0x72, 0xda, - 0x2a, 0x9f, 0x3c, 0x96, 0x42, 0x9b, 0x50, 0x71, 0xf7, 0xdc, 0x50, 0x24, 0xcb, 0x45, 0xc0, 0xdd, - 0x73, 0xa5, 0x80, 0xfa, 0x4d, 0xa8, 0x4f, 0x87, 0x2e, 0xaa, 0x43, 0xf6, 0x84, 0x4c, 0xe4, 0x7a, - 0xec, 0x11, 0xad, 0xcb, 0x6d, 0xf1, 0x35, 0xca, 0x9a, 0xdc, 0xe3, 0x6f, 0x32, 0xa1, 0x72, 0x18, - 0xad, 0xec, 0xba, 0x31, 0x90, 0xe0, 0xda, 0x95, 0xbd, 0x66, 0x4b, 0x00, 0x44, 0x2b, 0x00, 0x88, - 0xd6, 0xe3, 0x00, 0x41, 0xda, 0xa5, 0x2f, 0x5f, 0x6c, 0xae, 0xfc, 0xec, 0x4f, 0x9b, 0x8a, 0xc6, - 0x35, 0xd0, 0x5b, 0x2c, 0xa0, 0xb0, 0x65, 0xeb, 0x96, 0x21, 0xd7, 0x29, 0xf2, 0x71, 0xc7, 0x40, - 0x9f, 0x42, 0xbd, 0xe7, 0xd8, 0x3e, 0xb1, 0xfd, 0x91, 0xcf, 0x60, 0x0e, 0x0f, 0x7d, 0x89, 0x05, - 0xf3, 0x0e, 0xf9, 0x20, 0x10, 0x3f, 0xe2, 0xd2, 0x5a, 0xad, 0x97, 0x9c, 0x40, 0xf7, 0x01, 0xc6, - 0x78, 0x60, 0x19, 0x98, 0x3a, 0x9e, 0xdf, 0xc8, 0x5d, 0xc9, 0x2e, 0x30, 0x76, 0x1c, 0x08, 0x3e, - 0x71, 0x0d, 0x4c, 0x49, 0x3b, 0xc7, 0xbe, 0x5c, 0x8b, 0xe9, 0xa3, 0x6d, 0xa8, 0x61, 0xd7, 0xd5, - 0x7d, 0x8a, 0x29, 0xd1, 0xbb, 0x13, 0x4a, 0x7c, 0x8e, 0x17, 0xab, 0x5a, 0x15, 0xbb, 0xee, 0x23, - 0x36, 0xdb, 0x66, 0x93, 0xaa, 0x11, 0x9e, 0x36, 0xbf, 0x9a, 0x08, 0x41, 0xce, 0xc0, 0x14, 0x73, - 0x6f, 0xad, 0x6a, 0xfc, 0x99, 0xcd, 0xb9, 0x98, 0xf6, 0xa5, 0x0f, 0xf8, 0x33, 0x7a, 0x03, 0x0a, - 0x7d, 0x62, 0x99, 0x7d, 0xca, 0xb7, 0x9d, 0xd5, 0xe4, 0x88, 0x1d, 0x8c, 0xeb, 0x39, 0x63, 0xc2, - 0xd1, 0xad, 0xa4, 0x89, 0x81, 0xfa, 0x8b, 0x0c, 0x5c, 0x38, 0x77, 0x7d, 0x99, 0xdd, 0x3e, 0xf6, - 0xfb, 0xc1, 0x5a, 0xec, 0x19, 0xdd, 0x66, 0x76, 0xb1, 0x41, 0x3c, 0x89, 0xca, 0x6f, 0xcf, 0xf1, - 0xc0, 0x21, 0x17, 0x92, 0x1b, 0x97, 0x2a, 0xe8, 0x09, 0xd4, 0x07, 0xd8, 0xa7, 0xba, 0x88, 0x7d, - 0x9d, 0xa3, 0x6c, 0x76, 0x21, 0x12, 0xdc, 0xc7, 0xc1, 0x9d, 0x61, 0xc1, 0x2d, 0xcd, 0xad, 0x0d, - 0x12, 0xb3, 0xe8, 0x29, 0xac, 0x77, 0x27, 0x3f, 0xc4, 0x36, 0xb5, 0x6c, 0xa2, 0x9f, 0x3b, 0xa3, - 0xcd, 0x39, 0xa6, 0xef, 0x8d, 0x2d, 0x83, 0xd8, 0xbd, 0xe0, 0x70, 0x2e, 0x86, 0x26, 0xc2, 0xc3, - 0xf3, 0xd5, 0xa7, 0xb0, 0x96, 0xc4, 0x22, 0xb4, 0x06, 0x19, 0x7a, 0x2a, 0x3d, 0x92, 0xa1, 0xa7, - 0xe8, 0x1b, 0x90, 0x63, 0xe6, 0xb8, 0x37, 0xd6, 0xe6, 0x92, 0x85, 0xd4, 0x7e, 0x3c, 0x71, 0x89, - 0xc6, 0xe5, 0x55, 0x35, 0xbc, 0x09, 0x21, 0x3e, 0x4d, 0xdb, 0x56, 0xaf, 0x43, 0x6d, 0x0a, 0x7a, - 0x62, 0xc7, 0xaa, 0xc4, 0x8f, 0x55, 0xad, 0x41, 0x35, 0x81, 0x30, 0xea, 0x1f, 0x0a, 0x50, 0xd2, - 0x88, 0xef, 0xb2, 0x20, 0x46, 0x87, 0x50, 0x26, 0xa7, 0x3d, 0x22, 0x68, 0x49, 0x59, 0x02, 0xe2, - 0x42, 0xe7, 0x5e, 0x20, 0xcf, 0x50, 0x33, 0x54, 0x46, 0xb7, 0x12, 0x94, 0xbc, 0xb5, 0xcc, 0x48, - 0x9c, 0x93, 0xef, 0x24, 0x39, 0xf9, 0x9d, 0x25, 0xba, 0x53, 0xa4, 0x7c, 0x2b, 0x41, 0xca, 0xcb, - 0x16, 0x4e, 0xb0, 0x72, 0x67, 0x06, 0x2b, 0x2f, 0xdb, 0xfe, 0x1c, 0x5a, 0xee, 0xcc, 0xa0, 0xe5, - 0x9d, 0xa5, 0xdf, 0x32, 0x93, 0x97, 0xef, 0x24, 0x79, 0x79, 0x99, 0x3b, 0xa6, 0x88, 0xf9, 0xfe, - 0x2c, 0x62, 0xbe, 0xbe, 0xc4, 0xc6, 0x5c, 0x66, 0x3e, 0x38, 0xc7, 0xcc, 0xdb, 0x4b, 0x4c, 0xcd, - 0xa0, 0xe6, 0x4e, 0x82, 0x9a, 0x21, 0x95, 0x6f, 0xe6, 0x70, 0xf3, 0x47, 0xe7, 0xb9, 0xf9, 0xda, - 0xb2, 0x50, 0x9b, 0x45, 0xce, 0xdf, 0x9a, 0x22, 0xe7, 0xab, 0xcb, 0x76, 0x35, 0x97, 0x9d, 0xaf, - 0x33, 0x7c, 0x9c, 0xba, 0x19, 0x0c, 0x4b, 0x89, 0xe7, 0x39, 0x9e, 0x24, 0x3e, 0x31, 0x50, 0x77, - 0x18, 0x62, 0x47, 0xf1, 0xbf, 0x80, 0xc9, 0xf9, 0xa5, 0x8d, 0x45, 0xbb, 0xfa, 0x85, 0x12, 0xe9, - 0x72, 0x64, 0x8b, 0xa3, 0x7d, 0x59, 0xa2, 0x7d, 0x8c, 0xe0, 0x33, 0x49, 0x82, 0xdf, 0x84, 0x0a, - 0xe3, 0x94, 0x29, 0xee, 0xc6, 0x6e, 0xc0, 0xdd, 0xe8, 0x06, 0x5c, 0xe0, 0xf8, 0x2b, 0xd2, 0x00, - 0x09, 0x24, 0x39, 0x0e, 0x24, 0x35, 0xf6, 0x42, 0x78, 0x50, 0x10, 0xc5, 0x57, 0xe1, 0x62, 0x4c, - 0x96, 0xd9, 0xe5, 0x5c, 0x20, 0x48, 0xaa, 0x1e, 0x4a, 0xef, 0xbb, 0xee, 0x21, 0xf6, 0xfb, 0xea, - 0x83, 0xc8, 0x41, 0x51, 0x5e, 0x80, 0x20, 0xd7, 0x73, 0x0c, 0xb1, 0xef, 0xaa, 0xc6, 0x9f, 0x59, - 0xae, 0x30, 0x70, 0x4c, 0xfe, 0x71, 0x65, 0x8d, 0x3d, 0x32, 0xa9, 0xf0, 0x6a, 0x97, 0xc5, 0x9d, - 0x55, 0x7f, 0xa7, 0x44, 0xf6, 0xa2, 0x54, 0x61, 0x16, 0xab, 0x2b, 0xaf, 0x93, 0xd5, 0x33, 0xff, - 0x1b, 0xab, 0xab, 0xff, 0x54, 0xa2, 0x23, 0x0d, 0xf9, 0xfa, 0xd5, 0x5c, 0xc0, 0xa2, 0xcb, 0xb2, - 0x0d, 0x72, 0xca, 0x5d, 0x9e, 0xd5, 0xc4, 0x20, 0x48, 0xb5, 0x0a, 0xfc, 0x18, 0x92, 0xa9, 0x56, - 0x91, 0xcf, 0x89, 0x01, 0x7a, 0x9f, 0xf3, 0xbc, 0xf3, 0x4c, 0x42, 0x43, 0x82, 0x04, 0x45, 0x51, - 0xd7, 0x92, 0xd5, 0xdc, 0x11, 0x13, 0xd3, 0x84, 0x74, 0x8c, 0x5f, 0xca, 0x89, 0xb4, 0xe1, 0x32, - 0x94, 0xd9, 0xa7, 0xfb, 0x2e, 0xee, 0x11, 0x7e, 0xb7, 0xcb, 0x5a, 0x34, 0xa1, 0x1a, 0x80, 0xce, - 0x63, 0x0c, 0x7a, 0x08, 0x05, 0x32, 0x26, 0x36, 0x65, 0x67, 0xc4, 0xdc, 0x7a, 0x79, 0x2e, 0x11, - 0x13, 0x9b, 0xb6, 0x1b, 0xcc, 0x99, 0x7f, 0x7f, 0xb1, 0x59, 0x17, 0x3a, 0xef, 0x39, 0x43, 0x8b, - 0x92, 0xa1, 0x4b, 0x27, 0x9a, 0xb4, 0xa2, 0xfe, 0x38, 0xc3, 0xf8, 0x30, 0x81, 0x3f, 0x33, 0xdd, - 0x1b, 0x5c, 0x9a, 0x4c, 0x2c, 0x45, 0x4a, 0xe7, 0xf2, 0xb7, 0x01, 0x4c, 0xec, 0xeb, 0xcf, 0xb1, - 0x4d, 0x89, 0x21, 0xfd, 0x5e, 0x36, 0xb1, 0xff, 0x1d, 0x3e, 0xc1, 0xf2, 0x4d, 0xf6, 0x7a, 0xe4, - 0x13, 0x83, 0x1f, 0x40, 0x56, 0x2b, 0x9a, 0xd8, 0x7f, 0xe2, 0x13, 0x23, 0xb6, 0xd7, 0xe2, 0xeb, - 0xd8, 0x6b, 0xd2, 0xdf, 0xa5, 0x69, 0x7f, 0xff, 0x24, 0x13, 0xdd, 0x8e, 0x28, 0x7d, 0xf8, 0xff, - 0xf4, 0xc5, 0x7f, 0x78, 0x4d, 0x91, 0x24, 0x01, 0xf4, 0x5d, 0xb8, 0x10, 0xde, 0x4a, 0x7d, 0xc4, - 0x6f, 0x6b, 0x10, 0x85, 0x2f, 0x77, 0xb9, 0xeb, 0xe3, 0xe4, 0xb4, 0x8f, 0x3e, 0x83, 0x37, 0xa7, - 0x30, 0x28, 0x5c, 0x20, 0xf3, 0x52, 0x50, 0x74, 0x29, 0x09, 0x45, 0x81, 0xfd, 0xc8, 0x7b, 0xd9, - 0xd7, 0xe2, 0xbd, 0x1f, 0xc0, 0x25, 0xe3, 0xc4, 0xd4, 0xcf, 0xbb, 0xe3, 0x55, 0x2a, 0x98, 0x8b, - 0xc6, 0x89, 0x39, 0xf5, 0xc6, 0x57, 0x3b, 0x2c, 0x49, 0x8e, 0x13, 0xe8, 0xcc, 0xa8, 0xdb, 0x82, - 0xaa, 0x47, 0x28, 0xab, 0xd6, 0x12, 0x75, 0xc9, 0xaa, 0x98, 0x14, 0xa4, 0xa3, 0xfe, 0x3c, 0x03, - 0xb5, 0x29, 0x3f, 0xa1, 0x0f, 0x20, 0x2f, 0x12, 0x01, 0x65, 0x61, 0x3f, 0x86, 0x1f, 0xbc, 0x74, - 0xad, 0x50, 0x40, 0xfb, 0x50, 0x22, 0x32, 0xc9, 0x97, 0x67, 0x73, 0x75, 0x49, 0x2d, 0x20, 0xf5, - 0x43, 0x35, 0x74, 0x17, 0xca, 0xa1, 0xe7, 0x96, 0x14, 0x90, 0xa1, 0x5f, 0xa4, 0x91, 0x48, 0x11, - 0x7d, 0x08, 0x45, 0x62, 0x53, 0xcf, 0x71, 0x27, 0x32, 0x7f, 0x9d, 0x97, 0xed, 0xdd, 0x13, 0x52, - 0xd2, 0x42, 0xa0, 0xa4, 0x1e, 0x40, 0x25, 0xb6, 0x3d, 0xf4, 0x15, 0x28, 0x0f, 0xf1, 0xa9, 0xac, - 0x1a, 0x45, 0x1d, 0x50, 0x1a, 0xe2, 0x53, 0x5e, 0x30, 0xa2, 0x37, 0xa1, 0xc8, 0x5e, 0x9a, 0x58, - 0xc4, 0x63, 0x56, 0x2b, 0x0c, 0xf1, 0xe9, 0xb7, 0xb1, 0xaf, 0xfe, 0x54, 0x81, 0xb5, 0xe4, 0x3e, - 0xd1, 0xbb, 0x80, 0x98, 0x2c, 0x36, 0x89, 0x6e, 0x8f, 0x86, 0x82, 0xea, 0x03, 0x8b, 0xb5, 0x21, - 0x3e, 0xdd, 0x37, 0xc9, 0xc3, 0xd1, 0x90, 0x2f, 0xed, 0xa3, 0x07, 0x50, 0x0f, 0x84, 0x83, 0x9e, - 0x9d, 0xf4, 0xea, 0x5b, 0xe7, 0x6a, 0xf6, 0xbb, 0x52, 0x40, 0x94, 0xec, 0xbf, 0x64, 0x25, 0xfb, - 0x9a, 0xb0, 0x17, 0xbc, 0x51, 0xdf, 0x87, 0xda, 0x94, 0xc7, 0x90, 0x0a, 0x55, 0x77, 0xd4, 0xd5, - 0x4f, 0xc8, 0x44, 0xe7, 0xee, 0xe0, 0x37, 0xb6, 0xac, 0x55, 0xdc, 0x51, 0xf7, 0x63, 0x32, 0x61, - 0xc5, 0x93, 0xaf, 0xde, 0x84, 0x6a, 0xc2, 0x49, 0x3c, 0xe9, 0x21, 0x8e, 0xad, 0x0f, 0x88, 0x6d, - 0xd2, 0xbe, 0xfc, 0x78, 0x60, 0x53, 0xf7, 0xf9, 0x8c, 0xda, 0x83, 0xb5, 0x64, 0x15, 0xc9, 0x18, - 0xd3, 0x73, 0x46, 0xb6, 0xc1, 0x85, 0xf3, 0x9a, 0x18, 0xa0, 0xdb, 0x90, 0x1f, 0x3b, 0xe2, 0x1a, - 0x2f, 0x2a, 0x1b, 0x8f, 0x1d, 0x4a, 0x62, 0xb5, 0xa8, 0xd0, 0x51, 0x7d, 0xc8, 0xf3, 0x0b, 0xc9, - 0x42, 0x9f, 0xd7, 0x83, 0x32, 0x63, 0x63, 0xcf, 0xe8, 0x18, 0x00, 0x53, 0xea, 0x59, 0xdd, 0x51, - 0x64, 0xbe, 0x11, 0x37, 0x3f, 0xb0, 0xba, 0x7e, 0xeb, 0x64, 0xdc, 0x3a, 0xc2, 0x96, 0xd7, 0xbe, - 0x2c, 0xaf, 0xf4, 0x7a, 0xa4, 0x13, 0xbb, 0xd6, 0x31, 0x4b, 0xea, 0x6f, 0xf3, 0x50, 0x10, 0x75, - 0x36, 0x8b, 0xb0, 0x78, 0xd7, 0xa7, 0xb2, 0xb7, 0x31, 0xef, 0xf3, 0x85, 0x94, 0xfc, 0xfa, 0x30, - 0x75, 0xdc, 0x9e, 0x6e, 0xa5, 0xb4, 0x2b, 0x67, 0x2f, 0x36, 0x8b, 0x3c, 0xed, 0xea, 0xdc, 0x8d, - 0xfa, 0x2a, 0xf3, 0xda, 0x0a, 0x41, 0x13, 0x27, 0xf7, 0xd2, 0x4d, 0x9c, 0x43, 0xa8, 0xc6, 0xf2, - 0x4c, 0xcb, 0x90, 0x05, 0xda, 0xc6, 0xa2, 0x6b, 0xde, 0xb9, 0x2b, 0xbf, 0xbf, 0x12, 0xe6, 0xa1, - 0x1d, 0x03, 0xed, 0x24, 0xbb, 0x0b, 0x3c, 0x5d, 0x15, 0x79, 0x52, 0xac, 0x61, 0xc0, 0x92, 0x55, - 0x76, 0x81, 0x18, 0x26, 0x09, 0x11, 0x91, 0x36, 0x95, 0xd8, 0x04, 0x7f, 0x79, 0x0d, 0x6a, 0x51, - 0x46, 0x27, 0x44, 0x4a, 0xc2, 0x4a, 0x34, 0xcd, 0x05, 0x6f, 0xc2, 0xba, 0x4d, 0x4e, 0xa9, 0x3e, - 0x2d, 0x5d, 0xe6, 0xd2, 0x88, 0xbd, 0x3b, 0x4e, 0x6a, 0x5c, 0x85, 0xb5, 0x88, 0x3b, 0xb8, 0x2c, - 0x88, 0x9e, 0x4f, 0x38, 0xcb, 0xc5, 0xde, 0x82, 0x52, 0x98, 0x6f, 0x57, 0xb8, 0x40, 0x11, 0x8b, - 0x34, 0x3b, 0xcc, 0xe0, 0x3d, 0xe2, 0x8f, 0x06, 0x54, 0x1a, 0x59, 0xe5, 0x32, 0x3c, 0x83, 0xd7, - 0xc4, 0x3c, 0x97, 0xdd, 0x82, 0x6a, 0x80, 0x63, 0x42, 0xae, 0xca, 0xe5, 0x56, 0x83, 0x49, 0x2e, - 0x74, 0x1d, 0xea, 0xae, 0xe7, 0xb8, 0x8e, 0x4f, 0x3c, 0x1d, 0x1b, 0x86, 0x47, 0x7c, 0xbf, 0xb1, - 0x26, 0xec, 0x05, 0xf3, 0xfb, 0x62, 0x1a, 0x1d, 0x44, 0x28, 0x56, 0x5b, 0x58, 0x85, 0xf3, 0x03, - 0x91, 0xb7, 0x34, 0x08, 0xb4, 0x00, 0xca, 0xbe, 0x06, 0xc5, 0xa0, 0x1a, 0x59, 0x87, 0x7c, 0x3b, - 0x04, 0xf6, 0x9c, 0x26, 0x06, 0x2c, 0x3b, 0xd9, 0x77, 0x5d, 0xd9, 0x9b, 0x64, 0x8f, 0xea, 0x00, - 0x8a, 0xf2, 0xd4, 0x67, 0x76, 0xa4, 0x1e, 0xc0, 0xaa, 0x8b, 0x3d, 0xe6, 0x8b, 0x78, 0x5f, 0x6a, - 0x1e, 0xc2, 0x1e, 0x61, 0x8f, 0x3e, 0x22, 0x34, 0xd1, 0x9e, 0xaa, 0x70, 0x7d, 0x31, 0xa5, 0xfe, - 0x5a, 0x81, 0xd5, 0xf8, 0x06, 0x58, 0x3c, 0x98, 0x9e, 0x33, 0x72, 0x75, 0xdf, 0x32, 0x6d, 0x4c, - 0x47, 0x1e, 0x91, 0xcb, 0xaf, 0xf1, 0xe9, 0x47, 0xc1, 0x6c, 0x04, 0x2b, 0x02, 0x77, 0x25, 0xac, - 0x4c, 0xe1, 0x53, 0x76, 0x1a, 0x9f, 0xd0, 0x25, 0x28, 0x30, 0x82, 0xb6, 0x0c, 0x59, 0x89, 0xe5, - 0x8d, 0x13, 0xb3, 0x63, 0xa0, 0x6d, 0xa8, 0xf1, 0xe8, 0xe2, 0xca, 0x3e, 0xc5, 0x1e, 0x95, 0x49, - 0x58, 0x95, 0x4d, 0xef, 0x13, 0xc7, 0x7e, 0xc4, 0x26, 0xd5, 0x5b, 0x50, 0x4d, 0xec, 0x89, 0x7d, - 0x06, 0x75, 0x28, 0x1e, 0x04, 0xe8, 0xc6, 0x07, 0xa1, 0xe7, 0x32, 0x91, 0xe7, 0xd4, 0xdb, 0x50, - 0x0e, 0x03, 0x94, 0x95, 0x95, 0xc1, 0xf9, 0x2b, 0x32, 0xe6, 0xe4, 0xb9, 0xaf, 0x43, 0xde, 0x75, - 0x9e, 0x13, 0x4f, 0x7e, 0xbb, 0x18, 0xa8, 0x24, 0x86, 0xdf, 0x22, 0x13, 0x40, 0x77, 0xa0, 0x28, - 0xf1, 0x5b, 0x82, 0xd0, 0xbc, 0xe6, 0xe0, 0x11, 0x07, 0xf4, 0xa0, 0x39, 0x28, 0xe0, 0x3d, 0x5a, - 0x26, 0x13, 0x5f, 0xe6, 0x47, 0x50, 0x0a, 0x10, 0x37, 0x49, 0xc6, 0x62, 0x85, 0x2b, 0xcb, 0xc8, - 0x58, 0x2e, 0x12, 0x23, 0xe3, 0x1b, 0x70, 0x81, 0x9d, 0x24, 0x31, 0xf4, 0x08, 0x77, 0xf8, 0x9a, - 0x25, 0xad, 0x26, 0x5e, 0xdc, 0x0f, 0x40, 0x45, 0xbd, 0x09, 0x05, 0xf1, 0xad, 0x33, 0x71, 0x7d, - 0x46, 0x9a, 0xa3, 0xfe, 0x4d, 0x81, 0x52, 0xc0, 0xb2, 0x33, 0x95, 0x12, 0x9b, 0xc8, 0xbc, 0xea, - 0x26, 0x5e, 0x3f, 0x0e, 0xbf, 0x07, 0x88, 0x47, 0x8a, 0x3e, 0x76, 0xa8, 0x65, 0x9b, 0xba, 0x38, - 0x0b, 0x11, 0x72, 0x75, 0xfe, 0xe6, 0x98, 0xbf, 0x38, 0x62, 0xf3, 0x37, 0xb6, 0xa0, 0x12, 0xeb, - 0x69, 0xa2, 0x22, 0x64, 0x1f, 0x92, 0xe7, 0xf5, 0x15, 0x54, 0x81, 0xa2, 0x46, 0x78, 0x47, 0xa8, - 0xae, 0xec, 0xfd, 0xa3, 0x08, 0xb5, 0xfd, 0xf6, 0x41, 0x67, 0xdf, 0x75, 0x07, 0x56, 0x8f, 0xd3, - 0x3e, 0xfa, 0x04, 0x72, 0xbc, 0x2b, 0x92, 0xe2, 0xd7, 0xbc, 0x66, 0x9a, 0xf6, 0x22, 0xd2, 0x20, - 0xcf, 0x9b, 0x27, 0x28, 0xcd, 0x8f, 0x7c, 0xcd, 0x54, 0x5d, 0x47, 0xf6, 0x91, 0x3c, 0xe0, 0x52, - 0xfc, 0xf6, 0xd7, 0x4c, 0xd3, 0x8a, 0x44, 0x9f, 0x41, 0x39, 0xea, 0x8a, 0xa4, 0xfd, 0x45, 0xb0, - 0x99, 0xba, 0x49, 0xc9, 0xec, 0x47, 0x75, 0x60, 0xda, 0xdf, 0xc3, 0x9a, 0xa9, 0xbb, 0x73, 0xe8, - 0x29, 0x14, 0x83, 0x8a, 0x3b, 0xdd, 0x6f, 0x76, 0xcd, 0x94, 0x0d, 0x44, 0x76, 0x7c, 0xa2, 0x51, - 0x92, 0xe6, 0x87, 0xc9, 0x66, 0xaa, 0x2e, 0x29, 0x7a, 0x02, 0x05, 0x59, 0x88, 0xa4, 0xfa, 0x35, - 0xae, 0x99, 0xae, 0x2d, 0xc8, 0x9c, 0x1c, 0xb5, 0xa2, 0xd2, 0xfe, 0x18, 0xdb, 0x4c, 0xdd, 0x1e, - 0x46, 0x18, 0x20, 0xd6, 0x3d, 0x49, 0xfd, 0x2b, 0x6b, 0x33, 0x7d, 0xdb, 0x17, 0x7d, 0x1f, 0x4a, - 0x61, 0x8d, 0x9c, 0xf2, 0xd7, 0xce, 0x66, 0xda, 0xce, 0x6b, 0xbb, 0xf3, 0xef, 0xbf, 0x6c, 0x28, - 0xbf, 0x3a, 0xdb, 0x50, 0xbe, 0x38, 0xdb, 0x50, 0xbe, 0x3c, 0xdb, 0x50, 0xfe, 0x78, 0xb6, 0xa1, - 0xfc, 0xf9, 0x6c, 0x43, 0xf9, 0xfd, 0x5f, 0x37, 0x94, 0xef, 0xbd, 0x6b, 0x5a, 0xb4, 0x3f, 0xea, - 0xb6, 0x7a, 0xce, 0x70, 0x37, 0x32, 0x18, 0x7f, 0x8c, 0xfe, 0x84, 0xa1, 0x5b, 0xe0, 0x80, 0xf5, - 0xf5, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x73, 0x36, 0xae, 0xb8, 0xd7, 0x20, 0x00, 0x00, + // 2608 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5a, 0xcd, 0x73, 0x1b, 0x49, + 0x15, 0xf7, 0xe8, 0x5b, 0x4f, 0x96, 0xa5, 0x74, 0x9c, 0xac, 0x22, 0xb2, 0x76, 0x6a, 0xbc, 0x71, + 0x9c, 0xec, 0x22, 0x2f, 0x86, 0xa5, 0x36, 0x24, 0xb5, 0x60, 0x39, 0x59, 0xac, 0xda, 0x24, 0xeb, + 0x1d, 0x27, 0xde, 0x00, 0x55, 0x3b, 0xb4, 0x34, 0x1d, 0x69, 0xca, 0xd2, 0xcc, 0x64, 0xa6, 0xa5, + 0x58, 0x29, 0xee, 0x14, 0x55, 0x1c, 0x38, 0x40, 0x15, 0x7f, 0xc2, 0x5e, 0xa8, 0x82, 0x2a, 0x0e, + 0x7b, 0xe4, 0xb8, 0x07, 0x0e, 0xfc, 0x05, 0x01, 0x0c, 0x27, 0x8a, 0x23, 0x45, 0x71, 0x83, 0xea, + 0x8f, 0xf9, 0x92, 0xf5, 0x31, 0x09, 0xb9, 0xed, 0xc5, 0x9e, 0xee, 0x7e, 0xef, 0xf5, 0xf4, 0xeb, + 0xee, 0xdf, 0xef, 0xbd, 0x37, 0x82, 0x8b, 0xb8, 0xdd, 0x31, 0xb7, 0xe9, 0xd8, 0x21, 0x9e, 0xf8, + 0xdb, 0x70, 0x5c, 0x9b, 0xda, 0xe8, 0x02, 0x25, 0x96, 0x41, 0xdc, 0x81, 0x69, 0xd1, 0x06, 0x13, + 0x69, 0xf0, 0xc1, 0xfa, 0x26, 0xed, 0x99, 0xae, 0xa1, 0x3b, 0xd8, 0xa5, 0xe3, 0x6d, 0x2e, 0xb9, + 0xdd, 0xb5, 0xbb, 0x76, 0xf8, 0x24, 0xd4, 0xeb, 0xf5, 0x8e, 0x3b, 0x76, 0xa8, 0xbd, 0x3d, 0x20, + 0xee, 0x71, 0x9f, 0xc8, 0x7f, 0x72, 0xec, 0x7c, 0xdf, 0x6c, 0x7b, 0xdb, 0xc7, 0xa3, 0xe8, 0x7c, + 0xf5, 0xf5, 0xae, 0x6d, 0x77, 0xfb, 0x44, 0xd8, 0x6c, 0x0f, 0x9f, 0x6c, 0x53, 0x73, 0x40, 0x3c, + 0x8a, 0x07, 0x8e, 0x14, 0x58, 0x9b, 0x14, 0x30, 0x86, 0x2e, 0xa6, 0xa6, 0x6d, 0x89, 0x71, 0xf5, + 0xdf, 0x59, 0xc8, 0x6b, 0xe4, 0xe9, 0x90, 0x78, 0x14, 0xbd, 0x0f, 0x19, 0xd2, 0xe9, 0xd9, 0xb5, + 0xd4, 0x15, 0x65, 0xab, 0xb4, 0xa3, 0x36, 0xa6, 0xae, 0xa5, 0x21, 0xa5, 0xef, 0x76, 0x7a, 0xf6, + 0xfe, 0x92, 0xc6, 0x35, 0xd0, 0x2d, 0xc8, 0x3e, 0xe9, 0x0f, 0xbd, 0x5e, 0x2d, 0xcd, 0x55, 0x37, + 0xe6, 0xab, 0x7e, 0xc8, 0x44, 0xf7, 0x97, 0x34, 0xa1, 0xc3, 0xa6, 0x35, 0xad, 0x27, 0x76, 0x2d, + 0x93, 0x64, 0xda, 0x96, 0xf5, 0x84, 0x4f, 0xcb, 0x34, 0xd0, 0x3e, 0x80, 0x47, 0xa8, 0x6e, 0x3b, + 0x6c, 0x41, 0xb5, 0x2c, 0xd7, 0xbf, 0x36, 0x5f, 0xff, 0x90, 0xd0, 0x8f, 0xb9, 0xf8, 0xfe, 0x92, + 0x56, 0xf4, 0xfc, 0x06, 0xb3, 0x64, 0x5a, 0x26, 0xd5, 0x3b, 0x3d, 0x6c, 0x5a, 0xb5, 0x5c, 0x12, + 0x4b, 0x2d, 0xcb, 0xa4, 0x7b, 0x4c, 0x9c, 0x59, 0x32, 0xfd, 0x06, 0x73, 0xc5, 0xd3, 0x21, 0x71, + 0xc7, 0xb5, 0x7c, 0x12, 0x57, 0x7c, 0xc2, 0x44, 0x99, 0x2b, 0xb8, 0x0e, 0xfa, 0x08, 0x4a, 0x6d, + 0xd2, 0x35, 0x2d, 0xbd, 0xdd, 0xb7, 0x3b, 0xc7, 0xb5, 0x02, 0x37, 0xb1, 0x35, 0xdf, 0x44, 0x93, + 0x29, 0x34, 0x99, 0xfc, 0xfe, 0x92, 0x06, 0xed, 0xa0, 0x85, 0x9a, 0x50, 0xe8, 0xf4, 0x48, 0xe7, + 0x58, 0xa7, 0x27, 0xb5, 0x22, 0xb7, 0x74, 0x75, 0xbe, 0xa5, 0x3d, 0x26, 0xfd, 0xf0, 0x64, 0x7f, + 0x49, 0xcb, 0x77, 0xc4, 0x23, 0xf3, 0x8b, 0x41, 0xfa, 0xe6, 0x88, 0xb8, 0xcc, 0xca, 0xf9, 0x24, + 0x7e, 0xb9, 0x23, 0xe4, 0xb9, 0x9d, 0xa2, 0xe1, 0x37, 0xd0, 0x5d, 0x28, 0x12, 0xcb, 0x90, 0x0b, + 0x2b, 0x71, 0x43, 0x9b, 0x0b, 0x4e, 0x98, 0x65, 0xf8, 0xcb, 0x2a, 0x10, 0xf9, 0x8c, 0x3e, 0x80, + 0x5c, 0xc7, 0x1e, 0x0c, 0x4c, 0x5a, 0x5b, 0xe6, 0x36, 0xde, 0x5a, 0xb0, 0x24, 0x2e, 0xbb, 0xbf, + 0xa4, 0x49, 0xad, 0x66, 0x1e, 0xb2, 0x23, 0xdc, 0x1f, 0x12, 0xf5, 0x1a, 0x94, 0x22, 0x27, 0x19, + 0xd5, 0x20, 0x3f, 0x20, 0x9e, 0x87, 0xbb, 0xa4, 0xa6, 0x5c, 0x51, 0xb6, 0x8a, 0x9a, 0xdf, 0x54, + 0x57, 0x60, 0x39, 0x7a, 0x6e, 0xd5, 0x41, 0xa0, 0xc8, 0xce, 0x22, 0x53, 0x1c, 0x11, 0xd7, 0x63, + 0x07, 0x50, 0x2a, 0xca, 0x26, 0xda, 0x80, 0x32, 0x5f, 0xad, 0xee, 0x8f, 0xb3, 0x7b, 0x95, 0xd1, + 0x96, 0x79, 0xe7, 0x91, 0x14, 0x5a, 0x87, 0x92, 0xb3, 0xe3, 0x04, 0x22, 0x69, 0x2e, 0x02, 0xce, + 0x8e, 0x23, 0x05, 0xd4, 0xef, 0x40, 0x75, 0xf2, 0xe8, 0xa2, 0x2a, 0xa4, 0x8f, 0xc9, 0x58, 0xce, + 0xc7, 0x1e, 0xd1, 0xaa, 0x5c, 0x16, 0x9f, 0xa3, 0xa8, 0xc9, 0x35, 0xfe, 0x36, 0x15, 0x28, 0x07, + 0xa7, 0x95, 0x5d, 0x37, 0x06, 0x12, 0x5c, 0xbb, 0xb4, 0x53, 0x6f, 0x08, 0x80, 0x68, 0xf8, 0x00, + 0xd1, 0x78, 0xe8, 0x23, 0x48, 0xb3, 0xf0, 0xe5, 0x8b, 0xf5, 0xa5, 0x5f, 0xfc, 0x79, 0x5d, 0xd1, + 0xb8, 0x06, 0xba, 0xc4, 0x0e, 0x14, 0x36, 0x2d, 0xdd, 0x34, 0xe4, 0x3c, 0x79, 0xde, 0x6e, 0x19, + 0xe8, 0x13, 0xa8, 0x76, 0x6c, 0xcb, 0x23, 0x96, 0x37, 0xf4, 0x18, 0xcc, 0xe1, 0x81, 0x27, 0xb1, + 0x60, 0xd6, 0x26, 0xef, 0xf9, 0xe2, 0x07, 0x5c, 0x5a, 0xab, 0x74, 0xe2, 0x1d, 0xe8, 0x1e, 0xc0, + 0x08, 0xf7, 0x4d, 0x03, 0x53, 0xdb, 0xf5, 0x6a, 0x99, 0x2b, 0xe9, 0x39, 0xc6, 0x8e, 0x7c, 0xc1, + 0x47, 0x8e, 0x81, 0x29, 0x69, 0x66, 0xd8, 0x9b, 0x6b, 0x11, 0x7d, 0xb4, 0x09, 0x15, 0xec, 0x38, + 0xba, 0x47, 0x31, 0x25, 0x7a, 0x7b, 0x4c, 0x89, 0xc7, 0xf1, 0x62, 0x59, 0x2b, 0x63, 0xc7, 0x39, + 0x64, 0xbd, 0x4d, 0xd6, 0xa9, 0x1a, 0xc1, 0x6e, 0xf3, 0xab, 0x89, 0x10, 0x64, 0x0c, 0x4c, 0x31, + 0xf7, 0xd6, 0xb2, 0xc6, 0x9f, 0x59, 0x9f, 0x83, 0x69, 0x4f, 0xfa, 0x80, 0x3f, 0xa3, 0x8b, 0x90, + 0xeb, 0x11, 0xb3, 0xdb, 0xa3, 0x7c, 0xd9, 0x69, 0x4d, 0xb6, 0xd8, 0xc6, 0x38, 0xae, 0x3d, 0x22, + 0x1c, 0xdd, 0x0a, 0x9a, 0x68, 0xa8, 0xbf, 0x4a, 0xc1, 0xb9, 0x33, 0xd7, 0x97, 0xd9, 0xed, 0x61, + 0xaf, 0xe7, 0xcf, 0xc5, 0x9e, 0xd1, 0x2d, 0x66, 0x17, 0x1b, 0xc4, 0x95, 0xa8, 0xfc, 0xe6, 0x0c, + 0x0f, 0xec, 0x73, 0x21, 0xb9, 0x70, 0xa9, 0x82, 0x1e, 0x41, 0xb5, 0x8f, 0x3d, 0xaa, 0x8b, 0xb3, + 0xaf, 0x73, 0x94, 0x4d, 0xcf, 0x45, 0x82, 0x7b, 0xd8, 0xbf, 0x33, 0xec, 0x70, 0x4b, 0x73, 0x2b, + 0xfd, 0x58, 0x2f, 0x7a, 0x0c, 0xab, 0xed, 0xf1, 0x73, 0x6c, 0x51, 0xd3, 0x22, 0xfa, 0x99, 0x3d, + 0x5a, 0x9f, 0x61, 0xfa, 0xee, 0xc8, 0x34, 0x88, 0xd5, 0xf1, 0x37, 0xe7, 0x7c, 0x60, 0x22, 0xd8, + 0x3c, 0x4f, 0x7d, 0x0c, 0x2b, 0x71, 0x2c, 0x42, 0x2b, 0x90, 0xa2, 0x27, 0xd2, 0x23, 0x29, 0x7a, + 0x82, 0xbe, 0x0d, 0x19, 0x66, 0x8e, 0x7b, 0x63, 0x65, 0x26, 0x59, 0x48, 0xed, 0x87, 0x63, 0x87, + 0x68, 0x5c, 0x5e, 0x55, 0x83, 0x9b, 0x10, 0xe0, 0xd3, 0xa4, 0x6d, 0xf5, 0x3a, 0x54, 0x26, 0xa0, + 0x27, 0xb2, 0xad, 0x4a, 0x74, 0x5b, 0xd5, 0x0a, 0x94, 0x63, 0x08, 0xa3, 0xfe, 0x31, 0x07, 0x05, + 0x8d, 0x78, 0x0e, 0x3b, 0xc4, 0x68, 0x1f, 0x8a, 0xe4, 0xa4, 0x43, 0x04, 0x2d, 0x29, 0x0b, 0x40, + 0x5c, 0xe8, 0xdc, 0xf5, 0xe5, 0x19, 0x6a, 0x06, 0xca, 0xe8, 0x66, 0x8c, 0x92, 0x37, 0x16, 0x19, + 0x89, 0x72, 0xf2, 0xed, 0x38, 0x27, 0xbf, 0xb5, 0x40, 0x77, 0x82, 0x94, 0x6f, 0xc6, 0x48, 0x79, + 0xd1, 0xc4, 0x31, 0x56, 0x6e, 0x4d, 0x61, 0xe5, 0x45, 0xcb, 0x9f, 0x41, 0xcb, 0xad, 0x29, 0xb4, + 0xbc, 0xb5, 0xf0, 0x5d, 0xa6, 0xf2, 0xf2, 0xed, 0x38, 0x2f, 0x2f, 0x72, 0xc7, 0x04, 0x31, 0xdf, + 0x9b, 0x46, 0xcc, 0xd7, 0x17, 0xd8, 0x98, 0xc9, 0xcc, 0x7b, 0x67, 0x98, 0x79, 0x73, 0x81, 0xa9, + 0x29, 0xd4, 0xdc, 0x8a, 0x51, 0x33, 0x24, 0xf2, 0xcd, 0x0c, 0x6e, 0xfe, 0xf0, 0x2c, 0x37, 0x5f, + 0x5b, 0x74, 0xd4, 0xa6, 0x91, 0xf3, 0x77, 0x27, 0xc8, 0xf9, 0xea, 0xa2, 0x55, 0xcd, 0x64, 0xe7, + 0xeb, 0x0c, 0x1f, 0x27, 0x6e, 0x06, 0xc3, 0x52, 0xe2, 0xba, 0xb6, 0x2b, 0x89, 0x4f, 0x34, 0xd4, + 0x2d, 0x86, 0xd8, 0xe1, 0xf9, 0x9f, 0xc3, 0xe4, 0xfc, 0xd2, 0x46, 0x4e, 0xbb, 0xfa, 0x85, 0x12, + 0xea, 0x72, 0x64, 0x8b, 0xa2, 0x7d, 0x51, 0xa2, 0x7d, 0x84, 0xe0, 0x53, 0x71, 0x82, 0x5f, 0x87, + 0x12, 0xe3, 0x94, 0x09, 0xee, 0xc6, 0x8e, 0xcf, 0xdd, 0xe8, 0x06, 0x9c, 0xe3, 0xf8, 0x2b, 0xc2, + 0x00, 0x09, 0x24, 0x19, 0x0e, 0x24, 0x15, 0x36, 0x20, 0x3c, 0x28, 0x88, 0xe2, 0xeb, 0x70, 0x3e, + 0x22, 0xcb, 0xec, 0x72, 0x2e, 0x10, 0x24, 0x55, 0x0d, 0xa4, 0x77, 0x1d, 0x67, 0x1f, 0x7b, 0x3d, + 0xf5, 0x7e, 0xe8, 0xa0, 0x30, 0x2e, 0x40, 0x90, 0xe9, 0xd8, 0x86, 0x58, 0x77, 0x59, 0xe3, 0xcf, + 0x2c, 0x56, 0xe8, 0xdb, 0x5d, 0xfe, 0x72, 0x45, 0x8d, 0x3d, 0x32, 0xa9, 0xe0, 0x6a, 0x17, 0xc5, + 0x9d, 0x55, 0x7f, 0xaf, 0x84, 0xf6, 0xc2, 0x50, 0x61, 0x1a, 0xab, 0x2b, 0xaf, 0x93, 0xd5, 0x53, + 0xff, 0x1f, 0xab, 0xab, 0xff, 0x52, 0xc2, 0x2d, 0x0d, 0xf8, 0xfa, 0xd5, 0x5c, 0xc0, 0x4e, 0x97, + 0x69, 0x19, 0xe4, 0x84, 0xbb, 0x3c, 0xad, 0x89, 0x86, 0x1f, 0x6a, 0xe5, 0xf8, 0x36, 0xc4, 0x43, + 0xad, 0x3c, 0xef, 0x13, 0x0d, 0xf4, 0x1e, 0xe7, 0x79, 0xfb, 0x89, 0x84, 0x86, 0x18, 0x09, 0x8a, + 0xa4, 0xae, 0x21, 0xb3, 0xb9, 0x03, 0x26, 0xa6, 0x09, 0xe9, 0x08, 0xbf, 0x14, 0x63, 0x61, 0xc3, + 0x65, 0x28, 0xb2, 0x57, 0xf7, 0x1c, 0xdc, 0x21, 0xfc, 0x6e, 0x17, 0xb5, 0xb0, 0x43, 0x35, 0x00, + 0x9d, 0xc5, 0x18, 0xf4, 0x00, 0x72, 0x64, 0x44, 0x2c, 0xca, 0xf6, 0x88, 0xb9, 0xf5, 0xf2, 0x4c, + 0x22, 0x26, 0x16, 0x6d, 0xd6, 0x98, 0x33, 0xff, 0xf1, 0x62, 0xbd, 0x2a, 0x74, 0xde, 0xb1, 0x07, + 0x26, 0x25, 0x03, 0x87, 0x8e, 0x35, 0x69, 0x45, 0xfd, 0x69, 0x8a, 0xf1, 0x61, 0x0c, 0x7f, 0xa6, + 0xba, 0xd7, 0xbf, 0x34, 0xa9, 0x48, 0x88, 0x94, 0xcc, 0xe5, 0x6f, 0x02, 0x74, 0xb1, 0xa7, 0x3f, + 0xc3, 0x16, 0x25, 0x86, 0xf4, 0x7b, 0xb1, 0x8b, 0xbd, 0x4f, 0x79, 0x07, 0x8b, 0x37, 0xd9, 0xf0, + 0xd0, 0x23, 0x06, 0xdf, 0x80, 0xb4, 0x96, 0xef, 0x62, 0xef, 0x91, 0x47, 0x8c, 0xc8, 0x5a, 0xf3, + 0xaf, 0x63, 0xad, 0x71, 0x7f, 0x17, 0x26, 0xfd, 0xfd, 0xb3, 0x54, 0x78, 0x3b, 0xc2, 0xf0, 0xe1, + 0xab, 0xe9, 0x8b, 0xff, 0xf2, 0x9c, 0x22, 0x4e, 0x02, 0xe8, 0x07, 0x70, 0x2e, 0xb8, 0x95, 0xfa, + 0x90, 0xdf, 0x56, 0xff, 0x14, 0xbe, 0xdc, 0xe5, 0xae, 0x8e, 0xe2, 0xdd, 0x1e, 0xfa, 0x0c, 0xde, + 0x98, 0xc0, 0xa0, 0x60, 0x82, 0xd4, 0x4b, 0x41, 0xd1, 0x85, 0x38, 0x14, 0xf9, 0xf6, 0x43, 0xef, + 0xa5, 0x5f, 0x8b, 0xf7, 0x7e, 0x0c, 0x17, 0x8c, 0xe3, 0xae, 0x7e, 0xd6, 0x1d, 0xaf, 0x92, 0xc1, + 0x9c, 0x37, 0x8e, 0xbb, 0x13, 0x23, 0x9e, 0xda, 0x62, 0x41, 0x72, 0x94, 0x40, 0xa7, 0x9e, 0xba, + 0x0d, 0x28, 0xbb, 0x84, 0xb2, 0x6c, 0x2d, 0x96, 0x97, 0x2c, 0x8b, 0x4e, 0x41, 0x3a, 0xea, 0x2f, + 0x53, 0x50, 0x99, 0xf0, 0x13, 0x7a, 0x1f, 0xb2, 0x22, 0x10, 0x50, 0xe6, 0xd6, 0x63, 0xf8, 0xc6, + 0x4b, 0xd7, 0x0a, 0x05, 0xb4, 0x0b, 0x05, 0x22, 0x83, 0x7c, 0xb9, 0x37, 0x57, 0x17, 0xe4, 0x02, + 0x52, 0x3f, 0x50, 0x43, 0x77, 0xa0, 0x18, 0x78, 0x6e, 0x41, 0x02, 0x19, 0xf8, 0x45, 0x1a, 0x09, + 0x15, 0xd1, 0x07, 0x90, 0x27, 0x16, 0x75, 0x6d, 0x67, 0x2c, 0xe3, 0xd7, 0x59, 0xd1, 0xde, 0x5d, + 0x21, 0x25, 0x2d, 0xf8, 0x4a, 0xea, 0x1e, 0x94, 0x22, 0xcb, 0x43, 0x5f, 0x83, 0xe2, 0x00, 0x9f, + 0xc8, 0xac, 0x51, 0xe4, 0x01, 0x85, 0x01, 0x3e, 0xe1, 0x09, 0x23, 0x7a, 0x03, 0xf2, 0x6c, 0xb0, + 0x8b, 0xc5, 0x79, 0x4c, 0x6b, 0xb9, 0x01, 0x3e, 0xf9, 0x3e, 0xf6, 0xd4, 0x9f, 0x2b, 0xb0, 0x12, + 0x5f, 0x27, 0x7a, 0x1b, 0x10, 0x93, 0xc5, 0x5d, 0xa2, 0x5b, 0xc3, 0x81, 0xa0, 0x7a, 0xdf, 0x62, + 0x65, 0x80, 0x4f, 0x76, 0xbb, 0xe4, 0xc1, 0x70, 0xc0, 0xa7, 0xf6, 0xd0, 0x7d, 0xa8, 0xfa, 0xc2, + 0x7e, 0xcd, 0x4e, 0x7a, 0xf5, 0xd2, 0x99, 0x9c, 0xfd, 0x8e, 0x14, 0x10, 0x29, 0xfb, 0xaf, 0x59, + 0xca, 0xbe, 0x22, 0xec, 0xf9, 0x23, 0xea, 0x7b, 0x50, 0x99, 0xf0, 0x18, 0x52, 0xa1, 0xec, 0x0c, + 0xdb, 0xfa, 0x31, 0x19, 0xeb, 0xdc, 0x1d, 0xfc, 0xc6, 0x16, 0xb5, 0x92, 0x33, 0x6c, 0x7f, 0x44, + 0xc6, 0x2c, 0x79, 0xf2, 0xd4, 0xcf, 0x15, 0x28, 0xc7, 0xbc, 0xc4, 0xa3, 0x1e, 0x62, 0x5b, 0x7a, + 0x9f, 0x58, 0x5d, 0xda, 0x93, 0x6f, 0x0f, 0xac, 0xeb, 0x1e, 0xef, 0x41, 0xdf, 0x82, 0x8b, 0xa6, + 0x85, 0x3b, 0xd4, 0x1c, 0x99, 0x74, 0xac, 0x3f, 0x33, 0x2d, 0xc3, 0x7e, 0xa6, 0x7b, 0xe6, 0x73, + 0x22, 0x1d, 0xb4, 0x1a, 0x8e, 0x7e, 0xca, 0x07, 0x0f, 0xcd, 0xe7, 0x04, 0x7d, 0x0f, 0x2e, 0xbb, + 0xe4, 0xe9, 0xd0, 0x74, 0x89, 0xa1, 0x07, 0xca, 0x0e, 0x71, 0x3b, 0xc4, 0xa2, 0x2c, 0x96, 0x13, + 0xc7, 0xb7, 0xee, 0xcb, 0xec, 0x4a, 0x91, 0x83, 0x40, 0x42, 0xed, 0xc0, 0x4a, 0x3c, 0x7d, 0x65, + 0x54, 0xed, 0xda, 0x43, 0xcb, 0xe0, 0x2f, 0x99, 0xd5, 0x44, 0x03, 0xdd, 0x82, 0xec, 0xc8, 0x16, + 0xf8, 0x31, 0x2f, 0x5f, 0x3d, 0xb2, 0x29, 0x89, 0x24, 0xc1, 0x42, 0x47, 0xf5, 0x20, 0xcb, 0x91, + 0x80, 0xdd, 0x39, 0x9e, 0x88, 0xca, 0x50, 0x91, 0x3d, 0xa3, 0x23, 0x00, 0x4c, 0xa9, 0x6b, 0xb6, + 0x87, 0xa1, 0xf9, 0x5a, 0xd4, 0x7c, 0xdf, 0x6c, 0x7b, 0x8d, 0xe3, 0x51, 0xe3, 0x00, 0x9b, 0x6e, + 0xf3, 0xb2, 0xc4, 0x92, 0xd5, 0x50, 0x27, 0x82, 0x27, 0x11, 0x4b, 0xea, 0xef, 0xb2, 0x90, 0x13, + 0x09, 0x3e, 0x3b, 0xda, 0xd1, 0x72, 0x53, 0x69, 0x67, 0x6d, 0xd6, 0xeb, 0x0b, 0x29, 0xf9, 0xf6, + 0x41, 0xcc, 0xba, 0x39, 0x59, 0xc3, 0x69, 0x96, 0x4e, 0x5f, 0xac, 0xe7, 0x79, 0xbc, 0xd7, 0xba, + 0x13, 0x16, 0x74, 0x66, 0xd5, 0x33, 0xfc, 0xea, 0x51, 0xe6, 0xa5, 0xab, 0x47, 0xfb, 0x50, 0x8e, + 0x04, 0xb8, 0xa6, 0x21, 0x33, 0xc3, 0xb5, 0x79, 0xf8, 0xd2, 0xba, 0x23, 0xdf, 0xbf, 0x14, 0x04, + 0xc0, 0x2d, 0x03, 0x6d, 0xc5, 0xcb, 0x1a, 0x3c, 0x4e, 0x16, 0x01, 0x5a, 0xa4, 0x52, 0xc1, 0xa2, + 0x64, 0x76, 0x73, 0x19, 0x18, 0x0a, 0x11, 0x11, 0xaf, 0x15, 0x58, 0x07, 0x1f, 0xbc, 0x06, 0x95, + 0x30, 0x94, 0x14, 0x22, 0x05, 0x61, 0x25, 0xec, 0xe6, 0x82, 0xef, 0xc2, 0xaa, 0x45, 0x4e, 0xa8, + 0x3e, 0x29, 0x5d, 0xe4, 0xd2, 0x88, 0x8d, 0x1d, 0xc5, 0x35, 0xae, 0xc2, 0x4a, 0x48, 0x5a, 0x5c, + 0x16, 0x44, 0xb1, 0x29, 0xe8, 0xe5, 0x62, 0x97, 0xa0, 0x10, 0x04, 0xfa, 0x25, 0x2e, 0x90, 0xc7, + 0x22, 0xbe, 0x0f, 0x52, 0x07, 0x97, 0x78, 0xc3, 0x3e, 0x95, 0x46, 0x96, 0xb9, 0x0c, 0x4f, 0x1d, + 0x34, 0xd1, 0xcf, 0x65, 0x37, 0xa0, 0xec, 0x03, 0xa8, 0x90, 0x2b, 0x73, 0xb9, 0x65, 0xbf, 0x93, + 0x0b, 0x5d, 0x87, 0xaa, 0xe3, 0xda, 0x8e, 0xed, 0x11, 0x57, 0xc7, 0x86, 0xe1, 0x12, 0xcf, 0xab, + 0xad, 0x08, 0x7b, 0x7e, 0xff, 0xae, 0xe8, 0x46, 0x7b, 0x21, 0x7c, 0x56, 0xe6, 0xa6, 0xff, 0x7c, + 0x43, 0x24, 0x3a, 0xf8, 0x07, 0xcd, 0xc7, 0xd0, 0x6f, 0x40, 0xde, 0x4f, 0x83, 0x56, 0x21, 0xdb, + 0x0c, 0x18, 0x25, 0xa3, 0x89, 0x06, 0x0b, 0x8b, 0x76, 0x1d, 0x47, 0x16, 0x45, 0xd9, 0xa3, 0xda, + 0x87, 0xbc, 0xdc, 0xf5, 0xa9, 0xa5, 0xb0, 0xfb, 0xb0, 0xec, 0x60, 0x97, 0xf9, 0x22, 0x5a, 0x10, + 0x9b, 0x05, 0xed, 0x07, 0xd8, 0xa5, 0x87, 0x84, 0xc6, 0xea, 0x62, 0x25, 0xae, 0x2f, 0xba, 0xd4, + 0xdf, 0x28, 0xb0, 0x1c, 0x5d, 0x00, 0x3b, 0x0f, 0x5d, 0xd7, 0x1e, 0x3a, 0xba, 0x67, 0x76, 0x2d, + 0x4c, 0x87, 0x2e, 0x91, 0xd3, 0xaf, 0xf0, 0xee, 0x43, 0xbf, 0x37, 0x84, 0x15, 0x81, 0x67, 0x12, + 0x56, 0x26, 0x70, 0x31, 0x7d, 0x06, 0x17, 0x2f, 0x40, 0x8e, 0x45, 0x06, 0xa6, 0x21, 0x53, 0xc0, + 0xac, 0x71, 0xdc, 0x6d, 0x19, 0x68, 0x13, 0x2a, 0xfc, 0x74, 0x71, 0x65, 0x8f, 0x62, 0x97, 0xca, + 0xe8, 0xaf, 0xcc, 0xba, 0x77, 0x89, 0x6d, 0x1d, 0xb2, 0x4e, 0xf5, 0x26, 0x94, 0x63, 0x6b, 0x62, + 0xaf, 0x41, 0x6d, 0x8a, 0xfb, 0x3e, 0xba, 0xf1, 0x46, 0xe0, 0xb9, 0x54, 0xe8, 0x39, 0xf5, 0x16, + 0x14, 0x83, 0x03, 0xca, 0xf2, 0x59, 0x7f, 0xff, 0x15, 0x79, 0xe6, 0xe4, 0xbe, 0xaf, 0x42, 0xd6, + 0xb1, 0x9f, 0x11, 0x57, 0xbe, 0xbb, 0x68, 0xa8, 0x24, 0x42, 0x1c, 0x22, 0x04, 0x41, 0xb7, 0x21, + 0x2f, 0x89, 0x43, 0x82, 0xd0, 0xac, 0xaa, 0xe4, 0x01, 0x67, 0x12, 0xbf, 0x2a, 0x29, 0x78, 0x25, + 0x9c, 0x26, 0x15, 0x9d, 0xe6, 0x27, 0x50, 0xf0, 0x11, 0x37, 0x1e, 0x05, 0x88, 0x19, 0xae, 0x2c, + 0x8a, 0x02, 0xe4, 0x24, 0x91, 0x28, 0xe0, 0x06, 0x9c, 0x63, 0x3b, 0x49, 0x0c, 0x3d, 0xc4, 0x1d, + 0x3e, 0x67, 0x41, 0xab, 0x88, 0x81, 0x7b, 0x3e, 0xa8, 0xa8, 0xef, 0x42, 0x4e, 0xbc, 0xeb, 0x54, + 0x5c, 0x9f, 0x12, 0x5f, 0xa9, 0x7f, 0x57, 0xa0, 0xe0, 0xd3, 0xfb, 0x54, 0xa5, 0xd8, 0x22, 0x52, + 0xaf, 0xba, 0x88, 0xd7, 0x8f, 0xc3, 0xef, 0x00, 0xe2, 0x27, 0x45, 0x1f, 0xd9, 0xd4, 0xb4, 0xba, + 0xba, 0xd8, 0x0b, 0x71, 0xe4, 0xaa, 0x7c, 0xe4, 0x88, 0x0f, 0x1c, 0xb0, 0xfe, 0x1b, 0x1b, 0x50, + 0x8a, 0x14, 0x53, 0x51, 0x1e, 0xd2, 0x0f, 0xc8, 0xb3, 0xea, 0x12, 0x2a, 0x41, 0x5e, 0x23, 0xbc, + 0x14, 0x55, 0x55, 0x76, 0xfe, 0x99, 0x87, 0xca, 0x6e, 0x73, 0xaf, 0xb5, 0xeb, 0x38, 0x7d, 0xb3, + 0xc3, 0xe3, 0x0d, 0xf4, 0x31, 0x64, 0x78, 0x39, 0x26, 0xc1, 0x67, 0xc4, 0x7a, 0x92, 0xba, 0x26, + 0xd2, 0x20, 0xcb, 0xab, 0x36, 0x28, 0xc9, 0xd7, 0xc5, 0x7a, 0xa2, 0x72, 0x27, 0x7b, 0x49, 0x7e, + 0xe0, 0x12, 0x7c, 0x74, 0xac, 0x27, 0xa9, 0x81, 0xa2, 0xcf, 0xa0, 0x18, 0x96, 0x63, 0x92, 0x7e, + 0x8a, 0xac, 0x27, 0xae, 0x8e, 0x32, 0xfb, 0x61, 0x02, 0x9a, 0xf4, 0x43, 0x5c, 0x3d, 0x71, 0x59, + 0x10, 0x3d, 0x86, 0xbc, 0x9f, 0xea, 0x27, 0xfb, 0x58, 0x58, 0x4f, 0x58, 0xb9, 0x64, 0xdb, 0x27, + 0x2a, 0x34, 0x49, 0xbe, 0x88, 0xd6, 0x13, 0x95, 0x67, 0xd1, 0x23, 0xc8, 0xc9, 0x0c, 0x28, 0xd1, + 0x67, 0xc0, 0x7a, 0xb2, 0x7a, 0x24, 0x73, 0x72, 0x58, 0x03, 0x4b, 0xfa, 0x15, 0xb8, 0x9e, 0xb8, + 0x2e, 0x8d, 0x30, 0x40, 0xa4, 0x6c, 0x93, 0xf8, 0xf3, 0x6e, 0x3d, 0x79, 0xbd, 0x19, 0xfd, 0x08, + 0x0a, 0x41, 0x72, 0x9e, 0xf0, 0x33, 0x6b, 0x3d, 0x69, 0xc9, 0xb7, 0xd9, 0xfa, 0xcf, 0x5f, 0xd7, + 0x94, 0xcf, 0x4f, 0xd7, 0x94, 0x2f, 0x4e, 0xd7, 0x94, 0x2f, 0x4f, 0xd7, 0x94, 0x3f, 0x9d, 0xae, + 0x29, 0x7f, 0x39, 0x5d, 0x53, 0xfe, 0xf0, 0xb7, 0x35, 0xe5, 0x87, 0x6f, 0x77, 0x4d, 0xda, 0x1b, + 0xb6, 0x1b, 0x1d, 0x7b, 0xb0, 0x1d, 0x1a, 0x8c, 0x3e, 0x86, 0xbf, 0x9d, 0x68, 0xe7, 0x38, 0x60, + 0x7d, 0xf3, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xd8, 0x8f, 0x3e, 0x37, 0x50, 0x21, 0x00, 0x00, } func (this *Request) Equal(that interface{}) bool { @@ -4852,6 +4872,12 @@ func (this *EntropyParams) Equal(that interface{}) bool { if this.AeonLength != that1.AeonLength { return false } + if this.InactivityWindowSize != that1.InactivityWindowSize { + return false + } + if this.RequiredActivityPercentage != that1.RequiredActivityPercentage { + return false + } if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { return false } @@ -7641,6 +7667,16 @@ func (m *EntropyParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.RequiredActivityPercentage != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.RequiredActivityPercentage)) + i-- + dAtA[i] = 0x18 + } + if m.InactivityWindowSize != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.InactivityWindowSize)) + i-- + dAtA[i] = 0x10 + } if m.AeonLength != 0 { i = encodeVarintTypes(dAtA, i, uint64(m.AeonLength)) i-- @@ -8950,8 +8986,16 @@ func NewPopulatedEntropyParams(r randyTypes, easy bool) *EntropyParams { if r.Intn(2) == 0 { this.AeonLength *= -1 } + this.InactivityWindowSize = int64(r.Int63()) + if r.Intn(2) == 0 { + this.InactivityWindowSize *= -1 + } + this.RequiredActivityPercentage = int64(r.Int63()) + if r.Intn(2) == 0 { + this.RequiredActivityPercentage *= -1 + } if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedTypes(r, 2) + this.XXX_unrecognized = randUnrecognizedTypes(r, 4) } return this } @@ -10212,6 +10256,12 @@ func (m *EntropyParams) Size() (n int) { if m.AeonLength != 0 { n += 1 + sovTypes(uint64(m.AeonLength)) } + if m.InactivityWindowSize != 0 { + n += 1 + sovTypes(uint64(m.InactivityWindowSize)) + } + if m.RequiredActivityPercentage != 0 { + n += 1 + sovTypes(uint64(m.RequiredActivityPercentage)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -15154,6 +15204,44 @@ func (m *EntropyParams) Unmarshal(dAtA []byte) error { break } } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field InactivityWindowSize", wireType) + } + m.InactivityWindowSize = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.InactivityWindowSize |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RequiredActivityPercentage", wireType) + } + m.RequiredActivityPercentage = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RequiredActivityPercentage |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) diff --git a/abci/types/types.proto b/abci/types/types.proto index 3cd5aeb05..731bba319 100644 --- a/abci/types/types.proto +++ b/abci/types/types.proto @@ -248,6 +248,8 @@ message ValidatorParams { message EntropyParams { // Note: must be greater than 0 int64 aeon_length = 1; + int64 inactivity_window_size = 2; + int64 required_activity_percentage = 3; } message LastCommitInfo { diff --git a/privval/file.go b/privval/file.go index 1303c559a..e54e8e430 100644 --- a/privval/file.go +++ b/privval/file.go @@ -283,6 +283,17 @@ func (pv *FilePV) SignDKGMessage(chainID string, msg *types.DKGMessage) error { return nil } +// SignEvidence signs a canonical representation of the Evidence, along with +// the chainID. Implements PrivValidator. +func (pv *FilePV) SignEvidence(chainID string, msg types.Evidence) ([]byte, error) { + signBytes := msg.SignBytes(chainID) + sig, err := pv.Key.PrivKey.Sign(signBytes) + if err != nil { + return nil, err + } + return sig, nil +} + // Save persists the FilePV to disk. func (pv *FilePV) Save() { pv.Key.Save() diff --git a/privval/messages.go b/privval/messages.go index 462282b62..c665b23da 100644 --- a/privval/messages.go +++ b/privval/messages.go @@ -82,6 +82,17 @@ type SignedDKGResponse struct { Error *RemoteSignerError } +// SignDKGRequest is a request to sign a DKG message +type SignEvidenceRequest struct { + Evidence types.Evidence +} + +// SignedDKGResponse is response containing a signed dkg message or an error +type SignedEvidenceResponse struct { + Signature []byte + Error *RemoteSignerError +} + // PingRequest is a request to confirm that the connection is alive. type PingRequest struct { } diff --git a/privval/retry_signer_client.go b/privval/retry_signer_client.go index f7fcb7f90..4bdfab8de 100644 --- a/privval/retry_signer_client.go +++ b/privval/retry_signer_client.go @@ -105,3 +105,15 @@ func (sc *RetrySignerClient) SignEntropy(chainID string, entropy *types.EntropyS } return fmt.Errorf("exhausted all attempts to sign entropy: %w", err) } + +func (sc *RetrySignerClient) SignEvidence(chainID string, msg types.Evidence) ([]byte, error) { + var err error + for i := 0; i < sc.retries || sc.retries == 0; i++ { + sig, err := sc.next.SignEvidence(chainID, msg) + if err == nil { + return sig, nil + } + time.Sleep(sc.timeout) + } + return nil, fmt.Errorf("exhausted all attempts to sign entropy: %w", err) +} diff --git a/privval/signer_client.go b/privval/signer_client.go index e8fa28afe..20a863d4b 100644 --- a/privval/signer_client.go +++ b/privval/signer_client.go @@ -173,3 +173,23 @@ func (sc *SignerClient) SignDKGMessage(chainID string, msg *types.DKGMessage) er return nil } + +// SignEvidence requests a remote signer to sign a DKG message +func (sc *SignerClient) SignEvidence(chainID string, msg types.Evidence) ([]byte, error) { + response, err := sc.endpoint.SendRequest(&SignEvidenceRequest{Evidence: msg}) + if err != nil { + sc.endpoint.Logger.Error("SignerClient::SignEvidence", "err", err) + return nil, err + } + + resp, ok := response.(*SignedEvidenceResponse) + if !ok { + sc.endpoint.Logger.Error("SignerClient::SignEvidence", "err", "response != SignedEvidence") + return nil, ErrUnexpectedResponse + } + if resp.Error != nil { + return nil, resp.Error + } + + return resp.Signature, nil +} diff --git a/privval/signer_requestHandler.go b/privval/signer_requestHandler.go index 14962f0bf..d360c9e5c 100644 --- a/privval/signer_requestHandler.go +++ b/privval/signer_requestHandler.go @@ -57,6 +57,14 @@ func DefaultValidationRequestHandler( res = &SignedDKGResponse{r.DKGMessage, nil} } + case *SignEvidenceRequest: + sig, err := privVal.SignEvidence(chainID, r.Evidence) + if err != nil { + res = &SignedEvidenceResponse{nil, &RemoteSignerError{0, err.Error()}} + } else { + res = &SignedEvidenceResponse{sig, nil} + } + case *PingRequest: err, res = nil, &PingResponse{} diff --git a/proto/types/evidence.pb.go b/proto/types/evidence.pb.go index 7452513f6..636b5936e 100644 --- a/proto/types/evidence.pb.go +++ b/proto/types/evidence.pb.go @@ -344,6 +344,84 @@ func (m *LunaticValidatorEvidence) GetInvalidHeaderField() string { return "" } +type BeaconInactivityEvidence struct { + EvidenceHeight int64 `protobuf:"varint,1,opt,name=evidence_height,json=evidenceHeight,proto3" json:"evidence_height,omitempty"` + EvidenceTime time.Time `protobuf:"bytes,2,opt,name=evidence_time,json=evidenceTime,proto3,stdtime" json:"evidence_time"` + DefendantAddress []byte `protobuf:"bytes,3,opt,name=defendant_address,json=defendantAddress,proto3" json:"defendant_address,omitempty"` + ComplainantAddress []byte `protobuf:"bytes,4,opt,name=complainant_address,json=complainantAddress,proto3" json:"complainant_address,omitempty"` + AeonStart int64 `protobuf:"varint,5,opt,name=aeon_start,json=aeonStart,proto3" json:"aeon_start,omitempty"` + ComplainantSignature []byte `protobuf:"bytes,6,opt,name=complainant_signature,json=complainantSignature,proto3" json:"complainant_signature,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BeaconInactivityEvidence) Reset() { *m = BeaconInactivityEvidence{} } +func (m *BeaconInactivityEvidence) String() string { return proto.CompactTextString(m) } +func (*BeaconInactivityEvidence) ProtoMessage() {} +func (*BeaconInactivityEvidence) Descriptor() ([]byte, []int) { + return fileDescriptor_86495eef24aeacc0, []int{6} +} +func (m *BeaconInactivityEvidence) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BeaconInactivityEvidence.Unmarshal(m, b) +} +func (m *BeaconInactivityEvidence) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BeaconInactivityEvidence.Marshal(b, m, deterministic) +} +func (m *BeaconInactivityEvidence) XXX_Merge(src proto.Message) { + xxx_messageInfo_BeaconInactivityEvidence.Merge(m, src) +} +func (m *BeaconInactivityEvidence) XXX_Size() int { + return xxx_messageInfo_BeaconInactivityEvidence.Size(m) +} +func (m *BeaconInactivityEvidence) XXX_DiscardUnknown() { + xxx_messageInfo_BeaconInactivityEvidence.DiscardUnknown(m) +} + +var xxx_messageInfo_BeaconInactivityEvidence proto.InternalMessageInfo + +func (m *BeaconInactivityEvidence) GetEvidenceHeight() int64 { + if m != nil { + return m.EvidenceHeight + } + return 0 +} + +func (m *BeaconInactivityEvidence) GetEvidenceTime() time.Time { + if m != nil { + return m.EvidenceTime + } + return time.Time{} +} + +func (m *BeaconInactivityEvidence) GetDefendantAddress() []byte { + if m != nil { + return m.DefendantAddress + } + return nil +} + +func (m *BeaconInactivityEvidence) GetComplainantAddress() []byte { + if m != nil { + return m.ComplainantAddress + } + return nil +} + +func (m *BeaconInactivityEvidence) GetAeonStart() int64 { + if m != nil { + return m.AeonStart + } + return 0 +} + +func (m *BeaconInactivityEvidence) GetComplainantSignature() []byte { + if m != nil { + return m.ComplainantSignature + } + return nil +} + type Evidence struct { // Types that are valid to be assigned to Sum: // *Evidence_DuplicateVoteEvidence @@ -352,6 +430,7 @@ type Evidence struct { // *Evidence_PotentialAmnesiaEvidence // *Evidence_MockEvidence // *Evidence_MockRandomEvidence + // *Evidence_BeaconInactivityEvidence Sum isEvidence_Sum `protobuf_oneof:"sum"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -362,7 +441,7 @@ func (m *Evidence) Reset() { *m = Evidence{} } func (m *Evidence) String() string { return proto.CompactTextString(m) } func (*Evidence) ProtoMessage() {} func (*Evidence) Descriptor() ([]byte, []int) { - return fileDescriptor_86495eef24aeacc0, []int{6} + return fileDescriptor_86495eef24aeacc0, []int{7} } func (m *Evidence) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Evidence.Unmarshal(m, b) @@ -404,6 +483,9 @@ type Evidence_MockEvidence struct { type Evidence_MockRandomEvidence struct { MockRandomEvidence *MockRandomEvidence `protobuf:"bytes,6,opt,name=mock_random_evidence,json=mockRandomEvidence,proto3,oneof" json:"mock_random_evidence,omitempty"` } +type Evidence_BeaconInactivityEvidence struct { + BeaconInactivityEvidence *BeaconInactivityEvidence `protobuf:"bytes,7,opt,name=beacon_inactivity_evidence,json=beaconInactivityEvidence,proto3,oneof" json:"beacon_inactivity_evidence,omitempty"` +} func (*Evidence_DuplicateVoteEvidence) isEvidence_Sum() {} func (*Evidence_ConflictingHeadersEvidence) isEvidence_Sum() {} @@ -411,6 +493,7 @@ func (*Evidence_LunaticValidatorEvidence) isEvidence_Sum() {} func (*Evidence_PotentialAmnesiaEvidence) isEvidence_Sum() {} func (*Evidence_MockEvidence) isEvidence_Sum() {} func (*Evidence_MockRandomEvidence) isEvidence_Sum() {} +func (*Evidence_BeaconInactivityEvidence) isEvidence_Sum() {} func (m *Evidence) GetSum() isEvidence_Sum { if m != nil { @@ -461,6 +544,13 @@ func (m *Evidence) GetMockRandomEvidence() *MockRandomEvidence { return nil } +func (m *Evidence) GetBeaconInactivityEvidence() *BeaconInactivityEvidence { + if x, ok := m.GetSum().(*Evidence_BeaconInactivityEvidence); ok { + return x.BeaconInactivityEvidence + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*Evidence) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -470,6 +560,7 @@ func (*Evidence) XXX_OneofWrappers() []interface{} { (*Evidence_PotentialAmnesiaEvidence)(nil), (*Evidence_MockEvidence)(nil), (*Evidence_MockRandomEvidence)(nil), + (*Evidence_BeaconInactivityEvidence)(nil), } } @@ -486,7 +577,7 @@ func (m *EvidenceData) Reset() { *m = EvidenceData{} } func (m *EvidenceData) String() string { return proto.CompactTextString(m) } func (*EvidenceData) ProtoMessage() {} func (*EvidenceData) Descriptor() ([]byte, []int) { - return fileDescriptor_86495eef24aeacc0, []int{7} + return fileDescriptor_86495eef24aeacc0, []int{8} } func (m *EvidenceData) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EvidenceData.Unmarshal(m, b) @@ -532,7 +623,7 @@ func (m *ProofOfLockChange) Reset() { *m = ProofOfLockChange{} } func (m *ProofOfLockChange) String() string { return proto.CompactTextString(m) } func (*ProofOfLockChange) ProtoMessage() {} func (*ProofOfLockChange) Descriptor() ([]byte, []int) { - return fileDescriptor_86495eef24aeacc0, []int{8} + return fileDescriptor_86495eef24aeacc0, []int{9} } func (m *ProofOfLockChange) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ProofOfLockChange.Unmarshal(m, b) @@ -573,6 +664,7 @@ func init() { proto.RegisterType((*MockRandomEvidence)(nil), "tendermint.proto.types.MockRandomEvidence") proto.RegisterType((*ConflictingHeadersEvidence)(nil), "tendermint.proto.types.ConflictingHeadersEvidence") proto.RegisterType((*LunaticValidatorEvidence)(nil), "tendermint.proto.types.LunaticValidatorEvidence") + proto.RegisterType((*BeaconInactivityEvidence)(nil), "tendermint.proto.types.BeaconInactivityEvidence") proto.RegisterType((*Evidence)(nil), "tendermint.proto.types.Evidence") proto.RegisterType((*EvidenceData)(nil), "tendermint.proto.types.EvidenceData") proto.RegisterType((*ProofOfLockChange)(nil), "tendermint.proto.types.ProofOfLockChange") @@ -581,54 +673,62 @@ func init() { func init() { proto.RegisterFile("proto/types/evidence.proto", fileDescriptor_86495eef24aeacc0) } var fileDescriptor_86495eef24aeacc0 = []byte{ - // 784 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0xcb, 0x6e, 0xdb, 0x38, - 0x14, 0xb5, 0xfc, 0x9a, 0x84, 0x71, 0xe6, 0x41, 0x24, 0x13, 0x43, 0x48, 0x26, 0x81, 0x30, 0x98, - 0x64, 0x06, 0x33, 0x72, 0xe2, 0x0c, 0x8a, 0x2e, 0x1b, 0x27, 0x0d, 0x5c, 0x24, 0x45, 0x03, 0xb5, - 0xc8, 0xa2, 0x8b, 0x0a, 0x94, 0x44, 0x4b, 0x84, 0x25, 0x51, 0x90, 0x28, 0x03, 0x5a, 0xb7, 0x8b, - 0x2e, 0xbb, 0xe9, 0x67, 0x74, 0xdb, 0x1f, 0xe8, 0xa6, 0xeb, 0x7e, 0x40, 0xfb, 0x2b, 0x85, 0x48, - 0x4a, 0x72, 0x90, 0xc8, 0x70, 0xbb, 0xeb, 0x26, 0x60, 0x2e, 0xef, 0x3d, 0xe7, 0x90, 0xf7, 0xea, - 0xd0, 0x40, 0x8d, 0x62, 0xca, 0xe8, 0x80, 0x65, 0x11, 0x4e, 0x06, 0x78, 0x46, 0x1c, 0x1c, 0xda, - 0x58, 0xe7, 0x41, 0xf8, 0x3b, 0xc3, 0xa1, 0x83, 0xe3, 0x80, 0x84, 0x4c, 0x44, 0x74, 0x9e, 0xa6, - 0xfe, 0xc5, 0x3c, 0x12, 0x3b, 0x66, 0x84, 0x62, 0x96, 0x0d, 0x44, 0xbd, 0x4b, 0x5d, 0x5a, 0xad, - 0x44, 0xb6, 0xba, 0x35, 0x8f, 0xcd, 0xff, 0xca, 0x8d, 0x5d, 0x97, 0x52, 0xd7, 0xc7, 0xa2, 0xd6, - 0x4a, 0x27, 0x03, 0x46, 0x02, 0x9c, 0x30, 0x14, 0x44, 0x32, 0x61, 0x47, 0x54, 0xda, 0x71, 0x16, - 0x31, 0x3a, 0x98, 0xe2, 0xec, 0x46, 0xbd, 0xf6, 0x41, 0x01, 0x9b, 0x67, 0x69, 0xe4, 0x13, 0x1b, - 0x31, 0x7c, 0x4d, 0x19, 0x7e, 0x28, 0x85, 0xc3, 0x07, 0xe0, 0xa7, 0x28, 0xb5, 0xcc, 0x29, 0xce, - 0xfa, 0xca, 0x9e, 0x72, 0xb0, 0x36, 0xdc, 0xd7, 0x6f, 0x1d, 0x42, 0xa0, 0xea, 0x39, 0xaa, 0x7e, - 0x95, 0x5a, 0x3e, 0xb1, 0x2f, 0x70, 0x66, 0x74, 0xa3, 0xd4, 0xba, 0xc0, 0x19, 0x3c, 0x06, 0xdd, - 0x19, 0x65, 0xd8, 0x44, 0xfd, 0x26, 0x07, 0xd8, 0xd6, 0xef, 0xbe, 0x05, 0x3d, 0xe7, 0x35, 0x3a, - 0x79, 0xee, 0x49, 0x59, 0x64, 0xf5, 0x5b, 0xcb, 0x16, 0x8d, 0xb4, 0x57, 0x0a, 0xe8, 0x5f, 0x51, - 0x86, 0x43, 0x46, 0x90, 0x7f, 0x12, 0x84, 0x38, 0x21, 0xa8, 0x3c, 0x48, 0x25, 0x43, 0xf9, 0x1e, - 0x19, 0xcd, 0xe5, 0x65, 0xbc, 0x53, 0x40, 0xef, 0x31, 0xb5, 0xa7, 0x25, 0xf5, 0x3e, 0xf8, 0xa5, - 0x18, 0x04, 0xd3, 0xc3, 0xc4, 0xf5, 0x18, 0xd7, 0xd0, 0x32, 0x7e, 0x2e, 0xc2, 0x63, 0x1e, 0x85, - 0x8f, 0xc0, 0x7a, 0x99, 0x98, 0x77, 0x50, 0xb2, 0xaa, 0xba, 0x68, 0xaf, 0x5e, 0xb4, 0x57, 0x7f, - 0x56, 0xb4, 0x77, 0xb4, 0xf2, 0xf1, 0xf3, 0x6e, 0xe3, 0xcd, 0x97, 0x5d, 0xc5, 0xe8, 0x15, 0xa5, - 0xf9, 0x26, 0xfc, 0x1b, 0xfc, 0x5a, 0x42, 0x21, 0xc7, 0x89, 0x71, 0x92, 0xf0, 0xab, 0xec, 0x19, - 0xa5, 0x96, 0x13, 0x11, 0xd6, 0x3e, 0x29, 0x00, 0xe6, 0x7a, 0x0d, 0x14, 0x3a, 0x34, 0xf8, 0x41, - 0x54, 0xc3, 0x1d, 0x00, 0x62, 0x14, 0x3a, 0xa6, 0x95, 0x31, 0x9c, 0xf4, 0xdb, 0x3c, 0x69, 0x35, - 0x8f, 0x8c, 0xf2, 0x80, 0xf6, 0x5a, 0x01, 0xea, 0x29, 0x0d, 0x27, 0x3e, 0xb1, 0x19, 0x09, 0xdd, - 0x31, 0x46, 0x0e, 0x8e, 0x93, 0xf2, 0x70, 0xff, 0x83, 0xa6, 0x77, 0x24, 0x27, 0xe1, 0xcf, 0xba, - 0xa6, 0x3e, 0x25, 0x6e, 0x88, 0x1d, 0x51, 0x6a, 0x34, 0xbd, 0x23, 0x5e, 0x35, 0x94, 0xc7, 0x5b, - 0xb6, 0x6a, 0xa8, 0xbd, 0x57, 0x40, 0xff, 0x32, 0x0d, 0x11, 0x23, 0xf6, 0x35, 0xf2, 0x89, 0x83, - 0x18, 0x8d, 0x4b, 0x21, 0xf7, 0x40, 0xd7, 0xe3, 0xa9, 0x52, 0xcc, 0x1f, 0x75, 0xb0, 0x12, 0x50, - 0x66, 0xc3, 0x43, 0xd0, 0xce, 0xa7, 0x6d, 0xa9, 0xb9, 0xe4, 0x99, 0xf0, 0x10, 0x6c, 0x90, 0x70, - 0x96, 0x0b, 0x30, 0x05, 0x86, 0x39, 0x21, 0xd8, 0x77, 0xf8, 0xfd, 0xae, 0x1a, 0x50, 0xee, 0x09, - 0x9a, 0xf3, 0x7c, 0x47, 0x7b, 0xd9, 0x01, 0x2b, 0xa5, 0x50, 0x17, 0x6c, 0x39, 0x85, 0x43, 0x98, - 0xfc, 0xa3, 0x28, 0x3a, 0x22, 0x95, 0xff, 0x57, 0xa7, 0xe1, 0x4e, 0x63, 0x19, 0x37, 0x8c, 0x4d, - 0xe7, 0x4e, 0xc7, 0x99, 0x81, 0x6d, 0xbb, 0x6a, 0x9c, 0xd4, 0x9a, 0x54, 0x6c, 0xe2, 0xc4, 0xc3, - 0x3a, 0xb6, 0xfa, 0xa6, 0x8f, 0x1b, 0x86, 0x6a, 0xd7, 0x8f, 0x44, 0x04, 0x54, 0x5f, 0x74, 0xc9, - 0x9c, 0x15, 0x6d, 0xaa, 0x58, 0x85, 0x0d, 0x1d, 0xd6, 0xb1, 0xd6, 0xf5, 0x77, 0xdc, 0x30, 0xfa, - 0x7e, 0x5d, 0xef, 0x23, 0xa0, 0x46, 0x85, 0x5d, 0x99, 0x48, 0xf8, 0x55, 0xc5, 0xd8, 0x5e, 0xcc, - 0x58, 0x67, 0x74, 0x39, 0x63, 0x54, 0x67, 0x82, 0x17, 0x60, 0x3d, 0xa0, 0xf6, 0xb4, 0x22, 0xe9, - 0x2c, 0x9e, 0xe5, 0x79, 0x1b, 0x1b, 0x37, 0x8c, 0x5e, 0x30, 0x6f, 0x6b, 0x2f, 0xc0, 0x06, 0x07, - 0x8b, 0xb9, 0x6f, 0x54, 0x98, 0x5d, 0x8e, 0xf9, 0xcf, 0x22, 0xcc, 0x9b, 0x56, 0x33, 0x6e, 0x18, - 0x30, 0xb8, 0x15, 0x1d, 0x75, 0x40, 0x2b, 0x49, 0x03, 0x6d, 0x02, 0x7a, 0x45, 0xe8, 0x0c, 0x31, - 0x04, 0x47, 0x60, 0x65, 0x6e, 0xf2, 0x5a, 0x07, 0x6b, 0xc3, 0xbd, 0x3a, 0xaa, 0x12, 0xaa, 0x9d, - 0xfb, 0x8d, 0x51, 0xd6, 0x41, 0x08, 0xda, 0x1e, 0x4a, 0x3c, 0x3e, 0x4b, 0x3d, 0x83, 0xaf, 0xb5, - 0xb7, 0x0a, 0xf8, 0xed, 0x2a, 0xa6, 0x74, 0xf2, 0x64, 0x72, 0x49, 0xed, 0xe9, 0xa9, 0x87, 0x42, - 0x17, 0xc3, 0xfb, 0x80, 0xbb, 0x7a, 0x22, 0xa9, 0x16, 0x7e, 0x68, 0x92, 0x46, 0x14, 0xc0, 0xf3, - 0xea, 0xe5, 0x6c, 0x7e, 0xd3, 0xcb, 0x29, 0x61, 0xe4, 0xfb, 0x39, 0xd2, 0x9f, 0xff, 0xeb, 0x12, - 0xe6, 0xa5, 0x96, 0x6e, 0xd3, 0x60, 0x50, 0x41, 0xcc, 0x2f, 0xe7, 0x7e, 0x17, 0x58, 0x5d, 0xfe, - 0xcf, 0xf1, 0xd7, 0x00, 0x00, 0x00, 0xff, 0xff, 0x97, 0x06, 0x2d, 0xa0, 0x89, 0x08, 0x00, 0x00, + // 900 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4d, 0x8f, 0xdb, 0x44, + 0x18, 0x8e, 0xb3, 0x49, 0xba, 0xfb, 0x36, 0x85, 0x76, 0xd8, 0xa5, 0x96, 0xd5, 0xb2, 0x95, 0x85, + 0x68, 0xf9, 0x72, 0xb6, 0x59, 0x84, 0x38, 0xb2, 0x69, 0xa9, 0x52, 0x6d, 0x11, 0x2b, 0x2f, 0xea, + 0x81, 0x03, 0xd6, 0xd8, 0x9e, 0xd8, 0xa3, 0xd8, 0x33, 0x96, 0x3d, 0x8e, 0xe4, 0x3b, 0x07, 0x8e, + 0x5c, 0xf8, 0x19, 0x5c, 0x39, 0x23, 0x71, 0xe1, 0xcc, 0x0f, 0x80, 0x5f, 0xc1, 0x1d, 0x79, 0xc6, + 0x5f, 0x65, 0xd7, 0x51, 0xe0, 0x82, 0x7a, 0x89, 0x9c, 0xf7, 0xe3, 0x79, 0xde, 0x99, 0xf7, 0x99, + 0x77, 0x06, 0x8c, 0x24, 0xe5, 0x82, 0xcf, 0x44, 0x91, 0x90, 0x6c, 0x46, 0x36, 0xd4, 0x27, 0xcc, + 0x23, 0x96, 0x34, 0xa2, 0xb7, 0x05, 0x61, 0x3e, 0x49, 0x63, 0xca, 0x84, 0xb2, 0x58, 0x32, 0xcc, + 0x78, 0x4f, 0x84, 0x34, 0xf5, 0x9d, 0x04, 0xa7, 0xa2, 0x98, 0xa9, 0xfc, 0x80, 0x07, 0xbc, 0xfd, + 0x52, 0xd1, 0xc6, 0xdd, 0x2e, 0xb6, 0xfc, 0xad, 0x1c, 0xc7, 0x01, 0xe7, 0x41, 0x44, 0x54, 0xae, + 0x9b, 0xaf, 0x66, 0x82, 0xc6, 0x24, 0x13, 0x38, 0x4e, 0xaa, 0x80, 0xfb, 0x2a, 0xd3, 0x4b, 0x8b, + 0x44, 0xf0, 0xd9, 0x9a, 0x14, 0xaf, 0xe4, 0x9b, 0xbf, 0x6a, 0x70, 0xf4, 0x34, 0x4f, 0x22, 0xea, + 0x61, 0x41, 0x5e, 0x72, 0x41, 0xbe, 0xa8, 0x0a, 0x47, 0x9f, 0xc3, 0x8d, 0x24, 0x77, 0x9d, 0x35, + 0x29, 0x74, 0xed, 0x81, 0xf6, 0xe8, 0xe6, 0xfc, 0xa1, 0x75, 0x65, 0x11, 0x0a, 0xd5, 0x2a, 0x51, + 0xad, 0x8b, 0xdc, 0x8d, 0xa8, 0x77, 0x4e, 0x0a, 0x7b, 0x92, 0xe4, 0xee, 0x39, 0x29, 0xd0, 0x29, + 0x4c, 0x36, 0x5c, 0x10, 0x07, 0xeb, 0x43, 0x09, 0x70, 0xcf, 0xba, 0x7e, 0x17, 0xac, 0x92, 0xd7, + 0x1e, 0x97, 0xb1, 0x67, 0x4d, 0x92, 0xab, 0xef, 0xed, 0x9a, 0xb4, 0x30, 0xbf, 0xd3, 0x40, 0xbf, + 0xe0, 0x82, 0x30, 0x41, 0x71, 0x74, 0x16, 0x33, 0x92, 0x51, 0xdc, 0x2c, 0xa4, 0x2d, 0x43, 0xfb, + 0x2f, 0x65, 0x0c, 0x77, 0x2f, 0xe3, 0x27, 0x0d, 0xa6, 0x5f, 0x72, 0x6f, 0xdd, 0x50, 0x3f, 0x84, + 0x37, 0x6b, 0x21, 0x38, 0x21, 0xa1, 0x41, 0x28, 0x64, 0x0d, 0x7b, 0xf6, 0x1b, 0xb5, 0x79, 0x29, + 0xad, 0xe8, 0x39, 0xdc, 0x6a, 0x02, 0xcb, 0x0e, 0x56, 0xac, 0x86, 0xa5, 0xda, 0x6b, 0xd5, 0xed, + 0xb5, 0xbe, 0xae, 0xdb, 0xbb, 0xd8, 0xff, 0xed, 0x8f, 0xe3, 0xc1, 0x0f, 0x7f, 0x1e, 0x6b, 0xf6, + 0xb4, 0x4e, 0x2d, 0x9d, 0xe8, 0x7d, 0xb8, 0xdd, 0x40, 0x61, 0xdf, 0x4f, 0x49, 0x96, 0xc9, 0xad, + 0x9c, 0xda, 0x4d, 0x2d, 0x67, 0xca, 0x6c, 0xfe, 0xae, 0x01, 0x2a, 0xeb, 0xb5, 0x31, 0xf3, 0x79, + 0xfc, 0x9a, 0x54, 0x8d, 0xee, 0x03, 0xa4, 0x98, 0xf9, 0x8e, 0x5b, 0x08, 0x92, 0xe9, 0x23, 0x19, + 0x74, 0x50, 0x5a, 0x16, 0xa5, 0xc1, 0xfc, 0x5e, 0x03, 0xe3, 0x09, 0x67, 0xab, 0x88, 0x7a, 0x82, + 0xb2, 0x60, 0x49, 0xb0, 0x4f, 0xd2, 0xac, 0x59, 0xdc, 0x27, 0x30, 0x0c, 0x1f, 0x57, 0x4a, 0x78, + 0xb7, 0xaf, 0xa9, 0x97, 0x34, 0x60, 0xc4, 0x57, 0xa9, 0xf6, 0x30, 0x7c, 0x2c, 0xb3, 0xe6, 0xd5, + 0xf2, 0x76, 0xcd, 0x9a, 0x9b, 0x3f, 0x6b, 0xa0, 0xbf, 0xc8, 0x19, 0x16, 0xd4, 0x7b, 0x89, 0x23, + 0xea, 0x63, 0xc1, 0xd3, 0xa6, 0x90, 0x4f, 0x61, 0x12, 0xca, 0xd0, 0xaa, 0x98, 0x77, 0xfa, 0x60, + 0x2b, 0xc0, 0x2a, 0x1a, 0x9d, 0xc0, 0xa8, 0x54, 0xdb, 0x4e, 0xba, 0x94, 0x91, 0xe8, 0x04, 0x0e, + 0x29, 0xdb, 0x94, 0x05, 0x38, 0x0a, 0xc3, 0x59, 0x51, 0x12, 0xf9, 0x72, 0x7f, 0x0f, 0x6c, 0x54, + 0xf9, 0x14, 0xcd, 0xb3, 0xd2, 0x63, 0xfe, 0x32, 0x04, 0x7d, 0x41, 0xb0, 0xc7, 0xd9, 0x73, 0x86, + 0x3d, 0x41, 0x37, 0x54, 0x14, 0xff, 0xab, 0x3c, 0x3e, 0x84, 0x3b, 0x3e, 0x59, 0x11, 0xe6, 0x63, + 0x26, 0xfe, 0xa1, 0x8f, 0xdb, 0x8d, 0xa3, 0x16, 0xc8, 0x0c, 0xde, 0xf2, 0x78, 0x9c, 0x44, 0x98, + 0xb2, 0x6e, 0xb8, 0x52, 0x0a, 0xea, 0xb8, 0x3a, 0x8a, 0xc2, 0x84, 0x33, 0x27, 0x13, 0x38, 0x15, + 0xfa, 0x58, 0x2e, 0xe6, 0xa0, 0xb4, 0x5c, 0x96, 0x06, 0x74, 0x0a, 0x47, 0x5d, 0xbc, 0x8c, 0x06, + 0x0c, 0x8b, 0x3c, 0x25, 0xfa, 0x44, 0x22, 0x1e, 0x76, 0x9c, 0x97, 0xb5, 0xcf, 0xfc, 0x6b, 0x0c, + 0xfb, 0xcd, 0x96, 0x05, 0x70, 0xd7, 0xaf, 0x87, 0xac, 0x23, 0xe7, 0x4a, 0xbd, 0xba, 0xaa, 0xf9, + 0x1f, 0xf7, 0xb5, 0xf1, 0xda, 0xd9, 0xbc, 0x1c, 0xd8, 0x47, 0xfe, 0xb5, 0x43, 0x7b, 0x03, 0xf7, + 0xbc, 0x56, 0xfb, 0x55, 0xbb, 0xb3, 0x96, 0x4d, 0x75, 0x60, 0xde, 0xc7, 0xd6, 0x7f, 0x6e, 0x96, + 0x03, 0xdb, 0xf0, 0xfa, 0x4f, 0x55, 0x02, 0x46, 0xa4, 0x84, 0xee, 0x6c, 0x6a, 0xa5, 0xb7, 0xac, + 0x6a, 0x92, 0x9f, 0xf4, 0xb1, 0xf6, 0x1d, 0x91, 0xe5, 0xc0, 0xd6, 0xa3, 0xbe, 0xe3, 0x93, 0x80, + 0x91, 0xd4, 0x13, 0xdf, 0xc1, 0x6a, 0xe4, 0xb7, 0x8c, 0xa3, 0xed, 0x8c, 0x7d, 0x77, 0x45, 0xc9, + 0x98, 0xf4, 0xdd, 0x23, 0xe7, 0x70, 0x2b, 0xe6, 0xde, 0xba, 0x25, 0x19, 0x6f, 0x1f, 0x07, 0xdd, + 0x9b, 0x60, 0x39, 0xb0, 0xa7, 0x71, 0xf7, 0x66, 0xf8, 0x16, 0x0e, 0x25, 0x58, 0x2a, 0x47, 0x6f, + 0x8b, 0x39, 0x91, 0x98, 0x1f, 0x6c, 0xc3, 0x7c, 0x75, 0x5a, 0x2f, 0x07, 0x36, 0x8a, 0xaf, 0xce, + 0xf0, 0x04, 0x0c, 0x57, 0x1e, 0x60, 0x87, 0x36, 0x27, 0xb8, 0x65, 0xb9, 0xb1, 0x7d, 0x7b, 0xfa, + 0x8e, 0x7e, 0xb9, 0x3d, 0x6e, 0x8f, 0x6f, 0x31, 0x86, 0xbd, 0x2c, 0x8f, 0xcd, 0x15, 0x4c, 0x6b, + 0xd3, 0x53, 0x2c, 0x30, 0x5a, 0xc0, 0x7e, 0x47, 0xeb, 0x7b, 0x8f, 0x6e, 0xce, 0x1f, 0xf4, 0xd1, + 0x36, 0x50, 0xa3, 0x72, 0x0a, 0xd8, 0x4d, 0x1e, 0x42, 0x30, 0x0a, 0x71, 0x16, 0x4a, 0xf5, 0x4e, + 0x6d, 0xf9, 0x6d, 0xfe, 0xa8, 0xc1, 0x9d, 0x8b, 0x94, 0xf3, 0xd5, 0x57, 0xab, 0x17, 0xdc, 0x5b, + 0x3f, 0x09, 0x31, 0x0b, 0x08, 0xfa, 0x0c, 0xe4, 0x55, 0x9c, 0x55, 0x54, 0x5b, 0xa7, 0x63, 0x45, + 0xa3, 0x12, 0xd0, 0xb3, 0xf6, 0xb9, 0x33, 0xfc, 0x57, 0xcf, 0x9d, 0x0a, 0xa6, 0x7a, 0xf4, 0x2c, + 0xac, 0x6f, 0x3e, 0x0a, 0xa8, 0x08, 0x73, 0xd7, 0xf2, 0x78, 0x3c, 0x6b, 0x21, 0xba, 0x9f, 0x9d, + 0xc7, 0x9c, 0x3b, 0x91, 0x7f, 0x4e, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x29, 0x21, 0xf9, 0x8a, + 0x3e, 0x0a, 0x00, 0x00, } diff --git a/proto/types/evidence.proto b/proto/types/evidence.proto index c8060a387..41fc503d2 100644 --- a/proto/types/evidence.proto +++ b/proto/types/evidence.proto @@ -47,6 +47,16 @@ message LunaticValidatorEvidence { string invalid_header_field = 3; } +message BeaconInactivityEvidence { + int64 evidence_height = 1; + google.protobuf.Timestamp evidence_time = 2 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + bytes defendant_address = 3; + bytes complainant_address = 4; + int64 aeon_start = 5; + bytes complainant_signature = 6; +} + message Evidence { oneof sum { DuplicateVoteEvidence duplicate_vote_evidence = 1; @@ -56,6 +66,8 @@ message Evidence { MockEvidence mock_evidence = 5; MockRandomEvidence mock_random_evidence = 6; + + BeaconInactivityEvidence beacon_inactivity_evidence = 7; } } diff --git a/types/evidence.go b/types/evidence.go index 95bda987e..ecea28c69 100644 --- a/types/evidence.go +++ b/types/evidence.go @@ -67,6 +67,8 @@ type Evidence interface { ValidateBasic() error String() string + + SignBytes(chainID string) []byte // for signing: evidence as bytes with chainID appended } func EvidenceToProto(evidence Evidence) (*tmproto.Evidence, error) { @@ -124,6 +126,24 @@ func EvidenceToProto(evidence Evidence) (*tmproto.Evidence, error) { }, } return tp, nil + case *BeaconInactivityEvidence: + if err := evi.ValidateBasic(); err != nil { + return nil, err + } + + tp := &tmproto.Evidence{ + Sum: &tmproto.Evidence_BeaconInactivityEvidence{ + BeaconInactivityEvidence: &tmproto.BeaconInactivityEvidence{ + EvidenceHeight: evi.Height(), + EvidenceTime: evi.Time(), + DefendantAddress: evi.DefendantAddress, + ComplainantAddress: evi.ComplainantAddress, + AeonStart: evi.AeonStart, + ComplainantSignature: evi.ComplainantSignature, + }, + }, + } + return tp, nil default: return nil, fmt.Errorf("toproto: evidence is not recognized: %T", evi) } @@ -176,6 +196,16 @@ func EvidenceFromProto(evidence *tmproto.Evidence) (Evidence, error) { randBytes: evi.MockRandomEvidence.RandBytes, } return mre, mre.ValidateBasic() + case *tmproto.Evidence_BeaconInactivityEvidence: + bie := BeaconInactivityEvidence{ + CreationHeight: evi.BeaconInactivityEvidence.GetEvidenceHeight(), + CreationTime: evi.BeaconInactivityEvidence.GetEvidenceTime(), + DefendantAddress: evi.BeaconInactivityEvidence.GetDefendantAddress(), + ComplainantAddress: evi.BeaconInactivityEvidence.GetComplainantAddress(), + AeonStart: evi.BeaconInactivityEvidence.GetAeonStart(), + ComplainantSignature: evi.BeaconInactivityEvidence.GetComplainantSignature(), + } + return &bie, bie.ValidateBasic() default: return nil, errors.New("evidence is not recognized") } @@ -358,6 +388,15 @@ func (dve *DuplicateVoteEvidence) ValidateBasic() error { return nil } +// Returns evidence as bytes with chainID appended +func (dve *DuplicateVoteEvidence) SignBytes(chainID string) []byte { + bz, err := cdc.MarshalBinaryLengthPrefixed(dve) + if err != nil { + panic(err) + } + return append([]byte(chainID), bz...) +} + //----------------------------------------------------------------- // UNSTABLE @@ -420,6 +459,118 @@ 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) } +func (e MockEvidence) SignBytes(chainID string) []byte { + bz, err := cdc.MarshalBinaryLengthPrefixed(e) + if err != nil { + panic(err) + } + return append([]byte(chainID), bz...) +} + +//------------------------------------------- + +// BeaconInactivityEvidence contains evidence a validator was did not +type BeaconInactivityEvidence struct { + CreationHeight int64 // Height evidence was created + CreationTime time.Time // Time evidence was created + DefendantAddress []byte // Address of validator accused of inactivity + ComplainantAddress []byte // Address of validator submitting complaint complaint + AeonStart int64 + ComplainantSignature []byte +} + +var _ Evidence = &BeaconInactivityEvidence{} + +// NewBeaconInactivityEvidence creates BeaconInactivityEvidence +func NewBeaconInactivityEvidence(height int64, defAddress []byte, comAddress []byte, aeon int64) *BeaconInactivityEvidence { + return &BeaconInactivityEvidence{ + CreationHeight: height, + CreationTime: time.Now(), + DefendantAddress: defAddress, + ComplainantAddress: comAddress, + AeonStart: aeon, + } +} + +// String returns a string representation of the evidence. +func (bie *BeaconInactivityEvidence) String() string { + return fmt.Sprintf("DefendantPubKey: %s, ComplainantPubKey: %s, Aeon: %v", bie.DefendantAddress, + bie.ComplainantAddress, bie.AeonStart) + +} + +// Height returns aeon start +func (bie *BeaconInactivityEvidence) Height() int64 { + return bie.CreationHeight +} + +// Time return +func (bie *BeaconInactivityEvidence) Time() time.Time { + return bie.CreationTime +} + +// Address returns the address of the validator. +func (bie *BeaconInactivityEvidence) Address() []byte { + return bie.ComplainantAddress +} + +// Bytes returns the evidence as byte slice +func (bie *BeaconInactivityEvidence) Bytes() []byte { + return cdcEncode(bie) +} + +// Hash returns the hash of the evidence. +func (bie *BeaconInactivityEvidence) Hash() []byte { + return tmhash.Sum(cdcEncode(bie)) +} + +// Verify returns the signature attached to the evidence matches the complainant address +func (bie *BeaconInactivityEvidence) Verify(chainID string, complainantPubKey crypto.PubKey) error { + if !complainantPubKey.VerifyBytes(bie.SignBytes(chainID), bie.ComplainantSignature) { + return fmt.Errorf("ComplainantSignature invalid") + } + + return nil +} + +// For signing with private key +func (bie BeaconInactivityEvidence) SignBytes(chainID string) []byte { + bie.ComplainantSignature = nil + bz, err := cdc.MarshalBinaryLengthPrefixed(bie) + if err != nil { + panic(err) + } + return append([]byte(chainID), bz...) +} + +// Equal checks if two pieces of evidence are equal. +func (bie *BeaconInactivityEvidence) Equal(ev Evidence) bool { + if _, ok := ev.(*BeaconInactivityEvidence); !ok { + return false + } + + // just check their hashes + bieHash := tmhash.Sum(cdcEncode(bie)) + evHash := tmhash.Sum(cdcEncode(ev)) + return bytes.Equal(bieHash, evHash) +} + +// ValidateBasic performs basic validation. +func (bie *BeaconInactivityEvidence) ValidateBasic() error { + if len(bie.ComplainantAddress) == 0 { + return errors.New("empty ComplainantAddress") + } + if len(bie.DefendantAddress) == 0 { + return errors.New("empty DefendantAddress") + } + if bie.AeonStart <= 0 { + return errors.New("invalid aeon start") + } + if len(bie.ComplainantSignature) == 0 { + return errors.New("empty complainant signature") + } + return nil +} //------------------------------------------- diff --git a/types/params.go b/types/params.go index 45b5aa57c..4d5147acd 100644 --- a/types/params.go +++ b/types/params.go @@ -63,6 +63,10 @@ type ValidatorParams struct { // EntropyParams determine configuration of DKG and entropy generation type EntropyParams struct { AeonLength int64 `json:"aeon_length"` + + // DRB slashing parameters + InactivityWindowSize int64 `json:"inactivity_window_size"` + RequiredActivityPercentage int64 `json:"required_activity_percentage"` } // DefaultConsensusParams returns a default ConsensusParams. @@ -101,7 +105,9 @@ func DefaultValidatorParams() ValidatorParams { // DefaultEntropyParams returns a default EntropyParams. func DefaultEntropyParams() EntropyParams { return EntropyParams{ - AeonLength: 100, + AeonLength: 100, + InactivityWindowSize: 50, + RequiredActivityPercentage: 50, } } @@ -162,6 +168,12 @@ func (params *ConsensusParams) Validate() error { if params.Entropy.AeonLength <= 0 { return errors.Errorf("entropyParams.AeonLength must be greater than 0. Got %v", params.Entropy.AeonLength) } + if params.Entropy.InactivityWindowSize <= 0 { + return errors.Errorf("entropyParams.InactivityWindowSize must be greater than 0. Got %v", params.Entropy.InactivityWindowSize) + } + if params.Entropy.RequiredActivityPercentage < 0 { + return errors.Errorf("entropyParams.RequiredActivityFraction can not be negative. Got %v", params.Entropy.RequiredActivityPercentage) + } return nil } @@ -215,6 +227,8 @@ func (params ConsensusParams) Update(params2 *abci.ConsensusParams) ConsensusPar } if params2.Entropy != nil { res.Entropy.AeonLength = params2.Entropy.AeonLength + res.Entropy.InactivityWindowSize = params2.Entropy.InactivityWindowSize + res.Entropy.RequiredActivityPercentage = params2.Entropy.RequiredActivityPercentage } return res } diff --git a/types/params_test.go b/types/params_test.go index e6e59297f..b29064485 100644 --- a/types/params_test.go +++ b/types/params_test.go @@ -70,7 +70,8 @@ func makeParams( PubKeyTypes: pubkeyTypes, }, Entropy: EntropyParams{ - AeonLength: aeonLength, + AeonLength: aeonLength, + InactivityWindowSize: 1, }, } } @@ -130,7 +131,8 @@ func TestConsensusParamsUpdate(t *testing.T) { PubKeyTypes: valSecp256k1, }, Entropy: &abci.EntropyParams{ - AeonLength: 120, + AeonLength: 120, + InactivityWindowSize: 1, }, }, makeParams(100, 200, 10, 300, valSecp256k1, 120), diff --git a/types/priv_validator.go b/types/priv_validator.go index e3c3bef38..66babfc8d 100644 --- a/types/priv_validator.go +++ b/types/priv_validator.go @@ -18,6 +18,7 @@ type PrivValidator interface { SignProposal(chainID string, proposal *Proposal) error SignEntropy(chainID string, share *EntropyShare) error SignDKGMessage(chainID string, msg *DKGMessage) error + SignEvidence(chainID string, msg Evidence) ([]byte, error) } //---------------------------------------- @@ -127,6 +128,15 @@ func (pv MockPV) SignDKGMessage(chainID string, msg *DKGMessage) error { return nil } +func (pv MockPV) SignEvidence(chainID string, msg Evidence) ([]byte, error) { + signBytes := msg.SignBytes(chainID) + sig, err := pv.PrivKey.Sign(signBytes) + if err != nil { + return nil, err + } + return sig, nil +} + // String returns a string representation of the MockPV. func (pv MockPV) String() string { mpv, _ := pv.GetPubKey() // mockPV will never return an error, ignored here @@ -165,6 +175,11 @@ func (pv *ErroringMockPV) SignDKGMessage(chainID string, msg *DKGMessage) error return ErroringMockPVErr } +// Implements PrivValidator +func (pv *ErroringMockPV) SignEvidence(chainID string, msg Evidence) ([]byte, error) { + return nil, ErroringMockPVErr +} + // NewErroringMockPV returns a MockPV that fails on each signing request. Again, for testing only. func NewErroringMockPV() *ErroringMockPV { diff --git a/types/protobuf.go b/types/protobuf.go index f1ed96a50..b9a88717b 100644 --- a/types/protobuf.go +++ b/types/protobuf.go @@ -156,7 +156,9 @@ func (tm2pb) ConsensusParams(params *ConsensusParams) *abci.ConsensusParams { PubKeyTypes: params.Validator.PubKeyTypes, }, Entropy: &abci.EntropyParams{ - AeonLength: params.Entropy.AeonLength, + AeonLength: params.Entropy.AeonLength, + InactivityWindowSize: params.Entropy.InactivityWindowSize, + RequiredActivityPercentage: params.Entropy.RequiredActivityPercentage, }, } } From 6a67020c7141fd75553b389ebfb98a09eeb9214f Mon Sep 17 00:00:00 2001 From: jinmannwong Date: Thu, 1 Oct 2020 09:47:51 +0100 Subject: [PATCH 2/7] Add comments --- types/params.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/params.go b/types/params.go index 4d5147acd..11ab66342 100644 --- a/types/params.go +++ b/types/params.go @@ -106,8 +106,8 @@ func DefaultValidatorParams() ValidatorParams { func DefaultEntropyParams() EntropyParams { return EntropyParams{ AeonLength: 100, - InactivityWindowSize: 50, - RequiredActivityPercentage: 50, + InactivityWindowSize: 50, // No. of blocks in which we track drb signature shares obtained + RequiredActivityPercentage: 50, // Minimum % of signature shares expected within window } } From 5e382e49641b427dac70081f12a10996257d7c50 Mon Sep 17 00:00:00 2001 From: jinmannwong Date: Thu, 1 Oct 2020 15:48:27 +0100 Subject: [PATCH 3/7] Track signature shares in entropy gen --- beacon/common_test.go | 3 +- beacon/entropy_generator.go | 103 ++++++++++++++++++++++++++++++- beacon/entropy_generator_test.go | 3 +- node/node.go | 7 ++- 4 files changed, 110 insertions(+), 6 deletions(-) diff --git a/beacon/common_test.go b/beacon/common_test.go index 026c56fe4..98cb86bce 100644 --- a/beacon/common_test.go +++ b/beacon/common_test.go @@ -129,9 +129,10 @@ func randBeaconAndConsensusNet(nValidators int, testName string, withConsensus b pubKey, _ := privVals[i].GetPubKey() index, _ := state.Validators.GetByAddress(pubKey.Address()) blockStores[i] = store.NewBlockStore(stateDB) + evpool := sm.MockEvidencePool{} aeonDetails, _ := newAeonDetails(privVals[i], 1, 1, state.Validators, aeonExecUnits[index], 1, 9) - entropyGenerators[i] = NewEntropyGenerator(&thisConfig.BaseConfig, thisConfig.Beacon, 0) + entropyGenerators[i] = NewEntropyGenerator(&thisConfig.BaseConfig, thisConfig.Beacon, 0, evpool, stateDB) entropyGenerators[i].SetLogger(logger) entropyGenerators[i].SetLastComputedEntropy(0, state.LastComputedEntropy) entropyGenerators[i].SetNextAeonDetails(aeonDetails) diff --git a/beacon/entropy_generator.go b/beacon/entropy_generator.go index 6dc5975aa..f0fa4c98d 100644 --- a/beacon/entropy_generator.go +++ b/beacon/entropy_generator.go @@ -1,6 +1,7 @@ package beacon import ( + "container/list" "fmt" "runtime/debug" "sync" @@ -25,6 +26,11 @@ const ( maxNextAeons = 5 ) +// interface to the evidence pool +type evidencePool interface { + AddEvidence(types.Evidence) error +} + // EntropyGenerator holds DKG keys for computing entropy and computes entropy shares // and entropy for dispatching along channel. Entropy generation is blocked by arrival of keys for the // keys for the current block height from the dkg - including for trivial entropy periods, for which the @@ -58,6 +64,11 @@ type EntropyGenerator struct { metrics *Metrics creatingEntropyAtHeight int64 creatingEntropyAtTimeMs time.Time + + // add evidence to the pool when it's detected + stateDB dbm.DB + evpool evidencePool + activityTracking map[uint]*list.List // Record of validators } func (entropyGenerator *EntropyGenerator) AttachMetrics(metrics *Metrics) { @@ -70,7 +81,8 @@ func (entropyGenerator *EntropyGenerator) AttachMetrics(metrics *Metrics) { } // NewEntropyGenerator creates new entropy generator with validator information -func NewEntropyGenerator(bConfig *cfg.BaseConfig, beaconConfig *cfg.BeaconConfig, blockHeight int64) *EntropyGenerator { +func NewEntropyGenerator(bConfig *cfg.BaseConfig, beaconConfig *cfg.BeaconConfig, blockHeight int64, + evpool evidencePool, stateDB dbm.DB) *EntropyGenerator { if bConfig == nil || beaconConfig == nil { panic(fmt.Errorf("NewEntropyGenerator: baseConfig/beaconConfig can not be nil")) } @@ -84,6 +96,8 @@ func NewEntropyGenerator(bConfig *cfg.BaseConfig, beaconConfig *cfg.BeaconConfig evsw: tmevents.NewEventSwitch(), quit: make(chan struct{}), metrics: NopMetrics(), + evpool: evpool, + stateDB: stateDB, } es.BaseService = *service.NewBaseService(nil, "EntropyGenerator", es) @@ -222,6 +236,7 @@ func (entropyGenerator *EntropyGenerator) SetNextAeonDetails(aeon *aeonDetails) // If over max number of keys pop of the oldest one if len(entropyGenerator.nextAeons) > maxNextAeons { + entropyGenerator.nextAeons[0] = nil entropyGenerator.nextAeons = entropyGenerator.nextAeons[1:len(entropyGenerator.nextAeons)] } entropyGenerator.nextAeons = append(entropyGenerator.nextAeons, aeon) @@ -245,6 +260,7 @@ func (entropyGenerator *EntropyGenerator) trimNextAeons() { if len(entropyGenerator.nextAeons) == 1 { entropyGenerator.nextAeons = make([]*aeonDetails, 0) } else { + entropyGenerator.nextAeons[0] = nil entropyGenerator.nextAeons = entropyGenerator.nextAeons[1:len(entropyGenerator.nextAeons)] } } else { @@ -302,6 +318,8 @@ func (entropyGenerator *EntropyGenerator) changeKeys() (didChangeKeys bool) { entropyGenerator.Logger.Info("changeKeys: Loaded new keys", "blockHeight", entropyGenerator.lastBlockHeight, "start", entropyGenerator.aeon.Start) didChangeKeys = true + + entropyGenerator.resetActivityTracking() } // If lastComputedEntropyHeight is not set then set it is equal to group public key (should @@ -552,6 +570,9 @@ OUTER_LOOP: entropyGenerator.metrics.EntropyGenerating.Set(0.0) } + // Check tracking information + entropyGenerator.updateActivityTracking(entropyToSend) + // Clean out old entropy shares and computed entropy entropyGenerator.flushOldEntropy() } @@ -634,6 +655,86 @@ func (entropyGenerator *EntropyGenerator) flushOldEntropy() { } } +// Resets the activity tracking when aeon keys have changed over. Only track signature shares if in qual, +// but do not track own activity +func (entropyGenerator *EntropyGenerator) resetActivityTracking() { + if entropyGenerator.aeon.aeonExecUnit == nil || !entropyGenerator.aeon.aeonExecUnit.CanSign() { + return + } + + entropyGenerator.activityTracking = make(map[uint]*list.List) + ownIndex := -1 + pubKey, err := entropyGenerator.aeon.privValidator.GetPubKey() + if err == nil { + ownIndex, _ = entropyGenerator.aeon.validators.GetByAddress(pubKey.Address()) + } + for i := 0; i < entropyGenerator.aeon.validators.Size(); i++ { + valIndex := uint(i) + if i != ownIndex && entropyGenerator.aeon.aeonExecUnit.InQual(valIndex) { + entropyGenerator.activityTracking[valIndex] = list.New() + } + } +} + +// Updates tracking information with signature shares from most recent height. If +func (entropyGenerator *EntropyGenerator) updateActivityTracking(entropy *types.ChannelEntropy) { + if entropyGenerator.aeon.aeonExecUnit == nil || !entropyGenerator.aeon.aeonExecUnit.CanSign() { + return + } + + newParams, err := sm.LoadConsensusParams(entropyGenerator.stateDB, entropy.Height) + if err != nil { + entropyGenerator.Logger.Error("updateActivityTracking: error fetching consensus params", "height", entropy.Height, + "err", err) + return + } + + // If entropy is not enabled then should have received no signature shares from anyone this + // height and append true to all validators activity tracking + for valIndex, activity := range entropyGenerator.activityTracking { + if _, haveShare := entropyGenerator.entropyShares[entropy.Height][valIndex]; !entropy.Enabled || haveShare { + activity.PushBack(1) + } else { + activity.PushBack(0) + } + + // Return if we have not got records for InactivityWindowSize blocks + if activity.Len() < int(newParams.Entropy.InactivityWindowSize) { + continue + } + + // Trim to sliding window size if too large by removing oldest elements + for activity.Len() > int(newParams.Entropy.InactivityWindowSize) { + activity.Remove(activity.Front()) + } + + // Measure inactivity + sigShareCount := 0 + for e := activity.Front(); e != nil; e = e.Next() { + sigShareCount += e.Value.(int) + } + + if int64(sigShareCount) < (newParams.Entropy.RequiredActivityPercentage/100.0)*newParams.Entropy.InactivityWindowSize { + // Create evidence and submit to evpool + defAddress, _ := entropyGenerator.aeon.validators.GetByIndex(int(valIndex)) + pubKey, err := entropyGenerator.aeon.privValidator.GetPubKey() + if err != nil { + entropyGenerator.Logger.Error("updateActivityTracking: error getting pub key", "err", err) + continue + } + evidence := types.NewBeaconInactivityEvidence(entropy.Height, defAddress, pubKey.Address(), + entropyGenerator.aeon.Start) + sig, err := entropyGenerator.aeon.privValidator.SignEvidence(entropyGenerator.baseConfig.ChainID(), evidence) + if err != nil { + entropyGenerator.Logger.Error("updateActivityTracking: error signing evidence", "err", err) + continue + } + evidence.ComplainantSignature = sig + entropyGenerator.evpool.AddEvidence(evidence) + } + } +} + func (entropyGenerator *EntropyGenerator) isSigningEntropy() bool { entropyGenerator.mtx.RLock() defer entropyGenerator.mtx.RUnlock() diff --git a/beacon/entropy_generator_test.go b/beacon/entropy_generator_test.go index 2d6492a3c..d347164a9 100644 --- a/beacon/entropy_generator_test.go +++ b/beacon/entropy_generator_test.go @@ -338,5 +338,6 @@ func testEntropyGen(validators *types.ValidatorSet, privVal types.PrivValidator, func testEntropyGenerator() *EntropyGenerator { config := cfg.ResetTestRoot("entropy_generator_test") - return NewEntropyGenerator(&config.BaseConfig, config.Beacon, 0) + stateDB := dbm.NewMemDB() // each state needs its own db + return NewEntropyGenerator(&config.BaseConfig, config.Beacon, 0, sm.MockEvidencePool{}, stateDB) } diff --git a/node/node.go b/node/node.go index 4123847e7..841f18463 100644 --- a/node/node.go +++ b/node/node.go @@ -571,10 +571,11 @@ func createBeaconReactor( beaconLogger log.Logger, fastSync bool, blockStore sm.BlockStore, dkgRunner *beacon.DKGRunner, - db dbm.DB) (chan types.ChannelEntropy, *beacon.EntropyGenerator, *beacon.Reactor, error) { + db dbm.DB, + evpool *evidence.Pool) (chan types.ChannelEntropy, *beacon.EntropyGenerator, *beacon.Reactor, error) { beacon.InitialiseMcl() - entropyGenerator := beacon.NewEntropyGenerator(&config.BaseConfig, config.Beacon, state.LastBlockHeight) + entropyGenerator := beacon.NewEntropyGenerator(&config.BaseConfig, config.Beacon, state.LastBlockHeight, evpool, db) entropyChannel := make(chan types.ChannelEntropy, config.Beacon.EntropyChannelCapacity) entropyGenerator.SetLogger(beaconLogger) entropyGenerator.SetEntropyChannel(entropyChannel) @@ -763,7 +764,7 @@ func NewNode(config *cfg.Config, // Make BeaconReactor beaconLogger := logger.With("module", "beacon") entropyChannel, entropyGenerator, beaconReactor, err := createBeaconReactor(config, state, privValidator, - beaconLogger, fastSync, blockStore, dkgRunner, stateDB) + beaconLogger, fastSync, blockStore, dkgRunner, stateDB, evidencePool) if err != nil { return nil, errors.Wrap(err, "could not load aeon keys from file") From 85128855e692e2a2814634bd9c05c316d2f1bae5 Mon Sep 17 00:00:00 2001 From: jinmannwong Date: Fri, 2 Oct 2020 09:49:09 +0100 Subject: [PATCH 4/7] Add tests --- beacon/common_test.go | 9 ++- beacon/entropy_generator.go | 51 +++++++++---- beacon/entropy_generator_test.go | 127 +++++++++++++++++++++++++++---- 3 files changed, 154 insertions(+), 33 deletions(-) diff --git a/beacon/common_test.go b/beacon/common_test.go index 98cb86bce..c75c4846d 100644 --- a/beacon/common_test.go +++ b/beacon/common_test.go @@ -172,9 +172,10 @@ func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.G sort.Sort(types.PrivValidatorsByAddress(privValidators)) return &types.GenesisDoc{ - GenesisTime: tmtime.Now(), - ChainID: config.ChainID(), - Validators: validators, - Entropy: "Fetch.ai Test Genesis Entropy", + GenesisTime: tmtime.Now(), + ChainID: config.ChainID(), + ConsensusParams: types.DefaultConsensusParams(), + Validators: validators, + Entropy: "Fetch.ai Test Genesis Entropy", }, privValidators } diff --git a/beacon/entropy_generator.go b/beacon/entropy_generator.go index f0fa4c98d..86fa02705 100644 --- a/beacon/entropy_generator.go +++ b/beacon/entropy_generator.go @@ -11,6 +11,7 @@ import ( dbm "github.com/tendermint/tm-db" cfg "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/tmhash" tmevents "github.com/tendermint/tendermint/libs/events" "github.com/tendermint/tendermint/libs/log" @@ -29,6 +30,7 @@ const ( // interface to the evidence pool type evidencePool interface { AddEvidence(types.Evidence) error + PendingEvidence(int64) []types.Evidence } // EntropyGenerator holds DKG keys for computing entropy and computes entropy shares @@ -66,9 +68,10 @@ type EntropyGenerator struct { creatingEntropyAtTimeMs time.Time // add evidence to the pool when it's detected - stateDB dbm.DB - evpool evidencePool - activityTracking map[uint]*list.List // Record of validators + stateDB dbm.DB + evpool evidencePool + aeonEntropyParams *types.EntropyParams // Inactivity params for this aeon + activityTracking map[uint]*list.List // Record of validators } func (entropyGenerator *EntropyGenerator) AttachMetrics(metrics *Metrics) { @@ -674,24 +677,34 @@ func (entropyGenerator *EntropyGenerator) resetActivityTracking() { entropyGenerator.activityTracking[valIndex] = list.New() } } + + // Fetch parameters at aeon dkg validator height so that they remain constant during the entire aeon + paramHeight := entropyGenerator.aeon.validatorHeight + newParams, err := sm.LoadConsensusParams(entropyGenerator.stateDB, paramHeight) + if err != nil { + entropyGenerator.Logger.Error("resetActivityTracking: error fetching consensus params", "height", paramHeight, + "err", err) + return + } + entropyGenerator.aeonEntropyParams = &newParams.Entropy } -// Updates tracking information with signature shares from most recent height. If +// Updates tracking information with signature shares from most recent height. Calculates signature shares +// received in the last window and creates evidence if not enough were received func (entropyGenerator *EntropyGenerator) updateActivityTracking(entropy *types.ChannelEntropy) { if entropyGenerator.aeon.aeonExecUnit == nil || !entropyGenerator.aeon.aeonExecUnit.CanSign() { return } - - newParams, err := sm.LoadConsensusParams(entropyGenerator.stateDB, entropy.Height) - if err != nil { - entropyGenerator.Logger.Error("updateActivityTracking: error fetching consensus params", "height", entropy.Height, - "err", err) + if entropyGenerator.aeonEntropyParams == nil { return } - // If entropy is not enabled then should have received no signature shares from anyone this - // height and append true to all validators activity tracking + entropyGenerator.mtx.Lock() + defer entropyGenerator.mtx.Unlock() + for valIndex, activity := range entropyGenerator.activityTracking { + // If entropy is not enabled then should have received no signature shares from anyone this + // height and append true to all validators activity tracking if _, haveShare := entropyGenerator.entropyShares[entropy.Height][valIndex]; !entropy.Enabled || haveShare { activity.PushBack(1) } else { @@ -699,12 +712,12 @@ func (entropyGenerator *EntropyGenerator) updateActivityTracking(entropy *types. } // Return if we have not got records for InactivityWindowSize blocks - if activity.Len() < int(newParams.Entropy.InactivityWindowSize) { + if activity.Len() < int(entropyGenerator.aeonEntropyParams.InactivityWindowSize) { continue } // Trim to sliding window size if too large by removing oldest elements - for activity.Len() > int(newParams.Entropy.InactivityWindowSize) { + for activity.Len() > int(entropyGenerator.aeonEntropyParams.InactivityWindowSize) { activity.Remove(activity.Front()) } @@ -714,7 +727,8 @@ func (entropyGenerator *EntropyGenerator) updateActivityTracking(entropy *types. sigShareCount += e.Value.(int) } - if int64(sigShareCount) < (newParams.Entropy.RequiredActivityPercentage/100.0)*newParams.Entropy.InactivityWindowSize { + threshold := float64(entropyGenerator.aeonEntropyParams.RequiredActivityPercentage*entropyGenerator.aeonEntropyParams.InactivityWindowSize) * 0.01 + if sigShareCount < int(threshold) { // Create evidence and submit to evpool defAddress, _ := entropyGenerator.aeon.validators.GetByIndex(int(valIndex)) pubKey, err := entropyGenerator.aeon.privValidator.GetPubKey() @@ -730,7 +744,16 @@ func (entropyGenerator *EntropyGenerator) updateActivityTracking(entropy *types. continue } evidence.ComplainantSignature = sig + + entropyGenerator.Logger.Debug("Add evidence for inactivity", "height", entropy.Height, "validator", crypto.AddressHash(defAddress)) entropyGenerator.evpool.AddEvidence(evidence) + + // Paid price for not contributing in this window so now convert the entire window to 1s in order + // for validator not be slashed again for this window + entropyGenerator.activityTracking[valIndex] = list.New() + for i := int64(0); i < entropyGenerator.aeonEntropyParams.InactivityWindowSize; i++ { + entropyGenerator.activityTracking[valIndex].PushBack(1) + } } } } diff --git a/beacon/entropy_generator_test.go b/beacon/entropy_generator_test.go index d347164a9..0a0b7bf46 100644 --- a/beacon/entropy_generator_test.go +++ b/beacon/entropy_generator_test.go @@ -16,6 +16,26 @@ import ( "github.com/tendermint/tendermint/types" ) +// Mock evidence pool for inactivity tracking +type mockEvidencePool struct { + receivedEvidence []types.Evidence +} + +func newMockEvidencePool() *mockEvidencePool { + return &mockEvidencePool{ + receivedEvidence: make([]types.Evidence, 0), + } +} + +func (mep *mockEvidencePool) AddEvidence(ev types.Evidence) error { + mep.receivedEvidence = append(mep.receivedEvidence, ev) + return nil +} + +func (mep *mockEvidencePool) PendingEvidence(int64) []types.Evidence { + return mep.receivedEvidence +} + func TestEntropyGeneratorStart(t *testing.T) { testCases := []struct { testName string @@ -76,7 +96,7 @@ func TestEntropyGeneratorNonValidator(t *testing.T) { nValidators := 4 state, privVals := groupTestSetup(nValidators) - newGen := testEntropyGen(state.Validators, nil, -1) + newGen := testEntropyGen(state, nil, -1) // Does not panic if can not sign assert.NotPanics(t, func() { @@ -90,7 +110,7 @@ func TestEntropyGeneratorNonValidator(t *testing.T) { privVal := privVals[i] pubKey, _ := privVal.GetPubKey() index, _ := state.Validators.GetByAddress(pubKey.Address()) - tempGen := testEntropyGen(state.Validators, privVal, index) + tempGen := testEntropyGen(state, privVal, index) tempGen.sign() share := tempGen.entropyShares[1][uint(index)] @@ -106,7 +126,7 @@ func TestEntropyGeneratorSign(t *testing.T) { pubKey, _ := privVals[0].GetPubKey() index, _ := state.Validators.GetByAddress(pubKey.Address()) - newGen := testEntropyGen(state.Validators, privVals[0], index) + newGen := testEntropyGen(state, privVals[0], index) newGen.SetLastComputedEntropy(2, []byte("Test Entropy")) newGen.setLastBlockHeight(2) @@ -126,7 +146,7 @@ func TestEntropyGeneratorApplyShare(t *testing.T) { state, privVals := groupTestSetup(nValidators) // Set up non-validator - newGen := testEntropyGen(state.Validators, nil, -1) + newGen := testEntropyGen(state, nil, -1) newGen.SetLastComputedEntropy(1, []byte("Test Entropy")) newGen.setLastBlockHeight(1) @@ -150,7 +170,7 @@ func TestEntropyGeneratorApplyShare(t *testing.T) { t.Run("applyShare old height", func(t *testing.T) { pubKey, _ := privVals[0].GetPubKey() index, _ := state.Validators.GetByAddress(pubKey.Address()) - otherGen := testEntropyGen(state.Validators, privVals[0], index) + otherGen := testEntropyGen(state, privVals[0], index) otherGen.SetLastComputedEntropy(1, []byte("Test Entropy")) otherGen.setLastBlockHeight(1) @@ -163,7 +183,7 @@ func TestEntropyGeneratorApplyShare(t *testing.T) { t.Run("applyShare height far ahead", func(t *testing.T) { pubKey, _ := privVals[0].GetPubKey() index, _ := state.Validators.GetByAddress(pubKey.Address()) - otherGen := testEntropyGen(state.Validators, privVals[0], index) + otherGen := testEntropyGen(state, privVals[0], index) otherGen.SetLastComputedEntropy(3, []byte("Test Entropy")) otherGen.setLastBlockHeight(3) @@ -195,7 +215,7 @@ func TestEntropyGeneratorApplyShare(t *testing.T) { t.Run("applyShare invalid validator signature", func(t *testing.T) { pubKey, _ := privVals[0].GetPubKey() index, _ := state.Validators.GetByAddress(pubKey.Address()) - otherGen := testEntropyGen(state.Validators, privVals[0], index) + otherGen := testEntropyGen(state, privVals[0], index) otherGen.SetLastComputedEntropy(1, []byte("Test Entropy")) otherGen.setLastBlockHeight(1) @@ -210,7 +230,7 @@ func TestEntropyGeneratorApplyShare(t *testing.T) { t.Run("applyShare correct", func(t *testing.T) { pubKey, _ := privVals[0].GetPubKey() index, _ := state.Validators.GetByAddress(pubKey.Address()) - otherGen := testEntropyGen(state.Validators, privVals[0], index) + otherGen := testEntropyGen(state, privVals[0], index) otherGen.SetLastComputedEntropy(1, []byte("Test Entropy")) otherGen.setLastBlockHeight(1) @@ -247,7 +267,7 @@ func TestEntropyGeneratorApplyComputedEntropy(t *testing.T) { state, privVals := groupTestSetup(nValidators) // Set up non-validator - newGen := testEntropyGen(state.Validators, nil, -1) + newGen := testEntropyGen(state, nil, -1) newGen.SetLastComputedEntropy(1, []byte("Test Entropy")) newGen.setLastBlockHeight(1) newGen.Start() @@ -263,7 +283,7 @@ func TestEntropyGeneratorApplyComputedEntropy(t *testing.T) { t.Run("applyEntropy invalid entropy", func(t *testing.T) { pubKey, _ := privVals[0].GetPubKey() index, _ := state.Validators.GetByAddress(pubKey.Address()) - otherGen := testEntropyGen(state.Validators, privVals[0], index) + otherGen := testEntropyGen(state, privVals[0], index) otherGen.SetLastComputedEntropy(1, []byte("Test Entropy")) otherGen.setLastBlockHeight(1) @@ -275,7 +295,7 @@ func TestEntropyGeneratorApplyComputedEntropy(t *testing.T) { t.Run("applyEntropy correct", func(t *testing.T) { pubKey, _ := privVals[0].GetPubKey() index, _ := state.Validators.GetByAddress(pubKey.Address()) - otherGen := testEntropyGen(state.Validators, privVals[0], index) + otherGen := testEntropyGen(state, privVals[0], index) otherGen.SetLastComputedEntropy(1, []byte("Test Entropy")) otherGen.setLastBlockHeight(1) otherGen.Start() @@ -283,7 +303,7 @@ func TestEntropyGeneratorApplyComputedEntropy(t *testing.T) { for _, val := range privVals { pubKey, _ := val.GetPubKey() tempIndex, _ := state.Validators.GetByAddress(pubKey.Address()) - tempGen := testEntropyGen(state.Validators, val, tempIndex) + tempGen := testEntropyGen(state, val, tempIndex) tempGen.SetLastComputedEntropy(1, []byte("Test Entropy")) tempGen.setLastBlockHeight(1) @@ -314,6 +334,82 @@ func TestEntropyGeneratorChangeKeys(t *testing.T) { assert.Eventually(t, func() bool { return newGen.isSigningEntropy() }, time.Second, 100*time.Millisecond) } +func TestEntropyResetActivityTracking(t *testing.T) { + nValidators := 4 + state, privVals := groupTestSetup(nValidators) + + testCases := []struct { + testName string + privVal types.PrivValidator + mapNil bool + activityTrackingSize int + }{ + {"Sentry", nil, true, 0}, + {"Validator", privVals[0], false, 3}, + } + for _, tc := range testCases { + t.Run(tc.testName, func(t *testing.T) { + index := -1 + if tc.privVal != nil { + pubKey, _ := tc.privVal.GetPubKey() + index, _ = state.Validators.GetByAddress(pubKey.Address()) + } + newGen := testEntropyGen(state, tc.privVal, index) + + assert.Equal(t, tc.mapNil, newGen.activityTracking == nil) + if !tc.mapNil { + assert.Equal(t, tc.activityTrackingSize, len(newGen.activityTracking)) + _, haveIndex := newGen.activityTracking[uint(index)] + assert.False(t, haveIndex) + assert.True(t, newGen.aeonEntropyParams != nil) + } + }) + } +} + +func TestEntropyActivityTracking(t *testing.T) { + nValidators := 4 + state, privVals := groupTestSetup(nValidators) + + // Set up validator + pubKey, _ := privVals[0].GetPubKey() + index, _ := state.Validators.GetByAddress(pubKey.Address()) + + testCases := []struct { + testName string + sharesReceived int64 + entropyHeight int64 + entropyEnabled bool + pendingEvidence int + }{ + {"Less than window size", 10, 10, true, 0}, + {"Slash all but one", 24, 50, false, 2}, + {"Slash everyone", 24, 50, true, 3}, + {"Does not double slash", 26, 51, true, 2}, + {"Slash new misbehaviour", 25, 51, true, 3}, + } + for _, tc := range testCases { + t.Run(tc.testName, func(t *testing.T) { + newGen := testEntropyGen(state, privVals[0], index) + + otherIndex := uint((index + 1) % nValidators) + for i := int64(0); i < tc.entropyHeight; i++ { + if i < tc.sharesReceived { + newGen.entropyShares[i+1] = make(map[uint]types.EntropyShare) + newGen.entropyShares[i+1][otherIndex] = types.EntropyShare{} + } + enabled := true + if i == tc.entropyHeight-1 { + enabled = tc.entropyEnabled + } + newGen.updateActivityTracking(types.NewChannelEntropy(i+1, types.BlockEntropy{}, enabled, nil)) + } + + assert.Equal(t, tc.pendingEvidence, len(newGen.evpool.PendingEvidence(0))) + }) + } +} + func groupTestSetup(nValidators int) (sm.State, []types.PrivValidator) { genDoc, privVals := randGenesisDoc(nValidators, false, 30) stateDB := dbm.NewMemDB() // each state needs its own db @@ -321,15 +417,16 @@ func groupTestSetup(nValidators int) (sm.State, []types.PrivValidator) { return state, privVals } -func testEntropyGen(validators *types.ValidatorSet, privVal types.PrivValidator, index int) *EntropyGenerator { +func testEntropyGen(state sm.State, privVal types.PrivValidator, index int) *EntropyGenerator { newGen := testEntropyGenerator() newGen.SetLogger(log.TestingLogger()) + sm.SaveState(newGen.stateDB, state) aeonExecUnit := testAeonFromFile("test_keys/non_validator.txt") if index >= 0 { aeonExecUnit = testAeonFromFile("test_keys/validator_" + strconv.Itoa(int(index)) + "_of_4.txt") } - aeonDetails, _ := newAeonDetails(privVal, 1, 1, validators, aeonExecUnit, 1, 50) + aeonDetails, _ := newAeonDetails(privVal, 1, 1, state.Validators, aeonExecUnit, 1, 50) newGen.SetNextAeonDetails(aeonDetails) newGen.SetLastComputedEntropy(0, []byte("Test Entropy")) newGen.changeKeys() @@ -339,5 +436,5 @@ func testEntropyGen(validators *types.ValidatorSet, privVal types.PrivValidator, func testEntropyGenerator() *EntropyGenerator { config := cfg.ResetTestRoot("entropy_generator_test") stateDB := dbm.NewMemDB() // each state needs its own db - return NewEntropyGenerator(&config.BaseConfig, config.Beacon, 0, sm.MockEvidencePool{}, stateDB) + return NewEntropyGenerator(&config.BaseConfig, config.Beacon, 0, newMockEvidencePool(), stateDB) } From 07511049f5962a12868d35a6f799fcc5aae28e81 Mon Sep 17 00:00:00 2001 From: jinmannwong Date: Fri, 2 Oct 2020 11:38:26 +0100 Subject: [PATCH 5/7] Review feedback --- beacon/entropy_generator.go | 13 +++++++++---- types/params.go | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/beacon/entropy_generator.go b/beacon/entropy_generator.go index 86fa02705..9b6c5a33d 100644 --- a/beacon/entropy_generator.go +++ b/beacon/entropy_generator.go @@ -727,8 +727,9 @@ func (entropyGenerator *EntropyGenerator) updateActivityTracking(entropy *types. sigShareCount += e.Value.(int) } - threshold := float64(entropyGenerator.aeonEntropyParams.RequiredActivityPercentage*entropyGenerator.aeonEntropyParams.InactivityWindowSize) * 0.01 - if sigShareCount < int(threshold) { + requiredFraction := float64(entropyGenerator.aeonEntropyParams.RequiredActivityPercentage) * 0.01 + threshold := int(requiredFraction * float64(entropyGenerator.aeonEntropyParams.InactivityWindowSize)) + if sigShareCount < threshold { // Create evidence and submit to evpool defAddress, _ := entropyGenerator.aeon.validators.GetByIndex(int(valIndex)) pubKey, err := entropyGenerator.aeon.privValidator.GetPubKey() @@ -745,8 +746,12 @@ func (entropyGenerator *EntropyGenerator) updateActivityTracking(entropy *types. } evidence.ComplainantSignature = sig - entropyGenerator.Logger.Debug("Add evidence for inactivity", "height", entropy.Height, "validator", crypto.AddressHash(defAddress)) - entropyGenerator.evpool.AddEvidence(evidence) + entropyGenerator.Logger.Info("Add evidence for inactivity", "height", entropy.Height, "validator", crypto.AddressHash(defAddress), + "shareCount", sigShareCount, "threshold", threshold, "windowSize", entropyGenerator.aeonEntropyParams.InactivityWindowSize) + err = entropyGenerator.evpool.AddEvidence(evidence) + if err != nil { + entropyGenerator.Logger.Error("updateActivityTracking: error adding evidence", "err", err) + } // Paid price for not contributing in this window so now convert the entire window to 1s in order // for validator not be slashed again for this window diff --git a/types/params.go b/types/params.go index 11ab66342..fc97bbccc 100644 --- a/types/params.go +++ b/types/params.go @@ -106,8 +106,8 @@ func DefaultValidatorParams() ValidatorParams { func DefaultEntropyParams() EntropyParams { return EntropyParams{ AeonLength: 100, - InactivityWindowSize: 50, // No. of blocks in which we track drb signature shares obtained - RequiredActivityPercentage: 50, // Minimum % of signature shares expected within window + InactivityWindowSize: 100, // No. of blocks in which we track drb signature shares obtained + RequiredActivityPercentage: 50, // Minimum % of signature shares expected within window } } From de04e186c851e3c2c053179bfeb9dc1313485c66 Mon Sep 17 00:00:00 2001 From: jinmannwong Date: Fri, 2 Oct 2020 12:06:05 +0100 Subject: [PATCH 6/7] Fix test --- beacon/common_test.go | 6 +++++- beacon/entropy_generator_test.go | 11 +++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/beacon/common_test.go b/beacon/common_test.go index c75c4846d..b82db26e6 100644 --- a/beacon/common_test.go +++ b/beacon/common_test.go @@ -171,10 +171,14 @@ func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.G } sort.Sort(types.PrivValidatorsByAddress(privValidators)) + // Make inactivity window smaller for tests + params := types.DefaultConsensusParams() + params.Entropy.InactivityWindowSize = 50 + return &types.GenesisDoc{ GenesisTime: tmtime.Now(), ChainID: config.ChainID(), - ConsensusParams: types.DefaultConsensusParams(), + ConsensusParams: params, Validators: validators, Entropy: "Fetch.ai Test Genesis Entropy", }, privValidators diff --git a/beacon/entropy_generator_test.go b/beacon/entropy_generator_test.go index 0a0b7bf46..97326e422 100644 --- a/beacon/entropy_generator_test.go +++ b/beacon/entropy_generator_test.go @@ -370,6 +370,9 @@ func TestEntropyResetActivityTracking(t *testing.T) { func TestEntropyActivityTracking(t *testing.T) { nValidators := 4 state, privVals := groupTestSetup(nValidators) + entropyParams := state.ConsensusParams.Entropy + windowSize := entropyParams.InactivityWindowSize + threshold := int64(float64(entropyParams.RequiredActivityPercentage*windowSize) * 0.01) // Set up validator pubKey, _ := privVals[0].GetPubKey() @@ -383,10 +386,10 @@ func TestEntropyActivityTracking(t *testing.T) { pendingEvidence int }{ {"Less than window size", 10, 10, true, 0}, - {"Slash all but one", 24, 50, false, 2}, - {"Slash everyone", 24, 50, true, 3}, - {"Does not double slash", 26, 51, true, 2}, - {"Slash new misbehaviour", 25, 51, true, 3}, + {"Slash all but one", threshold - 1, windowSize, false, 2}, + {"Slash everyone", threshold - 1, windowSize, true, 3}, + {"Does not double slash", threshold + 1, windowSize + 1, true, 2}, + {"Slash new misbehaviour", threshold, windowSize + 1, true, 3}, } for _, tc := range testCases { t.Run(tc.testName, func(t *testing.T) { From e14479964e4528d9a0811f26659d3e08db89981c Mon Sep 17 00:00:00 2001 From: jinmannwong Date: Mon, 5 Oct 2020 09:23:37 +0100 Subject: [PATCH 7/7] Deployment fixes --- beacon/common_test.go | 2 +- beacon/entropy_generator.go | 10 +++++---- beacon/entropy_generator_test.go | 22 ++++++++++++------- evidence/pool.go | 2 +- node/node.go | 2 +- state/execution.go | 2 +- state/validation.go | 4 ++-- types/evidence.go | 36 +++++++++++++++++++++++--------- types/protobuf.go | 7 +++++-- 9 files changed, 57 insertions(+), 30 deletions(-) diff --git a/beacon/common_test.go b/beacon/common_test.go index b82db26e6..8fc271b7c 100644 --- a/beacon/common_test.go +++ b/beacon/common_test.go @@ -132,7 +132,7 @@ func randBeaconAndConsensusNet(nValidators int, testName string, withConsensus b evpool := sm.MockEvidencePool{} aeonDetails, _ := newAeonDetails(privVals[i], 1, 1, state.Validators, aeonExecUnits[index], 1, 9) - entropyGenerators[i] = NewEntropyGenerator(&thisConfig.BaseConfig, thisConfig.Beacon, 0, evpool, stateDB) + entropyGenerators[i] = NewEntropyGenerator(state.ChainID, &thisConfig.BaseConfig, thisConfig.Beacon, 0, evpool, stateDB) entropyGenerators[i].SetLogger(logger) entropyGenerators[i].SetLastComputedEntropy(0, state.LastComputedEntropy) entropyGenerators[i].SetNextAeonDetails(aeonDetails) diff --git a/beacon/entropy_generator.go b/beacon/entropy_generator.go index 9b6c5a33d..8dd8e9fb4 100644 --- a/beacon/entropy_generator.go +++ b/beacon/entropy_generator.go @@ -52,6 +52,7 @@ type EntropyGenerator struct { nextAeons []*aeonDetails aeon *aeonDetails + chainID string baseConfig *cfg.BaseConfig beaconConfig *cfg.BeaconConfig @@ -84,7 +85,7 @@ func (entropyGenerator *EntropyGenerator) AttachMetrics(metrics *Metrics) { } // NewEntropyGenerator creates new entropy generator with validator information -func NewEntropyGenerator(bConfig *cfg.BaseConfig, beaconConfig *cfg.BeaconConfig, blockHeight int64, +func NewEntropyGenerator(chainID string, bConfig *cfg.BaseConfig, beaconConfig *cfg.BeaconConfig, blockHeight int64, evpool evidencePool, stateDB dbm.DB) *EntropyGenerator { if bConfig == nil || beaconConfig == nil { panic(fmt.Errorf("NewEntropyGenerator: baseConfig/beaconConfig can not be nil")) @@ -94,6 +95,7 @@ func NewEntropyGenerator(bConfig *cfg.BaseConfig, beaconConfig *cfg.BeaconConfig lastBlockHeight: blockHeight, lastComputedEntropyHeight: -1, // value is invalid and requires last entropy to be set entropyComputed: make(map[int64]types.ThresholdSignature), + chainID: chainID, baseConfig: bConfig, beaconConfig: beaconConfig, evsw: tmevents.NewEventSwitch(), @@ -378,7 +380,7 @@ func (entropyGenerator *EntropyGenerator) applyEntropyShare(share *types.Entropy } // Verify signature on message - verifySig := validator.PubKey.VerifyBytes(share.SignBytes(entropyGenerator.baseConfig.ChainID()), share.Signature) + verifySig := validator.PubKey.VerifyBytes(share.SignBytes(entropyGenerator.chainID), share.Signature) if !verifySig { entropyGenerator.Logger.Error("applyEntropyShare: invalid validator signature", "validator", share.SignerAddress, "index", index) return @@ -493,7 +495,7 @@ func (entropyGenerator *EntropyGenerator) sign() { SignatureShare: signature, } // Sign message - err = entropyGenerator.aeon.privValidator.SignEntropy(entropyGenerator.baseConfig.ChainID(), &share) + err = entropyGenerator.aeon.privValidator.SignEntropy(entropyGenerator.chainID, &share) if err != nil { entropyGenerator.Logger.Error(err.Error()) return @@ -739,7 +741,7 @@ func (entropyGenerator *EntropyGenerator) updateActivityTracking(entropy *types. } evidence := types.NewBeaconInactivityEvidence(entropy.Height, defAddress, pubKey.Address(), entropyGenerator.aeon.Start) - sig, err := entropyGenerator.aeon.privValidator.SignEvidence(entropyGenerator.baseConfig.ChainID(), evidence) + sig, err := entropyGenerator.aeon.privValidator.SignEvidence(entropyGenerator.chainID, evidence) if err != nil { entropyGenerator.Logger.Error("updateActivityTracking: error signing evidence", "err", err) continue diff --git a/beacon/entropy_generator_test.go b/beacon/entropy_generator_test.go index 97326e422..145ce4772 100644 --- a/beacon/entropy_generator_test.go +++ b/beacon/entropy_generator_test.go @@ -55,7 +55,7 @@ func TestEntropyGeneratorStart(t *testing.T) { } for _, tc := range testCases { t.Run(tc.testName, func(t *testing.T) { - newGen := testEntropyGenerator() + newGen := testEntropyGenerator("TestChain") tc.setup(newGen) assert.NotPanics(t, func() { newGen.Start() @@ -65,7 +65,7 @@ func TestEntropyGeneratorStart(t *testing.T) { } func TestEntropyGeneratorSetAeon(t *testing.T) { - newGen := testEntropyGenerator() + newGen := testEntropyGenerator("TestChain") // Set be on the end of first aeon lastBlockHeight := int64(99) newGen.setLastBlockHeight(lastBlockHeight) @@ -245,7 +245,7 @@ func TestEntropyGeneratorApplyShare(t *testing.T) { func TestEntropyGeneratorFlush(t *testing.T) { state, privVal := groupTestSetup(1) - newGen := testEntropyGenerator() + newGen := testEntropyGenerator(state.ChainID) newGen.SetLogger(log.TestingLogger()) aeonExecUnit := testAeonFromFile("test_keys/single_validator.txt") @@ -319,7 +319,7 @@ func TestEntropyGeneratorApplyComputedEntropy(t *testing.T) { } func TestEntropyGeneratorChangeKeys(t *testing.T) { - newGen := testEntropyGenerator() + newGen := testEntropyGenerator("TestChain") newGen.SetLogger(log.TestingLogger()) newGen.SetNextAeonDetails(keylessAeonDetails(0, 4)) @@ -408,7 +408,13 @@ func TestEntropyActivityTracking(t *testing.T) { newGen.updateActivityTracking(types.NewChannelEntropy(i+1, types.BlockEntropy{}, enabled, nil)) } - assert.Equal(t, tc.pendingEvidence, len(newGen.evpool.PendingEvidence(0))) + evidence := newGen.evpool.PendingEvidence(0) + assert.Equal(t, tc.pendingEvidence, len(evidence)) + for _, ev := range evidence { + _, val := state.Validators.GetByAddress(ev.Address()) + assert.Nil(t, ev.Verify(state.ChainID, val.PubKey)) + } + }) } } @@ -421,7 +427,7 @@ func groupTestSetup(nValidators int) (sm.State, []types.PrivValidator) { } func testEntropyGen(state sm.State, privVal types.PrivValidator, index int) *EntropyGenerator { - newGen := testEntropyGenerator() + newGen := testEntropyGenerator(state.ChainID) newGen.SetLogger(log.TestingLogger()) sm.SaveState(newGen.stateDB, state) @@ -436,8 +442,8 @@ func testEntropyGen(state sm.State, privVal types.PrivValidator, index int) *Ent return newGen } -func testEntropyGenerator() *EntropyGenerator { +func testEntropyGenerator(chainID string) *EntropyGenerator { config := cfg.ResetTestRoot("entropy_generator_test") stateDB := dbm.NewMemDB() // each state needs its own db - return NewEntropyGenerator(&config.BaseConfig, config.Beacon, 0, newMockEvidencePool(), stateDB) + return NewEntropyGenerator(chainID, &config.BaseConfig, config.Beacon, 0, newMockEvidencePool(), stateDB) } diff --git a/evidence/pool.go b/evidence/pool.go index 68967ede1..8afb78114 100644 --- a/evidence/pool.go +++ b/evidence/pool.go @@ -108,7 +108,7 @@ func (evpool *Pool) AddEvidence(evidence types.Evidence) error { // fetch the validator and return its voting power as its priority // TODO: something better ? - valset, err := sm.LoadValidators(evpool.stateDB, evidence.Height()) + valset, err := sm.LoadValidators(evpool.stateDB, evidence.ValidatorHeight()) if err != nil { return err } diff --git a/node/node.go b/node/node.go index 841f18463..3a822aa84 100644 --- a/node/node.go +++ b/node/node.go @@ -575,7 +575,7 @@ func createBeaconReactor( evpool *evidence.Pool) (chan types.ChannelEntropy, *beacon.EntropyGenerator, *beacon.Reactor, error) { beacon.InitialiseMcl() - entropyGenerator := beacon.NewEntropyGenerator(&config.BaseConfig, config.Beacon, state.LastBlockHeight, evpool, db) + entropyGenerator := beacon.NewEntropyGenerator(state.ChainID, &config.BaseConfig, config.Beacon, state.LastBlockHeight, evpool, db) entropyChannel := make(chan types.ChannelEntropy, config.Beacon.EntropyChannelCapacity) entropyGenerator.SetLogger(beaconLogger) entropyGenerator.SetEntropyChannel(entropyChannel) diff --git a/state/execution.go b/state/execution.go index 6238af96c..bb86857f8 100644 --- a/state/execution.go +++ b/state/execution.go @@ -372,7 +372,7 @@ func getBeginBlockValidatorInfo(block *types.Block, stateDB dbm.DB) (abci.LastCo // We need the validator set. We already did this in validateBlock. // TODO: Should we instead cache the valset in the evidence itself and add // `SetValidatorSet()` and `ToABCI` methods ? - valset, err := LoadValidators(stateDB, ev.Height()) + valset, err := LoadValidators(stateDB, ev.ValidatorHeight()) if err != nil { panic(err) } diff --git a/state/validation.go b/state/validation.go index ccbcc72e2..e44e43b07 100644 --- a/state/validation.go +++ b/state/validation.go @@ -177,7 +177,7 @@ func VerifyEvidence(stateDB dbm.DB, state State, evidence types.Evidence) error ) } - valset, err := LoadValidators(stateDB, evidence.Height()) + valset, err := LoadValidators(stateDB, evidence.ValidatorHeight()) if err != nil { // TODO: if err is just that we cant find it cuz we pruned, ignore. // TODO: if its actually bad evidence, punish peer @@ -190,7 +190,7 @@ func VerifyEvidence(stateDB dbm.DB, state State, evidence types.Evidence) error // XXX: this makes lite-client bisection as is unsafe // See https://github.com/tendermint/tendermint/issues/3244 ev := evidence - height, addr := ev.Height(), ev.Address() + height, addr := ev.ValidatorHeight(), ev.Address() _, val := valset.GetByAddress(addr) if val == nil { return fmt.Errorf("address %X was not a validator at height %d", addr, height) diff --git a/types/evidence.go b/types/evidence.go index ecea28c69..abc831d7d 100644 --- a/types/evidence.go +++ b/types/evidence.go @@ -58,6 +58,7 @@ func (err *ErrEvidenceOverflow) Error() string { // Evidence represents any provable malicious activity by a validator type Evidence interface { Height() int64 // height of the equivocation + ValidatorHeight() int64 // height of validators Time() time.Time // time of the equivocation Address() []byte // address of the equivocating validator Bytes() []byte // bytes which comprise the evidence @@ -214,6 +215,7 @@ func EvidenceFromProto(evidence *tmproto.Evidence) (Evidence, error) { func RegisterEvidences(cdc *amino.Codec) { cdc.RegisterInterface((*Evidence)(nil), nil) cdc.RegisterConcrete(&DuplicateVoteEvidence{}, "tendermint/DuplicateVoteEvidence", nil) + cdc.RegisterConcrete(&BeaconInactivityEvidence{}, "tendermint/BeaconInactivityEvidence", nil) } func RegisterMockEvidences(cdc *amino.Codec) { @@ -280,6 +282,11 @@ func (dve *DuplicateVoteEvidence) Height() int64 { return dve.VoteA.Height } +// Height returns the height this evidence refers to. +func (dve *DuplicateVoteEvidence) ValidatorHeight() int64 { + return dve.VoteA.Height +} + // Time return the time the evidence was created func (dve *DuplicateVoteEvidence) Time() time.Time { return dve.VoteA.Timestamp @@ -438,9 +445,10 @@ func NewMockEvidence(height int64, eTime time.Time, idx int, address []byte) Moc 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) Height() int64 { return e.EvidenceHeight } +func (e MockEvidence) ValidatorHeight() 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)) @@ -471,18 +479,18 @@ func (e MockEvidence) SignBytes(chainID string) []byte { // BeaconInactivityEvidence contains evidence a validator was did not type BeaconInactivityEvidence struct { - CreationHeight int64 // Height evidence was created - CreationTime time.Time // Time evidence was created - DefendantAddress []byte // Address of validator accused of inactivity - ComplainantAddress []byte // Address of validator submitting complaint complaint - AeonStart int64 + CreationHeight int64 // Height evidence was created + CreationTime time.Time // Time evidence was created + DefendantAddress crypto.Address // Address of validator accused of inactivity + ComplainantAddress crypto.Address // Address of validator submitting complaint complaint + AeonStart int64 // Height for fetching validators ComplainantSignature []byte } var _ Evidence = &BeaconInactivityEvidence{} // NewBeaconInactivityEvidence creates BeaconInactivityEvidence -func NewBeaconInactivityEvidence(height int64, defAddress []byte, comAddress []byte, aeon int64) *BeaconInactivityEvidence { +func NewBeaconInactivityEvidence(height int64, defAddress crypto.Address, comAddress crypto.Address, aeon int64) *BeaconInactivityEvidence { return &BeaconInactivityEvidence{ CreationHeight: height, CreationTime: time.Now(), @@ -499,11 +507,16 @@ func (bie *BeaconInactivityEvidence) String() string { } -// Height returns aeon start +// Height returns evidence was created func (bie *BeaconInactivityEvidence) Height() int64 { return bie.CreationHeight } +// Height returns validator height +func (bie *BeaconInactivityEvidence) ValidatorHeight() int64 { + return bie.AeonStart +} + // Time return func (bie *BeaconInactivityEvidence) Time() time.Time { return bie.CreationTime @@ -530,6 +543,9 @@ func (bie *BeaconInactivityEvidence) Verify(chainID string, complainantPubKey cr return fmt.Errorf("ComplainantSignature invalid") } + // Need to verify defendant address in state and also aeon start is correct + // and evidence height is greater than aeon start + return nil } diff --git a/types/protobuf.go b/types/protobuf.go index b9a88717b..1bd02363e 100644 --- a/types/protobuf.go +++ b/types/protobuf.go @@ -16,8 +16,9 @@ import ( // Use strings to distinguish types in ABCI messages const ( - ABCIEvidenceTypeDuplicateVote = "duplicate/vote" - ABCIEvidenceTypeMock = "mock/evidence" + ABCIEvidenceTypeDuplicateVote = "duplicate/vote" + ABCIEvidenceTypeMock = "mock/evidence" + ABCIEvidenceTypeBeaconInactivity = "beacon/inactivity" ) const ( @@ -181,6 +182,8 @@ func (tm2pb) Evidence(ev Evidence, valSet *ValidatorSet, evTime time.Time) abci. case MockEvidence: // XXX: not great to have test types in production paths ... evType = ABCIEvidenceTypeMock + case *BeaconInactivityEvidence: + evType = ABCIEvidenceTypeBeaconInactivity default: panic(fmt.Sprintf("Unknown evidence type: %v %v", ev, reflect.TypeOf(ev))) }