cmd, eth: support switching client modes of operation
This commit is contained in:
		
							parent
							
								
									10ed107ba2
								
							
						
					
					
						commit
						92f9a3e5fa
					
				| @ -304,6 +304,7 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso | |||||||
| 		utils.DataDirFlag, | 		utils.DataDirFlag, | ||||||
| 		utils.BlockchainVersionFlag, | 		utils.BlockchainVersionFlag, | ||||||
| 		utils.OlympicFlag, | 		utils.OlympicFlag, | ||||||
|  | 		utils.EthModeFlag, | ||||||
| 		utils.EthVersionFlag, | 		utils.EthVersionFlag, | ||||||
| 		utils.CacheFlag, | 		utils.CacheFlag, | ||||||
| 		utils.JSpathFlag, | 		utils.JSpathFlag, | ||||||
|  | |||||||
| @ -28,6 +28,7 @@ import ( | |||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"runtime" | 	"runtime" | ||||||
| 	"strconv" | 	"strconv" | ||||||
|  | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"github.com/codegangsta/cli" | 	"github.com/codegangsta/cli" | ||||||
| 	"github.com/ethereum/ethash" | 	"github.com/ethereum/ethash" | ||||||
| @ -148,9 +149,14 @@ var ( | |||||||
| 		Name:  "olympic", | 		Name:  "olympic", | ||||||
| 		Usage: "Use olympic style protocol", | 		Usage: "Use olympic style protocol", | ||||||
| 	} | 	} | ||||||
|  | 	EthModeFlag = cli.StringFlag{ | ||||||
|  | 		Name:  "mode", | ||||||
|  | 		Value: "archive", | ||||||
|  | 		Usage: "Client mode of operation (archive, full, light)", | ||||||
|  | 	} | ||||||
| 	EthVersionFlag = cli.IntFlag{ | 	EthVersionFlag = cli.IntFlag{ | ||||||
| 		Name:  "eth", | 		Name:  "eth", | ||||||
| 		Value: 62, | 		Value: 63, | ||||||
| 		Usage: "Highest eth protocol to advertise (temporary, dev option)", | 		Usage: "Highest eth protocol to advertise (temporary, dev option)", | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -425,12 +431,25 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		glog.V(logger.Error).Infoln("WARNING: No etherbase set and no accounts found as default") | 		glog.V(logger.Error).Infoln("WARNING: No etherbase set and no accounts found as default") | ||||||
| 	} | 	} | ||||||
| 
 | 	// Resolve the mode of opeation from the string flag
 | ||||||
|  | 	var clientMode eth.Mode | ||||||
|  | 	switch strings.ToLower(ctx.GlobalString(EthModeFlag.Name)) { | ||||||
|  | 	case "archive": | ||||||
|  | 		clientMode = eth.ArchiveMode | ||||||
|  | 	case "full": | ||||||
|  | 		clientMode = eth.FullMode | ||||||
|  | 	case "light": | ||||||
|  | 		clientMode = eth.LightMode | ||||||
|  | 	default: | ||||||
|  | 		glog.Fatalf("Unknown node type requested: %s", ctx.GlobalString(EthModeFlag.Name)) | ||||||
|  | 	} | ||||||
|  | 	// Assemble the entire eth configuration and return
 | ||||||
