mirror of
https://github.com/stronk-dev/LivepeerEvents.git
synced 2025-07-05 10:45:10 +02:00
Now with block timestamps
This commit is contained in:
parent
41a6ab4ab8
commit
5aadf97278
15
backend/src/models/block.js
Normal file
15
backend/src/models/block.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import mongoose from 'mongoose';
|
||||||
|
|
||||||
|
const BlockSchema = new mongoose.Schema({
|
||||||
|
blockNumber: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
blockTime: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}, { timestamps: false });
|
||||||
|
|
||||||
|
const Block = mongoose.model('BlockSchema', BlockSchema);
|
||||||
|
export default Block;
|
@ -24,8 +24,12 @@ const EventSchema = new mongoose.Schema({
|
|||||||
blockNumber: {
|
blockNumber: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
blockTime: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
}
|
}
|
||||||
}, { timestamps: true });
|
}, { timestamps: false });
|
||||||
|
|
||||||
const Event = mongoose.model('Event', EventSchema);
|
const Event = mongoose.model('Event', EventSchema);
|
||||||
export default Event;
|
export default Event;
|
@ -1,5 +1,6 @@
|
|||||||
import express from "express";
|
import express from "express";
|
||||||
import Event from '../models/event';
|
import Event from '../models/event';
|
||||||
|
import Block from '../models/block';
|
||||||
const apiRouter = express.Router();
|
const apiRouter = express.Router();
|
||||||
import {
|
import {
|
||||||
API_CMC, API_L1_HTTP, API_L2_HTTP, API_L2_WS
|
API_CMC, API_L1_HTTP, API_L2_HTTP, API_L2_WS
|
||||||
@ -78,6 +79,27 @@ const BondingManagerTargetAbi = JSON.parse(BondingManagerTargetJson);
|
|||||||
const BondingManagerProxyAddr = "0x35Bcf3c30594191d53231E4FF333E8A770453e40";
|
const BondingManagerProxyAddr = "0x35Bcf3c30594191d53231E4FF333E8A770453e40";
|
||||||
const contractInstance = new web3layer2WS.eth.Contract(BondingManagerTargetAbi.abi, BondingManagerProxyAddr);
|
const contractInstance = new web3layer2WS.eth.Contract(BondingManagerTargetAbi.abi, BondingManagerProxyAddr);
|
||||||
|
|
||||||
|
let blockCache = [];
|
||||||
|
const getBlock = async function (blockNumber) {
|
||||||
|
// See if it is cached
|
||||||
|
for (const thisBlock of blockCache) {
|
||||||
|
if (thisBlock.number === blockNumber) {
|
||||||
|
return thisBlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Else get it and cache it
|
||||||
|
const thisBlock = await web3layer2.eth.getBlock(blockNumber);
|
||||||
|
console.log("Caching new block " + thisBlock.number + " mined at " + thisBlock.timestamp);
|
||||||
|
const blockObj = {
|
||||||
|
blockNumber: thisBlock.number,
|
||||||
|
blockTime: thisBlock.timestamp
|
||||||
|
};
|
||||||
|
blockCache.push(blockObj);
|
||||||
|
const dbObj = new Block(blockObj);
|
||||||
|
await dbObj.save();
|
||||||
|
return thisBlock;
|
||||||
|
}
|
||||||
|
|
||||||
// If fullsync: drop collection on DB
|
// If fullsync: drop collection on DB
|
||||||
if (fullSync) {
|
if (fullSync) {
|
||||||
console.log("dropping old data due to full synchronization");
|
console.log("dropping old data due to full synchronization");
|
||||||
@ -97,6 +119,7 @@ var BondingManagerProxyListener = contractInstance.events.allEvents(async (error
|
|||||||
} else {
|
} else {
|
||||||
console.log('Received new Event on block ' + event.blockNumber);
|
console.log('Received new Event on block ' + event.blockNumber);
|
||||||
}
|
}
|
||||||
|
const thisBlock = await getBlock(event.blockNumber);
|
||||||
// Push obj of event to cache and create a new entry for it in the DB
|
// Push obj of event to cache and create a new entry for it in the DB
|
||||||
const eventObj = {
|
const eventObj = {
|
||||||
address: event.address,
|
address: event.address,
|
||||||
@ -104,13 +127,14 @@ var BondingManagerProxyListener = contractInstance.events.allEvents(async (error
|
|||||||
transactionUrl: "https://arbiscan.io/tx/" + event.transactionHash,
|
transactionUrl: "https://arbiscan.io/tx/" + event.transactionHash,
|
||||||
name: event.event,
|
name: event.event,
|
||||||
data: event.returnValues,
|
data: event.returnValues,
|
||||||
blockNumber: event.blockNumber
|
blockNumber: thisBlock.number,
|
||||||
|
blockTime: thisBlock.timestamp
|
||||||
}
|
}
|
||||||
if(!isSyncing){
|
if (!isSyncing) {
|
||||||
const dbObj = new Event(eventObj);
|
const dbObj = new Event(eventObj);
|
||||||
await dbObj.save();
|
await dbObj.save();
|
||||||
eventsCache.push(eventObj);
|
eventsCache.push(eventObj);
|
||||||
}else{
|
} else {
|
||||||
syncCache.push(eventObj);
|
syncCache.push(eventObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,13 +160,15 @@ const doSync = function () {
|
|||||||
if (event.blockNumber > lastBlockDataAdded) {
|
if (event.blockNumber > lastBlockDataAdded) {
|
||||||
lastBlockDataAdded = event.blockNumber;
|
lastBlockDataAdded = event.blockNumber;
|
||||||
}
|
}
|
||||||
|
const thisBlock = await getBlock(event.blockNumber);
|
||||||
const eventObj = {
|
const eventObj = {
|
||||||
address: event.address,
|
address: event.address,
|
||||||
transactionHash: event.transactionHash,
|
transactionHash: event.transactionHash,
|
||||||
transactionUrl: "https://arbiscan.io/tx/" + event.transactionHash,
|
transactionUrl: "https://arbiscan.io/tx/" + event.transactionHash,
|
||||||
name: event.event,
|
name: event.event,
|
||||||
data: event.returnValues,
|
data: event.returnValues,
|
||||||
blockNumber: event.blockNumber
|
blockNumber: thisBlock.number,
|
||||||
|
blockTime: thisBlock.timestamp
|
||||||
}
|
}
|
||||||
const dbObj = new Event(eventObj);
|
const dbObj = new Event(eventObj);
|
||||||
await dbObj.save();
|
await dbObj.save();
|
||||||
@ -170,6 +196,7 @@ const handleSync = async function () {
|
|||||||
name: 1,
|
name: 1,
|
||||||
data: 1,
|
data: 1,
|
||||||
blockNumber: 1,
|
blockNumber: 1,
|
||||||
|
blockTime: 1,
|
||||||
_id: 0
|
_id: 0
|
||||||
});
|
});
|
||||||
console.log("Retrieved existing Events of size " + eventsCache.length);
|
console.log("Retrieved existing Events of size " + eventsCache.length);
|
||||||
@ -186,12 +213,18 @@ const handleSync = async function () {
|
|||||||
latestMissedDuringSync = latestBlock;
|
latestMissedDuringSync = latestBlock;
|
||||||
}
|
}
|
||||||
console.log("Parsed up to block " + lastBlockDataAdded + " out of " + latestMissedDuringSync + " blocks");
|
console.log("Parsed up to block " + lastBlockDataAdded + " out of " + latestMissedDuringSync + " blocks");
|
||||||
|
// Get all parsed blocks
|
||||||
|
blockCache = await Block.find({}, {
|
||||||
|
blockNumber: 1,
|
||||||
|
blockTime: 1
|
||||||
|
});
|
||||||
|
console.log("Retrieved existing Blocks of size " + blockCache.length);
|
||||||
doSync();
|
doSync();
|
||||||
while (isSyncRunning) {
|
while (isSyncRunning) {
|
||||||
await sleep(1000);
|
await sleep(1000);
|
||||||
console.log("Parsed " + lastBlockDataAdded + " out of " + latestMissedDuringSync + " blocks");
|
console.log("Parsed " + lastBlockDataAdded + " out of " + latestMissedDuringSync + " blocks");
|
||||||
}
|
}
|
||||||
while(syncCache.length){
|
while (syncCache.length) {
|
||||||
const liveEvents = syncCache;
|
const liveEvents = syncCache;
|
||||||
syncCache = [];
|
syncCache = [];
|
||||||
for (const eventObj of liveEvents) {
|
for (const eventObj of liveEvents) {
|
||||||
|
@ -1,13 +1,23 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
const Block = (obj) => {
|
const Block = (obj) => {
|
||||||
|
const thisEpoch = obj.time;
|
||||||
|
var dateObj = new Date(0);
|
||||||
|
dateObj.setUTCSeconds(thisEpoch);
|
||||||
|
const [thisDate, thisTime] = dateObj.toISOString().split('T');
|
||||||
return (
|
return (
|
||||||
<div className="rowAlignLeft" style={{ width: '100%' }}>
|
<div className="rowAlignLeft" style={{ width: '100%' }}>
|
||||||
<span className="rowAlignRight elipsText">
|
<span className="rowAlignRight elipsText">
|
||||||
Block {obj.block}
|
<a className="selectOrch" href={"https://arbiscan.io/block/" + obj.block}>
|
||||||
|
🔗{obj.block}
|
||||||
|
</a>
|
||||||
|
<p className="darkText">📅{thisDate} - {thisTime.split('.')[0]} </p>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default Block;
|
export default Block;
|
@ -63,6 +63,7 @@ export const getEvents = () => async dispatch => {
|
|||||||
let currentTx = "";
|
let currentTx = "";
|
||||||
let currentUrl = "";
|
let currentUrl = "";
|
||||||
let currentBlock = 0;
|
let currentBlock = 0;
|
||||||
|
let currentTime = 0;
|
||||||
// Current Event we are processing
|
// Current Event we are processing
|
||||||
let eventType = ""; // Named type: Withdraw, Update, Claim, Reward, Activate, Unbond, Stake
|
let eventType = ""; // Named type: Withdraw, Update, Claim, Reward, Activate, Unbond, Stake
|
||||||
let eventDescription = ""; // Descriptive text, also containing Amount, AmountOther and When
|
let eventDescription = ""; // Descriptive text, also containing Amount, AmountOther and When
|
||||||
@ -89,6 +90,7 @@ export const getEvents = () => async dispatch => {
|
|||||||
currentTx = eventObj.transactionHash;
|
currentTx = eventObj.transactionHash;
|
||||||
currentUrl = eventObj.transactionUrl;
|
currentUrl = eventObj.transactionUrl;
|
||||||
currentBlock = eventObj.blockNumber;
|
currentBlock = eventObj.blockNumber;
|
||||||
|
currentTime = eventObj.blockTime;
|
||||||
}
|
}
|
||||||
// New transaction found
|
// New transaction found
|
||||||
if (currentTx !== eventObj.transactionHash) {
|
if (currentTx !== eventObj.transactionHash) {
|
||||||
@ -150,7 +152,8 @@ export const getEvents = () => async dispatch => {
|
|||||||
eventColour,
|
eventColour,
|
||||||
transactionHash: currentTx,
|
transactionHash: currentTx,
|
||||||
transactionUrl: currentUrl,
|
transactionUrl: currentUrl,
|
||||||
transactionBlock: currentBlock
|
transactionBlock: currentBlock,
|
||||||
|
transactionTime: currentTime
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,6 +179,7 @@ export const getEvents = () => async dispatch => {
|
|||||||
currentTx = eventObj.transactionHash;
|
currentTx = eventObj.transactionHash;
|
||||||
currentUrl = eventObj.transactionUrl;
|
currentUrl = eventObj.transactionUrl;
|
||||||
currentBlock = eventObj.blockNumber;
|
currentBlock = eventObj.blockNumber;
|
||||||
|
currentTime = eventObj.blockTime;
|
||||||
}
|
}
|
||||||
// Always split off WithdrawStake as a separate Withdraw Event
|
// Always split off WithdrawStake as a separate Withdraw Event
|
||||||
if (eventObj.name === "WithdrawStake") {
|
if (eventObj.name === "WithdrawStake") {
|
||||||
@ -193,7 +197,8 @@ export const getEvents = () => async dispatch => {
|
|||||||
eventColour: withdrawStakeColour,
|
eventColour: withdrawStakeColour,
|
||||||
transactionHash: currentTx,
|
transactionHash: currentTx,
|
||||||
transactionUrl: currentUrl,
|
transactionUrl: currentUrl,
|
||||||
transactionBlock: currentBlock
|
transactionBlock: currentBlock,
|
||||||
|
transactionTime: currentTime
|
||||||
});
|
});
|
||||||
} else if (eventObj.name === "WithdrawFees") {
|
} else if (eventObj.name === "WithdrawFees") {
|
||||||
const amount = parseFloat(eventObj.data.amount) / 1000000000000000000;
|
const amount = parseFloat(eventObj.data.amount) / 1000000000000000000;
|
||||||
@ -210,7 +215,8 @@ export const getEvents = () => async dispatch => {
|
|||||||
eventColour: withdrawStakeColour,
|
eventColour: withdrawStakeColour,
|
||||||
transactionHash: currentTx,
|
transactionHash: currentTx,
|
||||||
transactionUrl: currentUrl,
|
transactionUrl: currentUrl,
|
||||||
transactionBlock: currentBlock
|
transactionBlock: currentBlock,
|
||||||
|
transactionTime: currentTime
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Always split off TranscoderUpdate as a separate Update Event
|
// Always split off TranscoderUpdate as a separate Update Event
|
||||||
@ -228,7 +234,8 @@ export const getEvents = () => async dispatch => {
|
|||||||
eventColour: updateColour,
|
eventColour: updateColour,
|
||||||
transactionHash: currentTx,
|
transactionHash: currentTx,
|
||||||
transactionUrl: currentUrl,
|
transactionUrl: currentUrl,
|
||||||
transactionBlock: currentBlock
|
transactionBlock: currentBlock,
|
||||||
|
transactionTime: currentTime
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Always split off EarningsClaimed as a separate Claim Event
|
// Always split off EarningsClaimed as a separate Claim Event
|
||||||
@ -259,7 +266,8 @@ export const getEvents = () => async dispatch => {
|
|||||||
eventColour: claimColour,
|
eventColour: claimColour,
|
||||||
transactionHash: currentTx,
|
transactionHash: currentTx,
|
||||||
transactionUrl: currentUrl,
|
transactionUrl: currentUrl,
|
||||||
transactionBlock: currentBlock
|
transactionBlock: currentBlock,
|
||||||
|
transactionTime: currentTime
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Always split off Reward as a separate Reward Event
|
// Always split off Reward as a separate Reward Event
|
||||||
@ -279,7 +287,8 @@ export const getEvents = () => async dispatch => {
|
|||||||
eventColour: rewardColour,
|
eventColour: rewardColour,
|
||||||
transactionHash: currentTx,
|
transactionHash: currentTx,
|
||||||
transactionUrl: currentUrl,
|
transactionUrl: currentUrl,
|
||||||
transactionBlock: currentBlock
|
transactionBlock: currentBlock,
|
||||||
|
transactionTime: currentTime
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Extract useful info from other types of Event
|
// Extract useful info from other types of Event
|
||||||
|
@ -44,7 +44,7 @@ const EventButton = (obj) => {
|
|||||||
|
|
||||||
let blockNumber;
|
let blockNumber;
|
||||||
if (obj.isFirstOfBlock) {
|
if (obj.isFirstOfBlock) {
|
||||||
blockNumber = <Block block={obj.isFirstOfBlock} />
|
blockNumber = <Block block={obj.isFirstOfBlock} time={obj.time} />
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,6 +141,7 @@ const EventViewer = (obj) => {
|
|||||||
key={eventObj.transactionHash + idx}
|
key={eventObj.transactionHash + idx}
|
||||||
eventObj={eventObj}
|
eventObj={eventObj}
|
||||||
isFirstOfBlock={prevBlock}
|
isFirstOfBlock={prevBlock}
|
||||||
|
time={eventObj.transactionTime}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user