Skip to content

Commit

Permalink
Sync: l2-testnet / scenario1 > dev (#703)
Browse files Browse the repository at this point in the history
* chore: sync changes from l2 branches

Signed-off-by: Tomás Migone <[email protected]>
  • Loading branch information
tmigone authored Sep 6, 2022
1 parent 69dcc9a commit 07c0790
Show file tree
Hide file tree
Showing 27 changed files with 899 additions and 263 deletions.
3 changes: 2 additions & 1 deletion TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ The command will perform the following actions:
- Run `migrate` hardhat task to deploy the protocol
- Run `migrate:ownership` hardhat task to transfer ownership of governed contracts to the governor
- Run `migrate:unpause` to unpause the protocol
- Run `e2e` hardhat task to run all e2e tests, including scenarios
- Run `e2e` hardhat task to run all deployment tests (config and init)
- Run `e2e:scenario` hardhat task to run a scenario

### Other networks

Expand Down
8 changes: 6 additions & 2 deletions cli/commands/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ const allContracts = [
'AllocationExchange',
]

export const migrate = async (cli: CLIEnvironment, cliArgs: CLIArgs): Promise<void> => {
export const migrate = async (
cli: CLIEnvironment,
cliArgs: CLIArgs,
autoMine = false,
): Promise<void> => {
const graphConfigPath = cliArgs.graphConfig
const force = cliArgs.force
const contractName = cliArgs.contract
Expand Down Expand Up @@ -140,7 +144,7 @@ export const migrate = async (cli: CLIEnvironment, cliArgs: CLIArgs): Promise<vo
logger.info(`Sent ${nTx} transaction${nTx === 1 ? '' : 's'} & spent ${EtherSymbol} ${spent}`)

if (chainId == 1337) {
await (cli.wallet.provider as providers.JsonRpcProvider).send('evm_setAutomine', [false])
await (cli.wallet.provider as providers.JsonRpcProvider).send('evm_setAutomine', [autoMine])
}
}

Expand Down
17 changes: 16 additions & 1 deletion config/graph.mainnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ contracts:
- fn: "setContractProxy"
id: "0x45fc200c7e4544e457d3c5709bfe0d520442c30bbcbdaede89e8d4a4bbc19247" # keccak256('GraphToken')
contractAddress: "${{GraphToken.address}}"
- fn: "setPauseGuardian"
pauseGuardian: *pauseGuardian
- fn: "transferOwnership"
owner: *governor
GraphProxyAdmin:
calls:
- fn: "transferOwnership"
owner: *governor
ServiceRegistry:
proxy: true
init:
Expand All @@ -45,6 +53,9 @@ contracts:
calls:
- fn: "addMinter"
minter: "${{RewardsManager.address}}"
- fn: "renounceMinter"
- fn: "transferOwnership"
owner: *governor
Curation:
proxy: true
init:
Expand Down Expand Up @@ -79,6 +90,8 @@ contracts:
tokenDescriptor: "${{SubgraphNFTDescriptor.address}}"
- fn: "setMinter"
minter: "${{GNS.address}}"
- fn: "transferOwnership"
owner: *governor
Staking:
proxy: true
init:
Expand Down Expand Up @@ -109,11 +122,13 @@ contracts:
calls:
- fn: "setIssuanceRate"
issuanceRate: "1000000012184945188" # per block increase of total supply, blocks in a year = 365*60*60*24/13
- fn: "setSubgraphAvailabilityOracle"
subgraphAvailabilityOracle: *availabilityOracle
AllocationExchange:
init:
graphToken: "${{GraphToken.address}}"
staking: "${{Staking.address}}"
governor: *governor
governor: *allocationExchangeOwner
authority: *authority
calls:
- fn: "approveAll"
48 changes: 48 additions & 0 deletions e2e/scenarios/close-allocations.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { expect } from 'chai'
import hre from 'hardhat'
import { AllocationFixture, getIndexerFixtures, IndexerFixture } from './fixtures/indexers'

enum AllocationState {
Null,
Active,
Closed,
Finalized,
Claimed,
}

let indexerFixtures: IndexerFixture[]

describe('Close allocations', () => {
const { contracts, getTestAccounts } = hre.graph()
const { Staking } = contracts

before(async () => {
indexerFixtures = getIndexerFixtures(await getTestAccounts())
})

describe('Allocations', () => {
let allocations: AllocationFixture[] = []
let openAllocations: AllocationFixture[] = []
let closedAllocations: AllocationFixture[] = []

before(async () => {
allocations = indexerFixtures.map((i) => i.allocations).flat()
openAllocations = allocations.filter((a) => !a.close)
closedAllocations = allocations.filter((a) => a.close)
})

it(`some allocatons should be open`, async function () {
for (const allocation of openAllocations) {
const state = await Staking.getAllocationState(allocation.signer.address)
expect(state).eq(AllocationState.Active)
}
})

it(`some allocatons should be closed`, async function () {
for (const allocation of closedAllocations) {
const state = await Staking.getAllocationState(allocation.signer.address)
expect(state).eq(AllocationState.Closed)
}
})
})
})
52 changes: 52 additions & 0 deletions e2e/scenarios/close-allocations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// ### Scenario description ###
// Common protocol actions > Close some allocations
// This scenario will close several open allocations. See fixtures for details.
// Need to wait at least 1 epoch after the allocations have been created before running it.
// On localhost, the epoch is automatically advanced to guarantee this.
// Run with:
// npx hardhat e2e:scenario close-allocations --network <network> --graph-config config/graph.<network>.yml

import hre from 'hardhat'
import { closeAllocation } from './lib/staking'
import { advanceToNextEpoch } from '../../test/lib/testHelpers'
import { fundAccountsETH } from './lib/accounts'
import { getIndexerFixtures } from './fixtures/indexers'
import { getGraphOptsFromArgv } from './lib/helpers'

async function main() {
const graphOpts = getGraphOptsFromArgv()
const graph = hre.graph(graphOpts)
const indexerFixtures = getIndexerFixtures(await graph.getTestAccounts())

const deployer = await graph.getDeployer()
const indexers = indexerFixtures.map((i) => i.signer.address)
const indexerETHBalances = indexerFixtures.map((i) => i.ethBalance)

// == Fund participants
console.log('\n== Fund indexers')
await fundAccountsETH(deployer, indexers, indexerETHBalances)

// == Time travel on local networks, ensure allocations can be closed
if (['hardhat', 'localhost'].includes(hre.network.name)) {
console.log('\n== Advancing to next epoch')
await advanceToNextEpoch(graph.contracts.EpochManager)
}

// == Close allocations
console.log('\n== Close allocations')

for (const indexer of indexerFixtures) {
for (const allocation of indexer.allocations.filter((a) => a.close)) {
await closeAllocation(graph.contracts, indexer.signer, allocation.signer.address)
}
}
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error)
process.exitCode = 1
})
72 changes: 72 additions & 0 deletions e2e/scenarios/create-subgraphs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { expect } from 'chai'
import hre from 'hardhat'
import { recreatePreviousSubgraphId } from './lib/subgraph'
import { BigNumber } from 'ethers'
import { CuratorFixture, getCuratorFixtures } from './fixtures/curators'
import { SubgraphFixture, getSubgraphFixtures, getSubgraphOwner } from './fixtures/subgraphs'
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'

