aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--build/win-ci-compile.bat26
-rw-r--r--build/win-ci-test.bat15
-rw-r--r--cmd/utils/cmd.go6
-rw-r--r--cmd/utils/fdlimit_freebsd.go54
-rw-r--r--cmd/utils/fdlimit_unix.go2
-rw-r--r--core/tx_pool.go11
-rw-r--r--eth/api.go4
-rw-r--r--eth/backend.go1
-rw-r--r--eth/handler.go60
-rw-r--r--eth/helper_test.go14
-rw-r--r--eth/peer.go21
-rw-r--r--eth/sync.go2
-rw-r--r--internal/debug/api.go10
-rw-r--r--internal/debug/flags.go4
-rw-r--r--internal/debug/trace.go6
-rw-r--r--internal/debug/trace_fallback.go4
-rw-r--r--internal/web3ext/web3ext.go12
-rw-r--r--jsre/ethereum_js.go7
-rw-r--r--miner/worker.go58
-rw-r--r--node/api.go12
-rw-r--r--rpc/websocket.go8
22 files changed, 239 insertions, 104 deletions
diff --git a/Makefile b/Makefile
index 2b553299f..c2fb9bb35 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ GOBIN = build/bin
GO ?= latest
geth:
- build/env.sh go install -v $(shell build/flags.sh) ./cmd/geth
+ build/env.sh go build -i -v $(shell build/flags.sh) -o $(GOBIN)/geth ./cmd/geth
@echo "Done building."
@echo "Run \"$(GOBIN)/geth\" to launch geth."
@@ -103,7 +103,9 @@ evm:
@echo "Run \"$(GOBIN)/evm to start the evm."
all:
- build/env.sh go install -v $(shell build/flags.sh) ./...
+ for cmd in `ls ./cmd/`; do \
+ build/env.sh go build -i -v $(shell build/flags.sh) -o $(GOBIN)/$$cmd ./cmd/$$cmd; \
+ done
test: all
build/env.sh go test ./...
diff --git a/build/win-ci-compile.bat b/build/win-ci-compile.bat
new file mode 100644
index 000000000..5750990bf
--- /dev/null
+++ b/build/win-ci-compile.bat
@@ -0,0 +1,26 @@
+@echo off
+if not exist .\build\win-ci-compile.bat (
+ echo This script must be run from the root of the repository.
+ exit /b
+)
+if not defined GOPATH (
+ echo GOPATH is not set.
+ exit /b
+)
+
+set GOPATH=%GOPATH%;%cd%\Godeps\_workspace
+set GOBIN=%cd%\build\bin
+
+rem set gitCommit when running from a Git checkout.
+set goLinkFlags=""
+if exist ".git\HEAD" (
+ where /q git
+ if not errorlevel 1 (
+ for /f %%h in ('git rev-parse HEAD') do (
+ set goLinkFlags="-X main.gitCommit=%%h"
+ )
+ )
+)
+
+@echo on
+go install -v -ldflags %goLinkFlags% ./...
diff --git a/build/win-ci-test.bat b/build/win-ci-test.bat
new file mode 100644
index 000000000..5945426db
--- /dev/null
+++ b/build/win-ci-test.bat
@@ -0,0 +1,15 @@
+@echo off
+if not exist .\build\win-ci-test.bat (
+ echo This script must be run from the root of the repository.
+ exit /b
+)
+if not defined GOPATH (
+ echo GOPATH is not set.
+ exit /b
+)
+
+set GOPATH=%GOPATH%;%cd%\Godeps\_workspace
+set GOBIN=%cd%\build\bin
+
+@echo on
+go test ./...
diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go
index d331f762f..9e2b14f56 100644
--- a/cmd/utils/cmd.go
+++ b/cmd/utils/cmd.go
@@ -73,15 +73,13 @@ func StartNode(stack *node.Node) {
<-sigc
glog.V(logger.Info).Infoln("Got interrupt, shutting down...")
go stack.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.Info).Infof("Already shutting down, interrupt %d more times for panic.", i-1)
}
}
- glog.V(logger.Error).Infof("Force quitting: this might not end so well.")
+ debug.Exit() // ensure trace and CPU profile data is flushed.
debug.LoudPanic("boom")
}()
}
diff --git a/cmd/utils/fdlimit_freebsd.go b/cmd/utils/fdlimit_freebsd.go
new file mode 100644
index 000000000..4cb5013c8
--- /dev/null
+++ b/cmd/utils/fdlimit_freebsd.go
@@ -0,0 +1,54 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
+// +build freebsd
+
+package utils
+
+import "syscall"
+
+// This file is largely identical to fdlimit_unix.go,
+// but Rlimit fields have type int64 on FreeBSD so it needs
+// an extra conversion.
+
+// raiseFdLimit tries to maximize the file descriptor allowance of this process
+// to the maximum hard-limit allowed by the OS.
+func raiseFdLimit(max uint64) error {
+ // Get the current limit
+ var limit syscall.Rlimit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return err
+ }
+ // Try to update the limit to the max allowance
+ limit.Cur = limit.Max
+ if limit.Cur > int64(max) {
+ limit.Cur = int64(max)
+ }
+ if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return err
+ }
+ return nil
+}
+
+// getFdLimit retrieves the number of file descriptors allowed to be opened by this
+// process.
+func getFdLimit() (int, error) {
+ var limit syscall.Rlimit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ return int(limit.Cur), nil
+}
diff --git a/cmd/utils/fdlimit_unix.go b/cmd/utils/fdlimit_unix.go
index 2a6dffc8f..08e153bbd 100644
--- a/cmd/utils/fdlimit_unix.go
+++ b/cmd/utils/fdlimit_unix.go
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
-// +build linux darwin
+// +build linux darwin netbsd openbsd solaris
package utils
diff --git a/core/tx_pool.go b/core/tx_pool.go
index e997e8cd0..f2eb2bbdd 100644
--- a/core/tx_pool.go
+++ b/core/tx_pool.go
@@ -60,8 +60,7 @@ type stateFn func() (*state.StateDB, error)
// two states over time as they are received and processed.
type TxPool struct {
config *ChainConfig
- quit chan bool // Quitting channel
- currentState stateFn // The state function which will allow us to do some pre checks
+ currentState stateFn // The state function which will allow us to do some pre checks
pendingState *state.ManagedState
gasLimit func() *big.Int // The current gas limit function callback
minGasPrice *big.Int
@@ -72,6 +71,8 @@ type TxPool struct {
pending map[common.Hash]*types.Transaction // processable transactions
queue map[common.Address]map[common.Hash]*types.Transaction
+ wg sync.WaitGroup // for shutdown sync
+
homestead bool
}
@@ -80,7 +81,6 @@ func NewTxPool(config *ChainConfig, eventMux *event.TypeMux, currentStateFn stat
config: config,
pending: make(map[common.Hash]*types.Transaction),
queue: make(map[common.Address]map[common.Hash]*types.Transaction),
- quit: make(chan bool),
eventMux: eventMux,
currentState: currentStateFn,
gasLimit: gasLimitFn,
@@ -90,12 +90,15 @@ func NewTxPool(config *ChainConfig, eventMux *event.TypeMux, currentStateFn stat
events: eventMux.Subscribe(ChainHeadEvent{}, GasPriceChanged{}, RemovedTransactionEvent{}),
}
+ pool.wg.Add(1)
go pool.eventLoop()
return pool
}
func (pool *TxPool) eventLoop() {
+ defer pool.wg.Done()
+
// Track chain events. When a chain events occurs (new chain canon block)
// we need to know the new state. The new state will help us determine
// the nonces in the managed state
@@ -155,8 +158,8 @@ func (pool *TxPool) resetState() {
}
func (pool *TxPool) Stop() {
- close(pool.quit)
pool.events.Unsubscribe()
+ pool.wg.Wait()
glog.V(logger.Info).Infoln("Transaction pool stopped")
}
diff --git a/eth/api.go b/eth/api.go
index bd8179962..1d66f53fe 100644
--- a/eth/api.go
+++ b/eth/api.go
@@ -1841,7 +1841,7 @@ func (s *PrivateDebugAPI) TraceTransaction(txHash common.Hash, logger *vm.LogCon
}
// Mutate the state if we haven't reached the tracing transaction yet
if uint64(idx) < txIndex {
- vmenv := core.NewEnv(stateDb, s.config, s.eth.BlockChain(), msg, parent.Header(), vm.Config{})
+ vmenv := core.NewEnv(stateDb, s.config, s.eth.BlockChain(), msg, block.Header(), vm.Config{})
_, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas()))
if err != nil {
return nil, fmt.Errorf("mutation failed: %v", err)
@@ -1849,7 +1849,7 @@ func (s *PrivateDebugAPI) TraceTransaction(txHash common.Hash, logger *vm.LogCon
continue
}
// Otherwise trace the transaction and return
- vmenv := core.NewEnv(stateDb, s.config, s.eth.BlockChain(), msg, parent.Header(), vm.Config{Debug: true, Logger: *logger})
+ vmenv := core.NewEnv(stateDb, s.config, s.eth.BlockChain(), msg, block.Header(), vm.Config{Debug: true, Logger: *logger})
ret, gas, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas()))
if err != nil {
return nil, fmt.Errorf("tracing failed: %v", err)
diff --git a/eth/backend.go b/eth/backend.go
index 9722e9625..f43dea777 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -416,6 +416,7 @@ func (s *Ethereum) Stop() error {
s.blockchain.Stop()
s.protocolManager.Stop()
s.txPool.Stop()
+ s.miner.Stop()
s.eventMux.Stop()
s.StopAutoDAG()
diff --git a/eth/handler.go b/eth/handler.go
index d6b474a91..3980a625e 100644
--- a/eth/handler.go
+++ b/eth/handler.go
@@ -74,14 +74,14 @@ type ProtocolManager struct {
minedBlockSub event.Subscription
// channels for fetcher, syncer, txsyncLoop
- newPeerCh chan *peer
- txsyncCh chan *txsync
- quitSync chan struct{}
+ newPeerCh chan *peer
+ txsyncCh chan *txsync
+ quitSync chan struct{}
+ noMorePeers chan struct{}
// wait group is used for graceful shutdowns during downloading
// and processing
- wg sync.WaitGroup
- quit bool
+ wg sync.WaitGroup
}
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
@@ -94,16 +94,17 @@ func NewProtocolManager(config *core.ChainConfig, fastSync bool, networkId int,
}
// Create the protocol manager with the base fields
manager := &ProtocolManager{
- networkId: networkId,
- fastSync: fastSync,
- eventMux: mux,
- txpool: txpool,
- blockchain: blockchain,
- chaindb: chaindb,
- peers: newPeerSet(),
- newPeerCh: make(chan *peer, 1),
- txsyncCh: make(chan *txsync),
- quitSync: make(chan struct{}),
+ networkId: networkId,
+ fastSync: fastSync,
+ eventMux: mux,
+ txpool: txpool,
+ blockchain: blockchain,
+ chaindb: chaindb,
+ peers: newPeerSet(),
+ newPeerCh: make(chan *peer),
+ noMorePeers: make(chan struct{}),
+ txsyncCh: make(chan *txsync),
+ quitSync: make(chan struct{}),
}
// Initiate a sub-protocol for every implemented version we can handle
manager.SubProtocols = make([]p2p.Protocol, 0, len(ProtocolVersions))
@@ -120,8 +121,14 @@ func NewProtocolManager(config *core.ChainConfig, fastSync bool, networkId int,
Length: ProtocolLengths[i],
Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
peer := manager.newPeer(int(version), p, rw)
- manager.newPeerCh <- peer
- return manager.handle(peer)
+ select {
+ case manager.newPeerCh <- peer:
+ manager.wg.Add(1)
+ defer manager.wg.Done()
+ return manager.handle(peer)
+ case <-manager.quitSync:
+ return p2p.DiscQuitting
+ }
},
NodeInfo: func() interface{} {
return manager.NodeInfo()
@@ -187,16 +194,25 @@ func (pm *ProtocolManager) Start() {
}
func (pm *ProtocolManager) Stop() {
- // Showing a log message. During download / process this could actually
- // take between 5 to 10 seconds and therefor feedback is required.
glog.V(logger.Info).Infoln("Stopping ethereum protocol handler...")
- pm.quit = true
pm.txSub.Unsubscribe() // quits txBroadcastLoop
pm.minedBlockSub.Unsubscribe() // quits blockBroadcastLoop
- close(pm.quitSync) // quits syncer, fetcher, txsyncLoop
- // Wait for any process action
+ // Quit the sync loop.
+ // After this send has completed, no new peers will be accepted.
+ pm.noMorePeers <- struct{}{}
+
+ // Quit fetcher, txsyncLoop.
+ close(pm.quitSync)
+
+ // Disconnect existing sessions.
+ // This also closes the gate for any new registrations on the peer set.
+ // sessions which are already established but not added to pm.peers yet
+ // will exit when they try to register.
+ pm.peers.Close()
+
+ // Wait for all peer handler goroutines and the loops to come down.
pm.wg.Wait()
glog.V(logger.Info).Infoln("Ethereum protocol handler stopped")
diff --git a/eth/helper_test.go b/eth/helper_test.go
index 5703d44cc..dacb1593f 100644
--- a/eth/helper_test.go
+++ b/eth/helper_test.go
@@ -140,14 +140,14 @@ func newTestPeer(name string, version int, pm *ProtocolManager, shake bool) (*te
// Start the peer on a new thread
errc := make(chan error, 1)
go func() {
- pm.newPeerCh <- peer
- errc <- pm.handle(peer)
+ select {
+ case pm.newPeerCh <- peer:
+ errc <- pm.handle(peer)
+ case <-pm.quitSync:
+ errc <- p2p.DiscQuitting
+ }
}()
- tp := &testPeer{
- app: app,
- net: net,
- peer: peer,
- }
+ tp := &testPeer{app: app, net: net, peer: peer}
// Execute any implicitly requested handshakes and return
if shake {
td, head, genesis := pm.blockchain.Status()
diff --git a/eth/peer.go b/eth/peer.go
index 15ba22ff5..8eb41b0f9 100644
--- a/eth/peer.go
+++ b/eth/peer.go
@@ -34,6 +34,7 @@ import (
)
var (
+ errClosed = errors.New("peer set is closed")
errAlreadyRegistered = errors.New("peer is already registered")
errNotRegistered = errors.New("peer is not registered")
)
@@ -351,8 +352,9 @@ func (p *peer) String() string {
// peerSet represents the collection of active peers currently participating in
// the Ethereum sub-protocol.
type peerSet struct {
- peers map[string]*peer
- lock sync.RWMutex
+ peers map[string]*peer
+ lock sync.RWMutex
+ closed bool
}
// newPeerSet creates a new peer set to track the active participants.
@@ -368,6 +370,9 @@ func (ps *peerSet) Register(p *peer) error {
ps.lock.Lock()
defer ps.lock.Unlock()
+ if ps.closed {
+ return errClosed
+ }
if _, ok := ps.peers[p.id]; ok {
return errAlreadyRegistered
}
@@ -450,3 +455,15 @@ func (ps *peerSet) BestPeer() *peer {
}
return bestPeer
}
+
+// Close disconnects all peers.
+// No new peers can be registered after Close has returned.
+func (ps *peerSet) Close() {
+ ps.lock.Lock()
+ defer ps.lock.Unlock()
+
+ for _, p := range ps.peers {
+ p.Disconnect(p2p.DiscQuitting)
+ }
+ ps.closed = true
+}
diff --git a/eth/sync.go b/eth/sync.go
index dd8aef8e4..69881530d 100644
--- a/eth/sync.go
+++ b/eth/sync.go
@@ -148,7 +148,7 @@ func (pm *ProtocolManager) syncer() {
// Force a sync even if not enough peers are present
go pm.synchronise(pm.peers.BestPeer())
- case <-pm.quitSync:
+ case <-pm.noMorePeers:
return
}
}
diff --git a/internal/debug/api.go b/internal/debug/api.go
index 2cb264040..96091541b 100644
--- a/internal/debug/api.go
+++ b/internal/debug/api.go
@@ -51,7 +51,7 @@ type HandlerT struct {
traceFile string
}
-// Verbosity sets the glog verbosity floor.
+// Verbosity sets the glog verbosity ceiling.
// The verbosity of individual packages and source files
// can be raised using Vmodule.
func (*HandlerT) Verbosity(level int) {
@@ -131,14 +131,14 @@ func (h *HandlerT) StopCPUProfile() error {
return nil
}
-// Trace turns on tracing for nsec seconds and writes
+// GoTrace turns on tracing for nsec seconds and writes
// trace data to file.
-func (h *HandlerT) Trace(file string, nsec uint) error {
- if err := h.StartTrace(file); err != nil {
+func (h *HandlerT) GoTrace(file string, nsec uint) error {
+ if err := h.StartGoTrace(file); err != nil {
return err
}
time.Sleep(time.Duration(nsec) * time.Second)
- h.StopTrace()
+ h.StopGoTrace()
return nil
}
diff --git a/internal/debug/flags.go b/internal/debug/flags.go
index 76f32561a..5b1a9b23c 100644
--- a/internal/debug/flags.go
+++ b/internal/debug/flags.go
@@ -89,7 +89,7 @@ func Setup(ctx *cli.Context) error {
runtime.MemProfileRate = ctx.GlobalInt(memprofilerateFlag.Name)
Handler.SetBlockProfileRate(ctx.GlobalInt(blockprofilerateFlag.Name))
if traceFile := ctx.GlobalString(traceFlag.Name); traceFile != "" {
- if err := Handler.StartTrace(traceFile); err != nil {
+ if err := Handler.StartGoTrace(traceFile); err != nil {
return err
}
}
@@ -114,5 +114,5 @@ func Setup(ctx *cli.Context) error {
// respective file.
func Exit() {
Handler.StopCPUProfile()
- Handler.StopTrace()
+ Handler.StopGoTrace()
}
diff --git a/internal/debug/trace.go b/internal/debug/trace.go
index 45637977a..c0cf921ff 100644
--- a/internal/debug/trace.go
+++ b/internal/debug/trace.go
@@ -27,8 +27,8 @@ import (
"github.com/ethereum/go-ethereum/logger/glog"
)
-// StartTrace turns on tracing, writing to the given file.
-func (h *HandlerT) StartTrace(file string) error {
+// StartGoTrace turns on tracing, writing to the given file.
+func (h *HandlerT) StartGoTrace(file string) error {
h.mu.Lock()
defer h.mu.Unlock()
if h.traceW != nil {
@@ -49,7 +49,7 @@ func (h *HandlerT) StartTrace(file string) error {
}
// StopTrace stops an ongoing trace.
-func (h *HandlerT) StopTrace() error {
+func (h *HandlerT) StopGoTrace() error {
h.mu.Lock()
defer h.mu.Unlock()
trace.Stop()
diff --git a/internal/debug/trace_fallback.go b/internal/debug/trace_fallback.go
index 319945925..4118ff408 100644
--- a/internal/debug/trace_fallback.go
+++ b/internal/debug/trace_fallback.go
@@ -22,10 +22,10 @@ package debug
import "errors"
-func (*HandlerT) StartTrace(string) error {
+func (*HandlerT) StartGoTrace(string) error {
return errors.New("tracing is not supported on Go < 1.5")
}
-func (*HandlerT) StopTrace() error {
+func (*HandlerT) StopGoTrace() error {
return errors.New("tracing is not supported on Go < 1.5")
}
diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go
index 14700b05c..64c1b5044 100644
--- a/internal/web3ext/web3ext.go
+++ b/internal/web3ext/web3ext.go
@@ -366,18 +366,18 @@ web3._extend({
params: 0
}),
new web3._extend.Method({
- name: 'trace',
- call: 'debug_trace',
+ name: 'goTrace',
+ call: 'debug_goTrace',
params: 2
}),
new web3._extend.Method({
- name: 'startTrace',
- call: 'debug_startTrace',
+ name: 'startGoTrace',
+ call: 'debug_startGoTrace',
params: 1
}),
new web3._extend.Method({
- name: 'stopTrace',
- call: 'debug_stopTrace',
+ name: 'stopGoTrace',
+ call: 'debug_stopGoTrace',
params: 0
}),
new web3._extend.Method({
diff --git a/jsre/ethereum_js.go b/jsre/ethereum_js.go
index dfdedeb11..79ce1d2e2 100644
--- a/jsre/ethereum_js.go
+++ b/jsre/ethereum_js.go
@@ -3911,7 +3911,12 @@ var outputSyncingFormatter = function(result) {
result.startingBlock = utils.toDecimal(result.startingBlock);
result.currentBlock = utils.toDecimal(result.currentBlock);
result.highestBlock = utils.toDecimal(result.highestBlock);
-
+ if (result.knownStates !== undefined) {
+ result.knownStates = utils.toDecimal(result.knownStates);
+ }
+ if (result.pulledStates !== undefined) {
+ result.pulledStates = utils.toDecimal(result.pulledStates);
+ }
return result;
};
diff --git a/miner/worker.go b/miner/worker.go
index 21588e310..fe759560c 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -94,10 +94,13 @@ type worker struct {
mu sync.Mutex
+ // update loop
+ mux *event.TypeMux
+ events event.Subscription
+ wg sync.WaitGroup
+
agents map[Agent]struct{}
recv chan *Result
- mux *event.TypeMux
- quit chan struct{}
pow pow.PoW
eth core.Backend
@@ -138,13 +141,13 @@ func newWorker(config *core.ChainConfig, coinbase common.Address, eth core.Backe
possibleUncles: make(map[common.Hash]*types.Block),
coinbase: coinbase,
txQueue: make(map[common.Hash]*types.Transaction),
- quit: make(chan struct{}),
agents: make(map[Agent]struct{}),
fullValidation: false,
}
+ worker.events = worker.mux.Subscribe(core.ChainHeadEvent{}, core.ChainSideEvent{}, core.TxPreEvent{})
go worker.update()
- go worker.wait()
+ go worker.wait()
worker.commitNewWork()
return worker
@@ -184,9 +187,10 @@ func (self *worker) start() {
}
func (self *worker) stop() {
+ self.wg.Wait()
+
self.mu.Lock()
defer self.mu.Unlock()
-
if atomic.LoadInt32(&self.mining) == 1 {
// Stop all agents.
for agent := range self.agents {
@@ -217,36 +221,22 @@ func (self *worker) unregister(agent Agent) {
}
func (self *worker) update() {
- eventSub := self.mux.Subscribe(core.ChainHeadEvent{}, core.ChainSideEvent{}, core.TxPreEvent{})
- defer eventSub.Unsubscribe()
-
- eventCh := eventSub.Chan()
- for {
- select {
- case event, ok := <-eventCh:
- if !ok {
- // Event subscription closed, set the channel to nil to stop spinning
- eventCh = nil
- continue
- }
- // A real event arrived, process interesting content
- switch ev := event.Data.(type) {
- case core.ChainHeadEvent:
- self.commitNewWork()
- case core.ChainSideEvent:
- self.uncleMu.Lock()
- self.possibleUncles[ev.Block.Hash()] = ev.Block
- self.uncleMu.Unlock()
- case core.TxPreEvent:
- // Apply transaction to the pending state if we're not mining
- if atomic.LoadInt32(&self.mining) == 0 {
- self.currentMu.Lock()
- self.current.commitTransactions(self.mux, types.Transactions{ev.Tx}, self.gasPrice, self.chain)
- self.currentMu.Unlock()
- }
+ for event := range self.events.Chan() {
+ // A real event arrived, process interesting content
+ switch ev := event.Data.(type) {
+ case core.ChainHeadEvent:
+ self.commitNewWork()
+ case core.ChainSideEvent:
+ self.uncleMu.Lock()
+ self.possibleUncles[ev.Block.Hash()] = ev.Block
+ self.uncleMu.Unlock()
+ case core.TxPreEvent:
+ // Apply transaction to the pending state if we're not mining
+ if atomic.LoadInt32(&self.mining) == 0 {
+ self.currentMu.Lock()
+ self.current.commitTransactions(self.mux, types.Transactions{ev.Tx}, self.gasPrice, self.chain)
+ self.currentMu.Unlock()
}
- case <-self.quit:
- return
}
}
}
diff --git a/node/api.go b/node/api.go
index f199a8d3d..9b2be9c2e 100644
--- a/node/api.go
+++ b/node/api.go
@@ -68,7 +68,11 @@ func (api *PrivateAdminAPI) StartRPC(host *string, port *rpc.HexNumber, cors *st
}
if host == nil {
- host = &api.node.httpHost
+ h := common.DefaultHTTPHost
+ if api.node.httpHost != "" {
+ h = api.node.httpHost
+ }
+ host = &h
}
if port == nil {
port = rpc.NewHexNumber(api.node.httpPort)
@@ -113,7 +117,11 @@ func (api *PrivateAdminAPI) StartWS(host *string, port *rpc.HexNumber, allowedOr
}
if host == nil {
- host = &api.node.wsHost
+ h := common.DefaultWSHost
+ if api.node.wsHost != "" {
+ h = api.node.wsHost
+ }
+ host = &h
}
if port == nil {
port = rpc.NewHexNumber(api.node.wsPort)
diff --git a/rpc/websocket.go b/rpc/websocket.go
index 1303f98db..fe9354d94 100644
--- a/rpc/websocket.go
+++ b/rpc/websocket.go
@@ -61,22 +61,22 @@ func wsHandshakeValidator(allowedOrigins []string) func(*websocket.Config, *http
allowAllOrigins = true
}
if origin != "" {
- origins.Add(origin)
+ origins.Add(strings.ToLower(origin))
}
}
- // allow localhost if no allowedOrigins are specified
+ // allow localhost if no allowedOrigins are specified.
if len(origins.List()) == 0 {
origins.Add("http://localhost")
if hostname, err := os.Hostname(); err == nil {
- origins.Add("http://" + hostname)
+ origins.Add("http://" + strings.ToLower(hostname))
}
}
glog.V(logger.Debug).Infof("Allowed origin(s) for WS RPC interface %v\n", origins.List())
f := func(cfg *websocket.Config, req *http.Request) error {
- origin := req.Header.Get("Origin")
+ origin := strings.ToLower(req.Header.Get("Origin"))
if allowAllOrigins || origins.Has(origin) {
return nil
}