Prevent Saving Empty Chunks to Disk (#9707)

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
Raul Jordan
2021-09-30 13:29:40 -05:00
committed by GitHub
parent 26978fcc50
commit f5234634d6
2 changed files with 31 additions and 3 deletions

View File

@@ -271,7 +271,11 @@ func (s *Store) SaveSlasherChunks(
encodedChunks := make([][]byte, len(chunkKeys))
for i := 0; i < len(chunkKeys); i++ {
encodedKeys[i] = append(ssz.MarshalUint8(make([]byte, 0), uint8(kind)), chunkKeys[i]...)
encodedChunks[i] = encodeSlasherChunk(chunks[i])
encodedChunk, err := encodeSlasherChunk(chunks[i])
if err != nil {
return err
}
encodedChunks[i] = encodedChunk
}
return s.db.Update(func(tx *bolt.Tx) error {
bkt := tx.Bucket(slasherChunksBucket)
@@ -453,12 +457,15 @@ func keyForValidatorProposal(slot types.Slot, proposerIndex types.ValidatorIndex
return append(encSlot, encValidatorIdx...), nil
}
func encodeSlasherChunk(chunk []uint16) []byte {
func encodeSlasherChunk(chunk []uint16) ([]byte, error) {
val := make([]byte, 0)
for i := 0; i < len(chunk); i++ {
val = append(val, ssz.MarshalUint16(make([]byte, 0), chunk[i])...)
}
return snappy.Encode(nil, val)
if len(val) == 0 {
return nil, errors.New("cannot encode empty chunk")
}
return snappy.Encode(nil, val), nil
}
func decodeSlasherChunk(enc []byte) ([]uint16, error) {
@@ -466,6 +473,12 @@ func decodeSlasherChunk(enc []byte) ([]uint16, error) {
if err != nil {
return nil, err
}
if len(chunkBytes)%2 != 0 {
return nil, fmt.Errorf(
"cannot decode slasher chunk with length %d, must be a multiple of 2",
len(chunkBytes),
)
}
chunk := make([]uint16, 0)
for i := 0; i < len(chunkBytes); i += 2 {
distance := ssz.UnmarshallUint16(chunkBytes[i : i+2])

View File

@@ -183,6 +183,21 @@ func TestStore_SlasherChunk_SaveRetrieve(t *testing.T) {
}
}
func TestStore_SlasherChunk_PreventsSavingWrongLength(t *testing.T) {
ctx := context.Background()
beaconDB := setupDB(t)
totalChunks := 64
chunkKeys := make([][]byte, totalChunks)
chunks := make([][]uint16, totalChunks)
for i := 0; i < totalChunks; i++ {
chunks[i] = []uint16{}
chunkKeys[i] = ssz.MarshalUint64(make([]byte, 0), uint64(i))
}
// We should get an error if saving empty chunks.
err := beaconDB.SaveSlasherChunks(ctx, slashertypes.MinSpan, chunkKeys, chunks)
require.ErrorContains(t, "cannot encode empty chunk", err)
}
func TestStore_ExistingBlockProposals(t *testing.T) {
ctx := context.Background()
beaconDB := setupDB(t)