Fortuna CI workflows (#1120)

* CI and docker

* cleanup

* erc

* whoops
This commit is contained in:
Jayant Krishnamurthy 2023-10-20 10:49:41 -07:00 committed by GitHub
parent d87cd7c5fd
commit 4776bdcdf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 138 additions and 44 deletions

20
.github/workflows/ci-fortuna.yml vendored Normal file
View File

@ -0,0 +1,20 @@
name: Check Fortuna
on:
pull_request:
paths: [fortuna/**]
push:
branches: [main]
paths: [fortuna/**]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly-2023-07-23
override: true
- name: Run executor tests
run: cargo test --manifest-path ./fortuna/Cargo.toml

View File

@ -0,0 +1,44 @@
name: Build and Push Fortuna Image
on:
push:
tags:
- fortuna-v*
workflow_dispatch:
inputs:
dispatch_description:
description: "Dispatch description"
required: true
type: string
permissions:
contents: read
id-token: write
jobs:
fortuna-image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set image tag to version of the git tag
if: ${{ startsWith(github.ref, 'refs/tags/fortuna-v') }}
run: |
PREFIX="refs/tags/fortuna-"
VERSION="${GITHUB_REF:${#PREFIX}}"
echo "IMAGE_TAG=${VERSION}" >> "${GITHUB_ENV}"
- name: Set image tag to the git commit hash
if: ${{ !startsWith(github.ref, 'refs/tags/fortuna-v') }}
run: |
echo "IMAGE_TAG=${{ github.sha }}" >> "${GITHUB_ENV}"
- uses: aws-actions/configure-aws-credentials@8a84b07f2009032ade05a88a28750d733cc30db1
with:
role-to-assume: arn:aws:iam::192824654885:role/github-actions-ecr
aws-region: eu-west-2
- uses: docker/login-action@v2
with:
registry: public.ecr.aws
env:
AWS_REGION: us-east-1
- run: |
DOCKER_BUILDKIT=1 docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f fortuna/Dockerfile .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
env:
ECR_REGISTRY: public.ecr.aws
ECR_REPOSITORY: pyth-network/fortuna

62
fortuna/Cargo.lock generated
View File

@ -1387,6 +1387,36 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "fortuna"
version = "0.1.0"
dependencies = [
"anyhow",
"axum",
"axum-macros",
"base64 0.21.4",
"byteorder",
"clap",
"ethabi",
"ethers",
"hex",
"prometheus-client",
"pythnet-sdk",
"rand",
"reqwest",
"serde",
"serde_json",
"serde_qs",
"serde_yaml",
"sha3",
"tokio",
"tower-http",
"tracing",
"tracing-subscriber",
"utoipa",
"utoipa-swagger-ui",
]
[[package]] [[package]]
name = "fs2" name = "fs2"
version = "0.4.3" version = "0.4.3"
@ -2660,40 +2690,10 @@ dependencies = [
"syn 2.0.38", "syn 2.0.38",
] ]
[[package]]
name = "pyth-rng"
version = "0.1.0"
dependencies = [
"anyhow",
"axum",
"axum-macros",
"base64 0.21.4",
"byteorder",
"clap",
"ethabi",
"ethers",
"hex",
"prometheus-client",
"pythnet-sdk",
"rand",
"reqwest",
"serde",
"serde_json",
"serde_qs",
"serde_yaml",
"sha3",
"tokio",
"tower-http",
"tracing",
"tracing-subscriber",
"utoipa",
"utoipa-swagger-ui",
]
[[package]] [[package]]
name = "pythnet-sdk" name = "pythnet-sdk"
version = "2.0.0" version = "2.0.0"
source = "git+https://github.com/pyth-network/pyth-crosschain#1a64d58834ac4bf6cd9b35ff5e72424c66a23301" source = "git+https://github.com/pyth-network/pyth-crosschain#d87cd7c5fdcf371837b7aa41dee35a04cdd6731d"
dependencies = [ dependencies = [
"bincode", "bincode",
"borsh", "borsh",

19
fortuna/Dockerfile Normal file
View File

@ -0,0 +1,19 @@
ARG RUST_VERSION=1.66.1
FROM rust:${RUST_VERSION} AS build
# Set default toolchain
RUN rustup default nightly-2023-07-23
# Build
WORKDIR /src
COPY fortuna fortuna
WORKDIR /src/fortuna
RUN --mount=type=cache,target=/root/.cargo/registry cargo build --release
FROM rust:${RUST_VERSION}
# Copy artifacts from other images
COPY --from=build /src/fortuna/target/release/fortuna /usr/local/bin/

View File

@ -8,6 +8,10 @@ use {
ethereum::SignablePythContract, ethereum::SignablePythContract,
}, },
anyhow::Result, anyhow::Result,
base64::{
engine::general_purpose::STANDARD as base64_standard_engine,
Engine as _,
},
std::sync::Arc, std::sync::Arc,
}; };
@ -40,7 +44,10 @@ pub async fn generate(opts: &GenerateOptions) -> Result<()> {
.json::<GetRandomValueResponse>() .json::<GetRandomValueResponse>()
.await?; .await?;
tracing::info!(response = resp, "Retrieved the provider's random value.",); tracing::info!(
response = base64_standard_engine.encode(resp.value),
"Retrieved the provider's random value.",
);
let provider_randomness = resp.value; let provider_randomness = resp.value;
// Submit the provider's and our values to the contract to reveal the random number. // Submit the provider's and our values to the contract to reveal the random number.
@ -53,7 +60,10 @@ pub async fn generate(opts: &GenerateOptions) -> Result<()> {
) )
.await?; .await?;
tracing::info!(number = random_value, "Random number generated."); tracing::info!(
number = base64_standard_engine.encode(random_value),
"Random number generated."
);
Ok(()) Ok(())
} }

View File

@ -64,7 +64,7 @@ pub enum Options {
pub struct ConfigOptions { pub struct ConfigOptions {
/// Path to a configuration file containing the list of supported blockchains /// Path to a configuration file containing the list of supported blockchains
#[arg(long = "config")] #[arg(long = "config")]
#[arg(env = "PYTH_CONFIG")] #[arg(env = "FORTUNA_CONFIG")]
#[arg(default_value = "config.yaml")] #[arg(default_value = "config.yaml")]
pub config: String, pub config: String,
} }
@ -75,13 +75,13 @@ pub struct ConfigOptions {
pub struct RandomnessOptions { pub struct RandomnessOptions {
/// A secret used for generating new hash chains. A 64-char hex string. /// A secret used for generating new hash chains. A 64-char hex string.
#[arg(long = "secret")] #[arg(long = "secret")]
#[arg(env = "PYTH_SECRET")] #[arg(env = "FORTUNA_SECRET")]
#[arg(default_value = "0000000000000000000000000000000000000000000000000000000000000000")] #[arg(default_value = "0000000000000000000000000000000000000000000000000000000000000000")]
pub secret: String, pub secret: String,
/// The length of the hash chain to generate. /// The length of the hash chain to generate.
#[arg(long = "chain-length")] #[arg(long = "chain-length")]
#[arg(env = "PYTH_CHAIN_LENGTH")] #[arg(env = "FORTUNA_CHAIN_LENGTH")]
#[arg(default_value = "32")] #[arg(default_value = "32")]
pub chain_length: u64, pub chain_length: u64,
} }

View File

@ -17,7 +17,7 @@ pub struct GenerateOptions {
/// Retrieve a randomness request to this provider /// Retrieve a randomness request to this provider
#[arg(long = "chain-id")] #[arg(long = "chain-id")]
#[arg(env = "PYTH_CHAIN_ID")] #[arg(env = "FORTUNA_CHAIN_ID")]
pub chain_id: ChainId, pub chain_id: ChainId,
/// A 20-byte (40 char) hex encoded Ethereum private key. /// A 20-byte (40 char) hex encoded Ethereum private key.

View File

@ -16,18 +16,18 @@ pub struct GetRequestOptions {
/// Retrieve a randomness request to this provider /// Retrieve a randomness request to this provider
#[arg(long = "chain-id")] #[arg(long = "chain-id")]
#[arg(env = "PYTH_CHAIN_ID")] #[arg(env = "FORTUNA_CHAIN_ID")]
pub chain_id: ChainId, pub chain_id: ChainId,
/// Retrieve a randomness request to this provider /// Retrieve a randomness request to this provider
#[arg(long = "provider")] #[arg(long = "provider")]
#[arg(env = "PYTH_PROVIDER")] #[arg(env = "FORTUNA_PROVIDER")]
#[arg(default_value = "0x368397bDc956b4F23847bE244f350Bde4615F25E")] #[arg(default_value = "0x368397bDc956b4F23847bE244f350Bde4615F25E")]
pub provider: Address, pub provider: Address,
/// The sequence number of the request to retrieve /// The sequence number of the request to retrieve
#[arg(long = "sequence")] #[arg(long = "sequence")]
#[arg(env = "PYTH_SEQUENCE")] #[arg(env = "FORTUNA_SEQUENCE")]
#[arg(default_value = "0")] #[arg(default_value = "0")]
pub sequence: u64, pub sequence: u64,
} }

View File

@ -19,7 +19,7 @@ pub struct RegisterProviderOptions {
/// Retrieve a randomness request to this provider /// Retrieve a randomness request to this provider
#[arg(long = "chain-id")] #[arg(long = "chain-id")]
#[arg(env = "PYTH_CHAIN_ID")] #[arg(env = "FORTUNA_CHAIN_ID")]
pub chain_id: ChainId, pub chain_id: ChainId,
/// A 20-byte (40 char) hex encoded Ethereum private key. /// A 20-byte (40 char) hex encoded Ethereum private key.

View File

@ -16,7 +16,7 @@ pub struct RequestRandomnessOptions {
/// Request randomness on this blockchain. /// Request randomness on this blockchain.
#[arg(long = "chain-id")] #[arg(long = "chain-id")]
#[arg(env = "PYTH_CHAIN_ID")] #[arg(env = "FORTUNA_CHAIN_ID")]
pub chain_id: ChainId, pub chain_id: ChainId,
/// A 20-byte (40 char) hex encoded Ethereum private key. /// A 20-byte (40 char) hex encoded Ethereum private key.
@ -27,7 +27,7 @@ pub struct RequestRandomnessOptions {
/// Submit a randomness request to this provider /// Submit a randomness request to this provider
#[arg(long = "provider")] #[arg(long = "provider")]
#[arg(env = "PYTH_PROVIDER")] #[arg(env = "FORTUNA_PROVIDER")]
#[arg(default_value = "0x368397bDc956b4F23847bE244f350Bde4615F25E")] #[arg(default_value = "0x368397bDc956b4F23847bE244f350Bde4615F25E")]
pub provider: Address, pub provider: Address,
} }

View File

@ -25,7 +25,7 @@ pub struct RunOptions {
/// The public key of the provider whose requests the server will respond to. /// The public key of the provider whose requests the server will respond to.
#[arg(long = "provider")] #[arg(long = "provider")]
#[arg(env = "PYTH_PROVIDER")] #[arg(env = "FORTUNA_PROVIDER")]
#[arg(default_value = "0x368397bDc956b4F23847bE244f350Bde4615F25E")] #[arg(default_value = "0x368397bDc956b4F23847bE244f350Bde4615F25E")]
pub provider: Address, pub provider: Address,
} }

View File

@ -77,6 +77,7 @@ import "./PythRandomEvents.sol";
// - gas optimizations // - gas optimizations
// - function to check invariants?? // - function to check invariants??
// - need to increment pyth fees if someone transfers funds to the contract via another method // - need to increment pyth fees if someone transfers funds to the contract via another method
// - off-chain data ERC support?
contract PythRandom is PythRandomState, PythRandomEvents { contract PythRandom is PythRandomState, PythRandomEvents {
// TODO: Use an upgradeable proxy // TODO: Use an upgradeable proxy
constructor(uint pythFeeInWei) { constructor(uint pythFeeInWei) {