github.com/filecoin-project/specs-actors/v4@v4.0.2/actors/builtin/miner/miner_internal_test.go (about)

     1  package miner
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/filecoin-project/go-state-types/abi"
     7  	"github.com/filecoin-project/go-state-types/big"
     8  	"github.com/minio/blake2b-simd"
     9  	"github.com/stretchr/testify/assert"
    10  
    11  	"github.com/filecoin-project/specs-actors/v4/actors/builtin"
    12  	"github.com/filecoin-project/specs-actors/v4/actors/util/smoothing"
    13  	tutils "github.com/filecoin-project/specs-actors/v4/support/testing"
    14  )
    15  
    16  func TestAssignProvingPeriodBoundary(t *testing.T) {
    17  	addr1 := tutils.NewActorAddr(t, "a")
    18  	addr2 := tutils.NewActorAddr(t, "b")
    19  	startEpoch := abi.ChainEpoch(1)
    20  
    21  	// ensure the values are different for different addresses
    22  	b1, err := assignProvingPeriodOffset(addr1, startEpoch, blake2b.Sum256)
    23  	assert.NoError(t, err)
    24  	assert.True(t, b1 >= 0)
    25  	assert.True(t, b1 < WPoStProvingPeriod)
    26  
    27  	b2, err := assignProvingPeriodOffset(addr2, startEpoch, blake2b.Sum256)
    28  	assert.NoError(t, err)
    29  	assert.True(t, b2 >= 0)
    30  	assert.True(t, b2 < WPoStProvingPeriod)
    31  
    32  	assert.NotEqual(t, b1, b2)
    33  
    34  	// Ensure boundaries are always less than a proving period.
    35  	for i := 0; i < 10_000; i++ {
    36  		boundary, err := assignProvingPeriodOffset(addr1, abi.ChainEpoch(i), blake2b.Sum256)
    37  		assert.NoError(t, err)
    38  		assert.True(t, boundary >= 0)
    39  		assert.True(t, boundary < WPoStProvingPeriod)
    40  	}
    41  }
    42  
    43  func TestCurrentProvingPeriodStart(t *testing.T) {
    44  	// At epoch zero...
    45  	curr := e(0)
    46  
    47  	// ... with offset zero, the current proving period starts now, ...
    48  	assert.Equal(t, e(0), currentProvingPeriodStart(curr, 0))
    49  
    50  	// ... and all other offsets are negative.
    51  	assert.Equal(t, -WPoStProvingPeriod+1, currentProvingPeriodStart(curr, 1))
    52  	assert.Equal(t, -WPoStProvingPeriod+10, currentProvingPeriodStart(curr, 10))
    53  	assert.Equal(t, e(-1), currentProvingPeriodStart(curr, WPoStProvingPeriod-1))
    54  
    55  	// At epoch 1, offsets 0 and 1 start at offset, but offsets 2 and later start in the past.
    56  	curr = 1
    57  	assert.Equal(t, e(0), currentProvingPeriodStart(curr, 0))
    58  	assert.Equal(t, e(1), currentProvingPeriodStart(curr, 1))
    59  	assert.Equal(t, -WPoStProvingPeriod+2, currentProvingPeriodStart(curr, 2))
    60  	assert.Equal(t, -WPoStProvingPeriod+3, currentProvingPeriodStart(curr, 3))
    61  	assert.Equal(t, e(-1), currentProvingPeriodStart(curr, WPoStProvingPeriod-1))
    62  
    63  	// An arbitrary mid-period epoch.
    64  	curr = 123
    65  	assert.Equal(t, e(0), currentProvingPeriodStart(curr, 0))
    66  	assert.Equal(t, e(1), currentProvingPeriodStart(curr, 1))
    67  	assert.Equal(t, e(122), currentProvingPeriodStart(curr, 122))
    68  	assert.Equal(t, e(123), currentProvingPeriodStart(curr, 123))
    69  	assert.Equal(t, -WPoStProvingPeriod+124, currentProvingPeriodStart(curr, 124))
    70  	assert.Equal(t, e(-1), currentProvingPeriodStart(curr, WPoStProvingPeriod-1))
    71  
    72  	// The final epoch in the chain's first full period
    73  	curr = WPoStProvingPeriod - 1
    74  	assert.Equal(t, e(0), currentProvingPeriodStart(curr, 0))
    75  	assert.Equal(t, e(1), currentProvingPeriodStart(curr, 1))
    76  	assert.Equal(t, e(2), currentProvingPeriodStart(curr, 2))
    77  	assert.Equal(t, WPoStProvingPeriod-2, currentProvingPeriodStart(curr, WPoStProvingPeriod-2))
    78  	assert.Equal(t, WPoStProvingPeriod-1, currentProvingPeriodStart(curr, WPoStProvingPeriod-1))
    79  
    80  	// Into the chain's second period
    81  	curr = WPoStProvingPeriod
    82  	assert.Equal(t, WPoStProvingPeriod, currentProvingPeriodStart(curr, 0))
    83  	assert.Equal(t, e(1), currentProvingPeriodStart(curr, 1))
    84  	assert.Equal(t, e(2), currentProvingPeriodStart(curr, 2))
    85  	assert.Equal(t, WPoStProvingPeriod-1, currentProvingPeriodStart(curr, WPoStProvingPeriod-1))
    86  
    87  	curr = WPoStProvingPeriod + 234
    88  	assert.Equal(t, WPoStProvingPeriod, currentProvingPeriodStart(curr, 0))
    89  	assert.Equal(t, WPoStProvingPeriod+1, currentProvingPeriodStart(curr, 1))
    90  	assert.Equal(t, WPoStProvingPeriod+233, currentProvingPeriodStart(curr, 233))
    91  	assert.Equal(t, WPoStProvingPeriod+234, currentProvingPeriodStart(curr, 234))
    92  	assert.Equal(t, e(235), currentProvingPeriodStart(curr, 235))
    93  	assert.Equal(t, WPoStProvingPeriod-1, currentProvingPeriodStart(curr, WPoStProvingPeriod-1))
    94  }
    95  
    96  type e = abi.ChainEpoch
    97  
    98  func TestFaultFeeInvariants(t *testing.T) {
    99  
   100  	// Construct plausible reward and qa power filtered estimates
   101  	epochReward := abi.NewTokenAmount(100 << 53)
   102  	rewardEstimate := smoothing.TestingConstantEstimate(epochReward) // not too much growth over ~3000 epoch projection in BR
   103  
   104  	networkPower := abi.NewStoragePower(100 << 50)
   105  	powerEstimate := smoothing.TestingConstantEstimate(networkPower)
   106  
   107  	// constant filter estimate cumsum ratio is just multiplication and division
   108  	// test that internal precision of BR calculation does not cost accuracy
   109  	// compared to simple multiplication in this case.
   110  	t.Run("br looks right in plausible (sectorPower, networkPower, reward) range", func(t *testing.T) {
   111  		// between 10 and 100 FIL is reasonable for near-mid future
   112  		tensOfFIL := big.Mul(abi.NewTokenAmount(1e18), big.NewInt(50))
   113  		rewardEstimate := smoothing.TestingConstantEstimate(tensOfFIL)
   114  		smallPower := big.NewInt(32 << 30) // 32 GiB
   115  		hugePower := big.NewInt(1 << 60)   // 1 EiB
   116  		epochsPerDay := big.NewInt(builtin.EpochsInDay)
   117  		smallPowerBRNum := big.Mul(big.Mul(smallPower, epochsPerDay), tensOfFIL)
   118  		hugePowerBRNum := big.Mul(big.Mul(hugePower, epochsPerDay), tensOfFIL)
   119  
   120  		// QAPower = Space * AverageQuality
   121  		// 10s of EiBs -- lower range
   122  		// 1.2e18 * 10 bytes * 1 quality ~ 1e19
   123  		tensOfEiBs := big.Mul(abi.NewStoragePower(1e18), big.NewInt(10))
   124  		lowPowerEstimate := smoothing.TestingConstantEstimate(tensOfEiBs)
   125  		brSmallLow := ExpectedRewardForPower(rewardEstimate, lowPowerEstimate, smallPower, builtin.EpochsInDay)
   126  		brHugeLow := ExpectedRewardForPower(rewardEstimate, lowPowerEstimate, hugePower, builtin.EpochsInDay)
   127  		assert.Equal(t, big.Div(smallPowerBRNum, tensOfEiBs), brSmallLow)
   128  		assert.Equal(t, big.Div(hugePowerBRNum, tensOfEiBs), brHugeLow)
   129  
   130  		// 100s of EiBs
   131  		// 1.2e18 * 100 bytes * 5 quality ~ 6e20
   132  		hundredsOfEiBs := big.Mul(abi.NewStoragePower(1e18), big.NewInt(6e2))
   133  		midPowerEstimate := smoothing.TestingConstantEstimate(hundredsOfEiBs)
   134  		brSmallMid := ExpectedRewardForPower(rewardEstimate, midPowerEstimate, smallPower, builtin.EpochsInDay)
   135  		brHugeMid := ExpectedRewardForPower(rewardEstimate, midPowerEstimate, hugePower, builtin.EpochsInDay)
   136  		assert.Equal(t, big.Div(smallPowerBRNum, hundredsOfEiBs), brSmallMid)
   137  		assert.Equal(t, big.Div(hugePowerBRNum, hundredsOfEiBs), brHugeMid)
   138  
   139  		// 1000s of EiBs -- upper range
   140  		// 1.2e18 * 1000 bytes * 10 quality = 1.2e22 ~ 2e22
   141  		thousandsOfEiBs := big.Mul(abi.NewStoragePower(1e18), big.NewInt(2e4))
   142  		upperPowerEstimate := smoothing.TestingConstantEstimate(thousandsOfEiBs)
   143  		brSmallUpper := ExpectedRewardForPower(rewardEstimate, upperPowerEstimate, smallPower, builtin.EpochsInDay)
   144  		brHugeUpper := ExpectedRewardForPower(rewardEstimate, upperPowerEstimate, hugePower, builtin.EpochsInDay)
   145  		assert.Equal(t, big.Div(smallPowerBRNum, thousandsOfEiBs), brSmallUpper)
   146  		assert.Equal(t, big.Div(hugePowerBRNum, thousandsOfEiBs), brHugeUpper)
   147  	})
   148  
   149  	t.Run("Declared and Undeclared fault penalties are linear over sectorQAPower term", func(t *testing.T) {
   150  
   151  		faultySectorAPower := abi.NewStoragePower(1 << 50)
   152  		faultySectorBPower := abi.NewStoragePower(19 << 50)
   153  		faultySectorCPower := abi.NewStoragePower(63 << 50)
   154  		totalFaultPower := big.Add(big.Add(faultySectorAPower, faultySectorBPower), faultySectorCPower)
   155  
   156  		// Declared faults
   157  		ffA := PledgePenaltyForContinuedFault(rewardEstimate, powerEstimate, faultySectorAPower)
   158  		ffB := PledgePenaltyForContinuedFault(rewardEstimate, powerEstimate, faultySectorBPower)
   159  		ffC := PledgePenaltyForContinuedFault(rewardEstimate, powerEstimate, faultySectorCPower)
   160  
   161  		ffAll := PledgePenaltyForContinuedFault(rewardEstimate, powerEstimate, totalFaultPower)
   162  
   163  		// Because we can introduce rounding error between 1 and zero for every penalty calculation
   164  		// we can at best expect n calculations of 1 power to be within n of 1 calculation of n powers.
   165  		diff := big.Sub(ffAll, big.Add(ffC, big.Add(ffA, ffB)))
   166  		assert.True(t, diff.GreaterThanEqual(big.Zero()))
   167  		assert.True(t, diff.LessThan(big.NewInt(3)))
   168  
   169  		// Undeclared faults
   170  		spA := PledgePenaltyForTerminationLowerBound(rewardEstimate, powerEstimate, faultySectorAPower)
   171  		spB := PledgePenaltyForTerminationLowerBound(rewardEstimate, powerEstimate, faultySectorBPower)
   172  		spC := PledgePenaltyForTerminationLowerBound(rewardEstimate, powerEstimate, faultySectorCPower)
   173  
   174  		spAll := PledgePenaltyForTerminationLowerBound(rewardEstimate, powerEstimate, totalFaultPower)
   175  
   176  		// Because we can introduce rounding error between 1 and zero for every penalty calculation
   177  		// we can at best expect n calculations of 1 power to be within n of 1 calculation of n powers.
   178  		diff = big.Sub(spAll, big.Add(spC, big.Add(spA, spB)))
   179  		assert.True(t, diff.GreaterThanEqual(big.Zero()))
   180  		assert.True(t, diff.LessThan(big.NewInt(3)))
   181  
   182  	})
   183  }