Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[entropy] Update readmes and docs #1163

Merged
merged 2 commits into from
Dec 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions fortuna/README.md
Original file line number Diff line number Diff line change
@@ -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 <chain id> --secret <secret> --private-key <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 <secret> --provider <provider>
```

This command will start the webservice on `localhost:34000`.
1 change: 0 additions & 1 deletion fortuna/src/config/register_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
29 changes: 14 additions & 15 deletions target_chains/ethereum/contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:

Expand Down
15 changes: 8 additions & 7 deletions target_chains/ethereum/contracts/contracts/entropy/Entropy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Loading