Skip to content

Commit

Permalink
Add time-based configurability for upgrades (#3400)
Browse files Browse the repository at this point in the history
  • Loading branch information
ss-es authored Jun 28, 2024
1 parent 1b35586 commit 2644ba4
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 22 deletions.
8 changes: 8 additions & 0 deletions crates/hotshot/src/tasks/task_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>> CreateTaskState<TYPES, I>
stop_proposing_view: handle.hotshot.config.stop_proposing_view,
start_voting_view: handle.hotshot.config.start_voting_view,
stop_voting_view: handle.hotshot.config.stop_voting_view,
start_proposing_time: handle.hotshot.config.start_proposing_time,
stop_proposing_time: handle.hotshot.config.stop_proposing_time,
start_voting_time: handle.hotshot.config.start_voting_time,
stop_voting_time: handle.hotshot.config.stop_voting_time,
};

#[cfg(feature = "example-upgrade")]
Expand All @@ -88,6 +92,10 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>> CreateTaskState<TYPES, I>
stop_proposing_view: 10,
start_voting_view: 0,
stop_voting_view: 20,
start_proposing_time: 0,
stop_proposing_time: u64::MAX,
start_voting_time: 0,
stop_voting_time: u64::MAX,
};
}
}
Expand Down
8 changes: 6 additions & 2 deletions crates/orchestrator/run-config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,11 @@ secs = 10
nanos = 0

[config.upgrade]
start_proposing_view = 0
start_proposing_view = 1
stop_proposing_view = 0
start_voting_view = 0
start_voting_view = 1
stop_voting_view = 0
start_proposing_time = 1
stop_proposing_time = 0
start_voting_time = 1
stop_voting_time = 0
16 changes: 16 additions & 0 deletions crates/orchestrator/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,14 @@ pub struct UpgradeConfig {
pub start_voting_view: u64,
/// View to stop voting on an upgrade. To prevent voting on an upgrade, set stop_voting_view <= start_voting_view.
pub stop_voting_view: u64,
/// Unix time in seconds at which we start proposing an upgrade
pub start_proposing_time: u64,
/// Unix time in seconds at which we stop proposing an upgrade. To prevent proposing an upgrade, set stop_proposing_time <= start_proposing_time.
pub stop_proposing_time: u64,
/// Unix time in seconds at which we start voting on an upgrade
pub start_voting_time: u64,
/// Unix time in seconds at which we stop voting on an upgrade. To prevent voting on an upgrade, set stop_voting_time <= start_voting_time.
pub stop_voting_time: u64,
}

// Explicitly implementing `Default` for clarity.
Expand All @@ -610,6 +618,10 @@ impl Default for UpgradeConfig {
stop_proposing_view: 0,
start_voting_view: u64::MAX,
stop_voting_view: 0,
start_proposing_time: u64::MAX,
stop_proposing_time: 0,
start_voting_time: u64::MAX,
stop_voting_time: 0,
}
}
}
Expand Down Expand Up @@ -695,6 +707,10 @@ impl<KEY: SignatureKey> From<HotShotConfigFile<KEY>> for HotShotConfig<KEY> {
stop_proposing_view: val.upgrade.stop_proposing_view,
start_voting_view: val.upgrade.start_voting_view,
stop_voting_view: val.upgrade.stop_voting_view,
start_proposing_time: val.upgrade.start_proposing_time,
stop_proposing_time: val.upgrade.stop_proposing_time,
start_voting_time: val.upgrade.start_voting_time,
stop_voting_time: val.upgrade.stop_voting_time,
}
}
}
Expand Down
68 changes: 50 additions & 18 deletions crates/task-impls/src/upgrade.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{marker::PhantomData, sync::Arc};
use std::{marker::PhantomData, sync::Arc, time::SystemTime};

