Skip to content

Commit

Permalink
Merge branch 'flyover-2.1.1' into refund-scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
Luisfc68 committed Nov 28, 2024
2 parents 95e17bd + d5ede3d commit caebe94
Show file tree
Hide file tree
Showing 22 changed files with 250 additions and 25 deletions.
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,17 @@ validation: lint
go mod verify
govulncheck ./... # should fail on non informational vulnerabilities

COMMIT_TAG ?= $(shell git describe --exact-match --tags)
COMMIT_HASH ?= $(shell git rev-parse HEAD)
SOURCE_VERSION := $(COMMIT_HASH)
SOURCE_TAG := $(COMMIT_TAG)

build: download
mkdir -p build && cd build
@echo "Building liquidity-provider-server $(SOURCE_VERSION)"
CGO_ENABLED=0 go build -v -installsuffix 'static' -ldflags="-s -X 'main.BuildVersion=$(SOURCE_VERSION)' -X 'main.BuildTime=$(shell date)'" -o ./build/liquidity-provider-server ./cmd/application/main.go
@echo "Building liquidity-provider-server $(SOURCE_TAG) ($(SOURCE_VERSION))"
CGO_ENABLED=0 go build -v -installsuffix 'static' \
-ldflags="-s -X 'main.BuildVersion=$(SOURCE_VERSION)' -X 'main.BuildTime=$(shell date)' -X 'github.com/rsksmart/liquidity-provider-server/internal/usecases/liquidity_provider.BuildVersion=$(SOURCE_TAG)' -X 'github.com/rsksmart/liquidity-provider-server/internal/usecases/liquidity_provider.BuildRevision=$(SOURCE_VERSION)'" \
-o ./build/liquidity-provider-server ./cmd/application/main.go

api:
go-swagger3 --module-path . \
Expand Down
25 changes: 25 additions & 0 deletions OpenApi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,20 @@ components:
- refundPegoutTxHash
- bridgeRefundTxHash
type: object
ServerInfoDTO:
properties:
revision:
description: Version commit hash
example: b7bf393a2b1cedde8ee15b00780f44e6e5d2ba9d
type: string
version:
description: Server version tag
example: v1.0.0
type: string
required:
- version
- revision
type: object
Services:
properties:
btc:
Expand Down Expand Up @@ -983,6 +997,17 @@ paths:
$ref: '#/components/schemas/DepositEventDTO'
description: Successfully retrieved the user quotes
summary: GetUserQuotes
/version:
get:
description: ' Returns the server version and revision'
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/ServerInfoDTO'
description: ""
summary: Get server version
servers:
- description: ' Testnet'
url: https://lps.testnet.flyover.rif.technology
Expand Down
2 changes: 2 additions & 0 deletions docker-compose/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ services:
dockerfile: docker-compose/lps/Dockerfile
args:
UID: "${LPS_UID}"
COMMIT_HASH: "${COMMIT_HASH}"
COMMIT_TAG: "${COMMIT_TAG}"
image: lps:latest
container_name: lps01
environment:
Expand Down
2 changes: 2 additions & 0 deletions docker-compose/local/docker-compose.lps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ services:
dockerfile: docker-compose/lps/Dockerfile
args:
UID: "${LPS_UID}"
COMMIT_HASH: "${COMMIT_HASH}"
COMMIT_TAG: "${COMMIT_TAG}"
image: lps:latest
container_name: lps01
environment:
Expand Down
22 changes: 13 additions & 9 deletions docker-compose/local/lps-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

set -e

COMMIT_HASH=$(git rev-parse HEAD)
COMMIT_TAG=$(git describe --exact-match --tags)
export COMMIT_HASH
export COMMIT_TAG

if [ -z "${LPS_STAGE}" ]; then
echo "LPS_STAGE is not set. Exit 1"
exit 1
Expand All @@ -16,7 +21,8 @@ else
fi

