Skip to content

Commit

Permalink
Merge PR cosmos#274: feat: allow building a shared library
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelfig authored Nov 4, 2020
1 parent 650bb76 commit 3a30839
Show file tree
Hide file tree
Showing 71 changed files with 492 additions and 168 deletions.
31 changes: 31 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
FROM golang:alpine as BUILD

WORKDIR /relayer

# Copy the files from host
COPY . .

# Update and install needed deps prioir to installing the binary.
RUN apk update && \
apk --no-cache add make=4.2.1-r2 git=2.24.3-r0 && \
make install

FROM alpine:edge

ENV RELAYER /relayer

RUN addgroup rlyuser && \
adduser -S -G rlyuser rlyuser -h "$RELAYER"

USER rlyuser

# Define working directory
WORKDIR $RELAYER

# Copy binary from BUILD
COPY --from=BUILD /go/bin/rly /usr/bin/rly

ENTRYPOINT ["/usr/bin/rly"]

# Make config available ofr mutaitons
VOLUME [ $RELAYER ]
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ build-zip: go.sum
@GOOS=windows GOARCH=amd64 go build -mod=readonly $(BUILD_FLAGS) -o build/windows-amd64-rly.exe main.go
@tar -czvf release.tar.gz ./build

# Compile the relayer as a shared library to be linked into another program
compile-clib:
go build -v -mod=readonly -buildmode=c-shared -o librelayer.so ./clib

install: go.sum
@echo "installing rly binary..."
@go build -mod=readonly $(BUILD_FLAGS) -o $${GOBIN-$${GOPATH-$$HOME/go}/bin}/rly main.go
Expand Down
36 changes: 18 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

The Cosmos IBC `relayer` package contains a basic relayer implementation that is
meant for users wishing to relay packets/data between sets of IBC enabled chains.
In additon, it is well documented and intended as an example where anyone who is
In addition, it is well documented and intended as an example where anyone who is
interested in building their own relayer can come for complete, working, examples.

### Security Notice
Expand All @@ -15,13 +15,13 @@ If you would like to report a security critical bug related to the relayer repo,

## Code of Conduct

The iqlusion team is dedicated to providing an inclusive and harrassment free experience for contributors. Please visit [Code of Conduct](CODE_OF_CONDUCT.md) for more information.
The iqlusion team is dedicated to providing an inclusive and harassment free experience for contributors. Please visit [Code of Conduct](CODE_OF_CONDUCT.md) for more information.

## Testnet

If you would like to join a relayer testnet, please [check out the instructions](./testnets/README.md).

### Compatability Table:
### Compatibility Table:

> NOTE:
Expand Down Expand Up @@ -61,16 +61,16 @@ $ rly cfg add-dir configs/demo/
$ cat ~/.relayer/config/config.yaml

# Now, add the key seeds from each chain to the relayer to give it funds to work with
$ rly keys restore ibc0 testkey "$(jq -r '.mnemonic' data/ibc0/key_seed.json)"
$ rly k r ibc1 testkey "$(jq -r '.mnemonic' data/ibc1/key_seed.json)"
$ rly keys restore ibc-0 testkey "$(jq -r '.mnemonic' data/ibc-0/key_seed.json)"
$ rly k r ibc-1 testkey "$(jq -r '.mnemonic' data/ibc-1/key_seed.json)"

# Then its time to initialize the relayer's light clients for each chain
# All data moving forward is validated by these light clients.
$ rly light init ibc0 -f
$ rly l i ibc1 -f
$ rly light init ibc-0 -f
$ rly l i ibc-1 -f

# At this point the relayer --home directory is ready for normal operations between
# ibc0 and ibc1. Looking at the folder structure of the relayer at this point is helpful
# ibc-0 and ibc-1. Looking at the folder structure of the relayer at this point is helpful
$ tree ~/.relayer

# See if the chains are ready to relay over
Expand All @@ -80,32 +80,32 @@ $ rly chains list
$ rly tx link demo -d -o 3s

# Check the token balances on both chains
$ rly q balance ibc0 | jq
$ rly q bal ibc1 | jq
$ rly q balance ibc-0 | jq
$ rly q bal ibc-1 | jq

# Then send some tokens between the chains
$ rly tx transfer ibc0 ibc1 1000000samoleans $(rly chains address ibc1)
$ rly tx transfer ibc-0 ibc-1 1000000samoleans $(rly chains address ibc-1)
$ rly tx relay demo -d

