Skip to content
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

Stake Table Integration test #2526

Draft
wants to merge 30 commits into
base: ab/leaf2-migration
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
5274951
epoch integration test
imabdulbasit Jan 21, 2025
2a09a9c
merge main
imabdulbasit Jan 30, 2025
5e27fc2
DEMO_GENESIS_FILE env
imabdulbasit Jan 30, 2025
6766269
Merge remote-tracking branch 'origin/main' into ab/epoch-integration-…
tbro Feb 3, 2025
a1803f7
fix error en `.env` file
tbro Feb 3, 2025
d688b6c
add pos test to justfile and CI workflow
tbro Feb 3, 2025
36a2c7b
Merge branch 'main' into ab/epoch-integration-test
imabdulbasit Feb 4, 2025
697d022
run demo native with base version set to pos
imabdulbasit Feb 4, 2025
7786cfb
Marketplace signatures should engage @ v99
tbro Feb 4, 2025
5f1a2b8
set epoch-height to 150
imabdulbasit Feb 4, 2025
cac2b3b
process-compose: remove fund-builder condition from `permissionless-b…
tbro Feb 4, 2025
4112773
Fix path to default genesis path
tbro Feb 4, 2025
ab84584
Some fixes
tbro Feb 4, 2025
8ed730f
temporarily disable versions we don't need for the current objective
tbro Feb 4, 2025
6f65adf
only run v 3 in CI for now
tbro Feb 5, 2025
213baf0
avoid redirect in header stream
tbro Feb 5, 2025
37307e4
Use named version (instead if integer)
tbro Feb 5, 2025
3ae3f66
Add missing header type + conversions
tbro Feb 5, 2025
7c6222b
bump todo_by by 1 month (#2534)
tbro Feb 5, 2025
a65cbb8
Put expected fee back as it was
tbro Feb 5, 2025
9613ce1
Add stake tables up to epoch 2 (inclusive)
tbro Feb 5, 2025
cbb414c
add stake table for ..=10
tbro Feb 5, 2025
aa31ce9
TODO questions
tbro Feb 6, 2025
a4e0b58
add backtrace to justfile
tbro Feb 6, 2025
7203717
TODO
tbro Feb 6, 2025
2f28e00
comment
tbro Feb 6, 2025
3779f32
Merge remote-tracking branch 'origin/ab/leaf2-migration' into ab/epoc…
tbro Feb 7, 2025
98a6969
version features
tbro Feb 7, 2025
711c7b9
I think build jet has more space (lets find out)
tbro Feb 7, 2025
dc25ada
Revert "I think build jet has more space (lets find out)"
tbro Feb 7, 2025
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
7 changes: 5 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,14 @@ jobs:
needs: [build-test-bins, build-test-artifacts-postgres]
strategy:
matrix:
version: [02,99]
version: [02,03,99]
include:
- version: 02
compose: "-f process-compose.yaml -D"

- version: 03
env:
DEMO_GENESIS_FILE: data/genesis/demo-pos.toml
compose: "-f process-compose.yaml -D"
- version: 99
compose: "-f process-compose.yaml -f process-compose-mp.yml -D"
runs-on: ubuntu-latest
Expand Down
2 changes: 2 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ surf-disco = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
vbs = { workspace = true }
hotshot-types = { workspace = true }
19 changes: 18 additions & 1 deletion client/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use anyhow::Context;
use espresso_types::{FeeAccount, FeeAmount, FeeMerkleTree, Header};
use espresso_types::{FeeAccount, FeeAmount, FeeMerkleTree, Header, PubKey};
use ethers::types::Address;
use futures::{stream::BoxStream, StreamExt};
use hotshot_types::stake_table::StakeTableEntry;
use jf_merkle_tree::{
prelude::{MerkleProof, Sha3Node},
MerkleTreeScheme,
Expand Down Expand Up @@ -119,6 +120,22 @@ impl SequencerClient {
let balance = proof.elem().copied().unwrap_or(0.into());
Ok(balance)
}

pub async fn current_epoch(&self) -> anyhow::Result<u64> {
self.0
.get::<u64>("node/current_epoch")
.send()
.await
.context("getting epoch value")
}

pub async fn stake_table(&self, epoch: u64) -> anyhow::Result<Vec<StakeTableEntry<PubKey>>> {
self.0
.get::<_>(&format!("node/stake-table/{epoch}"))
.send()
.await
.context("getting epoch value")
}
}

#[cfg(test)]
Expand Down
21 changes: 21 additions & 0 deletions data/genesis/demo-pos-base.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
base_version = "0.3"
upgrade_version = "0.0"

[stake_table]
capacity = 10

[chain_config]
chain_id = 999999999
max_block_size = '1mb'
base_fee = '1 wei'
fee_recipient = "0x0000000000000000000000000000000000000000"
bid_recipient = "0x0000000000000000000000000000000000000000"
fee_contract = "0xa15bb66138824a1c7167f5e85b957d04dd34e468"
stake_table_contract = "0x8ce361602b935680e8dec218b820ff5056beb7af"

[header]
timestamp = "1970-01-01T00:00:00Z"

[l1_finalized]
number = 0

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ timestamp = "1970-01-01T00:00:00Z"
number = 0

[[upgrade]]
version = "0.99"
version = "0.3"
start_proposing_view = 10
stop_proposing_view = 60

Expand Down
11 changes: 11 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ build profile="test":
demo-native-mp *args: build
scripts/demo-native -f process-compose.yaml -f process-compose-mp.yml {{args}}

demo-native-pos *args: build
DEMO_GENESIS_FILE=data/genesis/demo-pos.toml scripts/demo-native -f process-compose.yaml {{args}}

demo-native-pos-base *args: build
DEMO_GENESIS_FILE=data/genesis/demo-pos-base.toml scripts/demo-native -f process-compose.yaml {{args}}

demo-native-benchmark:
cargo build --release --features benchmarking
scripts/demo-native
Expand Down Expand Up @@ -71,10 +77,15 @@ test-all:
test-integration:
@echo 'NOTE that demo-native must be running for this test to succeed.'
INTEGRATION_TEST_SEQUENCER_VERSION=2 cargo nextest run --all-features --nocapture --profile integration smoke

test-integration-mp:
@echo 'NOTE that demo-native-mp must be running for this test to succeed.'
INTEGRATION_TEST_SEQUENCER_VERSION=99 cargo nextest run --all-features --nocapture --profile integration

test-integration-pos:
@echo 'NOTE that demo-native-pos must be running for this test to succeed.'
INTEGRATION_TEST_SEQUENCER_VERSION=3 cargo nextest run --all-features --nocapture --profile integration smoke

clippy:
@echo 'features: "embedded-db"'
cargo clippy --workspace --features embedded-db --all-targets -- -D warnings
Expand Down
4 changes: 2 additions & 2 deletions process-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ environment:
- ESPRESSO_SEQUENCER_ORCHESTRATOR_URL=http://localhost:$ESPRESSO_ORCHESTRATOR_PORT
- ESPRESSO_SEQUENCER_URL=http://localhost:$ESPRESSO_SEQUENCER_API_PORT
- ESPRESSO_SEQUENCER_L1_PROVIDER=http://localhost:$ESPRESSO_SEQUENCER_L1_PORT
- ESPRESSO_SEQUENCER_GENESIS_FILE=data/genesis/demo.toml
- ESPRESSO_BUILDER_GENESIS_FILE=data/genesis/demo.toml
- ESPRESSO_SEQUENCER_GENESIS_FILE=$DEMO_GENESIS_FILE
- ESPRESSO_BUILDER_GENESIS_FILE=$DEMO_GENESIS_FILE
- ESPRESSO_SEQUENCER_INITIAL_PERMISSIONED_STAKE_TABLE_PATH=data/initial_stake_table.toml
- ESPRESSO_STATE_RELAY_SERVER_URL=http://localhost:$ESPRESSO_STATE_RELAY_SERVER_PORT
- QUERY_SERVICE_URI=http://localhost:$ESPRESSO_SEQUENCER1_API_PORT/v0/
Expand Down
1 change: 1 addition & 0 deletions sequencer-sqlite/Cargo.lock

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

4 changes: 4 additions & 0 deletions sequencer/api/node.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ DOC = "Get the stake table for the current epoch"
PATH = ["stake-table/:epoch_number"]
":epoch_number" = "Integer"
DOC = "Get the stake table for the given epoch"

[route.current_epoch]
PATH = ["current_epoch"]
DOC = "Get the current epoch"
14 changes: 7 additions & 7 deletions sequencer/src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use super::{
};
use clap::Parser;
use espresso_types::{
traits::NullEventConsumer, FeeVersion, MarketplaceVersion, SequencerVersions,
traits::NullEventConsumer, EpochVersion, FeeVersion, MarketplaceVersion, SequencerVersions,
SolverAuctionResultsProvider, V0_0,
};
use futures::future::FutureExt;
Expand Down Expand Up @@ -38,30 +38,30 @@ pub async fn main() -> anyhow::Result<()> {
let upgrade = genesis.upgrade_version;

match (base, upgrade) {
(FeeVersion::VERSION, MarketplaceVersion::VERSION) => {
(FeeVersion::VERSION, EpochVersion::VERSION) => {
run(
genesis,
modules,
opt,
SequencerVersions::<FeeVersion, MarketplaceVersion>::new(),
SequencerVersions::<FeeVersion, EpochVersion>::new(),
)
.await
}
(FeeVersion::VERSION, _) => {
(EpochVersion::VERSION, _) => {
run(
genesis,
modules,
opt,
SequencerVersions::<FeeVersion, V0_0>::new(),
SequencerVersions::<EpochVersion, V0_0>::new(),
)
.await
}
(MarketplaceVersion::VERSION, _) => {
(FeeVersion::VERSION, MarketplaceVersion::VERSION) => {
run(
genesis,
modules,
opt,
SequencerVersions::<MarketplaceVersion, V0_0>::new(),
SequencerVersions::<FeeVersion, MarketplaceVersion>::new(),
)
.await
}
Expand Down
1 change: 1 addition & 0 deletions tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ reqwest = { workspace = true, features = ["json"] }
surf-disco = { workspace = true }
tokio = { workspace = true }
vbs = { workspace = true }
sequencer-utils = { path = "../utils" }
125 changes: 115 additions & 10 deletions tests/upgrades.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
use std::{path::Path, time::Duration};

use crate::common::TestConfig;
use anyhow::Result;
use espresso_types::{FeeVersion, MarketplaceVersion};
use client::SequencerClient;
use dotenvy::var;
use espresso_types::{EpochVersion, FeeVersion, MarketplaceVersion};
use futures::{future::join_all, StreamExt};
use vbs::version::StaticVersionType;
use sequencer_utils::stake_table::{update_stake_table, PermissionedStakeTableUpdate};
use tokio::time::sleep;
use vbs::version::{StaticVersionType, Version};

const SEQUENCER_BLOCKS_TIMEOUT: u64 = 200;

Expand All @@ -12,10 +18,10 @@ async fn test_upgrade() -> Result<()> {

let testing = TestConfig::new().await.unwrap();

let versions = if testing.sequencer_version as u16 >= MarketplaceVersion::version().minor {
(FeeVersion::version(), MarketplaceVersion::version())
} else {
panic!("Invalid sequencer version provided for upgrade test.");
let (base, upgrade) = match testing.sequencer_version {
3 => (FeeVersion::version(), EpochVersion::version()),
version if version > 3 => (FeeVersion::version(), MarketplaceVersion::version()),
_ => panic!("Invalid sequencer version provided for upgrade test."),
};

println!("Waiting on readiness");
Expand All @@ -26,6 +32,23 @@ async fn test_upgrade() -> Result<()> {

let clients = testing.sequencer_clients;

let height = test_header_version(clients.clone(), base, upgrade).await?;
// check that atleast 50 blocks are produced after the upgrade
test_blocks_production(clients.clone(), height, 50).await?;

if upgrade == EpochVersion::version() {
test_stake_table_update(clients).await?;
}

// TODO assert transactions are incrementing
Ok(())
}

async fn test_header_version(
clients: Vec<SequencerClient>,
base: Version,
upgrade: Version,
) -> Result<u64> {
// Test is limited to those sequencers with correct modules
// enabled. It would be less fragile if we could discover them.
let subscriptions = join_all(clients.iter().map(|c| c.subscribe_headers(0)))
Expand All @@ -34,7 +57,7 @@ async fn test_upgrade() -> Result<()> {
.collect::<anyhow::Result<Vec<_>>>()?;

let mut stream = futures::stream::iter(subscriptions).flatten_unordered(None);

let mut height = 0;
while let Some(header) = stream.next().await {
let header = header.unwrap();
println!(
Expand All @@ -46,11 +69,12 @@ async fn test_upgrade() -> Result<()> {
// TODO is it possible to discover the view at which upgrade should be finished?
// First few views should be `Base` version.
if header.height() <= 20 {
assert_eq!(header.version(), versions.0)
assert_eq!(header.version(), base)
}

if header.version() == versions.1 {
if header.version() == upgrade {
println!("header version matched! height={:?}", header.height());
height = header.height();
break;
}

Expand All @@ -59,6 +83,87 @@ async fn test_upgrade() -> Result<()> {
}
}

// TODO assert transactions are incrementing
Ok(height)
}

async fn test_blocks_production(clients: Vec<SequencerClient>, from: u64, num: u64) -> Result<()> {
let subscriptions = join_all(clients.iter().map(|c| c.subscribe_blocks(from)))
.await
.into_iter()
.collect::<anyhow::Result<Vec<_>>>()?;

let mut num_blocks = 0;

for mut node in subscriptions {
while let Some(block) = node.next().await {
let _block = block.unwrap();
num_blocks += 1;
if num_blocks == num {
break;
}
}

num_blocks = 0;
}

Ok(())
}

async fn test_stake_table_update(clients: Vec<SequencerClient>) -> Result<()> {
/*
EPOCH V3
*/

let rpc_url = var("ESPRESSO_SEQUENCER_L1_PROVIDER")?;
let account_index = var("ESPRESSO_DEPLOYER_ACCOUNT_INDEX")?;
let contract_address = var("ESPRESSO_SEQUENCER_PERMISSIONED_STAKE_TABLE_ADDRESS")?;
let initial_stake_table_path = var("ESPRESSO_SEQUENCER_INITIAL_PERMISSIONED_STAKE_TABLE_PATH")?;

let permissioned_stake_table =
PermissionedStakeTableUpdate::from_toml_file(Path::new(&initial_stake_table_path))?;

// initial stake table has 5 new stakers

let new_stakers = permissioned_stake_table.new_stakers;
//lets remove one
let staker_removed = new_stakers[0].clone();

let st_with_one_removed =
PermissionedStakeTableUpdate::new(vec![staker_removed.clone()], vec![]);
let client = clients[0].clone();

let epoch_before_update = client.current_epoch().await?;

update_stake_table(
rpc_url.parse()?,
Duration::from_secs(7),
"test test test test test test test test test test test junk".to_string(),
account_index.parse()?,
contract_address.parse()?,
st_with_one_removed,
)
.await?;

loop {
sleep(Duration::from_secs(10)).await;
let epoch = clients[0].current_epoch().await?;

if epoch > epoch_before_update {
let stake_table = client.stake_table(epoch).await?;
assert_eq!(stake_table.len(), 4);

assert!(
stake_table
.iter()
.all(|st| st.stake_key != staker_removed.stake_table_key),
"Entry for {} already exists in the stake table",
staker_removed.stake_table_key
);

break;
}
}
// TODO: randomize this test

Ok(())
}
2 changes: 1 addition & 1 deletion types/src/v0/impls/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ fn validate_builder_fee(
// TODO Marketplace signatures are placeholders for now. In
// finished Marketplace signatures will cover the full
// transaction.
if version.minor >= 3 {
if version.minor >= 99 {
imabdulbasit marked this conversation as resolved.
Show resolved Hide resolved
fee_info
.account()
.validate_sequencing_fee_signature_marketplace(
Expand Down
Loading
Loading