Skip to content

Commit

Permalink
feat: Add logging and tracing middleware and slight reorg (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
vitsalis authored May 6, 2024
1 parent 8ea05ee commit 8685063
Show file tree
Hide file tree
Showing 15 changed files with 212 additions and 135 deletions.
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,4 @@ workflows:
only:
- main
- dev
- logging-middleware
5 changes: 0 additions & 5 deletions cmd/signerCmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package cmd
import (
"github.com/babylonchain/covenant-signer/btcclient"
"github.com/babylonchain/covenant-signer/config"
"github.com/babylonchain/covenant-signer/logger"
"github.com/babylonchain/covenant-signer/signerapp"
"github.com/babylonchain/covenant-signer/signerservice"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -31,7 +30,6 @@ var runSignerCmd = &cobra.Command{
if err != nil {
return err
}
log := logger.DefaultLogger()

fullNodeClient, err := btcclient.NewBtcClient(parsedConfig.BtcNodeConfig)

Expand All @@ -53,7 +51,6 @@ var runSignerCmd = &cobra.Command{
paramsGetter := signerapp.NewConfigParamsRetriever(parsedConfig.ParamsConfig)

app := signerapp.NewSignerApp(
log,
signer,
chainInfo,
paramsGetter,
Expand All @@ -62,7 +59,6 @@ var runSignerCmd = &cobra.Command{

srv, err := signerservice.New(
cmd.Context(),
log,
parsedConfig,
app,
)
Expand All @@ -71,7 +67,6 @@ var runSignerCmd = &cobra.Command{
return err
}

log.Info("Starting signer service")
// TODO: Add signal handling and gracefull shutdown
return srv.Start()
},
Expand Down
4 changes: 0 additions & 4 deletions itest/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/babylonchain/covenant-signer/btcclient"
"github.com/babylonchain/covenant-signer/config"
"github.com/babylonchain/covenant-signer/itest/containers"
"github.com/babylonchain/covenant-signer/logger"
"github.com/babylonchain/covenant-signer/signerapp"
"github.com/babylonchain/covenant-signer/signerservice"
"github.com/btcsuite/btcd/btcec/v2"
Expand Down Expand Up @@ -69,7 +68,6 @@ func defaultStakingData() *stakingData {
func StartManager(
t *testing.T,
numMatureOutputsInWallet uint32) *TestManager {
logger := logger.DefaultLogger()
m, err := containers.NewManager()
require.NoError(t, err)
t.Cleanup(func() {
Expand Down Expand Up @@ -159,7 +157,6 @@ func StartManager(
paramsGetter := signerapp.NewConfigParamsRetriever(parsedconfig.ParamsConfig)

app := signerapp.NewSignerApp(
logger,
signer,
chainInfo,
paramsGetter,
Expand All @@ -168,7 +165,6 @@ func StartManager(

server, err := signerservice.New(
context.Background(),
logger,
parsedconfig,
app,
)
Expand Down
10 changes: 0 additions & 10 deletions logger/logger.go

This file was deleted.

29 changes: 29 additions & 0 deletions observability/tracing/tracing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package tracing

import (
"context"
"github.com/google/uuid"
)

type TraceContextKey string

const TraceInfoKey = TraceContextKey("requestTracingInfo")
const TraceIdKey = TraceContextKey("requestTraceId")

type SpanDetail struct {
Name string
Duration int64
}

type TracingInfo struct {
SpanDetails []SpanDetail
}

func AttachTracingIntoContext(ctx context.Context) context.Context {
// Attach traceId into context
traceID := uuid.New().String()
ctx = context.WithValue(ctx, TraceIdKey, traceID)

// Start tracingInfo
return context.WithValue(ctx, TraceInfoKey, &TracingInfo{})
}
21 changes: 8 additions & 13 deletions signerapp/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"bytes"
"context"
"fmt"
"log/slog"

"github.com/babylonchain/babylon/btcstaking"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
Expand Down Expand Up @@ -64,26 +62,23 @@ type BabylonParamsRetriever interface {
}

type SignerApp struct {
logger *slog.Logger
s ExternalBtcSigner
r BtcChainInfo
p BabylonParamsRetriever
net *chaincfg.Params
s ExternalBtcSigner
r BtcChainInfo
p BabylonParamsRetriever
net *chaincfg.Params
}

func NewSignerApp(
log *slog.Logger,
s ExternalBtcSigner,
r BtcChainInfo,
p BabylonParamsRetriever,
net *chaincfg.Params,
) *SignerApp {
return &SignerApp{
logger: log,
s: s,
r: r,
p: p,
net: net,
s: s,
r: r,
p: p,
net: net,
}
}

Expand Down
6 changes: 4 additions & 2 deletions signerservice/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"github.com/babylonchain/covenant-signer/signerservice/handlers"
"github.com/babylonchain/covenant-signer/signerservice/types"
"io"
"net/http"
"time"
Expand Down Expand Up @@ -34,7 +36,7 @@ func RequestCovenantSignaure(

pkScriptHex := hex.EncodeToString(stakingTransactionPkScript)

req := SignUnbondingTxRequest{
req := types.SignUnbondingTxRequest{
StakingOutputPkScriptHex: pkScriptHex,
UnbondingTxHex: unbondingTxHex,
CovenantPublicKey: keyHex,
Expand Down Expand Up @@ -77,7 +79,7 @@ func RequestCovenantSignaure(
return nil, err
}

var response PublicResponse[SignUnbondingTxResponse]
var response handlers.PublicResponse[types.SignUnbondingTxResponse]
if err := json.Unmarshal(resBody, &response); err != nil {
return nil, err
}
Expand Down
33 changes: 33 additions & 0 deletions signerservice/handlers/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package handlers

import (
"context"
s "github.com/babylonchain/covenant-signer/signerapp"
"net/http"
)

type Handler struct {
s *s.SignerApp
}

type Result struct {
Data interface{}
Status int
}

type PublicResponse[T any] struct {
Data T `json:"data"`
}

func NewResult[T any](data T) *Result {
res := &PublicResponse[T]{Data: data}
return &Result{Data: res, Status: http.StatusOK}
}

func NewHandler(
_ context.Context, s *s.SignerApp,
) (*Handler, error) {
return &Handler{
s: s,
}, nil
}
60 changes: 60 additions & 0 deletions signerservice/handlers/sign_unbonding.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package handlers

import (
"encoding/hex"
"encoding/json"
"github.com/babylonchain/covenant-signer/signerservice/types"
"github.com/babylonchain/covenant-signer/utils"
"github.com/btcsuite/btcd/btcec/v2"
"net/http"
)

func (h *Handler) SignUnbonding(request *http.Request) (*Result, *types.Error) {
payload := &types.SignUnbondingTxRequest{}
err := json.NewDecoder(request.Body).Decode(payload)
if err != nil {
return nil, types.NewErrorWithMsg(http.StatusBadRequest, types.BadRequest, "invalid request payload")
}

pkScript, err := hex.DecodeString(payload.StakingOutputPkScriptHex)

if err != nil {
return nil, types.NewErrorWithMsg(http.StatusBadRequest, types.BadRequest, "invalid staking output pk script")
}

covenantPublicKeyBytes, err := hex.DecodeString(payload.CovenantPublicKey)

if err != nil {
return nil, types.NewErrorWithMsg(http.StatusBadRequest, types.BadRequest, "invalid covenant public key")
}

covenantPublicKey, err := btcec.ParsePubKey(covenantPublicKeyBytes)

if err != nil {
return nil, types.NewErrorWithMsg(http.StatusBadRequest, types.BadRequest, "invalid covenant public key")
}

unbondingTx, _, err := utils.NewBTCTxFromHex(payload.UnbondingTxHex)

if err != nil {
return nil, types.NewErrorWithMsg(http.StatusBadRequest, types.BadRequest, "invalid unbonding transaction")
}

sig, err := h.s.SignUnbondingTransaction(
request.Context(),
pkScript,
unbondingTx,
covenantPublicKey,
)

if err != nil {
// TODO Properly translate errors between layers
return nil, types.NewErrorWithMsg(http.StatusInternalServerError, types.InternalServiceError, err.Error())
}

resp := types.SignUnbondingTxResponse{
SignatureHex: hex.EncodeToString(sig.Serialize()),
}

return NewResult(resp), nil
}
33 changes: 12 additions & 21 deletions signerservice/http_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package signerservice

import (
"encoding/json"
"log/slog"
"github.com/babylonchain/covenant-signer/signerservice/handlers"
"github.com/babylonchain/covenant-signer/signerservice/types"
logger "github.com/rs/zerolog"
"net/http"
)

Expand All @@ -13,7 +15,7 @@ type ErrorResponse struct {

func newInternalServiceError() *ErrorResponse {
return &ErrorResponse{
ErrorCode: InternalServiceError.String(),
ErrorCode: types.InternalServiceError.String(),
Message: "Internal service error",
}
}
Expand All @@ -22,21 +24,7 @@ func (e *ErrorResponse) Error() string {
return e.Message
}

type Result struct {
Data interface{}
Status int
}

type PublicResponse[T any] struct {
Data T `json:"data"`
}

func NewResult[T any](data T) *Result {
res := &PublicResponse[T]{Data: data}
return &Result{Data: res, Status: http.StatusOK}
}

func registerHandler(logger *slog.Logger, handlerFunc func(*http.Request) (*Result, *Error)) func(http.ResponseWriter, *http.Request) {
func registerHandler(handlerFunc func(*http.Request) (*handlers.Result, *types.Error)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
// Set up metrics recording for the endpoint

Expand All @@ -45,6 +33,7 @@ func registerHandler(logger *slog.Logger, handlerFunc func(*http.Request) (*Resu

if err != nil {
if http.StatusText(err.StatusCode) == "" {
logger.Ctx(r.Context()).Error().Err(err).Int("status_code", err.StatusCode).Msg("invalid status code")
err.StatusCode = http.StatusInternalServerError
}

Expand All @@ -54,26 +43,27 @@ func registerHandler(logger *slog.Logger, handlerFunc func(*http.Request) (*Resu
}
// Log the error
if err.StatusCode >= http.StatusInternalServerError {
logger.Ctx(r.Context()).Error().Err(errorResponse).Msg("request failed with 5xx error")
errorResponse.Message = "Internal service error" // Hide the internal message error from client
}
// terminate the request here
writeResponse(logger, w, r, err.StatusCode, errorResponse)
writeResponse(w, r, err.StatusCode, errorResponse)
return
}

if result == nil || http.StatusText(result.Status) == "" {
logger.Ctx(r.Context()).Error().Msg("invalid success response, error returned")
// terminate the request here
writeResponse(logger, w, r, http.StatusInternalServerError, newInternalServiceError())
writeResponse(w, r, http.StatusInternalServerError, newInternalServiceError())
return
}

writeResponse(logger, w, r, result.Status, result.Data)
writeResponse(w, r, result.Status, result.Data)
}
}

// Write and return response
func writeResponse(
logger *slog.Logger,
w http.ResponseWriter,
r *http.Request,
statusCode int,
Expand All @@ -82,6 +72,7 @@ func writeResponse(
respBytes, err := json.Marshal(res)

if err != nil {
logger.Ctx(r.Context()).Err(err).Msg("failed to marshal error response")
http.Error(w, "Failed to process the request. Please try again later.", http.StatusInternalServerError)
return
}
Expand Down
Loading

0 comments on commit 8685063

Please sign in to comment.