mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 07:58:22 -05:00
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:
319
proto/slashing/slashing.pb.go
generated
319
proto/slashing/slashing.pb.go
generated
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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: ðpb.ProposerSlashing{Header_1: blk2slot0, Header_2: blk1slot0},
|
||||
blk: sigBlk1slot0,
|
||||
incomingBlk: sigBlk2slot0,
|
||||
slashing: ðpb.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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 ðpb.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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 := ðpb.Validators{
|
||||
ValidatorList: []*ethpb.Validators_ValidatorContainer{
|
||||
{
|
||||
Index: 3, Validator: ðpb.Validator{PublicKey: keys[3].PublicKey().Marshal()},
|
||||
},
|
||||
},
|
||||
}
|
||||
bClient.EXPECT().ListValidators(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(wantedValidators1, nil)
|
||||
|
||||
wantedGenesis := ðpb.Genesis{
|
||||
GenesisValidatorsRoot: []byte("I am genesis"),
|
||||
}
|
||||
nClient.EXPECT().GetGenesis(gomock.Any(), gomock.Any()).Return(wantedGenesis, nil)
|
||||
savedAttestation := ðpb.IndexedAttestation{
|
||||
AttestingIndices: []uint64{3},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 3},
|
||||
Target: ðpb.Checkpoint{Epoch: 4},
|
||||
},
|
||||
}
|
||||
incomingAtt := ðpb.IndexedAttestation{
|
||||
AttestingIndices: []uint64{1, 3},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 2},
|
||||
Target: ðpb.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 := ðpb.Validators{
|
||||
ValidatorList: []*ethpb.Validators_ValidatorContainer{
|
||||
{
|
||||
Index: 1, Validator: ðpb.Validator{PublicKey: keys[1].PublicKey().Marshal()},
|
||||
},
|
||||
},
|
||||
}
|
||||
bClient.EXPECT().ListValidators(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(wantedValidators, nil)
|
||||
|
||||
wantedGenesis := ðpb.Genesis{
|
||||
GenesisValidatorsRoot: []byte("I am genesis"),
|
||||
}
|
||||
nClient.EXPECT().GetGenesis(gomock.Any(), gomock.Any()).Return(wantedGenesis, nil)
|
||||
savedBlock := ðpb.SignedBeaconBlockHeader{
|
||||
Header: ðpb.BeaconBlockHeader{
|
||||
Slot: 1,
|
||||
ProposerIndex: 1,
|
||||
BodyRoot: bytesutil.PadTo([]byte("body root"), 32),
|
||||
},
|
||||
}
|
||||
incomingBlock := ðpb.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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 := ð.IndexedAttestation{
|
||||
|
||||
Reference in New Issue
Block a user