Skip to content

Commit

Permalink
multi: surface server swap initiation grpc error codes
Browse files Browse the repository at this point in the history
Formatting our error was stifling any grpc error returned by the
server. Instead, we bubble up our grpc error, setting an unknown
code if the server did not specifically return an error code.
  • Loading branch information
carlaKC committed Jul 19, 2021
1 parent e7ee29b commit d1c26a2
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 8 deletions.
15 changes: 15 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/lightninglabs/loop/loopdb"
"github.com/lightninglabs/loop/swap"
"github.com/lightninglabs/loop/sweep"
"google.golang.org/grpc/status"
)

var (
Expand Down Expand Up @@ -610,3 +611,17 @@ func (s *Client) LoopInTerms(ctx context.Context) (

return s.Server.GetLoopInTerms(ctx)
}

// wrapGrpcError wraps the non-nil error provided with a message providing
// additional context, preserving the grpc code returned with the original
// error. If the original error has no grpc code, then codes.Unknown is used.
func wrapGrpcError(message string, err error) error {
// Since our error is non-nil, we don't need to worry about a nil
// grpcStatus, we'll just get an unknown one if no code was passed back.
grpcStatus, _ := status.FromError(err)

return status.Error(
grpcStatus.Code(), fmt.Sprintf("%v: %v", message,
grpcStatus.Message()),
)
}
38 changes: 38 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import (
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/stretchr/testify/require"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

var (
Expand Down Expand Up @@ -372,3 +374,39 @@ func testSuccess(ctx *testContext, amt btcutil.Amount, hash lntypes.Hash,

ctx.finish()
}

// TestWrapGrpcError tests grpc error wrapping in the case where a grpc error
// code is present, and when it is absent.
func TestWrapGrpcError(t *testing.T) {
tests := []struct {
name string
original error
expectedCode codes.Code
}{
{
name: "out of range error",
original: status.Error(
codes.OutOfRange, "err string",
),
expectedCode: codes.OutOfRange,
},
{
name: "no grpc code",
original: errors.New("no error code"),
expectedCode: codes.Unknown,
},
}

for _, testCase := range tests {
testCase := testCase

t.Run(testCase.name, func(t *testing.T) {
err := wrapGrpcError("", testCase.original)
require.Error(t, err, "test only expects errors")

status, ok := status.FromError(err)
require.True(t, ok, "test expects grpc code")
require.Equal(t, testCase.expectedCode, status.Code())
})
}
}
7 changes: 3 additions & 4 deletions loopin.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ import (
"sync"
"time"

"github.com/btcsuite/btcutil"

"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/mempool"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/lightninglabs/lndclient"
"github.com/lightninglabs/loop/labels"
"github.com/lightninglabs/loop/loopdb"
Expand Down Expand Up @@ -86,7 +85,7 @@ func newLoopInSwap(globalCtx context.Context, cfg *swapConfig,
// request that we send to the server.
quote, err := cfg.server.GetLoopInQuote(globalCtx, request.Amount)
if err != nil {
return nil, fmt.Errorf("loop in terms: %v", err)
return nil, wrapGrpcError("loop in terms", err)
}

swapFee := quote.SwapFee
Expand Down Expand Up @@ -172,7 +171,7 @@ func newLoopInSwap(globalCtx context.Context, cfg *swapConfig,
)
probeWaitCancel()
if err != nil {
return nil, fmt.Errorf("cannot initiate swap: %v", err)
return nil, wrapGrpcError("cannot initiate swap", err)
}

// Because the context is cancelled, it is guaranteed that we will be
Expand Down
5 changes: 2 additions & 3 deletions loopin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import (
"context"
"testing"

"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/lightninglabs/loop/loopdb"
"github.com/lightninglabs/loop/swap"
"github.com/lightninglabs/loop/test"
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/stretchr/testify/require"

"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
)

var (
Expand Down
2 changes: 1 addition & 1 deletion loopout.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func newLoopOutSwap(globalCtx context.Context, cfg *swapConfig,
receiverKey, request.SwapPublicationDeadline, request.Initiator,
)
if err != nil {
return nil, fmt.Errorf("cannot initiate swap: %v", err)
return nil, wrapGrpcError("cannot initiate swap", err)
}

err = validateLoopOutContract(
Expand Down

0 comments on commit d1c26a2

Please sign in to comment.