Skip to content

Commit a4fffbc

Browse files
tmigoneneithanmo
authored andcommitted
fix(aggregator): use split EIP712 domains for TAP v1 and v2 aggregator
Signed-off-by: Tomás Migone <[email protected]>
1 parent 4f19f22 commit a4fffbc

File tree

6 files changed

+65
-22
lines changed

6 files changed

+65
-22
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ criterion = { version = "0.5.1", features = ["async_std"] }
3232
futures-util = "0.3.31"
3333
hyper = { version = "1.6.0", features = ["full"] }
3434
insta = { version = "1.42.2", features = ["json"] }
35-
jsonrpsee = { version = "0.25.1", features = ["macros", "server"] }
35+
jsonrpsee = { version = "0.25.1", features = ["macros", "server", "client"] }
3636
jsonrpsee-core = "0.25.1"
3737
lazy_static = "1.5.0"
3838
log = "0.4.27"

tap_aggregator/src/main.rs

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -54,23 +54,19 @@ struct Args {
5454
#[arg(long, default_value_t = 5000, env = "TAP_METRICS_PORT")]
5555
metrics_port: u16,
5656

57-
/// Domain name to be used for the EIP-712 domain separator.
58-
#[arg(long, env = "TAP_DOMAIN_NAME")]
59-
domain_name: Option<String>,
60-
61-
/// Domain version to be used for the EIP-712 domain separator.
62-
#[arg(long, env = "TAP_DOMAIN_VERSION")]
63-
domain_version: Option<String>,
64-
6557
/// Domain chain ID to be used for the EIP-712 domain separator.
6658
#[arg(long, env = "TAP_DOMAIN_CHAIN_ID")]
6759
domain_chain_id: Option<String>,
6860

69-
/// Domain verifying contract to be used for the EIP-712 domain separator.
61+
/// [TAP v1] Domain verifying contract to be used for the EIP-712 domain separator.
7062
#[arg(long, env = "TAP_DOMAIN_VERIFYING_CONTRACT")]
7163
domain_verifying_contract: Option<Address>,
7264

73-
/// Domain salt to be used for the EIP-712 domain separator.
65+
/// [TAP v2] Domain verifying contract to be used for the EIP-712 domain separator.
66+
#[arg(long, env = "TAP_DOMAIN_VERIFYING_CONTRACT_V2")]
67+
domain_verifying_contract_v2: Option<Address>,
68+
69+
/// [Shared] Domain salt to be used for the EIP-712 domain separator.
7470
#[arg(long, env = "TAP_DOMAIN_SALT")]
7571
domain_salt: Option<String>,
7672

@@ -100,7 +96,8 @@ async fn main() -> Result<()> {
10096
info!("Wallet address: {:#40x}", wallet.address());
10197

10298
// Create the EIP-712 domain separator.
103-
let domain_separator = create_eip712_domain(&args)?;
99+
let domain_separator = create_eip712_domain(&args, TapVersion::V1)?;
100+
let domain_separator_v2 = create_eip712_domain(&args, TapVersion::V2)?;
104101

105102
// Create HashSet of *all* allowed signers
106103
let mut accepted_addresses: HashSet<Address> = std::collections::HashSet::new();
@@ -127,6 +124,7 @@ async fn main() -> Result<()> {
127124
wallet,
128125
accepted_addresses,
129126
domain_separator,
127+
domain_separator_v2,
130128
args.max_request_body_size,
131129
args.max_response_body_size,
132130
args.max_connections,
@@ -142,9 +140,9 @@ async fn main() -> Result<()> {
142140
Ok(())
143141
}
144142

145-
fn create_eip712_domain(args: &Args) -> Result<Eip712Domain> {
143+
/// Creates the TAP EIP-712 domain separator based on the provided arguments and TAP version
144+
fn create_eip712_domain(args: &Args, version: TapVersion) -> Result<Eip712Domain> {
146145
// Transform the args into the types expected by Eip712Domain::new().
147-
148146
// Transform optional strings into optional Cow<str>.
149147
// Transform optional strings into optional U256.
150148
if args.domain_chain_id.is_some() {
@@ -161,12 +159,9 @@ fn create_eip712_domain(args: &Args) -> Result<Eip712Domain> {
161159
}
162160

163161
// Transform optional strings into optional Address.
164-
let verifying_contract: Option<Address> = args.domain_verifying_contract;
165-
166-
// Determine TAP version from domain_version argument
167-
let version = match args.domain_version.as_deref() {
168-
Some("2") => TapVersion::V2,
169-
_ => TapVersion::V1, // Default to V1
162+
let verifying_contract: Option<Address> = match version {
163+
TapVersion::V1 => args.domain_verifying_contract,
164+
TapVersion::V2 => args.domain_verifying_contract_v2,
170165
};
171166

172167
// Create the EIP-712 domain separator.

tap_aggregator/src/server.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ pub trait Rpc {
8585
#[method(name = "eip712domain_info")]
8686
fn eip712_domain_info(&self) -> JsonRpcResult<Eip712Domain>;
8787

88+
/// Returns the v2 EIP-712 domain separator information used by this server.
89+
/// The client is able to verify the signatures of the receipts and receipt aggregate vouchers.
90+
#[cfg(feature = "v2")]
91+
#[method(name = "eip712domain_info_v2")]
92+
fn eip712_domain_info_v2(&self) -> JsonRpcResult<Eip712Domain>;
93+
8894
/// Aggregates the given receipts into a receipt aggregate voucher.
8995
/// Returns an error if the user expected API version is not supported.
9096
#[method(name = "aggregate_receipts")]
@@ -112,6 +118,8 @@ struct RpcImpl {
112118
wallet: PrivateKeySigner,
113119
accepted_addresses: HashSet<Address>,
114120
domain_separator: Eip712Domain,
121+
#[cfg(feature = "v2")]
122+
domain_separator_v2: Eip712Domain,
115123
kafka: Option<rdkafka::producer::ThreadedProducer<rdkafka::producer::DefaultProducerContext>>,
116124
}
117125

@@ -340,7 +348,7 @@ impl v2::tap_aggregator_server::TapAggregator for RpcImpl {
340348
let receipts_count: u64 = receipts.len() as u64;
341349

342350
match aggregator::v2::check_and_aggregate_receipts(
343-
&self.domain_separator,
351+
&self.domain_separator_v2,
344352
receipts.as_slice(),
345353
previous_rav,
346354
&self.wallet,
@@ -381,6 +389,11 @@ impl RpcServer for RpcImpl {
381389
Ok(JsonRpcResponse::ok(self.domain_separator.clone()))
382390
}
383391

392+
#[cfg(feature = "v2")]
393+
fn eip712_domain_info_v2(&self) -> JsonRpcResult<Eip712Domain> {
394+
Ok(JsonRpcResponse::ok(self.domain_separator_v2.clone()))
395+
}
396+
384397
fn aggregate_receipts(
385398
&self,
386399
api_version: String,
@@ -435,7 +448,7 @@ impl RpcServer for RpcImpl {
435448
api_version,
436449
&self.wallet,
437450
&self.accepted_addresses,
438-
&self.domain_separator,
451+
&self.domain_separator_v2,
439452
receipts,
440453
previous_rav,
441454
) {
@@ -468,6 +481,7 @@ pub async fn run_server(
468481
wallet: PrivateKeySigner,
469482
accepted_addresses: HashSet<Address>,
470483
domain_separator: Eip712Domain,
484+
domain_separator_v2: Eip712Domain,
471485
max_request_body_size: u32,
472486
max_response_body_size: u32,
473487
max_concurrent_connections: u32,
@@ -478,6 +492,7 @@ pub async fn run_server(
478492
wallet,
479493
accepted_addresses,
480494
domain_separator,
495+
domain_separator_v2,
481496
kafka,
482497
};
483498
let (json_rpc_service, _) = create_json_rpc_service(
@@ -661,6 +676,10 @@ mod tests {
661676
fn domain_separator() -> Eip712Domain {
662677
tap_eip712_domain(1, Address::from([0x11u8; 20]), TapVersion::V1)
663678
}
679+
#[fixture]
680+
fn domain_separator_v2() -> Eip712Domain {
681+
tap_eip712_domain(1, Address::from([0x22u8; 20]), TapVersion::V2)
682+
}
664683

665684
#[fixture]
666685
fn http_request_size_limit() -> u32 {
@@ -681,6 +700,7 @@ mod tests {
681700
#[tokio::test]
682701
async fn protocol_version(
683702
domain_separator: Eip712Domain,
703+
domain_separator_v2: Eip712Domain,
684704
http_request_size_limit: u32,
685705
http_response_size_limit: u32,
686706
http_max_concurrent_connections: u32,
@@ -694,6 +714,7 @@ mod tests {
694714
keys_main.wallet,
695715
HashSet::from([keys_main.address]),
696716
domain_separator,
717+
domain_separator_v2,
697718
http_request_size_limit,
698719
http_response_size_limit,
699720
http_max_concurrent_connections,
@@ -720,6 +741,7 @@ mod tests {
720741
#[tokio::test]
721742
async fn signed_rav_is_valid_with_no_previous_rav(
722743
domain_separator: Eip712Domain,
744+
domain_separator_v2: Eip712Domain,
723745
http_request_size_limit: u32,
724746
http_response_size_limit: u32,
725747
http_max_concurrent_connections: u32,
@@ -746,6 +768,7 @@ mod tests {
746768
keys_main.wallet.clone(),
747769
HashSet::from([keys_main.address, keys_0.address, keys_1.address]),
748770
domain_separator.clone(),
771+
domain_separator_v2.clone(),
749772
http_request_size_limit,
750773
http_response_size_limit,
751774
http_max_concurrent_connections,
@@ -803,6 +826,7 @@ mod tests {
803826
#[tokio::test]
804827
async fn signed_rav_is_valid_with_previous_rav(
805828
domain_separator: Eip712Domain,
829+
domain_separator_v2: Eip712Domain,
806830
http_request_size_limit: u32,
807831
http_response_size_limit: u32,
808832
http_max_concurrent_connections: u32,
@@ -829,6 +853,7 @@ mod tests {
829853
keys_main.wallet.clone(),
830854
HashSet::from([keys_main.address, keys_0.address, keys_1.address]),
831855
domain_separator.clone(),
856+
domain_separator_v2.clone(),
832857
http_request_size_limit,
833858
http_response_size_limit,
834859
http_max_concurrent_connections,
@@ -893,6 +918,7 @@ mod tests {
893918
#[tokio::test]
894919
async fn invalid_api_version(
895920
domain_separator: Eip712Domain,
921+
domain_separator_v2: Eip712Domain,
896922
http_request_size_limit: u32,
897923
http_response_size_limit: u32,
898924
http_max_concurrent_connections: u32,
@@ -907,6 +933,7 @@ mod tests {
907933
keys_main.wallet.clone(),
908934
HashSet::from([keys_main.address]),
909935
domain_separator.clone(),
936+
domain_separator_v2.clone(),
910937
http_request_size_limit,
911938
http_response_size_limit,
912939
http_max_concurrent_connections,
@@ -976,6 +1003,7 @@ mod tests {
9761003
#[tokio::test]
9771004
async fn request_size_limit(
9781005
domain_separator: Eip712Domain,
1006+
domain_separator_v2: Eip712Domain,
9791007
http_response_size_limit: u32,
9801008
http_max_concurrent_connections: u32,
9811009
allocation_ids: Vec<Address>,
@@ -999,6 +1027,7 @@ mod tests {
9991027
keys_main.wallet.clone(),
10001028
HashSet::from([keys_main.address]),
10011029
domain_separator.clone(),
1030+
domain_separator_v2.clone(),
10021031
http_request_size_limit,
10031032
http_response_size_limit,
10041033
http_max_concurrent_connections,

tap_aggregator/tests/aggregate_test.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use tonic::codec::CompressionEncoding;
1717
#[tokio::test]
1818
async fn aggregation_test() {
1919
let domain_separator = tap_eip712_domain(1, Address::ZERO, TapVersion::V1);
20+
let domain_separator_v2 = tap_eip712_domain(1, Address::ZERO, TapVersion::V2);
2021

2122
let wallet = PrivateKeySigner::random();
2223

@@ -31,6 +32,7 @@ async fn aggregation_test() {
3132
wallet.clone(),
3233
accepted_addresses,
3334
domain_separator.clone(),
35+
domain_separator_v2.clone(),
3436
max_request_body_size,
3537
max_response_body_size,
3638
max_concurrent_connections,

tap_aggregator/tests/aggregate_v1_and_v2.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use tonic::codec::CompressionEncoding;
2121
#[tokio::test]
2222
async fn aggregation_test() {
2323
let domain_separator = tap_eip712_domain(1, Address::ZERO, TapVersion::V2);
24+
let domain_separator_v2 = tap_eip712_domain(1, Address::ZERO, TapVersion::V2);
2425

2526
let wallet = PrivateKeySigner::random();
2627

@@ -35,6 +36,7 @@ async fn aggregation_test() {
3536
wallet.clone(),
3637
accepted_addresses,
3738
domain_separator.clone(),
39+
domain_separator_v2.clone(),
3840
max_request_body_size,
3941
max_response_body_size,
4042
max_concurrent_connections,

tap_integration_tests/tests/showcase.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ fn domain_separator() -> Eip712Domain {
124124
tap_eip712_domain(1, Address::from([0x11u8; 20]), TapVersion::V1)
125125
}
126126

127+
#[fixture]
128+
fn domain_separator_v2() -> Eip712Domain {
129+
tap_eip712_domain(1, Address::from([0x22u8; 20]), TapVersion::V2)
130+
}
131+
127132
// Query price will typically be set by the Indexer. It's assumed to be part of the Indexer service.
128133
#[fixture]
129134
#[once]
@@ -336,6 +341,7 @@ fn wrong_requests(
336341
async fn single_indexer_test_server(
337342
keys_sender: PrivateKeySigner,
338343
domain_separator: Eip712Domain,
344+
domain_separator_v2: Eip712Domain,
339345
http_request_size_limit: u32,
340346
http_response_size_limit: u32,
341347
http_max_concurrent_connections: u32,
@@ -347,6 +353,7 @@ async fn single_indexer_test_server(
347353
let (sender_aggregator_handle, sender_aggregator_addr) = start_sender_aggregator(
348354
keys_sender,
349355
domain_separator.clone(),
356+
domain_separator_v2.clone(),
350357
http_request_size_limit,
351358
http_response_size_limit,
352359
http_max_concurrent_connections,
@@ -375,6 +382,7 @@ async fn single_indexer_test_server(
375382
async fn two_indexers_test_servers(
376383
keys_sender: PrivateKeySigner,
377384
domain_separator: Eip712Domain,
385+
domain_separator_v2: Eip712Domain,
378386
http_request_size_limit: u32,
379387
http_response_size_limit: u32,
380388
http_max_concurrent_connections: u32,
@@ -394,6 +402,7 @@ async fn two_indexers_test_servers(
394402
let (sender_aggregator_handle, sender_aggregator_addr) = start_sender_aggregator(
395403
keys_sender,
396404
domain_separator.clone(),
405+
domain_separator_v2.clone(),
397406
http_request_size_limit,
398407
http_response_size_limit,
399408
http_max_concurrent_connections,
@@ -445,6 +454,7 @@ async fn two_indexers_test_servers(
445454
async fn single_indexer_wrong_sender_test_server(
446455
wrong_keys_sender: PrivateKeySigner,
447456
domain_separator: Eip712Domain,
457+
domain_separator_v2: Eip712Domain,
448458
http_request_size_limit: u32,
449459
http_response_size_limit: u32,
450460
http_max_concurrent_connections: u32,
@@ -456,6 +466,7 @@ async fn single_indexer_wrong_sender_test_server(
456466
let (sender_aggregator_handle, sender_aggregator_addr) = start_sender_aggregator(
457467
wrong_keys_sender,
458468
domain_separator.clone(),
469+
domain_separator_v2.clone(),
459470
http_request_size_limit,
460471
http_response_size_limit,
461472
http_max_concurrent_connections,
@@ -692,6 +703,7 @@ async fn test_tap_manager_rav_timestamp_cuttoff(
692703
async fn test_tap_aggregator_rav_timestamp_cuttoff(
693704
keys_sender: PrivateKeySigner,
694705
domain_separator: Eip712Domain,
706+
domain_separator_v2: Eip712Domain,
695707
http_request_size_limit: u32,
696708
http_response_size_limit: u32,
697709
http_max_concurrent_connections: u32,
@@ -703,6 +715,7 @@ async fn test_tap_aggregator_rav_timestamp_cuttoff(
703715
let (sender_handle, sender_addr) = start_sender_aggregator(
704716
keys_sender,
705717
domain_separator,
718+
domain_separator_v2,
706719
http_request_size_limit,
707720
http_response_size_limit,
708721
http_max_concurrent_connections,
@@ -827,6 +840,7 @@ async fn start_indexer_server(
827840
async fn start_sender_aggregator(
828841
keys: PrivateKeySigner,
829842
domain_separator: Eip712Domain,
843+
domain_separator_v2: Eip712Domain,
830844
http_request_size_limit: u32,
831845
http_response_size_limit: u32,
832846
http_max_concurrent_connections: u32,
@@ -843,6 +857,7 @@ async fn start_sender_aggregator(
843857
keys,
844858
accepted_addresses,
845859
domain_separator,
860+
domain_separator_v2,
846861
http_request_size_limit,
847862
http_response_size_limit,
848863
http_max_concurrent_connections,

0 commit comments

Comments
 (0)