Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: cherry picked 2489 #2514

Merged
merged 1 commit into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/relay/src/formatters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ const formatContractResult = (cr: any) => {
const commonFields = {
blockHash: toHash32(cr.block_hash),
blockNumber: nullableNumberTo0x(cr.block_number),
chainId: cr.chain_id,
from: cr.from.substring(0, 42),
gas: nanOrNumberTo0x(cr.gas_used),
gasPrice: toNullIfEmptyHex(cr.gas_price),
Expand All @@ -161,6 +160,10 @@ const formatContractResult = (cr: any) => {
type: nullableNumberTo0x(cr.type),
v: cr.type === null ? null : nanOrNumberTo0x(cr.v),
value: nanOrNumberTo0x(cr.amount),
// for legacy EIP155 with tx.chainId=0x0, mirror-node will return a '0x' (EMPTY_HEX) value for contract result's chain_id
// which is incompatibile with certain tools (i.e. foundry). By setting this field, chainId, to undefined, the end jsonrpc
// object will leave out this field, which is the proper behavior for other tools to be compatible with.
chainId: cr.chain_id === EMPTY_HEX ? undefined : cr.chain_id,
};

switch (cr.type) {
Expand Down
5 changes: 5 additions & 0 deletions packages/relay/tests/lib/formatters.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,11 @@ describe('Formatters', () => {
expect(formattedResult.yParity).to.equal('0x0');
expect(formattedResult.value).to.equal('0x0');
});

it('Should not include chainId field for legacy EIP155 transaction (tx.chainId=0x0)', () => {
const formattedResult: any = formatContractResult({ ...contractResult, chain_id: '0x' });
expect(formattedResult.chainId).to.be.undefined;
});
});

describe('prepend0x', () => {
Expand Down
20 changes: 20 additions & 0 deletions packages/server/tests/acceptance/rpc_batch1.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,26 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () {
expect(balanceChange.toString()).to.eq(Number(ONE_TINYBAR).toString());
});

it('should return transaction result with no chainId field for legacy EIP155 transactions (with no chainId i.e. chainId=0x0)', async function () {
const transaction = {
...defaultLegacyTransactionData,
to: parentContractAddress,
nonce: await relay.getAccountNonce(accounts[1].address, requestId),
gasPrice: await relay.gasPrice(requestId),
};
const signedTx = await accounts[1].wallet.signTransaction(transaction);
const transactionHash = await relay.sendRawTransaction(signedTx, requestId);

const transactionResult = await relay.call(
RelayCalls.ETH_ENDPOINTS.ETH_GET_TRANSACTION_BY_HASH,
[transactionHash],
requestId,
);

const result = Object.prototype.hasOwnProperty.call(transactionResult, 'chainId');
expect(result).to.be.false;
});

it('should fail "eth_sendRawTransaction" for Legacy transactions (with gas price too low)', async function () {
const transaction = {
...defaultLegacyTransactionData,
Expand Down
Loading