Skip to content

Commit 9414255

Browse files
committed
fix bestblock definition
1 parent ca59c76 commit 9414255

File tree

6 files changed

+77
-70
lines changed

6 files changed

+77
-70
lines changed

examples/docker-compose-bodhi-stack.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ services:
2222
POSTGRES_PASSWORD: postgres
2323

2424
subquery-node:
25-
image: acala/evm-subql:2.7.13
25+
image: acala/evm-subql:2.7.16
2626
container_name: subquery-node
2727
ports:
2828
- 3000:3000
@@ -69,7 +69,7 @@ services:
6969
- --indexer=http://subquery-node:3000
7070

7171
eth-rpc-adapter-server:
72-
image: acala/eth-rpc-adapter:2.7.13
72+
image: acala/eth-rpc-adapter:2.7.16
7373
container_name: eth-rpc-adapter-server
7474
restart: always
7575
depends_on:

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"start:chain": "docker compose up --build -- chain-ready",
2626
"start:eth-rpc-adapter": "docker compose up --build -- eth-rpc-adapter-ready",
2727
"start:eth-rpc-adapter-subql": "docker compose up --build -- eth-rpc-adapter-with-subql-ready",
28+
"feed-tx": "yarn e2e:feed-tx && yarn e2e:feed-tx-2",
2829
"e2e:feed-tx": "yarn workspace evm-waffle-example-dex run test",
2930
"e2e:feed-tx-2": "yarn workspace evm-waffle-example-e2e run test",
3031
"e2e:eth-providers": "yarn start:chain; yarn e2e:feed-tx; yarn start:eth-rpc-adapter; yarn workspace @acala-network/eth-providers run test:e2e",

