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

Resolve issues with some fields in eth_getBlock #432

Merged
merged 3 commits into from
Aug 10, 2022
Merged
Show file tree
Hide file tree
Changes from 2 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
15 changes: 4 additions & 11 deletions packages/relay/src/lib/eth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -923,27 +923,20 @@ export class EthImpl implements Eth {
const timestampRange = blockResponse.timestamp;
const timestampRangeParams = [`gte:${timestampRange.from}`, `lte:${timestampRange.to}`];
const contractResults = await this.mirrorNodeClient.getContractResults({ timestamp: timestampRangeParams });
const maxGasLimit = constants.BLOCK_GAS_LIMIT;
const gasUsed = blockResponse.gas_used;

if (contractResults === null || contractResults.results === undefined) {
// contract result not found
return null;
}

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

for (const result of contractResults.results) {
maxGasLimit = result.gas_limit > maxGasLimit ? result.gas_limit : maxGasLimit;
gasUsed += result.gas_used;
if (timestamp === 0) {
// The consensus timestamp of the first transaction in the block, with the nanoseconds part omitted.
timestamp = result.timestamp.substring(0, result.timestamp.indexOf('.')); // mirrorNode response assures format of ssssssssss.nnnnnnnnn
}

// depending on stage of contract execution revert the result.to value may be null
if (!_.isNil(result.to)) {
const transaction = await this.getTransactionFromContractResult(result.to, result.timestamp);
Expand Down
4 changes: 3 additions & 1 deletion packages/relay/tests/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,9 @@ export const defaultBlock = {
'timestamp': {
'from': '1651560386.060890949',
'to': '1651560389.060890949'
}
},
'gas_used': gasUsed1 + gasUsed2,
'logs_bloom': '0x'
};
export const defaultContractResults = {
'results': [
Expand Down
40 changes: 19 additions & 21 deletions packages/relay/tests/lib/eth.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const validateHash = (hash: string, len?: number) => {
};

const verifyBlockConstants = (block: Block) => {
expect(block.gasLimit).equal(EthImpl.numberTo0x(15000000));
expect(block.baseFeePerGas).equal('0x84b6a5c400');
expect(block.difficulty).equal(EthImpl.zeroHex);
expect(block.extraData).equal(EthImpl.emptyHex);
Expand Down Expand Up @@ -115,7 +116,9 @@ describe('Eth calls using MirrorNode', async function () {
const gasUsed2 = 800000;
const maxGasLimit = 250000;
const maxGasLimitHex = EthImpl.numberTo0x(maxGasLimit);
const contractCallData = "0xef641f44"
const contractCallData = "0xef641f44";
const blockTimestamp = '1651560386';
const blockTimestampHex = EthImpl.numberTo0x(Number(blockTimestamp));
const firstTransactionTimestampSeconds = '1653077547';
const firstTransactionTimestampSecondsHex = EthImpl.numberTo0x(Number(firstTransactionTimestampSeconds));
const contractAddress1 = '0x000000000000000000000000000000000000055f';
Expand All @@ -134,16 +137,18 @@ describe('Eth calls using MirrorNode', async function () {

const defaultBlock = {
'count': blockTransactionCount,
'hapi_version': '0.27.0',
'hapi_version': '0.28.1',
'hash': blockHash,
'name': '2022-05-03T06_46_26.060890949Z.rcd',
'number': blockNumber,
'previous_hash': '0xf7d6481f659c866c35391ee230c374f163642ebf13a5e604e04a95a9ca48a298dc2dfa10f51bcbaab8ae23bc6d662a0b',
'size': null,
'timestamp': {
'from': '1651560386.060890949',
'from': `${blockTimestamp}.060890949`,
'to': '1651560389.060890949'
}
},
'gas_used': gasUsed1 + gasUsed2,
'logs_bloom': '0x'
};


Expand Down Expand Up @@ -435,10 +440,9 @@ describe('Eth calls using MirrorNode', async function () {
// verify aggregated info
expect(result.hash).equal(blockHashTrimmed);
expect(result.gasUsed).equal(totalGasUsed);
expect(result.gasLimit).equal(maxGasLimitHex);
expect(result.number).equal(blockNumberHex);
expect(result.parentHash).equal(blockHashPreviousTrimmed);
expect(result.timestamp).equal(firstTransactionTimestampSecondsHex);
expect(result.timestamp).equal(blockTimestampHex);
expect(result.transactions.length).equal(2);
expect((result.transactions[0] as string)).equal(contractHash1);
expect((result.transactions[1] as string)).equal(contractHash1);
Expand All @@ -449,7 +453,7 @@ describe('Eth calls using MirrorNode', async function () {

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

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

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

Expand All @@ -509,10 +511,9 @@ describe('Eth calls using MirrorNode', async function () {
// verify aggregated info
expect(result.hash).equal(blockHashTrimmed);
expect(result.gasUsed).equal(EthImpl.numberTo0x(gasUsed1));
expect(result.gasLimit).equal(maxGasLimitHex);
expect(result.number).equal(blockNumberHex);
expect(result.parentHash).equal(blockHashPreviousTrimmed);
expect(result.timestamp).equal(firstTransactionTimestampSecondsHex);
expect(result.timestamp).equal(blockTimestampHex);
expect(result.transactions.length).equal(0);

// verify expected constants
Expand Down Expand Up @@ -598,10 +599,9 @@ describe('Eth calls using MirrorNode', async function () {
// verify aggregated info
expect(result.hash).equal(blockHashTrimmed);
expect(result.gasUsed).equal(totalGasUsed);
expect(result.gasLimit).equal(maxGasLimitHex);
expect(result.number).equal(blockNumberHex);
expect(result.parentHash).equal(blockHashPreviousTrimmed);
expect(result.timestamp).equal(firstTransactionTimestampSecondsHex);
expect(result.timestamp).equal(blockTimestampHex);
expect(result.transactions.length).equal(2);
expect((result.transactions[0] as string)).equal(contractHash1);
expect((result.transactions[1] as string)).equal(contractHash1);
Expand All @@ -625,10 +625,9 @@ describe('Eth calls using MirrorNode', async function () {
// verify aggregated info
expect(result.hash).equal(blockHashTrimmed);
expect(result.gasUsed).equal(totalGasUsed);
expect(result.gasLimit).equal(maxGasLimitHex);
expect(result.number).equal(blockNumberHex);
expect(result.parentHash).equal(blockHashPreviousTrimmed);
expect(result.timestamp).equal(firstTransactionTimestampSecondsHex);
expect(result.timestamp).equal(blockTimestampHex);
expect(result.transactions.length).equal(2);
expect((result.transactions[0] as Transaction).hash).equal(contractHash1);
expect((result.transactions[1] as Transaction).hash).equal(contractHash1);
Expand All @@ -639,7 +638,7 @@ describe('Eth calls using MirrorNode', async function () {

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

Expand All @@ -650,10 +649,9 @@ describe('Eth calls using MirrorNode', async function () {
// verify aggregated info
expect(result.hash).equal(blockHashTrimmed);
expect(result.gasUsed).equal(EthImpl.numberTo0x(gasUsed1));
expect(result.gasLimit).equal(maxGasLimitHex);
expect(result.number).equal(blockNumberHex);
expect(result.parentHash).equal(blockHashPreviousTrimmed);
expect(result.timestamp).equal(firstTransactionTimestampSecondsHex);
expect(result.timestamp).equal(blockTimestampHex);
expect(result.transactions.length).equal(0);

// verify expected constants
Expand Down
21 changes: 4 additions & 17 deletions packages/server/tests/helpers/assertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export default class Assertions {
static defaultGasPrice = 720_000_000_000;
static datedGasPrice = 570_000_000_000;
static updatedGasPrice = 640_000_000_000;
static maxBlockGasLimit = 15_000_000;
static defaultGasUsed = 0.5;

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

// Assert dynamic values
expect(relayResponse.hash).to.be.equal(mirrorNodeResponse.hash.slice(0, 66));
expect(relayResponse.number).to.be.equal(ethers.utils.hexValue(mirrorNodeResponse.number));
expect(relayResponse.transactions.length).to.equal(mirrorTransactions.length);
expect(relayResponse.parentHash).to.equal(mirrorNodeResponse.previous_hash.slice(0, 66));
expect(relayResponse.size).to.equal(ethers.utils.hexValue(mirrorNodeResponse.size | 0));

let maxGasLimit = 0;
let gasUsed = 0;
let timestamp = 0;

for (const result of mirrorTransactions) {
maxGasLimit = result.gas_limit > maxGasLimit ? result.gas_limit : maxGasLimit;
gasUsed += result.gas_used;
if (timestamp === 0) {
timestamp = result.timestamp.substring(0, result.timestamp.indexOf('.'));
}
}

expect(relayResponse.gasLimit).to.equal(ethers.utils.hexValue(maxGasLimit));
expect(relayResponse.gasUsed).to.equal(ethers.utils.hexValue(gasUsed));
expect(relayResponse.timestamp).to.equal(ethers.utils.hexValue(Number(timestamp)));

expect(relayResponse.gasUsed).to.equal(ethers.utils.hexValue(mirrorNodeResponse.gas_used));
expect(relayResponse.timestamp).to.equal(ethers.utils.hexValue(Number(mirrorNodeResponse.timestamp.from.split('.')[0])));
if (relayResponse.transactions.length) {
expect(relayResponse.transactionsRoot).to.equal(mirrorNodeResponse.hash.slice(0, 66));
}
Expand Down