Skip to content

Commit

Permalink
Merge pull request #1699 from mesg-foundation/feature/process-coins
Browse files Browse the repository at this point in the history
Get coins from execution's process if attached
  • Loading branch information
Nicolas Mahé authored Mar 13, 2020
2 parents d7014ac + 46623cf commit 970eb34
Show file tree
Hide file tree
Showing 11 changed files with 176 additions and 11 deletions.
2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ func NewInitApp(
// Engine's module keepers
app.ownershipKeeper = ownership.NewKeeper(app.cdc, keys[ownership.StoreKey], app.bankKeeper)
app.instanceKeeper = instance.NewKeeper(app.cdc, keys[instance.StoreKey])
app.processKeeper = process.NewKeeper(app.cdc, keys[process.StoreKey], app.instanceKeeper, app.ownershipKeeper)
app.processKeeper = process.NewKeeper(app.cdc, keys[process.StoreKey], app.instanceKeeper, app.ownershipKeeper, app.bankKeeper)
app.serviceKeeper = service.NewKeeper(app.cdc, keys[service.StoreKey], app.ownershipKeeper)
app.runnerKeeper = runner.NewKeeper(app.cdc, keys[runner.StoreKey], app.instanceKeeper, app.ownershipKeeper)
app.executionKeeper = execution.NewKeeper(
Expand Down
2 changes: 1 addition & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func defaultConfig() (*Config, error) {

c.IpfsEndpoint = "http://ipfs.app.mesg.com:8080/ipfs/"

c.DefaultExecutionPrice = "10000atto" // /x/execution/internal/type/params.go#DefaultMinPrice
c.DefaultExecutionPrice = "10000atto" // /x/execution/internal/types/params.go#DefaultMinPrice

c.Server.Address = ":50052"
c.Log.Format = "text"
Expand Down
12 changes: 9 additions & 3 deletions e2e/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"testing"

"github.com/cosmos/cosmos-sdk/crypto/keys"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/rest"
"github.com/mesg-foundation/engine/app"
"github.com/mesg-foundation/engine/config"
Expand All @@ -31,9 +32,11 @@ type apiclient struct {
}

var (
client apiclient
cclient *cosmos.Client
cdc = app.MakeCodec()
minExecutionPrice sdk.Coins
client apiclient
cclient *cosmos.Client
cdc = app.MakeCodec()
processInitialBalance = sdk.NewCoins(sdk.NewInt64Coin("atto", 10000000))
)

const (
Expand Down Expand Up @@ -77,6 +80,9 @@ func TestAPI(t *testing.T) {
cfg, err := config.New()
require.NoError(t, err)

minExecutionPrice, err = sdk.ParseCoins(cfg.DefaultExecutionPrice)
require.NoError(t, err)

cosmos.CustomizeConfig(cfg)

conn, err := grpc.DialContext(context.Background(), "localhost:50052", grpc.WithInsecure())
Expand Down
8 changes: 4 additions & 4 deletions e2e/execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ func testExecution(t *testing.T) {
t.Run("execution balance before completed", func(t *testing.T) {
coins := sdk.Coins{}
lcdGet(t, "bank/balances/"+execAddress.String(), &coins)
require.True(t, coins.AmountOf("atto").Equal(sdk.NewInt(50000)))
require.True(t, coins.AmountOf("atto").Equal(sdk.NewInt(50000)), coins)
})

var executorBalance sdk.Coins
Expand All @@ -241,20 +241,20 @@ func testExecution(t *testing.T) {
t.Run("executor balance", func(t *testing.T) {
coins := sdk.Coins{}
lcdGet(t, "bank/balances/"+executorAddress.String(), &coins)
require.True(t, coins.AmountOf("atto").Equal(sdk.NewInt(45000).Add(executorBalance.AmountOf("atto"))))
require.True(t, coins.AmountOf("atto").Equal(sdk.NewInt(45000).Add(executorBalance.AmountOf("atto"))), coins)
})
// check balance of service
t.Run("service balance", func(t *testing.T) {
coins := sdk.Coins{}
lcdGet(t, "bank/balances/"+serviceAddress.String(), &coins)
require.True(t, coins.AmountOf("atto").Equal(sdk.NewInt(5000).Add(serviceBalance.AmountOf("atto"))))
require.True(t, coins.AmountOf("atto").Equal(sdk.NewInt(5000).Add(serviceBalance.AmountOf("atto"))), coins)
})
// check balance of execution
t.Run("execution balance", func(t *testing.T) {
coins := sdk.Coins{}
execAddress := sdk.AccAddress(crypto.AddressHash(resp.Hash))
lcdGet(t, "bank/balances/"+execAddress.String(), &coins)
require.True(t, coins.AmountOf("atto").Equal(sdk.NewInt(0)))
require.True(t, coins.AmountOf("atto").Equal(sdk.NewInt(0)), coins)
})

t.Run("withdraw from service", func(t *testing.T) {
Expand Down
109 changes: 109 additions & 0 deletions e2e/orchestrator_balance_withdraw_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package main

import (
"context"
"testing"
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/mesg-foundation/engine/execution"
"github.com/mesg-foundation/engine/hash"
"github.com/mesg-foundation/engine/process"
pb "github.com/mesg-foundation/engine/protobuf/api"
"github.com/mesg-foundation/engine/protobuf/types"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
)

func testOrchestratorProcessBalanceWithdraw(executionStream pb.Execution_StreamClient, instanceHash hash.Hash) func(t *testing.T) {
return func(t *testing.T) {
var processHash hash.Hash

t.Run("create process", func(t *testing.T) {
respProc, err := client.ProcessClient.Create(context.Background(), &pb.CreateProcessRequest{
Name: "event-task-process",
Nodes: []*process.Process_Node{
{
Key: "n0",
Type: &process.Process_Node_Event_{
Event: &process.Process_Node_Event{
InstanceHash: instanceHash,
EventKey: "test_event",
},
},
},
{
Key: "n1",
Type: &process.Process_Node_Task_{
Task: &process.Process_Node_Task{
InstanceHash: instanceHash,
TaskKey: "task1",
},
},
},
},
Edges: []*process.Process_Edge{
{Src: "n0", Dst: "n1"},
},
})
require.NoError(t, err)
processHash = respProc.Hash
})
t.Run("check coins on process", func(t *testing.T) {
var coins sdk.Coins
param := bank.NewQueryBalanceParams(sdk.AccAddress(crypto.AddressHash(processHash)))
require.NoError(t, cclient.QueryJSON("custom/bank/balances", param, &coins))
require.True(t, coins.IsEqual(processInitialBalance), coins)
})
t.Run("trigger process", func(t *testing.T) {
_, err := client.EventClient.Create(context.Background(), &pb.CreateEventRequest{
InstanceHash: instanceHash,
Key: "test_event",
Data: &types.Struct{
Fields: map[string]*types.Value{
"msg": {
Kind: &types.Value_StringValue{
StringValue: "foo_1",
},
},
"timestamp": {
Kind: &types.Value_NumberValue{
NumberValue: float64(time.Now().Unix()),
},
},
},
},
})
require.NoError(t, err)
})
t.Run("check in progress execution", func(t *testing.T) {
exec, err := executionStream.Recv()
require.NoError(t, err)
require.True(t, processHash.Equal(exec.ProcessHash))
require.Equal(t, execution.Status_InProgress, exec.Status)
})
t.Run("check completed execution", func(t *testing.T) {
exec, err := executionStream.Recv()
require.NoError(t, err)
require.True(t, processHash.Equal(exec.ProcessHash))
require.Equal(t, execution.Status_Completed, exec.Status)
})
t.Run("check coins on process after 1 execution", func(t *testing.T) {
var coins sdk.Coins
param := bank.NewQueryBalanceParams(sdk.AccAddress(crypto.AddressHash(processHash)))
require.NoError(t, cclient.QueryJSON("custom/bank/balances", param, &coins))
require.True(t, coins.IsEqual(processInitialBalance.Sub(minExecutionPrice)), coins)
})
t.Run("delete process", func(t *testing.T) {
_, err := client.ProcessClient.Delete(context.Background(), &pb.DeleteProcessRequest{Hash: processHash})
require.NoError(t, err)
})
t.Run("check coins on process after deletion", func(t *testing.T) {
var coins sdk.Coins
param := bank.NewQueryBalanceParams(sdk.AccAddress(crypto.AddressHash(processHash)))
require.NoError(t, cclient.QueryJSON("custom/bank/balances", param, &coins))
require.True(t, coins.IsZero(), coins)
})
}
}
1 change: 1 addition & 0 deletions e2e/orchestrator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ func testOrchestrator(t *testing.T) {
acknowledgement.WaitForStreamToBeReady(executionStream)

// running orchestrator tests
t.Run("process balance and withdraw", testOrchestratorProcessBalanceWithdraw(executionStream, testInstanceHash))
t.Run("event task", testOrchestratorEventTask(executionStream, testInstanceHash))
t.Run("result task", testOrchestratorResultTask(executionStream, testRunnerHash, testInstanceHash))
t.Run("map const", testOrchestratorMapConst(executionStream, testInstanceHash))
Expand Down
17 changes: 17 additions & 0 deletions e2e/process_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import (
"context"
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/mesg-foundation/engine/hash"
"github.com/mesg-foundation/engine/ownership"
"github.com/mesg-foundation/engine/process"
pb "github.com/mesg-foundation/engine/protobuf/api"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
)

var testProcessHash hash.Hash
Expand Down Expand Up @@ -102,6 +105,13 @@ func testProcess(t *testing.T) {
})
})

t.Run("check coins on process", func(t *testing.T) {
var coins sdk.Coins
param := bank.NewQueryBalanceParams(sdk.AccAddress(crypto.AddressHash(processHash)))
require.NoError(t, cclient.QueryJSON("custom/bank/balances", param, &coins))
require.True(t, coins.IsEqual(processInitialBalance), coins)
})

t.Run("list", func(t *testing.T) {
t.Run("grpc", func(t *testing.T) {
ps, err := client.ProcessClient.List(context.Background(), &pb.ListProcessRequest{})
Expand Down Expand Up @@ -132,4 +142,11 @@ func testProcess(t *testing.T) {
require.Len(t, ownerships.Ownerships, 2)
})
})

t.Run("check coins on process", func(t *testing.T) {
var coins sdk.Coins
param := bank.NewQueryBalanceParams(sdk.AccAddress(crypto.AddressHash(processHash)))
require.NoError(t, cclient.QueryJSON("custom/bank/balances", param, &coins))
require.True(t, coins.IsZero(), coins)
})
}
9 changes: 9 additions & 0 deletions e2e/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import (
"context"
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/mesg-foundation/engine/hash"
"github.com/mesg-foundation/engine/protobuf/acknowledgement"
pb "github.com/mesg-foundation/engine/protobuf/api"
"github.com/mesg-foundation/engine/runner"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
)

var testRunnerHash hash.Hash
Expand Down Expand Up @@ -93,4 +96,10 @@ func testDeleteRunner(t *testing.T) {
lcdGet(t, "runner/list", &rs)
require.Len(t, rs, 0)
})
t.Run("check coins on runner", func(t *testing.T) {
var coins sdk.Coins
param := bank.NewQueryBalanceParams(sdk.AccAddress(crypto.AddressHash(testRunnerHash)))
require.NoError(t, cclient.QueryJSON("custom/bank/balances", param, &coins))
require.True(t, coins.IsZero(), coins)
})
}
6 changes: 5 additions & 1 deletion x/execution/internal/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,12 @@ func (k *Keeper) Create(ctx sdk.Context, msg types.MsgCreateExecution) (*executi
M.InProgress.Add(1)
}

from := msg.Signer
if !msg.Request.ProcessHash.IsZero() {
from = sdk.AccAddress(crypto.AddressHash(msg.Request.ProcessHash))
}
execAddress := sdk.AccAddress(crypto.AddressHash(exec.Hash))
if err := k.bankKeeper.SendCoins(ctx, msg.Signer, execAddress, price); err != nil {
if err := k.bankKeeper.SendCoins(ctx, from, execAddress, price); err != nil {
return nil, err
}

Expand Down
16 changes: 15 additions & 1 deletion x/process/internal/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,29 @@ import (
"github.com/mesg-foundation/engine/process"
processpb "github.com/mesg-foundation/engine/process"
"github.com/mesg-foundation/engine/x/process/internal/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/log"
)

var processCreateInitialBalance = "10000000atto"

// Keeper of the process store
type Keeper struct {
storeKey sdk.StoreKey
cdc *codec.Codec
ownershipKeeper types.OwnershipKeeper
instanceKeeper types.InstanceKeeper
bankKeeper types.BankKeeper
}

// NewKeeper creates a process keeper
func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, instanceKeeper types.InstanceKeeper, ownershipKeeper types.OwnershipKeeper) Keeper {
func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, instanceKeeper types.InstanceKeeper, ownershipKeeper types.OwnershipKeeper, bankKeeper types.BankKeeper) Keeper {
keeper := Keeper{
storeKey: key,
cdc: cdc,
instanceKeeper: instanceKeeper,
ownershipKeeper: ownershipKeeper,
bankKeeper: bankKeeper,
}
return keeper
}
Expand Down Expand Up @@ -67,6 +72,15 @@ func (k Keeper) Create(ctx sdk.Context, msg *types.MsgCreateProcess) (*processpb
}
}

procAddress := sdk.AccAddress(crypto.AddressHash(p.Hash))
procInitBal, err := sdk.ParseCoins(processCreateInitialBalance)
if err != nil {
return nil, err
}
if err := k.bankKeeper.SendCoins(ctx, msg.Owner, procAddress, procInitBal); err != nil {
return nil, err
}

value, err := k.cdc.MarshalBinaryLengthPrefixed(p)
if err != nil {
return nil, err
Expand Down
5 changes: 5 additions & 0 deletions x/process/internal/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,8 @@ type OwnershipKeeper interface {
Delete(ctx sdk.Context, owner sdk.AccAddress, resourceHash hash.Hash) error
Set(ctx sdk.Context, owner sdk.AccAddress, resourceHash hash.Hash, resource ownershippb.Ownership_Resource) (*ownershippb.Ownership, error)
}

// BankKeeper module interface.
type BankKeeper interface {
SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error
}

0 comments on commit 970eb34

Please sign in to comment.