From 0be0ffd6159e7efac1a6a5bc0740bca4f35fecce Mon Sep 17 00:00:00 2001 From: jochen Date: Sun, 25 Oct 2026 21:47:30 +0100 Subject: [PATCH] =?UTF-8?q?Compare=20the=20have's=20user=20list=20by=20wha?= =?UTF-8?q?t=20it=20says,=20so=20a=20have=20is=20not=20written=20again=20f?= =?UTF-8?q?or=20the=20same=20list=20(ADR=200547=20=C2=A78)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go/delivery/delivery.go | 14 +++++++++++++- go/delivery/delivery_test.go | 12 ++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/go/delivery/delivery.go b/go/delivery/delivery.go index 769420c..8fccfaa 100644 --- a/go/delivery/delivery.go +++ b/go/delivery/delivery.go @@ -491,7 +491,19 @@ func DecodePulse(data []byte) (Pulse, error) { } // SameHave says whether two haves are the same value, so a writer writes only when they differ. -func SameHave(a, b Have) bool { return a == b } +func SameHave(a, b Have) bool { + ua, ub := a.UserList, b.UserList + a.UserList, b.UserList = nil, nil + if a != b || (ua == nil) != (ub == nil) { + return false + } + if ua == nil { + return true + } + x, y := *ua, *ub + x.At, y.At = time.Time{}, time.Time{} + return x == y && ua.At.Equal(ub.At) +} // SameHaveNode says whether two node facts are the same value, comparing each carried JSON without its spacing. func SameHaveNode(a, b HaveNode) bool { diff --git a/go/delivery/delivery_test.go b/go/delivery/delivery_test.go index 3b1ac09..a0aba8d 100644 --- a/go/delivery/delivery_test.go +++ b/go/delivery/delivery_test.go @@ -294,6 +294,18 @@ func TestSame(t *testing.T) { if SameHave(a, b) { t.Error("different haves same") } + // The user list is compared by what it says, never by where it is held (ADR 0547 ยง8). + at := time.Date(2026, 10, 25, 21, 0, 0, 0, time.UTC) + ua, ub := a, a + ua.UserList = &UserListWritten{Source: "k", Revision: 1, Wanted: "sha256:a", Digest: "sha256:a", Users: 2, At: at} + ub.UserList = &UserListWritten{Source: "k", Revision: 1, Wanted: "sha256:a", Digest: "sha256:a", Users: 2, At: at.In(time.Local)} + if !SameHave(ua, ub) || SameHave(ua, a) { + t.Error("equal user lists differ, or one said and one not are the same") + } + ub.UserList.Revision = 2 + if SameHave(ua, ub) { + t.Error("different user lists same") + } n := HaveNode{V: 1, Busy: json.RawMessage(`true`)} if !SameHaveNode(n, HaveNode{V: 1, Busy: json.RawMessage(`true`)}) || SameHaveNode(n, HaveNode{V: 1}) { t.Error("have node")