From 3e400739a77c8d2555ea74ae1544b483b375a960 Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Tue, 28 Jan 2014 15:35:44 +0100
Subject: Implemented get chain msg

---
 peer.go | 44 +++++++++++++++++++++++++++++++++-----------
 1 file changed, 33 insertions(+), 11 deletions(-)

diff --git a/peer.go b/peer.go
index d2328c393..ab16575e7 100644
--- a/peer.go
+++ b/peer.go
@@ -178,9 +178,14 @@ out:
 			// Respond back with pong
 			p.QueueMessage(ethwire.NewMessage(ethwire.MsgPongTy, ""))
 		case ethwire.MsgPongTy:
+			// If we received a pong back from a peer we set the
+			// last pong so the peer handler knows this peer is still
+			// active.
 			p.lastPong = time.Now().Unix()
 		case ethwire.MsgBlockTy:
-			for i := 0; i < msg.Data.Length(); i++ {
+			// Get all blocks and process them (TODO reverse order?)
+			msg.Data = msg.Data.Get(0)
+			for i := msg.Data.Length() - 1; i >= 0; i-- {
 				block := ethchain.NewBlockFromRlpValue(msg.Data.Get(i))
 				err := p.ethereum.BlockManager.ProcessBlock(block)
 
@@ -189,10 +194,15 @@ out:
 				}
 			}
 		case ethwire.MsgTxTy:
+			// If the message was a transaction queue the transaction
+			// in the TxPool where it will undergo validation and
+			// processing when a new block is found
 			for i := 0; i < msg.Data.Length(); i++ {
 				p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromRlpValue(msg.Data.Get(i)))
 			}
 		case ethwire.MsgGetPeersTy:
+			// Flag this peer as a 'requested of new peers' this to
+			// prevent malicious peers being forced.
 			p.requestedPeerList = true
 			// Peer asked for list of connected peers
 			p.pushPeers()
@@ -214,22 +224,31 @@ out:
 				p.requestedPeerList = false
 			}
 		case ethwire.MsgGetChainTy:
-			blocksFound := 0
-			l := msg.Data.Length()
+			var parent *ethchain.Block
+			// FIXME
+			msg.Data = msg.Data.Get(0)
+			// Length minus one since the very last element in the array is a count
+			l := msg.Data.Length() - 1
+			// Amount of parents in the canonical chain
+			amountOfBlocks := msg.Data.Get(l).AsUint()
 			// Check each SHA block hash from the message and determine whether
 			// the SHA is in the database
 			for i := 0; i < l; i++ {
-				if p.ethereum.BlockManager.BlockChain().HasBlock(msg.Data.Get(i).AsString()) {
-					blocksFound++
-					// TODO send reply
+				if data := msg.Data.Get(i).AsBytes(); p.ethereum.BlockManager.BlockChain().HasBlock(data) {
+					parent = p.ethereum.BlockManager.BlockChain().GetBlock(data)
+					break
 				}
 			}
 
-			// If no blocks are found we send back a reply with msg not in chain
-			// and the last hash from get chain
-			if blocksFound == 0 {
-				lastHash := msg.Data.Get(l - 1)
-				p.QueueMessage(ethwire.NewMessage(ethwire.MsgNotInChainTy, lastHash))
+			// If a parent is found send back a reply
+			if parent != nil {
+				chain := p.ethereum.BlockManager.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks)
+				p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain))
+			} else {
+				// If no blocks are found we send back a reply with msg not in chain
+				// and the last hash from get chain
+				lastHash := msg.Data.Get(l)
+				p.QueueMessage(ethwire.NewMessage(ethwire.MsgNotInChainTy, lastHash.AsRaw()))
 			}
 		case ethwire.MsgNotInChainTy:
 			log.Println("Not in chain, not yet implemented")
@@ -320,6 +339,9 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) {
 
 			p.Stop()
 		}
+	} else {
+		msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash(), uint64(100)})
+		p.QueueMessage(msg)
 	}
 }
 
-- 
cgit v1.2.3