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