Wrote bulk of ibc post packet middleware

This commit is contained in:
Ethan Frey 2017-07-17 21:52:02 +02:00
parent 1fc222e449
commit 30eced21c5
1 changed files with 75 additions and 2 deletions

View File

@ -1,6 +1,8 @@
package ibc
import (
"errors"
"github.com/tendermint/basecoin"
"github.com/tendermint/basecoin/stack"
"github.com/tendermint/basecoin/state"
@ -27,11 +29,82 @@ func (Middleware) Name() string {
// 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
// if it is not a PostPacket, just let it go through
post, ok := tx.Unwrap().(PostPacketTx)
if !ok {
return next.CheckTx(ctx, store, tx)
}
// parse this packet and get the ibc-enhanced tx and context
ictx, itx, err := m.verifyPost(ctx, store, post)
if err != nil {
return res, err
}
return next.CheckTx(ictx, store, itx)
}
// 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
// if it is not a PostPacket, just let it go through
post, ok := tx.Unwrap().(PostPacketTx)
if !ok {
return next.DeliverTx(ctx, store, tx)
}
// parse this packet and get the ibc-enhanced tx and context
ictx, itx, err := m.verifyPost(ctx, store, post)
if err != nil {
return res, err
}
return next.DeliverTx(ictx, store, itx)
}
// verifyPost accepts a message bound for this chain...
// TODO: think about relay
func (m Middleware) verifyPost(ctx basecoin.Context, store state.KVStore,
tx PostPacketTx) (ictx basecoin.Context, itx basecoin.Tx, err error) {
// make sure the chain is registered
from := tx.FromChainID
if !NewChainSet(store).Exists([]byte(from)) {
err = ErrNotRegistered(from)
return
}
// make sure this sequence number is the next in the list
q := InputQueue(store, from)
packet := tx.Packet
if q.Tail() != packet.Sequence {
err = errors.New("Incorrect sequence number - out of order") // TODO
return
}
// look up the referenced header
space := stack.PrefixedStore(from, store)
provider := newDBProvider(space)
// TODO: GetExactHeight helper?
seed, err := provider.GetByHeight(int(tx.FromChainHeight))
if err != nil {
return ictx, itx, err
}
if seed.Height() != int(tx.FromChainHeight) {
err = errors.New("no such height") // TODO
return
}
// verify the merkle hash....
root := seed.Header.AppHash
key := []byte("?????") // TODO!
tx.Proof.Verify(key, packet.Bytes(), root)
// TODO: verify packet.Permissions
// add to input queue
q.Push(packet.Bytes())
// return the wrapped tx along with the extra permissions
ictx = ictx.WithPermissions(packet.Permissions...)
itx = packet.Tx
return
}