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

Mempool info #423

Merged
merged 2 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 47 additions & 3 deletions docs/architecture/mempool.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,55 @@ The transaction is also checked against other transactions in the mempool, to en

## Fee Required for Inclusion

If the mempool is not full, all transactions regardless of fee are accepted into the mempool. The maximum mempool size can vary by version, and transactions have a large variance in size, but it is generally 10-100 blocks.
When you submit a transaction, one of several possible scenarios will play out, depending on how full the mempool is, how large of a fee was included, the CLVM cost of the transaction, and other factors. Keep in mind that each farmer has its own copy of the mempool, with its own set of rules. The default mempool behavior discussed in this section will apply to most, but not all, nodes. It is up to each individual farmer to decide which transactions to include upon creating a block.

Transactions with 0 fee are accepted into the mempool as of chia-blockchain version 1.2.12. Fees that are very close to zero are considered equivalent to zero. The threshold is set at 5 mojo per cost, but this can vary by implementation, version, and settings, so it's not guaranteed by the protocol.
To view the current status of the mempool, see the dashboard for [mainnet](https://dashboard.chia.net/d/46EAA05E/mempool-transactions-and-fees?orgId=1&var-network=mainnet) and [testnet10](https://dashboard.chia.net/d/46EAA05E/mempool-transactions-and-fees?orgId=1&var-network=testnet10).

When the mempool gets full, nodes will start rejecting transactions that don't meet a minimum fee. The full node sorts the transactions by fee-per-cost, and kicks out the least valuable transactions first, when including new ones.
:::info

Currently, the block size is artificially limited to 50% of its capacity. Eventually this limitation will be lifted, but the numbers discussed in this section assume it is being enforced.

:::

:::info

The total size of the mempool differs by network.
* Mainnet: 550 billion cost, or 100 blocks
* Testnet10: 110 billion cost, or 20 blocks

:::

### Scenario 1: Mempool Not Busy

If the transaction you just submitted -- plus the entire contents of the mempool -- can fit into one block, then your transaction will be added to the next block. This is true even if you don't include a transaction fee.

The reason for this is straightforward -- the farmer has nothing to gain by excluding certain transactions, so it will include everything. Note that some proprietary software takes the opposite approach: the farmer will _only_ include transactions that pay a fee, regardless of mempool size.

The mempool for Chia's mainnet is often in this state. This does not mean that no transactions are being submitted. It simply means that the network's speed of around 20 transactions per second is sufficient to keep up with demand.

### Scenario 2: Mempool Busy But Not Full

If the mempool's contents will occupy more than one block, but the mempool is not full, then it is considered _busy_. In this case:
* Transactions that don't include fees will be added to the mempool, but they won't make it into the next block. Instead, they will have to "wait in line" for higher-priority transactions to be cleared. They likely will eventually be included in a block, but this is not guaranteed.
* Transactions with fees will be added to the mempool and prioritized according to the size of their fee-per-cost. For example, a transaction with a 1-mojo fee will enter the queue ahead of zero-fee transactions.

:::info Testnet10 info

Testnet10 is constantly being "dusted" (thousands of small transactions are being included) in order to simulate a busy network, which can be useful for testing. The dust transactions do not include any fees, so in order for your transaction to be prioritized ahead of the dust, you simply have to include a 1-mojo fee. In this case, your transaction will likely be included in the next transaction block. However, if you don't include a fee, it will likely need to wait ~40-60 minutes before being included.

:::

### Scenario 3: Mempool Full

If the mempool is completely full, then in order for your transaction to be added, it will need to kick out one or more transactions. In this scenario:
* Transactions with no fee will not be added to the mempool.
* Transactions with a fee of less than five mojos per cost (~100 million mojos for 2-input, 2-output transactions) will be treated as zero-fee transactions, i.e. they will not be added to the mempool.
* Transactions with a fee of at least five mojos per cost will be added to the mempool, prioritized by fee-per-cost, _if_ they are not the lowest priority transactions. In this case, one or more of the lowest-priority transactions will be removed.
* If the lowest-cost transaction in the mempool is higher than than the new transaction, then the new transaction will not be added. For example, if the lowest priority transaction in the mempool has a fee of 100 mojos-per-cost (as might be the case in a very busy network), then a new transaction will have to include a higher fee in order to be added to the mempool.

This scenario often occurs on testnet10. When the mempool is completely full, the dusters stop submitting transactions until some of the dust has been cleared. This scenario might occasionally happen on mainnet as well, in which case a minimum fee would be required.

If you see `INVALID_FEE_TOO_CLOSE_TO_ZERO` in your log file, the mempool was likely full when you submitted your transaction, and you did not include a sufficient fee to kick out an existing transaction. Try resubmitting your transaction with a higher fee.

## Replace by Fee

Expand Down
30 changes: 5 additions & 25 deletions docs/resources/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -725,31 +725,7 @@ The wallet no longer automatically adds unknown CATs wallets for CATs that may h

### How can I make a coin that may only be spent until a certain timestamp or block height?

Chialisp does not directly enable this capability. There are only conditions to make a coin that may be spent _after_ a certain timestamp or block height. Coin spends can only become valid; they can never become invalid.

There are at least 4 reasons for this:

1. **To keep CLVM separate from the mempool** -- When a block is farmed, the local node executes the CLVM from all of the coin spends in that block. The mempool only contains the output of this execution. Thus, the CLVM code execution is kept separate from the mempool, and the CLVM does not need to examine the blockchain's state in order to execute. If coin spends could become invalid, then the CLVM would need to examine the blockchain's state, which would require special handling in the mempool (and possibly cause other problems).

2. **To preserve mempool efficiency** -- If a coin spend depended on determining the timestamp or height of the last confirmed block, as would be required if coin spends could become invalid with time, then the output of the CLVM from this spend would need to be executed with each block, in order to determine if it is still valid. If the mempool became full of such transactions, then the entire mempool would need to be re-calculated with each block. This would be extremely inefficient and a potential attack vector.

As it stands with CLVM's implementation, coin spends only need to be executed once. The mempool can safely assume that the spend has not become invalid simply because time has passed, so there is no need to re-execute the code.

3. **To keep reorg logic simple** -- Small reorgs are rare in Chia, but still possible. If coin spends could become invalid with time, then they also could become invalid in a reorg. Any coin spends that depended on the original would then be invalidated. Sorting through the ripple effects of this behavior would require messy logic that would invalidate other spends, potentially even if they were only distantly related to the original.

Note that this problem doesn't exist when coin spends can only become _valid_ with time. In a reorg, an invalid spend could become valid; any resulting coin spends would also remain valid. As a result, there would be nothing to unwind.

4. **To prevent censorship** -- If someone attempts to spend a coin that is about to be made invalid, the farmer of the next transaction block could refuse to include that coin spend, thus making the coin unspendable _forever_. This is a slippery slope -- any coin spend that will become invalid in the future could be censored until the final valid timestamp or block has been reached. The only way to guarantee that such a coin is spendable would be for the owner to farm the block in which it is spent.

A related problem would occur if the coin spend didn't add a large enough fee to be included in the next block. This could be avoided by adding a larger fee, but the problem that a valid coin spend could become invalid still would exist.

**Recommended Solution**

Because of the problems listed above, any solutions to making a coin spendable _until_ a certain timestamp or block height would need to come from outside the core CLVM implementation.

Our current recommendation: First, create `Coin A`, which will run a `CREATE_COIN_ANNOUNCEMENT` condition when it is spent. Next, create `Coin B`, which uses the `ASSERT_COIN_ANNOUNCEMENT` condition for `Coin A`'s announcementID. A spend of `Coin A` will automatically invalidate any attempts to spend `Coin B` forever.

A similar (but slightly more complex technique) would be to use a singleton instead of a standard coin. Updating the singleton automatically would invalidate a coin spend, and the singleton could be reused to invalidate future spends. This technique could also be used to invalidate offers.
This capability is available by using the `ASSERT_BEFORE_*` conditions, originally added in [CHIP-14](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0014.md). In order to prevent the possibility of bricking a coin, you are recommended to use these conditions only in a coin's _solution_ and not in its _puzzle_. See [our documentation](/conditions#assert-before-seconds-relative) for more info.

### Where is the executable file to start the reference wallet GUI located on Windows?

Expand Down Expand Up @@ -951,6 +927,10 @@ Regarding feature 1, the only ephemeral spends that are currently supported must

Chia version 1.8.2 introduces identical spend aggregation, which addresses some of the use cases of Feature 2. Spends that make use of this feature are still restricted by the lack of `AGG_SIG_*` conditions, which means that anyone who needs to assert an announcement from an aggregated spend could also have spent the coin. However, this version brings Chia one step closer to offering full support for inter-transaction announcements.

### Why do I see `INVALID_FEE_TOO_CLOSE_TO_ZERO` in my log file?

This error message occurs when you submit a transaction that does not include a high enough fee, for example when the network is quite busy. Try submitting the transaction again with a higher fee (100 million mojos will generally suffice for standard transactions). For more details, see our [mempool documentation](/mempool#fee-required-for-inclusion).

---

## Offers
Expand Down