diff --git a/.drone.jsonnet b/.drone.jsonnet new file mode 100644 index 00000000..87ce4402 --- /dev/null +++ b/.drone.jsonnet @@ -0,0 +1,73 @@ +local Image(name, image) = { + name: name, + image: "gcr.io/kosu-io/" + image, + pull: "always", + environment: { + WEB3_URI: "http://kosu-geth:8545", + WEB3_URI_WS: "ws://kosu-geth:8546", + } +}; + +local KosuNode(id) = Image("kosu-node-"+id, "go-kosu-ci:latest") { + detach: true, + depends_on: ["build-project"], + commands: [ + "cd packages/go-kosu", + './kosud -H ./testnet/node%(id)s -E ws://go-kosu-ci-geth:8546' %id, + ] +}; + +local KosuGeth(name) = Image(name, "kosu-test-geth:latest") { + ports: [8545, 8546] +}; + +{ + "kind": "pipeline", + "name": "tests", + "steps": [ + Image("prettier_project", "node-lts:latest") { + "commands": ["yarn prettier:ci"], + "depends_on": ["clone"], + }, + + Image("build-project", "node-lts:latest") { + "commands": [ + "yarn", + "yarn setup:ci", + "cd packages/kosu-system-contracts", + "yarn migrate:ci", + "WEB3_URI=http://go-kosu-ci-geth:8545 yarn migrate:ci" + ], + "depends_on": ["clone"] + }, + + Image("npm-tests", "node-lts:latest") { + "commands": [ "yarn test:ci" ], + "depends_on": [ "build-project" ], + }, + + Image("solidity", "node-lts:latest") { + "commands": [ "yarn contracts:test:ci" ], + "depends_on": [ "build-project" ], + }, + + KosuNode(0), KosuNode(1), KosuNode(2), KosuNode(3), + Image("go-kosu", "go-kosu-ci:latest") { + "commands": [ + "cd packages/go-kosu", + "export KOSU_TEST_NODES=$(pwd)/testnet/node0@kosu-node-1:26657,$(pwd)/testnet/node1@kosu-node-1:26657,$(pwd)/testnet/node2@kosu-node-1:26657,$(pwd)/testnet/node3@kosu-node-1:26657", + "make ci" + ], + "depends_on": ["build-project", "kosu-node-0", "kosu-node-1","kosu-node-2","kosu-node-3"] + }, + ], + + "services": [ + KosuGeth("kosu-geth"), + KosuGeth("go-kosu-ci-geth"), + ], + + "trigger": { + "event": [ "pull_request" ] + }, +} diff --git a/.drone.yml b/.drone.yml index f9660e59..02b20313 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,84 +1,152 @@ -# Kosu monorepo CI config file (last updated: 24 June 2019) - +--- kind: pipeline name: tests +platform: + os: linux + arch: amd64 + steps: - - name: prettier-project - image: gcr.io/kosu-io/node-lts:latest - pull: always - environment: - WEB3_URI: http://kosu-geth:8545 - commands: - - yarn prettier:ci - depends_on: - - clone +- name: prettier_project + pull: always + image: gcr.io/kosu-io/node-lts:latest + commands: + - yarn prettier:ci + environment: + WEB3_URI: http://kosu-geth:8545 + WEB3_URI_WS: ws://kosu-geth:8546 + depends_on: + - clone + +- name: build-project + pull: always + image: gcr.io/kosu-io/node-lts:latest + commands: + - yarn + - yarn setup:ci + - cd packages/kosu-system-contracts + - yarn migrate:ci + - WEB3_URI=http://go-kosu-ci-geth:8545 yarn migrate:ci + environment: + WEB3_URI: http://kosu-geth:8545 + WEB3_URI_WS: ws://kosu-geth:8546 + depends_on: + - clone + +- name: npm-tests + pull: always + image: gcr.io/kosu-io/node-lts:latest + commands: + - yarn test:ci + environment: + WEB3_URI: http://kosu-geth:8545 + WEB3_URI_WS: ws://kosu-geth:8546 + depends_on: + - build-project - - name: build-project - image: gcr.io/kosu-io/node-lts:latest - pull: always - environment: - WEB3_URI: http://kosu-geth:8545 - commands: - - yarn - - yarn setup:ci - - cd packages/kosu-system-contracts - - yarn migrate:ci - depends_on: - - clone +- name: solidity + pull: always + image: gcr.io/kosu-io/node-lts:latest + commands: + - yarn contracts:test:ci + environment: + WEB3_URI: http://kosu-geth:8545 + WEB3_URI_WS: ws://kosu-geth:8546 + depends_on: + - build-project - - name: npm-tests - image: gcr.io/kosu-io/node-lts:latest - pull: always - environment: - WEB3_URI: http://kosu-geth:8545 - commands: - - yarn test:ci - depends_on: - - build-project +- name: kosu-node-0 + pull: always + image: gcr.io/kosu-io/go-kosu-ci:latest + detach: true + commands: + - cd packages/go-kosu + - ./kosud -H ./testnet/node0 -E ws://go-kosu-ci-geth:8546 + environment: + WEB3_URI: http://kosu-geth:8545 + WEB3_URI_WS: ws://kosu-geth:8546 + depends_on: + - build-project - - name: solidity-tests - image: gcr.io/kosu-io/node-lts:latest - pull: always - environment: - WEB3_URI: http://kosu-geth:8545 - commands: - - yarn contracts:test:ci - depends_on: - - build-project +- name: kosu-node-1 + pull: always + image: gcr.io/kosu-io/go-kosu-ci:latest + detach: true + commands: + - cd packages/go-kosu + - ./kosud -H ./testnet/node1 -E ws://go-kosu-ci-geth:8546 + environment: + WEB3_URI: http://kosu-geth:8545 + WEB3_URI_WS: ws://kosu-geth:8546 + depends_on: + - build-project - - name: go-kosu - image: gcr.io/kosu-io/go-kosu-ci:latest - pull: always - environment: - WEB3_TEST_URI: ws://kosu-geth:8546 - commands: - - cd packages/go-kosu - - make ci - depends_on: - - build-project +- name: kosu-node-2 + pull: always + image: gcr.io/kosu-io/go-kosu-ci:latest + detach: true + commands: + - cd packages/go-kosu + - ./kosud -H ./testnet/node2 -E ws://go-kosu-ci-geth:8546 + environment: + WEB3_URI: http://kosu-geth:8545 + WEB3_URI_WS: ws://kosu-geth:8546 + depends_on: + - build-project + +- name: kosu-node-3 + pull: always + image: gcr.io/kosu-io/go-kosu-ci:latest + detach: true + commands: + - cd packages/go-kosu + - ./kosud -H ./testnet/node3 -E ws://go-kosu-ci-geth:8546 + environment: + WEB3_URI: http://kosu-geth:8545 + WEB3_URI_WS: ws://kosu-geth:8546 + depends_on: + - build-project + +- name: go-kosu + pull: always + image: gcr.io/kosu-io/go-kosu-ci:latest + commands: + - cd packages/go-kosu + - export KOSU_TEST_NODES=$(pwd)/testnet/node0@kosu-node-1:26657,$(pwd)/testnet/node1@kosu-node-1:26657,$(pwd)/testnet/node2@kosu-node-1:26657,$(pwd)/testnet/node3@kosu-node-1:26657 + - make ci + environment: + WEB3_URI: http://kosu-geth:8545 + WEB3_URI_WS: ws://kosu-geth:8546 + depends_on: + - build-project + - kosu-node-0 + - kosu-node-1 + - kosu-node-2 + - kosu-node-3 services: - - name: kosu-geth - image: gcr.io/kosu-io/kosu-test-geth:latest - pull: always - ports: - - 8545 - - 8546 +- name: kosu-geth + pull: always + image: gcr.io/kosu-io/kosu-test-geth:latest + environment: + WEB3_URI: http://kosu-geth:8545 + WEB3_URI_WS: ws://kosu-geth:8546 + ports: + - 8545 + - 8546 + +- name: go-kosu-ci-geth + pull: always + image: gcr.io/kosu-io/kosu-test-geth:latest + environment: + WEB3_URI: http://kosu-geth:8545 + WEB3_URI_WS: ws://kosu-geth:8546 + ports: + - 8545 + - 8546 trigger: - event: - - pull_request + event: + - pull_request -# UNTESTED -# --- -# kind: pipeline -# name: go-kosu-release -# -# release: -# image: golang:1.12 -# secrets: [github_token] -# commands: -# curl -sL https://git.io/goreleaser | bash -# when: -# event: tag +... diff --git a/packages/go-kosu/Dockerfile.compose b/packages/go-kosu/Dockerfile.compose index adab0a63..aa90eae8 100644 --- a/packages/go-kosu/Dockerfile.compose +++ b/packages/go-kosu/Dockerfile.compose @@ -1,11 +1,11 @@ FROM golang:1.12 WORKDIR /go-kosu -COPY kosud . -COPY kosu-cli . -COPY ./testnet/ ./testnet/ +# COPY kosud . +# COPY kosu-cli . +# COPY ./testnet/ ./testnet/ -#COPY . . -#RUN make +COPY . . +RUN go build -o kosud ./cmd/kosud CMD ./kosud diff --git a/packages/go-kosu/Makefile b/packages/go-kosu/Makefile index fec7dd6b..2143f624 100644 --- a/packages/go-kosu/Makefile +++ b/packages/go-kosu/Makefile @@ -1,5 +1,4 @@ -GOTEST_FLAGS ?= -GOTEST_TAGS ?= integration +GOTEST_FLAGS ?= -v GOTEST = go test ./... ${GOTEST_FLAGS} KOSU_VERSION ?= $(shell jq -r .version package.json) @@ -27,7 +26,7 @@ test-fast: $(GOTEST) -failfast test: - $(GOTEST) -race -tags=$(GOTEST_TAGS) + $(GOTEST) lint: $(GOLINT) diff --git a/packages/go-kosu/abci/app.go b/packages/go-kosu/abci/app.go index 4b8ad462..b778b930 100644 --- a/packages/go-kosu/abci/app.go +++ b/packages/go-kosu/abci/app.go @@ -71,7 +71,7 @@ func (app *App) NewClient() (*Client, error) { return nil, err } - return NewHTTPClient(url, key), nil + return NewHTTPClient(url, key) } // Query queries the application state using the store.Query method @@ -301,5 +301,5 @@ func (app *App) DeliverTx(req []byte) abci.ResponseDeliverTx { fmt.Printf("Unknown Tx: %t", tx.GetData()) } - return abci.ResponseDeliverTx{Code: 1, Info: "Unknown Transaction type"} + return abci.ResponseDeliverTx{Code: 1, Log: "Unknown Transaction type"} } diff --git a/packages/go-kosu/abci/client.go b/packages/go-kosu/abci/client.go index 881a89a2..97871ccd 100644 --- a/packages/go-kosu/abci/client.go +++ b/packages/go-kosu/abci/client.go @@ -4,6 +4,7 @@ import ( "context" "errors" + "github.com/gogo/protobuf/proto" "github.com/tendermint/tendermint/libs/pubsub/query" "github.com/tendermint/tendermint/rpc/client" rpctypes "github.com/tendermint/tendermint/rpc/core/types" @@ -33,9 +34,13 @@ func NewClient(c client.Client, key []byte) *Client { } // NewHTTPClient calls NewClient using a HTTPClient as ABCClient -func NewHTTPClient(addr string, key []byte) *Client { +func NewHTTPClient(addr string, key []byte) (*Client, error) { c := client.NewHTTP(addr, "/websocket") - return NewClient(c, key) + if err := c.Start(); err != nil { + return nil, err + } + + return NewClient(c, key), nil } // BroadcastTxAsync will return right away without waiting to hear if the transaction is even valid @@ -91,24 +96,13 @@ func (c *Client) Subscribe(ctx context.Context, q string) (<-chan rpctypes.Resul return nil, nil, err } - // Start WS if not yet - if httpC, ok := c.Client.(*client.HTTP); ok { - if !httpC.IsRunning() { - if err := httpC.Start(); err != nil { - return nil, nil, err - } - } - } - ch, err := c.Client.Subscribe(ctx, "kosu", q) if err != nil { return nil, nil, err } closer := func() { - if httpC, ok := c.Client.(*client.HTTP); ok { - _ = httpC.Stop() - } + _ = c.Client.Unsubscribe(ctx, "kosu", q) } return ch, closer, nil @@ -139,6 +133,27 @@ func (c *Client) QueryConsensusParams() (*types.ConsensusParams, error) { return &pb, nil } +// QueryLastEvent performs a ABCI Query to "/lastevent". +// `lastevent` keeps track of the last block height recorded from the Ethereum chain +func (c *Client) QueryLastEvent() (uint64, error) { + out, err := c.ABCIQuery("/chain/key", []byte("lastevent")) + if err != nil { + return 0, err + } + res := out.Response + + if res.IsErr() { + return 0, errors.New(res.GetLog()) + } + + if len(res.Value) == 0 { + return 0, nil + } + + buf := proto.NewBuffer(res.Value) + return buf.DecodeFixed64() +} + // QueryPoster performs a ABCI Query to "/posters/" func (c *Client) QueryPoster(addr string) (*types.Poster, error) { var pb types.Poster diff --git a/packages/go-kosu/abci/witness.go b/packages/go-kosu/abci/witness.go index 4e04357f..516054c3 100644 --- a/packages/go-kosu/abci/witness.go +++ b/packages/go-kosu/abci/witness.go @@ -33,8 +33,8 @@ func (app *App) deliverWitnessTx(tx *types.TransactionWitness, nodeID []byte) ab } func (app *App) pruneWitnessTxs(block uint64) { + params := app.store.ConsensusParams() fn := func(tx *types.TransactionWitness) { - params := app.store.ConsensusParams() if block-tx.Block >= params.BlocksBeforePruning { app.log.Debug("Pruning tx", "id", hex.EncodeToString(tx.Id)) app.store.DeleteWitnessTx(tx.Id) diff --git a/packages/go-kosu/cmd/kosu-cli/main.go b/packages/go-kosu/cmd/kosu-cli/main.go index 1757b2b6..25ba48fa 100644 --- a/packages/go-kosu/cmd/kosu-cli/main.go +++ b/packages/go-kosu/cmd/kosu-cli/main.go @@ -16,7 +16,7 @@ import ( ) func main() { - var client abci.Client + var client *abci.Client rootCmd := &cobra.Command{ Use: "kosu-cli", @@ -46,11 +46,11 @@ func main() { addr := cmd.Flag("abci").Value.String() // update the client - client = *abci.NewHTTPClient(addr, key) - return nil + client, err = abci.NewHTTPClient(addr, key) + return err } - abci := cli.New(&client) + abci := cli.New(client) tx := &cobra.Command{ Use: "tx", diff --git a/packages/go-kosu/cmd/kosud/main.go b/packages/go-kosu/cmd/kosud/main.go index f47aeb01..ff731f4b 100644 --- a/packages/go-kosu/cmd/kosud/main.go +++ b/packages/go-kosu/cmd/kosud/main.go @@ -43,9 +43,12 @@ func newDB(dir string, debug bool) (db.DB, error) { } func startWitness(ctx context.Context, ethAddr string, nodeAddr string, key []byte, logger log.Logger) error { - client := abci.NewHTTPClient(nodeAddr, key) - p, err := witness.NewEthereumProvider(ethAddr) + client, err := abci.NewHTTPClient(nodeAddr, key) + if err != nil { + return nil + } + p, err := witness.NewEthereumProvider(ethAddr) if err != nil { return err } diff --git a/packages/go-kosu/docker-compose.yml b/packages/go-kosu/docker-compose.yml index 0857d949..07c33f15 100644 --- a/packages/go-kosu/docker-compose.yml +++ b/packages/go-kosu/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: node0: - container_name: node0 + container_name: kosu-node-0 build: context: . dockerfile: Dockerfile.compose @@ -14,7 +14,7 @@ services: ipv4_address: 192.167.10.2 node1: - container_name: node1 + container_name: kosu-node-1 build: context: . dockerfile: Dockerfile.compose @@ -26,7 +26,7 @@ services: ipv4_address: 192.167.10.3 node2: - container_name: node2 + container_name: kosu-node-2 build: context: . dockerfile: Dockerfile.compose @@ -38,7 +38,7 @@ services: ipv4_address: 192.167.10.4 node3: - container_name: node3 + container_name: kosu-node-3 build: context: . dockerfile: Dockerfile.compose @@ -55,5 +55,4 @@ networks: ipam: driver: default config: - - - subnet: 192.167.10.0/16 + - subnet: 192.167.10.0/16 diff --git a/packages/go-kosu/go.mod b/packages/go-kosu/go.mod index 34fba455..3cca2d18 100644 --- a/packages/go-kosu/go.mod +++ b/packages/go-kosu/go.mod @@ -13,7 +13,7 @@ require ( github.com/ethereum/go-ethereum v1.8.27 github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a // indirect github.com/gogo/protobuf v1.2.1 - github.com/golang/protobuf v1.3.1 + github.com/golang/protobuf v1.3.2 github.com/google/gofuzz v1.0.0 // indirect github.com/hashicorp/golang-lru v0.5.1 // indirect github.com/huin/goupnp v1.0.0 // indirect @@ -29,13 +29,15 @@ require ( github.com/spf13/cobra v0.0.3 github.com/spf13/viper v1.3.2 github.com/stretchr/testify v1.3.0 - github.com/syndtr/goleveldb v1.0.0 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965 // indirect github.com/tendermint/iavl v0.12.2 // indirect github.com/tendermint/tendermint v0.31.5 github.com/tidwall/gjson v1.3.0 golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 + golang.org/x/net v0.0.0-20190628185345-da137c7871d7 // indirect golang.org/x/tools v0.0.0-20190703212419-2214986f1668 // indirect - google.golang.org/grpc v1.20.1 // indirect + google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2 // indirect + google.golang.org/grpc v1.22.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/urfave/cli.v1 v1.20.0 // indirect ) diff --git a/packages/go-kosu/go.sum b/packages/go-kosu/go.sum index aa8c05f7..4102f77c 100644 --- a/packages/go-kosu/go.sum +++ b/packages/go-kosu/go.sum @@ -49,14 +49,17 @@ github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9r github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/go-ethereum v1.8.27 h1:d+gkiLaBDk5fn3Pe/xNVaMrB/ozI+AUB2IlVBp29IrY= github.com/ethereum/go-ethereum v1.8.27/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY= github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a h1:1znxn4+q2MrEdTk1eCk6KIV3muTYVclBIB6CTVR/zBc= github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-kit/kit v0.6.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= @@ -73,9 +76,12 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -84,6 +90,7 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= @@ -114,6 +121,7 @@ github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= @@ -151,6 +159,7 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jOqq0gIVUe6Yk0/QMZ640k6NvkxcBf+8= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU= @@ -174,12 +183,14 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykE github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4= github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.1 h1:qgMbHoJbPbw579P+1zVY+6n4nIFuIchaIjzZ/I/Yq8M= github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= @@ -188,6 +199,7 @@ github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmq github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.0.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/spf13/viper v1.0.3/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= @@ -199,15 +211,19 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/syndtr/goleveldb v0.0.0-20180708030551-c4c61651e9e3/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965 h1:1oFLiOyVl+W7bnBzGhf7BbIv9loSFQcieWWYIjLqcAw= +github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U= github.com/tendermint/go-amino v0.14.1 h1:o2WudxNfdLNBwMyl2dqOJxiro5rfrEaU0Ugs6offJMk= github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso= github.com/tendermint/iavl v0.12.1/go.mod h1:EoKMMv++tDOL5qKKVnoIqtVPshRrEPeJ0WsgDOLAauM= github.com/tendermint/iavl v0.12.2 h1:Ls5p5VINCM1HRT9g5Vvs2zmDOCU/CCIvIHzd/pZ8P0E= github.com/tendermint/iavl v0.12.2/go.mod h1:EoKMMv++tDOL5qKKVnoIqtVPshRrEPeJ0WsgDOLAauM= +github.com/tendermint/tendermint v0.31.2-0.20190822092307-7b2d018f847e/go.mod h1:ZK2c29jl1QRYznIRyRWRDsmm1yvtPzBRT00x4t1JToY= github.com/tendermint/tendermint v0.31.5 h1:vTet8tCq3B9/J9Yo11dNZ8pOB7NtSy++bVSfkP4KzR4= github.com/tendermint/tendermint v0.31.5/go.mod h1:ymcPyWblXCplCPQjbOYbrF1fWnpslATMVqiGgWbZrlc= github.com/tendermint/tendermint v0.32.1 h1:J8ddXMbCmG6GZjdCl/N1wgdXDU9uO91J2Y5CA9xYfGo= +github.com/tendermint/tm-db v0.1.1/go.mod h1:0cPKWu2Mou3IlxecH+MEUSYc1Ch537alLe6CpFrKzgw= github.com/tidwall/gjson v1.3.0 h1:kfpsw1W3trbg4Xm6doUtqSl9+LhLB6qJ9PkltVAQZYs= github.com/tidwall/gjson v1.3.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc= @@ -217,6 +233,7 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -235,6 +252,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2eP golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -258,14 +277,19 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384 h1:TFlARGu6Czu1z7q93HTxcP1P+/ZFC/IKythI5RzrnRg= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190703212419-2214986f1668 h1:3LJOYcj2ObWSZJXX21oGIIPv5SaOoi5JkzQTWnCXRhg= golang.org/x/tools v0.0.0-20190703212419-2214986f1668/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2 h1:67iHsV9djwGdZpdZNbLuQj6FOzCaZe3w+vhLjn5AcFA= +google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.22.0 h1:J0UbZOIrCAl+fpTOf8YLs4dJo8L/owV4LYVtAXQoPkw= +google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= @@ -282,3 +306,4 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/packages/go-kosu/rpc/cmd.go b/packages/go-kosu/rpc/cmd.go index 7acd75e6..9ccb1d0a 100644 --- a/packages/go-kosu/rpc/cmd.go +++ b/packages/go-kosu/rpc/cmd.go @@ -49,8 +49,11 @@ func NewCommand() *cobra.Command { return nil }, - Run: func(cmd *cobra.Command, args []string) { - client := abci.NewHTTPClient(url, key) + RunE: func(cmd *cobra.Command, args []string) error { + client, err := abci.NewHTTPClient(url, key) + if err != nil { + return err + } srv := NewServer(client) wg := sync.WaitGroup{} @@ -74,6 +77,7 @@ func NewCommand() *cobra.Command { }() } wg.Wait() + return nil }, } diff --git a/packages/go-kosu/testnet/node0/config/config.toml b/packages/go-kosu/testnet/node0/config/config.toml index c2c74d20..e526129c 100644 --- a/packages/go-kosu/testnet/node0/config/config.toml +++ b/packages/go-kosu/testnet/node0/config/config.toml @@ -22,7 +22,7 @@ db_backend = "leveldb" db_dir = "data" # Output level for logging, including package level options -log_level = "app:info,*:error" +log_level = "app:debug,*:error" # Output format: 'plain' (colored text) or 'json' log_format = "plain" @@ -142,7 +142,7 @@ external_address = "" seeds = "" # Comma separated list of nodes to keep persistent connections to -persistent_peers = "4858315c384a60d3664f8c2afa4270e8ef2e1864@192.167.10.2:26656,73df76c913c65763cb37038758e1e6e9b6e55e9b@192.167.10.3:26656,06baf318001f3c0694560a24c849b2a0a58ec233@192.167.10.4:26656,386ee942c2acd02092783d20105ac84caeab7903@192.167.10.5:26656" +persistent_peers = "4858315c384a60d3664f8c2afa4270e8ef2e1864@kosu-node-0:26656,73df76c913c65763cb37038758e1e6e9b6e55e9b@kosu-node-1:26656,06baf318001f3c0694560a24c849b2a0a58ec233@kosu-node-2:26656,386ee942c2acd02092783d20105ac84caeab7903@kosu-node-3:26656" # UPNP port forwarding upnp = false diff --git a/packages/go-kosu/testnet/node0/config/genesis.json b/packages/go-kosu/testnet/node0/config/genesis.json index c4a3e84b..48ba7f39 100644 --- a/packages/go-kosu/testnet/node0/config/genesis.json +++ b/packages/go-kosu/testnet/node0/config/genesis.json @@ -43,7 +43,8 @@ "app_state": { "ConsensusParams": { "PeriodLimit": 100000, - "PeriodLength": 10 + "PeriodLength": 10, + "BlocksBeforePruning": 10 } } } diff --git a/packages/go-kosu/testnet/node1/config/config.toml b/packages/go-kosu/testnet/node1/config/config.toml index 00db51cf..7e593093 100644 --- a/packages/go-kosu/testnet/node1/config/config.toml +++ b/packages/go-kosu/testnet/node1/config/config.toml @@ -142,7 +142,7 @@ external_address = "" seeds = "" # Comma separated list of nodes to keep persistent connections to -persistent_peers = "4858315c384a60d3664f8c2afa4270e8ef2e1864@192.167.10.2:26656,73df76c913c65763cb37038758e1e6e9b6e55e9b@192.167.10.3:26656,06baf318001f3c0694560a24c849b2a0a58ec233@192.167.10.4:26656,386ee942c2acd02092783d20105ac84caeab7903@192.167.10.5:26656" +persistent_peers = "4858315c384a60d3664f8c2afa4270e8ef2e1864@kosu-node-0:26656,73df76c913c65763cb37038758e1e6e9b6e55e9b@kosu-node-1:26656,06baf318001f3c0694560a24c849b2a0a58ec233@kosu-node-2:26656,386ee942c2acd02092783d20105ac84caeab7903@kosu-node-3:26656" # UPNP port forwarding upnp = false diff --git a/packages/go-kosu/testnet/node1/config/genesis.json b/packages/go-kosu/testnet/node1/config/genesis.json index c4a3e84b..48ba7f39 100644 --- a/packages/go-kosu/testnet/node1/config/genesis.json +++ b/packages/go-kosu/testnet/node1/config/genesis.json @@ -43,7 +43,8 @@ "app_state": { "ConsensusParams": { "PeriodLimit": 100000, - "PeriodLength": 10 + "PeriodLength": 10, + "BlocksBeforePruning": 10 } } } diff --git a/packages/go-kosu/testnet/node2/config/config.toml b/packages/go-kosu/testnet/node2/config/config.toml index 00db51cf..7e593093 100644 --- a/packages/go-kosu/testnet/node2/config/config.toml +++ b/packages/go-kosu/testnet/node2/config/config.toml @@ -142,7 +142,7 @@ external_address = "" seeds = "" # Comma separated list of nodes to keep persistent connections to -persistent_peers = "4858315c384a60d3664f8c2afa4270e8ef2e1864@192.167.10.2:26656,73df76c913c65763cb37038758e1e6e9b6e55e9b@192.167.10.3:26656,06baf318001f3c0694560a24c849b2a0a58ec233@192.167.10.4:26656,386ee942c2acd02092783d20105ac84caeab7903@192.167.10.5:26656" +persistent_peers = "4858315c384a60d3664f8c2afa4270e8ef2e1864@kosu-node-0:26656,73df76c913c65763cb37038758e1e6e9b6e55e9b@kosu-node-1:26656,06baf318001f3c0694560a24c849b2a0a58ec233@kosu-node-2:26656,386ee942c2acd02092783d20105ac84caeab7903@kosu-node-3:26656" # UPNP port forwarding upnp = false diff --git a/packages/go-kosu/testnet/node2/config/genesis.json b/packages/go-kosu/testnet/node2/config/genesis.json index c4a3e84b..48ba7f39 100644 --- a/packages/go-kosu/testnet/node2/config/genesis.json +++ b/packages/go-kosu/testnet/node2/config/genesis.json @@ -43,7 +43,8 @@ "app_state": { "ConsensusParams": { "PeriodLimit": 100000, - "PeriodLength": 10 + "PeriodLength": 10, + "BlocksBeforePruning": 10 } } } diff --git a/packages/go-kosu/testnet/node3/config/config.toml b/packages/go-kosu/testnet/node3/config/config.toml index 00db51cf..7e593093 100644 --- a/packages/go-kosu/testnet/node3/config/config.toml +++ b/packages/go-kosu/testnet/node3/config/config.toml @@ -142,7 +142,7 @@ external_address = "" seeds = "" # Comma separated list of nodes to keep persistent connections to -persistent_peers = "4858315c384a60d3664f8c2afa4270e8ef2e1864@192.167.10.2:26656,73df76c913c65763cb37038758e1e6e9b6e55e9b@192.167.10.3:26656,06baf318001f3c0694560a24c849b2a0a58ec233@192.167.10.4:26656,386ee942c2acd02092783d20105ac84caeab7903@192.167.10.5:26656" +persistent_peers = "4858315c384a60d3664f8c2afa4270e8ef2e1864@kosu-node-0:26656,73df76c913c65763cb37038758e1e6e9b6e55e9b@kosu-node-1:26656,06baf318001f3c0694560a24c849b2a0a58ec233@kosu-node-2:26656,386ee942c2acd02092783d20105ac84caeab7903@kosu-node-3:26656" # UPNP port forwarding upnp = false diff --git a/packages/go-kosu/testnet/node3/config/genesis.json b/packages/go-kosu/testnet/node3/config/genesis.json index c4a3e84b..48ba7f39 100644 --- a/packages/go-kosu/testnet/node3/config/genesis.json +++ b/packages/go-kosu/testnet/node3/config/genesis.json @@ -43,7 +43,8 @@ "app_state": { "ConsensusParams": { "PeriodLimit": 100000, - "PeriodLength": 10 + "PeriodLength": 10, + "BlocksBeforePruning": 10 } } } diff --git a/packages/go-kosu/tests/helpers.go b/packages/go-kosu/tests/helpers.go new file mode 100644 index 00000000..ff9fdcbd --- /dev/null +++ b/packages/go-kosu/tests/helpers.go @@ -0,0 +1,25 @@ +package tests + +import ( + "math/rand" + "os" + "testing" +) + +func envOrSkip(t *testing.T, env string) string { + v := os.Getenv(env) + if v == "" { + t.Skipf("Integration test suite requires '%s' to be exported", env) + } + return v +} + +func randomHex(size int) string { + var alphabet = []rune("abcdefABCDEF0123456789") + + b := make([]rune, size) + for i := range b { + b[i] = alphabet[rand.Intn(len(alphabet))] + } + return string(b) +} diff --git a/packages/go-kosu/tests/order_test.go b/packages/go-kosu/tests/order_test.go index a5151ef1..f78631e6 100644 --- a/packages/go-kosu/tests/order_test.go +++ b/packages/go-kosu/tests/order_test.go @@ -8,85 +8,92 @@ import ( "go-kosu/abci/types" "go-kosu/rpc" - . "github.com/smartystreets/goconvey/convey" "github.com/stretchr/testify/require" ) -func (s *Suite) TestOrderTx() { - addr := "0xe3ec7592166d0145b9677f5f45dd1bd95ffe6596" - order := `{"subContract":"0xebe8fdf63db77e3b41b0aec8208c49fa46569606","maker":"0xe3ec7592166d0145b9677f5f45dd1bd95ffe6596","arguments":{"maker":[{"datatype":"address","name":"signer"},{"datatype":"address","name":"signerToken"},{"datatype":"uint","name":"signerTokenCount"},{"datatype":"address","name":"buyerToken"},{"datatype":"uint","name":"buyerTokenCount"},{"datatype":"signature","name":"signature","signatureFields":[0,1,2,3,4]}],"taker":[{"datatype":"uint","name":"tokensToBuy"}]},"makerValues":{"signer":"0xe3ec7592166d0145b9677f5f45dd1bd95ffe6596","signerToken":"0xbFB972996fd7658099a95E6290e8B0fa46b9BDd5","signerTokenCount":"1000","buyer":"0xbcd1c49f4e54cca1a0a59ac21b7eb90f07970a3a","buyerToken":"0x92cBc0Bec2121f55E84bC331f096b7dAAe5A5ddA","buyerTokenCount":"1000","signature":"0xce84772cbbbe5a844c9002e6d54e53d72830b890ff1ea1521cbd86faada28aa136997b5cd3cafd85e887a9d6fc25bb2bfbe03fc6319d371b2c976f3374bcd8c300"},"makerSignature":"0xce84772cbbbe5a844c9002e6d54e53d72830b890ff1ea1521cbd86faada28aa136997b5cd3cafd85e887a9d6fc25bb2bfbe03fc6319d371b2c976f3374bcd8c300","posterSignature":"0xc3550b7ceab610e638dfb1b33e5cf7aaf9490854197328eadbe8ac049adef7510a07a0ea046fa1d410c5cc1048828152b9368a8d8925f8f0072192ebfe1bbb3101"}` // nolint:lll +func NewOrderTx(t *testing.T) *types.TransactionOrder { + // nolint:lll + order := `{ + "subContract":"0xebe8fdf63db77e3b41b0aec8208c49fa46569606", + "maker":"0xe3ec7592166d0145b9677f5f45dd1bd95ffe6596", + "arguments":{"maker":[{"datatype":"address","name":"signer"},{"datatype":"address","name":"signerToken"},{"datatype":"uint","name":"signerTokenCount"},{"datatype":"address","name":"buyerToken"},{"datatype":"uint","name":"buyerTokenCount"},{"datatype":"signature","name":"signature","signatureFields":[0,1,2,3,4]}],"taker":[{"datatype":"uint","name":"tokensToBuy"}]}, + "makerValues":{ + "signer":"0xe3ec7592166d0145b9677f5f45dd1bd95ffe6596", + "signerToken":"0xbFB972996fd7658099a95E6290e8B0fa46b9BDd5", + "signerTokenCount":"1000", + "buyer":"0xbcd1c49f4e54cca1a0a59ac21b7eb90f07970a3a", + "buyerToken":"0x92cBc0Bec2121f55E84bC331f096b7dAAe5A5ddA", + "buyerTokenCount":"1000", + "signature":"0xce84772cbbbe5a844c9002e6d54e53d72830b890ff1ea1521cbd86faada28aa136997b5cd3cafd85e887a9d6fc25bb2bfbe03fc6319d371b2c976f3374bcd8c300" + }, + "makerSignature":"0xce84772cbbbe5a844c9002e6d54e53d72830b890ff1ea1521cbd86faada28aa136997b5cd3cafd85e887a9d6fc25bb2bfbe03fc6319d371b2c976f3374bcd8c300","posterSignature":"0xc3550b7ceab610e638dfb1b33e5cf7aaf9490854197328eadbe8ac049adef7510a07a0ea046fa1d410c5cc1048828152b9368a8d8925f8f0072192ebfe1bbb3101"} + ` tx := &types.TransactionOrder{} - require.NoError(s.T(), json.Unmarshal([]byte(order), tx)) - - GivenABCIServer(s.T(), s, func(t *testing.T) { - Convey("And an existing poster with Limit > 0", func() { - posterTx := &types.TransactionWitness{ - Subject: types.TransactionWitness_POSTER, - Address: addr, - Amount: types.NewBigIntFromInt(10), - } - BroadcastTxCommit(t, s.client, posterTx) - - BroadcastNextRebalance(t, s.client) - - Convey("When sending an OrderTx", func() { - poster, err := s.client.QueryPoster(addr) - require.NoError(t, err) - BroadcastTxCommit(t, s.client, tx) - - Convey("Limit should be decremented by 1", func() { - found, err := s.client.QueryPoster(addr) - require.NoError(t, err) - - So(poster.Limit, ShouldEqual, found.Limit+1) - }) - }) - - Convey("Given a RPC client", func() { - client := rpc.DialInProc( - rpc.NewServer(s.client), - ) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - ch := make(chan *types.TransactionOrder) - defer close(ch) - - sub, err := client.Subscribe(ctx, "kosu", ch, "newOrders") - require.NoError(t, err) - defer sub.Unsubscribe() - - Convey("And a OrderTx is sent", func() { - BroadcastTxCommit(t, s.client, tx) - - Convey("Event should be sent and matches the Broadcasted Tx", func() { - event := <-ch - So(event.String(), ShouldEqual, tx.String()) - }) - - Convey("TotalOrders is updated", func() { - var total uint64 - err := client.Call(&total, "kosu_totalOrders") - require.NoError(t, err) - So(total, ShouldEqual, 1) - }) - }) - - }) - - Convey("And a non existing poster", func() { - tx.Maker = "0x404" - - Convey("When sending an OrderTx", func() { - res, err := s.client.BroadcastTxSync(tx) - require.NoError(t, err) - - Convey("Tx should be rejected", func() { - So(res.Code, ShouldNotEqual, 0) - }) - }) - }) - }) + err := json.Unmarshal([]byte(order), tx) + require.NoError(t, err) + + // this is used to avoid TM complains about duplicated tx in cache + tx.MakerValues["nonce"] = randomHex(128) + return tx +} + +func (suite *IntegrationTestSuite) TestOrders() { + tx := NewOrderTx(suite.T()) + + last, err := suite.Client().QueryLastEvent() + suite.Require().NoError(err) + + // setup a poster with a balance + posterTx := &types.TransactionWitness{ + Subject: types.TransactionWitness_POSTER, + Address: tx.Maker, + Amount: types.NewBigIntFromInt(10), + Block: last + 1, + } + suite.WithConfirmations(posterTx) + suite.WaitForNewBlock() + suite.BroadcastNextRebalance() + + poster, err := suite.Client().QueryPoster(tx.Maker) + suite.Require().NoError(err) + + suite.Run("LimitUpdate", func() { + suite.BroadcastTxCommit(tx) + + found, err := suite.Client().QueryPoster(tx.Maker) + suite.Require().NoError(err) + + suite.Equal(poster.Limit, found.Limit+1) }) + + suite.Run("UnknownPoster", func() { + tx := NewOrderTx(suite.T()) + tx.Maker = "0x404" + res, err := suite.Client().BroadcastTxSync(tx) + suite.Require().NoError(err) + + suite.NotEqual(0, res.Code) + }) + + suite.Run("RPCEvents", func() { + tx := NewOrderTx(suite.T()) + rpcClient := rpc.DialInProc( + rpc.NewServer(suite.Client()), + ) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ch := make(chan *types.TransactionOrder) + sub, err := rpcClient.Subscribe(ctx, "kosu", ch, "newOrders") + suite.Require().NoError(err) + defer sub.Unsubscribe() + + suite.BroadcastTxSync(tx) + + event := <-ch + suite.Equal(tx.String(), event.String()) + }) + } diff --git a/packages/go-kosu/tests/rebalance_test.go b/packages/go-kosu/tests/rebalance_test.go index a7a4388b..1d787d51 100644 --- a/packages/go-kosu/tests/rebalance_test.go +++ b/packages/go-kosu/tests/rebalance_test.go @@ -1,91 +1,32 @@ package tests import ( - "context" "go-kosu/abci/types" - "go-kosu/witness" - "testing" - - . "github.com/smartystreets/goconvey/convey" - "github.com/stretchr/testify/require" ) -func (s *Suite) TestRebalance() { - GivenABCIServer(s.T(), s, func(t *testing.T) { - Convey("And an initial Rebalance Tx", func() { - tx := &types.TransactionRebalance{ - RoundInfo: &types.RoundInfo{ - Number: 1, - StartsAt: 100, - EndsAt: 110, - }, - } - - BroadcastTxCommit(t, s.client, tx) - - Convey("RoundInfo should be updated", func() { - info, err := s.client.QueryRoundInfo() - So(err, ShouldBeNil) - - So(info.Number, ShouldEqual, tx.RoundInfo.Number) - So(info.StartsAt, ShouldEqual, tx.RoundInfo.StartsAt) - So(info.EndsAt, ShouldEqual, tx.RoundInfo.EndsAt) - }) - }) - - Convey("Next Tx's .RoundInfo.Number gap is > 1 ", func() { - tx := &types.TransactionRebalance{ - RoundInfo: &types.RoundInfo{Number: 10}, - } +func (suite *IntegrationTestSuite) TestRebalance() { + suite.Run("ValidRoundInfo", func() { + tx := &types.TransactionRebalance{ + RoundInfo: suite.NextRoundInfo(), + } + suite.BroadcastTxCommit(tx) - res, err := s.client.BroadcastTxSync(tx) - So(err, ShouldBeNil) + round, err := suite.Client().QueryRoundInfo() + suite.Require().NoError(err) - Convey("Tx should be rejected", func() { - So(res.Code, ShouldEqual, 1) - So(res.Log, ShouldContainSubstring, "proposal rejected") - }) - }) + suite.Equal(tx.RoundInfo.String(), round.String(), "RoundInfo should be updated") }) -} -func (s *Suite) TestRebalanceWitness() { - GivenABCIServer(s.T(), s, func(t *testing.T) { + suite.Run("InvalidRoundInfo", func() { tx := &types.TransactionRebalance{ - RoundInfo: &types.RoundInfo{ - StartsAt: 10, - EndsAt: 20, - }, + RoundInfo: suite.NextRoundInfo(), } + tx.RoundInfo.Number += 10 - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - // Create the witness - w := witness.New(s.client, witness.NewMockProvider(0), witness.DefaultOptions) - require.NoError(t, w.WithLogger(nil).Start(ctx)) - - Convey("When a set of Rebalance Tx are committed", func() { - roundNumber := []uint64{1, 2, 3} - for _, n := range roundNumber { - tx.RoundInfo.Number = n - - BroadcastTxCommit(t, s.client, tx) - - tx.RoundInfo.StartsAt = tx.RoundInfo.EndsAt - tx.RoundInfo.EndsAt += 10 - } - - // Wait until the next block is minted - sub, closer, err := s.client.Subscribe(ctx, "tm.event = 'NewBlock'") - So(err, ShouldBeNil) - defer closer() - - <-sub + res, err := suite.Client().BroadcastTxSync(tx) + suite.Require().NoError(err) - Convey("It should update the local witness state", func() { - So(w.RoundInfo().Number, ShouldEqual, 3) - }) - }) + suite.EqualValues(1, res.Code, "Proposal should be rejected") + suite.Contains(res.Log, "proposal rejected") }) } diff --git a/packages/go-kosu/tests/run_test.go b/packages/go-kosu/tests/run_test.go deleted file mode 100644 index f76b1d48..00000000 --- a/packages/go-kosu/tests/run_test.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build integration - -package tests - -import ( - "testing" - - "github.com/stretchr/testify/suite" -) - -func TestIntegration(t *testing.T) { - suite.Run(t, new(Suite)) -} diff --git a/packages/go-kosu/tests/suite_test.go b/packages/go-kosu/tests/suite_test.go index 87310f59..40e58a65 100644 --- a/packages/go-kosu/tests/suite_test.go +++ b/packages/go-kosu/tests/suite_test.go @@ -1,73 +1,207 @@ package tests import ( - "go-kosu/abci" - "go-kosu/abci/types" + "context" + "math/rand" + "path/filepath" + "strings" "testing" + "time" - . "github.com/smartystreets/goconvey/convey" //nolint "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" - cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/libs/db" + "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/privval" rpctypes "github.com/tendermint/tendermint/rpc/core/types" + tmtypes "github.com/tendermint/tendermint/types" + + "go-kosu/abci" + "go-kosu/abci/types" ) -type Suite struct { +func init() { + rand.Seed(time.Now().UnixNano()) +} + +type Node struct { + Client *abci.Client + Config *config.Config + PrivVal privval.FilePVKey +} + +type IntegrationTestSuite struct { suite.Suite - client *abci.Client - config *cfg.Config + // Nodes are populated on SetupSuite based on the KOSU_TEST_NODES environment variable + // KOSU_TEST_NODES is a comma separated list of nodes following this format: + // [@url],... + // is required and points to the node home directory + // is optional and represents the node url, if not specified it will take the url from config.RPC.ListenAddress + Nodes []Node + + // CurrentBlock will be updated on each new test from the suite + CurrentBlock *tmtypes.Block } -// GivenABCIServer a ABCI Server inside a Convey block -func GivenABCIServer(t *testing.T, suite *Suite, fn func(*testing.T)) { - Convey("Given an ABCI Server", t, func() { - app, closer := StartServer(t, db.NewMemDB()) - defer closer() - suite.config = app.Config +// Client returns the first client out of the node list. +func (suite *IntegrationTestSuite) Client() *abci.Client { + return suite.Nodes[0].Client +} - key, err := abci.LoadPrivateKey(app.Config.RootDir) - require.NoError(t, err) +func (suite *IntegrationTestSuite) WaitForNewBlock() *tmtypes.Block { + events, closer, err := suite.Client().Subscribe(context.Background(), "tm.event = 'NewBlock'") + suite.Require().NoError(err) + defer closer() - suite.client = abci.NewHTTPClient("http://localhost:26657", key) - fn(t) - }) + event := <-events + return event.Data.(tmtypes.EventDataNewBlock).Block } -// BroadcastTxSync is a helper function to Broadcast a Tx under test -func BroadcastTxSync(t *testing.T, c *abci.Client, tx interface{}) *rpctypes.ResultBroadcastTx { - res, err := c.BroadcastTxSync(tx) - So(err, ShouldBeNil) - require.Zero(t, res.Code, res.Log) - return res +// IsValidTxCommit performs assertions over a BroadcastTxCommit +func (suite *IntegrationTestSuite) IsValidTxCommit(res *rpctypes.ResultBroadcastTxCommit, err error) { + suite.Require().NoError(err) + suite.Require().True(res.CheckTx.IsOK(), res.CheckTx.Log) + suite.Require().True(res.DeliverTx.IsOK(), res.DeliverTx.Log) +} + +// IsValidTxSync performs assertions over a BroadcastTxSync +func (suite *IntegrationTestSuite) IsValidTxSync(res *rpctypes.ResultBroadcastTx, err error) { + suite.Require().NoError(err) + suite.Require().Zero(res.Code, res.Log) } // BroadcastTxCommit is a helper function to Broadcast a Tx under test -func BroadcastTxCommit(t *testing.T, c *abci.Client, tx interface{}) *rpctypes.ResultBroadcastTxCommit { - res, err := c.BroadcastTxCommit(tx) - So(err, ShouldBeNil) - require.True(t, res.CheckTx.IsOK(), res.CheckTx.Log) - require.True(t, res.DeliverTx.IsOK(), res.DeliverTx.Log) +func (suite *IntegrationTestSuite) BroadcastTxCommit(tx interface{}) *rpctypes.ResultBroadcastTxCommit { + res, err := suite.Client().BroadcastTxCommit(tx) + suite.IsValidTxCommit(res, err) return res } -func BroadcastNextRebalance(t *testing.T, c *abci.Client) { - params, err := c.QueryConsensusParams() - require.NoError(t, err) +// BroadcastTxSync is a helper function to Broadcast a Tx under test +func (suite *IntegrationTestSuite) BroadcastTxSync(tx interface{}) *rpctypes.ResultBroadcastTx { + res, err := suite.Client().BroadcastTxSync(tx) + suite.IsValidTxSync(res, err) + return res +} + +// WithNode calls fn for every node defined in the node set. +// If fn returns err, the error is returned and the execution stopped. +func (suite *IntegrationTestSuite) WithNode(fn func(*Node) error) error { + for _, node := range suite.Nodes { + if err := fn(&node); err != nil { + return err + } + } + return nil +} + +// WithConfirmations Broadcast a Tx across all the nodes so that we make sure it's confirmed +func (suite *IntegrationTestSuite) WithConfirmations(tx interface{}) { + _ = suite.WithNode(func(node *Node) error { + suite.IsValidTxSync( + node.Client.BroadcastTxSync(tx), + ) + return nil + }) +} + +// NextRoundInfo calculates the next round info based on the current one +func (suite *IntegrationTestSuite) NextRoundInfo() *types.RoundInfo { + round, err := suite.Client().QueryRoundInfo() + suite.Require().NoError(err) + + diff := round.EndsAt - round.StartsAt + round.StartsAt = round.EndsAt + round.EndsAt += diff + round.Number++ + + return round +} + +func (suite *IntegrationTestSuite) BroadcastNextRebalance() { + params, err := suite.Client().QueryConsensusParams() + suite.Require().NoError(err) - info, err := c.QueryRoundInfo() + info, err := suite.Client().QueryRoundInfo() if err != nil { info = &types.RoundInfo{ - Number: 1, + Number: 0, StartsAt: 1, EndsAt: 1, } } else { info.StartsAt = info.EndsAt } + info.Number++ info.EndsAt += uint64(params.PeriodLength) - BroadcastTxCommit(t, c, &types.TransactionRebalance{RoundInfo: info}) + suite.BroadcastTxCommit(&types.TransactionRebalance{RoundInfo: info}) +} + +func newClient(t *testing.T, rootdir, url string) *abci.Client { + key, err := abci.LoadPrivateKey(rootdir) + require.NoError(t, err) + + client, err := abci.NewHTTPClient(url, key) + require.NoError(t, err) + + return client +} + +func (suite *IntegrationTestSuite) addNode(homedir, url string) { + cfg, err := abci.LoadConfig(homedir) + suite.Require().NoError(err) + + priv := privval.LoadFilePV( + cfg.PrivValidatorKeyFile(), + cfg.PrivValidatorStateFile(), + ).Key + + if url == "" { + url = cfg.RPC.ListenAddress + } + + suite.Nodes = append(suite.Nodes, Node{ + Client: newClient(suite.T(), homedir, url), + Config: cfg, + PrivVal: priv, + }) +} + +// SetupSuite setup the test suite +func (suite *IntegrationTestSuite) SetupSuite() { + nodes := envOrSkip(suite.T(), "KOSU_TEST_NODES") + for _, node := range strings.Split(nodes, ",") { + var homedir, url string + split := strings.Split(node, "@") + homedir = split[0] + if len(split) == 2 { + url = split[1] + } + if !filepath.IsAbs(homedir) { + suite.T().Fatalf("home dir must be absolute, got: %s", homedir) + } + + suite.addNode(homedir, url) + } +} + +// SetupTest creates a new subscriptions to `NewBlocks` and waits for a new block before each test +func (suite *IntegrationTestSuite) SetupTest() { + suite.CurrentBlock = suite.WaitForNewBlock() +} + +func (suite *IntegrationTestSuite) TearDownTest() { +} + +func (suite *IntegrationTestSuite) TearDownSuite() { + for _, node := range suite.Nodes { + err := node.Client.Stop() + suite.Require().NoError(err) + } +} + +func TestIntegrationTestSuite(t *testing.T) { + suite.Run(t, new(IntegrationTestSuite)) } diff --git a/packages/go-kosu/tests/validators_test.go b/packages/go-kosu/tests/validators_test.go new file mode 100644 index 00000000..10fa580d --- /dev/null +++ b/packages/go-kosu/tests/validators_test.go @@ -0,0 +1,63 @@ +package tests + +import ( + "encoding/hex" + "go-kosu/abci/types" +) + +func (suite *IntegrationTestSuite) TestValidators() { + initial, err := suite.Client().Validators(nil) + suite.Require().NoError(err) + + last, err := suite.Client().QueryLastEvent() + suite.Require().NoError(err) + + pubkey, err := hex.DecodeString(randomHex(64)) + suite.Require().NoError(err) + + tx := &types.TransactionWitness{ + Subject: types.TransactionWitness_VALIDATOR, + Address: randomHex(40), + PublicKey: pubkey, + Block: last, + } + + suite.Run("AddValidator", func() { + tx.Amount = types.NewBigIntFromString("1000000000000000000", 10) + + suite.WithConfirmations(tx) + + // wait for 2 blocks to make sure the validator set is updated + suite.WaitForNewBlock() + suite.WaitForNewBlock() + + res, err := suite.Client().Validators(nil) + suite.Require().NoError(err) + + suite.Equal( + len(initial.Validators)+1, + len(res.Validators), + "validator set should be updated with 1 new validator", + ) + }) + + suite.Run("RemoveValidator", func() { + tx.Block++ + tx.Amount = types.NewBigIntFromInt(0) + + suite.WithConfirmations(tx) + + // wait for 2 blocks to make sure the validator set is updated + suite.WaitForNewBlock() + suite.WaitForNewBlock() + + res, err := suite.Client().Validators(nil) + suite.Require().NoError(err) + + suite.Equal( + len(initial.Validators), + len(res.Validators), + "validator set should be equal to the initial set", + ) + }) +} diff --git a/packages/go-kosu/tests/witness_test.go b/packages/go-kosu/tests/witness_test.go index f0bb8068..a4eeb5da 100644 --- a/packages/go-kosu/tests/witness_test.go +++ b/packages/go-kosu/tests/witness_test.go @@ -1,147 +1,73 @@ package tests import ( - "context" - "testing" - - . "github.com/smartystreets/goconvey/convey" - "github.com/stretchr/testify/require" - - "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/privval" - tmtypes "github.com/tendermint/tendermint/types" - "go-kosu/abci" "go-kosu/abci/types" ) -func buildWitnessTx(cfg *config.Config, tx *types.TransactionWitness) *types.TransactionWitness { - priv := privval.LoadFilePV( - cfg.PrivValidatorKeyFile(), - cfg.PrivValidatorStateFile(), - ).Key - - tx.Address = priv.Address.String() - tx.PublicKey = priv.PubKey.Bytes()[5:] - return tx -} +func (suite *IntegrationTestSuite) TestWitness() { + newTx := func() *types.TransactionWitness { + last, err := suite.Client().QueryLastEvent() + suite.Require().NoError(err) -func (s *Suite) TestWitnessTxPoster() { - GivenABCIServer(s.T(), s, func(t *testing.T) { - tx := buildWitnessTx(s.config, &types.TransactionWitness{ + return &types.TransactionWitness{ Subject: types.TransactionWitness_POSTER, - Block: 10, + Block: last, Amount: types.NewBigIntFromString("1000000000000000000", 10), - }) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - ch, closer, err := s.client.Subscribe(ctx, "tm.event = 'Tx'") - So(err, ShouldBeNil) - defer closer() - - Convey("Broadcasting a Witness Tx with enough confirmations", func() { - BroadcastTxSync(t, s.client, tx) - - Convey("Querying Poster by Tx.Address should be found after N confirmations", func() { - <-ch + Address: randomHex(40), + } + } - p, err := s.client.QueryPoster(tx.Address) - So(err, ShouldBeNil) - require.EqualValues(t, p.Balance.BigInt(), tx.Amount.BigInt()) - }) + suite.Run("WithEnoughConfirmations", func() { + tx := newTx() + suite.WithConfirmations(tx) + suite.WaitForNewBlock() - Convey("Broadcasting a Witness Tx with smaller block number should error", func() { - tx.Block-- + poster, err := suite.Client().QueryPoster(tx.Address) + suite.Require().NoError(err) - BroadcastTxSync(t, s.client, tx) - - <-ch // discard the first tx - e := <-ch - txEvent := e.Data.(tmtypes.EventDataTx) - So(txEvent.Result.IsErr(), ShouldBeTrue) - }) - }) + suite.NotNil(poster) + suite.Equal(tx.Amount.String(), poster.Balance.String()) + }) - Convey("Broadcasting a Witness Tx without required confirmations", func() { - BroadcastTxSync(t, s.client, tx) + suite.Run("WithoutEnoughConfirmations", func() { + tx := newTx() + res, err := suite.Client().BroadcastTxCommit(tx) + suite.Require().NoError(err) + suite.Require().True(res.DeliverTx.IsOK(), res.DeliverTx.Log) - Convey("Querying Poster by Tx.Address should NOT be found after N confirmations", func() { - // <-ch + poster, err := suite.Client().QueryPoster(tx.Address) + suite.Require().Equal(abci.ErrNotFound, err) + suite.Nil(poster) - p, err := s.client.QueryPoster(tx.Address) - So(err, ShouldNotBeNil) - So(p, ShouldBeNil) - }) - }) }) -} - -func (s *Suite) TestWitnessValidator() { - GivenABCIServer(s.T(), s, func(t *testing.T) { - tx := buildWitnessTx(s.config, &types.TransactionWitness{ - Subject: types.TransactionWitness_VALIDATOR, - Block: 10, - Amount: types.NewBigIntFromString("1000000000000000000", 10), - }) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + suite.Run("WithSmallerBlock", func() { + tx := newTx() + tx.Block-- - ch, closer, err := s.client.Subscribe(ctx, "tm.event = 'NewBlock'") - So(err, ShouldBeNil) - defer closer() + res, err := suite.Client().BroadcastTxSync(tx) + suite.Require().NoError(err) - Convey("And an initial number of validators", func() { - res, err := s.client.Validators(nil) - require.NoError(t, err) - So(res.Validators[0].VotingPower, ShouldEqual, 10) + suite.NotEqual(0, res.Code) + }) - Convey("When a Tx is broadcasted", func() { - BroadcastTxSync(t, s.client, tx) - Convey("Validator's voting power should be updated", func() { - // Wait for 2 blocks for validator set to be updated - <-ch - <-ch + suite.Run("Prunning", func() { + tx1 := newTx() + suite.BroadcastTxCommit(tx1) - res, err := s.client.Validators(nil) - require.NoError(t, err) + res, err := suite.Client().ABCIQuery("/witness/key", tx1.Hash()) + suite.Require().NoError(err) + suite.Require().NotNil(res.Response.Value) + suite.Require().NotEmpty(res.Response.Value) - So(res.Validators[0].VotingPower, ShouldEqual, 1) + tx2 := newTx() + tx2.Block = abci.GenesisAppState.ConsensusParams.BlocksBeforePruning + tx1.Block + suite.BroadcastTxCommit(tx2) - }) - }) - }) - }) -} + res, err = suite.Client().ABCIQuery("/witness/key", tx1.Hash()) + suite.Require().NoError(err) -func (s *Suite) TestWitnessTxPruning() { - GivenABCIServer(s.T(), s, func(t *testing.T) { - Convey("When a Tx#1 is broadcasted", func() { - tx := buildWitnessTx(s.config, &types.TransactionWitness{ - Subject: types.TransactionWitness_VALIDATOR, - Block: 10, - Amount: types.NewBigIntFromString("1000000000000000000", 10), - }) - txID := tx.Hash() - - BroadcastTxCommit(t, s.client, tx) - res, err := s.client.ABCIQuery("/witness/key", txID) - require.NoError(t, err) - require.Zero(t, res.Response.Code) - require.NotNil(t, res.Response.Value) - - Convey("And Tx#2 is broadcasted `BlocksBeforePruning` Ethereum blocks later", func() { - tx.Block += abci.GenesisAppState.ConsensusParams.BlocksBeforePruning - BroadcastTxCommit(t, s.client, tx) - - Convey("Tx#1 should not exist", func() { - res, err := s.client.ABCIQuery("/witness/key", txID) - require.NoError(t, err) - require.Zero(t, res.Response.Code) - }) - }) - }) + suite.Empty(res.Response.Value) }) } diff --git a/packages/go-kosu/witness/eth.go.orig b/packages/go-kosu/witness/eth.go.orig deleted file mode 100644 index d8b6f3ab..00000000 --- a/packages/go-kosu/witness/eth.go.orig +++ /dev/null @@ -1,119 +0,0 @@ -package witness - -import ( - "context" - "log" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient" -) - -var _ Provider = &EthereumProvider{} - -// EthereumProvider implements a Provider that connect to the Ethereum Blockchain -type EthereumProvider struct { - client *ethclient.Client -} - -// NewEthereumProvider returns a new EthereumProvider -func NewEthereumProvider(addr string) (*EthereumProvider, error) { - client, err := ethclient.Dial(addr) - if err != nil { - return nil, err - } - -<<<<<<< HEAD - return &EthereumProvider{client: client}, nil -} - -// WatchEvents watches for emitted events from the EventEmitter contract. -// First, emits the existing events in the blockchain, then subscribes to get the emitted events as they happen -func (w *EthereumProvider) WatchEvents(ctx context.Context, fn EventHandler) error { - emitter, err := NewEventEmitter( - common.HexToAddress(KosuEventEmitterAddress), - w.client, -======= - nID, err := client.NetworkID(context.Background()) - if err != nil { - return nil, err - } - - cAddr, err := GetContractAddress(nID, "EventEmitter") - if err != nil { - return nil, err - } - - events, err := NewEventEmitter( - common.HexToAddress(cAddr), - client, ->>>>>>> master - ) - if err != nil { - return err - } - - f, err := emitter.FilterKosuEvent(nil) - if err != nil { - return err - } - defer f.Close() // nolint:errcheck - - events := make(chan *EventEmitterKosuEvent) - defer close(events) - - sub, err := emitter.WatchKosuEvent(nil, events) - if err != nil { - return err - } - defer sub.Unsubscribe() - - for f.Next() { - fn(f.Event) - } - - for { - select { - case <-ctx.Done(): - return ctx.Err() - case err := <-sub.Err(): - log.Fatalf("WatchEvents: err = %+v", err) - return err - case evt := <-events: - fn(evt) - } - } -} - -// WatchBlocks watches for incoming block headers -func (w *EthereumProvider) WatchBlocks(ctx context.Context, fn BlockHandler) error { - ch := make(chan *types.Header) - defer close(ch) - - sub, err := w.client.SubscribeNewHead(ctx, ch) - if err != nil { - return err - } - defer sub.Unsubscribe() - - for { - select { - case <-ctx.Done(): - return ctx.Err() - case err := <-sub.Err(): - return err - case header := <-ch: - fn(header) - } - } -} - -// GetLastBlockNumber returns the latest known block number from the chain -func (w *EthereumProvider) GetLastBlockNumber(ctx context.Context) (uint64, error) { - block, err := w.client.BlockByNumber(ctx, nil) - if err != nil { - return 0, err - } - - return block.NumberU64(), nil -} diff --git a/packages/go-kosu/witness/eth_test.go b/packages/go-kosu/witness/eth_test.go index 6f3115c1..8a5004c1 100644 --- a/packages/go-kosu/witness/eth_test.go +++ b/packages/go-kosu/witness/eth_test.go @@ -12,7 +12,7 @@ import ( ) func TestEth(t *testing.T) { - env := "WEB3_TEST_URI" + env := "WEB3_URI_WS" addr := os.Getenv(env) if addr == "" { t.Skipf("%s env not declared", env) @@ -28,6 +28,7 @@ func TestEth(t *testing.T) { fn := func(e *EventEmitterKosuEvent) { log.Printf("type(%-30s) @#%d", e.EventType, e.Raw.BlockNumber) } + err := eth.WatchEvents(ctx, fn) require.Equal(t, context.DeadlineExceeded, err) }) diff --git a/packages/kosu.js/package.json b/packages/kosu.js/package.json index fc083cb9..0e42e038 100644 --- a/packages/kosu.js/package.json +++ b/packages/kosu.js/package.json @@ -7,7 +7,7 @@ "scripts": { "test": "mocha", "coverage": "nyc mocha && istanbul report html && open coverage/lcov-report/index.html", - "test:ci": "ts-mocha -p tsconfig.json test/ --timeout 8000 -- geth", + "test:ci": "ts-mocha -p tsconfig.json test/ --timeout 20000 -- geth", "test:ganache": "docker run --rm -p 8545:8545 ${npm_package_config_ganache_image_uri}", "test:ganache_detached": "docker run --rm -d -p 8545:8545 ${npm_package_config_ganache_image_uri}", "build": "tsc",