func startEth(ctx *cli.Context, eth *eth.Ethereum) { // Start Ethereum itself utils.StartEthereum(eth) am := eth.AccountManager() account := ctx.GlobalString(utils.UnlockedAccountFlag.Name) accounts := strings.Split(account, " ") for i, account := range accounts { if len(account) > 0 { if account == "primary" { utils.Fatalf("the 'primary' keyword is deprecated. You can use integer indexes, but the indexes are not permanent, they can change if you add external keys, export your keys or copy your keystore to another node.") } unlockAccount(ctx, am, account, i) } } // Start auxiliary services if enabled. if !ctx.GlobalBool(utils.IPCDisabledFlag.Name) { if err := utils.StartIPC(eth, ctx); err != nil { utils.Fatalf("Error string IPC: %v", err) } } if ctx.GlobalBool(utils.RPCEnabledFlag.Name) { if err := utils.StartRPC(eth, ctx); err != nil { utils.Fatalf("Error starting RPC: %v", err) } } if ctx.GlobalBool(utils.MiningEnabledFlag.Name) { if err := eth.StartMining(ctx.GlobalInt(utils.MinerThreadsFlag.Name)); err != nil { utils.Fatalf("%v", err) } } }
func startEth(ctx *cli.Context, eth *eth.Ethereum) { // Start Ethereum itself utils.StartEthereum(eth) am := eth.AccountManager() account := ctx.GlobalString(utils.UnlockedAccountFlag.Name) if len(account) > 0 { if account == "primary" { accbytes, err := am.Primary() if err != nil { utils.Fatalf("no primary account: %v", err) } account = common.ToHex(accbytes) } unlockAccount(ctx, am, account) } // Start auxiliary services if enabled. if ctx.GlobalBool(utils.RPCEnabledFlag.Name) { if err := utils.StartRPC(eth, ctx); err != nil { utils.Fatalf("Error starting RPC: %v", err) } } if ctx.GlobalBool(utils.MiningEnabledFlag.Name) { if err := eth.StartMining(); err != nil { utils.Fatalf("%v", err) } } }
// startNode boots up the system node and all registered protocols, after which // it unlocks any requested accounts, and starts the RPC/IPC interfaces and the // miner. func startNode(ctx *cli.Context, stack *node.Node) { // Start up the node itself utils.StartNode(stack) // Unlock any account specifically requested var ethereum *eth.Ethereum if err := stack.Service(ðereum); err != nil { utils.Fatalf("ethereum service not running: %v", err) } accman := ethereum.AccountManager() passwords := utils.MakePasswordList(ctx) accounts := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",") for i, account := range accounts { if trimmed := strings.TrimSpace(account); trimmed != "" { unlockAccount(ctx, accman, trimmed, i, passwords) } } // Start auxiliary services if enabled if ctx.GlobalBool(utils.MiningEnabledFlag.Name) { if err := ethereum.StartMining(ctx.GlobalInt(utils.MinerThreadsFlag.Name), ctx.GlobalString(utils.MiningGPUFlag.Name)); err != nil { utils.Fatalf("Failed to start mining: %v", err) } } }
// New creates an XEth that uses the given frontend. // If a nil Frontend is provided, a default frontend which // confirms all transactions will be used. func New(eth *eth.Ethereum, frontend Frontend) *XEth { xeth := &XEth{ backend: eth, frontend: frontend, quit: make(chan struct{}), filterManager: filter.NewFilterManager(eth.EventMux()), logQueue: make(map[int]*logQueue), blockQueue: make(map[int]*hashQueue), transactionQueue: make(map[int]*hashQueue), messages: make(map[int]*whisperFilter), agent: miner.NewRemoteAgent(), } if eth.Whisper() != nil { xeth.whisper = NewWhisper(eth.Whisper()) } eth.Miner().Register(xeth.agent) if frontend == nil { xeth.frontend = dummyFrontend{} } xeth.state = NewState(xeth, xeth.backend.ChainManager().TransState()) go xeth.start() go xeth.filterManager.Start() return xeth }
func pendingTransactions(repl *testjethre, t *testing.T) (txc int64, err error) { var ethereum *eth.Ethereum repl.stack.Service(ðereum) txs := ethereum.TxPool().GetTransactions() return int64(len(txs)), nil }
func TestBlockChain(t *testing.T) { tmp, repl, node := testJEthRE(t) defer node.Stop() defer os.RemoveAll(tmp) // get current block dump before export/import. val, err := repl.re.Run("JSON.stringify(debug.dumpBlock(eth.blockNumber))") if err != nil { t.Errorf("expected no error, got %v", err) } beforeExport := val.String() // do the export extmp, err := ioutil.TempDir("", "geth-test-export") if err != nil { t.Fatal(err) } defer os.RemoveAll(extmp) tmpfile := filepath.Join(extmp, "export.chain") tmpfileq := strconv.Quote(tmpfile) var ethereum *eth.Ethereum node.Service(ðereum) ethereum.BlockChain().Reset() checkEvalJSON(t, repl, `admin.exportChain(`+tmpfileq+`)`, `true`) if _, err := os.Stat(tmpfile); err != nil { t.Fatal(err) } // check import, verify that dumpBlock gives the same result. checkEvalJSON(t, repl, `admin.importChain(`+tmpfileq+`)`, `true`) checkEvalJSON(t, repl, `debug.dumpBlock(eth.blockNumber)`, beforeExport) }
func testREPL(t *testing.T, config func(*eth.Config)) (string, *testjethre, *node.Node) { tmp, err := ioutil.TempDir("", "geth-test") if err != nil { t.Fatal(err) } // Create a networkless protocol stack stack, err := node.New(&node.Config{DataDir: tmp, PrivateKey: testNodeKey, Name: "test", NoDiscovery: true}) if err != nil { t.Fatalf("failed to create node: %v", err) } // Initialize and register the Ethereum protocol accman := accounts.NewPlaintextManager(filepath.Join(tmp, "keystore")) db, _ := ethdb.NewMemDatabase() core.WriteGenesisBlockForTesting(db, core.GenesisAccount{ Address: common.HexToAddress(testAddress), Balance: common.String2Big(testBalance), }) ethConf := ð.Config{ ChainConfig: &core.ChainConfig{HomesteadBlock: new(big.Int)}, TestGenesisState: db, AccountManager: accman, DocRoot: "/", SolcPath: testSolcPath, PowTest: true, } if config != nil { config(ethConf) } if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { return eth.New(ctx, ethConf) }); err != nil { t.Fatalf("failed to register ethereum protocol: %v", err) } // Initialize all the keys for testing a, err := accman.ImportECDSA(testAccount, "") if err != nil { t.Fatal(err) } if err := accman.Unlock(a, ""); err != nil { t.Fatal(err) } // Start the node and assemble the REPL tester if err := stack.Start(); err != nil { t.Fatalf("failed to start test stack: %v", err) } var ethereum *eth.Ethereum stack.Service(ðereum) assetPath := filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist", "assets", "ext") client, err := stack.Attach() if err != nil { t.Fatalf("failed to attach to node: %v", err) } tf := &testjethre{client: ethereum.HTTPClient()} repl := newJSRE(stack, assetPath, "", client, false) tf.jsre = repl return tmp, tf, stack }
// New creates an XEth that uses the given frontend. // If a nil Frontend is provided, a default frontend which // confirms all transactions will be used. func New(ethereum *eth.Ethereum, frontend Frontend) *XEth { xeth := &XEth{ backend: ethereum, frontend: frontend, quit: make(chan struct{}), filterManager: filters.NewFilterSystem(ethereum.EventMux()), logQueue: make(map[int]*logQueue), blockQueue: make(map[int]*hashQueue), transactionQueue: make(map[int]*hashQueue), messages: make(map[int]*whisperFilter), agent: miner.NewRemoteAgent(), gpo: eth.NewGasPriceOracle(ethereum), } if ethereum.Whisper() != nil { xeth.whisper = NewWhisper(ethereum.Whisper()) } ethereum.Miner().Register(xeth.agent) if frontend == nil { xeth.frontend = dummyFrontend{} } state, _ := xeth.backend.BlockChain().State() xeth.state = NewState(xeth, state) go xeth.start() return xeth }
// InsertPreState populates the given database with the genesis // accounts defined by the test. func (t *BlockTest) InsertPreState(ethereum *eth.Ethereum) (*state.StateDB, error) { db := ethereum.StateDb() statedb := state.New(common.Hash{}, db) for addrString, acct := range t.preAccounts { addr, err := hex.DecodeString(addrString) if err != nil { return nil, err } code, err := hex.DecodeString(strings.TrimPrefix(acct.Code, "0x")) if err != nil { return nil, err } balance, ok := new(big.Int).SetString(acct.Balance, 0) if !ok { return nil, err } nonce, err := strconv.ParseUint(prepInt(16, acct.Nonce), 16, 64) if err != nil { return nil, err } if acct.PrivateKey != "" { privkey, err := hex.DecodeString(strings.TrimPrefix(acct.PrivateKey, "0x")) err = crypto.ImportBlockTestKey(privkey) err = ethereum.AccountManager().TimedUnlock(common.BytesToAddress(addr), "", 999999*time.Second) if err != nil { return nil, err } } obj := statedb.CreateAccount(common.HexToAddress(addrString)) obj.SetCode(code) obj.SetBalance(balance) obj.SetNonce(nonce) for k, v := range acct.Storage { statedb.SetState(common.HexToAddress(addrString), common.HexToHash(k), common.HexToHash(v)) } } // sync objects to trie statedb.SyncObjects() // sync trie to disk statedb.Sync() if !bytes.Equal(t.Genesis.Root().Bytes(), statedb.Root().Bytes()) { return nil, fmt.Errorf("computed state root does not match genesis block %x %x", t.Genesis.Root().Bytes()[:4], statedb.Root().Bytes()[:4]) } return statedb, nil }
// New creates a new Ether APIs instance, connects with it to the Ethereum network // via an embedded Geth instance and attaches an RPC in-process endpoint to it. func New(datadir string, network geth.EthereumNetwork, address common.Address) (*EtherAPIs, error) { // Create a Geth instance and boot it up client, err := geth.New(datadir, network) if err != nil { return nil, err } if err := client.Start(); err != nil { return nil, err } // Retrieve the underlying ethereum service and attach global RPC interface var ethereum *eth.Ethereum if err := client.Stack().Service(ðereum); err != nil { return nil, err } api, err := client.Attach() if err != nil { return nil, err } // Assemble an interface around the consensus contract contract, err := contract.New(ethereum.ChainDb(), ethereum.EventMux(), ethereum.BlockChain(), ethereum.Miner().PendingState) if err != nil { return nil, err } // Assemble and return the Ether APIs instance return &EtherAPIs{ client: client, ethereum: ethereum, eventmux: client.Stack().EventMux(), rpcapi: api, contract: contract, }, nil }
// New creates a new Ether APIs instance, connects with it to the Ethereum network // via an embedded Geth instance and attaches an RPC in-process endpoint to it. func New(datadir string, network geth.EthereumNetwork, address common.Address) (*EtherAPIs, error) { // Create a Geth instance and boot it up client, err := geth.New(datadir, network) if err != nil { return nil, err } if err := client.Start(); err != nil { return nil, err } // Retrieve the underlying ethereum service and attach global RPC interface var ethereum *eth.Ethereum if err := client.Stack().Service(ðereum); err != nil { return nil, err } api, err := client.Attach() if err != nil { return nil, err } // Assemble an interface around the consensus contract rpcClient, err := client.Stack().Attach() if err != nil { return nil, err } contract, err := contract.NewEtherAPIs(address, backends.NewRPCBackend(rpcClient)) if err != nil { return nil, err } // Assemble and return the Ether APIs instance return &EtherAPIs{ client: client, ethereum: ethereum, eventmux: client.Stack().EventMux(), rpcapi: api, contract: contract, signer: func(from common.Address, tx *types.Transaction) (*types.Transaction, error) { signature, err := ethereum.AccountManager().Sign(accounts.Account{Address: from}, tx.SigHash().Bytes()) if err != nil { return nil, err } return tx.WithSignature(signature) }, }, nil }
func (self *jsre) UnlockAccount(addr []byte) bool { fmt.Printf("Please unlock account %x.\n", addr) pass, err := utils.Stdin.PasswordPrompt("Passphrase: ") if err != nil { return false } // TODO: allow retry var ethereum *eth.Ethereum if err := self.stack.Service(ðereum); err != nil { return false } a := accounts.Account{Address: common.BytesToAddress(addr)} if err := ethereum.AccountManager().Unlock(a, pass); err != nil { return false } else { fmt.Println("Account is now unlocked for this session.") return true } }
func processTxs(repl *testjethre, t *testing.T, expTxc int) bool { var txc int64 var err error for i := 0; i < 50; i++ { txc, err = pendingTransactions(repl, t) if err != nil { t.Errorf("unexpected error checking pending transactions: %v", err) return false } if expTxc < int(txc) { t.Errorf("too many pending transactions: expected %v, got %v", expTxc, txc) return false } else if expTxc == int(txc) { break } time.Sleep(100 * time.Millisecond) } if int(txc) != expTxc { t.Errorf("incorrect number of pending transactions, expected %v, got %v", expTxc, txc) return false } var ethereum *eth.Ethereum repl.stack.Service(ðereum) err = ethereum.StartMining(runtime.NumCPU(), "") if err != nil { t.Errorf("unexpected error mining: %v", err) return false } defer ethereum.StopMining() timer := time.NewTimer(100 * time.Second) blockNr := ethereum.BlockChain().CurrentBlock().Number() height := new(big.Int).Add(blockNr, big.NewInt(1)) repl.wait <- height select { case <-timer.C: // if times out make sure the xeth loop does not block go func() { select { case repl.wait <- nil: case <-repl.wait: } }() case <-repl.wait: } txc, err = pendingTransactions(repl, t) if err != nil { t.Errorf("unexpected error checking pending transactions: %v", err) return false } if txc != 0 { t.Errorf("%d trasactions were not mined", txc) return false } return true }
func StartEthereumForTest(ethereum *eth.Ethereum) { glog.V(logger.Info).Infoln("Starting ", ethereum.Name()) ethereum.StartForTest() RegisterInterrupt(func(sig os.Signal) { ethereum.Stop() logger.Flush() }) }
func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath, libPath string) *UiLib { x := xeth.New(eth, nil) lib := &UiLib{ XEth: x, engine: engine, eth: eth, assetPath: assetPath, filterCallbacks: make(map[int][]int), } lib.filterManager = filter.NewFilterManager(eth.EventMux()) go lib.filterManager.Start() return lib }
// RunTest executes the specified test against an already pre-configured protocol // stack to ensure basic checks pass before running RPC tests. func RunTest(stack *node.Node, test *tests.BlockTest) error { var ethereum *eth.Ethereum stack.Service(ðereum) blockchain := ethereum.BlockChain() // Process the blocks and verify the imported headers blocks, err := test.TryBlocksInsert(blockchain) if err != nil { return err } if err := test.ValidateImportedHeaders(blockchain, blocks); err != nil { return err } // Retrieve the assembled state and validate it stateDb, err := blockchain.State() if err != nil { return err } if err := test.ValidatePostState(stateDb); err != nil { return err } return nil }
func startEth(ctx *cli.Context, eth *eth.Ethereum) { // Start Ethereum itself utils.StartEthereum(eth) am := eth.AccountManager() account := ctx.GlobalString(utils.UnlockedAccountFlag.Name) accounts := strings.Split(account, " ") for _, account := range accounts { if len(account) > 0 { if account == "primary" { primaryAcc, err := am.Primary() if err != nil { utils.Fatalf("no primary account: %v", err) } account = primaryAcc.Hex() } unlockAccount(ctx, am, account) } } // Start auxiliary services if enabled. if !ctx.GlobalBool(utils.IPCDisabledFlag.Name) { if err := utils.StartIPC(eth, ctx); err != nil { utils.Fatalf("Error string IPC: %v", err) } } if ctx.GlobalBool(utils.RPCEnabledFlag.Name) { if err := utils.StartRPC(eth, ctx); err != nil { utils.Fatalf("Error starting RPC: %v", err) } } if ctx.GlobalBool(utils.MiningEnabledFlag.Name) { if err := eth.StartMining(ctx.GlobalInt(utils.MinerThreadsFlag.Name)); err != nil { utils.Fatalf("%v", err) } } }
func StartEthereum(ethereum *eth.Ethereum) { glog.V(logger.Info).Infoln("Starting ", ethereum.Name()) if err := ethereum.Start(); err != nil { Fatalf("Error starting Ethereum: %v", err) } RegisterInterrupt(func(sig os.Signal) { ethereum.Stop() logger.Flush() }) }
func StartIPC(eth *eth.Ethereum, ctx *cli.Context) error { config := comms.IpcConfig{ Endpoint: IpcSocketPath(ctx), } initializer := func(conn net.Conn) (comms.Stopper, shared.EthereumApi, error) { fe := useragent.NewRemoteFrontend(conn, eth.AccountManager()) xeth := xeth.New(eth, fe) apis, err := api.ParseApiString(ctx.GlobalString(IPCApiFlag.Name), codec.JSON, xeth, eth) if err != nil { return nil, nil, err } return xeth, api.Merge(apis...), nil } return comms.StartIpc(config, codec.JSON, initializer) }
func StartEthereum(ethereum *eth.Ethereum) { glog.V(logger.Info).Infoln("Starting", ethereum.Name()) if err := ethereum.Start(); err != nil { Fatalf("Error starting Ethereum: %v", err) } go func() { sigc := make(chan os.Signal, 1) signal.Notify(sigc, os.Interrupt) defer signal.Stop(sigc) <-sigc glog.V(logger.Info).Infoln("Got interrupt, shutting down...") go ethereum.Stop() logger.Flush() for i := 10; i > 0; i-- { <-sigc if i > 1 { glog.V(logger.Info).Infoln("Already shutting down, please be patient.") glog.V(logger.Info).Infoln("Interrupt", i-1, "more times to induce panic.") } } glog.V(logger.Error).Infof("Force quitting: this might not end so well.") panic("boom") }() }