cosmos-sdk/cmd/basecoin/commands/ibc.go

252 lines
5.5 KiB
Go
Raw Normal View History

package commands
2017-01-29 18:41:37 -08:00
import (
"encoding/hex"
"errors"
"fmt"
"io/ioutil"
"github.com/urfave/cli"
"github.com/tendermint/basecoin/plugins/ibc"
cmn "github.com/tendermint/go-common"
"github.com/tendermint/go-merkle"
"github.com/tendermint/go-wire"
tmtypes "github.com/tendermint/tendermint/types"
)
var (
IbcCmd = cli.Command{
Name: "ibc",
Usage: "Send a transaction to the interblockchain (ibc) plugin",
Flags: []cli.Flag{
2017-01-30 06:27:02 -08:00
NodeFlag,
ChainIDFlag,
2017-01-30 06:27:02 -08:00
FromFlag,
2017-01-30 06:27:02 -08:00
AmountFlag,
CoinFlag,
GasFlag,
FeeFlag,
SeqFlag,
2017-01-30 06:27:02 -08:00
NameFlag,
DataFlag,
},
Subcommands: []cli.Command{
IbcRegisterTxCmd,
IbcUpdateTxCmd,
IbcPacketTxCmd,
},
}
IbcRegisterTxCmd = cli.Command{
Name: "register",
Usage: "Register a blockchain via IBC",
Action: func(c *cli.Context) error {
return cmdIBCRegisterTx(c)
},
Flags: []cli.Flag{
2017-01-30 06:27:02 -08:00
IbcChainIDFlag,
IbcGenesisFlag,
},
}
IbcUpdateTxCmd = cli.Command{
Name: "update",
Usage: "Update the latest state of a blockchain via IBC",
Action: func(c *cli.Context) error {
return cmdIBCUpdateTx(c)
},
Flags: []cli.Flag{
2017-01-30 06:27:02 -08:00
IbcHeaderFlag,
IbcCommitFlag,
},
}
IbcPacketTxCmd = cli.Command{
Name: "packet",
Usage: "Send a new packet via IBC",
Flags: []cli.Flag{
//
},
Subcommands: []cli.Command{
IbcPacketCreateTx,
IbcPacketPostTx,
},
}
IbcPacketCreateTx = cli.Command{
Name: "create",
Usage: "Create an egress IBC packet",
Action: func(c *cli.Context) error {
return cmdIBCPacketCreateTx(c)
},
Flags: []cli.Flag{
2017-01-30 06:27:02 -08:00
IbcFromFlag,
IbcToFlag,
IbcTypeFlag,
IbcPayloadFlag,
IbcSequenceFlag,
},
}
IbcPacketPostTx = cli.Command{
Name: "post",
Usage: "Deliver an IBC packet to another chain",
Action: func(c *cli.Context) error {
return cmdIBCPacketPostTx(c)
},
Flags: []cli.Flag{
2017-01-30 06:27:02 -08:00
IbcFromFlag,
IbcHeightFlag,
IbcPacketFlag,
IbcProofFlag,
},
}
)
2017-01-29 18:41:37 -08:00
func cmdIBCRegisterTx(c *cli.Context) error {
chainID := c.String("chain_id")
genesisFile := c.String("genesis")
parent := c.Parent()
genesisBytes, err := ioutil.ReadFile(genesisFile)
if err != nil {
return errors.New(cmn.Fmt("Error reading genesis file %v: %v", genesisFile, err))
}
ibcTx := ibc.IBCRegisterChainTx{
ibc.BlockchainGenesis{
ChainID: chainID,
Genesis: string(genesisBytes),
},
}
fmt.Println("IBCTx:", string(wire.JSONBytes(ibcTx)))
2017-01-29 20:06:14 -08:00
data := []byte(wire.BinaryBytes(struct {
ibc.IBCTx `json:"unwrap"`
}{ibcTx}))
name := "IBC"
2017-01-29 18:41:37 -08:00
return AppTx(parent, name, data)
2017-01-29 18:41:37 -08:00
}
func cmdIBCUpdateTx(c *cli.Context) error {
headerBytes, err := hex.DecodeString(stripHex(c.String("header")))
if err != nil {
return errors.New(cmn.Fmt("Header (%v) is invalid hex: %v", c.String("header"), err))
}
commitBytes, err := hex.DecodeString(stripHex(c.String("commit")))
if err != nil {
return errors.New(cmn.Fmt("Commit (%v) is invalid hex: %v", c.String("commit"), err))
}
2017-01-29 20:06:14 -08:00
header := new(tmtypes.Header)
commit := new(tmtypes.Commit)
2017-01-29 18:41:37 -08:00
if err := wire.ReadBinaryBytes(headerBytes, &header); err != nil {
return errors.New(cmn.Fmt("Error unmarshalling header: %v", err))
}
if err := wire.ReadBinaryBytes(commitBytes, &commit); err != nil {
return errors.New(cmn.Fmt("Error unmarshalling commit: %v", err))
}
ibcTx := ibc.IBCUpdateChainTx{
2017-01-29 20:06:14 -08:00
Header: *header,
Commit: *commit,
2017-01-29 18:41:37 -08:00
}
fmt.Println("IBCTx:", string(wire.JSONBytes(ibcTx)))
2017-01-29 20:06:14 -08:00
data := []byte(wire.BinaryBytes(struct {
ibc.IBCTx `json:"unwrap"`
}{ibcTx}))
name := "IBC"
2017-01-29 18:41:37 -08:00
return AppTx(c.Parent(), name, data)
2017-01-29 18:41:37 -08:00
}
func cmdIBCPacketCreateTx(c *cli.Context) error {
2017-01-29 19:18:50 -08:00
fromChain, toChain := c.String("from"), c.String("to")
packetType := c.String("type")
payloadBytes, err := hex.DecodeString(stripHex(c.String("payload")))
if err != nil {
return errors.New(cmn.Fmt("Payload (%v) is invalid hex: %v", c.String("payload"), err))
}
sequence, err := getIBCSequence(c)
if err != nil {
return err
}
ibcTx := ibc.IBCPacketCreateTx{
Packet: ibc.Packet{
SrcChainID: fromChain,
DstChainID: toChain,
Sequence: sequence,
Type: packetType,
Payload: payloadBytes,
},
}
fmt.Println("IBCTx:", string(wire.JSONBytes(ibcTx)))
2017-01-29 20:06:14 -08:00
data := []byte(wire.BinaryBytes(struct {
ibc.IBCTx `json:"unwrap"`
}{ibcTx}))
2017-01-29 19:18:50 -08:00
return AppTx(c.Parent().Parent(), "IBC", data)
2017-01-29 18:41:37 -08:00
}
func cmdIBCPacketPostTx(c *cli.Context) error {
2017-01-29 19:18:50 -08:00
fromChain, fromHeight := c.String("from"), c.Int("height")
2017-01-29 18:41:37 -08:00
2017-01-29 19:18:50 -08:00
packetBytes, err := hex.DecodeString(stripHex(c.String("packet")))
if err != nil {
return errors.New(cmn.Fmt("Packet (%v) is invalid hex: %v", c.String("packet"), err))
}
proofBytes, err := hex.DecodeString(stripHex(c.String("proof")))
if err != nil {
return errors.New(cmn.Fmt("Proof (%v) is invalid hex: %v", c.String("proof"), err))
}
var packet ibc.Packet
2017-01-29 22:43:07 -08:00
proof := new(merkle.IAVLProof)
2017-01-29 18:41:37 -08:00
2017-01-29 19:18:50 -08:00
if err := wire.ReadBinaryBytes(packetBytes, &packet); err != nil {
return errors.New(cmn.Fmt("Error unmarshalling packet: %v", err))
}
if err := wire.ReadBinaryBytes(proofBytes, &proof); err != nil {
return errors.New(cmn.Fmt("Error unmarshalling proof: %v", err))
}
2017-01-29 18:41:37 -08:00
2017-01-29 19:18:50 -08:00
ibcTx := ibc.IBCPacketPostTx{
2017-01-29 18:41:37 -08:00
FromChainID: fromChain,
2017-01-29 19:18:50 -08:00
FromChainHeight: uint64(fromHeight),
Packet: packet,
Proof: proof,
2017-01-29 18:41:37 -08:00
}
fmt.Println("IBCTx:", string(wire.JSONBytes(ibcTx)))
2017-01-29 20:06:14 -08:00
data := []byte(wire.BinaryBytes(struct {
ibc.IBCTx `json:"unwrap"`
}{ibcTx}))
2017-01-29 18:41:37 -08:00
return AppTx(c.Parent().Parent(), "IBC", data)
2017-01-29 19:18:50 -08:00
}
func getIBCSequence(c *cli.Context) (uint64, error) {
if c.IsSet("sequence") {
return uint64(c.Int("sequence")), nil
}
// TODO: get sequence
return 0, nil
2017-01-29 18:41:37 -08:00
}