Jayant Krishnamurthy 2 years ago
parent
commit
30bca115a0

+ 2 - 0
pyth-rng/src/config.rs

@@ -5,6 +5,7 @@ use clap::crate_version;
 use clap::Parser;
 use clap::Args;
 
+
 mod register_provider;
 mod request_randomness;
 mod run;
@@ -14,6 +15,7 @@ pub use register_provider::RegisterProviderOptions;
 pub use request_randomness::RequestRandomnessOptions;
 pub use get_request::GetRequestOptions;
 pub use run::RunOptions;
+use crate::ethereum::PythProvider;
 
 #[derive(Parser, Debug)]
 #[command(name = crate_name!())]

+ 7 - 0
pyth-rng/src/config/request_randomness.rs

@@ -11,4 +11,11 @@ pub struct RequestRandomnessOptions {
 
     #[command(flatten)]
     pub randomness: RandomnessOptions,
+
+    // FIXME: I think this has to be the pubkey of the private key in the ethereum options
+    /// Submit a randomness request to this provider
+    #[arg(long = "provider")]
+    #[arg(env = "PYTH_PROVIDER")]
+    #[arg(default_value = "0x368397bDc956b4F23847bE244f350Bde4615F25E")]
+    pub provider: String,
 }

+ 16 - 14
pyth-rng/src/ethereum.rs

@@ -1,3 +1,12 @@
+
+mod register_provider;
+mod request_randomness;
+mod get_request;
+
+pub use register_provider::register_provider;
+pub use request_randomness::request_randomness;
+pub use get_request::get_request;
+
 use ethers::contract::abigen;
 use ethers::core::types::Address;
 use ethers::middleware::SignerMiddleware;
@@ -8,29 +17,22 @@ use ethers::signers::LocalWallet;
 use ethers::signers::Signer;
 use std::error::Error;
 use std::sync::Arc;
-
-mod register_provider;
-mod request_randomness;
-mod get_request;
-
-pub use register_provider::register_provider;
-pub use request_randomness::request_randomness;
-pub use get_request::get_request;
+use crate::config::EthereumOptions;
+use anyhow::anyhow;
 
 // TODO: Programatically generate this so we don't have to keep committed ABI in sync with the
 // contract in the same repo.
 abigen!(PythRandom, "src/abi.json");
 
-const PROVIDER: &str = "https://goerli.optimism.io";
 pub type PythProvider = PythRandom<SignerMiddleware<Provider<Http>, LocalWallet>>;
 
-async fn provider(key: &str, contract_addr: &str) -> Result<PythProvider, Box<dyn Error>> {
-    let provider = Provider::<Http>::try_from(PROVIDER)?;
+pub async fn provider(opts: &EthereumOptions) -> Result<PythProvider, Box<dyn Error>> {
+    let provider = Provider::<Http>::try_from(&opts.geth_rpc_addr)?;
     let chain_id = provider.get_chainid().await?;
-    let wallet__ = key.parse::<LocalWallet>()?.with_chain_id(chain_id.as_u64());
+    let wallet__ = opts.private_key.clone().ok_or(anyhow!("No private key specified"))?.parse::<LocalWallet>()?.with_chain_id(chain_id.as_u64());
 
     Ok(PythRandom::new(
-        contract_addr.parse::<Address>()?,
+        opts.contract_addr.parse::<Address>()?,
         Arc::new(SignerMiddleware::new(provider, wallet__)),
     ))
-}
+}

+ 1 - 1
pyth-rng/src/ethereum/get_request.rs