let curatorFixtures: CuratorFixture[]
let subgraphFixtures: SubgraphFixture[]
let subgraphOwnerFixture: SignerWithAddress

describe('Publish subgraphs', () => {
const { contracts, getTestAccounts } = hre.graph()
const { GNS, GraphToken, Curation } = contracts

before(async () => {
const testAccounts = await getTestAccounts()
curatorFixtures = getCuratorFixtures(testAccounts)
subgraphFixtures = getSubgraphFixtures()
subgraphOwnerFixture = getSubgraphOwner(testAccounts).signer
})

describe('GRT balances', () => {
it(`curator balances should match airdropped amount minus signalled`, async function () {
for (const curator of curatorFixtures) {
const address = curator.signer.address
const balance = await GraphToken.balanceOf(address)
expect(balance).eq(curator.grtBalance.sub(curator.signalled))
}
})
})

describe('Subgraphs', () => {
it(`should be published`, async function () {
for (let i = 0; i < subgraphFixtures.length; i++) {
const subgraphId = await recreatePreviousSubgraphId(
contracts,
subgraphOwnerFixture.address,
subgraphFixtures.length - i,
)
const isPublished = await GNS.isPublished(subgraphId)
expect(isPublished).eq(true)
}
})

it(`should have signal`, async function () {
for (let i = 0; i < subgraphFixtures.length; i++) {
const subgraph = subgraphFixtures[i]
const subgraphId = await recreatePreviousSubgraphId(
contracts,
subgraphOwnerFixture.address,
subgraphFixtures.length - i,
)

let totalSignal: BigNumber = BigNumber.from(0)
for (const curator of curatorFixtures) {
const _subgraph = curator.subgraphs.find((s) => s.deploymentId === subgraph.deploymentId)
if (_subgraph) {
totalSignal = totalSignal.add(_subgraph.signal)
}
}

const tokens = await GNS.subgraphTokens(subgraphId)
const MAX_PPM = 1000000
const curationTax = await Curation.curationTaxPercentage()
const tax = totalSignal.mul(curationTax).div(MAX_PPM)
expect(tokens).eq(totalSignal.sub(tax))
}
})
})
})
71 changes: 71 additions & 0 deletions e2e/scenarios/create-subgraphs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// ### Scenario description ###
// Common protocol actions > Set up subgraphs: publish and signal
// This scenario will create a set of subgraphs and add signal to them. See fixtures for details.
// Run with:
// npx hardhat e2e:scenario create-subgraphs --network <network> --graph-config config/graph.<network>.yml

import hre from 'hardhat'
import { publishNewSubgraph } from './lib/subgraph'
import { fundAccountsETH, fundAccountsGRT } from './lib/accounts'
import { signal } from './lib/curation'
import { getSubgraphFixtures, getSubgraphOwner } from './fixtures/subgraphs'
import { getCuratorFixtures } from './fixtures/curators'
import { getGraphOptsFromArgv } from './lib/helpers'

async function main() {
const graphOpts = getGraphOptsFromArgv()
const graph = hre.graph(graphOpts)
const testAccounts = await graph.getTestAccounts()

const subgraphFixtures = getSubgraphFixtures()
const subgraphOwnerFixture = getSubgraphOwner(testAccounts)
const curatorFixtures = getCuratorFixtures(testAccounts)

const deployer = await graph.getDeployer()
const subgraphOwners = [subgraphOwnerFixture.signer.address]
const subgraphOwnerETHBalance = [subgraphOwnerFixture.ethBalance]
const curators = curatorFixtures.map((c) => c.signer.address)
const curatorETHBalances = curatorFixtures.map((i) => i.ethBalance)
const curatorGRTBalances = curatorFixtures.map((i) => i.grtBalance)

// == Fund participants
console.log('\n== Fund subgraph owners and curators')
await fundAccountsETH(
deployer,
[...subgraphOwners, ...curators],
[...subgraphOwnerETHBalance, ...curatorETHBalances],
)
await fundAccountsGRT(deployer, curators, curatorGRTBalances, graph.contracts.GraphToken)

// == Publish subgraphs
console.log('\n== Publishing subgraphs')

for (const subgraph of subgraphFixtures) {
const id = await publishNewSubgraph(
graph.contracts,
subgraphOwnerFixture.signer,
subgraph.deploymentId,
)
const subgraphData = subgraphFixtures.find((s) => s.deploymentId === subgraph.deploymentId)
if (subgraphData) subgraphData.subgraphId = id
}

// == Signal subgraphs
console.log('\n== Signaling subgraphs')
for (const curator of curatorFixtures) {
for (const subgraph of curator.subgraphs) {
const subgraphData = subgraphFixtures.find((s) => s.deploymentId === subgraph.deploymentId)
if (subgraphData)
await signal(graph.contracts, curator.signer, subgraphData.subgraphId, subgraph.signal)
}
}
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error)
process.exitCode = 1
})
Loading

0 comments on commit 07c0790

Please sign in to comment.