feat: add bootnode binary (#397)

This commit is contained in:
noot
2023-04-21 18:52:07 +02:00
committed by GitHub
parent dda4cacaea
commit dbcc97f9c1
21 changed files with 527 additions and 187 deletions

86
bootnode/bootnode.go Normal file
View File

@@ -0,0 +1,86 @@
// Copyright 2023 The AthanorLabs/atomic-swap Authors
// SPDX-License-Identifier: LGPL-3.0-only
// Package bootnode is responsible for assembling, running and cleanly shutting
// down a swap bootnode.
package bootnode
import (
"context"
"errors"
"fmt"
"math/big"
"net/http"
"github.com/athanorlabs/atomic-swap/net"
"github.com/athanorlabs/atomic-swap/rpc"
"github.com/hashicorp/go-multierror"
logging "github.com/ipfs/go-log"
)
var log = logging.Logger("bootnode")
// Config provides the configuration for a bootnode.
type Config struct {
DataDir string
Bootnodes []string
HostListenIP string
Libp2pPort uint16
Libp2pKeyFile string
RPCPort uint16
EthereumChainID *big.Int
}
// RunBootnode assembles and runs a bootnode instance, blocking until the node is
// shut down. Typically, shutdown happens because a signal handler cancels the
// passed in context, or when the shutdown RPC method is called.
func RunBootnode(ctx context.Context, cfg *Config) error {
host, err := net.NewHost(&net.Config{
Ctx: ctx,
DataDir: cfg.DataDir,
Port: cfg.Libp2pPort,
KeyFile: cfg.Libp2pKeyFile,
Bootnodes: cfg.Bootnodes,
ProtocolID: fmt.Sprintf("%s/%d", net.ProtocolID, cfg.EthereumChainID.Int64()),
ListenIP: cfg.HostListenIP,
IsRelayer: false,
IsBootnodeOnly: true,
})
if err != nil {
return err
}
defer func() {
if hostErr := host.Stop(); hostErr != nil {
err = multierror.Append(err, fmt.Errorf("error shutting down peer-to-peer services: %w", hostErr))
}
}()
if err = host.Start(); err != nil {
return err
}
rpcServer, err := rpc.NewServer(&rpc.Config{
Ctx: ctx,
Address: fmt.Sprintf("127.0.0.1:%d", cfg.RPCPort),
Net: host,
Namespaces: map[string]struct{}{
rpc.DaemonNamespace: {},
rpc.NetNamespace: {},
},
IsBootnodeOnly: true,
})
log.Infof("starting bootnode with data-dir %s", cfg.DataDir)
err = rpcServer.Start()
if errors.Is(err, http.ErrServerClosed) {
// Remove the error for a clean program exit, as ErrServerClosed only
// happens when the server is told to shut down
err = nil
}
// err can get set in defer blocks, so return err or use an empty
// return statement below (not nil)
return err
}