Skip to content

Commit

Permalink
Merge pull request #57 from derekpierre/bears
Browse files Browse the repository at this point in the history
Documentation updates + nginx cleanup
  • Loading branch information
derekpierre authored Dec 13, 2023
2 parents 8254bf3 + f0998d4 commit f0f8828
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 107 deletions.
100 changes: 77 additions & 23 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ operate their own.
Running a Porter Instance
-------------------------

By default, Porter runs on port ``9155``.

Security Considerations
***********************

Expand All @@ -39,16 +41,49 @@ Security Considerations


.. note::

Ideally, you would run Porter behind a reverse proxy (e.g. `nginx <https://www.nginx.com/>`_) for additional
functionality such as HTTPS, CORS, authentication etc.
Managing a Porter instance on ``mainnet`` requires solid server
administration skills. This includes understanding how to provision and
secure servers, applying security best practices, and maintaining
consistent system performance. Key competencies like network configuration,
SSL/TLS encryption, and CORS, are also essential to ensure the
secure and efficient operation of your Porter instance.

.. warning::

By default, Porter runs over HTTP. However, Porter instances must be
secured with a valid HTTPS certificate in order to be compatible with
network applications. A Porter instance running without SSL/TLS is not
only insecure but also browser-based apps and websites will be
unable to connect.

To secure your Porter instance with HTTPS, use a reverse proxy
like `Nginx <https://www.nginx.com/>`_ or
`Apache <https://httpd.apache.org/docs/2.4/ssl/ssl_howto.html>`_ for SSL
processing, and potentially `Let's Encrypt <https://letsencrypt.org/>`_
for automated SSL certificate issuance and renewal. Additionally, consider
using cloud-based services like AWS/Digital Ocean load balancers or
Cloudflare for SSL termination and enhanced security.


Configurable Operation Timeouts
*******************************
Some Porter endpoints allow optional integer timeouts to be specified as a
parameter. However, to prevent DDOS attacks, timeouts are capped. By default
the ``/decrypt`` and ``/get_ursulas`` endpoints limit their timeouts at 15s. If
the optional timeout parameter is not provided or the provided timeout
parameter value is greater than the default timeout, the timeout used for the
operation will be the default timeout.

If modifying the default timeout values is desirable, they can be configured
via environment variables:

* ``PORTER_MAX_DECRYPTION_TIMEOUT`` for ``/decrypt`` operations
* ``PORTER_MAX_GET_URSULAS_TIMEOUT`` for ``/get_ursulas`` operations


Run via Docker
**************

By default, Porter runs on port ``9155``.

#. Get the latest ``porter`` image:

.. code:: bash
Expand All @@ -66,7 +101,8 @@ By default, Porter runs on port ``9155``.
--restart=unless-stopped \
nucypher/porter:latest \
nucypher-porter run \
--eth-endpoint <YOUR WEB3 PROVIDER URI> \
--eth-endpoint <YOUR ETH WEB3 PROVIDER URI> \
--polygon-endpoint <YOUR POLYGON WEB3 PROVIDER URI> \
--domain <TACO DOMAIN>
The command above is for illustrative purposes and can be modified as
Expand Down Expand Up @@ -113,7 +149,7 @@ For a full list of CLI options after installation ``nucypher-porter``, run:
* Run Porter service via HTTP
.. code:: console
$ nucypher-porter run --eth-endpoint <YOUR WEB3 PROVIDER URI> --domain <TACO DOMAIN>
$ nucypher-porter run --eth-endpoint <YOUR ETH WEB3 PROVIDER URI> --polygon-endpoint <YOUR POLYGON WEB3 PROVIDER URI> --domain <TACO DOMAIN>
______
Expand All @@ -127,6 +163,7 @@ For a full list of CLI options after installation ``nucypher-porter``, run:
TACo Domain: <TACO DOMAIN>
ETH Endpoint URI: ...
Polygon Endpoint URI: ...
Running Porter Web Controller at http://127.0.0.1:9155
Expand Down Expand Up @@ -205,6 +242,15 @@ Parameters
| ``encrypted_decryption_requests`` | Dict[String, String] | | Base64 encoded encrypted decryption requests |
| | | | keyed by node staking provider address. |
+-----------------------------------+----------------------+------------------------------------------------+
| ``timeout`` | *(Optional)* int | | The timeout for the operation. Default value |
| | | | is 15s unless the Porter instance is |
| | | | configured to modify the default setting via |
| | | | the ``PORTER_MAX_DECRYPTION_TIMEOUT`` env |
| | | | variable on startup. Timeouts provided that |
| | | | are greater than this max default value are |
| | | | capped at the default value |
+-----------------------------------+----------------------+------------------------------------------------+


