diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cec6a3234..4865840e5 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,10 +1,20 @@
image: covenantsql/build
+stages:
+ - build
+ - test
+ - cleanup
+
variables:
REVIEWDOG_VERSION: 0.9.11
REVIEWDOG_GITLAB_API_TOKEN: $REVIEWDOG_TOKEN
CODECOV_TOKEN: $CODECOV_TOKEN
UNITTESTTAGS: linux sqlite_omit_load_extension
+ CACHE_DIR: /CovenantSQL_bins
+ PIPELINE_CACHE: $CACHE_DIR/$CI_PIPELINE_IID
+ BIN_CACHE: $CACHE_DIR/$CI_PIPELINE_IID/bin
+ PREV_VERSION: v0.4.0
+ # gitlabci bins: 192.168.2.100:/srv/gitlab-runner/config/CovenantSQL_bins
before_script:
# Setup dependency management tool
@@ -23,12 +33,23 @@ before_script:
- ulimit -n 8192
# - curl -fSL https://github.com/haya14busa/reviewdog/releases/download/$REVIEWDOG_VERSION/reviewdog_linux_amd64 -o ~/bin/reviewdog && chmod +x ~/bin/reviewdog
-test-my-project:
+build:
+ stage: build
+ script:
+ - set -x
+ - make clean
+ - make use_all_cores
+ - mkdir -p ${BIN_CACHE}
+ - cp bin/* ${BIN_CACHE}/
+
+unit-test:
stage: test
script:
+ - make clean
+ - cp ${BIN_CACHE}/* bin/
- ./alltest.sh
-compatibility-testnet:
+testnet-compatibility:
stage: test
script:
- set -o errexit
@@ -37,7 +58,43 @@ compatibility-testnet:
- branch=$(git branch -rv |grep $commit | awk '{print $1}')
- if [[ $branch =~ "/beta_" ]]; then exit 0; fi
- make clean
- - make -j8 client
+ - cp ${BIN_CACHE}/* bin/
- go test -tags "$UNITTESTTAGS" -bench=^BenchmarkTestnetMiner2$ -benchtime=5s -run ^$ ./cmd/cql-minerd/
- set -x
- ./test/testnet_client/run.sh
+
+old-client-compatibility:
+ stage: test
+ script:
+ - set -o errexit
+ - set -o pipefail
+ - set -x
+ - make clean
+ - cp ${BIN_CACHE}/* bin/
+ - ./test/compatibility/specific_old.sh client
+
+old-bp-compatibility:
+ stage: test
+ script:
+ - set -o errexit
+ - set -o pipefail
+ - set -x
+ - make clean
+ - cp ${BIN_CACHE}/* bin/
+ - ./test/compatibility/specific_old.sh bp
+
+old-miner-compatibility:
+ stage: test
+ script:
+ - set -o errexit
+ - set -o pipefail
+ - set -x
+ - make clean
+ - cp ${BIN_CACHE}/* bin/
+ - ./test/compatibility/specific_old.sh miner
+
+cleanup_cache:
+ stage: cleanup
+ script:
+ - rm -r ${PIPELINE_CACHE}
+ when: on_success
diff --git a/.travis.yml b/.travis.yml
index 23f022dff..23da32731 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,7 +7,7 @@ env:
- REVIEWDOG_VERSION=0.9.11
language: go
go:
- - '1.10.x'
+ - '1.11.x'
os:
- linux
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 73544d80c..5795be024 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,30 @@
# Changelog
+## [v0.4.0](https://github.com/CovenantSQL/CovenantSQL/tree/v0.4.0) (2019-02-25)
+
+[Full Changelog](https://github.com/CovenantSQL/CovenantSQL/compare/v0.3.0...v0.4.0)
+
+**Merged pull requests:**
+
+- Use minimum assertion instead of exact version [\#265](https://github.com/CovenantSQL/CovenantSQL/pull/265) ([leventeliu](https://github.com/leventeliu))
+- Promote beta branch [\#264](https://github.com/CovenantSQL/CovenantSQL/pull/264) ([leventeliu](https://github.com/leventeliu))
+- Add imports format script and format all codes [\#263](https://github.com/CovenantSQL/CovenantSQL/pull/263) ([leventeliu](https://github.com/leventeliu))
+- Add listen flag for adapter [\#262](https://github.com/CovenantSQL/CovenantSQL/pull/262) ([auxten](https://github.com/auxten))
+- Use rpc broadcast for dht node info synchronization instead of kayak [\#261](https://github.com/CovenantSQL/CovenantSQL/pull/261) ([xq262144](https://github.com/xq262144))
+- Merge observer and explorer into cql [\#260](https://github.com/CovenantSQL/CovenantSQL/pull/260) ([auxten](https://github.com/auxten))
+- Add transaction hash as return value in create/drop [\#259](https://github.com/CovenantSQL/CovenantSQL/pull/259) ([leventeliu](https://github.com/leventeliu))
+- Combine createRandomBlock functions into one. [\#258](https://github.com/CovenantSQL/CovenantSQL/pull/258) ([laodouya](https://github.com/laodouya))
+- Improve unit test cover ratio [\#257](https://github.com/CovenantSQL/CovenantSQL/pull/257) ([laodouya](https://github.com/laodouya))
+- Refactor observer synchronization to pull mode [\#256](https://github.com/CovenantSQL/CovenantSQL/pull/256) ([xq262144](https://github.com/xq262144))
+- Refactor observer synchronization to pull mode [\#255](https://github.com/CovenantSQL/CovenantSQL/pull/255) ([xq262144](https://github.com/xq262144))
+- Fix SQLChain forks [\#254](https://github.com/CovenantSQL/CovenantSQL/pull/254) ([xq262144](https://github.com/xq262144))
+- Update beta with develop updates [\#253](https://github.com/CovenantSQL/CovenantSQL/pull/253) ([xq262144](https://github.com/xq262144))
+- Improve unit test cover ratio. [\#251](https://github.com/CovenantSQL/CovenantSQL/pull/251) ([laodouya](https://github.com/laodouya))
+- Add blocks cache limit for block producers [\#249](https://github.com/CovenantSQL/CovenantSQL/pull/249) ([leventeliu](https://github.com/leventeliu))
+- Support pprof http handler in BlockProducer [\#248](https://github.com/CovenantSQL/CovenantSQL/pull/248) ([xq262144](https://github.com/xq262144))
+- Unit all docker client config to same private.key [\#247](https://github.com/CovenantSQL/CovenantSQL/pull/247) ([laodouya](https://github.com/laodouya))
+- Make observer API writeTimeout = 10 \* readTimeout [\#246](https://github.com/CovenantSQL/CovenantSQL/pull/246) ([auxten](https://github.com/auxten))
+
## [v0.3.0](https://github.com/CovenantSQL/CovenantSQL/tree/v0.3.0) (2019-01-30)
[Full Changelog](https://github.com/CovenantSQL/CovenantSQL/compare/v0.2.0...v0.3.0)
diff --git a/Makefile b/Makefile
index e1bf36bce..ca3362038 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,6 @@ use_all_cores:
BUILDER := covenantsql/covenantsql-builder
IMAGE := covenantsql/covenantsql
-OB_IMAGE := covenantsql/covenantsql-observer
GIT_COMMIT ?= $(shell git rev-parse --short HEAD)
GIT_DIRTY ?= $(shell test -n "`git status --porcelain`" && echo "+CHANGES" || true)
@@ -41,7 +40,7 @@ builder: status
-f docker/builder.Dockerfile \
.
-runner: builder
+docker: builder
docker build \
--tag $(IMAGE):$(VERSION) \
--tag $(IMAGE):latest \
@@ -50,24 +49,11 @@ runner: builder
-f docker/Dockerfile \
.
-observer_docker: builder
- docker build \
- --tag $(OB_IMAGE):$(VERSION) \
- --tag $(OB_IMAGE):latest \
- --build-arg COMMIT=$(COMMIT) \
- --build-arg VERSION=$(VERSION) \
- -f docker/observer.Dockerfile \
- .
-
-docker: runner observer_docker
-
docker_clean: status
docker rmi -f $(BUILDER):latest
docker rmi -f $(IMAGE):latest
- docker rmi -f $(OB_IMAGE):latest
docker rmi -f $(BUILDER):$(VERSION)
docker rmi -f $(IMAGE):$(VERSION)
- docker rmi -f $(OB_IMAGE):$(VERSION)
save: status
@@ -89,27 +75,19 @@ logs:
docker-compose logs -f --tail=10
push_testnet:
- docker tag $(OB_IMAGE):$(VERSION) $(OB_IMAGE):testnet
- docker push $(OB_IMAGE):testnet
docker tag $(IMAGE):$(VERSION) $(IMAGE):testnet
docker push $(IMAGE):testnet
push_bench:
- docker tag $(OB_IMAGE):$(VERSION) $(OB_IMAGE):bench
- docker push $(OB_IMAGE):bench
docker tag $(IMAGE):$(VERSION) $(IMAGE):bench
docker push $(IMAGE):bench
push_staging:
- docker tag $(OB_IMAGE):$(VERSION) $(OB_IMAGE):staging
- docker push $(OB_IMAGE):staging
docker tag $(IMAGE):$(VERSION) $(IMAGE):staging
docker push $(IMAGE):staging
push:
- docker push $(OB_IMAGE):$(VERSION)
- docker push $(OB_IMAGE):latest
docker push $(IMAGE):$(VERSION)
docker push $(IMAGE):latest
@@ -162,18 +140,6 @@ bin/cql-minerd:
-o bin/cql-minerd \
github.com/CovenantSQL/CovenantSQL/cmd/cql-minerd
-bin/cql-observer.test:
- $(GOTEST) \
- -ldflags "$(ldflags_role_client)" \
- -o bin/cql-observer.test \
- github.com/CovenantSQL/CovenantSQL/cmd/cql-observer
-
-bin/cql-observer:
- $(GOBUILD) \
- -ldflags "$(ldflags_role_client)" \
- -o bin/cql-observer \
- github.com/CovenantSQL/CovenantSQL/cmd/cql-observer
-
bin/cql-utils:
$(GOBUILD) \
-ldflags "$(ldflags_role_client_simple_log)" \
@@ -186,18 +152,19 @@ bin/cql:
-o bin/cql \
github.com/CovenantSQL/CovenantSQL/cmd/cql
+bin/cql.test:
+ $(GOTEST) \
+ -ldflags "$(ldflags_role_client)" \
+ -o bin/cql.test \
+ github.com/CovenantSQL/CovenantSQL/cmd/cql
+
+
bin/cql-fuse:
$(GOBUILD) \
-ldflags "$(ldflags_role_client_simple_log)" \
-o bin/cql-fuse \
github.com/CovenantSQL/CovenantSQL/cmd/cql-fuse
-bin/cql-adapter:
- $(GOBUILD) \
- -ldflags "$(ldflags_role_client)" \
- -o bin/cql-adapter \
- github.com/CovenantSQL/CovenantSQL/cmd/cql-adapter
-
bin/cql-mysql-adapter:
$(GOBUILD) \
-ldflags "$(ldflags_role_client)" \
@@ -210,21 +177,13 @@ bin/cql-faucet:
-o bin/cql-faucet \
github.com/CovenantSQL/CovenantSQL/cmd/cql-faucet
-bin/cql-explorer:
- $(GOBUILD) \
- -ldflags "$(ldflags_role_client)" \
- -o bin/cql-explorer \
- github.com/CovenantSQL/CovenantSQL/cmd/cql-explorer
-
bp: bin/cqld.test bin/cqld
miner: bin/cql-minerd.test bin/cql-minerd
-observer: bin/cql-observer.test bin/cql-observer
-
-client: bin/cql-utils bin/cql bin/cql-fuse bin/cql-adapter bin/cql-mysql-adapter bin/cql-faucet bin/cql-explorer
+client: bin/cql-utils bin/cql bin/cql.test bin/cql-fuse bin/cql-mysql-adapter bin/cql-faucet
-all: bp miner observer client
+all: bp miner client
clean:
rm -rf bin/cql*
@@ -232,5 +191,5 @@ clean:
rm -f coverage.txt
.PHONY: status start stop logs push push_testnet clean \
- bin/cqld.test bin/cqld bin/cql-minerd.test bin/cql-minerd bin/cql-utils bin/cql-observer bin/cql-observer.test \
- bin/cql bin/cql-fuse bin/cql-adapter bin/cql-mysql-adapter bin/cql-faucet bin/cql-explorer
+ bin/cqld.test bin/cqld bin/cql-minerd.test bin/cql-minerd bin/cql-utils \
+ bin/cql bin/cql.test bin/cql-fuse bin/cql-mysql-adapter bin/cql-faucet
diff --git a/README.md b/README.md
index b322ab190..6da536ba9 100644
--- a/README.md
+++ b/README.md
@@ -28,8 +28,9 @@
[中文简介](https://github.com/CovenantSQL/CovenantSQL/blob/develop/README-zh.md)
-CovenantSQL is a decentralized, crowdsourcing SQL database on blockchain with features:
+CovenantSQL is a GDPR-compliant SQL database running on Open Internet without central coordination:
+- **GDPR-compliant**: Zero pain to be GDPR-compliant.
- **SQL**: most SQL-92 support.
- **Decentralize**: decentralize with our consensus algorithm DH-RPC & Kayak.
- **Privacy**: access with granted permission and Encryption Pass.
@@ -107,10 +108,14 @@ Watch us or [
+- [MainChain Explorer](http://scan.covenantsql.io)
+- [SQLChain Explorer](https://explorer.dbhub.org)
+- [Demo & Forum](https://demo.covenantsql.io/forum/)
## Contact
-- [mail us](mailto:webmaster@covenantsql.io)
+- [Mail](mailto:webmaster@covenantsql.io)
+- [Forum](https://demo.covenantsql.io/forum/)
-
diff --git a/alltest.sh b/alltest.sh
index b762c25d6..31421cda0 100755
--- a/alltest.sh
+++ b/alltest.sh
@@ -5,9 +5,6 @@ set -o pipefail
set -o nounset
main() {
- make clean
- make -j6 bp miner observer
-
go test -tags "$UNITTESTTAGS" -race -failfast -parallel 16 -cpu 16 -coverprofile main.cover.out $(go list ./... | grep -v CovenantSQL/api)
go test -tags "$UNITTESTTAGS" -race -failfast -parallel 16 -cpu 16 -coverpkg ./api/...,./rpc/jsonrpc -coverprofile api.cover.out ./api/...
diff --git a/bin/docker-entry.sh b/bin/docker-entry.sh
index cb7619ed8..f1da213d6 100755
--- a/bin/docker-entry.sh
+++ b/bin/docker-entry.sh
@@ -12,12 +12,10 @@ blockproducer)
exec /app/cqld -config "${COVENANT_CONF}" -metric-web "${METRIC_WEB_ADDR}" "${@}"
;;
observer)
- MAGIC_DOLLAR='$' envsubst < /etc/nginx/conf.d/servers/explorer.conf.template > /etc/nginx/conf.d/default.conf
- nginx -g 'daemon off;' .
+// #include
import "C"
func getLoad() ([]float64, error) {
diff --git a/metric/meminfo_darwin.go b/metric/meminfo_darwin.go
index 2e85a61f0..121479495 100644
--- a/metric/meminfo_darwin.go
+++ b/metric/meminfo_darwin.go
@@ -2,7 +2,7 @@
package metric
-// #include .
+// #include
import "C"
import (
diff --git a/cmd/cql-adapter/README.md b/sqlchain/adapter/README.md
similarity index 100%
rename from cmd/cql-adapter/README.md
rename to sqlchain/adapter/README.md
diff --git a/cmd/cql-adapter/api/account.go b/sqlchain/adapter/api/account.go
similarity index 100%
rename from cmd/cql-adapter/api/account.go
rename to sqlchain/adapter/api/account.go
diff --git a/cmd/cql-adapter/api/admin.go b/sqlchain/adapter/api/admin.go
similarity index 98%
rename from cmd/cql-adapter/api/admin.go
rename to sqlchain/adapter/api/admin.go
index 55eb4ef79..c367799ea 100644
--- a/cmd/cql-adapter/api/admin.go
+++ b/sqlchain/adapter/api/admin.go
@@ -22,7 +22,7 @@ import (
"net/http"
"strconv"
- "github.com/CovenantSQL/CovenantSQL/cmd/cql-adapter/config"
+ "github.com/CovenantSQL/CovenantSQL/sqlchain/adapter/config"
"github.com/CovenantSQL/CovenantSQL/utils/log"
)
diff --git a/cmd/cql-adapter/api/doc.go b/sqlchain/adapter/api/doc.go
similarity index 100%
rename from cmd/cql-adapter/api/doc.go
rename to sqlchain/adapter/api/doc.go
diff --git a/cmd/cql-adapter/api/query.go b/sqlchain/adapter/api/query.go
similarity index 98%
rename from cmd/cql-adapter/api/query.go
rename to sqlchain/adapter/api/query.go
index 1142e4bf2..0b865718c 100644
--- a/cmd/cql-adapter/api/query.go
+++ b/sqlchain/adapter/api/query.go
@@ -20,7 +20,7 @@ import (
"fmt"
"net/http"
- "github.com/CovenantSQL/CovenantSQL/cmd/cql-adapter/config"
+ "github.com/CovenantSQL/CovenantSQL/sqlchain/adapter/config"
"github.com/CovenantSQL/CovenantSQL/utils/log"
)
diff --git a/cmd/cql-adapter/api/router.go b/sqlchain/adapter/api/router.go
similarity index 100%
rename from cmd/cql-adapter/api/router.go
rename to sqlchain/adapter/api/router.go
diff --git a/cmd/cql-adapter/api/utils.go b/sqlchain/adapter/api/utils.go
similarity index 100%
rename from cmd/cql-adapter/api/utils.go
rename to sqlchain/adapter/api/utils.go
diff --git a/cmd/cql-adapter/config/config.go b/sqlchain/adapter/config/config.go
similarity index 93%
rename from cmd/cql-adapter/config/config.go
rename to sqlchain/adapter/config/config.go
index ba2ed392d..8a89bcdb7 100644
--- a/cmd/cql-adapter/config/config.go
+++ b/sqlchain/adapter/config/config.go
@@ -27,9 +27,8 @@ import (
yaml "gopkg.in/yaml.v2"
- "github.com/CovenantSQL/CovenantSQL/client"
- "github.com/CovenantSQL/CovenantSQL/cmd/cql-adapter/storage"
"github.com/CovenantSQL/CovenantSQL/conf"
+ "github.com/CovenantSQL/CovenantSQL/sqlchain/adapter/storage"
"github.com/CovenantSQL/CovenantSQL/utils/log"
)
@@ -69,8 +68,9 @@ type confWrapper struct {
Adapter Config `yaml:"Adapter"`
}
-// LoadConfig load and verify config in config file and set to global config instance.
-func LoadConfig(configPath string, password string) (config *Config, err error) {
+// LoadConfig load and verify config in config file (Reuse some global config instance values).
+// Should call conf.LoadConfig before use. e.g client.Init
+func LoadConfig(configPath string) (config *Config, err error) {
var workingRoot string
var configBytes []byte
if configBytes, err = ioutil.ReadFile(configPath); err != nil {
@@ -88,10 +88,6 @@ func LoadConfig(configPath string, password string) (config *Config, err error)
config.StorageDriver = "covenantsql"
}
if config.StorageDriver == "covenantsql" {
- // init client
- if err = client.Init(configPath, []byte(password)); err != nil {
- return
- }
workingRoot = conf.GConf.WorkingRoot
} else {
if workingRoot, err = os.Getwd(); err != nil {
diff --git a/cmd/cql-adapter/config/doc.go b/sqlchain/adapter/config/doc.go
similarity index 100%
rename from cmd/cql-adapter/config/doc.go
rename to sqlchain/adapter/config/doc.go
diff --git a/cmd/cql-adapter/config/errors.go b/sqlchain/adapter/config/errors.go
similarity index 100%
rename from cmd/cql-adapter/config/errors.go
rename to sqlchain/adapter/config/errors.go
diff --git a/cmd/cql-adapter/server.go b/sqlchain/adapter/server.go
similarity index 85%
rename from cmd/cql-adapter/server.go
rename to sqlchain/adapter/server.go
index 4fb17af78..de1fb533f 100644
--- a/cmd/cql-adapter/server.go
+++ b/sqlchain/adapter/server.go
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package main
+package adapter
import (
"context"
@@ -24,8 +24,8 @@ import (
"github.com/gorilla/handlers"
- "github.com/CovenantSQL/CovenantSQL/cmd/cql-adapter/api"
- "github.com/CovenantSQL/CovenantSQL/cmd/cql-adapter/config"
+ "github.com/CovenantSQL/CovenantSQL/sqlchain/adapter/api"
+ "github.com/CovenantSQL/CovenantSQL/sqlchain/adapter/config"
)
// HTTPAdapter is a adapter for covenantsql/alternative sqlite3 service.
@@ -34,12 +34,12 @@ type HTTPAdapter struct {
}
// NewHTTPAdapter creates adapter to service.
-func NewHTTPAdapter(listenAddr string, configFile string, password string) (adapter *HTTPAdapter, err error) {
+func NewHTTPAdapter(listenAddr string, configFile string) (adapter *HTTPAdapter, err error) {
adapter = new(HTTPAdapter)
// load config file
var cfg *config.Config
- if cfg, err = config.LoadConfig(configFile, password); err != nil {
+ if cfg, err = config.LoadConfig(configFile); err != nil {
return
}
diff --git a/cmd/cql-adapter/storage/covenantsql.go b/sqlchain/adapter/storage/covenantsql.go
similarity index 100%
rename from cmd/cql-adapter/storage/covenantsql.go
rename to sqlchain/adapter/storage/covenantsql.go
diff --git a/cmd/cql-adapter/storage/doc.go b/sqlchain/adapter/storage/doc.go
similarity index 100%
rename from cmd/cql-adapter/storage/doc.go
rename to sqlchain/adapter/storage/doc.go
diff --git a/cmd/cql-adapter/storage/sqlite3.go b/sqlchain/adapter/storage/sqlite3.go
similarity index 100%
rename from cmd/cql-adapter/storage/sqlite3.go
rename to sqlchain/adapter/storage/sqlite3.go
diff --git a/cmd/cql-adapter/storage/storage.go b/sqlchain/adapter/storage/storage.go
similarity index 100%
rename from cmd/cql-adapter/storage/storage.go
rename to sqlchain/adapter/storage/storage.go
diff --git a/sqlchain/observer/api.go b/sqlchain/observer/api.go
index 2e7cf426f..cc20e7eb8 100644
--- a/sqlchain/observer/api.go
+++ b/sqlchain/observer/api.go
@@ -26,6 +26,7 @@ import (
"strconv"
"time"
+ "github.com/gorilla/handlers"
"github.com/gorilla/mux"
"github.com/rakyll/statik/fs"
@@ -668,15 +669,15 @@ func startAPI(service *Service, listenAddr string, version string) (server *http
}
router := mux.NewRouter()
- fs := http.FileServer(statikFS)
- router.Handle("/", fs)
- router.Handle("/static/{type}/{file}", fs)
+ fsh := http.FileServer(statikFS)
+ router.Handle("/", fsh)
+ router.Handle("/static/{type}/{file}", fsh)
router.PathPrefix("/dbs").HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
r2 := new(http.Request)
*r2 = *request
r2.URL = new(url.URL)
r2.URL.Path = "/"
- fs.ServeHTTP(writer, r2)
+ fsh.ServeHTTP(writer, r2)
})
router.HandleFunc("/version", func(rw http.ResponseWriter, r *http.Request) {
sendResponse(http.StatusOK, true, nil, map[string]interface{}{
@@ -714,7 +715,7 @@ func startAPI(service *Service, listenAddr string, version string) (server *http
WriteTimeout: apiTimeout * 10,
ReadTimeout: apiTimeout,
IdleTimeout: apiTimeout,
- Handler: router,
+ Handler: handlers.CORS()(router),
}
go func() {
diff --git a/sqlchain/observer/observation_test.go b/sqlchain/observer/observation_test.go
index f7743f0ae..f9a95ab31 100644
--- a/sqlchain/observer/observation_test.go
+++ b/sqlchain/observer/observation_test.go
@@ -91,7 +91,7 @@ func startNodes() {
if cmd, err = utils.RunCommandNB(
FJ(baseDir, "./bin/cqld.test"),
[]string{"-config", FJ(testWorkingDir, "./observation/node_0/config.yaml"),
- "-test.coverprofile", FJ(baseDir, "./cmd/cql-observer/leader.cover.out"),
+ "-test.coverprofile", FJ(baseDir, "./cmd/cql/leader.cover.out"),
},
"leader", testWorkingDir, logDir, false,
); err == nil {
@@ -102,7 +102,7 @@ func startNodes() {
if cmd, err = utils.RunCommandNB(
FJ(baseDir, "./bin/cqld.test"),
[]string{"-config", FJ(testWorkingDir, "./observation/node_1/config.yaml"),
- "-test.coverprofile", FJ(baseDir, "./cmd/cql-observer/follower1.cover.out"),
+ "-test.coverprofile", FJ(baseDir, "./cmd/cql/follower1.cover.out"),
},
"follower1", testWorkingDir, logDir, false,
); err == nil {
@@ -113,7 +113,7 @@ func startNodes() {
if cmd, err = utils.RunCommandNB(
FJ(baseDir, "./bin/cqld.test"),
[]string{"-config", FJ(testWorkingDir, "./observation/node_2/config.yaml"),
- "-test.coverprofile", FJ(baseDir, "./cmd/cql-observer/follower2.cover.out"),
+ "-test.coverprofile", FJ(baseDir, "./cmd/cql/follower2.cover.out"),
},
"follower2", testWorkingDir, logDir, false,
); err == nil {
@@ -150,7 +150,7 @@ func startNodes() {
if cmd, err = utils.RunCommandNB(
FJ(baseDir, "./bin/cql-minerd.test"),
[]string{"-config", FJ(testWorkingDir, "./observation/node_miner_0/config.yaml"),
- "-test.coverprofile", FJ(baseDir, "./cmd/cql-observer/miner0.cover.out"),
+ "-test.coverprofile", FJ(baseDir, "./cmd/cql/miner0.cover.out"),
},
"miner0", testWorkingDir, logDir, false,
); err == nil {
@@ -163,7 +163,7 @@ func startNodes() {
if cmd, err = utils.RunCommandNB(
FJ(baseDir, "./bin/cql-minerd.test"),
[]string{"-config", FJ(testWorkingDir, "./observation/node_miner_1/config.yaml"),
- "-test.coverprofile", FJ(baseDir, "./cmd/cql-observer/miner1.cover.out"),
+ "-test.coverprofile", FJ(baseDir, "./cmd/cql/miner1.cover.out"),
},
"miner1", testWorkingDir, logDir, false,
); err == nil {
@@ -176,7 +176,7 @@ func startNodes() {
if cmd, err = utils.RunCommandNB(
FJ(baseDir, "./bin/cql-minerd.test"),
[]string{"-config", FJ(testWorkingDir, "./observation/node_miner_2/config.yaml"),
- "-test.coverprofile", FJ(baseDir, "./cmd/cql-observer/miner2.cover.out"),
+ "-test.coverprofile", FJ(baseDir, "./cmd/cql/miner2.cover.out"),
},
"miner2", testWorkingDir, logDir, false,
); err == nil {
@@ -487,10 +487,11 @@ func TestFullProcess(t *testing.T) {
var observerCmd *utils.CMD
observerCmd, err = utils.RunCommandNB(
- FJ(baseDir, "./bin/cql-observer.test"),
+ FJ(baseDir, "./bin/cql.test"),
[]string{"-config", FJ(testWorkingDir, "./observation/node_observer/config.yaml"),
- "-log-level", "debug",
- "-test.coverprofile", FJ(baseDir, "./cmd/cql-observer/observer.cover.out"),
+ "-bg-log-level", "debug",
+ "-test.coverprofile", FJ(baseDir, "./cmd/cql/observer.cover.out"),
+ "-web", "127.0.0.1:4663",
},
"observer", testWorkingDir, logDir, false,
)
@@ -717,9 +718,11 @@ func TestFullProcess(t *testing.T) {
// start observer again
observerCmd, err = utils.RunCommandNB(
- FJ(baseDir, "./bin/cql-observer.test"),
+ FJ(baseDir, "./bin/cql.test"),
[]string{"-config", FJ(testWorkingDir, "./observation/node_observer/config.yaml"),
- "-test.coverprofile", FJ(baseDir, "./cmd/cql-observer/observer.cover.out"),
+ "-bg-log-level", "debug",
+ "-test.coverprofile", FJ(baseDir, "./cmd/cql/observer.cover.out"),
+ "-web", "127.0.0.1:4663",
},
"observer", testWorkingDir, logDir, false,
)
diff --git a/sqlchain/observer/observer.go b/sqlchain/observer/observer.go
index bfde4ad9e..79de69f61 100644
--- a/sqlchain/observer/observer.go
+++ b/sqlchain/observer/observer.go
@@ -63,11 +63,6 @@ func stopService(service *Service) (err error) {
// StartObserver starts the observer service and http API server.
func StartObserver(listenAddr string, version string) (service *Service, httpServer *http.Server, err error) {
- // init node
- if err = initNode(); err != nil {
- log.WithError(err).Fatal("init node failed")
- }
-
// start service
if service, err = startService(); err != nil {
log.WithError(err).Fatal("start observation failed")
diff --git a/sqlchain/observer/service.go b/sqlchain/observer/service.go
index 6713000b6..7bf244360 100644
--- a/sqlchain/observer/service.go
+++ b/sqlchain/observer/service.go
@@ -306,6 +306,13 @@ func (s *Service) addQueryTracker(dbID proto.DatabaseID, height int32, offset in
func (s *Service) addBlock(dbID proto.DatabaseID, count int32, b *types.Block) (err error) {
instance, err := s.getUpstream(dbID)
+ if err != nil {
+ return
+ }
+ if b == nil {
+ return
+ }
+
h := int32(b.Timestamp().Sub(instance.GenesisBlock.Timestamp()) / conf.GConf.SQLChainPeriod)
key := utils.ConcatAll(int32ToBytes(h), b.BlockHash().AsBytes(), int32ToBytes(count))
// It's actually `countToBytes`
diff --git a/test/compatibility/node_0/config.yaml b/test/compatibility/node_0/config.yaml
new file mode 100644
index 000000000..cd1a54cda
--- /dev/null
+++ b/test/compatibility/node_0/config.yaml
@@ -0,0 +1,122 @@
+IsTestMode: true
+WorkingRoot: "./"
+PubKeyStoreFile: "public.keystore"
+PrivateKeyFile: "private.key"
+DHTFileName: "dht.db"
+ListenAddr: "127.0.0.1:3122"
+ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
+QPS: 1000
+BillingBlockCount: 2
+ChainBusPeriod: 1s
+BPPeriod: 3s
+BPTick: 1s
+SQLChainPeriod: 3s
+SQLChainTick: 1s
+SQLChainTTL: 10
+MinProviderDeposit: 1000000
+ValidDNSKeys:
+ koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
+ mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
+MinNodeIDDifficulty: 2
+DNSSeed:
+ EnforcedDNSSEC: false
+ DNSServers:
+ - 1.1.1.1
+ - 202.46.34.74
+ - 202.46.34.75
+ - 202.46.34.76
+
+BlockProducer:
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ ChainFileName: "chain.db"
+ BPGenesisInfo:
+ Version: 1
+ BlockHash: f745ca6427237aac858dd3c7f2df8e6f3c18d0f1c164e07a1c6b8eebeba6b154
+ Producer: 0000000000000000000000000000000000000000000000000000000000000001
+ MerkleRoot: 0000000000000000000000000000000000000000000000000000000000000001
+ ParentHash: 0000000000000000000000000000000000000000000000000000000000000001
+ Timestamp: 2018-08-13T21:59:59.12Z
+ BaseAccounts:
+ - Address: ba0ba731c7a76ccef2c1170f42038f7e228dfb474ef0190dfe35d9a37911ed37
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 1a7b0959bbd0d0ec529278a61c0056c277bffe75b2646e1699b46b10a90210be
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 9235bc4130a2ed4e6c35ea189dab35198ebb105640bedb97dd5269cc80863b16
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 9e1618775cceeb19f110e04fbc6c5bca6c8e4e9b116e193a42fe69bf602e7bcd
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+KnownNodes:
+- ID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ Addr: 127.0.0.1:3122
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Leader
+- ID: 00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35
+ Nonce:
+ a: 478373
+ b: 0
+ c: 0
+ d: 2305843009893772025
+ Addr: 127.0.0.1:3121
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582
+ Nonce:
+ a: 259939
+ b: 0
+ c: 0
+ d: 2305843012544226372
+ Addr: 127.0.0.1:3120
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d
+ Nonce:
+ a: 22403
+ b: 0
+ c: 0
+ d: 0
+ Addr: ""
+ PublicKey: 02ec784ca599f21ef93fe7abdc68d78817ab6c9b31f2324d15ea174d9da498b4c4
+ Role: Client
+- ID: 000005aa62048f85da4ae9698ed59c14ec0d48a88a07c15a32265634e7e64ade
+ Nonce:
+ a: 567323
+ b: 0
+ c: 0
+ d: 3104982049
+ Addr: 127.0.0.1:2144
+ PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
+ Role: Miner
+- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
+ Nonce:
+ a: 240524
+ b: 0
+ c: 0
+ d: 2305843010430351476
+ Addr: 127.0.0.1:2145
+ PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
+ Role: Miner
+- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
+ Nonce:
+ a: 606016
+ b: 0
+ c: 0
+ d: 13835058056920509601
+ Addr: 127.0.0.1:2146
+ PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
+ Role: Miner
diff --git a/test/compatibility/node_0/private.key b/test/compatibility/node_0/private.key
new file mode 100644
index 000000000..449618c0a
--- /dev/null
+++ b/test/compatibility/node_0/private.key
@@ -0,0 +1,2 @@
+WAð8#|TZԓ`mF}~eʆ?~*E%vpo*a߂ç_Bľ@8
+MC2
\ No newline at end of file
diff --git a/test/compatibility/node_1/config.yaml b/test/compatibility/node_1/config.yaml
new file mode 100644
index 000000000..eca03e17d
--- /dev/null
+++ b/test/compatibility/node_1/config.yaml
@@ -0,0 +1,122 @@
+IsTestMode: true
+WorkingRoot: "./"
+PubKeyStoreFile: "public.keystore"
+PrivateKeyFile: "private.key"
+DHTFileName: "dht.db"
+ListenAddr: "127.0.0.1:3121"
+ThisNodeID: "00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35"
+QPS: 1000
+BillingBlockCount: 2
+ChainBusPeriod: 1s
+BPPeriod: 3s
+BPTick: 1s
+SQLChainPeriod: 3s
+SQLChainTick: 1s
+SQLChainTTL: 10
+MinProviderDeposit: 1000000
+ValidDNSKeys:
+ koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
+ mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
+MinNodeIDDifficulty: 2
+DNSSeed:
+ EnforcedDNSSEC: false
+ DNSServers:
+ - 1.1.1.1
+ - 202.46.34.74
+ - 202.46.34.75
+ - 202.46.34.76
+
+BlockProducer:
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ ChainFileName: "chain.db"
+ BPGenesisInfo:
+ Version: 1
+ BlockHash: f745ca6427237aac858dd3c7f2df8e6f3c18d0f1c164e07a1c6b8eebeba6b154
+ Producer: 0000000000000000000000000000000000000000000000000000000000000001
+ MerkleRoot: 0000000000000000000000000000000000000000000000000000000000000001
+ ParentHash: 0000000000000000000000000000000000000000000000000000000000000001
+ Timestamp: 2018-08-13T21:59:59.12Z
+ BaseAccounts:
+ - Address: ba0ba731c7a76ccef2c1170f42038f7e228dfb474ef0190dfe35d9a37911ed37
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 1a7b0959bbd0d0ec529278a61c0056c277bffe75b2646e1699b46b10a90210be
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 9235bc4130a2ed4e6c35ea189dab35198ebb105640bedb97dd5269cc80863b16
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 9e1618775cceeb19f110e04fbc6c5bca6c8e4e9b116e193a42fe69bf602e7bcd
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+KnownNodes:
+- ID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ Addr: 127.0.0.1:3122
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Leader
+- ID: 00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35
+ Nonce:
+ a: 478373
+ b: 0
+ c: 0
+ d: 2305843009893772025
+ Addr: 127.0.0.1:3121
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582
+ Nonce:
+ a: 259939
+ b: 0
+ c: 0
+ d: 2305843012544226372
+ Addr: 127.0.0.1:3120
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d
+ Nonce:
+ a: 22403
+ b: 0
+ c: 0
+ d: 0
+ Addr: ""
+ PublicKey: 02ec784ca599f21ef93fe7abdc68d78817ab6c9b31f2324d15ea174d9da498b4c4
+ Role: Client
+- ID: 000005aa62048f85da4ae9698ed59c14ec0d48a88a07c15a32265634e7e64ade
+ Nonce:
+ a: 567323
+ b: 0
+ c: 0
+ d: 3104982049
+ Addr: 127.0.0.1:2144
+ PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
+ Role: Miner
+- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
+ Nonce:
+ a: 240524
+ b: 0
+ c: 0
+ d: 2305843010430351476
+ Addr: 127.0.0.1:2145
+ PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
+ Role: Miner
+- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
+ Nonce:
+ a: 606016
+ b: 0
+ c: 0
+ d: 13835058056920509601
+ Addr: 127.0.0.1:2146
+ PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
+ Role: Miner
diff --git a/test/compatibility/node_1/private.key b/test/compatibility/node_1/private.key
new file mode 100644
index 000000000..449618c0a
--- /dev/null
+++ b/test/compatibility/node_1/private.key
@@ -0,0 +1,2 @@
+WAð8#|TZԓ`mF}~eʆ?~*E%vpo*a߂ç_Bľ@8
+MC2
\ No newline at end of file
diff --git a/test/compatibility/node_2/config.yaml b/test/compatibility/node_2/config.yaml
new file mode 100644
index 000000000..30a422bc3
--- /dev/null
+++ b/test/compatibility/node_2/config.yaml
@@ -0,0 +1,122 @@
+IsTestMode: true
+WorkingRoot: "./"
+PubKeyStoreFile: "public.keystore"
+PrivateKeyFile: "private.key"
+DHTFileName: "dht.db"
+ListenAddr: "127.0.0.1:3120"
+ThisNodeID: "000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582"
+QPS: 1000
+BillingBlockCount: 2
+ChainBusPeriod: 1s
+BPPeriod: 3s
+BPTick: 1s
+SQLChainPeriod: 3s
+SQLChainTick: 1s
+SQLChainTTL: 10
+MinProviderDeposit: 1000000
+ValidDNSKeys:
+ koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
+ mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
+MinNodeIDDifficulty: 2
+DNSSeed:
+ EnforcedDNSSEC: false
+ DNSServers:
+ - 1.1.1.1
+ - 202.46.34.74
+ - 202.46.34.75
+ - 202.46.34.76
+
+BlockProducer:
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ ChainFileName: "chain.db"
+ BPGenesisInfo:
+ Version: 1
+ BlockHash: f745ca6427237aac858dd3c7f2df8e6f3c18d0f1c164e07a1c6b8eebeba6b154
+ Producer: 0000000000000000000000000000000000000000000000000000000000000001
+ MerkleRoot: 0000000000000000000000000000000000000000000000000000000000000001
+ ParentHash: 0000000000000000000000000000000000000000000000000000000000000001
+ Timestamp: 2018-08-13T21:59:59.12Z
+ BaseAccounts:
+ - Address: ba0ba731c7a76ccef2c1170f42038f7e228dfb474ef0190dfe35d9a37911ed37
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 1a7b0959bbd0d0ec529278a61c0056c277bffe75b2646e1699b46b10a90210be
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 9235bc4130a2ed4e6c35ea189dab35198ebb105640bedb97dd5269cc80863b16
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 9e1618775cceeb19f110e04fbc6c5bca6c8e4e9b116e193a42fe69bf602e7bcd
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+KnownNodes:
+- ID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ Addr: 127.0.0.1:3122
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Leader
+- ID: 00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35
+ Nonce:
+ a: 478373
+ b: 0
+ c: 0
+ d: 2305843009893772025
+ Addr: 127.0.0.1:3121
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582
+ Nonce:
+ a: 259939
+ b: 0
+ c: 0
+ d: 2305843012544226372
+ Addr: 127.0.0.1:3120
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d
+ Nonce:
+ a: 22403
+ b: 0
+ c: 0
+ d: 0
+ Addr: ""
+ PublicKey: 02ec784ca599f21ef93fe7abdc68d78817ab6c9b31f2324d15ea174d9da498b4c4
+ Role: Client
+- ID: 000005aa62048f85da4ae9698ed59c14ec0d48a88a07c15a32265634e7e64ade
+ Nonce:
+ a: 567323
+ b: 0
+ c: 0
+ d: 3104982049
+ Addr: 127.0.0.1:2144
+ PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
+ Role: Miner
+- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
+ Nonce:
+ a: 240524
+ b: 0
+ c: 0
+ d: 2305843010430351476
+ Addr: 127.0.0.1:2145
+ PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
+ Role: Miner
+- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
+ Nonce:
+ a: 606016
+ b: 0
+ c: 0
+ d: 13835058056920509601
+ Addr: 127.0.0.1:2146
+ PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
+ Role: Miner
diff --git a/test/compatibility/node_2/private.key b/test/compatibility/node_2/private.key
new file mode 100644
index 000000000..449618c0a
--- /dev/null
+++ b/test/compatibility/node_2/private.key
@@ -0,0 +1,2 @@
+WAð8#|TZԓ`mF}~eʆ?~*E%vpo*a߂ç_Bľ@8
+MC2
\ No newline at end of file
diff --git a/test/compatibility/node_c/config.yaml b/test/compatibility/node_c/config.yaml
new file mode 100644
index 000000000..84320e6c2
--- /dev/null
+++ b/test/compatibility/node_c/config.yaml
@@ -0,0 +1,122 @@
+IsTestMode: true
+WorkingRoot: "./"
+PubKeyStoreFile: "public.keystore"
+PrivateKeyFile: "private.key"
+DHTFileName: "dht.db"
+ListenAddr: "127.0.0.1:3120"
+ThisNodeID: "00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d"
+QPS: 1000
+BillingBlockCount: 2
+ChainBusPeriod: 1s
+BPPeriod: 3s
+BPTick: 1s
+SQLChainPeriod: 3s
+SQLChainTick: 1s
+SQLChainTTL: 10
+MinProviderDeposit: 1000000
+ValidDNSKeys:
+ koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
+ mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
+MinNodeIDDifficulty: 2
+DNSSeed:
+ EnforcedDNSSEC: false
+ DNSServers:
+ - 1.1.1.1
+ - 202.46.34.74
+ - 202.46.34.75
+ - 202.46.34.76
+
+BlockProducer:
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ ChainFileName: "chain.db"
+ BPGenesisInfo:
+ Version: 1
+ BlockHash: f745ca6427237aac858dd3c7f2df8e6f3c18d0f1c164e07a1c6b8eebeba6b154
+ Producer: 0000000000000000000000000000000000000000000000000000000000000001
+ MerkleRoot: 0000000000000000000000000000000000000000000000000000000000000001
+ ParentHash: 0000000000000000000000000000000000000000000000000000000000000001
+ Timestamp: 2018-08-13T21:59:59.12Z
+ BaseAccounts:
+ - Address: ba0ba731c7a76ccef2c1170f42038f7e228dfb474ef0190dfe35d9a37911ed37
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 1a7b0959bbd0d0ec529278a61c0056c277bffe75b2646e1699b46b10a90210be
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 9235bc4130a2ed4e6c35ea189dab35198ebb105640bedb97dd5269cc80863b16
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 9e1618775cceeb19f110e04fbc6c5bca6c8e4e9b116e193a42fe69bf602e7bcd
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+KnownNodes:
+- ID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ Addr: 127.0.0.1:3122
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Leader
+- ID: 00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35
+ Nonce:
+ a: 478373
+ b: 0
+ c: 0
+ d: 2305843009893772025
+ Addr: 127.0.0.1:3121
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582
+ Nonce:
+ a: 259939
+ b: 0
+ c: 0
+ d: 2305843012544226372
+ Addr: 127.0.0.1:3120
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d
+ Nonce:
+ a: 22403
+ b: 0
+ c: 0
+ d: 0
+ Addr: ""
+ PublicKey: 02ec784ca599f21ef93fe7abdc68d78817ab6c9b31f2324d15ea174d9da498b4c4
+ Role: Client
+- ID: 000005aa62048f85da4ae9698ed59c14ec0d48a88a07c15a32265634e7e64ade
+ Nonce:
+ a: 567323
+ b: 0
+ c: 0
+ d: 3104982049
+ Addr: 127.0.0.1:2144
+ PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
+ Role: Miner
+- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
+ Nonce:
+ a: 240524
+ b: 0
+ c: 0
+ d: 2305843010430351476
+ Addr: 127.0.0.1:2145
+ PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
+ Role: Miner
+- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
+ Nonce:
+ a: 606016
+ b: 0
+ c: 0
+ d: 13835058056920509601
+ Addr: 127.0.0.1:2146
+ PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
+ Role: Miner
diff --git a/test/compatibility/node_c/private.key b/test/compatibility/node_c/private.key
new file mode 100644
index 000000000..f563980c1
Binary files /dev/null and b/test/compatibility/node_c/private.key differ
diff --git a/test/compatibility/node_miner_0/config.yaml b/test/compatibility/node_miner_0/config.yaml
new file mode 100644
index 000000000..ce99baf98
--- /dev/null
+++ b/test/compatibility/node_miner_0/config.yaml
@@ -0,0 +1,118 @@
+IsTestMode: true
+WorkingRoot: "./"
+PubKeyStoreFile: "public.keystore"
+PrivateKeyFile: "private.key"
+DHTFileName: "dht.db"
+ListenAddr: "127.0.0.1:2144"
+ThisNodeID: "000005aa62048f85da4ae9698ed59c14ec0d48a88a07c15a32265634e7e64ade"
+QPS: 1000
+BillingBlockCount: 2
+ChainBusPeriod: 1s
+BPPeriod: 3s
+BPTick: 1s
+SQLChainPeriod: 3s
+SQLChainTick: 1s
+SQLChainTTL: 10
+MinProviderDeposit: 1000000
+ValidDNSKeys:
+ koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
+ mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
+BlockProducer:
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ ChainFileName: "chain.db"
+ BPGenesisInfo:
+ Version: 1
+ BlockHash: f745ca6427237aac858dd3c7f2df8e6f3c18d0f1c164e07a1c6b8eebeba6b154
+ Producer: 0000000000000000000000000000000000000000000000000000000000000001
+ MerkleRoot: 0000000000000000000000000000000000000000000000000000000000000001
+ ParentHash: 0000000000000000000000000000000000000000000000000000000000000001
+ Timestamp: 2018-08-13T21:59:59.12Z
+ BaseAccounts:
+ - Address: ba0ba731c7a76ccef2c1170f42038f7e228dfb474ef0190dfe35d9a37911ed37
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 1a7b0959bbd0d0ec529278a61c0056c277bffe75b2646e1699b46b10a90210be
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 9235bc4130a2ed4e6c35ea189dab35198ebb105640bedb97dd5269cc80863b16
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 9e1618775cceeb19f110e04fbc6c5bca6c8e4e9b116e193a42fe69bf602e7bcd
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+Miner:
+ IsTestMode: true
+ RootDir: "./data"
+ MaxReqTimeGap: "2s"
+ ProvideServiceInterval: "60s"
+KnownNodes:
+- ID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ Addr: 127.0.0.1:3122
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Leader
+- ID: 00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35
+ Nonce:
+ a: 478373
+ b: 0
+ c: 0
+ d: 2305843009893772025
+ Addr: 127.0.0.1:3121
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582
+ Nonce:
+ a: 259939
+ b: 0
+ c: 0
+ d: 2305843012544226372
+ Addr: 127.0.0.1:3120
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d
+ Nonce:
+ a: 22403
+ b: 0
+ c: 0
+ d: 0
+ Addr: ""
+ PublicKey: 02ec784ca599f21ef93fe7abdc68d78817ab6c9b31f2324d15ea174d9da498b4c4
+ Role: Client
+- ID: 000005aa62048f85da4ae9698ed59c14ec0d48a88a07c15a32265634e7e64ade
+ Nonce:
+ a: 567323
+ b: 0
+ c: 0
+ d: 3104982049
+ Addr: 127.0.0.1:2144
+ PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
+ Role: Miner
+- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
+ Nonce:
+ a: 240524
+ b: 0
+ c: 0
+ d: 2305843010430351476
+ Addr: 127.0.0.1:2145
+ PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
+ Role: Miner
+- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
+ Nonce:
+ a: 606016
+ b: 0
+ c: 0
+ d: 13835058056920509601
+ Addr: 127.0.0.1:2146
+ PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
+ Role: Miner
diff --git a/test/compatibility/node_miner_0/private.key b/test/compatibility/node_miner_0/private.key
new file mode 100644
index 000000000..12e7d3d80
--- /dev/null
+++ b/test/compatibility/node_miner_0/private.key
@@ -0,0 +1 @@
+8s_/W-7IyH_DyTG*M9C#8p%x>SߪRLmPB>{:̜뢷||
\ No newline at end of file
diff --git a/test/compatibility/node_miner_1/config.yaml b/test/compatibility/node_miner_1/config.yaml
new file mode 100644
index 000000000..6cec5bbc7
--- /dev/null
+++ b/test/compatibility/node_miner_1/config.yaml
@@ -0,0 +1,118 @@
+IsTestMode: true
+WorkingRoot: "./"
+PubKeyStoreFile: "public.keystore"
+PrivateKeyFile: "private.key"
+DHTFileName: "dht.db"
+ListenAddr: "127.0.0.1:2145"
+ThisNodeID: "000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5"
+QPS: 1000
+BillingBlockCount: 2
+ChainBusPeriod: 1s
+BPPeriod: 3s
+BPTick: 1s
+SQLChainPeriod: 3s
+SQLChainTick: 1s
+SQLChainTTL: 10
+MinProviderDeposit: 1000000
+ValidDNSKeys:
+ koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
+ mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
+BlockProducer:
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ ChainFileName: "chain.db"
+ BPGenesisInfo:
+ Version: 1
+ BlockHash: f745ca6427237aac858dd3c7f2df8e6f3c18d0f1c164e07a1c6b8eebeba6b154
+ Producer: 0000000000000000000000000000000000000000000000000000000000000001
+ MerkleRoot: 0000000000000000000000000000000000000000000000000000000000000001
+ ParentHash: 0000000000000000000000000000000000000000000000000000000000000001
+ Timestamp: 2018-08-13T21:59:59.12Z
+ BaseAccounts:
+ - Address: ba0ba731c7a76ccef2c1170f42038f7e228dfb474ef0190dfe35d9a37911ed37
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 1a7b0959bbd0d0ec529278a61c0056c277bffe75b2646e1699b46b10a90210be
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 9235bc4130a2ed4e6c35ea189dab35198ebb105640bedb97dd5269cc80863b16
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 9e1618775cceeb19f110e04fbc6c5bca6c8e4e9b116e193a42fe69bf602e7bcd
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+Miner:
+ IsTestMode: true
+ RootDir: "./data"
+ MaxReqTimeGap: "2s"
+ ProvideServiceInterval: "60s"
+KnownNodes:
+- ID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ Addr: 127.0.0.1:3122
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Leader
+- ID: 00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35
+ Nonce:
+ a: 478373
+ b: 0
+ c: 0
+ d: 2305843009893772025
+ Addr: 127.0.0.1:3121
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582
+ Nonce:
+ a: 259939
+ b: 0
+ c: 0
+ d: 2305843012544226372
+ Addr: 127.0.0.1:3120
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d
+ Nonce:
+ a: 22403
+ b: 0
+ c: 0
+ d: 0
+ Addr: ""
+ PublicKey: 02ec784ca599f21ef93fe7abdc68d78817ab6c9b31f2324d15ea174d9da498b4c4
+ Role: Client
+- ID: 000005aa62048f85da4ae9698ed59c14ec0d48a88a07c15a32265634e7e64ade
+ Nonce:
+ a: 567323
+ b: 0
+ c: 0
+ d: 3104982049
+ Addr: 127.0.0.1:2144
+ PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
+ Role: Miner
+- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
+ Nonce:
+ a: 240524
+ b: 0
+ c: 0
+ d: 2305843010430351476
+ Addr: 127.0.0.1:2145
+ PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
+ Role: Miner
+- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
+ Nonce:
+ a: 606016
+ b: 0
+ c: 0
+ d: 13835058056920509601
+ Addr: 127.0.0.1:2146
+ PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
+ Role: Miner
diff --git a/test/compatibility/node_miner_1/private.key b/test/compatibility/node_miner_1/private.key
new file mode 100644
index 000000000..44e8915e6
--- /dev/null
+++ b/test/compatibility/node_miner_1/private.key
@@ -0,0 +1,2 @@
+s]](o3R
+D5*9C
7ZinƋSp*SS5^ޑax>Xо2#IxRw+Ŕ
\ No newline at end of file
diff --git a/test/compatibility/node_miner_2/config.yaml b/test/compatibility/node_miner_2/config.yaml
new file mode 100644
index 000000000..ec0ac5060
--- /dev/null
+++ b/test/compatibility/node_miner_2/config.yaml
@@ -0,0 +1,118 @@
+IsTestMode: true
+WorkingRoot: "./"
+PubKeyStoreFile: "public.keystore"
+PrivateKeyFile: "private.key"
+DHTFileName: "dht.db"
+ListenAddr: "127.0.0.1:2146"
+ThisNodeID: "000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8"
+QPS: 1000
+BillingBlockCount: 2
+ChainBusPeriod: 1s
+BPPeriod: 3s
+BPTick: 1s
+SQLChainPeriod: 3s
+SQLChainTick: 1s
+SQLChainTTL: 10
+MinProviderDeposit: 1000000
+ValidDNSKeys:
+ koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
+ mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: cloudflare.com
+ oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==: cloudflare.com
+BlockProducer:
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ NodeID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ ChainFileName: "chain.db"
+ BPGenesisInfo:
+ Version: 1
+ BlockHash: f745ca6427237aac858dd3c7f2df8e6f3c18d0f1c164e07a1c6b8eebeba6b154
+ Producer: 0000000000000000000000000000000000000000000000000000000000000001
+ MerkleRoot: 0000000000000000000000000000000000000000000000000000000000000001
+ ParentHash: 0000000000000000000000000000000000000000000000000000000000000001
+ Timestamp: 2018-08-13T21:59:59.12Z
+ BaseAccounts:
+ - Address: ba0ba731c7a76ccef2c1170f42038f7e228dfb474ef0190dfe35d9a37911ed37
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 1a7b0959bbd0d0ec529278a61c0056c277bffe75b2646e1699b46b10a90210be
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 9235bc4130a2ed4e6c35ea189dab35198ebb105640bedb97dd5269cc80863b16
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+ - Address: 9e1618775cceeb19f110e04fbc6c5bca6c8e4e9b116e193a42fe69bf602e7bcd
+ StableCoinBalance: 10000000000000000000
+ CovenantCoinBalance: 10000000000000000000
+Miner:
+ IsTestMode: true
+ RootDir: "./data"
+ MaxReqTimeGap: "2s"
+ ProvideServiceInterval: "60s"
+KnownNodes:
+- ID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ Addr: 127.0.0.1:3122
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Leader
+- ID: 00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35
+ Nonce:
+ a: 478373
+ b: 0
+ c: 0
+ d: 2305843009893772025
+ Addr: 127.0.0.1:3121
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582
+ Nonce:
+ a: 259939
+ b: 0
+ c: 0
+ d: 2305843012544226372
+ Addr: 127.0.0.1:3120
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d
+ Nonce:
+ a: 22403
+ b: 0
+ c: 0
+ d: 0
+ Addr: ""
+ PublicKey: 02ec784ca599f21ef93fe7abdc68d78817ab6c9b31f2324d15ea174d9da498b4c4
+ Role: Client
+- ID: 000005aa62048f85da4ae9698ed59c14ec0d48a88a07c15a32265634e7e64ade
+ Nonce:
+ a: 567323
+ b: 0
+ c: 0
+ d: 3104982049
+ Addr: 127.0.0.1:2144
+ PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
+ Role: Miner
+- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
+ Nonce:
+ a: 240524
+ b: 0
+ c: 0
+ d: 2305843010430351476
+ Addr: 127.0.0.1:2145
+ PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
+ Role: Miner
+- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
+ Nonce:
+ a: 606016
+ b: 0
+ c: 0
+ d: 13835058056920509601
+ Addr: 127.0.0.1:2146
+ PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
+ Role: Miner
diff --git a/test/compatibility/node_miner_2/private.key b/test/compatibility/node_miner_2/private.key
new file mode 100644
index 000000000..adb437e75
--- /dev/null
+++ b/test/compatibility/node_miner_2/private.key
@@ -0,0 +1 @@
+6i.i%8pVVrLBKb: 1;(fF&y췥 RW3?CA;e"K2
\ No newline at end of file
diff --git a/test/compatibility/specific_old.sh b/test/compatibility/specific_old.sh
new file mode 100755
index 000000000..eec7174ee
--- /dev/null
+++ b/test/compatibility/specific_old.sh
@@ -0,0 +1,69 @@
+#!/bin/bash -x
+test_case=$1
+set -e
+
+TEST_WD=$(cd $(dirname $0)/; pwd)
+PROJECT_DIR=$(cd ${TEST_WD}/../../; pwd)
+
+OLD_BIN_DIR=${CACHE_DIR}/${PREV_VERSION}
+NEW_BIN_DIR=${PROJECT_DIR}/bin
+
+LOGS_DIR=${PIPELINE_CACHE}/logs/old_${test_case}
+mkdir -p ${LOGS_DIR}
+
+case $test_case in
+ "client")
+ CLIENTBIN=${OLD_BIN_DIR}/cql
+ BPBIN=${NEW_BIN_DIR}/cqld
+ MINERBIN=${NEW_BIN_DIR}/cql-minerd
+ ;;
+ "bp")
+ CLIENTBIN=${NEW_BIN_DIR}/cql
+ BPBIN=${OLD_BIN_DIR}/cqld
+ MINERBIN=${NEW_BIN_DIR}/cql-minerd
+ ;;
+ "miner")
+ CLIENTBIN=${NEW_BIN_DIR}/cql
+ BPBIN=${NEW_BIN_DIR}/cqld
+ MINERBIN=${OLD_BIN_DIR}/cql-minerd
+ ;;
+ *)
+ exit 1
+ ;;
+esac
+
+cd ${TEST_WD}
+# start bp
+nohup ${BPBIN} -config node_0/config.yaml >${LOGS_DIR}/bp0.log 2>&1 &
+nohup ${BPBIN} -config node_1/config.yaml >${LOGS_DIR}/bp1.log 2>&1 &
+nohup ${BPBIN} -config node_2/config.yaml >${LOGS_DIR}/bp2.log 2>&1 &
+
+# wait bp start
+sleep 20
+
+# start miner
+nohup ${MINERBIN} -config node_miner_0/config.yaml >${LOGS_DIR}/miner0.log 2>&1 &
+nohup ${MINERBIN} -config node_miner_1/config.yaml >${LOGS_DIR}/miner1.log 2>&1 &
+nohup ${MINERBIN} -config node_miner_2/config.yaml >${LOGS_DIR}/miner2.log 2>&1 &
+
+# wait miner start
+sleep 20
+
+${CLIENTBIN} -config node_c/config.yaml -get-balance
+
+${CLIENTBIN} -config node_c/config.yaml -create 2 -wait-tx-confirm | tee dsn.txt
+
+#get dsn
+dsn=$(cat dsn.txt)
+if [ -z "$dsn" ]; then
+ exit 1
+fi
+
+${CLIENTBIN} -config ${PROJECT_DIR}/test/integration/node_c/config.yaml -dsn ${dsn} \
+ -command 'create table test_for_new_account(column1 int);'
+
+${CLIENTBIN} -config ${PROJECT_DIR}/test/integration/node_c/config.yaml -dsn ${dsn} \
+ -command 'show tables;' | tee result.log
+
+grep "1 row" result.log
+
diff --git a/test/testnet_client/run.sh b/test/testnet_client/run.sh
index a17511d0c..5e53cd7d2 100755
--- a/test/testnet_client/run.sh
+++ b/test/testnet_client/run.sh
@@ -1,9 +1,9 @@
#!/bin/bash -x
-
set -e
TEST_WD=$(cd $(dirname $0)/; pwd)
PROJECT_DIR=$(cd ${TEST_WD}/../../; pwd)
+BIN=${PROJECT_DIR}/bin
echo ${PROJECT_DIR}
@@ -12,27 +12,28 @@ echo ${PROJECT_DIR}
# cd ${PROJECT_DIR} && make use_all_cores
cd ${TEST_WD}
-echo -ne "y\n" | ${PROJECT_DIR}/bin/cql-utils -tool confgen -skip-master-key
-${PROJECT_DIR}/bin/cql-utils -tool addrgen -skip-master-key | tee wallet.txt
+
+echo -ne "y\n" | ${BIN}/cql-utils -tool confgen -skip-master-key
#get wallet addr
+${BIN}/cql-utils -tool addrgen -skip-master-key | tee wallet.txt
wallet=$(awk '{print $3}' wallet.txt)
#transfer some coin to above address
-${PROJECT_DIR}/bin/cql -config ${PROJECT_DIR}/conf/testnet/config.yaml -transfer \
+${BIN}/cql -config ${PROJECT_DIR}/conf/testnet/config.yaml -transfer \
'{"addr":"'${wallet}'", "amount":"100000000 Particle"}' -wait-tx-confirm
-${PROJECT_DIR}/bin/cql -get-balance
+${BIN}/cql -get-balance
-${PROJECT_DIR}/bin/cql -create 2 -wait-tx-confirm | tee dsn.txt
+${BIN}/cql -create 2 -wait-tx-confirm | tee dsn.txt
#get dsn
dsn=$(cat dsn.txt)
-${PROJECT_DIR}/bin/cql -dsn ${dsn} \
+${BIN}/cql -dsn ${dsn} \
-command 'create table test_for_new_account(column1 int);'
-${PROJECT_DIR}/bin/cql -dsn ${dsn} \
+${BIN}/cql -dsn ${dsn} \
-command 'show tables;' | tee result.log
grep "1 row" result.log
diff --git a/utils/log/debug/handler.go b/utils/log/debug/handler.go
new file mode 100644
index 000000000..45a3fa45b
--- /dev/null
+++ b/utils/log/debug/handler.go
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2019 The CovenantSQL Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package debug
+
+import (
+ "encoding/json"
+ "net/http"
+
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
+)
+
+func init() {
+ http.HandleFunc("/debug/covenantsql/loglevel",
+ func(w http.ResponseWriter, req *http.Request) {
+ data := map[string]interface{}{}
+ switch req.Method {
+ case http.MethodPost:
+ level := req.FormValue("level")
+ data["orig"] = log.GetLevel().String()
+ if level != "" {
+ data["want"] = level
+ lvl, err := log.ParseLevel(level)
+ if err != nil {
+ data["err"] = err.Error()
+ } else {
+ // set level
+ log.SetLevel(lvl)
+ }
+ }
+ fallthrough
+ case http.MethodGet:
+ data["level"] = log.GetLevel().String()
+ _ = json.NewEncoder(w).Encode(data)
+ default:
+ w.WriteHeader(http.StatusBadRequest)
+ }
+ },
+ )
+}
diff --git a/utils/log/debug/handler_test.go b/utils/log/debug/handler_test.go
new file mode 100644
index 000000000..8ba588dd2
--- /dev/null
+++ b/utils/log/debug/handler_test.go
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2019 The CovenantSQL Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package debug_test
+
+import (
+ "encoding/json"
+ "net"
+ "net/http"
+ "testing"
+
+ "github.com/jmoiron/jsonq"
+ . "github.com/smartystreets/goconvey/convey"
+
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
+)
+
+func parseResponse(resp *http.Response, r error) (result *jsonq.JsonQuery, err error) {
+ if r != nil {
+ err = r
+ return
+ }
+
+ var res map[string]interface{}
+ err = json.NewDecoder(resp.Body).Decode(&res)
+ if err != nil {
+ return
+ }
+
+ result = jsonq.NewQuery(res)
+ return
+}
+
+func mustJSONQ(c C) func(interface{}, error) interface{} {
+ return func(i interface{}, e error) interface{} {
+ c.So(e, ShouldBeNil)
+ return i
+ }
+}
+
+func TestDebugHandler(t *testing.T) {
+ Convey("test debug handler", t, func(c C) {
+ server := http.Server{}
+ listener, err := net.Listen("tcp", ":0")
+ So(err, ShouldBeNil)
+ defer func() {
+ _ = listener.Close()
+ }()
+ go func() {
+ _ = server.Serve(listener)
+ }()
+ log.SetLevel(log.DebugLevel)
+ url := "http://" + listener.Addr().String() + "/debug/covenantsql/loglevel"
+ resp, err := parseResponse(http.Get(url))
+ So(err, ShouldBeNil)
+ So(mustJSONQ(c)(resp.String("level")), ShouldEqual, log.GetLevel().String())
+ resp, err = parseResponse(http.PostForm(url, map[string][]string{"level": {"fatal"}}))
+ So(err, ShouldBeNil)
+ So(mustJSONQ(c)(resp.String("level")), ShouldEqual, log.GetLevel().String())
+ So(log.GetLevel().String(), ShouldEqual, "fatal")
+ So(mustJSONQ(c)(resp.String("orig")), ShouldEqual, "debug")
+ So(mustJSONQ(c)(resp.String("want")), ShouldEqual, "fatal")
+ resp, err = parseResponse(http.PostForm(url, map[string][]string{"level": {"info"}}))
+ So(err, ShouldBeNil)
+ So(mustJSONQ(c)(resp.String("level")), ShouldEqual, log.GetLevel().String())
+ So(log.GetLevel().String(), ShouldEqual, "info")
+ So(mustJSONQ(c)(resp.String("orig")), ShouldEqual, "fatal")
+ So(mustJSONQ(c)(resp.String("want")), ShouldEqual, "info")
+
+ // test invalid level
+ resp, err = parseResponse(http.PostForm(url, map[string][]string{"level": {"happy"}}))
+ So(err, ShouldBeNil)
+ So(mustJSONQ(c)(resp.String("level")), ShouldEqual, log.GetLevel().String())
+ So(log.GetLevel().String(), ShouldEqual, "info")
+ So(mustJSONQ(c)(resp.String("orig")), ShouldEqual, "info")
+ So(mustJSONQ(c)(resp.String("want")), ShouldEqual, "happy")
+ So(mustJSONQ(c)(resp.String("err")), ShouldNotBeEmpty)
+
+ // test empty level
+ resp, err = parseResponse(http.PostForm(url, nil))
+ So(err, ShouldBeNil)
+ So(mustJSONQ(c)(resp.String("level")), ShouldEqual, log.GetLevel().String())
+ So(log.GetLevel().String(), ShouldEqual, "info")
+ So(mustJSONQ(c)(resp.String("orig")), ShouldEqual, "info")
+
+ // test invalid query
+ rawResp, err := http.Head(url)
+ So(err, ShouldBeNil)
+ So(rawResp.StatusCode, ShouldEqual, http.StatusBadRequest)
+
+ })
+}
diff --git a/utils/signal.go b/utils/signal.go
new file mode 100644
index 000000000..c348d8ea1
--- /dev/null
+++ b/utils/signal.go
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2019 The CovenantSQL Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package utils
+
+import (
+ "os"
+ "os/signal"
+ "syscall"
+)
+
+// WaitForExit waits for user cancellation signals: SIGINT/SIGTERM and ignore SIGHUP/SIGTTIN/SIGTTOU.
+func WaitForExit() <-chan os.Signal {
+ signalCh := make(chan os.Signal, 1)
+ signal.Notify(
+ signalCh,
+ syscall.SIGINT,
+ syscall.SIGTERM,
+ )
+ signal.Ignore(syscall.SIGHUP, syscall.SIGTTIN, syscall.SIGTTOU)
+ return signalCh
+}
diff --git a/xenomint/query_sanitizer.go b/xenomint/query_sanitizer.go
index 81119fede..25dc32c14 100644
--- a/xenomint/query_sanitizer.go
+++ b/xenomint/query_sanitizer.go
@@ -76,7 +76,7 @@ var (
func convertQueryAndBuildArgs(pattern string, args []types.NamedArg) (containsDDL bool, p string, ifs []interface{}, err error) {
if lower := strings.ToLower(pattern); strings.Contains(lower, "begin") ||
- strings.Contains(lower, "rollback") {
+ strings.Contains(lower, "rollback") || strings.Contains(lower, "commit") {
return false, pattern, nil, nil
}
var (
diff --git a/xenomint/state.go b/xenomint/state.go
index e7034a620..7bcbf5557 100644
--- a/xenomint/state.go
+++ b/xenomint/state.go
@@ -404,6 +404,11 @@ func (s *State) write(
}
defer s.executer.Exec(`ROLLBACK TO "?"`, lastSeq)
}
+ if s.level != sql.LevelReadUncommitted {
+ // NOTE(leventeliu): this will cancel any uncommitted transaction, and do not harm to
+ // committed ones.
+ defer s.executer.Exec(`ROLLBACK`)
+ }
for i, v := range req.Payload.Queries {
var res sql.Result
if res, ierr = s.writeSingle(ctx, &v); ierr != nil {
@@ -426,10 +431,6 @@ func (s *State) write(
return
}
}
- } else {
- // NOTE(leventeliu): this will cancel any uncommitted transaction, and do not harm to
- // committed ones.
- s.executer.Exec(`ROLLBACK`)
}
// Try to commit if the ongoing tx is too large or schema is changed
if s.getSeq()-s.getLastCommitPoint() > s.maxTx ||
diff --git a/xenomint/state_test.go b/xenomint/state_test.go
index 8c058d831..9811f38be 100644
--- a/xenomint/state_test.go
+++ b/xenomint/state_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"os"
"path"
+ "reflect"
"sync"
"testing"
@@ -702,6 +703,72 @@ func TestSerializableState(t *testing.T) {
_, resp, err = state.Query(req, true)
So(err, ShouldBeNil)
So(resp, ShouldNotBeNil)
+ Convey("The state should keep consistent with committed transaction", func(c C) {
+ var (
+ count = 1000
+ insertQueries = make([]types.Query, count+2)
+ deleteQueries = make([]types.Query, count+2)
+ iReq, dReq *types.Request
+ )
+ insertQueries[0] = buildQuery(`BEGIN`)
+ deleteQueries[0] = buildQuery(`BEGIN`)
+ for i := 0; i < count; i++ {
+ insertQueries[i+1] = buildQuery(
+ `INSERT INTO t1(k, v) VALUES (?, ?)`, i, fmt.Sprintf("v%d", i),
+ )
+ deleteQueries[i+1] = buildQuery(`DELETE FROM t1 WHERE k=?`, i)
+ }
+ insertQueries[count+1] = buildQuery(`COMMIT`)
+ deleteQueries[count+1] = buildQuery(`COMMIT`)
+ iReq = buildRequest(types.WriteQuery, insertQueries)
+ dReq = buildRequest(types.WriteQuery, deleteQueries)
+
+ var (
+ wg = &sync.WaitGroup{}
+ ctx, cancel = context.WithCancel(context.Background())
+ )
+ defer func() {
+ cancel()
+ wg.Wait()
+ }()
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ var (
+ resp *types.Response
+ err error
+ )
+ for {
+ _, resp, err = state.Query(iReq, true)
+ c.So(err, ShouldBeNil)
+ c.Printf("insert affected rows: %d\n", resp.Header.AffectedRows)
+ _, resp, err = state.Query(dReq, true)
+ c.So(err, ShouldBeNil)
+ c.Printf("delete affected rows: %d\n", resp.Header.AffectedRows)
+ select {
+ case <-ctx.Done():
+ return
+ default:
+ }
+ }
+ }()
+
+ for i := 0; i < count; i++ {
+ _, resp, err = state.Query(buildRequest(types.ReadQuery, []types.Query{
+ buildQuery(`SELECT COUNT(1) AS cnt FROM t1`),
+ }), true)
+ So(reflect.DeepEqual(resp.Payload, types.ResponsePayload{
+ Columns: []string{"cnt"},
+ DeclTypes: []string{""},
+ Rows: []types.ResponseRow{{Values: []interface{}{int64(0)}}},
+ }) || reflect.DeepEqual(resp.Payload, types.ResponsePayload{
+ Columns: []string{"cnt"},
+ DeclTypes: []string{""},
+ Rows: []types.ResponseRow{{Values: []interface{}{int64(count)}}},
+ }), ShouldBeTrue)
+ Printf("index = %d, count = %v\n", i, resp)
+ }
+ })
Convey("The state should not see uncommitted changes", func(c C) {
// Build transaction query
var (
@@ -751,6 +818,82 @@ func TestSerializableState(t *testing.T) {
})
}
})
+ Convey("The state should see changes", FailureContinues, func(c C) {
+ // Build transaction query
+ var (
+ count = 1000
+ queries = make([]types.Query, count+2)
+ req *types.Request
+ )
+ queries[0] = buildQuery(`BEGIN`)
+ for i := 0; i < count; i++ {
+ queries[i+1] = buildQuery(
+ `INSERT INTO t1(k, v) VALUES (?, ?)`, i, fmt.Sprintf("v%d", i),
+ )
+ }
+ queries[count+1] = buildQuery(`COMMIT`)
+ req = buildRequest(types.WriteQuery, queries)
+ // Send uncommitted transaction on background
+ var _, resp, err = state.Query(req, true)
+ c.So(err, ShouldBeNil)
+ c.So(resp.Header.RowCount, ShouldEqual, 0)
+
+ // Test isolation level
+ for i := 0; i < count; i++ {
+ _, resp, err = state.Query(buildRequest(types.ReadQuery, []types.Query{
+ buildQuery(`SELECT COUNT(1) AS cnt FROM t1`),
+ }), true)
+ So(resp.Payload, ShouldResemble, types.ResponsePayload{
+ Columns: []string{"cnt"},
+ DeclTypes: []string{""},
+ Rows: []types.ResponseRow{{Values: []interface{}{int64(count)}}},
+ })
+ }
+
+ req = buildRequest(types.WriteQuery, []types.Query{
+ buildQuery("DELETE FROM t1"),
+ })
+ _, resp, err = state.Query(req, true)
+ c.So(err, ShouldBeNil)
+ })
+ Convey("The state should not see changes because of failure query content", FailureContinues, func(c C) {
+ // Build transaction query
+ var (
+ count = 1000
+ queries = make([]types.Query, count+3)
+ req *types.Request
+ )
+ queries[0] = buildQuery(`BEGIN`)
+ for i := 0; i < count; i++ {
+ queries[i+1] = buildQuery(
+ `INSERT INTO t1(k, v) VALUES (?, ?)`, i, fmt.Sprintf("v%d", i),
+ )
+ }
+ queries[count+1] = buildQuery(`HAHA`)
+ queries[count+2] = buildQuery(`COMMIT`)
+ req = buildRequest(types.WriteQuery, queries)
+ // Send uncommitted transaction on background
+ var _, resp, err = state.Query(req, true)
+ c.So(err, ShouldNotBeNil)
+
+ // Test isolation level
+ for i := 0; i < count; i++ {
+ _, resp, err = state.Query(buildRequest(types.ReadQuery, []types.Query{
+ buildQuery(`SELECT COUNT(1) AS cnt FROM t1`),
+ }), true)
+ So(resp.Payload, ShouldResemble, types.ResponsePayload{
+ Columns: []string{"cnt"},
+ DeclTypes: []string{""},
+ Rows: []types.ResponseRow{{Values: []interface{}{int64(0)}}},
+ })
+ }
+
+ req = buildRequest(types.WriteQuery, []types.Query{
+ buildQuery("DELETE FROM t1"),
+ })
+ _, resp, err = state.Query(req, true)
+ c.So(err, ShouldBeNil)
+ })
})
})
}
diff --git a/xenomint/xxx_test.go b/xenomint/xxx_test.go
index a670fca3e..b0a7686d0 100644
--- a/xenomint/xxx_test.go
+++ b/xenomint/xxx_test.go
@@ -21,6 +21,7 @@ import (
"math/rand"
"os"
"path"
+ "runtime"
"sync"
"sync/atomic"
"syscall"
@@ -198,16 +199,18 @@ func setup() {
rand.Seed(time.Now().UnixNano())
- // Set NOFILE limit
- if err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lmt); err != nil {
- panic(err)
- }
- if lmt.Max < minNoFile {
- panic("insufficient max RLIMIT_NOFILE")
- }
- lmt.Cur = lmt.Max
- if err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &lmt); err != nil {
- panic(err)
+ if runtime.GOOS == "linux" {
+ // Set NOFILE limit
+ if err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lmt); err != nil {
+ panic(err)
+ }
+ if lmt.Max < minNoFile {
+ panic("insufficient max RLIMIT_NOFILE")
+ }
+ lmt.Cur = lmt.Max
+ if err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &lmt); err != nil {
+ panic(err)
+ }
}
// Initialze kms