188 lines
5.8 KiB
Go
188 lines
5.8 KiB
Go
// stm: #integration
|
|
package itests
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/filecoin-project/go-state-types/abi"
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
"github.com/filecoin-project/lotus/chain/wallet/key"
|
|
"github.com/filecoin-project/lotus/itests/kit"
|
|
"github.com/filecoin-project/lotus/markets/storageadapter"
|
|
"github.com/filecoin-project/lotus/node"
|
|
"github.com/filecoin-project/lotus/node/config"
|
|
"github.com/filecoin-project/lotus/node/modules"
|
|
"github.com/filecoin-project/lotus/storage/ctladdr"
|
|
)
|
|
|
|
var (
|
|
publishPeriod = 1 * time.Second
|
|
maxDealsPerMsg = uint64(2) // Set max deals per publish deals message to 2
|
|
|
|
blockTime = 3 * time.Millisecond
|
|
)
|
|
|
|
func TestDealsRetryLackOfFunds(t *testing.T) {
|
|
t.Run("cover-gas", func(t *testing.T) {
|
|
testDealsRetryLackOfFunds(t, types.NewInt(1020000000000))
|
|
})
|
|
t.Run("empty", func(t *testing.T) {
|
|
testDealsRetryLackOfFunds(t, types.NewInt(1))
|
|
})
|
|
}
|
|
|
|
func testDealsRetryLackOfFunds(t *testing.T, publishStorageAccountFunds abi.TokenAmount) {
|
|
//stm: @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001,
|
|
//stm: @CHAIN_SYNCER_START_001, @CHAIN_SYNCER_SYNC_001, @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01
|
|
//stm: @CHAIN_SYNCER_COLLECT_CHAIN_001, @CHAIN_SYNCER_COLLECT_HEADERS_001, @CHAIN_SYNCER_VALIDATE_TIPSET_001
|
|
//stm: @CHAIN_SYNCER_NEW_PEER_HEAD_001, @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_STOP_001
|
|
|
|
//stm: @CHAIN_INCOMING_HANDLE_INCOMING_BLOCKS_001, @CHAIN_INCOMING_VALIDATE_BLOCK_PUBSUB_001, @CHAIN_INCOMING_VALIDATE_MESSAGE_PUBSUB_001
|
|
//stm: @CLIENT_STORAGE_DEALS_LIST_IMPORTS_001
|
|
ctx := context.Background()
|
|
|
|
kit.QuietMiningLogs()
|
|
|
|
// Allow 8MB sectors
|
|
eightMBSectorsOpt := kit.SectorSize(8 << 20)
|
|
|
|
publishStorageDealKey, err := key.GenerateKey(types.KTSecp256k1)
|
|
require.NoError(t, err)
|
|
|
|
opts := node.Options(
|
|
node.Override(new(*storageadapter.DealPublisher),
|
|
storageadapter.NewDealPublisher(nil, storageadapter.PublishMsgConfig{
|
|
Period: publishPeriod,
|
|
MaxDealsPerMsg: maxDealsPerMsg,
|
|
}),
|
|
),
|
|
node.Override(new(*ctladdr.AddressSelector), modules.AddressSelector(&config.MinerAddressConfig{
|
|
DealPublishControl: []string{
|
|
publishStorageDealKey.Address.String(),
|
|
},
|
|
DisableOwnerFallback: true,
|
|
DisableWorkerFallback: true,
|
|
})),
|
|
)
|
|
|
|
minerFullNode, clientFullNode, miner, ens := kit.EnsembleTwoOne(t, kit.Account(publishStorageDealKey, publishStorageAccountFunds), kit.ConstructorOpts(opts), kit.MockProofs(), eightMBSectorsOpt)
|
|
|
|
kit.QuietMiningLogs()
|
|
|
|
ens.
|
|
Start().
|
|
InterconnectAll().
|
|
BeginMining(blockTime)
|
|
|
|
_, err = minerFullNode.WalletImport(ctx, &publishStorageDealKey.KeyInfo)
|
|
require.NoError(t, err)
|
|
|
|
miner.SetControlAddresses(publishStorageDealKey.Address)
|
|
|
|
dh := kit.NewDealHarness(t, clientFullNode, miner, miner)
|
|
|
|
res, _ := clientFullNode.CreateImportFile(ctx, 0, 4<<20) // 4MiB file.
|
|
list, err := clientFullNode.ClientListImports(ctx)
|
|
require.NoError(t, err)
|
|
require.Len(t, list, 1)
|
|
require.Equal(t, res.Root, *list[0].Root)
|
|
|
|
dp := dh.DefaultStartDealParams()
|
|
dp.Data.Root = res.Root
|
|
dp.FastRetrieval = true
|
|
dp.EpochPrice = abi.NewTokenAmount(62500000) // minimum asking price.
|
|
deal := dh.StartDeal(ctx, dp)
|
|
|
|
propcid := *deal
|
|
|
|
go func() {
|
|
time.Sleep(30 * time.Second)
|
|
|
|
kit.SendFunds(ctx, t, minerFullNode, publishStorageDealKey.Address, types.FromFil(1))
|
|
|
|
err := miner.MarketRetryPublishDeal(ctx, propcid)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}()
|
|
|
|
dh.WaitDealSealed(ctx, deal, false, false, nil)
|
|
}
|
|
|
|
func TestDealsRetryLackOfFunds_blockInPublishDeal(t *testing.T) {
|
|
//stm: @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001,
|
|
//stm: @CHAIN_SYNCER_START_001, @CHAIN_SYNCER_SYNC_001, @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01
|
|
//stm: @CHAIN_SYNCER_COLLECT_CHAIN_001, @CHAIN_SYNCER_COLLECT_HEADERS_001, @CHAIN_SYNCER_VALIDATE_TIPSET_001
|
|
//stm: @CHAIN_SYNCER_NEW_PEER_HEAD_001, @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_STOP_001
|
|
//stm: @CLIENT_STORAGE_DEALS_LIST_IMPORTS_001
|
|
ctx := context.Background()
|
|
kit.QuietMiningLogs()
|
|
|
|
// Allow 8MB sectors
|
|
eightMBSectorsOpt := kit.SectorSize(8 << 20)
|
|
|
|
publishStorageDealKey, err := key.GenerateKey(types.KTSecp256k1)
|
|
require.NoError(t, err)
|
|
|
|
opts := node.Options(
|
|
node.Override(new(*storageadapter.DealPublisher),
|
|
storageadapter.NewDealPublisher(nil, storageadapter.PublishMsgConfig{
|
|
Period: publishPeriod,
|
|
MaxDealsPerMsg: maxDealsPerMsg,
|
|
}),
|
|
),
|
|
node.Override(new(*ctladdr.AddressSelector), modules.AddressSelector(&config.MinerAddressConfig{
|
|
DealPublishControl: []string{
|
|
publishStorageDealKey.Address.String(),
|
|
},
|
|
DisableOwnerFallback: true,
|
|
DisableWorkerFallback: true,
|
|
})),
|
|
)
|
|
|
|
publishStorageAccountFunds := types.NewInt(1020000000000)
|
|
minerFullNode, clientFullNode, miner, ens := kit.EnsembleTwoOne(t, kit.Account(publishStorageDealKey, publishStorageAccountFunds), kit.ConstructorOpts(opts), kit.MockProofs(), eightMBSectorsOpt)
|
|
|
|
kit.QuietMiningLogs()
|
|
|
|
ens.
|
|
Start().
|
|
InterconnectAll().
|
|
BeginMining(blockTime)
|
|
|
|
_, err = minerFullNode.WalletImport(ctx, &publishStorageDealKey.KeyInfo)
|
|
require.NoError(t, err)
|
|
|
|
miner.SetControlAddresses(publishStorageDealKey.Address)
|
|
|
|
dh := kit.NewDealHarness(t, clientFullNode, miner, miner)
|
|
|
|
res, _ := clientFullNode.CreateImportFile(ctx, 0, 4<<20) // 4MiB file.
|
|
list, err := clientFullNode.ClientListImports(ctx)
|
|
require.NoError(t, err)
|
|
require.Len(t, list, 1)
|
|
require.Equal(t, res.Root, *list[0].Root)
|
|
|
|
dp := dh.DefaultStartDealParams()
|
|
dp.Data.Root = res.Root
|
|
dp.FastRetrieval = true
|
|
dp.EpochPrice = abi.NewTokenAmount(62500000) // minimum asking price.
|
|
deal := dh.StartDeal(ctx, dp)
|
|
|
|
dealSealed := make(chan struct{})
|
|
go func() {
|
|
dh.WaitDealSealedQuiet(ctx, deal, false, false, nil)
|
|
dealSealed <- struct{}{}
|
|
}()
|
|
|
|
select {
|
|
case <-dealSealed:
|
|
t.Fatal("deal shouldn't have sealed")
|
|
case <-time.After(time.Second * 15):
|
|
}
|
|
}
|