Now with block timestamps

This commit is contained in:
Marco van Dijk 2022-03-05 17:38:58 +01:00
parent 41a6ab4ab8
commit 5aadf97278
7 changed files with 86 additions and 14 deletions

View 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;

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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} />
} }

View File

@ -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}
/> />
} }
} }