From 3c67dc0432ce3f424d7dc34fa05b57391c367727 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Sat, 2 Dec 2023 13:09:37 -0800 Subject: [PATCH 1/2] add some docs --- fortuna/README.md | 40 ++++++++++++++++++++++ fortuna/src/config/register_provider.rs | 1 - target_chains/ethereum/contracts/README.md | 29 ++++++++-------- 3 files changed, 54 insertions(+), 16 deletions(-) create mode 100644 fortuna/README.md diff --git a/fortuna/README.md b/fortuna/README.md new file mode 100644 index 0000000000..53b0b6b1c0 --- /dev/null +++ b/fortuna/README.md @@ -0,0 +1,40 @@ +# Fortuna + +Fortuna is a webservice that serves random numbers according to the Entropy protocol. +The webservice generates a hash chain of random numbers and reveals them to callers when permitted by the protocol. +The hash chain is generated from a secret key that is provided to the server on startup. + +A single instance of this webservice can simultaneously serve random numbers for several different blockchains. +Each blockchain is configured in `config.yaml`. + +## Build & Test + +Fortuna uses Cargo for building and dependency management. +Simply run `cargo build` and `cargo test` to build and test the project. + +## Command-Line Interface + +The Fortuna binary has a command-line interface to perform useful operations on the contract, such as +registering a new randomness provider, or drawing a random value. To see the available commands, simply run `cargo run`. + +## Local Development + +To start an instance of the webserver for local testing, you first need to perform a few setup steps: + +1. Edit `config.yaml` to point to the desired blockchains and Entropy contracts. +1. Generate a secret key. The secret key is a 32-byte random value used to construct the hash chains. + You can generate this value using the `openssl` command: + `openssl rand -hex 32` +1. Generate an ethereum wallet for the provider. You can do this in foundry using `cast wallet new`. + Note both the private key and the address; you will need both for subsequent steps. +1. Register a randomness provider for this service: `cargo run -- register-provider --chain-id --secret --private-key `. + The chain id is the key of the blockchain in `config.yaml`, the secret is from step (2), and the private key is from step (3). + Note that you need to run this command once per blockchain configured in `config.yaml`. + +Once you've completed the setup, simply run the following command, using the secret from step (2) and the wallet address from step (3) as the provider: + +```bash +cargo run -- run --secret --provider +``` + +This command will start the webservice on `localhost:34000`. diff --git a/fortuna/src/config/register_provider.rs b/fortuna/src/config/register_provider.rs index c6281cdc61..b971dc2cae 100644 --- a/fortuna/src/config/register_provider.rs +++ b/fortuna/src/config/register_provider.rs @@ -26,7 +26,6 @@ pub struct RegisterProviderOptions { /// This key is required to submit transactions (such as registering with the contract). #[arg(long = "private-key")] #[arg(env = "PRIVATE_KEY")] - #[arg(default_value = None)] pub private_key: String, #[command(flatten)] diff --git a/target_chains/ethereum/contracts/README.md b/target_chains/ethereum/contracts/README.md index b2a64157f6..aadbff42c3 100644 --- a/target_chains/ethereum/contracts/README.md +++ b/target_chains/ethereum/contracts/README.md @@ -4,30 +4,29 @@ This directory contains The Pyth contract on Ethereum and utilities to deploy it ## Installation -Run the following command on the repo root to install required dependencies for the contract: +The contracts are built and tested using Foundry. Follow the [Foundry installation instructions](https://book.getfoundry.sh/getting-started/installation) to install it if you do not already have it. + +Next, run the following command from the repo root to install required dependencies for the contract: ``` npm ci npx lerna run build --scope="@pythnetwork/pyth-evm-contract" --include-dependencies ``` -## Foundry - -Foundry can be installed by the official installer, or by running our helper script which will automatically pull the correct installation script individually for Foundry and the Solidity compiler for your current OS. This may work better if you are running into networking/firewall issues using Foundry's Solidity installer. To use helper script, run the command below from this directory: - -```sh -pyth-crosschain/target_chains/ethereum/contracts $ bash ../../../scripts/install-foundry.sh -``` - -You need to install npm dependencies as described in [Installation](#installation). Also, you need to run the following -command in the `contracts` directory to install forge dependencies: +Next, from the `contracts` directory, run the following command to install forge dependencies: ``` npm run install-forge-deps ``` -After installing the dependencies. Run `forge build` to build the contracts and `forge test` to -test the contracts using tests in `forge-test` directory. To see line by line test coverage: +## Testing + +Run `forge build` to build the contracts and `forge test` to run the contract unit tests. +The unit tests live in the `forge-test` directory. + +### Code Coverage + +To see line-by-line test coverage: ``` npm run coverage @@ -57,9 +56,9 @@ cp .env.test .env && npx truffle compile --all && npx truffle migrate npm run test-contract ``` -### Gas Benchmark +### Gas Benchmarks -You can use foundry to run benchmark tests written in [`forge-test/GasBenchmark.t.sol`](./forge-test/GasBenchmark.t.sol). To run the tests with gas report +You can use foundry to run gas benchmark tests (which can be found in the `forge-test` directory). To run the tests with gas report you can run `forge test --gas-report --match-contract GasBenchmark`. However, as there are multiple benchmarks, this might not be useful. You can run a specific benchmark test by passing the test name using `--match-test`. A full command to run `testBenchmarkUpdatePriceFeedsFresh` benchmark test is like this: From d5acc33eba9810c5961c27f6c84e2fccdb8e48d6 Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Sat, 2 Dec 2023 13:15:47 -0800 Subject: [PATCH 2/2] more doc edits --- .../contracts/contracts/entropy/Entropy.sol | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/target_chains/ethereum/contracts/contracts/entropy/Entropy.sol b/target_chains/ethereum/contracts/contracts/entropy/Entropy.sol index 377dd590bb..58f542067d 100644 --- a/target_chains/ethereum/contracts/contracts/entropy/Entropy.sol +++ b/target_chains/ethereum/contracts/contracts/entropy/Entropy.sol @@ -38,14 +38,15 @@ import "./EntropyState.sol"; // of the provider's random numbers the user will receive. // 3. The user submits an off-chain request (e.g. via HTTP) to the provider to reveal the i'th random number. // 4. The provider checks the on-chain sequence number and ensures it is > i. If it is not, the provider -// refuses to reveal the ith random number. +// refuses to reveal the ith random number. The provider should wait for a sufficient number of block confirmations +// to ensure that the request does not get re-orged out of the blockchain. // 5. The provider reveals x_i to the user. // 6. The user submits both the provider's revealed number x_i and their own x_U to the contract. // 7. The contract verifies hash(x_i) == x_{i-1} to prove that x_i is the i'th random number. The contract also checks that hash(x_U) == h_U. // The contract stores x_i as the i'th random number to reuse for future verifications. // 8. If both of the above conditions are satisfied, the random number r = hash(x_i, x_U). -// (Optional) as an added security mechanism, this step can further incorporate the blockhash of the request transaction, -// r = hash(x_i, x_U, blockhash). +// (Optional) as an added security mechanism, this step can further incorporate the blockhash of the block that the +// request transaction landed in: r = hash(x_i, x_U, blockhash). // // This protocol has the same security properties as the 2-party randomness protocol above: as long as either // the provider or user is honest, the number r is random. Honesty here means that the participant keeps their @@ -63,12 +64,12 @@ import "./EntropyState.sol"; // random number. Verification therefore may require computing multiple hashes (~ the number of concurrent requests). // Second, the implementation allows providers to rotate their commitment at any time. This operation allows // providers to commit to additional random numbers once they reach the end of their initial sequence, or rotate out -// a compromised sequence. On rotation, any in-flight requests are continue to use the pre-rotation commitment. -// Each commitment has a metadata field that providers can use to determine which commitment a request is for. -// Providers *must* retrieve the metadata for a request from the blockchain itself to prevent user manipulation of this field. +// a compromised sequence. On rotation, any in-flight requests continue to use the pre-rotation commitment. +// Providers can use the sequence number of the request along with the event log of their registrations to determine +// which hash chain contains the requested random number. // // Warning to integrators: -// An important caveat for users of this protocol is that the user can compute the random number r before +// An important caveat of this protocol is that the user can compute the random number r before // revealing their own number to the contract. This property means that the user can choose to halt the // protocol prior to the random number being revealed (i.e., prior to step (6) above). Integrators should ensure that // the user is always incentivized to reveal their random number, and that the protocol has an escape hatch for