Skip to content

Commit

Permalink
Merge branch 'main' into add-new-metrics-for-spending-plans
Browse files Browse the repository at this point in the history
  • Loading branch information
victor-yanev authored Sep 9, 2024
2 parents 086a452 + 559285b commit d4ea964
Show file tree
Hide file tree
Showing 15 changed files with 170 additions and 62 deletions.
1 change: 1 addition & 0 deletions charts/hedera-json-rpc-relay/value-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ config:
FILTER_API_ENABLED: true
MULTI_SET: true
GAS_PRICE_PERCENTAGE_BUFFER: 0
ETH_CALL_FORCE_TO_CONSENSUS_BY_SELECTOR: true

# Enable rolling_restarts if SDK calls fail this is usually due to stale connections that get cycled on restart
rolling_restart:
Expand Down
1 change: 1 addition & 0 deletions charts/hedera-json-rpc-relay/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ config:
FILTER_API_ENABLED: true
MULTI_SET: true
GAS_PRICE_PERCENTAGE_BUFFER: 0
ETH_CALL_FORCE_TO_CONSENSUS_BY_SELECTOR: true

# -- Extra environment variables from existing secrets or configmaps
extraEnvFrom: []
Expand Down
65 changes: 33 additions & 32 deletions docs/configuration.md

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@
"@ethereumjs/rlp": "^5.0.2",
"@ethereumjs/trie": "^6.2.0",
"@ethereumjs/util": "^9.0.3",
"@hashgraph/hedera-local": "^2.29.0",
"@hashgraph/hedera-local": "^2.29.2",
"@open-rpc/schema-utils-js": "^1.16.1",
"@types/find-config": "^1.0.4",
"@types/sinon": "^10.0.20",
"chai-exclude": "^2.1.1",
"ajv": "^8.16.0",
"ajv-formats": "^3.0.1",
"chai-exclude": "^2.1.1",
"eslint-config-standard-with-typescript": "^43.0.1",
"eslint-plugin-n": "^15.7.0",
"keyv-file": "^0.3.1",
Expand Down
8 changes: 8 additions & 0 deletions packages/relay/src/formatters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
import crypto from 'crypto';
import constants from './lib/constants';
import { BigNumber as BN } from 'bignumber.js';
import { TransactionRecord } from '@hashgraph/sdk';
import { BigNumber } from '@hashgraph/sdk/lib/Transfer';
import { MirrorNodeTransactionRecord } from './lib/types/mirrorNode';
import { Transaction, Transaction1559, Transaction2930 } from './lib/model';

const EMPTY_HEX = '0x';
Expand Down Expand Up @@ -297,6 +299,11 @@ const isHex = (value: string): boolean => {
return hexRegex.test(value);
};

const getFunctionSelector = (data?: string): string => {
if (!data) return '';
return data.replace(/^0x/, '').substring(0, 8);
};

