watcher-ts/packages/graph-node/src/eden.test.ts
Nabarun Gogoi 07887c160e
Use block number for eth_call in rpc-eth-client (#435)
* Update subgraph readme to run fill before job-runner

* Fix getContractEntitiesMap incase of template data sources

* Use rpcSupportsBlockHashParam flag to use blockNumber for rpc client eth_call

* Fix optional baseFeePerGas in rpc-eth-client

* Fix graph-node tests after changes

* Remove completed TODO
2023-10-25 11:04:12 +05:30

426 lines
13 KiB
TypeScript

//
// Copyright 2021 Vulcanize, Inc.
//
import assert from 'assert';
import { ethers, utils } from 'ethers';
import path from 'path';
import chai from 'chai';
import spies from 'chai-spies';
import { BaseProvider } from '@ethersproject/providers';
import { GraphDatabase, createEvent, Block, createBlock, EventData } from '@cerc-io/util';
import { instantiate } from './loader';
import edenNetworkAbi from '../test/subgraph/eden/EdenNetwork/abis/EdenNetwork.json';
import merkleDistributorAbi from '../test/subgraph/eden/EdenNetworkDistribution/abis/MerkleDistributor.json';
import distributorGovernanceAbi from '../test/subgraph/eden/EdenNetworkGovernance/abis/DistributorGovernance.json';
import { getDummyEventData, getTestDatabase, getTestIndexer, getTestProvider } from '../test/utils';
import { Indexer } from '../test/utils/indexer';
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
chai.use(spies);
const sandbox = chai.spy.sandbox();
xdescribe('eden wasm loader tests', async () => {
let db: GraphDatabase;
let indexer: Indexer;
let provider: BaseProvider;
let dummyEventData: EventData;
before(async () => {
db = getTestDatabase();
indexer = getTestIndexer();
provider = getTestProvider();
// Create dummy test data.
dummyEventData = await getDummyEventData();
sandbox.on(indexer, 'createDiffStaged', (contractAddress: string, blockHash: string, data: any) => {
assert(contractAddress);
assert(blockHash);
assert(data);
});
sandbox.on(db, 'getEntity', (blockHash: string, entityString: string, idString: string) => {
assert(blockHash);
assert(entityString);
assert(idString);
});
sandbox.on(db, 'fromGraphEntity', async (instanceExports: any, block: Block, entity: string, entityInstance: any) => {
const entityFields: any = [];
return db.getEntityValues(instanceExports, block, entityInstance, entityFields);
});
sandbox.on(db, 'saveEntity', (entity: string, data: any) => {
assert(entity);
assert(data);
});
});
describe('EdenNetwork wasm', () => {
let exports: any;
// EdenNetwork contract address string.
const contractAddress = process.env.EDEN_NETWORK_CONTRACT_ADDRESS;
assert(contractAddress);
const data = {
abis: {
EdenNetwork: edenNetworkAbi
},
dataSource: {
address: contractAddress,
network: 'mainnet',
name: 'EdenNetwork'
}
};
const contractInterface = new utils.Interface(edenNetworkAbi);
it('should load the subgraph network wasm', async () => {
const filePath = path.resolve(__dirname, '../test/subgraph/eden/EdenNetwork/EdenNetwork.wasm');
({ exports } = await instantiate(
db,
indexer,
provider,
{
rpcSupportsBlockHashParam: true,
block: dummyEventData.block,
contractAddress
},
filePath,
data
));
const { _start } = exports;
_start();
});
it('should call the slotClaimed handler', async () => {
const {
slotClaimed
} = exports;
// Create dummy SlotClaimedEvent params.
const eventFragment = contractInterface.getEvent('SlotClaimed(uint8,address,address,uint128,uint128,uint16,uint16)');
dummyEventData.inputs = eventFragment.inputs;
dummyEventData.event = {
slot: 0,
owner: ZERO_ADDRESS,
delegate: ZERO_ADDRESS,
newBidAmount: BigInt(1),
oldBidAmount: BigInt(1),
taxNumerator: 1,
taxDenominator: 1
};
// Create an ethereum event SlotClaimedEvent to be passed to handler.
const slotClaimedEvent = await createEvent(exports, contractAddress, dummyEventData);
await slotClaimed(slotClaimedEvent);
});
it('should call the slotDelegateUpdated handler', async () => {
const {
slotDelegateUpdated
} = exports;
// Create dummy SlotDelegateUpdatedEvent params.
const eventFragment = contractInterface.getEvent('SlotDelegateUpdated(uint8,address,address,address)');
dummyEventData.inputs = eventFragment.inputs;
dummyEventData.event = {
slot: 0,
owner: ZERO_ADDRESS,
newDelegate: ZERO_ADDRESS,
oldDelegate: ZERO_ADDRESS
};
// Create an ethereum event SlotDelegateUpdatedEvent to be passed to handler.
const slotClaimedEvent = await createEvent(exports, contractAddress, dummyEventData);
await slotDelegateUpdated(slotClaimedEvent);
});
xit('should call the stake handler', async () => {
const {
stake
} = exports;
// Create dummy StakeEvent params.
const eventFragment = contractInterface.getEvent('Stake(address,uint256)');
dummyEventData.inputs = eventFragment.inputs;
dummyEventData.event = {
staker: '0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc',
stakeAmount: BigInt(1)
};
// Create an ethereum event StakeEvent to be passed to handler.
const stakeEvent = await createEvent(exports, contractAddress, dummyEventData);
await stake(stakeEvent);
});
xit('should call the unstake handler', async () => {
const {
unstake
} = exports;
// Create dummy UnstakeEvent params.
const eventFragment = contractInterface.getEvent('Unstake(address,uint256)');
dummyEventData.inputs = eventFragment.inputs;
dummyEventData.event = {
staker: ZERO_ADDRESS,
unstakedAmount: BigInt(1)
};
// Create an ethereum event UnstakeEvent to be passed to handler.
const unstakeEvent = await createEvent(exports, contractAddress, dummyEventData);
await unstake(unstakeEvent);
});
});
describe('EdenNetworkDistribution wasm', () => {
let exports: any;
// EdenNetworkDistribution contract address string.
const contractAddress = process.env.EDEN_NETWORK_DISTRIBUTION_CONTRACT_ADDRESS;
assert(contractAddress);
const data = {
abis: {
Distribution: merkleDistributorAbi
},
dataSource: {
address: contractAddress,
network: 'mainnet',
name: 'EdenNetworkDistribution'
}
};
const contractInterface = new utils.Interface(merkleDistributorAbi);
it('should load the subgraph network distribution wasm', async () => {
const filePath = path.resolve(__dirname, '../test/subgraph/eden/EdenNetworkDistribution/EdenNetworkDistribution.wasm');
({ exports } = await instantiate(db,
indexer,
provider,
{
rpcSupportsBlockHashParam: true,
block: dummyEventData.block,
contractAddress
},
filePath,
data
));
const { _start } = exports;
_start();
});
it('should call the claimed handler', async () => {
const {
claimed
} = exports;
// Create dummy ClaimedEvent params.
const eventFragment = contractInterface.getEvent('Claimed(uint256,uint256,address,uint256)');
dummyEventData.inputs = eventFragment.inputs;
dummyEventData.event = {
index: BigInt(1),
totalEarned: BigInt(1),
account: ZERO_ADDRESS,
claimed: BigInt(1)
};
// Create an ethereum event ClaimedEvent to be passed to handler.
const claimedEvent = await createEvent(exports, contractAddress, dummyEventData);
await claimed(claimedEvent);
});
it('should call the slashed handler', async () => {
const {
slashed
} = exports;
// Create dummy SlashedEvent params.
const eventFragment = contractInterface.getEvent('Slashed(address,uint256)');
dummyEventData.inputs = eventFragment.inputs;
dummyEventData.event = {
account: ZERO_ADDRESS,
slashed: BigInt(1)
};
// Create an ethereum event SlashedEvent to be passed to handler.
const slashedEvent = await createEvent(exports, contractAddress, dummyEventData);
await slashed(slashedEvent);
});
it('should call the merkleRootUpdated handler', async () => {
const {
merkleRootUpdated
} = exports;
// Create dummy MerkleRootUpdatedEvent params.
const eventFragment = contractInterface.getEvent('MerkleRootUpdated(bytes32,uint256,string)');
dummyEventData.inputs = eventFragment.inputs;
dummyEventData.event = {
merkleRoot: ethers.utils.hexlify(ethers.utils.randomBytes(32)),
distributionNumber: BigInt(1),
metadataURI: 'abc'
};
// Create an ethereum event MerkleRootUpdatedEvent to be passed to handler.
const merkleRootUpdatedEvent = await createEvent(exports, contractAddress, dummyEventData);
await merkleRootUpdated(merkleRootUpdatedEvent);
});
it('should call the accountUpdated handler', async () => {
const {
accountUpdated
} = exports;
// Create dummy AccountUpdatedEvent params.
const eventFragment = contractInterface.getEvent('AccountUpdated(address,uint256,uint256)');
dummyEventData.inputs = eventFragment.inputs;
dummyEventData.event = {
account: ZERO_ADDRESS,
totalClaimed: BigInt(1),
totalSlashed: BigInt(1)
};
// Create an ethereum event AccountUpdatedEvent to be passed to handler.
const accountUpdatedEvent = await createEvent(exports, contractAddress, dummyEventData);
await accountUpdated(accountUpdatedEvent);
});
});
describe('EdenNetworkGovernance wasm', () => {
let exports: any;
// EdenNetworkGovernance contract address string.
const contractAddress = process.env.EDEN_NETWORK_GOVERNANCE_CONTRACT_ADDRESS;
assert(contractAddress);
const data = {
abis: {
Governance: distributorGovernanceAbi
},
dataSource: {
address: contractAddress,
network: 'mainnet',
name: 'EdenNetworkGovernance'
}
};
const contractInterface = new utils.Interface(distributorGovernanceAbi);
it('should load the subgraph network governance wasm', async () => {
const filePath = path.resolve(__dirname, '../test/subgraph/eden/EdenNetworkGovernance/EdenNetworkGovernance.wasm');
({ exports } = await instantiate(
db,
indexer,
provider,
{
rpcSupportsBlockHashParam: true,
block: dummyEventData.block,
contractAddress
},
filePath,
data
));
const { _start } = exports;
_start();
});
it('should call the blockProducerAdded handler', async () => {
const {
blockProducerAdded
} = exports;
// Create dummy BlockProducerAddedEvent params.
const eventFragment = contractInterface.getEvent('BlockProducerAdded(address)');
dummyEventData.inputs = eventFragment.inputs;
dummyEventData.event = { producer: ZERO_ADDRESS };
// Create an ethereum event BlockProducerAddedEvent to be passed to handler.
const blockProducerAddedEvent = await createEvent(exports, contractAddress, dummyEventData);
await blockProducerAdded(blockProducerAddedEvent);
});
it('should call the blockProducerRemoved handler', async () => {
const {
blockProducerRemoved
} = exports;
// Create dummy BlockProducerRemovedEvent params.
const eventFragment = contractInterface.getEvent('BlockProducerRemoved(address)');
dummyEventData.inputs = eventFragment.inputs;
dummyEventData.event = { producer: ZERO_ADDRESS };
// Create an ethereum event BlockProducerRemovedEvent to be passed to handler.
const blockProducerRemovedEvent = await createEvent(exports, contractAddress, dummyEventData);
await blockProducerRemoved(blockProducerRemovedEvent);
});
it('should call the blockProducerRewardCollectorChanged handler', async () => {
const {
blockProducerRewardCollectorChanged
} = exports;
// Create dummy BlockProducerRewardCollectorChangedEvent params.
const eventFragment = contractInterface.getEvent('BlockProducerRewardCollectorChanged(address,address)');
dummyEventData.inputs = eventFragment.inputs;
dummyEventData.event = {
producer: ZERO_ADDRESS,
collector: ZERO_ADDRESS,
metadataURI: 'abc'
};
// Create an ethereum event BlockProducerRewardCollectorChangedEvent to be passed to handler.
const blockProducerRewardCollectorChangedEvent = await createEvent(exports, contractAddress, dummyEventData);
await blockProducerRewardCollectorChanged(blockProducerRewardCollectorChangedEvent);
});
it('should call the rewardScheduleChanged handler', async () => {
const {
rewardScheduleChanged
} = exports;
const eventFragment = contractInterface.getEvent('RewardScheduleChanged()');
dummyEventData.inputs = eventFragment.inputs;
dummyEventData.event = {};
// Create an ethereum event RewardScheduleChangedEvent to be passed to handler.
const rewardScheduleChangedEvent = await createEvent(exports, contractAddress, dummyEventData);
await rewardScheduleChanged(rewardScheduleChangedEvent);
});
it('should call the block handler', async () => {
const { handleBlock } = exports;
const blockData = dummyEventData.block;
// Create an ethereum block to be passed to the handler.
const block = await createBlock(exports, blockData);
await handleBlock(block);
});
});
after(() => {
sandbox.restore();
});
});