I am writing a test app. For this, it would be ideal if my libp2p nodes would keep their IDs across restarts - otherwise I need to think of some intermediate service which keeps track of NodeIDs for the nodes to connect during a test.
Can I do this?
Currently, if I just run the https://docs.libp2p.io/guides/getting-started/go/ tutorial, after each restart, it prints a different Node ID.
❯ go run ./main.go
Listen addresses: /ip4/127.0.0.1/tcp/9436/p2p/12D3KooWNK774CCm9b48H84qZu3mp2Jq4wvDBh9813omB712qqLW
^CReceived signal, shutting down...
❯ go run ./main.go
Listen addresses: /ip4/127.0.0.1/tcp/9436/p2p/12D3KooWGLgDLUaNiuruX5umaExyFQJQBsf3yyXgC9MPy7cGS99F
^CReceived signal, shutting down...
This comment seems to provide the answer: https://github.com/libp2p/go-libp2p/issues/1040#issuecomment-767695679
Quoting from there:
A libp2p peer can't connect to a remote peer without it's peerId.
You can configure a libp2p node to use a persisted secret key to derive the same peerId as before by using the Identity option.
libp2p.New(context.Background(), libp2p.Identity(//secret key here))
To get a hosts's secret key and then marshal it, you can use:
sk := h.Peerstore().PrivKey(h.ID())
bz, _ := crypto.MarshalPrivateKey(sk)