Skip to content

Commit

Permalink
Add tests for onchain address, pgp sign verification. Improve Dockerfile
Browse files Browse the repository at this point in the history
  • Loading branch information
Reckless-Satoshi committed Nov 15, 2023
1 parent c8e3fe5 commit 8080447
Show file tree
Hide file tree
Showing 17 changed files with 264 additions and 136 deletions.
1 change: 0 additions & 1 deletion .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ jobs:
- name: Patch Dockerfile and .env-sample
run: |
sed -i "1s/FROM python:.*/FROM python:${{ matrix.python-tag }}/" Dockerfile
sed -i '/RUN pip install --no-cache-dir -r requirements.txt/a COPY requirements_dev.txt .\nRUN pip install --no-cache-dir -r requirements_dev.txt' Dockerfile
sed -i "s/^LNVENDOR=.*/LNVENDOR='${{ matrix.ln-vendor }}'/" .env-sample
- uses: satackey/[email protected]
Expand Down
6 changes: 6 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
FROM python:3.11.6-slim-bookworm
ARG DEBIAN_FRONTEND=noninteractive
ARG DEVELOPMENT=False

RUN mkdir -p /usr/src/robosats
WORKDIR /usr/src/robosats
Expand All @@ -17,6 +18,11 @@ RUN python -m pip install --upgrade pip
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY requirements_dev.txt ./
RUN if [ "$DEVELOPMENT" = "true" ]; then \
pip install --no-cache-dir -r requirements_dev.txt; \
fi

# copy current dir's content to container's WORKDIR root i.e. all the contents of the robosats app
COPY . .

Expand Down
8 changes: 8 additions & 0 deletions api/lightning/cln.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ def get_info(cls):
except Exception as e:
print(f"Cannot get CLN node id: {e}")

@classmethod
def newaddress(cls):
"""Only used on tests to fund the regtest node"""
nodestub = node_pb2_grpc.NodeStub(cls.node_channel)
request = node_pb2.NewaddrRequest()
response = nodestub.NewAddr(request)
return response.bech32

@classmethod
def decode_payreq(cls, invoice):
"""Decodes a lightning payment request (invoice)"""
Expand Down
3 changes: 2 additions & 1 deletion api/lightning/lnd.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,11 @@ def estimate_fee(cls, amount_sats, target_conf=2, min_confs=1):
lightningstub = lightning_pb2_grpc.LightningStub(cls.channel)
request = lightning_pb2.GetInfoRequest()
response = lightningstub.GetInfo(request)
log("lightning_pb2_grpc.GetInfo", request, response)

if response.testnet:
dummy_address = "tb1qehyqhruxwl2p5pt52k6nxj4v8wwc3f3pg7377x"
elif response.chains[0].network == "regtest":
dummy_address = "bcrt1q3w8xja7knmycsglnxg2xzjq8uv9u7jdwau25nl"
else:
dummy_address = "bc1qgxwaqe4m9mypd7ltww53yv3lyxhcfnhzzvy5j3"
# We assume segwit. Use hardcoded address as shortcut so there is no need of user inputs yet.
Expand Down
4 changes: 2 additions & 2 deletions api/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ def test_weighted_median(self):

