Skip to content

Commit c01522f

Browse files
committed
[encrypted-mempool] Introduce new payload type
1 parent 154b201 commit c01522f

File tree

9 files changed

+199
-4
lines changed

9 files changed

+199
-4
lines changed

api/src/transactions.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,13 @@ impl TransactionsApi {
12941294
}
12951295
},
12961296
},
1297+
TransactionPayload::EncryptedPayload(_) => {
1298+
return Err(SubmitTransactionError::bad_request_with_code(
1299+
"Encrypted Transaction is not supported yet",
1300+
AptosErrorCode::InvalidInput,
1301+
ledger_info,
1302+
));
1303+
},
12971304
}
12981305
// TODO: Verify script args?
12991306

@@ -1580,6 +1587,18 @@ impl TransactionsApi {
15801587
));
15811588
}
15821589

1590+
if txn
1591+
.raw_transaction_ref()
1592+
.payload_ref()
1593+
.is_encrypted_variant()
1594+
{
1595+
return Err(SubmitTransactionError::bad_request_with_code(
1596+
"Encrypted transactions cannot be simulated",
1597+
AptosErrorCode::InvalidInput,
1598+
&ledger_info,
1599+
));
1600+
}
1601+
15831602
// Simulate transaction
15841603
let state_view = self.context.latest_state_view_poem(&ledger_info)?;
15851604
let (vm_status, output) =
@@ -1639,6 +1658,9 @@ impl TransactionsApi {
16391658
};
16401659
stats_key
16411660
},
1661+
TransactionPayload::EncryptedPayload(_) => {
1662+
unreachable!("Encrypted transactions must not be simulated")
1663+
},
16421664
};
16431665
self.context
16441666
.simulate_txn_stats()

api/types/src/convert.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,9 @@ impl<'a, S: StateView> MoveConverter<'a, S> {
403403
},
404404
// Deprecated.
405405
ModuleBundle(_) => bail!("Module bundle payload has been removed"),
406+
EncryptedPayload(_) => {
407+
bail!("Encrypted payload isn't supported yet")
408+
},
406409
};
407410
Ok(ret)
408411
}

aptos-move/aptos-transaction-simulation-session/src/session.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ impl Session {
326326
name_from_executable(executable)
327327
},
328328
TransactionPayload::ModuleBundle(_) => unreachable!(),
329+
TransactionPayload::EncryptedPayload(_) => "encrypted".to_string(),
329330
};
330331

331332
let output_path = self

aptos-move/aptos-vm/src/aptos_vm.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3198,6 +3198,10 @@ impl VMValidator for AptosVM {
31983198
}
31993199
}
32003200

3201+
if transaction.payload().is_encrypted_variant() {
3202+
return VMValidatorResult::error(StatusCode::FEATURE_UNDER_GATING);
3203+
}
3204+
32013205
let txn = match transaction.check_signature() {
32023206
Ok(t) => t,
32033207
_ => {

consensus/src/quorum_store/types.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,11 @@ impl Batch {
177177
ensure!(
178178
txn.gas_unit_price() >= self.gas_bucket_start(),
179179
"Payload gas unit price doesn't match batch info"
180-
)
180+
);
181+
ensure!(
182+
!txn.payload().is_encrypted_variant(),
183+
"Encrypted transaction is not supported yet"
184+
);
181185
}
182186
Ok(())
183187
}

crates/aptos-transaction-filters/src/transaction_filter.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use aptos_crypto::{ed25519::Ed25519PublicKey, HashValue};
55
use aptos_types::transaction::{
66
authenticator::{AccountAuthenticator, AnyPublicKey, TransactionAuthenticator},
7+
encrypted_payload::EncryptedPayload,
78
EntryFunction, MultisigTransactionPayload, Script, SignedTransaction, TransactionExecutableRef,
89
TransactionExtraConfig, TransactionPayload, TransactionPayloadInner,
910
};
@@ -343,6 +344,18 @@ fn matches_entry_function(
343344
},
344345
}
345346
},
347+
TransactionPayload::EncryptedPayload(EncryptedPayload::V1(payload)) => {
348+
if let Ok(executable) = payload.executable_ref() {
349+
match executable {
350+
TransactionExecutableRef::Script(_) | TransactionExecutableRef::Empty => false,
351+
TransactionExecutableRef::EntryFunction(entry_function) => {
352+
compare_entry_function(entry_function, address, module_name, function)
353+
},
354+
}
355+
} else {
356+
false
357+
}
358+
},
346359
}
347360
}
348361

