mirror of
https://github.com/cerc-io/watcher-ts
synced 2025-09-21 13:24:07 +00:00
* 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
426 lines
13 KiB
TypeScript
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();
|
|
});
|
|
});
|