fix syntax errors

This commit is contained in:
rhuairahrighairigh 2018-07-13 14:27:55 +01:00
parent 315a0cefe9
commit 469dd84a32
5 changed files with 93 additions and 77 deletions

View File

@ -1,8 +1,8 @@
package paychan package paychan
import ( import (
"reflect"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"reflect"
) )
// NewHandler returns a handler for "paychan" type messages. // NewHandler returns a handler for "paychan" type messages.
@ -21,18 +21,17 @@ func NewHandler(k Keeper) sdk.Handler {
} }
} }
// Handle CreateMsg. // Handle CreateMsg.
// Leaves validation to the keeper methods. // Leaves validation to the keeper methods.
func handleMsgCreate(ctx sdk.Context, k Keeper, msg MsgCreate) sdk.Result { func handleMsgCreate(ctx sdk.Context, k Keeper, msg MsgCreate) sdk.Result {
// TODO maybe remove tags for first version // TODO maybe remove tags for first version
tags, err := k.CreatePaychan(msg.sender, msg.receiver, msg.amount) tags, err := k.CreatePaychan(ctx, msg.sender, msg.receiver, msg.amount)
if err != nil { if err != nil {
return err.Result() return err.Result()
} }
// TODO any other information that should be returned in Result? // TODO any other information that should be returned in Result?
return sdk.Result{ return sdk.Result{
Tags: tags Tags: tags,
} }
} }
@ -40,12 +39,12 @@ func handleMsgCreate(ctx sdk.Context, k Keeper, msg MsgCreate) sdk.Result {
// Leaves validation to the keeper methods. // Leaves validation to the keeper methods.
func handleMsgClose(ctx sdk.Context, k Keeper, msg MsgClose) sdk.Result { func handleMsgClose(ctx sdk.Context, k Keeper, msg MsgClose) sdk.Result {
// TODO maybe remove tags for first version // TODO maybe remove tags for first version
tags, err := k.ClosePaychan(msg.sender, msg.receiver, msg.id, msg.receiverAmount) tags, err := k.ClosePaychan(ctx, msg.sender, msg.receiver, msg.id, msg.receiverAmount)
if err != nil { if err != nil {
return err.Result() return err.Result()
} }
// These tags can be used to subscribe to channel closures // These tags can be used to subscribe to channel closures
return sdk.Result{ return sdk.Result{
Tags: tags Tags: tags,
} }
} }

View File

@ -5,13 +5,14 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/wire"
"github.com/cosmos/cosmos-sdk/x/bank"
) )
// keeper of the paychan store // keeper of the paychan store
// Handles validation internally. Does not rely on calling code to do validation. // Handles validation internally. Does not rely on calling code to do validation.
// Aim to keep public methids safe, private ones not necessaily. // Aim to keep public methids safe, private ones not necessaily.
type Keeper struct { type Keeper struct {
storeKey sdk.StoreKey storeKey sdk.StoreKey
cdc *wire.Codec // needed to serialize objects before putting them in the store cdc *wire.Codec // needed to serialize objects before putting them in the store
coinKeeper bank.Keeper coinKeeper bank.Keeper
@ -23,7 +24,7 @@ type Keeper struct {
//func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper, codespace sdk.CodespaceType) Keeper { //func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper, codespace sdk.CodespaceType) Keeper {
func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper) Keeper { func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper) Keeper {
keeper := Keeper{ keeper := Keeper{
storeKey: key, storeKey: key,
cdc: cdc, cdc: cdc,
coinKeeper: ck, coinKeeper: ck,
//codespace: codespace, //codespace: codespace,
@ -33,10 +34,9 @@ func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper) Keeper {
// bunch of business logic ... // bunch of business logic ...
// Reteive a payment channel struct from the blockchain store. // Reteive a payment channel struct from the blockchain store.
// They are indexed by a concatenation of sender address, receiver address, and an integer. // They are indexed by a concatenation of sender address, receiver address, and an integer.
func (keeper Keeper) GetPaychan(ctx sdk.Context, sender sdk.Address, receiver sdk.Address, id integer) (Paychan, bool) { func (k Keeper) GetPaychan(ctx sdk.Context, sender sdk.Address, receiver sdk.Address, id int64) (Paychan, bool) {
// Return error as second argument instead of bool? // Return error as second argument instead of bool?
var pych Paychan var pych Paychan
// load from DB // load from DB
@ -52,108 +52,109 @@ func (keeper Keeper) GetPaychan(ctx sdk.Context, sender sdk.Address, receiver sd
} }
// Store payment channel struct in blockchain store. // Store payment channel struct in blockchain store.
func (keeper Keeper) setPaychan(pych Paychan) sdk.Error { func (k Keeper) setPaychan(ctx sdk.Context, pych Paychan) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
// marshal // marshal
bz := k.cdc.MustMarshalBinary(pych) bz := k.cdc.MustMarshalBinary(pych) // panics if something goes wrong
// write to db // write to db
pychKey := paychanKey(pych.sender, pych.receiver, pych.id) pychKey := paychanKey(pych.sender, pych.receiver, pych.id)
store.Set(pychKey, bz) // panics if something goes wrong store.Set(pychKey, bz) // panics if something goes wrong
} }
// Create a new payment channel and lock up sender funds. // Create a new payment channel and lock up sender funds.
func (keeer Keeper) CreatePaychan(ctx sdk.Context, sender sdk.Address, receiver sdkAddress, amt sdk.Coins) (sdk.Tags, sdk.Error) { func (k Keeper) CreatePaychan(ctx sdk.Context, sender sdk.Address, receiver sdk.Address, amount sdk.Coins) (sdk.Tags, sdk.Error) {
// TODO move validation somewhere nicer // TODO move validation somewhere nicer
// args present // args present
if len(sender) == 0 { if len(sender) == 0 {
return sdk.ErrInvalidAddress(sender.String()) return nil, sdk.ErrInvalidAddress(sender.String())
} }
if len(receiver) == 0 { if len(receiver) == 0 {
return sdk.ErrInvalidAddress(receiver.String()) return nil, sdk.ErrInvalidAddress(receiver.String())
} }
if len(amount) == 0 { if len(amount) == 0 {
return sdk.ErrInvalidCoins(amount.String()) return nil, sdk.ErrInvalidCoins(amount.String())
} }
// Check if coins are sorted, non zero, positive // Check if coins are sorted, non zero, positive
if !amount.IsValid() { if !amount.IsValid() {
return sdk.ErrInvalidCoins(amount.String()) return nil, sdk.ErrInvalidCoins(amount.String())
} }
if !amount.IsPositive() { if !amount.IsPositive() {
return sdk.ErrInvalidCoins(amount.String()) return nil, sdk.ErrInvalidCoins(amount.String())
} }
// sender should exist already as they had to sign. // sender should exist already as they had to sign.
// receiver address exists. am is the account mapper in the coin keeper. // receiver address exists. am is the account mapper in the coin keeper.
// TODO automatically create account if not present? // TODO automatically create account if not present?
if k.coinKepper.am.GetAccount(ctx, receiver) == nil { // TODO remove as account mapper not available to this pkg
return sdk.ErrUnknownAddress(receiver.String()) //if k.coinKeeper.am.GetAccount(ctx, receiver) == nil {
} // return nil, sdk.ErrUnknownAddress(receiver.String())
//}
// sender has enough coins - done in Subtract method // sender has enough coins - done in Subtract method
// TODO check if sender and receiver different? // TODO check if sender and receiver different?
// Calculate next id (num existing paychans plus 1) // Calculate next id (num existing paychans plus 1)
id := len(keeper.GetPaychans(sender, receiver)) + 1 // TODO check for overflow? id := int64(len(k.GetPaychans(sender, receiver)) + 1) // TODO check for overflow?
// subtract coins from sender // subtract coins from sender
coins, tags, err := k.coinKeeper.SubtractCoins(ctx, sender, amt) _, tags, err := k.coinKeeper.SubtractCoins(ctx, sender, amount)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// create new Paychan struct // create new Paychan struct
pych := Paychan{sender, pych := Paychan{
receiver, sender: sender,
id, receiver: receiver,
balance: amt} id: id,
balance: amount,
}
// save to db // save to db
k.setPaychan(pych) k.setPaychan(ctx, pych)
// TODO create tags // TODO create tags
tags := sdk.NewTags() //tags := sdk.NewTags()
return tags, err return tags, err
} }
// Close a payment channel and distribute funds to participants. // Close a payment channel and distribute funds to participants.
func (keeper Keeper) ClosePaychan(sender sdk.Address, receiver sdk.Address, id integer, receiverAmt sdk.Coins) (sdk.Tags, sdk.Error) { func (k Keeper) ClosePaychan(ctx sdk.Context, sender sdk.Address, receiver sdk.Address, id int64, receiverAmount sdk.Coins) (sdk.Tags, sdk.Error) {
if len(msg.sender) == 0 { if len(sender) == 0 {
return sdk.ErrInvalidAddress(msg.sender.String()) return nil, sdk.ErrInvalidAddress(sender.String())
} }
if len(msg.receiver) == 0 { if len(receiver) == 0 {
return sdk.ErrInvalidAddress(msg.receiver.String()) return nil, sdk.ErrInvalidAddress(receiver.String())
} }
if len(msg.receiverAmount) == 0 { if len(receiverAmount) == 0 {
return sdk.ErrInvalidCoins(msg.receiverAmount.String()) return nil, sdk.ErrInvalidCoins(receiverAmount.String())
} }
// check id ≥ 0 // check id ≥ 0
if msg.id < 0 { if id < 0 {
return sdk.ErrInvalidAddress(strconv.Itoa(id)) // TODO implement custom errors return nil, sdk.ErrInvalidAddress(strconv.Itoa(int(id))) // TODO implement custom errors
} }
// Check if coins are sorted, non zero, non negative // Check if coins are sorted, non zero, non negative
if !msg.receiverAmount.IsValid() { if !receiverAmount.IsValid() {
return sdk.ErrInvalidCoins(msg.receiverAmount.String()) return nil, sdk.ErrInvalidCoins(receiverAmount.String())
} }
if !msg.receiverAmount.IsPositive() { if !receiverAmount.IsPositive() {
return sdk.ErrInvalidCoins(msg.receiverAmount.String()) return nil, sdk.ErrInvalidCoins(receiverAmount.String())
} }
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
pych, exists := GetPaychan(ctx, sender, receiver, id) pych, exists := k.GetPaychan(ctx, sender, receiver, id)
if !exists { if !exists {
return nil, sdk.ErrUnknownAddress() // TODO implement custom errors return nil, sdk.ErrUnknownAddress("paychan not found") // TODO implement custom errors
} }
// compute coin distribution // compute coin distribution
senderAmt = pych.balance.Minus(receiverAmt) // Minus sdk.Coins method senderAmount := pych.balance.Minus(receiverAmount) // Minus sdk.Coins method
// check that receiverAmt not greater than paychan balance // check that receiverAmt not greater than paychan balance
if !senderAmt.IsNotNegative() { if !senderAmount.IsNotNegative() {
return nil, sdk.ErrInsufficientFunds(pych.balance.String()) return nil, sdk.ErrInsufficientFunds(pych.balance.String())
} }
// add coins to sender // add coins to sender
// creating account if it doesn't exist // creating account if it doesn't exist
k.coinKeeper.AddCoins(ctx, sender, senderAmt) k.coinKeeper.AddCoins(ctx, sender, senderAmount)
// add coins to receiver // add coins to receiver
k.coinKeeper.AddCoins(ctx, receiver, receiverAmt) k.coinKeeper.AddCoins(ctx, receiver, receiverAmount)
// delete paychan from db // delete paychan from db
pychKey := paychanKey(pych.sender, pych.receiver, pych.id) pychKey := paychanKey(pych.sender, pych.receiver, pych.id)
@ -170,19 +171,22 @@ func (keeper Keeper) ClosePaychan(sender sdk.Address, receiver sdk.Address, id i
} }
// Creates a key to reference a paychan in the blockchain store. // Creates a key to reference a paychan in the blockchain store.
func paychanKey(sender sdk.Address, receiver sdk.Address, id integer) []byte { func paychanKey(sender sdk.Address, receiver sdk.Address, id int64) []byte {
//sdk.Address is just a slice of bytes under a different name //sdk.Address is just a slice of bytes under a different name
//convert id to string then to byte slice //convert id to string then to byte slice
idAsBytes := []byte(strconv.Itoa(id)) idAsBytes := []byte(strconv.Itoa(int(id)))
// concat sender and receiver and integer ID // concat sender and receiver and integer ID
return append(sender.Bytes(), receiver.Bytes()..., idAsBytes...) key := append(sender.Bytes(), receiver.Bytes()...)
key = append(key, idAsBytes...)
return key
} }
// Get all paychans between a given sender and receiver. // Get all paychans between a given sender and receiver.
func (keeper Keeper) GetPaychans(sender sdk.Address, receiver sdk.Address) []Paychan { func (k Keeper) GetPaychans(sender sdk.Address, receiver sdk.Address) []Paychan {
var paychans []Paychan var paychans []Paychan
// TODO Implement this // TODO Implement this
return paychans return paychans
} }
// maybe getAllPaychans(sender sdk.address) []Paychan // maybe getAllPaychans(sender sdk.address) []Paychan

View File

@ -2,8 +2,7 @@ package paychan
import ( import (
"testing" "testing"
//"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/assert"
) )
// example from x/bank // example from x/bank

View File

@ -1,21 +1,20 @@
package paychan package paychan
import ( import (
sdk "github.com/cosmos/cosmos-sdk/types"
"strconv" "strconv"
sdk "github.com/cosmos/cosmos-sdk/types"
) )
// Paychan Type // Paychan Type
// Used to represent paychan in keeper module and to serialize. // Used to represent paychan in keeper module and to serialize.
// probably want to convert this to a general purpose "state" // probably want to convert this to a general purpose "state"
struct Paychan { type Paychan struct {
sender sdk.Address sender sdk.Address
receiver sdk.Address receiver sdk.Address
id integer id int64
balance sdk.Coins balance sdk.Coins
} }
// Message Types // Message Types
// Message implement the sdk.Msg interface: // Message implement the sdk.Msg interface:
@ -39,7 +38,6 @@ struct Paychan {
// GetSigners() []Address // GetSigners() []Address
// } // }
// A message to create a payment channel. // A message to create a payment channel.
type MsgCreate struct { type MsgCreate struct {
// maybe just wrap a paychan struct // maybe just wrap a paychan struct
@ -100,6 +98,7 @@ func (msg MsgCreate) ValidateBasic() sdk.Error {
return sdk.ErrInvalidCoins(msg.amount.String()) return sdk.ErrInvalidCoins(msg.amount.String())
} }
// TODO check if Address valid? // TODO check if Address valid?
return nil
} }
func (msg MsgCreate) GetSigners() []sdk.Address { func (msg MsgCreate) GetSigners() []sdk.Address {
@ -107,16 +106,13 @@ func (msg MsgCreate) GetSigners() []sdk.Address {
return []sdk.Address{msg.sender} return []sdk.Address{msg.sender}
} }
// A message to close a payment channel. // A message to close a payment channel.
type MsgClose struct { type MsgClose struct {
// have to include sender and receiver in msg explicitly (rather than just universal paychanID) // have to include sender and receiver in msg explicitly (rather than just universal paychanID)
// this gives ability to verify signatures with no external information // this gives ability to verify signatures with no external information
sender sdk.Address sender sdk.Address
receiver sdk.Address receiver sdk.Address
id integer id int64 // TODO is another int type better?
receiverAmount sdk.Coins // amount the receiver should get - sender amount implicit with paychan balance receiverAmount sdk.Coins // amount the receiver should get - sender amount implicit with paychan balance
} }
@ -136,13 +132,13 @@ func (msg MsgClose) GetSignBytes() []byte {
b, err := msgCdc.MarshalJSON(struct { b, err := msgCdc.MarshalJSON(struct {
SenderAddr string `json:"sender_addr"` SenderAddr string `json:"sender_addr"`
ReceiverAddr string `json:"receiver_addr"` ReceiverAddr string `json:"receiver_addr"`
Id integer `json:"id"` Id int64 `json:"id"`
ReceiverAmount sdk.Coins `json:"receiver_amount"` ReceiverAmount sdk.Coins `json:"receiver_amount"`
}{ }{
SenderAddr: sdk.MustBech32ifyAcc(msg.sender), SenderAddr: sdk.MustBech32ifyAcc(msg.sender),
ReceiverAddr: sdk.MustBech32ifyAcc(msg.receiver), ReceiverAddr: sdk.MustBech32ifyAcc(msg.receiver),
Id: msg.id Id: msg.id,
Amount: msg.receiverAmount, ReceiverAmount: msg.receiverAmount,
}) })
if err != nil { if err != nil {
panic(err) panic(err)
@ -163,7 +159,7 @@ func (msg MsgClose) ValidateBasic() sdk.Error {
} }
// check id ≥ 0 // check id ≥ 0
if msg.id < 0 { if msg.id < 0 {
return sdk.ErrInvalidAddress(strconv.Itoa(id)) // TODO implement custom errors return sdk.ErrInvalidAddress(strconv.Itoa(int(msg.id))) // TODO implement custom errors
} }
// Check if coins are sorted, non zero, non negative // Check if coins are sorted, non zero, non negative
if !msg.receiverAmount.IsValid() { if !msg.receiverAmount.IsValid() {
@ -173,10 +169,10 @@ func (msg MsgClose) ValidateBasic() sdk.Error {
return sdk.ErrInvalidCoins(msg.receiverAmount.String()) return sdk.ErrInvalidCoins(msg.receiverAmount.String())
} }
// TODO check if Address valid? // TODO check if Address valid?
return nil
} }
func (msg MsgClose) GetSigners() []sdk.Address { func (msg MsgClose) GetSigners() []sdk.Address {
// Both sender and receiver must sign in order to close a channel // Both sender and receiver must sign in order to close a channel
retutn []sdk.Address{sender, receiver} return []sdk.Address{msg.sender, msg.receiver}
} }

View File

@ -0,0 +1,18 @@
package paychan
import (
"github.com/cosmos/cosmos-sdk/wire"
)
func RegisterWire(cdc *wire.Codec) {
cdc.RegisterConcrete(MsgCreate{}, "paychan/MsgCreate", nil)
cdc.RegisterConcrete(MsgClose{}, "paychan/MsgClose", nil)
}
var msgCdc = wire.NewCodec()
func init() {
RegisterWire(msgCdc)
// TODO is this needed?
//wire.RegisterCrypto(msgCdc)
}