Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for sending compact slates #366

Merged

Conversation

yeastplume
Copy link
Member

@yeastplume yeastplume commented Mar 13, 2020

Very WIP at the moment, with the goal being to allow a 'compact slate' mode where the sender only provides their calculated excess instead of all of their inputs/outputs. Will fill out with more detail as we go.

Notes so far:

  • The recipient won't be able to verify the fee in this case
  • Sender will need an extra step at some point in the workflow to repopulate the slate's transaction with their outputs. Have to figure out whether this should mean an extra explicit call in the workflow of if there's anywhere this step can be logically inserted into the existing calls.
  • BPs can either be stored in the transaction context, or just regenerated at repopulation time

Changes to slate to support mimimalization:

  • tx field becomes an Option
  • tx field is omitted from the slate if it is None (null)
  • tx field and enclosed inputs/outputs do not need to be included in the first leg of a transaction exchange. (All inputs/outputs naturally need to be present at time of posting).
  • num_participants becomes an Option
  • num_participants may be omitted from the slate if it is None (null), if num_participants is omitted, its value is assumed to be 2
  • lock_height becomes an Option
  • lock_height may be omitted from the slate if it is None (null) if lock_height is omitted, it's value is assumed to be 0
  • ttl_cutoff_height may be omitted from the slate if it is None (null),
  • payment_proof may be omitted from the slate if it is None (null),
  • message is removed from participant_info entries
  • message_sig is removed from participant_info entries
  • id is removed from participant_info entries. Parties can identify themselves via private keys stored in the transaction context. The initiator must also record whether the transaction was intended to be an invoice in the context
  • part_sig may be omitted from a participant_info entry if it has not yet been filled out
  • receiver_signature may be omitted from payment_proof if it has not yet been filled out

@DavidBurkett
Copy link
Contributor

It was discussed in the past that this would be an RFC. I still think that would be a good idea so we could all weigh in on what belongs in the slate.

@yeastplume
Copy link
Member Author

Yes, (perhaps should have been clearer that) that's the plan. I need to have a play around with this and get something working, so the intention is to introduce the RFC alongside this PR once I've formed an opinion on the best approach.

@yeastplume
Copy link
Member Author

yeastplume commented Mar 19, 2020

With the compacted transaction workflow working, the current state of a compact slate is:

{                                                                                                                                                                                                                                                                                                               
  "version_info": {                                                                                                                                                                                                                                                                                                            
    "version": 4,                                                                                                                                                                                                                                                                                                              
    "orig_version": 4,                                                                                                                                                                                                                                                                                                         
    "block_header_version": 3                                                                                                                                                                                                                                                                                                  
  },                                                                                                                                                           
  "num_participants": 2,                                                                                                                                       
  "id": "106340df-0854-4fa2-9655-1ad5fda3a24b",                                                                                                                
  "tx": null,                                                                                                                                                                                                                                                                                                                  
  "excess": "0814a621184c6190dccc5f70c0edace9ea95e06e8c9fdd3fccc10298a33939bdb5",                                                                                                                                                                                                                                              
  "is_compact": true,                                                                                                                                          
  "amount": "60000000000",                                                                                                                                                                                                                                                                                                     
  "fee": "0",                                                                                                                                                                                                                                                                                                                  
  "height": "14",                                                                                                                                                                                                                                                                                                              
  "lock_height": "0",                                                                                                                                                                                                                                                                                                          
  "ttl_cutoff_height": null,                                                                                                                                                                                                                                                                                                   
  "participant_data": [                                                                                                                                                                                                                                                                                                        
    {                                                                                                                                                                                                                                                                                                                          
      "id": "1",                                                                                                                                               
      "public_blind_excess": "02e2dcb9cde8a1e536dc1ddf3fe16ec7c270928792c300d9ce080ca052c3138e19",                                                             
      "public_nonce": "025be5ec2a55e8c082c004e3459660f1a63cf5d6c230e343069163d0b8b9ce4fd3",                                                                                                                                                                                                                                    
      "part_sig": null,                                                                                                                                                                                                                                                                                                        
      "message": null,                                                                                                                                                                                                                                                                                                         
      "message_sig": null                                                                                                                                                                                                                                                                                                      
    }                                                                                                                                                          
  ],                                                                                                                                                           
  "payment_proof": null                                                                                                                                        
}

