A private Bitmessage contour cannot be assembled by letting the nodes find
each other. The sybil check in connectionpool refuses a candidate whose /16 is
already among the outbound connections, and every container of a compose
project shares one /16 -- so each node keeps a single outbound connection to a
randomly chosen peer, and the contour splits into components on some runs and
not on others.
Three variables make the topology explicit instead:
BITMESSAGE_TRUSTED_PEER trustedpeer = host:port
BITMESSAGE_SEND_OUTGOING sendoutgoingconnections = True/False
BITMESSAGE_KNOWN_NODES host:port,... -> knownnodes.dat
With them a star is one line of config per node: the hub takes
SEND_OUTGOING=False and only accepts, the spokes take TRUSTED_PEER=<hub>:8444.
Details worth knowing:
- trustedpeer is absent from the stock keys.dat, so a substitution alone would
be a silent no-op. The key is added the same way maxtotalconnections is,
and it is added even when the value is empty -- that is how a node that was
pinned before can be unpinned. Its anchors stop at "=" rather than "= ",
because an empty value leaves no trailing space to match.
- knownnodes.dat is rewritten on every start, not only when missing. "Only
when missing" would never have fired: the image ships one, built by the
`pybitmessage -t` run in the Dockerfile, and a named volume inherits it.
Seeding it is also what stops the DNS bootstrap -- deserialising any peer
that is neither a DEFAULT_NODE nor "self" raises knownNodesActual, and
startBootstrappers only runs while that flag is down.
- Both peer variables are validated here. PyBitmessage does check trustedpeer,
but with a sys.exit() from a constructor in the network thread, which reads
as a container that died for no stated reason.