Skip to main content

Module 0x2::config

use 0x1::option; use 0x2::dynamic_field; use 0x2::object; use 0x2::transfer; use 0x2::tx_context;

Resource Config

struct Config<WriteCap> has key

Fields

Struct Setting

struct Setting<Value: copy, drop, store> has drop, store

Fields

Struct SettingData

struct SettingData<Value: copy, drop, store> has drop, store

Fields
newer_value_epoch: u64
newer_value: option::Option<Value>
older_value_opt: option::Option<Value>

Constants

const EBCSSerializationFailure: u64 = 2;

const EAlreadySetForEpoch: u64 = 0;

const ENotSetForEpoch: u64 = 1;

Function new

public(friend) fun new<WriteCap>(_cap: &mut WriteCap, ctx: &mut tx_context::TxContext): config::Config<WriteCap>

Implementation

public(package) fun new<WriteCap>(_cap: &mut WriteCap, ctx: &mut TxContext): Config<WriteCap> { Config<WriteCap> { id: object::new(ctx) } }

Function share

public(friend) fun share<WriteCap>(config: config::Config<WriteCap>)

Implementation

public(package) fun share<WriteCap>(config: Config<WriteCap>) { transfer::share_object(config) }

Function transfer

public(friend) fun transfer<WriteCap>(config: config::Config<WriteCap>, owner: address)

Implementation

public(package) fun transfer<WriteCap>(config: Config<WriteCap>, owner: address) { transfer::transfer(config, owner) }

Function add_for_next_epoch

public(friend) fun add_for_next_epoch<WriteCap, Name: copy, drop, store, Value: copy, drop, store>(config: &mut config::Config<WriteCap>, _cap: &mut WriteCap, name: Name, value: Value, ctx: &mut tx_context::TxContext): option::Option<Value>

Implementation

