diff --git a/executor/tests/on_chain_config_test.rs b/executor/tests/on_chain_config_test.rs index ad757b3b7b..6494c63f35 100644 --- a/executor/tests/on_chain_config_test.rs +++ b/executor/tests/on_chain_config_test.rs @@ -188,79 +188,79 @@ fn test_modify_on_chain_txn_publish_option() -> Result<()> { Ok(()) } -// #[stest::test] -// fn test_modify_on_chain_vm_config_option() -> Result<()> { -// let alice = Account::new(); -// let bob = Account::new(); -// let (chain_state, net) = prepare_genesis(); -// let pre_mint_amount = net.genesis_config().pre_mine_amount; -// let action_type_tag = vm_config_type_tag(); -// -// let one_day: u64 = 60 * 60 * 24 * 1000; -// -// // blockmeta txn is needed to create reward info. -// // block 1 -// { -// let block_number = current_block_number(&chain_state) + 1; -// let block_timestamp = net.time_service().now_millis() + one_day * block_number - 1; -// let miner = Account::new(); -// blockmeta_execute( -// &chain_state, -// BlockMetadata::new( -// HashValue::zero(), -// block_timestamp, -// *miner.address(), -// Some(miner.auth_key()), -// 0, -// block_number, -// net.chain_id(), -// 0, -// ), -// )?; -// } -// //create user for txn verifier -// let script_function = encode_create_account_script_function( -// net.stdlib_version(), -// stc_type_tag(), -// bob.address(), -// bob.auth_key(), -// pre_mint_amount / 8, -// ); -// association_execute_should_success( -// &net, -// &chain_state, -// TransactionPayload::ScriptFunction(script_function), -// )?; -// -// //get gas_used -// let output = account_execute_with_output(&bob, &chain_state, empty_txn_payload()); -// let old_gas_used = output.gas_used(); -// let account_state_reader = AccountStateReader::new(&chain_state); -// let mut vm_config = account_state_reader -// .get_on_chain_config::()? -// .unwrap(); -// //set vm config parameter -// vm_config -// .gas_schedule -// .gas_constants -// .global_memory_per_byte_cost = InternalGasUnits::new(8); -// vm_config -// .gas_schedule -// .gas_constants -// .global_memory_per_byte_write_cost = InternalGasUnits::new(12); -// let vote_script = vote_vm_config_script(&net, vm_config); -// -// dao_vote_test( -// &alice, -// &chain_state, -// &net, -// vote_script, -// on_chain_config_type_tag(action_type_tag.clone()), -// execute_script_on_chain_config(&net, action_type_tag, 0u64), -// 0, -// )?; -// // get gas used of modified gas schedule -// let output = account_execute_with_output(&bob, &chain_state, empty_txn_payload()); -// assert!(output.gas_used() > old_gas_used); -// Ok(()) -// } +#[stest::test] +fn test_modify_on_chain_vm_config_option() -> Result<()> { + let alice = Account::new(); + let bob = Account::new(); + let (chain_state, net) = prepare_genesis(); + let pre_mint_amount = net.genesis_config().pre_mine_amount; + let action_type_tag = vm_config_type_tag(); + + let one_day: u64 = 60 * 60 * 24 * 1000; + + // blockmeta txn is needed to create reward info. + // block 1 + { + let block_number = current_block_number(&chain_state) + 1; + let block_timestamp = net.time_service().now_millis() + one_day * block_number - 1; + let miner = Account::new(); + blockmeta_execute( + &chain_state, + BlockMetadata::new( + HashValue::zero(), + block_timestamp, + *miner.address(), + Some(miner.auth_key()), + 0, + block_number, + net.chain_id(), + 0, + ), + )?; + } + //create user for txn verifier + let script_function = encode_create_account_script_function( + net.stdlib_version(), + stc_type_tag(), + bob.address(), + bob.auth_key(), + pre_mint_amount / 8, + ); + association_execute_should_success( + &net, + &chain_state, + TransactionPayload::ScriptFunction(script_function), + )?; + + //get gas_used + let output = account_execute_with_output(&bob, &chain_state, empty_txn_payload()); + let old_gas_used = output.gas_used(); + let account_state_reader = AccountStateReader::new(&chain_state); + let mut vm_config = account_state_reader + .get_on_chain_config::()? + .unwrap(); + //set vm config parameter + vm_config + .gas_schedule + .gas_constants + .global_memory_per_byte_cost = InternalGasUnits::new(8); + vm_config + .gas_schedule + .gas_constants + .global_memory_per_byte_write_cost = InternalGasUnits::new(12); + let vote_script = vote_vm_config_script(&net, vm_config); + + dao_vote_test( + &alice, + &chain_state, + &net, + vote_script, + on_chain_config_type_tag(action_type_tag.clone()), + execute_script_on_chain_config(&net, action_type_tag, 0u64), + 0, + )?; + // get gas used of modified gas schedule + let output = account_execute_with_output(&bob, &chain_state, empty_txn_payload()); + assert!(output.gas_used() > old_gas_used); + Ok(()) +} diff --git a/genesis/generated/halley/genesis b/genesis/generated/halley/genesis index 936dd78464..9925ccf7ca 100644 Binary files a/genesis/generated/halley/genesis and b/genesis/generated/halley/genesis differ diff --git a/genesis/src/lib.rs b/genesis/src/lib.rs index 911f1018f5..3c94ccb336 100644 --- a/genesis/src/lib.rs +++ b/genesis/src/lib.rs @@ -345,7 +345,7 @@ mod tests { use starcoin_types::account_config::{genesis_address, ModuleUpgradeStrategy}; use starcoin_vm_types::account_config::association_address; use starcoin_vm_types::genesis_config::ChainId; - use starcoin_vm_types::on_chain_config::{ConsensusConfig, VMConfig, Version}; + use starcoin_vm_types::on_chain_config::{ConsensusConfig, Version}; use starcoin_vm_types::on_chain_config::{DaoConfig, TransactionPublishOption}; use starcoin_vm_types::on_chain_resource::Epoch; diff --git a/vm/stdlib/compiled/latest/stdlib/18_ChainId.mv b/vm/stdlib/compiled/latest/stdlib/18_ChainId.mv new file mode 100644 index 0000000000..49e87572ee Binary files /dev/null and b/vm/stdlib/compiled/latest/stdlib/18_ChainId.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/18_VMConfig.mv b/vm/stdlib/compiled/latest/stdlib/19_VMConfig.mv similarity index 81% rename from vm/stdlib/compiled/latest/stdlib/18_VMConfig.mv rename to vm/stdlib/compiled/latest/stdlib/19_VMConfig.mv index 4233fcc715..2fb933c0ce 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/18_VMConfig.mv and b/vm/stdlib/compiled/latest/stdlib/19_VMConfig.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/19_Version.mv b/vm/stdlib/compiled/latest/stdlib/20_Version.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/19_Version.mv rename to vm/stdlib/compiled/latest/stdlib/20_Version.mv diff --git a/vm/stdlib/compiled/latest/stdlib/20_PackageTxnManager.mv b/vm/stdlib/compiled/latest/stdlib/21_PackageTxnManager.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/20_PackageTxnManager.mv rename to vm/stdlib/compiled/latest/stdlib/21_PackageTxnManager.mv diff --git a/vm/stdlib/compiled/latest/stdlib/21_Treasury.mv b/vm/stdlib/compiled/latest/stdlib/22_Treasury.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/21_Treasury.mv rename to vm/stdlib/compiled/latest/stdlib/22_Treasury.mv diff --git a/vm/stdlib/compiled/latest/stdlib/22_Dao.mv b/vm/stdlib/compiled/latest/stdlib/23_Dao.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/22_Dao.mv rename to vm/stdlib/compiled/latest/stdlib/23_Dao.mv diff --git a/vm/stdlib/compiled/latest/stdlib/23_UpgradeModuleDaoProposal.mv b/vm/stdlib/compiled/latest/stdlib/24_UpgradeModuleDaoProposal.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/23_UpgradeModuleDaoProposal.mv rename to vm/stdlib/compiled/latest/stdlib/24_UpgradeModuleDaoProposal.mv diff --git a/vm/stdlib/compiled/latest/stdlib/24_TransactionTimeoutConfig.mv b/vm/stdlib/compiled/latest/stdlib/25_TransactionTimeoutConfig.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/24_TransactionTimeoutConfig.mv rename to vm/stdlib/compiled/latest/stdlib/25_TransactionTimeoutConfig.mv diff --git a/vm/stdlib/compiled/latest/stdlib/25_TransactionPublishOption.mv b/vm/stdlib/compiled/latest/stdlib/26_TransactionPublishOption.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/25_TransactionPublishOption.mv rename to vm/stdlib/compiled/latest/stdlib/26_TransactionPublishOption.mv diff --git a/vm/stdlib/compiled/latest/stdlib/26_RewardConfig.mv b/vm/stdlib/compiled/latest/stdlib/27_RewardConfig.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/26_RewardConfig.mv rename to vm/stdlib/compiled/latest/stdlib/27_RewardConfig.mv diff --git a/vm/stdlib/compiled/latest/stdlib/27_OnChainConfigDao.mv b/vm/stdlib/compiled/latest/stdlib/28_OnChainConfigDao.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/27_OnChainConfigDao.mv rename to vm/stdlib/compiled/latest/stdlib/28_OnChainConfigDao.mv diff --git a/vm/stdlib/compiled/latest/stdlib/28_ModifyDaoConfigProposal.mv b/vm/stdlib/compiled/latest/stdlib/29_ModifyDaoConfigProposal.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/28_ModifyDaoConfigProposal.mv rename to vm/stdlib/compiled/latest/stdlib/29_ModifyDaoConfigProposal.mv diff --git a/vm/stdlib/compiled/latest/stdlib/29_ConsensusConfig.mv b/vm/stdlib/compiled/latest/stdlib/30_ConsensusConfig.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/29_ConsensusConfig.mv rename to vm/stdlib/compiled/latest/stdlib/30_ConsensusConfig.mv diff --git a/vm/stdlib/compiled/latest/stdlib/30_STC.mv b/vm/stdlib/compiled/latest/stdlib/31_STC.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/30_STC.mv rename to vm/stdlib/compiled/latest/stdlib/31_STC.mv diff --git a/vm/stdlib/compiled/latest/stdlib/31_TransactionFee.mv b/vm/stdlib/compiled/latest/stdlib/32_TransactionFee.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/31_TransactionFee.mv rename to vm/stdlib/compiled/latest/stdlib/32_TransactionFee.mv diff --git a/vm/stdlib/compiled/latest/stdlib/32_Hash.mv b/vm/stdlib/compiled/latest/stdlib/33_Hash.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/32_Hash.mv rename to vm/stdlib/compiled/latest/stdlib/33_Hash.mv diff --git a/vm/stdlib/compiled/latest/stdlib/33_Authenticator.mv b/vm/stdlib/compiled/latest/stdlib/34_Authenticator.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/33_Authenticator.mv rename to vm/stdlib/compiled/latest/stdlib/34_Authenticator.mv diff --git a/vm/stdlib/compiled/latest/stdlib/34_Account.mv b/vm/stdlib/compiled/latest/stdlib/35_Account.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/34_Account.mv rename to vm/stdlib/compiled/latest/stdlib/35_Account.mv diff --git a/vm/stdlib/compiled/latest/stdlib/35_AccountScripts.mv b/vm/stdlib/compiled/latest/stdlib/36_AccountScripts.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/35_AccountScripts.mv rename to vm/stdlib/compiled/latest/stdlib/36_AccountScripts.mv diff --git a/vm/stdlib/compiled/latest/stdlib/36_Block.mv b/vm/stdlib/compiled/latest/stdlib/37_Block.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/36_Block.mv rename to vm/stdlib/compiled/latest/stdlib/37_Block.mv diff --git a/vm/stdlib/compiled/latest/stdlib/37_TreasuryWithdrawDaoProposal.mv b/vm/stdlib/compiled/latest/stdlib/38_TreasuryWithdrawDaoProposal.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/37_TreasuryWithdrawDaoProposal.mv rename to vm/stdlib/compiled/latest/stdlib/38_TreasuryWithdrawDaoProposal.mv diff --git a/vm/stdlib/compiled/latest/stdlib/38_BlockReward.mv b/vm/stdlib/compiled/latest/stdlib/39_BlockReward.mv similarity index 100% rename from vm/stdlib/compiled/latest/stdlib/38_BlockReward.mv rename to vm/stdlib/compiled/latest/stdlib/39_BlockReward.mv diff --git a/vm/stdlib/compiled/latest/stdlib/39_ChainId.mv b/vm/stdlib/compiled/latest/stdlib/39_ChainId.mv deleted file mode 100644 index d13599d50c..0000000000 Binary files a/vm/stdlib/compiled/latest/stdlib/39_ChainId.mv and /dev/null differ diff --git a/vm/stdlib/modules/ChainId.move b/vm/stdlib/modules/ChainId.move index 9434828e8b..f03319f72b 100644 --- a/vm/stdlib/modules/ChainId.move +++ b/vm/stdlib/modules/ChainId.move @@ -16,6 +16,13 @@ module ChainId { id: u8 } + const MAIN_CHAIN_ID: u8 = 1; + const BARNARD_CHAIN_ID: u8 = 251; + const PROXIMA_CHAIN_ID: u8 = 252; + const HALLEY_CHAIN_ID: u8 = 253; + const DEV_CHAIN_ID: u8 = 254; + const TEST_CHAIN_ID: u8 = 255; + /// Publish the chain ID under the genesis account public fun initialize(account: &signer, id: u8) { Timestamp::assert_genesis(); @@ -35,6 +42,10 @@ module ChainId { borrow_global(CoreAddresses::GENESIS_ADDRESS()).id } + public fun is_dev(): bool acquires ChainId { + get() == DEV_CHAIN_ID + } + spec get { aborts_if !exists(CoreAddresses::SPEC_GENESIS_ADDRESS()); ensures exists(CoreAddresses::SPEC_GENESIS_ADDRESS()); diff --git a/vm/stdlib/modules/VMConfig.move b/vm/stdlib/modules/VMConfig.move index 99b436ee93..e9fd1e11e8 100644 --- a/vm/stdlib/modules/VMConfig.move +++ b/vm/stdlib/modules/VMConfig.move @@ -5,6 +5,7 @@ module VMConfig { use 0x1::Signer; use 0x1::CoreAddresses; use 0x1::Vector; + use 0x1::ChainId; spec module { pragma verify = false; pragma aborts_if_is_strict; @@ -167,6 +168,7 @@ module VMConfig { } public fun gas_constants(): GasConstants { + let min_price_per_gas_unit: u64 = if (ChainId::is_dev()) { 0 } else { 1 }; GasConstants { global_memory_per_byte_cost: 4, global_memory_per_byte_write_cost: 9, @@ -174,7 +176,7 @@ module VMConfig { large_transaction_cutoff: 600, instrinsic_gas_per_byte: 8, maximum_number_of_gas_units: 40000000, //must less than base_block_gas_limit - min_price_per_gas_unit: 1, + min_price_per_gas_unit, max_price_per_gas_unit: 10000, max_transaction_size_in_bytes: 1024 * 128, gas_unit_scaling_factor: 1, diff --git a/vm/stdlib/modules/doc/ChainId.md b/vm/stdlib/modules/doc/ChainId.md index 6e53c76bec..ecaf72165b 100644 --- a/vm/stdlib/modules/doc/ChainId.md +++ b/vm/stdlib/modules/doc/ChainId.md @@ -7,11 +7,13 @@ The module provides chain id information. - [Resource `ChainId`](#0x1_ChainId_ChainId) +- [Constants](#@Constants_0) - [Function `initialize`](#0x1_ChainId_initialize) - [Function `get`](#0x1_ChainId_get) -- [Specification](#@Specification_0) - - [Function `initialize`](#@Specification_0_initialize) - - [Function `get`](#@Specification_0_get) +- [Function `is_dev`](#0x1_ChainId_is_dev) +- [Specification](#@Specification_1) + - [Function `initialize`](#@Specification_1_initialize) + - [Function `get`](#@Specification_1_get)
use 0x1::CoreAddresses;
@@ -48,6 +50,65 @@ chain id data structure.
 
 
 