def test_validate_pgp_keys(self):
# Example test client generated GPG keys
client_pub_key = r"-----BEGIN PGP PUBLIC KEY BLOCK-----\\xjMEZTWJ1xYJKwYBBAHaRw8BAQdAsfdKb90BurKniu+pBPBDHCkzg08S51W0\mUR0SKqLmdjNTFJvYm9TYXRzIElEIDU1MmRkMWE2NjFhN2FjYTRhNDFmODg5\MTBmZjM0YWMzYjFhYzgwYmI3Nzk0ZWQ5ZmQ1NWQ4Yjc2Yjk3YWFkOTfCjAQQ\FgoAPgWCZTWJ1wQLCQcICZA3N7au4gi/zgMVCAoEFgACAQIZAQKbAwIeARYh\BO5iBLnj0J/E6sntEDc3tq7iCL/OAADkVwEA/tBt9FPqrxLHOPFtyUypppr0\/t6vrl3RrLzCLqqE1nUA/0fmhir2F88KcsxmCJwADo/FglwXGFkjrV4sP6Fj\YBEBzjgEZTWJ1xIKKwYBBAGXVQEFAQEHQCyUIe3sQTaYa/IFNKGNmXz/+hrH\ukcot4TOvi2bD9p8AwEIB8J4BBgWCAAqBYJlNYnXCZA3N7au4gi/zgKbDBYh\BO5iBLnj0J/E6sntEDc3tq7iCL/OAACaFAD7BG3E7TkUoWKtJe5OPzTwX+bM\Xy7hbPSQw0zM9Re8KP0BAIeTG8d280dTK63h/seQAKeMj0zf7AYXr0CscvS7\f38D\=h03E\-----END PGP PUBLIC KEY BLOCK-----"
client_enc_priv_key = r"-----BEGIN PGP PRIVATE KEY BLOCK-----\\xYYEZTWJ1xYJKwYBBAHaRw8BAQdAsfdKb90BurKniu+pBPBDHCkzg08S51W0\mUR0SKqLmdj+CQMICrS3TNCA/LHgxckC+iTUMxkqQJ9GpXWCDacx1rBQCztu\PDgUHNvWdcvW1wWVxU/aJaQLqBTtRVYkJTz332jrKvsSl/LnrfwmUfKgN4nG\Oc1MUm9ib1NhdHMgSUQgNTUyZGQxYTY2MWE3YWNhNGE0MWY4ODkxMGZmMzRh\YzNiMWFjODBiYjc3OTRlZDlmZDU1ZDhiNzZiOTdhYWQ5N8KMBBAWCgA+BYJl\NYnXBAsJBwgJkDc3tq7iCL/OAxUICgQWAAIBAhkBApsDAh4BFiEE7mIEuePQ\n8Tqye0QNze2ruIIv84AAORXAQD+0G30U+qvEsc48W3JTKmmmvT+3q+uXdGs\vMIuqoTWdQD/R+aGKvYXzwpyzGYInAAOj8WCXBcYWSOtXiw/oWNgEQHHiwRl\NYnXEgorBgEEAZdVAQUBAQdALJQh7exBNphr8gU0oY2ZfP/6Gse6Ryi3hM6+\LZsP2nwDAQgH/gkDCPPoYWyzm4mT4N/TDBF11GVq0xSEEcubFqjArFKyibRy\TDnB8+o8BlkRuGClcfRyKkR5/Rp1v5B0n1BuMsc8nY4Yg4BJv4KhsPfXRp4m\31zCeAQYFggAKgWCZTWJ1wmQNze2ruIIv84CmwwWIQTuYgS549CfxOrJ7RA3\N7au4gi/zgAAmhQA+wRtxO05FKFirSXuTj808F/mzF8u4Wz0kMNMzPUXvCj9\AQCHkxvHdvNHUyut4f7HkACnjI9M3+wGF69ArHL0u39/Aw==\=1hCT\-----END PGP PRIVATE KEY BLOCK-----"
client_pub_key = r"-----BEGIN PGP PUBLIC KEY BLOCK-----\\mDMEZVO9bxYJKwYBBAHaRw8BAQdAVyePBQK63FB2r5ZpIqO998WaqZjmro+LFNH+\sw2raQC0TFJvYm9TYXRzIElEIGVkN2QzYjJiMmU1ODlhYjI2NzIwNjA1ZTc0MTRh\YjRmYmNhMjFjYjRiMzFlNWI0ZTYyYTZmYTUxYzI0YTllYWKIjAQQFgoAPgWCZVO9\bwQLCQcICZAuNFtLSY2XJAMVCAoEFgACAQIZAQKbAwIeARYhBDIhViOFpzWovPuw\vC40W0tJjZckAACTeAEA+AdXmA8p6I+FFqXaFVRh5JRa5ZoO4xhGb+QY00kgZisB\AJee8XdW6FHBj2J3b4M9AYqufdpvuj+lLmaVAshN9U4MuDgEZVO9bxIKKwYBBAGX\VQEFAQEHQORkbvSesg9oJeCRKigTNdQ5tkgmVGXfdz/+vwBIl3E3AwEIB4h4BBgW\CAAqBYJlU71vCZAuNFtLSY2XJAKbDBYhBDIhViOFpzWovPuwvC40W0tJjZckAABZ\1AD/RIJM/WNb28pYqtq4XmeOaqLCrbQs2ua8mXpGBZSl8E0BALWSlbHICYTNy9L6\KV0a5pXbxcXpzejcjpJmVwzuWz8P\=32+r\-----END PGP PUBLIC KEY BLOCK-----"
client_enc_priv_key = r"-----BEGIN PGP PRIVATE KEY BLOCK-----\\xYYEZVO9bxYJKwYBBAHaRw8BAQdAVyePBQK63FB2r5ZpIqO998WaqZjmro+L\FNH+sw2raQD+CQMIHkZZZnDa6d/gHioGTKf6JevirkCBWwz8tFLGFs5DFwjD\tI4ew9CJd09AUxfMq2WvTilhMNrdw2nmqtmAoaIyIo43azVT1VQoxSDnWxFv\Tc1MUm9ib1NhdHMgSUQgZWQ3ZDNiMmIyZTU4OWFiMjY3MjA2MDVlNzQxNGFi\NGZiY2EyMWNiNGIzMWU1YjRlNjJhNmZhNTFjMjRhOWVhYsKMBBAWCgA+BYJl\U71vBAsJBwgJkC40W0tJjZckAxUICgQWAAIBAhkBApsDAh4BFiEEMiFWI4Wn\Nai8+7C8LjRbS0mNlyQAAJN4AQD4B1eYDynoj4UWpdoVVGHklFrlmg7jGEZv\5BjTSSBmKwEAl57xd1boUcGPYndvgz0Biq592m+6P6UuZpUCyE31TgzHiwRl\U71vEgorBgEEAZdVAQUBAQdA5GRu9J6yD2gl4JEqKBM11Dm2SCZUZd93P/6/\AEiXcTcDAQgH/gkDCGSRul0JyboW4JZSQVlHNVlx2mrfE1gRTh2R5hJWU9Kg\aw2gET8OwWDYU4F8wKTo/s7BGn+HN4jrZeLw1k/etKUKLzuPC06KUXhj3rMF\Ti3CeAQYFggAKgWCZVO9bwmQLjRbS0mNlyQCmwwWIQQyIVYjhac1qLz7sLwu\NFtLSY2XJAAAWdQA/0SCTP1jW9vKWKrauF5njmqiwq20LNrmvJl6RgWUpfBN\AQC1kpWxyAmEzcvS+ildGuaV28XF6c3o3I6SZlcM7ls/Dw==\=YAfZ\-----END PGP PRIVATE KEY BLOCK-----"

# Example valid formatted GPG keys
with open("tests/robots/1/pub_key", "r") as file:
Expand Down
3 changes: 3 additions & 0 deletions control/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ def get_ln_remote_unsettled():
def __str__(self):
return f"Balance at {self.time.strftime('%d/%m/%Y %H:%M:%S')}"

class Meta:
get_latest_by = "time"


class Dispute(models.Model):
pass
7 changes: 5 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ services:
network_mode: service:tor

backend:
build: .
build:
context: .
args:
DEVELOPMENT: True
image: backend-image
container_name: django-dev
restart: always
Expand All @@ -30,7 +33,7 @@ services:
- lnd
- redis
environment:
DEVELOPMENT: 1
DEVELOPMENT: True
volumes:
- .:/usr/src/robosats
- ./node/lnd:/lnd
Expand Down
10 changes: 8 additions & 2 deletions docker-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ services:
- cln:/root/.lightning
- ./docker/cln/plugins/cln-grpc-hold:/root/.lightning/plugins/cln-grpc-hold
- bitcoin:/root/.bitcoin
command: --regtest --wumbo --bitcoin-rpcuser=test --bitcoin-rpcpassword=test --rest-host=0.0.0.0 --bind-addr=127.0.0.1:9737 --max-concurrent-htlcs=483 --grpc-port=9999 --grpc-hold-port=9998 --important-plugin=/root/.lightning/plugins/cln-grpc-hold --database-upgrade=true
command: --regtest --wumbo --bitcoin-rpcuser=test --bitcoin-rpcpassword=test --rest-host=0.0.0.0 --rest-port=3010 --bind-addr=127.0.0.1:9737 --max-concurrent-htlcs=483 --grpc-port=9999 --grpc-hold-port=9998 --important-plugin=/root/.lightning/plugins/cln-grpc-hold --database-upgrade=true
depends_on:
- bitcoind
network_mode: service:bitcoind
Expand Down Expand Up @@ -132,7 +132,10 @@ services:
network_mode: service:bitcoind

