mirror of
https://github.com/cerc-io/watcher-ts
synced 2025-07-30 11:42:07 +00:00
Handle template create events processing order during reorgs
This commit is contained in:
parent
a585500012
commit
74a85039e6
@ -635,6 +635,10 @@ export class Indexer implements IndexerInterface {
|
||||
return this._baseIndexer.watchContract(address, kind, checkpoint, startingBlock, context);
|
||||
}
|
||||
|
||||
async removeContract (address: string, kind: string): Promise<void> {
|
||||
return this._baseIndexer.removeContract(address, kind);
|
||||
}
|
||||
|
||||
updateStateStatusMap (address: string, stateStatus: StateStatus): void {
|
||||
this._baseIndexer.updateStateStatusMap(address, stateStatus);
|
||||
}
|
||||
|
@ -734,25 +734,13 @@ export const instantiate = async (
|
||||
return __newString(dataSource.network);
|
||||
},
|
||||
'dataSource.create': async (name: number, params: number) => {
|
||||
const [addressStringPtr] = __getArray(params);
|
||||
const addressString = __getString(addressStringPtr);
|
||||
const contractKind = __getString(name);
|
||||
|
||||
assert(indexer.watchContract);
|
||||
assert(context.block);
|
||||
await indexer.watchContract(utils.getAddress(addressString), contractKind, true, Number(context.block.blockNumber));
|
||||
await handleDataSourceCreate(name, params);
|
||||
},
|
||||
'dataSource.createWithContext': async (name: number, params: number, dataSourceContext: number) => {
|
||||
const [addressStringPtr] = __getArray(params);
|
||||
const addressString = __getString(addressStringPtr);
|
||||
const contractKind = __getString(name);
|
||||
|
||||
const contextInstance = await Entity.wrap(dataSourceContext);
|
||||
const dbData = await database.fromGraphContext(instanceExports, contextInstance);
|
||||
|
||||
assert(indexer.watchContract);
|
||||
assert(context.block);
|
||||
await indexer.watchContract(utils.getAddress(addressString), contractKind, true, Number(context.block.blockNumber), dbData);
|
||||
await handleDataSourceCreate(name, params, dbData);
|
||||
}
|
||||
},
|
||||
json: {
|
||||
@ -786,6 +774,34 @@ export const instantiate = async (
|
||||
}
|
||||
};
|
||||
|
||||
const handleDataSourceCreate = async (name: number, params: number, dbData?: {[key: string]: any}) => {
|
||||
const [addressStringPtr] = __getArray(params);
|
||||
const addressString = __getString(addressStringPtr);
|
||||
const contractKind = __getString(name);
|
||||
|
||||
assert(context.block);
|
||||
const contractAddress = utils.getAddress(addressString);
|
||||
const watchedContracts = indexer.isContractAddressWatched(contractAddress);
|
||||
|
||||
// If template contract is already watched (incase of reorgs)
|
||||
// Remove from watched contracts and throw error to reprocess block with correct order of template contract events
|
||||
if (
|
||||
watchedContracts &&
|
||||
watchedContracts.some(watchedContract => watchedContract.kind === contractKind)
|
||||
) {
|
||||
await indexer.removeContract(contractAddress, contractKind);
|
||||
throw new Error(`Template contract ${contractAddress} of kind ${contractKind} already exists; removed from watched contracts`);
|
||||
}
|
||||
|
||||
await indexer.watchContract(
|
||||
contractAddress,
|
||||
contractKind,
|
||||
true,
|
||||
Number(context.block.blockNumber),
|
||||
dbData
|
||||
);
|
||||
};
|
||||
|
||||
const instance = await loader.instantiate(source, imports);
|
||||
const { exports: instanceExports } = instance;
|
||||
|
||||
|
@ -920,6 +920,22 @@ export class Indexer {
|
||||
}
|
||||
}
|
||||
|
||||
async removeContract (address: string, kind: string): Promise<void> {
|
||||
const dbTx = await this._db.createTransactionRunner();
|
||||
|
||||
try {
|
||||
await this._db.deleteEntitiesByConditions(dbTx, 'contract', { kind, address });
|
||||
this._clearWatchedContracts(
|
||||
watchedContract => watchedContract.kind === kind && watchedContract.address === address
|
||||
);
|
||||
} catch (error) {
|
||||
await dbTx.rollbackTransaction();
|
||||
throw error;
|
||||
} finally {
|
||||
await dbTx.release();
|
||||
}
|
||||
}
|
||||
|
||||
cacheContract (contract: ContractInterface): void {
|
||||
if (!this._watchedContractsByAddressMap[contract.address]) {
|
||||
this._watchedContractsByAddressMap[contract.address] = [];
|
||||
|
@ -217,6 +217,7 @@ export interface IndexerInterface {
|
||||
addContracts?: () => Promise<void>
|
||||
cacheContract: (contract: ContractInterface) => void;
|
||||
watchContract: (address: string, kind: string, checkpoint: boolean, startingBlock: number, context?: any) => Promise<void>
|
||||
removeContract: (address: string, kind: string) => Promise<void>;
|
||||
getEntityTypesMap?: () => Map<string, { [key: string]: string }>
|
||||
getRelationsMap?: () => Map<any, { [key: string]: any }>
|
||||
processInitialState: (contractAddress: string, blockHash: string) => Promise<any>
|
||||
|
Loading…
Reference in New Issue
Block a user