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

TIP-550: P2P message snappy compression #550

Closed
jwrct opened this issue May 22, 2023 · 9 comments
Closed

TIP-550: P2P message snappy compression #550

jwrct opened this issue May 22, 2023 · 9 comments

Comments

@jwrct
Copy link
Contributor

jwrct commented May 22, 2023

Tip: 550
Title: P2P message snappy compression
Author: allen.cheng@tron.network
Status: Final
Type: Standards Track
Category: Networking
Date: 2023-05-22

Simple Summary

This TIP proposes a small extension to the TRON protocol to enable Snappy compression on all message payloads after the initial handshake.

Abstract

The base networking protocol used by TRON currently does not employ any form of compression. This results in a massive amount of bandwidth wasted in the entire network, making both initial sync and regular operation slower and laggier. This situation can be improved by compressing network messages. After extensive benchmarks, the results show that data traffic is decreased by 40-60% for block synchronization.

Motivation

Currently, the block size of the TRON ​​network is around 80k bytes. And as the TRON ​​network continues to grow, the block size may continue to increase, the network load will also increase, and the bandwidth requirements of nodes will also increase. However, most data (blocks, transactions) are highly compressible. By enabling compression at the message payload level, we can reduce the amount of data transmitted by the message, reducing bandwidth usage and data synchronization latency.

Rationale

Enable Snappy compression on all TCP channel message payloads after the initial handshake. Compress the message before sending it through the channel. When receiving a compressed message, decompress it first and then continue the subsequent business processing. The handshake message is never compressed, since it is needed to negotiate the common version.

Specification

Pack the compressed message into CompressMessage for network transmission. The structure of CompressMessage is as follows:

message CompressMessage {
  enum CompressType {
    uncompress = 0;
    snappy = 1;
  }
  CompressType type = 1;
  bytes data = 2;
}

Implementation

Snappy dependency

implementation group: 'org.xerial.snappy', name: 'snappy-java', version: '1.1.8.4'

Compression implementation when sending messages:

public void send(Message message) {
  if (finishHandshake) {
    data = ProtoUtil.compressMessage(message.getSendData()).toByteArray();
  }
  ...
}

public static Connect.CompressMessage compressMessage(byte[] data) throws IOException {
    Connect.CompressMessage.CompressType type = Connect.CompressMessage.CompressType.uncompress;
    byte[] bytes = data;

    byte[] compressData = Snappy.compress(data);
    if (compressData.length < bytes.length) {
      type = Connect.CompressMessage.CompressType.snappy;
      bytes = compressData;
    }

    return Connect.CompressMessage.newBuilder()
            .setData(ByteString.copyFrom(bytes))
            .setType(type).build();
  }

Decompression implementation when receiving a compressed message:

@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) {
    byte[] data = new byte[buffer.readableBytes()];
    buffer.readBytes(data);
    if (channel.isFinishHandshake()) {
      data = ProtoUtil.uncompressMessage(Connect.CompressMessage.parseFrom(data));
    }
    ...
}

public static byte[] uncompressMessage(Connect.CompressMessage message) throws IOException {
    if (message.getType().equals(Connect.CompressMessage.CompressType.uncompress)) {
      return message.getData().toByteArray();
    } else {
      return Snappy.uncompress(message.getData().toByteArray());
    }
}

Backward Compatibility

This proposal is fully backward compatible. Clients upgrading to the proposed new version protocol should still support skipping the compression step for older version protocol connections.

Test

Download blocks with block heights from 46314350 to 46314360, and perform a compression and decompression test. The compression rate is about 51%. The specific test results are as follows:

Block size (byte) Compressed size (byte) Compression rate Compression/decompression time(ms)
89803 44361 0.50 <1
104504 50926 0.51 <1
70970 35247 0.50 <1
96544 46905 0.51 <1
82820 41005 0.50 1
83987 41878 0.50 <1
82296 40566 0.51 <1
77820 39108 0.50 <1
73715 36027 0.51 <1
90632 43918 0.52 <1
@jwrct jwrct changed the title TIP: P2P Message Compression TIP-550: P2P Message Compression May 22, 2023
@Ocea91
Copy link

Ocea91 commented May 25, 2023

wow, this will basically slash the disk space needed in half. When will this release?

@L-Reid
Copy link

L-Reid commented May 25, 2023

wow, this will basically slash the disk space needed in half. When will this release?

This may not decrease the disk occupation, What I understand is that it is only compressed the message when the message is transmitted which reduced the bandwidth usage. Will this speed up the block synchronization?

@jwrct
Copy link
Contributor Author

jwrct commented May 25, 2023

wow, this will basically slash the disk space needed in half. When will this release?

This may not decrease the disk occupation, What I understand is that it is only compressed the message when the message is transmitted which reduced the bandwidth usage. Will this speed up the block synchronization?

Yes, you are right. From a global perspective, reducing bandwidth usage will speed up block synchronization.

@jwrct
Copy link
Contributor Author

jwrct commented May 25, 2023

wow, this will basically slash the disk space needed in half. When will this release?

It will be released in the next version, the exact date is not yet confirmed, but soon.

@Jamestepfoward
Copy link

Good job, just that why you suggest using Snappy compression sdk, have you compared with other similar compression method such as Zstd? I just wonder the process you decide to choose Snappy, I mean if we want to optimize it, it's better to use the best one right?

@jwrct
Copy link
Contributor Author

jwrct commented May 26, 2023

Good job, just that why you suggest using Snappy compression sdk, have you compared with other similar compression method such as Zstd? I just wonder the process you decide to choose Snappy, I mean if we want to optimize it, it's better to use the best one right?

When choosing a compression method, we compared the performance of various compression methods, and in the end we decided to choose the same compression method used by Ethereum. Of course, we will continue to test different compression methods. If the advantages are obvious, we will consider supporting multiple compression methods later.

@Bellgin
Copy link

Bellgin commented May 26, 2023

I would say thank you for the test stats, they seem convincible. Catching up Eth with the same method would shovel loads of work.

@ikirudoughnuts
Copy link

Cutting off 51% of the redundant message size, a surprisingly good one, this should be a mandatory update.

@jwrct jwrct changed the title TIP-550: P2P Message Compression TIP-550: P2P Message Snappy Compression Jun 13, 2023
@jwrct jwrct changed the title TIP-550: P2P Message Snappy Compression TIP-550: P2P message snappy compression Jun 13, 2023
@jwrct
Copy link
Contributor Author

jwrct commented Jul 3, 2023

Close this issue as it is implemented by GreatVoyage-v4.7.2.
Check TIP detail at TIP-550
Check implementation PR at tronprotocol/libp2p#7

@jwrct jwrct closed this as completed Jul 3, 2023
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

No branches or pull requests

6 participants