coordinator:
build: .
build:
context: .
args:
DEVELOPMENT: True
image: robosats-image
container_name: coordinator
restart: always
Expand All @@ -142,6 +145,9 @@ services:
USE_TOR: False
MACAROON_PATH: 'data/chain/bitcoin/regtest/admin.macaroon'
CLN_DIR: '/cln/regtest/'
BITCOIND_RPCURL: 'http://127.0.0.1:18443'
BITCOIND_RPCUSER: 'test'
BITCOIND_RPCPASSWORD: 'test'
env_file:
- ${ROBOSATS_ENVS_FILE}
depends_on:
Expand Down
97 changes: 85 additions & 12 deletions tests/node_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import time

import requests
from decouple import config
from requests.auth import HTTPBasicAuth
from requests.exceptions import ReadTimeout

wait_step = 0.2
LNVENDOR = config("LNVENDOR", cast=str, default="LND")
WAIT_STEP = 0.2


def get_node(name="robot"):
Expand Down Expand Up @@ -59,8 +61,8 @@ def wait_for_lnd_node_sync(node_name):
f"\rWaiting for {node_name} node chain sync {round(waited,1)}s"

Check failure on line 61 in tests/node_utils.py

View workflow job for this annotation

GitHub Actions / Flake8

tests/node_utils.py#L61

Missing whitespace after ',' (E231)
)
sys.stdout.flush()
waited += wait_step
time.sleep(wait_step)
waited += WAIT_STEP
time.sleep(WAIT_STEP)


def LND_has_active_channels(node_name):
Expand Down Expand Up @@ -97,8 +99,8 @@ def wait_for_active_channels(lnvendor, node_name="coordinator"):
)

sys.stdout.flush()
waited += wait_step
time.sleep(wait_step)
waited += WAIT_STEP
time.sleep(WAIT_STEP)


def wait_for_cln_node_sync():
Expand All @@ -112,8 +114,8 @@ def wait_for_cln_node_sync():
f"\rWaiting for coordinator CLN node sync {round(waited,1)}s"

Check failure on line 114 in tests/node_utils.py

View workflow job for this annotation

GitHub Actions / Flake8

tests/node_utils.py#L114

Missing whitespace after ',' (E231)
)
sys.stdout.flush()
waited += wait_step
time.sleep(wait_step)
waited += WAIT_STEP
time.sleep(WAIT_STEP)
else:
return

Expand All @@ -131,8 +133,66 @@ def wait_for_cln_active_channels():
f"\rWaiting for coordinator CLN node channels to be active {round(waited,1)}s"

Check failure on line 133 in tests/node_utils.py

View workflow job for this annotation

GitHub Actions / Flake8

tests/node_utils.py#L133

Missing whitespace after ',' (E231)
)
sys.stdout.flush()
waited += wait_step
time.sleep(wait_step)
waited += WAIT_STEP
time.sleep(WAIT_STEP)


def wait_nodes_sync():
wait_for_lnd_node_sync("robot")
if LNVENDOR == "LND":
wait_for_lnd_node_sync("coordinator")
elif LNVENDOR == "CLN":
wait_for_cln_node_sync()


