This repository has been archived by the owner on Jun 7, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
RFC: trits-t1b1
encoding
#14
Open
Alex6323
wants to merge
2
commits into
iotaledger:master
Choose a base branch
from
Alex6323:rfc-t1b1
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
+ Feature name: `trits-t1b1` | ||
+ Start date: 2019-09-25 | ||
+ 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 an encoding that stores sequences of balanced trits (`-1`, `0`, `1`) in a `Vec` of signed bytes `i8`. It is one of the encodings used in the IOTA ecosystem, which are mentioned in RFC #10. It is the most memory inefficient encoding possible to store or transfer trits, because only 3 out of 256 possible states in a byte are actually used. Nevertheless this sometimes referred to as "raw trits" encoding is the representation expected as input by the trinary `Curl` hash function, and as well the representation of its output. | ||
|
||
# Motivation | ||
|
||
This encoding of sequences of balanced trits is necessary for the `Curl` hash function and therefore still necessary to allow for the Bee framework to interoperate with the current IOTA mainnet. | ||
|
||
# Detailed design | ||
|
||
The design of this encoding consists of two steps: | ||
* create a type-safe trit representation `Trit` on top of `i8` | ||
* create the `t1b1` encoding on top of `Trit` | ||
|
||
For step 1 this proposal employs the `newtype` pattern. It allows to add semantics to the wrapped datatype, which in this case is a signed byte `i8`. | ||
|
||
Note: For the sake of simplicity and increased code readability access modifiers are omitted. Just be aware that the wrapped `i8` can be accessed only from inside the crate which is trusted to do things right. | ||
|
||
```Rust | ||
struct Trit(i8); | ||
|
||
impl Trit { | ||
fn value(&self) -> i8 { | ||
self.0 | ||
} | ||
fn index(&self) -> usize { | ||
match self.0 { | ||
0 | 1 => self.0 as usize, | ||
-1 => 2 as usize, | ||
_ => unreachable!(), | ||
} | ||
} | ||
} | ||
``` | ||
As you can see this implementation provides two accessor methods `value` and `index` which are self-explanatory. The `index` method is currently only used internally to retreive the trit `char` representation from a lookup table. | ||
|
||
To make working with `Trit`s convenient this proposal suggests implementing the following traits, which allow to safely create single `Trit`s from their `char` or their `i8` representation as well as display them for easier debugging or logging: | ||
|
||
```Rust | ||
impl TryInto<Trit> for char {...} | ||
impl TryInto<Trit> for i8 {...} | ||
impl Display for Trit {...} | ||
``` | ||
|
||
For step 2 this proposal suggests modeling `T1B1` as a compound type of `Vec` and `Trit` using the newtype pattern again rather than a type alias. This allows to have full control over the API of this type, and is more secure. | ||
|
||
```Rust | ||
struct T1B1(Vec<Trit>); | ||
``` | ||
|
||
This proposal suggests two basic operations for now for adding and removing `Trit`s. | ||
```Rust | ||
impl T1B1 { | ||
fn push(&mut self, trit: Trit) { | ||
self.0.push(trit); | ||
} | ||
fn pop(&mut self) { | ||
self.0.pop(); | ||
} | ||
} | ||
``` | ||
|
||
Furthermore most of the functionality of this type is realized in trait implementations: | ||
```Rust | ||
// implements all functionality required for a (trit) encoding | ||
impl Encoding for T1B1 {...} | ||
|
||
// conversion logic to move to 'T3B1' encoding | ||
impl ToT3B1 for T1B1 {...} | ||
|
||
// conversion logic to move to 'T5B1' encoding | ||
impl ToT5B1 for T1B1 {...} | ||
|
||
// conversion logic to move to 'T9B2' encoding | ||
impl ToT9B2 for T1B1 {...} | ||
|
||
// conveniently converts string slices into 'T1B1' | ||
impl<'a> TryInto<T1B1> for &'a str {...} | ||
|
||
// displays 'T1B1' as a trit sequence, e.g. 1--100-11 | ||
impl Display for T1B1 {...} | ||
``` | ||
# Drawbacks | ||
|
||
This type is only necessary for compatibility with the current IOTA mainnet. It is inefficient and should ideally not be used for anything other than hashing and debugging. | ||
|
||
# Rationale and alternatives | ||
|
||
There are no alternatives as long as standard `Curl` hashing requires and produces data in this encoding. | ||
|
||
# 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. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curl
can be implemented using a more efficient encoding (64 trits per two 64-bit words). This way memory footprint can be reduced by a factor of 4. When pointer arithmetic is used to access words ofCurl
state (instead ofLUT
) then the memory footprint reduces additionally be a factor of 4/3. All in all, optimizing ofCurl
is worth investigating.So, it's not a very convincing argument that "balanced trits is necessary for the
Curl
". Maybe we should talk aboutCurl
-compliant encoding?t1b1
however is the simplest encoding that could be very useful for tests, to compare invariants when other encodings are used to perform the same trits transformation.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not if we actually do a difference between
Curl
andPCurl
. Per seCurl
is the one operating onT1B1
whilePCurl
accepts different encodings. It is briefly mentioned in the base RFC here https://github.com/iotaledger/bee-rfcs/pull/10/files#diff-b075c83057cb59013a66d6ee87aa3986R31.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea, I know of BCT-Curl. There is already a Rust port of it btw. But can we use it as a full replacement for Standard-Curl? Or putting this question differently: Is there really no other usecase for
T1B1
other than tests, debugging, ....There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think for single hashing
Curl
is faster thanPCurl
because of all the overhead it has. Also, almost all prototyping is done withT1B1
.