diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 088e441e08..bd45af655c 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -39,7 +39,6 @@ import ( const ( eth60 = 60 // Constant to check for old protocol support eth61 = 61 // Constant to check for new protocol support - eth62 = 62 // Constant to check for experimental protocol support ) var ( @@ -332,7 +331,7 @@ func (d *Downloader) syncWithPeer(p *peer, hash common.Hash, td *big.Int) (err e if err = d.fetchBlocks60(); err != nil { return err } - case eth61, eth62: + case eth61: // New eth/61, use forward, concurrent hash and block retrieval algorithm number, err := d.findAncestor(p) if err != nil { diff --git a/eth/handler.go b/eth/handler.go index 102901c086..accc09f5ca 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -188,6 +188,9 @@ func (pm *ProtocolManager) handle(p *peer) error { glog.V(logger.Debug).Infof("%v: handshake failed: %v", p, err) return err } + if rw, ok := p.rw.(*meteredMsgReadWriter); ok { + rw.Init(p.version) + } // Register the peer locally glog.V(logger.Detail).Infof("%v: adding peer", p) if err := pm.peers.Register(p); err != nil { @@ -228,12 +231,12 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { defer msg.Discard() // Handle the message depending on its contents - switch msg.Code { - case StatusMsg: + switch { + case msg.Code == StatusMsg: // Status messages should never arrive after the handshake return errResp(ErrExtraStatusMsg, "uncontrolled status message") - case GetBlockHashesMsg: + case (p.version == eth60 || p.version == eth61) && msg.Code == GetBlockHashesMsg: // Retrieve the number of hashes to return and from which origin hash var request getBlockHashesData if err := msg.Decode(&request); err != nil { @@ -249,7 +252,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } return p.SendBlockHashes(hashes) - case GetBlockHashesFromNumberMsg: + case (p.version == eth60 || p.version == eth61) && msg.Code == GetBlockHashesFromNumberMsg: // Retrieve and decode the number of hashes to return and from which origin number var request getBlockHashesFromNumberData if err := msg.Decode(&request); err != nil { @@ -276,7 +279,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } return p.SendBlockHashes(hashes) - case BlockHashesMsg: + case (p.version == eth60 || p.version == eth61) && msg.Code == BlockHashesMsg: // A batch of hashes arrived to one of our previous requests var hashes []common.Hash if err := msg.Decode(&hashes); err != nil { @@ -288,7 +291,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { glog.V(logger.Debug).Infoln(err) } - case GetBlocksMsg: + case (p.version == eth60 || p.version == eth61) && msg.Code == GetBlocksMsg: // Decode the retrieval message msgStream := rlp.NewStream(msg.Payload, uint64(msg.Size)) if _, err := msgStream.List(); err != nil { @@ -316,7 +319,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } return p.SendBlocks(blocks) - case BlocksMsg: + case (p.version == eth60 || p.version == eth61) && msg.Code == BlocksMsg: // Decode the arrived block message var blocks []*types.Block if err := msg.Decode(&blocks); err != nil { @@ -332,7 +335,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { pm.downloader.DeliverBlocks(p.id, blocks) } - case GetBlockHeadersMsg: + case p.version == eth62 && msg.Code == GetBlockHeadersMsg: // Decode the retrieval message msgStream := rlp.NewStream(msg.Payload, uint64(msg.Size)) if _, err := msgStream.List(); err != nil { @@ -359,7 +362,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } return p.SendBlockHeaders(headers) - case GetNodeDataMsg: + case p.version == eth63 && msg.Code == GetNodeDataMsg: // Decode the retrieval message msgStream := rlp.NewStream(msg.Payload, uint64(msg.Size)) if _, err := msgStream.List(); err != nil { @@ -386,7 +389,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } return p.SendNodeData(data) - case NewBlockHashesMsg: + case msg.Code == NewBlockHashesMsg: // Retrieve and deseralize the remote new block hashes notification var hashes []common.Hash if err := msg.Decode(&hashes); err != nil { @@ -408,7 +411,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { pm.fetcher.Notify(p.id, hash, time.Now(), p.RequestBlocks) } - case NewBlockMsg: + case msg.Code == NewBlockMsg: // Retrieve and decode the propagated block var request newBlockData if err := msg.Decode(&request); err != nil { @@ -440,7 +443,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { go pm.synchronise(p) } - case TxMsg: + case msg.Code == TxMsg: // Transactions arrived, parse all of them and deliver to the pool var txs []*types.Transaction if err := msg.Decode(&txs); err != nil { diff --git a/eth/handler_test.go b/eth/handler_test.go index 7cc7db16f4..84c977b0e3 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -19,9 +19,12 @@ import ( // Tests that hashes can be retrieved from a remote chain by hashes in reverse // order. -func TestGetBlockHashes(t *testing.T) { +func TestGetBlockHashes60(t *testing.T) { testGetBlockHashes(t, 60) } +func TestGetBlockHashes61(t *testing.T) { testGetBlockHashes(t, 61) } + +func testGetBlockHashes(t *testing.T, protocol int) { pm := newTestProtocolManager(downloader.MaxHashFetch+15, nil, nil) - peer, _ := newTestPeer("peer", pm, true) + peer, _ := newTestPeer("peer", protocol, pm, true) defer peer.close() // Create a batch of tests for various scenarios @@ -60,9 +63,12 @@ func TestGetBlockHashes(t *testing.T) { // Tests that hashes can be retrieved from a remote chain by numbers in forward // order. -func TestGetBlockHashesFromNumber(t *testing.T) { +func TestGetBlockHashesFromNumber60(t *testing.T) { testGetBlockHashesFromNumber(t, 60) } +func TestGetBlockHashesFromNumber61(t *testing.T) { testGetBlockHashesFromNumber(t, 61) } + +func testGetBlockHashesFromNumber(t *testing.T, protocol int) { pm := newTestProtocolManager(downloader.MaxHashFetch+15, nil, nil) - peer, _ := newTestPeer("peer", pm, true) + peer, _ := newTestPeer("peer", protocol, pm, true) defer peer.close() // Create a batch of tests for various scenarios @@ -98,9 +104,12 @@ func TestGetBlockHashesFromNumber(t *testing.T) { } // Tests that blocks can be retrieved from a remote chain based on their hashes. -func TestGetBlocks(t *testing.T) { +func TestGetBlocks60(t *testing.T) { testGetBlocks(t, 60) } +func TestGetBlocks61(t *testing.T) { testGetBlocks(t, 61) } + +func testGetBlocks(t *testing.T, protocol int) { pm := newTestProtocolManager(downloader.MaxHashFetch+15, nil, nil) - peer, _ := newTestPeer("peer", pm, true) + peer, _ := newTestPeer("peer", protocol, pm, true) defer peer.close() // Create a batch of tests for various scenarios @@ -166,9 +175,9 @@ func TestGetBlocks(t *testing.T) { } // Tests that block headers can be retrieved from a remote chain based on their hashes. -func TestGetBlockHeaders(t *testing.T) { +func TestGetBlockHeaders62(t *testing.T) { pm := newTestProtocolManager(downloader.MaxHashFetch+15, nil, nil) - peer, _ := newTestPeer("peer", pm, true) + peer, _ := newTestPeer("peer", 62, pm, true) defer peer.close() // Create a batch of tests for various scenarios @@ -226,15 +235,15 @@ func TestGetBlockHeaders(t *testing.T) { } } // Send the hash request and verify the response - p2p.Send(peer.app, 0x09, hashes) - if err := p2p.ExpectMsg(peer.app, 0x0a, headers); err != nil { + p2p.Send(peer.app, 0x03, hashes) + if err := p2p.ExpectMsg(peer.app, 0x04, headers); err != nil { t.Errorf("test %d: headers mismatch: %v", i, err) } } } // Tests that the node state database can be retrieved based on hashes. -func TestGetNodeData(t *testing.T) { +func TestGetNodeData63(t *testing.T) { // Define three accounts to simulate transactions with acc1Key, _ := crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") acc2Key, _ := crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") @@ -271,7 +280,7 @@ func TestGetNodeData(t *testing.T) { } // Assemble the test environment pm := newTestProtocolManager(4, generator, nil) - peer, _ := newTestPeer("peer", pm, true) + peer, _ := newTestPeer("peer", 63, pm, true) defer peer.close() // Fetch for now the entire state db @@ -279,12 +288,12 @@ func TestGetNodeData(t *testing.T) { for _, key := range pm.statedb.(*ethdb.MemDatabase).Keys() { hashes = append(hashes, common.BytesToHash(key)) } - p2p.Send(peer.app, 0x0b, hashes) + p2p.Send(peer.app, 0x0d, hashes) msg, err := peer.app.ReadMsg() if err != nil { t.Fatalf("failed to read node data response: %v", err) } - if msg.Code != 0x0c { + if msg.Code != 0x0e { t.Fatalf("response packet code mismatch: have %x, want %x", msg.Code, 0x0c) } var data [][]byte diff --git a/eth/helper_test.go b/eth/helper_test.go index 533eaff6e4..3a799e6f69 100644 --- a/eth/helper_test.go +++ b/eth/helper_test.go @@ -93,7 +93,7 @@ type testPeer struct { } // newTestPeer creates a new peer registered at the given protocol manager. -func newTestPeer(name string, pm *ProtocolManager, shake bool) (*testPeer, <-chan error) { +func newTestPeer(name string, version int, pm *ProtocolManager, shake bool) (*testPeer, <-chan error) { // Create a message pipe to communicate through app, net := p2p.MsgPipe() @@ -101,7 +101,7 @@ func newTestPeer(name string, pm *ProtocolManager, shake bool) (*testPeer, <-cha var id discover.NodeID rand.Read(id[:]) - peer := pm.newPeer(int(ProtocolVersions[0]), NetworkId, p2p.NewPeer(id, name, nil), net) + peer := pm.newPeer(version, NetworkId, p2p.NewPeer(id, name, nil), net) // Start the peer on a new thread errc := make(chan error, 1) @@ -126,7 +126,7 @@ func newTestPeer(name string, pm *ProtocolManager, shake bool) (*testPeer, <-cha // remote side as we are simulating locally. func (p *testPeer) handshake(t *testing.T, td *big.Int, head common.Hash, genesis common.Hash) { msg := &statusData{ - ProtocolVersion: uint32(ProtocolVersions[0]), + ProtocolVersion: uint32(p.version), NetworkId: uint32(NetworkId), TD: td, CurrentBlock: head, diff --git a/eth/metrics.go b/eth/metrics.go index 13745dc43d..778747210d 100644 --- a/eth/metrics.go +++ b/eth/metrics.go @@ -22,44 +22,53 @@ import ( ) var ( - propTxnInPacketsMeter = metrics.NewMeter("eth/prop/txns/in/packets") - propTxnInTrafficMeter = metrics.NewMeter("eth/prop/txns/in/traffic") - propTxnOutPacketsMeter = metrics.NewMeter("eth/prop/txns/out/packets") - propTxnOutTrafficMeter = metrics.NewMeter("eth/prop/txns/out/traffic") - propHashInPacketsMeter = metrics.NewMeter("eth/prop/hashes/in/packets") - propHashInTrafficMeter = metrics.NewMeter("eth/prop/hashes/in/traffic") - propHashOutPacketsMeter = metrics.NewMeter("eth/prop/hashes/out/packets") - propHashOutTrafficMeter = metrics.NewMeter("eth/prop/hashes/out/traffic") - propBlockInPacketsMeter = metrics.NewMeter("eth/prop/blocks/in/packets") - propBlockInTrafficMeter = metrics.NewMeter("eth/prop/blocks/in/traffic") - propBlockOutPacketsMeter = metrics.NewMeter("eth/prop/blocks/out/packets") - propBlockOutTrafficMeter = metrics.NewMeter("eth/prop/blocks/out/traffic") - reqHashInPacketsMeter = metrics.NewMeter("eth/req/hashes/in/packets") - reqHashInTrafficMeter = metrics.NewMeter("eth/req/hashes/in/traffic") - reqHashOutPacketsMeter = metrics.NewMeter("eth/req/hashes/out/packets") - reqHashOutTrafficMeter = metrics.NewMeter("eth/req/hashes/out/traffic") - reqBlockInPacketsMeter = metrics.NewMeter("eth/req/blocks/in/packets") - reqBlockInTrafficMeter = metrics.NewMeter("eth/req/blocks/in/traffic") - reqBlockOutPacketsMeter = metrics.NewMeter("eth/req/blocks/out/packets") - reqBlockOutTrafficMeter = metrics.NewMeter("eth/req/blocks/out/traffic") - reqHeaderInPacketsMeter = metrics.NewMeter("eth/req/header/in/packets") - reqHeaderInTrafficMeter = metrics.NewMeter("eth/req/header/in/traffic") - reqHeaderOutPacketsMeter = metrics.NewMeter("eth/req/header/out/packets") - reqHeaderOutTrafficMeter = metrics.NewMeter("eth/req/header/out/traffic") - reqStateInPacketsMeter = metrics.NewMeter("eth/req/state/in/packets") - reqStateInTrafficMeter = metrics.NewMeter("eth/req/state/in/traffic") - reqStateOutPacketsMeter = metrics.NewMeter("eth/req/state/out/packets") - reqStateOutTrafficMeter = metrics.NewMeter("eth/req/state/out/traffic") - miscInPacketsMeter = metrics.NewMeter("eth/misc/in/packets") - miscInTrafficMeter = metrics.NewMeter("eth/misc/in/traffic") - miscOutPacketsMeter = metrics.NewMeter("eth/misc/out/packets") - miscOutTrafficMeter = metrics.NewMeter("eth/misc/out/traffic") + propTxnInPacketsMeter = metrics.NewMeter("eth/prop/txns/in/packets") + propTxnInTrafficMeter = metrics.NewMeter("eth/prop/txns/in/traffic") + propTxnOutPacketsMeter = metrics.NewMeter("eth/prop/txns/out/packets") + propTxnOutTrafficMeter = metrics.NewMeter("eth/prop/txns/out/traffic") + propHashInPacketsMeter = metrics.NewMeter("eth/prop/hashes/in/packets") + propHashInTrafficMeter = metrics.NewMeter("eth/prop/hashes/in/traffic") + propHashOutPacketsMeter = metrics.NewMeter("eth/prop/hashes/out/packets") + propHashOutTrafficMeter = metrics.NewMeter("eth/prop/hashes/out/traffic") + propBlockInPacketsMeter = metrics.NewMeter("eth/prop/blocks/in/packets") + propBlockInTrafficMeter = metrics.NewMeter("eth/prop/blocks/in/traffic") + propBlockOutPacketsMeter = metrics.NewMeter("eth/prop/blocks/out/packets") + propBlockOutTrafficMeter = metrics.NewMeter("eth/prop/blocks/out/traffic") + reqHashInPacketsMeter = metrics.NewMeter("eth/req/hashes/in/packets") + reqHashInTrafficMeter = metrics.NewMeter("eth/req/hashes/in/traffic") + reqHashOutPacketsMeter = metrics.NewMeter("eth/req/hashes/out/packets") + reqHashOutTrafficMeter = metrics.NewMeter("eth/req/hashes/out/traffic") + reqBlockInPacketsMeter = metrics.NewMeter("eth/req/blocks/in/packets") + reqBlockInTrafficMeter = metrics.NewMeter("eth/req/blocks/in/traffic") + reqBlockOutPacketsMeter = metrics.NewMeter("eth/req/blocks/out/packets") + reqBlockOutTrafficMeter = metrics.NewMeter("eth/req/blocks/out/traffic") + reqHeaderInPacketsMeter = metrics.NewMeter("eth/req/header/in/packets") + reqHeaderInTrafficMeter = metrics.NewMeter("eth/req/header/in/traffic") + reqHeaderOutPacketsMeter = metrics.NewMeter("eth/req/header/out/packets") + reqHeaderOutTrafficMeter = metrics.NewMeter("eth/req/header/out/traffic") + reqBodyInPacketsMeter = metrics.NewMeter("eth/req/body/in/packets") + reqBodyInTrafficMeter = metrics.NewMeter("eth/req/body/in/traffic") + reqBodyOutPacketsMeter = metrics.NewMeter("eth/req/body/out/packets") + reqBodyOutTrafficMeter = metrics.NewMeter("eth/req/body/out/traffic") + reqStateInPacketsMeter = metrics.NewMeter("eth/req/state/in/packets") + reqStateInTrafficMeter = metrics.NewMeter("eth/req/state/in/traffic") + reqStateOutPacketsMeter = metrics.NewMeter("eth/req/state/out/packets") + reqStateOutTrafficMeter = metrics.NewMeter("eth/req/state/out/traffic") + reqReceiptInPacketsMeter = metrics.NewMeter("eth/req/receipt/in/packets") + reqReceiptInTrafficMeter = metrics.NewMeter("eth/req/receipt/in/traffic") + reqReceiptOutPacketsMeter = metrics.NewMeter("eth/req/receipt/out/packets") + reqReceiptOutTrafficMeter = metrics.NewMeter("eth/req/receipt/out/traffic") + miscInPacketsMeter = metrics.NewMeter("eth/misc/in/packets") + miscInTrafficMeter = metrics.NewMeter("eth/misc/in/traffic") + miscOutPacketsMeter = metrics.NewMeter("eth/misc/out/packets") + miscOutTrafficMeter = metrics.NewMeter("eth/misc/out/traffic") ) // meteredMsgReadWriter is a wrapper around a p2p.MsgReadWriter, capable of // accumulating the above defined metrics based on the data stream contents. type meteredMsgReadWriter struct { - p2p.MsgReadWriter + p2p.MsgReadWriter // Wrapped message stream to meter + version int // Protocol version to select correct meters } // newMeteredMsgWriter wraps a p2p MsgReadWriter with metering support. If the @@ -68,7 +77,13 @@ func newMeteredMsgWriter(rw p2p.MsgReadWriter) p2p.MsgReadWriter { if !metrics.Enabled { return rw } - return &meteredMsgReadWriter{rw} + return &meteredMsgReadWriter{MsgReadWriter: rw} +} + +// Init sets the protocol version used by the stream to know which meters to +// increment in case of overlapping message ids between protocol versions. +func (rw *meteredMsgReadWriter) Init(version int) { + rw.version = version } func (rw *meteredMsgReadWriter) ReadMsg() (p2p.Msg, error) { @@ -79,20 +94,27 @@ func (rw *meteredMsgReadWriter) ReadMsg() (p2p.Msg, error) { } // Account for the data traffic packets, traffic := miscInPacketsMeter, miscInTrafficMeter - switch msg.Code { - case BlockHashesMsg: + switch { + case (rw.version == eth60 || rw.version == eth61) && msg.Code == BlockHashesMsg: packets, traffic = reqHashInPacketsMeter, reqHashInTrafficMeter - case BlocksMsg: + case (rw.version == eth60 || rw.version == eth61) && msg.Code == BlocksMsg: packets, traffic = reqBlockInPacketsMeter, reqBlockInTrafficMeter - case BlockHeadersMsg: - packets, traffic = reqHeaderInPacketsMeter, reqHeaderInTrafficMeter - case NodeDataMsg: + + case rw.version == eth62 && msg.Code == BlockHeadersMsg: + packets, traffic = reqBlockInPacketsMeter, reqBlockInTrafficMeter + case rw.version == eth62 && msg.Code == BlockBodiesMsg: + packets, traffic = reqBodyInPacketsMeter, reqBodyInTrafficMeter + + case rw.version == eth63 && msg.Code == NodeDataMsg: packets, traffic = reqStateInPacketsMeter, reqStateInTrafficMeter - case NewBlockHashesMsg: + case rw.version == eth63 && msg.Code == ReceiptsMsg: + packets, traffic = reqReceiptInPacketsMeter, reqReceiptInTrafficMeter + + case msg.Code == NewBlockHashesMsg: packets, traffic = propHashInPacketsMeter, propHashInTrafficMeter - case NewBlockMsg: + case msg.Code == NewBlockMsg: packets, traffic = propBlockInPacketsMeter, propBlockInTrafficMeter - case TxMsg: + case msg.Code == TxMsg: packets, traffic = propTxnInPacketsMeter, propTxnInTrafficMeter } packets.Mark(1) @@ -104,20 +126,27 @@ func (rw *meteredMsgReadWriter) ReadMsg() (p2p.Msg, error) { func (rw *meteredMsgReadWriter) WriteMsg(msg p2p.Msg) error { // Account for the data traffic packets, traffic := miscOutPacketsMeter, miscOutTrafficMeter - switch msg.Code { - case BlockHashesMsg: + switch { + case (rw.version == eth60 || rw.version == eth61) && msg.Code == BlockHashesMsg: packets, traffic = reqHashOutPacketsMeter, reqHashOutTrafficMeter - case BlocksMsg: + case (rw.version == eth60 || rw.version == eth61) && msg.Code == BlocksMsg: packets, traffic = reqBlockOutPacketsMeter, reqBlockOutTrafficMeter - case BlockHeadersMsg: + + case rw.version == eth62 && msg.Code == BlockHeadersMsg: packets, traffic = reqHeaderOutPacketsMeter, reqHeaderOutTrafficMeter - case NodeDataMsg: + case rw.version == eth62 && msg.Code == BlockBodiesMsg: + packets, traffic = reqBodyOutPacketsMeter, reqBodyOutTrafficMeter + + case rw.version == eth63 && msg.Code == NodeDataMsg: packets, traffic = reqStateOutPacketsMeter, reqStateOutTrafficMeter - case NewBlockHashesMsg: + case rw.version == eth63 && msg.Code == ReceiptsMsg: + packets, traffic = reqReceiptOutPacketsMeter, reqReceiptOutTrafficMeter + + case msg.Code == NewBlockHashesMsg: packets, traffic = propHashOutPacketsMeter, propHashOutTrafficMeter - case NewBlockMsg: + case msg.Code == NewBlockMsg: packets, traffic = propBlockOutPacketsMeter, propBlockOutTrafficMeter - case TxMsg: + case msg.Code == TxMsg: packets, traffic = propTxnOutPacketsMeter, propTxnOutTrafficMeter } packets.Mark(1) diff --git a/eth/protocol.go b/eth/protocol.go index fcc5f21e2e..fc8446589b 100644 --- a/eth/protocol.go +++ b/eth/protocol.go @@ -23,11 +23,19 @@ import ( "github.com/ethereum/go-ethereum/core/types" ) +// Constants to match up protocol versions and messages +const ( + eth60 = 60 + eth61 = 61 + eth62 = 62 + eth63 = 63 +) + // Supported versions of the eth protocol (first is primary). -var ProtocolVersions = []uint{62, 61, 60} +var ProtocolVersions = []uint{61, 60} // Number of implemented message corresponding to different protocol versions. -var ProtocolLengths = []uint64{13, 9, 8} +var ProtocolLengths = []uint64{9, 8} const ( NetworkId = 1 @@ -37,23 +45,29 @@ const ( // eth protocol message codes const ( // Protocol messages belonging to eth/60 - StatusMsg = iota - NewBlockHashesMsg - TxMsg - GetBlockHashesMsg - BlockHashesMsg - GetBlocksMsg - BlocksMsg - NewBlockMsg + StatusMsg = 0x00 + NewBlockHashesMsg = 0x01 + TxMsg = 0x02 + GetBlockHashesMsg = 0x03 + BlockHashesMsg = 0x04 + GetBlocksMsg = 0x05 + BlocksMsg = 0x06 + NewBlockMsg = 0x07 // Protocol messages belonging to eth/61 - GetBlockHashesFromNumberMsg + GetBlockHashesFromNumberMsg = 0x08 // Protocol messages belonging to eth/62 - GetBlockHeadersMsg - BlockHeadersMsg - GetNodeDataMsg - NodeDataMsg + GetBlockHeadersMsg = 0x03 + BlockHeadersMsg = 0x04 + GetBlockBodiesMsg = 0x05 + BlockBodiesMsg = 0x06 + + // Protocol messages belonging to eth/63 + GetNodeDataMsg = 0x0d + NodeDataMsg = 0x0e + GetReceiptsMsg = 0x0f + ReceiptsMsg = 0x10 ) type errCode int diff --git a/eth/protocol_test.go b/eth/protocol_test.go index 166488b79a..4b89bc1f75 100644 --- a/eth/protocol_test.go +++ b/eth/protocol_test.go @@ -36,7 +36,13 @@ func init() { var testAccount = crypto.NewKey(rand.Reader) -func TestStatusMsgErrors(t *testing.T) { +// Tests that handshake failures are detected and reported correctly. +func TestStatusMsgErrors60(t *testing.T) { testStatusMsgErrors(t, 60) } +func TestStatusMsgErrors61(t *testing.T) { testStatusMsgErrors(t, 61) } +func TestStatusMsgErrors62(t *testing.T) { testStatusMsgErrors(t, 62) } +func TestStatusMsgErrors63(t *testing.T) { testStatusMsgErrors(t, 63) } + +func testStatusMsgErrors(t *testing.T, protocol int) { pm := newTestProtocolManager(0, nil, nil) td, currentBlock, genesis := pm.chainman.Status() defer pm.Stop() @@ -52,20 +58,20 @@ func TestStatusMsgErrors(t *testing.T) { }, { code: StatusMsg, data: statusData{10, NetworkId, td, currentBlock, genesis}, - wantError: errResp(ErrProtocolVersionMismatch, "10 (!= %d)", ProtocolVersions[0]), + wantError: errResp(ErrProtocolVersionMismatch, "10 (!= %d)", protocol), }, { - code: StatusMsg, data: statusData{uint32(ProtocolVersions[0]), 999, td, currentBlock, genesis}, + code: StatusMsg, data: statusData{uint32(protocol), 999, td, currentBlock, genesis}, wantError: errResp(ErrNetworkIdMismatch, "999 (!= 1)"), }, { - code: StatusMsg, data: statusData{uint32(ProtocolVersions[0]), NetworkId, td, currentBlock, common.Hash{3}}, + code: StatusMsg, data: statusData{uint32(protocol), NetworkId, td, currentBlock, common.Hash{3}}, wantError: errResp(ErrGenesisBlockMismatch, "0300000000000000000000000000000000000000000000000000000000000000 (!= %x)", genesis), }, } for i, test := range tests { - p, errc := newTestPeer("peer", pm, false) + p, errc := newTestPeer("peer", protocol, pm, false) // The send call might hang until reset because // the protocol might not read the payload. go p2p.Send(p.app, test.code, test.data) @@ -85,10 +91,15 @@ func TestStatusMsgErrors(t *testing.T) { } // This test checks that received transactions are added to the local pool. -func TestRecvTransactions(t *testing.T) { +func TestRecvTransactions60(t *testing.T) { testRecvTransactions(t, 60) } +func TestRecvTransactions61(t *testing.T) { testRecvTransactions(t, 61) } +func TestRecvTransactions62(t *testing.T) { testRecvTransactions(t, 62) } +func TestRecvTransactions63(t *testing.T) { testRecvTransactions(t, 63) } + +func testRecvTransactions(t *testing.T, protocol int) { txAdded := make(chan []*types.Transaction) pm := newTestProtocolManager(0, nil, txAdded) - p, _ := newTestPeer("peer", pm, true) + p, _ := newTestPeer("peer", protocol, pm, true) defer pm.Stop() defer p.close() @@ -109,7 +120,12 @@ func TestRecvTransactions(t *testing.T) { } // This test checks that pending transactions are sent. -func TestSendTransactions(t *testing.T) { +func TestSendTransactions60(t *testing.T) { testSendTransactions(t, 60) } +func TestSendTransactions61(t *testing.T) { testSendTransactions(t, 61) } +func TestSendTransactions62(t *testing.T) { testSendTransactions(t, 62) } +func TestSendTransactions63(t *testing.T) { testSendTransactions(t, 63) } + +func testSendTransactions(t *testing.T, protocol int) { pm := newTestProtocolManager(0, nil, nil) defer pm.Stop() @@ -156,7 +172,7 @@ func TestSendTransactions(t *testing.T) { } } for i := 0; i < 3; i++ { - p, _ := newTestPeer(fmt.Sprintf("peer #%d", i), pm, true) + p, _ := newTestPeer(fmt.Sprintf("peer #%d", i), protocol, pm, true) wg.Add(1) go checktxs(p) }