Returns
^^^^^^^
Expand Down Expand Up @@ -256,7 +302,7 @@ Example Response
}
}
},
"version":"1.0.0"
"version": "3.3.0"
}
.. note::
Expand All @@ -272,19 +318,27 @@ and associated information.

Parameters
^^^^^^^^^^
+----------------------------------+---------------+-----------------------------------------------+
| **Parameter** | **Type** | **Description** |
+==================================+===============+===============================================+
| ``quantity`` | Integer | Number of total TACo nodes to return. |
+----------------------------------+---------------+-----------------------------------------------+
| ``include_ursulas`` *(Optional)* | List[String] | | List of Ursula checksum addresses to |
| | | | give preference to. If any of these Ursulas |
| | | | are unavailable, they will not be included |
| | | | in result. |
+----------------------------------+---------------+-----------------------------------------------+
| ``exclude_ursulas`` *(Optional)* | List[String] | | List of Ursula checksum addresses to not |
| | | | include in the result. |
+----------------------------------+---------------+-----------------------------------------------+
+----------------------------------+------------------+------------------------------------------------+
| **Parameter** | **Type** | **Description** |
+==================================+==================+================================================+
| ``quantity`` | Integer | Number of total TACo nodes to return. |
+----------------------------------+------------------+------------------------------------------------+
| ``include_ursulas`` *(Optional)* | List[String] | | List of Ursula checksum addresses to |
| | | | give preference to. If any of these Ursulas |
| | | | are unavailable, they will not be included |
| | | | in result. |
+----------------------------------+------------------+------------------------------------------------+
| ``exclude_ursulas`` *(Optional)* | List[String] | | List of Ursula checksum addresses to not |
| | | | include in the result. |
+----------------------------------+------------------+------------------------------------------------+
| ``timeout`` | *(Optional)* int | | The timeout for the operation. Default value |
| | | | is 15s unless the Porter instance is |
| | | | configured to modify the default setting via |
| | | | the ``PORTER_MAX_GET_URSULAS_TIMEOUT`` env |
| | | | variable on startup. Timeouts provided that |
| | | | are greater than this max default value are |
| | | | capped at the default value |
+----------------------------------+------------------+------------------------------------------------+


Returns
Expand Down Expand Up @@ -351,7 +405,7 @@ Example Response
}
]
},
"version": "1.0.0"
"version": "3.3.0"
}
Expand Down Expand Up @@ -455,5 +509,5 @@ Example Response
}
]
},
"version": "1.0.0"
"version": "3.3.0"
}
6 changes: 3 additions & 3 deletions deploy/docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ services:
- .:/code
- ~/.local/share/nucypher:/nucypher
command: ["nucypher-porter", "run",
"--eth-endpoint", "${WEB3_PROVIDER_URI}",
"--domain", "${NUCYPHER_NETWORK}",
"--allow-origins", "${PORTER_CORS_ALLOW_ORIGINS}"] # empty string if env var not defined which translates to CORS not enabled by default
"--eth-endpoint", "${ETH_WEB3_PROVIDER_URI}",
"--polygon-endpoint", "${POLY_WEB3_PROVIDER_URI}",
"--domain", "${TACO_DOMAIN}"]
4 changes: 0 additions & 4 deletions deploy/docker/nginx/Dockerfile

This file was deleted.

38 changes: 0 additions & 38 deletions deploy/docker/nginx/docker-compose.yml

This file was deleted.

19 changes: 0 additions & 19 deletions deploy/docker/nginx/porter.local_location

This file was deleted.

42 changes: 22 additions & 20 deletions porter/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os
from pathlib import Path
from typing import Dict, List, NamedTuple, Optional, Sequence
from typing import Dict, List, NamedTuple, Optional, Sequence, Union

from constant_sorrow.constants import NO_CONTROL_PROTOCOL
from eth_typing import ChecksumAddress
Expand Down Expand Up @@ -56,7 +56,7 @@ class Porter(Learner):

DEFAULT_PORT = 9155

