Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HashProto: Use fastssz when available #5218

Merged
merged 14 commits into from Mar 28, 2020
Merged
8 changes: 4 additions & 4 deletions beacon-chain/blockchain/process_attestation_test.go
Expand Up @@ -149,7 +149,7 @@ func TestStore_SaveCheckpointState(t *testing.T) {
LatestBlockHeader: &ethpb.BeaconBlockHeader{},
JustificationBits: []byte{0},
Slashings: make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector),
FinalizedCheckpoint: &ethpb.Checkpoint{},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'A'}, 32)},
})
r := [32]byte{'g'}
if err := service.beaconDB.SaveState(ctx, s, r); err != nil {
Expand All @@ -160,7 +160,7 @@ func TestStore_SaveCheckpointState(t *testing.T) {
service.finalizedCheckpt = &ethpb.Checkpoint{Root: r[:]}
service.prevFinalizedCheckpt = &ethpb.Checkpoint{Root: r[:]}

cp1 := &ethpb.Checkpoint{Epoch: 1, Root: []byte{'A'}}
cp1 := &ethpb.Checkpoint{Epoch: 1, Root: bytesutil.PadTo([]byte{'A'}, 32)}
service.beaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'A'}))
s1, err := service.getAttPreState(ctx, cp1)
if err != nil {
Expand All @@ -170,7 +170,7 @@ func TestStore_SaveCheckpointState(t *testing.T) {
t.Errorf("Wanted state slot: %d, got: %d", 1*params.BeaconConfig().SlotsPerEpoch, s1.Slot())
}

cp2 := &ethpb.Checkpoint{Epoch: 2, Root: []byte{'B'}}
cp2 := &ethpb.Checkpoint{Epoch: 2, Root: bytesutil.PadTo([]byte{'B'}, 32)}
service.beaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'B'}))
s2, err := service.getAttPreState(ctx, cp2)
if err != nil {
Expand Down Expand Up @@ -209,7 +209,7 @@ func TestStore_SaveCheckpointState(t *testing.T) {
service.bestJustifiedCheckpt = &ethpb.Checkpoint{Root: r[:]}
service.finalizedCheckpt = &ethpb.Checkpoint{Root: r[:]}
service.prevFinalizedCheckpt = &ethpb.Checkpoint{Root: r[:]}
cp3 := &ethpb.Checkpoint{Epoch: 1, Root: []byte{'C'}}
cp3 := &ethpb.Checkpoint{Epoch: 1, Root: bytesutil.PadTo([]byte{'C'}, 32)}
service.beaconDB.SaveState(ctx, s, bytesutil.ToBytes32([]byte{'C'}))
s3, err := service.getAttPreState(ctx, cp3)
if err != nil {
Expand Down
7 changes: 4 additions & 3 deletions beacon-chain/cache/checkpoint_state_test.go
Expand Up @@ -4,14 +4,15 @@ import (
"reflect"
"testing"

"github.com/prysmaticlabs/prysm/shared/bytesutil"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/hashutil"
)

func TestCheckpointStateCacheKeyFn_OK(t *testing.T) {
cp := &ethpb.Checkpoint{Epoch: 1, Root: []byte{'A'}}
cp := &ethpb.Checkpoint{Epoch: 1, Root: bytesutil.PadTo([]byte{'A'}, 32)}
st, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Slot: 64,
})
Expand Down Expand Up @@ -45,7 +46,7 @@ func TestCheckpointStateCacheKeyFn_InvalidObj(t *testing.T) {
func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
cache := NewCheckpointStateCache()

cp1 := &ethpb.Checkpoint{Epoch: 1, Root: []byte{'A'}}
cp1 := &ethpb.Checkpoint{Epoch: 1, Root: bytesutil.PadTo([]byte{'A'}, 32)}
st, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Slot: 64,
})
Expand Down Expand Up @@ -75,7 +76,7 @@ func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
t.Error("incorrectly cached state")
}

cp2 := &ethpb.Checkpoint{Epoch: 2, Root: []byte{'B'}}
cp2 := &ethpb.Checkpoint{Epoch: 2, Root: bytesutil.PadTo([]byte{'B'}, 32)}
st2, err := stateTrie.InitializeFromProto(&pb.BeaconState{
Slot: 128,
})
Expand Down
13 changes: 10 additions & 3 deletions beacon-chain/cache/depositcache/pending_deposits_test.go
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/gogo/protobuf/proto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
dbpb "github.com/prysmaticlabs/prysm/proto/beacon/db"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
)

