Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion packages/relay/src/lib/eth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ export class EthImpl implements Eth {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async estimateGas(transaction: any, _blockParam: string | null, requestId?: string) {
const requestIdPrefix = formatRequestIdMessage(requestId);
this.logger.trace(`${requestIdPrefix} estimateGas()`);
this.logger.trace(`${requestIdPrefix} estimateGas(transaction=${JSON.stringify(transaction)}, _blockParam=${_blockParam})`);
if (!transaction || !transaction.data || transaction.data === '0x') {
return EthImpl.gasTxBaseCost;
} else {
Expand Down
60 changes: 40 additions & 20 deletions packages/server/src/validator/objectTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,70 +4,90 @@ import { predefined } from '@hashgraph/json-rpc-relay';
export const OBJECTS_VALIDATIONS = {
"blockHashObject": {
"blockHash": {
type: "blockHash"
type: "blockHash",
nullable: false
}
},
"blockNumberObject": {
"blockNumber": {
type: "blockNumber"
type: "blockNumber",
nullable: false
}
},
"filter": {
"blockHash": {
type: "blockHash"
type: "blockHash",
nullable: false
},
"fromBlock": {
type: "blockNumber"
type: "blockNumber",
nullable: false
},
"toBlock": {
type: "blockNumber"
type: "blockNumber",
nullable: false
},
"address": {
type: "addressFilter"
type: "addressFilter",
nullable: false
},
"topics": {
type: "topics"
type: "topics",
nullable: false
}
},
"transaction": {
"from": {
type: "address"
type: "address",
nullable: false
},
"to": {
type: "address"
type: "address",
nullable: false
},
"gas": {
type: "hex"
type: "hex",
nullable: false
},
"gasPrice": {
type: "hex"
type: "hex",
nullable: false
},
"maxPriorityFeePerGas": {
type: "hex"
type: "hex",
nullable: false
},
"maxFeePerGas": {
type: "hex"
type: "hex",
nullable: false
},
"value": {
type: "hex"
type: "hex",
nullable: false
},
"data": {
type: "hex"
type: "hex",
nullable: true
},
"type": {
type: "hex"
type: "hex",
nullable: false
},
"chainId": {
type: "hex"
type: "hex",
nullable: false
},
"nonce": {
type: "hex"
type: "hex",
nullable: false
},
"input": {
type: "hex"
type: "hex",
nullable: false
},
"accessList": {
type: "array"
type: "array",
nullable: false
}
}
};
Expand Down
12 changes: 8 additions & 4 deletions packages/server/src/validator/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function validateParam(index: number | string, param: any, validation: an
if (param != null) {
const result = isArray? paramType.test(index, param, validation.type[1]) : paramType.test(param);
if(result === false) {
throw predefined.INVALID_PARAMETER(index, paramType.error);
throw predefined.INVALID_PARAMETER(index, `${paramType.error}, value: ${param}`);
}
}
}
Expand All @@ -31,16 +31,16 @@ export function validateObject(object: any, filters: any) {
throw predefined.MISSING_REQUIRED_PARAMETER(`'${property}' for ${object.name()}`);
}

if (param !== undefined) {
if (isValidAndNonNullableParam(param, validation.nullable)) {
try {
result = Validator.TYPES[validation.type].test(param);

if(!result) {
throw predefined.INVALID_PARAMETER(`'${property}' for ${object.name()}`, Validator.TYPES[validation.type].error);
throw predefined.INVALID_PARAMETER(`'${property}' for ${object.name()}`, `${Validator.TYPES[validation.type].error}, value: ${param}`);
}
} catch(error: any) {
if (error instanceof JsonRpcError) {
throw predefined.INVALID_PARAMETER(`'${property}' for ${object.name()}`, Validator.TYPES[validation.type].error);
throw predefined.INVALID_PARAMETER(`'${property}' for ${object.name()}`, `${Validator.TYPES[validation.type].error}, value: ${param}`);
}

throw error;
Expand Down Expand Up @@ -71,3 +71,7 @@ export function hasUnexpectedParams(actual: any, expected: any, object: string)
export function requiredIsMissing(param: any, required: boolean) {
return required && param === undefined;
}

export function isValidAndNonNullableParam(param: any, nullable: boolean) {
return param !== undefined && (param !== null || !nullable);
}
20 changes: 10 additions & 10 deletions packages/server/tests/acceptance/rpc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -961,8 +961,8 @@ describe('@api RPC Server Acceptance Tests', function () {
it('should not be able to execute "eth_estimateGas" with wrong from field', async function () {
try {
await relay.call('eth_estimateGas', [{
from: '0x114f60009ee6b84861c0cdae8829751e517bc4d7',
to: '0xae410f34f7487e2cd03396499cebb09b79f45',
from: '0x114f60009ee6b84861c0cdae8829751e517b',
to: '0xae410f34f7487e2cd03396499cebb09b79f45d6e',
value: '0xa688906bd8b00000',
gas: '0xd97010',
accessList: []
Expand All @@ -972,7 +972,7 @@ describe('@api RPC Server Acceptance Tests', function () {
const err = JSON.parse(error.body);
expect(error).to.not.be.null;
expect(err.error.name).to.be.equal('Invalid parameter');
expect(err.error.message.endsWith(`Invalid parameter 'to' for TransactionObject: Expected 0x prefixed string representing the address (20 bytes)`)).to.be.true;
expect(err.error.message.endsWith(`Invalid parameter 'from' for TransactionObject: Expected 0x prefixed string representing the address (20 bytes), value: 0x114f60009ee6b84861c0cdae8829751e517b`)).to.be.true;
}
});

Expand All @@ -990,7 +990,7 @@ describe('@api RPC Server Acceptance Tests', function () {
const err = JSON.parse(error.body);
expect(error).to.not.be.null;
expect(err.error.name).to.be.equal('Invalid parameter');
expect(err.error.message.endsWith(`Invalid parameter 'to' for TransactionObject: Expected 0x prefixed string representing the address (20 bytes)`)).to.be.true;
expect(err.error.message.endsWith(`Invalid parameter 'to' for TransactionObject: Expected 0x prefixed string representing the address (20 bytes), value: 0xae410f34f7487e2cd03396499cebb09b79f45`)).to.be.true;
}
});

Expand All @@ -1008,7 +1008,7 @@ describe('@api RPC Server Acceptance Tests', function () {
const err = JSON.parse(error.body);
expect(error).to.not.be.null;
expect(err.error.name).to.be.equal('Invalid parameter');
expect(err.error.message.endsWith(`Invalid parameter 'value' for TransactionObject: Expected 0x prefixed hexadecimal value`)).to.be.true;
expect(err.error.message.endsWith(`Invalid parameter 'value' for TransactionObject: Expected 0x prefixed hexadecimal value, value: 123`)).to.be.true;
}
});

Expand All @@ -1026,7 +1026,7 @@ describe('@api RPC Server Acceptance Tests', function () {
const err = JSON.parse(error.body);
expect(error).to.not.be.null;
expect(err.error.name).to.be.equal('Invalid parameter');
expect(err.error.message.endsWith(`Invalid parameter 'gas' for TransactionObject: Expected 0x prefixed hexadecimal value`)).to.be.true;
expect(err.error.message.endsWith(`Invalid parameter 'gas' for TransactionObject: Expected 0x prefixed hexadecimal value, value: 123`)).to.be.true;
}
});
});
Expand Down Expand Up @@ -1454,7 +1454,7 @@ describe('@api RPC Server Acceptance Tests', function () {
await relay.call('eth_call', [callData, 'newest'], requestId);
Assertions.expectedError();
} catch (error) {
Assertions.jsonRpcError(error,predefined.INVALID_PARAMETER(1, 'Expected 0x prefixed string representing the hash (32 bytes) in object, 0x prefixed hexadecimal block number, or the string "latest", "earliest" or "pending'));
Assertions.jsonRpcError(error,predefined.INVALID_PARAMETER(1, 'Expected 0x prefixed string representing the hash (32 bytes) in object, 0x prefixed hexadecimal block number, or the string "latest", "earliest" or "pending, value: newest'));
}
});

Expand All @@ -1469,7 +1469,7 @@ describe('@api RPC Server Acceptance Tests', function () {
await relay.call('eth_call', [callData, '123'], requestId);
Assertions.expectedError();
} catch (error) {
Assertions.jsonRpcError(error,predefined.INVALID_PARAMETER(1, 'Expected 0x prefixed string representing the hash (32 bytes) in object, 0x prefixed hexadecimal block number, or the string "latest", "earliest" or "pending'));
Assertions.jsonRpcError(error,predefined.INVALID_PARAMETER(1, 'Expected 0x prefixed string representing the hash (32 bytes) in object, 0x prefixed hexadecimal block number, or the string "latest", "earliest" or "pending, value: 123'));
}
});

Expand All @@ -1485,7 +1485,7 @@ describe('@api RPC Server Acceptance Tests', function () {
Assertions.expectedError();
} catch (error) {

Assertions.jsonRpcError(error,predefined.INVALID_PARAMETER(`'blockHash' for BlockHashObject`, 'Expected 0x prefixed string representing the hash (32 bytes) of a block'));
Assertions.jsonRpcError(error,predefined.INVALID_PARAMETER(`'blockHash' for BlockHashObject`, 'Expected 0x prefixed string representing the hash (32 bytes) of a block, value: 0x123'));
}
});

Expand All @@ -1500,7 +1500,7 @@ describe('@api RPC Server Acceptance Tests', function () {
await relay.call('eth_call', [callData, {'blockNumber' : '123'}], requestId);
Assertions.expectedError();
} catch (error) {
Assertions.jsonRpcError(error,predefined.INVALID_PARAMETER(`'blockNumber' for BlockNumberObject`, 'Expected 0x prefixed hexadecimal block number, or the string "latest", "earliest" or "pending"'));
Assertions.jsonRpcError(error,predefined.INVALID_PARAMETER(`'blockNumber' for BlockNumberObject`, 'Expected 0x prefixed hexadecimal block number, or the string "latest", "earliest" or "pending", value: 123'));
}
});
});
Expand Down
Loading