Slatepacks, implementation for MWC

MWC Slatepacks implementation is in the progress, currently it is at the final stage. Slatepack feature is implemented by grin and it works great. Unfortunately slatepacks comes with other features that make grin abandon old code and stop supporting anything except slatepacks.

For MWC we need to keep backward compatibility with old wallets because we want keep our users happy. Because of that our slatepack implementaiton is very different from what grin has. We kept all features that wallet already has and kept backward compatibility.

The general slatepack idea was adopted form the grin, but the rest is different. Please check for the details at the document https://github.com/mwcproject/mwc-wallet/blob/rebase4.0.0/doc/slatepack_data_format.md

Currently the changes at the branch, soon they will be moved to the master branch, mwc713 command will be adopted and QT wallet will adopt that feature as well.

8 Likes

@Konstantin You swapped decrypted/encrypted data.

I compare it with Grin Slate V4 :

pub struct SlateV4 {
	pub ver: VersionCompatInfoV4,
	pub id: Uuid,
	pub sta: SlateStateV4,
	pub off: BlindingFactor,
	pub num_parts: u8,
	pub amt: u64,
	pub fee: FeeFields,
	pub feat: u8,
	pub ttl: u64,
	pub sigs: Vec<ParticipantDataV4>,
	pub coms: Option<Vec<CommitsV4>>,
	pub proof: Option<PaymentInfoV4>,
	pub feat_args: Option<KernelFeaturesArgsV4>,
}

And mapping to yours one:

Data Size Mapped
content 3 bit sta: SlateStateV4,
Slate UUID 16 bytes id: Uuid,
Network 1 bit
amount Varibale amt: u64,
fee Varibale fee: FeeFields,
height Varibale
lock_height Varibale feat_args: Option<KernelFeaturesArgsV4>,
Option ttl_cutoff_height Varibale ttl: u64,
Slate offset 32 bytes off: BlindingFactor,
Inputs types 1 bit
Input feature 1 bit
Input commit 33 bytes coms: Option<Vec<CommitsV4>>,
Input stop bit 1 bit
Output commit 33 bytes coms: Option<Vec<CommitsV4>>,
Output Range proof size 10 bits
Output Range proof length
Output stop bit 1 bit
Kernel commit 33 bytes
Kernel signature 64 bytes
Kernel stop bit 1 bit
Participant blind Excess size 7 bits sigs: Vec<ParticipantDataV4>,
Participant blind Excess length
Participant Nonce size 7 bits
Participant Nonce length
Participant signature flag 1 bit
Participant signature 64 bytes
Participant message flag 1 bit
Participant Message size 16 bits
Participant message length
Another participant data
Proof flag 1 bit proof: Option<PaymentInfoV4>,
Proof Sender Address variable saddr: DalekPublicKey, (in proof)
Proof Receiver address variable raddr: DalekPublicKey, (in proof)
Proof Signature flag 1 bit rsig: Option<DalekSignature>, (in proof)
Proof Signature len delta 4 bit
Proof Signature 64 bytes
Future usage any

My questions:

  1. Looks like you would need use dedicated serialization code with this definition, why not use Rust standard serialization? I guess you want to have a most compact data format?
  2. Backward compatibility is absolutely making users happy, but the code maintaining will be painful and more buggy, and hard to upgrade in the future. I suppose this is why Grin throw the old slate versions and facilitate the hard fork to get beautiful and easy-to-maintain source code, to make future’s life easy.
  3. I don’t find the kernel part in the new V4 slate. Do you understand why it has been removed? I suppose that’s only useful in the final step and normally the wallet don’t need to send to remote party, instead it just merge it locally and post to network.
  1. Yes, it is a dedicated serialization functionality. One of advantages that it allow to maintain compatibility easier. The rust standard serialization requires new data format for another new version and conversion of structures form one to another. In order to use rust to perform the same, complexity will not be eaiser.
    Also, normally save/load operations are independent form data. Rust make serialization convenient for data structures, but it doesn’t mean that we should never use alternatives.

  2. Backward compatibility we should maintain if we can. So far it is not so bad from the code perspective. Implementation is working. Of course it will be much better to have one implementation, but idea of compact slates comes only and we want to have it. The most confusing - it is how those slated build, the kernel offset calculated differently. But fortunately it is solvable with a single flag and we have good enough test coverage to validate that.

  3. V4 has offset (pub off: BlindingFactor) - it is kernel offset and it has the kernel features (pub feat_args: Option). Together it is what you need to build the kernel. So the data is here but it is not named as a kernel. I think the reason in new grin ‘Slate’ implementation. The Transaction data is optional, but offset BlindingFactor is always exist. Such separation make sense for ‘compact slate’ workflow. Initial send data is Kernel offset and Participant data only, no transaction is needed.

@suem What do you mean? “You swapped decrypted/encrypted data.”

Under title “not encrypted”, you put encrypted data structure; and “encrypted” with “not encrypted structure”.

Looks fine for me. Non encrypted data contain encrypted. Probably it is better use Binary data instead of not encrypted. Encryption result is a binary data.

Check update version (please note, it is in the master branch)