Skip to content

☂️ Create abstractions to make the wire serialization protocol exchangable. #233

@manoranjith

Description

@manoranjith

Location

[wire], [pkg/io], [wire/net]

Motivation

Currently, wire messages in go-perun are encoded/decoded using a home-baked. When developing alternate implementations of the perun channel client, in a different programming language, the encoders and decoders have to be re-implemented in that language.

If we are able to exchange the custom format for standard ones like "protocol buffers", the messages can be defined once and the encoders/decoders can be generated for different programming languages. This will eliminate the overhead of implementing and maintaining the encoders/decoders in multiple languages.

However, this it is currently not possible to exchange custom format for a different one, as the necessary abstractions are missing. The scope of this task is to introduce the necessary abstractions.

Details

Abstractions necessary for making the wire serialization format exchangeable has been discussed and accepted in proposal#5.

This can be implemented in 6 steps, each involving one PR. This an umbrella issue to track the complete task.

  • Step 1

  • Step 2 Add env serializer interface #297

    • Define EnvelopeSerializer interface.
    type EnvelopeSerializer interface {
        Encode(io.Writer, Envelope) error
        Decode(io.Reader) (Envelope, error)
    }
    
    • Add a unexported package level variable that holds an instance of EnvelopeSerializer and an exported function
      SetEnvelopeSerializer, for setting it. The function should panic, if invoked more than once.
    • Implement the EnvelopeSerializer for perunio serialization format. The implementation should be placed in new package :wire/perunio/serializer. Because, package wire/perunio cannot import package wire.
    • Add an init function in package wire/perunio/serializer, which sets the wire.enveloperSerializer to perunio envelope serializer.

    Remark: It would be nicer to have the EnvelopeSerializer implementation directly in package wire/perunio. However, this might require some refactoring (as described in step 7) and hence could be done later.

  • Step 3 Add env serializer interface #297

    • Replace the wire.(Encode/Decode) methods with functions EncodeEnvelope and DecodeEvelope.
    • Update the Recv and Send on ioconn in the wire/net package to use the newly defined functions instead of wire.(Encode/Decode) methods.
  • Step 4 Use UnmarshalBinary and MarshalBinary for converting to/from Binary form #298

    • Use (Un)MarshalBinary function instead of perunio.(En|De)code in places where data is to be converted to/from binary representation, but need not be written to the wire. In particular, see 75150e1 and 1dc0797.
  • Step 5 (Can be done later)

  • Step 6 (Can be done later)

    • Move the decoders map from the wire package to the wire/perun package.
    • In the wire package, decode envelopes instead of messages.
  • Step 7 (Can be done later)
    From the client package,

    • Move the message definitions to the wire package and
    • Move the encoder/decoder implementations to the wire/perun package.
    • After these changes, merge wire/perunio/serializer package into wire/perunio. Because, now it would be possible for wire/perunio package to import wire package.

Notes:

  1. Regarding persistence, we can continue to use the perunio protocol as that is used for wire serialization. This should continue to work without any additional changes unless we implement step 7. When we implement step 7, we could rethink how we should handle it.

  2. Make ProposalID independent of perunio Mechanism for proposal ID generation #301

  3. Export all relevant all message types 💥 Off-chain messages: Naming conventions and type export for wire serialization #302

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions