Skip to content

Commit

Permalink
[aptos-vm] enable automatic creation of sponsored accounts
Browse files Browse the repository at this point in the history
This is the implementation of AIP-52:
https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-52.md

This AIP proposes to allow sponsored transactions, one in which the gas
payer is not the primary signer of the transaction, to create accounts
for the primary signer if it does not exist. Currently when submitting a
sponsored transaction an account must first exist. This is an
unnecessary friction for using gas fee payer accounts for new accounts.
As it means that the gas fee payer solution must first submit an
independent transaction to the blockchain.

I also cleaned up the tests for fee payer since there were a lot, and they
were excessively complex.
  • Loading branch information
davidiw committed Oct 6, 2023
1 parent b079676 commit c6be4eb
Show file tree
Hide file tree
Showing 15 changed files with 309 additions and 299 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ pub enum FeatureFlag {
SaferResourceGroups,
SaferMetadata,
Secp256k1ECDSAAuthenticator,
SponsoredAutomaticAccountCreation,
}

fn generate_features_blob(writer: &CodeWriter, data: &[u64]) {
Expand Down Expand Up @@ -220,6 +221,9 @@ impl From<FeatureFlag> for AptosFeatureFlag {
FeatureFlag::Secp256k1ECDSAAuthenticator => {
AptosFeatureFlag::SECP256K1_ECDSA_AUTHENTICATOR
},
FeatureFlag::SponsoredAutomaticAccountCreation => {
AptosFeatureFlag::SPONSORED_AUTOMATIC_ACCOUNT_CREATION
},
}
}
}
Expand Down Expand Up @@ -279,6 +283,9 @@ impl From<AptosFeatureFlag> for FeatureFlag {
AptosFeatureFlag::SECP256K1_ECDSA_AUTHENTICATOR => {
FeatureFlag::Secp256k1ECDSAAuthenticator
},
AptosFeatureFlag::SPONSORED_AUTOMATIC_ACCOUNT_CREATION => {
FeatureFlag::SponsoredAutomaticAccountCreation
},
}
}
}
Expand Down
21 changes: 21 additions & 0 deletions aptos-move/aptos-vm/src/aptos_vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1103,6 +1103,27 @@ impl AptosVM {
session = self.0.new_session(resolver, SessionId::txn(txn));
}

if let aptos_types::transaction::authenticator::TransactionAuthenticator::FeePayer {
..
} = &txn.authenticator_ref()
{
if self
.0
.get_features()
.is_enabled(FeatureFlag::SPONSORED_AUTOMATIC_ACCOUNT_CREATION)
{
if let Err(err) = session.execute_function_bypass_visibility(
&ACCOUNT_MODULE,
CREATE_ACCOUNT_IF_DOES_NOT_EXIST,
vec![],
serialize_values(&vec![MoveValue::Address(txn.sender())]),
gas_meter,
) {
return discard_error_vm_status(err.into());
};
}
}

let storage_gas_params = unwrap_or_discard!(self.0.get_storage_gas_parameters(log_context));
let txn_data = TransactionMetadata::new(txn);

Expand Down
3 changes: 1 addition & 2 deletions aptos-move/aptos-vm/src/aptos_vm_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ impl AptosVMImpl {
.iter()
.map(|auth_key| MoveValue::vector_u8(auth_key.to_vec()))
.collect();

let (prologue_function_name, args) = if let (Some(fee_payer), Some(fee_payer_auth_key)) = (
txn_data.fee_payer(),
txn_data.fee_payer_authentication_key.as_ref(),
Expand Down Expand Up @@ -429,7 +430,6 @@ impl AptosVMImpl {
.execute_function_bypass_visibility(
&APTOS_TRANSACTION_VALIDATION.module_id(),
prologue_function_name,
// TODO: Deprecate this once we remove gas currency on the Move side.
vec![],
serialize_values(&args),
&mut gas_meter,
Expand Down Expand Up @@ -458,7 +458,6 @@ impl AptosVMImpl {
.execute_function_bypass_visibility(
&APTOS_TRANSACTION_VALIDATION.module_id(),
&APTOS_TRANSACTION_VALIDATION.module_prologue_name,
// TODO: Deprecate this once we remove gas currency on the Move side.
vec![],
serialize_values(&vec![
MoveValue::Signer(txn_data.sender),
Expand Down
10 changes: 10 additions & 0 deletions aptos-move/aptos-vm/src/system_module_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ use aptos_types::account_config;
use move_core_types::{ident_str, identifier::IdentStr, language_storage::ModuleId};
use once_cell::sync::Lazy;

pub static ACCOUNT_MODULE: Lazy<ModuleId> = Lazy::new(|| {
ModuleId::new(
account_config::CORE_CODE_ADDRESS,
ident_str!("account").to_owned(),
)
});

pub const CREATE_ACCOUNT_IF_DOES_NOT_EXIST: &IdentStr =
ident_str!("create_account_if_does_not_exist");

// Data to resolve basic account and transaction flow functions and structs
/// The ModuleId for the aptos block module
pub static BLOCK_MODULE: Lazy<ModuleId> = Lazy::new(|| {
Expand Down
Loading

0 comments on commit c6be4eb

Please sign in to comment.