2018-07-08 22:09:07 +00:00
|
|
|
package paychan
|
|
|
|
|
|
|
|
import (
|
2018-08-29 03:45:26 +00:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
//"github.com/stretchr/testify/require"
|
|
|
|
"github.com/tendermint/tendermint/crypto"
|
2018-07-08 22:09:07 +00:00
|
|
|
"testing"
|
2018-08-29 03:45:26 +00:00
|
|
|
)
|
2018-07-13 15:22:58 +00:00
|
|
|
|
2018-08-29 03:45:26 +00:00
|
|
|
func TestKeeper(t *testing.T) {
|
2018-07-13 15:22:58 +00:00
|
|
|
|
2018-08-29 03:45:26 +00:00
|
|
|
t.Run("CreateChannel", func(t *testing.T) {
|
|
|
|
|
|
|
|
//
|
|
|
|
////// SETUP
|
|
|
|
// create basic mock app
|
|
|
|
ctx, coinKeeper, channelKeeper, addrs, genAccFunding := createMockApp()
|
|
|
|
|
|
|
|
sender := addrs[0]
|
|
|
|
receiver := addrs[1]
|
|
|
|
coins := sdk.Coins{sdk.NewCoin("KVA", 10)}
|
|
|
|
|
|
|
|
//
|
|
|
|
////// ACTION
|
|
|
|
_, err := channelKeeper.CreateChannel(ctx, sender, receiver, coins)
|
|
|
|
|
|
|
|
//
|
|
|
|
////// CHECK RESULTS
|
|
|
|
assert.Nil(t, err)
|
|
|
|
// channel exists with correct attributes
|
|
|
|
channelID := ChannelID(0) // should be 0 as first channel
|
|
|
|
expectedChan := Channel{
|
|
|
|
ID: channelID,
|
|
|
|
Participants: [2]sdk.AccAddress{sender, receiver},
|
|
|
|
Coins: coins,
|
|
|
|
}
|
|
|
|
createdChan, _ := channelKeeper.getChannel(ctx, channelID)
|
|
|
|
assert.Equal(t, expectedChan, createdChan)
|
|
|
|
// check coins deducted from sender
|
|
|
|
assert.Equal(t, genAccFunding.Minus(coins), coinKeeper.GetCoins(ctx, sender))
|
|
|
|
// check no coins deducted from receiver
|
|
|
|
assert.Equal(t, genAccFunding, coinKeeper.GetCoins(ctx, receiver))
|
|
|
|
// check next chan id
|
|
|
|
assert.Equal(t, ChannelID(1), channelKeeper.getNewChannelID(ctx))
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("ReceiverCloseChannel", func(t *testing.T) {
|
|
|
|
// SETUP
|
|
|
|
ctx, coinKeeper, channelKeeper, addrs, genAccFunding := createMockApp()
|
|
|
|
|
|
|
|
sender := addrs[0]
|
|
|
|
receiver := addrs[1]
|
|
|
|
coins := sdk.Coins{sdk.NewCoin("KVA", 10)}
|
|
|
|
|
|
|
|
// create new channel
|
|
|
|
channelID := ChannelID(0) // should be 0 as first channel
|
|
|
|
channel := Channel{
|
|
|
|
ID: channelID,
|
|
|
|
Participants: [2]sdk.AccAddress{sender, receiver},
|
|
|
|
Coins: coins,
|
|
|
|
}
|
|
|
|
channelKeeper.setChannel(ctx, channel)
|
|
|
|
|
|
|
|
// create closing update
|
|
|
|
payouts := Payouts{
|
|
|
|
{sender, sdk.Coins{sdk.NewCoin("KVA", 3)}},
|
|
|
|
{receiver, sdk.Coins{sdk.NewCoin("KVA", 7)}},
|
|
|
|
}
|
|
|
|
update := Update{
|
|
|
|
ChannelID: channelID,
|
|
|
|
Payouts: payouts,
|
|
|
|
Sequence: 0,
|
|
|
|
Sigs: [1]crypto.Signature{},
|
|
|
|
}
|
|
|
|
// Set empty submittedUpdatesQueue TODO work out proper genesis initialisation
|
|
|
|
channelKeeper.setSubmittedUpdatesQueue(ctx, SubmittedUpdatesQueue{})
|
2018-07-08 22:09:07 +00:00
|
|
|
|
2018-08-29 03:45:26 +00:00
|
|
|
// ACTION
|
|
|
|
_, err := channelKeeper.CloseChannelByReceiver(ctx, update)
|
|
|
|
|
|
|
|
// CHECK RESULTS
|
|
|
|
// no error
|
|
|
|
assert.Nil(t, err)
|
|
|
|
// coins paid out
|
|
|
|
senderPayout, _ := payouts.Get(sender)
|
|
|
|
assert.Equal(t, genAccFunding.Plus(senderPayout), coinKeeper.GetCoins(ctx, sender))
|
|
|
|
receiverPayout, _ := payouts.Get(receiver)
|
|
|
|
assert.Equal(t, genAccFunding.Plus(receiverPayout), coinKeeper.GetCoins(ctx, receiver))
|
|
|
|
// channel deleted
|
|
|
|
_, found := channelKeeper.getChannel(ctx, channelID)
|
|
|
|
assert.False(t, found)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("SenderInitCloseChannel", func(t *testing.T) {
|
|
|
|
// SETUP
|
|
|
|
ctx, _, channelKeeper, addrs, _ := createMockApp()
|
|
|
|
|
|
|
|
sender := addrs[0]
|
|
|
|
receiver := addrs[1]
|
|
|
|
coins := sdk.Coins{sdk.NewCoin("KVA", 10)}
|
|
|
|
|
|
|
|
// create new channel
|
|
|
|
channelID := ChannelID(0) // should be 0 as first channel
|
|
|
|
channel := Channel{
|
|
|
|
ID: channelID,
|
|
|
|
Participants: [2]sdk.AccAddress{sender, receiver},
|
|
|
|
Coins: coins,
|
|
|
|
}
|
|
|
|
channelKeeper.setChannel(ctx, channel)
|
|
|
|
|
|
|
|
// create closing update
|
|
|
|
payouts := Payouts{
|
|
|
|
{sender, sdk.Coins{sdk.NewCoin("KVA", 3)}},
|
|
|
|
{receiver, sdk.Coins{sdk.NewCoin("KVA", 7)}},
|
|
|
|
}
|
|
|
|
update := Update{
|
|
|
|
ChannelID: channelID,
|
|
|
|
Payouts: payouts,
|
|
|
|
Sequence: 0,
|
|
|
|
Sigs: [1]crypto.Signature{},
|
|
|
|
}
|
|
|
|
// Set empty submittedUpdatesQueue TODO work out proper genesis initialisation
|
|
|
|
channelKeeper.setSubmittedUpdatesQueue(ctx, SubmittedUpdatesQueue{})
|
|
|
|
|
|
|
|
// ACTION
|
|
|
|
_, err := channelKeeper.InitCloseChannelBySender(ctx, update)
|
|
|
|
|
|
|
|
// CHECK RESULTS
|
|
|
|
// no error
|
|
|
|
assert.Nil(t, err)
|
|
|
|
// submittedupdate in queue and correct
|
|
|
|
suq, found := channelKeeper.getSubmittedUpdatesQueue(ctx)
|
|
|
|
assert.True(t, found)
|
|
|
|
assert.True(t, suq.Contains(channelID))
|
|
|
|
|
|
|
|
su, found := channelKeeper.getSubmittedUpdate(ctx, channelID)
|
|
|
|
assert.True(t, found)
|
|
|
|
expectedSubmittedUpdate := SubmittedUpdate{
|
|
|
|
Update: update,
|
|
|
|
ExecutionTime: ChannelDisputeTime,
|
|
|
|
}
|
|
|
|
assert.Equal(t, expectedSubmittedUpdate, su)
|
|
|
|
// TODO check channel is still in db and coins haven't changed?
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2018-07-13 15:22:58 +00:00
|
|
|
|
|
|
|
func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey, *sdk.KVStoreKey) {
|
|
|
|
// create db
|
|
|
|
db := dbm.NewMemDB()
|
|
|
|
// create keys
|
|
|
|
authKey := sdk.NewKVStoreKey("authkey")
|
|
|
|
paychanKey := sdk.NewKVStoreKey("paychankey")
|
|
|
|
// create new multistore around db
|
|
|
|
ms := store.NewCommitMultiStore(db) // DB handle plus store key maps
|
|
|
|
// register separate stores in the multistore
|
|
|
|
ms.MountStoreWithDB(authKey, sdk.StoreTypeIAVL, db) // sets store key map
|
|
|
|
ms.MountStoreWithDB(paychanKey, sdk.StoreTypeIAVL, db)
|
|
|
|
ms.LoadLatestVersion()
|
|
|
|
|
|
|
|
return ms, authKey, paychanKey
|
|
|
|
}
|
|
|
|
|
|
|
|
func setupCodec() *wire.Codec {
|
|
|
|
cdc := wire.NewCodec()
|
|
|
|
auth.RegisterBaseAccount(cdc)
|
|
|
|
// TODO might need to register paychan struct
|
|
|
|
return cdc
|
|
|
|
}
|
|
|
|
|
2018-07-08 22:09:07 +00:00
|
|
|
func TestKeeper(t *testing.T) {
|
2018-07-13 15:22:58 +00:00
|
|
|
// Setup
|
2018-07-15 11:41:55 +00:00
|
|
|
|
2018-07-13 15:22:58 +00:00
|
|
|
// create multistore and key
|
|
|
|
ms, authKey, paychanKey := setupMultiStore()
|
|
|
|
|
|
|
|
// create and initialise codec(s)
|
|
|
|
cdc := setupCodec()
|
|
|
|
|
|
|
|
// create context
|
|
|
|
ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger())
|
|
|
|
|
|
|
|
// create accountMapper
|
|
|
|
accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{})
|
|
|
|
|
|
|
|
// create coinkeeper
|
|
|
|
coinKeeper := bank.NewKeeper(accountMapper)
|
|
|
|
|
|
|
|
// create keeper
|
|
|
|
paychanKeeper := NewKeeper(cdc, paychanKey, coinKeeper)
|
|
|
|
|
|
|
|
// Test no paychans exist
|
|
|
|
_, exists := paychanKeeper.GetPaychan(ctx, sdk.Address{}, sdk.Address{}, 0)
|
|
|
|
if exists {
|
|
|
|
t.Error("payment channel found when none exist")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test paychan can be set and get
|
|
|
|
p := Paychan{
|
2018-07-15 11:41:55 +00:00
|
|
|
Sender: sdk.Address([]byte("senderAddress")),
|
|
|
|
Receiver: sdk.Address([]byte("receiverAddress")),
|
|
|
|
Id: 0,
|
|
|
|
Balance: sdk.Coins{{"KVA", 100}},
|
2018-07-13 15:22:58 +00:00
|
|
|
}
|
|
|
|
paychanKeeper.setPaychan(ctx, p)
|
|
|
|
|
2018-07-15 11:41:55 +00:00
|
|
|
_, exists = paychanKeeper.GetPaychan(ctx, p.Sender, p.Receiver, p.Id)
|
2018-07-13 15:22:58 +00:00
|
|
|
if !exists {
|
|
|
|
t.Error("payment channel not found")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test create paychan under normal conditions
|
|
|
|
senderAddress := sdk.Address([]byte("senderAddress"))
|
|
|
|
senderFunds := sdk.Coins{{"KVA", 100}}
|
|
|
|
receiverAddress := sdk.Address([]byte("receiverAddress"))
|
|
|
|
balance := sdk.Coins{{"KVA", 10}}
|
|
|
|
|
|
|
|
coinKeeper.SetCoins(ctx, senderAddress, senderFunds)
|
|
|
|
|
|
|
|
_, err := paychanKeeper.CreatePaychan(ctx, senderAddress, receiverAddress, balance)
|
|
|
|
if err != nil {
|
|
|
|
t.Error("unexpected error created payment channel", err)
|
|
|
|
}
|
|
|
|
|
2018-07-15 11:41:55 +00:00
|
|
|
p, exists = paychanKeeper.GetPaychan(ctx, senderAddress, receiverAddress, 0)
|
|
|
|
if !exists {
|
|
|
|
t.Error("payment channel missing")
|
|
|
|
}
|
|
|
|
if !p.Balance.IsEqual(balance) {
|
|
|
|
t.Error("payment channel balance incorrect", p.Balance, balance)
|
2018-07-13 15:22:58 +00:00
|
|
|
}
|
|
|
|
expectedNewSenderFunds := senderFunds.Minus(balance)
|
|
|
|
if !coinKeeper.GetCoins(ctx, senderAddress).IsEqual(expectedNewSenderFunds) {
|
|
|
|
t.Error("sender has incorrect balance after paychan creation")
|
|
|
|
}
|
2018-07-08 22:09:07 +00:00
|
|
|
|
2018-07-15 11:41:55 +00:00
|
|
|
// Test close paychan under normal conditions
|
|
|
|
senderFunds = coinKeeper.GetCoins(ctx, senderAddress)
|
|
|
|
receiverAmount := sdk.Coins{{"KVA", 9}}
|
|
|
|
_, err = paychanKeeper.ClosePaychan(ctx, senderAddress, receiverAddress, 0, receiverAmount)
|
|
|
|
if err != nil {
|
|
|
|
t.Error("unexpected error closing payment channel", err)
|
|
|
|
}
|
|
|
|
// paychan shouldn't exist
|
|
|
|
_, exists = paychanKeeper.GetPaychan(ctx, senderAddress, receiverAddress, 0)
|
|
|
|
if exists {
|
|
|
|
t.Error("payment channel should not exist")
|
|
|
|
}
|
|
|
|
// sender's funds should have increased
|
|
|
|
expectedNewSenderFunds = senderFunds.Plus(balance.Minus(receiverAmount))
|
|
|
|
if !coinKeeper.GetCoins(ctx, senderAddress).IsEqual(expectedNewSenderFunds) {
|
|
|
|
t.Error("sender has incorrect balance after paychan creation", expectedNewSenderFunds)
|
|
|
|
}
|
|
|
|
// receiver's funds should have increased
|
|
|
|
expectedNewReceiverFunds := receiverAmount // started at zero
|
|
|
|
if !coinKeeper.GetCoins(ctx, receiverAddress).IsEqual(expectedNewReceiverFunds) {
|
|
|
|
t.Error("receiver has incorrect balance after paychan creation")
|
|
|
|
}
|
2018-07-13 15:22:58 +00:00
|
|
|
|
2018-07-15 11:41:55 +00:00
|
|
|
}
|
2018-08-28 03:48:48 +00:00
|
|
|
*/
|