MAX_GET_URSULAS_TIMEOUT = os.getenv("PORTER_GET_URSULAS_TIMEOUT", default=15)
MAX_GET_URSULAS_TIMEOUT = os.getenv("PORTER_MAX_GET_URSULAS_TIMEOUT", default=15)
MAX_DECRYPTION_TIMEOUT = os.getenv(
"PORTER_MAX_DECRYPTION_TIMEOUT",
default=ThresholdDecryptionClient.DEFAULT_DECRYPTION_TIMEOUT,
Expand Down Expand Up @@ -152,15 +152,9 @@ def get_ursulas(
include_ursulas: Optional[Sequence[ChecksumAddress]] = None,
timeout: Optional[int] = None,
) -> List[UrsulaInfo]:
if timeout and timeout > self.MAX_GET_URSULAS_TIMEOUT:
self.log.warn(
f"Provided sampling timeout ({timeout}s) exceeds "
f"maximum ({self.MAX_GET_URSULAS_TIMEOUT}s); "
f"using {self.MAX_GET_URSULAS_TIMEOUT}s instead"
)
timeout = self.MAX_GET_URSULAS_TIMEOUT
else:
timeout = timeout or self.MAX_GET_URSULAS_TIMEOUT
timeout = self._configure_timeout(
"sampling", timeout, self.MAX_GET_URSULAS_TIMEOUT
)

reservoir = self._make_reservoir(exclude_ursulas, include_ursulas)
available_nodes_to_sample = len(reservoir.values) + len(reservoir.reservoir)
Expand Down Expand Up @@ -244,15 +238,9 @@ def decrypt(
timeout: Optional[int] = None,
) -> DecryptOutcome:
decryption_client = ThresholdDecryptionClient(self)
if timeout and timeout > self.MAX_DECRYPTION_TIMEOUT:
self.log.warn(
f"Provided decryption timeout ({timeout}s) exceeds "
f"maximum ({self.MAX_DECRYPTION_TIMEOUT}s); "
f"using {self.MAX_DECRYPTION_TIMEOUT}s instead"
)
timeout = self.MAX_DECRYPTION_TIMEOUT
else:
timeout = timeout or self.MAX_DECRYPTION_TIMEOUT
timeout = self._configure_timeout(
"decryption", timeout, self.MAX_DECRYPTION_TIMEOUT
)

successes, failures = decryption_client.gather_encrypted_decryption_shares(
encrypted_requests=encrypted_decryption_requests,
Expand All @@ -265,6 +253,20 @@ def decrypt(
)
return decrypt_outcome

def _configure_timeout(
self, operation: str, timeout: Union[int, None], max_timeout: int
):
if timeout and timeout > max_timeout:
self.log.warn(
f"Provided {operation} timeout ({timeout}s) exceeds "
f"maximum ({max_timeout}s); "
f"using {max_timeout}s instead"
)
timeout = max_timeout
else:
timeout = timeout or max_timeout
return timeout

def _make_reservoir(
self,
exclude_ursulas: Optional[Sequence[ChecksumAddress]] = None,
Expand Down
45 changes: 45 additions & 0 deletions tests/test_porter_configure_timeout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import pytest

from porter.main import Porter


@pytest.mark.parametrize(
"provided_timeout,max_timeout,expected_timeout",
[
(None, 10, 10),
(1, 10, 1),
(5, 10, 5),
(9, 10, 9),
(10, 10, 10),
(11, 10, 10),
(20, 10, 10),
(25, 10, 10),
(
Porter.MAX_GET_URSULAS_TIMEOUT - 1,
Porter.MAX_GET_URSULAS_TIMEOUT,
Porter.MAX_GET_URSULAS_TIMEOUT - 1,
),
(
Porter.MAX_GET_URSULAS_TIMEOUT + 1,
Porter.MAX_GET_URSULAS_TIMEOUT,
Porter.MAX_GET_URSULAS_TIMEOUT,
),
(
Porter.MAX_DECRYPTION_TIMEOUT / 2,
Porter.MAX_DECRYPTION_TIMEOUT,
Porter.MAX_DECRYPTION_TIMEOUT / 2,
),
(
Porter.MAX_DECRYPTION_TIMEOUT * 2,
Porter.MAX_DECRYPTION_TIMEOUT,
Porter.MAX_DECRYPTION_TIMEOUT,
),
],
)
def test_porter_configure_timeout(
porter, provided_timeout, max_timeout, expected_timeout
):
resultant_timeout = porter._configure_timeout(
operation="test", timeout=provided_timeout, max_timeout=max_timeout
)
assert resultant_timeout == expected_timeout

0 comments on commit f0f8828

Please sign in to comment.