# Decoding vote lock up periods A more detailed explanation of this [SE question/answer](https://substrate.stackexchange.com/questions/3736/decoding-democracy-voted). In the answer of Jaco [here](https://substrate.stackexchange.com/a/3737/234) he mentions : > *The aye (bool) & conviction (enum) is encoded together as a single byte. The top-most bit indicated the true/false, the remaining bits indicates the conviction.* A byte is a total of 8 bits. These 8 bits represent 8 positions and every position has a specific value as shown below : |position | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | |--- | --- | --- | --- | --- | --- |--- |--- |--- | |bit | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | |value | 128 | 64 | 32 | 16 | 8 | 4 | 2 |1 | In the above table I used the binary number `10001010` as an example which results in decimal in the number 138. The reason why it results in the number 138 is the values under each bit in the above table. If you add the values that are under the `1`s so 128 + 8 + 2 you get 138. In other words, the `1`s in the binary number tells you which bits are activated so which values you can add and which not. So, back to our `vote`. Since we know that : - `aye` + `conviction`is a byte = 8 bits and - that `aye` is the top-most bit then we can add `vote` in the above table and in the corresponding bit positions and we will have : <body> <table> <tr> <th>position</th> <th>8</th> <th>7</th> <th>6</th> <th>5</th> <th>4</th> <th>3</th> <th>2</th> <th>1</th> </tr> <tr> <td>bit </td> <td>1</td> <td>0</td> <td>0</td> <td>0</td> <td>1</td> <td>0</td> <td>1</td> <td>0</td> </tr> <tr> <td>value</td> <td style="color:#D6769D">128</td> <td style="color:#3498db ">64</td> <td style="color:#3498db">32</td> <td style="color:#3498db">16</td> <td style="color:#3498db">8</td> <td style="color:#3498db">4</td> <td style="color:#3498db">2</td> <td style="color:#3498db">1</td> </tr> <tr> <td>vote</td> <td style="color:#D6769D">aye</td> <td colspan="7" style="color:#3498db" align="center">conviction</td> </tr> </table> </body> ## Vote -> 128 Back to the SE question/answer, Jaco says that : > *So in your example, 128 would be an aye with no conviction.* Why ? The number 128 in binary is `10000000`. Again : - I will put every bit of this binary number in our table above and - at the same time make green only the bits that are 1 to show that only these bits are "activated". So the table becomes : <body> <table> <tr> <th>position</th> <th>8</th> <th>7</th> <th>6</th> <th>5</th> <th>4</th> <th>3</th> <th>2</th> <th>1</th> </tr> <tr> <td>bit</td> <td style="color:#28b463">1</td> <td style="color:#95a5a6">0</td> <td style="color:#95a5a6">0</td> <td style="color:#95a5a6">0</td> <td style="color:#95a5a6">0</td> <td style="color:#95a5a6">0</td> <td style="color:#95a5a6">0</td> <td style="color:#95a5a6">0</td> </tr> <tr> <td>value</td> <td style="color:#28b463">128</td> <td style="color:#95a5a6">64</td> <td style="color:#95a5a6">32</td> <td style="color:#95a5a6">16</td> <td style="color:#95a5a6">8</td> <td style="color:#95a5a6">4</td> <td style="color:#95a5a6">2</td> <td style="color:#95a5a6">1</td> </tr> <tr> <td>vote</td> <td>aye</td> <td colspan="7" style="color:" align="center">conviction</td> </tr> </table> </body> So now to find the values of `aye` and `conviction` we again (as in the beginning) : - check the `bit` row and see if it is a `1` or a `0` or in other words which bit is activated and which not. - From the table (that represents the value of `vote` = 128) we see: - that the bit for `aye` is activated (it is `1`) so its value is true (since it is a boolean). - we also see that all the bits that represent the `conviction` are deactivated since they are all `0`. This means that we cannot add any of the values (3rd row) that are under these bits so the value of `conviction` results to `0`. Based on this [map](https://github.com/paritytech/substrate/blob/42044053b5895991d06ddc776e45da61c6462c78/frame/democracy/src/conviction.rs#L57L63) we see that a value of 0 corresponds to `conviction` = `None`. ## Vote -> 132 Let's see another example of vote 132 as shown in this [extrinsic](https://polkadot.subscan.io/extrinsic/14418422-2?event=14418422-34) in block [#14418422](https://polkadot.subscan.io/block/14418422) The number 132 in binary is 10000100. Now our table becomes : <body> <table> <tr> <th>position</th> <th>8</th> <th>7</th> <th>6</th> <th>5</th> <th>4</th> <th>3</th> <th>2</th> <th>1</th> </tr> <tr> <td>bit</td> <td style="color:#28b463">1</td> <td style="color:#95a5a6">0</td> <td style="color:#95a5a6">0</td> <td style="color:#95a5a6">0</td> <td style="color:#95a5a6">0</td> <td style="color:#28b463">1</td> <td style="color:#95a5a6">0</td> <td style="color:#95a5a6">0</td> </tr> <tr> <td>value</td> <td style="color:#28b463">128</td> <td style="color:#95a5a6">64</td> <td style="color:#95a5a6">32</td> <td style="color:#95a5a6">16</td> <td style="color:#95a5a6">8</td> <td style="color:#28b463">4</td> <td style="color:#95a5a6">2</td> <td style="color:#95a5a6">1</td> </tr> <tr> <td>vote</td> <td>aye</td> <td colspan="7" style="color:" align="center">conviction</td> </tr> </table> </body> Again to find the values of `aye` and `conviction` we : - check the `bit` row and see if it is a `1` or a `0` or in other words which bit is activated and which not. - From this table (that represents the value of `vote` = 132) we see: - that the bit for `aye` is activated (it is `1`) so its value is true (since it is a boolean). - we also see that from the bits that represent the `conviction` there is one that is active. The value of this bit (3rd row) is 4 so the value of `conviction` results also to `4`. Based on this [map](https://github.com/paritytech/substrate/blob/42044053b5895991d06ddc776e45da61c6462c78/frame/democracy/src/conviction.rs#L57L63) we see that a value of 4 corresponds to `conviction` = `Locked4x`. ## Confirm with js code We can also double check that what we just concluded is correct by running this simple js code : ```javascript const { ApiPromise, WsProvider } = require('@polkadot/api'); async function main () { const wsProvider = new WsProvider('wss://rpc.polkadot.io'); const api = await ApiPromise.create({ provider: wsProvider }); const apiAt = await api.at("0x3cf058c7d1704d94007dcdba922c211a2f9691b53f03448b45ca54652a0cfcad"); const events = await apiAt.query.system.events(); console.log(`${JSON.stringify(events.toHuman())}`); } main().catch(console.error).finally(() => process.exit()); ``` ***Sidenote*** *I would recommend to install `jq` with ` brew install jq` and then run the script with `jq` for example `node main.js | jq '.'` so that the json result is more readable.* With the above code I just retrieved all the events in the corresponding block and I see that there is an event `voted` : ```json "event": { "method": "Voted", "section": "democracy", "index": "0x0e0b", "data": [ "15Doapat3eiJR31q21u5PBiLrkWmSmP55mGkLwYCKrbnp3j7", "106", { "Standard": { "vote": { "conviction": "Locked4x", "vote": "Aye" }, "balance": "1,000,000,000,000" } } ] }, ``` and it looks that the values of `aye` and `conviction` are the same as what we concluded by checking the bits. ## Testing yourself You can try it out yourself simply by : - converting the number of vote into binary - fill the corresponding table - calculating the `aye` and `conviction` - confirming by querying the block and finding the event Voted (with the js code) ## Code explanation Regarding the [Vote decoding code](https://github.com/paritytech/substrate/blob/42044053b5895991d06ddc776e45da61c6462c78/frame/democracy/src/vote.rs#L44-L53) that Jaco shares : ```rust impl Decode for Vote { fn decode<I: Input>(input: &mut I) -> Result<Self, codec::Error> { let b = input.read_byte()?; Ok(Vote { aye: (b & 0b1000_0000) == 0b1000_0000, conviction: Conviction::try_from(b & 0b0111_1111) .map_err(|_| codec::Error::from("Invalid conviction"))?, }) } } ``` It uses 2 concepts called : - bitmasks *With a bitmask we want to activate the bit(s) we are interested in and the bits we are not interested we set to `0`.* - [bitwise operation](https://www.techtarget.com/whatis/definition/bitwise) *we use the `&` operation to actually get value of that particular bit.* to do exactly what we did previously. ### `aye` In this line of code ```rust aye: (b & 0b1000_0000) == 0b1000_0000, ``` the bitmask `0b1000_0000` is used to get the value of `aye`. More in detail : **0b** : just denotes that what follows is a binary number **1000_0000** : this is the 1st bitmask used and if you notice the first bit is 1 and the rest is 0. **Why?** In this line of code we are interested in the bit in position 8 (since we want to get the value of `aye`) so we only "activate" (set to 1) that position and the rest we set to `0`. **&**: So we do the AND bitwise operation between - our number/byte `b` (the value of `vote` so the value of `aye`+`conviction` together) and - the bitmask `0b1000_0000` and - in that way we get only the value of `aye` from vote. So in a nutshell, we put the value `1` to the appropriate place/bit and then we use the `&` operation to get value of that particular bit. ### `conviction` The conviction we get with this code/bitmask ```rust (b & 0b0111_1111) ``` Here the bitmask `0b0111_1111` is used and if you notice is the exact reverse of the bitmask used for `aye`. More in detail : **0b** : just denotes that what follows is a binary number **0111_1111** : this is the 2nd bitmask used and here the first bit is 0 and the rest is all 1. **Why?** Because now we want to deactivate the bit that represents the `aye` and activate all the bit(s) that represent the `conviction`. **&** : we use the `&` operation to actually get value of the bits we are interested. So we do the `AND` bitwise operation between : - our number/byte `b` (the value of vote that includes the value of `aye`+`conviction` together) and - the bitmask `0b0111_1111` and - in that way we get only the value of `conviction` from vote. ### Relevant Resources - [Bit numbering](https://en.wikipedia.org/wiki/Bit_numbering) - [Decimal to Binary converter](https://www.rapidtables.com/convert/number/decimal-to-binary.html) - [What is bit masking?](https://stackoverflow.com/a/10493604)