From 48aaecf556c5424236baa7e176ecae7e66d0c3d6 Mon Sep 17 00:00:00 2001 From: jochen Date: Sun, 25 Oct 2026 01:50:00 +0200 Subject: [PATCH] List a node's own want among the assigner's wants, never as unreadable (issue 1945) --- .../mesh-delivery-view/internal/view/read.go | 10 +++++- .../internal/view/wants_test.go | 34 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/modules/mesh-delivery-view/internal/view/read.go b/modules/mesh-delivery-view/internal/view/read.go index bac6085..55ab022 100644 --- a/modules/mesh-delivery-view/internal/view/read.go +++ b/modules/mesh-delivery-view/internal/view/read.go @@ -342,7 +342,8 @@ const ( HavesReadTool = "node_haves" ) -// WantsAnswer is the answer of assigner_wants: the wants by key (`want..`) and the holds by key +// WantsAnswer is the answer of assigner_wants: the wants by key (`want..`, a node's own `want..node` +// among them) and the holds by key // (`held..`), each as stored, and the keys that are neither. type WantsAnswer struct { Wants map[string]json.RawMessage `json:"wants"` @@ -394,6 +395,13 @@ func (r Reader) Wants(node, module string) (WantsAnswer, error) { } continue } + // A node's own want, want..node (ADR 0539 clause 6): listed with the wants, under the module name "node". + if n, err := delivery.ParseWantNodeKey(k); err == nil { + if (node == "" || n == node) && (module == "" || module == "node") { + out.Wants[k] = raw + } + continue + } if m, _, err := delivery.ParseHeldKey(k); err == nil { if node == "" && (module == "" || m == module) { out.Held[k] = raw diff --git a/modules/mesh-delivery-view/internal/view/wants_test.go b/modules/mesh-delivery-view/internal/view/wants_test.go index 42832ef..abc4fd4 100644 --- a/modules/mesh-delivery-view/internal/view/wants_test.go +++ b/modules/mesh-delivery-view/internal/view/wants_test.go @@ -1,6 +1,7 @@ package view import ( + "encoding/json" "strings" "testing" @@ -346,3 +347,36 @@ func TestMotionIsSaidOnlyOnceTheBucketsHaveBeenRead(t *testing.T) { t.Errorf("said %q", types(said)) } } + +// assigner_wants lists a node's own want (want..node, ADR 0539 clause 6) among the wants, and never as unreadable: +// on 2026-10-25 every node's own want was listed unreadable, though its value was what the assigner writes (issue 1945). +func TestTheWantsListANodesOwnWant(t *testing.T) { + own, err := delivery.WantNodeKey("ace") + if err != nil { + t.Fatal(err) + } + value, err := delivery.EncodeNodeWant(delivery.NodeWant{Composed: "sha256:" + strings.Repeat("d", 64)}) + if err != nil { + t.Fatal(err) + } + moduleKey, _ := delivery.WantKey("ace", "web") + moduleValue, _ := delivery.EncodeWant(delivery.Want{FP: fpNew, Composed: "sha256:" + strings.Repeat("c", 64)}) + state := map[string][]byte{own: value, moduleKey: moduleValue} + r := Reader{WantsState: StateRead{ + Keys: func() ([]string, error) { return []string{own, moduleKey}, nil }, + Get: func(k string) (json.RawMessage, error) { return state[k], nil }, + }} + got, err := r.Wants("", "") + if err != nil { + t.Fatal(err) + } + if len(got.Unreadable) != 0 || got.Wants[own] == nil || got.Wants[moduleKey] == nil { + t.Fatalf("the wants: %v, unreadable %v", got.Wants, got.Unreadable) + } + if got, _ := r.Wants("g14", ""); len(got.Wants) != 0 { + t.Errorf("another node's wants: %v", got.Wants) + } + if got, _ := r.Wants("ace", "web"); got.Wants[own] != nil { + t.Errorf("the node's own want was listed under the module web") + } +}