Skip to content

Commit

Permalink
Traditional environment for backend development
Browse files Browse the repository at this point in the history
  • Loading branch information
jerryfletcher21 committed Jul 13, 2024
1 parent 7b3c62e commit 76ad7e3
Show file tree
Hide file tree
Showing 13 changed files with 2,324 additions and 15 deletions.
3 changes: 3 additions & 0 deletions .env-sample
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ REDIS_HOST="localhost"
REDIS_PORT="6379"
REDIS_DB_NUMBER="1"

LOG_TO_CONSOLE=False
LOGGER_LEVEL="WARNING"

# List of market price public APIs. If the currency is available in more than 1 API, will use median price.
MARKET_PRICE_APIS = https://blockchain.info/ticker, https://api.yadio.io/exrates/BTC, https://bitpay.com/rates/BTC, https://criptoya.com/api/btc

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -653,3 +653,6 @@ mobile/html/Web.bundle/assets*

# Protocol Buffers
api/lightning/*.proto

# Traditional environment
regtest/
4 changes: 2 additions & 2 deletions api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ def compute_avg_premium(queryset):

def validate_pgp_keys(pub_key, enc_priv_key):
"""Validates PGP valid keys. Formats them in a way understandable by the frontend"""
gpg = gnupg.GPG()
gpg = gnupg.GPG(gnupghome=config("GNUPG_DIR", default=None))

# Standardize format with linux linebreaks '\n'. Windows users submitting their own keys have '\r\n' breaking communication.
enc_priv_key = enc_priv_key.replace("\r\n", "\n").replace("\\", "\n")
Expand Down Expand Up @@ -441,7 +441,7 @@ def verify_signed_message(pub_key, signed_message):
Verifies a signed cleartext PGP message. Returns whether the signature
is valid (was made by the given pub_key) and the content of the message.
"""
gpg = gnupg.GPG()
gpg = gnupg.GPG(gnupghome=config("GNUPG_DIR", default=None))

# import the public key
import_result = gpg.import_keys(pub_key)
Expand Down
4 changes: 4 additions & 0 deletions api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from rest_framework.views import APIView

from api.logics import Logics
from api.tasks import cache_market
from api.models import (
Currency,
LNPayment,
Expand Down Expand Up @@ -146,6 +147,9 @@ def post(self, request):
status.HTTP_400_BAD_REQUEST,
)

if len(Currency.objects.all()) == 0:
cache_market()

# Creates a new order
order = Order(
type=type,
Expand Down
3 changes: 2 additions & 1 deletion requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
coverage==7.5.0
ruff==0.5.1
git+https://github.com/Reckless-Satoshi/drf-openapi-tester.git@soften-django-requirements
pre-commit==3.7.0
pre-commit==3.7.0
python-dotenv[cli]==1.0.1
6 changes: 3 additions & 3 deletions robosats/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
SESSION_COOKIE_HTTPONLY = False

# Logging settings
if os.environ.get("LOG_TO_CONSOLE"):
if config("LOG_TO_CONSOLE", cast=bool, default=False):
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
Expand All @@ -70,12 +70,12 @@
},
"root": {
"handlers": ["console"],
"level": "WARNING",
"level": str(config("LOGGER_LEVEL", cast=str, default="WARNING")),
},
"loggers": {
"api.utils": {
"handlers": ["console"],
"level": "WARNING",
"level": str(config("LOGGER_LEVEL", cast=str, default="WARNING")),
},
},
}
Expand Down
222 changes: 222 additions & 0 deletions scripts/traditional/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
# Robosats traditional environment

Robosats backend development and testing without docker and containers.

Binaries needed:
* postgresql (`postgres`, `initdb`, `psql`)
* redis (`redis-server`)
* bitcoin (`bitcoind`, `bitcoin-cli`)
* cln (`lightningd`, `lightning-cli`, `holdinvoice`)
* lnd (`lnd`, `lncli`)

## Preparation

Postgresql and redis can be found in all linux distros and bsds.

Some distros do not put postgresql binaries in `PATH`, if this is the
case simply link them somewhere in your `PATH`.

Example on debian:
```
ln -sf /usr/lib/postgresql/16/bin/postgres ~/.local/bin/
ln -sf /usr/lib/postgresql/16/bin/initdb ~/.local/bin/
ln -sf /usr/lib/postgresql/16/bin/psql ~/.local/bin/
```

Bitcoin nodes if not already installed need to be manually downloaded.
* bitcoin core binaries can be found here: https://bitcoincore.org/en/download
* cln binaries can be found here: https://github.com/ElementsProject/lightning/releases
* holdinvoice binary can be found here: https://github.com/daywalker90/holdinvoice/releases
* lnd binaries can be found here: https://github.com/lightningnetwork/lnd/releases

Example preparation:
```
$ python3 -m venv venv
$ . venv/bin/activate
$ pip install -r requirements_dev.txt
$ pip install -r requirements.txt

$ mkdir regtest
$ mkdir regtest/programs
$ cd regtest/programs
$ mkdir bitcoin cln lnd
# download bitcoin, cln (and holdinvoice) and lnd binaries

# if you want to use roboauto
# still in regtest/programs
$ git clone https://github.com/jerryfletcher21/roboauto
$ cd roboauto
$ pip install -r requirements.txt
$ pip install .
```

## env file

```
$ cp .env-sample .env
```
Edit `.env`, both robosats and regtest scripts will read from there.

Variables to change:
```
LNVENDOR = "CLN"
# LNVENDOR = "LND"

LND_DIR = "regtest/nodes/lnd-coord/"
MACAROON_PATH = "data/chain/bitcoin/regtest/admin.macaroon"
CLN_DIR = "regtest/nodes/cln-coord/regtest/"
BITCOIND_RPCPORT = "18443"
POSTGRES_DB = "robosats"
POSTGRES_USER = "robosats"
POSTGRES_PASSWORD = "robosats"
USE_TOR = False
LOG_TO_CONSOLE = True
LOGGER_LEVEL = "INFO"
```

Variables to add:
```
DEVELOPMENT = True
TESTING = True

LNVENDOR_ROBOT = "LND"
# LNVENDOR_ROBOT = "CLN"

BITCOIND_BIN = "regtest/programs/bitcoin/bitcoin-27.1/bin/bitcoind"
BITCOIN_CLI_BIN = "regtest/programs/bitcoin/bitcoin-27.1/bin/bitcoin-cli"
LIGHTNINGD_BIN = "regtest/programs/cln/usr/bin/lightningd"
LIGHTNING_CLI_BIN = "regtest/programs/cln/usr/bin/lightning-cli"
HOLDINVOICE_PLUGIN_BIN = "regtest/programs/cln/holdinvoice"
LND_BIN = "regtest/programs/lnd/lnd-linux-amd64-v0.18.1-beta/lnd"
LNCLI_BIN = "regtest/programs/lnd/lnd-linux-amd64-v0.18.1-beta/lncli"
ROBOAUTO_GIT_DIR = "regtest/programs/roboauto"

REGTEST_NODES_DIR = "regtest/nodes"
REGTEST_SERVICES_DIR = "regtest/services"
REGTEST_LOGS_DIR = "regtest/logs"
GNUPG_DIR = "regtest/services/gnupg"

BITCOIND_TEST_RPCUSER = "robodev"
BITCOIND_TEST_RPCPASSWORD = "robodev"
CLN_TEST_COORD_LISTEN_PORT = 9785
LND_TEST_COORD_LISTEN_PORT = 9885
LND_TEST_COORD_MACAROON_PATH = "regtest/nodes/lnd-coord/data/chain/bitcoin/regtest/admin.macaroon"
LND_TEST_ROBOT_MACAROON_PATH = "regtest/nodes/lnd-user/data/chain/bitcoin/regtest/admin.macaroon"
LND_TEST_ROBOT_REST_PORT = 8180
LND_TEST_COORD_REST_PORT = 8181
```

Paths can be relative or absolute. Binaries should be paths, they are
not resolved with `PATH`.

Roboauto can be disabled by not setting `ROBOAUTO_GIT_DIR` or setting it
to `false`.

If some ports are already in use, change their value.

To check which port are already in use, `netstat -tulnp` with root
privileges can be used.

For example if there is alread an instance of postgresql running on the
default port, change `POSTGRES_PORT = "5433"`.

## Usage

For development and testing two scripts are provided:
* `regtest-services` for non bitcoin related services
* `regtest-nodes` for bitcoin and lightning nodes

`regtest-services` sets up the database and manages the services.

Everything is done locally, so no root privileges/service managers are
needed.

`regtest-nodes` is a script that should be sourced, it sets up a regtest
environment, with bitcoin core, cln, lnd and roboauto, connecting them
and creating channels. It then exposes the functions `btc_reg`,
`cln_coord`, `cln_user`, `lnd_coord`, `lnd_user`, `ra_reg` to interact
with the nodes and roboauto.

If the script is sourced in a `bash` shell, it will also source
completions for all the functions.

`regtest-nodes` can also be run without arguments to simply expose the
functions to start and remove the nodes and to create the channels
between them, without setting up a specific environment.

Setup:
```
# after having changed .env file

$ . venv/bin/activate

# generate cln and lnd grpc
$ scripts/generate_grpc.sh

$ scripts/traditional/regtest-services postgres-setup

$ scripts/traditional/regtest-services postgres-database

# postgres-database will create the database specified by
# POSTGRES_DB in .env, it can be run multiple times with
# different values of POSTGRES_DB for different databases
```

Testing:
```
# edit .env setting LNVENDOR to either "CLN" or "LND"
# LNVENDOR_ROBOT while running tests should be set to "LND"

# in the main window
$ . venv/bin/activate
$ . scripts/traditional/regtest-nodes test

# in a secondary window
$ . venv/bin/activate
# can be stopped with Control-C
$ scripts/traditional/regtest-services test

# back in the main window
$ python3 manage.py test

# after having run the tests run
$ robosats_regtest_stop_and_remove_all
# to remove the nodes, they will be recreated when
# running the tests again

# the tests should be run with a clean database so if you have already run
# the server and want to keep the database, either use a different value
# of POSTGRES_DB or use a different directory by moving
# regtest/services/postgres somewhere and the moving it back when you want
# to run the server again
```

Development:
```
# edit .env setting LNVENDOR to either "CLN" or "LND"
# and LNVENDOR_ROBOT to either "CLN" or "LND"

# in the main window
$ . venv/bin/activate
$ . scripts/traditional/regtest-nodes server

# in a secondary window
$ . venv/bin/activate
# can be stopped with Control-C
$ scripts/traditional/regtest-services server

# to see the output of the django runserver command
# in a third window
$ tail -f regtest/logs/runserver

# if roboauto is active, use it to test the backend
# back in the main window
$ ra_reg --help
...
$ ra_reg create-order "$(ra_reg generate-robot --loc)" type=buy currency=btc min_amount=0.01 max_amount=0.02 payment_method="On-Chain BTC" premium=-1.5
...
$ ra_reg take-order $(ra_reg generate-robot --loc) order-id
...
$ ra_reg escrow-pay RobotName
...
```
Loading

0 comments on commit 76ad7e3

Please sign in to comment.