-
Notifications
You must be signed in to change notification settings - Fork 179
fix(zetaclient): snapshot telemetry peer data #4589
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| package metrics | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/libp2p/go-libp2p/core/peer" | ||
| "github.com/stretchr/testify/require" | ||
| ) | ||
|
|
||
| func TestTelemetryServerCopiesPingRTT(t *testing.T) { | ||
| telemetry := NewTelemetryServer() | ||
| peerID := peer.ID("peer-a") | ||
|
|
||
| rtt := map[peer.ID]int64{peerID: 10} | ||
| telemetry.SetPingRTT(rtt) | ||
|
|
||
| rtt[peerID] = 20 | ||
| require.Equal(t, int64(10), telemetry.GetPingRTT()[peerID]) | ||
|
|
||
| snapshot := telemetry.GetPingRTT() | ||
| snapshot[peerID] = 30 | ||
| require.Equal(t, int64(10), telemetry.GetPingRTT()[peerID]) | ||
| } | ||
|
|
||
| func TestTelemetryServerCopiesConnectedPeers(t *testing.T) { | ||
| telemetry := NewTelemetryServer() | ||
| peerA := peer.ID("peer-a") | ||
| peerB := peer.ID("peer-b") | ||
| peerC := peer.ID("peer-c") | ||
|
|
||
| peers := []peer.AddrInfo{{ID: peerA}} | ||
| telemetry.SetConnectedPeers(peers) | ||
|
|
||
| peers[0].ID = peerB | ||
| require.Equal(t, peerA, telemetry.GetConnectedPeers()[0].ID) | ||
|
|
||
| snapshot := telemetry.GetConnectedPeers() | ||
| snapshot[0].ID = peerC | ||
| require.Equal(t, peerA, telemetry.GetConnectedPeers()[0].ID) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,14 +43,14 @@ func HealthcheckWorker(ctx context.Context, server *tss.Server, p HealthcheckPro | |
|
|
||
| // Ping & collect round trip time | ||
| var ( | ||
| host = server.GetP2PHost() | ||
| pingRTT = make(map[peer.ID]int64) | ||
| mu = sync.Mutex{} | ||
| host = server.GetP2PHost() | ||
| mu = sync.Mutex{} | ||
| ) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Prompt To Fix With AIThis is a comment left during a code review.
Path: zetaclient/tss/healthcheck.go
Line: 44-48
Comment:
`mu` is now only used inside `pinger` to guard concurrent goroutine writes to the per-invocation `pingRTT` map. Since `pingRTT` is local to each closure call, `mu` no longer needs to live in the outer scope — moving it inside `pinger` would make the ownership clear and avoid the appearance that it protects shared state across ticks. If the ticker ever ran overlapping invocations, the shared `mu` would also impose false contention between two independent ping rounds.
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is already addressed on the current branch: |
||
|
|
||
| const pingTimeout = 5 * time.Second | ||
|
|
||
| pinger := func(ctx context.Context, _ *ticker.Ticker) error { | ||
| pingRTT := make(map[peer.ID]int64) | ||
| var wg sync.WaitGroup | ||
| for _, peerID := range p.WhitelistPeers { | ||
| if peerID == host.ID() { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
peer.AddrInfohas anAddrs []Multiaddrslice field that is not deep-copied here.append([]peer.AddrInfo(nil), peers...)copies each struct by value, soIDis isolated correctly, but theAddrsslice header in every copied element still shares the same backing array as the original. If any caller replaces an element insnapshot[i].Addrs, that change writes through to the stored slice. For the current HTTP-handler read pattern this is harmless, but it leaves the isolation guarantee incomplete compared to the intent of the rest of this PR.Prompt To Fix With AI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in
2f88a0e0:copyConnectedPeersnow allocates a newpeer.AddrInfoslice and deep-copies each non-nilAddrsslice, so the stored telemetry snapshot no longer shares address slice backing arrays with callers.