Coder Social home page Coder Social logo

statediff's Introduction

State exploration for filecoin (lotus centric)

This tool provides functionality for exploration and comparing changes to filecoin state.

Contents

CLI

go get github.com/filecoin-project/statediff/cmd/statediff

Usage

See what state change is expected by a test vector:

statediff vector --file vector.json 

See what state changed on the local lotus chain across a block or message:

statediff chain --expand-actors all bafy...

Compare two roots in a CAR

statediff car --file export.car <left CID> <right CID>

API

Other tools working with state trees can access statediff by importing github.com/filecoin-project/statediff.

  • Diff(context.Context, blockstore.Blockstore, a, b cid.Cid, ...Option) string Diff generates a textual unified diff between stateroots a and b. State objects are retreived out of the provided blockstore.
    • Options can be used to control the amount of recursion / expansion performed. In particular, ExpandActors will perform recursive introspection into each individual actor account with a differing HEAD state, and ExpandActorByCid will selectively expand actor accounts based on provided CIDs.

Web

The web viewer (stateexplorer) provides a JSON transformation layer and interactive state tree exploration.

git clone https://github.com/filecoin-project/statediff
go generate ./...

Note: you need npm installed for go generate to properly bundle frontend assets.

When running in production, either use the provided docker image, or run the explorer in its self-contained-binary form (assets are bundled via the go generate above.)

go run ./cmd/stateexplorer explore --bind 0.0.0.0:33333 --api $(cat ~/.lotus/token):$(cat ~/.lotus/api)

If not explicitly provided as an argument, statediff/stateexplorer will attempt to locate a lotus instance running on the same host by probing your home directory.

In development mode, assets can be loaded from disk so that changes are reflected on reload.

go run ./cmd/stateexplorer explore --bind 0.0.0.0:33333 --assets .

License

Dual-licensed under MIT + Apache 2.0

statediff's People

Contributors

alanshaw avatar dependabot[bot] avatar f8-ptrk avatar galargh avatar iand avatar raulk avatar unjapones avatar web-flow avatar willscott avatar zenground0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

statediff's Issues

Cache Headers

stateql headers should be conditioned on input - if query is rooted at an immutable cid or height below reorg potential then the response should have strong cache headers.

Fast Responses

Responses are often slower than they need to be, and there are a set of low-hanging work items that will make performance notably faster (we believe)

  • #81 is important for not doing extra unneeded work
  • Support split data stores (e.g. a local car with state roots) so that api calls can be skipped on commonly needed data blocks.
  • support an object cache of commonly accessed realized ipld.Node's, so that cbor decodes for these hot head requested items can be amortized.

graphql queries

graphql may be an natural way for expressing data out of the state root. requirements still pretty vague

Filters

It would be potentially nice to allow the All accessors on Maps and Lists to take a filter fragment that allows filtering on direct properties if not full subtrees.

dump state tree to json

Some forms of analysis may prefer a json view rather than the IPLD data store for queries over a state tree. Support a way to transform between these views

Support additional map accessors

currently there isn't a way to get all key-value tuples efficiently off an ipld map. You would need to ask for all keys, and then in another set of queries ask for values for keys to get the mapping.

We should provide an All like lists have, which return a list of structs containing both the key and value for entries.

