go/asks: an ask may carry its Details whole, for a channel that proves who answers (hq issue 383)
mesh/merge-gate head f4745447ba6d merged into trunk a0fc82fdcd7c — pass, with a note: builds mesh-sdk (+40 dependent(s)) → ace, g14, novox, shanks; no bus …
mesh/repo-check head f4745447ba6d merged into trunk a0fc82fdcd7c — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (typescript)…
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate head f4745447ba6d merged into trunk a0fc82fdcd7c — pass, with a note: builds mesh-sdk (+40 dependent(s)) → ace, g14, novox, shanks; no bus …
mesh/repo-check head f4745447ba6d merged into trunk a0fc82fdcd7c — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (typescript)…
mesh/delivery superseded: a newer head of the same pull request
The review of mesh-controller #304: a settings proposal with more than three keys showed only the names of the rest, and its Details could carry no value under the content rule, so Approve bound values the operator never saw. WholeDetails carries every value whole for the note on a proving channel, held to the secret rule alone, as Whole is; it is digested only when given.
This commit is contained in:
@@ -174,6 +174,12 @@ func (a Ask) Digest() string {
|
||||
canonical(&b, a.Whole)
|
||||
canonical(&b, a.Details)
|
||||
}
|
||||
// WholeDetails (novox/hq issue 383, the review of mesh-controller #304) follows only when given, so every
|
||||
// ask without it digests as it did before it existed.
|
||||
if a.WholeDetails != "" {
|
||||
canonical(&b, "whole-details")
|
||||
canonical(&b, a.WholeDetails)
|
||||
}
|
||||
sum := sha256.Sum256([]byte(b.String()))
|
||||
return "sha256:" + hex.EncodeToString(sum[:])
|
||||
}
|
||||
@@ -207,6 +213,12 @@ type Ask struct {
|
||||
// (Message.Note), after what the ask's options do and when it expires — never in its body (novox/hq
|
||||
// issue 639).
|
||||
Details string `json:"details,omitempty"`
|
||||
// WholeDetails are the Details with their exact values whole, shown in place of Details where Whole is shown
|
||||
// in place of the explanation (a kind that proves who answers, given the ask's answers): every value an
|
||||
// approval sets, whole, so the person reads exactly what they approve (novox/hq issue 383). Held, like
|
||||
// Whole, to the secret rule alone; the router refuses the ask when a secret's shape is left in it. Empty,
|
||||
// Details are shown everywhere.
|
||||
WholeDetails string `json:"whole-details,omitempty"`
|
||||
}
|
||||
|
||||
// What an ask's explanation is held to, so it reads at a glance on a phone (novox/hq issue 639): a summary
|
||||
|
||||
+22
-2
@@ -253,8 +253,8 @@ func TestDigestsAreCanonicalOverNamedFields(t *testing.T) {
|
||||
t.Error("changing Whole beside Details left the digest the same")
|
||||
}
|
||||
// A field added to Ask or Option without being added to Digest fails here.
|
||||
if n := reflect.TypeOf(Ask{}).NumField(); n != 11 {
|
||||
t.Errorf("Ask has %d fields, and Digest covers 11: add the new one to Digest and to this test", n)
|
||||
if n := reflect.TypeOf(Ask{}).NumField(); n != 12 {
|
||||
t.Errorf("Ask has %d fields, and Digest covers 12: add the new one to Digest and to this test", n)
|
||||
}
|
||||
if n := reflect.TypeOf(Option{}).NumField(); n != 5 {
|
||||
t.Errorf("Option has %d fields, and Digest covers 5: add the new one to Digest and to this test", n)
|
||||
@@ -317,3 +317,23 @@ func TestAMessageCarriesItsNoteApart(t *testing.T) {
|
||||
t.Fatalf("an empty note is encoded: %s", raw)
|
||||
}
|
||||
}
|
||||
|
||||
// WholeDetails is digested when given, and an ask without it digests as before it existed: a router and an asker
|
||||
// of different builds still agree on every such ask.
|
||||
func TestWholeDetailsAreDigestedOnlyWhenGiven(t *testing.T) {
|
||||
a := Ask{ID: "a", Headline: "h", Explanation: "e", Details: "d"}
|
||||
before := a.Digest()
|
||||
a.WholeDetails = "+ shares: media=/storage/media"
|
||||
if a.Digest() == before {
|
||||
t.Fatal("the whole details are not in the digest")
|
||||
}
|
||||
b := a
|
||||
b.WholeDetails = "+ shares: media=/storage/other"
|
||||
if a.Digest() == b.Digest() {
|
||||
t.Fatal("two whole details digest the same")
|
||||
}
|
||||
a.WholeDetails = ""
|
||||
if a.Digest() != before {
|
||||
t.Fatal("an ask without whole details digests otherwise than before")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user