diff --git a/examples/amm/src/contract.rs b/examples/amm/src/contract.rs index cef6457044c3..47e27ee5e198 100644 --- a/examples/amm/src/contract.rs +++ b/examples/amm/src/contract.rs @@ -326,6 +326,9 @@ impl AmmContract { "Unauthorized" ) } + AccountOwner::Chain => { + panic!("Using chain balance is not authorized") + } } } diff --git a/examples/fungible/src/contract.rs b/examples/fungible/src/contract.rs index db3c9c1ea347..8362b1496458 100644 --- a/examples/fungible/src/contract.rs +++ b/examples/fungible/src/contract.rs @@ -143,6 +143,9 @@ impl FungibleTokenContract { "The requested transfer is not correctly authenticated." ) } + AccountOwner::Chain => { + panic!("Chain account is not supported") + } } } diff --git a/examples/gen-nft/src/contract.rs b/examples/gen-nft/src/contract.rs index 8d5f9b420acd..3b989d798f08 100644 --- a/examples/gen-nft/src/contract.rs +++ b/examples/gen-nft/src/contract.rs @@ -140,6 +140,9 @@ impl GenNftContract { "The requested transfer is not correctly authenticated." ) } + AccountOwner::Chain => { + panic!("Chain account is not supported") + } } } diff --git a/examples/matching-engine/src/contract.rs b/examples/matching-engine/src/contract.rs index 5462238ae279..c879214a8312 100644 --- a/examples/matching-engine/src/contract.rs +++ b/examples/matching-engine/src/contract.rs @@ -166,6 +166,9 @@ impl MatchingEngineContract { "Unauthorized" ) } + AccountOwner::Chain => { + panic!("Chain account is not supported") + } } } diff --git a/examples/native-fungible/src/contract.rs b/examples/native-fungible/src/contract.rs index f80b1882cbe5..e5df39565d9b 100644 --- a/examples/native-fungible/src/contract.rs +++ b/examples/native-fungible/src/contract.rs @@ -38,9 +38,9 @@ impl Contract for NativeFungibleTokenContract { for (owner, amount) in state.accounts { let account = Account { chain_id: self.runtime.chain_id(), - owner: Some(owner), + owner, }; - self.runtime.transfer(None, account, amount); + self.runtime.transfer(AccountOwner::Chain, account, amount); } } @@ -63,7 +63,7 @@ impl Contract for NativeFungibleTokenContract { let fungible_target_account = target_account; let target_account = self.normalize_account(target_account); - self.runtime.transfer(Some(owner), target_account, amount); + self.runtime.transfer(owner, target_account, amount); self.transfer(fungible_target_account.chain_id); FungibleResponse::Ok @@ -129,7 +129,7 @@ impl NativeFungibleTokenContract { fn normalize_account(&self, account: fungible::Account) -> Account { Account { chain_id: account.chain_id, - owner: Some(account.owner), + owner: account.owner, } } @@ -144,6 +144,9 @@ impl NativeFungibleTokenContract { ); } AccountOwner::Application(_) => panic!("Applications not supported yet"), + AccountOwner::Chain => { + panic!("Chain accounts are not supported") + } } } } diff --git a/examples/non-fungible/src/contract.rs b/examples/non-fungible/src/contract.rs index 765ca97e866f..569c1352e310 100644 --- a/examples/non-fungible/src/contract.rs +++ b/examples/non-fungible/src/contract.rs @@ -144,6 +144,9 @@ impl NonFungibleTokenContract { "The requested transfer is not correctly authenticated." ) } + AccountOwner::Chain => { + panic!("Chain account is not supported") + } } } diff --git a/linera-base/src/identifiers.rs b/linera-base/src/identifiers.rs index cabbe90626f3..590fb58182a2 100644 --- a/linera-base/src/identifiers.rs +++ b/linera-base/src/identifiers.rs @@ -37,7 +37,9 @@ pub enum AccountOwner { /// An account owned by a user. User(Owner), /// An account for an application. - Application(ApplicationId), + Application(UserApplicationId), + /// Chain account. + Chain, } /// A system account. @@ -48,8 +50,7 @@ pub struct Account { /// The chain of the account. pub chain_id: ChainId, /// The owner of the account, or `None` for the chain balance. - #[debug(skip_if = Option::is_none)] - pub owner: Option, + pub owner: AccountOwner, } impl Account { @@ -57,7 +58,7 @@ impl Account { pub fn chain(chain_id: ChainId) -> Self { Account { chain_id, - owner: None, + owner: AccountOwner::Chain, } } @@ -65,17 +66,14 @@ impl Account { pub fn owner(chain_id: ChainId, owner: impl Into) -> Self { Account { chain_id, - owner: Some(owner.into()), + owner: owner.into(), } } } impl Display for Account { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.owner { - Some(owner) => write!(f, "{}:{}", self.chain_id, owner), - None => write!(f, "{}", self.chain_id), - } + write!(f, "{}:{}", self.chain_id, self.owner) } } @@ -306,7 +304,7 @@ pub struct ApplicationId { /// Alias for `ApplicationId`. Use this alias in the core /// protocol where the distinction with the more general enum `GenericApplicationId` matters. -pub type UserApplicationId = ApplicationId; +pub type UserApplicationId = ApplicationId<()>; /// A unique identifier for an application. #[derive( @@ -328,7 +326,7 @@ pub enum GenericApplicationId { /// The system application. System, /// A user application. - User(ApplicationId), + User(UserApplicationId), } impl GenericApplicationId { @@ -951,6 +949,7 @@ impl<'de> serde::de::Visitor<'de> for OwnerVisitor { enum SerializableAccountOwner { User(Owner), Application(ApplicationId), + Chain, } impl Serialize for AccountOwner { @@ -961,6 +960,7 @@ impl Serialize for AccountOwner { match self { AccountOwner::Application(app_id) => SerializableAccountOwner::Application(*app_id), AccountOwner::User(owner) => SerializableAccountOwner::User(*owner), + AccountOwner::Chain => SerializableAccountOwner::Chain, } .serialize(serializer) } @@ -980,6 +980,7 @@ impl<'de> Deserialize<'de> for AccountOwner { Ok(AccountOwner::Application(app_id)) } SerializableAccountOwner::User(owner) => Ok(AccountOwner::User(owner)), + SerializableAccountOwner::Chain => Ok(AccountOwner::Chain), } } } @@ -990,6 +991,7 @@ impl Display for AccountOwner { match self { AccountOwner::User(owner) => write!(f, "User:{}", owner)?, AccountOwner::Application(app_id) => write!(f, "Application:{}", app_id)?, + AccountOwner::Chain => write!(f, "Chain")?, }; Ok(()) @@ -1008,6 +1010,8 @@ impl FromStr for AccountOwner { Ok(AccountOwner::Application( ApplicationId::from_str(app_id).context("Getting ApplicationId should not fail")?, )) + } else if s.strip_prefix("Chain").is_some() { + Ok(AccountOwner::Chain) } else { Err(anyhow!("Invalid enum! Enum: {}", s)) } diff --git a/linera-base/src/unit_tests.rs b/linera-base/src/unit_tests.rs index 5756286130c4..e2fbb5731470 100644 --- a/linera-base/src/unit_tests.rs +++ b/linera-base/src/unit_tests.rs @@ -85,7 +85,7 @@ fn send_message_request_test_case() -> SendMessageRequest> { fn account_test_case() -> Account { Account { chain_id: ChainId::root(10), - owner: Some(AccountOwner::User(Owner(CryptoHash::test_hash("account")))), + owner: AccountOwner::User(Owner(CryptoHash::test_hash("account"))), } } diff --git a/linera-core/src/chain_worker/state/temporary_changes.rs b/linera-core/src/chain_worker/state/temporary_changes.rs index 04a8bc984809..77cc392d2c7c 100644 --- a/linera-core/src/chain_worker/state/temporary_changes.rs +++ b/linera-core/src/chain_worker/state/temporary_changes.rs @@ -219,9 +219,14 @@ where if query.request_committees { info.requested_committees = Some(chain.execution_state.system.committees.get().clone()); } - if let Some(owner) = query.request_owner_balance { - info.requested_owner_balance = - chain.execution_state.system.balances.get(&owner).await?; + match query.request_owner_balance { + owner @ AccountOwner::Application(_) | owner @ AccountOwner::User(_) => { + info.requested_owner_balance = + chain.execution_state.system.balances.get(&owner).await?; + } + AccountOwner::Chain => { + info.requested_owner_balance = Some(*chain.execution_state.system.balance.get()); + } } if let Some(next_block_height) = query.test_next_block_height { ensure!( diff --git a/linera-core/src/client/mod.rs b/linera-core/src/client/mod.rs index feb46bb14433..a70366b074d0 100644 --- a/linera-core/src/client/mod.rs +++ b/linera-core/src/client/mod.rs @@ -2260,7 +2260,7 @@ where #[instrument(level = "trace", skip(application_id, query))] pub async fn query_user_application( &self, - application_id: UserApplicationId, + application_id: ApplicationId, query: &A::Query, ) -> Result, ChainClientError> { let query = Query::user(application_id, query)?; @@ -2294,7 +2294,7 @@ where /// block. #[instrument(level = "trace")] pub async fn query_balance(&self) -> Result { - let (balance, _) = self.query_balances_with_owner(None).await?; + let (balance, _) = self.query_balances_with_owner(AccountOwner::Chain).await?; Ok(balance) } @@ -2310,7 +2310,7 @@ where owner: AccountOwner, ) -> Result { Ok(self - .query_balances_with_owner(Some(owner)) + .query_balances_with_owner(owner) .await? .1 .unwrap_or(Amount::ZERO)) @@ -2325,7 +2325,7 @@ where #[instrument(level = "trace", skip(owner))] async fn query_balances_with_owner( &self, - owner: Option, + owner: AccountOwner, ) -> Result<(Amount, Option), ChainClientError> { let incoming_bundles = self.pending_message_bundles().await?; let (previous_block_hash, height, timestamp) = { @@ -2343,10 +2343,11 @@ where operations: Vec::new(), previous_block_hash, height, - authenticated_signer: owner.and_then(|owner| match owner { + authenticated_signer: match owner { AccountOwner::User(user) => Some(user), AccountOwner::Application(_) => None, - }), + AccountOwner::Chain => None, // These should be unreachable? + }, timestamp, }; match self @@ -2382,7 +2383,7 @@ 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(None).await?; + let (balance, _) = self.local_balances_with_owner(AccountOwner::Chain).await?; Ok(balance) } @@ -2395,7 +2396,7 @@ where owner: AccountOwner, ) -> Result { Ok(self - .local_balances_with_owner(Some(owner)) + .local_balances_with_owner(owner) .await? .1 .unwrap_or(Amount::ZERO)) @@ -2407,7 +2408,7 @@ where #[instrument(level = "trace", skip(owner))] async fn local_balances_with_owner( &self, - owner: Option, + owner: AccountOwner, ) -> Result<(Amount, Option), ChainClientError> { let next_block_height = self.next_block_height(); ensure!( @@ -2936,7 +2937,7 @@ where parameters: &Parameters, instantiation_argument: &InstantiationArgument, required_application_ids: Vec, - ) -> Result, ConfirmedBlockCertificate)>, ChainClientError> + ) -> Result, ConfirmedBlockCertificate)>, ChainClientError> { let instantiation_argument = serde_json::to_vec(instantiation_argument)?; let parameters = serde_json::to_vec(parameters)?; diff --git a/linera-core/src/data_types.rs b/linera-core/src/data_types.rs index 3c5ad0c2256d..0d93c00e0432 100644 --- a/linera-core/src/data_types.rs +++ b/linera-core/src/data_types.rs @@ -71,8 +71,7 @@ pub struct ChainInfoQuery { #[debug(skip_if = Option::is_none)] pub test_next_block_height: Option, /// Request the balance of a given [`AccountOwner`]. - #[debug(skip_if = Option::is_none)] - pub request_owner_balance: Option, + pub request_owner_balance: AccountOwner, /// Query the current committees. #[debug(skip_if = Not::not)] pub request_committees: bool, @@ -102,7 +101,7 @@ impl ChainInfoQuery { chain_id, test_next_block_height: None, request_committees: false, - request_owner_balance: None, + request_owner_balance: AccountOwner::Chain, request_pending_message_bundles: false, request_sent_certificate_hashes_in_range: None, request_received_log_excluding_first_n: None, @@ -123,7 +122,7 @@ impl ChainInfoQuery { } pub fn with_owner_balance(mut self, owner: AccountOwner) -> Self { - self.request_owner_balance = Some(owner); + self.request_owner_balance = owner; self } diff --git a/linera-core/src/unit_tests/client_tests.rs b/linera-core/src/unit_tests/client_tests.rs index c29f843d328f..b7684dc224c5 100644 --- a/linera-core/src/unit_tests/client_tests.rs +++ b/linera-core/src/unit_tests/client_tests.rs @@ -195,10 +195,7 @@ where Amount::from_tokens(3) ); assert_eq!( - receiver - .local_balances_with_owner(Some(owner)) - .await - .unwrap(), + receiver.local_balances_with_owner(owner).await.unwrap(), (Amount::ZERO, Some(Amount::from_tokens(3))) ); assert_eq!(receiver.query_balance().await.unwrap(), Amount::ZERO); @@ -207,10 +204,7 @@ where Amount::from_millis(2999) ); assert_eq!( - receiver - .query_balances_with_owner(Some(owner)) - .await - .unwrap(), + receiver.query_balances_with_owner(owner).await.unwrap(), (Amount::ZERO, Some(Amount::from_millis(2999))) ); diff --git a/linera-core/src/unit_tests/worker_tests.rs b/linera-core/src/unit_tests/worker_tests.rs index e926fa7134ce..98e50ac30c26 100644 --- a/linera-core/src/unit_tests/worker_tests.rs +++ b/linera-core/src/unit_tests/worker_tests.rs @@ -323,7 +323,9 @@ where account.chain_id, MessageKind::Tracked, SystemMessage::Credit { - source: source.map(AccountOwner::User), + source: source + .map(AccountOwner::User) + .unwrap_or(AccountOwner::Chain), target: account.owner, amount, }, @@ -371,16 +373,16 @@ fn direct_outgoing_message( fn system_credit_message(amount: Amount) -> Message { Message::System(SystemMessage::Credit { - source: None, - target: None, + source: AccountOwner::Chain, + target: AccountOwner::Chain, amount, }) } fn direct_credit_message(recipient: ChainId, amount: Amount) -> OutgoingMessage { let message = SystemMessage::Credit { - source: None, - target: None, + source: AccountOwner::Chain, + target: AccountOwner::Chain, amount, }; direct_outgoing_message(recipient, MessageKind::Tracked, message) @@ -2090,14 +2092,14 @@ where let sender = Owner::from(sender_key_pair.public()); let sender_account = Account { chain_id: ChainId::root(1), - owner: Some(AccountOwner::User(sender)), + owner: AccountOwner::User(sender), }; let recipient_key_pair = AccountSecretKey::generate(); let recipient = Owner::from(sender_key_pair.public()); let recipient_account = Account { chain_id: ChainId::root(2), - owner: Some(AccountOwner::User(recipient)), + owner: AccountOwner::User(recipient), }; let (committee, worker) = init_worker_with_chains( @@ -2152,8 +2154,8 @@ where timestamp: Timestamp::from(0), transaction_index: 0, messages: vec![Message::System(SystemMessage::Credit { - source: None, - target: Some(AccountOwner::User(sender)), + source: AccountOwner::Chain, + target: AccountOwner::User(sender), amount: Amount::from_tokens(5), }) .to_posted(0, MessageKind::Tracked)], @@ -2233,8 +2235,8 @@ where timestamp: Timestamp::from(0), transaction_index: 0, messages: vec![Message::System(SystemMessage::Credit { - source: Some(AccountOwner::User(sender)), - target: Some(AccountOwner::User(recipient)), + source: AccountOwner::User(sender), + target: AccountOwner::User(recipient), amount: Amount::from_tokens(3), }) .to_posted(0, MessageKind::Tracked)], @@ -2249,8 +2251,8 @@ where timestamp: Timestamp::from(0), transaction_index: 0, messages: vec![Message::System(SystemMessage::Credit { - source: Some(AccountOwner::User(sender)), - target: Some(AccountOwner::User(recipient)), + source: AccountOwner::User(sender), + target: AccountOwner::User(recipient), amount: Amount::from_tokens(2), }) .to_posted(0, MessageKind::Tracked)], @@ -2291,8 +2293,8 @@ where timestamp: Timestamp::from(0), transaction_index: 0, messages: vec![Message::System(SystemMessage::Credit { - source: Some(AccountOwner::User(sender)), - target: Some(AccountOwner::User(recipient)), + source: AccountOwner::User(sender), + target: AccountOwner::User(recipient), amount: Amount::from_tokens(3), }) .to_posted(0, MessageKind::Bouncing)], diff --git a/linera-execution/src/execution.rs b/linera-execution/src/execution.rs index da55c8b64f57..c11197ebaf71 100644 --- a/linera-execution/src/execution.rs +++ b/linera-execution/src/execution.rs @@ -401,7 +401,10 @@ where kind: MessageKind::Tracked, message: SystemMessage::Credit { amount, - source: context.authenticated_signer.map(AccountOwner::User), + source: context + .authenticated_signer + .map(AccountOwner::User) + .unwrap_or(AccountOwner::Chain), target: account.owner, }, }; diff --git a/linera-execution/src/execution_state_actor.rs b/linera-execution/src/execution_state_actor.rs index 3ca8e7202951..a2c3403c126c 100644 --- a/linera-execution/src/execution_state_actor.rs +++ b/linera-execution/src/execution_state_actor.rs @@ -196,14 +196,13 @@ where application_id, callback, } => { - let owner = source.owner.ok_or(ExecutionError::OwnerIsNone)?; let mut execution_outcome = RawExecutionOutcome::default(); let message = self .system .claim( signer, Some(application_id), - owner, + source.owner, source.chain_id, Recipient::Account(destination), amount, @@ -551,8 +550,7 @@ pub enum ExecutionRequest { }, Transfer { - #[debug(skip_if = Option::is_none)] - source: Option, + source: AccountOwner, destination: Account, amount: Amount, #[debug(skip_if = Option::is_none)] diff --git a/linera-execution/src/lib.rs b/linera-execution/src/lib.rs index 9f72b25c1974..5ec92de95d6d 100644 --- a/linera-execution/src/lib.rs +++ b/linera-execution/src/lib.rs @@ -711,7 +711,7 @@ pub trait ContractRuntime: BaseRuntime { /// Transfers amount from source to destination. fn transfer( &mut self, - source: Option, + source: AccountOwner, destination: Account, amount: Amount, ) -> Result<(), ExecutionError>; @@ -1028,10 +1028,12 @@ impl RawOutgoingMessage { } impl OperationContext { + /// Returns an account for the refund. + /// Returns `None` if there is no authenticated signer of the [`OperationContext`]. fn refund_grant_to(&self) -> Option { - Some(Account { + self.authenticated_signer.map(|owner| Account { chain_id: self.chain_id, - owner: self.authenticated_signer.map(AccountOwner::User), + owner: AccountOwner::User(owner), }) } @@ -1176,7 +1178,7 @@ impl Operation { /// Creates a new user application operation following the `application_id`'s [`Abi`]. #[cfg(with_testing)] pub fn user( - application_id: UserApplicationId, + application_id: ApplicationId, operation: &A::Operation, ) -> Result { Self::user_without_abi(application_id.forget_abi(), operation) @@ -1186,7 +1188,7 @@ impl Operation { /// `application_id`. #[cfg(with_testing)] pub fn user_without_abi( - application_id: UserApplicationId<()>, + application_id: ApplicationId<()>, operation: &impl Serialize, ) -> Result { Ok(Operation::User { @@ -1234,7 +1236,7 @@ impl Message { /// Creates a new user application message assuming that the `message` is valid for the /// `application_id`. pub fn user( - application_id: UserApplicationId, + application_id: ApplicationId, message: &M, ) -> Result { let application_id = application_id.forget_abi(); @@ -1299,7 +1301,7 @@ impl Query { /// Creates a new user application query following the `application_id`'s [`Abi`]. pub fn user( - application_id: UserApplicationId, + application_id: ApplicationId, query: &A::Query, ) -> Result { Self::user_without_abi(application_id.forget_abi(), query) @@ -1308,7 +1310,7 @@ impl Query { /// Creates a new user application query assuming that the `query` is valid for the /// `application_id`. pub fn user_without_abi( - application_id: UserApplicationId<()>, + application_id: ApplicationId<()>, query: &impl Serialize, ) -> Result { Ok(Query::User { diff --git a/linera-execution/src/runtime.rs b/linera-execution/src/runtime.rs index d1e0a13235cc..1fb5a2d18e67 100644 --- a/linera-execution/src/runtime.rs +++ b/linera-execution/src/runtime.rs @@ -1272,7 +1272,7 @@ impl ContractRuntime for ContractSyncRuntimeHandle { fn transfer( &mut self, - source: Option, + source: AccountOwner, destination: Account, amount: Amount, ) -> Result<(), ExecutionError> { diff --git a/linera-execution/src/system.rs b/linera-execution/src/system.rs index 35ea03a64a21..3af1132eb566 100644 --- a/linera-execution/src/system.rs +++ b/linera-execution/src/system.rs @@ -210,11 +210,9 @@ pub enum SystemMessage { /// Credits `amount` units of value to the account `target` -- unless the message is /// bouncing, in which case `source` is credited instead. Credit { - #[debug(skip_if = Option::is_none)] - target: Option, + target: AccountOwner, amount: Amount, - #[debug(skip_if = Option::is_none)] - source: Option, + source: AccountOwner, }, /// Withdraws `amount` units of value from the account and starts a transfer to credit /// the recipient. The message must be properly authenticated. Receiver chains may @@ -419,7 +417,7 @@ where .transfer( context.authenticated_signer, None, - owner.map(AccountOwner::User), + owner.map(AccountOwner::User).unwrap_or(AccountOwner::Chain), recipient, amount, ) @@ -645,24 +643,22 @@ where &mut self, authenticated_signer: Option, authenticated_application_id: Option, - source: Option, + source: AccountOwner, recipient: Recipient, amount: Amount, ) -> Result>, ExecutionError> { match (source, authenticated_signer, authenticated_application_id) { - (Some(AccountOwner::User(owner)), Some(signer), _) => ensure!( + (AccountOwner::User(owner), Some(signer), _) => ensure!( signer == owner, ExecutionError::UnauthenticatedTransferOwner ), - ( - Some(AccountOwner::Application(account_application)), - _, - Some(authorized_application), - ) => ensure!( - account_application == authorized_application, - ExecutionError::UnauthenticatedTransferOwner - ), - (None, Some(signer), _) => ensure!( + (AccountOwner::Application(account_application), _, Some(authorized_application)) => { + ensure!( + account_application == authorized_application, + ExecutionError::UnauthenticatedTransferOwner + ) + } + (AccountOwner::Chain, Some(signer), _) => ensure!( self.ownership.get().verify_owner(&signer), ExecutionError::UnauthenticatedTransferOwner ), @@ -672,7 +668,7 @@ where amount > Amount::ZERO, ExecutionError::IncorrectTransferAmount ); - self.debit(source.as_ref(), amount).await?; + self.debit(&source, amount).await?; match recipient { Recipient::Account(account) => { let message = RawOutgoingMessage { @@ -711,6 +707,7 @@ where authenticated_application_id == Some(owner), ExecutionError::UnauthenticatedClaimOwner ), + AccountOwner::Chain => unreachable!(), } ensure!(amount > Amount::ZERO, ExecutionError::IncorrectClaimAmount); @@ -730,26 +727,28 @@ where /// Debits an [`Amount`] of tokens from an account's balance. async fn debit( &mut self, - account: Option<&AccountOwner>, + account: &AccountOwner, amount: Amount, ) -> Result<(), ExecutionError> { - let balance = if let Some(owner) = account { - self.balances.get_mut(owner).await?.ok_or_else(|| { + let balance = match account { + AccountOwner::Chain => self.balance.get_mut(), + other => self.balances.get_mut(other).await?.ok_or_else(|| { ExecutionError::InsufficientFunding { balance: Amount::ZERO, } - })? - } else { - self.balance.get_mut() + })?, }; balance .try_sub_assign(amount) .map_err(|_| ExecutionError::InsufficientFunding { balance: *balance })?; - if let Some(owner) = account { - if balance.is_zero() { - self.balances.remove(owner)?; + match account { + AccountOwner::Chain => {} + other => { + if balance.is_zero() { + self.balances.remove(other)?; + } } } @@ -772,12 +771,12 @@ where } => { let receiver = if context.is_bouncing { source } else { target }; match receiver { - None => { + AccountOwner::Chain => { let new_balance = self.balance.get().saturating_add(amount); self.balance.set(new_balance); } - Some(owner) => { - let balance = self.balances.get_mut_or_default(&owner).await?; + other => { + let balance = self.balances.get_mut_or_default(&other).await?; *balance = balance.saturating_add(amount); } } @@ -787,7 +786,7 @@ where owner, recipient, } => { - self.debit(Some(&owner), amount).await?; + self.debit(&owner, amount).await?; match recipient { Recipient::Account(account) => { let message = RawOutgoingMessage { @@ -797,7 +796,7 @@ where kind: MessageKind::Tracked, message: SystemMessage::Credit { amount, - source: Some(owner), + source: owner, target: account.owner, }, }; @@ -882,7 +881,7 @@ where epoch: config.epoch, } ); - self.debit(None, config.balance).await?; + self.debit(&AccountOwner::Chain, config.balance).await?; let open_chain_message = RawOutgoingMessage { destination: Destination::Recipient(child_id), authenticated: false, diff --git a/linera-execution/src/unit_tests/system_tests.rs b/linera-execution/src/unit_tests/system_tests.rs index 02394494d207..01ebc81501b7 100644 --- a/linera-execution/src/unit_tests/system_tests.rs +++ b/linera-execution/src/unit_tests/system_tests.rs @@ -129,7 +129,7 @@ async fn empty_accounts_are_removed() -> anyhow::Result<()> { .into_view() .await; - view.system.debit(Some(&owner), amount).await?; + view.system.debit(&owner, amount).await?; assert!(view.system.balances.indices().await?.is_empty()); diff --git a/linera-execution/src/wasm/runtime_api.rs b/linera-execution/src/wasm/runtime_api.rs index b6b755da8830..4b3eaa4c74ce 100644 --- a/linera-execution/src/wasm/runtime_api.rs +++ b/linera-execution/src/wasm/runtime_api.rs @@ -471,7 +471,7 @@ where /// balance) to `destination`. fn transfer( caller: &mut Caller, - source: Option, + source: AccountOwner, destination: Account, amount: Amount, ) -> Result<(), RuntimeError> { diff --git a/linera-execution/tests/contract_runtime_apis.rs b/linera-execution/tests/contract_runtime_apis.rs index 7611304d7b3d..ad93d9a3fccf 100644 --- a/linera-execution/tests/contract_runtime_apis.rs +++ b/linera-execution/tests/contract_runtime_apis.rs @@ -788,25 +788,25 @@ impl TransferTestEndpoint { } /// Returns the [`AccountOwner`] to represent this transfer endpoint as a sender. - pub fn sender_account_owner(&self) -> Option { + pub fn sender_account_owner(&self) -> AccountOwner { match self { - TransferTestEndpoint::Chain => None, - TransferTestEndpoint::User => Some(AccountOwner::User(Self::sender_owner())), + TransferTestEndpoint::Chain => AccountOwner::Chain, + TransferTestEndpoint::User => AccountOwner::User(Self::sender_owner()), TransferTestEndpoint::Application => { - Some(AccountOwner::Application(Self::sender_application_id())) + AccountOwner::Application(Self::sender_application_id()) } } } /// Returns the [`AccountOwner`] to represent this transfer endpoint as an unauthorized sender. - pub fn unauthorized_sender_account_owner(&self) -> Option { + pub fn unauthorized_sender_account_owner(&self) -> AccountOwner { match self { - TransferTestEndpoint::Chain => None, + TransferTestEndpoint::Chain => AccountOwner::Chain, TransferTestEndpoint::User => { - Some(AccountOwner::User(Owner(CryptoHash::test_hash("attacker")))) + AccountOwner::User(Owner(CryptoHash::test_hash("attacker"))) } TransferTestEndpoint::Application => { - Some(AccountOwner::Application(Self::recipient_application_id())) + AccountOwner::Application(Self::recipient_application_id()) } } } @@ -832,12 +832,12 @@ impl TransferTestEndpoint { } /// Returns the [`AccountOwner`] to represent this transfer endpoint as a recipient. - pub fn recipient_account_owner(&self) -> Option { + pub fn recipient_account_owner(&self) -> AccountOwner { match self { - TransferTestEndpoint::Chain => None, - TransferTestEndpoint::User => Some(AccountOwner::User(Self::recipient_owner())), + TransferTestEndpoint::Chain => AccountOwner::Chain, + TransferTestEndpoint::User => AccountOwner::User(Self::recipient_owner()), TransferTestEndpoint::Application => { - Some(AccountOwner::Application(Self::recipient_application_id())) + AccountOwner::Application(Self::recipient_application_id()) } } } @@ -850,8 +850,8 @@ impl TransferTestEndpoint { amount: Amount, ) -> anyhow::Result<()> { let (expected_chain_balance, expected_balances) = match self.recipient_account_owner() { - None => (amount, vec![]), - Some(account_owner) => (Amount::ZERO, vec![(account_owner, amount)]), + AccountOwner::Chain => (amount, vec![]), + account_owner => (Amount::ZERO, vec![(account_owner, amount)]), }; let balances = system.balances.index_values().await?; diff --git a/linera-execution/tests/fee_consumption.rs b/linera-execution/tests/fee_consumption.rs index 396891727b38..13d6678c0e45 100644 --- a/linera-execution/tests/fee_consumption.rs +++ b/linera-execution/tests/fee_consumption.rs @@ -187,10 +187,12 @@ async fn test_fee_consumption( )); application.expect_call(ExpectedCall::default_finalize()); - let refund_grant_to = Some(Account { - chain_id: ChainId::root(0), - owner: authenticated_signer.map(AccountOwner::User), - }); + let refund_grant_to = authenticated_signer + .map(|owner| Account { + chain_id: ChainId::root(0), + owner: AccountOwner::User(owner), + }) + .or(None); let context = MessageContext { chain_id: ChainId::root(0), is_bouncing: false, diff --git a/linera-execution/tests/test_execution.rs b/linera-execution/tests/test_execution.rs index 4da4a6e0e25b..8ade01153007 100644 --- a/linera-execution/tests/test_execution.rs +++ b/linera-execution/tests/test_execution.rs @@ -12,7 +12,9 @@ use linera_base::{ Amount, ApplicationPermissions, Blob, BlockHeight, OracleResponse, Resources, SendMessageRequest, Timestamp, }, - identifiers::{Account, ChainDescription, ChainId, Destination, MessageId, Owner}, + identifiers::{ + Account, AccountOwner, ChainDescription, ChainId, Destination, MessageId, Owner, + }, ownership::ChainOwnership, }; use linera_execution::{ @@ -627,7 +629,7 @@ async fn test_sending_message_from_finalize() -> anyhow::Result<()> { let account = Account { chain_id: ChainId::root(0), - owner: None, + owner: AccountOwner::Chain, }; let txn_outcome = txn_tracker.into_outcome().unwrap(); @@ -925,7 +927,7 @@ async fn test_simple_message() -> anyhow::Result<()> { let account = Account { chain_id: ChainId::root(0), - owner: None, + owner: AccountOwner::Chain, }; let txn_outcome = txn_tracker.into_outcome().unwrap(); @@ -1008,7 +1010,7 @@ async fn test_message_from_cross_application_call() -> anyhow::Result<()> { let account = Account { chain_id: ChainId::root(0), - owner: None, + owner: AccountOwner::Chain, }; let txn_outcome = txn_tracker.into_outcome().unwrap(); @@ -1102,7 +1104,7 @@ async fn test_message_from_deeper_call() -> anyhow::Result<()> { let account = Account { chain_id: ChainId::root(0), - owner: None, + owner: AccountOwner::Chain, }; let txn_outcome = txn_tracker.into_outcome().unwrap(); let mut expected = TransactionTracker::default(); @@ -1235,7 +1237,7 @@ async fn test_multiple_messages_from_different_applications() -> anyhow::Result< let account = Account { chain_id: ChainId::root(0), - owner: None, + owner: AccountOwner::Chain, }; // Return to checking the user application outcomes @@ -1301,7 +1303,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(None, destination, Amount::ONE)?; + runtime.transfer(AccountOwner::Chain, destination, Amount::ONE)?; let id = runtime.application_id()?; let application_permissions = ApplicationPermissions::new_single(id); let (actual_message_id, chain_id) = @@ -1498,11 +1500,11 @@ async fn test_message_receipt_spending_chain_balance( let (application_id, application, blobs) = view.register_mock_application(0).await?; - let receiver_chain_account = None; + let receiver_chain_account = AccountOwner::Chain; let sender_chain_id = ChainId::root(2); let recipient = Account { chain_id: sender_chain_id, - owner: None, + owner: AccountOwner::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 93747e4d0f7e..9a7319dc0e06 100644 --- a/linera-execution/tests/test_system_execution.rs +++ b/linera-execution/tests/test_system_execution.rs @@ -6,7 +6,7 @@ use linera_base::{ crypto::{AccountSecretKey, CryptoHash}, data_types::{Amount, BlockHeight, Timestamp}, - identifiers::{ChainDescription, ChainId, MessageId, Owner}, + identifiers::{AccountOwner, ChainDescription, ChainId, MessageId, Owner}, ownership::ChainOwnership, }; use linera_execution::{ @@ -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: None, - source: None, + target: AccountOwner::Chain, + source: AccountOwner::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 145fa8c200e0..3823611c31c1 100644 --- a/linera-indexer/example/tests/test.rs +++ b/linera-indexer/example/tests/test.rs @@ -9,7 +9,11 @@ use std::{str::FromStr, sync::LazyLock, time::Duration}; -use linera_base::{command::resolve_binary, data_types::Amount, identifiers::ChainId}; +use linera_base::{ + command::resolve_binary, + data_types::Amount, + identifiers::{Account, ChainId}, +}; use linera_indexer_graphql_client::{ indexer::{plugins, state, Plugins, State}, operations::{get_operation, GetOperation, OperationKey}, @@ -69,10 +73,11 @@ fn indexer_running(child: &mut Child) { } } -async fn transfer(client: &reqwest::Client, from: ChainId, to: ChainId, amount: &str) { +async fn transfer(client: &reqwest::Client, from: ChainId, to: Account, amount: &str) { let variables = transfer::Variables { chain_id: from, - recipient: to, + recipient_chain: to.chain_id, + recipient_account: to.owner, amount: Amount::from_str(amount).unwrap(), }; request::(client, "http://localhost:8080", variables) @@ -115,7 +120,7 @@ async fn test_end_to_end_operations_indexer(config: impl LineraNetConfig) { // making a few transfers let chain0 = ChainId::root(0); - let chain1 = ChainId::root(1); + let chain1 = Account::chain(ChainId::root(1)); for _ in 0..10 { transfer(&req_client, chain0, chain1, "0.1").await; linera_base::time::timer::sleep(Duration::from_millis(TRANSFER_DELAY_MILLIS)).await; diff --git a/linera-rpc/proto/rpc.proto b/linera-rpc/proto/rpc.proto index 6b7ef1f84fb2..0da981651260 100644 --- a/linera-rpc/proto/rpc.proto +++ b/linera-rpc/proto/rpc.proto @@ -190,7 +190,7 @@ message ChainInfoQuery { bool request_leader_timeout = 8; // Query the balance of a given owner. - optional AccountOwner request_owner_balance = 9; + AccountOwner request_owner_balance = 9; // Request a signed vote for fallback mode. bool request_fallback = 10; diff --git a/linera-rpc/src/grpc/conversions.rs b/linera-rpc/src/grpc/conversions.rs index 3c5538bc872e..e6988ed0671f 100644 --- a/linera-rpc/src/grpc/conversions.rs +++ b/linera-rpc/src/grpc/conversions.rs @@ -555,10 +555,7 @@ impl TryFrom for ChainInfoQuery { Ok(Self { request_committees: chain_info_query.request_committees, - request_owner_balance: chain_info_query - .request_owner_balance - .map(TryInto::try_into) - .transpose()?, + request_owner_balance: try_proto_convert(chain_info_query.request_owner_balance)?, request_pending_message_bundles: chain_info_query.request_pending_message_bundles, chain_id: try_proto_convert(chain_info_query.chain_id)?, request_sent_certificate_hashes_in_range, @@ -580,10 +577,7 @@ impl TryFrom for api::ChainInfoQuery { .request_sent_certificate_hashes_in_range .map(|range| bincode::serialize(&range)) .transpose()?; - let request_owner_balance = chain_info_query - .request_owner_balance - .map(|owner| owner.try_into()) - .transpose()?; + let request_owner_balance = Some(chain_info_query.request_owner_balance.try_into()?); Ok(Self { chain_id: Some(chain_info_query.chain_id.into()), @@ -1109,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: None, + request_owner_balance: AccountOwner::Chain, request_pending_message_bundles: false, request_sent_certificate_hashes_in_range: Some( linera_core::data_types::BlockHeightRange { diff --git a/linera-rpc/tests/snapshots/format__format.yaml.snap b/linera-rpc/tests/snapshots/format__format.yaml.snap index d0434928ef90..e403f5251b7a 100644 --- a/linera-rpc/tests/snapshots/format__format.yaml.snap +++ b/linera-rpc/tests/snapshots/format__format.yaml.snap @@ -7,8 +7,7 @@ Account: - chain_id: TYPENAME: ChainId - owner: - OPTION: - TYPENAME: AccountOwner + TYPENAME: AccountOwner AccountOwner: ENUM: 0: @@ -19,6 +18,8 @@ AccountOwner: Application: NEWTYPE: TYPENAME: ApplicationId + 2: + Chain: UNIT AccountPublicKey: ENUM: 0: @@ -286,8 +287,7 @@ ChainInfoQuery: OPTION: TYPENAME: BlockHeight - request_owner_balance: - OPTION: - TYPENAME: AccountOwner + TYPENAME: AccountOwner - request_committees: BOOL - request_pending_message_bundles: BOOL - request_sent_certificate_hashes_in_range: @@ -1042,13 +1042,11 @@ SystemMessage: Credit: STRUCT: - target: - OPTION: - TYPENAME: AccountOwner + TYPENAME: AccountOwner - amount: TYPENAME: Amount - source: - OPTION: - TYPENAME: AccountOwner + TYPENAME: AccountOwner 1: Withdraw: STRUCT: diff --git a/linera-sdk/src/base/conversions_from_wit.rs b/linera-sdk/src/base/conversions_from_wit.rs index 41cdc20dbc03..bc3d9d7b2ee6 100644 --- a/linera-sdk/src/base/conversions_from_wit.rs +++ b/linera-sdk/src/base/conversions_from_wit.rs @@ -42,6 +42,7 @@ macro_rules! impl_from_wit { $wit_base_api::AccountOwner::Application(owner) => { AccountOwner::Application(owner.into()) } + $wit_base_api::AccountOwner::Chain => AccountOwner::Chain, } } } diff --git a/linera-sdk/src/base/conversions_to_wit.rs b/linera-sdk/src/base/conversions_to_wit.rs index a74758a095f7..ea334e9439d2 100644 --- a/linera-sdk/src/base/conversions_to_wit.rs +++ b/linera-sdk/src/base/conversions_to_wit.rs @@ -45,6 +45,7 @@ macro_rules! impl_to_wit { AccountOwner::Application(application_id) => { $wit_base_api::AccountOwner::Application(application_id.into()) } + AccountOwner::Chain => $wit_base_api::AccountOwner::Chain, } } } diff --git a/linera-sdk/src/contract/conversions_to_wit.rs b/linera-sdk/src/contract/conversions_to_wit.rs index 6e7e8e5002a7..3af9d85eef84 100644 --- a/linera-sdk/src/contract/conversions_to_wit.rs +++ b/linera-sdk/src/contract/conversions_to_wit.rs @@ -58,7 +58,7 @@ impl From for wit_contract_api::Account { fn from(account: Account) -> Self { wit_contract_api::Account { chain_id: account.chain_id.into(), - owner: account.owner.map(|owner| owner.into()), + owner: account.owner.into(), } } } @@ -70,6 +70,7 @@ impl From for wit_contract_api::AccountOwner { AccountOwner::Application(application_id) => { wit_contract_api::AccountOwner::Application(application_id.into()) } + AccountOwner::Chain => wit_contract_api::AccountOwner::Chain, } } } diff --git a/linera-sdk/src/contract/runtime.rs b/linera-sdk/src/contract/runtime.rs index fc5b0509732f..4db3e65ab3b9 100644 --- a/linera-sdk/src/contract/runtime.rs +++ b/linera-sdk/src/contract/runtime.rs @@ -231,12 +231,8 @@ where /// Transfers an `amount` of native tokens from `source` owner account (or the current chain's /// balance) to `destination`. - pub fn transfer(&mut self, source: Option, destination: Account, amount: Amount) { - contract_wit::transfer( - source.map(|source| source.into()), - destination.into(), - amount.into(), - ) + pub fn transfer(&mut self, source: AccountOwner, destination: Account, amount: Amount) { + contract_wit::transfer(source.into(), destination.into(), amount.into()) } /// Claims an `amount` of native tokens from a `source` account to a `destination` account. diff --git a/linera-sdk/src/contract/test_runtime.rs b/linera-sdk/src/contract/test_runtime.rs index 08fefa4677c8..6cacc8b64d2e 100644 --- a/linera-sdk/src/contract/test_runtime.rs +++ b/linera-sdk/src/contract/test_runtime.rs @@ -499,7 +499,7 @@ where /// Transfers an `amount` of native tokens from `source` owner account (or the current chain's /// balance) to `destination`. - pub fn transfer(&mut self, source: Option, destination: Account, amount: Amount) { + pub fn transfer(&mut self, source: AccountOwner, destination: Account, amount: Amount) { self.debit(source, amount); if Some(destination.chain_id) == self.chain_id { @@ -514,10 +514,10 @@ where /// Debits an `amount` of native tokens from a `source` owner account (or the current /// chain's balance). - fn debit(&mut self, source: Option, amount: Amount) { + fn debit(&mut self, source: AccountOwner, amount: Amount) { let source_balance = match source { - Some(owner) => self.owner_balance_mut(owner), - None => self.chain_balance_mut(), + AccountOwner::Application(_) | AccountOwner::User(_) => self.owner_balance_mut(source), + AccountOwner::Chain => self.chain_balance_mut(), }; *source_balance = source_balance @@ -527,10 +527,12 @@ where /// Credits an `amount` of native tokens into a `destination` owner account (or the /// current chain's balance). - fn credit(&mut self, destination: Option, amount: Amount) { + fn credit(&mut self, destination: AccountOwner, amount: Amount) { let destination_balance = match destination { - Some(owner) => self.owner_balance_mut(owner), - None => self.chain_balance_mut(), + owner @ AccountOwner::Application(_) | owner @ AccountOwner::User(_) => { + self.owner_balance_mut(owner) + } + AccountOwner::Chain => self.chain_balance_mut(), }; *destination_balance = destination_balance diff --git a/linera-sdk/wit/base-runtime-api.wit b/linera-sdk/wit/base-runtime-api.wit index 82d5440a4ef5..a0336784eaf1 100644 --- a/linera-sdk/wit/base-runtime-api.wit +++ b/linera-sdk/wit/base-runtime-api.wit @@ -33,6 +33,7 @@ interface base-runtime-api { variant account-owner { user(owner), application(application-id), + chain, } record amount { diff --git a/linera-sdk/wit/contract-runtime-api.wit b/linera-sdk/wit/contract-runtime-api.wit index 079f74fde0da..55309e1181a7 100644 --- a/linera-sdk/wit/contract-runtime-api.wit +++ b/linera-sdk/wit/contract-runtime-api.wit @@ -8,7 +8,7 @@ interface contract-runtime-api { send-message: func(message: send-message-request); subscribe: func(chain: chain-id, channel: channel-name); unsubscribe: func(chain: chain-id, channel: channel-name); - transfer: func(source: option, destination: account, amount: amount); + transfer: func(source: account-owner, destination: account, amount: amount); claim: func(source: account, destination: account, amount: amount); open-chain: func(chain-ownership: chain-ownership, application-permissions: application-permissions, balance: amount) -> tuple; close-chain: func() -> result, close-chain-error>; @@ -23,12 +23,13 @@ interface contract-runtime-api { record account { chain-id: chain-id, - owner: option, + owner: account-owner, } variant account-owner { user(owner), application(application-id), + chain, } record amount { diff --git a/linera-service-graphql-client/gql/service_requests.graphql b/linera-service-graphql-client/gql/service_requests.graphql index 85fe05b830e9..d6374ff1a44a 100644 --- a/linera-service-graphql-client/gql/service_requests.graphql +++ b/linera-service-graphql-client/gql/service_requests.graphql @@ -358,6 +358,6 @@ subscription Notifications($chainId: ChainId!) { notifications(chainId: $chainId) } -mutation Transfer($chainId: ChainId!, $recipient: ChainId!, $amount: Amount!) { - transfer(chainId: $chainId, recipient: { Account: { chain_id: $recipient } }, amount: $amount) +mutation Transfer($chainId: ChainId!, $recipient_chain: ChainId!, $recipient_account: AccountOwner!, $amount: Amount!) { + transfer(chainId: $chainId, recipient: { Account: { chain_id: $recipient_chain, owner: $recipient_account } }, amount: $amount) } diff --git a/linera-service-graphql-client/src/service.rs b/linera-service-graphql-client/src/service.rs index 4a6ac8e0d15d..de772050998f 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, - Owner, StreamName, + Account, AccountOwner, BlobId, ChainDescription, ChainId, ChannelName, Destination, + GenericApplicationId, Owner, StreamName, }, }; diff --git a/linera-service-graphql-client/tests/test.rs b/linera-service-graphql-client/tests/test.rs index c71d99413a60..6416fede9cf3 100644 --- a/linera-service-graphql-client/tests/test.rs +++ b/linera-service-graphql-client/tests/test.rs @@ -10,7 +10,11 @@ use std::{collections::BTreeMap, str::FromStr, sync::LazyLock, time::Duration}; use fungible::{FungibleTokenAbi, InitialState}; -use linera_base::{data_types::Amount, identifiers::ChainId, vm::VmRuntime}; +use linera_base::{ + data_types::Amount, + identifiers::{Account, ChainId}, + vm::VmRuntime, +}; use linera_service::cli_wrappers::{ local_net::{Database, LocalNetConfig, ProcessInbox}, LineraNet, LineraNetConfig, Network, @@ -31,10 +35,11 @@ fn reqwest_client() -> reqwest::Client { .unwrap() } -async fn transfer(client: &reqwest::Client, url: &str, from: ChainId, to: ChainId, amount: &str) { +async fn transfer(client: &reqwest::Client, url: &str, from: ChainId, to: Account, amount: &str) { let variables = transfer::Variables { chain_id: from, - recipient: to, + recipient_chain: to.chain_id, + recipient_account: to.owner, amount: Amount::from_str(amount).unwrap(), }; request::(client, url, variables) @@ -86,7 +91,7 @@ async fn test_end_to_end_queries(config: impl LineraNetConfig) { // sending a few transfers let chain0 = ChainId::root(0); - let chain1 = ChainId::root(1); + let chain1 = Account::chain(ChainId::root(1)); for _ in 0..10 { transfer(req_client, url, chain0, chain1, "0.1").await; } diff --git a/linera-service/benches/transfers.rs b/linera-service/benches/transfers.rs index f3ce350013b1..483df632184b 100644 --- a/linera-service/benches/transfers.rs +++ b/linera-service/benches/transfers.rs @@ -80,7 +80,7 @@ async fn setup_native_token_balances( for chain in &chains { let recipient = Recipient::Account(Account { chain_id: chain.id(), - owner: Some(chain.public_key().into()), + owner: chain.public_key().into(), }); // TODO: Support benchmarking chains with multiple owner accounts @@ -110,7 +110,7 @@ fn prepare_transfers( .iter() .map(|chain| Account { chain_id: chain.id(), - owner: Some(chain.public_key().into()), + owner: chain.public_key().into(), }) .collect::>(); diff --git a/linera-service/src/linera/main.rs b/linera-service/src/linera/main.rs index 77abb0bd302d..6e1a7cee036e 100644 --- a/linera-service/src/linera/main.rs +++ b/linera-service/src/linera/main.rs @@ -102,11 +102,11 @@ impl Runnable for Job { } => { let chain_client = context.make_chain_client(sender.chain_id)?; let owner = match sender.owner { - Some(AccountOwner::User(owner)) => Some(owner), - Some(AccountOwner::Application(_)) => { + AccountOwner::User(owner) => Some(owner), + AccountOwner::Application(_) => { bail!("Can't transfer from an application account") } - None => None, + AccountOwner::Chain => None, }; info!( "Starting transfer of {} native tokens from {} to {}", @@ -288,8 +288,10 @@ impl Runnable for Job { info!("Reading the balance of {} from the local state", account); let time_start = Instant::now(); let balance = match account.owner { - Some(owner) => chain_client.local_owner_balance(owner).await?, - None => chain_client.local_balance().await?, + AccountOwner::User(_) | AccountOwner::Application(_) => { + chain_client.local_owner_balance(account.owner).await? + } + AccountOwner::Chain => chain_client.local_balance().await?, }; let time_total = time_start.elapsed(); info!("Local balance obtained after {} ms", time_total.as_millis()); @@ -305,8 +307,10 @@ impl Runnable for Job { ); let time_start = Instant::now(); let balance = match account.owner { - Some(owner) => chain_client.query_owner_balance(owner).await?, - None => chain_client.query_balance().await?, + AccountOwner::User(_) | AccountOwner::Application(_) => { + chain_client.query_owner_balance(account.owner).await? + } + AccountOwner::Chain => chain_client.query_balance().await?, }; let time_total = time_start.elapsed(); info!("Balance obtained after {} ms", time_total.as_millis()); @@ -321,8 +325,10 @@ impl Runnable for Job { let time_start = Instant::now(); chain_client.synchronize_from_validators().await?; let result = match account.owner { - Some(owner) => chain_client.query_owner_balance(owner).await, - None => chain_client.query_balance().await, + AccountOwner::User(_) | AccountOwner::Application(_) => { + chain_client.query_owner_balance(account.owner).await + } + AccountOwner::Chain => chain_client.query_balance().await, }; context.update_wallet_from_client(&chain_client).await?; let balance = result.context("Failed to synchronize from validators")?;