if [ -z "${LPS_UID}" ]; then
export LPS_UID=$(id -u)
LPS_UID=$(id -u)
export LPS_UID
if [ "$LPS_UID" = "0" ]; then
echo "Please set LPS_UID env var or run as a non-root user"
exit 1
Expand Down Expand Up @@ -58,7 +64,7 @@ elif [ "$SCRIPT_CMD" = "deploy" ]; then
exit 0
elif [ "$SCRIPT_CMD" = "import-rsk-db" ]; then
echo "Importing rsk db..."
docker compose --env-file "$ENV_FILE" run -d rskj java -Xmx6g -Drpc.providers.web.http.bind_address=0.0.0.0 -Drpc.providers.web.http.hosts.0=localhost -Drpc.providers.web.http.hosts.1=rskj -cp rskj-core.jar co.rsk.Start --${LPS_STAGE} --import
docker compose --env-file "$ENV_FILE" run -d rskj java -Xmx6g -Drpc.providers.web.http.bind_address=0.0.0.0 -Drpc.providers.web.http.hosts.0=localhost -Drpc.providers.web.http.hosts.1=rskj -cp rskj-core.jar co.rsk.Start --"${LPS_STAGE}" --import
exit 0
elif [ "$SCRIPT_CMD" = "start-bitcoind" ]; then
echo "Starting bitcoind..."
Expand Down Expand Up @@ -90,7 +96,7 @@ echo "LPS_UID: $LPS_UID; BTCD_HOME: '$BTCD_HOME'; RSKJ_HOME: '$RSKJ_HOME'; LPS_H
# start bitcoind and RSKJ dependant services
docker compose --env-file "$ENV_FILE" up -d bitcoind rskj mongodb localstack

# read env vars
# shellcheck disable=SC1090
. ./"$ENV_FILE"

echo "Waiting for RskJ to be up and running..."
Expand Down Expand Up @@ -127,8 +133,6 @@ curl -s "http://127.0.0.1:5555" --user "$BTC_USERNAME:$BTC_PASSWORD" -H "Content
| jq .result | xargs -I ADDRESS curl -s "http://127.0.0.1:5555" --user "$BTC_USERNAME:$BTC_PASSWORD" -H "Content-Type: application/json" -d '{"jsonrpc": "1.0", "method": "generatetoaddress", "params": [1, "ADDRESS"], "id":"generatetoaddress"}'

if [ "$LPS_STAGE" = "regtest" ]; then
PROVIDER_RSK_ADDR_LINE=$(cat "$ENV_FILE" | grep "$LIQUIDITY_PROVIDER_RSK_ADDR" | head -n 1 | tr -d '\r')
PROVIDER_RSK_ADDR="${PROVIDER_RSK_ADDR_LINE#"$LIQUIDITY_PROVIDER_RSK_ADDR="}"
PROVIDER_TX_COUNT=$(curl -s -X POST "http://127.0.0.1:4444" -H "Content-Type: application/json" -d "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionCount\",\"params\": [\"$LIQUIDITY_PROVIDER_RSK_ADDR\",\"latest\"],\"id\":1}" | jq -r ".result")
if [ "$PROVIDER_TX_COUNT" = "0x0" ]; then
echo "Transferring funds to $LIQUIDITY_PROVIDER_RSK_ADDR..."
Expand Down Expand Up @@ -160,11 +164,11 @@ echo "LBC deployed at $LBC_ADDR"
docker compose --env-file "$ENV_FILE" up -d powpeg-pegin powpeg-pegout
# start LPS

docker compose --env-file "$ENV_FILE" -f docker-compose.yml -f docker-compose.lps.yml build --build-arg COMMIT_HASH="$(git rev-parse HEAD)" lps
docker compose --env-file "$ENV_FILE" -f docker-compose.yml -f docker-compose.lps.yml build lps
docker compose --env-file "$ENV_FILE" -f docker-compose.yml -f docker-compose.lps.yml up -d lps

FAIL=true
for i in {1..10}
for ((i=1;i<=10;i++));
do
sleep 5
curl -s "http://localhost:8080/health" \
Expand Down Expand Up @@ -192,7 +196,7 @@ CSRF_TOKEN=$(curl -s -c cookie_jar.txt -H 'Content-Type: application/json' \
-H 'Sec-Fetch-Site: same-origin' \
"http://localhost:8080/management" | sed -n 's/.*name="csrf"[^>]*value="\([^"]*\)".*/\1/p')

CSRF_TOKEN=$(echo "$CSRF_TOKEN" | sed 's/&#43;/+/g')
CSRF_TOKEN=${CSRF_TOKEN//&#43;/+}
curl -s -b cookie_jar.txt -c cookie_jar.txt "http://localhost:8080/management/login" \
-H "X-CSRF-Token: $CSRF_TOKEN" \
-H 'Content-Type: application/json' \
Expand Down Expand Up @@ -287,4 +291,4 @@ curl -s -b cookie_jar.txt 'http://localhost:8080/pegout/configuration' \
"expireBlocks": 500,
"bridgeTransactionMin": "1500000000000000000"
}
}'
}'
6 changes: 4 additions & 2 deletions docker-compose/lps/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
FROM --platform=linux/amd64 golang:1.22.8@sha256:0ca97f4ab335f4b284a5b8190980c7cdc21d320d529f2b643e8a8733a69bfb6b AS builder