var _ = PendingDepositsFetcher(&DepositCache{})
Expand All @@ -33,8 +34,12 @@ func TestInsertPendingDeposit_ignoresNilDeposit(t *testing.T) {

func TestRemovePendingDeposit_OK(t *testing.T) {
db := DepositCache{}
depToRemove := &ethpb.Deposit{Proof: [][]byte{[]byte("A")}}
otherDep := &ethpb.Deposit{Proof: [][]byte{[]byte("B")}}
proof1 := make([][]byte, 33)
proof1[0] = bytesutil.PadTo([]byte{'A'}, 32)
proof2 := make([][]byte, 33)
proof2[0] = bytesutil.PadTo([]byte{'A'}, 32)
depToRemove := &ethpb.Deposit{Proof: proof1}
otherDep := &ethpb.Deposit{Proof: proof2}
db.pendingDeposits = []*dbpb.DepositContainer{
{Deposit: depToRemove, Index: 1},
{Deposit: otherDep, Index: 5},
Expand All @@ -57,7 +62,9 @@ func TestRemovePendingDeposit_IgnoresNilDeposit(t *testing.T) {

func TestPendingDeposit_RoundTrip(t *testing.T) {
dc := DepositCache{}
dep := &ethpb.Deposit{Proof: [][]byte{[]byte("A")}}
proof := make([][]byte, 33)
proof[0] = bytesutil.PadTo([]byte{'A'}, 32)
dep := &ethpb.Deposit{Proof: proof}
dc.InsertPendingDeposit(context.Background(), dep, 111, 100, [32]byte{})
dc.RemovePendingDeposit(context.Background(), dep)
if len(dc.pendingDeposits) != 0 {
Expand Down
1 change: 1 addition & 0 deletions beacon-chain/operations/attestations/BUILD.bazel
Expand Up @@ -50,5 +50,6 @@ go_test(
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@in_gopkg_d4l3k_messagediff_v1//:go_default_library",
],
)
16 changes: 12 additions & 4 deletions beacon-chain/operations/attestations/aggregate_test.go
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/shared/bls"
"gopkg.in/d4l3k/messagediff.v1"
)

func TestAggregateAttestations_SingleAttestation(t *testing.T) {
Expand Down Expand Up @@ -48,10 +49,14 @@ func TestAggregateAttestations_MultipleAttestationsSameRoot(t *testing.T) {
sk := bls.RandKey()
sig := sk.Sign([]byte("dummy_test_data"), 0 /*domain*/)

data := &ethpb.AttestationData{
Source: &ethpb.Checkpoint{},
Target: &ethpb.Checkpoint{},
}
attsToBeAggregated := []*ethpb.Attestation{
{Data: &ethpb.AttestationData{}, AggregationBits: bitfield.Bitlist{0b110001}, Signature: sig.Marshal()},
{Data: &ethpb.AttestationData{}, AggregationBits: bitfield.Bitlist{0b100010}, Signature: sig.Marshal()},
{Data: &ethpb.AttestationData{}, AggregationBits: bitfield.Bitlist{0b101100}, Signature: sig.Marshal()},
{Data: data, AggregationBits: bitfield.Bitlist{0b110001}, Signature: sig.Marshal()},
{Data: data, AggregationBits: bitfield.Bitlist{0b100010}, Signature: sig.Marshal()},
{Data: data, AggregationBits: bitfield.Bitlist{0b101100}, Signature: sig.Marshal()},
}

if err := s.aggregateAttestations(context.Background(), attsToBeAggregated); err != nil {
Expand All @@ -66,7 +71,10 @@ func TestAggregateAttestations_MultipleAttestationsSameRoot(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(wanted, s.pool.AggregatedAttestations()) {
got := s.pool.AggregatedAttestations()
if !reflect.DeepEqual(wanted, got) {
diff, _ := messagediff.PrettyDiff(got[0], wanted[0])
t.Log(diff)
t.Error("Did not aggregate attestations")
}
}
Expand Down
2 changes: 1 addition & 1 deletion beacon-chain/state/stateutil/blocks.go
Expand Up @@ -4,9 +4,9 @@ import (
"bytes"
"encoding/binary"

"github.com/prysmaticlabs/go-ssz"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/hashutil"
Expand Down
5 changes: 3 additions & 2 deletions beacon-chain/sync/pending_attestations_queue_test.go
Expand Up @@ -20,6 +20,7 @@ import (
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/roughtime"
"github.com/prysmaticlabs/prysm/shared/testutil"
Expand Down Expand Up @@ -119,8 +120,8 @@ func TestProcessPendingAtts_HasBlockSaveAggregatedAtt(t *testing.T) {
att := &ethpb.Attestation{
Data: &ethpb.AttestationData{
BeaconBlockRoot: root[:],
Source: &ethpb.Checkpoint{Epoch: 0, Root: []byte("hello-world")},
Target: &ethpb.Checkpoint{Epoch: 0, Root: []byte("hello-world")},
Source: &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
},
AggregationBits: aggBits,
}
Expand Down
5 changes: 3 additions & 2 deletions beacon-chain/sync/validate_aggregate_proof_test.go
Expand Up @@ -24,6 +24,7 @@ import (
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
)
Expand Down Expand Up @@ -257,8 +258,8 @@ func TestValidateAggregateAndProof_ExistedInPool(t *testing.T) {
Data: &ethpb.AttestationData{
Slot: 1,
BeaconBlockRoot: root[:],
Source: &ethpb.Checkpoint{Epoch: 0, Root: []byte("hello-world")},
Target: &ethpb.Checkpoint{Epoch: 0, Root: []byte("hello-world")},
Source: &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
},
AggregationBits: aggBits,
}
Expand Down
2 changes: 1 addition & 1 deletion endtoend/BUILD.bazel
Expand Up @@ -13,8 +13,8 @@ go_test(
args = ["-test.v"],
data = [
"//beacon-chain",
"//validator",
"//slasher",
"//validator",
"@com_github_ethereum_go_ethereum//cmd/geth",
],
shard_count = 3,
Expand Down
3 changes: 3 additions & 0 deletions shared/hashutil/BUILD.bazel
Expand Up @@ -10,6 +10,7 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//shared/bytesutil:go_default_library",
"@com_github_ferranbt_fastssz//:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_minio_highwayhash//:go_default_library",
"@com_github_minio_sha256_simd//:go_default_library",
Expand All @@ -27,7 +28,9 @@ go_test(
embed = [":go_default_library"],
deps = [
"//proto/testing:go_default_library",
"//shared/bls:go_default_library",
"//shared/bytesutil:go_default_library",
"@com_github_google_gofuzz//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
],
)
8 changes: 7 additions & 1 deletion shared/hashutil/hash.go
Expand Up @@ -6,6 +6,7 @@ import (
"reflect"
"sync"

ssz "github.com/ferranbt/fastssz"
"github.com/gogo/protobuf/proto"
"github.com/minio/highwayhash"
"github.com/minio/sha256-simd"
Expand Down Expand Up @@ -112,7 +113,12 @@ func HashProto(msg proto.Message) (result [32]byte, err error) {
if msg == nil || reflect.ValueOf(msg).IsNil() {
return [32]byte{}, ErrNilProto
}
data, err := proto.Marshal(msg)
var data []byte
if m, ok := msg.(ssz.Marshaler); ok {
data, err = m.MarshalSSZ()
} else {
data, err = proto.Marshal(msg)
}
if err != nil {
return [32]byte{}, err
}
Expand Down
20 changes: 20 additions & 0 deletions shared/hashutil/hash_test.go
Expand Up @@ -5,7 +5,9 @@ import (
"testing"

fuzz "github.com/google/gofuzz"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
pb "github.com/prysmaticlabs/prysm/proto/testing"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/hashutil"
)
Expand Down Expand Up @@ -97,3 +99,21 @@ func TestHashProtoFuzz(t *testing.T) {
_, _ = hashutil.HashProto(msg)
}
}

func BenchmarkHashProto(b *testing.B) {
att := &ethpb.Attestation{
AggregationBits: nil,
Data: &ethpb.AttestationData{
Slot: 5,
CommitteeIndex: 3,
BeaconBlockRoot: []byte{},
Source: nil,
Target: nil,
},
Signature: bls.NewAggregateSignature().Marshal(),
}

for i := 0; i < b.N; i++ {
hashutil.HashProto(att)
}
}
2 changes: 2 additions & 0 deletions slasher/db/kv/BUILD.bazel
Expand Up @@ -49,6 +49,7 @@ go_test(
embed = [":go_default_library"],
deps = [
"//beacon-chain/core/helpers:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil:go_default_library",
"//slasher/db/iface:go_default_library",
Expand All @@ -57,6 +58,7 @@ go_test(
"//slasher/flags:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@in_gopkg_d4l3k_messagediff_v1//:go_default_library",
"@in_gopkg_urfave_cli_v2//:go_default_library",
],
)
12 changes: 9 additions & 3 deletions slasher/db/kv/attester_slashings.go
Expand Up @@ -109,7 +109,10 @@ func (db *Store) SaveAttesterSlashing(ctx context.Context, status types.Slashing
if err != nil {
return errors.Wrap(err, "failed to marshal")
}
root := hashutil.Hash(enc)
root, err := hashutil.HashProto(slashing)
if err != nil {
return err
}
key := encodeTypeRoot(types.SlashingType(types.Attestation), root)
return db.update(func(tx *bolt.Tx) error {
b := tx.Bucket(slashingBucket)
Expand All @@ -130,8 +133,11 @@ func (db *Store) SaveAttesterSlashings(ctx context.Context, status types.Slashin
if err != nil {
return errors.Wrap(err, "failed to marshal")
}
encHash := hashutil.Hash(enc[i])
key[i] = encodeTypeRoot(types.SlashingType(types.Attestation), encHash)
root, err := hashutil.HashProto(slashing)
if err != nil {
return err
}
key[i] = encodeTypeRoot(types.SlashingType(types.Attestation), root)
}

return db.update(func(tx *bolt.Tx) error {
Expand Down