Skip to content

Commit f74d18b

Browse files
committed
chore: validate receipt signer
1 parent 106f212 commit f74d18b

File tree

5 files changed

+60
-15
lines changed

5 files changed

+60
-15
lines changed

packages/indexer-common/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"@bufbuild/protobuf": "2.2.3",
2626
"@graphprotocol/common-ts": "2.0.11",
2727
"@graphprotocol/cost-model": "0.1.18",
28-
"@graphprotocol/dips-proto": "0.2.0",
28+
"@graphprotocol/dips-proto": "0.2.1",
2929
"@grpc/grpc-js": "^1.12.6",
3030
"@semiotic-labs/tap-contracts-bindings": "^1.2.1",
3131
"@thi.ng/heaps": "1.2.38",

packages/indexer-common/src/allocations/escrow-accounts.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ export type EscrowAccountResponse = {
1313
}[]
1414
}
1515

16+
export type EscrowSenderResponse = {
17+
signer: {
18+
sender: {
19+
id: string
20+
}
21+
}
22+
}
23+
1624
export class EscrowAccounts {
1725
constructor(private sendersBalances: Map<Address, U256>) {}
1826

@@ -65,3 +73,26 @@ export const getEscrowAccounts = async (
6573
}
6674
return EscrowAccounts.fromResponse(result.data)
6775
}
76+
77+
export const getEscrowSenderForSigner = async (
78+
tapSubgraph: SubgraphClient,
79+
signer: Address,
80+
): Promise<Address> => {
81+
const signerLower = signer.toLowerCase()
82+
const result = await tapSubgraph.query<EscrowSenderResponse>(
83+
gql`
84+
query EscrowAccountQuery($signer: ID!) {
85+
signer(id: $signer) {
86+
sender {
87+
id
88+
}
89+
}
90+
}
91+
`,
92+
{ signer: signerLower },
93+
)
94+
if (!result.data) {
95+
throw `There was an error while querying Tap Subgraph. Errors: ${result.error}`
96+
}
97+
return toAddress(result.data.signer.sender.id)
98+
}

