feat: track gas price, avg block time, blocknumbers and blocks (#65)
* feat: block stats * load last 10 blocks
This commit is contained in:
parent
4232fc3231
commit
5ee1234f0f
110
src/subspace.js
110
src/subspace.js
|
@ -1,4 +1,4 @@
|
|||
import { ReplaySubject } from 'rxjs';
|
||||
import { ReplaySubject, BehaviorSubject } from 'rxjs';
|
||||
import { distinctUntilChanged, map } from 'rxjs/operators';
|
||||
import equal from 'fast-deep-equal';
|
||||
import Database from './database/database.js';
|
||||
|
@ -26,18 +26,31 @@ export default class Subspace {
|
|||
this.options.refreshLastNBlocks = options.refreshLastNBlocks || 12;
|
||||
this.options.callInterval = options.callInterval || 0;
|
||||
this.options.dbFilename = options.dbFilename || 'subspace.db';
|
||||
this.latestBlockNumber = undefined;
|
||||
this.disableDatabase = options.disableDatabase;
|
||||
this.networkId = undefined;
|
||||
this.isWebsocketProvider = options.disableSubscriptions ? false : !!provider.on;
|
||||
|
||||
|
||||
// TODO: part of manager
|
||||
this.latestBlockNumber = undefined;
|
||||
this.latestGasPrice = undefined;
|
||||
this.latestBlock = undefined;
|
||||
this.latest10Blocks = [];
|
||||
|
||||
|
||||
// TODO: part of manager
|
||||
this.blockNumberObservable = null;
|
||||
this.gasPriceObservable = null;
|
||||
this.blockObservable = null;
|
||||
this.blockTimeObservable = null;
|
||||
|
||||
this.newBlocksSubscription = null;
|
||||
this.intervalTracker = null;
|
||||
this.callables = [];
|
||||
}
|
||||
|
||||
init() {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
if (this.disableDatabase === true) {
|
||||
this._db = new NullDatabase("", this.events);
|
||||
} else {
|
||||
|
@ -50,19 +63,35 @@ export default class Subspace {
|
|||
this.networkId = netId;
|
||||
});
|
||||
|
||||
this.web3.getBlock('latest').then(block => {
|
||||
this.latestBlockNumber = block.number;
|
||||
|
||||
if(this.isWebsocketProvider){
|
||||
this._initNewBlocksSubscription();
|
||||
} else {
|
||||
this.options.callInterval = this.options.callInterval || 1000;
|
||||
this._initCallInterval();
|
||||
const block = await this.web3.getBlock('latest');
|
||||
const gasPrice = await this.web3.getGasPrice();
|
||||
|
||||
// Preload <= 10 blocks to calculate avg block time
|
||||
if(block.number !== 0){
|
||||
const minBlock = Math.max(0, block.number - 9);
|
||||
for(let i = minBlock; i < block.number; i++){
|
||||
this.latest10Blocks.push(this.web3.getBlock(i));
|
||||
}
|
||||
|
||||
resolve();
|
||||
})
|
||||
})
|
||||
this.latest10Blocks = await Promise.all(this.latest10Blocks);
|
||||
}
|
||||
|
||||
// TODO: part of manager
|
||||
this.latestBlockNumber = block.number;
|
||||
this.latestGasPrice = gasPrice;
|
||||
this.latestBlock = block;
|
||||
this.latest10Blocks.push(block);
|
||||
|
||||
if(this.isWebsocketProvider){
|
||||
this._initNewBlocksSubscription();
|
||||
} else {
|
||||
this.options.callInterval = this.options.callInterval || 1000;
|
||||
this._initCallInterval();
|
||||
}
|
||||
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
contract(contractInstance) {
|
||||
|
@ -223,6 +252,61 @@ export default class Subspace {
|
|||
return returnSub;
|
||||
}
|
||||
|
||||
_addDistinctCallable(trackAttribute, cbBuilder, subject, subjectArg = undefined) {
|
||||
if(this[trackAttribute]) return this[trackAttribute].pipe(distinctUntilChanged((a, b) => equal(a, b)));
|
||||
this[trackAttribute] = new subject(subjectArg);
|
||||
const cb = cbBuilder(this[trackAttribute]);
|
||||
cb();
|
||||
this.callables.push(cb);
|
||||
return this[trackAttribute].pipe(distinctUntilChanged((a, b) => equal(a, b)));
|
||||
}
|
||||
|
||||
trackBlock() {
|
||||
const blockCB = (subject) => () => {
|
||||
this.web3.getBlock('latest').then(block => {
|
||||
if(this.latest10Blocks[this.latest10Blocks.length - 1].number === block.number) return;
|
||||
|
||||
this.latest10Blocks.push(block);
|
||||
if(this.latest10Blocks.length > 10){
|
||||
this.latest10Blocks.shift();
|
||||
}
|
||||
subject.next(block);
|
||||
}).catch(error => subject.error(error));
|
||||
};
|
||||
return this._addDistinctCallable('blockObservable', blockCB, BehaviorSubject, this.latestBlock);
|
||||
}
|
||||
|
||||
trackBlockNumber() {
|
||||
const blockNumberCB = (subject) => () => {
|
||||
this.web3.getBlockNumber().then(blockNumber => subject.next(blockNumber)).catch(error => subject.error(error));
|
||||
};
|
||||
return this._addDistinctCallable('blockNumberObservable', blockNumberCB, BehaviorSubject, this.latestBlockNumber);
|
||||
}
|
||||
|
||||
trackGasPrice() {
|
||||
const gasPriceCB = (subject) => () => {
|
||||
this.web3.getGasPrice().then(gasPrice => subject.next(gasPrice)).catch(error => subject.error(error));
|
||||
};
|
||||
return this._addDistinctCallable('gasPriceObservable', gasPriceCB, BehaviorSubject, this.latestGasPrice);
|
||||
}
|
||||
|
||||
trackAverageBlocktime() {
|
||||
|
||||
this.trackBlock()
|
||||
|
||||
const avgTimeCB = (subject) => () => {
|
||||
const times = [];
|
||||
for (let i = 1; i < this.latest10Blocks.length; i++) {
|
||||
let time = this.latest10Blocks[i].timestamp - this.latest10Blocks[i - 1].timestamp;
|
||||
times.push(time)
|
||||
}
|
||||
const average = times.length ? Math.round(times.reduce((a, b) => a + b) / times.length) * 1000 : 0;
|
||||
subject.next(average);
|
||||
};
|
||||
return this._addDistinctCallable('blockTimeObservable', avgTimeCB, BehaviorSubject, 123456);
|
||||
}
|
||||
|
||||
|
||||
trackBalance(address, erc20Address) {
|
||||
const sub = new ReplaySubject();
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
const Web3Eth = require('web3-eth');
|
||||
const Subspace = require('../dist/index.js').default;
|
||||
|
||||
let eth = new Web3Eth("https://mainnet.infura.io/v3/562ba55287324547adbdd59b1dabc869");
|
||||
|
||||
async function run() {
|
||||
const subspace = new Subspace(eth.currentProvider);
|
||||
await subspace.init()
|
||||
|
||||
subspace.trackBlockNumber().subscribe((v) => console.log("Blocknumber", v));
|
||||
subspace.trackGasPrice().subscribe((v) => console.log("GasPrice", v));
|
||||
subspace.trackBlock().subscribe((v) => console.log("Block.difficulty", v.difficulty));
|
||||
subspace.trackAverageBlocktime().subscribe((v) => console.log("Blocktime", v));
|
||||
}
|
||||
|
||||
run()
|
Loading…
Reference in New Issue