export {
hashNumber,
formatRequestIdMessage,
Expand All @@ -322,5 +329,6 @@ export {
isValidEthereumAddress,
isHex,
ASCIIToHex,
getFunctionSelector,
mapKeysAndValues,
};
8 changes: 8 additions & 0 deletions packages/relay/src/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,14 @@ export default {
DETERMINISTIC_DEPLOYMENT_SIGNER: '0x3fab184622dc19b6109349b94811493bf2a45362',
DETERMINISTIC_PROXY_CONTRACT: '0x4e59b44847b379578588920ca78fbf26c0b4956c',

// Only active when process.env.ETH_CALL_FORCE_TO_CONSENSUS_BY_SELECTOR = true
// When eth_call is called with one of the data values it should be forced to go through Consensus node regardless of ETH_CALL_DEFAULT_TO_CONSENSUS_NODE
ETH_CALL_SELECTORS_ALWAYS_TO_CONSENSUS: [
// isAssociated()
// calls to this method should be handled by Consensus until the required EVM changes are applied to the Mirror node
'4d8fdd6d',
],

// computed hash of an empty Trie object
DEFAULT_ROOT_HASH: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',

Expand Down
22 changes: 14 additions & 8 deletions packages/relay/src/lib/eth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import {
weibarHexToTinyBarInt,
isValidEthereumAddress,
formatTransactionIdWithoutQueryParams,
getFunctionSelector,
} from '../formatters';

const _ = require('lodash');
Expand Down Expand Up @@ -1619,7 +1620,7 @@ export class EthImpl implements Eth {
): Promise<string | JsonRpcError> {
const callData = call.data ? call.data : call.input;
// log request
this.logger.trace(
this.logger.info(
`${requestIdPrefix} call({to=${call.to}, from=${call.from}, data=${callData}, gas=${call.gas}, gasPrice=${call.gasPrice} blockParam=${blockParam}, estimate=${call.estimate})`,
);
// log call data size
Expand All @@ -1640,18 +1641,23 @@ export class EthImpl implements Eth {

await this.contractCallFormat(call, requestIdPrefix);

const selector = getFunctionSelector(call.data!);

const shouldForceToConsensus =
process.env.ETH_CALL_FORCE_TO_CONSENSUS_BY_SELECTOR == 'true' &&
constants.ETH_CALL_SELECTORS_ALWAYS_TO_CONSENSUS.indexOf(selector) !== -1;

// ETH_CALL_DEFAULT_TO_CONSENSUS_NODE = false enables the use of Mirror node
const shouldDefaultToConsensus = process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE === 'true';

let result: string | JsonRpcError = '';
try {
// ETH_CALL_DEFAULT_TO_CONSENSUS_NODE = false enables the use of Mirror node
if (
process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE === undefined ||
process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE == 'false'
) {
if (shouldForceToConsensus || shouldDefaultToConsensus) {
result = await this.callConsensusNode(call, gas, requestIdPrefix);
} else {
//temporary workaround until precompiles are implemented in Mirror node evm module
// Execute the call and get the response
result = await this.callMirrorNode(call, gas, call.value, blockNumberOrTag, requestIdPrefix);
} else {
result = await this.callConsensusNode(call, gas, requestIdPrefix);
}

this.logger.debug(`${requestIdPrefix} eth_call response: ${JSON.stringify(result)}`);
Expand Down
58 changes: 58 additions & 0 deletions packages/relay/tests/lib/eth/eth_call.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -867,4 +867,62 @@ describe('@ethCall Eth Call spec', async function () {
expect(transaction.from).to.equal(operatorEvmAddress);
});
});

describe('eth_call using consensus node because of redirect by selector', async function () {
let initialForceToConsensusBySelectorFF;
let initialEthCallConesneusFF;
const REDIRECTED_SELECTOR = '0x4d8fdd6d';
const NON_REDIRECTED_SELECTOR = '0xaaaaaaaa';
let callConsensusNodeSpy: sinon.SinonSpy;
let callMirrorNodeSpy: sinon.SinonSpy;
let sandbox: sinon.SinonSandbox;

before(() => {
initialForceToConsensusBySelectorFF = process.env.ETH_CALL_FORCE_TO_CONSENSUS_BY_SELECTOR;
initialEthCallConesneusFF = process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE;
process.env.ETH_CALL_FORCE_TO_CONSENSUS_BY_SELECTOR = 'true';
process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE = 'false';
});

after(() => {
process.env.ETH_CALL_FORCE_TO_CONSENSUS_BY_SELECTOR = initialForceToConsensusBySelectorFF;
process.env.ETH_CALL_DEFAULT_TO_CONSENSUS_NODE = initialEthCallConesneusFF;
});

beforeEach(() => {
sandbox = sinon.createSandbox();
callConsensusNodeSpy = sandbox.spy(ethImpl, 'callConsensusNode');
callMirrorNodeSpy = sandbox.spy(ethImpl, 'callMirrorNode');
});

afterEach(() => {
sandbox.restore();
});

it('eth_call with matched selector redirects to consensus', async function () {
await ethImpl.call(
{
to: ACCOUNT_ADDRESS_1,
data: REDIRECTED_SELECTOR,
},
'latest',
);

assert(callConsensusNodeSpy.calledOnce);
assert(callMirrorNodeSpy.notCalled);
});

it('eth_call with non-matched selector redirects to consensus', async function () {
await ethImpl.call(
{
to: ACCOUNT_ADDRESS_1,
data: NON_REDIRECTED_SELECTOR,
},
'latest',
);

assert(callConsensusNodeSpy.notCalled);
assert(callMirrorNodeSpy.calledOnce);
});
});
});
26 changes: 26 additions & 0 deletions packages/relay/tests/lib/formatters.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ import {
toNullableBigNumber,
toNullIfEmptyHex,
trimPrecedingZeros,
isHex,
ASCIIToHex,
formatRequestIdMessage,
strip0x,
getFunctionSelector,
toHexString,
weibarHexToTinyBarInt,
} from '../../src/formatters';
import constants from '../../src/lib/constants';
Expand Down Expand Up @@ -682,6 +688,26 @@ describe('Formatters', () => {
});
});

describe('getFunctionSelector', () => {
it('should return an empty string when input is an empty string or undefined', () => {
const result = getFunctionSelector('');
expect(result).to.eq('');

const undefinedResult = getFunctionSelector(undefined);
expect(undefinedResult).to.eq('');
});

it('should return the first 8 characters of a valid hex string without "0x"', () => {
const result = getFunctionSelector('1234567890abcdef');
expect(result).to.eq('12345678');
});

it('should return the first 8 characters of a valid hex string starting with "0x"', () => {
const result = getFunctionSelector('0x1234567890abcdef');
expect(result).to.eq('12345678');
});
});

describe('mapKeysAndValues', () => {
it('should map keys and values correctly', () => {
const target = { a: '1', b: '2', c: '3' };
Expand Down
2 changes: 1 addition & 1 deletion packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"uuid": "^3.3.2"
},
"devDependencies": {
"@hashgraph/hedera-local": "^2.29.0",
"@hashgraph/hedera-local": "^2.29.2",
"@hashgraph/sdk": "^2.50.0-beta.3",
"@koa/cors": "^5.0.0",
"@types/chai": "^4.3.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/ws-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"pnpm": "8.15.9"
},
"devDependencies": {
"@hashgraph/hedera-local": "^2.29.0",
"@hashgraph/hedera-local": "^2.29.2",
"@hashgraph/sdk": "^2.50.0-beta.3",
"@koa/cors": "^5.0.0",
"@types/chai": "^4.3.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/ws-server/tests/acceptance/subscribe.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ describe('@web-socket-batch-3 eth_subscribe', async function () {
assertions.expectLogArgs(eventsReceived[0], contracts[1], [BigInt(1)]);
});

it('Subscribing for contract logs for a speciffic contract address and a wrong topic.', async function () {
it('Subscribing for contract logs for a specific contract address and a wrong topic.', async function () {
let eventsReceived = eventsReceivedGlobal[6];

// Only the logs from logContractSigner.target are captured
Expand Down
9 changes: 4 additions & 5 deletions tools/hardhat-viem-example/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tools/hardhat-viem-example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"local-node": "npx @hashgraph/hedera-local restart -d"
},
"dependencies": {
"@hashgraph/hedera-local": "^2.29.0",
"@hashgraph/hedera-local": "^2.29.2",
"@nomicfoundation/hardhat-toolbox-viem": "^3.0.0",
"dotenv": "^16.0.3"
},
Expand Down

0 comments on commit d4ea964

Please sign in to comment.