Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions linera-execution/src/execution_state_actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,22 @@ where
.to_round()?;
callback.respond(validation_round);
}

TotalStorageSize {
application,
callback,
} => {
let view = self.state.users.try_load_entry(&application).await?;
let result = match view {
Some(view) => {
let total_size = view.total_size();
(total_size.key, total_size.value)
}
None => (0, 0),
};
tracing::info!("TotalStorageSize, result={result:?}");
callback.respond(result);
}
}

Ok(())
Expand Down Expand Up @@ -1206,4 +1222,10 @@ pub enum ExecutionRequest {
#[debug(skip)]
callback: Sender<Option<u32>>,
},

TotalStorageSize {
application: ApplicationId,
#[debug(skip)]
callback: Sender<(u32, u32)>,
},
}
4 changes: 4 additions & 0 deletions linera-execution/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -663,9 +663,10 @@

/// Reads a data blob specified by a given hash.
fn read_data_blob(&mut self, hash: DataBlobHash) -> Result<Vec<u8>, ExecutionError>;

Check warning on line 666 in linera-execution/src/lib.rs

View workflow job for this annotation

GitHub Actions / lint-cargo-fmt

Diff in /home/runner/work/linera-protocol/linera-protocol/linera-execution/src/lib.rs
/// Asserts the existence of a data blob with the given hash.
fn assert_data_blob_exists(&mut self, hash: DataBlobHash) -> Result<(), ExecutionError>;

}

pub trait ServiceRuntime: BaseRuntime {
Expand Down Expand Up @@ -813,6 +814,9 @@

/// Writes a batch of changes.
fn write_batch(&mut self, batch: Batch) -> Result<(), ExecutionError>;

/// Returns true if the corresponding contract uses a zero amount of storage.
fn has_trivial_storage(&mut self, application: ApplicationId) -> Result<bool, ExecutionError>;
}

/// An operation to be executed in a block.
Expand Down
13 changes: 13 additions & 0 deletions linera-execution/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -894,9 +894,10 @@
let this = self.inner();
let blob_id = hash.into();
this.execution_state_sender
.send_request(|callback| ExecutionRequest::AssertBlobExists { blob_id, callback })?

Check warning on line 897 in linera-execution/src/runtime.rs

View workflow job for this annotation

GitHub Actions / lint-cargo-fmt

Diff in /home/runner/work/linera-protocol/linera-protocol/linera-execution/src/runtime.rs
.recv_response()
}

}

/// An extension trait to determine in compile time the different behaviors between contract and
Expand Down Expand Up @@ -1535,6 +1536,18 @@
.recv_response()?;
Ok(())
}

fn has_trivial_storage(&mut self, application: ApplicationId) -> Result<bool, ExecutionError> {
let this = self.inner();
let (key_size, value_size) = this
.execution_state_sender
.send_request(move |callback| ExecutionRequest::TotalStorageSize {
application,
callback,
})?
.recv_response()?;
Ok(key_size + value_size == 0)
}
}

impl ServiceSyncRuntime {
Expand Down
12 changes: 12 additions & 0 deletions linera-execution/src/wasm/runtime_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,18 @@ where
.write_batch(Batch { operations })
.map_err(|error| RuntimeError::Custom(error.into()))
}

/// Returns true if the corresponding contract uses a zero amount of storage.
fn has_trivial_storage(
caller: &mut Caller,
application: ApplicationId,
) -> Result<bool, RuntimeError> {
caller
.user_data_mut()
.runtime
.has_trivial_storage(application)
.map_err(|error| RuntimeError::Custom(error.into()))
}
}

/// An implementation of the system API made available to services.
Expand Down
5 changes: 5 additions & 0 deletions linera-sdk/src/contract/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ where
pub fn assert_data_blob_exists(&mut self, hash: DataBlobHash) {
base_wit::assert_data_blob_exists(hash.into())
}

/// Returns true if the corresponding contract uses a zero amount of storage.
pub fn has_trivial_storage(&mut self, application: ApplicationId) -> bool {
contract_wit::has_trivial_storage(application.into())
}
}

