mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Slasher grpc service (#3271)
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -21,4 +21,8 @@ yarn-error.log
|
||||
.vscode/
|
||||
|
||||
# Ignore password file
|
||||
password.txt
|
||||
password.txt
|
||||
|
||||
# go dependancy
|
||||
/go.mod
|
||||
/go.sum
|
||||
|
||||
@@ -17,6 +17,7 @@ go_library(
|
||||
visibility = [
|
||||
"//beacon-chain:__subpackages__",
|
||||
"//shared/testutil:__pkg__",
|
||||
"//slasher:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//beacon-chain/cache:go_default_library",
|
||||
|
||||
603
proto/eth/v1alpha1/slasher.pb.go
generated
603
proto/eth/v1alpha1/slasher.pb.go
generated
@@ -6,6 +6,7 @@ package eth
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
io "io"
|
||||
math "math"
|
||||
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
@@ -24,29 +25,143 @@ var _ = math.Inf
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type ProposerSlashingRequest struct {
|
||||
BlockHeader *BeaconBlockHeader `protobuf:"bytes,1,opt,name=block_header,json=blockHeader,proto3" json:"block_header,omitempty"`
|
||||
ValidatorIndex uint64 `protobuf:"varint,2,opt,name=validator_index,json=validatorIndex,proto3" json:"validator_index,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ProposerSlashingRequest) Reset() { *m = ProposerSlashingRequest{} }
|
||||
func (m *ProposerSlashingRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProposerSlashingRequest) ProtoMessage() {}
|
||||
func (*ProposerSlashingRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_c3db2cc39857595b, []int{0}
|
||||
}
|
||||
func (m *ProposerSlashingRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *ProposerSlashingRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_ProposerSlashingRequest.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 *ProposerSlashingRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ProposerSlashingRequest.Merge(m, src)
|
||||
}
|
||||
func (m *ProposerSlashingRequest) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *ProposerSlashingRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ProposerSlashingRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ProposerSlashingRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *ProposerSlashingRequest) GetBlockHeader() *BeaconBlockHeader {
|
||||
if m != nil {
|
||||
return m.BlockHeader
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ProposerSlashingRequest) GetValidatorIndex() uint64 {
|
||||
if m != nil {
|
||||
return m.ValidatorIndex
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type ProposerSlashingResponse struct {
|
||||
ProposerSlashing []*ProposerSlashing `protobuf:"bytes,1,rep,name=proposer_slashing,json=proposerSlashing,proto3" json:"proposer_slashing,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ProposerSlashingResponse) Reset() { *m = ProposerSlashingResponse{} }
|
||||
func (m *ProposerSlashingResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProposerSlashingResponse) ProtoMessage() {}
|
||||
func (*ProposerSlashingResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_c3db2cc39857595b, []int{1}
|
||||
}
|
||||
func (m *ProposerSlashingResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *ProposerSlashingResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_ProposerSlashingResponse.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 *ProposerSlashingResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ProposerSlashingResponse.Merge(m, src)
|
||||
}
|
||||
func (m *ProposerSlashingResponse) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *ProposerSlashingResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ProposerSlashingResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ProposerSlashingResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *ProposerSlashingResponse) GetProposerSlashing() []*ProposerSlashing {
|
||||
if m != nil {
|
||||
return m.ProposerSlashing
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*ProposerSlashingRequest)(nil), "ethereum.eth.v1alpha1.ProposerSlashingRequest")
|
||||
proto.RegisterType((*ProposerSlashingResponse)(nil), "ethereum.eth.v1alpha1.ProposerSlashingResponse")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("proto/eth/v1alpha1/slasher.proto", fileDescriptor_c3db2cc39857595b) }
|
||||
|
||||
var fileDescriptor_c3db2cc39857595b = []byte{
|
||||
// 296 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x91, 0xc1, 0x4a, 0xf4, 0x30,
|
||||
0x14, 0x85, 0x29, 0x3f, 0xfc, 0x42, 0x56, 0x12, 0x98, 0x59, 0x8c, 0x50, 0x44, 0x14, 0x5d, 0x25,
|
||||
0x33, 0x8a, 0x2b, 0x57, 0x56, 0x04, 0xdd, 0x09, 0x2e, 0x84, 0xd9, 0xc8, 0x4d, 0xbd, 0x36, 0xc5,
|
||||
0xb4, 0x29, 0xc9, 0xad, 0x30, 0xef, 0xe0, 0x83, 0xb9, 0xf4, 0x11, 0xa4, 0x4f, 0x22, 0x93, 0x38,
|
||||
0x5a, 0xb4, 0x23, 0xba, 0xbc, 0xbd, 0xdf, 0x3d, 0xe7, 0xf4, 0x84, 0x6d, 0x37, 0xce, 0x92, 0x95,
|
||||
0x48, 0x5a, 0x3e, 0xce, 0xc0, 0x34, 0x1a, 0x66, 0xd2, 0x1b, 0xf0, 0x1a, 0x9d, 0x08, 0x2b, 0x3e,
|
||||
0x42, 0xd2, 0xe8, 0xb0, 0xad, 0x04, 0x92, 0x16, 0x2b, 0x68, 0xb2, 0x55, 0x58, 0x5b, 0x18, 0x94,
|
||||
0x01, 0x52, 0xed, 0xbd, 0xc4, 0xaa, 0xa1, 0x45, 0xbc, 0x99, 0xec, 0x0d, 0xa8, 0x2a, 0x84, 0xdc,
|
||||
0xd6, 0xb7, 0xca, 0xd8, 0xfc, 0xe1, 0x1d, 0xdb, 0x1d, 0xc0, 0x80, 0x08, 0x3d, 0x01, 0x95, 0xb6,
|
||||
0x8e, 0xd4, 0xe1, 0xd3, 0x3f, 0xb6, 0x71, 0x1d, 0x23, 0x71, 0x64, 0xe3, 0x4b, 0x1f, 0x06, 0x50,
|
||||
0x06, 0x4f, 0x3f, 0x59, 0xbe, 0x23, 0x06, 0x73, 0x8a, 0x1e, 0x33, 0xd9, 0xff, 0x91, 0x41, 0x17,
|
||||
0x84, 0xcb, 0xba, 0xe0, 0xc8, 0x36, 0x7b, 0x36, 0xd9, 0x32, 0x32, 0x3f, 0x58, 0x73, 0x9c, 0x85,
|
||||
0xff, 0x0a, 0xcc, 0x05, 0xc2, 0x1d, 0xba, 0xb5, 0x36, 0x57, 0xce, 0x36, 0xd6, 0xf7, 0x6c, 0x6e,
|
||||
0x18, 0xff, 0x30, 0x89, 0x4b, 0x30, 0x9e, 0x8f, 0x45, 0xac, 0x56, 0xac, 0xaa, 0x15, 0xe7, 0xcb,
|
||||
0x6a, 0x7f, 0x2d, 0x3b, 0x4d, 0xf8, 0x9c, 0x8d, 0x86, 0x4a, 0xfa, 0xbb, 0xf6, 0xd7, 0x66, 0xa6,
|
||||
0x49, 0x76, 0xf6, 0xdc, 0xa5, 0xc9, 0x4b, 0x97, 0x26, 0xaf, 0x5d, 0x9a, 0xcc, 0x8f, 0x8b, 0x92,
|
||||
0x74, 0xab, 0x44, 0x6e, 0x2b, 0xd9, 0xb8, 0x85, 0xaf, 0x80, 0xca, 0xdc, 0x80, 0xf2, 0x71, 0x92,
|
||||
0xdf, 0x5f, 0xf8, 0x04, 0x49, 0xab, 0xff, 0xe1, 0xfb, 0xd1, 0x5b, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0xcd, 0x19, 0xa4, 0x22, 0x7f, 0x02, 0x00, 0x00,
|
||||
// 406 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0x41, 0x6b, 0x14, 0x31,
|
||||
0x14, 0xc7, 0x89, 0x15, 0x85, 0xac, 0x68, 0x0d, 0xb4, 0x0e, 0x23, 0x2c, 0xc3, 0xa2, 0xec, 0x9c,
|
||||
0x92, 0x76, 0xc5, 0x93, 0x27, 0x57, 0x04, 0x8b, 0x17, 0xd9, 0x0a, 0x42, 0x2f, 0x43, 0x32, 0xfb,
|
||||
0x9c, 0x0c, 0x66, 0x26, 0x31, 0xc9, 0x14, 0xfb, 0x29, 0xbc, 0xfb, 0x89, 0x3c, 0xfa, 0x11, 0x64,
|
||||
0x3f, 0x89, 0x4c, 0x66, 0xda, 0x2d, 0xbb, 0xb3, 0xb2, 0x3d, 0xbe, 0xf7, 0x7e, 0x79, 0xef, 0x9f,
|
||||
0xff, 0x7b, 0x38, 0x31, 0x56, 0x7b, 0xcd, 0xc0, 0x4b, 0x76, 0x79, 0xca, 0x95, 0x91, 0xfc, 0x94,
|
||||
0x39, 0xc5, 0x9d, 0x04, 0x4b, 0x43, 0x89, 0x1c, 0x81, 0x97, 0x60, 0xa1, 0xa9, 0x28, 0x78, 0x49,
|
||||
0xaf, 0xa1, 0xf8, 0x79, 0xa1, 0x75, 0xa1, 0x80, 0x05, 0x48, 0x34, 0x5f, 0x19, 0x54, 0xc6, 0x5f,
|
||||
0x75, 0x6f, 0xe2, 0x97, 0x03, 0x5d, 0x05, 0xf0, 0x5c, 0xd7, 0x99, 0x50, 0x3a, 0xff, 0xd6, 0x63,
|
||||
0x2f, 0x06, 0x30, 0xee, 0x3d, 0x38, 0xcf, 0x7d, 0xa9, 0xeb, 0x8e, 0x9a, 0xfc, 0x44, 0xf8, 0xd9,
|
||||
0x27, 0xab, 0x8d, 0x76, 0x60, 0xcf, 0x5b, 0x69, 0x65, 0x5d, 0x2c, 0xe0, 0x7b, 0x03, 0xce, 0x93,
|
||||
0x8f, 0xf8, 0x51, 0x68, 0x98, 0x49, 0xe0, 0x4b, 0xb0, 0x11, 0x4a, 0x50, 0x3a, 0x9a, 0xa5, 0x74,
|
||||
0x50, 0x33, 0x9d, 0x07, 0x09, 0xf3, 0xf6, 0xc1, 0x87, 0xc0, 0x2f, 0x46, 0x62, 0x1d, 0x90, 0x29,
|
||||
0x7e, 0x72, 0xc9, 0x55, 0xb9, 0xe4, 0x5e, 0xdb, 0xac, 0xac, 0x97, 0xf0, 0x23, 0xba, 0x97, 0xa0,
|
||||
0xf4, 0xfe, 0xe2, 0xf1, 0x4d, 0xfa, 0xac, 0xcd, 0x4e, 0x0c, 0x8e, 0xb6, 0x05, 0x39, 0xa3, 0x6b,
|
||||
0x07, 0xe4, 0x33, 0x7e, 0x6a, 0xfa, 0x5a, 0xe6, 0xfa, 0x62, 0x84, 0x92, 0x83, 0x74, 0x34, 0x9b,
|
||||
0xee, 0x90, 0xb5, 0xd5, 0xeb, 0xd0, 0x6c, 0x64, 0x66, 0xbf, 0x0e, 0xf0, 0xc3, 0xf3, 0x6e, 0x2d,
|
||||
0x04, 0xf0, 0xf1, 0x99, 0x0b, 0x01, 0x17, 0x0a, 0xde, 0xae, 0xfd, 0x22, 0x93, 0x1d, 0x03, 0x6e,
|
||||
0x31, 0xf1, 0xf4, 0xbf, 0xcc, 0x7a, 0x24, 0x71, 0xf8, 0xf0, 0xd6, 0x98, 0x60, 0x1a, 0xa1, 0xfb,
|
||||
0xfe, 0xa0, 0x5b, 0x4f, 0xcc, 0xf6, 0xe6, 0x7b, 0xf7, 0xbe, 0x60, 0x72, 0x33, 0xb2, 0x83, 0xb8,
|
||||
0x72, 0xe4, 0x98, 0x76, 0xc7, 0x46, 0xaf, 0x8f, 0x8d, 0xbe, 0x6f, 0x8f, 0x2d, 0xde, 0xd7, 0xd0,
|
||||
0x13, 0x44, 0x2e, 0xf0, 0xd1, 0x90, 0x65, 0x77, 0xef, 0xbd, 0xe9, 0xd3, 0x09, 0x9a, 0xbf, 0xfb,
|
||||
0xbd, 0x1a, 0xa3, 0x3f, 0xab, 0x31, 0xfa, 0xbb, 0x1a, 0xa3, 0x8b, 0xd7, 0x45, 0xe9, 0x65, 0x23,
|
||||
0x68, 0xae, 0x2b, 0x66, 0xec, 0x95, 0xab, 0xb8, 0x2f, 0x73, 0xc5, 0x85, 0xeb, 0x22, 0xb6, 0x7d,
|
||||
0xf3, 0x6f, 0xc0, 0x4b, 0xf1, 0x20, 0xe4, 0x5f, 0xfd, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x8a, 0x43,
|
||||
0x60, 0x04, 0x91, 0x03, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
@@ -62,7 +177,7 @@ const _ = grpc.SupportPackageIsVersion4
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type SlasherClient interface {
|
||||
IsSlashableAttestation(ctx context.Context, in *Attestation, opts ...grpc.CallOption) (*AttesterSlashing, error)
|
||||
IsSlashableBlock(ctx context.Context, in *BeaconBlockHeader, opts ...grpc.CallOption) (*ProposerSlashing, error)
|
||||
IsSlashableBlock(ctx context.Context, in *ProposerSlashingRequest, opts ...grpc.CallOption) (*ProposerSlashingResponse, error)
|
||||
SlashableProposals(ctx context.Context, in *types.Empty, opts ...grpc.CallOption) (Slasher_SlashableProposalsClient, error)
|
||||
SlashableAttestations(ctx context.Context, in *types.Empty, opts ...grpc.CallOption) (Slasher_SlashableAttestationsClient, error)
|
||||
}
|
||||
@@ -84,8 +199,8 @@ func (c *slasherClient) IsSlashableAttestation(ctx context.Context, in *Attestat
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *slasherClient) IsSlashableBlock(ctx context.Context, in *BeaconBlockHeader, opts ...grpc.CallOption) (*ProposerSlashing, error) {
|
||||
out := new(ProposerSlashing)
|
||||
func (c *slasherClient) IsSlashableBlock(ctx context.Context, in *ProposerSlashingRequest, opts ...grpc.CallOption) (*ProposerSlashingResponse, error) {
|
||||
out := new(ProposerSlashingResponse)
|
||||
err := c.cc.Invoke(ctx, "/ethereum.eth.v1alpha1.Slasher/IsSlashableBlock", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -160,7 +275,7 @@ func (x *slasherSlashableAttestationsClient) Recv() (*AttesterSlashing, error) {
|
||||
// SlasherServer is the server API for Slasher service.
|
||||
type SlasherServer interface {
|
||||
IsSlashableAttestation(context.Context, *Attestation) (*AttesterSlashing, error)
|
||||
IsSlashableBlock(context.Context, *BeaconBlockHeader) (*ProposerSlashing, error)
|
||||
IsSlashableBlock(context.Context, *ProposerSlashingRequest) (*ProposerSlashingResponse, error)
|
||||
SlashableProposals(*types.Empty, Slasher_SlashableProposalsServer) error
|
||||
SlashableAttestations(*types.Empty, Slasher_SlashableAttestationsServer) error
|
||||
}
|
||||
@@ -188,7 +303,7 @@ func _Slasher_IsSlashableAttestation_Handler(srv interface{}, ctx context.Contex
|
||||
}
|
||||
|
||||
func _Slasher_IsSlashableBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(BeaconBlockHeader)
|
||||
in := new(ProposerSlashingRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -200,7 +315,7 @@ func _Slasher_IsSlashableBlock_Handler(srv interface{}, ctx context.Context, dec
|
||||
FullMethod: "/ethereum.eth.v1alpha1.Slasher/IsSlashableBlock",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SlasherServer).IsSlashableBlock(ctx, req.(*BeaconBlockHeader))
|
||||
return srv.(SlasherServer).IsSlashableBlock(ctx, req.(*ProposerSlashingRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
@@ -274,3 +389,439 @@ var _Slasher_serviceDesc = grpc.ServiceDesc{
|
||||
},
|
||||
Metadata: "proto/eth/v1alpha1/slasher.proto",
|
||||
}
|
||||
|
||||
func (m *ProposerSlashingRequest) 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 *ProposerSlashingRequest) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.BlockHeader != nil {
|
||||
dAtA[i] = 0xa
|
||||
i++
|
||||
i = encodeVarintSlasher(dAtA, i, uint64(m.BlockHeader.Size()))
|
||||
n1, err := m.BlockHeader.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n1
|
||||
}
|
||||
if m.ValidatorIndex != 0 {
|
||||
dAtA[i] = 0x10
|
||||
i++
|
||||
i = encodeVarintSlasher(dAtA, i, uint64(m.ValidatorIndex))
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
i += copy(dAtA[i:], m.XXX_unrecognized)
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (m *ProposerSlashingResponse) 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 *ProposerSlashingResponse) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.ProposerSlashing) > 0 {
|
||||
for _, msg := range m.ProposerSlashing {
|
||||
dAtA[i] = 0xa
|
||||
i++
|
||||
i = encodeVarintSlasher(dAtA, i, uint64(msg.Size()))
|
||||
n, err := msg.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n
|
||||
}
|
||||
}
|
||||
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)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
dAtA[offset] = uint8(v)
|
||||
return offset + 1
|
||||
}
|
||||
func (m *ProposerSlashingRequest) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if m.BlockHeader != nil {
|
||||
l = m.BlockHeader.Size()
|
||||
n += 1 + l + sovSlasher(uint64(l))
|
||||
}
|
||||
if m.ValidatorIndex != 0 {
|
||||
n += 1 + sovSlasher(uint64(m.ValidatorIndex))
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
n += len(m.XXX_unrecognized)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *ProposerSlashingResponse) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.ProposerSlashing) > 0 {
|
||||
for _, e := range m.ProposerSlashing {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovSlasher(uint64(l))
|
||||
}
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
n += len(m.XXX_unrecognized)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovSlasher(x uint64) (n int) {
|
||||
for {
|
||||
n++
|
||||
x >>= 7
|
||||
if x == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
func sozSlasher(x uint64) (n int) {
|
||||
return sovSlasher(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (m *ProposerSlashingRequest) 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: ProposerSlashingRequest: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: ProposerSlashingRequest: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field BlockHeader", 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.BlockHeader == nil {
|
||||
m.BlockHeader = &BeaconBlockHeader{}
|
||||
}
|
||||
if err := m.BlockHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ValidatorIndex", wireType)
|
||||
}
|
||||
m.ValidatorIndex = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowSlasher
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.ValidatorIndex |= uint64(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 *ProposerSlashingResponse) 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: ProposerSlashingResponse: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: ProposerSlashingResponse: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ProposerSlashing", 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
|
||||
}
|
||||
m.ProposerSlashing = append(m.ProposerSlashing, &ProposerSlashing{})
|
||||
if err := m.ProposerSlashing[len(m.ProposerSlashing)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
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
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowSlasher
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowSlasher
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if dAtA[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
return iNdEx, nil
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowSlasher
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthSlasher
|
||||
}
|
||||
iNdEx += length
|
||||
if iNdEx < 0 {
|
||||
return 0, ErrInvalidLengthSlasher
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 3:
|
||||
for {
|
||||
var innerWire uint64
|
||||
var start int = iNdEx
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowSlasher
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
innerWire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
innerWireType := int(innerWire & 0x7)
|
||||
if innerWireType == 4 {
|
||||
break
|
||||
}
|
||||
next, err := skipSlasher(dAtA[start:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
iNdEx = start + next
|
||||
if iNdEx < 0 {
|
||||
return 0, ErrInvalidLengthSlasher
|
||||
}
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 4:
|
||||
return iNdEx, nil
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
return iNdEx, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthSlasher = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowSlasher = fmt.Errorf("proto: integer overflow")
|
||||
)
|
||||
|
||||
@@ -21,7 +21,7 @@ service Slasher {
|
||||
|
||||
// Gets ProposerSlashing container if the block header that
|
||||
// was received produces a slashable event.
|
||||
rpc IsSlashableBlock(ethereum.eth.v1alpha1.BeaconBlockHeader) returns (ethereum.eth.v1alpha1.ProposerSlashing);
|
||||
rpc IsSlashableBlock(ProposerSlashingRequest) returns (ProposerSlashingResponse);
|
||||
|
||||
// Subscription to receive all slashable proposer slashing events found by the watchtower.
|
||||
rpc SlashableProposals(google.protobuf.Empty) returns (stream ethereum.eth.v1alpha1.ProposerSlashing);
|
||||
@@ -29,3 +29,10 @@ service Slasher {
|
||||
// Subscription to receive all slashable attester slashing events found by the watchtower.
|
||||
rpc SlashableAttestations(google.protobuf.Empty) returns (stream ethereum.eth.v1alpha1.AttesterSlashing);
|
||||
}
|
||||
message ProposerSlashingRequest {
|
||||
ethereum.eth.v1alpha1.BeaconBlockHeader block_header=1;
|
||||
uint64 validator_index=2;
|
||||
}
|
||||
message ProposerSlashingResponse {
|
||||
repeated ethereum.eth.v1alpha1.ProposerSlashing proposer_slashing=1;
|
||||
}
|
||||
30
slasher/BUILD.bazel
Normal file
30
slasher/BUILD.bazel
Normal file
@@ -0,0 +1,30 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["service.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/slasher",
|
||||
visibility = ["//slasher:__subpackages__"],
|
||||
deps = [
|
||||
"//slasher/db:go_default_library",
|
||||
"@com_github_grpc_ecosystem_go_grpc_middleware//:go_default_library",
|
||||
"@com_github_grpc_ecosystem_go_grpc_middleware//recovery:go_default_library",
|
||||
"@com_github_grpc_ecosystem_go_grpc_prometheus//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@io_opencensus_go//plugin/ocgrpc:go_default_library",
|
||||
"@org_golang_google_grpc//:go_default_library",
|
||||
"@org_golang_google_grpc//credentials:go_default_library",
|
||||
"@org_golang_google_grpc//reflection:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["service_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//shared/testutil:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
||||
],
|
||||
)
|
||||
@@ -6,6 +6,7 @@ go_library(
|
||||
"block_header.go",
|
||||
"db.go",
|
||||
"schema.go",
|
||||
"setup_db.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/slasher/db",
|
||||
visibility = ["//slasher:__subpackages__"],
|
||||
@@ -24,11 +25,8 @@ go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"block_header_test.go",
|
||||
"db_test.go",
|
||||
"setup_db_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//shared/testutil:go_default_library",
|
||||
],
|
||||
deps = ["//proto/eth/v1alpha1:go_default_library"],
|
||||
)
|
||||
|
||||
@@ -23,7 +23,7 @@ func createBlockHeader(enc []byte) (*ethpb.BeaconBlockHeader, error) {
|
||||
// BlockHeader accepts an epoch and validator id and returns the corresponding block header array.
|
||||
// Returns nil if the block header for those values does not exist.
|
||||
func (db *Store) BlockHeader(epoch uint64, validatorID uint64) ([]*ethpb.BeaconBlockHeader, error) {
|
||||
var bha []*ethpb.BeaconBlockHeader
|
||||
var blockHeaders []*ethpb.BeaconBlockHeader
|
||||
err := db.view(func(tx *bolt.Tx) error {
|
||||
c := tx.Bucket(historicBlockHeadersBucket).Cursor()
|
||||
prefix := encodeEpochValidatorID(epoch, validatorID)
|
||||
@@ -32,11 +32,11 @@ func (db *Store) BlockHeader(epoch uint64, validatorID uint64) ([]*ethpb.BeaconB
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bha = append(bha, bh)
|
||||
blockHeaders = append(blockHeaders, bh)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return bha, err
|
||||
return blockHeaders, err
|
||||
}
|
||||
|
||||
// HasBlockHeader accepts an epoch and validator id and returns true if the block header exists.
|
||||
@@ -76,7 +76,7 @@ func (db *Store) SaveBlockHeader(epoch uint64, validatorID uint64, blockHeader *
|
||||
|
||||
// prune history to max size every 10th epoch
|
||||
if epoch%params.BeaconConfig().PruneSlasherStoragePeriod == 0 {
|
||||
err = db.pruneHistory(epoch, params.BeaconConfig().WeakSubjectivityPeriod)
|
||||
err = db.PruneHistory(epoch, params.BeaconConfig().WeakSubjectivityPeriod)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -95,7 +95,8 @@ func (db *Store) DeleteBlockHeader(epoch uint64, validatorID uint64, blockHeader
|
||||
})
|
||||
}
|
||||
|
||||
func (db *Store) pruneHistory(currentEpoch uint64, historySize uint64) error {
|
||||
// PruneHistory leaves only records younger then history size.
|
||||
func (db *Store) PruneHistory(currentEpoch uint64, historySize uint64) error {
|
||||
pruneTill := int64(currentEpoch) - int64(historySize)
|
||||
if pruneTill <= 0 {
|
||||
return nil
|
||||
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
)
|
||||
|
||||
func TestNilDBHistoryBlkHdr(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
defer teardownDB(t, db)
|
||||
db := SetupSlasherDB(t)
|
||||
defer TeardownSlasherDB(t, db)
|
||||
|
||||
epoch := uint64(1)
|
||||
validatorID := uint64(1)
|
||||
@@ -29,8 +29,8 @@ func TestNilDBHistoryBlkHdr(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSaveHistoryBlkHdr(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
defer teardownDB(t, db)
|
||||
db := SetupSlasherDB(t)
|
||||
defer TeardownSlasherDB(t, db)
|
||||
tests := []struct {
|
||||
epoch uint64
|
||||
vID uint64
|
||||
@@ -72,8 +72,8 @@ func TestSaveHistoryBlkHdr(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDeleteHistoryBlkHdr(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
defer teardownDB(t, db)
|
||||
db := SetupSlasherDB(t)
|
||||
defer TeardownSlasherDB(t, db)
|
||||
tests := []struct {
|
||||
epoch uint64
|
||||
vID uint64
|
||||
@@ -130,8 +130,8 @@ func TestDeleteHistoryBlkHdr(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHasHistoryBlkHdr(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
defer teardownDB(t, db)
|
||||
db := SetupSlasherDB(t)
|
||||
defer TeardownSlasherDB(t, db)
|
||||
tests := []struct {
|
||||
epoch uint64
|
||||
vID uint64
|
||||
@@ -179,8 +179,8 @@ func TestHasHistoryBlkHdr(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPruneHistoryBlkHdr(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
defer teardownDB(t, db)
|
||||
db := SetupSlasherDB(t)
|
||||
defer TeardownSlasherDB(t, db)
|
||||
tests := []struct {
|
||||
epoch uint64
|
||||
vID uint64
|
||||
@@ -230,7 +230,7 @@ func TestPruneHistoryBlkHdr(t *testing.T) {
|
||||
}
|
||||
currentEpoch := uint64(3)
|
||||
historyToKeep := uint64(2)
|
||||
err := db.pruneHistory(currentEpoch, historyToKeep)
|
||||
err := db.PruneHistory(currentEpoch, historyToKeep)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to prune: %v", err)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
@@ -11,16 +10,7 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var log = logrus.WithField("prefix", "beacondb")
|
||||
|
||||
// Database defines the necessary methods for slasher service which may
|
||||
// be implemented by any key-value or relational database in practice.
|
||||
type Database interface {
|
||||
io.Closer
|
||||
DatabasePath() string
|
||||
|
||||
ClearDB() error
|
||||
}
|
||||
var log = logrus.WithField("prefix", "slasherDB")
|
||||
|
||||
// Store defines an implementation of the Prysm Database interface
|
||||
// using BoltDB as the underlying persistent kv-store for eth2.
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
)
|
||||
|
||||
var _ = Database(&Store{})
|
||||
|
||||
// setupDB instantiates and returns a SlasherDB instance.
|
||||
func setupDB(t testing.TB) *Store {
|
||||
|
||||
randPath, err := rand.Int(rand.Reader, big.NewInt(1000000))
|
||||
if err != nil {
|
||||
t.Fatalf("Could not generate random file path: %v", err)
|
||||
}
|
||||
path := path.Join(testutil.TempDir(), fmt.Sprintf("/%d", randPath))
|
||||
if err := os.RemoveAll(path); err != nil {
|
||||
t.Fatalf("Failed to remove directory: %v", err)
|
||||
}
|
||||
db, err := NewDB(path)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to instantiate DB: %v", err)
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
||||
// teardownDB cleans up a test BeaconDB instance.
|
||||
func teardownDB(t testing.TB, db *Store) {
|
||||
if err := db.Close(); err != nil {
|
||||
t.Fatalf("Failed to close database: %v", err)
|
||||
}
|
||||
if err := os.RemoveAll(db.DatabasePath()); err != nil {
|
||||
t.Fatalf("Failed to remove directory: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClearDB(t *testing.T) {
|
||||
slasherDB := setupDB(t)
|
||||
if err := slasherDB.ClearDB(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(slasherDB.DatabasePath()); !os.IsNotExist(err) {
|
||||
t.Fatalf("db wasnt cleared %v", err)
|
||||
}
|
||||
}
|
||||
49
slasher/db/setup_db.go
Normal file
49
slasher/db/setup_db.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// SetupSlasherDB instantiates and returns a SlasherDB instance.
|
||||
func SetupSlasherDB(t testing.TB) *Store {
|
||||
randPath, err := rand.Int(rand.Reader, big.NewInt(1000000))
|
||||
if err != nil {
|
||||
t.Fatalf("Could not generate random file path: %v", err)
|
||||
}
|
||||
p := path.Join(TempDir(), fmt.Sprintf("/%d", randPath))
|
||||
if err := os.RemoveAll(p); err != nil {
|
||||
t.Fatalf("Failed to remove directory: %v", err)
|
||||
}
|
||||
db, err := NewDB(p)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to instantiate DB: %v", err)
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
||||
// TempDir returns a directory path for temporary test storage.
|
||||
func TempDir() string {
|
||||
d := os.Getenv("TEST_TMPDIR")
|
||||
|
||||
// If the test is not run via bazel, the environment var won't be set.
|
||||
if d == "" {
|
||||
return os.TempDir()
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
// TeardownSlasherDB cleans up a test BeaconDB instance.
|
||||
func TeardownSlasherDB(t testing.TB, db *Store) {
|
||||
if err := db.Close(); err != nil {
|
||||
t.Fatalf("Failed to close database: %v", err)
|
||||
}
|
||||
if err := os.RemoveAll(db.DatabasePath()); err != nil {
|
||||
t.Fatalf("Failed to remove directory: %v", err)
|
||||
}
|
||||
}
|
||||
18
slasher/db/setup_db_test.go
Normal file
18
slasher/db/setup_db_test.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestClearDB(t *testing.T) {
|
||||
slasherDB := SetupSlasherDB(t)
|
||||
defer TeardownSlasherDB(t, slasherDB)
|
||||
if err := slasherDB.ClearDB(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(slasherDB.DatabasePath()); !os.IsNotExist(err) {
|
||||
t.Fatalf("db wasnt cleared %v", err)
|
||||
}
|
||||
}
|
||||
120
slasher/service.go
Normal file
120
slasher/service.go
Normal file
@@ -0,0 +1,120 @@
|
||||
// Package slasher defines the service used to retrieve slashings proofs.
|
||||
package slasher
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||
recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
|
||||
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
||||
"github.com/prysmaticlabs/prysm/slasher/db"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/plugin/ocgrpc"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/reflection"
|
||||
)
|
||||
|
||||
var log logrus.FieldLogger
|
||||
|
||||
func init() {
|
||||
log = logrus.WithField("prefix", "slasherRPC")
|
||||
}
|
||||
|
||||
// Service defining an RPC server for the slasher service.
|
||||
type Service struct {
|
||||
slasherDb *db.Store
|
||||
grpcServer *grpc.Server
|
||||
port string
|
||||
withCert string
|
||||
withKey string
|
||||
listener net.Listener
|
||||
credentialError error
|
||||
failStatus error
|
||||
}
|
||||
|
||||
// Config options for the slasher server.
|
||||
type Config struct {
|
||||
Port string
|
||||
CertFlag string
|
||||
KeyFlag string
|
||||
SlasherDb *db.Store
|
||||
}
|
||||
|
||||
// NewRPCService creates a new instance of a struct implementing the SlasherService
|
||||
// interface.
|
||||
func NewRPCService(cfg *Config) *Service {
|
||||
return &Service{
|
||||
slasherDb: cfg.SlasherDb,
|
||||
port: cfg.Port,
|
||||
}
|
||||
}
|
||||
|
||||
// Start the gRPC server.
|
||||
func (s *Service) Start() {
|
||||
log.Info("Starting service on port: %v", s.port)
|
||||
lis, err := net.Listen("tcp", fmt.Sprintf(":%s", s.port))
|
||||
if err != nil {
|
||||
log.Errorf("Could not listen to port in Start() :%s: %v", s.port, err)
|
||||
}
|
||||
s.listener = lis
|
||||
log.WithField("port", s.port).Info("Listening on port")
|
||||
|
||||
opts := []grpc.ServerOption{
|
||||
grpc.StatsHandler(&ocgrpc.ServerHandler{}),
|
||||
grpc.StreamInterceptor(middleware.ChainStreamServer(
|
||||
recovery.StreamServerInterceptor(),
|
||||
grpc_prometheus.StreamServerInterceptor,
|
||||
)),
|
||||
grpc.UnaryInterceptor(middleware.ChainUnaryServer(
|
||||
recovery.UnaryServerInterceptor(),
|
||||
grpc_prometheus.UnaryServerInterceptor,
|
||||
)),
|
||||
}
|
||||
// TODO(#791): Utilize a certificate for secure connections
|
||||
// between beacon nodes and validator clients.
|
||||
if s.withCert != "" && s.withKey != "" {
|
||||
creds, err := credentials.NewServerTLSFromFile(s.withCert, s.withKey)
|
||||
if err != nil {
|
||||
log.Errorf("Could not load TLS keys: %s", err)
|
||||
s.credentialError = err
|
||||
}
|
||||
opts = append(opts, grpc.Creds(creds))
|
||||
} else {
|
||||
log.Warn("You are using an insecure gRPC connection! Provide a certificate and key to connect securely")
|
||||
}
|
||||
s.grpcServer = grpc.NewServer(opts...)
|
||||
|
||||
// Register reflection service on gRPC server.
|
||||
reflection.Register(s.grpcServer)
|
||||
|
||||
go func() {
|
||||
if s.listener != nil {
|
||||
if err := s.grpcServer.Serve(s.listener); err != nil {
|
||||
log.Errorf("Could not serve gRPC: %v", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Stop the service.
|
||||
func (s *Service) Stop() error {
|
||||
log.Info("Stopping service")
|
||||
if s.listener != nil {
|
||||
s.grpcServer.GracefulStop()
|
||||
log.Debug("Initiated graceful stop of gRPC server")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Status returns nil, credentialError or fail status.
|
||||
func (s *Service) Status() error {
|
||||
if s.credentialError != nil {
|
||||
return s.credentialError
|
||||
}
|
||||
if s.failStatus != nil {
|
||||
return s.failStatus
|
||||
}
|
||||
return nil
|
||||
}
|
||||
79
slasher/service_test.go
Normal file
79
slasher/service_test.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package slasher
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/sirupsen/logrus"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
|
||||
func init() {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
logrus.SetOutput(ioutil.Discard)
|
||||
}
|
||||
|
||||
func TestLifecycle_OK(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
rpcService := NewRPCService(&Config{
|
||||
Port: "7348",
|
||||
CertFlag: "alice.crt",
|
||||
KeyFlag: "alice.key",
|
||||
})
|
||||
|
||||
rpcService.Start()
|
||||
|
||||
testutil.AssertLogsContain(t, hook, "Starting service")
|
||||
testutil.AssertLogsContain(t, hook, "Listening on port")
|
||||
|
||||
rpcService.Stop()
|
||||
testutil.AssertLogsContain(t, hook, "Stopping service")
|
||||
|
||||
}
|
||||
|
||||
func TestRPC_BadEndpoint(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
|
||||
rpcService := NewRPCService(&Config{
|
||||
Port: "ralph merkle!!!",
|
||||
})
|
||||
|
||||
testutil.AssertLogsDoNotContain(t, hook, "Could not listen to port in Start()")
|
||||
testutil.AssertLogsDoNotContain(t, hook, "Could not load TLS keys")
|
||||
testutil.AssertLogsDoNotContain(t, hook, "Could not serve gRPC")
|
||||
|
||||
rpcService.Start()
|
||||
|
||||
testutil.AssertLogsContain(t, hook, "Starting service")
|
||||
testutil.AssertLogsContain(t, hook, "Could not listen to port in Start()")
|
||||
|
||||
rpcService.Stop()
|
||||
}
|
||||
|
||||
func TestStatus_CredentialError(t *testing.T) {
|
||||
credentialErr := errors.New("credentialError")
|
||||
s := &Service{credentialError: credentialErr}
|
||||
|
||||
if err := s.Status(); err != s.credentialError {
|
||||
t.Errorf("Wanted: %v, got: %v", s.credentialError, s.Status())
|
||||
}
|
||||
}
|
||||
|
||||
func TestRPC_InsecureEndpoint(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
rpcService := NewRPCService(&Config{
|
||||
Port: "7777",
|
||||
})
|
||||
|
||||
rpcService.Start()
|
||||
|
||||
testutil.AssertLogsContain(t, hook, "Starting service")
|
||||
testutil.AssertLogsContain(t, hook, fmt.Sprint("Listening on port"))
|
||||
testutil.AssertLogsContain(t, hook, "You are using an insecure gRPC connection")
|
||||
|
||||
rpcService.Stop()
|
||||
testutil.AssertLogsContain(t, hook, "Stopping service")
|
||||
}
|
||||
Reference in New Issue
Block a user