From d3bdf31e402fe2f08496ec942242d3e1d2546610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 3 Oct 2024 11:36:55 -0300 Subject: [PATCH] feat: add ops script for query dispute testing and sdk modifications to support it (#934) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../ops/testDisputeConflict/acceptDispute.ts | 20 ++++++++ .../ops/testDisputeConflict/createDispute.ts | 51 +++++++++++++++++++ .../ops/testDisputeConflict/setupIndexer.ts | 40 +++++++++++++++ packages/sdk/src/deployments/index.ts | 1 + .../deployments/network/actions/disputes.ts | 20 ++++++++ .../deployments/network/actions/staking.ts | 16 +++--- 6 files changed, 138 insertions(+), 10 deletions(-) create mode 100644 packages/contracts/scripts/ops/testDisputeConflict/acceptDispute.ts create mode 100644 packages/contracts/scripts/ops/testDisputeConflict/createDispute.ts create mode 100644 packages/contracts/scripts/ops/testDisputeConflict/setupIndexer.ts create mode 100644 packages/sdk/src/deployments/network/actions/disputes.ts diff --git a/packages/contracts/scripts/ops/testDisputeConflict/acceptDispute.ts b/packages/contracts/scripts/ops/testDisputeConflict/acceptDispute.ts new file mode 100644 index 000000000..013daec30 --- /dev/null +++ b/packages/contracts/scripts/ops/testDisputeConflict/acceptDispute.ts @@ -0,0 +1,20 @@ +import { Wallet } from 'ethers' +import hre from 'hardhat' + +async function main() { + const graph = hre.graph() + const arbitratorPrivateKey = process.env.ARBITRATOR_PRIVATE_KEY + const arbitrator = new Wallet(arbitratorPrivateKey, graph.provider) + console.log('Arbitrator:', arbitrator.address) + + const disputeId = '0x35e6e68aa71ee59cb710d8005563d63d644f11f2eee879eca9bc22f523c9fade' + console.log('Dispute ID:', disputeId) + + // Accept dispute + await graph.contracts.DisputeManager.connect(arbitrator).acceptDispute(disputeId) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/packages/contracts/scripts/ops/testDisputeConflict/createDispute.ts b/packages/contracts/scripts/ops/testDisputeConflict/createDispute.ts new file mode 100644 index 000000000..26df99a4a --- /dev/null +++ b/packages/contracts/scripts/ops/testDisputeConflict/createDispute.ts @@ -0,0 +1,51 @@ +import { + GraphChainId, + buildAttestation, + encodeAttestation, + randomHexBytes, +} from '@graphprotocol/sdk' +import hre from 'hardhat' + +async function main() { + const graph = hre.graph() + const deployer = await graph.getDeployer() + const [indexer] = await graph.getTestAccounts() + const indexerChannelPrivKey = '0x82226c70efbe0d9525a5f9dc85c29b11fed1f46798a416b7626e21fdd6518d08' + + console.log('Deployer:', deployer.address) + console.log('Indexer:', indexer.address) + + const receipt = { + requestCID: '0x8bec406793c8e1c5d4bd4e059833e95b7a9aeed6a118cbe335a79735836f9ff7', + responseCID: '0xbdfc41643b5ff8d55f6cdb50f05575e1fdf177fa54d98cae1b9c76d8b360ff57', + subgraphDeploymentID: '0xa3bfbfc6f53fd8a61b78e0b9a90c7fbe9ff290cba87b045bc476137fb2963cf9', + } + const receipt2 = { ...receipt, responseCID: randomHexBytes() } + + const attestation1 = await buildAttestation( + receipt, + indexerChannelPrivKey, + graph.contracts.DisputeManager.address, + graph.chainId as GraphChainId, + ) + const attestation2 = await buildAttestation( + receipt2, + indexerChannelPrivKey, + graph.contracts.DisputeManager.address, + graph.chainId as GraphChainId, + ) + + console.log('Attestation 1:', attestation1) + console.log('Attestation 2:', attestation2) + + // Create dispute + await graph.contracts.DisputeManager.connect(deployer).createQueryDisputeConflict( + encodeAttestation(attestation1), + encodeAttestation(attestation2), + ) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/packages/contracts/scripts/ops/testDisputeConflict/setupIndexer.ts b/packages/contracts/scripts/ops/testDisputeConflict/setupIndexer.ts new file mode 100644 index 000000000..9d2cd0ede --- /dev/null +++ b/packages/contracts/scripts/ops/testDisputeConflict/setupIndexer.ts @@ -0,0 +1,40 @@ +import { allocateFrom, deriveChannelKey, randomHexBytes, stake, toGRT } from '@graphprotocol/sdk' +import hre, { ethers } from 'hardhat' + +async function main() { + const graph = hre.graph() + const deployer = await graph.getDeployer() + const [indexer] = await graph.getTestAccounts() + + console.log('Deployer:', deployer.address) + console.log('Indexer:', indexer.address) + + const receipt = { + requestCID: '0x8bec406793c8e1c5d4bd4e059833e95b7a9aeed6a118cbe335a79735836f9ff7', + responseCID: '0xbdfc41643b5ff8d55f6cdb50f05575e1fdf177fa54d98cae1b9c76d8b360ff57', + subgraphDeploymentID: '0xa3bfbfc6f53fd8a61b78e0b9a90c7fbe9ff290cba87b045bc476137fb2963cf9', + } + + console.log('Receipt requestCID:', receipt.requestCID) + console.log('Receipt response CID:', receipt.responseCID) + console.log('Receipt subgraphDeploymentID:', receipt.subgraphDeploymentID) + + const indexerChannelKey = deriveChannelKey() + console.log('Indexer channel key:', indexerChannelKey.address) + console.log('Indexer channel key privKey:', indexerChannelKey.privKey) + + // Set up indexer + await deployer.sendTransaction({ value: toGRT('0.05'), to: indexer.address }) + await graph.contracts.GraphToken.connect(deployer).transfer(indexer.address, toGRT('100000')) + await stake(graph.contracts, indexer, { amount: toGRT('100000') }) + await allocateFrom(graph.contracts, indexer, { + channelKey: indexerChannelKey, + amount: toGRT('100000'), + subgraphDeploymentID: receipt.subgraphDeploymentID, + }) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/packages/sdk/src/deployments/index.ts b/packages/sdk/src/deployments/index.ts index 23b4b0e16..43bca79cf 100644 --- a/packages/sdk/src/deployments/index.ts +++ b/packages/sdk/src/deployments/index.ts @@ -33,6 +33,7 @@ export { getDefaults, } from './network/deployment/config' +export * from './network/actions/disputes' export * from './network/actions/gns' export * from './network/actions/staking' export * from './network/actions/graph-token' diff --git a/packages/sdk/src/deployments/network/actions/disputes.ts b/packages/sdk/src/deployments/network/actions/disputes.ts new file mode 100644 index 000000000..785bfb626 --- /dev/null +++ b/packages/sdk/src/deployments/network/actions/disputes.ts @@ -0,0 +1,20 @@ +import { + createAttestation, + encodeAttestation as encodeAttestationLib, + Attestation, + Receipt, +} from '@graphprotocol/common-ts' +import { GraphChainId } from '../../../chain' + +export async function buildAttestation( + receipt: Receipt, + signer: string, + disputeManagerAddress: string, + chainId: GraphChainId, +) { + return await createAttestation(signer, chainId, disputeManagerAddress, receipt, '0') +} + +export function encodeAttestation(attestation: Attestation): string { + return encodeAttestationLib(attestation) +} diff --git a/packages/sdk/src/deployments/network/actions/staking.ts b/packages/sdk/src/deployments/network/actions/staking.ts index 3ad513cf8..1d67e4408 100644 --- a/packages/sdk/src/deployments/network/actions/staking.ts +++ b/packages/sdk/src/deployments/network/actions/staking.ts @@ -6,6 +6,7 @@ import { randomHexBytes } from '../../../utils/bytes' import type { GraphNetworkAction } from './types' import type { GraphNetworkContracts } from '../deployment/contracts/load' +import { ChannelKey } from '../../../utils' export const stake: GraphNetworkAction<{ amount: BigNumber }> = async ( contracts: GraphNetworkContracts, @@ -28,23 +29,18 @@ export const stake: GraphNetworkAction<{ amount: BigNumber }> = async ( } export const allocateFrom: GraphNetworkAction<{ - allocationSigner: SignerWithAddress + channelKey: ChannelKey subgraphDeploymentID: string amount: BigNumber }> = async ( contracts: GraphNetworkContracts, indexer: SignerWithAddress, - args: { allocationSigner: SignerWithAddress; subgraphDeploymentID: string; amount: BigNumber }, + args: { channelKey: ChannelKey; subgraphDeploymentID: string; amount: BigNumber }, ): Promise => { - const { allocationSigner, subgraphDeploymentID, amount } = args + const { channelKey, subgraphDeploymentID, amount } = args - const allocationId = allocationSigner.address - const messageHash = ethers.utils.solidityKeccak256( - ['address', 'address'], - [indexer.address, allocationId], - ) - const messageHashBytes = ethers.utils.arrayify(messageHash) - const proof = await allocationSigner.signMessage(messageHashBytes) + const allocationId = channelKey.address + const proof = await channelKey.generateProof(indexer.address) const metadata = ethers.constants.HashZero console.log(`\nAllocating ${amount} tokens on ${allocationId}...`)