packages/indexer-common/src/indexing-fees/dips.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { formatGRT, Logger, SubgraphDeploymentID } from '@graphprotocol/common-ts'
22
import {
33
AllocationManager,
4+
getEscrowSenderForSigner,
45
GraphNode,
56
IndexerManagementModels,
67
IndexingDecisionBasis,
@@ -12,19 +13,19 @@ import {
1213
import { Op } from 'sequelize'
1314

1415
import {
15-
createDipperServiceClient,
16+
createGatewayDipsServiceClient,
1617
createSignedCancellationRequest,
1718
createSignedCollectionRequest,
1819
decodeTapReceipt,
19-
} from './dipper-service-client'
20+
} from './gateway-dips-service-client'
2021
import {
2122
CollectPaymentStatus,
22-
DipperServiceClientImpl,
23+
GatewayDipsServiceClientImpl,
2324
} from '@graphprotocol/dips-proto/generated/gateway'
2425
import { IndexingAgreement } from '../indexer-management/models/indexing-agreement'
2526

2627
export class DipsManager {
27-
private dipperServiceClient: DipperServiceClientImpl
28+
private gatewayDipsServiceClient: GatewayDipsServiceClientImpl
2829

2930
constructor(
3031
private logger: Logger,
@@ -36,7 +37,7 @@ export class DipsManager {
3637
if (!this.network.specification.indexerOptions.dipperEndpoint) {
3738
throw new Error('dipperEndpoint is not set')
3839
}
39-
this.dipperServiceClient = createDipperServiceClient(
40+
this.gatewayDipsServiceClient = createGatewayDipsServiceClient(
4041
this.network.specification.indexerOptions.dipperEndpoint,
4142
)
4243
}
@@ -54,7 +55,7 @@ export class DipsManager {
5455
agreement.id,
5556
this.network.wallet,
5657
)
57-
await this.dipperServiceClient.CancelAgreement({
58+
await this.gatewayDipsServiceClient.CancelAgreement({
5859
version: 1,
5960
signedCancellation: cancellation,
6061
})
@@ -117,7 +118,7 @@ export class DipsManager {
117118
this.network.wallet,
118119
)
119120
try {
120-
const response = await this.dipperServiceClient.CollectPayment({
121+
const response = await this.gatewayDipsServiceClient.CollectPayment({
121122
version: 1,
122123
signedCollection: collection,
123124
})
@@ -130,6 +131,19 @@ export class DipsManager {
130131
response.tapReceipt,
131132
this.network.tapCollector?.tapContracts.tapVerifier.address,
132133
)
134+
// TODO: check that the signer of the TAP receipt is a signer
135+
// on the corresponding escrow account for the payer (sender) of the
136+
// indexing agreement
137+
const escrowSender = await getEscrowSenderForSigner(
138+
this.network.tapCollector?.tapSubgraph,
139+
tapReceipt.signer_address,
140+
)
141+
if (escrowSender !== agreement.payer) {
142+
// TODO: should we cancel the agreement here?
143+
throw new Error(
144+
'Signer of TAP receipt is not a signer on the indexing agreement',
145+
)
146+
}
133147
await this.network.queryFeeModels.scalarTapReceipts.create(tapReceipt)
134148
} else {
135149
this.logger.error(`Error collecting payment for agreement ${agreement.id}`, {

packages/indexer-common/src/indexing-fees/dipper-service-client.ts renamed to packages/indexer-common/src/indexing-fees/gateway-dips-service-client.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Client, credentials } from '@grpc/grpc-js'
22
import { UnaryCallback } from '@grpc/grpc-js/build/src/client'
3-
import { DipperServiceClientImpl } from '@graphprotocol/dips-proto/generated/gateway'
3+
import { GatewayDipsServiceClientImpl } from '@graphprotocol/dips-proto/generated/gateway'
44
import { Wallet } from 'ethers'
55
import {
66
_TypedDataEncoder,
@@ -156,7 +156,7 @@ export const createRpc = (url: string): Rpc => {
156156
return { request }
157157
}
158158

159-
export const createDipperServiceClient = (url: string) => {
159+
export const createGatewayDipsServiceClient = (url: string) => {
160160
const rpc = createRpc(url)
161-
return new DipperServiceClientImpl(rpc)
161+
return new GatewayDipsServiceClientImpl(rpc)
162162
}

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -798,10 +798,10 @@
798798
"@mapbox/node-pre-gyp" "1.0.11"
799799
cargo-cp-artifact "0.1.8"
800800

801-
"@graphprotocol/[email protected].0":
802-
version "0.2.0"
803-
resolved "https://registry.yarnpkg.com/@graphprotocol/dips-proto/-/dips-proto-0.2.0.tgz#e86ceff0dd30ea8ee3b89e84b5b6ad598301ac13"
804-
integrity sha512-Ppt5XZNCrdTT0PwN1UTYIoDBFS11sC4E83yxK6O6rpOHwsjaCw/bM1vwR7JOl64WC+0Jy0fEhOwWEaRBLtAxaQ==
801+
"@graphprotocol/[email protected].1":
802+
version "0.2.1"
803+
resolved "https://registry.yarnpkg.com/@graphprotocol/dips-proto/-/dips-proto-0.2.1.tgz#e65b6a8dfdefb5604da96da4eaaeb0fe096a0627"
804+
integrity sha512-1+6+M7P/xsmEHPRtPX5tO6yCdCDkEvg+Owc0/GJfKpmJmFdN+hxYDvAZ4GD1drLilsyxR/iLQxEvHHQsU3FoxA==
805805

806806
"@graphprotocol/[email protected]":
807807
version "0.7.1"

0 commit comments

Comments
 (0)