Skip to content
This repository was archived by the owner on Jul 10, 2025. It is now read-only.

Commit 3a23274

Browse files
authored
feat(script): allow to overwrite spell script (#128)
1 parent 6267324 commit 3a23274

File tree

3 files changed

+57
-17
lines changed

3 files changed

+57
-17
lines changed

src/spell/modules/spell/spell/src/error_handling.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use marine_sqlite_connector::{State, Statement};
77

88
use fluence_spell_dtos::value::UnitValue;
99

10-
use crate::auth::is_by_spell;
10+
use crate::auth::{is_by_creator, is_by_spell};
1111
use crate::schema::db;
1212

1313
/// The `%last_error%` content.
@@ -85,7 +85,8 @@ pub struct AllErrorsResult {
8585
pub fn store_error(error: LastError, error_idx: u32, particle_timestamp: u64) -> UnitValue {
8686
let call_parameters = marine_rs_sdk::get_call_parameters();
8787

88-
if !is_by_spell(&call_parameters) {
88+
// We want to prevent anyone except this spell to store errors to its kv
89+
if !is_by_creator() || !is_by_spell(&call_parameters) {
8990
return UnitValue::error("store_error can be called only by the associated spell script");
9091
}
9192

@@ -218,7 +219,7 @@ mod tests {
218219
fn cp(service_id: String, particle_id: String) -> CallParameters {
219220
CallParameters {
220221
init_peer_id: "folex".to_string(),
221-
service_creator_peer_id: "not folex".to_string(),
222+
service_creator_peer_id: "folex".to_string(),
222223
service_id,
223224
host_id: "".to_string(),
224225
particle_id,

src/spell/modules/spell/spell/src/script.rs

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::fs::OpenOptions;
2-
use std::io;
32
use std::io::Write;
43

54
use marine_rs_sdk::marine;
@@ -24,17 +23,19 @@ pub fn set_script_source_to_file(script: String) -> UnitValue {
2423
return UnitValue::error("Only owner of the service can set the script");
2524
}
2625

26+
// open file for writing, overwrite if exists, create if not exists
2727
let write = OpenOptions::new()
28-
.create_new(true)
28+
// create file if it doesn't exist
29+
.create(true)
30+
// remove all contents of the file if it exists
31+
.truncate(true)
32+
// grant writing permissions
2933
.write(true)
3034
.open(SCRIPT_FILE)
3135
.map(|mut f| f.write_all(script.as_bytes()));
3236

3337
match write {
3438
Ok(_) => UnitValue::ok(),
35-
Err(e) if e.kind() == io::ErrorKind::AlreadyExists => {
36-
UnitValue::error("Script can be set only once, and it was already set")
37-
}
3839
Err(e) => UnitValue::error(format!("Error writing script to {}: {}", SCRIPT_FILE, e)),
3940
}
4041
}
@@ -100,8 +101,8 @@ pub fn script_cid() -> CIDValue {
100101
#[test_env_helpers::after_each]
101102
#[cfg(test)]
102103
mod tests {
103-
use marine_rs_sdk_test::marine_test;
104104
use marine_rs_sdk_test::CallParameters;
105+
use marine_rs_sdk_test::marine_test;
105106

106107
use crate::schema::DB_FILE;
107108

@@ -143,14 +144,52 @@ mod tests {
143144
);
144145
let second_set = spell.set_script_source_to_file("(seq (null) (null))".to_string());
145146
assert!(
146-
!second_set.success,
147-
"set_script_source_to_file returned true expected false"
148-
);
149-
assert_eq!(
150-
second_set.error,
151-
"Script can be set only once, and it was already set"
147+
second_set.success,
148+
"set_script_source_to_file returned false (fail), expected true (success)"
152149
);
153-
assert_eq!(spell.get_script_source_from_file().source_code, "(null)");
150+
assert_eq!(spell.get_script_source_from_file().source_code, "(seq (null) (null))");
151+
}
152+
153+
#[marine_test(
154+
config_path = "../tests_artifacts/Config.toml",
155+
modules_dir = "../tests_artifacts"
156+
)]
157+
fn test_set_script_by_spell(spell: marine_test_env::spell::ModuleInterface) {
158+
let service_id = uuid::Uuid::new_v4();
159+
let particle_id = format!("spell_{}_123", service_id);
160+
161+
let cp = CallParameters {
162+
init_peer_id: "folex".to_string(),
163+
service_creator_peer_id: "folex".to_string(),
164+
service_id: service_id.to_string(),
165+
host_id: "".to_string(),
166+
particle_id: particle_id,
167+
tetraplets: vec![],
168+
};
169+
170+
let set = spell.set_script_source_to_file_cp("(null)".to_string(), cp);
171+
172+
assert!(set.success, "set script failed: {}", set.error);
173+
}
174+
175+
#[marine_test(
176+
config_path = "../tests_artifacts/Config.toml",
177+
modules_dir = "../tests_artifacts"
178+
)]
179+
fn test_set_script_by_third_party(spell: marine_test_env::spell::ModuleInterface) {
180+
let cp = CallParameters {
181+
init_peer_id: "definitely not folex".to_string(),
182+
service_creator_peer_id: "folex".to_string(),
183+
service_id: "spell_service_id".to_string(),
184+
host_id: "".to_string(),
185+
particle_id: "some_particle_id_from_somewhere".to_string(),
186+
tetraplets: vec![],
187+
};
188+
189+
let set = spell.set_script_source_to_file_cp("(null)".to_string(), cp);
190+
191+
assert!(!set.success, "set script succeeded while shouldn't");
192+
assert_eq!(set.error, "Only owner of the service can set the script");
154193
}
155194

156195
#[marine_test(

src/spell/modules/spell/spell/test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ cp ../target/wasm32-wasi/release/spell.wasm tests_artifacts/
1414

1515
if [[ ! -f "tests_artifacts/sqlite3.wasm" ]]; then
1616
# download SQLite 3
17-
curl -L https://github.com/fluencelabs/sqlite/releases/download/v0.18.0_w/sqlite3.wasm -o tests_artifacts/sqlite3.wasm
17+
curl -L https://github.com/fluencelabs/sqlite/releases/download/sqlite-wasm-v0.18.1/sqlite3.wasm -o tests_artifacts/sqlite3.wasm
1818
fi
1919

2020
# run tests

0 commit comments

Comments
 (0)