Skip to content

Commit d5a07ae

Browse files
committed
spv: fix unsafe waitgroup usage
The goroutine started after receiving an inv also spawns its own goroutines and increments the waitgroup counter. This is invalid waitgroup usage as it could occur concurrently with or after the call to Wait(). Removing the superfluous outer goroutine fixes this issue.
1 parent 0ea0698 commit d5a07ae

File tree

1 file changed

+34
-40
lines changed

1 file changed

+34
-40
lines changed

spv/sync.go

Lines changed: 34 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -703,49 +703,43 @@ func (s *Syncer) receiveInv(ctx context.Context) error {
703703
return err
704704
}
705705

706-
wg.Add(1)
707-
go func() {
708-
defer wg.Done()
709-
710-
var blocks []*chainhash.Hash
711-
var txs []*chainhash.Hash
712-
713-
for _, inv := range msg.InvList {
714-
switch inv.Type {
715-
case wire.InvTypeBlock:
716-
blocks = append(blocks, &inv.Hash)
717-
case wire.InvTypeTx:
718-
txs = append(txs, &inv.Hash)
719-
}
706+
var blocks []*chainhash.Hash
707+
var txs []*chainhash.Hash
708+
for _, inv := range msg.InvList {
709+
switch inv.Type {
710+
case wire.InvTypeBlock:
711+
blocks = append(blocks, &inv.Hash)
712+
case wire.InvTypeTx:
713+
txs = append(txs, &inv.Hash)
720714
}
715+
}
721716

722-
if len(blocks) != 0 {
723-
wg.Add(1)
724-
go func() {
725-
defer wg.Done()
717+
if len(blocks) != 0 {
718+
wg.Add(1)
719+
go func() {
720+
defer wg.Done()
726721

727-
err := s.handleBlockInvs(ctx, rp, blocks)
728-
if ctx.Err() != nil {
729-
return
730-
}
731-
if errors.Is(err, errors.Protocol) || errors.Is(err, errors.Consensus) {
732-
log.Warnf("Disconnecting peer %v: %v", rp, err)
733-
rp.Disconnect(err)
734-
return
735-
}
736-
if err != nil {
737-
log.Warnf("Failed to handle blocks inventoried by %v: %v", rp, err)
738-
}
739-
}()
740-
}
741-
if len(txs) != 0 {
742-
wg.Add(1)
743-
go func() {
744-
s.handleTxInvs(ctx, rp, txs)
745-
wg.Done()
746-
}()
747-
}
748-
}()
722+
err := s.handleBlockInvs(ctx, rp, blocks)
723+
if ctx.Err() != nil {
724+
return
725+
}
726+
if errors.Is(err, errors.Protocol) || errors.Is(err, errors.Consensus) {
727+
log.Warnf("Disconnecting peer %v: %v", rp, err)
728+
rp.Disconnect(err)
729+
return
730+
}
731+
if err != nil {
732+
log.Warnf("Failed to handle blocks inventoried by %v: %v", rp, err)
733+
}
734+
}()
735+
}
736+
if len(txs) != 0 {
737+
wg.Add(1)
738+
go func() {
739+
s.handleTxInvs(ctx, rp, txs)
740+
wg.Done()
741+
}()
742+
}
749743
}
750744
}
751745

0 commit comments

Comments
 (0)