Files
mpc/pkg/event/reveal_test.go
zooqueen 861db0f621 a request nobody hears is not a quorum problem, and a secret needs a way in
Two halves of opening a secret were missing, and both showed up the first time
this ran against the real ring rather than an in-process one.

The request reached no party. Parties subscribed to "mpc.reveal_request.*" and
the requester published to "mpc.reveal_request.<session>". This transport
delivers by exact map lookup on the topic — it has no wildcards — so the
subscription matched nothing, every node stayed silent, and the opening failed
as "0 of 2 answered" with all three shares present and nobody having been asked.
That reads like a quorum fault and is a routing one. Both sides name one literal
now; the session rides in the body, where a reader wants it anyway. The pattern
came from the NATS-era topics next door, where wildcards do work.

And nothing could seal. mpcrek requires a sealed root to bring and no tool in
the estate produced one, so the protocol had no beginning. reveal.Seal takes the
published group key and a secret — no share, no node, no round, because writing
to the committee needs none of that — and `mpcd seal` is that from a shell, with
the secret on stdin so it never becomes an argument other processes can read.

Sealing to the identity is refused. It decodes as a valid point, so the decoder
lets it through, and every answer verifies against it: a secret sealed there is
readable by anyone. A test asked for that and the first version did not do it.
2026-08-21 00:57:48 -07:00

42 lines
1.6 KiB
Go

package event
import (
"strings"
"testing"
)
// The consensus transport delivers by exact map lookup on the topic string. It
// has no wildcards, so a party subscribed to a pattern is subscribed to nothing
// and hears no request — the opening then times out with every share present
// and nobody having been asked, which reads like a quorum problem and is not
// one. That is how this shipped, and a "*" here is the whole of it.
func TestTopicsAreLiteral(t *testing.T) {
for name, topic := range map[string]string{
"RevealRequestTopic": RevealRequestTopic,
"RevealAnswerTopicBase": RevealAnswerTopicBase,
} {
if strings.ContainsAny(topic, "*>") {
t.Errorf("%s = %q carries a wildcard; this transport matches exactly", name, topic)
}
}
}
// One request reaches every party, so both sides have to name the same string.
// The session that separates two openings in flight rides in the body, and the
// answers come back on their own per-session topic built from the base.
func TestARequestIsOneTopicAndAnAnswerIsPerSession(t *testing.T) {
if RevealRequestTopic != "mpc.reveal_request" {
t.Errorf("request topic = %q", RevealRequestTopic)
}
if RevealAnswerTopicBase != "mpc.reveal_answer" {
t.Errorf("answer base = %q", RevealAnswerTopicBase)
}
if strings.HasPrefix(RevealAnswerTopicBase, RevealRequestTopic) {
t.Error("the answer base is a prefix of the request topic; a request would land on the answer path")
}
var r RevealRequest
if _, ok := any(r.SessionID).(string); !ok {
t.Error("the request must carry its session, since the topic no longer does")
}
}