diff --git a/cmd/geth/dao_test.go b/cmd/geth/dao_test.go
index fd6831c15c92f05fc319c6ff499dc050d0dd4765..bfa0c2a035e5e86e7faaac6eae47f43449a589f7 100644
--- a/cmd/geth/dao_test.go
+++ b/cmd/geth/dao_test.go
@@ -29,7 +29,8 @@ import (
 	"github.com/ethereum/go-ethereum/params"
 )
 
-var daoNoForkGenesis = `{
+// Genesis block for nodes which don't care about the DAO fork (i.e. not configured)
+var daoOldGenesis = `{
 	"alloc"      : {},
 	"coinbase"   : "0x0000000000000000000000000000000000000000",
 	"difficulty" : "0x20000",
@@ -38,214 +39,140 @@ var daoNoForkGenesis = `{
 	"nonce"      : "0x0000000000000042",
 	"mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
 	"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
-	"timestamp"  : "0x00"
+	"timestamp"  : "0x00",
+	"config"     : {}
 }`
-var daoNoForkGenesisHash = common.HexToHash("5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0")
 
-var daoProForkGenesis = `{
+// Genesis block for nodes which actively oppose the DAO fork
+var daoNoForkGenesis = `{
 	"alloc"      : {},
 	"coinbase"   : "0x0000000000000000000000000000000000000000",
 	"difficulty" : "0x20000",
 	"extraData"  : "",
 	"gasLimit"   : "0x2fefd8",
-	"nonce"      : "0x0000000000000043",
+	"nonce"      : "0x0000000000000042",
 	"mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
 	"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
 	"timestamp"  : "0x00",
 	"config"     : {
-		"daoForkBlock": 314
+		"daoForkBlock"   : 314,
+		"daoForkSupport" : false
 	}
 }`
-var daoProForkGenesisHash = common.HexToHash("c80f3c1c3d81ae6d8ea59edf35d3e4b723e4c8684ec71fdb6d4715e3f8add237")
-var daoProForkBlock = big.NewInt(314)
-
-// Tests that creating a new node to with or without the DAO fork flag will correctly
-// set the genesis block but with DAO support explicitly set or unset in the chain
-// config in the database.
-func TestDAOSupportMainnet(t *testing.T) {
-	testDAOForkBlockNewChain(t, false, "", true, params.MainNetDAOForkBlock)
-}
-func TestDAOSupportTestnet(t *testing.T) {
-	testDAOForkBlockNewChain(t, true, "", true, params.TestNetDAOForkBlock)
-}
-func TestDAOSupportPrivnet(t *testing.T) {
-	testDAOForkBlockNewChain(t, false, daoProForkGenesis, false, daoProForkBlock)
-}
-func TestDAONoSupportMainnet(t *testing.T) {
-	testDAOForkBlockNewChain(t, false, "", false, nil)
-}
-func TestDAONoSupportTestnet(t *testing.T) {
-	testDAOForkBlockNewChain(t, true, "", false, nil)
-}
-func TestDAONoSupportPrivnet(t *testing.T) {
-	testDAOForkBlockNewChain(t, false, daoNoForkGenesis, false, nil)
-}
 
-func testDAOForkBlockNewChain(t *testing.T, testnet bool, genesis string, fork bool, expect *big.Int) {
-	// Create a temporary data directory to use and inspect later
-	datadir := tmpdir(t)
-	defer os.RemoveAll(datadir)
-
-	// Start a Geth instance with the requested flags set and immediately terminate
-	if genesis != "" {
-		json := filepath.Join(datadir, "genesis.json")
-		if err := ioutil.WriteFile(json, []byte(genesis), 0600); err != nil {
-			t.Fatalf("failed to write genesis file: %v", err)
-		}
-		runGeth(t, "--datadir", datadir, "init", json).cmd.Wait()
-	}
-	execDAOGeth(t, datadir, testnet, fork, false)
-
-	// Retrieve the DAO config flag from the database
-	path := filepath.Join(datadir, "chaindata")
-	if testnet {
-		path = filepath.Join(datadir, "testnet", "chaindata")
-	}
-	db, err := ethdb.NewLDBDatabase(path, 0, 0)
-	if err != nil {
-		t.Fatalf("failed to open test database: %v", err)
+// Genesis block for nodes which actively support the DAO fork
+var daoProForkGenesis = `{
+	"alloc"      : {},
+	"coinbase"   : "0x0000000000000000000000000000000000000000",
+	"difficulty" : "0x20000",
+	"extraData"  : "",
+	"gasLimit"   : "0x2fefd8",
+	"nonce"      : "0x0000000000000042",
+	"mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
+	"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
+	"timestamp"  : "0x00",
+	"config"     : {
+		"daoForkBlock"   : 314,
+		"daoForkSupport" : true
 	}
-	defer db.Close()
+}`
 
-	genesisHash := common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
-	if testnet {
-		genesisHash = common.HexToHash("0x0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303")
-	} else if genesis == daoNoForkGenesis {
-		genesisHash = daoNoForkGenesisHash
-	} else if genesis == daoProForkGenesis {
-		genesisHash = daoProForkGenesisHash
-	}
-	config, err := core.GetChainConfig(db, genesisHash)
-	if err != nil {
-		t.Fatalf("failed to retrieve chain config: %v", err)
-	}
-	// Validate the DAO hard-fork block number against the expected value
-	if config.DAOForkBlock == nil {
-		if expect != nil {
-			t.Fatalf("dao hard-fork block mismatch: have nil, want %v", expect)
-		}
-	} else if config.DAOForkBlock.Cmp(expect) != 0 {
-		t.Fatalf("dao hard-fork block mismatch: have %v, want %v", config.DAOForkBlock, expect)
-	}
-}
+var daoGenesisHash = common.HexToHash("5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0")
+var daoGenesisForkBlock = big.NewInt(314)
 
-// Tests that starting up an already existing node with various DAO fork override
-// flags correctly changes the chain configs in the database.
+// Tests that the DAO hard-fork number and the nodes support/opposition is correctly
+// set in the database after various initialization procedures and invocations.
 func TestDAODefaultMainnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, "", false, false, false, false, nil)
-}
-func TestDAOStartSupportMainnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, "", false, true, false, false, params.MainNetDAOForkBlock)
-}
-func TestDAOContinueExplicitSupportMainnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, "", true, true, false, false, params.MainNetDAOForkBlock)
-}
-func TestDAOContinueImplicitSupportMainnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, "", true, false, false, false, params.MainNetDAOForkBlock)
+	testDAOForkBlockNewChain(t, false, "", [][2]bool{{false, false}}, params.MainNetDAOForkBlock, false)
 }
-func TestDAOSwitchSupportMainnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, "", false, true, true, false, params.MainNetDAOForkBlock)
-}
-func TestDAOStartOpposeMainnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, "", false, false, false, true, nil)
+func TestDAOSupportMainnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, "", [][2]bool{{true, false}}, params.MainNetDAOForkBlock, true)
 }
-func TestDAOContinueExplicitOpposeMainnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, "", false, false, true, true, nil)
+func TestDAOOpposeMainnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, "", [][2]bool{{false, true}}, params.MainNetDAOForkBlock, false)
 }
-func TestDAOContinueImplicitOpposeMainnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, "", false, false, true, false, nil)
+func TestDAOSwitchToSupportMainnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, "", [][2]bool{{false, true}, {true, false}}, params.MainNetDAOForkBlock, true)
 }
-func TestDAOSwitchOpposeMainnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, "", true, false, false, true, nil)
+func TestDAOSwitchToOpposeMainnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, "", [][2]bool{{true, false}, {false, true}}, params.MainNetDAOForkBlock, false)
 }
 func TestDAODefaultTestnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, true, "", false, false, false, false, nil)
-}
-func TestDAOStartSupportTestnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, true, "", false, true, false, false, params.TestNetDAOForkBlock)
-}
-func TestDAOContinueExplicitSupportTestnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, true, "", true, true, false, false, params.TestNetDAOForkBlock)
-}
-func TestDAOContinueImplicitSupportTestnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, true, "", true, false, false, false, params.TestNetDAOForkBlock)
-}
-func TestDAOSwitchSupportTestnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, true, "", false, true, true, false, params.TestNetDAOForkBlock)
+	testDAOForkBlockNewChain(t, true, "", [][2]bool{{false, false}}, params.TestNetDAOForkBlock, false)
 }
-func TestDAOStartOpposeTestnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, true, "", false, false, false, true, nil)
+func TestDAOSupportTestnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, true, "", [][2]bool{{true, false}}, params.TestNetDAOForkBlock, true)
 }
-func TestDAOContinueExplicitOpposeTestnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, true, "", false, false, true, true, nil)
+func TestDAOOpposeTestnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, true, "", [][2]bool{{false, true}}, params.TestNetDAOForkBlock, false)
 }
-func TestDAOContinueImplicitOpposeTestnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, true, "", false, false, true, false, nil)
+func TestDAOSwitchToSupportTestnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, true, "", [][2]bool{{false, true}, {true, false}}, params.TestNetDAOForkBlock, true)
 }
-func TestDAOSwitchOpposeTestnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, true, "", true, false, false, true, nil)
+func TestDAOSwitchToOpposeTestnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, true, "", [][2]bool{{true, false}, {false, true}}, params.TestNetDAOForkBlock, false)
 }
-func TestDAODefaultPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoNoForkGenesis, false, false, false, false, nil)
+func TestDAOInitOldPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{}, nil, false)
 }
-func TestDAOStartSupportConPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoNoForkGenesis, false, true, false, false, params.MainNetDAOForkBlock)
+func TestDAODefaultOldPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{false, false}}, params.MainNetDAOForkBlock, false)
 }
-func TestDAOContinueExplicitSupportConPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoNoForkGenesis, true, true, false, false, params.MainNetDAOForkBlock)
+func TestDAOSupportOldPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{true, false}}, params.MainNetDAOForkBlock, true)
 }
-func TestDAOContinueImplicitSupportConPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoNoForkGenesis, true, false, false, false, params.MainNetDAOForkBlock)
+func TestDAOOpposeOldPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{false, true}}, params.MainNetDAOForkBlock, false)
 }
-func TestDAOSwitchSupportConPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoNoForkGenesis, false, true, true, false, params.MainNetDAOForkBlock)
+func TestDAOSwitchToSupportOldPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{false, true}, {true, false}}, params.MainNetDAOForkBlock, true)
 }
-func TestDAOStartOpposeConPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoNoForkGenesis, false, false, false, true, nil)
+func TestDAOSwitchToOpposeOldPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{true, false}, {false, true}}, params.MainNetDAOForkBlock, false)
 }
-func TestDAOContinueExplicitOpposeConPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoNoForkGenesis, false, false, true, true, nil)
+func TestDAOInitNoForkPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{}, daoGenesisForkBlock, false)
 }
-func TestDAOContinueImplicitOpposeConPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoNoForkGenesis, false, false, true, false, nil)
+func TestDAODefaultNoForkPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{{false, false}}, daoGenesisForkBlock, false)
 }
-func TestDAOSwitchOpposeConPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoNoForkGenesis, true, false, false, true, nil)
+func TestDAOSupportNoForkPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{{true, false}}, daoGenesisForkBlock, true)
 }
-func TestDAODefaultProPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoProForkGenesis, false, false, false, false, daoProForkBlock)
+func TestDAOOpposeNoForkPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{{false, true}}, daoGenesisForkBlock, false)
 }
-func TestDAOStartSupportProPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoProForkGenesis, false, true, false, false, daoProForkBlock)
+func TestDAOSwitchToSupportNoForkPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{{false, true}, {true, false}}, daoGenesisForkBlock, true)
 }
-func TestDAOContinueExplicitSupportProPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoProForkGenesis, true, true, false, false, daoProForkBlock)
+func TestDAOSwitchToOpposeNoForkPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{{true, false}, {false, true}}, daoGenesisForkBlock, false)
 }
-func TestDAOContinueImplicitSupportProPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoProForkGenesis, true, false, false, false, daoProForkBlock)
+func TestDAOInitProForkPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{}, daoGenesisForkBlock, true)
 }
-func TestDAOSwitchSupportProPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoProForkGenesis, false, true, true, false, params.MainNetDAOForkBlock)
+func TestDAODefaultProForkPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{{false, false}}, daoGenesisForkBlock, true)
 }
-func TestDAOStartOpposeProPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoProForkGenesis, false, false, false, true, nil)
+func TestDAOSupportProForkPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{{true, false}}, daoGenesisForkBlock, true)
 }
-func TestDAOContinueExplicitOpposeProPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoProForkGenesis, false, false, true, true, nil)
+func TestDAOOpposeProForkPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{{false, true}}, daoGenesisForkBlock, false)
 }
-func TestDAOContinueImplicitOpposeProPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoProForkGenesis, false, false, true, false, nil)
+func TestDAOSwitchToSupportProForkPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{{false, true}, {true, false}}, daoGenesisForkBlock, true)
 }
-func TestDAOSwitchOpposeProPrivnet(t *testing.T) {
-	testDAOForkBlockOldChain(t, false, daoProForkGenesis, true, false, false, true, nil)
+func TestDAOSwitchToOpposeProForkPrivnet(t *testing.T) {
+	testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{{true, false}, {false, true}}, daoGenesisForkBlock, false)
 }
 
-func testDAOForkBlockOldChain(t *testing.T, testnet bool, genesis string, oldSupport, newSupport, oldOppose, newOppose bool, expect *big.Int) {
+func testDAOForkBlockNewChain(t *testing.T, testnet bool, genesis string, votes [][2]bool, expectBlock *big.Int, expectVote bool) {
 	// Create a temporary data directory to use and inspect later
 	datadir := tmpdir(t)
 	defer os.RemoveAll(datadir)
 
-	// Cycle two Geth instances, possibly changing fork support in between
+	// Start a Geth instance with the requested flags set and immediately terminate
 	if genesis != "" {
 		json := filepath.Join(datadir, "genesis.json")
 		if err := ioutil.WriteFile(json, []byte(genesis), 0600); err != nil {
@@ -253,12 +180,23 @@ func testDAOForkBlockOldChain(t *testing.T, testnet bool, genesis string, oldSup
 		}
 		runGeth(t, "--datadir", datadir, "init", json).cmd.Wait()
 	}
-	execDAOGeth(t, datadir, testnet, oldSupport, oldOppose)
-	execDAOGeth(t, datadir, testnet, newSupport, newOppose)
-
+	for _, vote := range votes {
+		args := []string{"--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", "--ipcdisable", "--datadir", datadir}
+		if testnet {
+			args = append(args, "--testnet")
+		}
+		if vote[0] {
+			args = append(args, "--support-dao-fork")
+		}
+		if vote[1] {
+			args = append(args, "--oppose-dao-fork")
+		}
+		geth := runGeth(t, append(args, []string{"--exec", "2+2", "console"}...)...)
+		geth.cmd.Wait()
+	}
 	// Retrieve the DAO config flag from the database
 	path := filepath.Join(datadir, "chaindata")
-	if testnet {
+	if testnet && genesis == "" {
 		path = filepath.Join(datadir, "testnet", "chaindata")
 	}
 	db, err := ethdb.NewLDBDatabase(path, 0, 0)
@@ -270,10 +208,9 @@ func testDAOForkBlockOldChain(t *testing.T, testnet bool, genesis string, oldSup
 	genesisHash := common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
 	if testnet {
 		genesisHash = common.HexToHash("0x0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303")
-	} else if genesis == daoNoForkGenesis {
-		genesisHash = daoNoForkGenesisHash
-	} else if genesis == daoProForkGenesis {
-		genesisHash = daoProForkGenesisHash
+	}
+	if genesis != "" {
+		genesisHash = daoGenesisHash
 	}
 	config, err := core.GetChainConfig(db, genesisHash)
 	if err != nil {
@@ -281,26 +218,15 @@ func testDAOForkBlockOldChain(t *testing.T, testnet bool, genesis string, oldSup
 	}
 	// Validate the DAO hard-fork block number against the expected value
 	if config.DAOForkBlock == nil {
-		if expect != nil {
-			t.Fatalf("dao hard-fork block mismatch: have nil, want %v", expect)
+		if expectBlock != nil {
+			t.Errorf("dao hard-fork block mismatch: have nil, want %v", expectBlock)
 		}
-	} else if config.DAOForkBlock.Cmp(expect) != 0 {
-		t.Fatalf("dao hard-fork block mismatch: have %v, want %v", config.DAOForkBlock, expect)
-	}
-}
-
-// execDAOGeth starts a Geth instance with some DAO forks set and terminates.
-func execDAOGeth(t *testing.T, datadir string, testnet bool, supportFork bool, opposeFork bool) {
-	args := []string{"--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", "--ipcdisable", "--datadir", datadir}
-	if testnet {
-		args = append(args, "--testnet")
-	}
-	if supportFork {
-		args = append(args, "--support-dao-fork")
+	} else if expectBlock == nil {
+		t.Errorf("dao hard-fork block mismatch: have %v, want nil", config.DAOForkBlock)
+	} else if config.DAOForkBlock.Cmp(expectBlock) != 0 {
+		t.Errorf("dao hard-fork block mismatch: have %v, want %v", config.DAOForkBlock, expectBlock)
 	}
-	if opposeFork {
-		args = append(args, "--oppose-dao-fork")
+	if config.DAOForkSupport != expectVote {
+		t.Errorf("dao hard-fork support mismatch: have %v, want %v", config.DAOForkSupport, expectVote)
 	}
-	geth := runGeth(t, append(args, []string{"--exec", "2+2", "console"}...)...)
-	geth.cmd.Wait()
 }
diff --git a/cmd/geth/genesis_test.go b/cmd/geth/genesis_test.go
index 43d678d8959b42dfd5c023cd3898d113c7b0a9a2..4f8b1642ef183e3ab82db305fe9fbd0a434f70a4 100644
--- a/cmd/geth/genesis_test.go
+++ b/cmd/geth/genesis_test.go
@@ -75,7 +75,8 @@ var customGenesisTests = []struct {
 			"timestamp"  : "0x00",
 			"config"     : {
 				"homesteadBlock" : 314,
-				"daoForkBlock"   : 141
+				"daoForkBlock"   : 141,
+				"daoForkSupport" : true
 			},
 		}`,
 		query:  "eth.getBlock(0).nonce",
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index b95f5159cde92954a218b081069540f1c7076081..fae1647b3e8aa1d87fbef72c1f079202edf2de50 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -798,43 +798,42 @@ func MustMakeChainConfig(ctx *cli.Context) *core.ChainConfig {
 // MustMakeChainConfigFromDb reads the chain configuration from the given database.
 func MustMakeChainConfigFromDb(ctx *cli.Context, db ethdb.Database) *core.ChainConfig {
 	// If the chain is already initialized, use any existing chain configs
+	config := new(core.ChainConfig)
+
 	if genesis := core.GetBlock(db, core.GetCanonicalHash(db, 0), 0); genesis != nil {
 		storedConfig, err := core.GetChainConfig(db, genesis.Hash())
-		if err == nil {
-			// Force override any existing configs if explicitly requested
-			switch {
-			case storedConfig.DAOForkBlock == nil && ctx.GlobalBool(SupportDAOFork.Name) && ctx.GlobalBool(TestNetFlag.Name):
-				storedConfig.DAOForkBlock = params.TestNetDAOForkBlock
-			case storedConfig.DAOForkBlock == nil && ctx.GlobalBool(SupportDAOFork.Name):
-				storedConfig.DAOForkBlock = params.MainNetDAOForkBlock
-			case ctx.GlobalBool(OpposeDAOFork.Name):
-				storedConfig.DAOForkBlock = nil
-			}
-			return storedConfig
-		} else if err != core.ChainConfigNotFoundErr {
+		switch err {
+		case nil:
+			config = storedConfig
+		case core.ChainConfigNotFoundErr:
+			// No configs found, use empty, will populate below
+		default:
 			Fatalf("Could not make chain configuration: %v", err)
 		}
 	}
-	// If the chain is uninitialized nor no configs are present, create one
-	var homesteadBlock *big.Int
-	if ctx.GlobalBool(TestNetFlag.Name) {
-		homesteadBlock = params.TestNetHomesteadBlock
-	} else {
-		homesteadBlock = params.MainNetHomesteadBlock
+	// Set any missing fields due to them being unset or system upgrade
+	if config.HomesteadBlock == nil {
+		if ctx.GlobalBool(TestNetFlag.Name) {
+			config.HomesteadBlock = new(big.Int).Set(params.TestNetHomesteadBlock)
+		} else {
+			config.HomesteadBlock = new(big.Int).Set(params.MainNetHomesteadBlock)
+		}
 	}
-	var daoForkBlock *big.Int
+	if config.DAOForkBlock == nil {
+		if ctx.GlobalBool(TestNetFlag.Name) {
+			config.DAOForkBlock = new(big.Int).Set(params.TestNetDAOForkBlock)
+		} else {
+			config.DAOForkBlock = new(big.Int).Set(params.MainNetDAOForkBlock)
+		}
+	}
+	// Force override any existing configs if explicitly requested
 	switch {
-	case ctx.GlobalBool(SupportDAOFork.Name) && ctx.GlobalBool(TestNetFlag.Name):
-		daoForkBlock = params.TestNetDAOForkBlock
 	case ctx.GlobalBool(SupportDAOFork.Name):
-		daoForkBlock = params.MainNetDAOForkBlock
+		config.DAOForkSupport = true
 	case ctx.GlobalBool(OpposeDAOFork.Name):
-		daoForkBlock = nil
-	}
-	return &core.ChainConfig{
-		HomesteadBlock: homesteadBlock,
-		DAOForkBlock:   daoForkBlock,
+		config.DAOForkSupport = false
 	}
+	return config
 }
 
 // MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails.
diff --git a/core/block_validator.go b/core/block_validator.go
index c3f959324ae24ce2d0180691b88a8df249a444ef..73d581328805cef631153fdbf4fe804672ddc6a5 100644
--- a/core/block_validator.go
+++ b/core/block_validator.go
@@ -17,6 +17,7 @@
 package core
 
 import (
+	"bytes"
 	"fmt"
 	"math/big"
 	"time"
@@ -247,6 +248,26 @@ func ValidateHeader(config *ChainConfig, pow pow.PoW, header *types.Header, pare
 			return &BlockNonceErr{header.Number, header.Hash(), header.Nonce.Uint64()}
 		}
 	}
+	// DAO hard-fork extension to the header validity: a) if the node is no-fork,
+	// do not accept blocks in the [fork, fork+10) range with the fork specific
+	// extra-data set; b) if the node is pro-fork, require blocks in the specific
+	// range to have the unique extra-data set.
+	if daoBlock := config.DAOForkBlock; daoBlock != nil {
+		// Check whether the block is among the fork extra-override range
+		limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange)
+		if daoBlock.Cmp(header.Number) <= 0 && header.Number.Cmp(limit) < 0 {
+			// Depending whether we support or oppose the fork, verrift the extra-data contents
+			if config.DAOForkSupport {
+				if bytes.Compare(header.Extra, params.DAOForkBlockExtra) != 0 {
+					return ValidationError("DAO pro-fork bad block extra-data: 0x%x", header.Extra)
+				}
+			} else {
+				if bytes.Compare(header.Extra, params.DAOForkBlockExtra) == 0 {
+					return ValidationError("DAO no-fork bad block extra-data: 0x%x", header.Extra)
+				}
+			}
+		}
+	}
 	return nil
 }
 
diff --git a/core/block_validator_test.go b/core/block_validator_test.go
index c6daf9e7f3515e17a84fe6008089e98e0e29499e..5320c3f8dad948436d8af5f45b469e94ab5cca31 100644
--- a/core/block_validator_test.go
+++ b/core/block_validator_test.go
@@ -27,6 +27,7 @@ import (
 	"github.com/ethereum/go-ethereum/core/vm"
 	"github.com/ethereum/go-ethereum/ethdb"
 	"github.com/ethereum/go-ethereum/event"
+	"github.com/ethereum/go-ethereum/params"
 	"github.com/ethereum/go-ethereum/pow/ezp"
 )
 
@@ -92,3 +93,107 @@ func TestPutReceipt(t *testing.T) {
 		t.Error("expected to get 1 receipt, got none.")
 	}
 }
+
+// Tests that DAO-fork enabled clients can properly filter out fork-commencing
+// blocks based on their extradata fields.
+func TestDAOForkRangeExtradata(t *testing.T) {
+	forkBlock := big.NewInt(32)
+
+	// Generate a common prefix for both pro-forkers and non-forkers
+	db, _ := ethdb.NewMemDatabase()
+	genesis := WriteGenesisBlockForTesting(db)
+	prefix, _ := GenerateChain(genesis, db, int(forkBlock.Int64()-1), func(i int, gen *BlockGen) {})
+
+	// Create the concurrent, conflicting two nodes
+	proDb, _ := ethdb.NewMemDatabase()
+	WriteGenesisBlockForTesting(proDb)
+	proBc, _ := NewBlockChain(proDb, &ChainConfig{HomesteadBlock: big.NewInt(0), DAOForkBlock: forkBlock, DAOForkSupport: true}, new(FakePow), new(event.TypeMux))
+
+	conDb, _ := ethdb.NewMemDatabase()
+	WriteGenesisBlockForTesting(conDb)
+	conBc, _ := NewBlockChain(conDb, &ChainConfig{HomesteadBlock: big.NewInt(0), DAOForkBlock: forkBlock, DAOForkSupport: false}, new(FakePow), new(event.TypeMux))
+
+	if _, err := proBc.InsertChain(prefix); err != nil {
+		t.Fatalf("pro-fork: failed to import chain prefix: %v", err)
+	}
+	if _, err := conBc.InsertChain(prefix); err != nil {
+		t.Fatalf("con-fork: failed to import chain prefix: %v", err)
+	}
+	// Try to expand both pro-fork and non-fork chains iteratively with other camp's blocks
+	for i := int64(0); i < params.DAOForkExtraRange.Int64(); i++ {
+		// Create a pro-fork block, and try to feed into the no-fork chain
+		db, _ = ethdb.NewMemDatabase()
+		WriteGenesisBlockForTesting(db)
+		bc, _ := NewBlockChain(db, &ChainConfig{HomesteadBlock: big.NewInt(0)}, new(FakePow), new(event.TypeMux))
+
+		blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().NumberU64()+1))
+		for j := 0; j < len(blocks)/2; j++ {
+			blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[j]
+		}
+		if _, err := bc.InsertChain(blocks); err != nil {
+			t.Fatalf("failed to import contra-fork chain for expansion: %v", err)
+		}
+		blocks, _ = GenerateChain(conBc.CurrentBlock(), db, 1, func(i int, gen *BlockGen) { gen.SetExtra(params.DAOForkBlockExtra) })
+		if _, err := conBc.InsertChain(blocks); err == nil {
+			t.Fatalf("contra-fork chain accepted pro-fork block: %v", blocks[0])
+		}
+		// Create a proper no-fork block for the contra-forker
+		blocks, _ = GenerateChain(conBc.CurrentBlock(), db, 1, func(i int, gen *BlockGen) {})
+		if _, err := conBc.InsertChain(blocks); err != nil {
+			t.Fatalf("contra-fork chain didn't accepted no-fork block: %v", err)
+		}
+		// Create a no-fork block, and try to feed into the pro-fork chain
+		db, _ = ethdb.NewMemDatabase()
+		WriteGenesisBlockForTesting(db)
+		bc, _ = NewBlockChain(db, &ChainConfig{HomesteadBlock: big.NewInt(0)}, new(FakePow), new(event.TypeMux))
+
+		blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().NumberU64()+1))
+		for j := 0; j < len(blocks)/2; j++ {
+			blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[j]
+		}
+		if _, err := bc.InsertChain(blocks); err != nil {
+			t.Fatalf("failed to import pro-fork chain for expansion: %v", err)
+		}
+		blocks, _ = GenerateChain(proBc.CurrentBlock(), db, 1, func(i int, gen *BlockGen) {})
+		if _, err := proBc.InsertChain(blocks); err == nil {
+			t.Fatalf("pro-fork chain accepted contra-fork block: %v", blocks[0])
+		}
+		// Create a proper pro-fork block for the pro-forker
+		blocks, _ = GenerateChain(proBc.CurrentBlock(), db, 1, func(i int, gen *BlockGen) { gen.SetExtra(params.DAOForkBlockExtra) })
+		if _, err := proBc.InsertChain(blocks); err != nil {
+			t.Fatalf("pro-fork chain didn't accepted pro-fork block: %v", err)
+		}
+	}
+	// Verify that contra-forkers accept pro-fork extra-datas after forking finishes
+	db, _ = ethdb.NewMemDatabase()
+	WriteGenesisBlockForTesting(db)
+	bc, _ := NewBlockChain(db, &ChainConfig{HomesteadBlock: big.NewInt(0)}, new(FakePow), new(event.TypeMux))
+
+	blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().NumberU64()+1))
+	for j := 0; j < len(blocks)/2; j++ {
+		blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[j]
+	}
+	if _, err := bc.InsertChain(blocks); err != nil {
+		t.Fatalf("failed to import contra-fork chain for expansion: %v", err)
+	}
+	blocks, _ = GenerateChain(conBc.CurrentBlock(), db, 1, func(i int, gen *BlockGen) { gen.SetExtra(params.DAOForkBlockExtra) })
+	if _, err := conBc.InsertChain(blocks); err != nil {
+		t.Fatalf("contra-fork chain didn't accept pro-fork block post-fork: %v", err)
+	}
+	// Verify that pro-forkers accept contra-fork extra-datas after forking finishes
+	db, _ = ethdb.NewMemDatabase()
+	WriteGenesisBlockForTesting(db)
+	bc, _ = NewBlockChain(db, &ChainConfig{HomesteadBlock: big.NewInt(0)}, new(FakePow), new(event.TypeMux))
+
+	blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().NumberU64()+1))
+	for j := 0; j < len(blocks)/2; j++ {
+		blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[j]
+	}
+	if _, err := bc.InsertChain(blocks); err != nil {
+		t.Fatalf("failed to import pro-fork chain for expansion: %v", err)
+	}
+	blocks, _ = GenerateChain(proBc.CurrentBlock(), db, 1, func(i int, gen *BlockGen) {})
+	if _, err := proBc.InsertChain(blocks); err != nil {
+		t.Fatalf("pro-fork chain didn't accept contra-fork block post-fork: %v", err)
+	}
+}
diff --git a/core/config.go b/core/config.go
index d04b00e9c345ca7b867e5f428fa1d52033b4cddc..c0d065a57febcc2378605e07120c5bd7736ba171 100644
--- a/core/config.go
+++ b/core/config.go
@@ -31,8 +31,9 @@ var ChainConfigNotFoundErr = errors.New("ChainConfig not found") // general conf
 // that any network, identified by its genesis block, can have its own
 // set of configuration options.
 type ChainConfig struct {
-	HomesteadBlock *big.Int `json:"homesteadBlock"` // homestead switch block (0 = already homestead)
-	DAOForkBlock   *big.Int `json:"daoForkBlock"`   // TheDAO hard-fork block (nil = no fork)
+	HomesteadBlock *big.Int `json:"homesteadBlock"` // Homestead switch block (nil = no fork, 0 = already homestead)
+	DAOForkBlock   *big.Int `json:"daoForkBlock"`   // TheDAO hard-fork switch block (nil = no fork)
+	DAOForkSupport bool     `json:"daoForkSupport"` // Whether the nodes supports or opposes the DAO hard-fork
 
 	VmConfig vm.Config `json:"-"`
 }
