Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate types for UserApplicationId and ApplicationId. #3582

Closed
wants to merge 1 commit into from
Closed
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
4 changes: 2 additions & 2 deletions examples/gen-nft/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use async_graphql::{InputObject, Request, Response, SimpleObject};
use fungible::Account;
use linera_sdk::{
graphql::GraphQLMutationRoot,
linera_base_types::{AccountOwner, ApplicationId, ChainId, ContractAbi, ServiceAbi},
linera_base_types::{AccountOwner, ChainId, ContractAbi, ServiceAbi, UserApplicationId},
ToBcsBytes,
};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -122,7 +122,7 @@ impl Display for TokenId {
impl Nft {
pub fn create_token_id(
chain_id: &ChainId,
application_id: &ApplicationId,
application_id: &UserApplicationId,
prompt: &String,
minter: &AccountOwner,
num_minted_nfts: u64,
Expand Down
4 changes: 2 additions & 2 deletions examples/non-fungible/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use async_graphql::{InputObject, Request, Response, SimpleObject};
use fungible::Account;
use linera_sdk::{
graphql::GraphQLMutationRoot,
linera_base_types::{AccountOwner, ApplicationId, ChainId, ContractAbi, ServiceAbi},
linera_base_types::{AccountOwner, ChainId, ContractAbi, ServiceAbi, UserApplicationId},
DataBlobHash, ToBcsBytes,
};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -127,7 +127,7 @@ impl Display for TokenId {
impl Nft {
pub fn create_token_id(
chain_id: &ChainId,
application_id: &ApplicationId,
application_id: &UserApplicationId,
name: &String,
minter: &AccountOwner,
blob_hash: &DataBlobHash,
Expand Down
8 changes: 4 additions & 4 deletions examples/rfq/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use async_graphql::{scalar, InputObject, Request, Response, SimpleObject};
use fungible::Account;
use linera_sdk::{
graphql::GraphQLMutationRoot,
linera_base_types::{Amount, ApplicationId, ChainId, ContractAbi, Owner, ServiceAbi},
linera_base_types::{Amount, ChainId, ContractAbi, Owner, ServiceAbi, UserApplicationId},
};
use serde::{Deserialize, Serialize};

Expand All @@ -26,8 +26,8 @@ impl ServiceAbi for RfqAbi {
#[derive(Debug, Clone, Serialize, Deserialize, SimpleObject, InputObject)]
#[graphql(input_name = "TokenPairInput")]
pub struct TokenPair {
pub token_offered: ApplicationId,
pub token_asked: ApplicationId,
pub token_offered: UserApplicationId,
pub token_asked: UserApplicationId,
}

#[derive(Debug, Clone, Serialize, Deserialize, SimpleObject, InputObject)]
Expand Down Expand Up @@ -70,7 +70,7 @@ impl RequestId {
#[derive(Debug, Clone, Serialize, Deserialize, SimpleObject, InputObject)]
#[graphql(input_name = "TokensInput")]
pub struct Tokens {
pub token_id: ApplicationId,
pub token_id: UserApplicationId,
pub owner: Account,
pub amount: Amount,
}
Expand Down
28 changes: 14 additions & 14 deletions linera-base/src/data_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ use crate::{
crypto::{BcsHashable, CryptoHash},
doc_scalar, hex_debug, http,
identifiers::{
ApplicationId, BlobId, BlobType, ChainId, Destination, EventId, GenericApplicationId,
ModuleId, StreamId, UserApplicationId,
BlobId, BlobType, ChainId, Destination, EventId, GenericApplicationId, ModuleId, StreamId,
UserApplicationId,
},
limited_writer::{LimitedWriter, LimitedWriterError},
time::{Duration, SystemTime},
Expand Down Expand Up @@ -726,34 +726,34 @@ pub struct ApplicationPermissions {
/// If it is `Some`, only operations from the specified applications are allowed, and
/// no system operations.
#[debug(skip_if = Option::is_none)]
pub execute_operations: Option<Vec<ApplicationId>>,
pub execute_operations: Option<Vec<UserApplicationId>>,
/// At least one operation or incoming message from each of these applications must occur in
/// every block.
#[graphql(default)]
#[debug(skip_if = Vec::is_empty)]
pub mandatory_applications: Vec<ApplicationId>,
pub mandatory_applications: Vec<UserApplicationId>,
/// These applications are allowed to close the current chain using the system API.
#[graphql(default)]
#[debug(skip_if = Vec::is_empty)]
pub close_chain: Vec<ApplicationId>,
pub close_chain: Vec<UserApplicationId>,
/// These applications are allowed to change the application permissions using the system API.
#[graphql(default)]
#[debug(skip_if = Vec::is_empty)]
pub change_application_permissions: Vec<ApplicationId>,
pub change_application_permissions: Vec<UserApplicationId>,
/// These applications are allowed to perform calls to services as oracles.
#[graphql(default)]
#[debug(skip_if = Option::is_none)]
pub call_service_as_oracle: Option<Vec<ApplicationId>>,
pub call_service_as_oracle: Option<Vec<UserApplicationId>>,
/// These applications are allowed to perform HTTP requests.
#[graphql(default)]
#[debug(skip_if = Option::is_none)]
pub make_http_requests: Option<Vec<ApplicationId>>,
pub make_http_requests: Option<Vec<UserApplicationId>>,
}

impl ApplicationPermissions {
/// Creates new `ApplicationPermissions` where the given application is the only one
/// whose operations are allowed and mandatory, and it can also close the chain.
pub fn new_single(app_id: ApplicationId) -> Self {
pub fn new_single(app_id: UserApplicationId) -> Self {
Self {
execute_operations: Some(vec![app_id]),
mandatory_applications: vec![app_id],
Expand All @@ -774,26 +774,26 @@ impl ApplicationPermissions {
}

/// Returns whether the given application is allowed to close this chain.
pub fn can_close_chain(&self, app_id: &ApplicationId) -> bool {
pub fn can_close_chain(&self, app_id: &UserApplicationId) -> bool {
self.close_chain.contains(app_id)
}

/// Returns whether the given application is allowed to change the application
/// permissions for this chain.
pub fn can_change_application_permissions(&self, app_id: &ApplicationId) -> bool {
pub fn can_change_application_permissions(&self, app_id: &UserApplicationId) -> bool {
self.change_application_permissions.contains(app_id)
}

/// Returns whether the given application can call services.
pub fn can_call_services(&self, app_id: &ApplicationId) -> bool {
pub fn can_call_services(&self, app_id: &UserApplicationId) -> bool {
self.call_service_as_oracle
.as_ref()
.map(|app_ids| app_ids.contains(app_id))
.unwrap_or(true)
}

/// Returns whether the given application can make HTTP requests.
pub fn can_make_http_requests(&self, app_id: &ApplicationId) -> bool {
pub fn can_make_http_requests(&self, app_id: &UserApplicationId) -> bool {
self.make_http_requests
.as_ref()
.map(|app_ids| app_ids.contains(app_id))
Expand Down Expand Up @@ -845,7 +845,7 @@ pub struct UserApplicationDescription {

impl From<&UserApplicationDescription> for UserApplicationId {
fn from(description: &UserApplicationDescription) -> Self {
UserApplicationId::new(CryptoHash::new(&BlobContent::new_application_description(
UserApplicationId(CryptoHash::new(&BlobContent::new_application_description(
description,
)))
}
Expand Down
98 changes: 55 additions & 43 deletions linera-base/src/identifiers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,17 +294,55 @@ pub struct MessageId {
/// A unique identifier for a user application from a blob.
#[derive(Debug, WitLoad, WitStore, WitType)]
#[cfg_attr(with_testing, derive(Default, test_strategy::Arbitrary))]
pub struct ApplicationId<A = ()> {
pub struct ApplicationId<A> {
/// The hash of the `UserApplicationDescription` this refers to.
pub application_description_hash: CryptoHash,
#[witty(skip)]
#[debug(skip)]
_phantom: PhantomData<A>,
}

/// Alias for `ApplicationId`. Use this alias in the core
/// protocol where the distinction with the more general enum `GenericApplicationId` matters.
pub type UserApplicationId = ApplicationId<()>;
/// Use this type in the core protocol where the distinction
/// with the more general enum `GenericApplicationId` matters.
#[derive(
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
WitLoad,
WitStore,
WitType,
Serialize,
Deserialize,
)]
#[cfg_attr(with_testing, derive(Default, test_strategy::Arbitrary))]
pub struct UserApplicationId(pub CryptoHash);

impl<A> From<ApplicationId<A>> for UserApplicationId {
fn from(app_id: ApplicationId<A>) -> Self {
UserApplicationId(app_id.application_description_hash)
}
}

impl UserApplicationId {
/// Converts the application ID to the ID of the blob containing the
/// `UserApplicationDescription`.
pub fn description_blob_id(self) -> BlobId {
BlobId::new(self.0, BlobType::ApplicationDescription)
}

/// Specializes an application ID for a given ABI.
pub fn with_abi<A>(self) -> ApplicationId<A> {
ApplicationId {
application_description_hash: self.0,
_phantom: PhantomData,
}
}
}

/// A unique identifier for an application.
#[derive(
Expand All @@ -331,7 +369,7 @@ pub enum GenericApplicationId {

impl GenericApplicationId {
/// Returns the `ApplicationId`, or `None` if it is `System`.
pub fn user_application_id(&self) -> Option<&ApplicationId> {
pub fn user_application_id(&self) -> Option<&UserApplicationId> {
if let GenericApplicationId::User(app_id) = self {
Some(app_id)
} else {
Expand All @@ -340,8 +378,8 @@ impl GenericApplicationId {
}
}

impl From<ApplicationId> for GenericApplicationId {
fn from(user_application_id: ApplicationId) -> Self {
impl From<UserApplicationId> for GenericApplicationId {
fn from(user_application_id: UserApplicationId) -> Self {
GenericApplicationId::User(user_application_id)
}
}
Expand Down Expand Up @@ -411,7 +449,7 @@ impl ChannelFullName {
}

/// Creates a full user channel name.
pub fn user(name: ChannelName, application_id: ApplicationId) -> Self {
pub fn user(name: ChannelName, application_id: UserApplicationId) -> Self {
Self {
application_id: application_id.into(),
name,
Expand Down Expand Up @@ -849,40 +887,10 @@ impl<'de, A> Deserialize<'de> for ApplicationId<A> {
}
}

impl ApplicationId {
/// Creates an application ID from the application description hash.
pub fn new(application_description_hash: CryptoHash) -> Self {
ApplicationId {
application_description_hash,
_phantom: PhantomData,
}
}

/// Specializes an application ID for a given ABI.
pub fn with_abi<A>(self) -> ApplicationId<A> {
ApplicationId {
application_description_hash: self.application_description_hash,
_phantom: PhantomData,
}
}
}

impl<A> ApplicationId<A> {
/// Forgets the ABI of a module ID (if any).
pub fn forget_abi(self) -> ApplicationId {
ApplicationId {
application_description_hash: self.application_description_hash,
_phantom: PhantomData,
}
}

/// Converts the application ID to the ID of the blob containing the
/// `UserApplicationDescription`.
pub fn description_blob_id(self) -> BlobId {
BlobId::new(
self.application_description_hash,
BlobType::ApplicationDescription,
)
pub fn forget_abi(self) -> UserApplicationId {
UserApplicationId(self.application_description_hash)
}
}

Expand Down Expand Up @@ -948,7 +956,7 @@ impl<'de> serde::de::Visitor<'de> for OwnerVisitor {
#[serde(rename = "AccountOwner")]
enum SerializableAccountOwner {
User(Owner),
Application(ApplicationId),
Application(UserApplicationId),
Chain,
}

Expand Down Expand Up @@ -1008,7 +1016,8 @@ impl FromStr for AccountOwner {
))
} else if let Some(app_id) = s.strip_prefix("Application:") {
Ok(AccountOwner::Application(
ApplicationId::from_str(app_id).context("Getting ApplicationId should not fail")?,
UserApplicationId::from_str(app_id)
.context("Getting UserApplicationId should not fail")?,
))
} else if s.strip_prefix("Chain").is_some() {
Ok(AccountOwner::Chain)
Expand Down Expand Up @@ -1075,7 +1084,10 @@ impl ChainId {

impl<'de> BcsHashable<'de> for ChainDescription {}

bcs_scalar!(ApplicationId, "A unique identifier for a user application");
bcs_scalar!(
UserApplicationId,
"A unique identifier for a user application"
);
doc_scalar!(
GenericApplicationId,
"A unique identifier for a user application or for the system application"
Expand Down
10 changes: 5 additions & 5 deletions linera-base/src/unit_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use crate::{
crypto::{AccountPublicKey, CryptoHash},
data_types::{Amount, BlockHeight, Resources, SendMessageRequest, TimeDelta, Timestamp},
identifiers::{
Account, AccountOwner, ApplicationId, ChainId, ChannelName, Destination, MessageId,
ModuleId, Owner,
Account, AccountOwner, ChainId, ChannelName, Destination, MessageId, ModuleId, Owner,
UserApplicationId,
},
ownership::{ChainOwnership, TimeoutConfig},
vm::VmRuntime,
Expand Down Expand Up @@ -110,9 +110,9 @@ fn message_id_test_case() -> MessageId {
}
}

/// Creates a dummy [`ApplicationId`] instance to use for the WIT roundtrip test.
fn application_id_test_case() -> ApplicationId {
ApplicationId::new(CryptoHash::test_hash("application description"))
/// Creates a dummy [`UserApplicationId`] instance to use for the WIT roundtrip test.
fn application_id_test_case() -> UserApplicationId {
UserApplicationId(CryptoHash::test_hash("application description"))
}

/// Creates a dummy [`ModuleId`] instance to use for the WIT roundtrip test.
Expand Down
6 changes: 3 additions & 3 deletions linera-chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use linera_base::{
bcs,
crypto::{CryptoError, CryptoHash},
data_types::{ArithmeticError, BlockHeight, Round, Timestamp},
identifiers::{ApplicationId, BlobId, ChainId},
identifiers::{BlobId, ChainId, UserApplicationId},
};
use linera_execution::ExecutionError;
use linera_views::views::ViewError;
Expand Down Expand Up @@ -153,9 +153,9 @@ pub enum ChainError {
#[error("Closed chains cannot have operations, accepted messages or empty blocks")]
ClosedChain,
#[error("All operations on this chain must be from one of the following applications: {0:?}")]
AuthorizedApplications(Vec<ApplicationId>),
AuthorizedApplications(Vec<UserApplicationId>),
#[error("Missing operations or messages from mandatory applications: {0:?}")]
MissingMandatoryApplications(Vec<ApplicationId>),
MissingMandatoryApplications(Vec<UserApplicationId>),
#[error("Can't use grant across different broadcast messages")]
GrantUseOnBroadcast,
#[error("ExecutedBlock contains fewer oracle responses than requests")]
Expand Down
Loading