use anyhow::Result;
use async_broadcast::{Receiver, Sender};
Expand All @@ -7,6 +7,10 @@ use async_trait::async_trait;
use committable::Committable;
use hotshot_task::task::TaskState;
use hotshot_types::{
constants::{
UPGRADE_BEGIN_OFFSET, UPGRADE_DECIDE_BY_OFFSET, UPGRADE_FINISH_OFFSET,
UPGRADE_PROPOSE_OFFSET,
},
data::UpgradeProposal,
event::{Event, EventType},
message::Proposal,
Expand Down Expand Up @@ -70,6 +74,18 @@ pub struct UpgradeTaskState<TYPES: NodeType, I: NodeImplementation<TYPES>> {

/// View to stop voting on an upgrade
pub stop_voting_view: u64,

/// Unix time in seconds at which we start proposing an upgrade
pub start_proposing_time: u64,

/// Unix time in seconds at which we stop proposing an upgrade
pub stop_proposing_time: u64,

/// Unix time in seconds at which we start voting on an upgrade
pub start_voting_time: u64,

/// Unix time in seconds at which we stop voting on an upgrade
pub stop_voting_time: u64,
}

impl<TYPES: NodeType, I: NodeImplementation<TYPES>> UpgradeTaskState<TYPES, I> {
Expand All @@ -84,9 +100,17 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>> UpgradeTaskState<TYPES, I> {
HotShotEvent::UpgradeProposalRecv(proposal, sender) => {
info!("Received upgrade proposal: {:?}", proposal);

if *proposal.data.view_number() < self.start_voting_view
|| *proposal.data.view_number() >= self.stop_voting_view
{
let view = *proposal.data.view_number();
let time = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.ok()?
.as_secs();

if time < self.start_voting_time || time >= self.stop_voting_time {
return None;
}

if view < self.start_voting_view || view >= self.stop_voting_view {
return None;
}

Expand Down Expand Up @@ -211,35 +235,43 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES>> UpgradeTaskState<TYPES, I> {
}
}
}
HotShotEvent::ViewChange(view) => {
let view = *view;
if *self.cur_view >= *view {
HotShotEvent::ViewChange(new_view) => {
if self.cur_view >= *new_view {
return None;
}

if *view - *self.cur_view > 1 {
warn!("View changed by more than 1 going to view {:?}", view);
}
self.cur_view = view;
self.cur_view = *new_view;

let view: u64 = *self.cur_view;
let time = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.ok()?
.as_secs();

// We try to form a certificate 5 views before we're leader.
if *view >= self.start_proposing_view
&& *view < self.stop_proposing_view
&& self.quorum_membership.leader(view + 5) == self.public_key
if view >= self.start_proposing_view
&& view < self.stop_proposing_view
&& time >= self.start_proposing_time
&& time < self.stop_proposing_time
&& self
.quorum_membership
.leader(TYPES::Time::new(view + UPGRADE_PROPOSE_OFFSET))
== self.public_key
{
let upgrade_proposal_data = UpgradeProposalData {
old_version: TYPES::Base::VERSION,
new_version: TYPES::Upgrade::VERSION,
new_version_hash: TYPES::UPGRADE_HASH.to_vec(),
// We schedule the upgrade to begin 15 views in the future
old_version_last_view: TYPES::Time::new(*view + 15),
old_version_last_view: TYPES::Time::new(view + UPGRADE_BEGIN_OFFSET),
// and end 20 views in the future
new_version_first_view: TYPES::Time::new(*view + 20),
decide_by: TYPES::Time::new(*view + 10),
new_version_first_view: TYPES::Time::new(view + UPGRADE_FINISH_OFFSET),
decide_by: TYPES::Time::new(view + UPGRADE_DECIDE_BY_OFFSET),
};

let upgrade_proposal = UpgradeProposal {
upgrade_proposal: upgrade_proposal_data.clone(),
view_number: view + 5,
view_number: TYPES::Time::new(view + UPGRADE_PROPOSE_OFFSET),
};

let signature = TYPES::SignatureKey::sign(
Expand Down
8 changes: 6 additions & 2 deletions crates/testing/src/test_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,10 +330,14 @@ impl TestDescription {
data_request_delay: Duration::from_millis(200),
// Placeholder until we spin up the builder
builder_urls: vec1::vec1![Url::parse("http://localhost:9999").expect("Valid URL")],
start_proposing_view: 0,
start_proposing_view: u64::MAX,
stop_proposing_view: 0,
start_voting_view: 0,
start_voting_view: u64::MAX,
stop_voting_view: 0,
start_proposing_time: u64::MAX,
stop_proposing_time: 0,
start_voting_time: u64::MAX,
stop_voting_time: 0,
};
let TimingData {
next_view_timeout,
Expand Down
12 changes: 12 additions & 0 deletions crates/types/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ pub type WebServerVersion = StaticVersion<WEB_SERVER_MAJOR_VERSION, WEB_SERVER_M
/// Constant for Web Server CDN Version
pub const WEB_SERVER_VERSION: WebServerVersion = StaticVersion {};

/// The offset for how far in the future we will send out a `QuorumProposal` with an `UpgradeCertificate` we form. This is also how far in advance of sending a `QuorumProposal` we begin collecting votes on an `UpgradeProposal`.
pub const UPGRADE_PROPOSE_OFFSET: u64 = 5;

/// The offset for how far in the future the upgrade certificate we attach should be decided on (or else discarded).
pub const UPGRADE_DECIDE_BY_OFFSET: u64 = UPGRADE_PROPOSE_OFFSET + 5;

/// The offset for how far in the future the upgrade actually begins.
pub const UPGRADE_BEGIN_OFFSET: u64 = UPGRADE_DECIDE_BY_OFFSET + 5;

/// The offset for how far in the future the upgrade ends.
pub const UPGRADE_FINISH_OFFSET: u64 = UPGRADE_BEGIN_OFFSET + 5;

/// For `STAKE_TABLE_CAPACITY=200`, the light client prover (a.k.a. `hotshot-state-prover`)
/// would need to generate proof for a circuit of slightly below 2^20 gates.
/// Thus we need to support this upperbounded degree in our Structured Reference String (SRS),
Expand Down
8 changes: 8 additions & 0 deletions crates/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,4 +210,12 @@ pub struct HotShotConfig<KEY: SignatureKey> {
pub start_voting_view: u64,
/// View to stop voting on an upgrade. To prevent voting on an upgrade, set stop_voting_view <= start_voting_view.
pub stop_voting_view: u64,
/// Unix time in seconds at which we start proposing an upgrade
pub start_proposing_time: u64,
/// Unix time in seconds at which we stop proposing an upgrade. To prevent proposing an upgrade, set stop_proposing_time <= start_proposing_time.
pub stop_proposing_time: u64,
/// Unix time in seconds at which we start voting on an upgrade
pub start_voting_time: u64,
/// Unix time in seconds at which we stop voting on an upgrade. To prevent voting on an upgrade, set stop_voting_time <= start_voting_time.
pub stop_voting_time: u64,
}

0 comments on commit 2644ba4

Please sign in to comment.