diff --git a/miner/worker.go b/miner/worker.go
index 7197a33ba4ecbabdfaaa80df0bdab90efd53ca9f..ba0085d52131d4768e410dd7a317c041b48d4379 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -17,6 +17,7 @@
 package miner
 
 import (
+	"bytes"
 	"fmt"
 	"math/big"
 	"sync"
@@ -469,12 +470,17 @@ func (self *worker) commitNewWork() {
 		Extra:      self.extra,
 		Time:       big.NewInt(tstamp),
 	}
-	// If we are doing a DAO hard-fork check whether to override the extra-data or not
+	// If we are care about TheDAO hard-fork check whether to override the extra-data or not
 	if daoBlock := self.config.DAOForkBlock; daoBlock != nil {
 		// Check whether the block is among the fork extra-override range
 		limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange)
 		if daoBlock.Cmp(header.Number) <= 0 && header.Number.Cmp(limit) < 0 {
-			header.Extra = common.CopyBytes(params.DAOForkBlockExtra)
+			// Depending whether we support or oppose the fork, override differently
+			if self.config.DAOForkSupport {
+				header.Extra = common.CopyBytes(params.DAOForkBlockExtra)
+			} else if bytes.Compare(header.Extra, params.DAOForkBlockExtra) == 0 {
+				header.Extra = []byte{} // If miner opposes, don't let it use the reserved extra-data
+			}
 		}
 	}
 	previous := self.current