Skip to content

Commit d5d82e2

Browse files
committed
feat(staking-cli): add metadata validation to update-metadata-uri
- Add --consensus-public-key parameter for metadata validation - Increase metadata fetch timeout from 3 to 5 seconds - Add parse_bls_pub_key helper function - Add error messages with --skip-metadata-validation hint - Update README with validation documentation - Add tests for metadata validation success/failure cases - Remove unnecessary spawn_blocking from tests
1 parent 25bc66a commit d5d82e2

File tree

15 files changed

+1181
-161
lines changed

15 files changed

+1181
-161
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ indexmap = { version = "2", features = ["serde"] }
141141
lazy_static = "1"
142142
libp2p-identity = { version = "0.2", features = ["ed25519", "serde"] }
143143
libp2p-swarm-derive = { version = "0.35" }
144-
moka = { version = "0.12.12", features = ["future"] }
145144
memoize = { version = "0.4", features = ["full"] }
145+
moka = { version = "0.12.12", features = ["future"] }
146146
multiaddr = { version = "0.18" }
147147
num_cpus = "1"
148148
parking_lot = { version = "0.12", features = ["send_guard"] }

contracts/rust/deployer/src/lib.rs

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use alloy::{
2121
};
2222
use anyhow::{anyhow, Context, Result};
2323
use clap::{builder::OsStr, Parser, ValueEnum};
24-
use derive_more::{derive::Deref, Display};
24+
use derive_more::Display;
2525
use espresso_types::{v0_1::L1Client, v0_3::Fetcher};
2626
use hotshot_contract_adapter::sol_types::*;
2727

@@ -274,8 +274,22 @@ impl From<Contract> for OsStr {
274274
}
275275

276276
/// Cache of contracts predeployed or deployed during this current run.
277-
#[derive(Deref, Debug, Clone, Default)]
278-
pub struct Contracts(HashMap<Contract, Address>);
277+
#[derive(Debug, Clone)]
278+
pub struct Contracts {
279+
addresses: HashMap<Contract, Address>,
280+
// TODO: having the cooldown field here is a bit hacky but we postpone a better solution to
281+
// avoid a large refactor.
282+
deploy_cooldown: Duration,
283+
}
284+
285+
impl Default for Contracts {
286+
fn default() -> Self {
287+
Self {
288+
addresses: HashMap::new(),
289+
deploy_cooldown: Duration::ZERO,
290+
}
291+
}
292+
}
279293

280294
impl From<DeployedContracts> for Contracts {
281295
fn from(deployed: DeployedContracts) -> Self {
@@ -337,17 +351,35 @@ impl From<DeployedContracts> for Contracts {
337351
if let Some(addr) = deployed.reward_claim_proxy {
338352
m.insert(Contract::RewardClaimProxy, addr);
339353
}
340-
Self(m)
354+
Self {
355+
addresses: m,
356+
deploy_cooldown: Duration::ZERO,
357+
}
341358
}
342359
}
343360

344361
impl Contracts {
345362
pub fn new() -> Self {
346-
Contracts(HashMap::new())
363+
Self::default()
364+
}
365+
366+
pub fn with_cooldown(cooldown: Duration) -> Self {
367+
Self {
368+
addresses: HashMap::new(),
369+
deploy_cooldown: cooldown,
370+
}
371+
}
372+
373+
pub fn set_cooldown(&mut self, cooldown: Duration) {
374+
self.deploy_cooldown = cooldown;
347375
}
348376

349377
pub fn address(&self, contract: Contract) -> Option<Address> {
350-
self.0.get(&contract).copied()
378+
self.addresses.get(&contract).copied()
379+
}
380+
381+
pub fn remove(&mut self, contract: &Contract) -> Option<Address> {
382+
self.addresses.remove(contract)
351383
}
352384

353385
/// Deploy a contract (with logging and cached deployments)
@@ -358,7 +390,7 @@ impl Contracts {
358390
where
359391
P: Provider,
360392
{
361-
if let Some(addr) = self.0.get(&name) {
393+
if let Some(addr) = self.addresses.get(&name) {
362394
tracing::info!("skipping deployment of {name}, already deployed at {addr:#x}");
363395
return Ok(*addr);
364396
}
@@ -377,18 +409,18 @@ impl Contracts {
377409

378410
tracing::info!("deployed {name} at {addr:#x}");
379411

380-
// Cooldown after deployment to avoid rate limiting on public RPC nodes
381-
// This helps when deploying multiple contracts in sequence
382-
tokio::time::sleep(Duration::from_millis(1000)).await;
383-
tracing::info!("cooldown 1000ms after deployment");
412+
if !self.deploy_cooldown.is_zero() {
413+
tokio::time::sleep(self.deploy_cooldown).await;
414+
tracing::info!("cooldown {:?} after deployment", self.deploy_cooldown);
415+
}
384416

385-
self.0.insert(name, addr);
417+
self.addresses.insert(name, addr);
386418
Ok(addr)
387419
}
388420

389421
/// Write a .env file.
390422
pub fn write(&self, mut w: impl Write) -> Result<()> {
391-
for (contract, address) in &self.0 {
423+
for (contract, address) in &self.addresses {
392424
writeln!(w, "{contract}={address:#x}")?;
393425
}
394426
Ok(())
@@ -2316,7 +2348,7 @@ mod tests {
23162348

23172349
impl Contracts {
23182350
fn insert(&mut self, name: Contract, address: Address) -> Option<Address> {
2319-
self.0.insert(name, address)
2351+
self.addresses.insert(name, address)
23202352
}
23212353
}
23222354

@@ -4486,7 +4518,7 @@ mod tests {
44864518
let cached_impl_addr = contracts.address(Contract::FeeContract);
44874519

44884520
// For patch upgrades, we need to clear the cache to allow redeployment
4489-
contracts.0.remove(&Contract::FeeContract);
4521+
contracts.remove(&Contract::FeeContract);
44904522

44914523
// Test the upgrade function directly
44924524
let receipt = upgrade_fee_v1(&provider, &mut contracts).await?;
@@ -4566,7 +4598,7 @@ mod tests {
45664598

45674599
// Second upgrade to V2 (re-applying same version)
45684600
// For patch upgrades, we need to clear the cache to allow redeployment
4569-
contracts.0.remove(&Contract::LightClientV2);
4601+
contracts.remove(&Contract::LightClientV2);
45704602

45714603
// Second upgrade to V2 (re-applying same version)
45724604
upgrade_light_client_v2(

sequencer/src/bin/deploy.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,16 @@ struct Options {
405405
#[clap(flatten)]
406406
logging: logging::Config,
407407

408+
/// Cooldown after each contract deployment to avoid outdated state during post deployment
409+
/// verification steps.
410+
#[clap(
411+
long,
412+
env = "ESPRESSO_POST_DEPLOYMENT_COOLDOWN",
413+
default_value = "1s",
414+
value_parser = parse_duration,
415+
)]
416+
post_deployment_cooldown: Duration,
417+
408418
/// Command to run
409419
///
410420
/// For backwards compatibility, the default is to deploy contracts, if no
@@ -432,6 +442,8 @@ async fn main() -> anyhow::Result<()> {
432442
};
433443

434444
let mut contracts = Contracts::from(opt.contracts);
445+
contracts.set_cooldown(opt.post_deployment_cooldown);
446+
435447
let provider = if opt.ledger {
436448
let signer = connect_ledger(opt.account_index as usize).await?;
437449
tracing::info!("Using ledger for signing, watch ledger device for prompts.");

0 commit comments

Comments
 (0)