From 393d675690923207746ac800568faacae723f251 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= <peterke@gmail.com>
Date: Fri, 26 Jun 2015 16:54:27 +0300
Subject: cmd/geth, cmd/utils, eth: advertise both eth/60 and eth/61

---
 cmd/geth/main.go   |  3 +--
 cmd/utils/flags.go |  6 ------
 eth/backend.go     | 59 +++++++++++++++++++++++++++++++-----------------------
 eth/handler.go     | 30 ++++++++++++++++-----------
 eth/protocol.go    | 11 +++++++---
 5 files changed, 61 insertions(+), 48 deletions(-)

diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index c46343a60..a7b769270 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -261,7 +261,6 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
 		utils.ExecFlag,
 		utils.WhisperEnabledFlag,
 		utils.VMDebugFlag,
-		utils.ProtocolVersionFlag,
 		utils.NetworkIdFlag,
 		utils.RPCCORSDomainFlag,
 		utils.VerbosityFlag,
@@ -598,7 +597,7 @@ func version(c *cli.Context) {
 	if gitCommit != "" {
 		fmt.Println("Git Commit:", gitCommit)
 	}
-	fmt.Println("Protocol Version:", c.GlobalInt(utils.ProtocolVersionFlag.Name))
+	fmt.Println("Protocol Versions:", eth.ProtocolVersions)
 	fmt.Println("Network Id:", c.GlobalInt(utils.NetworkIdFlag.Name))
 	fmt.Println("Go Version:", runtime.Version())
 	fmt.Println("OS:", runtime.GOOS)
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 0d59980ec..6f319eb40 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -82,11 +82,6 @@ var (
 		Usage: "Data directory to be used",
 		Value: DirectoryString{common.DefaultDataDir()},
 	}
-	ProtocolVersionFlag = cli.IntFlag{
-		Name:  "protocolversion",
-		Usage: "ETH protocol version (integer)",
-		Value: eth.ProtocolVersion,
-	}
 	NetworkIdFlag = cli.IntFlag{
 		Name:  "networkid",
 		Usage: "Network Id (integer)",
@@ -359,7 +354,6 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
 	return &eth.Config{
 		Name:                    common.MakeName(clientID, version),
 		DataDir:                 ctx.GlobalString(DataDirFlag.Name),
-		ProtocolVersion:         ctx.GlobalInt(ProtocolVersionFlag.Name),
 		GenesisNonce:            ctx.GlobalInt(GenesisNonceFlag.Name),
 		BlockChainVersion:       ctx.GlobalInt(BlockchainVersionFlag.Name),
 		SkipBcVersionCheck:      false,
diff --git a/eth/backend.go b/eth/backend.go
index 4644b8a93..23d76dfd1 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -57,10 +57,9 @@ var (
 )
 
 type Config struct {
-	Name            string
-	ProtocolVersion int
-	NetworkId       int
-	GenesisNonce    int
+	Name         string
+	NetworkId    int
+	GenesisNonce int
 
 	BlockChainVersion  int
 	SkipBcVersionCheck bool // e.g. blockchain export
@@ -226,7 +225,6 @@ type Ethereum struct {
 	autodagquit   chan bool
 	etherbase     common.Address
 	clientVersion string
-	ethVersionId  int
 	netVersionId  int
 	shhVersionId  int
 }
@@ -291,14 +289,20 @@ func New(config *Config) (*Ethereum, error) {
 	nodeDb := filepath.Join(config.DataDir, "nodes")
 
 	// Perform database sanity checks
-	d, _ := blockDb.Get([]byte("ProtocolVersion"))
-	protov := int(common.NewValue(d).Uint())
-	if protov != config.ProtocolVersion && protov != 0 {
-		path := filepath.Join(config.DataDir, "blockchain")
-		return nil, fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, config.ProtocolVersion, path)
-	}
-	saveProtocolVersion(blockDb, config.ProtocolVersion)
-	glog.V(logger.Info).Infof("Protocol Version: %v, Network Id: %v", config.ProtocolVersion, config.NetworkId)
+	/*
+		// The databases were previously tied to protocol versions. Currently we
+		// are moving away from this decision as approaching Frontier. The below
+		// check was left in for now but should eventually be just dropped.
+
+		d, _ := blockDb.Get([]byte("ProtocolVersion"))
+		protov := int(common.NewValue(d).Uint())
+		if protov != config.ProtocolVersion && protov != 0 {
+			path := filepath.Join(config.DataDir, "blockchain")
+			return nil, fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, config.ProtocolVersion, path)
+		}
+		saveProtocolVersion(blockDb, config.ProtocolVersion)
+	*/
+	glog.V(logger.Info).Infof("Protocol Versions: %v, Network Id: %v", ProtocolVersions, config.NetworkId)
 
 	if !config.SkipBcVersionCheck {
 		b, _ := blockDb.Get([]byte("BlockchainVersion"))
@@ -321,7 +325,6 @@ func New(config *Config) (*Ethereum, error) {
 		DataDir:                 config.DataDir,
 		etherbase:               common.HexToAddress(config.Etherbase),
 		clientVersion:           config.Name, // TODO should separate from Name
-		ethVersionId:            config.ProtocolVersion,
 		netVersionId:            config.NetworkId,
 		NatSpec:                 config.NatSpec,
 		MinerThreads:            config.MinerThreads,
@@ -345,7 +348,7 @@ func New(config *Config) (*Ethereum, error) {
 
 	eth.blockProcessor = core.NewBlockProcessor(stateDb, extraDb, eth.pow, eth.chainManager, eth.EventMux())
 	eth.chainManager.SetProcessor(eth.blockProcessor)
-	eth.protocolManager = NewProtocolManager(config.ProtocolVersion, config.NetworkId, eth.eventMux, eth.txPool, eth.pow, eth.chainManager)
+	eth.protocolManager = NewProtocolManager(config.NetworkId, eth.eventMux, eth.txPool, eth.pow, eth.chainManager)
 
 	eth.miner = miner.New(eth, eth.EventMux(), eth.pow)
 	eth.miner.SetGasPrice(config.GasPrice)
@@ -358,7 +361,7 @@ func New(config *Config) (*Ethereum, error) {
 	if err != nil {
 		return nil, err
 	}
-	protocols := []p2p.Protocol{eth.protocolManager.SubProtocol}
+	protocols := append([]p2p.Protocol{}, eth.protocolManager.SubProtocols...)
 	if config.Shh {
 		protocols = append(protocols, eth.whisper.Protocol())
 	}
@@ -495,7 +498,7 @@ func (s *Ethereum) PeerCount() int                       { return s.net.PeerCoun
 func (s *Ethereum) Peers() []*p2p.Peer                   { return s.net.Peers() }
 func (s *Ethereum) MaxPeers() int                        { return s.net.MaxPeers }
 func (s *Ethereum) ClientVersion() string                { return s.clientVersion }
-func (s *Ethereum) EthVersion() int                      { return s.ethVersionId }
+func (s *Ethereum) EthVersion() int                      { return int(s.protocolManager.SubProtocols[0].Version) }
 func (s *Ethereum) NetVersion() int                      { return s.netVersionId }
 func (s *Ethereum) ShhVersion() int                      { return s.shhVersionId }
 func (s *Ethereum) Downloader() *downloader.Downloader   { return s.protocolManager.downloader }
@@ -504,7 +507,7 @@ func (s *Ethereum) Downloader() *downloader.Downloader   { return s.protocolMana
 func (s *Ethereum) Start() error {
 	jsonlogger.LogJson(&logger.LogStarting{
 		ClientString:    s.net.Name,
-		ProtocolVersion: ProtocolVersion,
+		ProtocolVersion: s.EthVersion(),
 	})
 	err := s.net.Start()
 	if err != nil {
@@ -560,7 +563,7 @@ done:
 func (s *Ethereum) StartForTest() {
 	jsonlogger.LogJson(&logger.LogStarting{
 		ClientString:    s.net.Name,
-		ProtocolVersion: ProtocolVersion,
+		ProtocolVersion: s.EthVersion(),
 	})
 }
 
@@ -667,14 +670,20 @@ func (self *Ethereum) StopAutoDAG() {
 	glog.V(logger.Info).Infof("Automatic pregeneration of ethash DAG OFF (ethash dir: %s)", ethash.DefaultDir)
 }
 
-func saveProtocolVersion(db common.Database, protov int) {
-	d, _ := db.Get([]byte("ProtocolVersion"))
-	protocolVersion := common.NewValue(d).Uint()
+/*
+	// The databases were previously tied to protocol versions. Currently we
+	// are moving away from this decision as approaching Frontier. The below
+	// code was left in for now but should eventually be just dropped.
+
+	func saveProtocolVersion(db common.Database, protov int) {
+		d, _ := db.Get([]byte("ProtocolVersion"))
+		protocolVersion := common.NewValue(d).Uint()
 
-	if protocolVersion == 0 {
-		db.Put([]byte("ProtocolVersion"), common.NewValue(protov).Bytes())
+		if protocolVersion == 0 {
+			db.Put([]byte("ProtocolVersion"), common.NewValue(protov).Bytes())
+		}
 	}
-}
+*/
 
 func saveBlockchainVersion(db common.Database, bcVersion int) {
 	d, _ := db.Get([]byte("BlockchainVersion"))
diff --git a/eth/handler.go b/eth/handler.go
index 278a2bec2..44d297461 100644
--- a/eth/handler.go
+++ b/eth/handler.go
@@ -49,7 +49,7 @@ type ProtocolManager struct {
 	fetcher        *fetcher.Fetcher
 	peers          *peerSet
 
-	SubProtocol p2p.Protocol
+	SubProtocols []p2p.Protocol
 
 	eventMux      *event.TypeMux
 	txSub         event.Subscription
@@ -68,8 +68,8 @@ type ProtocolManager struct {
 
 // NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
 // with the ethereum network.
-func NewProtocolManager(protocolVersion, networkId int, mux *event.TypeMux, txpool txPool, pow pow.PoW, chainman *core.ChainManager) *ProtocolManager {
-	// Create the protocol manager and initialize peer handlers
+func NewProtocolManager(networkId int, mux *event.TypeMux, txpool txPool, pow pow.PoW, chainman *core.ChainManager) *ProtocolManager {
+	// Create the protocol manager with the base fields
 	manager := &ProtocolManager{
 		eventMux:  mux,
 		txpool:    txpool,
@@ -79,15 +79,21 @@ func NewProtocolManager(protocolVersion, networkId int, mux *event.TypeMux, txpo
 		txsyncCh:  make(chan *txsync),
 		quitSync:  make(chan struct{}),
 	}
-	manager.SubProtocol = p2p.Protocol{
-		Name:    "eth",
-		Version: uint(protocolVersion),
-		Length:  ProtocolLength,
-		Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
-			peer := manager.newPeer(protocolVersion, networkId, p, rw)
-			manager.newPeerCh <- peer
-			return manager.handle(peer)
-		},
+	// Initiate a sub-protocol for every implemented version we can handle
+	manager.SubProtocols = make([]p2p.Protocol, len(ProtocolVersions))
+	for i := 0; i < len(manager.SubProtocols); i++ {
+		version := ProtocolVersions[i]
+
+		manager.SubProtocols[i] = p2p.Protocol{
+			Name:    "eth",
+			Version: version,
+			Length:  ProtocolLengths[i],
+			Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
+				peer := manager.newPeer(int(version), networkId, p, rw)
+				manager.newPeerCh <- peer
+				return manager.handle(peer)
+			},
+		}
 	}
 	// Construct the different synchronisation mechanisms
 	manager.downloader = downloader.New(manager.eventMux, manager.chainman.HasBlock, manager.chainman.GetBlock, manager.chainman.InsertChain, manager.removePeer)
diff --git a/eth/protocol.go b/eth/protocol.go
index 57805d9bd..56409721b 100644
--- a/eth/protocol.go
+++ b/eth/protocol.go
@@ -7,11 +7,15 @@ import (
 	"github.com/ethereum/go-ethereum/core/types"
 )
 
+// Supported versions of the eth protocol (first is primary).
+var ProtocolVersions = []uint{61, 60}
+
+// Number of implemented message corresponding to different protocol versions.
+var ProtocolLengths = []uint64{9, 8}
+
 const (
-	ProtocolVersion    = 60
 	NetworkId          = 0
-	ProtocolLength     = uint64(8)
-	ProtocolMaxMsgSize = 10 * 1024 * 1024
+	ProtocolMaxMsgSize = 10 * 1024 * 1024 // Maximum cap on the size of a protocol message
 )
 
 // eth protocol message codes
@@ -24,6 +28,7 @@ const (
 	GetBlocksMsg
 	BlocksMsg
 	NewBlockMsg
+	BlockHashesFromNumbers
 )
 
 type errCode int
-- 
cgit v1.2.3