-
Notifications
You must be signed in to change notification settings - Fork 20.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
les: UDP pre-negotiation of available server capacity #22183
Conversation
50d2d39
to
a509441
Compare
c696d15
to
663180f
Compare
6767f00
to
cbc40f4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am using the les-simulator for a testing run.
At least it can happen if nodiscover
is enabled?
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x68 pc=0x444ac0a]
goroutine 1 [running]:
github.com/ethereum/go-ethereum/p2p/discover.(*UDPv5).RegisterTalkHandler(0x0, 0x4dd09d7, 0x3, 0xc000093f00)
/Users/gary/gopath/src/github.com/ethereum/go-ethereum/p2p/discover/v5_udp.go:240 +0x3a
github.com/ethereum/go-ethereum/les.(*LesServer).Start(0xc00077c7e0, 0x0, 0x0)
/Users/gary/gopath/src/github.com/ethereum/go-ethereum/les/server.go:223 +0x117
github.com/ethereum/go-ethereum/node.(*Node).Start(0xc00016d2b0, 0x0, 0x0)
/Users/gary/gopath/src/github.com/ethereum/go-ethereum/node/node.go:184 +0x2c8
github.com/ethereum/go-ethereum/p2p/simulations/adapters.(*SimNode).Start(0xc0001a21c0, 0x0, 0xd, 0x5)
/Users/gary/gopath/src/github.com/ethereum/go-ethereum/p2p/simulations/adapters/inproc.go:272 +0x8a
github.com/ethereum/go-ethereum/p2p/simulations.(*Network).startWithSnapshots(0xc00023a700, 0x28f36fb5e23a417a, 0xa6ba96cde70ddcc3, 0xc43277c345b658de, 0xcc18c5e4df37b363, 0x0, 0x0, 0x0)
/Users/gary/gopath/src/github.com/ethereum/go-ethereum/p2p/simulations/network.go:190 +0x2e2
github.com/ethereum/go-ethereum/p2p/simulations.(*Network).Start(...)
/Users/gary/gopath/src/github.com/ethereum/go-ethereum/p2p/simulations/network.go:173
github.com/rjl493456442/les-simulator/simulator.(*Cluster).StartNodes(0xc00020e900, 0x0, 0x0)
/Users/gary/gopath/src/github.com/rjl493456442/les-simulator/simulator/cluster.go:258 +0x11e
main.main()
/Users/gary/gopath/src/github.com/rjl493456442/les-simulator/cmd/les-example/main.go:69 +0x38e
@rjl493456442 I'll address your comments soon. In the meantime, I promised to write a bit about CapacityCurve. The question we are trying to answer here is "what is the maximal capacity I can get?", or "how much capacity can I get if I buy a given amount of tokens?" This query format plays well with the priority client logic. The necessary info to answer this is in the priority queue used in PriorityPool because the amount of available capacity depends on the priority level. But you basically have to deconstruct the heap in order to get the necessary info, pop items from the top of the queue until the priority of the requesting client is not enough any more. Other clients with high capacity are also reduced in multiple steps so some items need to be put back into the queue with lower capacity and higher priority. It's not a terrible amount of calculation in absolute terms but if we do it to serve each individual capacity request then it could easily be an attack vector. So instead of touching the PriorityPool queue each time I used a cached curve that shows how much capacity can be gained at each priority level. I update it periodically or when the pool is changed. But if there are a lot of capacity requests then most of them can use the cached curve. |
Finally there is a binary search on this curve to find the available capacity because the priorityof the requesting client is inversely proportional to the capacity. |
This PR implements the first one of the "lespay" UDP queries which is already useful in itself: the capacity query. The server pool is making use of this query by doing a cheap UDP query to determine whether it is worth starting the more expensive TCP connection process.