From cdf5f1c46018e05bc91a12871b876294399c4968 Mon Sep 17 00:00:00 2001 From: /alex/ Date: Fri, 27 Sep 2019 02:59:13 +0200 Subject: [PATCH 1/3] Initial RFC draft --- text/0000-trits-t3b1/0000-trits-t3b1.md | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 text/0000-trits-t3b1/0000-trits-t3b1.md diff --git a/text/0000-trits-t3b1/0000-trits-t3b1.md b/text/0000-trits-t3b1/0000-trits-t3b1.md new file mode 100644 index 00000000..1afd297b --- /dev/null +++ b/text/0000-trits-t3b1/0000-trits-t3b1.md @@ -0,0 +1,30 @@ ++ Feature name: `trits-t3b1` ++ Start date: 2019-09-27) ++ RFC PR: [iotaledger/bee-rfcs#0000](https://github.com/iotaledger/bee-rfcs/pull/0000) ++ Bee issue: [iotaledger/bee#0000](https://github.com/iotaledger/bee/issues/0000) + +# Summary + +This RFC proposes a trit encoding that stores sequences of trytes (representing the values `-13,...,0,...13`) in a `Vec` of signed bytes `i8`. It also introduces simply handling of trytes using their character equivalents `N,..Z,9,A,...M` or `9A-Z` for short. It is one of the trit encodings mentioned in RFC #10 and basically useful for displaying trinary data due to its convenient mapping to the alphabet. Instead of `0` the `9` represents the zero tryte. That is to not confuse it with the letter `O`. + +# Motivation + +WIP + + + +# Detailed design + +WIP + +# Drawbacks + +This encoding is very inefficient in terms of memory as it only uses 27 values out of 256 available in a (signed) byte and therefore should not be used for storing or transmitting trinary data. + +# Rationale and alternatives + +There is no reason to not have this encoding. Although not relevant for storage or transport it is a very helpful encoding when it comes to debugging, unit testing and logging. + +# Unresolved questions + +It is a well-known and long-time used encoding in the IOTA ecosystem, so there are no open questions around it known to the author. \ No newline at end of file From 6fa8b50a887e4a13ded57f1bdb3e8bb9c638895d Mon Sep 17 00:00:00 2001 From: /alex/ Date: Thu, 3 Oct 2019 20:59:10 +0200 Subject: [PATCH 2/3] Completed writing most of the paragraphs --- text/0000-trits-t3b1/0000-trits-t3b1.md | 85 +++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/text/0000-trits-t3b1/0000-trits-t3b1.md b/text/0000-trits-t3b1/0000-trits-t3b1.md index 1afd297b..b857c66c 100644 --- a/text/0000-trits-t3b1/0000-trits-t3b1.md +++ b/text/0000-trits-t3b1/0000-trits-t3b1.md @@ -5,17 +5,92 @@ # Summary -This RFC proposes a trit encoding that stores sequences of trytes (representing the values `-13,...,0,...13`) in a `Vec` of signed bytes `i8`. It also introduces simply handling of trytes using their character equivalents `N,..Z,9,A,...M` or `9A-Z` for short. It is one of the trit encodings mentioned in RFC #10 and basically useful for displaying trinary data due to its convenient mapping to the alphabet. Instead of `0` the `9` represents the zero tryte. That is to not confuse it with the letter `O`. +This RFC proposes a byte encoding for trit sequences of arbitrary length, which sequentially maps groups of 3 trits (trytes) to corresponding bytes starting from the left. If the last group consists of less than 3 trits (incomplete tryte), then those missing trits are assumed to be 0 and then mapped accordingly. This encoding is 3 times more memory efficient than [`t1b1`](), but only 60% as efficient as [`t5b1`](). It is a human-readable encoding that can be used anywhere a user needs to interact with trinary data, like reading IOTA addresses or entering seeds to access an account. + # Motivation -WIP +We would like to have a trinary representation that is as compact as possible and still human-readable. We could use [`t1b1`](https://github.com/Alex6323/bee-rfcs/blob/rfc-t3b1/text/0000-trits-t3b1/0000-trits-t3b1.md) which can easily be mapped onto the characters `{'-', '0', '1'}` for display. But because it uses only so few characters that are available on any keyboard those sequences would be too long for any practical purposes. And we shouldn't force users to type in more characters than absolutely necessary. + +As an example consider the following trit sequence: `-10--1--1`. Let's imagine that it represents a seed (a very bad one though) owned by some user. Rather than the whole trit sequence with the proposed `t3b1` encoding all the user would have to enter to access this account would be `BEE` (I am oversimplifying here on purpose). +### List of use-cases: +* During development for debugging, testing, and logging +* In production for displaying and inputting trinary data in wallets such as addresses or seeds +### Job stories: +When I design a UI element to enter a seed, I want it to be as convenient as possible to use, so instead of raw trits one can pick from the frequently used characters `9,A-Z`. Whether the input is valid or not can be checked easily by using a regular expressions. + +When I have to display the trinary representation of some arbitrary data, I want it to be represented only by characters that I am familiar with, yet it should be as short as possible, so I can convert that data into the `t3b1` encoding and display it in an alphabet-like format. # Detailed design -WIP +Any trit sequence will be interpreted as a sequence of trit triplets (trytes) like so: `-10|--1|--1` and then mapped to a corresponding integer from the set `{-13,...,0,...,13}` which can be stored in a signed byte `i8`. If the length of the sequence is not a multiple of 3, then the remaining trits are assumed to be `0`. The following table shows the mapping between all possible `27` trit triplets, their corresponding decimal value, and their corresponding character representation: + +| trit triplet (tryte) | decimal value | character symbol | +| -------------------- | ------------- | ---------------- | +| 000 | 0 | '9' | +| 100 | 1 | 'A' | +| -10 | 2 | 'B' | +| 010 | 3 | 'C' | +| 110 | 4 | 'D' | +| --1 | 5 | 'E' | +| 0-1 | 6 | 'F' | +| 1-1 | 7 | 'G' | +| -01 | 8 | 'H' | +| 001 | 9 | 'I' | +| 101 | 10 | 'J' | +| -11 | 11 | 'K' | +| 011 | 12 | 'L' | +| 111 | 13 | 'M' | +| --- | -13 | 'N' | +| 0-- | -12 | 'O' | +| 1-- | -11 | 'P' | +| -0- | -10 | 'Q' | +| 00- | -9 | 'R' | +| 10- | -8 | 'S' | +| -1- | -7 | 'T' | +| 01- | -6 | 'U' | +| 11- | -5 | 'V' | +| --0 | -4 | 'W' | +| 0-0 | -3 | 'X' | +| 1-0 | -2 | 'Y' | +| -00 | -1 | 'Z' | + +That table can optionally be implemented with up to 3 lookup table (LUT). + +```Rust +const TRYTEINDEX_TO_TRYTE: [[i8; 3]; 27] = [[0,0,0], [1,0,0] ...]; +const TRYTEINDEX_TO_VALUE: [i8; 27] = [0, 1, ...]; +const TRYTEINDEX_TO_CHAR: [char; 27] = ['9', 'A', ...]; +``` + +Because an `i8` can represent any number in the set `{-128,...,0,...127}` not every such number is valid. To provide type safety and perform bounds checks this proposal employs the newtype pattern to define a `Tryte` struct. This way we can profit from compile-time checks and make our code much less error prone. + +Note: For readability sake visibility modifiers are omitted. Also, since this RFC is a proposal for `T3B1` and not for the `Tryte` implementation itself it is kept simple and internal. + +```Rust +struct Tryte(i8); + +impl Tryte { + fn value(&self) -> i8 { + self.0 + } + ... +} +``` + +From that the actual encoding can be implemented using `std::vec::Vec` from Rust's standard library (optimizations are possible but excluded on purpose in this RFC). + +```Rust +struct T3B1(Vec); +``` + +```Rust +impl Encoding for T3B1 { + ... +} +``` # Drawbacks @@ -23,8 +98,8 @@ This encoding is very inefficient in terms of memory as it only uses 27 values o # Rationale and alternatives -There is no reason to not have this encoding. Although not relevant for storage or transport it is a very helpful encoding when it comes to debugging, unit testing and logging. +There is no reason to not have this encoding. Although not relevant for storage or transport it is indispensible for everything UI related, and also very helpful when it comes to debugging, testing and logging. # Unresolved questions -It is a well-known and long-time used encoding in the IOTA ecosystem, so there are no open questions around it known to the author. \ No newline at end of file +* Should the interface only allow the list to grow? When does it actually make sense to remove trits or trytes from the encoding? \ No newline at end of file From c61e8abc596ac549a1133db12d66981b20474b84 Mon Sep 17 00:00:00 2001 From: /alex/ Date: Fri, 4 Oct 2019 00:30:05 +0200 Subject: [PATCH 3/3] Added link to trits-module-preview --- text/0000-trits-t3b1/0000-trits-t3b1.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/text/0000-trits-t3b1/0000-trits-t3b1.md b/text/0000-trits-t3b1/0000-trits-t3b1.md index b857c66c..ed97d262 100644 --- a/text/0000-trits-t3b1/0000-trits-t3b1.md +++ b/text/0000-trits-t3b1/0000-trits-t3b1.md @@ -92,6 +92,8 @@ impl Encoding for T3B1 { } ``` +For more details checkout [this prototype](https://github.com/Alex6323/trits-module-preview) of a trits-module, that implements and abstracts over several different trit encodings. + # Drawbacks This encoding is very inefficient in terms of memory as it only uses 27 values out of 256 available in a (signed) byte and therefore should not be used for storing or transmitting trinary data.