diff --git a/examples/native-fungible/tests/transfers.rs b/examples/native-fungible/tests/transfers.rs index a4347a703cc4..b5ecac6eb045 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(None, recipient, transfer_amount); + block.with_native_token_transfer(AccountOwner::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(None, recipient, transfer_amount); + block.with_native_token_transfer(AccountOwner::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(None, recipient, transfer_amount); + block.with_native_token_transfer(AccountOwner::Chain, recipient, transfer_amount); } }) .await; @@ -155,7 +155,7 @@ async fn emptied_account_disappears_from_queries() { let transfer_certificate = funding_chain .add_block(|block| { - block.with_native_token_transfer(None, recipient, transfer_amount); + block.with_native_token_transfer(AccountOwner::Chain, recipient, transfer_amount); }) .await; @@ -167,7 +167,11 @@ async fn emptied_account_disappears_from_queries() { recipient_chain .add_block(|block| { - block.with_native_token_transfer(Some(owner), Recipient::Burn, transfer_amount); + block.with_native_token_transfer( + AccountOwner::User(owner), + Recipient::Burn, + transfer_amount, + ); }) .await; diff --git a/linera-chain/src/test.rs b/linera-chain/src/test.rs index 121672d09c3c..a270e1c4bdd1 100644 --- a/linera-chain/src/test.rs +++ b/linera-chain/src/test.rs @@ -7,7 +7,7 @@ use linera_base::{ crypto::{AccountPublicKey, AccountSecretKey}, data_types::{Amount, BlockHeight, Round, Timestamp}, hashed::Hashed, - identifiers::{ChainId, Owner}, + identifiers::{AccountOwner, ChainId, Owner}, }; use linera_execution::{ committee::{Committee, Epoch, ValidatorState}, @@ -62,7 +62,7 @@ pub trait BlockTestExt: Sized { fn with_operation(self, operation: impl Into) -> Self; /// Returns the block with a transfer operation appended at the end. - fn with_transfer(self, owner: Option, recipient: Recipient, amount: Amount) -> Self; + fn with_transfer(self, owner: AccountOwner, recipient: Recipient, amount: Amount) -> Self; /// Returns the block with a simple transfer operation appended at the end. fn with_simple_transfer(self, chain_id: ChainId, amount: Amount) -> Self; @@ -97,7 +97,7 @@ impl BlockTestExt for ProposedBlock { self } - fn with_transfer(self, owner: Option, recipient: Recipient, amount: Amount) -> Self { + fn with_transfer(self, owner: AccountOwner, recipient: Recipient, amount: Amount) -> Self { self.with_operation(SystemOperation::Transfer { owner, recipient, @@ -106,7 +106,7 @@ impl BlockTestExt for ProposedBlock { } fn with_simple_transfer(self, chain_id: ChainId, amount: Amount) -> Self { - self.with_transfer(None, Recipient::chain(chain_id), amount) + self.with_transfer(AccountOwner::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 e1a2b181427e..695babb0ec03 100644 --- a/linera-chain/src/unit_tests/chain_tests.rs +++ b/linera-chain/src/unit_tests/chain_tests.rs @@ -17,7 +17,7 @@ use linera_base::{ UserApplicationDescription, }, hashed::Hashed, - identifiers::{ApplicationId, ChainId, MessageId, ModuleId}, + identifiers::{AccountOwner, ApplicationId, ChainId, MessageId, ModuleId}, ownership::ChainOwnership, vm::VmRuntime, }; @@ -168,7 +168,7 @@ async fn test_block_size_limit() { let invalid_block = valid_block .clone() .with_operation(SystemOperation::Transfer { - owner: None, + owner: AccountOwner::Chain, recipient: Recipient::root(0), amount: Amount::ONE, }); diff --git a/linera-client/src/benchmark.rs b/linera-client/src/benchmark.rs index e84f47a8164e..1dc51c9dd7b6 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: None, + owner: AccountOwner::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 b25a28ea8e8d..cd6e3d9259b2 100644 --- a/linera-client/src/unit_tests/chain_listener.rs +++ b/linera-client/src/unit_tests/chain_listener.rs @@ -10,7 +10,7 @@ use futures::{lock::Mutex, FutureExt as _}; use linera_base::{ crypto::{AccountPublicKey, AccountSecretKey, Secp256k1SecretKey}, data_types::{Amount, BlockHeight, TimeDelta, Timestamp}, - identifiers::ChainId, + identifiers::{AccountOwner, ChainId}, ownership::{ChainOwnership, TimeoutConfig}, }; use linera_core::{ @@ -160,7 +160,9 @@ async fn test_chain_listener() -> anyhow::Result<()> { // Transfer one token to chain 0. The listener should eventually become leader and receive // the message. let recipient0 = Recipient::chain(chain_id0); - client1.transfer(None, Amount::ONE, recipient0).await?; + client1 + .transfer(AccountOwner::Chain, Amount::ONE, recipient0) + .await?; for i in 0.. { client0.synchronize_from_validators().boxed().await?; let balance = client0.local_balance().await?; diff --git a/linera-core/benches/client_benchmarks.rs b/linera-core/benches/client_benchmarks.rs index 47b36b0a9194..d17ba1910e90 100644 --- a/linera-core/benches/client_benchmarks.rs +++ b/linera-core/benches/client_benchmarks.rs @@ -2,7 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 use criterion::{criterion_group, criterion_main, measurement::Measurement, BatchSize, Criterion}; -use linera_base::{data_types::Amount, identifiers::Account, time::Duration}; +use linera_base::{ + data_types::Amount, + identifiers::{Account, AccountOwner}, + time::Duration, +}; use linera_core::{ client, test_utils::{MemoryStorageBuilder, NodeProvider, StorageBuilder, TestBuilder}, @@ -55,7 +59,7 @@ where let account = Account::owner(chain2.chain_id(), owner1); let cert = chain1 - .transfer_to_account(None, amt, account) + .transfer_to_account(AccountOwner::Chain, amt, account) .await .unwrap() .unwrap(); diff --git a/linera-core/src/client/mod.rs b/linera-core/src/client/mod.rs index a70366b074d0..9c8e74a9551e 100644 --- a/linera-core/src/client/mod.rs +++ b/linera-core/src/client/mod.rs @@ -1610,7 +1610,7 @@ where #[instrument(level = "trace")] pub async fn transfer( &self, - owner: Option, + owner: AccountOwner, amount: Amount, recipient: Recipient, ) -> Result, ChainClientError> { @@ -2432,7 +2432,7 @@ where #[instrument(level = "trace")] pub async fn transfer_to_account( &self, - owner: Option, + owner: AccountOwner, amount: Amount, account: Account, ) -> Result, ChainClientError> { @@ -2444,7 +2444,7 @@ where #[instrument(level = "trace")] pub async fn burn( &self, - owner: Option, + owner: AccountOwner, amount: Amount, ) -> Result, ChainClientError> { self.transfer(owner, amount, Recipient::Burn).await @@ -3159,7 +3159,7 @@ where #[instrument(level = "trace")] pub async fn transfer_to_account_unsafe_unconfirmed( &self, - owner: Option, + owner: AccountOwner, amount: Amount, account: Account, ) -> Result, ChainClientError> { diff --git a/linera-core/src/unit_tests/client_tests.rs b/linera-core/src/unit_tests/client_tests.rs index b7684dc224c5..ad4732b85943 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( - None, + AccountOwner::Chain, Amount::from_tokens(3), Account::chain(ChainId::root(2)), ) @@ -156,7 +156,7 @@ where let friend = receiver.identity().await?; sender .transfer_to_account( - None, + AccountOwner::Chain, Amount::from_tokens(3), Account::owner(receiver_id, owner), ) @@ -165,7 +165,7 @@ where .unwrap(); let cert = sender .transfer_to_account( - None, + AccountOwner::Chain, Amount::from_millis(100), Account::owner(receiver_id, friend), ) @@ -291,7 +291,10 @@ where ); sender.synchronize_from_validators().await.unwrap(); // Can still use the chain. - sender.burn(None, Amount::from_tokens(3)).await.unwrap(); + sender + .burn(AccountOwner::Chain, Amount::from_tokens(3)) + .await + .unwrap(); Ok(()) } @@ -335,7 +338,9 @@ where sender.synchronize_from_validators().await.unwrap(); // Cannot use the chain any more. assert_matches!( - sender.burn(None, Amount::from_tokens(3)).await, + sender + .burn(AccountOwner::Chain, Amount::from_tokens(3)) + .await, Err(ChainClientError::CannotFindKeyForChain(_)) ); Ok(()) @@ -376,7 +381,10 @@ where ); sender.synchronize_from_validators().await.unwrap(); // Can still use the chain with the old client. - sender.burn(None, Amount::from_tokens(2)).await.unwrap(); + sender + .burn(AccountOwner::Chain, Amount::from_tokens(2)) + .await + .unwrap(); assert_eq!(sender.next_block_height(), BlockHeight::from(2)); // Make a client to try the new key. let client = builder @@ -401,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(None, Amount::ONE).await; + let result = client.burn(AccountOwner::Chain, Amount::ONE).await; assert_matches!( result, Err(ChainClientError::CommunicationError( @@ -411,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(None, Amount::ONE).await, + sender.burn(AccountOwner::Chain, Amount::ONE).await, Err(ChainClientError::CommunicationError( CommunicationError::Trusted(ClientIoError { .. }) )) @@ -429,14 +437,18 @@ where Amount::from_tokens(2) ); client.clear_pending_proposal(); - client.burn(None, Amount::ONE).await.unwrap().unwrap(); + client + .burn(AccountOwner::Chain, Amount::ONE) + .await + .unwrap() + .unwrap(); // The other client doesn't know the new round number yet: sender.synchronize_from_validators().await.unwrap(); sender.process_inbox().await.unwrap(); assert_eq!(sender.local_balance().await.unwrap(), Amount::ONE); sender.clear_pending_proposal(); - sender.burn(None, Amount::ONE).await.unwrap(); + sender.burn(AccountOwner::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); @@ -522,7 +534,11 @@ where }); // Transfer before creating the chain. The validators will ignore the cross-chain messages. sender - .transfer_to_account(None, Amount::from_tokens(2), Account::chain(new_id)) + .transfer_to_account( + AccountOwner::Chain, + Amount::from_tokens(2), + Account::chain(new_id), + ) .await .unwrap(); // Open the new chain. @@ -564,7 +580,11 @@ where // Make another block on top of the one that sent the two tokens, so that the validators // process the cross-chain messages. let certificate2 = sender - .transfer_to_account(None, Amount::from_tokens(1), Account::chain(new_id)) + .transfer_to_account( + AccountOwner::Chain, + Amount::from_tokens(1), + Account::chain(new_id), + ) .await .unwrap() .unwrap(); @@ -576,7 +596,10 @@ where client.query_balance().await.unwrap(), Amount::from_tokens(3) ); - client.burn(None, Amount::from_tokens(3)).await.unwrap(); + client + .burn(AccountOwner::Chain, Amount::from_tokens(3)) + .await + .unwrap(); Ok(()) } @@ -602,7 +625,11 @@ where }); // Transfer before creating the chain. sender - .transfer_to_account(None, Amount::from_tokens(3), Account::chain(new_id)) + .transfer_to_account( + AccountOwner::Chain, + Amount::from_tokens(3), + Account::chain(new_id), + ) .await .unwrap(); // Open the new chain. @@ -640,7 +667,9 @@ where .receive_certificate_and_update_validators(certificate) .await .unwrap(); - let result = client.burn(None, Amount::from_tokens(3)).await; + let result = client + .burn(AccountOwner::Chain, Amount::from_tokens(3)) + .await; assert_matches!( result, Err(ChainClientError::LocalNodeError( @@ -680,7 +709,11 @@ where let new_id = ChainId::child(message_id); // Transfer after creating the chain. let transfer_certificate = sender - .transfer_to_account(None, Amount::from_tokens(3), Account::chain(new_id)) + .transfer_to_account( + AccountOwner::Chain, + Amount::from_tokens(3), + Account::chain(new_id), + ) .await .unwrap() .unwrap(); @@ -705,7 +738,10 @@ where client.query_balance().await.unwrap(), Amount::from_tokens(3) ); - client.burn(None, Amount::from_tokens(3)).await.unwrap(); + client + .burn(AccountOwner::Chain, Amount::from_tokens(3)) + .await + .unwrap(); assert_eq!(client.local_balance().await.unwrap(), Amount::ZERO); Ok(()) } @@ -743,7 +779,9 @@ where certificate ); // Cannot use the chain for operations any more. - let result = client1.burn(None, Amount::from_tokens(3)).await; + let result = client1 + .burn(AccountOwner::Chain, Amount::from_tokens(3)) + .await; assert!( matches!( &result, @@ -758,7 +796,7 @@ where // Incoming messages now get rejected. client2 .transfer_to_account( - None, + AccountOwner::Chain, Amount::from_tokens(3), Account::chain(client1.chain_id()), ) @@ -816,7 +854,7 @@ where let sender = builder.add_root_chain(1, Amount::from_tokens(4)).await?; let result = sender .transfer_to_account_unsafe_unconfirmed( - None, + AccountOwner::Chain, Amount::from_tokens(3), Account::chain(ChainId::root(2)), ) @@ -866,7 +904,7 @@ where ); let certificate = client1 .transfer_to_account( - None, + AccountOwner::Chain, Amount::from_tokens(3), Account::chain(client2.chain_id), ) @@ -914,7 +952,11 @@ where // Process the inbox and send back some money. assert_eq!(client2.next_block_height(), BlockHeight::ZERO); client2 - .transfer_to_account(None, Amount::ONE, Account::chain(client1.chain_id)) + .transfer_to_account( + AccountOwner::Chain, + Amount::ONE, + Account::chain(client1.chain_id), + ) .await .unwrap(); assert_eq!(client2.next_block_height(), BlockHeight::from(1)); @@ -957,7 +999,7 @@ where let client2 = builder.add_root_chain(2, Amount::ZERO).await?; let certificate = client1 .transfer_to_account_unsafe_unconfirmed( - None, + AccountOwner::Chain, Amount::from_tokens(2), Account::chain(client2.chain_id), ) @@ -1006,11 +1048,19 @@ where // Transferring funds from client1 to client2. // Confirming to a quorum of nodes only at the end. client1 - .transfer_to_account_unsafe_unconfirmed(None, Amount::ONE, Account::chain(client2.chain_id)) + .transfer_to_account_unsafe_unconfirmed( + AccountOwner::Chain, + Amount::ONE, + Account::chain(client2.chain_id), + ) .await .unwrap(); client1 - .transfer_to_account_unsafe_unconfirmed(None, Amount::ONE, Account::chain(client2.chain_id)) + .transfer_to_account_unsafe_unconfirmed( + AccountOwner::Chain, + Amount::ONE, + Account::chain(client2.chain_id), + ) .await .unwrap(); client1 @@ -1027,7 +1077,7 @@ where // Sending money from client2 fails, as a consequence. let obtained_error = client2 .transfer_to_account_unsafe_unconfirmed( - None, + AccountOwner::Chain, Amount::from_tokens(2), Account::chain(client3.chain_id), ) @@ -1044,7 +1094,7 @@ where client2.synchronize_from_validators().await.unwrap(); let certificate = client2 .transfer_to_account( - None, + AccountOwner::Chain, Amount::from_tokens(2), Account::chain(client3.chain_id), ) @@ -1107,7 +1157,7 @@ where // Sending money from the admin chain is supported. let cert = admin .transfer_to_account( - None, + AccountOwner::Chain, Amount::from_tokens(2), Account::chain(user.chain_id()), ) @@ -1115,7 +1165,11 @@ where .unwrap() .unwrap(); admin - .transfer_to_account(None, Amount::ONE, Account::chain(user.chain_id())) + .transfer_to_account( + AccountOwner::Chain, + Amount::ONE, + Account::chain(user.chain_id()), + ) .await .unwrap() .unwrap(); @@ -1138,7 +1192,7 @@ where // Try to make a transfer back to the admin chain. let cert = user .transfer_to_account( - None, + AccountOwner::Chain, Amount::from_tokens(2), Account::chain(admin.chain_id()), ) @@ -1153,7 +1207,11 @@ where // Try again to make a transfer back to the admin chain. let cert = user - .transfer_to_account(None, Amount::ONE, Account::chain(admin.chain_id())) + .transfer_to_account( + AccountOwner::Chain, + Amount::ONE, + Account::chain(admin.chain_id()), + ) .await .unwrap() .unwrap(); @@ -1179,10 +1237,14 @@ where .with_policy(ResourceControlPolicy::fuel_and_block()); let sender = builder.add_root_chain(1, Amount::from_tokens(3)).await?; - let obtained_error = sender.burn(None, Amount::from_tokens(4)).await; + let obtained_error = sender + .burn(AccountOwner::Chain, Amount::from_tokens(4)) + .await; assert_insufficient_funding_during_operation(obtained_error, 0); - let obtained_error = sender.burn(None, Amount::from_tokens(3)).await; + let obtained_error = sender + .burn(AccountOwner::Chain, Amount::from_tokens(3)) + .await; assert_insufficient_funding_fees(obtained_error); Ok(()) } @@ -1346,7 +1408,7 @@ where *info2_b.manager.requested_locking.unwrap() ); let bt_certificate = client2_b - .burn(None, Amount::from_tokens(1)) + .burn(AccountOwner::Chain, Amount::from_tokens(1)) .await .unwrap() .unwrap(); @@ -1363,7 +1425,7 @@ where .body .operations .contains(&Operation::System(SystemOperation::Transfer { - owner: None, + owner: AccountOwner::Chain, recipient: Recipient::Burn, amount: Amount::from_tokens(1), }))); @@ -1473,7 +1535,7 @@ where client2_b.prepare_chain().await.unwrap(); let bt_certificate = client2_b - .burn(None, Amount::from_tokens(1)) + .burn(AccountOwner::Chain, Amount::from_tokens(1)) .await .unwrap() .unwrap(); @@ -1490,7 +1552,7 @@ where .body .operations .contains(&Operation::System(SystemOperation::Transfer { - owner: None, + owner: AccountOwner::Chain, recipient: Recipient::Burn, amount: Amount::from_tokens(1), }))); @@ -1822,7 +1884,7 @@ where // The other owner is leader now. Trying to submit a block should return `WaitForTimeout`. let result = client - .transfer(None, Amount::ONE, Recipient::root(2)) + .transfer(AccountOwner::Chain, Amount::ONE, Recipient::root(2)) .await .unwrap(); let timeout = match result { @@ -1849,7 +1911,7 @@ where // Now we are the leader, and the transfer should succeed. let _certificate = client - .transfer(None, Amount::ONE, Recipient::root(2)) + .transfer(AccountOwner::Chain, Amount::ONE, Recipient::root(2)) .await .unwrap() .unwrap(); @@ -1906,7 +1968,9 @@ where builder .set_fault_type([2], FaultType::OfflineWithInfo) .await; - let result = client0.burn(None, Amount::from_tokens(3)).await; + let result = client0 + .burn(AccountOwner::Chain, Amount::from_tokens(3)) + .await; assert!(result.is_err()); // Client 1 thinks it is madness to burn 3 tokens! They want to publish a blob instead. @@ -1947,7 +2011,10 @@ 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(None, Amount::from_tokens(1)).await.unwrap(); + client0 + .burn(AccountOwner::Chain, Amount::from_tokens(1)) + .await + .unwrap(); client0.synchronize_from_validators().await.unwrap(); client0.process_inbox().await.unwrap(); assert_eq!( @@ -1958,7 +2025,10 @@ where // Burn another token so Client 1 sees that the blob is already published client1.prepare_chain().await.unwrap(); - client1.burn(None, Amount::from_tokens(1)).await.unwrap(); + client1 + .burn(AccountOwner::Chain, Amount::from_tokens(1)) + .await + .unwrap(); client1.synchronize_from_validators().await.unwrap(); client1.process_inbox().await.unwrap(); assert_eq!( @@ -1987,7 +2057,9 @@ where builder .set_fault_type([2], FaultType::OfflineWithInfo) .await; - let result = client.burn(None, Amount::from_tokens(3)).await; + let result = client + .burn(AccountOwner::Chain, Amount::from_tokens(3)) + .await; assert!(result.is_err()); // Now three validators are online again. @@ -1995,7 +2067,7 @@ 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(None, Amount::ONE).await.unwrap(); + client.burn(AccountOwner::Chain, Amount::ONE).await.unwrap(); client.synchronize_from_validators().await.unwrap(); client.process_inbox().await.unwrap(); assert_eq!( @@ -2045,7 +2117,9 @@ where .set_fault_type([1, 2], FaultType::DontProcessValidated) .await; builder.set_fault_type([3], FaultType::Offline).await; - let result = client0.burn(None, Amount::from_tokens(3)).await; + let result = client0 + .burn(AccountOwner::Chain, Amount::from_tokens(3)) + .await; assert!(result.is_err()); let manager = client0 .chain_info_with_manager_values() @@ -2081,7 +2155,9 @@ where assert!(manager.requested_proposed.is_some()); assert!(manager.requested_locking.is_none()); assert_eq!(manager.current_round, Round::MultiLeader(0)); - let result = client1.burn(None, Amount::from_tokens(2)).await; + let result = client1 + .burn(AccountOwner::Chain, Amount::from_tokens(2)) + .await; assert!(result.is_err()); // Finally, three validators are online and honest again. Client 1 realizes there has been a @@ -2100,7 +2176,10 @@ where ); assert_eq!(manager.current_round, Round::MultiLeader(1)); assert!(client1.pending_proposal().is_some()); - client1.burn(None, Amount::from_tokens(4)).await.unwrap(); + client1 + .burn(AccountOwner::Chain, Amount::from_tokens(4)) + .await + .unwrap(); // Burning 3 and 4 tokens got finalized; the pending 2 tokens got skipped. client0.synchronize_from_validators().await.unwrap(); @@ -2125,7 +2204,7 @@ where let mut receiver = builder.add_root_chain(2, Amount::ZERO).await?; let recipient = Recipient::chain(receiver.chain_id()); let cert = sender - .transfer(None, Amount::ONE, recipient) + .transfer(AccountOwner::Chain, Amount::ONE, recipient) .await .unwrap() .unwrap(); @@ -2210,7 +2289,11 @@ where // Send a message from chain 2 to chain 3. let certificate = client2 - .transfer(None, Amount::from_millis(1), Recipient::chain(chain_id3)) + .transfer( + AccountOwner::Chain, + Amount::from_millis(1), + Recipient::chain(chain_id3), + ) .await .unwrap() .unwrap(); diff --git a/linera-core/src/unit_tests/worker_tests.rs b/linera-core/src/unit_tests/worker_tests.rs index 98e50ac30c26..5ca104437b34 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()), - None, + AccountOwner::Chain, Recipient::chain(target_id), amount, incoming_bundles, @@ -221,7 +221,8 @@ where async fn make_transfer_certificate( chain_description: ChainDescription, key_pair: &AccountSecretKey, - source: Option, + authenticated_signer: Option, + source: AccountOwner, recipient: Recipient, amount: Amount, incoming_bundles: Vec, @@ -237,7 +238,7 @@ where make_transfer_certificate_for_epoch( chain_description, key_pair, - source.or_else(|| Some(key_pair.public().into())), + authenticated_signer, source, recipient, amount, @@ -257,7 +258,7 @@ async fn make_transfer_certificate_for_epoch( chain_description: ChainDescription, key_pair: &AccountSecretKey, authenticated_signer: Option, - source: Option, + source: AccountOwner, recipient: Recipient, amount: Amount, incoming_bundles: Vec, @@ -323,9 +324,7 @@ where account.chain_id, MessageKind::Tracked, SystemMessage::Credit { - source: source - .map(AccountOwner::User) - .unwrap_or(AccountOwner::Chain), + source, target: account.owner, amount, }, @@ -1391,7 +1390,7 @@ where ChainDescription::Root(2), &sender_key_pair, Some(chain_key_pair.public().into()), - None, + AccountOwner::Chain, Recipient::chain(ChainId::root(2)), Amount::from_tokens(5), Vec::new(), @@ -2124,7 +2123,8 @@ where let certificate00 = make_transfer_certificate( ChainDescription::Root(1), &sender_key_pair, - None, + Some(Owner::from(sender_key_pair.public())), + AccountOwner::Chain, Recipient::Account(sender_account), Amount::from_tokens(5), Vec::new(), @@ -2143,7 +2143,8 @@ where let certificate01 = make_transfer_certificate( ChainDescription::Root(1), &sender_key_pair, - None, + Some(Owner::from(sender_key_pair.public())), + AccountOwner::Chain, Recipient::Burn, Amount::ONE, vec![IncomingBundle { @@ -2185,6 +2186,7 @@ where ChainDescription::Root(1), &sender_key_pair, Some(sender), + AccountOwner::User(sender), Recipient::Account(recipient_account), Amount::from_tokens(3), Vec::new(), @@ -2204,6 +2206,7 @@ where ChainDescription::Root(1), &sender_key_pair, Some(sender), + AccountOwner::User(sender), Recipient::Account(recipient_account), Amount::from_tokens(2), Vec::new(), @@ -2224,6 +2227,7 @@ where ChainDescription::Root(2), &recipient_key_pair, Some(recipient), + AccountOwner::User(recipient), Recipient::Burn, Amount::ONE, vec![ @@ -2283,6 +2287,7 @@ where ChainDescription::Root(1), &sender_key_pair, Some(sender), + AccountOwner::User(sender), Recipient::Burn, Amount::from_tokens(3), vec![IncomingBundle { @@ -2978,7 +2983,7 @@ async fn test_cross_chain_helper() -> anyhow::Result<()> { ChainDescription::Root(0), &key_pair0, Some(key_pair0.public().into()), - None, + AccountOwner::Chain, Recipient::chain(id1), Amount::ONE, Vec::new(), @@ -2994,7 +2999,7 @@ async fn test_cross_chain_helper() -> anyhow::Result<()> { ChainDescription::Root(0), &key_pair0, Some(key_pair0.public().into()), - None, + AccountOwner::Chain, Recipient::chain(id1), Amount::ONE, Vec::new(), @@ -3010,7 +3015,7 @@ async fn test_cross_chain_helper() -> anyhow::Result<()> { ChainDescription::Root(0), &key_pair0, Some(key_pair0.public().into()), - None, + AccountOwner::Chain, Recipient::chain(id1), Amount::ONE, Vec::new(), @@ -3027,7 +3032,7 @@ async fn test_cross_chain_helper() -> anyhow::Result<()> { ChainDescription::Root(0), &key_pair0, Some(key_pair0.public().into()), - None, + AccountOwner::Chain, Recipient::chain(id1), Amount::ONE, Vec::new(), @@ -3506,7 +3511,7 @@ 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(None, Recipient::Burn, Amount::from_tokens(1)) + .with_transfer(AccountOwner::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/system.rs b/linera-execution/src/system.rs index 3af1132eb566..1e8e3aa71c99 100644 --- a/linera-execution/src/system.rs +++ b/linera-execution/src/system.rs @@ -114,8 +114,7 @@ pub enum SystemOperation { /// Transfers `amount` units of value from the given owner's account to the recipient. /// If no owner is given, try to take the units out of the unattributed account. Transfer { - #[debug(skip_if = Option::is_none)] - owner: Option, + owner: AccountOwner, recipient: Recipient, amount: Amount, }, @@ -414,13 +413,7 @@ where .. } => { let message = self - .transfer( - context.authenticated_signer, - None, - owner.map(AccountOwner::User).unwrap_or(AccountOwner::Chain), - recipient, - amount, - ) + .transfer(context.authenticated_signer, None, owner, recipient, amount) .await?; if let Some(message) = message { diff --git a/linera-execution/tests/test_system_execution.rs b/linera-execution/tests/test_system_execution.rs index 9a7319dc0e06..04182ed3fca1 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: None, + owner: AccountOwner::Chain, amount: Amount::from_tokens(4), recipient: Recipient::Burn, }; diff --git a/linera-indexer/example/tests/test.rs b/linera-indexer/example/tests/test.rs index 3823611c31c1..716a5f189d38 100644 --- a/linera-indexer/example/tests/test.rs +++ b/linera-indexer/example/tests/test.rs @@ -12,7 +12,7 @@ use std::{str::FromStr, sync::LazyLock, time::Duration}; use linera_base::{ command::resolve_binary, data_types::Amount, - identifiers::{Account, ChainId}, + identifiers::{Account, AccountOwner, ChainId}, }; use linera_indexer_graphql_client::{ indexer::{plugins, state, Plugins, State}, @@ -76,6 +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: AccountOwner::Chain, recipient_chain: to.chain_id, recipient_account: to.owner, amount: Amount::from_str(amount).unwrap(), diff --git a/linera-rpc/tests/snapshots/format__format.yaml.snap b/linera-rpc/tests/snapshots/format__format.yaml.snap index bdc284b7644f..8a4a22860f3f 100644 --- a/linera-rpc/tests/snapshots/format__format.yaml.snap +++ b/linera-rpc/tests/snapshots/format__format.yaml.snap @@ -1090,8 +1090,7 @@ SystemOperation: Transfer: STRUCT: - owner: - OPTION: - TYPENAME: Owner + TYPENAME: AccountOwner - recipient: TYPENAME: Recipient - amount: diff --git a/linera-sdk/src/test/block.rs b/linera-sdk/src/test/block.rs index e9f127f8cec0..3820bb770e43 100644 --- a/linera-sdk/src/test/block.rs +++ b/linera-sdk/src/test/block.rs @@ -9,7 +9,9 @@ use linera_base::{ abi::ContractAbi, data_types::{Amount, ApplicationPermissions, Round, Timestamp}, hashed::Hashed, - identifiers::{ApplicationId, ChainId, ChannelFullName, GenericApplicationId, Owner}, + identifiers::{ + AccountOwner, ApplicationId, ChainId, ChannelFullName, GenericApplicationId, Owner, + }, ownership::TimeoutConfig, }; use linera_chain::{ @@ -89,7 +91,7 @@ impl BlockBuilder { /// Adds a native token transfer to this block. pub fn with_native_token_transfer( &mut self, - sender: Option, + sender: AccountOwner, recipient: Recipient, amount: Amount, ) -> &mut Self { diff --git a/linera-service-graphql-client/gql/service_requests.graphql b/linera-service-graphql-client/gql/service_requests.graphql index d6374ff1a44a..8ddc8285cf2d 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_chain: ChainId!, $recipient_account: AccountOwner!, $amount: Amount!) { - transfer(chainId: $chainId, recipient: { Account: { chain_id: $recipient_chain, owner: $recipient_account } }, amount: $amount) +mutation Transfer($chainId: ChainId!, $owner: AccountOwner!, $recipient_chain: ChainId!, $recipient_account: AccountOwner!, $amount: Amount!) { + transfer(chainId: $chainId, owner: $owner, recipient: { Account: { chain_id: $recipient_chain, owner: $recipient_account } }, amount: $amount) } diff --git a/linera-service-graphql-client/gql/service_schema.graphql b/linera-service-graphql-client/gql/service_schema.graphql index 54ef5675e200..c4cc7f540dbe 100644 --- a/linera-service-graphql-client/gql/service_schema.graphql +++ b/linera-service-graphql-client/gql/service_schema.graphql @@ -747,7 +747,7 @@ type MutationRoot { Transfers `amount` units of value from the given owner's account to the recipient. If no owner is given, try to take the units out of the unattributed account. """ - transfer(chainId: ChainId!, owner: Owner, recipient: Recipient!, amount: Amount!): CryptoHash! + transfer(chainId: ChainId!, owner: AccountOwner!, recipient: Recipient!, amount: Amount!): CryptoHash! """ Claims `amount` units of value from the given owner's account in the remote `target` chain. Depending on its configuration, the `target` chain may refuse to diff --git a/linera-service-graphql-client/tests/test.rs b/linera-service-graphql-client/tests/test.rs index 6416fede9cf3..8ade791a809b 100644 --- a/linera-service-graphql-client/tests/test.rs +++ b/linera-service-graphql-client/tests/test.rs @@ -12,7 +12,7 @@ use std::{collections::BTreeMap, str::FromStr, sync::LazyLock, time::Duration}; use fungible::{FungibleTokenAbi, InitialState}; use linera_base::{ data_types::Amount, - identifiers::{Account, ChainId}, + identifiers::{Account, AccountOwner, ChainId}, vm::VmRuntime, }; use linera_service::cli_wrappers::{ @@ -38,6 +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: AccountOwner::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 483df632184b..f6d25faf3eb7 100644 --- a/linera-service/benches/transfers.rs +++ b/linera-service/benches/transfers.rs @@ -9,7 +9,7 @@ use futures::{ use linera_base::{ crypto::{AccountSecretKey, Ed25519SecretKey, Secp256k1SecretKey}, data_types::Amount, - identifiers::{Account, ChainId, Owner}, + identifiers::{Account, AccountOwner, ChainId}, time::{Duration, Instant}, }; use linera_execution::system::Recipient; @@ -88,7 +88,7 @@ async fn setup_native_token_balances( admin_chain .add_block(|block| { block.with_native_token_transfer( - None, + AccountOwner::Chain, recipient, Amount::from_tokens(initial_balance), ); @@ -119,7 +119,7 @@ fn prepare_transfers( .enumerate() .map(|(index, chain)| { let chain_id = chain.id(); - let sender = Some(Owner::from(chain.public_key())); + let sender = AccountOwner::from(chain.public_key()); let transfers = accounts .iter() diff --git a/linera-service/src/linera/main.rs b/linera-service/src/linera/main.rs index 6e1a7cee036e..b89b516b5cfe 100644 --- a/linera-service/src/linera/main.rs +++ b/linera-service/src/linera/main.rs @@ -101,12 +101,8 @@ impl Runnable for Job { amount, } => { let chain_client = context.make_chain_client(sender.chain_id)?; - let owner = match sender.owner { - AccountOwner::User(owner) => Some(owner), - AccountOwner::Application(_) => { - bail!("Can't transfer from an application account") - } - AccountOwner::Chain => None, + if let AccountOwner::Application(_) = sender.owner { + bail!("Can't transfer from an application account") }; info!( "Starting transfer of {} native tokens from {} to {}", @@ -118,7 +114,7 @@ impl Runnable for Job { let chain_client = chain_client.clone(); async move { chain_client - .transfer_to_account(owner, amount, recipient) + .transfer_to_account(sender.owner, amount, recipient) .await } }) diff --git a/linera-service/src/node_service.rs b/linera-service/src/node_service.rs index 141a479ac8ec..f82766c5aeaa 100644 --- a/linera-service/src/node_service.rs +++ b/linera-service/src/node_service.rs @@ -18,7 +18,7 @@ use linera_base::{ data_types::{Amount, ApplicationPermissions, Bytecode, TimeDelta, UserApplicationDescription}, ensure, hashed::Hashed, - identifiers::{ApplicationId, ChainId, ModuleId, Owner, UserApplicationId}, + identifiers::{AccountOwner, ApplicationId, ChainId, ModuleId, Owner, UserApplicationId}, ownership::{ChainOwnership, TimeoutConfig}, vm::VmRuntime, BcsHexParseError, @@ -267,7 +267,7 @@ where async fn transfer( &self, chain_id: ChainId, - owner: Option, + owner: AccountOwner, recipient: Recipient, amount: Amount, ) -> Result {