Started on ibc module tx, types
This commit is contained in:
parent
88781593bb
commit
697c2f1e04
|
@ -0,0 +1 @@
|
||||||
|
package ibc
|
|
@ -0,0 +1,40 @@
|
||||||
|
package ibc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/tendermint/basecoin"
|
||||||
|
"github.com/tendermint/basecoin/state"
|
||||||
|
)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
const (
|
||||||
|
NameIBC = "ibc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Handler allows us to update the chain state or create a packet
|
||||||
|
type Handler struct {
|
||||||
|
basecoin.NopOption
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ basecoin.Handler = Handler{}
|
||||||
|
|
||||||
|
// NewHandler makes a role handler to create roles
|
||||||
|
func NewHandler() Handler {
|
||||||
|
return Handler{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name - return name space
|
||||||
|
func (Handler) Name() string {
|
||||||
|
return NameIBC
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckTx verifies the packet is formated correctly, and has the proper sequence
|
||||||
|
// for a registered chain
|
||||||
|
func (h Handler) CheckTx(ctx basecoin.Context, store state.KVStore, tx basecoin.Tx) (res basecoin.Result, err error) {
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeliverTx verifies all signatures on the tx and updated the chain state
|
||||||
|
// apropriately
|
||||||
|
func (h Handler) DeliverTx(ctx basecoin.Context, store state.KVStore, tx basecoin.Tx) (res basecoin.Result, err error) {
|
||||||
|
return res, nil
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package ibc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/tendermint/basecoin"
|
||||||
|
"github.com/tendermint/basecoin/stack"
|
||||||
|
"github.com/tendermint/basecoin/state"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Middleware allows us to verify the IBC proof on a packet and
|
||||||
|
// and if valid, attach this permission to the wrapped packet
|
||||||
|
type Middleware struct {
|
||||||
|
stack.PassOption
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ stack.Middleware = Middleware{}
|
||||||
|
|
||||||
|
// NewMiddleware creates a role-checking middleware
|
||||||
|
func NewMiddleware() Middleware {
|
||||||
|
return Middleware{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name - return name space
|
||||||
|
func (Middleware) Name() string {
|
||||||
|
return NameIBC
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckTx verifies the named chain and height is present, and verifies
|
||||||
|
// the merkle proof in the packet
|
||||||
|
func (m Middleware) CheckTx(ctx basecoin.Context, store state.KVStore, tx basecoin.Tx, next basecoin.Checker) (res basecoin.Result, err error) {
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeliverTx verifies the named chain and height is present, and verifies
|
||||||
|
// the merkle proof in the packet
|
||||||
|
func (m Middleware) DeliverTx(ctx basecoin.Context, store state.KVStore, tx basecoin.Tx, next basecoin.Deliver) (res basecoin.Result, err error) {
|
||||||
|
return res, nil
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package ibc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/tendermint/light-client/certifiers"
|
||||||
|
|
||||||
|
"github.com/tendermint/basecoin/stack"
|
||||||
|
"github.com/tendermint/basecoin/state"
|
||||||
|
)
|
||||||
|
|
||||||
|
// newCertifier loads up the current state of this chain to make a proper
|
||||||
|
func newCertifier(chainID string, store state.KVStore) (*certifiers.InquiringCertifier, error) {
|
||||||
|
// each chain has their own prefixed subspace
|
||||||
|
space := stack.PrefixedStore(chainID, store)
|
||||||
|
p := dbProvider{space}
|
||||||
|
|
||||||
|
// this gets the most recent verified seed
|
||||||
|
seed, err := certifiers.LatestSeed(p)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// we have no source for untrusted keys, but use the db to load trusted history
|
||||||
|
cert := certifiers.NewInquiring(chainID, seed.Validators, p,
|
||||||
|
certifiers.MissingProvider{})
|
||||||
|
return cert, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// dbProvider wraps our kv store so it integrates with light-client verification
|
||||||
|
type dbProvider struct {
|
||||||
|
store state.KVStore
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ certifiers.Provider = dbProvider{}
|
||||||
|
|
||||||
|
func (d dbProvider) StoreSeed(seed certifiers.Seed) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d dbProvider) GetByHeight(h int) (certifiers.Seed, error) {
|
||||||
|
return certifiers.Seed{}, certifiers.ErrSeedNotFound()
|
||||||
|
}
|
||||||
|
func (d dbProvider) GetByHash(hash []byte) (certifiers.Seed, error) {
|
||||||
|
return certifiers.Seed{}, certifiers.ErrSeedNotFound()
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
package ibc
|
|
@ -0,0 +1,152 @@
|
||||||
|
package ibc
|
||||||
|
|
||||||
|
import (
|
||||||
|
abci "github.com/tendermint/abci/types"
|
||||||
|
"github.com/tendermint/light-client/certifiers"
|
||||||
|
merkle "github.com/tendermint/merkleeyes/iavl"
|
||||||
|
|
||||||
|
"github.com/tendermint/basecoin"
|
||||||
|
"github.com/tendermint/basecoin/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
const (
|
||||||
|
// 0x3? series for ibc
|
||||||
|
ByteRegisterChain = byte(0x30)
|
||||||
|
ByteUpdateChain = byte(0x31)
|
||||||
|
BytePacketCreate = byte(0x32)
|
||||||
|
BytePacketPost = byte(0x33)
|
||||||
|
|
||||||
|
TypeRegisterChain = NameIBC + "/register"
|
||||||
|
TypeUpdateChain = NameIBC + "/update"
|
||||||
|
TypePacketCreate = NameIBC + "/create"
|
||||||
|
TypePacketPost = NameIBC + "/post"
|
||||||
|
|
||||||
|
IBCCodeEncodingError = abci.CodeType(1001)
|
||||||
|
IBCCodeChainAlreadyExists = abci.CodeType(1002)
|
||||||
|
IBCCodePacketAlreadyExists = abci.CodeType(1003)
|
||||||
|
IBCCodeUnknownHeight = abci.CodeType(1004)
|
||||||
|
IBCCodeInvalidCommit = abci.CodeType(1005)
|
||||||
|
IBCCodeInvalidProof = abci.CodeType(1006)
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
basecoin.TxMapper.
|
||||||
|
RegisterImplementation(RegisterChainTx{}, TypeRegisterChain, ByteRegisterChain).
|
||||||
|
RegisterImplementation(UpdateChainTx{}, TypeUpdateChain, ByteUpdateChain).
|
||||||
|
RegisterImplementation(PacketCreateTx{}, TypePacketCreate, BytePacketCreate).
|
||||||
|
RegisterImplementation(PacketPostTx{}, TypePacketPost, BytePacketPost)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterChainTx allows you to register a new chain on this blockchain
|
||||||
|
type RegisterChainTx struct {
|
||||||
|
Seed certifiers.Seed `json:"seed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainID helps get the chain this tx refers to
|
||||||
|
func (r RegisterChainTx) ChainID() string {
|
||||||
|
return r.Seed.Header.ChainID
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateBasic makes sure this is consistent, without checking the sigs
|
||||||
|
func (r RegisterChainTx) ValidateBasic() error {
|
||||||
|
return r.Seed.ValidateBasic(r.ChainID())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap - used to satisfy TxInner
|
||||||
|
func (r RegisterChainTx) Wrap() basecoin.Tx {
|
||||||
|
return basecoin.Tx{r}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateChainTx updates the state of this chain
|
||||||
|
type UpdateChainTx struct {
|
||||||
|
Seed certifiers.Seed `json:"seed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainID helps get the chain this tx refers to
|
||||||
|
func (u UpdateChainTx) ChainID() string {
|
||||||
|
return u.Seed.Header.ChainID
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateBasic makes sure this is consistent, without checking the sigs
|
||||||
|
func (u UpdateChainTx) ValidateBasic() error {
|
||||||
|
return u.Seed.ValidateBasic(u.ChainID())
|
||||||
|
}
|
||||||
|
|
||||||
|
// PacketCreateTx is meant to be called by IPC, another module...
|
||||||
|
//
|
||||||
|
// this is the tx that will be sent to another app and the permissions it
|
||||||
|
// comes with (which must be a subset of the permissions on the current tx)
|
||||||
|
//
|
||||||
|
// TODO: how to control who can create packets (can I just signed create packet?)
|
||||||
|
type PacketCreateTx struct {
|
||||||
|
DestChain string `json:"dest_chain"`
|
||||||
|
Permissions []basecoin.Actor `json:"permissions"`
|
||||||
|
Tx basecoin.Tx `json:"tx"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateBasic makes sure this is consistent - used to satisfy TxInner
|
||||||
|
func (p PacketCreateTx) ValidateBasic() error {
|
||||||
|
if p.DestChain == "" {
|
||||||
|
return errors.ErrNoChain()
|
||||||
|
}
|
||||||
|
// if len(p.Permissions) == 0 {
|
||||||
|
// return ErrNoPermissions()
|
||||||
|
// }
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap - used to satisfy TxInner
|
||||||
|
func (p PacketCreateTx) Wrap() basecoin.Tx {
|
||||||
|
return basecoin.Tx{p}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PacketPostTx takes a wrapped packet from another chain and
|
||||||
|
// TODO!!!
|
||||||
|
type PacketPostTx struct {
|
||||||
|
FromChainID string // The immediate source of the packet, not always Packet.SrcChainID
|
||||||
|
FromChainHeight uint64 // The block height in which Packet was committed, to check Proof
|
||||||
|
Proof *merkle.IAVLProof
|
||||||
|
// Packet
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateBasic makes sure this is consistent - used to satisfy TxInner
|
||||||
|
func (p PacketPostTx) ValidateBasic() error {
|
||||||
|
// TODO
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap - used to satisfy TxInner
|
||||||
|
func (p PacketPostTx) Wrap() basecoin.Tx {
|
||||||
|
return basecoin.Tx{p}
|
||||||
|
}
|
||||||
|
|
||||||
|
// proof := tx.Proof
|
||||||
|
// if proof == nil {
|
||||||
|
// sm.res.Code = IBCCodeInvalidProof
|
||||||
|
// sm.res.Log = "Proof is nil"
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// packetBytes := wire.BinaryBytes(packet)
|
||||||
|
|
||||||
|
// // Make sure packet's proof matches given (packet, key, blockhash)
|
||||||
|
// ok := proof.Verify(packetKeyEgress, packetBytes, header.AppHash)
|
||||||
|
// if !ok {
|
||||||
|
// sm.res.Code = IBCCodeInvalidProof
|
||||||
|
// sm.res.Log = fmt.Sprintf("Proof is invalid. key: %s; packetByes %X; header %v; proof %v", packetKeyEgress, packetBytes, header, proof)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Execute payload
|
||||||
|
// switch payload := packet.Payload.(type) {
|
||||||
|
// case DataPayload:
|
||||||
|
// // do nothing
|
||||||
|
// case CoinsPayload:
|
||||||
|
// // Add coins to destination account
|
||||||
|
// acc := types.GetAccount(sm.store, payload.Address)
|
||||||
|
// if acc == nil {
|
||||||
|
// acc = &types.Account{}
|
||||||
|
// }
|
||||||
|
// acc.Balance = acc.Balance.Plus(payload.Coins)
|
||||||
|
// types.SetAccount(sm.store, payload.Address, acc)
|
||||||
|
// }
|
Loading…
Reference in New Issue