def wait_channels():
wait_for_active_channels(LNVENDOR, "coordinator")
wait_for_active_channels("LND", "robot")


def set_up_regtest_network():
if channel_is_active():
print("Regtest network was already ready. Skipping initalization.")
return
# Fund two LN nodes in regtest and open channels
# Coordinator is either LND or CLN. Robot user is always LND.
if LNVENDOR == "LND":
coordinator_node_id = get_lnd_node_id("coordinator")
coordinator_port = 9735
elif LNVENDOR == "CLN":
coordinator_node_id = get_cln_node_id()
coordinator_port = 9737

print("Coordinator Node ID: ", coordinator_node_id)

# Fund both robot and coordinator nodes
robot_funding_address = create_address("robot")
coordinator_funding_address = create_address("coordinator")
generate_blocks(coordinator_funding_address, 1)
generate_blocks(robot_funding_address, 101)
wait_nodes_sync()

# Open channel between Robot user and coordinator
print(f"\nOpening channel from Robot user node to coordinator {LNVENDOR} node")
connect_to_node("robot", coordinator_node_id, f"localhost:{coordinator_port}")
open_channel("robot", coordinator_node_id, 100_000_000, 50_000_000)

# Generate 10 blocks so the channel becomes active and wait for sync
generate_blocks(robot_funding_address, 10)

# Wait a tiny bit so payments can be done in the new channel
wait_nodes_sync()
wait_channels()
time.sleep(1)


def channel_is_active():
robot_channel_active = LND_has_active_channels("robot")
if LNVENDOR == "LND":
coordinator_channel_active = LND_has_active_channels("coordinator")
elif LNVENDOR == "CLN":
coordinator_channel_active = CLN_has_active_channels()
return robot_channel_active and coordinator_channel_active


def connect_to_node(node_name, node_id, ip_port):
Expand All @@ -151,7 +211,7 @@ def connect_to_node(node_name, node_id, ip_port):
if "already connected to peer" in response.json()["message"]:
return response.json()
print(f"Could not peer coordinator node: {response.json()}")
time.sleep(wait_step)
time.sleep(WAIT_STEP)


def open_channel(node_name, node_id, local_funding_amount, push_sat):
Expand All @@ -169,14 +229,27 @@ def open_channel(node_name, node_id, local_funding_amount, push_sat):
return response.json()


def create_address(node_name):
def create_address_LND(node_name):
node = get_node(node_name)
response = requests.get(
f'http://localhost:{node["port"]}/v1/newaddress', headers=node["headers"]
)
return response.json()["address"]


def create_address_CLN():
from api.lightning.cln import CLNNode

return CLNNode.newaddress()


def create_address(node_name):
if node_name == "coordinator" and LNVENDOR == "CLN":
return create_address_CLN()
else:
return create_address_LND(node_name)


def generate_blocks(address, num_blocks):
print(f"Mining {num_blocks} blocks")
data = {
Expand All @@ -199,7 +272,7 @@ def pay_invoice(node_name, invoice):
f'http://localhost:{node["port"]}/v1/channels/transactions',
json=data,
headers=node["headers"],
timeout=1,
timeout=0.3, # 0.15s is enough for LND to LND hodl ACCEPT.
)
except ReadTimeout:
# Request to pay hodl invoice has timed out: that's good!
Expand Down
22 changes: 22 additions & 0 deletions tests/pgp_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import gnupg


def sign_message(message, private_key_path, passphrase_path):
gpg = gnupg.GPG()

with open(private_key_path, "r") as f:
private_key = f.read()

with open(passphrase_path, "r") as f:
passphrase = f.read()

gpg.import_keys(private_key, passphrase=passphrase)

# keyid=import_result.fingerprints[0]
signed_message = gpg.sign(
message, passphrase=passphrase, extra_args=["--digest-algo", "SHA512"]
)

# [print(name, getattr(signed_message, name)) for name in dir(signed_message) if not callable(getattr(signed_message, name))]

