mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-24 05:36:46 +00:00
eth, eth/downloader: support overlapping messages between proto versions
This commit is contained in:
parent
4644814a85
commit
5c1cded016
7 changed files with 176 additions and 106 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
131
eth/metrics.go
131
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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue