relayer app
This commit is contained in:
parent
7049025f87
commit
820152b873
10
x/ibc/commands/flags.go
Normal file
10
x/ibc/commands/flags.go
Normal file
@ -0,0 +1,10 @@
|
||||
package commands
|
||||
|
||||
const (
|
||||
flagTo = "to"
|
||||
flagAmount = "amount"
|
||||
flagChain = "chain"
|
||||
flagChain1 = "chain1"
|
||||
flagChain2 = "chain2"
|
||||
flagSequence = "sequence"
|
||||
)
|
||||
61
x/ibc/commands/helpers.go
Normal file
61
x/ibc/commands/helpers.go
Normal file
@ -0,0 +1,61 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
wire "github.com/cosmos/cosmos-sdk/wire"
|
||||
)
|
||||
|
||||
func buildTx(cdc *wire.Codec, msg sdk.Msg) ([]byte, error) {
|
||||
keybase, err := keys.GetKeyBase()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
name := viper.GetString(client.FlagName)
|
||||
|
||||
bz := msg.GetSignBytes()
|
||||
buf := client.BufferStdin()
|
||||
prompt := fmt.Sprintf("Password to sign with '%s':", name)
|
||||
passphrase, err := client.GetPassword(prompt, buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sig, pubkey, err := keybase.Sign(name, passphrase, bz)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sigs := []sdk.StdSignature{{
|
||||
PubKey: pubkey,
|
||||
Signature: sig,
|
||||
Sequence: viper.GetInt64(flagSequence),
|
||||
}}
|
||||
|
||||
tx := sdk.NewStdTx(msg, sigs)
|
||||
|
||||
txBytes, err := cdc.MarshalBinary(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return txBytes, nil
|
||||
}
|
||||
|
||||
func getAddress() []byte {
|
||||
keybase, err := keys.GetKeyBase()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
name := viper.GetString(client.FlagName)
|
||||
info, err := keybase.Get(name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return info.Address()
|
||||
}
|
||||
171
x/ibc/commands/relay.go
Normal file
171
x/ibc/commands/relay.go
Normal file
@ -0,0 +1,171 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/builder"
|
||||
|
||||
wire "github.com/cosmos/cosmos-sdk/wire"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc"
|
||||
)
|
||||
|
||||
func IBCRelayCmd(cdc *wire.Codec) *cobra.Command {
|
||||
cmdr := relayCommander{cdc, "ibc"}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "relay",
|
||||
Run: cmdr.runIBCRelay,
|
||||
}
|
||||
cmd.Flags().String(flagTo, "", "Address to send coins")
|
||||
cmd.Flags().String(flagAmount, "", "Amount of coins to send")
|
||||
cmd.Flags().Int64(flagSequence, 0, "Sequence number to sign the tx")
|
||||
return cmd
|
||||
}
|
||||
|
||||
type relayCommander struct {
|
||||
cdc *wire.Codec
|
||||
ibcStore string
|
||||
}
|
||||
|
||||
func (c relayCommander) runIBCRelay(cmd *cobra.Command, args []string) {
|
||||
chain1 := viper.GetString(flagChain1)
|
||||
chain2 := viper.GetString(flagChain2)
|
||||
|
||||
go c.loop(chain1, chain2)
|
||||
go c.loop(chain2, chain1)
|
||||
}
|
||||
|
||||
// https://github.com/cosmos/cosmos-sdk/blob/master/client/helpers.go using specified address
|
||||
|
||||
func query(id string, key []byte, storeName string) (res []byte, err error) {
|
||||
orig := viper.GetString(client.FlagNode)
|
||||
viper.Set(client.FlagNode, id)
|
||||
res, err = builder.Query(key, storeName)
|
||||
viper.Set(client.FlagNode, orig)
|
||||
return res, err
|
||||
}
|
||||
|
||||
func broadcastTx(id string, tx []byte) error {
|
||||
orig := viper.GetString(client.FlagNode)
|
||||
viper.Set(client.FlagNode, id)
|
||||
_, err := builder.BroadcastTx(tx)
|
||||
viper.Set(client.FlagNode, orig)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c relayCommander) refine(bz []byte, sequence int64) []byte {
|
||||
var packet ibc.IBCPacket
|
||||
if err := c.cdc.UnmarshalBinary(bz, &packet); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
address := getAddress()
|
||||
msg := ibc.IBCReceiveMsg{
|
||||
IBCPacket: packet,
|
||||
Relayer: address,
|
||||
Sequence: sequence,
|
||||
}
|
||||
res, err := buildTx(c.cdc, msg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (c relayCommander) loop(fromID, toID string) {
|
||||
ingressKey := ibc.IngressKey(fromID)
|
||||
|
||||
processedbz, err := query(toID, ingressKey, c.ibcStore)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var processed int64
|
||||
if err = c.cdc.UnmarshalBinary(processedbz, &processed); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
OUTER:
|
||||
for {
|
||||
time.Sleep(time.Second)
|
||||
|
||||
lengthKey := ibc.EgressLengthKey(toID)
|
||||
egressLengthbz, err := query(fromID, lengthKey, c.ibcStore)
|
||||
if err != nil {
|
||||
fmt.Printf("Error querying outgoing packet list length: '%s'\n", err)
|
||||
continue OUTER
|
||||
}
|
||||
var egressLength int64
|
||||
if err = c.cdc.UnmarshalBinary(egressLengthbz, &egressLength); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for i := processed; i < egressLength; i++ {
|
||||
egressbz, err := query(fromID, ibc.EgressKey(toID, i), c.ibcStore)
|
||||
if err != nil {
|
||||
fmt.Printf("Error querying egress packet: '%s'\n", err)
|
||||
continue OUTER
|
||||
}
|
||||
|
||||
err = broadcastTx(toID, c.refine(egressbz, i))
|
||||
if err != nil {
|
||||
fmt.Printf("Error broadcasting ingress packet: '%s'\n", err)
|
||||
continue OUTER
|
||||
}
|
||||
|
||||
fmt.Printf("Relayed packet: %d\n", i)
|
||||
}
|
||||
|
||||
processed = egressLength
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
func (c relayCommander) buildTx() ([]byte, error) {
|
||||
keybase, err := keys.GetKeyBase()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
name := viper.GetString(client.FlagName)
|
||||
info, err := keybase.Get(name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("No key for: %s, name")
|
||||
}
|
||||
from := info.PubKey.Address()
|
||||
|
||||
msg, err := buildMsg(from)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bz := msg.GetSignBytes()
|
||||
buf := client.BufferStdin()
|
||||
prompt := fmt.Sprintf("Password to sign with '%s':", name)
|
||||
passphrase, err := client.GetPassword(prompt, buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sig, pubkey, err := keybase.Sign(name, passphrase, bz)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sigs := []sdk.StdSignature{{
|
||||
PubKey: pubkey,
|
||||
Signature: sig,
|
||||
Sequence: viper.GetInt64(flagSequence),
|
||||
}}
|
||||
|
||||
tx := sdk.NewStdTx(msg, sigs)
|
||||
|
||||
txBytes, err := c.cdc.MarshalBinary(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return txBytes, nil
|
||||
}*/
|
||||
80
x/ibc/commands/send.go
Normal file
80
x/ibc/commands/send.go
Normal file
@ -0,0 +1,80 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/builder"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
wire "github.com/cosmos/cosmos-sdk/wire"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc"
|
||||
)
|
||||
|
||||
func IBCTransferCmd(cdc *wire.Codec) *cobra.Command {
|
||||
cmdr := sendCommander{cdc}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "send",
|
||||
RunE: cmdr.runIBCTransfer,
|
||||
}
|
||||
cmd.Flags().String(flagTo, "", "Address to send coins")
|
||||
cmd.Flags().String(flagAmount, "", "Amount of coins to send")
|
||||
cmd.Flags().String(flagChain, "", "Destination chain to send coins")
|
||||
return cmd
|
||||
}
|
||||
|
||||
type sendCommander struct {
|
||||
cdc *wire.Codec
|
||||
}
|
||||
|
||||
func (c sendCommander) runIBCTransfer(cmd *cobra.Command, args []string) error {
|
||||
address := getAddress()
|
||||
msg, err := buildMsg(address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
txBytes, err := buildTx(c.cdc, msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := builder.BroadcastTx(txBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Committed at block %d. Hash: %s\n", res.Height, res.Hash.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildMsg(from sdk.Address) (sdk.Msg, error) {
|
||||
amount := viper.GetString(flagAmount)
|
||||
coins, err := sdk.ParseCoins(amount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dest := viper.GetString(flagTo)
|
||||
bz, err := hex.DecodeString(dest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
to := sdk.Address(bz)
|
||||
|
||||
return ibc.IBCTransferMsg{
|
||||
IBCPacket: ibc.IBCPacket{
|
||||
SrcAddr: from,
|
||||
DestAddr: to,
|
||||
Coins: coins,
|
||||
SrcChain: viper.GetString(client.FlagNode),
|
||||
DestChain: viper.GetString(flagChain),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user