Merge pull request 'The bus node writes the grants part's signed user list alone once the lease is handed (issue 774)' (#194) from feat/l3-removal into main
This commit was merged in pull request #194.
This commit is contained in:
@@ -3,7 +3,7 @@ module github.com/novox/mesh-host
|
||||
go 1.26.0
|
||||
|
||||
require (
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101151945-b2a27ed5cec4
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101235037-c21d8fd9692c
|
||||
github.com/nats-io/nats-server/v2 v2.11.17
|
||||
github.com/nats-io/nats.go v1.54.0
|
||||
golang.org/x/crypto v0.57.0
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101151945-b2a27ed5cec4 h1:xeuMBwOHNKrVUdGVg7Bdv5tkdueBvngwJFyk6n10rp0=
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101151945-b2a27ed5cec4/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101235037-c21d8fd9692c h1:/YCxh+NYfqry3PxZYY1nQXaccupobxpsFt8c9BYuGBg=
|
||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101235037-c21d8fd9692c/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
||||
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
||||
|
||||
@@ -27,6 +27,11 @@
|
||||
// against the key's digest, and written to the same file (mode 0600) only when the file's digest differs; otherwise the
|
||||
// controller's compositions are the source, as before. Never both. The have says which it follows and this node's key,
|
||||
// which the grants part seals to.
|
||||
//
|
||||
// **From the lease write it never follows the controller's list again** (ADR 0571 clause 8, ADR 0547 clause 11). The
|
||||
// grants part's key then says the lease is handed (delivery.GrantsUserList.LeaseHanded): a key that later cannot be read or
|
||||
// is deleted is said, the key last heard stands, and the list loaded stays; no list is written from a composition of the
|
||||
// controller.
|
||||
package userlist
|
||||
|
||||
import (
|
||||
@@ -250,23 +255,36 @@ func (f *Follower) busNode() bool {
|
||||
}
|
||||
|
||||
// takeGrants keeps the grants part's key as heard; a value it cannot read is said and leaves the controller's list
|
||||
// followed (no list is followed that the node cannot check).
|
||||
// followed (no list is followed that the node cannot check), unless the key last heard says the lease is handed: then
|
||||
// the controller's list is never followed again (novox/hq ADR 0571 clause 8, ADR 0547 clause 11), the key as last heard
|
||||
// stands, and the list loaded stays.
|
||||
func (f *Follower) takeGrants(u agent.Update) {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
f.grantsRev = u.Revision
|
||||
handed := f.grants != nil && f.grants.LeaseHanded
|
||||
if u.Deleted {
|
||||
if handed {
|
||||
f.sayOnceLocked("the grants part's user-list key is deleted, and the lease is handed, so the list loaded is kept")
|
||||
return
|
||||
}
|
||||
f.grantsRev = u.Revision
|
||||
f.grants = nil
|
||||
f.keep(nil, 0)
|
||||
return
|
||||
}
|
||||
g, err := delivery.DecodeGrantsUserList(u.Value)
|
||||
if err != nil {
|
||||
if handed {
|
||||
f.sayOnceLocked("the grants part's user-list key cannot be read, and the lease is handed, so the list loaded is kept: " + err.Error())
|
||||
return
|
||||
}
|
||||
f.grantsRev = u.Revision
|
||||
f.grants = nil
|
||||
f.keep(nil, 0)
|
||||
f.sayOnceLocked("the grants part's user-list key cannot be read, so the controller's list is followed: " + err.Error())
|
||||
return
|
||||
}
|
||||
f.grantsRev = u.Revision
|
||||
f.grants = &g
|
||||
f.keep(u.Value, u.Revision)
|
||||
}
|
||||
@@ -278,7 +296,8 @@ func (f *Follower) keep(value []byte, rev uint64) {
|
||||
}
|
||||
}
|
||||
|
||||
// Following is which list the follower takes now: the grants part's while its key says so, the controller's otherwise.
|
||||
// Following is which list the follower takes now: the grants part's while its key says so or says the lease is handed, the
|
||||
// controller's otherwise.
|
||||
func (f *Follower) Following() string {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
@@ -286,7 +305,7 @@ func (f *Follower) Following() string {
|
||||
}
|
||||
|
||||
func (f *Follower) followingLocked() string {
|
||||
if f.grants != nil && f.grants.Follow == delivery.FollowGrants {
|
||||
if f.grants != nil && (f.grants.Follow == delivery.FollowGrants || f.grants.LeaseHanded) {
|
||||
return delivery.FollowGrants
|
||||
}
|
||||
return delivery.FollowController
|
||||
|
||||
@@ -132,6 +132,9 @@ type gput struct {
|
||||
otherKey, badDigest bool
|
||||
// after puts it once the grants part's list was written, as a hand-back comes after a take-over.
|
||||
after bool
|
||||
// handed says the controller's lease is handed (ADR 0582 clause 3); unreadable and deleted make the key a value that
|
||||
// does not read, or a deleted key, instead of a list (774/S31).
|
||||
handed, unreadable, deleted bool
|
||||
}
|
||||
|
||||
type put struct {
|
||||
@@ -226,6 +229,20 @@ func TestTheBusNodeWritesTheNewestSignedUserListAlone(t *testing.T) {
|
||||
{name: "in shadow the grants part's list is not taken",
|
||||
before: []put{{module: "nats", fp: fpOf("a"), content: two}}, grants: []gput{{follow: delivery.FollowController, content: three}},
|
||||
wantWrites: []string{two}, wantUsers: 3, wantSource: "novox.nats." + fpOf("a")[len(delivery.SourcePrefix2):], wantFollows: delivery.FollowController},
|
||||
// 774/S31 (ADR 0571 clause 8, ADR 0547 clause 11): once the key says the lease is handed, the controller's list is never
|
||||
// followed again, whatever becomes of the key; without the flag the controller's list is still the fallback.
|
||||
{name: "a handed lease: a grants key that turns unreadable keeps the loaded list and never writes the controller's",
|
||||
before: []put{{module: "nats", fp: fpOf("a"), content: two}},
|
||||
grants: []gput{{follow: delivery.FollowGrants, content: three, handed: true}, {unreadable: true, after: true}},
|
||||
wantWrites: []string{three}, wantUsers: 4, wantSource: delivery.GrantsUserListSource, wantFollows: delivery.FollowGrants},
|
||||
{name: "a handed lease: a grants key that is deleted keeps the loaded list and never writes the controller's",
|
||||
before: []put{{module: "nats", fp: fpOf("a"), content: two}},
|
||||
grants: []gput{{follow: delivery.FollowGrants, content: three, handed: true}, {deleted: true, after: true}},
|
||||
wantWrites: []string{three}, wantUsers: 4, wantSource: delivery.GrantsUserListSource, wantFollows: delivery.FollowGrants},
|
||||
{name: "no handed lease: a grants key that turns unreadable falls back to the controller's list",
|
||||
before: []put{{module: "nats", fp: fpOf("a"), content: two}},
|
||||
grants: []gput{{follow: delivery.FollowGrants, content: three}, {unreadable: true, after: true}},
|
||||
wantWrites: []string{three, two}, wantUsers: 3, wantSource: "novox.nats." + fpOf("a")[len(delivery.SourcePrefix2):], wantFollows: delivery.FollowController},
|
||||
{name: "a grants list that does not open to its digest is refused and the file kept",
|
||||
before: []put{{module: "nats", fp: fpOf("a"), content: two}}, grants: []gput{{follow: delivery.FollowGrants, content: three, badDigest: true}},
|
||||
onDisk: two, wantErr: "could not be had", wantRefused: true, wantSource: delivery.GrantsUserListSource},
|
||||
@@ -256,6 +273,11 @@ func TestTheBusNodeWritesTheNewestSignedUserListAlone(t *testing.T) {
|
||||
gs = append(append([]gput(nil), gs...), *c.kept)
|
||||
}
|
||||
for i, g := range gs {
|
||||
if g.unreadable || g.deleted {
|
||||
u := agent.Update{Key: delivery.GrantsUserListKey, Value: []byte("not a user-list key"), Revision: uint64(i + 1), Deleted: g.deleted}
|
||||
grantsAfter = append(grantsAfter, u)
|
||||
continue
|
||||
}
|
||||
to := nodeKey.PublicKey
|
||||
if g.otherKey {
|
||||
other, _ := seal.GenerateKeyPair()
|
||||
@@ -271,7 +293,7 @@ func TestTheBusNodeWritesTheNewestSignedUserListAlone(t *testing.T) {
|
||||
}
|
||||
sealed[delivery.UserListObjectName(digest)] = object
|
||||
raw, err := delivery.EncodeGrantsUserList(delivery.GrantsUserList{Follow: g.follow, Digest: digest,
|
||||
Object: delivery.UserListObjectName(digest), SealedTo: delivery.SealingKeyID(to), Node: node, Revision: uint64(i + 1)})
|
||||
Object: delivery.UserListObjectName(digest), SealedTo: delivery.SealingKeyID(to), Node: node, Revision: uint64(i + 1), LeaseHanded: g.handed})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user