Skip to content

Commit

Permalink
Merge pull request #1976 from aeternity/feature/devmode-poll-interval
Browse files Browse the repository at this point in the history
fix: ttl validation error in dev mode by reducing polling intervals
  • Loading branch information
davidyuk authored Apr 22, 2024
2 parents e62236f + 6f8cdc9 commit 0e1038b
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 31 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ jobs:
runs-on: ubuntu-22.04
steps:
- run: |
wget -q https://packages.erlang-solutions.com/erlang/debian/pool/esl-erlang_25.0.4-1~ubuntu~jammy_amd64.deb
sudo apt install --allow-downgrades ./esl-erlang_25.0.4-1~ubuntu~jammy_amd64.deb
wget -q https://packages.erlang-solutions.com/erlang/debian/pool/esl-erlang_25.2.3-1~ubuntu~jammy_amd64.deb
sudo apt install ./esl-erlang_25.2.3-1~ubuntu~jammy_amd64.deb
- uses: actions/checkout@v4
with:
fetch-depth: 100
Expand Down
46 changes: 28 additions & 18 deletions src/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,25 @@ import {
* @param type - Type
* @param options - Options
*/
export function _getPollInterval(
type: 'block' | 'microblock', // TODO: rename to 'key-block' | 'micro-block'
{ _expectedMineRate = 180000, _microBlockCycle = 3000 }:
{ _expectedMineRate?: number; _microBlockCycle?: number },
): number {
const base = {
block: _expectedMineRate,
microblock: _microBlockCycle,
}[type];
export async function _getPollInterval(
type: 'key-block' | 'micro-block',
{ _expectedMineRate, _microBlockCycle, onNode }:
{ _expectedMineRate?: number; _microBlockCycle?: number; onNode: Node },
): Promise<number> {
const getVal = async (
t: string,
val: number | undefined,
devModeDef: number,
def: number,
): Promise<number | null> => {
if (t !== type) return null;
if (val != null) return val;
return await onNode?.getNetworkId() === 'ae_dev' ? devModeDef : def;
};

const base = await getVal('key-block', _expectedMineRate, 0, 180000)
?? await getVal('micro-block', _microBlockCycle, 0, 3000)
?? (() => { throw new InternalError(`Unknown type: ${type}`); })();
return Math.floor(base / 3);
}

Expand All @@ -53,7 +63,7 @@ export async function getHeight(
const onNode = unwrapProxy(options.onNode);
if (cached) {
const cache = heightCache.get(onNode);
if (cache != null && cache.time > Date.now() - _getPollInterval('block', options)) {
if (cache != null && cache.time > Date.now() - await _getPollInterval('key-block', options)) {
return cache.height;
}
}
Expand All @@ -77,21 +87,21 @@ export async function getHeight(
export async function poll(
th: Encoded.TxHash,
{
blocks = 5, interval, onNode, ...options
blocks = 5, interval, ...options
}:
{ blocks?: number; interval?: number; onNode: Node } & Parameters<typeof _getPollInterval>[1],
): Promise<TransformNodeType<SignedTx>> {
interval ??= _getPollInterval('microblock', options);
interval ??= await _getPollInterval('micro-block', options);
let max;
do {
const tx = await onNode.getTransactionByHash(th);
const tx = await options.onNode.getTransactionByHash(th);
if (tx.blockHeight !== -1) return tx;
if (max == null) {
max = tx.tx.ttl !== 0 ? -1
: await getHeight({ ...options, onNode, cached: true }) + blocks;
: await getHeight({ ...options, cached: true }) + blocks;
}
await pause(interval);
} while (max === -1 ? true : await getHeight({ ...options, onNode, cached: true }) < max);
} while (max === -1 ? true : await getHeight({ ...options, cached: true }) < max);
throw new TxTimedOutError(blocks, th);
}

Expand All @@ -106,14 +116,14 @@ export async function poll(
*/
export async function awaitHeight(
height: number,
{ interval, onNode, ...options }:
{ interval, ...options }:
{ interval?: number; onNode: Node } & Parameters<typeof _getPollInterval>[1],
): Promise<number> {
interval ??= Math.min(_getPollInterval('block', options), 5000);
interval ??= Math.min(await _getPollInterval('key-block', options), 5000);
let currentHeight;
do {
if (currentHeight != null) await pause(interval);
currentHeight = await getHeight({ onNode });
currentHeight = await getHeight(options);
} while (currentHeight < height);
return currentHeight;
}
Expand Down
14 changes: 7 additions & 7 deletions src/oracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,12 @@ type OracleQueries = Awaited<ReturnType<Node['getOracleQueriesByPubkey']>>['orac
export function pollForQueries(
oracleId: Encoded.OracleAddress,
onQuery: (query: OracleQueries[number]) => void,
{ interval, onNode, ...options }: { interval?: number; onNode: Node }
{ interval, ...options }: { interval?: number; onNode: Node }
& Parameters<typeof _getPollInterval>[1],
): () => void {
interval ??= _getPollInterval('microblock', options);
const knownQueryIds = new Set();
const checkNewQueries = async (): Promise<void> => {
const queries = ((await onNode.getOracleQueriesByPubkey(oracleId)).oracleQueries ?? [])
const queries = ((await options.onNode.getOracleQueriesByPubkey(oracleId)).oracleQueries ?? [])
.filter(({ id }) => !knownQueryIds.has(id));
queries.forEach((query) => {
knownQueryIds.add(query.id);
Expand All @@ -52,6 +51,7 @@ export function pollForQueries(

// eslint-disable-next-line @typescript-eslint/no-floating-promises
(async () => {
interval ??= await _getPollInterval('micro-block', options);
while (!stopped) { // eslint-disable-line no-unmodified-loop-condition
// TODO: allow to handle this error somehow
await checkNewQueries().catch(console.error);
Expand All @@ -74,19 +74,19 @@ export function pollForQueries(
export async function pollForQueryResponse(
oracleId: Encoded.OracleAddress,
queryId: Encoded.OracleQueryId,
{ interval, onNode, ...options }:
{ interval, ...options }:
{ interval?: number; onNode: Node } & Parameters<typeof _getPollInterval>[1],
): Promise<string> {
interval ??= _getPollInterval('microblock', options);
interval ??= await _getPollInterval('micro-block', options);
let height;
let ttl;
let response;
do {
({ response, ttl } = await onNode.getOracleQueryByPubkeyAndQueryId(oracleId, queryId));
({ response, ttl } = await options.onNode.getOracleQueryByPubkeyAndQueryId(oracleId, queryId));
const responseBuffer = decode(response as Encoded.OracleResponse);
if (responseBuffer.length > 0) return responseBuffer.toString();
await pause(interval);
height = await getHeight({ ...options, onNode, cached: true });
height = await getHeight({ ...options, cached: true });
} while (ttl >= height);
throw new RequestTimedOutError(height);
}
Expand Down
2 changes: 1 addition & 1 deletion src/tx/builder/field-types/ttl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default {
onNode?: Node;
absoluteTtl?: boolean;
_isInternalBuild?: boolean;
} & Parameters<typeof _getPollInterval>[1],
} & Omit<Parameters<typeof _getPollInterval>[1], 'onNode'>,
) {
if (absoluteTtl !== true && value !== 0 && (value != null || _isInternalBuild === true)) {
if (onNode == null) throw new ArgumentError('onNode', 'provided', onNode);
Expand Down
24 changes: 24 additions & 0 deletions test/integration/AeSdk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { describe, it } from 'mocha';
import { expect } from 'chai';
import { getSdk, networkId } from '.';

describe('AeSdk', () => {
describe('_getPollInterval', () => {
it('returns value based on options', async () => {
const aeSdk = await getSdk(0);
aeSdk._options._expectedMineRate = 1000;
aeSdk._options._microBlockCycle = 300;
expect(await aeSdk._getPollInterval('key-block')).to.be.equal(333);
expect(await aeSdk._getPollInterval('micro-block')).to.be.equal(100);
});

it('returns correct value', async () => {
const aeSdk = await getSdk(0);
delete aeSdk._options._expectedMineRate;
delete aeSdk._options._microBlockCycle;
const [kb, mb] = networkId === 'ae_dev' ? [0, 0] : [60000, 1000];
expect(await aeSdk._getPollInterval('key-block')).to.be.equal(kb);
expect(await aeSdk._getPollInterval('micro-block')).to.be.equal(mb);
});
});
});
6 changes: 3 additions & 3 deletions test/unit/ae-sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import '../index';
import { AeSdk } from '../../src';

describe('AeSdk', () => {
it('executes methods without node, compiler, accounts', () => {
const aeSdk = new AeSdk();
expect(aeSdk._getPollInterval('block')).to.be.a('number');
it('executes methods without node, compiler, accounts', async () => {
const aeSdk = new AeSdk({ _expectedMineRate: 1000 });
expect(await aeSdk._getPollInterval('key-block')).to.be.equal(333);
});
});

0 comments on commit 0e1038b

Please sign in to comment.