mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-22 04:36:42 +00:00
fix: resolve race conditions, add bounds checks, and remove redundant code
This commit is contained in:
parent
d8419ffca2
commit
8bd797b6c6
2 changed files with 28 additions and 7 deletions
|
|
@ -316,6 +316,11 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error {
|
|||
defer close(dead)
|
||||
|
||||
// If we have any explicit peer required block hashes, request them
|
||||
// Capture peer ID and logger to avoid race conditions in goroutines
|
||||
peerID := peer.ID()
|
||||
peerLogger := peer.Log()
|
||||
peerAddr := peer.RemoteAddr()
|
||||
peerName := peer.Name()
|
||||
for number, hash := range h.requiredBlocks {
|
||||
resCh := make(chan *eth.Response)
|
||||
|
||||
|
|
@ -323,7 +328,7 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go func(number uint64, hash common.Hash, req *eth.Request) {
|
||||
go func(number uint64, hash common.Hash, req *eth.Request, id string, logger log.Logger, addr string, name string) {
|
||||
// Ensure the request gets cancelled in case of error/drop
|
||||
defer req.Close()
|
||||
|
||||
|
|
@ -345,19 +350,19 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error {
|
|||
return
|
||||
}
|
||||
if headers[0].Number.Uint64() != number || headers[0].Hash() != hash {
|
||||
peer.Log().Info("Required block mismatch, dropping peer", "number", number, "hash", headers[0].Hash(), "want", hash)
|
||||
logger.Info("Required block mismatch, dropping peer", "number", number, "hash", headers[0].Hash(), "want", hash)
|
||||
res.Done <- errors.New("required block mismatch")
|
||||
return
|
||||
}
|
||||
peer.Log().Debug("Peer required block verified", "number", number, "hash", hash)
|
||||
logger.Debug("Peer required block verified", "number", number, "hash", hash)
|
||||
res.Done <- nil
|
||||
case <-timeout.C:
|
||||
peer.Log().Warn("Required block challenge timed out, dropping", "addr", peer.RemoteAddr(), "type", peer.Name())
|
||||
h.removePeer(peer.ID())
|
||||
logger.Warn("Required block challenge timed out, dropping", "addr", addr, "type", name)
|
||||
h.removePeer(id)
|
||||
case <-dead:
|
||||
// Peer handler terminated, abort all goroutines
|
||||
}
|
||||
}(number, hash, req)
|
||||
}(number, hash, req, peerID, peerLogger, peerAddr, peerName)
|
||||
}
|
||||
// Handle incoming messages until the connection is torn down
|
||||
return handler(peer)
|
||||
|
|
|
|||
|
|
@ -52,10 +52,26 @@ func (t *stateTracker) releaseState(number uint64, release StateReleaseFunc) {
|
|||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
|
||||
// Validate that the state number is within the expected range
|
||||
if number < t.oldest {
|
||||
// This should not happen in normal operation, but handle gracefully
|
||||
// by just appending the release function without updating the used array
|
||||
t.releases = append(t.releases, release)
|
||||
return
|
||||
}
|
||||
|
||||
// Calculate the index and ensure it's within bounds
|
||||
index := int(number - t.oldest)
|
||||
if index < 0 || index >= len(t.used) {
|
||||
// State is outside the tracking window, just append the release function
|
||||
t.releases = append(t.releases, release)
|
||||
return
|
||||
}
|
||||
|
||||
// Set the state as used, the corresponding flag is indexed by
|
||||
// the distance between the specified state and the oldest state
|
||||
// which is still using for trace.
|
||||
t.used[int(number-t.oldest)] = true
|
||||
t.used[index] = true
|
||||
|
||||
// If the oldest state is used up, update the oldest marker by moving
|
||||
// it to the next state which is not used up.
|
||||
|
|
|
|||
Loading…
Reference in a new issue