+
+
+## Constants
+
+
+
+
+
+
+
const BARNARD_CHAIN_ID: u8 = 251;
+
+ + + + + + + +
const DEV_CHAIN_ID: u8 = 254;
+
+ + + + + + + +
const HALLEY_CHAIN_ID: u8 = 253;
+
+ + + + + + + +
const MAIN_CHAIN_ID: u8 = 1;
+
+ + + + + + + +
const PROXIMA_CHAIN_ID: u8 = 252;
+
+ + + + + + + +
const TEST_CHAIN_ID: u8 = 255;
+
+ + + ## Function `initialize` @@ -100,7 +161,31 @@ Return the chain ID of this chain - + + +## Function `is_dev` + + + +
public fun is_dev(): bool
+
+ + + +
+Implementation + + +
public fun is_dev(): bool acquires ChainId {
+    get() == DEV_CHAIN_ID
+}
+
+ + + +
+ + ## Specification @@ -112,7 +197,7 @@ Return the chain ID of this chain - + ### Function `initialize` @@ -131,7 +216,7 @@ Return the chain ID of this chain - + ### Function `get` diff --git a/vm/stdlib/modules/doc/VMConfig.md b/vm/stdlib/modules/doc/VMConfig.md index 4af66b66e4..e5e4b46556 100644 --- a/vm/stdlib/modules/doc/VMConfig.md +++ b/vm/stdlib/modules/doc/VMConfig.md @@ -20,7 +20,8 @@ - [Function `initialize`](#@Specification_0_initialize) -
use 0x1::Config;
+
use 0x1::ChainId;
+use 0x1::Config;
 use 0x1::CoreAddresses;
 use 0x1::Vector;
 
