Skip to content

Commit fde43c6

Browse files
quiet-nodeebadiere
andauthored
chore: cherry picked 2499 (#2519)
fix: Applied fix using trimPrecedingZeros. (#2499) fix: fix for gasPrice. fix: Clean up Signed-off-by: ebadiere <[email protected]> Signed-off-by: Logan Nguyen <[email protected]> Co-authored-by: Eric Badiere <[email protected]>
1 parent 3ffc120 commit fde43c6

File tree

4 files changed

+77
-18
lines changed

4 files changed

+77
-18
lines changed

packages/relay/src/formatters.ts

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -144,21 +144,28 @@ const formatContractResult = (cr: any) => {
144144
return null;
145145
}
146146

147+
const gasPrice =
148+
cr.gas_price === null || cr.gas_price === '0x'
149+
? '0x0'
150+
: isHex(cr.gas_price)
151+
? cr.gas_price
152+
: nanOrNumberTo0x(cr.gas_price);
153+
147154
const commonFields = {
148155
blockHash: toHash32(cr.block_hash),
149156
blockNumber: nullableNumberTo0x(cr.block_number),
150157
from: cr.from.substring(0, 42),
151158
gas: nanOrNumberTo0x(cr.gas_used),
152-
gasPrice: toNullIfEmptyHex(cr.gas_price),
159+
gasPrice,
153160
hash: cr.hash.substring(0, 66),
154161
input: cr.function_parameters,
155162
nonce: nanOrNumberTo0x(cr.nonce),
156-
r: cr.r === null ? null : cr.r.substring(0, 66),
157-
s: cr.s === null ? null : cr.s.substring(0, 66),
163+
r: cr.r === null ? '0x0' : cr.r.substring(0, 66),
164+
s: cr.s === null ? '0x0' : cr.s.substring(0, 66),
158165
to: cr.to?.substring(0, 42),
159166
transactionIndex: nullableNumberTo0x(cr.transaction_index),
160-
type: nullableNumberTo0x(cr.type),
161-
v: cr.type === null ? null : nanOrNumberTo0x(cr.v),
167+
type: cr.type === null ? '0x0' : nanOrNumberTo0x(cr.type),
168+
v: cr.type === null ? '0x0' : nanOrNumberTo0x(cr.v),
162169
value: nanOrNumberTo0x(cr.amount),
163170
// for legacy EIP155 with tx.chainId=0x0, mirror-node will return a '0x' (EMPTY_HEX) value for contract result's chain_id
164171
// which is incompatibile with certain tools (i.e. foundry). By setting this field, chainId, to undefined, the end jsonrpc
@@ -178,8 +185,14 @@ const formatContractResult = (cr: any) => {
178185
return new Transaction1559({
179186
...commonFields,
180187
accessList: [],
181-
maxPriorityFeePerGas: toNullIfEmptyHex(cr.max_priority_fee_per_gas),
182-
maxFeePerGas: toNullIfEmptyHex(cr.max_fee_per_gas),
188+
maxPriorityFeePerGas:
189+
cr.max_priority_fee_per_gas === null || cr.max_priority_fee_per_gas === '0x'
190+
? '0x0'
191+
: prepend0x(trimPrecedingZeros(cr.max_priority_fee_per_gas)),
192+
maxFeePerGas:
193+
cr.max_fee_per_gas === null || cr.max_fee_per_gas === '0x'
194+
? '0x0'
195+
: prepend0x(trimPrecedingZeros(cr.max_fee_per_gas)),
183196
}); // eip 1559 fields
184197
case null:
185198
return new Transaction(commonFields); //hapi
@@ -248,6 +261,11 @@ const isValidEthereumAddress = (address: string): boolean => {
248261
return new RegExp(constants.BASE_HEX_REGEX + '{40}$').test(address);
249262
};
250263

264+
const isHex = (value: string): boolean => {
265+
const hexRegex = /^0x[0-9a-fA-F]+$/;
266+
return hexRegex.test(value);
267+
};
268+
251269
export {
252270
hashNumber,
253271
formatRequestIdMessage,
@@ -270,4 +288,5 @@ export {
270288
stringToHex,
271289
toHexString,
272290
isValidEthereumAddress,
291+
isHex,
273292
};

packages/relay/src/lib/eth.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1893,6 +1893,7 @@ export class EthImpl implements Eth {
18931893

18941894
const fromAddress = await this.resolveEvmAddress(contractResult.from, requestIdPrefix, [constants.TYPE_ACCOUNT]);
18951895
const toAddress = await this.resolveEvmAddress(contractResult.to, requestIdPrefix);
1896+
contractResult.chain_id = contractResult.chain_id || this.chain;
18961897

18971898
return formatContractResult({
18981899
...contractResult,
@@ -2149,6 +2150,7 @@ export class EthImpl implements Eth {
21492150
constants.TYPE_ACCOUNT,
21502151
]);
21512152
contractResult.to = await this.resolveEvmAddress(contractResult.to, requestIdPrefix);
2153+
contractResult.chain_id = contractResult.chain_id || this.chain;
21522154

21532155
transactionArray.push(showDetails ? formatContractResult(contractResult) : contractResult.hash);
21542156
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,22 +152,22 @@ describe('@ethGetTransactionByHash eth_getTransactionByHash tests', async functi
152152
});
153153

154154
it('returns correct transaction for existing hash w no sigs', async function () {
155-
const detailedResultsWithNullNullableValues = {
155+
const detailedResultsWithZeroXZeroValues = {
156156
...defaultDetailedContractResultByHash,
157157
r: null,
158158
s: null,
159159
};
160160

161161
const uniqueTxHash = '0x97cad7b827375d12d73af57b6a3f84353645fd31305ea58ff52dda53ec640533';
162162

163-
restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, detailedResultsWithNullNullableValues);
163+
restMock.onGet(`contracts/results/${uniqueTxHash}`).reply(200, detailedResultsWithZeroXZeroValues);
164164
const result = await ethImpl.getTransactionByHash(uniqueTxHash);
165165
RelayAssertions.assertTransaction(result, {
166166
...DEFAULT_TRANSACTION,
167167
maxFeePerGas: '0x55',
168168
maxPriorityFeePerGas: '0x43',
169-
r: null,
170-
s: null,
169+
r: '0x0',
170+
s: '0x0',
171171
});
172172
});
173173

packages/relay/tests/lib/formatters.spec.ts

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
weibarHexToTinyBarInt,
3737
isValidEthereumAddress,
3838
trimPrecedingZeros,
39+
isHex,
3940
} from '../../src/formatters';
4041
import constants from '../../src/lib/constants';
4142
import { BigNumber as BN } from 'bignumber.js';
@@ -202,10 +203,10 @@ describe('Formatters', () => {
202203
expect(formattedResult.chainId).to.equal('0x12a');
203204
expect(formattedResult.from).to.equal('0x05fba803be258049a27b820088bab1cad2058871');
204205
expect(formattedResult.gas).to.equal('0x61a80');
205-
expect(formattedResult.gasPrice).to.equal(null);
206+
expect(formattedResult.gasPrice).to.equal('0x0');
206207
expect(formattedResult.hash).to.equal('0xfc4ab7133197016293d2e14e8cf9c5227b07357e6385184f1cd1cb40d783cfbd');
207208
expect(formattedResult.input).to.equal('0x08090033');
208-
expect(formattedResult.maxPriorityFeePerGas).to.equal(null);
209+
expect(formattedResult.maxPriorityFeePerGas).to.equal('0x0');
209210
expect(formattedResult.maxFeePerGas).to.equal('0x59');
210211
expect(formattedResult.nonce).to.equal('0x2');
211212
expect(formattedResult.r).to.equal('0x2af9d41244c702764ed86c5b9f1a734b075b91c4d9c65e78bc584b0e35181e42');
@@ -238,14 +239,14 @@ describe('Formatters', () => {
238239
expect(formattedResult.chainId).to.equal('0x12a');
239240
expect(formattedResult.from).to.equal('0x05fba803be258049a27b820088bab1cad2058871');
240241
expect(formattedResult.gas).to.equal('0x0');
241-
expect(formattedResult.gasPrice).to.equal(null);
242+
expect(formattedResult.gasPrice).to.equal('0x0');
242243
expect(formattedResult.hash).to.equal('0xfc4ab7133197016293d2e14e8cf9c5227b07357e6385184f1cd1cb40d783cfbd');
243244
expect(formattedResult.input).to.equal('0x08090033');
244-
expect(formattedResult.maxPriorityFeePerGas).to.equal(null);
245-
expect(formattedResult.maxFeePerGas).to.equal(null);
245+
expect(formattedResult.maxPriorityFeePerGas).to.equal('0x0');
246+
expect(formattedResult.maxFeePerGas).to.equal('0x0');
246247
expect(formattedResult.nonce).to.equal('0x0');
247-
expect(formattedResult.r).to.equal(null);
248-
expect(formattedResult.s).to.equal(null);
248+
expect(formattedResult.r).to.equal('0x0');
249+
expect(formattedResult.s).to.equal('0x0');
249250
expect(formattedResult.to).to.equal('0x0000000000000000000000000000000000000409');
250251
expect(formattedResult.transactionIndex).to.equal(null);
251252
expect(formattedResult.v).to.equal(`0x0`);
@@ -427,4 +428,41 @@ describe('Formatters', () => {
427428
expect(isValidEthereumAddress(address)).to.equal(false);
428429
});
429430
});
431+
describe('isHex Function', () => {
432+
it('should return true for valid lowercase hexadecimal string', () => {
433+
expect(isHex('0x1a3f')).to.be.true;
434+
});
435+
436+
it('should return true for valid uppercase hexadecimal string', () => {
437+
expect(isHex('0xABC')).to.be.true;
438+
});
439+
440+
it('should return true for mixed-case hexadecimal string', () => {
441+
expect(isHex('0xAbC123')).to.be.true;
442+
});
443+
444+
it('should return false for string without 0x prefix', () => {
445+
expect(isHex('1a3f')).to.be.false;
446+
});
447+
448+
it('should return false for string with invalid characters', () => {
449+
expect(isHex('0x1g3f')).to.be.false;
450+
});
451+
452+
it('should return false for string with only 0x prefix', () => {
453+
expect(isHex('0x')).to.be.false;
454+
});
455+
456+
it('should return false for empty string', () => {
457+
expect(isHex('')).to.be.false;
458+
});
459+
460+
it('should return false for string with spaces', () => {
461+
expect(isHex('0x 1a3f')).to.be.false;
462+
});
463+
464+
it('should return true for a known gasPrice', () => {
465+
expect(isHex('0x58')).to.be.true;
466+
});
467+
});
430468
});

0 commit comments

Comments
 (0)