Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

add gas fee payer by adding a new payload type #8904

Merged
merged 31 commits into from
Jul 4, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
5bcb383
first update
gerben-stavenga Jun 29, 2023
8993f16
Use RawTransactionWithData
gerben-stavenga Jun 30, 2023
564c64f
fix all locations
gerben-stavenga Jun 30, 2023
153c0b3
introduce the gas fee authenticator
davidiw Jul 1, 2023
8035f1c
[fee-payer] plumb through the VM and framework
davidiw Jul 3, 2023
529dfc1
move tests pass
davidiw Jul 3, 2023
341a74c
fix prover
gerben-stavenga Jul 3, 2023
04f3578
fix order
gerben-stavenga Jul 3, 2023
ae18471
Merge branch 'main' into gerben-fee-payer
gerben-stavenga Jul 3, 2023
0f535ea
regen
gerben-stavenga Jul 3, 2023
884b378
Add
gerben-stavenga Jul 3, 2023
e2dfc10
restore sdk/src/types.rs
gerben-stavenga Jul 3, 2023
3ec2125
remove old comment
gerben-stavenga Jul 3, 2023
7512ad2
split test/remove println
gerben-stavenga Jul 3, 2023
b7ad826
remove unnecessary payload
davidiw Jul 3, 2023
a08294b
Redo protos
gerben-stavenga Jul 4, 2023
7512d0d
remove more
gerben-stavenga Jul 4, 2023
531c014
undo changes
gerben-stavenga Jul 4, 2023
2c2124e
Merge branch 'main' into gerben-fee-payer
gerben-stavenga Jul 4, 2023
90d0465
Merge branch 'main' into gerben-fee-payer
gregnazario Jul 4, 2023
fc8bf30
Add spec
gerben-stavenga Jul 4, 2023
fcfdcfe
add test
gerben-stavenga Jul 4, 2023
ba958a0
rest api
gerben-stavenga Jul 4, 2023
3b7dcbf
api test
gerben-stavenga Jul 4, 2023
48e890d
regen
gerben-stavenga Jul 4, 2023
9d41347
regen
gerben-stavenga Jul 4, 2023
72e7a93
lint
gerben-stavenga Jul 4, 2023
16b19c3
reinsert seq too big test
gerben-stavenga Jul 4, 2023
c789507
regen
gerben-stavenga Jul 4, 2023
0a8302a
regen
gerben-stavenga Jul 4, 2023
b1f8bb8
prover improvement
gerben-stavenga Jul 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions api/src/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,10 @@ impl TransactionsApi {
})?;
// Verify the signed transaction
match signed_transaction.payload() {
TransactionPayload::EntryFunction(entry_function) => {
TransactionPayload::MultiAgentWithFeePayer(
MultisigTransactionPayload::EntryFunction(entry_function),
)
| TransactionPayload::EntryFunction(entry_function) => {
TransactionsApi::validate_entry_function_payload_format(
ledger_info,
entry_function,
Expand Down Expand Up @@ -1270,7 +1273,6 @@ impl TransactionsApi {
.map_err(|err| {
BasicError::bad_request_with_code(err, AptosErrorCode::InvalidInput, &ledger_info)
})?;

let raw_message = match request.secondary_signers {
Some(secondary_signer_addresses) => signing_message(
&RawTransactionWithData::new_multi_agent(
Expand Down
11 changes: 8 additions & 3 deletions api/types/src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,10 @@ impl<'a, R: MoveResolverExt + ?Sized> MoveConverter<'a, R> {
use aptos_types::transaction::TransactionPayload::*;
let ret = match payload {
Script(s) => TransactionPayload::ScriptPayload(s.try_into()?),
EntryFunction(fun) => {
MultiAgentWithFeePayer(
aptos_types::transaction::MultisigTransactionPayload::EntryFunction(fun),
)
| EntryFunction(fun) => {
let (module, function, ty_args, args) = fun.into_inner();
let func_args = self
.inner
Expand Down Expand Up @@ -581,7 +584,10 @@ impl<'a, R: MoveResolverExt + ?Sized> MoveConverter<'a, R> {
use aptos_types::transaction::TransactionPayload as Target;

let ret = match payload {
TransactionPayload::EntryFunctionPayload(entry_func_payload) => {
TransactionPayload::EntryFunctionPayload(entry_func_payload)
| TransactionPayload::FeePayerPayload(
MultisigTransactionPayload::EntryFunctionPayload(entry_func_payload),
) => {
let EntryFunctionPayload {
function,
type_arguments,
Expand Down Expand Up @@ -695,7 +701,6 @@ impl<'a, R: MoveResolverExt + ?Sized> MoveConverter<'a, R> {
transaction_payload,
})
},

// Deprecated. Will be removed in the future.
TransactionPayload::ModuleBundlePayload(payload) => {
Target::ModuleBundle(ModuleBundle::new(
Expand Down
16 changes: 8 additions & 8 deletions api/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ pub use table::{RawTableItemRequest, TableItemRequest};
pub use transaction::{
AccountSignature, BlockMetadataTransaction, DeleteModule, DeleteResource, DeleteTableItem,
DirectWriteSet, Ed25519Signature, EncodeSubmissionRequest, EntryFunctionPayload, Event,
GasEstimation, GasEstimationBcs, GenesisPayload, GenesisTransaction, ModuleBundlePayload,
MultiAgentSignature, MultiEd25519Signature, MultisigPayload, MultisigTransactionPayload,
PendingTransaction, ScriptPayload, ScriptWriteSet, SubmitTransactionRequest, Transaction,
TransactionData, TransactionId, TransactionInfo, TransactionOnChainData, TransactionPayload,
TransactionSignature, TransactionSigningMessage, TransactionsBatchSingleSubmissionFailure,
TransactionsBatchSubmissionResult, UserCreateSigningMessageRequest, UserTransaction,
UserTransactionRequest, VersionedEvent, WriteModule, WriteResource, WriteSet, WriteSetChange,
WriteSetPayload, WriteTableItem,
FeePayerSignature, GasEstimation, GasEstimationBcs, GenesisPayload, GenesisTransaction,
ModuleBundlePayload, MultiAgentSignature, MultiEd25519Signature, MultisigPayload,
MultisigTransactionPayload, PendingTransaction, ScriptPayload, ScriptWriteSet,
SubmitTransactionRequest, Transaction, TransactionData, TransactionId, TransactionInfo,
TransactionOnChainData, TransactionPayload, TransactionSignature, TransactionSigningMessage,
TransactionsBatchSingleSubmissionFailure, TransactionsBatchSubmissionResult,
UserCreateSigningMessageRequest, UserTransaction, UserTransactionRequest, VersionedEvent,
WriteModule, WriteResource, WriteSet, WriteSetChange, WriteSetPayload, WriteTableItem,
};
pub use view::ViewRequest;
pub use wrappers::{EventGuid, IdentifierWrapper, StateKeyWrapper};
Expand Down
106 changes: 106 additions & 0 deletions api/types/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ pub enum TransactionPayload {
// Deprecated. Will be removed in the future.
ModuleBundlePayload(ModuleBundlePayload),
MultisigPayload(MultisigPayload),
FeePayerPayload(MultisigTransactionPayload),
}

impl VerifyInput for TransactionPayload {
Expand All @@ -594,6 +595,9 @@ impl VerifyInput for TransactionPayload {
TransactionPayload::EntryFunctionPayload(inner) => inner.verify(),
TransactionPayload::ScriptPayload(inner) => inner.verify(),
TransactionPayload::MultisigPayload(inner) => inner.verify(),
TransactionPayload::FeePayerPayload(
MultisigTransactionPayload::EntryFunctionPayload(inner),
) => inner.function.verify(),
// Deprecated. Will be removed in the future.
TransactionPayload::ModuleBundlePayload(inner) => inner.verify(),
}
Expand Down Expand Up @@ -848,6 +852,7 @@ pub enum TransactionSignature {
Ed25519Signature(Ed25519Signature),
MultiEd25519Signature(MultiEd25519Signature),
MultiAgentSignature(MultiAgentSignature),
FeePayerSignature(FeePayerSignature),
}

impl VerifyInput for TransactionSignature {
Expand All @@ -856,6 +861,7 @@ impl VerifyInput for TransactionSignature {
TransactionSignature::Ed25519Signature(inner) => inner.verify(),
TransactionSignature::MultiEd25519Signature(inner) => inner.verify(),
TransactionSignature::MultiAgentSignature(inner) => inner.verify(),
TransactionSignature::FeePayerSignature(inner) => inner.verify(),
}
}
}
Expand All @@ -868,6 +874,7 @@ impl TryFrom<TransactionSignature> for TransactionAuthenticator {
TransactionSignature::Ed25519Signature(sig) => sig.try_into()?,
TransactionSignature::MultiEd25519Signature(sig) => sig.try_into()?,
TransactionSignature::MultiAgentSignature(sig) => sig.try_into()?,
TransactionSignature::FeePayerSignature(sig) => sig.try_into()?,
})
}
}
Expand Down Expand Up @@ -1228,6 +1235,89 @@ impl
}
}

/// Fee payer signature for fee payer transactions
///
/// This allows you to have transactions across multiple accounts and with a fee payer
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Object)]
pub struct FeePayerSignature {
pub sender: AccountSignature,
/// The other involved parties' addresses
pub secondary_signer_addresses: Vec<Address>,
/// The associated signatures, in the same order as the secondary addresses
pub secondary_signers: Vec<AccountSignature>,
/// The address of the paying party
pub fee_payer_address: Address,
/// The signature of the fee payer
pub fee_payer_signer: AccountSignature,
}

impl VerifyInput for FeePayerSignature {
fn verify(&self) -> anyhow::Result<()> {
self.sender.verify()?;

for signer in self.secondary_signers.iter() {
signer.verify()?;
}
self.fee_payer_signer.verify()?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to verify that this signature matches the fee payer address here? Should at least be done in the execution flow somewhere

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's done in the prologue

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found this in Move in fee_payer_script_prologue. I wonder if we should have a separate error here because it'd be hard to know which signature mismatches with the address - senders' or payer's. Users would see the same error for both cases and be confused

Ok(())
}
}

impl TryFrom<FeePayerSignature> for TransactionAuthenticator {
type Error = anyhow::Error;

fn try_from(value: FeePayerSignature) -> Result<Self, Self::Error> {
let FeePayerSignature {
sender,
secondary_signer_addresses,
secondary_signers,
fee_payer_address,
fee_payer_signer,
} = value;
Ok(TransactionAuthenticator::fee_payer(
sender.try_into()?,
secondary_signer_addresses
.into_iter()
.map(|a| a.into())
.collect(),
secondary_signers
.into_iter()
.map(|s| s.try_into())
.collect::<anyhow::Result<_>>()?,
fee_payer_address.into(),
fee_payer_signer.try_into()?,
))
}
}

impl
From<(
&AccountAuthenticator,
&Vec<AccountAddress>,
&Vec<AccountAuthenticator>,
&AccountAddress,
&AccountAuthenticator,
)> for FeePayerSignature
{
fn from(
(sender, addresses, signers, fee_payer_address, fee_payer_signer): (
&AccountAuthenticator,
&Vec<AccountAddress>,
&Vec<AccountAuthenticator>,
&AccountAddress,
&AccountAuthenticator,
),
) -> Self {
Self {
sender: sender.into(),
secondary_signer_addresses: addresses.iter().map(|address| (*address).into()).collect(),
secondary_signers: signers.iter().map(|s| s.into()).collect(),
fee_payer_address: (*fee_payer_address).into(),
fee_payer_signer: fee_payer_signer.into(),
}
}
}

impl From<TransactionAuthenticator> for TransactionSignature {
fn from(auth: TransactionAuthenticator) -> Self {
use TransactionAuthenticator::*;
Expand All @@ -1247,6 +1337,22 @@ impl From<TransactionAuthenticator> for TransactionSignature {
} => Self::MultiAgentSignature(
(sender, secondary_signer_addresses, secondary_signers).into(),
),
FeePayer {
sender,
secondary_signer_addresses,
secondary_signers,
fee_payer_address,
fee_payer_signer,
} => Self::FeePayerSignature(
(
sender,
secondary_signer_addresses,
secondary_signers,
fee_payer_address,
fee_payer_signer,
)
.into(),
),
}
}
}
Expand Down
21 changes: 13 additions & 8 deletions aptos-move/aptos-debugger/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use aptos_types::{
chain_id::ChainId,
on_chain_config::{Features, OnChainConfig, TimedFeatures},
transaction::{
SignedTransaction, Transaction, TransactionInfo, TransactionOutput, TransactionPayload,
Version,
MultisigTransactionPayload, SignedTransaction, Transaction, TransactionInfo,
TransactionOutput, TransactionPayload, Version,
},
vm_status::VMStatus,
};
Expand Down Expand Up @@ -87,12 +87,17 @@ impl AptosDebugger {
);
let gas_profiler = match txn.payload() {
TransactionPayload::Script(_) => GasProfiler::new_script(gas_meter),
TransactionPayload::EntryFunction(entry_func) => GasProfiler::new_function(
gas_meter,
entry_func.module().clone(),
entry_func.function().to_owned(),
entry_func.ty_args().to_vec(),
),
TransactionPayload::MultiAgentWithFeePayer(
MultisigTransactionPayload::EntryFunction(entry_func),
)
| TransactionPayload::EntryFunction(entry_func) => {
GasProfiler::new_function(
gas_meter,
entry_func.module().clone(),
entry_func.function().to_owned(),
entry_func.ty_args().to_vec(),
)
},
TransactionPayload::ModuleBundle(..) => unreachable!("not supported"),
TransactionPayload::Multisig(..) => unimplemented!("not supported yet"),
};
Expand Down
29 changes: 9 additions & 20 deletions aptos-move/aptos-vm/src/aptos_vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
adapter_common::{
discard_error_output, discard_error_vm_status, PreprocessedTransaction, VMAdapter,
},
aptos_vm_impl::{get_transaction_output, AptosVMImpl, AptosVMInternals, GAS_PAYER_FLAG_BIT},
aptos_vm_impl::{get_transaction_output, AptosVMImpl, AptosVMInternals},
block_executor::BlockAptosVM,
counters::*,
data_cache::StorageAdapter,
Expand Down Expand Up @@ -394,18 +394,6 @@ impl AptosVM {
)?)
}

fn get_senders(txn_data: &TransactionMetadata) -> Vec<AccountAddress> {
let mut res = vec![txn_data.sender];
res.extend(txn_data.secondary_signers());
if txn_data.sequence_number & GAS_PAYER_FLAG_BIT != 0 {
// In a gas payer tx, the last multi-agent signer of the secondary signers is in
// fact the gas payer and not to be part of the tx parameters. So we remove the last
// signer.
res.pop();
}
res
}

fn execute_script_or_entry_function(
&self,
resolver: &impl MoveResolverExt,
Expand All @@ -431,13 +419,12 @@ impl AptosVM {

match payload {
TransactionPayload::Script(script) => {
let senders = Self::get_senders(txn_data);
let loaded_func =
session.load_script(script.code(), script.ty_args().to_vec())?;
let args =
verifier::transaction_arg_validation::validate_combine_signer_and_txn_args(
&mut session,
senders,
txn_data.senders(),
convert_txn_args(script.args()),
&loaded_func,
self.0
Expand All @@ -452,11 +439,10 @@ impl AptosVM {
)?;
},
TransactionPayload::EntryFunction(script_fn) => {
let senders = Self::get_senders(txn_data);
self.validate_and_execute_entry_function(
&mut session,
gas_meter,
senders,
txn_data.senders(),
script_fn,
)?;
},
Expand Down Expand Up @@ -1067,7 +1053,8 @@ impl AptosVM {
let mut new_published_modules_loaded = false;
let result = match txn.payload() {
payload @ TransactionPayload::Script(_)
| payload @ TransactionPayload::EntryFunction(_) => self
| payload @ TransactionPayload::EntryFunction(_)
| payload @ TransactionPayload::MultiAgentWithFeePayer(_) => self
.execute_script_or_entry_function(
resolver,
session,
Expand Down Expand Up @@ -1460,7 +1447,8 @@ impl AptosVM {
self.0.check_gas(resolver, txn_data, log_context)?;
self.0.run_script_prologue(session, txn_data, log_context)
},
TransactionPayload::EntryFunction(_) => {
TransactionPayload::EntryFunction(_)
| TransactionPayload::MultiAgentWithFeePayer(_) => {
// NOTE: Script and EntryFunction shares the same prologue
self.0.check_gas(resolver, txn_data, log_context)?;
self.0.run_script_prologue(session, txn_data, log_context)
Expand Down Expand Up @@ -1855,7 +1843,8 @@ impl AptosSimulationVM {
let mut new_published_modules_loaded = false;
let result = match txn.payload() {
payload @ TransactionPayload::Script(_)
| payload @ TransactionPayload::EntryFunction(_) => {
| payload @ TransactionPayload::EntryFunction(_)
| payload @ TransactionPayload::MultiAgentWithFeePayer(_) => {
self.0.execute_script_or_entry_function(
resolver,
session,
Expand Down
Loading