diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index ca86fb26f80996bf6bdb9cd795ce9cd9b10d2bdf..3e3a3eb0352b9ab97207e936f1ad0af46a5dffc1 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -304,8 +304,7 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
 		utils.DataDirFlag,
 		utils.BlockchainVersionFlag,
 		utils.OlympicFlag,
-		utils.EthModeFlag,
-		utils.EthVersionFlag,
+		utils.FastSyncFlag,
 		utils.CacheFlag,
 		utils.JSpathFlag,
 		utils.ListenPortFlag,
@@ -361,7 +360,6 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
 		utils.SetupLogger(ctx)
 		utils.SetupNetwork(ctx)
 		utils.SetupVM(ctx)
-		utils.SetupEth(ctx)
 		if ctx.GlobalBool(utils.PProfEanbledFlag.Name) {
 			utils.StartPProf(ctx)
 		}
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 792fcb41d15ec1f1ae2abc411e919e5c276714c1..060d80b351ec945fd62361c27f2ad653334ba2d8 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -28,7 +28,6 @@ import (
 	"path/filepath"
 	"runtime"
 	"strconv"
-	"strings"
 
 	"github.com/codegangsta/cli"
 	"github.com/ethereum/ethash"
@@ -149,15 +148,9 @@ var (
 		Name:  "olympic",
 		Usage: "Use olympic style protocol",
 	}
-	EthModeFlag = cli.StringFlag{
-		Name:  "mode",
-		Value: "archive",
-		Usage: "Client mode of operation (archive, full, light)",
-	}
-	EthVersionFlag = cli.IntFlag{
-		Name:  "eth",
-		Value: 63,
-		Usage: "Highest eth protocol to advertise (temporary, dev option)",
+	FastSyncFlag = cli.BoolFlag{
+		Name:  "fast",
+		Usage: "Enables fast syncing through state downloads",
 	}
 
 	// miner settings
@@ -431,25 +424,13 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
 	if err != nil {
 		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 := &eth.Config{
 		Name:                    common.MakeName(clientID, version),
 		DataDir:                 MustDataDir(ctx),
 		GenesisNonce:            ctx.GlobalInt(GenesisNonceFlag.Name),
 		GenesisFile:             ctx.GlobalString(GenesisFileFlag.Name),
-		Mode:                    clientMode,
+		FastSync:                ctx.GlobalBool(FastSyncFlag.Name),
 		BlockChainVersion:       ctx.GlobalInt(BlockchainVersionFlag.Name),
 		DatabaseCache:           ctx.GlobalInt(CacheFlag.Name),
 		SkipBcVersionCheck:      false,
@@ -550,18 +531,6 @@ func SetupVM(ctx *cli.Context) {
 	vm.SetJITCacheSize(ctx.GlobalInt(VMJitCacheFlag.Name))
 }
 
-// SetupEth configures the eth packages global settings
-func SetupEth(ctx *cli.Context) {
-	version := ctx.GlobalInt(EthVersionFlag.Name)
-	for len(eth.ProtocolVersions) > 0 && eth.ProtocolVersions[0] > uint(version) {
-		eth.ProtocolVersions = eth.ProtocolVersions[1:]
-		eth.ProtocolLengths = eth.ProtocolLengths[1:]
-	}
-	if len(eth.ProtocolVersions) == 0 {
-		Fatalf("No valid eth protocols remaining")
-	}
-}
-
 // MakeChain creates a chain manager from set command line flags.
 func MakeChain(ctx *cli.Context) (chain *core.BlockChain, chainDb ethdb.Database) {
 	datadir := MustDataDir(ctx)
diff --git a/eth/backend.go b/eth/backend.go
index f4acc76cb81223c424f04f21c7c821c37b58ae9e..0a37917833b2f7dfcd805f7052eaf31c58244e13 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -88,8 +88,8 @@ type Config struct {
 	GenesisNonce int
 	GenesisFile  string
 	GenesisBlock *types.Block // used by block tests
+	FastSync     bool
 	Olympic      bool
-	Mode         Mode
 
 	BlockChainVersion  int
 	SkipBcVersionCheck bool // e.g. blockchain export
@@ -399,7 +399,7 @@ func New(config *Config) (*Ethereum, error) {
 
 	eth.blockProcessor = core.NewBlockProcessor(chainDb, eth.pow, eth.blockchain, eth.EventMux())
 	eth.blockchain.SetProcessor(eth.blockProcessor)
-	if eth.protocolManager, err = NewProtocolManager(config.Mode, config.NetworkId, eth.eventMux, eth.txPool, eth.pow, eth.blockchain, chainDb); err != nil {
+	if eth.protocolManager, err = NewProtocolManager(config.FastSync, 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)
diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go
index bb8d892cdd79acc42eac1edfce73f9e9fb260ca0..17fbb1c7fd6fb6ac270d5b4919638e51af1499ff 100644
--- a/eth/downloader/queue.go
+++ b/eth/downloader/queue.go
@@ -422,10 +422,12 @@ func (q *queue) ReserveNodeData(p *peer, count int) *fetchRequest {
 		q.stateSchedLock.Lock()
 		defer q.stateSchedLock.Unlock()
 
-		for _, hash := range q.stateScheduler.Missing(max) {
-			q.stateTaskPool[hash] = q.stateTaskIndex
-			q.stateTaskQueue.Push(hash, -float32(q.stateTaskIndex))
-			q.stateTaskIndex++
+		if q.stateScheduler != nil {
+			for _, hash := range q.stateScheduler.Missing(max) {
+				q.stateTaskPool[hash] = q.stateTaskIndex
+				q.stateTaskQueue.Push(hash, -float32(q.stateTaskIndex))
+				q.stateTaskIndex++
+			}
 		}
 	}
 	return q.reserveHashes(p, count, q.stateTaskQueue, generator, q.statePendPool, count)
diff --git a/eth/handler.go b/eth/handler.go
index 40a57884260896d6612504652cf4de12d4276168..7251780354291e3a9e945e5f52b877f8127b94c8 100644
--- a/eth/handler.go
+++ b/eth/handler.go
@@ -55,7 +55,7 @@ type hashFetcherFn func(common.Hash) error
 type blockFetcherFn func([]common.Hash) error
 
 type ProtocolManager struct {
-	mode       Mode
+	fastSync   bool
 	txpool     txPool
 	blockchain *core.BlockChain
 	chaindb    ethdb.Database
@@ -83,10 +83,10 @@ type ProtocolManager struct {
 
 // NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
 // with the ethereum network.
-func NewProtocolManager(mode Mode, networkId int, mux *event.TypeMux, txpool txPool, pow pow.PoW, blockchain *core.BlockChain, chaindb ethdb.Database) (*ProtocolManager, error) {
+func NewProtocolManager(fastSync bool, 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
 	manager := &ProtocolManager{
-		mode:       mode,
+		fastSync:   fastSync,
 		eventMux:   mux,
 		txpool:     txpool,
 		blockchain: blockchain,
@@ -100,7 +100,7 @@ func NewProtocolManager(mode Mode, networkId int, mux *event.TypeMux, txpool txP
 	manager.SubProtocols = make([]p2p.Protocol, 0, len(ProtocolVersions))
 	for i, version := range ProtocolVersions {
 		// Skip protocol version if incompatible with the mode of operation
-		if minimumProtocolVersion[mode] > version {
+		if fastSync && version < eth63 {
 			continue
 		}
 		// Compatible, initialize the sub-protocol
@@ -120,14 +120,9 @@ func NewProtocolManager(mode Mode, networkId int, mux *event.TypeMux, txpool txP
 		return nil, errIncompatibleConfig
 	}
 	// Construct the different synchronisation mechanisms
-	var syncMode downloader.SyncMode
-	switch mode {
-	case ArchiveMode:
-		syncMode = downloader.FullSync
-	case FullMode:
+	syncMode := downloader.FullSync
+	if fastSync {
 		syncMode = downloader.FastSync
-	case LightMode:
-		syncMode = downloader.LightSync
 	}
 	manager.downloader = downloader.New(syncMode, chaindb, manager.eventMux, blockchain.HasHeader, blockchain.HasBlock, blockchain.GetHeader,
 		blockchain.GetBlock, blockchain.CurrentHeader, blockchain.CurrentBlock, blockchain.CurrentFastBlock, blockchain.FastSyncCommitHead,
diff --git a/eth/handler_test.go b/eth/handler_test.go
index 5ddfc4a8f320189cb2f2c1e4a8474e5a2b6c4888..843b02fd479549f3018b59c04b523e6ec588bb3a 100644
--- a/eth/handler_test.go
+++ b/eth/handler_test.go
@@ -22,12 +22,11 @@ func TestProtocolCompatibility(t *testing.T) {
 	// Define the compatibility chart
 	tests := []struct {
 		version    uint
-		mode       Mode
+		fastSync   bool
 		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},
+		{61, false, true}, {62, false, true}, {63, false, true},
+		{61, true, false}, {62, true, false}, {63, true, true},
 	}
 	// Make sure anything we screw up is restored
 	backup := ProtocolVersions
@@ -37,7 +36,7 @@ func TestProtocolCompatibility(t *testing.T) {
 	for i, tt := range tests {
 		ProtocolVersions = []uint{tt.version}
 
-		pm, err := newTestProtocolManager(tt.mode, 0, nil, nil)
+		pm, err := newTestProtocolManager(tt.fastSync, 0, nil, nil)
 		if pm != nil {
 			defer pm.Stop()
 		}
@@ -52,7 +51,7 @@ func TestProtocolCompatibility(t *testing.T) {
 func TestGetBlockHashes61(t *testing.T) { testGetBlockHashes(t, 61) }
 
 func testGetBlockHashes(t *testing.T, protocol int) {
-	pm := newTestProtocolManagerMust(t, ArchiveMode, downloader.MaxHashFetch+15, nil, nil)
+	pm := newTestProtocolManagerMust(t, false, downloader.MaxHashFetch+15, nil, nil)
 	peer, _ := newTestPeer("peer", protocol, pm, true)
 	defer peer.close()
 
@@ -95,7 +94,7 @@ func testGetBlockHashes(t *testing.T, protocol int) {
 func TestGetBlockHashesFromNumber61(t *testing.T) { testGetBlockHashesFromNumber(t, 61) }
 
 func testGetBlockHashesFromNumber(t *testing.T, protocol int) {
-	pm := newTestProtocolManagerMust(t, ArchiveMode, downloader.MaxHashFetch+15, nil, nil)
+	pm := newTestProtocolManagerMust(t, false, downloader.MaxHashFetch+15, nil, nil)
 	peer, _ := newTestPeer("peer", protocol, pm, true)
 	defer peer.close()
 
@@ -135,7 +134,7 @@ func testGetBlockHashesFromNumber(t *testing.T, protocol int) {
 func TestGetBlocks61(t *testing.T) { testGetBlocks(t, 61) }
 
 func testGetBlocks(t *testing.T, protocol int) {
-	pm := newTestProtocolManagerMust(t, ArchiveMode, downloader.MaxHashFetch+15, nil, nil)
+	pm := newTestProtocolManagerMust(t, false, downloader.MaxHashFetch+15, nil, nil)
 	peer, _ := newTestPeer("peer", protocol, pm, true)
 	defer peer.close()
 
@@ -204,10 +203,9 @@ func testGetBlocks(t *testing.T, protocol int) {
 // Tests that block headers can be retrieved from a remote chain based on user queries.
 func TestGetBlockHeaders62(t *testing.T) { testGetBlockHeaders(t, 62) }
 func TestGetBlockHeaders63(t *testing.T) { testGetBlockHeaders(t, 63) }
-func TestGetBlockHeaders64(t *testing.T) { testGetBlockHeaders(t, 64) }
 
 func testGetBlockHeaders(t *testing.T, protocol int) {
-	pm := newTestProtocolManagerMust(t, ArchiveMode, downloader.MaxHashFetch+15, nil, nil)
+	pm := newTestProtocolManagerMust(t, false, downloader.MaxHashFetch+15, nil, nil)
 	peer, _ := newTestPeer("peer", protocol, pm, true)
 	defer peer.close()
 
@@ -330,10 +328,9 @@ func testGetBlockHeaders(t *testing.T, protocol int) {
 // Tests that block contents can be retrieved from a remote chain based on their hashes.
 func TestGetBlockBodies62(t *testing.T) { testGetBlockBodies(t, 62) }
 func TestGetBlockBodies63(t *testing.T) { testGetBlockBodies(t, 63) }
-func TestGetBlockBodies64(t *testing.T) { testGetBlockBodies(t, 64) }
 
 func testGetBlockBodies(t *testing.T, protocol int) {
-	pm := newTestProtocolManagerMust(t, ArchiveMode, downloader.MaxBlockFetch+15, nil, nil)
+	pm := newTestProtocolManagerMust(t, false, downloader.MaxBlockFetch+15, nil, nil)
 	peer, _ := newTestPeer("peer", protocol, pm, true)
 	defer peer.close()
 
@@ -402,7 +399,6 @@ func testGetBlockBodies(t *testing.T, protocol int) {
 
 // Tests that the node state database can be retrieved based on hashes.
 func TestGetNodeData63(t *testing.T) { testGetNodeData(t, 63) }
-func TestGetNodeData64(t *testing.T) { testGetNodeData(t, 64) }
 
 func testGetNodeData(t *testing.T, protocol int) {
 	// Define three accounts to simulate transactions with
@@ -440,7 +436,7 @@ func testGetNodeData(t *testing.T, protocol int) {
 		}
 	}
 	// Assemble the test environment
-	pm := newTestProtocolManagerMust(t, ArchiveMode, 4, generator, nil)
+	pm := newTestProtocolManagerMust(t, false, 4, generator, nil)
 	peer, _ := newTestPeer("peer", protocol, pm, true)
 	defer peer.close()
 
@@ -492,7 +488,6 @@ func testGetNodeData(t *testing.T, protocol int) {
 
 // Tests that the transaction receipts can be retrieved based on hashes.
 func TestGetReceipt63(t *testing.T) { testGetReceipt(t, 63) }
-func TestGetReceipt64(t *testing.T) { testGetReceipt(t, 64) }
 
 func testGetReceipt(t *testing.T, protocol int) {
 	// Define three accounts to simulate transactions with
@@ -530,7 +525,7 @@ func testGetReceipt(t *testing.T, protocol int) {
 		}
 	}
 	// Assemble the test environment
-	pm := newTestProtocolManagerMust(t, ArchiveMode, 4, generator, nil)
+	pm := newTestProtocolManagerMust(t, false, 4, generator, nil)
 	peer, _ := newTestPeer("peer", protocol, pm, true)
 	defer peer.close()
 
diff --git a/eth/helper_test.go b/eth/helper_test.go
index ede0e3f15640ec6a734faef46584f0b8319ea1df..16907be8bfd05b9555bdf1c4ef3da97471bc5e0d 100644
--- a/eth/helper_test.go
+++ b/eth/helper_test.go
@@ -28,7 +28,7 @@ var (
 // newTestProtocolManager creates a new protocol manager for testing purposes,
 // with the given number of blocks already known, and potential notification
 // channels for different events.
-func newTestProtocolManager(mode Mode, blocks int, generator func(int, *core.BlockGen), newtx chan<- []*types.Transaction) (*ProtocolManager, error) {
+func newTestProtocolManager(fastSync bool, blocks int, generator func(int, *core.BlockGen), newtx chan<- []*types.Transaction) (*ProtocolManager, error) {
 	var (
 		evmux         = new(event.TypeMux)
 		pow           = new(core.FakePow)
@@ -42,7 +42,7 @@ func newTestProtocolManager(mode Mode, blocks int, generator func(int, *core.Blo
 	if _, err := blockchain.InsertChain(chain); err != nil {
 		panic(err)
 	}
-	pm, err := NewProtocolManager(mode, NetworkId, evmux, &testTxPool{added: newtx}, pow, blockchain, db)
+	pm, err := NewProtocolManager(fastSync, NetworkId, evmux, &testTxPool{added: newtx}, pow, blockchain, db)
 	if err != nil {
 		return nil, err
 	}
@@ -54,8 +54,8 @@ func newTestProtocolManager(mode Mode, blocks int, generator func(int, *core.Blo
 // 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)
+func newTestProtocolManagerMust(t *testing.T, fastSync bool, blocks int, generator func(int, *core.BlockGen), newtx chan<- []*types.Transaction) *ProtocolManager {
+	pm, err := newTestProtocolManager(fastSync, blocks, generator, newtx)
 	if err != nil {
 		t.Fatalf("Failed to create protocol manager: %v", err)
 	}
diff --git a/eth/protocol.go b/eth/protocol.go
index f2b98a8b1e640de13cb62d77a052c5c332e42923..410347ed328e7d058b1fee4334b8e978a12b0a86 100644
--- a/eth/protocol.go
+++ b/eth/protocol.go
@@ -26,36 +26,18 @@ import (
 	"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
 const (
 	eth61 = 61
 	eth62 = 62
 	eth63 = 63
-	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).
-var ProtocolVersions = []uint{eth64, eth63, eth62, eth61}
+var ProtocolVersions = []uint{eth63, eth62, eth61}
 
 // Number of implemented message corresponding to different protocol versions.
-var ProtocolLengths = []uint64{19, 17, 8, 9}
+var ProtocolLengths = []uint64{17, 8, 9}
 
 const (
 	NetworkId          = 1
@@ -90,11 +72,6 @@ const (
 	NodeDataMsg    = 0x0e
 	GetReceiptsMsg = 0x0f
 	ReceiptsMsg    = 0x10
-
-	// Protocol messages belonging to eth/64
-	GetAcctProofMsg     = 0x11
-	GetStorageDataProof = 0x12
-	Proof               = 0x13
 )
 
 type errCode int
diff --git a/eth/protocol_test.go b/eth/protocol_test.go
index bac519ae3922bcd43a6f4c36143507d887cb0f25..372c7e20365763c36082ad01f25f7d89dbc8d923 100644
--- a/eth/protocol_test.go
+++ b/eth/protocol_test.go
@@ -41,10 +41,9 @@ var testAccount = crypto.NewKey(rand.Reader)
 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 TestStatusMsgErrors64(t *testing.T) { testStatusMsgErrors(t, 64) }
 
 func testStatusMsgErrors(t *testing.T, protocol int) {
-	pm := newTestProtocolManagerMust(t, ArchiveMode, 0, nil, nil)
+	pm := newTestProtocolManagerMust(t, false, 0, nil, nil)
 	td, currentBlock, genesis := pm.blockchain.Status()
 	defer pm.Stop()
 
@@ -95,11 +94,10 @@ func testStatusMsgErrors(t *testing.T, protocol int) {
 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 TestRecvTransactions64(t *testing.T) { testRecvTransactions(t, 64) }
 
 func testRecvTransactions(t *testing.T, protocol int) {
 	txAdded := make(chan []*types.Transaction)
-	pm := newTestProtocolManagerMust(t, ArchiveMode, 0, nil, txAdded)
+	pm := newTestProtocolManagerMust(t, false, 0, nil, txAdded)
 	p, _ := newTestPeer("peer", protocol, pm, true)
 	defer pm.Stop()
 	defer p.close()
@@ -124,10 +122,9 @@ func testRecvTransactions(t *testing.T, protocol int) {
 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 TestSendTransactions64(t *testing.T) { testSendTransactions(t, 64) }
 
 func testSendTransactions(t *testing.T, protocol int) {
-	pm := newTestProtocolManagerMust(t, ArchiveMode, 0, nil, nil)
+	pm := newTestProtocolManagerMust(t, false, 0, nil, nil)
 	defer pm.Stop()
 
 	// Fill the pool with big transactions.