mirror of
https://github.com/aljazceru/python-teos.git
synced 2025-12-17 06:04:21 +01:00
pisa -> teos
This commit is contained in:
@@ -21,46 +21,46 @@ jobs:
|
||||
# Download and cache dependencies
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-dependencies-{{ checksum "pisa/requirements.txt" }}-{{ checksum "pisa/requirements-dev.txt" }}-{{ checksum "apps/cli/requirements-dev.txt" }}-{{ checksum "test/pisa/e2e/bitcoind_snap.sh" }}
|
||||
- v1-dependencies-{{ checksum "teos/requirements.txt" }}-{{ checksum "teos/requirements-dev.txt" }}-{{ checksum "apps/cli/requirements-dev.txt" }}-{{ checksum "test/teos/e2e/bitcoind_snap.sh" }}
|
||||
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: |
|
||||
sudo snap install `cat test/pisa/e2e/bitcoind_snap.sh`
|
||||
sudo snap install `cat test/teos/e2e/bitcoind_snap.sh`
|
||||
pyenv local 3.7.0
|
||||
python3 -m venv venv
|
||||
. venv/bin/activate
|
||||
sudo pip install --upgrade pip
|
||||
pip install -r pisa/requirements.txt
|
||||
pip install -r pisa/requirements-dev.txt
|
||||
pip install -r teos/requirements.txt
|
||||
pip install -r teos/requirements-dev.txt
|
||||
pip install -r apps/cli/requirements-dev.txt
|
||||
|
||||
- save_cache:
|
||||
paths:
|
||||
- ./venv
|
||||
- /snap
|
||||
key: v1-dependencies-{{ checksum "pisa/requirements.txt" }}-{{ checksum "pisa/requirements-dev.txt" }}-{{ checksum "apps/cli/requirements-dev.txt" }}-{{ checksum "test/pisa/e2e/bitcoind_snap.sh" }}
|
||||
key: v1-dependencies-{{ checksum "teos/requirements.txt" }}-{{ checksum "teos/requirements-dev.txt" }}-{{ checksum "apps/cli/requirements-dev.txt" }}-{{ checksum "test/teos/e2e/bitcoind_snap.sh" }}
|
||||
|
||||
# Run bitcoind for E2E testing (running it early so it has time to bootstrap)
|
||||
- run:
|
||||
name: Run bitcoind
|
||||
command: |
|
||||
mkdir -p /home/circleci/snap/bitcoin-core/common/.bitcoin/
|
||||
cp test/pisa/e2e/bitcoin.conf /home/circleci/snap/bitcoin-core/common/.bitcoin/
|
||||
cp test/teos/e2e/bitcoin.conf /home/circleci/snap/bitcoin-core/common/.bitcoin/
|
||||
/snap/bin/bitcoin-core.daemon
|
||||
|
||||
# Run unit tests
|
||||
- run:
|
||||
name: Creates config files
|
||||
command: |
|
||||
cp pisa/sample_conf.py pisa/conf.py
|
||||
cp teos/sample_conf.py teos/conf.py
|
||||
cp apps/cli/sample_conf.py apps/cli/conf.py
|
||||
|
||||
- run:
|
||||
name: Run pisa unit tests
|
||||
name: Run teos unit tests
|
||||
command: |
|
||||
. venv/bin/activate
|
||||
pytest test/pisa/unit/
|
||||
pytest test/teos/unit/
|
||||
|
||||
- run:
|
||||
name: Run common unit tests
|
||||
@@ -74,14 +74,14 @@ jobs:
|
||||
. venv/bin/activate
|
||||
pytest test/apps/cli/unit
|
||||
|
||||
# Setup pisa for E2E testing
|
||||
# Setup teos for E2E testing
|
||||
- run:
|
||||
name: Setup pisa
|
||||
name: Setup teos
|
||||
command: |
|
||||
. venv/bin/activate
|
||||
cp test/pisa/e2e/pisa-conf.py pisa/conf.py
|
||||
python3 -m apps.generate_key -d ~/.pisa_btc/
|
||||
python3 -m apps.generate_key -n cli -d ~/.pisa_btc/
|
||||
cp test/teos/e2e/teos-conf.py teos/conf.py
|
||||
python3 -m apps.generate_key -d ~/.teos/
|
||||
python3 -m apps.generate_key -n cli -d ~/.teos/
|
||||
|
||||
|
||||
# Run E2E tests
|
||||
@@ -89,7 +89,7 @@ jobs:
|
||||
name: Run e2e tests
|
||||
command: |
|
||||
. venv/bin/activate
|
||||
pytest test/pisa/e2e/
|
||||
pytest test/teos/e2e/
|
||||
|
||||
# - store_artifacts:
|
||||
# path: test-reports
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[run]
|
||||
omit =
|
||||
*__init__.py
|
||||
pisa/pisad.py
|
||||
pisa/logger.py
|
||||
pisa/sample_conf.py
|
||||
pisa/utils/auth_proxy.py
|
||||
teos/teosd.py
|
||||
teos/logger.py
|
||||
teos/sample_conf.py
|
||||
teos/utils/auth_proxy.py
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -17,4 +17,5 @@ test.py
|
||||
.coverage
|
||||
htmlcov
|
||||
docs/
|
||||
.pisa_btc
|
||||
.teos
|
||||
.teos_cli
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Contributing to PISA
|
||||
# Contributing to The Eye of Satoshi
|
||||
|
||||
The following is a set of guidelines for contributing to PISA.
|
||||
The following is a set of guidelines for contributing to TEOS.
|
||||
|
||||
## Code Style Guidelines
|
||||
We use [black](https://github.com/psf/black) as our base code formatter with a line length of 120 chars. Before submitting a PR make sure you have properly formatted your code by running:
|
||||
@@ -36,7 +36,7 @@ An exception to the rule are nested `if` statements that placed right after each
|
||||
for opt, arg in opts:
|
||||
if opt in ["-s", "server"]:
|
||||
if arg:
|
||||
pisa_api_server = arg
|
||||
teos_api_server = arg
|
||||
```
|
||||
|
||||
```python
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Dependencies
|
||||
|
||||
`wt_cli` has both system-wide and Python dependencies. This document walks you through how to satisfy them.
|
||||
`teos_cli` has both system-wide and Python dependencies. This document walks you through how to satisfy them.
|
||||
|
||||
## System-wide dependencies
|
||||
|
||||
`wt_cli` has the following system-wide dependencies:
|
||||
`teos_cli` has the following system-wide dependencies:
|
||||
|
||||
- `python3`
|
||||
- `pip3`
|
||||
@@ -27,7 +27,7 @@ It is also likely that, if `python3` is installed in our system, the `python` al
|
||||
|
||||
python3 --version
|
||||
|
||||
If `python3` is installed but the `python` alias is not set to it, we should either set it, or use `python3` to run `wt_cli`.
|
||||
If `python3` is installed but the `python` alias is not set to it, we should either set it, or use `python3` to run `teos_cli`.
|
||||
|
||||
Regarding `pip`, we can check what version is installed in our system (if any) by running:
|
||||
|
||||
@@ -74,7 +74,7 @@ and for `pip3`:
|
||||
|
||||
## Python dependencies
|
||||
|
||||
`wt_cli` has the following dependencies (which can be satisfied by using `pip install -r requirements.txt`):
|
||||
`teos_cli` has the following dependencies (which can be satisfied by using `pip install -r requirements.txt`):
|
||||
|
||||
- `cryptography`
|
||||
- `requests`
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# Install
|
||||
|
||||
`wt_cli` has some dependencies that can be satisfied by following [DEPENDENCIES.md](DEPENDENCIES.md). If your system already satisfies the dependencies, you can skip that part.
|
||||
`teos_cli` has some dependencies that can be satisfied by following [DEPENDENCIES.md](DEPENDENCIES.md). If your system already satisfies the dependencies, you can skip that part.
|
||||
|
||||
There are two ways of running `wt_cli`: adding the library to the `PYTHONPATH` env variable, or running it as a module.
|
||||
There are two ways of running `teos_cli`: adding the library to the `PYTHONPATH` env variable, or running it as a module.
|
||||
|
||||
## Modifying `PYTHONPATH`
|
||||
In order to run `wt_cli`, you should set your `PYTHONPATH` env variable to include the folder that contains the `apps` folder. You can do so by running:
|
||||
In order to run `teos_cli`, you should set your `PYTHONPATH` env variable to include the folder that contains the `apps` folder. You can do so by running:
|
||||
|
||||
export PYTHONPATH=$PYTHONPATH:<absolute_path_to_apps>
|
||||
|
||||
@@ -17,17 +17,17 @@ You should also include the command in your `.bashrc` to avoid having to run it
|
||||
|
||||
echo 'export PYTHONPATH=$PYTHONPATH:<absolute_path_to_apps>' >> ~/.bashrc
|
||||
|
||||
Once the `PYTHONPATH` is set, you should be able to run `wt_cli` straightaway. Try it by running:
|
||||
Once the `PYTHONPATH` is set, you should be able to run `teos_cli` straightaway. Try it by running:
|
||||
|
||||
cd <absolute_path_to_apps>/apps/cli
|
||||
python wt_cli.py -h
|
||||
python teos_cli.py -h
|
||||
|
||||
## Running `wt_cli` as a module
|
||||
## Running `teos_cli` as a module
|
||||
Python code can be also run as a module, to do so you need to use `python -m`. From `apps` **parent** directory run:
|
||||
|
||||
python -m apps.cli.wt_cli -h
|
||||
python -m apps.cli.teos_cli -h
|
||||
|
||||
Notice that if you run `wt_cli` as a module, you'll need to replace all the calls from `python wt_cli.py <argument>` to `python -m apps.cli.wt_cli <argument>`
|
||||
Notice that if you run `teos_cli` as a module, you'll need to replace all the calls from `python teos_cli.py <argument>` to `python -m apps.cli.teos_cli <argument>`
|
||||
|
||||
## Modify configuration parameters
|
||||
If you'd like to modify some of the configuration defaults (such as the user directory, where the logs and appointment receipts will be stored) you can do so in the config file located at:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# wt_cli
|
||||
# teos_cli
|
||||
|
||||
`wt_cli` is a command line interface to interact with the Eye of Satoshi watchtower server, written in Python3.
|
||||
`teos_cli` is a command line interface to interact with the Eye of Satoshi watchtower server, written in Python3.
|
||||
|
||||
## Dependencies
|
||||
Refer to [DEPENDENCIES.md](DEPENDENCIES.md)
|
||||
@@ -11,7 +11,7 @@ Refer to [INSTALL.md](INSTALL.md)
|
||||
|
||||
## Usage
|
||||
|
||||
python wt_cli.py [global options] command [command options] [arguments]
|
||||
python teos_cli.py [global options] command [command options] [arguments]
|
||||
|
||||
#### Global options
|
||||
|
||||
@@ -59,7 +59,7 @@ The alpha release does not have authentication, payments nor rate limiting, ther
|
||||
|
||||
#### Usage
|
||||
|
||||
python wt_cli.py add_appointment [command options] <appointment>/<path_to_appointment_file>
|
||||
python teos_cli.py add_appointment [command options] <appointment>/<path_to_appointment_file>
|
||||
|
||||
if `-f, --file` **is** specified, then the command expects a path to a json file instead of a json encoded string as parameter.
|
||||
|
||||
@@ -103,7 +103,7 @@ if `-f, --file` **is** specified, then the command expects a path to a json file
|
||||
|
||||
#### Usage
|
||||
|
||||
python wt_cli.py get_appointment <appointment_locator>
|
||||
python teos_cli.py get_appointment <appointment_locator>
|
||||
|
||||
|
||||
|
||||
@@ -112,11 +112,11 @@ if `-f, --file` **is** specified, then the command expects a path to a json file
|
||||
Shows the list of commands or help about how to run a specific command.
|
||||
|
||||
#### Usage
|
||||
python wt_cli.py help
|
||||
python teos_cli.py help
|
||||
|
||||
or
|
||||
|
||||
python wt_cli.py help command
|
||||
python teos_cli.py help command
|
||||
|
||||
## Example
|
||||
|
||||
@@ -131,7 +131,7 @@ or
|
||||
2. Send the appointment to the tower API. Which will then start monitoring for matching transactions.
|
||||
|
||||
```
|
||||
python wt_cli.py add_appointment -f dummy_appointment_data.json
|
||||
python teos_cli.py add_appointment -f dummy_appointment_data.json
|
||||
```
|
||||
|
||||
This returns a appointment locator that can be used to get updates about this appointment from the tower.
|
||||
@@ -139,20 +139,20 @@ or
|
||||
3. Test that the tower is still watching the appointment by replacing the appointment locator received into the following command:
|
||||
|
||||
```
|
||||
python wt_cli.py get_appointment <appointment_locator>
|
||||
python teos_cli.py get_appointment <appointment_locator>
|
||||
```
|
||||
|
||||
## the Eye of Satoshi's API
|
||||
|
||||
If you wish to read about the underlying API, and how to write your own tool to interact with it, refer to [tEOS-API.md](tEOS-API.md).
|
||||
If you wish to read about the underlying API, and how to write your own tool to interact with it, refer to [tEOS-API.md](TEOS-API.md).
|
||||
|
||||
## Are you reckless? Try me on mainnet
|
||||
Would you like to try me on `mainnet` instead of `testnet`? Add `-s https://mainnet.teos.pisa.watch` to your calls, for example:
|
||||
|
||||
```
|
||||
python wt_cli.py -s https://teosmainnet.pisa.watch add_appointment -f dummy_appointment_data.json
|
||||
python teos_cli.py -s https://teosmainnet.pisa.watch add_appointment -f dummy_appointment_data.json
|
||||
```
|
||||
|
||||
You can also change the config file to avoid specifying the server every time:
|
||||
|
||||
`DEFAULT_PISA_API_SERVER = "https://teosmainnet.pisa.watch"`
|
||||
`DEFAULT_TEOS_API_SERVER = "https://teosmainnet.pisa.watch"`
|
||||
@@ -6,14 +6,14 @@ LOG_PREFIX = "cli"
|
||||
|
||||
# Load config fields
|
||||
conf_fields = {
|
||||
"DEFAULT_PISA_API_SERVER": {"value": conf.DEFAULT_PISA_API_SERVER, "type": str},
|
||||
"DEFAULT_PISA_API_PORT": {"value": conf.DEFAULT_PISA_API_PORT, "type": int},
|
||||
"DEFAULT_TEOS_API_SERVER": {"value": conf.DEFAULT_TEOS_API_SERVER, "type": str},
|
||||
"DEFAULT_TEOS_API_PORT": {"value": conf.DEFAULT_TEOS_API_PORT, "type": int},
|
||||
"DATA_FOLDER": {"value": conf.DATA_FOLDER, "type": str},
|
||||
"CLIENT_LOG_FILE": {"value": conf.CLIENT_LOG_FILE, "type": str, "path": True},
|
||||
"APPOINTMENTS_FOLDER_NAME": {"value": conf.APPOINTMENTS_FOLDER_NAME, "type": str, "path": True},
|
||||
# "CLI_PUBLIC_KEY": {"value": conf.CLI_PUBLIC_KEY, "type": str, "path": True},
|
||||
# "CLI_PRIVATE_KEY": {"value": conf.CLI_PRIVATE_KEY, "type": str, "path": True},
|
||||
# "PISA_PUBLIC_KEY": {"value": conf.PISA_PUBLIC_KEY, "type": str, "path": True},
|
||||
# "TEOS_PUBLIC_KEY": {"value": conf.TEOS_PUBLIC_KEY, "type": str, "path": True},
|
||||
}
|
||||
|
||||
# Expand user (~) if found and check fields are correct
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
def help_add_appointment():
|
||||
return (
|
||||
"NAME:"
|
||||
"\tpython wt_cli add_appointment - Registers a json formatted appointment to the tower."
|
||||
"\tpython teos_cli add_appointment - Registers a json formatted appointment to the tower."
|
||||
"\n\nUSAGE:"
|
||||
"\tpython wt_cli add_appointment [command options] appointment/path_to_appointment_file"
|
||||
"\tpython teos_cli add_appointment [command options] appointment/path_to_appointment_file"
|
||||
"\n\nDESCRIPTION:"
|
||||
"\n\n\tRegisters a json formatted appointment to the tower."
|
||||
"\n\tif -f, --file *is* specified, then the command expects a path to a json file instead of a json encoded "
|
||||
@@ -17,9 +17,9 @@ def help_add_appointment():
|
||||
def help_get_appointment():
|
||||
return (
|
||||
"NAME:"
|
||||
"\tpython wt_cli get_appointment - Gets json formatted data about an appointment from the tower."
|
||||
"\tpython teos_cli get_appointment - Gets json formatted data about an appointment from the tower."
|
||||
"\n\nUSAGE:"
|
||||
"\tpython wt_cli get_appointment appointment_locator"
|
||||
"\tpython teos_cli get_appointment appointment_locator"
|
||||
"\n\nDESCRIPTION:"
|
||||
"\n\n\tGets json formatted data about an appointment from the tower.\n"
|
||||
)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# PISA-WT-SERVER
|
||||
DEFAULT_PISA_API_SERVER = "https://teos.pisa.watch"
|
||||
DEFAULT_PISA_API_PORT = 443
|
||||
# TEOS-SERVER
|
||||
DEFAULT_TEOS_API_SERVER = "https://teos.pisa.watch"
|
||||
DEFAULT_TEOS_API_PORT = 443
|
||||
|
||||
# WT-CLI
|
||||
DATA_FOLDER = "~/.wt_cli/"
|
||||
DATA_FOLDER = "~/.teos_cli/"
|
||||
|
||||
CLIENT_LOG_FILE = "cli.log"
|
||||
APPOINTMENTS_FOLDER_NAME = "appointment_receipts"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## tEOS-API
|
||||
## TEOS-API
|
||||
|
||||
### Disclaimer: Everything in here is experimental and subject to change.
|
||||
|
||||
|
||||
@@ -24,26 +24,26 @@ from common.tools import check_sha256_hex_format, check_locator_format, compute_
|
||||
logger = Logger(actor="Client", log_name_prefix=LOG_PREFIX)
|
||||
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix=LOG_PREFIX)
|
||||
|
||||
# FIXME: creating a simpler load_keys for the alpha. Client keys will not be necessary. PISA key is hardcoded.
|
||||
# def load_keys(pisa_pk_path, cli_sk_path, cli_pk_path):
|
||||
# FIXME: creating a simpler load_keys for the alpha. Client keys will not be necessary. TEOS key is hardcoded.
|
||||
# def load_keys(teos_pk_path, cli_sk_path, cli_pk_path):
|
||||
# """
|
||||
# Loads all the keys required so sign, send, and verify the appointment.
|
||||
#
|
||||
# Args:
|
||||
# pisa_pk_path (:obj:`str`): path to the PISA public key file.
|
||||
# teos_pk_path (:obj:`str`): path to the TEOS public key file.
|
||||
# cli_sk_path (:obj:`str`): path to the client private key file.
|
||||
# cli_pk_path (:obj:`str`): path to the client public key file.
|
||||
#
|
||||
# Returns:
|
||||
# :obj:`tuple` or ``None``: a three item tuple containing a pisa_pk object, cli_sk object and the cli_sk_der
|
||||
# :obj:`tuple` or ``None``: a three item tuple containing a teos_pk object, cli_sk object and the cli_sk_der
|
||||
# encoded key if all keys can be loaded. ``None`` otherwise.
|
||||
# """
|
||||
#
|
||||
# pisa_pk_der = Cryptographer.load_key_file(pisa_pk_path)
|
||||
# pisa_pk = Cryptographer.load_public_key_der(pisa_pk_der)
|
||||
# teos_pk_der = Cryptographer.load_key_file(teos_pk_path)
|
||||
# teos_pk = Cryptographer.load_public_key_der(teos_pk_der)
|
||||
#
|
||||
# if pisa_pk is None:
|
||||
# logger.error("PISA's public key file not found. Please check your settings")
|
||||
# if teos_pk is None:
|
||||
# logger.error("TEOS's public key file not found. Please check your settings")
|
||||
# return None
|
||||
#
|
||||
# cli_sk_der = Cryptographer.load_key_file(cli_sk_path)
|
||||
@@ -59,14 +59,14 @@ common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix=LOG_
|
||||
# logger.error("Client's public key file not found. Please check your settings")
|
||||
# return None
|
||||
#
|
||||
# return pisa_pk, cli_sk, cli_pk_der
|
||||
# return teos_pk, cli_sk, cli_pk_der
|
||||
|
||||
|
||||
def load_keys():
|
||||
PISA_PUBLIC_KEY = "0230053e39c53b8bcb43354a4ed886b8082af1d1e8fc14956e60ad0592bfdfab51"
|
||||
pisa_pk = PublicKey(binascii.unhexlify(PISA_PUBLIC_KEY))
|
||||
TEOS_PUBLIC_KEY = "0230053e39c53b8bcb43354a4ed886b8082af1d1e8fc14956e60ad0592bfdfab51"
|
||||
teos_pk = PublicKey(binascii.unhexlify(TEOS_PUBLIC_KEY))
|
||||
|
||||
return pisa_pk
|
||||
return teos_pk
|
||||
|
||||
|
||||
def add_appointment(args):
|
||||
@@ -95,9 +95,9 @@ def add_appointment(args):
|
||||
:obj:`bool`: True if the appointment is accepted by the tower and the receipt is properly stored, false if any
|
||||
error occurs during the process.
|
||||
"""
|
||||
# FIXME: creating a simpler load_keys for the alpha. Client keys will not be necessary. PISA key is hardcoded.
|
||||
# pisa_pk, cli_sk, cli_pk_der = load_keys(
|
||||
# config.get("PISA_PUBLIC_KEY"), config.get("CLI_PRIVATE_KEY"), config.get("CLI_PUBLIC_KEY")
|
||||
# FIXME: creating a simpler load_keys for the alpha. Client keys will not be necessary. TEOS key is hardcoded.
|
||||
# teos_pk, cli_sk, cli_pk_der = load_keys(
|
||||
# config.get("TEOS_PUBLIC_KEY"), config.get("CLI_PRIVATE_KEY"), config.get("CLI_PUBLIC_KEY")
|
||||
# )
|
||||
#
|
||||
# try:
|
||||
@@ -106,9 +106,9 @@ def add_appointment(args):
|
||||
# except binascii.Error as e:
|
||||
# logger.error("Could not successfully encode public key as hex", error=str(e))
|
||||
# return False
|
||||
pisa_pk = load_keys()
|
||||
teos_pk = load_keys()
|
||||
|
||||
if pisa_pk is None:
|
||||
if teos_pk is None:
|
||||
return False
|
||||
|
||||
# Get appointment data from user.
|
||||
@@ -163,7 +163,7 @@ def add_appointment(args):
|
||||
return False
|
||||
|
||||
rpk = Cryptographer.recover_pk(appointment.serialize(), signature)
|
||||
if not Cryptographer.verify_rpk(pisa_pk, rpk):
|
||||
if not Cryptographer.verify_rpk(teos_pk, rpk):
|
||||
logger.error("The returned appointment's signature is invalid")
|
||||
return False
|
||||
|
||||
@@ -237,7 +237,7 @@ def post_appointment(data):
|
||||
logger.info("Sending appointment to the Eye of Satoshi")
|
||||
|
||||
try:
|
||||
add_appointment_endpoint = "{}:{}".format(pisa_api_server, pisa_api_port)
|
||||
add_appointment_endpoint = "{}:{}".format(teos_api_server, teos_api_port)
|
||||
return requests.post(url=add_appointment_endpoint, json=json.dumps(data), timeout=5)
|
||||
|
||||
except ConnectTimeout:
|
||||
@@ -347,7 +347,7 @@ def get_appointment(locator):
|
||||
logger.error("The provided locator is not valid", locator=locator)
|
||||
return None
|
||||
|
||||
get_appointment_endpoint = "{}:{}/get_appointment".format(pisa_api_server, pisa_api_port)
|
||||
get_appointment_endpoint = "{}:{}/get_appointment".format(teos_api_server, teos_api_port)
|
||||
parameters = "?locator={}".format(locator)
|
||||
|
||||
try:
|
||||
@@ -372,7 +372,7 @@ def get_appointment(locator):
|
||||
def show_usage():
|
||||
return (
|
||||
"USAGE: "
|
||||
"\n\tpython wt_cli.py [global options] command [command options] [arguments]"
|
||||
"\n\tpython teos_cli.py [global options] command [command options] [arguments]"
|
||||
"\n\nCOMMANDS:"
|
||||
"\n\tadd_appointment \tRegisters a json formatted appointment with the tower."
|
||||
"\n\tget_appointment \tGets json formatted data about an appointment from the tower."
|
||||
@@ -381,14 +381,14 @@ def show_usage():
|
||||
"\n\t-s, --server \tAPI server where to send the requests. Defaults to https://teos.pisa.watch (modifiable in "
|
||||
"config.py)"
|
||||
"\n\t-p, --port \tAPI port where to send the requests. Defaults to 443 (modifiable in conf.py)"
|
||||
"\n\t-d, --debug \tshows debug information and stores it in wt_cli.log"
|
||||
"\n\t-d, --debug \tshows debug information and stores it in teos_cli.log"
|
||||
"\n\t-h --help \tshows this message."
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pisa_api_server = config.get("DEFAULT_PISA_API_SERVER")
|
||||
pisa_api_port = config.get("DEFAULT_PISA_API_PORT")
|
||||
teos_api_server = config.get("DEFAULT_TEOS_API_SERVER")
|
||||
teos_api_port = config.get("DEFAULT_TEOS_API_PORT")
|
||||
commands = ["add_appointment", "get_appointment", "help"]
|
||||
|
||||
try:
|
||||
@@ -397,11 +397,11 @@ if __name__ == "__main__":
|
||||
for opt, arg in opts:
|
||||
if opt in ["-s", "server"]:
|
||||
if arg:
|
||||
pisa_api_server = arg
|
||||
teos_api_server = arg
|
||||
|
||||
if opt in ["-p", "--port"]:
|
||||
if arg:
|
||||
pisa_api_port = int(arg)
|
||||
teos_api_port = int(arg)
|
||||
|
||||
if opt in ["-h", "--help"]:
|
||||
sys.exit(show_usage())
|
||||
@@ -8,7 +8,7 @@ from cryptography.hazmat.primitives.asymmetric import ec
|
||||
|
||||
|
||||
# Simple tool to generate an ECDSA private key using the secp256k1 curve and save private and public keys
|
||||
# as 'pisa_sk.der' 'and pisa_pk.der', respectively.
|
||||
# as 'teos_sk.der' 'and teos_pk.der', respectively.
|
||||
|
||||
|
||||
def save_sk(sk, filename):
|
||||
@@ -29,7 +29,7 @@ def save_pk(pk, filename):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
name = "pisa"
|
||||
name = "teos"
|
||||
output_dir = "."
|
||||
|
||||
opts, _ = getopt(argv[1:], "n:d:", ["name", "dir"])
|
||||
|
||||
@@ -41,7 +41,7 @@ class Appointment:
|
||||
``{locator, start_time, end_time, to_self_delay, encrypted_blob}``
|
||||
|
||||
Returns:
|
||||
:obj:`Appointment <pisa.appointment.Appointment>`: An appointment initialized using the provided data.
|
||||
:obj:`Appointment <teos.appointment.Appointment>`: An appointment initialized using the provided data.
|
||||
|
||||
Raises:
|
||||
ValueError: If one of the mandatory keys is missing in ``appointment_data``.
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import os
|
||||
import pisa.conf as conf
|
||||
import teos.conf as conf
|
||||
from common.tools import check_conf_fields, setup_logging, extend_paths, setup_data_folder
|
||||
from pisa.utils.auth_proxy import AuthServiceProxy
|
||||
from teos.utils.auth_proxy import AuthServiceProxy
|
||||
|
||||
HOST = "localhost"
|
||||
PORT = 9814
|
||||
LOG_PREFIX = "pisa"
|
||||
LOG_PREFIX = "teos"
|
||||
|
||||
# Load config fields
|
||||
conf_fields = {
|
||||
@@ -22,7 +22,7 @@ conf_fields = {
|
||||
"EXPIRY_DELTA": {"value": conf.EXPIRY_DELTA, "type": int},
|
||||
"MIN_TO_SELF_DELAY": {"value": conf.MIN_TO_SELF_DELAY, "type": int},
|
||||
"SERVER_LOG_FILE": {"value": conf.SERVER_LOG_FILE, "type": str, "path": True},
|
||||
"PISA_SECRET_KEY": {"value": conf.PISA_SECRET_KEY, "type": str, "path": True},
|
||||
"TEOS_SECRET_KEY": {"value": conf.TEOS_SECRET_KEY, "type": str, "path": True},
|
||||
"DB_PATH": {"value": conf.DB_PATH, "type": str, "path": True},
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ import json
|
||||
import logging
|
||||
from flask import Flask, request, abort, jsonify
|
||||
|
||||
from pisa import HOST, PORT, LOG_PREFIX
|
||||
from teos import HOST, PORT, LOG_PREFIX
|
||||
from common.logger import Logger
|
||||
from pisa.inspector import Inspector
|
||||
from teos.inspector import Inspector
|
||||
from common.appointment import Appointment
|
||||
|
||||
from common.constants import HTTP_OK, HTTP_BAD_REQUEST, HTTP_SERVICE_UNAVAILABLE, LOCATOR_LEN_HEX
|
||||
@@ -32,7 +32,7 @@ class API:
|
||||
:obj:`tuple`: A tuple containing the response (``json``) and response code (``int``). For accepted
|
||||
appointments, the ``rcode`` is always 0 and the response contains the signed receipt. For rejected
|
||||
appointments, the ``rcode`` is a negative value and the response contains the error message. Error messages
|
||||
can be found at :mod:`Errors <pisa.errors>`.
|
||||
can be found at :mod:`Errors <teos.errors>`.
|
||||
"""
|
||||
|
||||
# Getting the real IP if the server is behind a reverse proxy
|
||||
@@ -101,11 +101,11 @@ class API:
|
||||
Returns:
|
||||
:obj:`dict`: A json formatted dictionary containing information about the requested appointment.
|
||||
|
||||
A ``status`` flag is added to the data provided by either the :obj:`Watcher <pisa.watcher.Watcher>` or the
|
||||
:obj:`Responder <pisa.responder.Responder>` that signals the status of the appointment.
|
||||
A ``status`` flag is added to the data provided by either the :obj:`Watcher <teos.watcher.Watcher>` or the
|
||||
:obj:`Responder <teos.responder.Responder>` that signals the status of the appointment.
|
||||
|
||||
- Appointments hold by the :obj:`Watcher <pisa.watcher.Watcher>` are flagged as ``being_watched``.
|
||||
- Appointments hold by the :obj:`Responder <pisa.responder.Responder>` are flagged as ``dispute_triggered``.
|
||||
- Appointments hold by the :obj:`Watcher <teos.watcher.Watcher>` are flagged as ``being_watched``.
|
||||
- Appointments hold by the :obj:`Responder <teos.responder.Responder>` are flagged as ``dispute_triggered``.
|
||||
- Unknown appointments are flagged as ``not_found``.
|
||||
"""
|
||||
|
||||
@@ -157,8 +157,8 @@ class API:
|
||||
|
||||
Returns:
|
||||
:obj:`dict`: A json formatted dictionary containing all the appointments hold by the
|
||||
:obj:`Watcher <pisa.watcher.Watcher>` (``watcher_appointments``) and by the
|
||||
:obj:`Responder <pisa.responder.Responder>` (``responder_trackers``).
|
||||
:obj:`Watcher <teos.watcher.Watcher>` (``watcher_appointments``) and by the
|
||||
:obj:`Responder <teos.responder.Responder>` (``responder_trackers``).
|
||||
|
||||
"""
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from common.logger import Logger
|
||||
|
||||
from pisa import LOG_PREFIX
|
||||
from pisa.tools import bitcoin_cli
|
||||
from pisa.utils.auth_proxy import JSONRPCException
|
||||
from teos import LOG_PREFIX
|
||||
from teos.tools import bitcoin_cli
|
||||
from teos.utils.auth_proxy import JSONRPCException
|
||||
|
||||
logger = Logger(actor="BlockProcessor", log_name_prefix=LOG_PREFIX)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class Builder:
|
||||
"""
|
||||
The :class:`Builder` class is in charge or reconstructing data loaded from the database and build the data
|
||||
structures of the :obj:`Watcher <pisa.watcher.Watcher>` and the :obj:`Responder <pisa.responder.Responder>`.
|
||||
structures of the :obj:`Watcher <teos.watcher.Watcher>` and the :obj:`Responder <teos.responder.Responder>`.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
@@ -12,13 +12,13 @@ class Builder:
|
||||
|
||||
Args:
|
||||
appointments_data (:obj:`dict`): a dictionary of dictionaries representing all the
|
||||
:obj:`Watcher <pisa.watcher.Watcher>` appointments stored in the database. The structure is as follows:
|
||||
:obj:`Watcher <teos.watcher.Watcher>` appointments stored in the database. The structure is as follows:
|
||||
|
||||
``{uuid: {locator: str, start_time: int, ...}, uuid: {locator:...}}``
|
||||
|
||||
Returns:
|
||||
:obj:`tuple`: A tuple with two dictionaries. ``appointments`` containing the appointment information in
|
||||
:obj:`Appointment <pisa.appointment.Appointment>` objects and ``locator_uuid_map`` containing a map of
|
||||
:obj:`Appointment <teos.appointment.Appointment>` objects and ``locator_uuid_map`` containing a map of
|
||||
appointment (``uuid:locator``).
|
||||
"""
|
||||
|
||||
@@ -44,14 +44,14 @@ class Builder:
|
||||
|
||||
Args:
|
||||
tracker_data (:obj:`dict`): a dictionary of dictionaries representing all the
|
||||
:mod:`Responder <pisa.responder.Responder>` trackers stored in the database.
|
||||
:mod:`Responder <teos.responder.Responder>` trackers stored in the database.
|
||||
The structure is as follows:
|
||||
|
||||
``{uuid: {locator: str, dispute_txid: str, ...}, uuid: {locator:...}}``
|
||||
|
||||
Returns:
|
||||
:obj:`tuple`: A tuple with two dictionaries. ``trackers`` containing the trackers' information in
|
||||
:obj:`TransactionTracker <pisa.responder.TransactionTracker>` objects and a ``tx_tracker_map`` containing
|
||||
:obj:`TransactionTracker <teos.responder.TransactionTracker>` objects and a ``tx_tracker_map`` containing
|
||||
the map of trackers (``penalty_txid: uuid``).
|
||||
|
||||
"""
|
||||
@@ -77,8 +77,8 @@ class Builder:
|
||||
@staticmethod
|
||||
def populate_block_queue(block_queue, missed_blocks):
|
||||
"""
|
||||
Populates a ``Queue`` of block hashes to initialize the :mod:`Watcher <pisa.watcher.Watcher>` or the
|
||||
:mod:`Responder <pisa.responder.Responder>` using backed up data.
|
||||
Populates a ``Queue`` of block hashes to initialize the :mod:`Watcher <teos.watcher.Watcher>` or the
|
||||
:mod:`Responder <teos.responder.Responder>` using backed up data.
|
||||
|
||||
Args:
|
||||
block_queue (:obj:`Queue`): a ``Queue``
|
||||
@@ -94,13 +94,13 @@ class Builder:
|
||||
@staticmethod
|
||||
def update_states(watcher, missed_blocks_watcher, missed_blocks_responder):
|
||||
"""
|
||||
Updates the states of both the :mod:`Watcher <pisa.watcher.Watcher>` and the :mod:`Responder <pisa.responder.Responder>`.
|
||||
Updates the states of both the :mod:`Watcher <teos.watcher.Watcher>` and the :mod:`Responder <teos.responder.Responder>`.
|
||||
If both have pending blocks to process they need to be updates at the same time, block by block.
|
||||
|
||||
If only one instance has to be updated, ``populate_block_queue`` should be used.
|
||||
|
||||
Args:
|
||||
watcher (:obj:`Watcher <pisa.watcher.Watcher>`): a ``Watcher`` instance (including a ``Responder``).
|
||||
watcher (:obj:`Watcher <teos.watcher.Watcher>`): a ``Watcher`` instance (including a ``Responder``).
|
||||
missed_blocks_watcher (:obj:`list`): the list of block missed by the ``Watcher``.
|
||||
missed_blocks_responder (:obj:`list`): the list of block missed by the ``Responder``.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from pisa import LOG_PREFIX
|
||||
from pisa.rpc_errors import *
|
||||
from teos import LOG_PREFIX
|
||||
from teos.rpc_errors import *
|
||||
from common.logger import Logger
|
||||
from pisa.tools import bitcoin_cli
|
||||
from pisa.utils.auth_proxy import JSONRPCException
|
||||
from pisa.errors import UNKNOWN_JSON_RPC_EXCEPTION, RPC_TX_REORGED_AFTER_BROADCAST
|
||||
from teos.tools import bitcoin_cli
|
||||
from teos.utils.auth_proxy import JSONRPCException
|
||||
from teos.errors import UNKNOWN_JSON_RPC_EXCEPTION, RPC_TX_REORGED_AFTER_BROADCAST
|
||||
|
||||
logger = Logger(actor="Carrier", log_name_prefix=LOG_PREFIX)
|
||||
|
||||
@@ -2,10 +2,10 @@ import zmq
|
||||
import binascii
|
||||
from threading import Thread, Event, Condition
|
||||
|
||||
from pisa import LOG_PREFIX
|
||||
from teos import LOG_PREFIX
|
||||
from common.logger import Logger
|
||||
from pisa.conf import FEED_PROTOCOL, FEED_ADDR, FEED_PORT, POLLING_DELTA, BLOCK_WINDOW_SIZE
|
||||
from pisa.block_processor import BlockProcessor
|
||||
from teos.conf import FEED_PROTOCOL, FEED_ADDR, FEED_PORT, POLLING_DELTA, BLOCK_WINDOW_SIZE
|
||||
from teos.block_processor import BlockProcessor
|
||||
|
||||
logger = Logger(actor="ChainMonitor", log_name_prefix=LOG_PREFIX)
|
||||
|
||||
@@ -14,7 +14,7 @@ class ChainMonitor:
|
||||
"""
|
||||
The :class:`ChainMonitor` is the class in charge of monitoring the blockchain (via ``bitcoind``) to detect new
|
||||
blocks on top of the best chain. If a new best block is spotted, the chain monitor will notify the
|
||||
:obj:`Watcher <pisa.watcher.Watcher>` and the :obj:`Responder <pisa.responder.Responder>` using ``Queues``.
|
||||
:obj:`Watcher <teos.watcher.Watcher>` and the :obj:`Responder <teos.responder.Responder>` using ``Queues``.
|
||||
|
||||
The :class:`ChainMonitor` monitors the chain using two methods: ``zmq`` and ``polling``. Blocks are only notified
|
||||
once per queue and the notification is triggered by the method that detects the block faster.
|
||||
@@ -31,9 +31,9 @@ class ChainMonitor:
|
||||
lock (:obj:`Condition`): a lock used to protect concurrent access to the queues and ``best_tip`` by the zmq and
|
||||
polling threads.
|
||||
zmqSubSocket (:obj:`socket`): a socket to connect to ``bitcoind`` via ``zmq``.
|
||||
watcher_queue (:obj:`Queue`): a queue to send new best tips to the :obj:`Watcher <pisa.watcher.Watcher>`.
|
||||
watcher_queue (:obj:`Queue`): a queue to send new best tips to the :obj:`Watcher <teos.watcher.Watcher>`.
|
||||
responder_queue (:obj:`Queue`): a queue to send new best tips to the
|
||||
:obj:`Responder <pisa.responder.Responder>`.
|
||||
:obj:`Responder <teos.responder.Responder>`.
|
||||
"""
|
||||
|
||||
def __init__(self, watcher_queue, responder_queue):
|
||||
@@ -141,7 +141,7 @@ class ChainMonitor:
|
||||
def monitor_chain(self, polling_delta=POLLING_DELTA):
|
||||
"""
|
||||
Main :class:`ChainMonitor` method. It initializes the ``best_tip`` to the current one (by querying the
|
||||
:obj:`BlockProcessor <pisa.block_processor.BlockProcessor>`) and creates two threads, one per each monitoring
|
||||
:obj:`BlockProcessor <teos.block_processor.BlockProcessor>`) and creates two threads, one per each monitoring
|
||||
approach (``zmq`` and ``polling``).
|
||||
|
||||
Args:
|
||||
@@ -1,4 +1,4 @@
|
||||
from pisa import LOG_PREFIX
|
||||
from teos import LOG_PREFIX
|
||||
|
||||
from common.logger import Logger
|
||||
|
||||
@@ -43,7 +43,7 @@ class Cleaner:
|
||||
|
||||
Args:
|
||||
uuid (:obj:`str`): the identifier of the appointment to be deleted.
|
||||
db_manager (:obj:`DBManager <pisa.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
db_manager (:obj:`DBManager <teos.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
database.
|
||||
"""
|
||||
|
||||
@@ -61,7 +61,7 @@ class Cleaner:
|
||||
Args:
|
||||
uuids (:obj:`list`): a list of identifiers to be removed from the map.
|
||||
locator (:obj:`str`): the identifier of the map to be either updated or deleted.
|
||||
db_manager (:obj:`DBManager <pisa.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
db_manager (:obj:`DBManager <teos.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
database.
|
||||
"""
|
||||
|
||||
@@ -87,15 +87,15 @@ class Cleaner:
|
||||
def delete_expired_appointments(expired_appointments, appointments, locator_uuid_map, db_manager):
|
||||
"""
|
||||
Deletes appointments which ``end_time`` has been reached (with no trigger) both from memory
|
||||
(:obj:`Watcher <pisa.watcher.Watcher>`) and disk.
|
||||
(:obj:`Watcher <teos.watcher.Watcher>`) and disk.
|
||||
|
||||
Args:
|
||||
expired_appointments (:obj:`list`): a list of appointments to be deleted.
|
||||
appointments (:obj:`dict`): a dictionary containing all the :mod:`Watcher <pisa.watcher.Watcher>`
|
||||
appointments (:obj:`dict`): a dictionary containing all the :mod:`Watcher <teos.watcher.Watcher>`
|
||||
appointments.
|
||||
locator_uuid_map (:obj:`dict`): a ``locator:uuid`` map for the :obj:`Watcher <pisa.watcher.Watcher>`
|
||||
locator_uuid_map (:obj:`dict`): a ``locator:uuid`` map for the :obj:`Watcher <teos.watcher.Watcher>`
|
||||
appointments.
|
||||
db_manager (:obj:`DBManager <pisa.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
db_manager (:obj:`DBManager <teos.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
database.
|
||||
"""
|
||||
|
||||
@@ -121,18 +121,18 @@ class Cleaner:
|
||||
@staticmethod
|
||||
def delete_completed_appointments(completed_appointments, appointments, locator_uuid_map, db_manager):
|
||||
"""
|
||||
Deletes a completed appointment from memory (:obj:`Watcher <pisa.watcher.Watcher>`) and disk.
|
||||
Deletes a completed appointment from memory (:obj:`Watcher <teos.watcher.Watcher>`) and disk.
|
||||
|
||||
Currently, an appointment is only completed if it cannot make it to the (:obj:`Responder <pisa.responder.Responder>`),
|
||||
Currently, an appointment is only completed if it cannot make it to the (:obj:`Responder <teos.responder.Responder>`),
|
||||
otherwise, it will be flagged as triggered and removed once the tracker is completed.
|
||||
|
||||
Args:
|
||||
completed_appointments (:obj:`list`): a list of appointments to be deleted.
|
||||
appointments (:obj:`dict`): a dictionary containing all the :obj:`Watcher <pisa.watcher.Watcher>`
|
||||
appointments (:obj:`dict`): a dictionary containing all the :obj:`Watcher <teos.watcher.Watcher>`
|
||||
appointments.
|
||||
locator_uuid_map (:obj:`dict`): a ``locator:uuid`` map for the :obj:`Watcher <pisa.watcher.Watcher>`
|
||||
locator_uuid_map (:obj:`dict`): a ``locator:uuid`` map for the :obj:`Watcher <teos.watcher.Watcher>`
|
||||
appointments.
|
||||
db_manager (:obj:`DBManager <pisa.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
db_manager (:obj:`DBManager <teos.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
database.
|
||||
"""
|
||||
locator_maps_to_update = {}
|
||||
@@ -160,16 +160,16 @@ class Cleaner:
|
||||
@staticmethod
|
||||
def flag_triggered_appointments(triggered_appointments, appointments, locator_uuid_map, db_manager):
|
||||
"""
|
||||
Deletes a list of triggered appointment from memory (:obj:`Watcher <pisa.watcher.Watcher>`) and flags them as
|
||||
Deletes a list of triggered appointment from memory (:obj:`Watcher <teos.watcher.Watcher>`) and flags them as
|
||||
triggered on disk.
|
||||
|
||||
Args:
|
||||
triggered_appointments (:obj:`list`): a list of appointments to be flagged as triggered on the database.
|
||||
appointments (:obj:`dict`): a dictionary containing all the :obj:`Watcher <pisa.watcher.Watcher>`
|
||||
appointments (:obj:`dict`): a dictionary containing all the :obj:`Watcher <teos.watcher.Watcher>`
|
||||
appointments.
|
||||
locator_uuid_map (:obj:`dict`): a ``locator:uuid`` map for the :obj:`Watcher <pisa.watcher.Watcher>`
|
||||
locator_uuid_map (:obj:`dict`): a ``locator:uuid`` map for the :obj:`Watcher <teos.watcher.Watcher>`
|
||||
appointments.
|
||||
db_manager (:obj:`DBManager <pisa.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
db_manager (:obj:`DBManager <teos.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
database.
|
||||
"""
|
||||
|
||||
@@ -180,17 +180,17 @@ class Cleaner:
|
||||
@staticmethod
|
||||
def delete_completed_trackers(completed_trackers, height, trackers, tx_tracker_map, db_manager):
|
||||
"""
|
||||
Deletes a completed tracker both from memory (:obj:`Responder <pisa.responder.Responder>`) and disk (from the
|
||||
Deletes a completed tracker both from memory (:obj:`Responder <teos.responder.Responder>`) and disk (from the
|
||||
Responder's and Watcher's databases).
|
||||
|
||||
Args:
|
||||
trackers (:obj:`dict`): a dictionary containing all the :obj:`Responder <pisa.responder.Responder>`
|
||||
trackers (:obj:`dict`): a dictionary containing all the :obj:`Responder <teos.responder.Responder>`
|
||||
trackers.
|
||||
tx_tracker_map (:obj:`dict`): a ``penalty_txid:uuid`` map for the :obj:`Responder
|
||||
<pisa.responder.Responder>` trackers.
|
||||
<teos.responder.Responder>` trackers.
|
||||
completed_trackers (:obj:`dict`): a dict of completed trackers to be deleted (uuid:confirmations).
|
||||
height (:obj:`int`): the block height at which the trackers were completed.
|
||||
db_manager (:obj:`DBManager <pisa.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
db_manager (:obj:`DBManager <teos.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
database.
|
||||
"""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import json
|
||||
import plyvel
|
||||
|
||||
from pisa import LOG_PREFIX
|
||||
from teos import LOG_PREFIX
|
||||
|
||||
from common.logger import Logger
|
||||
|
||||
@@ -22,12 +22,12 @@ class DBManager:
|
||||
|
||||
The database is split in six prefixes:
|
||||
|
||||
- ``WATCHER_PREFIX``, defined as ``b'w``, is used to store :obj:`Watcher <pisa.watcher.Watcher>` appointments.
|
||||
- ``RESPONDER_PREFIX``, defines as ``b'r``, is used to store :obj:`Responder <pisa.responder.Responder>` trackers.
|
||||
- ``WATCHER_LAST_BLOCK_KEY``, defined as ``b'bw``, is used to store the last block hash known by the :obj:`Watcher <pisa.watcher.Watcher>`.
|
||||
- ``RESPONDER_LAST_BLOCK_KEY``, defined as ``b'br``, is used to store the last block hash known by the :obj:`Responder <pisa.responder.Responder>`.
|
||||
- ``WATCHER_PREFIX``, defined as ``b'w``, is used to store :obj:`Watcher <teos.watcher.Watcher>` appointments.
|
||||
- ``RESPONDER_PREFIX``, defines as ``b'r``, is used to store :obj:`Responder <teos.responder.Responder>` trackers.
|
||||
- ``WATCHER_LAST_BLOCK_KEY``, defined as ``b'bw``, is used to store the last block hash known by the :obj:`Watcher <teos.watcher.Watcher>`.
|
||||
- ``RESPONDER_LAST_BLOCK_KEY``, defined as ``b'br``, is used to store the last block hash known by the :obj:`Responder <teos.responder.Responder>`.
|
||||
- ``LOCATOR_MAP_PREFIX``, defined as ``b'm``, is used to store the ``locator:uuid`` maps.
|
||||
- ``TRIGGERED_APPOINTMENTS_PREFIX``, defined as ``b'ta``, is used to stored triggered appointments (appointments that have been handed to the :obj:`Responder <pisa.responder.Responder>`.)
|
||||
- ``TRIGGERED_APPOINTMENTS_PREFIX``, defined as ``b'ta``, is used to stored triggered appointments (appointments that have been handed to the :obj:`Responder <teos.responder.Responder>`.)
|
||||
|
||||
Args:
|
||||
db_path (:obj:`str`): the path (relative or absolute) to the system folder containing the database. A fresh
|
||||
@@ -357,7 +357,7 @@ class DBManager:
|
||||
|
||||
def load_last_block_hash_watcher(self):
|
||||
"""
|
||||
Loads the last known block hash of the :obj:`Watcher <pisa.watcher.Watcher>` from the database.
|
||||
Loads the last known block hash of the :obj:`Watcher <teos.watcher.Watcher>` from the database.
|
||||
|
||||
Returns:
|
||||
:obj:`str` or :obj:`None`: A 32-byte hex-encoded string representing the last known block hash if found.
|
||||
@@ -368,7 +368,7 @@ class DBManager:
|
||||
|
||||
def load_last_block_hash_responder(self):
|
||||
"""
|
||||
Loads the last known block hash of the :obj:`Responder <pisa.responder.Responder>` from the database.
|
||||
Loads the last known block hash of the :obj:`Responder <teos.responder.Responder>` from the database.
|
||||
|
||||
Returns:
|
||||
:obj:`str` or :obj:`None`: A 32-byte hex-encoded string representing the last known block hash if found.
|
||||
@@ -379,7 +379,7 @@ class DBManager:
|
||||
|
||||
def store_last_block_hash_watcher(self, block_hash):
|
||||
"""
|
||||
Stores a block hash as the last known block of the :obj:`Watcher <pisa.watcher.Watcher>`.
|
||||
Stores a block hash as the last known block of the :obj:`Watcher <teos.watcher.Watcher>`.
|
||||
|
||||
Args:
|
||||
block_hash (:obj:`str`): the block hash to be stored (32-byte hex-encoded)
|
||||
@@ -389,7 +389,7 @@ class DBManager:
|
||||
|
||||
def store_last_block_hash_responder(self, block_hash):
|
||||
"""
|
||||
Stores a block hash as the last known block of the :obj:`Responder <pisa.responder.Responder>`.
|
||||
Stores a block hash as the last known block of the :obj:`Responder <teos.responder.Responder>`.
|
||||
|
||||
Args:
|
||||
block_hash (:obj:`str`): the block hash to be stored (32-byte hex-encoded)
|
||||
@@ -5,17 +5,17 @@ import common.cryptographer
|
||||
from common.constants import LOCATOR_LEN_HEX
|
||||
from common.cryptographer import Cryptographer, PublicKey
|
||||
|
||||
from pisa import errors, LOG_PREFIX
|
||||
from teos import errors, LOG_PREFIX
|
||||
from common.logger import Logger
|
||||
from common.appointment import Appointment
|
||||
from pisa.block_processor import BlockProcessor
|
||||
from teos.block_processor import BlockProcessor
|
||||
|
||||
logger = Logger(actor="Inspector", log_name_prefix=LOG_PREFIX)
|
||||
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix=LOG_PREFIX)
|
||||
|
||||
# FIXME: The inspector logs the wrong messages sent form the users. A possible attack surface would be to send a really
|
||||
# long field that, even if not accepted by PISA, would be stored in the logs. This is a possible DoS surface
|
||||
# since pisa would store any kind of message (no matter the length). Solution: truncate the length of the fields
|
||||
# long field that, even if not accepted by TEOS, would be stored in the logs. This is a possible DoS surface
|
||||
# since teos would store any kind of message (no matter the length). Solution: truncate the length of the fields
|
||||
# stored + blacklist if multiple wrong requests are received.
|
||||
|
||||
|
||||
@@ -41,12 +41,12 @@ class Inspector:
|
||||
public_key (:obj:`str`): the user's public key (hex encoded).
|
||||
|
||||
Returns:
|
||||
:obj:`Appointment <pisa.appointment.Appointment>` or :obj:`tuple`: An appointment initialized with the
|
||||
:obj:`Appointment <teos.appointment.Appointment>` or :obj:`tuple`: An appointment initialized with the
|
||||
provided data if it is correct.
|
||||
|
||||
Returns a tuple ``(return code, message)`` describing the error otherwise.
|
||||
|
||||
Errors are defined in :mod:`Errors <pisa.errors>`.
|
||||
Errors are defined in :mod:`Errors <teos.errors>`.
|
||||
"""
|
||||
|
||||
block_height = BlockProcessor.get_block_count()
|
||||
@@ -2,11 +2,11 @@ import json
|
||||
from queue import Queue
|
||||
from threading import Thread
|
||||
|
||||
from pisa import LOG_PREFIX
|
||||
from teos import LOG_PREFIX
|
||||
from common.logger import Logger
|
||||
from pisa.cleaner import Cleaner
|
||||
from pisa.carrier import Carrier
|
||||
from pisa.block_processor import BlockProcessor
|
||||
from teos.cleaner import Cleaner
|
||||
from teos.carrier import Carrier
|
||||
from teos.block_processor import BlockProcessor
|
||||
|
||||
CONFIRMATIONS_BEFORE_RETRY = 6
|
||||
MIN_CONFIRMATIONS = 6
|
||||
@@ -17,7 +17,7 @@ logger = Logger(actor="Responder", log_name_prefix=LOG_PREFIX)
|
||||
class TransactionTracker:
|
||||
"""
|
||||
A :class:`TransactionTracker` is used to monitor a ``penalty_tx``. Once the dispute is seen by the
|
||||
:obj:`Watcher <pisa.watcher.Watcher>` the penalty transaction is decrypted and the relevant appointment data is
|
||||
:obj:`Watcher <teos.watcher.Watcher>` the penalty transaction is decrypted and the relevant appointment data is
|
||||
passed along to the :obj:`Responder`.
|
||||
|
||||
Once the :obj:`Responder` has succeeded on broadcasting the penalty transaction it will create a
|
||||
@@ -105,11 +105,11 @@ class TransactionTracker:
|
||||
class Responder:
|
||||
"""
|
||||
The :class:`Responder` is the class in charge of ensuring that channel breaches are dealt with. It does so handling
|
||||
the decrypted ``penalty_txs`` handed by the :obj:`Watcher <pisa.watcher.Watcher>` and ensuring the they make it to
|
||||
the decrypted ``penalty_txs`` handed by the :obj:`Watcher <teos.watcher.Watcher>` and ensuring the they make it to
|
||||
the blockchain.
|
||||
|
||||
Args:
|
||||
db_manager (:obj:`DBManager <pisa.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
db_manager (:obj:`DBManager <teos.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
database.
|
||||
|
||||
Attributes:
|
||||
@@ -122,8 +122,8 @@ class Responder:
|
||||
missed_confirmations (:obj:`dict`): A dictionary that keeps count of how many confirmations each ``penalty_tx``
|
||||
has missed. Used to trigger rebroadcast if needed.
|
||||
block_queue (:obj:`Queue`): A queue used by the :obj:`Responder` to receive block hashes from ``bitcoind``. It
|
||||
is populated by the :obj:`ChainMonitor <pisa.chain_monitor.ChainMonitor>`.
|
||||
db_manager (:obj:`DBManager <pisa.db_manager.DBManager>`): A ``DBManager`` instance to interact with the
|
||||
is populated by the :obj:`ChainMonitor <teos.chain_monitor.ChainMonitor>`.
|
||||
db_manager (:obj:`DBManager <teos.db_manager.DBManager>`): A ``DBManager`` instance to interact with the
|
||||
database.
|
||||
|
||||
"""
|
||||
@@ -150,7 +150,7 @@ class Responder:
|
||||
Whether the :obj:`Responder` is on sync with ``bitcoind`` or not. Used when recovering from a crash.
|
||||
|
||||
The Watchtower can be instantiated with fresh or with backed up data. In the later, some triggers may have been
|
||||
missed. In order to go back on sync both the :obj:`Watcher <pisa.watcher.Watcher>` and the :obj:`Responder`
|
||||
missed. In order to go back on sync both the :obj:`Watcher <teos.watcher.Watcher>` and the :obj:`Responder`
|
||||
need to perform the state transitions until they catch up.
|
||||
|
||||
If a transaction is broadcast by the :obj:`Responder` and it is rejected (due to a double-spending for example)
|
||||
@@ -191,7 +191,7 @@ class Responder:
|
||||
block_hash (:obj:`str`): the block hash at which the breach was seen (used to see if we are on sync).
|
||||
|
||||
Returns:
|
||||
:obj:`Receipt <pisa.carrier.Receipt>`: A ``Receipt`` indicating whether or not the ``penalty_tx`` made it
|
||||
:obj:`Receipt <teos.carrier.Receipt>`: A ``Receipt`` indicating whether or not the ``penalty_tx`` made it
|
||||
into the blockchain.
|
||||
"""
|
||||
|
||||
@@ -403,7 +403,7 @@ class Responder:
|
||||
txs_to_rebroadcast (:obj:`list`): a list of transactions to be rebroadcast.
|
||||
|
||||
Returns:
|
||||
:obj:`list`: A list of :obj:`Receipts <pisa.carrier.Receipt>` with information about whether or not every
|
||||
:obj:`list`: A list of :obj:`Receipts <teos.carrier.Receipt>` with information about whether or not every
|
||||
transaction made it trough the network.
|
||||
"""
|
||||
|
||||
@@ -10,13 +10,13 @@ FEED_PROTOCOL = "tcp"
|
||||
FEED_ADDR = "127.0.0.1"
|
||||
FEED_PORT = 28332
|
||||
|
||||
# PISA
|
||||
DATA_FOLDER = "~/.pisa_btc/"
|
||||
# TEOS
|
||||
DATA_FOLDER = "~/.teos/"
|
||||
MAX_APPOINTMENTS = 100
|
||||
EXPIRY_DELTA = 6
|
||||
MIN_TO_SELF_DELAY = 20
|
||||
SERVER_LOG_FILE = "pisa.log"
|
||||
PISA_SECRET_KEY = "pisa_sk.der"
|
||||
SERVER_LOG_FILE = "teos.log"
|
||||
TEOS_SECRET_KEY = "teos_sk.der"
|
||||
|
||||
# CHAIN MONITOR
|
||||
POLLING_DELTA = 60
|
||||
@@ -6,15 +6,15 @@ import common.cryptographer
|
||||
from common.logger import Logger
|
||||
from common.cryptographer import Cryptographer
|
||||
|
||||
from pisa import config, LOG_PREFIX
|
||||
from pisa.api import API
|
||||
from pisa.watcher import Watcher
|
||||
from pisa.builder import Builder
|
||||
from pisa.responder import Responder
|
||||
from pisa.db_manager import DBManager
|
||||
from pisa.chain_monitor import ChainMonitor
|
||||
from pisa.block_processor import BlockProcessor
|
||||
from pisa.tools import can_connect_to_bitcoind, in_correct_network
|
||||
from teos import config, LOG_PREFIX
|
||||
from teos.api import API
|
||||
from teos.watcher import Watcher
|
||||
from teos.builder import Builder
|
||||
from teos.responder import Responder
|
||||
from teos.db_manager import DBManager
|
||||
from teos.chain_monitor import ChainMonitor
|
||||
from teos.block_processor import BlockProcessor
|
||||
from teos.tools import can_connect_to_bitcoind, in_correct_network
|
||||
|
||||
logger = Logger(actor="Daemon", log_name_prefix=LOG_PREFIX)
|
||||
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix=LOG_PREFIX)
|
||||
@@ -25,7 +25,7 @@ def handle_signals(signal_received, frame):
|
||||
db_manager.db.close()
|
||||
chain_monitor.terminate = True
|
||||
|
||||
logger.info("Shutting down PISA")
|
||||
logger.info("Shutting down TEOS")
|
||||
exit(0)
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ def main():
|
||||
signal(SIGTERM, handle_signals)
|
||||
signal(SIGQUIT, handle_signals)
|
||||
|
||||
logger.info("Starting PISA")
|
||||
logger.info("Starting TEOS")
|
||||
db_manager = DBManager(config.get("DB_PATH"))
|
||||
|
||||
if not can_connect_to_bitcoind():
|
||||
@@ -47,9 +47,9 @@ def main():
|
||||
|
||||
else:
|
||||
try:
|
||||
secret_key_der = Cryptographer.load_key_file(config.get("PISA_SECRET_KEY"))
|
||||
secret_key_der = Cryptographer.load_key_file(config.get("TEOS_SECRET_KEY"))
|
||||
if not secret_key_der:
|
||||
raise IOError("PISA private key can't be loaded")
|
||||
raise IOError("TEOS private key can't be loaded")
|
||||
|
||||
watcher = Watcher(db_manager, Responder(db_manager), secret_key_der, config)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from http.client import HTTPException
|
||||
from socket import timeout
|
||||
|
||||
import pisa.conf as conf
|
||||
from pisa.utils.auth_proxy import AuthServiceProxy, JSONRPCException
|
||||
import teos.conf as conf
|
||||
from teos.utils.auth_proxy import AuthServiceProxy, JSONRPCException
|
||||
|
||||
"""
|
||||
Tools is a module with general methods that can used by different entities in the codebase.
|
||||
@@ -15,7 +15,7 @@ def bitcoin_cli():
|
||||
An ``http`` connection with ``bitcoind`` using the ``json-rpc`` interface.
|
||||
|
||||
Returns:
|
||||
:obj:`AuthServiceProxy <pisa.utils.auth_proxy.AuthServiceProxy>`: An authenticated service proxy to ``bitcoind``
|
||||
:obj:`AuthServiceProxy <teos.utils.auth_proxy.AuthServiceProxy>`: An authenticated service proxy to ``bitcoind``
|
||||
that can be used to send ``json-rpc`` commands.
|
||||
"""
|
||||
|
||||
@@ -9,9 +9,9 @@ from common.tools import compute_locator
|
||||
|
||||
from common.logger import Logger
|
||||
|
||||
from pisa import LOG_PREFIX
|
||||
from pisa.cleaner import Cleaner
|
||||
from pisa.block_processor import BlockProcessor
|
||||
from teos import LOG_PREFIX
|
||||
from teos.cleaner import Cleaner
|
||||
from teos.block_processor import BlockProcessor
|
||||
|
||||
logger = Logger(actor="Watcher", log_name_prefix=LOG_PREFIX)
|
||||
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix=LOG_PREFIX)
|
||||
@@ -25,36 +25,36 @@ class Watcher:
|
||||
The :class:`Watcher` keeps track of the accepted appointments in ``appointments`` and, for new received block,
|
||||
checks if any breach has happened by comparing the txids with the appointment locators. If a breach is seen, the
|
||||
:obj:`EncryptedBlob <common.encrypted_blob.EncryptedBlob>` of the corresponding appointment is decrypted and the data
|
||||
is passed to the :obj:`Responder <pisa.responder.Responder>`.
|
||||
is passed to the :obj:`Responder <teos.responder.Responder>`.
|
||||
|
||||
If an appointment reaches its end with no breach, the data is simply deleted.
|
||||
|
||||
The :class:`Watcher` receives information about new received blocks via the ``block_queue`` that is populated by the
|
||||
:obj:`ChainMonitor <pisa.chain_monitor.ChainMonitor>`.
|
||||
:obj:`ChainMonitor <teos.chain_monitor.ChainMonitor>`.
|
||||
|
||||
Args:
|
||||
db_manager (:obj:`DBManager <pisa.db_manager>`): a ``DBManager`` instance to interact with the database.
|
||||
db_manager (:obj:`DBManager <teos.db_manager>`): a ``DBManager`` instance to interact with the database.
|
||||
sk_der (:obj:`bytes`): a DER encoded private key used to sign appointment receipts (signaling acceptance).
|
||||
config (:obj:`dict`): a dictionary containing all the configuration parameters. Used locally to retrieve
|
||||
``MAX_APPOINTMENTS`` and ``EXPIRY_DELTA``.
|
||||
responder (:obj:`Responder <pisa.responder.Responder>`): a ``Responder`` instance.
|
||||
responder (:obj:`Responder <teos.responder.Responder>`): a ``Responder`` instance.
|
||||
|
||||
|
||||
Attributes:
|
||||
appointments (:obj:`dict`): a dictionary containing a simplification of the appointments (:obj:`Appointment
|
||||
<pisa.appointment.Appointment>` instances) accepted by the tower (``locator`` and ``end_time``).
|
||||
<teos.appointment.Appointment>` instances) accepted by the tower (``locator`` and ``end_time``).
|
||||
It's populated trough ``add_appointment``.
|
||||
locator_uuid_map (:obj:`dict`): a ``locator:uuid`` map used to allow the :obj:`Watcher` to deal with several
|
||||
appointments with the same ``locator``.
|
||||
block_queue (:obj:`Queue`): A queue used by the :obj:`Watcher` to receive block hashes from ``bitcoind``. It is
|
||||
populated by the :obj:`ChainMonitor <pisa.chain_monitor.ChainMonitor>`.
|
||||
populated by the :obj:`ChainMonitor <teos.chain_monitor.ChainMonitor>`.
|
||||
config (:obj:`dict`): a dictionary containing all the configuration parameters. Used locally to retrieve
|
||||
``MAX_APPOINTMENTS`` and ``EXPIRY_DELTA``.
|
||||
db_manager (:obj:`DBManager <pisa.db_manager>`): A db manager instance to interact with the database.
|
||||
db_manager (:obj:`DBManager <teos.db_manager>`): A db manager instance to interact with the database.
|
||||
signing_key (:mod:`PrivateKey`): a private key used to sign accepted appointments.
|
||||
|
||||
Raises:
|
||||
ValueError: if `pisa_sk_file` is not found.
|
||||
ValueError: if `teos_sk_file` is not found.
|
||||
|
||||
"""
|
||||
|
||||
@@ -82,7 +82,7 @@ class Watcher:
|
||||
|
||||
Once a breach is seen on the blockchain, the :obj:`Watcher` will decrypt the corresponding
|
||||
:obj:`EncryptedBlob <common.encrypted_blob.EncryptedBlob>` and pass the information to the
|
||||
:obj:`Responder <pisa.responder.Responder>`.
|
||||
:obj:`Responder <teos.responder.Responder>`.
|
||||
|
||||
The tower may store multiple appointments with the same ``locator`` to avoid DoS attacks based on data
|
||||
rewriting. `locators`` should be derived from the ``dispute_txid``, but that task is performed by the user, and
|
||||
@@ -90,7 +90,7 @@ class Watcher:
|
||||
identified by ``uuid`` and stored in ``appointments`` and ``locator_uuid_map``.
|
||||
|
||||
Args:
|
||||
appointment (:obj:`Appointment <pisa.appointment.Appointment>`): the appointment to be added to the
|
||||
appointment (:obj:`Appointment <teos.appointment.Appointment>`): the appointment to be added to the
|
||||
:obj:`Watcher`.
|
||||
|
||||
Returns:
|
||||
@@ -134,7 +134,7 @@ class Watcher:
|
||||
Monitors the blockchain whilst there are pending appointments.
|
||||
|
||||
This is the main method of the :obj:`Watcher` and the one in charge to pass appointments to the
|
||||
:obj:`Responder <pisa.responder.Responder>` upon detecting a breach.
|
||||
:obj:`Responder <teos.responder.Responder>` upon detecting a breach.
|
||||
"""
|
||||
|
||||
while True:
|
||||
@@ -233,7 +233,7 @@ class Watcher:
|
||||
|
||||
The :obj:`Watcher` cannot if a given :obj:`EncryptedBlob <common.encrypted_blob.EncryptedBlob>` contains a valid
|
||||
transaction until a breach if seen. Blobs that contain arbitrary data are dropped and not sent to the
|
||||
:obj:`Responder <pisa.responder.Responder>`.
|
||||
:obj:`Responder <teos.responder.Responder>`.
|
||||
|
||||
Args:
|
||||
breaches (:obj:`dict`): a dictionary containing channel breaches (``locator:txid``).
|
||||
@@ -11,10 +11,10 @@ from common.appointment import Appointment
|
||||
from common.cryptographer import Cryptographer
|
||||
|
||||
from common.blob import Blob
|
||||
import apps.cli.wt_cli as wt_cli
|
||||
import apps.cli.teos_cli as teos_cli
|
||||
from test.apps.cli.unit.conftest import get_random_value_hex
|
||||
|
||||
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix=wt_cli.LOG_PREFIX)
|
||||
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix=teos_cli.LOG_PREFIX)
|
||||
|
||||
# dummy keys for the tests
|
||||
dummy_sk = PrivateKey()
|
||||
@@ -23,11 +23,11 @@ another_sk = PrivateKey()
|
||||
|
||||
|
||||
# Replace the key in the module with a key we control for the tests
|
||||
wt_cli.pisa_public_key = dummy_pk
|
||||
teos_cli.teos_public_key = dummy_pk
|
||||
# Replace endpoint with dummy one
|
||||
wt_cli.pisa_api_server = "https://dummy.com"
|
||||
wt_cli.pisa_api_port = 12345
|
||||
pisa_endpoint = "{}:{}/".format(wt_cli.pisa_api_server, wt_cli.pisa_api_port)
|
||||
teos_cli.teos_api_server = "https://dummy.com"
|
||||
teos_cli.teos_api_port = 12345
|
||||
teos_endpoint = "{}:{}/".format(teos_cli.teos_api_server, teos_cli.teos_api_port)
|
||||
|
||||
dummy_appointment_request = {
|
||||
"tx": get_random_value_hex(192),
|
||||
@@ -74,17 +74,17 @@ def get_bad_signature(*args):
|
||||
# f.write(dummy_pk_der)
|
||||
#
|
||||
# # Now we can test the function passing the using this files (we'll use the same pk for both)
|
||||
# r = wt_cli.load_keys(public_key_file_path, private_key_file_path, public_key_file_path)
|
||||
# r = teos_cli.load_keys(public_key_file_path, private_key_file_path, public_key_file_path)
|
||||
# assert isinstance(r, tuple)
|
||||
# assert len(r) == 3
|
||||
#
|
||||
# # If any param does not match we should get None as result
|
||||
# assert wt_cli.load_keys(None, private_key_file_path, public_key_file_path) is None
|
||||
# assert wt_cli.load_keys(public_key_file_path, None, public_key_file_path) is None
|
||||
# assert wt_cli.load_keys(public_key_file_path, private_key_file_path, None) is None
|
||||
# assert teos_cli.load_keys(None, private_key_file_path, public_key_file_path) is None
|
||||
# assert teos_cli.load_keys(public_key_file_path, None, public_key_file_path) is None
|
||||
# assert teos_cli.load_keys(public_key_file_path, private_key_file_path, None) is None
|
||||
#
|
||||
# # The same should happen if we pass a public key where a private should be, for instance
|
||||
# assert wt_cli.load_keys(private_key_file_path, public_key_file_path, private_key_file_path) is None
|
||||
# assert teos_cli.load_keys(private_key_file_path, public_key_file_path, private_key_file_path) is None
|
||||
#
|
||||
# os.remove(private_key_file_path)
|
||||
# os.remove(public_key_file_path)
|
||||
@@ -95,14 +95,14 @@ def get_bad_signature(*args):
|
||||
def test_add_appointment(monkeypatch):
|
||||
# Simulate a request to add_appointment for dummy_appointment, make sure that the right endpoint is requested
|
||||
# and the return value is True
|
||||
monkeypatch.setattr(wt_cli, "load_keys", load_dummy_keys)
|
||||
monkeypatch.setattr(teos_cli, "load_keys", load_dummy_keys)
|
||||
|
||||
response = {"locator": dummy_appointment.locator, "signature": get_dummy_signature()}
|
||||
responses.add(responses.POST, pisa_endpoint, json=response, status=200)
|
||||
result = wt_cli.add_appointment([json.dumps(dummy_appointment_request)])
|
||||
responses.add(responses.POST, teos_endpoint, json=response, status=200)
|
||||
result = teos_cli.add_appointment([json.dumps(dummy_appointment_request)])
|
||||
|
||||
assert len(responses.calls) == 1
|
||||
assert responses.calls[0].request.url == pisa_endpoint
|
||||
assert responses.calls[0].request.url == teos_endpoint
|
||||
assert result
|
||||
|
||||
|
||||
@@ -112,39 +112,39 @@ def test_add_appointment_with_invalid_signature(monkeypatch):
|
||||
# make sure that the right endpoint is requested, but the return value is False
|
||||
|
||||
# Make sure the test uses the bad dummy signature
|
||||
monkeypatch.setattr(wt_cli, "load_keys", load_dummy_keys)
|
||||
monkeypatch.setattr(teos_cli, "load_keys", load_dummy_keys)
|
||||
|
||||
response = {
|
||||
"locator": dummy_appointment.to_dict()["locator"],
|
||||
"signature": get_bad_signature(), # Sign with a bad key
|
||||
}
|
||||
|
||||
responses.add(responses.POST, pisa_endpoint, json=response, status=200)
|
||||
result = wt_cli.add_appointment([json.dumps(dummy_appointment_request)])
|
||||
responses.add(responses.POST, teos_endpoint, json=response, status=200)
|
||||
result = teos_cli.add_appointment([json.dumps(dummy_appointment_request)])
|
||||
|
||||
assert result is False
|
||||
|
||||
|
||||
def test_parse_add_appointment_args():
|
||||
# If no args are passed, function should fail.
|
||||
appt_data = wt_cli.parse_add_appointment_args(None)
|
||||
appt_data = teos_cli.parse_add_appointment_args(None)
|
||||
assert not appt_data
|
||||
|
||||
# If file doesn't exist, function should fail.
|
||||
appt_data = wt_cli.parse_add_appointment_args(["-f", "nonexistent_file"])
|
||||
appt_data = teos_cli.parse_add_appointment_args(["-f", "nonexistent_file"])
|
||||
assert not appt_data
|
||||
|
||||
# If file exists and has data in it, function should work.
|
||||
with open("appt_test_file", "w") as f:
|
||||
json.dump(dummy_appointment_request, f)
|
||||
|
||||
appt_data = wt_cli.parse_add_appointment_args(["-f", "appt_test_file"])
|
||||
appt_data = teos_cli.parse_add_appointment_args(["-f", "appt_test_file"])
|
||||
assert appt_data
|
||||
|
||||
os.remove("appt_test_file")
|
||||
|
||||
# If appointment json is passed in, function should work.
|
||||
appt_data = wt_cli.parse_add_appointment_args([json.dumps(dummy_appointment_request)])
|
||||
appt_data = teos_cli.parse_add_appointment_args([json.dumps(dummy_appointment_request)])
|
||||
assert appt_data
|
||||
|
||||
|
||||
@@ -155,11 +155,11 @@ def test_post_appointment():
|
||||
"signature": Cryptographer.sign(dummy_appointment.serialize(), dummy_pk),
|
||||
}
|
||||
|
||||
responses.add(responses.POST, pisa_endpoint, json=response, status=200)
|
||||
response = wt_cli.post_appointment(json.dumps(dummy_appointment_request))
|
||||
responses.add(responses.POST, teos_endpoint, json=response, status=200)
|
||||
response = teos_cli.post_appointment(json.dumps(dummy_appointment_request))
|
||||
|
||||
assert len(responses.calls) == 1
|
||||
assert responses.calls[0].request.url == pisa_endpoint
|
||||
assert responses.calls[0].request.url == teos_endpoint
|
||||
assert response
|
||||
|
||||
|
||||
@@ -172,28 +172,28 @@ def test_process_post_appointment_response():
|
||||
}
|
||||
|
||||
# A 200 OK with a correct json response should return the json of the response
|
||||
responses.add(responses.POST, pisa_endpoint, json=response, status=200)
|
||||
r = wt_cli.post_appointment(json.dumps(dummy_appointment_request))
|
||||
assert wt_cli.process_post_appointment_response(r) == r.json()
|
||||
responses.add(responses.POST, teos_endpoint, json=response, status=200)
|
||||
r = teos_cli.post_appointment(json.dumps(dummy_appointment_request))
|
||||
assert teos_cli.process_post_appointment_response(r) == r.json()
|
||||
|
||||
# If we modify the response code tor a rejection (lets say 404) we should get None
|
||||
responses.replace(responses.POST, pisa_endpoint, json=response, status=404)
|
||||
r = wt_cli.post_appointment(json.dumps(dummy_appointment_request))
|
||||
assert wt_cli.process_post_appointment_response(r) is None
|
||||
responses.replace(responses.POST, teos_endpoint, json=response, status=404)
|
||||
r = teos_cli.post_appointment(json.dumps(dummy_appointment_request))
|
||||
assert teos_cli.process_post_appointment_response(r) is None
|
||||
|
||||
# The same should happen if the response is not in json
|
||||
responses.replace(responses.POST, pisa_endpoint, status=404)
|
||||
r = wt_cli.post_appointment(json.dumps(dummy_appointment_request))
|
||||
assert wt_cli.process_post_appointment_response(r) is None
|
||||
responses.replace(responses.POST, teos_endpoint, status=404)
|
||||
r = teos_cli.post_appointment(json.dumps(dummy_appointment_request))
|
||||
assert teos_cli.process_post_appointment_response(r) is None
|
||||
|
||||
|
||||
def test_save_appointment_receipt(monkeypatch):
|
||||
appointments_folder = "test_appointments_receipts"
|
||||
wt_cli.config["APPOINTMENTS_FOLDER_NAME"] = appointments_folder
|
||||
teos_cli.config["APPOINTMENTS_FOLDER_NAME"] = appointments_folder
|
||||
|
||||
# The functions creates a new directory if it does not exist
|
||||
assert not os.path.exists(appointments_folder)
|
||||
wt_cli.save_appointment_receipt(dummy_appointment.to_dict(), get_dummy_signature())
|
||||
teos_cli.save_appointment_receipt(dummy_appointment.to_dict(), get_dummy_signature())
|
||||
assert os.path.exists(appointments_folder)
|
||||
|
||||
# Check that the receipt has been saved by checking the file names
|
||||
@@ -209,9 +209,9 @@ def test_get_appointment():
|
||||
dummy_appointment_full["status"] = "being_watched"
|
||||
response = dummy_appointment_full
|
||||
|
||||
request_url = "{}get_appointment?locator={}".format(pisa_endpoint, response.get("locator"))
|
||||
request_url = "{}get_appointment?locator={}".format(teos_endpoint, response.get("locator"))
|
||||
responses.add(responses.GET, request_url, json=response, status=200)
|
||||
result = wt_cli.get_appointment(response.get("locator"))
|
||||
result = teos_cli.get_appointment(response.get("locator"))
|
||||
|
||||
assert len(responses.calls) == 1
|
||||
assert responses.calls[0].request.url == request_url
|
||||
@@ -223,7 +223,7 @@ def test_get_appointment_err():
|
||||
locator = get_random_value_hex(16)
|
||||
|
||||
# Test that get_appointment handles a connection error appropriately.
|
||||
request_url = "{}get_appointment?locator=".format(pisa_endpoint, locator)
|
||||
request_url = "{}get_appointment?locator=".format(teos_endpoint, locator)
|
||||
responses.add(responses.GET, request_url, body=ConnectionError())
|
||||
|
||||
assert not wt_cli.get_appointment(locator)
|
||||
assert not teos_cli.get_appointment(locator)
|
||||
|
||||
@@ -3,8 +3,8 @@ import pytest
|
||||
import logging
|
||||
from copy import deepcopy
|
||||
|
||||
# FIXME: Import from pisa. Common should not import anything from cli nor pisa.
|
||||
from pisa import conf_fields
|
||||
# FIXME: Import from teos. Common should not import anything from cli nor teos.
|
||||
from teos import conf_fields
|
||||
|
||||
from common.constants import LOCATOR_LEN_BYTES
|
||||
from common.tools import (
|
||||
|
||||
@@ -3,9 +3,9 @@ import random
|
||||
from multiprocessing import Process
|
||||
from decimal import Decimal, getcontext
|
||||
|
||||
import pisa.conf as conf
|
||||
from pisa.pisad import main
|
||||
from pisa.utils.auth_proxy import AuthServiceProxy
|
||||
import teos.conf as conf
|
||||
from teos.teosd import main
|
||||
from teos.utils.auth_proxy import AuthServiceProxy
|
||||
|
||||
getcontext().prec = 10
|
||||
END_TIME_DELTA = 10
|
||||
@@ -50,11 +50,11 @@ def create_txs(bitcoin_cli):
|
||||
return signed_commitment_tx, signed_penalty_tx
|
||||
|
||||
|
||||
def run_pisad():
|
||||
pisad_process = Process(target=main, daemon=True)
|
||||
pisad_process.start()
|
||||
def run_teosd():
|
||||
teosd_process = Process(target=main, daemon=True)
|
||||
teosd_process.start()
|
||||
|
||||
return pisad_process
|
||||
return teosd_process
|
||||
|
||||
|
||||
def get_random_value_hex(nbytes):
|
||||
@@ -10,13 +10,13 @@ FEED_PROTOCOL = "tcp"
|
||||
FEED_ADDR = "127.0.0.1"
|
||||
FEED_PORT = 28335
|
||||
|
||||
# PISA
|
||||
DATA_FOLDER = "~/.pisa_btc/"
|
||||
# TEOS
|
||||
DATA_FOLDER = "~/.teos/"
|
||||
MAX_APPOINTMENTS = 100
|
||||
EXPIRY_DELTA = 6
|
||||
MIN_TO_SELF_DELAY = 20
|
||||
SERVER_LOG_FILE = "pisa.log"
|
||||
PISA_SECRET_KEY = "pisa_sk.der"
|
||||
SERVER_LOG_FILE = "teos.log"
|
||||
TEOS_SECRET_KEY = "teos_sk.der"
|
||||
|
||||
# CHAIN MONITOR
|
||||
POLLING_DELTA = 60
|
||||
@@ -2,9 +2,9 @@ import json
|
||||
from time import sleep
|
||||
from riemann.tx import Tx
|
||||
|
||||
from pisa import config
|
||||
from pisa import HOST, PORT
|
||||
from apps.cli import wt_cli
|
||||
from teos import config
|
||||
from teos import HOST, PORT
|
||||
from apps.cli import teos_cli
|
||||
from common.blob import Blob
|
||||
|
||||
import common.cryptographer
|
||||
@@ -12,31 +12,31 @@ from common.logger import Logger
|
||||
from common.tools import compute_locator
|
||||
from common.appointment import Appointment
|
||||
from common.cryptographer import Cryptographer
|
||||
from pisa.utils.auth_proxy import JSONRPCException
|
||||
from test.pisa.e2e.conftest import (
|
||||
from teos.utils.auth_proxy import JSONRPCException
|
||||
from test.teos.e2e.conftest import (
|
||||
END_TIME_DELTA,
|
||||
build_appointment_data,
|
||||
get_random_value_hex,
|
||||
create_penalty_tx,
|
||||
run_pisad,
|
||||
run_teosd,
|
||||
)
|
||||
|
||||
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix="")
|
||||
|
||||
# We'll use wt_cli to add appointments. The expected input format is a list of arguments with a json-encoded
|
||||
# We'll use teos_cli to add appointments. The expected input format is a list of arguments with a json-encoded
|
||||
# appointment
|
||||
wt_cli.pisa_api_server = "http://{}".format(HOST)
|
||||
wt_cli.pisa_api_port = PORT
|
||||
teos_cli.teos_api_server = "http://{}".format(HOST)
|
||||
teos_cli.teos_api_port = PORT
|
||||
|
||||
# Run pisad
|
||||
pisad_process = run_pisad()
|
||||
# Run teosd
|
||||
teosd_process = run_teosd()
|
||||
|
||||
|
||||
def get_pisa_pk():
|
||||
pisa_sk = Cryptographer.load_private_key_der(Cryptographer.load_key_file(config.get("PISA_SECRET_KEY")))
|
||||
pisa_pk = pisa_sk.public_key
|
||||
def get_teos_pk():
|
||||
teos_sk = Cryptographer.load_private_key_der(Cryptographer.load_key_file(config.get("TEOS_SECRET_KEY")))
|
||||
teos_pk = teos_sk.public_key
|
||||
|
||||
return pisa_pk
|
||||
return teos_pk
|
||||
|
||||
|
||||
def broadcast_transaction_and_mine_block(bitcoin_cli, commitment_tx, addr):
|
||||
@@ -48,18 +48,18 @@ def broadcast_transaction_and_mine_block(bitcoin_cli, commitment_tx, addr):
|
||||
def get_appointment_info(locator):
|
||||
# Check that the justice has been triggered (the appointment has moved from Watcher to Responder)
|
||||
sleep(1) # Let's add a bit of delay so the state can be updated
|
||||
return wt_cli.get_appointment(locator)
|
||||
return teos_cli.get_appointment(locator)
|
||||
|
||||
|
||||
def test_appointment_life_cycle(monkeypatch, bitcoin_cli, create_txs):
|
||||
monkeypatch.setattr(wt_cli, "load_keys", get_pisa_pk)
|
||||
monkeypatch.setattr(teos_cli, "load_keys", get_teos_pk)
|
||||
|
||||
commitment_tx, penalty_tx = create_txs
|
||||
commitment_tx_id = bitcoin_cli.decoderawtransaction(commitment_tx).get("txid")
|
||||
appointment_data = build_appointment_data(bitcoin_cli, commitment_tx_id, penalty_tx)
|
||||
locator = compute_locator(commitment_tx_id)
|
||||
|
||||
assert wt_cli.add_appointment([json.dumps(appointment_data)]) is True
|
||||
assert teos_cli.add_appointment([json.dumps(appointment_data)]) is True
|
||||
|
||||
appointment_info = get_appointment_info(locator)
|
||||
assert appointment_info is not None
|
||||
@@ -97,7 +97,7 @@ def test_appointment_life_cycle(monkeypatch, bitcoin_cli, create_txs):
|
||||
|
||||
|
||||
def test_appointment_malformed_penalty(monkeypatch, bitcoin_cli, create_txs):
|
||||
monkeypatch.setattr(wt_cli, "load_keys", get_pisa_pk)
|
||||
monkeypatch.setattr(teos_cli, "load_keys", get_teos_pk)
|
||||
|
||||
# Lets start by creating two valid transaction
|
||||
commitment_tx, penalty_tx = create_txs
|
||||
@@ -111,7 +111,7 @@ def test_appointment_malformed_penalty(monkeypatch, bitcoin_cli, create_txs):
|
||||
appointment_data = build_appointment_data(bitcoin_cli, commitment_tx_id, mod_penalty_tx.hex())
|
||||
locator = compute_locator(commitment_tx_id)
|
||||
|
||||
assert wt_cli.add_appointment([json.dumps(appointment_data)]) is True
|
||||
assert teos_cli.add_appointment([json.dumps(appointment_data)]) is True
|
||||
|
||||
# Broadcast the commitment transaction and mine a block
|
||||
new_addr = bitcoin_cli.getnewaddress()
|
||||
@@ -134,14 +134,14 @@ def test_appointment_wrong_key(bitcoin_cli, create_txs):
|
||||
# The appointment data is built using a random 32-byte value.
|
||||
appointment_data = build_appointment_data(bitcoin_cli, get_random_value_hex(32), penalty_tx)
|
||||
|
||||
# We can't use wt_cli.add_appointment here since it computes the locator internally, so let's do it manually.
|
||||
# We can't use teos_cli.add_appointment here since it computes the locator internally, so let's do it manually.
|
||||
# We will encrypt the blob using the random value and derive the locator from the commitment tx.
|
||||
appointment_data["locator"] = compute_locator(bitcoin_cli.decoderawtransaction(commitment_tx).get("txid"))
|
||||
appointment_data["encrypted_blob"] = Cryptographer.encrypt(Blob(penalty_tx), get_random_value_hex(32))
|
||||
appointment = Appointment.from_dict(appointment_data)
|
||||
|
||||
# pisa_pk, cli_sk, cli_pk_der = wt_cli.load_keys(
|
||||
# cli_conf.get("PISA_PUBLIC_KEY"), cli_conf.get("CLI_PRIVATE_KEY"), cli_conf.get("CLI_PUBLIC_KEY")
|
||||
# teos_pk, cli_sk, cli_pk_der = teos_cli.load_keys(
|
||||
# cli_conf.get("TEOS_PUBLIC_KEY"), cli_conf.get("CLI_PRIVATE_KEY"), cli_conf.get("CLI_PUBLIC_KEY")
|
||||
# )
|
||||
# hex_pk_der = binascii.hexlify(cli_pk_der)
|
||||
#
|
||||
@@ -149,18 +149,18 @@ def test_appointment_wrong_key(bitcoin_cli, create_txs):
|
||||
# data = {"appointment": appointment.to_dict(), "signature": signature, "public_key": hex_pk_der.decode("utf-8")}
|
||||
# FIXME: Since the pk is now hardcoded for the alpha in the cli we cannot use load_keys here. We need to derive
|
||||
# the pk from the sk on disk.
|
||||
pisa_pk = get_pisa_pk()
|
||||
teos_pk = get_teos_pk()
|
||||
data = {"appointment": appointment.to_dict()}
|
||||
|
||||
# Send appointment to the server.
|
||||
response = wt_cli.post_appointment(data)
|
||||
response_json = wt_cli.process_post_appointment_response(response)
|
||||
response = teos_cli.post_appointment(data)
|
||||
response_json = teos_cli.process_post_appointment_response(response)
|
||||
|
||||
# Check that the server has accepted the appointment
|
||||
signature = response_json.get("signature")
|
||||
assert signature is not None
|
||||
rpk = Cryptographer.recover_pk(appointment.serialize(), signature)
|
||||
assert Cryptographer.verify_rpk(pisa_pk, rpk) is True
|
||||
assert Cryptographer.verify_rpk(teos_pk, rpk) is True
|
||||
assert response_json.get("locator") == appointment.locator
|
||||
|
||||
# Trigger the appointment
|
||||
@@ -177,7 +177,7 @@ def test_appointment_wrong_key(bitcoin_cli, create_txs):
|
||||
|
||||
|
||||
def test_two_identical_appointments(monkeypatch, bitcoin_cli, create_txs):
|
||||
monkeypatch.setattr(wt_cli, "load_keys", get_pisa_pk)
|
||||
monkeypatch.setattr(teos_cli, "load_keys", get_teos_pk)
|
||||
|
||||
# Tests sending two identical appointments to the tower.
|
||||
# At the moment there are no checks for identical appointments, so both will be accepted, decrypted and kept until
|
||||
@@ -191,8 +191,8 @@ def test_two_identical_appointments(monkeypatch, bitcoin_cli, create_txs):
|
||||
locator = compute_locator(commitment_tx_id)
|
||||
|
||||
# Send the appointment twice
|
||||
assert wt_cli.add_appointment([json.dumps(appointment_data)]) is True
|
||||
assert wt_cli.add_appointment([json.dumps(appointment_data)]) is True
|
||||
assert teos_cli.add_appointment([json.dumps(appointment_data)]) is True
|
||||
assert teos_cli.add_appointment([json.dumps(appointment_data)]) is True
|
||||
|
||||
# Broadcast the commitment transaction and mine a block
|
||||
new_addr = bitcoin_cli.getnewaddress()
|
||||
@@ -212,7 +212,7 @@ def test_two_identical_appointments(monkeypatch, bitcoin_cli, create_txs):
|
||||
|
||||
|
||||
def test_two_appointment_same_locator_different_penalty(monkeypatch, bitcoin_cli, create_txs):
|
||||
monkeypatch.setattr(wt_cli, "load_keys", get_pisa_pk)
|
||||
monkeypatch.setattr(teos_cli, "load_keys", get_teos_pk)
|
||||
|
||||
# This tests sending an appointment with two valid transaction with the same locator.
|
||||
commitment_tx, penalty_tx1 = create_txs
|
||||
@@ -227,8 +227,8 @@ def test_two_appointment_same_locator_different_penalty(monkeypatch, bitcoin_cli
|
||||
appointment2_data = build_appointment_data(bitcoin_cli, commitment_tx_id, penalty_tx2)
|
||||
locator = compute_locator(commitment_tx_id)
|
||||
|
||||
assert wt_cli.add_appointment([json.dumps(appointment1_data)]) is True
|
||||
assert wt_cli.add_appointment([json.dumps(appointment2_data)]) is True
|
||||
assert teos_cli.add_appointment([json.dumps(appointment1_data)]) is True
|
||||
assert teos_cli.add_appointment([json.dumps(appointment2_data)]) is True
|
||||
|
||||
# Broadcast the commitment transaction and mine a block
|
||||
new_addr = bitcoin_cli.getnewaddress()
|
||||
@@ -245,25 +245,25 @@ def test_two_appointment_same_locator_different_penalty(monkeypatch, bitcoin_cli
|
||||
assert appointment_info[0].get("penalty_rawtx") == penalty_tx1
|
||||
|
||||
|
||||
def test_appointment_shutdown_pisa_trigger_back_online(monkeypatch, create_txs, bitcoin_cli):
|
||||
global pisad_process
|
||||
def test_appointment_shutdown_teos_trigger_back_online(monkeypatch, create_txs, bitcoin_cli):
|
||||
global teosd_process
|
||||
|
||||
monkeypatch.setattr(wt_cli, "load_keys", get_pisa_pk)
|
||||
monkeypatch.setattr(teos_cli, "load_keys", get_teos_pk)
|
||||
|
||||
pisa_pid = pisad_process.pid
|
||||
teos_pid = teosd_process.pid
|
||||
|
||||
commitment_tx, penalty_tx = create_txs
|
||||
commitment_tx_id = bitcoin_cli.decoderawtransaction(commitment_tx).get("txid")
|
||||
appointment_data = build_appointment_data(bitcoin_cli, commitment_tx_id, penalty_tx)
|
||||
locator = compute_locator(commitment_tx_id)
|
||||
|
||||
assert wt_cli.add_appointment([json.dumps(appointment_data)]) is True
|
||||
assert teos_cli.add_appointment([json.dumps(appointment_data)]) is True
|
||||
|
||||
# Restart pisa
|
||||
pisad_process.terminate()
|
||||
pisad_process = run_pisad()
|
||||
# Restart teos
|
||||
teosd_process.terminate()
|
||||
teosd_process = run_teosd()
|
||||
|
||||
assert pisa_pid != pisad_process.pid
|
||||
assert teos_pid != teosd_process.pid
|
||||
|
||||
# Check that the appointment is still in the Watcher
|
||||
appointment_info = get_appointment_info(locator)
|
||||
@@ -285,19 +285,19 @@ def test_appointment_shutdown_pisa_trigger_back_online(monkeypatch, create_txs,
|
||||
assert appointment_info[0].get("status") == "dispute_responded"
|
||||
|
||||
|
||||
def test_appointment_shutdown_pisa_trigger_while_offline(monkeypatch, create_txs, bitcoin_cli):
|
||||
global pisad_process
|
||||
def test_appointment_shutdown_teos_trigger_while_offline(monkeypatch, create_txs, bitcoin_cli):
|
||||
global teosd_process
|
||||
|
||||
monkeypatch.setattr(wt_cli, "load_keys", get_pisa_pk)
|
||||
monkeypatch.setattr(teos_cli, "load_keys", get_teos_pk)
|
||||
|
||||
pisa_pid = pisad_process.pid
|
||||
teos_pid = teosd_process.pid
|
||||
|
||||
commitment_tx, penalty_tx = create_txs
|
||||
commitment_tx_id = bitcoin_cli.decoderawtransaction(commitment_tx).get("txid")
|
||||
appointment_data = build_appointment_data(bitcoin_cli, commitment_tx_id, penalty_tx)
|
||||
locator = compute_locator(commitment_tx_id)
|
||||
|
||||
assert wt_cli.add_appointment([json.dumps(appointment_data)]) is True
|
||||
assert teos_cli.add_appointment([json.dumps(appointment_data)]) is True
|
||||
|
||||
# Check that the appointment is still in the Watcher
|
||||
appointment_info = get_appointment_info(locator)
|
||||
@@ -306,13 +306,13 @@ def test_appointment_shutdown_pisa_trigger_while_offline(monkeypatch, create_txs
|
||||
assert appointment_info[0].get("status") == "being_watched"
|
||||
|
||||
# Shutdown and trigger
|
||||
pisad_process.terminate()
|
||||
teosd_process.terminate()
|
||||
new_addr = bitcoin_cli.getnewaddress()
|
||||
broadcast_transaction_and_mine_block(bitcoin_cli, commitment_tx, new_addr)
|
||||
|
||||
# Restart
|
||||
pisad_process = run_pisad()
|
||||
assert pisa_pid != pisad_process.pid
|
||||
teosd_process = run_teosd()
|
||||
assert teos_pid != teosd_process.pid
|
||||
|
||||
# The appointment should have been moved to the Responder
|
||||
sleep(1)
|
||||
@@ -322,4 +322,4 @@ def test_appointment_shutdown_pisa_trigger_while_offline(monkeypatch, create_txs
|
||||
assert len(appointment_info) == 1
|
||||
assert appointment_info[0].get("status") == "dispute_responded"
|
||||
|
||||
pisad_process.terminate()
|
||||
teosd_process.terminate()
|
||||
@@ -9,9 +9,9 @@ from threading import Thread
|
||||
from coincurve import PrivateKey
|
||||
|
||||
from common.blob import Blob
|
||||
from pisa.responder import TransactionTracker
|
||||
from pisa.tools import bitcoin_cli
|
||||
from pisa.db_manager import DBManager
|
||||
from teos.responder import TransactionTracker
|
||||
from teos.tools import bitcoin_cli
|
||||
from teos.db_manager import DBManager
|
||||
from common.appointment import Appointment
|
||||
from common.tools import compute_locator
|
||||
|
||||
@@ -19,7 +19,7 @@ from bitcoind_mock.transaction import create_dummy_transaction
|
||||
from bitcoind_mock.bitcoind import BitcoindMock
|
||||
from bitcoind_mock.conf import BTC_RPC_HOST, BTC_RPC_PORT
|
||||
|
||||
from pisa import LOG_PREFIX
|
||||
from teos import LOG_PREFIX
|
||||
import common.cryptographer
|
||||
from common.logger import Logger
|
||||
from common.constants import LOCATOR_LEN_HEX
|
||||
@@ -151,7 +151,7 @@ def generate_dummy_tracker():
|
||||
|
||||
|
||||
def get_config():
|
||||
data_folder = os.path.expanduser("~/.pisa_btc")
|
||||
data_folder = os.path.expanduser("~/.teos")
|
||||
config = {
|
||||
"BTC_RPC_USER": "username",
|
||||
"BTC_RPC_PASSWD": "password",
|
||||
@@ -165,8 +165,8 @@ def get_config():
|
||||
"MAX_APPOINTMENTS": 100,
|
||||
"EXPIRY_DELTA": 6,
|
||||
"MIN_TO_SELF_DELAY": 20,
|
||||
"SERVER_LOG_FILE": data_folder + "pisa.log",
|
||||
"PISA_SECRET_KEY": data_folder + "pisa_sk.der",
|
||||
"SERVER_LOG_FILE": data_folder + "teos.log",
|
||||
"TEOS_SECRET_KEY": data_folder + "teos_sk.der",
|
||||
"DB_PATH": "appointments",
|
||||
}
|
||||
|
||||
@@ -4,14 +4,14 @@ import requests
|
||||
from time import sleep
|
||||
from threading import Thread
|
||||
|
||||
from pisa.api import API
|
||||
from pisa.watcher import Watcher
|
||||
from pisa.responder import Responder
|
||||
from pisa.tools import bitcoin_cli
|
||||
from pisa import HOST, PORT
|
||||
from pisa.chain_monitor import ChainMonitor
|
||||
from teos.api import API
|
||||
from teos.watcher import Watcher
|
||||
from teos.responder import Responder
|
||||
from teos.tools import bitcoin_cli
|
||||
from teos import HOST, PORT
|
||||
from teos.chain_monitor import ChainMonitor
|
||||
|
||||
from test.pisa.unit.conftest import (
|
||||
from test.teos.unit.conftest import (
|
||||
generate_block,
|
||||
generate_blocks,
|
||||
get_random_value_hex,
|
||||
@@ -23,7 +23,7 @@ from test.pisa.unit.conftest import (
|
||||
from common.constants import LOCATOR_LEN_BYTES
|
||||
|
||||
|
||||
PISA_API = "http://{}:{}".format(HOST, PORT)
|
||||
TEOS_API = "http://{}:{}".format(HOST, PORT)
|
||||
MULTIPLE_APPOINTMENTS = 10
|
||||
|
||||
appointments = []
|
||||
@@ -58,7 +58,7 @@ def new_appt_data():
|
||||
|
||||
|
||||
def add_appointment(new_appt_data):
|
||||
r = requests.post(url=PISA_API, json=json.dumps(new_appt_data), timeout=5)
|
||||
r = requests.post(url=TEOS_API, json=json.dumps(new_appt_data), timeout=5)
|
||||
|
||||
if r.status_code == 200:
|
||||
appointments.append(new_appt_data["appointment"])
|
||||
@@ -78,7 +78,7 @@ def test_add_appointment(run_api, run_bitcoind, new_appt_data):
|
||||
|
||||
|
||||
def test_request_random_appointment():
|
||||
r = requests.get(url=PISA_API + "/get_appointment?locator=" + get_random_value_hex(LOCATOR_LEN_BYTES))
|
||||
r = requests.get(url=TEOS_API + "/get_appointment?locator=" + get_random_value_hex(LOCATOR_LEN_BYTES))
|
||||
assert r.status_code == 200
|
||||
|
||||
received_appointments = json.loads(r.content)
|
||||
@@ -113,7 +113,7 @@ def test_add_too_many_appointment(new_appt_data):
|
||||
|
||||
|
||||
def test_get_all_appointments_watcher():
|
||||
r = requests.get(url=PISA_API + "/get_all_appointments")
|
||||
r = requests.get(url=TEOS_API + "/get_all_appointments")
|
||||
assert r.status_code == 200 and r.reason == "OK"
|
||||
|
||||
received_appointments = json.loads(r.content)
|
||||
@@ -137,7 +137,7 @@ def test_get_all_appointments_responder():
|
||||
generate_blocks(6)
|
||||
|
||||
# Get all appointments
|
||||
r = requests.get(url=PISA_API + "/get_all_appointments")
|
||||
r = requests.get(url=TEOS_API + "/get_all_appointments")
|
||||
received_appointments = json.loads(r.content)
|
||||
|
||||
# Make sure there is not pending locator in the watcher
|
||||
@@ -154,7 +154,7 @@ def test_request_appointment_watcher(new_appt_data):
|
||||
assert r.status_code == 200
|
||||
|
||||
# Next we can request it
|
||||
r = requests.get(url=PISA_API + "/get_appointment?locator=" + new_appt_data["appointment"]["locator"])
|
||||
r = requests.get(url=TEOS_API + "/get_appointment?locator=" + new_appt_data["appointment"]["locator"])
|
||||
assert r.status_code == 200
|
||||
|
||||
# Each locator may point to multiple appointments, check them all
|
||||
@@ -181,7 +181,7 @@ def test_request_appointment_responder(new_appt_data):
|
||||
# Generate a block to trigger the watcher
|
||||
generate_block()
|
||||
|
||||
r = requests.get(url=PISA_API + "/get_appointment?locator=" + new_appt_data["appointment"]["locator"])
|
||||
r = requests.get(url=TEOS_API + "/get_appointment?locator=" + new_appt_data["appointment"]["locator"])
|
||||
assert r.status_code == 200
|
||||
|
||||
received_appointments = json.loads(r.content)
|
||||
@@ -1,7 +1,7 @@
|
||||
import pytest
|
||||
|
||||
from pisa.block_processor import BlockProcessor
|
||||
from test.pisa.unit.conftest import get_random_value_hex, generate_block, generate_blocks, fork
|
||||
from teos.block_processor import BlockProcessor
|
||||
from test.teos.unit.conftest import get_random_value_hex, generate_block, generate_blocks, fork
|
||||
|
||||
|
||||
hex_tx = (
|
||||
@@ -2,10 +2,10 @@ import pytest
|
||||
from uuid import uuid4
|
||||
from queue import Queue
|
||||
|
||||
from pisa.builder import Builder
|
||||
from pisa.watcher import Watcher
|
||||
from pisa.responder import Responder
|
||||
from test.pisa.unit.conftest import (
|
||||
from teos.builder import Builder
|
||||
from teos.watcher import Watcher
|
||||
from teos.responder import Responder
|
||||
from test.teos.unit.conftest import (
|
||||
get_random_value_hex,
|
||||
generate_dummy_appointment,
|
||||
generate_dummy_tracker,
|
||||
@@ -1,9 +1,9 @@
|
||||
import pytest
|
||||
|
||||
from pisa.carrier import Carrier
|
||||
from teos.carrier import Carrier
|
||||
from bitcoind_mock.transaction import create_dummy_transaction
|
||||
from test.pisa.unit.conftest import generate_blocks, get_random_value_hex
|
||||
from pisa.rpc_errors import RPC_VERIFY_ALREADY_IN_CHAIN, RPC_DESERIALIZATION_ERROR
|
||||
from test.teos.unit.conftest import generate_blocks, get_random_value_hex
|
||||
from teos.rpc_errors import RPC_VERIFY_ALREADY_IN_CHAIN, RPC_DESERIALIZATION_ERROR
|
||||
|
||||
|
||||
# FIXME: This test do not fully cover the carrier since the simulator does not support every single error bitcoind may
|
||||
@@ -3,10 +3,10 @@ import time
|
||||
from queue import Queue
|
||||
from threading import Thread, Event, Condition
|
||||
|
||||
from pisa.block_processor import BlockProcessor
|
||||
from pisa.chain_monitor import ChainMonitor
|
||||
from teos.block_processor import BlockProcessor
|
||||
from teos.chain_monitor import ChainMonitor
|
||||
|
||||
from test.pisa.unit.conftest import get_random_value_hex, generate_block
|
||||
from test.teos.unit.conftest import get_random_value_hex, generate_block
|
||||
|
||||
|
||||
def test_init(run_bitcoind):
|
||||
@@ -1,11 +1,11 @@
|
||||
import random
|
||||
from uuid import uuid4
|
||||
|
||||
from pisa.responder import TransactionTracker
|
||||
from pisa.cleaner import Cleaner
|
||||
from teos.responder import TransactionTracker
|
||||
from teos.cleaner import Cleaner
|
||||
from common.appointment import Appointment
|
||||
|
||||
from test.pisa.unit.conftest import get_random_value_hex
|
||||
from test.teos.unit.conftest import get_random_value_hex
|
||||
|
||||
from common.constants import LOCATOR_LEN_BYTES, LOCATOR_LEN_HEX
|
||||
|
||||
@@ -4,8 +4,8 @@ import pytest
|
||||
import shutil
|
||||
from uuid import uuid4
|
||||
|
||||
from pisa.db_manager import DBManager
|
||||
from pisa.db_manager import (
|
||||
from teos.db_manager import DBManager
|
||||
from teos.db_manager import (
|
||||
WATCHER_LAST_BLOCK_KEY,
|
||||
RESPONDER_LAST_BLOCK_KEY,
|
||||
LOCATOR_MAP_PREFIX,
|
||||
@@ -14,7 +14,7 @@ from pisa.db_manager import (
|
||||
|
||||
from common.constants import LOCATOR_LEN_BYTES
|
||||
|
||||
from test.pisa.unit.conftest import get_random_value_hex, generate_dummy_appointment
|
||||
from test.teos.unit.conftest import get_random_value_hex, generate_dummy_appointment
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
@@ -1,18 +1,18 @@
|
||||
from binascii import unhexlify
|
||||
|
||||
from pisa.errors import *
|
||||
from pisa.inspector import Inspector
|
||||
from teos.errors import *
|
||||
from teos.inspector import Inspector
|
||||
from common.appointment import Appointment
|
||||
from pisa.block_processor import BlockProcessor
|
||||
from pisa.conf import MIN_TO_SELF_DELAY
|
||||
from teos.block_processor import BlockProcessor
|
||||
from teos.conf import MIN_TO_SELF_DELAY
|
||||
|
||||
from test.pisa.unit.conftest import get_random_value_hex, generate_dummy_appointment_data, generate_keypair, get_config
|
||||
from test.teos.unit.conftest import get_random_value_hex, generate_dummy_appointment_data, generate_keypair, get_config
|
||||
|
||||
from common.constants import LOCATOR_LEN_BYTES, LOCATOR_LEN_HEX
|
||||
from common.cryptographer import Cryptographer
|
||||
from common.logger import Logger
|
||||
|
||||
from pisa import LOG_PREFIX
|
||||
from teos import LOG_PREFIX
|
||||
import common.cryptographer
|
||||
|
||||
common.cryptographer.logger = Logger(actor="Cryptographer", log_name_prefix=LOG_PREFIX)
|
||||
@@ -7,15 +7,15 @@ from shutil import rmtree
|
||||
from copy import deepcopy
|
||||
from threading import Thread
|
||||
|
||||
from pisa.db_manager import DBManager
|
||||
from pisa.responder import Responder, TransactionTracker
|
||||
from pisa.block_processor import BlockProcessor
|
||||
from pisa.chain_monitor import ChainMonitor
|
||||
from pisa.tools import bitcoin_cli
|
||||
from teos.db_manager import DBManager
|
||||
from teos.responder import Responder, TransactionTracker
|
||||
from teos.block_processor import BlockProcessor
|
||||
from teos.chain_monitor import ChainMonitor
|
||||
from teos.tools import bitcoin_cli
|
||||
|
||||
from common.constants import LOCATOR_LEN_HEX
|
||||
from bitcoind_mock.transaction import create_dummy_transaction, create_tx_from_hex
|
||||
from test.pisa.unit.conftest import generate_block, generate_blocks, get_random_value_hex
|
||||
from test.teos.unit.conftest import generate_block, generate_blocks, get_random_value_hex
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
@@ -1,4 +1,4 @@
|
||||
from pisa.tools import can_connect_to_bitcoind, in_correct_network, bitcoin_cli
|
||||
from teos.tools import can_connect_to_bitcoind, in_correct_network, bitcoin_cli
|
||||
|
||||
from common.tools import check_sha256_hex_format
|
||||
|
||||
@@ -4,23 +4,23 @@ from shutil import rmtree
|
||||
from threading import Thread
|
||||
from coincurve import PrivateKey
|
||||
|
||||
from pisa.watcher import Watcher
|
||||
from pisa.responder import Responder
|
||||
from pisa.tools import bitcoin_cli
|
||||
from pisa.chain_monitor import ChainMonitor
|
||||
from pisa.db_manager import DBManager
|
||||
from teos.watcher import Watcher
|
||||
from teos.responder import Responder
|
||||
from teos.tools import bitcoin_cli
|
||||
from teos.chain_monitor import ChainMonitor
|
||||
from teos.db_manager import DBManager
|
||||
|
||||
from test.pisa.unit.conftest import (
|
||||
from test.teos.unit.conftest import (
|
||||
generate_blocks,
|
||||
generate_dummy_appointment,
|
||||
get_random_value_hex,
|
||||
generate_keypair,
|
||||
get_config,
|
||||
)
|
||||
from pisa.conf import EXPIRY_DELTA, MAX_APPOINTMENTS
|
||||
from teos.conf import EXPIRY_DELTA, MAX_APPOINTMENTS
|
||||
|
||||
import common.cryptographer
|
||||
from pisa import LOG_PREFIX
|
||||
from teos import LOG_PREFIX
|
||||
from common.logger import Logger
|
||||
from common.tools import compute_locator
|
||||
from common.cryptographer import Cryptographer
|
||||
Reference in New Issue
Block a user