diff --git a/examples/non-fungible/README.md b/examples/non-fungible/README.md index ed46a05c9f4c..f66305bbfa44 100644 --- a/examples/non-fungible/README.md +++ b/examples/non-fungible/README.md @@ -104,10 +104,7 @@ linera service --port $PORT & mint( minter: "User:7136460f0c87ae46f966f898d494c4b40c4ae8c527f4d1c0b1fa0f7cff91d20f", name: "nft1", - blobId: { - hash: "34a20da0fdd7e24ddbff60cb7f952b053b3f0e196e622d47c3a368f690f01326", - blob_type: "Data" - } + blobHash: "34a20da0fdd7e24ddbff60cb7f952b053b3f0e196e622d47c3a368f690f01326", ) } ``` diff --git a/examples/non-fungible/src/contract.rs b/examples/non-fungible/src/contract.rs index af558e0144d3..2d3b6efd2c98 100644 --- a/examples/non-fungible/src/contract.rs +++ b/examples/non-fungible/src/contract.rs @@ -9,7 +9,7 @@ use std::collections::BTreeSet; use fungible::Account; use linera_sdk::{ - base::{AccountOwner, BlobId, WithContractAbi}, + base::{AccountOwner, CryptoHash, WithContractAbi}, views::{RootView, View, ViewStorageContext}, Contract, ContractRuntime, }; @@ -51,10 +51,10 @@ impl Contract for NonFungibleTokenContract { Operation::Mint { minter, name, - blob_id, + blob_hash, } => { self.check_account_authentication(minter); - self.mint(minter, name, blob_id).await; + self.mint(minter, name, blob_hash).await; } Operation::Transfer { @@ -176,14 +176,14 @@ impl NonFungibleTokenContract { .expect("NFT {token_id} not found") } - async fn mint(&mut self, owner: AccountOwner, name: String, blob_id: BlobId) { - self.runtime.assert_blob_exists(blob_id); + async fn mint(&mut self, owner: AccountOwner, name: String, blob_hash: CryptoHash) { + self.runtime.assert_data_blob_exists(blob_hash); let token_id = Nft::create_token_id( &self.runtime.chain_id(), &self.runtime.application_id().forget_abi(), &name, &owner, - &blob_id, + &blob_hash, *self.state.num_minted_nfts.get(), ) .expect("Failed to serialize NFT metadata"); @@ -193,7 +193,7 @@ impl NonFungibleTokenContract { owner, name, minter: owner, - blob_id, + blob_hash, }) .await; diff --git a/examples/non-fungible/src/lib.rs b/examples/non-fungible/src/lib.rs index a59febfed711..209cf50bbd47 100644 --- a/examples/non-fungible/src/lib.rs +++ b/examples/non-fungible/src/lib.rs @@ -108,10 +108,7 @@ linera service --port $PORT & mint( minter: "User:7136460f0c87ae46f966f898d494c4b40c4ae8c527f4d1c0b1fa0f7cff91d20f", name: "nft1", - blobId: { - hash: "34a20da0fdd7e24ddbff60cb7f952b053b3f0e196e622d47c3a368f690f01326", - blob_type: "Data" - } + blobHash: "34a20da0fdd7e24ddbff60cb7f952b053b3f0e196e622d47c3a368f690f01326", ) } ``` @@ -182,7 +179,7 @@ use std::fmt::{Display, Formatter}; use async_graphql::{InputObject, Request, Response, SimpleObject}; use fungible::Account; use linera_sdk::{ - base::{AccountOwner, ApplicationId, BlobId, ChainId, ContractAbi, ServiceAbi}, + base::{AccountOwner, ApplicationId, ChainId, ContractAbi, CryptoHash, ServiceAbi}, graphql::GraphQLMutationRoot, ToBcsBytes, }; @@ -215,7 +212,7 @@ pub enum Operation { Mint { minter: AccountOwner, name: String, - blob_id: BlobId, + blob_hash: CryptoHash, }, /// Transfers a token from a (locally owned) account to a (possibly remote) account. Transfer { @@ -255,7 +252,7 @@ pub struct Nft { pub owner: AccountOwner, pub name: String, pub minter: AccountOwner, - pub blob_id: BlobId, + pub blob_hash: CryptoHash, } #[derive(Debug, Serialize, Deserialize, Clone, SimpleObject, PartialEq, Eq)] @@ -304,7 +301,7 @@ impl Nft { application_id: &ApplicationId, name: &String, minter: &AccountOwner, - blob_id: &BlobId, + blob_hash: &CryptoHash, num_minted_nfts: u64, ) -> Result { use sha3::Digest as _; @@ -315,7 +312,7 @@ impl Nft { hasher.update(name); hasher.update(name.len().to_bcs_bytes()?); hasher.update(minter.to_bcs_bytes()?); - hasher.update(blob_id.to_bcs_bytes()?); + hasher.update(blob_hash.to_bcs_bytes()?); hasher.update(num_minted_nfts.to_bcs_bytes()?); Ok(TokenId { diff --git a/examples/non-fungible/src/service.rs b/examples/non-fungible/src/service.rs index 2f16549900e3..ce898bf5b22a 100644 --- a/examples/non-fungible/src/service.rs +++ b/examples/non-fungible/src/service.rs @@ -14,7 +14,7 @@ use async_graphql::{EmptySubscription, Object, Request, Response, Schema}; use base64::engine::{general_purpose::STANDARD_NO_PAD, Engine as _}; use fungible::Account; use linera_sdk::{ - base::{AccountOwner, BlobId, WithServiceAbi}, + base::{AccountOwner, CryptoHash, WithServiceAbi}, views::{View, ViewStorageContext}, Service, ServiceRuntime, }; @@ -82,7 +82,7 @@ impl QueryRoot { .runtime .try_lock() .expect("Services only run in a single thread"); - runtime.read_blob(nft.blob_id).into_inner().bytes + runtime.read_data_blob(nft.blob_hash) }; let nft_output = NftOutput::new_with_token_id(token_id, nft, payload); Some(nft_output) @@ -101,7 +101,7 @@ impl QueryRoot { .runtime .try_lock() .expect("Services only run in a single thread"); - runtime.read_blob(nft.blob_id).into_inner().bytes + runtime.read_data_blob(nft.blob_hash) }; let nft_output = NftOutput::new(nft, payload); nfts.insert(nft_output.token_id.clone(), nft_output); @@ -166,7 +166,7 @@ impl QueryRoot { .runtime .try_lock() .expect("Services only run in a single thread"); - runtime.read_blob(nft.blob_id).into_inner().bytes + runtime.read_data_blob(nft.blob_hash) }; let nft_output = NftOutput::new(nft, payload); result.insert(nft_output.token_id.clone(), nft_output); @@ -180,11 +180,11 @@ struct MutationRoot; #[Object] impl MutationRoot { - async fn mint(&self, minter: AccountOwner, name: String, blob_id: BlobId) -> Vec { + async fn mint(&self, minter: AccountOwner, name: String, blob_hash: CryptoHash) -> Vec { bcs::to_bytes(&Operation::Mint { minter, name, - blob_id, + blob_hash, }) .unwrap() } diff --git a/examples/non-fungible/web-frontend/src/App.js b/examples/non-fungible/web-frontend/src/App.js index f62d42653659..066ad18f7f64 100644 --- a/examples/non-fungible/web-frontend/src/App.js +++ b/examples/non-fungible/web-frontend/src/App.js @@ -33,8 +33,12 @@ const GET_OWNED_NFTS = gql` `; const MINT_NFT = gql` - mutation Mint($minter: AccountOwner!, $name: String!, $blobId: BlobId!) { - mint(minter: $minter, name: $name, blobId: $blobId) + mutation Mint( + $minter: AccountOwner! + $name: String! + $blobHash: CryptoHash! + ) { + mint(minter: $minter, name: $name, blobHash: $blobHash) } `; @@ -183,24 +187,28 @@ function App({ chainId, owner }) { variables: { chainId: chainId, blobContent: { - bytes: Array.from(byteArrayFile) + bytes: Array.from(byteArrayFile), }, }, }).then((r) => { if ('errors' in r) { - console.log('Got error while publishing Data Blob: ' + JSON.stringify(r, null, 2)); + console.log( + 'Got error while publishing Data Blob: ' + JSON.stringify(r, null, 2) + ); } else { console.log('Data Blob published: ' + JSON.stringify(r, null, 2)); - const blobId = r['data']['publishDataBlob']; + const blobHash = r['data']['publishDataBlob']['hash']; mintNft({ variables: { minter: `User:${owner}`, name: name, - blobId: blobId, + blobHash: blobHash, }, }).then((r) => { if ('errors' in r) { - console.log('Got error while minting NFT: ' + JSON.stringify(r, null, 2)); + console.log( + 'Got error while minting NFT: ' + JSON.stringify(r, null, 2) + ); } else { console.log('NFT minted: ' + JSON.stringify(r, null, 2)); } @@ -229,7 +237,9 @@ function App({ chainId, owner }) { }, }).then((r) => { if ('errors' in r) { - console.log('Error while transferring NFT: ' + JSON.stringify(r, null, 2)); + console.log( + 'Error while transferring NFT: ' + JSON.stringify(r, null, 2) + ); } else { console.log('NFT transferred: ' + JSON.stringify(r, null, 2)); } diff --git a/linera-base/src/identifiers.rs b/linera-base/src/identifiers.rs index a45c2441840f..d24cd77627b1 100644 --- a/linera-base/src/identifiers.rs +++ b/linera-base/src/identifiers.rs @@ -211,8 +211,13 @@ pub struct BlobId { impl BlobId { /// Creates a new `BlobId` from a `BlobContent` pub fn new_data(blob_content: &BlobContent) -> Self { + Self::new_data_from_hash(CryptoHash::new(blob_content)) + } + + /// Creates a new `BlobId` from a hash + pub fn new_data_from_hash(hash: CryptoHash) -> Self { BlobId { - hash: CryptoHash::new(blob_content), + hash, blob_type: BlobType::Data, } } diff --git a/linera-execution/src/lib.rs b/linera-execution/src/lib.rs index 5e932b91b899..f77aa20f2649 100644 --- a/linera-execution/src/lib.rs +++ b/linera-execution/src/lib.rs @@ -31,7 +31,7 @@ use linera_base::{ abi::Abi, crypto::CryptoHash, data_types::{ - Amount, ApplicationPermissions, ArithmeticError, Blob, BlobContent, BlockHeight, Resources, + Amount, ApplicationPermissions, ArithmeticError, Blob, BlockHeight, Resources, SendMessageRequest, Timestamp, }, doc_scalar, hex_debug, @@ -257,7 +257,7 @@ pub trait ExecutionRuntimeContext { description: &UserApplicationDescription, ) -> Result; - async fn get_blob(&self, blob_id: BlobId) -> Result; + async fn get_data_blob(&self, blob_id: BlobId) -> Result; async fn contains_blob(&self, blob_id: BlobId) -> Result; } @@ -492,11 +492,11 @@ pub trait BaseRuntime { /// owner, not a super owner. fn assert_before(&mut self, timestamp: Timestamp) -> Result<(), ExecutionError>; - /// Reads a blob content specified by a given `BlobId`. - fn read_blob_content(&mut self, blob_id: &BlobId) -> Result; + /// Reads a data blob content specified by a given hash. + fn read_data_blob(&mut self, hash: &CryptoHash) -> Result, ExecutionError>; - /// Asserts the existence of a blob with the given `BlobId`. - fn assert_blob_exists(&mut self, blob_id: &BlobId) -> Result<(), ExecutionError>; + /// Asserts the existence of a data blob with the given hash. + fn assert_data_blob_exists(&mut self, hash: &CryptoHash) -> Result<(), ExecutionError>; } pub trait ServiceRuntime: BaseRuntime { @@ -918,7 +918,7 @@ impl ExecutionRuntimeContext for TestExecutionRuntimeContext { .clone()) } - async fn get_blob(&self, blob_id: BlobId) -> Result { + async fn get_data_blob(&self, blob_id: BlobId) -> Result { Ok(self .blobs .get(&blob_id) diff --git a/linera-execution/src/runtime.rs b/linera-execution/src/runtime.rs index 639f538ee2ce..72cb716b9c43 100644 --- a/linera-execution/src/runtime.rs +++ b/linera-execution/src/runtime.rs @@ -11,9 +11,10 @@ use std::{ use custom_debug_derive::Debug; use linera_base::{ + crypto::CryptoHash, data_types::{ - Amount, ApplicationPermissions, ArithmeticError, BlobContent, BlockHeight, OracleResponse, - Resources, SendMessageRequest, Timestamp, + Amount, ApplicationPermissions, ArithmeticError, BlockHeight, OracleResponse, Resources, + SendMessageRequest, Timestamp, }, ensure, identifiers::{ @@ -712,12 +713,12 @@ impl BaseRuntime for SyncRuntimeHandle { self.inner().assert_before(timestamp) } - fn read_blob_content(&mut self, blob_id: &BlobId) -> Result { - self.inner().read_blob_content(blob_id) + fn read_data_blob(&mut self, hash: &CryptoHash) -> Result, ExecutionError> { + self.inner().read_data_blob(hash) } - fn assert_blob_exists(&mut self, blob_id: &BlobId) -> Result<(), ExecutionError> { - self.inner().assert_blob_exists(blob_id) + fn assert_data_blob_exists(&mut self, hash: &CryptoHash) -> Result<(), ExecutionError> { + self.inner().assert_data_blob_exists(hash) } } @@ -1017,42 +1018,38 @@ impl BaseRuntime for SyncRuntimeInternal { Ok(()) } - fn read_blob_content(&mut self, blob_id: &BlobId) -> Result { + fn read_data_blob(&mut self, hash: &CryptoHash) -> Result, ExecutionError> { + let blob_id = BlobId::new_data_from_hash(*hash); if let Some(responses) = &mut self.replaying_oracle_responses { match responses.next() { - Some(OracleResponse::Blob(oracle_blob_id)) if oracle_blob_id == *blob_id => {} + Some(OracleResponse::Blob(oracle_blob_id)) if oracle_blob_id == blob_id => {} Some(_) => return Err(ExecutionError::OracleResponseMismatch), None => return Err(ExecutionError::MissingOracleResponse), } } let blob_content = self .execution_state_sender - .send_request(|callback| ExecutionRequest::ReadBlobContent { - blob_id: *blob_id, - callback, - })? + .send_request(|callback| ExecutionRequest::ReadBlobContent { blob_id, callback })? .recv_response()?; self.recorded_oracle_responses - .push(OracleResponse::Blob(*blob_id)); - Ok(blob_content) + .push(OracleResponse::Blob(blob_id)); + Ok(blob_content.bytes) } - fn assert_blob_exists(&mut self, blob_id: &BlobId) -> Result<(), ExecutionError> { + fn assert_data_blob_exists(&mut self, hash: &CryptoHash) -> Result<(), ExecutionError> { + let blob_id = BlobId::new_data_from_hash(*hash); if let Some(responses) = &mut self.replaying_oracle_responses { match responses.next() { - Some(OracleResponse::Blob(oracle_blob_id)) if oracle_blob_id == *blob_id => {} + Some(OracleResponse::Blob(oracle_blob_id)) if oracle_blob_id == blob_id => {} Some(_) => return Err(ExecutionError::OracleResponseMismatch), None => return Err(ExecutionError::MissingOracleResponse), } } self.execution_state_sender - .send_request(|callback| ExecutionRequest::AssertBlobExists { - blob_id: *blob_id, - callback, - })? + .send_request(|callback| ExecutionRequest::AssertBlobExists { blob_id, callback })? .recv_response()?; self.recorded_oracle_responses - .push(OracleResponse::Blob(*blob_id)); + .push(OracleResponse::Blob(blob_id)); Ok(()) } } diff --git a/linera-execution/src/system.rs b/linera-execution/src/system.rs index 1beb5034557f..0c7f01660a87 100644 --- a/linera-execution/src/system.rs +++ b/linera-execution/src/system.rs @@ -1084,7 +1084,7 @@ where ) -> Result { self.context() .extra() - .get_blob(blob_id) + .get_data_blob(blob_id) .await .map_err(|_| SystemExecutionError::BlobNotFoundOnRead(blob_id)) .map(Into::into) diff --git a/linera-execution/src/wasm/system_api.rs b/linera-execution/src/wasm/system_api.rs index 4e5742e753a4..b9828c07257f 100644 --- a/linera-execution/src/wasm/system_api.rs +++ b/linera-execution/src/wasm/system_api.rs @@ -4,12 +4,9 @@ use std::{any::Any, collections::HashMap, marker::PhantomData}; use linera_base::{ - data_types::{ - Amount, ApplicationPermissions, BlobContent, BlockHeight, SendMessageRequest, Timestamp, - }, - identifiers::{ - Account, ApplicationId, BlobId, ChainId, ChannelName, MessageId, Owner, StreamName, - }, + crypto::CryptoHash, + data_types::{Amount, ApplicationPermissions, BlockHeight, SendMessageRequest, Timestamp}, + identifiers::{Account, ApplicationId, ChainId, ChannelName, MessageId, Owner, StreamName}, ownership::{ChainOwnership, CloseChainError}, }; use linera_views::batch::{Batch, WriteOperation}; @@ -356,24 +353,21 @@ where .map_err(|error| RuntimeError::Custom(error.into())) } - /// Reads a blob content from storage. - fn read_blob_content( - caller: &mut Caller, - blob_id: BlobId, - ) -> Result { + /// Reads a data blob from storage. + fn read_data_blob(caller: &mut Caller, hash: CryptoHash) -> Result, RuntimeError> { caller .user_data_mut() .runtime - .read_blob_content(&blob_id) + .read_data_blob(&hash) .map_err(|error| RuntimeError::Custom(error.into())) } - /// Asserts the existence of a blob with the given `BlobId`. - fn assert_blob_exists(caller: &mut Caller, blob_id: BlobId) -> Result<(), RuntimeError> { + /// Asserts the existence of a data blob with the given hash. + fn assert_data_blob_exists(caller: &mut Caller, hash: CryptoHash) -> Result<(), RuntimeError> { caller .user_data_mut() .runtime - .assert_blob_exists(&blob_id) + .assert_data_blob_exists(&hash) .map_err(|error| RuntimeError::Custom(error.into())) } @@ -542,24 +536,21 @@ where .map_err(|error| RuntimeError::Custom(error.into())) } - /// Reads a blob content from storage. - fn read_blob_content( - caller: &mut Caller, - blob_id: BlobId, - ) -> Result { + /// Reads a data blob from storage. + fn read_data_blob(caller: &mut Caller, hash: CryptoHash) -> Result, RuntimeError> { caller .user_data_mut() .runtime - .read_blob_content(&blob_id) + .read_data_blob(&hash) .map_err(|error| RuntimeError::Custom(error.into())) } - /// Asserts the existence of a blob with the given `BlobId`. - fn assert_blob_exists(caller: &mut Caller, blob_id: BlobId) -> Result<(), RuntimeError> { + /// Asserts the existence of a data blob with the given hash. + fn assert_data_blob_exists(caller: &mut Caller, hash: CryptoHash) -> Result<(), RuntimeError> { caller .user_data_mut() .runtime - .assert_blob_exists(&blob_id) + .assert_data_blob_exists(&hash) .map_err(|error| RuntimeError::Custom(error.into())) } diff --git a/linera-sdk/src/contract/conversions_from_wit.rs b/linera-sdk/src/contract/conversions_from_wit.rs index 385dc6d4ad12..57d4f7088b8d 100644 --- a/linera-sdk/src/contract/conversions_from_wit.rs +++ b/linera-sdk/src/contract/conversions_from_wit.rs @@ -5,8 +5,8 @@ use linera_base::{ crypto::{CryptoHash, PublicKey}, - data_types::{Amount, BlobContent, BlockHeight, TimeDelta, Timestamp}, - identifiers::{ApplicationId, BlobId, BlobType, BytecodeId, ChainId, MessageId, Owner}, + data_types::{Amount, BlockHeight, TimeDelta, Timestamp}, + identifiers::{ApplicationId, BytecodeId, ChainId, MessageId, Owner}, ownership::{ChainOwnership, CloseChainError, TimeoutConfig}, }; @@ -37,29 +37,6 @@ impl From for ApplicationId { } } -impl From for BlobId { - fn from(blob_id: wit_system_api::BlobId) -> Self { - Self { - hash: blob_id.hash.into(), - blob_type: blob_id.blob_type.into(), - } - } -} - -impl From for BlobType { - fn from(blob_type: wit_system_api::BlobType) -> Self { - match blob_type { - wit_system_api::BlobType::Data => BlobType::Data, - } - } -} - -impl From for BlobContent { - fn from(blob: wit_system_api::BlobContent) -> Self { - BlobContent { bytes: blob.bytes } - } -} - impl From for BytecodeId { fn from(bytecode_id: wit_system_api::BytecodeId) -> Self { BytecodeId::new(bytecode_id.message_id.into()) diff --git a/linera-sdk/src/contract/conversions_to_wit.rs b/linera-sdk/src/contract/conversions_to_wit.rs index 809ecd79ece8..5a5b18fcea42 100644 --- a/linera-sdk/src/contract/conversions_to_wit.rs +++ b/linera-sdk/src/contract/conversions_to_wit.rs @@ -10,8 +10,8 @@ use linera_base::{ Timestamp, }, identifiers::{ - Account, ApplicationId, BlobId, BlobType, BytecodeId, ChainId, ChannelName, Destination, - MessageId, Owner, StreamName, + Account, ApplicationId, BytecodeId, ChainId, ChannelName, Destination, MessageId, Owner, + StreamName, }, ownership::{ChainOwnership, TimeoutConfig}, }; @@ -45,23 +45,6 @@ impl From for wit_system_api::Owner { } } -impl From for wit_system_api::BlobId { - fn from(blob_id: BlobId) -> Self { - wit_system_api::BlobId { - hash: blob_id.hash.into(), - blob_type: blob_id.blob_type.into(), - } - } -} - -impl From for wit_system_api::BlobType { - fn from(blob_id: BlobType) -> Self { - match blob_id { - BlobType::Data => wit_system_api::BlobType::Data, - } - } -} - impl From for wit_system_api::Amount { fn from(host: Amount) -> Self { wit_system_api::Amount { diff --git a/linera-sdk/src/contract/runtime.rs b/linera-sdk/src/contract/runtime.rs index e5af9301060c..72ad1f844b23 100644 --- a/linera-sdk/src/contract/runtime.rs +++ b/linera-sdk/src/contract/runtime.rs @@ -5,13 +5,12 @@ use linera_base::{ abi::{ContractAbi, ServiceAbi}, + crypto::CryptoHash, data_types::{ - Amount, ApplicationPermissions, Blob, BlobContent, BlockHeight, Resources, - SendMessageRequest, Timestamp, + Amount, ApplicationPermissions, BlockHeight, Resources, SendMessageRequest, Timestamp, }, identifiers::{ - Account, ApplicationId, BlobId, ChainId, ChannelName, Destination, MessageId, Owner, - StreamName, + Account, ApplicationId, ChainId, ChannelName, Destination, MessageId, Owner, StreamName, }, ownership::{ChainOwnership, CloseChainError}, }; @@ -271,14 +270,14 @@ where wit::assert_before(timestamp.into()); } - /// Reads a blob with the given `BlobId` from storage. - pub fn read_blob(&mut self, blob_id: BlobId) -> Blob { - BlobContent::from(wit::read_blob_content(blob_id.into())).with_blob_id_unchecked(blob_id) + /// Reads a data blob with the given hash from storage. + pub fn read_data_blob(&mut self, hash: CryptoHash) -> Vec { + wit::read_data_blob(hash.into()) } - /// Asserts that a blob with the given `BlobId` exists in storage. - pub fn assert_blob_exists(&mut self, blob_id: BlobId) { - wit::assert_blob_exists(blob_id.into()) + /// Asserts that a data blob with the given hash exists in storage. + pub fn assert_data_blob_exists(&mut self, hash: CryptoHash) { + wit::assert_data_blob_exists(hash.into()) } } diff --git a/linera-sdk/src/contract/test_runtime.rs b/linera-sdk/src/contract/test_runtime.rs index 36b5c4dd58a3..4642cdcef916 100644 --- a/linera-sdk/src/contract/test_runtime.rs +++ b/linera-sdk/src/contract/test_runtime.rs @@ -10,10 +10,10 @@ use std::{ use linera_base::{ abi::{ContractAbi, ServiceAbi}, - data_types::{Amount, Blob, BlockHeight, Resources, SendMessageRequest, Timestamp}, + crypto::CryptoHash, + data_types::{Amount, BlockHeight, Resources, SendMessageRequest, Timestamp}, identifiers::{ - Account, ApplicationId, BlobId, ChainId, ChannelName, Destination, MessageId, Owner, - StreamName, + Account, ApplicationId, ChainId, ChannelName, Destination, MessageId, Owner, StreamName, }, ownership::{ChainOwnership, CloseChainError}, }; @@ -48,8 +48,8 @@ where claim_requests: Vec, expected_service_queries: VecDeque<(ApplicationId, String, String)>, expected_post_requests: VecDeque<(String, Vec, Vec)>, - expected_read_blob_requests: VecDeque<(BlobId, Blob)>, - expected_contains_blob_requests: VecDeque<(BlobId, Option<()>)>, + expected_read_blob_requests: VecDeque<(CryptoHash, Vec)>, + expected_assert_data_blob_exists_requests: VecDeque<(CryptoHash, Option<()>)>, key_value_store: KeyValueStore, } @@ -92,7 +92,7 @@ where expected_service_queries: VecDeque::new(), expected_post_requests: VecDeque::new(), expected_read_blob_requests: VecDeque::new(), - expected_contains_blob_requests: VecDeque::new(), + expected_assert_data_blob_exists_requests: VecDeque::new(), key_value_store: KeyValueStore::mock().to_mut(), } } @@ -616,15 +616,18 @@ where } /// Adds an expected `read_blob` call, and the response it should return in the test. - pub fn add_expected_read_blob_requests(&mut self, blob_id: BlobId, response: Blob) { - self.expected_read_blob_requests - .push_back((blob_id, response)); + pub fn add_expected_read_blob_requests(&mut self, hash: CryptoHash, response: Vec) { + self.expected_read_blob_requests.push_back((hash, response)); } - /// Adds an expected `contains_blob` call, and the response it should return in the test. - pub fn add_expected_contains_blob_requests(&mut self, blob_id: BlobId, response: Option<()>) { - self.expected_contains_blob_requests - .push_back((blob_id, response)); + /// Adds an expected `assert_data_blob_exists` call, and the response it should return in the test. + pub fn add_expected_assert_data_blob_exists_requests( + &mut self, + hash: CryptoHash, + response: Option<()>, + ) { + self.expected_assert_data_blob_exists_requests + .push_back((hash, response)); } /// Queries our application service as an oracle and returns the response. @@ -673,19 +676,20 @@ where assert!(self.timestamp.is_some_and(|t| t < timestamp)) } - /// Reads a blob with the given `BlobId` from storage. - pub fn read_blob(&mut self, blob_id: &BlobId) -> Blob { + /// Reads a data blob with the given hash from storage. + pub fn read_data_blob(&mut self, hash: &CryptoHash) -> Vec { let maybe_request = self.expected_read_blob_requests.pop_front(); - let (expected_blob_id, response) = maybe_request.expect("Unexpected read_blob request"); - assert_eq!(*blob_id, expected_blob_id); + let (expected_hash, response) = maybe_request.expect("Unexpected read_data_blob request"); + assert_eq!(*hash, expected_hash); response } - /// Asserts that a blob with the given `BlobId` exists in storage. - pub fn assert_blob_exists(&mut self, blob_id: BlobId) { - let maybe_request = self.expected_contains_blob_requests.pop_front(); - let (expected_blob_id, response) = maybe_request.expect("Unexpected contains_blob request"); - assert_eq!(blob_id, expected_blob_id); + /// Asserts that a blob with the given hash exists in storage. + pub fn assert_data_blob_exists(&mut self, hash: CryptoHash) { + let maybe_request = self.expected_assert_data_blob_exists_requests.pop_front(); + let (expected_blob_hash, response) = + maybe_request.expect("Unexpected assert_data_blob_exists request"); + assert_eq!(hash, expected_blob_hash); response.expect("Blob does not exist!"); } } diff --git a/linera-sdk/src/service/conversions_from_wit.rs b/linera-sdk/src/service/conversions_from_wit.rs index 8869500c9b8a..f4ebc1506d72 100644 --- a/linera-sdk/src/service/conversions_from_wit.rs +++ b/linera-sdk/src/service/conversions_from_wit.rs @@ -5,8 +5,8 @@ use linera_base::{ crypto::CryptoHash, - data_types::{Amount, BlobContent, BlockHeight, Timestamp}, - identifiers::{ApplicationId, BlobId, BlobType, BytecodeId, ChainId, MessageId, Owner}, + data_types::{Amount, BlockHeight, Timestamp}, + identifiers::{ApplicationId, BytecodeId, ChainId, MessageId, Owner}, }; use super::wit::service_system_api as wit_system_api; @@ -23,29 +23,6 @@ impl From for Owner { } } -impl From for BlobId { - fn from(blob_id: wit_system_api::BlobId) -> Self { - Self { - hash: blob_id.hash.into(), - blob_type: blob_id.blob_type.into(), - } - } -} - -impl From for BlobType { - fn from(blob_type: wit_system_api::BlobType) -> Self { - match blob_type { - wit_system_api::BlobType::Data => BlobType::Data, - } - } -} - -impl From for BlobContent { - fn from(blob: wit_system_api::BlobContent) -> Self { - BlobContent { bytes: blob.bytes } - } -} - impl From for Amount { fn from(balance: wit_system_api::Amount) -> Self { let (lower_half, upper_half) = balance.inner0; diff --git a/linera-sdk/src/service/conversions_to_wit.rs b/linera-sdk/src/service/conversions_to_wit.rs index 5c655a955303..7221077c06b9 100644 --- a/linera-sdk/src/service/conversions_to_wit.rs +++ b/linera-sdk/src/service/conversions_to_wit.rs @@ -6,7 +6,7 @@ use linera_base::{ crypto::CryptoHash, data_types::BlockHeight, - identifiers::{ApplicationId, BlobId, BlobType, BytecodeId, ChainId, MessageId, Owner}, + identifiers::{ApplicationId, BytecodeId, ChainId, MessageId, Owner}, }; use super::wit::service_system_api as wit_system_api; @@ -44,23 +44,6 @@ impl From for wit_system_api::Owner { } } -impl From for wit_system_api::BlobId { - fn from(blob_id: BlobId) -> Self { - wit_system_api::BlobId { - hash: blob_id.hash.into(), - blob_type: blob_id.blob_type.into(), - } - } -} - -impl From for wit_system_api::BlobType { - fn from(blob_type: BlobType) -> Self { - match blob_type { - BlobType::Data => wit_system_api::BlobType::Data, - } - } -} - impl From for wit_system_api::BlockHeight { fn from(block_height: BlockHeight) -> Self { wit_system_api::BlockHeight { diff --git a/linera-sdk/src/service/runtime.rs b/linera-sdk/src/service/runtime.rs index 16d37234d6e4..77951de26842 100644 --- a/linera-sdk/src/service/runtime.rs +++ b/linera-sdk/src/service/runtime.rs @@ -7,8 +7,9 @@ use std::cell::Cell; use linera_base::{ abi::ServiceAbi, - data_types::{Amount, Blob, BlobContent, BlockHeight, Timestamp}, - identifiers::{ApplicationId, BlobId, ChainId, Owner}, + crypto::CryptoHash, + data_types::{Amount, BlockHeight, Timestamp}, + identifiers::{ApplicationId, ChainId, Owner}, }; use super::wit::service_system_api as wit; @@ -145,13 +146,13 @@ where value } - /// Reads a blob with the given `BlobId` from storage. - pub fn read_blob(&mut self, blob_id: BlobId) -> Blob { - BlobContent::from(wit::read_blob_content(blob_id.into())).with_blob_id_unchecked(blob_id) + /// Reads a data blob with the given hash from storage. + pub fn read_data_blob(&mut self, hash: CryptoHash) -> Vec { + wit::read_data_blob(hash.into()) } - /// Asserts that a blob with the given `BlobId` exists in storage. - pub fn assert_blob_exists(&mut self, blob_id: BlobId) { - wit::assert_blob_exists(blob_id.into()) + /// Asserts that a data blob with the given hash exists in storage. + pub fn assert_data_blob_exists(&mut self, hash: CryptoHash) { + wit::assert_data_blob_exists(hash.into()) } } diff --git a/linera-sdk/src/service/test_runtime.rs b/linera-sdk/src/service/test_runtime.rs index 1e22575808d3..180cd75e1ea4 100644 --- a/linera-sdk/src/service/test_runtime.rs +++ b/linera-sdk/src/service/test_runtime.rs @@ -10,8 +10,9 @@ use std::{ use linera_base::{ abi::ServiceAbi, - data_types::{Amount, Blob, BlockHeight, Timestamp}, - identifiers::{ApplicationId, BlobId, ChainId, Owner}, + crypto::CryptoHash, + data_types::{Amount, BlockHeight, Timestamp}, + identifiers::{ApplicationId, ChainId, Owner}, }; use crate::{KeyValueStore, Service}; @@ -30,7 +31,7 @@ where owner_balances: RefCell>>, query_application_handler: RefCell>, url_blobs: RefCell>>>, - blobs: RefCell>>, + blobs: RefCell>>>, key_value_store: KeyValueStore, } @@ -359,56 +360,56 @@ where }) } - /// Configures the blobs returned when fetching from `BlobId`s during the test. - pub fn with_blobs(self, blobs: impl IntoIterator) -> Self { + /// Configures the blobs returned when fetching from hashes during the test. + pub fn with_blobs(self, blobs: impl IntoIterator)>) -> Self { *self.blobs.borrow_mut() = Some(blobs.into_iter().collect()); self } - /// Configures the blobs returned when fetching from `BlobId`s during the test. - pub fn set_blobs(&self, blobs: impl IntoIterator) -> &Self { + /// Configures the blobs returned when fetching from hashes during the test. + pub fn set_blobs(&self, blobs: impl IntoIterator)>) -> &Self { *self.blobs.borrow_mut() = Some(blobs.into_iter().collect()); self } /// Configures the `Blob` returned when fetching from the `BlobId` during the test. - pub fn with_blob(self, blob_id: impl Into, blob: Blob) -> Self { - self.set_blob(blob_id, blob); + pub fn with_blob(self, hash: impl Into, blob: Vec) -> Self { + self.set_blob(hash, blob); self } - /// Configures the `Blob` returned when fetching from the `BlobId` during the test. - pub fn set_blob(&self, blob_id: impl Into, blob: Blob) -> &Self { + /// Configures the blob returned when fetching from the hash during the test. + pub fn set_blob(&self, hash: impl Into, blob: Vec) -> &Self { self.blobs .borrow_mut() .get_or_insert_with(HashMap::new) - .insert(blob_id.into(), blob); + .insert(hash.into(), blob); self } - /// Fetches a `Blob` from a given `BlobId`. - pub fn read_blob(&mut self, blob_id: BlobId) -> Blob { + /// Fetches a blob from a given hash. + pub fn read_data_blob(&mut self, hash: CryptoHash) -> Vec { self.blobs .borrow() .as_ref() - .and_then(|blobs| blobs.get(&blob_id).cloned()) + .and_then(|blobs| blobs.get(&hash).cloned()) .unwrap_or_else(|| { panic!( - "Blob for BlobId {blob_id:?} has not been mocked, \ + "Blob for hash {hash:?} has not been mocked, \ please call `MockServiceRuntime::set_blob` first" ) }) } - /// Asserts that a blob with the given `BlobId` exists in storage. - pub fn assert_blob_exists(&mut self, blob_id: BlobId) { + /// Asserts that a blob with the given hash exists in storage. + pub fn assert_blob_exists(&mut self, hash: CryptoHash) { self.blobs .borrow() .as_ref() - .map(|blobs| blobs.contains_key(&blob_id)) + .map(|blobs| blobs.contains_key(&hash)) .unwrap_or_else(|| { panic!( - "Blob for BlobId {blob_id:?} has not been mocked, \ + "Blob for hash {hash:?} has not been mocked, \ please call `MockServiceRuntime::set_blob` first" ) }); diff --git a/linera-sdk/wit/contract-system-api.wit b/linera-sdk/wit/contract-system-api.wit index 6dc5cbc0868a..5fac034eac3a 100644 --- a/linera-sdk/wit/contract-system-api.wit +++ b/linera-sdk/wit/contract-system-api.wit @@ -25,8 +25,8 @@ interface contract-system-api { query-service: func(application-id: application-id, query: list) -> list; http-post: func(query: string, content-type: string, payload: list) -> list; assert-before: func(timestamp: timestamp); - read-blob-content: func(blob-id: blob-id) -> blob-content; - assert-blob-exists: func(blob-id: blob-id); + read-data-blob: func(hash: crypto-hash) -> list; + assert-data-blob-exists: func(hash: crypto-hash); log: func(message: string, level: log-level); consume-fuel: func(fuel: u64); @@ -50,19 +50,6 @@ interface contract-system-api { close-chain: list, } - record blob-content { - bytes: list, - } - - record blob-id { - hash: crypto-hash, - blob-type: blob-type, - } - - enum blob-type { - data, - } - record block-height { inner0: u64, } diff --git a/linera-sdk/wit/service-system-api.wit b/linera-sdk/wit/service-system-api.wit index abeae2d84e8b..1650961bc068 100644 --- a/linera-sdk/wit/service-system-api.wit +++ b/linera-sdk/wit/service-system-api.wit @@ -14,8 +14,8 @@ interface service-system-api { fetch-url: func(url: string) -> list; query-service: func(application-id: application-id, query: list) -> list; http-post: func(query: string, content-type: string, payload: list) -> list; - read-blob-content: func(blob-id: blob-id) -> blob-content; - assert-blob-exists: func(blob-id: blob-id); + read-data-blob: func(hash: crypto-hash) -> list; + assert-data-blob-exists: func(hash: crypto-hash); assert-before: func(timestamp: timestamp); log: func(message: string, level: log-level); @@ -28,19 +28,6 @@ interface service-system-api { creation: message-id, } - record blob-content { - bytes: list, - } - - record blob-id { - hash: crypto-hash, - blob-type: blob-type, - } - - enum blob-type { - data, - } - record block-height { inner0: u64, } diff --git a/linera-service/tests/end_to_end_tests.rs b/linera-service/tests/end_to_end_tests.rs index ba2e250b1806..b4f420aafd00 100644 --- a/linera-service/tests/end_to_end_tests.rs +++ b/linera-service/tests/end_to_end_tests.rs @@ -20,8 +20,9 @@ use common::INTEGRATION_TEST_GUARD; use futures::{channel::mpsc, SinkExt, StreamExt}; use linera_base::{ command::resolve_binary, + crypto::CryptoHash, data_types::{Amount, Blob}, - identifiers::{Account, AccountOwner, ApplicationId, BlobId, ChainId}, + identifiers::{Account, AccountOwner, ApplicationId, ChainId}, }; #[cfg(any( feature = "dynamodb", @@ -212,7 +213,7 @@ impl NonFungibleApp { application_id: &ApplicationId, name: &String, minter: &AccountOwner, - blob_id: &BlobId, + hash: &CryptoHash, num_minted_nfts: u64, ) -> String { use base64::engine::{general_purpose::STANDARD_NO_PAD, Engine as _}; @@ -221,7 +222,7 @@ impl NonFungibleApp { application_id, name, minter, - blob_id, + hash, num_minted_nfts, ) .expect("Creating token ID should not fail"); @@ -245,12 +246,12 @@ impl NonFungibleApp { )?) } - async fn mint(&self, minter: &AccountOwner, name: &String, blob_id: &BlobId) -> Value { + async fn mint(&self, minter: &AccountOwner, name: &String, blob_hash: &CryptoHash) -> Value { let mutation = format!( - "mint(minter: {}, name: {}, blobId: {})", + "mint(minter: {}, name: {}, blobHash: {})", minter.to_value(), name.to_value(), - blob_id.to_value(), + blob_hash.to_value(), ); self.0.mutate(mutation).await.unwrap() } @@ -1046,16 +1047,19 @@ async fn test_wasm_end_to_end_non_fungible(config: impl LineraNetConfig) -> Resu .await?; assert_eq!(nft1_blob_id, blob_id); + let nft1_blob_hash = nft1_blob_id.hash; + let nft1_id = NonFungibleApp::create_token_id( &chain1, &application_id.forget_abi(), &nft1_name, &nft1_minter, - &nft1_blob_id, + &nft1_blob_hash, 0, // No NFTs are supposed to have been minted yet in this chain ); - app1.mint(&account_owner1, &nft1_name, &nft1_blob_id).await; + app1.mint(&account_owner1, &nft1_name, &nft1_blob_hash) + .await; let mut expected_nft1 = NftOutput { token_id: nft1_id.clone(), @@ -1173,17 +1177,20 @@ async fn test_wasm_end_to_end_non_fungible(config: impl LineraNetConfig) -> Resu .await?; assert_eq!(nft2_blob_id, blob_id); + let nft2_blob_hash = nft2_blob_id.hash; + let nft2_id = NonFungibleApp::create_token_id( &chain2, &application_id.forget_abi(), &nft2_name, &nft2_minter, - &nft2_blob_id, + &nft2_blob_hash, 0, // No NFTs are supposed to have been minted yet in this chain ); // Minting NFT from chain2 - app2.mint(&account_owner2, &nft2_name, &nft2_blob_id).await; + app2.mint(&account_owner2, &nft2_name, &nft2_blob_hash) + .await; let expected_nft2 = NftOutput { token_id: nft2_id.clone(), diff --git a/linera-storage/src/lib.rs b/linera-storage/src/lib.rs index e0137f31506f..568d668910e7 100644 --- a/linera-storage/src/lib.rs +++ b/linera-storage/src/lib.rs @@ -470,7 +470,7 @@ where } } - async fn get_blob(&self, blob_id: BlobId) -> Result { + async fn get_data_blob(&self, blob_id: BlobId) -> Result { Ok(self.storage.read_blob(blob_id).await?) }