From ee0772396c7e4dbe31e20b27bfdb9625eddd8ce3 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sun, 21 May 2017 11:08:46 -0400 Subject: [PATCH] [ibc] cleanup tests --- plugins/ibc/ibc.go | 10 ++ plugins/ibc/ibc_test.go | 318 +++++++++++++++++----------------------- 2 files changed, 144 insertions(+), 184 deletions(-) diff --git a/plugins/ibc/ibc.go b/plugins/ibc/ibc.go index 06fd25cbca..7e38967957 100644 --- a/plugins/ibc/ibc.go +++ b/plugins/ibc/ibc.go @@ -59,6 +59,16 @@ type Packet struct { Payload Payload } +func NewPacket(src, dst string, seq uint64, ty string, payload Payload) Packet { + return Packet{ + SrcChainID: src, + DstChainID: dst, + Sequence: seq, + Type: ty, + Payload: payload, + } +} + //-------------------------------------------------------------------------------- const ( diff --git a/plugins/ibc/ibc_test.go b/plugins/ibc/ibc_test.go index 1853a3a72d..4b2c6a945c 100644 --- a/plugins/ibc/ibc_test.go +++ b/plugins/ibc/ibc_test.go @@ -101,34 +101,19 @@ var testGenesisDoc = `{ }` func TestIBCGenesisFromString(t *testing.T) { - assert := assert.New(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{}, - } + ctx := types.NewCallContext(nil, nil, types.Coins{}) - res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCRegisterChainTx{ - BlockchainGenesis{ - ChainID: "test_chain", - Genesis: testGenesisDoc, - }, - }})) - assert.True(res.IsOK(), res.Log) - t.Log(">>", strings.Join(store.GetLogLines(), "\n")) - store.ClearLogLines() + registerChain(t, ibcPlugin, store, ctx, "test_chain", testGenesisDoc) } //-------------------------------------------------------------------------------- -func TestIBCPlugin(t *testing.T) { - assert := assert.New(t) +func TestIBCPluginRegister(t *testing.T) { require := require.New(t) eyesClient := eyes.NewLocalClient("", 0) @@ -136,14 +121,10 @@ func TestIBCPlugin(t *testing.T) { store.SetLogging() // Log all activity ibcPlugin := New() - ctx := types.CallContext{ - CallerAddress: nil, - CallerAccount: nil, - Coins: types.Coins{}, - } + ctx := types.NewCallContext(nil, nil, types.Coins{}) chainID_1 := "test_chain" - genDoc_1, privAccs_1 := genGenesisDoc(chainID_1, 4) + genDoc_1, _ := genGenesisDoc(chainID_1, 4) genDocJSON_1, err := json.Marshal(genDoc_1) require.Nil(err) @@ -154,20 +135,10 @@ func TestIBCPlugin(t *testing.T) { Genesis: "", }, }})) - assert.Equal(IBCCodeEncodingError, res.Code) - t.Log(">>", strings.Join(store.GetLogLines(), "\n")) - store.ClearLogLines() + assertAndLog(t, store, res, IBCCodeEncodingError) // Successfully register a chain - res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCRegisterChainTx{ - BlockchainGenesis{ - ChainID: "test_chain", - Genesis: string(genDocJSON_1), - }, - }})) - assert.True(res.IsOK(), res.Log) - t.Log(">>", strings.Join(store.GetLogLines(), "\n")) - store.ClearLogLines() + registerChain(t, ibcPlugin, store, ctx, "test_chain", string(genDocJSON_1)) // Duplicate request fails res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCRegisterChainTx{ @@ -176,74 +147,88 @@ func TestIBCPlugin(t *testing.T) { Genesis: string(genDocJSON_1), }, }})) - assert.Equal(IBCCodeChainAlreadyExists, res.Code, res.Log) - t.Log(">>", strings.Join(store.GetLogLines(), "\n")) - store.ClearLogLines() + assertAndLog(t, store, res, IBCCodeChainAlreadyExists) +} + +func TestIBCPluginPost(t *testing.T) { + require := require.New(t) + + eyesClient := eyes.NewLocalClient("", 0) + store := types.NewKVCache(eyesClient) + store.SetLogging() // Log all activity + + ibcPlugin := New() + ctx := types.NewCallContext(nil, nil, types.Coins{}) + + chainID_1 := "test_chain" + genDoc_1, _ := genGenesisDoc(chainID_1, 4) + genDocJSON_1, err := json.Marshal(genDoc_1) + require.Nil(err) + + // Register a chain + registerChain(t, ibcPlugin, store, ctx, "test_chain", string(genDocJSON_1)) // 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 := NewPacket("test_chain", "dst_chain", 0, "data", BytesPayload([]byte("hello world"))) + res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{ Packet: packet, }})) - assert.Equal(abci.CodeType_OK, res.Code, res.Log) - t.Log(">>", strings.Join(store.GetLogLines(), "\n")) - store.ClearLogLines() + assertAndLog(t, store, res, abci.CodeType_OK) // Post a duplicate packet res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{ Packet: packet, }})) - assert.Equal(IBCCodePacketAlreadyExists, res.Code, res.Log) - t.Log(">>", strings.Join(store.GetLogLines(), "\n")) - store.ClearLogLines() + assertAndLog(t, store, res, IBCCodePacketAlreadyExists) +} + +func TestIBCPlugin(t *testing.T) { + assert := assert.New(t) + require := require.New(t) + + eyesClient := eyes.NewLocalClient("", 0) + store := types.NewKVCache(eyesClient) + store.SetLogging() // Log all activity + + ibcPlugin := New() + ctx := types.NewCallContext(nil, nil, types.Coins{}) + + chainID_1 := "test_chain" + genDoc_1, privAccs_1 := genGenesisDoc(chainID_1, 4) + genDocJSON_1, err := json.Marshal(genDoc_1) + require.Nil(err) + + // Register a chain + registerChain(t, ibcPlugin, store, ctx, "test_chain", string(genDocJSON_1)) + + // Create a new packet (for testing) + packet := NewPacket("test_chain", "dst_chain", 0, "data", BytesPayload([]byte("hello world"))) + res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{ + Packet: packet, + }})) + assertAndLog(t, store, res, abci.CodeType_OK) + + // Post a duplicate packet + res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{ + Packet: packet, + }})) + assertAndLog(t, store, res, IBCCodePacketAlreadyExists) // 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 - } + header := newHeader("test_chain", 999, appHash, []byte("must_exist")) // 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 - } + commit := constructCommit(privAccs_1, header) // Update a chain res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCUpdateChainTx{ Header: header, Commit: commit, }})) - assert.Equal(abci.CodeType_OK, res.Code, res.Log) - t.Log(">>", strings.Join(store.GetLogLines(), "\n")) - store.ClearLogLines() + assertAndLog(t, store, res, abci.CodeType_OK) // Get proof for the packet packetKey := toKey(_IBC, _EGRESS, @@ -268,13 +253,10 @@ func TestIBCPlugin(t *testing.T) { Packet: packet, Proof: proof, }})) - assert.Equal(abci.CodeType_OK, res.Code, res.Log) - t.Log(">>", strings.Join(store.GetLogLines(), "\n")) - store.ClearLogLines() + assertAndLog(t, store, res, abci.CodeType_OK) } func TestIBCPluginBadCommit(t *testing.T) { - assert := assert.New(t) require := require.New(t) eyesClient := eyes.NewLocalClient("", 0) @@ -282,11 +264,7 @@ func TestIBCPluginBadCommit(t *testing.T) { store.SetLogging() // Log all activity ibcPlugin := New() - ctx := types.CallContext{ - CallerAddress: nil, - CallerAccount: nil, - Coins: types.Coins{}, - } + ctx := types.NewCallContext(nil, nil, types.Coins{}) chainID_1 := "test_chain" genDoc_1, privAccs_1 := genGenesisDoc(chainID_1, 4) @@ -294,57 +272,24 @@ func TestIBCPluginBadCommit(t *testing.T) { require.Nil(err) // Successfully register a chain - res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCRegisterChainTx{ - BlockchainGenesis{ - ChainID: "test_chain", - Genesis: string(genDocJSON_1), - }, - }})) - assert.True(res.IsOK(), res.Log) - t.Log(">>", strings.Join(store.GetLogLines(), "\n")) - store.ClearLogLines() + registerChain(t, ibcPlugin, store, ctx, "test_chain", string(genDocJSON_1)) // Construct a Header - header := tm.Header{ - ChainID: "test_chain", - Height: 999, - ValidatorsHash: []byte("must_exist"), // TODO make optional - } + header := newHeader("test_chain", 999, nil, []byte("must_exist")) // 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 - } + commit := constructCommit(privAccs_1, header) // Update a chain with a broken commit // Modify the first byte of the first signature sig := commit.Precommits[0].Signature.Unwrap().(crypto.SignatureEd25519) sig[0] += 1 commit.Precommits[0].Signature = sig.Wrap() - res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCUpdateChainTx{ + res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCUpdateChainTx{ Header: header, Commit: commit, }})) - assert.Equal(IBCCodeInvalidCommit, res.Code, res.Log) - t.Log(">>", strings.Join(store.GetLogLines(), "\n")) - store.ClearLogLines() + assertAndLog(t, store, res, IBCCodeInvalidCommit) } @@ -357,11 +302,7 @@ func TestIBCPluginBadProof(t *testing.T) { store.SetLogging() // Log all activity ibcPlugin := New() - ctx := types.CallContext{ - CallerAddress: nil, - CallerAccount: nil, - Coins: types.Coins{}, - } + ctx := types.NewCallContext(nil, nil, types.Coins{}) chainID_1 := "test_chain" genDoc_1, privAccs_1 := genGenesisDoc(chainID_1, 4) @@ -369,72 +310,30 @@ func TestIBCPluginBadProof(t *testing.T) { require.Nil(err) // Successfully register a chain - res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCRegisterChainTx{ - BlockchainGenesis{ - ChainID: "test_chain", - Genesis: string(genDocJSON_1), - }, - }})) - assert.True(res.IsOK(), res.Log) - t.Log(">>", strings.Join(store.GetLogLines(), "\n")) - store.ClearLogLines() + registerChain(t, ibcPlugin, store, ctx, "test_chain", string(genDocJSON_1)) // 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 := NewPacket("test_chain", "dst_chain", 0, "data", BytesPayload([]byte("hello world"))) + res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{ Packet: packet, }})) - assert.Equal(abci.CodeType_OK, res.Code, res.Log) - t.Log(">>", strings.Join(store.GetLogLines(), "\n")) - store.ClearLogLines() + assertAndLog(t, store, res, abci.CodeType_OK) // 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 - } + header := newHeader("test_chain", 999, appHash, []byte("must_exist")) // 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 - } + commit := constructCommit(privAccs_1, header) // Update a chain res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCUpdateChainTx{ Header: header, Commit: commit, }})) - assert.Equal(abci.CodeType_OK, res.Code, res.Log) - t.Log(">>", strings.Join(store.GetLogLines(), "\n")) - store.ClearLogLines() + assertAndLog(t, store, res, abci.CodeType_OK) // Get proof for the packet packetKey := toKey(_IBC, _EGRESS, @@ -462,7 +361,58 @@ func TestIBCPluginBadProof(t *testing.T) { Packet: packet, Proof: proof, }})) - assert.Equal(IBCCodeInvalidProof, res.Code, res.Log) + assertAndLog(t, store, res, IBCCodeInvalidProof) +} + +//------------------------------------- +// utils + +func assertAndLog(t *testing.T, store *types.KVCache, res abci.Result, codeExpected abci.CodeType) { + assert := assert.New(t) + assert.Equal(codeExpected, res.Code, res.Log) t.Log(">>", strings.Join(store.GetLogLines(), "\n")) store.ClearLogLines() } + +func newHeader(chainID string, height int, appHash, valHash []byte) tm.Header { + return tm.Header{ + ChainID: chainID, + Height: height, + AppHash: appHash, + ValidatorsHash: valHash, + } +} + +func registerChain(t *testing.T, ibcPlugin *IBCPlugin, store *types.KVCache, ctx types.CallContext, chainID, genDoc string) { + res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCRegisterChainTx{ + BlockchainGenesis{ + ChainID: chainID, + Genesis: genDoc, + }, + }})) + assertAndLog(t, store, res, abci.CodeType_OK) +} + +func constructCommit(privAccs []types.PrivAccount, header tm.Header) tm.Commit { + blockHash := header.Hash() + blockID := tm.BlockID{Hash: blockHash} + commit := tm.Commit{ + BlockID: blockID, + Precommits: make([]*tm.Vote, len(privAccs)), + } + for i, privAcc := range privAccs { + 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 + } + return commit +}