2021-07-20 11:00:49 -03:00
|
|
|
import datetime
|
|
|
|
import io
|
|
|
|
import json
|
|
|
|
import os
|
|
|
|
import random
|
|
|
|
import string
|
|
|
|
from http import HTTPStatus
|
|
|
|
|
|
|
|
from database import db
|
|
|
|
from models import Invoice, Order
|
2021-12-21 16:32:30 -03:00
|
|
|
from utils import hmac_sha256_digest
|
2021-07-20 11:00:49 -03:00
|
|
|
import bidding
|
|
|
|
import constants
|
|
|
|
|
|
|
|
|
|
|
|
def rnd_string(n_bytes):
|
|
|
|
"""Generate random string with given number of bytes"""
|
|
|
|
return ''.join(
|
|
|
|
random.choice(string.ascii_letters + string.digits)
|
|
|
|
for _ in range(n_bytes))
|
|
|
|
|
|
|
|
|
Support multiple parallel logical message channels
The same server now can handle multiple logical channels, on which the
transmitter logic runs independently. That is, while previously a single
message would be in transmitting state at a time, now multiple messages
can be in transmitting state as long as they belong to distinct logical
channels.
The supported channels each have different permissions. The user channel
is where users can post, get, and delete messages as needed. In
contrast, the other channels do not grant all permissions to users. Some
are read-only (users can get but not post) and there is a channel (the
auth channel) on which users have no permissions (neither get nor post).
For the channels on which users do not have all permissions (get, post,
and delete), this patch adds admin-specific routes, which are prefixed
by /admin/. The /admin/ route is protected via SSL in production and
allows the admin host to send GET/POST/DELETE requests normally. Hence,
for instance, the admin host can post a message on the auth channel
(with POST /admin/order) and read it (with GET /admin/order) for
transmission over satellite, whereas regulars cannot. With this scheme,
the auth channel messages are accessible exclusively over satellite (and
not over the internet).
The admin routes were added to the following endpoints:
- /order/<uuid> (GET and DELETE requests)
- /order (POST request)
- /orders/<state> (GET request)
- /message/<tx_seq_num> (GET request)
The messages posted by the admin are not paid, so this patch removes the
requirement of invoice generation and payment. Only paid orders now
generate an invoice. Thus, the POST request to the /order/ endpoint does
not return an invoice for non-paid (admin-only) messages.
Also, this patch updates the queue page to display the orders separately
for each channel. The query string channel parameter determines which
channel the page shows.
Finally, this patch updates the events published into the Redis db on
transmission. The event includes the corresponding logical channel so
that SSE events can be subscribed independently for each channel.
2023-01-31 18:14:55 -03:00
|
|
|
def upload_test_file(client, msg, bid, regions=[], channel=None, admin=False):
|
2021-12-21 16:32:10 -03:00
|
|
|
post_data = {'bid': bid, 'file': (io.BytesIO(msg.encode()), 'testfile')}
|
|
|
|
|
|
|
|
if len(regions) > 0:
|
|
|
|
post_data['regions'] = [regions]
|
Support multiple parallel logical message channels
The same server now can handle multiple logical channels, on which the
transmitter logic runs independently. That is, while previously a single
message would be in transmitting state at a time, now multiple messages
can be in transmitting state as long as they belong to distinct logical
channels.
The supported channels each have different permissions. The user channel
is where users can post, get, and delete messages as needed. In
contrast, the other channels do not grant all permissions to users. Some
are read-only (users can get but not post) and there is a channel (the
auth channel) on which users have no permissions (neither get nor post).
For the channels on which users do not have all permissions (get, post,
and delete), this patch adds admin-specific routes, which are prefixed
by /admin/. The /admin/ route is protected via SSL in production and
allows the admin host to send GET/POST/DELETE requests normally. Hence,
for instance, the admin host can post a message on the auth channel
(with POST /admin/order) and read it (with GET /admin/order) for
transmission over satellite, whereas regulars cannot. With this scheme,
the auth channel messages are accessible exclusively over satellite (and
not over the internet).
The admin routes were added to the following endpoints:
- /order/<uuid> (GET and DELETE requests)
- /order (POST request)
- /orders/<state> (GET request)
- /message/<tx_seq_num> (GET request)
The messages posted by the admin are not paid, so this patch removes the
requirement of invoice generation and payment. Only paid orders now
generate an invoice. Thus, the POST request to the /order/ endpoint does
not return an invoice for non-paid (admin-only) messages.
Also, this patch updates the queue page to display the orders separately
for each channel. The query string channel parameter determines which
channel the page shows.
Finally, this patch updates the events published into the Redis db on
transmission. The event includes the corresponding logical channel so
that SSE events can be subscribed independently for each channel.
2023-01-31 18:14:55 -03:00
|
|
|
if channel:
|
|
|
|
post_data['channel'] = channel
|
|
|
|
endpoint = '/admin/order' if admin else '/order'
|
2021-12-21 16:32:10 -03:00
|
|
|
|
Support multiple parallel logical message channels
The same server now can handle multiple logical channels, on which the
transmitter logic runs independently. That is, while previously a single
message would be in transmitting state at a time, now multiple messages
can be in transmitting state as long as they belong to distinct logical
channels.
The supported channels each have different permissions. The user channel
is where users can post, get, and delete messages as needed. In
contrast, the other channels do not grant all permissions to users. Some
are read-only (users can get but not post) and there is a channel (the
auth channel) on which users have no permissions (neither get nor post).
For the channels on which users do not have all permissions (get, post,
and delete), this patch adds admin-specific routes, which are prefixed
by /admin/. The /admin/ route is protected via SSL in production and
allows the admin host to send GET/POST/DELETE requests normally. Hence,
for instance, the admin host can post a message on the auth channel
(with POST /admin/order) and read it (with GET /admin/order) for
transmission over satellite, whereas regulars cannot. With this scheme,
the auth channel messages are accessible exclusively over satellite (and
not over the internet).
The admin routes were added to the following endpoints:
- /order/<uuid> (GET and DELETE requests)
- /order (POST request)
- /orders/<state> (GET request)
- /message/<tx_seq_num> (GET request)
The messages posted by the admin are not paid, so this patch removes the
requirement of invoice generation and payment. Only paid orders now
generate an invoice. Thus, the POST request to the /order/ endpoint does
not return an invoice for non-paid (admin-only) messages.
Also, this patch updates the queue page to display the orders separately
for each channel. The query string channel parameter determines which
channel the page shows.
Finally, this patch updates the events published into the Redis db on
transmission. The event includes the corresponding logical channel so
that SSE events can be subscribed independently for each channel.
2023-01-31 18:14:55 -03:00
|
|
|
return client.post(endpoint,
|
2021-12-21 16:32:10 -03:00
|
|
|
data=post_data,
|
2021-07-20 11:00:49 -03:00
|
|
|
content_type='multipart/form-data')
|
|
|
|
|
|
|
|
|
Support multiple parallel logical message channels
The same server now can handle multiple logical channels, on which the
transmitter logic runs independently. That is, while previously a single
message would be in transmitting state at a time, now multiple messages
can be in transmitting state as long as they belong to distinct logical
channels.
The supported channels each have different permissions. The user channel
is where users can post, get, and delete messages as needed. In
contrast, the other channels do not grant all permissions to users. Some
are read-only (users can get but not post) and there is a channel (the
auth channel) on which users have no permissions (neither get nor post).
For the channels on which users do not have all permissions (get, post,
and delete), this patch adds admin-specific routes, which are prefixed
by /admin/. The /admin/ route is protected via SSL in production and
allows the admin host to send GET/POST/DELETE requests normally. Hence,
for instance, the admin host can post a message on the auth channel
(with POST /admin/order) and read it (with GET /admin/order) for
transmission over satellite, whereas regulars cannot. With this scheme,
the auth channel messages are accessible exclusively over satellite (and
not over the internet).
The admin routes were added to the following endpoints:
- /order/<uuid> (GET and DELETE requests)
- /order (POST request)
- /orders/<state> (GET request)
- /message/<tx_seq_num> (GET request)
The messages posted by the admin are not paid, so this patch removes the
requirement of invoice generation and payment. Only paid orders now
generate an invoice. Thus, the POST request to the /order/ endpoint does
not return an invoice for non-paid (admin-only) messages.
Also, this patch updates the queue page to display the orders separately
for each channel. The query string channel parameter determines which
channel the page shows.
Finally, this patch updates the events published into the Redis db on
transmission. The event includes the corresponding logical channel so
that SSE events can be subscribed independently for each channel.
2023-01-31 18:14:55 -03:00
|
|
|
def place_order(client,
|
|
|
|
n_bytes,
|
|
|
|
regions=[],
|
|
|
|
bid=None,
|
|
|
|
channel=None,
|
|
|
|
admin=False):
|
2021-12-21 16:32:30 -03:00
|
|
|
if bid is None:
|
|
|
|
bid = bidding.get_min_bid(n_bytes)
|
2021-07-20 11:00:49 -03:00
|
|
|
msg = rnd_string(n_bytes)
|
Support multiple parallel logical message channels
The same server now can handle multiple logical channels, on which the
transmitter logic runs independently. That is, while previously a single
message would be in transmitting state at a time, now multiple messages
can be in transmitting state as long as they belong to distinct logical
channels.
The supported channels each have different permissions. The user channel
is where users can post, get, and delete messages as needed. In
contrast, the other channels do not grant all permissions to users. Some
are read-only (users can get but not post) and there is a channel (the
auth channel) on which users have no permissions (neither get nor post).
For the channels on which users do not have all permissions (get, post,
and delete), this patch adds admin-specific routes, which are prefixed
by /admin/. The /admin/ route is protected via SSL in production and
allows the admin host to send GET/POST/DELETE requests normally. Hence,
for instance, the admin host can post a message on the auth channel
(with POST /admin/order) and read it (with GET /admin/order) for
transmission over satellite, whereas regulars cannot. With this scheme,
the auth channel messages are accessible exclusively over satellite (and
not over the internet).
The admin routes were added to the following endpoints:
- /order/<uuid> (GET and DELETE requests)
- /order (POST request)
- /orders/<state> (GET request)
- /message/<tx_seq_num> (GET request)
The messages posted by the admin are not paid, so this patch removes the
requirement of invoice generation and payment. Only paid orders now
generate an invoice. Thus, the POST request to the /order/ endpoint does
not return an invoice for non-paid (admin-only) messages.
Also, this patch updates the queue page to display the orders separately
for each channel. The query string channel parameter determines which
channel the page shows.
Finally, this patch updates the events published into the Redis db on
transmission. The event includes the corresponding logical channel so
that SSE events can be subscribed independently for each channel.
2023-01-31 18:14:55 -03:00
|
|
|
return upload_test_file(client, msg, bid, regions, channel, admin)
|
2021-07-20 11:00:49 -03:00
|
|
|
|
|
|
|
|
|
|
|
def check_upload(order_uuid, expected_data):
|
|
|
|
path = os.path.join(constants.MSG_STORE_PATH, order_uuid)
|
|
|
|
assert os.path.exists(path)
|
|
|
|
|
|
|
|
with open(path) as fd:
|
|
|
|
upload_data = fd.read()
|
|
|
|
assert upload_data == expected_data
|
|
|
|
|
|
|
|
db_order = Order.query.filter_by(uuid=order_uuid).first()
|
|
|
|
assert db_order is not None
|
|
|
|
|
|
|
|
|
|
|
|
def check_invoice(generated_invoice, order_uuid):
|
|
|
|
db_order = Order.query.filter_by(uuid=order_uuid).first()
|
|
|
|
assert db_order is not None
|
|
|
|
db_invoice = \
|
|
|
|
Invoice.query.filter_by(lid=generated_invoice['id']).first()
|
|
|
|
assert db_invoice is not None
|
|
|
|
assert db_invoice.order_id == db_order.id
|
|
|
|
assert db_invoice.amount == db_order.unpaid_bid
|
|
|
|
|
|
|
|
|
2021-12-21 16:32:30 -03:00
|
|
|
def pay_invoice(invoice, client):
|
|
|
|
charged_auth_token = hmac_sha256_digest(constants.LIGHTNING_WEBHOOK_KEY,
|
|
|
|
invoice.lid)
|
|
|
|
rv = client.post(f'/callback/{invoice.lid}/{charged_auth_token}')
|
|
|
|
assert rv.status_code == HTTPStatus.OK
|
|
|
|
|
|
|
|
|
|
|
|
def confirm_tx(tx_seq_num, regions, client):
|
|
|
|
tx_rv = client.post(f'/order/tx/{tx_seq_num}', data={'regions': [regions]})
|
|
|
|
assert tx_rv.status_code == HTTPStatus.OK
|
|
|
|
|
|
|
|
|
2021-07-20 11:00:49 -03:00
|
|
|
def new_invoice(order_id, invoice_status, amount):
|
|
|
|
assert (isinstance(invoice_status, constants.InvoiceStatus))
|
|
|
|
lid = rnd_string(50)
|
|
|
|
return Invoice(
|
Extend the states returned by /orders/:state
Previously, the /orders/:state endpoint only returned the "pending",
"queued", and "sent" states. This patch adds the following new states:
"paid", "transmitting", "confirming", "rx-pending", "retransmitting",
and "received". These are mapped directly to the order status, except
for the "rx-pending" and "retransmitting" states, which are inferred
based on other information. The "rx-pending" state returns orders with
sent status only, as opposed to the call to /orders/sent, which returns
orders with sent and received status. The "retransmitting" state returns
any order with entries on the retransmission database.
2023-02-10 14:40:32 -03:00
|
|
|
id=random.randint(1, 1000000),
|
2021-07-20 11:00:49 -03:00
|
|
|
lid=lid,
|
|
|
|
invoice=json.dumps({
|
|
|
|
"id":
|
|
|
|
lid,
|
|
|
|
"msatoshi":
|
|
|
|
amount,
|
|
|
|
"description":
|
|
|
|
"BSS Test",
|
|
|
|
"rhash":
|
|
|
|
"94855ac3b06543",
|
|
|
|
"payreq":
|
|
|
|
"lntb100n1psfy",
|
|
|
|
"expires_at":
|
|
|
|
str(datetime.datetime.utcnow() +
|
|
|
|
datetime.timedelta(seconds=constants.LN_INVOICE_EXPIRY)),
|
|
|
|
"created_at":
|
|
|
|
str(datetime.datetime.utcnow()),
|
|
|
|
"metadata": {
|
|
|
|
"uuid": "7f9a5b81-5358-4be0-9af6-b8c6fbac9dcd",
|
|
|
|
"sha256_message_digest":
|
|
|
|
"a591a6d40bf420404a011733cfb7b190d62c6"
|
|
|
|
},
|
|
|
|
"status":
|
|
|
|
"unpaid"
|
|
|
|
}),
|
|
|
|
order_id=order_id,
|
|
|
|
status=invoice_status.value,
|
|
|
|
amount=amount,
|
|
|
|
expires_at=datetime.datetime.utcnow() +
|
|
|
|
datetime.timedelta(seconds=constants.LN_INVOICE_EXPIRY))
|
|
|
|
|
|
|
|
|
|
|
|
def generate_test_order(mock_new_invoice,
|
|
|
|
client,
|
|
|
|
order_status=None,
|
|
|
|
invoice_status=constants.InvoiceStatus.pending,
|
|
|
|
tx_seq_num=None,
|
|
|
|
n_bytes=500,
|
|
|
|
bid=None,
|
2021-12-21 16:32:10 -03:00
|
|
|
order_id=1,
|
2021-12-21 16:32:30 -03:00
|
|
|
regions=[],
|
Support multiple parallel logical message channels
The same server now can handle multiple logical channels, on which the
transmitter logic runs independently. That is, while previously a single
message would be in transmitting state at a time, now multiple messages
can be in transmitting state as long as they belong to distinct logical
channels.
The supported channels each have different permissions. The user channel
is where users can post, get, and delete messages as needed. In
contrast, the other channels do not grant all permissions to users. Some
are read-only (users can get but not post) and there is a channel (the
auth channel) on which users have no permissions (neither get nor post).
For the channels on which users do not have all permissions (get, post,
and delete), this patch adds admin-specific routes, which are prefixed
by /admin/. The /admin/ route is protected via SSL in production and
allows the admin host to send GET/POST/DELETE requests normally. Hence,
for instance, the admin host can post a message on the auth channel
(with POST /admin/order) and read it (with GET /admin/order) for
transmission over satellite, whereas regulars cannot. With this scheme,
the auth channel messages are accessible exclusively over satellite (and
not over the internet).
The admin routes were added to the following endpoints:
- /order/<uuid> (GET and DELETE requests)
- /order (POST request)
- /orders/<state> (GET request)
- /message/<tx_seq_num> (GET request)
The messages posted by the admin are not paid, so this patch removes the
requirement of invoice generation and payment. Only paid orders now
generate an invoice. Thus, the POST request to the /order/ endpoint does
not return an invoice for non-paid (admin-only) messages.
Also, this patch updates the queue page to display the orders separately
for each channel. The query string channel parameter determines which
channel the page shows.
Finally, this patch updates the events published into the Redis db on
transmission. The event includes the corresponding logical channel so
that SSE events can be subscribed independently for each channel.
2023-01-31 18:14:55 -03:00
|
|
|
started_transmission_at=None,
|
|
|
|
channel=None,
|
|
|
|
admin=False):
|
2021-07-20 11:00:49 -03:00
|
|
|
"""Generate a valid order and add it to the database
|
|
|
|
|
|
|
|
This function generates an order with a related invoice with
|
|
|
|
given parameters and stores them in the database.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
mock_new_invoice: A python mock for simulation
|
|
|
|
orders.new_invoice function
|
|
|
|
client: Flask client used to send api calls
|
|
|
|
order_status: status to be set for the generated order,
|
Extend the states returned by /orders/:state
Previously, the /orders/:state endpoint only returned the "pending",
"queued", and "sent" states. This patch adds the following new states:
"paid", "transmitting", "confirming", "rx-pending", "retransmitting",
and "received". These are mapped directly to the order status, except
for the "rx-pending" and "retransmitting" states, which are inferred
based on other information. The "rx-pending" state returns orders with
sent status only, as opposed to the call to /orders/sent, which returns
orders with sent and received status. The "retransmitting" state returns
any order with entries on the retransmission database.
2023-02-10 14:40:32 -03:00
|
|
|
default input value is None but in the
|
2021-07-20 11:00:49 -03:00
|
|
|
database it will be set to pending
|
|
|
|
invoice_status: status to be set for the generated invoice,
|
|
|
|
default is pending
|
|
|
|
tx_seq_num: tx_seq_num value to be set for the generated
|
|
|
|
order, default value is None
|
|
|
|
n_bytes: length of generated message
|
|
|
|
bid: amount of bid, default value is None, if None a minimum
|
|
|
|
valid value will be set
|
|
|
|
order_id: the id to be used when connecting invoice to an
|
|
|
|
order, default value is 1
|
2021-12-21 16:32:10 -03:00
|
|
|
regions: list of regions over which this order should be
|
|
|
|
transmitted. The default value is an empty list implying
|
|
|
|
the order should be sent over all regions.
|
Support multiple parallel logical message channels
The same server now can handle multiple logical channels, on which the
transmitter logic runs independently. That is, while previously a single
message would be in transmitting state at a time, now multiple messages
can be in transmitting state as long as they belong to distinct logical
channels.
The supported channels each have different permissions. The user channel
is where users can post, get, and delete messages as needed. In
contrast, the other channels do not grant all permissions to users. Some
are read-only (users can get but not post) and there is a channel (the
auth channel) on which users have no permissions (neither get nor post).
For the channels on which users do not have all permissions (get, post,
and delete), this patch adds admin-specific routes, which are prefixed
by /admin/. The /admin/ route is protected via SSL in production and
allows the admin host to send GET/POST/DELETE requests normally. Hence,
for instance, the admin host can post a message on the auth channel
(with POST /admin/order) and read it (with GET /admin/order) for
transmission over satellite, whereas regulars cannot. With this scheme,
the auth channel messages are accessible exclusively over satellite (and
not over the internet).
The admin routes were added to the following endpoints:
- /order/<uuid> (GET and DELETE requests)
- /order (POST request)
- /orders/<state> (GET request)
- /message/<tx_seq_num> (GET request)
The messages posted by the admin are not paid, so this patch removes the
requirement of invoice generation and payment. Only paid orders now
generate an invoice. Thus, the POST request to the /order/ endpoint does
not return an invoice for non-paid (admin-only) messages.
Also, this patch updates the queue page to display the orders separately
for each channel. The query string channel parameter determines which
channel the page shows.
Finally, this patch updates the events published into the Redis db on
transmission. The event includes the corresponding logical channel so
that SSE events can be subscribed independently for each channel.
2023-01-31 18:14:55 -03:00
|
|
|
channel: Logical channel on which to transmit the order.
|
|
|
|
admin: Whether to post the order via the /admin/order route.
|
2021-07-20 11:00:49 -03:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
The json response of the create order endpoint.
|
|
|
|
|
|
|
|
"""
|
|
|
|
assert (isinstance(invoice_status, constants.InvoiceStatus))
|
|
|
|
|
|
|
|
if not bid:
|
|
|
|
bid = bidding.get_min_bid(n_bytes)
|
|
|
|
|
|
|
|
mock_new_invoice.return_value = (True,
|
|
|
|
new_invoice(order_id, invoice_status,
|
|
|
|
bid))
|
Support multiple parallel logical message channels
The same server now can handle multiple logical channels, on which the
transmitter logic runs independently. That is, while previously a single
message would be in transmitting state at a time, now multiple messages
can be in transmitting state as long as they belong to distinct logical
channels.
The supported channels each have different permissions. The user channel
is where users can post, get, and delete messages as needed. In
contrast, the other channels do not grant all permissions to users. Some
are read-only (users can get but not post) and there is a channel (the
auth channel) on which users have no permissions (neither get nor post).
For the channels on which users do not have all permissions (get, post,
and delete), this patch adds admin-specific routes, which are prefixed
by /admin/. The /admin/ route is protected via SSL in production and
allows the admin host to send GET/POST/DELETE requests normally. Hence,
for instance, the admin host can post a message on the auth channel
(with POST /admin/order) and read it (with GET /admin/order) for
transmission over satellite, whereas regulars cannot. With this scheme,
the auth channel messages are accessible exclusively over satellite (and
not over the internet).
The admin routes were added to the following endpoints:
- /order/<uuid> (GET and DELETE requests)
- /order (POST request)
- /orders/<state> (GET request)
- /message/<tx_seq_num> (GET request)
The messages posted by the admin are not paid, so this patch removes the
requirement of invoice generation and payment. Only paid orders now
generate an invoice. Thus, the POST request to the /order/ endpoint does
not return an invoice for non-paid (admin-only) messages.
Also, this patch updates the queue page to display the orders separately
for each channel. The query string channel parameter determines which
channel the page shows.
Finally, this patch updates the events published into the Redis db on
transmission. The event includes the corresponding logical channel so
that SSE events can be subscribed independently for each channel.
2023-01-31 18:14:55 -03:00
|
|
|
post_rv = place_order(client, n_bytes, regions, bid, channel, admin)
|
2021-07-20 11:00:49 -03:00
|
|
|
assert post_rv.status_code == HTTPStatus.OK
|
|
|
|
uuid = post_rv.get_json()['uuid']
|
|
|
|
# Set order's sequence number and status
|
|
|
|
db_order = Order.query.filter_by(uuid=uuid).first()
|
2021-12-21 16:32:30 -03:00
|
|
|
|
2021-07-20 11:00:49 -03:00
|
|
|
if order_status:
|
|
|
|
assert (isinstance(order_status, constants.OrderStatus))
|
|
|
|
db_order.status = order_status.value
|
2021-12-21 16:32:30 -03:00
|
|
|
|
2021-07-20 11:00:49 -03:00
|
|
|
if tx_seq_num:
|
|
|
|
db_order.tx_seq_num = tx_seq_num
|
|
|
|
|
2021-12-21 16:32:30 -03:00
|
|
|
if started_transmission_at:
|
|
|
|
db_order.started_transmission_at = started_transmission_at
|
|
|
|
|
2021-07-20 11:00:49 -03:00
|
|
|
db.session.commit()
|
|
|
|
return post_rv.get_json()
|