This repository has been archived by the owner on Mar 3, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 565
initial support for mapping types #498
Merged
Merged
Changes from 9 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
8b76861
initial support for mapping types
cdetrio aef34c6
move sha3 mapping from traceChache to web3VMProvider
yann300 3ff34f1
remove location from getStructMembers
yann300 ce16924
use helper
yann300 0958b7e
add doc
yann300 72e1b87
remove uneeded function
yann300 e59e564
extract sha3 input
yann300 ce3caa6
cache the preimages for a debug session (using the initial state)
yann300 075fa4e
fix sha3 input extract
yann300 4013d35
return a promise if mappings alrady requested
yann300 cbd30b8
typo + emptyFill if memory not yet filled
yann300 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
var global = require('../helpers/global') | ||
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. Please document all functions here. |
||
|
||
module.exports = { | ||
decodeMappingsKeys: decodeMappingsKeys | ||
} | ||
|
||
/** | ||
* extract the mappings location from the storage | ||
* like { "<mapping_slot>" : { "<mapping-key1>": preimageOf1 }, { "<mapping-key2>": preimageOf2 }, ... } | ||
* | ||
* @param {Object} storage - storage given by storage Viewer (basically a mapping hashedkey : {key, value}) | ||
* @param {Function} callback - calback | ||
* @return {Map} - solidity mapping location (e.g { "<mapping_slot>" : { "<mapping-key1>": preimageOf1 }, { "<mapping-key2>": preimageOf2 }, ... }) | ||
*/ | ||
async function decodeMappingsKeys (storage, callback) { | ||
var ret = {} | ||
for (var hashedLoc in storage) { | ||
var preimage | ||
try { | ||
preimage = await getPreimage(storage[hashedLoc].key) | ||
} catch (e) { | ||
} | ||
if (preimage) { | ||
// got preimage! | ||
// get mapping position (i.e. storage slot), its the last 32 bytes | ||
var slotByteOffset = preimage.length - 64 | ||
var mappingSlot = preimage.substr(slotByteOffset) | ||
var mappingKey = preimage.substr(0, slotByteOffset) | ||
if (!ret[mappingSlot]) { | ||
ret[mappingSlot] = {} | ||
} | ||
ret[mappingSlot][mappingKey] = preimage | ||
} | ||
} | ||
callback(null, ret) | ||
} | ||
|
||
/** | ||
* Uses web3 to return preimage of a key | ||
* | ||
* @param {String} key - key to retrieve the preimage of | ||
* @return {String} - preimage of the given key | ||
*/ | ||
function getPreimage (key) { | ||
return new Promise((resolve, reject) => { | ||
global.web3.debug.preimage(key, function (error, preimage) { | ||
if (error) { | ||
reject(error) | ||
} else { | ||
resolve(preimage) | ||
} | ||
}) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,12 @@ | ||
'use strict' | ||
var helper = require('../helpers/util') | ||
var mappingPreimages = require('./mappingPreimages') | ||
|
||
/** | ||
* easier access to the storage resolver | ||
* Basically one instance is created foreach execution step and foreach component that need it. | ||
* (TODO: one instance need to be shared over all the components) | ||
*/ | ||
class StorageViewer { | ||
constructor (_context, _storageResolver, _traceManager) { | ||
this.context = _context | ||
|
@@ -15,11 +21,11 @@ class StorageViewer { | |
} | ||
|
||
/** | ||
* return the storage for the current context (address and vm trace index) | ||
* by default now returns the range 0 => 1000 | ||
* | ||
* @param {Function} - callback - contains a map: [hashedKey] = {key, hashedKey, value} | ||
*/ | ||
* return the storage for the current context (address and vm trace index) | ||
* by default now returns the range 0 => 1000 | ||
* | ||
* @param {Function} - callback - contains a map: [hashedKey] = {key, hashedKey, value} | ||
*/ | ||
storageRange (callback) { | ||
this.storageResolver.storageRange(this.context.tx, this.context.stepIndex, this.context.address, (error, storage) => { | ||
if (error) { | ||
|
@@ -58,6 +64,59 @@ class StorageViewer { | |
isComplete (address) { | ||
return this.storageResolver.isComplete(address) | ||
} | ||
|
||
/** | ||
* return all the possible mappings locations for the current context (cached) | ||
* | ||
* @param {Function} callback | ||
*/ | ||
async mappingsLocation () { | ||
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. return a promise |
||
return new Promise((resolve, reject) => { | ||
if (this.completeMappingsLocation) { | ||
return resolve(this.completeMappingsLocation) | ||
} | ||
this.storageResolver.initialPreimagesMappings(this.context.tx, this.context.stepIndex, this.context.address, (error, initialMappingsLocation) => { | ||
if (error) { | ||
reject(error) | ||
} else { | ||
this.extractMappingsLocationChanges(this.storageChanges, (error, mappingsLocationChanges) => { | ||
if (error) { | ||
return reject(error) | ||
} | ||
this.completeMappingsLocation = Object.assign({}, initialMappingsLocation) | ||
for (var key in mappingsLocationChanges) { | ||
if (!initialMappingsLocation[key]) { | ||
initialMappingsLocation[key] = {} | ||
} | ||
this.completeMappingsLocation[key] = Object.assign({}, initialMappingsLocation[key], mappingsLocationChanges[key]) | ||
} | ||
resolve(this.completeMappingsLocation) | ||
}) | ||
} | ||
}) | ||
}) | ||
} | ||
|
||
/** | ||
* retrieve mapping location changes from the storage changes. | ||
* | ||
* @param {Function} callback | ||
*/ | ||
extractMappingsLocationChanges (storageChanges, callback) { | ||
if (this.mappingsLocationChanges) { | ||
return callback(null, this.mappingsLocationChanges) | ||
} | ||
mappingPreimages.decodeMappingsKeys(storageChanges, (error, mappings) => { | ||
if (!error) { | ||
this.mappingsLocationChanges = mappings | ||
return callback(null, this.mappingsLocationChanges) | ||
} else { | ||
callback(error) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
|
||
|
||
module.exports = StorageViewer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Please add a test for the following type:
struct X { uint a; mapping(uint=>uint) b; uint c; }
If such a struct is used in memory, it should be identical to
struct X { uint a; uint c; }
.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.
issue https://github.com/ethereum/remix/issues/510