CIP: 10
Title: Multi-Peer Multi-Asset sends "MPMA Sends"
Authors: John Villar (chiguireitor) & Javier Varona (pataegrillo)
Status: Draft
Type: Standards Track
Created: 2017-03-28
Discussions-To: https://counterpartytalk.org/t/cip0010-multi-peer-multi-asset-sends/2799
Establishes a new send message type geared towards batch processing to send multiple assets to multiple addresses.
- Simplify batch transactions
- Reduce transaction fees
Multiple transactions are wasteful when the sender already knows who are the recipients and how much of each asset each one needs to receive. This functionality is especially useful for sites dealing with a group of asset to asset exchanges. MPMA addresses this issue by creating a lookup table for addresses and grouping sends by type of asset sent.
- LUT: A lookup table. Elements are expressed as indexes into this table with the minimum amount of bits required for the total amount of elements in it.
- RLE: Run-length Encoding, a compression technique used to express multiple values grouped by type. A run-length specifies a group value and amount of elements contained in that group.
- INT: A big endian 8 byte integer,
The main idea is to create a LUT for addreses so they can be expressed by simple indexes, and then compress each amount sent with simple RLE. This would save space by reducing the amount of bits dedicated to expressing the addresses. In the most extreme cases, reduction of bits needed to express each address is 168 times than standard sends.
The message format is constructed in the following way (Where N is the number of recipients, M the number of assets, X the Log base 2 of N rounded up to the nearest integer):
LUT size | LUT address 0 | ... | LUT address N | Asset Signaling bit 1 | Asset SubList 0 | ... | Asset Signaling Bit 1 | Asset Sublist M | Asset Signaling Bit 0 |
---|---|---|---|---|---|---|---|---|---|
16 Bits | 21 bytes | ... | 21 bytes | 1-bit | AssetList | ... | 1-bit | AssetList | 1-bit |
AssetList
is built in the following way:
Asset Name | # Z of recipients | LUT Idx 0 | Amount Idx 0 | ... | LUT Idx Z | Amount Idx Z |
---|---|---|---|---|---|---|
INT | X bits | X bits | INT | ... | X bits | INT |
Note that addresses are only 21 bytes. That's the result of decoding the base58 addresses into binary representation and stripping the last 4 bytes which are just a checksum.
Due to the high bandwidth of transactions created by MPMA sends, and to prevent spam from a given address to DDoS the counterparty network, each address can only transmit an MPMA send once per block. After and address transmits an MPMA send on a given block, subsequent MPMA sends from that same address will be ignored until the next block. This should also be reported as an error from the counterparty-lib client and RPC interfaces.
The MPMA sends messages should by identified by the message type 3 inside a standard, CIP11 compliant, message envelope.
The following example is broken into several newlines, but the data stream is continuous on the encoded TX data. Numbers are preceded by a marker, 'x' for hexadecimal numbers, 'b' for bits.
x2000
LUT Size: 2 addresses, 1 bit to represent each onex00F3A6B6E4A093E5A5B9DA76977A5270FD4D62553E
Base58 decoded address (into hex, 21 bytes), LUT index 0x009BDE9D244E7ABD061B0DCC1DFA8C0D880CD7DA21
Base58 decoded address (into hex, 21 bytes), LUT index 1b1
Bit, Valid asset after thisx0100000000000000
64 bits XCP asset IDb1
2 recipientsb0
Address 0 into the lookup tablex0000000001000000
Send 1 of the current Asset (XCP, divisible)b1
Address 1 into the lookup tablex0000000004000000
Send 4 of the current Asset (XCP)b0
End sending data
The whole transaction would then be encoded as (padded with 0s on the last byte):
020000f3a6b6e4a093e5a5b9da76977a5270fd4d62553e009bde9d244e7abd061b0dcc1dfa8c0d880cd7da21800000000000000000c0000020000000001000000040000000
For a total of 69 bytes to send XCP to two addresses. This is a "bad" use case for MPMA because the byte-length gains compared to standard transactions are low, however, sending more assets to more addresses would make gains a lot more evident.
A more complex send like:
[
('XCP', '3NA8hsjfdgVkmmVS9moHmkZsVCoLxUkvvv', 143250000),
('XCP', '1LWkDHE1gJ3z4k6hiC3zpvGd11sxqr3pdh', 649398295),
('PEPECASH', '1AXnNzHtee19mmsi7bKAgWTpTAsTFEfos', 4565463342),
('PEPECASH', '1LWkDHE1gJ3z4k6hiC3zpvGd11sxqr3pdh', 37563345767423),
('PEPECASH', '3NA8hsjfdgVkmmVS9moHmkZsVCoLxUkvvv', 877654544),
('HAIRPEPE', '1AXnNzHtee19mmsi7bKAgWTpTAsTFEfos', 65),
('HAIRPEPE', '3NA8hsjfdgVkmmVS9moHmkZsVCoLxUkvvv', 3),
('HAIRPEPE', '1KS9Pw8RSofrLVtVkGHSPhTR7993siXn2m', 2),
('PWAPWAPWAPWA', '1LWkDHE1gJ3z4k6hiC3zpvGd11sxqr3pdh', 6),
('PWAPWAPWAPWA', '1AXnNzHtee19mmsi7bKAgWTpTAsTFEfos', 8)
]
Would yield:
04000001cd70839b1529dc929d8f39df20dd826753491a00ca33abd906b406e5ccb7c6bd6545f8444c9fdb0305e083685a1097ce1ea9e91987ab9e94eae33d8a1300d60a862c1be090e587efd7c5ea6161d5e953bf9ba58631308e000000617388f88008000007ff17c3ca524400010879279a00000000404000000000000029434a2420000000031708b52600000000cc1ac50e7ed1e700583000000000000000100000000000000182da461d0d000000c410000000000000080c00000000000001020000000000000000
Which results on a message size of 203 bytes.
If one of the sends inside the whole MPMA message breaks consensus rules, that MPMA transaction will be considered erroneous and shall not be processed.
The MPMA send type will be a consensus change that will activate at a specific block to be determined after implementation. All parsing servers will need to upgrade before this block to maintain consensus.
CIP0010 implementation will have the following development milestones with their corresponding percentage of the total bounty:
- Milestone #1 (40% - 200 XCP) Implementation of MPMA in Counterparty-lib with all necessary unit tests.
- Milestone #2 (35% - 175 XCP) Release of memo requirement to mainnet.
- Maintenance and bug testing for 3 months. (25% - 125 XCP)
A bounty custodian has been appointed for collection and awarding of the milestones completion. User Jeremy Johnson (@j-dog) provided the following address for bounty collection:
1vkxvSE1HAZciYvJxSM2etMEh75ttEs2m
It is estimated that this implementation will take ~50 man hours to develop, with a suggested cost of 10 XCP/man hour, which would total about 500 XCP.
Each milestone should be accompanied by a git commit following CP's coding standards and requirements.
This document is placed in the public domain.