dao_test.go 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. // Copyright 2016 The go-ethereum Authors
  2. // This file is part of go-ethereum.
  3. //
  4. // go-ethereum is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // go-ethereum is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
  16. package main
  17. import (
  18. "io/ioutil"
  19. "math/big"
  20. "os"
  21. "path/filepath"
  22. "testing"
  23. "github.com/ethereum/go-ethereum/common"
  24. "github.com/ethereum/go-ethereum/core"
  25. "github.com/ethereum/go-ethereum/ethdb"
  26. "github.com/ethereum/go-ethereum/params"
  27. )
  28. // Genesis block for nodes which don't care about the DAO fork (i.e. not configured)
  29. var daoOldGenesis = `{
  30. "alloc" : {},
  31. "coinbase" : "0x0000000000000000000000000000000000000000",
  32. "difficulty" : "0x20000",
  33. "extraData" : "",
  34. "gasLimit" : "0x2fefd8",
  35. "nonce" : "0x0000000000000042",
  36. "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  37. "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  38. "timestamp" : "0x00",
  39. "config" : {}
  40. }`
  41. // Genesis block for nodes which actively oppose the DAO fork
  42. var daoNoForkGenesis = `{
  43. "alloc" : {},
  44. "coinbase" : "0x0000000000000000000000000000000000000000",
  45. "difficulty" : "0x20000",
  46. "extraData" : "",
  47. "gasLimit" : "0x2fefd8",
  48. "nonce" : "0x0000000000000042",
  49. "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  50. "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  51. "timestamp" : "0x00",
  52. "config" : {
  53. "daoForkBlock" : 314,
  54. "daoForkSupport" : false
  55. }
  56. }`
  57. // Genesis block for nodes which actively support the DAO fork
  58. var daoProForkGenesis = `{
  59. "alloc" : {},
  60. "coinbase" : "0x0000000000000000000000000000000000000000",
  61. "difficulty" : "0x20000",
  62. "extraData" : "",
  63. "gasLimit" : "0x2fefd8",
  64. "nonce" : "0x0000000000000042",
  65. "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  66. "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  67. "timestamp" : "0x00",
  68. "config" : {
  69. "daoForkBlock" : 314,
  70. "daoForkSupport" : true
  71. }
  72. }`
  73. var daoGenesisHash = common.HexToHash("5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0")
  74. var daoGenesisForkBlock = big.NewInt(314)
  75. // Tests that the DAO hard-fork number and the nodes support/opposition is correctly
  76. // set in the database after various initialization procedures and invocations.
  77. func TestDAODefaultMainnet(t *testing.T) {
  78. testDAOForkBlockNewChain(t, false, "", [][2]bool{{false, false}}, params.MainNetDAOForkBlock, true)
  79. }
  80. func TestDAOSupportMainnet(t *testing.T) {
  81. testDAOForkBlockNewChain(t, false, "", [][2]bool{{true, false}}, params.MainNetDAOForkBlock, true)
  82. }
  83. func TestDAOOpposeMainnet(t *testing.T) {
  84. testDAOForkBlockNewChain(t, false, "", [][2]bool{{false, true}}, params.MainNetDAOForkBlock, false)
  85. }
  86. func TestDAOSwitchToSupportMainnet(t *testing.T) {
  87. testDAOForkBlockNewChain(t, false, "", [][2]bool{{false, true}, {true, false}}, params.MainNetDAOForkBlock, true)
  88. }
  89. func TestDAOSwitchToOpposeMainnet(t *testing.T) {
  90. testDAOForkBlockNewChain(t, false, "", [][2]bool{{true, false}, {false, true}}, params.MainNetDAOForkBlock, false)
  91. }
  92. func TestDAODefaultTestnet(t *testing.T) {
  93. testDAOForkBlockNewChain(t, true, "", [][2]bool{{false, false}}, params.TestNetDAOForkBlock, true)
  94. }
  95. func TestDAOSupportTestnet(t *testing.T) {
  96. testDAOForkBlockNewChain(t, true, "", [][2]bool{{true, false}}, params.TestNetDAOForkBlock, true)
  97. }
  98. func TestDAOOpposeTestnet(t *testing.T) {
  99. testDAOForkBlockNewChain(t, true, "", [][2]bool{{false, true}}, params.TestNetDAOForkBlock, false)
  100. }
  101. func TestDAOSwitchToSupportTestnet(t *testing.T) {
  102. testDAOForkBlockNewChain(t, true, "", [][2]bool{{false, true}, {true, false}}, params.TestNetDAOForkBlock, true)
  103. }
  104. func TestDAOSwitchToOpposeTestnet(t *testing.T) {
  105. testDAOForkBlockNewChain(t, true, "", [][2]bool{{true, false}, {false, true}}, params.TestNetDAOForkBlock, false)
  106. }
  107. func TestDAOInitOldPrivnet(t *testing.T) {
  108. testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{}, nil, false)
  109. }
  110. func TestDAODefaultOldPrivnet(t *testing.T) {
  111. testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{false, false}}, params.MainNetDAOForkBlock, true)
  112. }
  113. func TestDAOSupportOldPrivnet(t *testing.T) {
  114. testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{true, false}}, params.MainNetDAOForkBlock, true)
  115. }
  116. func TestDAOOpposeOldPrivnet(t *testing.T) {
  117. testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{false, true}}, params.MainNetDAOForkBlock, false)
  118. }
  119. func TestDAOSwitchToSupportOldPrivnet(t *testing.T) {
  120. testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{false, true}, {true, false}}, params.MainNetDAOForkBlock, true)
  121. }
  122. func TestDAOSwitchToOpposeOldPrivnet(t *testing.T) {
  123. testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{true, false}, {false, true}}, params.MainNetDAOForkBlock, false)
  124. }
  125. func TestDAOInitNoForkPrivnet(t *testing.T) {
  126. testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{}, daoGenesisForkBlock, false)
  127. }
  128. func TestDAODefaultNoForkPrivnet(t *testing.T) {
  129. testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{{false, false}}, daoGenesisForkBlock, false)
  130. }
  131. func TestDAOSupportNoForkPrivnet(t *testing.T) {
  132. testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{{true, false}}, daoGenesisForkBlock, true)
  133. }
  134. func TestDAOOpposeNoForkPrivnet(t *testing.T) {
  135. testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{{false, true}}, daoGenesisForkBlock, false)
  136. }
  137. func TestDAOSwitchToSupportNoForkPrivnet(t *testing.T) {
  138. testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{{false, true}, {true, false}}, daoGenesisForkBlock, true)
  139. }
  140. func TestDAOSwitchToOpposeNoForkPrivnet(t *testing.T) {
  141. testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{{true, false}, {false, true}}, daoGenesisForkBlock, false)
  142. }
  143. func TestDAOInitProForkPrivnet(t *testing.T) {
  144. testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{}, daoGenesisForkBlock, true)
  145. }
  146. func TestDAODefaultProForkPrivnet(t *testing.T) {
  147. testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{{false, false}}, daoGenesisForkBlock, true)
  148. }
  149. func TestDAOSupportProForkPrivnet(t *testing.T) {
  150. testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{{true, false}}, daoGenesisForkBlock, true)
  151. }
  152. func TestDAOOpposeProForkPrivnet(t *testing.T) {
  153. testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{{false, true}}, daoGenesisForkBlock, false)
  154. }
  155. func TestDAOSwitchToSupportProForkPrivnet(t *testing.T) {
  156. testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{{false, true}, {true, false}}, daoGenesisForkBlock, true)
  157. }
  158. func TestDAOSwitchToOpposeProForkPrivnet(t *testing.T) {
  159. testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{{true, false}, {false, true}}, daoGenesisForkBlock, false)
  160. }
  161. func testDAOForkBlockNewChain(t *testing.T, testnet bool, genesis string, votes [][2]bool, expectBlock *big.Int, expectVote bool) {
  162. // Create a temporary data directory to use and inspect later
  163. datadir := tmpdir(t)
  164. defer os.RemoveAll(datadir)
  165. // Start a Geth instance with the requested flags set and immediately terminate
  166. if genesis != "" {
  167. json := filepath.Join(datadir, "genesis.json")
  168. if err := ioutil.WriteFile(json, []byte(genesis), 0600); err != nil {
  169. t.Fatalf("failed to write genesis file: %v", err)
  170. }
  171. runGeth(t, "--datadir", datadir, "init", json).cmd.Wait()
  172. }
  173. for _, vote := range votes {
  174. args := []string{"--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", "--ipcdisable", "--datadir", datadir}
  175. if testnet {
  176. args = append(args, "--testnet")
  177. }
  178. if vote[0] {
  179. args = append(args, "--support-dao-fork")
  180. }
  181. if vote[1] {
  182. args = append(args, "--oppose-dao-fork")
  183. }
  184. geth := runGeth(t, append(args, []string{"--exec", "2+2", "console"}...)...)
  185. geth.cmd.Wait()
  186. }
  187. // Retrieve the DAO config flag from the database
  188. path := filepath.Join(datadir, "geth", "chaindata")
  189. if testnet && genesis == "" {
  190. path = filepath.Join(datadir, "testnet", "geth", "chaindata")
  191. }
  192. db, err := ethdb.NewLDBDatabase(path, 0, 0)
  193. if err != nil {
  194. t.Fatalf("failed to open test database: %v", err)
  195. }
  196. defer db.Close()
  197. genesisHash := common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
  198. if testnet {
  199. genesisHash = common.HexToHash("0x0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303")
  200. }
  201. if genesis != "" {
  202. genesisHash = daoGenesisHash
  203. }
  204. config, err := core.GetChainConfig(db, genesisHash)
  205. if err != nil {
  206. t.Fatalf("failed to retrieve chain config: %v", err)
  207. }
  208. // Validate the DAO hard-fork block number against the expected value
  209. if config.DAOForkBlock == nil {
  210. if expectBlock != nil {
  211. t.Errorf("dao hard-fork block mismatch: have nil, want %v", expectBlock)
  212. }
  213. } else if expectBlock == nil {
  214. t.Errorf("dao hard-fork block mismatch: have %v, want nil", config.DAOForkBlock)
  215. } else if config.DAOForkBlock.Cmp(expectBlock) != 0 {
  216. t.Errorf("dao hard-fork block mismatch: have %v, want %v", config.DAOForkBlock, expectBlock)
  217. }
  218. if config.DAOForkSupport != expectVote {
  219. t.Errorf("dao hard-fork support mismatch: have %v, want %v", config.DAOForkSupport, expectVote)
  220. }
  221. }