No sig slasher rpc (#6174)

* detect slashable attestations and blocks without db update
* lint fixes
* fix mock
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* preston feedback
* Merge branch 'no_sig_slasher_rpc' of github.com:prysmaticlabs/prysm into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* nishant and ivan feedback
* Merge branch 'no_sig_slasher_rpc' of github.com:prysmaticlabs/prysm into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Merge refs/heads/master into no_sig_slasher_rpc
* Apply suggestions from code review
This commit is contained in:
Shay Zluf
2020-06-11 21:50:12 +03:00
committed by GitHub
parent ec6309a928
commit 898cd8b42b
10 changed files with 648 additions and 54 deletions

View File

@@ -77,6 +77,53 @@ func (m *ProposerSlashingResponse) GetProposerSlashing() []*v1alpha1.ProposerSla
return nil
}
type Slashable struct {
Slashable bool `protobuf:"varint,1,opt,name=slashable,proto3" json:"slashable,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Slashable) Reset() { *m = Slashable{} }
func (m *Slashable) String() string { return proto.CompactTextString(m) }
func (*Slashable) ProtoMessage() {}
func (*Slashable) Descriptor() ([]byte, []int) {
return fileDescriptor_da7e95107d0081b4, []int{1}
}
func (m *Slashable) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Slashable) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Slashable.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Slashable) XXX_Merge(src proto.Message) {
xxx_messageInfo_Slashable.Merge(m, src)
}
func (m *Slashable) XXX_Size() int {
return m.Size()
}
func (m *Slashable) XXX_DiscardUnknown() {
xxx_messageInfo_Slashable.DiscardUnknown(m)
}
var xxx_messageInfo_Slashable proto.InternalMessageInfo
func (m *Slashable) GetSlashable() bool {
if m != nil {
return m.Slashable
}
return false
}
type AttesterSlashingResponse struct {
AttesterSlashing []*v1alpha1.AttesterSlashing `protobuf:"bytes,1,rep,name=attester_slashing,json=attesterSlashing,proto3" json:"attester_slashing,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
@@ -88,7 +135,7 @@ func (m *AttesterSlashingResponse) Reset() { *m = AttesterSlashingRespon
func (m *AttesterSlashingResponse) String() string { return proto.CompactTextString(m) }
func (*AttesterSlashingResponse) ProtoMessage() {}
func (*AttesterSlashingResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_da7e95107d0081b4, []int{1}
return fileDescriptor_da7e95107d0081b4, []int{2}
}
func (m *AttesterSlashingResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -136,7 +183,7 @@ func (m *ProposalHistory) Reset() { *m = ProposalHistory{} }
func (m *ProposalHistory) String() string { return proto.CompactTextString(m) }
func (*ProposalHistory) ProtoMessage() {}
func (*ProposalHistory) Descriptor() ([]byte, []int) {
return fileDescriptor_da7e95107d0081b4, []int{2}
return fileDescriptor_da7e95107d0081b4, []int{3}
}
func (m *ProposalHistory) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -191,7 +238,7 @@ func (m *AttestationHistory) Reset() { *m = AttestationHistory{} }
func (m *AttestationHistory) String() string { return proto.CompactTextString(m) }
func (*AttestationHistory) ProtoMessage() {}
func (*AttestationHistory) Descriptor() ([]byte, []int) {
return fileDescriptor_da7e95107d0081b4, []int{3}
return fileDescriptor_da7e95107d0081b4, []int{4}
}
func (m *AttestationHistory) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -236,6 +283,7 @@ func (m *AttestationHistory) GetLatestEpochWritten() uint64 {
func init() {
proto.RegisterType((*ProposerSlashingResponse)(nil), "ethereum.slashing.ProposerSlashingResponse")
proto.RegisterType((*Slashable)(nil), "ethereum.slashing.Slashable")
proto.RegisterType((*AttesterSlashingResponse)(nil), "ethereum.slashing.AttesterSlashingResponse")
proto.RegisterType((*ProposalHistory)(nil), "ethereum.slashing.ProposalHistory")
proto.RegisterType((*AttestationHistory)(nil), "ethereum.slashing.AttestationHistory")
@@ -245,38 +293,41 @@ func init() {
func init() { proto.RegisterFile("proto/slashing/slashing.proto", fileDescriptor_da7e95107d0081b4) }
var fileDescriptor_da7e95107d0081b4 = []byte{
// 483 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xc1, 0x6e, 0xd3, 0x40,
0x10, 0xd5, 0xb6, 0x05, 0xc4, 0x52, 0x41, 0xba, 0x54, 0x28, 0x8a, 0x44, 0x1a, 0xe5, 0x42, 0x10,
0x74, 0xdd, 0x96, 0x0b, 0x70, 0xab, 0xa5, 0x4a, 0xed, 0x09, 0xe4, 0x44, 0xe2, 0x68, 0xad, 0xed,
0xa9, 0xbd, 0xea, 0xc6, 0xbb, 0xda, 0x1d, 0x17, 0xf2, 0x1f, 0x7c, 0x14, 0x47, 0xbe, 0x00, 0xa1,
0x9c, 0x11, 0x1f, 0xc0, 0x09, 0x79, 0xed, 0x54, 0xa1, 0x49, 0x24, 0x7a, 0x9b, 0x99, 0x37, 0xf3,
0xde, 0xf3, 0x78, 0x87, 0x3e, 0x37, 0x56, 0xa3, 0x0e, 0x9c, 0x12, 0xae, 0x90, 0x65, 0x7e, 0x13,
0x70, 0x5f, 0x67, 0x7b, 0x80, 0x05, 0x58, 0xa8, 0xa6, 0x7c, 0x01, 0xf4, 0x0e, 0x00, 0x8b, 0xe0,
0xfa, 0x58, 0x28, 0x53, 0x88, 0xe3, 0x20, 0x01, 0x91, 0xea, 0x32, 0x4e, 0x94, 0x4e, 0xaf, 0x9a,
0x99, 0xde, 0x61, 0x2e, 0xb1, 0xa8, 0x12, 0x9e, 0xea, 0x69, 0x90, 0xeb, 0x5c, 0x07, 0xbe, 0x9c,
0x54, 0x97, 0x3e, 0x6b, 0xf4, 0xea, 0xa8, 0x69, 0x1f, 0x1a, 0xda, 0xfd, 0x68, 0xb5, 0xd1, 0x0e,
0xec, 0xb8, 0xd5, 0x88, 0xc0, 0x19, 0x5d, 0x3a, 0x60, 0x13, 0xba, 0x67, 0x5a, 0x2c, 0x5e, 0x18,
0xe8, 0x92, 0xc1, 0xf6, 0xe8, 0xd1, 0xc9, 0x0b, 0x7e, 0x63, 0x0d, 0xb0, 0xe0, 0x0b, 0x43, 0x7c,
0x85, 0xab, 0x63, 0x6e, 0x55, 0x6a, 0xc5, 0x53, 0x44, 0x70, 0xb8, 0x5e, 0x51, 0xb4, 0xd8, 0xff,
0x2a, 0xae, 0x70, 0x75, 0xc4, 0xad, 0xca, 0xf0, 0x2b, 0xa1, 0x4f, 0x1a, 0x63, 0x42, 0x9d, 0x4b,
0x87, 0xda, 0xce, 0xd8, 0x07, 0x4a, 0xc1, 0xe8, 0xb4, 0x88, 0x13, 0x89, 0xae, 0x4b, 0x06, 0x64,
0xb4, 0x1b, 0x1e, 0xfd, 0xf9, 0x71, 0xf0, 0x7a, 0x69, 0x7d, 0xc6, 0xce, 0xdc, 0x54, 0xa0, 0x4c,
0x95, 0x48, 0x5c, 0x90, 0xeb, 0xc3, 0x44, 0xe2, 0xa5, 0x04, 0x95, 0xf1, 0x50, 0xa2, 0x92, 0x0e,
0xa3, 0x87, 0x9e, 0x23, 0x94, 0xe8, 0xd8, 0x11, 0xdd, 0x57, 0xa2, 0x16, 0x8e, 0x1b, 0xde, 0xcf,
0x56, 0x22, 0x42, 0xd9, 0xdd, 0x1a, 0x90, 0xd1, 0x4e, 0xc4, 0x1a, 0xec, 0xac, 0x86, 0x3e, 0x35,
0xc8, 0xf0, 0x37, 0xa1, 0xac, 0x71, 0x2f, 0x50, 0xea, 0x72, 0xe1, 0x2c, 0xa5, 0x1d, 0x14, 0x36,
0x07, 0x8c, 0x51, 0xc7, 0x4e, 0x57, 0x36, 0x85, 0x76, 0x05, 0xef, 0xf8, 0xca, 0x7b, 0xe0, 0xab,
0x04, 0x7c, 0xe2, 0xa7, 0x27, 0x7a, 0xec, 0x67, 0xcf, 0x4a, 0xb4, 0xb3, 0xe8, 0x31, 0xfe, 0x53,
0xbc, 0xbb, 0xdb, 0xde, 0x29, 0x7d, 0xba, 0x86, 0x98, 0x75, 0xe8, 0xf6, 0x15, 0xcc, 0xfc, 0x02,
0x77, 0xa2, 0x3a, 0x64, 0xfb, 0xf4, 0xde, 0xb5, 0x50, 0x15, 0xb4, 0x5c, 0x4d, 0xf2, 0x7e, 0xeb,
0x2d, 0x39, 0xf9, 0x45, 0xe8, 0x03, 0xff, 0x53, 0xc0, 0x32, 0x43, 0x9f, 0x5d, 0x38, 0x9f, 0x88,
0x44, 0xc1, 0xd2, 0x57, 0xb0, 0x97, 0x1b, 0x7e, 0xf4, 0x45, 0x99, 0xc1, 0x17, 0xc8, 0x96, 0x5a,
0x7b, 0xaf, 0x36, 0x2e, 0x64, 0xcd, 0xdb, 0xd2, 0xb4, 0xb3, 0xa4, 0x18, 0xd6, 0x27, 0xc3, 0xf8,
0x06, 0xad, 0xb1, 0xcc, 0x4b, 0xc8, 0x42, 0x7f, 0x5d, 0xbe, 0xf3, 0x1c, 0x44, 0x06, 0x76, 0xad,
0xe0, 0xa6, 0xf3, 0x09, 0x77, 0xbf, 0xcd, 0xfb, 0xe4, 0xfb, 0xbc, 0x4f, 0x7e, 0xce, 0xfb, 0x24,
0xb9, 0xef, 0xef, 0xed, 0xcd, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x11, 0xe3, 0x4b, 0x92, 0xf3,
0x03, 0x00, 0x00,
// 537 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcd, 0x6e, 0xd3, 0x40,
0x10, 0x96, 0xdb, 0xf2, 0x93, 0xa5, 0x82, 0x74, 0xa9, 0x50, 0x14, 0x95, 0x34, 0xca, 0x85, 0x54,
0xd0, 0x75, 0x5b, 0x2e, 0xc0, 0xad, 0x96, 0x2a, 0xb5, 0x17, 0x40, 0x4e, 0x10, 0x47, 0x6b, 0x6d,
0x4f, 0xed, 0x55, 0x1d, 0xef, 0x6a, 0x77, 0x52, 0xc8, 0x7b, 0xf0, 0x36, 0xbc, 0x00, 0x47, 0x9e,
0x00, 0xa1, 0x3c, 0x00, 0x0f, 0xc0, 0x09, 0x79, 0x9d, 0xa4, 0x21, 0xb1, 0x11, 0xbd, 0xcd, 0xce,
0xec, 0x7e, 0x3f, 0xe3, 0x19, 0x93, 0xa7, 0x4a, 0x4b, 0x94, 0xae, 0xc9, 0xb8, 0x49, 0x45, 0x9e,
0x2c, 0x02, 0x66, 0xf3, 0x74, 0x07, 0x30, 0x05, 0x0d, 0xe3, 0x11, 0x9b, 0x17, 0xda, 0xfb, 0x80,
0xa9, 0x7b, 0x7d, 0xcc, 0x33, 0x95, 0xf2, 0x63, 0x37, 0x04, 0x1e, 0xc9, 0x3c, 0x08, 0x33, 0x19,
0x5d, 0x95, 0x6f, 0xda, 0x87, 0x89, 0xc0, 0x74, 0x1c, 0xb2, 0x48, 0x8e, 0xdc, 0x44, 0x26, 0xd2,
0xb5, 0xe9, 0x70, 0x7c, 0x69, 0x4f, 0x25, 0x5f, 0x11, 0x95, 0xd7, 0x7b, 0x8a, 0xb4, 0xde, 0x6b,
0xa9, 0xa4, 0x01, 0x3d, 0x98, 0x71, 0xf8, 0x60, 0x94, 0xcc, 0x0d, 0xd0, 0x21, 0xd9, 0x51, 0xb3,
0x5a, 0x30, 0x17, 0xd0, 0x72, 0xba, 0x9b, 0xfd, 0x07, 0x27, 0xcf, 0xd8, 0x42, 0x1a, 0x60, 0xca,
0xe6, 0x82, 0xd8, 0x1a, 0x56, 0x53, 0xad, 0x64, 0x7a, 0x07, 0xa4, 0x61, 0x63, 0x1e, 0x66, 0x40,
0xf7, 0x48, 0xc3, 0xcc, 0x0f, 0x2d, 0xa7, 0xeb, 0xf4, 0xef, 0xfb, 0x37, 0x89, 0x42, 0xdc, 0x29,
0x22, 0x18, 0xac, 0x16, 0xc7, 0x67, 0xb5, 0xff, 0x15, 0xb7, 0x86, 0xd5, 0xe4, 0x2b, 0x99, 0xde,
0x17, 0x87, 0x3c, 0x2a, 0x3d, 0xf0, 0xec, 0x5c, 0x18, 0x94, 0x7a, 0x42, 0xdf, 0x11, 0x02, 0x4a,
0x46, 0x69, 0x10, 0x0a, 0x34, 0x56, 0xe4, 0xb6, 0x77, 0xf4, 0xfb, 0xc7, 0xfe, 0x8b, 0xa5, 0x4e,
0x2b, 0x3d, 0x31, 0x23, 0x8e, 0x22, 0xca, 0x78, 0x68, 0xdc, 0x44, 0x1e, 0x86, 0x02, 0x2f, 0x05,
0x64, 0x31, 0xf3, 0x04, 0x66, 0xc2, 0xa0, 0xdf, 0xb0, 0x18, 0x9e, 0x40, 0x43, 0x8f, 0xc8, 0x6e,
0xc6, 0x0b, 0xe2, 0xa0, 0xc4, 0xfd, 0xa4, 0x05, 0x22, 0xe4, 0xad, 0x8d, 0xae, 0xd3, 0xdf, 0xf2,
0x69, 0x59, 0x3b, 0x2b, 0x4a, 0x1f, 0xcb, 0x4a, 0xef, 0x97, 0x43, 0x68, 0xa9, 0x9e, 0xa3, 0x90,
0xf9, 0x5c, 0x59, 0x44, 0x9a, 0xc8, 0x75, 0x02, 0x18, 0xa0, 0x0c, 0x8c, 0x1c, 0xeb, 0x08, 0x66,
0x2d, 0x78, 0xcd, 0xd6, 0x46, 0x87, 0xad, 0x03, 0xb0, 0xa1, 0x7d, 0x3d, 0x94, 0x03, 0xfb, 0xf6,
0x2c, 0x47, 0x3d, 0xf1, 0x1f, 0xe2, 0x5f, 0xc9, 0xdb, 0xab, 0x6d, 0x9f, 0x92, 0xc7, 0x15, 0xc0,
0xb4, 0x49, 0x36, 0xaf, 0x60, 0x62, 0x1b, 0xb8, 0xe5, 0x17, 0x21, 0xdd, 0x25, 0x77, 0xae, 0x79,
0x36, 0x86, 0x19, 0x56, 0x79, 0x78, 0xb3, 0xf1, 0xca, 0x39, 0xf9, 0xba, 0x49, 0xee, 0xd9, 0x8f,
0x02, 0x9a, 0x2a, 0xf2, 0xe4, 0xc2, 0x2c, 0x46, 0x66, 0xc9, 0x05, 0x3d, 0xa8, 0xf9, 0xd0, 0x17,
0x79, 0x0c, 0x9f, 0x21, 0x5e, 0xba, 0xda, 0x7e, 0x5e, 0xdb, 0x90, 0x8a, 0xd9, 0x92, 0xa4, 0xb9,
0xc4, 0xe8, 0x15, 0xdb, 0x45, 0x59, 0x0d, 0xd7, 0x40, 0x24, 0x39, 0xc4, 0x9e, 0x5d, 0x44, 0x7b,
0xf3, 0x1c, 0x78, 0x0c, 0xba, 0x92, 0xb0, 0x76, 0xd3, 0x04, 0xe9, 0x54, 0x5b, 0x7c, 0x2b, 0x3f,
0xa8, 0x98, 0x23, 0xdc, 0xc6, 0xea, 0x5e, 0x05, 0xf3, 0xcd, 0xc6, 0x85, 0xa4, 0xb5, 0xea, 0x6d,
0x41, 0xd2, 0xaf, 0x21, 0x59, 0x77, 0xf7, 0x4f, 0x0e, 0x6f, 0xfb, 0xdb, 0xb4, 0xe3, 0x7c, 0x9f,
0x76, 0x9c, 0x9f, 0xd3, 0x8e, 0x13, 0xde, 0xb5, 0x7f, 0x9a, 0x97, 0x7f, 0x02, 0x00, 0x00, 0xff,
0xff, 0x2a, 0xff, 0x62, 0x56, 0xed, 0x04, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -293,6 +344,8 @@ const _ = grpc.SupportPackageIsVersion4
type SlasherClient interface {
IsSlashableAttestation(ctx context.Context, in *v1alpha1.IndexedAttestation, opts ...grpc.CallOption) (*AttesterSlashingResponse, error)
IsSlashableBlock(ctx context.Context, in *v1alpha1.SignedBeaconBlockHeader, opts ...grpc.CallOption) (*ProposerSlashingResponse, error)
IsSlashableAttestationNoUpdate(ctx context.Context, in *v1alpha1.IndexedAttestation, opts ...grpc.CallOption) (*Slashable, error)
IsSlashableBlockNoUpdate(ctx context.Context, in *v1alpha1.BeaconBlockHeader, opts ...grpc.CallOption) (*Slashable, error)
}
type slasherClient struct {
@@ -321,10 +374,30 @@ func (c *slasherClient) IsSlashableBlock(ctx context.Context, in *v1alpha1.Signe
return out, nil
}
func (c *slasherClient) IsSlashableAttestationNoUpdate(ctx context.Context, in *v1alpha1.IndexedAttestation, opts ...grpc.CallOption) (*Slashable, error) {
out := new(Slashable)
err := c.cc.Invoke(ctx, "/ethereum.slashing.Slasher/IsSlashableAttestationNoUpdate", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *slasherClient) IsSlashableBlockNoUpdate(ctx context.Context, in *v1alpha1.BeaconBlockHeader, opts ...grpc.CallOption) (*Slashable, error) {
out := new(Slashable)
err := c.cc.Invoke(ctx, "/ethereum.slashing.Slasher/IsSlashableBlockNoUpdate", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// SlasherServer is the server API for Slasher service.
type SlasherServer interface {
IsSlashableAttestation(context.Context, *v1alpha1.IndexedAttestation) (*AttesterSlashingResponse, error)
IsSlashableBlock(context.Context, *v1alpha1.SignedBeaconBlockHeader) (*ProposerSlashingResponse, error)
IsSlashableAttestationNoUpdate(context.Context, *v1alpha1.IndexedAttestation) (*Slashable, error)
IsSlashableBlockNoUpdate(context.Context, *v1alpha1.BeaconBlockHeader) (*Slashable, error)
}
// UnimplementedSlasherServer can be embedded to have forward compatible implementations.
@@ -337,6 +410,12 @@ func (*UnimplementedSlasherServer) IsSlashableAttestation(ctx context.Context, r
func (*UnimplementedSlasherServer) IsSlashableBlock(ctx context.Context, req *v1alpha1.SignedBeaconBlockHeader) (*ProposerSlashingResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method IsSlashableBlock not implemented")
}
func (*UnimplementedSlasherServer) IsSlashableAttestationNoUpdate(ctx context.Context, req *v1alpha1.IndexedAttestation) (*Slashable, error) {
return nil, status.Errorf(codes.Unimplemented, "method IsSlashableAttestationNoUpdate not implemented")
}
func (*UnimplementedSlasherServer) IsSlashableBlockNoUpdate(ctx context.Context, req *v1alpha1.BeaconBlockHeader) (*Slashable, error) {
return nil, status.Errorf(codes.Unimplemented, "method IsSlashableBlockNoUpdate not implemented")
}
func RegisterSlasherServer(s *grpc.Server, srv SlasherServer) {
s.RegisterService(&_Slasher_serviceDesc, srv)
@@ -378,6 +457,42 @@ func _Slasher_IsSlashableBlock_Handler(srv interface{}, ctx context.Context, dec
return interceptor(ctx, in, info, handler)
}
func _Slasher_IsSlashableAttestationNoUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(v1alpha1.IndexedAttestation)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SlasherServer).IsSlashableAttestationNoUpdate(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.slashing.Slasher/IsSlashableAttestationNoUpdate",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SlasherServer).IsSlashableAttestationNoUpdate(ctx, req.(*v1alpha1.IndexedAttestation))
}
return interceptor(ctx, in, info, handler)
}
func _Slasher_IsSlashableBlockNoUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(v1alpha1.BeaconBlockHeader)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SlasherServer).IsSlashableBlockNoUpdate(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.slashing.Slasher/IsSlashableBlockNoUpdate",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SlasherServer).IsSlashableBlockNoUpdate(ctx, req.(*v1alpha1.BeaconBlockHeader))
}
return interceptor(ctx, in, info, handler)
}
var _Slasher_serviceDesc = grpc.ServiceDesc{
ServiceName: "ethereum.slashing.Slasher",
HandlerType: (*SlasherServer)(nil),
@@ -390,6 +505,14 @@ var _Slasher_serviceDesc = grpc.ServiceDesc{
MethodName: "IsSlashableBlock",
Handler: _Slasher_IsSlashableBlock_Handler,
},
{
MethodName: "IsSlashableAttestationNoUpdate",
Handler: _Slasher_IsSlashableAttestationNoUpdate_Handler,
},
{
MethodName: "IsSlashableBlockNoUpdate",
Handler: _Slasher_IsSlashableBlockNoUpdate_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "proto/slashing/slashing.proto",
@@ -436,6 +559,43 @@ func (m *ProposerSlashingResponse) MarshalToSizedBuffer(dAtA []byte) (int, error
return len(dAtA) - i, nil
}
func (m *Slashable) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Slashable) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Slashable) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.XXX_unrecognized != nil {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if m.Slashable {
i--
if m.Slashable {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func (m *AttesterSlashingResponse) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@@ -592,6 +752,21 @@ func (m *ProposerSlashingResponse) Size() (n int) {
return n
}
func (m *Slashable) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Slashable {
n += 2
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func (m *AttesterSlashingResponse) Size() (n int) {
if m == nil {
return 0
@@ -746,6 +921,80 @@ func (m *ProposerSlashingResponse) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *Slashable) 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 ErrIntOverflowSlashing
}
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: Slashable: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Slashable: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Slashable", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSlashing
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.Slashable = bool(v != 0)
default:
iNdEx = preIndex
skippy, err := skipSlashing(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthSlashing
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthSlashing
}
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 *AttesterSlashingResponse) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0

View File

@@ -17,12 +17,24 @@ service Slasher {
// Returns any found proposer slashings if the passed in proposal conflicts with a validators history.
rpc IsSlashableBlock(ethereum.eth.v1alpha1.SignedBeaconBlockHeader) returns (ProposerSlashingResponse);
// Returns if a given indexed attestation could be slashable when compared to the slashers history for the attesters.
// This function is read-only, and does not need the indexed attestation to be signed.
rpc IsSlashableAttestationNoUpdate(ethereum.eth.v1alpha1.IndexedAttestation) returns (Slashable);
// Returns if a given beacon block header could be slashable when compared to the slashers history for the proposer.
// This function is read-only, and does not need the beacon block header to be signed.
rpc IsSlashableBlockNoUpdate(ethereum.eth.v1alpha1.BeaconBlockHeader) returns (Slashable);
}
message ProposerSlashingResponse {
repeated ethereum.eth.v1alpha1.ProposerSlashing proposer_slashing = 1;
}
message Slashable {
bool slashable = 1;
}
message AttesterSlashingResponse {
repeated ethereum.eth.v1alpha1.AttesterSlashing attester_slashing = 1;
}

View File

@@ -170,6 +170,11 @@ func (ds *Service) DetectDoubleProposals(ctx context.Context, incomingBlock *eth
return ds.proposalsDetector.DetectDoublePropose(ctx, incomingBlock)
}
// DetectDoubleProposeNoUpdate checks if the given beacon block header is a slashable offense.
func (ds *Service) DetectDoubleProposeNoUpdate(ctx context.Context, incomingBlock *ethpb.BeaconBlockHeader) (bool, error) {
return ds.proposalsDetector.DetectDoubleProposeNoUpdate(ctx, incomingBlock)
}
// mapResultsToAtts handles any duplicate detections by ensuring they reuse the same pool of attestations, instead of re-checking the DB for the same data.
func (ds *Service) mapResultsToAtts(ctx context.Context, results []*types.DetectionResult) (map[[32]byte][]*ethpb.IndexedAttestation, error) {
ctx, span := trace.StartSpan(ctx, "detection.mapResultsToAtts")

View File

@@ -351,36 +351,36 @@ func TestDetect_detectProposerSlashing(t *testing.T) {
incomingBlk *ethpb.SignedBeaconBlockHeader
slashing *ethpb.ProposerSlashing
}
blk1slot0, err := testDetect.SignedBlockHeader(testDetect.StartSlot(0), 0)
sigBlk1slot0, err := testDetect.SignedBlockHeader(testDetect.StartSlot(0), 0)
if err != nil {
t.Fatal(err)
}
blk2slot0, err := testDetect.SignedBlockHeader(testDetect.StartSlot(0), 0)
sigBlk2slot0, err := testDetect.SignedBlockHeader(testDetect.StartSlot(0), 0)
if err != nil {
t.Fatal(err)
}
blk1epoch1, err := testDetect.SignedBlockHeader(testDetect.StartSlot(1), 0)
sigBlk1epoch1, err := testDetect.SignedBlockHeader(testDetect.StartSlot(1), 0)
if err != nil {
t.Fatal(err)
}
tests := []testStruct{
{
name: "same block sig dont slash",
blk: blk1slot0,
incomingBlk: blk1slot0,
blk: sigBlk1slot0,
incomingBlk: sigBlk1slot0,
slashing: nil,
},
{
name: "block from different epoch dont slash",
blk: blk1slot0,
incomingBlk: blk1epoch1,
blk: sigBlk1slot0,
incomingBlk: sigBlk1epoch1,
slashing: nil,
},
{
name: "different sig from same slot slash",
blk: blk1slot0,
incomingBlk: blk2slot0,
slashing: &ethpb.ProposerSlashing{Header_1: blk2slot0, Header_2: blk1slot0},
blk: sigBlk1slot0,
incomingBlk: sigBlk2slot0,
slashing: &ethpb.ProposerSlashing{Header_1: sigBlk2slot0, Header_2: sigBlk1slot0},
},
}
for _, tt := range tests {
@@ -419,6 +419,86 @@ func TestDetect_detectProposerSlashing(t *testing.T) {
})
}
}
func TestDetect_detectProposerSlashingNoUpdate(t *testing.T) {
type testStruct struct {
name string
blk *ethpb.SignedBeaconBlockHeader
noUpdtaeBlk *ethpb.BeaconBlockHeader
slashable bool
}
sigBlk1slot0, err := testDetect.SignedBlockHeader(testDetect.StartSlot(0), 0)
if err != nil {
t.Fatal(err)
}
blk1slot0, err := testDetect.BlockHeader(testDetect.StartSlot(0), 0)
if err != nil {
t.Fatal(err)
}
blk2slot0, err := testDetect.BlockHeader(testDetect.StartSlot(0), 0)
if err != nil {
t.Fatal(err)
}
diffRoot := [32]byte{1, 1, 1}
blk2slot0.ParentRoot = diffRoot[:]
blk3slot0, err := testDetect.BlockHeader(testDetect.StartSlot(0), 0)
if err != nil {
t.Fatal(err)
}
blk3slot0.StateRoot = diffRoot[:]
blk4slot0, err := testDetect.BlockHeader(testDetect.StartSlot(0), 0)
if err != nil {
t.Fatal(err)
}
blk4slot0.BodyRoot = diffRoot[:]
tests := []testStruct{
{
name: "same block don't slash",
blk: sigBlk1slot0,
noUpdtaeBlk: blk1slot0,
slashable: false,
},
{
name: "diff parent root slash",
blk: sigBlk1slot0,
noUpdtaeBlk: blk2slot0,
slashable: true,
},
{
name: "diff state root slash",
blk: sigBlk1slot0,
noUpdtaeBlk: blk3slot0,
slashable: true,
},
{
name: "diff body root slash",
blk: sigBlk1slot0,
noUpdtaeBlk: blk4slot0,
slashable: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
db := testDB.SetupSlasherDB(t, false)
ctx := context.Background()
ds := Service{
ctx: ctx,
slasherDB: db,
proposalsDetector: proposals.NewProposeDetector(db),
}
if err := db.SaveBlockHeader(ctx, tt.blk); err != nil {
t.Fatal(err)
}
slashble, err := ds.proposalsDetector.DetectDoubleProposeNoUpdate(ctx, tt.noUpdtaeBlk)
if err != nil {
t.Fatal(err)
}
if slashble != tt.slashable {
t.Errorf("Wanted slashbale: %v, received slashable: %v", tt.slashable, slashble)
}
})
}
}
func TestServer_MapResultsToAtts(t *testing.T) {
db := testDB.SetupSlasherDB(t, false)

View File

@@ -51,3 +51,27 @@ func (dd *ProposeDetector) DetectDoublePropose(
}
return nil, nil
}
// DetectDoubleProposeNoUpdate detects double proposals for a given block header by db search
// without storing the incoming block to db.
func (dd *ProposeDetector) DetectDoubleProposeNoUpdate(
ctx context.Context,
incomingBlk *ethpb.BeaconBlockHeader,
) (bool, error) {
ctx, span := trace.StartSpan(ctx, "detector.DetectDoubleProposeNoUpdate")
defer span.End()
headersFromIdx, err := dd.slasherDB.BlockHeaders(ctx, incomingBlk.Slot, incomingBlk.ProposerIndex)
if err != nil {
return false, err
}
for _, blockHeader := range headersFromIdx {
sameBodyRoot := bytes.Equal(blockHeader.Header.BodyRoot, incomingBlk.BodyRoot)
sameStateRoot := bytes.Equal(blockHeader.Header.StateRoot, incomingBlk.StateRoot)
sameParentRoot := bytes.Equal(blockHeader.Header.ParentRoot, incomingBlk.ParentRoot)
if sameBodyRoot && sameStateRoot && sameParentRoot {
continue
}
return true, nil
}
return false, nil
}

View File

@@ -10,4 +10,5 @@ import (
// ProposalsDetector defines an interface for different implementations.
type ProposalsDetector interface {
DetectDoublePropose(ctx context.Context, incomingBlk *ethpb.SignedBeaconBlockHeader) (*ethpb.ProposerSlashing, error)
DetectDoubleProposeNoUpdate(ctx context.Context, incomingBlk *ethpb.BeaconBlockHeader) (bool, error)
}

View File

@@ -12,7 +12,7 @@ import (
// SignedBlockHeader given slot, proposer index this function generates signed block header.
// with random bytes as its signature.
func SignedBlockHeader(slot uint64, proposerIdx uint64) (*ethpb.SignedBeaconBlockHeader, error) {
sig, err := genRandomSig()
sig, err := genRandomByteArray(96)
if err != nil {
return nil, err
}
@@ -29,8 +29,20 @@ func SignedBlockHeader(slot uint64, proposerIdx uint64) (*ethpb.SignedBeaconBloc
}, nil
}
func genRandomSig() ([]byte, error) {
blk := make([]byte, 96)
// BlockHeader given slot, proposer index this function generates block header.
func BlockHeader(slot uint64, proposerIdx uint64) (*ethpb.BeaconBlockHeader, error) {
root := [32]byte{1, 2, 3}
return &ethpb.BeaconBlockHeader{
ProposerIndex: proposerIdx,
Slot: slot,
ParentRoot: root[:],
StateRoot: root[:],
BodyRoot: root[:],
}, nil
}
func genRandomByteArray(length int) ([]byte, error) {
blk := make([]byte, length)
_, err := rand.Read(blk)
return blk, err
}

View File

@@ -82,20 +82,20 @@ func (ss *Server) IsSlashableAttestation(ctx context.Context, req *ethpb.Indexed
err = attestationutil.VerifyIndexedAttestationSig(ctx, req, pubkeys, domain)
if err != nil {
log.WithError(err).Error("Failed to verify indexed attestation signature")
return nil, status.Errorf(codes.Internal, "Could not verify indexed attestation signature: %v: %v", req, err)
log.WithError(err).Error("failed to verify indexed attestation signature")
return nil, status.Errorf(codes.Internal, "could not verify indexed attestation signature: %v: %v", req, err)
}
slashings, err := ss.detector.DetectAttesterSlashings(ctx, req)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not detect attester slashings for attestation: %v: %v", req, err)
return nil, status.Errorf(codes.Internal, "could not detect attester slashings for attestation: %v: %v", req, err)
}
if len(slashings) < 1 {
if err := ss.slasherDB.SaveIndexedAttestation(ctx, req); err != nil {
log.WithError(err).Error("Could not save indexed attestation")
return nil, status.Errorf(codes.Internal, "Could not save indexed attestation: %v: %v", req, err)
return nil, status.Errorf(codes.Internal, "could not save indexed attestation: %v: %v", req, err)
}
if err := ss.detector.UpdateSpans(ctx, req); err != nil {
log.WithError(err).Error("Could not update spans")
log.WithError(err).Error("could not update spans")
}
}
return &slashpb.AttesterSlashingResponse{
@@ -139,7 +139,7 @@ func (ss *Server) IsSlashableBlock(ctx context.Context, req *ethpb.SignedBeaconB
}
slashing, err := ss.detector.DetectDoubleProposals(ctx, req)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not detect proposer slashing for block: %v: %v", req, err)
return nil, status.Errorf(codes.Internal, "could not detect proposer slashing for block: %v: %v", req, err)
}
psr := &slashpb.ProposerSlashingResponse{}
if slashing != nil {
@@ -150,3 +150,30 @@ func (ss *Server) IsSlashableBlock(ctx context.Context, req *ethpb.SignedBeaconB
return psr, nil
}
// IsSlashableAttestationNoUpdate returns true if the attestation submitted
// is a slashable vote (no db update is being done).
func (ss *Server) IsSlashableAttestationNoUpdate(ctx context.Context, req *ethpb.IndexedAttestation) (*slashpb.Slashable, error) {
sl := &slashpb.Slashable{}
slashings, err := ss.detector.DetectAttesterSlashings(ctx, req)
if err != nil {
return sl, status.Errorf(codes.Internal, "could not detect attester slashings for attestation: %v: %v", req, err)
}
if len(slashings) < 1 {
return sl, nil
}
sl.Slashable = true
return sl, nil
}
// IsSlashableBlockNoUpdate returns true if the block submitted
// is slashable (no db update is being done).
func (ss *Server) IsSlashableBlockNoUpdate(ctx context.Context, req *ethpb.BeaconBlockHeader) (*slashpb.Slashable, error) {
sl := &slashpb.Slashable{}
slash, err := ss.detector.DetectDoubleProposeNoUpdate(ctx, req)
if err != nil {
return sl, status.Errorf(codes.Internal, "could not detect proposer slashing for block: %v: %v", req, err)
}
sl.Slashable = slash
return sl, nil
}

View File

@@ -138,6 +138,93 @@ func TestServer_IsSlashableAttestation(t *testing.T) {
}
}
func TestServer_IsSlashableAttestationNoUpdate(t *testing.T) {
db := testDB.SetupSlasherDB(t, false)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
bClient := mock.NewMockBeaconChainClient(ctrl)
nClient := mock.NewMockNodeClient(ctrl)
ctx := context.Background()
_, keys, err := testutil.DeterministicDepositsAndKeys(4)
if err != nil {
t.Fatal(err)
}
wantedValidators1 := &ethpb.Validators{
ValidatorList: []*ethpb.Validators_ValidatorContainer{
{
Index: 3, Validator: &ethpb.Validator{PublicKey: keys[3].PublicKey().Marshal()},
},
},
}
bClient.EXPECT().ListValidators(
gomock.Any(),
gomock.Any(),
).Return(wantedValidators1, nil)
wantedGenesis := &ethpb.Genesis{
GenesisValidatorsRoot: []byte("I am genesis"),
}
nClient.EXPECT().GetGenesis(gomock.Any(), gomock.Any()).Return(wantedGenesis, nil)
savedAttestation := &ethpb.IndexedAttestation{
AttestingIndices: []uint64{3},
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 3},
Target: &ethpb.Checkpoint{Epoch: 4},
},
}
incomingAtt := &ethpb.IndexedAttestation{
AttestingIndices: []uint64{1, 3},
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 2},
Target: &ethpb.Checkpoint{Epoch: 4},
},
}
cfg := &detection.Config{
SlasherDB: db,
}
fork, err := p2putils.Fork(savedAttestation.Data.Target.Epoch)
if err != nil {
t.Fatal(err)
}
domain, err := helpers.Domain(fork, savedAttestation.Data.Target.Epoch, params.BeaconConfig().DomainBeaconAttester, wantedGenesis.GenesisValidatorsRoot)
if err != nil {
t.Fatal(err)
}
root, err := helpers.ComputeSigningRoot(savedAttestation.Data, domain)
if err != nil {
t.Error(err)
}
sig := []*bls.Signature{}
for _, idx := range savedAttestation.AttestingIndices {
validatorSig := keys[idx].Sign(root[:])
sig = append(sig, validatorSig)
}
aggSig := bls.AggregateSignatures(sig)
marshalledSig := aggSig.Marshal()
savedAttestation.Signature = marshalledSig
bcCfg := &beaconclient.Config{BeaconClient: bClient, NodeClient: nClient, SlasherDB: db}
bs, err := beaconclient.NewBeaconClientService(ctx, bcCfg)
ds := detection.NewDetectionService(ctx, cfg)
server := Server{ctx: ctx, detector: ds, slasherDB: db, beaconClient: bs}
slashings, err := server.IsSlashableAttestation(ctx, savedAttestation)
if err != nil {
t.Fatalf("got error while trying to detect slashing: %v", err)
}
if len(slashings.AttesterSlashing) != 0 {
t.Fatalf("Found slashings while no slashing should have been found on first attestation: %v slashing found: %v", savedAttestation, slashings)
}
sl, err := server.IsSlashableAttestationNoUpdate(ctx, incomingAtt)
if err != nil {
t.Fatalf("got error while trying to detect slashing: %v", err)
}
if sl.Slashable != true {
t.Fatalf("attestation should be found to be slashable. got: %v", sl.Slashable)
}
}
func TestServer_IsSlashableBlock(t *testing.T) {
db := testDB.SetupSlasherDB(t, false)
ctrl := gomock.NewController(t)
@@ -239,3 +326,86 @@ func TestServer_IsSlashableBlock(t *testing.T) {
t.Fatalf("only one slashing should have been found. got: %v", len(slashing.ProposerSlashing))
}
}
func TestServer_IsSlashableBlockNoUpdate(t *testing.T) {
db := testDB.SetupSlasherDB(t, false)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
bClient := mock.NewMockBeaconChainClient(ctrl)
nClient := mock.NewMockNodeClient(ctrl)
ctx := context.Background()
_, keys, err := testutil.DeterministicDepositsAndKeys(4)
if err != nil {
t.Fatal(err)
}
wantedValidators := &ethpb.Validators{
ValidatorList: []*ethpb.Validators_ValidatorContainer{
{
Index: 1, Validator: &ethpb.Validator{PublicKey: keys[1].PublicKey().Marshal()},
},
},
}
bClient.EXPECT().ListValidators(
gomock.Any(),
gomock.Any(),
).Return(wantedValidators, nil)
wantedGenesis := &ethpb.Genesis{
GenesisValidatorsRoot: []byte("I am genesis"),
}
nClient.EXPECT().GetGenesis(gomock.Any(), gomock.Any()).Return(wantedGenesis, nil)
savedBlock := &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 1,
ProposerIndex: 1,
BodyRoot: bytesutil.PadTo([]byte("body root"), 32),
},
}
incomingBlock := &ethpb.BeaconBlockHeader{
Slot: 1,
ProposerIndex: 1,
BodyRoot: bytesutil.PadTo([]byte("body root2"), 32),
}
cfg := &detection.Config{
SlasherDB: db,
}
savedBlockEpoch := helpers.SlotToEpoch(savedBlock.Header.Slot)
fork, err := p2putils.Fork(savedBlockEpoch)
if err != nil {
t.Fatal(err)
}
domain, err := helpers.Domain(fork, savedBlockEpoch, params.BeaconConfig().DomainBeaconProposer, wantedGenesis.GenesisValidatorsRoot)
if err != nil {
t.Fatal(err)
}
bhr, err := stateutil.BlockHeaderRoot(savedBlock.Header)
if err != nil {
t.Error(err)
}
root, err := helpers.ComputeSigningRoot(bhr, domain)
if err != nil {
t.Error(err)
}
blockSig := keys[savedBlock.Header.ProposerIndex].Sign(root[:])
marshalledSig := blockSig.Marshal()
savedBlock.Signature = marshalledSig
bcCfg := &beaconclient.Config{BeaconClient: bClient, NodeClient: nClient, SlasherDB: db}
bs, err := beaconclient.NewBeaconClientService(ctx, bcCfg)
ds := detection.NewDetectionService(ctx, cfg)
server := Server{ctx: ctx, detector: ds, slasherDB: db, beaconClient: bs}
slashings, err := server.IsSlashableBlock(ctx, savedBlock)
if err != nil {
t.Fatalf("got error while trying to detect slashing: %v", err)
}
if len(slashings.ProposerSlashing) != 0 {
t.Fatalf("Found slashings while no slashing should have been found on first block: %v slashing found: %v", savedBlock, slashings)
}
sl, err := server.IsSlashableBlockNoUpdate(ctx, incomingBlock)
if err != nil {
t.Fatalf("got error while trying to detect slashing: %v", err)
}
if sl.Slashable != true {
t.Fatalf("block should be found to be slashable. got: %v", sl.Slashable)
}
}

View File

@@ -35,6 +35,14 @@ func (ms mockSlasher) IsSlashableAttestation(ctx context.Context, in *eth.Indexe
}
return nil, nil
}
func (ms mockSlasher) IsSlashableAttestationNoUpdate(ctx context.Context, in *eth.IndexedAttestation, opts ...grpc.CallOption) (*slashpb.Slashable, error) {
return &slashpb.Slashable{
Slashable: ms.slashAttestation,
}, nil
}
func (ms mockSlasher) IsSlashableBlock(ctx context.Context, in *eth.SignedBeaconBlockHeader, opts ...grpc.CallOption) (*slashpb.ProposerSlashingResponse, error) {
if ms.slashBlock {
slashingBlk, ok := proto.Clone(in).(*eth.SignedBeaconBlockHeader)
@@ -54,6 +62,12 @@ func (ms mockSlasher) IsSlashableBlock(ctx context.Context, in *eth.SignedBeacon
return nil, nil
}
func (ms mockSlasher) IsSlashableBlockNoUpdate(ctx context.Context, in *eth.BeaconBlockHeader, opts ...grpc.CallOption) (*slashpb.Slashable, error) {
return &slashpb.Slashable{
Slashable: ms.slashBlock,
}, nil
}
func TestService_VerifyAttestation(t *testing.T) {
s := &Service{slasherClient: mockSlasher{slashAttestation: true}}
att := &eth.IndexedAttestation{