-
Notifications
You must be signed in to change notification settings - Fork 917
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Attester proposer slashing store (#4315)
* Merge branch 'master' of github.com:prysmaticlabs/prysm into update_validators # Conflicts: # slasher/flags/flags.go # slasher/main.go # slasher/service/data_update.go # slasher/service/service.go # slasher/service/service_test.go * proposal and attester store * day to status * comment change * one bucket * Merge branch 'master' of github.com:prysmaticlabs/prysm into attester_proposer_slashing_store # Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit. added comments * comment * typo fix * raul review fix * raul review fix full * nishant feedback * test fix * fix tests and remove update gofmt goimports * remove blank line in imports * nishant fixes * comment and fir delete proposer slashings * avoid marshal twice * remove space * Update slasher/db/attester_slashings.go Co-Authored-By: terence tsao <terence@prysmaticlabs.com> * terence feedback Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com> Co-authored-by: terence tsao <terence@prysmaticlabs.com>
- Loading branch information
1 parent
62811e8
commit 0b35743
Showing
7 changed files
with
544 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package db | ||
|
||
import ( | ||
"bytes" | ||
|
||
"github.com/boltdb/bolt" | ||
"github.com/gogo/protobuf/proto" | ||
"github.com/pkg/errors" | ||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1" | ||
"github.com/prysmaticlabs/prysm/shared/hashutil" | ||
) | ||
|
||
func createAttesterSlashing(enc []byte) (*ethpb.AttesterSlashing, error) { | ||
protoSlashing := ðpb.AttesterSlashing{} | ||
err := proto.Unmarshal(enc, protoSlashing) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "failed to unmarshal encoding") | ||
} | ||
return protoSlashing, nil | ||
} | ||
|
||
func toAttesterSlashings(encoded [][]byte) ([]*ethpb.AttesterSlashing, error) { | ||
attesterSlashings := make([]*ethpb.AttesterSlashing, len(encoded)) | ||
for i, enc := range encoded { | ||
ps, err := createAttesterSlashing(enc) | ||
if err != nil { | ||
return nil, err | ||
} | ||
attesterSlashings[i] = ps | ||
} | ||
return attesterSlashings, nil | ||
} | ||
|
||
// AttesterSlashings accepts a status and returns all slashings with this status. | ||
// returns empty []*ethpb.AttesterSlashing if no slashing has been found with this status. | ||
func (db *Store) AttesterSlashings(status SlashingStatus) ([]*ethpb.AttesterSlashing, error) { | ||
encoded := make([][]byte, 0) | ||
err := db.view(func(tx *bolt.Tx) error { | ||
c := tx.Bucket(slashingBucket).Cursor() | ||
prefix := encodeType(SlashingType(Attestation)) | ||
for k, v := c.Seek(prefix); k != nil && bytes.HasPrefix(k, prefix); k, v = c.Next() { | ||
if v[0] == byte(status) { | ||
encoded = append(encoded, v[1:]) | ||
} | ||
} | ||
return nil | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return toAttesterSlashings(encoded) | ||
} | ||
|
||
// DeleteAttesterSlashing deletes an attester slashing proof from db. | ||
func (db *Store) DeleteAttesterSlashing(attesterSlashing *ethpb.AttesterSlashing) error { | ||
root, err := hashutil.HashProto(attesterSlashing) | ||
if err != nil { | ||
return errors.Wrap(err, "failed to get hash root of attesterSlashing") | ||
} | ||
return db.update(func(tx *bolt.Tx) error { | ||
bucket := tx.Bucket(slashingBucket) | ||
k := encodeTypeRoot(SlashingType(Attestation), root) | ||
if err != nil { | ||
return errors.Wrap(err, "failed to get key for for attester slashing.") | ||
} | ||
if err := bucket.Delete(k); err != nil { | ||
return errors.Wrap(err, "failed to delete the slashing proof from slashing bucket") | ||
} | ||
return nil | ||
}) | ||
} | ||
|
||
// HasAttesterSlashing returns true and slashing status if slashing is found in db. | ||
func (db *Store) HasAttesterSlashing(slashing *ethpb.AttesterSlashing) (bool, SlashingStatus, error) { | ||
root, err := hashutil.HashProto(slashing) | ||
var status SlashingStatus | ||
var found bool | ||
key := encodeTypeRoot(SlashingType(Attestation), root) | ||
if err != nil { | ||
return found, status, errors.Wrap(err, "failed to get hash root of attesterSlashing") | ||
} | ||
err = db.view(func(tx *bolt.Tx) error { | ||
b := tx.Bucket(slashingBucket) | ||
enc := b.Get(key) | ||
if enc != nil { | ||
found = true | ||
status = SlashingStatus(enc[0]) | ||
} | ||
return nil | ||
}) | ||
return found, status, err | ||
} | ||
|
||
// SaveAttesterSlashing accepts a slashing proof and its status and writes it to disk. | ||
func (db *Store) SaveAttesterSlashing(status SlashingStatus, slashing *ethpb.AttesterSlashing) error { | ||
enc, err := proto.Marshal(slashing) | ||
if err != nil { | ||
return errors.Wrap(err, "failed to marshal") | ||
} | ||
root := hashutil.Hash(enc) | ||
key := encodeTypeRoot(SlashingType(Attestation), root) | ||
err = db.update(func(tx *bolt.Tx) error { | ||
b := tx.Bucket(slashingBucket) | ||
e := b.Put(key, append([]byte{byte(status)}, enc...)) | ||
if e != nil { | ||
return nil | ||
} | ||
return err | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package db | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
|
||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1" | ||
) | ||
|
||
func TestStore_AttesterSlashingNilBucket(t *testing.T) { | ||
db := SetupSlasherDB(t) | ||
defer TeardownSlasherDB(t, db) | ||
as := ðpb.AttesterSlashing{Attestation_1: ðpb.IndexedAttestation{Signature: []byte("hello")}} | ||
has, _, err := db.HasAttesterSlashing(as) | ||
if err != nil { | ||
t.Fatalf("HasAttesterSlashing should not return error: %v", err) | ||
} | ||
if has { | ||
t.Fatal("HasAttesterSlashing should return false") | ||
} | ||
|
||
p, err := db.AttesterSlashings(SlashingStatus(Active)) | ||
if err != nil { | ||
t.Fatalf("failed to get attester slashing: %v", err) | ||
} | ||
if p == nil || len(p) != 0 { | ||
t.Fatalf("get should return empty attester slashing array for a non existent key") | ||
} | ||
} | ||
|
||
func TestStore_SaveAttesterSlashing(t *testing.T) { | ||
db := SetupSlasherDB(t) | ||
defer TeardownSlasherDB(t, db) | ||
tests := []struct { | ||
ss SlashingStatus | ||
as *ethpb.AttesterSlashing | ||
}{ | ||
{ | ||
ss: Active, | ||
as: ðpb.AttesterSlashing{Attestation_1: ðpb.IndexedAttestation{Signature: []byte("hello")}}, | ||
}, | ||
{ | ||
ss: Included, | ||
as: ðpb.AttesterSlashing{Attestation_1: ðpb.IndexedAttestation{Signature: []byte("hello2")}}, | ||
}, | ||
{ | ||
ss: Reverted, | ||
as: ðpb.AttesterSlashing{Attestation_1: ðpb.IndexedAttestation{Signature: []byte("hello3")}}, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
err := db.SaveAttesterSlashing(tt.ss, tt.as) | ||
if err != nil { | ||
t.Fatalf("save attester slashing failed: %v", err) | ||
} | ||
|
||
attesterSlashings, err := db.AttesterSlashings(tt.ss) | ||
if err != nil { | ||
t.Fatalf("failed to get attester slashings: %v", err) | ||
} | ||
|
||
if attesterSlashings == nil || !reflect.DeepEqual(attesterSlashings[0], tt.as) { | ||
t.Fatalf("attester slashing: %v should be part of attester slashings response: %v", tt.as, attesterSlashings) | ||
} | ||
} | ||
|
||
} | ||
|
||
func TestStore_UpdateAttesterSlashingStatus(t *testing.T) { | ||
db := SetupSlasherDB(t) | ||
defer TeardownSlasherDB(t, db) | ||
tests := []struct { | ||
ss SlashingStatus | ||
as *ethpb.AttesterSlashing | ||
}{ | ||
{ | ||
ss: Active, | ||
as: ðpb.AttesterSlashing{Attestation_1: ðpb.IndexedAttestation{Signature: []byte("hello")}}, | ||
}, | ||
{ | ||
ss: Active, | ||
as: ðpb.AttesterSlashing{Attestation_1: ðpb.IndexedAttestation{Signature: []byte("hello2")}}, | ||
}, | ||
{ | ||
ss: Active, | ||
as: ðpb.AttesterSlashing{Attestation_1: ðpb.IndexedAttestation{Signature: []byte("hello3")}}, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
err := db.SaveAttesterSlashing(tt.ss, tt.as) | ||
if err != nil { | ||
t.Fatalf("save attester slashing failed: %v", err) | ||
} | ||
} | ||
|
||
for _, tt := range tests { | ||
has, st, err := db.HasAttesterSlashing(tt.as) | ||
if err != nil { | ||
t.Fatalf("failed to get attester slashing: %v", err) | ||
} | ||
if !has { | ||
t.Fatalf("failed to find attester slashing: %v", tt.as) | ||
} | ||
if st != tt.ss { | ||
t.Fatalf("failed to find attester slashing with the correct status: %v", tt.as) | ||
} | ||
|
||
err = db.SaveAttesterSlashing(SlashingStatus(Included), tt.as) | ||
has, st, err = db.HasAttesterSlashing(tt.as) | ||
if err != nil { | ||
t.Fatalf("failed to get attester slashing: %v", err) | ||
} | ||
if !has { | ||
t.Fatalf("failed to find attester slashing: %v", tt.as) | ||
} | ||
if st != Included { | ||
t.Fatalf("failed to find attester slashing with the correct status: %v", tt.as) | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.