diff options
Diffstat (limited to 'les')
-rw-r--r-- | les/api_backend.go | 4 | ||||
-rw-r--r-- | les/handler.go | 3 | ||||
-rw-r--r-- | les/helper_test.go | 8 | ||||
-rw-r--r-- | les/server.go | 30 | ||||
-rw-r--r-- | les/serverpool.go | 92 |
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) |