| 	cfg := ð.Config{ | 	cfg := ð.Config{ | ||||||
| 		Name:                    common.MakeName(clientID, version), | 		Name:                    common.MakeName(clientID, version), | ||||||
| 		DataDir:                 MustDataDir(ctx), | 		DataDir:                 MustDataDir(ctx), | ||||||
| 		GenesisNonce:            ctx.GlobalInt(GenesisNonceFlag.Name), | 		GenesisNonce:            ctx.GlobalInt(GenesisNonceFlag.Name), | ||||||
| 		GenesisFile:             ctx.GlobalString(GenesisFileFlag.Name), | 		GenesisFile:             ctx.GlobalString(GenesisFileFlag.Name), | ||||||
|  | 		Mode:                    clientMode, | ||||||
| 		BlockChainVersion:       ctx.GlobalInt(BlockchainVersionFlag.Name), | 		BlockChainVersion:       ctx.GlobalInt(BlockchainVersionFlag.Name), | ||||||
| 		DatabaseCache:           ctx.GlobalInt(CacheFlag.Name), | 		DatabaseCache:           ctx.GlobalInt(CacheFlag.Name), | ||||||
| 		SkipBcVersionCheck:      false, | 		SkipBcVersionCheck:      false, | ||||||
| @ -499,7 +518,6 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config { | |||||||
| 
 | 
 | ||||||
| 		glog.V(logger.Info).Infoln("dev mode enabled") | 		glog.V(logger.Info).Infoln("dev mode enabled") | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	return cfg | 	return cfg | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -89,6 +89,7 @@ type Config struct { | |||||||
| 	GenesisFile  string | 	GenesisFile  string | ||||||
| 	GenesisBlock *types.Block // used by block tests
 | 	GenesisBlock *types.Block // used by block tests
 | ||||||
| 	Olympic      bool | 	Olympic      bool | ||||||
|  | 	Mode         Mode | ||||||
| 
 | 
 | ||||||
| 	BlockChainVersion  int | 	BlockChainVersion  int | ||||||
| 	SkipBcVersionCheck bool // e.g. blockchain export
 | 	SkipBcVersionCheck bool // e.g. blockchain export
 | ||||||
| @ -398,8 +399,9 @@ func New(config *Config) (*Ethereum, error) { | |||||||
| 
 | 
 | ||||||
| 	eth.blockProcessor = core.NewBlockProcessor(chainDb, eth.pow, eth.blockchain, eth.EventMux()) | 	eth.blockProcessor = core.NewBlockProcessor(chainDb, eth.pow, eth.blockchain, eth.EventMux()) | ||||||
| 	eth.blockchain.SetProcessor(eth.blockProcessor) | 	eth.blockchain.SetProcessor(eth.blockProcessor) | ||||||
| 	eth.protocolManager = NewProtocolManager(config.NetworkId, eth.eventMux, eth.txPool, eth.pow, eth.blockchain, chainDb) | 	if eth.protocolManager, err = NewProtocolManager(config.Mode, config.NetworkId, eth.eventMux, eth.txPool, eth.pow, eth.blockchain, chainDb); err != nil { | ||||||
| 
 | 		return nil, err | ||||||
|  | 	} | ||||||
| 	eth.miner = miner.New(eth, eth.EventMux(), eth.pow) | 	eth.miner = miner.New(eth, eth.EventMux(), eth.pow) | ||||||
| 	eth.miner.SetGasPrice(config.GasPrice) | 	eth.miner.SetGasPrice(config.GasPrice) | ||||||
| 	eth.miner.SetExtra(config.ExtraData) | 	eth.miner.SetExtra(config.ExtraData) | ||||||
|  | |||||||
| @ -17,6 +17,7 @@ | |||||||
| package eth | package eth | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"math" | 	"math" | ||||||
| 	"math/big" | 	"math/big" | ||||||
| @ -42,6 +43,10 @@ const ( | |||||||
| 	estHeaderRlpSize  = 500             // Approximate size of an RLP encoded block header
 | 	estHeaderRlpSize  = 500             // Approximate size of an RLP encoded block header
 | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | // errIncompatibleConfig is returned if the requested protocols and configs are
 | ||||||
|  | // not compatible (low protocol version restrictions and high requirements).
 | ||||||
|  | var errIncompatibleConfig = errors.New("incompatible configuration") | ||||||
|  | 
 | ||||||
| func errResp(code errCode, format string, v ...interface{}) error { | func errResp(code errCode, format string, v ...interface{}) error { | ||||||
| 	return fmt.Errorf("%v - %v", code, fmt.Sprintf(format, v...)) | 	return fmt.Errorf("%v - %v", code, fmt.Sprintf(format, v...)) | ||||||
| } | } | ||||||
| @ -49,17 +54,8 @@ func errResp(code errCode, format string, v ...interface{}) error { | |||||||
| type hashFetcherFn func(common.Hash) error | type hashFetcherFn func(common.Hash) error | ||||||
| type blockFetcherFn func([]common.Hash) error | type blockFetcherFn func([]common.Hash) error | ||||||
| 
 | 
 | ||||||
| // extProt is an interface which is passed around so we can expose GetHashes and GetBlock without exposing it to the rest of the protocol
 |  | ||||||
| // extProt is passed around to peers which require to GetHashes and GetBlocks
 |  | ||||||
| type extProt struct { |  | ||||||
| 	getHashes hashFetcherFn |  | ||||||
| 	getBlocks blockFetcherFn |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (ep extProt) GetHashes(hash common.Hash) error    { return ep.getHashes(hash) } |  | ||||||
| func (ep extProt) GetBlock(hashes []common.Hash) error { return ep.getBlocks(hashes) } |  | ||||||
| 
 |  | ||||||
| type ProtocolManager struct { | type ProtocolManager struct { | ||||||
|  | 	mode       Mode | ||||||
| 	txpool     txPool | 	txpool     txPool | ||||||
| 	blockchain *core.BlockChain | 	blockchain *core.BlockChain | ||||||
| 	chaindb    ethdb.Database | 	chaindb    ethdb.Database | ||||||
| @ -87,9 +83,10 @@ type ProtocolManager struct { | |||||||
| 
 | 
 | ||||||
| // NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
 | // NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
 | ||||||
| // with the ethereum network.
 | // with the ethereum network.
 | ||||||
| func NewProtocolManager(networkId int, mux *event.TypeMux, txpool txPool, pow pow.PoW, blockchain *core.BlockChain, chaindb ethdb.Database) *ProtocolManager { | func NewProtocolManager(mode Mode, networkId int, mux *event.TypeMux, txpool txPool, pow pow.PoW, blockchain *core.BlockChain, chaindb ethdb.Database) (*ProtocolManager, error) { | ||||||
| 	// Create the protocol manager with the base fields
 | 	// Create the protocol manager with the base fields
 | ||||||
| 	manager := &ProtocolManager{ | 	manager := &ProtocolManager{ | ||||||
|  | 		mode:       mode, | ||||||
| 		eventMux:   mux, | 		eventMux:   mux, | ||||||
| 		txpool:     txpool, | 		txpool:     txpool, | ||||||
| 		blockchain: blockchain, | 		blockchain: blockchain, | ||||||
| @ -100,11 +97,15 @@ func NewProtocolManager(networkId int, mux *event.TypeMux, txpool txPool, pow po | |||||||
| 		quitSync:   make(chan struct{}), | 		quitSync:   make(chan struct{}), | ||||||
| 	} | 	} | ||||||
| 	// Initiate a sub-protocol for every implemented version we can handle
 | 	// Initiate a sub-protocol for every implemented version we can handle
 | ||||||
| 	manager.SubProtocols = make([]p2p.Protocol, len(ProtocolVersions)) | 	manager.SubProtocols = make([]p2p.Protocol, 0, len(ProtocolVersions)) | ||||||
| 	for i := 0; i < len(manager.SubProtocols); i++ { | 	for i, version := range ProtocolVersions { | ||||||
| 		version := ProtocolVersions[i] | 		// Skip protocol version if incompatible with the mode of operation
 | ||||||
| 
 | 		if minimumProtocolVersion[mode] > version { | ||||||
| 		manager.SubProtocols[i] = p2p.Protocol{ | 			continue | ||||||
|  | 		} | ||||||
|  | 		// Compatible, initialize the sub-protocol
 | ||||||
|  | 		version := version // Closure for the run
 | ||||||
|  | 		manager.SubProtocols = append(manager.SubProtocols, p2p.Protocol{ | ||||||
| 			Name:    "eth", | 			Name:    "eth", | ||||||
| 			Version: version, | 			Version: version, | ||||||
| 			Length:  ProtocolLengths[i], | 			Length:  ProtocolLengths[i], | ||||||
| @ -113,7 +114,10 @@ func NewProtocolManager(networkId int, mux *event.TypeMux, txpool txPool, pow po | |||||||
| 				manager.newPeerCh <- peer | 				manager.newPeerCh <- peer | ||||||
| 				return manager.handle(peer) | 				return manager.handle(peer) | ||||||
| 			}, | 			}, | ||||||
| 		} | 		}) | ||||||
|  | 	} | ||||||
|  | 	if len(manager.SubProtocols) == 0 { | ||||||
|  | 		return nil, errIncompatibleConfig | ||||||
| 	} | 	} | ||||||
| 	// Construct the different synchronisation mechanisms
 | 	// Construct the different synchronisation mechanisms
 | ||||||
| 	manager.downloader = downloader.New(manager.eventMux, manager.blockchain.HasBlock, manager.blockchain.GetBlock, manager.blockchain.CurrentBlock, manager.blockchain.GetTd, manager.blockchain.InsertChain, manager.removePeer) | 	manager.downloader = downloader.New(manager.eventMux, manager.blockchain.HasBlock, manager.blockchain.GetBlock, manager.blockchain.CurrentBlock, manager.blockchain.GetTd, manager.blockchain.InsertChain, manager.removePeer) | ||||||
| @ -126,7 +130,7 @@ func NewProtocolManager(networkId int, mux *event.TypeMux, txpool txPool, pow po | |||||||
| 	} | 	} | ||||||
| 	manager.fetcher = fetcher.New(manager.blockchain.GetBlock, validator, manager.BroadcastBlock, heighter, manager.blockchain.InsertChain, manager.removePeer) | 	manager.fetcher = fetcher.New(manager.blockchain.GetBlock, validator, manager.BroadcastBlock, heighter, manager.blockchain.InsertChain, manager.removePeer) | ||||||
| 
 | 
 | ||||||
| 	return manager | 	return manager, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (pm *ProtocolManager) removePeer(id string) { | func (pm *ProtocolManager) removePeer(id string) { | ||||||
|  | |||||||
| @ -17,12 +17,42 @@ import ( | |||||||
| 	"github.com/ethereum/go-ethereum/params" | 	"github.com/ethereum/go-ethereum/params" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | // Tests that protocol versions and modes of operations are matched up properly.
 | ||||||
|  | func TestProtocolCompatibility(t *testing.T) { | ||||||
|  | 	// Define the compatibility chart
 | ||||||
|  | 	tests := []struct { | ||||||
|  | 		version    uint | ||||||
|  | 		mode       Mode | ||||||
|  | 		compatible bool | ||||||
|  | 	}{ | ||||||
|  | 		{61, ArchiveMode, true}, {62, ArchiveMode, true}, {63, ArchiveMode, true}, {64, ArchiveMode, true}, | ||||||
|  | 		{61, FullMode, false}, {62, FullMode, false}, {63, FullMode, true}, {64, FullMode, true}, | ||||||
|  | 		{61, LightMode, false}, {62, LightMode, false}, {63, LightMode, false}, {64, LightMode, true}, | ||||||
|  | 	} | ||||||
|  | 	// Make sure anything we screw up is restored
 | ||||||
|  | 	backup := ProtocolVersions | ||||||
|  | 	defer func() { ProtocolVersions = backup }() | ||||||
|  | 
 | ||||||
|  | 	// Try all available compatibility configs and check for errors
 | ||||||
|  | 	for i, tt := range tests { | ||||||
|  | 		ProtocolVersions = []uint{tt.version} | ||||||
|  | 
 | ||||||
|  | 		pm, err := newTestProtocolManager(tt.mode, 0, nil, nil) | ||||||
|  | 		if pm != nil { | ||||||
|  | 			defer pm.Stop() | ||||||
|  | 		} | ||||||
|  | 		if (err == nil && !tt.compatible) || (err != nil && tt.compatible) { | ||||||
|  | 			t.Errorf("test %d: compatibility mismatch: have error %v, want compatibility %v", i, err, tt.compatible) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Tests that hashes can be retrieved from a remote chain by hashes in reverse
 | // Tests that hashes can be retrieved from a remote chain by hashes in reverse
 | ||||||
| // order.
 | // order.
 | ||||||
| func TestGetBlockHashes61(t *testing.T) { testGetBlockHashes(t, 61) } | func TestGetBlockHashes61(t *testing.T) { testGetBlockHashes(t, 61) } | ||||||
| 
 | 
 | ||||||
| func testGetBlockHashes(t *testing.T, protocol int) { | func testGetBlockHashes(t *testing.T, protocol int) { | ||||||
| 	pm := newTestProtocolManager(downloader.MaxHashFetch+15, nil, nil) | 	pm := newTestProtocolManagerMust(t, ArchiveMode, downloader.MaxHashFetch+15, nil, nil) | ||||||
| 	peer, _ := newTestPeer("peer", protocol, pm, true) | 	peer, _ := newTestPeer("peer", protocol, pm, true) | ||||||
| 	defer peer.close() | 	defer peer.close() | ||||||
| 
 | 
 | ||||||
| @ -65,7 +95,7 @@ func testGetBlockHashes(t *testing.T, protocol int) { | |||||||
| func TestGetBlockHashesFromNumber61(t *testing.T) { testGetBlockHashesFromNumber(t, 61) } | func TestGetBlockHashesFromNumber61(t *testing.T) { testGetBlockHashesFromNumber(t, 61) } | ||||||
| 
 | 
 | ||||||
| func testGetBlockHashesFromNumber(t *testing.T, protocol int) { | func testGetBlockHashesFromNumber(t *testing.T, protocol int) { | ||||||
| 	pm := newTestProtocolManager(downloader.MaxHashFetch+15, nil, nil) | 	pm := newTestProtocolManagerMust(t, ArchiveMode, downloader.MaxHashFetch+15, nil, nil) | ||||||
| 	peer, _ := newTestPeer("peer", protocol, pm, true) | 	peer, _ := newTestPeer("peer", protocol, pm, true) | ||||||
| 	defer peer.close() | 	defer peer.close() | ||||||
| 
 | 
 | ||||||
| @ -105,7 +135,7 @@ func testGetBlockHashesFromNumber(t *testing.T, protocol int) { | |||||||
| func TestGetBlocks61(t *testing.T) { testGetBlocks(t, 61) } | func TestGetBlocks61(t *testing.T) { testGetBlocks(t, 61) } | ||||||
| 
 | 
 | ||||||
| func testGetBlocks(t *testing.T, protocol int) { | func testGetBlocks(t *testing.T, protocol int) { | ||||||
| 	pm := newTestProtocolManager(downloader.MaxHashFetch+15, nil, nil) | 	pm := newTestProtocolManagerMust(t, ArchiveMode, downloader.MaxHashFetch+15, nil, nil) | ||||||
| 	peer, _ := newTestPeer("peer", protocol, pm, true) | 	peer, _ := newTestPeer("peer", protocol, pm, true) | ||||||
| 	defer peer.close() | 	defer peer.close() | ||||||
| 
 | 
 | ||||||
| @ -177,7 +207,7 @@ func TestGetBlockHeaders63(t *testing.T) { testGetBlockHeaders(t, 63) } | |||||||
| func TestGetBlockHeaders64(t *testing.T) { testGetBlockHeaders(t, 64) } | func TestGetBlockHeaders64(t *testing.T) { testGetBlockHeaders(t, 64) } | ||||||
| 
 | 
 | ||||||
| func testGetBlockHeaders(t *testing.T, protocol int) { | func testGetBlockHeaders(t *testing.T, protocol int) { | ||||||
| 	pm := newTestProtocolManager(downloader.MaxHashFetch+15, nil, nil) | 	pm := newTestProtocolManagerMust(t, ArchiveMode, downloader.MaxHashFetch+15, nil, nil) | ||||||
| 	peer, _ := newTestPeer("peer", protocol, pm, true) | 	peer, _ := newTestPeer("peer", protocol, pm, true) | ||||||
| 	defer peer.close() | 	defer peer.close() | ||||||
| 
 | 
 | ||||||
| @ -303,7 +333,7 @@ func TestGetBlockBodies63(t *testing.T) { testGetBlockBodies(t, 63) } | |||||||
| func TestGetBlockBodies64(t *testing.T) { testGetBlockBodies(t, 64) } | func TestGetBlockBodies64(t *testing.T) { testGetBlockBodies(t, 64) } | ||||||
| 
 | 
 | ||||||
| func testGetBlockBodies(t *testing.T, protocol int) { | func testGetBlockBodies(t *testing.T, protocol int) { | ||||||
| 	pm := newTestProtocolManager(downloader.MaxBlockFetch+15, nil, nil) | 	pm := newTestProtocolManagerMust(t, ArchiveMode, downloader.MaxBlockFetch+15, nil, nil) | ||||||
| 	peer, _ := newTestPeer("peer", protocol, pm, true) | 	peer, _ := newTestPeer("peer", protocol, pm, true) | ||||||
| 	defer peer.close() | 	defer peer.close() | ||||||
| 
 | 
 | ||||||
| @ -410,7 +440,7 @@ func testGetNodeData(t *testing.T, protocol int) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	// Assemble the test environment
 | 	// Assemble the test environment
 | ||||||
| 	pm := newTestProtocolManager(4, generator, nil) | 	pm := newTestProtocolManagerMust(t, ArchiveMode, 4, generator, nil) | ||||||
| 	peer, _ := newTestPeer("peer", protocol, pm, true) | 	peer, _ := newTestPeer("peer", protocol, pm, true) | ||||||
| 	defer peer.close() | 	defer peer.close() | ||||||
| 
 | 
 | ||||||
| @ -500,7 +530,7 @@ func testGetReceipt(t *testing.T, protocol int) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	// Assemble the test environment
 | 	// Assemble the test environment
 | ||||||
| 	pm := newTestProtocolManager(4, generator, nil) | 	pm := newTestProtocolManagerMust(t, ArchiveMode, 4, generator, nil) | ||||||
| 	peer, _ := newTestPeer("peer", protocol, pm, true) | 	peer, _ := newTestPeer("peer", protocol, pm, true) | ||||||
| 	defer peer.close() | 	defer peer.close() | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -28,7 +28,7 @@ var ( | |||||||
| // newTestProtocolManager creates a new protocol manager for testing purposes,
 | // newTestProtocolManager creates a new protocol manager for testing purposes,
 | ||||||
| // with the given number of blocks already known, and potential notification
 | // with the given number of blocks already known, and potential notification
 | ||||||
| // channels for different events.
 | // channels for different events.
 | ||||||
| func newTestProtocolManager(blocks int, generator func(int, *core.BlockGen), newtx chan<- []*types.Transaction) *ProtocolManager { | func newTestProtocolManager(mode Mode, blocks int, generator func(int, *core.BlockGen), newtx chan<- []*types.Transaction) (*ProtocolManager, error) { | ||||||
| 	var ( | 	var ( | ||||||
| 		evmux         = new(event.TypeMux) | 		evmux         = new(event.TypeMux) | ||||||
| 		pow           = new(core.FakePow) | 		pow           = new(core.FakePow) | ||||||
| @ -42,8 +42,23 @@ func newTestProtocolManager(blocks int, generator func(int, *core.BlockGen), new | |||||||
| 	if _, err := blockchain.InsertChain(chain); err != nil { | 	if _, err := blockchain.InsertChain(chain); err != nil { | ||||||
| 		panic(err) | 		panic(err) | ||||||
| 	} | 	} | ||||||
| 	pm := NewProtocolManager(NetworkId, evmux, &testTxPool{added: newtx}, pow, blockchain, db) | 	pm, err := NewProtocolManager(mode, NetworkId, evmux, &testTxPool{added: newtx}, pow, blockchain, db) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
| 	pm.Start() | 	pm.Start() | ||||||
|  | 	return pm, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // newTestProtocolManagerMust creates a new protocol manager for testing purposes,
 | ||||||
|  | // with the given number of blocks already known, and potential notification
 | ||||||
|  | // channels for different events. In case of an error, the constructor force-
 | ||||||
|  | // fails the test.
 | ||||||
|  | func newTestProtocolManagerMust(t *testing.T, mode Mode, blocks int, generator func(int, *core.BlockGen), newtx chan<- []*types.Transaction) *ProtocolManager { | ||||||
|  | 	pm, err := newTestProtocolManager(mode, blocks, generator, newtx) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("Failed to create protocol manager: %v", err) | ||||||
|  | 	} | ||||||
| 	return pm | 	return pm | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -26,6 +26,15 @@ import ( | |||||||
| 	"github.com/ethereum/go-ethereum/rlp" | 	"github.com/ethereum/go-ethereum/rlp" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | // Mode represents the mode of operation of the eth client.
 | ||||||
|  | type Mode int | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	ArchiveMode Mode = iota // Maintain the entire blockchain history
 | ||||||
|  | 	FullMode                // Maintain only a recent view of the blockchain
 | ||||||
|  | 	LightMode               // Don't maintain any history, rather fetch on demand
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| // Constants to match up protocol versions and messages
 | // Constants to match up protocol versions and messages
 | ||||||
| const ( | const ( | ||||||
| 	eth61 = 61 | 	eth61 = 61 | ||||||
| @ -34,6 +43,14 @@ const ( | |||||||
| 	eth64 = 64 | 	eth64 = 64 | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | // minimumProtocolVersion is the minimum version of the protocol eth must run to
 | ||||||
|  | // support the desired mode of operation.
 | ||||||
|  | var minimumProtocolVersion = map[Mode]uint{ | ||||||
|  | 	ArchiveMode: eth61, | ||||||
|  | 	FullMode:    eth63, | ||||||
|  | 	LightMode:   eth64, | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Supported versions of the eth protocol (first is primary).
 | // Supported versions of the eth protocol (first is primary).
 | ||||||
| var ProtocolVersions = []uint{eth64, eth63, eth62, eth61} | var ProtocolVersions = []uint{eth64, eth63, eth62, eth61} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -44,7 +44,7 @@ func TestStatusMsgErrors63(t *testing.T) { testStatusMsgErrors(t, 63) } | |||||||
| func TestStatusMsgErrors64(t *testing.T) { testStatusMsgErrors(t, 64) } | func TestStatusMsgErrors64(t *testing.T) { testStatusMsgErrors(t, 64) } | ||||||
| 
 | 
 | ||||||
| func testStatusMsgErrors(t *testing.T, protocol int) { | func testStatusMsgErrors(t *testing.T, protocol int) { | ||||||
| 	pm := newTestProtocolManager(0, nil, nil) | 	pm := newTestProtocolManagerMust(t, ArchiveMode, 0, nil, nil) | ||||||
| 	td, currentBlock, genesis := pm.blockchain.Status() | 	td, currentBlock, genesis := pm.blockchain.Status() | ||||||
| 	defer pm.Stop() | 	defer pm.Stop() | ||||||
| 
 | 
 | ||||||
| @ -99,7 +99,7 @@ func TestRecvTransactions64(t *testing.T) { testRecvTransactions(t, 64) } | |||||||
| 
 | 
 | ||||||
| func testRecvTransactions(t *testing.T, protocol int) { | func testRecvTransactions(t *testing.T, protocol int) { | ||||||
| 	txAdded := make(chan []*types.Transaction) | 	txAdded := make(chan []*types.Transaction) | ||||||
| 	pm := newTestProtocolManager(0, nil, txAdded) | 	pm := newTestProtocolManagerMust(t, ArchiveMode, 0, nil, txAdded) | ||||||
| 	p, _ := newTestPeer("peer", protocol, pm, true) | 	p, _ := newTestPeer("peer", protocol, pm, true) | ||||||
| 	defer pm.Stop() | 	defer pm.Stop() | ||||||
| 	defer p.close() | 	defer p.close() | ||||||
| @ -127,7 +127,7 @@ func TestSendTransactions63(t *testing.T) { testSendTransactions(t, 63) } | |||||||
| func TestSendTransactions64(t *testing.T) { testSendTransactions(t, 64) } | func TestSendTransactions64(t *testing.T) { testSendTransactions(t, 64) } | ||||||
| 
 | 
 | ||||||
| func testSendTransactions(t *testing.T, protocol int) { | func testSendTransactions(t *testing.T, protocol int) { | ||||||
| 	pm := newTestProtocolManager(0, nil, nil) | 	pm := newTestProtocolManagerMust(t, ArchiveMode, 0, nil, nil) | ||||||
| 	defer pm.Stop() | 	defer pm.Stop() | ||||||
| 
 | 
 | ||||||
| 	// Fill the pool with big transactions.
 | 	// Fill the pool with big transactions.
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user