diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | build/win-ci-compile.bat | 26 | ||||
-rw-r--r-- | build/win-ci-test.bat | 15 | ||||
-rw-r--r-- | cmd/utils/cmd.go | 6 | ||||
-rw-r--r-- | cmd/utils/fdlimit_freebsd.go | 54 | ||||
-rw-r--r-- | cmd/utils/fdlimit_unix.go | 2 | ||||
-rw-r--r-- | core/tx_pool.go | 11 | ||||
-rw-r--r-- | eth/api.go | 4 | ||||
-rw-r--r-- | eth/backend.go | 1 | ||||
-rw-r--r-- | eth/handler.go | 60 | ||||
-rw-r--r-- | eth/helper_test.go | 14 | ||||
-rw-r--r-- | eth/peer.go | 21 | ||||
-rw-r--r-- | eth/sync.go | 2 | ||||
-rw-r--r-- | internal/debug/api.go | 10 | ||||
-rw-r--r-- | internal/debug/flags.go | 4 | ||||
-rw-r--r-- | internal/debug/trace.go | 6 | ||||
-rw-r--r-- | internal/debug/trace_fallback.go | 4 | ||||
-rw-r--r-- | internal/web3ext/web3ext.go | 12 | ||||
-rw-r--r-- | jsre/ethereum_js.go | 7 | ||||
-rw-r--r-- | miner/worker.go | 58 | ||||
-rw-r--r-- | node/api.go | 12 | ||||
-rw-r--r-- | rpc/websocket.go | 8 |
22 files changed, 239 insertions, 104 deletions
@@ -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 } |