network: implement getblocks command
Fixes #577, tested with C# nodes connecting to neo-go privnet.
This commit is contained in:
parent
9145855d2c
commit
234d94d27e
2 changed files with 37 additions and 0 deletions
|
@ -5,6 +5,11 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/util"
|
"github.com/CityOfZion/neo-go/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Maximum inventory hashes number is limited to 500.
|
||||||
|
const (
|
||||||
|
MaxHashesCount = 500
|
||||||
|
)
|
||||||
|
|
||||||
// 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
|
||||||
|
|
|
@ -463,6 +463,35 @@ func (s *Server) handleGetDataCmd(p Peer, inv *payload.Inventory) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleGetBlocksCmd processes the getblocks request.
|
||||||
|
func (s *Server) handleGetBlocksCmd(p Peer, gb *payload.GetBlocks) error {
|
||||||
|
if len(gb.HashStart) < 1 {
|
||||||
|
return errInvalidHashStart
|
||||||
|
}
|
||||||
|
startHash := gb.HashStart[0]
|
||||||
|
if startHash.Equals(gb.HashStop) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
start, err := s.chain.GetHeader(startHash)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
blockHashes := make([]util.Uint256, 0)
|
||||||
|
for i := start.Index + 1; i < start.Index+1+payload.MaxHashesCount; i++ {
|
||||||
|
hash := s.chain.GetHeaderHash(int(i))
|
||||||
|
if hash.Equals(util.Uint256{}) || hash.Equals(gb.HashStop) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
blockHashes = append(blockHashes, hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(blockHashes) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
payload := payload.NewInventory(payload.BlockType, blockHashes)
|
||||||
|
return p.WriteMsg(NewMessage(s.Net, CMDInv, payload))
|
||||||
|
}
|
||||||
|
|
||||||
// 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 {
|
if len(gh.HashStart) < 1 {
|
||||||
|
@ -585,6 +614,9 @@ func (s *Server) handleMessage(peer Peer, msg *Message) error {
|
||||||
case CMDGetAddr:
|
case CMDGetAddr:
|
||||||
// it has no payload
|
// it has no payload
|
||||||
return s.handleGetAddrCmd(peer)
|
return s.handleGetAddrCmd(peer)
|
||||||
|
case CMDGetBlocks:
|
||||||
|
gb := msg.Payload.(*payload.GetBlocks)
|
||||||
|
return s.handleGetBlocksCmd(peer, gb)
|
||||||
case CMDGetData:
|
case CMDGetData:
|
||||||
inv := msg.Payload.(*payload.Inventory)
|
inv := msg.Payload.(*payload.Inventory)
|
||||||
return s.handleGetDataCmd(peer, inv)
|
return s.handleGetDataCmd(peer, inv)
|
||||||
|
|
Loading…
Reference in a new issue