github.com/calmw/ethereum@v0.1.1/cmd/geth/genesis_test.go (about) 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 17 package main 18 19 import ( 20 "fmt" 21 "os" 22 "path/filepath" 23 "strconv" 24 "testing" 25 ) 26 27 var customGenesisTests = []struct { 28 genesis string 29 query string 30 result string 31 }{ 32 // Genesis file with an empty chain configuration (ensure missing fields work) 33 { 34 genesis: `{ 35 "alloc" : {}, 36 "coinbase" : "0x0000000000000000000000000000000000000000", 37 "difficulty" : "0x20000", 38 "extraData" : "", 39 "gasLimit" : "0x2fefd8", 40 "nonce" : "0x0000000000001338", 41 "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", 42 "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", 43 "timestamp" : "0x00", 44 "config" : { 45 "terminalTotalDifficultyPassed": true 46 } 47 }`, 48 query: "eth.getBlock(0).nonce", 49 result: "0x0000000000001338", 50 }, 51 // Genesis file with specific chain configurations 52 { 53 genesis: `{ 54 "alloc" : {}, 55 "coinbase" : "0x0000000000000000000000000000000000000000", 56 "difficulty" : "0x20000", 57 "extraData" : "", 58 "gasLimit" : "0x2fefd8", 59 "nonce" : "0x0000000000001339", 60 "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", 61 "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", 62 "timestamp" : "0x00", 63 "config" : { 64 "homesteadBlock" : 42, 65 "daoForkBlock" : 141, 66 "daoForkSupport" : true, 67 "terminalTotalDifficultyPassed" : true 68 } 69 }`, 70 query: "eth.getBlock(0).nonce", 71 result: "0x0000000000001339", 72 }, 73 } 74 75 // Tests that initializing Geth with a custom genesis block and chain definitions 76 // work properly. 77 func TestCustomGenesis(t *testing.T) { 78 t.Parallel() 79 for i, tt := range customGenesisTests { 80 // Create a temporary data directory to use and inspect later 81 datadir := t.TempDir() 82 83 // Initialize the data directory with the custom genesis block 84 json := filepath.Join(datadir, "genesis.json") 85 if err := os.WriteFile(json, []byte(tt.genesis), 0600); err != nil { 86 t.Fatalf("test %d: failed to write genesis file: %v", i, err) 87 } 88 runGeth(t, "--datadir", datadir, "init", json).WaitExit() 89 90 // Query the custom genesis block 91 geth := runGeth(t, "--networkid", "1337", "--syncmode=full", "--cache", "16", 92 "--datadir", datadir, "--maxpeers", "0", "--port", "0", "--authrpc.port", "0", 93 "--nodiscover", "--nat", "none", "--ipcdisable", 94 "--exec", tt.query, "console") 95 geth.ExpectRegexp(tt.result) 96 geth.ExpectExit() 97 } 98 } 99 100 // TestCustomBackend that the backend selection and detection (leveldb vs pebble) works properly. 101 func TestCustomBackend(t *testing.T) { 102 t.Parallel() 103 // Test pebble, but only on 64-bit platforms 104 if strconv.IntSize != 64 { 105 t.Skip("Custom backends are only available on 64-bit platform") 106 } 107 genesis := `{ 108 "alloc" : {}, 109 "coinbase" : "0x0000000000000000000000000000000000000000", 110 "difficulty" : "0x20000", 111 "extraData" : "", 112 "gasLimit" : "0x2fefd8", 113 "nonce" : "0x0000000000001338", 114 "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", 115 "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", 116 "timestamp" : "0x00", 117 "config" : { 118 "terminalTotalDifficultyPassed": true 119 } 120 }` 121 type backendTest struct { 122 initArgs []string 123 initExpect string 124 execArgs []string 125 execExpect string 126 } 127 testfunc := func(t *testing.T, tt backendTest) error { 128 // Create a temporary data directory to use and inspect later 129 datadir := t.TempDir() 130 131 // Initialize the data directory with the custom genesis block 132 json := filepath.Join(datadir, "genesis.json") 133 if err := os.WriteFile(json, []byte(genesis), 0600); err != nil { 134 return fmt.Errorf("failed to write genesis file: %v", err) 135 } 136 { // Init 137 args := append(tt.initArgs, "--datadir", datadir, "init", json) 138 geth := runGeth(t, args...) 139 geth.ExpectRegexp(tt.initExpect) 140 geth.ExpectExit() 141 } 142 { // Exec + query 143 args := append(tt.execArgs, "--networkid", "1337", "--syncmode=full", "--cache", "16", 144 "--datadir", datadir, "--maxpeers", "0", "--port", "0", "--authrpc.port", "0", 145 "--nodiscover", "--nat", "none", "--ipcdisable", 146 "--exec", "eth.getBlock(0).nonce", "console") 147 geth := runGeth(t, args...) 148 geth.ExpectRegexp(tt.execExpect) 149 geth.ExpectExit() 150 } 151 return nil 152 } 153 for i, tt := range []backendTest{ 154 { // When not specified, it should default to pebble 155 execArgs: []string{"--db.engine", "pebble"}, 156 execExpect: "0x0000000000001338", 157 }, 158 { // Explicit leveldb 159 initArgs: []string{"--db.engine", "leveldb"}, 160 execArgs: []string{"--db.engine", "leveldb"}, 161 execExpect: "0x0000000000001338", 162 }, 163 { // Explicit leveldb first, then autodiscover 164 initArgs: []string{"--db.engine", "leveldb"}, 165 execExpect: "0x0000000000001338", 166 }, 167 { // Explicit pebble 168 initArgs: []string{"--db.engine", "pebble"}, 169 execArgs: []string{"--db.engine", "pebble"}, 170 execExpect: "0x0000000000001338", 171 }, 172 { // Explicit pebble, then auto-discover 173 initArgs: []string{"--db.engine", "pebble"}, 174 execExpect: "0x0000000000001338", 175 }, 176 { // Can't start pebble on top of leveldb 177 initArgs: []string{"--db.engine", "leveldb"}, 178 execArgs: []string{"--db.engine", "pebble"}, 179 execExpect: `Fatal: Failed to register the Ethereum service: db.engine choice was pebble but found pre-existing leveldb database in specified data directory`, 180 }, 181 { // Can't start leveldb on top of pebble 182 initArgs: []string{"--db.engine", "pebble"}, 183 execArgs: []string{"--db.engine", "leveldb"}, 184 execExpect: `Fatal: Failed to register the Ethereum service: db.engine choice was leveldb but found pre-existing pebble database in specified data directory`, 185 }, 186 { // Reject invalid backend choice 187 initArgs: []string{"--db.engine", "mssql"}, 188 initExpect: `Fatal: Invalid choice for db.engine 'mssql', allowed 'leveldb' or 'pebble'`, 189 // Since the init fails, this will return the (default) mainnet genesis 190 // block nonce 191 execExpect: `0x0000000000000042`, 192 }, 193 } { 194 if err := testfunc(t, tt); err != nil { 195 t.Fatalf("test %d-leveldb: %v", i, err) 196 } 197 } 198 }