Summarizing next steps based on discussions in the wallet dev transaction building channel.

  • Slates should not output fields if they're null
  • orig_version is no longer necessary
  • message and message_sig can go altogether
  • num_participants can be assumed to be 2 if the field doesn't exist
  • payment_proof and ttl_cutoff_height can remain, if desired, (but do not have to exist in the slate)
  • If we assume all V4 slates start off as compacted, we can lose the is_compact field

Next steps would be to reduce the initial compacted slate to something like the following:

{                                                                                                                                                                                                                                                                                                               
  "version_info": {                                                                                                                                                                                                                                                                                                            
    "version": 4,                                                                                                                                                                                                                                                                                                              
    "block_header_version": 3                                                                                                                                                                                                                                                                                                  
  },                                                                                                                                                           
  "id": "106340df-0854-4fa2-9655-1ad5fda3a24b",                                                                                                                
  "excess": "0814a621184c6190dccc5f70c0edace9ea95e06e8c9fdd3fccc10298a33939bdb5",                                                                                                                                                                                                                                              
  "amount": "60000000000",                                                                                                                                                                                                                                                                                                     
  "fee": "400",                                                                                                                                                                                                                                                                                                                  
  "participant_data": [                                                                                                                                                                                                                                                                                                        
    {                                                                                                                                                                                                                                                                                                                          
      "id": "1",                                                                                                                                               
      "public_nonce": "025be5ec2a55e8c082c004e3459660f1a63cf5d6c230e343069163d0b8b9ce4fd3",                                                                                                                                                                                                                                    
    }                                                                                                                                                          
  ]                                                                                                                                                           
}

.commit_sum(vec![tx_excess], vec![offset_excess])?)
// if explicit excess is provided, just add to the current
// tx sum without including the offset. Otherwise, calc as normal
if let Some(ex) = self.excess.as_ref() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

H

@yeastplume
Copy link
Member Author

yeastplume commented Apr 2, 2020

Latest state of Slate:

{
  "version_info": {
    "version": 4,
    "block_header_version": 3
  },
  "id": "c10f8321-a328-4d11-9a43-c446dc942fdd",
  "amount": "1000000000",
  "fee": "8000000",
  "height": "437088",
  "participant_data": [
    {
      "public_blind_excess": "02ef37e5552a112f829e292bb031b484aaba53836cd6415aacbdb8d3d2b0c4bb9a",
      "public_nonce": "03c78da42179b80bd123f5a39f5f04e2a918679da09cad5558ebbe20953a82883e"
    }
  ]
}

And with a payment proof:

{
  "version_info": {
    "version": 4,
    "block_header_version": 3
  },
  "id": "77fcf666-2a91-4bde-b76c-2d43c3b4aff5",
  "amount": "1000000000",
  "fee": "8000000",
  "height": "437100",
  "participant_data": [
    {
      "public_blind_excess": "03097ec1d0d1d013814734b71db39a6d20ec0a4f85e32b3ac83a17afc1da1f2e5f",
      "public_nonce": "03cf874b8722648ee023932a62cba85acbbe26b5944f3a53b54963b180f8ff0794"
    }
  ],
  "payment_proof": {
    "sender_address": "7e008eb593ba17d116e282d6267a3c6aad87b910933ad34dfa4d7d2c92b6ba31",
    "receiver_address": "3a425bd5da5f0f78593251ede7fad0ecf7a95679d84b2cb405255d97ce068234"
  }
}

I've updated the top comment with the fuller list of slate changes, last couple of outstanding questions are:

  • Is height necessary?
  • Is version_info.block_header_version still necessary? I believe we use it during the period between forks

@lehnberg
Copy link
Collaborator

lehnberg commented Apr 2, 2020

Nice work documenting all this and providing samples @yeastplume!

I'm putting on a nitpick hat and trying to be "clever" with ways to reduce this even further. I suspect some of this cleverness may be a bit too clever for my own good here, so please forgive me if these are stupid suggestions.

