diff --git a/cmd/client/errors.go b/cmd/client/errors.go new file mode 100644 index 00000000..5dfe0244 --- /dev/null +++ b/cmd/client/errors.go @@ -0,0 +1,14 @@ +package main + +import ( + "errors" +) + +var ( + errNoMultiaddr = errors.New("must provide peer's multiaddress with --multiaddr") + errNoMinAmount = errors.New("must provide non-zero --min-amount") + errNoMaxAmount = errors.New("must provide non-zero --max-amount") + errNoExchangeRate = errors.New("must provide non-zero --exchange-rate") + errNoOfferID = errors.New("must provide --offer-id") + errNoProvidesAmount = errors.New("must provide --provides-amount") +) diff --git a/cmd/client/main.go b/cmd/client/main.go index 95a94fb8..c5f80f30 100644 --- a/cmd/client/main.go +++ b/cmd/client/main.go @@ -2,13 +2,12 @@ package main import ( "context" - "errors" "fmt" "os" - "github.com/noot/atomic-swap/cmd/client/client" - "github.com/noot/atomic-swap/common/rpcclient" "github.com/noot/atomic-swap/common/types" + "github.com/noot/atomic-swap/rpcclient" + "github.com/noot/atomic-swap/rpcclient/wsclient" logging "github.com/ipfs/go-log" "github.com/urfave/cli" @@ -191,7 +190,7 @@ func runAddresses(ctx *cli.Context) error { endpoint = defaultSwapdAddress } - c := client.NewClient(endpoint) + c := rpcclient.NewClient(endpoint) addrs, err := c.Addresses() if err != nil { return err @@ -218,7 +217,7 @@ func runDiscover(ctx *cli.Context) error { searchTime := ctx.Uint("search-time") - c := client.NewClient(endpoint) + c := rpcclient.NewClient(endpoint) peers, err := c.Discover(provides, uint64(searchTime)) if err != nil { return err @@ -234,7 +233,7 @@ func runDiscover(ctx *cli.Context) error { func runQuery(ctx *cli.Context) error { maddr := ctx.String("multiaddr") if maddr == "" { - return errors.New("must provide peer's multiaddress with --multiaddr") + return errNoMultiaddr } endpoint := ctx.String("daemon-addr") @@ -242,7 +241,7 @@ func runQuery(ctx *cli.Context) error { endpoint = defaultSwapdAddress } - c := client.NewClient(endpoint) + c := rpcclient.NewClient(endpoint) res, err := c.Query(maddr) if err != nil { return err @@ -257,17 +256,17 @@ func runQuery(ctx *cli.Context) error { func runMake(ctx *cli.Context) error { min := ctx.Float64("min-amount") if min == 0 { - return errors.New("must provide non-zero --min-amount") + return errNoMinAmount } max := ctx.Float64("max-amount") if max == 0 { - return errors.New("must provide non-zero --max-amount") + return errNoMaxAmount } exchangeRate := ctx.Float64("exchange-rate") if exchangeRate == 0 { - return errors.New("must provide non-zero --exchange-rate") + return errNoExchangeRate } endpoint := ctx.String("daemon-addr") @@ -276,7 +275,7 @@ func runMake(ctx *cli.Context) error { } if ctx.Bool("subscribe") { - c, err := rpcclient.NewWsClient(context.Background(), endpoint) + c, err := wsclient.NewWsClient(context.Background(), endpoint) if err != nil { return err } @@ -301,7 +300,7 @@ func runMake(ctx *cli.Context) error { return nil } - c := client.NewClient(endpoint) + c := rpcclient.NewClient(endpoint) id, err := c.MakeOffer(min, max, exchangeRate) if err != nil { return err @@ -314,17 +313,17 @@ func runMake(ctx *cli.Context) error { func runTake(ctx *cli.Context) error { maddr := ctx.String("multiaddr") if maddr == "" { - return errors.New("must provide peer's multiaddress with --multiaddr") + return errNoMultiaddr } offerID := ctx.String("offer-id") if offerID == "" { - return errors.New("must provide --offer-id") + return errNoOfferID } providesAmount := ctx.Float64("provides-amount") if providesAmount == 0 { - return errors.New("must provide --provides-amount") + return errNoProvidesAmount } endpoint := ctx.String("daemon-addr") @@ -333,7 +332,7 @@ func runTake(ctx *cli.Context) error { } if ctx.Bool("subscribe") { - c, err := rpcclient.NewWsClient(context.Background(), endpoint) + c, err := wsclient.NewWsClient(context.Background(), endpoint) if err != nil { return err } @@ -355,7 +354,7 @@ func runTake(ctx *cli.Context) error { return nil } - c := client.NewClient(endpoint) + c := rpcclient.NewClient(endpoint) id, err := c.TakeOffer(maddr, offerID, providesAmount) if err != nil { return err @@ -371,7 +370,7 @@ func runGetPastSwapIDs(ctx *cli.Context) error { endpoint = defaultSwapdAddress } - c := client.NewClient(endpoint) + c := rpcclient.NewClient(endpoint) ids, err := c.GetPastSwapIDs() if err != nil { return err @@ -387,7 +386,7 @@ func runGetOngoingSwap(ctx *cli.Context) error { endpoint = defaultSwapdAddress } - c := client.NewClient(endpoint) + c := rpcclient.NewClient(endpoint) info, err := c.GetOngoingSwap() if err != nil { return err @@ -412,7 +411,7 @@ func runGetPastSwap(ctx *cli.Context) error { endpoint = defaultSwapdAddress } - c := client.NewClient(endpoint) + c := rpcclient.NewClient(endpoint) info, err := c.GetPastSwap(uint64(id)) if err != nil { return err @@ -435,7 +434,7 @@ func runRefund(ctx *cli.Context) error { endpoint = defaultSwapdAddress } - c := client.NewClient(endpoint) + c := rpcclient.NewClient(endpoint) resp, err := c.Refund() if err != nil { return err @@ -451,7 +450,7 @@ func runCancel(ctx *cli.Context) error { endpoint = defaultSwapdAddress } - c := client.NewClient(endpoint) + c := rpcclient.NewClient(endpoint) resp, err := c.Cancel() if err != nil { return err @@ -467,7 +466,7 @@ func runGetStage(ctx *cli.Context) error { endpoint = defaultSwapdAddress } - c := client.NewClient(endpoint) + c := rpcclient.NewClient(endpoint) resp, err := c.GetStage() if err != nil { return err @@ -485,7 +484,7 @@ func runSetSwapTimeout(ctx *cli.Context) error { endpoint = defaultSwapdAddress } - c := client.NewClient(endpoint) + c := rpcclient.NewClient(endpoint) err := c.SetSwapTimeout(uint64(duration)) if err != nil { return err diff --git a/cmd/daemon/wait.go b/cmd/daemon/wait.go index 7d4681d1..faa21fe2 100644 --- a/cmd/daemon/wait.go +++ b/cmd/daemon/wait.go @@ -23,6 +23,8 @@ func (d *daemon) wait() { case <-d.ctx.Done(): fmt.Println("protocol complete, shutting down...") } + + wg.Done() }() wg.Wait() diff --git a/cmd/recover/errors.go b/cmd/recover/errors.go new file mode 100644 index 00000000..baa1368f --- /dev/null +++ b/cmd/recover/errors.go @@ -0,0 +1,11 @@ +package main + +import ( + "errors" +) + +var ( + errNoSecretsProvided = errors.New("must also provide one of --alice-secret or --bob-secret") + errNoAliceSecretOrContractProvided = errors.New("must also provide one of --alice-secret or --contract-addr") + errNoBobSecretOrContractProvided = errors.New("must also provide one of --contract-addr or --bob-secret") +) diff --git a/cmd/recover/main.go b/cmd/recover/main.go index 96f06ed9..e527290e 100644 --- a/cmd/recover/main.go +++ b/cmd/recover/main.go @@ -2,7 +2,6 @@ package main import ( "context" - "errors" "math/big" "os" @@ -136,15 +135,15 @@ func (inst *instance) recover(c *cli.Context) error { } if as == "" && bs == "" { - return errors.New("must also provide one of --alice-secret or --bob-secret") + return errNoSecretsProvided } if as == "" && contractAddr == "" { - return errors.New("must also provide one of --alice-secret or --contract-addr") + return errNoAliceSecretOrContractProvided } if contractAddr == "" && bs == "" { - return errors.New("must also provide one of --contract-addr or --bob-secret") + return errNoBobSecretOrContractProvided } swapID := big.NewInt(int64(c.Uint(flagContractSwapID))) diff --git a/cmd/tester/main.go b/cmd/tester/main.go index 28cf8d00..a7d8ac4b 100644 --- a/cmd/tester/main.go +++ b/cmd/tester/main.go @@ -16,8 +16,10 @@ import ( "github.com/urfave/cli" - "github.com/noot/atomic-swap/common/rpcclient" + "github.com/noot/atomic-swap/common" "github.com/noot/atomic-swap/common/types" + "github.com/noot/atomic-swap/monero" + "github.com/noot/atomic-swap/rpcclient/wsclient" logging "github.com/ipfs/go-log" ) @@ -26,13 +28,17 @@ const ( flagConfig = "config" flagTimeout = "timeout" flagLog = "log" + flagDev = "dev" defaultConfigFile = "testerconfig.json" ) -var defaultTimeout = time.Minute * 15 - -var log = logging.Logger("cmd") +var ( + defaultTimeout = time.Minute * 15 + log = logging.Logger("cmd") + isDev = false + defaultMoneroClient monero.Client +) var ( app = &cli.App{ @@ -52,6 +58,10 @@ var ( Name: flagLog, Usage: "set log level: one of [error|warn|info|debug]", }, + &cli.BoolFlag{ + Name: flagDev, + Usage: "run tester in development environment", + }, }, } ) @@ -90,6 +100,7 @@ func setLogLevels(c *cli.Context) error { _ = logging.SetLogLevel("net", level) _ = logging.SetLogLevel("rpc", level) _ = logging.SetLogLevel("rpcclient", level) + _ = logging.SetLogLevel("wsclient", level) return nil } @@ -99,6 +110,12 @@ func runTester(c *cli.Context) error { return err } + isDev = c.Bool(flagDev) + if !isDev { + // TODO: add a flag to specify local endpoint + defaultMoneroClient = monero.NewClient(common.DefaultBobMoneroEndpoint) + } + var timeout time.Duration timeoutMins := c.Uint(flagTimeout) @@ -171,6 +188,20 @@ func getRandomExchangeRate() types.ExchangeRate { return types.ExchangeRate(rate) } +func generateBlocks() { + cBob := monero.NewClient(common.DefaultAliceMoneroEndpoint) + + bobAddr, err := cBob.GetAddress(0) + if err != nil { + log.Errorf("failed to get default monero address: %s", err) + return + } + + log.Infof("development: generating blocks...") + dclient := monero.NewDaemonClient(common.DefaultMoneroDaemonEndpoint) + _ = dclient.GenerateBlocks(bobAddr.Address, 128) +} + type daemon struct { rsl *resultLogger endpoint string @@ -245,7 +276,7 @@ func (d *daemon) logErrors(done <-chan struct{}) { func (d *daemon) takeOffer(done <-chan struct{}) { log.Debugf("node %d discovering offers...", d.idx) - wsc, err := rpcclient.NewWsClient(context.Background(), d.endpoint) + wsc, err := wsclient.NewWsClient(context.Background(), d.endpoint) if err != nil { d.errCh <- err return @@ -314,7 +345,11 @@ func (d *daemon) takeOffer(done <-chan struct{}) { } d.rsl.logTakerStatus(status) - d.rsl.logSwapDuration(time.Since(start)) + + if status != types.CompletedAbort { + d.rsl.logSwapDuration(time.Since(start)) + } + return } } @@ -327,7 +362,7 @@ func getRandomInt(max int) int { func (d *daemon) makeOffer(done <-chan struct{}) { log.Infof("node %d making offer...", d.idx) - wsc, err := rpcclient.NewWsClient(context.Background(), d.endpoint) + wsc, err := wsclient.NewWsClient(context.Background(), d.endpoint) if err != nil { d.errCh <- err return @@ -342,6 +377,18 @@ func (d *daemon) makeOffer(done <-chan struct{}) { if err != nil { log.Errorf("failed to make offer (node %d): %s", d.idx, err) d.errCh <- err + + if strings.Contains(err.Error(), "unlocked balance is less than maximum") { + if isDev { + generateBlocks() + } else { + _, err := monero.WaitForBlocks(defaultMoneroClient, 10) + if err != nil { + log.Errorf("failed to wait for blocks: %s", err) + } + } + } + return } @@ -377,7 +424,10 @@ func (d *daemon) makeOffer(done <-chan struct{}) { } d.rsl.logMakerStatus(status) - d.rsl.logSwapDuration(time.Since(start)) + if status != types.CompletedAbort { + d.rsl.logSwapDuration(time.Since(start)) + } + return } } diff --git a/cmd/utils/utils.go b/cmd/utils/utils.go index 2799fe53..fc7219f0 100644 --- a/cmd/utils/utils.go +++ b/cmd/utils/utils.go @@ -21,6 +21,11 @@ var log = logging.Logger("cmd") var defaultEnvironment = common.Development +var ( + errNoEthereumPrivateKey = errors.New("must provide --ethereum-privkey file for non-development environment") + errInvalidEnv = errors.New("--env must be one of mainnet, stagenet, or dev") +) + // GetEthereumPrivateKey returns an ethereum private key hex string given the CLI options. func GetEthereumPrivateKey(c *cli.Context, env common.Environment, devBob bool) (ethPrivKey string, err error) { if c.String(flagEthereumPrivKey) != "" { @@ -38,7 +43,7 @@ func GetEthereumPrivateKey(c *cli.Context, env common.Environment, devBob bool) } else { if env != common.Development { // TODO: allow this to be set via RPC - return "", errors.New("must provide --ethereum-privkey file for non-development environment") + return "", errNoEthereumPrivateKey } log.Warn("no ethereum private key file provided, using ganache deterministic key") @@ -68,7 +73,7 @@ func GetEnvironment(c *cli.Context) (env common.Environment, cfg common.Config, env = defaultEnvironment cfg = common.DevelopmentConfig default: - return 0, common.Config{}, errors.New("--env must be one of mainnet, stagenet, or dev") + return 0, common.Config{}, errInvalidEnv } return env, cfg, nil diff --git a/common/rpcclient/utils.go b/common/rpctypes/utils.go similarity index 88% rename from common/rpcclient/utils.go rename to common/rpctypes/utils.go index 32801012..2a83539c 100644 --- a/common/rpcclient/utils.go +++ b/common/rpctypes/utils.go @@ -1,4 +1,4 @@ -package rpcclient +package rpctypes import ( "bytes" @@ -9,8 +9,6 @@ import ( "net" "net/http" "time" - - "github.com/noot/atomic-swap/common/rpctypes" ) var ( @@ -31,7 +29,7 @@ var ( ) // PostRPC posts a JSON-RPC call to the given endpoint. -func PostRPC(endpoint, method, params string) (*rpctypes.Response, error) { +func PostRPC(endpoint, method, params string) (*Response, error) { data := []byte(`{"jsonrpc":"2.0","method":"` + method + `","params":` + params + `,"id":0}`) buf := &bytes.Buffer{} _, err := buf.Write(data) @@ -63,7 +61,7 @@ func PostRPC(endpoint, method, params string) (*rpctypes.Response, error) { return nil, fmt.Errorf("failed to read response body: %w", err) } - var sv *rpctypes.Response + var sv *Response if err = json.Unmarshal(body, &sv); err != nil { return nil, err } diff --git a/common/types/provides.go b/common/types/provides.go index d179a520..d869a080 100644 --- a/common/types/provides.go +++ b/common/types/provides.go @@ -8,6 +8,8 @@ type ProvidesCoin string var ( ProvidesXMR ProvidesCoin = "XMR" //nolint ProvidesETH ProvidesCoin = "ETH" //nolint + + errInvalidCoin = errors.New("invalid ProvidesCoin") ) // NewProvidesCoin converts a string to a ProvidesCoin. @@ -18,6 +20,6 @@ func NewProvidesCoin(s string) (ProvidesCoin, error) { case "ETH", "eth": return ProvidesETH, nil default: - return "", errors.New("invalid ProvidesCoin") + return "", errInvalidCoin } } diff --git a/common/utils.go b/common/utils.go index 005c5766..809da4bd 100644 --- a/common/utils.go +++ b/common/utils.go @@ -22,6 +22,8 @@ const ( var ( log = logging.Logger("common") + + errReceiptTimeOut = errors.New("failed to get receipt, timed out") ) // Reverse reverses the byte slice and returns it. @@ -51,7 +53,7 @@ func WaitForReceipt(ctx context.Context, ethclient *ethclient.Client, txHash eth return receipt, nil } - return nil, errors.New("failed to get receipt, timed out") + return nil, errReceiptTimeOut } // EthereumPrivateKeyToAddress returns the address associated with a private key diff --git a/crypto/monero/crypto.go b/crypto/monero/crypto.go index 695b20ef..b0f6fd44 100644 --- a/crypto/monero/crypto.go +++ b/crypto/monero/crypto.go @@ -108,7 +108,7 @@ type PrivateSpendKey struct { // NewPrivateSpendKey returns a new PrivateSpendKey from the given canonically-encoded scalar. func NewPrivateSpendKey(b []byte) (*PrivateSpendKey, error) { if len(b) != privateKeySize { - return nil, errors.New("input is not 32 bytes") + return nil, errInvalidInput } sk, err := ed25519.NewScalar().SetCanonicalBytes(b) diff --git a/crypto/monero/sign.go b/crypto/monero/sign.go index f509672e..e6d21703 100644 --- a/crypto/monero/sign.go +++ b/crypto/monero/sign.go @@ -6,6 +6,11 @@ import ( "errors" ) +var ( + errInvalidSignatureLength = errors.New("invalid length for signature") + errNoPrivateKeySeed = errors.New("private key does not have seed, key must be created with GenerateKeys") +) + // Signature represents an ed25519 signature type Signature struct { s []byte @@ -20,7 +25,7 @@ func NewSignatureFromHex(s string) (*Signature, error) { } if len(b) != ed25519.SignatureSize { - return nil, errors.New("invalid length for signature") + return nil, errInvalidSignatureLength } return &Signature{ @@ -37,7 +42,7 @@ func (s *Signature) Hex() string { // The private key must have been created with GenerateKeys(). func (k *PrivateSpendKey) Sign(msg []byte) (*Signature, error) { if k.seed == [32]byte{} { - return nil, errors.New("private key does not have seed, key must be created with GenerateKeys") + return nil, errNoPrivateKeySeed } pub := k.Public().key.Bytes() diff --git a/crypto/secp256k1/secp256k1.go b/crypto/secp256k1/secp256k1.go index 49b960e0..491e9408 100644 --- a/crypto/secp256k1/secp256k1.go +++ b/crypto/secp256k1/secp256k1.go @@ -10,6 +10,10 @@ import ( ethsecp256k1 "github.com/ethereum/go-ethereum/crypto/secp256k1" ) +var ( + errInvalidPubkeyLength = errors.New("encoded public key is not 64 bytes") +) + // PublicKey represents a secp256k1 public key type PublicKey struct { x, y [32]byte @@ -39,7 +43,7 @@ func NewPublicKeyFromHex(s string) (*PublicKey, error) { } if len(k) != 64 { - return nil, errors.New("encoded public key is not 64 bytes") + return nil, errInvalidPubkeyLength } pk := &PublicKey{} diff --git a/monero/client.go b/monero/client.go index 04e45bb3..40e2030f 100644 --- a/monero/client.go +++ b/monero/client.go @@ -2,7 +2,7 @@ package monero import ( "github.com/noot/atomic-swap/common" - "github.com/noot/atomic-swap/common/rpcclient" + "github.com/noot/atomic-swap/common/rpctypes" mcrypto "github.com/noot/atomic-swap/crypto/monero" ) @@ -74,7 +74,7 @@ func (c *client) Refresh() error { func (c *client) refresh() error { const method = "refresh" - resp, err := rpcclient.PostRPC(c.endpoint, method, "{}") + resp, err := rpctypes.PostRPC(c.endpoint, method, "{}") if err != nil { return err } @@ -97,7 +97,7 @@ func (c *client) OpenWallet(filename, password string) error { func (c *client) CloseWallet() error { const method = "close_wallet" - resp, err := rpcclient.PostRPC(c.endpoint, method, "{}") + resp, err := rpctypes.PostRPC(c.endpoint, method, "{}") if err != nil { return err } diff --git a/monero/daemon.go b/monero/daemon.go index fddc7776..f0baa030 100644 --- a/monero/daemon.go +++ b/monero/daemon.go @@ -3,7 +3,7 @@ package monero import ( "encoding/json" - "github.com/noot/atomic-swap/common/rpcclient" + "github.com/noot/atomic-swap/common/rpctypes" ) // DaemonClient represents a monerod client. @@ -40,7 +40,7 @@ func (c *client) callGenerateBlocks(address string, amount uint) error { return err } - resp, err := rpcclient.PostRPC(c.endpoint, method, string(params)) + resp, err := rpctypes.PostRPC(c.endpoint, method, string(params)) if err != nil { return err } diff --git a/monero/rpc.go b/monero/rpc.go index d6b61d67..bc32d06c 100644 --- a/monero/rpc.go +++ b/monero/rpc.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - "github.com/noot/atomic-swap/common/rpcclient" + "github.com/noot/atomic-swap/common/rpctypes" mcrypto "github.com/noot/atomic-swap/crypto/monero" ) @@ -46,7 +46,7 @@ func (c *client) callGenerateFromKeys(sk *mcrypto.PrivateSpendKey, vk *mcrypto.P return err } - resp, err := rpcclient.PostRPC(c.endpoint, method, string(params)) + resp, err := rpctypes.PostRPC(c.endpoint, method, string(params)) if err != nil { return err } @@ -101,7 +101,7 @@ func (c *client) callSweepAll(to string, accountIdx uint) (*SweepAllResponse, er return nil, err } - resp, err := rpcclient.PostRPC(c.endpoint, method, string(params)) + resp, err := rpctypes.PostRPC(c.endpoint, method, string(params)) if err != nil { return nil, err } @@ -152,7 +152,7 @@ func (c *client) callTransfer(destinations []Destination, accountIdx uint) (*Tra return nil, err } - resp, err := rpcclient.PostRPC(c.endpoint, method, string(params)) + resp, err := rpctypes.PostRPC(c.endpoint, method, string(params)) if err != nil { return nil, err } @@ -193,7 +193,7 @@ func (c *client) callGetBalance(idx uint) (*GetBalanceResponse, error) { return nil, err } - resp, err := rpcclient.PostRPC(c.endpoint, method, string(params)) + resp, err := rpctypes.PostRPC(c.endpoint, method, string(params)) if err != nil { return nil, err } @@ -230,7 +230,7 @@ func (c *client) callGetAddress(idx uint) (*getAddressResponse, error) { return nil, err } - resp, err := rpcclient.PostRPC(c.endpoint, method, string(params)) + resp, err := rpctypes.PostRPC(c.endpoint, method, string(params)) if err != nil { return nil, err } @@ -254,7 +254,7 @@ type getAccountsResponse struct { func (c *client) callGetAccounts() (*getAccountsResponse, error) { const method = "get_accounts" - resp, err := rpcclient.PostRPC(c.endpoint, method, "{}") + resp, err := rpctypes.PostRPC(c.endpoint, method, "{}") if err != nil { return nil, err } @@ -289,7 +289,7 @@ func (c *client) callOpenWallet(filename, password string) error { return err } - resp, err := rpcclient.PostRPC(c.endpoint, method, string(params)) + resp, err := rpctypes.PostRPC(c.endpoint, method, string(params)) if err != nil { return err } @@ -321,7 +321,7 @@ func (c *client) callCreateWallet(filename, password string) error { return err } - resp, err := rpcclient.PostRPC(c.endpoint, method, string(params)) + resp, err := rpctypes.PostRPC(c.endpoint, method, string(params)) if err != nil { return err } @@ -340,7 +340,7 @@ type getHeightResponse struct { func (c *client) callGetHeight() (uint, error) { const method = "get_height" - resp, err := rpcclient.PostRPC(c.endpoint, method, "{}") + resp, err := rpctypes.PostRPC(c.endpoint, method, "{}") if err != nil { return 0, err } diff --git a/monero/utils.go b/monero/utils.go index aafe2d0d..4df9b271 100644 --- a/monero/utils.go +++ b/monero/utils.go @@ -19,32 +19,35 @@ var ( log = logging.Logger("monero") ) -// WaitForBlocks waits for a new block to arrive. -func WaitForBlocks(client Client) (uint, error) { +// WaitForBlocks waits for `count` new blocks to arrive. +// It returns the height of the chain. +func WaitForBlocks(client Client, count int) (uint, error) { prevHeight, err := client.GetHeight() if err != nil { return 0, fmt.Errorf("failed to get height: %w", err) } - for i := 0; i < maxRetries; i++ { - if err := client.Refresh(); err != nil { - return 0, err - } + for j := 0; j < count; j++ { + for i := 0; i < maxRetries; i++ { + if err := client.Refresh(); err != nil { + return 0, err + } - height, err := client.GetHeight() - if err != nil { - continue - } + height, err := client.GetHeight() + if err != nil { + continue + } - if height > prevHeight { - return height, nil - } + if height > prevHeight { + return height, nil + } - log.Infof("waiting for next block, current height=%d", height) - time.Sleep(blockSleepDuration) + log.Infof("waiting for next block, current height=%d", height) + time.Sleep(blockSleepDuration) + } } - return 0, fmt.Errorf("timed out waiting for next block") + return 0, fmt.Errorf("timed out waiting for blocks") } // CreateMoneroWallet creates a monero wallet from a private keypair. diff --git a/monero/utils_test.go b/monero/utils_test.go index cd7211f7..ce1d7d91 100644 --- a/monero/utils_test.go +++ b/monero/utils_test.go @@ -20,7 +20,7 @@ func TestWaitForBlocks(t *testing.T) { _ = daemon.callGenerateBlocks(addr.Address, 181) }() - _, err = WaitForBlocks(c) + _, err = WaitForBlocks(c, 1) require.NoError(t, err) } diff --git a/net/errors.go b/net/errors.go new file mode 100644 index 00000000..4d83f56a --- /dev/null +++ b/net/errors.go @@ -0,0 +1,13 @@ +package net + +import ( + "errors" +) + +var ( + errNilStream = errors.New("stream is nil") + errFailedToBootstrap = errors.New("failed to bootstrap to any bootnode") + errNoOngoingSwap = errors.New("no swap currently happening") + errSwapAlreadyInProgress = errors.New("already have ongoing swap") + errInvalidBufferLength = errors.New("buffer has length 0") +) diff --git a/net/host.go b/net/host.go index 2be3d962..c423a465 100644 --- a/net/host.go +++ b/net/host.go @@ -2,7 +2,6 @@ package net import ( "context" - "errors" "fmt" "sync" "time" @@ -231,7 +230,7 @@ func (h *host) SendSwapMessage(msg Message) error { defer h.swapMu.Unlock() if h.swapStream == nil { - return errors.New("no swap currently happening") + return errNoOngoingSwap } return h.writeToStream(h.swapStream, msg) @@ -294,7 +293,7 @@ func (h *host) handleConn(conn libp2pnetwork.Conn) { // readStream reads from the stream into the given buffer, returning the number of bytes read func readStream(stream libp2pnetwork.Stream, buf []byte) (int, error) { if stream == nil { - return 0, errors.New("stream is nil") + return 0, errNilStream } var ( @@ -349,7 +348,7 @@ func (h *host) bootstrap() error { } if failed == len(h.bootnodes) && len(h.bootnodes) != 0 { - return errors.New("failed to bootstrap to any bootnode") + return errFailedToBootstrap } return nil diff --git a/net/initiate.go b/net/initiate.go index 4f39c052..a5e186e9 100644 --- a/net/initiate.go +++ b/net/initiate.go @@ -2,7 +2,6 @@ package net import ( "context" - "errors" "fmt" "time" @@ -24,7 +23,7 @@ func (h *host) Initiate(who peer.AddrInfo, msg *SendKeysMessage, s common.SwapSt defer h.swapMu.Unlock() if h.swapState != nil { - return errors.New("already have ongoing swap") + return errSwapAlreadyInProgress } ctx, cancel := context.WithTimeout(h.ctx, protocolTimeout) diff --git a/net/utils.go b/net/utils.go index 818732c6..7909954d 100644 --- a/net/utils.go +++ b/net/utils.go @@ -3,7 +3,6 @@ package net import ( crand "crypto/rand" "encoding/hex" - "errors" "fmt" "io" "io/ioutil" @@ -114,7 +113,7 @@ func uint64ToLEB128(in uint64) []byte { func readLEB128ToUint64(r io.Reader, buf []byte) (uint64, int, error) { if len(buf) == 0 { - return 0, 0, errors.New("buffer has length 0") + return 0, 0, errInvalidBufferLength } var out uint64 diff --git a/protocol/alice/errors.go b/protocol/alice/errors.go index b046f0dd..a90f1c13 100644 --- a/protocol/alice/errors.go +++ b/protocol/alice/errors.go @@ -5,10 +5,25 @@ import ( ) var ( - errNoOngoingSwap = errors.New("no ongoing swap") - errUnexpectedMessageType = errors.New("unexpected message type") - errMissingKeys = errors.New("did not receive Bob's public spend or private view key") - errMissingAddress = errors.New("did not receive Bob's address") - errNoClaimLogsFound = errors.New("no Claimed logs found") - errCannotRefund = errors.New("swap is not at a stage where it can refund") + // various instance and swap errors + errNilSwapContractOrAddress = errors.New("must provide swap contract and address") + errNoOngoingSwap = errors.New("no ongoing swap") + errUnexpectedMessageType = errors.New("unexpected message type") + errMissingKeys = errors.New("did not receive Bob's public spend or private view key") + errMissingAddress = errors.New("did not receive Bob's address") + errNoClaimLogsFound = errors.New("no Claimed logs found") + errCannotRefund = errors.New("swap is not at a stage where it can refund") + errNilMessage = errors.New("message is nil") + errIncorrectMessageType = errors.New("received unexpected message") + errNoLockedXMRAddress = errors.New("got empty address for locked XMR") + errClaimTxHasNoLogs = errors.New("claim transaction has no logs") + errNoPublicKeysSet = errors.New("our public keys aren't set") + errCounterpartyKeysNotSet = errors.New("counterparty's keys aren't set") + errSwapInstantiationNoLogs = errors.New("expected 1 log, got 0") + errSwapCompleted = errors.New("swap has already completed") + + // inititation errors + errProtocolAlreadyInProgress = errors.New("protocol already in progress") + errBalanceTooLow = errors.New("eth balance lower than amount to be provided") + errNoSwapContractSet = errors.New("no swap contract found") ) diff --git a/protocol/alice/instance.go b/protocol/alice/instance.go index cc41a252..d06f5179 100644 --- a/protocol/alice/instance.go +++ b/protocol/alice/instance.go @@ -108,7 +108,7 @@ func NewInstance(cfg *Config) (*Instance, error) { } if cfg.SwapContract == nil || (cfg.SwapContractAddress == ethcommon.Address{}) { - return nil, fmt.Errorf("must provide swap contract and address") + return nil, errNilSwapContractOrAddress } // TODO: check that Alice's monero-wallet-cli endpoint has wallet-dir configured diff --git a/protocol/alice/instance_test.go b/protocol/alice/instance_test.go new file mode 100644 index 00000000..d54b3c28 --- /dev/null +++ b/protocol/alice/instance_test.go @@ -0,0 +1,20 @@ +package alice + +import ( + "testing" + + "github.com/noot/atomic-swap/common" + "github.com/noot/atomic-swap/monero" + + "github.com/stretchr/testify/require" +) + +func TestGetAddress(t *testing.T) { + c := monero.NewClient(common.DefaultAliceMoneroEndpoint) + addr, err := getAddress(c, "", "") + require.NoError(t, err) + + addr2, err := getAddress(c, swapDepositWallet, "") + require.NoError(t, err) + require.Equal(t, addr, addr2) +} diff --git a/protocol/alice/message_handler.go b/protocol/alice/message_handler.go index 360730f2..107aa535 100644 --- a/protocol/alice/message_handler.go +++ b/protocol/alice/message_handler.go @@ -1,7 +1,6 @@ package alice import ( - "errors" "fmt" "time" @@ -54,7 +53,7 @@ func (s *swapState) HandleProtocolMessage(msg net.Message) (net.Message, bool, e s.clearNextExpectedMessage(types.CompletedSuccess) return nil, true, nil default: - return nil, false, errors.New("unexpected message type") + return nil, false, errUnexpectedMessageType } } @@ -86,7 +85,7 @@ func (s *swapState) setNextExpectedMessage(msg net.Message) { func (s *swapState) checkMessageType(msg net.Message) error { if msg == nil { - return errors.New("message is nil") + return errNilMessage } if s.nextExpectedMessage == nil { @@ -94,7 +93,7 @@ func (s *swapState) checkMessageType(msg net.Message) error { } if msg.Type() != s.nextExpectedMessage.Type() { - return errors.New("received unexpected message") + return errIncorrectMessageType } return nil @@ -222,7 +221,7 @@ func (s *swapState) handleSendKeysMessage(msg *net.SendKeysMessage) (net.Message func (s *swapState) handleNotifyXMRLock(msg *message.NotifyXMRLock) (net.Message, error) { if msg.Address == "" { - return nil, errors.New("got empty address for locked XMR") + return nil, errNoLockedXMRAddress } // check that XMR was locked in expected account, and confirm amount @@ -246,14 +245,7 @@ func (s *swapState) handleNotifyXMRLock(msg *message.NotifyXMRLock) (net.Message log.Infof("waiting for new blocks...") // wait for 2 new blocks, otherwise balance might be 0 // TODO: check transaction hash - height, err := monero.WaitForBlocks(s.alice.client) - if err != nil { - return nil, err - } - - log.Infof("monero block height: %d", height) - - height, err = monero.WaitForBlocks(s.alice.client) + height, err := monero.WaitForBlocks(s.alice.client, 2) if err != nil { return nil, err } @@ -370,7 +362,7 @@ func (s *swapState) handleNotifyClaimed(txHash string) (mcrypto.Address, error) } if len(receipt.Logs) == 0 { - return "", errors.New("claim transaction has no logs") + return "", errClaimTxHasNoLogs } log.Infof("counterparty claimed ETH; tx hash=%s", txHash) diff --git a/protocol/alice/net.go b/protocol/alice/net.go index 64190948..f25e124e 100644 --- a/protocol/alice/net.go +++ b/protocol/alice/net.go @@ -1,8 +1,6 @@ package alice import ( - "errors" - "github.com/noot/atomic-swap/common" "github.com/noot/atomic-swap/common/types" pcommon "github.com/noot/atomic-swap/protocol" @@ -34,7 +32,7 @@ func (a *Instance) initiate(providesAmount common.EtherAmount, receivedAmount co defer a.swapMu.Unlock() if a.swapState != nil { - return errors.New("protocol already in progress") + return errProtocolAlreadyInProgress } balance, err := a.ethClient.BalanceAt(a.ctx, a.callOpts.From, nil) @@ -44,7 +42,7 @@ func (a *Instance) initiate(providesAmount common.EtherAmount, receivedAmount co // check user's balance and that they actually have what they will provide if balance.Cmp(providesAmount.BigInt()) <= 0 { - return errors.New("balance lower than amount to be provided") + return errBalanceTooLow } a.swapState, err = newSwapState(a, pcommon.GetSwapInfoFilepath(a.basepath), providesAmount, diff --git a/protocol/alice/recovery_test.go b/protocol/alice/recovery_test.go index 66ab22e9..dc383cc8 100644 --- a/protocol/alice/recovery_test.go +++ b/protocol/alice/recovery_test.go @@ -24,15 +24,6 @@ func newTestRecoveryState(t *testing.T) *recoveryState { s.setBobKeys(s.pubkeys.SpendKey(), s.privkeys.ViewKey(), akp.Secp256k1PublicKey) s.bobAddress = inst.callOpts.From - // skAB := mcrypto.SumPrivateSpendKeys(s.privkeys.SpendKey(), s.privkeys.SpendKey()) - // vkAB := mcrypto.SumPrivateViewKeys(s.privkeys.ViewKey(), s.privkeys.ViewKey()) - // kpAB := mcrypto.NewPrivateKeyPair(skAB, vkAB) - // require.NoError(t, err) - // xmrAddr := kpAB.Address(common.Development) - - // _, err = inst.client.Transfer(xmrAddr, 0, 1000000000) - // require.NoError(t, err) - _, err = s.lockETH(common.NewEtherAmount(1)) require.NoError(t, err) diff --git a/protocol/alice/swap_state.go b/protocol/alice/swap_state.go index db25fc6d..fb7b13c9 100644 --- a/protocol/alice/swap_state.go +++ b/protocol/alice/swap_state.go @@ -3,7 +3,6 @@ package alice import ( "context" "encoding/hex" - "errors" "fmt" "math/big" "strings" @@ -69,7 +68,7 @@ type swapState struct { func newSwapState(a *Instance, infofile string, providesAmount common.EtherAmount, receivedAmount common.MoneroAmount, exhangeRate types.ExchangeRate) (*swapState, error) { if a.contract == nil { - return nil, errors.New("no swap contract found") + return nil, errNoSwapContractSet } txOpts, err := bind.NewKeyedTransactorWithChainID(a.ethPrivKey, a.chainID) @@ -319,7 +318,7 @@ func (s *swapState) tryRefund() (ethcommon.Hash, error) { func (s *swapState) setTimeouts() error { if s.alice.contract == nil { - return errors.New("contract is nil") + return errNoSwapContractSet } if (s.t0 != time.Time{}) && (s.t1 != time.Time{}) { @@ -387,11 +386,11 @@ func (s *swapState) setBobKeys(sk *mcrypto.PublicKey, vk *mcrypto.PrivateViewKey // lockETH the Swap contract function new_swap and locks `amount` ether in it. func (s *swapState) lockETH(amount common.EtherAmount) (ethcommon.Hash, error) { if s.pubkeys == nil { - return ethcommon.Hash{}, errors.New("public keys aren't set") + return ethcommon.Hash{}, errNoPublicKeysSet } if s.bobPublicSpendKey == nil || s.bobPrivateViewKey == nil { - return ethcommon.Hash{}, errors.New("bob's keys aren't set") + return ethcommon.Hash{}, errCounterpartyKeysNotSet } cmtAlice := s.secp256k1Pub.Keccak256() @@ -415,7 +414,7 @@ func (s *swapState) lockETH(amount common.EtherAmount) (ethcommon.Hash, error) { } if len(receipt.Logs) == 0 { - return ethcommon.Hash{}, errors.New("expected 1 log, got 0") + return ethcommon.Hash{}, errSwapInstantiationNoLogs } s.contractSwapID, err = swapfactory.GetIDFromLog(receipt.Logs[0]) @@ -451,7 +450,7 @@ func (s *swapState) ready() error { // If time t_1 passes and Claim() has not been called, Alice should call Refund(). func (s *swapState) refund() (ethcommon.Hash, error) { if s.alice.contract == nil { - return ethcommon.Hash{}, errors.New("contract is nil") + return ethcommon.Hash{}, errNoSwapContractSet } sc := s.getSecret() @@ -472,7 +471,7 @@ func (s *swapState) refund() (ethcommon.Hash, error) { func (s *swapState) claimMonero(skB *mcrypto.PrivateSpendKey) (mcrypto.Address, error) { if !s.info.Status().IsOngoing() { - return "", errors.New("swap has already completed") + return "", errSwapCompleted } skAB := mcrypto.SumPrivateSpendKeys(skB, s.privkeys.SpendKey()) diff --git a/protocol/bob/errors.go b/protocol/bob/errors.go index dcb8ff6e..63b29976 100644 --- a/protocol/bob/errors.go +++ b/protocol/bob/errors.go @@ -5,9 +5,26 @@ import ( ) var ( - errUnexpectedMessageType = errors.New("unexpected message type") - errMissingKeys = errors.New("did not receive Alice's public spend or view key") - errMissingAddress = errors.New("got empty contract address") - errNoRefundLogsFound = errors.New("no refund logs found") - errPastClaimTime = errors.New("past t1, can no longer claim") + // various instance and swap errors + errMustProvideDaemonEndpoint = errors.New("environment is development, must provide monero daemon endpoint") + errUnexpectedMessageType = errors.New("unexpected message type") + errMissingKeys = errors.New("did not receive Alice's public spend or view key") + errMissingAddress = errors.New("got empty contract address") + errNoRefundLogsFound = errors.New("no refund logs found") + errPastClaimTime = errors.New("past t1, can no longer claim") + errNilSwapState = errors.New("swap state is nil") + errNilMessage = errors.New("message is nil") + errIncorrectMessageType = errors.New("received unexpected message") + errNilContractSwapID = errors.New("expected swapID in NotifyETHLocked message") + errClaimTxHasNoLogs = errors.New("claim transaction has no logs") + errCannotFindNewLog = errors.New("cannot find New log") + errUnexpectedSwapID = errors.New("unexpected swap ID was emitted by New log") + + // protocol initiation errors + errProtocolAlreadyInProgress = errors.New("protocol already in progress") + errBalanceTooLow = errors.New("balance lower than amount to be provided") + errNoOfferWithID = errors.New("failed to find offer with given ID") + errAmountProvidedTooLow = errors.New("amount provided by taker is too low for offer") + errAmountProvidedTooHigh = errors.New("amount provided by taker is too high for offer") + errUnlockedBalanceTooLow = errors.New("unlocked balance is less than maximum offer amount") ) diff --git a/protocol/bob/instance.go b/protocol/bob/instance.go index 6a351ddc..8bc28fbf 100644 --- a/protocol/bob/instance.go +++ b/protocol/bob/instance.go @@ -3,7 +3,6 @@ package bob import ( "context" "crypto/ecdsa" - "errors" "math/big" "sync" @@ -71,7 +70,7 @@ type Config struct { // It accepts an endpoint to a monero-wallet-rpc instance where account 0 contains Bob's XMR. func NewInstance(cfg *Config) (*Instance, error) { if cfg.Environment == common.Development && cfg.MoneroDaemonEndpoint == "" { - return nil, errors.New("environment is development, must provide monero daemon endpoint") + return nil, errMustProvideDaemonEndpoint } addr := common.EthereumPrivateKeyToAddress(cfg.EthereumPrivateKey) diff --git a/protocol/bob/message_handler.go b/protocol/bob/message_handler.go index bf7b5dba..1a6b7b9c 100644 --- a/protocol/bob/message_handler.go +++ b/protocol/bob/message_handler.go @@ -1,7 +1,6 @@ package bob import ( - "errors" "fmt" "time" @@ -21,7 +20,7 @@ import ( // this function will return an error. func (s *swapState) HandleProtocolMessage(msg net.Message) (net.Message, bool, error) { if s == nil { - return nil, true, errors.New("swap state is nil") + return nil, true, errNilSwapState } s.Lock() @@ -77,7 +76,7 @@ func (s *swapState) HandleProtocolMessage(msg net.Message) (net.Message, bool, e log.Infof("regained control over monero account %s", addr) return nil, true, nil default: - return nil, true, errors.New("unexpected message type") + return nil, true, errUnexpectedMessageType } } @@ -108,7 +107,7 @@ func (s *swapState) setNextExpectedMessage(msg net.Message) { func (s *swapState) checkMessageType(msg net.Message) error { if msg == nil { - return errors.New("message is nil") + return errNilMessage } if s == nil || s.nextExpectedMessage == nil { @@ -121,7 +120,7 @@ func (s *swapState) checkMessageType(msg net.Message) error { } if msg.Type() != s.nextExpectedMessage.Type() { - return errors.New("received unexpected message") + return errIncorrectMessageType } return nil @@ -133,7 +132,7 @@ func (s *swapState) handleNotifyETHLocked(msg *message.NotifyETHLocked) (net.Mes } if msg.ContractSwapID == nil { - return nil, errors.New("expected swapID in NotifyETHLocked message") + return nil, errNilContractSwapID } log.Infof("got NotifyETHLocked; address=%s contract swap ID=%d", msg.Address, msg.ContractSwapID) @@ -237,7 +236,7 @@ func (s *swapState) handleRefund(txHash string) (mcrypto.Address, error) { } if len(receipt.Logs) == 0 { - return "", errors.New("claim transaction has no logs") + return "", errClaimTxHasNoLogs } sa, err := swapfactory.GetSecretFromLog(receipt.Logs[0], "Refunded") diff --git a/protocol/bob/net.go b/protocol/bob/net.go index 222efd76..972d3cbd 100644 --- a/protocol/bob/net.go +++ b/protocol/bob/net.go @@ -1,8 +1,6 @@ package bob import ( - "errors" - "github.com/noot/atomic-swap/common" "github.com/noot/atomic-swap/common/types" "github.com/noot/atomic-swap/net" @@ -22,7 +20,7 @@ func (b *Instance) initiate(offer *types.Offer, offerExtra *types.OfferExtra, pr defer b.swapMu.Unlock() if b.swapState != nil { - return errors.New("protocol already in progress") + return errProtocolAlreadyInProgress } balance, err := b.client.GetBalance(0) @@ -32,7 +30,7 @@ func (b *Instance) initiate(offer *types.Offer, offerExtra *types.OfferExtra, pr // check user's balance and that they actually have what they will provide if balance.UnlockedBalance <= float64(providesAmount) { - return errors.New("balance lower than amount to be provided") + return errBalanceTooLow } b.swapState, err = newSwapState(b, offer, offerExtra.StatusCh, offerExtra.InfoFile, providesAmount, desiredAmount) @@ -65,17 +63,17 @@ func (b *Instance) HandleInitiateMessage(msg *net.SendKeysMessage) (net.SwapStat offer, offerExtra := b.offerManager.getAndDeleteOffer(id) if offer == nil { - return nil, nil, errors.New("failed to find offer with given ID") + return nil, nil, errNoOfferWithID } providedAmount := offer.ExchangeRate.ToXMR(msg.ProvidedAmount) if providedAmount < offer.MinimumAmount { - return nil, nil, errors.New("amount provided by taker is too low for offer") + return nil, nil, errAmountProvidedTooLow } if providedAmount > offer.MaximumAmount { - return nil, nil, errors.New("amount provided by taker is too low for offer") + return nil, nil, errAmountProvidedTooHigh } if err = b.initiate(offer, offerExtra, common.MoneroToPiconero(providedAmount), common.EtherToWei(msg.ProvidedAmount)); err != nil { //nolint:lll diff --git a/protocol/bob/offers.go b/protocol/bob/offers.go index a0a172ee..8304ab8f 100644 --- a/protocol/bob/offers.go +++ b/protocol/bob/offers.go @@ -1,8 +1,6 @@ package bob import ( - "errors" - "github.com/noot/atomic-swap/common" "github.com/noot/atomic-swap/common/types" pcommon "github.com/noot/atomic-swap/protocol" @@ -64,7 +62,7 @@ func (b *Instance) MakeOffer(o *types.Offer) (*types.OfferExtra, error) { } if common.MoneroAmount(balance.UnlockedBalance) < common.MoneroToPiconero(o.MaximumAmount) { - return nil, errors.New("unlocked balance is less than maximum offer amount") + return nil, errUnlockedBalanceTooLow } extra := b.offerManager.putOffer(o) diff --git a/protocol/bob/swap_state.go b/protocol/bob/swap_state.go index e187c4c0..7f73c730 100644 --- a/protocol/bob/swap_state.go +++ b/protocol/bob/swap_state.go @@ -5,7 +5,6 @@ import ( "context" "crypto/ecdsa" "encoding/hex" - "errors" "fmt" "math/big" "strings" @@ -157,7 +156,7 @@ func (s *swapState) ID() uint64 { // If the swap already completed successfully, this function does not doing anything in regards to the protoco. func (s *swapState) Exit() error { if s == nil { - return errors.New("swap state is nil") + return errNilSwapState } s.Lock() @@ -167,7 +166,7 @@ func (s *swapState) Exit() error { func (s *swapState) exit() error { if s == nil { - return errors.New("swap state is nil") + return errNilSwapState } log.Debugf("attempting to exit swap: nextExpectedMessage=%v", s.nextExpectedMessage) @@ -411,7 +410,7 @@ func (s *swapState) checkContract(txHash ethcommon.Hash) error { // check that New log was emitted if len(receipt.Logs) == 0 { - return errors.New("cannot find New log") + return errCannotFindNewLog } event, err := s.contract.ParseNew(*receipt.Logs[0]) @@ -420,7 +419,7 @@ func (s *swapState) checkContract(txHash ethcommon.Hash) error { } if event.SwapID.Cmp(s.contractSwapID) != 0 { - return errors.New("unexpected swap ID was emitted by New log") + return errUnexpectedSwapID } // check that contract was constructed with correct secp256k1 keys @@ -482,7 +481,7 @@ func (s *swapState) lockFunds(amount common.MoneroAmount) (mcrypto.Address, erro _ = s.bob.daemonClient.GenerateBlocks(bobAddr.Address, 2) } else { // otherwise, wait for new blocks - height, err := monero.WaitForBlocks(s.bob.client) + height, err := monero.WaitForBlocks(s.bob.client, 1) if err != nil { return "", err } diff --git a/protocol/common.go b/protocol/common.go index 88aac98c..af63553f 100644 --- a/protocol/common.go +++ b/protocol/common.go @@ -2,7 +2,6 @@ package protocol import ( "encoding/hex" - "errors" mcrypto "github.com/noot/atomic-swap/crypto/monero" "github.com/noot/atomic-swap/crypto/secp256k1" @@ -67,7 +66,7 @@ func VerifyKeysAndProof(proofStr, secp256k1PubString string) (*secp256k1.PublicK } if res.Secp256k1PublicKey().String() != secp256k1PubString { - return nil, errors.New("secp256k1 public key resulting from proof verification does not match key sent") + return nil, errInvalidSecp256k1Key } secp256k1Pub, err := secp256k1.NewPublicKeyFromHex(secp256k1PubString) diff --git a/protocol/errors.go b/protocol/errors.go new file mode 100644 index 00000000..b832b8e0 --- /dev/null +++ b/protocol/errors.go @@ -0,0 +1,9 @@ +package protocol + +import ( + "errors" +) + +var ( + errInvalidSecp256k1Key = errors.New("secp256k1 public key resulting from proof verification does not match key sent") +) diff --git a/rpc/errors.go b/rpc/errors.go new file mode 100644 index 00000000..dc359ab4 --- /dev/null +++ b/rpc/errors.go @@ -0,0 +1,20 @@ +package rpc + +import ( + "errors" +) + +var ( + // net_ errors + errNoOfferWithID = errors.New("peer does not have offer with given ID") + errFailedToGetSwapInfo = errors.New("failed to get swap info after initiating") + + // swap_ errors + errNoSwapWithID = errors.New("unable to find swap with given ID") + errNoOngoingSwap = errors.New("no current ongoing swap") + errCannotRefund = errors.New("cannot refund if not the ETH provider") + + // ws errors + errUnimplemented = errors.New("unimplemented") + errInvalidMethod = errors.New("invalid method") +) diff --git a/rpc/net.go b/rpc/net.go index 870debd8..fcf0efd3 100644 --- a/rpc/net.go +++ b/rpc/net.go @@ -1,7 +1,6 @@ package rpc import ( - "errors" "fmt" "net/http" "time" @@ -142,7 +141,7 @@ func (s *NetService) takeOffer(multiaddr, offerID string, } if !found { - return 0, nil, "", errors.New("peer does not have offer with given ID") + return 0, nil, "", errNoOfferWithID } swapState, err := s.alice.InitiateProtocol(providesAmount, offer) @@ -165,7 +164,7 @@ func (s *NetService) takeOffer(multiaddr, offerID string, info := s.sm.GetOngoingSwap() if info == nil { - return 0, nil, "", errors.New("failed to get swap info after initiating") + return 0, nil, "", errFailedToGetSwapInfo } return swapState.ID(), info.StatusCh(), swapState.InfoFile(), nil diff --git a/rpc/net_test.go b/rpc/net_test.go new file mode 100644 index 00000000..453d10e2 --- /dev/null +++ b/rpc/net_test.go @@ -0,0 +1,74 @@ +package rpc + +import ( + "testing" + + "github.com/noot/atomic-swap/common/rpctypes" + "github.com/noot/atomic-swap/common/types" + + "github.com/stretchr/testify/require" +) + +func TestNet_Discover(t *testing.T) { + ns := NewNetService(new(mockNet), new(mockAlice), nil, new(mockSwapManager)) + + req := &rpctypes.DiscoverRequest{ + Provides: "", + } + + resp := new(rpctypes.DiscoverResponse) + + err := ns.Discover(nil, req, resp) + require.NoError(t, err) + require.Equal(t, 0, len(resp.Peers)) +} + +func TestNet_Query(t *testing.T) { + ns := NewNetService(new(mockNet), new(mockAlice), nil, new(mockSwapManager)) + + req := &rpctypes.QueryPeerRequest{ + Multiaddr: "/ip4/127.0.0.1/tcp/9900/p2p/12D3KooWDqCzbjexHEa8Rut7bzxHFpRMZyDRW1L6TGkL1KY24JH5", + } + + resp := new(rpctypes.QueryPeerResponse) + + err := ns.QueryPeer(nil, req, resp) + require.NoError(t, err) + require.Equal(t, 1, len(resp.Offers)) +} + +func TestNet_TakeOffer(t *testing.T) { + ns := NewNetService(new(mockNet), new(mockAlice), nil, new(mockSwapManager)) + + offer := &types.Offer{} + + req := &rpctypes.TakeOfferRequest{ + Multiaddr: "/ip4/127.0.0.1/tcp/9900/p2p/12D3KooWDqCzbjexHEa8Rut7bzxHFpRMZyDRW1L6TGkL1KY24JH5", + OfferID: offer.GetID().String(), + ProvidesAmount: 1, + } + + resp := new(rpctypes.TakeOfferResponse) + + err := ns.TakeOffer(nil, req, resp) + require.NoError(t, err) + require.Equal(t, testSwapID, resp.ID) +} + +func TestNet_TakeOfferSync(t *testing.T) { + ns := NewNetService(new(mockNet), new(mockAlice), nil, new(mockSwapManager)) + + offer := &types.Offer{} + + req := &rpctypes.TakeOfferRequest{ + Multiaddr: "/ip4/127.0.0.1/tcp/9900/p2p/12D3KooWDqCzbjexHEa8Rut7bzxHFpRMZyDRW1L6TGkL1KY24JH5", + OfferID: offer.GetID().String(), + ProvidesAmount: 1, + } + + resp := new(TakeOfferSyncResponse) + + err := ns.TakeOfferSync(nil, req, resp) + require.NoError(t, err) + require.Equal(t, testSwapID, resp.ID) +} diff --git a/rpc/swap.go b/rpc/swap.go index f3a1081f..96edd2cd 100644 --- a/rpc/swap.go +++ b/rpc/swap.go @@ -1,7 +1,6 @@ package rpc import ( - "errors" "fmt" "net/http" @@ -56,7 +55,7 @@ type GetPastResponse struct { func (s *SwapService) GetPast(_ *http.Request, req *GetPastRequest, resp *GetPastResponse) error { info := s.sm.GetPastSwap(req.ID) if info == nil { - return errors.New("unable to find swap with given ID") + return errNoSwapWithID } resp.Provided = info.Provides() @@ -81,7 +80,7 @@ type GetOngoingResponse struct { func (s *SwapService) GetOngoing(_ *http.Request, _ *interface{}, resp *GetOngoingResponse) error { info := s.sm.GetOngoingSwap() if info == nil { - return errors.New("no current ongoing swap") + return errNoOngoingSwap } resp.ID = info.ID() @@ -103,11 +102,11 @@ type RefundResponse struct { func (s *SwapService) Refund(_ *http.Request, _ *interface{}, resp *RefundResponse) error { info := s.sm.GetOngoingSwap() if info == nil { - return errors.New("no current ongoing swap") + return errNoOngoingSwap } if info.Provides() != types.ProvidesETH { - return errors.New("cannot refund if not the ETH provider") + return errCannotRefund } txHash, err := s.alice.Refund() @@ -129,7 +128,7 @@ type GetStageResponse struct { func (s *SwapService) GetStage(_ *http.Request, _ *interface{}, resp *GetStageResponse) error { info := s.sm.GetOngoingSwap() if info == nil { - return errors.New("no current ongoing swap") + return errNoOngoingSwap } resp.Stage = info.Status().String() @@ -157,7 +156,7 @@ type CancelResponse struct { func (s *SwapService) Cancel(_ *http.Request, _ *interface{}, resp *CancelResponse) error { info := s.sm.GetOngoingSwap() if info == nil { - return errors.New("no current ongoing swap") + return errNoOngoingSwap } var ss common.SwapState diff --git a/rpc/ws.go b/rpc/ws.go index e6cdb4c7..9ecb38f8 100644 --- a/rpc/ws.go +++ b/rpc/ws.go @@ -3,7 +3,6 @@ package rpc import ( "context" "encoding/json" - "errors" "fmt" "net/http" @@ -71,7 +70,7 @@ func (s *wsServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (s *wsServer) handleRequest(conn *websocket.Conn, req *rpctypes.Request) error { switch req.Method { case subscribeNewPeer: - return errors.New("unimplemented") + return errUnimplemented case "net_discover": var params *rpctypes.DiscoverRequest if err := json.Unmarshal(req.Params, ¶ms); err != nil { @@ -131,7 +130,7 @@ func (s *wsServer) handleRequest(conn *websocket.Conn, req *rpctypes.Request) er s.ns.net.Advertise() return s.subscribeMakeOffer(s.ctx, conn, offerID, offerExtra) default: - return errors.New("invalid method") + return errInvalidMethod } } @@ -266,7 +265,7 @@ func (s *wsServer) subscribeSwapStatus(ctx context.Context, conn *websocket.Conn func (s *wsServer) writeSwapExitStatus(conn *websocket.Conn, id uint64) error { info := s.sm.GetPastSwap(id) if info == nil { - return errors.New("unable to find swap with given ID") + return errNoSwapWithID } resp := &rpctypes.SubscribeSwapStatusResponse{ diff --git a/rpc/ws_test.go b/rpc/ws_test.go index 2d7ff4f6..3c730cda 100644 --- a/rpc/ws_test.go +++ b/rpc/ws_test.go @@ -8,11 +8,11 @@ import ( "time" "github.com/noot/atomic-swap/common" - "github.com/noot/atomic-swap/common/rpcclient" "github.com/noot/atomic-swap/common/types" "github.com/noot/atomic-swap/net" "github.com/noot/atomic-swap/net/message" "github.com/noot/atomic-swap/protocol/swap" + "github.com/noot/atomic-swap/rpcclient/wsclient" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/libp2p/go-libp2p-core/peer" @@ -149,7 +149,7 @@ func TestSubscribeSwapStatus(t *testing.T) { t.Cleanup(func() { cancel() }) - c, err := rpcclient.NewWsClient(ctx, defaultWSEndpoint()) + c, err := wsclient.NewWsClient(ctx, defaultWSEndpoint()) require.NoError(t, err) ch, err := c.SubscribeSwapStatus(testSwapID) @@ -192,7 +192,7 @@ func TestSubscribeTakeOffer(t *testing.T) { t.Cleanup(func() { cancel() }) - c, err := rpcclient.NewWsClient(ctx, defaultWSEndpoint()) + c, err := wsclient.NewWsClient(ctx, defaultWSEndpoint()) require.NoError(t, err) offerID := (&types.Offer{}).GetID() diff --git a/cmd/client/client/addresses.go b/rpcclient/addresses.go similarity index 77% rename from cmd/client/client/addresses.go rename to rpcclient/addresses.go index 4740f313..5712030f 100644 --- a/cmd/client/client/addresses.go +++ b/rpcclient/addresses.go @@ -1,9 +1,9 @@ -package client +package rpcclient import ( "encoding/json" - "github.com/noot/atomic-swap/common/rpcclient" + "github.com/noot/atomic-swap/common/rpctypes" "github.com/noot/atomic-swap/rpc" ) @@ -13,7 +13,7 @@ func (c *Client) Addresses() ([]string, error) { method = "net_addresses" ) - resp, err := rpcclient.PostRPC(c.endpoint, method, "{}") + resp, err := rpctypes.PostRPC(c.endpoint, method, "{}") if err != nil { return nil, err } diff --git a/cmd/client/client/cancel.go b/rpcclient/cancel.go similarity index 78% rename from cmd/client/client/cancel.go rename to rpcclient/cancel.go index 50dd5be6..6c0655f1 100644 --- a/cmd/client/client/cancel.go +++ b/rpcclient/cancel.go @@ -1,9 +1,9 @@ -package client +package rpcclient import ( "encoding/json" - "github.com/noot/atomic-swap/common/rpcclient" + "github.com/noot/atomic-swap/common/rpctypes" "github.com/noot/atomic-swap/common/types" "github.com/noot/atomic-swap/rpc" ) @@ -14,7 +14,7 @@ func (c *Client) Cancel() (types.Status, error) { method = "swap_cancel" ) - resp, err := rpcclient.PostRPC(c.endpoint, method, "{}") + resp, err := rpctypes.PostRPC(c.endpoint, method, "{}") if err != nil { return 0, err } diff --git a/cmd/client/client/client.go b/rpcclient/client.go similarity index 55% rename from cmd/client/client/client.go rename to rpcclient/client.go index 6267162b..2792a9db 100644 --- a/cmd/client/client/client.go +++ b/rpcclient/client.go @@ -1,6 +1,6 @@ -package client +package rpcclient -// Client represents a swap client, used to interact with a swap daemon via JSON-RPC calls. +// Client represents a swap RPC client, used to interact with a swap daemon via JSON-RPC calls. type Client struct { endpoint string } diff --git a/cmd/client/client/discover.go b/rpcclient/discover.go similarity index 83% rename from cmd/client/client/discover.go rename to rpcclient/discover.go index 13b94d09..286f80ef 100644 --- a/cmd/client/client/discover.go +++ b/rpcclient/discover.go @@ -1,9 +1,8 @@ -package client +package rpcclient import ( "encoding/json" - "github.com/noot/atomic-swap/common/rpcclient" "github.com/noot/atomic-swap/common/rpctypes" "github.com/noot/atomic-swap/common/types" ) @@ -24,7 +23,7 @@ func (c *Client) Discover(provides types.ProvidesCoin, searchTime uint64) ([][]s return nil, err } - resp, err := rpcclient.PostRPC(c.endpoint, method, string(params)) + resp, err := rpctypes.PostRPC(c.endpoint, method, string(params)) if err != nil { return nil, err } diff --git a/cmd/client/client/get_offers.go b/rpcclient/get_offers.go similarity index 79% rename from cmd/client/client/get_offers.go rename to rpcclient/get_offers.go index cd6f2406..3e84466b 100644 --- a/cmd/client/client/get_offers.go +++ b/rpcclient/get_offers.go @@ -1,9 +1,9 @@ -package client +package rpcclient import ( "encoding/json" - "github.com/noot/atomic-swap/common/rpcclient" + "github.com/noot/atomic-swap/common/rpctypes" "github.com/noot/atomic-swap/common/types" "github.com/noot/atomic-swap/rpc" ) @@ -14,7 +14,7 @@ func (c *Client) GetOffers() ([]*types.Offer, error) { method = "swap_getOffers" ) - resp, err := rpcclient.PostRPC(c.endpoint, method, "{}") + resp, err := rpctypes.PostRPC(c.endpoint, method, "{}") if err != nil { return nil, err } diff --git a/cmd/client/client/make_offer.go b/rpcclient/make_offer.go similarity index 85% rename from cmd/client/client/make_offer.go rename to rpcclient/make_offer.go index 2074f200..8eb4b7e5 100644 --- a/cmd/client/client/make_offer.go +++ b/rpcclient/make_offer.go @@ -1,10 +1,9 @@ -package client +package rpcclient import ( "encoding/json" "fmt" - "github.com/noot/atomic-swap/common/rpcclient" "github.com/noot/atomic-swap/common/rpctypes" "github.com/noot/atomic-swap/common/types" ) @@ -26,7 +25,7 @@ func (c *Client) MakeOffer(min, max, exchangeRate float64) (string, error) { return "", err } - resp, err := rpcclient.PostRPC(c.endpoint, method, string(params)) + resp, err := rpctypes.PostRPC(c.endpoint, method, string(params)) if err != nil { return "", err } diff --git a/cmd/client/client/personal.go b/rpcclient/personal.go similarity index 77% rename from cmd/client/client/personal.go rename to rpcclient/personal.go index 4e750c93..db414855 100644 --- a/cmd/client/client/personal.go +++ b/rpcclient/personal.go @@ -1,9 +1,9 @@ -package client +package rpcclient import ( "encoding/json" - "github.com/noot/atomic-swap/common/rpcclient" + "github.com/noot/atomic-swap/common/rpctypes" "github.com/noot/atomic-swap/rpc" ) @@ -22,7 +22,7 @@ func (c *Client) SetSwapTimeout(duration uint64) error { return err } - resp, err := rpcclient.PostRPC(c.endpoint, method, string(params)) + resp, err := rpctypes.PostRPC(c.endpoint, method, string(params)) if err != nil { return err } diff --git a/cmd/client/client/query.go b/rpcclient/query.go similarity index 81% rename from cmd/client/client/query.go rename to rpcclient/query.go index 9e909129..07094fed 100644 --- a/cmd/client/client/query.go +++ b/rpcclient/query.go @@ -1,9 +1,8 @@ -package client +package rpcclient import ( "encoding/json" - "github.com/noot/atomic-swap/common/rpcclient" "github.com/noot/atomic-swap/common/rpctypes" ) @@ -22,7 +21,7 @@ func (c *Client) Query(maddr string) (*rpctypes.QueryPeerResponse, error) { return nil, err } - resp, err := rpcclient.PostRPC(c.endpoint, method, string(params)) + resp, err := rpctypes.PostRPC(c.endpoint, method, string(params)) if err != nil { return nil, err } diff --git a/cmd/client/client/swap.go b/rpcclient/swap.go similarity index 85% rename from cmd/client/client/swap.go rename to rpcclient/swap.go index 3c7e819d..82868a0b 100644 --- a/cmd/client/client/swap.go +++ b/rpcclient/swap.go @@ -1,10 +1,10 @@ -package client +package rpcclient import ( "encoding/json" "fmt" - "github.com/noot/atomic-swap/common/rpcclient" + "github.com/noot/atomic-swap/common/rpctypes" "github.com/noot/atomic-swap/rpc" ) @@ -14,7 +14,7 @@ func (c *Client) GetPastSwapIDs() ([]uint64, error) { method = "swap_getPastIDs" ) - resp, err := rpcclient.PostRPC(c.endpoint, method, "{}") + resp, err := rpctypes.PostRPC(c.endpoint, method, "{}") if err != nil { return nil, err } @@ -37,7 +37,7 @@ func (c *Client) GetOngoingSwap() (*rpc.GetOngoingResponse, error) { method = "swap_getOngoing" ) - resp, err := rpcclient.PostRPC(c.endpoint, method, "{}") + resp, err := rpctypes.PostRPC(c.endpoint, method, "{}") if err != nil { return nil, err } @@ -69,7 +69,7 @@ func (c *Client) GetPastSwap(id uint64) (*rpc.GetPastResponse, error) { return nil, err } - resp, err := rpcclient.PostRPC(c.endpoint, method, string(params)) + resp, err := rpctypes.PostRPC(c.endpoint, method, string(params)) if err != nil { return nil, err } @@ -92,7 +92,7 @@ func (c *Client) Refund() (*rpc.RefundResponse, error) { method = "swap_refund" ) - resp, err := rpcclient.PostRPC(c.endpoint, method, "{}") + resp, err := rpctypes.PostRPC(c.endpoint, method, "{}") if err != nil { return nil, err } @@ -115,7 +115,7 @@ func (c *Client) GetStage() (*rpc.GetStageResponse, error) { method = "swap_getStage" ) - resp, err := rpcclient.PostRPC(c.endpoint, method, "{}") + resp, err := rpctypes.PostRPC(c.endpoint, method, "{}") if err != nil { return nil, err } diff --git a/cmd/client/client/take_offer.go b/rpcclient/take_offer.go similarity index 84% rename from cmd/client/client/take_offer.go rename to rpcclient/take_offer.go index 316eff16..8c74db8a 100644 --- a/cmd/client/client/take_offer.go +++ b/rpcclient/take_offer.go @@ -1,10 +1,9 @@ -package client +package rpcclient import ( "encoding/json" "fmt" - "github.com/noot/atomic-swap/common/rpcclient" "github.com/noot/atomic-swap/common/rpctypes" ) @@ -25,7 +24,7 @@ func (c *Client) TakeOffer(maddr string, offerID string, providesAmount float64) return 0, err } - resp, err := rpcclient.PostRPC(c.endpoint, method, string(params)) + resp, err := rpctypes.PostRPC(c.endpoint, method, string(params)) if err != nil { return 0, err } diff --git a/common/rpcclient/wsclient.go b/rpcclient/wsclient/wsclient.go similarity index 99% rename from common/rpcclient/wsclient.go rename to rpcclient/wsclient/wsclient.go index 806f00f2..6fe90892 100644 --- a/common/rpcclient/wsclient.go +++ b/rpcclient/wsclient/wsclient.go @@ -1,4 +1,4 @@ -package rpcclient +package wsclient import ( "context" diff --git a/tests/integration_test.go b/tests/integration_test.go index 4b689fd7..7bf39fa9 100644 --- a/tests/integration_test.go +++ b/tests/integration_test.go @@ -10,11 +10,11 @@ import ( "testing" "time" - "github.com/noot/atomic-swap/cmd/client/client" "github.com/noot/atomic-swap/common" - "github.com/noot/atomic-swap/common/rpcclient" "github.com/noot/atomic-swap/common/types" "github.com/noot/atomic-swap/monero" + "github.com/noot/atomic-swap/rpcclient" + "github.com/noot/atomic-swap/rpcclient/wsclient" "github.com/stretchr/testify/require" ) @@ -94,11 +94,11 @@ func generateBlocksAsync() { } func TestAlice_Discover(t *testing.T) { - bc := client.NewClient(defaultBobDaemonEndpoint) + bc := rpcclient.NewClient(defaultBobDaemonEndpoint) _, err := bc.MakeOffer(bobProvideAmount, bobProvideAmount, exchangeRate) require.NoError(t, err) - c := client.NewClient(defaultAliceDaemonEndpoint) + c := rpcclient.NewClient(defaultAliceDaemonEndpoint) providers, err := c.Discover(types.ProvidesXMR, defaultDiscoverTimeout) require.NoError(t, err) require.Equal(t, 1, len(providers)) @@ -106,18 +106,18 @@ func TestAlice_Discover(t *testing.T) { } func TestBob_Discover(t *testing.T) { - c := client.NewClient(defaultBobDaemonEndpoint) + c := rpcclient.NewClient(defaultBobDaemonEndpoint) providers, err := c.Discover(types.ProvidesETH, defaultDiscoverTimeout) require.NoError(t, err) require.Equal(t, 0, len(providers)) } func TestAlice_Query(t *testing.T) { - bc := client.NewClient(defaultBobDaemonEndpoint) + bc := rpcclient.NewClient(defaultBobDaemonEndpoint) _, err := bc.MakeOffer(bobProvideAmount, bobProvideAmount, exchangeRate) require.NoError(t, err) - c := client.NewClient(defaultAliceDaemonEndpoint) + c := rpcclient.NewClient(defaultAliceDaemonEndpoint) providers, err := c.Discover(types.ProvidesXMR, defaultDiscoverTimeout) require.NoError(t, err) @@ -138,14 +138,14 @@ func TestSuccess(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - bwsc, err := rpcclient.NewWsClient(ctx, defaultBobDaemonWSEndpoint) + bwsc, err := wsclient.NewWsClient(ctx, defaultBobDaemonWSEndpoint) require.NoError(t, err) offerID, takenCh, statusCh, err := bwsc.MakeOfferAndSubscribe(0.1, bobProvideAmount, types.ExchangeRate(exchangeRate)) require.NoError(t, err) - bc := client.NewClient(defaultBobDaemonEndpoint) + bc := rpcclient.NewClient(defaultBobDaemonEndpoint) offersBefore, err := bc.GetOffers() require.NoError(t, err) @@ -181,8 +181,8 @@ func TestSuccess(t *testing.T) { } }() - c := client.NewClient(defaultAliceDaemonEndpoint) - wsc, err := rpcclient.NewWsClient(ctx, defaultAliceDaemonWSEndpoint) + c := rpcclient.NewClient(defaultAliceDaemonEndpoint) + wsc, err := wsclient.NewWsClient(ctx, defaultAliceDaemonWSEndpoint) require.NoError(t, err) // TODO: implement discovery over websockets @@ -239,14 +239,14 @@ func TestRefund_AliceCancels(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - bwsc, err := rpcclient.NewWsClient(ctx, defaultBobDaemonWSEndpoint) + bwsc, err := wsclient.NewWsClient(ctx, defaultBobDaemonWSEndpoint) require.NoError(t, err) offerID, takenCh, statusCh, err := bwsc.MakeOfferAndSubscribe(0.1, bobProvideAmount, types.ExchangeRate(exchangeRate)) require.NoError(t, err) - bc := client.NewClient(defaultBobDaemonEndpoint) + bc := rpcclient.NewClient(defaultBobDaemonEndpoint) offersBefore, err := bc.GetOffers() require.NoError(t, err) @@ -282,8 +282,8 @@ func TestRefund_AliceCancels(t *testing.T) { } }() - c := client.NewClient(defaultAliceDaemonEndpoint) - wsc, err := rpcclient.NewWsClient(ctx, defaultAliceDaemonWSEndpoint) + c := rpcclient.NewClient(defaultAliceDaemonEndpoint) + wsc, err := wsclient.NewWsClient(ctx, defaultAliceDaemonWSEndpoint) require.NoError(t, err) err = c.SetSwapTimeout(swapTimeout) @@ -362,8 +362,8 @@ func testRefundBobCancels(t *testing.T, swapTimeout uint64, expectedExitStatus t ctx, cancel := context.WithCancel(context.Background()) defer cancel() - bcli := client.NewClient(defaultBobDaemonEndpoint) - bwsc, err := rpcclient.NewWsClient(ctx, defaultBobDaemonWSEndpoint) + bcli := rpcclient.NewClient(defaultBobDaemonEndpoint) + bwsc, err := wsclient.NewWsClient(ctx, defaultBobDaemonWSEndpoint) require.NoError(t, err) offerID, takenCh, statusCh, err := bwsc.MakeOfferAndSubscribe(0.1, bobProvideAmount, @@ -414,8 +414,8 @@ func testRefundBobCancels(t *testing.T, swapTimeout uint64, expectedExitStatus t } }() - c := client.NewClient(defaultAliceDaemonEndpoint) - wsc, err := rpcclient.NewWsClient(ctx, defaultAliceDaemonWSEndpoint) + c := rpcclient.NewClient(defaultAliceDaemonEndpoint) + wsc, err := wsclient.NewWsClient(ctx, defaultAliceDaemonWSEndpoint) require.NoError(t, err) err = c.SetSwapTimeout(swapTimeout) @@ -480,14 +480,14 @@ func TestAbort_AliceCancels(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - bwsc, err := rpcclient.NewWsClient(ctx, defaultBobDaemonWSEndpoint) + bwsc, err := wsclient.NewWsClient(ctx, defaultBobDaemonWSEndpoint) require.NoError(t, err) offerID, takenCh, statusCh, err := bwsc.MakeOfferAndSubscribe(0.1, bobProvideAmount, types.ExchangeRate(exchangeRate)) require.NoError(t, err) - bc := client.NewClient(defaultBobDaemonEndpoint) + bc := rpcclient.NewClient(defaultBobDaemonEndpoint) offersBefore, err := bc.GetOffers() require.NoError(t, err) @@ -523,8 +523,8 @@ func TestAbort_AliceCancels(t *testing.T) { } }() - c := client.NewClient(defaultAliceDaemonEndpoint) - wsc, err := rpcclient.NewWsClient(ctx, defaultAliceDaemonWSEndpoint) + c := rpcclient.NewClient(defaultAliceDaemonEndpoint) + wsc, err := wsclient.NewWsClient(ctx, defaultAliceDaemonWSEndpoint) require.NoError(t, err) providers, err := c.Discover(types.ProvidesXMR, defaultDiscoverTimeout) @@ -587,15 +587,15 @@ func TestAbort_BobCancels(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - bcli := client.NewClient(defaultBobDaemonEndpoint) - bwsc, err := rpcclient.NewWsClient(ctx, defaultBobDaemonWSEndpoint) + bcli := rpcclient.NewClient(defaultBobDaemonEndpoint) + bwsc, err := wsclient.NewWsClient(ctx, defaultBobDaemonWSEndpoint) require.NoError(t, err) offerID, takenCh, statusCh, err := bwsc.MakeOfferAndSubscribe(0.1, bobProvideAmount, types.ExchangeRate(exchangeRate)) require.NoError(t, err) - bc := client.NewClient(defaultBobDaemonEndpoint) + bc := rpcclient.NewClient(defaultBobDaemonEndpoint) offersBefore, err := bc.GetOffers() require.NoError(t, err) @@ -640,8 +640,8 @@ func TestAbort_BobCancels(t *testing.T) { } }() - c := client.NewClient(defaultAliceDaemonEndpoint) - wsc, err := rpcclient.NewWsClient(ctx, defaultAliceDaemonWSEndpoint) + c := rpcclient.NewClient(defaultAliceDaemonEndpoint) + wsc, err := wsclient.NewWsClient(ctx, defaultAliceDaemonWSEndpoint) require.NoError(t, err) providers, err := c.Discover(types.ProvidesXMR, defaultDiscoverTimeout) @@ -695,11 +695,11 @@ func TestError_ShouldOnlyTakeOfferOnce(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - bc := client.NewClient(defaultBobDaemonEndpoint) + bc := rpcclient.NewClient(defaultBobDaemonEndpoint) offerID, err := bc.MakeOffer(bobProvideAmount, bobProvideAmount, exchangeRate) require.NoError(t, err) - ac := client.NewClient(defaultAliceDaemonEndpoint) + ac := rpcclient.NewClient(defaultAliceDaemonEndpoint) providers, err := ac.Discover(types.ProvidesXMR, defaultDiscoverTimeout) require.NoError(t, err) @@ -709,7 +709,7 @@ func TestError_ShouldOnlyTakeOfferOnce(t *testing.T) { errCh := make(chan error) go func() { - wsc, err := rpcclient.NewWsClient(ctx, defaultAliceDaemonWSEndpoint) + wsc, err := wsclient.NewWsClient(ctx, defaultAliceDaemonWSEndpoint) require.NoError(t, err) _, takerStatusCh, err := wsc.TakeOfferAndSubscribe(providers[0][0], offerID, 0.05) @@ -735,7 +735,7 @@ func TestError_ShouldOnlyTakeOfferOnce(t *testing.T) { }() go func() { - wsc, err := rpcclient.NewWsClient(ctx, defaultCharlieDaemonWSEndpoint) + wsc, err := wsclient.NewWsClient(ctx, defaultCharlieDaemonWSEndpoint) require.NoError(t, err) _, takerStatusCh, err := wsc.TakeOfferAndSubscribe(providers[0][0], offerID, 0.05)