Add test for bad proof
This commit is contained in:
+8
-3
@@ -121,7 +121,7 @@ type IBCPacketPostTx 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
|
||||
Packet
|
||||
Proof merkle.IAVLProof
|
||||
Proof *merkle.IAVLProof
|
||||
}
|
||||
|
||||
func (IBCPacketPostTx) ValidateBasic() (res abci.Result) {
|
||||
@@ -298,7 +298,7 @@ func (sm *IBCStateMachine) runPacketCreateTx(tx IBCPacketCreateTx) {
|
||||
return
|
||||
}
|
||||
// Save new Packet
|
||||
save(sm.store, packetKey, wire.BinaryBytes(packet))
|
||||
save(sm.store, packetKey, packet)
|
||||
}
|
||||
|
||||
func (sm *IBCStateMachine) runPacketPostTx(tx IBCPacketPostTx) {
|
||||
@@ -326,7 +326,7 @@ func (sm *IBCStateMachine) runPacketPostTx(tx IBCPacketPostTx) {
|
||||
}
|
||||
|
||||
// Save new Packet
|
||||
save(sm.store, packetKeyIngress, wire.BinaryBytes(packet))
|
||||
save(sm.store, packetKeyIngress, packet)
|
||||
|
||||
// Load Header and make sure it exists
|
||||
var header tm.Header
|
||||
@@ -352,6 +352,11 @@ func (sm *IBCStateMachine) runPacketPostTx(tx IBCPacketPostTx) {
|
||||
}
|
||||
*/
|
||||
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)
|
||||
|
||||
+158
-19
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/tendermint/basecoin/types"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-merkle"
|
||||
"github.com/tendermint/go-wire"
|
||||
eyes "github.com/tendermint/merkleeyes/client"
|
||||
tm "github.com/tendermint/tendermint/types"
|
||||
@@ -66,8 +67,8 @@ func (pas PrivAccountsByAddress) Swap(i, j int) {
|
||||
|
||||
func TestIBCPlugin(t *testing.T) {
|
||||
|
||||
tree := eyes.NewLocalClient("", 0)
|
||||
store := types.NewKVCache(tree)
|
||||
eyesClient := eyes.NewLocalClient("", 0)
|
||||
store := types.NewKVCache(eyesClient)
|
||||
store.SetLogging() // Log all activity
|
||||
|
||||
ibcPlugin := New()
|
||||
@@ -115,14 +116,15 @@ func TestIBCPlugin(t *testing.T) {
|
||||
store.ClearLogLines()
|
||||
|
||||
// Create a new packet (for testing)
|
||||
packet := Packet{
|
||||
SrcChainID: "test_chain",
|
||||
DstChainID: "dst_chain",
|
||||
Sequence: 0,
|
||||
Type: "data",
|
||||
Payload: []byte("hello world"),
|
||||
}
|
||||
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"),
|
||||
},
|
||||
Packet: packet,
|
||||
}}))
|
||||
assert.Equal(t, abci.CodeType_OK, res.Code, res.Log)
|
||||
t.Log(">>", strings.Join(store.GetLogLines(), "\n"))
|
||||
@@ -130,13 +132,7 @@ func TestIBCPlugin(t *testing.T) {
|
||||
|
||||
// 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"),
|
||||
},
|
||||
Packet: packet,
|
||||
}}))
|
||||
assert.Equal(t, IBCCodePacketAlreadyExists, res.Code, res.Log)
|
||||
t.Log(">>", strings.Join(store.GetLogLines(), "\n"))
|
||||
@@ -144,7 +140,7 @@ func TestIBCPlugin(t *testing.T) {
|
||||
|
||||
// Construct a Header that includes the above packet.
|
||||
store.Sync()
|
||||
resCommit := tree.CommitSync()
|
||||
resCommit := eyesClient.CommitSync()
|
||||
appHash := resCommit.Data
|
||||
header := tm.Header{
|
||||
ChainID: "test_chain",
|
||||
@@ -183,12 +179,39 @@ func TestIBCPlugin(t *testing.T) {
|
||||
assert.Equal(t, abci.CodeType_OK, res.Code, res.Log)
|
||||
t.Log(">>", strings.Join(store.GetLogLines(), "\n"))
|
||||
store.ClearLogLines()
|
||||
|
||||
// Get proof for the packet
|
||||
packetKey := toKey(_IBC, _EGRESS,
|
||||
packet.SrcChainID,
|
||||
packet.DstChainID,
|
||||
cmn.Fmt("%v", packet.Sequence),
|
||||
)
|
||||
resQuery, err := eyesClient.QuerySync(abci.RequestQuery{
|
||||
Path: "/store",
|
||||
Data: packetKey,
|
||||
Prove: true,
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
var proof *merkle.IAVLProof
|
||||
err = wire.ReadBinaryBytes(resQuery.Proof, &proof)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Post a packet
|
||||
res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketPostTx{
|
||||
FromChainID: "test_chain",
|
||||
FromChainHeight: 999,
|
||||
Packet: packet,
|
||||
Proof: proof,
|
||||
}}))
|
||||
assert.Equal(t, abci.CodeType_OK, res.Code, res.Log)
|
||||
t.Log(">>", strings.Join(store.GetLogLines(), "\n"))
|
||||
store.ClearLogLines()
|
||||
}
|
||||
|
||||
func TestIBCPluginBadCommit(t *testing.T) {
|
||||
|
||||
tree := eyes.NewLocalClient("", 0)
|
||||
store := types.NewKVCache(tree)
|
||||
eyesClient := eyes.NewLocalClient("", 0)
|
||||
store := types.NewKVCache(eyesClient)
|
||||
store.SetLogging() // Log all activity
|
||||
|
||||
ibcPlugin := New()
|
||||
@@ -256,3 +279,119 @@ func TestIBCPluginBadCommit(t *testing.T) {
|
||||
store.ClearLogLines()
|
||||
|
||||
}
|
||||
|
||||
func TestIBCPluginBadProof(t *testing.T) {
|
||||
|
||||
eyesClient := eyes.NewLocalClient("", 0)
|
||||
store := types.NewKVCache(eyesClient)
|
||||
store.SetLogging() // Log all activity
|
||||
|
||||
ibcPlugin := New()
|
||||
ctx := types.CallContext{
|
||||
CallerAddress: nil,
|
||||
CallerAccount: nil,
|
||||
Coins: types.Coins{},
|
||||
}
|
||||
|
||||
chainID_1 := "test_chain"
|
||||
genDoc_1, privAccs_1 := genGenesisDoc(chainID_1, 4)
|
||||
genDocJSON_1 := wire.JSONBytesPretty(genDoc_1)
|
||||
|
||||
// Successfully register a chain
|
||||
res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCRegisterChainTx{
|
||||
BlockchainGenesis{
|
||||
ChainID: "test_chain",
|
||||
Genesis: string(genDocJSON_1),
|
||||
},
|
||||
}}))
|
||||
assert.True(t, res.IsOK(), res.Log)
|
||||
t.Log(">>", strings.Join(store.GetLogLines(), "\n"))
|
||||
store.ClearLogLines()
|
||||
|
||||
// Create a new packet (for testing)
|
||||
packet := Packet{
|
||||
SrcChainID: "test_chain",
|
||||
DstChainID: "dst_chain",
|
||||
Sequence: 0,
|
||||
Type: "data",
|
||||
Payload: []byte("hello world"),
|
||||
}
|
||||
res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{
|
||||
Packet: packet,
|
||||
}}))
|
||||
assert.Equal(t, abci.CodeType_OK, res.Code, res.Log)
|
||||
t.Log(">>", strings.Join(store.GetLogLines(), "\n"))
|
||||
store.ClearLogLines()
|
||||
|
||||
// Construct a Header that includes the above packet.
|
||||
store.Sync()
|
||||
resCommit := eyesClient.CommitSync()
|
||||
appHash := resCommit.Data
|
||||
header := tm.Header{
|
||||
ChainID: "test_chain",
|
||||
Height: 999,
|
||||
AppHash: appHash,
|
||||
ValidatorsHash: []byte("must_exist"), // TODO make optional
|
||||
}
|
||||
|
||||
// Construct a Commit that signs above header
|
||||
blockHash := header.Hash()
|
||||
blockID := tm.BlockID{Hash: blockHash}
|
||||
commit := tm.Commit{
|
||||
BlockID: blockID,
|
||||
Precommits: make([]*tm.Vote, len(privAccs_1)),
|
||||
}
|
||||
for i, privAcc := range privAccs_1 {
|
||||
vote := &tm.Vote{
|
||||
ValidatorAddress: privAcc.Account.PubKey.Address(),
|
||||
ValidatorIndex: i,
|
||||
Height: 999,
|
||||
Round: 0,
|
||||
Type: tm.VoteTypePrecommit,
|
||||
BlockID: tm.BlockID{Hash: blockHash},
|
||||
}
|
||||
vote.Signature = privAcc.PrivKey.Sign(
|
||||
tm.SignBytes("test_chain", vote),
|
||||
)
|
||||
commit.Precommits[i] = vote
|
||||
}
|
||||
|
||||
// Update a chain
|
||||
res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCUpdateChainTx{
|
||||
Header: header,
|
||||
Commit: commit,
|
||||
}}))
|
||||
assert.Equal(t, abci.CodeType_OK, res.Code, res.Log)
|
||||
t.Log(">>", strings.Join(store.GetLogLines(), "\n"))
|
||||
store.ClearLogLines()
|
||||
|
||||
// Get proof for the packet
|
||||
packetKey := toKey(_IBC, _EGRESS,
|
||||
packet.SrcChainID,
|
||||
packet.DstChainID,
|
||||
cmn.Fmt("%v", packet.Sequence),
|
||||
)
|
||||
resQuery, err := eyesClient.QuerySync(abci.RequestQuery{
|
||||
Path: "/store",
|
||||
Data: packetKey,
|
||||
Prove: true,
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
var proof *merkle.IAVLProof
|
||||
err = wire.ReadBinaryBytes(resQuery.Proof, &proof)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Mutate the proof
|
||||
proof.InnerNodes[0].Height += 1
|
||||
|
||||
// Post a packet
|
||||
res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketPostTx{
|
||||
FromChainID: "test_chain",
|
||||
FromChainHeight: 999,
|
||||
Packet: packet,
|
||||
Proof: proof,
|
||||
}}))
|
||||
assert.Equal(t, IBCCodeInvalidProof, res.Code, res.Log)
|
||||
t.Log(">>", strings.Join(store.GetLogLines(), "\n"))
|
||||
store.ClearLogLines()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user