From 203e5ef871717b37f9ccc46217b308cf5cb3cc22 Mon Sep 17 00:00:00 2001 From: Carlos V Date: Thu, 28 Dec 2023 16:01:39 -0600 Subject: [PATCH 1/2] Added test for rav redeem and removed unecesary code Co-authored-by: Ricardo Romero --- .../src/__tests__/redeem-rav-test.ts | 197 ++++++++++++++++++ .../src/allocations/query-fees.ts | 37 +--- 2 files changed, 198 insertions(+), 36 deletions(-) create mode 100644 packages/indexer-common/src/__tests__/redeem-rav-test.ts diff --git a/packages/indexer-common/src/__tests__/redeem-rav-test.ts b/packages/indexer-common/src/__tests__/redeem-rav-test.ts new file mode 100644 index 000000000..48b38b734 --- /dev/null +++ b/packages/indexer-common/src/__tests__/redeem-rav-test.ts @@ -0,0 +1,197 @@ +import { AllocationReceiptCollector } from './../allocations/query-fees' +import { AllocationStatus, SubgraphDeployment } from '@graphprotocol/indexer-common' +import { + Logger, + Metrics, + Eventual, + SubgraphDeploymentID, + EventualValue, +} from '@graphprotocol/common-ts' +import { BigNumber, Contract, providers, Wallet } from 'ethers' +import { + Gateway, + IndexerOptions, + TransactionMonitoring, +} from './../network-specification' +import { + NetworkContracts as EscrowContracts, + connectContracts, +} from '@semiotic-labs/tap-contracts-bindings' +import { toAddress } from '@graphprotocol/common-ts' +import { Allocation, QueryFeeModels, TransactionManager, specification as spec } from '..' +function createAllocation(id: string, indexer: string): Allocation { + const subgraphDeploymentID = new SubgraphDeploymentID('mock-deployment-id') + const mockSubgraphDeployment: SubgraphDeployment = { + id: subgraphDeploymentID, + deniedAt: Date.now(), + stakedTokens: BigNumber.from('1000'), + signalledTokens: BigNumber.from('500'), + queryFeesAmount: BigNumber.from('200'), + protocolNetwork: 'mainnet', + } + return { + id: toAddress(`0x${id}`), + status: AllocationStatus.ACTIVE, + subgraphDeployment: mockSubgraphDeployment, + indexer: toAddress(`0x${indexer}`), + allocatedTokens: BigNumber.from(1000), + createdAtEpoch: 1, + createdAtBlockHash: '', + closedAtEpoch: 1, + closedAtEpochStartBlockHash: '', + previousEpochStartBlockHash: '', + closedAtBlockHash: '', + poi: '', + queryFeeRebates: BigNumber.from(1000), + queryFeesCollected: BigNumber.from(1000), + } +} +// const histogramConfig = { +// name: 'test_histogram', +// help: 'Histogram for testing purposes', +// labelNames: ['label1', 'label2'], +// buckets: [0.1, 5, 15, 50, 100, 500], +// } +//const mockHistogram = new Histogram(histogramConfig) + +describe('AllocationReceiptCollector', () => { + let mockLogger: Logger + let mockMetrics: Metrics + let transactionManager: TransactionManager + let escrowContracts: EscrowContracts + let paused: Eventual + let isOperator: Eventual + let mockModel: QueryFeeModels + let allocation: Allocation + let mockAllocationExchange: Contract + let networkSpecification: spec.NetworkSpecification + let allocations: Eventual + const TAPVerifierAddress = '0x995629b19667Ae71483DC812c1B5a35fCaaAF4B8' + const escrowAddress = '0x94dFeceb91678ec912ef8f14c72721c102ed2Df7' + const indexerAddress = '0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b' //<--receiver + //const gatewayAddress = '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1' + const allocationID = '0x3fD652C93dFA333979ad762Cf581Df89BaBa6795' + const allocationIDTrkrAddress = '0x25AF99b922857C37282f578F428CB7f34335B379' + const rpc_url = 'localhost:8545' + const chainId = 1337 + + beforeEach(async () => { + const provider = new providers.JsonRpcProvider() + + const { allocationIDTracker, escrow, tapVerifier } = await connectContracts( + provider, + chainId, + { + [chainId]: { + TAPVerifier: TAPVerifierAddress, + AllocationIDTracker: allocationIDTrkrAddress, + Escrow: escrowAddress, + }, + }, + ) + + allocation = createAllocation(allocationID, indexerAddress) + const specification: TransactionMonitoring = { + gasIncreaseTimeout: 240, + gasIncreaseFactor: 1.2, + gasPriceMax: 50000, + maxTransactionAttempts: 3, + } + const existingAllocations: Allocation[] = [allocation] + + allocations = new EventualValue(existingAllocations) + + networkSpecification.networkIdentifier = '' // <-- Whats this + networkSpecification.gateway = Gateway.parse({ + url: rpc_url, // <-- Url is it rpc url too? + }) + networkSpecification.indexerOptions = IndexerOptions.parse({ + mnemonic: + 'myth like bonus scare over problem client lizard pioneer submit female collect', + url: rpc_url, // <-- Url is it rpc url too? + }) + + const wallet = new Wallet( + '6370fd033278c143179d81c5526140625662b8daa446c22ee2d73db3707e620c', // <-- + provider, + ) // <-- Is this the Gateway PK? + + mockLogger = { + error: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + child: jest.fn(), + } as unknown as Logger + + mockMetrics = { + ravsRedeemDuration: { + startTimer: jest.fn(() => jest.fn()), + }, + invalidRavRedeems: { + inc: jest.fn(), + }, + ravCollectedFees: { + set: jest.fn(), + }, + failedRavRedeems: { + inc: jest.fn(), + }, + } as unknown as Metrics + + transactionManager = new TransactionManager( + provider, + wallet, + paused, + isOperator, + specification, + ) + // const collectorOptions = { + // logger: mockLogger, + // metrics: mockMetrics, + // transactionManager: transactionManager, + // models: mockModel, + // allocationExchange: mockAllocationExchange, + // escrowContracts: escrowContracts, + // allocations: allocations, + // networkSpecification: specification, + // } + }) + + it('should log an error if escrow contracts are undefined', async () => { + const signedRavs = [ + { + message: { + allocationId: allocationID, + timestampNs: 123, + valueAggregate: 5, + }, + signature: '', + }, + ] + try { + const collector = await AllocationReceiptCollector.create({ + logger: mockLogger, + metrics: mockMetrics, + transactionManager: transactionManager, + models: mockModel, + allocationExchange: mockAllocationExchange, + escrowContracts: escrowContracts, + allocations: allocations, + networkSpecification: networkSpecification, + }) + + await (collector as any).submitRAVs(signedRavs) + } catch (error) { + console.error('Error creating AllocationReceiptCollector:', error) + } + + // Check if the error logging method was called + expect(mockLogger.error).toHaveBeenCalled() + expect(mockLogger.error).toHaveBeenCalledWith( + expect.any(String), + expect.objectContaining({ signedRavs }), + ) + }) + + // ... other test cases +}) diff --git a/packages/indexer-common/src/allocations/query-fees.ts b/packages/indexer-common/src/allocations/query-fees.ts index b8b9990dc..fe66f5b15 100644 --- a/packages/indexer-common/src/allocations/query-fees.ts +++ b/packages/indexer-common/src/allocations/query-fees.ts @@ -152,7 +152,7 @@ export class AllocationReceiptCollector implements ReceiptCollector { collector.startReceiptCollecting() collector.startVoucherProcessing() if (collector.escrowContracts) { - collector.logger.info(`RAV processing is initiated`); + collector.logger.info(`RAV processing is initiated`) collector.startRAVProcessing() } await collector.queuePendingReceiptsFromDatabase() @@ -801,41 +801,6 @@ export class AllocationReceiptCollector implements ReceiptCollector { stopTimer() } - // Postprocess obsolete RAVs from the database - logger.info(`Successfully redeemed RAV, delete local copy`) - try { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - await this.models.allocationSummaries.sequelize!.transaction( - async (transaction) => { - for (const signedRav of signedRavs) { - const [summary] = await ensureAllocationSummary( - this.models, - toAddress(signedRav.rav.allocationId), - transaction, - this.protocolNetwork, - ) - summary.withdrawnFees = BigNumber.from(summary.withdrawnFees) - .add(signedRav.rav.valueAggregate) - .toString() - await summary.save({ transaction }) - } - }, - ) - - await this.models.receiptAggregateVouchers.destroy({ - where: { - allocation_id: signedRavs.map((signedRav) => signedRav.rav.allocationId), - }, - }) - signedRavs.map((signedRav) => - this.metrics.successRavRedeems.inc({ allocation: signedRav.rav.allocationId }), - ) - logger.info(`Successfully deleted local RAV copy`) - } catch (err) { - logger.warn(`Failed to delete local RAV copy, will try again later`, { - err, - }) - } } public async queuePendingReceiptsFromDatabase(): Promise { From cf88f52354563975e190abc8e0c2e8758e4f564d Mon Sep 17 00:00:00 2001 From: Carlos V Date: Fri, 9 Feb 2024 13:15:01 -0600 Subject: [PATCH 2/2] yarn lock change --- yarn.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7ee56aec3..a9665b592 100644 --- a/yarn.lock +++ b/yarn.lock @@ -868,7 +868,7 @@ "@graphprotocol/cost-model@0.1.16": version "0.1.16" - resolved "https://registry.npmjs.org/@graphprotocol/cost-model/-/cost-model-0.1.16.tgz" + resolved "https://registry.yarnpkg.com/@graphprotocol/cost-model/-/cost-model-0.1.16.tgz#42e6889a23934f293f119db9ac23159be019df0c" integrity sha512-oDBhXH4sdKLduw0PgcK6rWPrzqJ4eFH9BTWz81c2iMIdTrm3n92eixCrhTwB3Nd1JpM1y0Bz9sMIvRGvC6htoA== dependencies: "@mapbox/node-pre-gyp" "1.0.9" @@ -2066,7 +2066,7 @@ "@mapbox/node-pre-gyp@1.0.9": version "1.0.9" - resolved "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz" + resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz#09a8781a3a036151cdebbe8719d6f8b25d4058bc" integrity sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw== dependencies: detect-libc "^2.0.0" @@ -2677,10 +2677,10 @@ "@noble/hashes" "~1.3.0" "@scure/base" "~1.1.0" -"@semiotic-labs/tap-contracts-bindings@^1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@semiotic-labs/tap-contracts-bindings/-/tap-contracts-bindings-1.1.0.tgz#94c18951eb4dbec1008f1e3b27134544981904d5" - integrity sha512-oVLx50mmhtypfORe6orchkmtKS6V09RJ0q9IkxG/ObVSQKZ/xCrdOwGIVJYUajhi6QdEt0Xh27b8rQVCtPKvsA== +"@semiotic-labs/tap-contracts-bindings@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@semiotic-labs/tap-contracts-bindings/-/tap-contracts-bindings-1.2.0.tgz#83835487dbfdae54f7dde2954389faf8cd12a559" + integrity sha512-bJfZAXug551h/vTYmo4XJh0BxV5XEe7FzZRXhdH2Hza+QZEp/pkx+JRppJjlvCpfqVglgzwLfp2X3CXlDvJm9A== dependencies: "@typechain/ethers-v5" "^11.1.2" abitype "^0.10.3" @@ -4291,7 +4291,7 @@ caniuse-lite@^1.0.30001517: cargo-cp-artifact@0.1.6: version "0.1.6" - resolved "https://registry.npmjs.org/cargo-cp-artifact/-/cargo-cp-artifact-0.1.6.tgz" + resolved "https://registry.yarnpkg.com/cargo-cp-artifact/-/cargo-cp-artifact-0.1.6.tgz#df1bc9dad036ae0f4230639a869182e1d5850f89" integrity sha512-CQw0doK/aaF7j041666XzuilHxqMxaKkn+I5vmBsd8SAwS0cO5CqVEVp0xJwOKstyqWZ6WK4Ww3O6p26x/Goyg== cargo-cp-artifact@0.1.7: