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

Change mint tx format and coinbase rules to mitigate dust accumulation #511

Merged
merged 4 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
33 changes: 28 additions & 5 deletions src/protocol/tx-validity.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,15 @@ def sum_inputs(tx, asset_id) -> int:
total += input.amount
return total

"""
Returns any minted amounts by the transaction
"""
def minted(tx, asset_id) -> int:
mint_amount: int = 0
if tx.type == TransactionType.Mint and asset_id == tx.mint_asset_id:
mint_amount = tx.mint_amount
return mint_amount

def sum_outputs(tx, asset_id) -> int:
total: int = 0
for output in tx.outputs:
Expand All @@ -114,7 +123,7 @@ def available_balance(tx, asset_id) -> int:
"""
Make the data message balance available to the script
"""
availableBalance = sum_inputs(tx, asset_id) + sum_data_messages(tx, asset_id)
availableBalance = sum_inputs(tx, asset_id) + sum_data_messages(tx, asset_id) + minted(tx, asset_id)
return availableBalance

def unavailable_balance(tx, asset_id) -> int:
Expand Down Expand Up @@ -206,11 +215,25 @@ Transaction processing is completed by removing spent UTXOs from the state and a

### Coinbase Transaction

The coinbase transaction is a mechanism for block creators to convert fees into spendable UTXOs.
The coinbase transaction is a mechanism for block creators to collect transaction fees.

In order for a coinbase transaction to be valid:

1. It must be a [Mint](../tx-format/transaction.md#TransactionMint) transaction.
2. The coinbase transaction must be the first transaction within a block, even if there are no other transactions in the block and the fee is zero.
3. The total output value of the coinbase transaction cannot exceed the total amount of fees processed from all other transactions within the same block.
4. The `asset_id` for coinbase transaction outputs must match the `asset_id` that fees are paid in (`asset_id == 0`).
1. The coinbase transaction must be the first transaction within a block, even if there are no other transactions in the block and the fee is zero.
Voxelot marked this conversation as resolved.
Show resolved Hide resolved
1. The `mintAmount` doesn't exceed the total amount of fees processed from all other transactions within the same block.
1. The `mintAssetId` matches the `asset_id` that fees are paid in (`asset_id == 0`).
1. the `gasPrice`, where relevant is assumed to be zero.

A [Mint](../tx-format/transaction.md#TransactionMint) transaction is only valid within the context of these coinbase validity rules.

Fee burning mechanisms are supported. The block creator may use a lower `mintAmount` than the total
amount of fees paid within the block, leaving the excess fees forever unclaimed.

The [Mint](../tx-format/transaction.md#TransactionMint) transaction type flexibly allows the block
creator to decide how fees should be collected.
For example, consider that a threshold amount exists for a UTXO to be considered non-spendable dust.
If the coinbase amount is below this threshold, the block creator could use a script to transfer the amount
into a contract balance. After the contract balance is high enough, the block creator would sweep the balance out as
spendable coin UTXOs. If the coinbase amount is above this threshold, the block creator may use
[OutputType.Coin](../tx-format/output.md#outputcoin) to avoid extra steps.
28 changes: 19 additions & 9 deletions src/tx-format/transaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,25 @@ Creates a contract with contract ID as computed [here](../identifiers/contract-i
## TransactionMint

The transaction is created by the block producer and is not signed. Since it is not usable outside of block creation or execution, all fields must be fully set upon creation without any zeroing.

| name | type | description |
|----------------|------------------------------|------------------------------------------------------|
| `txPointer` | [TXPointer](./tx-pointer.md) | The location of the `Mint` transaction in the block. |
| `outputsCount` | `uint8` | Number of outputs. |
| `outputs` | [Output](./output.md)`[]` | List of outputs. |
This means that the transaction ID must also include the correct `txPointer` value, not zeroed out.

| name | type | description |
|----------------|------------------------------|-----------------------------------------------------------|
| `mintAmount` | `uint64` | The amount of funds being minted within this transaction. |
| `mintAssetId` | `byte[32]` | The asset ID of funds minted within this transaction. |
Voxelot marked this conversation as resolved.
Show resolved Hide resolved
| `gasLimit` | `uint64` | Gas limit for transaction |
Voxelot marked this conversation as resolved.
Show resolved Hide resolved
| `scriptLength` | `uint16` | Script length, in instructions. |
| `inputsCount` | `uint8` | Number of inputs. |
| `outputsCount` | `uint8` | Number of outputs. |
| `txPointer` | [TXPointer](./tx-pointer.md) | The location of the `Mint` transaction in the block. |
| `receiptsRoot` | `byte[32]` | Merkle root of receipts. |
| `script` | `byte[]` | Script to execute. |
Voxelot marked this conversation as resolved.
Show resolved Hide resolved
| `inputs` | [Input](./input.md)`[]` | List of inputs. |
| `outputs` | [Output](./output.md)`[]` | List of outputs. |

Transaction is invalid if:

- Any output is not of type `OutputType.Coin`
- Any two outputs have the same `asset_id`
- `txPointer` is zero or doesn't match the block.
- Any output is of type `OutputType.ContractCreated`
- `scriptLength > MAX_SCRIPT_LENGTH`
- `scriptDataLength > MAX_SCRIPT_DATA_LENGTH`
- `scriptLength * 4 != len(script)`
Loading