mesh-enrolment: keep the tunnel key in delivery.Enrolment's own field
mesh-sdk 22c03af carries the machine's tunnel key on the enrolment (OverlayKey, overlay-key, required at every stage), so the holder's wrapper that kept it beside the contract is gone; the wire is unchanged. Test fixtures give the seeded enrolments a real tunnel key, which the contract now requires. (issue 774) Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
@@ -50,18 +50,11 @@ const (
|
||||
StageRedeeming = delivery.EnrolmentRedeeming
|
||||
)
|
||||
|
||||
// Reservation is the seat's state contract for an address key (delivery.EnrolmentAddress).
|
||||
type Reservation = delivery.EnrolmentAddress
|
||||
|
||||
// Enrolment is a node key: the seat's state contract (delivery.Enrolment) and the machine's tunnel key given at issue, which
|
||||
// the node enters placement with on the operator's yes and which redeem must present again (the operator's decision of
|
||||
// 2026-11-02 01:05). The contract does not carry the tunnel key yet: it is kept as one more member of the same JSON object,
|
||||
// which every reader of the contract decodes as before (delivery's decode ignores a member it does not know). Once
|
||||
// delivery.Enrolment carries `overlay-key` this wrapper goes.
|
||||
type Enrolment struct {
|
||||
delivery.Enrolment
|
||||
OverlayKey string `json:"overlay-key,omitempty"`
|
||||
}
|
||||
// Enrolment and Reservation are the seat's state contract (delivery.Enrolment, delivery.EnrolmentAddress).
|
||||
type (
|
||||
Enrolment = delivery.Enrolment
|
||||
Reservation = delivery.EnrolmentAddress
|
||||
)
|
||||
|
||||
const (
|
||||
nodePrefix = "node."
|
||||
@@ -85,33 +78,12 @@ func CheckNode(node string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func decodeEnrolment(raw []byte) (Enrolment, error) {
|
||||
e, err := delivery.DecodeEnrolment(raw)
|
||||
if err != nil {
|
||||
return Enrolment{}, err
|
||||
}
|
||||
var tunnel struct {
|
||||
OverlayKey string `json:"overlay-key"`
|
||||
}
|
||||
_ = json.Unmarshal(raw, &tunnel)
|
||||
return Enrolment{Enrolment: e, OverlayKey: tunnel.OverlayKey}, nil
|
||||
}
|
||||
func decodeEnrolment(raw []byte) (Enrolment, error) { return delivery.DecodeEnrolment(raw) }
|
||||
|
||||
// Encode is a value of the bucket as the seat's contract writes it: an Enrolment or a Reservation checked and versioned.
|
||||
func Encode(v any) (json.RawMessage, error) {
|
||||
switch x := v.(type) {
|
||||
case Enrolment:
|
||||
raw, err := delivery.EncodeEnrolment(x.Enrolment)
|
||||
if err != nil || x.OverlayKey == "" {
|
||||
return raw, err
|
||||
}
|
||||
var obj map[string]json.RawMessage
|
||||
if err := json.Unmarshal(raw, &obj); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
obj["overlay-key"], _ = json.Marshal(x.OverlayKey)
|
||||
return json.Marshal(obj)
|
||||
case delivery.Enrolment:
|
||||
return delivery.EncodeEnrolment(x)
|
||||
case Reservation:
|
||||
return delivery.EncodeEnrolmentAddress(x.Node)
|
||||
|
||||
@@ -149,7 +149,8 @@ func (h *Holder) warrantOf(e Enrolment) (delivery.AddNodeWarrant, error) {
|
||||
return delivery.AddNodeWarrant{Node: e.Node, Address: e.Address, Ask: e.Ask, Warrant: warrant}, nil
|
||||
}
|
||||
|
||||
// checkTunnelKey says a tunnel key is a WireGuard public key, as `nox-mesh-host key` prints it: 32 bytes in standard base64.
|
||||
// checkTunnelKey says a tunnel key is a WireGuard public key, as `nox-mesh-host key` prints it: 32 bytes in standard base64
|
||||
// (as delivery.Enrolment requires it too); said here so issue names it among its findings.
|
||||
func checkTunnelKey(k string) error {
|
||||
raw, err := base64.StdEncoding.DecodeString(strings.TrimSpace(k))
|
||||
if err != nil || len(raw) != 32 {
|
||||
|
||||
@@ -98,8 +98,8 @@ func (h *Holder) Issue(caller, node, why, overlayKey string, lasts time.Duration
|
||||
return IssueAnswer{}, fmt.Errorf("no enrolment of %q is issued: %s", node, strings.Join(findings, "; "))
|
||||
}
|
||||
now := h.now()
|
||||
e := Enrolment{Enrolment: delivery.Enrolment{Node: node, Why: strings.TrimSpace(why), Caller: caller, Stage: StageAsked,
|
||||
Issued: now, Expires: now.Add(lasts)}, OverlayKey: overlayKey}
|
||||
e := Enrolment{Node: node, Why: strings.TrimSpace(why), Caller: caller, Stage: StageAsked, Issued: now, Expires: now.Add(lasts),
|
||||
OverlayKey: overlayKey}
|
||||
e.Ask = "enrol-" + node + "-" + now.UTC().Format("20060102t150405")
|
||||
skip := map[string]bool{}
|
||||
for {
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
// redeemArgs are a node's redeem call with a proof signed by the key seeded, over the keys given.
|
||||
func redeemArgs(node string, seed byte, serving string) delivery.Redeem {
|
||||
return redeemArgsWith(node, seed, serving, "overlay-"+node)
|
||||
return redeemArgsWith(node, seed, serving, tunnelKey)
|
||||
}
|
||||
|
||||
// redeemArgsWith is redeemArgs presenting the tunnel key given.
|
||||
|
||||
@@ -13,8 +13,8 @@ import (
|
||||
|
||||
// seed writes an open enrolment of node at stage, with its address key, as the holder would have.
|
||||
func (r *rig) seed(node, address string, stage string) {
|
||||
e := Enrolment{Enrolment: delivery.Enrolment{Node: node, Address: address, Why: "a new machine", Caller: "person.operator", Ask: "ask-" + node,
|
||||
Stage: stage, Issued: r.now.Add(-time.Minute), Expires: r.now.Add(time.Hour)}, OverlayKey: "overlay-" + node}
|
||||
e := Enrolment{Node: node, Address: address, Why: "a new machine", Caller: "person.operator", Ask: "ask-" + node,
|
||||
Stage: stage, Issued: r.now.Add(-time.Minute), Expires: r.now.Add(time.Hour), OverlayKey: tunnelKey}
|
||||
if stage == StageRedeeming {
|
||||
e.KeysDigest = delivery.KeysDigest("pk", "ov", "se", "sv")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user