diff --git a/go/delivery/assigner.go b/go/delivery/assigner.go index 7bb559e..6c5d8e2 100644 --- a/go/delivery/assigner.go +++ b/go/delivery/assigner.go @@ -322,10 +322,13 @@ type NodeWant struct { Words string `json:"words,omitempty"` } -// EncodeNodeWant is w as JSON at Version; it refuses a digest not of the sha256 form. +// EncodeNodeWant is w as JSON at Version; it refuses a digest not of the sha256 form. From ADR 0547's second milestone +// the node composes its own composition (§2) and its own want names none: an empty Composed is that want. func EncodeNodeWant(w NodeWant) ([]byte, error) { - if err := checkDigest(w.Composed, "the node's own want's composition digest"); err != nil { - return nil, err + if w.Composed != "" { + if err := checkDigest(w.Composed, "the node's own want's composition digest"); err != nil { + return nil, err + } } w.V = Version return json.Marshal(w) @@ -343,8 +346,10 @@ func DecodeNodeWant(data []byte) (NodeWant, error) { if err := d.Decode(&w); err != nil { return NodeWant{}, fmt.Errorf("delivery: a node's own want does not fit its shape: %w", err) } - if err := checkDigest(w.Composed, "the node's own want's composition digest"); err != nil { - return NodeWant{}, err + if w.Composed != "" { + if err := checkDigest(w.Composed, "the node's own want's composition digest"); err != nil { + return NodeWant{}, err + } } return w, nil } diff --git a/go/delivery/want_composed_test.go b/go/delivery/want_composed_test.go index 7c9d68d..98d3476 100644 --- a/go/delivery/want_composed_test.go +++ b/go/delivery/want_composed_test.go @@ -90,11 +90,17 @@ func TestTheNodesOwnWant(t *testing.T) { if err != nil || back != w { t.Errorf("node want came back %+v, %v", back, err) } - for _, bad := range []NodeWant{{}, {Composed: "sha256:1"}} { + for _, bad := range []NodeWant{{Composed: "sha256:1"}} { if _, err := EncodeNodeWant(bad); err == nil { t.Errorf("EncodeNodeWant(%+v) accepted", bad) } } + // ADR 0547 §2 (issue 1126): from the second milestone the node composes its own composition, and its want names none. + if raw, err := EncodeNodeWant(NodeWant{Words: "the node composes its own"}); err != nil { + t.Errorf("a node want naming no composition: %v", err) + } else if back, err := DecodeNodeWant(raw); err != nil || back.Composed != "" { + t.Errorf("a node want naming no composition came back %+v, %v", back, err) + } if _, err := DecodeNodeWant([]byte(`{"v":1,"composed":"` + hashOf('2') + `","fp":"` + fp2of('a') + `"}`)); err == nil { t.Errorf("a node want naming a fingerprint was read") }