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"
|
||||
)
|
||||
|
||||
// Maximum inventory hashes number is limited to 500.
|
||||
const (
|
||||
MaxHashesCount = 500
|
||||
)
|
||||
|
||||
// GetBlocks contains fields and methods to be shared with the
|
||||
type GetBlocks struct {
|
||||
// hash of latest block that node requests
|
||||
|
|
|
@ -463,6 +463,35 @@ func (s *Server) handleGetDataCmd(p Peer, inv *payload.Inventory) error {
|
|||
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.
|
||||
func (s *Server) handleGetHeadersCmd(p Peer, gh *payload.GetBlocks) error {
|
||||
if len(gh.HashStart) < 1 {
|
||||
|
@ -585,6 +614,9 @@ func (s *Server) handleMessage(peer Peer, msg *Message) error {
|
|||
case CMDGetAddr:
|
||||
// it has no payload
|
||||
return s.handleGetAddrCmd(peer)
|
||||
case CMDGetBlocks:
|
||||
gb := msg.Payload.(*payload.GetBlocks)
|
||||
return s.handleGetBlocksCmd(peer, gb)
|
||||
case CMDGetData:
|
||||
inv := msg.Payload.(*payload.Inventory)
|
||||
return s.handleGetDataCmd(peer, inv)
|
||||
|
|
Loading…
Reference in a new issue