ARG COMMIT_HASH
ENV COMMIT_HASH=${COMMIT_HASH}
ARG COMMIT_TAG
ENV COMMIT_HASH_VALUE=${COMMIT_HASH}
ENV COMMIT_TAG_VALUE=${COMMIT_TAG}

WORKDIR /code

Expand All @@ -10,7 +12,7 @@ COPY cmd ./cmd
COPY pkg ./pkg
COPY internal ./internal

RUN make build
RUN test -n "$COMMIT_TAG_VALUE" && test -n "$COMMIT_HASH_VALUE" && make build

FROM --platform=linux/amd64 alpine:3.19.1@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b

Expand Down
2 changes: 2 additions & 0 deletions docker-compose/mainnet/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ services:
dockerfile: docker-compose/lps/Dockerfile
args:
UID: "${LPS_UID}"
COMMIT_HASH: "${COMMIT_HASH}"
COMMIT_TAG: "${COMMIT_TAG}"
image: lps:latest
container_name: lps01
environment:
Expand Down
21 changes: 10 additions & 11 deletions docs/LP-Management.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Liquidity Provider Server - Liquidity Provider specification
The intent of this document is to explain all the points that the liquidity provider (LP) should know in order to operate his instance of the liquidity
provider server (LPS).
This document contains both technical and non-technical information, so it is recommended to be reviewed by the LP itself and the person who is in change of
This document contains both technical and non-technical information, so it is recommended to be reviewed by the LP itself and the person who is in change of
setting up the environment where the LPS is going to be deployed.

