Skip to content

Commit

Permalink
Fix a bug in pubsub message ID hash function (#791)
Browse files Browse the repository at this point in the history
The prior implementation I believe intended to include additional fields
into account when calculating the message ID from data. But was only
returning hash of data for both manifest and GPBFT messages.

Fix this by writing the data to the hasher, _then_ computing the hash
with no suffix.
  • Loading branch information
masih authored Dec 13, 2024
1 parent b04ede1 commit d4f3a0c
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 4 deletions.
12 changes: 8 additions & 4 deletions internal/psutil/psutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ func pubsubMsgIdHashData(m *pubsub_pb.Message) string {
if _, err := hasher.Write(topic); err != nil {
panic(err)
}

hash := blake2b.Sum256(m.Data)
if _, err := hasher.Write(m.Data); err != nil {
panic(err)
}
hash := hasher.Sum(nil)
return string(hash[:])
}

Expand All @@ -53,8 +55,10 @@ func pubsubMsgIdHashDataAndSender(m *pubsub_pb.Message) string {
if _, err := hasher.Write(m.From); err != nil {
panic(err)
}

hash := blake2b.Sum256(m.Data)
if _, err := hasher.Write(m.Data); err != nil {
panic(err)
}
hash := hasher.Sum(nil)
return string(hash[:])
}

Expand Down
121 changes: 121 additions & 0 deletions internal/psutil/psutil_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package psutil_test

import (
"testing"

"github.com/filecoin-project/go-f3/internal/psutil"
pubsub_pb "github.com/libp2p/go-libp2p-pubsub/pb"
"github.com/stretchr/testify/require"
)

func TestManifestMessageIdFn(t *testing.T) {
for _, test := range []struct {
name string
one *pubsub_pb.Message
other *pubsub_pb.Message
expectEqualID bool
}{
{
name: "same topic different data",
one: &pubsub_pb.Message{
Topic: topic("fish"),
From: []byte("barreleye"),
Data: []byte("undadasea"),
},
other: &pubsub_pb.Message{
Topic: topic("fish"),
From: []byte("barreleye"),
Data: []byte("lobstermuncher"),
},
expectEqualID: false,
},
{
name: "same data different topic",
one: &pubsub_pb.Message{
Topic: topic("fish"),
From: []byte("barreleye"),
Data: []byte("undadasea"),
},
other: &pubsub_pb.Message{
Topic: topic("lobster"),
From: []byte("barreleye"),
Data: []byte("undadasea"),
},
expectEqualID: false,
},
{
name: "same data and topic different sender",
one: &pubsub_pb.Message{
Topic: topic("fish"),
From: []byte("barreleye"),
Data: []byte("undadasea"),
},
other: &pubsub_pb.Message{
Topic: topic("fish"),
From: []byte("fisherman"),
Data: []byte("undadasea"),
},
expectEqualID: false,
},
} {
t.Run(test.name, func(t *testing.T) {
this, that := psutil.ManifestMessageIdFn(test.one), psutil.ManifestMessageIdFn(test.other)
require.Equal(t, test.expectEqualID, this == that)
})
}
}

func TestGPBFTMessageIdFn(t *testing.T) {
for _, test := range []struct {
name string
one *pubsub_pb.Message
other *pubsub_pb.Message
expectEqualID bool
}{
{
name: "same topic different data",
one: &pubsub_pb.Message{
Topic: topic("fish"),
Data: []byte("undadasea"),
},
other: &pubsub_pb.Message{
Topic: topic("fish"),
Data: []byte("lobstermuncher"),
},
expectEqualID: false,
},
{
name: "same data different topic",
one: &pubsub_pb.Message{
Topic: topic("fish"),
Data: []byte("undadasea"),
},
other: &pubsub_pb.Message{
Topic: topic("lobster"),
Data: []byte("undadasea"),
},
expectEqualID: false,
},
{
name: "same data and topic different sender",
one: &pubsub_pb.Message{
Topic: topic("fish"),
From: []byte("barreleye"),
Data: []byte("undadasea"),
},
other: &pubsub_pb.Message{
Topic: topic("fish"),
From: []byte("fisherman"),
Data: []byte("undadasea"),
},
expectEqualID: true,
},
} {
t.Run(test.name, func(t *testing.T) {
this, that := psutil.GPBFTMessageIdFn(test.one), psutil.GPBFTMessageIdFn(test.other)
require.Equal(t, test.expectEqualID, this == that)
})
}
}

func topic(s string) *string { return &s }

0 comments on commit d4f3a0c

Please sign in to comment.