github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/iavl/cmd/iaviewer/README.md (about) 1 # IaViewer 2 3 `iaviewer` is a utility to inspect the contents of a persisted iavl tree, given (a copy of) the leveldb store. 4 This can be quite useful for debugging, especially when you find odd errors, or non-deterministic behavior. 5 Below is a brief introduction to the tool. 6 7 ## Installation 8 9 Once this is merged into the official repo, master, you should be able to do: 10 11 ```shell 12 go get github.com/tendermint/classic/iavl 13 cd ${GOPATH}/src/github.com/tendermint/classic/iavl 14 make get_vendor_deps 15 make install 16 ``` 17 18 ## Using the tool 19 20 First make sure it is properly installed and you have `${GOPATH}/bin` in your `PATH`. 21 Typing `iaviewer` should run and print out a usage message. 22 23 ### Sample databases 24 25 Once you understand the tool, you will most likely want to run it on captures from your 26 own abci app (built on cosmos-sdk or weave), but as a tutorial, you can try to use some 27 captures from an actual bug I found in my code... Same data, different hash. 28 29 ```shell 30 mkdir ./testdata 31 cd ./testdata 32 curl -L https://github.com/iov-one/iavl/files/2860877/bns-a.db.zip > bns-a.db.zip 33 unzip bns-a.db.zip 34 curl -L https://github.com/iov-one/iavl/files/2860878/bns-b.db.zip > bns-b.db.zip 35 unzip bns-b.db.zip 36 ``` 37 38 Now, if you run `ls -l`, you should see two directories... `bns-a.db` and `bns-b.db` 39 40 ### Inspecting available versions 41 42 ```shell 43 iaviewer versions ./bns-a.db 44 ``` 45 46 This should print out a list of 20 versions of the code. Note the the iavl tree will persist multiple 47 historical versions, which is a great aid in forensic queries (thanks Tendermint team!). For the rest 48 of the cases, we will consider only the last two versions, 190257 (last one where they match) and 190258 49 (where they are different). 50 51 ### Checking keys and app hash 52 53 First run these two and take a quick a look at the output: 54 55 ```shell 56 iaviewer data ./bns-a.db 57 iaviewer data ./bns-a.db 190257 58 ``` 59 60 Notice you see the different heights and there is a change in size and app hash. 61 That's what happens when we process a transaction. Let's go further and use 62 the handy tool `diff` to compare two states. 63 64 ```shell 65 iaviewer data ./bns-a.db 190257 > a-last.data 66 iaviewer data ./bns-b.db 190257 > b-last.data 67 68 diff a-last.data b-last.data 69 ``` 70 71 Same, same :) 72 But if we take the current version... 73 74 ```shell 75 iaviewer data ./bns-a.db 190258 > a-cur.data 76 iaviewer data ./bns-b.db 190258 > b-cur.data 77 78 diff a-cur.data b-cur.data 79 ``` 80 81 Hmmm... everything is the same, except the hash. Odd... 82 So odd that I [wrote an article about it](https://medium.com/@ethan.frey/tracking-down-a-tendermint-consensus-failure-77f6ff414406) 83 84 And finally, if we want to inspect which keys were modified in the last block: 85 86 ```shell 87 diff a-cur.data a-last.data 88 ``` 89 90 You should see 6 writes.. the `_i.usernft_*` are the secondary indexes on the username nft. 91 `sigs.*` is setting the nonce (if this were an update, you would see a previous value). 92 And `usrnft:*` is creating the actual username nft. 93 94 ### Checking the tree shape 95 96 So, remember above, when we found that the current state of a and b have the same data 97 but different hashes. This must be due to the shape of the iavl tree. 98 To confirm that, and possibly get more insights, there is another command. 99 100 ```shell 101 iaviewer shape ./bns-a.db 190258 > a-cur.shape 102 iaviewer shape ./bns-b.db 190258 > b-cur.shape 103 diff a-cur.shape b-cur.shape 104 ``` 105 106 Yup, that is quite some difference. You can also look at the tree as a whole. 107 So, stretch your terminal nice and wide, and... 108 109 ```shell 110 less a-cur.shape 111 ``` 112 113 It has `-5 ` for an inner node of depth 5, and `*6 ` for a leaf node (data) of depth 6. 114 Indentation also suggests the shape of the tree. 115 116 Note, if anyone wants to improve the visualization, that would be awesome. 117 I have no idea how to do this well, but at least text output makes some 118 sense and is diff-able.