diff --git a/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/approval.go b/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/approval.go index 76b2cc0a..e12a85ab 100644 --- a/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/approval.go +++ b/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/approval.go @@ -808,23 +808,13 @@ func gateAsk(group string, heads []sdk.Head, asking int, ask oc.Ask) (sdk.Ask, e } // askOf reads the router's ask a gate ask carries and holds it to what the gate owes: the id its group, heads and asking -// give, and at least one option. kvOperator.Ask holds every ask it writes to it, too. +// give, and at least one option (occ.Carried). kvOperator.Ask holds every ask it writes to it, too. func askOf(a sdk.Ask) (oc.Ask, error) { - var ask oc.Ask - if err := json.Unmarshal(a.Ask, &ask); err != nil { - return oc.Ask{}, fmt.Errorf("the ask is not a router's ask: %w", err) - } key, err := sdk.MergeAskKey(a.Group, a.Heads) if err != nil { return oc.Ask{}, fmt.Errorf("an ask needs its group and at least one pull request's head: %w", err) } - if want := sdk.AskingID(key, a.Asking); ask.ID != want { - return oc.Ask{}, fmt.Errorf("the ask's id %q is not %q, the id its group, heads and asking %d give", ask.ID, want, a.Asking) - } - if len(ask.Options) == 0 { - return oc.Ask{}, fmt.Errorf("the ask has no option") - } - return ask, nil + return occ.Carried(a.Ask, sdk.AskingID(key, a.Asking)) } // kvOperator is the operator over the runtime: the ask is a key of the gate's bucket asks, the answer a key of the teller's diff --git a/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/approval_test.go b/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/approval_test.go index 20ca5ff6..fcfa8933 100644 --- a/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/approval_test.go +++ b/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/approval_test.go @@ -495,9 +495,10 @@ func TestTheGateRefusesAnAskWithAnotherIdOrNoOption(t *testing.T) { }{ {"the first asking's id", 1, oc.Ask{ID: sdk.AskingID(key, 1), Options: []oc.Option{option}}, ""}, {"the second asking's id", 2, oc.Ask{ID: sdk.AskingID(key, 2), Options: []oc.Option{option}}, ""}, - {"another id", 1, oc.Ask{ID: "another-id", Options: []oc.Option{option}}, "is not"}, - {"the first asking's id at the second asking", 2, oc.Ask{ID: sdk.AskingID(key, 1), Options: []oc.Option{option}}, "is not"}, - {"no option", 1, oc.Ask{ID: sdk.AskingID(key, 1)}, "no option"}, + // The refusals are operator-channel's client's (occ.Carried), held to the id the gate's key and asking give. + {"another id", 1, oc.Ask{ID: "another-id", Options: []oc.Option{option}}, "the id it was kept under"}, + {"the first asking's id at the second asking", 2, oc.Ask{ID: sdk.AskingID(key, 1), Options: []oc.Option{option}}, "the id it was kept under"}, + {"no option", 1, oc.Ask{ID: sdk.AskingID(key, 1)}, "offers no option"}, } { a, err := gateAsk("feat/g", heads, c.asking, c.ask) if c.refuse == "" { @@ -515,4 +516,9 @@ func TestTheGateRefusesAnAskWithAnotherIdOrNoOption(t *testing.T) { t.Errorf("%s: kvOperator wrote it (%v, %v)", c.name, err, a) } } + // A value that carries no router's ask is refused before it is written. + if err := (kvOperator{}).Ask(key, sdk.Ask{Group: "feat/g", Heads: heads, Asking: 1, Ask: json.RawMessage(`"an ask"`)}); err == nil || + !strings.Contains(err.Error(), "carries no operator-channel ask") { + t.Errorf("a value carrying no ask: %v", err) + } }