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 (asset, address, quantity) tuple is 168 times smaller 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 |
Addresses in the LUT must not be duplicate, as that would make the AssetList references indeterminist.
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.
A given asset can only be referenced once from an AssetList. Having more than one AssetList referencing the same asset makes the whole MPMA message invalid.
A given address can only be referenced once from a given AssetList. Having more than one reference for a LUT item in an AssetList makes the whole MPMA message invalid.
The MPMA sends messages should by identified by the message type 3 inside a standard, CIP11 compliant, message envelope.
Due to the high bandwidth of transactions that can be created with MPMA sends, there's a real possibility of usage by a malicious third party to create high cpu usage to all the nodes in the network. Tests should be made on the testnet regarding high loads and appropiate measures be included in consensus code to prevent edge cases. Probable avenues to lower high cpu usage are:
- Prevent the amount of simultaneous MPMA sends created by same source address.
- Prevent more than a set amount of MPMA sends happening at once on each block.
- Include an anti spam fee of XCP burnt.
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.
x0200
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 tablex0000000005f5e100
Send 1 of the current Asset (XCP, divisible)b1
Address 1 into the lookup tablex0000000017d78400
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):
020000f3a6b6e4a093e5a5b9da76977a5270fd4d62553e009bde9d244e7abd061b0dcc1dfa8c0d880cd7da2180800000000000004000000000bebc2010000000017d784000
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:
000405e083685a1097ce1ea9e91987ab9e94eae33d8a130001cd70839b1529dc929d8f39df20dd826753491a00d60a862c1be090e587efd7c5ea6161d5e953bf9b00ca33abd906b406e5ccb7c6bd6545f8444c9fdb03cc1ac50e7ed1e700503000000000000002100000000000000182da461d0d000000d410000000000000000c000000000000030200000000000000a58631308e000000697388f88008000005ff17c3ca524400000879279a00000000404000000000000021434a2420000000021708b5260000000000
Which results on a message size of 203 bytes.
If one of the sends inside the whole MPMA message breaks consensus rules, that whole 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.