impl<Application> ContractRuntime<Application>
Expand Down
21 changes: 21 additions & 0 deletions linera-sdk/src/contract/test_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ where
expected_http_requests: VecDeque<(http::Request, http::Response)>,
expected_read_data_blob_requests: VecDeque<(DataBlobHash, Vec<u8>)>,
expected_assert_data_blob_exists_requests: VecDeque<(DataBlobHash, Option<()>)>,
expected_has_trivial_storage_requests: VecDeque<(ApplicationId, bool)>,
expected_open_chain_calls: VecDeque<(ChainOwnership, ApplicationPermissions, Amount, ChainId)>,
expected_publish_module_calls: VecDeque<ExpectedPublishModuleCall>,
expected_create_application_calls: VecDeque<ExpectedCreateApplicationCall>,
Expand Down Expand Up @@ -127,6 +128,7 @@ where
expected_http_requests: VecDeque::new(),
expected_read_data_blob_requests: VecDeque::new(),
expected_assert_data_blob_exists_requests: VecDeque::new(),
expected_has_trivial_storage_requests: VecDeque::new(),
expected_open_chain_calls: VecDeque::new(),
expected_publish_module_calls: VecDeque::new(),
expected_create_application_calls: VecDeque::new(),
Expand Down Expand Up @@ -936,6 +938,16 @@ where
.push_back((hash, response));
}

/// Adds an expected `has_trivial_storage` call, and the response it should return in the test.
pub fn add_expected_has_trivial_storage_requests(
&mut self,
application: ApplicationId,
response: bool,
) {
self.expected_has_trivial_storage_requests
.push_back((application, response));
}

/// Queries an application service as an oracle and returns the response.
///
/// Should only be used with queries where it is very likely that all validators will compute
Expand Down Expand Up @@ -997,6 +1009,15 @@ where
response.expect("Blob does not exist!");
}

/// Returns true if the corresponding contract uses a zero amount of storage.
pub fn has_trivial_storage(&mut self, application: ApplicationId) -> bool {
let maybe_request = self.expected_has_trivial_storage_requests.pop_front();
let (expected_application_id, response) =
maybe_request.expect("Unexpected has_trivial_storage request");
assert_eq!(application, expected_application_id);
response
}

/// Returns the round in which this block was validated.
pub fn validation_round(&mut self) -> Option<u32> {
self.round
Expand Down
1 change: 1 addition & 0 deletions linera-sdk/src/service/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,10 @@
}

/// Asserts that a data blob with the given hash exists in storage.
pub fn assert_data_blob_exists(&self, hash: DataBlobHash) {

Check warning on line 159 in linera-sdk/src/service/runtime.rs

View workflow job for this annotation

GitHub Actions / lint-cargo-fmt

Diff in /home/runner/work/linera-protocol/linera-protocol/linera-sdk/src/service/runtime.rs
base_wit::assert_data_blob_exists(hash.into())
}

}

impl<Application> ServiceRuntime<Application>
Expand Down
1 change: 1 addition & 0 deletions linera-sdk/wit/contract-runtime-api.wit
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ interface contract-runtime-api {
consume-fuel: func(fuel: u64);
validation-round: func() -> option<u32>;
write-batch: func(operations: list<write-operation>);
has-trivial-storage: func(application: application-id) -> bool;

record account {
chain-id: chain-id,
Expand Down
3 changes: 2 additions & 1 deletion linera-views/src/views/key_value_store_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,11 +393,12 @@
/// # tokio_test::block_on(async {
/// # use linera_views::context::MemoryContext;
/// # use linera_views::key_value_store_view::{KeyValueStoreView, SizeData};
/// # use linera_views::views::View;

Check warning on line 396 in linera-views/src/views/key_value_store_view.rs

View workflow job for this annotation

GitHub Actions / lint-cargo-fmt

Diff in /home/runner/work/linera-protocol/linera-protocol/linera-views/src/views/key_value_store_view.rs
/// # let context = MemoryContext::new_for_testing(());
/// let mut view = KeyValueStoreView::load(context).await.unwrap();
/// view.insert(vec![0, 1], vec![0,1,2,3,4]).await.unwrap();
/// let total_size = view.total_size();
/// assert_eq!(total_size, SizeData::default());
/// assert_eq!(total_size, SizeData { key: 2, value: 5});
/// # })
/// ```
pub fn total_size(&self) -> SizeData {
Expand Down
Loading