Fill remaining IBC run* methods

This commit is contained in:
Jae Kwon 2017-01-29 19:54:38 -08:00
parent a5eefe12fa
commit 530694f93c
2 changed files with 123 additions and 12 deletions

View File

@ -21,6 +21,7 @@ const (
_STATE = "state"
_HEADER = "header"
_EGRESS = "egress"
_INGRESS = "ingress"
_CONNECTION = "connection"
)
@ -29,6 +30,7 @@ type IBCPluginState struct {
// @[:ibc, :blockchain, :state, ChainID] <~ BlockchainState
// @[:ibc, :blockchain, :header, ChainID, Height] <~ tm.Header
// @[:ibc, :egress, Src, Dst, Sequence] <~ Packet
// @[:ibc, :ingress, Dst, Src, Sequence] <~ Packet
// @[:ibc, :connection, Src, Dst] <~ Connection # TODO - keep connection state
}
@ -60,8 +62,11 @@ const (
IBCTxTypePacketCreate = byte(0x03)
IBCTxTypePacketPost = byte(0x04)
IBCCodeEncodingError = abci.CodeType(1001)
IBCCodeChainAlreadyExists = abci.CodeType(1002)
IBCCodeEncodingError = abci.CodeType(1001)
IBCCodeChainAlreadyExists = abci.CodeType(1002)
IBCCodePacketAlreadyExists = abci.CodeType(1003)
IBCCodeUnknownHeight = abci.CodeType(1004)
IBCCodeInvalidProof = abci.CodeType(1005)
)
var _ = wire.RegisterInterface(
@ -277,15 +282,85 @@ func (sm *IBCStateMachine) runUpdateChainTx(tx IBCUpdateChainTx) {
}
func (sm *IBCStateMachine) runPacketCreateTx(tx IBCPacketCreateTx) {
// TODO Store packet in egress
packet := tx.Packet
packetKey := toKey(_IBC, _EGRESS,
packet.SrcChainID,
packet.DstChainID,
cmn.Fmt("%v", packet.Sequence),
)
// Make sure packet doesn't already exist
if exists(sm.store, packetKey) {
sm.res.Code = IBCCodePacketAlreadyExists
sm.res.AppendLog("Already exists")
return
}
// Save new Packet
save(sm.store, packetKey, wire.BinaryBytes(packet))
}
func (sm *IBCStateMachine) runPacketPostTx(tx IBCPacketPostTx) {
// TODO Make sure packat doesn't already exist
// TODO Load associated blockHash and make sure it exists
// TODO compute packet key
// TODO Make sure packet's proof matches given (packet, key, blockhash)
// TODO Store packet
packet := tx.Packet
packetKeyEgress := toKey(_IBC, _EGRESS,
packet.SrcChainID,
packet.DstChainID,
cmn.Fmt("%v", packet.Sequence),
)
packetKeyIngress := toKey(_IBC, _INGRESS,
packet.DstChainID,
packet.SrcChainID,
cmn.Fmt("%v", packet.Sequence),
)
headerKey := toKey(_IBC, _BLOCKCHAIN, _HEADER,
tx.FromChainID,
cmn.Fmt("%v", tx.FromChainHeight),
)
// Make sure packet doesn't already exist
if exists(sm.store, packetKeyIngress) {
sm.res.Code = IBCCodePacketAlreadyExists
sm.res.AppendLog("Already exists")
return
}
// Save new Packet
save(sm.store, packetKeyIngress, wire.BinaryBytes(packet))
// Load Header and make sure it exists
var header tm.Header
exists, err := load(sm.store, headerKey, &header)
if err != nil {
sm.res = abci.ErrInternalError.AppendLog(cmn.Fmt("Loading Header: %v", err.Error()))
return
}
if !exists {
sm.res.Code = IBCCodeUnknownHeight
sm.res.AppendLog(cmn.Fmt("Loading Header: %v", err.Error()))
return
}
/*
// Read Proof
var proof *merkle.IAVLProof
err = wire.ReadBinaryBytes(tx.Proof, &proof)
if err != nil {
sm.res.Code = IBCEncodingError
sm.res.AppendLog(cmn.Fmt("Reading Proof: %v", err.Error()))
return
}
*/
proof := tx.Proof
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.AppendLog("Proof is invalid")
return
}
return
}
func (ibc *IBCPlugin) InitChain(store types.KVStore, vals []*abci.Validator) {

View File

@ -5,10 +5,12 @@ import (
"testing"
"github.com/stretchr/testify/assert"
abci "github.com/tendermint/abci/types"
"github.com/tendermint/basecoin/testutils"
"github.com/tendermint/basecoin/types"
cmn "github.com/tendermint/go-common"
"github.com/tendermint/go-wire"
eyes "github.com/tendermint/merkleeyes/client"
tm "github.com/tendermint/tendermint/types"
)
@ -36,7 +38,8 @@ func genGenesisDoc(chainID string, numVals int) (*tm.GenesisDoc, []*tm.Validator
func TestIBCPlugin(t *testing.T) {
store := types.NewKVCache(nil)
tree := eyes.NewLocalClient("", 0)
store := types.NewKVCache(tree)
store.SetLogging() // Log all activity
ibcPlugin := New()
@ -68,7 +71,7 @@ func TestIBCPlugin(t *testing.T) {
Genesis: string(genDocJSON_1),
},
}}))
assert.True(t, res.IsOK(), res)
assert.True(t, res.IsOK(), res.Log)
t.Log(">>", strings.Join(store.GetLogLines(), "\n"))
store.ClearLogLines()
@ -79,9 +82,42 @@ func TestIBCPlugin(t *testing.T) {
Genesis: string(genDocJSON_1),
},
}}))
assert.Equal(t, res.Code, IBCCodeChainAlreadyExists, res)
assert.Equal(t, res.Code, IBCCodeChainAlreadyExists, res.Log)
t.Log(">>", strings.Join(store.GetLogLines(), "\n"))
store.ClearLogLines()
t.Log(">>", vals_1)
// Create a new packet (for testing)
res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{
Packet{
SrcChainID: "test_chain",
DstChainID: "dst_chain",
Sequence: 0,
Type: "data",
Payload: []byte("hello world"),
},
}}))
assert.Equal(t, res.Code, abci.CodeType(0), res.Log)
t.Log(">>", strings.Join(store.GetLogLines(), "\n"))
store.ClearLogLines()
// Post a duplicate packet
res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{
Packet{
SrcChainID: "test_chain",
DstChainID: "dst_chain",
Sequence: 0,
Type: "data",
Payload: []byte("hello world"),
},
}}))
assert.Equal(t, res.Code, IBCCodePacketAlreadyExists, res.Log)
t.Log(">>", strings.Join(store.GetLogLines(), "\n"))
store.ClearLogLines()
// Update a chain
//header, commit :=
store.Sync()
resCommit := tree.CommitSync()
t.Log(">>", vals_1, tree, resCommit.Data)
}