Skip to content

Commit

Permalink
adding dependency charging and add event validation
Browse files Browse the repository at this point in the history
  • Loading branch information
beer-1 committed Mar 5, 2024
1 parent 92e448c commit 2ddb29d
Show file tree
Hide file tree
Showing 19 changed files with 351 additions and 45 deletions.
58 changes: 29 additions & 29 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -104,35 +104,35 @@ bigdecimal = "0.4"
# Note: the BEGIN and END comments below are required for external tooling. Do not remove.
# BEGIN MOVE DEPENDENCIES

# move-abigen = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
# move-bytecode-utils = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
# move-errmapgen = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
# move-ir-compiler = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
# move-prover-test-utils = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
# move-stackless-bytecode-interpreter = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
# move-transactional-test-runner = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
# read-write-set = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
# read-write-set-dynamic = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-binary-format = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-bytecode-verifier = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-cli = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-command-line-common = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-compiler = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-core-types = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-docgen = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-model = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-package = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-prover = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-prover-boogie-backend = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-prover-bytecode-pipeline = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-resource-viewer = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-stackless-bytecode = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-stdlib = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-symbol-pool = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-unit-test = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-vm-runtime = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-vm-test-utils = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
move-vm-types = { git = "https://github.com/initia-labs/move.git", rev = "73efc58e3389d456a6e65b33e4d2ec444f18fd47" }
# move-abigen = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
# move-bytecode-utils = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
# move-errmapgen = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
# move-ir-compiler = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
# move-prover-test-utils = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
# move-stackless-bytecode-interpreter = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
# move-transactional-test-runner = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
# read-write-set = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
# read-write-set-dynamic = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-binary-format = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-bytecode-verifier = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-cli = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-command-line-common = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-compiler = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-core-types = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-docgen = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-model = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-package = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-prover = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-prover-boogie-backend = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-prover-bytecode-pipeline = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-resource-viewer = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-stackless-bytecode = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-stdlib = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-symbol-pool = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-unit-test = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-vm-runtime = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-vm-test-utils = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }
move-vm-types = { git = "https://github.com/initia-labs/move.git", rev = "c27b20c33a8dea33716bf3da931ca8229ac88e00" }

# END MOVE DEPENDENCIES

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module std::BasicCoin {
test: bool,
}

#[event]
/// Event emitted when some amount of coins are withdrawn from an Collateral.
struct MintEvent has drop, store {
amount: u64,
Expand Down
2 changes: 1 addition & 1 deletion crates/e2e-move-tests/src/tests/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ fn test_redeploy_should_update_module_cache() {

h.initialize();

let code = hex::decode("a11ceb0b060000000d01000a020a12031c28044404054822076aa001088a022010aa02350adf02140bf302020cf502670ddc03020ede030200000001000200030004000509010001000600000007060003110700000800010100000900020100000a03040100000b04010002120700000413040801000114050401060505060901050103010b00010900020c03000109000205070b0001090001060c010803010802094261736963436f696e056576656e74067369676e657206737472696e6709747970655f696e666f04436f696e06496e69746961094d696e744576656e7403676574086765745f636f696e046d696e74066e756d6265720576616c756504746573740b64756d6d795f6669656c6406616d6f756e7409636f696e5f7479706506537472696e670a616464726573735f6f6609747970655f6e616d6504656d6974000000000000000000000000000000000000000000000000000000000000000113696e697469613a3a6d657461646174615f76302000000303676574010100066e756d626572010100086765745f636f696e0101000002020c030d010102010e010202020f031008030005000100010004050b003d0037001402010100010004040b003d0014020201040100061d0e0011040c020a023b0020040d0e000a010839003f0005180b023c000c030a033700140a01160b033600150b0138001202380102030100000402064101000000000000020000000500").expect("ms");
let code = hex::decode("a11ceb0b060000000d01000a020a12031c28044404054822076aa001088a022010aa02420aec02140b8003020c8203670de903020eeb030200000001000200030004000509010001000600000007060003110700000800010100000900020100000a03040100000b04010002120700000413040801000114050401060505060901050103010b00010900020c03000109000205070b0001090001060c010803010802094261736963436f696e056576656e74067369676e657206737472696e6709747970655f696e666f04436f696e06496e69746961094d696e744576656e7403676574086765745f636f696e046d696e74066e756d6265720576616c756504746573740b64756d6d795f6669656c6406616d6f756e7409636f696e5f7479706506537472696e670a616464726573735f6f6609747970655f6e616d6504656d6974000000000000000000000000000000000000000000000000000000000000000113696e697469613a3a6d657461646174615f76302d0001094d696e744576656e740104000303676574010100066e756d626572010100086765745f636f696e0101000002020c030d010102010e010202020f031008030005000100010004050b003d0037001402010100010004040b003d0014020201040100061d0e0011040c020a023b0020040d0e000a010839003f0005180b023c000c030a033700140a01160b033600150b0138001202380102030100000402064101000000000000020000000500").expect("ms");
let msg = h.create_publish_message(
AccountAddress::ONE,
vec!["0x1::BasicCoin".to_string()],
Expand Down
119 changes: 107 additions & 12 deletions crates/vm/src/move_vm.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use move_binary_format::{
access::ModuleAccess,
compatibility::Compatibility,
errors::{Location, PartialVMError, VMResult},
CompiledModule,
Expand All @@ -12,18 +13,22 @@ use move_core_types::{
value::MoveValue,
vm_status::{StatusCode, VMStatus},
};
use move_vm_runtime::session::SerializedReturnValues;
use move_vm_runtime::{
config::VMConfig, native_extensions::NativeContextExtensions, runtime::VMRuntime,
session_cache::SessionCache,
};
use move_vm_runtime::{
module_traversal::{TraversalContext, TraversalStorage},
session::SerializedReturnValues,
};
use move_vm_types::gas::GasMeter;

use std::{collections::BTreeSet, sync::Arc};

use initia_move_gas::MiscGasParameters;
use initia_move_gas::{
Gas, InitiaGasMeter, InitiaGasParameters, InitialGasSchedule, NativeGasParameters,
};
use initia_move_gas::{MiscGasParameters, NumBytes};
use initia_move_natives::{
account::{AccountAPI, NativeAccountContext},
all_natives,
Expand Down Expand Up @@ -63,7 +68,8 @@ use crate::{
convert::convert_move_value_to_serde_value,
session::{SessionExt, SessionOutput},
verifier::{
config::verifier_config, errors::metadata_validation_error, metadata::get_vm_metadata,
config::verifier_config, errors::metadata_validation_error,
event_validation::verify_no_event_emission_in_script, metadata::get_vm_metadata,
module_init::verify_module_init_function, module_metadata::validate_publish_request,
transaction_arg_validation::validate_combine_signer_and_txn_args,
view_function::validate_view_function,
Expand Down Expand Up @@ -166,6 +172,8 @@ impl MoveVM {
let mut gas_meter = InitiaGasMeter::new(gas_params, gas_limit);

let mut session = self.create_session(api, env, state_view_impl, table_view_impl);
let traversal_storage = TraversalStorage::new();
let mut traversal_context = TraversalContext::new(&traversal_storage);

let publish_request = PublishRequest {
check_compat: false,
Expand All @@ -174,8 +182,12 @@ impl MoveVM {
module_bundle,
};

let published_module_ids =
self.resolve_pending_code_publish(&mut session, &mut gas_meter, publish_request)?;
let published_module_ids = self.resolve_pending_code_publish(
&mut session,
&mut gas_meter,
publish_request,
&mut traversal_context,
)?;

// execute code::init_genesis to properly store module metadata.
{
Expand Down Expand Up @@ -225,6 +237,8 @@ impl MoveVM {
) -> Result<MessageOutput, VMStatus> {
let senders = msg.senders().to_vec();
let mut gas_meter = InitiaGasMeter::new(self.gas_params.clone(), gas_limit);
let traversal_storage = TraversalStorage::new();
let mut traversal_context = TraversalContext::new(&traversal_storage);

// Charge for msg byte size
gas_meter.charge_intrinsic_gas_for_transaction((msg.size() as u64).into())?;
Expand All @@ -237,6 +251,7 @@ impl MoveVM {
senders,
msg.payload(),
&mut gas_meter,
&mut traversal_context,
);

res
Expand Down Expand Up @@ -299,14 +314,27 @@ impl MoveVM {
senders: Vec<AccountAddress>,
payload: &MessagePayload,
gas_meter: &mut InitiaGasMeter,
traversal_context: &mut TraversalContext,
) -> Result<MessageOutput, VMStatus> {
let mut session = self.create_session(api, env, state_view_impl, table_view_impl);

let res = match payload {
MessagePayload::Script(script) => {
session.check_script_dependencies_and_check_gas(
gas_meter,
traversal_context,
script.code(),
)?;

// we only use the ok path, let move vm handle the wrong path.
// let Ok(s) = CompiledScript::deserialize(script.code());
let func_inst = session.load_script(script.code(), script.ty_args().to_vec())?;

verify_no_event_emission_in_script(
script.code(),
&session.get_vm_config().deserializer_config,
)?;

let args = validate_combine_signer_and_txn_args(
&mut session,
senders,
Expand All @@ -322,6 +350,15 @@ impl MoveVM {
)
}
MessagePayload::Execute(entry_fn) => {
let module_id = traversal_context
.referenced_module_ids
.alloc(entry_fn.module().clone());
session.check_dependencies_and_charge_gas(
gas_meter,
traversal_context,
[(module_id.address(), module_id.name())],
)?;

let func_inst = session.load_function(
entry_fn.module(),
entry_fn.function(),
Expand Down Expand Up @@ -355,7 +392,12 @@ impl MoveVM {
}

if let Some(publish_request) = session.extract_publish_request() {
self.resolve_pending_code_publish(&mut session, gas_meter, publish_request)?;
self.resolve_pending_code_publish(
&mut session,
gas_meter,
publish_request,
traversal_context,
)?;
}

let session_output = session.finish()?;
Expand All @@ -377,6 +419,7 @@ impl MoveVM {
session: &mut SessionExt,
gas_meter: &mut InitiaGasMeter,
publish_request: PublishRequest,
traversal_context: &mut TraversalContext,
) -> VMResult<Vec<String>> {
let PublishRequest {
destination,
Expand All @@ -391,12 +434,65 @@ impl MoveVM {
// directly pass CompiledModule.
let sorted_module_bundle = module_bundle.sorted_code_and_modules();
let modules = self.deserialize_module_bundle(&sorted_module_bundle)?;
let modules: &Vec<CompiledModule> =
traversal_context.referenced_module_bundles.alloc(modules);

// Note: Feature gating is needed here because the traversal of the dependencies could
// result in shallow-loading of the modules and therefore subtle changes in
// the error semantics.
{
// Charge old versions of the modules, in case of upgrades.
session.check_dependencies_and_charge_gas_non_recursive_optional(
gas_meter,
traversal_context,
modules
.iter()
.map(|module| (module.self_addr(), module.self_name())),
)?;

// Charge all modules in the bundle that is about to be published.
for (module, blob) in modules.iter().zip(sorted_module_bundle.iter()) {
let module_id = &module.self_id();
gas_meter
.charge_dependency(
true,
module_id.address(),
module_id.name(),
NumBytes::new(blob.code().len() as u64),
)
.map_err(|err| err.finish(Location::Undefined))?;
}

// Charge all dependencies.
//
// Must exclude the ones that are in the current bundle because they have not
// been published yet.
let module_ids_in_bundle = modules
.iter()
.map(|module| (module.self_addr(), module.self_name()))
.collect::<BTreeSet<_>>();

session.check_dependencies_and_charge_gas(
gas_meter,
traversal_context,
modules
.iter()
.flat_map(|module| {
module
.immediate_dependencies_iter()
.chain(module.immediate_friends_iter())
})
.filter(|addr_and_name| !module_ids_in_bundle.contains(addr_and_name)),
)?;

// TODO: Revisit the order of traversal. Consider switching to alphabetical order.
}

// validate modules are properly compiled with metadata
validate_publish_request(&modules)?;
validate_publish_request(session, modules)?;

if let Some(mut expected_modules) = expected_modules {
for m in &modules {
for m in modules {
if !expected_modules.remove(m.self_id().short_str_lossless().as_str()) {
return Err(metadata_validation_error(&format!(
"unregistered module: '{}'",
Expand All @@ -409,7 +505,7 @@ impl MoveVM {
// Check what modules exist before publishing.
let mut exists = BTreeSet::new();
let mut published_module_ids = vec![];
for m in &modules {
for m in modules {
let id = m.self_id();
published_module_ids.push(id.short_str_lossless());

Expand All @@ -418,8 +514,7 @@ impl MoveVM {
}
}

// need to invalidate cache if tx failed and publish module executed
// in previous message.
// publish and cache the modules on loader cache.
session.publish_module_bundle_with_compat_config(
sorted_module_bundle.into_inner(),
destination,
Expand All @@ -432,7 +527,7 @@ impl MoveVM {
)?;

// call init function of the each module
self.execute_module_initialization(session, gas_meter, &modules, exists, &[destination])?;
self.execute_module_initialization(session, gas_meter, modules, exists, &[destination])?;

Ok(published_module_ids)
}
Expand Down
Loading

0 comments on commit 2ddb29d

Please sign in to comment.