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