aboutsummaryrefslogtreecommitdiffstats
path: root/les
diff options
context:
space:
mode:
Diffstat (limited to 'les')
-rw-r--r--les/api_backend.go4
-rw-r--r--les/handler.go3
-rw-r--r--les/helper_test.go8
-rw-r--r--les/server.go30
-rw-r--r--les/serverpool.go92
5 files changed, 64 insertions, 73 deletions
diff --git a/les/api_backend.go b/les/api_backend.go
index 3a71ac4e0..ed2a7cd13 100644
--- a/les/api_backend.go
+++ b/les/api_backend.go
@@ -88,7 +88,7 @@ func (b *LesApiBackend) GetTd(blockHash common.Hash) *big.Int {
return b.eth.blockchain.GetTdByHash(blockHash)
}
-func (b *LesApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header) (*vm.EVM, func() error, error) {
+func (b *LesApiBackend) GetEVM(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) {
stateDb := state.(*light.LightState).Copy()
addr := msg.From()
from, err := stateDb.GetOrNewStateObject(ctx, addr)
@@ -99,7 +99,7 @@ func (b *LesApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state et
vmstate := light.NewVMState(ctx, stateDb)
context := core.NewEVMContext(msg, header, b.eth.blockchain)
- return vm.NewEVM(context, vmstate, b.eth.chainConfig, vm.Config{}), vmstate.Error, nil
+ return vm.NewEVM(context, vmstate, b.eth.chainConfig, vmCfg), vmstate.Error, nil
}
func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
diff --git a/les/handler.go b/les/handler.go
index 603ce9ad4..42a45845d 100644
--- a/les/handler.go
+++ b/les/handler.go
@@ -160,9 +160,6 @@ func NewProtocolManager(chainConfig *params.ChainConfig, lightSync bool, network
if manager.serverPool != nil {
addr := p.RemoteAddr().(*net.TCPAddr)
entry = manager.serverPool.connect(peer, addr.IP, uint16(addr.Port))
- if entry == nil {
- return fmt.Errorf("unwanted connection")
- }
}
peer.poolEntry = entry
select {
diff --git a/les/helper_test.go b/les/helper_test.go
index e0b7558ee..2c6f34a92 100644
--- a/les/helper_test.go
+++ b/les/helper_test.go
@@ -57,6 +57,8 @@ var (
testContractDeployed = uint64(2)
testBufLimit = uint64(100)
+
+ bigTxGas = new(big.Int).SetUint64(params.TxGas)
)
/*
@@ -80,15 +82,15 @@ func testChainGen(i int, block *core.BlockGen) {
switch i {
case 0:
// In block 1, the test bank sends account #1 some ether.
- tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, testBankKey)
+ tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), signer, testBankKey)
block.AddTx(tx)
case 1:
// In block 2, the test bank sends some more ether to account #1.
// acc1Addr passes it on to account #2.
// acc1Addr creates a test contract.
- tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, testBankKey)
+ tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, testBankKey)
nonce := block.TxNonce(acc1Addr)
- tx2, _ := types.SignTx(types.NewTransaction(nonce, acc2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, acc1Key)
+ tx2, _ := types.SignTx(types.NewTransaction(nonce, acc2Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, acc1Key)
nonce++
tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), big.NewInt(200000), big.NewInt(0), testContractCode), signer, acc1Key)
testContractAddr = crypto.CreateAddress(acc1Addr, nonce)
diff --git a/les/server.go b/les/server.go
index e55616a44..c4c6fcab5 100644
--- a/les/server.go
+++ b/les/server.go
@@ -42,9 +42,7 @@ type LesServer struct {
fcManager *flowcontrol.ClientManager // nil if our node is client only
fcCostStats *requestCostStats
defParams *flowcontrol.ServerParams
- srvr *p2p.Server
- synced, stopped bool
- lock sync.Mutex
+ stopped bool
}
func NewLesServer(eth *eth.Ethereum, config *eth.Config) (*LesServer, error) {
@@ -70,35 +68,13 @@ func (s *LesServer) Protocols() []p2p.Protocol {
return s.protocolManager.SubProtocols
}
-// Start only starts the actual service if the ETH protocol has already been synced,
-// otherwise it will be started by Synced()
+// Start starts the LES server
func (s *LesServer) Start(srvr *p2p.Server) {
- s.lock.Lock()
- defer s.lock.Unlock()
-
- s.srvr = srvr
- if s.synced {
- s.protocolManager.Start(s.srvr)
- }
-}
-
-// Synced notifies the server that the ETH protocol has been synced and LES service can be started
-func (s *LesServer) Synced() {
- s.lock.Lock()
- defer s.lock.Unlock()
-
- s.synced = true
- if s.srvr != nil && !s.stopped {
- s.protocolManager.Start(s.srvr)
- }
+ s.protocolManager.Start(srvr)
}
// Stop stops the LES service
func (s *LesServer) Stop() {
- s.lock.Lock()
- defer s.lock.Unlock()
-
- s.stopped = true
s.fcCostStats.store()
s.fcManager.Stop()
go func() {
diff --git a/les/serverpool.go b/les/serverpool.go
index e3b7cf620..9735a718e 100644
--- a/les/serverpool.go
+++ b/les/serverpool.go
@@ -160,10 +160,10 @@ func (pool *serverPool) connect(p *peer, ip net.IP, port uint16) *poolEntry {
defer pool.lock.Unlock()
entry := pool.entries[p.ID()]
if entry == nil {
- return nil
+ entry = pool.findOrNewNode(p.ID(), ip, port)
}
glog.V(logger.Debug).Infof("connecting to %v, state: %v", p.id, entry.state)
- if entry.state != psDialed {
+ if entry.state == psConnected || entry.state == psRegistered {
return nil
}
pool.connWg.Add(1)
@@ -250,11 +250,17 @@ type poolStatAdjust struct {
// adjustBlockDelay adjusts the block announce delay statistics of a node
func (pool *serverPool) adjustBlockDelay(entry *poolEntry, time time.Duration) {
+ if entry == nil {
+ return
+ }
pool.adjustStats <- poolStatAdjust{pseBlockDelay, entry, time}
}
// adjustResponseTime adjusts the request response time statistics of a node
func (pool *serverPool) adjustResponseTime(entry *poolEntry, time time.Duration, timeout bool) {
+ if entry == nil {
+ return
+ }
if timeout {
pool.adjustStats <- poolStatAdjust{pseResponseTimeout, entry, time}
} else {
@@ -342,7 +348,9 @@ func (pool *serverPool) selectPeerWait(reqID uint64, canSend func(*peer) (bool,
func (pool *serverPool) eventLoop() {
lookupCnt := 0
var convTime mclock.AbsTime
- pool.discSetPeriod <- time.Millisecond * 100
+ if pool.discSetPeriod != nil {
+ pool.discSetPeriod <- time.Millisecond * 100
+ }
for {
select {
case entry := <-pool.timeout:
@@ -375,39 +383,7 @@ func (pool *serverPool) eventLoop() {
case node := <-pool.discNodes:
pool.lock.Lock()
- now := mclock.Now()
- id := discover.NodeID(node.ID)
- entry := pool.entries[id]
- if entry == nil {
- glog.V(logger.Debug).Infof("discovered %v", node.String())
- entry = &poolEntry{
- id: id,
- addr: make(map[string]*poolEntryAddress),
- addrSelect: *newWeightedRandomSelect(),
- shortRetry: shortRetryCnt,
- }
- pool.entries[id] = entry
- // initialize previously unknown peers with good statistics to give a chance to prove themselves
- entry.connectStats.add(1, initStatsWeight)
- entry.delayStats.add(0, initStatsWeight)
- entry.responseStats.add(0, initStatsWeight)
- entry.timeoutStats.add(0, initStatsWeight)
- }
- entry.lastDiscovered = now
- addr := &poolEntryAddress{
- ip: node.IP,
- port: node.TCP,
- }
- if a, ok := entry.addr[addr.strKey()]; ok {
- addr = a
- } else {
- entry.addr[addr.strKey()] = addr
- }
- addr.lastSeen = now
- entry.addrSelect.update(addr)
- if !entry.known {
- pool.newQueue.setLatest(entry)
- }
+ entry := pool.findOrNewNode(discover.NodeID(node.ID), node.IP, node.TCP)
pool.updateCheckDial(entry)
pool.lock.Unlock()
@@ -419,12 +395,16 @@ func (pool *serverPool) eventLoop() {
lookupCnt++
if pool.fastDiscover && (lookupCnt == 50 || time.Duration(mclock.Now()-convTime) > time.Minute) {
pool.fastDiscover = false
- pool.discSetPeriod <- time.Minute
+ if pool.discSetPeriod != nil {
+ pool.discSetPeriod <- time.Minute
+ }
}
}
case <-pool.quit:
- close(pool.discSetPeriod)
+ if pool.discSetPeriod != nil {
+ close(pool.discSetPeriod)
+ }
pool.connWg.Wait()
pool.saveNodes()
pool.wg.Done()
@@ -434,6 +414,42 @@ func (pool *serverPool) eventLoop() {
}
}
+func (pool *serverPool) findOrNewNode(id discover.NodeID, ip net.IP, port uint16) *poolEntry {
+ now := mclock.Now()
+ entry := pool.entries[id]
+ if entry == nil {
+ glog.V(logger.Debug).Infof("discovered %v", id.String())
+ entry = &poolEntry{
+ id: id,
+ addr: make(map[string]*poolEntryAddress),
+ addrSelect: *newWeightedRandomSelect(),
+ shortRetry: shortRetryCnt,
+ }
+ pool.entries[id] = entry
+ // initialize previously unknown peers with good statistics to give a chance to prove themselves
+ entry.connectStats.add(1, initStatsWeight)
+ entry.delayStats.add(0, initStatsWeight)
+ entry.responseStats.add(0, initStatsWeight)
+ entry.timeoutStats.add(0, initStatsWeight)
+ }
+ entry.lastDiscovered = now
+ addr := &poolEntryAddress{
+ ip: ip,
+ port: port,
+ }
+ if a, ok := entry.addr[addr.strKey()]; ok {
+ addr = a
+ } else {
+ entry.addr[addr.strKey()] = addr
+ }
+ addr.lastSeen = now
+ entry.addrSelect.update(addr)
+ if !entry.known {
+ pool.newQueue.setLatest(entry)
+ }
+ return entry
+}
+
// loadNodes loads known nodes and their statistics from the database
func (pool *serverPool) loadNodes() {
enc, err := pool.db.Get(pool.dbKey)