Skip to content

Fix sharedState data race in backgroundProposalOutcome#132

Open
brunotm wants to merge 1 commit intosmartcontractkit:masterfrom
brunotm:bm/DS-2444-fix-backgroundProposalOutcome-data-race
Open

Fix sharedState data race in backgroundProposalOutcome#132
brunotm wants to merge 1 commit intosmartcontractkit:masterfrom
brunotm:bm/DS-2444-fix-backgroundProposalOutcome-data-race

Conversation

@brunotm
Copy link

@brunotm brunotm commented Feb 26, 2026

This change fixes a unsynchronised access to outgen.sharedState.committedOutcome, by using the captured outctx.PreviousOutcome from the shared state which is passed by value to backgroundProposalOutcome.

Write at commit() at outcome_generation_follower.go:846 outgen.sharedState.committedOutcome = commit.Outcome

Read at backgroundProposalOutcome() at outcome_generation_follower.go:499 outgen.sharedState.committedOutcome when calling MakeOutcomeInputsDigest()

https://github.com/smartcontractkit/chainlink/actions/runs/22384997421/job/64793669658

==================
WARNING: DATA RACE
Write at 0x00c0339aade0 by goroutine 481858:
  github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3/protocol.(*outcomeGenerationState[go.shape.struct { LifeCycleStage github.com/smartcontractkit/chainlink-common/pkg/types/llo.LifeCycleStage; ReportFormat github.com/smartcontractkit/chainlink-common/pkg/types/llo.ReportFormat }]).commit()
      /home/runner/go/pkg/mod/github.com/smartcontractkit/libocr@v0.0.0-20260130195252-6e18e2a30acc/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_follower.go:846 +0x3ea
  github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3/protocol.(*outcomeGenerationState[go.shape.struct { LifeCycleStage github.com/smartcontractkit/chainlink-common/pkg/types/llo.LifeCycleStage; ReportFormat github.com/smartcontractkit/chainlink-common/pkg/types/llo.ReportFormat }]).commit()
      /home/runner/go/pkg/mod/github.com/smartcontractkit/libocr@v0.0.0-20260130195252-6e18e2a30acc/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_follower.go:842 +0x344
  github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3/protocol.(*outcomeGenerationState[go.shape.struct { LifeCycleStage github.com/smartcontractkit/chainlink-common/pkg/types/llo.LifeCycleStage; ReportFormat github.com/smartcontractkit/chainlink-common/pkg/types/llo.ReportFormat }]).messageEpochStart()
      /home/runner/go/pkg/mod/github.com/smartcontractkit/libocr@v0.0.0-20260130195252-6e18e2a30acc/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_follower.go:81 +0x14cb
  github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3/protocol.MessageEpochStart[go.shape.struct { LifeCycleStage github.com/smartcontractkit/chainlink-common/pkg/types/llo.LifeCycleStage; ReportFormat github.com/smartcontractkit/chainlink-common/pkg/types/llo.ReportFormat }].processOutcomeGeneration()
      /home/runner/go/pkg/mod/github.com/smartcontractkit/libocr@v0.0.0-20260130195252-6e18e2a30acc/offchainreporting2plus/internal/ocr3/protocol/message.go:258 +0x150
  github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3/protocol.(*MessageEpochStart[github.com/smartcontractkit/chainlink-common/pkg/types/llo.ReportInfo]).processOutcomeGeneration()
      <autogenerated>:1 +0x29
  github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3/protocol.(*outcomeGenerationState[go.shape.struct { LifeCycleStage github.com/smartcontractkit/chainlink-common/pkg/types/llo.LifeCycleStage; ReportFormat github.com/smartcontractkit/chainlink-common/pkg/types/llo.ReportFormat }]).unbufferMessages()
      /home/runner/go/pkg/mod/github.com/smartcontractkit/libocr@v0.0.0-20260130195252-6e18e2a30acc/offchainreporting2plus/internal/ocr3/protocol/outcome_generation.go:273 +0x961
  github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3/protocol.(*outcomeGenerationState[go.shape.struct { LifeCycleStage github.com/smartcontractkit/chainlink-common/pkg/types/llo.LifeCycleStage; ReportFormat github.com/smartcontractkit/chainlink-common/pkg/types/llo.ReportFormat }]).eventNewEpochStart()
      /home/runner/go/pkg/mod/github.com/smartcontractkit/libocr@v0.0.0-20260130195252-6e18e2a30acc/offchainreporting2plus/internal/ocr3/protocol/outcome_generation.go:349 +0x15f1
  github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3/protocol.EventNewEpochStart[go.shape.struct { LifeCycleStage github.com/smartcontractkit/chainlink-common/pkg/types/llo.LifeCycleStage; ReportFormat github.com/smartcontractkit/chainlink-common/pkg/types/llo.ReportFormat }].processOutcomeGeneration()
      /home/runner/go/pkg/mod/github.com/smartcontractkit/libocr@v0.0.0-20260130195252-6e18e2a30acc/offchainreporting2plus/internal/ocr3/protocol/message.go:43 +0x6c
  github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3/protocol.(*EventNewEpochStart[github.com/smartcontractkit/chainlink-common/pkg/types/llo.ReportInfo]).processOutcomeGeneration()
      <autogenerated>:1 +0x1b
  github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3/protocol.(*outcomeGenerationState[go.shape.struct { LifeCycleStage github.com/smartcontractkit/chainlink-common/pkg/types/llo.LifeCycleStage; ReportFormat github.com/smartcontractkit/chainlink-common/pkg/types/llo.ReportFormat }]).run()
      /home/runner/go/pkg/mod/github.com/smartcontractkit/libocr@v0.0.0-20260130195252-6e18e2a30acc/offchainreporting2plus/internal/ocr3/protocol/outcome_generation.go:205 +0x885
  github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3/protocol.RunOutcomeGeneration[go.shape.struct { LifeCycleStage github.com/smartcontractkit/chainlink-common/pkg/types/llo.LifeCycleStage; ReportFormat github.com/smartcontractkit/chainlink-common/pkg/types/llo.ReportFormat }]()
      /home/runner/go/pkg/mod/github.com/smartcontractkit/libocr@v0.0.0-20260130195252-6e18e2a30acc/offchainreporting2plus/internal/ocr3/protocol/outcome_generation.go:69 +0x3cc
  github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3/protocol.(*oracleState[go.shape.struct { LifeCycleStage github.com/smartcontractkit/chainlink-common/pkg/types/llo.LifeCycleStage; ReportFormat github.com/smartcontractkit/chainlink-common/pkg/types/llo.ReportFormat }]).run.func2()
      /home/runner/go/pkg/mod/github.com/smartcontractkit/libocr@v0.0.0-20260130195252-6e18e2a30acc/offchainreporting2plus/internal/ocr3/protocol/oracle.go:188 +0x4f1
  github.com/smartcontractkit/libocr/subprocesses.(*Subprocesses).Go.func1()
      /home/runner/go/pkg/mod/github.com/smartcontractkit/libocr@v0.0.0-20260130195252-6e18e2a30acc/subprocesses/subprocesses.go:29 +0x82

