Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add TipSet identity-producing method to various Node interfaces #149

Merged
merged 6 commits into from
Mar 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/filecoin-project/go-fil-markets/retrievalmarket"
"github.com/filecoin-project/go-fil-markets/shared"
)

type expectedVoucherKey struct {
Expand Down Expand Up @@ -118,6 +119,10 @@ func (trpn *TestRetrievalProviderNode) GetMinerWorker(ctx context.Context, addr
return addr, nil
}

func (trpn *TestRetrievalProviderNode) GetChainHead(ctx context.Context) (shared.TipSetToken, abi.ChainEpoch, error) {
return []byte{42}, 0, nil
}

// --- Non-interface Functions

// to ExpectedVoucherKey creates a lookup key for expected vouchers.
Expand Down
4 changes: 4 additions & 0 deletions retrievalmarket/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"fmt"
"io"

"github.com/filecoin-project/go-fil-markets/shared"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
Expand Down Expand Up @@ -311,6 +313,8 @@ type RetrievalProvider interface {

// RetrievalProviderNode are the node depedencies for a RetrevalProvider
type RetrievalProviderNode interface {
GetChainHead(ctx context.Context) (shared.TipSetToken, abi.ChainEpoch, error)

// returns the worker address associated with a miner
GetMinerWorker(ctx context.Context, miner address.Address) (address.Address, error)
UnsealSector(ctx context.Context, sectorID uint64, offset uint64, length uint64) (io.ReadCloser, error)
Expand Down
4 changes: 4 additions & 0 deletions shared/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package shared

// TipSetToken is the implementation-nonspecific identity for a tipset.
type TipSetToken []byte
5 changes: 2 additions & 3 deletions storagemarket/impl/providerstates/provider_states.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,13 @@ func ValidateDealProposal(ctx fsm.Context, environment ProviderDealEnvironment,
return ctx.Trigger(storagemarket.ProviderEventDealRejected, xerrors.Errorf("incorrect provider for deal"))
}

head, err := environment.Node().MostRecentStateId(ctx.Context())

_, height, err := environment.Node().GetChainHead(ctx.Context())
if err != nil {
return ctx.Trigger(storagemarket.ProviderEventNodeErrored, xerrors.Errorf("getting most recent state id: %w", err))
}

// TODO: set configurable value for how many epochs in the future StartEpoch must be
if head.Height() >= deal.Proposal.StartEpoch {
if height >= deal.Proposal.StartEpoch {
return ctx.Trigger(storagemarket.ProviderEventDealRejected, xerrors.Errorf("deal proposal already expired"))
}

Expand Down
15 changes: 10 additions & 5 deletions storagemarket/impl/providerstates/provider_states_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

"github.com/filecoin-project/go-fil-markets/filestore"
"github.com/filecoin-project/go-fil-markets/piecestore"
"github.com/filecoin-project/go-fil-markets/shared"
tut "github.com/filecoin-project/go-fil-markets/shared_testutil"
"github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/filecoin-project/go-fil-markets/storagemarket/impl/providerstates"
Expand Down Expand Up @@ -467,6 +468,7 @@ func TestFailDeal(t *testing.T) {

// all of these default parameters are setup to allow a deal to complete each handler with no errors
var defaultHeight = abi.ChainEpoch(50)
var defaultTipSetToken = []byte{1, 2, 3}
var defaultStoragePricePerEpoch = abi.NewTokenAmount(10000)
var defaultPieceSize = abi.PaddedPieceSize(1048576)
var defaultStartEpoch = abi.ChainEpoch(200)
Expand Down Expand Up @@ -494,6 +496,7 @@ type nodeParams struct {
MinerWorkerError error
EnsureFundsError error
Height abi.ChainEpoch
TipSetToken shared.TipSetToken
ClientMarketBalance abi.TokenAmount
ClientMarketBalanceError error
VerifySignatureFails bool
Expand Down Expand Up @@ -553,8 +556,10 @@ func makeExecutor(ctx context.Context,
smstate := testnodes.NewStorageMarketState()
if nodeParams.Height != abi.ChainEpoch(0) {
smstate.Epoch = nodeParams.Height
smstate.TipSetToken = nodeParams.TipSetToken
} else {
smstate.Epoch = defaultHeight
smstate.TipSetToken = defaultTipSetToken
}
if !nodeParams.ClientMarketBalance.Nil() {
smstate.AddFunds(defaultClientAddress, nodeParams.ClientMarketBalance)
Expand All @@ -563,11 +568,11 @@ func makeExecutor(ctx context.Context,
}

common := testnodes.FakeCommonNode{
SMState: smstate,
MostRecentStateIDError: nodeParams.MostRecentStateIDError,
GetBalanceError: nodeParams.ClientMarketBalanceError,
VerifySignatureFails: nodeParams.VerifySignatureFails,
EnsureFundsError: nodeParams.EnsureFundsError,
SMState: smstate,
GetChainHeadError: nodeParams.MostRecentStateIDError,
GetBalanceError: nodeParams.ClientMarketBalanceError,
VerifySignatureFails: nodeParams.VerifySignatureFails,
EnsureFundsError: nodeParams.EnsureFundsError,
}

node := &testnodes.FakeProviderNode{
Expand Down
6 changes: 3 additions & 3 deletions storagemarket/impl/storedask/storedask.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ func (s *StoredAsk) AddAsk(price abi.TokenAmount, duration abi.ChainEpoch) error
seqno = s.ask.Ask.SeqNo + 1
}

stateKey, err := s.spn.MostRecentStateId(context.TODO())
_, height, err := s.spn.GetChainHead(context.TODO())
if err != nil {
return err
}
ask := &storagemarket.StorageAsk{
Price: price,
Timestamp: stateKey.Height(),
Expiry: stateKey.Height() + duration,
Timestamp: height,
Expiry: height + duration,
Miner: s.actor,
SeqNo: seqno,
MinPieceSize: defaultMinPieceSize,
Expand Down
4 changes: 2 additions & 2 deletions storagemarket/impl/storedask/storedask_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ func TestStoredAsk(t *testing.T) {
t.Run("node errors", func(t *testing.T) {
spnStateIDErr := &testnodes.FakeProviderNode{
FakeCommonNode: testnodes.FakeCommonNode{
MostRecentStateIDError: errors.New("something went wrong"),
SMState: testnodes.NewStorageMarketState(),
GetChainHeadError: errors.New("something went wrong"),
SMState: testnodes.NewStorageMarketState(),
},
}
// should load cause ask is is still in data store
Expand Down
40 changes: 19 additions & 21 deletions storagemarket/testnodes/testnodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"io"

"github.com/filecoin-project/go-fil-markets/shared"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
Expand All @@ -17,17 +19,10 @@ import (

// Below fake node implementations

// TestStateKey is just a stubbed state key that returns a preset height
type TestStateKey struct{ Epoch abi.ChainEpoch }

// Height returns the value specified by Epoch
func (k *TestStateKey) Height() abi.ChainEpoch {
return k.Epoch
}

// StorageMarketState represents a state for the storage market that can be inspected
// - methods on the provider nodes will affect this state
type StorageMarketState struct {
TipSetToken shared.TipSetToken
Epoch abi.ChainEpoch
DealId abi.DealID
Balances map[address.Address]abi.TokenAmount
Expand Down Expand Up @@ -72,37 +67,40 @@ func (sma *StorageMarketState) Deals(addr address.Address) []storagemarket.Stora
}

// StateKey returns a state key with the storage market states set Epoch
func (sma *StorageMarketState) StateKey() storagemarket.StateKey {
return &TestStateKey{sma.Epoch}
func (sma *StorageMarketState) StateKey() (shared.TipSetToken, abi.ChainEpoch) {
return sma.TipSetToken, sma.Epoch
}

// AddDeal adds a deal to the current state of the storage market
func (sma *StorageMarketState) AddDeal(deal storagemarket.StorageDeal) storagemarket.StateKey {
func (sma *StorageMarketState) AddDeal(deal storagemarket.StorageDeal) (shared.TipSetToken, abi.ChainEpoch) {
for _, addr := range []address.Address{deal.Client, deal.Provider} {
if existing, ok := sma.StorageDeals[addr]; ok {
sma.StorageDeals[addr] = append(existing, deal)
} else {
sma.StorageDeals[addr] = []storagemarket.StorageDeal{deal}
}
}

return sma.StateKey()
}

// FakeCommonNode has the common methods for the storage & client node adapters
type FakeCommonNode struct {
SMState *StorageMarketState
EnsureFundsError error
VerifySignatureFails bool
GetBalanceError error
MostRecentStateIDError error
SMState *StorageMarketState
EnsureFundsError error
VerifySignatureFails bool
GetBalanceError error
GetChainHeadError error
}

// MostRecentStateId returns the state id in the storage market state
func (n *FakeCommonNode) MostRecentStateId(ctx context.Context) (storagemarket.StateKey, error) {
if n.MostRecentStateIDError == nil {
return n.SMState.StateKey(), nil
// GetChainHead returns the state id in the storage market state
func (n *FakeCommonNode) GetChainHead(ctx context.Context) (shared.TipSetToken, abi.ChainEpoch, error) {
if n.GetChainHeadError == nil {
key, epoch := n.SMState.StateKey()
return key, epoch, nil
}
return &TestStateKey{}, n.MostRecentStateIDError

return []byte{}, 0, n.GetChainHeadError
}

// AddFunds adds funds to the given actor in the storage market state
Expand Down
9 changes: 3 additions & 6 deletions storagemarket/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/libp2p/go-libp2p-core/peer"

"github.com/filecoin-project/go-fil-markets/filestore"
"github.com/filecoin-project/go-fil-markets/shared"
)

//go:generate cbor-gen-for ClientDeal MinerDeal Balance SignedStorageAsk StorageAsk StorageDeal DataRef
Expand Down Expand Up @@ -96,10 +97,6 @@ type StorageAsk struct {

var StorageAskUndefined = StorageAsk{}

type StateKey interface {
Height() abi.ChainEpoch
}

type MinerDeal struct {
market.ClientDealProposal
ProposalCid cid.Cid
Expand Down Expand Up @@ -287,7 +284,7 @@ type StorageProvider interface {

// Node dependencies for a StorageProvider
type StorageProviderNode interface {
MostRecentStateId(ctx context.Context) (StateKey, error)
GetChainHead(ctx context.Context) (shared.TipSetToken, abi.ChainEpoch, error)

// Verify a signature against an address + data
VerifySignature(signature crypto.Signature, signer address.Address, plaintext []byte) bool
Expand Down Expand Up @@ -326,7 +323,7 @@ type DealSectorCommittedCallback func(err error)

// Node dependencies for a StorageClient
type StorageClientNode interface {
MostRecentStateId(ctx context.Context) (StateKey, error)
GetChainHead(ctx context.Context) (shared.TipSetToken, abi.ChainEpoch, error)

// Verify a signature against an address + data
VerifySignature(signature crypto.Signature, signer address.Address, plaintext []byte) bool
Expand Down