## Table of contents
Expand All @@ -20,17 +20,17 @@ If you are a liquidity provider, and you're not interested in the technical deta
- [Wallet Management](#wallet-management)

## Context
In the Flyover Protocol, there are two main actors, the regular user (user), who is party interested in executing Peg-In/Peg-Out operations and the Liquidity
Provider (LP), who puts liquidity to speed up the operation for the user in exchange for a fee as a reward. In order to do this, the user and the LP need to
In the Flyover Protocol, there are two main actors, the regular user (user), who is party interested in executing Peg-In/Peg-Out operations and the Liquidity
Provider (LP), who puts liquidity to speed up the operation for the user in exchange for a fee as a reward. In order to do this, the user and the LP need to
agree on the terms of the service (a Peg-In/Peg-Out *Quote*). This implies that the different LPs may offer different quotes, so the user needs to be able to
interact with each LP to receive quote details and decide which one is going to use for the operation.

The user interacts with the Flyover Protocol through the [Flyover SDK](https://github.com/rsksmart/unified-bridges-sdk/tree/main/packages/flyover-sdk). This
The user interacts with the Flyover Protocol through the [Flyover SDK](https://github.com/rsksmart/unified-bridges-sdk/tree/main/packages/flyover-sdk). This
SDK fetches the list of the available LP from the liquidity bridge contract (LBC), this contract returns a list where each element has some information about
the LP, among this information will be the URL of the liquidity provider server (LPS) instance of that LP so the user can communicate with it. This means
the LP, among this information will be the URL of the liquidity provider server (LPS) instance of that LP so the user can communicate with it. This means
that **the LPS has an API that every user interacts with to do the quote agreement**.

The LP also needs to interact with the protocol to perform some management operations related to topics such as collateral, funds, fees management, configuration,
The LP also needs to interact with the protocol to perform some management operations related to topics such as collateral, funds, fees management, configuration,
etc. The LP does this operation through the LPS, that's the reason why the LPS also has an API that the LP interacts with to perform various management operations.

To summarize, the LPS has two main APIs:
Expand All @@ -55,14 +55,14 @@ environment where the LPS will run.
By default, the Management API is disabled, and it can be enabled only by setting the `ENABLE_MANAGEMENT_API` environment variable to `true`. This is a security measure
to ensure that the API will only be accessible if it is explicitly enabled by the LP (or the person setting up the environment).

Once this variable is set to true **it is responsibility of the LP and the person setting up the environment to ensure that the API is properly secured**.
Once this variable is set to true **it is responsibility of the LP and the person setting up the environment to ensure that the API is properly secured**.

### Management UI Access
The LPS provides a Management UI out of the box to facilitate the interaction with the Management API. To go to that UI you just need to go to
`<LPS URL>/management` page in your browser.

In order to interact with this API, the LP needs to be authenticated. The authentication mechanisms consists in user/password credentials. There is a default credentials
pair which is `admin` as username and a random password that the LPS will generate on its startup in the file `management_password.txt` inside the temporal directory
pair which is `admin` as username and a random password that the LPS will generate on its startup in the file `management_password.txt` inside the temporal directory
of your OS. E. g.: `/tmp/management_password.txt`.

The first time that the LP enters the Management UI he will be asked to provide the default credentials and set the new ones to use from that point to the future.
Expand Down Expand Up @@ -108,13 +108,14 @@ whether it should be treated as public or secured as a private endpoint.
| /management/logout | POST | PRIVATE | Logout from the Management API |
| /management/credentials | POST | PRIVATE | Update credentials for Management API login |
| /management | GET | PRIVATE | Serve Management UI |
| /version | GET | PUBLIC | Get server version info |

## Wallet management
The LPS performs operations in behalf of the LP during the process of the protocol, it means that it requires access to both LP's Bitcoin and
Rootstock wallets. To be more specific, it requires access to the RSK wallet of the LP and by having it, it also has access to the BTC wallet
associated with that RSK wallet.

The LPS has the following options to be provided with the access of that wallet, and depending on the option picked by the LP (set with
The LPS has the following options to be provided with the access of that wallet, and depending on the option picked by the LP (set with
the value of the `WALLET` environment variable), the LP will need to manage those wallets in a different way:

### Run LPS using local wallet integration
Expand Down Expand Up @@ -168,5 +169,3 @@ of the ways that the AWS client allows (through a file in home directory, enviro
the secrets to use through the environment variables (that are listed below). This is the recommended option for productive environments.
- `KEY_SECRET`
- `PASSWORD_SECRET`


26 changes: 26 additions & 0 deletions internal/adapters/entrypoints/rest/handlers/get_version_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package handlers

import (
"github.com/rsksmart/liquidity-provider-server/internal/adapters/entrypoints/rest"
"github.com/rsksmart/liquidity-provider-server/internal/usecases/liquidity_provider"
"github.com/rsksmart/liquidity-provider-server/pkg"
"net/http"
)

// NewVersionInfoHandler
// @Title Get server version
// @Description Returns the server version and revision
// @Route /version [get]
// @Success 200 object pkg.ServerInfoDTO
func NewVersionInfoHandler(useCase *liquidity_provider.ServerInfoUseCase) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
version, err := useCase.Run()
if err != nil {
rest.JsonErrorResponse(w, http.StatusInternalServerError, rest.NewErrorResponse(err.Error(), false))
return
}

dto := pkg.ToServerInfoDTO(version)
rest.JsonResponseWithBody(w, http.StatusOK, &dto)
}
}
1 change: 1 addition & 0 deletions internal/adapters/entrypoints/rest/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ type UseCaseRegistry interface {
GetPeginStatusUseCase() *pegin.StatusUseCase
GetPegoutStatusUseCase() *pegout.StatusUseCase
GetAvailableLiquidityUseCase() *liquidity_provider.GetAvailableLiquidityUseCase
GetServerInfoUseCase() *liquidity_provider.ServerInfoUseCase
}
7 changes: 7 additions & 0 deletions internal/adapters/entrypoints/rest/routes/public.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,12 @@ func GetPublicEndpoints(useCaseRegistry registry.UseCaseRegistry) []PublicEndpoi
Handler: handlers.NewGetAvailableLiquidityHandler(useCaseRegistry.GetAvailableLiquidityUseCase()),
},
},
{
Endpoint: Endpoint{
Path: "/version",
Method: http.MethodGet,
Handler: handlers.NewVersionInfoHandler(useCaseRegistry.GetServerInfoUseCase()),
},
},
}
}
3 changes: 2 additions & 1 deletion internal/adapters/entrypoints/rest/routes/public_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func TestGetPublicEndpoints(t *testing.T) {
registryMock.EXPECT().GetPeginStatusUseCase().Return(&pegin.StatusUseCase{})
registryMock.EXPECT().GetPegoutStatusUseCase().Return(&pegout.StatusUseCase{})
registryMock.EXPECT().GetAvailableLiquidityUseCase().Return(&liquidity_provider.GetAvailableLiquidityUseCase{})
registryMock.EXPECT().GetServerInfoUseCase().Return(&liquidity_provider.ServerInfoUseCase{})

endpoints := routes.GetPublicEndpoints(registryMock)
specBytes := test.ReadFile(t, "OpenApi.yml")
Expand All @@ -36,7 +37,7 @@ func TestGetPublicEndpoints(t *testing.T) {
err := yaml.Unmarshal(specBytes, spec)
require.NoError(t, err)

assert.Len(t, endpoints, 11)
assert.Len(t, endpoints, 12)
for _, endpoint := range endpoints {
lowerCaseMethod := strings.ToLower(endpoint.Method)
assert.NotNilf(t, spec.Paths[endpoint.Path][lowerCaseMethod], "Handler not found for path %s and verb %s", endpoint.Path, endpoint.Method)
Expand Down
1 change: 1 addition & 0 deletions internal/adapters/entrypoints/rest/routes/routes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ func setupRegistryMock(registryMock *mocks.UseCaseRegistryMock) {
registryMock.EXPECT().SetCredentialsUseCase().Return(&liquidity_provider.SetCredentialsUseCase{})
registryMock.EXPECT().LoginUseCase().Return(&liquidity_provider.LoginUseCase{})
registryMock.EXPECT().GetManagementUiDataUseCase().Return(&liquidity_provider.GetManagementUiDataUseCase{})
registryMock.EXPECT().GetServerInfoUseCase().Return(&liquidity_provider.ServerInfoUseCase{})
}

func assertHasCorsHeaders(t *testing.T, recorder *httptest.ResponseRecorder) {
Expand Down
6 changes: 6 additions & 0 deletions internal/configuration/registry/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type UseCaseRegistry struct {
pegoutStatusUseCase *pegout.StatusUseCase
availableLiquidityUseCase *liquidity_provider.GetAvailableLiquidityUseCase
updatePeginDepositUseCase *watcher.UpdatePeginDepositUseCase
getServerInfoUseCase *liquidity_provider.ServerInfoUseCase
}

// NewUseCaseRegistry
Expand Down Expand Up @@ -231,6 +232,7 @@ func NewUseCaseRegistry(
pegoutStatusUseCase: pegout.NewStatusUseCase(databaseRegistry.PegoutRepository),
availableLiquidityUseCase: liquidity_provider.NewGetAvailableLiquidityUseCase(liquidityProvider, liquidityProvider, liquidityProvider),
updatePeginDepositUseCase: watcher.NewUpdatePeginDepositUseCase(databaseRegistry.PeginRepository),
getServerInfoUseCase: liquidity_provider.NewServerInfoUseCase(),
}
}

Expand Down Expand Up @@ -341,3 +343,7 @@ func (registry *UseCaseRegistry) GetPegoutStatusUseCase() *pegout.StatusUseCase
func (registry *UseCaseRegistry) GetAvailableLiquidityUseCase() *liquidity_provider.GetAvailableLiquidityUseCase {
return registry.availableLiquidityUseCase
}

func (registry *UseCaseRegistry) GetServerInfoUseCase() *liquidity_provider.ServerInfoUseCase {
return registry.getServerInfoUseCase
}
5 changes: 5 additions & 0 deletions internal/entities/liquidity_provider/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,8 @@ func (confirmations ConfirmationsPerAmount) ForValue(value *entities.Wei) uint16
return confirmations[values[index]]
}
}

type ServerInfo struct {
Version string
Revision string
}
1 change: 1 addition & 0 deletions internal/usecases/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const (
PegoutQuoteStatusId UseCaseId = "PegoutQuoteStatus"
GetAvailableLiquidityId UseCaseId = "GetAvailableLiquidity"
UpdatePeginDepositId UseCaseId = "UpdatePeginDeposit"
ServerInfoId UseCaseId = "ServerInfo"
)

var (
Expand Down
28 changes: 28 additions & 0 deletions internal/usecases/liquidity_provider/server_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package liquidity_provider

import (
"errors"
"github.com/rsksmart/liquidity-provider-server/internal/entities/liquidity_provider"
"github.com/rsksmart/liquidity-provider-server/internal/usecases"
)

var (
BuildVersion string
BuildRevision string
)

type ServerInfoUseCase struct{}

func NewServerInfoUseCase() *ServerInfoUseCase {
return &ServerInfoUseCase{}
}

func (useCase *ServerInfoUseCase) Run() (liquidity_provider.ServerInfo, error) {
if BuildVersion == "" || BuildRevision == "" {
return liquidity_provider.ServerInfo{}, usecases.WrapUseCaseError(usecases.ServerInfoId, errors.New("unable to read build info"))
}
return liquidity_provider.ServerInfo{
Version: BuildVersion,
Revision: BuildRevision,
}, nil
}
Loading

0 comments on commit caebe94

Please sign in to comment.