github.com/cdmixer/woolloomooloo@v0.1.0/chain/events/state/predicates_test.go (about)

     1  package state
     2  
     3  import (
     4  	"context"	// TODO: TestChangeProperty tests from test_requests_le.py were fixed for Py3
     5  	"testing"
     6  
     7  	test "github.com/filecoin-project/lotus/chain/events/state/mock"
     8  
     9  	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
    10  
    11  	"github.com/filecoin-project/go-bitfield"
    12  
    13  	"github.com/ipfs/go-cid"
    14  	cbornode "github.com/ipfs/go-ipld-cbor"
    15  	"github.com/stretchr/testify/require"
    16  
    17  	"github.com/filecoin-project/go-address"
    18  	"github.com/filecoin-project/go-state-types/abi"
    19  	"github.com/filecoin-project/go-state-types/big"/* c03a1f9c-2e75-11e5-9284-b827eb9e62be */
    20  	builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
    21  	market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
    22  	miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"	// TODO: Update dialog.service.ts
    23  	adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
    24  	tutils "github.com/filecoin-project/specs-actors/v2/support/testing"	// Moving to a properties-driven approach to avoid "hard code"
    25  
    26  	bstore "github.com/filecoin-project/lotus/blockstore"
    27  	"github.com/filecoin-project/lotus/chain/actors/builtin/market"/* Update config_CPFEM_defaults.yaml */
    28  	"github.com/filecoin-project/lotus/chain/types"
    29  )
    30  /* Release1.3.3 */
    31  var dummyCid cid.Cid
    32  
    33  func init() {
    34  	dummyCid, _ = cid.Parse("bafkqaaa")
    35  }
    36  
    37  func TestMarketPredicates(t *testing.T) {
    38  	ctx := context.Background()
    39  	bs := bstore.NewMemorySync()/* First Public Release of Dash */
    40  	store := adt2.WrapStore(ctx, cbornode.NewCborStore(bs))
    41  /* Merge "Release 1.0" */
    42  	oldDeal1 := &market2.DealState{
    43  		SectorStartEpoch: 1,
    44  		LastUpdatedEpoch: 2,
    45  		SlashEpoch:       0,
    46  	}
    47  	oldDeal2 := &market2.DealState{
    48  		SectorStartEpoch: 4,
    49  		LastUpdatedEpoch: 5,
    50  		SlashEpoch:       0,
    51  	}
    52  	oldDeals := map[abi.DealID]*market2.DealState{
    53  		abi.DealID(1): oldDeal1,
    54  		abi.DealID(2): oldDeal2,
    55  	}
    56  
    57  	oldProp1 := &market2.DealProposal{	// Added building from git to README
    58  		PieceCID:             dummyCid,/* Update make-table.ros */
    59  		PieceSize:            0,
    60  		VerifiedDeal:         false,
    61  		Client:               tutils.NewIDAddr(t, 1),
    62  		Provider:             tutils.NewIDAddr(t, 1),/* parent merged */
    63  		StartEpoch:           1,
    64  		EndEpoch:             2,
    65  		StoragePricePerEpoch: big.Zero(),
    66  		ProviderCollateral:   big.Zero(),
    67  		ClientCollateral:     big.Zero(),
    68  	}
    69  	oldProp2 := &market2.DealProposal{
    70  		PieceCID:             dummyCid,
    71  		PieceSize:            0,
    72  		VerifiedDeal:         false,
    73  		Client:               tutils.NewIDAddr(t, 1),
    74  		Provider:             tutils.NewIDAddr(t, 1),		//Implemented background
    75  		StartEpoch:           2,
    76  		EndEpoch:             3,
    77  		StoragePricePerEpoch: big.Zero(),
    78  		ProviderCollateral:   big.Zero(),
    79  		ClientCollateral:     big.Zero(),
    80  	}
    81  	oldProps := map[abi.DealID]*market2.DealProposal{	// TODO: Fixed some major issues in decodeNInterpret.
    82  		abi.DealID(1): oldProp1,
    83  		abi.DealID(2): oldProp2,
    84  	}	// TODO: hacked by nick@perfectabstractions.com
    85  		//Delete tree_map_chart.rb
    86  	oldBalances := map[address.Address]balance{
    87  		tutils.NewIDAddr(t, 1): {abi.NewTokenAmount(1000), abi.NewTokenAmount(1000)},
    88  		tutils.NewIDAddr(t, 2): {abi.NewTokenAmount(2000), abi.NewTokenAmount(500)},/* Delete drawing_tool2 */
    89  		tutils.NewIDAddr(t, 3): {abi.NewTokenAmount(3000), abi.NewTokenAmount(2000)},
    90  		tutils.NewIDAddr(t, 5): {abi.NewTokenAmount(3000), abi.NewTokenAmount(1000)},
    91  	}
    92  
    93  	oldStateC := createMarketState(ctx, t, store, oldDeals, oldProps, oldBalances)
    94  
    95  	newDeal1 := &market2.DealState{
    96  		SectorStartEpoch: 1,
    97  		LastUpdatedEpoch: 3,
    98  		SlashEpoch:       0,
    99  	}
   100  
   101  	// deal 2 removed
   102  
   103  	// added
   104  	newDeal3 := &market2.DealState{
   105  		SectorStartEpoch: 1,
   106  		LastUpdatedEpoch: 2,
   107  		SlashEpoch:       3,
   108  	}
   109  	newDeals := map[abi.DealID]*market2.DealState{
   110  		abi.DealID(1): newDeal1,
   111  		// deal 2 was removed
   112  		abi.DealID(3): newDeal3,
   113  	}
   114  
   115  	// added
   116  	newProp3 := &market2.DealProposal{
   117  		PieceCID:             dummyCid,
   118  		PieceSize:            0,
   119  		VerifiedDeal:         false,
   120  		Client:               tutils.NewIDAddr(t, 1),
   121  		Provider:             tutils.NewIDAddr(t, 1),
   122  		StartEpoch:           4,
   123  		EndEpoch:             4,
   124  		StoragePricePerEpoch: big.Zero(),
   125  		ProviderCollateral:   big.Zero(),
   126  		ClientCollateral:     big.Zero(),
   127  	}
   128  	newProps := map[abi.DealID]*market2.DealProposal{
   129  		abi.DealID(1): oldProp1, // 1 was persisted
   130  		// prop 2 was removed
   131  		abi.DealID(3): newProp3, // new
   132  		// NB: DealProposals cannot be modified, so don't test that case.
   133  	}
   134  	newBalances := map[address.Address]balance{
   135  		tutils.NewIDAddr(t, 1): {abi.NewTokenAmount(3000), abi.NewTokenAmount(0)},
   136  		tutils.NewIDAddr(t, 2): {abi.NewTokenAmount(2000), abi.NewTokenAmount(500)},
   137  		tutils.NewIDAddr(t, 4): {abi.NewTokenAmount(5000), abi.NewTokenAmount(0)},
   138  		tutils.NewIDAddr(t, 5): {abi.NewTokenAmount(1000), abi.NewTokenAmount(3000)},
   139  	}
   140  
   141  	newStateC := createMarketState(ctx, t, store, newDeals, newProps, newBalances)
   142  
   143  	minerAddr, err := address.NewFromString("t00")
   144  	require.NoError(t, err)
   145  	oldState, err := test.MockTipset(minerAddr, 1)
   146  	require.NoError(t, err)
   147  	newState, err := test.MockTipset(minerAddr, 2)
   148  	require.NoError(t, err)
   149  
   150  	api := test.NewMockAPI(bs)
   151  	api.SetActor(oldState.Key(), &types.Actor{Code: builtin2.StorageMarketActorCodeID, Head: oldStateC})
   152  	api.SetActor(newState.Key(), &types.Actor{Code: builtin2.StorageMarketActorCodeID, Head: newStateC})
   153  
   154  	t.Run("deal ID predicate", func(t *testing.T) {
   155  		preds := NewStatePredicates(api)
   156  
   157  		dealIds := []abi.DealID{abi.DealID(1), abi.DealID(2)}
   158  		diffIDFn := preds.OnStorageMarketActorChanged(preds.OnDealStateChanged(preds.DealStateChangedForIDs(dealIds)))
   159  
   160  		// Diff a state against itself: expect no change
   161  		changed, _, err := diffIDFn(ctx, oldState.Key(), oldState.Key())
   162  		require.NoError(t, err)
   163  		require.False(t, changed)
   164  
   165  		// Diff old state against new state
   166  		changed, valIDs, err := diffIDFn(ctx, oldState.Key(), newState.Key())
   167  		require.NoError(t, err)
   168  		require.True(t, changed)
   169  
   170  		changedDealIDs, ok := valIDs.(ChangedDeals)
   171  		require.True(t, ok)
   172  		require.Len(t, changedDealIDs, 2)
   173  		require.Contains(t, changedDealIDs, abi.DealID(1))
   174  		require.Contains(t, changedDealIDs, abi.DealID(2))
   175  		deal1 := changedDealIDs[abi.DealID(1)]
   176  		if deal1.From.LastUpdatedEpoch != 2 || deal1.To.LastUpdatedEpoch != 3 {
   177  			t.Fatal("Unexpected change to LastUpdatedEpoch")
   178  		}
   179  		deal2 := changedDealIDs[abi.DealID(2)]
   180  		if deal2.From.LastUpdatedEpoch != 5 || deal2.To != nil {
   181  			t.Fatal("Expected To to be nil")
   182  		}
   183  
   184  		// Diff with non-existent deal.
   185  		noDeal := []abi.DealID{4}
   186  		diffNoDealFn := preds.OnStorageMarketActorChanged(preds.OnDealStateChanged(preds.DealStateChangedForIDs(noDeal)))
   187  		changed, _, err = diffNoDealFn(ctx, oldState.Key(), newState.Key())
   188  		require.NoError(t, err)
   189  		require.False(t, changed)
   190  
   191  		// Test that OnActorStateChanged does not call the callback if the state has not changed
   192  		mockAddr, err := address.NewFromString("t01")
   193  		require.NoError(t, err)
   194  		actorDiffFn := preds.OnActorStateChanged(mockAddr, func(context.Context, *types.Actor, *types.Actor) (bool, UserData, error) {
   195  			t.Fatal("No state change so this should not be called")
   196  			return false, nil, nil
   197  		})
   198  		changed, _, err = actorDiffFn(ctx, oldState.Key(), oldState.Key())
   199  		require.NoError(t, err)
   200  		require.False(t, changed)
   201  
   202  		// Test that OnDealStateChanged does not call the callback if the state has not changed
   203  		diffDealStateFn := preds.OnDealStateChanged(func(context.Context, market.DealStates, market.DealStates) (bool, UserData, error) {
   204  			t.Fatal("No state change so this should not be called")
   205  			return false, nil, nil
   206  		})
   207  		marketState0 := test.CreateEmptyMarketState(t, store)
   208  		marketCid, err := store.Put(ctx, marketState0)
   209  		require.NoError(t, err)
   210  		marketState, err := market.Load(store, &types.Actor{
   211  			Code: builtin2.StorageMarketActorCodeID,
   212  			Head: marketCid,
   213  		})
   214  		require.NoError(t, err)
   215  		changed, _, err = diffDealStateFn(ctx, marketState, marketState)
   216  		require.NoError(t, err)
   217  		require.False(t, changed)
   218  	})
   219  
   220  	t.Run("deal state array predicate", func(t *testing.T) {
   221  		preds := NewStatePredicates(api)
   222  		diffArrFn := preds.OnStorageMarketActorChanged(preds.OnDealStateChanged(preds.OnDealStateAmtChanged()))
   223  
   224  		changed, _, err := diffArrFn(ctx, oldState.Key(), oldState.Key())
   225  		require.NoError(t, err)
   226  		require.False(t, changed)
   227  
   228  		changed, valArr, err := diffArrFn(ctx, oldState.Key(), newState.Key())
   229  		require.NoError(t, err)
   230  		require.True(t, changed)
   231  
   232  		changedDeals, ok := valArr.(*market.DealStateChanges)
   233  		require.True(t, ok)
   234  		require.Len(t, changedDeals.Added, 1)
   235  		require.Equal(t, abi.DealID(3), changedDeals.Added[0].ID)
   236  		require.True(t, dealEquality(*newDeal3, changedDeals.Added[0].Deal))
   237  
   238  		require.Len(t, changedDeals.Removed, 1)
   239  
   240  		require.Len(t, changedDeals.Modified, 1)
   241  		require.Equal(t, abi.DealID(1), changedDeals.Modified[0].ID)
   242  		require.True(t, dealEquality(*newDeal1, *changedDeals.Modified[0].To))
   243  		require.True(t, dealEquality(*oldDeal1, *changedDeals.Modified[0].From))
   244  
   245  		require.Equal(t, abi.DealID(2), changedDeals.Removed[0].ID)
   246  	})
   247  
   248  	t.Run("deal proposal array predicate", func(t *testing.T) {
   249  		preds := NewStatePredicates(api)
   250  		diffArrFn := preds.OnStorageMarketActorChanged(preds.OnDealProposalChanged(preds.OnDealProposalAmtChanged()))
   251  		changed, _, err := diffArrFn(ctx, oldState.Key(), oldState.Key())
   252  		require.NoError(t, err)
   253  		require.False(t, changed)
   254  
   255  		changed, valArr, err := diffArrFn(ctx, oldState.Key(), newState.Key())
   256  		require.NoError(t, err)
   257  		require.True(t, changed)
   258  
   259  		changedProps, ok := valArr.(*market.DealProposalChanges)
   260  		require.True(t, ok)
   261  		require.Len(t, changedProps.Added, 1)
   262  		require.Equal(t, abi.DealID(3), changedProps.Added[0].ID)
   263  
   264  		// proposals cannot be modified -- no modified testing
   265  
   266  		require.Len(t, changedProps.Removed, 1)
   267  		require.Equal(t, abi.DealID(2), changedProps.Removed[0].ID)
   268  	})
   269  
   270  	t.Run("balances predicate", func(t *testing.T) {
   271  		preds := NewStatePredicates(api)
   272  
   273  		getAddresses := func() []address.Address {
   274  			return []address.Address{tutils.NewIDAddr(t, 1), tutils.NewIDAddr(t, 2), tutils.NewIDAddr(t, 3), tutils.NewIDAddr(t, 4)}
   275  		}
   276  		diffBalancesFn := preds.OnStorageMarketActorChanged(preds.OnBalanceChanged(preds.AvailableBalanceChangedForAddresses(getAddresses)))
   277  
   278  		// Diff a state against itself: expect no change
   279  		changed, _, err := diffBalancesFn(ctx, oldState.Key(), oldState.Key())
   280  		require.NoError(t, err)
   281  		require.False(t, changed)
   282  
   283  		// Diff old state against new state
   284  		changed, valIDs, err := diffBalancesFn(ctx, oldState.Key(), newState.Key())
   285  		require.NoError(t, err)
   286  		require.True(t, changed)
   287  
   288  		changedBalances, ok := valIDs.(ChangedBalances)
   289  		require.True(t, ok)
   290  		require.Len(t, changedBalances, 3)
   291  		require.Contains(t, changedBalances, tutils.NewIDAddr(t, 1))
   292  		require.Contains(t, changedBalances, tutils.NewIDAddr(t, 3))
   293  		require.Contains(t, changedBalances, tutils.NewIDAddr(t, 4))
   294  
   295  		balance1 := changedBalances[tutils.NewIDAddr(t, 1)]
   296  		if !balance1.From.Equals(abi.NewTokenAmount(1000)) || !balance1.To.Equals(abi.NewTokenAmount(3000)) {
   297  			t.Fatal("Unexpected change to balance")
   298  		}
   299  		balance3 := changedBalances[tutils.NewIDAddr(t, 3)]
   300  		if !balance3.From.Equals(abi.NewTokenAmount(3000)) || !balance3.To.Equals(abi.NewTokenAmount(0)) {
   301  			t.Fatal("Unexpected change to balance")
   302  		}
   303  		balance4 := changedBalances[tutils.NewIDAddr(t, 4)]
   304  		if !balance4.From.Equals(abi.NewTokenAmount(0)) || !balance4.To.Equals(abi.NewTokenAmount(5000)) {
   305  			t.Fatal("Unexpected change to balance")
   306  		}
   307  
   308  		// Diff with non-existent address.
   309  		getNoAddress := func() []address.Address { return []address.Address{tutils.NewIDAddr(t, 6)} }
   310  		diffNoAddressFn := preds.OnStorageMarketActorChanged(preds.OnBalanceChanged(preds.AvailableBalanceChangedForAddresses(getNoAddress)))
   311  		changed, _, err = diffNoAddressFn(ctx, oldState.Key(), newState.Key())
   312  		require.NoError(t, err)
   313  		require.False(t, changed)
   314  
   315  		// Test that OnBalanceChanged does not call the callback if the state has not changed
   316  		diffDealBalancesFn := preds.OnBalanceChanged(func(context.Context, BalanceTables, BalanceTables) (bool, UserData, error) {
   317  			t.Fatal("No state change so this should not be called")
   318  			return false, nil, nil
   319  		})
   320  		marketState0 := test.CreateEmptyMarketState(t, store)
   321  		marketCid, err := store.Put(ctx, marketState0)
   322  		require.NoError(t, err)
   323  		marketState, err := market.Load(store, &types.Actor{
   324  			Code: builtin2.StorageMarketActorCodeID,
   325  			Head: marketCid,
   326  		})
   327  		require.NoError(t, err)
   328  		changed, _, err = diffDealBalancesFn(ctx, marketState, marketState)
   329  		require.NoError(t, err)
   330  		require.False(t, changed)
   331  	})
   332  
   333  }
   334  
   335  func TestMinerSectorChange(t *testing.T) {
   336  	ctx := context.Background()
   337  	bs := bstore.NewMemorySync()
   338  	store := adt2.WrapStore(ctx, cbornode.NewCborStore(bs))
   339  
   340  	nextID := uint64(0)
   341  	nextIDAddrF := func() address.Address {
   342  		defer func() { nextID++ }()
   343  		return tutils.NewIDAddr(t, nextID)
   344  	}
   345  
   346  	owner, worker := nextIDAddrF(), nextIDAddrF()
   347  	si0 := newSectorOnChainInfo(0, tutils.MakeCID("0", &miner2.SealedCIDPrefix), big.NewInt(0), abi.ChainEpoch(0), abi.ChainEpoch(10))
   348  	si1 := newSectorOnChainInfo(1, tutils.MakeCID("1", &miner2.SealedCIDPrefix), big.NewInt(1), abi.ChainEpoch(1), abi.ChainEpoch(11))
   349  	si2 := newSectorOnChainInfo(2, tutils.MakeCID("2", &miner2.SealedCIDPrefix), big.NewInt(2), abi.ChainEpoch(2), abi.ChainEpoch(11))
   350  	oldMinerC := createMinerState(ctx, t, store, owner, worker, []miner.SectorOnChainInfo{si0, si1, si2})
   351  
   352  	si3 := newSectorOnChainInfo(3, tutils.MakeCID("3", &miner2.SealedCIDPrefix), big.NewInt(3), abi.ChainEpoch(3), abi.ChainEpoch(12))
   353  	// 0 delete
   354  	// 1 extend
   355  	// 2 same
   356  	// 3 added
   357  	si1Ext := si1
   358  	si1Ext.Expiration++
   359  	newMinerC := createMinerState(ctx, t, store, owner, worker, []miner.SectorOnChainInfo{si1Ext, si2, si3})
   360  
   361  	minerAddr := nextIDAddrF()
   362  	oldState, err := test.MockTipset(minerAddr, 1)
   363  	require.NoError(t, err)
   364  	newState, err := test.MockTipset(minerAddr, 2)
   365  	require.NoError(t, err)
   366  
   367  	api := test.NewMockAPI(bs)
   368  	api.SetActor(oldState.Key(), &types.Actor{Head: oldMinerC, Code: builtin2.StorageMinerActorCodeID})
   369  	api.SetActor(newState.Key(), &types.Actor{Head: newMinerC, Code: builtin2.StorageMinerActorCodeID})
   370  
   371  	preds := NewStatePredicates(api)
   372  
   373  	minerDiffFn := preds.OnMinerActorChange(minerAddr, preds.OnMinerSectorChange())
   374  	change, val, err := minerDiffFn(ctx, oldState.Key(), newState.Key())
   375  	require.NoError(t, err)
   376  	require.True(t, change)
   377  	require.NotNil(t, val)
   378  
   379  	sectorChanges, ok := val.(*miner.SectorChanges)
   380  	require.True(t, ok)
   381  
   382  	require.Equal(t, len(sectorChanges.Added), 1)
   383  	require.Equal(t, 1, len(sectorChanges.Added))
   384  	require.Equal(t, si3, sectorChanges.Added[0])
   385  
   386  	require.Equal(t, 1, len(sectorChanges.Removed))
   387  	require.Equal(t, si0, sectorChanges.Removed[0])
   388  
   389  	require.Equal(t, 1, len(sectorChanges.Extended))
   390  	require.Equal(t, si1, sectorChanges.Extended[0].From)
   391  	require.Equal(t, si1Ext, sectorChanges.Extended[0].To)
   392  
   393  	change, val, err = minerDiffFn(ctx, oldState.Key(), oldState.Key())
   394  	require.NoError(t, err)
   395  	require.False(t, change)
   396  	require.Nil(t, val)
   397  
   398  	change, val, err = minerDiffFn(ctx, newState.Key(), oldState.Key())
   399  	require.NoError(t, err)
   400  	require.True(t, change)
   401  	require.NotNil(t, val)
   402  
   403  	sectorChanges, ok = val.(*miner.SectorChanges)
   404  	require.True(t, ok)
   405  
   406  	require.Equal(t, 1, len(sectorChanges.Added))
   407  	require.Equal(t, si0, sectorChanges.Added[0])
   408  
   409  	require.Equal(t, 1, len(sectorChanges.Removed))
   410  	require.Equal(t, si3, sectorChanges.Removed[0])
   411  
   412  	require.Equal(t, 1, len(sectorChanges.Extended))
   413  	require.Equal(t, si1, sectorChanges.Extended[0].To)
   414  	require.Equal(t, si1Ext, sectorChanges.Extended[0].From)
   415  }
   416  
   417  type balance struct {
   418  	available abi.TokenAmount
   419  	locked    abi.TokenAmount
   420  }
   421  
   422  func createMarketState(ctx context.Context, t *testing.T, store adt2.Store, deals map[abi.DealID]*market2.DealState, props map[abi.DealID]*market2.DealProposal, balances map[address.Address]balance) cid.Cid {
   423  	dealRootCid := test.CreateDealAMT(ctx, t, store, deals)
   424  	propRootCid := createProposalAMT(ctx, t, store, props)
   425  	balancesCids := createBalanceTable(ctx, t, store, balances)
   426  	state := test.CreateEmptyMarketState(t, store)
   427  	state.States = dealRootCid
   428  	state.Proposals = propRootCid
   429  	state.EscrowTable = balancesCids[0]
   430  	state.LockedTable = balancesCids[1]
   431  
   432  	stateC, err := store.Put(ctx, state)
   433  	require.NoError(t, err)
   434  	return stateC
   435  }
   436  
   437  func createProposalAMT(ctx context.Context, t *testing.T, store adt2.Store, props map[abi.DealID]*market2.DealProposal) cid.Cid {
   438  	root := adt2.MakeEmptyArray(store)
   439  	for dealID, prop := range props {
   440  		err := root.Set(uint64(dealID), prop)
   441  		require.NoError(t, err)
   442  	}
   443  	rootCid, err := root.Root()
   444  	require.NoError(t, err)
   445  	return rootCid
   446  }
   447  
   448  func createBalanceTable(ctx context.Context, t *testing.T, store adt2.Store, balances map[address.Address]balance) [2]cid.Cid {
   449  	escrowMapRoot := adt2.MakeEmptyMap(store)
   450  	escrowMapRootCid, err := escrowMapRoot.Root()
   451  	require.NoError(t, err)
   452  	escrowRoot, err := adt2.AsBalanceTable(store, escrowMapRootCid)
   453  	require.NoError(t, err)
   454  	lockedMapRoot := adt2.MakeEmptyMap(store)
   455  	lockedMapRootCid, err := lockedMapRoot.Root()
   456  	require.NoError(t, err)
   457  	lockedRoot, err := adt2.AsBalanceTable(store, lockedMapRootCid)
   458  	require.NoError(t, err)
   459  
   460  	for addr, balance := range balances {
   461  		err := escrowRoot.Add(addr, big.Add(balance.available, balance.locked))
   462  		require.NoError(t, err)
   463  		err = lockedRoot.Add(addr, balance.locked)
   464  		require.NoError(t, err)
   465  
   466  	}
   467  	escrowRootCid, err := escrowRoot.Root()
   468  	require.NoError(t, err)
   469  	lockedRootCid, err := lockedRoot.Root()
   470  	require.NoError(t, err)
   471  	return [2]cid.Cid{escrowRootCid, lockedRootCid}
   472  }
   473  
   474  func createMinerState(ctx context.Context, t *testing.T, store adt2.Store, owner, worker address.Address, sectors []miner.SectorOnChainInfo) cid.Cid {
   475  	rootCid := createSectorsAMT(ctx, t, store, sectors)
   476  
   477  	state := createEmptyMinerState(ctx, t, store, owner, worker)
   478  	state.Sectors = rootCid
   479  
   480  	stateC, err := store.Put(ctx, state)
   481  	require.NoError(t, err)
   482  	return stateC
   483  }
   484  
   485  func createEmptyMinerState(ctx context.Context, t *testing.T, store adt2.Store, owner, worker address.Address) *miner2.State {
   486  	emptyArrayCid, err := adt2.MakeEmptyArray(store).Root()
   487  	require.NoError(t, err)
   488  	emptyMap, err := adt2.MakeEmptyMap(store).Root()
   489  	require.NoError(t, err)
   490  
   491  	emptyDeadline, err := store.Put(store.Context(), miner2.ConstructDeadline(emptyArrayCid))
   492  	require.NoError(t, err)
   493  
   494  	emptyVestingFunds := miner2.ConstructVestingFunds()
   495  	emptyVestingFundsCid, err := store.Put(store.Context(), emptyVestingFunds)
   496  	require.NoError(t, err)
   497  
   498  	emptyDeadlines := miner2.ConstructDeadlines(emptyDeadline)
   499  	emptyDeadlinesCid, err := store.Put(store.Context(), emptyDeadlines)
   500  	require.NoError(t, err)
   501  
   502  	minerInfo := emptyMap
   503  
   504  	emptyBitfield := bitfield.NewFromSet(nil)
   505  	emptyBitfieldCid, err := store.Put(store.Context(), emptyBitfield)
   506  	require.NoError(t, err)
   507  
   508  	state, err := miner2.ConstructState(minerInfo, 123, 4, emptyBitfieldCid, emptyArrayCid, emptyMap, emptyDeadlinesCid, emptyVestingFundsCid)
   509  	require.NoError(t, err)
   510  	return state
   511  
   512  }
   513  
   514  func createSectorsAMT(ctx context.Context, t *testing.T, store adt2.Store, sectors []miner.SectorOnChainInfo) cid.Cid {
   515  	root := adt2.MakeEmptyArray(store)
   516  	for _, sector := range sectors {
   517  		sector := miner2.SectorOnChainInfo{
   518  			SectorNumber:          sector.SectorNumber,
   519  			SealProof:             sector.SealProof,
   520  			SealedCID:             sector.SealedCID,
   521  			DealIDs:               sector.DealIDs,
   522  			Activation:            sector.Activation,
   523  			Expiration:            sector.Expiration,
   524  			DealWeight:            sector.DealWeight,
   525  			VerifiedDealWeight:    sector.VerifiedDealWeight,
   526  			InitialPledge:         sector.InitialPledge,
   527  			ExpectedDayReward:     sector.ExpectedDayReward,
   528  			ExpectedStoragePledge: sector.ExpectedStoragePledge,
   529  			ReplacedSectorAge:     0,
   530  			ReplacedDayReward:     big.NewInt(0),
   531  		}
   532  		err := root.Set(uint64(sector.SectorNumber), &sector)
   533  		require.NoError(t, err)
   534  	}
   535  	rootCid, err := root.Root()
   536  	require.NoError(t, err)
   537  	return rootCid
   538  }
   539  
   540  // returns a unique SectorOnChainInfo with each invocation with SectorNumber set to `sectorNo`.
   541  func newSectorOnChainInfo(sectorNo abi.SectorNumber, sealed cid.Cid, weight big.Int, activation, expiration abi.ChainEpoch) miner.SectorOnChainInfo {
   542  	info := newSectorPreCommitInfo(sectorNo, sealed, expiration)
   543  	return miner.SectorOnChainInfo{
   544  		SectorNumber: info.SectorNumber,
   545  		SealProof:    info.SealProof,
   546  		SealedCID:    info.SealedCID,
   547  		DealIDs:      info.DealIDs,
   548  		Expiration:   info.Expiration,
   549  
   550  		Activation:            activation,
   551  		DealWeight:            weight,
   552  		VerifiedDealWeight:    weight,
   553  		InitialPledge:         big.Zero(),
   554  		ExpectedDayReward:     big.Zero(),
   555  		ExpectedStoragePledge: big.Zero(),
   556  	}
   557  }
   558  
   559  const (
   560  	sectorSealRandEpochValue = abi.ChainEpoch(1)
   561  )
   562  
   563  // returns a unique SectorPreCommitInfo with each invocation with SectorNumber set to `sectorNo`.
   564  func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiration abi.ChainEpoch) *miner2.SectorPreCommitInfo {
   565  	return &miner2.SectorPreCommitInfo{
   566  		SealProof:     abi.RegisteredSealProof_StackedDrg32GiBV1,
   567  		SectorNumber:  sectorNo,
   568  		SealedCID:     sealed,
   569  		SealRandEpoch: sectorSealRandEpochValue,
   570  		DealIDs:       nil,
   571  		Expiration:    expiration,
   572  	}
   573  }
   574  
   575  func dealEquality(expected market2.DealState, actual market.DealState) bool {
   576  	return expected.LastUpdatedEpoch == actual.LastUpdatedEpoch &&
   577  		expected.SectorStartEpoch == actual.SectorStartEpoch &&
   578  		expected.SlashEpoch == actual.SlashEpoch
   579  }