return signed_message.data.decode(encoding="UTF-8", errors="strict")
2 changes: 1 addition & 1 deletion tests/robots/1/b91_token
Original file line number Diff line number Diff line change
@@ -1 +1 @@
qz*fp3CzNfK0Y2MWx;<Ke}2&S}ymduQyhjoJtIZE
Y#>]mLP@:Ka2/t_;no*:0GeGd}j2rSQ{}1qwZCED
30 changes: 15 additions & 15 deletions tests/robots/1/enc_priv_key
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----

xYYEZTWJ1xYJKwYBBAHaRw8BAQdAsfdKb90BurKniu+pBPBDHCkzg08S51W0
mUR0SKqLmdj+CQMICrS3TNCA/LHgxckC+iTUMxkqQJ9GpXWCDacx1rBQCztu
PDgUHNvWdcvW1wWVxU/aJaQLqBTtRVYkJTz332jrKvsSl/LnrfwmUfKgN4nG
Oc1MUm9ib1NhdHMgSUQgNTUyZGQxYTY2MWE3YWNhNGE0MWY4ODkxMGZmMzRh
YzNiMWFjODBiYjc3OTRlZDlmZDU1ZDhiNzZiOTdhYWQ5N8KMBBAWCgA+BYJl
NYnXBAsJBwgJkDc3tq7iCL/OAxUICgQWAAIBAhkBApsDAh4BFiEE7mIEuePQ
n8Tqye0QNze2ruIIv84AAORXAQD+0G30U+qvEsc48W3JTKmmmvT+3q+uXdGs
vMIuqoTWdQD/R+aGKvYXzwpyzGYInAAOj8WCXBcYWSOtXiw/oWNgEQHHiwRl
NYnXEgorBgEEAZdVAQUBAQdALJQh7exBNphr8gU0oY2ZfP/6Gse6Ryi3hM6+
LZsP2nwDAQgH/gkDCPPoYWyzm4mT4N/TDBF11GVq0xSEEcubFqjArFKyibRy
TDnB8+o8BlkRuGClcfRyKkR5/Rp1v5B0n1BuMsc8nY4Yg4BJv4KhsPfXRp4m
31zCeAQYFggAKgWCZTWJ1wmQNze2ruIIv84CmwwWIQTuYgS549CfxOrJ7RA3
N7au4gi/zgAAmhQA+wRtxO05FKFirSXuTj808F/mzF8u4Wz0kMNMzPUXvCj9
AQCHkxvHdvNHUyut4f7HkACnjI9M3+wGF69ArHL0u39/Aw==
=1hCT
xYYEZVO9bxYJKwYBBAHaRw8BAQdAVyePBQK63FB2r5ZpIqO998WaqZjmro+L
FNH+sw2raQD+CQMIHkZZZnDa6d/gHioGTKf6JevirkCBWwz8tFLGFs5DFwjD
tI4ew9CJd09AUxfMq2WvTilhMNrdw2nmqtmAoaIyIo43azVT1VQoxSDnWxFv
Tc1MUm9ib1NhdHMgSUQgZWQ3ZDNiMmIyZTU4OWFiMjY3MjA2MDVlNzQxNGFi
NGZiY2EyMWNiNGIzMWU1YjRlNjJhNmZhNTFjMjRhOWVhYsKMBBAWCgA+BYJl
U71vBAsJBwgJkC40W0tJjZckAxUICgQWAAIBAhkBApsDAh4BFiEEMiFWI4Wn
Nai8+7C8LjRbS0mNlyQAAJN4AQD4B1eYDynoj4UWpdoVVGHklFrlmg7jGEZv
5BjTSSBmKwEAl57xd1boUcGPYndvgz0Biq592m+6P6UuZpUCyE31TgzHiwRl
U71vEgorBgEEAZdVAQUBAQdA5GRu9J6yD2gl4JEqKBM11Dm2SCZUZd93P/6/
AEiXcTcDAQgH/gkDCGSRul0JyboW4JZSQVlHNVlx2mrfE1gRTh2R5hJWU9Kg
aw2gET8OwWDYU4F8wKTo/s7BGn+HN4jrZeLw1k/etKUKLzuPC06KUXhj3rMF
Ti3CeAQYFggAKgWCZVO9bwmQLjRbS0mNlyQCmwwWIQQyIVYjhac1qLz7sLwu
NFtLSY2XJAAAWdQA/0SCTP1jW9vKWKrauF5njmqiwq20LNrmvJl6RgWUpfBN
AQC1kpWxyAmEzcvS+ildGuaV28XF6c3o3I6SZlcM7ls/Dw==
=YAfZ
-----END PGP PRIVATE KEY BLOCK-----
2 changes: 1 addition & 1 deletion tests/robots/1/nickname
Original file line number Diff line number Diff line change
@@ -1 +1 @@
MyopicRacket333
UptightPub730
22 changes: 11 additions & 11 deletions tests/robots/1/pub_key
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----

