Skip to content

refactor(argus): remove fortuna-specific keeper code #2534

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

Merged
merged 1 commit into from
Apr 1, 2025
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
2 changes: 1 addition & 1 deletion apps/argus/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 0 additions & 25 deletions apps/argus/config.sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ chains:
geth_rpc_addr: https://replicator.pegasus.lightlink.io/rpc/v1
contract_addr: 0x8250f4aF4B972684F7b336503E2D6dFeDeB1487a

# Keeper configuration for the chain
reveal_delay_blocks: 0
gas_limit: 500000

# Multiplier for the priority fee estimate, as a percentage (i.e., 100 = no change).
# Defaults to 100 if the field is omitted.
Expand Down Expand Up @@ -38,23 +35,7 @@ chains:
min_profit_pct: 0
target_profit_pct: 20
max_profit_pct: 100

# A list of block delays for processing blocks multiple times. Each number represents
# how many blocks to wait before processing. For example, [5, 10, 20] means process
# blocks after 5 blocks, then again after 10 blocks, and finally after 20 blocks.
block_delays: [5, 10, 20]

# Historical commitments -- delete this block for local development purposes
commitments:
# prettier-ignore
- seed: [219,125,217,197,234,88,208,120,21,181,172,143,239,102,41,233,167,212,237,106,37,255,184,165,238,121,230,155,116,158,173,48]
chain_length: 10000
original_commitment_sequence_number: 104
provider:
uri: http://localhost:8080/
chain_length: 100000
chain_sample_interval: 10

# An ethereum wallet address and private key. Generate with `cast wallet new`
address: 0xADDRESS
private_key:
Expand All @@ -63,12 +44,6 @@ provider:
# For production, you can store the private key in a file.
# file: provider-key.txt
# A 32 byte random value in hexadecimal
# Generate with `openssl rand -hex 32`
secret:
# For local development, you can hardcode the value here
value: abcd
# For production, you can store the private key in a file.
# file: secret.txt

