|
1 |
| -use anyhow::{anyhow, Result}; |
| 1 | +use anyhow::{anyhow, Context, Result}; |
2 | 2 | use client::SequencerClient;
|
3 | 3 | use espresso_types::{FeeAmount, FeeVersion, MarketplaceVersion};
|
4 | 4 | use ethers::prelude::*;
|
5 | 5 | use futures::future::join_all;
|
| 6 | +use std::path::Path; |
6 | 7 | use std::{fmt, str::FromStr, time::Duration};
|
7 | 8 | use surf_disco::Url;
|
8 | 9 | use tokio::time::{sleep, timeout};
|
9 | 10 | use vbs::version::StaticVersionType;
|
10 | 11 |
|
| 12 | +use dotenvy::var; |
| 13 | +use sequencer_utils::stake_table::{ |
| 14 | + update_stake_table, PermissionedStakeTableUpdate, StakerIdentity, |
| 15 | +}; |
| 16 | + |
11 | 17 | const L1_PROVIDER_RETRY_INTERVAL: Duration = Duration::from_secs(1);
|
12 | 18 | // TODO add to .env
|
13 | 19 | const RECIPIENT_ADDRESS: &str = "0x0000000000000000000000000000000000000000";
|
@@ -277,3 +283,67 @@ async fn wait_for_service(url: Url, interval: u64, timeout_duration: u64) -> Res
|
277 | 283 | .await
|
278 | 284 | .map_err(|e| anyhow!("Wait for service, timeout: ({}) {}", url, e))?
|
279 | 285 | }
|
| 286 | + |
| 287 | +pub async fn test_stake_table_update(clients: Vec<SequencerClient>) -> Result<()> { |
| 288 | + /* |
| 289 | + EPOCH V3 |
| 290 | + */ |
| 291 | + |
| 292 | + let l1_port = var("ESPRESSO_SEQUENCER_L1_PORT")?; |
| 293 | + let account_index = var("ESPRESSO_DEPLOYER_ACCOUNT_INDEX")?; |
| 294 | + let contract_address = var("ESPRESSO_SEQUENCER_PERMISSIONED_STAKE_TABLE_ADDRESS")?; |
| 295 | + let initial_stake_table_path = var("ESPRESSO_SEQUENCER_INITIAL_PERMISSIONED_STAKE_TABLE_PATH")?; |
| 296 | + |
| 297 | + let permissioned_stake_table = |
| 298 | + PermissionedStakeTableUpdate::from_toml_file(Path::new(&initial_stake_table_path))?; |
| 299 | + |
| 300 | + // initial stake table has 5 new stakers |
| 301 | + |
| 302 | + let new_stakers = permissioned_stake_table.new_stakers; |
| 303 | + //lets remove one |
| 304 | + let staker_removed = new_stakers[0].clone(); |
| 305 | + |
| 306 | + let st_with_one_removed = PermissionedStakeTableUpdate::new( |
| 307 | + vec![], |
| 308 | + vec![StakerIdentity { |
| 309 | + stake_table_key: staker_removed.stake_table_key.clone(), |
| 310 | + }], |
| 311 | + ); |
| 312 | + let client = clients[0].clone(); |
| 313 | + |
| 314 | + let epoch_before_update = client.current_epoch().await?.context("curr epoch")?; |
| 315 | + tracing::warn!("current_epoch={epoch_before_update:?}"); |
| 316 | + update_stake_table( |
| 317 | + format!("http://localhost:{l1_port}").parse()?, |
| 318 | + Duration::from_secs(7), |
| 319 | + "test test test test test test test test test test test junk".to_string(), |
| 320 | + account_index.parse()?, |
| 321 | + contract_address.parse()?, |
| 322 | + st_with_one_removed, |
| 323 | + ) |
| 324 | + .await?; |
| 325 | + |
| 326 | + loop { |
| 327 | + sleep(Duration::from_secs(10)).await; |
| 328 | + let epoch = clients[0].current_epoch().await?.context("curr epoch")?; |
| 329 | + tracing::info!("current_epoch={epoch:?}"); |
| 330 | + if epoch > epoch_before_update + 6 { |
| 331 | + let stake_table = client.stake_table(epoch).await?; |
| 332 | + tracing::info!("stake_table={stake_table:?}"); |
| 333 | + assert_eq!(stake_table.len(), 4); |
| 334 | + |
| 335 | + assert!( |
| 336 | + stake_table |
| 337 | + .iter() |
| 338 | + .all(|st| st.stake_key != staker_removed.stake_table_key), |
| 339 | + "Entry for {} already exists in the stake table", |
| 340 | + staker_removed.stake_table_key |
| 341 | + ); |
| 342 | + |
| 343 | + break; |
| 344 | + } |
| 345 | + } |
| 346 | + // TODO: randomize this test |
| 347 | + |
| 348 | + Ok(()) |
| 349 | +} |
0 commit comments