Public
Edited
Sep 21, 2023
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 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
Insert cell
multiaddrsIpsLatestReport = (await fetch(`${multiaddrsIpsLatestBucketUrl}/multiaddrs-ips-latest.json`)).json()
Insert cell
minerPeerIds = {
const minerPeerIds = new Map()
for (const { miner, peerId } of multiaddrsIpsLatestReport.multiaddrsIps) {
minerPeerIds.set(miner, peerId)
}
return minerPeerIds
}
Insert cell
Insert cell
asksSubsetLatest
Insert cell
Insert cell
Insert cell
minTimestamp = dateFns.subDays(new Date(), 14)
Insert cell
Insert cell
Insert cell
Insert cell
Inputs.table([...selectedMinerIndexes].sort(sortMiners).map(i => ({miner: i})))
Insert cell
maxElapsed = 1 * 60 * 1000
Insert cell
selectedMinerIndexes = {
let miners = []

if (subsetToScan === 'Recents') {
for (const miner of minerPeerIds.keys()) {
if (latestMiners.has(miner)) miners.push(miner)
}
} else if (subsetToScan === 'No recents') {
for (const miner of minerPeerIds.keys()) {
if (!latestMiners.has(miner)) miners.push(miner)
}
} else {
miners = [...minerPeerIds.keys()]
}
return d3.shuffle(miners)
}
Insert cell
testMiner = 'f02620' // magik
Insert cell
queryAskTest = client.clientQueryAsk(minerPeerIds.get(testMiner), testMiner)
Insert cell
async function* queryAskStream() {
const concurrency = 25
const callQueryAskStream = transform(concurrency, async miner => {
const startTime = new Date()
try {
const peerId = minerPeerIds.get(miner)
const timeoutTimer = delay => new Promise(resolve => setTimeout(resolve, delay))
// console.log('Start', miner, startTime)
const queryAsk = await Promise.race([
client.clientQueryAsk(peerId, miner),
timeoutTimer(10000)
])
const endTime = new Date()
// console.log('Finished', miner, endTime, queryAsk)
if (!queryAsk) {
throw new Error('Timed out')
}

return {
miner,
seqNo: queryAsk.SeqNo,
askTimestamp: queryAsk.Timestamp,
price: queryAsk.Price,
verifiedPrice: queryAsk.VerifiedPrice,
minPieceSize: queryAsk.MinPieceSize,
maxPieceSize: queryAsk.MaxPieceSize,
expiry: queryAsk.Expiry,
startTime: startTime.toISOString(),
endTime: endTime.toISOString()
}
} catch (e) {
const endTime = new Date()
console.error('Query ask error', miner, e)
return {
miner,
error: e.message,
startTime: startTime.toISOString(),
endTime: endTime.toISOString()
}
}
})
const startTime = new Date()
let counter = 0
let errors = 0
for await (const ask of callQueryAskStream(selectedMinerIndexes)) {
const now = new Date()
if (ask.error) errors++
yield {
counter,
errors,
epoch: selectedEpoch,
...ask
}
counter++
if (now - startTime > maxElapsed) {
yield {
done: true,
timeout: true,
counter,
errors
}
return
}
}
}
Insert cell
// queryAskStream()
Insert cell
minerCount
Insert cell
asks = {
if (start === 0) {
yield {
state: 'paused'
}
return
}
yield {
state: 'starting'
}
let records = []
let totalErrors = 0
const startTime = new Date()
for await (const {counter, errors, epoch, ...record} of queryAskStream()) {
totalErrors = errors
if (!record.error && record.miner) records.push(record)
console.log('Jim record', record)
yield {
state: "streaming",
elapsed: ((new Date()) - startTime) / 1000,
counter,
recordsLength: records.length,
errors
}
}
const endTime = new Date()
yield {
state: "done",
elapsed: (endTime - startTime) / 1000,
records,
startTime,
endTime,
errors: totalErrors
}
}
Insert cell
asks.state === 'done' && md`Miner | Price | Verified Price | Min Size | Max Size
---|---|---|---|---
${asks.records.filter(({ error }) => !error).slice(0, maxRows).map(({ miner, price, verifiedPrice, minPieceSize, maxPieceSize }) => {
let lines = `${miner} | ${price} | ${verifiedPrice} | ${bytes(minPieceSize, { format: 'binary'})} | ${bytes(maxPieceSize, { format: '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 "https://lotus.miner.report/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
Multiaddr = (await require('https://bundle.run/multiaddr@9.0.1')).Multiaddr
Insert cell
Buffer = (await require('https://bundle.run/buffer@6.0.3')).Buffer

Insert cell
maddrBin = Buffer.from('BLaDBMMGf/g=', 'base64')
Insert cell
(new Multiaddr(maddrBin)).toString()
Insert cell
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