cosmos-sdk/plugins/ibc/ibc_test.go

513 lines
15 KiB
Go

package ibc
// import (
// "bytes"
// "encoding/json"
// "sort"
// "strings"
// "testing"
// "github.com/stretchr/testify/assert"
// "github.com/stretchr/testify/require"
// abci "github.com/tendermint/abci/types"
// crypto "github.com/tendermint/go-crypto"
// "github.com/tendermint/go-wire"
// eyes "github.com/tendermint/merkleeyes/client"
// "github.com/tendermint/merkleeyes/iavl"
// cmn "github.com/tendermint/tmlibs/common"
// "github.com/tendermint/basecoin/types"
// tm "github.com/tendermint/tendermint/types"
// )
// // NOTE: PrivAccounts are sorted by Address,
// // GenesisDoc, not necessarily.
// func genGenesisDoc(chainID string, numVals int) (*tm.GenesisDoc, []types.PrivAccount) {
// var privAccs []types.PrivAccount
// genDoc := &tm.GenesisDoc{
// ChainID: chainID,
// Validators: nil,
// }
// for i := 0; i < numVals; i++ {
// name := cmn.Fmt("%v_val_%v", chainID, i)
// privAcc := types.PrivAccountFromSecret(name)
// genDoc.Validators = append(genDoc.Validators, tm.GenesisValidator{
// PubKey: privAcc.PubKey,
// Amount: 1,
// Name: name,
// })
// privAccs = append(privAccs, privAcc)
// }
// // Sort PrivAccounts
// sort.Sort(PrivAccountsByAddress(privAccs))
// return genDoc, privAccs
// }
// //-------------------------------------
// // Implements sort for sorting PrivAccount by address.
// type PrivAccountsByAddress []types.PrivAccount
// func (pas PrivAccountsByAddress) Len() int {
// return len(pas)
// }
// func (pas PrivAccountsByAddress) Less(i, j int) bool {
// return bytes.Compare(pas[i].Account.PubKey.Address(), pas[j].Account.PubKey.Address()) == -1
// }
// func (pas PrivAccountsByAddress) Swap(i, j int) {
// it := pas[i]
// pas[i] = pas[j]
// pas[j] = it
// }
// //--------------------------------------------------------------------------------
// var testGenesisDoc = `{
// "app_hash": "",
// "chain_id": "test_chain_1",
// "genesis_time": "0001-01-01T00:00:00.000Z",
// "validators": [
// {
// "amount": 10,
// "name": "",
// "pub_key": {
// "type": "ed25519",
// "data":"D6EBB92440CF375054AA59BCF0C99D596DEEDFFB2543CAE1BA1908B72CF9676A"
// }
// }
// ],
// "app_options": {
// "accounts": [
// {
// "pub_key": {
// "type": "ed25519",
// "data": "B3588BDC92015ED3CDB6F57A86379E8C79A7111063610B7E625487C76496F4DF"
// },
// "coins": [
// {
// "denom": "mycoin",
// "amount": 9007199254740992
// }
// ]
// }
// ]
// }
// }`
// func TestIBCGenesisFromString(t *testing.T) {
// eyesClient := eyes.NewLocalClient("", 0)
// store := types.NewKVCache(eyesClient)
// store.SetLogging() // Log all activity
// ibcPlugin := New()
// ctx := types.NewCallContext(nil, nil, coin.Coins{})
// registerChain(t, ibcPlugin, store, ctx, "test_chain", testGenesisDoc)
// }
// //--------------------------------------------------------------------------------
// func TestIBCPluginRegister(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, coin.Coins{})
// chainID_1 := "test_chain"
// genDoc_1, _ := genGenesisDoc(chainID_1, 4)
// genDocJSON_1, err := json.Marshal(genDoc_1)
// require.Nil(err)
// // Register a malformed chain
// res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCRegisterChainTx{
// BlockchainGenesis{
// ChainID: "test_chain",
// Genesis: "<THIS IS NOT JSON>",
// },
// }}))
// assertAndLog(t, store, res, IBCCodeEncodingError)
// // Successfully register a chain
// registerChain(t, ibcPlugin, store, ctx, "test_chain", string(genDocJSON_1))
// // Duplicate request fails
// res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCRegisterChainTx{
// BlockchainGenesis{
// ChainID: "test_chain",
// Genesis: string(genDocJSON_1),
// },
// }}))
// 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, coin.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 := NewPacket("test_chain", "dst_chain", 0, DataPayload([]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)
// }
// func TestIBCPluginPayloadBytes(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, coin.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, DataPayload([]byte("hello world")))
// res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{
// Packet: packet,
// }}))
// assertAndLog(t, store, res, abci.CodeType_OK)
// // Construct a Header that includes the above packet.
// store.Sync()
// resCommit := eyesClient.CommitSync()
// appHash := resCommit.Data
// header := newHeader("test_chain", 999, appHash, []byte("must_exist"))
// // Construct a Commit that signs above header
// commit := constructCommit(privAccs_1, header)
// // Update a chain
// res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCUpdateChainTx{
// Header: header,
// Commit: commit,
// }}))
// assertAndLog(t, store, res, abci.CodeType_OK)
// // 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(err)
// var proof *iavl.IAVLProof
// err = wire.ReadBinaryBytes(resQuery.Proof, &proof)
// assert.Nil(err)
// // Post a packet
// res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketPostTx{
// FromChainID: "test_chain",
// FromChainHeight: 999,
// Packet: packet,
// Proof: proof,
// }}))
// assertAndLog(t, store, res, abci.CodeType_OK)
// }
// func TestIBCPluginPayloadCoins(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()
// coins := coin.Coins{
// coin.Coin{
// Denom: "mycoin",
// Amount: 100,
// },
// }
// ctx := types.NewCallContext(nil, nil, 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))
// // send coins to this addr on the other chain
// destinationAddr := []byte("some address")
// coinsBad := coin.Coins{coin.Coin{"mycoin", 200}}
// coinsGood := coin.Coins{coin.Coin{"mycoin", 1}}
// // Try to send too many coins
// packet := NewPacket("test_chain", "dst_chain", 0, CoinsPayload{
// Address: destinationAddr,
// Coins: coinsBad,
// })
// res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{
// Packet: packet,
// }}))
// assertAndLog(t, store, res, abci.CodeType_InsufficientFunds)
// // Send a small enough number of coins
// packet = NewPacket("test_chain", "dst_chain", 0, CoinsPayload{
// Address: destinationAddr,
// Coins: coinsGood,
// })
// res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{
// Packet: packet,
// }}))
// assertAndLog(t, store, res, abci.CodeType_OK)
// // Construct a Header that includes the above packet.
// store.Sync()
// resCommit := eyesClient.CommitSync()
// appHash := resCommit.Data
// header := newHeader("test_chain", 999, appHash, []byte("must_exist"))
// // Construct a Commit that signs above header
// commit := constructCommit(privAccs_1, header)
// // Update a chain
// res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCUpdateChainTx{
// Header: header,
// Commit: commit,
// }}))
// assertAndLog(t, store, res, abci.CodeType_OK)
// // 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(err)
// var proof *iavl.IAVLProof
// err = wire.ReadBinaryBytes(resQuery.Proof, &proof)
// assert.Nil(err)
// // Account should be empty before the tx
// acc := types.GetAccount(store, destinationAddr)
// assert.Nil(acc)
// // Post a packet
// res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketPostTx{
// FromChainID: "test_chain",
// FromChainHeight: 999,
// Packet: packet,
// Proof: proof,
// }}))
// assertAndLog(t, store, res, abci.CodeType_OK)
// // Account should now have some coins
// acc = types.GetAccount(store, destinationAddr)
// assert.Equal(acc.Balance, coinsGood)
// }
// func TestIBCPluginBadCommit(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, coin.Coins{})
// chainID_1 := "test_chain"
// genDoc_1, privAccs_1 := genGenesisDoc(chainID_1, 4)
// genDocJSON_1, err := json.Marshal(genDoc_1)
// require.Nil(err)
// // Successfully register a chain
// registerChain(t, ibcPlugin, store, ctx, "test_chain", string(genDocJSON_1))
// // Construct a Header
// header := newHeader("test_chain", 999, nil, []byte("must_exist"))
// // Construct a Commit that signs above header
// 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{
// Header: header,
// Commit: commit,
// }}))
// assertAndLog(t, store, res, IBCCodeInvalidCommit)
// }
// func TestIBCPluginBadProof(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, coin.Coins{})
// chainID_1 := "test_chain"
// genDoc_1, privAccs_1 := genGenesisDoc(chainID_1, 4)
// genDocJSON_1, err := json.Marshal(genDoc_1)
// require.Nil(err)
// // Successfully 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, DataPayload([]byte("hello world")))
// res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{
// Packet: packet,
// }}))
// assertAndLog(t, store, res, abci.CodeType_OK)
// // Construct a Header that includes the above packet.
// store.Sync()
// resCommit := eyesClient.CommitSync()
// appHash := resCommit.Data
// header := newHeader("test_chain", 999, appHash, []byte("must_exist"))
// // Construct a Commit that signs above header
// commit := constructCommit(privAccs_1, header)
// // Update a chain
// res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCUpdateChainTx{
// Header: header,
// Commit: commit,
// }}))
// assertAndLog(t, store, res, abci.CodeType_OK)
// // 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(err)
// var proof *iavl.IAVLProof
// err = wire.ReadBinaryBytes(resQuery.Proof, &proof)
// assert.Nil(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,
// }}))
// 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
// }