Skip to content

Commit

Permalink
Provider cancels lease
Browse files Browse the repository at this point in the history
fixes #173

* close lease

* close lease

* close lease

* fix tests

* add test
  • Loading branch information
aastein authored Apr 23, 2018
1 parent 658db91 commit 2c45ebb
Show file tree
Hide file tree
Showing 14 changed files with 580 additions and 98 deletions.
149 changes: 146 additions & 3 deletions app/lease/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ func (a *app) AcceptTx(ctx apptypes.Context, tx interface{}) bool {
switch tx.(type) {
case *types.TxPayload_TxCreateLease:
return true
case *types.TxPayload_TxCloseLease:
return true
}
return false
}
Expand All @@ -46,6 +48,9 @@ func (a *app) CheckTx(ctx apptypes.Context, tx interface{}) tmtypes.ResponseChec
case *types.TxPayload_TxCreateLease:
resp, _ := a.doCheckCreateTx(ctx, tx.TxCreateLease)
return resp
case *types.TxPayload_TxCloseLease:
resp, _ := a.doCheckCloseTx(ctx, tx.TxCloseLease)
return resp
}
return tmtypes.ResponseCheckTx{
Code: code.UNKNOWN_TRANSACTION,
Expand All @@ -57,6 +62,8 @@ func (a *app) DeliverTx(ctx apptypes.Context, tx interface{}) tmtypes.ResponseDe
switch tx := tx.(type) {
case *types.TxPayload_TxCreateLease:
return a.doDeliverCreateTx(ctx, tx.TxCreateLease)
case *types.TxPayload_TxCloseLease:
return a.doDeliverCloseTx(ctx, tx.TxCloseLease)
}
return tmtypes.ResponseDeliverTx{
Code: code.UNKNOWN_TRANSACTION,
Expand Down Expand Up @@ -200,7 +207,7 @@ func (a *app) doCheckCreateTx(ctx apptypes.Context, tx *types.TxCreateLease) (tm
}

func (a *app) doDeliverCreateTx(ctx apptypes.Context, tx *types.TxCreateLease) tmtypes.ResponseDeliverTx {
cresp, order := a.doCheckCreateTx(ctx, tx)
cresp, matchedOrder := a.doCheckCreateTx(ctx, tx)
if !cresp.IsOK() {
return tmtypes.ResponseDeliverTx{
Code: cresp.Code,
Expand All @@ -224,13 +231,47 @@ func (a *app) doDeliverCreateTx(ctx apptypes.Context, tx *types.TxCreateLease) t
}
}

order.State = types.Order_MATCHED
if err := a.State().Order().Save(order); err != nil {
group, err := a.State().DeploymentGroup().Get(tx.Deployment, tx.Group)
if err != nil {
return tmtypes.ResponseDeliverTx{
Code: code.ERROR,
Log: err.Error(),
}
}
if group == nil {
return tmtypes.ResponseDeliverTx{
Code: code.INVALID_TRANSACTION,
Log: "group not found",
}
}

orders, err := a.State().Order().ForGroup(group)
if err != nil {
return tmtypes.ResponseDeliverTx{
Code: code.ERROR,
Log: err.Error(),
}
}
if orders == nil {
return tmtypes.ResponseDeliverTx{
Code: code.INVALID_TRANSACTION,
Log: "orders not found",
}
}

for _, order := range orders {
if order.Seq != matchedOrder.Seq {
order.State = types.Order_CLOSED
} else {
order.State = types.Order_MATCHED
}
if err := a.State().Order().Save(order); err != nil {
return tmtypes.ResponseDeliverTx{
Code: code.INVALID_TRANSACTION,
Log: err.Error(),
}
}
}

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

func (a *app) doCheckCloseTx(ctx apptypes.Context, tx *types.TxCloseLease) (tmtypes.ResponseCheckTx, *types.Lease) {
if tx.Lease == nil {
return tmtypes.ResponseCheckTx{
Code: code.INVALID_TRANSACTION,
Log: "empty lease",
}, nil
}

// lookup provider
lease, err := a.State().Lease().GetByKey(tx.Lease)
if err != nil {
return tmtypes.ResponseCheckTx{
Code: code.ERROR,
Log: err.Error(),
}, nil
}
if lease == nil {
return tmtypes.ResponseCheckTx{
Code: code.INVALID_TRANSACTION,
Log: "lease not found",
}, nil
}

if lease.State != types.Lease_ACTIVE {
return tmtypes.ResponseCheckTx{
Code: code.INVALID_TRANSACTION,
Log: "lease not active",
}, nil
}

return tmtypes.ResponseCheckTx{}, lease
}

func (a *app) doDeliverCloseTx(ctx apptypes.Context, tx *types.TxCloseLease) tmtypes.ResponseDeliverTx {
cresp, lease := a.doCheckCloseTx(ctx, tx)
if !cresp.IsOK() {
return tmtypes.ResponseDeliverTx{
Code: cresp.Code,
Log: cresp.Log,
}
}

group, err := a.State().DeploymentGroup().Get(lease.Deployment, lease.Group)
if err != nil {
return tmtypes.ResponseDeliverTx{
Code: code.ERROR,
Log: err.Error(),
}
}
if group == nil {
return tmtypes.ResponseDeliverTx{
Code: code.INVALID_TRANSACTION,
Log: "group not found",
}
}

order, err := a.State().Order().Get(lease.Deployment, lease.Group, lease.Order)
if err != nil {
return tmtypes.ResponseDeliverTx{
Code: code.ERROR,
Log: err.Error(),
}
}
if order == nil {
return tmtypes.ResponseDeliverTx{
Code: code.INVALID_TRANSACTION,
Log: "order not found",
}
}

order.State = types.Order_CLOSED
if err := a.State().Order().Save(order); err != nil {
return tmtypes.ResponseDeliverTx{
Code: code.INVALID_TRANSACTION,
Log: err.Error(),
}
}

group.State = types.DeploymentGroup_OPEN
if err := a.State().DeploymentGroup().Save(group); err != nil {
return tmtypes.ResponseDeliverTx{
Code: code.INVALID_TRANSACTION,
Log: err.Error(),
}
}

lease.State = types.Lease_CLOSED
if err := a.State().Lease().Save(lease); err != nil {
return tmtypes.ResponseDeliverTx{
Code: code.INVALID_TRANSACTION,
Log: err.Error(),
}
}

tags := apptypes.NewTags(a.Name(), apptypes.TxTypeCloseLease)
tags = append(tags, tmcommon.KVPair{Key: []byte(apptypes.TagNameLease), Value: state.IDForLease(lease)})

return tmtypes.ResponseDeliverTx{
Tags: tags,
}
}

func (a *app) doQuery(key base.Bytes) tmtypes.ResponseQuery {
lease, err := a.State().Lease().GetByKey(key)

Expand Down
27 changes: 20 additions & 7 deletions app/lease/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ func TestValidTx(t *testing.T) {
dapp, err := dapp.NewApp(state, testutil.Logger())
require.NoError(t, err)
tnonce := uint64(1)
deployment, groups := testutil.CreateDeployment(t, dapp, taccount, &tkey, tnonce)
groupSeq := groups.GetItems()[0].Seq
testutil.CreateDeployment(t, dapp, taccount, &tkey, tnonce)
groupSeq := uint64(1)
daddress := state_.DeploymentAddress(taccount.Address, tnonce)

// create order
oapp, err := oapp.NewApp(state, testutil.Logger())
require.NoError(t, err)
oSeq := uint64(0)
testutil.CreateOrder(t, oapp, taccount, &tkey, deployment.Address, groupSeq, oSeq)
testutil.CreateOrder(t, oapp, taccount, &tkey, daddress, groupSeq, oSeq)
price := uint32(0)

// create fulfillment
Expand All @@ -84,12 +84,25 @@ func TestValidTx(t *testing.T) {
require.True(t, resp.IsOK())
lea := new(types.Lease)
require.NoError(t, lea.Unmarshal(resp.Value))

assert.Equal(t, lease.Deployment, lea.Deployment)
assert.Equal(t, lease.Group, lea.Group)
assert.Equal(t, lease.Order, lea.Order)
assert.Equal(t, lease.Provider, lea.Provider)
assert.Equal(t, lease.Price, lea.Price)
assert.Equal(t, types.Lease_ACTIVE, lea.State)
}

// close lease
leaseAddr := state.Lease().IDFor(lease)
testutil.CloseLease(t, app, leaseAddr, &pkey)
{
path := query.LeasePath(lease.Deployment, lease.Group, lease.Order, lease.Provider)
resp := app.Query(tmtypes.RequestQuery{Path: path})
assert.Empty(t, resp.Log)
require.True(t, resp.IsOK())
lea := new(types.Lease)
require.NoError(t, lea.Unmarshal(resp.Value))
assert.Equal(t, types.Lease_CLOSED, lea.State)
}
}

Expand Down Expand Up @@ -126,15 +139,15 @@ func TestBilling(t *testing.T) {
dapp, err := dapp.NewApp(state, testutil.Logger())
require.NoError(t, err)
tnonce := uint64(1)
deployment, groups := testutil.CreateDeployment(t, dapp, tenant, &tkey, tnonce)
groupSeq := groups.GetItems()[0].Seq
testutil.CreateDeployment(t, dapp, tenant, &tkey, tnonce)
groupSeq := uint64(1)
daddress := state_.DeploymentAddress(tenant.Address, tnonce)

// create order
oapp, err := oapp.NewApp(state, testutil.Logger())
require.NoError(t, err)
oSeq := uint64(0)
testutil.CreateOrder(t, oapp, tenant, &tkey, deployment.Address, groupSeq, oSeq)
testutil.CreateOrder(t, oapp, tenant, &tkey, daddress, groupSeq, oSeq)
price := uint32(1)
p := uint64(price)

Expand Down
1 change: 1 addition & 0 deletions app/types/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (

TagAppLease = "lease"
TxTypeCreateLease = "lease-create"
TxTypeCloseLease = "lease-close"

TagAppProvider = "provider"
TxTypeProviderCreate = "provider-create"
Expand Down
3 changes: 3 additions & 0 deletions cmd/akash/marketplace.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,8 @@ func marketplaceMonitorHandler() marketplace.Handler {
OnTxCloseFulfillment(func(tx *types.TxCloseFulfillment) {
fmt.Printf("FULFILLMENT CLOSED\t%v\n", X(tx.Fulfillment))
}).
OnTxCloseLease(func(tx *types.TxCloseLease) {
fmt.Printf("LEASE CLOSED\t%v\n", X(tx.Lease))
}).
Create()
}
70 changes: 70 additions & 0 deletions cmd/akash/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"math/rand"
"strconv"

"github.com/ovrclk/akash/cmd/akash/constants"
"github.com/ovrclk/akash/cmd/akash/context"
Expand Down Expand Up @@ -36,6 +37,7 @@ func providerCommand() *cobra.Command {
cmd.AddCommand(createProviderCommand())
cmd.AddCommand(runCommand())
cmd.AddCommand(closeFulfillmentCommand())
cmd.AddCommand(closeLeaseCommand())

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

return nil
}

func closeLeaseCommand() *cobra.Command {

cmd := &cobra.Command{
Use: "closel <deployment> <group> <order> <provider>",
Short: "close an active lease",
Args: cobra.ExactArgs(4),
RunE: context.WithContext(context.RequireNode(doCloseLeaseCommand)),
}

context.AddFlagKeyType(cmd, cmd.Flags())

return cmd
}

func doCloseLeaseCommand(ctx context.Context, cmd *cobra.Command, args []string) error {
signer, _, err := ctx.Signer()
if err != nil {
return err
}

nonce, err := ctx.Nonce()
if err != nil {
return err
}

deployment := new(base.Bytes)
if err := deployment.DecodeString(args[0]); err != nil {
return err
}

group, err := strconv.ParseUint(args[1], 10, 64)
if err != nil {
return err
}

order, err := strconv.ParseUint(args[2], 10, 64)
if err != nil {
return err
}

provider := new(base.Bytes)
if err := provider.DecodeString(args[3]); err != nil {
return err
}

lease := state.LeaseID(*deployment, group, order, *provider)

tx, err := txutil.BuildTx(signer, nonce, &types.TxCloseLease{
Lease: lease,
})
if err != nil {
return err
}

result, err := ctx.Client().BroadcastTxCommit(tx)
if err != nil {
return err
}
if result.CheckTx.IsErr() {
return errors.New(result.CheckTx.GetLog())
}
if result.DeliverTx.IsErr() {
return errors.New(result.DeliverTx.GetLog())
}

return nil
}
Loading

0 comments on commit 2c45ebb

Please sign in to comment.