func (s *NodeServerRequest) handleGetBlocks() error {
	var payload nodeclient.ComGetBlocks
	err := s.parseRequestData(&payload)
	if err != nil {
		return err
	}
	blocks := s.Node.NodeBC.GetBCManager().GetBlocksShortInfo(payload.StartFrom, 1000)
	s.Logger.Trace.Printf("Loaded %d block hashes", len(blocks))
	data := [][]byte{}
	for i := len(blocks) - 1; i >= 0; i-- {
		bdata, _ := blocks[i].Serialize()
		data = append(data, bdata)
		s.Logger.Trace.Printf("Block: %x", blocks[i].Hash)
	}
	s.Node.CheckAddressKnown(payload.AddrFrom)
	return s.Node.NodeClient.SendInv(payload.AddrFrom, "block", data)
}
/*
Request to get list of blocks hashes .
It can contain a starting block hash to return data from it
If no that starting hash, then data from a top are returned
package server
import (
	"bytes"
	"encoding/gob"
	"errors"
	"fmt"
	"github.com/gelembjuk/democoin/lib/net"
	"github.com/gelembjuk/democoin/lib/nodeclient"
	"github.com/gelembjuk/democoin/lib/utils"
	"github.com/gelembjuk/democoin/node/blockchain"
	"github.com/gelembjuk/democoin/node/nodemanager"
	"github.com/gelembjuk/democoin/node/structures"
	"github.com/gelembjuk/democoin/node/transactions"
)
type NodeServerRequest struct {
	Node              *nodemanager.Node
	S                 *NodeServer
	Request           []byte
	RequestIP         string
	Logger            *utils.LoggerMan
	HasResponse       bool
	Response          []byte
	NodeAuthStrIsGood bool
	SessID            string
}
func (s *NodeServerRequest) Init() {
	s.HasResponse = false
	s.Response = nil
}
func (s *NodeServerRequest) parseRequestData(payload interface{}) error {
	var buff bytes.Buffer
	buff.Write(s.Request)
	dec := gob.NewDecoder(&buff)
	err := dec.Decode(payload)
	if err != nil {
		return errors.New("Parse request: " + err.Error())
	}
	return nil
}
func (s *NodeServerRequest) handleGetUnspent() error {
	s.HasResponse = true
	var payload nodeclient.ComGetUnspentTransactions
	err := s.parseRequestData(&payload)
	if err != nil {
		return err
	}
	result := nodeclient.ComUnspentTransactions{}
	result.LastBlock, err = s.Node.NodeBC.GetTopBlockHash()
	if err != nil {
		return err
	}
	err = s.Node.GetTransactionsManager().ForEachUnspentOutput(payload.Address,
		func(fromaddr string, value float64, txID []byte, output int, isbase bool) error {
			ut := nodeclient.ComUnspentTransaction{}
			ut.Amount = value
			ut.TXID = txID
			ut.Vout = output
			ut.From = fromaddr
			ut.IsBase = isbase
			result.Transactions = append(result.Transactions, ut)
			return nil
		})
	if err != nil {
		return err
	}
	s.Response, err = net.GobEncode(result)
	if err != nil {
		return err
	}
	s.Logger.Trace.Printf("Return %d unspent transactions for %s\n", len(result.Transactions), payload.Address)
	return nil
}
func (s *NodeServerRequest) handleGetHistory() error {
	s.HasResponse = true
	var payload nodeclient.ComGetHistoryTransactions
	err := s.parseRequestData(&payload)
	if err != nil {
		return err
	}
	result := []nodeclient.ComHistoryTransaction{}
	history, err := s.Node.NodeBC.GetAddressHistory(payload.Address)
	if err != nil {
		return err
	}
	for _, t := range history {
		ut := nodeclient.ComHistoryTransaction{}
		ut.Amount = t.Value
		ut.IOType = t.IOType
		ut.TXID = t.TXID
		if t.IOType {
			ut.From = t.Address
		} else {
			ut.To = t.Address
		}
		result = append(result, ut)
	}
	s.Response, err = net.GobEncode(result)
	if err != nil {
		return err
	}
	s.Logger.Trace.Printf("Return %d history records for %s\n", len(result), payload.Address)
	return nil
}
func (s *NodeServerRequest) handleGetBalance() error {
	s.HasResponse = true
	var payload nodeclient.ComGetWalletBalance
	err := s.parseRequestData(&payload)
	if err != nil {
		return err
	}
	balance := nodeclient.ComWalletBalance{}
	balancen, err := s.Node.GetTransactionsManager().GetAddressBalance(payload.Address)
	if err != nil {
		return err
	}
	balance.Total = balancen.Total
	balance.Approved = balancen.Approved
	balance.Pending = balancen.Pending
	s.Response, err = net.GobEncode(balance)
	if err != nil {
		return err
	}
	s.Logger.Trace.Printf("Return balance for %s. %.8f, %.8f, %.8f", payload.Address, balance.Total, balance.Approved, balance.Pending)
	return nil
}
func (s *NodeServerRequest) handleTxFull() error {
	s.HasResponse = true
	var payload nodeclient.ComNewTransaction
	err := s.parseRequestData(&payload)
	if err != nil {
		return err
	}
	TX := structures.Transaction{}
	TX.DeserializeTransaction(payload.TX)
	err = s.Node.GetTransactionsManager().ReceivedNewTransaction(&TX)
	if err != nil {
		return errors.New(fmt.Sprintf("Transaction accepting error: %s", err.Error()))
	}
	s.Logger.Trace.Printf("Acceppted new transaction from %s\n", payload.Address)
	s.S.TryToMakeNewBlock(TX.ID)
	s.Response, err = net.GobEncode(payload.TX)
	if err != nil {
		return errors.New(fmt.Sprintf("TXFull Response Error: %s", err.Error()))
	}
	return nil
}
func (s *NodeServerRequest) handleTxData() error {
	s.HasResponse = true
	var payload nodeclient.ComNewTransactionData
	err := s.parseRequestData(&payload)
	if err != nil {
		return err
	}
	TX, err := s.Node.GetTransactionsManager().ReceivedNewTransactionData(payload.TX, payload.Signatures)
	if err != nil {
		return errors.New(fmt.Sprintf("Transaction accepting error: %s", err.Error()))
	}
	s.Logger.Trace.Printf("Acceppted new transaction from %s\n", payload.Address)
	s.S.TryToMakeNewBlock(TX.ID)
	s.Response, err = net.GobEncode(TX.ID)
	if err != nil {
		return errors.New(fmt.Sprintf("TXFull Response Error: %s", err.Error()))
	}
	return nil
}
func (s *NodeServerRequest) handleTxRequest() error {
	s.HasResponse = true
	var payload nodeclient.ComRequestTransaction
	err := s.parseRequestData(&payload)
	if err != nil {
		return err
	}
	result := nodeclient.ComRequestTransactionData{}
	TXBytes, DataToSign, err := s.Node.GetTransactionsManager().
		PrepareNewTransaction(payload.PubKey, payload.To, payload.Amount)
	if err != nil {
		return err
	}
	result.DataToSign = DataToSign
	result.TX = TXBytes
	s.Response, err = net.GobEncode(result)
	if err != nil {
		return err
	}
	return nil
}
func (s *NodeServerRequest) handleGetFirstBlocks() error {
	s.HasResponse = true
	result := nodeclient.ComGetFirstBlocksData{}
	blocks, height, err := s.Node.NodeBC.GetBCManager().GetFirstBlocks(10)
	if err != nil {
		return err
	}
	result.Blocks = [][]byte{}
	result.Height = height
	for _, block := range blocks {
		blockdata, err := block.Serialize()
		if err != nil {
			return err
		}
		result.Blocks = append(result.Blocks, blockdata)
	}
	s.Response, err = net.GobEncode(result)
	if err != nil {
		return err
	}
	s.Logger.Trace.Printf("Return first %d blocks\n", len(blocks))
	return nil
}
func (s *NodeServerRequest) handleAddr() error {
	var payload []net.NodeAddr
	err := s.parseRequestData(&payload)
	if err != nil {
		return err
	}
	addednodes := []net.NodeAddr{}
	s.Logger.Trace.Printf("SessID: %s . Received nodes %s", s.SessID, payload)
	for _, node := range payload {
		s.Logger.Trace.Printf("SessID: %s . node %s", s.SessID, node.NodeAddrToString())
		if s.S.Node.NodeNet.AddNodeToKnown(node) {
			addednodes = append(addednodes, node)
			s.Logger.Trace.Printf("SessID: %s . node appended %s", s.SessID, node.NodeAddrToString())
		}
	}
	s.Logger.Trace.Printf("SessID: %s . There are %d known nodes now!", s.SessID, len(s.Node.NodeNet.Nodes))
	s.Logger.Trace.Printf("SessID: %s . Send version to %d new nodes", s.SessID, len(addednodes))
	if len(addednodes) > 0 {
		s.Node.SendVersionToNodes(addednodes)
	}
	return nil
}
func (s *NodeServerRequest) handleBlock() error {
	var payload nodeclient.ComBlock
	err := s.parseRequestData(&payload)
	if err != nil {
		return err
	}
	blockstate, addstate, block, err := s.Node.ReceivedFullBlockFromOtherNode(payload.Block)
	s.Logger.Trace.Printf("adding new block %d, %d", blockstate, addstate)
	if err != nil {
		return err
	}
	if blockstate == 0 {
		s.Logger.Trace.Printf("send block to all ")
		s.Node.SendBlockToAll(block, payload.AddrFrom)
	}
	s.Logger.Trace.Printf("check count blocks left %d ", s.S.Transit.GetBlocksCount(payload.AddrFrom))
	if s.S.Transit.GetBlocksCount(payload.AddrFrom) > 0 {
		for {
			blockdata, err := s.S.Transit.ShiftNextBlock(payload.AddrFrom)
			if err != nil {
				s.Logger.Trace.Printf("Request new block failed %s ", err.Error())
				return err
			}
			blockstate, err := s.Node.ReceivedBlockFromOtherNode(payload.AddrFrom, blockdata)
			if err != nil {
				return err
			}
			if blockstate == 0 {
				break
			}
			if blockstate == 2 {
				s.S.Transit.CleanBlocks(payload.AddrFrom)
				bs := &structures.BlockShort{}
				err := bs.DeserializeBlock(blockdata)
				if err != nil {
					return err
				}
				s.Node.NodeClient.SendGetBlocks(payload.AddrFrom, bs.PrevBlockHash)
			}
			if s.S.Transit.GetBlocksCount(payload.AddrFrom) == 0 {
				break
			}
		}
	}
	s.Logger.Trace.Printf("check if try to make new %d , %d ", addstate, blockchain.BCBAddState_addedToParallelTop)
	if addstate == blockchain.BCBAddState_addedToParallelTop {
		s.S.TryToMakeNewBlock([]byte{1})
	}
	s.Node.CheckAddressKnown(payload.AddrFrom)
	return nil
}
func (s *NodeServerRequest) handleInv() error {
	var payload nodeclient.ComInv
	err := s.parseRequestData(&payload)
	if err != nil {
		return err
	}
	s.Logger.Trace.Printf("SessID: %s . Recevied inventory with %d %s\n", s.SessID, len(payload.Items), payload.Type)
	if payload.Type == "block" {
		s.S.Transit.AddBlocks(payload.AddrFrom, payload.Items)
		for {
			blockdata, err := s.S.Transit.ShiftNextBlock(payload.AddrFrom)
			if err != nil {
				return err
			}
			blockstate, err := s.Node.ReceivedBlockFromOtherNode(payload.AddrFrom, blockdata)
			if err != nil {
				return err
			}
			if blockstate == 0 {
				break
			}
			if blockstate == 2 {
				s.S.Transit.CleanBlocks(payload.AddrFrom)
				bs := &structures.BlockShort{}
				err := bs.DeserializeBlock(blockdata)
				if err != nil {
					return err
				}
				s.Node.NodeClient.SendGetBlocks(payload.AddrFrom, bs.PrevBlockHash)
			}
			if s.S.Transit.GetBlocksCount(payload.AddrFrom) == 0 {
				break
			}
		}
	}
	if payload.Type == "tx" {
		txID := payload.Items[0]
		s.Logger.Trace.Printf("Check if TX exists %x\n", txID)
		tx, err := s.Node.GetTransactionsManager().GetIfExists(txID)
		if tx == nil && err == nil {
			s.Logger.Trace.Printf("Not exist. Request it\n")
			s.Node.NodeClient.SendGetData(payload.AddrFrom, "tx", txID)
		}
	}
	s.Node.CheckAddressKnown(payload.AddrFrom)
	return nil
}