-
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
Changes from 1 commit
e3e6220
026ffe4
b8d5adc
9a0a72f
1ecc198
720e3c3
bc2bc69
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,4 +1,12 @@ | ||||||
import { Address, TypeOutput, bigIntToHex, bytesToHex, hexToBytes, toType } from '@ethereumjs/util' | ||||||
import { | ||||||
Address, | ||||||
TypeOutput, | ||||||
bigIntToHex, | ||||||
bytesToBigInt, | ||||||
bytesToHex, | ||||||
hexToBytes, | ||||||
toType, | ||||||
} from '@ethereumjs/util' | ||||||
|
||||||
import { INTERNAL_ERROR, INVALID_PARAMS } from '../error-code' | ||||||
import { getBlockByOption } from '../helpers' | ||||||
|
@@ -8,6 +16,7 @@ import type { EthereumClient } from '../..' | |||||
import type { Chain } from '../../blockchain' | ||||||
import type { FullEthereumService } from '../../service' | ||||||
import type { RpcTx } from '../types' | ||||||
import type { Block } from '@ethereumjs/block' | ||||||
import type { VM } from '@ethereumjs/vm' | ||||||
|
||||||
export interface tracerOpts { | ||||||
|
@@ -92,6 +101,7 @@ export class Debug { | |||||
[validators.transaction()], | ||||||
[validators.blockOption], | ||||||
]) | ||||||
this.storageRangeAt = middleware(this.storageRangeAt.bind(this), 5, [[validators.hex]]) | ||||||
} | ||||||
|
||||||
/** | ||||||
|
@@ -278,4 +288,80 @@ export class Debug { | |||||
message: err.message.toString(), | ||||||
} | ||||||
} | ||||||
|
||||||
/** | ||||||
* 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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
just making it less ambiguous |
||||||
* 2. The number index of the requested transaction within the block. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* 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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* 5. The maximum number of storage values that will be returned. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* @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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
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 commentThe reason will be displayed to describe this comment to others. Learn more. The reference implementation does use |
||||||
const [blockHash, txIndex, account, startKey, limit] = params | ||||||
|
||||||
if (txIndex < 0) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we don't already have a validator for |
||||||
throw { | ||||||
code: INTERNAL_ERROR, | ||||||
message: 'txIndex cannot be smaller than 0.', | ||||||
} | ||||||
} | ||||||
|
||||||
let address: Address | ||||||
let blockHashBytes: Uint8Array | ||||||
let startKeyBytes: Uint8Array | ||||||
try { | ||||||
address = Address.fromString(account) | ||||||
blockHashBytes = hexToBytes(blockHash) | ||||||
startKeyBytes = hexToBytes(startKey) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There does not appear to exist a There was a problem hiding this comment. Choose a reason for hiding this commentThe 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: |
||||||
} catch (err: any) { | ||||||
throw { | ||||||
code: INVALID_PARAMS, | ||||||
message: err.message.toString(), | ||||||
} | ||||||
} | ||||||
|
||||||
let block: Block | ||||||
try { | ||||||
block = await this.service.chain.getBlock(blockHashBytes) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
this.chain is available |
||||||
} catch (err: any) { | ||||||
throw { | ||||||
code: INTERNAL_ERROR, | ||||||
message: 'Could not get requested block hash.', | ||||||
} | ||||||
} | ||||||
|
||||||
if (txIndex + 1 > block.transactions.length) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
more comprehensible about the check |
||||||
throw { | ||||||
code: INTERNAL_ERROR, | ||||||
message: 'txIndex cannot be larger than the number of transactions in the block.', | ||||||
} | ||||||
} | ||||||
|
||||||
try { | ||||||
const block = await this.service.chain.getBlock(hexToBytes(blockHash)) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isn't the block already read above (in params check) also |
||||||
const parentBlock = await this.service.chain.getBlock(block.header.parentHash) | ||||||
|
||||||
// Copy the VM and run transactions including the relevant transaction. | ||||||
const vmCopy = await this.service.execution.vm.shallowCopy() | ||||||
await vmCopy.stateManager.setStateRoot(parentBlock.header.stateRoot) | ||||||
for (let i = 0; i <= txIndex; i++) { | ||||||
await vmCopy.runTx({ tx: block.transactions[i], block }) | ||||||
} | ||||||
|
||||||
return await vmCopy.stateManager.dumpStorageRange( | ||||||
address, | ||||||
bytesToBigInt(startKeyBytes), | ||||||
limit | ||||||
) | ||||||
} catch (err: any) { | ||||||
throw { | ||||||
code: INTERNAL_ERROR, | ||||||
message: err.message.toString(), | ||||||
} | ||||||
} | ||||||
} | ||||||
} |
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