Skip to content

Commit d89ea3e

Browse files
authored
Merge pull request #3253 from zsfelfoldi/light-topic3
Light client bugfixes and updates
2 parents ca73dea + b10bcd9 commit d89ea3e

File tree

13 files changed

+148
-100
lines changed

13 files changed

+148
-100
lines changed

common/registrar/ethreg/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ func (be *registryAPIBackend) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr
187187
if gasPrice.BitLen() == 0 {
188188
gasPrice = new(big.Int).Mul(big.NewInt(50), common.Shannon)
189189
}
190-
msg := types.NewMessage(from.Address(), to, 0, common.Big(valueStr), gas, gasPrice, common.FromHex(dataStr))
190+
msg := types.NewMessage(from.Address(), to, 0, common.Big(valueStr), gas, gasPrice, common.FromHex(dataStr), false)
191191

192192
header := be.bc.CurrentBlock().Header()
193193
vmenv := core.NewEnv(statedb, be.config, be.bc, msg, header, vm.Config{})

core/types/transaction.go

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -321,12 +321,13 @@ func (tx *Transaction) SignatureValues() (v byte, r *big.Int, s *big.Int, err er
321321
// XXX Rename message to something less arbitrary?
322322
func (tx *Transaction) AsMessage(s Signer) (Message, error) {
323323
msg := Message{
324-
nonce: tx.data.AccountNonce,
325-
price: new(big.Int).Set(tx.data.Price),
326-
gasLimit: new(big.Int).Set(tx.data.GasLimit),
327-
to: tx.data.Recipient,
328-
amount: tx.data.Amount,
329-
data: tx.data.Payload,
324+
nonce: tx.data.AccountNonce,
325+
price: new(big.Int).Set(tx.data.Price),
326+
gasLimit: new(big.Int).Set(tx.data.GasLimit),
327+
to: tx.data.Recipient,
328+
amount: tx.data.Amount,
329+
data: tx.data.Payload,
330+
checkNonce: true,
330331
}
331332

332333
var err error
@@ -535,17 +536,19 @@ type Message struct {
535536
nonce uint64
536537
amount, price, gasLimit *big.Int
537538
data []byte
539+
checkNonce bool
538540
}
539541

540-
func NewMessage(from common.Address, to *common.Address, nonce uint64, amount, gasLimit, price *big.Int, data []byte) Message {
542+
func NewMessage(from common.Address, to *common.Address, nonce uint64, amount, gasLimit, price *big.Int, data []byte, checkNonce bool) Message {
541543
return Message{
542-
from: from,
543-
to: to,
544-
nonce: nonce,
545-
amount: amount,
546-
price: price,
547-
gasLimit: gasLimit,
548-
data: data,
544+
from: from,
545+
to: to,
546+
nonce: nonce,
547+
amount: amount,
548+
price: price,
549+
gasLimit: gasLimit,
550+
data: data,
551+
checkNonce: checkNonce,
549552
}
550553
}
551554

@@ -556,4 +559,4 @@ func (m Message) Value() *big.Int { return m.amount }
556559
func (m Message) Gas() *big.Int { return m.gasLimit }
557560
func (m Message) Nonce() uint64 { return m.nonce }
558561
func (m Message) Data() []byte { return m.data }
559-
func (m Message) CheckNonce() bool { return true }
562+
func (m Message) CheckNonce() bool { return m.checkNonce }

internal/ethapi/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr
545545
if gasPrice.Cmp(common.Big0) == 0 {
546546
gasPrice = new(big.Int).Mul(big.NewInt(50), common.Shannon)
547547
}
548-
msg := types.NewMessage(addr, args.To, 0, args.Value.BigInt(), gas, gasPrice, common.FromHex(args.Data))
548+
msg := types.NewMessage(addr, args.To, 0, args.Value.BigInt(), gas, gasPrice, common.FromHex(args.Data), false)
549549

550550
// Execute the call and return
551551
vmenv, vmError, err := s.b.GetVMEnv(ctx, msg, state, header)

les/flowcontrol/control.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ type ServerNode struct {
9999
params *ServerParams
100100
sumCost uint64 // sum of req costs sent to this server
101101
pending map[uint64]uint64 // value = sumCost after sending the given req
102-
lock sync.Mutex
102+
lock sync.RWMutex
103103
}
104104

105105
func NewServerNode(params *ServerParams) *ServerNode {
@@ -135,8 +135,8 @@ func (peer *ServerNode) canSend(maxCost uint64) uint64 {
135135
}
136136

137137
func (peer *ServerNode) CanSend(maxCost uint64) uint64 {
138-
peer.lock.Lock()
139-
defer peer.lock.Unlock()
138+
peer.lock.RLock()
139+
defer peer.lock.RUnlock()
140140

141141
return peer.canSend(maxCost)
142142
}
@@ -148,7 +148,10 @@ func (peer *ServerNode) SendRequest(reqID, maxCost uint64) {
148148

149149
peer.recalcBLE(getTime())
150150
for peer.bufEstimate < maxCost {
151-
time.Sleep(time.Duration(peer.canSend(maxCost)))
151+
wait := time.Duration(peer.canSend(maxCost))
152+
peer.lock.Unlock()
153+
time.Sleep(wait)
154+
peer.lock.Lock()
152155
peer.recalcBLE(getTime())
153156
}
154157
peer.bufEstimate -= maxCost

les/handler.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ func (pm *ProtocolManager) findServers() {
240240
if pm.p2pServer == nil || pm.topicDisc == nil {
241241
return
242242
}
243+
glog.V(logger.Debug).Infoln("Looking for topic", string(pm.lesTopic))
243244
enodes := make(chan string, 100)
244245
stop := make(chan struct{})
245246
go pm.topicDisc.SearchTopic(pm.lesTopic, stop, enodes)
@@ -280,9 +281,9 @@ func (pm *ProtocolManager) Start(srvr *p2p.Server) {
280281
} else {
281282
if pm.topicDisc != nil {
282283
go func() {
283-
glog.V(logger.Debug).Infoln("Starting topic register")
284+
glog.V(logger.Debug).Infoln("Starting registering topic", string(pm.lesTopic))
284285
pm.topicDisc.RegisterTopic(pm.lesTopic, pm.quitSync)
285-
glog.V(logger.Debug).Infoln("Stopped topic register")
286+
glog.V(logger.Debug).Infoln("Stopped registering topic", string(pm.lesTopic))
286287
}()
287288
}
288289
go func() {

les/odr_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
119119
from := statedb.GetOrNewStateObject(testBankAddress)
120120
from.SetBalance(common.MaxBig)
121121

122-
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data)}
122+
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)}
123123
vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
124124
gp := new(core.GasPool).AddGas(common.MaxBig)
125125
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
@@ -132,7 +132,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
132132
if err == nil {
133133
from.SetBalance(common.MaxBig)
134134

135-
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data)}
135+
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)}
136136

137137
vmenv := light.NewEnv(ctx, state, config, lc, msg, header, vm.Config{})
138138
gp := new(core.GasPool).AddGas(common.MaxBig)

light/lightchain.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ func NewLightChain(odr OdrBackend, config *params.ChainConfig, pow pow.PoW, mux
108108
// add trusted CHT
109109
if config.DAOForkSupport {
110110
WriteTrustedCht(bc.chainDb, TrustedCht{
111-
Number: 612,
112-
Root: common.HexToHash("8c87a93e0ee531e2aca1b4460e4c201a60c19ffec4f5979262bf14ceeeff8471"),
111+
Number: 637,
112+
Root: common.HexToHash("01e408d9b1942f05dba1a879f3eaafe34d219edaeb8223fecf1244cc023d3e23"),
113113
})
114114
} else {
115115
WriteTrustedCht(bc.chainDb, TrustedCht{
@@ -122,8 +122,8 @@ func NewLightChain(odr OdrBackend, config *params.ChainConfig, pow pow.PoW, mux
122122
if bc.genesisBlock.Hash() == (common.Hash{12, 215, 134, 162, 66, 93, 22, 241, 82, 198, 88, 49, 108, 66, 62, 108, 225, 24, 30, 21, 195, 41, 88, 38, 215, 201, 144, 76, 186, 156, 227, 3}) {
123123
// add trusted CHT for testnet
124124
WriteTrustedCht(bc.chainDb, TrustedCht{
125-
Number: 436,
126-
Root: common.HexToHash("97a12df5d04d72bde4b4b840e1018e4f08aee34b7d0bf2c5dbfc052b86fe7439"),
125+
Number: 452,
126+
Root: common.HexToHash("511da2c88e32b14cf4a4e62f7fcbb297139faebc260a4ab5eb43cce6edcba324"),
127127
})
128128
glog.V(logger.Info).Infoln("Added trusted CHT for testnet")
129129
} else {

light/odr_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
167167
from := statedb.GetOrNewStateObject(testBankAddress)
168168
from.SetBalance(common.MaxBig)
169169

170-
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(1000000), new(big.Int), data)}
170+
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(1000000), new(big.Int), data, false)}
171171
vmenv := core.NewEnv(statedb, testChainConfig(), bc, msg, header, vm.Config{})
172172
gp := new(core.GasPool).AddGas(common.MaxBig)
173173
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
@@ -180,7 +180,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
180180
if err == nil {
181181
from.SetBalance(common.MaxBig)
182182

183-
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(1000000), new(big.Int), data)}
183+
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(1000000), new(big.Int), data, false)}
184184
vmenv := NewEnv(ctx, state, testChainConfig(), lc, msg, header, vm.Config{})
185185
gp := new(core.GasPool).AddGas(common.MaxBig)
186186
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)

