Skip to content

Commit

Permalink
get logs from cache (#985)
Browse files Browse the repository at this point in the history
* get logs from cache

* add cache

* polish logging

* fix naming
  • Loading branch information
shunjizhan committed Apr 19, 2024
1 parent c15752e commit 87b6ca6
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 12 deletions.
21 changes: 21 additions & 0 deletions packages/eth-providers/src/__tests__/e2e/json-rpc-provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,27 @@ describe('JsonRpcProvider', async () => {
});
});

describe('get logs without subql', () => {
it('works', async () => {
const echoFactory = new ContractFactory(echoJson.abi, echoJson.bytecode, wallet);
const echo = await echoFactory.deploy();

const { blockNumber: block0 } = await (await echo.scream('hello Gogeta!')).wait();
let logs = await wallet.provider.getLogs({
address: echo.address,
});
expect(logs.length).to.eq(1);

const { blockNumber: block1 } = await (await echo.scream('hello Vegito!')).wait();
logs = await wallet.provider.getLogs({
address: echo.address,
fromBlock: block0,
toBlock: block1,
});
expect(logs.length).to.eq(2);
});
});

describe('subscription', () => {
it('subscribe to new block', async () => {
const curBlockNumber = await provider.getBlockNumber();
Expand Down
48 changes: 36 additions & 12 deletions packages/eth-providers/src/base-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1795,17 +1795,26 @@ export abstract class BaseProvider extends AbstractProvider {
_getSubqlMissedLogs = async (toBlock: number, filter: SanitizedLogFilter): Promise<Log[]> => {
const targetBlock = Math.min(toBlock, await this.finalizedBlockNumber); // subql upperbound is finalizedBlockNumber
const lastProcessedHeight = await this.subql.getLastProcessedHeight();
const missedBlockCount = targetBlock - lastProcessedHeight;
if (missedBlockCount <= 0) return [];

const firstMissedHeight = lastProcessedHeight + 1;
const missedHeights = Array.from(
{ length: missedBlockCount },
(_, i) => firstMissedHeight + i,

return this._getLogsFromCache(firstMissedHeight, targetBlock, filter);
};

_getLogsFromCache = async (
fromBlock: number,
toBlock: number,
filter: SanitizedLogFilter,
): Promise<Log[]> => {
const blockCount = toBlock - fromBlock + 1; // when to === from, it should return 1 block
if (blockCount <= 0) return [];

const heights = Array.from(
{ length: blockCount },
(_, i) => fromBlock + i,
);
const missedBlockHashes = await Promise.all(missedHeights.map(this._getBlockHash.bind(this)));
const blockHashes = await Promise.all(heights.map(this._getBlockHash.bind(this)));

return missedBlockHashes
return blockHashes
.map(this.blockCache.getLogsAtBlock.bind(this))
.flat()
.filter(log => filterLogByBlockNumber(log, filter.fromBlock, filter.toBlock))
Expand All @@ -1814,13 +1823,28 @@ export abstract class BaseProvider extends AbstractProvider {

// Bloom-filter Queries
getLogs = async (rawFilter: LogFilter): Promise<Log[]> => {
const filter = await this._sanitizeRawFilter(rawFilter);

if (!this.subql) {
return logger.throwError(
'missing subql url to fetch logs, to initialize base provider with subql, please provide a subqlUrl param.'
const _throwErr = (earliestCachedBlockNumber?: number) => logger.throwError(
'cache does not contain enough info to fetch requested logs, please reduce block range or initialize provider with a subql url',
Logger.errors.SERVER_ERROR,
{
requestFromBlock: filter.fromBlock,
earliestCachedBlockNumber,
},
);
}

const filter = await this._sanitizeRawFilter(rawFilter);
const earliestCachedBlockHash = this.blockCache.cachedBlockHashes[0];
if (!earliestCachedBlockHash) return _throwErr();

const earliestCachedBlockNumber = await this._getBlockNumber(earliestCachedBlockHash);
const isAllTargetLogsInCache = earliestCachedBlockNumber <= filter.fromBlock;

return isAllTargetLogsInCache
? this._getLogsFromCache(filter.fromBlock, filter.toBlock, filter)
: _throwErr(earliestCachedBlockNumber);
}

// only filter by blockNumber and address, since topics are filtered at last
const [subqlLogs, extraLogs] = await Promise.all([
Expand Down

0 comments on commit 87b6ca6

Please sign in to comment.