Public
Edited
Sep 21, 2023
4 forks
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
await client.version()
Insert cell
chainHead = await client.chainHead()
Insert cell
Insert cell
Insert cell
viewof interactiveEpoch = html`<input type=range min=${currentEpoch - 5000} max=${currentEpoch} value=${currentEpoch - 1} style="width: 100%">`
Insert cell
selectedEpoch = {
// return 142500
return interactiveEpoch
}
Insert cell
selectedDate = epochToDate(selectedEpoch).toISOString()
Insert cell
Insert cell
tipSet = [...tipSetKey].map(obj => obj['/']).sort().join(',')

Insert cell
Insert cell
Insert cell
minerCount = selectedMinerIndexes.length
Insert cell
Insert cell
maxElapsed = 10 * 60 * 1000
Insert cell
Insert cell
Insert cell
minTimestamp = dateFns.subDays(new Date(), 14)
Insert cell
Insert cell
Insert cell
Insert cell
allMiners = (await client.stateListMiners(tipSetKey)).sort(sortMiners)
Insert cell
sortMiners = function (a, b) { return Number(a.slice(1)) - Number(b.slice(1)) }
Insert cell
allMiners.slice(-5)
Insert cell
Insert cell
import { annotatedMinerIndexes } from '@jimpick/provider-quest-feeds'
Insert cell
// annotatedMinerIndexes
Insert cell
selectedMinerIndexes = {
let miners = []

const recentMinerSet = new Set()
const recentAveragesMinerSet = new Set()
for (const miner of Object.keys(minerPowerLatestReport.miners)) {
if (d3.isoParse(minerPowerLatestReport.miners[miner].timestamp) > minTimestamp) {
recentMinerSet.add(miner)
recentAveragesMinerSet.add(miner)
}
}

for (const miner of Object.keys(minerPowerDailyAverageReport.miners)) {
recentAveragesMinerSet.add(miner)
}
for (const miner of Object.keys(minerPowerMultidayAverageReport.miners)) {
recentAveragesMinerSet.add(miner)
}
if (subsetToScan === 'Recents') {
miners = [...recentMinerSet]
} else if (subsetToScan === 'Recents, Averages') {
miners = [...recentAveragesMinerSet]
} else if (subsetToScan === 'Newest miners, not recent') {
miners = allMiners.slice(-10000).filter(miner => !recentMinerSet.has(miner))
} else if (subsetToScan === 'All miners, not recent') {
miners = allMiners.filter(miner => !recentMinerSet.has(miner))
/*
} else if (subsetToScan === 'Legacy annotated') {
miners = annotatedMinerIndexes
*/
} else if (subsetToScan === 'All miners') {
miners = allMiners
}
return d3.shuffle(miners)
}
Insert cell
async function* minerPowerStream() {
const concurrency = 15
const callMinerPowerStream = transform(concurrency, async miner => {
try {
const minerPower = (await client.stateMinerPower(miner, tipSetKey)).MinerPower
console.log('Jim', miner, minerPower.QualityAdjPower)
return {
miner,
rawBytePower: Number(minerPower.RawBytePower),
qualityAdjPower: Number(minerPower.QualityAdjPower)
}
} catch (e) {
console.error('Fetch error', e)
return {}
}
})
const startTime = new Date()
let counter = 0
for await (const { miner, rawBytePower, qualityAdjPower } of callMinerPowerStream(selectedMinerIndexes)) {
const now = new Date()
if (rawBytePower > 0 || qualityAdjPower > 0) {
yield {
counter,
epoch: selectedEpoch,
miner,
rawBytePower,
qualityAdjPower
}
} else {
yield {
counter
}
}
counter++
if (now - startTime > maxElapsed) {
yield {
done: true,
timeout: true,
counter
}
return
}
}
}
Insert cell
// minerPowerStream()
Insert cell
minerPower = {
if (start === 0) {
yield {
state: 'paused'
}
return
}
yield {
state: 'starting'
}
let records = []
const startTime = new Date()
for await (const {counter, ...record} of minerPowerStream()) {
if (record.epoch) {
records.push(record)
}
yield {
state: "streaming",
elapsed: ((new Date()) - startTime) / 1000,
counter,
recordsLength: records.length
}
}
const endTime = new Date()
yield {
state: "done",
elapsed: (endTime - startTime) / 1000,
records,
startTime: startTime.toISOString(),
endTime: endTime.toISOString()
}
}
Insert cell
minerPower.state === 'done' && md`Miner | Raw Byte Power | Quality Adjusted Power
---|---|---
${minerPower.records.sort((a, b) => b.qualityAdjPower - a.qualityAdjPower).slice(0, maxRows).map(({ miner, rawBytePower, qualityAdjPower }) => {
let lines = `${miner} | ${bytes(rawBytePower, { mode: 'binary' })} | ${bytes(qualityAdjPower, { mode: 'binary' })}\n`
return lines
})}
`
Insert cell
maxRows = 50
Insert cell
Insert cell
LotusRPC = (await import('@filecoin-shipyard/lotus-client-rpc')).LotusRPC
Insert cell
BrowserProvider = (await import('@filecoin-shipyard/lotus-client-provider-browser')).BrowserProvider
Insert cell
schema = (await import('@filecoin-shipyard/lotus-client-schema')).mainnet.fullNode
Insert cell
Insert cell
Object.keys(schema.methods)
Insert cell
Insert cell
endpointUrl = {
return "wss://lotus.miner.report/mainnet_api/0/node/rpc/v0"
// return "wss://lotus.jimpick.com/mainnet_api/0/node/rpc/v0"
// return "https://api.node.glif.io/rpc/v0"
}
Insert cell
client = {
const provider = new BrowserProvider(endpointUrl)
return new LotusRPC(provider, { schema })
}
Insert cell
Insert cell
transform = (await import('streaming-iterables@7.1.0')).transform
Insert cell
import { epochToDate } from '@jbenet/filecoin-chain-time-calculator'
Insert cell
bytes = (await import('@jimpick/bytes-iec@3.1.0-2')).default
Insert cell
d3 = require("d3@6")
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more