From aac2b6ae4c5cf6f78547159c47f9192babe3e6dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 29 Jun 2015 17:32:14 +0300 Subject: [PATCH] eth: add the blocks from numbers protocol message --- eth/handler.go | 4 ++-- eth/peer.go | 28 +++++++++++----------------- eth/protocol.go | 29 ++++++++++++++++++++++++++--- eth/protocol_test.go | 8 ++++---- 4 files changed, 43 insertions(+), 26 deletions(-) diff --git a/eth/handler.go b/eth/handler.go index d0456446d0..3705f5bb6d 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -240,7 +240,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { pm.txpool.AddTransactions(txs) case GetBlockHashesMsg: - var request getBlockHashesMsgData + var request getBlockHashesData if err := msg.Decode(&request); err != nil { return errResp(ErrDecode, "->msg %v: %v", msg, err) } @@ -368,7 +368,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { case NewBlockMsg: // Retrieve and decode the propagated block - var request newBlockMsgData + var request newBlockData if err := msg.Decode(&request); err != nil { return errResp(ErrDecode, "%v: %v", msg, err) } diff --git a/eth/peer.go b/eth/peer.go index 0120cd033e..a5d56249d2 100644 --- a/eth/peer.go +++ b/eth/peer.go @@ -25,19 +25,6 @@ const ( maxKnownBlocks = 1024 // Maximum block hashes to keep in the known list (prevent DOS) ) -type statusMsgData struct { - ProtocolVersion uint32 - NetworkId uint32 - TD *big.Int - CurrentBlock common.Hash - GenesisBlock common.Hash -} - -type getBlockHashesMsgData struct { - Hash common.Hash - Amount uint64 -} - type peer struct { *p2p.Peer @@ -181,8 +168,15 @@ func (p *peer) SendNewBlock(block *types.Block) error { // RequestHashes fetches a batch of hashes from a peer, starting at from, going // towards the genesis block. func (p *peer) RequestHashes(from common.Hash) error { - glog.V(logger.Debug).Infof("Peer [%s] fetching hashes (%d) %x...\n", p.id, downloader.MaxHashFetch, from[:4]) - return p2p.Send(p.rw, GetBlockHashesMsg, getBlockHashesMsgData{from, uint64(downloader.MaxHashFetch)}) + glog.V(logger.Debug).Infof("Peer [%s] fetching hashes (%d) from %x...\n", p.id, downloader.MaxHashFetch, from[:4]) + return p2p.Send(p.rw, GetBlockHashesMsg, getBlockHashesData{from, uint64(downloader.MaxHashFetch)}) +} + +// RequestHashesFromNumber fetches a batch of hashes from a peer, starting at the +// requested block number, going upwards towards the genesis block. +func (p *peer) RequestHashesFromNumber(from uint64) error { + glog.V(logger.Debug).Infof("Peer [%s] fetching hashes (%d) from #%d...\n", p.id, downloader.MaxHashFetch, from) + return p2p.Send(p.rw, GetBlockHashesFromNumberMsg, getBlockHashesFromNumberData{from, uint64(downloader.MaxHashFetch)}) } // RequestBlocks fetches a batch of blocks corresponding to the specified hashes. @@ -197,7 +191,7 @@ func (p *peer) Handshake(td *big.Int, head common.Hash, genesis common.Hash) err // Send out own handshake in a new thread errc := make(chan error, 1) go func() { - errc <- p2p.Send(p.rw, StatusMsg, &statusMsgData{ + errc <- p2p.Send(p.rw, StatusMsg, &statusData{ ProtocolVersion: uint32(p.version), NetworkId: uint32(p.network), TD: td, @@ -217,7 +211,7 @@ func (p *peer) Handshake(td *big.Int, head common.Hash, genesis common.Hash) err return errResp(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize) } // Decode the handshake and make sure everything matches - var status statusMsgData + var status statusData if err := msg.Decode(&status); err != nil { return errResp(ErrDecode, "msg %v: %v", msg, err) } diff --git a/eth/protocol.go b/eth/protocol.go index 56409721b3..bf9e155c55 100644 --- a/eth/protocol.go +++ b/eth/protocol.go @@ -28,7 +28,7 @@ const ( GetBlocksMsg BlocksMsg NewBlockMsg - BlockHashesFromNumbers + GetBlockHashesFromNumberMsg ) type errCode int @@ -77,8 +77,31 @@ type chainManager interface { Status() (td *big.Int, currentBlock common.Hash, genesisBlock common.Hash) } -// message structs used for RLP serialization -type newBlockMsgData struct { +// statusData is the network packet for the status message. +type statusData struct { + ProtocolVersion uint32 + NetworkId uint32 + TD *big.Int + CurrentBlock common.Hash + GenesisBlock common.Hash +} + +// getBlockHashesData is the network packet for the hash based block retrieval +// message. +type getBlockHashesData struct { + Hash common.Hash + Amount uint64 +} + +// getBlockHashesFromNumberData is the network packet for the number based block +// retrieval message. +type getBlockHashesFromNumberData struct { + Number uint64 + Amount uint64 +} + +// newBlockData is the network packet for the block propagation message. +type newBlockData struct { Block *types.Block TD *big.Int } diff --git a/eth/protocol_test.go b/eth/protocol_test.go index ffd4ca19fc..4c1579d4e5 100644 --- a/eth/protocol_test.go +++ b/eth/protocol_test.go @@ -39,15 +39,15 @@ func TestStatusMsgErrors(t *testing.T) { wantError: errResp(ErrNoStatusMsg, "first msg has code 2 (!= 0)"), }, { - code: StatusMsg, data: statusMsgData{10, NetworkId, td, currentBlock, genesis}, + code: StatusMsg, data: statusData{10, NetworkId, td, currentBlock, genesis}, wantError: errResp(ErrProtocolVersionMismatch, "10 (!= 0)"), }, { - code: StatusMsg, data: statusMsgData{uint32(ProtocolVersions[0]), 999, td, currentBlock, genesis}, + code: StatusMsg, data: statusData{uint32(ProtocolVersions[0]), 999, td, currentBlock, genesis}, wantError: errResp(ErrNetworkIdMismatch, "999 (!= 0)"), }, { - code: StatusMsg, data: statusMsgData{uint32(ProtocolVersions[0]), NetworkId, td, currentBlock, common.Hash{3}}, + code: StatusMsg, data: statusData{uint32(ProtocolVersions[0]), NetworkId, td, currentBlock, common.Hash{3}}, wantError: errResp(ErrGenesisBlockMismatch, "0300000000000000000000000000000000000000000000000000000000000000 (!= %x)", genesis), }, } @@ -188,7 +188,7 @@ func newTestPeer(pm *ProtocolManager) (*testPeer, <-chan error) { func (p *testPeer) handshake(t *testing.T) { td, currentBlock, genesis := p.pm.chainman.Status() - msg := &statusMsgData{ + msg := &statusData{ ProtocolVersion: uint32(p.pm.protVer), NetworkId: uint32(p.pm.netId), TD: td,