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

[prover-service] add light client state update logic to epoch QC #2762

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
4 changes: 4 additions & 0 deletions Cargo.lock

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

27 changes: 14 additions & 13 deletions builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ pub mod testing {
},
HotShotConfig, PeerConfig, ValidatorConfig,
};
use jf_signature::bls_over_bn254::VerKey;
use sequencer::{context::Consensus, network, SequencerApiVersion};
use surf_disco::Client;
use vbs::version::StaticVersion;
Expand All @@ -90,7 +89,7 @@ pub mod testing {

#[derive(Clone)]
pub struct HotShotTestConfig {
pub config: HotShotConfig<PubKey>,
pub config: HotShotConfig<SeqTypes>,
priv_keys_staking_nodes: Vec<BLSPrivKey>,
priv_keys_non_staking_nodes: Vec<BLSPrivKey>,
staking_nodes_state_key_pairs: Vec<StateKeyPair>,
Expand All @@ -115,7 +114,7 @@ pub mod testing {

let builder_url = hotshot_builder_url();

let config: HotShotConfig<PubKey> = HotShotConfig {
let config: HotShotConfig<SeqTypes> = HotShotConfig {
num_nodes_with_stake: NonZeroUsize::new(num_nodes_with_stake).unwrap(),
known_da_nodes: known_nodes_with_stake.clone(),
known_nodes_with_stake: known_nodes_with_stake.clone(),
Expand Down Expand Up @@ -157,7 +156,11 @@ pub mod testing {
pub fn generate_stake_table_entries(
num_nodes: u64,
stake_value: u64,
) -> (Vec<BLSPrivKey>, Vec<StateKeyPair>, Vec<PeerConfig<PubKey>>) {
) -> (
Vec<BLSPrivKey>,
Vec<StateKeyPair>,
Vec<PeerConfig<SeqTypes>>,
) {
// Generate keys for the nodes.
let priv_keys = (0..num_nodes)
.map(|_| PrivKey::generate(&mut rand::thread_rng()))
Expand All @@ -173,7 +176,7 @@ pub mod testing {
let nodes_with_stake = pub_keys
.iter()
.zip(&state_key_pairs)
.map(|(pub_key, state_key_pair)| PeerConfig::<PubKey> {
.map(|(pub_key, state_key_pair)| PeerConfig::<SeqTypes> {
stake_table_entry: pub_key.stake_table_entry(stake_value),
state_ver_key: state_key_pair.ver_key(),
})
Expand Down Expand Up @@ -201,11 +204,7 @@ pub mod testing {
pub fn get_anvil(&self) -> Arc<AnvilInstance> {
self.anvil.clone()
}
pub fn get_validator_config(
&self,
i: usize,
is_staked: bool,
) -> ValidatorConfig<hotshot_state_prover::QCVerKey> {
pub fn get_validator_config(&self, i: usize, is_staked: bool) -> ValidatorConfig<SeqTypes> {
if is_staked {
ValidatorConfig {
public_key: self.config.known_nodes_with_stake[i]
Expand All @@ -216,7 +215,8 @@ pub mod testing {
.stake_table_entry
.stake_amount
.as_u64(),
state_key_pair: self.staking_nodes_state_key_pairs[i].clone(),
state_public_key: self.staking_nodes_state_key_pairs[i].ver_key(),
state_private_key: self.staking_nodes_state_key_pairs[i].sign_key(),
is_da: true,
}
} else {
Expand All @@ -226,7 +226,8 @@ pub mod testing {
.stake_key,
private_key: self.priv_keys_non_staking_nodes[i].clone(),
stake_value: 0,
state_key_pair: self.non_staking_nodes_state_key_pairs[i].clone(),
state_public_key: self.non_staking_nodes_state_key_pairs[i].ver_key(),
state_private_key: self.non_staking_nodes_state_key_pairs[i].sign_key(),
is_da: true,
}
}
Expand Down Expand Up @@ -267,7 +268,7 @@ pub mod testing {
// enable hotshot event streaming
pub fn enable_hotshot_node_event_streaming<P: SequencerPersistence, V: Versions>(
hotshot_events_api_url: Url,
known_nodes_with_stake: Vec<PeerConfig<VerKey>>,
known_nodes_with_stake: Vec<PeerConfig<SeqTypes>>,
num_non_staking_nodes: usize,
hotshot_context_handle: Arc<Consensus<network::Memory, P, V>>,
) {
Expand Down
8 changes: 4 additions & 4 deletions contracts/rust/adapter/src/light_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ impl From<contract_bindings_ethers::light_client::LightClientState> for ParsedLi
impl<F: PrimeField> From<ParsedLightClientState> for GenericLightClientState<F> {
fn from(v: ParsedLightClientState) -> Self {
Self {
view_number: v.view_num as usize,
block_height: v.block_height as usize,
view_number: v.view_num,
block_height: v.block_height,
block_comm_root: u256_to_field(v.block_comm_root),
}
}
Expand All @@ -64,8 +64,8 @@ impl<F: PrimeField> From<ParsedLightClientState> for GenericLightClientState<F>
impl<F: PrimeField> From<GenericLightClientState<F>> for ParsedLightClientState {
fn from(v: GenericLightClientState<F>) -> Self {
Self {
view_num: v.view_number as u64,
block_height: v.block_height as u64,
view_num: v.view_number,
block_height: v.block_height,
block_comm_root: field_to_u256(v.block_comm_root),
}
}
Expand Down
14 changes: 10 additions & 4 deletions contracts/rust/adapter/src/stake_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use hotshot_types::{
network::PeerConfigKeys,
signature_key::BLSPubKey,
stake_table::StakeTableEntry,
traits::signature_key::SignatureKey as _,
traits::{node_implementation::NodeType, signature_key::SignatureKey as _},
PeerConfig,
};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -219,7 +219,10 @@ impl From<NodeInfoJf> for StakeTableEntry<BLSPubKey> {
}
}

impl From<NodeInfoJf> for PeerConfig<BLSPubKey> {
impl<TYPES> From<NodeInfoJf> for PeerConfig<TYPES>
where
TYPES: NodeType<SignatureKey = BLSPubKey, StateSignatureKey = StateVerKey>,
{
fn from(value: NodeInfoJf) -> Self {
Self {
stake_table_entry: StakeTableEntry {
Expand Down Expand Up @@ -291,8 +294,11 @@ impl From<NodeInfoAlloy> for NodeInfoJf {
}
}

impl From<PeerConfigKeys<BLSPubKey>> for NodeInfoJf {
fn from(value: PeerConfigKeys<BLSPubKey>) -> Self {
impl<TYPES> From<PeerConfigKeys<TYPES>> for NodeInfoJf
where
TYPES: NodeType<SignatureKey = BLSPubKey, StateSignatureKey = StateVerKey>,
{
fn from(value: PeerConfigKeys<TYPES>) -> Self {
let PeerConfigKeys {
stake_table_key,
state_ver_key,
Expand Down
3 changes: 2 additions & 1 deletion hotshot-builder-core/src/testing/basic_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ mod tests {
};
use hotshot_types::{
data::{vid_commitment, DaProposal2, Leaf2, QuorumProposal2, QuorumProposalWrapper},
signature_key::BuilderKey,
signature_key::{BuilderKey, SchnorrPubKey},
simple_vote::QuorumData2,
traits::{block_contents::BlockHeader, node_implementation::Versions, EncodeBytes},
utils::BuilderCommitment,
Expand Down Expand Up @@ -89,6 +89,7 @@ mod tests {
type Membership = StaticCommittee<Self>;
type BuilderSignatureKey = BuilderKey;
type AuctionResult = TestAuctionResult;
type StateSignatureKey = SchnorrPubKey;
}
// no of test messages to send
let num_test_messages = 5;
Expand Down
9 changes: 5 additions & 4 deletions hotshot-events-service/src/events_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ where
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(bound = "Types::SignatureKey: for<'a> Deserialize<'a>")]
pub struct StartupInfo<Types: NodeType> {
pub known_node_with_stake: Vec<PeerConfig<Types::SignatureKey>>,
pub known_node_with_stake: Vec<PeerConfig<Types>>,
pub non_staked_node_count: usize,
}

Expand All @@ -46,12 +47,12 @@ pub struct EventsStreamer<Types: NodeType> {
subscriber_send_channel: BroadcastSender<Arc<Event<Types>>>,

// required for sending startup info
known_nodes_with_stake: Vec<PeerConfig<Types::SignatureKey>>,
known_nodes_with_stake: Vec<PeerConfig<Types>>,
non_staked_node_count: usize,
}

impl<Types: NodeType> EventsStreamer<Types> {
pub fn known_node_with_stake(&self) -> Vec<PeerConfig<Types::SignatureKey>> {
pub fn known_node_with_stake(&self) -> Vec<PeerConfig<Types>> {
self.known_nodes_with_stake.clone()
}

Expand Down Expand Up @@ -155,7 +156,7 @@ impl<Types: NodeType> EventsSource<Types> for EventsStreamer<Types> {

impl<Types: NodeType> EventsStreamer<Types> {
pub fn new(
known_nodes_with_stake: Vec<PeerConfig<Types::SignatureKey>>,
known_nodes_with_stake: Vec<PeerConfig<Types>>,
non_staked_node_count: usize,
) -> Self {
let (mut subscriber_send_channel, to_subscribe_clone_recv) =
Expand Down
2 changes: 1 addition & 1 deletion hotshot-events-service/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ mod tests {
let pub_key = BLSPubKey::from_private(&private_key);
let state_key_pair = StateKeyPair::generate();

let peer_config = PeerConfig::<BLSPubKey> {
let peer_config = PeerConfig::<TestTypes> {
stake_table_entry: pub_key.stake_table_entry(1),
state_ver_key: state_key_pair.ver_key(),
};
Expand Down
11 changes: 10 additions & 1 deletion hotshot-example-types/src/block_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ use async_trait::async_trait;
use committable::{Commitment, Committable, RawCommitmentBuilder};
use hotshot_types::{
data::{BlockError, Leaf2, VidCommitment},
light_client::LightClientState,
traits::{
block_contents::{BlockHeader, BuilderFee, EncodeBytes, TestableBlock, Transaction},
node_implementation::NodeType,
node_implementation::{ConsensusTime, NodeType},
BlockPayload, ValidatedState,
},
utils::BuilderCommitment,
Expand Down Expand Up @@ -403,6 +404,14 @@ impl<
fn get_auction_results(&self) -> Option<TYPES::AuctionResult> {
Some(TYPES::AuctionResult { urls: vec![] })
}

fn get_light_client_state(&self, view: TYPES::View) -> anyhow::Result<LightClientState> {
LightClientState::new(
view.u64(),
self.block_number,
self.payload_commitment.as_ref(),
)
}
}

impl Committable for TestBlockHeader {
Expand Down
8 changes: 7 additions & 1 deletion hotshot-example-types/src/node_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use hotshot::traits::{
use hotshot_types::{
constants::TEST_UPGRADE_CONSTANTS,
data::{EpochNumber, ViewNumber},
signature_key::{BLSPubKey, BuilderKey},
signature_key::{BLSPubKey, BuilderKey, SchnorrPubKey},
traits::node_implementation::{NodeType, Versions},
upgrade_config::UpgradeConstants,
};
Expand Down Expand Up @@ -67,6 +67,7 @@ impl NodeType for TestTypes {
type InstanceState = TestInstanceState;
type Membership = StaticCommittee<TestTypes>;
type BuilderSignatureKey = BuilderKey;
type StateSignatureKey = SchnorrPubKey;
}

#[derive(
Expand Down Expand Up @@ -99,6 +100,7 @@ impl NodeType for TestTypesRandomizedLeader {
type InstanceState = TestInstanceState;
type Membership = Committee<TestTypesRandomizedLeader>;
type BuilderSignatureKey = BuilderKey;
type StateSignatureKey = SchnorrPubKey;
}

#[derive(
Expand Down Expand Up @@ -129,6 +131,7 @@ impl NodeType for TestTypesEpochCatchupTypes {
type InstanceState = TestInstanceState;
type Membership = DummyCatchupCommittee<TestTypesEpochCatchupTypes>;
type BuilderSignatureKey = BuilderKey;
type StateSignatureKey = SchnorrPubKey;
}

#[derive(
Expand Down Expand Up @@ -165,6 +168,7 @@ impl<CONFIG: QuorumFilterConfig> NodeType for TestTypesRandomizedCommitteeMember
type Membership =
RandomizedCommitteeMembers<TestTypesRandomizedCommitteeMembers<CONFIG>, CONFIG>;
type BuilderSignatureKey = BuilderKey;
type StateSignatureKey = SchnorrPubKey;
}

#[derive(
Expand Down Expand Up @@ -197,6 +201,7 @@ impl NodeType for TestConsecutiveLeaderTypes {
type InstanceState = TestInstanceState;
type Membership = StaticCommitteeLeaderForTwoViews<TestConsecutiveLeaderTypes>;
type BuilderSignatureKey = BuilderKey;
type StateSignatureKey = SchnorrPubKey;
}

#[derive(
Expand Down Expand Up @@ -229,6 +234,7 @@ impl NodeType for TestTwoStakeTablesTypes {
type InstanceState = TestInstanceState;
type Membership = TwoStaticCommittees<TestTwoStakeTablesTypes>;
type BuilderSignatureKey = BuilderKey;
type StateSignatureKey = SchnorrPubKey;
}

/// The Push CDN implementation
Expand Down
30 changes: 29 additions & 1 deletion hotshot-example-types/src/storage_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ use hotshot_types::{
drb::DrbResult,
event::HotShotAction,
message::{convert_proposal, Proposal},
simple_certificate::{NextEpochQuorumCertificate2, QuorumCertificate2, UpgradeCertificate},
simple_certificate::{
LightClientStateUpdateCertificate, NextEpochQuorumCertificate2, QuorumCertificate2,
UpgradeCertificate,
},
traits::{
node_implementation::{ConsensusTime, NodeType},
storage::Storage,
Expand Down Expand Up @@ -59,6 +62,7 @@ pub struct TestStorageState<TYPES: NodeType> {
epoch: Option<TYPES::Epoch>,
drb_results: BTreeMap<TYPES::Epoch, DrbResult>,
epoch_roots: BTreeMap<TYPES::Epoch, TYPES::BlockHeader>,
state_cert: Option<hotshot_types::simple_certificate::LightClientStateUpdateCertificate<TYPES>>,
}

impl<TYPES: NodeType> Default for TestStorageState<TYPES> {
Expand All @@ -78,6 +82,7 @@ impl<TYPES: NodeType> Default for TestStorageState<TYPES> {
epoch: None,
drb_results: BTreeMap::new(),
epoch_roots: BTreeMap::new(),
state_cert: None,
}
}
}
Expand Down Expand Up @@ -141,6 +146,10 @@ impl<TYPES: NodeType> TestStorage<TYPES> {
pub async fn vids_cloned(&self) -> VidShares2<TYPES> {
self.inner.read().await.vid2.clone()
}

pub async fn state_cert_cloned(&self) -> Option<LightClientStateUpdateCertificate<TYPES>> {
self.inner.read().await.state_cert.clone()
}
}

#[async_trait]
Expand Down Expand Up @@ -313,6 +322,25 @@ impl<TYPES: NodeType> Storage<TYPES> for TestStorage<TYPES> {
Ok(())
}

async fn update_state_cert(
&self,
state_cert: hotshot_types::simple_certificate::LightClientStateUpdateCertificate<TYPES>,
) -> Result<()> {
if self.should_return_err {
bail!("Failed to update state_cert to storage");
}
Self::run_delay_settings_from_config(&self.delay_config).await;
let mut inner = self.inner.write().await;
if let Some(ref current_state_cert) = inner.state_cert {
if state_cert.epoch > current_state_cert.epoch {
inner.state_cert = Some(state_cert);
}
} else {
inner.state_cert = Some(state_cert);
}
Ok(())
}

async fn update_next_epoch_high_qc2(
&self,
new_next_epoch_high_qc: hotshot_types::simple_certificate::NextEpochQuorumCertificate2<
Expand Down
Loading