From 3e910b7a4c7bc3cc921db86b8b290536e848db31 Mon Sep 17 00:00:00 2001 From: Fibonacci747 Date: Thu, 27 Nov 2025 16:37:35 +0000 Subject: [PATCH] fix: closure capture race in generateTrieRoot goroutines --- core/state/snapshot/conversion.go | 17 ++++++++++------- triedb/pathdb/verifier.go | 17 ++++++++++------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/core/state/snapshot/conversion.go b/core/state/snapshot/conversion.go index 0d39687be4..2e386b68e9 100644 --- a/core/state/snapshot/conversion.go +++ b/core/state/snapshot/conversion.go @@ -298,23 +298,26 @@ func generateTrieRoot(db ethdb.KeyValueWriter, scheme string, it Iterator, accou return stop(err) } // Fetch the next account and process it concurrently - account, err := types.FullAccount(it.(AccountIterator).Account()) + acc, err := types.FullAccount(it.(AccountIterator).Account()) if err != nil { return stop(err) } - go func(hash common.Hash) { - subroot, err := leafCallback(db, hash, common.BytesToHash(account.CodeHash), stats) + h := it.Hash() + ch := common.BytesToHash(acc.CodeHash) + wr := acc.Root + go func(hash common.Hash, codeHash common.Hash, wantRoot common.Hash) { + subroot, err := leafCallback(db, hash, codeHash, stats) if err != nil { results <- err return } - if account.Root != subroot { - results <- fmt.Errorf("invalid subroot(path %x), want %x, have %x", hash, account.Root, subroot) + if wantRoot != subroot { + results <- fmt.Errorf("invalid subroot(path %x), want %x, have %x", hash, wantRoot, subroot) return } results <- nil - }(it.Hash()) - fullData, err = rlp.EncodeToBytes(account) + }(h, ch, wr) + fullData, err = rlp.EncodeToBytes(acc) if err != nil { return stop(err) } diff --git a/triedb/pathdb/verifier.go b/triedb/pathdb/verifier.go index a69b10f4f3..8ed69bb530 100644 --- a/triedb/pathdb/verifier.go +++ b/triedb/pathdb/verifier.go @@ -294,23 +294,26 @@ func generateTrieRoot(it Iterator, account common.Hash, generatorFn trieHasherFn return stop(err) } // Fetch the next account and process it concurrently - account, err := types.FullAccount(it.(AccountIterator).Account()) + acc, err := types.FullAccount(it.(AccountIterator).Account()) if err != nil { return stop(err) } - go func(hash common.Hash) { - subroot, err := leafCallback(hash, common.BytesToHash(account.CodeHash), stats) + h := it.Hash() + ch := common.BytesToHash(acc.CodeHash) + wr := acc.Root + go func(hash common.Hash, codeHash common.Hash, wantRoot common.Hash) { + subroot, err := leafCallback(hash, codeHash, stats) if err != nil { results <- err return } - if account.Root != subroot { - results <- fmt.Errorf("invalid subroot(path %x), want %x, have %x", hash, account.Root, subroot) + if wantRoot != subroot { + results <- fmt.Errorf("invalid subroot(path %x), want %x, have %x", hash, wantRoot, subroot) return } results <- nil - }(it.Hash()) - fullData, err = rlp.EncodeToBytes(account) + }(h, ch, wr) + fullData, err = rlp.EncodeToBytes(acc) if err != nil { return stop(err) }