p2p/discv5/net.go

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ var (
4141
)
4242

4343
const (
44-
autoRefreshInterval = 1 * time.Hour
45-
seedCount = 30
46-
seedMaxAge = 5 * 24 * time.Hour
44+
autoRefreshInterval = 1 * time.Hour
45+
bucketRefreshInterval = 1 * time.Minute
46+
seedCount = 30
47+
seedMaxAge = 5 * 24 * time.Hour
4748
)
4849

4950
const testTopic = "foo"
@@ -62,8 +63,9 @@ func debugLog(s string) {
6263
// BootNodes are the enode URLs of the P2P bootstrap nodes for the experimental RLPx v5 "Topic Discovery" network
6364
// warning: local bootnodes for testing!!!
6465
var BootNodes = []*Node{
65-
//MustParseNode("enode://6f974ede10d07334e7e651c1501cb540d087dd3a6dea81432620895c913f281790b49459d72cb8011bfbbfbd24fad956356189c31b7181a96cd44ccfb68bfc71@127.0.0.1:30301"),
6666
MustParseNode("enode://0cc5f5ffb5d9098c8b8c62325f3797f56509bff942704687b6530992ac706e2cb946b90a34f1f19548cd3c7baccbcaea354531e5983c7d1bc0dee16ce4b6440b@40.118.3.223:30305"),
67+
MustParseNode("enode://1c7a64d76c0334b0418c004af2f67c50e36a3be60b5e4790bdac0439d21603469a85fad36f2473c9a80eb043ae60936df905fa28f1ff614c3e5dc34f15dcd2dc@40.118.3.223:30308"),
68+
MustParseNode("enode://85c85d7143ae8bb96924f2b54f1b3e70d8c4d367af305325d30a61385a432f247d2c75c45c6b4a60335060d072d7f5b35dd1d4c45f76941f62a4f83b6e75daaf@40.118.3.223:30309"),
6769
}
6870

6971
// Network manages the table and all protocol interaction.
@@ -82,7 +84,6 @@ type Network struct {
8284
tableOpResp chan struct{}
8385
topicRegisterReq chan topicRegisterReq
8486
topicSearchReq chan topicSearchReq
85-
bucketFillChn chan chan struct{}
8687

8788
// State of the main loop.
8889
tab *Table
@@ -169,7 +170,6 @@ func newNetwork(conn transport, ourPubkey ecdsa.PublicKey, natm nat.Interface, d
169170
queryReq: make(chan *findnodeQuery),
170171
topicRegisterReq: make(chan topicRegisterReq),
171172
topicSearchReq: make(chan topicSearchReq),
172-
bucketFillChn: make(chan chan struct{}, 1),
173173
nodes: make(map[NodeID]*Node),
174174
}
175175
go net.loop()
@@ -353,8 +353,9 @@ func (net *Network) reqTableOp(f func()) (called bool) {
353353

354354
func (net *Network) loop() {
355355
var (
356-
refreshTimer = time.NewTicker(autoRefreshInterval)
357-
refreshDone chan struct{} // closed when the 'refresh' lookup has ended
356+
refreshTimer = time.NewTicker(autoRefreshInterval)
357+
bucketRefreshTimer = time.NewTimer(bucketRefreshInterval)
358+
refreshDone chan struct{} // closed when the 'refresh' lookup has ended
358359
)
359360

360361
// Tracking the next ticket to register.
@@ -389,6 +390,7 @@ func (net *Network) loop() {
389390
topicRegisterLookupDone chan []*Node
390391
topicRegisterLookupTick = time.NewTimer(0)
391392
topicSearchLookupTarget lookupInfo
393+
searchReqWhenRefreshDone []topicSearchReq
392394
)
393395
topicSearchLookupDone := make(chan []*Node, 1)
394396
<-topicRegisterLookupTick.C
@@ -406,6 +408,7 @@ loop:
406408

407409
// Ingress packet handling.
408410
case pkt := <-net.read:
411+
//fmt.Println("read", pkt.ev)
409412
debugLog("<-net.read")
410413
n := net.internNode(&pkt)
411414
prestate := n.state
@@ -503,14 +506,18 @@ loop:
503506
net.conn.sendTopicRegister(nextTicket.t.node, nextTicket.t.topics, nextTicket.idx, nextTicket.t.pong)
504507

505508
case req := <-net.topicSearchReq:
506-
debugLog("<-net.topicSearchReq")
507-
if req.found == nil {
508-
net.ticketStore.removeSearchTopic(req.topic)
509-
continue
510-
}
511-
net.ticketStore.addSearchTopic(req.topic, req.found)
512-
if (topicSearchLookupTarget.target == common.Hash{}) {
513-
topicSearchLookupDone <- nil
509+
if refreshDone == nil {
510+
debugLog("<-net.topicSearchReq")
511+
if req.found == nil {
512+
net.ticketStore.removeSearchTopic(req.topic)
513+
continue
514+
}
515+
net.ticketStore.addSearchTopic(req.topic, req.found)
516+
if (topicSearchLookupTarget.target == common.Hash{}) {
517+
topicSearchLookupDone <- nil
518+
}
519+
} else {
520+
searchReqWhenRefreshDone = append(searchReqWhenRefreshDone, req)
514521
}
515522

516523
case nodes := <-topicSearchLookupDone:
@@ -519,7 +526,14 @@ loop:
519526
net.ping(n, n.addr())
520527
return n.pingEcho
521528
}, func(n *Node, topic Topic) []byte {
522-
return net.conn.send(n, topicQueryPacket, topicQuery{Topic: topic}) // TODO: set expiration
529+
if n.state == known {
530+
return net.conn.send(n, topicQueryPacket, topicQuery{Topic: topic}) // TODO: set expiration
531+
} else {
532+
if n.state == unknown {
533+
net.ping(n, n.addr())
534+
}
535+
return nil
536+
}
523537
})
524538
topicSearchLookupTarget = net.ticketStore.nextSearchLookup()
525539
target := topicSearchLookupTarget.target
@@ -564,9 +578,12 @@ loop:
564578
refreshDone = make(chan struct{})
565579
net.refresh(refreshDone)
566580
}
567-
case doneChn := <-net.bucketFillChn:
568-
debugLog("bucketFill")
569-
net.bucketFill(doneChn)
581+
case <-bucketRefreshTimer.C:
582+
target := net.tab.chooseBucketRefreshTarget()
583+
go func() {
584+
net.lookup(target, false)
585+
bucketRefreshTimer.Reset(bucketRefreshInterval)
586+
}()
570587
case newNursery := <-net.refreshReq:
571588
debugLog("<-net.refreshReq")
572589
if newNursery != nil {
@@ -580,6 +597,13 @@ loop:
580597
case <-refreshDone:
581598
debugLog("<-net.refreshDone")
582599
refreshDone = nil
600+
list := searchReqWhenRefreshDone
601+
searchReqWhenRefreshDone = nil
602+
go func() {
603+
for _, req := range list {
604+
net.topicSearchReq <- req
605+
}
606+
}()
583607
}
584608
}
585609
debugLog("loop stopped")
@@ -643,28 +667,13 @@ func (net *Network) refresh(done chan<- struct{}) {
643667
}()
644668
}
645669

