Skip to content

Commit c4801ae

Browse files
authored
fix: convert value from weibars to tinybars in eth_call (#2184)
* fix: eth_call expects weibars as value Signed-off-by: Ivo Yankov <[email protected]> * chore: simplify fix Signed-off-by: Ivo Yankov <[email protected]> * test: add unit tests to illustrate conversion Signed-off-by: Ivo Yankov <[email protected]> * chore: reduce code duplication Signed-off-by: Ivo Yankov <[email protected]> --------- Signed-off-by: Ivo Yankov <[email protected]>
1 parent 68bfe45 commit c4801ae

File tree

5 files changed

+40
-6
lines changed

5 files changed

+40
-6
lines changed

packages/relay/src/lib/eth.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import {
3737
nullableNumberTo0x,
3838
nanOrNumberTo0x,
3939
toHash32,
40-
toNullableBigNumber,
4140
weibarHexToTinyBarInt,
4241
trimPrecedingZeros,
4342
} from '../formatters';
@@ -1477,7 +1476,6 @@ export class EthImpl implements Eth {
14771476

14781477
// Get a reasonable value for "gas" if it is not specified.
14791478
const gas = this.getCappedBlockGasLimit(call.gas, requestIdPrefix);
1480-
const value: string | null = toNullableBigNumber(call.value);
14811479

14821480
this.contractCallFormat(call);
14831481

@@ -1489,7 +1487,7 @@ export class EthImpl implements Eth {
14891487
) {
14901488
//temporary workaround until precompiles are implemented in Mirror node evm module
14911489
// Execute the call and get the response
1492-
return await this.callMirrorNode(call, gas, value, blockNumberOrTag, requestIdPrefix);
1490+
return await this.callMirrorNode(call, gas, call.value, blockNumberOrTag, requestIdPrefix);
14931491
}
14941492

14951493
return await this.callConsensusNode(call, gas, requestIdPrefix);

packages/relay/tests/lib/eth/eth-config.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* limitations under the License.
1818
*
1919
*/
20-
import { defaultEvmAddress, defaultLogs1, defaultLogs2, defaultLogs3, mockData } from '../../helpers';
20+
import { defaultEvmAddress, defaultLogs1, defaultLogs2, defaultLogs3, mockData, toHex } from '../../helpers';
2121
import { numberTo0x } from '../../../dist/formatters';
2222
import constants from '../../../src/lib/constants';
2323

@@ -129,6 +129,8 @@ export const DEPLOYED_BYTECODE =
129129
export const MIRROR_NODE_DEPLOYED_BYTECODE =
130130
'0x608060405234801561001057600080fd5b5060405161078938038061078983398181016040528101906100321234';
131131
export const TINYBAR_TO_WEIBAR_COEF_BIGINT = BigInt(constants.TINYBAR_TO_WEIBAR_COEF);
132+
export const ONE_TINYBAR_IN_WEI_HEX = toHex(TINYBAR_TO_WEIBAR_COEF_BIGINT);
133+
132134
export const BASE_FEE_PER_GAS_HEX = numberTo0x(
133135
BigInt(DEFAULT_NETWORK_FEES.fees[2].gas) * TINYBAR_TO_WEIBAR_COEF_BIGINT,
134136
); // '0x84b6a5c400' -> 570_000_000_000 tb

packages/relay/tests/lib/eth/eth_call.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import {
4242
NO_TRANSACTIONS,
4343
NON_EXISTENT_CONTRACT_ADDRESS,
4444
WRONG_CONTRACT_ADDRESS,
45+
ONE_TINYBAR_IN_WEI_HEX,
4546
} from './eth-config';
4647
import { JsonRpcError, predefined } from '../../../src/lib/errors/JsonRpcError';
4748
import RelayAssertions from '../../assertions';
@@ -674,6 +675,25 @@ describe('@ethCall Eth Call spec', async function () {
674675
expect(result).to.equal('0x00');
675676
});
676677

678+
it('eth_call with all fields and value', async function () {
679+
const callData = {
680+
...defaultCallData,
681+
gas: MAX_GAS_LIMIT,
682+
data: CONTRACT_CALL_DATA,
683+
to: CONTRACT_ADDRESS_2,
684+
from: ACCOUNT_ADDRESS_1,
685+
value: 1, // Mirror node is called with value in Tinybars
686+
block: 'latest',
687+
};
688+
689+
web3Mock.onPost('contracts/call', { ...callData, estimate: false }).reply(200, { result: `0x00` });
690+
restMock.onGet(`contracts/${CONTRACT_ADDRESS_2}`).reply(200, DEFAULT_CONTRACT_2);
691+
692+
// Relay is called with value in Weibars
693+
const result = await ethImpl.call({ ...callData, value: ONE_TINYBAR_IN_WEI_HEX }, 'latest');
694+
expect(result).to.equal('0x00');
695+
});
696+
677697
it('eth_call with all fields but mirrorNode throws 429', async function () {
678698
const callData = {
679699
...defaultCallData,

packages/relay/tests/lib/eth/eth_estimateGas.spec.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { EthImpl } from '../../../src/lib/eth';
2828
import constants from '../../../src/lib/constants';
2929
import { SDKClient } from '../../../src/lib/clients';
3030
import { numberTo0x } from '../../../dist/formatters';
31-
import { DEFAULT_NETWORK_FEES, NO_TRANSACTIONS, RECEIVER_ADDRESS } from './eth-config';
31+
import { DEFAULT_NETWORK_FEES, NO_TRANSACTIONS, ONE_TINYBAR_IN_WEI_HEX, RECEIVER_ADDRESS } from './eth-config';
3232
import { JsonRpcError } from '../../../src/lib/errors/JsonRpcError';
3333
import { generateEthTestEnv } from './eth-helpers';
3434

@@ -113,6 +113,18 @@ describe('@ethEstimateGas Estimate Gas spec', async function () {
113113
expect((gas as string).toLowerCase()).to.equal(numberTo0x(constants.TX_DEFAULT_GAS_DEFAULT).toLowerCase());
114114
});
115115

116+
it('should eth_estimateGas contract call with value is converted to tinybars before it is sent to mirror node', async function () {
117+
const callData = {
118+
data: '0x608060405234801561001057600080fd5b506040516107893803806107898339818101604052810190610032919061015a565b806000908051906020019061004892919061004f565b50506102f6565b82805461005b90610224565b90600052602060002090601f01602090048101928261007d57600085556100c4565b82601f1061009657805160ff19168380011785556100c4565b828001600101855582156100c4579182015b828111156100c35782518255916020019190600101906100a8565b5b5090506100d191906100d5565b5090565b5b808211156100ee5760008160009055506001016100d6565b5090565b6000610105610100846101c0565b61019b565b90508281526020810184848401111561011d57600080fd5b6101288482856101f1565b509392505050565b600082601f83011261014157600080fd5b81516101518482602086016100f2565b91505092915050565b60006020828403121561016c57600080fd5b600082015167ffffffffffffffff81111561018657600080fd5b61019284828501610130565b91505092915050565b60006101a56101b6565b90506101b18282610256565b919050565b6000604051905090565b600067ffffffffffffffff8211156101db576101da6102b6565b5b6101e4826102e5565b9050602081019050919050565b60005b8381101561020f5780820151818401526020810190506101f4565b8381111561021e576000848401525b50505050565b6000600282049050600182168061023c57607f821691505b602082108114156102505761024f610287565b5b50919050565b61025f826102e5565b810181811067ffffffffffffffff8211171561027e5761027d6102b6565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b610484806103056000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063a41368621461003b578063cfae321714610057575b600080fd5b6100556004803603810190610050919061022c565b610075565b005b61005f61008f565b60405161006c91906102a6565b60405180910390f35b806000908051906020019061008b929190610121565b5050565b60606000805461009e9061037c565b80601f01602080910402602001604051908101604052809291908181526020018280546100ca9061037c565b80156101175780601f106100ec57610100808354040283529160200191610117565b820191906000526020600020905b8154815290600101906020018083116100fa57829003601f168201915b5050505050905090565b82805461012d9061037c565b90600052602060002090601f01602090048101928261014f5760008555610196565b82601f1061016857805160ff1916838001178555610196565b82800160010185558215610196579182015b8281111561019557825182559160200191906001019061017a565b5b5090506101a391906101a7565b5090565b5b808211156101c05760008160009055506001016101a8565b5090565b60006101d76101d2846102ed565b6102c8565b9050828152602081018484840111156101ef57600080fd5b6101fa84828561033a565b509392505050565b600082601f83011261021357600080fd5b81356102238482602086016101c4565b91505092915050565b60006020828403121561023e57600080fd5b600082013567ffffffffffffffff81111561025857600080fd5b61026484828501610202565b91505092915050565b60006102788261031e565b6102828185610329565b9350610292818560208601610349565b61029b8161043d565b840191505092915050565b600060208201905081810360008301526102c0818461026d565b905092915050565b60006102d26102e3565b90506102de82826103ae565b919050565b6000604051905090565b600067ffffffffffffffff8211156103085761030761040e565b5b6103118261043d565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b82818337600083830152505050565b60005b8381101561036757808201518184015260208101905061034c565b83811115610376576000848401525b50505050565b6000600282049050600182168061039457607f821691505b602082108114156103a8576103a76103df565b5b50919050565b6103b78261043d565b810181811067ffffffffffffffff821117156103d6576103d561040e565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f830116905091905056fea264697066735822122070d157c4efbb3fba4a1bde43cbba5b92b69f2fc455a650c0dfb61e9ed3d4bd6364736f6c634300080400330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b696e697469616c5f6d7367000000000000000000000000000000000000000000',
119+
from: '0x81cb089c285e5ee3a7353704fb114955037443af',
120+
value: 1,
121+
};
122+
web3Mock.onPost('contracts/call', { ...callData, estimate: true }).reply(200, { result: `0x61A80` });
123+
124+
const gas = await ethImpl.estimateGas({ ...callData, value: ONE_TINYBAR_IN_WEI_HEX }, null);
125+
expect((gas as string).toLowerCase()).to.equal(numberTo0x(constants.TX_DEFAULT_GAS_DEFAULT).toLowerCase());
126+
});
127+
116128
it('should eth_estimateGas contract call returns default', async function () {
117129
const gas = await ethImpl.estimateGas({ data: '0x01' }, null);
118130
expect(gas).to.equal(numberTo0x(constants.TX_DEFAULT_GAS_DEFAULT));

packages/server/tests/acceptance/rpc_batch3.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import { CacheService } from '../../../relay/src/lib/services/cacheService/cache
5454
import { CommonService } from '../../../relay/src/lib/services/ethService';
5555
import * as chai from 'chai';
5656
import chaiExclude from 'chai-exclude';
57+
import Constants from '@hashgraph/json-rpc-relay/dist/lib/constants';
5758

5859
chai.use(chaiExclude);
5960

@@ -92,6 +93,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () {
9293
'0x0000000000000000000000000000000000000000000000000000000000000000',
9394
'0x000000000000000000000000000000000000000000000000000000000000042d',
9495
];
96+
const ONE_THOUSAND_TINYBARS = Utils.add0xPrefix(Utils.toHex(Constants.TINYBAR_TO_WEIBAR_COEF * 1000));
9597

9698
beforeEach(async () => {
9799
requestId = Utils.generateRequestId();
@@ -484,7 +486,7 @@ describe('@api-batch-3 RPC Server Acceptance Tests', function () {
484486
const callData = {
485487
...defaultCallData,
486488
data: '0xddf363d7',
487-
value: '0x3e8',
489+
value: ONE_THOUSAND_TINYBARS,
488490
};
489491

490492
const res = await relay.call(RelayCall.ETH_ENDPOINTS.ETH_CALL, [callData, 'latest'], requestId);

0 commit comments

Comments
 (0)