@@ -385,6 +386,7 @@ The GasCost tracks:
public fun gas_constants(): GasConstants {
+    let min_price_per_gas_unit: u64 = if (ChainId::is_dev()) { 0 }  else { 1 };
     GasConstants {
         global_memory_per_byte_cost: 4,
         global_memory_per_byte_write_cost: 9,
@@ -392,7 +394,7 @@ The  GasCost tracks:
         large_transaction_cutoff: 600,
         instrinsic_gas_per_byte: 8,
         maximum_number_of_gas_units: 40000000, //must less than base_block_gas_limit
-        min_price_per_gas_unit: 1,
+        min_price_per_gas_unit,
         max_price_per_gas_unit: 10000,
         max_transaction_size_in_bytes: 1024 * 128,
         gas_unit_scaling_factor: 1,
diff --git a/vm/types/src/on_chain_config/mod.rs b/vm/types/src/on_chain_config/mod.rs
index 27efb24b32..9b7950b570 100644
--- a/vm/types/src/on_chain_config/mod.rs
+++ b/vm/types/src/on_chain_config/mod.rs
@@ -30,10 +30,7 @@ pub use self::{
     },
     move_lang_version::MoveLanguageVersion,
     version::{version_config_type_tag, Version, VERSION_CONFIG_IDENTIFIER},
-    vm_config::{
-        vm_config_type_tag, TransactionPublishOption, VMConfig, SCRIPT_HASH_LENGTH,
-        VM_CONFIG_IDENTIFIER,
-    },
+    vm_config::*,
 };
 pub use crate::on_chain_resource::GlobalTimeOnChain;
 
diff --git a/vm/types/src/on_chain_config/vm_config.rs b/vm/types/src/on_chain_config/vm_config.rs
index 4f9ba7a045..5e0b2a28fe 100644
--- a/vm/types/src/on_chain_config/vm_config.rs
+++ b/vm/types/src/on_chain_config/vm_config.rs
@@ -16,6 +16,12 @@ pub const SCRIPT_HASH_LENGTH: usize = HashValue::LENGTH;
 const VM_CONFIG_MODULE_NAME: &str = "VMConfig";
 pub static VM_CONFIG_IDENTIFIER: Lazy =
     Lazy::new(|| Identifier::new(VM_CONFIG_MODULE_NAME).unwrap());
+pub static INSTRUCTION_SCHEDULE_IDENTIFIER: Lazy =
+    Lazy::new(|| Identifier::new("instruction_schedule").unwrap());
+pub static NATIVE_SCHEDULE_IDENTIFIER: Lazy =
+    Lazy::new(|| Identifier::new("native_schedule").unwrap());
+pub static GAS_CONSTANTS_IDENTIFIER: Lazy =
+    Lazy::new(|| Identifier::new("gas_constants").unwrap());
 
 /// Defines and holds the publishing policies for the VM. There are three possible configurations:
 /// 1.  !script_allowed && !module_publishing_allowed No module publishing, only script function are allowed.
@@ -83,46 +89,46 @@ pub struct VMConfig {
     pub gas_schedule: CostTable,
 }
 
-// #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-// struct CostTableInner {
-//     pub instruction_table: Vec,
-//     pub native_table: Vec,
-//     pub gas_constants: GasConstants,
-// }
-//
-// #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
-// #[allow(clippy::upper_case_acronyms)]
-// struct VMConfigInner {
-//     pub gas_schedule: CostTableInner,
-// }
-//
-// impl CostTableInner {
-//     pub fn as_cost_table(&self) -> Result {
-//         let instruction_table = bcs_ext::from_bytes(&self.instruction_table)?;
-//         let native_table = bcs_ext::from_bytes(&self.native_table)?;
-//         Ok(CostTable {
-//             instruction_table,
-//             native_table,
-//             gas_constants: self.gas_constants.clone(),
-//         })
-//     }
-// }
-
-// impl OnChainConfig for VMConfig {
-//     const MODULE_IDENTIFIER: &'static str = VM_CONFIG_MODULE_NAME;
-//     const CONF_IDENTIFIER: &'static str = VM_CONFIG_MODULE_NAME;
-//
-//     fn deserialize_into_config(bytes: &[u8]) -> Result {
-//         let raw_vm_config = bcs_ext::from_bytes::(bytes).map_err(|e| {
-//             format_err!(
-//                 "Failed first round of deserialization for VMConfigInner: {}",
-//                 e
-//             )
-//         })?;
-//         let gas_schedule = raw_vm_config.gas_schedule.as_cost_table()?;
-//         Ok(VMConfig { gas_schedule })
-//     }
-// }
+#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
+struct CostTableInner {
+    pub instruction_table: Vec,
+    pub native_table: Vec,
+    pub gas_constants: GasConstants,
+}
+
+#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
+#[allow(clippy::upper_case_acronyms)]
+struct VMConfigInner {
+    pub gas_schedule: CostTableInner,
+}
+
+impl CostTableInner {
+    pub fn as_cost_table(&self) -> Result {
+        let instruction_table = bcs_ext::from_bytes(&self.instruction_table)?;
+        let native_table = bcs_ext::from_bytes(&self.native_table)?;
+        Ok(CostTable {
+            instruction_table,
+            native_table,
+            gas_constants: self.gas_constants.clone(),
+        })
+    }
+}
+
+impl OnChainConfig for VMConfig {
+    const MODULE_IDENTIFIER: &'static str = VM_CONFIG_MODULE_NAME;
+    const CONF_IDENTIFIER: &'static str = VM_CONFIG_MODULE_NAME;
+
+    fn deserialize_into_config(bytes: &[u8]) -> Result {
+        let raw_vm_config = bcs_ext::from_bytes::(bytes).map_err(|e| {
+            format_err!(
+                "Failed first round of deserialization for VMConfigInner: {}",
+                e
+            )
+        })?;
+        let gas_schedule = raw_vm_config.gas_schedule.as_cost_table()?;
+        Ok(VMConfig { gas_schedule })
+    }
+}
 
 pub fn vm_config_type_tag() -> TypeTag {
     TypeTag::Struct(StructTag {
diff --git a/vm/vm-runtime/src/starcoin_vm.rs b/vm/vm-runtime/src/starcoin_vm.rs
index b957a38fd3..fc2781d696 100644
--- a/vm/vm-runtime/src/starcoin_vm.rs
+++ b/vm/vm-runtime/src/starcoin_vm.rs
@@ -41,7 +41,10 @@ use starcoin_vm_types::gas_schedule::{zero_cost_schedule, GasConstants, GasCost,
 use starcoin_vm_types::genesis_config::StdlibVersion;
 use starcoin_vm_types::identifier::IdentStr;
 use starcoin_vm_types::language_storage::ModuleId;
-use starcoin_vm_types::on_chain_config::{MoveLanguageVersion, VM_CONFIG_IDENTIFIER};
+use starcoin_vm_types::on_chain_config::{
+    MoveLanguageVersion, GAS_CONSTANTS_IDENTIFIER, INSTRUCTION_SCHEDULE_IDENTIFIER,
+    NATIVE_SCHEDULE_IDENTIFIER, VM_CONFIG_IDENTIFIER,
+};
 use starcoin_vm_types::transaction::{DryRunTransaction, Package, TransactionPayloadType};
 use starcoin_vm_types::transaction_metadata::TransactionPayloadMetadata;
 use starcoin_vm_types::value::{serialize_values, MoveValue};
@@ -73,6 +76,9 @@ pub struct StarcoinVM {
     metrics: Option,
 }
 
+/// marking of stdlib version which includes vmconfig upgrades.
+const VMCONFIG_UPGRADE_VERSION_MARK: u64 = 10;
+
 impl StarcoinVM {
     pub fn new(metrics: Option) -> Self {
         let inner = MoveVM::new(super::natives::starcoin_natives())
@@ -99,60 +105,6 @@ impl StarcoinVM {
     }
 
     fn load_configs_impl(&mut self, state: &dyn StateView) -> Result<(), Error> {
-        let instruction_schedule = {
-            let data = self
-                .execute_readonly_function(
-                    state,
-                    &ModuleId::new(core_code_address(), VM_CONFIG_IDENTIFIER.to_owned()),
-                    IdentStr::new("instruction_schedule").unwrap(),
-                    vec![],
-                    vec![],
-                )?
-                .pop()
-                .ok_or_else(|| {
-                    anyhow::anyhow!("Expect 0x1::VMConfig::instruction_schedule() return value")
-                })?;
-            bcs_ext::from_bytes::>(&data)?
-        };
-        let native_schedule = {
-            let data = self
-                .execute_readonly_function(
-                    state,
-                    &ModuleId::new(core_code_address(), VM_CONFIG_IDENTIFIER.to_owned()),
-                    IdentStr::new("native_schedule").unwrap(),
-                    vec![],
-                    vec![],
-                )?
-                .pop()
-                .ok_or_else(|| {
-                    anyhow::anyhow!("Expect 0x1::VMConfig::native_schedule() return value")
-                })?;
-            bcs_ext::from_bytes::>(&data)?
-        };
-        let gas_constants = {
-            let data = self
-                .execute_readonly_function(
-                    state,
-                    &ModuleId::new(core_code_address(), VM_CONFIG_IDENTIFIER.to_owned()),
-                    IdentStr::new("gas_constants").unwrap(),
-                    vec![],
-                    vec![],
-                )?
-                .pop()
-                .ok_or_else(|| {
-                    anyhow::anyhow!("Expect 0x1::VMConfig::gas_constants() return value")
-                })?;
-            bcs_ext::from_bytes::(&data)?
-        };
-
-        self.vm_config = Some(VMConfig {
-            gas_schedule: CostTable {
-                instruction_table: instruction_schedule,
-                native_table: native_schedule,
-                gas_constants,
-            },
-        });
-
         let remote_storage = RemoteStorage::new(state);
         self.version = Some(
             Version::fetch_config(&remote_storage)?
@@ -160,6 +112,70 @@ impl StarcoinVM {
         );
         // move version can be none.
         self.move_version = MoveLanguageVersion::fetch_config(&remote_storage)?;
+
+        if let Some(v) = &self.version {
+            self.vm_config = if v.major < VMCONFIG_UPGRADE_VERSION_MARK {
+                Some(VMConfig::fetch_config(&remote_storage)?.ok_or_else(|| {
+                    format_err!("Load VMConfig fail, VMConfig resource not exist.")
+                })?)
+            } else {
+                let instruction_schedule = {
+                    let data = self
+                        .execute_readonly_function(
+                            state,
+                            &ModuleId::new(core_code_address(), VM_CONFIG_IDENTIFIER.to_owned()),
+                            INSTRUCTION_SCHEDULE_IDENTIFIER.as_ident_str(),
+                            vec![],
+                            vec![],
+                        )?
+                        .pop()
+                        .ok_or_else(|| {
+                            anyhow::anyhow!(
+                                "Expect 0x1::VMConfig::instruction_schedule() return value"
+                            )
+                        })?;
+                    bcs_ext::from_bytes::>(&data)?
+                };
+                let native_schedule = {
+                    let data = self
+                        .execute_readonly_function(
+                            state,
+                            &ModuleId::new(core_code_address(), VM_CONFIG_IDENTIFIER.to_owned()),
+                            NATIVE_SCHEDULE_IDENTIFIER.as_ident_str(),
+                            vec![],
+                            vec![],
+                        )?
+                        .pop()
+                        .ok_or_else(|| {
+                            anyhow::anyhow!("Expect 0x1::VMConfig::native_schedule() return value")
+                        })?;
+                    bcs_ext::from_bytes::>(&data)?
+                };
+                let gas_constants = {
+                    let data = self
+                        .execute_readonly_function(
+                            state,
+                            &ModuleId::new(core_code_address(), VM_CONFIG_IDENTIFIER.to_owned()),
+                            GAS_CONSTANTS_IDENTIFIER.as_ident_str(),
+                            vec![],
+                            vec![],
+                        )?
+                        .pop()
+                        .ok_or_else(|| {
+                            anyhow::anyhow!("Expect 0x1::VMConfig::gas_constants() return value")
+                        })?;
+                    bcs_ext::from_bytes::(&data)?
+                };
+
+                Some(VMConfig {
+                    gas_schedule: CostTable {
+                        instruction_table: instruction_schedule,
+                        native_table: native_schedule,
+                        gas_constants,
+                    },
+                })
+            }
+        }
         Ok(())
     }