Skip to content

Commit 76b75e8

Browse files
authored
Resolve issues with some fields in eth_getBlock (#432)
* fix: resolve issues with block fields Signed-off-by: Ivo Yankov <[email protected]> * fix: getBlock return correct value of gasUsed Signed-off-by: Ivo Yankov <[email protected]>
1 parent 6316fe7 commit 76b75e8

File tree

4 files changed

+37
-57
lines changed

4 files changed

+37
-57
lines changed

packages/relay/src/lib/eth.ts

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export class EthImpl implements Eth {
6969
static ethGetTransactionCount = 'eth_getTransactionCount';
7070
static ethSendRawTransaction = 'eth_sendRawTransaction';
7171

72-
// block constants
72+
// block constants
7373
static blockLatest = 'latest';
7474
static blockEarliest = 'earliest';
7575
static blockPending = 'pending';
@@ -446,7 +446,7 @@ export class EthImpl implements Eth {
446446
}
447447

448448
/**
449-
* Gets the value from a storage position at the given Ethereum address.
449+
* Gets the value from a storage position at the given Ethereum address.
450450
*
451451
* @param address
452452
* @param slot
@@ -460,7 +460,7 @@ export class EthImpl implements Eth {
460460
const contractResult = await this.mirrorNodeClient.getLatestContractResultsByAddress(address, blockEndTimestamp, 1);
461461

462462
if (contractResult?.results?.length > 0) {
463-
// retrieve the contract result details
463+
// retrieve the contract result details
464464
await this.mirrorNodeClient.getContractResultsDetails(address, contractResult.results[0].timestamp)
465465
.then( contractResultDetails => {
466466
if(contractResultDetails && contractResultDetails.state_changes) {
@@ -477,7 +477,7 @@ export class EthImpl implements Eth {
477477
e,
478478
`${requestIdPrefix} Failed to retrieve contract result details for contract address ${address} at timestamp=${contractResult.results[0].timestamp}`,
479479
);
480-
throw e;
480+
throw e;
481481
});
482482
}
483483

@@ -975,27 +975,20 @@ export class EthImpl implements Eth {
975975
const timestampRange = blockResponse.timestamp;
976976
const timestampRangeParams = [`gte:${timestampRange.from}`, `lte:${timestampRange.to}`];
977977
const contractResults = await this.mirrorNodeClient.getContractResults({ timestamp: timestampRangeParams },undefined, requestId);
978+
const maxGasLimit = constants.BLOCK_GAS_LIMIT;
979+
const gasUsed = blockResponse.gas_used;
978980

979981
if (contractResults === null || contractResults.results === undefined) {
980982
// contract result not found
981983
return null;
982984
}
983985

984-
// loop over contract function results to calculated aggregated datapoints
985-
let gasUsed = 0;
986-
let maxGasLimit = 0;
987-
let timestamp = 0;
986+
// The consensus timestamp of the block, with the nanoseconds part omitted.
987+
const timestamp = timestampRange.from.substring(0, timestampRange.from.indexOf('.'));
988988
const transactionObjects: Transaction[] = [];
989989
const transactionHashes: string[] = [];
990990

991991
for (const result of contractResults.results) {
992-
maxGasLimit = result.gas_limit > maxGasLimit ? result.gas_limit : maxGasLimit;
993-
gasUsed += result.gas_used;
994-
if (timestamp === 0) {
995-
// The consensus timestamp of the first transaction in the block, with the nanoseconds part omitted.
996-
timestamp = result.timestamp.substring(0, result.timestamp.indexOf('.')); // mirrorNode response assures format of ssssssssss.nnnnnnnnn
997-
}
998-
999992
// depending on stage of contract execution revert the result.to value may be null
1000993
if (!_.isNil(result.to)) {
1001994
const transaction = await this.getTransactionFromContractResult(result.to, result.timestamp, requestId);
@@ -1037,7 +1030,7 @@ export class EthImpl implements Eth {
10371030
}
10381031

10391032
/**
1040-
* returns the block response
1033+
* returns the block response
10411034
* otherwise return undefined.
10421035
*
10431036
* @param blockNumberOrTag
@@ -1046,7 +1039,7 @@ export class EthImpl implements Eth {
10461039
private async getHistoricalBlockResponse(blockNumberOrTag?: string | null, returnLatest?: boolean): Promise<any | null> {
10471040
let blockResponse: any;
10481041
// Determine if the latest block should be returned and if not then just return null
1049-
if (!returnLatest &&
1042+
if (!returnLatest &&
10501043
(blockNumberOrTag == null || blockNumberOrTag === EthImpl.blockLatest || blockNumberOrTag === EthImpl.blockPending)) {
10511044
return null;
10521045
}
@@ -1064,7 +1057,7 @@ export class EthImpl implements Eth {
10641057
blockResponse = await this.mirrorNodeClient.getBlock(blockNumberOrTag);
10651058
}
10661059
if (_.isNil(blockResponse) || blockResponse.hash === undefined) {
1067-
// block not found.
1060+
// block not found.
10681061
throw predefined.RESOURCE_NOT_FOUND;
10691062
}
10701063

packages/relay/tests/helpers.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,9 @@ export const defaultBlock = {
133133
'timestamp': {
134134
'from': '1651560386.060890949',
135135
'to': '1651560389.060890949'
136-
}
136+
},
137+
'gas_used': gasUsed1 + gasUsed2,
138+
'logs_bloom': '0x'
137139
};
138140
export const defaultContractResults = {
139141
'results': [

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

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const validateHash = (hash: string, len?: number) => {
5454
};
5555

5656
const verifyBlockConstants = (block: Block) => {
57+
expect(block.gasLimit).equal(EthImpl.numberTo0x(15000000));
5758
expect(block.baseFeePerGas).equal('0x84b6a5c400');
5859
expect(block.difficulty).equal(EthImpl.zeroHex);
5960
expect(block.extraData).equal(EthImpl.emptyHex);
@@ -115,7 +116,9 @@ describe('Eth calls using MirrorNode', async function () {
115116
const gasUsed2 = 800000;
116117
const maxGasLimit = 250000;
117118
const maxGasLimitHex = EthImpl.numberTo0x(maxGasLimit);
118-
const contractCallData = "0xef641f44"
119+
const contractCallData = "0xef641f44";
120+
const blockTimestamp = '1651560386';
121+
const blockTimestampHex = EthImpl.numberTo0x(Number(blockTimestamp));
119122
const firstTransactionTimestampSeconds = '1653077547';
120123
const firstTransactionTimestampSecondsHex = EthImpl.numberTo0x(Number(firstTransactionTimestampSeconds));
121124
const contractAddress1 = '0x000000000000000000000000000000000000055f';
@@ -134,16 +137,18 @@ describe('Eth calls using MirrorNode', async function () {
134137

135138
const defaultBlock = {
136139
'count': blockTransactionCount,
137-
'hapi_version': '0.27.0',
140+
'hapi_version': '0.28.1',
138141
'hash': blockHash,
139142
'name': '2022-05-03T06_46_26.060890949Z.rcd',
140143
'number': blockNumber,
141144
'previous_hash': '0xf7d6481f659c866c35391ee230c374f163642ebf13a5e604e04a95a9ca48a298dc2dfa10f51bcbaab8ae23bc6d662a0b',
142145
'size': null,
143146
'timestamp': {
144-
'from': '1651560386.060890949',
147+
'from': `${blockTimestamp}.060890949`,
145148
'to': '1651560389.060890949'
146-
}
149+
},
150+
'gas_used': gasUsed1 + gasUsed2,
151+
'logs_bloom': '0x'
147152
};
148153

149154

@@ -435,10 +440,9 @@ describe('Eth calls using MirrorNode', async function () {
435440
// verify aggregated info
436441
expect(result.hash).equal(blockHashTrimmed);
437442
expect(result.gasUsed).equal(totalGasUsed);
438-
expect(result.gasLimit).equal(maxGasLimitHex);
439443
expect(result.number).equal(blockNumberHex);
440444
expect(result.parentHash).equal(blockHashPreviousTrimmed);
441-
expect(result.timestamp).equal(firstTransactionTimestampSecondsHex);
445+
expect(result.timestamp).equal(blockTimestampHex);
442446
expect(result.transactions.length).equal(2);
443447
expect((result.transactions[0] as string)).equal(contractHash1);
444448
expect((result.transactions[1] as string)).equal(contractHash1);
@@ -449,7 +453,7 @@ describe('Eth calls using MirrorNode', async function () {
449453

450454
it('eth_getBlockByNumber with zero transactions', async function () {
451455
// mirror node request mocks
452-
mock.onGet(`blocks/${blockNumber}`).reply(200, defaultBlock);
456+
mock.onGet(`blocks/${blockNumber}`).reply(200, {...defaultBlock, gas_used: 0});
453457
mock.onGet(`contracts/results?timestamp=gte:${defaultBlock.timestamp.from}&timestamp=lte:${defaultBlock.timestamp.to}`).reply(200, { 'results': [] });
454458
mock.onGet('network/fees').reply(200, defaultNetworkFees);
455459
const result = await ethImpl.getBlockByNumber(EthImpl.numberTo0x(blockNumber), false);
@@ -459,10 +463,9 @@ describe('Eth calls using MirrorNode', async function () {
459463
// verify aggregated info
460464
expect(result.hash).equal(blockHashTrimmed);
461465
expect(result.gasUsed).equal('0x0');
462-
expect(result.gasLimit).equal('0x0');
463466
expect(result.number).equal(blockNumberHex);
464467
expect(result.parentHash).equal(blockHashPreviousTrimmed);
465-
expect(result.timestamp).equal('0x0');
468+
expect(result.timestamp).equal(blockTimestampHex);
466469
expect(result.transactions.length).equal(0);
467470
expect(result.transactionsRoot).equal(EthImpl.ethEmptyTrie);
468471

@@ -484,10 +487,9 @@ describe('Eth calls using MirrorNode', async function () {
484487
// verify aggregated info
485488
expect(result.hash).equal(blockHashTrimmed);
486489
expect(result.gasUsed).equal(totalGasUsed);
487-
expect(result.gasLimit).equal(maxGasLimitHex);
488490
expect(result.number).equal(blockNumberHex);
489491
expect(result.parentHash).equal(blockHashPreviousTrimmed);
490-
expect(result.timestamp).equal(firstTransactionTimestampSecondsHex);
492+
expect(result.timestamp).equal(blockTimestampHex);
491493
expect(result.transactions.length).equal(2);
492494
expect((result.transactions[0] as Transaction).hash).equal(contractHash1);
493495
expect((result.transactions[1] as Transaction).hash).equal(contractHash1);
@@ -498,7 +500,7 @@ describe('Eth calls using MirrorNode', async function () {
498500

499501
it('eth_getBlockByNumber with block match and contract revert', async function () {
500502
// mirror node request mocks
501-
mock.onGet(`blocks/${blockNumber}`).reply(200, defaultBlock);
503+
mock.onGet(`blocks/${blockNumber}`).reply(200, {...defaultBlock, gas_used: gasUsed1});
502504
mock.onGet(`contracts/results?timestamp=gte:${defaultBlock.timestamp.from}&timestamp=lte:${defaultBlock.timestamp.to}`).reply(200, defaultContractResultsRevert);
503505
mock.onGet('network/fees').reply(200, defaultNetworkFees);
504506

@@ -509,10 +511,9 @@ describe('Eth calls using MirrorNode', async function () {
509511
// verify aggregated info
510512
expect(result.hash).equal(blockHashTrimmed);
511513
expect(result.gasUsed).equal(EthImpl.numberTo0x(gasUsed1));
512-
expect(result.gasLimit).equal(maxGasLimitHex);
513514
expect(result.number).equal(blockNumberHex);
514515
expect(result.parentHash).equal(blockHashPreviousTrimmed);
515-
expect(result.timestamp).equal(firstTransactionTimestampSecondsHex);
516+
expect(result.timestamp).equal(blockTimestampHex);
516517
expect(result.transactions.length).equal(0);
517518

518519
// verify expected constants
@@ -598,10 +599,9 @@ describe('Eth calls using MirrorNode', async function () {
598599
// verify aggregated info
599600
expect(result.hash).equal(blockHashTrimmed);
600601
expect(result.gasUsed).equal(totalGasUsed);
601-
expect(result.gasLimit).equal(maxGasLimitHex);
602602
expect(result.number).equal(blockNumberHex);
603603
expect(result.parentHash).equal(blockHashPreviousTrimmed);
604-
expect(result.timestamp).equal(firstTransactionTimestampSecondsHex);
604+
expect(result.timestamp).equal(blockTimestampHex);
605605
expect(result.transactions.length).equal(2);
606606
expect((result.transactions[0] as string)).equal(contractHash1);
607607
expect((result.transactions[1] as string)).equal(contractHash1);
@@ -625,10 +625,9 @@ describe('Eth calls using MirrorNode', async function () {
625625
// verify aggregated info
626626
expect(result.hash).equal(blockHashTrimmed);
627627
expect(result.gasUsed).equal(totalGasUsed);
628-
expect(result.gasLimit).equal(maxGasLimitHex);
629628
expect(result.number).equal(blockNumberHex);
630629
expect(result.parentHash).equal(blockHashPreviousTrimmed);
631-
expect(result.timestamp).equal(firstTransactionTimestampSecondsHex);
630+
expect(result.timestamp).equal(blockTimestampHex);
632631
expect(result.transactions.length).equal(2);
633632
expect((result.transactions[0] as Transaction).hash).equal(contractHash1);
634633
expect((result.transactions[1] as Transaction).hash).equal(contractHash1);
@@ -639,7 +638,7 @@ describe('Eth calls using MirrorNode', async function () {
639638

640639
it('eth_getBlockByHash with block match and contract revert', async function () {
641640
// mirror node request mocks
642-
mock.onGet(`blocks/${blockHash}`).reply(200, defaultBlock);
641+
mock.onGet(`blocks/${blockHash}`).reply(200, {...defaultBlock, gas_used: gasUsed1});
643642
mock.onGet(`contracts/results?timestamp=gte:${defaultBlock.timestamp.from}&timestamp=lte:${defaultBlock.timestamp.to}`).reply(200, defaultContractResultsRevert);
644643
mock.onGet('network/fees').reply(200, defaultNetworkFees);
645644

@@ -650,10 +649,9 @@ describe('Eth calls using MirrorNode', async function () {
650649
// verify aggregated info
651650
expect(result.hash).equal(blockHashTrimmed);
652651
expect(result.gasUsed).equal(EthImpl.numberTo0x(gasUsed1));
653-
expect(result.gasLimit).equal(maxGasLimitHex);
654652
expect(result.number).equal(blockNumberHex);
655653
expect(result.parentHash).equal(blockHashPreviousTrimmed);
656-
expect(result.timestamp).equal(firstTransactionTimestampSecondsHex);
654+
expect(result.timestamp).equal(blockTimestampHex);
657655
expect(result.transactions.length).equal(0);
658656

659657
// verify expected constants

packages/server/tests/helpers/assertions.ts

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export default class Assertions {
3232
static defaultGasPrice = 720_000_000_000;
3333
static datedGasPrice = 570_000_000_000;
3434
static updatedGasPrice = 640_000_000_000;
35+
static maxBlockGasLimit = 15_000_000;
3536
static defaultGasUsed = 0.5;
3637

3738
static assertId = (id) => {
@@ -80,30 +81,16 @@ export default class Assertions {
8081
expect(relayResponse.uncles).to.be.exist;
8182
expect(relayResponse.uncles.length).to.eq(0);
8283
expect(relayResponse.logsBloom).to.eq(Assertions.emptyBloom);
84+
expect(relayResponse.gasLimit).to.equal(ethers.utils.hexValue(Assertions.maxBlockGasLimit));
8385

8486
// Assert dynamic values
8587
expect(relayResponse.hash).to.be.equal(mirrorNodeResponse.hash.slice(0, 66));
8688
expect(relayResponse.number).to.be.equal(ethers.utils.hexValue(mirrorNodeResponse.number));
8789
expect(relayResponse.transactions.length).to.equal(mirrorTransactions.length);
8890
expect(relayResponse.parentHash).to.equal(mirrorNodeResponse.previous_hash.slice(0, 66));
8991
expect(relayResponse.size).to.equal(ethers.utils.hexValue(mirrorNodeResponse.size | 0));
90-
91-
let maxGasLimit = 0;
92-
let gasUsed = 0;
93-
let timestamp = 0;
94-
95-
for (const result of mirrorTransactions) {
96-
maxGasLimit = result.gas_limit > maxGasLimit ? result.gas_limit : maxGasLimit;
97-
gasUsed += result.gas_used;
98-
if (timestamp === 0) {
99-
timestamp = result.timestamp.substring(0, result.timestamp.indexOf('.'));
100-
}
101-
}
102-
103-
expect(relayResponse.gasLimit).to.equal(ethers.utils.hexValue(maxGasLimit));
104-
expect(relayResponse.gasUsed).to.equal(ethers.utils.hexValue(gasUsed));
105-
expect(relayResponse.timestamp).to.equal(ethers.utils.hexValue(Number(timestamp)));
106-
92+
expect(relayResponse.gasUsed).to.equal(ethers.utils.hexValue(mirrorNodeResponse.gas_used));
93+
expect(relayResponse.timestamp).to.equal(ethers.utils.hexValue(Number(mirrorNodeResponse.timestamp.from.split('.')[0])));
10794
if (relayResponse.transactions.length) {
10895
expect(relayResponse.transactionsRoot).to.equal(mirrorNodeResponse.hash.slice(0, 66));
10996
}

0 commit comments

Comments
 (0)