Skip to content

Commit

Permalink
Merge ec5eb3d into 4b403c9
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivo-Yankov authored Aug 10, 2022
2 parents 4b403c9 + ec5eb3d commit f19619f
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 57 deletions.
29 changes: 11 additions & 18 deletions packages/relay/src/lib/eth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export class EthImpl implements Eth {
static ethGetTransactionCount = 'eth_getTransactionCount';
static ethSendRawTransaction = 'eth_sendRawTransaction';

// block constants
// block constants
static blockLatest = 'latest';
static blockEarliest = 'earliest';
static blockPending = 'pending';
Expand Down Expand Up @@ -446,7 +446,7 @@ export class EthImpl implements Eth {
}

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

if (contractResult?.results?.length > 0) {
// retrieve the contract result details
// retrieve the contract result details
await this.mirrorNodeClient.getContractResultsDetails(address, contractResult.results[0].timestamp)
.then( contractResultDetails => {
if(contractResultDetails && contractResultDetails.state_changes) {
Expand All @@ -477,7 +477,7 @@ export class EthImpl implements Eth {
e,
`${requestIdPrefix} Failed to retrieve contract result details for contract address ${address} at timestamp=${contractResult.results[0].timestamp}`,
);
throw e;
throw e;
});
}

Expand Down Expand Up @@ -975,27 +975,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 },undefined, requestId);
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, requestId);
Expand Down Expand Up @@ -1037,7 +1030,7 @@ export class EthImpl implements Eth {
}

/**
* returns the block response
* returns the block response
* otherwise return undefined.
*
* @param blockNumberOrTag
Expand All @@ -1046,7 +1039,7 @@ export class EthImpl implements Eth {
private async getHistoricalBlockResponse(blockNumberOrTag?: string | null, returnLatest?: boolean): Promise<any | null> {
let blockResponse: any;
// Determine if the latest block should be returned and if not then just return null
if (!returnLatest &&
if (!returnLatest &&
(blockNumberOrTag == null || blockNumberOrTag === EthImpl.blockLatest || blockNumberOrTag === EthImpl.blockPending)) {
return null;
}
Expand All @@ -1064,7 +1057,7 @@ export class EthImpl implements Eth {
blockResponse = await this.mirrorNodeClient.getBlock(blockNumberOrTag);
}
if (_.isNil(blockResponse) || blockResponse.hash === undefined) {
// block not found.
// block not found.
throw predefined.RESOURCE_NOT_FOUND;
}

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

0 comments on commit f19619f

Please sign in to comment.