@@ -11,7 +11,7 @@ use std::sync::Arc;
 
 pub async fn get_request(opts: &GetRequestOptions) -> Result<(), Box<dyn Error>> {
     // Initialize a Provider to interface with the EVM contract.
-    let contract = Arc::new(provider(&opts.provider_key, &opts.contract_addr).await?);
+    let contract = Arc::new(provider(&opts.ethereum).await?);
 
     if let r = contract.get_request(opts.provider.parse::<H160>()?, opts.sequence).call().await? {
         println!("Found request: {:?}", r);

+ 2 - 5
pyth-rng/src/ethereum/register_provider.rs

@@ -12,14 +12,11 @@ use std::sync::Arc;
 // TODO: Return to use rand::random instead of hardcoded randomness.
 pub async fn register_provider(opts: &RegisterProviderOptions) -> Result<(), Box<dyn Error>> {
     // Initialize a Provider to interface with the EVM contract.
-    let contract = Arc::new(provider(&opts.provider_key, &opts.contract_addr).await?);
+    let contract = Arc::new(provider(&opts.ethereum).await?);
 
     // Create new HashChain. We need a real random number to seed this.
     let random = [0u8; 32]; // rand::random::<[u8; 32]>();
-    let mut secret: [u8; 32] = [0u8; 32];
-    secret.copy_from_slice(&hex::decode(opts.secret.clone())?[0..32]);
-    let secret: [u8; 32] = Keccak256::digest([random, secret].flatten()).into();
-    let mut chain = PebbleHashChain::new(secret, 32);
+    let mut chain = PebbleHashChain::from_config(&opts.randomness, random)?;
 
     // Arguments to the contract to register our new provider.
     let fee_in_wei = U256::from(opts.fee);

+ 3 - 9
pyth-rng/src/ethereum/request_randomness.rs

@@ -10,24 +10,18 @@ use sha3::Keccak256;
 use std::error::Error;
 use std::sync::Arc;
 
-
-// TODO: Don't use hardcoded 32.
 // TODO: Use State to access existing random chain, don't regenerate.
 pub async fn request_randomness(opts: &RequestRandomnessOptions) -> Result<(), Box<dyn Error>> {
     // Initialize a Provider to interface with the EVM contract.
-    let contract = Arc::new(provider(&opts.key, &opts.contract_addr).await?);
+    let contract = Arc::new(provider(&opts.ethereum).await?);
 
     // Create new HashChain. We need a real random number to seed this.
     let random = [0u8; 32];
-    let mut secret: [u8; 32] = [0u8; 32];
-    secret.copy_from_slice(&hex::decode(opts.secret.clone())?[0..32]);
-    let secret: [u8; 32] = Keccak256::digest([random, secret].flatten()).into();
-    let chain = PebbleHashChain::new(secret, 32);
+    let chain = PebbleHashChain::from_config(&opts.randomness, random)?;
 
-    // TODO Hash result.
     let user_randomness = rand::random::<[u8; 32]>();
     let hashed_randomness: [u8; 32] = Keccak256::digest(user_randomness).into();
-    let provider = opts.addr.parse::<Address>()?;
+    let provider = opts.provider.parse::<Address>()?;
 
     if let Some(r) = contract
         .request(provider, hashed_randomness, false)

+ 11 - 0
pyth-rng/src/state.rs

@@ -2,6 +2,9 @@ use anyhow::ensure;
 use anyhow::Result;
 use sha3::Digest;
 use sha3::Keccak256;
+use std::error::Error;
+
+use crate::config::RandomnessOptions;
 
 /// A HashChain.
 pub struct PebbleHashChain {
@@ -24,6 +27,14 @@ impl PebbleHashChain {
         Self { hash, next: 0 }
     }
 
+    pub fn from_config(opts: &RandomnessOptions, random: [u8; 32]) -> Result<Self, Box<dyn Error>> {
+        let mut secret: [u8; 32] = [0u8; 32];
+        secret.copy_from_slice(&hex::decode(opts.secret.clone())?[0..32]);
+        let secret: [u8; 32] = Keccak256::digest([random, secret].flatten()).into();
+
+        Ok(Self::new(secret, opts.chain_length.try_into()?))
+    }
+
     /// Reveal the next hash in the chain using the previous proof.
     pub fn reveal(&mut self) -> Result<[u8; 32]> {
         ensure!(self.next < self.len(), "no more hashes in the chain");