From 1b234102147901738bb79b2edf2d803225a36d57 Mon Sep 17 00:00:00 2001
From: David Hill <dhill@mindcry.org>
Date: Tue, 26 Apr 2016 14:24:03 -0400
Subject: [PATCH] btcd: sendheaders server support (#671)

This adds support for serving headers instead of inventory messages in
accordance with BIP0130.  btcd itself does not yet make use of the
feature when receiving data.
---
 blockmanager.go |  2 +-
 server.go       | 22 +++++++++++++++++++++-
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/blockmanager.go b/blockmanager.go
index b8c4a55b..26659d01 100644
--- a/blockmanager.go
+++ b/blockmanager.go
@@ -1190,7 +1190,7 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
 
 		// Generate the inventory vector and relay it.
 		iv := wire.NewInvVect(wire.InvTypeBlock, block.Sha())
-		b.server.RelayInventory(iv, nil)
+		b.server.RelayInventory(iv, block.MsgBlock().Header)
 
 	// A block has been connected to the main block chain.
 	case blockchain.NTBlockConnected:
diff --git a/server.go b/server.go
index f2c64ec9..008bb9a0 100644
--- a/server.go
+++ b/server.go
@@ -1302,6 +1302,26 @@ func (s *server) handleRelayInvMsg(state *peerState, msg relayMsg) {
 			return
 		}
 
+		// If the inventory is a block and the peer prefers headers,
+		// generate and send a headers message instead of an inventory
+		// message.
+		if msg.invVect.Type == wire.InvTypeBlock && sp.WantsHeaders() {
+			blockHeader, ok := msg.data.(wire.BlockHeader)
+			if !ok {
+				peerLog.Warnf("Underlying data for headers" +
+					" is not a block header")
+				return
+			}
+			msgHeaders := wire.NewMsgHeaders()
+			if err := msgHeaders.AddBlockHeader(&blockHeader); err != nil {
+				peerLog.Errorf("Failed to add block"+
+					" header: %v", err)
+				return
+			}
+			sp.QueueMessage(msgHeaders, nil)
+			return
+		}
+
 		if msg.invVect.Type == wire.InvTypeTx {
 			// Don't relay the transaction to the peer when it has
 			// transaction relaying disabled.
@@ -1533,7 +1553,7 @@ func newPeerConfig(sp *serverPeer) *peer.Config {
 		ChainParams:      sp.server.chainParams,
 		Services:         sp.server.services,
 		DisableRelayTx:   cfg.BlocksOnly,
-		ProtocolVersion:  70011,
+		ProtocolVersion:  wire.SendHeadersVersion,
 	}
 }