Skip to content

Commit

Permalink
Merge branch 'release/0.21' into cherry-pick-1067-to-0-21
Browse files Browse the repository at this point in the history
  • Loading branch information
lukelee-sl authored Apr 15, 2023
2 parents f9bc8e9 + 80eaa25 commit 7a7f34f
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 2 deletions.
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,9 @@ SUBSCRIPTIONS_ENABLED=
SERVER_PORT=
WEB_SOCKET_PORT=
CONNECTION_LIMIT=
WS_MAX_CONNECTION_TTL=
WS_CONNECTION_LIMIT_PER_IP=
WS_SUBSCRIPTION_LIMIT=
WS_MULTIPLE_ADDRESSES_ENABLED=
ETH_BLOCK_NUMBER_CACHE_TTL_MS=
ETH_GET_BALANCE_CACHE_TTL_MS=
1 change: 1 addition & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Unless you need to set a non-default value, it is recommended to only populate o
| `DEFAULT_RATE_LIMIT` | "200" | default fallback rate limit, if no other is configured. |
| `ETH_CALL_CACHE_TTL` | "200" | Maximum time in ms to cache an eth_call response. |
| `ETH_BLOCK_NUMBER_CACHE_TTL_MS` | "1000" | Time in ms to cache response from mirror node |
| `ETH_GET_BALANCE_CACHE_TTL_MS` | "1000" | Time in ms to cache balance returned |
| `ETH_CALL_DEFAULT_TO_CONSENSUS_NODE ` | "false" | Flag to set if eth_call logic should first query the mirror node. |
| `ETH_GET_LOGS_BLOCK_RANGE_LIMIT` | "1000" | The maximum block number range to consider during an eth_getLogs call. |
| `FEE_HISTORY_MAX_RESULTS` | "10" | The maximum number of results to returns as part of `eth_feeHistory`. |
Expand Down
1 change: 0 additions & 1 deletion k6/.envexample
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,3 @@ DEFAULT_GRACEFUL_STOP=
FILTER_TEST=
DEBUG_MODE=
SIGNED_TXS=
ETH_BLOCK_NUMBER_CACHE_TTL_MS=
1 change: 1 addition & 0 deletions packages/relay/src/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum CACHE_KEY {
FEE_HISTORY = 'fee_history',
GET_CONTRACT_RESULT = 'getContractResult',
ETH_BLOCK_NUMBER = 'eth_block_number',
ETH_GET_BALANCE = 'eth_get_balance',
}

enum CACHE_TTL {
Expand Down
16 changes: 16 additions & 0 deletions packages/relay/src/lib/eth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export class EthImpl implements Eth {
static invalidEVMInstruction = '0xfe';
static ethCallCacheTtl = process.env.ETH_CALL_CACHE_TTL || 200;
static ethBlockNumberCacheTtlMs = process.env.ETH_BLOCK_NUMBER_CACHE_TTL_MS || 1000;
static ethGetBalanceCacheTtlMs = process.env.ETH_GET_BALANCE_CACHE_TTL_MS || 1000;

// endpoint metric callerNames
static ethCall = 'eth_call';
Expand Down Expand Up @@ -309,6 +310,7 @@ export class EthImpl implements Eth {
const blockNumberCached = this.cache.get(cacheKey);

if(blockNumberCached) {
this.logger.trace(`${requestIdPrefix} returning cached value ${cacheKey}:${JSON.stringify(blockNumberCached)}`);
return blockNumberCached;
}

Expand All @@ -318,6 +320,7 @@ export class EthImpl implements Eth {
const currentBlock = EthImpl.numberTo0x(blocks[0].number);
// save the latest block number in cache
this.cache.set(cacheKey, currentBlock, { ttl: EthImpl.ethBlockNumberCacheTtlMs });
this.logger.trace(`${requestIdPrefix} caching ${cacheKey}:${JSON.stringify(currentBlock)} for ${EthImpl.ethBlockNumberCacheTtlMs} ms`);

return currentBlock;
}
Expand Down Expand Up @@ -577,6 +580,15 @@ export class EthImpl implements Eth {
}
}

// check cache first
// create a key for the cache
const cacheKey = `${constants.CACHE_KEY.ETH_GET_BALANCE}-${account}-${blockNumberOrTag}`;
const cachedBalance = this.cache.get(cacheKey);
if (cachedBalance) {
this.logger.trace(`${requestIdPrefix} returning cached value ${cacheKey}:${JSON.stringify(cachedBalance)}`);
return cachedBalance;
}

let blockNumber = null;
let balanceFound = false;
let weibars: BigInt = BigInt(0);
Expand Down Expand Up @@ -649,6 +661,10 @@ export class EthImpl implements Eth {
return EthImpl.zeroHex;
}

// save in cache the current balance for the account and blockNumberOrTag
this.cache.set(cacheKey, EthImpl.numberTo0x(weibars), {ttl: EthImpl.ethGetBalanceCacheTtlMs});
this.logger.trace(`${requestIdPrefix} caching ${cacheKey}:${JSON.stringify(cachedBalance)} for ${EthImpl.ethGetBalanceCacheTtlMs} ms`);

return EthImpl.numberTo0x(weibars);
} catch (error: any) {
throw this.genericErrorHandler(error, `${requestIdPrefix} Error raised during getBalance for account ${account}`);
Expand Down
40 changes: 39 additions & 1 deletion packages/relay/tests/lib/eth.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,44 @@ describe('Eth calls using MirrorNode', async function () {
expect(resBalance).to.equal(defHexBalance);
});

it('should return balance for latest block from cache', async () => {
restMock.onGet(`blocks?limit=1&order=desc`).reply(200, {
blocks: [{
number: 10000
}]
});
restMock.onGet(`accounts/${contractAddress1}`).reply(200, {
account: contractAddress1,
balance: {
balance: defBalance
}
});

const resBalance = await ethImpl.getBalance(contractAddress1, null);
expect(resBalance).to.equal(defHexBalance);

// next call should use cache
restMock.onGet(`accounts/${contractAddress1}`).reply(404, {});

const resBalanceCached = await ethImpl.getBalance(contractAddress1, null);
expect(resBalanceCached).to.equal(resBalance);

// Third call should return new number using mirror node
const newBalance = 55555;
const newBalanceHex = EthImpl.numberTo0x(BigInt(newBalance) * TINYBAR_TO_WEIBAR_COEF_BIGINT);
restMock.onGet(`accounts/${contractAddress1}`).reply(200, {
account: contractAddress1,
balance: {
balance: newBalance
}
});
// expire cache, instead of waiting for ttl we clear it to simulate expiry faster.
cache.clear();

const resBalanceNew = await ethImpl.getBalance(contractAddress1, null);
expect(newBalanceHex).to.equal(resBalanceNew);
});

it('should return balance from mirror node with block number passed as param the same as latest', async () => {
const blockNumber = "0x2710";
restMock.onGet(`blocks?limit=1&order=desc`).reply(200, {
Expand Down Expand Up @@ -1394,7 +1432,7 @@ describe('Eth calls using MirrorNode', async function () {

const resCached = await ethImpl.getBalance(contractAddress1, null);
expect(resNoCache).to.equal(defHexBalance);
expect(resCached).to.equal(EthImpl.zeroHex);
expect(resCached).to.equal(defHexBalance);
});

describe('with blockNumberOrTag filter', async function() {
Expand Down

0 comments on commit 7a7f34f

Please sign in to comment.