config.rs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. use {
  2. crate::api::ChainId,
  3. anyhow::{
  4. anyhow,
  5. Result,
  6. },
  7. clap::{
  8. crate_authors,
  9. crate_description,
  10. crate_name,
  11. crate_version,
  12. Args,
  13. Parser,
  14. },
  15. ethers::types::Address,
  16. std::{
  17. collections::HashMap,
  18. fs,
  19. },
  20. };
  21. pub use {
  22. generate::GenerateOptions,
  23. get_request::GetRequestOptions,
  24. register_provider::RegisterProviderOptions,
  25. request_randomness::RequestRandomnessOptions,
  26. run::RunOptions,
  27. };
  28. mod generate;
  29. mod get_request;
  30. mod register_provider;
  31. mod request_randomness;
  32. mod run;
  33. const DEFAULT_RPC_ADDR: &str = "127.0.0.1:34000";
  34. const DEFAULT_HTTP_ADDR: &str = "http://127.0.0.1:34000";
  35. #[derive(Parser, Debug)]
  36. #[command(name = crate_name!())]
  37. #[command(author = crate_authors!())]
  38. #[command(about = crate_description!())]
  39. #[command(version = crate_version!())]
  40. #[allow(clippy::large_enum_variant)]
  41. pub enum Options {
  42. /// Run the Randomness Service.
  43. Run(RunOptions),
  44. /// Register a new provider with the Pyth Random oracle.
  45. RegisterProvider(RegisterProviderOptions),
  46. /// Request a random number from the contract.
  47. RequestRandomness(RequestRandomnessOptions),
  48. /// Generate a random number by running the entire protocol end-to-end
  49. Generate(GenerateOptions),
  50. /// Get the status of a pending request for a random number.
  51. GetRequest(GetRequestOptions),
  52. }
  53. #[derive(Args, Clone, Debug)]
  54. #[command(next_help_heading = "Config Options")]
  55. #[group(id = "Config")]
  56. pub struct ConfigOptions {
  57. /// Path to a configuration file containing the list of supported blockchains
  58. #[arg(long = "config")]
  59. #[arg(env = "FORTUNA_CONFIG")]
  60. #[arg(default_value = "config.yaml")]
  61. pub config: String,
  62. }
  63. #[derive(Args, Clone, Debug)]
  64. #[command(next_help_heading = "Randomness Options")]
  65. #[group(id = "Randomness")]
  66. pub struct RandomnessOptions {
  67. /// A secret used for generating new hash chains. A 64-char hex string.
  68. #[arg(long = "secret")]
  69. #[arg(env = "FORTUNA_SECRET")]
  70. #[arg(default_value = "0000000000000000000000000000000000000000000000000000000000000000")]
  71. pub secret: String,
  72. /// The length of the hash chain to generate.
  73. #[arg(long = "chain-length")]
  74. #[arg(env = "FORTUNA_CHAIN_LENGTH")]
  75. #[arg(default_value = "32")]
  76. pub chain_length: u64,
  77. }
  78. #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
  79. pub struct Config {
  80. pub chains: HashMap<ChainId, EthereumConfig>,
  81. }
  82. impl Config {
  83. pub fn load(path: &str) -> Result<Config> {
  84. // Open and read the YAML file
  85. // TODO: the default serde deserialization doesn't enforce unique keys
  86. let yaml_content = fs::read_to_string(path)?;
  87. let config: Config = serde_yaml::from_str(&yaml_content)?;
  88. Ok(config)
  89. }
  90. pub fn get_chain_config(&self, chain_id: &ChainId) -> Result<EthereumConfig> {
  91. self.chains
  92. .get(chain_id)
  93. .map(|x| x.clone())
  94. .ok_or(anyhow!("Could not find chain id {} in the configuration", &chain_id).into())
  95. }
  96. }
  97. #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
  98. pub struct EthereumConfig {
  99. /// URL of a Geth RPC endpoint to use for interacting with the blockchain.
  100. pub geth_rpc_addr: String,
  101. /// Address of a Pyth Randomness contract to interact with.
  102. pub contract_addr: Address,
  103. }