Skip to content

Commit

Permalink
Add chains tests for block updates (#529)
Browse files Browse the repository at this point in the history
  • Loading branch information
mholtzman authored Aug 4, 2021
1 parent 7cbfa10 commit 26ef2cc
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 29 deletions.
5 changes: 3 additions & 2 deletions main/chains/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ class ChainConnection extends EventEmitter {
if (this.chainId != 1) {
// prior to the london hardfork, mainnet uses its own gas service
gasCalculator.getGasPrices().then(gas => {
const customLevel = store('main.networksMeta', this.network, this.chainId, 'gas.price.levels.custom')
const customLevel = store('main.networksMeta', this.type, this.chainId, 'gas.price.levels.custom')

store.setGasPrices({
store.setGasPrices(this.type, this.chainId, {
...gas,
custom: customLevel || gas.fast
})
Expand All @@ -92,6 +92,7 @@ class ChainConnection extends EventEmitter {
})
}
}

accounts.updatePendingFees(this.chainId)
})
}
Expand Down
47 changes: 21 additions & 26 deletions test/main/accounts/index.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
const { addHexPrefix } = require('ethereumjs-util')
import { addHexPrefix } from 'ethereumjs-util'
import store from '../../../main/store'

jest.mock('../../../main/signers', () => jest.fn())
jest.mock('../../../main/windows', () => ({ broadcast: jest.fn(), showTray: jest.fn() }))
jest.mock('../../../main/externalData')

jest.mock('../../../main/store/persist', () => ({
get: jest.fn(),
set: jest.fn()
}))

jest.mock('../../../main/nebula', () => jest.fn(() => ({
ens: {
lookupAddress: jest.fn()
Expand All @@ -17,35 +24,23 @@ const weiToHex = wei => addHexPrefix(wei.toString(16))
const gweiToHex = gwei => weiToHex(gwei * 1e9)

const account = {
"id": "0x22dd63c3619818fdbc262c78baee43cb61e9cccf",
"name": "Seed Account",
"lastSignerType": "seed",
"address": "0x22dd63c3619818fdbc262c78baee43cb61e9cccf",
"status": "ok",
"signer": "3935336131653838663031303266613139373335616337626261373962343231",
"requests": {},
"ensName": null,
"tokens": {},
"created": "12819530:1626189153547"
}

const mockStore = {
'main.accounts': {
"0x22dd63c3619818fdbc262c78baee43cb61e9cccf": account
}
id: '0x22dd63c3619818fdbc262c78baee43cb61e9cccf',
name: 'Seed Account',
lastSignerType: 'seed',
address: '0x22dd63c3619818fdbc262c78baee43cb61e9cccf',
status: 'ok',
signer: '3935336131653838663031303266613139373335616337626261373962343231',
requests: {},
ensName: null,
tokens: {},
created: '12819530:1626189153547'
}

jest.mock('../../../main/store', () => {
const store = k => mockStore[k]

store.updateAccount = () => {}
store.observer = () => {}
return store
})

let Accounts, request

beforeAll(async () => {
store.updateAccount(account)

// need to import this after mocks are set up
Accounts = (await import('../../../main/accounts')).default
})
Expand All @@ -64,7 +59,7 @@ beforeEach(() => {
}
}

Accounts.setSigner('0x22dd63c3619818fdbc262c78baee43cb61e9cccf', jest.fn())
Accounts.setSigner(account.address, jest.fn())
})

afterEach(() => {
Expand Down
188 changes: 188 additions & 0 deletions test/main/chains/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import EventEmitter from 'events'
import { addHexPrefix } from 'ethereumjs-util'
import log from 'electron-log'

import store from '../../../main/store'
import { gweiToHex, weiToHex } from '../../util'

log.transports.console.level = false

class MockConnection extends EventEmitter {
constructor (chainId) {
super()

this.send = payload => {
return new Promise((resolve, reject) => {
if (payload.method === 'eth_getBlockByNumber') {
return resolve(block)
} else if (payload.method === 'eth_gasPrice') {
return resolve(gasPrice)
} else if (payload.method === 'eth_feeHistory') {
return resolve({
baseFeePerGas: [gweiToHex(15), gweiToHex(8), gweiToHex(9), gweiToHex(8), gweiToHex(7)],
gasUsedRatio: [0.11, 0.8, 0.2, 0.5],
reward: [
[gweiToHex(1), gweiToHex(1), gweiToHex(1), gweiToHex(1),]
]
})
}

return reject('unknown method!')
})
}

this.sendAsync = (payload, cb) => {
if (payload.method === 'eth_chainId') return cb(null, { result: addHexPrefix(chainId.toString(16)) })
return cb('unknown method!')
}
}
}

let block, gasPrice, observer
const mockConnection = new MockConnection(4)
const state = {
main: {
currentNetwork: {
type: 'ethereum',
id: '4'
},
networkPresets: {
ethereum: {
default: {
local: 'direct'
},
4: {
infura: 'infuraRinkeby'
}
}
},
networks: {
ethereum: {
4: {
id: 4,
type: 'ethereum',
layer: 'testnet',
symbol: 'ETH',
name: 'Rinkeby',
explorer: 'https://rinkeby.etherscan.io',
gas: {
price: {
selected: 'standard',
levels: { slow: '', standard: '', fast: '', asap: '', custom: '' }
}
},
connection: {
primary: { on: true, current: 'infura', status: 'loading', connected: false, type: '', network: '', custom: '' },
secondary: { on: false, current: 'custom', status: 'loading', connected: false, type: '', network: '', custom: '' }
},
on: true
}
}
},
networksMeta: {
ethereum: {
4: {
gas: {
fees: {},
price: {
selected: 'standard',
levels: { slow: '', standard: '', fast: '', asap: '', custom: '' }
}
}
}
}
}
}
}

jest.mock('eth-provider', () => () => mockConnection)
jest.mock('../../../main/store/state', () => () => state)
jest.mock('../../../main/accounts', () => ({ updatePendingFees: jest.fn() }))
jest.mock('../../../main/store/persist', () => ({
get: jest.fn(),
set: jest.fn()
}))


let Chains
beforeAll(async () => {
// need to import this after mocks are set up
Chains = (await import('../../../main/chains')).default
})

beforeEach(() => {
block = {}
store.setGasPrices('ethereum', '4', {})
store.setGasFees('ethereum', '4', {})
})

afterEach(() => {
if (observer) {
observer.remove()
}

mockConnection.emit('close')
})

it('sets legacy gas prices on a new non-London block', done => {
gasPrice = gweiToHex(6)
block = {
number: addHexPrefix((8897988 - 20).toString(16)) // london block: 8897988
}

observer = store.observer(() => {
const gas = store('main.networksMeta.ethereum.4.gas.price.levels')
if (gas.fast) {
expect(gas.fast).toBe(gweiToHex(6))

done()
}
})

mockConnection.emit('connect')
})

it('sets legacy gas prices on one of the first 120 blocks after the London hardfork', done => {
gasPrice = gweiToHex(7)
block = {
number: addHexPrefix((8897988 + 20).toString(16)), // london block: 8897988
baseFeePerGas: gweiToHex(16)
}

observer = store.observer(() => {
const gas = store('main.networksMeta.ethereum.4.gas.price.levels')
if (gas.fast) {
expect(gas.fast).toBe(gweiToHex(7))

done()
}
})

mockConnection.emit('connect')
})

it('sets fee market prices on a new London block', done => {
block = {
number: addHexPrefix((8897988 + 200).toString(16)), // london block: 8897988
baseFeePerGas: gweiToHex(9)
}

const expectedBaseFee = 7e9 * 1.125 * 1.125
const expectedPriorityFee = 1e9

observer = store.observer(() => {
const gas = store('main.networksMeta.ethereum.4.gas.price')
if (gas.fees.maxBaseFeePerGas) {
expect(gas.fees.maxBaseFeePerGas).toBe(weiToHex(expectedBaseFee))
expect(gas.fees.maxPriorityFeePerGas).toBe(weiToHex(expectedPriorityFee))
expect(gas.fees.maxFeePerGas).toBe(weiToHex(expectedBaseFee + expectedPriorityFee))

expect(gas.selected).toBe('fast')
expect(gas.levels.fast).toBe(weiToHex(expectedBaseFee + expectedPriorityFee))

done()
}
})

mockConnection.emit('connect')
})
6 changes: 5 additions & 1 deletion test/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

const EventEmitter = require('events')
const store = require('../main/store')
const { addHexPrefix } = require('ethereumjs-util')

const weiToHex = wei => addHexPrefix(wei.toString(16))
const gweiToHex = gwei => weiToHex(gwei * 1e9)

class Observer extends EventEmitter {
constructor (root, keys) {
Expand Down Expand Up @@ -39,4 +43,4 @@ class Counter {
}
}

module.exports = { Counter, Observer }
module.exports = { Counter, Observer, weiToHex, gweiToHex }

0 comments on commit 26ef2cc

Please sign in to comment.