mDMEZTWJ1xYJKwYBBAHaRw8BAQdAsfdKb90BurKniu+pBPBDHCkzg08S51W0mUR0
SKqLmdi0TFJvYm9TYXRzIElEIDU1MmRkMWE2NjFhN2FjYTRhNDFmODg5MTBmZjM0
YWMzYjFhYzgwYmI3Nzk0ZWQ5ZmQ1NWQ4Yjc2Yjk3YWFkOTeIjAQQFgoAPgWCZTWJ
1wQLCQcICZA3N7au4gi/zgMVCAoEFgACAQIZAQKbAwIeARYhBO5iBLnj0J/E6snt
EDc3tq7iCL/OAADkVwEA/tBt9FPqrxLHOPFtyUypppr0/t6vrl3RrLzCLqqE1nUA
/0fmhir2F88KcsxmCJwADo/FglwXGFkjrV4sP6FjYBEBuDgEZTWJ1xIKKwYBBAGX
VQEFAQEHQCyUIe3sQTaYa/IFNKGNmXz/+hrHukcot4TOvi2bD9p8AwEIB4h4BBgW
CAAqBYJlNYnXCZA3N7au4gi/zgKbDBYhBO5iBLnj0J/E6sntEDc3tq7iCL/OAACa
FAD7BG3E7TkUoWKtJe5OPzTwX+bMXy7hbPSQw0zM9Re8KP0BAIeTG8d280dTK63h
/seQAKeMj0zf7AYXr0CscvS7f38D
=+xY8
mDMEZVO9bxYJKwYBBAHaRw8BAQdAVyePBQK63FB2r5ZpIqO998WaqZjmro+LFNH+
sw2raQC0TFJvYm9TYXRzIElEIGVkN2QzYjJiMmU1ODlhYjI2NzIwNjA1ZTc0MTRh
YjRmYmNhMjFjYjRiMzFlNWI0ZTYyYTZmYTUxYzI0YTllYWKIjAQQFgoAPgWCZVO9
bwQLCQcICZAuNFtLSY2XJAMVCAoEFgACAQIZAQKbAwIeARYhBDIhViOFpzWovPuw
vC40W0tJjZckAACTeAEA+AdXmA8p6I+FFqXaFVRh5JRa5ZoO4xhGb+QY00kgZisB
AJee8XdW6FHBj2J3b4M9AYqufdpvuj+lLmaVAshN9U4MuDgEZVO9bxIKKwYBBAGX
VQEFAQEHQORkbvSesg9oJeCRKigTNdQ5tkgmVGXfdz/+vwBIl3E3AwEIB4h4BBgW
CAAqBYJlU71vCZAuNFtLSY2XJAKbDBYhBDIhViOFpzWovPuwvC40W0tJjZckAABZ
1AD/RIJM/WNb28pYqtq4XmeOaqLCrbQs2ua8mXpGBZSl8E0BALWSlbHICYTNy9L6
KV0a5pXbxcXpzejcjpJmVwzuWz8P
=32+r
-----END PGP PUBLIC KEY BLOCK-----
Loading

0 comments on commit 8080447

Please sign in to comment.