Skip to content

Commit

Permalink
deploy: load initial stake table from toml file
Browse files Browse the repository at this point in the history
  • Loading branch information
sveitser committed Nov 27, 2024
1 parent beed539 commit c919dd1
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 20 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ services:

deploy-sequencer-contracts:
image: ghcr.io/espressosystems/espresso-sequencer/deploy:main
command: deploy --only fee-contract
command: deploy --only sequencer,permissioned-stake-table
environment:
- ESPRESSO_SEQUENCER_ETH_MULTISIG_ADDRESS
- ESPRESSO_SEQUENCER_L1_PROVIDER
Expand Down
25 changes: 25 additions & 0 deletions sequencer/src/bin/deploy.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use std::{fs::File, io::stdout, path::PathBuf};

use clap::Parser;
use espresso_types::PubKey;
use ethers::types::Address;
use futures::FutureExt;
use hotshot_stake_table::config::STAKE_TABLE_CAPACITY;
use hotshot_state_prover::service::light_client_genesis;
use sequencer_utils::{
deployer::{deploy, ContractGroup, Contracts, DeployedContracts},
logging,
stake_table::PermissionedStakeTableConfig,
};
use url::Url;

Expand Down Expand Up @@ -111,6 +113,20 @@ struct Options {
#[clap(long, env = "ESPRESSO_SEQUENCER_PERMISSIONED_PROVER")]
permissioned_prover: Option<Address>,

/// A toml file with the initial stake table.
///
/// Schema:
///
/// public_keys = [
/// {
/// stake_table_key = "BLS_VER_KEY~bQszS-QKYvUij2g20VqS8asttGSb95NrTu2PUj0uMh1CBUxNy1FqyPDjZqB29M7ZbjWqj79QkEOWkpga84AmDYUeTuWmy-0P1AdKHD3ehc-dKvei78BDj5USwXPJiDUlCxvYs_9rWYhagaq-5_LXENr78xel17spftNd5MA1Mw5U",

Check warning on line 122 in sequencer/src/bin/deploy.rs

View workflow job for this annotation

GitHub Actions / typos

"Ue" should be "Use" or "Due".

Check warning on line 122 in sequencer/src/bin/deploy.rs

View workflow job for this annotation

GitHub Actions / typos

"Nd" should be "And".
/// state_ver_key = "SCHNORR_VER_KEY~lJqDaVZyM0hWP2Br52IX5FeE-dCAIC-dPX7bL5-qUx-vjbunwe-ENOeZxj6FuOyvDCFzoGeP7yZ0fM995qF-CRE",
/// da = true,
/// },
/// ]
#[clap(long, env = "ESPRESSO_SEQUENCER_INITIAL_PERMISSIONED_STAKE_TABLE_PATH")]
initial_stake_table_path: Option<PathBuf>,

#[clap(flatten)]
logging: logging::Config,
}
Expand All @@ -126,6 +142,14 @@ async fn main() -> anyhow::Result<()> {

let genesis = light_client_genesis(&sequencer_url, opt.stake_table_capacity).boxed();

let initial_stake_table = if let Some(path) = opt.initial_stake_table_path {
Some(PermissionedStakeTableConfig::<PubKey>::from_toml_file(
&path,
)?)
} else {
None
};

let contracts = deploy(
opt.rpc_url,
opt.mnemonic,
Expand All @@ -136,6 +160,7 @@ async fn main() -> anyhow::Result<()> {
genesis,
opt.permissioned_prover,
contracts,
initial_stake_table,
)
.await?;

Expand Down
1 change: 1 addition & 0 deletions types/src/v0/v0_3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ pub use chain_config::*;
pub use fee_info::IterableFeeInfo;
pub use header::Header;
pub use solver::*;
pub use stake_table::CombinedStakeTable;
40 changes: 22 additions & 18 deletions types/src/v0/v0_3/stake_table.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,40 @@
use ark_ec::{short_weierstrass, twisted_edwards};
use crate::PubKey;
use ark_ec::{bn, short_weierstrass, twisted_edwards};
use ark_ed_on_bn254::EdwardsConfig;
use contract_bindings::permissioned_stake_table::{EdOnBN254Point, NodeInfo};
use derive_more::derive::From;
use ethers::types::U256;
use hotshot::types::{BLSPubKey, SignatureKey};
use hotshot_contract_adapter::stake_table::ParsedG1Point;
use hotshot_types::{light_client::StateVerKey, stake_table::StakeTableEntry, PeerConfig};
use hotshot_types::{light_client::StateVerKey, network::PeerConfigKeys};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize, From)]
struct PermissionedPeerConfig(pub(crate) PeerConfig<BLSPubKey>);
pub struct PermissionedPeerConfig(pub(crate) PeerConfigKeys<PubKey>);

