Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
Merge a2c3427 into d458a59
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmurdoch committed Jul 3, 2019
2 parents d458a59 + a2c3427 commit db3d5d4
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 31 deletions.
37 changes: 25 additions & 12 deletions lib/blockchain_double.js
Expand Up @@ -354,12 +354,17 @@ BlockchainDouble.prototype.clearPendingTransactions = function() {
* @param {Function} callback Callback function called after block is created
* @return Block The block created.
*/
BlockchainDouble.prototype.createBlock = function(parent, callback) {
BlockchainDouble.prototype.createBlock = function(parent, emulateParent, callback) {
var self = this;

if (typeof parent === "function") {
callback = parent;
parent = null;
emulateParent = false;
} else if (typeof emulateParent === "function") {
callback = parent;
parent = null;
emulateParent = false;
}

var block = new Block();
Expand All @@ -377,18 +382,26 @@ BlockchainDouble.prototype.createBlock = function(parent, callback) {
return callback(err);
}

var parentNumber = parent != null ? to.number(parent.header.number) : -1;

block.header.gasLimit = self.blockGasLimit;

// Ensure we have the right block number for the VM.
block.header.number = to.hex(parentNumber + 1);
if (parent != null && emulateParent) {
block.header.number = parent.header.number;

block.header.timestamp = parent.header.timestamp;

// Set the timestamp before processing txs
block.header.timestamp = to.hex(self.currentTime());
block.header.parentHash = parent.header.parentHash;
} else {
var parentNumber = parent != null ? to.number(parent.header.number) : -1;

// Ensure we have the right block number for the VM.
block.header.number = to.hex(parentNumber + 1);

if (parent != null) {
block.header.parentHash = to.hex(parent.hash());
// Set the timestamp before processing txs
block.header.timestamp = to.hex(self.currentTime());

if (parent != null) {
block.header.parentHash = to.hex(parent.hash());
}
}

callback(null, block);
Expand Down Expand Up @@ -490,7 +503,7 @@ BlockchainDouble.prototype.processCall = function(tx, blockNumber, callback) {
}

// create a fake block with this fake transaction
self.createBlock(parentBlock, function(err, newBlock) {
self.createBlock(parentBlock, true, function(err, newBlock) {
if (err) {
return callback(err);
}
Expand Down Expand Up @@ -542,7 +555,7 @@ BlockchainDouble.prototype.estimateGas = function(tx, blockNumber, callback) {
}

// create a fake block with this fake transaction
self.createBlock(parentBlock, function(err, newBlock) {
self.createBlock(parentBlock, false, function(err, newBlock) {
if (err) {
return callback(err);
}
Expand Down Expand Up @@ -902,7 +915,7 @@ BlockchainDouble.prototype.processTransactionTrace = async function(hash, params
vm = self.createVMFromStateTrie(stateTrie);

// Prepare the "next" block with necessary transactions
self.createBlock(parent, function(err, block) {
self.createBlock(parent, false, function(err, block) {
if (err) {
return callback(err);
}
Expand Down
23 changes: 12 additions & 11 deletions lib/utils/forkedblockchain.js
Expand Up @@ -79,18 +79,19 @@ ForkedBlockchain.prototype.patchVM = function(vm) {
* like `forkBlockNumber` (required for tracing transactions)
*/
ForkedBlockchain.prototype.createStateTrie = function(db, root, options) {
return new ForkedStorageTrie(
db,
root,
Object.assign(
{
fork: this.fork,
forkBlockNumber: this.forkBlockNumber,
blockchain: this
},
options
)
options = Object.assign(
{
fork: this.fork,
forkBlockNumber: this.forkBlockNumber,
blockchain: this
},
options
);
// never allow the forkBlockNumber to go beyond our root forkBlockNumber
if (options.forkBlockNumber > this.forkBlockNumber) {
options.forkBlockNumber = this.forkBlockNumber;
}
return new ForkedStorageTrie(db, root, options);
};

ForkedBlockchain.prototype.createGenesisBlock = function(callback) {
Expand Down
7 changes: 7 additions & 0 deletions test/call.js
Expand Up @@ -27,4 +27,11 @@ describe("eth_call", function() {

assert.strictEqual(status, true);
});

it("should use the current block number via `eth_call`", async() => {
const actualBlockNumber = await context.web3.eth.getBlockNumber();
// should read the block number, too
const callBlockNumber = await context.instance.methods.currentBlock().call();
assert.strictEqual(parseInt(callBlockNumber, 10), actualBlockNumber);
});
});
2 changes: 2 additions & 0 deletions test/contracts/debug/DebugContract.sol
Expand Up @@ -4,10 +4,12 @@ pragma solidity ^0.4.2;
contract DebugContract {
uint public value = 5;
uint public otherValue = 5;
uint public currentBlock = 0;

function setValue(uint _val) public {
value = _val;
otherValue += _val;
currentBlock = block.number;
}

function callSetValueTwice() public {
Expand Down
4 changes: 4 additions & 0 deletions test/contracts/gas/EstimateGas.sol
Expand Up @@ -99,4 +99,8 @@ contract EstimateGas {

return true;
}

function currentBlock() returns (uint) {
return block.number;
}
}
36 changes: 31 additions & 5 deletions test/debug/debug.js
Expand Up @@ -84,6 +84,9 @@ function test(forked) {

describe("Trace a successful transaction", function() {
let options;
let originalStoredBlockNumber;
let latestStoredBlockNumber;
let latestBlockNumber;
before("set up transaction that should be traced", async() => {
const { accounts, instance } = context;
options = { from: accounts[0], gas };
Expand All @@ -93,6 +96,14 @@ function test(forked) {
hashToTrace = tx.transactionHash;
});

it("sets the blockNumber in storage", async() => {
const { instance, web3 } = context;
// check the value is what we expect it to be: 26
originalStoredBlockNumber = await instance.methods.currentBlock().call(options);
const blockNumber = await web3.eth.getBlockNumber();
assert.strictEqual(parseInt(originalStoredBlockNumber, 10), blockNumber);
});

it("sets the value to 26", async() => {
const { instance } = context;
// check the value is what we expect it to be: 26
Expand All @@ -101,9 +112,12 @@ function test(forked) {
});

it("changes state of contract to ensure trace doesn't overwrite data", async() => {
const { accounts, instance } = context;
const { accounts, instance, web3 } = context;
options = { from: accounts[0], gas };
await instance.methods.setValue(expectedValueBeforeTrace).send(options);
latestStoredBlockNumber = await instance.methods.currentBlock().call(options);

latestBlockNumber = await web3.eth.getBlockNumber();

// check the value is what we expect it to be: 1234
const value = await instance.methods.value().call(options);
Expand All @@ -112,7 +126,7 @@ function test(forked) {

it("should trace a successful transaction without changing state", async function() {
// We want to trace the transaction that sets the value to 26
const { accounts, instance, send } = context;
const { accounts, instance, send, web3 } = context;

const response = await send("debug_traceTransaction", hashToTrace, []);

Expand All @@ -138,7 +152,7 @@ function test(forked) {

assert.strictEqual(lastop.op, "STOP");
assert.strictEqual(lastop.gasCost, 1);
assert.strictEqual(lastop.pc, 209);
assert.strictEqual(lastop.pc, 220);
assert.strictEqual(
lastop.storage["0000000000000000000000000000000000000000000000000000000000000000"],
"000000000000000000000000000000000000000000000000000000000000001a"
Expand All @@ -147,12 +161,24 @@ function test(forked) {
lastop.storage["0000000000000000000000000000000000000000000000000000000000000001"],
"000000000000000000000000000000000000000000000000000000000000001f"
);
assert.strictEqual(
lastop.storage["0000000000000000000000000000000000000000000000000000000000000002"],
originalStoredBlockNumber.padStart(64, "0")
);
console.log("--------------------------------------------------");
const value = await instance.methods.value().call({ from: accounts[0], gas });
assert.strictEqual(value, expectedValueBeforeTrace);

const otherValue = await instance.methods.otherValue().call({ from: accounts[0], gas });
assert.strictEqual(otherValue, "1265");

// stored block number should not have changed:
const storedBlockNumber = await instance.methods.currentBlock().call({ from: accounts[0], gas });
assert.strictEqual(storedBlockNumber, latestStoredBlockNumber);

// block number should not have incremented because of `debug_traceTransaction`
const currentBlockNumber = await web3.eth.getBlockNumber();
assert.strictEqual(currentBlockNumber, latestBlockNumber);
});
});

Expand Down Expand Up @@ -233,12 +259,12 @@ function test(forked) {

// ensure the call to setValue with 2 was successfully stored for value
assert.strictEqual(
arrayOfStorageKeyValues[2]["0000000000000000000000000000000000000000000000000000000000000000"],
arrayOfStorageKeyValues[3]["0000000000000000000000000000000000000000000000000000000000000000"],
"0000000000000000000000000000000000000000000000000000000000000002"
);
// ensure the call to setValue with 2 was successfully stored for otherValue
assert.strictEqual(
arrayOfStorageKeyValues[3]["0000000000000000000000000000000000000000000000000000000000000001"],
arrayOfStorageKeyValues[4]["0000000000000000000000000000000000000000000000000000000000000001"],
"00000000000000000000000000000000000000000000000000000000000004f4"
);

Expand Down
9 changes: 7 additions & 2 deletions test/debug/debugStorage.js
Expand Up @@ -82,15 +82,20 @@ describe("Debug Storage", function() {
"0000000000000000000000000000000000000000000000000000000000000006"
);

assert.strictEqual(
arrayOfStorageKeyValues[1]["0000000000000000000000000000000000000000000000000000000000000001"],
"0000000000000000000000000000000000000000000000000000000000000006"
);

// ensure the call to setValue with 2 was successfully stored for value
assert.strictEqual(
arrayOfStorageKeyValues[2]["0000000000000000000000000000000000000000000000000000000000000000"],
arrayOfStorageKeyValues[3]["0000000000000000000000000000000000000000000000000000000000000000"],
"0000000000000000000000000000000000000000000000000000000000000002"
);

// ensure the call to setValue with 2 was successfully stored for otherValue, making it 8
assert.strictEqual(
arrayOfStorageKeyValues[3]["0000000000000000000000000000000000000000000000000000000000000001"],
arrayOfStorageKeyValues[4]["0000000000000000000000000000000000000000000000000000000000000001"],
"0000000000000000000000000000000000000000000000000000000000000008"
);
}
Expand Down
2 changes: 1 addition & 1 deletion test/forking.js
Expand Up @@ -308,7 +308,7 @@ describe("Forking", function() {
const expectedNumber = await mainWeb3.eth.getBlockNumber();

const number = await oracle.methods.currentBlock().call();
assert.strictEqual(to.number(number), expectedNumber + 1);
assert.strictEqual(to.number(number), expectedNumber);

await oracle.methods.setCurrentBlock().send({ from: mainAccounts[0], gas: 3141592 });
const val = await oracle.methods.lastBlock().call({ from: mainAccounts[0] });
Expand Down

0 comments on commit db3d5d4

Please sign in to comment.