-
Notifications
You must be signed in to change notification settings - Fork 788
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
Client/StateManager: storageRangeAt() RPC call / EVMStateManager Interface Extension #2922
Conversation
Codecov Report
Additional details and impacted files
Flags with carried forward coverage won't be shown. Click here to find out more. |
@@ -92,6 +101,7 @@ export class Debug { | |||
[validators.transaction()], | |||
[validators.blockOption], | |||
]) | |||
this.storageRangeAt = middleware(this.storageRangeAt.bind(this), 5, [[validators.hex]]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the validators here will only validate the first arg, reading from comments need 5 validators
/** | ||
* Returns a limited set of storage keys belonging to an account. | ||
* @param params An array of 5 parameters: | ||
* 1. The hash of the block that contains the requested account storage. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* 1. The hash of the block that contains the requested account storage. | |
* 1. The hash of the block at which to get storage from the state. |
just making it less ambiguous
* Returns a limited set of storage keys belonging to an account. | ||
* @param params An array of 5 parameters: | ||
* 1. The hash of the block that contains the requested account storage. | ||
* 2. The number index of the requested transaction within the block. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* 2. The number index of the requested transaction within the block. | |
* 2. The transaction index of the requested block post which to get the storage. |
* 1. The hash of the block that contains the requested account storage. | ||
* 2. The number index of the requested transaction within the block. | ||
* 3. The address of the account. | ||
* 4. The smallest (hashed) storage key that will be returned. To include the entire range, pass '0x00'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* 4. The smallest (hashed) storage key that will be returned. To include the entire range, pass '0x00'. | |
* 4. The starting (hashed) key from which storage will be returned. To include the entire range, pass '0x00'. |
* 2. The number index of the requested transaction within the block. | ||
* 3. The address of the account. | ||
* 4. The smallest (hashed) storage key that will be returned. To include the entire range, pass '0x00'. | ||
* 5. The maximum number of storage values that will be returned. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* 5. The maximum number of storage values that will be returned. | |
* 5. The maximum number of storage values that could be returned. |
|
||
let block: Block | ||
try { | ||
block = await this.service.chain.getBlock(blockHashBytes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
block = await this.service.chain.getBlock(blockHashBytes) | |
block = await this.chain.getBlock(blockHashBytes) |
this.chain is available
} | ||
} | ||
|
||
if (txIndex + 1 > block.transactions.length) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (txIndex + 1 > block.transactions.length) { | |
if (txIndex >= block.transactions.length) { |
more comprehensible about the check
} | ||
|
||
try { | ||
const block = await this.service.chain.getBlock(hexToBytes(blockHash)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't the block already read above (in params check) also this.chain
can be directly refereed
try { | ||
address = Address.fromString(account) | ||
blockHashBytes = hexToBytes(blockHash) | ||
startKeyBytes = hexToBytes(startKey) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
startKey
could be directly converted to bigint using a hexToBig... helper , and if limit is also coming as hex encoded it needs to be converted to number/bigint as well as per the requirement
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There does not appear to exist a hexToBigInt()
helper. I have however moved the function calls to the same line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the hex is '0x' prefixed, you can just use the BigInt constructor like: BigInt('0xabcde')
* @returns A {@link StorageRange} object that will contain at most `limit` entries in its `storage` field. | ||
* The object will also contain `nextKey`, the next (hashed) storage key after the range included in `storage`. | ||
*/ | ||
async storageRangeAt(params: [string, number, string, string, number]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
async storageRangeAt(params: [string, number, string, string, number]) { | |
async storageRangeAt(params: [string, string, string, string, string]) { |
most like it will come as a hex encoded number ... not sure about that but do check and update/confirm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reference implementation does use int
for both of these.
Thanks a lot for this PR! 🙏🙂❤️ |
It appears that parameters |
If you are open to do maybe add a very simple /**
* bool validator to check if type is boolean
* @param params parameters of method
* @param index index of parameter
*/
get bool() {
return (params: any[], index: number) => {
if (typeof params[index] !== 'boolean') {
return {
code: INVALID_PARAMS,
message: `invalid argument ${index}: argument is not boolean`,
}
}
}
} |
@@ -92,6 +101,14 @@ export class Debug { | |||
[validators.transaction()], | |||
[validators.blockOption], | |||
]) | |||
// TODO: txIndex and limit are currently not input validated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need new validator types for these?
context.createdAddressNoStorage = thirdResult.createdAddress!! | ||
}) | ||
|
||
it<TestSetup>('Should return the correct (number of) key value pairs.', async ({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does the <TestSetup>
type parameter do? is it just a label, or does it change the it
function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a typesafe way of passing variables from beforeEach()
to tests (see here). For legibility, I had already annotated the TestSetup
interface.
throw new Error('Missing VM.') | ||
} | ||
|
||
if (txIndex < 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we don't already have a validator for index
parameters, it could be worth adding one. especially if there are other methods are doing this themselves
return await vmCopy.stateManager.dumpStorageRange( | ||
// Validator already verified that `account` and `startKey` are properly formatted. | ||
Address.fromString(account), | ||
bytesToBigInt(hexToBytes(startKey)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bytesToBigInt(hexToBytes(startKey)), | |
BigInt(startKey), |
Are there methods that use signed integers (negative numbers)? "index" will always be unsigned, so it might be better to add |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Thanks for including all the tests, and for adding the validator! super helpful 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Congrats, your important contribution to this open-source project has earned you a GitPOAP! GitPOAP: 2023 EthereumJS Contributor: Head to gitpoap.io & connect your GitHub account to mint! Learn more about GitPOAPs here. |
@KoningR Hi there, thanks again for this great work! 🤩 We'll directly that this into the upcoming releases (so: today)! |
This PR implements
debug_storageRangeAt()
as discussed in ethereum/go-ethereum#14350. An implementation is only provided forDefaultStateManager
, not forEthersStateManager
. Additionally, hashed key preimages are alwaysnull
because there does not seem to be a good way to retrieve them currently.