Better html ux

  • back/previous button for actor filtering / paging is janky (#29 )
  • could benefit from standard framework for ux rather than just some bootstrap css

point-in-time, interactive state examination at epoch N via progressive HTML

statediff already spiders down the state tree, dives into ADT data structures, and binds them to high-level objects. This allows us to go from a IPLD state tree, into a big typed struct that represents the state in a way that's inspectable (and diffable).

It uses a read-through CBORStore that falls back to RPC calls to fetch objects from a client.

The goal is to use these mechanics to enable point-in-time, interactive state examination at a given epoch.

The experience/flow we planned is:

  1. Via CLI, call statediff providing an RPC endpoint and an epoch to examine.
  2. statediff populates an initial, single-page, high-level HTML, with nodes that can be expanded.
  3. As you expand those nodes, we progressively enhance in the HTML with the new content.

Time based and interval queries for integration with grafana

I've been playing with the graphql api in https://observablehq.com/d/4e09dcb851b5ed05 โ€“ it's a really helpful tool for developing an understanding of the filecoin data model, and for creating useful visualisation of how the state changes over time...

We already have the Heights query which allows us to get a contiguous range of epochs... but for longer range queries, you can end up asking for with waaay more data than you need. Something like an interval parameter would be nice:

Heights(from: Int, to: Int, interval: Int) - get epochs between from amd to every interval apart.

Going further.... heights are a proxy for time that is specific to Filecoin. What if we supported the more universal concept of TIME! This would let us integrate statediff directly with grafana, via https://grafana.com/grafana/plugins/fifemon-graphql-datasource?src=grafana_add_ds

e.g.

TimeRange(fromUnixEpoch: Int!, toUnixEpoch: Int!): [LotusBlockHeader!]!
query {
  TimeRange(fromUnixEpoch:"$__from", toUnixEpoch:"$__to"){
    Time # Int! calculated unixEpoch in seconds
    Height 
    ParentStateRoot {
      Actors{
        At(key:"f099") {
          Balance
        }
      }
    }
  }
}

basically, can we have the grapql equivelant of these SQL functions: https://github.com/filecoin-project/sentinel-visor/blob/5bef7da1e9a6aead50d6585fc3e08ba582d7c354/storage/migrations/21_height_functions.go#L11-L17

Of note... Once we point grafana at something, it tends to get a lot of queries, and humans love to press the "show me all the date for last year" button... which prompted the suggestion about the interval parameter.

clean up amt mappings

expected implicit structures:

[Miner]
PreCommittedSectors HAMT[SectorNumber]SectorPreCommitOnChainInfo
[Init]
AddressMap HAMT[Address]ActorID
[VerifReg]
Verifiers HAMT[Address]DataCap
VerifiedClients HAMT[Address]DataCap
[Market]
PendingProposals HAMT[DealCid]DealProposal
EscrowTable HAMT[Address]TokenAmount
LockedTable HAMT[Address]TokenAmount
DealOpsByEpoch HAMT[ChainEpoch]HAMT[uintKey]DealID
[Multisig]
PendingTxns HAMT[TxnID]Transaction
[Power]
CronEventQueue HAMT[ChainEpoch]CronEvent
Claims HAMT[Address]Claim
ProofValidationBatch HAMT[AddrKey]AMT[uint64]SealVerifyInfo

ref: https://github.com/filecoin-project/statediff/blob/master/examine.go#L227-L258

cli command to provide a CAR file and generate a diff from two roots

To replace the library usage here with an execution of the statediff binary:

https://github.com/filecoin-project/lotus/blob/b1d251e9502dab68eaa93d25e4d4843d0470bc77/conformance/runner_test.go#L277-L284

I'm thinking of something along the lines of:

$ # statediff --car /path/to/car root_cid_1 root_cid_2
$ statediff --car /path/to/car bafy2bzacedegvywl7nddo6gqzodjh7vbyfzqzdqwzeli6kz3mms3yz2udylru bafy2bzacedgvyh2n6esbu3c552ae35nvbnlb3dyw5lrcoxeteg22yup55uqpq

Blocking filecoin-project/lotus#3666.

consider rename to 'statetool'

This tool is quickly doing more than just 'diff' - examination of a single state tree in various forms. some other name may be more appropriate.

allow non-tipset roots in html view

html cid is expected to be either a tipset from lotus or a stateroot type.
It should at least support also cid's of actor heads, and ideally should attempt all the various decodings of the cbor until it finds one that works.

Limit rendered bitfield image width

Big bitfields produce reeeeeally wide images. Limit width to something likely to fit on a screen, like 1000px.

Though it could be complicated. There's nothing that essentially limits the magnitude of the numbers in any bitfield, only the number of runs. So a bitfield could possibly have numbers in the range 2**60, which is going to be a really big image.

This line ๐Ÿ‘‡ is a bitfield image I plucked from state.

download

install instructions won't work

I'm assuming those instructions are for installing the statediff binary. There are several reasons why they won't work:

  • there are local directory replace directives that will not be picked up by go get.
  • the go generate ./... command makes no sense.

root cid can have multiple options. allow choosing between them

car headers provide an array. test vectors have a pre and post root. the current tipset of the chain is a list.
Currently the 'current' button in the html view arbitrarily picks the first cid. it should probably auto expand to the different potential roots.

export json of actor state

allow partially destructured exports at an actor level, to support reasonable efficiency of queries interested in how an individual actor (by address)'s state has changed over epochs.

IPLD schema based URLS

currently, getting json of specific parts of the state tree is done via urls of the form
/cid?cid=<cid>&as=<type>
It would be more useful, potentially to have URLs structured semantically:
/filecoinblockhash/t06/Claims/t01475/QAPower

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.