Commit a1940151 authored by Janos Guljas's avatar Janos Guljas

read and generate secp256k1 private key for libp2p

parent 112eb36f
......@@ -18,13 +18,13 @@ Docker image `janos/bee`.
Execute the command terminals to start `node 1`:
```sh
bee start --api-addr :8501 --p2p-addr :30401 --debug-api-addr :6061
bee start --api-addr :8501 --p2p-addr :30401 --data-dir data1
```
Use one of the multiaddresses as bootnode for `node 2` in order to connect them:
```sh
bee start --api-addr :8502 --p2p-addr :30402 --debug-api-addr :6062 --bootnode /ip4/127.0.0.1/tcp/30401/p2p/QmT4TNB4cKYanUjdYodw1Cns8cuVaRVo24hHNYcT7JjkTB
bee start --api-addr :8502 --p2p-addr :30402 --data-dir data2 --bootnode /ip4/127.0.0.1/tcp/30401/p2p/QmT4TNB4cKYanUjdYodw1Cns8cuVaRVo24hHNYcT7JjkTB
```
Use the last part of `node 1` multiaddress to ping it using `node 2` by making an HTTP request to `localhost:{PORT2}/pingpong/{ID1}` like:
......@@ -53,7 +53,5 @@ curl localhost:8502/pingpong/QmT4TNB4cKYanUjdYodw1Cns8cuVaRVo24hHNYcT7JjkTB
- P2P mock (protocol tester) implementation improvements
- Overlay addressing in libp2p (provide overlay address in p2p.Peer)
- Identity with private keys
- Figure out routing (whether to use libp2p Routing or to abstract hive on top of p2p package)
- Listener configurations (ipv4, ipv6, dns, tcp, ws, quic)
- Instrumentation: logging, metrics, tracing, pprof...
......@@ -6,6 +6,7 @@ package cmd
import (
"errors"
"os"
"path/filepath"
"strings"
......@@ -119,3 +120,16 @@ func (c *command) setHomeDir() (err error) {
c.homeDir = dir
return nil
}
// baseDir is the directory where the executable is located.
var baseDir = func() string {
path, err := os.Executable()
if err != nil {
panic(err)
}
path, err = filepath.EvalSymlinks(path)
if err != nil {
panic(err)
}
return filepath.Dir(path)
}()
......@@ -6,8 +6,10 @@ package cmd
import (
"context"
"io"
"os"
"os/signal"
"path/filepath"
"syscall"
"time"
......@@ -22,6 +24,7 @@ import (
func (c *command) initStartCmd() (err error) {
const (
optionNameDataDir = "data-dir"
optionNameAPIAddr = "api-addr"
optionNameP2PAddr = "p2p-addr"
optionNameP2PDisableWS = "p2p-disable-ws"
......@@ -45,10 +48,24 @@ func (c *command) initStartCmd() (err error) {
logger := logging.New(cmd.OutOrStdout())
logger.SetLevel(logrus.TraceLevel)
var libp2pPrivateKey io.ReadWriteCloser
if dataDir := c.config.GetString(optionNameDataDir); dataDir != "" {
dir := filepath.Join(dataDir, "libp2p")
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return err
}
f, err := os.OpenFile(filepath.Join(dir, "private.key"), os.O_CREATE|os.O_RDWR, 0600)
if err != nil {
return err
}
libp2pPrivateKey = f
}
b, err := node.NewBee(node.Options{
APIAddr: c.config.GetString(optionNameAPIAddr),
DebugAPIAddr: c.config.GetString(optionNameDebugAPIAddr),
LibP2POptions: libp2p.Options{
PrivateKey: libp2pPrivateKey,
Addr: c.config.GetString(optionNameP2PAddr),
DisableWS: c.config.GetBool(optionNameP2PDisableWS),
DisableQUIC: c.config.GetBool(optionNameP2PDisableQUIC),
......@@ -99,6 +116,7 @@ func (c *command) initStartCmd() (err error) {
},
}
cmd.Flags().String(optionNameDataDir, filepath.Join(baseDir, "data"), "data directory")
cmd.Flags().String(optionNameAPIAddr, ":8500", "HTTP API listen address")
cmd.Flags().String(optionNameP2PAddr, ":30399", "P2P listen address")
cmd.Flags().Bool(optionNameP2PDisableWS, false, "disable P2P WebSocket protocol")
......
......@@ -5,9 +5,13 @@
package libp2p
import (
"bytes"
"context"
"fmt"
"io"
"io/ioutil"
"net"
"os"
"time"
"github.com/janos/bee/pkg/p2p"
......@@ -15,6 +19,7 @@ import (
"github.com/libp2p/go-libp2p"
autonat "github.com/libp2p/go-libp2p-autonat-svc"
connmgr "github.com/libp2p/go-libp2p-connmgr"
"github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/helpers"
"github.com/libp2p/go-libp2p-core/host"
"github.com/libp2p/go-libp2p-core/network"
......@@ -35,6 +40,7 @@ type Service struct {
}
type Options struct {
PrivateKey io.ReadWriteCloser
Addr string
DisableWS bool
DisableQUIC bool
......@@ -88,8 +94,6 @@ func New(ctx context.Context, o Options) (*Service, error) {
}
opts := []libp2p.Option{
// Use the keypair we generated
//libp2p.Identity(priv),
// Multiple listen addresses
libp2p.ListenAddrStrings(listenAddrs...),
// support TLS connections
......@@ -109,6 +113,41 @@ func New(ctx context.Context, o Options) (*Service, error) {
libp2p.NATPortMap(),
}
if o.PrivateKey != nil {
var privateKey crypto.PrivKey
privateKeyData, err := ioutil.ReadAll(o.PrivateKey)
if err != nil && !os.IsNotExist(err) {
return nil, fmt.Errorf("read private key: %w", err)
}
if len(privateKeyData) == 0 {
var err error
privateKey, _, err = crypto.GenerateSecp256k1Key(nil)
if err != nil {
return nil, fmt.Errorf("generate secp256k1 key: %w", err)
}
d, err := crypto.MarshalPrivateKey(privateKey)
if err != nil {
return nil, fmt.Errorf("encode private key: %w", err)
}
if _, err := io.Copy(o.PrivateKey, bytes.NewReader(d)); err != nil {
return nil, fmt.Errorf("write private key: %w", err)
}
} else {
var err error
privateKey, err = crypto.UnmarshalPrivateKey(privateKeyData)
if err != nil {
return nil, fmt.Errorf("decode private key: %w", err)
}
}
if err := o.PrivateKey.Close(); err != nil {
return nil, fmt.Errorf("close private key: %w", err)
}
opts = append(opts,
// Use the keypair we generated
libp2p.Identity(privateKey),
)
}
if !o.DisableQUIC {
opts = append(opts,
// support QUIC - experimental
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment