aboutsummaryrefslogtreecommitdiffstats
path: root/xeth
diff options
context:
space:
mode:
authorFelix Lange <fjl@twurst.com>2015-10-27 04:42:24 +0800
committerFelix Lange <fjl@twurst.com>2015-10-28 01:43:47 +0800
commitae1b5b3ff2611af1232643d38e13a77d704dae28 (patch)
tree2f575d95db4fe0e6f02308a21928f5fe2ed6e268 /xeth
parent77878f76a935061cee82ae9c2a1bc64b192b592b (diff)
downloadgo-tangerine-ae1b5b3ff2611af1232643d38e13a77d704dae28.tar
go-tangerine-ae1b5b3ff2611af1232643d38e13a77d704dae28.tar.gz
go-tangerine-ae1b5b3ff2611af1232643d38e13a77d704dae28.tar.bz2
go-tangerine-ae1b5b3ff2611af1232643d38e13a77d704dae28.tar.lz
go-tangerine-ae1b5b3ff2611af1232643d38e13a77d704dae28.tar.xz
go-tangerine-ae1b5b3ff2611af1232643d38e13a77d704dae28.tar.zst
go-tangerine-ae1b5b3ff2611af1232643d38e13a77d704dae28.zip
eth, xeth: fix GasPriceOracle goroutine leak
XEth.gpo was being initialized as needed. WithState copies the XEth struct including the gpo field. If gpo was nil at the time of the copy and Call or Transact were invoked on it, an additional GPO listenLoop would be spawned. Move the lazy initialization to GasPriceOracle instead so the same GPO instance is shared among all created XEths. Fixes #1317 Might help with #1930
Diffstat (limited to 'xeth')
-rw-r--r--xeth/xeth.go41
1 files changed, 17 insertions, 24 deletions
diff --git a/xeth/xeth.go b/xeth/xeth.go
index 1cb072f0d..f1e8cc5ee 100644
--- a/xeth/xeth.go
+++ b/xeth/xeth.go
@@ -59,24 +59,8 @@ const (
LogFilterTy
)
-func DefaultGas() *big.Int { return new(big.Int).Set(defaultGas) }
-
-func (self *XEth) DefaultGasPrice() *big.Int {
- if self.gpo == nil {
- self.gpo = eth.NewGasPriceOracle(self.backend)
- }
- return self.gpo.SuggestPrice()
-}
-
type XEth struct {
- backend *eth.Ethereum
- frontend Frontend
-
- state *State
- whisper *Whisper
-
- quit chan struct{}
- filterManager *filters.FilterSystem
+ quit chan struct{}
logMu sync.RWMutex
logQueue map[int]*logQueue
@@ -92,16 +76,18 @@ type XEth struct {
transactMu sync.Mutex
- agent *miner.RemoteAgent
-
- gpo *eth.GasPriceOracle
+ // read-only fields
+ backend *eth.Ethereum
+ frontend Frontend
+ agent *miner.RemoteAgent
+ gpo *eth.GasPriceOracle
+ state *State
+ whisper *Whisper
+ filterManager *filters.FilterSystem
}
func NewTest(eth *eth.Ethereum, frontend Frontend) *XEth {
- return &XEth{
- backend: eth,
- frontend: frontend,
- }
+ return &XEth{backend: eth, frontend: frontend}
}
// New creates an XEth that uses the given frontend.
@@ -118,6 +104,7 @@ func New(ethereum *eth.Ethereum, frontend Frontend) *XEth {
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())
@@ -207,6 +194,12 @@ func cTopics(t [][]string) [][]common.Hash {
return topics
}
+func DefaultGas() *big.Int { return new(big.Int).Set(defaultGas) }
+
+func (self *XEth) DefaultGasPrice() *big.Int {
+ return self.gpo.SuggestPrice()
+}
+
func (self *XEth) RemoteMining() *miner.RemoteAgent { return self.agent }
func (self *XEth) AtStateNum(num int64) *XEth {