func upgradeDB(ctx *cli.Context) { glog.Infoln("Upgrading blockchain database") chain, chainDb := utils.MakeChain(ctx) v, _ := chainDb.Get([]byte("BlockchainVersion")) bcVersion := int(common.NewValue(v).Uint()) if bcVersion == 0 { bcVersion = core.BlockChainVersion } // Export the current chain. filename := fmt.Sprintf("blockchain_%d_%s.chain", bcVersion, time.Now().Format("20060102_150405")) exportFile := filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), filename) if err := utils.ExportChain(chain, exportFile); err != nil { utils.Fatalf("Unable to export chain for reimport %s", err) } chainDb.Close() os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "chaindata")) // Import the chain file. chain, chainDb = utils.MakeChain(ctx) chainDb.Put([]byte("BlockchainVersion"), common.NewValue(core.BlockChainVersion).Bytes()) err := utils.ImportChain(chain, exportFile) chainDb.Close() if err != nil { utils.Fatalf("Import error %v (a backup is made in %s, use the import command to import it)", err, exportFile) } else { os.Remove(exportFile) glog.Infoln("Import finished") } }
func saveBlockchainVersion(db common.Database, bcVersion int) { d, _ := db.Get([]byte("BlockchainVersion")) blockchainVersion := common.NewValue(d).Uint() if blockchainVersion == 0 { db.Put([]byte("BlockchainVersion"), common.NewValue(bcVersion).Bytes()) } }
func saveProtocolVersion(db common.Database, protov int) { d, _ := db.Get([]byte("ProtocolVersion")) protocolVersion := common.NewValue(d).Uint() if protocolVersion == 0 { db.Put([]byte("ProtocolVersion"), common.NewValue(protov).Bytes()) } }
func upgradeDb(ctx *cli.Context) { fmt.Println("Upgrade blockchain DB") cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx) cfg.SkipBcVersionCheck = true ethereum, err := eth.New(cfg) if err != nil { utils.Fatalf("%v\n", err) } v, _ := ethereum.BlockDb().Get([]byte("BlockchainVersion")) bcVersion := int(common.NewValue(v).Uint()) if bcVersion == 0 { bcVersion = core.BlockChainVersion } filename := fmt.Sprintf("blockchain_%d_%s.chain", bcVersion, time.Now().Format("2006-01-02_15:04:05")) exportFile := path.Join(ctx.GlobalString(utils.DataDirFlag.Name), filename) err = utils.ExportChain(ethereum.ChainManager(), exportFile) if err != nil { utils.Fatalf("Unable to export chain for reimport %s\n", err) } ethereum.BlockDb().Close() ethereum.StateDb().Close() ethereum.ExtraDb().Close() os.RemoveAll(path.Join(ctx.GlobalString(utils.DataDirFlag.Name), "blockchain")) ethereum, err = eth.New(cfg) if err != nil { utils.Fatalf("%v\n", err) } ethereum.BlockDb().Put([]byte("BlockchainVersion"), common.NewValue(core.BlockChainVersion).Bytes()) err = utils.ImportChain(ethereum.ChainManager(), exportFile) if err != nil { utils.Fatalf("Import error %v (a backup is made in %s, use the import command to import it)\n", err, exportFile) } // force database flush ethereum.BlockDb().Close() ethereum.StateDb().Close() ethereum.ExtraDb().Close() os.Remove(exportFile) fmt.Println("Import finished") }
func (c *StateObject) GetInstr(pc *big.Int) *common.Value { if int64(len(c.code)-1) < pc.Int64() { return common.NewValue(0) } return common.NewValueFromBytes([]byte{c.code[pc.Int64()]}) }
func (self *StateDB) SetState(addr common.Address, key common.Hash, value interface{}) { stateObject := self.GetOrNewStateObject(addr) if stateObject != nil { stateObject.SetState(key, common.NewValue(value)) } }
func New(config *Config) (*Ethereum, error) { // Bootstrap database logger.New(config.DataDir, config.LogFile, config.Verbosity) if len(config.LogJSON) > 0 { logger.NewJSONsystem(config.DataDir, config.LogJSON) } // Let the database take 3/4 of the max open files (TODO figure out a way to get the actual limit of the open files) const dbCount = 3 ethdb.OpenFileLimit = 256 / (dbCount + 1) newdb := config.NewDB if newdb == nil { newdb = func(path string) (common.Database, error) { return ethdb.NewLDBDatabase(path) } } blockDb, err := newdb(filepath.Join(config.DataDir, "blockchain")) if err != nil { return nil, fmt.Errorf("blockchain db err: %v", err) } stateDb, err := newdb(filepath.Join(config.DataDir, "state")) if err != nil { return nil, fmt.Errorf("state db err: %v", err) } extraDb, err := newdb(filepath.Join(config.DataDir, "extra")) if err != nil { return nil, fmt.Errorf("extra db err: %v", err) } nodeDb := filepath.Join(config.DataDir, "nodes") // Perform database sanity checks d, _ := blockDb.Get([]byte("ProtocolVersion")) protov := int(common.NewValue(d).Uint()) if protov != config.ProtocolVersion && protov != 0 { path := filepath.Join(config.DataDir, "blockchain") return nil, fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, config.ProtocolVersion, path) } saveProtocolVersion(blockDb, config.ProtocolVersion) glog.V(logger.Info).Infof("Protocol Version: %v, Network Id: %v", config.ProtocolVersion, config.NetworkId) if !config.SkipBcVersionCheck { b, _ := blockDb.Get([]byte("BlockchainVersion")) bcVersion := int(common.NewValue(b).Uint()) if bcVersion != config.BlockChainVersion && bcVersion != 0 { return nil, fmt.Errorf("Blockchain DB version mismatch (%d / %d). Run geth upgradedb.\n", bcVersion, config.BlockChainVersion) } saveBlockchainVersion(blockDb, config.BlockChainVersion) } glog.V(logger.Info).Infof("Blockchain DB Version: %d", config.BlockChainVersion) eth := &Ethereum{ shutdownChan: make(chan bool), databasesClosed: make(chan bool), blockDb: blockDb, stateDb: stateDb, extraDb: extraDb, eventMux: &event.TypeMux{}, accountManager: config.AccountManager, DataDir: config.DataDir, etherbase: common.HexToAddress(config.Etherbase), clientVersion: config.Name, // TODO should separate from Name ethVersionId: config.ProtocolVersion, netVersionId: config.NetworkId, NatSpec: config.NatSpec, } eth.chainManager = core.NewChainManager(blockDb, stateDb, eth.EventMux()) eth.downloader = downloader.New(eth.chainManager.HasBlock, eth.chainManager.GetBlock) eth.pow = ethash.New() eth.txPool = core.NewTxPool(eth.EventMux(), eth.chainManager.State, eth.chainManager.GasLimit) eth.blockProcessor = core.NewBlockProcessor(stateDb, extraDb, eth.pow, eth.txPool, eth.chainManager, eth.EventMux()) eth.chainManager.SetProcessor(eth.blockProcessor) eth.miner = miner.New(eth, eth.pow) eth.miner.SetGasPrice(config.GasPrice) eth.protocolManager = NewProtocolManager(config.ProtocolVersion, config.NetworkId, eth.eventMux, eth.txPool, eth.chainManager, eth.downloader) if config.Shh { eth.whisper = whisper.New() eth.shhVersionId = int(eth.whisper.Version()) } netprv, err := config.nodeKey() if err != nil { return nil, err } protocols := []p2p.Protocol{eth.protocolManager.SubProtocol} if config.Shh { protocols = append(protocols, eth.whisper.Protocol()) } eth.net = &p2p.Server{ PrivateKey: netprv, Name: config.Name, MaxPeers: config.MaxPeers, MaxPendingPeers: config.MaxPendingPeers, Protocols: protocols, NAT: config.NAT, NoDial: !config.Dial, BootstrapNodes: config.parseBootNodes(), StaticNodes: config.parseNodes(staticNodes), TrustedNodes: config.parseNodes(trustedNodes), NodeDatabase: nodeDb, } if len(config.Port) > 0 { eth.net.ListenAddr = ":" + config.Port } vm.Debug = config.VmDebug return eth, nil }
func New(config *Config) (*Ethereum, error) { // Bootstrap database logger.New(config.DataDir, config.LogFile, config.Verbosity) if len(config.LogJSON) > 0 { logger.NewJSONsystem(config.DataDir, config.LogJSON) } // Let the database take 3/4 of the max open files (TODO figure out a way to get the actual limit of the open files) const dbCount = 3 ethdb.OpenFileLimit = 128 / (dbCount + 1) newdb := config.NewDB if newdb == nil { newdb = func(path string) (common.Database, error) { return ethdb.NewLDBDatabase(path, config.DatabaseCache) } } blockDb, err := newdb(filepath.Join(config.DataDir, "blockchain")) if err != nil { return nil, fmt.Errorf("blockchain db err: %v", err) } if db, ok := blockDb.(*ethdb.LDBDatabase); ok { db.Meter("eth/db/block/") } stateDb, err := newdb(filepath.Join(config.DataDir, "state")) if err != nil { return nil, fmt.Errorf("state db err: %v", err) } if db, ok := stateDb.(*ethdb.LDBDatabase); ok { db.Meter("eth/db/state/") } extraDb, err := newdb(filepath.Join(config.DataDir, "extra")) if err != nil { return nil, fmt.Errorf("extra db err: %v", err) } if db, ok := extraDb.(*ethdb.LDBDatabase); ok { db.Meter("eth/db/extra/") } nodeDb := filepath.Join(config.DataDir, "nodes") glog.V(logger.Info).Infof("Protocol Versions: %v, Network Id: %v", ProtocolVersions, config.NetworkId) if len(config.GenesisFile) > 0 { fr, err := os.Open(config.GenesisFile) if err != nil { return nil, err } block, err := core.WriteGenesisBlock(stateDb, blockDb, fr) if err != nil { return nil, err } glog.V(logger.Info).Infof("Successfully wrote genesis block. New genesis hash = %x\n", block.Hash()) } if config.Olympic { _, err := core.WriteTestNetGenesisBlock(stateDb, blockDb, 42) if err != nil { return nil, err } glog.V(logger.Error).Infoln("Starting Olympic network") } // This is for testing only. if config.GenesisBlock != nil { core.WriteBlock(blockDb, config.GenesisBlock) core.WriteHead(blockDb, config.GenesisBlock) } if !config.SkipBcVersionCheck { b, _ := blockDb.Get([]byte("BlockchainVersion")) bcVersion := int(common.NewValue(b).Uint()) if bcVersion != config.BlockChainVersion && bcVersion != 0 { return nil, fmt.Errorf("Blockchain DB version mismatch (%d / %d). Run geth upgradedb.\n", bcVersion, config.BlockChainVersion) } saveBlockchainVersion(blockDb, config.BlockChainVersion) } glog.V(logger.Info).Infof("Blockchain DB Version: %d", config.BlockChainVersion) eth := &Ethereum{ shutdownChan: make(chan bool), databasesClosed: make(chan bool), blockDb: blockDb, stateDb: stateDb, extraDb: extraDb, eventMux: &event.TypeMux{}, accountManager: config.AccountManager, DataDir: config.DataDir, etherbase: config.Etherbase, clientVersion: config.Name, // TODO should separate from Name netVersionId: config.NetworkId, NatSpec: config.NatSpec, MinerThreads: config.MinerThreads, SolcPath: config.SolcPath, AutoDAG: config.AutoDAG, PowTest: config.PowTest, GpoMinGasPrice: config.GpoMinGasPrice, GpoMaxGasPrice: config.GpoMaxGasPrice, GpoFullBlockRatio: config.GpoFullBlockRatio, GpobaseStepDown: config.GpobaseStepDown, GpobaseStepUp: config.GpobaseStepUp, GpobaseCorrectionFactor: config.GpobaseCorrectionFactor, } if config.PowTest { glog.V(logger.Info).Infof("ethash used in test mode") eth.pow, err = ethash.NewForTesting() if err != nil { return nil, err } } else { eth.pow = ethash.New() } //genesis := core.GenesisBlock(uint64(config.GenesisNonce), stateDb) eth.chainManager, err = core.NewChainManager(blockDb, stateDb, extraDb, eth.pow, eth.EventMux()) if err != nil { if err == core.ErrNoGenesis { return nil, fmt.Errorf(`Genesis block not found. Please supply a genesis block with the "--genesis /path/to/file" argument`) } return nil, err } eth.txPool = core.NewTxPool(eth.EventMux(), eth.chainManager.State, eth.chainManager.GasLimit) eth.blockProcessor = core.NewBlockProcessor(stateDb, extraDb, eth.pow, eth.chainManager, eth.EventMux()) eth.chainManager.SetProcessor(eth.blockProcessor) eth.protocolManager = NewProtocolManager(config.NetworkId, eth.eventMux, eth.txPool, eth.pow, eth.chainManager) eth.miner = miner.New(eth, eth.EventMux(), eth.pow) eth.miner.SetGasPrice(config.GasPrice) extra := config.Name if uint64(len(extra)) > params.MaximumExtraDataSize.Uint64() { extra = extra[:params.MaximumExtraDataSize.Uint64()] } eth.miner.SetExtra([]byte(extra)) if config.Shh { eth.whisper = whisper.New() eth.shhVersionId = int(eth.whisper.Version()) } netprv, err := config.nodeKey() if err != nil { return nil, err } protocols := append([]p2p.Protocol{}, eth.protocolManager.SubProtocols...) if config.Shh { protocols = append(protocols, eth.whisper.Protocol()) } eth.net = &p2p.Server{ PrivateKey: netprv, Name: config.Name, MaxPeers: config.MaxPeers, MaxPendingPeers: config.MaxPendingPeers, Discovery: config.Discovery, Protocols: protocols, NAT: config.NAT, NoDial: !config.Dial, BootstrapNodes: config.parseBootNodes(), StaticNodes: config.parseNodes(staticNodes), TrustedNodes: config.parseNodes(trustedNodes), NodeDatabase: nodeDb, } if len(config.Port) > 0 { eth.net.ListenAddr = ":" + config.Port } vm.Debug = config.VmDebug return eth, nil }
func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) { // this minimalistic recoding is enough (works for natspec.js) var jsontx = fmt.Sprintf(`{"params":[{"to":"%s","data": "%s"}]}`, toStr, codeStr) if !self.ConfirmTransaction(jsontx) { err := fmt.Errorf("Transaction not confirmed") return "", err } var ( from = common.HexToAddress(fromStr) to = common.HexToAddress(toStr) value = common.NewValue(valueStr) gas = common.Big(gasStr) price = common.Big(gasPriceStr) data []byte contractCreation bool ) // TODO if no_private_key then //if _, exists := p.register[args.From]; exists { // p.register[args.From] = append(p.register[args.From], args) //} else { /* account := accounts.Get(common.FromHex(args.From)) if account != nil { if account.Unlocked() { if !unlockAccount(account) { return } } result, _ := account.Transact(common.FromHex(args.To), common.FromHex(args.Value), common.FromHex(args.Gas), common.FromHex(args.GasPrice), common.FromHex(args.Data)) if len(result) > 0 { *reply = common.ToHex(result) } } else if _, exists := p.register[args.From]; exists { p.register[ags.From] = append(p.register[args.From], args) } */ // TODO: align default values to have the same type, e.g. not depend on // common.Value conversions later on if gas.Cmp(big.NewInt(0)) == 0 { gas = DefaultGas() } if price.Cmp(big.NewInt(0)) == 0 { price = DefaultGasPrice() } data = common.FromHex(codeStr) if len(toStr) == 0 { contractCreation = true } var tx *types.Transaction if contractCreation { tx = types.NewContractCreationTx(value.BigInt(), gas, price, data) } else { tx = types.NewTransactionMessage(to, value.BigInt(), gas, price, data) } state := self.backend.ChainManager().TxState() var nonce uint64 if len(nonceStr) != 0 { nonce = common.Big(nonceStr).Uint64() } else { nonce = state.NewNonce(from) } tx.SetNonce(nonce) if err := self.sign(tx, from, false); err != nil { return "", err } if err := self.backend.TxPool().Add(tx); err != nil { return "", err } if contractCreation { addr := core.AddressFromMessage(tx) glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr) return core.AddressFromMessage(tx).Hex(), nil } else { glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To()) } return tx.Hash().Hex(), nil }
func RunVmTest(p string, t *testing.T) { tests := make(map[string]VmTest) helper.CreateFileTests(t, p, &tests) for name, test := range tests { /* vm.Debug = true glog.SetV(4) glog.SetToStderr(true) if name != "stackLimitPush32_1024" { continue } */ db, _ := ethdb.NewMemDatabase() statedb := state.New(common.Hash{}, db) for addr, account := range test.Pre { obj := StateObjectFromAccount(db, addr, account) statedb.SetStateObject(obj) for a, v := range account.Storage { obj.SetState(common.HexToHash(a), common.NewValue(helper.FromHex(v))) } } // XXX Yeah, yeah... env := make(map[string]string) env["currentCoinbase"] = test.Env.CurrentCoinbase env["currentDifficulty"] = test.Env.CurrentDifficulty env["currentGasLimit"] = test.Env.CurrentGasLimit env["currentNumber"] = test.Env.CurrentNumber env["previousHash"] = test.Env.PreviousHash if n, ok := test.Env.CurrentTimestamp.(float64); ok { env["currentTimestamp"] = strconv.Itoa(int(n)) } else { env["currentTimestamp"] = test.Env.CurrentTimestamp.(string) } var ( ret []byte gas *big.Int err error logs state.Logs ) isVmTest := len(test.Exec) > 0 if isVmTest { ret, logs, gas, err = helper.RunVm(statedb, env, test.Exec) } else { ret, logs, gas, err = helper.RunState(statedb, env, test.Transaction) } rexp := helper.FromHex(test.Out) if bytes.Compare(rexp, ret) != 0 { t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) } if isVmTest { if len(test.Gas) == 0 && err == nil { t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name) } else { gexp := common.Big(test.Gas) if gexp.Cmp(gas) != 0 { t.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas) } } } for addr, account := range test.Post { obj := statedb.GetStateObject(common.HexToAddress(addr)) if obj == nil { continue } if len(test.Exec) == 0 { if obj.Balance().Cmp(common.Big(account.Balance)) != 0 { t.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance())) } if obj.Nonce() != common.String2Big(account.Nonce).Uint64() { t.Errorf("%s's : (%x) nonce failed. Expected %v, got %v\n", name, obj.Address().Bytes()[:4], account.Nonce, obj.Nonce()) } } for addr, value := range account.Storage { v := obj.GetState(common.HexToHash(addr)).Bytes() vexp := helper.FromHex(value) if bytes.Compare(v, vexp) != 0 { t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, common.BigD(vexp), common.BigD(v)) } } } if !isVmTest { statedb.Sync() //if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) { if common.HexToHash(test.PostStateRoot) != statedb.Root() { t.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root()) } } if len(test.Logs) > 0 { if len(test.Logs) != len(logs) { t.Errorf("log length mismatch. Expected %d, got %d", len(test.Logs), len(logs)) } else { for i, log := range test.Logs { if common.HexToAddress(log.AddressF) != logs[i].Address { t.Errorf("'%s' log address expected %v got %x", name, log.AddressF, logs[i].Address) } if !bytes.Equal(logs[i].Data, helper.FromHex(log.DataF)) { t.Errorf("'%s' log data expected %v got %x", name, log.DataF, logs[i].Data) } if len(log.TopicsF) != len(logs[i].Topics) { t.Errorf("'%s' log topics length expected %d got %d", name, len(log.TopicsF), logs[i].Topics) } else { for j, topic := range log.TopicsF { if common.HexToHash(topic) != logs[i].Topics[j] { t.Errorf("'%s' log topic[%d] expected %v got %x", name, j, topic, logs[i].Topics[j]) } } } genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256) if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) { t.Errorf("'%s' bloom mismatch", name) } } } } //fmt.Println(string(statedb.Dump())) } logger.Flush() }
func New(config *Config) (*Ethereum, error) { // Bootstrap database logger.New(config.DataDir, config.LogFile, config.Verbosity) if len(config.LogJSON) > 0 { logger.NewJSONsystem(config.DataDir, config.LogJSON) } // Let the database take 3/4 of the max open files (TODO figure out a way to get the actual limit of the open files) const dbCount = 3 ethdb.OpenFileLimit = 128 / (dbCount + 1) newdb := config.NewDB if newdb == nil { newdb = func(path string) (common.Database, error) { return ethdb.NewLDBDatabase(path) } } blockDb, err := newdb(filepath.Join(config.DataDir, "blockchain")) if err != nil { return nil, fmt.Errorf("blockchain db err: %v", err) } if db, ok := blockDb.(*ethdb.LDBDatabase); ok { db.GetTimer = metrics.NewTimer("eth/db/block/user/gets") db.PutTimer = metrics.NewTimer("eth/db/block/user/puts") db.MissMeter = metrics.NewMeter("eth/db/block/user/misses") db.ReadMeter = metrics.NewMeter("eth/db/block/user/reads") db.WriteMeter = metrics.NewMeter("eth/db/block/user/writes") db.CompTimeMeter = metrics.NewMeter("eth/db/block/compact/time") db.CompReadMeter = metrics.NewMeter("eth/db/block/compact/input") db.CompWriteMeter = metrics.NewMeter("eth/db/block/compact/output") } stateDb, err := newdb(filepath.Join(config.DataDir, "state")) if err != nil { return nil, fmt.Errorf("state db err: %v", err) } if db, ok := stateDb.(*ethdb.LDBDatabase); ok { db.GetTimer = metrics.NewTimer("eth/db/state/user/gets") db.PutTimer = metrics.NewTimer("eth/db/state/user/puts") db.MissMeter = metrics.NewMeter("eth/db/state/user/misses") db.ReadMeter = metrics.NewMeter("eth/db/state/user/reads") db.WriteMeter = metrics.NewMeter("eth/db/state/user/writes") db.CompTimeMeter = metrics.NewMeter("eth/db/state/compact/time") db.CompReadMeter = metrics.NewMeter("eth/db/state/compact/input") db.CompWriteMeter = metrics.NewMeter("eth/db/state/compact/output") } extraDb, err := newdb(filepath.Join(config.DataDir, "extra")) if err != nil { return nil, fmt.Errorf("extra db err: %v", err) } if db, ok := extraDb.(*ethdb.LDBDatabase); ok { db.GetTimer = metrics.NewTimer("eth/db/extra/user/gets") db.PutTimer = metrics.NewTimer("eth/db/extra/user/puts") db.MissMeter = metrics.NewMeter("eth/db/extra/user/misses") db.ReadMeter = metrics.NewMeter("eth/db/extra/user/reads") db.WriteMeter = metrics.NewMeter("eth/db/extra/user/writes") db.CompTimeMeter = metrics.NewMeter("eth/db/extra/compact/time") db.CompReadMeter = metrics.NewMeter("eth/db/extra/compact/input") db.CompWriteMeter = metrics.NewMeter("eth/db/extra/compact/output") } nodeDb := filepath.Join(config.DataDir, "nodes") // Perform database sanity checks d, _ := blockDb.Get([]byte("ProtocolVersion")) protov := int(common.NewValue(d).Uint()) if protov != config.ProtocolVersion && protov != 0 { path := filepath.Join(config.DataDir, "blockchain") return nil, fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, config.ProtocolVersion, path) } saveProtocolVersion(blockDb, config.ProtocolVersion) glog.V(logger.Info).Infof("Protocol Version: %v, Network Id: %v", config.ProtocolVersion, config.NetworkId) if !config.SkipBcVersionCheck { b, _ := blockDb.Get([]byte("BlockchainVersion")) bcVersion := int(common.NewValue(b).Uint()) if bcVersion != config.BlockChainVersion && bcVersion != 0 { return nil, fmt.Errorf("Blockchain DB version mismatch (%d / %d). Run geth upgradedb.\n", bcVersion, config.BlockChainVersion) } saveBlockchainVersion(blockDb, config.BlockChainVersion) } glog.V(logger.Info).Infof("Blockchain DB Version: %d", config.BlockChainVersion) eth := &Ethereum{ shutdownChan: make(chan bool), databasesClosed: make(chan bool), blockDb: blockDb, stateDb: stateDb, extraDb: extraDb, eventMux: &event.TypeMux{}, accountManager: config.AccountManager, DataDir: config.DataDir, etherbase: common.HexToAddress(config.Etherbase), clientVersion: config.Name, // TODO should separate from Name ethVersionId: config.ProtocolVersion, netVersionId: config.NetworkId, NatSpec: config.NatSpec, MinerThreads: config.MinerThreads, SolcPath: config.SolcPath, AutoDAG: config.AutoDAG, GpoMinGasPrice: config.GpoMinGasPrice, GpoMaxGasPrice: config.GpoMaxGasPrice, GpoFullBlockRatio: config.GpoFullBlockRatio, GpobaseStepDown: config.GpobaseStepDown, GpobaseStepUp: config.GpobaseStepUp, GpobaseCorrectionFactor: config.GpobaseCorrectionFactor, } eth.pow = ethash.New() genesis := core.GenesisBlock(uint64(config.GenesisNonce), stateDb) eth.chainManager, err = core.NewChainManager(genesis, blockDb, stateDb, eth.pow, eth.EventMux()) if err != nil { return nil, err } eth.txPool = core.NewTxPool(eth.EventMux(), eth.chainManager.State, eth.chainManager.GasLimit) eth.blockProcessor = core.NewBlockProcessor(stateDb, extraDb, eth.pow, eth.chainManager, eth.EventMux()) eth.chainManager.SetProcessor(eth.blockProcessor) eth.protocolManager = NewProtocolManager(config.ProtocolVersion, config.NetworkId, eth.eventMux, eth.txPool, eth.pow, eth.chainManager) eth.miner = miner.New(eth, eth.EventMux(), eth.pow) eth.miner.SetGasPrice(config.GasPrice) if config.Shh { eth.whisper = whisper.New() eth.shhVersionId = int(eth.whisper.Version()) } netprv, err := config.nodeKey() if err != nil { return nil, err } protocols := []p2p.Protocol{eth.protocolManager.SubProtocol} if config.Shh { protocols = append(protocols, eth.whisper.Protocol()) } eth.net = &p2p.Server{ PrivateKey: netprv, Name: config.Name, MaxPeers: config.MaxPeers, MaxPendingPeers: config.MaxPendingPeers, Discovery: config.Discovery, Protocols: protocols, NAT: config.NAT, NoDial: !config.Dial, BootstrapNodes: config.parseBootNodes(), StaticNodes: config.parseNodes(staticNodes), TrustedNodes: config.parseNodes(trustedNodes), NodeDatabase: nodeDb, } if len(config.Port) > 0 { eth.net.ListenAddr = ":" + config.Port } vm.Debug = config.VmDebug return eth, nil }
func New(config *Config) (*Ethereum, error) { logger.New(config.DataDir, config.LogFile, config.Verbosity) // Let the database take 3/4 of the max open files (TODO figure out a way to get the actual limit of the open files) const dbCount = 3 ethdb.OpenFileLimit = 128 / (dbCount + 1) newdb := config.NewDB if newdb == nil { newdb = func(path string) (ethdb.Database, error) { return ethdb.NewLDBDatabase(path, config.DatabaseCache) } } // Open the chain database and perform any upgrades needed chainDb, err := newdb(filepath.Join(config.DataDir, "chaindata")) if err != nil { if errno, ok := err.(syscall.Errno); ok && datadirInUseErrnos[uint(errno)] { err = fmt.Errorf("%v (check if another instance of geth is already running with the same data directory '%s')", err, config.DataDir) } return nil, fmt.Errorf("blockchain db err: %v", err) } if db, ok := chainDb.(*ethdb.LDBDatabase); ok { db.Meter("eth/db/chaindata/") } if err := upgradeChainDatabase(chainDb); err != nil { return nil, err } if err := addMipmapBloomBins(chainDb); err != nil { return nil, err } dappDb, err := newdb(filepath.Join(config.DataDir, "dapp")) if err != nil { if errno, ok := err.(syscall.Errno); ok && datadirInUseErrnos[uint(errno)] { err = fmt.Errorf("%v (check if another instance of geth is already running with the same data directory '%s')", err, config.DataDir) } return nil, fmt.Errorf("dapp db err: %v", err) } if db, ok := dappDb.(*ethdb.LDBDatabase); ok { db.Meter("eth/db/dapp/") } nodeDb := filepath.Join(config.DataDir, "nodes") glog.V(logger.Info).Infof("Protocol Versions: %v, Network Id: %v", ProtocolVersions, config.NetworkId) if len(config.GenesisFile) > 0 { fr, err := os.Open(config.GenesisFile) if err != nil { return nil, err } block, err := core.WriteGenesisBlock(chainDb, fr) if err != nil { return nil, err } glog.V(logger.Info).Infof("Successfully wrote genesis block. New genesis hash = %x\n", block.Hash()) } // different modes switch { case config.Olympic: glog.V(logger.Error).Infoln("Starting Olympic network") fallthrough case config.DevMode: _, err := core.WriteOlympicGenesisBlock(chainDb, 42) if err != nil { return nil, err } case config.TestNet: state.StartingNonce = 1048576 // (2**20) _, err := core.WriteTestNetGenesisBlock(chainDb, 0x6d6f7264656e) if err != nil { return nil, err } } // This is for testing only. if config.GenesisBlock != nil { core.WriteTd(chainDb, config.GenesisBlock.Hash(), config.GenesisBlock.Difficulty()) core.WriteBlock(chainDb, config.GenesisBlock) core.WriteCanonicalHash(chainDb, config.GenesisBlock.Hash(), config.GenesisBlock.NumberU64()) core.WriteHeadBlockHash(chainDb, config.GenesisBlock.Hash()) } if !config.SkipBcVersionCheck { b, _ := chainDb.Get([]byte("BlockchainVersion")) bcVersion := int(common.NewValue(b).Uint()) if bcVersion != config.BlockChainVersion && bcVersion != 0 { return nil, fmt.Errorf("Blockchain DB version mismatch (%d / %d). Run geth upgradedb.\n", bcVersion, config.BlockChainVersion) } saveBlockchainVersion(chainDb, config.BlockChainVersion) } glog.V(logger.Info).Infof("Blockchain DB Version: %d", config.BlockChainVersion) eth := &Ethereum{ shutdownChan: make(chan bool), chainDb: chainDb, dappDb: dappDb, eventMux: &event.TypeMux{}, accountManager: config.AccountManager, DataDir: config.DataDir, etherbase: config.Etherbase, clientVersion: config.Name, // TODO should separate from Name netVersionId: config.NetworkId, NatSpec: config.NatSpec, MinerThreads: config.MinerThreads, SolcPath: config.SolcPath, AutoDAG: config.AutoDAG, PowTest: config.PowTest, GpoMinGasPrice: config.GpoMinGasPrice, GpoMaxGasPrice: config.GpoMaxGasPrice, GpoFullBlockRatio: config.GpoFullBlockRatio, GpobaseStepDown: config.GpobaseStepDown, GpobaseStepUp: config.GpobaseStepUp, GpobaseCorrectionFactor: config.GpobaseCorrectionFactor, httpclient: httpclient.New(config.DocRoot), } if config.PowTest { glog.V(logger.Info).Infof("ethash used in test mode") eth.pow, err = ethash.NewForTesting() if err != nil { return nil, err } } else { eth.pow = ethash.New() } //genesis := core.GenesisBlock(uint64(config.GenesisNonce), stateDb) eth.blockchain, err = core.NewBlockChain(chainDb, eth.pow, eth.EventMux()) if err != nil { if err == core.ErrNoGenesis { return nil, fmt.Errorf(`Genesis block not found. Please supply a genesis block with the "--genesis /path/to/file" argument`) } return nil, err } newPool := core.NewTxPool(eth.EventMux(), eth.blockchain.State, eth.blockchain.GasLimit) eth.txPool = newPool 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) eth.miner.SetGasPrice(config.GasPrice) eth.miner.SetExtra(config.ExtraData) if config.Shh { eth.whisper = whisper.New() eth.shhVersionId = int(eth.whisper.Version()) } netprv, err := config.nodeKey() if err != nil { return nil, err } protocols := append([]p2p.Protocol{}, eth.protocolManager.SubProtocols...) if config.Shh { protocols = append(protocols, eth.whisper.Protocol()) } eth.net = &p2p.Server{ PrivateKey: netprv, Name: config.Name, MaxPeers: config.MaxPeers, MaxPendingPeers: config.MaxPendingPeers, Discovery: config.Discovery, Protocols: protocols, NAT: config.NAT, NoDial: !config.Dial, BootstrapNodes: config.parseBootNodes(), StaticNodes: config.parseNodes(staticNodes), TrustedNodes: config.parseNodes(trustedNodes), NodeDatabase: nodeDb, } if len(config.Port) > 0 { eth.net.ListenAddr = ":" + config.Port } vm.Debug = config.VmDebug return eth, nil }