Public
Edited
Dec 22, 2022
Insert cell
Insert cell
Insert cell
allCCProviders = [...(await FileAttachment("allCCProviders.json").json())].sort()
Insert cell
x = (await client.stateGetActor('f0127595', tipSetKey))
Insert cell
y = (await client.stateMinerInfo('f0127595', tipSetKey))
Insert cell
minerData = {
const owners = new Set()
let count = 0
let totalMinerBalance = 0n
for (const minerId of allCCProviders) {
count++
console.log('Jim', minerId)
const minerActor = (await client.stateGetActor(minerId, tipSetKey))
const minerInfo = (await client.stateMinerInfo(minerId, tipSetKey))
owners.add(minerInfo.Owner)
totalMinerBalance += BigInt(minerActor.Balance)
yield {
count,
minerId,
totalMinerBalance,
owners
}
}
}
Insert cell
Insert cell
ownerData = {
let count = 0
let totalOwnerBalance = 0n
const ownersSorted = [...owners].sort()
for (const address of ownersSorted) {
count++
const actor = (await client.stateGetActor(address, tipSetKey))
totalOwnerBalance += BigInt(actor.Balance)
yield {
count,
address,
totalOwnerBalance
}
}
}
Insert cell
filecoinNumber = import('https://cdn.skypack.dev/pin/@glif/filecoin-number@v2.0.0-beta.0-iQnBkhznGjB3HsyiyYB8/mode=imports,min/optimized/@glif/filecoin-number.js')
Insert cell
FilecoinNumber = filecoinNumber.FilecoinNumber
Insert cell
totalMinerBalance = Number(new FilecoinNumber(minerData.totalMinerBalance, 'attofil').toFil())
Insert cell
totalOwnerBalance = Number(new FilecoinNumber(ownerData.totalOwnerBalance, 'attofil').toFil())
Insert cell
totalMinerPlusOwnerBalance = totalMinerBalance + totalOwnerBalance
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(), 7)
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')).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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more