Store Validators Min and Max Spans for Slashing (#3941)

* store validator min max span

* terence feedback

* terence feedback

* raul feedback

* raul formatting feedback

* raul formatting feedback

* raul validatorIdx feedback

* fix

* shorter err

* Update slasher/db/min_max_span.go

Co-Authored-By: terence tsao <terence@prysmaticlabs.com>

* Update proto/eth/v1alpha1/slasher.proto

Co-Authored-By: terence tsao <terence@prysmaticlabs.com>

* Update slasher/db/min_max_span.go

Co-Authored-By: terence tsao <terence@prysmaticlabs.com>

* Update slasher/db/min_max_span.go

Co-Authored-By: terence tsao <terence@prysmaticlabs.com>

* Update slasher/db/min_max_span.go

Co-Authored-By: terence tsao <terence@prysmaticlabs.com>

* Update slasher/db/min_max_span.go

Co-Authored-By: terence tsao <terence@prysmaticlabs.com>

* Update slasher/db/min_max-span_test.go

Co-Authored-By: terence tsao <terence@prysmaticlabs.com>

* Update slasher/db/min_max-span_test.go
This commit is contained in:
shayzluf
2019-11-07 01:38:20 +05:30
committed by Raul Jordan
parent 0be4e6fed8
commit b50f1583f3
7 changed files with 745 additions and 39 deletions

View File

@@ -6,12 +6,11 @@ package eth
import (
context "context"
fmt "fmt"
io "io"
math "math"
proto "github.com/gogo/protobuf/proto"
types "github.com/gogo/protobuf/types"
grpc "google.golang.org/grpc"
io "io"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
@@ -237,48 +236,161 @@ func (m *ProposerSlashingResponse) GetProposerSlashing() []*ProposerSlashing {
return nil
}
type MinMaxSpan struct {
MinSpan uint32 `protobuf:"varint,1,opt,name=min_span,json=minSpan,proto3" json:"min_span,omitempty"`
MaxSpan uint32 `protobuf:"varint,2,opt,name=max_span,json=maxSpan,proto3" json:"max_span,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *MinMaxSpan) Reset() { *m = MinMaxSpan{} }
func (m *MinMaxSpan) String() string { return proto.CompactTextString(m) }
func (*MinMaxSpan) ProtoMessage() {}
func (*MinMaxSpan) Descriptor() ([]byte, []int) {
return fileDescriptor_c3db2cc39857595b, []int{4}
}
func (m *MinMaxSpan) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *MinMaxSpan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_MinMaxSpan.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalTo(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *MinMaxSpan) XXX_Merge(src proto.Message) {
xxx_messageInfo_MinMaxSpan.Merge(m, src)
}
func (m *MinMaxSpan) XXX_Size() int {
return m.Size()
}
func (m *MinMaxSpan) XXX_DiscardUnknown() {
xxx_messageInfo_MinMaxSpan.DiscardUnknown(m)
}
var xxx_messageInfo_MinMaxSpan proto.InternalMessageInfo
func (m *MinMaxSpan) GetMinSpan() uint32 {
if m != nil {
return m.MinSpan
}
return 0
}
func (m *MinMaxSpan) GetMaxSpan() uint32 {
if m != nil {
return m.MaxSpan
}
return 0
}
type EpochSpanMap struct {
EpochSpanMap map[uint64]*MinMaxSpan `protobuf:"bytes,1,rep,name=epoch_span_map,json=epochSpanMap,proto3" json:"epoch_span_map,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EpochSpanMap) Reset() { *m = EpochSpanMap{} }
func (m *EpochSpanMap) String() string { return proto.CompactTextString(m) }
func (*EpochSpanMap) ProtoMessage() {}
func (*EpochSpanMap) Descriptor() ([]byte, []int) {
return fileDescriptor_c3db2cc39857595b, []int{5}
}
func (m *EpochSpanMap) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *EpochSpanMap) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_EpochSpanMap.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalTo(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *EpochSpanMap) XXX_Merge(src proto.Message) {
xxx_messageInfo_EpochSpanMap.Merge(m, src)
}
func (m *EpochSpanMap) XXX_Size() int {
return m.Size()
}
func (m *EpochSpanMap) XXX_DiscardUnknown() {
xxx_messageInfo_EpochSpanMap.DiscardUnknown(m)
}
var xxx_messageInfo_EpochSpanMap proto.InternalMessageInfo
func (m *EpochSpanMap) GetEpochSpanMap() map[uint64]*MinMaxSpan {
if m != nil {
return m.EpochSpanMap
}
return nil
}
func init() {
proto.RegisterType((*ValidatorIDToIdxAtt)(nil), "ethereum.eth.v1alpha1.ValidatorIDToIdxAtt")
proto.RegisterType((*ValidatorIDToIdxAttList)(nil), "ethereum.eth.v1alpha1.ValidatorIDToIdxAttList")
proto.RegisterType((*ProposerSlashingRequest)(nil), "ethereum.eth.v1alpha1.ProposerSlashingRequest")
proto.RegisterType((*ProposerSlashingResponse)(nil), "ethereum.eth.v1alpha1.ProposerSlashingResponse")
proto.RegisterType((*MinMaxSpan)(nil), "ethereum.eth.v1alpha1.MinMaxSpan")
proto.RegisterType((*EpochSpanMap)(nil), "ethereum.eth.v1alpha1.EpochSpanMap")
proto.RegisterMapType((map[uint64]*MinMaxSpan)(nil), "ethereum.eth.v1alpha1.EpochSpanMap.EpochSpanMapEntry")
}
func init() { proto.RegisterFile("proto/eth/v1alpha1/slasher.proto", fileDescriptor_c3db2cc39857595b) }
var fileDescriptor_c3db2cc39857595b = []byte{
// 495 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0xc1, 0x6e, 0xd3, 0x40,
0x10, 0x86, 0xb5, 0xa4, 0xa2, 0x74, 0x53, 0x41, 0x59, 0xd4, 0xd6, 0x4a, 0x51, 0x14, 0x45, 0xa0,
0x44, 0x1c, 0xd6, 0x6d, 0x10, 0x27, 0x4e, 0x0d, 0x20, 0x11, 0xd1, 0x03, 0x72, 0x2b, 0x90, 0x7a,
0xb1, 0xd6, 0xf6, 0x60, 0x2f, 0x38, 0x5e, 0xb3, 0x3b, 0xae, 0xda, 0xa7, 0xe0, 0xce, 0x13, 0x71,
0xe4, 0x11, 0x50, 0x9e, 0x04, 0x79, 0xed, 0x34, 0x51, 0xe3, 0xa0, 0x70, 0x9c, 0x7f, 0xfe, 0x9d,
0x7f, 0xfd, 0x79, 0x87, 0xf6, 0x72, 0xad, 0x50, 0xb9, 0x80, 0x89, 0x7b, 0x75, 0x22, 0xd2, 0x3c,
0x11, 0x27, 0xae, 0x49, 0x85, 0x49, 0x40, 0x73, 0xdb, 0x62, 0xfb, 0x80, 0x09, 0x68, 0x28, 0xa6,
0x1c, 0x30, 0xe1, 0x73, 0x53, 0xe7, 0x28, 0x56, 0x2a, 0x4e, 0xc1, 0xb5, 0xa6, 0xa0, 0xf8, 0xe2,
0xc2, 0x34, 0xc7, 0x9b, 0xea, 0x4c, 0xe7, 0x79, 0xc3, 0xd4, 0x00, 0x44, 0xa8, 0x32, 0x3f, 0x48,
0x55, 0xf8, 0xad, 0xb6, 0x3d, 0x6b, 0xb0, 0x09, 0x44, 0x30, 0x28, 0x50, 0xaa, 0xac, 0x72, 0xf5,
0xbf, 0xd2, 0x27, 0x9f, 0x44, 0x2a, 0x23, 0x81, 0x4a, 0x4f, 0xde, 0x5e, 0xa8, 0x49, 0x74, 0x7d,
0x8a, 0xc8, 0x1c, 0xba, 0x2d, 0xb3, 0x48, 0x86, 0x60, 0x1c, 0xd2, 0x6b, 0x0d, 0xb7, 0xbc, 0x79,
0xc9, 0x8e, 0xe8, 0x4e, 0x24, 0x50, 0xf8, 0x5a, 0x29, 0x74, 0xee, 0xf5, 0xc8, 0x70, 0xd7, 0x7b,
0x50, 0x0a, 0x9e, 0x52, 0xc8, 0x9e, 0xd2, 0x1d, 0x23, 0xe3, 0x4c, 0x60, 0xa1, 0xc1, 0x69, 0xd9,
0xe6, 0x42, 0xe8, 0xc7, 0xf4, 0xb0, 0x21, 0xeb, 0x4c, 0x1a, 0x64, 0x67, 0xb4, 0x5d, 0x07, 0x94,
0xa5, 0xcd, 0x6c, 0x8f, 0x5e, 0xf0, 0x46, 0x3a, 0xbc, 0x61, 0x88, 0xb7, 0x7c, 0xbc, 0xff, 0x83,
0xd0, 0xc3, 0x8f, 0x5a, 0xe5, 0xca, 0x80, 0x3e, 0x2f, 0x79, 0xcb, 0x2c, 0xf6, 0xe0, 0x7b, 0x01,
0x06, 0xd9, 0x07, 0xba, 0x6b, 0x29, 0xf9, 0x09, 0x88, 0x08, 0xb4, 0x43, 0x7a, 0x64, 0xd8, 0x1e,
0x0d, 0xd7, 0x44, 0x8d, 0x2d, 0xd7, 0x71, 0x79, 0xe0, 0xbd, 0xf5, 0x7b, 0xed, 0x60, 0x51, 0xb0,
0x01, 0x7d, 0x74, 0x35, 0xbf, 0x8c, 0x2f, 0xb3, 0x08, 0xae, 0x2d, 0x92, 0x2d, 0xef, 0xe1, 0xad,
0x3c, 0x29, 0xd5, 0x7e, 0x4e, 0x9d, 0xd5, 0x0b, 0x99, 0x5c, 0x65, 0x06, 0xd8, 0x05, 0x7d, 0x9c,
0xd7, 0x3d, 0xdf, 0xd4, 0xcd, 0x9a, 0xc0, 0x60, 0xcd, 0xb5, 0x56, 0x66, 0xed, 0xe5, 0x77, 0x94,
0xd1, 0xcf, 0x16, 0xdd, 0x3e, 0xaf, 0xde, 0x1a, 0x03, 0x7a, 0x30, 0x31, 0xb6, 0x10, 0x41, 0x0a,
0xa7, 0x8b, 0x47, 0xc0, 0xfa, 0x6b, 0x02, 0x96, 0x3c, 0x9d, 0xc1, 0x3f, 0x3d, 0x8b, 0x48, 0x66,
0xe8, 0xde, 0x52, 0x8c, 0x85, 0xc6, 0xf8, 0xa6, 0x5f, 0x50, 0xfd, 0x9e, 0x8e, 0xbb, 0xb1, 0xbf,
0xa6, 0xf7, 0x99, 0xb2, 0xdb, 0xc8, 0xca, 0x24, 0x52, 0xc3, 0x0e, 0x78, 0xb5, 0x41, 0x7c, 0xbe,
0x41, 0xfc, 0x5d, 0xb9, 0x41, 0x9d, 0x4d, 0x81, 0x1e, 0x13, 0x76, 0x49, 0xf7, 0x9b, 0x90, 0xfd,
0xff, 0xec, 0xbb, 0x9c, 0x8e, 0xc9, 0xf8, 0xcd, 0xaf, 0x59, 0x97, 0xfc, 0x9e, 0x75, 0xc9, 0x9f,
0x59, 0x97, 0x5c, 0xbe, 0x8a, 0x25, 0x26, 0x45, 0xc0, 0x43, 0x35, 0x75, 0x73, 0x7d, 0x63, 0xa6,
0x02, 0x65, 0x98, 0x8a, 0xc0, 0x54, 0x95, 0xbb, 0xba, 0xc8, 0xaf, 0x01, 0x93, 0xe0, 0xbe, 0xd5,
0x5f, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x04, 0xd4, 0x21, 0x51, 0x66, 0x04, 0x00, 0x00,
// 616 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xc1, 0x6e, 0xd3, 0x4c,
0x10, 0xd6, 0x36, 0xfd, 0xff, 0xb6, 0x93, 0x50, 0xda, 0x45, 0x6d, 0x43, 0x8a, 0xaa, 0x60, 0x81,
0x1a, 0x71, 0xb0, 0xdb, 0xa0, 0x0a, 0x04, 0xa7, 0x06, 0x2a, 0x11, 0xd1, 0x4a, 0xc8, 0xad, 0x40,
0x2a, 0x07, 0x6b, 0x9d, 0x0c, 0xf1, 0x52, 0x7b, 0x77, 0xf1, 0x6e, 0xaa, 0xe4, 0x29, 0xb8, 0xf3,
0x44, 0xdc, 0xe0, 0x11, 0x50, 0x9f, 0x04, 0x79, 0xed, 0x34, 0xa1, 0x49, 0x50, 0xb9, 0xf9, 0x9b,
0xf9, 0x66, 0xe6, 0xf3, 0xe7, 0xf1, 0x40, 0x5d, 0xa5, 0xd2, 0x48, 0x0f, 0x4d, 0xe4, 0x5d, 0xee,
0xb3, 0x58, 0x45, 0x6c, 0xdf, 0xd3, 0x31, 0xd3, 0x11, 0xa6, 0xae, 0x4d, 0xd1, 0x0d, 0x34, 0x11,
0xa6, 0xd8, 0x4f, 0x5c, 0x34, 0x91, 0x3b, 0x22, 0xd5, 0xb6, 0x7b, 0x52, 0xf6, 0x62, 0xf4, 0x2c,
0x29, 0xec, 0x7f, 0xf2, 0x30, 0x51, 0x66, 0x98, 0xd7, 0xd4, 0x1e, 0xcf, 0xe8, 0x1a, 0x22, 0xeb,
0x48, 0x11, 0x84, 0xb1, 0xec, 0x5c, 0x14, 0xb4, 0x47, 0x33, 0x68, 0xcc, 0x18, 0xd4, 0x86, 0x19,
0x2e, 0x45, 0xce, 0x72, 0x3e, 0xc3, 0xbd, 0xf7, 0x2c, 0xe6, 0x5d, 0x66, 0x64, 0xda, 0x7e, 0x7d,
0x26, 0xdb, 0xdd, 0xc1, 0xa1, 0x31, 0xb4, 0x0a, 0x4b, 0x5c, 0x74, 0x79, 0x07, 0x75, 0x95, 0xd4,
0x4b, 0x8d, 0x45, 0x7f, 0x04, 0xe9, 0x36, 0xac, 0x74, 0x99, 0x61, 0x41, 0x2a, 0xa5, 0xa9, 0x2e,
0xd4, 0x49, 0xa3, 0xe2, 0x2f, 0x67, 0x01, 0x5f, 0x4a, 0x43, 0x1f, 0xc0, 0x8a, 0xe6, 0x3d, 0xc1,
0x4c, 0x3f, 0xc5, 0x6a, 0xc9, 0x26, 0xc7, 0x01, 0xa7, 0x07, 0x5b, 0x33, 0x66, 0x1d, 0x73, 0x6d,
0xe8, 0x31, 0x94, 0x8b, 0x01, 0x19, 0xb4, 0x33, 0xcb, 0xcd, 0x27, 0xee, 0x4c, 0x77, 0xdc, 0x19,
0x4d, 0xfc, 0xc9, 0x72, 0xe7, 0x2b, 0x81, 0xad, 0x77, 0xa9, 0x54, 0x52, 0x63, 0x7a, 0x9a, 0xf9,
0xcd, 0x45, 0xcf, 0xc7, 0x2f, 0x7d, 0xd4, 0x86, 0xbe, 0x85, 0x8a, 0x75, 0x29, 0x88, 0x90, 0x75,
0x31, 0xad, 0x92, 0x3a, 0x69, 0x94, 0x9b, 0x8d, 0x39, 0xa3, 0x5a, 0xd6, 0xd7, 0x56, 0x56, 0xf0,
0xc6, 0xf2, 0xfd, 0x72, 0x38, 0x06, 0x74, 0x17, 0xee, 0x5e, 0x8e, 0xc4, 0x04, 0x5c, 0x74, 0x71,
0x60, 0x2d, 0x59, 0xf4, 0x57, 0xaf, 0xc3, 0xed, 0x2c, 0xea, 0x28, 0xa8, 0x4e, 0x0b, 0xd2, 0x4a,
0x0a, 0x8d, 0xf4, 0x0c, 0xd6, 0x55, 0x91, 0x0b, 0x74, 0x91, 0x2c, 0x1c, 0xd8, 0x9d, 0x23, 0x6b,
0xaa, 0xd7, 0x9a, 0xba, 0x11, 0x71, 0x5a, 0x00, 0x27, 0x5c, 0x9c, 0xb0, 0xc1, 0xa9, 0x62, 0x82,
0xde, 0x87, 0xe5, 0x84, 0x8b, 0x40, 0x2b, 0x26, 0xec, 0x1b, 0xdf, 0xf1, 0x97, 0x12, 0x2e, 0xae,
0x53, 0x6c, 0x90, 0xa7, 0x16, 0x8a, 0x54, 0x5e, 0xe5, 0xfc, 0x20, 0x50, 0x39, 0x52, 0xb2, 0x13,
0x65, 0xe8, 0x84, 0x29, 0xfa, 0x11, 0x56, 0x31, 0xc3, 0x96, 0x1d, 0x24, 0x4c, 0x15, 0x3a, 0x0f,
0xe6, 0xe8, 0x9c, 0x2c, 0xfe, 0x03, 0x1c, 0x09, 0x93, 0x0e, 0xfd, 0x0a, 0x4e, 0x84, 0x6a, 0x21,
0xac, 0x4f, 0x51, 0xe8, 0x1a, 0x94, 0x2e, 0x70, 0x68, 0x35, 0x2f, 0xfa, 0xd9, 0x23, 0x7d, 0x06,
0xff, 0x5d, 0xb2, 0xb8, 0x8f, 0x56, 0x6c, 0xb9, 0xf9, 0x70, 0xce, 0xe8, 0xf1, 0xcb, 0xfb, 0x39,
0xff, 0xc5, 0xc2, 0x73, 0xd2, 0xfc, 0x56, 0x82, 0xa5, 0xd3, 0xfc, 0x0f, 0xa4, 0x08, 0x9b, 0x6d,
0x6d, 0x01, 0x0b, 0x63, 0x3c, 0x1c, 0xff, 0x1a, 0xd4, 0x99, 0xd3, 0x73, 0x82, 0x53, 0xdb, 0xfd,
0x2b, 0x67, 0xfc, 0x21, 0xa8, 0x86, 0xb5, 0x89, 0x31, 0x76, 0x95, 0xa8, 0x7b, 0xdb, 0xef, 0x9a,
0x2f, 0x6d, 0xcd, 0xbb, 0x35, 0xbf, 0xd8, 0xa9, 0x0f, 0x40, 0xaf, 0x47, 0xe6, 0x24, 0x16, 0x6b,
0xba, 0xe9, 0xe6, 0x77, 0xc5, 0x1d, 0xdd, 0x15, 0xf7, 0x28, 0xbb, 0x2b, 0xb5, 0xdb, 0xae, 0xd9,
0x1e, 0xa1, 0xe7, 0xb0, 0x31, 0xcb, 0xb2, 0x7f, 0xef, 0x7d, 0xd3, 0xa7, 0x3d, 0xd2, 0x7a, 0xf5,
0xfd, 0x6a, 0x87, 0xfc, 0xbc, 0xda, 0x21, 0xbf, 0xae, 0x76, 0xc8, 0xf9, 0x41, 0x8f, 0x9b, 0xa8,
0x1f, 0xba, 0x1d, 0x99, 0x78, 0x2a, 0x1d, 0xea, 0x84, 0x19, 0xde, 0x89, 0x59, 0xa8, 0x73, 0xe4,
0x4d, 0x9f, 0xb7, 0x97, 0x68, 0xa2, 0xf0, 0x7f, 0x1b, 0x7f, 0xfa, 0x3b, 0x00, 0x00, 0xff, 0xff,
0x96, 0x7b, 0xa2, 0x30, 0x7c, 0x05, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -659,6 +771,85 @@ func (m *ProposerSlashingResponse) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func (m *MinMaxSpan) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *MinMaxSpan) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.MinSpan != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintSlasher(dAtA, i, uint64(m.MinSpan))
}
if m.MaxSpan != 0 {
dAtA[i] = 0x10
i++
i = encodeVarintSlasher(dAtA, i, uint64(m.MaxSpan))
}
if m.XXX_unrecognized != nil {
i += copy(dAtA[i:], m.XXX_unrecognized)
}
return i, nil
}
func (m *EpochSpanMap) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *EpochSpanMap) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.EpochSpanMap) > 0 {
for k, _ := range m.EpochSpanMap {
dAtA[i] = 0xa
i++
v := m.EpochSpanMap[k]
msgSize := 0
if v != nil {
msgSize = v.Size()
msgSize += 1 + sovSlasher(uint64(msgSize))
}
mapSize := 1 + sovSlasher(uint64(k)) + msgSize
i = encodeVarintSlasher(dAtA, i, uint64(mapSize))
dAtA[i] = 0x8
i++
i = encodeVarintSlasher(dAtA, i, uint64(k))
if v != nil {
dAtA[i] = 0x12
i++
i = encodeVarintSlasher(dAtA, i, uint64(v.Size()))
n4, err := v.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n4
}
}
}
if m.XXX_unrecognized != nil {
i += copy(dAtA[i:], m.XXX_unrecognized)
}
return i, nil
}
func encodeVarintSlasher(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
@@ -750,6 +941,49 @@ func (m *ProposerSlashingResponse) Size() (n int) {
return n
}
func (m *MinMaxSpan) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.MinSpan != 0 {
n += 1 + sovSlasher(uint64(m.MinSpan))
}
if m.MaxSpan != 0 {
n += 1 + sovSlasher(uint64(m.MaxSpan))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func (m *EpochSpanMap) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.EpochSpanMap) > 0 {
for k, v := range m.EpochSpanMap {
_ = k
_ = v
l = 0
if v != nil {
l = v.Size()
l += 1 + sovSlasher(uint64(l))
}
mapEntrySize := 1 + sovSlasher(uint64(k)) + l
n += mapEntrySize + 1 + sovSlasher(uint64(mapEntrySize))
}
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovSlasher(x uint64) (n int) {
for {
n++
@@ -1246,6 +1480,267 @@ func (m *ProposerSlashingResponse) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *MinMaxSpan) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSlasher
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: MinMaxSpan: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: MinMaxSpan: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field MinSpan", wireType)
}
m.MinSpan = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSlasher
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.MinSpan |= uint32(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field MaxSpan", wireType)
}
m.MaxSpan = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSlasher
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.MaxSpan |= uint32(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipSlasher(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthSlasher
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthSlasher
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *EpochSpanMap) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSlasher
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: EpochSpanMap: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: EpochSpanMap: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field EpochSpanMap", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSlasher
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthSlasher
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthSlasher
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.EpochSpanMap == nil {
m.EpochSpanMap = make(map[uint64]*MinMaxSpan)
}
var mapkey uint64
var mapvalue *MinMaxSpan
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSlasher
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSlasher
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
mapkey |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
} else if fieldNum == 2 {
var mapmsglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSlasher
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
mapmsglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if mapmsglen < 0 {
return ErrInvalidLengthSlasher
}
postmsgIndex := iNdEx + mapmsglen
if postmsgIndex < 0 {
return ErrInvalidLengthSlasher
}
if postmsgIndex > l {
return io.ErrUnexpectedEOF
}
mapvalue = &MinMaxSpan{}
if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil {
return err
}
iNdEx = postmsgIndex
} else {
iNdEx = entryPreIndex
skippy, err := skipSlasher(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthSlasher
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
m.EpochSpanMap[mapkey] = mapvalue
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipSlasher(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthSlasher
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthSlasher
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipSlasher(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0

View File

@@ -41,9 +41,23 @@ message ValidatorIDToIdxAttList {
}
message ProposerSlashingRequest {
ethereum.eth.v1alpha1.BeaconBlockHeader block_header=1;
uint64 validator_index=2;
ethereum.eth.v1alpha1.BeaconBlockHeader block_header = 1;
uint64 validator_index = 2;
}
message ProposerSlashingResponse {
repeated ethereum.eth.v1alpha1.ProposerSlashing proposer_slashing=1;
repeated ethereum.eth.v1alpha1.ProposerSlashing proposer_slashing = 1;
}
// In order to detect surrounded attestation we need to compare
// each attestation source to those spans
// see https://github.com/protolambda/eth2-surround/blob/master/README.md#min-max-surround
// for further details.
message MinMaxSpan {
uint32 min_span = 1;
uint32 max_span = 2;
}
// every validator will have his own spans map containing min and max value for each epoch
// in order to detect slashable attestation as quick as possible.
message EpochSpanMap {
// uint64 is for storing the epoch
map<uint64, MinMaxSpan> epoch_span_map = 1;
}

View File

@@ -6,6 +6,7 @@ go_library(
"block_header.go",
"db.go",
"indexed_attestations.go",
"min_max_span.go",
"schema.go",
"setup_db.go",
"validator_id_pubkey.go",
@@ -29,9 +30,13 @@ go_test(
srcs = [
"block_header_test.go",
"indexed_attestations_test.go",
"min_max-span_test.go",
"setup_db_test.go",
"validator_id_pubkey_test.go",
],
embed = [":go_default_library"],
deps = ["//proto/eth/v1alpha1:go_default_library"],
deps = [
"//proto/eth/v1alpha1:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
],
)

View File

@@ -86,6 +86,7 @@ func NewKVStore(dirPath string) (*Store, error) {
historicBlockHeadersBucket,
indexedAttestationsIndicesBucket,
validatorsPublicKeysBucket,
validatorsMinMaxSpanBucket,
)
}); err != nil {
return nil, err

View File

@@ -0,0 +1,117 @@
package db
import (
"github.com/gogo/protobuf/proto"
"testing"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
)
type spanMapTestStruct struct {
validatorIdx uint64
spanMap *ethpb.EpochSpanMap
}
var spanTests []spanMapTestStruct
func init() {
spanTests = []spanMapTestStruct{
{
validatorIdx: 1,
spanMap: &ethpb.EpochSpanMap{
EpochSpanMap: map[uint64]*ethpb.MinMaxSpan{
1: {MinSpan: 10, MaxSpan: 20},
2: {MinSpan: 11, MaxSpan: 21},
3: {MinSpan: 12, MaxSpan: 22},
},
},
},
{
validatorIdx: 2,
spanMap: &ethpb.EpochSpanMap{
EpochSpanMap: map[uint64]*ethpb.MinMaxSpan{
1: {MinSpan: 10, MaxSpan: 20},
2: {MinSpan: 11, MaxSpan: 21},
3: {MinSpan: 12, MaxSpan: 22},
},
},
},
{
validatorIdx: 3,
spanMap: &ethpb.EpochSpanMap{
EpochSpanMap: map[uint64]*ethpb.MinMaxSpan{
1: {MinSpan: 10, MaxSpan: 20},
2: {MinSpan: 11, MaxSpan: 21},
3: {MinSpan: 12, MaxSpan: 22},
},
},
},
}
}
func TestValidatorSpanMap_NilDB(t *testing.T) {
db := SetupSlasherDB(t)
defer TeardownSlasherDB(t, db)
validatorIdx := uint64(1)
vsm, err := db.ValidatorSpansMap(validatorIdx)
if err != nil {
t.Fatalf("Nil ValidatorSpansMap should not return error: %v", err)
}
if vsm.EpochSpanMap != nil {
t.Fatal("ValidatorSpansMap should return nil")
}
}
func TestValidatorSpanMap_Save(t *testing.T) {
db := SetupSlasherDB(t)
defer TeardownSlasherDB(t, db)
for _, tt := range spanTests {
err := db.SaveValidatorSpansMap(tt.validatorIdx, tt.spanMap)
if err != nil {
t.Fatalf("Save validator span map failed: %v", err)
}
sm, err := db.ValidatorSpansMap(tt.validatorIdx)
if err != nil {
t.Fatalf("Failed to get validator span map: %v", err)
}
if sm == nil || !proto.Equal(sm, tt.spanMap) {
t.Fatalf("Get should return validator span map: %v got: %v", tt.spanMap, sm)
}
}
}
func TestValidatorSpanMap_Delete(t *testing.T) {
db := SetupSlasherDB(t)
defer TeardownSlasherDB(t, db)
for _, tt := range spanTests {
err := db.SaveValidatorSpansMap(tt.validatorIdx, tt.spanMap)
if err != nil {
t.Fatalf("Save validator span map failed: %v", err)
}
}
for _, tt := range spanTests {
sm, err := db.ValidatorSpansMap(tt.validatorIdx)
if err != nil {
t.Fatalf("Failed to get validator span map: %v", err)
}
if sm == nil || !proto.Equal(sm, tt.spanMap) {
t.Fatalf("Get should return validator span map: %v got: %v", tt.spanMap, sm)
}
err = db.DeleteValidatorSpanMap(tt.validatorIdx)
if err != nil {
t.Fatalf("Delete validator span map error: %v", err)
}
sm, err = db.ValidatorSpansMap(tt.validatorIdx)
if err != nil {
t.Fatal(err)
}
if sm.EpochSpanMap != nil {
t.Errorf("Expected validator span map to be deleted, received: %v", sm)
}
}
}

View File

@@ -0,0 +1,70 @@
package db
import (
"github.com/boltdb/bolt"
"github.com/gogo/protobuf/proto"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
)
func createEpochSpanMap(enc []byte) (*ethpb.EpochSpanMap, error) {
epochSpanMap := &ethpb.EpochSpanMap{}
err := proto.Unmarshal(enc, epochSpanMap)
if err != nil {
return nil, errors.Wrap(err, "failed to unmarshal encoding")
}
return epochSpanMap, nil
}
// ValidatorSpansMap accepts validator index and returns the corresponding spans
// map for slashing detection.
// Returns nil if the span map for this validator index does not exist.
func (db *Store) ValidatorSpansMap(validatorIdx uint64) (*ethpb.EpochSpanMap, error) {
var sm *ethpb.EpochSpanMap
err := db.view(func(tx *bolt.Tx) error {
b := tx.Bucket(validatorsMinMaxSpanBucket)
enc := b.Get(bytesutil.Bytes4(validatorIdx))
var err error
sm, err = createEpochSpanMap(enc)
if err != nil {
return err
}
return nil
})
return sm, err
}
// SaveValidatorSpansMap accepts a validator index and span map and writes it to disk.
func (db *Store) SaveValidatorSpansMap(validatorIdx uint64, spanMap *ethpb.EpochSpanMap) error {
err := db.update(func(tx *bolt.Tx) error {
bucket := tx.Bucket(validatorsMinMaxSpanBucket)
key := bytesutil.Bytes4(validatorIdx)
val, err := proto.Marshal(spanMap)
if err != nil {
return errors.Wrap(err, "failed to marshal span map")
}
if err := bucket.Put(key, val); err != nil {
return errors.Wrapf(err, "failed to delete validator id: %d from validators min max span bucket", validatorIdx)
}
return err
})
return err
}
// DeleteValidatorSpanMap deletes a validator span map using a validator index as bucket key.
func (db *Store) DeleteValidatorSpanMap(validatorIdx uint64) error {
return db.update(func(tx *bolt.Tx) error {
bucket := tx.Bucket(validatorsMinMaxSpanBucket)
key := bytesutil.Bytes4(validatorIdx)
enc := bucket.Get(key)
if enc == nil {
return nil
}
if err := bucket.Delete(key); err != nil {
tx.Rollback()
return errors.Wrapf(err, "failed to delete the span map for validator idx: %v from validators min max span bucket", validatorIdx)
}
return nil
})
}

View File

@@ -10,6 +10,10 @@ var (
historicBlockHeadersBucket = []byte("historic-block-headers-bucket")
indexedAttestationsIndicesBucket = []byte("indexed-attestations-indices-bucket")
validatorsPublicKeysBucket = []byte("validators-public-keys-bucket")
// in order to quickly detect surround and surrounded attestations we need to store
// the min and max span for each validator for each epoch.
// see https://github.com/protolambda/eth2-surround/blob/master/README.md#min-max-surround
validatorsMinMaxSpanBucket = []byte("validators-min-max-span-bucket")
)
func encodeEpochValidatorID(epoch uint64, validatorID uint64) []byte {