diff --git a/aptos-move/framework/aptos-stdlib/doc/simple_map.md b/aptos-move/framework/aptos-stdlib/doc/simple_map.md index 844de13914d3c..c114cfab0f38f 100644 --- a/aptos-move/framework/aptos-stdlib/doc/simple_map.md +++ b/aptos-move/framework/aptos-stdlib/doc/simple_map.md @@ -734,6 +734,7 @@ Remove a key/value pair from the map. The key must exist.
pragma intrinsic;
 pragma opaque;
+aborts_if [abstract] false;
 ensures [abstract] spec_len(result) == 0;
 ensures [abstract] forall k: Key: !spec_contains_key(result, k);
 
@@ -753,6 +754,7 @@ Remove a key/value pair from the map. The key must exist.
pragma intrinsic;
 pragma opaque;
+aborts_if [abstract] false;
 ensures [abstract] spec_len(result) == len(keys);
 ensures [abstract] forall k: Key: spec_contains_key(result, k) <==> vector::spec_contains(keys, k);
 ensures [abstract] forall i in 0..len(keys):
diff --git a/aptos-move/framework/aptos-stdlib/sources/simple_map.spec.move b/aptos-move/framework/aptos-stdlib/sources/simple_map.spec.move
index 9071fc043610c..fefe52ee5d18f 100644
--- a/aptos-move/framework/aptos-stdlib/sources/simple_map.spec.move
+++ b/aptos-move/framework/aptos-stdlib/sources/simple_map.spec.move
@@ -71,6 +71,7 @@ spec aptos_std::simple_map {
     spec new(): SimpleMap {
         pragma intrinsic;
         pragma opaque;
+        aborts_if [abstract] false;
         ensures [abstract] spec_len(result) == 0;
         ensures [abstract] forall k: Key: !spec_contains_key(result, k);
     }
@@ -81,6 +82,7 @@ spec aptos_std::simple_map {
     ): SimpleMap {
         pragma intrinsic;
         pragma opaque;
+        aborts_if [abstract] false;
         ensures [abstract] spec_len(result) == len(keys);
         ensures [abstract] forall k: Key: spec_contains_key(result, k) <==> vector::spec_contains(keys, k);
         ensures [abstract] forall i in 0..len(keys):
diff --git a/aptos-move/framework/src/aptos.rs b/aptos-move/framework/src/aptos.rs
index a78b0e7bbda4f..b27745c8eb289 100644
--- a/aptos-move/framework/src/aptos.rs
+++ b/aptos-move/framework/src/aptos.rs
@@ -187,6 +187,7 @@ static NAMED_ADDRESSES: Lazy> = Lazy::new(||
     result.insert("aptos_token".to_owned(), three);
     result.insert("aptos_token_objects".to_owned(), four);
     result.insert("core_resources".to_owned(), resources);
+    result.insert("vm".to_owned(), zero);
     result.insert("vm_reserved".to_owned(), zero);
     result
 });
diff --git a/aptos-move/framework/src/natives/consensus_config.rs b/aptos-move/framework/src/natives/consensus_config.rs
new file mode 100644
index 0000000000000..0d15f084b7f3d
--- /dev/null
+++ b/aptos-move/framework/src/natives/consensus_config.rs
@@ -0,0 +1,31 @@
+// Copyright © Aptos Foundation
+
+use aptos_native_interface::{
+    safely_pop_arg, RawSafeNative, SafeNativeBuilder, SafeNativeContext, SafeNativeResult,
+};
+use aptos_types::on_chain_config::OnChainConsensusConfig;
+use move_vm_runtime::native_functions::NativeFunction;
+use move_vm_types::{loaded_data::runtime_types::Type, values::Value};
+use smallvec::{smallvec, SmallVec};
+use std::collections::VecDeque;
+
+pub fn validator_txn_enabled(
+    _context: &mut SafeNativeContext,
+    _ty_args: Vec,
+    mut args: VecDeque,
+) -> SafeNativeResult> {
+    let config_bytes = safely_pop_arg!(args, Vec);
+    let config = bcs::from_bytes::(&config_bytes).unwrap_or_default();
+    Ok(smallvec![Value::bool(config.is_vtxn_enabled())])
+}
+
+pub fn make_all(
+    builder: &SafeNativeBuilder,
+) -> impl Iterator + '_ {
+    let natives = vec![(
+        "validator_txn_enabled_internal",
+        validator_txn_enabled as RawSafeNative,
+    )];
+
+    builder.make_named_natives(natives)
+}
diff --git a/aptos-move/framework/src/natives/mod.rs b/aptos-move/framework/src/natives/mod.rs
index 408b9f660c11d..9f5cdf25b6cab 100644
--- a/aptos-move/framework/src/natives/mod.rs
+++ b/aptos-move/framework/src/natives/mod.rs
@@ -5,6 +5,7 @@
 pub mod account;
 pub mod aggregator_natives;
 pub mod code;
+pub mod consensus_config;
 pub mod create_signer;
 pub mod cryptography;
 pub mod debug;
@@ -12,6 +13,7 @@ pub mod event;
 pub mod hash;
 pub mod object;
 pub mod object_code_deployment;
+pub mod randomness;
 pub mod state_storage;
 pub mod string_utils;
 pub mod transaction_context;
@@ -62,6 +64,7 @@ pub fn all_natives(
     add_natives_from_module!("type_info", type_info::make_all(builder));
     add_natives_from_module!("util", util::make_all(builder));
     add_natives_from_module!("from_bcs", util::make_all(builder));
+    add_natives_from_module!("randomness", randomness::make_all(builder));
     add_natives_from_module!(
         "ristretto255_bulletproofs",
         cryptography::bulletproofs::make_all(builder)
@@ -79,6 +82,7 @@ pub fn all_natives(
     add_natives_from_module!("object", object::make_all(builder));
     add_natives_from_module!("debug", debug::make_all(builder));
     add_natives_from_module!("string_utils", string_utils::make_all(builder));
+    add_natives_from_module!("consensus_config", consensus_config::make_all(builder));
 
     make_table_from_iter(framework_addr, natives)
 }
diff --git a/aptos-move/framework/src/natives/randomness.rs b/aptos-move/framework/src/natives/randomness.rs
new file mode 100644
index 0000000000000..b35ca1e47b769
--- /dev/null
+++ b/aptos-move/framework/src/natives/randomness.rs
@@ -0,0 +1,58 @@
+// Copyright © Aptos Foundation
+
+use aptos_native_interface::{
+    RawSafeNative, SafeNativeBuilder, SafeNativeContext, SafeNativeResult,
+};
+use better_any::{Tid, TidAble};
+use move_vm_runtime::native_functions::NativeFunction;
+use move_vm_types::{loaded_data::runtime_types::Type, values::Value};
+use smallvec::{smallvec, SmallVec};
+use std::collections::VecDeque;
+
+/// A txn-local counter that increments each time a random 32-byte blob is requested.
+#[derive(Tid, Default)]
+pub struct RandomnessContext {
+    txn_local_state: Vec, //   8-byte counter
+}
+
+impl RandomnessContext {
+    pub fn new() -> Self {
+        Self {
+            txn_local_state: vec![0; 8],
+        }
+    }
+
+    pub fn increment(&mut self) {
+        for byte in self.txn_local_state.iter_mut() {
+            if *byte < 255 {
+                *byte += 1;
+                break;
+            } else {
+                *byte = 0;
+            }
+        }
+    }
+}
+
+pub fn fetch_and_increment_txn_counter(
+    context: &mut SafeNativeContext,
+    _ty_args: Vec,
+    _args: VecDeque,
+) -> SafeNativeResult> {
+    // TODO: charge gas?
+    let rand_ctxt = context.extensions_mut().get_mut::();
+    let ret = rand_ctxt.txn_local_state.to_vec();
+    rand_ctxt.increment();
+    Ok(smallvec![Value::vector_u8(ret)])
+}
+
+pub fn make_all(
+    builder: &SafeNativeBuilder,
+) -> impl Iterator + '_ {
+    let natives = vec![(
+        "fetch_and_increment_txn_counter",
+        fetch_and_increment_txn_counter as RawSafeNative,
+    )];
+
+    builder.make_named_natives(natives)
+}
diff --git a/third_party/move/move-stdlib/sources/hash.move b/third_party/move/move-stdlib/sources/hash.move
index daadc4e815770..ad1d0ae794afa 100644
--- a/third_party/move/move-stdlib/sources/hash.move
+++ b/third_party/move/move-stdlib/sources/hash.move
@@ -5,4 +5,9 @@
 module std::hash {
     native public fun sha2_256(data: vector): vector;
     native public fun sha3_256(data: vector): vector;
+
+    spec sha3_256(data: vector): vector {
+        aborts_if [abstract] false;
+        ensures [abstract] len(result) == 32;
+    }
 }