Ideas

Re-considering version_info

In your non-payment proof slate example above,

"version_info": {
    "version": 4,
    "block_header_version": 3
  }

Takes up ~16% of the slate (66/407 characters). I note you are asking whether block_header_version is even required any more, but if we assume it is, could this data instead be represented as

"version" : 4.3

Where 4 is version and 3 is block_header_version? This would be 15 characters, i.e. 77% less characters, taking up 4.2% of the reduced slate size instead (15/356 characters).

Reconsidering id

"id": "77fcf666-2a91-4bde-b76c-2d43c3b4aff5"

Takes up 10.8% of the slate (44/407 characters). How is this ID derived? Correct me if I'm wrong, but the purpose of this ID is to identify the slate in question and associate it with an open transaction in the sender's/recipient's wallet. Is a 36-character string justified for uniqueness or might we be able to derive a smaller UID here?

Reconsidering public_ keys

If we can assume that transacting parties will never be sharing their private excess or nonce, might we be able to drop the public_ in public_blind_excess and public_nonce keys?

Reconsidering participant_ keys

Similarly, if we can assume that only participants will be sharing data, is it possible to drop participant_ in participant_data without losing any information?

Reconsidering indentation

Okay, I suspect you'll hate me for this, but just want to point out that assuming a space takes up space in serialisation, just by removing indentation we'll gain 10.8% (363/407), without sacrificing a lot of readability imo:

{
"version_info": {
"version": 4,
"block_header_version": 3
},
"id": "c10f8321-a328-4d11-9a43-c446dc942fdd",
"amount": "1000000000",
"fee": "8000000",
"height": "437088",
"participant_data": [
{
"public_blind_excess": "02ef37e5552a112f829e292bb031b484aaba53836cd6415aacbdb8d3d2b0c4bb9a",
"public_nonce": "03c78da42179b80bd123f5a39f5f04e2a918679da09cad5558ebbe20953a82883e"
}
]
}

Questions

  1. What is height used for in this context?
  2. How does payment_proof{} work in a transaction with 3 or more participants? Assuming two receivers, are they distinguished as receiver_address1, receiver_address2, or differently?

@yeastplume
Copy link
Member Author

"version" : 4.3

Yep, if we decide we need to leave the block version in something like this will work fine. Otherwise it just becomes "version": 4

Reconsidering id

I would like to keep UUID, but we can de/ser shorter UUIDs into the slate:

https://github.com/seigert/shorter-uuid-rs

Fine with all of the field renaming.

Reconsidering indentation

This is just being output with pretty-printing for reference. They can also be output without whitespace for more compactness, and the whitespace can be re-added for printing at any stage if needed.

@yeastplume
Copy link
Member Author

yeastplume commented Apr 6, 2020

See the RFC for continued discussion of compacting the Slate:

mimblewimble/grin-rfcs#49

This particular PR is already far larger than I'd like it to be, but it implements the parts of the RFC that required some experimentation and validation. Before this one gets much bigger, would prefer to clean it up, merge once we're a little way into the RFC process, then implement the rest in further PRs.

@yeastplume yeastplume changed the title [WIP] Add support for sending compact slates Add support for sending compact slates Apr 8, 2020
@yeastplume
Copy link
Member Author

Ready for review/merge now provided there isn't major pushback on the RFC (which there doesn't appear to be just yet). Apologies again for the length, but further changes towards compacting the slate and conforming to the RFC should be contained in much shorter PRs.

@yeastplume
Copy link
Member Author

See mimblewimble/rust-secp256k1-zkp#68 for cause of current test failures, will fix once new version of libsecp is integrated into Grin.

/// A message for other participants
pub message: Option<String>,
/// Signature, created with private key corresponding to 'public_blind_excess'
#[serde(with = "secp_ser::option_sig_serde")]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These directives and the Serialize trait on the Slate and included structs aren't necessary (only versioned slates are ever de/serialized), will be cleaning this up in a further PR

@yeastplume
Copy link
Member Author

