Skip to content

Commit

Permalink
Remove explicit direct cache interactions
Browse files Browse the repository at this point in the history
The method `warmCache` on `stateManager` and the `populateCache` option directly expose
the existence of the state cache. This makes removing all references to the cache impossible.
  • Loading branch information
mattdean-digicatapult committed Oct 8, 2018
1 parent 9a3dc04 commit 3f1e0ad
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 167 deletions.
4 changes: 0 additions & 4 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,3 @@ VM.prototype.copy = function () {
VM.prototype.loadCompiled = function (address, src, cb) {
this.stateManager.trie.db.put(address, src, cb)
}

VM.prototype.populateCache = function (addresses, cb) {
this.stateManager.warmCache(addresses, cb)
}
8 changes: 5 additions & 3 deletions lib/opFns.js
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,11 @@ module.exports = {

stateManager.putContractStorage(address, key, value, function (err) {
if (err) return cb(err)
runState.contract = stateManager.cache.get(address)
cb(null)
stateManager.getAccount(address, function (err, account) {
if (err) return cb(err)
runState.contract = account
cb(null)
})
})
})
},
Expand Down Expand Up @@ -943,7 +946,6 @@ function makeCall (runState, callOptions, localOpts, cb) {
callOptions.origin = runState.origin
callOptions.gasPrice = runState.gasPrice
callOptions.block = runState.block
callOptions.populateCache = false
callOptions.static = callOptions.static || false
callOptions.selfdestruct = runState.selfdestruct

Expand Down
114 changes: 51 additions & 63 deletions lib/runBlock.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ module.exports = function (opts, cb) {
const receiptTrie = new Trie()
// the total amount of gas used processing this block
var gasUsed = new BN(0)
// miner account
var minerAccount
var receipts = []
var txResults = []
var result
Expand All @@ -47,8 +45,8 @@ module.exports = function (opts, cb) {
// run everything
async.series([
beforeBlock,
populateCache,
processTransactions
processTransactions,
payOmmersAndMiner
], parseBlockResults)

function beforeBlock (cb) {
Expand All @@ -59,22 +57,6 @@ module.exports = function (opts, cb) {
self.emit('afterBlock', result, cb)
}

// populates the cache with accounts that we know we will need
function populateCache (cb) {
var accounts = new Set()
accounts.add(block.header.coinbase.toString('hex'))
block.transactions.forEach(function (tx) {
accounts.add(tx.getSenderAddress().toString('hex'))
accounts.add(tx.to.toString('hex'))
})

block.uncleHeaders.forEach(function (uh) {
accounts.add(uh.coinbase.toString('hex'))
})

self.populateCache(accounts, cb)
}

/**
* Processes all of the transaction in the block
* @method processTransaction
Expand All @@ -95,8 +77,7 @@ module.exports = function (opts, cb) {
// run the tx through the VM
self.runTx({
tx: tx,
block: block,
populateCache: false
block: block
}, parseTxResult)

function parseTxResult (err, result) {
Expand Down Expand Up @@ -134,13 +115,58 @@ module.exports = function (opts, cb) {
}

receipts.push(txReceipt)
receiptTrie.put(rlp.encode(validReceiptCount), rlp.encode(rawTxReceipt))
validReceiptCount++
cb()
receiptTrie.put(rlp.encode(validReceiptCount), rlp.encode(rawTxReceipt), function () {
validReceiptCount++
cb()
})
}
}
}

// credit all block rewards
function payOmmersAndMiner (cb) {
var ommers = block.uncleHeaders

// pay each ommer
async.series([
rewardOmmers,
rewardMiner
], cb)

function rewardOmmers (done) {
async.each(block.uncleHeaders, function (ommer, next) {
// calculate reward
var minerReward = new BN(self._common.param('pow', 'minerReward'))
var heightDiff = new BN(block.header.number).sub(new BN(ommer.number))
var reward = ((new BN(8)).sub(heightDiff)).mul(minerReward.divn(8))

if (reward.ltn(0)) {
reward = new BN(0)
}

rewardAccount(ommer.coinbase, reward, next)
}, done)
}

function rewardMiner (done) {
// calculate nibling reward
var minerReward = new BN(self._common.param('pow', 'minerReward'))
var niblingReward = minerReward.divn(32)
var totalNiblingReward = niblingReward.muln(ommers.length)
var reward = minerReward.add(totalNiblingReward)
rewardAccount(block.header.coinbase, reward, done)
}

function rewardAccount (address, reward, done) {
self.stateManager.getAccount(address, function (err, account) {
if (err) return done(err)
// give miner the block reward
account.balance = new BN(account.balance).add(reward)
self.stateManager.putAccount(address, account, done)
})
}
}

// handle results or error from block run
function parseBlockResults (err) {
if (err) {
Expand All @@ -149,9 +175,6 @@ module.exports = function (opts, cb) {
return
}

// credit all block rewards
payOmmersAndMiner()

// credit all block rewards
if (generateStateRoot) {
block.header.stateRoot = self.stateManager.trie.root
Expand Down Expand Up @@ -186,39 +209,4 @@ module.exports = function (opts, cb) {
})
})
}

// credit all block rewards
function payOmmersAndMiner () {
var ommers = block.uncleHeaders
// pay each ommer
ommers.forEach(rewardOmmer)

// calculate nibling reward
var minerReward = new BN(self._common.param('pow', 'minerReward'))
var niblingReward = minerReward.divn(32)
var totalNiblingReward = niblingReward.muln(ommers.length)
minerAccount = self.stateManager.cache.get(block.header.coinbase)
// give miner the block reward
minerAccount.balance = new BN(minerAccount.balance)
.add(minerReward)
.add(totalNiblingReward)
self.stateManager.cache.put(block.header.coinbase, minerAccount)
}

// credit ommer
function rewardOmmer (ommer) {
// calculate reward
var minerReward = new BN(self._common.param('pow', 'minerReward'))
var heightDiff = new BN(block.header.number).sub(new BN(ommer.number))
var reward = ((new BN(8)).sub(heightDiff)).mul(minerReward.divn(8))

if (reward.ltn(0)) {
reward = new BN(0)
}

// credit miners account
var ommerAccount = self.stateManager.cache.get(ommer.coinbase)
ommerAccount.balance = reward.add(new BN(ommerAccount.balance))
self.stateManager.cache.put(ommer.coinbase, ommerAccount)
}
}
19 changes: 13 additions & 6 deletions lib/runCall.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ module.exports = function (opts, cb) {
var createdAddress
var txValue = opts.value || Buffer.from([0])
var caller = opts.caller
var account = stateManager.cache.get(caller)
var account
var block = opts.block
var code = opts.code
var txData = opts.data
Expand All @@ -53,6 +53,7 @@ module.exports = function (opts, cb) {

// run and parse
async.series([
loadFromAccount,
subTxValue,
loadToAccount,
addTxValue,
Expand All @@ -61,9 +62,15 @@ module.exports = function (opts, cb) {
saveCode
], parseCallResult)

function loadFromAccount (done) {
stateManager.getAccount(caller, function (err, fromAccount) {
account = fromAccount
done(err)
})
}

function loadToAccount (done) {
// get receiver's account
// toAccount = stateManager.cache.get(toAddress)
if (!toAddress) {
// generate a new contract if no `to`
code = txData
Expand Down Expand Up @@ -98,8 +105,10 @@ module.exports = function (opts, cb) {
})
} else {
// else load the `to` account
toAccount = stateManager.cache.get(toAddress)
done()
stateManager.getAccount(toAddress, function (err, account) {
toAccount = account
done(err)
})
}
}

Expand Down Expand Up @@ -166,7 +175,6 @@ module.exports = function (opts, cb) {
block: block,
depth: depth,
selfdestruct: selfdestruct,
populateCache: false,
static: isStatic
}

Expand All @@ -175,7 +183,6 @@ module.exports = function (opts, cb) {
codeRunner.call(self, runCodeOpts, parseRunResult)

function parseRunResult (err, results) {
toAccount = self.stateManager.cache.get(toAddress)
vmResults = results

if (createdAddress) {
Expand Down
10 changes: 1 addition & 9 deletions lib/runCode.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ module.exports = function (opts, cb) {
origin: opts.origin || opts.caller || utils.zeros(32),
callData: opts.data || Buffer.from([0]),
code: opts.code,
populateCache: opts.populateCache === undefined ? true : opts.populateCache,
static: opts.static || false
}

Expand Down Expand Up @@ -261,14 +260,7 @@ module.exports = function (opts, cb) {
results.gasUsed = runState.gasLimit.sub(runState.gasLeft)
}

if (runState.populateCache) {
self.stateManager.cache.flush(function () {
self.stateManager.cache.clear()
cb(err, results)
})
} else {
cb(err, results)
}
cb(err, results)
}
}

Expand Down

0 comments on commit 3f1e0ad

Please sign in to comment.