# Set this to the address of your keeper wallet if you would like the keeper wallet to
# be able to withdraw fees from the contract.
Expand Down
13 changes: 3 additions & 10 deletions apps/argus/src/api.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use {
crate::{
chain::reader::{BlockNumber, BlockStatus},
},
crate::chain::reader::BlockStatus,
anyhow::Result,
axum::{
body::Body,
Expand Down Expand Up @@ -47,9 +45,7 @@ pub struct ApiState {
}

impl ApiState {
pub async fn new(
metrics_registry: Arc<RwLock<Registry>>,
) -> ApiState {
pub async fn new(metrics_registry: Arc<RwLock<Registry>>) -> ApiState {
let metrics = ApiMetrics {
http_requests: Family::default(),
};
Expand All @@ -68,16 +64,13 @@ impl ApiState {
}
}

/// The state of the randomness service for a single blockchain.
/// The state of the service for a single blockchain.
#[derive(Clone)]
pub struct BlockchainState {
/// The chain id for this blockchain, useful for logging
pub id: ChainId,
/// The address of the provider that this server is operating for.
pub provider_address: Address,
/// The server will wait for this many block confirmations of a request before revealing
/// the random number.
pub reveal_delay_blocks: BlockNumber,
/// The BlockStatus of the block that is considered to be confirmed on the blockchain.
/// For eg., Finalized, Safe
pub confirmed_block_status: BlockStatus,
Expand Down
4 changes: 1 addition & 3 deletions apps/argus/src/chain/reader.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use {
ethers::types::{Address, BlockNumber as EthersBlockNumber},
};
use ethers::types::{Address, BlockNumber as EthersBlockNumber};

pub type BlockNumber = u64;

Expand Down
42 changes: 4 additions & 38 deletions apps/argus/src/command/register_provider.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
use {
crate::{
api::{get_register_uri, ChainId},
api::ChainId,
chain::ethereum::SignablePythContract,
config::{Config, EthereumConfig, ProviderConfig, RegisterProviderOptions},
},
anyhow::{anyhow, Result},
ethers::{
abi::Bytes,
types::U256,
},
std::sync::Arc,
};

Expand All @@ -31,48 +27,18 @@ pub async fn register_provider(opts: &RegisterProviderOptions) -> Result<()> {

pub async fn register_provider_from_config(
provider_config: &ProviderConfig,
chain_id: &ChainId,
_chain_id: &ChainId,
chain_config: &EthereumConfig,
) -> Result<()> {
let private_key_string = provider_config.private_key.load()?.ok_or(anyhow!(
"Please specify a provider private key in the config"
))?;

// Initialize a Provider to interface with the EVM contract.
let contract =
let _contract =
Arc::new(SignablePythContract::from_config(chain_config, &private_key_string).await?);
// Create a new random hash chain.
let random = rand::random::<[u8; 32]>();

// FIXME: delete this
let commitment_length = 1000;

// Arguments to the contract to register our new provider.
let fee_in_wei = chain_config.fee;
let commitment = [0; 32];
// Store the random seed and chain length in the metadata field so that we can regenerate the hash
// chain at-will. (This is secure because you can't generate the chain unless you also have the secret)
let commitment_metadata = CommitmentMetadata {
seed: random,
chain_length: commitment_length,
};
let uri = get_register_uri(&provider_config.uri, chain_id)?;
let call = contract.register(
fee_in_wei,
commitment,
bincode::serialize(&commitment_metadata)?.into(),
commitment_length,
// Use Bytes to serialize the uri. Most users will be using JS/TS to deserialize this uri.
// Bincode is a different encoding mechanisms, and I didn't find any JS/TS library to parse bincode.
Bytes::from(uri.as_str()).into(),
);
let mut gas_estimate = call.estimate_gas().await?;
let gas_multiplier = U256::from(2); //TODO: smarter gas estimation
gas_estimate *= gas_multiplier;
let call_with_gas = call.gas(gas_estimate);
if let Some(r) = call_with_gas.send().await?.await? {
tracing::info!("Registered provider: {:?}", r);
}
// TODO: implement registration for Pulse

Ok(())
}
10 changes: 2 additions & 8 deletions apps/argus/src/command/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ use {
config::{Config, EthereumConfig, RunOptions},
keeper::{self, keeper_metrics::KeeperMetrics},
},
fortuna::eth_utils::traced_client::{RpcMetrics, TracedClient},
anyhow::{anyhow, Error, Result},
axum::Router,
ethers::{
middleware::Middleware,
types::{Address, BlockNumber},
},
fortuna::eth_utils::traced_client::{RpcMetrics, TracedClient},
futures::future::join_all,
prometheus_client::{
encoding::EncodeLabelSet,
Expand Down Expand Up @@ -110,12 +110,7 @@ pub async fn run(opts: &RunOptions) -> Result<()> {
let mut tasks = Vec::new();
for (chain_id, chain_config) in config.chains.clone() {
tasks.push(spawn(async move {
let state = setup_chain_state(
&config.provider.address,
&chain_id,
&chain_config,
)
.await;
let state = setup_chain_state(&config.provider.address, &chain_id, &chain_config).await;

(chain_id, state)
}));
Expand Down Expand Up @@ -183,7 +178,6 @@ async fn setup_chain_state(
let state = BlockchainState {
id: chain_id.clone(),
provider_address: *provider,
reveal_delay_blocks: chain_config.reveal_delay_blocks,
confirmed_block_status: chain_config.confirmed_block_status,
};
Ok(state)
Expand Down
57 changes: 2 additions & 55 deletions apps/argus/src/command/setup_provider.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use {
crate::{
api::{get_register_uri, ChainId},
api::ChainId,
chain::ethereum::{ProviderInfo, SignablePythContract},
command::register_provider::register_provider_from_config,
config::{Config, EthereumConfig, SetupProviderOptions},
},
anyhow::{anyhow, Result},
ethers::{
abi::Bytes as AbiBytes,
signers::{LocalWallet, Signer},
types::{Address, Bytes},
types::Address,
},
futures::future::join_all,
std::sync::Arc,
Expand Down Expand Up @@ -88,11 +87,6 @@ async fn setup_chain_provider(
.in_current_span()
.await?;

let uri = get_register_uri(&provider_config.uri, chain_id)?;
sync_uri(&contract, &provider_info, uri)
.in_current_span()
.await?;

sync_fee_manager(
&contract,
&provider_info,
Expand All @@ -101,34 +95,6 @@ async fn setup_chain_provider(
.in_current_span()
.await?;

sync_max_num_hashes(
&contract,
&provider_info,
chain_config.max_num_hashes.unwrap_or(0),
)
.in_current_span()
.await?;

Ok(())
}

async fn sync_uri(
contract: &Arc<SignablePythContract>,
provider_info: &ProviderInfo,
uri: String,
) -> Result<()> {
let uri_as_bytes: Bytes = AbiBytes::from(uri.as_str()).into();
if provider_info.uri != uri_as_bytes {
tracing::info!("Updating provider uri to {}", uri);
if let Some(receipt) = contract
.set_provider_uri(uri_as_bytes)
.send()
.await?
.await?
{
tracing::info!("Updated provider uri: {:?}", receipt);
}
}
Ok(())
}

Expand Down Expand Up @@ -164,22 +130,3 @@ async fn sync_fee_manager(
}
Ok(())
}

async fn sync_max_num_hashes(
contract: &Arc<SignablePythContract>,
provider_info: &ProviderInfo,
max_num_hashes: u32,
) -> Result<()> {
if provider_info.max_num_hashes != max_num_hashes {
tracing::info!("Updating provider max num hashes to {:?}", max_num_hashes);
if let Some(receipt) = contract
.set_max_num_hashes(max_num_hashes)
.send()
.await?
.await?
{
tracing::info!("Updated provider max num hashes to : {:?}", receipt);
}
}
Ok(())
}
38 changes: 3 additions & 35 deletions apps/argus/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
use {
crate::{
api::ChainId,
chain::reader::{BlockNumber, BlockStatus},
},
fortuna::eth_utils::utils::EscalationPolicy,
crate::{api::ChainId, chain::reader::BlockStatus},
anyhow::{anyhow, Result},
clap::{crate_authors, crate_description, crate_name, crate_version, Args, Parser},
ethers::types::Address,
fortuna::eth_utils::utils::EscalationPolicy,
std::{collections::HashMap, fs},
};
pub use {
Expand Down Expand Up @@ -66,7 +63,7 @@ pub enum Options {
pub struct ConfigOptions {
/// Path to a configuration file containing the list of supported blockchains
#[arg(long = "config")]
#[arg(env = "FORTUNA_CONFIG")]
#[arg(env = "ARGUS_CONFIG")]
#[arg(default_value = "config.yaml")]
pub config: String,
}
Expand Down Expand Up @@ -117,12 +114,6 @@ pub struct EthereumConfig {
/// Address of a Pyth Randomness contract to interact with.
pub contract_addr: Address,

/// reveal_delay_blocks - The difference between the block number with the
/// confirmed_block_status(see below) and the block number of a request to
/// Entropy should be greater than `reveal_delay_blocks` for Fortuna to reveal
/// its commitment.
pub reveal_delay_blocks: BlockNumber,

/// The BlockStatus of the block that is considered confirmed.
/// For example, Finalized, Safe, Latest
#[serde(default)]
Expand All @@ -136,7 +127,6 @@ pub struct EthereumConfig {
pub gas_limit: u64,

/// The percentage multiplier to apply to priority fee estimates (100 = no change, e.g. 150 = 150% of base fee)
#[serde(default = "default_priority_fee_multiplier_pct")]
pub priority_fee_multiplier_pct: u64,

/// The escalation policy governs how the gas limit and fee are increased during backoff retries.
Expand Down Expand Up @@ -171,24 +161,6 @@ pub struct EthereumConfig {
/// How much the provider charges for a request on this chain.
#[serde(default)]
pub fee: u128,

/// Maximum number of hashes to record in a request.
/// This should be set according to the maximum gas limit the provider supports for callbacks.
pub max_num_hashes: Option<u32>,

/// A list of delays (in blocks) that indicates how many blocks should be delayed
/// before we process a block. For retry logic, we can process blocks multiple times
/// at each specified delay. For example: [5, 10, 20].
#[serde(default = "default_block_delays")]
pub block_delays: Vec<u64>,
}

fn default_block_delays() -> Vec<u64> {
vec![5]
}

fn default_priority_fee_multiplier_pct() -> u64 {
100
}

#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
Expand Down Expand Up @@ -272,10 +244,6 @@ impl EscalationPolicyConfig {
/// Configuration values that are common to a single provider (and shared across chains).
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct ProviderConfig {
/// The URI where clients can retrieve random values from this provider,
/// i.e., wherever fortuna for this provider will be hosted.
pub uri: String,

/// The public key of the provider whose requests the server will respond to.
pub address: Address,

Expand Down
Loading