forked from TrueCloudLab/neoneo-go
Merge pull request #983 from nspcc-dev/neo3/protocol/getblocks
protocol: refactor getblocks payload
This commit is contained in:
commit
d12d198eed
3 changed files with 42 additions and 48 deletions
|
@ -1,6 +1,8 @@
|
||||||
package payload
|
package payload
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
)
|
)
|
||||||
|
@ -13,27 +15,30 @@ const (
|
||||||
// GetBlocks contains fields and methods to be shared with the
|
// GetBlocks contains fields and methods to be shared with the
|
||||||
type GetBlocks struct {
|
type GetBlocks struct {
|
||||||
// hash of latest block that node requests
|
// hash of latest block that node requests
|
||||||
HashStart []util.Uint256
|
HashStart util.Uint256
|
||||||
// hash of last block that node requests
|
Count int16
|
||||||
HashStop util.Uint256
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGetBlocks returns a pointer to a GetBlocks object.
|
// NewGetBlocks returns a pointer to a GetBlocks object.
|
||||||
func NewGetBlocks(start []util.Uint256, stop util.Uint256) *GetBlocks {
|
func NewGetBlocks(start util.Uint256, count int16) *GetBlocks {
|
||||||
return &GetBlocks{
|
return &GetBlocks{
|
||||||
HashStart: start,
|
HashStart: start,
|
||||||
HashStop: stop,
|
Count: count,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeBinary implements Serializable interface.
|
// DecodeBinary implements Serializable interface.
|
||||||
func (p *GetBlocks) DecodeBinary(br *io.BinReader) {
|
func (p *GetBlocks) DecodeBinary(br *io.BinReader) {
|
||||||
br.ReadArray(&p.HashStart)
|
p.HashStart.DecodeBinary(br)
|
||||||
br.ReadBytes(p.HashStop[:])
|
p.Count = int16(br.ReadU16LE())
|
||||||
|
if p.Count < -1 || p.Count == 0 {
|
||||||
|
br.Err = errors.New("invalid count")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodeBinary implements Serializable interface.
|
// EncodeBinary implements Serializable interface.
|
||||||
func (p *GetBlocks) EncodeBinary(bw *io.BinWriter) {
|
func (p *GetBlocks) EncodeBinary(bw *io.BinWriter) {
|
||||||
bw.WriteArray(p.HashStart)
|
p.HashStart.EncodeBinary(bw)
|
||||||
bw.WriteBytes(p.HashStop[:])
|
bw.WriteU16LE(uint16(p.Count))
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,31 +5,24 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/internal/testserdes"
|
"github.com/nspcc-dev/neo-go/pkg/internal/testserdes"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetBlockEncodeDecode(t *testing.T) {
|
func TestGetBlockEncodeDecode(t *testing.T) {
|
||||||
start := []util.Uint256{
|
start := hash.Sha256([]byte("a"))
|
||||||
hash.Sha256([]byte("a")),
|
|
||||||
hash.Sha256([]byte("b")),
|
|
||||||
hash.Sha256([]byte("c")),
|
|
||||||
hash.Sha256([]byte("d")),
|
|
||||||
}
|
|
||||||
|
|
||||||
p := NewGetBlocks(start, util.Uint256{})
|
p := NewGetBlocks(start, 124)
|
||||||
testserdes.EncodeDecodeBinary(t, p, new(GetBlocks))
|
testserdes.EncodeDecodeBinary(t, p, new(GetBlocks))
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetBlockEncodeDecodeWithHashStop(t *testing.T) {
|
// invalid count
|
||||||
var (
|
p = NewGetBlocks(start, -2)
|
||||||
start = []util.Uint256{
|
data, err := testserdes.EncodeBinary(p)
|
||||||
hash.Sha256([]byte("a")),
|
require.NoError(t, err)
|
||||||
hash.Sha256([]byte("b")),
|
require.Error(t, testserdes.DecodeBinary(data, new(GetBlocks)))
|
||||||
hash.Sha256([]byte("c")),
|
|
||||||
hash.Sha256([]byte("d")),
|
// invalid count
|
||||||
}
|
p = NewGetBlocks(start, 0)
|
||||||
stop = hash.Sha256([]byte("e"))
|
data, err = testserdes.EncodeBinary(p)
|
||||||
)
|
require.NoError(t, err)
|
||||||
p := NewGetBlocks(start, stop)
|
require.Error(t, testserdes.DecodeBinary(data, new(GetBlocks)))
|
||||||
testserdes.EncodeDecodeBinary(t, p, new(GetBlocks))
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -535,21 +535,18 @@ func (s *Server) handleGetDataCmd(p Peer, inv *payload.Inventory) error {
|
||||||
|
|
||||||
// handleGetBlocksCmd processes the getblocks request.
|
// handleGetBlocksCmd processes the getblocks request.
|
||||||
func (s *Server) handleGetBlocksCmd(p Peer, gb *payload.GetBlocks) error {
|
func (s *Server) handleGetBlocksCmd(p Peer, gb *payload.GetBlocks) error {
|
||||||
if len(gb.HashStart) < 1 {
|
count := gb.Count
|
||||||
return errInvalidHashStart
|
if gb.Count < 0 || gb.Count > payload.MaxHashesCount {
|
||||||
|
count = payload.MaxHashesCount
|
||||||
}
|
}
|
||||||
startHash := gb.HashStart[0]
|
start, err := s.chain.GetHeader(gb.HashStart)
|
||||||
if startHash.Equals(gb.HashStop) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
start, err := s.chain.GetHeader(startHash)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
blockHashes := make([]util.Uint256, 0)
|
blockHashes := make([]util.Uint256, 0)
|
||||||
for i := start.Index + 1; i < start.Index+1+payload.MaxHashesCount; i++ {
|
for i := start.Index + 1; i < start.Index+uint32(count); i++ {
|
||||||
hash := s.chain.GetHeaderHash(int(i))
|
hash := s.chain.GetHeaderHash(int(i))
|
||||||
if hash.Equals(util.Uint256{}) || hash.Equals(gb.HashStop) {
|
if hash.Equals(util.Uint256{}) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
blockHashes = append(blockHashes, hash)
|
blockHashes = append(blockHashes, hash)
|
||||||
|
@ -565,19 +562,19 @@ func (s *Server) handleGetBlocksCmd(p Peer, gb *payload.GetBlocks) error {
|
||||||
|
|
||||||
// handleGetHeadersCmd processes the getheaders request.
|
// handleGetHeadersCmd processes the getheaders request.
|
||||||
func (s *Server) handleGetHeadersCmd(p Peer, gh *payload.GetBlocks) error {
|
func (s *Server) handleGetHeadersCmd(p Peer, gh *payload.GetBlocks) error {
|
||||||
if len(gh.HashStart) < 1 {
|
count := gh.Count
|
||||||
return errInvalidHashStart
|
if gh.Count < 0 || gh.Count > payload.MaxHashesCount {
|
||||||
|
count = payload.MaxHashesCount
|
||||||
}
|
}
|
||||||
startHash := gh.HashStart[0]
|
start, err := s.chain.GetHeader(gh.HashStart)
|
||||||
start, err := s.chain.GetHeader(startHash)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
resp := payload.Headers{}
|
resp := payload.Headers{}
|
||||||
resp.Hdrs = make([]*block.Header, 0, payload.MaxHeadersAllowed)
|
resp.Hdrs = make([]*block.Header, 0, payload.MaxHeadersAllowed)
|
||||||
for i := start.Index + 1; i < start.Index+1+payload.MaxHeadersAllowed; i++ {
|
for i := start.Index + 1; i < start.Index+uint32(count); i++ {
|
||||||
hash := s.chain.GetHeaderHash(int(i))
|
hash := s.chain.GetHeaderHash(int(i))
|
||||||
if hash.Equals(util.Uint256{}) || hash.Equals(gh.HashStop) {
|
if hash.Equals(util.Uint256{}) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
header, err := s.chain.GetHeader(hash)
|
header, err := s.chain.GetHeader(hash)
|
||||||
|
@ -637,10 +634,9 @@ func (s *Server) handleGetAddrCmd(p Peer) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// requestHeaders sends a getheaders message to the peer.
|
// requestHeaders sends a getheaders message to the peer.
|
||||||
// The peer will respond with headers op to a count of 2000.
|
// The peer will respond with headers op to a count of 500.
|
||||||
func (s *Server) requestHeaders(p Peer) error {
|
func (s *Server) requestHeaders(p Peer) error {
|
||||||
start := []util.Uint256{s.chain.CurrentHeaderHash()}
|
payload := payload.NewGetBlocks(s.chain.CurrentHeaderHash(), -1)
|
||||||
payload := payload.NewGetBlocks(start, util.Uint256{})
|
|
||||||
return p.EnqueueP2PMessage(NewMessage(CMDGetHeaders, payload))
|
return p.EnqueueP2PMessage(NewMessage(CMDGetHeaders, payload))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue