Skip to content

Commit 2c45ebb

Browse files
authored
Provider cancels lease
fixes #173 * close lease * close lease * close lease * fix tests * add test
1 parent 658db91 commit 2c45ebb

File tree

14 files changed

+580
-98
lines changed

14 files changed

+580
-98
lines changed

app/lease/app.go

Lines changed: 146 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ func (a *app) AcceptTx(ctx apptypes.Context, tx interface{}) bool {
3737
switch tx.(type) {
3838
case *types.TxPayload_TxCreateLease:
3939
return true
40+
case *types.TxPayload_TxCloseLease:
41+
return true
4042
}
4143
return false
4244
}
@@ -46,6 +48,9 @@ func (a *app) CheckTx(ctx apptypes.Context, tx interface{}) tmtypes.ResponseChec
4648
case *types.TxPayload_TxCreateLease:
4749
resp, _ := a.doCheckCreateTx(ctx, tx.TxCreateLease)
4850
return resp
51+
case *types.TxPayload_TxCloseLease:
52+
resp, _ := a.doCheckCloseTx(ctx, tx.TxCloseLease)
53+
return resp
4954
}
5055
return tmtypes.ResponseCheckTx{
5156
Code: code.UNKNOWN_TRANSACTION,
@@ -57,6 +62,8 @@ func (a *app) DeliverTx(ctx apptypes.Context, tx interface{}) tmtypes.ResponseDe
5762
switch tx := tx.(type) {
5863
case *types.TxPayload_TxCreateLease:
5964
return a.doDeliverCreateTx(ctx, tx.TxCreateLease)
65+
case *types.TxPayload_TxCloseLease:
66+
return a.doDeliverCloseTx(ctx, tx.TxCloseLease)
6067
}
6168
return tmtypes.ResponseDeliverTx{
6269
Code: code.UNKNOWN_TRANSACTION,
@@ -200,7 +207,7 @@ func (a *app) doCheckCreateTx(ctx apptypes.Context, tx *types.TxCreateLease) (tm
200207
}
201208

202209
func (a *app) doDeliverCreateTx(ctx apptypes.Context, tx *types.TxCreateLease) tmtypes.ResponseDeliverTx {
203-
cresp, order := a.doCheckCreateTx(ctx, tx)
210+
cresp, matchedOrder := a.doCheckCreateTx(ctx, tx)
204211
if !cresp.IsOK() {
205212
return tmtypes.ResponseDeliverTx{
206213
Code: cresp.Code,
@@ -224,13 +231,47 @@ func (a *app) doDeliverCreateTx(ctx apptypes.Context, tx *types.TxCreateLease) t
224231
}
225232
}
226233

227-
order.State = types.Order_MATCHED
228-
if err := a.State().Order().Save(order); err != nil {
234+
group, err := a.State().DeploymentGroup().Get(tx.Deployment, tx.Group)
235+
if err != nil {
236+
return tmtypes.ResponseDeliverTx{
237+
Code: code.ERROR,
238+
Log: err.Error(),
239+
}
240+
}
241+
if group == nil {
229242
return tmtypes.ResponseDeliverTx{
230243
Code: code.INVALID_TRANSACTION,
244+
Log: "group not found",
245+
}
246+
}
247+
248+
orders, err := a.State().Order().ForGroup(group)
249+
if err != nil {
250+
return tmtypes.ResponseDeliverTx{
251+
Code: code.ERROR,
231252
Log: err.Error(),
232253
}
233254
}
255+
if orders == nil {
256+
return tmtypes.ResponseDeliverTx{
257+
Code: code.INVALID_TRANSACTION,
258+
Log: "orders not found",
259+
}
260+
}
261+
262+
for _, order := range orders {
263+
if order.Seq != matchedOrder.Seq {
264+
order.State = types.Order_CLOSED
265+
} else {
266+
order.State = types.Order_MATCHED
267+
}
268+
if err := a.State().Order().Save(order); err != nil {
269+
return tmtypes.ResponseDeliverTx{
270+
Code: code.INVALID_TRANSACTION,
271+
Log: err.Error(),
272+
}
273+
}
274+
}
234275

235276
tags := apptypes.NewTags(a.Name(), apptypes.TxTypeCreateLease)
236277
tags = append(tags, tmcommon.KVPair{Key: []byte(apptypes.TagNameDeployment), Value: lease.Deployment})
@@ -241,6 +282,108 @@ func (a *app) doDeliverCreateTx(ctx apptypes.Context, tx *types.TxCreateLease) t
241282
}
242283
}
243284

285+
func (a *app) doCheckCloseTx(ctx apptypes.Context, tx *types.TxCloseLease) (tmtypes.ResponseCheckTx, *types.Lease) {
286+
if tx.Lease == nil {
287+
return tmtypes.ResponseCheckTx{
288+
Code: code.INVALID_TRANSACTION,
289+
Log: "empty lease",
290+
}, nil
291+
}
292+
293+
// lookup provider
294+
lease, err := a.State().Lease().GetByKey(tx.Lease)
295+
if err != nil {
296+
return tmtypes.ResponseCheckTx{
297+
Code: code.ERROR,
298+
Log: err.Error(),
299+
}, nil
300+
}
301+
if lease == nil {
302+
return tmtypes.ResponseCheckTx{
303+
Code: code.INVALID_TRANSACTION,
304+
Log: "lease not found",
305+
}, nil
306+
}
307+
308+
if lease.State != types.Lease_ACTIVE {
309+
return tmtypes.ResponseCheckTx{
310+
Code: code.INVALID_TRANSACTION,
311+
Log: "lease not active",
312+
}, nil
313+
}
314+
315+
return tmtypes.ResponseCheckTx{}, lease
316+
}
317+
318+
func (a *app) doDeliverCloseTx(ctx apptypes.Context, tx *types.TxCloseLease) tmtypes.ResponseDeliverTx {
319+
cresp, lease := a.doCheckCloseTx(ctx, tx)
320+
if !cresp.IsOK() {
321+
return tmtypes.ResponseDeliverTx{
322+
Code: cresp.Code,
323+
Log: cresp.Log,
324+
}
325+
}
326+
327+
group, err := a.State().DeploymentGroup().Get(lease.Deployment, lease.Group)
328+
if err != nil {
329+
return tmtypes.ResponseDeliverTx{
330+
Code: code.ERROR,
331+
Log: err.Error(),
332+
}
333+
}
334+
if group == nil {
335+
return tmtypes.ResponseDeliverTx{
336+
Code: code.INVALID_TRANSACTION,
337+
Log: "group not found",
338+
}
339+
}
340+
341+
order, err := a.State().Order().Get(lease.Deployment, lease.Group, lease.Order)
342+
if err != nil {
343+
return tmtypes.ResponseDeliverTx{
344+
Code: code.ERROR,
345+
Log: err.Error(),
346+
}
347+
}
348+
if order == nil {
349+
return tmtypes.ResponseDeliverTx{
350+
Code: code.INVALID_TRANSACTION,
351+
Log: "order not found",
352+
}
353+
}
354+
355+
order.State = types.Order_CLOSED
356+
if err := a.State().Order().Save(order); err != nil {
357+
return tmtypes.ResponseDeliverTx{
358+
Code: code.INVALID_TRANSACTION,
359+
Log: err.Error(),
360+
}
361+
}
362+
363+
group.State = types.DeploymentGroup_OPEN
364+
if err := a.State().DeploymentGroup().Save(group); err != nil {
365+
return tmtypes.ResponseDeliverTx{
366+
Code: code.INVALID_TRANSACTION,
367+
Log: err.Error(),
368+
}
369+
}
370+
371+
lease.State = types.Lease_CLOSED
372+
if err := a.State().Lease().Save(lease); err != nil {
373+
return tmtypes.ResponseDeliverTx{
374+
Code: code.INVALID_TRANSACTION,
375+
Log: err.Error(),
376+
}
377+
}
378+
379+
tags := apptypes.NewTags(a.Name(), apptypes.TxTypeCloseLease)
380+
tags = append(tags, tmcommon.KVPair{Key: []byte(apptypes.TagNameLease), Value: state.IDForLease(lease)})
381+
382+
return tmtypes.ResponseDeliverTx{
383+
Tags: tags,
384+
}
385+
}
386+
244387
func (a *app) doQuery(key base.Bytes) tmtypes.ResponseQuery {
245388
lease, err := a.State().Lease().GetByKey(key)
246389

app/lease/app_test.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,15 @@ func TestValidTx(t *testing.T) {
5959
dapp, err := dapp.NewApp(state, testutil.Logger())
6060
require.NoError(t, err)
6161
tnonce := uint64(1)
62-
deployment, groups := testutil.CreateDeployment(t, dapp, taccount, &tkey, tnonce)
63-
groupSeq := groups.GetItems()[0].Seq
62+
testutil.CreateDeployment(t, dapp, taccount, &tkey, tnonce)
63+
groupSeq := uint64(1)
6464
daddress := state_.DeploymentAddress(taccount.Address, tnonce)
6565

6666
// create order
6767
oapp, err := oapp.NewApp(state, testutil.Logger())
6868
require.NoError(t, err)
6969
oSeq := uint64(0)
70-
testutil.CreateOrder(t, oapp, taccount, &tkey, deployment.Address, groupSeq, oSeq)
70+
testutil.CreateOrder(t, oapp, taccount, &tkey, daddress, groupSeq, oSeq)
7171
price := uint32(0)
7272

7373
// create fulfillment
@@ -84,12 +84,25 @@ func TestValidTx(t *testing.T) {
8484
require.True(t, resp.IsOK())
8585
lea := new(types.Lease)
8686
require.NoError(t, lea.Unmarshal(resp.Value))
87-
8887
assert.Equal(t, lease.Deployment, lea.Deployment)
8988
assert.Equal(t, lease.Group, lea.Group)
9089
assert.Equal(t, lease.Order, lea.Order)
9190
assert.Equal(t, lease.Provider, lea.Provider)
9291
assert.Equal(t, lease.Price, lea.Price)
92+
assert.Equal(t, types.Lease_ACTIVE, lea.State)
93+
}
94+
95+
// close lease
96+
leaseAddr := state.Lease().IDFor(lease)
97+
testutil.CloseLease(t, app, leaseAddr, &pkey)
98+
{
99+
path := query.LeasePath(lease.Deployment, lease.Group, lease.Order, lease.Provider)
100+
resp := app.Query(tmtypes.RequestQuery{Path: path})
101+
assert.Empty(t, resp.Log)
102+
require.True(t, resp.IsOK())
103+
lea := new(types.Lease)
104+
require.NoError(t, lea.Unmarshal(resp.Value))
105+
assert.Equal(t, types.Lease_CLOSED, lea.State)
93106
}
94107
}
95108

@@ -126,15 +139,15 @@ func TestBilling(t *testing.T) {
126139
dapp, err := dapp.NewApp(state, testutil.Logger())
127140
require.NoError(t, err)
128141
tnonce := uint64(1)
129-
deployment, groups := testutil.CreateDeployment(t, dapp, tenant, &tkey, tnonce)
130-
groupSeq := groups.GetItems()[0].Seq
142+
testutil.CreateDeployment(t, dapp, tenant, &tkey, tnonce)
143+
groupSeq := uint64(1)
131144
daddress := state_.DeploymentAddress(tenant.Address, tnonce)
132145

133146
// create order
134147
oapp, err := oapp.NewApp(state, testutil.Logger())
135148
require.NoError(t, err)
136149
oSeq := uint64(0)
137-
testutil.CreateOrder(t, oapp, tenant, &tkey, deployment.Address, groupSeq, oSeq)
150+
testutil.CreateOrder(t, oapp, tenant, &tkey, daddress, groupSeq, oSeq)
138151
price := uint32(1)
139152
p := uint64(price)
140153

app/types/tags.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const (
2626

2727
TagAppLease = "lease"
2828
TxTypeCreateLease = "lease-create"
29+
TxTypeCloseLease = "lease-close"
2930

3031
TagAppProvider = "provider"
3132
TxTypeProviderCreate = "provider-create"

cmd/akash/marketplace.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,8 @@ func marketplaceMonitorHandler() marketplace.Handler {
6363
OnTxCloseFulfillment(func(tx *types.TxCloseFulfillment) {
6464
fmt.Printf("FULFILLMENT CLOSED\t%v\n", X(tx.Fulfillment))
6565
}).
66+
OnTxCloseLease(func(tx *types.TxCloseLease) {
67+
fmt.Printf("LEASE CLOSED\t%v\n", X(tx.Lease))
68+
}).
6669
Create()
6770
}

cmd/akash/provider.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"fmt"
77
"math/rand"
8+
"strconv"
89

910
"github.com/ovrclk/akash/cmd/akash/constants"
1011
"github.com/ovrclk/akash/cmd/akash/context"
@@ -36,6 +37,7 @@ func providerCommand() *cobra.Command {
3637
cmd.AddCommand(createProviderCommand())
3738
cmd.AddCommand(runCommand())
3839
cmd.AddCommand(closeFulfillmentCommand())
40+
cmd.AddCommand(closeLeaseCommand())
3941

4042
return cmd
4143
}
@@ -299,3 +301,71 @@ func doCloseFulfillmentCommand(ctx context.Context, cmd *cobra.Command, args []s
299301

300302
return nil
301303
}
304+
305+
func closeLeaseCommand() *cobra.Command {
306+
307+
cmd := &cobra.Command{
308+
Use: "closel <deployment> <group> <order> <provider>",
309+
Short: "close an active lease",
310+
Args: cobra.ExactArgs(4),
311+
RunE: context.WithContext(context.RequireNode(doCloseLeaseCommand)),
312+
}
313+
314+
context.AddFlagKeyType(cmd, cmd.Flags())
315+
316+
return cmd
317+
}
318+
319+
func doCloseLeaseCommand(ctx context.Context, cmd *cobra.Command, args []string) error {
320+
signer, _, err := ctx.Signer()
321+
if err != nil {
322+
return err
323+
}
324+
325+
nonce, err := ctx.Nonce()
326+
if err != nil {
327+
return err
328+
}
329+
330+
deployment := new(base.Bytes)
331+
if err := deployment.DecodeString(args[0]); err != nil {
332+
return err
333+
}
334+
335+
group, err := strconv.ParseUint(args[1], 10, 64)
336+
if err != nil {
337+
return err
338+
}
339+
340+
order, err := strconv.ParseUint(args[2], 10, 64)
341+
if err != nil {
342+
return err
343+
}
344+
345+
provider := new(base.Bytes)
346+
if err := provider.DecodeString(args[3]); err != nil {
347+
return err
348+
}
349+
350+
lease := state.LeaseID(*deployment, group, order, *provider)
351+
352+
tx, err := txutil.BuildTx(signer, nonce, &types.TxCloseLease{
353+
Lease: lease,
354+
})
355+
if err != nil {
356+
return err
357+
}
358+
359+
result, err := ctx.Client().BroadcastTxCommit(tx)
360+
if err != nil {
361+
return err
362+
}
363+
if result.CheckTx.IsErr() {
364+
return errors.New(result.CheckTx.GetLog())
365+
}
366+
if result.DeliverTx.IsErr() {
367+
return errors.New(result.DeliverTx.GetLog())
368+
}
369+
370+
return nil
371+
}

0 commit comments

Comments
 (0)