Skip to content

Commit

Permalink
feat: add support for debug_storageRangeAt RPC (trufflesuite#755)
Browse files Browse the repository at this point in the history
  • Loading branch information
eshaben authored and sam committed Apr 15, 2021
1 parent 59a20c3 commit fb874f1
Show file tree
Hide file tree
Showing 10 changed files with 986 additions and 123 deletions.
67 changes: 42 additions & 25 deletions src/chains/ethereum/ethereum/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,13 +332,6 @@ export default class EthereumApi implements types.Api {
const blockProm = this.#blockchain.blocks.getRaw(blockNumber);

const trie = this.#blockchain.trie.copy();
const getFromTrie = (address: Buffer): Promise<Buffer> =>
new Promise((resolve, reject) => {
trie.get(address, (err, data) => {
if (err) return void reject(err);
resolve(data);
});
});
const block = await blockProm;
if (!block) throw new Error("header not found");

Expand All @@ -351,7 +344,10 @@ export default class EthereumApi implements types.Api {
const blockStateRoot = headerData[3];
trie.root = blockStateRoot;

const addressDataPromise = getFromTrie(Address.from(address).toBuffer());
const addressDataPromise = this.#blockchain.getFromTrie(
trie,
Address.from(address).toBuffer()
);

const posBuff = Quantity.from(position).toBuffer();
const length = posBuff.length;
Expand Down Expand Up @@ -1087,13 +1083,6 @@ export default class EthereumApi implements types.Api {
const blockProm = blockchain.blocks.getRaw(blockNumber);

const trie = blockchain.trie.copy();
const getFromTrie = (address: Buffer): Promise<Buffer> =>
new Promise((resolve, reject) => {
trie.get(address, (err: Error, data: Buffer) => {
if (err) return void reject(err);
resolve(data);
});
});
const block = await blockProm;
if (!block) throw new Error("header not found");

Expand All @@ -1106,7 +1095,10 @@ export default class EthereumApi implements types.Api {
const blockStateRoot = headerData[3];
trie.root = blockStateRoot;

const addressDataPromise = getFromTrie(Address.from(address).toBuffer());
const addressDataPromise = this.#blockchain.getFromTrie(
trie,
Address.from(address).toBuffer()
);

const addressData = await addressDataPromise;
// An address's codeHash is stored in the 4th rlp entry
Expand Down Expand Up @@ -1144,13 +1136,6 @@ export default class EthereumApi implements types.Api {
const blockProm = this.#blockchain.blocks.getRaw(blockNumber);

const trie = this.#blockchain.trie.copy();
const getFromTrie = (address: Buffer): Promise<Buffer> =>
new Promise((resolve, reject) => {
trie.get(address, (err, data) => {
if (err) return void reject(err);
resolve(data);
});
});
const block = await blockProm;
if (!block) throw new Error("header not found");

Expand All @@ -1163,7 +1148,10 @@ export default class EthereumApi implements types.Api {
const blockStateRoot = headerData[3];
trie.root = blockStateRoot;

const addressDataPromise = getFromTrie(Address.from(address).toBuffer());
const addressDataPromise = this.#blockchain.getFromTrie(
trie,
Address.from(address).toBuffer()
);

const posBuff = Quantity.from(position).toBuffer();
const length = posBuff.length;
Expand All @@ -1189,7 +1177,7 @@ export default class EthereumApi implements types.Api {
Buffer /*stateRoot*/,
Buffer /*codeHash*/
])[2];
const value = await getFromTrie(paddedPosBuff);
const value = await this.#blockchain.getFromTrie(trie, paddedPosBuff);
return Data.from(rlpDecode(value));
}

Expand Down Expand Up @@ -1907,6 +1895,35 @@ export default class EthereumApi implements types.Api {
return this.#blockchain.traceTransaction(transactionHash, options || {});
}

/**
* Attempts to replay the transaction as it was executed on the network and
* return storage data given a starting key and max number of entries to return.
*
* @param blockHash DATA, 32 Bytes - hash of a block
* @param txIndex QUANTITY - integer of the transaction index position
* @param contractAddress DATA, 20 Bytes - address of the contract
* @param startKey DATA - hash of the start key for grabbing storage entries
* @param maxResult integer of maximum number of storage entries to return
* @returns returns a storage object with the keys being keccak-256 hashes of the storage keys,
* and the values being the raw, unhashed key and value for that specific storage slot. Also
* returns a next key which is the keccak-256 hash of the next key in storage for continuous downloading.
*/
async debug_storageRangeAt(
blockHash: string | Buffer,
transactionIndex: number,
contractAddress: string,
keyStart: string | Buffer,
maxResult: number
) {
return this.#blockchain.storageRangeAt(
blockHash,
transactionIndex,
contractAddress,
keyStart,
maxResult
);
}

//#endregion

//#region personal
Expand Down
Loading

0 comments on commit fb874f1

Please sign in to comment.