mirror of
https://github.com/AthanorLabs/atomic-swap.git
synced 2026-01-08 21:58:07 -05:00
fix: bootnode version RPC call (#467)
This commit is contained in:
@@ -9,9 +9,9 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/athanorlabs/atomic-swap/common"
|
||||||
"github.com/athanorlabs/atomic-swap/net"
|
"github.com/athanorlabs/atomic-swap/net"
|
||||||
"github.com/athanorlabs/atomic-swap/rpc"
|
"github.com/athanorlabs/atomic-swap/rpc"
|
||||||
|
|
||||||
@@ -23,26 +23,27 @@ var log = logging.Logger("bootnode")
|
|||||||
|
|
||||||
// Config provides the configuration for a bootnode.
|
// Config provides the configuration for a bootnode.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
DataDir string
|
Env common.Environment
|
||||||
Bootnodes []string
|
DataDir string
|
||||||
HostListenIP string
|
Bootnodes []string
|
||||||
Libp2pPort uint16
|
HostListenIP string
|
||||||
Libp2pKeyFile string
|
Libp2pPort uint16
|
||||||
RPCPort uint16
|
Libp2pKeyFile string
|
||||||
EthereumChainID *big.Int
|
RPCPort uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunBootnode assembles and runs a bootnode instance, blocking until the node is
|
// RunBootnode assembles and runs a bootnode instance, blocking until the node is
|
||||||
// shut down. Typically, shutdown happens because a signal handler cancels the
|
// shut down. Typically, shutdown happens because a signal handler cancels the
|
||||||
// passed in context, or when the shutdown RPC method is called.
|
// passed in context, or when the shutdown RPC method is called.
|
||||||
func RunBootnode(ctx context.Context, cfg *Config) error {
|
func RunBootnode(ctx context.Context, cfg *Config) error {
|
||||||
|
chainID := common.ChainIDFromEnv(cfg.Env)
|
||||||
host, err := net.NewHost(&net.Config{
|
host, err := net.NewHost(&net.Config{
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
DataDir: cfg.DataDir,
|
DataDir: cfg.DataDir,
|
||||||
Port: cfg.Libp2pPort,
|
Port: cfg.Libp2pPort,
|
||||||
KeyFile: cfg.Libp2pKeyFile,
|
KeyFile: cfg.Libp2pKeyFile,
|
||||||
Bootnodes: cfg.Bootnodes,
|
Bootnodes: cfg.Bootnodes,
|
||||||
ProtocolID: fmt.Sprintf("%s/%d", net.ProtocolID, cfg.EthereumChainID.Int64()),
|
ProtocolID: fmt.Sprintf("%s/%d", net.ProtocolID, chainID),
|
||||||
ListenIP: cfg.HostListenIP,
|
ListenIP: cfg.HostListenIP,
|
||||||
IsRelayer: false,
|
IsRelayer: false,
|
||||||
IsBootnodeOnly: true,
|
IsBootnodeOnly: true,
|
||||||
@@ -61,9 +62,14 @@ func RunBootnode(ctx context.Context, cfg *Config) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rpcServer, err := rpc.NewServer(&rpc.Config{
|
rpcServer, err := rpc.NewServer(&rpc.Config{
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
Address: fmt.Sprintf("127.0.0.1:%d", cfg.RPCPort),
|
Env: cfg.Env,
|
||||||
Net: host,
|
Address: fmt.Sprintf("127.0.0.1:%d", cfg.RPCPort),
|
||||||
|
Net: host,
|
||||||
|
XMRTaker: nil,
|
||||||
|
XMRMaker: nil,
|
||||||
|
ProtocolBackend: nil,
|
||||||
|
RecoveryDB: nil,
|
||||||
Namespaces: map[string]struct{}{
|
Namespaces: map[string]struct{}{
|
||||||
rpc.DaemonNamespace: {},
|
rpc.DaemonNamespace: {},
|
||||||
rpc.NetNamespace: {},
|
rpc.NetNamespace: {},
|
||||||
|
|||||||
@@ -135,13 +135,13 @@ func runBootnode(c *cli.Context) error {
|
|||||||
|
|
||||||
rpcPort := uint16(c.Uint(flagRPCPort))
|
rpcPort := uint16(c.Uint(flagRPCPort))
|
||||||
return bootnode.RunBootnode(c.Context, &bootnode.Config{
|
return bootnode.RunBootnode(c.Context, &bootnode.Config{
|
||||||
DataDir: config.DataDir,
|
Env: config.Env,
|
||||||
Bootnodes: config.Bootnodes,
|
DataDir: config.DataDir,
|
||||||
HostListenIP: hostListenIP,
|
Bootnodes: config.Bootnodes,
|
||||||
Libp2pPort: libp2pPort,
|
HostListenIP: hostListenIP,
|
||||||
Libp2pKeyFile: libp2pKeyFile,
|
Libp2pPort: libp2pPort,
|
||||||
RPCPort: rpcPort,
|
Libp2pKeyFile: libp2pKeyFile,
|
||||||
EthereumChainID: config.EthereumChainID,
|
RPCPort: rpcPort,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
69
cmd/bootnode/main_test.go
Normal file
69
cmd/bootnode/main_test.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
// Copyright 2023 The AthanorLabs/atomic-swap Authors
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-only
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/athanorlabs/atomic-swap/cliutil"
|
||||||
|
"github.com/athanorlabs/atomic-swap/common"
|
||||||
|
"github.com/athanorlabs/atomic-swap/daemon"
|
||||||
|
"github.com/athanorlabs/atomic-swap/rpcclient"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getFreePort(t *testing.T) uint16 {
|
||||||
|
port, err := common.GetFreeTCPPort()
|
||||||
|
require.NoError(t, err)
|
||||||
|
return uint16(port)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBootnode(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
rpcPort := getFreePort(t)
|
||||||
|
dataDir := t.TempDir()
|
||||||
|
|
||||||
|
flags := []string{
|
||||||
|
"bootnode",
|
||||||
|
fmt.Sprintf("--%s=dev", flagEnv),
|
||||||
|
fmt.Sprintf("--%s=debug", cliutil.FlagLogLevel),
|
||||||
|
fmt.Sprintf("--%s=%s", flagDataDir, dataDir),
|
||||||
|
fmt.Sprintf("--%s=%d", flagRPCPort, rpcPort),
|
||||||
|
fmt.Sprintf("--%s=0", flagLibp2pPort),
|
||||||
|
}
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
err := cliApp().RunContext(ctx, flags)
|
||||||
|
// We may want to replace context.Cancelled with nil at some point in the code
|
||||||
|
assert.ErrorIs(t, context.Canceled, err)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Ensure the bootnode fully starts before some basic sanity checks
|
||||||
|
daemon.WaitForSwapdStart(t, rpcPort)
|
||||||
|
|
||||||
|
cli := rpcclient.NewClient(ctx, fmt.Sprintf("http://127.0.0.1:%d", rpcPort))
|
||||||
|
versionResp, err := cli.Version()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotEmpty(t, versionResp.P2PVersion)
|
||||||
|
t.Logf("Bootnode p2p version is: %s", versionResp.P2PVersion)
|
||||||
|
require.Nil(t, versionResp.SwapCreatorAddr) // bootnode does not know the address
|
||||||
|
|
||||||
|
addressResp, err := cli.Addresses()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Greater(t, len(addressResp.Addrs), 1)
|
||||||
|
|
||||||
|
// We check the contract code below, but we don't need the daemon for that
|
||||||
|
cli.Shutdown()
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
@@ -7,13 +7,9 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/athanorlabs/atomic-swap/common"
|
"github.com/athanorlabs/atomic-swap/common"
|
||||||
"github.com/athanorlabs/atomic-swap/common/vjson"
|
|
||||||
contracts "github.com/athanorlabs/atomic-swap/ethereum"
|
contracts "github.com/athanorlabs/atomic-swap/ethereum"
|
||||||
"github.com/athanorlabs/atomic-swap/ethereum/extethclient"
|
"github.com/athanorlabs/atomic-swap/ethereum/extethclient"
|
||||||
|
|
||||||
@@ -21,23 +17,14 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/ethclient"
|
"github.com/ethereum/go-ethereum/ethclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
contractAddressesFile = "contract-addresses.json"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errNoEthPrivateKey = fmt.Errorf("must provide --%s file for non-development environment", flagEthPrivKey)
|
errNoEthPrivateKey = fmt.Errorf("must provide --%s file for non-development environment", flagEthPrivKey)
|
||||||
)
|
)
|
||||||
|
|
||||||
type contractAddresses struct {
|
|
||||||
SwapCreatorAddr ethcommon.Address `json:"swapCreatorAddr" validate:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func getOrDeploySwapCreator(
|
func getOrDeploySwapCreator(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
swapCreatorAddr ethcommon.Address,
|
swapCreatorAddr ethcommon.Address,
|
||||||
env common.Environment,
|
env common.Environment,
|
||||||
dataDir string,
|
|
||||||
ec extethclient.EthClient,
|
ec extethclient.EthClient,
|
||||||
) (ethcommon.Address, error) {
|
) (ethcommon.Address, error) {
|
||||||
var err error
|
var err error
|
||||||
@@ -47,7 +34,7 @@ func getOrDeploySwapCreator(
|
|||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
swapCreatorAddr, err = deploySwapCreator(ctx, ec.Raw(), ec.PrivateKey(), dataDir)
|
swapCreatorAddr, err = deploySwapCreator(ctx, ec.Raw(), ec.PrivateKey())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ethcommon.Address{}, fmt.Errorf("failed to deploy swap creator: %w", err)
|
return ethcommon.Address{}, fmt.Errorf("failed to deploy swap creator: %w", err)
|
||||||
}
|
}
|
||||||
@@ -68,7 +55,6 @@ func deploySwapCreator(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
ec *ethclient.Client,
|
ec *ethclient.Client,
|
||||||
privkey *ecdsa.PrivateKey,
|
privkey *ecdsa.PrivateKey,
|
||||||
dataDir string,
|
|
||||||
) (ethcommon.Address, error) {
|
) (ethcommon.Address, error) {
|
||||||
if privkey == nil {
|
if privkey == nil {
|
||||||
return ethcommon.Address{}, errNoEthPrivateKey
|
return ethcommon.Address{}, errNoEthPrivateKey
|
||||||
@@ -79,25 +65,5 @@ func deploySwapCreator(
|
|||||||
return ethcommon.Address{}, err
|
return ethcommon.Address{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the contract addresses on disk
|
|
||||||
err = writeContractAddressesToFile(
|
|
||||||
path.Join(dataDir, contractAddressesFile),
|
|
||||||
&contractAddresses{
|
|
||||||
SwapCreatorAddr: swapCreatorAddr,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return ethcommon.Address{}, fmt.Errorf("failed to write contract address to file: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return swapCreatorAddr, nil
|
return swapCreatorAddr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeContractAddressesToFile writes the contract addresses to the given file
|
|
||||||
func writeContractAddressesToFile(filePath string, addresses *contractAddresses) error {
|
|
||||||
jsonData, err := vjson.MarshalIndentStruct(addresses, "", " ")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return os.WriteFile(filepath.Clean(filePath), jsonData, 0600)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -18,13 +18,11 @@ import (
|
|||||||
func TestGetOrDeploySwapCreator_Deploy(t *testing.T) {
|
func TestGetOrDeploySwapCreator_Deploy(t *testing.T) {
|
||||||
pk := tests.GetTakerTestKey(t)
|
pk := tests.GetTakerTestKey(t)
|
||||||
ec := extethclient.CreateTestClient(t, pk)
|
ec := extethclient.CreateTestClient(t, pk)
|
||||||
tmpDir := t.TempDir()
|
|
||||||
|
|
||||||
_, err := getOrDeploySwapCreator(
|
_, err := getOrDeploySwapCreator(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
ethcommon.Address{},
|
ethcommon.Address{},
|
||||||
common.Development,
|
common.Development,
|
||||||
tmpDir,
|
|
||||||
ec,
|
ec,
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -33,14 +31,12 @@ func TestGetOrDeploySwapCreator_Deploy(t *testing.T) {
|
|||||||
func TestGetOrDeploySwapCreator_Get(t *testing.T) {
|
func TestGetOrDeploySwapCreator_Get(t *testing.T) {
|
||||||
pk := tests.GetTakerTestKey(t)
|
pk := tests.GetTakerTestKey(t)
|
||||||
ec := extethclient.CreateTestClient(t, pk)
|
ec := extethclient.CreateTestClient(t, pk)
|
||||||
tmpDir := t.TempDir()
|
|
||||||
|
|
||||||
// deploy and get address
|
// deploy and get address
|
||||||
address, err := getOrDeploySwapCreator(
|
address, err := getOrDeploySwapCreator(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
ethcommon.Address{},
|
ethcommon.Address{},
|
||||||
common.Development,
|
common.Development,
|
||||||
tmpDir,
|
|
||||||
ec,
|
ec,
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -49,7 +45,6 @@ func TestGetOrDeploySwapCreator_Get(t *testing.T) {
|
|||||||
context.Background(),
|
context.Background(),
|
||||||
address,
|
address,
|
||||||
common.Development,
|
common.Development,
|
||||||
tmpDir,
|
|
||||||
ec,
|
ec,
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
@@ -368,7 +368,6 @@ func validateOrDeployContracts(c *cli.Context, envConf *common.Config, ec exteth
|
|||||||
c.Context,
|
c.Context,
|
||||||
envConf.SwapCreatorAddr,
|
envConf.SwapCreatorAddr,
|
||||||
envConf.Env,
|
envConf.Env,
|
||||||
envConf.DataDir,
|
|
||||||
ec,
|
ec,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@@ -78,8 +77,14 @@ func TestDaemon_DevXMRTaker(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Ensure the daemon fully started before we cancel the context
|
// Ensure the daemon fully before we query the contract address
|
||||||
daemon.WaitForSwapdStart(t, rpcPort)
|
daemon.WaitForSwapdStart(t, rpcPort)
|
||||||
|
|
||||||
|
cli := rpcclient.NewClient(ctx, fmt.Sprintf("http://127.0.0.1:%d", rpcPort))
|
||||||
|
versionResp, err := cli.Version()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// We check the contract code below, but we don't need the daemon for that
|
||||||
cancel()
|
cancel()
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
@@ -87,21 +92,9 @@ func TestDaemon_DevXMRTaker(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Validate that --deploy created a contract address file.
|
|
||||||
// At some future point, we will ask the RPC endpoint
|
|
||||||
// what the contract addresses are instead of using this file.
|
|
||||||
//
|
|
||||||
data, err := os.ReadFile(path.Join(dataDir, contractAddressesFile))
|
|
||||||
require.NoError(t, err)
|
|
||||||
m := make(map[string]string)
|
|
||||||
require.NoError(t, json.Unmarshal(data, &m))
|
|
||||||
swapCreatorAddr, ok := m["swapCreatorAddr"]
|
|
||||||
require.True(t, ok)
|
|
||||||
|
|
||||||
ec, _ := tests.NewEthClient(t)
|
ec, _ := tests.NewEthClient(t)
|
||||||
ecCtx := context.Background()
|
ecCtx := context.Background()
|
||||||
err = contracts.CheckSwapCreatorContractCode(ecCtx, ec, ethcommon.HexToAddress(swapCreatorAddr))
|
err = contracts.CheckSwapCreatorContractCode(ecCtx, ec, *versionResp.SwapCreatorAddr)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +104,7 @@ func TestDaemon_DevXMRMaker(t *testing.T) {
|
|||||||
ec, _ := tests.NewEthClient(t)
|
ec, _ := tests.NewEthClient(t)
|
||||||
|
|
||||||
// We tested --deploy with the taker, so test passing the contract address here
|
// We tested --deploy with the taker, so test passing the contract address here
|
||||||
swapCreatorAddr, err := deploySwapCreator(context.Background(), ec, key, t.TempDir())
|
swapCreatorAddr, err := deploySwapCreator(context.Background(), ec, key)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
flags := []string{
|
flags := []string{
|
||||||
@@ -148,7 +141,7 @@ func TestDaemon_BadFlags(t *testing.T) {
|
|||||||
ec, _ := tests.NewEthClient(t)
|
ec, _ := tests.NewEthClient(t)
|
||||||
ctx, _ := newTestContext(t)
|
ctx, _ := newTestContext(t)
|
||||||
|
|
||||||
swapCreatorAddr, err := deploySwapCreator(ctx, ec, key, t.TempDir())
|
swapCreatorAddr, err := deploySwapCreator(ctx, ec, key)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
baseFlags := []string{
|
baseFlags := []string{
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ type MoneroNode struct {
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
Env Environment
|
Env Environment
|
||||||
DataDir string
|
DataDir string
|
||||||
EthereumChainID *big.Int
|
|
||||||
EthEndpoint string
|
EthEndpoint string
|
||||||
MoneroNodes []*MoneroNode
|
MoneroNodes []*MoneroNode
|
||||||
SwapCreatorAddr ethcommon.Address
|
SwapCreatorAddr ethcommon.Address
|
||||||
@@ -46,10 +45,9 @@ type Config struct {
|
|||||||
// MainnetConfig is the mainnet ethereum and monero configuration
|
// MainnetConfig is the mainnet ethereum and monero configuration
|
||||||
func MainnetConfig() *Config {
|
func MainnetConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
Env: Mainnet,
|
Env: Mainnet,
|
||||||
DataDir: path.Join(baseDir, "mainnet"),
|
DataDir: path.Join(baseDir, "mainnet"),
|
||||||
EthereumChainID: big.NewInt(MainnetChainID),
|
EthEndpoint: "", // No mainnet default (permissionless URLs are not reliable)
|
||||||
EthEndpoint: "", // No mainnet default (permissionless URLs are not reliable)
|
|
||||||
MoneroNodes: []*MoneroNode{
|
MoneroNodes: []*MoneroNode{
|
||||||
{
|
{
|
||||||
Host: "node.sethforprivacy.com",
|
Host: "node.sethforprivacy.com",
|
||||||
@@ -84,10 +82,9 @@ func MainnetConfig() *Config {
|
|||||||
// StagenetConfig is the monero stagenet and ethereum Sepolia configuration
|
// StagenetConfig is the monero stagenet and ethereum Sepolia configuration
|
||||||
func StagenetConfig() *Config {
|
func StagenetConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
Env: Stagenet,
|
Env: Stagenet,
|
||||||
DataDir: path.Join(baseDir, "stagenet"),
|
DataDir: path.Join(baseDir, "stagenet"),
|
||||||
EthereumChainID: big.NewInt(SepoliaChainID),
|
EthEndpoint: "https://rpc.sepolia.org/",
|
||||||
EthEndpoint: "https://rpc.sepolia.org/",
|
|
||||||
MoneroNodes: []*MoneroNode{
|
MoneroNodes: []*MoneroNode{
|
||||||
{
|
{
|
||||||
Host: "node.sethforprivacy.com",
|
Host: "node.sethforprivacy.com",
|
||||||
@@ -119,10 +116,9 @@ func StagenetConfig() *Config {
|
|||||||
// DevelopmentConfig is the monero and ethereum development environment configuration
|
// DevelopmentConfig is the monero and ethereum development environment configuration
|
||||||
func DevelopmentConfig() *Config {
|
func DevelopmentConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
Env: Development,
|
Env: Development,
|
||||||
EthereumChainID: big.NewInt(1337),
|
DataDir: path.Join(baseDir, "dev"),
|
||||||
DataDir: path.Join(baseDir, "dev"),
|
EthEndpoint: DefaultGanacheEndpoint,
|
||||||
EthEndpoint: DefaultGanacheEndpoint,
|
|
||||||
MoneroNodes: []*MoneroNode{
|
MoneroNodes: []*MoneroNode{
|
||||||
{
|
{
|
||||||
Host: "127.0.0.1",
|
Host: "127.0.0.1",
|
||||||
@@ -190,3 +186,18 @@ func DefaultMoneroPortFromEnv(env Environment) uint {
|
|||||||
panic("invalid environment")
|
panic("invalid environment")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ChainIDFromEnv returns the expected chainID that we should find on the
|
||||||
|
// ethereum endpoint when running int the passed environment.
|
||||||
|
func ChainIDFromEnv(env Environment) *big.Int {
|
||||||
|
switch env {
|
||||||
|
case Development:
|
||||||
|
return big.NewInt(GanacheChainID)
|
||||||
|
case Stagenet:
|
||||||
|
return big.NewInt(SepoliaChainID)
|
||||||
|
case Mainnet:
|
||||||
|
return big.NewInt(MainnetChainID)
|
||||||
|
default:
|
||||||
|
panic("invalid environment")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ func RunSwapDaemon(ctx context.Context, conf *SwapdConfig) (err error) {
|
|||||||
|
|
||||||
rpcServer, err := rpc.NewServer(&rpc.Config{
|
rpcServer, err := rpc.NewServer(&rpc.Config{
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
|
Env: conf.EnvConf.Env,
|
||||||
Address: fmt.Sprintf("127.0.0.1:%d", conf.RPCPort),
|
Address: fmt.Sprintf("127.0.0.1:%d", conf.RPCPort),
|
||||||
Net: host,
|
Net: host,
|
||||||
XMRTaker: xmrTaker,
|
XMRTaker: xmrTaker,
|
||||||
|
|||||||
@@ -479,7 +479,7 @@ func TestRunSwapDaemon_RPC_Version(t *testing.T) {
|
|||||||
|
|
||||||
require.Equal(t, conf.EnvConf.Env, versionResp.Env)
|
require.Equal(t, conf.EnvConf.Env, versionResp.Env)
|
||||||
require.NotEmpty(t, versionResp.SwapdVersion)
|
require.NotEmpty(t, versionResp.SwapdVersion)
|
||||||
require.Equal(t, conf.EnvConf.SwapCreatorAddr, versionResp.SwapCreatorAddr)
|
require.Equal(t, conf.EnvConf.SwapCreatorAddr, *versionResp.SwapCreatorAddr)
|
||||||
require.Equal(t, protocolVersion, versionResp.P2PVersion)
|
require.Equal(t, protocolVersion, versionResp.P2PVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,11 +99,10 @@ example below:
|
|||||||
```bash
|
```bash
|
||||||
BOOT_NODE=/ip4/127.0.0.1/udp/9933/quic-v1/p2p/12D3KooWHRi24PVZ6TBnQJHdVyewDRcKFZtYV3qmB4KQo8iMyqik
|
BOOT_NODE=/ip4/127.0.0.1/udp/9933/quic-v1/p2p/12D3KooWHRi24PVZ6TBnQJHdVyewDRcKFZtYV3qmB4KQo8iMyqik
|
||||||
```
|
```
|
||||||
Now get the ethereum contract address that Alice deployed to. This can be pulled from the Alice's logs,
|
Now get the ethereum contract address that Alice deployed to. This can be pulled
|
||||||
the file ..., or if you have `jq` installed (available via `sudo apt install jq`), you can set a
|
from the Alice's logs, or from a `version` RPC request.
|
||||||
variable like this:
|
|
||||||
```bash
|
```bash
|
||||||
CONTRACT_ADDR=$(jq -r .swapCreatorAddr "${TMPDIR-/tmp}"/xmrtaker-*/contract-addresses.json)
|
CONTRACT_ADDR=$(./bin/swapcli version | grep '^swap creator address' | sed 's/.*: //')
|
||||||
```
|
```
|
||||||
|
|
||||||
Now start Bob's swapd instance:
|
Now start Bob's swapd instance:
|
||||||
|
|||||||
@@ -13,13 +13,19 @@ import (
|
|||||||
|
|
||||||
// DaemonService handles RPC requests for swapd version, administration and (in the future) status requests.
|
// DaemonService handles RPC requests for swapd version, administration and (in the future) status requests.
|
||||||
type DaemonService struct {
|
type DaemonService struct {
|
||||||
stopServer func()
|
stopServer func()
|
||||||
pb ProtocolBackend
|
env common.Environment
|
||||||
|
swapCreatorAddr *ethcommon.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDaemonService ...
|
// NewDaemonService creates a new daemon service. `swapCreatorAddr` is optional
|
||||||
func NewDaemonService(stopServer func(), pb ProtocolBackend) *DaemonService {
|
// and not set by bootnodes.
|
||||||
return &DaemonService{stopServer, pb}
|
func NewDaemonService(stopServer func(), env common.Environment, swapCreatorAddr *ethcommon.Address) *DaemonService {
|
||||||
|
return &DaemonService{
|
||||||
|
stopServer: stopServer,
|
||||||
|
env: env,
|
||||||
|
swapCreatorAddr: swapCreatorAddr,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown swapd
|
// Shutdown swapd
|
||||||
@@ -28,19 +34,20 @@ func (s *DaemonService) Shutdown(_ *http.Request, _ *any, _ *any) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// VersionResponse ...
|
// VersionResponse contains the version response provided by both swapd and
|
||||||
|
// bootnodes. In the case of bootnodes, the swapCreatorAddress is nil.
|
||||||
type VersionResponse struct {
|
type VersionResponse struct {
|
||||||
SwapdVersion string `json:"swapdVersion" validate:"required"`
|
SwapdVersion string `json:"swapdVersion" validate:"required"`
|
||||||
P2PVersion string `json:"p2pVersion" validate:"required"`
|
P2PVersion string `json:"p2pVersion" validate:"required"`
|
||||||
Env common.Environment `json:"env" validate:"required"`
|
Env common.Environment `json:"env" validate:"required"`
|
||||||
SwapCreatorAddr ethcommon.Address `json:"swapCreatorAddress" validate:"required"`
|
SwapCreatorAddr *ethcommon.Address `json:"swapCreatorAddress,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version returns version & misc info about swapd and its dependencies
|
// Version returns version & misc info about swapd and its dependencies
|
||||||
func (s *DaemonService) Version(_ *http.Request, _ *any, resp *VersionResponse) error {
|
func (s *DaemonService) Version(_ *http.Request, _ *any, resp *VersionResponse) error {
|
||||||
resp.SwapdVersion = cliutil.GetVersion()
|
resp.SwapdVersion = cliutil.GetVersion()
|
||||||
resp.P2PVersion = fmt.Sprintf("%s/%d", net.ProtocolID, s.pb.ETHClient().ChainID())
|
resp.P2PVersion = fmt.Sprintf("%s/%d", net.ProtocolID, common.ChainIDFromEnv(s.env))
|
||||||
resp.Env = s.pb.Env()
|
resp.Env = s.env
|
||||||
resp.SwapCreatorAddr = s.pb.SwapCreatorAddr()
|
resp.SwapCreatorAddr = s.swapCreatorAddr
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ func (*mockProtocolBackend) ETHClient() extethclient.EthClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (*mockProtocolBackend) SwapCreatorAddr() ethcommon.Address {
|
func (*mockProtocolBackend) SwapCreatorAddr() ethcommon.Address {
|
||||||
panic("not implemented")
|
return ethcommon.Address{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*mockProtocolBackend) TransferXMR(_ *mcrypto.Address, _ *coins.PiconeroAmount) (string, error) {
|
func (*mockProtocolBackend) TransferXMR(_ *mcrypto.Address, _ *coins.PiconeroAmount) (string, error) {
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import (
|
|||||||
"github.com/gorilla/rpc/v2"
|
"github.com/gorilla/rpc/v2"
|
||||||
logging "github.com/ipfs/go-log"
|
logging "github.com/ipfs/go-log"
|
||||||
"github.com/libp2p/go-libp2p/core/peer"
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
|
|
||||||
"github.com/athanorlabs/atomic-swap/coins"
|
"github.com/athanorlabs/atomic-swap/coins"
|
||||||
@@ -54,12 +53,13 @@ type Server struct {
|
|||||||
// Config ...
|
// Config ...
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Ctx context.Context
|
Ctx context.Context
|
||||||
|
Env common.Environment
|
||||||
Address string // "IP:port"
|
Address string // "IP:port"
|
||||||
Net Net
|
Net Net
|
||||||
XMRTaker XMRTaker
|
XMRTaker XMRTaker // nil on bootnodes
|
||||||
XMRMaker XMRMaker
|
XMRMaker XMRMaker // nil on bootnodes
|
||||||
ProtocolBackend ProtocolBackend
|
ProtocolBackend ProtocolBackend // nil on bootnodes
|
||||||
RecoveryDB RecoveryDB
|
RecoveryDB RecoveryDB // nil on bootnodes
|
||||||
Namespaces map[string]struct{}
|
Namespaces map[string]struct{}
|
||||||
IsBootnodeOnly bool
|
IsBootnodeOnly bool
|
||||||
}
|
}
|
||||||
@@ -81,13 +81,19 @@ func NewServer(cfg *Config) (*Server, error) {
|
|||||||
rpcServer.RegisterCodec(NewCodec(), "application/json")
|
rpcServer.RegisterCodec(NewCodec(), "application/json")
|
||||||
|
|
||||||
serverCtx, serverCancel := context.WithCancel(cfg.Ctx)
|
serverCtx, serverCancel := context.WithCancel(cfg.Ctx)
|
||||||
err := rpcServer.RegisterService(NewDaemonService(serverCancel, cfg.ProtocolBackend), "daemon")
|
var swapCreatorAddr *ethcommon.Address
|
||||||
|
if !cfg.IsBootnodeOnly {
|
||||||
|
addr := cfg.ProtocolBackend.SwapCreatorAddr()
|
||||||
|
swapCreatorAddr = &addr
|
||||||
|
}
|
||||||
|
daemonService := NewDaemonService(serverCancel, cfg.Env, swapCreatorAddr)
|
||||||
|
err := rpcServer.RegisterService(daemonService, "daemon")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var swapManager swap.Manager
|
var swapManager swap.Manager
|
||||||
if cfg.ProtocolBackend != nil {
|
if !cfg.IsBootnodeOnly {
|
||||||
swapManager = cfg.ProtocolBackend.SwapManager()
|
swapManager = cfg.ProtocolBackend.SwapManager()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,13 +145,15 @@ func NewServer(cfg *Config) (*Server, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
SetupMetrics(serverCtx, reg, cfg.Net, cfg.ProtocolBackend, cfg.XMRMaker)
|
if !cfg.IsBootnodeOnly {
|
||||||
|
SetupMetrics(serverCtx, reg, cfg.Net, cfg.ProtocolBackend, cfg.XMRMaker)
|
||||||
|
}
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
r.Handle("/", rpcServer)
|
r.Handle("/", rpcServer)
|
||||||
r.Handle("/ws", wsServer)
|
r.Handle("/ws", wsServer)
|
||||||
r.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{}))
|
if !cfg.IsBootnodeOnly {
|
||||||
|
r.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{}))
|
||||||
|
}
|
||||||
headersOk := handlers.AllowedHeaders([]string{"content-type", "username", "password"})
|
headersOk := handlers.AllowedHeaders([]string{"content-type", "username", "password"})
|
||||||
methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})
|
methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})
|
||||||
originsOk := handlers.AllowedOrigins([]string{"*"})
|
originsOk := handlers.AllowedOrigins([]string{"*"})
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/athanorlabs/atomic-swap/coins"
|
"github.com/athanorlabs/atomic-swap/coins"
|
||||||
|
"github.com/athanorlabs/atomic-swap/common"
|
||||||
"github.com/athanorlabs/atomic-swap/common/types"
|
"github.com/athanorlabs/atomic-swap/common/types"
|
||||||
"github.com/athanorlabs/atomic-swap/rpcclient/wsclient"
|
"github.com/athanorlabs/atomic-swap/rpcclient/wsclient"
|
||||||
)
|
)
|
||||||
@@ -30,6 +31,7 @@ func newServer(t *testing.T) *Server {
|
|||||||
|
|
||||||
cfg := &Config{
|
cfg := &Config{
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
|
Env: common.Development,
|
||||||
Address: "127.0.0.1:0", // OS assigned port
|
Address: "127.0.0.1:0", // OS assigned port
|
||||||
Net: new(mockNet),
|
Net: new(mockNet),
|
||||||
ProtocolBackend: newMockProtocolBackend(),
|
ProtocolBackend: newMockProtocolBackend(),
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ fi
|
|||||||
echo "Stopping any monero-wallet-rpc instances"
|
echo "Stopping any monero-wallet-rpc instances"
|
||||||
"${pkill_cmd[@]}" '/monero-wallet-rpc '
|
"${pkill_cmd[@]}" '/monero-wallet-rpc '
|
||||||
|
|
||||||
|
echo "Stopping any bootnode instances"
|
||||||
|
"${pkill_cmd[@]}" '/bootnode '
|
||||||
|
|
||||||
echo "Stopping any monerod regest instances"
|
echo "Stopping any monerod regest instances"
|
||||||
if "${pkill_cmd[@]}" '/monerod .* --regtest '; then
|
if "${pkill_cmd[@]}" '/monerod .* --regtest '; then
|
||||||
sleep 2 # we don't want to exit the script while it is still running
|
sleep 2 # we don't want to exit the script while it is still running
|
||||||
|
|||||||
@@ -32,41 +32,62 @@ create-eth-keys() {
|
|||||||
echo "${GANACHE_KEYS[${i}]}" >"${key_file}"
|
echo "${GANACHE_KEYS[${i}]}" >"${key_file}"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
# This is the local multiaddr created when using ./tests/alice-libp2p.key on the default libp2p port
|
|
||||||
ALICE_MULTIADDR=/ip4/127.0.0.1/tcp/9933/p2p/12D3KooWAAxG7eTEHr2uBVw3BDMxYsxyqfKvj3qqqpRGtTfuzTuH
|
|
||||||
ALICE_LIBP2PKEY=./tests/alice-libp2p.key
|
|
||||||
LOG_LEVEL=debug
|
LOG_LEVEL=debug
|
||||||
|
|
||||||
|
BOOTNODE_RPC_PORT=4999
|
||||||
ALICE_RPC_PORT=5000
|
ALICE_RPC_PORT=5000
|
||||||
BOB_RPC_PORT=5001
|
BOB_RPC_PORT=5001
|
||||||
CHARLIE_RPC_PORT=5002
|
CHARLIE_RPC_PORT=5002
|
||||||
|
|
||||||
|
start-bootnode() {
|
||||||
|
local flags=(
|
||||||
|
"--rpc-port=${BOOTNODE_RPC_PORT}"
|
||||||
|
--env=dev
|
||||||
|
"--log-level=${LOG_LEVEL}"
|
||||||
|
)
|
||||||
|
local log_file="${SWAP_TEST_DATA_DIR}/bootnode.log"
|
||||||
|
|
||||||
|
echo "Starting bootnode, logs in ${log_file}"
|
||||||
|
./bin/bootnode "${flags[@]}" &>"${log_file}" &
|
||||||
|
local pid="${!}"
|
||||||
|
echo "${pid}" >"${SWAP_TEST_DATA_DIR}/bootnode.pid"
|
||||||
|
|
||||||
|
if wait-rpc-started "bootnode" "${pid}" "${BOOTNODE_RPC_PORT}"; then
|
||||||
|
return 0 # success
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Failed to start bootnode"
|
||||||
|
echo "=============== Failed logs ==============="
|
||||||
|
cat "${log_file}"
|
||||||
|
echo "============================================"
|
||||||
|
stop-daemons
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
stop-bootnode() {
|
||||||
|
stop-program "bootnode"
|
||||||
|
}
|
||||||
|
|
||||||
start-swapd() {
|
start-swapd() {
|
||||||
local swapd_user="${1:?}"
|
local swapd_user="${1:?}"
|
||||||
local rpc_port="${2:?}"
|
local rpc_port="${2:?}"
|
||||||
local swapd_flags=("${@:3}" "--rpc-port=${rpc_port}")
|
local swapd_flags=(
|
||||||
|
"${@:3}"
|
||||||
|
--env=dev
|
||||||
|
"--rpc-port=${rpc_port}"
|
||||||
|
"--log-level=${LOG_LEVEL}"
|
||||||
|
)
|
||||||
local log_file="${SWAP_TEST_DATA_DIR}/${swapd_user}-swapd.log"
|
local log_file="${SWAP_TEST_DATA_DIR}/${swapd_user}-swapd.log"
|
||||||
|
|
||||||
echo "Starting ${swapd_user^}'s swapd, logs in ${SWAP_TEST_DATA_DIR}/${swapd_user}-swapd.log"
|
echo "Starting ${swapd_user^}'s swapd, logs in ${log_file}"
|
||||||
./bin/swapd "${swapd_flags[@]}" &>"${log_file}" &
|
./bin/swapd "${swapd_flags[@]}" &>"${log_file}" &
|
||||||
local swapd_pid="${!}"
|
local swapd_pid="${!}"
|
||||||
echo "${swapd_pid}" >"${SWAP_TEST_DATA_DIR}/${swapd_user}-swapd.pid"
|
echo "${swapd_pid}" >"${SWAP_TEST_DATA_DIR}/${swapd_user}-swapd.pid"
|
||||||
|
|
||||||
# Wait up to 60 seconds for the daemon's port to be listening
|
if wait-rpc-started "${swapd_user}" "${swapd_pid}" "${rpc_port}"; then
|
||||||
for i in {1..60}; do
|
return 0 # success, bypass failure code below
|
||||||
sleep 1
|
fi
|
||||||
|
|
||||||
# Test if pid is still alive, leave loop if it is not
|
|
||||||
if ! kill -0 "${swapd_pid}" 2>/dev/null; then
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Test if RPC port is listening, exit success if it is
|
|
||||||
if is-port-open "${rpc_port}"; then
|
|
||||||
echo "${swapd_user^}'s swapd instance is listening after ${i} seconds"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Failed to start ${swapd_user^}'s swapd"
|
echo "Failed to start ${swapd_user^}'s swapd"
|
||||||
echo "=============== Failed logs ==============="
|
echo "=============== Failed logs ==============="
|
||||||
@@ -81,32 +102,49 @@ stop-swapd() {
|
|||||||
stop-program "${swapd_user}-swapd"
|
stop-program "${swapd_user}-swapd"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Waits for up to 60 seconds for the RPC port to be listening.
|
||||||
|
# If the passed PID exits, we stop waiting. This method only
|
||||||
|
# returns success(0)/failure(1) and will not exit the script.
|
||||||
wait-rpc-started() {
|
wait-rpc-started() {
|
||||||
local swapd_user="${1}"
|
local user="${1}"
|
||||||
local rpc_port="${1}"
|
local pid="${2}"
|
||||||
|
local port="${3}"
|
||||||
|
|
||||||
|
# Wait up to 60 seconds for the daemon's port to be listening
|
||||||
|
for i in {1..60}; do
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
# Test if pid is still alive, fail if it isn't
|
||||||
|
if ! kill -0 "${pid}" 2>/dev/null; then
|
||||||
|
return 1 # fail
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test if RPC port is listening, return success if it is
|
||||||
|
if is-port-open "${port}"; then
|
||||||
|
echo "${user^}'s instance is listening after ${i} seconds"
|
||||||
|
return 0 # success
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
return 1 # fail
|
||||||
}
|
}
|
||||||
|
|
||||||
start-daemons() {
|
start-daemons() {
|
||||||
start-monerod-regtest
|
start-monerod-regtest
|
||||||
start-ganache
|
start-ganache
|
||||||
|
start-bootnode
|
||||||
|
|
||||||
|
local bootnode_addr
|
||||||
|
bootnode_addr="$(./bin/swapcli addresses --swapd-port ${BOOTNODE_RPC_PORT} | grep '^1:' | sed 's/.* //')"
|
||||||
start-swapd alice "${ALICE_RPC_PORT}" \
|
start-swapd alice "${ALICE_RPC_PORT}" \
|
||||||
--dev-xmrtaker \
|
--dev-xmrtaker \
|
||||||
"--log-level=${LOG_LEVEL}" \
|
"--bootnodes=${bootnode_addr}" \
|
||||||
"--data-dir=${SWAP_TEST_DATA_DIR}/alice" \
|
"--data-dir=${SWAP_TEST_DATA_DIR}/alice" \
|
||||||
"--libp2p-key=${ALICE_LIBP2PKEY}" \
|
|
||||||
--deploy
|
--deploy
|
||||||
|
|
||||||
CONTRACT_ADDR_FILE="${SWAP_TEST_DATA_DIR}/alice/contract-addresses.json"
|
local contract_addr
|
||||||
if [[ ! -f "${CONTRACT_ADDR_FILE}" ]]; then
|
contract_addr="$(./bin/swapcli version | grep '^swap creator address' | sed 's/.*: //')"
|
||||||
echo "Failed to get Alice's deployed contract address file"
|
if [[ -z "${contract_addr}" ]]; then
|
||||||
stop-daemons
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
SWAP_CREATOR_ADDR="$(jq -r .swapCreatorAddr "${CONTRACT_ADDR_FILE}")"
|
|
||||||
if [[ -z "${SWAP_CREATOR_ADDR}" ]]; then
|
|
||||||
echo "Failed to get Alice's deployed contract addresses"
|
echo "Failed to get Alice's deployed contract addresses"
|
||||||
stop-daemons
|
stop-daemons
|
||||||
exit 1
|
exit 1
|
||||||
@@ -114,19 +152,16 @@ start-daemons() {
|
|||||||
|
|
||||||
start-swapd bob "${BOB_RPC_PORT}" \
|
start-swapd bob "${BOB_RPC_PORT}" \
|
||||||
--dev-xmrmaker \
|
--dev-xmrmaker \
|
||||||
"--log-level=${LOG_LEVEL}" \
|
"--bootnodes=${bootnode_addr}" \
|
||||||
"--data-dir=${SWAP_TEST_DATA_DIR}/bob" \
|
"--data-dir=${SWAP_TEST_DATA_DIR}/bob" \
|
||||||
--libp2p-port=9944 \
|
--libp2p-port=9944 \
|
||||||
"--bootnodes=${ALICE_MULTIADDR}" \
|
"--contract-address=${contract_addr}"
|
||||||
"--contract-address=${SWAP_CREATOR_ADDR}"
|
|
||||||
|
|
||||||
start-swapd charlie "${CHARLIE_RPC_PORT}" \
|
start-swapd charlie "${CHARLIE_RPC_PORT}" \
|
||||||
"--env=dev" \
|
"--bootnodes=${bootnode_addr}" \
|
||||||
"--log-level=${LOG_LEVEL}" \
|
|
||||||
--data-dir "${SWAP_TEST_DATA_DIR}/charlie" \
|
--data-dir "${SWAP_TEST_DATA_DIR}/charlie" \
|
||||||
--libp2p-port=9955 \
|
--libp2p-port=9955 \
|
||||||
"--bootnodes=${ALICE_MULTIADDR}" \
|
"--contract-address=${contract_addr}" \
|
||||||
"--contract-address=${SWAP_CREATOR_ADDR}" \
|
|
||||||
"--relayer"
|
"--relayer"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,6 +169,7 @@ stop-daemons() {
|
|||||||
stop-swapd charlie
|
stop-swapd charlie
|
||||||
stop-swapd bob
|
stop-swapd bob
|
||||||
stop-swapd alice
|
stop-swapd alice
|
||||||
|
stop-bootnode
|
||||||
stop-monerod-regtest
|
stop-monerod-regtest
|
||||||
stop-ganache
|
stop-ganache
|
||||||
}
|
}
|
||||||
@@ -142,14 +178,14 @@ stop-daemons() {
|
|||||||
echo "running integration tests..."
|
echo "running integration tests..."
|
||||||
create-eth-keys
|
create-eth-keys
|
||||||
start-daemons
|
start-daemons
|
||||||
TESTS=integration CONTRACT_ADDR=${SWAP_CREATOR_ADDR} go test ./tests -v -count=1 -timeout=30m
|
TESTS=integration go test ./tests -v -count=1 -timeout=30m
|
||||||
OK="${?}"
|
OK="${?}"
|
||||||
KEEP_TEST_DATA="${OK}" stop-daemons
|
KEEP_TEST_DATA="${OK}" stop-daemons
|
||||||
|
|
||||||
# Cleanup test files if we succeeded
|
# Cleanup test files if we succeeded
|
||||||
if [[ "${OK}" -eq 0 ]]; then
|
if [[ "${OK}" -eq 0 ]]; then
|
||||||
rm -f "${CHARLIE_ETH_KEY}"
|
rm -f "${CHARLIE_ETH_KEY}"
|
||||||
rm -f "${SWAP_TEST_DATA_DIR}/"{alice,bob,charlie}/{contract-addresses.json,monero-wallet-rpc.log}
|
rm -f "${SWAP_TEST_DATA_DIR}/"{alice,bob,charlie}/monero-wallet-rpc.log
|
||||||
rm -f "${SWAP_TEST_DATA_DIR}/"{alice,bob,charlie}/{net,eth}.key
|
rm -f "${SWAP_TEST_DATA_DIR}/"{alice,bob,charlie}/{net,eth}.key
|
||||||
rm -rf "${SWAP_TEST_DATA_DIR}/"{alice,bob,charlie}/{wallet,libp2p-datastore,db}
|
rm -rf "${SWAP_TEST_DATA_DIR}/"{alice,bob,charlie}/{wallet,libp2p-datastore,db}
|
||||||
rmdir "${SWAP_TEST_DATA_DIR}/"{alice,bob,charlie}
|
rmdir "${SWAP_TEST_DATA_DIR}/"{alice,bob,charlie}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
d97f10b75b1d5772fa07468f20329b13489b2bf9165e57ae0fe777630830ee9405462a30fedaaa5ebe0f30d8a8c4dc8f141876cd3fc1c8b95a898ec64bc70668
|
|
||||||
Reference in New Issue
Block a user