---
# System prepended metadata

title: Meta Merkle Tree - Implementation

---

## Current mining flow

```sequence
Miner -> Compute: Partition request
Compute -> ComputeRaft: MiningPipelineItem::MiningParticipant
ComputeRaft -> Compute: Consensus-ed MiningParticipant
Compute -> Compute: Add Miner to participant_intake
note over Compute: Repeat process till timeout/minimum size met
Compute -> ComputeRaft: MiningPipelineItem::CompleteParticipant
ComputeRaft -> Compute: Consensus-ed CompleteParticipant
note over Compute: Randomly select miners for paritition
Compute -> Miner: Flood pre-block and rand_num
note over Miner: if rand_num: start partition PoW
Miner -> Compute: Partition PoW for next round
note over Miner: if block: Start PoW
Miner -> Compute: Actual PoW for current round
note over Compute: Collect PoWs
note over Compute: Select winning PoW
```

## Current mining flow - Explanation

The provided sequence diagram describes the complex process of mining in the Zenotta network. Here's a summarized explanation of the steps and interactions involved:

The process begins with a Miner Node initiating a **Partition request**, signaling their intent to participate in the mining. This request is received by the Compute ring, which plays the pivotal role in managing and coordinating mining activities and partitions.

The Compute Node, in turn, engages with **ComputeRaft**, a consensus mechanism run among the *Compute Ring*, to determine whether they can add a mining participant to the netowrk via the message **MiningParticipant**. The consensused miner is then added to the *participant_intake* queue, and this entire process is repeated until a specific condition is met, such as a timeout or reaching a minimum required participant size. This iterative approach ensures the inclusion of multiple miners in the mining process, enhancing the network's decentralization and security.

The next step involves Compute randomly selecting miners for the partition from the *participant_intake* queue and adds an element of unpredictability to the process. The Compute nodes will make use of the UniCorn random number generator to randomly select participating miners. These selected miners are then provided with **Pre-Block**(which is a block packaged by the ComputeRing *for* mining) and a random number from UniCorn.

If a specific condition, likely related to the received random number, is met, the miners start a partition Proof of Work (PoW) for the next round. PoW is a resource-intensive computational process that miners perform to validate and add new blocks to the blockchain. Miners communicate their partition PoW status back to Compute, keeping the system informed of their progress. 

Additionally, if the pre-block is available, miners initiate PoW for the current mining round, further contributing to the blockchain's integrity.

As the mining process unfolds, the Compute node collects all the PoWs generated by the participating miners. Among these collected PoWs, the ComputeRing selects the winning PoW. The selection of the winning PoW is a critical step in determining which miner gets to add the next block to the blockchain and get's rewarded for the round.

In summary, this sequence outlines the decentralized mining pipeline where miners compete to perform Proof of Work, and contribute to the consensus mechanism of the blockchain. The use of consensus, random selection, and PoW adds layers of fairness, security, and decentralization to the overall mining process, which is fundamental to the functioning of the Zenotta Network.

### PoW with Meta Merkle Tree:

- The problem is to overcome ASIC mining. They find nonces in 10 mins, even for 32-bit nonce space.
- Bitcoin overcomes this by changing transaction orders, but we cannot do that since computes are strict about tx ordering.
- The ordering of the transactions are rigourously set by the compute nodes in Merkle Trees.

### Implications in MMT implementation:
- Meta Merkle tree is **built by a combination of nodes**(whereas it was one only the computes before) and the compute needs to validate all the merkle trees it receives.
- This **can be a problem if there are a lot of miners** in the network.
- Possible solution: Choose **the winning miner first and then validate their PoW**.
- The **introduction of block difficulty fn** can make things better by reducing the participating miners number.
- Though Byron says this might open up **attack vectors like DDoS**
    - **Possible solution:** Since we are working on a closed group, it's much easier to RateLimit the messages that are coming from the connected miners

### Block packing and repacking:

- The way we package the blocks(specifically the block header) will be affected the most

```sequence
note over Compute: Generate an empty block
note over Compute: Add n transactions to merkle tree
note over Compute: Update BlockHeader with tx_root
Compute -> Miner: Send pre-block for mining
note over Miner: Create Coinbase tx
note over Miner: Add cb_hash to merkle tree
note over Miner: Compute meta_root and update block header
note over Miner: Run PoW
Miner -> Compute: Send found PoW
note over Compute: Collect all PoWs
note over Compute: Select a lucky miner
note over Compute: Validate lucky miner's PoW
```

#### Questions(as of current implementation):

1. What exactly do we get out of verifying the merkle tree?
2. Reason for using a Galios Counter mode.
3. No **transaction verification** happens though we have the infrastructure in code ready. When should this happen in the pipeline?
4. The **Partition PoW right now is done for the SocketAddrs** of the Miner and there are no coinbases involved here. But Alex mentioned that CB txs are what we use for Partition PoW.
5. Since coinbase come later in the pipeline now, **what happens if there are no user transactions** for that certain block. What `tx_root` will the compute give to miners?
    - Computes cannot send an empty tree as, miners can pre-compute PoW for all the block numbers, and send the PoW in the first try.
    - Can the coinbase tx be added to the Transactions branch? But that would ultimately change the tx_root.
6. Can we have two PoW: one for Tx_root and one for Meta_root to increase Nonce space?

----

## Pre-requisites to implement MMT validation

1. Basic validation mechanism of Transactions(via Merkle trees) at Miner.
2. Design: Packing and re-packing the block post MMT coinbase hash branch addition
    - How to maintain integrity of the block? Decouple MMT and Block? 
3. Partition PoW: Ideal flow vs Reality.

## Expectation
```sequence
Miner -> Mempool: Partition request
note over Mempool: Miner added to request_list
Mempool -> Miner: Pariticipation confirmation
note over Miner: Parition PoW with Coinbase Tx
Miner -> Mempool: Partition PoW(PartitionEntry)
note over Mempool: Validate PartitionPoW
note over Mempool: Add Miner to participant_list
```

## Reality
```sequence
Miner -> Mempool: Partition request
note over Mempool: Miner added to request_list
note over Mempool: Generate pre-block and rand_num
Mempool -> Miner: Send rand_num
note over Miner: Perform Parition PoW for next round
Miner -> Mempool: Partition PoW(PartitionEntry)
note over Mempool: Validate PartitionPoW
note over Mempool: Add Miner to participant_list
```

https://github.com/zenotta/naom/tree/merkle_tree_update