/// Stake table holding all staking information (DA and non-DA stakers)
#[derive(Debug, Clone, Serialize, Deserialize, From)]
pub struct CombinedStakeTable(Vec<PeerConfigKeys<PubKey>>);

impl From<NodeInfo> for PermissionedPeerConfig {
fn from(node_info: NodeInfo) -> Self {
let NodeInfo {
bls_vk,
schnorr_vk,
// TODO: handle DA flag
..
is_da,
} = node_info;
let stake_table_entry = {
let stake_table_key = {
let g2 = diff_test_bn254::ParsedG2Point {
x0: bls_vk.x_0,
x1: bls_vk.x_1,
y0: bls_vk.y_0,
y1: bls_vk.y_1,
};
let g2_affine = short_weierstrass::Affine::<ark_bn254::g2::Config>::from(g2);
// let g2_proj = bn::G2Projective::from(g2_affine);
// TODO
let stake_key = BLSPubKey::generated_from_seed_indexed(Default::default(), 0).0;
StakeTableEntry {
stake_key,
stake_amount: U256::from(0),
// TODO: maybe this works until I find a better way
let g2_proj = bn::G2Projective::<ark_bn254::Config>::from(g2_affine);
unsafe {
std::mem::transmute::<short_weierstrass::Projective<ark_bn254::g2::Config>, PubKey>(
g2_proj,
)
}
};
let state_ver_key = {
Expand All @@ -41,13 +43,15 @@ impl From<NodeInfo> for PermissionedPeerConfig {
let state_sk_affine = twisted_edwards::Affine::<EdwardsConfig>::from(g1_point);
StateVerKey::from(state_sk_affine)
};
PeerConfig {
stake_table_entry,
PeerConfigKeys {
stake_table_key,
state_ver_key,
da: is_da,
stake: 1,
}
.into()
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
struct StakeTable(Vec<PeerConfig<BLSPubKey>>);
// #[derive(Debug, Clone, Serialize, Deserialize)]
// struct StakeTable(Vec<PeerConfig<BLSPubKey>>);
2 changes: 2 additions & 0 deletions utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ derive_more = { workspace = true }
ethers = { workspace = true }
futures = { workspace = true }
hotshot = { workspace = true }
hotshot-types = { workspace = true }
hotshot-contract-adapter = { workspace = true }
log-panics = { workspace = true }
portpicker = { workspace = true }
Expand All @@ -29,5 +30,6 @@ serde_json = "^1.0.113"
surf = "2.3.2"
tempfile = { workspace = true }
tokio = { workspace = true }
toml = { workspace = true }
tracing = "0.1.37"
url = "2.3.1"
38 changes: 37 additions & 1 deletion utils/src/deployer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use contract_bindings::{
light_client_mock::LIGHTCLIENTMOCK_ABI,
light_client_state_update_vk::LightClientStateUpdateVK,
light_client_state_update_vk_mock::LightClientStateUpdateVKMock,
permissioned_stake_table::PermissionedStakeTable,
plonk_verifier::PlonkVerifier,
};
use derive_more::Display;
Expand All @@ -15,13 +16,16 @@ use ethers::{
utils::hex,
};
use futures::future::{BoxFuture, FutureExt};
use hotshot::types::SignatureKey;
use hotshot_contract_adapter::light_client::{
LightClientConstructorArgs, ParsedLightClientState, ParsedStakeTableState,
};
use std::sync::Arc;
use std::{collections::HashMap, io::Write, ops::Deref};
use url::Url;

use crate::stake_table::PermissionedStakeTableConfig;

/// Set of predeployed contracts.
#[derive(Clone, Debug, Parser)]
pub struct DeployedContracts {
Expand All @@ -48,6 +52,10 @@ pub struct DeployedContracts {
/// Use an already-deployed FeeContract.sol proxy instead of deploying a new one.
#[clap(long, env = Contract::FeeContractProxy)]
fee_contract_proxy: Option<Address>,

/// Use an already-deployed PermissonedStakeTable.sol proxy instead of deploying a new one.
#[clap(long, env = Contract::FeeContractProxy)]
permissioned_stake_table: Option<Address>,
}

/// An identifier for a particular contract.
Expand All @@ -65,6 +73,8 @@ pub enum Contract {
FeeContract,
#[display("ESPRESSO_SEQUENCER_FEE_CONTRACT_PROXY_ADDRESS")]
FeeContractProxy,
#[display("ESPRESSO_SEQUENCER_PERMISSIONED_STAKE_TABLE_ADDRESS")]
PermissonedStakeTable,
}

impl From<Contract> for OsStr {
Expand Down Expand Up @@ -98,6 +108,9 @@ impl From<DeployedContracts> for Contracts {
if let Some(addr) = deployed.fee_contract_proxy {
m.insert(Contract::FeeContractProxy, addr);
}
if let Some(addr) = deployed.permissioned_stake_table {
m.insert(Contract::PermissonedStakeTable, addr);
}
Self(m)
}
}
Expand Down Expand Up @@ -298,7 +311,7 @@ pub async fn deploy_mock_light_client_contract<M: Middleware + 'static>(
}

#[allow(clippy::too_many_arguments)]
pub async fn deploy(
pub async fn deploy<K: SignatureKey>(
l1url: Url,
mnemonic: String,
account_index: u32,
Expand All @@ -308,6 +321,7 @@ pub async fn deploy(
genesis: BoxFuture<'_, anyhow::Result<(ParsedLightClientState, ParsedStakeTableState)>>,
permissioned_prover: Option<Address>,
mut contracts: Contracts,
initial_stake_table: Option<PermissionedStakeTableConfig<K>>,
) -> anyhow::Result<Contracts> {
let provider = Provider::<Http>::try_from(l1url.to_string())?;
let chain_id = provider.get_chainid().await?.as_u64();
Expand Down Expand Up @@ -426,6 +440,27 @@ pub async fn deploy(
}
}

// `PermissionedStakeTable.sol`
if should_deploy(ContractGroup::PermissionedStakeTable, &only) {
let stake_table_address = contracts
.deploy_tx(
Contract::PermissonedStakeTable,
PermissionedStakeTable::deploy(l1.clone(), ())?,
)
.await?;
let stake_table = PermissionedStakeTable::new(stake_table_address, l1.clone());

// Transfer ownership to the multisig wallet if provided.
if let Some(owner) = multisig_address {
tracing::info!(
%stake_table_address,
%owner,
"transferring fee contract proxy ownership to multisig",
);
stake_table.transfer_ownership(owner).send().await?.await?;
}
}

Ok(contracts)
}

Expand Down Expand Up @@ -459,6 +494,7 @@ pub async fn is_proxy_contract(
pub enum ContractGroup {
FeeContract,
LightClient,
PermissionedStakeTable,
}

#[cfg(any(test, feature = "testing"))]
Expand Down
1 change: 1 addition & 0 deletions utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub mod blocknative;
pub mod deployer;
pub mod logging;
pub mod ser;
pub mod stake_table;
pub mod test_utils;

pub type Signer = SignerMiddleware<Provider<Http>, LocalWallet>;
Expand Down
27 changes: 27 additions & 0 deletions utils/src/stake_table.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use hotshot::types::SignatureKey;
use hotshot_types::network::PeerConfigKeys;
use std::{fs, path::Path};

/// A stake table config stored in a file
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
#[serde(bound(deserialize = ""))]
pub struct PermissionedStakeTableConfig<K: SignatureKey> {
/// The list of public keys that are initially inserted into the
/// permissioned stake table contract.
#[serde(default)]
pub public_keys: Vec<PeerConfigKeys<K>>,
}

impl<K: SignatureKey> PermissionedStakeTableConfig<K> {
pub fn from_toml_file(path: &Path) -> anyhow::Result<Self> {
let config_file_as_string: String = fs::read_to_string(path)
.unwrap_or_else(|_| panic!("Could not read config file located at {}", path.display()));

Ok(
toml::from_str::<Self>(&config_file_as_string).expect(&format!(
"Unable to convert config file {} to TOML",
path.display()
)),
)
}
}

0 comments on commit c919dd1

Please sign in to comment.