Actor Spec: Miner

Back to Master Tracking Doc

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

Background

This section provides background information helpful for understanding the material described in Adding more storage and 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
  • 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).

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).

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:

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. 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:

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

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

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
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

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
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

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
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

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

Related concepts:

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: Queries Reward actor to get the epoch reward for the current epoch.
  • StoragePower.CurrentTotalPower: Queries StoragePower actor to get the current total power and pledge collateral of the network.
  • StoragePower.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: If the Miner's pledge changes due to accrued penalties, the StoragePower actor is updated.

6. PreCommitSector

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

Related concepts:

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:

7. ProveCommitSector

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

Related concepts:

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
  • At the end of the same epoch, the StoragePower actor invokes 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:

8. ExtendSectorExpiration

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

TODO

9. TerminateSectors

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

TODO

10. DeclareFaults

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:

11. DeclareFaultsRecovered

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

Related concepts:

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

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:

CronEventProcessEarlyTerminations

TODO

13. CheckSectorProven

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
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

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

Related concepts:

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:

15. ReportConsensusFault

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

TODO

16. WithdrawBalance

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

Related concepts:

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:

17. ConfirmSectorProofsValid

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

Related concepts:

Summary:
ConfirmSectorProofsValid marks the final step in the process of adding more storage. It is invoked in StoragePower.OnEpochTickEnd, passing in a list of each Sector correctly ProveCommitted by this Miner over the last epoch. Once Sectors reach this step:

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:

18. ChangeMultiaddrs

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
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

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

TODO

20. CompactSectorNumbers

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

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

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).


Select a repo