Documentation
¶
Overview ¶
Package membership provides a transport-independent, signed membership protocol reference for CRDT replication groups. Gossip reports liveness but never changes the active set; only a signed View may fence a replica or change the tombstone-GC membership epoch.
Index ¶
- Variables
- func ManifestHash(manifest replica.Manifest) [sha256.Size]byte
- func MarshalGossipMessage(message GossipMessage) ([]byte, error)
- func MarshalReceipt(receipt Receipt) ([]byte, error)
- func MarshalView(view View) ([]byte, error)
- func SortedTags(tags []crdt.Tag) ([]crdt.Tag, error)
- func VerifyView(view View, authorityKey ed25519.PublicKey) error
- type GCBridge
- type Gossip
- type GossipMessage
- type Liveness
- type LivenessEvent
- type Manager
- type Member
- type MemoryStore
- type Receipt
- type View
- type ViewStore
Constants ¶
This section is empty.
Variables ¶
var ( ErrInvalidReceipt = errors.New("membership: invalid tombstone receipt") ErrReceiptReplay = errors.New("membership: tombstone receipt replay") )
var ( ErrInvalidView = errors.New("membership: invalid view") ErrInvalidSignature = errors.New("membership: invalid signature") ErrViewRollback = errors.New("membership: view epoch rollback") ErrViewFork = errors.New("membership: view predecessor mismatch") ErrGroupMismatch = errors.New("membership: replication group mismatch") ErrMissingView = errors.New("membership: missing persisted view") )
var ErrInvalidGossip = errors.New("membership: invalid gossip message")
Functions ¶
func ManifestHash ¶
ManifestHash returns the control-plane binding digest for a replication manifest. It includes the membership/data-plane epoch, schema, codec, frame IDs, semantics version, and negotiated outer frame version; changing any of them requires a new signed View.
func MarshalGossipMessage ¶
func MarshalGossipMessage(message GossipMessage) ([]byte, error)
MarshalGossipMessage returns a bounded canonical signed heartbeat.
func MarshalReceipt ¶
MarshalReceipt returns a bounded canonical signed tombstone receipt.
func MarshalView ¶
MarshalView returns the bounded canonical wire representation of a signed View. Call VerifyView with the configured authority key after decoding.
func SortedTags ¶
SortedTags returns a sorted, duplicate-free copy suitable for a receipt. It is a convenience for producers that take tags from multiple chunks; it never infers a receipt from a frontier.
Types ¶
type GCBridge ¶
type GCBridge[T comparable] struct { // contains filtered or unexported fields }
GCBridge accepts authenticated receipts only for the active signed view and feeds their exact tags to Coordinator. It serializes each member's sequence to reject stale/replayed packets before they reach the GC path.
func NewGCBridge ¶
func NewGCBridge[T comparable](manager *Manager[T]) (*GCBridge[T], error)
type Gossip ¶
type Gossip struct {
// contains filtered or unexported fields
}
Gossip is a compact SWIM-style heartbeat/reference fanout engine. It signs source heartbeats, verifies them against the active View, and exposes deterministic peer selection for embedding transports. It does not open a socket, decide membership, or make a failure detector authoritative.
func NewGossipAt ¶
func NewGossipAt(view View, selfID string, privateKey ed25519.PrivateKey, suspectAfter time.Duration, startedAt time.Time) (*Gossip, error)
NewGossipAt is NewGossip with an explicit local start time. It makes failure detector tests reproducible and starts the suspect timer for every active peer, including peers that have not yet sent a heartbeat.
func (*Gossip) Heartbeat ¶
func (g *Gossip) Heartbeat() (GossipMessage, error)
Heartbeat returns a newly signed heartbeat. The embedding transport sends it to some or all targets returned by Peers; no membership state is changed.
func (*Gossip) Observe ¶
func (g *Gossip) Observe(message GossipMessage, now time.Time) (LivenessEvent, bool, error)
Observe verifies and records a received heartbeat. Duplicate/out-of-order messages are harmless. A later valid heartbeat transitions a suspect peer back to Alive but cannot change the signed membership view.
type GossipMessage ¶
type GossipMessage struct {
GroupID string
Epoch uint64
ViewHash [sha256.Size]byte
From string
Incarnation uint64
Counter uint64
Signature []byte
}
GossipMessage is a signed heartbeat that may be forwarded over any application-selected transport. Counter is monotonic within an incarnation.
func UnmarshalGossipMessage ¶
func UnmarshalGossipMessage(data []byte) (GossipMessage, error)
UnmarshalGossipMessage decodes a bounded canonical heartbeat. Observe verifies its signature against the current View before recording liveness.
type Liveness ¶
type Liveness uint8
Liveness is deliberately separate from membership authorization. Suspect means an observer has not heard a heartbeat recently; it never permits the observer to remove a replica from a signed View or from tombstone GC.
type LivenessEvent ¶
LivenessEvent is emitted on a local state transition and is intended for observability or an external authority's decision process.
type Manager ¶
type Manager[T comparable] struct { // contains filtered or unexported fields }
Manager is the bridge from a signed authoritative View to a Coordinator. It persists a valid next view before fencing the local data plane at that epoch. The caller must use the same epoch in replica.Manifest during its authenticated handshake.
func NewManager ¶
func NewManager[T comparable](initial View, authorityKey ed25519.PublicKey, store ViewStore) (*Manager[T], error)
NewManager verifies and durably installs initial before exposing a coordinator. It is suitable for first bootstrap and for a process that has obtained the currently authoritative view from its control plane.
func OpenManager ¶
func OpenManager[T comparable](authorityKey ed25519.PublicKey, store ViewStore) (*Manager[T], error)
OpenManager restores a previously persisted signed view. Receipt state is intentionally not restored: losing it delays GC, while restoring an untrusted or stale receipt could compact too early.
func (*Manager[T]) Coordinator ¶
func (m *Manager[T]) Coordinator() *tombstonegc.Coordinator[T]
Coordinator exposes the local exact-acknowledgement coordinator. All membership changes must continue through Install, never through direct ReplaceMembership calls.
func (*Manager[T]) Install ¶
Install verifies a direct successor, persists it, and then advances the coordinator epoch. A process crash after persistence is safe because OpenManager restores the newer fence; a crash before persistence leaves the older in-memory state and therefore only delays collection.
type Member ¶
Member is one stable logical replica authorized by a View. Incarnation must advance when a previously fenced replica is admitted again; a process must never silently resume replication with an older incarnation.
type MemoryStore ¶
type MemoryStore struct {
// contains filtered or unexported fields
}
MemoryStore is a concurrency-safe store for tests, examples, and embedding applications that already provide their own durable control-plane store. It intentionally makes no durability claim.
func (*MemoryStore) SaveView ¶
func (s *MemoryStore) SaveView(view View) error
type Receipt ¶
type Receipt struct {
GroupID string
Epoch uint64
ViewHash [sha256.Size]byte
MemberID string
Incarnation uint64
Sequence uint64
CheckpointID [sha256.Size]byte
Tags []crdt.Tag
Signature []byte
}
Receipt is an authenticated assertion by one crash-fault-trusted member that it has durably installed the listed tombstones in a non-zero checkpoint ID. A signature establishes origin and replay scope; it cannot prove honesty or durable storage against a Byzantine signer.
func SignReceipt ¶
func SignReceipt(receipt Receipt, privateKey ed25519.PrivateKey) (Receipt, error)
SignReceipt returns a canonical signed copy. Tags must be sorted and unique so a receipt has exactly one byte representation and cannot inflate GC accounting through duplicate acknowledgements.
func UnmarshalReceipt ¶
UnmarshalReceipt decodes a bounded canonical receipt. GCBridge.Apply verifies signature, view binding, member incarnation, and replay sequence.
type View ¶
type View struct {
GroupID string
Epoch uint64
PreviousHash [sha256.Size]byte
ManifestHash [sha256.Size]byte
Members []Member
Signature []byte
}
View is the authoritative active-member set for exactly one replication group. ManifestHash binds this control-plane decision to the application replication manifest. PreviousHash forms an append-only view chain.
func SignView ¶
func SignView(view View, privateKey ed25519.PrivateKey) (View, error)
SignView returns a canonical signed copy of view. The signing key is owned by the application's membership authority, not by an ordinary replica.
func UnmarshalView ¶
UnmarshalView decodes a bounded canonical View. It validates only structure; callers must invoke VerifyView before treating it as authoritative.
func (View) Hash ¶
Hash returns a stable digest of the signed view. It is the predecessor and receipt binding value, not a substitute for signature verification.
func (View) MatchesManifest ¶
MatchesManifest reports whether view fences exactly manifest. It is intended for an authenticated handshake before a replica accepts state, delta, or GC receipt traffic. A matching group ID alone is not sufficient.