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

Miner payment management #1845

Merged
merged 1 commit into from
Mar 7, 2019
Merged

Miner payment management #1845

merged 1 commit into from
Mar 7, 2019

Conversation

lkowalick
Copy link
Contributor

@lkowalick lkowalick commented Feb 8, 2019

We coalesce the the storage of storage deals for both storage miners and storage clients into a single datastore with a single namespace. This allows easy querying of storage deals, regardless of whether one is a miner or client. This also easily allows a miner to obtain vouchers for storage deals that have been successfully executed, thus enabling miner payments with minimal hoop-jumping.

Resolves #1433

node/node.go Outdated
@@ -409,6 +410,7 @@ func (nc *Config) Build(ctx context.Context) (*Node, error) {
MsgQueryer: msg.NewQueryer(nc.Repo, fcWallet, chainReader, &cstOffline, bs),
MsgSender: msg.NewSender(nc.Repo, fcWallet, chainReader, msgPool, fsub.Publish),
MsgWaiter: msg.NewWaiter(chainReader, bs, &cstOffline),
Deals: dls.New(nc.Repo.DealsDatastore()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok this i is interesting. right now plumbing only accesses information that is widely available in the node. it doesnt access information owned by a particular protocol. i think access to information owned by a protocol should probably be accessed through that protocol's api. we dont have a mechanism for that yet. it seems really natural though to have an api for each protocol that has things like start and stop and to take actions on it. it would not be part of porcelain. we need to talk about this on our end. for now keep this but file an issue in the porcelain epic and referenece here about surfacing protocol private data in our apis how to do that. and @rosalinekarr and i will talk about it and come make it do the right thing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually @ZenGround0 is going to look at this, @ZenGround0 please ack

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good idea and opens the door to some potentially useful features in the future. Having this datastore exposed without the protocol could allow users to list their active deals, view how much money each deal has made, export deals to a backup and import deals on another client with access to the same sector base.

}

// Query returns a channel of deals matching the given query.
func (querier *Querier) Query(qry query.Query) (<-chan *deal.Deal, <-chan error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why return a channel? why not just iterate them and return a slice?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mainly because @whyrusleeping made this comment on the previous persisting deals PR:

#1526 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hooray for premature optimization at the cost of code clarity

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, because technical debt is awesome and everyone loves dealing with it.

porcelain/api.go Outdated Show resolved Hide resolved
porcelain/api.go Outdated Show resolved Hide resolved
porcelain/api.go Outdated Show resolved Hide resolved
}

// Ls returns a channel of deals matching the given query.
func (lser *Lser) Ls() (<-chan *deal.Deal, <-chan error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

returning two channels like this is really hard to use as a consumer without race conditions, instead create an option type (would be great if go had these natively) and return a channel of MaybeDeal (or something with a better name).

@phritz
Copy link
Contributor

phritz commented Feb 12, 2019

@rkowalick this is still labeled wip so i'm not sure if i should review. please add me back as a reviewer when it is ready.

@lkowalick lkowalick force-pushed the feat/miner-payment-management branch from 0b2f9c7 to eb2ead4 Compare February 27, 2019 19:52
porcelain/deals.go Outdated Show resolved Hide resolved
@lkowalick lkowalick changed the title WIP miner payment management Miner payment management Mar 1, 2019
@lkowalick lkowalick requested review from phritz and rosalinekarr March 1, 2019 21:02
api/impl/client.go Outdated Show resolved Hide resolved
commands/client.go Outdated Show resolved Hide resolved
@lkowalick lkowalick force-pushed the feat/miner-payment-management branch from fd19d26 to 51a0023 Compare March 4, 2019 22:50
Copy link
Contributor

@rosalinekarr rosalinekarr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than @phritz's suggestions, this LGTM

@@ -143,7 +143,7 @@ func (r *zeroRewarder) GasReward(ctx context.Context, st state.Tree, minerAddr a
}

// makeNodes makes at least two nodes, a miner and a client; numNodes is the total wanted
func makeNodes(ctx context.Context, t *testing.T, assertions *assert.Assertions, numNodes int) (address.Address, []*Node) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 for removing unnecessary contexts!

// DealPut puts a given deal in the datastore
func (api *API) DealPut(storageDeal *storagedeal.Deal) error {
return api.storagedeals.Put(storageDeal)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like where this is going. In the future, we could consider adding a DealRemove or DealDelete for letting users define their own data retention policies around deals.

We briefly discussed expiration policies around deals when we initially added deal persistence, but we never came up with a great solution for it. With this, we could potentially have an automatic delete after a few days for most users and let larger miners with capacity and interest in holding records for longer define their own policies through manual commands.

@lkowalick lkowalick force-pushed the feat/miner-payment-management branch from 51a0023 to 1c13a56 Compare March 5, 2019 16:23
Copy link
Contributor

@phritz phritz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally LGTM, see comments re deal put/ls in plumbing which i conclude is not a great home for them in the limit.

node/node.go Outdated Show resolved Hide resolved
node/node.go Outdated Show resolved Hide resolved
@@ -120,7 +125,17 @@ func (api *API) BlockGet(ctx context.Context, id cid.Cid) (*types.Block, error)
return api.chain.GetBlock(ctx, id)
}

// MessagePoolPending lists messages in the pool.
// DealsLs a slice of all storagedeals in the local datastore and possibly an error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unclear to me whether these deal calls belong in plumbing long term. they are used only by the storage protocol i think, and put at least should probably be a private interface that it uses. fine here for now but @shannonwells can you ack that you'll consider moving this as part of your work? they might just want to be private dependencies of the storage protocol instead of public calls part of the plumbing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, if we are going to make storage mining part of protocol then it will need to be moved out of here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK'd, comment I made below is heavily related to this thread too.


results, err := store.dealsDs.Query(query.Query{Prefix: "/" + StorageDealPrefix})
if err != nil {
return deals, errors.Wrap(err, "failed to query deals from datastore")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this comment is accurate i would not expect this to be an error, i would expect it to just return empty results

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This err case is distinct from the query returning an empty result set, so I thought it might be wise to point it out.

plumbing/strgdls/store.go Show resolved Hide resolved
porcelain/storagedeals.go Show resolved Hide resolved
protocol/storage/client.go Outdated Show resolved Hide resolved
plumbing/strgdls/store.go Outdated Show resolved Hide resolved
protocol/storage/client.go Outdated Show resolved Hide resolved
@@ -1,13 +1,15 @@
package storage
package storagedeal
Copy link
Contributor

@phritz phritz Mar 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocking: why do we have a new package for this? i suspect an import cycle which speaks to a deeper problem. i think the issue is likely that storage protocol depends on deal put/ls plumbing, which depend on storage protocol. this is a strong signal that deal put/ls do not belong in plumbing. the putter and lser should be direct, private dependencies of the storage protocol and should not be in the plumbing interface. commands that need deal ls should get it from the deal lser the storage protocol uses, which can be surfaced to them in storage protocol control api which will be separate from plumbing because it is higher level, which is part of #2030. for now we can keep it but @shannonwells can you please ack (and @rkowalick please ensure she does) that undoing this -- moving the deal back into the storage package as storage.deal and removing deal put/ls from plumbing -- is part of the scope for 2030? sorry to ramble here, i'm going ooo. and sorry @rkowalick this is not really something you could have forseen, we are underprepared to move protocol specific calls at this point, we'll have to play catch up.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it makes sense to have everything that's interacting with storage deals use the upcoming protocol api, if that's what you're asking.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@phritz I agree entirely that this is the core of the problem. It seems the protocol refactor stuff that @shannonwells will likely reorganize this stuff, so it seems like wasted effort to pull this stuff out of plumbing right now.

@lkowalick lkowalick force-pushed the feat/miner-payment-management branch from fb05742 to 305970f Compare March 6, 2019 17:55
We coalesce the storage deal stores for both miners and clients so they
can easily be queried by each. This allows miners to query the vouchers
they have for various storage deals, along with the state of those
deals.

We also push the deal storage mechanism into plumbing, though it may be
moved shortly with the upcoming protocol refactor.

There is also some simple cleanup such as:
- Removing some unused contexts
- Removing the in-memory cache of the deal store. Badger is really fast
  and this simplifies the code tremendously
@lkowalick lkowalick force-pushed the feat/miner-payment-management branch from bf8bab1 to 115352d Compare March 7, 2019 15:30
@lkowalick lkowalick merged commit 87f1b55 into master Mar 7, 2019
@lkowalick lkowalick deleted the feat/miner-payment-management branch March 7, 2019 16:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants