Add test for bad proof

This commit is contained in:
Jae Kwon 2017-01-29 22:31:05 -08:00
parent 15aa84fd4c
commit 8636946f80
3 changed files with 191 additions and 26 deletions

29
glide.lock generated
View File

@ -1,5 +1,5 @@
hash: 3869944d14a8df914ffcad02c2ef3548173daba51c5ea697767f8af77c07b348
updated: 2017-01-28T09:14:54.898268931-08:00
updated: 2017-01-29T22:09:11.408245895-08:00
imports:
- name: github.com/btcsuite/btcd
version: afec1bd1245a4a19e6dfe1306974b733e7cbb9b8
@ -9,6 +9,8 @@ imports:
version: 637e656429416087660c84436a2a035d69d54e2e
- name: github.com/BurntSushi/toml
version: 99064174e013895bbd9b025c31100bd1d9b590ca
- name: github.com/ebuchman/fail-test
version: c1eddaa09da2b4017351245b0d43234955276798
- name: github.com/go-stack/stack
version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82
- name: github.com/golang/protobuf
@ -46,6 +48,8 @@ imports:
version: 8df0bc3a40ccad0d2be10e33c62c404e65c92502
subpackages:
- client
- example/dummy
- example/nil
- server
- types
- name: github.com/tendermint/ed25519
@ -53,6 +57,10 @@ imports:
subpackages:
- edwards25519
- extra25519
- name: github.com/tendermint/go-autofile
version: 0416e0aa9c68205aa44844096f9f151ada9d0405
- name: github.com/tendermint/go-clist
version: 3baa390bbaf7634251c42ad69a8682e7e3990552
- name: github.com/tendermint/go-common
version: 339e135776142939d82bc8e699db0bf391fd938d
- name: github.com/tendermint/go-config
@ -79,23 +87,36 @@ imports:
version: 6177eb8398ebd4613fbecb71fd96d7c7d97303ec
subpackages:
- client
- server
- types
- name: github.com/tendermint/go-wire
version: 2f3b7aafe21c80b19b6ee3210ecb3e3d07c7a471
version: 3216ec9d47bbdf8d4fc27d22169ea86a6688bc15
- name: github.com/tendermint/log15
version: 9545b249b3aacafa97f79e0838b02b274adc6f5f
subpackages:
- term
- name: github.com/tendermint/merkleeyes
version: 00d915af3e425cf57c10afe502fd9e0a6a70acd4
version: 7c1ec0ef86c42b7a461e3967efb6c35bd5652101
subpackages:
- app
- client
- name: github.com/tendermint/tendermint
version: 7c15b54cccac574cfe673c473d4edff01c2503ec
version: 67ab574e9889c0641ae959296d391e3cadec55e3
subpackages:
- blockchain
- config/tendermint
- consensus
- mempool
- node
- proxy
- rpc/core
- rpc/core/types
- rpc/grpc
- state
- types
- version
- name: github.com/urfave/cli
version: 8ef3805c9de2519805c3f060524b695bba2cd715
- name: golang.org/x/crypto
version: aa2481cbfe81d911eb62b642b7a6b5ec58bbea71
subpackages:

View File

@ -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)

View File

@ -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()
}