node-engine client: the exported fingerprint key part is mesh-catalog's client's, the codec checks the field's form itself (a client imports no other seat's client; ADR 0625 §4, ADR 0634 §2; issue 1966)
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
@@ -20,16 +20,18 @@ import (
|
||||
// alone, so the encoding keeps the field order its first writer used, which the contract's generated type (fields sorted)
|
||||
// does not: the wire structs below hold it.
|
||||
|
||||
// SourcePrefix is the start of a fingerprint of the new form, `src2:` and 64 lowercase hex digits.
|
||||
const SourcePrefix = "src2:"
|
||||
// sourcePrefix opens a source fingerprint of the form mesh-catalog's client defines (meshcatalogclient.SourcePrefix2,
|
||||
// KeyPart); a client imports no other seat's client (ADR 0625 §4), so a composition's field is checked here for that form
|
||||
// only, and a caller makes the key part with meshcatalogclient.KeyPart.
|
||||
const sourcePrefix = "src2:"
|
||||
|
||||
// FingerprintKeyPart is a new-form fingerprint as the key part of ComposedKey: its 64 hex digits without the prefix.
|
||||
func FingerprintKeyPart(fp string) (string, error) {
|
||||
part, ok := strings.CutPrefix(fp, SourcePrefix)
|
||||
// checkFingerprintForm refuses a fingerprint that is not `src2:` and 64 lowercase hex digits, naming it.
|
||||
func checkFingerprintForm(fp string) error {
|
||||
part, ok := strings.CutPrefix(fp, sourcePrefix)
|
||||
if !ok || !keys.IsHex64(part) {
|
||||
return "", fmt.Errorf("node-engine: %q is not a fingerprint of the new form, %s and 64 lowercase hex digits", fp, SourcePrefix)
|
||||
return fmt.Errorf("node-engine: %q is not a fingerprint of the new form, %s and 64 lowercase hex digits", fp, sourcePrefix)
|
||||
}
|
||||
return part, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// Composition is one module's resources composed for one node at one fingerprint, or, with Module and FP empty, the node's
|
||||
@@ -171,11 +173,10 @@ func (c Composition) check() error {
|
||||
return fmt.Errorf("node-engine: the node's own composition carries no plan and no refusal: only a module's does")
|
||||
}
|
||||
} else {
|
||||
part, err := FingerprintKeyPart(c.FP)
|
||||
if err != nil {
|
||||
if err := checkFingerprintForm(c.FP); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := ComposedKey(c.Node, c.Module, part); err != nil {
|
||||
if _, err := ComposedKey(c.Node, c.Module, strings.TrimPrefix(c.FP, sourcePrefix)); err != nil {
|
||||
return err
|
||||
}
|
||||
if !ownIsEmpty(c.Own) {
|
||||
|
||||
@@ -36,7 +36,7 @@ func captured(t *testing.T) (account string, byModule map[string][]json.RawMessa
|
||||
return c.Account, byModule
|
||||
}
|
||||
|
||||
func fp(n int) string { return SourcePrefix + fmt.Sprintf("%064x", n) }
|
||||
func fp(n int) string { return sourcePrefix + fmt.Sprintf("%064x", n) }
|
||||
|
||||
// TestCompositionDigests: a composition's digest is the one the first writer computed (the values are the digests
|
||||
// mesh-sdk's delivery package gave for the same compositions when it moved here), whatever order the contract's generated
|
||||
|
||||
Reference in New Issue
Block a user