Storage Power Consensus
TODO: remove all stale .id, .go files referenced
The Storage Power Consensus subsystem is the main interface which enables Filecoin nodes to agree on the state of the system. SPC accounts for individual storage miners' effective power over consensus in given chains in its Power Table. It also runs Expected Consensus (the underlying consensus algorithm in use by Filecoin), enabling storage miners to run leader election and generate new blocks updating the state of the Filecoin system.
Succinctly, the SPC subsystem offers the following services:
Access to the Power Table for every subchain, accounting for individual storage miner power and total power on-chain.
Access to Expected Consensus for individual storage miners, enabling:
Running Leader Election to produce new blocks.
Running Chain Selection across subchains using EC's weighting function.
Identification of the most recently finalized tipset, for use by all protocol participants.
Much of the Storage Power Consensus' subsystem functionality is detailed in the code below but we touch upon some of its behaviors in more detail.
Distinguishing between storage miners and block miners
There are two ways to earn Filecoin tokens in the Filecoin network:
By participating in the Storage Market as a storage provider and being paid by clients for file storage deals.
By mining new blocks on the network, helping modify system state and secure the Filecoin consensus mechanism.
We must distinguish between both types of "miners" (storage and block miners). Leader Election in Filecoin is predicated on a miner's storage power. Thus, while all block miners will be storage miners, the reverse is not necessarily true.
However, given Filecoin's "useful Proof-of-Work" is achieved through file storage (PoRep and PoSt), there is little overhead cost for storage miners to participate in leader election. Such a Storage Miner Actor need only register with the Storage Power Actor in order to participate in Expected Consensus and mine blocks.
On Power
Claimed power is assigned to every sector as a static function of its SectorStorageWeightDesc
which includes SectorSize
, Duration
, and DealWeight
. DealWeight is a measure that maps size and duration of active deals in a sector during its lifetime to its impact on power and reward distribution. A CommittedCapacity Sector (see Sector Types in Storage Mining Subsystem) will have a DealWeight of zero but all sectors have an explicit Duration which is defined from the ChainEpoch that the sector comes online in a ProveCommit message to the Expiration ChainEpoch of the sector. In principle, power is the number of votes a miner has in leader election and it is a point in time concept of storage. However, the exact function that maps SectorStorageWeightDesc
to claimed StoragePower
and BlockReward
will be announced soon.
More precisely,
Claimed power = power from ProveCommit sectors minus sectors in TemporaryFault effective duration.
Nominal power = claimed power, unless the miner is in DetectedFault or Challenged state. Nominal power is used to determine total network storage power for purposes of consensus minimum.
Consensus power = nominal power, unless the miner fails to meet consensus minimum, or is undercollateralized.
Beacon Entries
The Filecoin protocol uses randomness produced by a drand beacon to seed unbiasable randomness seeds for use in the chain (see randomness).
In turn these random seeds are used by:
The sector_sealer as SealSeeds to bind sector commitments to a given subchain.
The post_generator as PoStChallenges to prove sectors remain committed as of a given block.
The Storage Power subsystem as randomness in leader_election to determine their eligibility to mine a block.
This randomness may be drawn from various Filecoin chain epochs by the respective protocols that use them according to their security requirements.
It is important to note that a given Filecoin network and a given drand network need not have the same round time, i.e. blocks may be generated faster or slower by Filecoin than randomness is generated by drand. For instance, if the drand beacon is producing randomness twice as fast as Filecoin produces blocks, we might expect two random values to be produced in a Filecoin epoch, conversely if the Filecoin network is twice as fast as drand, we might expect a random value every other Filecoin epoch. Accordingly, depending on both networks' configurations, certain Filecoin blocks could contain multiple or no drand entries. Furthermore, it must be that any call to the drand network for a new randomness entry during an outage should be blocking, as noted with the drand.Public()
calls below. In all cases, Filecoin blocks must include all drand beacon outputs generated since the last epoch in the BeaconEntries
field of the block header. Any use of randomness from a given Filecoin epoch should use the last valid drand entry included in a Filecoin block. This is shown below.
Get drand randomness for VM
For operations such as PoRep creation, proof validations, or anything that requires randomness for the Filecoin VM, the following method shows how to extract the drand entry from the chain. Note that the round may span multiple filecoin epochs if drand is slower; the lowest epoch number block will contain the requested beacon entry. As well, if there has been null rounds where the beacon should have been inserted, we need to iterate on the chain to find where the entry is inserted.
Fetch randomness from drand network
When mining, a miner can fetch entries from the drand network to include them in the new block by calling the method GetBeaconEntriesForEpoch
.
Validating Beacon Entries on block reception
Per the above, a Filecoin chain will contain the entirety of the beacon's output from the Filecoin genesis to the current block.
Given their role in leader election and other critical protocols in Filecoin, a block's beacon entries must be validated for every block. See drand for details. This can be done by ensuring every beacon entry is a valid signature over the prior one in the chain, using drand's Verify
endpoint as follows:
Tickets
Filecoin block headers also contain a single "ticket" generated from its epoch's beacon entry. Tickets are used to break ties in the Fork Choice Rule, for forks of equal weight.
You can find the Ticket data structure here
Whenever comparing tickets in Filecoin, the comparison is that of the ticket's VRFDigest's bytes.
Randomness Ticket generation
At a Filecoin epoch n, a new ticket is generated using the appropriate beacon entry for epoch n.
The miner runs the beacon entry through a Verifiable Random Function (VRF) to get a new unique ticket. The beacon entry is prepended with the ticket domain separation tag and concatenated with the miner actor address (to ensure miners using the same worker keys get different tickets).
To generate a ticket for a given epoch n:
We use the VRF from Verifiable Random Functions for ticket generation (see the PrepareNewTicket
method below).
Ticket Validation
Each Ticket should be generated from the prior one in the VRF-chain and verified accordingly as shown in validateTicket
below.
Minimum Miner Size
In order to secure Storage Power Consensus, the system defines a minimum miner size required to participate in consensus.
Specifically, miners must have either at least MIN_MINER_SIZE_STOR
of power (i.e. storage power currently used in storage deals) in order to participate in leader election. If no miner has MIN_MINER_SIZE_STOR
or more power, miners with at least as much power as the smallest miner in the top MIN_MINER_SIZE_TARG
of miners (sorted by storage power) will be able to participate in leader election. In plain english, take MIN_MINER_SIZE_TARG = 3
for instance, this means that miners with at least as much power as the 3rd largest miner will be eligible to participate in consensus.
Miners smaller than this cannot mine blocks and earn block rewards in the network. Their power will still be counted in the total network (raw or claimed) storage power, even though their power will not be counted as votes for leader election. However, it is important to note that such miners can still have their power faulted and be penalized accordingly.
Accordingly, to bootstrap the network, the genesis block must include miners, potentially just CommittedCapacity sectors, to initiate the network.
The MIN_MINER_SIZE_TARG
condition will not be used in a network in which any miner has more than MIN_MINER_SIZE_STOR
power. It is nonetheless defined to ensure liveness in small networks (e.g. close to genesis or after large power drops).
NOTE: The below values are currently placeholders.
We currently set:
MIN_MINER_SIZE_STOR = 100 * (1 << 40) Bytes
(100 TiB)MIN_MINER_SIZE_TARG = 3
Network recovery after halting
Placeholder where we will define a means of rebooting network liveness after it halts catastrophically (i.e. empty power table).
Last updated