Skip to content

Commit

Permalink
SignedSSVMessage (#345)
Browse files Browse the repository at this point in the history
* Add SignedSSVMessage

* Add SSZ encoding

* Test structures for SignedSSVMessage

* Test utils and encoding test

* Tests

* Generate tests

* Adapt message validation

* Fix expected error; Bring back commented tests

* Add comment on signature

* Adjust ssz-max in SignedSSVMessage

* Include RSA check in test

* Generate JSONs
  • Loading branch information
MatheusFranco99 authored Mar 21, 2024
1 parent a57c4bc commit df58d97
Show file tree
Hide file tree
Showing 22 changed files with 608 additions and 7 deletions.
31 changes: 27 additions & 4 deletions p2p/validation/msg_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package validation

import (
"context"

"github.com/bloxapp/ssv-spec/qbft"
"github.com/bloxapp/ssv-spec/ssv"
"github.com/bloxapp/ssv-spec/types"
Expand All @@ -15,11 +16,19 @@ type MsgValidatorFunc = func(ctx context.Context, p peer.ID, msg *pubsub.Message

func MsgValidation(runner ssv.Runner) MsgValidatorFunc {
return func(ctx context.Context, p peer.ID, msg *pubsub.Message) pubsub.ValidationResult {
ssvMsg, err := DecodePubsubMsg(msg)
signedSSVMsg, err := DecodePubsubMsg(msg)
if err != nil {
return pubsub.ValidationReject
}
if validateSSVMessage(runner, ssvMsg) != nil {

// Validate SignedSSVMessage
if validateSignedSSVMessage(runner, signedSSVMsg) != nil {
return pubsub.ValidationReject
}

// Get SSVMessage
ssvMsg, err := signedSSVMsg.GetSSVMessageFromData()
if err != nil {
return pubsub.ValidationReject
}

Expand All @@ -40,15 +49,29 @@ func MsgValidation(runner ssv.Runner) MsgValidatorFunc {
}
}

func DecodePubsubMsg(msg *pubsub.Message) (*types.SSVMessage, error) {
func DecodePubsubMsg(msg *pubsub.Message) (*types.SignedSSVMessage, error) {
byts := msg.GetData()
ret := &types.SSVMessage{}
ret := &types.SignedSSVMessage{}
if err := ret.Decode(byts); err != nil {
return nil, err
}
return ret, nil
}

func validateSignedSSVMessage(runner ssv.Runner, msg *types.SignedSSVMessage) error {

if err := msg.Validate(); err != nil {
return err
}

ssvMessage, err := msg.GetSSVMessageFromData()
if err != nil {
return err
}

return validateSSVMessage(runner, ssvMessage)
}

func validateSSVMessage(runner ssv.Runner, msg *types.SSVMessage) error {
if !runner.GetBaseRunner().Share.ValidatorPubKey.MessageIDBelongs(msg.GetID()) {
return errors.New("msg ID doesn't match validator ID")
Expand Down
2 changes: 1 addition & 1 deletion types/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package types
//go:generate go run github.com/ferranbt/fastssz/sszgen --path share.go --include ./operator.go,./messages.go,./signer.go,./domain_type.go

// rm -f ./messages_encoding.go
// go run github.com/ferranbt/fastssz/sszgen --path messages.go --exclude-objs ValidatorPK,MessageID,MsgType
// go run github.com/ferranbt/fastssz/sszgen --path messages.go --include ./operator.go --exclude-objs ValidatorPK,MessageID,MsgType

//go:generate rm -f ./beacon_types_encoding.go
//go:generate go run github.com/ferranbt/fastssz/sszgen --path beacon_types.go --include $GOPATH/pkg/mod/github.com/attestantio/[email protected]/spec/phase0 --exclude-objs BeaconNetwork,BeaconRole
Expand Down
61 changes: 61 additions & 0 deletions types/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"bytes"
"encoding/binary"
"encoding/hex"

"github.com/pkg/errors"
)

// ValidatorPK is an eth2 validator public key
Expand Down Expand Up @@ -125,3 +127,62 @@ func (msg *SSVMessage) Encode() ([]byte, error) {
func (msg *SSVMessage) Decode(data []byte) error {
return msg.UnmarshalSSZ(data)
}

// SSVMessage is the main message passed within the SSV network. It encapsulates the SSVMessage structure and a signature
type SignedSSVMessage struct {
OperatorID OperatorID
Signature []byte `ssz-max:"512"` // Created by the operator's private key. Max size allow keys up to 512*8 = 4096 bits
Data []byte `ssz-max:"6291893"` // Max size extracted from SSVMessage
}

// GetOperatorID returns the sender operator ID
func (msg *SignedSSVMessage) GetOperatorID() OperatorID {
return msg.OperatorID
}

// GetSignature returns the signature of the OperatorID over Data
func (msg *SignedSSVMessage) GetSignature() []byte {
return msg.Signature
}

// GetData returns message Data as byte slice
func (msg *SignedSSVMessage) GetData() []byte {
return msg.Data
}

// GetSSVMessageFromData returns message SSVMessage decoded from data
func (msg *SignedSSVMessage) GetSSVMessageFromData() (*SSVMessage, error) {
ssvMessage := &SSVMessage{}
err := ssvMessage.Decode(msg.Data)
if err != nil {
return nil, errors.Wrap(err, "could not decode SSVMessage from data in SignedSSVMessage")
}
return ssvMessage, nil
}

// Encode returns a msg encoded bytes or error
func (msg *SignedSSVMessage) Encode() ([]byte, error) {
return msg.MarshalSSZ()
}

// Decode returns error if decoding failed
func (msg *SignedSSVMessage) Decode(data []byte) error {
return msg.UnmarshalSSZ(data)
}

// Validate checks the following rules:
// - OperatorID should not be 0
// - Signature length should not be 0
// - Data length should not be 0
func (msg *SignedSSVMessage) Validate() error {
if msg.OperatorID == 0 {
return errors.New("OperatorID in SignedSSVMessage is 0")
}
if len(msg.Signature) == 0 {
return errors.New("Signature has length 0 in SignedSSVMessage")
}
if len(msg.Data) == 0 {
return errors.New("Data has length 0 in SignedSSVMessage")
}
return nil
}
152 changes: 151 additions & 1 deletion types/messages_encoding.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions types/spectest/all_tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"github.com/bloxapp/ssv-spec/types/spectest/tests/partialsigmessage"
"github.com/bloxapp/ssv-spec/types/spectest/tests/share"
"github.com/bloxapp/ssv-spec/types/spectest/tests/ssvmsg"

"github.com/bloxapp/ssv-spec/types/spectest/tests/signedssvmsg"
"github.com/bloxapp/ssv-spec/types/spectest/tests/ssz"
)

Expand Down Expand Up @@ -97,6 +99,13 @@ var AllTests = []SpecTest{

beacon.DepositData(),

signedssvmsg.Encoding(),
signedssvmsg.Valid(),
signedssvmsg.NoData(),
signedssvmsg.EmptySignature(),
signedssvmsg.ZeroSigner(),
signedssvmsg.WrongData(),

share.HasPartialQuorumButNoQuorum(),
share.HasQuorum(),
share.HasQuorum3f1(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"Name": "encoding",
"Data": "AQAAAAAAAAAQAAAAEAEAAJ4RbcE7rt9XkrU0Gz+CmiUMg88fH/b8hB/oHOpFocKDdcWx5Q5xbAjiCHmq8rZtUHzrskOqPoZLsR9UY3LRAlJF9ban+DOnDnmloFi67e82d6EAfk6AYZ1ZNSZinWVYkRvP03J5gk3yRddHhPOWVDc4rwdxGYrTOLNZTTwyMcEiBqrPMrJ2SDwVpmw9RXGdEDNLrpVsuBRsCQKjr+7X1PBijkvmDfZO78uzyELIr/WUXWjgeBt1JK+4EVS2fn6DHY+t4E+kjKOrwsTw/+I6h7onqZa4kN7MM/10Cftu/NRTFhLiSwAxGgu6PcrDfDfmpaqFZgr1kdGrrGp8gDgB4CcBAAAAAAAAAAAAAwGOgAZlUagbMYJYcJ7a990fY81oag5NuLKbu3rP5lYIZ3r1pSfZRI7keDVIXgK1C8AAAAAARAAAAGwAAAC4Hs0i5KpVrepqk99cOgnRwFklXk1z+iLSuhz7kDMpGlKR3Fcf+DnJb/Hl+PSPwFcARY04jz4nVo8NdgTUduo7GOUm+WixamknKtLuJv5boz/EBTmKKiYlItZjiR4ztSABAAAAAAAAAAIAAAAAAAAADAAAAAAAAAAUAAAApHmwI9nyjrnM3TW7lg+1wmVTDf8Xiufkqbd/AX91nKWiEl5ya94M2SozMAlUlMjAB4Kif6iQfowarePazbjgYUaGxn4fYoMEYF14YeDtmAPGriFrSq5VqP+0nu0ZPL6nRiYR0sWSvfUhTxJP56Ummrc9RO/J5s4avjL4GWrlJt4BAAAAAAAAAA=="
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"Name": "empty signature",
"Messages": [
{
"OperatorID": 1,
"Signature": "",
"Data": "AQIDBA=="
}
],
"ExpectedError": "Signature has length 0 in SignedSSVMessage",
"RSAPublicKey": null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"Name": "no data",
"Messages": [
{
"OperatorID": 1,
"Signature": "AQIDBA==",
"Data": ""
}
],
"ExpectedError": "Data has length 0 in SignedSSVMessage",
"RSAPublicKey": null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"Name": "valid",
"Messages": [
{
"OperatorID": 1,
"Signature": "asg313UXGPJPH1X4S5kFA0mP0EViK+/fiAudKPNWxmgSLAOOZa+zwhUCkd1lI6Mzxta8GsUwxxRekEclK7ipkjqeND6S9M5+EyyKOIXPkv3jaSHSJgy3czrM95vmr+ZEvlFeNVc1ueCVSc4tYn1WPE2Jgv5x2yGiI65gxOptXXUULfwxeTt+N+9nhKwYkHkosHYLEcSzVJ8+VSBLtQUQhZPAIhQBAQU5QO2xlHQaGz3AYoWXf1dMI3fmDJzxxT+We2pwW8mZ5uFiZnKxJKbo0Qjw6Pp8ZGBHAf9+3O3AxHjpwgJq7enmMTPVcgf8igiB4lqPSS2EbpNUBkAo6CyXqg==",
"Data": "AQAAAAAAAAAAAAMBjoAGZVGoGzGCWHCe2vfdH2PNaGoOTbiym7t6z+ZWCGd69aUn2USO5Hg1SF4CtQvAAAAAAEQAAABsAAAAuB7NIuSqVa3qapPfXDoJ0cBZJV5Nc/oi0roc+5AzKRpSkdxXH/g5yW/x5fj0j8BXAEWNOI8+J1aPDXYE1HbqOxjlJvlosWppJyrS7ib+W6M/xAU5iiomJSLWY4keM7UgAQAAAAAAAAACAAAAAAAAAAwAAAAAAAAAFAAAAKR5sCPZ8o65zN01u5YPtcJlUw3/F4rn5Km3fwF/dZylohJecmveDNkqMzAJVJTIwAeCon+okH6MGq3j2s244GFGhsZ+H2KDBGBdeGHg7ZgDxq4ha0quVaj/tJ7tGTy+p0YmEdLFkr31IU8ST+elJpq3PUTvyebOGr4y+Blq5SbeAQAAAAAAAAA="
}
],
"ExpectedError": "",
"RSAPublicKey": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBdU1WaU9YbWZ6aTA5MnZ6aUZrVUkKRHNRdEhLemlRZXh2cDhCa0lBd3R4cXpadFJXT2IzVFp3NG8zbDB3Z2RiQ0wvQzBLUWlMOUFCOGViTUQzUi9UdApFRXJtcEhHdTlDOTY5OTdyNlhtbjk2a3RabjN2RjdXUzN4elFHTytkR2Z0S0hLMG5YdldLVXAvcUJ6KzFFNnBYCkVTeVNHR01lZ2w5L3BSQkdXSEZVZUVXODRDV0ttaWlXVU1aYXBlTE1BalJwK20zTi96Unc3dHVpMmZrVnNFV0UKNGwxck01VlZ1R0JOUFc2dDR3cUJpbDdHY3pHNmpyQ3Z2TDJEZzF6eDM3cUVWZHBkMVBQdjc1VzdQUlVuTzV5NApkVTVwSEZPUENwbmZvRkJENjgwOTZHYW5EU2NTaDRpd3VkeGgyTGg0MmREVzI2eUNQYTQ3OUZXd0NFMk9JVEk1Cjl3SURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"Name": "wrong data",
"Messages": [
{
"OperatorID": 1,
"Signature": "AQIDBA==",
"Data": "AQIDBA=="
}
],
"ExpectedError": "could not decode SSVMessage from data in SignedSSVMessage: incorrect size",
"RSAPublicKey": null
}
Loading

0 comments on commit df58d97

Please sign in to comment.