packages/eth-providers/src/base-provider-dd.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ const TRACE_METHODS = [
5353
'_getMaxTargetBlock',
5454
'_getSubqlMissedLogs',
5555
'getLogs',
56-
'_waitForCache',
5756
'getIndexerMetadata',
5857
'healthCheck',
5958
'addEventListener',

packages/eth-providers/src/base-provider.ts

Lines changed: 38 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ import {
8888
runWithRetries,
8989
runWithTiming,
9090
sendTx,
91-
sleep,
9291
sortObjByKey,
9392
subqlReceiptAdapter,
9493
throwNotImplemented,
@@ -341,14 +340,17 @@ export abstract class BaseProvider extends AbstractProvider {
341340
}
342341

343342
get bestBlockHash() {
344-
return firstValueFrom(this.best$).then(({ hash }) => hash);
343+
return this.blockCache.lastCachedBlock.hash;
345344
}
345+
346346
get bestBlockNumber() {
347-
return firstValueFrom(this.best$).then(({ number }) => number);
347+
return this.blockCache.lastCachedBlock.number;
348348
}
349+
349350
get finalizedBlockHash() {
350351
return firstValueFrom(this.finalized$).then(({ hash }) => hash);
351352
}
353+
352354
get finalizedBlockNumber() {
353355
return firstValueFrom(this.finalized$).then(({ number }) => number);
354356
}
@@ -362,15 +364,21 @@ export abstract class BaseProvider extends AbstractProvider {
362364
this.finalizedHead$ = this.api.rx.rpc.chain.subscribeFinalizedHeads();
363365

364366
const headSub = this.head$.subscribe(header => {
365-
this.best$.next({ hash: header.hash.toHex(), number: header.number.toNumber() });
367+
this.best$.next({
368+
hash: header.hash.toHex(),
369+
number: header.number.toNumber(),
370+
});
366371
});
367372

368373
const finalizedSub = this.finalizedHead$.subscribe(header => {
369374
this.finalizedBlockHashes.add(header.hash.toHex());
370-
this.finalized$.next({ hash: header.hash.toHex(), number: header.number.toNumber() });
375+
this.finalized$.next({
376+
hash: header.hash.toHex(),
377+
number: header.number.toNumber(),
378+
});
371379
});
372380

373-
await firstValueFrom(this.head$);
381+
const firstBlock = await firstValueFrom(this.head$);
374382
await firstValueFrom(this.finalizedHead$);
375383

376384
const safeHead$ = this.safeMode
@@ -393,6 +401,11 @@ export abstract class BaseProvider extends AbstractProvider {
393401
this.#finalizedHeadTasks.set(header.hash.toHex(), task);
394402
});
395403

404+
this.blockCache.setlastCachedBlock({
405+
hash: firstBlock.hash.toHex(),
406+
number: firstBlock.number.toNumber(),
407+
});
408+
396409
return () => {
397410
headSub.unsubscribe();
398411
finalizedSub.unsubscribe();
@@ -410,7 +423,7 @@ export abstract class BaseProvider extends AbstractProvider {
410423
const receipts = await getAllReceiptsAtBlock(this.api, blockHash);
411424
// update block cache
412425
this.blockCache.addReceipts(blockHash, receipts);
413-
this.blockCache.setlastCachedHeight(blockNumber);
426+
this.blockCache.setlastCachedBlock({ hash: blockHash, number: blockNumber });
414427

415428
// eth_subscribe
416429
await this._notifySubscribers(header, receipts);
@@ -558,11 +571,9 @@ export abstract class BaseProvider extends AbstractProvider {
558571
isReady = async (): Promise<void> => {
559572
try {
560573
await this.api.isReadyOrError;
561-
await this.getNetwork();
562574

563-
if (!this.#subscription) {
564-
this.#subscription = this.startSubscriptions();
565-
}
575+
this.#subscription ??= this.startSubscriptions();
576+
566577
// wait for subscription to happen
567578
await this.#subscription;
568579
} catch (e) {
@@ -593,27 +604,27 @@ export abstract class BaseProvider extends AbstractProvider {
593604
};
594605

595606
getNetwork = async (): Promise<Network> => {
596-
if (!this.network) {
597-
this.network = {
598-
name: this.api.runtimeVersion.specName.toString(),
599-
chainId: await this.chainId(),
600-
};
601-
}
607+
await this.isReady();
608+
609+
this.network ??= {
610+
name: this.api.runtimeVersion.specName.toString(),
611+
chainId: await this.chainId(),
612+
};
602613

603614
return this.network;
604615
};
605616

606-
netVersion = async (): Promise<string> => {
607-
return this.api.consts.evmAccounts.chainId.toString();
608-
};
617+
netVersion = async (): Promise<string> =>
618+
this.api.consts.evmAccounts.chainId.toString();
609619

610-
chainId = async (): Promise<number> => {
611-
return this.api.consts.evmAccounts.chainId.toNumber();
612-
};
620+
chainId = async (): Promise<number> =>
621+
this.api.consts.evmAccounts.chainId.toNumber();
613622

614-
getBlockNumber = async (): Promise<number> => {
615-
return this.safeMode ? this.finalizedBlockNumber : this.bestBlockNumber;
616-
};
623+
getBlockNumber = async (): Promise<number> => (
624+
this.safeMode
625+
? this.finalizedBlockNumber
626+
: this.bestBlockNumber
627+
);
617628

618629
getBlockData = async (_blockTag: BlockTag | Promise<BlockTag>, full?: boolean): Promise<BlockData> => {
619630
const blockTag = await this._ensureSafeModeBlockTagFinalization(_blockTag);
@@ -1820,16 +1831,14 @@ export abstract class BaseProvider extends AbstractProvider {
18201831

18211832
_getSubqlMissedLogs = async (toBlock: number, filter: SanitizedLogFilter): Promise<Log[]> => {
18221833
const targetBlock = await this._getMaxTargetBlock(toBlock);
1823-
const lastProcessedHeight = await this._checkSubqlHeight(); // all missed logs should be in cache
1834+
const lastProcessedHeight = await this._checkSubqlHeight();
18241835
const missedBlockCount = targetBlock - lastProcessedHeight;
18251836
if (missedBlockCount <= 0) return [];
18261837

18271838
const firstMissedBlock = lastProcessedHeight + 1;
18281839
const missedBlocks = Array.from({ length: missedBlockCount }, (_, i) => firstMissedBlock + i);
18291840
const missedBlockHashes = await Promise.all(missedBlocks.map(this._getBlockHash.bind(this)));
18301841

1831-
await this._waitForCache(targetBlock);
1832-
18331842
// no need to filter by blocknumber anymore, since these logs are from missedBlocks directly
18341843
return missedBlockHashes
18351844
.map(this.blockCache.getLogsAtBlock.bind(this))
@@ -1855,25 +1864,6 @@ export abstract class BaseProvider extends AbstractProvider {
18551864
.map(log => this.formatter.filterLog(log));
18561865
};
18571866

1858-
_waitForCache = async (_targetBlock: number) => {
1859-
const CACHE_MAX_WAIT_BLOCKS = 2;
1860-
1861-
const targetBlock = await this._getMaxTargetBlock(_targetBlock);
1862-
let lastCachedHeight = await this.subql.getLastProcessedHeight();
1863-
if (targetBlock - lastCachedHeight > CACHE_MAX_WAIT_BLOCKS){
1864-
return logger.throwError(
1865-
'blockCache is not synced to target block, please wait for it to catch up',
1866-
Logger.errors.SERVER_ERROR,
1867-
{ targetBlock, lastCachedHeight }
1868-
);
1869-
}
1870-
1871-
while (lastCachedHeight < targetBlock) {
1872-
await sleep(1000);
1873-
lastCachedHeight = this.blockCache.lastCachedHeight;
1874-
}
1875-
};
1876-
18771867
getIndexerMetadata = async (): Promise<_Metadata | undefined> => {
18781868
return this.subql?.getIndexerMetadata();
18791869
};

packages/eth-providers/src/utils/BlockCache.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import { FullReceipt } from './receiptHelper';
44

55
export type TxHashToReceipt = Record<string, FullReceipt>;
66
export type BlockHashToReceipts = Record<string, FullReceipt[]>;
7+
export type Block = {
8+
number: number;
9+
hash: string;
10+
}
711

812
export interface CacheInspect {
913
maxCachedBlocks: number;
@@ -17,18 +21,17 @@ export class BlockCache {
1721
txHashToReceipt: TxHashToReceipt;
1822
cachedBlockHashes: string[];
1923
maxCachedBlocks: number;
20-
lastCachedHeight: number;
24+
lastCachedBlock: Block;
2125

2226
constructor(maxCachedBlocks = 200) {
2327
this.txHashToReceipt = {};
2428
this.blockHashToReceipts = {};
2529
this.cachedBlockHashes = [];
2630
this.maxCachedBlocks = maxCachedBlocks;
27-
this.lastCachedHeight = -1;
31+
this.lastCachedBlock = null;
2832
}
2933

30-
setlastCachedHeight = (blockNumber: number) =>
31-
(this.lastCachedHeight = blockNumber);
34+
setlastCachedBlock = (block: Block) => (this.lastCachedBlock = block);
3235

3336
// automatically preserve a sliding window of ${maxCachedBlocks} blocks
3437
addReceipts = (blockHash: string, receipts: FullReceipt[]): void => {

packages/eth-rpc-adapter/src/__tests__/e2e/endpoint.test.ts

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -107,17 +107,31 @@ describe('endpoint', () => {
107107
const DETERMINISTIC_SETUP_TOTAL_TXS = 12;
108108
const DETERMINISTIC_SETUP_TOTAL_LOGS = 13;
109109
let tries = 0;
110-
let [allTxReceipts, allLogs] = await Promise.all([subql.getAllTxReceipts(), subql.getAllLogs()]);
110+
let [allTxReceipts, allLogs] = await Promise.all([
111+
subql.getAllTxReceipts(),
112+
subql.getAllLogs(),
113+
]);
111114
while (
112-
(allTxReceipts.length < DETERMINISTIC_SETUP_TOTAL_TXS || allLogs.length < DETERMINISTIC_SETUP_TOTAL_LOGS) &&
113-
tries++ < 10
115+
tries++ < 5 &&
116+
(
117+
allTxReceipts.length < DETERMINISTIC_SETUP_TOTAL_TXS ||
118+
allLogs.length < DETERMINISTIC_SETUP_TOTAL_LOGS
119+
)
114120
) {
115-
console.log(`let's give subql a little bit more time to index, retrying #${tries} in 5s ...`);
116-
await sleep(10000);
117-
[allTxReceipts, allLogs] = await Promise.all([subql.getAllTxReceipts(), subql.getAllLogs()]);
121+
console.log(allTxReceipts.length, allLogs.length);
122+
console.log(`let's give subql a little bit more time to index, retrying #${tries} in 3s ...`);
123+
await sleep(3000);
124+
125+
[allTxReceipts, allLogs] = await Promise.all([
126+
subql.getAllTxReceipts(),
127+
subql.getAllLogs(),
128+
]);
118129
}
119130

120-
if (allTxReceipts.length < DETERMINISTIC_SETUP_TOTAL_TXS || allLogs.length < DETERMINISTIC_SETUP_TOTAL_LOGS) {
131+
if (
132+
allTxReceipts.length < DETERMINISTIC_SETUP_TOTAL_TXS ||
133+
allLogs.length < DETERMINISTIC_SETUP_TOTAL_LOGS
134+
) {
121135
throw new Error(`
122136
test env setup failed!
123137
expected ${DETERMINISTIC_SETUP_TOTAL_TXS} Txs in subql but got ${allTxReceipts.length}
@@ -222,7 +236,7 @@ describe('endpoint', () => {
222236
describe('eth_getLogs', () => {
223237
const ALL_BLOCK_RANGE_FILTER = { fromBlock: 'earliest' };
224238

225-
describe('when no filter', () => {
239+
describe.concurrent('when no filter', () => {
226240
it('returns all logs from latest block', async () => {
227241
const res = (await eth_getLogs([{}])).data.result;
228242
expect(res.length).to.equal(2);
@@ -231,7 +245,7 @@ describe('endpoint', () => {
231245
});
232246
});
233247

234-
describe('filter by address', () => {
248+
describe.concurrent('filter by address', () => {
235249
it('returns correct logs', async () => {
236250
/* ---------- single address ---------- */
237251
for (const log of allLogs) {
@@ -251,7 +265,7 @@ describe('endpoint', () => {
251265
});
252266
});
253267

254-
describe('filter by block number', () => {
268+
describe.concurrent('filter by block number', () => {
255269
it('returns correct logs', async () => {
256270
const BIG_NUMBER = 88888888;
257271
const BIG_NUMBER_HEX = '0x54C5638';
@@ -299,7 +313,7 @@ describe('endpoint', () => {
299313
});
300314
});
301315

302-
describe('filter by block tag', () => {
316+
describe.concurrent('filter by block tag', () => {
303317
it('returns correct logs for valid tag', async () => {
304318
let res: Awaited<ReturnType<typeof eth_getLogs>>;
305319
let expectedLogs: LogHexified[];
@@ -350,7 +364,7 @@ describe('endpoint', () => {
350364
});
351365
});
352366

353-
describe('filter by topics', () => {
367+
describe.concurrent('filter by topics', () => {
354368
it('returns correct logs', async () => {
355369
let res: Awaited<ReturnType<typeof eth_getLogs>>;
356370
let expectedLogs: LogHexified[];
@@ -396,7 +410,7 @@ describe('endpoint', () => {
396410
});
397411
});
398412

399-
describe('filter by blockhash', () => {
413+
describe.concurrent('filter by blockhash', () => {
400414
it('returns correct logs', async () => {
401415
const allLogsFromSubql = await subql.getAllLogs().then(logs => logs.map(hexilifyLog));
402416
for (const log of allLogsFromSubql) {
@@ -407,7 +421,7 @@ describe('endpoint', () => {
407421
});
408422
});
409423

410-
describe('filter by multiple params', () => {
424+
describe.concurrent('filter by multiple params', () => {
411425
it('returns correct logs', async () => {
412426
let res: Awaited<ReturnType<typeof eth_getLogs>>;
413427
let expectedLogs: LogHexified[];
@@ -474,7 +488,7 @@ describe('endpoint', () => {
474488
expect(res2.data.result).to.deep.equal(res.data.result);
475489
});
476490

477-
it('should throw correct error is subql is not synced', async () => {
491+
it('should throw correct error if subql is not synced', async () => {
478492
const curblockNum = await provider.getBlockNumber();
479493
const pendings = [] as any[];
480494
for (let i = 0; i < 5; i++) {

0 commit comments

Comments
 (0)