From 7c6cdcbcc92e8ee03c2e8e6d637dba98bec75112 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Mon, 3 Aug 2020 13:30:51 +0300 Subject: [PATCH 1/7] core: fix bug with policy.MaxVerificationGas In 121c9664b we should take into account isValid flag of NativePolicy contract while retrieving MaxVerificationGas native policy value. Otherwise we won't be able to get MaxVerificationGas after the node was restarted, because this value is not truly stored along with the other native policy values. This commit fixes bug with headers verification after the node restarting with an existing storage: ``` 2020-08-03T12:52:56.158+0300 WARN failed processing headers {"error": "vm failed to execute the script with error: error encountered at instruction 0 (PUSHDATA1): gas limit is exceeded", "errorVerbose": "vm failed to execute the script with error: error encountered at instruction 0 (PUSHDATA1): gas limit is exceeded\ngithub.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).verifyHashAgainstScript\n\t/home/neospcc/Documents/GitProjects/nspcc-dev/neo-go/pkg/core/blockchain.go:1454\ngithub.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).verifyHeaderWitnesses\n\t/home/neospcc/Documents/GitProjects/nspcc-dev/neo-go/pkg/core/blockchain.go:1517\ngithub.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).verifyHeader\n\t/home/neospcc/Documents/GitProjects/nspcc-dev/neo-go/pkg/core/blockchain.go:1175\ngithub.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).addHeaders\n\t/home/neospcc/Documents/GitProjects/nspcc-dev/neo-go/pkg/core/blockchain.go:484\ngithub.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).AddHeaders\n\t/home/neospcc/Documents/GitProjects/nspcc-dev/neo-go/pkg/core/blockchain.go:453\ngithub.com/nspcc-dev/neo-go/pkg/network.(*Server).handleHeadersCmd\n\t/home/neospcc/Documents/GitProjects/nspcc-dev/neo-go/pkg/network/server.go:454\nruntime.goexit\n\t/usr/local/go/src/runtime/asm_amd64.s:1373"} ``` --- pkg/core/native/policy.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/core/native/policy.go b/pkg/core/native/policy.go index 9d7c31cad..2cd090bbe 100644 --- a/pkg/core/native/policy.go +++ b/pkg/core/native/policy.go @@ -203,6 +203,8 @@ func (p *Policy) OnPersistEnd(dao dao.DAO) { maxBlockSystemFee := p.getInt64WithKey(dao, maxBlockSystemFeeKey) p.maxBlockSystemFee = maxBlockSystemFee + p.maxVerificationGas = defaultMaxVerificationGas + p.isValid = true } @@ -256,7 +258,10 @@ func (p *Policy) GetFeePerByteInternal(dao dao.DAO) int64 { // GetMaxVerificationGas returns maximum gas allowed to be burned during verificaion. func (p *Policy) GetMaxVerificationGas(_ dao.DAO) int64 { - return p.maxVerificationGas + if p.isValid { + return p.maxVerificationGas + } + return defaultMaxVerificationGas } // getMaxBlockSystemFee is Policy contract method and returns the maximum overall From 737ba700e9d44aed1be4bb2474a0014901813772 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Fri, 31 Jul 2020 13:58:22 +0300 Subject: [PATCH 2/7] network: rename GetBlockData command GetBlockData -> GetBlockByIndex --- pkg/network/message.go | 28 +++++++++---------- pkg/network/message_string.go | 6 ++-- .../{getblockdata.go => getblockbyindex.go} | 14 +++++----- ...ckdata_test.go => getblockbyindex_test.go} | 12 ++++---- pkg/network/server.go | 10 +++---- 5 files changed, 35 insertions(+), 35 deletions(-) rename pkg/network/payload/{getblockdata.go => getblockbyindex.go} (60%) rename pkg/network/payload/{getblockdata_test.go => getblockbyindex_test.go} (54%) diff --git a/pkg/network/message.go b/pkg/network/message.go index 1fee8e24f..d336bd5ad 100644 --- a/pkg/network/message.go +++ b/pkg/network/message.go @@ -61,18 +61,18 @@ const ( CMDPong CommandType = 0x19 // synchronization - CMDGetHeaders CommandType = 0x20 - CMDHeaders CommandType = 0x21 - CMDGetBlocks CommandType = 0x24 - CMDMempool CommandType = 0x25 - CMDInv CommandType = 0x27 - CMDGetData CommandType = 0x28 - CMDGetBlockData CommandType = 0x29 - CMDNotFound CommandType = 0x2a - CMDTX = CommandType(payload.TXType) - CMDBlock = CommandType(payload.BlockType) - CMDConsensus = CommandType(payload.ConsensusType) - CMDReject CommandType = 0x2f + CMDGetHeaders CommandType = 0x20 + CMDHeaders CommandType = 0x21 + CMDGetBlocks CommandType = 0x24 + CMDMempool CommandType = 0x25 + CMDInv CommandType = 0x27 + CMDGetData CommandType = 0x28 + CMDGetBlockByIndex CommandType = 0x29 + CMDNotFound CommandType = 0x2a + CMDTX = CommandType(payload.TXType) + CMDBlock = CommandType(payload.BlockType) + CMDConsensus = CommandType(payload.ConsensusType) + CMDReject CommandType = 0x2f // SPV protocol CMDFilterLoad CommandType = 0x30 @@ -149,8 +149,8 @@ func (m *Message) decodePayload() error { fallthrough case CMDGetHeaders: p = &payload.GetBlocks{} - case CMDGetBlockData: - p = &payload.GetBlockData{} + case CMDGetBlockByIndex: + p = &payload.GetBlockByIndex{} case CMDHeaders: p = &payload.Headers{Network: m.Network} case CMDTX: diff --git a/pkg/network/message_string.go b/pkg/network/message_string.go index d505f9696..233c9084b 100644 --- a/pkg/network/message_string.go +++ b/pkg/network/message_string.go @@ -20,7 +20,7 @@ func _() { _ = x[CMDMempool-37] _ = x[CMDInv-39] _ = x[CMDGetData-40] - _ = x[CMDGetBlockData-41] + _ = x[CMDGetBlockByIndex-41] _ = x[CMDNotFound-42] _ = x[CMDTX-43] _ = x[CMDBlock-44] @@ -39,7 +39,7 @@ const ( _CommandType_name_2 = "CMDPingCMDPong" _CommandType_name_3 = "CMDGetHeadersCMDHeaders" _CommandType_name_4 = "CMDGetBlocksCMDMempool" - _CommandType_name_5 = "CMDInvCMDGetDataCMDGetBlockDataCMDNotFoundCMDTXCMDBlockCMDConsensus" + _CommandType_name_5 = "CMDInvCMDGetDataCMDGetBlockByIndexCMDNotFoundCMDTXCMDBlockCMDConsensus" _CommandType_name_6 = "CMDRejectCMDFilterLoadCMDFilterAddCMDFilterClear" _CommandType_name_7 = "CMDMerkleBlock" _CommandType_name_8 = "CMDAlert" @@ -51,7 +51,7 @@ var ( _CommandType_index_2 = [...]uint8{0, 7, 14} _CommandType_index_3 = [...]uint8{0, 13, 23} _CommandType_index_4 = [...]uint8{0, 12, 22} - _CommandType_index_5 = [...]uint8{0, 6, 16, 31, 42, 47, 55, 67} + _CommandType_index_5 = [...]uint8{0, 6, 16, 34, 45, 50, 58, 70} _CommandType_index_6 = [...]uint8{0, 9, 22, 34, 48} ) diff --git a/pkg/network/payload/getblockdata.go b/pkg/network/payload/getblockbyindex.go similarity index 60% rename from pkg/network/payload/getblockdata.go rename to pkg/network/payload/getblockbyindex.go index 2ed9c0d9f..bd7688abe 100644 --- a/pkg/network/payload/getblockdata.go +++ b/pkg/network/payload/getblockbyindex.go @@ -9,22 +9,22 @@ import ( // maximum number of blocks to query about const maxBlockCount = 500 -// GetBlockData payload -type GetBlockData struct { +// GetBlockByIndex payload +type GetBlockByIndex struct { IndexStart uint32 Count uint16 } -// NewGetBlockData returns GetBlockData payload with specified start index and count -func NewGetBlockData(indexStart uint32, count uint16) *GetBlockData { - return &GetBlockData{ +// NewGetBlockByIndex returns GetBlockByIndex payload with specified start index and count +func NewGetBlockByIndex(indexStart uint32, count uint16) *GetBlockByIndex { + return &GetBlockByIndex{ IndexStart: indexStart, Count: count, } } // DecodeBinary implements Serializable interface. -func (d *GetBlockData) DecodeBinary(br *io.BinReader) { +func (d *GetBlockByIndex) DecodeBinary(br *io.BinReader) { d.IndexStart = br.ReadU32LE() d.Count = br.ReadU16LE() if d.Count == 0 || d.Count > maxBlockCount { @@ -33,7 +33,7 @@ func (d *GetBlockData) DecodeBinary(br *io.BinReader) { } // EncodeBinary implements Serializable interface. -func (d *GetBlockData) EncodeBinary(bw *io.BinWriter) { +func (d *GetBlockByIndex) EncodeBinary(bw *io.BinWriter) { bw.WriteU32LE(d.IndexStart) bw.WriteU16LE(d.Count) } diff --git a/pkg/network/payload/getblockdata_test.go b/pkg/network/payload/getblockbyindex_test.go similarity index 54% rename from pkg/network/payload/getblockdata_test.go rename to pkg/network/payload/getblockbyindex_test.go index 6704af858..e02dfafa2 100644 --- a/pkg/network/payload/getblockdata_test.go +++ b/pkg/network/payload/getblockbyindex_test.go @@ -8,18 +8,18 @@ import ( ) func TestGetBlockDataEncodeDecode(t *testing.T) { - d := NewGetBlockData(123, 100) - testserdes.EncodeDecodeBinary(t, d, new(GetBlockData)) + d := NewGetBlockByIndex(123, 100) + testserdes.EncodeDecodeBinary(t, d, new(GetBlockByIndex)) // invalid block count - d = NewGetBlockData(5, 0) + d = NewGetBlockByIndex(5, 0) data, err := testserdes.EncodeBinary(d) require.NoError(t, err) - require.Error(t, testserdes.DecodeBinary(data, new(GetBlockData))) + require.Error(t, testserdes.DecodeBinary(data, new(GetBlockByIndex))) // invalid block count - d = NewGetBlockData(5, maxBlockCount+1) + d = NewGetBlockByIndex(5, maxBlockCount+1) data, err = testserdes.EncodeBinary(d) require.NoError(t, err) - require.Error(t, testserdes.DecodeBinary(data, new(GetBlockData))) + require.Error(t, testserdes.DecodeBinary(data, new(GetBlockByIndex))) } diff --git a/pkg/network/server.go b/pkg/network/server.go index 7ea3f2f3b..874642588 100644 --- a/pkg/network/server.go +++ b/pkg/network/server.go @@ -609,8 +609,8 @@ func (s *Server) handleGetBlocksCmd(p Peer, gb *payload.GetBlocks) error { return p.EnqueueP2PMessage(msg) } -// handleGetBlockDataCmd processes the getblockdata request. -func (s *Server) handleGetBlockDataCmd(p Peer, gbd *payload.GetBlockData) error { +// handleGetBlockByIndexCmd processes the getblockbyindex request. +func (s *Server) handleGetBlockByIndexCmd(p Peer, gbd *payload.GetBlockByIndex) error { for i := gbd.IndexStart; i < gbd.IndexStart+uint32(gbd.Count); i++ { b, err := s.chain.GetBlock(s.chain.GetHeaderHash(int(i))) if err != nil { @@ -750,9 +750,9 @@ func (s *Server) handleMessage(peer Peer, msg *Message) error { case CMDGetBlocks: gb := msg.Payload.(*payload.GetBlocks) return s.handleGetBlocksCmd(peer, gb) - case CMDGetBlockData: - gbd := msg.Payload.(*payload.GetBlockData) - return s.handleGetBlockDataCmd(peer, gbd) + case CMDGetBlockByIndex: + gbd := msg.Payload.(*payload.GetBlockByIndex) + return s.handleGetBlockByIndexCmd(peer, gbd) case CMDGetData: inv := msg.Payload.(*payload.Inventory) return s.handleGetDataCmd(peer, inv) From 0b856033b0f6c6e0e5ee9690b2e1bca41c2a1317 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Fri, 31 Jul 2020 14:03:35 +0300 Subject: [PATCH 3/7] network: use MaxHeadersAllowed to restrict GetBlockByIndex --- pkg/network/payload/getblockbyindex.go | 5 +---- pkg/network/payload/getblockbyindex_test.go | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/pkg/network/payload/getblockbyindex.go b/pkg/network/payload/getblockbyindex.go index bd7688abe..450dd4503 100644 --- a/pkg/network/payload/getblockbyindex.go +++ b/pkg/network/payload/getblockbyindex.go @@ -6,9 +6,6 @@ import ( "github.com/nspcc-dev/neo-go/pkg/io" ) -// maximum number of blocks to query about -const maxBlockCount = 500 - // GetBlockByIndex payload type GetBlockByIndex struct { IndexStart uint32 @@ -27,7 +24,7 @@ func NewGetBlockByIndex(indexStart uint32, count uint16) *GetBlockByIndex { func (d *GetBlockByIndex) DecodeBinary(br *io.BinReader) { d.IndexStart = br.ReadU32LE() d.Count = br.ReadU16LE() - if d.Count == 0 || d.Count > maxBlockCount { + if d.Count == 0 || d.Count > MaxHeadersAllowed { br.Err = errors.New("invalid block count") } } diff --git a/pkg/network/payload/getblockbyindex_test.go b/pkg/network/payload/getblockbyindex_test.go index e02dfafa2..1bd2f3452 100644 --- a/pkg/network/payload/getblockbyindex_test.go +++ b/pkg/network/payload/getblockbyindex_test.go @@ -18,7 +18,7 @@ func TestGetBlockDataEncodeDecode(t *testing.T) { require.Error(t, testserdes.DecodeBinary(data, new(GetBlockByIndex))) // invalid block count - d = NewGetBlockByIndex(5, maxBlockCount+1) + d = NewGetBlockByIndex(5, MaxHeadersAllowed+1) data, err = testserdes.EncodeBinary(d) require.NoError(t, err) require.Error(t, testserdes.DecodeBinary(data, new(GetBlockByIndex))) From 0b0591fc34a36d6fa227ec95be42535423f574d1 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Fri, 31 Jul 2020 14:17:14 +0300 Subject: [PATCH 4/7] network: allow to use -1 to specify GetBlockByIndex.Count --- pkg/network/payload/getblockbyindex.go | 10 +++++----- pkg/network/server.go | 6 +++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/pkg/network/payload/getblockbyindex.go b/pkg/network/payload/getblockbyindex.go index 450dd4503..a4e59db1d 100644 --- a/pkg/network/payload/getblockbyindex.go +++ b/pkg/network/payload/getblockbyindex.go @@ -9,11 +9,11 @@ import ( // GetBlockByIndex payload type GetBlockByIndex struct { IndexStart uint32 - Count uint16 + Count int16 } // NewGetBlockByIndex returns GetBlockByIndex payload with specified start index and count -func NewGetBlockByIndex(indexStart uint32, count uint16) *GetBlockByIndex { +func NewGetBlockByIndex(indexStart uint32, count int16) *GetBlockByIndex { return &GetBlockByIndex{ IndexStart: indexStart, Count: count, @@ -23,8 +23,8 @@ func NewGetBlockByIndex(indexStart uint32, count uint16) *GetBlockByIndex { // DecodeBinary implements Serializable interface. func (d *GetBlockByIndex) DecodeBinary(br *io.BinReader) { d.IndexStart = br.ReadU32LE() - d.Count = br.ReadU16LE() - if d.Count == 0 || d.Count > MaxHeadersAllowed { + d.Count = int16(br.ReadU16LE()) + if d.Count < -1 || d.Count == 0 || d.Count > MaxHeadersAllowed { br.Err = errors.New("invalid block count") } } @@ -32,5 +32,5 @@ func (d *GetBlockByIndex) DecodeBinary(br *io.BinReader) { // EncodeBinary implements Serializable interface. func (d *GetBlockByIndex) EncodeBinary(bw *io.BinWriter) { bw.WriteU32LE(d.IndexStart) - bw.WriteU16LE(d.Count) + bw.WriteU16LE(uint16(d.Count)) } diff --git a/pkg/network/server.go b/pkg/network/server.go index 874642588..6df448d27 100644 --- a/pkg/network/server.go +++ b/pkg/network/server.go @@ -611,7 +611,11 @@ func (s *Server) handleGetBlocksCmd(p Peer, gb *payload.GetBlocks) error { // handleGetBlockByIndexCmd processes the getblockbyindex request. func (s *Server) handleGetBlockByIndexCmd(p Peer, gbd *payload.GetBlockByIndex) error { - for i := gbd.IndexStart; i < gbd.IndexStart+uint32(gbd.Count); i++ { + count := gbd.Count + if gbd.Count < 0 || gbd.Count > payload.MaxHashesCount { + count = payload.MaxHashesCount + } + for i := gbd.IndexStart; i < gbd.IndexStart+uint32(count); i++ { b, err := s.chain.GetBlock(s.chain.GetHeaderHash(int(i))) if err != nil { return err From 7b1c3050002441f42fff7b74aca5512de88e7c18 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Fri, 31 Jul 2020 14:51:51 +0300 Subject: [PATCH 5/7] network: fix handleGetBlockByIndexCmd method It returned an error in case if block wasn't found (it might be when our chain is lower). Fixed. It also should return all requested blocks, not the first one. --- pkg/network/server.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pkg/network/server.go b/pkg/network/server.go index 6df448d27..e681f335d 100644 --- a/pkg/network/server.go +++ b/pkg/network/server.go @@ -616,12 +616,18 @@ func (s *Server) handleGetBlockByIndexCmd(p Peer, gbd *payload.GetBlockByIndex) count = payload.MaxHashesCount } for i := gbd.IndexStart; i < gbd.IndexStart+uint32(count); i++ { - b, err := s.chain.GetBlock(s.chain.GetHeaderHash(int(i))) + hash := s.chain.GetHeaderHash(int(i)) + if hash.Equals(util.Uint256{}) { + break + } + b, err := s.chain.GetBlock(hash) if err != nil { - return err + break } msg := NewMessage(CMDBlock, b) - return p.EnqueueP2PMessage(msg) + if err = p.EnqueueP2PMessage(msg); err != nil { + return err + } } return nil } From f6f3863e0ef2b74811d66d1652b0e9c90fe504dc Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Fri, 31 Jul 2020 14:47:42 +0300 Subject: [PATCH 6/7] network: allow to GetHeaders by index Use GetBlockByIndex payload for GetHeaders command instead of GetBlocks payload. --- pkg/network/message.go | 4 ++-- pkg/network/server.go | 23 +++++++++++------------ pkg/network/server_test.go | 2 +- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/pkg/network/message.go b/pkg/network/message.go index d336bd5ad..502ebbaed 100644 --- a/pkg/network/message.go +++ b/pkg/network/message.go @@ -146,9 +146,9 @@ func (m *Message) decodePayload() error { case CMDConsensus: p = consensus.NewPayload(m.Network) case CMDGetBlocks: - fallthrough - case CMDGetHeaders: p = &payload.GetBlocks{} + case CMDGetHeaders: + fallthrough case CMDGetBlockByIndex: p = &payload.GetBlockByIndex{} case CMDHeaders: diff --git a/pkg/network/server.go b/pkg/network/server.go index e681f335d..cba5b4976 100644 --- a/pkg/network/server.go +++ b/pkg/network/server.go @@ -633,18 +633,17 @@ func (s *Server) handleGetBlockByIndexCmd(p Peer, gbd *payload.GetBlockByIndex) } // handleGetHeadersCmd processes the getheaders request. -func (s *Server) handleGetHeadersCmd(p Peer, gh *payload.GetBlocks) error { - count := gh.Count - if gh.Count < 0 || gh.Count > payload.MaxHashesCount { - count = payload.MaxHashesCount +func (s *Server) handleGetHeadersCmd(p Peer, gh *payload.GetBlockByIndex) error { + if gh.IndexStart > s.chain.HeaderHeight() { + return nil } - start, err := s.chain.GetHeader(gh.HashStart) - if err != nil { - return err + count := gh.Count + if gh.Count < 0 || gh.Count > payload.MaxHeadersAllowed { + count = payload.MaxHeadersAllowed } resp := payload.Headers{} - resp.Hdrs = make([]*block.Header, 0, payload.MaxHeadersAllowed) - for i := start.Index + 1; i < start.Index+uint32(count); i++ { + resp.Hdrs = make([]*block.Header, 0, count) + for i := gh.IndexStart; i < gh.IndexStart+uint32(count); i++ { hash := s.chain.GetHeaderHash(int(i)) if hash.Equals(util.Uint256{}) { break @@ -709,9 +708,9 @@ func (s *Server) handleGetAddrCmd(p Peer) error { } // requestHeaders sends a getheaders message to the peer. -// The peer will respond with headers op to a count of 500. +// The peer will respond with headers op to a count of 2000. func (s *Server) requestHeaders(p Peer) error { - payload := payload.NewGetBlocks(s.chain.CurrentHeaderHash(), -1) + payload := payload.NewGetBlockByIndex(s.chain.HeaderHeight(), -1) return p.EnqueueP2PMessage(NewMessage(CMDGetHeaders, payload)) } @@ -767,7 +766,7 @@ func (s *Server) handleMessage(peer Peer, msg *Message) error { inv := msg.Payload.(*payload.Inventory) return s.handleGetDataCmd(peer, inv) case CMDGetHeaders: - gh := msg.Payload.(*payload.GetBlocks) + gh := msg.Payload.(*payload.GetBlockByIndex) return s.handleGetHeadersCmd(peer, gh) case CMDHeaders: headers := msg.Payload.(*payload.Headers) diff --git a/pkg/network/server_test.go b/pkg/network/server_test.go index 6c783f53f..dddd19a77 100644 --- a/pkg/network/server_test.go +++ b/pkg/network/server_test.go @@ -149,7 +149,7 @@ func TestRequestHeaders(t *testing.T) { p = newLocalPeer(t, s) ) p.messageHandler = func(t *testing.T, msg *Message) { - assert.IsType(t, &payload.GetBlocks{}, msg.Payload) + assert.IsType(t, &payload.GetBlockByIndex{}, msg.Payload) assert.Equal(t, CMDGetHeaders, msg.Command) } s.requestHeaders(p) From 6c8accf18c02ad676806cca686f8b93fd2d48eee Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Fri, 31 Jul 2020 17:12:13 +0300 Subject: [PATCH 7/7] core, network: request blocks instead of headers Closes #1192 1. We now have CMDGetBlockByIndex, so there's no need to request headers first when we can just ask for blocks. 2. We don't ask for headers (i.e. we don't send CMDGetHeaders), consequently, we shouldn't react on CMDHeaders. 3. But we still keep on reacting on CMDGetHeaders command as there could be a node which needs headers. --- pkg/network/server.go | 52 ++++---------------------------------- pkg/network/server_test.go | 12 --------- pkg/network/tcp_peer.go | 4 +-- 3 files changed, 7 insertions(+), 61 deletions(-) diff --git a/pkg/network/server.go b/pkg/network/server.go index cba5b4976..562908eaa 100644 --- a/pkg/network/server.go +++ b/pkg/network/server.go @@ -446,23 +446,6 @@ func (s *Server) handleVersionCmd(p Peer, version *payload.Version) error { return p.SendVersionAck(NewMessage(CMDVerack, nil)) } -// handleHeadersCmd processes the headers received from its peer. -// If the headerHeight of the blockchain still smaller then the peer -// the server will request more headers. -// This method could best be called in a separate routine. -func (s *Server) handleHeadersCmd(p Peer, headers *payload.Headers) { - if err := s.chain.AddHeaders(headers.Hdrs...); err != nil { - s.log.Warn("failed processing headers", zap.Error(err)) - return - } - // The peer will respond with a maximum of 2000 headers in one batch. - // We will ask one more batch here if needed. Eventually we will get synced - // due to the startProtocol routine that will ask headers every protoTick. - if s.chain.HeaderHeight() < p.LastBlockIndex() { - s.requestHeaders(p) - } -} - // handleBlockCmd processes the received block received from its peer. func (s *Server) handleBlockCmd(p Peer, block *block.Block) error { return s.bQueue.putBlock(block) @@ -479,8 +462,8 @@ func (s *Server) handlePong(p Peer, pong *payload.Ping) error { if err != nil { return err } - if s.chain.HeaderHeight() < pong.LastBlockIndex { - return s.requestHeaders(p) + if s.chain.BlockHeight() < pong.LastBlockIndex { + return s.requestBlocks(p) } return nil } @@ -707,34 +690,12 @@ func (s *Server) handleGetAddrCmd(p Peer) error { return p.EnqueueP2PMessage(NewMessage(CMDAddr, alist)) } -// requestHeaders sends a getheaders message to the peer. -// The peer will respond with headers op to a count of 2000. -func (s *Server) requestHeaders(p Peer) error { - payload := payload.NewGetBlockByIndex(s.chain.HeaderHeight(), -1) - return p.EnqueueP2PMessage(NewMessage(CMDGetHeaders, payload)) -} - -// requestBlocks sends a getdata message to the peer +// requestBlocks sends a CMDGetBlockByIndex message to the peer // to sync up in blocks. A maximum of maxBlockBatch will // send at once. func (s *Server) requestBlocks(p Peer) error { - var ( - hashes []util.Uint256 - hashStart = s.chain.BlockHeight() + 1 - headerHeight = s.chain.HeaderHeight() - ) - for hashStart <= headerHeight && len(hashes) < maxBlockBatch { - hash := s.chain.GetHeaderHash(int(hashStart)) - hashes = append(hashes, hash) - hashStart++ - } - if len(hashes) > 0 { - payload := payload.NewInventory(payload.BlockType, hashes) - return p.EnqueueP2PMessage(NewMessage(CMDGetData, payload)) - } else if s.chain.HeaderHeight() < p.LastBlockIndex() { - return s.requestHeaders(p) - } - return nil + payload := payload.NewGetBlockByIndex(s.chain.BlockHeight(), -1) + return p.EnqueueP2PMessage(NewMessage(CMDGetBlockByIndex, payload)) } // handleMessage processes the given message. @@ -768,9 +729,6 @@ func (s *Server) handleMessage(peer Peer, msg *Message) error { case CMDGetHeaders: gh := msg.Payload.(*payload.GetBlockByIndex) return s.handleGetHeadersCmd(peer, gh) - case CMDHeaders: - headers := msg.Payload.(*payload.Headers) - go s.handleHeadersCmd(peer, headers) case CMDInv: inventory := msg.Payload.(*payload.Inventory) return s.handleInvCmd(peer, inventory) diff --git a/pkg/network/server_test.go b/pkg/network/server_test.go index dddd19a77..30f18942d 100644 --- a/pkg/network/server_test.go +++ b/pkg/network/server_test.go @@ -142,15 +142,3 @@ func TestServerNotSendsVerack(t *testing.T) { assert.NotNil(t, err) require.Equal(t, errAlreadyConnected, err) } - -func TestRequestHeaders(t *testing.T) { - var ( - s = newTestServer(t, ServerConfig{}) - p = newLocalPeer(t, s) - ) - p.messageHandler = func(t *testing.T, msg *Message) { - assert.IsType(t, &payload.GetBlockByIndex{}, msg.Payload) - assert.Equal(t, CMDGetHeaders, msg.Command) - } - s.requestHeaders(p) -} diff --git a/pkg/network/tcp_peer.go b/pkg/network/tcp_peer.go index 29cd71d94..664089bdf 100644 --- a/pkg/network/tcp_peer.go +++ b/pkg/network/tcp_peer.go @@ -235,8 +235,8 @@ func (p *TCPPeer) StartProtocol() { zap.Uint32("id", p.Version().Nonce)) p.server.discovery.RegisterGoodAddr(p.PeerAddr().String(), p.version.Capabilities) - if p.server.chain.HeaderHeight() < p.LastBlockIndex() { - err = p.server.requestHeaders(p) + if p.server.chain.BlockHeight() < p.LastBlockIndex() { + err = p.server.requestBlocks(p) if err != nil { p.Disconnect(err) return