mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-26 00:05:18 +00:00
initial refactor sketch
This commit is contained in:
parent
3b325798c2
commit
3549c75474
@ -4,12 +4,7 @@ Simplifications:
|
|||||||
|
|
||||||
- unidirectional paychans
|
- unidirectional paychans
|
||||||
- no top ups or partial withdrawals (only opening and closing)
|
- no top ups or partial withdrawals (only opening and closing)
|
||||||
- no protection against fund lock up from dissapearing receiver
|
|
||||||
|
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
- fix issue with multisig accounts and sequence numbers
|
- chnge module name to "channel"?
|
||||||
- create a nicer paychan store key for querying (and implement query)
|
|
||||||
- expand client code
|
|
||||||
- tidy up - add return tags
|
|
||||||
- start removing simplifications, refactor
|
|
||||||
|
@ -33,6 +33,7 @@ import (
|
|||||||
// send paychan payment
|
// send paychan payment
|
||||||
// get balance from receiver
|
// get balance from receiver
|
||||||
|
|
||||||
|
/*
|
||||||
func CreatePaychanCmd(cdc *wire.Codec) *cobra.Command {
|
func CreatePaychanCmd(cdc *wire.Codec) *cobra.Command {
|
||||||
flagTo := "to"
|
flagTo := "to"
|
||||||
flagAmount := "amount"
|
flagAmount := "amount"
|
||||||
@ -297,3 +298,4 @@ func EnsureSignBuild(ctx context.CoreContext, name string, msg sdk.Msg, cdc *wir
|
|||||||
}
|
}
|
||||||
return txBytes, nil
|
return txBytes, nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
//"github.com/cosmos/cosmos-sdk/wire"
|
//"github.com/cosmos/cosmos-sdk/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
// RegisterRoutes registers paychan-related REST handlers to a router
|
// RegisterRoutes registers paychan-related REST handlers to a router
|
||||||
func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
|
func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
|
||||||
//r.HandleFunc("/accounts/{address}/send", SendRequestHandlerFn(cdc, kb, ctx)).Methods("POST")
|
//r.HandleFunc("/accounts/{address}/send", SendRequestHandlerFn(cdc, kb, ctx)).Methods("POST")
|
||||||
@ -20,3 +21,4 @@ func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb
|
|||||||
// get balance from receiver
|
// get balance from receiver
|
||||||
// get balance from local storage
|
// get balance from local storage
|
||||||
// handle incoming payment
|
// handle incoming payment
|
||||||
|
*/
|
||||||
|
13
internal/x/paychan/endblocker.go
Normal file
13
internal/x/paychan/endblocker.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package paychan
|
||||||
|
|
||||||
|
import ()
|
||||||
|
|
||||||
|
func EndBlocker(ctx sdk.Context k Keeper) sdk.Tags {
|
||||||
|
|
||||||
|
// Iterate through submittedUpdates and for each
|
||||||
|
// if current block height >= executionDate
|
||||||
|
// k.CloseChannel(...)
|
||||||
|
|
||||||
|
tags := sdk.NewTags()
|
||||||
|
return tags
|
||||||
|
}
|
@ -12,8 +12,8 @@ func NewHandler(k Keeper) sdk.Handler {
|
|||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
case MsgCreate:
|
case MsgCreate:
|
||||||
return handleMsgCreate(ctx, k, msg)
|
return handleMsgCreate(ctx, k, msg)
|
||||||
case MsgClose:
|
case MsgSubmitUpdate:
|
||||||
return handleMsgClose(ctx, k, msg)
|
return handleMsgSubmitUpdate(ctx, k, msg)
|
||||||
default:
|
default:
|
||||||
errMsg := "Unrecognized paychan Msg type: " + reflect.TypeOf(msg).Name()
|
errMsg := "Unrecognized paychan Msg type: " + reflect.TypeOf(msg).Name()
|
||||||
return sdk.ErrUnknownRequest(errMsg).Result()
|
return sdk.ErrUnknownRequest(errMsg).Result()
|
||||||
@ -21,11 +21,10 @@ func NewHandler(k Keeper) sdk.Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle CreateMsg.
|
// Handle MsgCreate
|
||||||
// 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
|
tags, err := k.CreateChannel(ctx, msg.Participants[0], msg.Participants[len(msg.Participants)-1], msg.Coins)
|
||||||
tags, err := k.CreatePaychan(ctx, msg.Sender, msg.Receiver, msg.Amount)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Result()
|
return err.Result()
|
||||||
}
|
}
|
||||||
@ -35,15 +34,19 @@ func handleMsgCreate(ctx sdk.Context, k Keeper, msg MsgCreate) sdk.Result {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle CloseMsg.
|
// Handle MsgSubmitUpdate
|
||||||
// Leaves validation to the keeper methods.
|
// Leaves validation to the keeper methods.
|
||||||
func handleMsgClose(ctx sdk.Context, k Keeper, msg MsgClose) sdk.Result {
|
func handleMsgSubmitUpdate(ctx sdk.Context, k Keeper, msg MsgSubmitUpdate) sdk.Result {
|
||||||
// TODO maybe remove tags for first version
|
|
||||||
tags, err := k.ClosePaychan(ctx, msg.Sender, msg.Receiver, msg.Id, msg.ReceiverAmount)
|
// if only sender sig then
|
||||||
|
tags, err := k.InitChannelCloseBySender()
|
||||||
|
// else (if there are both)
|
||||||
|
tags, err := k.ChannelCloseByReceiver()
|
||||||
|
|
||||||
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 by clients to subscribe to channel close attempts
|
||||||
return sdk.Result{
|
return sdk.Result{
|
||||||
Tags: tags,
|
Tags: tags,
|
||||||
}
|
}
|
||||||
|
@ -8,20 +8,19 @@ import (
|
|||||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
"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 methods 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
|
||||||
|
|
||||||
// codespace
|
// TODO investigate codespace
|
||||||
//codespace sdk.CodespaceType // ??
|
//codespace sdk.CodespaceType
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when creating new app.
|
// Called when creating new app.
|
||||||
//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,
|
||||||
@ -33,7 +32,7 @@ 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 (k Keeper) GetPaychan(ctx sdk.Context, sender sdk.Address, receiver sdk.Address, id int64) (Paychan, bool) {
|
func (k Keeper) GetPaychan(ctx sdk.Context, sender sdk.Address, receiver sdk.Address, id int64) (Paychan, bool) {
|
||||||
@ -60,60 +59,91 @@ func (k Keeper) setPaychan(ctx sdk.Context, pych Paychan) {
|
|||||||
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 (k Keeper) CreatePaychan(ctx sdk.Context, sender sdk.Address, receiver sdk.Address, amount sdk.Coins) (sdk.Tags, sdk.Error) {
|
func (k Keeper) CreatePaychan(ctx sdk.Context, sender sdk.Address, receiver sdk.Address, coins sdk.Coins) (sdk.Tags, sdk.Error) {
|
||||||
// TODO move validation somewhere nicer
|
// TODO do validation and maybe move somewhere nicer
|
||||||
// args present
|
/*
|
||||||
if len(sender) == 0 {
|
// args present
|
||||||
return nil, sdk.ErrInvalidAddress(sender.String())
|
if len(sender) == 0 {
|
||||||
}
|
return nil, sdk.ErrInvalidAddress(sender.String())
|
||||||
if len(receiver) == 0 {
|
}
|
||||||
return nil, sdk.ErrInvalidAddress(receiver.String())
|
if len(receiver) == 0 {
|
||||||
}
|
return nil, sdk.ErrInvalidAddress(receiver.String())
|
||||||
if len(amount) == 0 {
|
}
|
||||||
return nil, sdk.ErrInvalidCoins(amount.String())
|
if len(amount) == 0 {
|
||||||
}
|
return nil, sdk.ErrInvalidCoins(amount.String())
|
||||||
// Check if coins are sorted, non zero, positive
|
}
|
||||||
if !amount.IsValid() {
|
// Check if coins are sorted, non zero, positive
|
||||||
return nil, sdk.ErrInvalidCoins(amount.String())
|
if !amount.IsValid() {
|
||||||
}
|
return nil, sdk.ErrInvalidCoins(amount.String())
|
||||||
if !amount.IsPositive() {
|
}
|
||||||
return nil, sdk.ErrInvalidCoins(amount.String())
|
if !amount.IsPositive() {
|
||||||
}
|
return nil, sdk.ErrInvalidCoins(amount.String())
|
||||||
// sender should exist already as they had to sign.
|
}
|
||||||
// receiver address exists. am is the account mapper in the coin keeper.
|
// sender should exist already as they had to sign.
|
||||||
// TODO automatically create account if not present?
|
// receiver address exists. am is the account mapper in the coin keeper.
|
||||||
// TODO remove as account mapper not available to this pkg
|
// TODO automatically create account if not present?
|
||||||
//if k.coinKeeper.am.GetAccount(ctx, receiver) == nil {
|
// TODO remove as account mapper not available to this pkg
|
||||||
// return nil, 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 (just num of existing paychans - zero indexed)
|
// Calculate next id
|
||||||
id := int64(len(k.GetPaychans(sender, receiver)))
|
id := k.getNewChannelID(ctx)
|
||||||
// subtract coins from sender
|
// subtract coins from sender
|
||||||
_, tags, err := k.coinKeeper.SubtractCoins(ctx, sender, amount)
|
_, tags, err := k.coinKeeper.SubtractCoins(ctx, sender, coins)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// create new Paychan struct
|
// create new Paychan struct
|
||||||
pych := Paychan{
|
channel := Channel{
|
||||||
Sender: sender,
|
ID: id
|
||||||
Receiver: receiver,
|
Participants: [2]sdk.AccAddress{sender, receiver},
|
||||||
Id: id,
|
Coins: coins,
|
||||||
Balance: amount,
|
|
||||||
}
|
}
|
||||||
// save to db
|
// save to db
|
||||||
k.setPaychan(ctx, pych)
|
k.setChannel(ctx, channel)
|
||||||
|
|
||||||
// TODO create tags
|
// TODO create tags
|
||||||
//tags := sdk.NewTags()
|
//tags := sdk.NewTags()
|
||||||
return tags, err
|
return tags, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is how gov manages creating unique IDs. Needs to be deterministic - can't use UUID
|
||||||
|
func (keeper Keeper) getNewChannelID(ctx sdk.Context) (channelID int64, err sdk.Error) {
|
||||||
|
store := ctx.KVStore(keeper.storeKey)
|
||||||
|
bz := store.Get(KeyNextProposalID)
|
||||||
|
if bz == nil {
|
||||||
|
return -1, ErrInvalidGenesis(keeper.codespace, "InitialProposalID never set")
|
||||||
|
}
|
||||||
|
keeper.cdc.MustUnmarshalBinary(bz, &proposalID)
|
||||||
|
bz = keeper.cdc.MustMarshalBinary(proposalID + 1)
|
||||||
|
store.Set(KeyNextProposalID, bz)
|
||||||
|
return proposalID, nil
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (k Keeper) ChannelCloseByReceiver() () {
|
||||||
|
// Validate inputs
|
||||||
|
// k.closeChannel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Keeper) InitChannelCloseBySender() () {
|
||||||
|
// Validate inputs
|
||||||
|
// Create SubmittedUpdate from Update and add to queue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Keeper) closeChannel() () {
|
||||||
|
// Remove corresponding SubmittedUpdate from queue (if it exist)
|
||||||
|
// Add coins to sender and receiver
|
||||||
|
// Delete Channel
|
||||||
|
}
|
||||||
|
/*
|
||||||
// Close a payment channel and distribute funds to participants.
|
// Close a payment channel and distribute funds to participants.
|
||||||
func (k Keeper) ClosePaychan(ctx sdk.Context, sender sdk.Address, receiver sdk.Address, id int64, receiverAmount 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(sender) == 0 {
|
if len(sender) == 0 {
|
||||||
@ -190,3 +220,4 @@ func (k Keeper) GetPaychans(sender sdk.Address, receiver sdk.Address) []Paychan
|
|||||||
}
|
}
|
||||||
|
|
||||||
// maybe getAllPaychans(sender sdk.address) []Paychan
|
// maybe getAllPaychans(sender sdk.address) []Paychan
|
||||||
|
*/
|
||||||
|
@ -5,81 +5,91 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Paychan Type
|
/* CHANNEL TYPES */
|
||||||
// Used to represent paychan in keeper module and to serialize.
|
|
||||||
// probably want to convert this to a general purpose "state"
|
// Used to represent a channel in the keeper module.
|
||||||
type Paychan struct {
|
// Participants is limited to two as currently these are unidirectional channels.
|
||||||
Sender sdk.Address
|
// Last participant is designated as receiver.
|
||||||
Receiver sdk.Address
|
type Channel struct {
|
||||||
Id int64
|
ID int64
|
||||||
Balance sdk.Coins
|
Participants [2]sdk.AccAddress
|
||||||
|
Coins sdk.Coins
|
||||||
}
|
}
|
||||||
|
|
||||||
// Message Types
|
// The data that is passed between participants as payments, and submitted to the blockchain to close a channel.
|
||||||
|
type Update struct {
|
||||||
|
ChannelID int64
|
||||||
|
CoinsUpdate //TODO type
|
||||||
|
Sequence int64
|
||||||
|
sig // TODO type, only sender needs to sign
|
||||||
|
}
|
||||||
|
|
||||||
// Message implement the sdk.Msg interface:
|
// An update that has been submitted to the blockchain, but not yet acted on.
|
||||||
|
type SubmittedUpdate {
|
||||||
|
Update
|
||||||
|
executionDate int64 // BlockHeight
|
||||||
|
}
|
||||||
|
|
||||||
// type Msg interface {
|
/* MESSAGE TYPES */
|
||||||
|
/*
|
||||||
|
Message implement the sdk.Msg interface:
|
||||||
|
type Msg interface {
|
||||||
|
|
||||||
// // Return the message type.
|
// Return the message type.
|
||||||
// // Must be alphanumeric or empty.
|
// Must be alphanumeric or empty.
|
||||||
// Type() string
|
Type() string
|
||||||
|
|
||||||
// // Get the canonical byte representation of the Msg.
|
// Get the canonical byte representation of the Msg.
|
||||||
// GetSignBytes() []byte
|
GetSignBytes() []byte
|
||||||
|
|
||||||
// // ValidateBasic does a simple validation check that
|
// ValidateBasic does a simple validation check that
|
||||||
// // doesn't require access to any other information.
|
// doesn't require access to any other information.
|
||||||
// ValidateBasic() Error
|
ValidateBasic() Error
|
||||||
|
|
||||||
// // Signers returns the addrs of signers that must sign.
|
// Signers returns the addrs of signers that must sign.
|
||||||
// // CONTRACT: All signatures must be present to be valid.
|
// CONTRACT: All signatures must be present to be valid.
|
||||||
// // CONTRACT: Returns addrs in some deterministic order.
|
// CONTRACT: Returns addrs in some deterministic order.
|
||||||
// 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
|
Participants [2]sdk.AccAddress
|
||||||
Sender sdk.Address
|
Coins sdk.Coins
|
||||||
Receiver sdk.Address
|
|
||||||
Amount sdk.Coins
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new message.
|
//Create a new message.
|
||||||
// Called in client code when constructing transaction from cli args to send to the network.
|
/*
|
||||||
// maybe just a placeholder for more advanced future functionality?
|
Called in client code when constructing transaction from cli args to send to the network.
|
||||||
// func (msg CreatMsg) NewMsgCreate(sender sdk.Address, receiver sdk.Address, amount sdk.Coins) MsgCreate {
|
maybe just a placeholder for more advanced future functionality?
|
||||||
// return MsgCreate{
|
func (msg CreatMsg) NewMsgCreate(sender sdk.Address, receiver sdk.Address, amount sdk.Coins) MsgCreate {
|
||||||
// sender
|
return MsgCreate{
|
||||||
// receiver
|
sender
|
||||||
// amount
|
receiver
|
||||||
// }
|
amount
|
||||||
// }
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
func (msg MsgCreate) Type() string { return "paychan" }
|
func (msg MsgCreate) Type() string { return "paychan" }
|
||||||
|
|
||||||
func (msg MsgCreate) GetSignBytes() []byte {
|
func (msg MsgCreate) GetSignBytes() []byte {
|
||||||
// TODO create msgCdc in wire.go
|
// TODO create msgCdc in wire.go
|
||||||
b, err := msgCdc.MarshalJSON(struct {
|
bz, err := msgCdc.Marshal(msg)
|
||||||
SenderAddr string `json:"sender_addr"`
|
|
||||||
ReceiverAddr string `json:"receiver_addr"`
|
|
||||||
Amount sdk.Coins `json:"amount"`
|
|
||||||
}{
|
|
||||||
SenderAddr: sdk.MustBech32ifyAcc(msg.Sender),
|
|
||||||
ReceiverAddr: sdk.MustBech32ifyAcc(msg.Receiver),
|
|
||||||
Amount: msg.Amount,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return b
|
return MustSortJSON(bz)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg MsgCreate) ValidateBasic() sdk.Error {
|
func (msg MsgCreate) ValidateBasic() sdk.Error {
|
||||||
// Validate msg as an optimisation to avoid all validation going to keeper. It's run before the sigs are checked by the auth module.
|
// Validate msg as an optimisation to avoid all validation going to keeper. It's run before the sigs are checked by the auth module.
|
||||||
// Validate without external information (such as account balance)
|
// Validate without external information (such as account balance)
|
||||||
|
|
||||||
|
//TODO implement
|
||||||
|
|
||||||
|
/*
|
||||||
// check if all fields present / not 0 valued
|
// check if all fields present / not 0 valued
|
||||||
if len(msg.Sender) == 0 {
|
if len(msg.Sender) == 0 {
|
||||||
return sdk.ErrInvalidAddress(msg.Sender.String())
|
return sdk.ErrInvalidAddress(msg.Sender.String())
|
||||||
@ -98,55 +108,42 @@ 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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg MsgCreate) GetSigners() []sdk.Address {
|
func (msg MsgCreate) GetSigners() []sdk.Address {
|
||||||
// Only sender must sign to create a paychan
|
// Only sender must sign to create a paychan
|
||||||
return []sdk.Address{msg.Sender}
|
return []sdk.AccAddress{msg.Participants[0]} // select sender address
|
||||||
}
|
}
|
||||||
|
|
||||||
// A message to close a payment channel.
|
// A message to close a payment channel.
|
||||||
type MsgClose struct {
|
type MsgSubmitUpdate struct {
|
||||||
// have to include sender and receiver in msg explicitly (rather than just universal paychanID)
|
Update
|
||||||
// this gives ability to verify signatures with no external information
|
// might need a "signer" to be able to say who is signing this as either can or not
|
||||||
Sender sdk.Address
|
|
||||||
Receiver sdk.Address
|
|
||||||
Id int64 // TODO is another int type better?
|
|
||||||
ReceiverAmount sdk.Coins // amount the receiver should get - sender amount implicit with paychan balance
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (msg MsgClose) NewMsgClose(sender sdk.Address, receiver sdk.Address, id integer, receiverAmount sdk.Coins) MsgClose {
|
// func (msg MsgSubmitUpdate) NewMsgSubmitUpdate(update Update) MsgSubmitUpdate {
|
||||||
// return MsgClose{
|
// return MsgSubmitUpdate{
|
||||||
// sender
|
// update
|
||||||
// receiver
|
|
||||||
// id
|
|
||||||
// receiverAmount
|
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func (msg MsgClose) Type() string { return "paychan" }
|
func (msg MsgSubmitUpdate) Type() string { return "paychan" }
|
||||||
|
|
||||||
func (msg MsgClose) GetSignBytes() []byte {
|
func (msg MsgSubmitUpdate) GetSignBytes() []byte {
|
||||||
// TODO create msgCdc in wire.go
|
// TODO create msgCdc in wire.go
|
||||||
b, err := msgCdc.MarshalJSON(struct {
|
bz, err := msgCdc.Marshal(msg)
|
||||||
SenderAddr string `json:"sender_addr"`
|
|
||||||
ReceiverAddr string `json:"receiver_addr"`
|
|
||||||
Id int64 `json:"id"`
|
|
||||||
ReceiverAmount sdk.Coins `json:"receiver_amount"`
|
|
||||||
}{
|
|
||||||
SenderAddr: sdk.MustBech32ifyAcc(msg.Sender),
|
|
||||||
ReceiverAddr: sdk.MustBech32ifyAcc(msg.Receiver),
|
|
||||||
Id: msg.Id,
|
|
||||||
ReceiverAmount: msg.ReceiverAmount,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return b
|
return MustSortJSON(bz)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg MsgClose) ValidateBasic() sdk.Error {
|
func (msg MsgSubmitUpdate) ValidateBasic() sdk.Error {
|
||||||
|
|
||||||
|
// TODO implement
|
||||||
|
/*
|
||||||
// check if all fields present / not 0 valued
|
// check if all fields present / not 0 valued
|
||||||
if len(msg.Sender) == 0 {
|
if len(msg.Sender) == 0 {
|
||||||
return sdk.ErrInvalidAddress(msg.Sender.String())
|
return sdk.ErrInvalidAddress(msg.Sender.String())
|
||||||
@ -169,10 +166,12 @@ 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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg MsgClose) GetSigners() []sdk.Address {
|
func (msg MsgSubmitUpdate) GetSigners() []sdk.Address {
|
||||||
// Both sender and receiver must sign in order to close a channel
|
// Signing not strictly necessary as signatures contained within the channel update.
|
||||||
return []sdk.Address{msg.Sender, msg.Receiver}
|
// TODO add signature by submitting address
|
||||||
|
return []sdk.Address{}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"github.com/cosmos/cosmos-sdk/wire"
|
"github.com/cosmos/cosmos-sdk/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
func RegisterWire(cdc *wire.Codec) {
|
func RegisterWire(cdc *wire.Codec) {
|
||||||
cdc.RegisterConcrete(MsgCreate{}, "paychan/MsgCreate", nil)
|
cdc.RegisterConcrete(MsgCreate{}, "paychan/MsgCreate", nil)
|
||||||
cdc.RegisterConcrete(MsgClose{}, "paychan/MsgClose", nil)
|
cdc.RegisterConcrete(MsgClose{}, "paychan/MsgClose", nil)
|
||||||
@ -16,3 +17,4 @@ func init() {
|
|||||||
// TODO is this needed?
|
// TODO is this needed?
|
||||||
//wire.RegisterCrypto(msgCdc)
|
//wire.RegisterCrypto(msgCdc)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user