@@ -374,6 +387,18 @@ fn matches_entry_function_module_address(
374387
},
375388
}
376389
},
390+
TransactionPayload::EncryptedPayload(EncryptedPayload::V1(payload)) => {
391+
if let Ok(executable) = payload.executable_ref() {
392+
match executable {
393+
TransactionExecutableRef::Script(_) | TransactionExecutableRef::Empty => false,
394+
TransactionExecutableRef::EntryFunction(entry_function) => {
395+
compare_entry_function_module_address(entry_function, module_address)
396+
},
397+
}
398+
} else {
399+
false
400+
}
401+
},
377402
}
378403
}
379404

@@ -397,6 +422,15 @@ fn matches_multisig_address(
397422
.unwrap_or(false),
398423
}
399424
},
425+
TransactionPayload::EncryptedPayload(EncryptedPayload::V1(payload)) => {
426+
match payload.extra_config() {
427+
TransactionExtraConfig::V1 {
428+
multisig_address, ..
429+
} => multisig_address
430+
.map(|multisig_address| multisig_address == *address)
431+
.unwrap_or(false),
432+
}
433+
},
400434
}
401435
}
402436

@@ -421,6 +455,19 @@ fn matches_script_argument_address(
421455
},
422456
}
423457
},
458+
TransactionPayload::EncryptedPayload(EncryptedPayload::V1(payload)) => {
459+
if let Ok(executable) = payload.executable_ref() {
460+
match executable {
461+
TransactionExecutableRef::EntryFunction(_)
462+
| TransactionExecutableRef::Empty => false,
463+
TransactionExecutableRef::Script(script) => {
464+
compare_script_argument_address(script, address)
465+
},
466+
}
467+
} else {
468+
false
469+
}
470+
},
424471
}
425472
}
426473

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright (c) Aptos Foundation
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use crate::transaction::{TransactionExecutable, TransactionExecutableRef, TransactionExtraConfig};
5+
use anyhow::{bail, Result};
6+
use aptos_crypto::HashValue;
7+
use serde::{Deserialize, Serialize};
8+
use std::ops::Deref;
9+
10+
pub type CipherText = Vec<u8>;
11+
pub type EvalProof = Vec<u8>;
12+
13+
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
14+
pub enum EncryptedPayload {
15+
V1(EncryptedPayloadV1),
16+
}
17+
18+
impl Deref for EncryptedPayload {
19+
type Target = EncryptedPayloadV1;
20+
21+
fn deref(&self) -> &Self::Target {
22+
let Self::V1(payload) = self;
23+
payload
24+
}
25+
}
26+
27+
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
28+
pub enum EncryptedPayloadV1 {
29+
Encrypted {
30+
ciphertext: CipherText,
31+
extra_config: TransactionExtraConfig,
32+
payload_hash: HashValue,
33+
},
34+
FailedDecryption {
35+
ciphertext: CipherText,
36+
extra_config: TransactionExtraConfig,
37+
payload_hash: HashValue,
38+
39+
eval_proof: EvalProof,
40+
},
41+
Decrypted {
42+
ciphertext: CipherText,
43+
extra_config: TransactionExtraConfig,
44+
payload_hash: HashValue,
45+
eval_proof: EvalProof,
46+
47+
// decrypted things
48+
executable: TransactionExecutable,
49+
decryption_nonce: u64,
50+
},
51+
}
52+
53+
impl EncryptedPayloadV1 {
54+
pub fn executable(&self) -> Result<TransactionExecutable> {
55+
let Self::Decrypted { executable, .. } = self else {
56+
bail!("Transaction is encrypted");
57+
};
58+
Ok(executable.clone())
59+
}
60+
61+
pub fn executable_ref(&self) -> Result<TransactionExecutableRef<'_>> {
62+
let Self::Decrypted { executable, .. } = self else {
63+
bail!("Transaction is encrypted");
64+
};
65+
Ok(executable.as_ref())
66+
}
67+
68+
pub fn extra_config(&self) -> &TransactionExtraConfig {
69+
match self {
70+
EncryptedPayloadV1::Encrypted { extra_config, .. } => extra_config,
71+
EncryptedPayloadV1::FailedDecryption { extra_config, .. } => extra_config,
72+
EncryptedPayloadV1::Decrypted { extra_config, .. } => extra_config,
73+
}
74+
}
75+
76+
pub fn is_encrypted(&self) -> bool {
77+
matches!(self, Self::Encrypted { .. })
78+
}
79+
}

