diff options
author | Dan Finlay <dan@danfinlay.com> | 2018-01-12 07:00:48 +0800 |
---|---|---|
committer | Dan Finlay <dan@danfinlay.com> | 2018-01-12 07:04:54 +0800 |
commit | 4a9dad7c40b97f1e625931d6b57fc9d7fdc5080d (patch) | |
tree | 5da6f5480adebd94f4df3ca24c07e35dc56f7298 /app | |
parent | 89f75a3a3bde50e583688559e7f876062d2fcdcb (diff) | |
download | tangerine-wallet-browser-4a9dad7c40b97f1e625931d6b57fc9d7fdc5080d.tar tangerine-wallet-browser-4a9dad7c40b97f1e625931d6b57fc9d7fdc5080d.tar.gz tangerine-wallet-browser-4a9dad7c40b97f1e625931d6b57fc9d7fdc5080d.tar.bz2 tangerine-wallet-browser-4a9dad7c40b97f1e625931d6b57fc9d7fdc5080d.tar.lz tangerine-wallet-browser-4a9dad7c40b97f1e625931d6b57fc9d7fdc5080d.tar.xz tangerine-wallet-browser-4a9dad7c40b97f1e625931d6b57fc9d7fdc5080d.tar.zst tangerine-wallet-browser-4a9dad7c40b97f1e625931d6b57fc9d7fdc5080d.zip |
Improve gas price estimation by backfilling recent-blocks
When first initializing, recent-block controller now back-fills up to
its desired history length. This makes estimated gas prices reflect a
longer recent history, even when first switching to a new network.
Fixes #2925
Diffstat (limited to 'app')
-rw-r--r-- | app/scripts/controllers/recent-blocks.js | 79 | ||||
-rw-r--r-- | app/scripts/metamask-controller.js | 6 |
2 files changed, 76 insertions, 9 deletions
diff --git a/app/scripts/controllers/recent-blocks.js b/app/scripts/controllers/recent-blocks.js index 4a906261e..c65c2b1c4 100644 --- a/app/scripts/controllers/recent-blocks.js +++ b/app/scripts/controllers/recent-blocks.js @@ -1,11 +1,13 @@ const ObservableStore = require('obs-store') const extend = require('xtend') +const BN = require('ethereumjs-util').BN class RecentBlocksController { constructor (opts = {}) { - const { blockTracker } = opts + const { blockTracker, ethQuery } = opts this.blockTracker = blockTracker + this.ethQuery = ethQuery this.historyLength = opts.historyLength || 40 const initState = extend({ @@ -14,6 +16,7 @@ class RecentBlocksController { this.store = new ObservableStore(initState) this.blockTracker.on('block', this.processBlock.bind(this)) + this.backfill() } resetState () { @@ -23,12 +26,7 @@ class RecentBlocksController { } processBlock (newBlock) { - const block = extend(newBlock, { - gasPrices: newBlock.transactions.map((tx) => { - return tx.gasPrice - }), - }) - delete block.transactions + const block = this.mapTransactionsToPrices(newBlock) const state = this.store.getState() state.recentBlocks.push(block) @@ -39,6 +37,73 @@ class RecentBlocksController { this.store.updateState(state) } + + backfillBlock (newBlock) { + const block = this.mapTransactionsToPrices(newBlock) + + const state = this.store.getState() + + if (state.recentBlocks.length < this.historyLength) { + state.recentBlocks.unshift(block) + } + + this.store.updateState(state) + } + + mapTransactionsToPrices (newBlock) { + const block = extend(newBlock, { + gasPrices: newBlock.transactions.map((tx) => { + return tx.gasPrice + }), + }) + delete block.transactions + return block + } + + async backfill() { + this.blockTracker.once('block', async (block) => { + let blockNum = block.number + let recentBlocks + let state = this.store.getState() + recentBlocks = state.recentBlocks + + while (recentBlocks.length < this.historyLength) { + try { + let blockNumBn = new BN(blockNum.substr(2), 16) + const newNum = blockNumBn.subn(1).toString(10) + const newBlock = await this.getBlockByNumber(newNum) + + if (newBlock) { + this.backfillBlock(newBlock) + blockNum = newBlock.number + } + + state = this.store.getState() + recentBlocks = state.recentBlocks + } catch (e) { + log.error(e) + } + await this.wait() + } + }) + } + + async wait () { + return new Promise((resolve) => { + setTimeout(resolve, 100) + }) + } + + async getBlockByNumber (number) { + const bn = new BN(number) + return new Promise((resolve, reject) => { + this.ethQuery.getBlockByNumber('0x' + bn.toString(16), true, (err, block) => { + if (err) reject(err) + resolve(block) + }) + }) + } + } module.exports = RecentBlocksController diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index f62b5e5cd..81d70797a 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -94,12 +94,14 @@ module.exports = class MetamaskController extends EventEmitter { this.provider = this.initializeProvider() this.blockTracker = this.provider._blockTracker + // eth data query tools + this.ethQuery = new EthQuery(this.provider) + this.recentBlocksController = new RecentBlocksController({ blockTracker: this.blockTracker, + ethQuery: this.ethQuery, }) - // eth data query tools - this.ethQuery = new EthQuery(this.provider) // account tracker watches balances, nonces, and any code at their address. this.accountTracker = new AccountTracker({ provider: this.provider, |