646-
func (net *Network) bucketFill(done chan<- struct{}) {
647-
target := net.tab.chooseBucketFillTarget()
648-
go func() {
649-
net.lookup(target, false)
650-
close(done)
651-
}()
652-
}
653-
654-
func (net *Network) BucketFill() {
655-
done := make(chan struct{})
656-
select {
657-
case net.bucketFillChn <- done:
658-
<-done
659-
case <-net.closed:
660-
close(done)
661-
}
662-
}
663-
664670
// Node Interning.
665671

666672
func (net *Network) internNode(pkt *ingressPacket) *Node {
667673
if n := net.nodes[pkt.remoteID]; n != nil {
674+
n.IP = pkt.remoteAddr.IP
675+
n.UDP = uint16(pkt.remoteAddr.Port)
676+
n.TCP = uint16(pkt.remoteAddr.Port)
668677
return n
669678
}
670679
n := NewNode(pkt.remoteID, pkt.remoteAddr.IP, uint16(pkt.remoteAddr.Port), uint16(pkt.remoteAddr.Port))
@@ -967,8 +976,10 @@ func init() {
967976

968977
// handle processes packets sent by n and events related to n.
969978
func (net *Network) handle(n *Node, ev nodeEvent, pkt *ingressPacket) error {
979+
//fmt.Println("handle", n.addr().String(), n.state, ev)
970980
if pkt != nil {
971981
if err := net.checkPacket(n, ev, pkt); err != nil {
982+
//fmt.Println("check err:", err)
972983
return err
973984
}
974985
// Start the background expiration goroutine after the first
@@ -985,6 +996,7 @@ func (net *Network) handle(n *Node, ev nodeEvent, pkt *ingressPacket) error {
985996
}
986997
next, err := n.state.handle(net, n, ev, pkt)
987998
net.transition(n, next)
999+
//fmt.Println("new state:", n.state)
9881000
return err
9891001
}
9901002

@@ -1040,6 +1052,11 @@ func (net *Network) abortTimedEvent(n *Node, ev nodeEvent) {
10401052
}
10411053

10421054
func (net *Network) ping(n *Node, addr *net.UDPAddr) {
1055+
//fmt.Println("ping", n.addr().String(), n.ID.String(), n.sha.Hex())
1056+
if n.pingEcho != nil || n.ID == net.tab.self.ID {
1057+
//fmt.Println(" not sent")
1058+
return
1059+
}
10431060
debugLog(fmt.Sprintf("ping(node = %x)", n.ID[:8]))
10441061
n.pingTopics = net.ticketStore.regTopicSet()
10451062
n.pingEcho = net.conn.sendPing(n, addr, n.pingTopics)

0 commit comments

Comments
 (0)