Skip to content

Latest commit

 

History

History
111 lines (76 loc) · 4.94 KB

kip-0013.md

File metadata and controls

111 lines (76 loc) · 4.94 KB
  KIP: 13
  Layer: Consensus (hard fork), Block Size
  Title: Transient Storage Handling
  Author: Michael Sutton <[email protected]>
          coderofstuff
  Status: draft

We propose tracking the transient storage consumption of transactions as a mass and bounding such consumption to a reasonable size for node operators. In the Kaspa jargon, the word mass is used for sizes that are used to limit transaction throughput due to their externality.

Motivation

Since KIP9, transactions now consume two types of masses, compute mass and storage mass. These masses are used to limit some consumption of resource per block (compute and persitent storage, respectively). However, neither of these directly limit the block size, byte-wise. We need to have a way to limit block byte sizes directly to have finer control over the worst-case storage and bandwidth used by a node.

Context

Payloads have been enabled in Testnet 11 which is running at 10 blocks per second (BPS). Payload bytes are charged at a gram per byte. At 10 BPS and with the current block mass limit of 500,000 grams, through the use of massive payloads, it's possible that storage within the pruning period can consume close to 1TB of data. To demonstrate this, we use the following calculation:

// Given:
block_mass_limit = 500,000
testnet_11_pruning_depth = 1,119,290
testnet_11_finality_depth = 432,000
bytes_per_gb = 1,000,000,000
// Assuming every block mass is exactly 1 byte:
worst_case_usage
= ((testnet_11_pruning_depth + testnet_11_finality_depth) * block_mass_limit) / bytes_per_gb;
= ((1,119,290 + 432,000) * 500,000) / 1,000,000,000
= 775 GB

Requiring node operators and common users who run nodes to have close to 1TB free to run a node is a tall ask. We must consider reducing this worst-case usage.

Typical Transactions

These are the most common kinds of tranactions that network users make.

A typical 1:2 transaction (1 input, 2 outputs)'s consumption looks like this

Field Data
Size 316 bytes
Actual Compute Mass 2036 grams
TPB* 245
Total Block Size** 77,420 bytes

*The transactions per block if it were completely filled with transactions like this only

**Total Block Size consumed if the block was filled with transactions like this only

Similarly 2:2 transactions (2 inputs, 2 outputs)'s consumption looks like this

Field Data
Size 434 bytes
Actual Compute Mass 3154 grams
TPB* 158
Total Block Size** 68,572 bytes

Finally a typical KRC20 transaction is usually either a 1:1 or 1:2 transaction. It's signature length is roughly 261 bytes.

Field Data
Size 429 bytes
Actual Compute Mass 1819 grams
TPB* 274
Total Block Size** 117,546 bytes

Plugging these sizes with the exact max pruning length (pruning + finality depth) of 10BPS, we get worst case disk sizes of 120GB, 106GB and 182GB respectively.

If we round it up to 125kb per block you get worst case usage of 193GB, which is much more reasonable and accessible than the initially calculated 775GB worst case requirement.

With these figures in mind, we can set the goals to be as follows:

  1. Keep the above costs for typical transactions (so we still fit those 150-250 TPB)
  2. Limit block size to 125KB

Our Proposal

Consensus Changes

The check_block_mass implementation introduced in KIP9 checks whether the transactions within a block fit within the block mass limit. It tracks storage mass and compute mass totals independently, and ensures each total mass falls within the block mass limit. We propose the following changes:

Change 1 - New Mass: Transient Storage mass

Introduce a new mass called transient_storage_mass. We will use this to limit the block size to 125KB as follows:

  • transient_storage_mass = transaction_serialized_size(tx) * 4.
  • The 4 above comes directly from trying to reduce the block size to 125KB (500,000 mass / 125,000 bytes = 4 mass / byte)

Change 2 - Independent Block Mass Tracking

Recall that KIP9 introduced tracking of compute_mass and storage_mass independently for block mass limits. This change is to add the transient_storage_mass as another mass to be tracked independently.

Mempool Changes

Change 1 - Fee Rate Keys

The calculated_transient_storage_mass will be pre-computed and accessible within the mempool. Fee rate keys will be updated to include calculated_transient_storage_mass in its mass via the max operator.

That is, the fee rate key is based on mass where mass = max(compute_mass, storage_mass, transient_storage_mass).

Optimizing the mempool transaction selection mechanism (tracking each mass independently somehow) is out of scope for this KIP.

Change 2 - Validations

Anywhere in the mempool where transaction compute mass is validated (such as against standard size), such mass will incorporate transient_storage_mass via the max operator.

Backwards compatibility

Breaks consensus rules, requires hardfork