---
# System prepended metadata

title: 'Actor Spec: Miner'

---

# Actor Spec: Miner

[Back to Master Tracking Doc](https://hackmd.io/LOZjAsz-THelSD5lWqSVlw)

Filecoin's consensus mechanism revolves around storage power. For any given epoch, your chance of being selected as a block producer depends on your storage power, which is publically recorded on-chain. Filecoin storage miners help maintain this system by performing two crucial actions:

1. **Adding more storage**
2. **Proving existing storage**

Most of the Miner actor's implementation is designed to support these two operations.

## Contents

[TOC]

## Background

This section provides background information helpful for understanding the material described in [Adding more storage](#Adding-more-storage) and [Proving existing storage](#Proving-existing-storage). It is recommended to start reading those sections first, as they will link to relevant background sections where needed.

### Randomness

Randomness is an important attribute that helps the network verify the integrity of Miners' stored data. Filecoin's block creation process includes two types of randomness:
* Drand: Values pulled from a distributed random beacon
    * Reference: https://github.com/drand/drand
* VRF: The output of a verifiable random function (VRF), which takes the previous block's VRF value and produces the current block's VRF value.

Each block produced in Filecoin includes values pulled from these two sources of randomness.

When Miners submit proofs about their stored data, the proofs incorporate references to randomness added at specific epochs. Assuming these values were not able to be predicted ahead of time, this helps ensure that Miners generated proofs at a specific point in time.

There are two proof types. Each uses one of the two sources of randomness:
* Windowed PoSt: Uses Drand values
* Proof of Replication (PoRep): Uses VRF values

### Sectors

A Sector is the fundamental unit of storage used in Filecoin storage mining. Sectors are allocations of disk space a Miner dedicates to the Filecoin network. Before a Sector can be used, the Miner must _seal_ the Sector: encode the data in the Sector to prepare it for the proving process.

Terms:
* **Unsealed Sector**: A Sector of raw data.
    * **UnsealedCID (CommD)**: The root hash of the Unsealed Sector's merkle tree. Also called CommD, or "data commitment."
* **Sealed Sector**: A Sector that has been encoded to prepare it for the proving process.
    * **SealedCID (CommR)**: The root hash of the Sealed Sector's merkle tree. Also called CommR, or "replica commitment."

#### Sealing a Sector

The sealing process takes an input of data from an Unsealed Sector, and produces an encrypted _replica_ of that data: the Sealed Sector.

Filecoin's proving processes make a few assumptions about these replicas:
* They take a _long time_ to generate
* They are composed of encrypted data, and so cannot be compressed

According to these assumptions, if a Miner is able to prove that they have this replica data, they must be allocating a certain amount of disk space to store it. 
* In particular, the long duration of the sealing process ensures that Miners do not have time to regenerate a Sealed Sector - they must already have it on their machine.

### Types of proofs

#### Proof of Replication

A Proof of Replication (PoRep) is a proof that a Miner has correctly generated a _replica_ of some underlying data.

In practice, the underlying data is the _raw data_ contained in an Unsealed Sector, and a PoRep is a SNARK proof that the _sealing process_ was performed correctly to produce a Sealed Sector (See [Sealing a Sector](#Sealing-a-Sector)).

When Miners commit to storing data, they must first produce a valid Proof of Replication.

#### Proof of Spacetime

A Proof of Spacetime (aka PoSt) is a long-term assurance of a Miner's continuous storage of their Sectors' data. _This is not a single proof,_ but a collection of proofs the Miner has submitted over time. Periodically, a Miner must add to these proofs by submitting a **Windowed PoSt**:
* Fundamentally, a Windowed PoSt is a collection of merkle proofs over the underlying data in a Miner's Sectors.
* Windowed PoSts bundle proofs of various leaves across groups of Sectors (called **Partitions**).
* These proofs are submitted as a single SNARK.

The historical and ongoing submission of Windowed PoSts creates some assurance that the Miner has been storing, and continues to store their Sectors' underlying data (See [Sealing a Sector](#Sealing-a-Sector)).

### Miner Accounting

Miners:
* Earn tokens from block rewards
* Deposit tokens to act as collateral for their PreCommitted and ProveCommitted Sectors
* Lose tokens if they are given penalties for various reasons

#### Balance Requirements

A Miner's token balance MUST cover ALL of the following:
* **PreCommit Deposits**: When a Miner PreCommits a Sector, they must supply a "precommit deposit" for the Sector, which acts as collateral. If the Sector is not ProveCommitted on time, this deposit is removed and burned.
* **Initial Pledge**: When a Miner ProveCommits a Sector, they must supply an "initial pledge" for the Sector, which acts as collateral. If the Sector is terminated, this deposit is removed and burned.
* **Locked Funds**: When a Miner receives tokens from block rewards, the tokens are locked and added to the Miner's vesting table to be unlocked at a future epoch.

#### Penalties and Fee Debt

A Miner may accrue penalties for many reasons:
* **PreCommit Expiry Penalty**: Occurs if a Miner fails to ProveCommit a PreCommitted Sector in time
* **Undeclared Fault Penalty**: Occurs if a Miner fails to submit a PoSt for a Sector on time
* **Declared Fault Penalty**: Occurs if a Miner fails to submit a PoSt for a Sector on time, but they declare the Sector faulty beforehand. This is lower than the undeclared fault penalty to incentivize Miners to declare faults early.
* **Ongoing Fault Penalty**: Occurs every Proving Period a Miner fails to submit a PoSt for a Sector
* **Termination Penalty**: Occurs if a Sector is forcibly terminated before its expiration
* **Consensus Fault Penalty**: Occurs if a Miner commits a consensus fault and is reported

When a Miner accrues penalties, the amount penalized is tracked as "Fee Debt." If a Miner has Fee Debt, they are restricted from certain actions until the amount owed is paid off. Miners with Fee Debt may not:
* PreCommit new Sectors
* Declare faulty Sectors "recovered"
* Withdraw balance

## Adding more storage

Background:
* [Sectors](#Sectors)
    * [Sealing a Sector](#Sealing-a-Sector)
* [Randomness](#Randomness)
* [Proof of Replication](#Proof-of-Replication)

A Miner adds more storage in the form of Sectors. Adding more storage is a two-step process:
1. **PreCommitting a Sector**: A Miner publishes a Sector's SealedCID and makes a deposit. The Sector is now registered to the Miner, and the Miner must ProveCommit the Sector or lose their deposit.
2. **ProveCommitting a Sector**: The Miner provides a Proof of Replication (PoRep) for the Sector. This proof must be submitted AFTER a delay (the InteractiveEpoch), and BEFORE PreCommit expiration.

This two-step process provides assurance that the Miner's PoRep _actually proves_ that the Miner has replicated the Sector data and is generating proofs from it:
* ProveCommitments must happen AFTER the InteractiveEpoch (150 blocks after Sector PreCommit), as the randomness included at that epoch is used in the PoRep.
* ProveCommitments must happen BEFORE the PreCommit expiration, which is a boundary established to make sure Miners don't have enough time to "fake" PoRep generation.

For each Sector successfully ProveCommitted, the Miner becomes responsible for continuously proving the existence of their Sectors' data (see [Proving existing storage](#Proving-existing-storage). In return, the Miner is awarded storage power!

_NOTE: Other documentation refers to ProveCommitted Sectors either as "active sectors," "committed sectors," or "proven sectors." This documentation will try to use "ProveCommitted Sectors" to differentiate between PreCommitted Sectors, and Windowed PoSt submission for ProveCommitted Sectors._

### Upgrading Sectors

Miners are granted storage power in exchange for the storage space they dedicate to Filecoin. Ideally, this storage space is used to store data on behalf of Clients, but there may not always be enough Clients to utilize all the space a Miner has to offer.

In order for a Miner to maximize storage power (and profit), they should take advantage of all available storage space immediately, _even before they find enough Clients to use this space_.

To facilitate this, there are _two types_ of Sectors that may be sealed and ProveCommitted:
* **Regular Sector**: A Sector that contains Client data
* **Committed Capacity (CC) Sector**: A Sector with no data (all zeroes)

In practice, Miners will add _as much storage as they can_ in the form of CC Sectors, because these can be added without needing to wait for Clients. CC Sectors empower Miners to immediately make use of existing disk space: earning storage power and a higher chance at producing a block. However, _CC Sectors do not grant the Miner as much power as Regular Sectors_.

To incentivize Miners to hoard storage space and dedicate it to Filecoin, CC Sectors have a unique capability: **they can be "upgraded" to Regular Sectors** (also called "replacing a CC Sector").

Miners upgrade their ProveCommitted CC Sectors by PreCommitting a Regular Sector, and specifying that it should replace an existing CC Sector. Once the Regular Sector is successfully ProveCommitted, it will replace the existing CC Sector, boosting the Miner's storage power!

## Proving existing storage

Background:
* [Proof of Spacetime](#Proof-of-Spacetime)

Once a Miner successfully adds and ProveCommits a Sector, the Sector is assigned to a Deadline: a specific window of time during which PoSts must be submitted. The day is broken up into 48 individual Deadlines of 30 minutes each, and ProveCommitted Sectors are assigned to one of these 48 Deadlines.
* PoSts may only be submitted for the currently-active Deadline. Deadlines are open for 30 minutes, starting from the Deadline's "Open" epoch and ending at its "Close" epoch.
* PoSts must incorporate randomness pulled from a random beacon. This randomness becomes publically available at the Deadline's "Challenge" epoch, which is 20 epochs prior to its "Open" epoch.
* Deadlines also have a "FaultCutoff" epoch, 70 epochs prior to its "Open" epoch. After this epoch, Faults can no longer be declared for the Deadline's Sectors.

### Faults and Recoveries

A Sectors' PoSts must be submitted on time, or that Sector is marked "faulty." There are two types of faults:
* **Declared fault**: When the Miner explicitly declares a Sector "faulty" _before_ its Deadline's FaultCutoff.
* **Undeclared fault**: When the Miner does not explicitly declare a Sector "faulty," but their submitted PoSt does not contain a proof for that Sector.

Both types of faults come with penalties, but in general, the penalties for declared faults are lower than those for undeclared faults - incentivizing Miners to declare faults whenever possible.

Faults are implied to be "temporary" - that is, a Miner that temporarily loses internet connection may choose to declare some Sectors for their upcoming Deadline as faulty, because the Miner knows they will regain the ability to submit proofs for those Sectors eventually. This declaration allows the Miner to still submit a valid proof for their Deadline (minus the faulty Sectors). This is incredibly important for Miners, as missing a Deadline's PoSt entirely incurs a high penalty. (TODO specifics)

### Terminating Sectors

If a Miner loses access to their Sectors entirely, they may wish to terminate the Sectors.

TODO

## Exported Methods

### 1. Constructor

```go=
func (a Actor) Constructor(rt Runtime, params *ConstructorParams) *adt.EmptyValue
```

The Miner's Constructor has three primary functions:
1. Initialize the Miner's state
2. Generate a proving period offset, which will define the start of the Miner's proving period
3. Enroll a cron event for the epoch before the Miner's first proving period starts

### 2. ControlAddresses

```go=
func (a Actor) ControlAddresses(rt Runtime, _ *adt.EmptyValue) *GetControlAddressesReturn
```

Simple getter. Returns the Miner's Owner and Worker addresses, as well as an array of other control addresses authorized to submit proofs.

##### Return

```go=
type GetControlAddressesReturn struct {
    Owner  addr.Address
    Worker addr.Address
    ControlAddrs []addr.Address
}
```

**`Owner`**: The Miner's Owner address

**`Worker`**: The Miner's Worker address

**`ControlAddrs`**: Other addresses the Miner has authorized to submit PoSts, PreCommit Sectors, and manage existing Sectors.

### 3. ChangeWorkerAddress

```go=
func (a Actor) ChangeWorkerAddress(rt Runtime, params *ChangeWorkerAddressParams) *adt.EmptyValue
```

Allows the Miner's `Owner` to queue a change to their `Worker` and `ControlAddrs` addresses. A change to `ControlAddrs` takes effect immediately, whereas a change to `Worker` will be committed after `WorkerKeyChangeDelay` epochs (900). In order to implement this, `ChangeWorkerAddress` enrolls a cron event with the StoragePower actor, using `EventType` `CronEventWorkerKeyChange`.

Until the pending change is committed, the pending `Worker` address is stored in `st.PendingWorkerKey` along with its effective epoch.

##### Parameters

```go=
type ChangeWorkerAddressParams struct {
    NewWorker addr.Address
    NewControlAddrs []addr.Address
}
```

**`NewWorker`**: The Miner's new `Worker` address, which will be committed after 900 epochs.
* Requirements:
    * Must be associated with an Account actor
    * Must be a BLS address, OR an ID address whose `PubkeyAddress` method returns a valid BLS address

**`NewControlAddrs`**: The Miner's new control addresses. This always overwrites the Miner's existing control addresses, even if it is empty.

##### Failure conditions
* Caller is not Miner's `Owner` address
* `params.NewWorker` could not be resolved to an ID address
* `params.NewWorker` does not have an Account actor code CID
* `params.NewWorker` is not a BLS address, and a Send to its `PubkeyAddress` method failed to return a valid BLS address.
* StoragePower.EnrollCronEvent fails

### 4. ChangePeerID

```go=
func (a Actor) ChangePeerID(rt Runtime, params *ChangePeerIDParams) *adt.EmptyValue
```

Allows the Miner's `Worker` address to change the Miner's `PeerId`. This change goes into effect immediately.

##### Parameters

```go=
type ChangePeerIDParams struct {
	NewID abi.PeerID
}
```

**`NewID`**: The new Libp2p identity used to connect to the Miner
* Requirements:
    * `len(NewID) <= MaxPeerIDLength` (128)

##### Failure conditions
* Caller is not the Miner's `Owner`, `Worker`, or one of the Miner's `ControlAddrs`
* Supplied `params.NewID` is larger than `MaxPeerIDLength` (128)

### 5. SubmitWindowedPoSt

```go=
func (a Actor) SubmitWindowedPoSt(rt Runtime, params *SubmitWindowedPoStParams) *adt.EmptyValue
```

**Related concepts:**
* [Proving existing storage](#Proving-existing-storage)
    * [Faults and Recoveries](#Faults-and-Recoveries)
* [Miner Accounting](#Miner-Accounting)
    * [Balance Requirements](#Balance-Requirements)
    * [Penalties and Fee Debt](#Penalties-and-Fee-Debt)

**Summary:**
Each of a Miner's ProveCommitted Sectors are assigned to a Deadline

**Rough process:**
1. Validate that the Miner is submitting a proof at the right time, for the current Deadline
2. Load sector info for all sectors being proven
3. Verify submitted PoSt
4. Calculate any penalties accrued and power gained/lost due to faulty sectors, failed recoveries, or unproven sectors being proven for the first time.
5. Record successful PoSt submissions and update the current Deadline.
6. Update the Miner's storage power and pledge levels (via StoragePower actor)

**Interactions with other actors:**
* [Reward.ThisEpochReward](https://hackmd.io/VMNxxYtGTw6V_jYr-WzE_g#3-ThisEpochReward): Queries Reward actor to get the epoch reward for the current epoch.
* [StoragePower.CurrentTotalPower](https://hackmd.io/BYSfLi9qTfCBj_gb6mLFSA#9-CurrentTotalPower): Queries StoragePower actor to get the current total power and pledge collateral of the network.
* [StoragePower.UpdateClaimedPower](https://hackmd.io/BYSfLi9qTfCBj_gb6mLFSA#3-UpdateClaimedPower): The sum of power gained for recovered Sectors and power lost for new Faults is sent to the StoragePower actor, which updates the Miner's Claim.
* BurntFunds.MethodSend: Any accrued penalties are burned via the BurntFunds actor.
* [StoragePower.UpdatePledgeTotal](https://hackmd.io/BYSfLi9qTfCBj_gb6mLFSA#6-UpdatePledgeTotal): If the Miner's pledge changes due to accrued penalties, the StoragePower actor is updated.

### 6. PreCommitSector

```go=
func (a Actor) PreCommitSector(rt Runtime, params *SectorPreCommitInfo) *adt.EmptyValue
```

**Related concepts:**
* [Adding more storage](#Adding-more-storage)
    * [Upgrading Sectors](#Upgrading-Sectors)
* [Miner Accounting](#Miner-Accounting)
    * [Balance Requirements](#Balance-Requirements)
    * [Penalties and Fee Debt](#Penalties-and-Fee-Debt)

**Summary:**
`PreCommitSector` is used by a Miner in order to do ONE of the following:
* Add a new Committed Capacity Sector
* Add a new Regular Sector
* Replace an existing Committed Capacity Sector with a Regular Sector

Regardless of which option a Miner is using, a successful PreCommit means that the Miner must now ProveCommit the Sector, or lose a deposit.

**Rough process:**
1. Validate the input `SectorPreCommitInfo`
2. Vest funds and ensure the Miner is not in fee debt
3. Add a PreCommit deposit on behalf of the Miner
4. Place the new PreCommitted Sector in state (`st.PreCommittedSectors`) and allocate the chosen sector number (`st.AllocatedSectors`)
5. Add the sector to `st.PreCommittedSectorsExpiry` by its quantized expiry

**Interactions with other actors:**
* [Reward.ThisEpochReward](https://hackmd.io/VMNxxYtGTw6V_jYr-WzE_g#3-ThisEpochReward): Queries Reward actor to get the baseline power and epoch reward for the current epoch.
* [StoragePower.CurrentTotalPower](https://hackmd.io/BYSfLi9qTfCBj_gb6mLFSA#9-CurrentTotalPower): Queries StoragePower actor to get the current total power and pledge collateral of the network.
* [StorageMarket.VerifyDealsForActivation](https://hackmd.io/v3GZbV9GTt2AIO2li44Tzw#5-VerifyDealsForActivation): For any Client data in the Sector, queries the StorageMarket actor to get the total weight of all relevant deals.
* [StoragePower.UpdatePledgeTotal](https://hackmd.io/BYSfLi9qTfCBj_gb6mLFSA#6-UpdatePledgeTotal): If the Miner has vested any funds, the amount vested is unlocked and removed from the pledge total.

### 7. ProveCommitSector

```go=
func (a Actor) ProveCommitSector(rt Runtime, params *ProveCommitSectorParams) *adt.EmptyValue
```

**Related concepts:**
* [Adding more storage](#Adding-more-storage)

**Summary:**
`ProveCommitSector` is used by a Miner to submit a PoRep for a PreCommitted Sector. 
* The PoRep is submitted to the StoragePower actor for verification
* The StoragePower actor performs this verification as part of its cron method, [`StoragePower.OnEpochTickEnd`](https://hackmd.io/BYSfLi9qTfCBj_gb6mLFSA#5-OnEpochTickEnd)
* At the end of the same epoch, the StoragePower actor invokes [`ConfirmSectorProofsValid`](#17-ConfirmSectorProofsValid) with a list of all the valid proofs submitted by this Miner.

**Rough process:**
1. Check that the Miner is submitting a proof on time (BEFORE PreCommit expiry, and AFTER the InteractiveEpoch)
2. Send the PoRep to the StoragePower actor for bulk verification.

**Interactions with other actors:**
* [StorageMarket.ComputeDataCommitment](https://hackmd.io/v3GZbV9GTt2AIO2li44Tzw#8-ComputeDataCommitment): Queries the StorageMarket actor to compute the UnsealedCID for any deals in the Sector.
* [StoragePower.SubmitPoRepForBulkVerify](https://hackmd.io/BYSfLi9qTfCBj_gb6mLFSA#8-SubmitPoRepForBulkVerify): Sends the PoRep to the StoragePower actor, which will be verified as part of its cron loop.

### 8. ExtendSectorExpiration

```go=
func (a Actor) ExtendSectorExpiration(rt Runtime, params *ExtendSectorExpirationParams) *adt.EmptyValue
```

TODO

### 9. TerminateSectors

```go=
func (a Actor) TerminateSectors(rt Runtime, params *TerminateSectorsParams) *TerminateSectorsReturn
```

TODO

### 10. DeclareFaults

```go=
func (a Actor) DeclareFaults(rt Runtime, params *DeclareFaultsParams) *adt.EmptyValue
```

**Related concepts:**
* TODO

**Summary:**
`DeclareFaults` is used by a Miner to declare a set of Sectors as "faulty," indicating that the next PoSt for those Sectors' Deadline will not contain a proof for those Sectors' existence.
* As part of fault declaration, the Miner loses power for the faulty Sector. They will pay a fee for the fault when they next submit a PoSt for the Sector's Deadline.
* The fault declaration for a given Sector will be rejected if it is made within 70 epochs of the Sector's next Deadline window.
* Fault declarations are assigned an expiration: after 14 days, a faulty sector will be terminated if it has not been proven in a PoSt

**Rough process:**
1. Ensure that the set of fault declarations does not exceed the maximum allowed addressed Partitions and Sectors.
2. Ensure the fault declaration is being made before each Sector's FaultCutoff (determined by the Sector's Deadline).
3. Mark the Sectors as faulty within their Deadline/Partition.
4. Update the expiration epoch for faulty Sectors to the maximum fault age (14 days after declaration).
5. Calculate power lost for newly-faulty Sectors, and update the StoragePower actor with this value.

**Interactions with other actors:**
* [StoragePower.UpdateClaimedPower](https://hackmd.io/BYSfLi9qTfCBj_gb6mLFSA#3-UpdateClaimedPower): The amount of power lost for newly-faulty sectors is sent to the StoragePower actor.

### 11. DeclareFaultsRecovered

```go=
func (a Actor) DeclareFaultsRecovered(rt Runtime, params *DeclareFaultsRecoveredParams) *adt.EmptyValue
```

**Related concepts:**
* [Miner Accounting](#Miner-Accounting)
    * [Balance Requirements](#Balance-Requirements)
    * [Penalties and Fee Debt](#Penalties-and-Fee-Debt)

**Summary:**
`DeclareFaultsRecovered` is used by a Miner to declare a set of faulty Sectors as "recovering," indicating that the next PoSt for those Sectors' Deadline will contain a proof for those Sectors' existence.
* As part of fault declaration, the Miner loses power for the faulty Sector. This power is not recovered when the Miner declares the Sector recovering, but rather when the Miner submits the next PoSt for the Sector.
* The recovery declaration for a given Sector will be rejected if it is made within 70 epochs of the Sector's next Deadline window.

**Rough process:**
1. Ensure that the set of recovery declarations does not exceed the maximum allowed addressed Partitions and Sectors.
2. Repay any existing FeeDebt
3. Ensure the recovery declaration is being made before each Sector's FaultCutoff (determined by the Sector's Deadline).
4. Mark the Sectors as recovering within their Deadline/Partition.
5. Burn funds used to repay FeeDebt

### 12. OnDeferredCronEvent

```go=
func (a Actor) OnDeferredCronEvent(rt Runtime, payload *CronEventPayload) *adt.EmptyValue
```

#### `CronEventProvingDeadline`

**Related concepts:**
TODO

**Summary:**
TODO

**Rough process:**
1. Unlock vested funds up to the current epoch
2. Process a pending worker key change, if one exists
3. Detect and penalize PreCommits that expire in/before the current epoch (and have not been proven)
4. Perform end-of-deadline processing for each of this Deadline's partitions. If any partitions are missing a PoSt, mark all the partition's Sectors as faulty and reschedule their expiration if needed.
5. Remove and explicitly mark terminated any Sectors with expiries at/before the current epoch, and remove the pledge of any Sectors that expired on-time.
6. Calculate and apply any penalties, and repay as much fee debt as possible.
7. Enroll a cron event for the end of the next deadline
8. Attempt to process early terminations, or schedule work for the next epoch

**Interactions with other actors:**
* [Reward.ThisEpochReward](https://hackmd.io/VMNxxYtGTw6V_jYr-WzE_g#3-ThisEpochReward): Queries Reward actor to get the baseline power and epoch reward for the current epoch.
* [StoragePower.CurrentTotalPower](https://hackmd.io/BYSfLi9qTfCBj_gb6mLFSA#9-CurrentTotalPower): Queries StoragePower actor to get the current total power and pledge collateral of the network.

#### `CronEventProcessEarlyTerminations`

TODO

### 13. CheckSectorProven

```go=
func (a Actor) CheckSectorProven(rt Runtime, params *CheckSectorProvenParams) *adt.EmptyValue
```

Simple getter. Allows anyone to query whether a Sector was successfully proven via `ProveCommitSector`. `Abortf` if the Sector in question was not proven yet. Returns `nil` with `ExitCode 0` if the Sector has been proven.

##### Parameters

```go=
type CheckSectorProvenParams struct {
	SectorNumber abi.SectorNumber
}
```

**`SectorNumber`**: The number of the Sector that should exist in `st.Sectors`

##### Failure conditions
* Referenced `SectorNumber` does not exist in `st.Sectors`

### 14. ApplyRewards

```go=
func (a Actor) ApplyRewards(rt Runtime, params *builtin.ApplyRewardParams) *adt.EmptyValue
```

**Related concepts:**
* [Miner Accounting](#Miner-Accounting)

**Summary:**
`ApplyRewards` is used by the Reward actor to award a block reward to a Miner. 
* The parameter `params.Reward` is expected to be sent as value by the Reward actor along with invocation, and is added to the Miner's vesting table to vest at some future epoch.
* The parameter `params.Penalty` is added to the Miner's fee debt.

Finally, the Miner also attempts to repay as much of their fee debt as possible.

**Rough process:**
1. Validate input and caller
    * `params.Reward` must be non-negative and must be unlocked within the Miner
    * `params.Penalty` must be non-negative
    * Caller must be the Reward actor
2. Vest funds up to the current epoch
3. Add `params.Reward` to the Miner's vesting table
4. Apply `params.Penalty` to the Miner's fee debt
5. Repay as much debt as possible
6. Update pledge via StoragePower actor

**Interactions with other actors:**
* [StoragePower.UpdatePledgeTotal](https://hackmd.io/BYSfLi9qTfCBj_gb6mLFSA#6-UpdatePledgeTotal): Updates the StoragePower actor with the change to the Miner's pledge total (`amountToLock` - amount vested)

### 15. ReportConsensusFault

```go=
func (a Actor) ReportConsensusFault(rt Runtime, params *ReportConsensusFaultParams) *adt.EmptyValue
```

TODO

### 16. WithdrawBalance

```go=
func (a Actor) WithdrawBalance(rt Runtime, params *WithdrawBalanceParams) *adt.EmptyValue
```

**Related concepts:**
* [Miner Accounting](#Miner-Accounting)
    * [Balance Requirements](#Balance-Requirements)
    * [Penalties and Fee Debt](#Penalties-and-Fee-Debt)

**Summary:**
`WithdrawBalance` is used by the Miner's Owner to withdraw available funds earned from block rewards (among other sources). Before withdrawing, the Miner must not have pending early-terminated Sectors, and must be able to repay any existing FeeDebt.

**Rough process:**
1. Validate input, caller, and Miner state
    * `params.AmountRequested` must be non-negative
    * Caller must be the Miner's Owner
    * Miner may not have any pending early-terminated Sectors
2. Vest funds up to the current epoch
3. Repay all accumulated FeeDebt
4. If any balance is left over, send up to `params.AmountRequested` to the Miner's Owner
5. Burn any repaid debt
6. Update pledge via StoragePower actor

**Interactions with other actors:**
* [StoragePower.UpdatePledgeTotal](https://hackmd.io/BYSfLi9qTfCBj_gb6mLFSA#6-UpdatePledgeTotal): Updates the StoragePower actor with the change to the Miner's pledge total (inverse of total amount vested)

### 17. ConfirmSectorProofsValid

```go=
func (a Actor) ConfirmSectorProofsValid(rt Runtime, params *builtin.ConfirmSectorProofsParams) *adt.EmptyValue
```

**Related concepts:**
* [Adding more storage](#Adding-more-storage)
* [Proving existing storage](#Proving-existing-storage)

**Summary:**
`ConfirmSectorProofsValid` marks the final step in the process of adding more storage. It is invoked in [`StoragePower.OnEpochTickEnd`](https://hackmd.io/BYSfLi9qTfCBj_gb6mLFSA#5-OnEpochTickEnd), passing in a list of each Sector correctly ProveCommitted by this Miner over the last epoch. Once Sectors reach this step:
* The Miner becomes responsible for periodically proving the existence of the underlying data via [`SubmitWindowedPoSt`](#5-SubmitWindowedPoSt)
    * The Miner may gain power for these newly-proven sectors following their first successful PoSt submission.
* The Miner may perform maintenance on the Sector via:
    * [`ExtendSectorExpiration`](#8-ExtendSectorExpiration)
    * [`TerminateSectors`](#9-TerminateSectors)
    * [`DeclareFaults`](#10-DeclareFaults)
    * [`DeclareFaultsRecovered`](#11-DeclareFaultsRecovered)

**Rough process:**
1. Activate deals associated with each Sector via the StorageMarket actor
2. For each Sector being replaced, reschedule its expiration to the end of its next Deadline window
3. Delete the old PreCommitted Sectors and create the new ProveCommitted Sectors. Assign new Sectors to Deadlines.
4. Unlock each PreCommit deposit and add it to the Miner's pledge requirement.
5. Update the Miner's pledge totals (via StoragePower actor).

**Interactions with other actors:**
* [Reward.ThisEpochReward](https://hackmd.io/VMNxxYtGTw6V_jYr-WzE_g#3-ThisEpochReward): Queries Reward actor to get the baseline power and epoch reward for the current epoch.
* [StoragePower.CurrentTotalPower](https://hackmd.io/BYSfLi9qTfCBj_gb6mLFSA#9-CurrentTotalPower): Queries StoragePower actor to get the current total power and pledge collateral of the network.
* [StorageMarket.ActivateDeals](https://hackmd.io/v3GZbV9GTt2AIO2li44Tzw#6-ActivateDeals): Any deals contained in the proven Sectors are activated via the StorageMarket actor.
* [StoragePower.UpdateClaimedPower](https://hackmd.io/BYSfLi9qTfCBj_gb6mLFSA#3-UpdateClaimedPower): Updates the StoragePower actor with the new power gained from the activated Sectors.
* [StoragePower.UpdatePledgeTotal](https://hackmd.io/BYSfLi9qTfCBj_gb6mLFSA#6-UpdatePledgeTotal): Updates the StoragePower actor with the change to the Miner's pledge total.

### 18. ChangeMultiaddrs

```go=
func (a Actor) ChangeMultiaddrs(rt Runtime, params *ChangeMultiaddrsParams) *adt.EmptyValue
```

Allows the Miner's `Worker` address to change the stored `Multiaddrs` used to establish a connection with the Miner. Changes take effect immediately.

##### Parameters

```go=
type ChangeMultiaddrsParams struct {
    NewMultiaddrs []abi.Multiaddrs
}
```

**`NewMultiaddrs`**: The updated slice of libp2p multi-addresses that can be used to establish a connection with the Miner.
* Requirements:
    * No entry in `NewMultiaddrs` may be empty
    * The cumulative length of the entries in `NewMultiaddrs` may not be over `MaxMultiaddrData` (1024)

##### Failure conditions
* Caller is not the Miner's `Owner`, `Worker`, or one of the Miner's `ControlAddrs`
* Any entry in `params.NewMultiaddrs` is empty
* Sum of length of entries in `params.NewMultiaddrs` exceeds `MaxMultiaddrData` (1024)

### 19. CompactPartitions

```go=
func (a Actor) CompactPartitions(rt Runtime, params *CompactPartitionsParams) *adt.EmptyValue
```

TODO

### 20. CompactSectorNumbers

```go=
func (a Actor) CompactSectorNumbers(rt Runtime, params *CompactSectorNumbersParams) *adt.EmptyValue
```

Used by the Miner to compact allocated Sector numbers to reduce the size of the allocated Sector number bitfield. 

The input bitfield is merged with the Miner's existing `st.AllocatedSectors` bitfield. If done optimally, this can drastically reduce the number of "runs" in `st.AllocatedSectors`, reducing the cost needed to PreCommit a new Sector.

#### Failure conditions
* `params.MaskSectorNumbers` references Sector numbers out of the range of `abi.MaxSectorNumber`
* Caller is not the Miner's `Owner` or `Worker`, and is not one of the Miner's `ControlAddresses`

### 21. ConfirmUpdateWorkerKey

```go=
func (a Actor) ConfirmUpdateWorkerKey(rt Runtime, params *adt.EmptyValue) *adt.EmptyValue
```

If a worker key change was requested (via `ChangeWorkerAddress`) and its effective epoch has been reached, this method allows the Miner to confirm the change without waiting for Cron to pick it up (via `OnDeferredCronEvent`).

#### Failure conditions
* Caller is not the Miner's `Owner`

### 22. RepayDebt

```go=
func (a Actor) RepayDebt(rt Runtime, params *adt.EmptyValue) *adt.EmptyValue
```

Allows the Miner (as the `Owner`, `Worker`, or one of the `ControlAddresses`) to repay any existing fee debt.

This method repays as much fee debt as possible, and may leave the Miner with remaining fee debt after execution (assuming existing funds were insufficient).

---