Skip to content

Commit cc8e00f

Browse files
committed
fix(receipt): update check for unique receipts in v1 and v2
Signed-off-by: Joseph Livesey <[email protected]>
1 parent 0f5bb43 commit cc8e00f

File tree

2 files changed

+26
-21
lines changed

2 files changed

+26
-21
lines changed

tap_aggregator/src/aggregator/v1.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
// Copyright 2023-, Semiotic AI, Inc.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use std::collections::{hash_set, HashSet};
4+
use std::collections::HashSet;
55

66
use anyhow::{bail, Ok, Result};
77
use rayon::prelude::*;
8-
use tap_core::signed_message::{Eip712SignedMessage, SignatureBytes, SignatureBytesExt};
8+
use tap_core::{receipt::WithUniqueId, signed_message::Eip712SignedMessage};
99
use tap_graph::{Receipt, ReceiptAggregateVoucher};
1010
use thegraph_core::alloy::{
1111
dyn_abi::Eip712Domain, primitives::Address, signers::local::PrivateKeySigner,
@@ -19,7 +19,7 @@ pub fn check_and_aggregate_receipts(
1919
wallet: &PrivateKeySigner,
2020
accepted_addresses: &HashSet<Address>,
2121
) -> Result<Eip712SignedMessage<ReceiptAggregateVoucher>> {
22-
check_signatures_unique(receipts)?;
22+
check_signatures_unique(domain_separator, receipts)?;
2323

2424
// Check that the receipts are signed by an accepted signer address
2525
receipts.par_iter().try_for_each(|receipt| {
@@ -93,14 +93,17 @@ fn check_allocation_id(
9393
Ok(())
9494
}
9595

96-
fn check_signatures_unique(receipts: &[Eip712SignedMessage<Receipt>]) -> Result<()> {
97-
let mut receipt_signatures: hash_set::HashSet<SignatureBytes> = hash_set::HashSet::new();
96+
fn check_signatures_unique(
97+
domain_separator: &Eip712Domain,
98+
receipts: &[Eip712SignedMessage<Receipt>],
99+
) -> Result<()> {
100+
let mut receipt_signatures = HashSet::new();
98101
for receipt in receipts.iter() {
99-
let signature = receipt.signature.get_signature_bytes();
102+
let signature = receipt.unique_id(domain_separator)?;
100103
if !receipt_signatures.insert(signature) {
101104
return Err(tap_core::Error::DuplicateReceiptSignature(format!(
102105
"{:?}",
103-
receipt.signature
106+
receipt.unique_id(domain_separator)?
104107
))
105108
.into());
106109
}
@@ -167,7 +170,6 @@ mod tests {
167170

168171
#[rstest]
169172
#[test]
170-
#[should_panic]
171173
fn test_signature_malleability_vulnerability(
172174
keys: (PrivateKeySigner, Address),
173175
allocation_ids: Vec<Address>,
@@ -219,7 +221,7 @@ mod tests {
219221

220222
// This should return an error because the signatures are different
221223
// but the messages are the same, which if allowed would present a security vulnerability
222-
let result = check_signatures_unique(&receipts);
224+
let result = check_signatures_unique(&domain_separator, &receipts);
223225

224226
// The result should be an error because the malleated signature is not treated as unique
225227
// and is detected as a duplicate
@@ -244,7 +246,7 @@ mod tests {
244246
receipts.push(receipt.clone());
245247
receipts.push(receipt);
246248

247-
let res = check_signatures_unique(&receipts);
249+
let res = check_signatures_unique(&domain_separator, &receipts);
248250
assert!(res.is_err());
249251
}
250252

@@ -271,7 +273,7 @@ mod tests {
271273
.unwrap(),
272274
];
273275

274-
let res = check_signatures_unique(&receipts);
276+
let res = check_signatures_unique(&domain_separator, &receipts);
275277
assert!(res.is_ok());
276278
}
277279

tap_aggregator/src/aggregator/v2.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
// Copyright 2023-, Semiotic AI, Inc.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use std::collections::{hash_set, HashSet};
4+
use std::collections::HashSet;
55

66
use anyhow::{bail, Ok, Result};
77
use rayon::prelude::*;
8-
use tap_core::signed_message::{Eip712SignedMessage, SignatureBytes, SignatureBytesExt};
8+
use tap_core::{receipt::WithUniqueId, signed_message::Eip712SignedMessage};
99
use tap_graph::v2::{Receipt, ReceiptAggregateVoucher};
1010
use thegraph_core::alloy::{
1111
dyn_abi::Eip712Domain, primitives::Address, signers::local::PrivateKeySigner,
@@ -19,7 +19,7 @@ pub fn check_and_aggregate_receipts(
1919
wallet: &PrivateKeySigner,
2020
accepted_addresses: &HashSet<Address>,
2121
) -> Result<Eip712SignedMessage<ReceiptAggregateVoucher>> {
22-
check_signatures_unique(receipts)?;
22+
check_signatures_unique(domain_separator, receipts)?;
2323

2424
// Check that the receipts are signed by an accepted signer address
2525
receipts.par_iter().try_for_each(|receipt| {
@@ -148,14 +148,17 @@ fn check_allocation_id(
148148
Ok(())
149149
}
150150

151-
fn check_signatures_unique(receipts: &[Eip712SignedMessage<Receipt>]) -> Result<()> {
152-
let mut receipt_signatures: hash_set::HashSet<SignatureBytes> = hash_set::HashSet::new();
151+
fn check_signatures_unique(
152+
domain_separator: &Eip712Domain,
153+
receipts: &[Eip712SignedMessage<Receipt>],
154+
) -> Result<()> {
155+
let mut receipt_signatures = HashSet::new();
153156
for receipt in receipts.iter() {
154-
let signature = receipt.signature.get_signature_bytes();
157+
let signature = receipt.unique_id(domain_separator)?;
155158
if !receipt_signatures.insert(signature) {
156159
return Err(tap_core::Error::DuplicateReceiptSignature(format!(
157160
"{:?}",
158-
receipt.signature
161+
receipt.unique_id(domain_separator)?
159162
))
160163
.into());
161164
}
@@ -251,7 +254,7 @@ mod tests {
251254
receipts.push(receipt.clone());
252255
receipts.push(receipt);
253256

254-
let res = super::check_signatures_unique(&receipts);
257+
let res = super::check_signatures_unique(&domain_separator, &receipts);
255258
assert!(res.is_err());
256259
}
257260

@@ -281,13 +284,13 @@ mod tests {
281284
.unwrap(),
282285
];
283286

284-
let res = super::check_signatures_unique(&receipts);
287+
let res = super::check_signatures_unique(&domain_separator, &receipts);
285288
assert!(res.is_ok());
286289
}
287290

288291
#[rstest]
289292
#[test]
290-
/// Test that a receipt with a timestamp greater then the rav timestamp passes
293+
/// Test that a receipt with a timestamp greater than the rav timestamp passes
291294
fn check_receipt_timestamps(
292295
keys: (PrivateKeySigner, Address),
293296
allocation_id: Address,

0 commit comments

Comments
 (0)