Remove what only served the controller's compositions: the own-secret resync, the shadow's wants watch and the vault key's follower
Every node composes its own since group A (issue 1126), so the resync that handed the vault an own secret's value while a node applied the controller's compositions never runs, the shadow's answers read no want, and nothing follows the heard vault key any more. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
@@ -1057,7 +1057,7 @@ func TestTheNodeComposesItsWantsFromTheBus(t *testing.T) {
|
||||
go func() { sh.Keep(sctx, func(int) time.Duration { return 5 * time.Millisecond }); close(kept) }()
|
||||
time.Sleep(30 * time.Millisecond)
|
||||
sb.missing(delivery.PlacementCandidatesBucket, false)
|
||||
sb.made(7)
|
||||
sb.made(6)
|
||||
rec, _ := delivery.EncodeHaveNode(delivery.HaveNode{Record: &delivery.NodeRecord{Node: "n1", TunnelKey: "k", SealingKey: "sk", Capabilities: []string{"systemd"}}})
|
||||
tp, _ := delivery.EncodePlacement(trunk)
|
||||
sb.put(delivery.PlacementBucket, "placement.n1", tp, 1)
|
||||
@@ -1321,7 +1321,7 @@ func TestTheNodeComposesItsWantsFromTheBus(t *testing.T) {
|
||||
nctx, ncancel := context.WithCancel(ctx)
|
||||
defer ncancel()
|
||||
go func() { _ = nsh.Run(nctx) }()
|
||||
nb.made(7)
|
||||
nb.made(6)
|
||||
nb.put(delivery.PlacementBucket, "placement.n1", tp, 1)
|
||||
nb.put(delivery.HaveBucket, "n1.node", rec, 1)
|
||||
for name, m := range mods {
|
||||
@@ -1335,19 +1335,19 @@ func TestTheNodeComposesItsWantsFromTheBus(t *testing.T) {
|
||||
oldRaw, _ := delivery.EncodePlacementCandidate(delivery.PlacementCandidate{Proposal: "older", Placement: &trunk})
|
||||
oldKey, _ := delivery.PlacementCandidateKey("older", "n1")
|
||||
nb.put(delivery.PlacementCandidatesBucket, oldKey, oldRaw, 2)
|
||||
for _, bucket := range []string{delivery.PlacementCandidatesBucket, delivery.PlacementBucket, delivery.HaveBucket, delivery.ModulesBucket, ResolvedBucket, delivery.BuilderBuildsBucket} {
|
||||
for _, bucket := range []string{delivery.PlacementCandidatesBucket, delivery.PlacementBucket, delivery.HaveBucket, delivery.ModulesBucket, delivery.BuilderBuildsBucket} {
|
||||
nb.send(bucket, agent.Update{Caught: true})
|
||||
}
|
||||
select {
|
||||
case a := <-nanswered:
|
||||
if g := a["same"]; g.Verdict != delivery.CandidateRefused || !strings.Contains(g.Refused, delivery.AssignerWantsBucket) || g.Proposal != "same" {
|
||||
t.Errorf("a shadow waiting for its wants answered %+v", g)
|
||||
if g := a["same"]; g.Verdict != delivery.CandidateRefused || !strings.Contains(g.Refused, ResolvedBucket) || g.Proposal != "same" {
|
||||
t.Errorf("a shadow waiting for its values answered %+v", g)
|
||||
}
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("a shadow not ready after its wait answered nothing")
|
||||
}
|
||||
nmu.Lock()
|
||||
if !strings.Contains(strings.Join(nsaid, "\n"), "this node answers no placement candidate yet: the node has not read "+delivery.AssignerWantsBucket) {
|
||||
if !strings.Contains(strings.Join(nsaid, "\n"), "this node answers no placement candidate yet: the node has not read "+ResolvedBucket) {
|
||||
t.Errorf("a shadow not ready said %q", nsaid)
|
||||
}
|
||||
nmu.Unlock()
|
||||
@@ -1355,7 +1355,7 @@ func TestTheNodeComposesItsWantsFromTheBus(t *testing.T) {
|
||||
scancel()
|
||||
<-kept
|
||||
setFor(t, &slowAfter, time.Nanosecond) // every answer is slow: said, and noted in words that do not move with the time
|
||||
nb.send(delivery.AssignerWantsBucket, agent.Update{Caught: true})
|
||||
nb.send(ResolvedBucket, agent.Update{Caught: true})
|
||||
select {
|
||||
case a := <-nanswered:
|
||||
if g := a["same"]; g.Verdict != delivery.CandidateSame || !strings.Contains(g.Note, "this answer took over") {
|
||||
|
||||
@@ -32,8 +32,6 @@ type Shadow struct {
|
||||
mu sync.Mutex
|
||||
candidates map[string]map[string]candidateKey // by proposal, by node
|
||||
answers map[string]delivery.CandidateAnswer
|
||||
// wants are the node's wants by module (agent.NodeModule for its own); a change of one answers again.
|
||||
wants map[string]delivery.Want
|
||||
// ran is, by module, the digest the module's have says runs: what runs, where the agent's list holds only the copy
|
||||
// from the declaration kept before the switch (issue 1126, probe #532 on shanks).
|
||||
ran map[string]string
|
||||
@@ -64,7 +62,7 @@ type answeredAt struct {
|
||||
}
|
||||
|
||||
// inputWords name the shadow's inputs, in Run's order, as an answer says which of them woke it.
|
||||
var inputWords = [...]string{"the candidate", "placement", "records", "modules", "values", "haves", "wants"}
|
||||
var inputWords = [...]string{"the candidate", "placement", "records", "modules", "values", "haves"}
|
||||
|
||||
// wokenBy says what moved between the answer a proposal stands at (had, when done) and the one about to be composed (at):
|
||||
// its first answer, a retry, its candidate's revisions, or the inputs that changed, by their words.
|
||||
@@ -99,7 +97,7 @@ type candidateKey struct {
|
||||
// NewShadow is the shadow composer of one node; answer writes the node's answers into its own have key.
|
||||
func NewShadow(env Env, answer func(ctx context.Context, answers map[string]delivery.CandidateAnswer)) *Shadow {
|
||||
return &Shadow{c: New(env), answer: answer, candidates: map[string]map[string]candidateKey{},
|
||||
answers: map[string]delivery.CandidateAnswer{}, wants: map[string]delivery.Want{}, ran: map[string]string{}}
|
||||
answers: map[string]delivery.CandidateAnswer{}, ran: map[string]string{}}
|
||||
}
|
||||
|
||||
// Keep runs the shadow until ctx ends, beginning again after backoff(try) whenever it stops: an input it cannot watch
|
||||
@@ -141,7 +139,6 @@ func (s *Shadow) Run(ctx context.Context) error {
|
||||
defer cancel()
|
||||
s.mu.Lock()
|
||||
s.candidates = map[string]map[string]candidateKey{}
|
||||
s.wants = map[string]delivery.Want{}
|
||||
s.ran = map[string]string{}
|
||||
s.answered = map[string]answeredAt{}
|
||||
s.moved = [len(inputWords)]uint64{}
|
||||
@@ -159,8 +156,6 @@ func (s *Shadow) Run(ctx context.Context) error {
|
||||
{ResolvedBucket, node + ".>", (*Composer).takeValue, nil},
|
||||
// What this node runs moved: an apply ends in its module's have.
|
||||
{delivery.HaveBucket, node + ".>", nil, nil},
|
||||
// Its wants.
|
||||
{delivery.AssignerWantsBucket, "want." + node + ".>", nil, nil},
|
||||
}
|
||||
type tagged struct {
|
||||
in int
|
||||
@@ -225,8 +220,6 @@ func (s *Shadow) Run(ctx context.Context) error {
|
||||
case t.in == 5:
|
||||
folded := c.takeModuleHave(t.u)
|
||||
changed = s.takeRan(t.u) || folded
|
||||
case t.in == 6:
|
||||
changed = s.takeWant(t.u)
|
||||
default:
|
||||
changed = c.takeChanged(ins[t.in], t.u)
|
||||
}
|
||||
@@ -685,33 +678,6 @@ func sameAnswer(a, b delivery.CandidateAnswer) bool {
|
||||
return errA == nil && errB == nil && string(x) == string(y)
|
||||
}
|
||||
|
||||
// takeWant takes one of the node's wants, and says whether it changed.
|
||||
func (s *Shadow) takeWant(u agent.Update) bool {
|
||||
module := ""
|
||||
var w delivery.Want
|
||||
if _, err := delivery.ParseWantNodeKey(u.Key); err == nil {
|
||||
module = agent.NodeModule
|
||||
} else if node, m, err := delivery.ParseWantKey(u.Key); err == nil && node == s.c.env.Node {
|
||||
module = m
|
||||
if !u.Deleted {
|
||||
if w, err = delivery.DecodeWant(u.Value); err != nil || w.Removed || w.FP == "" {
|
||||
u.Deleted = true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
old, had := s.wants[module]
|
||||
if u.Deleted {
|
||||
delete(s.wants, module)
|
||||
return had
|
||||
}
|
||||
s.wants[module] = w
|
||||
return !had || old.FP != w.FP
|
||||
}
|
||||
|
||||
// sameValue says whether two sealed values open, with this node's key, to the same value; unknown when either does not
|
||||
// open (or the node holds no opener). Only the comparison leaves: never a value (issue 1126, the shadow shows its work).
|
||||
func (c *Composer) sameValue(a, b string) (same, known bool) {
|
||||
|
||||
Reference in New Issue
Block a user