Created a separate branch 4.0.0/compact_slates to contain compact slate work. Will be merging PRs freely into that branch to try and retain some review atomicity, and also won't be concerned with tests passing until the final PR (particularly the JSON-RPC doctests, which will all be updated at the end).

@yeastplume yeastplume merged commit b079af7 into mimblewimble:4.0.0/compact_slates Apr 17, 2020
@yeastplume yeastplume deleted the compact_slate_send branch April 17, 2020 10:39
@yeastplume yeastplume mentioned this pull request May 11, 2020
yeastplume added a commit that referenced this pull request May 19, 2020
* Add support for sending compact slates (#366)

* WIP add support for sending compact slates

* add repopulate_tx function to internal API

* first pass at compacted slate working

* move slate compaction to separate function

* test fixes

* support compact slate inits in invoice workflow

* add compress flags to send and invoice

* attempting to remove is_compact and assume all V4 slates begin as compact

* attempting to calculate offsets when full tx data isn't available

* update calc_commit to use participant blind data

* update doctests for compact slates

* start to remove unneeded fields from serialization

* make num_participants optional

* remove other_version from slate

* use grin master branch

* remove message field

* lock height assumed to be 0 if it doesn't exist

* don't serialise receiver signature when null

* don't serialize payment_info if not needed

* remove participant id from participant info

* add note on id field

* fix finalize and receive doctests

* finalize_tx tests, init_send_tx tests

* doctests for process_invoice_tx, retrieve_tx, tx_lock_outputs

* finished test changes

* update from grin master

* rebuild PR from diff (#380)

* recreate PR from diff (#381)

* serialize tx struct into top level coms object (#382)

* remove height (#383)

* Add State Slate (#384)

* add state field to slate and SlateV4

* set slate state at each transaction stage, add check to tests

* serialize slate status properly

* V4 Slate field tweaks (#386)

* various tweaks to V4 slate

* field renaming

* serialize slate v4 ID as base64 (#387)

* remove amount and fee where not needed (#388)

* Final Changes for compact Slate (#389)

* add tests for all types of file output, remove message args

* default range proof serialization

* shorten output features serialization

* rename payment proof fields in slate v4

* v4 payment proof serialization

* Binary Slates (#385)

* start test implementation

* add experimental binary serialization to slate

* serialize id

* serialize fields that can be skipped as a separate struct

* factor out sigs serialization

* clean up sigs and coms serialization

* completed v4 bin serialization

* add manual de/ser traits for V4 bin slate

* add simple byte array serializer

* complete wiring in of bin slate serialization

* clarify comment

* clarify comment

* update version

* test output dir name fix

* update slate v4 change description

* add binary output to command line

* Remove unneeded signature data during S2 and I2 stages (#390)

* remove unneeded return signature data during S2

* remove unneeded sig data from I2

* Doctest Fixes for compact slate branch (#392)

* begin to fix doctests

* more doctest fixes

* fix receive_tx

* update get_stored_tx to accept an UUID instead of a tx object, and operate on a raw Transaction object (#394)

* Fixes to async transaction posting (#395)

* unstash post_tx changes

* add offset during S3 and I3

* Revert slate id serialization to hex-string uuid (#396)

* update from master (#397)

* v3.x.x - v4.0.0 wallet compatibility fixes (#398)

* changes to support http sending to v3 wallets

* sending via http/tor TO 3.0.0 wallet works

* receiving FROM 3.0.0 wallets works over http/tor

* output converted V3 slate when needed

* paying invoices from 3.0.0 wallets working

* handle all participant info in slate states

* sending and receiving standard file transactions between v3 and 4 wallets confirmed working

* all file-based workflows working

* fixes resulting from tests

* remove reminder warnings

* remove lock_height, add kernel_features + arguments (#399)

* grin-wallet master now building against grin master (#402) (#403)

Co-authored-by: Antioch Peverell <apeverell@protonmail.com>

* Enhanced offset creation (#407)

* initial tests reworking offset creation

* invoice flow fixing + tests

* further test fixes

* change offset name in v4 slate, base64 serialize

* logic optimisation

* changes based on review feedback

Co-authored-by: Antioch Peverell <apeverell@protonmail.com>
antiochp added a commit to antiochp/grin-wallet that referenced this pull request Aug 7, 2020
* Add support for sending compact slates (mimblewimble#366)

* WIP add support for sending compact slates

* add repopulate_tx function to internal API

* first pass at compacted slate working

* move slate compaction to separate function

* test fixes

* support compact slate inits in invoice workflow

* add compress flags to send and invoice

* attempting to remove is_compact and assume all V4 slates begin as compact

* attempting to calculate offsets when full tx data isn't available

* update calc_commit to use participant blind data

* update doctests for compact slates

* start to remove unneeded fields from serialization

* make num_participants optional

* remove other_version from slate

* use grin master branch

* remove message field

* lock height assumed to be 0 if it doesn't exist

* don't serialise receiver signature when null

* don't serialize payment_info if not needed

* remove participant id from participant info

* add note on id field

* fix finalize and receive doctests

* finalize_tx tests, init_send_tx tests

* doctests for process_invoice_tx, retrieve_tx, tx_lock_outputs

* finished test changes

* update from grin master

* rebuild PR from diff (mimblewimble#380)

* recreate PR from diff (mimblewimble#381)

* serialize tx struct into top level coms object (mimblewimble#382)

* remove height (mimblewimble#383)

* Add State Slate (mimblewimble#384)

* add state field to slate and SlateV4

* set slate state at each transaction stage, add check to tests

* serialize slate status properly

* V4 Slate field tweaks (mimblewimble#386)

* various tweaks to V4 slate

* field renaming

* serialize slate v4 ID as base64 (mimblewimble#387)

* remove amount and fee where not needed (mimblewimble#388)

* Final Changes for compact Slate (mimblewimble#389)

* add tests for all types of file output, remove message args

* default range proof serialization

* shorten output features serialization

* rename payment proof fields in slate v4

* v4 payment proof serialization

* Binary Slates (mimblewimble#385)

* start test implementation

* add experimental binary serialization to slate

* serialize id

* serialize fields that can be skipped as a separate struct

* factor out sigs serialization

* clean up sigs and coms serialization

* completed v4 bin serialization

* add manual de/ser traits for V4 bin slate

* add simple byte array serializer

* complete wiring in of bin slate serialization

* clarify comment

* clarify comment

* update version

* test output dir name fix

* update slate v4 change description

* add binary output to command line

* Remove unneeded signature data during S2 and I2 stages (mimblewimble#390)

* remove unneeded return signature data during S2

* remove unneeded sig data from I2

* Doctest Fixes for compact slate branch (mimblewimble#392)

* begin to fix doctests

* more doctest fixes

* fix receive_tx

* update get_stored_tx to accept an UUID instead of a tx object, and operate on a raw Transaction object (mimblewimble#394)

* Fixes to async transaction posting (mimblewimble#395)

* unstash post_tx changes

* add offset during S3 and I3

* Revert slate id serialization to hex-string uuid (mimblewimble#396)

* update from master (mimblewimble#397)

* v3.x.x - v4.0.0 wallet compatibility fixes (mimblewimble#398)

* changes to support http sending to v3 wallets

* sending via http/tor TO 3.0.0 wallet works

* receiving FROM 3.0.0 wallets works over http/tor

* output converted V3 slate when needed

* paying invoices from 3.0.0 wallets working

* handle all participant info in slate states

* sending and receiving standard file transactions between v3 and 4 wallets confirmed working

* all file-based workflows working

* fixes resulting from tests

* remove reminder warnings

* remove lock_height, add kernel_features + arguments (mimblewimble#399)

* grin-wallet master now building against grin master (mimblewimble#402) (mimblewimble#403)

Co-authored-by: Antioch Peverell <apeverell@protonmail.com>

* Enhanced offset creation (mimblewimble#407)

* initial tests reworking offset creation

* invoice flow fixing + tests

* further test fixes

* change offset name in v4 slate, base64 serialize

* logic optimisation

* changes based on review feedback

Co-authored-by: Antioch Peverell <apeverell@protonmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants