language/diem-framework/releases/artifacts/release-1.2.0-rc0/docs/modules/DiemConfig.md
<a name="0x1_DiemConfig"></a>
0x1::DiemConfigPublishes configuration information for validators, and issues reconfiguration events to synchronize configuration changes for the validators.
DiemConfigNewEpochEventConfigurationModifyConfigCapabilityDisableReconfigurationinitializegetsetset_with_capability_and_reconfiguredisable_reconfigurationenable_reconfigurationreconfiguration_enabledpublish_new_config_and_get_capabilitypublish_new_configreconfigurereconfigure_emit_genesis_reconfiguration_event<a name="0x1_DiemConfig_DiemConfig"></a>
DiemConfigA generic singleton resource that holds a value of a specific type.
<pre><code><b>resource</b> <b>struct</b> <a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><Config: <b>copyable</b>> </code></pre> <details> <summary>Fields</summary> <dl> <dt> <code>payload: Config</code> </dt> <dd> Holds specific info for instance of <code>Config</code> type. </dd> </dl> </details><a name="0x1_DiemConfig_NewEpochEvent"></a>
NewEpochEventEvent that signals DiemBFT algorithm to start a new epoch, with new configuration information. This is also called a "reconfiguration event"
<pre><code><b>struct</b> <a href="DiemConfig.md#0x1_DiemConfig_NewEpochEvent">NewEpochEvent</a> </code></pre> <details> <summary>Fields</summary> <dl> <dt> <code>epoch: u64</code> </dt> <dd> </dd> </dl> </details><a name="0x1_DiemConfig_Configuration"></a>
ConfigurationHolds information about state of reconfiguration
<pre><code><b>resource</b> <b>struct</b> <a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a> </code></pre> <details> <summary>Fields</summary> <dl> <dt> <code>epoch: u64</code> </dt> <dd> Epoch number </dd> <dt> <code>last_reconfiguration_time: u64</code> </dt> <dd> Time of last reconfiguration. Only changes on reconfiguration events. </dd> <dt> <code>events: <a href="../../../../../../move-stdlib/docs/Event.md#0x1_Event_EventHandle">Event::EventHandle</a><<a href="DiemConfig.md#0x1_DiemConfig_NewEpochEvent">DiemConfig::NewEpochEvent</a>></code> </dt> <dd> Event handle for reconfiguration events </dd> </dl> </details><a name="0x1_DiemConfig_ModifyConfigCapability"></a>
ModifyConfigCapabilityAccounts with this privilege can modify DiemConfig<TypeName> under Diem root address.
<pre><code><b>resource</b> <b>struct</b> <a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">ModifyConfigCapability</a><TypeName> </code></pre> <details> <summary>Fields</summary> <dl> <dt> <code>dummy_field: bool</code> </dt> <dd> </dd> </dl> </details><a name="0x1_DiemConfig_DisableReconfiguration"></a>
DisableReconfigurationReconfiguration disabled if this resource occurs under LibraRoot.
<pre><code><b>resource</b> <b>struct</b> <a href="DiemConfig.md#0x1_DiemConfig_DisableReconfiguration">DisableReconfiguration</a> </code></pre> <details> <summary>Fields</summary> <dl> <dt> <code>dummy_field: bool</code> </dt> <dd> </dd> </dl> </details><a name="@Constants_0"></a>
<a name="0x1_DiemConfig_MAX_U64"></a>
The largest possible u64 value
<pre><code><b>const</b> <a href="DiemConfig.md#0x1_DiemConfig_MAX_U64">MAX_U64</a>: u64 = 18446744073709551615; </code></pre><a name="0x1_DiemConfig_ECONFIGURATION"></a>
The <code><a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a></code> resource is in an invalid state
<pre><code><b>const</b> <a href="DiemConfig.md#0x1_DiemConfig_ECONFIGURATION">ECONFIGURATION</a>: u64 = 0; </code></pre><a name="0x1_DiemConfig_EDIEM_CONFIG"></a>
A <code><a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a></code> resource is in an invalid state
<pre><code><b>const</b> <a href="DiemConfig.md#0x1_DiemConfig_EDIEM_CONFIG">EDIEM_CONFIG</a>: u64 = 1; </code></pre><a name="0x1_DiemConfig_EINVALID_BLOCK_TIME"></a>
An invalid block time was encountered.
<pre><code><b>const</b> <a href="DiemConfig.md#0x1_DiemConfig_EINVALID_BLOCK_TIME">EINVALID_BLOCK_TIME</a>: u64 = 3; </code></pre><a name="0x1_DiemConfig_EMODIFY_CAPABILITY"></a>
A <code><a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">ModifyConfigCapability</a></code> is in a different state than was expected
<pre><code><b>const</b> <a href="DiemConfig.md#0x1_DiemConfig_EMODIFY_CAPABILITY">EMODIFY_CAPABILITY</a>: u64 = 2; </code></pre><a name="0x1_DiemConfig_initialize"></a>
initializePublishes <code><a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a></code> resource. Can only be invoked by Diem root, and only a single time in Genesis.
<pre><code><b>public</b> <b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_initialize">initialize</a>(dr_account: &signer) </code></pre> <details> <summary>Implementation</summary> <pre><code><b>public</b> <b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_initialize">initialize</a>( dr_account: &signer, ) { <a href="DiemTimestamp.md#0x1_DiemTimestamp_assert_genesis">DiemTimestamp::assert_genesis</a>(); <a href="CoreAddresses.md#0x1_CoreAddresses_assert_diem_root">CoreAddresses::assert_diem_root</a>(dr_account); <b>assert</b>(!<b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()), <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_already_published">Errors::already_published</a>(<a href="DiemConfig.md#0x1_DiemConfig_ECONFIGURATION">ECONFIGURATION</a>)); move_to<<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>( dr_account, <a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a> { epoch: 0, last_reconfiguration_time: 0, events: <a href="../../../../../../move-stdlib/docs/Event.md#0x1_Event_new_event_handle">Event::new_event_handle</a><<a href="DiemConfig.md#0x1_DiemConfig_NewEpochEvent">NewEpochEvent</a>>(dr_account), } ); } </code></pre> </details> <details> <summary>Specification</summary> <pre><code><b>pragma</b> opaque; <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_InitializeAbortsIf">InitializeAbortsIf</a>; <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_InitializeEnsures">InitializeEnsures</a>; <b>modifies</b> <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <b>modifies</b> <b>global</b><<a href="../../../../../../move-stdlib/docs/Event.md#0x1_Event_EventHandleGenerator">Event::EventHandleGenerator</a>>(<a href="../../../../../../move-stdlib/docs/Signer.md#0x1_Signer_spec_address_of">Signer::spec_address_of</a>(dr_account)); </code></pre><a name="0x1_DiemConfig_InitializeAbortsIf"></a>
<pre><code><b>schema</b> <a href="DiemConfig.md#0x1_DiemConfig_InitializeAbortsIf">InitializeAbortsIf</a> { dr_account: signer; <b>include</b> <a href="DiemTimestamp.md#0x1_DiemTimestamp_AbortsIfNotGenesis">DiemTimestamp::AbortsIfNotGenesis</a>; <b>include</b> <a href="CoreAddresses.md#0x1_CoreAddresses_AbortsIfNotDiemRoot">CoreAddresses::AbortsIfNotDiemRoot</a>{account: dr_account}; <b>aborts_if</b> <a href="DiemConfig.md#0x1_DiemConfig_spec_has_config">spec_has_config</a>() <b>with</b> <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_ALREADY_PUBLISHED">Errors::ALREADY_PUBLISHED</a>; } </code></pre><a name="0x1_DiemConfig_InitializeEnsures"></a>
<pre><code><b>schema</b> <a href="DiemConfig.md#0x1_DiemConfig_InitializeEnsures">InitializeEnsures</a> { <b>ensures</b> <a href="DiemConfig.md#0x1_DiemConfig_spec_has_config">spec_has_config</a>(); <a name="0x1_DiemConfig_new_config$16"></a> <b>let</b> new_config = <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <b>ensures</b> new_config.epoch == 0; <b>ensures</b> new_config.last_reconfiguration_time == 0; } </code></pre> </details><a name="0x1_DiemConfig_get"></a>
getReturns a copy of <code>Config</code> value stored under <code>addr</code>.
<pre><code><b>public</b> <b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_get">get</a><Config: <b>copyable</b>>(): Config </code></pre> <details> <summary>Implementation</summary> <pre><code><b>public</b> <b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_get">get</a><Config: <b>copy</b> + drop + store>(): Config <b>acquires</b> <a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a> { <b>let</b> addr = <a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>(); <b>assert</b>(<b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><Config>>(addr), <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_not_published">Errors::not_published</a>(<a href="DiemConfig.md#0x1_DiemConfig_EDIEM_CONFIG">EDIEM_CONFIG</a>)); *&borrow_global<<a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><Config>>(addr).payload } </code></pre> </details> <details> <summary>Specification</summary> <pre><code><b>pragma</b> opaque; <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_AbortsIfNotPublished">AbortsIfNotPublished</a><Config>; <b>ensures</b> result == <a href="DiemConfig.md#0x1_DiemConfig_get">get</a><Config>(); </code></pre><a name="0x1_DiemConfig_AbortsIfNotPublished"></a>
<pre><code><b>schema</b> <a href="DiemConfig.md#0x1_DiemConfig_AbortsIfNotPublished">AbortsIfNotPublished</a><Config> { <b>aborts_if</b> !<b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><Config>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()) <b>with</b> <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_NOT_PUBLISHED">Errors::NOT_PUBLISHED</a>; } </code></pre> </details><a name="0x1_DiemConfig_set"></a>
setSet a config item to a new value with the default capability stored under config address and trigger a reconfiguration. This function requires that the signer have a <code><a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">ModifyConfigCapability</a><Config></code> resource published under it.
<pre><code><b>public</b> <b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_set">set</a><Config: <b>copyable</b>>(account: &signer, payload: Config) </code></pre> <details> <summary>Implementation</summary> <pre><code><b>public</b> <b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_set">set</a><Config: <b>copy</b> + drop + store>(account: &signer, payload: Config) <b>acquires</b> <a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a>, <a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a> { <b>let</b> signer_address = <a href="../../../../../../move-stdlib/docs/Signer.md#0x1_Signer_address_of">Signer::address_of</a>(account); // Next should always be <b>true</b> <b>if</b> properly initialized. <b>assert</b>(<b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">ModifyConfigCapability</a><Config>>(signer_address), <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_requires_capability">Errors::requires_capability</a>(<a href="DiemConfig.md#0x1_DiemConfig_EMODIFY_CAPABILITY">EMODIFY_CAPABILITY</a>)); <b>let</b> addr = <a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>(); <b>assert</b>(<b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><Config>>(addr), <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_not_published">Errors::not_published</a>(<a href="DiemConfig.md#0x1_DiemConfig_EDIEM_CONFIG">EDIEM_CONFIG</a>)); <b>let</b> config = borrow_global_mut<<a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><Config>>(addr); config.payload = payload; <a href="DiemConfig.md#0x1_DiemConfig_reconfigure_">reconfigure_</a>(); } </code></pre> </details> <details> <summary>Specification</summary>TODO: turned off verification until we solve the generic type/specific invariant issue
<pre><code><b>pragma</b> opaque, verify = <b>false</b>; <b>modifies</b> <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <b>modifies</b> <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><Config>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_SetAbortsIf">SetAbortsIf</a><Config>; <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_SetEnsures">SetEnsures</a><Config>; </code></pre><a name="0x1_DiemConfig_SetAbortsIf"></a>
<pre><code><b>schema</b> <a href="DiemConfig.md#0x1_DiemConfig_SetAbortsIf">SetAbortsIf</a><Config> { account: signer; <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_AbortsIfNotModifiable">AbortsIfNotModifiable</a><Config>; <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_AbortsIfNotPublished">AbortsIfNotPublished</a><Config>; <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_ReconfigureAbortsIf">ReconfigureAbortsIf</a>; } </code></pre><a name="0x1_DiemConfig_AbortsIfNotModifiable"></a>
<pre><code><b>schema</b> <a href="DiemConfig.md#0x1_DiemConfig_AbortsIfNotModifiable">AbortsIfNotModifiable</a><Config> { account: signer; <b>aborts_if</b> !<b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">ModifyConfigCapability</a><Config>>(<a href="../../../../../../move-stdlib/docs/Signer.md#0x1_Signer_spec_address_of">Signer::spec_address_of</a>(account)) <b>with</b> <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_REQUIRES_CAPABILITY">Errors::REQUIRES_CAPABILITY</a>; } </code></pre><a name="0x1_DiemConfig_SetEnsures"></a>
<pre><code><b>schema</b> <a href="DiemConfig.md#0x1_DiemConfig_SetEnsures">SetEnsures</a><Config> { payload: Config; <b>ensures</b> <a href="DiemConfig.md#0x1_DiemConfig_spec_is_published">spec_is_published</a><Config>(); <b>ensures</b> <a href="DiemConfig.md#0x1_DiemConfig_get">get</a><Config>() == payload; <b>ensures</b> <b>old</b>(<a href="DiemConfig.md#0x1_DiemConfig_spec_has_config">spec_has_config</a>()) == <a href="DiemConfig.md#0x1_DiemConfig_spec_has_config">spec_has_config</a>(); } </code></pre> </details><a name="0x1_DiemConfig_set_with_capability_and_reconfigure"></a>
set_with_capability_and_reconfigureSet a config item to a new value and trigger a reconfiguration. This function requires a reference to a <code><a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">ModifyConfigCapability</a></code>, which is returned when the config is published using <code>publish_new_config_and_get_capability</code>. It is called by <code><a href="DiemSystem.md#0x1_DiemSystem_update_config_and_reconfigure">DiemSystem::update_config_and_reconfigure</a></code>, which allows validator operators to change the validator set. All other config changes require a Diem root signer.
<pre><code><b>public</b> <b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_set_with_capability_and_reconfigure">set_with_capability_and_reconfigure</a><Config: <b>copyable</b>>(_cap: &<a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">DiemConfig::ModifyConfigCapability</a><Config>, payload: Config) </code></pre> <details> <summary>Implementation</summary> <pre><code><b>public</b> <b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_set_with_capability_and_reconfigure">set_with_capability_and_reconfigure</a><Config: <b>copy</b> + drop + store>( _cap: &<a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">ModifyConfigCapability</a><Config>, payload: Config ) <b>acquires</b> <a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a>, <a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a> { <b>let</b> addr = <a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>(); <b>assert</b>(<b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><Config>>(addr), <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_not_published">Errors::not_published</a>(<a href="DiemConfig.md#0x1_DiemConfig_EDIEM_CONFIG">EDIEM_CONFIG</a>)); <b>let</b> config = borrow_global_mut<<a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><Config>>(addr); config.payload = payload; <a href="DiemConfig.md#0x1_DiemConfig_reconfigure_">reconfigure_</a>(); } </code></pre> </details> <details> <summary>Specification</summary>TODO: turned off verification until we solve the generic type/specific invariant issue
<pre><code><b>pragma</b> opaque, verify = <b>false</b>; <b>modifies</b> <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_AbortsIfNotPublished">AbortsIfNotPublished</a><Config>; <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_ReconfigureAbortsIf">ReconfigureAbortsIf</a>; <b>modifies</b> <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><Config>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_SetEnsures">SetEnsures</a><Config>; <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_ReconfigureEmits">ReconfigureEmits</a>; </code></pre> </details><a name="0x1_DiemConfig_disable_reconfiguration"></a>
disable_reconfigurationPrivate function to temporarily halt reconfiguration. This function should only be used for offline WriteSet generation purpose and should never be invoked on chain.
<pre><code><b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_disable_reconfiguration">disable_reconfiguration</a>(dr_account: &signer) </code></pre> <details> <summary>Implementation</summary> <pre><code><b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_disable_reconfiguration">disable_reconfiguration</a>(dr_account: &signer) { <b>assert</b>( <a href="../../../../../../move-stdlib/docs/Signer.md#0x1_Signer_address_of">Signer::address_of</a>(dr_account) == <a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>(), <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_requires_address">Errors::requires_address</a>(<a href="DiemConfig.md#0x1_DiemConfig_EDIEM_CONFIG">EDIEM_CONFIG</a>) ); <a href="Roles.md#0x1_Roles_assert_diem_root">Roles::assert_diem_root</a>(dr_account); <b>assert</b>(<a href="DiemConfig.md#0x1_DiemConfig_reconfiguration_enabled">reconfiguration_enabled</a>(), <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_invalid_state">Errors::invalid_state</a>(<a href="DiemConfig.md#0x1_DiemConfig_ECONFIGURATION">ECONFIGURATION</a>)); move_to(dr_account, <a href="DiemConfig.md#0x1_DiemConfig_DisableReconfiguration">DisableReconfiguration</a> {} ) } </code></pre> </details><a name="0x1_DiemConfig_enable_reconfiguration"></a>
enable_reconfigurationPrivate function to resume reconfiguration. This function should only be used for offline WriteSet generation purpose and should never be invoked on chain.
<pre><code><b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_enable_reconfiguration">enable_reconfiguration</a>(dr_account: &signer) </code></pre> <details> <summary>Implementation</summary> <pre><code><b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_enable_reconfiguration">enable_reconfiguration</a>(dr_account: &signer) <b>acquires</b> <a href="DiemConfig.md#0x1_DiemConfig_DisableReconfiguration">DisableReconfiguration</a> { <b>assert</b>( <a href="../../../../../../move-stdlib/docs/Signer.md#0x1_Signer_address_of">Signer::address_of</a>(dr_account) == <a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>(), <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_requires_address">Errors::requires_address</a>(<a href="DiemConfig.md#0x1_DiemConfig_EDIEM_CONFIG">EDIEM_CONFIG</a>) ); <a href="Roles.md#0x1_Roles_assert_diem_root">Roles::assert_diem_root</a>(dr_account); <b>assert</b>(!<a href="DiemConfig.md#0x1_DiemConfig_reconfiguration_enabled">reconfiguration_enabled</a>(), <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_invalid_state">Errors::invalid_state</a>(<a href="DiemConfig.md#0x1_DiemConfig_ECONFIGURATION">ECONFIGURATION</a>)); <a href="DiemConfig.md#0x1_DiemConfig_DisableReconfiguration">DisableReconfiguration</a> {} = move_from<<a href="DiemConfig.md#0x1_DiemConfig_DisableReconfiguration">DisableReconfiguration</a>>(<a href="../../../../../../move-stdlib/docs/Signer.md#0x1_Signer_address_of">Signer::address_of</a>(dr_account)); } </code></pre> </details><a name="0x1_DiemConfig_reconfiguration_enabled"></a>
reconfiguration_enabled<a name="0x1_DiemConfig_publish_new_config_and_get_capability"></a>
publish_new_config_and_get_capabilityPublishes a new config. The caller will use the returned ModifyConfigCapability to specify the access control policy for who can modify the config. Does not trigger a reconfiguration.
<pre><code><b>public</b> <b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_publish_new_config_and_get_capability">publish_new_config_and_get_capability</a><Config: <b>copyable</b>>(dr_account: &signer, payload: Config): <a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">DiemConfig::ModifyConfigCapability</a><Config> </code></pre> <details> <summary>Implementation</summary> <pre><code><b>public</b> <b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_publish_new_config_and_get_capability">publish_new_config_and_get_capability</a><Config: <b>copy</b> + drop + store>( dr_account: &signer, payload: Config, ): <a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">ModifyConfigCapability</a><Config> { <a href="Roles.md#0x1_Roles_assert_diem_root">Roles::assert_diem_root</a>(dr_account); <b>assert</b>( !<b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><Config>>(<a href="../../../../../../move-stdlib/docs/Signer.md#0x1_Signer_address_of">Signer::address_of</a>(dr_account)), <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_already_published">Errors::already_published</a>(<a href="DiemConfig.md#0x1_DiemConfig_EDIEM_CONFIG">EDIEM_CONFIG</a>) ); move_to(dr_account, <a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a> { payload }); <a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">ModifyConfigCapability</a><Config> {} } </code></pre> </details> <details> <summary>Specification</summary>TODO: turned off verification until we solve the generic type/specific invariant issue
<pre><code><b>pragma</b> opaque, verify = <b>false</b>; <b>modifies</b> <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><Config>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <b>include</b> <a href="Roles.md#0x1_Roles_AbortsIfNotDiemRoot">Roles::AbortsIfNotDiemRoot</a>{account: dr_account}; <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_AbortsIfPublished">AbortsIfPublished</a><Config>; <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_SetEnsures">SetEnsures</a><Config>; </code></pre><a name="0x1_DiemConfig_AbortsIfPublished"></a>
<pre><code><b>schema</b> <a href="DiemConfig.md#0x1_DiemConfig_AbortsIfPublished">AbortsIfPublished</a><Config> { <b>aborts_if</b> <b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><Config>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()) <b>with</b> <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_ALREADY_PUBLISHED">Errors::ALREADY_PUBLISHED</a>; } </code></pre> </details><a name="0x1_DiemConfig_publish_new_config"></a>
publish_new_configPublish a new config item. Only Diem root can modify such config. Publishes the capability to modify this config under the Diem root account. Does not trigger a reconfiguration.
<pre><code><b>public</b> <b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_publish_new_config">publish_new_config</a><Config: <b>copyable</b>>(dr_account: &signer, payload: Config) </code></pre> <details> <summary>Implementation</summary> <pre><code><b>public</b> <b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_publish_new_config">publish_new_config</a><Config: <b>copy</b> + drop + store>( dr_account: &signer, payload: Config ) { <b>let</b> capability = <a href="DiemConfig.md#0x1_DiemConfig_publish_new_config_and_get_capability">publish_new_config_and_get_capability</a><Config>(dr_account, payload); <b>assert</b>( !<b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">ModifyConfigCapability</a><Config>>(<a href="../../../../../../move-stdlib/docs/Signer.md#0x1_Signer_address_of">Signer::address_of</a>(dr_account)), <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_already_published">Errors::already_published</a>(<a href="DiemConfig.md#0x1_DiemConfig_EMODIFY_CAPABILITY">EMODIFY_CAPABILITY</a>) ); move_to(dr_account, capability); } </code></pre> </details> <details> <summary>Specification</summary> <pre><code><b>pragma</b> opaque; <b>modifies</b> <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><Config>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <b>modifies</b> <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">ModifyConfigCapability</a><Config>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_PublishNewConfigAbortsIf">PublishNewConfigAbortsIf</a><Config>; <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_PublishNewConfigEnsures">PublishNewConfigEnsures</a><Config>; </code></pre><a name="0x1_DiemConfig_PublishNewConfigAbortsIf"></a>
<pre><code><b>schema</b> <a href="DiemConfig.md#0x1_DiemConfig_PublishNewConfigAbortsIf">PublishNewConfigAbortsIf</a><Config> { dr_account: signer; <b>include</b> <a href="Roles.md#0x1_Roles_AbortsIfNotDiemRoot">Roles::AbortsIfNotDiemRoot</a>{account: dr_account}; <b>aborts_if</b> <a href="DiemConfig.md#0x1_DiemConfig_spec_is_published">spec_is_published</a><Config>(); <b>aborts_if</b> <b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">ModifyConfigCapability</a><Config>>(<a href="../../../../../../move-stdlib/docs/Signer.md#0x1_Signer_spec_address_of">Signer::spec_address_of</a>(dr_account)); } </code></pre><a name="0x1_DiemConfig_PublishNewConfigEnsures"></a>
<pre><code><b>schema</b> <a href="DiemConfig.md#0x1_DiemConfig_PublishNewConfigEnsures">PublishNewConfigEnsures</a><Config> { dr_account: signer; payload: Config; <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_SetEnsures">SetEnsures</a><Config>; <b>ensures</b> <b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">ModifyConfigCapability</a><Config>>(<a href="../../../../../../move-stdlib/docs/Signer.md#0x1_Signer_spec_address_of">Signer::spec_address_of</a>(dr_account)); } </code></pre> </details><a name="0x1_DiemConfig_reconfigure"></a>
reconfigureSignal validators to start using new configuration. Must be called by Diem root.
<pre><code><b>public</b> <b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_reconfigure">reconfigure</a>(dr_account: &signer) </code></pre> <details> <summary>Implementation</summary> <pre><code><b>public</b> <b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_reconfigure">reconfigure</a>( dr_account: &signer, ) <b>acquires</b> <a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a> { <a href="Roles.md#0x1_Roles_assert_diem_root">Roles::assert_diem_root</a>(dr_account); <a href="DiemConfig.md#0x1_DiemConfig_reconfigure_">reconfigure_</a>(); } </code></pre> </details> <details> <summary>Specification</summary> <pre><code><b>pragma</b> opaque; <b>modifies</b> <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <b>include</b> <a href="Roles.md#0x1_Roles_AbortsIfNotDiemRoot">Roles::AbortsIfNotDiemRoot</a>{account: dr_account}; <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_ReconfigureAbortsIf">ReconfigureAbortsIf</a>; </code></pre> </details><a name="0x1_DiemConfig_reconfigure_"></a>
reconfigure_Private function to do reconfiguration. Updates reconfiguration status resource <code><a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a></code> and emits a <code><a href="DiemConfig.md#0x1_DiemConfig_NewEpochEvent">NewEpochEvent</a></code>
<pre><code><b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_reconfigure_">reconfigure_</a>() </code></pre> <details> <summary>Implementation</summary> <pre><code><b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_reconfigure_">reconfigure_</a>() <b>acquires</b> <a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a> { // Do not do anything <b>if</b> genesis has not finished. <b>if</b> (<a href="DiemTimestamp.md#0x1_DiemTimestamp_is_genesis">DiemTimestamp::is_genesis</a>() || <a href="DiemTimestamp.md#0x1_DiemTimestamp_now_microseconds">DiemTimestamp::now_microseconds</a>() == 0 || !<a href="DiemConfig.md#0x1_DiemConfig_reconfiguration_enabled">reconfiguration_enabled</a>()) { <b>return</b> () }; <b>let</b> config_ref = borrow_global_mut<<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <b>let</b> current_time = <a href="DiemTimestamp.md#0x1_DiemTimestamp_now_microseconds">DiemTimestamp::now_microseconds</a>(); // Do not do anything <b>if</b> a reconfiguration event is already emitted within this transaction. // // This is OK because: // - The time changes in every non-empty block // - A block automatically ends after a transaction that emits a reconfiguration event, which is guaranteed by // DiemVM <b>spec</b> that all transactions comming after a reconfiguration transaction will be returned <b>as</b> Retry // status. // - Each transaction must emit at most one reconfiguration event // // Thus, this check <b>ensures</b> that a transaction that does multiple "reconfiguration required" actions emits only // one reconfiguration event. // <b>if</b> (current_time == config_ref.last_reconfiguration_time) { <b>return</b> }; <b>assert</b>(current_time > config_ref.last_reconfiguration_time, <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_invalid_state">Errors::invalid_state</a>(<a href="DiemConfig.md#0x1_DiemConfig_EINVALID_BLOCK_TIME">EINVALID_BLOCK_TIME</a>)); config_ref.last_reconfiguration_time = current_time; config_ref.epoch = config_ref.epoch + 1; <a href="../../../../../../move-stdlib/docs/Event.md#0x1_Event_emit_event">Event::emit_event</a><<a href="DiemConfig.md#0x1_DiemConfig_NewEpochEvent">NewEpochEvent</a>>( &<b>mut</b> config_ref.events, <a href="DiemConfig.md#0x1_DiemConfig_NewEpochEvent">NewEpochEvent</a> { epoch: config_ref.epoch, }, ); } </code></pre> </details> <details> <summary>Specification</summary> <pre><code><b>pragma</b> opaque; <b>modifies</b> <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <b>ensures</b> <b>old</b>(<a href="DiemConfig.md#0x1_DiemConfig_spec_has_config">spec_has_config</a>()) == <a href="DiemConfig.md#0x1_DiemConfig_spec_has_config">spec_has_config</a>(); <a name="0x1_DiemConfig_config$25"></a> <b>let</b> config = <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <a name="0x1_DiemConfig_now$26"></a> <b>let</b> now = <a href="DiemTimestamp.md#0x1_DiemTimestamp_spec_now_microseconds">DiemTimestamp::spec_now_microseconds</a>(); <a name="0x1_DiemConfig_epoch$27"></a> <b>let</b> epoch = config.epoch; <b>include</b> !<a href="DiemConfig.md#0x1_DiemConfig_spec_reconfigure_omitted">spec_reconfigure_omitted</a>() || (config.last_reconfiguration_time == now) ==> <a href="DiemConfig.md#0x1_DiemConfig_InternalReconfigureAbortsIf">InternalReconfigureAbortsIf</a> && <a href="DiemConfig.md#0x1_DiemConfig_ReconfigureAbortsIf">ReconfigureAbortsIf</a>; <b>ensures</b> <a href="DiemConfig.md#0x1_DiemConfig_spec_reconfigure_omitted">spec_reconfigure_omitted</a>() || (<b>old</b>(config).last_reconfiguration_time == now) ==> config == <b>old</b>(config); <b>ensures</b> !(<a href="DiemConfig.md#0x1_DiemConfig_spec_reconfigure_omitted">spec_reconfigure_omitted</a>() || (config.last_reconfiguration_time == now)) ==> config == update_field( update_field(<b>old</b>(config), epoch, <b>old</b>(config.epoch) + 1), last_reconfiguration_time, now); <b>include</b> <a href="DiemConfig.md#0x1_DiemConfig_ReconfigureEmits">ReconfigureEmits</a>; </code></pre>The following schema describes aborts conditions which we do not want to be propagated to the verification of callers, and which are therefore marked as <code>concrete</code> to be only verified against the implementation. These conditions are unlikely to happen in reality, and excluding them avoids formal noise.
<a name="0x1_DiemConfig_InternalReconfigureAbortsIf"></a>
<a name="0x1_DiemConfig_config$19"></a>
<pre><code><b>schema</b> <a href="DiemConfig.md#0x1_DiemConfig_InternalReconfigureAbortsIf">InternalReconfigureAbortsIf</a> { <b>let</b> config = <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <a name="0x1_DiemConfig_current_time$20"></a> <b>let</b> current_time = <a href="DiemTimestamp.md#0x1_DiemTimestamp_spec_now_microseconds">DiemTimestamp::spec_now_microseconds</a>(); <b>aborts_if</b> [concrete] current_time < config.last_reconfiguration_time <b>with</b> <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_INVALID_STATE">Errors::INVALID_STATE</a>; <b>aborts_if</b> [concrete] config.epoch == <a href="DiemConfig.md#0x1_DiemConfig_MAX_U64">MAX_U64</a> && current_time != config.last_reconfiguration_time <b>with</b> EXECUTION_FAILURE; } </code></pre>This schema is to be used by callers of <code>reconfigure</code>
<a name="0x1_DiemConfig_ReconfigureAbortsIf"></a>
<a name="0x1_DiemConfig_config$17"></a>
<pre><code><b>schema</b> <a href="DiemConfig.md#0x1_DiemConfig_ReconfigureAbortsIf">ReconfigureAbortsIf</a> { <b>let</b> config = <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <a name="0x1_DiemConfig_current_time$18"></a> <b>let</b> current_time = <a href="DiemTimestamp.md#0x1_DiemTimestamp_spec_now_microseconds">DiemTimestamp::spec_now_microseconds</a>(); <b>aborts_if</b> <a href="DiemTimestamp.md#0x1_DiemTimestamp_is_operating">DiemTimestamp::is_operating</a>() && <a href="DiemConfig.md#0x1_DiemConfig_reconfiguration_enabled">reconfiguration_enabled</a>() && <a href="DiemTimestamp.md#0x1_DiemTimestamp_spec_now_microseconds">DiemTimestamp::spec_now_microseconds</a>() > 0 && config.epoch < <a href="DiemConfig.md#0x1_DiemConfig_MAX_U64">MAX_U64</a> && current_time < config.last_reconfiguration_time <b>with</b> <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_INVALID_STATE">Errors::INVALID_STATE</a>; } </code></pre><a name="0x1_DiemConfig_ReconfigureEmits"></a>
<a name="0x1_DiemConfig_config$21"></a>
<pre><code><b>schema</b> <a href="DiemConfig.md#0x1_DiemConfig_ReconfigureEmits">ReconfigureEmits</a> { <b>let</b> config = <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <a name="0x1_DiemConfig_now$22"></a> <b>let</b> now = <a href="DiemTimestamp.md#0x1_DiemTimestamp_spec_now_microseconds">DiemTimestamp::spec_now_microseconds</a>(); <a name="0x1_DiemConfig_msg$23"></a> <b>let</b> msg = <a href="DiemConfig.md#0x1_DiemConfig_NewEpochEvent">NewEpochEvent</a> { epoch: config.epoch, }; <a name="0x1_DiemConfig_handle$24"></a> <b>let</b> handle = config.events; emits msg <b>to</b> handle <b>if</b> (!<a href="DiemConfig.md#0x1_DiemConfig_spec_reconfigure_omitted">spec_reconfigure_omitted</a>() && now != <b>old</b>(config).last_reconfiguration_time); } </code></pre> </details><a name="0x1_DiemConfig_emit_genesis_reconfiguration_event"></a>
emit_genesis_reconfiguration_eventEmit a <code><a href="DiemConfig.md#0x1_DiemConfig_NewEpochEvent">NewEpochEvent</a></code> event. This function will be invoked by genesis directly to generate the very first reconfiguration event.
<pre><code><b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_emit_genesis_reconfiguration_event">emit_genesis_reconfiguration_event</a>() </code></pre> <details> <summary>Implementation</summary> <pre><code><b>fun</b> <a href="DiemConfig.md#0x1_DiemConfig_emit_genesis_reconfiguration_event">emit_genesis_reconfiguration_event</a>() <b>acquires</b> <a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a> { <b>assert</b>(<b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()), <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_not_published">Errors::not_published</a>(<a href="DiemConfig.md#0x1_DiemConfig_ECONFIGURATION">ECONFIGURATION</a>)); <b>let</b> config_ref = borrow_global_mut<<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <b>assert</b>(config_ref.epoch == 0 && config_ref.last_reconfiguration_time == 0, <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_invalid_state">Errors::invalid_state</a>(<a href="DiemConfig.md#0x1_DiemConfig_ECONFIGURATION">ECONFIGURATION</a>)); config_ref.epoch = 1; <a href="../../../../../../move-stdlib/docs/Event.md#0x1_Event_emit_event">Event::emit_event</a><<a href="DiemConfig.md#0x1_DiemConfig_NewEpochEvent">NewEpochEvent</a>>( &<b>mut</b> config_ref.events, <a href="DiemConfig.md#0x1_DiemConfig_NewEpochEvent">NewEpochEvent</a> { epoch: config_ref.epoch, }, ); } </code></pre> </details> <details> <summary>Specification</summary><a name="0x1_DiemConfig_config$28"></a>
<pre><code><b>let</b> config = <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); <a name="0x1_DiemConfig_handle$29"></a> <b>let</b> handle = config.events; <a name="0x1_DiemConfig_msg$30"></a> <b>let</b> msg = <a href="DiemConfig.md#0x1_DiemConfig_NewEpochEvent">NewEpochEvent</a> { epoch: config.epoch, }; emits msg <b>to</b> handle; </code></pre> </details><a name="@Module_Specification_1"></a>
<a name="0x1_DiemConfig_spec_reconfigure_omitted"></a>
<pre><code><b>define</b> <a href="DiemConfig.md#0x1_DiemConfig_spec_reconfigure_omitted">spec_reconfigure_omitted</a>(): bool { <a href="DiemTimestamp.md#0x1_DiemTimestamp_is_genesis">DiemTimestamp::is_genesis</a>() || <a href="DiemTimestamp.md#0x1_DiemTimestamp_spec_now_microseconds">DiemTimestamp::spec_now_microseconds</a>() == 0 || !<a href="DiemConfig.md#0x1_DiemConfig_reconfiguration_enabled">reconfiguration_enabled</a>() } </code></pre><a name="@Initialization_2"></a>
After genesis, the <code><a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a></code> is published.
<pre><code><b>invariant</b> [<b>global</b>] <a href="DiemTimestamp.md#0x1_DiemTimestamp_is_operating">DiemTimestamp::is_operating</a>() ==> <a href="DiemConfig.md#0x1_DiemConfig_spec_has_config">spec_has_config</a>(); </code></pre><a name="@Invariants_3"></a>
Configurations are only stored at the diem root address.
<pre><code><b>invariant</b> [<b>global</b>] <b>forall</b> config_address: address, config_type: type <b>where</b> <b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><config_type>>(config_address): config_address == <a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>(); </code></pre>After genesis, no new configurations are added.
<pre><code><b>invariant</b> <b>update</b> [<b>global</b>] <a href="DiemTimestamp.md#0x1_DiemTimestamp_is_operating">DiemTimestamp::is_operating</a>() ==> (<b>forall</b> config_type: type <b>where</b> <a href="DiemConfig.md#0x1_DiemConfig_spec_is_published">spec_is_published</a><config_type>(): <b>old</b>(<a href="DiemConfig.md#0x1_DiemConfig_spec_is_published">spec_is_published</a><config_type>())); </code></pre>Published configurations are persistent.
<pre><code><b>invariant</b> <b>update</b> [<b>global</b>] (<b>forall</b> config_type: type <b>where</b> <b>old</b>(<a href="DiemConfig.md#0x1_DiemConfig_spec_is_published">spec_is_published</a><config_type>()): <a href="DiemConfig.md#0x1_DiemConfig_spec_is_published">spec_is_published</a><config_type>()); </code></pre>If <code><a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">ModifyConfigCapability</a><Config></code> is published, it is persistent.
<pre><code><b>invariant</b> <b>update</b> [<b>global</b>] <b>forall</b> config_type: type <b>where</b> <b>old</b>(<b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">ModifyConfigCapability</a><config_type>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>())): <b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig_ModifyConfigCapability">ModifyConfigCapability</a><config_type>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()); </code></pre><a name="@Helper_Functions_4"></a>
<a name="0x1_DiemConfig_spec_has_config"></a>
<pre><code><b>define</b> <a href="DiemConfig.md#0x1_DiemConfig_spec_has_config">spec_has_config</a>(): bool { <b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig_Configuration">Configuration</a>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()) } <a name="0x1_DiemConfig_spec_is_published"></a> <b>define</b> <a href="DiemConfig.md#0x1_DiemConfig_spec_is_published">spec_is_published</a><Config>(): bool { <b>exists</b><<a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><Config>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()) } <a name="0x1_DiemConfig_spec_get_config"></a> <b>define</b> <a href="DiemConfig.md#0x1_DiemConfig_spec_get_config">spec_get_config</a><Config>(): Config { <b>global</b><<a href="DiemConfig.md#0x1_DiemConfig">DiemConfig</a><Config>>(<a href="CoreAddresses.md#0x1_CoreAddresses_DIEM_ROOT_ADDRESS">CoreAddresses::DIEM_ROOT_ADDRESS</a>()).payload } </code></pre>