Skip to content

Commit c33283c

Browse files
authored
Merge pull request ethereumjs#375 from danjm/failing-blockchain-tests-sd-coinbase
Stop adding account to cache when checking if it is empty.
2 parents 280eb78 + 614abdd commit c33283c

File tree

3 files changed

+103
-7
lines changed

3 files changed

+103
-7
lines changed

lib/stateManager.js

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,22 @@ proto.getAccount = function (address, cb) {
4040
this.cache.getOrLoad(address, cb)
4141
}
4242

43+
proto._getAccountPure = function (address, cb) {
44+
const self = this
45+
const cachedAccount = this.cache.get(address)
46+
47+
if (cachedAccount) {
48+
cb(null, cachedAccount)
49+
} else {
50+
self.trie.get(address, function (err, account) {
51+
if (err) {
52+
return cb(err)
53+
}
54+
cb(null, account)
55+
})
56+
}
57+
}
58+
4359
// saves the account
4460
proto.putAccount = function (address, account, cb) {
4561
var self = this
@@ -285,9 +301,16 @@ proto.generateGenesis = function (initState, cb) {
285301
}, cb)
286302
}
287303

288-
proto.accountIsEmpty = function (address, cb) {
304+
proto.accountIsEmpty = function (address, getAccountWithoutLoad, cb) {
305+
if (cb === undefined) {
306+
cb = getAccountWithoutLoad
307+
getAccountWithoutLoad = null
308+
}
309+
289310
var self = this
290-
self.getAccount(address, function (err, account) {
311+
var getAccountCall = getAccountWithoutLoad ? self._getAccountPure : self.getAccount
312+
313+
getAccountCall.bind(this)(address, function (err, account) {
291314
if (err) {
292315
return cb(err)
293316
}
@@ -301,7 +324,7 @@ proto.cleanupTouchedAccounts = function (cb) {
301324
var touchedArray = Array.from(self._touched)
302325
async.forEach(touchedArray, function (addressHex, next) {
303326
var address = Buffer.from(addressHex, 'hex')
304-
self.accountIsEmpty(address, function (err, empty) {
327+
self.accountIsEmpty(address, true, function (err, empty) {
305328
if (err) {
306329
next(err)
307330
return

tests/api/stateManager.js

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ tape('StateManager', (t) => {
1818
st.end()
1919
})
2020

21-
t.test('should put and get account', async (st) => {
21+
t.test('should put and get account, and add to the underlying cache if the account is not found', async (st) => {
2222
const stateManager = new StateManager()
2323
const account = createAccount()
2424

@@ -32,6 +32,79 @@ tape('StateManager', (t) => {
3232
)
3333

3434
st.equal(res.balance.toString('hex'), 'fff384')
35+
36+
stateManager.cache.clear()
37+
38+
res = await promisify(stateManager.getAccount.bind(stateManager))(
39+
'a94f5374fce5edbc8e2a8697c15331677e6ebf0b'
40+
)
41+
42+
st.equal(stateManager.cache._cache.keys[0], 'a94f5374fce5edbc8e2a8697c15331677e6ebf0b')
43+
44+
st.end()
45+
})
46+
47+
t.test('should retrieve a cached account, without adding to the underlying cache if the account is not found', async (st) => {
48+
const stateManager = new StateManager()
49+
const account = createAccount()
50+
51+
await promisify(stateManager.putAccount.bind(stateManager))(
52+
'a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
53+
account
54+
)
55+
56+
let res = await promisify(stateManager._getAccountPure.bind(stateManager))(
57+
'a94f5374fce5edbc8e2a8697c15331677e6ebf0b'
58+
)
59+
60+
st.equal(res.balance.toString('hex'), 'fff384')
61+
62+
stateManager.cache.clear()
63+
64+
res = await promisify(stateManager._getAccountPure.bind(stateManager))(
65+
'a94f5374fce5edbc8e2a8697c15331677e6ebf0b'
66+
)
67+
68+
st.notOk(stateManager.cache._cache.keys[0])
69+
70+
st.end()
71+
})
72+
73+
t.test('should call the callback with a boolean representing emptiness, and not cache the account if passed correct params', async (st) => {
74+
const stateManager = new StateManager()
75+
76+
const promisifiedAccountIsEmpty = promisify(stateManager.accountIsEmpty.bind(stateManager), function (err, result) {
77+
return err || result
78+
})
79+
let res = await promisifiedAccountIsEmpty('a94f5374fce5edbc8e2a8697c15331677e6ebf0b', true)
80+
81+
st.ok(res)
82+
st.notOk(stateManager.cache._cache.keys[0])
83+
84+
let res2 = await promisifiedAccountIsEmpty('0x095e7baea6a6c7c4c2dfeb977efac326af552d87')
85+
86+
st.ok(res2)
87+
st.equal(stateManager.cache._cache.keys[0], '0x095e7baea6a6c7c4c2dfeb977efac326af552d87')
88+
89+
st.end()
90+
})
91+
92+
t.test('should call the callback with a false boolean representing emptiness when the account is empty', async (st) => {
93+
const stateManager = new StateManager()
94+
const account = createAccount('0x1', '0x1')
95+
96+
await promisify(stateManager.putAccount.bind(stateManager))(
97+
'a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
98+
account
99+
)
100+
101+
const promisifiedAccountIsEmpty = promisify(stateManager.accountIsEmpty.bind(stateManager), function (err, result) {
102+
return err || result
103+
})
104+
let res = await promisifiedAccountIsEmpty('a94f5374fce5edbc8e2a8697c15331677e6ebf0b', true)
105+
106+
st.notOk(res)
107+
35108
st.end()
36109
})
37110
})

tests/api/utils.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ function createGenesis () {
1111
return genesis
1212
}
1313

14-
function createAccount () {
14+
function createAccount (nonce, balance) {
1515
const raw = {
16-
nonce: '0x00',
17-
balance: '0xfff384'
16+
nonce: nonce || '0x00',
17+
balance: balance || '0xfff384'
1818
}
1919
const acc = new Account(raw)
2020
return acc

0 commit comments

Comments
 (0)