add basic keeper logic

This commit is contained in:
rhuairahrighairigh 2018-07-09 19:46:51 +01:00
parent afb7de58dd
commit 757b6eaff4
3 changed files with 67 additions and 15 deletions

View File

@ -5,6 +5,7 @@ import (
"reflect" "reflect"
) )
// Called when adding routes to a newly created app.
// NewHandler returns a handler for "paychan" type messages. // NewHandler returns a handler for "paychan" type messages.
func NewHandler(k Keeper) sdk.Handler { func NewHandler(k Keeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {

View File

@ -1,62 +1,112 @@
package paychan package paychan
import (
"strconv"
)
// keeper of the paychan store // keeper of the paychan store
type Keeper struct { type Keeper struct {
storeKey sdk.StoreKey storeKey sdk.StoreKey
cdc *wire.Codec // needed? //cdc *wire.Codec // needed?
coinKeeper bank.Keeper coinKeeper bank.Keeper
// codespace // codespace
codespace sdk.CodespaceType // ?? //codespace sdk.CodespaceType // ??
} }
func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper, codespace sdk.CodespaceType) Keeper { // Called when creating new app.
//func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper, codespace sdk.CodespaceType) Keeper {
func NewKeeper(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,
} }
return keeper return keeper
} }
// bunch of business logic ... // bunch of business logic ...
func (keeper Keeper) GetPaychan(paychanID) Paychan {
// Reteive a payment channel struct from the blockchain store.
// 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) {
// Return error as second argument instead of bool?
var pych Paychan
// load from DB // load from DB
// unmarshall store := ctx.KVStore(k.storeKey)
bz := store.Get(paychanKey(sender, receiver, id))
if bz == nil {
return pych, false
}
// unmarshal
k.cdc.MustUnmarshalBinary(bz, &pych)
// return // return
return pych, true
} }
// Store payment channel struct in blockchain store.
func (keeper Keeper) setPaychan(pych Paychan) sdk.Error { func (keeper Keeper) setPaychan(pych Paychan) sdk.Error {
store := ctx.KVStore(k.storeKey)
// marshal // marshal
bz := k.cdc.MustMarshalBinary(pych)
// write to db // write to db
pychKey := paychanKey(pych.sender, pych.receiver, pych.id)
store.Set(pychKey, bz)
// TODO handler errors
} }
func (keeer Keeper) CreatePaychan(receiver sdkAddress, amt sdk.Coins) (Paychan, sdk.Error) { // Create a new payment channel and lock up sender funds.
func (keeer Keeper) CreatePaychan(sender sdk.Address, receiver sdkAddress, id integer, amt sdk.Coins) (Paychan, sdk.Error) {
// subtract coins from sender // subtract coins from sender
k.coinKeeper.SubtractCoins(ctx, sender, amt)
// create new Paychan struct (create ID) // create new Paychan struct (create ID)
pych := Paychan{sender,
receiver,
id,
balance: amt}
// save to db // save to db
err := k.setPaychan(pych)
// validation: return pych, err
// sender has enough coins
// TODO validation
// sender has enough coins - done in Subtract method
// receiver address exists? // receiver address exists?
// paychan doesn't exist already // paychan doesn't exist already
} }
func (keeper Keeper) ClosePaychan() sdk.Error { // 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.Error {
pych := GetPaychan(ctx, sender, receiver, id)
// compute coin distribution
senderAmt = pych.balance.Minus(receiverAmt) // Minus sdk.Coins method
// add coins to sender // add coins to sender
k.coinKeeper.AddCoins(ctx, sender, senderAmt)
// add coins to receiver // add coins to receiver
k.coinKeeper.AddCoins(ctx, receiver, receiverAmt)
// delete paychan from db // delete paychan from db
pychKey := paychanKey(pych.sender, pych.receiver, pych.id)
store.Delete(pychKey)
// validation:
// TODO validation
// paychan exists // paychan exists
// output coins are less than paychan balance // output coins are less than paychan balance
// sender and receiver addresses exist? // sender and receiver addresses exist?
return nil
} }
func paychanKey(Paychan) { // Creates a key to reference a paychan in the blockchain store.
func paychanKey(sender sdk.Address, receiver sdk.Address, id integer) []byte {
//sdk.Address is just a slice of bytes under a different name
//convert id to string then to byte slice
idAsBytes := []byte(strconv.Itoa(id))
// concat sender and receiver and integer ID // concat sender and receiver and integer ID
return append(sender.Bytes(), receiver.Bytes()..., idAsBytes...)
} }
// maybe getAllPaychans(sender sdk.address) []Paychan // maybe getAllPaychans(sender sdk.address) []Paychan

View File

@ -11,6 +11,7 @@ struct Paychan {
balance sdk.Coins balance sdk.Coins
sender sdk.Address sender sdk.Address
receiver sdk.Address receiver sdk.Address
id integer
} }