Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/keeper/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ require (
github.com/yusufpapurcu/wmi v1.2.4 // indirect
golang.org/x/crypto v0.46.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.40.0 // indirect
golang.org/x/sys v0.42.0 // indirect
golang.org/x/time v0.12.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
Expand Down
1 change: 1 addition & 0 deletions cmd/keeper/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
Expand Down
4 changes: 3 additions & 1 deletion consensus/bor/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,9 @@ func (api *API) GetCurrentValidators() ([]*valset.Validator, error) {
return snap.ValidatorSet.Validators, nil
}

// GetRootHash returns the merkle root of the start-to-end blocks' headers
// GetRootHash returns the merkle root of the start-to-end blocks' headers.
// rootHashCache is normally initialized eagerly inside Bor.APIs (sync.Once);
// the lazy init below is kept as fallback for direct-API paths (e.g., tests) that don't go through Bor.APIs.
func (api *API) GetRootHash(start uint64, end uint64) (string, error) {
if err := api.initializeRootHashCache(); err != nil {
return "", err
Expand Down
24 changes: 23 additions & 1 deletion consensus/bor/bor.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,10 @@ type Bor struct {
// ctx is cancelled when Close() is called, allowing in-flight operations to abort promptly.
ctx context.Context
ctxCancel context.CancelFunc

// api is the bor engine API instance reused across all callers (JSON-RPC and gRPC).
api *API
apiOnce sync.Once
}

type signer struct {
Expand Down Expand Up @@ -1520,11 +1524,29 @@ func (c *Bor) SealHash(header *types.Header) common.Hash {

// APIs implements consensus.Engine, returning the user facing RPC API to allow
// controlling the signer voting.
//
// The returned *API is cached on the first call so that per-API state (e.g.,
// rootHashCache) persists across calls. JSON-RPC only invokes APIs() once at
// node startup, but the gRPC backend fetches it on every handler call — without
// the cache those calls would each start from an empty state.
//
// rootHashCache is initialized here (inside the sync.Once) rather than lazily
// in GetRootHash so that concurrent gRPC handlers sharing the cached *API
// cannot race in initializeRootHashCache.
func (c *Bor) APIs(chain consensus.ChainHeaderReader) []rpc.API {
c.apiOnce.Do(func() {
a := &API{chain: chain, bor: c}
if err := a.initializeRootHashCache(); err != nil {
// log.Crit logs at the highest severity and then exits the process;
// This is currently unreachable (size is a constant in initializeRootHashCache),
log.Crit("bor: failed to initialize rootHashCache", "err", err)
}
c.api = a
})
return []rpc.API{{
Namespace: "bor",
Version: "1.0",
Service: &API{chain: chain, bor: c},
Service: c.api,
Public: false,
}}
}
Expand Down
14 changes: 14 additions & 0 deletions consensus/bor/bor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2039,6 +2039,20 @@ func TestAPIs_ReturnsBorNamespace(t *testing.T) {
require.Equal(t, "1.0", apis[0].Version)
}

// TestAPIs_ReturnsSameInstanceAcrossCalls verifies that repeated calls to APIs() must return the same *API
// so per-API state such as rootHashCache persists across calls. This matters for the gRPC backend
// which fetches APIs() on every handler invocation; returning a fresh *API each call defeats caching.
func TestAPIs_ReturnsSameInstanceAcrossCalls(t *testing.T) {
t.Parallel()
sp := &fakeSpanner{vals: []*valset.Validator{{Address: common.HexToAddress("0x1"), VotingPower: 1}}}
borCfg := defaultBorConfig()
chain, b := newChainAndBorForTest(t, sp, borCfg, false, common.Address{}, uint64(time.Now().Unix()))

first := b.APIs(chain.HeaderChain())
second := b.APIs(chain.HeaderChain())
require.Same(t, first[0].Service, second[0].Service, "APIs must return the cached *API on repeated calls")
}

func TestClose_Idempotent(t *testing.T) {
t.Parallel()
sp := &fakeSpanner{vals: []*valset.Validator{{Address: common.HexToAddress("0x1"), VotingPower: 1}}}
Expand Down
20 changes: 10 additions & 10 deletions eth/tracers/data.csv
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
TransactionIndex, Incarnation, VersionTxIdx, VersionInc, Path, Operation
0 , 0, -1 , -1, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000001, Read
0 , 0, -1 , -1, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000103, Read
0 , 0, -1 , -1, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103, Read
0 , 0, -1 , -1, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, Read
0 , 0, 0 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103, Write
0 , 0, -1 , -1, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000001, Read
0 , 0, 0 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000001, Write
0 , 0, 0 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000103, Write
0 , 0, 0 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, Write
1 , 0, 0 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, Read
0 , 0, 0 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103, Write
1 , 0, 0 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000001, Read

Check notice on line 10 in eth/tracers/data.csv

View check run for this annotation

Claude / Claude Code Review

data.csv row reordering is pure diff noise from non-deterministic map iteration

This is a pre-existing issue: `eth/tracers/data.csv` is listed in `eth/tracers/.gitignore` yet committed to the repo, and its rows are generated by iterating Go maps (`GetReadMapDump`/`GetWriteMapDump` → `MVReadList`/`MVWriteList` in `core/state/statedb.go`) whose iteration order is non-deterministic — so every regeneration shuffles rows within each TransactionIndex group. The simplest action on this PR is to revert `eth/tracers/data.csv` to its pre-PR contents so the 40-line diff of pure noise
Comment thread
claude[bot] marked this conversation as resolved.
1 , 0, 0 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000103, Read
1 , 0, 0 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103, Read
1 , 0, 1 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, Write
1 , 0, 1 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103, Write
1 , 0, 0 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, Read
1 , 0, 1 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000001, Write
1 , 0, 1 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000103, Write
2 , 0, 1 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, Read
2 , 0, 1 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000001, Read
1 , 0, 1 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, Write
1 , 0, 1 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103, Write
2 , 0, 1 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000103, Read
2 , 0, 1 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103, Read
2 , 0, 1 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, Read
2 , 0, 1 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000001, Read
2 , 0, 2 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000001, Write
2 , 0, 2 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000103, Write
2 , 0, 2 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, Write
2 , 0, 2 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103, Write
2 , 0, 2 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000001, Write
3 , 0, 2 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103, Read
3 , 0, 2 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, Read
3 , 0, 2 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000001, Read
3 , 0, 2 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000103, Read
3 , 0, 2 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103, Read
3 , 0, 3 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000001, Write
3 , 0, 3 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000103, Write
3 , 0, 3 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, Write
3 , 0, 3 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103, Write
4 , 0, 3 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000001, Read
4 , 0, 3 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000103, Read
4 , 0, 3 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103, Read
4 , 0, 3 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, Read
4 , 0, 3 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000001, Read
4 , 0, 4 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000001, Write
4 , 0, 4 , 0, 000000000000000000000000000000000000dead00000000000000000000000000000000000000000000000000000000000000000103, Write
4 , 0, 4 , 0, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, Write
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ go 1.26.2
require (
github.com/0xPolygon/crand v1.0.3
github.com/0xPolygon/heimdall-v2 v0.6.0
github.com/0xPolygon/polyproto v0.0.7
github.com/0xPolygon/polyproto v0.0.8-0.20260423132317-7d955b45ef8a
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2
github.com/BurntSushi/toml v1.4.0
github.com/JekaMas/go-grpc-net-conn v0.0.0-20220708155319-6aff21f2d13d
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ github.com/0xPolygon/crand v1.0.3 h1:BYYflmgLhmGPEgqtopG4muq6wV6DOkwD8uPymNz5WeQ
github.com/0xPolygon/crand v1.0.3/go.mod h1:km4366oC7EVFl1xNUCwzxUXNM10swZqd8LZ0E5SgbAE=
github.com/0xPolygon/heimdall-v2 v0.6.0 h1:rA8RISMnns1w08PxTLvDBS5WiaTOFHJGSrhDWDJLtHc=
github.com/0xPolygon/heimdall-v2 v0.6.0/go.mod h1:fVkGiODG6cGLaDyrE3qxIrvz1rbUr4Zdrr3dOm2SPgg=
github.com/0xPolygon/polyproto v0.0.7 h1:Ody+kFyCRK4QXRPXbsP5pdxKrDgwAAXtFB8NPgaIxRs=
github.com/0xPolygon/polyproto v0.0.7/go.mod h1:2Iw93k2LismvckKKeXQITuhJH9vLbqOa212AMskH6no=
github.com/0xPolygon/polyproto v0.0.8-0.20260423132317-7d955b45ef8a h1:vVtSjO29FcFBZbNVsVGy6z3lv3RRr/sI1vPR7IzbZZE=
github.com/0xPolygon/polyproto v0.0.8-0.20260423132317-7d955b45ef8a/go.mod h1:2Iw93k2LismvckKKeXQITuhJH9vLbqOa212AMskH6no=
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs=
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4=
github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0=
Expand Down
Loading
Loading