Skip to content

Commit a9c3e8c

Browse files
mattdean-digicatapultholgerd77
authored andcommitted
Clear stateManager cache after setStateRoot
1 parent fcf6eb7 commit a9c3e8c

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

lib/stateManager.js

+6
Original file line numberDiff line numberDiff line change
@@ -396,11 +396,17 @@ proto.setStateRoot = function (stateRoot, cb) {
396396

397397
self._cache.flush(function (err) {
398398
if (err) { return cb(err) }
399+
if (stateRoot === self._trie.EMPTY_TRIE_ROOT) {
400+
self._trie.root = stateRoot
401+
self._cache.clear()
402+
return cb()
403+
}
399404
self._trie.checkRoot(stateRoot, function (err, hasRoot) {
400405
if (err || !hasRoot) {
401406
cb(err || new Error('State trie does not contain state root'))
402407
} else {
403408
self._trie.root = stateRoot
409+
self._cache.clear()
404410
cb()
405411
}
406412
})

tests/api/runBlock.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ tape('runBlock', async (t) => {
6464

6565
// The mocked VM uses a mocked runTx
6666
// which always returns an error.
67-
await suite.p.runBlock({ block, root: genesis.header.stateRoot, skipBlockValidation: true })
67+
await suite.p.runBlock({ block, skipBlockValidation: true })
6868
.then(() => t.fail('should have returned error'))
6969
.catch((e) => t.equal(e.message, 'test'))
7070

@@ -112,7 +112,7 @@ tape('should fail when tx gas limit higher than block gas limit', async (t) => {
112112

113113
await suite.p.generateCanonicalGenesis()
114114

115-
await suite.p.runBlock({ block, root: genesis.header.stateRoot, skipBlockValidation: true })
115+
await suite.p.runBlock({ block, skipBlockValidation: true })
116116
.then(() => t.fail('should have returned error'))
117117
.catch((e) => t.ok(e.message.includes('higher gas limit')))
118118

@@ -137,7 +137,7 @@ tape('should fail when runCall fails', async (t) => {
137137
// runTx is a full implementation that works.
138138
suite.vm.runTx = runTx
139139

140-
await suite.p.runBlock({ block, root: suite.vm.stateManager._trie.root, skipBlockValidation: true })
140+
await suite.p.runBlock({ block, skipBlockValidation: true })
141141

142142
.then(() => t.fail('should have returned error'))
143143
.catch((e) => t.equal(e.message, 'test'))

tests/api/stateManager.js

+30
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,36 @@ tape('StateManager', (t) => {
1818
st.end()
1919
})
2020

21+
t.test('should clear the cache when the state root is set', async (st) => {
22+
const stateManager = new StateManager()
23+
const addressBuffer = Buffer.from('a94f5374fce5edbc8e2a8697c15331677e6ebf0b', "hex")
24+
const account = createAccount()
25+
26+
const getStateRoot = promisify((...args) => stateManager.getStateRoot(...args))
27+
const checkpoint = promisify((...args) => stateManager.checkpoint(...args))
28+
const putAccount = promisify((...args) => stateManager.putAccount(...args))
29+
const getAccount = promisify((...args) => stateManager.getAccount(...args))
30+
const commit = promisify((...args) => stateManager.commit(...args))
31+
const setStateRoot = promisify((...args) => stateManager.setStateRoot(...args))
32+
33+
const initialStateRoot = await getStateRoot()
34+
await checkpoint()
35+
await putAccount(addressBuffer, account)
36+
37+
const account0 = await getAccount(addressBuffer)
38+
st.equal(account0.balance.toString("hex"), account.balance.toString("hex"), 'account value is set in the cache')
39+
40+
await commit()
41+
const account1 = await getAccount(addressBuffer)
42+
st.equal(account1.balance.toString("hex"), account.balance.toString("hex"), 'account value is set in the state trie')
43+
44+
await setStateRoot(initialStateRoot)
45+
const account2 = await getAccount(addressBuffer)
46+
st.equal(account2.balance.toString("hex"), "", 'account value is set to 0 in original state root')
47+
48+
st.end()
49+
})
50+
2151
t.test('should put and get account, and add to the underlying cache if the account is not found', async (st) => {
2252
const stateManager = new StateManager()
2353
const account = createAccount()

0 commit comments

Comments
 (0)