Skip to content

Commit

Permalink
capability: allow to decode unknown capabilities
Browse files Browse the repository at this point in the history
It's more symmetric than the C# counterpart, but the essence is the same: we
can accept capabilities we can't interpret. Refs. neo-project/neo#3639

Signed-off-by: Roman Khimov <roman@nspcc.ru>
  • Loading branch information
roman-khimov committed Dec 28, 2024
1 parent 47b6793 commit 4720727
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 4 deletions.
28 changes: 24 additions & 4 deletions pkg/network/capability/capability.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ import (
"github.com/nspcc-dev/neo-go/pkg/io"
)

// MaxCapabilities is the maximum number of capabilities per payload.
const MaxCapabilities = 32
const (
// MaxCapabilities is the maximum number of capabilities per payload.
MaxCapabilities = 32

// MaxDataSize is the maximum size of capability payload.
MaxDataSize = 1024
)

// Capabilities is a list of Capability.
type Capabilities []Capability
Expand Down Expand Up @@ -65,8 +70,7 @@ func (c *Capability) DecodeBinary(br *io.BinReader) {
case TCPServer, WSServer:
c.Data = &Server{}
default:
br.Err = errors.New("unknown node capability type")
return
c.Data = &Unknown{}
}
c.Data.DecodeBinary(br)
}
Expand Down Expand Up @@ -111,3 +115,19 @@ func (s *Server) DecodeBinary(br *io.BinReader) {
func (s *Server) EncodeBinary(bw *io.BinWriter) {
bw.WriteU16LE(s.Port)
}

// Unknown represents an unknown capability with some data. Other nodes can
// decode it even if they can't interpret it. This is not expected to be used
// for sending data directly (proper new types should be used), but it allows
// for easier protocol extensibility (old nodes won't reject new capabilities).
type Unknown []byte

// DecodeBinary implements io.Serializable.
func (u *Unknown) DecodeBinary(br *io.BinReader) {
*u = br.ReadVarBytes()
}

// EncodeBinary implements io.Serializable.
func (u *Unknown) EncodeBinary(bw *io.BinWriter) {
bw.WriteVarBytes(*u)
}
15 changes: 15 additions & 0 deletions pkg/network/capability/capability_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package capability

import (
"testing"

"github.com/nspcc-dev/neo-go/internal/testserdes"
)

func TestUnknownEncodeDecode(t *testing.T) {
var (
u = Unknown{0x55, 0xaa}
ud Unknown
)
testserdes.EncodeDecodeBinary(t, &u, &ud)
}
8 changes: 8 additions & 0 deletions pkg/network/payload/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,20 @@ func TestVersionEncodeDecode(t *testing.T) {
Port: wsPort,
},
},
{
Type: 0xff,
Data: &capability.Unknown{},
},
{
Type: capability.FullNode,
Data: &capability.Node{
StartHeight: height,
},
},
{
Type: 0xf0,
Data: &capability.Unknown{0x55, 0xaa},
},
}

version := NewVersion(magic, id, useragent, capabilities)
Expand Down

0 comments on commit 4720727

Please sign in to comment.