Skip to content

Commit

Permalink
add Random package & system object to Sui/framework (MystenLabs#14743)
Browse files Browse the repository at this point in the history
## Description 

Adds a `random` package to Move framework, with `Random` system object
that contains bytes generated by the random beacon protocol running in
narwhal.

Adds code to generate the initial `Random` object at end-of-epoch,
process newly generated randomness from narwhal Certificates and
generate system tx to write it to the Move object.

## Test Plan 

Added some unit tests. More e2e testing to follow once read API is implemented.
  • Loading branch information
aschran authored Nov 17, 2023
1 parent 7e4b3ef commit 908ef63
Show file tree
Hide file tree
Showing 52 changed files with 1,443 additions and 61 deletions.
6 changes: 6 additions & 0 deletions crates/sui-config/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use sui_types::gas_coin::TOTAL_SUPPLY_MIST;
use sui_types::messages_checkpoint::{
CertifiedCheckpointSummary, CheckpointContents, CheckpointSummary, VerifiedCheckpoint,
};
use sui_types::randomness_state::get_randomness_state_obj_initial_shared_version;
use sui_types::sui_system_state::{
get_sui_system_state, get_sui_system_state_wrapper, SuiSystemState, SuiSystemStateTrait,
SuiSystemStateWrapper, SuiValidatorGenesis,
Expand Down Expand Up @@ -159,6 +160,11 @@ impl Genesis {
.expect("Read from genesis cannot fail")
}

pub fn randomness_state_obj_initial_shared_version(&self) -> Option<SequenceNumber> {
get_randomness_state_obj_initial_shared_version(&self.objects())
.expect("Read from genesis cannot fail")
}

pub fn clock(&self) -> Clock {
let clock = self
.objects()
Expand Down
22 changes: 22 additions & 0 deletions crates/sui-core/src/authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3983,6 +3983,25 @@ impl AuthorityState {
Some(tx)
}

#[instrument(level = "debug", skip_all)]
fn create_randomness_state_tx(
&self,
epoch_store: &Arc<AuthorityPerEpochStore>,
) -> Option<EndOfEpochTransactionKind> {
if !epoch_store.protocol_config().random_beacon() {
info!("randomness state transactions not enabled");
return None;
}

if epoch_store.randomness_state_exists() {
return None;
}

let tx = EndOfEpochTransactionKind::new_randomness_state_create();
info!("Creating RandomnessStateCreate tx");
Some(tx)
}

/// Creates and execute the advance epoch transaction to effects without committing it to the database.
/// The effects of the change epoch tx are only written to the database after a certified checkpoint has been
/// formed and executed by CheckpointExecutor.
Expand All @@ -4006,6 +4025,9 @@ impl AuthorityState {
if let Some(tx) = self.create_authenticator_state_tx(epoch_store) {
txns.push(tx);
}
if let Some(tx) = self.create_randomness_state_tx(epoch_store) {
txns.push(tx);
}

let next_epoch = epoch_store.epoch() + 1;

Expand Down
23 changes: 23 additions & 0 deletions crates/sui-core/src/authority/authority_per_epoch_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,18 @@ impl AuthorityPerEpochStore {
.is_some()
}

// Returns true if randomness state is enabled in the protocol config *and* the
// randomness state object already exists
pub fn randomness_state_enabled(&self) -> bool {
self.protocol_config().random_beacon() && self.randomness_state_exists()
}

pub fn randomness_state_exists(&self) -> bool {
self.epoch_start_configuration
.randomness_obj_initial_shared_version()
.is_some()
}

pub fn get_parent_path(&self) -> PathBuf {
self.parent_path.clone()
}
Expand Down Expand Up @@ -1975,6 +1987,10 @@ impl AuthorityPerEpochStore {
return None;
}
}
SequencedConsensusTransactionKind::External(ConsensusTransaction {
kind: ConsensusTransactionKind::RandomnessStateUpdate(_round, _bytes),
..
}) => {}
SequencedConsensusTransactionKind::System(_) => {}
}
Some(VerifiedSequencedConsensusTransaction(transaction))
Expand Down Expand Up @@ -2467,6 +2483,13 @@ impl AuthorityPerEpochStore {
}
Ok(ConsensusCertificateResult::ConsensusMessage)
}
SequencedConsensusTransactionKind::External(ConsensusTransaction {
kind: ConsensusTransactionKind::RandomnessStateUpdate(_, _),
..
}) => {
// These are always generated as System transactions (handled below).
panic!("process_consensus_transaction called with external RandomnessStateUpdate");
}
SequencedConsensusTransactionKind::System(system_transaction) => {
if !self
.get_reconfig_state_read_lock_guard()
Expand Down
1 change: 1 addition & 0 deletions crates/sui-core/src/authority/authority_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ impl AuthorityStore {
genesis.sui_system_object().into_epoch_start_state(),
*genesis.checkpoint().digest(),
genesis.authenticator_state_obj_initial_shared_version(),
genesis.randomness_state_obj_initial_shared_version(),
);
perpetual_tables
.set_epoch_start_configuration(&epoch_start_configuration)
Expand Down
94 changes: 87 additions & 7 deletions crates/sui-core/src/authority/epoch_start_configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub trait EpochStartConfigTrait {
fn epoch_start_state(&self) -> &EpochStartSystemState;
fn flags(&self) -> &[EpochFlag];
fn authenticator_obj_initial_shared_version(&self) -> Option<SequenceNumber>;
fn randomness_obj_initial_shared_version(&self) -> Option<SequenceNumber>;
}

#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
Expand All @@ -33,50 +34,67 @@ pub enum EpochStartConfiguration {
V1(EpochStartConfigurationV1),
V2(EpochStartConfigurationV2),
V3(EpochStartConfigurationV3),
V4(EpochStartConfigurationV4),
}

impl EpochStartConfiguration {
pub fn new(
system_state: EpochStartSystemState,
epoch_digest: CheckpointDigest,
authenticator_obj_initial_shared_version: Option<SequenceNumber>,
randomness_obj_initial_shared_version: Option<SequenceNumber>,
) -> Self {
Self::new_v3(
Self::new_v4(
system_state,
epoch_digest,
EpochFlag::default_flags_for_new_epoch(),
authenticator_obj_initial_shared_version,
randomness_obj_initial_shared_version,
)
}

pub fn new_v1(system_state: EpochStartSystemState, epoch_digest: CheckpointDigest) -> Self {
Self::V1(EpochStartConfigurationV1::new(system_state, epoch_digest))
EpochStartConfigurationV1::new(system_state, epoch_digest).into()
}

pub fn new_v2(
system_state: EpochStartSystemState,
epoch_digest: CheckpointDigest,
flags: Vec<EpochFlag>,
) -> Self {
Self::V2(EpochStartConfigurationV2::new(
EpochStartConfigurationV2::new(system_state, epoch_digest, flags).into()
}

pub fn new_v3(
system_state: EpochStartSystemState,
epoch_digest: CheckpointDigest,
flags: Vec<EpochFlag>,
authenticator_obj_initial_shared_version: Option<SequenceNumber>,
) -> Self {
EpochStartConfigurationV3::new(
system_state,
epoch_digest,
flags,
))
authenticator_obj_initial_shared_version,
)
.into()
}

pub fn new_v3(
pub fn new_v4(
system_state: EpochStartSystemState,
epoch_digest: CheckpointDigest,
flags: Vec<EpochFlag>,
authenticator_obj_initial_shared_version: Option<SequenceNumber>,
randomness_obj_initial_shared_version: Option<SequenceNumber>,
) -> Self {
Self::V3(EpochStartConfigurationV3::new(
EpochStartConfigurationV4::new(
system_state,
epoch_digest,
flags,
authenticator_obj_initial_shared_version,
))
randomness_obj_initial_shared_version,
)
.into()
}

pub fn epoch_data(&self) -> EpochData {
Expand Down Expand Up @@ -118,6 +136,16 @@ pub struct EpochStartConfigurationV3 {
authenticator_obj_initial_shared_version: Option<SequenceNumber>,
}

#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
pub struct EpochStartConfigurationV4 {
system_state: EpochStartSystemState,
epoch_digest: CheckpointDigest,
flags: Vec<EpochFlag>,
/// Do the state objects exist at the beginning of the epoch?
authenticator_obj_initial_shared_version: Option<SequenceNumber>,
randomness_obj_initial_shared_version: Option<SequenceNumber>,
}

impl EpochStartConfigurationV1 {
pub fn new(system_state: EpochStartSystemState, epoch_digest: CheckpointDigest) -> Self {
Self {
Expand Down Expand Up @@ -157,6 +185,24 @@ impl EpochStartConfigurationV3 {
}
}

impl EpochStartConfigurationV4 {
pub fn new(
system_state: EpochStartSystemState,
epoch_digest: CheckpointDigest,
flags: Vec<EpochFlag>,
authenticator_obj_initial_shared_version: Option<SequenceNumber>,
randomness_obj_initial_shared_version: Option<SequenceNumber>,
) -> Self {
Self {
system_state,
epoch_digest,
flags,
authenticator_obj_initial_shared_version,
randomness_obj_initial_shared_version,
}
}
}

impl EpochStartConfigTrait for EpochStartConfigurationV1 {
fn epoch_digest(&self) -> CheckpointDigest {
self.epoch_digest
Expand All @@ -173,6 +219,10 @@ impl EpochStartConfigTrait for EpochStartConfigurationV1 {
fn authenticator_obj_initial_shared_version(&self) -> Option<SequenceNumber> {
None
}

fn randomness_obj_initial_shared_version(&self) -> Option<SequenceNumber> {
None
}
}

impl EpochStartConfigTrait for EpochStartConfigurationV2 {
Expand All @@ -191,6 +241,10 @@ impl EpochStartConfigTrait for EpochStartConfigurationV2 {
fn authenticator_obj_initial_shared_version(&self) -> Option<SequenceNumber> {
None
}

fn randomness_obj_initial_shared_version(&self) -> Option<SequenceNumber> {
None
}
}

impl EpochStartConfigTrait for EpochStartConfigurationV3 {
Expand All @@ -209,6 +263,32 @@ impl EpochStartConfigTrait for EpochStartConfigurationV3 {
fn authenticator_obj_initial_shared_version(&self) -> Option<SequenceNumber> {
self.authenticator_obj_initial_shared_version
}

fn randomness_obj_initial_shared_version(&self) -> Option<SequenceNumber> {
None
}
}

impl EpochStartConfigTrait for EpochStartConfigurationV4 {
fn epoch_digest(&self) -> CheckpointDigest {
self.epoch_digest
}

fn epoch_start_state(&self) -> &EpochStartSystemState {
&self.system_state
}

fn flags(&self) -> &[EpochFlag] {
&self.flags
}

fn authenticator_obj_initial_shared_version(&self) -> Option<SequenceNumber> {
self.authenticator_obj_initial_shared_version
}

fn randomness_obj_initial_shared_version(&self) -> Option<SequenceNumber> {
self.randomness_obj_initial_shared_version
}
}

impl EpochFlag {
Expand Down
1 change: 1 addition & 0 deletions crates/sui-core/src/authority/test_authority_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ impl<'a> TestAuthorityBuilder<'a> {
genesis.sui_system_object().into_epoch_start_state(),
*genesis.checkpoint().digest(),
genesis.authenticator_state_obj_initial_shared_version(),
genesis.randomness_state_obj_initial_shared_version(),
);
let expensive_safety_checks = match self.expensive_safety_checks {
None => ExpensiveSafetyCheckConfig::default(),
Expand Down
1 change: 1 addition & 0 deletions crates/sui-core/src/checkpoints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,7 @@ impl CheckpointBuilder {
transaction.inner().transaction_data().kind(),
TransactionKind::ConsensusCommitPrologue(_)
| TransactionKind::AuthenticatorStateUpdate(_)
| TransactionKind::RandomnessStateUpdate(_)
) {
transaction_keys.push(SequencedConsensusTransactionKey::External(
ConsensusTransactionKey::Certificate(*effects.transaction_digest()),
Expand Down
Loading

0 comments on commit 908ef63

Please sign in to comment.