parent
c22da8450c
commit
08351f801a
@ -0,0 +1,132 @@ |
|||||||
|
const EventEmitter = require('events').EventEmitter |
||||||
|
const inherits = require('util').inherits |
||||||
|
const async = require('async') |
||||||
|
const clone = require('clone') |
||||||
|
const EthQuery = require('eth-query') |
||||||
|
|
||||||
|
module.exports = EthereumStore |
||||||
|
|
||||||
|
|
||||||
|
inherits(EthereumStore, EventEmitter) |
||||||
|
function EthereumStore(engine) { |
||||||
|
const self = this |
||||||
|
EventEmitter.call(self) |
||||||
|
self._currentState = { |
||||||
|
accounts: {}, |
||||||
|
transactions: {}, |
||||||
|
} |
||||||
|
self._query = new EthQuery(engine) |
||||||
|
|
||||||
|
engine.on('block', self._updateForBlock.bind(self)) |
||||||
|
} |
||||||
|
|
||||||
|
//
|
||||||
|
// public
|
||||||
|
//
|
||||||
|
|
||||||
|
EthereumStore.prototype.getState = function(){ |
||||||
|
const self = this |
||||||
|
return clone(self._currentState) |
||||||
|
} |
||||||
|
|
||||||
|
EthereumStore.prototype.addAccount = function(address){ |
||||||
|
const self = this |
||||||
|
self._currentState.accounts[address] = {} |
||||||
|
self._didUpdate() |
||||||
|
if (!self.currentBlockNumber) return |
||||||
|
self._updateAccountForBlock(self.currentBlockNumber, address, noop) |
||||||
|
} |
||||||
|
|
||||||
|
EthereumStore.prototype.removeAccount = function(address){ |
||||||
|
const self = this |
||||||
|
delete self._currentState.accounts[address] |
||||||
|
self._didUpdate() |
||||||
|
} |
||||||
|
|
||||||
|
EthereumStore.prototype.addTransaction = function(txHash){ |
||||||
|
const self = this |
||||||
|
self._currentState.transactions[txHash] = {} |
||||||
|
self._didUpdate() |
||||||
|
if (!self.currentBlockNumber) return |
||||||
|
self._updateTransaction(self.currentBlockNumber, txHash, noop) |
||||||
|
} |
||||||
|
|
||||||
|
EthereumStore.prototype.removeTransaction = function(address){ |
||||||
|
const self = this |
||||||
|
delete self._currentState.transactions[address] |
||||||
|
self._didUpdate() |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// private
|
||||||
|
//
|
||||||
|
|
||||||
|
EthereumStore.prototype._didUpdate = function() { |
||||||
|
const self = this |
||||||
|
var state = self.getState() |
||||||
|
self.emit('update', state) |
||||||
|
} |
||||||
|
|
||||||
|
EthereumStore.prototype._updateForBlock = function(block) { |
||||||
|
const self = this |
||||||
|
var blockNumber = '0x'+block.number.toString('hex') |
||||||
|
self.currentBlockNumber = blockNumber |
||||||
|
async.parallel([ |
||||||
|
self._updateAccountsForBlock.bind(self, blockNumber), |
||||||
|
self._updateTransactions.bind(self, blockNumber), |
||||||
|
], function(err){ |
||||||
|
if (err) return console.error(err) |
||||||
|
self.emit('block', self.getState()) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
EthereumStore.prototype._updateAccountsForBlock = function(block, cb) { |
||||||
|
const self = this |
||||||
|
var accountsState = self._currentState.accounts |
||||||
|
var addresses = Object.keys(accountsState) |
||||||
|
async.each(addresses, self._updateAccountForBlock.bind(self, block), cb) |
||||||
|
} |
||||||
|
|
||||||
|
EthereumStore.prototype._updateAccountForBlock = function(block, address, cb) { |
||||||
|
const self = this |
||||||
|
var accountsState = self._currentState.accounts |
||||||
|
self._query.getAccount(address, block, function(err, result){ |
||||||
|
if (err) return cb(err) |
||||||
|
result.address = address |
||||||
|
// only populate if the entry is still present
|
||||||
|
if (accountsState[address]) { |
||||||
|
accountsState[address] = result |
||||||
|
self._didUpdate() |
||||||
|
} |
||||||
|
cb(null, result) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
EthereumStore.prototype._updateTransactions = function(block, cb) { |
||||||
|
const self = this |
||||||
|
var transactionsState = self._currentState.transactions |
||||||
|
var txHashes = Object.keys(transactionsState) |
||||||
|
async.each(txHashes, self._updateTransaction.bind(self, block), cb) |
||||||
|
} |
||||||
|
|
||||||
|
EthereumStore.prototype._updateTransaction = function(block, txHash, cb) { |
||||||
|
const self = this |
||||||
|
// would use the block here to determine how many confirmations the tx has
|
||||||
|
var transactionsState = self._currentState.transactions |
||||||
|
self._query.getTransaction(txHash, function(err, result){ |
||||||
|
if (err) return cb(err) |
||||||
|
// only populate if the entry is still present
|
||||||
|
if (transactionsState[txHash]) { |
||||||
|
transactionsState[txHash] = result |
||||||
|
self._didUpdate() |
||||||
|
} |
||||||
|
cb(null, result) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
function valuesFor(obj){ |
||||||
|
return Object.keys(obj).map(function(key){ return obj[key] }) |
||||||
|
} |
||||||
|
|
||||||
|
function noop(){} |
Loading…
Reference in new issue