# See that the transfer has completed
$ rly q bal ibc0 | jq
$ rly q bal ibc1 | jq
$ rly q bal ibc-0 | jq
$ rly q bal ibc-1 | jq

# Send the tokens back to the account on ibc0
$ rly tx xfer ibc1 ibc0 1000000transfer/ibczeroxfer/samoleans $(rly ch addr ibc0)
# Send the tokens back to the account on ibc-0
$ rly tx xfer ibc-1 ibc-0 1000000transfer/ibczeroxfer/samoleans $(rly ch addr ibc-0)
$ rly tx rly demo -d

# See that the return trip has completed
$ rly q bal ibc0 | jq
$ rly q bal ibc1 | jq
$ rly q bal ibc-0 | jq
$ rly q bal ibc-1 | jq

# NOTE: you will see the stake balances decreasing on each chain. This is to pay for fees
# You can change the amount of fees you are paying on each chain in the configuration.
```

## Setting up Developer Environment

Working with the relayer can frequently involve working with local developement branches of `gaia`, `cosmos-sdk` and the `relayer`. To setup your environment to point at the local versions of the code and reduce the amount of time in your read-eval-print loops try the following:
Working with the relayer can frequently involve working with local development branches of `gaia`, `cosmos-sdk` and the `relayer`. To setup your environment to point at the local versions of the code and reduce the amount of time in your read-eval-print loops try the following:

1. Set `replace github.com/cosmos/cosmos-sdk => /path/to/local/github.com/comsos/cosmos-sdk` at the end of the `go.mod` files for the `relayer` and `gaia`. This will force building from the local version of the `cosmos-sdk` when running the `./dev-env` script.
2. After `./dev-env` has run, you can use `go run main.go` for any relayer commands you are working on. This allows you make changes and immediately test them as long as there are no server side changes.
Expand Down
130 changes: 130 additions & 0 deletions clib/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// This is the entry point for a shared library built around the relayer.
// It depends on cgo, unlike the rly binary.
//
// This library was used as the basis for the Agoric Smart Relay:
// https://github.com/Agoric/agoric-sdk/tree/goz-smart-relay/packages/smart-relay

package main

// /* These comments before the import "C" are included in the C output. */
// #include <stdlib.h>
// typedef const char* Body;
// typedef int (*sendFunc)(int, int, Body);
// inline int invokeSendFunc(sendFunc send, int port, int reply, Body str) {
// return send(port, reply, str);
// }
import "C"
import (
"encoding/json"
"errors"
"fmt"
"os"

"github.com/cosmos/relayer/cmd"
"github.com/cosmos/relayer/relayer"
)

type goReturn = struct {
str string
err error
}

var clibPort = 0
var replies = map[int]chan goReturn{}
var lastReply = 0

//export RunClib
func RunClib(nodePort C.int, toNode C.sendFunc, clibArgs []*C.char) C.int {
if relayer.SendToController == nil {
relayer.SendToController = func(needReply bool, str string) (string, error) {
var rPort int
if needReply {
lastReply++
rPort = lastReply
replies[rPort] = make(chan goReturn)
}
// Send the message.
C.invokeSendFunc(toNode, nodePort, C.int(rPort), C.CString(str))
if !needReply {
// Return immediately
return "<no-reply-requested>", nil
}

// Block the sending goroutine while we wait for the reply
ret := <-replies[rPort]
delete(replies, rPort)
return ret.str, ret.err
}
}

args := make([]string, len(clibArgs))
for i, s := range clibArgs {
args[i] = C.GoString(s)
}
// fmt.Println("Starting relayer with args", args)
go func() {
os.Args = args
cmd.Execute()
// fmt.Printf("exiting with nodePort %d\n", nodePort)
if nodePort == 0 {
os.Exit(0)
}
}()

clibPort++
return C.int(clibPort)
}

//export ReplyToClib
func ReplyToClib(replyPort C.int, isError C.int, str C.Body) C.int {
goStr := C.GoString(str)
returnCh := replies[int(replyPort)]
if returnCh == nil {
return C.int(0)
}
ret := goReturn{}
if int(isError) == 0 {
ret.str = goStr
} else {
ret.err = errors.New(goStr)
}
returnCh <- ret
return C.int(0)
}

//export SendToClib
func SendToClib(port C.int, str C.Body) C.Body {
goStr := C.GoString(str)
var action relayer.DeliverMsgsAction
err := json.Unmarshal([]byte(goStr), &action)
if err == nil {
switch action.Type {
case "RELAYER_SEND":
src := relayer.UnmarshalChain(action.Src)
dst := relayer.UnmarshalChain(action.Dst)
if src == nil || dst == nil {
return C.CString("false")
}
rm := relayer.RelayMsgs{
Succeeded: action.Succeeded,
Last: action.Last,
}
rm.Src = relayer.DecodeMsgs(src, action.SrcMsgs)
rm.Dst = relayer.DecodeMsgs(dst, action.DstMsgs)

rm.SendWithController(src, dst, false)
if !rm.Succeeded {
return C.CString("0")
}
return C.CString(fmt.Sprintf("%d", len(rm.Src)+len(rm.Dst)))
default:
fmt.Printf("failed action.Type %s\n", action.Type)
}
} else {
fmt.Printf("failed unmarshalling %s\n", err)
}
return C.CString("false")
}

// Do nothing in main.
func main() {}
11 changes: 11 additions & 0 deletions cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@ func startCmd() *cobra.Command {
return err
}

if relayer.SendToController != nil {
action := relayer.PathAction{
Path: path,
Type: "RELAYER_PATH_START",
}
cont, err := relayer.ControllerUpcall(&action)
if !cont {
return err
}
}

done, err := relayer.RunStrategy(c[src], c[dst], strategy)
if err != nil {
return err
Expand Down
21 changes: 21 additions & 0 deletions cmd/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ limitations under the License.
package cmd

import (
"fmt"
"strings"
"time"

"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/relayer/relayer"
Expand All @@ -37,6 +39,7 @@ func transactionCmd() *cobra.Command {

cmd.AddCommand(
linkCmd(),
linkThenStartCmd(),
relayMsgsCmd(),
relayAcksCmd(),
xfersend(),
Expand Down Expand Up @@ -253,6 +256,24 @@ func linkCmd() *cobra.Command {
return timeoutFlag(cmd)
}

func linkThenStartCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "link-then-start [path-name]",
Short: "wait for a link to come up, then start relaying packets",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
lCmd := linkCmd()
for err := lCmd.RunE(cmd, args); err != nil; err = lCmd.RunE(cmd, args) {
fmt.Printf("retrying link: %s\n", err)
time.Sleep(1 * time.Second)
}
sCmd := startCmd()
return sCmd.RunE(cmd, args)
},
}
return timeoutFlag(cmd)
}

func relayMsgsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "relay-packets [path-name]",
Expand Down
2 changes: 1 addition & 1 deletion configs/agoric/demo.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"src":{"chain-id":"ibc0","client-id":"ibconeclient","connection-id":"ibconeconnection","channel-id":"ibconexfer","port-id":"transfer"},"dst":{"chain-id":"ibc1","client-id":"ibczeroclient","connection-id":"ibczeroconnection","channel-id":"ibczeroxfer","port-id":"transfer"},"strategy":{"type":"naive"}}
{"src":{"chain-id":"ibc-0","client-id":"ibconeclient","connection-id":"ibconeconnection","channel-id":"ibconexfer","port-id":"transfer","version":"ics20-1"},"dst":{"chain-id":"ibc-1","client-id":"ibczeroclient","connection-id":"ibczeroconnection","channel-id":"ibczeroxfer","port-id":"transfer","version":"ics20-1"},"strategy":{"type":"naive"}}
1 change: 1 addition & 0 deletions configs/agoric/ibc-0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"key":"testkey","chain-id":"ibc-0","rpc-addr":"http://localhost:26657","account-prefix":"agoric","gas":200000,"gas-adjustment":1.0,"gas-prices":"","default-denom":"uagstake","trusting-period":"336h"}
1 change: 1 addition & 0 deletions configs/agoric/ibc-1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"key":"testkey","chain-id":"ibc-1","rpc-addr":"http://localhost:26557","account-prefix":"agoric","gas":200000,"gas-adjustment":1.0,"gas-prices":"","default-denom":"uagstake","trusting-period":"336h"}
1 change: 0 additions & 1 deletion configs/agoric/ibc0.json

This file was deleted.

1 change: 0 additions & 1 deletion configs/agoric/ibc1.json

This file was deleted.

2 changes: 1 addition & 1 deletion configs/akash/demo.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"src":{"chain-id":"ibc0","client-id":"ibconeclient","connection-id":"ibconeconnection","channel-id":"ibconexfer","port-id":"transfer","order":"unordered"},"dst":{"chain-id":"ibc1","client-id":"ibczeroclient","connection-id":"ibczeroconnection","channel-id":"ibczeroxfer","port-id":"transfer","order":"unordered"},"strategy":{"type":"naive"}}
{"src":{"chain-id":"ibc-0","client-id":"ibconeclient","connection-id":"ibconeconnection","channel-id":"ibconexfer","port-id":"transfer","order":"unordered","version":"ics20-1"},"dst":{"chain-id":"ibc-1","client-id":"ibczeroclient","connection-id":"ibczeroconnection","channel-id":"ibczeroxfer","port-id":"transfer","order":"unordered","version":"ics20-1"},"strategy":{"type":"naive"}}
1 change: 1 addition & 0 deletions configs/akash/ibc-0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"key":"testkey","chain-id":"ibc-0","rpc-addr":"http://localhost:26657","account-prefix":"cosmos","gas-adjustment":1.5,"gas-prices":"0.025stake","trusting-period":"336h"}
1 change: 1 addition & 0 deletions configs/akash/ibc-1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"key":"testkey","chain-id":"ibc-1","rpc-addr":"http://localhost:26557","account-prefix":"akash","gas-adjustment":1.5,"gas-prices":"0.025stake", "trusting-period":"336h"}
1 change: 0 additions & 1 deletion configs/akash/ibc0.json

This file was deleted.

1 change: 0 additions & 1 deletion configs/akash/ibc1.json

This file was deleted.

2 changes: 1 addition & 1 deletion configs/demo/demo.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"src":{"chain-id":"ibc0","client-id":"ibconeclient","connection-id":"ibconeconnection","channel-id":"ibconexfer","port-id":"transfer","order":"unordered"},"dst":{"chain-id":"ibc1","client-id":"ibczeroclient","connection-id":"ibczeroconnection","channel-id":"ibczeroxfer","port-id":"transfer","order":"unordered"},"strategy":{"type":"naive"}}
{"src":{"chain-id":"ibc-0","client-id":"ibconeclient","connection-id":"ibconeconnection","channel-id":"ibconexfer","port-id":"transfer","order":"unordered","version":"ics20-1"},"dst":{"chain-id":"ibc-1","client-id":"ibczeroclient","connection-id":"ibczeroconnection","channel-id":"ibczeroxfer","port-id":"transfer","order":"unordered","version":"ics20-1"},"strategy":{"type":"naive"}}
1 change: 1 addition & 0 deletions configs/demo/ibc-0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"key":"testkey","chain-id":"ibc-0","rpc-addr":"http://localhost:26657","account-prefix":"cosmos","gas-adjustment":1.5,"gas-prices":"0.025stake","trusting-period":"336h"}
1 change: 1 addition & 0 deletions configs/demo/ibc-1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"key":"testkey","chain-id":"ibc-1","rpc-addr":"http://localhost:26557","account-prefix":"cosmos","gas-adjustment":1.5,"gas-prices":"0.025stake", "trusting-period":"336h"}
1 change: 0 additions & 1 deletion configs/demo/ibc0.json

This file was deleted.

1 change: 0 additions & 1 deletion configs/demo/ibc1.json

This file was deleted.

1 change: 1 addition & 0 deletions configs/four/ibc-0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"key":"testkey","chain-id":"ibc-0","rpc-addr":"http://localhost:46657","account-prefix":"cosmos","gas-adjustment":1.0,"trusting-period":"336h"}
1 change: 1 addition & 0 deletions configs/four/ibc-1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"key":"testkey","chain-id":"ibc-1","rpc-addr":"http://localhost:46658","account-prefix":"cosmos","gas-adjustment":1.0,"trusting-period":"336h"}
1 change: 1 addition & 0 deletions configs/four/ibc-2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"key":"testkey","chain-id":"ibc-2","rpc-addr":"http://localhost:46659","account-prefix":"cosmos","gas-adjustment":1.0,"trusting-period":"336h"}
1 change: 1 addition & 0 deletions configs/four/ibc-3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"key":"testkey","chain-id":"ibc-3","rpc-addr":"http://localhost:46660","account-prefix":"cosmos","gas-adjustment":1.0,"trusting-period":"336h"}
1 change: 0 additions & 1 deletion configs/four/ibc0.json

This file was deleted.

1 change: 0 additions & 1 deletion configs/four/ibc1.json

This file was deleted.

1 change: 0 additions & 1 deletion configs/four/ibc2.json

This file was deleted.

1 change: 0 additions & 1 deletion configs/four/ibc3.json

This file was deleted.

2 changes: 1 addition & 1 deletion configs/four/onetwo.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"src":{"chain-id":"ibc1","client-id":"acvfuvmoyy","connection-id":"pvsadpxocj","channel-id":"gxigiquvdc","port-id":"transfer"},"dst":{"chain-id":"ibc2","client-id":"vnsqzxwsfs","connection-id":"ikmrjehlzn","channel-id":"kzeiryubgz","port-id":"transfer"},"strategy":{"type":"naive"}}
{"src":{"chain-id":"ibc-1","client-id":"acvfuvmoyy","connection-id":"pvsadpxocj","channel-id":"gxigiquvdc","port-id":"transfer","version":"ics20-1"},"dst":{"chain-id":"ibc-2","client-id":"vnsqzxwsfs","connection-id":"ikmrjehlzn","channel-id":"kzeiryubgz","port-id":"transfer","version":"ics20-1"},"strategy":{"type":"naive"}}
2 changes: 1 addition & 1 deletion configs/four/threezero.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"src":{"chain-id":"ibc3","client-id":"zjyshingti","connection-id":"kygrljuplq","channel-id":"hdiooxmgry","port-id":"transfer"},"dst":{"chain-id":"ibc0","client-id":"vddpwioaua","connection-id":"wmvxarvtdj","channel-id":"mytxyocvdk","port-id":"transfer"},"strategy":{"type":"naive"}}
{"src":{"chain-id":"ibc-3","client-id":"zjyshingti","connection-id":"kygrljuplq","channel-id":"hdiooxmgry","port-id":"transfer","version":"ics20-1"},"dst":{"chain-id":"ibc-0","client-id":"vddpwioaua","connection-id":"wmvxarvtdj","channel-id":"mytxyocvdk","port-id":"transfer","version":"ics20-1"},"strategy":{"type":"naive"}}
2 changes: 1 addition & 1 deletion configs/four/twothree.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"src":{"chain-id":"ibc2","client-id":"jluiqkandb","connection-id":"mfyxyvmogc","channel-id":"ckcplvbklp","port-id":"transfer"},"dst":{"chain-id":"ibc3","client-id":"kvhumysqxf","connection-id":"kejwjeluuz","channel-id":"pcqmpcbqgi","port-id":"transfer"},"strategy":{"type":"naive"}}
{"src":{"chain-id":"ibc-2","client-id":"jluiqkandb","connection-id":"mfyxyvmogc","channel-id":"ckcplvbklp","port-id":"transfer","version":"ics20-1"},"dst":{"chain-id":"ibc-3","client-id":"kvhumysqxf","connection-id":"kejwjeluuz","channel-id":"pcqmpcbqgi","port-id":"transfer","version":"ics20-1"},"strategy":{"type":"naive"}}
2 changes: 1 addition & 1 deletion configs/four/zeroone.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"src":{"chain-id":"ibc0","client-id":"ytwwxbikra","connection-id":"znruvklbwm","channel-id":"spqkreyyhp","port-id":"transfer"},"dst":{"chain-id":"ibc1","client-id":"unfkygnnyq","connection-id":"jighhjlxjf","channel-id":"dkqbmdcyuk","port-id":"transfer"},"strategy":{"type":"naive"}}
{"src":{"chain-id":"ibc-0","client-id":"ytwwxbikra","connection-id":"znruvklbwm","channel-id":"spqkreyyhp","port-id":"transfer","version":"ics20-1"},"dst":{"chain-id":"ibc-1","client-id":"unfkygnnyq","connection-id":"jighhjlxjf","channel-id":"dkqbmdcyuk","port-id":"transfer","version":"ics20-1"},"strategy":{"type":"naive"}}
Loading

0 comments on commit 3a30839

Please sign in to comment.