diff --git a/examples/amm/src/contract.rs b/examples/amm/src/contract.rs index c048554d2cd2..daedb407aa59 100644 --- a/examples/amm/src/contract.rs +++ b/examples/amm/src/contract.rs @@ -319,9 +319,6 @@ impl AmmContract { "Unauthorized" ) } - MultiAddress::Chain => { - panic!("Using chain balance is not authorized") - } } } diff --git a/examples/fungible/src/contract.rs b/examples/fungible/src/contract.rs index 29dc027f5076..96ec1e2a4d56 100644 --- a/examples/fungible/src/contract.rs +++ b/examples/fungible/src/contract.rs @@ -136,9 +136,6 @@ impl FungibleTokenContract { "The requested transfer is not correctly authenticated." ) } - MultiAddress::Chain => { - panic!("Chain account is not supported") - } } } diff --git a/examples/gen-nft/src/contract.rs b/examples/gen-nft/src/contract.rs index 07c7eab5f0f0..a2a353d46c8d 100644 --- a/examples/gen-nft/src/contract.rs +++ b/examples/gen-nft/src/contract.rs @@ -133,9 +133,6 @@ impl GenNftContract { "The requested transfer is not correctly authenticated." ) } - MultiAddress::Chain => { - panic!("Chain account is not supported") - } } } diff --git a/examples/matching-engine/src/contract.rs b/examples/matching-engine/src/contract.rs index 12447e42ff48..49f52110c875 100644 --- a/examples/matching-engine/src/contract.rs +++ b/examples/matching-engine/src/contract.rs @@ -159,9 +159,6 @@ impl MatchingEngineContract { "Unauthorized." ) } - MultiAddress::Chain => { - panic!("Chain account is not supported") - } } } diff --git a/examples/native-fungible/src/contract.rs b/examples/native-fungible/src/contract.rs index e295d9402f11..27a067796f77 100644 --- a/examples/native-fungible/src/contract.rs +++ b/examples/native-fungible/src/contract.rs @@ -40,7 +40,8 @@ impl Contract for NativeFungibleTokenContract { chain_id: self.runtime.chain_id(), owner, }; - self.runtime.transfer(MultiAddress::Chain, account, amount); + self.runtime + .transfer(MultiAddress::chain(), account, amount); } } @@ -143,9 +144,6 @@ impl NativeFungibleTokenContract { "The requested transfer is not correctly authenticated." ) } - MultiAddress::Chain => { - panic!("Chain accounts are not supported") - } } } } diff --git a/examples/native-fungible/tests/transfers.rs b/examples/native-fungible/tests/transfers.rs index d3170d67334f..e2bf24b69814 100644 --- a/examples/native-fungible/tests/transfers.rs +++ b/examples/native-fungible/tests/transfers.rs @@ -33,7 +33,7 @@ async fn chain_balance_transfers() { let transfer_certificate = funding_chain .add_block(|block| { - block.with_native_token_transfer(MultiAddress::Chain, recipient, transfer_amount); + block.with_native_token_transfer(MultiAddress::chain(), recipient, transfer_amount); }) .await; @@ -69,7 +69,7 @@ async fn transfer_to_owner() { let transfer_certificate = funding_chain .add_block(|block| { - block.with_native_token_transfer(MultiAddress::Chain, recipient, transfer_amount); + block.with_native_token_transfer(MultiAddress::chain(), recipient, transfer_amount); }) .await; @@ -114,7 +114,7 @@ async fn transfer_to_multiple_owners() { let transfer_certificate = funding_chain .add_block(|block| { for (recipient, transfer_amount) in recipients.zip(transfer_amounts.clone()) { - block.with_native_token_transfer(MultiAddress::Chain, recipient, transfer_amount); + block.with_native_token_transfer(MultiAddress::chain(), recipient, transfer_amount); } }) .await; @@ -154,7 +154,7 @@ async fn emptied_account_disappears_from_queries() { let transfer_certificate = funding_chain .add_block(|block| { - block.with_native_token_transfer(MultiAddress::Chain, recipient, transfer_amount); + block.with_native_token_transfer(MultiAddress::chain(), recipient, transfer_amount); }) .await; diff --git a/examples/non-fungible/src/contract.rs b/examples/non-fungible/src/contract.rs index 1b591c0f5259..a94476ace982 100644 --- a/examples/non-fungible/src/contract.rs +++ b/examples/non-fungible/src/contract.rs @@ -137,9 +137,6 @@ impl NonFungibleTokenContract { "The requested transfer is not correctly authenticated." ) } - MultiAddress::Chain => { - panic!("Chain account is not supported") - } } } diff --git a/linera-base/src/crypto/hash.rs b/linera-base/src/crypto/hash.rs index 479c6139b6a2..d4f54ab36f5e 100644 --- a/linera-base/src/crypto/hash.rs +++ b/linera-base/src/crypto/hash.rs @@ -6,7 +6,7 @@ #[cfg(with_testing)] use std::ops::RangeInclusive; -use std::{borrow::Cow, fmt, io, str::FromStr}; +use std::{borrow::Cow, fmt, io, str::FromStr, sync::LazyLock}; #[cfg(with_testing)] use alloy_primitives::FixedBytes; @@ -28,6 +28,15 @@ use crate::{ doc_scalar, }; +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +struct Chain; + +impl BcsHashable<'_> for Chain {} + +/// The CryptoHash of `Chain` newtype struct. +/// It's a marker for a generic `Chain` object. +pub static CHAIN_CRYPTO_HASH: LazyLock = LazyLock::new(|| CryptoHash::new(&Chain)); + /// A Keccak256 value. #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash)] #[cfg_attr(with_testing, derive(Default))] diff --git a/linera-base/src/data_types.rs b/linera-base/src/data_types.rs index 6948358b8f80..6c6fee886cdf 100644 --- a/linera-base/src/data_types.rs +++ b/linera-base/src/data_types.rs @@ -34,8 +34,7 @@ use crate::{ crypto::{BcsHashable, CryptoHash}, doc_scalar, hex_debug, http, identifiers::{ - BlobId, BlobType, ChainId, Destination, EventId, GenericApplicationId, ModuleId, - MultiAddress, StreamId, + BlobId, BlobType, ChainId, Destination, EventId, ModuleId, MultiAddress, StreamId, }, limited_writer::{LimitedWriter, LimitedWriterError}, time::{Duration, SystemTime}, @@ -765,12 +764,14 @@ impl ApplicationPermissions { } /// Returns whether operations with the given application ID are allowed on this chain. - pub fn can_execute_operations(&self, app_id: &GenericApplicationId) -> bool { - match (app_id, &self.execute_operations) { - (_, None) => true, - (GenericApplicationId::System, Some(_)) => false, - (GenericApplicationId::User(app_id), Some(app_ids)) => app_ids.contains(app_id), + pub fn can_execute_operations(&self, app_id: &MultiAddress) -> bool { + if self.execute_operations.is_none() { + return true; } + if app_id.is_chain() { + return false; + } + self.execute_operations.as_ref().unwrap().contains(app_id) } /// Returns whether the given application is allowed to close this chain. diff --git a/linera-base/src/identifiers.rs b/linera-base/src/identifiers.rs index 468f4f8d57a1..e809f955e18d 100644 --- a/linera-base/src/identifiers.rs +++ b/linera-base/src/identifiers.rs @@ -18,7 +18,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use crate::{ bcs_scalar, - crypto::{AccountPublicKey, BcsHashable, CryptoError, CryptoHash}, + crypto::{AccountPublicKey, BcsHashable, CryptoError, CryptoHash, CHAIN_CRYPTO_HASH}, data_types::BlockHeight, doc_scalar, hex_debug, vm::VmRuntime, @@ -36,16 +36,25 @@ pub struct Owner(pub CryptoHash); pub enum MultiAddress { /// 32-byte account address. Address32(CryptoHash), - /// Chain account. - Chain, +} + +impl MultiAddress { + /// Returns the default chain address. + pub fn chain() -> Self { + MultiAddress::Address32(*CHAIN_CRYPTO_HASH) + } + + /// Returns whether current address is a special chain address. + pub fn is_chain(&self) -> bool { + self == &MultiAddress::chain() + } } impl MultiAddress { /// Returns the address, if any, as [`CryptoHash`]. - pub fn as_address(&self) -> Option { + pub fn as_address(&self) -> CryptoHash { match self { - MultiAddress::Address32(address) => Some(*address), - MultiAddress::Chain => None, + MultiAddress::Address32(address) => *address, } } } @@ -71,7 +80,7 @@ impl Account { pub fn chain(chain_id: ChainId) -> Self { Account { chain_id, - owner: MultiAddress::Chain, + owner: MultiAddress::chain(), } } @@ -337,58 +346,18 @@ impl MultiAddress { /// Converts the application ID to the ID of the blob containing the /// `UserApplicationDescription`. pub fn description_blob_id(self) -> BlobId { - BlobId::new(self.as_address().unwrap(), BlobType::ApplicationDescription) + BlobId::new(self.as_address(), BlobType::ApplicationDescription) } /// Specializes an application ID for a given ABI. pub fn with_abi(self) -> ApplicationId { ApplicationId { - application_description_hash: self.as_address().unwrap(), + application_description_hash: self.as_address(), _phantom: PhantomData, } } } -/// A unique identifier for an application. -#[derive( - Eq, - PartialEq, - Ord, - PartialOrd, - Copy, - Clone, - Hash, - Debug, - Serialize, - Deserialize, - WitLoad, - WitStore, - WitType, -)] -pub enum GenericApplicationId { - /// The system application. - System, - /// A user application. - User(MultiAddress), -} - -impl GenericApplicationId { - /// Returns the `ApplicationId`, or `None` if it is `System`. - pub fn user_application_id(&self) -> Option<&MultiAddress> { - if let GenericApplicationId::User(app_id) = self { - Some(app_id) - } else { - None - } - } -} - -impl From for GenericApplicationId { - fn from(user_application_id: MultiAddress) -> Self { - GenericApplicationId::User(user_application_id) - } -} - /// A unique identifier for a module. #[derive(Debug, WitLoad, WitStore, WitType)] #[cfg_attr(with_testing, derive(Default, test_strategy::Arbitrary))] @@ -429,7 +398,7 @@ pub struct ChannelName( /// A channel name together with its application ID. pub struct ChannelFullName { /// The application owning the channel. - pub application_id: GenericApplicationId, + pub application_id: MultiAddress, /// The name of the channel. pub name: ChannelName, } @@ -437,9 +406,11 @@ pub struct ChannelFullName { impl fmt::Display for ChannelFullName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let name = hex::encode(&self.name); - match self.application_id { - GenericApplicationId::System => write!(f, "system channel {name}"), - GenericApplicationId::User(app_id) => write!(f, "user channel {name} for app {app_id}"), + if self.application_id.is_chain() { + write!(f, "system channel {name}") + } else { + let app_id = self.application_id; + write!(f, "user channel {name} for app {app_id}") } } } @@ -448,7 +419,7 @@ impl ChannelFullName { /// Creates a full system channel name. pub fn system(name: ChannelName) -> Self { Self { - application_id: GenericApplicationId::System, + application_id: MultiAddress::chain(), name, } } @@ -456,7 +427,7 @@ impl ChannelFullName { /// Creates a full user channel name. pub fn user(name: ChannelName, application_id: MultiAddress) -> Self { Self { - application_id: application_id.into(), + application_id, name, } } @@ -510,7 +481,7 @@ where )] pub struct StreamId { /// The application that can add events to this stream. - pub application_id: GenericApplicationId, + pub application_id: MultiAddress, /// The name of this stream: an application can have multiple streams with different names. pub stream_name: StreamName, } @@ -519,7 +490,7 @@ impl StreamId { /// Creates a system stream ID with the given name. pub fn system(name: impl Into) -> Self { StreamId { - application_id: GenericApplicationId::System, + application_id: MultiAddress::chain(), stream_name: name.into(), } } @@ -961,7 +932,6 @@ impl<'de> serde::de::Visitor<'de> for OwnerVisitor { #[serde(rename = "MultiAddress")] enum SerializableAccountOwner { Address32(CryptoHash), - Chain, } impl Serialize for MultiAddress { @@ -971,7 +941,6 @@ impl Serialize for MultiAddress { } else { match self { MultiAddress::Address32(app_id) => SerializableAccountOwner::Address32(*app_id), - MultiAddress::Chain => SerializableAccountOwner::Chain, } .serialize(serializer) } @@ -988,7 +957,6 @@ impl<'de> Deserialize<'de> for MultiAddress { let value = SerializableAccountOwner::deserialize(deserializer)?; match value { SerializableAccountOwner::Address32(app_id) => Ok(MultiAddress::Address32(app_id)), - SerializableAccountOwner::Chain => Ok(MultiAddress::Chain), } } } @@ -998,7 +966,6 @@ impl Display for MultiAddress { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { MultiAddress::Address32(owner) => write!(f, "0x{}", owner)?, - MultiAddress::Chain => write!(f, "Chain")?, }; Ok(()) @@ -1013,8 +980,6 @@ impl FromStr for MultiAddress { Ok(MultiAddress::Address32( CryptoHash::from_str(owner).context("Parsing Address should not fail")?, )) - } else if s.strip_prefix("Chain").is_some() { - Ok(MultiAddress::Chain) } else { Err(anyhow!("Invalid enum! Enum: {}", s)) } @@ -1069,10 +1034,6 @@ impl ChainId { impl<'de> BcsHashable<'de> for ChainDescription {} -doc_scalar!( - GenericApplicationId, - "A unique identifier for a user application or for the system application" -); bcs_scalar!(ModuleId, "A unique identifier for an application module"); doc_scalar!(ChainDescription, "How to create a chain"); doc_scalar!( @@ -1092,7 +1053,10 @@ doc_scalar!( Destination, "The destination of a message, relative to a particular application." ); -doc_scalar!(MultiAddress, "An owner of an account."); +doc_scalar!( + MultiAddress, + "A unique identifier for a user or an application." +); doc_scalar!(Account, "An account"); doc_scalar!( BlobId, @@ -1146,11 +1110,8 @@ mod tests { let crypto_hash = CryptoHash::new(&TestString::new("Chain")); let input_str = format!("0x{}", crypto_hash); let account_owner = MultiAddress::from_str(&input_str).unwrap(); - if let MultiAddress::Address32(owner) = account_owner { - assert_eq!(owner, crypto_hash); - } else { - panic!("Expected Address32 variant"); - } + let MultiAddress::Address32(owner) = account_owner; + assert_eq!(owner, crypto_hash); assert_eq!( MultiAddress::from_str(&account_owner.to_string()).unwrap(), account_owner diff --git a/linera-chain/src/test/mod.rs b/linera-chain/src/test/mod.rs index 3ed0e520fe54..b83f8c0c5278 100644 --- a/linera-chain/src/test/mod.rs +++ b/linera-chain/src/test/mod.rs @@ -109,7 +109,7 @@ impl BlockTestExt for ProposedBlock { } fn with_simple_transfer(self, chain_id: ChainId, amount: Amount) -> Self { - self.with_transfer(MultiAddress::Chain, Recipient::chain(chain_id), amount) + self.with_transfer(MultiAddress::chain(), Recipient::chain(chain_id), amount) } fn with_incoming_bundle(mut self, incoming_bundle: IncomingBundle) -> Self { diff --git a/linera-chain/src/unit_tests/chain_tests.rs b/linera-chain/src/unit_tests/chain_tests.rs index f456aaeb2b6b..6115481c9d48 100644 --- a/linera-chain/src/unit_tests/chain_tests.rs +++ b/linera-chain/src/unit_tests/chain_tests.rs @@ -166,7 +166,7 @@ async fn test_block_size_limit() { let invalid_block = valid_block .clone() .with_operation(SystemOperation::Transfer { - owner: MultiAddress::Chain, + owner: MultiAddress::chain(), recipient: Recipient::root(0), amount: Amount::ONE, }); diff --git a/linera-client/src/benchmark.rs b/linera-client/src/benchmark.rs index 7b1133c23b29..eb57129c3ce7 100644 --- a/linera-client/src/benchmark.rs +++ b/linera-client/src/benchmark.rs @@ -594,7 +594,7 @@ where amount, ), None => Operation::System(SystemOperation::Transfer { - owner: MultiAddress::Chain, + owner: MultiAddress::chain(), recipient: Recipient::chain(previous_chain_id), amount, }), diff --git a/linera-client/src/unit_tests/chain_listener.rs b/linera-client/src/unit_tests/chain_listener.rs index d33533fd4e7b..5037e99888a2 100644 --- a/linera-client/src/unit_tests/chain_listener.rs +++ b/linera-client/src/unit_tests/chain_listener.rs @@ -161,7 +161,7 @@ async fn test_chain_listener() -> anyhow::Result<()> { // the message. let recipient0 = Recipient::chain(chain_id0); client1 - .transfer(MultiAddress::Chain, Amount::ONE, recipient0) + .transfer(MultiAddress::chain(), Amount::ONE, recipient0) .await?; for i in 0.. { client0.synchronize_from_validators().boxed().await?; diff --git a/linera-core/benches/client_benchmarks.rs b/linera-core/benches/client_benchmarks.rs index 63427cfe183d..f17db6066f1d 100644 --- a/linera-core/benches/client_benchmarks.rs +++ b/linera-core/benches/client_benchmarks.rs @@ -59,7 +59,7 @@ where let account = Account::address32(chain2.chain_id(), owner1.0); let cert = chain1 - .transfer_to_account(MultiAddress::Chain, amt, account) + .transfer_to_account(MultiAddress::chain(), amt, account) .await .unwrap() .unwrap(); diff --git a/linera-core/src/chain_worker/state/temporary_changes.rs b/linera-core/src/chain_worker/state/temporary_changes.rs index e544e6584326..aaeb73a51153 100644 --- a/linera-core/src/chain_worker/state/temporary_changes.rs +++ b/linera-core/src/chain_worker/state/temporary_changes.rs @@ -8,7 +8,7 @@ use std::collections::HashMap; use linera_base::{ data_types::{ArithmeticError, Blob, Timestamp, UserApplicationDescription}, ensure, - identifiers::{ChannelFullName, GenericApplicationId, MultiAddress, Owner}, + identifiers::{ChannelFullName, MultiAddress, Owner}, }; use linera_chain::{ data_types::{ @@ -278,14 +278,15 @@ where if query.request_committees { info.requested_committees = Some(chain.execution_state.system.committees.get().clone()); } - match query.request_owner_balance { - owner @ MultiAddress::Address32(_) => { - info.requested_owner_balance = - chain.execution_state.system.balances.get(&owner).await?; - } - MultiAddress::Chain => { - info.requested_owner_balance = Some(*chain.execution_state.system.balance.get()); - } + if query.request_owner_balance == MultiAddress::chain() { + info.requested_owner_balance = Some(*chain.execution_state.system.balance.get()); + } else { + info.requested_owner_balance = chain + .execution_state + .system + .balances + .get(&query.request_owner_balance) + .await?; } if let Some(next_block_height) = query.test_next_block_height { ensure!( @@ -307,16 +308,18 @@ where let subscriptions = &chain.execution_state.system.subscriptions; for (origin, inbox) in pairs { if let Medium::Channel(ChannelFullName { - application_id: GenericApplicationId::System, + application_id, name, }) = &origin.medium { - let subscription = ChannelSubscription { - chain_id: origin.sender, - name: name.clone(), - }; - if !subscriptions.contains(&subscription).await? { - continue; // We are not subscribed to this channel. + if application_id.is_chain() { + let subscription = ChannelSubscription { + chain_id: origin.sender, + name: name.clone(), + }; + if !subscriptions.contains(&subscription).await? { + continue; // We are not subscribed to this channel. + } } } for bundle in inbox.added_bundles.elements().await? { diff --git a/linera-core/src/client/mod.rs b/linera-core/src/client/mod.rs index c735f68882eb..a9d373780ed0 100644 --- a/linera-core/src/client/mod.rs +++ b/linera-core/src/client/mod.rs @@ -2289,7 +2289,9 @@ where /// block. #[instrument(level = "trace")] pub async fn query_balance(&self) -> Result { - let (balance, _) = self.query_balances_with_owner(MultiAddress::Chain).await?; + let (balance, _) = self + .query_balances_with_owner(MultiAddress::chain()) + .await?; Ok(balance) } @@ -2339,8 +2341,8 @@ where previous_block_hash, height, authenticated_signer: match owner { - MultiAddress::Address32(user) => Some(Owner(user)), - MultiAddress::Chain => None, // These should be unreachable? + MultiAddress::Address32(_) if owner == MultiAddress::chain() => None, + MultiAddress::Address32(other) => Some(Owner(other)), }, timestamp, }; @@ -2377,7 +2379,9 @@ where /// Does not process the inbox or attempt to synchronize with validators. #[instrument(level = "trace")] pub async fn local_balance(&self) -> Result { - let (balance, _) = self.local_balances_with_owner(MultiAddress::Chain).await?; + let (balance, _) = self + .local_balances_with_owner(MultiAddress::chain()) + .await?; Ok(balance) } diff --git a/linera-core/src/data_types.rs b/linera-core/src/data_types.rs index 52cb01c696cb..229858db7f10 100644 --- a/linera-core/src/data_types.rs +++ b/linera-core/src/data_types.rs @@ -101,7 +101,7 @@ impl ChainInfoQuery { chain_id, test_next_block_height: None, request_committees: false, - request_owner_balance: MultiAddress::Chain, + request_owner_balance: MultiAddress::chain(), request_pending_message_bundles: false, request_sent_certificate_hashes_in_range: None, request_received_log_excluding_first_n: None, diff --git a/linera-core/src/unit_tests/client_tests.rs b/linera-core/src/unit_tests/client_tests.rs index c71ce0344cf6..d63efb96652a 100644 --- a/linera-core/src/unit_tests/client_tests.rs +++ b/linera-core/src/unit_tests/client_tests.rs @@ -104,7 +104,7 @@ where { let certificate = sender .transfer_to_account( - MultiAddress::Chain, + MultiAddress::chain(), Amount::from_tokens(3), Account::chain(ChainId::root(2)), ) @@ -156,7 +156,7 @@ where let friend = receiver.identity().await?; sender .transfer_to_account( - MultiAddress::Chain, + MultiAddress::chain(), Amount::from_tokens(3), Account::address32(receiver_id, owner_identity.0), ) @@ -165,7 +165,7 @@ where .unwrap(); let cert = sender .transfer_to_account( - MultiAddress::Chain, + MultiAddress::chain(), Amount::from_millis(100), Account::address32(receiver_id, friend.0), ) @@ -292,7 +292,7 @@ where sender.synchronize_from_validators().await.unwrap(); // Can still use the chain. sender - .burn(MultiAddress::Chain, Amount::from_tokens(3)) + .burn(MultiAddress::chain(), Amount::from_tokens(3)) .await .unwrap(); Ok(()) @@ -339,7 +339,7 @@ where // Cannot use the chain any more. assert_matches!( sender - .burn(MultiAddress::Chain, Amount::from_tokens(3)) + .burn(MultiAddress::chain(), Amount::from_tokens(3)) .await, Err(ChainClientError::CannotFindKeyForChain(_)) ); @@ -382,7 +382,7 @@ where sender.synchronize_from_validators().await.unwrap(); // Can still use the chain with the old client. sender - .burn(MultiAddress::Chain, Amount::from_tokens(2)) + .burn(MultiAddress::chain(), Amount::from_tokens(2)) .await .unwrap(); assert_eq!(sender.next_block_height(), BlockHeight::from(2)); @@ -409,7 +409,7 @@ where // We need at least three validators for making an operation. builder.set_fault_type([0, 1], FaultType::Offline).await; - let result = client.burn(MultiAddress::Chain, Amount::ONE).await; + let result = client.burn(MultiAddress::chain(), Amount::ONE).await; assert_matches!( result, Err(ChainClientError::CommunicationError( @@ -419,7 +419,7 @@ where builder.set_fault_type([0, 1], FaultType::Honest).await; builder.set_fault_type([2, 3], FaultType::Offline).await; assert_matches!( - sender.burn(MultiAddress::Chain, Amount::ONE).await, + sender.burn(MultiAddress::chain(), Amount::ONE).await, Err(ChainClientError::CommunicationError( CommunicationError::Trusted(ClientIoError { .. }) )) @@ -438,7 +438,7 @@ where ); client.clear_pending_proposal(); client - .burn(MultiAddress::Chain, Amount::ONE) + .burn(MultiAddress::chain(), Amount::ONE) .await .unwrap() .unwrap(); @@ -448,7 +448,10 @@ where sender.process_inbox().await.unwrap(); assert_eq!(sender.local_balance().await.unwrap(), Amount::ONE); sender.clear_pending_proposal(); - sender.burn(MultiAddress::Chain, Amount::ONE).await.unwrap(); + sender + .burn(MultiAddress::chain(), Amount::ONE) + .await + .unwrap(); // That's it, we spent all our money on this test! assert_eq!(sender.local_balance().await.unwrap(), Amount::ZERO); @@ -535,7 +538,7 @@ where // Transfer before creating the chain. The validators will ignore the cross-chain messages. sender .transfer_to_account( - MultiAddress::Chain, + MultiAddress::chain(), Amount::from_tokens(2), Account::chain(new_id), ) @@ -581,7 +584,7 @@ where // process the cross-chain messages. let certificate2 = sender .transfer_to_account( - MultiAddress::Chain, + MultiAddress::chain(), Amount::from_tokens(1), Account::chain(new_id), ) @@ -597,7 +600,7 @@ where Amount::from_tokens(3) ); client - .burn(MultiAddress::Chain, Amount::from_tokens(3)) + .burn(MultiAddress::chain(), Amount::from_tokens(3)) .await .unwrap(); Ok(()) @@ -626,7 +629,7 @@ where // Transfer before creating the chain. sender .transfer_to_account( - MultiAddress::Chain, + MultiAddress::chain(), Amount::from_tokens(3), Account::chain(new_id), ) @@ -668,7 +671,7 @@ where .await .unwrap(); let result = client - .burn(MultiAddress::Chain, Amount::from_tokens(3)) + .burn(MultiAddress::chain(), Amount::from_tokens(3)) .await; assert_matches!( result, @@ -710,7 +713,7 @@ where // Transfer after creating the chain. let transfer_certificate = sender .transfer_to_account( - MultiAddress::Chain, + MultiAddress::chain(), Amount::from_tokens(3), Account::chain(new_id), ) @@ -739,7 +742,7 @@ where Amount::from_tokens(3) ); client - .burn(MultiAddress::Chain, Amount::from_tokens(3)) + .burn(MultiAddress::chain(), Amount::from_tokens(3)) .await .unwrap(); assert_eq!(client.local_balance().await.unwrap(), Amount::ZERO); @@ -780,7 +783,7 @@ where ); // Cannot use the chain for operations any more. let result = client1 - .burn(MultiAddress::Chain, Amount::from_tokens(3)) + .burn(MultiAddress::chain(), Amount::from_tokens(3)) .await; assert!( matches!( @@ -796,7 +799,7 @@ where // Incoming messages now get rejected. client2 .transfer_to_account( - MultiAddress::Chain, + MultiAddress::chain(), Amount::from_tokens(3), Account::chain(client1.chain_id()), ) @@ -854,7 +857,7 @@ where let sender = builder.add_root_chain(1, Amount::from_tokens(4)).await?; let result = sender .transfer_to_account_unsafe_unconfirmed( - MultiAddress::Chain, + MultiAddress::chain(), Amount::from_tokens(3), Account::chain(ChainId::root(2)), ) @@ -904,7 +907,7 @@ where ); let certificate = client1 .transfer_to_account( - MultiAddress::Chain, + MultiAddress::chain(), Amount::from_tokens(3), Account::chain(client2.chain_id), ) @@ -953,7 +956,7 @@ where assert_eq!(client2.next_block_height(), BlockHeight::ZERO); client2 .transfer_to_account( - MultiAddress::Chain, + MultiAddress::chain(), Amount::ONE, Account::chain(client1.chain_id), ) @@ -999,7 +1002,7 @@ where let client2 = builder.add_root_chain(2, Amount::ZERO).await?; let certificate = client1 .transfer_to_account_unsafe_unconfirmed( - MultiAddress::Chain, + MultiAddress::chain(), Amount::from_tokens(2), Account::chain(client2.chain_id), ) @@ -1049,7 +1052,7 @@ where // Confirming to a quorum of nodes only at the end. client1 .transfer_to_account_unsafe_unconfirmed( - MultiAddress::Chain, + MultiAddress::chain(), Amount::ONE, Account::chain(client2.chain_id), ) @@ -1057,7 +1060,7 @@ where .unwrap(); client1 .transfer_to_account_unsafe_unconfirmed( - MultiAddress::Chain, + MultiAddress::chain(), Amount::ONE, Account::chain(client2.chain_id), ) @@ -1077,7 +1080,7 @@ where // Sending money from client2 fails, as a consequence. let obtained_error = client2 .transfer_to_account_unsafe_unconfirmed( - MultiAddress::Chain, + MultiAddress::chain(), Amount::from_tokens(2), Account::chain(client3.chain_id), ) @@ -1094,7 +1097,7 @@ where client2.synchronize_from_validators().await.unwrap(); let certificate = client2 .transfer_to_account( - MultiAddress::Chain, + MultiAddress::chain(), Amount::from_tokens(2), Account::chain(client3.chain_id), ) @@ -1170,7 +1173,7 @@ where // Sending money from the admin chain is supported. let cert = admin .transfer_to_account( - MultiAddress::Chain, + MultiAddress::chain(), Amount::from_tokens(2), Account::chain(user.chain_id()), ) @@ -1179,7 +1182,7 @@ where .unwrap(); admin .transfer_to_account( - MultiAddress::Chain, + MultiAddress::chain(), Amount::ONE, Account::chain(user.chain_id()), ) @@ -1205,7 +1208,7 @@ where // Try to make a transfer back to the admin chain. let cert = user .transfer_to_account( - MultiAddress::Chain, + MultiAddress::chain(), Amount::from_tokens(2), Account::chain(admin.chain_id()), ) @@ -1221,7 +1224,7 @@ where // Try again to make a transfer back to the admin chain. let cert = user .transfer_to_account( - MultiAddress::Chain, + MultiAddress::chain(), Amount::ONE, Account::chain(admin.chain_id()), ) @@ -1251,12 +1254,12 @@ where let sender = builder.add_root_chain(1, Amount::from_tokens(3)).await?; let obtained_error = sender - .burn(MultiAddress::Chain, Amount::from_tokens(4)) + .burn(MultiAddress::chain(), Amount::from_tokens(4)) .await; assert_insufficient_funding_during_operation(obtained_error, 0); let obtained_error = sender - .burn(MultiAddress::Chain, Amount::from_tokens(3)) + .burn(MultiAddress::chain(), Amount::from_tokens(3)) .await; assert_insufficient_funding_fees(obtained_error); Ok(()) @@ -1421,7 +1424,7 @@ where *info2_b.manager.requested_locking.unwrap() ); let bt_certificate = client2_b - .burn(MultiAddress::Chain, Amount::from_tokens(1)) + .burn(MultiAddress::chain(), Amount::from_tokens(1)) .await .unwrap() .unwrap(); @@ -1438,7 +1441,7 @@ where .body .operations .contains(&Operation::System(SystemOperation::Transfer { - owner: MultiAddress::Chain, + owner: MultiAddress::chain(), recipient: Recipient::Burn, amount: Amount::from_tokens(1), }))); @@ -1548,7 +1551,7 @@ where client2_b.prepare_chain().await.unwrap(); let bt_certificate = client2_b - .burn(MultiAddress::Chain, Amount::from_tokens(1)) + .burn(MultiAddress::chain(), Amount::from_tokens(1)) .await .unwrap() .unwrap(); @@ -1565,7 +1568,7 @@ where .body .operations .contains(&Operation::System(SystemOperation::Transfer { - owner: MultiAddress::Chain, + owner: MultiAddress::chain(), recipient: Recipient::Burn, amount: Amount::from_tokens(1), }))); @@ -1897,7 +1900,7 @@ where // The other owner is leader now. Trying to submit a block should return `WaitForTimeout`. let result = client - .transfer(MultiAddress::Chain, Amount::ONE, Recipient::root(2)) + .transfer(MultiAddress::chain(), Amount::ONE, Recipient::root(2)) .await .unwrap(); let timeout = match result { @@ -1924,7 +1927,7 @@ where // Now we are the leader, and the transfer should succeed. let _certificate = client - .transfer(MultiAddress::Chain, Amount::ONE, Recipient::root(2)) + .transfer(MultiAddress::chain(), Amount::ONE, Recipient::root(2)) .await .unwrap() .unwrap(); @@ -1982,7 +1985,7 @@ where .set_fault_type([2], FaultType::OfflineWithInfo) .await; let result = client0 - .burn(MultiAddress::Chain, Amount::from_tokens(3)) + .burn(MultiAddress::chain(), Amount::from_tokens(3)) .await; assert!(result.is_err()); @@ -2025,7 +2028,7 @@ where // Client 0 now only tries to burn 1 token. Before that, they automatically finalize the // pending block, which publishes the blob, leaving 10 - 1 = 9. client0 - .burn(MultiAddress::Chain, Amount::from_tokens(1)) + .burn(MultiAddress::chain(), Amount::from_tokens(1)) .await .unwrap(); client0.synchronize_from_validators().await.unwrap(); @@ -2039,7 +2042,7 @@ where // Burn another token so Client 1 sees that the blob is already published client1.prepare_chain().await.unwrap(); client1 - .burn(MultiAddress::Chain, Amount::from_tokens(1)) + .burn(MultiAddress::chain(), Amount::from_tokens(1)) .await .unwrap(); client1.synchronize_from_validators().await.unwrap(); @@ -2071,7 +2074,7 @@ where .set_fault_type([2], FaultType::OfflineWithInfo) .await; let result = client - .burn(MultiAddress::Chain, Amount::from_tokens(3)) + .burn(MultiAddress::chain(), Amount::from_tokens(3)) .await; assert!(result.is_err()); @@ -2080,7 +2083,10 @@ where // The client tries to burn another token. Before that, they automatically finalize the // pending block, which burns 3 tokens, leaving 10 - 3 - 1 = 6. - client.burn(MultiAddress::Chain, Amount::ONE).await.unwrap(); + client + .burn(MultiAddress::chain(), Amount::ONE) + .await + .unwrap(); client.synchronize_from_validators().await.unwrap(); client.process_inbox().await.unwrap(); assert_eq!( @@ -2131,7 +2137,7 @@ where .await; builder.set_fault_type([3], FaultType::Offline).await; let result = client0 - .burn(MultiAddress::Chain, Amount::from_tokens(3)) + .burn(MultiAddress::chain(), Amount::from_tokens(3)) .await; assert!(result.is_err()); let manager = client0 @@ -2169,7 +2175,7 @@ where assert!(manager.requested_locking.is_none()); assert_eq!(manager.current_round, Round::MultiLeader(0)); let result = client1 - .burn(MultiAddress::Chain, Amount::from_tokens(2)) + .burn(MultiAddress::chain(), Amount::from_tokens(2)) .await; assert!(result.is_err()); @@ -2190,7 +2196,7 @@ where assert_eq!(manager.current_round, Round::MultiLeader(1)); assert!(client1.pending_proposal().is_some()); client1 - .burn(MultiAddress::Chain, Amount::from_tokens(4)) + .burn(MultiAddress::chain(), Amount::from_tokens(4)) .await .unwrap(); @@ -2217,7 +2223,7 @@ where let mut receiver = builder.add_root_chain(2, Amount::ZERO).await?; let recipient = Recipient::chain(receiver.chain_id()); let cert = sender - .transfer(MultiAddress::Chain, Amount::ONE, recipient) + .transfer(MultiAddress::chain(), Amount::ONE, recipient) .await .unwrap() .unwrap(); @@ -2303,7 +2309,7 @@ where // Send a message from chain 2 to chain 3. let certificate = client2 .transfer( - MultiAddress::Chain, + MultiAddress::chain(), Amount::from_millis(1), Recipient::chain(chain_id3), ) diff --git a/linera-core/src/unit_tests/wasm_client_tests.rs b/linera-core/src/unit_tests/wasm_client_tests.rs index a8cfce00fce5..261ecf438e64 100644 --- a/linera-core/src/unit_tests/wasm_client_tests.rs +++ b/linera-core/src/unit_tests/wasm_client_tests.rs @@ -346,7 +346,7 @@ where certificate.block().body.events, vec![vec![Event { stream_id: StreamId { - application_id: application_id2.forget_abi().into(), + application_id: application_id2.forget_abi(), stream_name: StreamName(b"announcements".to_vec()), }, key: b"updates".to_vec(), diff --git a/linera-core/src/unit_tests/worker_tests.rs b/linera-core/src/unit_tests/worker_tests.rs index 9c383d169379..a06a6c960143 100644 --- a/linera-core/src/unit_tests/worker_tests.rs +++ b/linera-core/src/unit_tests/worker_tests.rs @@ -203,7 +203,7 @@ where chain_description, key_pair, Some(key_pair.public().into()), - MultiAddress::Chain, + MultiAddress::chain(), Recipient::chain(target_id), amount, incoming_bundles, @@ -372,16 +372,16 @@ fn direct_outgoing_message( fn system_credit_message(amount: Amount) -> Message { Message::System(SystemMessage::Credit { - source: MultiAddress::Chain, - target: MultiAddress::Chain, + source: MultiAddress::chain(), + target: MultiAddress::chain(), amount, }) } fn direct_credit_message(recipient: ChainId, amount: Amount) -> OutgoingMessage { let message = SystemMessage::Credit { - source: MultiAddress::Chain, - target: MultiAddress::Chain, + source: MultiAddress::chain(), + target: MultiAddress::chain(), amount, }; direct_outgoing_message(recipient, MessageKind::Tracked, message) @@ -1390,7 +1390,7 @@ where ChainDescription::Root(2), &sender_key_pair, Some(chain_key_pair.public().into()), - MultiAddress::Chain, + MultiAddress::chain(), Recipient::chain(ChainId::root(2)), Amount::from_tokens(5), Vec::new(), @@ -2124,7 +2124,7 @@ where ChainDescription::Root(1), &sender_key_pair, Some(Owner::from(sender_key_pair.public())), - MultiAddress::Chain, + MultiAddress::chain(), Recipient::Account(sender_account), Amount::from_tokens(5), Vec::new(), @@ -2144,7 +2144,7 @@ where ChainDescription::Root(1), &sender_key_pair, Some(Owner::from(sender_key_pair.public())), - MultiAddress::Chain, + MultiAddress::chain(), Recipient::Burn, Amount::ONE, vec![IncomingBundle { @@ -2155,7 +2155,7 @@ where timestamp: Timestamp::from(0), transaction_index: 0, messages: vec![Message::System(SystemMessage::Credit { - source: MultiAddress::Chain, + source: MultiAddress::chain(), target: MultiAddress::from(sender), amount: Amount::from_tokens(5), }) @@ -2983,7 +2983,7 @@ async fn test_cross_chain_helper() -> anyhow::Result<()> { ChainDescription::Root(0), &key_pair0, Some(key_pair0.public().into()), - MultiAddress::Chain, + MultiAddress::chain(), Recipient::chain(id1), Amount::ONE, Vec::new(), @@ -2999,7 +2999,7 @@ async fn test_cross_chain_helper() -> anyhow::Result<()> { ChainDescription::Root(0), &key_pair0, Some(key_pair0.public().into()), - MultiAddress::Chain, + MultiAddress::chain(), Recipient::chain(id1), Amount::ONE, Vec::new(), @@ -3015,7 +3015,7 @@ async fn test_cross_chain_helper() -> anyhow::Result<()> { ChainDescription::Root(0), &key_pair0, Some(key_pair0.public().into()), - MultiAddress::Chain, + MultiAddress::chain(), Recipient::chain(id1), Amount::ONE, Vec::new(), @@ -3032,7 +3032,7 @@ async fn test_cross_chain_helper() -> anyhow::Result<()> { ChainDescription::Root(0), &key_pair0, Some(key_pair0.public().into()), - MultiAddress::Chain, + MultiAddress::chain(), Recipient::chain(id1), Amount::ONE, Vec::new(), @@ -3515,7 +3515,11 @@ where // The first round is the multi-leader round 0. Anyone is allowed to propose. // But non-owners are not allowed to transfer the chain's funds. let proposal = make_child_block(&change_ownership_value) - .with_transfer(MultiAddress::Chain, Recipient::Burn, Amount::from_tokens(1)) + .with_transfer( + MultiAddress::chain(), + Recipient::Burn, + Amount::from_tokens(1), + ) .into_proposal_with_round(&AccountSecretKey::generate(), Round::MultiLeader(0)); let result = worker.handle_block_proposal(proposal).await; assert_matches!(result, Err(WorkerError::ChainError(error)) if matches!(&*error, diff --git a/linera-execution/src/execution.rs b/linera-execution/src/execution.rs index 3594d90e5d77..fc78b44ff980 100644 --- a/linera-execution/src/execution.rs +++ b/linera-execution/src/execution.rs @@ -370,7 +370,7 @@ where source: context .authenticated_signer .map(MultiAddress::from) - .unwrap_or(MultiAddress::Chain), + .unwrap_or(MultiAddress::chain()), target: account.owner, }; txn_tracker.add_outgoing_message( diff --git a/linera-execution/src/lib.rs b/linera-execution/src/lib.rs index 856fd3370868..47a4c68b88fb 100644 --- a/linera-execution/src/lib.rs +++ b/linera-execution/src/lib.rs @@ -43,7 +43,7 @@ use linera_base::{ doc_scalar, hex_debug, http, identifiers::{ Account, ApplicationId, BlobId, BlobType, ChainId, ChannelName, Destination, EventId, - GenericApplicationId, MessageId, ModuleId, MultiAddress, Owner, StreamName, + MessageId, ModuleId, MultiAddress, Owner, StreamName, }, ownership::ChainOwnership, task, @@ -1160,10 +1160,10 @@ impl Operation { }) } - pub fn application_id(&self) -> GenericApplicationId { + pub fn application_id(&self) -> MultiAddress { match self { - Self::System(_) => GenericApplicationId::System, - Self::User { application_id, .. } => GenericApplicationId::User(*application_id), + Self::System(_) => MultiAddress::chain(), + Self::User { application_id, .. } => *application_id, } } @@ -1212,10 +1212,10 @@ impl Message { }) } - pub fn application_id(&self) -> GenericApplicationId { + pub fn application_id(&self) -> MultiAddress { match self { - Self::System(_) => GenericApplicationId::System, - Self::User { application_id, .. } => GenericApplicationId::User(*application_id), + Self::System(_) => MultiAddress::chain(), + Self::User { application_id, .. } => *application_id, } } @@ -1284,10 +1284,10 @@ impl Query { }) } - pub fn application_id(&self) -> GenericApplicationId { + pub fn application_id(&self) -> MultiAddress { match self { - Self::System(_) => GenericApplicationId::System, - Self::User { application_id, .. } => GenericApplicationId::User(*application_id), + Self::System(_) => MultiAddress::chain(), + Self::User { application_id, .. } => *application_id, } } } diff --git a/linera-execution/src/runtime.rs b/linera-execution/src/runtime.rs index 839f43b46f8b..785b476122e2 100644 --- a/linera-execution/src/runtime.rs +++ b/linera-execution/src/runtime.rs @@ -1301,7 +1301,7 @@ impl ContractRuntime for ContractSyncRuntimeHandle { stream_name.0.len() <= MAX_STREAM_NAME_LEN, ExecutionError::StreamNameTooLong ); - let application_id = this.current_application().id.into(); + let application_id = this.current_application().id; let stream_id = StreamId { stream_name, application_id, diff --git a/linera-execution/src/system.rs b/linera-execution/src/system.rs index 195373bfe903..ac88993de1ba 100644 --- a/linera-execution/src/system.rs +++ b/linera-execution/src/system.rs @@ -628,22 +628,25 @@ where recipient: Recipient, amount: Amount, ) -> Result, ExecutionError> { - match (source, authenticated_signer, authenticated_application_id) { - (MultiAddress::Address32(source), Some(Owner(signer)), _) => ensure!( - signer == source, + if source == MultiAddress::chain() && authenticated_signer.is_some() { + ensure!( + self.ownership + .get() + .verify_owner(&authenticated_signer.unwrap()), ExecutionError::UnauthenticatedTransferOwner - ), - (MultiAddress::Address32(account_application), _, Some(authorized_application)) => { - ensure!( - account_application == authorized_application.as_address().unwrap(), - ExecutionError::UnauthenticatedTransferOwner - ) - } - (MultiAddress::Chain, Some(signer), _) => ensure!( - self.ownership.get().verify_owner(&signer), + ) + } else if let Some(authenticated_signer) = authenticated_signer { + ensure!( + source == MultiAddress::from(authenticated_signer), ExecutionError::UnauthenticatedTransferOwner - ), - (_, _, _) => return Err(ExecutionError::UnauthenticatedTransferOwner), + ) + } else if let Some(authenticated_application) = authenticated_application_id { + ensure!( + source == authenticated_application, + ExecutionError::UnauthenticatedTransferOwner + ) + } else { + return Err(ExecutionError::UnauthenticatedTransferOwner); } ensure!( amount > Amount::ZERO, @@ -680,7 +683,6 @@ where || authenticated_application_id == Some(source), ExecutionError::UnauthenticatedClaimOwner ), - MultiAddress::Chain => unreachable!(), } ensure!(amount > Amount::ZERO, ExecutionError::IncorrectClaimAmount); @@ -701,26 +703,22 @@ where account: &MultiAddress, amount: Amount, ) -> Result<(), ExecutionError> { - let balance = match account { - MultiAddress::Chain => self.balance.get_mut(), - other => self.balances.get_mut(other).await?.ok_or_else(|| { + let balance = if account == &MultiAddress::chain() { + self.balance.get_mut() + } else { + self.balances.get_mut(account).await?.ok_or_else(|| { ExecutionError::InsufficientFunding { balance: Amount::ZERO, } - })?, + })? }; balance .try_sub_assign(amount) .map_err(|_| ExecutionError::InsufficientFunding { balance: *balance })?; - match account { - MultiAddress::Chain => {} - other => { - if balance.is_zero() { - self.balances.remove(other)?; - } - } + if account != &MultiAddress::chain() && balance.is_zero() { + self.balances.remove(account)?; } Ok(()) @@ -741,15 +739,12 @@ where target, } => { let receiver = if context.is_bouncing { source } else { target }; - match receiver { - MultiAddress::Chain => { - let new_balance = self.balance.get().saturating_add(amount); - self.balance.set(new_balance); - } - other => { - let balance = self.balances.get_mut_or_default(&other).await?; - *balance = balance.saturating_add(amount); - } + if receiver == MultiAddress::chain() { + let new_balance = self.balance.get().saturating_add(amount); + self.balance.set(new_balance); + } else { + let balance = self.balances.get_mut_or_default(&receiver).await?; + *balance = balance.saturating_add(amount); } } Withdraw { @@ -849,7 +844,7 @@ where epoch: config.epoch, } ); - self.debit(&MultiAddress::Chain, config.balance).await?; + self.debit(&MultiAddress::chain(), config.balance).await?; let message = SystemMessage::OpenChain(config); Ok(OutgoingMessage::new(child_id, message).with_kind(MessageKind::Protected)) } diff --git a/linera-execution/tests/contract_runtime_apis.rs b/linera-execution/tests/contract_runtime_apis.rs index 40424fa74e7b..39495d28813d 100644 --- a/linera-execution/tests/contract_runtime_apis.rs +++ b/linera-execution/tests/contract_runtime_apis.rs @@ -761,7 +761,7 @@ impl TransferTestEndpoint { TransferTestEndpoint::Application => ( Amount::ZERO, vec![( - MultiAddress::Address32(Self::sender_application_id().as_address().unwrap()), + MultiAddress::Address32(Self::sender_application_id().as_address()), transfer_amount, )], None, @@ -785,7 +785,7 @@ impl TransferTestEndpoint { /// Returns the [`MultiAddress`] to represent this transfer endpoint as a sender. pub fn sender_account_owner(&self) -> MultiAddress { match self { - TransferTestEndpoint::Chain => MultiAddress::Chain, + TransferTestEndpoint::Chain => MultiAddress::chain(), TransferTestEndpoint::User => MultiAddress::Address32(Self::sender_owner().0), TransferTestEndpoint::Application => Self::sender_application_id(), } @@ -794,7 +794,7 @@ impl TransferTestEndpoint { /// Returns the [`MultiAddress`] to represent this transfer endpoint as an unauthorized sender. pub fn unauthorized_sender_account_owner(&self) -> MultiAddress { match self { - TransferTestEndpoint::Chain => MultiAddress::Chain, + TransferTestEndpoint::Chain => MultiAddress::chain(), TransferTestEndpoint::User => { MultiAddress::Address32(CryptoHash::test_hash("attacker")) } @@ -825,7 +825,7 @@ impl TransferTestEndpoint { /// Returns the [`MultiAddress`] to represent this transfer endpoint as a recipient. pub fn recipient_account_owner(&self) -> MultiAddress { match self { - TransferTestEndpoint::Chain => MultiAddress::Chain, + TransferTestEndpoint::Chain => MultiAddress::chain(), TransferTestEndpoint::User => MultiAddress::Address32(Self::recipient_owner().0), TransferTestEndpoint::Application => Self::recipient_application_id(), } @@ -838,9 +838,12 @@ impl TransferTestEndpoint { system: &SystemExecutionStateView>, amount: Amount, ) -> anyhow::Result<()> { - let (expected_chain_balance, expected_balances) = match self.recipient_account_owner() { - MultiAddress::Chain => (amount, vec![]), - account_owner => (Amount::ZERO, vec![(account_owner, amount)]), + let account_owner = self.recipient_account_owner(); + let (expected_chain_balance, expected_balances) = if account_owner == MultiAddress::chain() + { + (amount, vec![]) + } else { + (Amount::ZERO, vec![(account_owner, amount)]) }; let balances = system.balances.index_values().await?; diff --git a/linera-execution/tests/test_execution.rs b/linera-execution/tests/test_execution.rs index 65385fdb0981..72b35a6b3d96 100644 --- a/linera-execution/tests/test_execution.rs +++ b/linera-execution/tests/test_execution.rs @@ -1288,7 +1288,7 @@ async fn test_open_chain() -> anyhow::Result<()> { move |runtime, _context, _operation| { assert_eq!(runtime.chain_ownership()?, ownership); let destination = Account::chain(ChainId::root(2)); - runtime.transfer(MultiAddress::Chain, destination, Amount::ONE)?; + runtime.transfer(MultiAddress::chain(), destination, Amount::ONE)?; let id = runtime.application_id()?; let application_permissions = ApplicationPermissions::new_single(id); let (actual_message_id, chain_id) = @@ -1485,11 +1485,11 @@ async fn test_message_receipt_spending_chain_balance( let (application_id, application, blobs) = view.register_mock_application(0).await?; - let receiver_chain_account = MultiAddress::Chain; + let receiver_chain_account = MultiAddress::chain(); let sender_chain_id = ChainId::root(2); let recipient = Account { chain_id: sender_chain_id, - owner: MultiAddress::Chain, + owner: MultiAddress::chain(), }; application.expect_call(ExpectedCall::execute_message( diff --git a/linera-execution/tests/test_system_execution.rs b/linera-execution/tests/test_system_execution.rs index 292e98e103b8..fb5add87ea75 100644 --- a/linera-execution/tests/test_system_execution.rs +++ b/linera-execution/tests/test_system_execution.rs @@ -30,7 +30,7 @@ async fn test_simple_system_operation() -> anyhow::Result<()> { }; let mut view = state.into_view().await; let operation = SystemOperation::Transfer { - owner: MultiAddress::Chain, + owner: MultiAddress::chain(), amount: Amount::from_tokens(4), recipient: Recipient::Burn, }; @@ -66,8 +66,8 @@ async fn test_simple_system_message() -> anyhow::Result<()> { let mut view = state.into_view().await; let message = SystemMessage::Credit { amount: Amount::from_tokens(4), - target: MultiAddress::Chain, - source: MultiAddress::Chain, + target: MultiAddress::chain(), + source: MultiAddress::chain(), }; let context = MessageContext { chain_id: ChainId::root(0), diff --git a/linera-indexer/example/tests/test.rs b/linera-indexer/example/tests/test.rs index 3f18a98bd8f7..e96d672be769 100644 --- a/linera-indexer/example/tests/test.rs +++ b/linera-indexer/example/tests/test.rs @@ -76,7 +76,7 @@ fn indexer_running(child: &mut Child) { async fn transfer(client: &reqwest::Client, from: ChainId, to: Account, amount: &str) { let variables = transfer::Variables { chain_id: from, - owner: MultiAddress::Chain, + owner: MultiAddress::chain(), recipient_chain: to.chain_id, recipient_account: to.owner, amount: Amount::from_str(amount).unwrap(), diff --git a/linera-rpc/src/grpc/conversions.rs b/linera-rpc/src/grpc/conversions.rs index 9ec2ff19b03c..7b5f619eb701 100644 --- a/linera-rpc/src/grpc/conversions.rs +++ b/linera-rpc/src/grpc/conversions.rs @@ -1103,7 +1103,7 @@ pub mod tests { chain_id: ChainId::root(0), test_next_block_height: Some(BlockHeight::from(10)), request_committees: false, - request_owner_balance: MultiAddress::Chain, + request_owner_balance: MultiAddress::chain(), request_pending_message_bundles: false, request_sent_certificate_hashes_in_range: Some( linera_core::data_types::BlockHeightRange { diff --git a/linera-rpc/tests/format.rs b/linera-rpc/tests/format.rs index 6eb1a9fd5cbd..3bffd21a3892 100644 --- a/linera-rpc/tests/format.rs +++ b/linera-rpc/tests/format.rs @@ -6,7 +6,7 @@ use linera_base::{ crypto::{AccountPublicKey, AccountSignature, TestString}, data_types::{BlobContent, OracleResponse, Round}, hashed::Hashed, - identifiers::{BlobType, ChainDescription, Destination, GenericApplicationId, MultiAddress}, + identifiers::{BlobType, ChainDescription, Destination, MultiAddress}, ownership::ChainOwnership, vm::VmRuntime, }; @@ -67,7 +67,7 @@ fn get_registry() -> Result { tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; - tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; diff --git a/linera-rpc/tests/snapshots/format__format.yaml.snap b/linera-rpc/tests/snapshots/format__format.yaml.snap index 90fc03d0e380..eda65e80fcf2 100644 --- a/linera-rpc/tests/snapshots/format__format.yaml.snap +++ b/linera-rpc/tests/snapshots/format__format.yaml.snap @@ -351,7 +351,7 @@ ChainOwnership: ChannelFullName: STRUCT: - application_id: - TYPENAME: GenericApplicationId + TYPENAME: MultiAddress - name: TYPENAME: ChannelName ChannelName: @@ -458,14 +458,6 @@ EventId: TYPENAME: StreamId - key: SEQ: U8 -GenericApplicationId: - ENUM: - 0: - System: UNIT - 1: - User: - NEWTYPE: - TYPENAME: MultiAddress HandleConfirmedCertificateRequest: STRUCT: - certificate: @@ -604,8 +596,6 @@ MultiAddress: Address32: NEWTYPE: TYPENAME: CryptoHash - 1: - Chain: UNIT NodeError: ENUM: 0: @@ -1041,7 +1031,7 @@ Secp256k1Signature: StreamId: STRUCT: - application_id: - TYPENAME: GenericApplicationId + TYPENAME: MultiAddress - stream_name: TYPENAME: StreamName StreamName: diff --git a/linera-sdk/src/base/conversions_from_wit.rs b/linera-sdk/src/base/conversions_from_wit.rs index 610f0b5899c0..eb89d59f6503 100644 --- a/linera-sdk/src/base/conversions_from_wit.rs +++ b/linera-sdk/src/base/conversions_from_wit.rs @@ -41,7 +41,6 @@ macro_rules! impl_from_wit { $wit_base_api::MultiAddress::Address32(owner) => { MultiAddress::Address32(owner.into()) } - $wit_base_api::MultiAddress::Chain => MultiAddress::Chain, } } } diff --git a/linera-sdk/src/base/conversions_to_wit.rs b/linera-sdk/src/base/conversions_to_wit.rs index 82d2c0d37bbf..7e668c261c04 100644 --- a/linera-sdk/src/base/conversions_to_wit.rs +++ b/linera-sdk/src/base/conversions_to_wit.rs @@ -44,7 +44,6 @@ macro_rules! impl_to_wit { MultiAddress::Address32(owner) => { $wit_base_api::MultiAddress::Address32(owner.into()) } - MultiAddress::Chain => $wit_base_api::MultiAddress::Chain, } } } diff --git a/linera-sdk/src/contract/conversions_from_wit.rs b/linera-sdk/src/contract/conversions_from_wit.rs index 61a5e8f2ebb5..34ca0978248e 100644 --- a/linera-sdk/src/contract/conversions_from_wit.rs +++ b/linera-sdk/src/contract/conversions_from_wit.rs @@ -65,7 +65,6 @@ impl From for MultiAddress { wit_contract_api::MultiAddress::Address32(owner) => { MultiAddress::Address32(owner.into()) } - wit_contract_api::MultiAddress::Chain => MultiAddress::Chain, } } } diff --git a/linera-sdk/src/contract/conversions_to_wit.rs b/linera-sdk/src/contract/conversions_to_wit.rs index 8676887cc9e4..5a95dbb46178 100644 --- a/linera-sdk/src/contract/conversions_to_wit.rs +++ b/linera-sdk/src/contract/conversions_to_wit.rs @@ -69,7 +69,6 @@ impl From for wit_contract_api::MultiAddress { MultiAddress::Address32(owner) => { wit_contract_api::MultiAddress::Address32(owner.into()) } - MultiAddress::Chain => wit_contract_api::MultiAddress::Chain, } } } diff --git a/linera-sdk/src/contract/test_runtime.rs b/linera-sdk/src/contract/test_runtime.rs index 092cdde6fcd9..c3eccf93eefc 100644 --- a/linera-sdk/src/contract/test_runtime.rs +++ b/linera-sdk/src/contract/test_runtime.rs @@ -515,9 +515,10 @@ where /// Debits an `amount` of native tokens from a `source` owner account (or the current /// chain's balance). fn debit(&mut self, source: MultiAddress, amount: Amount) { - let source_balance = match source { - MultiAddress::Address32(_) => self.owner_balance_mut(source), - MultiAddress::Chain => self.chain_balance_mut(), + let source_balance = if source == MultiAddress::chain() { + self.chain_balance_mut() + } else { + self.owner_balance_mut(source) }; *source_balance = source_balance @@ -528,9 +529,10 @@ where /// Credits an `amount` of native tokens into a `destination` owner account (or the /// current chain's balance). fn credit(&mut self, destination: MultiAddress, amount: Amount) { - let destination_balance = match destination { - owner @ MultiAddress::Address32(_) => self.owner_balance_mut(owner), - MultiAddress::Chain => self.chain_balance_mut(), + let destination_balance = if destination == MultiAddress::chain() { + self.chain_balance_mut() + } else { + self.owner_balance_mut(destination) }; *destination_balance = destination_balance diff --git a/linera-sdk/src/service/conversions_to_wit.rs b/linera-sdk/src/service/conversions_to_wit.rs index 5a8da11c53ab..57d81f420e8f 100644 --- a/linera-sdk/src/service/conversions_to_wit.rs +++ b/linera-sdk/src/service/conversions_to_wit.rs @@ -26,7 +26,6 @@ impl From for wit_service_api::MultiAddress { MultiAddress::Address32(owner) => { wit_service_api::MultiAddress::Address32(owner.into()) } - MultiAddress::Chain => wit_service_api::MultiAddress::Chain, } } } diff --git a/linera-sdk/src/test/block.rs b/linera-sdk/src/test/block.rs index e82d00240631..e532ccdbaf12 100644 --- a/linera-sdk/src/test/block.rs +++ b/linera-sdk/src/test/block.rs @@ -9,9 +9,7 @@ use linera_base::{ abi::ContractAbi, data_types::{Amount, ApplicationPermissions, Blob, Round, Timestamp}, hashed::Hashed, - identifiers::{ - ApplicationId, ChainId, ChannelFullName, GenericApplicationId, MultiAddress, Owner, - }, + identifiers::{ApplicationId, ChainId, ChannelFullName, MultiAddress, Owner}, ownership::TimeoutConfig, }; use linera_chain::{ @@ -186,7 +184,7 @@ impl BlockBuilder { channel: SystemChannel, ) -> &mut Self { let medium = Medium::Channel(ChannelFullName { - application_id: GenericApplicationId::System, + application_id: MultiAddress::chain(), name: channel.name(), }); self.with_messages_from_by_medium(certificate, &medium, MessageAction::Accept) diff --git a/linera-sdk/wit/base-runtime-api.wit b/linera-sdk/wit/base-runtime-api.wit index 791b59185609..d383801bdeb2 100644 --- a/linera-sdk/wit/base-runtime-api.wit +++ b/linera-sdk/wit/base-runtime-api.wit @@ -97,7 +97,6 @@ interface base-runtime-api { variant multi-address { address32(crypto-hash), - chain, } record owner { diff --git a/linera-sdk/wit/contract-runtime-api.wit b/linera-sdk/wit/contract-runtime-api.wit index 39bfaaca0dfb..dc7b0215945e 100644 --- a/linera-sdk/wit/contract-runtime-api.wit +++ b/linera-sdk/wit/contract-runtime-api.wit @@ -93,7 +93,6 @@ interface contract-runtime-api { variant multi-address { address32(crypto-hash), - chain, } record owner { diff --git a/linera-sdk/wit/service-runtime-api.wit b/linera-sdk/wit/service-runtime-api.wit index 500e9c1a6db9..c77402bbbbb0 100644 --- a/linera-sdk/wit/service-runtime-api.wit +++ b/linera-sdk/wit/service-runtime-api.wit @@ -14,6 +14,5 @@ interface service-runtime-api { variant multi-address { address32(crypto-hash), - chain, } } diff --git a/linera-service-graphql-client/gql/service_schema.graphql b/linera-service-graphql-client/gql/service_schema.graphql index 079a48752a99..7c53914c0536 100644 --- a/linera-service-graphql-client/gql/service_schema.graphql +++ b/linera-service-graphql-client/gql/service_schema.graphql @@ -531,11 +531,6 @@ type ExecutionStateView { } -""" -A unique identifier for a user application or for the system application -""" -scalar GenericApplicationId - type HashedConfirmedBlock { hash: CryptoHash! value: ConfirmedBlock! @@ -725,7 +720,7 @@ A unique identifier for an application module scalar ModuleId """ -An owner of an account. +A unique identifier for a user or an application. """ scalar MultiAddress @@ -1172,7 +1167,7 @@ type StreamId { """ The application that can add events to this stream. """ - applicationId: GenericApplicationId! + applicationId: MultiAddress! """ The name of this stream: an application can have multiple streams with different names. """ diff --git a/linera-service-graphql-client/src/service.rs b/linera-service-graphql-client/src/service.rs index 3925594b6948..c0de5231142a 100644 --- a/linera-service-graphql-client/src/service.rs +++ b/linera-service-graphql-client/src/service.rs @@ -6,8 +6,8 @@ use linera_base::{ crypto::CryptoHash, data_types::{Amount, Blob, BlockHeight, OracleResponse, Round, Timestamp}, identifiers::{ - Account, BlobId, ChainDescription, ChainId, ChannelName, Destination, GenericApplicationId, - MultiAddress, Owner, StreamName, + Account, BlobId, ChainDescription, ChainId, ChannelName, Destination, MultiAddress, Owner, + StreamName, }, }; diff --git a/linera-service-graphql-client/tests/test.rs b/linera-service-graphql-client/tests/test.rs index ffc3e27e86d4..01be75b12724 100644 --- a/linera-service-graphql-client/tests/test.rs +++ b/linera-service-graphql-client/tests/test.rs @@ -38,7 +38,7 @@ fn reqwest_client() -> reqwest::Client { async fn transfer(client: &reqwest::Client, url: &str, from: ChainId, to: Account, amount: &str) { let variables = transfer::Variables { chain_id: from, - owner: MultiAddress::Chain, + owner: MultiAddress::chain(), recipient_chain: to.chain_id, recipient_account: to.owner, amount: Amount::from_str(amount).unwrap(), diff --git a/linera-service/benches/transfers.rs b/linera-service/benches/transfers.rs index 349dea385da7..cba6a40d2586 100644 --- a/linera-service/benches/transfers.rs +++ b/linera-service/benches/transfers.rs @@ -88,7 +88,7 @@ async fn setup_native_token_balances( admin_chain .add_block(|block| { block.with_native_token_transfer( - MultiAddress::Chain, + MultiAddress::chain(), recipient, Amount::from_tokens(initial_balance), ); diff --git a/linera-service/src/linera/main.rs b/linera-service/src/linera/main.rs index 34342e8507c2..421488eff342 100644 --- a/linera-service/src/linera/main.rs +++ b/linera-service/src/linera/main.rs @@ -281,10 +281,12 @@ impl Runnable for Job { info!("Reading the balance of {} from the local state", account); let time_start = Instant::now(); let balance = match account.owner { + MultiAddress::Address32(_) if account.owner == MultiAddress::chain() => { + chain_client.local_balance().await? + } MultiAddress::Address32(_) => { chain_client.local_owner_balance(account.owner).await? } - MultiAddress::Chain => chain_client.local_balance().await?, }; let time_total = time_start.elapsed(); info!("Local balance obtained after {} ms", time_total.as_millis()); @@ -300,10 +302,12 @@ impl Runnable for Job { ); let time_start = Instant::now(); let balance = match account.owner { + MultiAddress::Address32(_) if account.owner == MultiAddress::chain() => { + chain_client.query_balance().await? + } MultiAddress::Address32(_) => { chain_client.query_owner_balance(account.owner).await? } - MultiAddress::Chain => chain_client.query_balance().await?, }; let time_total = time_start.elapsed(); info!("Balance obtained after {} ms", time_total.as_millis()); @@ -318,10 +322,12 @@ impl Runnable for Job { let time_start = Instant::now(); chain_client.synchronize_from_validators().await?; let result = match account.owner { + MultiAddress::Address32(_) if account.owner == MultiAddress::chain() => { + chain_client.query_balance().await + } MultiAddress::Address32(_) => { chain_client.query_owner_balance(account.owner).await } - MultiAddress::Chain => chain_client.query_balance().await, }; context.update_wallet_from_client(&chain_client).await?; let balance = result.context("Failed to synchronize from validators")?;