Previous read at 0x00c0339aade0 by goroutine 486328:
  github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3/protocol.(*outcomeGenerationState[go.shape.struct { LifeCycleStage github.com/smartcontractkit/chainlink-common/pkg/types/llo.LifeCycleStage; ReportFormat github.com/smartcontractkit/chainlink-common/pkg/types/llo.ReportFormat }]).backgroundProposalOutcome()
      /home/runner/go/pkg/mod/github.com/smartcontractkit/libocr@v0.0.0-20260130195252-6e18e2a30acc/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_follower.go:499 +0x1094
  github.com/smartcontractkit/libocr/offchainreporting2plus/internal/ocr3/protocol.(*outcomeGenerationState[go.shape.struct { LifeCycleStage github.com/smartcontractkit/chainlink-common/pkg/types/llo.LifeCycleStage; ReportFormat github.com/smartcontractkit/chainlink-common/pkg/types/llo.ReportFormat }]).tryProcessProposalPool.func1()
      /home/runner/go/pkg/mod/github.com/smartcontractkit/libocr@v0.0.0-20260130195252-6e18e2a30acc/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_follower.go:383 +0x1d3
  github.com/smartcontractkit/libocr/subprocesses.(*Subprocesses).Go.func1()
      /home/runner/go/pkg/mod/github.com/smartcontractkit/libocr@v0.0.0-20260130195252-6e18e2a30acc/subprocesses/subprocesses.go:29 +0x82

…utcomeInputsDigest instead of the unsynchronized sharedState.committedOutcome
@brunotm brunotm requested a review from a team as a code owner February 26, 2026 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant