Skip to content

Commit

Permalink
Init sc update (#3333)
Browse files Browse the repository at this point in the history
* caller_has_write_access

* remove function exists inteface impl

* add get_owned_addresses_for

* cargo lock update

* sc_deployment execution test

* use testnet_18 version of runtime

* change setup_test.rs used tag

* caller_has_write_access optim
  • Loading branch information
Eitu33 authored Dec 19, 2022
1 parent 25826b0 commit eb0bc83
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 4 deletions.
4 changes: 3 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions massa-execution-worker/src/interface_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,26 @@ impl Interface for InterfaceImpl {
Ok(context.has_data_entry(&addr, key))
}

/// Check whether or not the caller has write access in the current context
///
/// # Returns
/// true if the caller has write access
fn caller_has_write_access(&self) -> Result<bool> {
let context = context_guard!(self);
let mut call_stack_iter = context.stack.iter().rev();
let caller_owned_addresses = if let Some(last) = call_stack_iter.next() {
if let Some(prev_to_last) = call_stack_iter.next() {
prev_to_last.owned_addresses.clone()
} else {
last.owned_addresses.clone()
}
} else {
return Err(anyhow!("empty stack"));
};
let current_address = context.get_current_address()?;
Ok(caller_owned_addresses.contains(&current_address))
}

/// Returns bytecode of the current address
fn raw_get_bytecode(&self) -> Result<Vec<u8>> {
let context = context_guard!(self);
Expand Down
79 changes: 77 additions & 2 deletions massa-execution-worker/src/tests/scenarios_mandatories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,10 +335,9 @@ fn send_and_receive_async_message() {
#[test]
#[serial]
fn local_execution() {
// setup the period duration and the maximum gas for asynchronous messages execution
// setup the period duration and cursor delay
let exec_cfg = ExecutionConfig {
t0: 100.into(),
max_async_gas: 1_000_000,
cursor_delay: 0.into(),
..ExecutionConfig::default()
};
Expand Down Expand Up @@ -424,6 +423,82 @@ fn local_execution() {
manager.stop();
}

/// Context
///
/// Functional test for sc deployment utility functions, `functionExists` and `callerHasWriteAccess`
///
/// 1. a block is created with one ExecuteSC operation containing
/// a deployment sc as bytecode to execute and a deplyed sc as an op datatsore entry
/// 2. store and set the block as final
/// 3. wait for execution
/// 4. retrieve events emitted by the initial an sub functions
/// 5. match events to make sure that `functionExists` and `callerHasWriteAccess` had the expected behaviour
#[test]
#[serial]
fn sc_deployment() {
// setup the period duration and cursor delay
let exec_cfg = ExecutionConfig {
t0: 100.into(),
cursor_delay: 0.into(),
..ExecutionConfig::default()
};
// get a sample final state
let (sample_state, _keep_file, _keep_dir) = get_sample_state().unwrap();

// init the storage
let mut storage = Storage::create_root();
// start the execution worker
let (mut manager, controller) = start_execution_worker(
exec_cfg.clone(),
sample_state.clone(),
sample_state.read().pos_state.selector.clone(),
);
// initialize the execution system with genesis blocks
init_execution_worker(&exec_cfg, &storage, controller.clone());
// keypair associated to thread 0
let keypair = KeyPair::from_str("S1JJeHiZv1C1zZN5GLFcbz6EXYiccmUPLkYuDFA3kayjxP39kFQ").unwrap();
// load bytecodes
// you can check the source code of the following wasm files in massa-unit-tests-src
let op_bytecode = include_bytes!("./wasm/deploy_sc.wasm");
let datastore_bytecode = include_bytes!("./wasm/init_sc.wasm").to_vec();
let mut datastore = BTreeMap::new();
datastore.insert(b"smart-contract".to_vec(), datastore_bytecode);

// create the block contaning the operation
let op = create_execute_sc_operation(&keypair, op_bytecode, datastore.clone()).unwrap();
storage.store_operations(vec![op.clone()]);
let block = create_block(KeyPair::generate(), vec![op], Slot::new(1, 0)).unwrap();
// store the block in storage
storage.store_block(block.clone());

// set our block as a final block so the message is sent
let mut finalized_blocks: HashMap<Slot, BlockId> = Default::default();
finalized_blocks.insert(block.content.header.content.slot, block.id);
let mut block_storage: PreHashMap<BlockId, Storage> = Default::default();
block_storage.insert(block.id, storage.clone());
controller.update_blockclique_status(
finalized_blocks,
Default::default(),
block_storage.clone(),
);
// sleep for 100ms to wait for execution
std::thread::sleep(Duration::from_millis(100));

// retrieve events emitted by smart contracts
let events = controller.get_filtered_sc_output_event(EventFilter {
..Default::default()
});

// match the events
assert!(events.len() == 3, "3 events were expected");
assert_eq!(events[0].data, "sc created");
assert_eq!(events[1].data, "constructor exists and will be called");
assert_eq!(events[2].data, "constructor called by deployer");

// stop the execution controller
manager.stop();
}

/// # Context
///
/// Functional test for asynchronous messages sending and handling with a filter
Expand Down
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion tools/setup_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use glob::glob;
use tar::Archive;

// git tag
const TAG: &str = "TEST.18.0";
const TAG: &str = "TEST.18.2";

// Maximum archive file size to download in bytes (here: 1Mb)
// const ARCHIVE_MAX_SIZE: u64 = 2; // Maximum archive file size to download in bytes (DEBUG)
Expand Down

0 comments on commit eb0bc83

Please sign in to comment.