Skip to content

Tighten client nodecache - #1190

Open
AlCutter wants to merge 2 commits into
transparency-dev:mainfrom
AlCutter:tighten_client_nodecache
Open

AlCutter wants to merge 2 commits into
transparency-dev:mainfrom
AlCutter:tighten_client_nodecache

Conversation

@AlCutter

Copy link
Copy Markdown
Collaborator

nodeCache was very relaxed in terms of the node IDs it
would serve and the tiles it would accept from a fetcher.

This PR tightens both, and removes a potential correctness issue:

  • GetNode explicitly rejects out-of-range nodes.
  • fetchTileNodes now asserts that a tile is either the precise partial
    size requested, or a full tile (i.e. the fetcher fell-back to
    requesting a full tile)
  • Removed call to GetRootHash. This was unnecessary, but
    also incorrectly populated the cache with ephemeral nodes.

@AlCutter
AlCutter requested a review from roger2hk September 18, 2026 14:49
@AlCutter
AlCutter requested a review from a team as a code owner September 18, 2026 14:49
@AlCutter
AlCutter force-pushed the tighten_client_nodecache branch from 6ad99d1 to dd98586 Compare September 18, 2026 14:53
nodeCache was very relaxed in terms of the node IDs it
would serve and the tiles it would accept from a fetcher.
This PR tightens both, and removes a potential correctness issue.

* GetNode explicitly rejects out-of-range nodes.
* fetchTileNodes now asserts that a tile is either the precise partial
  size requested, or a full tile (i.e. the fetcher fell-back to
  requesting a full tile)
* Removed call to GetRootHash. This was unnecessary, but
  also incorrectly populated the cache with ephemeral nodes.
@AlCutter
AlCutter force-pushed the tighten_client_nodecache branch from dd98586 to 21fedf9 Compare September 18, 2026 15:59
Comment thread client/client.go
// Trim the full tile down to the size of the requested partial tile.
tile.Nodes = tile.Nodes[:wantSize]
default:
return nil, fmt.Errorf("invalid tile: expected %d or %d nodes, got %d", wantSize, layout.TileWidth, gotLen)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If wantSize is 256 and p = 0, the error message would become:

invalid tile: expected 256 or 256 nodes, got 255

Having 256 twice seems confusing.

Comment thread client/client.go
return otel.Trace(ctx, "tessera.client.nodecache.fetchTileNodes", tracer, func(ctx context.Context, span trace.Span) (map[compact.NodeID][]byte, error) {
tileRaw, err := n.getTile(ctx, tileLevel, tileIndex, p)
if err != nil {
return nil, fmt.Errorf("failed to fetch tile: %v", err)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change in L489 is ineffective because the os.ErrNotExist is not returned here.

Suggested change
return nil, fmt.Errorf("failed to fetch tile: %w", err)

Comment thread client/client_test.go

func TestNodeCacheHandlesInvalidRequest(t *testing.T) {
func TestNodeCache(t *testing.T) {
ctx := context.Background()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ctx := context.Background()
ctx := t.context()

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.

2 participants