public(package) fun add_for_next_epoch< WriteCap, Name: copy + drop + store, Value: copy + drop + store, >( config: &mut Config<WriteCap>, cap: &mut WriteCap, name: Name, value: Value, ctx: &mut TxContext, ): Option<Value> { let epoch = ctx.epoch(); if (!field::exists(&config.id, name)) { let sobj = Setting { data: option::some(SettingData { newer_value_epoch: epoch, newer_value: option::some(value), older_value_opt: option::none(), }), }; field::add(&mut config.id, name, sobj); option::none() } else { let sobj: &mut Setting<Value> = field::borrow_mut(&mut config.id, name); let SettingData { newer_value_epoch, newer_value, older_value_opt, } = sobj.data.extract(); let (older_value_opt, removed_value) = if (epoch > newer_value_epoch) { // if the newer_value is for a previous epoch, move it to older_value_opt (move newer_value, move older_value_opt) } else { // the current epoch cannot be less than the newer_value_epoch assert!(epoch == newer_value_epoch); // if the newer_value is for the current epoch, then the option must be none assert!(newer_value.is_none(), EAlreadySetForEpoch); (move older_value_opt, option::none()) }; sobj.data.fill(SettingData { newer_value_epoch: epoch, newer_value: option::some(value), older_value_opt, }); removed_value } }

Function remove_for_next_epoch

public(friend) fun remove_for_next_epoch<WriteCap, Name: copy, drop, store, Value: copy, drop, store>(config: &mut config::Config<WriteCap>, _cap: &mut WriteCap, name: Name, ctx: &mut tx_context::TxContext): option::Option<Value>

Implementation

public(package) fun remove_for_next_epoch< WriteCap, Name: copy + drop + store, Value: copy + drop + store, >( config: &mut Config<WriteCap>, cap: &mut WriteCap, name: Name, ctx: &mut TxContext, ): Option<Value> { let epoch = ctx.epoch(); if (!field::exists(&config.id, name)) return option::none(); let sobj: &mut Setting<Value> = field::borrow_mut(&mut config.id, name); let SettingData { newer_value_epoch, newer_value, older_value_opt, } = sobj.data.extract(); let (older_value_opt, removed_value) = if (epoch > newer_value_epoch) { // if the newer_value is for a previous epoch, move it to older_value_opt (move newer_value, option::none()) } else { // the current epoch cannot be less than the newer_value_epoch assert!(epoch == newer_value_epoch); (move older_value_opt, move newer_value) }; let older_value_opt_is_none = older_value_opt.is_none(); sobj.data.fill(SettingData { newer_value_epoch: epoch, newer_value: option::none(), older_value_opt, }); if (older_value_opt_is_none) { field::remove<_, Setting<Value>>(&mut config.id, name); }; removed_value }

Function exists_with_type

public(friend) fun exists_with_type<WriteCap, Name: copy, drop, store, Value: copy, drop, store>(config: &config::Config<WriteCap>, name: Name): bool

Implementation

public(package) fun exists_with_type< WriteCap, Name: copy + drop + store, Value: copy + drop + store, >( config: &Config<WriteCap>, name: Name, ): bool { field::exists_with_type<_, Setting<Value>>(&config.id, name) }

Function exists_with_type_for_next_epoch

public(friend) fun exists_with_type_for_next_epoch<WriteCap, Name: copy, drop, store, Value: copy, drop, store>(config: &config::Config<WriteCap>, name: Name, ctx: &tx_context::TxContext): bool

Implementation

public(package) fun exists_with_type_for_next_epoch< WriteCap, Name: copy + drop + store, Value: copy + drop + store, >( config: & Config<WriteCap>, name: Name, ctx: &TxContext, ): bool { field::exists_with_type<_, Setting<Value>>(&config.id, name) && { let epoch = ctx.epoch(); let sobj: &Setting<Value> = field::borrow(&config.id, name); epoch == sobj.data.borrow().newer_value_epoch && sobj.data.borrow().newer_value.is_some() } }

Function borrow_for_next_epoch_mut

public(friend) fun borrow_for_next_epoch_mut<WriteCap, Name: copy, drop, store, Value: copy, drop, store>(config: &mut config::Config<WriteCap>, _cap: &mut WriteCap, name: Name, ctx: &mut tx_context::TxContext): &mut Value

Implementation

public(package) fun borrow_for_next_epoch_mut< WriteCap, Name: copy + drop + store, Value: copy + drop + store, >( config: &mut Config<WriteCap>, _cap: &mut WriteCap, name: Name, ctx: &mut TxContext, ): &mut Value { let epoch = ctx.epoch(); let sobj: &mut Setting<Value> = field::borrow_mut(&mut config.id, name); let data = sobj.data.borrow_mut(); assert!(data.newer_value_epoch == epoch, ENotSetForEpoch); assert!(data.newer_value.is_some(), ENotSetForEpoch); data.newer_value.borrow_mut() }

Function read_setting_for_next_epoch

public(friend) fun read_setting_for_next_epoch<WriteCap, Name: copy, drop, store, Value: copy, drop, store>(config: &config::Config<WriteCap>, name: Name): option::Option<Value>

Implementation

public(package) fun read_setting_for_next_epoch< WriteCap, Name: copy + drop + store, Value: copy + drop + store, >( config: &Config<WriteCap>, name: Name, ): Option<Value> { if (!field::exists_with_type<_, Setting<Value>>(&config.id, name)) return option::none(); let sobj: &Setting<Value> = field::borrow(&config.id, name); let data = sobj.data.borrow(); data.newer_value }

Function read_setting

public(friend) fun read_setting<Name: copy, drop, store, Value: copy, drop, store>(config: object::ID, name: Name, ctx: &tx_context::TxContext): option::Option<Value>

Implementation

public(package) fun read_setting<Name: copy + drop + store, Value: copy + drop + store>( config: ID, name: Name, ctx: &TxContext, ): Option<Value> { use iota::dynamic_field::Field; let config_id = config.to_address(); let setting_df = field::hash_type_and_key(config_id, name); read_setting_impl<Field<Name, Setting<Value>>, Setting<Value>, SettingData<Value>, Value>( config_id, setting_df, ctx.epoch(), ) }

Function read_setting_impl

fun read_setting_impl<FieldSettingValue: key, SettingValue: store, SettingDataValue: store, Value: copy, drop, store>(config: address, name: address, current_epoch: u64): option::Option<Value>

Implementation

native fun read_setting_impl< FieldSettingValue: key, SettingValue: store, SettingDataValue: store, Value: copy + drop + store, >( config: address, name: address, current_epoch: u64, ): Option<Value>;