tka: mark young AUMs as active even if the chain is long

Existing compaction logic seems to have had an assumption that
markActiveChain would cover a longer part of the chain than
markYoungAUMs. This prevented long, but fresh, chains, from being
compacted correctly.

Updates tailscale/corp#33537

Signed-off-by: Anton Tolchanov <anton@tailscale.com>
This commit is contained in:
Anton Tolchanov
2025-11-18 17:04:08 +00:00
committed by Anton Tolchanov
parent bd29b189fe
commit 04a9d25a54
2 changed files with 45 additions and 11 deletions

View File

@@ -15,6 +15,7 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"golang.org/x/crypto/blake2s"
"tailscale.com/types/key"
"tailscale.com/util/must"
)
@@ -601,3 +602,33 @@ func TestCompact(t *testing.T) {
}
}
}
func TestCompactLongButYoung(t *testing.T) {
ourPriv := key.NewNLPrivate()
ourKey := Key{Kind: Key25519, Public: ourPriv.Public().Verifier(), Votes: 1}
someOtherKey := Key{Kind: Key25519, Public: key.NewNLPrivate().Public().Verifier(), Votes: 1}
storage := &Mem{}
auth, _, err := Create(storage, State{
Keys: []Key{ourKey, someOtherKey},
DisablementSecrets: [][]byte{DisablementKDF(bytes.Repeat([]byte{0xa5}, 32))},
}, ourPriv)
if err != nil {
t.Fatalf("tka.Create() failed: %v", err)
}
genesis := auth.Head()
for range 100 {
upd := auth.NewUpdater(ourPriv)
must.Do(upd.RemoveKey(someOtherKey.MustID()))
must.Do(upd.AddKey(someOtherKey))
aums := must.Get(upd.Finalize(storage))
must.Do(auth.Inform(storage, aums))
}
lastActiveAncestor := must.Get(Compact(storage, auth.Head(), CompactionOptions{MinChain: 5, MinAge: time.Hour}))
if lastActiveAncestor != genesis {
t.Errorf("last active ancestor = %v, want %v", lastActiveAncestor, genesis)
}
}