Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: working governance integration tests in ci #113

Merged
merged 4 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- name: pretty
run: yarn pretty

test:
unit-test:
runs-on: ubuntu-20.04
steps:
- name: Checkout
Expand All @@ -48,8 +48,9 @@ jobs:
- name: Run Matchstick tests
run: yarn test

integration-test:
integration-test-isolated-pools:
runs-on: ubuntu-20.04
needs: unit-test
steps:
- name: Checkout
uses: actions/checkout@v2
Expand All @@ -72,7 +73,27 @@ jobs:

- name: Run Isolated Pools integration integration tests
run: |
docker exec -i subgraph-hardhat-node yarn workspace isolated-pools-subgraph run test:integration
docker exec -i subgraph-hardhat-node yarn workspace isolated-pools-subgraph run test:integration --bail

- name: Stop containers
if: always()
run: |
docker-compose down -v
docker system prune -f -a --volumes

integration-test-governance:
runs-on: ubuntu-20.04
needs: unit-test
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Start containers
run: docker-compose up -d

- name: Sleep to allow graph-node to become accessible
shell: bash
run: sleep 45s

- name: Generate Governance graphql types
run: |
Expand All @@ -82,11 +103,10 @@ jobs:
docker exec -i subgraph-hardhat-node yarn workspace venus-governance-subgraph run deploy:docker
sleep 5s
docker exec -i subgraph-hardhat-node yarn workspace venus-governance-subgraph run generate-subgraph-types

# @TODO - turn on once the integration tests pass
# - name: Run Governance integration integration tests
# run: |
# docker exec -i subgraph-hardhat-node yarn workspace venus-governance-subgraph run test:integration

- name: Run Governance integration integration tests
run: |
docker exec -i subgraph-hardhat-node yarn workspace venus-governance-subgraph run test:integration --bail

- name: Stop containers
if: always()
Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ hardhat.config.ts
/subgraphs/venus-governance/subgraph-client/.graphclient
typechain-types

/subgraphs/venus-governance/tests/integration/index.ts
2 changes: 1 addition & 1 deletion subgraphs/venus-governance/config/local.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"network": "hardhat",
"accessControlManagerAddress": "0xc5a5C42992dECbae36851359345FE25997F5C42d",
"accessControlManagerAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512",
"accessControlManagerStartBlock": "0",
"governorAlphaAddress": "0x1c9fD50dF7a4f066884b58A05D91e4b55005876A",
"governorAlphaStartBlock": "0",
Expand Down
104 changes: 59 additions & 45 deletions subgraphs/venus-governance/src/operations/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { GovernorBravoDelegate2 } from '../../generated/GovernorBravoDelegate2/G
import { Timelock } from '../../generated/GovernorBravoDelegate2/Timelock';
import { Delegate, Governance, GovernanceRoute, Proposal } from '../../generated/schema';
import { BIGINT_ZERO } from '../constants';
import { governorBravoDelegateAddress } from '../constants/addresses';
import { governorBravoDelegateAddress, nullAddress } from '../constants/addresses';

/**
* While technically this function does also create, we don't care because it only happens once as the id is a constant.
Expand All @@ -20,51 +20,65 @@ export const getGovernanceEntity = (): Governance => {
governance.totalVoters = BIGINT_ZERO;
governance.totalVotesMantissa = BIGINT_ZERO;
governance.proposalsQueued = BIGINT_ZERO;
// Mocking values until we can correctly index current governance contract
governance.admin = nullAddress;
governance.implementation = nullAddress;
governance.guardian = nullAddress;
governance.quorumVotesMantissa = BIGINT_ZERO;
governance.proposalMaxOperations = BIGINT_ZERO;

governance.admin = governorBravoDelegate2.admin();
governance.implementation = governorBravoDelegate2.implementation();
governance.guardian = governorBravoDelegate2.guardian();
governance.quorumVotesMantissa = governorBravoDelegate2.quorumVotes();
governance.proposalMaxOperations = governorBravoDelegate2.proposalMaxOperations();
// Governance Routes are set in initialization
// Normal
const normalProposalConfig = governorBravoDelegate2.proposalConfigs(new BigInt(0));
const normalTimelockAddress = governorBravoDelegate2.proposalTimelocks(new BigInt(0));
const normalTimelock = Timelock.bind(normalTimelockAddress);
const normalGovernanceRoute = new GovernanceRoute('0');
normalGovernanceRoute.governor = governorBravoDelegateAddress;
normalGovernanceRoute.timelock = normalTimelockAddress;
normalGovernanceRoute.queueDelayBlocks = normalTimelock.delay();
normalGovernanceRoute.votingDelayBlocks = normalProposalConfig.getVotingDelay();
normalGovernanceRoute.votingPeriodBlocks = normalProposalConfig.getVotingPeriod();
normalGovernanceRoute.proposalThresholdMantissa = normalProposalConfig.getProposalThreshold();
normalGovernanceRoute.save();
// Fast track
const fastTrackProposalConfig = governorBravoDelegate2.proposalConfigs(new BigInt(1));
const fastTrackTimelockAddress = governorBravoDelegate2.proposalTimelocks(new BigInt(1));
const fastTrackTimelock = Timelock.bind(normalTimelockAddress);
const fastTrackGovernanceRoute = new GovernanceRoute('1');
fastTrackGovernanceRoute.governor = governorBravoDelegateAddress;
fastTrackGovernanceRoute.timelock = fastTrackTimelockAddress;
fastTrackGovernanceRoute.queueDelayBlocks = fastTrackTimelock.delay();
fastTrackGovernanceRoute.votingDelayBlocks = fastTrackProposalConfig.getVotingDelay();
fastTrackGovernanceRoute.votingPeriodBlocks = fastTrackProposalConfig.getVotingPeriod();
fastTrackGovernanceRoute.proposalThresholdMantissa =
fastTrackProposalConfig.getProposalThreshold();
fastTrackGovernanceRoute.save();
// Critical
const criticalProposalConfig = governorBravoDelegate2.proposalConfigs(new BigInt(2));
const criticalTimelockAddress = governorBravoDelegate2.proposalTimelocks(new BigInt(2));
const criticalTimelock = Timelock.bind(normalTimelockAddress);
const criticalGovernanceRoute = new GovernanceRoute('2');
criticalGovernanceRoute.governor = governorBravoDelegateAddress;
criticalGovernanceRoute.timelock = criticalTimelockAddress;
criticalGovernanceRoute.queueDelayBlocks = criticalTimelock.delay();
criticalGovernanceRoute.votingDelayBlocks = criticalProposalConfig.getVotingDelay();
criticalGovernanceRoute.votingPeriodBlocks = criticalProposalConfig.getVotingPeriod();
criticalGovernanceRoute.proposalThresholdMantissa =
criticalProposalConfig.getProposalThreshold();
criticalGovernanceRoute.save();
// There is only one active governance entity
// but while indexing proposals created with previous governance contracts all these calls will fail
// This method only exists on the latest governance interface so if it succeeds we can safely index the contract
const normalProposalConfigResult = governorBravoDelegate2.try_proposalConfigs(new BigInt(0));
if (normalProposalConfigResult.reverted === false) {
governance.admin = governorBravoDelegate2.admin();
governance.implementation = governorBravoDelegate2.implementation();
governance.guardian = governorBravoDelegate2.guardian();
governance.quorumVotesMantissa = governorBravoDelegate2.quorumVotes();
governance.proposalMaxOperations = governorBravoDelegate2.proposalMaxOperations();
// Governance Routes are set in initialization
// Normal
const normalProposalConfig = normalProposalConfigResult.value;
const normalTimelockAddress = governorBravoDelegate2.proposalTimelocks(new BigInt(0));
const normalTimelock = Timelock.bind(normalTimelockAddress);
const normalGovernanceRoute = new GovernanceRoute('0');
normalGovernanceRoute.governor = governorBravoDelegateAddress;
normalGovernanceRoute.timelock = normalTimelockAddress;
normalGovernanceRoute.queueDelayBlocks = normalTimelock.delay();
normalGovernanceRoute.votingDelayBlocks = normalProposalConfig.getVotingDelay();
normalGovernanceRoute.votingPeriodBlocks = normalProposalConfig.getVotingPeriod();
normalGovernanceRoute.proposalThresholdMantissa = normalProposalConfig.getProposalThreshold();
normalGovernanceRoute.save();
// Fast track
const fastTrackProposalConfig = governorBravoDelegate2.proposalConfigs(new BigInt(1));
const fastTrackTimelockAddress = governorBravoDelegate2.proposalTimelocks(new BigInt(1));
const fastTrackTimelock = Timelock.bind(normalTimelockAddress);
const fastTrackGovernanceRoute = new GovernanceRoute('1');
fastTrackGovernanceRoute.governor = governorBravoDelegateAddress;
fastTrackGovernanceRoute.timelock = fastTrackTimelockAddress;
fastTrackGovernanceRoute.queueDelayBlocks = fastTrackTimelock.delay();
fastTrackGovernanceRoute.votingDelayBlocks = fastTrackProposalConfig.getVotingDelay();
fastTrackGovernanceRoute.votingPeriodBlocks = fastTrackProposalConfig.getVotingPeriod();
fastTrackGovernanceRoute.proposalThresholdMantissa =
fastTrackProposalConfig.getProposalThreshold();
fastTrackGovernanceRoute.save();
// Critical
const criticalProposalConfig = governorBravoDelegate2.proposalConfigs(new BigInt(2));
const criticalTimelockAddress = governorBravoDelegate2.proposalTimelocks(new BigInt(2));
const criticalTimelock = Timelock.bind(normalTimelockAddress);
const criticalGovernanceRoute = new GovernanceRoute('2');
criticalGovernanceRoute.governor = governorBravoDelegateAddress;
criticalGovernanceRoute.timelock = criticalTimelockAddress;
criticalGovernanceRoute.queueDelayBlocks = criticalTimelock.delay();
criticalGovernanceRoute.votingDelayBlocks = criticalProposalConfig.getVotingDelay();
criticalGovernanceRoute.votingPeriodBlocks = criticalProposalConfig.getVotingPeriod();
criticalGovernanceRoute.proposalThresholdMantissa =
criticalProposalConfig.getProposalThreshold();
criticalGovernanceRoute.save();
}

governance.save();
}

return governance as Governance;
Expand Down
6 changes: 6 additions & 0 deletions subgraphs/venus-governance/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ dataSources:
abis:
- name: GovernorAlpha
file: ../../packages/venus-governance-abis/GovernorAlpha.json
- name: GovernorBravoDelegate2
file: ../../packages/venus-governance-abis/GovernorBravoDelegate2.json
eventHandlers:
- event: ProposalCreated(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,string)
handler: handleProposalCreated
Expand Down Expand Up @@ -55,6 +57,8 @@ dataSources:
abis:
- name: GovernorAlpha2
file: ../../packages/venus-governance-abis/GovernorAlpha2.json
- name: GovernorBravoDelegate2
file: ../../packages/venus-governance-abis/GovernorBravoDelegate2.json
eventHandlers:
- event: ProposalCreated(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,string)
handler: handleProposalCreated
Expand Down Expand Up @@ -86,6 +90,8 @@ dataSources:
abis:
- name: GovernorBravoDelegate
file: ../../packages/venus-governance-abis/GovernorBravoDelegate.json
- name: GovernorBravoDelegate2
file: ../../packages/venus-governance-abis/GovernorBravoDelegate2.json
eventHandlers:
- event: ProposalCreated(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,string)
handler: handleProposalCreated
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import '@nomiclabs/hardhat-ethers';
import { expect } from 'chai';
import { ethers } from 'hardhat';
import { waitForSubgraphToBeSynced } from 'venus-subgraph-utils';

import subgraphClient from '../../subgraph-client/index';
import { SYNC_DELAY } from './utils/constants';

describe('AccessControlManager', function () {
before(async function () {
this.timeout(50000000); // sometimes it takes a long time

await waitForSubgraphToBeSynced(SYNC_DELAY);
});

describe('Permission events', function () {
it('indexes permission granted events', async function () {
const { data } = await subgraphClient.getPermissions();

const { permissions } = data!;
expect(permissions.length).to.be.equal(12);

permissions.forEach(pe => {
expect(pe.type).to.be.equal('GRANTED');
});
});

it('indexes permission revoked events', async function () {
const accessControlManager = await ethers.getContract('AccessControlManager');
const tx = await accessControlManager.revokeCallPermission(
ethers.constants.AddressZero,
'setMinLiquidatableCollateral(uint256)',
ethers.constants.AddressZero,
);
await tx.wait();
await waitForSubgraphToBeSynced(SYNC_DELAY);

const { data } = await subgraphClient.getPermissions();

const { permissions } = data!;
expect(permissions.length).to.be.equal(13);

expect(permissions[0].type).to.be.equal('REVOKED');
});

it('updates a previously created record with a new permission type', async function () {
const accessControlManager = await ethers.getContract('AccessControlManager');
const tx = await accessControlManager.giveCallPermission(
ethers.constants.AddressZero,
'setMinLiquidatableCollateral(uint256)',
ethers.constants.AddressZero,
);
await tx.wait();
await waitForSubgraphToBeSynced(SYNC_DELAY);

const { data } = await subgraphClient.getPermissions();

const { permissions } = data!;
expect(permissions.length).to.be.equal(13);

expect(permissions[0].type).to.be.equal('GRANTED');
});
});
});
Loading
Loading