types/src/transaction/mod.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ use crate::{
1212
keyless::{KeylessPublicKey, KeylessSignature},
1313
ledger_info::LedgerInfo,
1414
proof::{TransactionInfoListWithProof, TransactionInfoWithProof},
15-
transaction::authenticator::{
16-
AASigningData, AccountAuthenticator, AnyPublicKey, AnySignature, SingleKeyAuthenticator,
17-
TransactionAuthenticator,
15+
transaction::{
16+
authenticator::{
17+
AASigningData, AccountAuthenticator, AnyPublicKey, AnySignature,
18+
SingleKeyAuthenticator, TransactionAuthenticator,
19+
},
20+
encrypted_payload::EncryptedPayload,
1821
},
1922
vm_status::{DiscardedVMStatus, KeptVMStatus, StatusCode, StatusType, VMStatus},
2023
write_set::{HotStateOp, WriteSet},
@@ -46,6 +49,7 @@ pub mod authenticator;
4649
pub mod block_epilogue;
4750
mod block_output;
4851
mod change_set;
52+
pub mod encrypted_payload;
4953
mod module;
5054
mod multisig;
5155
mod script;
@@ -546,6 +550,10 @@ impl RawTransaction {
546550
self.payload
547551
}
548552

553+
pub fn payload_ref(&self) -> &TransactionPayload {
554+
&self.payload
555+
}
556+
549557
pub fn executable_ref(&self) -> Result<TransactionExecutableRef<'_>> {
550558
self.payload.executable_ref()
551559
}
@@ -679,6 +687,8 @@ pub enum TransactionPayload {
679687
/// Contains an executable (script/entry function) along with extra configuration.
680688
/// Once this new format is fully rolled out, above payload variants will be deprecated.
681689
Payload(TransactionPayloadInner),
690+
/// Represents an encrypted transaction payload
691+
EncryptedPayload(EncryptedPayload),
682692
}
683693

684694
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
@@ -761,6 +771,9 @@ impl TransactionPayload {
761771
TransactionPayload::Payload(TransactionPayloadInner::V1 { extra_config, .. }) => {
762772
extra_config.is_multisig()
763773
},
774+
TransactionPayload::EncryptedPayload(encrypted_payload) => {
775+
encrypted_payload.extra_config().is_multisig()
776+
},
764777
}
765778
}
766779

@@ -793,6 +806,9 @@ impl TransactionPayload {
793806
TransactionPayload::ModuleBundle(_) => {
794807
Err(format_err!("ModuleBundle variant is deprecated"))
795808
},
809+
TransactionPayload::EncryptedPayload(encrypted_payload) => {
810+
encrypted_payload.executable()
811+
},
796812
}
797813
}
798814

@@ -809,6 +825,9 @@ impl TransactionPayload {
809825
TransactionPayload::ModuleBundle(_) => {
810826
Err(format_err!("ModuleBundle variant is deprecated"))
811827
},
828+
TransactionPayload::EncryptedPayload(encrypted_payload) => {
829+
encrypted_payload.executable_ref()
830+
},
812831
}
813832
}
814833

@@ -827,6 +846,9 @@ impl TransactionPayload {
827846
TransactionPayload::Payload(TransactionPayloadInner::V1 { extra_config, .. }) => {
828847
extra_config.clone()
829848
},
849+
TransactionPayload::EncryptedPayload(encrypted_payload) => {
850+
encrypted_payload.extra_config().clone()
851+
},
830852
}
831853
}
832854

@@ -919,6 +941,10 @@ impl TransactionPayload {
919941
extra_config,
920942
})
921943
}
944+
945+
pub fn is_encrypted_variant(&self) -> bool {
946+
matches!(self, Self::EncryptedPayload(_))
947+
}
922948
}
923949

924950
impl TransactionExtraConfig {

types/src/transaction/use_case.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ fn parse_use_case(payload: &TransactionPayload) -> UseCaseKey {
4141
None
4242
}
4343
},
44+
EncryptedPayload(encrypted_payload) => {
45+
if let Ok(TransactionExecutableRef::EntryFunction(entry_fun)) =
46+
encrypted_payload.executable_ref()
47+
{
48+
Some(entry_fun)
49+
} else {
50+
None
51+
}
52+
},
4453
};
4554

4655
match maybe_entry_func {

0 commit comments

Comments
 (0)