Skip to content

Commit 6ab9709

Browse files
authored
Expand eth_call validation to support blockParam object (#817) (#823)
Expand `eth_call` validation to support `blockParam` object, introduced with [EIP-1898](https://eips.ethereum.org/EIPS/eip-1898). The Graph is passing blockHash as parameter and currently validations only accepts `blockNumber` or `tag`. More info can be found in this issue from this [comment](https://github.com/hashgraph/hedera-json-rpc-relay/issues/626#issuecomment-1383554578) onwards. Fix some minor intermittent bugs in ERC20 tests. Bump network images to `0.33.2` and mirror-node images to `0.72.0`. Signed-off-by: georgi-l95 <[email protected]> Signed-off-by: georgi-l95 <[email protected]>
1 parent 5ed5468 commit 6ab9709

File tree

13 files changed

+331
-1028
lines changed

13 files changed

+331
-1028
lines changed

package-lock.json

Lines changed: 117 additions & 999 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"check:node": "ts-node packages/server/tests/helpers/nodeCheck.ts"
4747
},
4848
"dependencies": {
49-
"@hashgraph/hedera-local": "^2.4.1",
49+
"@hashgraph/hedera-local": "^2.4.3",
5050
"@open-rpc/schema-utils-js": "^1.16.1",
5151
"@types/find-config": "^1.0.1",
5252
"keyv-file": "^0.2.0",

packages/relay/src/lib/eth.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,7 @@ export class EthImpl implements Eth {
10501050

10511051
return new Transaction({
10521052
accessList: undefined, // we don't support access lists, so punt for now
1053-
blockHash: contractResult.block_hash.substring(0, 66),
1053+
blockHash: EthImpl.toHash32(contractResult.block_hash),
10541054
blockNumber: EthImpl.numberTo0x(contractResult.block_number),
10551055
chainId: contractResult.chain_id,
10561056
from: fromAddress,
@@ -1237,7 +1237,7 @@ export class EthImpl implements Eth {
12371237
}
12381238
}
12391239

1240-
const blockHash = blockResponse.hash.substring(0, 66);
1240+
const blockHash = EthImpl.toHash32(blockResponse.hash);
12411241
const transactionArray = showDetails ? transactionObjects : transactionHashes;
12421242
return new Block({
12431243
baseFeePerGas: await this.gasPrice(requestId),
@@ -1327,7 +1327,7 @@ export class EthImpl implements Eth {
13271327
const sSig = contractResultDetails.s === null ? null : contractResultDetails.s.substring(0, 66);
13281328
return new Transaction({
13291329
accessList: undefined, // we don't support access lists for now, so punt
1330-
blockHash: contractResultDetails.block_hash.substring(0, 66),
1330+
blockHash: EthImpl.toHash32(contractResultDetails.block_hash),
13311331
blockNumber: EthImpl.numberTo0x(contractResultDetails.block_number),
13321332
chainId: contractResultDetails.chain_id,
13331333
from: contractResultDetails.from.substring(0, 42),

packages/server/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
"pino-pretty": "^7.6.1"
2121
},
2222
"devDependencies": {
23-
"@hashgraph/hedera-local": "^2.1.3",
24-
"@hashgraph/sdk": "^2.19.0",
23+
"@hashgraph/hedera-local": "^2.4.3",
24+
"@hashgraph/sdk": "^2.19.2",
2525
"@koa/cors": "^3.1.0",
2626
"@types/chai": "^4.3.0",
2727
"@types/cors": "^2.8.12",

packages/server/src/validator/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export const DEFAULT_HEX_ERROR = 'Expected 0x prefixed hexadecimal value';
44
export const HASH_ERROR = '0x prefixed string representing the hash (32 bytes)';
55
export const ADDRESS_ERROR = 'Expected 0x prefixed string representing the address (20 bytes)';
66
export const BLOCK_NUMBER_ERROR = 'Expected 0x prefixed hexadecimal block number, or the string "latest", "earliest" or "pending"';
7+
export const BLOCK_PARAMS_ERROR = `Expected ${HASH_ERROR} in object, 0x prefixed hexadecimal block number, or the string "latest", "earliest" or "pending`;
78
export const BLOCK_HASH_ERROR = `Expected ${HASH_ERROR} of a block`;
89
export const TRANSACTION_HASH_ERROR = `Expected ${HASH_ERROR} of a transaction`;
910
export const TOPIC_HASH_ERROR = `Expected ${HASH_ERROR} of a topic`;

packages/server/src/validator/methods.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export const METHODS = {
6565
},
6666
1: {
6767
required: true,
68-
type: 'blockNumber'
68+
type: 'blockParams'
6969
}
7070
},
7171
"eth_sendRawTransaction": {

packages/server/src/validator/objectTypes.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@ import { Validator } from ".";
22
import { predefined } from '@hashgraph/json-rpc-relay';
33

44
export const OBJECTS_VALIDATIONS = {
5+
"blockHashObject": {
6+
"blockHash": {
7+
type: "blockHash"
8+
}
9+
},
10+
"blockNumberObject": {
11+
"blockNumber": {
12+
type: "blockNumber"
13+
}
14+
},
515
"filter": {
616
"blockHash": {
717
type: "blockHash"
@@ -118,3 +128,38 @@ export class FilterObject {
118128
return this.constructor.name;
119129
}
120130
};
131+
132+
export class BlockHashObject {
133+
blockHash: string;
134+
135+
constructor (param: any) {
136+
Validator.hasUnexpectedParams(param, OBJECTS_VALIDATIONS.blockHashObject, this.name());
137+
this.blockHash = param.blockHash;
138+
}
139+
140+
validate() {
141+
return Validator.validateObject(this, OBJECTS_VALIDATIONS.blockHashObject);
142+
}
143+
144+
name() {
145+
return this.constructor.name;
146+
}
147+
};
148+
149+
export class BlockNumberObject {
150+
blockNumber: string;
151+
152+
constructor (param: any) {
153+
Validator.hasUnexpectedParams(param, OBJECTS_VALIDATIONS.blockNumberObject, this.name());
154+
this.blockNumber = param.blockNumber;
155+
}
156+
157+
validate() {
158+
return Validator.validateObject(this, OBJECTS_VALIDATIONS.blockNumberObject);
159+
}
160+
161+
name() {
162+
return this.constructor.name;
163+
}
164+
};
165+

packages/server/src/validator/types.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,25 @@ export const TYPES = {
2323
error: Constants.BLOCK_HASH_ERROR
2424
},
2525
'blockNumber': {
26-
test: (param: string) => /^0[xX]([1-9A-Fa-f]+[0-9A-Fa-f]{0,13}|0)$/.test(param) && Number.MAX_SAFE_INTEGER >= Number(param) || ["earliest", "latest", "pending"].includes(param),
26+
test: (param: string) => /^0[xX]([1-9A-Fa-f][0-9A-Fa-f]{0,13}|0)$/.test(param) && Number.MAX_SAFE_INTEGER >= Number(param) || ["earliest", "latest", "pending"].includes(param),
2727
error: Constants.BLOCK_NUMBER_ERROR
2828
},
2929
'boolean': {
3030
test: (param: boolean) => param === true || param === false,
3131
error: 'Expected boolean type'
3232
},
33+
'blockParams': {
34+
test: (param: any) => {
35+
if(Object.prototype.toString.call(param) === "[object Object]") {
36+
if (param.hasOwnProperty('blockHash')) {
37+
return new Validator.BlockHashObject(param).validate();
38+
}
39+
return new Validator.BlockNumberObject(param).validate();
40+
}
41+
return /^0[xX]([1-9A-Fa-f]+[0-9A-Fa-f]{0,13}|0)$/.test(param) && Number.MAX_SAFE_INTEGER >= Number(param) || ["earliest", "latest", "pending"].includes(param)
42+
},
43+
error: Constants.BLOCK_PARAMS_ERROR
44+
},
3345
"filter": {
3446
test: (param: any) => {
3547
if(Object.prototype.toString.call(param) === "[object Object]") {

packages/server/tests/acceptance/erc20.spec.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,10 @@ describe('@erc20 Acceptance Tests', async function () {
171171
});
172172

173173
it('emits a transfer event', async function () {
174-
await expect(tx)
175-
.to.emit(contract, 'Transfer')
176-
.withArgs(tokenOwnerWallet.address, toWallet.address, amount);
174+
const transferEvent = (await tx.wait()).events.filter(e => e.event === 'Transfer')[0].args;
175+
expect(transferEvent.from).to.eq(tokenOwnerWallet.address);
176+
expect(transferEvent.to).to.eq(toWallet.address);
177+
expect(transferEvent.value).to.eq(amount);
177178
});
178179

179180
it ('other account transfers tokens back to owner', async function () {
@@ -194,9 +195,10 @@ describe('@erc20 Acceptance Tests', async function () {
194195

195196
it('emits an approval event', async function () {
196197
const allowance = await contract.allowance(tokenOwner, spender);
197-
await expect(tx)
198-
.to.emit(contract, 'Approval')
199-
.withArgs(tokenOwnerWallet.address, spenderWallet.address, allowance);
198+
const approvalEvent = (await tx.wait()).events.filter(e => e.event === 'Approval')[0].args;
199+
expect(approvalEvent.owner).to.eq(tokenOwnerWallet.address);
200+
expect(approvalEvent.spender).to.eq(spenderWallet.address);
201+
expect(approvalEvent.value).to.eq(allowance);
200202
});
201203

202204
describe('when the token owner has enough balance', function () {
@@ -224,9 +226,10 @@ describe('@erc20 Acceptance Tests', async function () {
224226
});
225227

226228
it('emits a transfer event', async function () {
227-
await expect(tx)
228-
.to.emit(contract, 'Transfer')
229-
.withArgs(tokenOwnerWallet.address, toWallet.address, amount);
229+
const transferEvent = (await tx.wait()).events.filter(e => e.event === 'Transfer')[0].args;
230+
expect(transferEvent.from).to.eq(tokenOwnerWallet.address);
231+
expect(transferEvent.to).to.eq(toWallet.address);
232+
expect(transferEvent.value).to.eq(amount);
230233
});
231234
});
232235

@@ -360,9 +363,8 @@ describe('@erc20 Acceptance Tests', async function () {
360363
await servicesNode.associateHTSToken(account.accountId, htsResult.receipt.tokenId, account.privateKey, htsResult.client, requestId);
361364
await servicesNode.approveHTSToken(account.accountId, htsResult.receipt.tokenId, htsResult.client, requestId);
362365
}
363-
364366
// Setup initial balance of token owner account
365-
await servicesNode.transferHTSToken(accounts[0].accountId, htsResult.receipt.tokenId, initialSupply, htsResult.client, requestId);
367+
await servicesNode.transferHTSToken(accounts[0].accountId, htsResult.receipt.tokenId, initialSupply, htsResult.client.operatorAccountId, requestId);
366368
const evmAddress = Utils.idToEvmAddress(htsResult.receipt.tokenId.toString());
367369
return new ethers.Contract(evmAddress, abi, accounts[0].wallet);
368370
};

packages/server/tests/acceptance/index.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,9 @@ describe('RPC Server Acceptance Tests', function () {
125125

126126
function runLocalHederaNetwork() {
127127
// set env variables for docker images until local-node is updated
128-
process.env['NETWORK_NODE_IMAGE_TAG'] = '0.32.0';
129-
process.env['HAVEGED_IMAGE_TAG'] = '0.32.0';
130-
process.env['MIRROR_IMAGE_TAG'] = '0.70.1';
128+
process.env['NETWORK_NODE_IMAGE_TAG'] = '0.33.2';
129+
process.env['HAVEGED_IMAGE_TAG'] = '0.33.2';
130+
process.env['MIRROR_IMAGE_TAG'] = '0.72.0';
131131

132132
console.log(`Docker container versions, services: ${process.env['NETWORK_NODE_IMAGE_TAG']}, mirror: ${process.env['MIRROR_IMAGE_TAG']}`);
133133

0 commit comments

Comments
 (0)