Skip to content

Commit fbd7d9f

Browse files
committed
[API] Add support for encrypted transaction filtering.
1 parent 8e61d6d commit fbd7d9f

File tree

4 files changed

+133
-0
lines changed

4 files changed

+133
-0
lines changed

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,28 @@ fn test_all_filter() {
140140
}
141141
}
142142

143+
#[test]
144+
fn test_encrypted_transaction_filter() {
145+
// Create a filter that only allows encrypted transactions
146+
let transactions = utils::create_encrypted_and_plaintext_transactions();
147+
let filter = TransactionFilter::empty()
148+
.add_encrypted_transaction_filter(true)
149+
.add_all_filter(false);
150+
151+
// Verify that the filter returns only encrypted transactions (txn 0, 1 and 2)
152+
let filtered_transactions = filter.filter_transactions(transactions.clone());
153+
assert_eq!(filtered_transactions, transactions[0..3].to_vec());
154+
155+
// Create a filter that denies encrypted transactions
156+
let filter = TransactionFilter::empty()
157+
.add_encrypted_transaction_filter(false)
158+
.add_all_filter(true);
159+
160+
// Verify that the filter returns only plaintext transactions (txn 3 onwards)
161+
let filtered_transactions = filter.filter_transactions(transactions.clone());
162+
assert_eq!(filtered_transactions, transactions[3..].to_vec());
163+
}
164+
143165
#[test]
144166
fn test_empty_filter() {
145167
for use_new_txn_payload_format in [false, true] {

crates/aptos-transaction-filters/src/tests/transaction_filter_config.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,28 @@ fn test_transaction_filter_config_multiple_matchers() {
118118
assert_eq!(filtered_transactions, transactions[4..].to_vec());
119119
}
120120
}
121+
122+
#[test]
123+
fn test_transaction_filter_config_multiple_matchers_encrypted() {
124+
// Create a set of transactions (encrypted and plaintext)
125+
let transactions = utils::create_encrypted_and_plaintext_transactions();
126+
127+
// Create a filter that denies encrypted transactions from the first transaction sender only
128+
let transaction_filter_string = format!(
129+
r#"
130+
transaction_rules:
131+
- Deny:
132+
- EncryptedTransaction
133+
- Sender: "{}"
134+
- Allow:
135+
- All
136+
"#,
137+
transactions[0].sender().to_standard_string()
138+
);
139+
let transaction_filter =
140+
serde_yaml::from_str::<TransactionFilter>(&transaction_filter_string).unwrap();
141+
142+
// Verify that the first transaction is denied
143+
let filtered_transactions = transaction_filter.filter_transactions(transactions.clone());
144+
assert_eq!(filtered_transactions, transactions[1..].to_vec());
145+
}

crates/aptos-transaction-filters/src/tests/utils.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use aptos_types::{
1212
quorum_store::BatchId,
1313
transaction::{
1414
authenticator::{AccountAuthenticator, AnyPublicKey, TransactionAuthenticator},
15+
encrypted_payload::EncryptedPayload,
1516
EntryFunction, Multisig, MultisigTransactionPayload, RawTransaction, Script,
1617
SignedTransaction, TransactionExecutable, TransactionExecutableRef, TransactionExtraConfig,
1718
TransactionPayload, TransactionPayloadInner,
@@ -29,6 +30,73 @@ pub fn create_account_authenticator(public_key: Ed25519PublicKey) -> AccountAuth
2930
}
3031
}
3132

33+
/// Creates and returns a list of transactions (3 encrypted and 5 plaintext)
34+
pub fn create_encrypted_and_plaintext_transactions() -> Vec<SignedTransaction> {
35+
let mut transactions = vec![];
36+
37+
// Create 3 encrypted transactions (all in different states)
38+
transactions.push(create_encrypted_transaction());
39+
transactions.push(create_encrypted_transaction_failed_state());
40+
transactions.push(create_encrypted_transaction_plaintext_state());
41+
42+
// Create 5 plaintext transactions
43+
for _ in 0..5 {
44+
let transaction = create_fee_payer_transaction();
45+
transactions.push(transaction)
46+
}
47+
48+
transactions
49+
}
50+
51+
/// Creates and returns an encrypted transaction
52+
pub fn create_encrypted_transaction() -> SignedTransaction {
53+
let encrypted_payload = EncryptedPayload::Encrypted {
54+
ciphertext: vec![],
55+
extra_config: TransactionExtraConfig::V1 {
56+
multisig_address: None,
57+
replay_protection_nonce: None,
58+
},
59+
payload_hash: HashValue::random(),
60+
};
61+
62+
let transaction_payload = TransactionPayload::EncryptedPayload(encrypted_payload);
63+
create_signed_transaction(transaction_payload, false)
64+
}
65+
66+
/// Creates and returns an encrypted transaction in a failed decryption state
67+
pub fn create_encrypted_transaction_failed_state() -> SignedTransaction {
68+
let encrypted_payload = EncryptedPayload::FailedDecryption {
69+
ciphertext: vec![],
70+
extra_config: TransactionExtraConfig::V1 {
71+
multisig_address: None,
72+
replay_protection_nonce: None,
73+
},
74+
payload_hash: HashValue::random(),
75+
eval_proof: vec![],
76+
};
77+
78+
let transaction_payload = TransactionPayload::EncryptedPayload(encrypted_payload);
79+
create_signed_transaction(transaction_payload, false)
80+
}
81+
82+
/// Creates and returns an encrypted transaction in a plaintext state
83+
pub fn create_encrypted_transaction_plaintext_state() -> SignedTransaction {
84+
let encrypted_payload = EncryptedPayload::Decrypted {
85+
ciphertext: vec![],
86+
extra_config: TransactionExtraConfig::V1 {
87+
multisig_address: None,
88+
replay_protection_nonce: None,
89+
},
90+
payload_hash: HashValue::random(),
91+
eval_proof: vec![],
92+
executable: TransactionExecutable::Empty,
93+
decryption_nonce: 0,
94+
};
95+
96+
let transaction_payload = TransactionPayload::EncryptedPayload(encrypted_payload);
97+
create_signed_transaction(transaction_payload, false)
98+
}
99+
32100
/// Creates and returns an entry function with the given member ID
33101
pub fn create_entry_function(function: MemberId) -> EntryFunction {
34102
let MemberId {

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ impl TransactionFilter {
101101
self.add_multiple_matchers_filter(allow, vec![transaction_matcher])
102102
}
103103

104+
/// Adds an encrypted transaction matcher to the filter
105+
pub fn add_encrypted_transaction_filter(self, allow: bool) -> Self {
106+
let transaction_matcher = TransactionMatcher::EncryptedTransaction;
107+
self.add_multiple_matchers_filter(allow, vec![transaction_matcher])
108+
}
109+
104110
/// Adds an entry function matcher to the filter
105111
pub fn add_entry_function_filter(
106112
self,
@@ -170,6 +176,7 @@ pub enum TransactionMatcher {
170176
EntryFunction(AccountAddress, String, String), // Matches any transaction that calls a specific entry function in a module
171177
AccountAddress(AccountAddress), // Matches any transaction that involves a specific account address
172178
PublicKey(AnyPublicKey), // Matches any transaction that involves a specific public key
179+
EncryptedTransaction, // Matches any encrypted transaction
173180
}
174181

175182
impl TransactionMatcher {
@@ -197,6 +204,9 @@ impl TransactionMatcher {
197204
TransactionMatcher::PublicKey(public_key) => {
198205
matches_transaction_authenticator_public_key(signed_transaction, public_key)
199206
},
207+
TransactionMatcher::EncryptedTransaction => {
208+
matches_encrypted_transaction(signed_transaction)
209+
},
200210
}
201211
}
202212
}
@@ -313,6 +323,14 @@ fn matches_any_public_key_address(any_public_key: &AnyPublicKey, address: &Accou
313323
}
314324
}
315325

326+
/// Returns true iff the transaction is an encrypted transaction
327+
fn matches_encrypted_transaction(signed_transaction: &SignedTransaction) -> bool {
328+
matches!(
329+
signed_transaction.payload(),
330+
TransactionPayload::EncryptedPayload(_)
331+
)
332+
}
333+
316334
/// Returns true iff the transaction's entry function matches the given account address, module name, and function name
317335
fn matches_entry_function(
318336
signed_transaction: &SignedTransaction,

0 commit comments

Comments
 (0)