Skip to content

Commit

Permalink
Fix/fee debt assumptions (#113)
Browse files Browse the repository at this point in the history
* Fix broken assumptions

* Add tests

* Fix failling test
  • Loading branch information
Schwartz10 authored Sep 25, 2024
1 parent 251c3bd commit 8ff6a1b
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 28 deletions.
20 changes: 4 additions & 16 deletions econ/terminate.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ func SampleSectors(sectors []uint64, samples int) []uint64 {
if sectorCount <= samples {
return sectors
}

// Compute the step size for evenly spaced sampling
step := float64(sectorCount-1) / float64(samples-1)

Expand Down Expand Up @@ -306,10 +306,10 @@ func TerminateSectors(ctx context.Context, api *lotusapi.FullNodeStruct, minerAd

// Assumptions:
// 1. there cannot be negative fee debt
// 2. there cannot be positive fee debt with a positive balance
// 2. there cannot be positive fee debt with a positive balance - BROKEN ASSUMPTION
// 3. there cannot be positive fee debt with a positive available balance
// 4. there cannot be a positive fee debt with a positive initial pledge
// 5. there cannot be a positive fee debt with a positive vesting funds
// 4. there cannot be a positive fee debt with a positive initial pledge - BROKEN ASSUMPTION
// 5. there cannot be a positive fee debt with a positive vesting funds - BROKEN ASSUMPTION
// 6. there cannot be a negative termination fee
// 7. there cannot be a negative initial pledge
// 8. with no fee debt, available balance should always be positive (or 0)
Expand All @@ -328,22 +328,10 @@ func failOnBrokenAssumptions(minerAddr address.Address, result *TerminateSectorR

// fee debt exists
if result.FeeDebt.Cmp(big.NewInt(0)) > 0 {
// 2.there cannot be positive fee debt with a positive balance
if result.TotalBalance.Cmp(big.NewInt(0)) > 0 {
return xerrors.Errorf("miner %s: positive fee debt with positive balance: %v", minerAddr, result.FeeDebt)
}
// 3. there cannot be positive fee debt with a positive available balance
if result.AvailableBalance.Cmp(big.NewInt(0)) > 0 {
return xerrors.Errorf("miner %s: positive fee debt with positive available balance: %v", minerAddr, result.FeeDebt)
}
// 4. there cannot be a positive fee debt with a positive initial pledge
if result.InitialPledge.Cmp(big.NewInt(0)) > 0 {
return xerrors.Errorf("miner %s: positive fee debt with positive initial pledge: %v", minerAddr, result.FeeDebt)
}
// 5. there cannot be a positive fee debt with a positive vesting funds
if result.VestingFunds.Cmp(big.NewInt(0)) > 0 {
return xerrors.Errorf("miner %s: positive fee debt with positive vesting funds: %v", minerAddr, result.FeeDebt)
}
} else if result.FeeDebt.Cmp(big.NewInt(0)) == 0 {
// no fee debt
// 8. with no fee debt, available balance should always be positive (or 0)
Expand Down
44 changes: 32 additions & 12 deletions econ/terminate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,14 +331,15 @@ func TestEstimateTerminationPenalty2(t *testing.T) {
}
}

var BLOCK_HEIGHT = big.NewInt(4198539)
var BASE_BLOCK_HEIGHT = big.NewInt(4198539)

type baseFiTest struct {
*BaseFi

maxBorrowAndSeal *big.Int
maxBorrowAndWithdraw *big.Int
liquidationValue *big.Int
height *big.Int
}

var baseFiTests = []struct {
Expand All @@ -360,6 +361,7 @@ var baseFiTests = []struct {
maxBorrowAndSeal: bigFromStr("50375782116425480034999"),
maxBorrowAndWithdraw: bigFromStr("12593945529106370008750"),
liquidationValue: bigFromStr("16791927372141826678333"),
height: BASE_BLOCK_HEIGHT,
}},
{"miner with fee debt", "f01836766", baseFiTest{
BaseFi: &BaseFi{
Expand All @@ -375,6 +377,7 @@ var baseFiTests = []struct {
maxBorrowAndSeal: big.NewInt(0),
maxBorrowAndWithdraw: big.NewInt(0),
liquidationValue: big.NewInt(0),
height: BASE_BLOCK_HEIGHT,
}},
{"inactive miner (all 0s)", "f01156", baseFiTest{
BaseFi: &BaseFi{
Expand All @@ -390,6 +393,7 @@ var baseFiTests = []struct {
maxBorrowAndSeal: big.NewInt(0),
maxBorrowAndWithdraw: big.NewInt(0),
liquidationValue: big.NewInt(0),
height: BASE_BLOCK_HEIGHT,
}},
{"normal miner", "f01344987", baseFiTest{
BaseFi: &BaseFi{
Expand All @@ -405,6 +409,23 @@ var baseFiTests = []struct {
maxBorrowAndSeal: bigFromStr("492527766798191726655114"),
maxBorrowAndWithdraw: bigFromStr("123131941699547931663779"),
liquidationValue: bigFromStr("164175922266063908885038"),
height: BASE_BLOCK_HEIGHT,
}},
{"miner with fee debt and positive balance", "f01931245", baseFiTest{
BaseFi: &BaseFi{
Balance: bigFromStr("65041872611791874551"),
AvailableBalance: bigFromStr("0"),
LockedRewards: bigFromStr("137666159110180561"),
InitialPledge: bigFromStr("64904206452681693990"),
FeeDebt: bigFromStr("957933257513729319"),
TerminationFee: bigFromStr("12832724091624933434"),
LiveSectors: big.NewInt(323),
FaultySectors: big.NewInt(323),
},
maxBorrowAndSeal: bigFromStr("156627445560500823351"),
maxBorrowAndWithdraw: bigFromStr("39156861390125205838"),
liquidationValue: bigFromStr("52209148520166941117"),
height: big.NewInt(4299545),
}},
}

Expand All @@ -420,14 +441,13 @@ func TestMinerFi(t *testing.T) {
}
defer closer()

ts, err := lapi.ChainGetTipSetByHeight(context.Background(), abi.ChainEpoch(BLOCK_HEIGHT.Int64()), types.EmptyTSK)
if err != nil {
t.Fatal(err)
}

for _, tt := range baseFiTests {
testname := fmt.Sprintf("%s:%s", tt.name, tt.miner)
t.Run(testname, func(t *testing.T) {
ts, err := lapi.ChainGetTipSetByHeight(context.Background(), abi.ChainEpoch(tt.want.height.Int64()), types.EmptyTSK)
if err != nil {
t.Fatal(err)
}
minerAddr, err := address.NewFromString(tt.miner)
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -490,7 +510,7 @@ var agentTests = []struct {
want agentFiTest
}{
// agent 59
{"agent many miners", "0x64Ea1aD49A78B6A6878c4975566b8953b1Ef1e79", BLOCK_HEIGHT, agentFiTest{
{"agent many miners", "0x64Ea1aD49A78B6A6878c4975566b8953b1Ef1e79", BASE_BLOCK_HEIGHT, agentFiTest{
AgentFi: &AgentFi{
BaseFi: BaseFi{
Balance: bigFromStr("2090733730144435384596917"),
Expand All @@ -517,7 +537,7 @@ var agentTests = []struct {
dtl: 0.574289111476492565,
}},
// agent 27
{"agent no miners", "0xDBa96B0FDbc87C7eEb641Ee37EAFC55B355079E4", BLOCK_HEIGHT, agentFiTest{
{"agent no miners", "0xDBa96B0FDbc87C7eEb641Ee37EAFC55B355079E4", BASE_BLOCK_HEIGHT, agentFiTest{
AgentFi: EmptyAgentFi(),
balance: big.NewInt(0),
maxBorrowAndSeal: big.NewInt(0),
Expand All @@ -530,7 +550,7 @@ var agentTests = []struct {
dtl: 0,
}},
// agent 2
{"agent single miner", "0xf0F1ceCCF78D411EeD9Ca190ca7F157140cCB2d3", BLOCK_HEIGHT, agentFiTest{
{"agent single miner", "0xf0F1ceCCF78D411EeD9Ca190ca7F157140cCB2d3", BASE_BLOCK_HEIGHT, agentFiTest{
AgentFi: &AgentFi{
BaseFi: BaseFi{
Balance: bigFromStr("133252309755096579751"),
Expand All @@ -557,7 +577,7 @@ var agentTests = []struct {
dtl: 0.016608593934123496,
}},
// agent 91
{"agent miner with fee debt", "0xFF65F5f3D309fEA7aA2d4cB2727E918FAb0aE7F7", BLOCK_HEIGHT, agentFiTest{
{"agent miner with fee debt", "0xFF65F5f3D309fEA7aA2d4cB2727E918FAb0aE7F7", BASE_BLOCK_HEIGHT, agentFiTest{
AgentFi: &AgentFi{
BaseFi: BaseFi{
Balance: bigFromStr("0"),
Expand Down Expand Up @@ -675,8 +695,8 @@ func TestComputePerc(t *testing.T) {
i := bigFromStr("28202982363374106229")

perc := computePerc(new(big.Int).Add(p, i), lv)
exp := big.NewFloat(0.394356164017979036)
if perc.Cmp(exp) != 0 {
exp, _ := new(big.Float).SetString("0.394356164017979036")
if perc.String() != exp.String() {
t.Fatalf("Expected perc: %v, actual: %v", exp, perc)
}
}
Expand Down

0 comments on commit 8ff6a1b

Please sign in to comment.