diff --git a/.gitignore b/.gitignore
index 1d2e9fce5..0ce9eb7e2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,6 @@
+*.trace
pprof.txt
+.dsn
*.svg
*.profile
*.key
@@ -28,6 +30,7 @@ bin/
*.test
bin/*
test/log/
+test/covenantsql*
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
diff --git a/.travis.yml b/.travis.yml
index 9b787d406..676511089 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,7 +4,7 @@ env:
- secure: "CNZXODvXHMB0z6Z+Jd8MjzP+RYgRzkykRNpZdCDCo6AC57BpV5U20Mn9o2MGhTA9lMgtyNXXEaQxeIGZMFp3iB2UHiPif1UD4C0uDttytTuCcmHMlBIVP8GiNcAexi1Zv2SchM1k8z3tw5zDhkYMwjs/4ZsGVXHa1ip/UzpZaJBPl9D64wedJxZGBjS/Kn9IZTrMkL2otr8rKk0ZFMtwDkHKdjfikZ+PAlkYpX2a2Dp69HTLbEtx+ugocNj02hzgVYNpFXA1K0CulyCYJq7oqdx0UFbtKEd3urYFWfmxEZSg6SoHcIujC+/BKfZELFyA3uomp+cLpGaRlEp/iAlj/ixTo4iFtu6XdDOim4J9ZVtNSg6DdDstL9uhxCu+vca/ntViGfyw6CF0hKcHTZvlH2awiV1njmHFdRvoaMy/1fdw1JAV9O7ylU3bV5GrF6fMQ1CpweYCnF3IMpvvwdeUnGR6NPvqjybcnyXoTXZ139PxfWzbUzSG8KbOvzt1aVhWF5184b8fqhN3768Y1stke+FjFpARqlPVsfzS7fnn5kx8zZ5nfmwZjnL/WFob24mvm+/9e7IsfWmeEQdFspD+spBE4WOta7tegqh5ANNfM2owd9evtH5kqlCLeAVD3LMs69ZQW45KS0rDJpY8+ffMWRJRmoM/pweW3CmbHPeb468="
# https://codecov.io/gh/CovenantSQL/CovenantSQL
- secure: "iJVHTJ8NNzb3UKgh8VRXZg+XVXxcnH10dPDyg44Osp67bkwB46nIDAgDvPRZCX4Kr2Q7FCip1DT1DzkcxCBqCD7XgSsvtoP05kckWZf5dUp2qdaaBgFBR5F2ijhTgpqSG2/MZyY/9DRZhfd/DTywo4K4cGRGpjUYm7BSmR/5ou1Dk6CksoPFMwkE0zHVdRBkRoMaqqVGl9uxFyU6ssZ9IFsLbbSiJ+/iFZDbfBMuzhpxziJ4Oli1LrveEMCCnwKFgVURD3bVUtHrpdQ1RNJQzjkM8tvtilrh3Sf5X9+sJ8K+N1NnzDJiPnEZfkd69vDSh5gEivgIg3j9zIgQGfreDoKCOTfEgzGxRaPusokLQUyDGcU0ZMtLV3mzikeWJ1nUv7jOR8RF97KoJL/ZEgK5Owh5w3WhA+EcvuWC5gggi5Lx2mf7AK6zbm5JiOomBZLINKnygT+tHOKbuglDgP2UL7OBDE3xCI+WT4q3Zz6VKuNdwEFv81Qg925QFr9ifZlCPSzaNHkepEGji++3yFaEPTEtS3TzM+DTqOefU/I1q4IFvgHRMh4M7AbYQPx1m6H/2kk9xwycMD6HtHHwA9Yk2jnMUM085lL1W3A2gEn3V73lm99jQuECW8AgYQ3o9J8BpuVuZnH9n5uXjyFPrhc2tCUPDrBes/phFfJycSrGq0Y="
- - REVIEWDOG_VERSION=0.9.9
+ - REVIEWDOG_VERSION=0.9.11
language: go
go:
- '1.11'
@@ -34,15 +34,17 @@ before_script:
- echo $TRAVIS_SECURE_ENV_VARS
script:
- bash build.sh
- - go test -v -race $(go list ./... | grep -v "/vendor/") -coverprofile cover.out
+ - go test -v -race -failfast -parallel 16 $(go list ./... | grep -v "/vendor/") -coverprofile cover.out
+ - cd rpc && go test -test.bench ^BenchmarkPersistentCaller_Call$ -test.run ^$ && cd -
- gocovmerge cover.out $(find cmd -name "*.cover.out") > coverage.txt && rm -f cover.out
- bash <(curl -s https://codecov.io/bash)
- >-
golint ./... | grep -v 'vendor/' | grep -v 'server/' | grep -v 'utils/' | reviewdog -f=golint -reporter=github-pr-review || true
before_deploy:
+ - bash build.sh
- mkdir -p build
- - tar czvf build/CovenantSQL-$TRAVIS_TAG.$TRAVIS_OS_NAME-amd64.tar.gz bin/cql*
+ - tar czvf build/CovenantSQL-$TRAVIS_TAG.$TRAVIS_OS_NAME-amd64.tar.gz $(ls bin/cql* | grep -v test)
deploy:
provider: releases
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 28274c80e..bcca8da03 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,31 @@
# Changelog
+## [v0.0.3](https://github.com/CovenantSQL/CovenantSQL/tree/v0.0.3) (2018-11-04)
+
+[Full Changelog](https://github.com/CovenantSQL/CovenantSQL/compare/v0.0.2...v0.0.3)
+
+**Fixed bugs:**
+
+- Cannot receive tokens from testnet [\#84](https://github.com/CovenantSQL/CovenantSQL/issues/84)
+- Potential deadlock in testing [\#93](https://github.com/CovenantSQL/CovenantSQL/issues/93)
+
+**Closed issues:**
+
+- Command cqld -version failed without -config parameter [\#99](https://github.com/CovenantSQL/CovenantSQL/issues/99)
+
+**Merged pull requests:**
+
+- Add call stack print for Error, Fatal and Panic [\#108](https://github.com/CovenantSQL/CovenantSQL/pull/108) ([auxten](https://github.com/auxten))
+- Update GNTE submodule to it's newest master [\#105](https://github.com/CovenantSQL/CovenantSQL/pull/105) ([laodouya](https://github.com/laodouya))
+- Add GNTE bench test [\#102](https://github.com/CovenantSQL/CovenantSQL/pull/102) ([laodouya](https://github.com/laodouya))
+- Use leveldb to instead boltdb on sqlchain [\#101](https://github.com/CovenantSQL/CovenantSQL/pull/101) ([zeqing-guo](https://github.com/zeqing-guo))
+- Update Dockerfile, using go1.11 instead [\#100](https://github.com/CovenantSQL/CovenantSQL/pull/100) ([laodouya](https://github.com/laodouya))
+- Replace hashicorp/yamux with xtaci/smux [\#98](https://github.com/CovenantSQL/CovenantSQL/pull/98) ([auxten](https://github.com/auxten))
+- Update MySQL Adapter to support mysql-java-connector/SequelPro/Navicat [\#96](https://github.com/CovenantSQL/CovenantSQL/pull/96) ([xq262144](https://github.com/xq262144))
+- Minerd performance tuning [\#95](https://github.com/CovenantSQL/CovenantSQL/pull/95) ([auxten](https://github.com/auxten))
+- Update README [\#91](https://github.com/CovenantSQL/CovenantSQL/pull/91) ([foreseaz](https://github.com/foreseaz))
+- Blockproducer Explorer feature including Transaction type encode/decode improvements [\#90](https://github.com/CovenantSQL/CovenantSQL/pull/90) ([xq262144](https://github.com/xq262144))
+
## [v0.0.2](https://github.com/CovenantSQL/CovenantSQL/tree/v0.0.2) (2018-10-17)
[Full Changelog](https://github.com/CovenantSQL/CovenantSQL/compare/v0.0.1...v0.0.2)
@@ -51,12 +77,13 @@
**Merged pull requests:**
-- Make cql-utils and README.md less ambiguous [\#77](https://github.com/CovenantSQL/CovenantSQL/pull/77) ([auxten](https://github.com/auxten))
+- Make idminer and README.md less ambiguous [\#77](https://github.com/CovenantSQL/CovenantSQL/pull/77) ([auxten](https://github.com/auxten))
- Make all path config in adapter relative to working root configuration [\#76](https://github.com/CovenantSQL/CovenantSQL/pull/76) ([auxten](https://github.com/auxten))
+- TestNet faucet for CovenantSQL API demo [\#75](https://github.com/CovenantSQL/CovenantSQL/pull/75) ([auxten](https://github.com/auxten))
- HTTPS RESTful API for CovenantSQL [\#74](https://github.com/CovenantSQL/CovenantSQL/pull/74) ([xq262144](https://github.com/xq262144))
- Unify the nonce increment, BaseAccount also increases account nonce. [\#73](https://github.com/CovenantSQL/CovenantSQL/pull/73) ([leventeliu](https://github.com/leventeliu))
- Fix a nonce checking issue and add more specific test cases. [\#72](https://github.com/CovenantSQL/CovenantSQL/pull/72) ([leventeliu](https://github.com/leventeliu))
-- Add an cql-utils readme for generating key pair and testnet address [\#71](https://github.com/CovenantSQL/CovenantSQL/pull/71) ([zeqing-guo](https://github.com/zeqing-guo))
+- Add an idminer readme for generating key pair and testnet address [\#71](https://github.com/CovenantSQL/CovenantSQL/pull/71) ([zeqing-guo](https://github.com/zeqing-guo))
- Add BenchmarkSingleMiner, use rpc.NewPersistentCaller for client conn [\#70](https://github.com/CovenantSQL/CovenantSQL/pull/70) ([auxten](https://github.com/auxten))
- Add RPC methods for balance query. [\#69](https://github.com/CovenantSQL/CovenantSQL/pull/69) ([leventeliu](https://github.com/leventeliu))
- Addrgen to generate testnet address [\#68](https://github.com/CovenantSQL/CovenantSQL/pull/68) ([zeqing-guo](https://github.com/zeqing-guo))
@@ -65,7 +92,7 @@
- Add auto config generator [\#65](https://github.com/CovenantSQL/CovenantSQL/pull/65) ([zeqing-guo](https://github.com/zeqing-guo))
- Use a well-defined interface to process transactions on block producers. [\#64](https://github.com/CovenantSQL/CovenantSQL/pull/64) ([leventeliu](https://github.com/leventeliu))
- Add an explanation for non-deterministic authenticated encryption input vector [\#63](https://github.com/CovenantSQL/CovenantSQL/pull/63) ([auxten](https://github.com/auxten))
-- Add nonce generator in cql-utils [\#61](https://github.com/CovenantSQL/CovenantSQL/pull/61) ([zeqing-guo](https://github.com/zeqing-guo))
+- Add nonce generator in idminer [\#61](https://github.com/CovenantSQL/CovenantSQL/pull/61) ([zeqing-guo](https://github.com/zeqing-guo))
- Optional database encryption support on database creation. [\#60](https://github.com/CovenantSQL/CovenantSQL/pull/60) ([xq262144](https://github.com/xq262144))
- Clarify README.md for project and DH-RPC [\#59](https://github.com/CovenantSQL/CovenantSQL/pull/59) ([auxten](https://github.com/auxten))
- Rename ThunderDB to CovenantSQL [\#57](https://github.com/CovenantSQL/CovenantSQL/pull/57) ([zeqing-guo](https://github.com/zeqing-guo))
@@ -75,8 +102,6 @@
- Fix/issue-50: use major version tag in docker file [\#51](https://github.com/CovenantSQL/CovenantSQL/pull/51) ([leventeliu](https://github.com/leventeliu))
- Add DH-RPC example [\#49](https://github.com/CovenantSQL/CovenantSQL/pull/49) ([auxten](https://github.com/auxten))
- Merge cli tool to core code base [\#48](https://github.com/CovenantSQL/CovenantSQL/pull/48) ([xq262144](https://github.com/xq262144))
-- Add observer helper functions and binaries and hotfix binary for dht database migrations. [\#47](https://github.com/CovenantSQL/CovenantSQL/pull/47) ([xq262144](https://github.com/xq262144))
-- [More...](https://github.com/CovenantSQL/CovenantSQL/pulls?q=is%3Apr+is%3Aclosed)
diff --git a/Dockerfile b/Dockerfile
index 866681942..2f046e8a4 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
# Stage: builder
-FROM golang:1.10-stretch as builder
+FROM golang:1.11-stretch as builder
WORKDIR /go/src/github.com/CovenantSQL/CovenantSQL
COPY . .
diff --git a/Gopkg.lock b/Gopkg.lock
index 4fdec7120..563485179 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -19,7 +19,7 @@
[[projects]]
branch = "master"
- digest = "1:8d21b4d359da7c7e49800d2e6e186997bae08ea6f814b7ca20bbd76e72e0338d"
+ digest = "1:599cc68328d92a329d9ec7fd516ed5ac2abfaaafd5f824001adafcb0cf10fe49"
name = "github.com/CovenantSQL/sqlparser"
packages = [
".",
@@ -29,7 +29,7 @@
"dependency/sqltypes",
]
pruneopts = "UT"
- revision = "fe86852c12c8b9055d4d0731940014487dca1f12"
+ revision = "fb543cee920387ed5e85a2f098eba2dcc12b13c7"
[[projects]]
branch = "master"
@@ -119,6 +119,14 @@
revision = "583e8937c61f1af6513608ccc75c97b6abdf4ff9"
version = "v1.3.0"
+[[projects]]
+ branch = "master"
+ digest = "1:7b274cc72af687fe6eb618acd83b9601c4317fbe5ac1dfb41cc116e3495f68b0"
+ name = "github.com/cyberdelia/go-metrics-graphite"
+ packages = ["."]
+ pruneopts = "UT"
+ revision = "39f87cc3b432bbb898d7c643c0e93cac2bc865ad"
+
[[projects]]
branch = "master"
digest = "1:710109527a119c813d4fac773712dd92f449ed7c2f7b81f49822f94d290c8f72"
@@ -192,7 +200,7 @@
name = "github.com/gopherjs/gopherjs"
packages = ["js"]
pruneopts = "UT"
- revision = "1babbf986f6fcb1156d0646cdba5c4f81bc32849"
+ revision = "0766667cb4d1cfb8d5fde1fe210ae41ead3cf589"
[[projects]]
digest = "1:c79fb010be38a59d657c48c6ba1d003a8aa651fa56b579d959d74573b7dff8e1"
@@ -218,14 +226,6 @@
revision = "e3702bed27f0d39777b0b37b664b6280e8ef8fbf"
version = "v1.6.2"
-[[projects]]
- branch = "master"
- digest = "1:a4826c308e84f5f161b90b54a814f0be7d112b80164b9b884698a6903ea47ab3"
- name = "github.com/hashicorp/yamux"
- packages = ["."]
- pruneopts = "UT"
- revision = "2f1d1f20f75d5404f53b9edf6b53ed5505508675"
-
[[projects]]
branch = "master"
digest = "1:438016f7d4af8e5a7010b6d0705b267a7607ddc0decad051e83a9458c6b9a523"
@@ -307,12 +307,12 @@
version = "v1.0.1"
[[projects]]
- digest = "1:57689550840d285f2da9e85356a66e626592a8b6f1170d7f2482438e64fe82e3"
+ digest = "1:c22d250c583ec1136ecad8b74a43f408c08ddbbcbae715341ec4a49f332628e0"
name = "github.com/miekg/dns"
packages = ["."]
pruneopts = "UT"
- revision = "d74956db7b5b20451796774572d0f5a0222e377a"
- version = "v1.0.13"
+ revision = "915ca3d5ffd945235828a097c917311a9d86ebb4"
+ version = "v1.0.14"
[[projects]]
branch = "master"
@@ -348,14 +348,14 @@
[[projects]]
branch = "master"
- digest = "1:f43f7e80e273179b98af510dd453d184c7860920d6f9aa5c89e06aed0494a7a8"
+ digest = "1:f696f304d2a14745859a153f1041b66e0e2cf150eff731beb6431e93e27ddc5c"
name = "github.com/prometheus/client_golang"
packages = [
"prometheus",
"prometheus/internal",
]
pruneopts = "UT"
- revision = "1cafe34db7fdec6022e17e00e1c1ea501022f3e4"
+ revision = "f30f428035633da15d00d3dfefb0128c5e569ef4"
[[projects]]
branch = "master"
@@ -367,7 +367,7 @@
[[projects]]
branch = "master"
- digest = "1:95ed48ec01b571d453b17ed631c7b65be39ced2b5082f1426a2fa6991799846f"
+ digest = "1:6366b518dc6e520027f67ad03792b99e370468aac47c4102bddd56ae6ce780e5"
name = "github.com/prometheus/common"
packages = [
"expfmt",
@@ -376,7 +376,7 @@
"version",
]
pruneopts = "UT"
- revision = "bcb74de08d37a417cb6789eec1d6c810040f0470"
+ revision = "7e9e6cabbd393fc208072eedef99188d0ce788b6"
[[projects]]
branch = "master"
@@ -393,11 +393,19 @@
[[projects]]
branch = "master"
- digest = "1:ff6b0586c0621a76832cf783eee58cbb9d9795d2ce8acbc199a4131db11c42a9"
+ digest = "1:d38f81081a389f1466ec98192cf9115a82158854d6f01e1c23e2e7554b97db71"
+ name = "github.com/rcrowley/go-metrics"
+ packages = ["."]
+ pruneopts = "UT"
+ revision = "3113b8401b8a98917cde58f8bbd42a1b1c03b1fd"
+
+[[projects]]
+ branch = "master"
+ digest = "1:a3b8912deeef29007fab9a13a9f21b9e9b59c621a2ed61e2fe7b37320a71fbd5"
name = "github.com/satori/go.uuid"
packages = ["."]
pruneopts = "UT"
- revision = "36e9d2ebbde5e3f13ab2e25625fd453271d6522e"
+ revision = "b2ce2384e17bbe0c6d34077efa39dbab3e09123b"
[[projects]]
branch = "master"
@@ -423,7 +431,7 @@
[[projects]]
branch = "master"
- digest = "1:a730590f80ebe31a7c88a072500766c6094a14b03e0c6931e4a63a13f227edc4"
+ digest = "1:d3384958d1ace51e2187c9747d806eee27d1aebdb1a4df798058a8cacc19b379"
name = "github.com/siddontang/go-mysql"
packages = [
"mysql",
@@ -431,7 +439,8 @@
"server",
]
pruneopts = "UT"
- revision = "c8bed9e1e90b2121165ad80fe85a34ceff169999"
+ revision = "7f644882a1f315e77bfda60b4f689a45a2eec228"
+ source = "github.com/CovenantSQL/go-mysql"
[[projects]]
digest = "1:3f53e9e4dfbb664cd62940c9c4b65a2171c66acd0b7621a1a6b8e78513525a52"
@@ -539,11 +548,11 @@
[[projects]]
branch = "master"
- digest = "1:8a6b9b1c86f610eb347e6e5e42af0fc9aff52427c619dd70e9e61a79c6114106"
+ digest = "1:3863946ace74cbd518a33a2e8dd145a13aba1fc37a0e89788154083f183fca11"
name = "github.com/xo/tblfmt"
packages = ["."]
pruneopts = "UT"
- revision = "3ae3311c5ac954b9ec8a89eed14e395abbb069e4"
+ revision = "e82d5611beb24993cc6afc59cdacf6e598891d12"
[[projects]]
branch = "master"
@@ -555,7 +564,7 @@
[[projects]]
branch = "master"
- digest = "1:6162124bb1bdabe76e3da4a734a5109e8979e8cf4ddcc5c0efeb0a50bd3c1ef5"
+ digest = "1:70492e57eb4abe45c86ff3855b87a6681f15bcf7e12666596c1e826a9c95d99f"
name = "github.com/xo/usql"
packages = [
"drivers",
@@ -568,7 +577,16 @@
"text",
]
pruneopts = "UT"
- revision = "ee0ef60c5b0883dcb5caa67d5317c56d6389e779"
+ revision = "885ff880d8520d74c227a9d1a310aa473209d155"
+ source = "github.com/CovenantSQL/usql"
+
+[[projects]]
+ digest = "1:07aaea55c778d9f0461a429eb19a134f17e9ac3232a5a28b16dfe57c637889bc"
+ name = "github.com/xtaci/smux"
+ packages = ["."]
+ pruneopts = "UT"
+ revision = "545ecee9d2a96ef4cf3c420c6b4095ac313fe870"
+ version = "v1.09"
[[projects]]
digest = "1:4619abe2e9ceabced45ff40a4826866c48f264bb58384efe799a8fb83c2256e0"
@@ -588,7 +606,7 @@
"ssh/terminal",
]
pruneopts = "UT"
- revision = "0c41d7ab0a0ee717d4590a44bcb987dfd9e183eb"
+ revision = "45a5f77698d342a8c2ef8423abdf0ba6880b008a"
[[projects]]
branch = "master"
@@ -604,18 +622,18 @@
"ipv6",
]
pruneopts = "UT"
- revision = "49bb7cea24b1df9410e1712aa6433dae904ff66a"
+ revision = "c44066c5c816ec500d459a2a324a753f78531ae0"
[[projects]]
branch = "master"
- digest = "1:f5aa274a0377f85735edc7fedfb0811d3cbc20af91633797cb359e29c3272271"
+ digest = "1:d2605ed96ca0244a457fa8e6c37d5c370ce98ea09dcc21e5e07d967bfcb78878"
name = "golang.org/x/sys"
packages = [
"unix",
"windows",
]
pruneopts = "UT"
- revision = "fa43e7bc11baaae89f3f902b2b4d832b68234844"
+ revision = "95b1ffbd15a57cc5abb3f04402b9e8ec0016a52c"
[[projects]]
digest = "1:342378ac4dcb378a5448dd723f0784ae519383532f5e70ade24132c4c8693202"
@@ -637,11 +655,11 @@
"github.com/btcsuite/btcd/btcec",
"github.com/btcsuite/btcutil/base58",
"github.com/coreos/bbolt",
+ "github.com/cyberdelia/go-metrics-graphite",
"github.com/dyatlov/go-opengraph/opengraph",
"github.com/fortytw2/leaktest",
"github.com/gorilla/handlers",
"github.com/gorilla/mux",
- "github.com/hashicorp/yamux",
"github.com/jmoiron/jsonq",
"github.com/jordwest/mock-conn",
"github.com/lufia/iostat",
@@ -653,6 +671,7 @@
"github.com/prometheus/common/expfmt",
"github.com/prometheus/common/version",
"github.com/prometheus/procfs",
+ "github.com/rcrowley/go-metrics",
"github.com/satori/go.uuid",
"github.com/siddontang/go-mysql/mysql",
"github.com/siddontang/go-mysql/server",
@@ -671,6 +690,7 @@
"github.com/xo/usql/handler",
"github.com/xo/usql/rline",
"github.com/xo/usql/text",
+ "github.com/xtaci/smux",
"golang.org/x/crypto/ed25519",
"golang.org/x/crypto/ssh/terminal",
"golang.org/x/sys/unix",
diff --git a/Gopkg.toml b/Gopkg.toml
index 6c483cb82..89678703c 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -50,6 +50,7 @@
[[override]]
name = "github.com/xo/usql"
+ source = "github.com/CovenantSQL/usql"
branch = "master"
[[override]]
@@ -60,11 +61,15 @@
name = "github.com/CovenantSQL/xurls"
branch = "master"
+[[override]]
+ name = "github.com/siddontang/go-mysql"
+ source = "github.com/CovenantSQL/go-mysql"
+ branch = "master"
+
[prune]
go-tests = true
unused-packages = true
-
[[constraint]]
branch = "master"
name = "github.com/btcsuite/btcutil"
diff --git a/README.md b/README.md
index c4788fba3..b54cc285d 100644
--- a/README.md
+++ b/README.md
@@ -69,17 +69,17 @@ that inspired us:
## Libs
### Network Stack
-
-
-
- - [DH-RPC](rpc/) := TLS - Cert + DHT
- - RPC Layer: compatible with golang `net/rpc`
- - Naming Layer: [**C**onsistent **S**ecure **DHT**](https://godoc.org/github.com/CovenantSQL/CovenantSQL/consistent)
- - Pooling Layer: session pool built on Yamux
- - Multiplex Layer: Yamux by Hashicorp
- - Transport Security Layer: [**E**nhanced **TLS**](https://github.com/CovenantSQL/research/wiki/ETLS(Enhanced-Transport-Layer-Security))
- - Network Layer: TCP or KCP for optional later
+[DH-RPC](rpc/) := TLS - Cert + DHT
+
+| Layer | Implementation |
+|:-------------------|:--------------:|
+| RPC | `net/rpc` |
+| Naming | [**C**onsistent **S**ecure **DHT**](https://godoc.org/github.com/CovenantSQL/CovenantSQL/consistent) |
+| Pooling | Session Pool |
+| Multiplex | Yamux |
+| Transport Security | [**E**nhanced **TLS**](https://github.com/CovenantSQL/research/wiki/ETLS(Enhanced-Transport-Layer-Security)) |
+| Network | TCP or KCP for optional later |
#### Test Tools
@@ -89,14 +89,17 @@ that inspired us:
#### Connector
-CovenantSQL is Still Under Construction(U know..). Test net will be released till Oct.
+CovenantSQL is still under construction and Testnet is already released, [have a try](https://testnet.covenantsql.io/).
-Watch us or [](https://twitter.com/intent/follow?screen_name=CovenantLabs) for updates.
- [Golang](client/)
- [Java](https://github.com/CovenantSQL/covenant-connector)
+- [NodeJS](https://github.com/CovenantSQL/node-covenantsql)
+- [Python](https://github.com/CovenantSQL/python-driver)
- Coding for more……
+Watch us or [](https://twitter.com/intent/follow?screen_name=CovenantLabs) for updates.
+
## TestNet
- [Quick Start](https://testnet.covenantsql.io/quickstart)
diff --git a/bin/docker-entry.sh b/bin/docker-entry.sh
index 8726f5b77..fd5348d4a 100755
--- a/bin/docker-entry.sh
+++ b/bin/docker-entry.sh
@@ -24,5 +24,8 @@ cli)
faucet)
exec /app/cql-faucet -config ${COVENANT_CONF} "${@}"
;;
+explorer)
+ exec /app/cql-explorer -config ${COVENANT_CONF} "${@}"
+ ;;
esac
diff --git a/blockproducer/blockindex.go b/blockproducer/blockindex.go
index 02891bcae..a916b5902 100644
--- a/blockproducer/blockindex.go
+++ b/blockproducer/blockindex.go
@@ -35,12 +35,12 @@ func newBlockNode(h uint32, block *types.Block, parent *blockNode) *blockNode {
var count uint32
if parent != nil {
- count = parent.height + 1
+ count = parent.count + 1
} else {
count = 0
}
bn := &blockNode{
- hash: block.SignedHeader.BlockHash,
+ hash: *block.BlockHash(),
parent: parent,
height: h,
count: count,
@@ -79,6 +79,18 @@ func (bn *blockNode) ancestor(h uint32) *blockNode {
return ancestor
}
+func (bn *blockNode) ancestorByCount(c uint32) *blockNode {
+ if c > bn.count {
+ return nil
+ }
+
+ ancestor := bn
+ for ancestor != nil && ancestor.count != c {
+ ancestor = ancestor.parent
+ }
+ return ancestor
+}
+
type blockIndex struct {
mu sync.RWMutex
index map[hash.Hash]*blockNode
@@ -107,9 +119,9 @@ func (bi *blockIndex) hasBlock(h hash.Hash) bool {
return has
}
-func (bi *blockIndex) lookupBlock(h hash.Hash) *blockNode {
+func (bi *blockIndex) lookupNode(h *hash.Hash) *blockNode {
bi.mu.RLock()
defer bi.mu.RUnlock()
- return bi.index[h]
+ return bi.index[*h]
}
diff --git a/blockproducer/blockindex_test.go b/blockproducer/blockindex_test.go
index 4a244e993..67b08e32a 100644
--- a/blockproducer/blockindex_test.go
+++ b/blockproducer/blockindex_test.go
@@ -31,7 +31,7 @@ func TestNewBlockNodeAndIndexKey(t *testing.T) {
}
parent := newBlockNode(0, block, nil)
if parent == nil {
- t.Fatalf("unexpected result: nil")
+ t.Fatal("unexpected result: nil")
} else if parent.parent != nil {
t.Fatalf("unexpected parent: %v", parent.parent)
} else if parent.height != 0 {
@@ -44,7 +44,7 @@ func TestNewBlockNodeAndIndexKey(t *testing.T) {
}
child := newBlockNode(1, block2, parent)
if child == nil {
- t.Fatalf("unexpected result: nil")
+ t.Fatal("unexpected result: nil")
} else if child.parent != parent {
t.Fatalf("unexpected parent: %v", parent.parent)
} else if child.height != parent.height+1 {
@@ -69,7 +69,7 @@ func TestAncestor(t *testing.T) {
}
parent := newBlockNode(0, block, nil)
if parent == nil {
- t.Fatalf("unexpected result: nil")
+ t.Fatal("unexpected result: nil")
} else if parent.parent != nil {
t.Fatalf("unexpected parent: %v", parent.parent)
} else if parent.height != 0 {
@@ -82,7 +82,7 @@ func TestAncestor(t *testing.T) {
}
child := newBlockNode(1, block2, parent)
if child == nil {
- t.Fatalf("unexpected result: nil")
+ t.Fatal("unexpected result: nil")
} else if child.parent != parent {
t.Fatalf("unexpected parent: %v", parent.parent)
} else if child.height != parent.height+1 {
@@ -107,7 +107,7 @@ func TestIndexBlock(t *testing.T) {
bi := newBlockIndex()
if bi == nil {
- t.Fatalf("unexpected result: nil")
+ t.Fatal("unexpected result: nil")
}
block0, err := generateRandomBlock(hash.Hash{}, true)
@@ -138,7 +138,7 @@ func TestIndexBlock(t *testing.T) {
t.Fatalf("lack of block index: %v", bn1)
}
- bn3 := bi.lookupBlock(bn0.hash)
+ bn3 := bi.lookupNode(&bn0.hash)
if !reflect.DeepEqual(bn0, bn3) {
t.Fatalf("two values should be equal: \n\tv0=%+v\n\tv1=%+v", bn0, bn3)
}
diff --git a/blockproducer/chain.go b/blockproducer/chain.go
index 330cdb187..59904afbd 100644
--- a/blockproducer/chain.go
+++ b/blockproducer/chain.go
@@ -18,15 +18,19 @@ package blockproducer
import (
"fmt"
+ "os"
"sync"
"time"
pi "github.com/CovenantSQL/CovenantSQL/blockproducer/interfaces"
- "github.com/CovenantSQL/CovenantSQL/blockproducer/types"
+ pt "github.com/CovenantSQL/CovenantSQL/blockproducer/types"
+ "github.com/CovenantSQL/CovenantSQL/crypto"
+ "github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
"github.com/CovenantSQL/CovenantSQL/merkle"
"github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/route"
"github.com/CovenantSQL/CovenantSQL/rpc"
"github.com/CovenantSQL/CovenantSQL/utils"
"github.com/CovenantSQL/CovenantSQL/utils/log"
@@ -34,16 +38,14 @@ import (
)
var (
- metaBucket = [4]byte{0x0, 0x0, 0x0, 0x0}
- metaStateKey = []byte("covenantsql-state")
- metaBlockIndexBucket = []byte("covenantsql-block-index-bucket")
- metaTransactionBucket = []byte("covenantsql-tx-index-bucket")
- metaTxBillingIndexBucket = []byte("covenantsql-tx-billing-index-bucket")
- metaLastTxBillingIndexBucket = []byte("covenantsql-last-tx-billing-index-bucket")
- metaAccountIndexBucket = []byte("covenantsql-account-index-bucket")
- metaSQLChainIndexBucket = []byte("covenantsql-sqlchain-index-bucket")
- gasprice uint32 = 1
- accountAddress proto.AccountAddress
+ metaBucket = [4]byte{0x0, 0x0, 0x0, 0x0}
+ metaStateKey = []byte("covenantsql-state")
+ metaBlockIndexBucket = []byte("covenantsql-block-index-bucket")
+ metaTransactionBucket = []byte("covenantsql-tx-index-bucket")
+ metaAccountIndexBucket = []byte("covenantsql-account-index-bucket")
+ metaSQLChainIndexBucket = []byte("covenantsql-sqlchain-index-bucket")
+ gasPrice uint32 = 1
+ accountAddress proto.AccountAddress
)
// Chain defines the main chain.
@@ -51,18 +53,21 @@ type Chain struct {
db *bolt.DB
ms *metaState
bi *blockIndex
- ti *txIndex
rt *rt
cl *rpc.Caller
- blocksFromSelf chan *types.Block
- blocksFromRPC chan *types.Block
+ blocksFromSelf chan *pt.Block
+ blocksFromRPC chan *pt.Block
pendingTxs chan pi.Transaction
stopCh chan struct{}
}
// NewChain creates a new blockchain.
func NewChain(cfg *Config) (*Chain, error) {
+ if fi, err := os.Stat(cfg.DataFile); err == nil && fi.Mode().IsRegular() {
+ return LoadChain(cfg)
+ }
+
// open db file
db, err := bolt.Open(cfg.DataFile, 0600, nil)
if err != nil {
@@ -74,11 +79,10 @@ func NewChain(cfg *Config) (*Chain, error) {
if err != nil {
return nil, err
}
- enc, err := pubKey.MarshalHash()
+ accountAddress, err := crypto.PubKeyHash(pubKey)
if err != nil {
return nil, err
}
- accountAddress = proto.AccountAddress(hash.THashH(enc[:]))
// create bucket for meta data
err = db.Update(func(tx *bolt.Tx) (err error) {
@@ -103,16 +107,6 @@ func NewChain(cfg *Config) (*Chain, error) {
}
}
- _, err = bucket.CreateBucketIfNotExists(metaTxBillingIndexBucket)
- if err != nil {
- return
- }
-
- _, err = bucket.CreateBucketIfNotExists(metaLastTxBillingIndexBucket)
- if err != nil {
- return
- }
-
_, err = bucket.CreateBucketIfNotExists(metaAccountIndexBucket)
if err != nil {
return
@@ -130,16 +124,15 @@ func NewChain(cfg *Config) (*Chain, error) {
db: db,
ms: newMetaState(),
bi: newBlockIndex(),
- ti: newTxIndex(),
rt: newRuntime(cfg, accountAddress),
cl: rpc.NewCaller(),
- blocksFromSelf: make(chan *types.Block),
- blocksFromRPC: make(chan *types.Block),
+ blocksFromSelf: make(chan *pt.Block),
+ blocksFromRPC: make(chan *pt.Block),
pendingTxs: make(chan pi.Transaction),
stopCh: make(chan struct{}),
}
- log.Debugf("pushing genesis block: %v", cfg.Genesis)
+ log.WithField("genesis", cfg.Genesis).Debug("pushing genesis block")
if err = chain.pushGenesisBlock(cfg.Genesis); err != nil {
return nil, err
@@ -170,29 +163,32 @@ func LoadChain(cfg *Config) (chain *Chain, err error) {
if err != nil {
return nil, err
}
- enc, err := pubKey.MarshalHash()
+ accountAddress, err = crypto.PubKeyHash(pubKey)
if err != nil {
return nil, err
}
- accountAddress = proto.AccountAddress(hash.THashH(enc[:]))
chain = &Chain{
db: db,
ms: newMetaState(),
bi: newBlockIndex(),
- ti: newTxIndex(),
rt: newRuntime(cfg, accountAddress),
cl: rpc.NewCaller(),
- blocksFromSelf: make(chan *types.Block),
- blocksFromRPC: make(chan *types.Block),
+ blocksFromSelf: make(chan *pt.Block),
+ blocksFromRPC: make(chan *pt.Block),
pendingTxs: make(chan pi.Transaction),
stopCh: make(chan struct{}),
}
err = chain.db.View(func(tx *bolt.Tx) (err error) {
meta := tx.Bucket(metaBucket[:])
+ metaEnc := meta.Get(metaStateKey)
+ if metaEnc == nil {
+ return ErrMetaStateNotFound
+ }
+
state := &State{}
- if err = state.deserialize(meta.Get(metaStateKey)); err != nil {
+ if err = utils.DecodeMsgPack(metaEnc, state); err != nil {
return
}
chain.rt.setHead(state)
@@ -203,10 +199,9 @@ func LoadChain(cfg *Config) (chain *Chain, err error) {
nodes := make([]blockNode, blocks.Stats().KeyN)
if err = blocks.ForEach(func(k, v []byte) (err error) {
- block := &types.Block{}
-
- if err = block.Deserialize(v); err != nil {
- log.Errorf("loadeing block: %v", err)
+ block := &pt.Block{}
+ if err = utils.DecodeMsgPack(v, block); err != nil {
+ log.WithError(err).Error("load block failed")
return err
}
@@ -214,14 +209,14 @@ func LoadChain(cfg *Config) (chain *Chain, err error) {
if last == nil {
// TODO(lambda): check genesis block
- } else if block.SignedHeader.ParentHash.IsEqual(&last.hash) {
+ } else if block.ParentHash().IsEqual(&last.hash) {
if err = block.SignedHeader.Verify(); err != nil {
return err
}
parent = last
} else {
- parent = chain.bi.lookupBlock(block.SignedHeader.BlockHash)
+ parent = chain.bi.lookupNode(block.ParentHash())
if parent == nil {
return ErrParentNotFound
@@ -229,6 +224,7 @@ func LoadChain(cfg *Config) (chain *Chain, err error) {
}
nodes[index].initBlockNode(block, parent)
+ chain.bi.addBlock(&nodes[index])
last = &nodes[index]
index++
return err
@@ -236,39 +232,6 @@ func LoadChain(cfg *Config) (chain *Chain, err error) {
return err
}
- txbillings := meta.Bucket(metaTxBillingIndexBucket)
- if err = txbillings.ForEach(func(k, v []byte) (err error) {
- txbilling := types.TxBilling{}
- err = txbilling.Deserialize(v)
- if err != nil {
- return
- }
- chain.ti.addTxBilling(&txbilling)
- return
- }); err != nil {
- return
- }
-
- lastTxBillings := meta.Bucket(metaLastTxBillingIndexBucket)
- if err = lastTxBillings.ForEach(func(k, v []byte) (err error) {
- var databaseID proto.DatabaseID
- err = utils.DecodeMsgPack(k, &databaseID)
- if err != nil {
- return
- }
-
- var sequenceID uint32
- err = utils.DecodeMsgPack(v, &sequenceID)
- if err != nil {
- return
- }
-
- chain.ti.updateLastTxBilling(&databaseID, sequenceID)
- return
- }); err != nil {
- return
- }
-
// Reload state
if err = chain.ms.reloadProcedure()(tx); err != nil {
return
@@ -283,70 +246,18 @@ func LoadChain(cfg *Config) (chain *Chain, err error) {
return chain, nil
}
-// checkTxBilling has two steps: 1. Hash 2. Signature 3. existed tx 4. SequenceID.
-func (c *Chain) checkTxBilling(tb *types.TxBilling) (err error) {
- err = tb.Verify()
- if err != nil {
- return err
- }
-
- if val := c.ti.getTxBilling(tb.TxHash); val == nil {
- err = c.db.View(func(tx *bolt.Tx) error {
- meta := tx.Bucket(metaBucket[:])
- dec := meta.Bucket(metaTxBillingIndexBucket).Get(tb.TxHash[:])
- if len(dec) != 0 {
- decTx := &types.TxBilling{}
- err = decTx.Deserialize(dec)
- if err != nil {
- return err
- }
-
- if decTx != nil && (!decTx.SignedBlock.IsEqual(tb.SignedBlock)) {
- return ErrExistedTx
- }
- }
- return nil
- })
- if err != nil {
- return err
- }
- } else {
- if val.SignedBlock != nil && (!val.SignedBlock.IsEqual(tb.SignedBlock)) {
- return ErrExistedTx
- }
- }
-
- // check sequence ID to avoid double rewards and fees
- databaseID := tb.GetDatabaseID()
- sequenceID, err := c.ti.lastSequenceID(databaseID)
- if err == nil {
- if sequenceID >= tb.GetSequenceID() {
- return ErrSmallerSequenceID
- }
- }
-
- return nil
-}
-
// checkBlock has following steps: 1. check parent block 2. checkTx 2. merkle tree 3. Hash 4. Signature.
-func (c *Chain) checkBlock(b *types.Block) (err error) {
+func (c *Chain) checkBlock(b *pt.Block) (err error) {
// TODO(lambda): process block fork
- if !b.SignedHeader.ParentHash.IsEqual(c.rt.getHead().getHeader()) {
+ if !b.ParentHash().IsEqual(c.rt.getHead().getHeader()) {
log.WithFields(log.Fields{
"head": c.rt.getHead().getHeader().String(),
"height": c.rt.getHead().getHeight(),
- "received_parent": b.SignedHeader.ParentHash,
+ "received_parent": b.ParentHash(),
}).Debug("invalid parent")
return ErrParentNotMatch
}
- // TODO(leventeliu): merge transactions checking.
- for i := range b.TxBillings {
- if err = c.checkTxBilling(b.TxBillings[i]); err != nil {
- return err
- }
- }
-
rootHash := merkle.NewMerkle(b.GetTxHashes()).GetRoot()
if !b.SignedHeader.MerkleRoot.IsEqual(rootHash) {
return ErrInvalidMerkleTreeRoot
@@ -357,14 +268,14 @@ func (c *Chain) checkBlock(b *types.Block) (err error) {
return err
}
h := hash.THashH(enc)
- if !b.SignedHeader.BlockHash.IsEqual(&h) {
+ if !b.BlockHash().IsEqual(&h) {
return ErrInvalidHash
}
return nil
}
-func (c *Chain) pushBlockWithoutCheck(b *types.Block) error {
+func (c *Chain) pushBlockWithoutCheck(b *pt.Block) error {
h := c.rt.getHeightFromTime(b.Timestamp())
node := newBlockNode(h, b, c.rt.getHead().getNode())
state := &State{
@@ -373,22 +284,22 @@ func (c *Chain) pushBlockWithoutCheck(b *types.Block) error {
Height: node.height,
}
- encBlock, err := b.Serialize()
+ encBlock, err := utils.EncodeMsgPack(b)
if err != nil {
return err
}
- encState, err := c.rt.getHead().serialize()
+ encState, err := utils.EncodeMsgPack(c.rt.getHead())
if err != nil {
return err
}
err = c.db.Update(func(tx *bolt.Tx) (err error) {
- err = tx.Bucket(metaBucket[:]).Put(metaStateKey, encState)
+ err = tx.Bucket(metaBucket[:]).Put(metaStateKey, encState.Bytes())
if err != nil {
return err
}
- err = tx.Bucket(metaBucket[:]).Bucket(metaBlockIndexBucket).Put(node.indexKey(), encBlock)
+ err = tx.Bucket(metaBucket[:]).Bucket(metaBlockIndexBucket).Put(node.indexKey(), encBlock.Bytes())
if err != nil {
return err
}
@@ -408,15 +319,15 @@ func (c *Chain) pushBlockWithoutCheck(b *types.Block) error {
return nil
}
-func (c *Chain) pushGenesisBlock(b *types.Block) (err error) {
+func (c *Chain) pushGenesisBlock(b *pt.Block) (err error) {
err = c.pushBlockWithoutCheck(b)
if err != nil {
- log.Errorf("push genesis block failed: %v", err)
+ log.WithError(err).Error("push genesis block failed")
}
return
}
-func (c *Chain) pushBlock(b *types.Block) error {
+func (c *Chain) pushBlock(b *pt.Block) error {
err := c.checkBlock(b)
if err != nil {
return err
@@ -427,81 +338,25 @@ func (c *Chain) pushBlock(b *types.Block) error {
return err
}
- for i := range b.TxBillings {
- err = c.pushTxBillingWithoutCheck(b.TxBillings[i])
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (c *Chain) pushTxBillingWithoutCheck(tb *types.TxBilling) error {
- encTx, err := tb.Serialize()
- if err != nil {
- return err
- }
-
- err = c.db.Update(func(tx *bolt.Tx) error {
- meta := tx.Bucket(metaBucket[:])
- err = meta.Bucket(metaTxBillingIndexBucket).Put(tb.TxHash[:], encTx)
- if err != nil {
- return err
- }
-
- // if the tx is packed in some block, its nonce should be stored to ensure nonce is monotone increasing
- if tb.SignedBlock != nil {
- databaseID, err := utils.EncodeMsgPack(tb.GetDatabaseID())
- if err != nil {
- return err
- }
-
- sequenceID, err := utils.EncodeMsgPack(tb.GetSequenceID())
- if err != nil {
- return err
- }
- err = meta.Bucket(metaLastTxBillingIndexBucket).Put(databaseID.Bytes(), sequenceID.Bytes())
- return err
- }
- return nil
- })
- if err != nil {
- return err
- }
- c.ti.addTxBilling(tb)
- if tb.IsSigned() {
- c.ti.updateLastTxBilling(tb.GetDatabaseID(), tb.GetSequenceID())
- }
return nil
}
-func (c *Chain) pushTxBilling(tb *types.TxBilling) error {
- err := c.checkTxBilling(tb)
- if err != nil {
- return err
- }
-
- err = c.pushTxBillingWithoutCheck(tb)
- return err
-}
-
func (c *Chain) produceBlock(now time.Time) error {
priv, err := kms.GetLocalPrivateKey()
if err != nil {
return err
}
- b := &types.Block{
- SignedHeader: types.SignedHeader{
- Header: types.Header{
+ b := &pt.Block{
+ SignedHeader: pt.SignedHeader{
+ Header: pt.Header{
Version: blockVersion,
Producer: c.rt.accountAddress,
ParentHash: *c.rt.getHead().getHeader(),
Timestamp: now,
},
},
- TxBillings: c.ti.fetchUnpackedTxBillings(),
+ Transactions: c.ms.pullTxs(),
}
err = b.PackAndSignBlock(priv)
@@ -509,11 +364,7 @@ func (c *Chain) produceBlock(now time.Time) error {
return err
}
- for i := range b.TxBillings {
- b.TxBillings[i].SetSignedBlock(&b.SignedHeader.BlockHash)
- }
-
- log.Debugf("generate new block: %v", b)
+ log.WithField("block", b).Debug("produced new block")
err = c.pushBlockWithoutCheck(b)
if err != nil {
@@ -527,7 +378,6 @@ func (c *Chain) produceBlock(now time.Time) error {
wg.Add(1)
go func(id proto.NodeID) {
defer wg.Done()
- method := fmt.Sprintf("%s.%s", MainChainRPCName, "AdviseNewBlock")
blockReq := &AdviseNewBlockReq{
Envelope: proto.Envelope{
// TODO(lambda): Add fields.
@@ -535,16 +385,19 @@ func (c *Chain) produceBlock(now time.Time) error {
Block: b,
}
blockResp := &AdviseNewBlockResp{}
- if err := c.cl.CallNode(id, method, blockReq, blockResp); err != nil {
+ if err := c.cl.CallNode(id, route.MCCAdviseNewBlock.String(), blockReq, blockResp); err != nil {
log.WithFields(log.Fields{
"peer": c.rt.getPeerInfoString(),
"curr_turn": c.rt.getNextTurn(),
"now_time": time.Now().UTC().Format(time.RFC3339Nano),
- "block_hash": b.SignedHeader.BlockHash,
+ "block_hash": b.BlockHash(),
}).WithError(err).Error(
- "Failed to advise new block")
+ "failed to advise new block")
} else {
- log.Debugf("Success to advising #%d height block to %s", c.rt.getHead().getHeight(), id)
+ log.WithFields(log.Fields{
+ "height": c.rt.getHead().getHeight(),
+ "node": id,
+ }).Debug("success advising block")
}
}(s.ID)
}
@@ -553,7 +406,7 @@ func (c *Chain) produceBlock(now time.Time) error {
return err
}
-func (c *Chain) produceTxBilling(br *types.BillingRequest) (_ *types.BillingResponse, err error) {
+func (c *Chain) produceBilling(br *pt.BillingRequest) (_ *pt.BillingRequest, err error) {
// TODO(lambda): simplify the function
if err = c.checkBillingRequest(br); err != nil {
return
@@ -563,7 +416,6 @@ func (c *Chain) produceTxBilling(br *types.BillingRequest) (_ *types.BillingResp
// TODO(lambda): because there is no token distribution,
// we only increase miners' balance but not decrease customer's balance
var (
- enc []byte
accountNumber = len(br.Header.GasAmounts)
receivers = make([]*proto.AccountAddress, accountNumber)
fees = make([]uint64, accountNumber)
@@ -572,30 +424,20 @@ func (c *Chain) produceTxBilling(br *types.BillingRequest) (_ *types.BillingResp
for i, addrAndGas := range br.Header.GasAmounts {
receivers[i] = &addrAndGas.AccountAddress
- fees[i] = addrAndGas.GasAmount * uint64(gasprice)
+ fees[i] = addrAndGas.GasAmount * uint64(gasPrice)
rewards[i] = 0
}
- if enc, err = br.MarshalHash(); err != nil {
- return
- }
- h := hash.THashH(enc)
-
- // generate response
- privKey, err := kms.GetLocalPrivateKey()
+ // add block producer signature
+ var privKey *asymmetric.PrivateKey
+ privKey, err = kms.GetLocalPrivateKey()
if err != nil {
return
}
- sign, err := privKey.Sign(h[:])
- if err != nil {
+
+ if _, _, err = br.SignRequestHeader(privKey, false); err != nil {
return
}
- resp := &types.BillingResponse{
- AccountAddress: accountAddress,
- RequestHash: h,
- Signee: privKey.PubKey(),
- Signature: sign,
- }
// generate and push the txbilling
// 1. generate txbilling
@@ -604,98 +446,70 @@ func (c *Chain) produceTxBilling(br *types.BillingRequest) (_ *types.BillingResp
return
}
var (
- tc = types.NewTxContent(uint32(nc), br, receivers, fees, rewards, resp)
- tb = types.NewTxBilling(tc, types.TxTypeBilling, &c.rt.accountAddress)
+ tc = pt.NewBillingHeader(nc, br, accountAddress, receivers, fees, rewards)
+ tb = pt.NewBilling(tc)
)
if err = tb.Sign(privKey); err != nil {
return
}
- log.Debugf("response is %s", resp.RequestHash)
+ log.WithField("billingRequestHash", br.RequestHash).Debug("generated billing transaction")
// 2. push tx
c.pendingTxs <- tb
- tbReq := &AdviseTxBillingReq{
- Envelope: proto.Envelope{
- // TODO(lambda): Add fields.
- },
- TxBilling: tb,
- }
- method := fmt.Sprintf("%s.%s", MainChainRPCName, "AdviseTxBilling")
- peers := c.rt.getPeers()
- wg := &sync.WaitGroup{}
- for _, s := range peers.Servers {
- if !s.ID.IsEqual(&c.rt.nodeID) {
- wg.Add(1)
- go func(id proto.NodeID) {
- defer wg.Done()
- tbResp := &AdviseTxBillingResp{}
- if err := c.cl.CallNode(id, method, tbReq, tbResp); err != nil {
- log.WithFields(log.Fields{
- "peer": c.rt.getPeerInfoString(),
- "curr_turn": c.rt.getNextTurn(),
- "now_time": time.Now().UTC().Format(time.RFC3339Nano),
- "tx_hash": tb.TxHash,
- }).WithError(err).Error(
- "Failed to advise new block")
- }
- }(s.ID)
- }
- }
- wg.Wait()
- return resp, nil
+ return br, nil
}
// checkBillingRequest checks followings by order:
// 1. period of sqlchain;
// 2. request's hash
// 3. miners' signatures.
-func (c *Chain) checkBillingRequest(br *types.BillingRequest) error {
+func (c *Chain) checkBillingRequest(br *pt.BillingRequest) (err error) {
// period of sqlchain;
// TODO(lambda): get and check period and miner list of specific sqlchain
- // request's hash
- enc, err := br.Header.MarshalHash()
- if err != nil {
- return err
- }
- h := hash.THashH(enc[:])
- if !h.IsEqual(&br.RequestHash) {
- return ErrInvalidHash
- }
+ err = br.VerifySignatures()
+ return
+}
- // miners' signatures
- sLen := len(br.Signees)
- if sLen != len(br.Signatures) {
- return ErrInvalidBillingRequest
+func (c *Chain) fetchBlockByHeight(h uint32) (b *pt.Block, count uint32, err error) {
+ node := c.rt.getHead().getNode().ancestor(h)
+ if node == nil {
+ return nil, 0, ErrNoSuchBlock
}
- for i := range br.Signees {
- if !br.Signatures[i].Verify(h[:], br.Signees[i]) {
- return ErrSignVerification
- }
+
+ b = &pt.Block{}
+ k := node.indexKey()
+
+ err = c.db.View(func(tx *bolt.Tx) error {
+ v := tx.Bucket(metaBucket[:]).Bucket(metaBlockIndexBucket).Get(k)
+ return utils.DecodeMsgPack(v, b)
+ })
+ if err != nil {
+ return nil, 0, err
}
- return nil
+ return b, node.count, nil
}
-func (c *Chain) fetchBlockByHeight(h uint32) (*types.Block, error) {
- node := c.rt.getHead().getNode().ancestor(h)
+func (c *Chain) fetchBlockByCount(count uint32) (b *pt.Block, height uint32, err error) {
+ node := c.rt.getHead().getNode().ancestorByCount(count)
if node == nil {
- return nil, ErrNoSuchBlock
+ return nil, 0, ErrNoSuchBlock
}
- b := &types.Block{}
+ b = &pt.Block{}
k := node.indexKey()
- err := c.db.View(func(tx *bolt.Tx) error {
+ err = c.db.View(func(tx *bolt.Tx) error {
v := tx.Bucket(metaBucket[:]).Bucket(metaBlockIndexBucket).Get(k)
- return b.Deserialize(v)
+ return utils.DecodeMsgPack(v, b)
})
if err != nil {
- return nil, err
+ return nil, 0, err
}
- return b, nil
+ return b, node.height, nil
}
// runCurrentTurn does the check and runs block producing if its my turn.
@@ -711,10 +525,10 @@ func (c *Chain) runCurrentTurn(now time.Time) {
return
}
- log.Infof("produce a new block with height %d", c.rt.getNextTurn())
+ log.WithField("height", c.rt.getNextTurn()).Info("producing a new block")
if err := c.produceBlock(now); err != nil {
log.WithField("now", now.Format(time.RFC3339Nano)).WithError(err).Errorln(
- "Failed to produce block")
+ "failed to produce block")
}
}
@@ -722,15 +536,21 @@ func (c *Chain) runCurrentTurn(now time.Time) {
func (c *Chain) sync() error {
log.WithFields(log.Fields{
"peer": c.rt.getPeerInfoString(),
- }).Debug("Synchronizing chain state")
+ }).Debug("synchronizing chain state")
for {
now := c.rt.now()
height := c.rt.getHeightFromTime(now)
- log.Infof("current height is %d, next turn is %d", height, c.rt.getNextTurn())
+ log.WithFields(log.Fields{
+ "height": height,
+ "nextTurn": c.rt.getNextTurn(),
+ }).Info("try sync heights")
if c.rt.getNextTurn() >= height {
- log.Infof("return with height %d, next turn is %d", height, c.rt.getNextTurn())
+ log.WithFields(log.Fields{
+ "height": height,
+ "nextTurn": c.rt.getNextTurn(),
+ }).Info("return heights")
break
}
@@ -769,7 +589,7 @@ func (c *Chain) Start() error {
func (c *Chain) processBlocks() {
rsCh := make(chan struct{})
rsWG := &sync.WaitGroup{}
- returnStash := func(stash []*types.Block) {
+ returnStash := func(stash []*pt.Block) {
defer rsWG.Done()
for _, block := range stash {
select {
@@ -786,7 +606,7 @@ func (c *Chain) processBlocks() {
c.rt.wg.Done()
}()
- var stash []*types.Block
+ var stash []*pt.Block
for {
select {
case block := <-c.blocksFromSelf:
@@ -801,7 +621,7 @@ func (c *Chain) processBlocks() {
if h := c.rt.getHeightFromTime(block.Timestamp()); h > c.rt.getNextTurn()-1 {
// Stash newer blocks for later check
if stash == nil {
- stash = make([]*types.Block, 0)
+ stash = make([]*pt.Block, 0)
}
stash = append(stash, block)
} else {
@@ -885,12 +705,11 @@ func (c *Chain) mainCycle() {
func (c *Chain) syncHead() {
// Try to fetch if the the block of the current turn is not advised yet
- log.WithFields(log.Fields{
- "index": c.rt.index,
- "next_turn": c.rt.getNextTurn(),
- "height": c.rt.getHead().getHeight(),
- "count": c.rt.getHead().getNode().count,
- }).Debugf("sync header")
+ //log.WithFields(log.Fields{
+ // "index": c.rt.index,
+ // "next_turn": c.rt.getNextTurn(),
+ // "height": c.rt.getHead().getHeight(),
+ //}).Debug("sync header")
if h := c.rt.getNextTurn() - 1; c.rt.getHead().getHeight() < h {
var err error
req := &FetchBlockReq{
@@ -900,13 +719,12 @@ func (c *Chain) syncHead() {
Height: h,
}
resp := &FetchBlockResp{}
- method := fmt.Sprintf("%s.%s", MainChainRPCName, "FetchBlock")
peers := c.rt.getPeers()
succ := false
for i, s := range peers.Servers {
if !s.ID.IsEqual(&c.rt.nodeID) {
- err = c.cl.CallNode(s.ID, method, req, resp)
+ err = c.cl.CallNode(s.ID, route.MCCFetchBlock.String(), req, resp)
if err != nil || resp.Block == nil {
log.WithFields(log.Fields{
"peer": c.rt.getPeerInfoString(),
diff --git a/blockproducer/chain_test.go b/blockproducer/chain_test.go
index 307518889..450a4f4cd 100644
--- a/blockproducer/chain_test.go
+++ b/blockproducer/chain_test.go
@@ -17,18 +17,20 @@
package blockproducer
import (
- "fmt"
"io/ioutil"
+ "os"
"sync"
"testing"
"time"
- "github.com/CovenantSQL/CovenantSQL/blockproducer/types"
- "github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
+ pi "github.com/CovenantSQL/CovenantSQL/blockproducer/interfaces"
+ pt "github.com/CovenantSQL/CovenantSQL/blockproducer/types"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
"github.com/CovenantSQL/CovenantSQL/kayak"
"github.com/CovenantSQL/CovenantSQL/pow/cpuminer"
"github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/route"
+ ct "github.com/CovenantSQL/CovenantSQL/sqlchain/types"
"github.com/CovenantSQL/CovenantSQL/utils/log"
. "github.com/smartystreets/goconvey/convey"
)
@@ -41,14 +43,9 @@ var (
testClientNumberPerChain = 10
)
-type nodeProfile struct {
- NodeID proto.NodeID
- PrivateKey *asymmetric.PrivateKey
- PublicKey *asymmetric.PublicKey
-}
-
func TestChain(t *testing.T) {
Convey("test main chain", t, func() {
+ log.SetLevel(log.InfoLevel)
confDir := "../test/mainchain/node_standalone/config.yaml"
privDir := "../test/mainchain/node_standalone/private.key"
cleanup, _, _, rpcServer, err := initNode(
@@ -62,6 +59,7 @@ func TestChain(t *testing.T) {
So(err, ShouldBeNil)
fl.Close()
+ os.Remove(fl.Name())
// create genesis block
genesis, err := generateRandomBlock(genesisHash, true)
@@ -77,7 +75,7 @@ func TestChain(t *testing.T) {
ao, ok := chain.ms.readonly.accounts[testAddress1]
So(ok, ShouldBeTrue)
So(ao, ShouldNotBeNil)
- So(chain.ms.pool.entries[testAddress1].transacions, ShouldBeEmpty)
+ So(chain.ms.pool.entries[testAddress1].transactions, ShouldBeEmpty)
So(chain.ms.pool.entries[testAddress1].baseNonce, ShouldEqual, 1)
var (
bl uint64
@@ -96,7 +94,7 @@ func TestChain(t *testing.T) {
So(loaded, ShouldBeTrue)
So(bl, ShouldEqual, testInitBalance)
- // Hack for signle instance test
+ // Hack for single instance test
chain.rt.bpNum = 5
for {
@@ -108,46 +106,56 @@ func TestChain(t *testing.T) {
chain.rt.isMyTurn())
// chain will receive blocks and tx
-
// receive block
// generate valid txbillings
- tbs := make([]*types.TxBilling, 10)
- for i := range tbs {
- tb, err := generateRandomTxBillingWithSeqID(0)
+ tbs := make([]pi.Transaction, 0, 20)
+
+ // pull previous processed transactions
+ tbs = append(tbs, chain.ms.pullTxs()...)
+
+ for i := 0; i != 10; i++ {
+ tb, err := generateRandomAccountBilling()
So(err, ShouldBeNil)
- tbs[i] = tb
+ tbs = append(tbs, tb)
}
// generate block
- block, err := generateRandomBlockWithTxBillings(*chain.rt.getHead().getHeader(), tbs)
+ block, err := generateRandomBlockWithTransactions(*chain.rt.getHead().getHeader(), tbs)
So(err, ShouldBeNil)
err = chain.pushBlock(block)
So(err, ShouldBeNil)
+ nextNonce, err := chain.ms.nextNonce(testAddress1)
+ So(err, ShouldBeNil)
for _, val := range tbs {
- So(chain.ti.hasTxBilling(val.TxHash), ShouldBeTrue)
+ // should be packed
+ So(nextNonce >= val.GetAccountNonce(), ShouldBeTrue)
}
So(chain.bi.hasBlock(block.SignedHeader.BlockHash), ShouldBeTrue)
// So(chain.rt.getHead().Height, ShouldEqual, height)
height := chain.rt.getHead().getHeight()
- specificHeightBlock1, err := chain.fetchBlockByHeight(height)
+ specificHeightBlock1, _, err := chain.fetchBlockByHeight(height)
So(err, ShouldBeNil)
So(block.SignedHeader.BlockHash, ShouldResemble, specificHeightBlock1.SignedHeader.BlockHash)
- specificHeightBlock2, err := chain.fetchBlockByHeight(height + 1000)
+ specificHeightBlock2, _, err := chain.fetchBlockByHeight(height + 1000)
So(specificHeightBlock2, ShouldBeNil)
So(err, ShouldNotBeNil)
- // receive txes
- receivedTbs := make([]*types.TxBilling, 9)
+ // receive txs
+ receivedTbs := make([]*pt.Billing, 9)
for i := range receivedTbs {
- tb, err := generateRandomTxBillingWithSeqID(0)
+ tb, err := generateRandomAccountBilling()
So(err, ShouldBeNil)
receivedTbs[i] = tb
- chain.pushTxBilling(tb)
+ err = chain.processTx(tb)
+ So(err, ShouldBeNil)
}
+ nextNonce, err = chain.ms.nextNonce(testAddress1)
+
for _, val := range receivedTbs {
- So(chain.ti.hasTxBilling(val.TxHash), ShouldBeTrue)
+ // should be packed or unpacked
+ So(chain.ms.pool.hasTx(val), ShouldBeTrue)
}
// So(height, ShouldEqual, chain.rt.getHead().Height)
@@ -155,8 +163,8 @@ func TestChain(t *testing.T) {
t.Logf("Pushed new block: height = %d, %s <- %s",
chain.rt.getHead().getHeight(),
- block.SignedHeader.ParentHash,
- block.SignedHeader.BlockHash)
+ block.ParentHash(),
+ block.BlockHash())
if chain.rt.getHead().getHeight() >= testPeriodNumber {
break
@@ -197,6 +205,8 @@ func TestMultiNode(t *testing.T) {
// create tmp file
fl, err := ioutil.TempFile("", "mainchain")
So(err, ShouldBeNil)
+ fl.Close()
+ os.Remove(fl.Name())
// init config
cleanup, dht, _, server, err := initNode(configs[i], privateKeys[i])
@@ -237,7 +247,7 @@ func TestMultiNode(t *testing.T) {
}
var resp proto.PingResp
dht.Ping(&req, &resp)
- log.Debugf("ping response: %v", resp)
+ log.WithField("resp", resp).Debug("got ping response")
err = chains[i].Start()
So(err, ShouldBeNil)
@@ -264,16 +274,18 @@ func TestMultiNode(t *testing.T) {
br, err := generateRandomBillingRequest()
c.So(err, ShouldBeNil)
- bReq := &AdviseBillingReq{
+ bReq := &ct.AdviseBillingReq{
Envelope: proto.Envelope{
// TODO(lambda): Add fields.
},
Req: br,
}
- bResp := &AdviseBillingResp{}
- method := fmt.Sprintf("%s.%s", MainChainRPCName, "AdviseBillingRequest")
- log.Debugf("CallNode %d hash is %s", val, br.RequestHash)
- err = chains[i].cl.CallNode(chains[i].rt.nodeID, method, bReq, bResp)
+ bResp := &ct.AdviseBillingResp{}
+ log.WithFields(log.Fields{
+ "node": val,
+ "requestHash": br.RequestHash,
+ }).Debug("advising billing request")
+ err = chains[i].cl.CallNode(chains[i].rt.nodeID, route.MCCAdviseBillingRequest.String(), bReq, bResp)
if err != nil {
log.WithFields(log.Fields{
"peer": chains[i].rt.getPeerInfoString(),
diff --git a/blockproducer/db_service.go b/blockproducer/db_service.go
index feadfc058..511227bc3 100644
--- a/blockproducer/db_service.go
+++ b/blockproducer/db_service.go
@@ -40,8 +40,6 @@ import (
const (
// DefaultAllocationRounds defines max rounds to try allocate peers for database creation.
DefaultAllocationRounds = 3
- // DBServiceName for block producer to provide database management related logic.
- DBServiceName = "BPDB"
)
var (
@@ -78,24 +76,37 @@ func (s *DBService) CreateDatabase(req *CreateDatabaseRequest, resp *CreateDatab
// TODO(xq262144): verify identity
// verify identity
+ defer func() {
+ log.WithFields(log.Fields{
+ "meta": req.Header.ResourceMeta,
+ "node": req.GetNodeID().String(),
+ }).WithError(err).Debug("create database")
+ }()
+
// create random DatabaseID
var dbID proto.DatabaseID
if dbID, err = s.generateDatabaseID(req.GetNodeID()); err != nil {
return
}
+ log.WithField("db", dbID).Debug("generated database id")
+
// allocate nodes
var peers *kayak.Peers
if peers, err = s.allocateNodes(0, dbID, req.Header.ResourceMeta); err != nil {
return
}
+ log.WithField("peers", peers).Debug("generated peers info")
+
// TODO(lambda): call accounting features, top up deposit
var genesisBlock *ct.Block
if genesisBlock, err = s.generateGenesisBlock(dbID, req.Header.ResourceMeta); err != nil {
return
}
+ log.WithField("block", genesisBlock).Debug("generated genesis block")
+
defer func() {
if err != nil {
// TODO(lambda): release deposit on error
@@ -104,11 +115,6 @@ func (s *DBService) CreateDatabase(req *CreateDatabaseRequest, resp *CreateDatab
// call miner nodes to provide service
var privateKey *asymmetric.PrivateKey
- var pubKey *asymmetric.PublicKey
-
- if pubKey, err = kms.GetLocalPublicKey(); err != nil {
- return
- }
if privateKey, err = kms.GetLocalPrivateKey(); err != nil {
return
}
@@ -120,7 +126,6 @@ func (s *DBService) CreateDatabase(req *CreateDatabaseRequest, resp *CreateDatab
Peers: peers,
GenesisBlock: genesisBlock,
}
- initSvcReq.Header.Signee = pubKey
if err = initSvcReq.Sign(privateKey); err != nil {
return
}
@@ -130,7 +135,6 @@ func (s *DBService) CreateDatabase(req *CreateDatabaseRequest, resp *CreateDatab
rollbackReq.Header.Instance = wt.ServiceInstance{
DatabaseID: dbID,
}
- rollbackReq.Header.Signee = pubKey
if err = rollbackReq.Sign(privateKey); err != nil {
return
}
@@ -147,7 +151,7 @@ func (s *DBService) CreateDatabase(req *CreateDatabaseRequest, resp *CreateDatab
GenesisBlock: genesisBlock,
}
- log.Debugf("generated instance meta: %v", instanceMeta)
+ log.WithField("meta", instanceMeta).Debug("generated instance meta")
if err = s.ServiceMap.Set(instanceMeta); err != nil {
// critical error
@@ -157,7 +161,6 @@ func (s *DBService) CreateDatabase(req *CreateDatabaseRequest, resp *CreateDatab
// send response to client
resp.Header.InstanceMeta = instanceMeta
- resp.Header.Signee = pubKey
// sign the response
err = resp.Sign(privateKey)
@@ -175,6 +178,13 @@ func (s *DBService) DropDatabase(req *DropDatabaseRequest, resp *DropDatabaseRes
// TODO(xq262144): verify identity
// verify identity and database belonging
+ defer func() {
+ log.WithFields(log.Fields{
+ "db": req.Header.DatabaseID,
+ "node": req.GetNodeID().String(),
+ }).Debug("drop database")
+ }()
+
// get database peers
var instanceMeta wt.ServiceInstance
if instanceMeta, err = s.ServiceMap.Get(req.Header.DatabaseID); err != nil {
@@ -228,6 +238,13 @@ func (s *DBService) GetDatabase(req *GetDatabaseRequest, resp *GetDatabaseRespon
// TODO(xq262144): verify identity
// verify identity and database belonging
+ defer func() {
+ log.WithFields(log.Fields{
+ "db": req.Header.DatabaseID,
+ "node": req.GetNodeID().String(),
+ }).Debug("get database")
+ }()
+
// fetch from meta
var instanceMeta wt.ServiceInstance
if instanceMeta, err = s.ServiceMap.Get(req.Header.DatabaseID); err != nil {
@@ -259,13 +276,13 @@ func (s *DBService) GetNodeDatabases(req *wt.InitService, resp *wt.InitServiceRe
return
}
- log.Debugf("current instance for node %v: %v", req.GetNodeID().ToNodeID(), instances)
+ log.WithFields(log.Fields{
+ "node": req.GetNodeID().String(),
+ "databases": instances,
+ }).Debug("get node databases")
// send response to client
resp.Header.Instances = instances
- if resp.Header.Signee, err = kms.GetLocalPublicKey(); err != nil {
- return
- }
var privateKey *asymmetric.PrivateKey
if privateKey, err = kms.GetLocalPrivateKey(); err != nil {
return
@@ -297,7 +314,7 @@ func (s *DBService) generateDatabaseID(reqNodeID *proto.RawNodeID) (dbID proto.D
startNonce.Inc()
dbID = proto.DatabaseID(nonce.Hash.String())
- log.Debugf("try generated database id %v", dbID)
+ log.WithField("db", dbID).Debug("try generate database id")
// check existence
if _, err = s.ServiceMap.Get(dbID); err == ErrNoSuchDatabase {
@@ -312,6 +329,14 @@ func (s *DBService) allocateNodes(lastTerm uint64, dbID proto.DatabaseID, resour
excludeNodes := make(map[proto.NodeID]bool)
var allocated []allocatedNode
+ defer func() {
+ log.WithFields(log.Fields{
+ "db": dbID,
+ "meta": resourceMeta,
+ "peers": peers,
+ }).WithError(err).Debug("try allocated nodes")
+ }()
+
if resourceMeta.Node <= 0 {
err = ErrDatabaseAllocation
return
@@ -325,7 +350,7 @@ func (s *DBService) allocateNodes(lastTerm uint64, dbID proto.DatabaseID, resour
}
for i := 0; i != s.AllocationRounds; i++ {
- log.Debugf("node allocation round %d", i+1)
+ log.WithField("round", i).Debug("try allocation node")
var nodes []proto.Node
@@ -341,7 +366,7 @@ func (s *DBService) allocateNodes(lastTerm uint64, dbID proto.DatabaseID, resour
nodes, err = s.Consistent.GetNeighborsEx(string(dbID), curRange, proto.ServerRoles(rolesFilter))
- log.Debugf("found %d neighbor nodes", len(nodes))
+ log.WithField("nodeCount", len(nodes)).Debug("found nodes to try dispatch")
// TODO(xq262144): brute force implementation to be optimized
var nodeIDs []proto.NodeID
@@ -352,7 +377,11 @@ func (s *DBService) allocateNodes(lastTerm uint64, dbID proto.DatabaseID, resour
}
}
- log.Debugf("found %d suitable nodes: %v", len(nodeIDs), nodeIDs)
+ log.WithFields(log.Fields{
+ "nodeCount": len(nodeIDs),
+ "totalCount": len(nodes),
+ "nodes": nodeIDs,
+ }).Debug("found nodes to dispatch")
if len(nodeIDs) < int(resourceMeta.Node) {
continue
@@ -361,15 +390,19 @@ func (s *DBService) allocateNodes(lastTerm uint64, dbID proto.DatabaseID, resour
// check node resource status
metrics := s.NodeMetrics.GetMetrics(nodeIDs)
- log.Debugf("get %d metric records for %d nodes", len(metrics), len(nodeIDs))
+ log.WithFields(log.Fields{
+ "recordCount": len(metrics),
+ "nodeCount": len(nodeIDs),
+ }).Debug("found metric records to dispatch")
for nodeID, nodeMetric := range metrics {
- log.Debugf("parse metric of node %v", nodeID)
+ log.WithField("node", nodeID).Debug("parse metric")
+
var metricValue uint64
// get metric
if metricValue, err = s.getMetric(nodeMetric, MetricKeyFreeMemory); err != nil {
- log.Debugf("get node %s memory metric failed", nodeID)
+ log.WithField("node", nodeID).Debug("get memory metric failed")
// add to excludes
excludeNodes[nodeID] = true
@@ -386,7 +419,11 @@ func (s *DBService) allocateNodes(lastTerm uint64, dbID proto.DatabaseID, resour
MemoryMetric: metricValue,
})
} else {
- log.Debugf("node %s memory metric does not meet requirements", nodeID)
+ log.WithFields(log.Fields{
+ "actual": metricValue,
+ "expected": resourceMeta.Memory,
+ "node": nodeID,
+ }).Debug("node memory node meets requirement")
excludeNodes[nodeID] = true
}
}
@@ -443,7 +480,11 @@ func (s *DBService) getMetric(metric metric.MetricMap, keys []string) (value uin
}
func (s *DBService) buildPeers(term uint64, nodes []proto.Node, allocated []proto.NodeID) (peers *kayak.Peers, err error) {
- log.Debugf("build peers for allocated nodes with term: %v, allocated nodes: %v", term, allocated)
+ log.WithFields(log.Fields{
+ "term": term,
+ "nodes": allocated,
+ }).Debug("build peers for term/nodes")
+
// get local private key
var pubKey *asymmetric.PublicKey
if pubKey, err = kms.GetLocalPublicKey(); err != nil {
@@ -498,10 +539,6 @@ func (s *DBService) generateGenesisBlock(dbID proto.DatabaseID, resourceMeta wt.
// TODO(xq262144): following is stub code, real logic should be implemented in the future
emptyHash := hash.Hash{}
- var pubKey *asymmetric.PublicKey
- if pubKey, err = kms.GetLocalPublicKey(); err != nil {
- return
- }
var privKey *asymmetric.PrivateKey
if privKey, err = kms.GetLocalPrivateKey(); err != nil {
return
@@ -520,8 +557,6 @@ func (s *DBService) generateGenesisBlock(dbID proto.DatabaseID, resourceMeta wt.
ParentHash: emptyHash,
Timestamp: time.Now().UTC(),
},
- Signee: pubKey,
- Signature: nil,
},
}
err = genesisBlock.PackAndSignBlock(privKey)
diff --git a/blockproducer/db_service_test.go b/blockproducer/db_service_test.go
index a06ed73bc..da00e68ba 100644
--- a/blockproducer/db_service_test.go
+++ b/blockproducer/db_service_test.go
@@ -46,10 +46,6 @@ func TestService(t *testing.T) {
defer cleanup()
// get keys
- var pubKey *asymmetric.PublicKey
- pubKey, err = kms.GetLocalPublicKey()
- So(err, ShouldBeNil)
-
var privateKey *asymmetric.PrivateKey
privateKey, err = kms.GetLocalPrivateKey()
So(err, ShouldBeNil)
@@ -66,7 +62,7 @@ func TestService(t *testing.T) {
}
// register BPDB service to rpc
- err = server.RegisterService(DBServiceName, dbService)
+ err = server.RegisterService(route.BPDBRPCName, dbService)
So(err, ShouldBeNil)
// get database
@@ -77,7 +73,6 @@ func TestService(t *testing.T) {
// test get database
getReq := new(GetDatabaseRequest)
getReq.Header.DatabaseID = proto.DatabaseID("db")
- getReq.Header.Signee = pubKey
err = getReq.Sign(privateKey)
So(err, ShouldBeNil)
@@ -101,7 +96,6 @@ func TestService(t *testing.T) {
createDBReq.Header.ResourceMeta = wt.ResourceMeta{
Node: 1,
}
- createDBReq.Header.Signee = pubKey
err = createDBReq.Sign(privateKey)
So(err, ShouldBeNil)
createDBRes := new(CreateDatabaseResponse)
@@ -166,7 +160,6 @@ func TestService(t *testing.T) {
// drop database
dropDBReq := new(DropDatabaseRequest)
dropDBReq.Header.DatabaseID = createDBRes.Header.InstanceMeta.DatabaseID
- dropDBReq.Header.Signee = pubKey
err = dropDBReq.Sign(privateKey)
So(err, ShouldBeNil)
dropDBRes := new(DropDatabaseResponse)
@@ -176,7 +169,6 @@ func TestService(t *testing.T) {
// get this database again to test if it is dropped
getReq = new(GetDatabaseRequest)
getReq.Header.DatabaseID = createDBRes.Header.InstanceMeta.DatabaseID
- getReq.Header.Signee = pubKey
err = getReq.Sign(privateKey)
So(err, ShouldBeNil)
err = rpc.NewCaller().CallNode(nodeID, route.BPDBGetDatabase.String(), getReq, getRes)
@@ -191,12 +183,8 @@ func buildQuery(queryType wt.QueryType, connID uint64, seqNo uint64, databaseID
return
}
- // get private/public key
- var pubKey *asymmetric.PublicKey
+ // get private key
var privateKey *asymmetric.PrivateKey
- if pubKey, err = kms.GetLocalPublicKey(); err != nil {
- return
- }
if privateKey, err = kms.GetLocalPrivateKey(); err != nil {
return
}
@@ -220,7 +208,6 @@ func buildQuery(queryType wt.QueryType, connID uint64, seqNo uint64, databaseID
SeqNo: seqNo,
Timestamp: tm,
},
- Signee: pubKey,
},
Payload: wt.RequestPayload{
Queries: realQueries,
diff --git a/blockproducer/db_service_types.go b/blockproducer/db_service_types.go
index 7797dff6c..6edac9581 100644
--- a/blockproducer/db_service_types.go
+++ b/blockproducer/db_service_types.go
@@ -65,6 +65,7 @@ func (sh *SignedCreateDatabaseRequestHeader) Sign(signer *asymmetric.PrivateKey)
// sign
sh.Signature, err = signer.Sign(sh.HeaderHash[:])
+ sh.Signee = signer.PubKey()
return
}
@@ -128,6 +129,7 @@ func (sh *SignedCreateDatabaseResponseHeader) Sign(signer *asymmetric.PrivateKey
// sign
sh.Signature, err = signer.Sign(sh.HeaderHash[:])
+ sh.Signee = signer.PubKey()
return
}
@@ -191,6 +193,7 @@ func (sh *SignedDropDatabaseRequestHeader) Sign(signer *asymmetric.PrivateKey) (
// sign
sh.Signature, err = signer.Sign(sh.HeaderHash[:])
+ sh.Signee = signer.PubKey()
return
}
@@ -256,6 +259,7 @@ func (sh *SignedGetDatabaseRequestHeader) Sign(signer *asymmetric.PrivateKey) (e
// sign
sh.Signature, err = signer.Sign(sh.HeaderHash[:])
+ sh.Signee = signer.PubKey()
return
}
@@ -318,6 +322,7 @@ func (sh *SignedGetDatabaseResponseHeader) Sign(signer *asymmetric.PrivateKey) (
// sign
sh.Signature, err = signer.Sign(sh.HeaderHash[:])
+ sh.Signee = signer.PubKey()
return
}
diff --git a/blockproducer/errors.go b/blockproducer/errors.go
index 507ebf263..53e845bab 100644
--- a/blockproducer/errors.go
+++ b/blockproducer/errors.go
@@ -74,4 +74,6 @@ var (
ErrUnknownTransactionType = errors.New("unknown transaction type")
// ErrTransactionMismatch indicates that transactions to be committed mismatch the pool.
ErrTransactionMismatch = errors.New("transaction mismatch")
+ // ErrMetaStateNotFound indicates that meta state not found in db.
+ ErrMetaStateNotFound = errors.New("meta state not found in db")
)
diff --git a/blockproducer/helper_test.go b/blockproducer/helper_test.go
index 2a8d42fb8..ccc5d7efa 100644
--- a/blockproducer/helper_test.go
+++ b/blockproducer/helper_test.go
@@ -29,7 +29,6 @@ import (
"time"
"github.com/CovenantSQL/CovenantSQL/conf"
-
"github.com/CovenantSQL/CovenantSQL/consistent"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
@@ -76,8 +75,6 @@ func createRandomBlock(parent hash.Hash, isGenesis bool) (b *ct.Block, err error
ParentHash: parent,
Timestamp: time.Now().UTC(),
},
- Signee: pub,
- Signature: nil,
},
Queries: make([]*hash.Hash, rand.Intn(10)+10),
}
@@ -187,7 +184,7 @@ func initNode(confRP, privateKeyRP string) (cleanupFunc func(), dht *route.DHTSe
if d, err = ioutil.TempDir("", "db_test_"); err != nil {
return
}
- log.Debugf("temp dir: %s", d)
+ log.WithField("d", d).Debug("created temp dir")
// init conf
_, testFile, _, _ := runtime.Caller(0)
@@ -215,14 +212,14 @@ func initNode(confRP, privateKeyRP string) (cleanupFunc func(), dht *route.DHTSe
}
// init rpc
- if server, err = rpc.NewServerWithService(rpc.ServiceMap{"DHT": dht}); err != nil {
+ if server, err = rpc.NewServerWithService(rpc.ServiceMap{route.DHTRPCName: dht}); err != nil {
return
}
// register metric service
metricService = metric.NewCollectServer()
if err = server.RegisterService(metric.MetricServiceName, metricService); err != nil {
- log.Errorf("init metric service failed: %v", err)
+ log.WithError(err).Error("init metric service failed")
return
}
diff --git a/blockproducer/interfaces/mixins.go b/blockproducer/interfaces/mixins.go
new file mode 100644
index 000000000..26cce6346
--- /dev/null
+++ b/blockproducer/interfaces/mixins.go
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018 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 interfaces
+
+//go:generate hsp
+
+// TransactionTypeMixin provide type heuristic features to transaction wrapper.
+type TransactionTypeMixin struct {
+ TxType TransactionType
+}
+
+// ContainsTransactionTypeMixin interface defines interface to detect transaction type mixin.
+type ContainsTransactionTypeMixin interface {
+ SetTransactionType(TransactionType)
+}
+
+// GetTransactionType implements Transaction.GetTransactionType.
+func (m *TransactionTypeMixin) GetTransactionType() TransactionType {
+ return m.TxType
+}
+
+// SetTransactionType is a helper function for derived types.
+func (m *TransactionTypeMixin) SetTransactionType(t TransactionType) {
+ m.TxType = t
+}
+
+// NewTransactionTypeMixin returns new instance.
+func NewTransactionTypeMixin(txType TransactionType) *TransactionTypeMixin {
+ return &TransactionTypeMixin{
+ TxType: txType,
+ }
+}
diff --git a/blockproducer/types/tx_gen.go b/blockproducer/interfaces/mixins_gen.go
similarity index 50%
rename from blockproducer/types/tx_gen.go
rename to blockproducer/interfaces/mixins_gen.go
index 46dfae05c..a3fb205a9 100644
--- a/blockproducer/types/tx_gen.go
+++ b/blockproducer/interfaces/mixins_gen.go
@@ -1,4 +1,4 @@
-package types
+package interfaces
// Code generated by github.com/CovenantSQL/HashStablePack DO NOT EDIT.
@@ -7,15 +7,21 @@ import (
)
// MarshalHash marshals for hash
-func (z TxType) MarshalHash() (o []byte, err error) {
+func (z *TransactionTypeMixin) MarshalHash() (o []byte, err error) {
var b []byte
o = hsp.Require(b, z.Msgsize())
- o = hsp.AppendByte(o, byte(z))
+ // map header, size 1
+ o = append(o, 0x81, 0x81)
+ if oTemp, err := z.TxType.MarshalHash(); err != nil {
+ return nil, err
+ } else {
+ o = hsp.AppendBytes(o, oTemp)
+ }
return
}
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
-func (z TxType) Msgsize() (s int) {
- s = hsp.ByteSize
+func (z *TransactionTypeMixin) Msgsize() (s int) {
+ s = 1 + 7 + z.TxType.Msgsize()
return
}
diff --git a/blockproducer/interfaces/mixins_gen_test.go b/blockproducer/interfaces/mixins_gen_test.go
new file mode 100644
index 000000000..eb3a35968
--- /dev/null
+++ b/blockproducer/interfaces/mixins_gen_test.go
@@ -0,0 +1,47 @@
+package interfaces
+
+// Code generated by github.com/CovenantSQL/HashStablePack DO NOT EDIT.
+
+import (
+ "bytes"
+ "crypto/rand"
+ "encoding/binary"
+ "testing"
+)
+
+func TestMarshalHashTransactionTypeMixin(t *testing.T) {
+ v := TransactionTypeMixin{}
+ binary.Read(rand.Reader, binary.BigEndian, &v)
+ bts1, err := v.MarshalHash()
+ if err != nil {
+ t.Fatal(err)
+ }
+ bts2, err := v.MarshalHash()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !bytes.Equal(bts1, bts2) {
+ t.Fatal("hash not stable")
+ }
+}
+
+func BenchmarkMarshalHashTransactionTypeMixin(b *testing.B) {
+ v := TransactionTypeMixin{}
+ b.ReportAllocs()
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ v.MarshalHash()
+ }
+}
+
+func BenchmarkAppendMsgTransactionTypeMixin(b *testing.B) {
+ v := TransactionTypeMixin{}
+ bts := make([]byte, 0, v.Msgsize())
+ bts, _ = v.MarshalHash()
+ b.SetBytes(int64(len(bts)))
+ b.ReportAllocs()
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ bts, _ = v.MarshalHash()
+ }
+}
diff --git a/blockproducer/interfaces/transaction.go b/blockproducer/interfaces/transaction.go
index df2497378..f4916ac80 100644
--- a/blockproducer/interfaces/transaction.go
+++ b/blockproducer/interfaces/transaction.go
@@ -61,32 +61,46 @@ const (
TransactionTypeDeleteDatabaseUser
// TransactionTypeBaseAccount defines base account transaction type.
TransactionTypeBaseAccount
- // TransactionTypeCreataDatabase defines database creation transaction type.
- TransactionTypeCreataDatabase
+ // TransactionTypeCreateDatabase defines database creation transaction type.
+ TransactionTypeCreateDatabase
// TransactionTypeNumber defines transaction types number.
TransactionTypeNumber
)
-// Serializer is the interface implemented by an object that can serialize itself into binary form.
-type Serializer interface {
- Serialize() ([]byte, error)
-}
-
-// Deserializer is the interface implemented by an object that can deserialize a binary
-// representation of itself.
-type Deserializer interface {
- Deserialize(enc []byte) error
+func (t TransactionType) String() string {
+ switch t {
+ case TransactionTypeBilling:
+ return "Billing"
+ case TransactionTypeTransfer:
+ return "Transfer"
+ case TransactionTypeCreateAccount:
+ return "CreateAccount"
+ case TransactionTypeDeleteAccount:
+ return "DeleteAccount"
+ case TransactionTypeAddDatabaseUser:
+ return "AddDatabaseUser"
+ case TransactionTypeAlterDatabaseUser:
+ return "AlterDatabaseUser"
+ case TransactionTypeDeleteDatabaseUser:
+ return "DeleteDatabaseUser"
+ case TransactionTypeBaseAccount:
+ return "BaseAccount"
+ case TransactionTypeCreateDatabase:
+ return "CreateDatabase"
+ default:
+ return "Unknown"
+ }
}
// Transaction is the interface implemented by an object that can be verified and processed by
// block producers.
type Transaction interface {
- Serializer
- Deserializer
GetAccountAddress() proto.AccountAddress
GetAccountNonce() AccountNonce
GetHash() hash.Hash
GetTransactionType() TransactionType
Sign(signer *asymmetric.PrivateKey) error
Verify() error
+ MarshalHash() ([]byte, error)
+ Msgsize() int
}
diff --git a/blockproducer/interfaces/transaction_wrapper.go b/blockproducer/interfaces/transaction_wrapper.go
new file mode 100644
index 000000000..37948aa38
--- /dev/null
+++ b/blockproducer/interfaces/transaction_wrapper.go
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2018 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 interfaces
+
+import (
+ "reflect"
+ "sync"
+
+ "github.com/CovenantSQL/CovenantSQL/utils"
+ "github.com/pkg/errors"
+ "github.com/ugorji/go/codec"
+)
+
+const (
+ // msgpack constants, copied from go/codec/msgpack.go
+ valueTypeMap = 9
+ valueTypeArray = 10
+)
+
+var (
+ txTypeMapping sync.Map
+ txType = reflect.TypeOf((*Transaction)(nil)).Elem()
+ txWrapperType = reflect.TypeOf((*TransactionWrapper)(nil))
+
+ // ErrInvalidContainerType represents invalid container type read from msgpack bytes.
+ ErrInvalidContainerType = errors.New("invalid container type for TransactionWrapper")
+ // ErrInvalidTransactionType represents invalid transaction type read from msgpack bytes.
+ ErrInvalidTransactionType = errors.New("invalid transaction type, can not instantiate transaction")
+ // ErrTransactionRegistration represents invalid transaction object type being registered.
+ ErrTransactionRegistration = errors.New("transaction register failed")
+ // ErrMsgPackVersionMismatch represents the msgpack library abi has changed.
+ ErrMsgPackVersionMismatch = errors.New("msgpack library version mismatch")
+)
+
+func init() {
+ // detect msgpack version
+ if codec.GenVersion != 8 {
+ panic(ErrMsgPackVersionMismatch)
+ }
+
+ // register transaction wrapper to msgpack handler
+ if err := utils.RegisterInterfaceToMsgPack(txType, txWrapperType); err != nil {
+ panic(err)
+ }
+}
+
+// TransactionWrapper is the wrapper for Transaction interface for serialization/deserialization purpose.
+type TransactionWrapper struct {
+ Transaction
+}
+
+// Unwrap returns transaction within wrapper.
+func (w *TransactionWrapper) Unwrap() Transaction {
+ return w.Transaction
+}
+
+// CodecEncodeSelf implements codec.Selfer interface.
+func (w *TransactionWrapper) CodecEncodeSelf(e *codec.Encoder) {
+ helperEncoder, encDriver := codec.GenHelperEncoder(e)
+
+ if w == nil || w.Transaction == nil {
+ encDriver.EncodeNil()
+ return
+ }
+
+ // if the transaction is supports type transaction mixin
+ var rawTx interface{} = w.Transaction
+ if _, ok := rawTx.(ContainsTransactionTypeMixin); ok {
+ // encode directly
+ helperEncoder.EncFallback(w.Transaction)
+ return
+ }
+
+ // translate wrapper to two fields array wrapped by map
+ encDriver.WriteArrayStart(2)
+ encDriver.WriteArrayElem()
+ encDriver.EncodeUint(uint64(w.GetTransactionType()))
+ encDriver.WriteArrayElem()
+ helperEncoder.EncFallback(w.Transaction)
+ encDriver.WriteArrayEnd()
+}
+
+// CodecDecodeSelf implements codec.Selfer interface.
+func (w *TransactionWrapper) CodecDecodeSelf(d *codec.Decoder) {
+ _, decodeDriver := codec.GenHelperDecoder(d)
+
+ // clear fields
+ w.Transaction = nil
+ ct := decodeDriver.ContainerType()
+
+ switch ct {
+ case valueTypeArray:
+ w.decodeFromWrapper(d)
+ case valueTypeMap:
+ w.decodeFromRaw(d)
+ default:
+ panic(errors.Wrapf(ErrInvalidContainerType, "type %v applied", ct))
+ }
+}
+
+func (w *TransactionWrapper) decodeFromWrapper(d *codec.Decoder) {
+ helperDecoder, decodeDriver := codec.GenHelperDecoder(d)
+ containerLen := decodeDriver.ReadArrayStart()
+
+ for i := 0; i < containerLen; i++ {
+ if decodeDriver.CheckBreak() {
+ break
+ }
+
+ decodeDriver.ReadArrayElem()
+
+ if i == 0 {
+ if decodeDriver.TryDecodeAsNil() {
+ // invalid type, can not instantiate transaction
+ panic(ErrInvalidTransactionType)
+ } else {
+ var txType TransactionType
+ helperDecoder.DecFallback(&txType, true)
+
+ var err error
+ if w.Transaction, err = NewTransaction(txType); err != nil {
+ panic(err)
+ }
+ }
+ } else if i == 1 {
+ if ct := decodeDriver.ContainerType(); ct != valueTypeMap {
+ panic(errors.Wrapf(ErrInvalidContainerType, "type %v applied", ct))
+ }
+
+ if !decodeDriver.TryDecodeAsNil() {
+ // the container type should be struct
+ helperDecoder.DecFallback(&w.Transaction, true)
+ }
+ } else {
+ helperDecoder.DecSwallow()
+ helperDecoder.DecStructFieldNotFound(i, "")
+ }
+ }
+
+ decodeDriver.ReadArrayEnd()
+
+ if containerLen < 2 {
+ panic(ErrInvalidTransactionType)
+ }
+}
+
+func (w *TransactionWrapper) decodeFromRaw(d *codec.Decoder) {
+ helperDecoder, _ := codec.GenHelperDecoder(d)
+
+ // read all container as raw
+ rawBytes := helperDecoder.DecRaw()
+
+ var typeDetector TransactionTypeMixin
+ typeDetector.SetTransactionType(TransactionTypeNumber)
+
+ var err error
+ if err = utils.DecodeMsgPack(rawBytes, &typeDetector); err != nil {
+ panic(err)
+ }
+
+ txType := typeDetector.GetTransactionType()
+
+ if txType == TransactionTypeNumber {
+ panic(ErrInvalidTransactionType)
+ }
+
+ if w.Transaction, err = NewTransaction(txType); err != nil {
+ panic(err)
+ }
+
+ if err = utils.DecodeMsgPack(rawBytes, w.Transaction); err != nil {
+ panic(err)
+ }
+}
+
+// RegisterTransaction registers transaction type to wrapper.
+func RegisterTransaction(t TransactionType, tx Transaction) {
+ if tx == nil {
+ panic(ErrTransactionRegistration)
+ }
+ rt := reflect.TypeOf(tx)
+
+ if rt == txWrapperType {
+ panic(ErrTransactionRegistration)
+ }
+
+ txTypeMapping.Store(t, rt)
+}
+
+// NewTransaction instantiates new transaction object.
+func NewTransaction(t TransactionType) (tx Transaction, err error) {
+ var d interface{}
+ var ok bool
+ var rt reflect.Type
+
+ if d, ok = txTypeMapping.Load(t); !ok {
+ err = errors.Wrapf(ErrInvalidTransactionType, "transaction not registered")
+ return
+ }
+ rt = d.(reflect.Type)
+
+ if !rt.Implements(txType) || rt == txWrapperType {
+ err = errors.Wrap(ErrInvalidTransactionType, "invalid transaction registered")
+ return
+ }
+
+ var rv reflect.Value
+
+ if rt.Kind() == reflect.Ptr {
+ rv = reflect.New(rt.Elem())
+ } else {
+ rv = reflect.New(rt).Elem()
+ }
+
+ rawTx := rv.Interface()
+ tx = rawTx.(Transaction)
+
+ if txTypeAwareness, ok := rawTx.(ContainsTransactionTypeMixin); ok {
+ txTypeAwareness.SetTransactionType(t)
+ }
+
+ return
+}
+
+// WrapTransaction wraps transaction in wrapper.
+func WrapTransaction(tx Transaction) *TransactionWrapper {
+ return &TransactionWrapper{
+ Transaction: tx,
+ }
+}
diff --git a/blockproducer/metastate.go b/blockproducer/metastate.go
index b1bbe6a7d..b4d1ae675 100644
--- a/blockproducer/metastate.go
+++ b/blockproducer/metastate.go
@@ -81,7 +81,11 @@ func (s *metaState) loadAccountStableBalance(addr proto.AccountAddress) (b uint6
defer s.Unlock()
defer func() {
- log.Debugf("query stable account: %v, result: %v, %v", addr.String(), b, loaded)
+ log.WithFields(log.Fields{
+ "account": addr.String(),
+ "balance": b,
+ "loaded": loaded,
+ }).Debug("queried stable account")
}()
if o, loaded = s.dirty.accounts[addr]; loaded && o != nil {
@@ -101,7 +105,11 @@ func (s *metaState) loadAccountCovenantBalance(addr proto.AccountAddress) (b uin
defer s.Unlock()
defer func() {
- log.Debugf("query covenant account: %v, result: %v, %v", addr.String(), b, loaded)
+ log.WithFields(log.Fields{
+ "account": addr.String(),
+ "balance": b,
+ "loaded": loaded,
+ }).Debug("queried covenant account")
}()
if o, loaded = s.dirty.accounts[addr]; loaded && o != nil {
@@ -116,7 +124,10 @@ func (s *metaState) loadAccountCovenantBalance(addr proto.AccountAddress) (b uin
}
func (s *metaState) storeBaseAccount(k proto.AccountAddress, v *accountObject) (err error) {
- log.Debugf("store account %v to %v", k.String(), v)
+ log.WithFields(log.Fields{
+ "addr": k.String(),
+ "account": v,
+ }).Debug("store account")
// Since a transfer tx may create an empty receiver account, this method should try to cover
// the side effect.
if ao, ok := s.loadOrStoreAccountObject(k, v); ok {
@@ -310,7 +321,7 @@ func (s *metaState) partialCommitProcedure(txs []pi.Transaction) (_ func(*bolt.T
// Rebuild dirty map
cm.dirty = newMetaIndex()
for _, v := range cp.entries {
- for _, tx := range v.transacions {
+ for _, tx := range v.transactions {
if err = cm.applyTransaction(tx); err != nil {
return
}
@@ -649,15 +660,15 @@ func (s *metaState) increaseNonce(addr proto.AccountAddress) (err error) {
return
}
-func (s *metaState) applyBilling(tx *pt.TxBilling) (err error) {
- for i, v := range tx.TxContent.Receivers {
+func (s *metaState) applyBilling(tx *pt.Billing) (err error) {
+ for i, v := range tx.Receivers {
// Create empty receiver account if not found
s.loadOrStoreAccountObject(*v, &accountObject{Account: pt.Account{Address: *v}})
- if err = s.increaseAccountCovenantBalance(*v, tx.TxContent.Fees[i]); err != nil {
+ if err = s.increaseAccountCovenantBalance(*v, tx.Fees[i]); err != nil {
return
}
- if err = s.increaseAccountStableBalance(*v, tx.TxContent.Rewards[i]); err != nil {
+ if err = s.increaseAccountStableBalance(*v, tx.Rewards[i]); err != nil {
return
}
}
@@ -668,10 +679,13 @@ func (s *metaState) applyTransaction(tx pi.Transaction) (err error) {
switch t := tx.(type) {
case *pt.Transfer:
err = s.transferAccountStableBalance(t.Sender, t.Receiver, t.Amount)
- case *pt.TxBilling:
+ case *pt.Billing:
err = s.applyBilling(t)
case *pt.BaseAccount:
err = s.storeBaseAccount(t.Address, &accountObject{Account: t.Account})
+ case *pi.TransactionWrapper:
+ // call again using unwrapped transaction
+ err = s.applyTransaction(t.Unwrap())
default:
err = ErrUnknownTransactionType
}
@@ -688,7 +702,7 @@ func (s *metaState) applyTransactionProcedure(t pi.Transaction) (_ func(*bolt.Tx
}
)
- log.Debugf("try applying transaction: %v", t)
+ log.WithField("tx", t).Debug("try applying transaction")
// Static checks, which have no relation with metaState
if err = t.Verify(); err != nil {
@@ -696,20 +710,20 @@ func (s *metaState) applyTransactionProcedure(t pi.Transaction) (_ func(*bolt.Tx
}
var (
- enc []byte
+ enc *bytes.Buffer
hash = t.GetHash()
addr = t.GetAccountAddress()
nonce = t.GetAccountNonce()
ttype = t.GetTransactionType()
)
- if enc, err = t.Serialize(); err != nil {
- log.Debugf("encode failed on applying transaction: %v", err)
+ if enc, err = utils.EncodeMsgPack(t); err != nil {
+ log.WithField("tx", t).WithError(err).Debug("encode failed on applying transaction")
return errPass
}
// metaState-related checks will be performed within bolt.Tx to guarantee consistency
return func(tx *bolt.Tx) (err error) {
- log.Debugf("processing transaction: %v", t)
+ log.WithField("tx", t).Debug("processing transaction")
// Check tx existense
// TODO(leventeliu): maybe move outside?
@@ -728,19 +742,22 @@ func (s *metaState) applyTransactionProcedure(t pi.Transaction) (_ func(*bolt.Tx
}
if nextNonce != nonce {
err = ErrInvalidAccountNonce
- log.Debugf("nonce not match during transaction apply: %v", err)
+ log.WithFields(log.Fields{
+ "actual": nonce,
+ "expected": nextNonce,
+ }).WithError(err).Debug("nonce not match during transaction apply")
return
}
// Try to put transaction before any state change, will be rolled back later
// if transaction doesn't apply
tb := tx.Bucket(metaBucket[:]).Bucket(metaTransactionBucket).Bucket(ttype.Bytes())
- if err = tb.Put(hash[:], enc); err != nil {
- log.Debugf("store transaction to bucket failed: %v", err)
+ if err = tb.Put(hash[:], enc.Bytes()); err != nil {
+ log.WithError(err).Debug("store transaction to bucket failed")
return
}
// Try to apply transaction to metaState
if err = s.applyTransaction(t); err != nil {
- log.Debugf("apply transaction failed: %v", err)
+ log.WithError(err).Debug("apply transaction failed")
return
}
if err = s.increaseNonce(addr); err != nil {
@@ -758,7 +775,7 @@ func (s *metaState) pullTxs() (txs []pi.Transaction) {
defer s.Unlock()
for _, v := range s.pool.entries {
// TODO(leventeliu): check race condition.
- txs = append(txs, v.transacions...)
+ txs = append(txs, v.transactions...)
}
return
}
diff --git a/blockproducer/metastate_test.go b/blockproducer/metastate_test.go
index f8296b45a..e27cc13af 100644
--- a/blockproducer/metastate_test.go
+++ b/blockproducer/metastate_test.go
@@ -568,31 +568,29 @@ func TestMetaState(t *testing.T) {
})
})
})
- Convey("When transacions are added", func() {
+ Convey("When transactions are added", func() {
var (
n pi.AccountNonce
- t0 = &pt.BaseAccount{
- Account: pt.Account{
- Address: addr1,
- },
- }
- t1 = &pt.Transfer{
- TransferHeader: pt.TransferHeader{
+ t0 = pt.NewBaseAccount(&pt.Account{
+ Address: addr1,
+ })
+ t1 = pt.NewTransfer(
+ &pt.TransferHeader{
Sender: addr1,
Receiver: addr2,
Nonce: 1,
Amount: 0,
},
- }
- t2 = &pt.TxBilling{
- TxContent: pt.TxContent{
- SequenceID: 2,
- Receivers: []*proto.AccountAddress{&addr2},
- Fees: []uint64{1},
- Rewards: []uint64{1},
+ )
+ t2 = pt.NewBilling(
+ &pt.BillingHeader{
+ Nonce: 2,
+ Producer: addr1,
+ Receivers: []*proto.AccountAddress{&addr2},
+ Fees: []uint64{1},
+ Rewards: []uint64{1},
},
- AccountAddress: &addr1,
- }
+ )
)
err = t1.Sign(testPrivKey)
So(err, ShouldBeNil)
@@ -600,20 +598,20 @@ func TestMetaState(t *testing.T) {
So(err, ShouldBeNil)
err = db.Update(ms.applyTransactionProcedure(t0))
So(err, ShouldBeNil)
- So(len(ms.pool.entries[addr1].transacions), ShouldEqual, 1)
+ So(len(ms.pool.entries[addr1].transactions), ShouldEqual, 1)
err = db.Update(ms.applyTransactionProcedure(t1))
So(err, ShouldBeNil)
_, loaded = ms.pool.entries[t1.GetAccountAddress()]
So(loaded, ShouldBeTrue)
So(ms.pool.hasTx(t0), ShouldBeTrue)
- So(len(ms.pool.entries[addr1].transacions), ShouldEqual, 2)
+ So(len(ms.pool.entries[addr1].transactions), ShouldEqual, 2)
_, loaded = ms.pool.entries[t1.GetAccountAddress()]
So(loaded, ShouldBeTrue)
So(ms.pool.hasTx(t0), ShouldBeTrue)
So(ms.pool.hasTx(t1), ShouldBeTrue)
err = db.Update(ms.applyTransactionProcedure(t2))
So(err, ShouldBeNil)
- So(len(ms.pool.entries[addr1].transacions), ShouldEqual, 3)
+ So(len(ms.pool.entries[addr1].transactions), ShouldEqual, 3)
_, loaded = ms.pool.entries[t1.GetAccountAddress()]
So(loaded, ShouldBeTrue)
_, loaded = ms.pool.entries[t2.GetAccountAddress()]
@@ -658,25 +656,25 @@ func TestMetaState(t *testing.T) {
err = db.Update(ms.partialCommitProcedure([]pi.Transaction{}))
So(err, ShouldBeNil)
So(ms.pool.entries[addr1].baseNonce, ShouldEqual, 0)
- So(len(ms.pool.entries[addr1].transacions), ShouldEqual, 3)
+ So(len(ms.pool.entries[addr1].transactions), ShouldEqual, 3)
})
Convey("The partial commit procedure should be appliable for tx0", func() {
err = db.Update(ms.partialCommitProcedure([]pi.Transaction{t0}))
So(err, ShouldBeNil)
So(ms.pool.entries[addr1].baseNonce, ShouldEqual, 1)
- So(len(ms.pool.entries[addr1].transacions), ShouldEqual, 2)
+ So(len(ms.pool.entries[addr1].transactions), ShouldEqual, 2)
})
Convey("The partial commit procedure should be appliable for tx0-1", func() {
err = db.Update(ms.partialCommitProcedure([]pi.Transaction{t0, t1}))
So(err, ShouldBeNil)
So(ms.pool.entries[addr1].baseNonce, ShouldEqual, 2)
- So(len(ms.pool.entries[addr1].transacions), ShouldEqual, 1)
+ So(len(ms.pool.entries[addr1].transactions), ShouldEqual, 1)
})
Convey("The partial commit procedure should be appliable for all tx", func() {
err = db.Update(ms.partialCommitProcedure([]pi.Transaction{t0, t1, t2}))
So(err, ShouldBeNil)
So(ms.pool.entries[addr1].baseNonce, ShouldEqual, 3)
- So(len(ms.pool.entries[addr1].transacions), ShouldEqual, 0)
+ So(len(ms.pool.entries[addr1].transactions), ShouldEqual, 0)
})
Convey(
"The partial commit procedure should not be appliable for modified tx",
@@ -686,7 +684,7 @@ func TestMetaState(t *testing.T) {
So(err, ShouldBeNil)
err = db.Update(ms.partialCommitProcedure([]pi.Transaction{t0, t1, t2}))
So(err, ShouldEqual, ErrTransactionMismatch)
- So(len(ms.pool.entries[addr1].transacions), ShouldEqual, 3)
+ So(len(ms.pool.entries[addr1].transactions), ShouldEqual, 3)
},
)
})
@@ -694,78 +692,78 @@ func TestMetaState(t *testing.T) {
Convey("When base account txs are added", func() {
var (
txs = []pi.Transaction{
- &pt.BaseAccount{
- Account: pt.Account{
+ pt.NewBaseAccount(
+ &pt.Account{
Address: addr1,
StableCoinBalance: 100,
CovenantCoinBalance: 100,
},
- },
- &pt.BaseAccount{
- Account: pt.Account{
+ ),
+ pt.NewBaseAccount(
+ &pt.Account{
Address: addr2,
StableCoinBalance: 100,
CovenantCoinBalance: 100,
},
- },
- &pt.Transfer{
- TransferHeader: pt.TransferHeader{
+ ),
+ pt.NewTransfer(
+ &pt.TransferHeader{
Sender: addr1,
Receiver: addr2,
Nonce: 1,
Amount: 10,
},
- },
- &pt.TxBilling{
- TxContent: pt.TxContent{
- SequenceID: 2,
- Receivers: []*proto.AccountAddress{&addr2},
- Fees: []uint64{1},
- Rewards: []uint64{1},
+ ),
+ pt.NewBilling(
+ &pt.BillingHeader{
+ Nonce: 2,
+ Producer: addr1,
+ Receivers: []*proto.AccountAddress{&addr2},
+ Fees: []uint64{1},
+ Rewards: []uint64{1},
},
- AccountAddress: &addr1,
- },
- &pt.TxBilling{
- TxContent: pt.TxContent{
- SequenceID: 1,
- Receivers: []*proto.AccountAddress{&addr1},
- Fees: []uint64{1},
- Rewards: []uint64{1},
+ ),
+ pt.NewBilling(
+ &pt.BillingHeader{
+ Nonce: 1,
+ Producer: addr2,
+ Receivers: []*proto.AccountAddress{&addr1},
+ Fees: []uint64{1},
+ Rewards: []uint64{1},
},
- AccountAddress: &addr2,
- },
- &pt.Transfer{
- TransferHeader: pt.TransferHeader{
+ ),
+ pt.NewTransfer(
+ &pt.TransferHeader{
Sender: addr2,
Receiver: addr1,
Nonce: 2,
Amount: 1,
},
- },
- &pt.Transfer{
- TransferHeader: pt.TransferHeader{
+ ),
+ pt.NewTransfer(
+ &pt.TransferHeader{
Sender: addr1,
Receiver: addr2,
Nonce: 3,
Amount: 10,
},
- },
- &pt.Transfer{
- TransferHeader: pt.TransferHeader{
+ ),
+ pt.NewTransfer(
+ &pt.TransferHeader{
Sender: addr2,
Receiver: addr1,
Nonce: 3,
Amount: 1,
},
- },
- &pt.Transfer{
- TransferHeader: pt.TransferHeader{
+ ),
+ pt.NewTransfer(
+ &pt.TransferHeader{
Sender: addr2,
Receiver: addr1,
Nonce: 4,
Amount: 1,
},
- },
+ ),
}
)
for _, tx := range txs {
diff --git a/blockproducer/rpc.go b/blockproducer/rpc.go
index 22322558d..358e5bad0 100644
--- a/blockproducer/rpc.go
+++ b/blockproducer/rpc.go
@@ -20,11 +20,7 @@ import (
pi "github.com/CovenantSQL/CovenantSQL/blockproducer/interfaces"
"github.com/CovenantSQL/CovenantSQL/blockproducer/types"
"github.com/CovenantSQL/CovenantSQL/proto"
-)
-
-const (
- // MainChainRPCName defines rpc service name of main chain internal consensus.
- MainChainRPCName = "MCC"
+ ct "github.com/CovenantSQL/CovenantSQL/sqlchain/types"
)
// ChainRPCService defines a main chain RPC server.
@@ -46,7 +42,7 @@ type AdviseNewBlockResp struct {
// AdviseTxBillingReq defines a request of the AdviseTxBilling RPC method.
type AdviseTxBillingReq struct {
proto.Envelope
- TxBilling *types.TxBilling
+ TxBilling *types.Billing
}
// AdviseTxBillingResp defines a response of the AdviseTxBilling RPC method.
@@ -54,18 +50,6 @@ type AdviseTxBillingResp struct {
proto.Envelope
}
-// AdviseBillingReq defines a request of the AdviseBillingRequest RPC method.
-type AdviseBillingReq struct {
- proto.Envelope
- Req *types.BillingRequest
-}
-
-// AdviseBillingResp defines a request of the AdviseBillingRequest RPC method.
-type AdviseBillingResp struct {
- proto.Envelope
- Resp *types.BillingResponse
-}
-
// FetchBlockReq defines a request of the FetchBlock RPC method.
type FetchBlockReq struct {
proto.Envelope
@@ -76,9 +60,16 @@ type FetchBlockReq struct {
type FetchBlockResp struct {
proto.Envelope
Height uint32
+ Count uint32
Block *types.Block
}
+// FetchBlockByCountReq define a request of the FetchBlockByCount RPC method.
+type FetchBlockByCountReq struct {
+ proto.Envelope
+ Count uint32
+}
+
// FetchTxBillingReq defines a request of the FetchTxBilling RPC method.
type FetchTxBillingReq struct {
proto.Envelope
@@ -113,12 +104,6 @@ type AddTxResp struct {
proto.Envelope
}
-// AddTxTransferReq defines a request of AddTxTransfer RPC method.
-type AddTxTransferReq struct {
- proto.Envelope
- Tx *types.Transfer
-}
-
// QueryAccountStableBalanceReq defines a request of the QueryAccountStableBalance RPC method.
type QueryAccountStableBalanceReq struct {
proto.Envelope
@@ -153,14 +138,9 @@ func (s *ChainRPCService) AdviseNewBlock(req *AdviseNewBlockReq, resp *AdviseNew
return s.chain.pushBlock(req.Block)
}
-// AdviseTxBilling is the RPC method to advise a new billing tx to target server.
-func (s *ChainRPCService) AdviseTxBilling(req *AdviseTxBillingReq, resp *AdviseTxBillingResp) error {
- return s.chain.pushTxBilling(req.TxBilling)
-}
-
// AdviseBillingRequest is the RPC method to advise a new billing request to main chain.
-func (s *ChainRPCService) AdviseBillingRequest(req *AdviseBillingReq, resp *AdviseBillingResp) error {
- response, err := s.chain.produceTxBilling(req.Req)
+func (s *ChainRPCService) AdviseBillingRequest(req *ct.AdviseBillingReq, resp *ct.AdviseBillingResp) error {
+ response, err := s.chain.produceBilling(req.Req)
if err != nil {
return err
}
@@ -168,15 +148,31 @@ func (s *ChainRPCService) AdviseBillingRequest(req *AdviseBillingReq, resp *Advi
return nil
}
-// FetchBlock is the RPC method to fetch a known block form the target server.
+// FetchBlock is the RPC method to fetch a known block from the target server.
func (s *ChainRPCService) FetchBlock(req *FetchBlockReq, resp *FetchBlockResp) error {
resp.Height = req.Height
- block, err := s.chain.fetchBlockByHeight(req.Height)
+ block, count, err := s.chain.fetchBlockByHeight(req.Height)
+ if err != nil {
+ return err
+ }
resp.Block = block
+ resp.Count = count
return err
}
-// FetchTxBilling is the RPC method to fetch a known billing tx form the target server.
+// FetchBlockByCount is the RPC method to fetch a known block from the target server.
+func (s *ChainRPCService) FetchBlockByCount(req *FetchBlockByCountReq, resp *FetchBlockResp) error {
+ resp.Count = req.Count
+ block, height, err := s.chain.fetchBlockByCount(req.Count)
+ if err != nil {
+ return err
+ }
+ resp.Block = block
+ resp.Height = height
+ return err
+}
+
+// FetchTxBilling is the RPC method to fetch a known billing tx from the target server.
func (s *ChainRPCService) FetchTxBilling(req *FetchTxBillingReq, resp *FetchTxBillingResp) error {
return nil
}
@@ -203,17 +199,6 @@ func (s *ChainRPCService) AddTx(req *AddTxReq, resp *AddTxResp) (err error) {
return
}
-// AddTxTransfer is the RPC method to add a transfer transaction.
-func (s *ChainRPCService) AddTxTransfer(req *AddTxTransferReq, resp *AddTxResp) (err error) {
- if req.Tx == nil {
- return ErrUnknownTransactionType
- }
-
- s.chain.pendingTxs <- req.Tx
-
- return
-}
-
// QueryAccountStableBalance is the RPC method to query acccount stable coin balance.
func (s *ChainRPCService) QueryAccountStableBalance(
req *QueryAccountStableBalanceReq, resp *QueryAccountStableBalanceResp) (err error,
diff --git a/blockproducer/runtime.go b/blockproducer/runtime.go
index f282a6cda..b1e376f0d 100644
--- a/blockproducer/runtime.go
+++ b/blockproducer/runtime.go
@@ -23,6 +23,7 @@ import (
"github.com/CovenantSQL/CovenantSQL/kayak"
"github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/route"
"github.com/CovenantSQL/CovenantSQL/rpc"
)
@@ -99,7 +100,7 @@ func newRuntime(cfg *Config, accountAddress proto.AccountAddress) *rt {
}
func (r *rt) startService(chain *Chain) {
- r.server.RegisterService(MainChainRPCName, &ChainRPCService{chain: chain})
+ r.server.RegisterService(route.BlockProducerRPCName, &ChainRPCService{chain: chain})
}
// nextTick returns the current clock reading and the duration till the next turn. If duration
diff --git a/blockproducer/state.go b/blockproducer/state.go
index 3875c9004..c82fc3618 100644
--- a/blockproducer/state.go
+++ b/blockproducer/state.go
@@ -20,7 +20,6 @@ import (
"sync"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
- "github.com/CovenantSQL/CovenantSQL/utils"
)
// State store the node info of chain.
@@ -31,22 +30,6 @@ type State struct {
Height uint32
}
-// serialize serializes the state.
-func (s *State) serialize() ([]byte, error) {
- buffer, err := utils.EncodeMsgPack(s)
- if err != nil {
- return nil, err
- }
-
- return buffer.Bytes(), nil
-}
-
-// deserialize deserializes the state.
-func (s *State) deserialize(b []byte) error {
- err := utils.DecodeMsgPack(b, s)
- return err
-}
-
func (s *State) getNode() *blockNode {
s.Lock()
defer s.Unlock()
diff --git a/blockproducer/txindex.go b/blockproducer/txindex.go
deleted file mode 100644
index d17eebd21..000000000
--- a/blockproducer/txindex.go
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2018 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 blockproducer
-
-import (
- "sync"
-
- "github.com/CovenantSQL/CovenantSQL/blockproducer/types"
- "github.com/CovenantSQL/CovenantSQL/crypto/hash"
- "github.com/CovenantSQL/CovenantSQL/proto"
-)
-
-// txIndex indexes the tx blockchain receive.
-type txIndex struct {
- mu sync.Mutex
-
- billingHashIndex map[hash.Hash]*types.TxBilling
- // lastBillingIndex indexes last appearing txBilling of DatabaseID
- // to ensure the nonce of txbilling monotone increasing
- lastBillingIndex map[*proto.DatabaseID]uint32
-}
-
-// newTxIndex creates a new TxIndex.
-func newTxIndex() *txIndex {
- ti := txIndex{
- billingHashIndex: make(map[hash.Hash]*types.TxBilling),
- lastBillingIndex: make(map[*proto.DatabaseID]uint32),
- }
- return &ti
-}
-
-// addTxBilling adds a checked TxBilling in the TxIndex.
-func (ti *txIndex) addTxBilling(tb *types.TxBilling) error {
- ti.mu.Lock()
- defer ti.mu.Unlock()
-
- if v, ok := ti.billingHashIndex[*tb.TxHash]; ok {
- // TODO(lambda): ensure whether the situation will happen
- if v == nil {
- return ErrCorruptedIndex
- }
- }
-
- ti.billingHashIndex[*tb.TxHash] = tb
-
- return nil
-}
-
-// updateLatTxBilling updates the last billing index of specific databaseID.
-func (ti *txIndex) updateLastTxBilling(databaseID *proto.DatabaseID, sequenceID uint32) (err error) {
- ti.mu.Lock()
- defer ti.mu.Unlock()
-
- if v, ok := ti.lastBillingIndex[databaseID]; ok {
- if v >= sequenceID {
- return ErrSmallerSequenceID
- }
- ti.lastBillingIndex[databaseID] = sequenceID
- }
- ti.lastBillingIndex[databaseID] = sequenceID
- return
-}
-
-// fetchUnpackedTxBillings fetch all txbillings in index.
-func (ti *txIndex) fetchUnpackedTxBillings() []*types.TxBilling {
- ti.mu.Lock()
- defer ti.mu.Unlock()
-
- txes := make([]*types.TxBilling, 0, 1024)
-
- for _, t := range ti.billingHashIndex {
- if t != nil && t.SignedBlock == nil {
- txes = append(txes, t)
- }
- }
- return txes
-}
-
-// hasTxBilling look up the specific txbilling in index.
-func (ti *txIndex) hasTxBilling(h *hash.Hash) bool {
- _, ok := ti.billingHashIndex[*h]
- return ok
-}
-
-// getTxBilling look up the specific txbilling in index.
-func (ti *txIndex) getTxBilling(h *hash.Hash) *types.TxBilling {
- val := ti.billingHashIndex[*h]
- return val
-}
-
-// lastSequenceID look up the last sequenceID of specific databaseID.
-func (ti *txIndex) lastSequenceID(databaseID *proto.DatabaseID) (uint32, error) {
- if seqID, ok := ti.lastBillingIndex[databaseID]; ok {
- return seqID, nil
- }
- return 0, ErrNoSuchTxBilling
-}
diff --git a/blockproducer/txindex_test.go b/blockproducer/txindex_test.go
deleted file mode 100644
index 784c7808f..000000000
--- a/blockproducer/txindex_test.go
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2018 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 blockproducer
-
-import (
- "math/rand"
- "reflect"
- "testing"
-
- "github.com/CovenantSQL/CovenantSQL/blockproducer/types"
-)
-
-func Test_AddAndHasTxBilling(t *testing.T) {
- ti := newTxIndex()
- maxLen := 100
- mlen := rand.Intn(maxLen)
- tbs := make([]*types.TxBilling, mlen)
- for i := range tbs {
- tb, err := generateRandomTxBilling()
- if err != nil {
- t.Fatalf("unexpect error: %v", err)
- }
- tbs[i] = tb
- err = ti.addTxBilling(tb)
- if err != nil {
- t.Fatalf("unexpect error: %v", err)
- }
- }
-
- for i := range tbs {
- if !ti.hasTxBilling(tbs[i].TxHash) {
- t.Fatalf("tx (%v) should be included in tx index", tbs[i])
- }
- if val := ti.getTxBilling(tbs[i].TxHash); !reflect.DeepEqual(tbs[i], val) {
- t.Fatalf("tx (%v) should be included in tx index", tbs[i])
- }
- tb, err := generateRandomTxBilling()
- if err != nil {
- t.Fatalf("unexpect error: %v", err)
- }
- if ti.hasTxBilling(tb.TxHash) {
- t.Fatalf("tx (%v) should be excluded in tx index", tb)
- }
- }
-
- fetchedTbs := ti.fetchUnpackedTxBillings()
- for i := range fetchedTbs {
- if !reflect.DeepEqual(tbs[i], fetchedTbs[i]) {
- t.Fatalf("two values should be equal: \n\tv1=%v\n\tv2=%v", tbs[i], fetchedTbs[i])
- }
- }
-}
diff --git a/blockproducer/txpool.go b/blockproducer/txpool.go
index 8a17156c8..4fd46f683 100644
--- a/blockproducer/txpool.go
+++ b/blockproducer/txpool.go
@@ -23,34 +23,34 @@ import (
)
type accountTxEntries struct {
- account proto.AccountAddress
- baseNonce pi.AccountNonce
- transacions []pi.Transaction
+ account proto.AccountAddress
+ baseNonce pi.AccountNonce
+ transactions []pi.Transaction
}
func newAccountTxEntries(
addr proto.AccountAddress, baseNonce pi.AccountNonce) (_ *accountTxEntries,
) {
return &accountTxEntries{
- account: addr,
- baseNonce: baseNonce,
- transacions: nil,
+ account: addr,
+ baseNonce: baseNonce,
+ transactions: nil,
}
}
func (e *accountTxEntries) nextNonce() pi.AccountNonce {
- return e.baseNonce + pi.AccountNonce(len(e.transacions))
+ return e.baseNonce + pi.AccountNonce(len(e.transactions))
}
func (e *accountTxEntries) addTx(tx pi.Transaction) {
- e.transacions = append(e.transacions, tx)
+ e.transactions = append(e.transactions, tx)
}
func (e *accountTxEntries) halfDeepCopy() (cpy *accountTxEntries) {
return &accountTxEntries{
- account: e.account,
- baseNonce: e.baseNonce,
- transacions: e.transacions[:],
+ account: e.account,
+ baseNonce: e.baseNonce,
+ transactions: e.transactions[:],
}
}
@@ -89,12 +89,12 @@ func (p *txPool) hasTx(tx pi.Transaction) (ok bool) {
nonce = tx.GetAccountNonce()
index = int(nonce - te.baseNonce)
)
- if ok = (nonce >= te.baseNonce && index < len(te.transacions)); !ok {
+ if ok = (nonce >= te.baseNonce && index < len(te.transactions)); !ok {
log.Debug("transaction nonce or index already exists")
return
}
// Check transaction hash
- if ok = (tx.GetHash() == te.transacions[index].GetHash()); !ok {
+ if ok = (tx.GetHash() == te.transactions[index].GetHash()); !ok {
log.Debug("transaction hash already exists")
return
}
@@ -108,15 +108,15 @@ func (p *txPool) cmpAndMoveNextTx(tx pi.Transaction) (ok bool) {
return
}
// Out of range
- if ok = (tx.GetAccountNonce() == te.baseNonce && len(te.transacions) > 0); !ok {
+ if ok = (tx.GetAccountNonce() == te.baseNonce && len(te.transactions) > 0); !ok {
return
}
// Check transaction hash
- if ok = (tx.GetHash() == te.transacions[0].GetHash()); !ok {
+ if ok = (tx.GetHash() == te.transactions[0].GetHash()); !ok {
return
}
// Move forward
- te.transacions = te.transacions[1:]
+ te.transactions = te.transactions[1:]
te.baseNonce++
return
}
diff --git a/blockproducer/types/account_gen.go b/blockproducer/types/account_gen.go
index 1b7ea56b4..031082942 100644
--- a/blockproducer/types/account_gen.go
+++ b/blockproducer/types/account_gen.go
@@ -12,14 +12,14 @@ func (z *Account) MarshalHash() (o []byte, err error) {
o = hsp.Require(b, z.Msgsize())
// map header, size 5
o = append(o, 0x85, 0x85)
+ o = hsp.AppendFloat64(o, z.Rating)
+ o = append(o, 0x85)
if oTemp, err := z.NextNonce.MarshalHash(); err != nil {
return nil, err
} else {
o = hsp.AppendBytes(o, oTemp)
}
o = append(o, 0x85)
- o = hsp.AppendFloat64(o, z.Rating)
- o = append(o, 0x85)
if oTemp, err := z.Address.MarshalHash(); err != nil {
return nil, err
} else {
@@ -34,7 +34,7 @@ func (z *Account) MarshalHash() (o []byte, err error) {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *Account) Msgsize() (s int) {
- s = 1 + 10 + z.NextNonce.Msgsize() + 7 + hsp.Float64Size + 8 + z.Address.Msgsize() + 18 + hsp.Uint64Size + 20 + hsp.Uint64Size
+ s = 1 + 7 + hsp.Float64Size + 10 + z.NextNonce.Msgsize() + 8 + z.Address.Msgsize() + 18 + hsp.Uint64Size + 20 + hsp.Uint64Size
return
}
diff --git a/blockproducer/types/baseaccount.go b/blockproducer/types/baseaccount.go
index af93be2ec..ce4facda1 100644
--- a/blockproducer/types/baseaccount.go
+++ b/blockproducer/types/baseaccount.go
@@ -17,13 +17,10 @@
package types
import (
- "bytes"
-
pi "github.com/CovenantSQL/CovenantSQL/blockproducer/interfaces"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
"github.com/CovenantSQL/CovenantSQL/proto"
- "github.com/CovenantSQL/CovenantSQL/utils"
)
//go:generate hsp
@@ -31,22 +28,15 @@ import (
// BaseAccount defines the base account type header.
type BaseAccount struct {
Account
- AccountHash hash.Hash
+ pi.TransactionTypeMixin
}
-// Serialize implements interfaces/Transaction.Serialize.
-func (b *BaseAccount) Serialize() (s []byte, err error) {
- var enc *bytes.Buffer
- if enc, err = utils.EncodeMsgPack(b); err != nil {
- return
+// NewBaseAccount returns new instance.
+func NewBaseAccount(account *Account) *BaseAccount {
+ return &BaseAccount{
+ Account: *account,
+ TransactionTypeMixin: *pi.NewTransactionTypeMixin(pi.TransactionTypeBaseAccount),
}
- s = enc.Bytes()
- return
-}
-
-// Deserialize implements interfaces/Transaction.Deserialize.
-func (b *BaseAccount) Deserialize(enc []byte) error {
- return utils.DecodeMsgPack(enc, b)
}
// GetAccountAddress implements interfaces/Transaction.GetAccountAddress.
@@ -61,13 +51,8 @@ func (b *BaseAccount) GetAccountNonce() pi.AccountNonce {
}
// GetHash implements interfaces/Transaction.GetHash.
-func (b *BaseAccount) GetHash() hash.Hash {
- return b.AccountHash
-}
-
-// GetTransactionType implements interfaces/Transaction.GetTransactionType.
-func (b *BaseAccount) GetTransactionType() pi.TransactionType {
- return pi.TransactionTypeBaseAccount
+func (b *BaseAccount) GetHash() (h hash.Hash) {
+ return
}
// Sign implements interfaces/Transaction.Sign.
@@ -79,3 +64,7 @@ func (b *BaseAccount) Sign(signer *asymmetric.PrivateKey) (err error) {
func (b *BaseAccount) Verify() (err error) {
return
}
+
+func init() {
+ pi.RegisterTransaction(pi.TransactionTypeBaseAccount, (*BaseAccount)(nil))
+}
diff --git a/blockproducer/types/baseaccount_gen.go b/blockproducer/types/baseaccount_gen.go
index 6f8c8f40f..857c98fd1 100644
--- a/blockproducer/types/baseaccount_gen.go
+++ b/blockproducer/types/baseaccount_gen.go
@@ -18,7 +18,7 @@ func (z *BaseAccount) MarshalHash() (o []byte, err error) {
o = hsp.AppendBytes(o, oTemp)
}
o = append(o, 0x82)
- if oTemp, err := z.AccountHash.MarshalHash(); err != nil {
+ if oTemp, err := z.TransactionTypeMixin.MarshalHash(); err != nil {
return nil, err
} else {
o = hsp.AppendBytes(o, oTemp)
@@ -28,6 +28,6 @@ func (z *BaseAccount) MarshalHash() (o []byte, err error) {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *BaseAccount) Msgsize() (s int) {
- s = 1 + 8 + z.Account.Msgsize() + 12 + z.AccountHash.Msgsize()
+ s = 1 + 8 + z.Account.Msgsize() + 21 + z.TransactionTypeMixin.Msgsize()
return
}
diff --git a/blockproducer/types/billing.go b/blockproducer/types/billing.go
index 3e4f80502..0beeb86f7 100644
--- a/blockproducer/types/billing.go
+++ b/blockproducer/types/billing.go
@@ -17,94 +17,81 @@
package types
import (
+ pi "github.com/CovenantSQL/CovenantSQL/blockproducer/interfaces"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
- "github.com/CovenantSQL/CovenantSQL/crypto/hash"
"github.com/CovenantSQL/CovenantSQL/proto"
)
//go:generate hsp
-// BillingRequestHeader includes contents that need to be signed. Billing blocks should be within
-// height range [low, high] (inclusive).
-type BillingRequestHeader struct {
- DatabaseID proto.DatabaseID
- // sqlchain block hash and its height
- LowBlock hash.Hash
- LowHeight int32
- HighBlock hash.Hash
- HighHeight int32
- GasAmounts []*proto.AddrAndGas
+// BillingHeader defines the customer's billing and block rewards in transaction.
+type BillingHeader struct {
+ // Transaction nonce
+ Nonce pi.AccountNonce
+ BillingRequest BillingRequest
+ // Bill producer
+ Producer proto.AccountAddress
+ // Bill receivers
+ Receivers []*proto.AccountAddress
+ // Fee paid by stable coin
+ Fees []uint64
+ // Reward is share coin
+ Rewards []uint64
}
-//
-//// MarshalHash marshals for hash
-//func (bh *BillingRequestHeader) MarshalHash() ([]byte, error) {
-// buffer := bytes.NewBuffer(nil)
-//
-// err := utils.WriteElements(buffer, binary.BigEndian,
-// &bh.DatabaseID,
-// &bh.LowBlock,
-// &bh.LowHeight,
-// &bh.HighBlock,
-// &bh.HighHeight,
-// &bh.GasAmounts,
-// )
-//
-// if err != nil {
-// return nil, err
-// }
-// return buffer.Bytes(), nil
-//}
-
-// BillingRequest defines periodically Billing sync.
-type BillingRequest struct {
- Header BillingRequestHeader
- RequestHash hash.Hash
- Signees []*asymmetric.PublicKey
- Signatures []*asymmetric.Signature
+// NewBillingHeader generates new BillingHeader.
+func NewBillingHeader(nonce pi.AccountNonce, bReq *BillingRequest, producer proto.AccountAddress, receivers []*proto.AccountAddress,
+ fees []uint64, rewards []uint64) *BillingHeader {
+ return &BillingHeader{
+ Nonce: nonce,
+ BillingRequest: *bReq,
+ Producer: producer,
+ Receivers: receivers,
+ Fees: fees,
+ Rewards: rewards,
+ }
}
-//// MarshalHash marshals for hash
-//func (br *BillingRequest) MarshalHash() ([]byte, error) {
-// buffer := bytes.NewBuffer(nil)
-//
-// err := utils.WriteElements(buffer, binary.BigEndian,
-// &br.Header,
-// &br.RequestHash,
-// &br.Signees,
-// &br.Signatures,
-// )
-//
-// if err != nil {
-// return nil, err
-// }
-// return buffer.Bytes(), nil
-//}
+// Billing is a type of tx, that is used to record sql chain billing and block rewards.
+type Billing struct {
+ BillingHeader
+ pi.TransactionTypeMixin
+ DefaultHashSignVerifierImpl
+}
-// PackRequestHeader computes the hash of header.
-func (br *BillingRequest) PackRequestHeader() (*hash.Hash, error) {
- b, err := br.Header.MarshalHash()
- if err != nil {
- return nil, err
+// NewBilling generates a new Billing.
+func NewBilling(header *BillingHeader) *Billing {
+ return &Billing{
+ BillingHeader: *header,
+ TransactionTypeMixin: *pi.NewTransactionTypeMixin(pi.TransactionTypeBilling),
}
+}
- h := hash.THashH(b)
- return &h, nil
+// Sign implements interfaces/Transaction.Sign.
+func (tb *Billing) Sign(signer *asymmetric.PrivateKey) (err error) {
+ return tb.DefaultHashSignVerifierImpl.Sign(&tb.BillingHeader, signer)
}
-// SignRequestHeader first computes the hash of BillingRequestHeader, then signs the request.
-func (br *BillingRequest) SignRequestHeader(signee *asymmetric.PrivateKey) (*asymmetric.Signature, error) {
- signature, err := signee.Sign(br.RequestHash[:])
- if err != nil {
- return nil, err
- }
- return signature, nil
+// Verify implements interfaces/Transaction.Verify.
+func (tb *Billing) Verify() error {
+ return tb.DefaultHashSignVerifierImpl.Verify(&tb.BillingHeader)
+}
+
+// GetAccountAddress implements interfaces/Transaction.GetAccountAddress.
+func (tb *Billing) GetAccountAddress() proto.AccountAddress {
+ return tb.Producer
+}
+
+// GetAccountNonce implements interfaces/Transaction.GetAccountNonce.
+func (tb *Billing) GetAccountNonce() pi.AccountNonce {
+ return tb.Nonce
+}
+
+// GetDatabaseID gets the database ID.
+func (tb *Billing) GetDatabaseID() *proto.DatabaseID {
+ return &tb.BillingRequest.Header.DatabaseID
}
-// BillingResponse defines the the response for BillingRequest.
-type BillingResponse struct {
- AccountAddress proto.AccountAddress
- RequestHash hash.Hash
- Signee *asymmetric.PublicKey
- Signature *asymmetric.Signature
+func init() {
+ pi.RegisterTransaction(pi.TransactionTypeBilling, (*Billing)(nil))
}
diff --git a/blockproducer/types/billing_gen.go b/blockproducer/types/billing_gen.go
index 6e2efb4ab..5260f1a35 100644
--- a/blockproducer/types/billing_gen.go
+++ b/blockproducer/types/billing_gen.go
@@ -7,44 +7,24 @@ import (
)
// MarshalHash marshals for hash
-func (z *BillingRequest) MarshalHash() (o []byte, err error) {
+func (z *Billing) MarshalHash() (o []byte, err error) {
var b []byte
o = hsp.Require(b, z.Msgsize())
- // map header, size 4
- o = append(o, 0x84, 0x84)
- if oTemp, err := z.Header.MarshalHash(); err != nil {
+ // map header, size 3
+ o = append(o, 0x83, 0x83)
+ if oTemp, err := z.BillingHeader.MarshalHash(); err != nil {
return nil, err
} else {
o = hsp.AppendBytes(o, oTemp)
}
- o = append(o, 0x84)
- o = hsp.AppendArrayHeader(o, uint32(len(z.Signees)))
- for za0001 := range z.Signees {
- if z.Signees[za0001] == nil {
- o = hsp.AppendNil(o)
- } else {
- if oTemp, err := z.Signees[za0001].MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
- }
- }
- o = append(o, 0x84)
- o = hsp.AppendArrayHeader(o, uint32(len(z.Signatures)))
- for za0002 := range z.Signatures {
- if z.Signatures[za0002] == nil {
- o = hsp.AppendNil(o)
- } else {
- if oTemp, err := z.Signatures[za0002].MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
- }
+ o = append(o, 0x83)
+ if oTemp, err := z.DefaultHashSignVerifierImpl.MarshalHash(); err != nil {
+ return nil, err
+ } else {
+ o = hsp.AppendBytes(o, oTemp)
}
- o = append(o, 0x84)
- if oTemp, err := z.RequestHash.MarshalHash(); err != nil {
+ o = append(o, 0x83)
+ if oTemp, err := z.TransactionTypeMixin.MarshalHash(); err != nil {
return nil, err
} else {
o = hsp.AppendBytes(o, oTemp)
@@ -53,39 +33,29 @@ func (z *BillingRequest) MarshalHash() (o []byte, err error) {
}
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
-func (z *BillingRequest) Msgsize() (s int) {
- s = 1 + 7 + z.Header.Msgsize() + 8 + hsp.ArrayHeaderSize
- for za0001 := range z.Signees {
- if z.Signees[za0001] == nil {
- s += hsp.NilSize
- } else {
- s += z.Signees[za0001].Msgsize()
- }
- }
- s += 11 + hsp.ArrayHeaderSize
- for za0002 := range z.Signatures {
- if z.Signatures[za0002] == nil {
- s += hsp.NilSize
- } else {
- s += z.Signatures[za0002].Msgsize()
- }
- }
- s += 12 + z.RequestHash.Msgsize()
+func (z *Billing) Msgsize() (s int) {
+ s = 1 + 14 + z.BillingHeader.Msgsize() + 28 + z.DefaultHashSignVerifierImpl.Msgsize() + 21 + z.TransactionTypeMixin.Msgsize()
return
}
// MarshalHash marshals for hash
-func (z *BillingRequestHeader) MarshalHash() (o []byte, err error) {
+func (z *BillingHeader) MarshalHash() (o []byte, err error) {
var b []byte
o = hsp.Require(b, z.Msgsize())
// map header, size 6
o = append(o, 0x86, 0x86)
- o = hsp.AppendArrayHeader(o, uint32(len(z.GasAmounts)))
- for za0001 := range z.GasAmounts {
- if z.GasAmounts[za0001] == nil {
+ if oTemp, err := z.BillingRequest.MarshalHash(); err != nil {
+ return nil, err
+ } else {
+ o = hsp.AppendBytes(o, oTemp)
+ }
+ o = append(o, 0x86)
+ o = hsp.AppendArrayHeader(o, uint32(len(z.Receivers)))
+ for za0001 := range z.Receivers {
+ if z.Receivers[za0001] == nil {
o = hsp.AppendNil(o)
} else {
- if oTemp, err := z.GasAmounts[za0001].MarshalHash(); err != nil {
+ if oTemp, err := z.Receivers[za0001].MarshalHash(); err != nil {
return nil, err
} else {
o = hsp.AppendBytes(o, oTemp)
@@ -93,23 +63,23 @@ func (z *BillingRequestHeader) MarshalHash() (o []byte, err error) {
}
}
o = append(o, 0x86)
- if oTemp, err := z.LowBlock.MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
+ o = hsp.AppendArrayHeader(o, uint32(len(z.Fees)))
+ for za0002 := range z.Fees {
+ o = hsp.AppendUint64(o, z.Fees[za0002])
}
o = append(o, 0x86)
- if oTemp, err := z.HighBlock.MarshalHash(); err != nil {
+ o = hsp.AppendArrayHeader(o, uint32(len(z.Rewards)))
+ for za0003 := range z.Rewards {
+ o = hsp.AppendUint64(o, z.Rewards[za0003])
+ }
+ o = append(o, 0x86)
+ if oTemp, err := z.Nonce.MarshalHash(); err != nil {
return nil, err
} else {
o = hsp.AppendBytes(o, oTemp)
}
o = append(o, 0x86)
- o = hsp.AppendInt32(o, z.LowHeight)
- o = append(o, 0x86)
- o = hsp.AppendInt32(o, z.HighHeight)
- o = append(o, 0x86)
- if oTemp, err := z.DatabaseID.MarshalHash(); err != nil {
+ if oTemp, err := z.Producer.MarshalHash(); err != nil {
return nil, err
} else {
o = hsp.AppendBytes(o, oTemp)
@@ -118,73 +88,15 @@ func (z *BillingRequestHeader) MarshalHash() (o []byte, err error) {
}
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
-func (z *BillingRequestHeader) Msgsize() (s int) {
- s = 1 + 11 + hsp.ArrayHeaderSize
- for za0001 := range z.GasAmounts {
- if z.GasAmounts[za0001] == nil {
+func (z *BillingHeader) Msgsize() (s int) {
+ s = 1 + 15 + z.BillingRequest.Msgsize() + 10 + hsp.ArrayHeaderSize
+ for za0001 := range z.Receivers {
+ if z.Receivers[za0001] == nil {
s += hsp.NilSize
} else {
- s += z.GasAmounts[za0001].Msgsize()
- }
- }
- s += 9 + z.LowBlock.Msgsize() + 10 + z.HighBlock.Msgsize() + 10 + hsp.Int32Size + 11 + hsp.Int32Size + 11 + z.DatabaseID.Msgsize()
- return
-}
-
-// MarshalHash marshals for hash
-func (z *BillingResponse) MarshalHash() (o []byte, err error) {
- var b []byte
- o = hsp.Require(b, z.Msgsize())
- // map header, size 4
- o = append(o, 0x84, 0x84)
- if z.Signee == nil {
- o = hsp.AppendNil(o)
- } else {
- if oTemp, err := z.Signee.MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
- }
- o = append(o, 0x84)
- if z.Signature == nil {
- o = hsp.AppendNil(o)
- } else {
- if oTemp, err := z.Signature.MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
+ s += z.Receivers[za0001].Msgsize()
}
}
- o = append(o, 0x84)
- if oTemp, err := z.RequestHash.MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
- o = append(o, 0x84)
- if oTemp, err := z.AccountAddress.MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
- return
-}
-
-// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
-func (z *BillingResponse) Msgsize() (s int) {
- s = 1 + 7
- if z.Signee == nil {
- s += hsp.NilSize
- } else {
- s += z.Signee.Msgsize()
- }
- s += 10
- if z.Signature == nil {
- s += hsp.NilSize
- } else {
- s += z.Signature.Msgsize()
- }
- s += 12 + z.RequestHash.Msgsize() + 15 + z.AccountAddress.Msgsize()
+ s += 5 + hsp.ArrayHeaderSize + (len(z.Fees) * (hsp.Uint64Size)) + 8 + hsp.ArrayHeaderSize + (len(z.Rewards) * (hsp.Uint64Size)) + 6 + z.Nonce.Msgsize() + 9 + z.Producer.Msgsize()
return
}
diff --git a/blockproducer/types/billing_gen_test.go b/blockproducer/types/billing_gen_test.go
index 1ad0c1426..845a15213 100644
--- a/blockproducer/types/billing_gen_test.go
+++ b/blockproducer/types/billing_gen_test.go
@@ -9,8 +9,8 @@ import (
"testing"
)
-func TestMarshalHashBillingRequest(t *testing.T) {
- v := BillingRequest{}
+func TestMarshalHashBilling(t *testing.T) {
+ v := Billing{}
binary.Read(rand.Reader, binary.BigEndian, &v)
bts1, err := v.MarshalHash()
if err != nil {
@@ -25,8 +25,8 @@ func TestMarshalHashBillingRequest(t *testing.T) {
}
}
-func BenchmarkMarshalHashBillingRequest(b *testing.B) {
- v := BillingRequest{}
+func BenchmarkMarshalHashBilling(b *testing.B) {
+ v := Billing{}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
@@ -34,8 +34,8 @@ func BenchmarkMarshalHashBillingRequest(b *testing.B) {
}
}
-func BenchmarkAppendMsgBillingRequest(b *testing.B) {
- v := BillingRequest{}
+func BenchmarkAppendMsgBilling(b *testing.B) {
+ v := Billing{}
bts := make([]byte, 0, v.Msgsize())
bts, _ = v.MarshalHash()
b.SetBytes(int64(len(bts)))
@@ -46,8 +46,8 @@ func BenchmarkAppendMsgBillingRequest(b *testing.B) {
}
}
-func TestMarshalHashBillingRequestHeader(t *testing.T) {
- v := BillingRequestHeader{}
+func TestMarshalHashBillingHeader(t *testing.T) {
+ v := BillingHeader{}
binary.Read(rand.Reader, binary.BigEndian, &v)
bts1, err := v.MarshalHash()
if err != nil {
@@ -62,8 +62,8 @@ func TestMarshalHashBillingRequestHeader(t *testing.T) {
}
}
-func BenchmarkMarshalHashBillingRequestHeader(b *testing.B) {
- v := BillingRequestHeader{}
+func BenchmarkMarshalHashBillingHeader(b *testing.B) {
+ v := BillingHeader{}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
@@ -71,45 +71,8 @@ func BenchmarkMarshalHashBillingRequestHeader(b *testing.B) {
}
}
-func BenchmarkAppendMsgBillingRequestHeader(b *testing.B) {
- v := BillingRequestHeader{}
- bts := make([]byte, 0, v.Msgsize())
- bts, _ = v.MarshalHash()
- b.SetBytes(int64(len(bts)))
- b.ReportAllocs()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- bts, _ = v.MarshalHash()
- }
-}
-
-func TestMarshalHashBillingResponse(t *testing.T) {
- v := BillingResponse{}
- binary.Read(rand.Reader, binary.BigEndian, &v)
- bts1, err := v.MarshalHash()
- if err != nil {
- t.Fatal(err)
- }
- bts2, err := v.MarshalHash()
- if err != nil {
- t.Fatal(err)
- }
- if !bytes.Equal(bts1, bts2) {
- t.Fatal("hash not stable")
- }
-}
-
-func BenchmarkMarshalHashBillingResponse(b *testing.B) {
- v := BillingResponse{}
- b.ReportAllocs()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- v.MarshalHash()
- }
-}
-
-func BenchmarkAppendMsgBillingResponse(b *testing.B) {
- v := BillingResponse{}
+func BenchmarkAppendMsgBillingHeader(b *testing.B) {
+ v := BillingHeader{}
bts := make([]byte, 0, v.Msgsize())
bts, _ = v.MarshalHash()
b.SetBytes(int64(len(bts)))
diff --git a/blockproducer/types/billing_request.go b/blockproducer/types/billing_request.go
new file mode 100644
index 000000000..14d96c1b9
--- /dev/null
+++ b/blockproducer/types/billing_request.go
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2018 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 types
+
+import (
+ "reflect"
+
+ "github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
+ "github.com/CovenantSQL/CovenantSQL/crypto/hash"
+ "github.com/CovenantSQL/CovenantSQL/proto"
+)
+
+//go:generate hsp
+
+// BillingRequestHeader includes contents that need to be signed. Billing blocks should be within
+// height range [low, high] (inclusive).
+type BillingRequestHeader struct {
+ DatabaseID proto.DatabaseID
+ // sqlchain block hash and its height
+ LowBlock hash.Hash
+ LowHeight int32
+ HighBlock hash.Hash
+ HighHeight int32
+ GasAmounts []*proto.AddrAndGas
+}
+
+// BillingRequest defines periodically Billing sync.
+type BillingRequest struct {
+ Header BillingRequestHeader
+ RequestHash hash.Hash
+ Signees []*asymmetric.PublicKey
+ Signatures []*asymmetric.Signature
+}
+
+// PackRequestHeader computes the hash of header.
+func (br *BillingRequest) PackRequestHeader() (h *hash.Hash, err error) {
+ var enc []byte
+ if enc, err = br.Header.MarshalHash(); err != nil {
+ return
+ }
+
+ br.RequestHash = hash.THashH(enc)
+ h = &br.RequestHash
+ return
+}
+
+// SignRequestHeader first computes the hash of BillingRequestHeader, then signs the request.
+func (br *BillingRequest) SignRequestHeader(signer *asymmetric.PrivateKey, calcHash bool) (
+ signee *asymmetric.PublicKey, signature *asymmetric.Signature, err error) {
+ if calcHash {
+ if _, err = br.PackRequestHeader(); err != nil {
+ return
+ }
+ }
+
+ if signature, err = signer.Sign(br.RequestHash[:]); err == nil {
+ // append to current signatures
+ signee = signer.PubKey()
+ br.Signees = append(br.Signees, signee)
+ br.Signatures = append(br.Signatures, signature)
+ }
+
+ return
+}
+
+// AddSignature add existing signature to BillingRequest, requires the structure to be packed first.
+func (br *BillingRequest) AddSignature(
+ signee *asymmetric.PublicKey, signature *asymmetric.Signature, calcHash bool) (err error) {
+ if calcHash {
+ if _, err = br.PackRequestHeader(); err != nil {
+ return
+ }
+ }
+
+ if !signature.Verify(br.RequestHash[:], signee) {
+ err = ErrSignVerification
+ return
+ }
+
+ // append
+ br.Signees = append(br.Signees, signee)
+ br.Signatures = append(br.Signatures, signature)
+
+ return
+}
+
+// VerifySignatures verify existing signatures.
+func (br *BillingRequest) VerifySignatures() (err error) {
+ if len(br.Signees) != len(br.Signatures) {
+ return ErrSignVerification
+ }
+
+ var enc []byte
+ if enc, err = br.Header.MarshalHash(); err != nil {
+ return
+ }
+
+ h := hash.THashH(enc)
+ if !br.RequestHash.IsEqual(&h) {
+ return ErrSignVerification
+ }
+
+ if len(br.Signees) == 0 {
+ return
+ }
+
+ for idx, signee := range br.Signees {
+ if !br.Signatures[idx].Verify(br.RequestHash[:], signee) {
+ return ErrSignVerification
+ }
+ }
+
+ return
+}
+
+// Compare returns if two billing records are identical.
+func (br *BillingRequest) Compare(r *BillingRequest) (err error) {
+ if !br.Header.LowBlock.IsEqual(&r.Header.LowBlock) ||
+ !br.Header.HighBlock.IsEqual(&br.Header.HighBlock) {
+ err = ErrBillingNotMatch
+ return
+ }
+
+ reqMap := make(map[proto.AccountAddress]*proto.AddrAndGas)
+ locMap := make(map[proto.AccountAddress]*proto.AddrAndGas)
+
+ for _, v := range br.Header.GasAmounts {
+ reqMap[v.AccountAddress] = v
+ }
+
+ for _, v := range r.Header.GasAmounts {
+ locMap[v.AccountAddress] = v
+ }
+
+ if !reflect.DeepEqual(reqMap, locMap) {
+ err = ErrBillingNotMatch
+ return
+ }
+
+ return
+}
diff --git a/blockproducer/types/billing_request_gen.go b/blockproducer/types/billing_request_gen.go
new file mode 100644
index 000000000..48da8b034
--- /dev/null
+++ b/blockproducer/types/billing_request_gen.go
@@ -0,0 +1,132 @@
+package types
+
+// Code generated by github.com/CovenantSQL/HashStablePack DO NOT EDIT.
+
+import (
+ hsp "github.com/CovenantSQL/HashStablePack/marshalhash"
+)
+
+// MarshalHash marshals for hash
+func (z *BillingRequest) MarshalHash() (o []byte, err error) {
+ var b []byte
+ o = hsp.Require(b, z.Msgsize())
+ // map header, size 4
+ o = append(o, 0x84, 0x84)
+ if oTemp, err := z.Header.MarshalHash(); err != nil {
+ return nil, err
+ } else {
+ o = hsp.AppendBytes(o, oTemp)
+ }
+ o = append(o, 0x84)
+ o = hsp.AppendArrayHeader(o, uint32(len(z.Signees)))
+ for za0001 := range z.Signees {
+ if z.Signees[za0001] == nil {
+ o = hsp.AppendNil(o)
+ } else {
+ if oTemp, err := z.Signees[za0001].MarshalHash(); err != nil {
+ return nil, err
+ } else {
+ o = hsp.AppendBytes(o, oTemp)
+ }
+ }
+ }
+ o = append(o, 0x84)
+ o = hsp.AppendArrayHeader(o, uint32(len(z.Signatures)))
+ for za0002 := range z.Signatures {
+ if z.Signatures[za0002] == nil {
+ o = hsp.AppendNil(o)
+ } else {
+ if oTemp, err := z.Signatures[za0002].MarshalHash(); err != nil {
+ return nil, err
+ } else {
+ o = hsp.AppendBytes(o, oTemp)
+ }
+ }
+ }
+ o = append(o, 0x84)
+ if oTemp, err := z.RequestHash.MarshalHash(); err != nil {
+ return nil, err
+ } else {
+ o = hsp.AppendBytes(o, oTemp)
+ }
+ return
+}
+
+// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
+func (z *BillingRequest) Msgsize() (s int) {
+ s = 1 + 7 + z.Header.Msgsize() + 8 + hsp.ArrayHeaderSize
+ for za0001 := range z.Signees {
+ if z.Signees[za0001] == nil {
+ s += hsp.NilSize
+ } else {
+ s += z.Signees[za0001].Msgsize()
+ }
+ }
+ s += 11 + hsp.ArrayHeaderSize
+ for za0002 := range z.Signatures {
+ if z.Signatures[za0002] == nil {
+ s += hsp.NilSize
+ } else {
+ s += z.Signatures[za0002].Msgsize()
+ }
+ }
+ s += 12 + z.RequestHash.Msgsize()
+ return
+}
+
+// MarshalHash marshals for hash
+func (z *BillingRequestHeader) MarshalHash() (o []byte, err error) {
+ var b []byte
+ o = hsp.Require(b, z.Msgsize())
+ // map header, size 6
+ o = append(o, 0x86, 0x86)
+ o = hsp.AppendArrayHeader(o, uint32(len(z.GasAmounts)))
+ for za0001 := range z.GasAmounts {
+ if z.GasAmounts[za0001] == nil {
+ o = hsp.AppendNil(o)
+ } else {
+ if oTemp, err := z.GasAmounts[za0001].MarshalHash(); err != nil {
+ return nil, err
+ } else {
+ o = hsp.AppendBytes(o, oTemp)
+ }
+ }
+ }
+ o = append(o, 0x86)
+ if oTemp, err := z.LowBlock.MarshalHash(); err != nil {
+ return nil, err
+ } else {
+ o = hsp.AppendBytes(o, oTemp)
+ }
+ o = append(o, 0x86)
+ if oTemp, err := z.HighBlock.MarshalHash(); err != nil {
+ return nil, err
+ } else {
+ o = hsp.AppendBytes(o, oTemp)
+ }
+ o = append(o, 0x86)
+ o = hsp.AppendInt32(o, z.LowHeight)
+ o = append(o, 0x86)
+ o = hsp.AppendInt32(o, z.HighHeight)
+ o = append(o, 0x86)
+ if oTemp, err := z.DatabaseID.MarshalHash(); err != nil {
+ return nil, err
+ } else {
+ o = hsp.AppendBytes(o, oTemp)
+ }
+ return
+}
+
+// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
+func (z *BillingRequestHeader) Msgsize() (s int) {
+ s = 1 + 11 + hsp.ArrayHeaderSize
+ for za0001 := range z.GasAmounts {
+ if z.GasAmounts[za0001] == nil {
+ s += hsp.NilSize
+ } else {
+ s += z.GasAmounts[za0001].Msgsize()
+ }
+ }
+ s += 9 + z.LowBlock.Msgsize() + 10 + z.HighBlock.Msgsize() + 10 + hsp.Int32Size + 11 + hsp.Int32Size + 11 + z.DatabaseID.Msgsize()
+ return
+}
diff --git a/blockproducer/types/txsqlchainbilling_gen_test.go b/blockproducer/types/billing_request_gen_test.go
similarity index 70%
rename from blockproducer/types/txsqlchainbilling_gen_test.go
rename to blockproducer/types/billing_request_gen_test.go
index add50d6f9..d46613c46 100644
--- a/blockproducer/types/txsqlchainbilling_gen_test.go
+++ b/blockproducer/types/billing_request_gen_test.go
@@ -9,8 +9,8 @@ import (
"testing"
)
-func TestMarshalHashTxBilling(t *testing.T) {
- v := TxBilling{}
+func TestMarshalHashBillingRequest(t *testing.T) {
+ v := BillingRequest{}
binary.Read(rand.Reader, binary.BigEndian, &v)
bts1, err := v.MarshalHash()
if err != nil {
@@ -25,8 +25,8 @@ func TestMarshalHashTxBilling(t *testing.T) {
}
}
-func BenchmarkMarshalHashTxBilling(b *testing.B) {
- v := TxBilling{}
+func BenchmarkMarshalHashBillingRequest(b *testing.B) {
+ v := BillingRequest{}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
@@ -34,8 +34,8 @@ func BenchmarkMarshalHashTxBilling(b *testing.B) {
}
}
-func BenchmarkAppendMsgTxBilling(b *testing.B) {
- v := TxBilling{}
+func BenchmarkAppendMsgBillingRequest(b *testing.B) {
+ v := BillingRequest{}
bts := make([]byte, 0, v.Msgsize())
bts, _ = v.MarshalHash()
b.SetBytes(int64(len(bts)))
@@ -46,8 +46,8 @@ func BenchmarkAppendMsgTxBilling(b *testing.B) {
}
}
-func TestMarshalHashTxContent(t *testing.T) {
- v := TxContent{}
+func TestMarshalHashBillingRequestHeader(t *testing.T) {
+ v := BillingRequestHeader{}
binary.Read(rand.Reader, binary.BigEndian, &v)
bts1, err := v.MarshalHash()
if err != nil {
@@ -62,8 +62,8 @@ func TestMarshalHashTxContent(t *testing.T) {
}
}
-func BenchmarkMarshalHashTxContent(b *testing.B) {
- v := TxContent{}
+func BenchmarkMarshalHashBillingRequestHeader(b *testing.B) {
+ v := BillingRequestHeader{}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
@@ -71,8 +71,8 @@ func BenchmarkMarshalHashTxContent(b *testing.B) {
}
}
-func BenchmarkAppendMsgTxContent(b *testing.B) {
- v := TxContent{}
+func BenchmarkAppendMsgBillingRequestHeader(b *testing.B) {
+ v := BillingRequestHeader{}
bts := make([]byte, 0, v.Msgsize())
bts, _ = v.MarshalHash()
b.SetBytes(int64(len(bts)))
diff --git a/blockproducer/types/billing_request_test.go b/blockproducer/types/billing_request_test.go
new file mode 100644
index 000000000..c6d7ee998
--- /dev/null
+++ b/blockproducer/types/billing_request_test.go
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2018 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 types
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
+ "github.com/CovenantSQL/CovenantSQL/crypto/hash"
+ "github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/utils"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
+)
+
+var (
+ peerNum = 32
+)
+
+func TestBillingRequestHeader_MarshalUnmarshalBinary(t *testing.T) {
+ reqHeader := generateRandomBillingRequestHeader()
+ b, err := utils.EncodeMsgPack(reqHeader)
+ if err != nil {
+ t.Fatalf("unexpect error when marshal request header: %v", err)
+ }
+
+ newReqHeader := &BillingRequestHeader{}
+ err = utils.DecodeMsgPack(b.Bytes(), newReqHeader)
+ if err != nil {
+ t.Fatalf("unexpect error when unmashll request header: %v", err)
+ }
+
+ if !reflect.DeepEqual(reqHeader, newReqHeader) {
+ t.Fatalf("values not match:\n\tv0=%+v\n\tv1=%+v", reqHeader, newReqHeader)
+ }
+}
+
+func TestBillingRequest_MarshalUnmarshalBinary(t *testing.T) {
+ req, err := generateRandomBillingRequest()
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+
+ enc, err := utils.EncodeMsgPack(req)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+
+ dec := &BillingRequest{}
+ err = utils.DecodeMsgPack(enc.Bytes(), dec)
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+
+ if !reflect.DeepEqual(req, dec) {
+ log.Debug(req)
+ log.Debug(dec)
+ t.Fatal("values not match")
+ }
+}
+
+func TestBillingRequest_PackRequestHeader(t *testing.T) {
+ req, err := generateRandomBillingRequest()
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+
+ enc, err := req.Header.MarshalHash()
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+
+ h := hash.THashH(enc)
+ if !h.IsEqual(&req.RequestHash) {
+ t.Fatalf("hash not matched: \n\tv1=%v\n\tv2=%v", req.RequestHash, h)
+ }
+}
+
+func TestBillingRequest_SignRequestHeader(t *testing.T) {
+ req, err := generateRandomBillingRequest()
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+
+ enc, err := req.Header.MarshalHash()
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+
+ h := hash.THashH(enc)
+ if !h.IsEqual(&req.RequestHash) {
+ t.Fatalf("hash not matched: \n\tv1=%v\n\tv2=%v", req.RequestHash, h)
+ }
+
+ for i, sign := range req.Signatures {
+ if !sign.Verify(req.RequestHash[:], req.Signees[i]) {
+
+ t.Fatalf("signature cannot match the hash and public key: %v", req)
+ }
+ }
+
+ priv, pub, err := asymmetric.GenSecp256k1KeyPair()
+ _, sign, err := req.SignRequestHeader(priv, false)
+ if err != nil || !sign.Verify(req.RequestHash[:], pub) {
+ t.Fatalf("signature cannot match the hash and public key: %v", req)
+ }
+}
+
+func TestBillingRequest_SignRequestHeader2(t *testing.T) {
+ header := generateRandomBillingRequestHeader()
+ req := &BillingRequest{
+ Header: *header,
+ }
+
+ priv, _, err := asymmetric.GenSecp256k1KeyPair()
+ signee, sign, err := req.SignRequestHeader(priv, true)
+ if err != nil || !sign.Verify(req.RequestHash[:], signee) {
+ t.Fatalf("signature cannot match the hash and public key: %v", req)
+ }
+}
+
+func TestBillingRequest_AddSignature(t *testing.T) {
+ header := generateRandomBillingRequestHeader()
+ req := &BillingRequest{
+ Header: *header,
+ }
+
+ priv, _, err := asymmetric.GenSecp256k1KeyPair()
+ signee, sign, err := req.SignRequestHeader(priv, true)
+ if err != nil || !sign.Verify(req.RequestHash[:], signee) {
+ t.Fatalf("signature cannot match the hash and public key, req: %v, err: %v", req, err)
+ }
+
+ // clear previous signees and signatures
+ req.Signees = req.Signees[:0]
+ req.Signatures = req.Signatures[:0]
+
+ if err := req.AddSignature(signee, sign, false); err != nil {
+ t.Fatalf("add signature failed, req: %v, err: %v", req, err)
+ }
+}
+
+func TestBillingRequest_AddSignature2(t *testing.T) {
+ header := generateRandomBillingRequestHeader()
+ req := &BillingRequest{
+ Header: *header,
+ }
+
+ priv, _, err := asymmetric.GenSecp256k1KeyPair()
+ signee, sign, err := req.SignRequestHeader(priv, true)
+ if err != nil || !sign.Verify(req.RequestHash[:], signee) {
+ t.Fatalf("signature cannot match the hash and public key, req: %v, err: %v", req, err)
+ }
+
+ // clear previous signees and signatures
+ req.RequestHash = hash.Hash{}
+ req.Signees = req.Signees[:0]
+ req.Signatures = req.Signatures[:0]
+
+ if err := req.AddSignature(signee, sign, true); err != nil {
+ t.Fatalf("add signature failed, req: %v, err: %v", req, err)
+ }
+}
+
+func TestBillingRequest_AddSignature3(t *testing.T) {
+ header := generateRandomBillingRequestHeader()
+ req := &BillingRequest{
+ Header: *header,
+ }
+
+ priv, _, err := asymmetric.GenSecp256k1KeyPair()
+ signee, sign, err := req.SignRequestHeader(priv, true)
+ if err != nil || !sign.Verify(req.RequestHash[:], signee) {
+ t.Fatalf("signature cannot match the hash and public key, req: %v, err: %v", req, err)
+ }
+
+ // clear previous signees and signatures
+ req.RequestHash = hash.Hash{}
+ req.Signees = req.Signees[:0]
+ req.Signatures = req.Signatures[:0]
+
+ _, signee, _ = asymmetric.GenSecp256k1KeyPair()
+ if err := req.AddSignature(signee, sign, true); err != ErrSignVerification {
+ t.Fatalf("add signature should failed, req: %v, err: %v", req, err)
+ }
+}
+
+func TestBillingRequest_VerifySignatures(t *testing.T) {
+ header := generateRandomBillingRequestHeader()
+ req := &BillingRequest{
+ Header: *header,
+ }
+
+ addSignature := func(calcHash bool) {
+ priv, _, err := asymmetric.GenSecp256k1KeyPair()
+ _, _, err = req.SignRequestHeader(priv, calcHash)
+ if err != nil {
+ t.Fatalf("sign request failed, req: %v, err: %v", req, err)
+ }
+ }
+
+ // add 3 signatures
+ addSignature(true)
+ addSignature(false)
+ addSignature(false)
+
+ if err := req.VerifySignatures(); err != nil {
+ t.Fatalf("verify signature failed, req: %v, err: %v", req, err)
+ }
+}
+
+func TestBillingRequest_VerifySignatures2(t *testing.T) {
+ header := generateRandomBillingRequestHeader()
+ req := &BillingRequest{
+ Header: *header,
+ }
+
+ addSignature := func(calcHash bool) {
+ priv, _, err := asymmetric.GenSecp256k1KeyPair()
+ _, _, err = req.SignRequestHeader(priv, calcHash)
+ if err != nil {
+ t.Fatalf("sign request failed, req: %v, err: %v", req, err)
+ }
+ }
+
+ // add 3 signatures
+ addSignature(true)
+ addSignature(false)
+ addSignature(false)
+
+ // length invalidation
+ req.Signees = req.Signees[:0]
+
+ if err := req.VerifySignatures(); err != ErrSignVerification {
+ t.Fatalf("verify should be failed, req: %v, err: %v", req, err)
+ }
+}
+
+func TestBillingRequest_VerifySignatures3(t *testing.T) {
+ header := generateRandomBillingRequestHeader()
+ req := &BillingRequest{
+ Header: *header,
+ }
+
+ addSignature := func(calcHash bool) {
+ priv, _, err := asymmetric.GenSecp256k1KeyPair()
+ _, _, err = req.SignRequestHeader(priv, calcHash)
+ if err != nil {
+ t.Fatalf("sign request failed, req: %v, err: %v", req, err)
+ }
+ }
+
+ // add 3 signatures
+ addSignature(true)
+ addSignature(false)
+ addSignature(false)
+
+ // length invalidation
+ req.RequestHash = hash.Hash{}
+
+ if err := req.VerifySignatures(); err != ErrSignVerification {
+ t.Fatalf("verify should be failed, req: %v, err: %v", req, err)
+ }
+}
+
+func TestBillingRequest_VerifySignatures4(t *testing.T) {
+ header := generateRandomBillingRequestHeader()
+ req := &BillingRequest{
+ Header: *header,
+ }
+
+ addSignature := func(calcHash bool) {
+ priv, _, err := asymmetric.GenSecp256k1KeyPair()
+ _, _, err = req.SignRequestHeader(priv, calcHash)
+ if err != nil {
+ t.Fatalf("sign request failed, req: %v, err: %v", req, err)
+ }
+ }
+
+ // add 3 signatures
+ addSignature(true)
+ addSignature(false)
+ addSignature(false)
+
+ // length invalidation
+ _, req.Signees[0], _ = asymmetric.GenSecp256k1KeyPair()
+
+ if err := req.VerifySignatures(); err == nil || err != ErrSignVerification {
+ t.Fatalf("verify should be failed, req: %v, err: %v", req, err)
+ }
+}
+
+func TestBillingRequest_Compare(t *testing.T) {
+ req, _ := generateRandomBillingRequest()
+
+ if err := req.Compare(req); err != nil {
+ t.Fatalf("compare failed, req: %v, err: %v", req, err)
+ }
+
+ var req2 BillingRequest
+ req2 = *req
+
+ req2.Header.LowBlock = hash.Hash{}
+
+ if err := req.Compare(&req2); err != ErrBillingNotMatch {
+ t.Fatalf("compare should be failed, req: %v, req2: %v, err: %v", req, req2, err)
+ }
+}
+
+func TestBillingRequest_Compare2(t *testing.T) {
+ req, _ := generateRandomBillingRequest()
+ var req2 BillingRequest
+ req2 = *req
+
+ var gasAmount proto.AddrAndGas
+ gasAmount = *req.Header.GasAmounts[0]
+ gasAmount.GasAmount += 10
+ req2.Header.GasAmounts = nil
+ req2.Header.GasAmounts = append(req2.Header.GasAmounts, &gasAmount)
+ req2.Header.GasAmounts = append(req2.Header.GasAmounts, req.Header.GasAmounts[1:]...)
+
+ if err := req.Compare(&req2); err != ErrBillingNotMatch {
+ t.Fatalf("compare should be failed, req: %v, req2: %v, err: %v", req, req2, err)
+ }
+}
diff --git a/blockproducer/types/billing_test.go b/blockproducer/types/billing_test.go
index 9f3f49446..bafa32c10 100644
--- a/blockproducer/types/billing_test.go
+++ b/blockproducer/types/billing_test.go
@@ -20,124 +20,104 @@ import (
"reflect"
"testing"
- "github.com/CovenantSQL/CovenantSQL/utils"
- "github.com/CovenantSQL/CovenantSQL/utils/log"
-
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
+ "github.com/CovenantSQL/CovenantSQL/utils"
)
-var (
- peerNum uint32 = 32
-)
-
-func TestBillingRequestHeader_MarshalUnmarshalBinary(t *testing.T) {
- reqHeader := generateRandomBillingRequestHeader()
- b, err := utils.EncodeMsgPack(reqHeader)
+func TestBillingHeader_MarshalUnmarshalBinary(t *testing.T) {
+ tc, err := generateRandomBillingHeader()
if err != nil {
- t.Fatalf("unexpect error when marshal request header: %v", err)
+ t.Fatalf("Unexpeted error: %v", err)
}
- newReqHeader := &BillingRequestHeader{}
- err = utils.DecodeMsgPack(b.Bytes(), newReqHeader)
+ enc, err := utils.EncodeMsgPack(tc)
if err != nil {
- t.Fatalf("unexpect error when unmashll request header: %v", err)
+ t.Fatalf("Unexpeted error: %v", err)
}
- if !reflect.DeepEqual(reqHeader, newReqHeader) {
- t.Fatalf("values not match:\n\tv0=%+v\n\tv1=%+v", reqHeader, newReqHeader)
- }
-}
-
-func TestBillingRequest_MarshalUnmarshalBinary(t *testing.T) {
- req, err := generateRandomBillingRequest()
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
-
- enc, err := utils.EncodeMsgPack(req)
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
-
- dec := &BillingRequest{}
+ dec := &BillingHeader{}
err = utils.DecodeMsgPack(enc.Bytes(), dec)
if err != nil {
- t.Fatalf("unexpected error: %v", err)
+ t.Fatalf("Unexpeted error: %v", err)
}
- if !reflect.DeepEqual(req, dec) {
- log.Debug(req)
- log.Debug(dec)
- t.Fatal("values not match")
+ if tc.Nonce != dec.Nonce {
+ t.Fatalf("Value not match: \n\tv1=%v\n\tv2=%v", tc.Nonce, tc.Nonce)
}
-}
-
-func TestBillingRequest_PackRequestHeader(t *testing.T) {
- req, err := generateRandomBillingRequest()
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
+ if tc.BillingRequest.RequestHash != dec.BillingRequest.RequestHash {
+ t.Fatalf("Value not match: \n\tv1=%v\n\tv2=%v", tc.BillingRequest.RequestHash, tc.BillingRequest.RequestHash)
}
-
- enc, err := req.Header.MarshalHash()
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
+ if !tc.BillingRequest.Signatures[0].IsEqual(dec.BillingRequest.Signatures[0]) {
+ t.Fatalf("Value not match: \n\tv1=%v\n\tv2=%v", tc.BillingRequest.Signatures[0], dec.BillingRequest.Signatures[0])
}
-
- h := hash.THashH(enc)
- if !h.IsEqual(&req.RequestHash) {
- t.Fatalf("hash not matched: \n\tv1=%v\n\tv2=%v", req.RequestHash, h)
+ for i := range tc.Receivers {
+ if !reflect.DeepEqual(tc.Receivers[i], dec.Receivers[i]) {
+ t.Fatalf("Value not match: \n\ttc.Receivers[%d]=%v\n\tReceive[%d]=%v", i, i, tc.Receivers[i], tc.Receivers[0])
+ }
+ if tc.Rewards[i] != dec.Rewards[i] {
+ t.Fatalf("Value not match: \n\ttc.Rewards[%d]=%v\n\tRewards[%d]=%v", i, i, tc.Rewards[i], tc.Rewards[0])
+ }
+ if tc.Fees[i] != dec.Fees[i] {
+ t.Fatalf("Value not match: \n\ttc.Fees[%d]=%v\n\tFees[%d]=%v", i, i, tc.Fees[i], tc.Fees[0])
+ }
}
}
-func TestBillingRequest_SignRequestHeader(t *testing.T) {
- req, err := generateRandomBillingRequest()
+func TestBilling_SerializeDeserialize(t *testing.T) {
+ tb, err := generateRandomBilling()
if err != nil {
- t.Fatalf("unexpected error: %v", err)
+ t.Fatalf("Unexpeted error: %v", err)
}
- enc, err := req.Header.MarshalHash()
+ enc, err := utils.EncodeMsgPack(tb)
if err != nil {
- t.Fatalf("unexpected error: %v", err)
+ t.Fatalf("Unexpeted error: %v", err)
}
- h := hash.THashH(enc)
- if !h.IsEqual(&req.RequestHash) {
- t.Fatalf("hash not matched: \n\tv1=%v\n\tv2=%v", req.RequestHash, h)
+ dec := Billing{}
+ err = utils.DecodeMsgPack(enc.Bytes(), &dec)
+ if err != nil {
+ t.Fatalf("Unexpeted error: %v", err)
}
- for i, sign := range req.Signatures {
- if !sign.Verify(req.RequestHash[:], req.Signees[i]) {
-
- t.Fatalf("signature cannot match the hash and public key: %v", req)
- }
+ if !tb.Signature.IsEqual(dec.Signature) {
+ t.Fatalf("Value not match: \n\tv1=%v\n\tv2=%v", tb.Signature, tb.Signature)
}
-
- priv, pub, err := asymmetric.GenSecp256k1KeyPair()
- sign, err := req.SignRequestHeader(priv)
- if !sign.Verify(req.RequestHash[:], pub) {
- t.Fatalf("signature cannot match the hash and public key: %v", req)
+ if !tb.Signee.IsEqual(dec.Signee) {
+ t.Fatalf("Value not match: \n\tv1=%v\n\tv2=%v", tb.Signee, tb.Signee)
}
- sign, err = req.SignRequestHeader(priv)
- if !sign.Verify(req.RequestHash[:], pub) {
- t.Fatalf("signature cannot match the hash and public key: %v", req)
+ if !tb.Hash.IsEqual(&dec.Hash) {
+ t.Fatalf("Value not match: \n\tv1=%v\n\tv2=%v", tb.Hash, tb.Hash)
}
}
-func TestBillingResponse_MarshalUnmarshalBinary(t *testing.T) {
- resp, err := generateRandomBillingResponse()
+func TestBilling_PackAndSignTx(t *testing.T) {
+ tb, err := generateRandomBilling()
if err != nil {
- t.Fatalf("unexpected error: %v", err)
+ t.Fatalf("Unexpeted error: %v", err)
}
- enc, err := utils.EncodeMsgPack(resp)
+ priv, _, err := asymmetric.GenSecp256k1KeyPair()
+ if err != nil {
+ t.Fatalf("Unexpeted error: %v", err)
+ }
+ tb.Sign(priv)
+ enc, err := tb.BillingHeader.MarshalHash()
if err != nil {
- t.Fatalf("unexpected error: %v", err)
+ t.Fatalf("Unexpeted error: %v", err)
+ }
+ h := hash.THashH(enc[:])
+ sign, err := priv.Sign(h[:])
+ if err != nil {
+ t.Fatalf("Unexpeted error: %v", err)
+ }
+ if !sign.IsEqual(tb.Signature) {
+ t.Fatalf("Value not match: \n\tv1=%v\n\tv2=%v", sign, tb.Signature)
}
- dec := &BillingResponse{}
- err = utils.DecodeMsgPack(enc.Bytes(), dec)
+ err = tb.Verify()
if err != nil {
- t.Fatalf("unexpected error: %v", err)
+ t.Fatalf("Verify signature failed: %v", err)
}
}
diff --git a/blockproducer/types/block.go b/blockproducer/types/block.go
index 515f6c595..a2f88d642 100644
--- a/blockproducer/types/block.go
+++ b/blockproducer/types/block.go
@@ -17,8 +17,6 @@
package types
import (
- "bytes"
- "reflect"
"time"
pi "github.com/CovenantSQL/CovenantSQL/blockproducer/interfaces"
@@ -26,7 +24,6 @@ import (
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
"github.com/CovenantSQL/CovenantSQL/merkle"
"github.com/CovenantSQL/CovenantSQL/proto"
- "github.com/ugorji/go/codec"
)
//go:generate hsp
@@ -60,22 +57,18 @@ func (s *SignedHeader) Verify() error {
// Block defines the main chain block.
type Block struct {
SignedHeader SignedHeader
- TxBillings []*TxBilling
Transactions []pi.Transaction
}
-// GetTxHashes returns all hashes of tx in block.{TxBillings, ...}
+// GetTxHashes returns all hashes of tx in block.{Billings, ...}
func (b *Block) GetTxHashes() []*hash.Hash {
// TODO(lambda): when you add new tx type, you need to put new tx's hash in the slice
- // get hashes in block.TxBillings
- bl := len(b.TxBillings)
- hs := make([]*hash.Hash, len(b.TxBillings)+len(b.Transactions))
- for i, v := range b.TxBillings {
- hs[i] = v.TxHash
- }
+ // get hashes in block.Transactions
+ hs := make([]*hash.Hash, len(b.Transactions))
+
for i, v := range b.Transactions {
h := v.GetHash()
- hs[bl+i] = &h
+ hs[i] = &h
}
return hs
}
@@ -102,64 +95,6 @@ func (b *Block) PackAndSignBlock(signer *asymmetric.PrivateKey) error {
return nil
}
-func enumType(t pi.TransactionType) (i pi.Transaction) {
- switch t {
- case pi.TransactionTypeBilling:
- i = (*TxBilling)(nil)
- case pi.TransactionTypeTransfer:
- i = (*Transfer)(nil)
- case pi.TransactionTypeBaseAccount:
- i = (*BaseAccount)(nil)
- case pi.TransactionTypeCreataDatabase:
- i = (*CreateDatabase)(nil)
- }
- return
-}
-
-// Serialize converts block to bytes.
-func (b *Block) Serialize() ([]byte, error) {
- buf := bytes.NewBuffer(nil)
- hd := codec.MsgpackHandle{
- WriteExt: true,
- RawToString: true,
- }
- enc := codec.NewEncoder(buf, &hd)
- err := enc.Encode(b)
- return buf.Bytes(), err
-}
-
-// Deserialize converts bytes to block.
-func (b *Block) Deserialize(buf []byte) error {
- r := bytes.NewBuffer(buf)
- hd := codec.MsgpackHandle{
- WriteExt: true,
- RawToString: true,
- }
-
- for i := pi.TransactionType(0); i < pi.TransactionTypeNumber; i++ {
- err := hd.Intf2Impl(
- reflect.TypeOf((*pi.Transaction)(nil)).Elem(),
- reflect.TypeOf(enumType(i)),
- )
- if err != nil {
- return err
- }
- }
-
- dec := codec.NewDecoder(r, &hd)
- return dec.Decode(b)
-}
-
-// PushTx pushes txes into block.
-func (b *Block) PushTx(tx *TxBilling) {
- if b.TxBillings != nil {
- // TODO(lambda): set appropriate capacity.
- b.TxBillings = make([]*TxBilling, 0, 100)
- }
-
- b.TxBillings = append(b.TxBillings, tx)
-}
-
// Verify verifies whether the block is valid.
func (b *Block) Verify() error {
hs := b.GetTxHashes()
@@ -190,3 +125,13 @@ func (b *Block) Timestamp() time.Time {
func (b *Block) Producer() proto.AccountAddress {
return b.SignedHeader.Producer
}
+
+// ParentHash returns the parent hash field of the block header.
+func (b *Block) ParentHash() *hash.Hash {
+ return &b.SignedHeader.ParentHash
+}
+
+// BlockHash returns the parent hash field of the block header.
+func (b *Block) BlockHash() *hash.Hash {
+ return &b.SignedHeader.BlockHash
+}
diff --git a/blockproducer/types/block_gen.go b/blockproducer/types/block_gen.go
index 5398974ce..1a0814c1c 100644
--- a/blockproducer/types/block_gen.go
+++ b/blockproducer/types/block_gen.go
@@ -18,16 +18,12 @@ func (z *Block) MarshalHash() (o []byte, err error) {
o = hsp.AppendBytes(o, oTemp)
}
o = append(o, 0x82)
- o = hsp.AppendArrayHeader(o, uint32(len(z.TxBillings)))
- for za0001 := range z.TxBillings {
- if z.TxBillings[za0001] == nil {
- o = hsp.AppendNil(o)
+ o = hsp.AppendArrayHeader(o, uint32(len(z.Transactions)))
+ for za0001 := range z.Transactions {
+ if oTemp, err := z.Transactions[za0001].MarshalHash(); err != nil {
+ return nil, err
} else {
- if oTemp, err := z.TxBillings[za0001].MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
+ o = hsp.AppendBytes(o, oTemp)
}
}
return
@@ -35,13 +31,9 @@ func (z *Block) MarshalHash() (o []byte, err error) {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *Block) Msgsize() (s int) {
- s = 1 + 13 + z.SignedHeader.Msgsize() + 11 + hsp.ArrayHeaderSize
- for za0001 := range z.TxBillings {
- if z.TxBillings[za0001] == nil {
- s += hsp.NilSize
- } else {
- s += z.TxBillings[za0001].Msgsize()
- }
+ s = 1 + 13 + z.SignedHeader.Msgsize() + 13 + hsp.ArrayHeaderSize
+ for za0001 := range z.Transactions {
+ s += z.Transactions[za0001].Msgsize()
}
return
}
diff --git a/blockproducer/types/block_test.go b/blockproducer/types/block_test.go
index e2c42bf0d..403123ea6 100644
--- a/blockproducer/types/block_test.go
+++ b/blockproducer/types/block_test.go
@@ -17,14 +17,12 @@
package types
import (
+ "bytes"
"encoding"
"reflect"
"testing"
- "bytes"
-
"github.com/CovenantSQL/CovenantSQL/utils"
- . "github.com/smartystreets/goconvey/convey"
)
func TestHeader_MarshalUnmarshalBinary(t *testing.T) {
@@ -86,14 +84,13 @@ func TestBlock_MarshalUnmarshalBinary(t *testing.T) {
t.Log("dec hash BinaryMashaler interface")
}
- enc, err := block.Serialize()
+ enc, err := utils.EncodeMsgPack(block)
if err != nil {
t.Fatalf("Failed to mashal binary: %v", err)
}
dec := &Block{}
-
- err = dec.Deserialize(enc)
+ err = utils.DecodeMsgPack(enc.Bytes(), dec)
if err != nil {
t.Fatalf("Failed to unmashal binary: %v", err)
}
@@ -109,10 +106,6 @@ func TestBlock_MarshalUnmarshalBinary(t *testing.T) {
if !bytes.Equal(bts1, bts2) {
t.Fatal("hash not stable")
}
-
- if !reflect.DeepEqual(block, dec) {
- t.Fatalf("value not match")
- }
}
func TestBlock_PackAndSignBlock(t *testing.T) {
@@ -132,27 +125,13 @@ func TestBlock_PackAndSignBlock(t *testing.T) {
t.Fatalf("Unexpected error: %v", err)
}
- tb, err := generateRandomTxBilling()
+ tb, err := generateRandomBilling()
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
- block.PushTx(tb)
+ block.Transactions = append(block.Transactions, tb)
err = block.Verify()
if err != ErrMerkleRootVerification {
t.Fatalf("Unexpected error: %v", err)
}
}
-
-func TestOther_MarshalHash(t *testing.T) {
- Convey("marshal hash", t, func() {
- tm := TxType(1)
- s, err := tm.MarshalHash()
- So(err, ShouldBeNil)
- So(s, ShouldNotBeEmpty)
-
- So(tm.String(), ShouldResemble, "TxUnknown")
-
- tm = TxType(0)
- So(tm.String(), ShouldResemble, "TxBilling")
- })
-}
diff --git a/blockproducer/types/common.go b/blockproducer/types/common.go
index c865cd63f..024cc9646 100644
--- a/blockproducer/types/common.go
+++ b/blockproducer/types/common.go
@@ -17,26 +17,10 @@
package types
import (
- "bytes"
-
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
- "github.com/CovenantSQL/CovenantSQL/utils"
)
-func serialize(i interface{}) (s []byte, err error) {
- var enc *bytes.Buffer
- if enc, err = utils.EncodeMsgPack(i); err != nil {
- return
- }
- s = enc.Bytes()
- return
-}
-
-func deserialize(enc []byte, o interface{}) error {
- return utils.DecodeMsgPack(enc, o)
-}
-
type marshalHasher interface {
MarshalHash() ([]byte, error)
}
diff --git a/blockproducer/types/createdb.go b/blockproducer/types/createdb.go
index 41e105421..2d5aa00fa 100644
--- a/blockproducer/types/createdb.go
+++ b/blockproducer/types/createdb.go
@@ -43,22 +43,16 @@ func (h *CreateDatabaseHeader) GetAccountNonce() pi.AccountNonce {
// CreateDatabase defines the database creation transaction.
type CreateDatabase struct {
CreateDatabaseHeader
+ pi.TransactionTypeMixin
DefaultHashSignVerifierImpl
}
-// Serialize implements interfaces/Transaction.Serialize.
-func (cd *CreateDatabase) Serialize() ([]byte, error) {
- return serialize(cd)
-}
-
-// Deserialize implements interfaces/Transaction.Deserialize.
-func (cd *CreateDatabase) Deserialize(enc []byte) error {
- return deserialize(enc, cd)
-}
-
-// GetTransactionType implements interfaces/Transaction.GetTransactionType.
-func (cd *CreateDatabase) GetTransactionType() pi.TransactionType {
- return pi.TransactionTypeCreataDatabase
+// NewCreateDatabase returns new instance.
+func NewCreateDatabase(header *CreateDatabaseHeader) *CreateDatabase {
+ return &CreateDatabase{
+ CreateDatabaseHeader: *header,
+ TransactionTypeMixin: *pi.NewTransactionTypeMixin(pi.TransactionTypeCreateDatabase),
+ }
}
// Sign implements interfaces/Transaction.Sign.
@@ -70,3 +64,7 @@ func (cd *CreateDatabase) Sign(signer *asymmetric.PrivateKey) (err error) {
func (cd *CreateDatabase) Verify() error {
return cd.DefaultHashSignVerifierImpl.Verify(&cd.CreateDatabaseHeader)
}
+
+func init() {
+ pi.RegisterTransaction(pi.TransactionTypeCreateDatabase, (*CreateDatabase)(nil))
+}
diff --git a/blockproducer/types/createdb_gen.go b/blockproducer/types/createdb_gen.go
index 368a8c99a..0b3e6b862 100644
--- a/blockproducer/types/createdb_gen.go
+++ b/blockproducer/types/createdb_gen.go
@@ -10,9 +10,9 @@ import (
func (z *CreateDatabase) MarshalHash() (o []byte, err error) {
var b []byte
o = hsp.Require(b, z.Msgsize())
+ // map header, size 3
// map header, size 2
- // map header, size 2
- o = append(o, 0x82, 0x82, 0x82, 0x82)
+ o = append(o, 0x83, 0x83, 0x82, 0x82)
if oTemp, err := z.CreateDatabaseHeader.Owner.MarshalHash(); err != nil {
return nil, err
} else {
@@ -24,18 +24,24 @@ func (z *CreateDatabase) MarshalHash() (o []byte, err error) {
} else {
o = hsp.AppendBytes(o, oTemp)
}
- o = append(o, 0x82)
+ o = append(o, 0x83)
if oTemp, err := z.DefaultHashSignVerifierImpl.MarshalHash(); err != nil {
return nil, err
} else {
o = hsp.AppendBytes(o, oTemp)
}
+ o = append(o, 0x83)
+ if oTemp, err := z.TransactionTypeMixin.MarshalHash(); err != nil {
+ return nil, err
+ } else {
+ o = hsp.AppendBytes(o, oTemp)
+ }
return
}
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *CreateDatabase) Msgsize() (s int) {
- s = 1 + 21 + 1 + 6 + z.CreateDatabaseHeader.Owner.Msgsize() + 6 + z.CreateDatabaseHeader.Nonce.Msgsize() + 28 + z.DefaultHashSignVerifierImpl.Msgsize()
+ s = 1 + 21 + 1 + 6 + z.CreateDatabaseHeader.Owner.Msgsize() + 6 + z.CreateDatabaseHeader.Nonce.Msgsize() + 28 + z.DefaultHashSignVerifierImpl.Msgsize() + 21 + z.TransactionTypeMixin.Msgsize()
return
}
diff --git a/blockproducer/types/errors.go b/blockproducer/types/errors.go
index 7d856cb81..13d135db1 100644
--- a/blockproducer/types/errors.go
+++ b/blockproducer/types/errors.go
@@ -33,4 +33,7 @@ var (
// ErrNodePublicKeyNotMatch indicates that the public key given with a node does not match the
// one in the key store.
ErrNodePublicKeyNotMatch = errors.New("node publick key doesn't match")
+
+ // ErrBillingNotMatch indicates that the billing request doesn't match the local result.
+ ErrBillingNotMatch = errors.New("billing request doesn't match")
)
diff --git a/blockproducer/types/msgpack_test.go b/blockproducer/types/msgpack_test.go
new file mode 100644
index 000000000..c448c3af6
--- /dev/null
+++ b/blockproducer/types/msgpack_test.go
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2018 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 types
+
+import (
+ "reflect"
+ "testing"
+
+ pi "github.com/CovenantSQL/CovenantSQL/blockproducer/interfaces"
+ "github.com/CovenantSQL/CovenantSQL/utils"
+ . "github.com/smartystreets/goconvey/convey"
+)
+
+type complexStructure struct {
+ Tx pi.Transaction
+ Txs []pi.Transaction
+ Maps map[string]pi.Transaction
+}
+
+func TestEncodeDecodeTransactions(t *testing.T) {
+ Convey("test encode/decode single transaction", t, func() {
+ var t pi.Transaction
+ t = NewBaseAccount(&Account{})
+ buf, err := utils.EncodeMsgPack(t)
+ So(err, ShouldBeNil)
+
+ var out pi.Transaction
+ err = utils.DecodeMsgPack(buf.Bytes(), &out)
+ So(err, ShouldBeNil)
+ So(out, ShouldNotBeNil)
+ So(reflect.TypeOf(out).String(), ShouldContainSubstring, "TransactionWrapper")
+ So(out.GetTransactionType(), ShouldEqual, t.GetTransactionType())
+ })
+ Convey("test encode/decode series of transactions", t, func() {
+ var t []pi.Transaction
+ t = append(t, NewBaseAccount(&Account{}))
+ t = append(t, NewTransfer(&TransferHeader{}))
+ t = append(t, NewBilling(&BillingHeader{}))
+ t = append(t, NewCreateDatabase(&CreateDatabaseHeader{}))
+
+ buf, err := utils.EncodeMsgPack(t)
+ So(err, ShouldBeNil)
+
+ var out []pi.Transaction
+ err = utils.DecodeMsgPack(buf.Bytes(), &out)
+ So(err, ShouldBeNil)
+ So(out, ShouldNotBeNil)
+ So(out, ShouldHaveLength, len(t))
+
+ for i := range t {
+ So(out[i], ShouldNotBeNil)
+ So(out[i].GetTransactionType(), ShouldEqual, t[i].GetTransactionType())
+ So(reflect.TypeOf(out[i]).String(), ShouldContainSubstring, "TransactionWrapper")
+ }
+ })
+ Convey("test encode/decode complex structure containing transactions", t, func() {
+ var t complexStructure
+ t.Tx = NewBaseAccount(&Account{})
+ t.Txs = append(t.Txs, NewBaseAccount(&Account{}))
+ t.Txs = append(t.Txs, NewTransfer(&TransferHeader{}))
+ t.Txs = append(t.Txs, NewBilling(&BillingHeader{}))
+ t.Txs = append(t.Txs, NewCreateDatabase(&CreateDatabaseHeader{}))
+ t.Maps = make(map[string]pi.Transaction)
+ t.Maps["BaseAccount"] = NewBaseAccount(&Account{})
+ t.Maps["Transfer"] = NewTransfer(&TransferHeader{})
+ t.Maps["Billing"] = NewBilling(&BillingHeader{})
+ t.Maps["CreateDatabase"] = NewCreateDatabase(&CreateDatabaseHeader{})
+ buf, err := utils.EncodeMsgPack(t)
+ So(err, ShouldBeNil)
+
+ var out complexStructure
+ err = utils.DecodeMsgPack(buf.Bytes(), &out)
+ So(err, ShouldBeNil)
+ So(out.Tx, ShouldNotBeNil)
+ So(out.Txs, ShouldNotBeNil)
+ So(out.Txs, ShouldHaveLength, len(t.Txs))
+ So(out.Maps, ShouldNotBeNil)
+ So(out.Maps, ShouldHaveLength, len(t.Maps))
+
+ So(out.Tx.GetTransactionType(), ShouldEqual, pi.TransactionTypeBaseAccount)
+ So(reflect.TypeOf(out.Tx).String(), ShouldContainSubstring, "TransactionWrapper")
+
+ for i := range out.Txs {
+ So(out.Txs[i], ShouldNotBeNil)
+ So(out.Txs[i].GetTransactionType(), ShouldEqual, t.Txs[i].GetTransactionType())
+ So(reflect.TypeOf(out.Txs[i]).String(), ShouldContainSubstring, "TransactionWrapper")
+ }
+
+ for k, v := range out.Maps {
+ So(v, ShouldNotBeNil)
+ So(out.Maps[k].GetTransactionType(), ShouldEqual, t.Maps[k].GetTransactionType())
+ So(reflect.TypeOf(out.Maps[k]).String(), ShouldContainSubstring, "TransactionWrapper")
+ }
+ })
+ Convey("test encode wrapper, decode using real type", t, func() {
+ var t pi.Transaction
+ t = pi.WrapTransaction(NewBaseAccount(&Account{}))
+ So(reflect.TypeOf(t).String(), ShouldContainSubstring, "TransactionWrapper")
+ So(t.GetTransactionType(), ShouldEqual, pi.TransactionTypeBaseAccount)
+ buf, err := utils.EncodeMsgPack(t)
+ So(err, ShouldBeNil)
+
+ var out *BaseAccount
+ err = utils.DecodeMsgPack(buf.Bytes(), &out)
+ So(err, ShouldBeNil)
+ So(out, ShouldNotBeNil)
+ So(out.GetTransactionType(), ShouldEqual, pi.TransactionTypeBaseAccount)
+ So(reflect.TypeOf(out).String(), ShouldContainSubstring, "BaseAccount")
+ })
+ Convey("decode invalid data", t, func() {
+ var testTypes = []interface{}{
+ "1",
+ 1,
+ 0.1,
+ []int{},
+ []int{1, 2},
+ []int{1, 2, 3},
+ struct{ A int }{A: 1},
+ struct{ TxType int }{TxType: int(pi.TransactionTypeNumber) + 1},
+ struct{ TxType struct{} }{},
+ struct{}{},
+ }
+
+ for _, val := range testTypes {
+ buf, err := utils.EncodeMsgPack(val)
+ So(err, ShouldBeNil)
+
+ var out pi.Transaction
+ err = utils.DecodeMsgPack(buf.Bytes(), &out)
+ So(err, ShouldNotBeNil)
+ }
+ })
+ Convey("decode wrapper with nil transaction", t, func() {
+ var t pi.Transaction
+ t = pi.WrapTransaction(nil)
+ buf, err := utils.EncodeMsgPack(t)
+ So(err, ShouldBeNil)
+
+ var out pi.Transaction
+ err = utils.DecodeMsgPack(buf.Bytes(), &out)
+ So(err, ShouldBeNil)
+ So(out, ShouldBeNil)
+ })
+}
diff --git a/blockproducer/types/transfer.go b/blockproducer/types/transfer.go
index 62f84b5e9..e9a170fa0 100644
--- a/blockproducer/types/transfer.go
+++ b/blockproducer/types/transfer.go
@@ -17,13 +17,9 @@
package types
import (
- "bytes"
-
pi "github.com/CovenantSQL/CovenantSQL/blockproducer/interfaces"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
- "github.com/CovenantSQL/CovenantSQL/crypto/hash"
"github.com/CovenantSQL/CovenantSQL/proto"
- "github.com/CovenantSQL/CovenantSQL/utils"
)
//go:generate hsp
@@ -38,24 +34,16 @@ type TransferHeader struct {
// Transfer defines the transfer transaction.
type Transfer struct {
TransferHeader
- HeaderHash hash.Hash
- Signee *asymmetric.PublicKey
- Signature *asymmetric.Signature
+ pi.TransactionTypeMixin
+ DefaultHashSignVerifierImpl
}
-// Serialize serializes TxBilling using msgpack.
-func (t *Transfer) Serialize() (b []byte, err error) {
- var enc *bytes.Buffer
- if enc, err = utils.EncodeMsgPack(t); err != nil {
- return
+// NewTransfer returns new instance.
+func NewTransfer(header *TransferHeader) *Transfer {
+ return &Transfer{
+ TransferHeader: *header,
+ TransactionTypeMixin: *pi.NewTransactionTypeMixin(pi.TransactionTypeTransfer),
}
- b = enc.Bytes()
- return
-}
-
-// Deserialize desrializes TxBilling using msgpack.
-func (t *Transfer) Deserialize(enc []byte) error {
- return utils.DecodeMsgPack(enc, t)
}
// GetAccountAddress implements interfaces/Transaction.GetAccountAddress.
@@ -68,42 +56,16 @@ func (t *Transfer) GetAccountNonce() pi.AccountNonce {
return t.Nonce
}
-// GetHash implements interfaces/Transaction.GetHash.
-func (t *Transfer) GetHash() hash.Hash {
- return t.HeaderHash
-}
-
-// GetTransactionType implements interfaces/Transaction.GetTransactionType.
-func (t *Transfer) GetTransactionType() pi.TransactionType {
- return pi.TransactionTypeTransfer
-}
-
// Sign implements interfaces/Transaction.Sign.
func (t *Transfer) Sign(signer *asymmetric.PrivateKey) (err error) {
- var enc []byte
- if enc, err = t.TransferHeader.MarshalHash(); err != nil {
- return
- }
- var h = hash.THashH(enc)
- if t.Signature, err = signer.Sign(h[:]); err != nil {
- return
- }
- t.HeaderHash = h
- t.Signee = signer.PubKey()
- return
+ return t.DefaultHashSignVerifierImpl.Sign(&t.TransferHeader, signer)
}
// Verify implements interfaces/Transaction.Verify.
func (t *Transfer) Verify() (err error) {
- var enc []byte
- if enc, err = t.TransferHeader.MarshalHash(); err != nil {
- return
- } else if h := hash.THashH(enc); !t.HeaderHash.IsEqual(&h) {
- err = ErrSignVerification
- return
- } else if !t.Signature.Verify(h[:], t.Signee) {
- err = ErrSignVerification
- return
- }
- return
+ return t.DefaultHashSignVerifierImpl.Verify(&t.TransferHeader)
+}
+
+func init() {
+ pi.RegisterTransaction(pi.TransactionTypeTransfer, (*Transfer)(nil))
}
diff --git a/blockproducer/types/transfer_gen.go b/blockproducer/types/transfer_gen.go
index 9091a1e62..6d910fa70 100644
--- a/blockproducer/types/transfer_gen.go
+++ b/blockproducer/types/transfer_gen.go
@@ -10,35 +10,21 @@ import (
func (z *Transfer) MarshalHash() (o []byte, err error) {
var b []byte
o = hsp.Require(b, z.Msgsize())
- // map header, size 4
- o = append(o, 0x84, 0x84)
- if z.Signee == nil {
- o = hsp.AppendNil(o)
- } else {
- if oTemp, err := z.Signee.MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
- }
- o = append(o, 0x84)
- if z.Signature == nil {
- o = hsp.AppendNil(o)
+ // map header, size 3
+ o = append(o, 0x83, 0x83)
+ if oTemp, err := z.DefaultHashSignVerifierImpl.MarshalHash(); err != nil {
+ return nil, err
} else {
- if oTemp, err := z.Signature.MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
+ o = hsp.AppendBytes(o, oTemp)
}
- o = append(o, 0x84)
+ o = append(o, 0x83)
if oTemp, err := z.TransferHeader.MarshalHash(); err != nil {
return nil, err
} else {
o = hsp.AppendBytes(o, oTemp)
}
- o = append(o, 0x84)
- if oTemp, err := z.HeaderHash.MarshalHash(); err != nil {
+ o = append(o, 0x83)
+ if oTemp, err := z.TransactionTypeMixin.MarshalHash(); err != nil {
return nil, err
} else {
o = hsp.AppendBytes(o, oTemp)
@@ -48,19 +34,7 @@ func (z *Transfer) MarshalHash() (o []byte, err error) {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *Transfer) Msgsize() (s int) {
- s = 1 + 7
- if z.Signee == nil {
- s += hsp.NilSize
- } else {
- s += z.Signee.Msgsize()
- }
- s += 10
- if z.Signature == nil {
- s += hsp.NilSize
- } else {
- s += z.Signature.Msgsize()
- }
- s += 15 + z.TransferHeader.Msgsize() + 11 + z.HeaderHash.Msgsize()
+ s = 1 + 28 + z.DefaultHashSignVerifierImpl.Msgsize() + 15 + z.TransferHeader.Msgsize() + 21 + z.TransactionTypeMixin.Msgsize()
return
}
diff --git a/blockproducer/types/tx_gen_test.go b/blockproducer/types/tx_gen_test.go
deleted file mode 100644
index 76e7feeed..000000000
--- a/blockproducer/types/tx_gen_test.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package types
-
-// Code generated by github.com/CovenantSQL/HashStablePack DO NOT EDIT.
diff --git a/blockproducer/types/txsqlchainbilling.go b/blockproducer/types/txsqlchainbilling.go
deleted file mode 100644
index fcb680ded..000000000
--- a/blockproducer/types/txsqlchainbilling.go
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright 2018 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 types
-
-import (
- "bytes"
- "sync"
-
- pi "github.com/CovenantSQL/CovenantSQL/blockproducer/interfaces"
- "github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
- "github.com/CovenantSQL/CovenantSQL/crypto/hash"
- "github.com/CovenantSQL/CovenantSQL/proto"
- "github.com/CovenantSQL/CovenantSQL/utils"
-)
-
-//go:generate hsp
-//hsp:ignore sync.Mutex Mutex
-
-// TxContent defines the customer's billing and block rewards in transaction.
-type TxContent struct {
- SequenceID uint32
- BillingRequest BillingRequest
- Receivers []*proto.AccountAddress
- // Fee paid by stable coin
- Fees []uint64
- // Reward is share coin
- Rewards []uint64
- BillingResponse BillingResponse
-}
-
-// NewTxContent generates new TxContent.
-func NewTxContent(seqID uint32,
- bReq *BillingRequest,
- receivers []*proto.AccountAddress,
- fees []uint64,
- rewards []uint64,
- bResp *BillingResponse) *TxContent {
- return &TxContent{
- SequenceID: seqID,
- BillingRequest: *bReq,
- Receivers: receivers,
- Fees: fees,
- Rewards: rewards,
- BillingResponse: *bResp,
- }
-}
-
-// GetHash returns the hash of transaction.
-func (tb *TxContent) GetHash() (*hash.Hash, error) {
- b, err := tb.MarshalHash()
- if err != nil {
- return nil, err
- }
- h := hash.THashH(b)
- return &h, nil
-}
-
-// TxBilling is a type of tx, that is used to record sql chain billing and block rewards.
-type TxBilling struct {
- mutex sync.Mutex
- TxContent TxContent
- TxType byte
- AccountAddress *proto.AccountAddress
- TxHash *hash.Hash
- Signee *asymmetric.PublicKey
- Signature *asymmetric.Signature
- SignedBlock *hash.Hash
-}
-
-// NewTxBilling generates a new TxBilling.
-func NewTxBilling(txContent *TxContent, txType TxType, addr *proto.AccountAddress) *TxBilling {
- return &TxBilling{
- TxContent: *txContent,
- TxType: txType.ToByte(),
- AccountAddress: addr,
- }
-}
-
-// Serialize serializes TxBilling using msgpack.
-func (tb *TxBilling) Serialize() (b []byte, err error) {
- var enc *bytes.Buffer
- if enc, err = utils.EncodeMsgPack(tb); err != nil {
- return
- }
- b = enc.Bytes()
- return
-}
-
-// Deserialize desrializes TxBilling using msgpack.
-func (tb *TxBilling) Deserialize(enc []byte) error {
- return utils.DecodeMsgPack(enc, tb)
-}
-
-// GetAccountAddress implements interfaces/Transaction.GetAccountAddress.
-func (tb *TxBilling) GetAccountAddress() proto.AccountAddress {
- return *tb.AccountAddress
-}
-
-// GetAccountNonce implements interfaces/Transaction.GetAccountNonce.
-func (tb *TxBilling) GetAccountNonce() pi.AccountNonce {
- return pi.AccountNonce(tb.TxContent.SequenceID)
-}
-
-// GetHash implements interfaces/Transaction.GetHash.
-func (tb *TxBilling) GetHash() hash.Hash {
- return *tb.TxHash
-}
-
-// GetTransactionType implements interfaces/Transaction.GetTransactionType.
-func (tb *TxBilling) GetTransactionType() pi.TransactionType {
- return pi.TransactionTypeBilling
-}
-
-// Sign computes tx of TxContent and signs it.
-func (tb *TxBilling) Sign(signer *asymmetric.PrivateKey) error {
- enc, err := tb.TxContent.MarshalHash()
- if err != nil {
- return err
- }
- h := hash.THashH(enc)
- tb.TxHash = &h
-
- pub := asymmetric.PublicKey(signer.PublicKey)
- tb.Signee = &pub
-
- signature, err := signer.Sign(h[:])
- if err != nil {
- return err
- }
- tb.Signature = signature
-
- return nil
-}
-
-// Verify verifies the signature of TxBilling.
-func (tb *TxBilling) Verify() (err error) {
- var enc []byte
- if enc, err = tb.TxContent.MarshalHash(); err != nil {
- return
- } else if h := hash.THashH(enc); !tb.TxHash.IsEqual(&h) {
- err = ErrSignVerification
- return
- } else if !tb.Signature.Verify(h[:], tb.Signee) {
- err = ErrSignVerification
- return
- }
- return
-}
-
-// GetDatabaseID gets the database ID.
-func (tb *TxBilling) GetDatabaseID() *proto.DatabaseID {
- return &tb.TxContent.BillingRequest.Header.DatabaseID
-}
-
-// GetSequenceID gets the sequence ID.
-func (tb *TxBilling) GetSequenceID() uint32 {
- return tb.TxContent.SequenceID
-}
-
-// IsSigned shows whether the tx billing is signed.
-func (tb *TxBilling) IsSigned() bool {
- tb.mutex.Lock()
- defer tb.mutex.Unlock()
- return tb.SignedBlock != nil
-}
-
-// SetSignedBlock sets the tx billing with block hash.
-func (tb *TxBilling) SetSignedBlock(h *hash.Hash) {
- tb.mutex.Lock()
- defer tb.mutex.Unlock()
- tb.SignedBlock = h
-}
-
-// GetSignedBlock gets the block hash.
-func (tb *TxBilling) GetSignedBlock() *hash.Hash {
- tb.mutex.Lock()
- defer tb.mutex.Unlock()
- return tb.SignedBlock
-}
diff --git a/blockproducer/types/txsqlchainbilling_gen.go b/blockproducer/types/txsqlchainbilling_gen.go
deleted file mode 100644
index 3cdd961e8..000000000
--- a/blockproducer/types/txsqlchainbilling_gen.go
+++ /dev/null
@@ -1,168 +0,0 @@
-package types
-
-// Code generated by github.com/CovenantSQL/HashStablePack DO NOT EDIT.
-
-import (
- hsp "github.com/CovenantSQL/HashStablePack/marshalhash"
-)
-
-// MarshalHash marshals for hash
-func (z *TxBilling) MarshalHash() (o []byte, err error) {
- var b []byte
- o = hsp.Require(b, z.Msgsize())
- // map header, size 7
- o = append(o, 0x87, 0x87)
- if z.Signee == nil {
- o = hsp.AppendNil(o)
- } else {
- if oTemp, err := z.Signee.MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
- }
- o = append(o, 0x87)
- if z.Signature == nil {
- o = hsp.AppendNil(o)
- } else {
- if oTemp, err := z.Signature.MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
- }
- o = append(o, 0x87)
- if z.SignedBlock == nil {
- o = hsp.AppendNil(o)
- } else {
- if oTemp, err := z.SignedBlock.MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
- }
- o = append(o, 0x87)
- if z.TxHash == nil {
- o = hsp.AppendNil(o)
- } else {
- if oTemp, err := z.TxHash.MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
- }
- o = append(o, 0x87)
- if z.AccountAddress == nil {
- o = hsp.AppendNil(o)
- } else {
- if oTemp, err := z.AccountAddress.MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
- }
- o = append(o, 0x87)
- if oTemp, err := z.TxContent.MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
- o = append(o, 0x87)
- o = hsp.AppendByte(o, z.TxType)
- return
-}
-
-// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
-func (z *TxBilling) Msgsize() (s int) {
- s = 1 + 7
- if z.Signee == nil {
- s += hsp.NilSize
- } else {
- s += z.Signee.Msgsize()
- }
- s += 10
- if z.Signature == nil {
- s += hsp.NilSize
- } else {
- s += z.Signature.Msgsize()
- }
- s += 12
- if z.SignedBlock == nil {
- s += hsp.NilSize
- } else {
- s += z.SignedBlock.Msgsize()
- }
- s += 7
- if z.TxHash == nil {
- s += hsp.NilSize
- } else {
- s += z.TxHash.Msgsize()
- }
- s += 15
- if z.AccountAddress == nil {
- s += hsp.NilSize
- } else {
- s += z.AccountAddress.Msgsize()
- }
- s += 10 + z.TxContent.Msgsize() + 7 + hsp.ByteSize
- return
-}
-
-// MarshalHash marshals for hash
-func (z *TxContent) MarshalHash() (o []byte, err error) {
- var b []byte
- o = hsp.Require(b, z.Msgsize())
- // map header, size 6
- o = append(o, 0x86, 0x86)
- if oTemp, err := z.BillingRequest.MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
- o = append(o, 0x86)
- if oTemp, err := z.BillingResponse.MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
- o = append(o, 0x86)
- o = hsp.AppendArrayHeader(o, uint32(len(z.Receivers)))
- for za0001 := range z.Receivers {
- if z.Receivers[za0001] == nil {
- o = hsp.AppendNil(o)
- } else {
- if oTemp, err := z.Receivers[za0001].MarshalHash(); err != nil {
- return nil, err
- } else {
- o = hsp.AppendBytes(o, oTemp)
- }
- }
- }
- o = append(o, 0x86)
- o = hsp.AppendArrayHeader(o, uint32(len(z.Fees)))
- for za0002 := range z.Fees {
- o = hsp.AppendUint64(o, z.Fees[za0002])
- }
- o = append(o, 0x86)
- o = hsp.AppendArrayHeader(o, uint32(len(z.Rewards)))
- for za0003 := range z.Rewards {
- o = hsp.AppendUint64(o, z.Rewards[za0003])
- }
- o = append(o, 0x86)
- o = hsp.AppendUint32(o, z.SequenceID)
- return
-}
-
-// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
-func (z *TxContent) Msgsize() (s int) {
- s = 1 + 15 + z.BillingRequest.Msgsize() + 16 + z.BillingResponse.Msgsize() + 10 + hsp.ArrayHeaderSize
- for za0001 := range z.Receivers {
- if z.Receivers[za0001] == nil {
- s += hsp.NilSize
- } else {
- s += z.Receivers[za0001].Msgsize()
- }
- }
- s += 5 + hsp.ArrayHeaderSize + (len(z.Fees) * (hsp.Uint64Size)) + 8 + hsp.ArrayHeaderSize + (len(z.Rewards) * (hsp.Uint64Size)) + 11 + hsp.Uint32Size
- return
-}
diff --git a/blockproducer/types/txsqlchainbilling_test.go b/blockproducer/types/txsqlchainbilling_test.go
deleted file mode 100644
index dc004a11b..000000000
--- a/blockproducer/types/txsqlchainbilling_test.go
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright 2018 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 types
-
-import (
- "reflect"
- "testing"
-
- "github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
- "github.com/CovenantSQL/CovenantSQL/crypto/hash"
- "github.com/CovenantSQL/CovenantSQL/utils"
-)
-
-func TestTxContent_GetHashAndGetType(t *testing.T) {
- tc, err := generateRandomTxContent()
- if err != nil {
- t.Fatalf("Unexpeted error: %v", err)
- }
-
- h, err := tc.GetHash()
- if err != nil {
- t.Fatalf("Unexpeted error: %v", err)
- }
-
- enc, err := tc.MarshalHash()
- encHash := hash.THashH(enc)
- if !h.IsEqual(&encHash) {
- t.Fatalf("Hash not match: \n\tv1=%v,\n\tv2=%v", h, encHash)
- }
-}
-
-func TestTxContent_MarshalUnmarshalBinary(t *testing.T) {
- tc, err := generateRandomTxContent()
- if err != nil {
- t.Fatalf("Unexpeted error: %v", err)
- }
-
- enc, err := utils.EncodeMsgPack(tc)
- if err != nil {
- t.Fatalf("Unexpeted error: %v", err)
- }
-
- dec := &TxContent{}
- err = utils.DecodeMsgPack(enc.Bytes(), dec)
- if err != nil {
- t.Fatalf("Unexpeted error: %v", err)
- }
-
- if tc.SequenceID != dec.SequenceID {
- t.Fatalf("Value not match: \n\tv1=%v\n\tv2=%v", tc.SequenceID, tc.SequenceID)
- }
- if tc.BillingRequest.RequestHash != dec.BillingRequest.RequestHash {
- t.Fatalf("Value not match: \n\tv1=%v\n\tv2=%v", tc.BillingRequest.RequestHash, tc.BillingRequest.RequestHash)
- }
- if !tc.BillingRequest.Signatures[0].IsEqual(dec.BillingRequest.Signatures[0]) {
- t.Fatalf("Value not match: \n\tv1=%v\n\tv2=%v", tc.BillingRequest.Signatures[0], dec.BillingRequest.Signatures[0])
- }
- for i := range tc.Receivers {
- if !reflect.DeepEqual(tc.Receivers[i], dec.Receivers[i]) {
- t.Fatalf("Value not match: \n\ttc.Receivers[%d]=%v\n\tReceive[%d]=%v", i, i, tc.Receivers[i], tc.Receivers[0])
- }
- if tc.Rewards[i] != dec.Rewards[i] {
- t.Fatalf("Value not match: \n\ttc.Rewards[%d]=%v\n\tRewards[%d]=%v", i, i, tc.Rewards[i], tc.Rewards[0])
- }
- if tc.Fees[i] != dec.Fees[i] {
- t.Fatalf("Value not match: \n\ttc.Fees[%d]=%v\n\tFees[%d]=%v", i, i, tc.Fees[i], tc.Fees[0])
- }
- }
-}
-
-func TestTxBilling_SerializeDeserialize(t *testing.T) {
- tb, err := generateRandomTxBilling()
- if err != nil {
- t.Fatalf("Unexpeted error: %v", err)
- }
-
- enc, err := tb.Serialize()
- if err != nil {
- t.Fatalf("Unexpeted error: %v", err)
- }
-
- dec := TxBilling{}
- err = dec.Deserialize(enc)
- if err != nil {
- t.Fatalf("Unexpeted error: %v", err)
- }
-
- if !tb.SignedBlock.IsEqual(dec.SignedBlock) {
- t.Fatalf("Value not match: \n\tv1=%v\n\tv2=%v", tb.SignedBlock, tb.SignedBlock)
- }
- if !tb.Signature.IsEqual(dec.Signature) {
- t.Fatalf("Value not match: \n\tv1=%v\n\tv2=%v", tb.Signature, tb.Signature)
- }
- if !tb.Signee.IsEqual(dec.Signee) {
- t.Fatalf("Value not match: \n\tv1=%v\n\tv2=%v", tb.Signee, tb.Signee)
- }
- if !tb.TxHash.IsEqual(dec.TxHash) {
- t.Fatalf("Value not match: \n\tv1=%v\n\tv2=%v", tb.TxHash, tb.TxHash)
- }
- if !reflect.DeepEqual(tb.TxContent.BillingResponse, dec.TxContent.BillingResponse) {
- t.Fatalf("Value not match: \n\tv1=%v\n\tv2=%v", tb.TxContent.BillingResponse, tb.TxContent.BillingResponse)
- }
-}
-
-func TestTxBilling_GetSet(t *testing.T) {
- tb, err := generateRandomTxBilling()
- if err != nil {
- t.Fatalf("Unexpeted error: %v", err)
- }
-
- tb.GetSequenceID()
- if tb.GetDatabaseID() == nil {
- t.Fatalf("String should not be nil: %v", tb)
- }
-
- if !tb.IsSigned() {
- t.Fatalf("BlockHash should not be nil: %v", tb)
- }
- h := generateRandomHash()
- tb.SetSignedBlock(&h)
- if !h.IsEqual(tb.GetSignedBlock()) {
- t.Fatalf("BlockHash should be the same: v1=%s, v2=%s", h.String(), tb.GetSignedBlock().String())
- }
-}
-
-func TestTxBilling_PackAndSignTx(t *testing.T) {
- tb, err := generateRandomTxBilling()
- if err != nil {
- t.Fatalf("Unexpeted error: %v", err)
- }
-
- priv, _, err := asymmetric.GenSecp256k1KeyPair()
- if err != nil {
- t.Fatalf("Unexpeted error: %v", err)
- }
- tb.Sign(priv)
- enc, err := tb.TxContent.MarshalHash()
- if err != nil {
- t.Fatalf("Unexpeted error: %v", err)
- }
- h := hash.THashH(enc[:])
- sign, err := priv.Sign(h[:])
- if err != nil {
- t.Fatalf("Unexpeted error: %v", err)
- }
- if !sign.IsEqual(tb.Signature) {
- t.Fatalf("Value not match: \n\tv1=%v\n\tv2=%v", sign, tb.Signature)
- }
-
- err = tb.Verify()
- if err != nil {
- t.Fatalf("Verify signature failed: %v", err)
- }
-}
diff --git a/blockproducer/types/xxx_test.go b/blockproducer/types/xxx_test.go
index f5a0efe10..31bd5a7ae 100644
--- a/blockproducer/types/xxx_test.go
+++ b/blockproducer/types/xxx_test.go
@@ -23,6 +23,7 @@ import (
"testing"
"time"
+ pi "github.com/CovenantSQL/CovenantSQL/blockproducer/interfaces"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
@@ -116,17 +117,9 @@ func randStringBytes(n int) string {
return string(b)
}
-func generateRandomUint32s(n int32) []uint32 {
- s := make([]uint32, n)
- for i := range s {
- s[i] = (uint32)(rand.Int31())
- }
- return s
-}
-
func generateRandomBlock(parent hash.Hash, isGenesis bool) (b *Block, err error) {
// Generate key pair
- priv, pub, err := asymmetric.GenSecp256k1KeyPair()
+ priv, _, err := asymmetric.GenSecp256k1KeyPair()
if err != nil {
return
@@ -143,16 +136,15 @@ func generateRandomBlock(parent hash.Hash, isGenesis bool) (b *Block, err error)
ParentHash: parent,
Timestamp: time.Now().UTC(),
},
- Signee: pub,
},
}
for i, n := 0, rand.Intn(10)+10; i < n; i++ {
- tb, err := generateRandomTxBilling()
+ tb, err := generateRandomBilling()
if err != nil {
return nil, err
}
- b.PushTx(tb)
+ b.Transactions = append(b.Transactions, tb)
}
err = b.PackAndSignBlock(priv)
@@ -170,72 +162,44 @@ func generateRandomBillingRequestHeader() *BillingRequestHeader {
}
}
-func generateRandomBillingRequest() (*BillingRequest, error) {
+func generateRandomBillingRequest() (req *BillingRequest, err error) {
reqHeader := generateRandomBillingRequestHeader()
- req := BillingRequest{
+ req = &BillingRequest{
Header: *reqHeader,
}
- h, err := req.PackRequestHeader()
- if err != nil {
+ if _, err = req.PackRequestHeader(); err != nil {
return nil, err
}
- signees := make([]*asymmetric.PublicKey, peerNum)
- signatures := make([]*asymmetric.Signature, peerNum)
-
- for i := range signees {
+ for i := 0; i < peerNum; i++ {
// Generate key pair
- priv, pub, err := asymmetric.GenSecp256k1KeyPair()
- if err != nil {
- return nil, err
+ var priv *asymmetric.PrivateKey
+
+ if priv, _, err = asymmetric.GenSecp256k1KeyPair(); err != nil {
+ return
}
- signees[i] = pub
- signatures[i], err = priv.Sign(h[:])
- if err != nil {
- return nil, err
+
+ if _, _, err = req.SignRequestHeader(priv, false); err != nil {
+ return
}
}
- req.RequestHash = *h
- req.Signatures = signatures
- req.Signees = signees
- return &req, nil
+ return
}
-func generateRandomBillingResponse() (*BillingResponse, error) {
- priv, pub, err := asymmetric.GenSecp256k1KeyPair()
- if err != nil {
- return nil, err
- }
- h := generateRandomHash()
- sign, err := priv.Sign(h[:])
- if err != nil {
- return nil, err
- }
- resp := BillingResponse{
- AccountAddress: proto.AccountAddress(generateRandomHash()),
- RequestHash: h,
- Signee: pub,
- Signature: sign,
+func generateRandomBillingHeader() (tc *BillingHeader, err error) {
+ var req *BillingRequest
+ if req, err = generateRandomBillingRequest(); err != nil {
+ return
}
- return &resp, nil
-}
-func generateRandomTxContent() (*TxContent, error) {
- req, err := generateRandomBillingRequest()
- if err != nil {
- return nil, err
- }
- priv, pub, err := asymmetric.GenSecp256k1KeyPair()
- sign, err := priv.Sign(req.RequestHash[:])
- if err != nil {
- return nil, err
+ var priv *asymmetric.PrivateKey
+ if priv, _, err = asymmetric.GenSecp256k1KeyPair(); err != nil {
+ return
}
- resp := &BillingResponse{
- AccountAddress: proto.AccountAddress(generateRandomHash()),
- RequestHash: req.RequestHash,
- Signee: pub,
- Signature: sign,
+
+ if _, _, err = req.SignRequestHeader(priv, false); err != nil {
+ return
}
receivers := make([]*proto.AccountAddress, peerNum)
@@ -249,33 +213,28 @@ func generateRandomTxContent() (*TxContent, error) {
rewards[i] = rand.Uint64()
}
- tc := NewTxContent(rand.Uint32(), req, receivers, fees, rewards, resp)
+ producer := proto.AccountAddress(generateRandomHash())
+ tc = NewBillingHeader(pi.AccountNonce(rand.Uint32()), req, producer, receivers, fees, rewards)
return tc, nil
}
-func generateRandomTxBilling() (*TxBilling, error) {
- txContent, err := generateRandomTxContent()
+func generateRandomBilling() (*Billing, error) {
+ header, err := generateRandomBillingHeader()
if err != nil {
return nil, err
}
- accountAddress := proto.AccountAddress(generateRandomHash())
- txHash := generateRandomHash()
- priv, pub, err := asymmetric.GenSecp256k1KeyPair()
- sign, err := priv.Sign(txHash[:])
+ priv, _, err := asymmetric.GenSecp256k1KeyPair()
if err != nil {
return nil, err
}
- blockHash := generateRandomHash()
-
- txBilling := NewTxBilling(txContent, TxTypeBilling, &accountAddress)
- txBilling.TxHash = &txHash
- txBilling.Signee = pub
- txBilling.Signature = sign
- txBilling.SignedBlock = &blockHash
+ txBilling := NewBilling(header)
+ if err := txBilling.Sign(priv); err != nil {
+ return nil, err
+ }
return txBilling, nil
}
-func generateRandomGasAmount(n uint32) []*proto.AddrAndGas {
+func generateRandomGasAmount(n int) []*proto.AddrAndGas {
gasAmount := make([]*proto.AddrAndGas, n)
for i := range gasAmount {
diff --git a/blockproducer/xxx_test.go b/blockproducer/xxx_test.go
index 4429f206b..8361b0eeb 100644
--- a/blockproducer/xxx_test.go
+++ b/blockproducer/xxx_test.go
@@ -25,8 +25,8 @@ import (
"time"
pi "github.com/CovenantSQL/CovenantSQL/blockproducer/interfaces"
- "github.com/CovenantSQL/CovenantSQL/blockproducer/types"
pt "github.com/CovenantSQL/CovenantSQL/blockproducer/types"
+ "github.com/CovenantSQL/CovenantSQL/crypto"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
@@ -41,17 +41,13 @@ var (
uuidLen = 32
peerNum uint32 = 32
- testAddress1 = proto.AccountAddress{0x0, 0x0, 0x0, 0x1}
- testAddress2 = proto.AccountAddress{0x0, 0x0, 0x0, 0x2}
- testInitBalance = uint64(10000)
- testMasterKey = []byte(".9K.sgch!3;C>w0v")
- testDifficulty = 4
- testDataDir string
- testPrivKeyFile string
- testPubKeysFile string
- testNonce pi.AccountNonce
- testPrivKey *asymmetric.PrivateKey
- testPubKey *asymmetric.PublicKey
+ testAddress1 = proto.AccountAddress{0x0, 0x0, 0x0, 0x1}
+ testAddress2 = proto.AccountAddress{0x0, 0x0, 0x0, 0x2}
+ testInitBalance = uint64(10000)
+ testDifficulty = 4
+ testDataDir string
+ testAddress1Nonce pi.AccountNonce
+ testPrivKey *asymmetric.PrivateKey
)
const (
@@ -87,9 +83,9 @@ func randStringBytes(n int) string {
return string(b)
}
-func generateRandomBlock(parent hash.Hash, isGenesis bool) (b *types.Block, err error) {
+func generateRandomBlock(parent hash.Hash, isGenesis bool) (b *pt.Block, err error) {
// Generate key pair
- priv, pub, err := asymmetric.GenSecp256k1KeyPair()
+ priv, _, err := asymmetric.GenSecp256k1KeyPair()
if err != nil {
return
@@ -98,43 +94,42 @@ func generateRandomBlock(parent hash.Hash, isGenesis bool) (b *types.Block, err
h := hash.Hash{}
rand.Read(h[:])
- b = &types.Block{
- SignedHeader: types.SignedHeader{
- Header: types.Header{
+ b = &pt.Block{
+ SignedHeader: pt.SignedHeader{
+ Header: pt.Header{
Version: 0x01000000,
Producer: proto.AccountAddress(h),
ParentHash: parent,
Timestamp: time.Now().UTC(),
},
- Signee: pub,
},
}
if !isGenesis {
for i, n := 0, rand.Intn(10)+10; i < n; i++ {
- tb, err := generateRandomTxBilling()
+ ba, tb, err := generateRandomBillingAndBaseAccount()
if err != nil {
return nil, err
}
- b.PushTx(tb)
+ b.Transactions = append(b.Transactions, ba, tb)
}
} else {
// Create base accounts
var (
- ba1 = &pt.BaseAccount{
- Account: pt.Account{
+ ba1 = pt.NewBaseAccount(
+ &pt.Account{
Address: testAddress1,
StableCoinBalance: testInitBalance,
CovenantCoinBalance: testInitBalance,
},
- }
- ba2 = &pt.BaseAccount{
- Account: pt.Account{
+ )
+ ba2 = pt.NewBaseAccount(
+ &pt.Account{
Address: testAddress2,
StableCoinBalance: testInitBalance,
CovenantCoinBalance: testInitBalance,
},
- }
+ )
)
if err = ba1.Sign(testPrivKey); err != nil {
return
@@ -142,17 +137,16 @@ func generateRandomBlock(parent hash.Hash, isGenesis bool) (b *types.Block, err
if err = ba2.Sign(testPrivKey); err != nil {
return
}
- b.Transactions = append(b.Transactions, ba1)
- b.Transactions = append(b.Transactions, ba2)
+ b.Transactions = append(b.Transactions, ba1, ba2)
}
err = b.PackAndSignBlock(priv)
return
}
-func generateRandomBlockWithTxBillings(parent hash.Hash, tbs []*types.TxBilling) (b *types.Block, err error) {
+func generateRandomBlockWithTransactions(parent hash.Hash, tbs []pi.Transaction) (b *pt.Block, err error) {
// Generate key pair
- priv, pub, err := asymmetric.GenSecp256k1KeyPair()
+ priv, _, err := asymmetric.GenSecp256k1KeyPair()
if err != nil {
return
@@ -161,44 +155,42 @@ func generateRandomBlockWithTxBillings(parent hash.Hash, tbs []*types.TxBilling)
h := hash.Hash{}
rand.Read(h[:])
- b = &types.Block{
- SignedHeader: types.SignedHeader{
- Header: types.Header{
+ b = &pt.Block{
+ SignedHeader: pt.SignedHeader{
+ Header: pt.Header{
Version: 0x01000000,
Producer: proto.AccountAddress(h),
ParentHash: parent,
Timestamp: time.Now().UTC(),
},
- Signee: pub,
},
}
- b.TxBillings = tbs
+ for _, tb := range tbs {
+ b.Transactions = append(b.Transactions, tb)
+ }
- testNonce++
- var tr = &pt.Transfer{
- TransferHeader: pt.TransferHeader{
+ testAddress1Nonce++
+ var tr = pt.NewTransfer(
+ &pt.TransferHeader{
Sender: testAddress1,
Receiver: testAddress2,
- Nonce: testNonce,
+ Nonce: testAddress1Nonce,
Amount: 1,
},
- }
+ )
if err = tr.Sign(priv); err != nil {
return
}
b.Transactions = append(b.Transactions, tr)
err = b.PackAndSignBlock(priv)
- for i := range b.TxBillings {
- b.TxBillings[i].SignedBlock = &b.SignedHeader.BlockHash
- }
return
}
-func generateRandomBillingRequestHeader() *types.BillingRequestHeader {
- return &types.BillingRequestHeader{
+func generateRandomBillingRequestHeader() *pt.BillingRequestHeader {
+ return &pt.BillingRequestHeader{
DatabaseID: *generateRandomDatabaseID(),
LowBlock: generateRandomHash(),
LowHeight: rand.Int31(),
@@ -208,9 +200,9 @@ func generateRandomBillingRequestHeader() *types.BillingRequestHeader {
}
}
-func generateRandomBillingRequest() (*types.BillingRequest, error) {
+func generateRandomBillingRequest() (*pt.BillingRequest, error) {
reqHeader := generateRandomBillingRequestHeader()
- req := types.BillingRequest{
+ req := pt.BillingRequest{
Header: *reqHeader,
}
h, err := req.PackRequestHeader()
@@ -240,40 +232,19 @@ func generateRandomBillingRequest() (*types.BillingRequest, error) {
return &req, nil
}
-func generateRandomBillingResponse() (*types.BillingResponse, error) {
- priv, pub, err := asymmetric.GenSecp256k1KeyPair()
- if err != nil {
- return nil, err
- }
- h := generateRandomHash()
- sign, err := priv.Sign(h[:])
- if err != nil {
- return nil, err
- }
- resp := types.BillingResponse{
- AccountAddress: proto.AccountAddress(generateRandomHash()),
- RequestHash: h,
- Signee: pub,
- Signature: sign,
+func generateRandomBillingHeader() (tc *pt.BillingHeader, err error) {
+ var req *pt.BillingRequest
+ if req, err = generateRandomBillingRequest(); err != nil {
+ return
}
- return &resp, nil
-}
-func generateRandomTxContent() (*types.TxContent, error) {
- req, err := generateRandomBillingRequest()
- if err != nil {
- return nil, err
- }
- priv, pub, err := asymmetric.GenSecp256k1KeyPair()
- sign, err := priv.Sign(req.RequestHash[:])
- if err != nil {
- return nil, err
+ var priv *asymmetric.PrivateKey
+ if priv, _, err = asymmetric.GenSecp256k1KeyPair(); err != nil {
+ return
}
- resp := &types.BillingResponse{
- AccountAddress: proto.AccountAddress(generateRandomHash()),
- RequestHash: req.RequestHash,
- Signee: pub,
- Signature: sign,
+
+ if _, _, err = req.SignRequestHeader(priv, false); err != nil {
+ return
}
receivers := make([]*proto.AccountAddress, peerNum)
@@ -286,69 +257,55 @@ func generateRandomTxContent() (*types.TxContent, error) {
fees[i] = rand.Uint64()
rewards[i] = rand.Uint64()
}
+ producer := proto.AccountAddress(generateRandomHash())
- tc := &types.TxContent{
- SequenceID: rand.Uint32(),
- BillingRequest: *req,
- BillingResponse: *resp,
- Receivers: receivers,
- Fees: fees,
- Rewards: rewards,
- }
+ tc = pt.NewBillingHeader(pi.AccountNonce(rand.Uint32()), req, producer, receivers, fees, rewards)
return tc, nil
}
-func generateRandomTxBilling() (*types.TxBilling, error) {
- txContent, err := generateRandomTxContent()
+func generateRandomBillingAndBaseAccount() (*pt.BaseAccount, *pt.Billing, error) {
+ header, err := generateRandomBillingHeader()
if err != nil {
- return nil, err
+ return nil, nil, err
}
- accountAddress := proto.AccountAddress(generateRandomHash())
- txHash := generateRandomHash()
- priv, pub, err := asymmetric.GenSecp256k1KeyPair()
- sign, err := priv.Sign(txHash[:])
- if err != nil {
- return nil, err
+ priv, _, err := asymmetric.GenSecp256k1KeyPair()
+ header.Producer, _ = crypto.PubKeyHash(priv.PubKey())
+
+ txBilling := pt.NewBilling(header)
+
+ if err := txBilling.Sign(priv); err != nil {
+ return nil, nil, err
}
- blockHash := generateRandomHash()
- txBilling := &types.TxBilling{
- TxContent: *txContent,
- AccountAddress: &accountAddress,
- TxHash: &txHash,
- Signee: pub,
- Signature: sign,
- SignedBlock: &blockHash,
+ txBaseAccount := pt.NewBaseAccount(
+ &pt.Account{
+ Address: header.Producer,
+ StableCoinBalance: testInitBalance,
+ CovenantCoinBalance: testInitBalance,
+ },
+ )
+
+ if err := txBaseAccount.Sign(priv); err != nil {
+ return nil, nil, err
}
- return txBilling, nil
+
+ return txBaseAccount, txBilling, nil
}
-func generateRandomTxBillingWithSeqID(seqID uint32) (*types.TxBilling, error) {
- txContent, err := generateRandomTxContent()
- txContent.SequenceID = seqID
+func generateRandomAccountBilling() (*pt.Billing, error) {
+ header, err := generateRandomBillingHeader()
if err != nil {
return nil, err
}
- accountAddress := testAddress1
- enc, err := txContent.MarshalHash()
- if err != nil {
- return nil, err
- }
- txHash := hash.THashH(enc)
- priv, pub, err := asymmetric.GenSecp256k1KeyPair()
- sign, err := priv.Sign(txHash[:])
- if err != nil {
+ header.Producer = testAddress1
+ testAddress1Nonce++
+ header.Nonce = testAddress1Nonce
+ txBilling := pt.NewBilling(header)
+
+ if err := txBilling.Sign(testPrivKey); err != nil {
return nil, err
}
- txBilling := &types.TxBilling{
- TxContent: *txContent,
- AccountAddress: &accountAddress,
- TxHash: &txHash,
- Signee: pub,
- Signature: sign,
- SignedBlock: nil,
- }
return txBilling, nil
}
@@ -372,22 +329,6 @@ func generateRandomHash() hash.Hash {
return h
}
-func generateRandomNode() (node *nodeProfile, err error) {
- priv, pub, err := asymmetric.GenSecp256k1KeyPair()
-
- if err != nil {
- return
- }
-
- node = &nodeProfile{
- PrivateKey: priv,
- PublicKey: pub,
- }
-
- createRandomString(10, 10, (*string)(&node.NodeID))
- return
-}
-
func registerNodesWithPublicKey(pub *asymmetric.PublicKey, diff int, num int) (
nis []cpuminer.NonceInfo, err error) {
nis = make([]cpuminer.NonceInfo, num)
@@ -432,17 +373,6 @@ func createRandomString(offset, length int, s *string) {
*s = string(buff)
}
-// createNodes assign Node asymmetric key pair and generate Node.NonceInfo
-// Node.ID = Node.NonceInfo.Hash.
-func createNodes(pubKey *asymmetric.PublicKey, timeThreshold time.Duration) *proto.Node {
- node := proto.NewNode()
- nonce := asymmetric.GetPubKeyNonce(pubKey, proto.NewNodeIDDifficulty, timeThreshold, nil)
- node.ID = proto.NodeID(nonce.Hash.String())
- node.Nonce = nonce.Nonce
- log.Debugf("Node: %v", node)
- return node
-}
-
func createTestPeersWithPrivKeys(priv *asymmetric.PrivateKey, num int) (nis []cpuminer.NonceInfo, p *kayak.Peers, err error) {
if num <= 0 {
return
@@ -552,7 +482,7 @@ func setup() {
rand.Read(genesisHash[:])
// Create key paire for test
- if testPrivKey, testPubKey, err = asymmetric.GenSecp256k1KeyPair(); err != nil {
+ if testPrivKey, _, err = asymmetric.GenSecp256k1KeyPair(); err != nil {
panic(err)
}
diff --git a/build.sh b/build.sh
index cb5211048..f856edc00 100755
--- a/build.sh
+++ b/build.sh
@@ -34,9 +34,6 @@ cql_observer_pkgpath="github.com/CovenantSQL/CovenantSQL/cmd/cql-observer"
go build -ldflags "-X main.version=${version} -X github.com/CovenantSQL/CovenantSQL/conf.RoleTag=C ${GOLDFLAGS}" -o bin/cql-observer ${cql_observer_pkgpath}
go test -coverpkg github.com/CovenantSQL/CovenantSQL/... -cover -race -c -tags 'testbinary' -ldflags "-X main.version=${version} -X github.com/CovenantSQL/CovenantSQL/conf.RoleTag=C ${GOLDFLAGS}" -o bin/cql-observer.test ${cql_observer_pkgpath}
-# hotfix_pkgpath="github.com/CovenantSQL/CovenantSQL/cmd/hotfix/msgpack-20180824"
-# CGO_ENABLED=1 go build -ldflags "${GOLDFLAGS}" -o bin/hotfix_msgpack_20180824 ${hotfix_pkgpath}
-
cli_pkgpath="github.com/CovenantSQL/CovenantSQL/cmd/cql"
CGO_ENABLED=1 go build -ldflags "-X main.version=${version} -X github.com/CovenantSQL/CovenantSQL/conf.RoleTag=C ${GOLDFLAGS}" --tags ${platform}" sqlite_omit_load_extension" -o bin/cql ${cli_pkgpath}
@@ -47,7 +44,10 @@ cql_faucet_pkgpath="github.com/CovenantSQL/CovenantSQL/cmd/cql-faucet"
CGO_ENABLED=1 go build -ldflags "-X main.version=${version} -X github.com/CovenantSQL/CovenantSQL/conf.RoleTag=C ${GOLDFLAGS}" --tags ${platform}" sqlite_omit_load_extension" -o bin/cql-faucet ${cql_faucet_pkgpath}
cql_mysql_adapter_pkgpath="github.com/CovenantSQL/CovenantSQL/cmd/cql-mysql-adapter"
-CGO_ENABLED=1 go build -ldflags "-X github.com/CovenantSQL/CovenantSQL/conf.RoleTag=C ${GOLDFLAGS}" --tags ${platform}" sqlite_omit_load_extension" -o bin/cql-mysql-adapter ${cql_mysql_adapter_pkgpath}
+CGO_ENABLED=1 go build -ldflags "-X main.version=${version} -X github.com/CovenantSQL/CovenantSQL/conf.RoleTag=C ${GOLDFLAGS}" --tags ${platform}" sqlite_omit_load_extension" -o bin/cql-mysql-adapter ${cql_mysql_adapter_pkgpath}
+
+cql_explorer_pkgpath="github.com/CovenantSQL/CovenantSQL/cmd/cql-explorer"
+CGO_ENABLED=1 go build -ldflags "-X main.version=${version} -X github.com/CovenantSQL/CovenantSQL/conf.RoleTag=C ${GOLDFLAGS}" --tags ${platform}" sqlite_omit_load_extension" -o bin/cql-explorer ${cql_explorer_pkgpath}
echo "done"
diff --git a/cleanupDB.sh b/cleanupDB.sh
index a14cbd9bd..caf5dc037 100755
--- a/cleanupDB.sh
+++ b/cleanupDB.sh
@@ -7,4 +7,5 @@ cd ${PROJECT_DIR} && find . -name '*.db-shm' -exec rm -f {} \;
cd ${PROJECT_DIR} && find . -name '*.db-wal' -exec rm -f {} \;
cd ${PROJECT_DIR} && find . -name 'db.meta' -exec rm -f {} \;
cd ${PROJECT_DIR} && find . -name 'public.keystore' -exec rm -f {} \;
-cd ${PROJECT_DIR} && find . -name '*.public.keystore' -exec rm -f {} \;
\ No newline at end of file
+cd ${PROJECT_DIR} && find . -name '*.public.keystore' -exec rm -f {} \;
+cd ${PROJECT_DIR} && find . -type d -name '*.ldb' -prune -exec rm -rf {} \;
diff --git a/client/_example/simple.go b/client/_example/simple.go
index 1bbd2e420..1dd270aab 100644
--- a/client/_example/simple.go
+++ b/client/_example/simple.go
@@ -19,7 +19,6 @@ package main
import (
"database/sql"
"flag"
-
"fmt"
"github.com/CovenantSQL/CovenantSQL/client"
diff --git a/client/clientbench_test.go b/client/clientbench_test.go
index af6e68738..b19fb2c85 100644
--- a/client/clientbench_test.go
+++ b/client/clientbench_test.go
@@ -41,7 +41,7 @@ func BenchmarkCovenantSQLDriver(b *testing.B) {
log.SetLevel(log.DebugLevel)
err = os.Chdir(testWorkingDir)
if err != nil {
- log.Errorf("change working dir failed: %s", err)
+ log.WithError(err).Error("change working dir failed")
return
}
@@ -59,7 +59,7 @@ func BenchmarkCovenantSQLDriver(b *testing.B) {
b.Fatal(err)
}
- log.Infof("the created database dsn is %v", dsn)
+ log.WithField("dsn", dsn).Info("created database")
db, err := sql.Open("covenantsql", dsn)
if err != nil {
@@ -90,7 +90,7 @@ func BenchmarkCovenantSQLDriver(b *testing.B) {
if err != nil || result < 0 {
b.Fatal(err)
}
- log.Debugf("result %d", result)
+ log.WithField("result", result).Debug("collected result")
}
})
err = db.Close()
diff --git a/client/config.go b/client/config.go
index 8b7a498eb..9f18a6861 100644
--- a/client/config.go
+++ b/client/config.go
@@ -18,26 +18,13 @@ package client
import (
"net/url"
- "time"
-)
-
-const (
- paramKeyDebug = "debug"
- paramKeyUpdateInterval = "update_interval"
-)
-
-var (
- // DefaultPeersUpdateInterval set client update peers config every 15 seconds.
- DefaultPeersUpdateInterval = time.Second * 15
+ "strings"
)
// Config is a configuration parsed from a DSN string.
type Config struct {
DatabaseID string
- Debug bool
- PeersUpdateInterval time.Duration
-
// additional configs should be filled
// such as read/write/exec timeout
// currently no timeout is supported.
@@ -45,10 +32,7 @@ type Config struct {
// NewConfig creates a new config with default value.
func NewConfig() *Config {
- return &Config{
- Debug: false,
- PeersUpdateInterval: DefaultPeersUpdateInterval,
- }
+ return &Config{}
}
// FormatDSN formats the given Config into a DSN string which can be passed to the driver.
@@ -56,20 +40,11 @@ func (cfg *Config) FormatDSN() string {
// build query from arguments
u := &url.URL{
- Scheme: "covenantsql",
+ Scheme: DBScheme,
Host: cfg.DatabaseID,
}
newQuery := u.Query()
-
- if cfg.Debug {
- newQuery.Set(paramKeyDebug, "true")
- }
-
- if cfg.PeersUpdateInterval != DefaultPeersUpdateInterval {
- newQuery.Set(paramKeyUpdateInterval, cfg.PeersUpdateInterval.String())
- }
-
u.RawQuery = newQuery.Encode()
return u.String()
@@ -77,6 +52,10 @@ func (cfg *Config) FormatDSN() string {
// ParseDSN parse the DSN string to a Config.
func ParseDSN(dsn string) (cfg *Config, err error) {
+ if !strings.HasPrefix(dsn, DBScheme) && !strings.HasPrefix(dsn, DBSchemeAlias) {
+ dsn = DBScheme + "://" + dsn
+ }
+
var u *url.URL
if u, err = url.Parse(dsn); err != nil {
return
@@ -85,17 +64,5 @@ func ParseDSN(dsn string) (cfg *Config, err error) {
cfg = NewConfig()
cfg.DatabaseID = u.Host
- urlQuery := u.Query()
-
- if urlQuery.Get(paramKeyDebug) == "true" {
- cfg.Debug = true
- }
- if updateInterval := urlQuery.Get(paramKeyUpdateInterval); updateInterval != "" {
- // parse update interval
- if cfg.PeersUpdateInterval, err = time.ParseDuration(updateInterval); err != nil {
- return
- }
- }
-
return
}
diff --git a/client/config_test.go b/client/config_test.go
index a59a42595..f7a3d501b 100644
--- a/client/config_test.go
+++ b/client/config_test.go
@@ -18,7 +18,6 @@ package client
import (
"testing"
- "time"
"github.com/CovenantSQL/CovenantSQL/proto"
. "github.com/smartystreets/goconvey/convey"
@@ -33,19 +32,15 @@ func TestConfig(t *testing.T) {
So(err, ShouldBeNil)
So(cfg.DatabaseID, ShouldEqual, proto.DatabaseID("db"))
So(cfg.FormatDSN(), ShouldEqual, "covenantsql://db")
-
- // test with parameters
- cfg, err = ParseDSN("covenantsql://db?debug=true&update_interval=1s")
+ })
+ Convey("test invalid config", t, func() {
+ _, err := ParseDSN("invalid dsn")
+ So(err, ShouldNotBeNil)
+ })
+ Convey("test dsn with only database id", t, func() {
+ dbIDStr := "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
+ cfg, err := ParseDSN(dbIDStr)
So(err, ShouldBeNil)
- So(cfg.DatabaseID, ShouldEqual, proto.DatabaseID("db"))
- So(cfg.Debug, ShouldBeTrue)
- So(cfg.PeersUpdateInterval, ShouldEqual, time.Second)
-
- cfg.Debug = false
- So(cfg.FormatDSN(), ShouldEqual, "covenantsql://db?update_interval=1s")
-
- cfg.Debug = true
- cfg.PeersUpdateInterval = DefaultPeersUpdateInterval
- So(cfg.FormatDSN(), ShouldEqual, "covenantsql://db?debug=true")
+ So(cfg.DatabaseID, ShouldEqual, dbIDStr)
})
}
diff --git a/client/conn.go b/client/conn.go
index 60c8371ed..a91de5258 100644
--- a/client/conn.go
+++ b/client/conn.go
@@ -20,13 +20,10 @@ import (
"context"
"database/sql"
"database/sql/driver"
- "math/rand"
- "strings"
"sync"
"sync/atomic"
"time"
- bp "github.com/CovenantSQL/CovenantSQL/blockproducer"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
"github.com/CovenantSQL/CovenantSQL/kayak"
@@ -37,39 +34,24 @@ import (
wt "github.com/CovenantSQL/CovenantSQL/worker/types"
)
-var (
- connectionID uint64
- seqNo uint64
- randSource = rand.New(rand.NewSource(time.Now().UnixNano()))
-)
-
// conn implements an interface sql.Conn.
type conn struct {
dbID proto.DatabaseID
- queries []wt.Query
- peers *kayak.Peers
- peersLock sync.RWMutex
- nodeID proto.NodeID
- privKey *asymmetric.PrivateKey
- pubKey *asymmetric.PublicKey
+ queries []wt.Query
+ localNodeID proto.NodeID
+ privKey *asymmetric.PrivateKey
+ ackCh chan *wt.Ack
inTransaction bool
closed int32
- closeCh chan struct{}
+ pCaller *rpc.PersistentCaller
}
func newConn(cfg *Config) (c *conn, err error) {
- if cfg.Debug {
- log.SetLevel(log.DebugLevel)
- }
-
- // init connectionID to random id
- atomic.CompareAndSwapUint64(&connectionID, 0, randSource.Uint64())
-
// get local node id
- var nodeID proto.NodeID
- if nodeID, err = kms.GetLocalNodeID(); err != nil {
+ var localNodeID proto.NodeID
+ if localNodeID, err = kms.GetLocalNodeID(); err != nil {
return
}
@@ -79,53 +61,85 @@ func newConn(cfg *Config) (c *conn, err error) {
return
}
- // get local public key
- var pubKey *asymmetric.PublicKey
- if pubKey, err = kms.GetLocalPublicKey(); err != nil {
+ c = &conn{
+ dbID: proto.DatabaseID(cfg.DatabaseID),
+ localNodeID: localNodeID,
+ privKey: privKey,
+ queries: make([]wt.Query, 0),
+ }
+
+ // get peers from BP
+ if _, err = cacheGetPeers(c.dbID, c.privKey); err != nil {
+ log.WithError(err).Error("cacheGetPeers failed")
+ c = nil
return
}
- c = &conn{
- dbID: proto.DatabaseID(cfg.DatabaseID),
- nodeID: nodeID,
- privKey: privKey,
- pubKey: pubKey,
- queries: make([]wt.Query, 0),
- closeCh: make(chan struct{}),
+ err = c.startAckWorkers(2)
+ if err != nil {
+ log.WithError(err).Error("startAckWorkers failed")
+ c = nil
+ return
}
+ log.WithField("db", c.dbID).Debug("new connection to database")
- c.log("new conn database ", c.dbID)
+ return
+}
- // get peers from BP
- if err = c.getPeers(); err != nil {
- return
+func (c *conn) startAckWorkers(workerCount int) (err error) {
+ c.ackCh = make(chan *wt.Ack, workerCount*4)
+ for i := 0; i < workerCount; i++ {
+ go c.ackWorker()
}
+ return
+}
- // start peers update routine
- go func() {
- ticker := time.NewTicker(cfg.PeersUpdateInterval)
- defer ticker.Stop()
+func (c *conn) stopAckWorkers() {
+ close(c.ackCh)
+}
- for {
- select {
- case <-c.closeCh:
- return
- case <-ticker.C:
+func (c *conn) ackWorker() {
+ if rawPeers, ok := peerList.Load(c.dbID); ok {
+ if peers, ok := rawPeers.(*kayak.Peers); ok {
+ var (
+ oneTime sync.Once
+ pc *rpc.PersistentCaller
+ err error
+ )
+
+ ackWorkerLoop:
+ for {
+ ack, got := <-c.ackCh
+ if !got { //closed and empty
+ break ackWorkerLoop
+ }
+ oneTime.Do(func() {
+ pc = rpc.NewPersistentCaller(peers.Leader.ID)
+ })
+ if err = ack.Sign(c.privKey, false); err != nil {
+ log.WithField("target", pc.TargetID).WithError(err).Error("failed to sign ack")
+ continue
+ }
+
+ var ackRes wt.AckResponse
+ // send ack back
+ if err = pc.Call(route.DBSAck.String(), ack, &ackRes); err != nil {
+ log.WithError(err).Warning("send ack failed")
+ continue
+ }
}
-
- if err = c.getPeers(); err != nil {
- c.log("update peers failed ", err.Error())
+ if pc != nil {
+ pc.CloseStream()
}
+ log.Debug("ack worker quiting")
+ return
}
- }()
+ }
+ log.Fatal("must GetPeers first")
return
}
-func (c *conn) log(msg ...interface{}) {
- log.Debug(msg...)
-}
-
// Prepare implements the driver.Conn.Prepare method.
func (c *conn) Prepare(query string) (driver.Stmt, error) {
return c.PrepareContext(context.Background(), query)
@@ -135,15 +149,10 @@ func (c *conn) Prepare(query string) (driver.Stmt, error) {
func (c *conn) Close() error {
// close the meta connection
if atomic.CompareAndSwapInt32(&c.closed, 0, 1) {
- c.log("closed connection")
- }
-
- select {
- case <-c.closeCh:
- default:
- close(c.closeCh)
+ log.WithField("db", c.dbID).Debug("closed connection")
}
-
+ c.stopAckWorkers()
+ c.pCaller.CloseStream()
return nil
}
@@ -159,7 +168,7 @@ func (c *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, e
}
// start transaction
- c.log("begin transaction tx=", c.inTransaction)
+ log.WithField("inTx", c.inTransaction).Debug("begin transaction")
if c.inTransaction {
return nil, sql.ErrTxDone
@@ -178,6 +187,8 @@ func (c *conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, e
return nil, driver.ErrBadConn
}
+ log.WithField("query", query).Debug("prepared statement")
+
// prepare the statement
return newStmt(c, query), nil
}
@@ -270,29 +281,55 @@ func (c *conn) addQuery(queryType wt.QueryType, query *wt.Query) (rows driver.Ro
// append queries
c.queries = append(c.queries, *query)
+
+ log.WithFields(log.Fields{
+ "pattern": query.Pattern,
+ "args": query.Args,
+ }).Debug("add query to tx")
+
return
}
+ log.WithFields(log.Fields{
+ "pattern": query.Pattern,
+ "args": query.Args,
+ }).Debug("execute query")
+
return c.sendQuery(queryType, []wt.Query{*query})
}
func (c *conn) sendQuery(queryType wt.QueryType, queries []wt.Query) (rows driver.Rows, err error) {
- c.peersLock.RLock()
- defer c.peersLock.RUnlock()
+ var peers *kayak.Peers
+ if peers, err = cacheGetPeers(c.dbID, c.privKey); err != nil {
+ return
+ }
+
+ // allocate sequence
+ connID, seqNo := allocateConnAndSeq()
+ defer putBackConn(connID)
+
+ defer func() {
+ log.WithFields(log.Fields{
+ "count": len(queries),
+ "type": queryType.String(),
+ "connID": connID,
+ "seqNo": seqNo,
+ "target": peers.Leader.ID,
+ "source": c.localNodeID,
+ }).WithError(err).Debug("send query")
+ }()
// build request
- seqNo := atomic.AddUint64(&seqNo, 1)
req := &wt.Request{
Header: wt.SignedRequestHeader{
RequestHeader: wt.RequestHeader{
QueryType: queryType,
- NodeID: c.nodeID,
+ NodeID: c.localNodeID,
DatabaseID: c.dbID,
- ConnectionID: atomic.LoadUint64(&connectionID),
+ ConnectionID: connID,
SeqNo: seqNo,
Timestamp: getLocalTime(),
},
- Signee: c.pubKey,
},
Payload: wt.RequestPayload{
Queries: queries,
@@ -303,87 +340,29 @@ func (c *conn) sendQuery(queryType wt.QueryType, queries []wt.Query) (rows drive
return
}
- pCaller := rpc.NewPersistentCaller(c.peers.Leader.ID)
- defer pCaller.Close()
+ c.pCaller = rpc.NewPersistentCaller(peers.Leader.ID)
var response wt.Response
- if err = pCaller.Call(route.DBSQuery.String(), req, &response); err != nil {
- if strings.Contains(err.Error(), "invalid request sequence") {
- // request sequence failure, try again
- atomic.StoreUint64(&connectionID, randSource.Uint64())
- req.Header.ConnectionID = atomic.LoadUint64(&connectionID)
- req.Header.SeqNo = atomic.AddUint64(&seqNo, 1)
-
- if err = req.Sign(c.privKey); err != nil {
- return
- }
-
- // send request again
- if err = pCaller.Call(route.DBSQuery.String(), req, &response); err != nil {
- return
- }
- } else {
- return
- }
+ if err = c.pCaller.Call(route.DBSQuery.String(), req, &response); err != nil {
+ return
}
// verify response
if err = response.Verify(); err != nil {
return
}
+ rows = newRows(&response)
// build ack
- ack := &wt.Ack{
+ c.ackCh <- &wt.Ack{
Header: wt.SignedAckHeader{
AckHeader: wt.AckHeader{
Response: response.Header,
- NodeID: c.nodeID,
+ NodeID: c.localNodeID,
Timestamp: getLocalTime(),
},
- Signee: c.pubKey,
},
}
- if err = ack.Sign(c.privKey); err != nil {
- return
- }
-
- var ackRes wt.AckResponse
-
- // send ack back
- if err = pCaller.Call(route.DBSAck.String(), ack, &ackRes); err != nil {
- log.Warningf("ack query failed: %v", err)
- err = nil
- }
-
- rows = newRows(&response)
-
- return
-}
-
-func (c *conn) getPeers() (err error) {
- c.peersLock.Lock()
- defer c.peersLock.Unlock()
-
- req := new(bp.GetDatabaseRequest)
- req.Header.DatabaseID = c.dbID
- req.Header.Signee = c.pubKey
-
- if err = req.Sign(c.privKey); err != nil {
- return
- }
-
- res := new(bp.GetDatabaseResponse)
- if err = requestBP(route.BPDBGetDatabase, req, res); err != nil {
- return
- }
-
- // verify response
- if err = res.Verify(); err != nil {
- return
- }
-
- c.peers = res.Header.InstanceMeta.Peers
-
return
}
diff --git a/client/conn_test.go b/client/conn_test.go
index 70e714f9a..29022e9e4 100644
--- a/client/conn_test.go
+++ b/client/conn_test.go
@@ -18,6 +18,7 @@ package client
import (
"database/sql"
+ "sync"
"testing"
"github.com/CovenantSQL/CovenantSQL/utils/log"
@@ -250,3 +251,40 @@ func TestTransaction(t *testing.T) {
So(err, ShouldNotBeNil)
})
}
+
+func TestConnAndSeqAllocation(t *testing.T) {
+ Convey("conn id and seq no allocation test", t, func() {
+ var wg sync.WaitGroup
+ var seqMap sync.Map
+ testFunc := func(c, s uint64) {
+ v, l := seqMap.LoadOrStore(c, s)
+ if l {
+ vi := v.(uint64)
+ if vi >= s {
+ // invalid
+ t.Fatalf(ErrInvalidRequestSeq.Error())
+ }
+ } else {
+ seqMap.Store(c, s)
+ }
+ }
+ f := func() {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for i := 0; i != 100; i++ {
+ connID, seqNo := allocateConnAndSeq()
+ t.Logf("connID: %v, seqNo: %v", connID, seqNo)
+ testFunc(connID, seqNo)
+ putBackConn(connID)
+ }
+ }()
+ }
+
+ f()
+ f()
+ f()
+ f()
+ wg.Wait()
+ })
+}
diff --git a/client/driver.go b/client/driver.go
index 0f9a9e2d9..4522fac11 100644
--- a/client/driver.go
+++ b/client/driver.go
@@ -19,27 +19,51 @@ package client
import (
"database/sql"
"database/sql/driver"
+ "math/rand"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/pkg/errors"
bp "github.com/CovenantSQL/CovenantSQL/blockproducer"
"github.com/CovenantSQL/CovenantSQL/conf"
"github.com/CovenantSQL/CovenantSQL/crypto"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
+ "github.com/CovenantSQL/CovenantSQL/kayak"
"github.com/CovenantSQL/CovenantSQL/proto"
"github.com/CovenantSQL/CovenantSQL/route"
"github.com/CovenantSQL/CovenantSQL/rpc"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
wt "github.com/CovenantSQL/CovenantSQL/worker/types"
)
const (
- // PubKeyStorePath defines public cache store.
- PubKeyStorePath = "./public.keystore"
+ // DBScheme defines the dsn scheme.
+ DBScheme = "covenantsql"
+ // DBSchemeAlias defines the alias dsn scheme.
+ DBSchemeAlias = "cql"
+)
+
+var (
+ // PeersUpdateInterval defines peers list refresh interval for client.
+ PeersUpdateInterval = time.Second * 5
+
+ driverInitialized uint32
+ peersUpdaterRunning uint32
+ peerList sync.Map // map[proto.DatabaseID]*kayak.Peers
+ connIDLock sync.Mutex
+ connIDAvail []uint64
+ globalSeqNo uint64
+ randSource = rand.New(rand.NewSource(time.Now().UnixNano()))
)
func init() {
- driver := new(covenantSQLDriver)
- sql.Register("covenantsql", driver)
- sql.Register("cql", driver)
+ d := new(covenantSQLDriver)
+ sql.Register(DBScheme, d)
+ sql.Register(DBSchemeAlias, d)
}
// covenantSQLDriver implements sql.Driver interface.
@@ -53,6 +77,11 @@ func (d *covenantSQLDriver) Open(dsn string) (conn driver.Conn, err error) {
return
}
+ if atomic.LoadUint32(&driverInitialized) == 0 {
+ err = ErrNotInitialized
+ return
+ }
+
return newConn(cfg)
}
@@ -61,6 +90,11 @@ type ResourceMeta wt.ResourceMeta
// Init defines init process for client.
func Init(configFile string, masterKey []byte) (err error) {
+ if !atomic.CompareAndSwapUint32(&driverInitialized, 0, 1) {
+ err = ErrAlreadyInitialized
+ return
+ }
+
// load config
if conf.GConf, err = conf.LoadConfig(configFile); err != nil {
return
@@ -71,31 +105,48 @@ func Init(configFile string, masterKey []byte) (err error) {
}
// ping block producer to register node
- err = registerNode()
+ if err = registerNode(); err != nil {
+ return
+ }
+
+ // run peers updater
+ if err = runPeerListUpdater(); err != nil {
+ return
+ }
return
}
// Create send create database operation to block producer.
func Create(meta ResourceMeta) (dsn string, err error) {
+ if atomic.LoadUint32(&driverInitialized) == 0 {
+ err = ErrNotInitialized
+ return
+ }
+
req := new(bp.CreateDatabaseRequest)
req.Header.ResourceMeta = wt.ResourceMeta(meta)
if req.Header.Signee, err = kms.GetLocalPublicKey(); err != nil {
+ err = errors.Wrap(err, "get local public key failed")
return
}
var privateKey *asymmetric.PrivateKey
if privateKey, err = kms.GetLocalPrivateKey(); err != nil {
+ err = errors.Wrap(err, "get local private key failed")
return
}
if err = req.Sign(privateKey); err != nil {
+ err = errors.Wrap(err, "sign request failed")
return
}
res := new(bp.CreateDatabaseResponse)
if err = requestBP(route.BPDBCreateDatabase, req, res); err != nil {
+ err = errors.Wrap(err, "call BPDB.CreateDatabase failed")
return
}
if err = res.Verify(); err != nil {
+ err = errors.Wrap(err, "response verify failed")
return
}
@@ -108,6 +159,11 @@ func Create(meta ResourceMeta) (dsn string, err error) {
// Drop send drop database operation to block producer.
func Drop(dsn string) (err error) {
+ if atomic.LoadUint32(&driverInitialized) == 0 {
+ err = ErrNotInitialized
+ return
+ }
+
var cfg *Config
if cfg, err = ParseDSN(dsn); err != nil {
return
@@ -133,6 +189,11 @@ func Drop(dsn string) (err error) {
// GetStableCoinBalance get the stable coin balance of current account.
func GetStableCoinBalance() (balance uint64, err error) {
+ if atomic.LoadUint32(&driverInitialized) == 0 {
+ err = ErrNotInitialized
+ return
+ }
+
req := new(bp.QueryAccountStableBalanceReq)
resp := new(bp.QueryAccountStableBalanceResp)
@@ -154,6 +215,11 @@ func GetStableCoinBalance() (balance uint64, err error) {
// GetCovenantCoinBalance get the covenant coin balance of current account.
func GetCovenantCoinBalance() (balance uint64, err error) {
+ if atomic.LoadUint32(&driverInitialized) == 0 {
+ err = ErrNotInitialized
+ return
+ }
+
req := new(bp.QueryAccountCovenantBalanceReq)
resp := new(bp.QueryAccountCovenantBalanceResp)
@@ -198,3 +264,141 @@ func registerNode() (err error) {
return
}
+
+func runPeerListUpdater() (err error) {
+ var privKey *asymmetric.PrivateKey
+ if privKey, err = kms.GetLocalPrivateKey(); err != nil {
+ return
+ }
+
+ if !atomic.CompareAndSwapUint32(&peersUpdaterRunning, 0, 1) {
+ return
+ }
+
+ go func() {
+ for {
+ if atomic.LoadUint32(&peersUpdaterRunning) == 0 {
+ return
+ }
+
+ var wg sync.WaitGroup
+
+ peerList.Range(func(rawDBID, _ interface{}) bool {
+ dbID := rawDBID.(proto.DatabaseID)
+
+ wg.Add(1)
+ go func(dbID proto.DatabaseID) {
+ defer wg.Done()
+ var err error
+
+ if _, err = getPeers(dbID, privKey); err != nil {
+ log.WithField("db", dbID).
+ WithError(err).
+ Warning("update peers failed")
+
+ // TODO(xq262144), better rpc remote error judgement
+ if strings.Contains(err.Error(), bp.ErrNoSuchDatabase.Error()) {
+ log.WithField("db", dbID).
+ Warning("database no longer exists, stopped peers update")
+ peerList.Delete(dbID)
+ }
+ }
+ }(dbID)
+
+ return true
+ })
+
+ wg.Wait()
+
+ time.Sleep(PeersUpdateInterval)
+ }
+ }()
+
+ return
+}
+
+func stopPeersUpdater() {
+ atomic.StoreUint32(&peersUpdaterRunning, 0)
+}
+
+func cacheGetPeers(dbID proto.DatabaseID, privKey *asymmetric.PrivateKey) (peers *kayak.Peers, err error) {
+ var ok bool
+ var rawPeers interface{}
+ var cacheHit bool
+
+ defer func() {
+ log.WithFields(log.Fields{
+ "db": dbID,
+ "hit": cacheHit,
+ }).WithError(err).Debug("cache get peers for database")
+ }()
+
+ if rawPeers, ok = peerList.Load(dbID); ok {
+ if peers, ok = rawPeers.(*kayak.Peers); ok {
+ cacheHit = true
+ return
+ }
+ }
+
+ // get peers using non-cache method
+ return getPeers(dbID, privKey)
+}
+
+func getPeers(dbID proto.DatabaseID, privKey *asymmetric.PrivateKey) (peers *kayak.Peers, err error) {
+ req := new(bp.GetDatabaseRequest)
+ req.Header.DatabaseID = dbID
+
+ defer func() {
+ log.WithFields(log.Fields{
+ "db": dbID,
+ "peers": peers,
+ }).WithError(err).Debug("get peers for database")
+ }()
+
+ if err = req.Sign(privKey); err != nil {
+ return
+ }
+
+ res := new(bp.GetDatabaseResponse)
+ if err = requestBP(route.BPDBGetDatabase, req, res); err != nil {
+ return
+ }
+
+ // verify response
+ if err = res.Verify(); err != nil {
+ return
+ }
+
+ peers = res.Header.InstanceMeta.Peers
+
+ // set peers in the updater cache
+ peerList.Store(dbID, peers)
+
+ return
+}
+
+func allocateConnAndSeq() (connID uint64, seqNo uint64) {
+ connIDLock.Lock()
+ defer connIDLock.Unlock()
+
+ if len(connIDAvail) == 0 {
+ // generate one
+ connID = randSource.Uint64()
+ seqNo = atomic.AddUint64(&globalSeqNo, 1)
+ return
+ }
+
+ // pop one conn
+ connID = connIDAvail[0]
+ connIDAvail = connIDAvail[1:]
+ seqNo = atomic.AddUint64(&globalSeqNo, 1)
+
+ return
+}
+
+func putBackConn(connID uint64) {
+ connIDLock.Lock()
+ defer connIDLock.Unlock()
+
+ connIDAvail = append(connIDAvail, connID)
+}
diff --git a/client/driver_test.go b/client/driver_test.go
index 162bb2ad2..f412b19f7 100644
--- a/client/driver_test.go
+++ b/client/driver_test.go
@@ -18,6 +18,7 @@ package client
import (
"path/filepath"
+ "sync/atomic"
"testing"
"github.com/CovenantSQL/CovenantSQL/route"
@@ -35,12 +36,15 @@ func TestInit(t *testing.T) {
stopTestService, confDir, err = startTestService()
So(err, ShouldBeNil)
defer stopTestService()
+ // fake driver not initialized
+ atomic.StoreUint32(&driverInitialized, 0)
err = Init(filepath.Join(confDir, "config.yaml"), []byte(""))
So(err, ShouldBeNil)
// test loaded block producer nodes
bps := route.GetBPs()
So(len(bps), ShouldBeGreaterThanOrEqualTo, 1)
//So(bps[0].ToRawNodeID().ToNodeID(), ShouldResemble, (*conf.GConf.KnownNodes)[0].ID)
+ stopPeersUpdater()
})
}
diff --git a/client/errors.go b/client/errors.go
index 28043ca20..ca89de944 100644
--- a/client/errors.go
+++ b/client/errors.go
@@ -16,9 +16,16 @@
package client
-import "errors"
+import "github.com/pkg/errors"
// Various errors the driver might returns.
var (
+ // ErrQueryInTransaction represents a read query is presented during user transaction.
ErrQueryInTransaction = errors.New("only write is supported during transaction")
+ // ErrNotInitialized represents the driver is not initialized yet.
+ ErrNotInitialized = errors.New("driver not initialized")
+ // ErrAlreadyInitialized represents the driver is already initialized.
+ ErrAlreadyInitialized = errors.New("driver already initialized")
+ // ErrInvalidRequestSeq defines invalid sequence no of request.
+ ErrInvalidRequestSeq = errors.New("invalid request sequence applied")
)
diff --git a/client/helper_test.go b/client/helper_test.go
index 59aafa303..ed267535a 100644
--- a/client/helper_test.go
+++ b/client/helper_test.go
@@ -25,6 +25,7 @@ import (
"path/filepath"
"runtime"
"sync"
+ "sync/atomic"
"time"
bp "github.com/CovenantSQL/CovenantSQL/blockproducer"
@@ -45,6 +46,11 @@ import (
wt "github.com/CovenantSQL/CovenantSQL/worker/types"
)
+const (
+ // PubKeyStorePath defines public cache store.
+ PubKeyStorePath = "./public.keystore"
+)
+
var (
rootHash = hash.Hash{}
)
@@ -207,7 +213,7 @@ func startTestService() (stopTestService func(), tempDir string, err error) {
block, err = createRandomBlock(rootHash, true)
// get database peers
- if peers, err = getPeers(1); err != nil {
+ if peers, err = genPeers(1); err != nil {
return
}
@@ -242,7 +248,7 @@ func initNode() (cleanupFunc func(), tempDir string, server *rpc.Server, err err
if tempDir, err = ioutil.TempDir("", "db_test_"); err != nil {
return
}
- log.Debugf("temp dir: %s", tempDir)
+ log.WithField("d", tempDir).Debug("created temp dir")
// init conf
_, testFile, _, _ := runtime.Caller(0)
@@ -260,7 +266,10 @@ func initNode() (cleanupFunc func(), tempDir string, server *rpc.Server, err err
log.Debugf("GConf: %#v", conf.GConf)
_, err = utils.CopyFile(privateKeyPath, conf.GConf.PrivateKeyFile)
if err != nil {
- log.Fatalf("Copy %s to %s failed: %v", privateKeyPath, conf.GConf.PrivateKeyFile, err)
+ log.WithFields(log.Fields{
+ "from": privateKeyPath,
+ "to": conf.GConf.PrivateKeyFile,
+ }).WithError(err).Fatal("copy private key failed")
return
}
// reset the once
@@ -276,17 +285,17 @@ func initNode() (cleanupFunc func(), tempDir string, server *rpc.Server, err err
}
// init rpc
- if server, err = rpc.NewServerWithService(rpc.ServiceMap{"DHT": dht}); err != nil {
+ if server, err = rpc.NewServerWithService(rpc.ServiceMap{route.DHTRPCName: dht}); err != nil {
return
}
// register bpdb service
- if err = server.RegisterService(bp.DBServiceName, &stubBPDBService{}); err != nil {
+ if err = server.RegisterService(route.BPDBRPCName, &stubBPDBService{}); err != nil {
return
}
// register fake chain service
- if err = server.RegisterService(bp.MainChainRPCName, &stubBPDBService{}); err != nil {
+ if err = server.RegisterService(route.BlockProducerRPCName, &stubBPDBService{}); err != nil {
return
}
@@ -305,6 +314,9 @@ func initNode() (cleanupFunc func(), tempDir string, server *rpc.Server, err err
server.Stop()
}
+ // fake database init already processed
+ atomic.StoreUint32(&driverInitialized, 1)
+
return
}
@@ -329,8 +341,6 @@ func createRandomBlock(parent hash.Hash, isGenesis bool) (b *ct.Block, err error
ParentHash: parent,
Timestamp: time.Now().UTC(),
},
- Signee: pub,
- Signature: nil,
},
Queries: make([]*hash.Hash, rand.Intn(10)+10),
}
@@ -391,7 +401,7 @@ func getKeys() (privKey *asymmetric.PrivateKey, pubKey *asymmetric.PublicKey, er
return
}
-func getPeers(term uint64) (peers *kayak.Peers, err error) {
+func genPeers(term uint64) (peers *kayak.Peers, err error) {
// get node id
var nodeID proto.NodeID
if nodeID, err = kms.GetLocalNodeID(); err != nil {
diff --git a/cmd/cql-adapter/README.md b/cmd/cql-adapter/README.md
index 38194e2a7..dbc4a3b2e 100644
--- a/cmd/cql-adapter/README.md
+++ b/cmd/cql-adapter/README.md
@@ -51,7 +51,7 @@ $ cql-utils -tool adapterconfgen -config config.yaml
ListenAddr (default: 0.0.0.0:4661): ⏎
CertificatePath (default: server.pem): ⏎
PrivateKeyPath (default: server-key.pem): ⏎
-VerifyCertificate (default: false): ⏎
+VerifyCertificate (default: true) (y/n): ⏎
ClientCAPath (default:): ⏎
AdminCerts (default:): ⏎
WriteCerts (default:): ⏎
@@ -120,8 +120,8 @@ $ cql-adapter -config config.yaml
```bash
// send query (linux)
curl -v https://127.0.0.1:4661/v1/query --insecure \
- --cert read.data.thunderdb.io.pem \
- --key read.data.thunderdb.io.key \
+ --cert read.data.covenantsql.io.pem \
+ --key read.data.covenantsql.io.key \
--form database=kucoin.GO.BTC \
--form query='select * from trades limit 10'
@@ -244,7 +244,7 @@ curl -v https://e.morenodes.com:11108/v1/query --insecure \
###### Parameters
-**node:** node count requirement for ThunderDB
+**node:** node count requirement for CovenantSQL
###### Response
diff --git a/cmd/cql-adapter/api/account.go b/cmd/cql-adapter/api/account.go
index 21dc3c35a..d06e49389 100644
--- a/cmd/cql-adapter/api/account.go
+++ b/cmd/cql-adapter/api/account.go
@@ -20,6 +20,7 @@ import (
"net/http"
"github.com/CovenantSQL/CovenantSQL/client"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
)
func init() {
@@ -35,7 +36,10 @@ type accountAPI struct{}
// StableCoinBalance defines query for stable coin balance.
func (a *accountAPI) StableCoinBalance(rw http.ResponseWriter, r *http.Request) {
- if balance, err := client.GetStableCoinBalance(); err != nil {
+ var balance uint64
+ var err error
+
+ if balance, err = client.GetStableCoinBalance(); err != nil {
sendResponse(http.StatusInternalServerError, false, err, nil, rw)
} else {
sendResponse(http.StatusOK, true, nil, map[string]interface{}{
@@ -43,12 +47,17 @@ func (a *accountAPI) StableCoinBalance(rw http.ResponseWriter, r *http.Request)
}, rw)
}
+ log.WithField("stableBalance", balance).WithError(err).Debug("get stable coin balance")
+
return
}
// CovenantCoinBalance defines query for covenant coin balance.
func (a *accountAPI) CovenantCoinBalance(rw http.ResponseWriter, r *http.Request) {
- if balance, err := client.GetCovenantCoinBalance(); err != nil {
+ var balance uint64
+ var err error
+
+ if balance, err = client.GetCovenantCoinBalance(); err != nil {
sendResponse(http.StatusInternalServerError, false, err, nil, rw)
} else {
sendResponse(http.StatusOK, true, nil, map[string]interface{}{
@@ -56,5 +65,7 @@ func (a *accountAPI) CovenantCoinBalance(rw http.ResponseWriter, r *http.Request
}, rw)
}
+ log.WithField("covenantBalance", balance).WithError(err).Debug("get covenant coin balance")
+
return
}
diff --git a/cmd/cql-adapter/api/admin.go b/cmd/cql-adapter/api/admin.go
index 2abd04d61..6ee4c2fe6 100644
--- a/cmd/cql-adapter/api/admin.go
+++ b/cmd/cql-adapter/api/admin.go
@@ -23,6 +23,7 @@ import (
"strconv"
"github.com/CovenantSQL/CovenantSQL/cmd/cql-adapter/config"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
)
func init() {
@@ -61,12 +62,20 @@ func (a *adminAPI) CreateDatabase(rw http.ResponseWriter, r *http.Request) {
nodeCntStr := r.FormValue("node")
nodeCnt, err := strconv.Atoi(nodeCntStr)
+ var dbID string
+
+ defer func() {
+ log.WithFields(log.Fields{
+ "nodeCnt": nodeCnt,
+ "db": dbID,
+ }).WithError(err).Debug("create database")
+ }()
+
if err != nil || nodeCnt <= 0 || nodeCnt >= math.MaxUint16 {
sendResponse(http.StatusBadRequest, false, "Invalid node count supplied", nil, rw)
return
}
- var dbID string
if dbID, err = config.GetConfig().StorageInstance.Create(nodeCnt); err != nil {
sendResponse(http.StatusInternalServerError, false, err, nil, rw)
return
@@ -80,11 +89,16 @@ func (a *adminAPI) CreateDatabase(rw http.ResponseWriter, r *http.Request) {
// DropDatabase defines drop database admin API.
func (a *adminAPI) DropDatabase(rw http.ResponseWriter, r *http.Request) {
var dbID string
+ var err error
+
+ defer func() {
+ log.WithField("db", dbID).WithError(err).Debug("drop database")
+ }()
+
if dbID = getDatabaseID(rw, r); dbID == "" {
return
}
- var err error
if err = config.GetConfig().StorageInstance.Drop(dbID); err != nil {
sendResponse(http.StatusInternalServerError, false, err, nil, rw)
return
diff --git a/cmd/cql-adapter/api/query.go b/cmd/cql-adapter/api/query.go
index 3cc5078f5..aed0b15de 100644
--- a/cmd/cql-adapter/api/query.go
+++ b/cmd/cql-adapter/api/query.go
@@ -47,7 +47,7 @@ func (a *queryAPI) Query(rw http.ResponseWriter, r *http.Request) {
return
}
- log.WithField("db", dbID).WithField("query", query).Infof("got query")
+ log.WithField("db", dbID).WithField("query", query).Info("got query")
assoc := r.FormValue("assoc")
@@ -136,7 +136,7 @@ func (a *queryAPI) Write(rw http.ResponseWriter, r *http.Request) {
return
}
- log.WithField("db", dbID).WithField("query", query).Infof("got exec")
+ log.WithField("db", dbID).WithField("query", query).Info("got exec")
var err error
if err = config.GetConfig().StorageInstance.Exec(dbID, query); err != nil {
diff --git a/cmd/cql-adapter/config/config.go b/cmd/cql-adapter/config/config.go
index 15b56a55c..debf4f5e7 100644
--- a/cmd/cql-adapter/config/config.go
+++ b/cmd/cql-adapter/config/config.go
@@ -59,7 +59,7 @@ type Config struct {
WriteCertificates []*x509.Certificate `yaml:"-"`
// storage config
- StorageDriver string `yaml:"StorageDriver"` // sqlite3 or ThunderDB
+ StorageDriver string `yaml:"StorageDriver"` // sqlite3 or covenantsql
StorageRoot string `yaml:"StorageRoot"`
StorageInstance storage.Storage `yaml:"-"`
}
@@ -73,17 +73,17 @@ func LoadConfig(configPath string, password string) (config *Config, err error)
var workingRoot string
var configBytes []byte
if configBytes, err = ioutil.ReadFile(configPath); err != nil {
- log.Errorf("read config file failed: %v", err)
+ log.WithError(err).Error("read config file failed")
}
configWrapper := &confWrapper{}
if err = yaml.Unmarshal(configBytes, configWrapper); err != nil {
- log.Errorf("unmarshal config file failed: %v", err)
+ log.WithError(err).Error("unmarshal config file failed")
return
}
if configWrapper.Adapter == nil {
err = ErrEmptyAdapterConfig
- log.Errorf("could not read adapter config: %v", err)
+ log.WithError(err).Error("could not read adapter config")
return
}
@@ -103,7 +103,7 @@ func LoadConfig(configPath string, password string) (config *Config, err error)
if config.CertificatePath == "" || config.PrivateKeyPath == "" {
err = ErrRequireServerCertificate
- log.Errorf("invalid adapter config: %v", err)
+ log.WithError(err).Error("invalid adapter config")
return
}
diff --git a/cmd/cql-adapter/main.go b/cmd/cql-adapter/main.go
index 1b356b7b0..570937371 100644
--- a/cmd/cql-adapter/main.go
+++ b/cmd/cql-adapter/main.go
@@ -19,8 +19,10 @@ package main
import (
"context"
"flag"
+ "fmt"
"os"
"os/signal"
+ "runtime"
"time"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
@@ -28,9 +30,13 @@ import (
"golang.org/x/sys/unix"
)
+const name = "cql-adapeter"
+
var (
- configFile string
- password string
+ version = "unknown"
+ configFile string
+ password string
+ showVersion bool
)
func init() {
@@ -38,26 +44,33 @@ func init() {
flag.StringVar(&password, "password", "", "master key password")
flag.BoolVar(&asymmetric.BypassSignature, "bypassSignature", false,
"Disable signature sign and verify, for testing")
+ flag.BoolVar(&showVersion, "version", false, "Show version information and exit")
}
func main() {
flag.Parse()
+ if showVersion {
+ fmt.Printf("%v %v %v %v %v\n",
+ name, version, runtime.GOOS, runtime.GOARCH, runtime.Version())
+ os.Exit(0)
+ }
+
flag.Visit(func(f *flag.Flag) {
- log.Infof("Args %s : %v", f.Name, f.Value)
+ log.Infof("Args %#v : %s", f.Name, f.Value)
})
server, err := NewHTTPAdapter(configFile, password)
if err != nil {
- log.Fatalf("init adapter failed: %v", err)
+ log.WithError(err).Fatal("init adapter failed")
return
}
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt, unix.SIGTERM)
- log.Infof("start adapter")
+ log.Info("start adapter")
if err = server.Serve(); err != nil {
- log.Fatalf("start adapter failed: %v", err)
+ log.WithError(err).Fatal("start adapter failed")
return
}
@@ -66,5 +79,5 @@ func main() {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
server.Shutdown(ctx)
- log.Infof("stopped adapter")
+ log.Info("stopped adapter")
}
diff --git a/cmd/cql-adapter/server.go b/cmd/cql-adapter/server.go
index 93090ab86..e8cc0c204 100644
--- a/cmd/cql-adapter/server.go
+++ b/cmd/cql-adapter/server.go
@@ -27,7 +27,7 @@ import (
"github.com/gorilla/handlers"
)
-// HTTPAdapter is a adapter for ThunderDB/alternative sqlite3 service.
+// HTTPAdapter is a adapter for covenantsql/alternative sqlite3 service.
type HTTPAdapter struct {
tlsConfig *tls.Config
server *http.Server
diff --git a/cmd/cql-adapter/storage/covenantsql.go b/cmd/cql-adapter/storage/covenantsql.go
index 14149d378..f5847d7b8 100644
--- a/cmd/cql-adapter/storage/covenantsql.go
+++ b/cmd/cql-adapter/storage/covenantsql.go
@@ -22,17 +22,17 @@ import (
"github.com/CovenantSQL/CovenantSQL/client"
)
-// ThunderDBStorage defines the thunderdb database abstraction.
-type ThunderDBStorage struct{}
+// CovenantSQLStorage defines the covenantsql database abstraction.
+type CovenantSQLStorage struct{}
-// NewCovenantSQLStorage returns new thunderdb storage handler.
-func NewCovenantSQLStorage() (s *ThunderDBStorage) {
- s = &ThunderDBStorage{}
+// NewCovenantSQLStorage returns new covenantsql storage handler.
+func NewCovenantSQLStorage() (s *CovenantSQLStorage) {
+ s = &CovenantSQLStorage{}
return
}
// Create implements the Storage abstraction interface.
-func (s *ThunderDBStorage) Create(nodeCnt int) (dbID string, err error) {
+func (s *CovenantSQLStorage) Create(nodeCnt int) (dbID string, err error) {
var dsn string
if dsn, err = client.Create(client.ResourceMeta{Node: uint16(nodeCnt)}); err != nil {
return
@@ -48,7 +48,7 @@ func (s *ThunderDBStorage) Create(nodeCnt int) (dbID string, err error) {
}
// Drop implements the Storage abstraction interface.
-func (s *ThunderDBStorage) Drop(dbID string) (err error) {
+func (s *CovenantSQLStorage) Drop(dbID string) (err error) {
cfg := client.NewConfig()
cfg.DatabaseID = dbID
err = client.Drop(cfg.FormatDSN())
@@ -56,7 +56,7 @@ func (s *ThunderDBStorage) Drop(dbID string) (err error) {
}
// Query implements the Storage abstraction interface.
-func (s *ThunderDBStorage) Query(dbID string, query string) (columns []string, types []string, result [][]interface{}, err error) {
+func (s *CovenantSQLStorage) Query(dbID string, query string) (columns []string, types []string, result [][]interface{}, err error) {
var conn *sql.DB
if conn, err = s.getConn(dbID); err != nil {
return
@@ -92,7 +92,7 @@ func (s *ThunderDBStorage) Query(dbID string, query string) (columns []string, t
}
// Exec implements the Storage abstraction interface.
-func (s *ThunderDBStorage) Exec(dbID string, query string) (err error) {
+func (s *CovenantSQLStorage) Exec(dbID string, query string) (err error) {
var conn *sql.DB
if conn, err = s.getConn(dbID); err != nil {
return
@@ -104,7 +104,7 @@ func (s *ThunderDBStorage) Exec(dbID string, query string) (err error) {
return
}
-func (s *ThunderDBStorage) getConn(dbID string) (db *sql.DB, err error) {
+func (s *CovenantSQLStorage) getConn(dbID string) (db *sql.DB, err error) {
cfg := client.NewConfig()
cfg.DatabaseID = dbID
diff --git a/cmd/cql-adapter/storage/sqlite3.go b/cmd/cql-adapter/storage/sqlite3.go
index e1311838c..f3a80f1af 100644
--- a/cmd/cql-adapter/storage/sqlite3.go
+++ b/cmd/cql-adapter/storage/sqlite3.go
@@ -24,7 +24,6 @@ import (
"math/rand"
"os"
"path/filepath"
-
// Import sqlite3 manually.
_ "github.com/CovenantSQL/go-sqlite3-encrypt"
)
@@ -130,7 +129,7 @@ func (s *SQLite3Storage) Exec(dbID string, query string) (err error) {
func (s *SQLite3Storage) getConn(dbID string, readonly bool) (db *sql.DB, err error) {
dbFile := filepath.Join(s.rootDir, dbID+".db3")
- dbDSN := fmt.Sprintf("file:%s?_journal_mode=WAL&_synchronous=FULL", dbFile)
+ dbDSN := fmt.Sprintf("file:%s?_journal_mode=WAL&_synchronous=NORMAL", dbFile)
if readonly {
dbDSN += "&mode=ro"
}
diff --git a/cmd/cql-explorer/README.md b/cmd/cql-explorer/README.md
new file mode 100644
index 000000000..6bce4872e
--- /dev/null
+++ b/cmd/cql-explorer/README.md
@@ -0,0 +1,182 @@
+This doc introduce the usage of CovenantSQL block producer chain explorer server.
+
+## Prerequisites
+
+Make sure the ```$GOPATH/bin``` is in your ```$PATH```, download/build the explorer binary.
+
+```shell
+$ go get github.com/CovenantSQL/CovenantSQL/cmd/cql-explorer
+```
+
+Adapter requires a CovenantSQL ```config.yaml``` which can by generated by configuration generator.
+
+### Generating Default Config File
+
+Generate the main configuration file. Same as [Generating Default Config File in Golang Client Doc](https://github.com/CovenantSQL/CovenantSQL/tree/develop/client#generating-default-config-file). An existing configuration file can also be used.
+
+## Explorer Usage
+
+### Start
+
+Start the explorer by following commands:
+
+```shell
+$ cql-explorer -config config.yaml
+```
+
+The available options are:
+
+```shell
+$ cql-explorer --help
+Usage of cql-explorer:
+ -config string
+ config file path (default "./config.yaml")
+ -interval duration
+ new block check interval for explorer (default 2s)
+ -listen string
+ listen address for http explorer api (default "127.0.0.1:4665")
+ -password string
+ master key password for covenantsql
+```
+
+### API
+
+#### Query Synced Head Block
+
+**GET** /v1/head
+
+##### Request
+
+##### Response
+
+```json
+{
+ "success" : true,
+ "status" : "ok",
+ "data" : {
+ "block" : {
+ "txs" : [],
+ "hash" : "20ba21af54da3e17252fb4b6b7331fb6f36aca1b9b793597af6ef46faad34dea",
+ "timestamp" : 1540278575120.34,
+ "version" : 1,
+ "count" : 561,
+ "producer" : "8d7604acfdb391891a4c795f0939425b6d58bd50a81e579d15f06ecd381ad549",
+ "height" : 3040488,
+ "parent" : "f9c4f9c7a1dcbcf14a13eb91a007b33672f1f8a261738f5a25fee27c3ccaa584"
+ }
+ }
+}
+```
+
+#### Query Block by _COUNT_
+
+**GET** /v1/count/{count}
+
+##### Request
+
+__count__: count of specified block, 0 for genesis block
+
+##### Response
+
+```json
+{
+ "success" : true,
+ "status" : "ok",
+ "data" : {
+ "block" : {
+ "version" : 1,
+ "height" : 0,
+ "count" : 0,
+ "timestamp" : 1534197599120,
+ "hash" : "f745ca6427237aac858dd3c7f2df8e6f3c18d0f1c164e07a1c6b8eebeba6b154",
+ "txs" : [],
+ "parent" : "0000000000000000000000000000000000000000000000000000000000000001",
+ "producer" : "0000000000000000000000000000000000000000000000000000000000000001"
+ }
+ }
+}
+```
+
+#### Query Block by _HASH_
+
+**GET** /v1/block/{hash}
+
+##### Request
+
+__hash__: hash of specified block
+
+##### Response
+
+```json
+{
+ "success" : true,
+ "status" : "ok",
+ "data" : {
+ "block" : {
+ "version" : 1,
+ "height" : 0,
+ "count" : 0,
+ "timestamp" : 1534197599120,
+ "hash" : "f745ca6427237aac858dd3c7f2df8e6f3c18d0f1c164e07a1c6b8eebeba6b154",
+ "txs" : [],
+ "parent" : "0000000000000000000000000000000000000000000000000000000000000001",
+ "producer" : "0000000000000000000000000000000000000000000000000000000000000001"
+ }
+ }
+}
+```
+
+#### Query Block by _HEIGHT_
+
+**GET** /v1/height/{height}
+
+##### Request
+
+__height__: height of specified block, 0 for genesis block (height is related to block produce time and interval)
+
+##### Response
+
+```json
+{
+ "success" : true,
+ "status" : "ok",
+ "data" : {
+ "block" : {
+ "version" : 1,
+ "height" : 0,
+ "count" : 0,
+ "timestamp" : 1534197599120,
+ "hash" : "f745ca6427237aac858dd3c7f2df8e6f3c18d0f1c164e07a1c6b8eebeba6b154",
+ "txs" : [],
+ "parent" : "0000000000000000000000000000000000000000000000000000000000000001",
+ "producer" : "0000000000000000000000000000000000000000000000000000000000000001"
+ }
+ }
+}
+```
+
+#### Query Transaction by _HASH_
+
+**GET** /v1/tx/{hash}
+
+##### Request
+
+__hash__: hash of specified tx
+
+##### Response
+
+```json
+{
+ "success": true,
+ "status": "ok",
+ "data": {
+ "tx": {
+ "nonce": 11616,
+ "amount": 1225,
+ "sender": "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9",
+ "receiver": "676b12fef8732ac78a97ea5dba0977bbbabc48f64eee66f09be89a589297e567",
+ "type": "Transfer"
+ }
+ }
+}
+```
\ No newline at end of file
diff --git a/cmd/cql-explorer/api.go b/cmd/cql-explorer/api.go
new file mode 100644
index 000000000..fb55c3366
--- /dev/null
+++ b/cmd/cql-explorer/api.go
@@ -0,0 +1,327 @@
+/*
+ * Copyright 2018 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 main
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "strconv"
+ "time"
+
+ pi "github.com/CovenantSQL/CovenantSQL/blockproducer/interfaces"
+ pt "github.com/CovenantSQL/CovenantSQL/blockproducer/types"
+ "github.com/CovenantSQL/CovenantSQL/crypto/hash"
+ "github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
+ "github.com/gorilla/mux"
+)
+
+var (
+ apiTimeout = time.Second * 10
+)
+
+func sendResponse(code int, success bool, msg interface{}, data interface{}, rw http.ResponseWriter) {
+ msgStr := "ok"
+ if msg != nil {
+ msgStr = fmt.Sprint(msg)
+ }
+ rw.WriteHeader(code)
+ json.NewEncoder(rw).Encode(map[string]interface{}{
+ "status": msgStr,
+ "success": success,
+ "data": data,
+ })
+}
+
+func sendError(err error, rw http.ResponseWriter) {
+ if err == ErrNotFound {
+ sendResponse(404, false, err, nil, rw)
+ } else if err == ErrBadRequest {
+ sendResponse(400, false, err, nil, rw)
+ } else if err != nil {
+ sendResponse(500, false, err, nil, rw)
+ } else {
+ sendResponse(200, true, nil, nil, rw)
+ }
+}
+
+func getUintFromVars(field string, r *http.Request) (value uint32, err error) {
+ vars := mux.Vars(r)
+ valueStr := vars[field]
+ if valueStr == "" {
+ err = ErrBadRequest
+ return
+ }
+
+ valueUint, err := strconv.ParseUint(valueStr, 10, 32)
+ if err != nil {
+ return
+ }
+
+ value = uint32(valueUint)
+
+ return
+}
+
+type explorerAPI struct {
+ service *Service
+}
+
+func (a *explorerAPI) GetHighestBlock(rw http.ResponseWriter, r *http.Request) {
+ count, err := a.service.getHighestCount()
+ if err != nil {
+ sendError(err, rw)
+ return
+ }
+
+ block, _, height, err := a.service.getBlockByCount(count)
+ if err != nil {
+ sendError(err, rw)
+ return
+ }
+
+ sendResponse(200, true, nil, a.formatBlock(count, height, block), rw)
+}
+
+func (a *explorerAPI) GetBlockByCount(rw http.ResponseWriter, r *http.Request) {
+ count, err := getUintFromVars("count", r)
+ if err != nil {
+ sendError(err, rw)
+ return
+ }
+
+ block, _, height, err := a.service.getBlockByCount(count)
+ if err != nil {
+ sendError(err, rw)
+ return
+ }
+
+ sendResponse(200, true, nil, a.formatBlock(count, height, block), rw)
+}
+
+func (a *explorerAPI) GetBlockByHeight(rw http.ResponseWriter, r *http.Request) {
+ height, err := getUintFromVars("height", r)
+ if err != nil {
+ sendError(err, rw)
+ return
+ }
+
+ block, count, _, err := a.service.getBlockByHeight(height)
+ if err != nil {
+ sendError(err, rw)
+ return
+ }
+
+ sendResponse(200, true, nil, a.formatBlock(count, height, block), rw)
+}
+
+func (a *explorerAPI) GetBlockByHash(rw http.ResponseWriter, r *http.Request) {
+ h, err := a.getHash(r)
+ if err != nil {
+ sendError(err, rw)
+ return
+ }
+
+ block, count, height, err := a.service.getBlockByHash(h)
+ if err != nil {
+ sendError(err, rw)
+ return
+ }
+
+ sendResponse(200, true, nil, a.formatBlock(count, height, block), rw)
+}
+
+func (a *explorerAPI) GetTxByHash(rw http.ResponseWriter, r *http.Request) {
+ h, err := a.getHash(r)
+ if err != nil {
+ sendError(err, rw)
+ return
+ }
+
+ tx, count, height, err := a.service.getTxByHash(h)
+ if err != nil {
+ sendError(err, rw)
+ return
+ }
+
+ sendResponse(200, true, nil, a.formatTx(count, height, tx), rw)
+}
+
+func (a *explorerAPI) formatTime(t time.Time) float64 {
+ return float64(t.UnixNano()) / 1e6
+}
+
+func (a *explorerAPI) formatBlock(count uint32, height uint32, b *pt.Block) map[string]interface{} {
+ txs := make([]map[string]interface{}, 0, len(b.Transactions))
+
+ for _, tx := range b.Transactions {
+ txs = append(txs, a.formatRawTx(tx))
+ }
+
+ return map[string]interface{}{
+ "block": map[string]interface{}{
+ "height": height,
+ "count": count,
+ "hash": b.BlockHash().String(),
+ "parent": b.ParentHash().String(),
+ "timestamp": a.formatTime(b.Timestamp()),
+ "version": b.SignedHeader.Version,
+ "producer": b.SignedHeader.Producer.String(),
+ "txs": txs,
+ },
+ }
+}
+
+func (a *explorerAPI) formatRawTx(t pi.Transaction) (res map[string]interface{}) {
+ if t == nil {
+ return nil
+ }
+
+ switch tx := t.(type) {
+ case *pt.Transfer:
+ res = map[string]interface{}{
+ "nonce": tx.Nonce,
+ "sender": tx.Sender.String(),
+ "receiver": tx.Receiver.String(),
+ "amount": tx.Amount,
+ }
+ case *pt.Billing:
+ res = a.formatTxBilling(tx)
+ case *pt.BaseAccount:
+ res = map[string]interface{}{
+ "next_nonce": tx.NextNonce,
+ "address": tx.Address,
+ "stable_balance": tx.StableCoinBalance,
+ "covenant_balance": tx.CovenantCoinBalance,
+ "rating": tx.Rating,
+ }
+ case *pi.TransactionWrapper:
+ res = a.formatRawTx(tx.Unwrap())
+ return
+ default:
+ // for unknown transactions
+ if txBytes, err := json.Marshal(tx); err != nil {
+ res = map[string]interface{}{
+ "error": err.Error(),
+ }
+ } else if err = json.Unmarshal(txBytes, &res); err != nil {
+ res = map[string]interface{}{
+ "error": err.Error(),
+ }
+ }
+ }
+
+ res["type"] = t.GetTransactionType().String()
+
+ return
+}
+
+func (a *explorerAPI) formatTxBilling(tx *pt.Billing) (res map[string]interface{}) {
+ if tx == nil {
+ return
+ }
+
+ return map[string]interface{}{
+ "nonce": tx.Nonce,
+ "producer": tx.Producer.String(),
+ "billing_request": func(br pt.BillingRequest) map[string]interface{} {
+ return map[string]interface{}{
+ "database_id": br.Header.DatabaseID,
+ "low_block": br.Header.LowBlock.String(),
+ "low_height": br.Header.LowHeight,
+ "high_block": br.Header.HighBlock.String(),
+ "high_height": br.Header.HighHeight,
+ "gas_amounts": func(gasAmounts []*proto.AddrAndGas) (d []map[string]interface{}) {
+ for _, g := range gasAmounts {
+ d = append(d, map[string]interface{}{
+ "address": g.AccountAddress.String(),
+ "node": g.RawNodeID.String(),
+ "amount": g.GasAmount,
+ })
+ }
+ return
+ }(br.Header.GasAmounts),
+ }
+ }(tx.BillingRequest),
+ "receivers": func(receivers []*proto.AccountAddress) (s []string) {
+ for _, r := range receivers {
+ s = append(s, r.String())
+ }
+ return
+ }(tx.Receivers),
+ "fees": tx.Fees,
+ "rewards": tx.Rewards,
+ }
+}
+
+func (a *explorerAPI) formatTx(count uint32, height uint32, tx pi.Transaction) map[string]interface{} {
+ var res map[string]interface{}
+
+ if res = a.formatRawTx(tx); res != nil {
+ res["height"] = height
+ res["count"] = count
+ }
+
+ return map[string]interface{}{
+ "tx": res,
+ }
+}
+
+func (a *explorerAPI) getHash(r *http.Request) (h *hash.Hash, err error) {
+ vars := mux.Vars(r)
+ hStr := vars["hash"]
+ return hash.NewHashFromStr(hStr)
+}
+
+func startAPI(service *Service, listenAddr string) (server *http.Server, err error) {
+ router := mux.NewRouter()
+ router.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
+ sendResponse(http.StatusOK, true, nil, nil, rw)
+ }).Methods("GET")
+
+ api := &explorerAPI{
+ service: service,
+ }
+ v1Router := router.PathPrefix("/v1").Subrouter()
+ v1Router.HandleFunc("/tx/{hash}", api.GetTxByHash).Methods("GET")
+ v1Router.HandleFunc("/height/{height:[0-9]+}", api.GetBlockByHeight).Methods("GET")
+ v1Router.HandleFunc("/block/{hash}", api.GetBlockByHash).Methods("GET")
+ v1Router.HandleFunc("/count/{count:[0-9]+}", api.GetBlockByCount).Methods("GET")
+ v1Router.HandleFunc("/head", api.GetHighestBlock).Methods("GET")
+
+ server = &http.Server{
+ Addr: listenAddr,
+ WriteTimeout: apiTimeout,
+ ReadTimeout: apiTimeout,
+ IdleTimeout: apiTimeout,
+ Handler: router,
+ }
+
+ go func() {
+ if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+ log.WithError(err).Fatal("start api server failed")
+ }
+ }()
+
+ return server, err
+}
+
+func stopAPI(server *http.Server) (err error) {
+ return server.Shutdown(context.Background())
+}
diff --git a/cmd/cql-explorer/errors.go b/cmd/cql-explorer/errors.go
new file mode 100644
index 000000000..22937dac8
--- /dev/null
+++ b/cmd/cql-explorer/errors.go
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 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 main
+
+import "github.com/pkg/errors"
+
+var (
+ // ErrNilBlock represents nil block received.
+ ErrNilBlock = errors.New("nil block received")
+ // ErrNilTransaction represents nil transaction received.
+ ErrNilTransaction = errors.New("nil transaction received")
+ // ErrStopped defines error on explorer service has already stopped
+ ErrStopped = errors.New("explorer service has stopped")
+ // ErrNotFound defines error on failed to found specified resource
+ ErrNotFound = errors.New("resource not found")
+ // ErrBadRequest defines errors on error input field.
+ ErrBadRequest = errors.New("request field not fulfilled")
+)
diff --git a/cmd/cql-explorer/main.go b/cmd/cql-explorer/main.go
new file mode 100644
index 000000000..171138d40
--- /dev/null
+++ b/cmd/cql-explorer/main.go
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2018 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 main
+
+import (
+ "flag"
+ "fmt"
+ "math/rand"
+ "net/http"
+ "os"
+ "os/signal"
+ "runtime"
+ "syscall"
+ "time"
+
+ "github.com/CovenantSQL/CovenantSQL/client"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
+)
+
+const name = "cql-explorer"
+
+var (
+ version = "unknown"
+)
+
+var (
+ // config
+ configFile string
+ password string
+ listenAddr string
+ checkInterval time.Duration
+ showVersion bool
+)
+
+func init() {
+ flag.StringVar(&configFile, "config", "./config.yaml", "config file path")
+ flag.StringVar(&listenAddr, "listen", "127.0.0.1:4665", "listen address for http explorer api")
+ flag.DurationVar(&checkInterval, "interval", time.Second*2, "new block check interval for explorer")
+ flag.StringVar(&password, "password", "", "master key password for covenantsql")
+ flag.BoolVar(&showVersion, "version", false, "Show version information and exit")
+}
+
+func main() {
+ // set random
+ rand.Seed(time.Now().UnixNano())
+ log.SetLevel(log.DebugLevel)
+ flag.Parse()
+ if showVersion {
+ fmt.Printf("%v %v %v %v %v\n",
+ name, version, runtime.GOOS, runtime.GOARCH, runtime.Version())
+ os.Exit(0)
+ }
+
+ flag.Visit(func(f *flag.Flag) {
+ log.Infof("Args %#v : %s", f.Name, f.Value)
+ })
+
+ // init client
+ var err error
+ if err = client.Init(configFile, []byte(password)); err != nil {
+ log.WithError(err).Fatal("init node failed")
+ return
+ }
+
+ // start service
+ var service *Service
+ if service, err = NewService(checkInterval); err != nil {
+ log.WithError(err).Fatal("init service failed")
+ return
+ }
+
+ // start api
+ var httpServer *http.Server
+ if httpServer, err = startAPI(service, listenAddr); err != nil {
+ log.WithError(err).Fatal("start explorer api failed")
+ return
+ }
+
+ // start subscription
+ if err = service.start(); err != nil {
+ log.WithError(err).Fatal("start service failed")
+ return
+ }
+
+ signalCh := make(chan os.Signal, 1)
+ signal.Notify(
+ signalCh,
+ syscall.SIGINT,
+ syscall.SIGTERM,
+ )
+ signal.Ignore(syscall.SIGHUP, syscall.SIGTTIN, syscall.SIGTTOU)
+
+ <-signalCh
+
+ // stop explorer api
+ if err = stopAPI(httpServer); err != nil {
+ log.WithError(err).Fatal("stop explorer api failed")
+ return
+ }
+
+ // stop subscription
+ if err = service.stop(); err != nil {
+ log.WithError(err).Fatal("stop service failed")
+ return
+ }
+
+ log.Info("explorer stopped")
+}
diff --git a/cmd/cql-explorer/service.go b/cmd/cql-explorer/service.go
new file mode 100644
index 000000000..0ccda7ff3
--- /dev/null
+++ b/cmd/cql-explorer/service.go
@@ -0,0 +1,460 @@
+/*
+ * Copyright 2018 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 main
+
+import (
+ "bytes"
+ "encoding/binary"
+ "path/filepath"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ bp "github.com/CovenantSQL/CovenantSQL/blockproducer"
+ pi "github.com/CovenantSQL/CovenantSQL/blockproducer/interfaces"
+ pt "github.com/CovenantSQL/CovenantSQL/blockproducer/types"
+ "github.com/CovenantSQL/CovenantSQL/conf"
+ "github.com/CovenantSQL/CovenantSQL/crypto/hash"
+ "github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/route"
+ "github.com/CovenantSQL/CovenantSQL/rpc"
+ "github.com/CovenantSQL/CovenantSQL/utils"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
+ "github.com/syndtr/goleveldb/leveldb"
+ "github.com/syndtr/goleveldb/leveldb/util"
+)
+
+const (
+ dbFileName = "explorer.db"
+)
+
+var (
+ // storage keys
+ blockKeyPrefix = []byte("BLOCK_")
+ blockHashPrefix = []byte("HASH_")
+ blockHeightPrefix = []byte("HEIGHT_")
+ txKeyPrefix = []byte("TX_")
+)
+
+// Service defines the main chain explorer service structure.
+type Service struct {
+ db *leveldb.DB
+
+ caller *rpc.Caller
+ stopped int32
+ stopCh chan struct{}
+ triggerCh chan struct{}
+ wg sync.WaitGroup
+
+ // new block check interval
+ checkInterval time.Duration
+
+ // next block to fetch
+ nextBlockToFetch uint32
+}
+
+// NewService creates new explorer service handler.
+func NewService(checkInterval time.Duration) (service *Service, err error) {
+ // open explorer database
+ dbFile := filepath.Join(conf.GConf.WorkingRoot, dbFileName)
+ db, err := leveldb.OpenFile(dbFile, nil)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ if err != nil {
+ db.Close()
+ }
+ }()
+
+ // init service
+ service = &Service{
+ db: db,
+ caller: rpc.NewCaller(),
+ stopCh: make(chan struct{}),
+ triggerCh: make(chan struct{}, 1),
+ checkInterval: checkInterval,
+ }
+
+ return
+}
+
+func (s *Service) start() (err error) {
+ if atomic.LoadInt32(&s.stopped) == 1 {
+ // stopped
+ return ErrStopped
+ }
+
+ if err = s.getSubscriptionCheckpoint(); err != nil {
+ return
+ }
+
+ // start subscription worker
+ s.wg.Add(1)
+ go s.subscriptionWorker()
+
+ return
+}
+
+func (s *Service) getBlockByCount(c uint32) (b *pt.Block, count uint32, height uint32, err error) {
+ var bKey []byte
+ bKey = append(bKey, blockKeyPrefix...)
+ bKey = append(bKey, uint32ToBytes(c)...)
+
+ it := s.db.NewIterator(util.BytesPrefix(bKey), nil)
+ if it.First() {
+ // decode
+ bKeyLen := len(bKey)
+ hBytes := it.Key()[bKeyLen : bKeyLen+4]
+ height = bytesToUint32(hBytes)
+ count = c
+ err = utils.DecodeMsgPack(it.Value(), &b)
+ } else {
+ // not found
+ err = ErrNotFound
+ }
+ it.Release()
+
+ if err != nil {
+ // ignore iterator error
+ it.Error()
+ return
+ }
+
+ err = it.Error()
+
+ return
+}
+
+func (s *Service) getBlockByHash(h *hash.Hash) (b *pt.Block, count uint32, height uint32, err error) {
+ if h == nil {
+ err = ErrNotFound
+ return
+ }
+
+ var bKey []byte
+ bKey = append(bKey, blockHashPrefix...)
+ bKey = append(bKey, h[:]...)
+
+ var bCountData []byte
+ if bCountData, err = s.db.Get(bKey, nil); err != nil {
+ if err == leveldb.ErrNotFound {
+ err = ErrNotFound
+ }
+ return
+ }
+
+ count = bytesToUint32(bCountData)
+ return s.getBlockByCount(count)
+}
+
+func (s *Service) getBlockByHeight(h uint32) (b *pt.Block, count uint32, height uint32, err error) {
+ var bKey []byte
+ bKey = append(bKey, blockHeightPrefix...)
+ bKey = append(bKey, uint32ToBytes(h)...)
+
+ var bCountData []byte
+ if bCountData, err = s.db.Get(bKey, nil); err != nil {
+ if err == leveldb.ErrNotFound {
+ err = ErrNotFound
+ }
+ return
+ }
+
+ count = bytesToUint32(bCountData)
+ return s.getBlockByCount(count)
+}
+
+func (s *Service) getTxByHash(h *hash.Hash) (tx pi.Transaction, c uint32, height uint32, err error) {
+ if h == nil {
+ err = ErrNotFound
+ return
+ }
+
+ var txKey []byte
+ txKey = append(txKey, txKeyPrefix...)
+ txKey = append(txKey, h[:]...)
+
+ var bCountData []byte
+ if bCountData, err = s.db.Get(txKeyPrefix, nil); err != nil {
+ if err == leveldb.ErrNotFound {
+ err = ErrNotFound
+ }
+ return
+ }
+
+ c = bytesToUint32(bCountData)
+
+ var b *pt.Block
+ if b, _, height, err = s.getBlockByCount(c); err != nil {
+ return
+ }
+
+ if b == nil || b.Transactions == nil {
+ err = ErrNotFound
+ return
+ }
+
+ for _, curTx := range b.Transactions {
+ if curTx == nil {
+ continue
+ }
+
+ if curH := curTx.GetHash(); h.IsEqual(&curH) {
+ tx = curTx
+ break
+ }
+ }
+
+ if tx == nil {
+ err = ErrNotFound
+ return
+ }
+
+ return
+}
+
+func (s *Service) getHighestCount() (c uint32, err error) {
+ // load previous committed counts
+ it := s.db.NewIterator(util.BytesPrefix(blockKeyPrefix), nil)
+ if it.Last() {
+ // decode block count from key
+ blockKey := it.Key()
+ prefixLen := len(blockKeyPrefix)
+ c = bytesToUint32(blockKey[prefixLen : prefixLen+4])
+ } else {
+ err = ErrNotFound
+ }
+ it.Release()
+
+ if err != nil {
+ it.Error()
+ return
+ }
+
+ err = it.Error()
+
+ return
+}
+
+func (s *Service) getSubscriptionCheckpoint() (err error) {
+ var lastBlockCount uint32
+ if lastBlockCount, err = s.getHighestCount(); err != nil {
+ log.WithError(err).Warning("get last block failed")
+
+ if err == ErrNotFound {
+ // not found, set last block count to 0
+ log.Info("set current block count fetch head to 0")
+ err = nil
+ atomic.StoreUint32(&s.nextBlockToFetch, 0)
+ }
+
+ return
+ }
+
+ log.WithFields(log.Fields{
+ "count": lastBlockCount,
+ }).Info("fetched last block count")
+
+ atomic.StoreUint32(&s.nextBlockToFetch, lastBlockCount+1)
+
+ return
+}
+
+func (s *Service) subscriptionWorker() {
+ defer s.wg.Done()
+
+ log.Info("started subscription worker")
+ for {
+ select {
+ case <-s.stopCh:
+ log.Info("exited subscription worker")
+ return
+ case <-s.triggerCh:
+ case <-time.After(s.checkInterval):
+ }
+
+ // request block producer for next block
+ s.requestBlock()
+ }
+}
+
+func (s *Service) requestBlock() {
+ if atomic.LoadInt32(&s.stopped) == 1 {
+ return
+ }
+
+ blockCount := atomic.LoadUint32(&s.nextBlockToFetch)
+ log.WithFields(log.Fields{"count": blockCount}).Info("try fetch next block")
+
+ req := &bp.FetchBlockByCountReq{Count: blockCount}
+ resp := &bp.FetchBlockResp{}
+
+ if err := s.requestBP(route.MCCFetchBlockByCount.String(), req, resp); err != nil {
+ // fetch block failed
+ log.WithError(err).Warning("fetch block failed,wait for next round")
+ return
+ }
+
+ // process block
+ if err := s.processBlock(blockCount, resp.Height, resp.Block); err != nil {
+ log.WithError(err).Warning("process block failed, try fetch/process again")
+ return
+ }
+
+ atomic.AddUint32(&s.nextBlockToFetch, 1)
+
+ // last fetch success, trigger next fetch for fast sync
+ select {
+ case s.triggerCh <- struct{}{}:
+ default:
+ }
+}
+
+func (s *Service) processBlock(c uint32, h uint32, b *pt.Block) (err error) {
+ if b == nil {
+ log.WithField("count", c).Warning("processed nil block")
+ return ErrNilBlock
+ }
+
+ log.WithFields(log.Fields{
+ "hash": b.BlockHash(),
+ "parent": b.ParentHash(),
+ "height": h,
+ "count": c,
+ }).Info("process new block")
+
+ if err = s.saveTransactions(c, b.Transactions); err != nil {
+ return
+ }
+
+ err = s.saveBlock(c, h, b)
+
+ return
+}
+
+func (s *Service) saveTransactions(c uint32, txs []pi.Transaction) (err error) {
+ if txs == nil || len(txs) == 0 {
+ return
+ }
+
+ for _, t := range txs {
+ if err = s.saveTransaction(c, t); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+func (s *Service) saveTransaction(c uint32, tx pi.Transaction) (err error) {
+ if tx == nil {
+ return ErrNilTransaction
+ }
+
+ txHash := tx.GetHash()
+
+ var txKey []byte
+
+ txKey = append(txKey, txKeyPrefix...)
+ txKey = append(txKey, txHash[:]...)
+ txData := uint32ToBytes(c)
+
+ err = s.db.Put(txKey, txData, nil)
+
+ return
+}
+
+func (s *Service) saveBlock(c uint32, h uint32, b *pt.Block) (err error) {
+ if b == nil {
+ return ErrNilBlock
+ }
+
+ bHash := b.BlockHash()
+
+ var buf *bytes.Buffer
+
+ if buf, err = utils.EncodeMsgPack(b); err != nil {
+ return
+ }
+
+ cBytes := uint32ToBytes(c)
+ hBytes := uint32ToBytes(h)
+
+ var bKey, bHashKey, bHeightKey []byte
+
+ bKey = append(bKey, blockKeyPrefix...)
+ bKey = append(bKey, cBytes...)
+ bKey = append(bKey, hBytes...)
+
+ bHashKey = append(bHashKey, blockHashPrefix...)
+ bHashKey = append(bHashKey, bHash[:]...)
+
+ bHeightKey = append(bHeightKey, blockHeightPrefix...)
+ bHeightKey = append(bHeightKey, hBytes...)
+
+ if err = s.db.Put(bKey, buf.Bytes(), nil); err != nil {
+ return
+ }
+
+ if err = s.db.Put(bHashKey, cBytes, nil); err != nil {
+ return
+ }
+
+ err = s.db.Put(bHeightKey, cBytes, nil)
+
+ return
+}
+
+func (s *Service) requestBP(method string, request interface{}, response interface{}) (err error) {
+ var bpNodeID proto.NodeID
+ if bpNodeID, err = rpc.GetCurrentBP(); err != nil {
+ return
+ }
+ return s.caller.CallNode(bpNodeID, method, request, response)
+}
+
+func (s *Service) stop() (err error) {
+ if !atomic.CompareAndSwapInt32(&s.stopped, 0, 1) {
+ // stopped
+ return ErrStopped
+ }
+
+ log.Info("stop subscription")
+
+ select {
+ case <-s.stopCh:
+ default:
+ close(s.stopCh)
+ }
+
+ s.wg.Wait()
+ s.db.Close()
+
+ return
+}
+
+func uint32ToBytes(h uint32) (data []byte) {
+ data = make([]byte, 4)
+ binary.BigEndian.PutUint32(data, h)
+ return
+}
+
+func bytesToUint32(data []byte) uint32 {
+ return binary.BigEndian.Uint32(data)
+}
diff --git a/cmd/cql-faucet/api.go b/cmd/cql-faucet/api.go
index 4025590c1..631a54598 100644
--- a/cmd/cql-faucet/api.go
+++ b/cmd/cql-faucet/api.go
@@ -159,7 +159,7 @@ func startAPI(v *Verifier, p *Persistence, listenAddr string) (server *http.Serv
go func() {
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
- log.Fatalf("start api server failed: %v", err)
+ log.WithError(err).Fatal("start api server failed")
}
}()
diff --git a/cmd/cql-faucet/config.go b/cmd/cql-faucet/config.go
index 7b2839cb3..7f30ba25b 100644
--- a/cmd/cql-faucet/config.go
+++ b/cmd/cql-faucet/config.go
@@ -46,19 +46,19 @@ type confWrapper struct {
func LoadConfig(configPath string) (config *Config, err error) {
var configBytes []byte
if configBytes, err = ioutil.ReadFile(configPath); err != nil {
- log.Errorf("read config file failed: %v", err)
+ log.WithError(err).Error("read config file failed")
return
}
configWrapper := &confWrapper{}
if err = yaml.Unmarshal(configBytes, configWrapper); err != nil {
- log.Errorf("unmarshal config file failed: %v", err)
+ log.WithError(err).Error("unmarshal config file failed")
return
}
if configWrapper.Faucet == nil {
err = ErrInvalidFaucetConfig
- log.Errorf("could not read faucet config: %v", err)
+ log.WithError(err).Error("could not read faucet config")
return
}
@@ -90,7 +90,7 @@ func LoadConfig(configPath string) (config *Config, err error) {
}
if config.AddressDailyQuota == 0 || config.AccountDailyQuota == 0 {
- log.Warningf("AddressDailyQuota & AccountDailyQuota should be valid positive number, 1 assumed")
+ log.Warning("AddressDailyQuota & AccountDailyQuota should be valid positive number, 1 assumed")
if config.AddressDailyQuota == 0 {
config.AddressDailyQuota = 1
@@ -103,7 +103,7 @@ func LoadConfig(configPath string) (config *Config, err error) {
}
if config.VerificationInterval.Nanoseconds() <= 0 {
- log.Warningf("a valid VerificationInterval is required, 30 seconds assumed")
+ log.Warning("a valid VerificationInterval is required, 30 seconds assumed")
config.VerificationInterval = 30 * time.Second
}
diff --git a/cmd/cql-faucet/main.go b/cmd/cql-faucet/main.go
index e9064c871..7f580285f 100644
--- a/cmd/cql-faucet/main.go
+++ b/cmd/cql-faucet/main.go
@@ -19,9 +19,11 @@ package main
import (
"context"
"flag"
+ "fmt"
"net/http"
"os"
"os/signal"
+ "runtime"
"time"
"github.com/CovenantSQL/CovenantSQL/client"
@@ -30,9 +32,13 @@ import (
"golang.org/x/sys/unix"
)
+const name = "cql-faucet"
+
var (
- configFile string
- password string
+ version = "unknown"
+ configFile string
+ password string
+ showVersion bool
)
func init() {
@@ -40,18 +46,25 @@ func init() {
flag.StringVar(&password, "password", "", "master key password for covenantsql")
flag.BoolVar(&asymmetric.BypassSignature, "bypassSignature", false,
"Disable signature sign and verify, for testing")
+ flag.BoolVar(&showVersion, "version", false, "Show version information and exit")
}
func main() {
flag.Parse()
+ if showVersion {
+ fmt.Printf("%v %v %v %v %v\n",
+ name, version, runtime.GOOS, runtime.GOARCH, runtime.Version())
+ os.Exit(0)
+ }
+
flag.Visit(func(f *flag.Flag) {
- log.Infof("Args %s : %v", f.Name, f.Value)
+ log.Infof("Args %#v : %s", f.Name, f.Value)
})
// init client
var err error
if err = client.Init(configFile, []byte(password)); err != nil {
- log.Errorf("init covenantsql client failed: %v", err)
+ log.WithError(err).Error("init covenantsql client failed")
os.Exit(-1)
return
}
@@ -60,7 +73,7 @@ func main() {
var cfg *Config
if cfg, err = LoadConfig(configFile); err != nil {
- log.Errorf("read faucet config failed: %v", err)
+ log.WithError(err).Error("read faucet config failed")
os.Exit(-1)
return
}
diff --git a/cmd/cql-faucet/persistence.go b/cmd/cql-faucet/persistence.go
index 961ece8e2..91a009030 100644
--- a/cmd/cql-faucet/persistence.go
+++ b/cmd/cql-faucet/persistence.go
@@ -26,7 +26,6 @@ import (
"github.com/CovenantSQL/CovenantSQL/conf"
"github.com/CovenantSQL/CovenantSQL/utils/log"
"github.com/satori/go.uuid"
-
// Load sqlite3 database driver.
_ "github.com/CovenantSQL/go-sqlite3-encrypt"
)
@@ -169,7 +168,7 @@ func (p *Persistence) checkAccountLimit(platform string, account string) (err er
log.WithFields(log.Fields{
"account": account,
"platform": platform,
- }).Errorf("daily account quota exceeded")
+ }).Error("daily account quota exceeded")
return ErrAccountQuotaExceeded
}
@@ -197,7 +196,7 @@ func (p *Persistence) checkAddressLimit(address string) (err error) {
// quota exceeded
log.WithFields(log.Fields{
"address": address,
- }).Errorf("daily address quota exceeded")
+ }).Error("daily address quota exceeded")
return ErrAddressQuotaExceeded
}
diff --git a/cmd/cql-faucet/verifier.go b/cmd/cql-faucet/verifier.go
index e3d53503e..aaefa1c30 100644
--- a/cmd/cql-faucet/verifier.go
+++ b/cmd/cql-faucet/verifier.go
@@ -31,7 +31,6 @@ import (
pt "github.com/CovenantSQL/CovenantSQL/blockproducer/types"
"github.com/CovenantSQL/CovenantSQL/crypto"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
- "github.com/CovenantSQL/CovenantSQL/crypto/hash"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
"github.com/CovenantSQL/CovenantSQL/proto"
"github.com/CovenantSQL/CovenantSQL/route"
@@ -103,14 +102,14 @@ func NewVerifier(cfg *Config, p *Persistence) (v *Verifier, err error) {
return
}
- log.Infof("vault address is: %v", hash.Hash(v.vaultAddress).String())
+ log.WithField("vault", v.vaultAddress.String()).Info("init verifier")
return
}
func (v *Verifier) run() {
for {
- log.Infof("begin verification iteration")
+ log.Info("begin verification iteration")
// fetch records
v.verify()
@@ -118,7 +117,7 @@ func (v *Verifier) run() {
// dispense
v.dispense()
- log.Infof("end verification iteration")
+ log.Info("end verification iteration")
select {
case <-time.After(v.interval):
@@ -143,7 +142,7 @@ func (v *Verifier) verify() {
defer wg.Done()
verified, err := f()
if err != nil {
- log.Warningf("verify applications failed: %v", err)
+ log.WithError(err).Warning("verify application failed")
ch <- verified
}
}
@@ -218,9 +217,9 @@ func (v *Verifier) dispenseOne(r *applicationRecord) (err error) {
// get current balance
if err = requestBP(route.MCCQueryAccountStableBalance.String(), balanceReq, balanceRes); err != nil {
- log.Warningf("get account balance failed: %v", err)
+ log.WithError(err).Warning("get account balance failed")
} else {
- log.Infof("get account balance success, balance: %v", balanceRes.Balance)
+ log.WithField("balance", balanceRes.Balance).Info("get account balance")
}
// allocate nonce
@@ -230,7 +229,7 @@ func (v *Verifier) dispenseOne(r *applicationRecord) (err error) {
if err = requestBP(route.MCCNextAccountNonce.String(), nonceReq, nonceResp); err != nil {
// allocate nonce failed
- log.Warningf("allocate nonce for transaction failed: %v", err)
+ log.WithError(err).Warning("allocate nonce for transaction failed")
return
}
@@ -243,7 +242,7 @@ func (v *Verifier) dispenseOne(r *applicationRecord) (err error) {
}
// log error
- log.Warningf("decode transfer target address failed: %v", err)
+ log.WithError(err).Warning("decode transfer target address failed")
// mark failed
r.failReason = err.Error()
@@ -252,32 +251,31 @@ func (v *Verifier) dispenseOne(r *applicationRecord) (err error) {
return
}
- log.WithFields(log.Fields(r.asMap())).Infof("dispensed application record failed")
+ log.WithFields(log.Fields(r.asMap())).Info("dispensed application record failed")
// skip invalid address faucet application
err = nil
return
}
- req := &bp.AddTxTransferReq{}
+ req := &bp.AddTxReq{}
resp := &bp.AddTxResp{}
- req.Tx = &pt.Transfer{
- TransferHeader: pt.TransferHeader{
+ req.Tx = pt.NewTransfer(
+ &pt.TransferHeader{
Sender: v.vaultAddress,
Receiver: targetAddress,
Nonce: nonceResp.Nonce,
Amount: uint64(r.tokenAmount),
},
- Signee: v.publicKey,
- }
+ )
if err = req.Tx.Sign(v.privateKey); err != nil {
// sign failed?
return
}
- if err = requestBP(route.MCCAddTxTransfer.String(), req, resp); err != nil {
+ if err = requestBP(route.MCCAddTx.String(), req, resp); err != nil {
// add transaction failed, try again
- log.Warningf("send transaction failed: %v", err)
+ log.WithError(err).Warning("send transaction failed")
return
}
@@ -290,7 +288,7 @@ func (v *Verifier) dispenseOne(r *applicationRecord) (err error) {
return
}
- log.WithFields(log.Fields(r.asMap())).Infof("dispensed application record")
+ log.WithFields(log.Fields(r.asMap())).Info("dispensed application record")
return
}
@@ -309,7 +307,7 @@ func (v *Verifier) doVerify(records []*applicationRecord, verifyFunc func(string
return
}
- log.WithFields(log.Fields(r.asMap())).Infof("verified application record")
+ log.WithFields(log.Fields(r.asMap())).Info("verified application record")
verified = r.rowID
}
diff --git a/cmd/cql-minerd/benchGNTE.sh b/cmd/cql-minerd/benchGNTE.sh
new file mode 100755
index 000000000..b26b2d207
--- /dev/null
+++ b/cmd/cql-minerd/benchGNTE.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+../../build.sh && \
+go test -bench=^BenchmarkMinerGNTE1$ -benchtime=10s -run ^$ && \
+go test -bench=^BenchmarkMinerGNTE2$ -benchtime=10s -run ^$ && \
+go test -bench=^BenchmarkMinerGNTE3$ -benchtime=10s -run ^$ && \
+go test -bench=^BenchmarkMinerGNTE4$ -benchtime=10s -run ^$ && \
+go test -bench=^BenchmarkMinerGNTE8$ -benchtime=10s -run ^$
diff --git a/cmd/cql-minerd/dbms.go b/cmd/cql-minerd/dbms.go
index 8616cf3d6..c2b712304 100644
--- a/cmd/cql-minerd/dbms.go
+++ b/cmd/cql-minerd/dbms.go
@@ -18,7 +18,6 @@ package main
import (
"bytes"
- "errors"
"io/ioutil"
"math/rand"
"os"
@@ -36,6 +35,7 @@ import (
"github.com/CovenantSQL/CovenantSQL/utils"
"github.com/CovenantSQL/CovenantSQL/worker"
wt "github.com/CovenantSQL/CovenantSQL/worker/types"
+ "github.com/pkg/errors"
)
var rootHash = hash.Hash{}
@@ -53,10 +53,12 @@ func startDBMS(server *rpc.Server) (dbms *worker.DBMS, err error) {
}
if dbms, err = worker.NewDBMS(cfg); err != nil {
+ err = errors.Wrap(err, "create new DBMS failed")
return
}
if err = dbms.Init(); err != nil {
+ err = errors.Wrap(err, "init DBMS failed")
return
}
@@ -68,9 +70,11 @@ func startDBMS(server *rpc.Server) (dbms *worker.DBMS, err error) {
var privKey *asymmetric.PrivateKey
if pubKey, err = kms.GetLocalPublicKey(); err != nil {
+ err = errors.Wrap(err, "get local public key failed")
return
}
if privKey, err = kms.GetLocalPrivateKey(); err != nil {
+ err = errors.Wrap(err, "get local private key failed")
return
}
@@ -102,12 +106,14 @@ func startDBMS(server *rpc.Server) (dbms *worker.DBMS, err error) {
}
if err = dbPeers.Sign(privKey); err != nil {
+ err = errors.Wrap(err, "sign peers failed")
return
}
// load genesis block
var block *ct.Block
if block, err = loadGenesisBlock(testFixture); err != nil {
+ err = errors.Wrap(err, "load genesis block failed")
return
}
@@ -118,6 +124,7 @@ func startDBMS(server *rpc.Server) (dbms *worker.DBMS, err error) {
GenesisBlock: block,
}
if err = dbms.Create(instance, false); err != nil {
+ err = errors.Wrap(err, "add new DBMS failed")
return
}
}
@@ -134,18 +141,21 @@ func loadGenesisBlock(fixture *conf.MinerDatabaseFixture) (block *ct.Block, err
var blockBytes []byte
if blockBytes, err = ioutil.ReadFile(fixture.GenesisBlockFile); err == nil {
+ err = errors.Wrap(err, "read block failed")
return
}
if os.IsNotExist(err) && fixture.AutoGenerateGenesisBlock {
// generate
if block, err = createRandomBlock(rootHash, true); err != nil {
+ err = errors.Wrap(err, "create random block failed")
return
}
// encode block
var bytesBuffer *bytes.Buffer
if bytesBuffer, err = utils.EncodeMsgPack(block); err != nil {
+ err = errors.Wrap(err, "encode block failed")
return
}
@@ -181,8 +191,6 @@ func createRandomBlock(parent hash.Hash, isGenesis bool) (b *ct.Block, err error
ParentHash: parent,
Timestamp: time.Now().UTC(),
},
- Signee: pub,
- Signature: nil,
},
Queries: make([]*hash.Hash, rand.Intn(10)+10),
}
diff --git a/cmd/cql-minerd/integration_test.go b/cmd/cql-minerd/integration_test.go
index 86b2a068c..60024948c 100644
--- a/cmd/cql-minerd/integration_test.go
+++ b/cmd/cql-minerd/integration_test.go
@@ -21,15 +21,17 @@ package main
import (
"context"
"database/sql"
+ "io/ioutil"
+ "math/rand"
"os"
+ "os/exec"
"path/filepath"
"sync"
+ "sync/atomic"
"syscall"
"testing"
"time"
- "os/exec"
-
"github.com/CovenantSQL/CovenantSQL/client"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/utils"
@@ -47,27 +49,11 @@ var nodeCmds []*utils.CMD
var FJ = filepath.Join
-func TestBuild(t *testing.T) {
- Convey("build", t, func() {
- log.SetLevel(log.DebugLevel)
- So(utils.Build(), ShouldBeNil)
- })
-}
-
func startNodes() {
ctx := context.Background()
// wait for ports to be available
var err error
- err = utils.WaitForPorts(ctx, "127.0.0.1", []int{
- 2144,
- 2145,
- 2146,
- }, time.Millisecond*200)
-
- if err != nil {
- log.Fatalf("wait for port ready timeout: %v", err)
- }
err = utils.WaitForPorts(ctx, "127.0.0.1", []int{
3122,
@@ -86,7 +72,7 @@ func startNodes() {
[]string{"-config", FJ(testWorkingDir, "./integration/node_0/config.yaml"),
"-test.coverprofile", FJ(baseDir, "./cmd/cql-minerd/leader.cover.out"),
},
- "leader", testWorkingDir, logDir, false,
+ "leader", testWorkingDir, logDir, true,
); err == nil {
nodeCmds = append(nodeCmds, cmd)
} else {
@@ -115,7 +101,31 @@ func startNodes() {
log.Errorf("start node failed: %v", err)
}
- time.Sleep(time.Second * 3)
+ ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
+ defer cancel()
+ err = utils.WaitToConnect(ctx, "127.0.0.1", []int{
+ 3122,
+ 3121,
+ 3120,
+ }, time.Second)
+
+ if err != nil {
+ log.Fatalf("wait for port ready timeout: %v", err)
+ }
+
+ ctx, cancel = context.WithTimeout(context.Background(), time.Second*30)
+ defer cancel()
+ err = utils.WaitForPorts(ctx, "127.0.0.1", []int{
+ 2144,
+ 2145,
+ 2146,
+ }, time.Millisecond*200)
+
+ if err != nil {
+ log.Fatalf("wait for port ready timeout: %v", err)
+ }
+
+ time.Sleep(10 * time.Second)
// start 3miners
os.RemoveAll(FJ(testWorkingDir, "./integration/node_miner_0/data"))
@@ -124,7 +134,7 @@ func startNodes() {
[]string{"-config", FJ(testWorkingDir, "./integration/node_miner_0/config.yaml"),
"-test.coverprofile", FJ(baseDir, "./cmd/cql-minerd/miner0.cover.out"),
},
- "miner0", testWorkingDir, logDir, false,
+ "miner0", testWorkingDir, logDir, true,
); err == nil {
nodeCmds = append(nodeCmds, cmd)
} else {
@@ -230,6 +240,10 @@ func startNodesProfile(bypassSign bool) {
FJ(baseDir, "./bin/cql-minerd"),
[]string{"-config", FJ(testWorkingDir, "./integration/node_miner_0/config.yaml"),
"-cpu-profile", FJ(baseDir, "./cmd/cql-minerd/miner0.profile"),
+ "-traceFile", FJ(baseDir, "./cmd/cql-minerd/miner0.trace"),
+ "-metricGraphiteServer", "192.168.2.100:2003",
+ "-profileServer", "0.0.0.0:8080",
+ "-metricLog",
bypassArg,
},
"miner0", testWorkingDir, logDir, false,
@@ -244,6 +258,10 @@ func startNodesProfile(bypassSign bool) {
FJ(baseDir, "./bin/cql-minerd"),
[]string{"-config", FJ(testWorkingDir, "./integration/node_miner_1/config.yaml"),
"-cpu-profile", FJ(baseDir, "./cmd/cql-minerd/miner1.profile"),
+ "-traceFile", FJ(baseDir, "./cmd/cql-minerd/miner1.trace"),
+ "-metricGraphiteServer", "192.168.2.100:2003",
+ "-profileServer", "0.0.0.0:8081",
+ "-metricLog",
bypassArg,
},
"miner1", testWorkingDir, logDir, false,
@@ -258,6 +276,10 @@ func startNodesProfile(bypassSign bool) {
FJ(baseDir, "./bin/cql-minerd"),
[]string{"-config", FJ(testWorkingDir, "./integration/node_miner_2/config.yaml"),
"-cpu-profile", FJ(baseDir, "./cmd/cql-minerd/miner2.profile"),
+ "-traceFile", FJ(baseDir, "./cmd/cql-minerd/miner2.trace"),
+ "-metricGraphiteServer", "192.168.2.100:2003",
+ "-profileServer", "0.0.0.0:8082",
+ "-metricLog",
bypassArg,
},
"miner2", testWorkingDir, logDir, false,
@@ -294,9 +316,12 @@ func TestFullProcess(t *testing.T) {
Convey("test full process", t, func() {
startNodes()
defer stopNodes()
- time.Sleep(5 * time.Second)
-
var err error
+
+ time.Sleep(10 * time.Second)
+
+ So(err, ShouldBeNil)
+
err = client.Init(FJ(testWorkingDir, "./integration/node_c/config.yaml"), []byte(""))
So(err, ShouldBeNil)
@@ -364,7 +389,7 @@ func TestFullProcess(t *testing.T) {
})
}
-func benchDB(b *testing.B, db *sql.DB) {
+func prepareBenchTable(db *sql.DB) {
_, err := db.Exec("DROP TABLE IF EXISTS test;")
So(err, ShouldBeNil)
@@ -376,14 +401,26 @@ func benchDB(b *testing.B, db *sql.DB) {
_, err = db.Exec("INSERT INTO test VALUES(?, ?)", 4, 4)
So(err, ShouldBeNil)
+}
+
+func benchDB(b *testing.B, db *sql.DB, createDB bool) {
+ var err error
+ if createDB {
+ prepareBenchTable(db)
+ }
+ var i int32
var insertedCount int
- b.Run("benchmark INSERT", func(b *testing.B) {
+
+ rand.Seed(time.Now().UnixNano())
+ start := (rand.Int31() % 100) * 10000
+
+ b.Run("benchmark Single INSERT", func(b *testing.B) {
b.ResetTimer()
insertedCount = b.N
for i := 0; i < b.N; i++ {
_, err = db.Exec("INSERT INTO test ( indexedColumn, nonIndexedColumn ) VALUES"+
- "(?, ?)", i, i,
+ "(?, ?)", int(start)+i, i,
)
if err != nil {
b.Fatal(err)
@@ -391,6 +428,26 @@ func benchDB(b *testing.B, db *sql.DB) {
}
})
+ if createDB {
+ prepareBenchTable(db)
+ }
+
+ b.Run("benchmark Multi INSERT", func(b *testing.B) {
+ b.ResetTimer()
+ insertedCount = b.N
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ ii := atomic.AddInt32(&i, 1)
+ _, err = db.Exec("INSERT INTO test ( indexedColumn, nonIndexedColumn ) VALUES"+
+ "(?, ?)", start+ii, ii,
+ )
+ if err != nil {
+ b.Fatal(err)
+ }
+ }
+ })
+ })
+
rowCount := db.QueryRow("SELECT COUNT(1) FROM test")
var count int
err = rowCount.Scan(&count)
@@ -402,7 +459,8 @@ func benchDB(b *testing.B, db *sql.DB) {
b.Run("benchmark SELECT", func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
- row := db.QueryRow("SELECT nonIndexedColumn FROM test WHERE indexedColumn = ? LIMIT 1", i%insertedCount)
+ index := i%insertedCount + int(start) + 1
+ row := db.QueryRow("SELECT nonIndexedColumn FROM test WHERE indexedColumn = ? LIMIT 1", index)
var result int
err = row.Scan(&result)
if err != nil || result < 0 {
@@ -426,23 +484,56 @@ func benchDB(b *testing.B, db *sql.DB) {
func benchMiner(b *testing.B, minerCount uint16, bypassSign bool) {
log.Warnf("Benchmark for %d Miners, BypassSignature: %v", minerCount, bypassSign)
asymmetric.BypassSignature = bypassSign
- startNodesProfile(bypassSign)
- time.Sleep(5 * time.Second)
+ if minerCount > 0 {
+ startNodesProfile(bypassSign)
+ utils.WaitToConnect(context.Background(), "127.0.0.1", []int{
+ 2144,
+ 2145,
+ 2146,
+ 3122,
+ 3121,
+ 3120,
+ }, 2*time.Second)
+ time.Sleep(time.Second)
+ }
- var err error
- err = client.Init(FJ(testWorkingDir, "./integration/node_c/config.yaml"), []byte(""))
+ // Create temp directory
+ testDataDir, err := ioutil.TempDir(testWorkingDir, "covenantsql")
+ if err != nil {
+ panic(err)
+ }
+ defer os.RemoveAll(testDataDir)
+ clientConf := FJ(testWorkingDir, "./integration/node_c/config.yaml")
+ tempConf := FJ(testDataDir, "config.yaml")
+ clientKey := FJ(testWorkingDir, "./integration/node_c/private.key")
+ tempKey := FJ(testDataDir, "private.key")
+ utils.CopyFile(clientConf, tempConf)
+ utils.CopyFile(clientKey, tempKey)
+
+ err = client.Init(tempConf, []byte(""))
So(err, ShouldBeNil)
- // create
- dsn, err := client.Create(client.ResourceMeta{Node: minerCount})
- So(err, ShouldBeNil)
+ dsnFile := FJ(baseDir, "./cmd/cql-minerd/.dsn")
+ var dsn string
+ if minerCount > 0 {
+ // create
+ dsn, err = client.Create(client.ResourceMeta{Node: minerCount})
+ So(err, ShouldBeNil)
- log.Infof("the created database dsn is %v", dsn)
+ log.Infof("the created database dsn is %v", dsn)
+ err = ioutil.WriteFile(dsnFile, []byte(dsn), 0666)
+ if err != nil {
+ log.Errorf("write .dsn failed: %v", err)
+ }
+ defer os.Remove(dsnFile)
+ } else {
+ dsn = os.Getenv("DSN")
+ }
db, err := sql.Open("covenantsql", dsn)
So(err, ShouldBeNil)
- benchDB(b, db)
+ benchDB(b, db, minerCount > 0)
err = client.Drop(dsn)
So(err, ShouldBeNil)
@@ -454,17 +545,65 @@ func BenchmarkSQLite(b *testing.B) {
os.Remove("./foo.db")
defer os.Remove("./foo.db")
- db, err := sql.Open("sqlite3", "./foo.db")
+ db, err := sql.Open("sqlite3", "./foo.db?_journal_mode=WAL&_synchronous=NORMAL&cache=shared")
if err != nil {
log.Fatal(err)
}
defer db.Close()
Convey("bench SQLite", b, func() {
- benchDB(b, db)
+ benchDB(b, db, true)
})
}
+func benchGNTEMiner(b *testing.B, minerCount uint16, bypassSign bool) {
+ log.Warnf("Benchmark GNTE for %d Miners, BypassSignature: %v", minerCount, bypassSign)
+ asymmetric.BypassSignature = bypassSign
+
+ // Create temp directory
+ testDataDir, err := ioutil.TempDir(testWorkingDir, "covenantsql")
+ if err != nil {
+ panic(err)
+ }
+ defer os.RemoveAll(testDataDir)
+ clientConf := FJ(testWorkingDir, "./GNTE/conf/node_c/config.yaml")
+ tempConf := FJ(testDataDir, "config.yaml")
+ clientKey := FJ(testWorkingDir, "./GNTE/conf/node_c/private.key")
+ tempKey := FJ(testDataDir, "private.key")
+ utils.CopyFile(clientConf, tempConf)
+ utils.CopyFile(clientKey, tempKey)
+
+ err = client.Init(tempConf, []byte(""))
+ So(err, ShouldBeNil)
+
+ dsnFile := FJ(baseDir, "./cmd/cql-minerd/.dsn")
+ var dsn string
+ if minerCount > 0 {
+ // create
+ dsn, err = client.Create(client.ResourceMeta{Node: minerCount})
+ So(err, ShouldBeNil)
+
+ log.Infof("the created database dsn is %v", dsn)
+ err = ioutil.WriteFile(dsnFile, []byte(dsn), 0666)
+ if err != nil {
+ log.Errorf("write .dsn failed: %v", err)
+ }
+ defer os.Remove(dsnFile)
+ } else {
+ dsn = os.Getenv("DSN")
+ }
+
+ db, err := sql.Open("covenantsql", dsn)
+ So(err, ShouldBeNil)
+
+ benchDB(b, db, minerCount > 0)
+
+ err = client.Drop(dsn)
+ So(err, ShouldBeNil)
+ time.Sleep(5 * time.Second)
+ stopNodes()
+}
+
func BenchmarkMinerOneNoSign(b *testing.B) {
Convey("bench single node", b, func() {
benchMiner(b, 1, true)
@@ -500,3 +639,38 @@ func BenchmarkMinerThree(b *testing.B) {
benchMiner(b, 3, false)
})
}
+
+func BenchmarkClientOnly(b *testing.B) {
+ Convey("bench three node", b, func() {
+ benchMiner(b, 0, false)
+ })
+}
+
+func BenchmarkMinerGNTE1(b *testing.B) {
+ Convey("bench GNTE one node", b, func() {
+ benchGNTEMiner(b, 1, false)
+ })
+}
+func BenchmarkMinerGNTE2(b *testing.B) {
+ Convey("bench GNTE two node", b, func() {
+ benchGNTEMiner(b, 2, false)
+ })
+}
+
+func BenchmarkMinerGNTE3(b *testing.B) {
+ Convey("bench GNTE three node", b, func() {
+ benchGNTEMiner(b, 3, false)
+ })
+}
+
+func BenchmarkMinerGNTE4(b *testing.B) {
+ Convey("bench GNTE three node", b, func() {
+ benchGNTEMiner(b, 4, false)
+ })
+}
+
+func BenchmarkMinerGNTE8(b *testing.B) {
+ Convey("bench GNTE three node", b, func() {
+ benchGNTEMiner(b, 8, false)
+ })
+}
diff --git a/cmd/cql-minerd/main.go b/cmd/cql-minerd/main.go
index 893ee6c90..1da8ac364 100644
--- a/cmd/cql-minerd/main.go
+++ b/cmd/cql-minerd/main.go
@@ -20,11 +20,13 @@ import (
"flag"
"fmt"
"math/rand"
+ "net"
"net/http"
_ "net/http/pprof"
"os"
"os/signal"
"runtime"
+ "runtime/trace"
"syscall"
"time"
@@ -32,12 +34,13 @@ import (
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
"github.com/CovenantSQL/CovenantSQL/metric"
- "github.com/CovenantSQL/CovenantSQL/proto"
"github.com/CovenantSQL/CovenantSQL/route"
"github.com/CovenantSQL/CovenantSQL/rpc"
"github.com/CovenantSQL/CovenantSQL/utils"
"github.com/CovenantSQL/CovenantSQL/utils/log"
"github.com/CovenantSQL/CovenantSQL/worker"
+ "github.com/cyberdelia/go-metrics-graphite"
+ "github.com/rcrowley/go-metrics"
)
const logo = `
@@ -58,20 +61,21 @@ const logo = `
`
var (
- version = "1"
- commit = "unknown"
- branch = "unknown"
+ version = "unknown"
)
var (
// config
configFile string
genKeyPair bool
+ metricLog bool
// profile
- cpuProfile string
- memProfile string
- profileServer string
+ cpuProfile string
+ memProfile string
+ profileServer string
+ metricGraphite string
+ traceFile string
// other
noLogo bool
@@ -83,6 +87,7 @@ const desc = `CovenantSQL is a Distributed Database running on BlockChain`
func init() {
flag.BoolVar(&noLogo, "nologo", false, "Do not print logo")
+ flag.BoolVar(&metricLog, "metricLog", false, "Print metrics in log")
flag.BoolVar(&showVersion, "version", false, "Show version information and exit")
flag.BoolVar(&genKeyPair, "genKeyPair", false, "Gen new key pair when no private key found")
flag.BoolVar(&asymmetric.BypassSignature, "bypassSignature", false,
@@ -93,6 +98,8 @@ func init() {
flag.StringVar(&profileServer, "profileServer", "", "Profile server address, default not started")
flag.StringVar(&cpuProfile, "cpu-profile", "", "Path to file for CPU profiling information")
flag.StringVar(&memProfile, "mem-profile", "", "Path to file for memory profiling information")
+ flag.StringVar(&metricGraphite, "metricGraphiteServer", "", "Metric graphite server to push metrics")
+ flag.StringVar(&traceFile, "traceFile", "", "trace profile")
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "\n%s\n\n", desc)
@@ -102,34 +109,41 @@ func init() {
}
func initLogs() {
- log.Infof("%s starting, version %s, commit %s, branch %s", name, version, commit, branch)
- log.Infof("%s, target architecture is %s, operating system target is %s", runtime.Version(), runtime.GOARCH, runtime.GOOS)
- log.Infof("role: %s", conf.RoleTag)
+ log.Infof("%#v starting, version %#v", name, version)
+ log.Infof("%#v, target architecture is %#v, operating system target is %#v", runtime.Version(), runtime.GOARCH, runtime.GOOS)
+ log.Infof("role: %#v", conf.RoleTag)
}
func main() {
// set random
rand.Seed(time.Now().UnixNano())
- log.SetLevel(log.InfoLevel)
+ log.SetLevel(log.DebugLevel)
flag.Parse()
+
+ if showVersion {
+ fmt.Printf("%v %v %v %v %v\n",
+ name, version, runtime.GOOS, runtime.GOARCH, runtime.Version())
+ os.Exit(0)
+ }
+
flag.Visit(func(f *flag.Flag) {
- log.Infof("Args %s : %v", f.Name, f.Value)
+ log.Infof("Args %#v : %s", f.Name, f.Value)
})
var err error
conf.GConf, err = conf.LoadConfig(configFile)
if err != nil {
- log.Fatalf("load config from %s failed: %s", configFile, err)
+ log.WithField("config", configFile).WithError(err).Fatal("load config failed")
}
if conf.GConf.Miner == nil {
- log.Fatalf("miner config does not exists")
+ log.Fatal("miner config does not exists")
}
if conf.GConf.Miner.MetricCollectInterval.Seconds() <= 0 {
- log.Fatalf("miner metric collect interval is invalid")
+ log.Fatal("miner metric collect interval is invalid")
}
if conf.GConf.Miner.MaxReqTimeGap.Seconds() <= 0 {
- log.Fatalf("miner request time gap is invalid")
+ log.Fatal("miner request time gap is invalid")
}
kms.InitBP()
@@ -138,12 +152,6 @@ func main() {
// init log
initLogs()
- if showVersion {
- log.Infof("%s %s %s %s %s (commit %s, branch %s)",
- name, version, runtime.GOOS, runtime.GOARCH, runtime.Version(), commit, branch)
- os.Exit(0)
- }
-
if !noLogo {
fmt.Print(logo)
}
@@ -158,12 +166,12 @@ func main() {
// start rpc
var server *rpc.Server
if server, err = initNode(); err != nil {
- log.Fatalf("init node failed: %v", err)
+ log.WithError(err).Fatal("init node failed")
}
if conf.GConf.Miner.IsTestMode {
// miner test mode enabled
- log.Debugf("miner test mode enabled")
+ log.Debug("miner test mode enabled")
}
// stop channel for all daemon routines
@@ -207,49 +215,10 @@ func main() {
}
}()
- // start block producer pinger
- go func() {
- var localNodeID proto.NodeID
- var err error
-
- // get local node id
- if localNodeID, err = kms.GetLocalNodeID(); err != nil {
- return
- }
-
- // get local node info
- var localNodeInfo *proto.Node
- if localNodeInfo, err = kms.GetNodeInfo(localNodeID); err != nil {
- return
- }
-
- log.Debugf("construct local node info: %v", localNodeInfo)
-
- go func() {
- for {
- select {
- case <-time.After(time.Second):
- case <-stopCh:
- return
- }
-
- // send ping requests to block producer
- bpNodeIDs := route.GetBPs()
-
- for _, bpNodeID := range bpNodeIDs {
- err := rpc.PingBP(localNodeInfo, bpNodeID)
- if err == nil {
- return
- }
- }
- }
- }()
- }()
-
// start dbms
var dbms *worker.DBMS
if dbms, err = startDBMS(server); err != nil {
- log.Fatalf("start dbms failed: %v", err)
+ log.WithError(err).Fatal("start dbms failed")
}
defer dbms.Shutdown()
@@ -271,6 +240,37 @@ func main() {
)
signal.Ignore(syscall.SIGHUP, syscall.SIGTTIN, syscall.SIGTTOU)
+ if metricLog {
+ go metrics.Log(metrics.DefaultRegistry, 5*time.Second, log.StandardLogger())
+ }
+
+ if metricGraphite != "" {
+ addr, err := net.ResolveTCPAddr("tcp", metricGraphite)
+ if err != nil {
+ log.WithError(err).Error("resolve metric graphite server addr failed")
+ return
+ }
+ minerName := fmt.Sprintf("miner-%s", conf.GConf.ThisNodeID[len(conf.GConf.ThisNodeID)-5:])
+ go graphite.Graphite(metrics.DefaultRegistry, 5*time.Second, minerName, addr)
+ }
+
+ if traceFile != "" {
+ f, err := os.Create(traceFile)
+ if err != nil {
+ log.WithError(err).Fatal("failed to create trace output file")
+ }
+ defer func() {
+ if err := f.Close(); err != nil {
+ log.WithError(err).Fatal("failed to close trace file")
+ }
+ }()
+
+ if err := trace.Start(f); err != nil {
+ log.WithError(err).Fatal("failed to start trace")
+ }
+ defer trace.Stop()
+ }
+
<-signalCh
log.Info("miner stopped")
diff --git a/cmd/cql-minerd/mcprof.sh b/cmd/cql-minerd/mcprof.sh
new file mode 100755
index 000000000..4c002b7d8
--- /dev/null
+++ b/cmd/cql-minerd/mcprof.sh
@@ -0,0 +1,8 @@
+#!/bin/sh -x
+
+../../cleanupDB.sh
+../../build.sh
+
+(go test -bench=^BenchmarkMinerTwo$ -benchtime=40s -run ^$ &) && \
+ (sleep 25 && DSN=`cat .dsn` go test '-bench=^BenchmarkClientOnly$' -benchtime=20s -run '^$')
+
diff --git a/cmd/cql-minerd/node.go b/cmd/cql-minerd/node.go
index ecc0ee6d0..2b7808e0a 100644
--- a/cmd/cql-minerd/node.go
+++ b/cmd/cql-minerd/node.go
@@ -19,13 +19,18 @@ package main
import (
"fmt"
"os"
+ "strings"
"syscall"
+ "time"
"github.com/CovenantSQL/CovenantSQL/conf"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
+ "github.com/CovenantSQL/CovenantSQL/kayak"
+ "github.com/CovenantSQL/CovenantSQL/proto"
"github.com/CovenantSQL/CovenantSQL/route"
"github.com/CovenantSQL/CovenantSQL/rpc"
"github.com/CovenantSQL/CovenantSQL/utils/log"
+ "github.com/pkg/errors"
"golang.org/x/crypto/ssh/terminal"
)
@@ -42,19 +47,24 @@ func initNode() (server *rpc.Server, err error) {
}
if err = kms.InitLocalKeyPair(conf.GConf.PrivateKeyFile, masterKey); err != nil {
- log.Errorf("init local key pair failed: %s", err)
+ log.WithError(err).Error("init local key pair failed")
return
}
- log.Infof("init routes")
+ log.Info("init routes")
// init kms routing
route.InitKMS(conf.GConf.PubKeyStoreFile)
+ err = registerNodeToBP(15 * time.Second)
+ if err != nil {
+ log.Fatalf("register node to BP failed: %v", err)
+ }
+
// init server
if server, err = createServer(
conf.GConf.PrivateKeyFile, conf.GConf.PubKeyStoreFile, masterKey, conf.GConf.ListenAddr); err != nil {
- log.Errorf("create server failed: %v", err)
+ log.WithError(err).Error("create server failed")
return
}
@@ -73,3 +83,53 @@ func createServer(privateKeyPath, pubKeyStorePath string, masterKey []byte, list
return
}
+
+func registerNodeToBP(timeout time.Duration) (err error) {
+ // get local node id
+ localNodeID, err := kms.GetLocalNodeID()
+ if err != nil {
+ err = errors.Wrap(err, "register node to BP")
+ return
+ }
+
+ // get local node info
+ localNodeInfo, err := kms.GetNodeInfo(localNodeID)
+ if err != nil {
+ err = errors.Wrap(err, "register node to BP")
+ return
+ }
+
+ log.WithField("node", localNodeInfo).Debug("construct local node info")
+
+ pingWaitCh := make(chan proto.NodeID)
+ bpNodeIDs := route.GetBPs()
+ for _, bpNodeID := range bpNodeIDs {
+ go func(ch chan proto.NodeID, id proto.NodeID) {
+ for {
+ err := rpc.PingBP(localNodeInfo, id)
+ if err == nil {
+ log.Infof("ping BP succeed: %v", localNodeInfo)
+ ch <- id
+ return
+ }
+ if strings.Contains(err.Error(), kayak.ErrNotLeader.Error()) {
+ log.Debug("stop ping non leader BP node")
+ return
+ }
+
+ log.Warnf("ping BP failed: %v", err)
+ time.Sleep(3 * time.Second)
+ }
+ }(pingWaitCh, bpNodeID)
+ }
+
+ select {
+ case bp := <-pingWaitCh:
+ close(pingWaitCh)
+ log.WithField("BP", bp).Infof("ping BP succeed")
+ case <-time.After(timeout):
+ return errors.New("ping BP timeout")
+ }
+
+ return
+}
diff --git a/cmd/cql-minerd/pprof.sh b/cmd/cql-minerd/pprof.sh
index 82afc6dea..f59633a46 100755
--- a/cmd/cql-minerd/pprof.sh
+++ b/cmd/cql-minerd/pprof.sh
@@ -1,7 +1,9 @@
-#!/bin/sh
+#!/bin/sh -x
+
+../../cleanupDB.sh
../../build.sh
-go test -bench=^BenchmarkMinerTwo$ -benchtime=60s -run ^$
+go test -bench=^BenchmarkMinerTwo$ -benchtime=15s -run ^$
go tool pprof -text miner1.profile > pprof.txt
go tool pprof -svg miner1.profile > tree.svg
go-torch -t 180 --width=2400 miner1.profile
diff --git a/cmd/cql-mysql-adapter/cursor.go b/cmd/cql-mysql-adapter/cursor.go
index 98ab3154c..1622f5537 100644
--- a/cmd/cql-mysql-adapter/cursor.go
+++ b/cmd/cql-mysql-adapter/cursor.go
@@ -25,26 +25,43 @@ import (
"sync"
"github.com/CovenantSQL/CovenantSQL/client"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
my "github.com/siddontang/go-mysql/mysql"
)
var (
- dbIDRegex = regexp.MustCompile("^[a-zA-Z0-9_\\.]+$")
- emptyResultQuery = regexp.MustCompile("^(?i)\\s*(?:(?:SELECT\\s+)?@@(?:\\w+\\.)?|SHOW\\s+VARIABLES|SHOW\\s+DATABASES|SET|ROLLBACK).*$")
- useDatabaseQuery = regexp.MustCompile("^(?i)\\s*USE\\s+(\\w+)\\s*$")
- readQuery = regexp.MustCompile("^(?i)\\s*(?:SELECT|SHOW|DESC)")
+ dbIDRegex = regexp.MustCompile("^[a-zA-Z0-9_\\.]+$")
+ specialSelectQuery = regexp.MustCompile("^(?i)SELECT\\s+(DATABASE|USER)\\(\\)\\s*;?\\s*$")
+ emptyResultQuery = regexp.MustCompile("^(?i)\\s*(?:/\\*.*?\\*/)?\\s*(?:SET|ROLLBACK).*$")
+ emptyResultWithResultSetQuery = regexp.MustCompile("^(?i)\\s*(?:/\\*.*?\\*/)?\\s*(?:(?:SELECT\\s+)?@@(?:\\w+\\.)?|SHOW\\s+WARNINGS).*$")
+ showVariablesQuery = regexp.MustCompile("^(?i)\\s*(?:/\\*.*?\\*/)?\\s*SHOW\\s+VARIABLES.*$")
+ showDatabasesQuery = regexp.MustCompile("^(?i)\\s*(?:/\\*.*?\\*/)?\\s*SHOW\\s+DATABASES.*$")
+ useDatabaseQuery = regexp.MustCompile("^(?i)\\s*USE\\s+`?(\\w+)`?\\s*$")
+ readQuery = regexp.MustCompile("^(?i)\\s*(?:SELECT|SHOW|DESC)")
+ mysqlServerVariables = map[string]interface{}{
+ "max_allowed_packet": 255 * 255 * 255,
+ "auto_increment_increment": 1,
+ "transaction_isolation": "SERIALIZABLE",
+ "tx_isolation": "SERIALIZABLE",
+ "transaction_read_only": 0,
+ "tx_read_only": 0,
+ "autocommit": 1,
+ "character_set_server": "utf8",
+ "collation_server": "utf8_general_ci",
+ }
)
// Cursor is a mysql connection handler, like a cursor of normal database.
type Cursor struct {
+ server *Server
curDBLock sync.Mutex
curDB string
curDBInstance *sql.DB
}
// NewCursor returns a new cursor.
-func NewCursor() (c *Cursor) {
- return &Cursor{}
+func NewCursor(s *Server) (c *Cursor) {
+ return &Cursor{server: s}
}
func (c *Cursor) buildResultSet(rows *sql.Rows) (r *my.Result, err error) {
@@ -117,6 +134,134 @@ func (c *Cursor) detectColumnType(typeStr string) (typeByte uint8) {
}
}
+func (c *Cursor) handleSpecialQuery(query string) (r *my.Result, processed bool, err error) {
+ if emptyResultQuery.MatchString(query) { // send empty result for variables query/table listing
+ // return empty result
+ r = &my.Result{
+ Status: 0,
+ InsertId: 0,
+ AffectedRows: 0,
+ Resultset: nil,
+ }
+ processed = true
+ } else if emptyResultWithResultSetQuery.MatchString(query) { // send empty result include non-nil result set
+ // return empty result with empty result set
+ var resultSet *my.Resultset
+ var columns []string
+ var row []interface{}
+
+ for k, v := range mysqlServerVariables {
+ if strings.Contains(query, k) {
+ columns = append(columns, k)
+ row = append(row, v)
+ }
+ }
+
+ if len(columns) == 0 {
+ columns = append(columns, "_")
+ }
+
+ if row != nil {
+ resultSet, _ = my.BuildSimpleTextResultset(columns, [][]interface{}{row})
+ } else {
+ resultSet, _ = my.BuildSimpleTextResultset(columns, [][]interface{}{})
+ }
+
+ if resultSet.RowDatas == nil {
+ // force non-empty result set
+ resultSet.RowDatas = make([]my.RowData, 0)
+ }
+
+ r = &my.Result{
+ Status: 0,
+ InsertId: 0,
+ AffectedRows: 0,
+ Resultset: resultSet,
+ }
+ processed = true
+ } else if showVariablesQuery.MatchString(query) { // send show variables result with custom config
+ var rows [][]interface{}
+
+ for k, v := range mysqlServerVariables {
+ rows = append(rows, []interface{}{k, v})
+ }
+
+ resultSet, _ := my.BuildSimpleTextResultset([]string{"Variable_name", "Value"}, rows)
+ r = &my.Result{
+ Status: 0,
+ InsertId: 0,
+ AffectedRows: 0,
+ Resultset: resultSet,
+ }
+ processed = true
+ } else if showDatabasesQuery.MatchString(query) { // send show databases result
+ // return result including current database
+ var curDBStr string
+ c.curDBLock.Lock()
+ curDBStr = c.curDB
+ c.curDBLock.Unlock()
+
+ var resultSet *my.Resultset
+
+ if curDBStr != "" {
+ resultSet, _ = my.BuildSimpleTextResultset([]string{"Database"}, [][]interface{}{{curDBStr}})
+ } else {
+ resultSet, _ = my.BuildSimpleTextResultset([]string{"Database"}, nil)
+ }
+
+ r = &my.Result{
+ Status: 0,
+ InsertId: 0,
+ AffectedRows: 0,
+ Resultset: resultSet,
+ }
+ processed = true
+ } else if matches := useDatabaseQuery.FindStringSubmatch(query); len(matches) > 1 { // use database query, same logic as COM_INIT_DB
+ dbID := matches[1]
+
+ processed = true
+ if err = c.UseDB(dbID); err == nil {
+ r = &my.Result{
+ Status: 0,
+ InsertId: 0,
+ AffectedRows: 0,
+ Resultset: nil,
+ }
+ }
+ } else if matches := specialSelectQuery.FindStringSubmatch(query); len(matches) > 1 {
+ // special select database
+ // for libmysql trivial implementations
+ // https://github.com/mysql/mysql-server/blob/4f1d7cf5fcb11a3f84cff27e37100d7295e7d5ca/client/mysql.cc#L4266
+
+ var resultSet *my.Resultset
+
+ switch strings.ToUpper(matches[1]) {
+ case "DATABASE":
+ c.curDBLock.Lock()
+ resultSet, _ = my.BuildSimpleTextResultset(
+ []string{"DATABASE()"},
+ [][]interface{}{{c.curDB}},
+ )
+ c.curDBLock.Unlock()
+ case "USER":
+ resultSet, _ = my.BuildSimpleTextResultset(
+ []string{"USER()"},
+ [][]interface{}{{c.server.mysqlUser}},
+ )
+ }
+
+ r = &my.Result{
+ Status: 0,
+ InsertId: 0,
+ AffectedRows: 0,
+ Resultset: resultSet,
+ }
+ processed = true
+ }
+
+ return
+}
+
// UseDB handle COM_INIT_DB command, you can check whether the dbName is valid, or other.
func (c *Cursor) UseDB(dbName string) (err error) {
c.curDBLock.Lock()
@@ -147,36 +292,17 @@ func (c *Cursor) UseDB(dbName string) (err error) {
// HandleQuery handle COM_QUERY comamnd, like SELECT, INSERT, UPDATE, etc...
// if Result has a Resultset (SELECT, SHOW, etc...), we will send this as the repsonse, otherwise, we will send Result.
func (c *Cursor) HandleQuery(query string) (r *my.Result, err error) {
- var conn *sql.DB
+ var processed bool
- if conn, err = c.ensureDatabase(); err != nil {
- return
- }
+ log.WithField("query", query).Info("received query")
- // send empty result for variables query/table listing
- if emptyResultQuery.MatchString(query) {
- // return empty result
- return &my.Result{
- Status: 0,
- InsertId: 0,
- AffectedRows: 0,
- Resultset: nil,
- }, nil
+ if r, processed, err = c.handleSpecialQuery(query); processed {
+ return
}
- // use database query, same logic as COM_INIT_DB
- if matches := useDatabaseQuery.FindStringSubmatch(query); len(matches) > 1 {
- dbID := matches[1]
-
- if err = c.UseDB(dbID); err == nil {
- r = &my.Result{
- Status: 0,
- InsertId: 0,
- AffectedRows: 0,
- Resultset: nil,
- }
- }
+ var conn *sql.DB
+ if conn, err = c.ensureDatabase(); err != nil {
return
}
diff --git a/cmd/cql-mysql-adapter/main.go b/cmd/cql-mysql-adapter/main.go
index bb6668e09..ada223bd1 100644
--- a/cmd/cql-mysql-adapter/main.go
+++ b/cmd/cql-mysql-adapter/main.go
@@ -18,8 +18,10 @@ package main
import (
"flag"
+ "fmt"
"os"
"os/signal"
+ "runtime"
"github.com/CovenantSQL/CovenantSQL/client"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
@@ -27,13 +29,17 @@ import (
"golang.org/x/sys/unix"
)
+const name = "cql-mysql-adapter"
+
var (
+ version = "unknown"
configFile string
password string
listenAddr string
mysqlUser string
mysqlPassword string
+ showVersion bool
)
func init() {
@@ -41,6 +47,7 @@ func init() {
flag.StringVar(&password, "password", "", "master key password")
flag.BoolVar(&asymmetric.BypassSignature, "bypassSignature", false,
"Disable signature sign and verify, for testing")
+ flag.BoolVar(&showVersion, "version", false, "Show version information and exit")
flag.StringVar(&listenAddr, "listen", "127.0.0.1:4664", "listen address for mysql adapter")
flag.StringVar(&mysqlUser, "mysql-user", "root", "mysql user for adapter server")
@@ -49,13 +56,19 @@ func init() {
func main() {
flag.Parse()
+ if showVersion {
+ fmt.Printf("%v %v %v %v %v\n",
+ name, version, runtime.GOOS, runtime.GOARCH, runtime.Version())
+ os.Exit(0)
+ }
+
flag.Visit(func(f *flag.Flag) {
- log.Infof("Args %s : %v", f.Name, f.Value)
+ log.Infof("Args %#v : %s", f.Name, f.Value)
})
// init client
if err := client.Init(configFile, []byte(password)); err != nil {
- log.Fatalf("init covenantsql client failed: %v", err)
+ log.WithError(err).Fatal("init covenantsql client failed")
return
}
@@ -64,17 +77,17 @@ func main() {
server, err := NewServer(listenAddr, mysqlUser, mysqlPassword)
if err != nil {
- log.Fatalf("init server failed: %v", err)
+ log.WithError(err).Fatal("init server failed")
return
}
go server.Serve()
- log.Infof("start mysql adapter")
+ log.Info("start mysql adapter")
<-stop
server.Shutdown()
- log.Infof("stopped mysql adapter")
+ log.Info("stopped mysql adapter")
}
diff --git a/cmd/cql-mysql-adapter/server.go b/cmd/cql-mysql-adapter/server.go
index c6728f7c6..db58a97d7 100644
--- a/cmd/cql-mysql-adapter/server.go
+++ b/cmd/cql-mysql-adapter/server.go
@@ -59,10 +59,10 @@ func (s *Server) Serve() {
}
func (s *Server) handleConn(conn net.Conn) {
- h, err := mys.NewConn(conn, s.mysqlUser, s.mysqlPassword, NewCursor())
+ h, err := mys.NewConn(conn, s.mysqlUser, s.mysqlPassword, NewCursor(s))
if err != nil {
- log.Errorf("process connection failed: %v", err)
+ log.WithError(err).Error("process connection failed")
return
}
diff --git a/cmd/cql-observer/api.go b/cmd/cql-observer/api.go
index 26c2dc998..2d644eed1 100644
--- a/cmd/cql-observer/api.go
+++ b/cmd/cql-observer/api.go
@@ -425,7 +425,7 @@ func startAPI(service *Service, listenAddr string) (server *http.Server, err err
go func() {
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
- log.Fatalf("start api server failed: %v", err)
+ log.WithError(err).Fatal("start api server failed")
}
}()
diff --git a/cmd/cql-observer/config.go b/cmd/cql-observer/config.go
index d304933b4..4b68f44c4 100644
--- a/cmd/cql-observer/config.go
+++ b/cmd/cql-observer/config.go
@@ -44,11 +44,11 @@ func loadConfig(path string) (config *Config, err error) {
wrapper = &configWrapper{}
)
if content, err = ioutil.ReadFile(path); err != nil {
- log.Errorf("Failed to read config file: %v", err)
+ log.WithError(err).Error("Failed to read config file")
return
}
if err = yaml.Unmarshal(content, wrapper); err != nil {
- log.Errorf("Failed to unmarshal config file: %v", err)
+ log.WithError(err).Error("Failed to unmarshal config file")
return
}
config = wrapper.Observer
diff --git a/cmd/cql-observer/main.go b/cmd/cql-observer/main.go
index fdf3efdc2..4fb15e7be 100644
--- a/cmd/cql-observer/main.go
+++ b/cmd/cql-observer/main.go
@@ -18,12 +18,13 @@ package main
import (
"flag"
+ "fmt"
"math/rand"
- "time"
-
"os"
"os/signal"
+ "runtime"
"syscall"
+ "time"
"github.com/CovenantSQL/CovenantSQL/conf"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
@@ -33,23 +34,23 @@ import (
"github.com/CovenantSQL/CovenantSQL/utils/log"
)
+const name = "cql-observer"
+
var (
version = "unknown"
- commit = "unknown"
- branch = "unknown"
-)
-var (
// config
configFile string
dbID string
listenAddr string
resetPosition string
+ showVersion bool
)
func init() {
- flag.StringVar(&configFile, "config", "./config.yaml", "Config file path")
+ flag.StringVar(&configFile, "config", "./config.yaml", "config file path")
flag.StringVar(&dbID, "database", "", "database to listen for observation")
+ flag.BoolVar(&showVersion, "version", false, "Show version information and exit")
flag.BoolVar(&asymmetric.BypassSignature, "bypassSignature", false,
"Disable signature sign and verify, for testing")
flag.StringVar(&resetPosition, "reset", "", "reset subscribe position")
@@ -61,14 +62,20 @@ func main() {
rand.Seed(time.Now().UnixNano())
log.SetLevel(log.DebugLevel)
flag.Parse()
+ if showVersion {
+ fmt.Printf("%v %v %v %v %v\n",
+ name, version, runtime.GOOS, runtime.GOARCH, runtime.Version())
+ os.Exit(0)
+ }
+
flag.Visit(func(f *flag.Flag) {
- log.Infof("Args %s : %v", f.Name, f.Value)
+ log.Infof("Args %#v : %s", f.Name, f.Value)
})
var err error
conf.GConf, err = conf.LoadConfig(configFile)
if err != nil {
- log.Fatalf("load config from %s failed: %s", configFile, err)
+ log.WithField("config", configFile).WithError(err).Fatal("load config failed")
}
kms.InitBP()
@@ -76,35 +83,35 @@ func main() {
// start rpc
var server *rpc.Server
if server, err = initNode(); err != nil {
- log.Fatalf("init node failed: %v", err)
+ log.WithError(err).Fatal("init node failed")
}
// start service
var service *Service
if service, err = startService(server); err != nil {
- log.Fatalf("start observation failed: %v", err)
+ log.WithError(err).Fatal("start observation failed")
}
// start explorer api
httpServer, err := startAPI(service, listenAddr)
if err != nil {
- log.Fatalf("start explorer api failed: %v", err)
+ log.WithError(err).Fatal("start explorer api failed")
}
// register node
if err = registerNode(); err != nil {
- log.Fatalf("register node failed: %v", err)
+ log.WithError(err).Fatal("register node failed")
}
// start subscription
var cfg *Config
if cfg, err = loadConfig(configFile); err != nil {
- log.Fatalf("failed to load config: %v", err)
+ log.WithError(err).Fatal("failed to load config")
}
if cfg != nil {
for _, v := range cfg.Databases {
if err = service.subscribe(proto.DatabaseID(v.ID), v.Position); err != nil {
- log.Fatalf("init subscription failed: %v", err)
+ log.WithError(err).Fatal("init subscription failed")
}
}
}
@@ -112,7 +119,7 @@ func main() {
// without changing the config.
if dbID != "" {
if err = service.subscribe(proto.DatabaseID(dbID), resetPosition); err != nil {
- log.Fatalf("init subscription failed: %v", err)
+ log.WithError(err).Fatal("init subscription failed")
}
}
@@ -128,12 +135,12 @@ func main() {
// stop explorer api
if err = stopAPI(httpServer); err != nil {
- log.Fatalf("stop explorer api failed: %v", err)
+ log.WithError(err).Fatal("stop explorer api failed")
}
// stop subscriptions
if err = stopService(service, server); err != nil {
- log.Fatalf("stop service failed: %v", err)
+ log.WithError(err).Fatal("stop service failed")
}
log.Info("observer stopped")
diff --git a/cmd/cql-observer/node.go b/cmd/cql-observer/node.go
index 2c687e619..49bb83513 100644
--- a/cmd/cql-observer/node.go
+++ b/cmd/cql-observer/node.go
@@ -41,11 +41,11 @@ func initNode() (server *rpc.Server, err error) {
}
if err = kms.InitLocalKeyPair(conf.GConf.PrivateKeyFile, masterKey); err != nil {
- log.Errorf("init local key pair failed: %v", err)
+ log.WithError(err).Error("init local key pair failed")
return
}
- log.Infof("init routes")
+ log.Info("init routes")
// init kms routing
route.InitKMS(conf.GConf.PubKeyStoreFile)
@@ -53,7 +53,7 @@ func initNode() (server *rpc.Server, err error) {
// init server
if server, err = createServer(
conf.GConf.PrivateKeyFile, conf.GConf.PubKeyStoreFile, masterKey, conf.GConf.ListenAddr); err != nil {
- log.Errorf("create server failed: %v", err)
+ log.WithError(err).Error("create server failed")
return
}
diff --git a/cmd/cql-observer/observation_test.go b/cmd/cql-observer/observation_test.go
index 5ed3cb07e..a0be43d42 100644
--- a/cmd/cql-observer/observation_test.go
+++ b/cmd/cql-observer/observation_test.go
@@ -52,30 +52,14 @@ var nodeCmds []*utils.CMD
var FJ = filepath.Join
-func TestBuild(t *testing.T) {
- Convey("build", t, func() {
- log.SetLevel(log.DebugLevel)
- So(utils.Build(), ShouldBeNil)
- })
-}
-
func startNodes() {
// wait for ports to be available
var err error
ctx := context.Background()
err = utils.WaitForPorts(ctx, "127.0.0.1", []int{
- 2144,
- 2145,
- 2146,
- }, time.Millisecond*200)
-
- if err != nil {
- log.Fatalf("wait for port ready timeout: %v", err)
- }
- err = utils.WaitForPorts(ctx, "127.0.0.1", []int{
- 3122,
- 3121,
- 3120,
+ 4120,
+ 4121,
+ 4122,
}, time.Millisecond*200)
if err != nil {
@@ -89,7 +73,7 @@ func startNodes() {
[]string{"-config", FJ(testWorkingDir, "./observation/node_0/config.yaml"),
"-test.coverprofile", FJ(baseDir, "./cmd/cql-observer/leader.cover.out"),
},
- "leader", testWorkingDir, logDir, false,
+ "leader", testWorkingDir, logDir, true,
); err == nil {
nodeCmds = append(nodeCmds, cmd)
} else {
@@ -118,8 +102,29 @@ func startNodes() {
log.Errorf("start node failed: %v", err)
}
- time.Sleep(time.Second * 3)
+ ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
+ defer cancel()
+ err = utils.WaitToConnect(ctx, "127.0.0.1", []int{
+ 4120,
+ 4121,
+ 4122,
+ }, time.Second)
+ if err != nil {
+ log.Fatalf("wait for port ready timeout: %v", err)
+ }
+
+ ctx, cancel = context.WithTimeout(context.Background(), time.Second*30)
+ defer cancel()
+ err = utils.WaitForPorts(ctx, "127.0.0.1", []int{
+ 4144,
+ 4145,
+ 4146,
+ }, time.Millisecond*200)
+ if err != nil {
+ log.Fatalf("wait for port ready timeout: %v", err)
+ }
+ time.Sleep(10 * time.Second)
// start 3miners
os.RemoveAll(FJ(testWorkingDir, "./observation/node_miner_0/data"))
if cmd, err = utils.RunCommandNB(
@@ -127,7 +132,7 @@ func startNodes() {
[]string{"-config", FJ(testWorkingDir, "./observation/node_miner_0/config.yaml"),
"-test.coverprofile", FJ(baseDir, "./cmd/cql-observer/miner0.cover.out"),
},
- "miner0", testWorkingDir, logDir, false,
+ "miner0", testWorkingDir, logDir, true,
); err == nil {
nodeCmds = append(nodeCmds, cmd)
} else {
@@ -140,7 +145,7 @@ func startNodes() {
[]string{"-config", FJ(testWorkingDir, "./observation/node_miner_1/config.yaml"),
"-test.coverprofile", FJ(baseDir, "./cmd/cql-observer/miner1.cover.out"),
},
- "miner1", testWorkingDir, logDir, false,
+ "miner1", testWorkingDir, logDir, true,
); err == nil {
nodeCmds = append(nodeCmds, cmd)
} else {
@@ -153,7 +158,7 @@ func startNodes() {
[]string{"-config", FJ(testWorkingDir, "./observation/node_miner_2/config.yaml"),
"-test.coverprofile", FJ(baseDir, "./cmd/cql-observer/miner2.cover.out"),
},
- "miner2", testWorkingDir, logDir, false,
+ "miner2", testWorkingDir, logDir, true,
); err == nil {
nodeCmds = append(nodeCmds, cmd)
} else {
@@ -221,11 +226,12 @@ func TestFullProcess(t *testing.T) {
log.SetLevel(log.DebugLevel)
Convey("test full process", t, func() {
+ var err error
startNodes()
defer stopNodes()
+
time.Sleep(10 * time.Second)
- var err error
err = client.Init(FJ(testWorkingDir, "./observation/node_c/config.yaml"), []byte(""))
So(err, ShouldBeNil)
diff --git a/cmd/cql-observer/observer.go b/cmd/cql-observer/observer.go
index a6913fb8a..ff7ed1b22 100644
--- a/cmd/cql-observer/observer.go
+++ b/cmd/cql-observer/observer.go
@@ -20,8 +20,8 @@ import (
"github.com/CovenantSQL/CovenantSQL/conf"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
"github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/route"
"github.com/CovenantSQL/CovenantSQL/rpc"
- ct "github.com/CovenantSQL/CovenantSQL/sqlchain/types"
)
func registerNode() (err error) {
@@ -48,7 +48,7 @@ func startService(server *rpc.Server) (service *Service, err error) {
return
}
- if err = server.RegisterService(ct.ObserverService, service); err != nil {
+ if err = server.RegisterService(route.ObserverRPCName, service); err != nil {
return
}
diff --git a/cmd/cql-observer/service.go b/cmd/cql-observer/service.go
index e143c4305..53b4b9720 100644
--- a/cmd/cql-observer/service.go
+++ b/cmd/cql-observer/service.go
@@ -241,10 +241,15 @@ func (s *Service) AdviseNewBlock(req *sqlchain.MuxAdviseNewBlockReq, resp *sqlch
}
if req.Block == nil {
- log.Infof("received empty block from node %v", req.GetNodeID().String())
+ log.WithField("node", req.GetNodeID().String()).Warning("received empty block")
return
}
+ log.WithFields(log.Fields{
+ "node": req.GetNodeID().String(),
+ "block": req.Block.BlockHash(),
+ }).Debug("received block")
+
return s.addBlock(req.DatabaseID, req.Count, req.Block)
}
@@ -256,7 +261,7 @@ func (s *Service) AdviseAckedQuery(req *sqlchain.MuxAdviseAckedQueryReq, resp *s
}
if req.Query == nil {
- log.Infof("received empty acked query from node %v", req.GetNodeID().String())
+ log.WithField("node", req.GetNodeID().String()).Info("received empty acked query")
return
}
@@ -278,7 +283,7 @@ func (s *Service) start() (err error) {
for _, dbID := range dbs {
if err = s.startSubscribe(dbID); err != nil {
- log.Warningf("start subscription failed on database %v: %v", dbID, err)
+ log.WithField("db", dbID).WithError(err).Warning("start subscription failed")
}
}
@@ -295,7 +300,7 @@ func (s *Service) startSubscribe(dbID proto.DatabaseID) (err error) {
defer s.lock.Unlock()
// start subscribe on first node of each sqlchain server peers
- log.Infof("start subscribing transactions from database %v", dbID)
+ log.WithField("db", dbID).Info("start subscribing transactions")
instance, err := s.getUpstream(dbID)
if err != nil {
@@ -318,7 +323,10 @@ func (s *Service) startSubscribe(dbID proto.DatabaseID) (err error) {
}
func (s *Service) addAckedQuery(dbID proto.DatabaseID, ack *wt.SignedAckHeader) (err error) {
- log.Debugf("add ack query %v: %v", dbID, ack.HeaderHash.String())
+ log.WithFields(log.Fields{
+ "ack": ack.HeaderHash.String(),
+ "db": dbID,
+ }).Debug("add ack query")
if atomic.LoadInt32(&s.stopped) == 1 {
// stopped
@@ -347,8 +355,11 @@ func (s *Service) addAckedQuery(dbID proto.DatabaseID, ack *wt.SignedAckHeader)
key := offsetToBytes(req.LogOffset)
key = append(key, resp.Request.Header.HeaderHash.CloneBytes()...)
- log.Debugf("add write request, offset: %v, %v, %v",
- req.LogOffset, resp.Request.Header.HeaderHash.String(), resp.Request.Payload.Queries)
+ log.WithFields(log.Fields{
+ "offset": req.LogOffset,
+ "reqHash": resp.Request.Header.HeaderHash.String(),
+ "reqQueries": resp.Request.Payload.Queries,
+ }).Debug("add write request")
var reqBytes *bytes.Buffer
if reqBytes, err = utils.EncodeMsgPack(resp.Request); err != nil {
@@ -434,7 +445,7 @@ func (s *Service) addBlock(dbID proto.DatabaseID, count int32, b *ct.Block) (err
}
func (s *Service) stop() (err error) {
- if atomic.LoadInt32(&s.stopped) == 1 {
+ if !atomic.CompareAndSwapInt32(&s.stopped, 0, 1) {
// stopped
return ErrStopped
}
@@ -442,10 +453,8 @@ func (s *Service) stop() (err error) {
s.lock.Lock()
defer s.lock.Unlock()
- atomic.StoreInt32(&s.stopped, 1)
-
// send cancel subscription to all databases
- log.Infof("stop subscribing all databases")
+ log.Info("stop subscribing all databases")
for dbID := range s.subscription {
// send cancel subscription rpc
@@ -455,7 +464,7 @@ func (s *Service) stop() (err error) {
if err = s.minerRequest(dbID, route.SQLCCancelSubscription.String(), req, resp); err != nil {
// cancel subscription failed
- log.Warningf("cancel subscription for database %v failed: %v", dbID, err)
+ log.WithField("db", dbID).WithError(err).Warning("cancel subscription")
}
}
@@ -475,7 +484,7 @@ func (s *Service) minerRequest(dbID proto.DatabaseID, method string, request int
}
func (s *Service) getUpstream(dbID proto.DatabaseID) (instance *wt.ServiceInstance, err error) {
- log.Infof("get peers info for database: %v", dbID)
+ log.WithField("db", dbID).Info("get peers info for database")
if iInstance, exists := s.upstreamServers.Load(dbID); exists {
instance = iInstance.(*wt.ServiceInstance)
@@ -492,14 +501,8 @@ func (s *Service) getUpstream(dbID proto.DatabaseID) (instance *wt.ServiceInstan
return
}
- pubKey, err := kms.GetLocalPublicKey()
- if err != nil {
- return
- }
-
req := &bp.GetDatabaseRequest{}
req.Header.DatabaseID = dbID
- req.Header.Signee = pubKey
if err = req.Sign(privateKey); err != nil {
return
}
diff --git a/cmd/cql-utils/adapterconfgen.go b/cmd/cql-utils/adapterconfgen.go
new file mode 100644
index 000000000..bcbad9273
--- /dev/null
+++ b/cmd/cql-utils/adapterconfgen.go
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2018 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 main
+
+import (
+ "bufio"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "strings"
+
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
+ "gopkg.in/yaml.v2"
+)
+
+type adapterConfig struct {
+ ListenAddr string `yaml:"ListenAddr"`
+ CertificatePath string `yaml:"CertificatePath"`
+ PrivateKeyPath string `yaml:"PrivateKeyPath"`
+ VerifyCertificate bool `yaml:"VerifyCertificate"`
+ ClientCAPath string `yaml:"ClientCAPath"`
+ AdminCerts []string `yaml:"AdminCerts"`
+ WriteCerts []string `yaml:"WriteCerts"`
+ StorageDriver string `yaml:"StorageDriver"`
+ StorageRoot string `yaml:"StorageRoot"`
+}
+
+var (
+ defaultAdapterConfig = &adapterConfig{
+ ListenAddr: "0.0.0.0:4661",
+ CertificatePath: "server.pem",
+ PrivateKeyPath: "server-key.pem",
+ VerifyCertificate: false,
+ ClientCAPath: "",
+ AdminCerts: []string{},
+ WriteCerts: []string{},
+ StorageDriver: "covenantsql",
+ StorageRoot: "",
+ }
+)
+
+func (c *adapterConfig) readListenAddr() {
+ newAddr := readDataFromStdin("ListenAddr (default: %v): ", c.ListenAddr)
+ if newAddr != "" {
+ c.ListenAddr = newAddr
+ }
+}
+
+func (c *adapterConfig) readCertificatePath() {
+ newCertPath := readDataFromStdin("CertificatePath (default: %v): ", c.CertificatePath)
+ if newCertPath != "" {
+ c.CertificatePath = newCertPath
+ }
+}
+
+func (c *adapterConfig) readPrivateKeyPath() {
+ newPrivateKeyPath := readDataFromStdin("PrivateKeyPath (default: %v): ", c.PrivateKeyPath)
+ if newPrivateKeyPath != "" {
+ c.PrivateKeyPath = newPrivateKeyPath
+ }
+}
+
+func (c *adapterConfig) readVerifyCertificate() bool {
+ shouldVerifyCertificate := readDataFromStdin(
+ "VerifyCertificate (default: %v) (y/n): ", c.VerifyCertificate)
+ if shouldVerifyCertificate != "" {
+ switch shouldVerifyCertificate {
+ case "y":
+ fallthrough
+ case "Y":
+ c.VerifyCertificate = true
+ case "N":
+ fallthrough
+ case "n":
+ c.VerifyCertificate = false
+ }
+ }
+
+ return c.VerifyCertificate
+}
+
+func (c *adapterConfig) readClientCAPath() {
+ newClientCAPath := readDataFromStdin("ClientCAPath (default: %v)", c.ClientCAPath)
+ if newClientCAPath != "" {
+ c.ClientCAPath = newClientCAPath
+ }
+}
+
+func (c *adapterConfig) readAdminCerts() {
+ var newCerts []string
+
+ for {
+ record := readDataFromStdin("AdminCerts: ")
+
+ if record == "" {
+ break
+ }
+
+ newCerts = append(newCerts, record)
+ }
+
+ c.AdminCerts = newCerts
+}
+
+func (c *adapterConfig) readWriteCerts() {
+ var newCerts []string
+
+ for {
+ record := readDataFromStdin("WriteCerts: ")
+
+ if record == "" {
+ break
+ }
+
+ newCerts = append(newCerts, record)
+ }
+
+ c.WriteCerts = newCerts
+}
+
+func (c *adapterConfig) readStorageDriver() {
+ newStorageDriver := readDataFromStdin("StorageDriver (default: %v)", c.StorageDriver)
+ if newStorageDriver != "" {
+ c.StorageDriver = newStorageDriver
+ }
+}
+
+func (c *adapterConfig) readStorageRoot() {
+ newStorageRoot := readDataFromStdin("StorageRoot (default: %v)", c.StorageRoot)
+ if newStorageRoot != "" {
+ c.StorageRoot = newStorageRoot
+ }
+}
+
+func (c *adapterConfig) loadFromExistingConfig(rawConfig yaml.MapSlice) {
+ if rawConfig == nil {
+ return
+ }
+
+ // find adapter config in map slice
+ var originalConfig interface{}
+
+ for _, item := range rawConfig {
+ if keyStr, ok := item.Key.(string); ok && keyStr == "Adapter" {
+ originalConfig = item.Value
+ }
+ }
+
+ if originalConfig == nil {
+ return
+ }
+
+ // fill values to config structure
+ var configBytes []byte
+ var err error
+
+ if configBytes, err = yaml.Marshal(originalConfig); err != nil {
+ log.WithError(err).Warning("load previous adapter config failed")
+ return
+ }
+
+ if err = yaml.Unmarshal(configBytes, c); err != nil {
+ log.WithError(err).Warning("load previous adapter config failed")
+ return
+ }
+
+ return
+}
+
+func (c *adapterConfig) writeToRawConfig(rawConfig yaml.MapSlice) yaml.MapSlice {
+ if rawConfig == nil {
+ return rawConfig
+ }
+
+ // find adapter config in map slice
+ for i, item := range rawConfig {
+ if keyStr, ok := item.Key.(string); ok && keyStr == "Adapter" {
+ rawConfig[i].Value = c
+ return rawConfig
+ }
+ }
+
+ // not found
+ rawConfig = append(rawConfig, yaml.MapItem{
+ Key: "Adapter",
+ Value: c,
+ })
+
+ return rawConfig
+}
+
+func (c *adapterConfig) readAllConfig() {
+ c.readListenAddr()
+ c.readCertificatePath()
+ c.readPrivateKeyPath()
+
+ if c.readVerifyCertificate() {
+ c.readClientCAPath()
+ c.readAdminCerts()
+ c.readWriteCerts()
+ }
+
+ c.readStorageDriver()
+ c.readStorageRoot()
+}
+
+func readDataFromStdin(prompt string, values ...interface{}) (s string) {
+ reader := bufio.NewReader(os.Stdin)
+ fmt.Printf(prompt, values...)
+ s, _ = reader.ReadString('\n')
+ s = strings.TrimSpace(s)
+ return
+}
+
+func runAdapterConfGen() {
+ if configFile == "" {
+ log.Error("config file path is required for adapterconfgen tool")
+ os.Exit(1)
+ }
+
+ var err error
+ var configBytes []byte
+ if configBytes, err = ioutil.ReadFile(configFile); err != nil {
+ log.WithError(err).Error("an existing config file is required for adapterconfggen")
+ os.Exit(1)
+ }
+
+ // load config
+ var rawConfig yaml.MapSlice
+ if err = yaml.Unmarshal(configBytes, &rawConfig); err != nil {
+ log.WithError(err).Error("a valid config file is required for adapterconfgen")
+ os.Exit(1)
+ }
+
+ if rawConfig == nil {
+ log.WithError(err).Error("a confgen generated config is required for adapterconfgen")
+ os.Exit(1)
+ }
+
+ // backup config
+ bakConfigFile := configFile + ".bak"
+ if err = ioutil.WriteFile(bakConfigFile, configBytes, 0600); err != nil {
+ log.WithError(err).Error("backup config file failed")
+ os.Exit(1)
+ }
+
+ defaultAdapterConfig.loadFromExistingConfig(rawConfig)
+ defaultAdapterConfig.readAllConfig()
+ rawConfig = defaultAdapterConfig.writeToRawConfig(rawConfig)
+
+ if configBytes, err = yaml.Marshal(rawConfig); err != nil {
+ log.WithError(err).Error("marshal config failed")
+ os.Exit(1)
+ }
+
+ if err = ioutil.WriteFile(configFile, configBytes, 0600); err != nil {
+ log.WithError(err).Error("write config to file failed")
+ os.Exit(1)
+ }
+
+ log.Info("adapter config generated")
+
+ return
+}
diff --git a/cmd/cql-utils/addrgen.go b/cmd/cql-utils/addrgen.go
new file mode 100644
index 000000000..d0df440cf
--- /dev/null
+++ b/cmd/cql-utils/addrgen.go
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2018 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 main
+
+import (
+ "encoding/hex"
+ "flag"
+ "fmt"
+ "os"
+
+ "github.com/CovenantSQL/CovenantSQL/crypto"
+ "github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
+ "github.com/CovenantSQL/CovenantSQL/crypto/kms"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
+)
+
+var (
+ isTestNetAddr bool
+)
+
+func init() {
+ flag.BoolVar(&isTestNetAddr, "addrgen", false, "addrgen generates a testnet address from your key pair")
+}
+
+func runAddrgen() {
+ var publicKey *asymmetric.PublicKey
+
+ if publicKeyHex != "" {
+ publicKeyBytes, err := hex.DecodeString(publicKeyHex)
+ if err != nil {
+ log.WithError(err).Fatal("error converting hex")
+ }
+ publicKey, err = asymmetric.ParsePubKey(publicKeyBytes)
+ if err != nil {
+ log.WithError(err).Fatal("error converting public key")
+ }
+ } else if privateKeyFile != "" {
+ masterKey, err := readMasterKey()
+ if err != nil {
+ fmt.Printf("read master key failed: %v\n", err)
+ os.Exit(1)
+ }
+ privateKey, err := kms.LoadPrivateKey(privateKeyFile, []byte(masterKey))
+ if err != nil {
+ log.WithError(err).Fatal("load private key file failed")
+ }
+ publicKey = privateKey.PubKey()
+ } else {
+ fmt.Println("privateKey path or publicKey hex is required for addrgen")
+ os.Exit(1)
+ }
+
+ addr, err := crypto.PubKey2Addr(publicKey, crypto.TestNet)
+ if err != nil {
+ log.WithError(err).Fatal("unexpected error")
+ }
+ fmt.Printf("wallet address: %s\n", addr)
+}
diff --git a/cmd/cql-utils/confgen.go b/cmd/cql-utils/confgen.go
new file mode 100644
index 000000000..4437f4626
--- /dev/null
+++ b/cmd/cql-utils/confgen.go
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2018 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 main
+
+import (
+ "bufio"
+ "encoding/hex"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path"
+ "strings"
+
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
+)
+
+var (
+ workingRoot string
+)
+
+func init() {
+ flag.StringVar(&workingRoot, "root", "conf", "confgen root is the working root directory containing all auto-generating keys and certifications")
+}
+
+func runConfgen() {
+ if workingRoot == "" {
+ log.Error("root directory is required for confgen")
+ os.Exit(1)
+ }
+
+ privateKeyFileName := "private.key"
+ publicKeystoreFileName := "public.keystore"
+
+ privateKeyFile = path.Join(workingRoot, privateKeyFileName)
+
+ if _, err := os.Stat(workingRoot); err == nil {
+ reader := bufio.NewReader(os.Stdin)
+ fmt.Println("The directory has already existed. \nDo you want to delete it? (y or n, press Enter for default n):")
+ t, err := reader.ReadString('\n')
+ t = strings.Trim(t, "\n")
+ if err != nil {
+ log.WithError(err).Error("unexpected error")
+ os.Exit(1)
+ }
+ if strings.Compare(t, "y") == 0 || strings.Compare(t, "yes") == 0 {
+ os.RemoveAll(workingRoot)
+ } else {
+ os.Exit(0)
+ }
+ }
+
+ err := os.Mkdir(workingRoot, 0755)
+ if err != nil {
+ log.WithError(err).Error("unexpected error")
+ os.Exit(1)
+ }
+
+ fmt.Println("Generating key pair...")
+ publicKey := runKeygen()
+ fmt.Println("Generated key pair.")
+
+ fmt.Println("Generating nonce...")
+ nonce := noncegen(publicKey)
+ fmt.Println("Generated nonce.")
+
+ fmt.Println("Generating config file...")
+
+ configContent := fmt.Sprintf(`IsTestMode: true
+WorkingRoot: "./"
+PrivateKeyFile: "%s"
+PubKeyStoreFile: "%s"
+DHTFileName: "dht.db"
+ListenAddr: "0.0.0.0:4661"
+ThisNodeID: %s
+MinNodeIDDifficulty: 24
+BlockProducer:
+ PublicKey: 034b4319f2e2a9d9f3fd55d1233ff7a2f2ea2e815e7227b3861b4a6a24a8d62697
+ NodeID: 0000011839f464418166658ef6dec09ea68da1619a7a9e0f247f16e0d6c6504d
+ Nonce:
+ a: 761802
+ b: 0
+ c: 0
+ d: 4611686019290328603
+ ChainFileName: "chain.db"
+ BPGenesisInfo:
+ Version: 1
+ BlockHash: f745ca6427237aac858dd3c7f2df8e6f3c18d0f1c164e07a1c6b8eebeba6b154
+ Producer: 0000000000000000000000000000000000000000000000000000000000000001
+ MerkleRoot: 0000000000000000000000000000000000000000000000000000000000000001
+ ParentHash: 0000000000000000000000000000000000000000000000000000000000000001
+ Timestamp: 2018-09-01T00:00:00Z
+ BaseAccounts:
+ - Address: d3dce44e0a4f1dae79b93f04ce13fb5ab719059f7409d7ca899d4c921da70129
+ StableCoinBalance: 100000000
+ CovenantCoinBalance: 100000000
+KnownNodes:
+- ID: 0000011839f464418166658ef6dec09ea68da1619a7a9e0f247f16e0d6c6504d
+ Nonce:
+ a: 761802
+ b: 0
+ c: 0
+ d: 4611686019290328603
+ Addr: 120.79.254.36:11105
+ PublicKey: 034b4319f2e2a9d9f3fd55d1233ff7a2f2ea2e815e7227b3861b4a6a24a8d62697
+ Role: Leader
+- ID: 00000177647ade3bd86a085510113ccae4b8e690424bb99b95b3545039ae8e8c
+ Nonce:
+ a: 197619
+ b: 0
+ c: 0
+ d: 4611686019249700888
+ Addr: 120.79.254.36:11106
+ PublicKey: 02d6f3afcd26aa8de25f5d088c5f8d6b052b4ad1b27ce5b84939bc9f105556844e
+ Role: Miner
+- ID: 000004b0267f959e645b0df5cd38ae0652c1160b960cdcb97b322caafe627e4f
+ Nonce:
+ a: 455820
+ b: 0
+ c: 0
+ d: 3627017019
+ Addr: 120.79.254.36:11107
+ PublicKey: 034b4319f2e2a9d9f3fd55d1233ff7a2f2ea2e815e7227b3861b4a6a24a8d62697
+ Role: Follower
+- ID: 00000328ef30233890f61d7504b640b45e8ba33d5671157a0cee81745e46b963
+ Nonce:
+ a: 333847
+ b: 0
+ c: 0
+ d: 6917529031239958890
+ Addr: 120.79.254.36:11108
+ PublicKey: 0202361b87a087cd61137ba3b5bd83c48c180566c8d7f1a0b386c3277bf0dc6ebd
+ Role: Miner
+- ID: %s
+ Nonce:
+ a: %d
+ b: %d
+ c: %d
+ d: %d
+ Addr: 127.0.0.1:11109
+ PublicKey: %s
+ Role: Client
+`, privateKeyFileName, publicKeystoreFileName,
+ nonce.Hash.String(), nonce.Hash.String(),
+ nonce.Nonce.A, nonce.Nonce.B, nonce.Nonce.C, nonce.Nonce.D, hex.EncodeToString(publicKey.Serialize()))
+
+ err = ioutil.WriteFile(path.Join(workingRoot, "config.yaml"), []byte(configContent), 0755)
+ if err != nil {
+ log.WithError(err).Error("unexpected error")
+ os.Exit(1)
+ }
+ fmt.Println("Generated nonce.")
+}
diff --git a/cmd/cql-utils/idminer.go b/cmd/cql-utils/idminer.go
new file mode 100644
index 000000000..b99da343d
--- /dev/null
+++ b/cmd/cql-utils/idminer.go
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2018 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 main
+
+import (
+ "encoding/hex"
+ "flag"
+ "fmt"
+ "math"
+ "math/rand"
+ "os"
+ "os/signal"
+ "runtime"
+ "syscall"
+ "time"
+
+ "github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
+ "github.com/CovenantSQL/CovenantSQL/crypto/kms"
+ mine "github.com/CovenantSQL/CovenantSQL/pow/cpuminer"
+ "github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
+)
+
+var (
+ difficulty int
+)
+
+func init() {
+ flag.IntVar(&difficulty, "difficulty", 24, "difficulty for miner to mine nodes and generating nonce")
+}
+
+func runMiner() {
+ masterKey, err := readMasterKey()
+ if err != nil {
+ fmt.Printf("read master key failed: %v\n", err)
+ os.Exit(1)
+ }
+
+ var publicKey *asymmetric.PublicKey
+
+ if publicKeyHex != "" {
+ publicKeyBytes, err := hex.DecodeString(publicKeyHex)
+ if err != nil {
+ log.WithError(err).Fatal("error converting hex")
+ }
+ publicKey, err = asymmetric.ParsePubKey(publicKeyBytes)
+ if err != nil {
+ log.WithError(err).Fatal("error converting public key")
+ }
+ } else if privateKeyFile != "" {
+ privateKey, err := kms.LoadPrivateKey(privateKeyFile, []byte(masterKey))
+ if err != nil {
+ log.WithError(err).Fatal("load private key file failed")
+ }
+ publicKey = privateKey.PubKey()
+ }
+
+ signalCh := make(chan os.Signal, 1)
+ signal.Notify(
+ signalCh,
+ syscall.SIGINT,
+ syscall.SIGTERM,
+ )
+ signal.Ignore(syscall.SIGHUP, syscall.SIGTTIN, syscall.SIGTTOU)
+
+ cpuCount := runtime.NumCPU()
+ log.Infof("cpu: %#v\n", cpuCount)
+ nonceChs := make([]chan mine.NonceInfo, cpuCount)
+ stopChs := make([]chan struct{}, cpuCount)
+
+ rand.Seed(time.Now().UnixNano())
+ step := math.MaxUint64 / uint64(cpuCount)
+
+ for i := 0; i < cpuCount; i++ {
+ nonceChs[i] = make(chan mine.NonceInfo)
+ stopChs[i] = make(chan struct{})
+ go func(i int) {
+ miner := mine.NewCPUMiner(stopChs[i])
+ nonceCh := nonceChs[i]
+ block := mine.MiningBlock{
+ Data: publicKey.Serialize(),
+ NonceChan: nonceCh,
+ Stop: nil,
+ }
+ start := mine.Uint256{D: step*uint64(i) + uint64(rand.Uint32())}
+ log.Infof("miner #%#v start: %#v\n", i, start)
+ miner.ComputeBlockNonce(block, start, difficulty)
+ }(i)
+ }
+
+ sig := <-signalCh
+ log.Infof("received signal %#v\n", sig)
+ for i := 0; i < cpuCount; i++ {
+ close(stopChs[i])
+ }
+
+ max := mine.NonceInfo{}
+ for i := 0; i < cpuCount; i++ {
+ newNonce := <-nonceChs[i]
+ if max.Difficulty < newNonce.Difficulty {
+ max = newNonce
+ }
+ }
+
+ // verify result
+ log.Infof("verify result: %#v\n", kms.IsIDPubNonceValid(&proto.RawNodeID{Hash: max.Hash}, &max.Nonce, publicKey))
+
+ // print result
+ fmt.Printf("nonce: %v\n", max)
+ fmt.Printf("node id: %v\n", max.Hash.String())
+}
diff --git a/cmd/cql-utils/keygen.go b/cmd/cql-utils/keygen.go
new file mode 100644
index 000000000..816477bde
--- /dev/null
+++ b/cmd/cql-utils/keygen.go
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2018 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 main
+
+import (
+ "bufio"
+ "encoding/hex"
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
+ "github.com/CovenantSQL/CovenantSQL/crypto/kms"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
+)
+
+func runKeygen() *asymmetric.PublicKey {
+ if _, err := os.Stat(privateKeyFile); err == nil {
+ reader := bufio.NewReader(os.Stdin)
+ fmt.Println("Private key file has already existed. \nDo you want to delete it? (y or n, press Enter for default n):")
+ t, err := reader.ReadString('\n')
+ t = strings.Trim(t, "\n")
+ if err != nil {
+ log.WithError(err).Error("unexpected error")
+ os.Exit(1)
+ }
+ if strings.Compare(t, "y") == 0 || strings.Compare(t, "yes") == 0 {
+ err = os.Remove(privateKeyFile)
+ if err != nil {
+ log.WithError(err).Error("unexpected error")
+ os.Exit(1)
+ }
+ } else {
+ os.Exit(0)
+ }
+ }
+
+ privateKey, _, err := asymmetric.GenSecp256k1KeyPair()
+ if err != nil {
+ log.WithError(err).Fatal("generate key pair failed")
+ }
+
+ masterKey, err := readMasterKey()
+ if err != nil {
+ log.WithError(err).Fatal("read master key failed")
+ }
+
+ if err = kms.SavePrivateKey(privateKeyFile, privateKey, []byte(masterKey)); err != nil {
+ log.WithError(err).Fatal("save generated keypair failed")
+ }
+
+ fmt.Printf("Private key file: %s\n", privateKeyFile)
+ fmt.Printf("Public key's hex: %s\n", hex.EncodeToString(privateKey.PubKey().Serialize()))
+ return privateKey.PubKey()
+}
diff --git a/cmd/cql-utils/keytool.go b/cmd/cql-utils/keytool.go
new file mode 100644
index 000000000..d96afcf64
--- /dev/null
+++ b/cmd/cql-utils/keytool.go
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2018 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 main
+
+import (
+ "encoding/hex"
+ "fmt"
+ "os"
+
+ "github.com/CovenantSQL/CovenantSQL/crypto/kms"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
+)
+
+func runKeytool() {
+ masterKey, err := readMasterKey()
+ if err != nil {
+ fmt.Printf("read master key failed: %v\n", err)
+ os.Exit(1)
+ }
+
+ privateKey, err := kms.LoadPrivateKey(privateKeyFile, []byte(masterKey))
+ if err != nil {
+ log.WithError(err).Error("load private key failed")
+ }
+
+ fmt.Printf("Public key's hex: %s\n", hex.EncodeToString(privateKey.PubKey().Serialize()))
+}
diff --git a/cmd/cql-utils/main.go b/cmd/cql-utils/main.go
index a769b1494..052f5b87c 100644
--- a/cmd/cql-utils/main.go
+++ b/cmd/cql-utils/main.go
@@ -17,36 +17,13 @@
package main
import (
- "bufio"
- "encoding/hex"
- "encoding/json"
"flag"
"fmt"
- "io/ioutil"
- "math"
- "math/rand"
"os"
- "os/signal"
- "path"
- "reflect"
"runtime"
- "strings"
"syscall"
- "time"
- "github.com/CovenantSQL/CovenantSQL/blockproducer"
- "github.com/CovenantSQL/CovenantSQL/client"
- "github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
- "github.com/CovenantSQL/CovenantSQL/crypto/kms"
- mine "github.com/CovenantSQL/CovenantSQL/pow/cpuminer"
- "github.com/CovenantSQL/CovenantSQL/proto"
- "github.com/CovenantSQL/CovenantSQL/route"
- "github.com/CovenantSQL/CovenantSQL/rpc"
- "github.com/CovenantSQL/CovenantSQL/sqlchain"
"github.com/CovenantSQL/CovenantSQL/utils/log"
- "github.com/CovenantSQL/CovenantSQL/worker"
-
- "github.com/CovenantSQL/CovenantSQL/crypto"
"golang.org/x/crypto/ssh/terminal"
)
@@ -55,39 +32,30 @@ var (
tool string
publicKeyHex string
privateKeyFile string
- difficulty int
- rpcName string
- rpcEndpoint string
- rpcReq string
configFile string
- workingRoot string
- isTestNetAddr bool
- rpcServiceMap = map[string]interface{}{
- "DHT": &route.DHTService{},
- "DBS": &worker.DBMSRPCService{},
- "BPDB": &blockproducer.DBService{},
- "SQLC": &sqlchain.MuxService{},
- }
+ showVersion bool
)
+const name = "cql-utils"
+
func init() {
- log.SetLevel(log.ErrorLevel)
+ log.SetLevel(log.InfoLevel)
- flag.StringVar(&tool, "tool", "", "tool type, miner, keygen, keytool, rpc, nonce, confgen, addrgen")
+ flag.StringVar(&tool, "tool", "", "tool type, miner, keygen, keytool, rpc, nonce, confgen, addrgen, adapterconfgen")
flag.StringVar(&publicKeyHex, "public", "", "public key hex string to mine node id/nonce")
flag.StringVar(&privateKeyFile, "private", "private.key", "private key file to generate/show")
- flag.IntVar(&difficulty, "difficulty", 24, "difficulty for miner to mine nodes and generating nonce")
- flag.StringVar(&rpcName, "rpc", "", "rpc name to do test call")
- flag.StringVar(&rpcEndpoint, "endpoint", "", "rpc endpoint to do test call")
- flag.StringVar(&rpcReq, "req", "", "rpc request to do test call, in json format")
- flag.StringVar(&configFile, "config", "", "rpc config file")
- flag.StringVar(&workingRoot, "root", "conf", "confgen root is the working root directory containing all auto-generating keys and certifications")
- flag.BoolVar(&isTestNetAddr, "addrgen", false, "addrgen generates a testnet address from your key pair")
+ flag.StringVar(&configFile, "config", "config.yaml", "config file to use")
+ flag.BoolVar(&showVersion, "version", false, "Show version information and exit")
}
func main() {
- log.Infof("idminer build: %s\n", version)
flag.Parse()
+ if showVersion {
+ fmt.Printf("%v %v %v %v %v\n",
+ name, version, runtime.GOOS, runtime.GOARCH, runtime.Version())
+ os.Exit(0)
+ }
+ log.Infof("cql-utils build: %#v\n", version)
switch tool {
case "miner":
@@ -112,25 +80,13 @@ func main() {
}
runKeytool()
case "rpc":
- if configFile == "" {
- // error
- log.Error("config file path is required for rpc tool")
- os.Exit(1)
- }
- if rpcEndpoint == "" || rpcName == "" || rpcReq == "" {
- // error
- log.Error("rpc payload is required for rpc tool")
- os.Exit(1)
- }
runRPC()
case "nonce":
runNonce()
case "confgen":
- if workingRoot == "" {
- log.Error("root directory is required for confgen")
- os.Exit(1)
- }
runConfgen()
+ case "adapterconfgen":
+ runAdapterConfGen()
case "addrgen":
if privateKeyFile == "" && publicKeyHex == "" {
log.Error("privateKey path or publicKey hex is required for addrgen")
@@ -143,477 +99,6 @@ func main() {
}
}
-func runMiner() {
- masterKey, err := readMasterKey()
- if err != nil {
- fmt.Printf("read master key failed: %v\n", err)
- os.Exit(1)
- }
-
- var publicKey *asymmetric.PublicKey
-
- if publicKeyHex != "" {
- publicKeyBytes, err := hex.DecodeString(publicKeyHex)
- if err != nil {
- log.Fatalf("error converting hex: %s\n", err)
- }
- publicKey, err = asymmetric.ParsePubKey(publicKeyBytes)
- if err != nil {
- log.Fatalf("error converting public key: %s\n", err)
- }
- } else if privateKeyFile != "" {
- privateKey, err := kms.LoadPrivateKey(privateKeyFile, []byte(masterKey))
- if err != nil {
- log.Fatalf("load private key file faile: %v\n", err)
- }
- publicKey = privateKey.PubKey()
- }
-
- signalCh := make(chan os.Signal, 1)
- signal.Notify(
- signalCh,
- syscall.SIGINT,
- syscall.SIGTERM,
- )
- signal.Ignore(syscall.SIGHUP, syscall.SIGTTIN, syscall.SIGTTOU)
-
- cpuCount := runtime.NumCPU()
- log.Infof("cpu: %d\n", cpuCount)
- nonceChs := make([]chan mine.NonceInfo, cpuCount)
- stopChs := make([]chan struct{}, cpuCount)
-
- rand.Seed(time.Now().UnixNano())
- step := math.MaxUint64 / uint64(cpuCount)
-
- for i := 0; i < cpuCount; i++ {
- nonceChs[i] = make(chan mine.NonceInfo)
- stopChs[i] = make(chan struct{})
- go func(i int) {
- miner := mine.NewCPUMiner(stopChs[i])
- nonceCh := nonceChs[i]
- block := mine.MiningBlock{
- Data: publicKey.Serialize(),
- NonceChan: nonceCh,
- Stop: nil,
- }
- start := mine.Uint256{D: step*uint64(i) + uint64(rand.Uint32())}
- log.Infof("miner #%d start: %v\n", i, start)
- miner.ComputeBlockNonce(block, start, difficulty)
- }(i)
- }
-
- sig := <-signalCh
- log.Infof("received signal %s\n", sig)
- for i := 0; i < cpuCount; i++ {
- close(stopChs[i])
- }
-
- max := mine.NonceInfo{}
- for i := 0; i < cpuCount; i++ {
- newNonce := <-nonceChs[i]
- if max.Difficulty < newNonce.Difficulty {
- max = newNonce
- }
- }
-
- // verify result
- log.Infof("verify result: %v\n", kms.IsIDPubNonceValid(&proto.RawNodeID{Hash: max.Hash}, &max.Nonce, publicKey))
-
- // print result
- fmt.Printf("nonce: %v\n", max)
- fmt.Printf("node id: %v\n", max.Hash.String())
-}
-
-func runKeygen() *asymmetric.PublicKey {
- if _, err := os.Stat(privateKeyFile); err == nil {
- reader := bufio.NewReader(os.Stdin)
- fmt.Println("Private key file has already existed. \nDo you want to delete it? (y or n, press Enter for default n):")
- t, err := reader.ReadString('\n')
- t = strings.Trim(t, "\n")
- if err != nil {
- log.Errorf("Unexpected error: %v\n", err)
- os.Exit(1)
- }
- if strings.Compare(t, "y") == 0 || strings.Compare(t, "yes") == 0 {
- err = os.Remove(privateKeyFile)
- if err != nil {
- log.Errorf("Unexpected error: %v\n", err)
- os.Exit(1)
- }
- } else {
- os.Exit(0)
- }
- }
-
- privateKey, _, err := asymmetric.GenSecp256k1KeyPair()
- if err != nil {
- log.Fatalf("generate key pair failed: %v\n", err)
- }
-
- masterKey, err := readMasterKey()
- if err != nil {
- log.Fatalf("read master key failed: %v\n", err)
- }
-
- if err = kms.SavePrivateKey(privateKeyFile, privateKey, []byte(masterKey)); err != nil {
- log.Fatalf("save generated keypair failed: %v\n", err)
- }
-
- fmt.Printf("Private key file: %s\n", privateKeyFile)
- fmt.Printf("Public key's hex: %s\n", hex.EncodeToString(privateKey.PubKey().Serialize()))
- return privateKey.PubKey()
-}
-
-func runKeytool() {
- masterKey, err := readMasterKey()
- if err != nil {
- fmt.Printf("read master key failed: %v\n", err)
- os.Exit(1)
- }
-
- privateKey, err := kms.LoadPrivateKey(privateKeyFile, []byte(masterKey))
- if err != nil {
- log.Errorf("load private key failed: %v\n", err)
- }
-
- fmt.Printf("Public key's hex: %s\n", hex.EncodeToString(privateKey.PubKey().Serialize()))
-}
-
-func runRPC() {
- if err := client.Init(configFile, []byte("")); err != nil {
- fmt.Printf("init rpc client failed: %v\n", err)
- os.Exit(1)
- return
- }
-
- req, resp := resolveRPCEntities()
-
- // fill the req with request body
- if err := json.Unmarshal([]byte(rpcReq), req); err != nil {
- fmt.Printf("decode request body failed: %v\n", err)
- os.Exit(1)
- return
- }
-
- if err := rpc.NewCaller().CallNode(proto.NodeID(rpcEndpoint), rpcName, req, resp); err != nil {
- // send request failed
- fmt.Printf("call rpc failed: %v\n", err)
- os.Exit(1)
- return
- }
-
- // print the response
- if resBytes, err := json.MarshalIndent(resp, "", " "); err != nil {
- fmt.Printf("marshal response failed: %v\n", err)
- os.Exit(1)
- } else {
- fmt.Println(string(resBytes))
- }
-}
-
-func resolveRPCEntities() (req interface{}, resp interface{}) {
- rpcParts := strings.SplitN(rpcName, ".", 2)
-
- if len(rpcParts) != 2 {
- // error rpc name
- fmt.Printf("%v is not a valid rpc name\n", rpcName)
- os.Exit(1)
- return
- }
-
- rpcService := rpcParts[0]
-
- if s, supported := rpcServiceMap[rpcService]; supported {
- typ := reflect.TypeOf(s)
-
- // traversing methods
- for m := 0; m < typ.NumMethod(); m++ {
- method := typ.Method(m)
- mtype := method.Type
-
- if method.Name == rpcParts[1] {
- // name matched
- if mtype.PkgPath() != "" || mtype.NumIn() != 3 || mtype.NumOut() != 1 {
- fmt.Printf("%v is not a valid rpc endpoint method\n", rpcName)
- os.Exit(1)
- return
- }
-
- argType := mtype.In(1)
- replyType := mtype.In(2)
-
- if argType.Kind() == reflect.Ptr {
- req = reflect.New(argType.Elem()).Interface()
- } else {
- req = reflect.New(argType).Interface()
-
- }
-
- resp = reflect.New(replyType.Elem()).Interface()
-
- return
- }
- }
- }
-
- // not found
- fmt.Printf("rpc method %v not found\n", rpcName)
- os.Exit(1)
-
- return
-}
-
-func runNonce() {
- var publicKey *asymmetric.PublicKey
-
- if publicKeyHex != "" {
- publicKeyBytes, err := hex.DecodeString(publicKeyHex)
- if err != nil {
- log.Fatalf("error converting hex: %s\n", err)
- }
- publicKey, err = asymmetric.ParsePubKey(publicKeyBytes)
- if err != nil {
- log.Fatalf("error converting public key: %s\n", err)
- }
- } else if privateKeyFile != "" {
- masterKey, err := readMasterKey()
- if err != nil {
- fmt.Printf("read master key failed: %v\n", err)
- os.Exit(1)
- }
- privateKey, err := kms.LoadPrivateKey(privateKeyFile, []byte(masterKey))
- if err != nil {
- log.Fatalf("load private key file fail: %v\n", err)
- }
- publicKey = privateKey.PubKey()
- } else {
- log.Fatalln("can neither convert public key nor load private key")
- }
-
- noncegen(publicKey)
-}
-
-func noncegen(publicKey *asymmetric.PublicKey) *mine.NonceInfo {
- publicKeyBytes := publicKey.Serialize()
-
- cpuCount := runtime.NumCPU()
- log.Infof("cpu: %d\n", cpuCount)
- stopCh := make(chan struct{})
- nonceCh := make(chan mine.NonceInfo)
-
- rand.Seed(time.Now().UnixNano())
- step := 256 / cpuCount
- for i := 0; i < cpuCount; i++ {
- go func(i int) {
- startBit := i * step
- position := startBit / 64
- shift := uint(startBit % 64)
- log.Infof("position: %d, shift: %d, i: %d", position, shift, i)
- var start mine.Uint256
- if position == 0 {
- start = mine.Uint256{A: uint64(1<= difficulty {
- nonce := mine.NonceInfo{
- Nonce: j,
- Difficulty: currentDifficulty,
- Hash: currentHash,
- }
- nonceCh <- nonce
- }
- }
- }
- }(i)
- }
-
- nonce := <-nonceCh
- close(stopCh)
-
- // verify result
- if !kms.IsIDPubNonceValid(&proto.RawNodeID{Hash: nonce.Hash}, &nonce.Nonce, publicKey) {
- log.Fatalf("nonce: %v\nnode id: %s", nonce, nonce.Hash.String())
- }
-
- // print result
- fmt.Printf("nonce: %v\n", nonce)
- fmt.Printf("node id: %v\n", nonce.Hash.String())
-
- return &nonce
-}
-
-func runConfgen() {
- privateKeyFileName := "private.key"
- publicKeystoreFileName := "public.keystore"
-
- privateKeyFile = path.Join(workingRoot, privateKeyFileName)
-
- if _, err := os.Stat(workingRoot); err == nil {
- reader := bufio.NewReader(os.Stdin)
- fmt.Println("The directory has already existed. \nDo you want to delete it? (y or n, press Enter for default n):")
- t, err := reader.ReadString('\n')
- t = strings.Trim(t, "\n")
- if err != nil {
- log.Errorf("Unexpected error: %v\n", err)
- os.Exit(1)
- }
- if strings.Compare(t, "y") == 0 || strings.Compare(t, "yes") == 0 {
- os.RemoveAll(workingRoot)
- } else {
- os.Exit(0)
- }
- }
-
- err := os.Mkdir(workingRoot, 0755)
- if err != nil {
- log.Errorf("Unexpected error: %v", err)
- os.Exit(1)
- }
-
- fmt.Println("Generating key pair...")
- publicKey := runKeygen()
- fmt.Println("Generated key pair.")
-
- fmt.Println("Generating nonce...")
- nonce := noncegen(publicKey)
- fmt.Println("Generated nonce.")
-
- fmt.Println("Generating config file...")
-
- configContent := fmt.Sprintf(`IsTestMode: true
-WorkingRoot: "./"
-PrivateKeyFile: "%s"
-PubKeyStoreFile: "%s"
-DHTFileName: "dht.db"
-ListenAddr: "0.0.0.0:4661"
-ThisNodeID: %s
-MinNodeIDDifficulty: 24
-BlockProducer:
- PublicKey: 034b4319f2e2a9d9f3fd55d1233ff7a2f2ea2e815e7227b3861b4a6a24a8d62697
- NodeID: 0000011839f464418166658ef6dec09ea68da1619a7a9e0f247f16e0d6c6504d
- Nonce:
- a: 761802
- b: 0
- c: 0
- d: 4611686019290328603
- ChainFileName: "chain.db"
- BPGenesisInfo:
- Version: 1
- BlockHash: f745ca6427237aac858dd3c7f2df8e6f3c18d0f1c164e07a1c6b8eebeba6b154
- Producer: 0000000000000000000000000000000000000000000000000000000000000001
- MerkleRoot: 0000000000000000000000000000000000000000000000000000000000000001
- ParentHash: 0000000000000000000000000000000000000000000000000000000000000001
- Timestamp: 2018-09-01T00:00:00Z
- BaseAccounts:
- - Address: d3dce44e0a4f1dae79b93f04ce13fb5ab719059f7409d7ca899d4c921da70129
- StableCoinBalance: 100000000
- CovenantCoinBalance: 100000000
-KnownNodes:
-- ID: 0000011839f464418166658ef6dec09ea68da1619a7a9e0f247f16e0d6c6504d
- Nonce:
- a: 761802
- b: 0
- c: 0
- d: 4611686019290328603
- Addr: 120.79.254.36:11105
- PublicKey: 034b4319f2e2a9d9f3fd55d1233ff7a2f2ea2e815e7227b3861b4a6a24a8d62697
- Role: Leader
-- ID: 00000177647ade3bd86a085510113ccae4b8e690424bb99b95b3545039ae8e8c
- Nonce:
- a: 197619
- b: 0
- c: 0
- d: 4611686019249700888
- Addr: 120.79.254.36:11106
- PublicKey: 02d6f3afcd26aa8de25f5d088c5f8d6b052b4ad1b27ce5b84939bc9f105556844e
- Role: Miner
-- ID: 000004b0267f959e645b0df5cd38ae0652c1160b960cdcb97b322caafe627e4f
- Nonce:
- a: 455820
- b: 0
- c: 0
- d: 3627017019
- Addr: 120.79.254.36:11107
- PublicKey: 034b4319f2e2a9d9f3fd55d1233ff7a2f2ea2e815e7227b3861b4a6a24a8d62697
- Role: Follower
-- ID: 00000328ef30233890f61d7504b640b45e8ba33d5671157a0cee81745e46b963
- Nonce:
- a: 333847
- b: 0
- c: 0
- d: 6917529031239958890
- Addr: 120.79.254.36:11108
- PublicKey: 0202361b87a087cd61137ba3b5bd83c48c180566c8d7f1a0b386c3277bf0dc6ebd
- Role: Miner
-- ID: %s
- Nonce:
- a: %d
- b: %d
- c: %d
- d: %d
- Addr: 127.0.0.1:11109
- PublicKey: %s
- Role: Client
-`, privateKeyFileName, publicKeystoreFileName,
- nonce.Hash.String(), nonce.Hash.String(),
- nonce.Nonce.A, nonce.Nonce.B, nonce.Nonce.C, nonce.Nonce.D, hex.EncodeToString(publicKey.Serialize()))
-
- err = ioutil.WriteFile(path.Join(workingRoot, "config.yaml"), []byte(configContent), 0755)
- if err != nil {
- log.Errorf("Unexpected error: %v\n", err)
- os.Exit(1)
- }
- fmt.Println("Generated nonce.")
-}
-
-func runAddrgen() {
- var publicKey *asymmetric.PublicKey
-
- if publicKeyHex != "" {
- publicKeyBytes, err := hex.DecodeString(publicKeyHex)
- if err != nil {
- log.Fatalf("error converting hex: %s\n", err)
- }
- publicKey, err = asymmetric.ParsePubKey(publicKeyBytes)
- if err != nil {
- log.Fatalf("error converting public key: %s\n", err)
- }
- } else if privateKeyFile != "" {
- masterKey, err := readMasterKey()
- if err != nil {
- fmt.Printf("read master key failed: %v\n", err)
- os.Exit(1)
- }
- privateKey, err := kms.LoadPrivateKey(privateKeyFile, []byte(masterKey))
- if err != nil {
- log.Fatalf("load private key file fail: %v\n", err)
- }
- publicKey = privateKey.PubKey()
- } else {
- fmt.Println("privateKey path or publicKey hex is required for addrgen")
- os.Exit(1)
- }
-
- addr, err := crypto.PubKey2Addr(publicKey, crypto.TestNet)
- if err != nil {
- log.Fatalf("unexpected error: %v\n", err)
- }
- fmt.Printf("wallet address: %s\n", addr)
-}
-
func readMasterKey() (string, error) {
fmt.Println("Enter master key(press Enter for default: \"\"): ")
bytePwd, err := terminal.ReadPassword(int(syscall.Stdin))
diff --git a/cmd/cql-utils/noncegen.go b/cmd/cql-utils/noncegen.go
new file mode 100644
index 000000000..be8acad38
--- /dev/null
+++ b/cmd/cql-utils/noncegen.go
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2018 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 main
+
+import (
+ "encoding/hex"
+ "fmt"
+ "math/rand"
+ "os"
+ "runtime"
+ "time"
+
+ "github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
+ "github.com/CovenantSQL/CovenantSQL/crypto/kms"
+ mine "github.com/CovenantSQL/CovenantSQL/pow/cpuminer"
+ "github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
+)
+
+func runNonce() {
+ var publicKey *asymmetric.PublicKey
+
+ if publicKeyHex != "" {
+ publicKeyBytes, err := hex.DecodeString(publicKeyHex)
+ if err != nil {
+ log.WithError(err).Fatal("error converting hex")
+ }
+ publicKey, err = asymmetric.ParsePubKey(publicKeyBytes)
+ if err != nil {
+ log.WithError(err).Fatal("error converting public key")
+ }
+ } else if privateKeyFile != "" {
+ masterKey, err := readMasterKey()
+ if err != nil {
+ log.WithError(err).Error("read master key failed")
+ os.Exit(1)
+ }
+ privateKey, err := kms.LoadPrivateKey(privateKeyFile, []byte(masterKey))
+ if err != nil {
+ log.WithError(err).Fatal("load private key file failed")
+ }
+ publicKey = privateKey.PubKey()
+ } else {
+ log.Fatalln("can neither convert public key nor load private key")
+ }
+
+ noncegen(publicKey)
+}
+
+func noncegen(publicKey *asymmetric.PublicKey) *mine.NonceInfo {
+ publicKeyBytes := publicKey.Serialize()
+
+ cpuCount := runtime.NumCPU()
+ log.Infof("cpu: %#v\n", cpuCount)
+ stopCh := make(chan struct{})
+ nonceCh := make(chan mine.NonceInfo)
+
+ rand.Seed(time.Now().UnixNano())
+ step := 256 / cpuCount
+ for i := 0; i < cpuCount; i++ {
+ go func(i int) {
+ startBit := i * step
+ position := startBit / 64
+ shift := uint(startBit % 64)
+ log.Infof("position: %#v, shift: %#v, i: %#v", position, shift, i)
+ var start mine.Uint256
+ if position == 0 {
+ start = mine.Uint256{A: uint64(1<= difficulty {
+ nonce := mine.NonceInfo{
+ Nonce: j,
+ Difficulty: currentDifficulty,
+ Hash: currentHash,
+ }
+ nonceCh <- nonce
+ }
+ }
+ }
+ }(i)
+ }
+
+ nonce := <-nonceCh
+ close(stopCh)
+
+ // verify result
+ if !kms.IsIDPubNonceValid(&proto.RawNodeID{Hash: nonce.Hash}, &nonce.Nonce, publicKey) {
+ log.WithFields(log.Fields{
+ "nonce": nonce,
+ "id": nonce.Hash.String(),
+ }).Fatal("invalid nonce")
+ }
+
+ // print result
+ fmt.Printf("nonce: %v\n", nonce)
+ fmt.Printf("node id: %v\n", nonce.Hash.String())
+
+ return &nonce
+}
diff --git a/cmd/cql-utils/rpc.go b/cmd/cql-utils/rpc.go
new file mode 100644
index 000000000..f3663fceb
--- /dev/null
+++ b/cmd/cql-utils/rpc.go
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2018 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 main
+
+import (
+ "encoding/json"
+ "flag"
+ "fmt"
+ "os"
+ "reflect"
+ "strings"
+
+ "github.com/CovenantSQL/CovenantSQL/blockproducer"
+ bp "github.com/CovenantSQL/CovenantSQL/blockproducer"
+ "github.com/CovenantSQL/CovenantSQL/client"
+ "github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
+ "github.com/CovenantSQL/CovenantSQL/crypto/kms"
+ "github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/route"
+ "github.com/CovenantSQL/CovenantSQL/rpc"
+ "github.com/CovenantSQL/CovenantSQL/sqlchain"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
+ "github.com/CovenantSQL/CovenantSQL/worker"
+ "gopkg.in/yaml.v2"
+)
+
+var (
+ rpcServiceMap = map[string]interface{}{
+ route.DHTRPCName: &route.DHTService{},
+ route.DBRPCName: &worker.DBMSRPCService{},
+ route.BPDBRPCName: &blockproducer.DBService{},
+ route.SQLChainRPCName: &sqlchain.MuxService{},
+ route.BlockProducerRPCName: &bp.ChainRPCService{},
+ }
+ rpcName string
+ rpcEndpoint string
+ rpcReq string
+)
+
+type canSign interface {
+ Sign(signer *asymmetric.PrivateKey) error
+}
+
+func init() {
+ flag.StringVar(&rpcName, "rpc", "", "rpc name to do test call")
+ flag.StringVar(&rpcEndpoint, "rpc-endpoint", "", "rpc endpoint to do test call")
+ flag.StringVar(&rpcReq, "rpc-req", "", "rpc request to do test call, in json format")
+}
+
+func runRPC() {
+ if configFile == "" {
+ // error
+ log.Error("config file path is required for rpc tool")
+ os.Exit(1)
+ }
+ if rpcEndpoint == "" || rpcName == "" || rpcReq == "" {
+ // error
+ log.Error("rpc payload is required for rpc tool")
+ os.Exit(1)
+ }
+
+ if err := client.Init(configFile, []byte("")); err != nil {
+ fmt.Printf("init rpc client failed: %v\n", err)
+ os.Exit(1)
+ return
+ }
+
+ req, resp := resolveRPCEntities()
+
+ // fill the req with request body
+ if err := json.Unmarshal([]byte(rpcReq), req); err != nil {
+ fmt.Printf("decode request body failed: %v\n", err)
+ os.Exit(1)
+ return
+ }
+
+ // requires signature?
+ if err := checkAndSign(req); err != nil {
+ fmt.Printf("sign request failed: %v\n", err)
+ os.Exit(1)
+ return
+ }
+
+ if err := rpc.NewCaller().CallNode(proto.NodeID(rpcEndpoint), rpcName, req, resp); err != nil {
+ // send request failed
+ fmt.Printf("call rpc failed: %v\n", err)
+ os.Exit(1)
+ return
+ }
+
+ // print the response
+ if resBytes, err := yaml.Marshal(resp); err != nil {
+ fmt.Printf("marshal response failed: %v\n", err)
+ os.Exit(1)
+ } else {
+ fmt.Println(string(resBytes))
+ }
+}
+
+func checkAndSign(req interface{}) (err error) {
+ if reflect.ValueOf(req).Kind() != reflect.Ptr {
+ return checkAndSign(&req)
+ }
+
+ if canSignObj, ok := req.(canSign); ok {
+ var privKey *asymmetric.PrivateKey
+ if privKey, err = kms.GetLocalPrivateKey(); err != nil {
+ return
+ }
+ if err = canSignObj.Sign(privKey); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+func resolveRPCEntities() (req interface{}, resp interface{}) {
+ rpcParts := strings.SplitN(rpcName, ".", 2)
+
+ if len(rpcParts) != 2 {
+ // error rpc name
+ fmt.Printf("%v is not a valid rpc name\n", rpcName)
+ os.Exit(1)
+ return
+ }
+
+ rpcService := rpcParts[0]
+
+ if s, supported := rpcServiceMap[rpcService]; supported {
+ typ := reflect.TypeOf(s)
+
+ // traversing methods
+ for m := 0; m < typ.NumMethod(); m++ {
+ method := typ.Method(m)
+ mtype := method.Type
+
+ if method.Name == rpcParts[1] {
+ // name matched
+ if mtype.PkgPath() != "" || mtype.NumIn() != 3 || mtype.NumOut() != 1 {
+ fmt.Printf("%v is not a valid rpc endpoint method\n", rpcName)
+ os.Exit(1)
+ return
+ }
+
+ argType := mtype.In(1)
+ replyType := mtype.In(2)
+
+ if argType.Kind() == reflect.Ptr {
+ req = reflect.New(argType.Elem()).Interface()
+ } else {
+ req = reflect.New(argType).Interface()
+ }
+
+ resp = reflect.New(replyType.Elem()).Interface()
+
+ return
+ }
+ }
+ }
+
+ // not found
+ fmt.Printf("rpc method %v not found\n", rpcName)
+ os.Exit(1)
+
+ return
+}
diff --git a/cmd/cql/main.go b/cmd/cql/main.go
index 9fed8cdf5..5ec683a4c 100644
--- a/cmd/cql/main.go
+++ b/cmd/cql/main.go
@@ -25,6 +25,7 @@ import (
"io"
"os"
"os/user"
+ "runtime"
"strconv"
"strings"
@@ -40,6 +41,8 @@ import (
"github.com/xo/usql/text"
)
+const name = "cql"
+
var (
version = "unknown"
dsn string
@@ -50,6 +53,7 @@ var (
configFile string
password string
singleTransaction bool
+ showVersion bool
variables varsFlag
// DML variables
@@ -145,7 +149,7 @@ func init() {
return 0, nil
},
Open: func(url *dburl.URL) (func(string, string) (*sql.DB, error), error) {
- log.Infof("connecting to %v", url.DSN)
+ log.Infof("connecting to %#v", url.DSN)
return sql.Open, nil
},
})
@@ -171,6 +175,7 @@ func init() {
flag.StringVar(&dsn, "dsn", "", "database url")
flag.StringVar(&command, "command", "", "run only single command (SQL or usql internal command) and exit")
flag.StringVar(&fileName, "file", "", "execute commands from file and exit")
+ flag.BoolVar(&showVersion, "version", false, "Show version information and exit")
flag.BoolVar(&noRC, "no-rc", false, "do not read start up file")
flag.BoolVar(&asymmetric.BypassSignature, "bypassSignature", false,
"Disable signature sign and verify, for testing")
@@ -188,12 +193,17 @@ func init() {
func main() {
flag.Parse()
+ if showVersion {
+ fmt.Printf("%v %v %v %v %v\n",
+ name, version, runtime.GOOS, runtime.GOARCH, runtime.Version())
+ os.Exit(0)
+ }
var err error
// init covenantsql driver
if err = client.Init(configFile, []byte(password)); err != nil {
- log.Errorf("init covenantsql client failed: %v", err)
+ log.WithError(err).Error("init covenantsql client failed")
os.Exit(-1)
return
}
@@ -202,16 +212,16 @@ func main() {
var stableCoinBalance, covenantCoinBalance uint64
if stableCoinBalance, err = client.GetStableCoinBalance(); err != nil {
- log.Errorf("get stable coin balance failed: %v", err)
+ log.WithError(err).Error("get stable coin balance failed")
return
}
if covenantCoinBalance, err = client.GetCovenantCoinBalance(); err != nil {
- log.Errorf("get covenant coin balance failed: %v", err)
+ log.WithError(err).Error("get covenant coin balance failed")
return
}
- log.Infof("stable coin balance is: %v", stableCoinBalance)
- log.Infof("covenant coin balance is: %v", covenantCoinBalance)
+ log.Infof("stable coin balance is: %#v", stableCoinBalance)
+ log.Infof("covenant coin balance is: %#v", covenantCoinBalance)
return
}
@@ -227,12 +237,12 @@ func main() {
if err := client.Drop(dropDB); err != nil {
// drop database failed
- log.Errorf("drop database %v failed: %v", dropDB, err)
+ log.WithField("db", dropDB).WithError(err).Error("drop database failed")
return
}
// drop database success
- log.Infof("drop database %v success", dropDB)
+ log.Infof("drop database %#v success", dropDB)
return
}
@@ -246,7 +256,7 @@ func main() {
nodeCnt, err := strconv.ParseUint(createDB, 10, 16)
if err != nil {
// still failing
- log.Errorf("create database failed: %v is not a valid instance description", createDB)
+ log.WithField("db", createDB).Error("create database failed: invalid instance description")
os.Exit(-1)
return
}
@@ -256,19 +266,19 @@ func main() {
dsn, err := client.Create(meta)
if err != nil {
- log.Infof("create database failed: %v", err)
+ log.WithError(err).Error("create database failed")
os.Exit(-1)
return
}
- log.Infof("the newly created database is: %v", dsn)
+ log.Infof("the newly created database is: %#v", dsn)
return
}
available := drivers.Available()
cur, err := user.Current()
if err != nil {
- log.Errorf("get current failed: %v", err)
+ log.WithError(err).Error("get current user failed")
os.Exit(-1)
return
}
@@ -276,14 +286,14 @@ func main() {
// run
err = run(cur)
if err != nil && err != io.EOF && err != rline.ErrInterrupt {
- log.Errorf("run cli error: %v", err)
+ log.WithError(err).Error("run cli error")
if e, ok := err.(*drivers.Error); ok && e.Err == text.ErrDriverNotAvailable {
bindings := make([]string, 0, len(available))
for name := range available {
bindings = append(bindings, name)
}
- log.Infof("Available drivers are: %v", bindings)
+ log.Infof("Available drivers are: %#v", bindings)
return
}
}
@@ -343,14 +353,14 @@ func run(u *user.User) (err error) {
h.SetSingleLineMode(true)
h.Reset([]rune(command))
if err = h.Run(); err != nil && err != io.EOF {
- log.Errorf("run command failed: %v", err)
+ log.WithError(err).Error("run command failed")
os.Exit(-1)
return
}
} else if fileName != "" {
// file
if err = h.Include(fileName, false); err != nil {
- log.Errorf("run file failed: %v", err)
+ log.WithError(err).Error("run file failed")
os.Exit(-1)
return
}
diff --git a/cmd/cql/util.go b/cmd/cql/util.go
index af29b3bc3..8622c372b 100644
--- a/cmd/cql/util.go
+++ b/cmd/cql/util.go
@@ -47,7 +47,6 @@ func (t *SqTime) Scan(v interface{}) error {
return nil
case []byte:
return t.parse(string(x))
-
case string:
return t.parse(x)
}
diff --git a/cmd/cqld/adapter.go b/cmd/cqld/adapter.go
index ba63f5224..af8d5ad4c 100644
--- a/cmd/cqld/adapter.go
+++ b/cmd/cqld/adapter.go
@@ -67,7 +67,7 @@ func initStorage(dbFile string) (stor *LocalStorage, err error) {
})
if err != nil {
wd, _ := os.Getwd()
- log.Errorf("create dht table %s failed: %s", utils.FJ(wd, dbFile), err)
+ log.WithField("file", utils.FJ(wd, dbFile)).WithError(err).Error("create dht table failed")
return
}
@@ -82,12 +82,12 @@ func initStorage(dbFile string) (stor *LocalStorage, err error) {
func (s *LocalStorage) Prepare(ctx context.Context, wb twopc.WriteBatch) (err error) {
payload, err := s.decodeLog(wb)
if err != nil {
- log.Errorf("decode log failed: %s", err)
+ log.WithError(err).Error("decode log failed")
return
}
execLog, err := s.compileExecLog(payload)
if err != nil {
- log.Errorf("compile exec log failed: %s", err)
+ log.WithError(err).Error("compile exec log failed")
return
}
return s.Storage.Prepare(ctx, execLog)
@@ -97,7 +97,7 @@ func (s *LocalStorage) Prepare(ctx context.Context, wb twopc.WriteBatch) (err er
func (s *LocalStorage) Commit(ctx context.Context, wb twopc.WriteBatch) (err error) {
payload, err := s.decodeLog(wb)
if err != nil {
- log.Errorf("decode log failed: %s", err)
+ log.WithError(err).Error("decode log failed")
return
}
return s.commit(ctx, payload)
@@ -107,30 +107,29 @@ func (s *LocalStorage) commit(ctx context.Context, payload *KayakPayload) (err e
var nodeToSet proto.Node
err = utils.DecodeMsgPack(payload.Data, &nodeToSet)
if err != nil {
- log.Errorf("unmarshal node from payload failed: %s", err)
+ log.WithError(err).Error("unmarshal node from payload failed")
return
}
execLog, err := s.compileExecLog(payload)
if err != nil {
- log.Errorf("compile exec log failed: %s", err)
+ log.WithError(err).Error("compile exec log failed")
return
}
err = route.SetNodeAddrCache(nodeToSet.ID.ToRawNodeID(), nodeToSet.Addr)
if err != nil {
- log.Errorf("set node addr %s %s cache failed: %v", nodeToSet.ID, nodeToSet.Addr, err)
+ log.WithFields(log.Fields{
+ "id": nodeToSet.ID,
+ "addr": nodeToSet.Addr,
+ }).WithError(err).Error("set node addr cache failed")
}
err = kms.SetNode(&nodeToSet)
if err != nil {
- log.Errorf("kms set node %v failed: %v", nodeToSet, err)
+ log.WithField("node", nodeToSet).WithError(err).Error("kms set node failed")
}
// if s.consistent == nil, it is called during Init. and AddCache will be called by consistent.InitConsistent
if s.consistent != nil {
- err = s.consistent.AddCache(nodeToSet)
- if err != nil {
- //TODO(auxten) even no error will be returned, there may be some inconsistency and needs sync periodically
- log.Errorf("add consistent cache failed: %s", err)
- }
+ s.consistent.AddCache(nodeToSet)
}
return s.Storage.Commit(ctx, execLog)
@@ -140,12 +139,12 @@ func (s *LocalStorage) commit(ctx context.Context, payload *KayakPayload) (err e
func (s *LocalStorage) Rollback(ctx context.Context, wb twopc.WriteBatch) (err error) {
payload, err := s.decodeLog(wb)
if err != nil {
- log.Errorf("decode log failed: %s", err)
+ log.WithError(err).Error("decode log failed")
return
}
execLog, err := s.compileExecLog(payload)
if err != nil {
- log.Errorf("compile exec log failed: %s", err)
+ log.WithError(err).Error("compile exec log failed")
return
}
@@ -158,11 +157,11 @@ func (s *LocalStorage) compileExecLog(payload *KayakPayload) (execLog *storage.E
var nodeToSet proto.Node
err = utils.DecodeMsgPack(payload.Data, &nodeToSet)
if err != nil {
- log.Errorf("compileExecLog: unmarshal node from payload failed: %s", err)
+ log.WithError(err).Error("compileExecLog: unmarshal node from payload failed")
return
}
query := "INSERT OR REPLACE INTO `dht` (`id`, `node`) VALUES (?, ?);"
- log.Debugf("sql: %s", query)
+ log.Debugf("sql: %#v", query)
execLog = &storage.ExecLog{
Queries: []storage.Query{
{
@@ -177,7 +176,7 @@ func (s *LocalStorage) compileExecLog(payload *KayakPayload) (execLog *storage.E
case CmdSetDatabase:
var instance wt.ServiceInstance
if err = utils.DecodeMsgPack(payload.Data, &instance); err != nil {
- log.Errorf("compileExecLog: unmarshal instance meta failed: %v", err)
+ log.WithError(err).Error("compileExecLog: unmarshal instance meta failed")
return
}
query := "INSERT OR REPLACE INTO `databases` (`id`, `meta`) VALUES (? ,?);"
@@ -195,7 +194,7 @@ func (s *LocalStorage) compileExecLog(payload *KayakPayload) (execLog *storage.E
case CmdDeleteDatabase:
var instance wt.ServiceInstance
if err = utils.DecodeMsgPack(payload.Data, &instance); err != nil {
- log.Errorf("compileExecLog: unmarshal instance id failed: %v", err)
+ log.WithError(err).Error("compileExecLog: unmarshal instance id failed")
return
}
// TODO(xq262144), should add additional limit 1 after delete clause
@@ -229,7 +228,7 @@ func (s *LocalStorage) decodeLog(wb twopc.WriteBatch) (payload *KayakPayload, er
}
err = utils.DecodeMsgPack(bytesPayload, payload)
if err != nil {
- log.Errorf("unmarshal payload failed: %s", err)
+ log.WithError(err).Error("unmarshal payload failed")
return
}
@@ -248,7 +247,7 @@ func (s *KayakKVServer) Init(storePath string, initNodes []proto.Node) (err erro
var nodeBuf *bytes.Buffer
nodeBuf, err = utils.EncodeMsgPack(n)
if err != nil {
- log.Errorf("marshal node failed: %v", err)
+ log.WithError(err).Error("marshal node failed")
return
}
payload := &KayakPayload{
@@ -259,18 +258,18 @@ func (s *KayakKVServer) Init(storePath string, initNodes []proto.Node) (err erro
var execLog *storage.ExecLog
execLog, err = s.KVStorage.compileExecLog(payload)
if err != nil {
- log.Errorf("compile exec log failed: %s", err)
+ log.WithError(err).Error("compile exec log failed")
return
}
err = s.KVStorage.Storage.Prepare(context.Background(), execLog)
if err != nil {
- log.Errorf("init kayak KV prepare node failed: %v", err)
+ log.WithError(err).Error("init kayak KV prepare node failed")
return
}
err = s.KVStorage.commit(context.Background(), payload)
if err != nil {
- log.Errorf("init kayak KV commit node failed: %v", err)
+ log.WithError(err).Error("init kayak KV commit node failed")
return
}
}
@@ -287,7 +286,7 @@ type KayakPayload struct {
func (s *KayakKVServer) SetNode(node *proto.Node) (err error) {
nodeBuf, err := utils.EncodeMsgPack(node)
if err != nil {
- log.Errorf("marshal node failed: %v", err)
+ log.WithError(err).Error("marshal node failed")
return
}
payload := &KayakPayload{
@@ -297,13 +296,13 @@ func (s *KayakKVServer) SetNode(node *proto.Node) (err error) {
writeData, err := utils.EncodeMsgPack(payload)
if err != nil {
- log.Errorf("marshal payload failed: %v", err)
+ log.WithError(err).Error("marshal payload failed")
return err
}
_, err = s.Runtime.Apply(writeData.Bytes())
if err != nil {
- log.Errorf("Apply set node failed: %s\nPayload:\n %s", err, writeData)
+ log.Errorf("Apply set node failed: %#v\nPayload:\n %#v", err, writeData)
}
return
@@ -334,7 +333,7 @@ func (s *KayakKVServer) GetDatabase(dbID proto.DatabaseID) (instance wt.ServiceI
},
})
if err != nil {
- log.Errorf("Query database %v instance meta failed: %v", dbID, err)
+ log.WithField("db", dbID).WithError(err).Error("query database instance meta failed")
return
}
@@ -368,13 +367,13 @@ func (s *KayakKVServer) SetDatabase(meta wt.ServiceInstance) (err error) {
writeData, err := utils.EncodeMsgPack(payload)
if err != nil {
- log.Errorf("marshal payload failed: %s", err)
+ log.WithError(err).Error("marshal payload failed")
return err
}
_, err = s.Runtime.Apply(writeData.Bytes())
if err != nil {
- log.Errorf("Apply set database failed: %s\nPayload:\n %s", err, writeData)
+ log.Errorf("Apply set database failed: %#v\nPayload:\n %#v", err, writeData)
}
return
@@ -397,13 +396,13 @@ func (s *KayakKVServer) DeleteDatabase(dbID proto.DatabaseID) (err error) {
writeData, err := utils.EncodeMsgPack(payload)
if err != nil {
- log.Errorf("marshal payload failed: %s", err)
+ log.WithError(err).Error("marshal payload failed")
return err
}
_, err = s.Runtime.Apply(writeData.Bytes())
if err != nil {
- log.Errorf("Apply set database failed: %s\nPayload:\n %s", err, writeData)
+ log.Errorf("Apply set database failed: %#v\nPayload:\n %#v", err, writeData)
}
return
@@ -419,7 +418,7 @@ func (s *KayakKVServer) GetAllDatabases() (instances []wt.ServiceInstance, err e
},
})
if err != nil {
- log.Errorf("Query all database instance meta failed: %v", err)
+ log.WithError(err).Error("query all database instance meta failed")
return
}
@@ -462,10 +461,10 @@ func (s *KayakKVServer) GetAllNodeInfo() (nodes []proto.Node, err error) {
},
})
if err != nil {
- log.Errorf("Query: %s failed: %s", query, err)
+ log.WithField("query", query).WithError(err).Error("query failed")
return
}
- log.Debugf("SQL: %v\nResults: %s", query, result)
+ log.Debugf("SQL: %#v\nResults: %#v", query, result)
nodes = make([]proto.Node, 0, len(result))
@@ -474,7 +473,7 @@ func (s *KayakKVServer) GetAllNodeInfo() (nodes []proto.Node, err error) {
continue
}
nodeBytes, ok := r[0].([]byte)
- log.Debugf("nodeBytes: %s, %v", nodeBytes, ok)
+ log.Debugf("nodeBytes: %#v, %#v", nodeBytes, ok)
if !ok {
continue
}
@@ -482,7 +481,7 @@ func (s *KayakKVServer) GetAllNodeInfo() (nodes []proto.Node, err error) {
nodeDec := proto.NewNode()
err = utils.DecodeMsgPack(nodeBytes, nodeDec)
if err != nil {
- log.Errorf("unmarshal node info failed: %s", err)
+ log.WithError(err).Error("unmarshal node info failed")
continue
}
nodes = append(nodes, *nodeDec)
diff --git a/cmd/cqld/bench_test.go b/cmd/cqld/bench_test.go
index 4c0c14ca6..0ead03fe0 100644
--- a/cmd/cqld/bench_test.go
+++ b/cmd/cqld/bench_test.go
@@ -32,7 +32,6 @@ import (
"github.com/CovenantSQL/CovenantSQL/rpc"
"github.com/CovenantSQL/CovenantSQL/utils"
"github.com/CovenantSQL/CovenantSQL/utils/log"
- . "github.com/smartystreets/goconvey/convey"
)
var (
@@ -43,13 +42,6 @@ var (
var FJ = filepath.Join
-func TestBuild(t *testing.T) {
- Convey("build", t, func() {
- log.SetLevel(log.DebugLevel)
- So(utils.Build(), ShouldBeNil)
- })
-}
-
func start3BPs() {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*15)
defer cancel()
@@ -90,7 +82,19 @@ func TestStartBP_CallRPC(t *testing.T) {
var err error
start3BPs()
- time.Sleep(5 * time.Second)
+
+ ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
+ defer cancel()
+ err = utils.WaitToConnect(ctx, "127.0.0.1", []int{
+ 2122,
+ 2121,
+ 2120,
+ }, time.Second)
+ if err != nil {
+ log.Fatalf("wait for port ready timeout: %v", err)
+ }
+
+ time.Sleep(2 * time.Second)
conf.GConf, err = conf.LoadConfig(FJ(testWorkingDir, "./node_c/config.yaml"))
if err != nil {
@@ -135,8 +139,8 @@ func TestStartBP_CallRPC(t *testing.T) {
reqType = "FindNeighbor"
reqFindNeighbor := &proto.FindNeighborReq{
- NodeID: proto.NodeID(nodePayload.ID),
- Count: 1,
+ ID: proto.NodeID(nodePayload.ID),
+ Count: 1,
}
respFindNeighbor := new(proto.FindNeighborResp)
log.Debugf("req %s: %v", reqType, reqFindNeighbor)
@@ -159,7 +163,7 @@ func TestStartBP_CallRPC(t *testing.T) {
reqType = "FindNode"
reqFN := &proto.FindNodeReq{
- NodeID: nodePayload.ID,
+ ID: nodePayload.ID,
}
respFN := new(proto.FindNodeResp)
err = RPCClient.Call("DHT."+reqType, reqFN, respFN)
@@ -214,18 +218,18 @@ func BenchmarkKayakKVServer_GetAllNodeInfo(b *testing.B) {
err = kms.InitLocalKeyPair(privateKeyPath, masterKey)
if err != nil {
- log.Errorf("init local key pair failed: %s", err)
+ log.WithError(err).Error("init local key pair failed")
return
}
conf.GConf.KnownNodes[idx].PublicKey, err = kms.GetLocalPublicKey()
if err != nil {
- log.Errorf("get local public key failed: %s", err)
+ log.WithError(err).Error("get local public key failed")
return
}
// init nodes
- log.Infof("init peers")
+ log.Info("init peers")
_, _, _, err = initNodePeers(nodeID, pubKeyStorePath)
if err != nil {
return
@@ -254,8 +258,8 @@ func BenchmarkKayakKVServer_GetAllNodeInfo(b *testing.B) {
nodePayload.Addr = "nodePayloadAddr"
reqFindNeighbor := &proto.FindNeighborReq{
- NodeID: proto.NodeID(nodePayload.ID),
- Count: 1,
+ ID: proto.NodeID(nodePayload.ID),
+ Count: 1,
}
respFindNeighbor := new(proto.FindNeighborResp)
log.Debugf("req %s: %v", reqType, reqFindNeighbor)
@@ -288,7 +292,7 @@ func BenchmarkKayakKVServer_GetAllNodeInfo(b *testing.B) {
reqType = "FindNode"
reqFN := &proto.FindNodeReq{
- NodeID: nodePayload.ID,
+ ID: nodePayload.ID,
}
respFN := new(proto.FindNodeResp)
b.Run("benchmark "+reqType, func(b *testing.B) {
diff --git a/cmd/cqld/bootstrap.go b/cmd/cqld/bootstrap.go
index d12681193..e885e5d3a 100644
--- a/cmd/cqld/bootstrap.go
+++ b/cmd/cqld/bootstrap.go
@@ -46,7 +46,6 @@ const (
//privateKeyFile = "private.key"
//dhtFileName = "dht.db"
kayakServiceName = "Kayak"
- dhtServiceName = "DHT"
)
func runNode(nodeID proto.NodeID, listenAddr string) (err error) {
@@ -67,15 +66,15 @@ func runNode(nodeID proto.NodeID, listenAddr string) (err error) {
err = kms.InitLocalKeyPair(conf.GConf.PrivateKeyFile, masterKey)
if err != nil {
- log.Errorf("init local key pair failed: %s", err)
+ log.WithError(err).Error("init local key pair failed")
return
}
// init nodes
- log.Infof("init peers")
+ log.Info("init peers")
_, peers, thisNode, err := initNodePeers(nodeID, conf.GConf.PubKeyStoreFile)
if err != nil {
- log.Errorf("init nodes and peers failed: %s", err)
+ log.WithError(err).Error("init nodes and peers failed")
return
}
@@ -83,38 +82,38 @@ func runNode(nodeID proto.NodeID, listenAddr string) (err error) {
var server *rpc.Server
// create server
- log.Infof("create server")
+ log.Info("create server")
if service, server, err = createServer(
conf.GConf.PrivateKeyFile, conf.GConf.PubKeyStoreFile, masterKey, listenAddr); err != nil {
- log.Errorf("create server failed: %s", err)
+ log.WithError(err).Error("create server failed")
return
}
// init storage
- log.Infof("init storage")
+ log.Info("init storage")
var st *LocalStorage
if st, err = initStorage(conf.GConf.DHTFileName); err != nil {
- log.Errorf("init storage failed: %s", err)
+ log.WithError(err).Error("init storage failed")
return
}
// init kayak
- log.Infof("init kayak runtime")
+ log.Info("init kayak runtime")
var kayakRuntime *kayak.Runtime
if _, kayakRuntime, err = initKayakTwoPC(rootPath, thisNode, peers, st, service); err != nil {
- log.Errorf("init kayak runtime failed: %s", err)
+ log.WithError(err).Error("init kayak runtime failed")
return
}
// init kayak and consistent
- log.Infof("init kayak and consistent runtime")
+ log.Info("init kayak and consistent runtime")
kvServer := &KayakKVServer{
Runtime: kayakRuntime,
KVStorage: st,
}
dht, err := route.NewDHTService(conf.GConf.DHTFileName, kvServer, true)
if err != nil {
- log.Errorf("init consistent hash failed: %s", err)
+ log.WithError(err).Error("init consistent hash failed")
return
}
@@ -122,35 +121,35 @@ func runNode(nodeID proto.NodeID, listenAddr string) (err error) {
kvServer.KVStorage.consistent = dht.Consistent
// register service rpc
- log.Infof("register dht service rpc")
- err = server.RegisterService(dhtServiceName, dht)
+ log.Info("register dht service rpc")
+ err = server.RegisterService(route.DHTRPCName, dht)
if err != nil {
- log.Errorf("register dht service failed: %s", err)
+ log.WithError(err).Error("register dht service failed")
return
}
// init metrics
- log.Infof("register metric service rpc")
+ log.Info("register metric service rpc")
metricService := metric.NewCollectServer()
if err = server.RegisterService(metric.MetricServiceName, metricService); err != nil {
- log.Errorf("init metric service failed: %v", err)
+ log.WithError(err).Error("init metric service failed")
return
}
// init block producer database service
- log.Infof("register block producer database service rpc")
+ log.Info("register block producer database service rpc")
var dbService *bp.DBService
if dbService, err = initDBService(kvServer, metricService); err != nil {
- log.Errorf("init block producer db service failed: %v", err)
+ log.WithError(err).Error("init block producer db service failed")
return
}
- if err = server.RegisterService(bp.DBServiceName, dbService); err != nil {
- log.Errorf("init block producer db service failed: %v", err)
+ if err = server.RegisterService(route.BPDBRPCName, dbService); err != nil {
+ log.WithError(err).Error("init block producer db service failed")
return
}
// init main chain service
- log.Infof("register main chain service rpc")
+ log.Info("register main chain service rpc")
chainConfig := bp.NewConfig(
genesis,
conf.GConf.BP.ChainFileName,
@@ -158,11 +157,11 @@ func runNode(nodeID proto.NodeID, listenAddr string) (err error) {
peers,
nodeID,
2*time.Second,
- 100*time.Millisecond,
+ 900*time.Millisecond,
)
chain, err := bp.NewChain(chainConfig)
if err != nil {
- log.Errorf("init chain failed: %v", err)
+ log.WithError(err).Error("init chain failed")
return
}
chain.Start()
@@ -209,18 +208,18 @@ func createServer(privateKeyPath, pubKeyStorePath string, masterKey []byte, list
func initKayakTwoPC(rootDir string, node *proto.Node, peers *kayak.Peers, worker twopc.Worker, service *kt.ETLSTransportService) (config kayak.Config, runtime *kayak.Runtime, err error) {
// create kayak config
- log.Infof("create twopc config")
+ log.Info("create twopc config")
config = ka.NewTwoPCConfig(rootDir, service, worker)
// create kayak runtime
- log.Infof("create kayak runtime")
+ log.Info("create kayak runtime")
runtime, err = ka.NewTwoPCKayak(peers, config)
if err != nil {
return
}
// init runtime
- log.Infof("init kayak twopc runtime")
+ log.Info("init kayak twopc runtime")
err = runtime.Init()
return
@@ -229,7 +228,7 @@ func initKayakTwoPC(rootDir string, node *proto.Node, peers *kayak.Peers, worker
func initDBService(kvServer *KayakKVServer, metricService *metric.CollectServer) (dbService *bp.DBService, err error) {
var serviceMap *bp.DBServiceMap
if serviceMap, err = bp.InitServiceMap(kvServer); err != nil {
- log.Errorf("init bp database service map failed")
+ log.WithError(err).Error("init bp database service map failed")
return
}
@@ -243,41 +242,9 @@ func initDBService(kvServer *KayakKVServer, metricService *metric.CollectServer)
return
}
-//FIXME(auxten): clean up ugly periodicPingBlockProducer
-func periodicPingBlockProducer() {
- var localNodeID proto.NodeID
- var err error
-
- // get local node id
- if localNodeID, err = kms.GetLocalNodeID(); err != nil {
- return
- }
-
- // get local node info
- var localNodeInfo *proto.Node
- if localNodeInfo, err = kms.GetNodeInfo(localNodeID); err != nil {
- return
- }
-
- log.Debugf("construct local node info: %v", localNodeInfo)
-
- go func() {
- for {
- time.Sleep(time.Second)
-
- // send ping requests to block producer
- bpNodeIDs := route.GetBPs()
-
- for _, bpNodeID := range bpNodeIDs {
- rpc.PingBP(localNodeInfo, bpNodeID)
- }
- }
- }()
-}
-
func loadGenesis() *types.Block {
genesisInfo := conf.GConf.BP.BPGenesis
- log.Infof("genesis config: %v", genesisInfo)
+ log.WithField("config", genesisInfo).Info("load genesis config")
genesis := &types.Block{
SignedHeader: types.SignedHeader{
@@ -297,14 +264,13 @@ func loadGenesis() *types.Block {
"address": ba.Address.String(),
"stableCoinBalance": ba.StableCoinBalance,
"covenantCoinBalance": ba.CovenantCoinBalance,
- }).Debugf("setting one balance fixture in genesis block")
- genesis.Transactions = append(genesis.Transactions, &pt.BaseAccount{
- Account: pt.Account{
+ }).Debug("setting one balance fixture in genesis block")
+ genesis.Transactions = append(genesis.Transactions, pt.NewBaseAccount(
+ &pt.Account{
Address: proto.AccountAddress(ba.Address),
StableCoinBalance: ba.StableCoinBalance,
CovenantCoinBalance: ba.CovenantCoinBalance,
- },
- })
+ }))
}
return genesis
diff --git a/cmd/cqld/client.go b/cmd/cqld/client.go
index 40e45f09e..f70b2a411 100644
--- a/cmd/cqld/client.go
+++ b/cmd/cqld/client.go
@@ -59,13 +59,13 @@ func runClient(nodeID proto.NodeID) (err error) {
err = kms.InitLocalKeyPair(privateKeyPath, masterKey)
if err != nil {
- log.Errorf("init local key pair failed: %s", err)
+ log.WithError(err).Error("init local key pair failed")
return
}
conf.GConf.KnownNodes[idx].PublicKey, err = kms.GetLocalPublicKey()
if err != nil {
- log.Errorf("get local public key failed: %s", err)
+ log.WithError(err).Error("get local public key failed")
return
}
//nodeInfo := asymmetric.GetPubKeyNonce(AllNodes[idx].PublicKey, 20, 500*time.Millisecond, nil)
@@ -73,7 +73,7 @@ func runClient(nodeID proto.NodeID) (err error) {
//log.Debugf("client nonce:\n%v", nodeInfo)
// init nodes
- log.Infof("init peers")
+ log.Info("init peers")
_, _, _, err = initNodePeers(nodeID, pubKeyStorePath)
if err != nil {
return
@@ -109,12 +109,12 @@ func clientRequest(reqType string, sql string) (err error) {
}
respA := new(proto.PingResp)
- log.Debugf("req %s: %v", reqType, reqA)
+ log.Debugf("req %#v: %#v", reqType, reqA)
err = client.Call("DHT."+reqType, reqA, respA)
if err != nil {
log.Fatal(err)
}
- log.Debugf("resp %s: %v", reqType, respA)
+ log.Debugf("resp %#v: %#v", reqType, respA)
} else {
for _, bp := range conf.GConf.KnownNodes {
if bp.Role == proto.Leader || bp.Role == proto.Follower {
@@ -124,19 +124,19 @@ func clientRequest(reqType string, sql string) (err error) {
if client, err = rpc.InitClientConn(conn); err != nil {
return
}
- log.Debugf("Calling BP: %s", bp.ID)
+ log.WithField("bp", bp.ID).Debug("Calling BP")
reqType = "FindNeighbor"
req := &proto.FindNeighborReq{
- NodeID: proto.NodeID(flag.Arg(0)),
- Count: 10,
+ ID: proto.NodeID(flag.Arg(0)),
+ Count: 10,
}
resp := new(proto.FindNeighborResp)
- log.Debugf("req %s: %v", reqType, req)
+ log.Debugf("req %#v: %#v", reqType, req)
err = client.Call("DHT."+reqType, req, resp)
if err != nil {
log.Fatal(err)
}
- log.Debugf("resp %s: %v", reqType, resp)
+ log.Debugf("resp %#v: %#v", reqType, resp)
}
}
}
diff --git a/cmd/cqld/initconf.go b/cmd/cqld/initconf.go
index 0b212b40c..cf2f96a0d 100644
--- a/cmd/cqld/initconf.go
+++ b/cmd/cqld/initconf.go
@@ -29,11 +29,11 @@ import (
func initNodePeers(nodeID proto.NodeID, publicKeystorePath string) (nodes *[]proto.Node, peers *kayak.Peers, thisNode *proto.Node, err error) {
privateKey, err := kms.GetLocalPrivateKey()
if err != nil {
- log.Fatalf("get local private key failed: %s", err)
+ log.WithError(err).Fatal("get local private key failed")
}
publicKey, err := kms.GetLocalPublicKey()
if err != nil {
- log.Fatalf("get local public key failed: %s", err)
+ log.WithError(err).Fatal("get local public key failed")
}
leader := &kayak.Server{
@@ -63,14 +63,14 @@ func initNodePeers(nodeID proto.NodeID, publicKeystorePath string) (nodes *[]pro
}
}
- log.Debugf("AllNodes:\n %v\n", conf.GConf.KnownNodes)
+ log.Debugf("AllNodes:\n %#v\n", conf.GConf.KnownNodes)
err = peers.Sign(privateKey)
if err != nil {
- log.Errorf("sign peers failed: %s", err)
+ log.WithError(err).Error("sign peers failed")
return nil, nil, nil, err
}
- log.Debugf("peers:\n %v\n", peers)
+ log.Debugf("peers:\n %#v\n", peers)
//route.initResolver()
kms.InitPublicKeyStore(publicKeystorePath, nil)
@@ -80,10 +80,13 @@ func initNodePeers(nodeID proto.NodeID, publicKeystorePath string) (nodes *[]pro
for _, p := range conf.GConf.KnownNodes {
rawNodeIDHash, err := hash.NewHashFromStr(string(p.ID))
if err != nil {
- log.Errorf("load hash from node id failed: %s", err)
+ log.WithError(err).Error("load hash from node id failed")
return nil, nil, nil, err
}
- log.Debugf("set node addr: %v, %v", rawNodeIDHash, p.Addr)
+ log.WithFields(log.Fields{
+ "node": rawNodeIDHash.String(),
+ "addr": p.Addr,
+ }).Debug("set node addr")
rawNodeID := &proto.RawNodeID{Hash: *rawNodeIDHash}
route.SetNodeAddrCache(rawNodeID, p.Addr)
node := &proto.Node{
@@ -95,7 +98,7 @@ func initNodePeers(nodeID proto.NodeID, publicKeystorePath string) (nodes *[]pro
}
err = kms.SetNode(node)
if err != nil {
- log.Errorf("set node failed: %v\n %s", node, err)
+ log.WithField("node", node).WithError(err).Error("set node failed")
}
if p.ID == nodeID {
kms.SetLocalNodeIDNonce(rawNodeID.CloneBytes(), &p.Nonce)
diff --git a/cmd/cqld/main.go b/cmd/cqld/main.go
index 430058b2a..04d6d401b 100644
--- a/cmd/cqld/main.go
+++ b/cmd/cqld/main.go
@@ -85,9 +85,9 @@ func init() {
}
func initLogs() {
- log.Infof("%s starting, version %s, commit %s, branch %s", name, version, commit, branch)
- log.Infof("%s, target architecture is %s, operating system target is %s", runtime.Version(), runtime.GOARCH, runtime.GOOS)
- log.Infof("role: %s", conf.RoleTag)
+ log.Infof("%#v starting, version %#v, commit %#v, branch %#v", name, version, commit, branch)
+ log.Infof("%#v, target architecture is %#v, operating system target is %#v", runtime.Version(), runtime.GOARCH, runtime.GOOS)
+ log.Infof("role: %#v", conf.RoleTag)
}
func main() {
@@ -95,14 +95,21 @@ func main() {
rand.Seed(time.Now().UnixNano())
log.SetLevel(log.DebugLevel)
flag.Parse()
+
+ if showVersion {
+ fmt.Printf("%v %v %v %v %v\n",
+ name, version, runtime.GOOS, runtime.GOARCH, runtime.Version())
+ os.Exit(0)
+ }
+
flag.Visit(func(f *flag.Flag) {
- log.Infof("Args %s : %v", f.Name, f.Value)
+ log.Infof("Args %#v : %s", f.Name, f.Value)
})
var err error
conf.GConf, err = conf.LoadConfig(configFile)
if err != nil {
- log.Fatalf("load config from %s failed: %s", configFile, err)
+ log.WithField("config", configFile).WithError(err).Fatal("load config failed")
}
kms.InitBP()
@@ -113,12 +120,6 @@ func main() {
// init log
initLogs()
- if showVersion {
- log.Infof("%s %s %s %s %s (commit %s, branch %s)",
- name, version, runtime.GOOS, runtime.GOARCH, runtime.Version(), commit, branch)
- os.Exit(0)
- }
-
if !noLogo {
fmt.Print(logo)
}
@@ -129,15 +130,15 @@ func main() {
if clientMode {
if err := runClient(conf.GConf.ThisNodeID); err != nil {
- log.Fatalf("run client failed: %v", err.Error())
+ log.WithError(err).Fatal("run client failed")
} else {
- log.Infof("run client success")
+ log.Info("run client success")
}
return
}
if err := runNode(conf.GConf.ThisNodeID, conf.GConf.ListenAddr); err != nil {
- log.Fatalf("run kayak failed: %v", err.Error())
+ log.WithError(err).Fatal("run kayak failed")
}
log.Info("server stopped")
diff --git a/cmd/hotfix/msgpack-20180824/main.go b/cmd/hotfix/hash-upgrade/main.go
similarity index 85%
rename from cmd/hotfix/msgpack-20180824/main.go
rename to cmd/hotfix/hash-upgrade/main.go
index d80453001..0b51cfa96 100644
--- a/cmd/hotfix/msgpack-20180824/main.go
+++ b/cmd/hotfix/hash-upgrade/main.go
@@ -92,24 +92,24 @@ type ServiceInstance struct {
func main() {
flag.Parse()
- log.Infof("start hotfix")
+ log.Info("start hotfix")
// load private key
privateKey, err := kms.LoadPrivateKey(privateKey, []byte(""))
if err != nil {
- log.Fatalf("load private key failed: %v", err)
+ log.WithError(err).Fatal("load private key failed")
return
}
// backup dht file
if err := exec.Command("cp", "-av", dhtFile, dhtFile+".bak").Run(); err != nil {
- log.Fatalf("backup database failed: %v", err)
+ log.WithError(err).Fatal("backup database failed")
return
}
st, err := storage.New(dhtFile)
if err != nil {
- log.Fatalf("open database failed: %v", err)
+ log.WithError(err).Fatal("open database failed")
return
}
defer st.Close()
@@ -118,7 +118,7 @@ func main() {
[]storage.Query{{Pattern: "SELECT `id`, `meta` FROM `databases`"}})
if err != nil {
- log.Fatalf("select databases failed: %v", err)
+ log.WithError(err).Fatal("select database failed")
return
}
@@ -137,7 +137,7 @@ func main() {
var newInstance wt.ServiceInstance
if err := utils.DecodeMsgPackPlain(rawInstance, &testDecode); err != nil {
- log.Fatalf("test decode failed: %v", err)
+ log.WithError(err).Fatal("test decode failed")
} else {
// detect if the genesis block is in old version
if strings.Contains(fmt.Sprintf("%#v", testDecode), "\"GenesisBlock\":[]uint8") {
@@ -145,7 +145,7 @@ func main() {
var instance ServiceInstance
if err := utils.DecodeMsgPackPlain(rawInstance, &instance); err != nil {
- log.Fatalf("decode msgpack failed: %v", err)
+ log.WithError(err).Fatal("decode msgpack failed")
return
}
@@ -160,25 +160,32 @@ func main() {
log.Info("detected new version, need re-signature")
if err := utils.DecodeMsgPack(rawInstance, &newInstance); err != nil {
- log.Fatalf("decode msgpack failed: %v", err)
+ log.WithError(err).Fatal("decode msgpack failed")
return
}
// set genesis block to now
newInstance.GenesisBlock.SignedHeader.Timestamp = time.Now().UTC()
+ // sign peers again
+ if err := newInstance.Peers.Sign(privateKey); err != nil {
+ log.WithError(err).Fatal("sign peers failed")
+ return
+ }
+
if err := newInstance.GenesisBlock.PackAndSignBlock(privateKey); err != nil {
- log.Fatalf("sign genesis block failed: %v", err)
+ log.WithError(err).Fatal("sign genesis block failed")
+ return
}
}
}
- log.Infof("database is: %v -> %v", id, newInstance)
+ log.Infof("database is: %#v -> %#v", id, newInstance)
// encode and put back to database
rawInstanceBuffer, err := utils.EncodeMsgPack(newInstance)
if err != nil {
- log.Fatalf("encode msgpack failed: %v", err)
+ log.WithError(err).Fatal("encode msgpack failed")
return
}
@@ -197,10 +204,10 @@ func main() {
},
},
}); err != nil {
- log.Fatalf("update meta failed: %v", err)
+ log.WithError(err).Fatal("update meta failed")
return
}
}
- log.Infof("hotfix complete")
+ log.Info("hotfix complete")
}
diff --git a/cmd/hotfix/msgpack-20180824/serial.go b/cmd/hotfix/hash-upgrade/serial.go
similarity index 99%
rename from cmd/hotfix/msgpack-20180824/serial.go
rename to cmd/hotfix/hash-upgrade/serial.go
index c5e3561b6..9fe483ecd 100644
--- a/cmd/hotfix/msgpack-20180824/serial.go
+++ b/cmd/hotfix/hash-upgrade/serial.go
@@ -1099,7 +1099,7 @@ func readElement(r io.Reader, order binary.ByteOrder, element interface{}) (err
return i.UnmarshalBinary(buffer)
}
- log.Debugf("element type is: %s", reflect.TypeOf(e))
+ log.Debugf("element type is: %#v", reflect.TypeOf(e).String())
return ErrInvalidType
}
@@ -1317,7 +1317,7 @@ func writeElement(w io.Writer, order binary.ByteOrder, element interface{}) (err
return
}
- log.Debugf("element type is: %s", reflect.TypeOf(e))
+ log.Debugf("element type is: %#v", reflect.TypeOf(e).String())
return ErrInvalidType
}
diff --git a/conf/config.go b/conf/config.go
index 79cba0795..59e4a8e0c 100644
--- a/conf/config.go
+++ b/conf/config.go
@@ -143,13 +143,13 @@ var GConf *Config
func LoadConfig(configPath string) (config *Config, err error) {
configBytes, err := ioutil.ReadFile(configPath)
if err != nil {
- log.Errorf("read config file failed: %s", err)
+ log.WithError(err).Error("read config file failed")
return
}
config = &Config{}
err = yaml.Unmarshal(configBytes, config)
if err != nil {
- log.Errorf("unmarshal config file failed: %s", err)
+ log.WithError(err).Error("unmarshal config file failed")
return
}
@@ -177,5 +177,14 @@ func LoadConfig(configPath string) (config *Config, err error) {
if config.Miner != nil && !path.IsAbs(config.Miner.RootDir) {
config.Miner.RootDir = path.Join(configDir, config.Miner.RootDir)
}
+ /*
+ The `go test -race` makes BP catch up block too slow, so let's make
+ genesis block just one day ago in test mode
+ */
+ if config.IsTestMode {
+ if config.BP != nil {
+ config.BP.BPGenesis.Timestamp = time.Now().AddDate(0, 0, -1)
+ }
+ }
return
}
diff --git a/conf/config_test.go b/conf/config_test.go
index c2b56571b..84d5d0103 100644
--- a/conf/config_test.go
+++ b/conf/config_test.go
@@ -23,9 +23,8 @@ import (
"testing"
"time"
- "github.com/CovenantSQL/CovenantSQL/crypto/hash"
-
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
+ "github.com/CovenantSQL/CovenantSQL/crypto/hash"
"github.com/CovenantSQL/CovenantSQL/pow/cpuminer"
"github.com/CovenantSQL/CovenantSQL/proto"
"github.com/CovenantSQL/CovenantSQL/utils/log"
diff --git a/consistent/consistent.go b/consistent/consistent.go
index 5f8fbe6bb..22166a250 100644
--- a/consistent/consistent.go
+++ b/consistent/consistent.go
@@ -73,6 +73,7 @@ type Consistent struct {
NumberOfReplicas int
count int64
persist Persistence
+ cacheLock sync.RWMutex
sync.RWMutex
}
@@ -97,21 +98,21 @@ func InitConsistent(storePath string, persistImpl Persistence, initBP bool) (c *
err = c.persist.Init(storePath, BPNodes)
if err != nil {
- log.Errorf("init persist BP nodes failed: %v", err)
+ log.WithError(err).Error("init persist BP nodes failed")
return
}
nodes, err := c.persist.GetAllNodeInfo()
if err != nil {
- log.Errorf("get all node id failed: %s", err)
+ log.WithError(err).Error("get all node id failed")
return
}
- log.Debugf("c.persist.GetAllNodeInfo: %v", nodes)
+ log.Debugf("c.persist.GetAllNodeInfo: %#v", nodes)
_, isKMSStorage := c.persist.(*KMSStorage)
if isKMSStorage {
for _, n := range nodes[:] {
- c.add(n)
+ c.Add(n)
}
} else {
// currently just for KayakKVServer
@@ -131,25 +132,64 @@ func (c *Consistent) nodeKey(nodeID proto.NodeID, idx int) string {
// Add inserts a string node in the consistent hash.
func (c *Consistent) Add(node proto.Node) (err error) {
- log.Debugf("add node %v to consistent ring", node)
+ log.WithField("node", node).Debug("add node to consistent ring")
c.Lock()
defer c.Unlock()
return c.add(node)
}
+// Remove removes an node from the hash.
+func (c *Consistent) Remove(nodeID proto.NodeID) (err error) {
+ c.Lock()
+ defer c.Unlock()
+ err = c.persist.DelNode(nodeID)
+ if err != nil {
+ log.WithField("node", nodeID).WithError(err).Error("del node failed")
+ return
+ }
+
+ c.RemoveCache(nodeID)
+ return
+}
+
+// Set sets all the nodes in the hash. If there are existing nodes not
+// present in nodes, they will be removed.
+func (c *Consistent) Set(nodes []proto.Node) (err error) {
+ c.Lock()
+ defer c.Unlock()
+
+ err = c.persist.Reset()
+ if err != nil {
+ log.WithError(err).Error("reset bucket failed")
+ return
+ }
+
+ c.ResetCache()
+
+ for _, v := range nodes {
+ c.add(v)
+ }
+
+ return
+}
+
// need c.Lock() before calling
func (c *Consistent) add(node proto.Node) (err error) {
err = c.persist.SetNode(&node)
if err != nil {
- log.Errorf("set node info failed: %s", err)
+ log.WithField("node", node).WithError(err).Error("set node info failed")
return
}
- return c.AddCache(node)
+ c.AddCache(node)
+ return
}
-// AddCache only adds c.circle skips persist
-func (c *Consistent) AddCache(node proto.Node) (err error) {
+// AddCache only adds c.circle skips persist.
+func (c *Consistent) AddCache(node proto.Node) {
+ c.cacheLock.Lock()
+ defer c.cacheLock.Unlock()
+
for i := 0; i < c.NumberOfReplicas; i++ {
c.circle[hashKey(c.nodeKey(node.ID, i))] = &node
}
@@ -158,56 +198,35 @@ func (c *Consistent) AddCache(node proto.Node) (err error) {
return
}
-// Remove removes an node from the hash.
-func (c *Consistent) Remove(node proto.NodeID) (err error) {
- c.Lock()
- defer c.Unlock()
- return c.remove(node)
-}
-
-// need c.Lock() before calling
-func (c *Consistent) remove(nodeID proto.NodeID) (err error) {
- err = c.persist.DelNode(nodeID)
- if err != nil {
- log.Errorf("del node failed: %s", err)
- return
- }
+// RemoveCache removes an node from the hash cache.
+func (c *Consistent) RemoveCache(nodeID proto.NodeID) {
+ c.cacheLock.Lock()
+ defer c.cacheLock.Unlock()
for i := 0; i < c.NumberOfReplicas; i++ {
delete(c.circle, hashKey(c.nodeKey(nodeID, i)))
}
c.updateSortedHashes()
c.count--
-
- return
}
-// Set sets all the nodes in the hash. If there are existing nodes not
-// present in nodes, they will be removed.
-func (c *Consistent) Set(nodes []proto.Node) (err error) {
- c.Lock()
- defer c.Unlock()
- err = c.persist.Reset()
- if err != nil {
- log.Errorf("reset bucket failed: %s", err)
- return
- }
+// ResetCache removes all node from the hash cache.
+func (c *Consistent) ResetCache() {
+ c.cacheLock.Lock()
+ defer c.cacheLock.Unlock()
c.circle = make(map[proto.NodeKey]*proto.Node)
c.count = 0
c.sortedHashes = NodeKeys{}
-
- for _, v := range nodes {
- c.add(v)
- }
-
- return
}
// GetNeighbor returns an node close to where name hashes to in the circle.
func (c *Consistent) GetNeighbor(name string) (proto.Node, error) {
c.RLock()
defer c.RUnlock()
+ c.cacheLock.RLock()
+ defer c.cacheLock.RUnlock()
+
if len(c.circle) == 0 {
return proto.Node{}, ErrEmptyCircle
}
@@ -220,6 +239,9 @@ func (c *Consistent) GetNeighbor(name string) (proto.Node, error) {
func (c *Consistent) GetNode(name string) (*proto.Node, error) {
c.RLock()
defer c.RUnlock()
+ c.cacheLock.RLock()
+ defer c.cacheLock.RUnlock()
+
n, ok := c.circle[hashKey(c.nodeKey(proto.NodeID(name), 0))]
if ok {
return n, nil
@@ -243,6 +265,9 @@ func (c *Consistent) search(key proto.NodeKey) (i int) {
func (c *Consistent) GetTwoNeighbors(name string) (proto.Node, proto.Node, error) {
c.RLock()
defer c.RUnlock()
+ c.cacheLock.RLock()
+ defer c.cacheLock.RUnlock()
+
if len(c.circle) == 0 {
return proto.Node{}, proto.Node{}, ErrEmptyCircle
}
@@ -272,6 +297,8 @@ func (c *Consistent) GetTwoNeighbors(name string) (proto.Node, proto.Node, error
func (c *Consistent) GetNeighborsEx(name string, n int, roles proto.ServerRoles) ([]proto.Node, error) {
c.RLock()
defer c.RUnlock()
+ c.cacheLock.RLock()
+ defer c.cacheLock.RUnlock()
if len(c.circle) == 0 {
return nil, ErrEmptyCircle
diff --git a/consistent/consistent_test.go b/consistent/consistent_test.go
index af0c9a1c4..8f890a7b4 100644
--- a/consistent/consistent_test.go
+++ b/consistent/consistent_test.go
@@ -31,10 +31,24 @@ import (
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
"github.com/CovenantSQL/CovenantSQL/pow/cpuminer"
. "github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
)
const testStorePath = "./test.store"
+var o sync.Once
+
+func init() {
+ o.Do(func() {
+ kms.Unittest = true
+ os.Remove(testStorePath)
+ x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
+ if x == nil {
+ log.Fatal("InitConsistent failed")
+ }
+ })
+}
+
// CheckNum make int assertion
func CheckNum(num, expected int, t *testing.T) {
if num != expected {
@@ -42,7 +56,7 @@ func CheckNum(num, expected int, t *testing.T) {
}
}
-func NewNodeFromID(id string) Node {
+func NewNodeFromString(id string) Node {
_, publicKey, _ := asymmetric.GenSecp256k1KeyPair()
return Node{
ID: NodeID(id),
@@ -59,7 +73,7 @@ func TestNew(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
if x == nil {
- t.Errorf("expected obj")
+ t.Error("expected obj")
}
}
@@ -70,17 +84,17 @@ func TestAdd(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
CheckNum(len(x.circle), x.NumberOfReplicas, t)
CheckNum(len(x.sortedHashes), x.NumberOfReplicas, t)
if sort.IsSorted(x.sortedHashes) == false {
- t.Errorf("expected sorted hashes to be sorted")
+ t.Error("expected sorted hashes to be sorted")
}
- x.Add(NewNodeFromID(("qwer")))
+ x.Add(NewNodeFromString(("3333333333333333333333333333333333333333333333333333333333333333")))
CheckNum(len(x.circle), 2*x.NumberOfReplicas, t)
CheckNum(len(x.sortedHashes), 2*x.NumberOfReplicas, t)
if sort.IsSorted(x.sortedHashes) == false {
- t.Errorf("expected sorted hashes to be sorted")
+ t.Error("expected sorted hashes to be sorted")
}
}
@@ -91,8 +105,8 @@ func TestRemove(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
- x.Remove("abcdefg")
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
+ x.Remove("0000000000000000000000000000000000000000000000000000000000000000")
CheckNum(len(x.circle), 0, t)
CheckNum(len(x.sortedHashes), 0, t)
}
@@ -104,8 +118,8 @@ func TestRemoveNonExisting(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
- x.Remove("abcdefghijk")
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
+ x.Remove("0000000000000000000000000000000000000000000000000000000000000000hijk")
CheckNum(len(x.circle), x.NumberOfReplicas, t)
}
@@ -118,10 +132,10 @@ func TestGetEmpty(t *testing.T) {
defer os.Remove(testStorePath)
_, err := x.GetNeighbor("asdfsadfsadf")
if err == nil {
- t.Errorf("expected error")
+ t.Error("expected error")
}
if err != ErrEmptyCircle {
- t.Errorf("expected empty circle error")
+ t.Error("expected empty circle error")
}
}
@@ -132,7 +146,7 @@ func TestGetSingle(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
f := func(s string) bool {
y, err := x.GetNeighbor(s)
if err != nil {
@@ -140,7 +154,7 @@ func TestGetSingle(t *testing.T) {
return false
}
//t.Logf("s = %v, y = %v", s, y)
- return y.ID == "abcdefg"
+ return y.ID == "0000000000000000000000000000000000000000000000000000000000000000"
}
if err := quick.Check(f, nil); err != nil {
t.Fatal(err)
@@ -150,10 +164,10 @@ func TestConsistent_GetNode(t *testing.T) {
kms.Unittest = true
os.Remove(testStorePath)
kms.ResetBucket()
- nodeID := "40f26f9c816577adcb271734fec72c76"
+ nodeID := "40f26f9c816577adcb271734fec72c7640f26f9c816577adcb271734fec72c76"
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID(nodeID))
+ x.Add(NewNodeFromString(nodeID))
f := func(s string) bool {
_, err := x.GetNode(s)
return err == ErrKeyNotFound
@@ -176,9 +190,9 @@ type gtest struct {
}
var gmtests = []gtest{
- {"iiii", "abcdefg"},
- {"hhh", "opqrstu"},
- {"ggg", "abcdefg"},
+ {"0000", "2222222222222222222222222222222222222222222222222222222222222222"},
+ {"2222", "1111111111111111111111111111111111111111111111111111111111111111"},
+ {"1111", "1111111111111111111111111111111111111111111111111111111111111111"},
}
func TestGetMultiple(t *testing.T) {
@@ -188,9 +202,9 @@ func TestGetMultiple(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
- x.Add(NewNodeFromID("hijklmn"))
- x.Add(NewNodeFromID("opqrstu"))
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
+ x.Add(NewNodeFromString("1111111111111111111111111111111111111111111111111111111111111111"))
+ x.Add(NewNodeFromString("2222222222222222222222222222222222222222222222222222222222222222"))
for i, v := range gmtests {
result, err := x.GetNeighbor(v.in)
if err != nil {
@@ -209,9 +223,9 @@ func TestGetMultipleQuick(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
- x.Add(NewNodeFromID("hijklmn"))
- x.Add(NewNodeFromID("opqrstu"))
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
+ x.Add(NewNodeFromString("1111111111111111111111111111111111111111111111111111111111111111"))
+ x.Add(NewNodeFromString("2222222222222222222222222222222222222222222222222222222222222222"))
f := func(s string) bool {
y, err := x.GetNeighbor(s)
if err != nil {
@@ -219,7 +233,7 @@ func TestGetMultipleQuick(t *testing.T) {
return false
}
//t.Logf("s = %v, y = %v", s, y)
- return y.ID == "abcdefg" || y.ID == "hijklmn" || y.ID == "opqrstu"
+ return y.ID == "0000000000000000000000000000000000000000000000000000000000000000" || y.ID == "1111111111111111111111111111111111111111111111111111111111111111" || y.ID == "2222222222222222222222222222222222222222222222222222222222222222"
}
if err := quick.Check(f, nil); err != nil {
t.Fatal(err)
@@ -227,15 +241,15 @@ func TestGetMultipleQuick(t *testing.T) {
}
var rtestsBefore = []gtest{
- {"iiii", "abcdefg"},
- {"hhh", "opqrstu"},
- {"ggg", "abcdefg"},
+ {"0000", "2222222222222222222222222222222222222222222222222222222222222222"},
+ {"2222", "1111111111111111111111111111111111111111111111111111111111111111"},
+ {"1111", "1111111111111111111111111111111111111111111111111111111111111111"},
}
var rtestsAfter = []gtest{
- {"iiii", "abcdefg"},
- {"hhh", "opqrstu"},
- {"ggg", "abcdefg"},
+ {"0000", "2222222222222222222222222222222222222222222222222222222222222222"},
+ {"2222", "0000000000000000000000000000000000000000000000000000000000000000"},
+ {"1111", "2222222222222222222222222222222222222222222222222222222222222222"},
}
func TestGetMultipleRemove(t *testing.T) {
@@ -245,9 +259,9 @@ func TestGetMultipleRemove(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
- x.Add(NewNodeFromID("hijklmn"))
- x.Add(NewNodeFromID("opqrstu"))
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
+ x.Add(NewNodeFromString("1111111111111111111111111111111111111111111111111111111111111111"))
+ x.Add(NewNodeFromString("2222222222222222222222222222222222222222222222222222222222222222"))
for i, v := range rtestsBefore {
result, err := x.GetNeighbor(v.in)
if err != nil {
@@ -257,7 +271,7 @@ func TestGetMultipleRemove(t *testing.T) {
t.Errorf("%d. got %v, expected %v before rm", i, result, v.out)
}
}
- x.Remove("hijklmn")
+ x.Remove("1111111111111111111111111111111111111111111111111111111111111111")
for i, v := range rtestsAfter {
result, err := x.GetNeighbor(v.in)
if err != nil {
@@ -276,10 +290,10 @@ func TestGetMultipleRemoveQuick(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
- x.Add(NewNodeFromID("hijklmn"))
- x.Add(NewNodeFromID("opqrstu"))
- x.Remove(NodeID("opqrstu"))
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
+ x.Add(NewNodeFromString("1111111111111111111111111111111111111111111111111111111111111111"))
+ x.Add(NewNodeFromString("2222222222222222222222222222222222222222222222222222222222222222"))
+ x.Remove(NodeID("2222222222222222222222222222222222222222222222222222222222222222"))
f := func(s string) bool {
y, err := x.GetNeighbor(s)
if err != nil {
@@ -287,7 +301,7 @@ func TestGetMultipleRemoveQuick(t *testing.T) {
return false
}
//t.Logf("s = %v, y = %v", s, y)
- return y.ID == "abcdefg" || y.ID == "hijklmn"
+ return y.ID == "0000000000000000000000000000000000000000000000000000000000000000" || y.ID == "1111111111111111111111111111111111111111111111111111111111111111"
}
if err := quick.Check(f, nil); err != nil {
t.Fatal(err)
@@ -301,20 +315,20 @@ func TestGetTwo(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
- x.Add(NewNodeFromID("hijklmn"))
- x.Add(NewNodeFromID("opqrstu"))
- a, b, err := x.GetTwoNeighbors("99999999")
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
+ x.Add(NewNodeFromString("1111111111111111111111111111111111111111111111111111111111111111"))
+ x.Add(NewNodeFromString("2222222222222222222222222222222222222222222222222222222222222222"))
+ a, b, err := x.GetTwoNeighbors("9999999999999999999999999999999999999999999999999999999999999999")
if err != nil {
t.Fatal(err)
}
if a.ID == b.ID {
- t.Errorf("a shouldn't equal b")
+ t.Error("a shouldn't equal b")
}
- if a.ID != "abcdefg" {
+ if a.ID != "0000000000000000000000000000000000000000000000000000000000000000" {
t.Errorf("wrong a: %v", a)
}
- if b.ID != "opqrstu" {
+ if b.ID != "1111111111111111111111111111111111111111111111111111111111111111" {
t.Errorf("wrong b: %v", b)
}
}
@@ -326,7 +340,7 @@ func TestGetTwoEmpty(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- _, _, err := x.GetTwoNeighbors("9999999")
+ _, _, err := x.GetTwoNeighbors("9999999999999999999999999999999999999999999999999999999999999999")
if err != ErrEmptyCircle {
t.Fatal(err)
}
@@ -339,9 +353,9 @@ func TestGetTwoQuick(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
- x.Add(NewNodeFromID("hijklmn"))
- x.Add(NewNodeFromID("opqrstu"))
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
+ x.Add(NewNodeFromString("1111111111111111111111111111111111111111111111111111111111111111"))
+ x.Add(NewNodeFromString("2222222222222222222222222222222222222222222222222222222222222222"))
f := func(s string) bool {
a, b, err := x.GetTwoNeighbors(s)
if err != nil {
@@ -349,15 +363,15 @@ func TestGetTwoQuick(t *testing.T) {
return false
}
if a.ID == b.ID {
- t.Logf("a.ID == b.ID")
+ t.Log("a.ID == b.ID")
return false
}
- if a.ID != "abcdefg" && a.ID != "hijklmn" && a.ID != "opqrstu" {
+ if a.ID != "0000000000000000000000000000000000000000000000000000000000000000" && a.ID != "1111111111111111111111111111111111111111111111111111111111111111" && a.ID != "2222222222222222222222222222222222222222222222222222222222222222" {
t.Logf("invalid a: %v", a)
return false
}
- if b.ID != "abcdefg" && b.ID != "hijklmn" && b.ID != "opqrstu" {
+ if b.ID != "0000000000000000000000000000000000000000000000000000000000000000" && b.ID != "1111111111111111111111111111111111111111111111111111111111111111" && b.ID != "2222222222222222222222222222222222222222222222222222222222222222" {
t.Logf("invalid b: %v", b)
return false
}
@@ -375,8 +389,8 @@ func TestGetTwoOnlyTwoQuick(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
- x.Add(NewNodeFromID("hijklmn"))
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
+ x.Add(NewNodeFromString("1111111111111111111111111111111111111111111111111111111111111111"))
f := func(s string) bool {
a, b, err := x.GetTwoNeighbors(s)
if err != nil {
@@ -384,15 +398,15 @@ func TestGetTwoOnlyTwoQuick(t *testing.T) {
return false
}
if a.ID == b.ID {
- t.Logf("a.ID == b.ID")
+ t.Log("a.ID == b.ID")
return false
}
- if a.ID != "abcdefg" && a.ID != "hijklmn" {
+ if a.ID != "0000000000000000000000000000000000000000000000000000000000000000" && a.ID != "1111111111111111111111111111111111111111111111111111111111111111" {
t.Logf("invalid a: %v", a)
return false
}
- if b.ID != "abcdefg" && b.ID != "hijklmn" {
+ if b.ID != "0000000000000000000000000000000000000000000000000000000000000000" && b.ID != "1111111111111111111111111111111111111111111111111111111111111111" {
t.Logf("invalid b: %v", b)
return false
}
@@ -410,15 +424,15 @@ func TestGetTwoOnlyOneInCircle(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
- a, b, err := x.GetTwoNeighbors("99999999")
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
+ a, b, err := x.GetTwoNeighbors("9999999999999999999999999999999999999999999999999999999999999999")
if err != nil {
t.Fatal(err)
}
if a.ID == b.ID {
- t.Errorf("a shouldn't equal b")
+ t.Error("a shouldn't equal b")
}
- if a.ID != "abcdefg" {
+ if a.ID != "0000000000000000000000000000000000000000000000000000000000000000" {
t.Errorf("wrong a: %v", a)
}
if b.ID != "" {
@@ -433,24 +447,24 @@ func TestGetN(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
- x.Add(NewNodeFromID("hijklmn"))
- x.Add(NewNodeFromID("opqrstu"))
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
+ x.Add(NewNodeFromString("1111111111111111111111111111111111111111111111111111111111111111"))
+ x.Add(NewNodeFromString("2222222222222222222222222222222222222222222222222222222222222222"))
members, err := x.GetNeighbors("9999999", 3)
- //members, err := x.GetNeighbors("abcdefg", 3)
+ //members, err := x.GetNeighbors("0000000000000000000000000000000000000000000000000000000000000000", 3)
if err != nil {
t.Fatal(err)
}
if len(members) != 3 {
t.Errorf("expected 3 members instead of %d", len(members))
}
- if members[0].ID != "opqrstu" {
+ if members[0].ID != "0000000000000000000000000000000000000000000000000000000000000000" {
t.Errorf("wrong members[0]: %v", members[0])
}
- if members[1].ID != "hijklmn" {
+ if members[1].ID != "2222222222222222222222222222222222222222222222222222222222222222" {
t.Errorf("wrong members[1]: %v", members[1])
}
- if members[2].ID != "abcdefg" {
+ if members[2].ID != "1111111111111111111111111111111111111111111111111111111111111111" {
t.Errorf("wrong members[2]: %v", members[2])
}
}
@@ -462,11 +476,11 @@ func TestGetNFilterRole(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- n := NewNodeFromID("abcdefg")
+ n := NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000")
n.Role = Leader
x.Add(n)
- x.Add(NewNodeFromID("hijklmn"))
- x.Add(NewNodeFromID("opqrstu"))
+ x.Add(NewNodeFromString("1111111111111111111111111111111111111111111111111111111111111111"))
+ x.Add(NewNodeFromString("2222222222222222222222222222222222222222222222222222222222222222"))
members, err := x.GetNeighborsEx("9999999", 3, ServerRoles{Unknown})
if err != nil {
t.Fatal(err)
@@ -474,10 +488,10 @@ func TestGetNFilterRole(t *testing.T) {
if len(members) != 2 {
t.Errorf("expected 2 members instead of %d", len(members))
}
- if members[0].ID != "opqrstu" {
+ if members[0].ID != "2222222222222222222222222222222222222222222222222222222222222222" {
t.Errorf("wrong members[0]: %v", members[0])
}
- if members[1].ID != "hijklmn" {
+ if members[1].ID != "1111111111111111111111111111111111111111111111111111111111111111" {
t.Errorf("wrong members[1]: %v", members[1])
}
@@ -488,7 +502,7 @@ func TestGetNFilterRole(t *testing.T) {
if len(members) != 1 {
t.Errorf("expected 1 members instead of %d", len(members))
}
- if members[0].ID != "abcdefg" {
+ if members[0].ID != "0000000000000000000000000000000000000000000000000000000000000000" {
t.Errorf("wrong members[0]: %v", members[0])
}
}
@@ -500,20 +514,20 @@ func TestGetNLess(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
- x.Add(NewNodeFromID("hijklmn"))
- x.Add(NewNodeFromID("opqrstu"))
- members, err := x.GetNeighbors("99999999", 2)
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
+ x.Add(NewNodeFromString("1111111111111111111111111111111111111111111111111111111111111111"))
+ x.Add(NewNodeFromString("2222222222222222222222222222222222222222222222222222222222222222"))
+ members, err := x.GetNeighbors("9999999999999999999999999999999999999999999999999999999999999999", 2)
if err != nil {
t.Fatal(err)
}
if len(members) != 2 {
t.Errorf("expected 2 members instead of %d", len(members))
}
- if members[0].ID != "abcdefg" {
+ if members[0].ID != "0000000000000000000000000000000000000000000000000000000000000000" {
t.Errorf("wrong members[0]: %v", members[0])
}
- if members[1].ID != "opqrstu" {
+ if members[1].ID != "1111111111111111111111111111111111111111111111111111111111111111" {
t.Errorf("wrong members[1]: %v", members[1])
}
}
@@ -525,9 +539,9 @@ func TestGetNMore(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
- x.Add(NewNodeFromID("hijklmn"))
- x.Add(NewNodeFromID("opqrstu"))
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
+ x.Add(NewNodeFromString("1111111111111111111111111111111111111111111111111111111111111111"))
+ x.Add(NewNodeFromString("2222222222222222222222222222222222222222222222222222222222222222"))
members, err := x.GetNeighbors("9999999", 5)
if err != nil {
t.Fatal(err)
@@ -535,13 +549,13 @@ func TestGetNMore(t *testing.T) {
if len(members) != 3 {
t.Errorf("expected 3 members instead of %d", len(members))
}
- if members[0].ID != "opqrstu" {
+ if members[0].ID != "0000000000000000000000000000000000000000000000000000000000000000" {
t.Errorf("wrong members[0]: %v", members[0])
}
- if members[1].ID != "hijklmn" {
+ if members[1].ID != "2222222222222222222222222222222222222222222222222222222222222222" {
t.Errorf("wrong members[1]: %v", members[1])
}
- if members[2].ID != "abcdefg" {
+ if members[2].ID != "1111111111111111111111111111111111111111111111111111111111111111" {
t.Errorf("wrong members[2]: %v", members[2])
}
}
@@ -569,9 +583,9 @@ func TestGetNQuick(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
- x.Add(NewNodeFromID("hijklmn"))
- x.Add(NewNodeFromID("opqrstu"))
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
+ x.Add(NewNodeFromString("1111111111111111111111111111111111111111111111111111111111111111"))
+ x.Add(NewNodeFromString("2222222222222222222222222222222222222222222222222222222222222222"))
f := func(s string) bool {
members, err := x.GetNeighbors(s, 3)
if err != nil {
@@ -585,11 +599,11 @@ func TestGetNQuick(t *testing.T) {
set := make(map[NodeID]Node, 4)
for _, member := range members {
if set[member.ID].ID != "" {
- t.Logf("duplicate error")
+ t.Log("duplicate error")
return false
}
set[member.ID] = Node{}
- if member.ID != "abcdefg" && member.ID != "hijklmn" && member.ID != "opqrstu" {
+ if member.ID != "0000000000000000000000000000000000000000000000000000000000000000" && member.ID != "1111111111111111111111111111111111111111111111111111111111111111" && member.ID != "2222222222222222222222222222222222222222222222222222222222222222" {
t.Logf("invalid member: %v", member)
return false
}
@@ -608,9 +622,9 @@ func TestGetNLessQuick(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
- x.Add(NewNodeFromID("hijklmn"))
- x.Add(NewNodeFromID("opqrstu"))
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
+ x.Add(NewNodeFromString("1111111111111111111111111111111111111111111111111111111111111111"))
+ x.Add(NewNodeFromString("2222222222222222222222222222222222222222222222222222222222222222"))
f := func(s string) bool {
members, err := x.GetNeighbors(s, 2)
if err != nil {
@@ -624,11 +638,11 @@ func TestGetNLessQuick(t *testing.T) {
set := make(map[NodeID]Node, 4)
for _, member := range members {
if set[member.ID].ID != "" {
- t.Logf("duplicate error")
+ t.Log("duplicate error")
return false
}
set[member.ID] = Node{}
- if member.ID != "abcdefg" && member.ID != "hijklmn" && member.ID != "opqrstu" {
+ if member.ID != "0000000000000000000000000000000000000000000000000000000000000000" && member.ID != "1111111111111111111111111111111111111111111111111111111111111111" && member.ID != "2222222222222222222222222222222222222222222222222222222222222222" {
t.Logf("invalid member: %v", member)
return false
}
@@ -647,9 +661,9 @@ func TestGetNMoreQuick(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abcdefg"))
- x.Add(NewNodeFromID("hijklmn"))
- x.Add(NewNodeFromID("opqrstu"))
+ x.Add(NewNodeFromString("0000000000000000000000000000000000000000000000000000000000000000"))
+ x.Add(NewNodeFromString("1111111111111111111111111111111111111111111111111111111111111111"))
+ x.Add(NewNodeFromString("2222222222222222222222222222222222222222222222222222222222222222"))
f := func(s string) bool {
members, err := x.GetNeighbors(s, 5)
if err != nil {
@@ -663,11 +677,11 @@ func TestGetNMoreQuick(t *testing.T) {
set := make(map[NodeID]Node, 4)
for _, member := range members {
if set[member.ID].ID != "" {
- t.Logf("duplicate error")
+ t.Log("duplicate error")
return false
}
set[member.ID] = Node{}
- if member.ID != "abcdefg" && member.ID != "hijklmn" && member.ID != "opqrstu" {
+ if member.ID != "0000000000000000000000000000000000000000000000000000000000000000" && member.ID != "1111111111111111111111111111111111111111111111111111111111111111" && member.ID != "2222222222222222222222222222222222222222222222222222222222222222" {
t.Logf("invalid member: %v", member)
return false
}
@@ -686,57 +700,57 @@ func TestSet(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("abc"))
- x.Add(NewNodeFromID("def"))
- x.Add(NewNodeFromID("ghi"))
+ x.Add(NewNodeFromString("0000"))
+ x.Add(NewNodeFromString("1111"))
+ x.Add(NewNodeFromString("2222"))
- x.Set([]Node{NewNodeFromID("jkl"), NewNodeFromID("mno")})
+ x.Set([]Node{NewNodeFromString("3333"), NewNodeFromString("4444")})
if x.count != 2 {
t.Errorf("expected 2 elts, got %d", x.count)
}
- a, b, err := x.GetTwoNeighbors("qwerqwerwqer")
+ a, b, err := x.GetTwoNeighbors("33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333wqer")
if err != nil {
t.Fatal(err)
}
- if a.ID != "jkl" && a.ID != "mno" {
- t.Errorf("expected jkl or mno, got %v", a)
+ if a.ID != "3333" && a.ID != "4444" {
+ t.Errorf("expected 3333 or 4444, got %v", a)
}
- if b.ID != "jkl" && b.ID != "mno" {
- t.Errorf("expected jkl or mno, got %v", b)
+ if b.ID != "3333" && b.ID != "4444" {
+ t.Errorf("expected 3333 or 4444, got %v", b)
}
if a.ID == b.ID {
t.Errorf("expected a != b, they were both %v", a)
}
- x.Set([]Node{NewNodeFromID("pqr"), NewNodeFromID("mno")})
+ x.Set([]Node{NewNodeFromString("5555"), NewNodeFromString("4444")})
if x.count != 2 {
t.Errorf("expected 2 elts, got %d", x.count)
}
- a, b, err = x.GetTwoNeighbors("qwerqwerwqer")
+ a, b, err = x.GetTwoNeighbors("33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333wqer")
if err != nil {
t.Fatal(err)
}
- if a.ID != "pqr" && a.ID != "mno" {
- t.Errorf("expected jkl or mno, got %v", a)
+ if a.ID != "5555" && a.ID != "4444" {
+ t.Errorf("expected 3333 or 4444, got %v", a)
}
- if b.ID != "pqr" && b.ID != "mno" {
- t.Errorf("expected jkl or mno, got %v", b)
+ if b.ID != "5555" && b.ID != "4444" {
+ t.Errorf("expected 3333 or 4444, got %v", b)
}
if a.ID == b.ID {
t.Errorf("expected a != b, they were both %v", a)
}
- x.Set([]Node{NewNodeFromID("pqr"), NewNodeFromID("mno")})
+ x.Set([]Node{NewNodeFromString("5555"), NewNodeFromString("4444")})
if x.count != 2 {
t.Errorf("expected 2 elts, got %d", x.count)
}
- a, b, err = x.GetTwoNeighbors("qwerqwerwqer")
+ a, b, err = x.GetTwoNeighbors("33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333wqer")
if err != nil {
t.Fatal(err)
}
- if a.ID != "pqr" && a.ID != "mno" {
- t.Errorf("expected jkl or mno, got %v", a)
+ if a.ID != "5555" && a.ID != "4444" {
+ t.Errorf("expected 3333 or 4444, got %v", a)
}
- if b.ID != "pqr" && b.ID != "mno" {
- t.Errorf("expected jkl or mno, got %v", b)
+ if b.ID != "5555" && b.ID != "4444" {
+ t.Errorf("expected 3333 or 4444, got %v", b)
}
if a.ID == b.ID {
t.Errorf("expected a != b, they were both %v", a)
@@ -769,11 +783,11 @@ func BenchmarkAllocations(b *testing.B) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("stays"))
+ x.Add(NewNodeFromString("stays"))
b.ResetTimer()
allocSize := allocBytes(func() {
for i := 0; i < b.N; i++ {
- x.Add(NewNodeFromID("Foo"))
+ x.Add(NewNodeFromString("Foo"))
x.Remove(NodeID("Foo"))
}
})
@@ -787,11 +801,11 @@ func BenchmarkMalloc(b *testing.B) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("stays"))
+ x.Add(NewNodeFromString("stays"))
b.ResetTimer()
mallocs := mallocNum(func() {
for i := 0; i < b.N; i++ {
- x.Add(NewNodeFromID("Foo"))
+ x.Add(NewNodeFromString("Foo"))
x.Remove(NodeID("Foo"))
}
})
@@ -805,10 +819,10 @@ func BenchmarkCycle(b *testing.B) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("nothing"))
+ x.Add(NewNodeFromString("nothing"))
b.ResetTimer()
for i := 0; i < b.N; i++ {
- x.Add(NewNodeFromID("foo" + strconv.Itoa(i)))
+ x.Add(NewNodeFromString("foo" + strconv.Itoa(i)))
x.Remove(NodeID("foo" + strconv.Itoa(i)))
}
}
@@ -821,11 +835,11 @@ func BenchmarkCycleLarge(b *testing.B) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
for i := 0; i < 10; i++ {
- x.Add(NewNodeFromID("start" + strconv.Itoa(i)))
+ x.Add(NewNodeFromString("start" + strconv.Itoa(i)))
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
- x.Add(NewNodeFromID("foo" + strconv.Itoa(i)))
+ x.Add(NewNodeFromString("foo" + strconv.Itoa(i)))
x.Remove(NodeID("foo" + strconv.Itoa(i)))
}
}
@@ -837,7 +851,7 @@ func BenchmarkGet(b *testing.B) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("nothing"))
+ x.Add(NewNodeFromString("nothing"))
b.ResetTimer()
for i := 0; i < b.N; i++ {
x.GetNeighbor("nothing")
@@ -852,7 +866,7 @@ func BenchmarkGetLarge(b *testing.B) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
for i := 0; i < 10; i++ {
- x.Add(NewNodeFromID("start" + strconv.Itoa(i)))
+ x.Add(NewNodeFromString("start" + strconv.Itoa(i)))
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
@@ -867,7 +881,7 @@ func BenchmarkGetN(b *testing.B) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("nothing"))
+ x.Add(NewNodeFromString("nothing"))
b.ResetTimer()
for i := 0; i < b.N; i++ {
x.GetNeighbors("nothing", 3)
@@ -882,7 +896,7 @@ func BenchmarkGetNLarge(b *testing.B) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
for i := 0; i < 10; i++ {
- x.Add(NewNodeFromID("start" + strconv.Itoa(i)))
+ x.Add(NewNodeFromString("start" + strconv.Itoa(i)))
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
@@ -897,7 +911,7 @@ func BenchmarkGetTwo(b *testing.B) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID("nothing"))
+ x.Add(NewNodeFromString("nothing"))
b.ResetTimer()
for i := 0; i < b.N; i++ {
x.GetTwoNeighbors("nothing")
@@ -912,7 +926,7 @@ func BenchmarkGetTwoLarge(b *testing.B) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
for i := 0; i < 10; i++ {
- x.Add(NewNodeFromID("start" + strconv.Itoa(i)))
+ x.Add(NewNodeFromString("start" + strconv.Itoa(i)))
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
@@ -924,17 +938,17 @@ func BenchmarkGetTwoLarge(b *testing.B) {
func TestAddCollision(t *testing.T) {
// These two strings produce several crc32 collisions after "|i" is
// appended added by Consistent.eltKey.
- const s1 = "abear"
- const s2 = "solidiform"
+ const s1 = "111111"
+ const s2 = "222222"
kms.Unittest = true
os.Remove(testStorePath)
kms.ResetBucket()
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Add(NewNodeFromID(s1))
- x.Add(NewNodeFromID(s2))
- elt1, err := x.GetNeighbor("abear")
+ x.Add(NewNodeFromString(s1))
+ x.Add(NewNodeFromString(s2))
+ elt1, err := x.GetNeighbor("111111")
if err != nil {
t.Fatal("unexpected error:", err)
}
@@ -942,8 +956,8 @@ func TestAddCollision(t *testing.T) {
y, _ := InitConsistent(testStorePath+"2", new(KMSStorage), false)
defer os.Remove(testStorePath + "2")
// add elements in opposite order
- y.Add(NewNodeFromID(s2))
- y.Add(NewNodeFromID(s1))
+ y.Add(NewNodeFromString(s2))
+ y.Add(NewNodeFromString(s1))
elt2, err := y.GetNeighbor(s1)
if err != nil {
t.Fatal("unexpected error:", err)
@@ -961,16 +975,16 @@ func TestConcurrentGetSet(t *testing.T) {
x, _ := InitConsistent(testStorePath, new(KMSStorage), false)
defer os.Remove(testStorePath)
- x.Set([]Node{NewNodeFromID("abc"), NewNodeFromID("def"), NewNodeFromID("ghi"), NewNodeFromID("jkl"), NewNodeFromID("mno")})
+ x.Set([]Node{NewNodeFromString("0000"), NewNodeFromString("1111"), NewNodeFromString("2222"), NewNodeFromString("3333"), NewNodeFromString("4444")})
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
for i := 0; i < 100; i++ {
- x.Set([]Node{NewNodeFromID("abc"), NewNodeFromID("def"), NewNodeFromID("ghi"), NewNodeFromID("jkl"), NewNodeFromID("mno")})
+ x.Set([]Node{NewNodeFromString("0000"), NewNodeFromString("1111"), NewNodeFromString("2222"), NewNodeFromString("3333"), NewNodeFromString("4444")})
time.Sleep(time.Duration(rand.Intn(10)) * time.Millisecond)
- x.Set([]Node{NewNodeFromID("pqr"), NewNodeFromID("stu"), NewNodeFromID("vwx")})
+ x.Set([]Node{NewNodeFromString("5555"), NewNodeFromString("6666"), NewNodeFromString("7777")})
time.Sleep(time.Duration(rand.Intn(10)) * time.Millisecond)
}
wg.Done()
@@ -981,12 +995,12 @@ func TestConcurrentGetSet(t *testing.T) {
wg.Add(1)
go func() {
for i := 0; i < 100; i++ {
- a, err := x.GetNeighbor("xxxxxxx")
+ a, err := x.GetNeighbor("111111")
if err != nil {
t.Error(err)
}
- if a.ID != "jkl" && a.ID != "vwx" {
- t.Errorf("got %v, expected vwx", a)
+ if a.ID != "5555" && a.ID != "3333" {
+ t.Errorf("got %v, expected 5555 or 3333", a)
}
time.Sleep(time.Duration(rand.Intn(10)) * time.Millisecond)
}
diff --git a/consistent/load_test.go b/consistent/load_test.go
index aeda95752..a85073b84 100644
--- a/consistent/load_test.go
+++ b/consistent/load_test.go
@@ -37,8 +37,8 @@ func TestSaveDHT(t *testing.T) {
Convey("save DHT", t, func() {
x, _ := InitConsistent(testStorePath1, new(KMSStorage), false)
- x.Add(NewNodeFromID("abcdefg"))
- x.Add(NewNodeFromID(("qwer")))
+ x.Add(NewNodeFromString("111111"))
+ x.Add(NewNodeFromString(("3333")))
So(len(x.circle), ShouldEqual, x.NumberOfReplicas*2)
So(len(x.sortedHashes), ShouldEqual, x.NumberOfReplicas*2)
So(sort.IsSorted(x.sortedHashes), ShouldBeTrue)
diff --git a/consistent/persistence.go b/consistent/persistence.go
index 90529e98e..8a9bb3a9c 100644
--- a/consistent/persistence.go
+++ b/consistent/persistence.go
@@ -58,7 +58,7 @@ func (s *KMSStorage) Reset() (err error) {
func (s *KMSStorage) GetAllNodeInfo() (nodes []proto.Node, err error) {
IDs, err := kms.GetAllNodeID()
if err != nil {
- log.Errorf("get all node id failed: %s", err)
+ log.WithError(err).Error("get all node id failed")
return
}
nodes = make([]proto.Node, 0, len(IDs))
@@ -67,7 +67,7 @@ func (s *KMSStorage) GetAllNodeInfo() (nodes []proto.Node, err error) {
node, err := kms.GetNodeInfo(id)
if err != nil {
// this may happen, just continue
- log.Errorf("get node info for %s failed: %s", id, err)
+ log.WithField("node", node).WithError(err).Error("get node info failed")
continue
}
nodes = append(nodes, *node)
diff --git a/crypto/asymmetric/keypair.go b/crypto/asymmetric/keypair.go
index d563b4a18..2f78a5d93 100644
--- a/crypto/asymmetric/keypair.go
+++ b/crypto/asymmetric/keypair.go
@@ -21,6 +21,7 @@ import (
"encoding/hex"
"fmt"
"math/big"
+ "sync"
"time"
mine "github.com/CovenantSQL/CovenantSQL/pow/cpuminer"
@@ -32,6 +33,8 @@ import (
// PrivateKeyBytesLen defines the length in bytes of a serialized private key.
const PrivateKeyBytesLen = 32
+var parsedPublicKeyCache sync.Map
+
// PrivateKey wraps an ec.PrivateKey as a convenience mainly for signing things with the the
// private key without having to directly import the ecdsa package.
type PrivateKey ec.PrivateKey
@@ -58,9 +61,15 @@ func (k *PublicKey) MarshalBinary() (keyBytes []byte, err error) {
// UnmarshalBinary does the deserialization
func (k *PublicKey) UnmarshalBinary(keyBytes []byte) (err error) {
- pubNew, err := ParsePubKey(keyBytes)
- if err == nil {
- *k = *pubNew
+ pubKeyI, ok := parsedPublicKeyCache.Load(string(keyBytes))
+ if ok {
+ *k = *pubKeyI.(*PublicKey)
+ } else {
+ pubNew, err := ParsePubKey(keyBytes)
+ if err == nil {
+ *k = *pubNew
+ parsedPublicKeyCache.Store(string(keyBytes), pubNew)
+ }
}
return
}
@@ -158,7 +167,7 @@ func GenSecp256k1KeyPair() (
privateKeyEc, err := ec.NewPrivateKey(ec.S256())
if err != nil {
- log.Errorf("private key generation error: %s", err)
+ log.WithError(err).Error("private key generation failed")
return nil, nil, err
}
publicKey = (*PublicKey)(privateKeyEc.PubKey())
diff --git a/crypto/asymmetric/keypair_test.go b/crypto/asymmetric/keypair_test.go
index ead4e40bf..34f95c230 100644
--- a/crypto/asymmetric/keypair_test.go
+++ b/crypto/asymmetric/keypair_test.go
@@ -20,7 +20,6 @@ import (
"bytes"
"strings"
"testing"
-
"time"
"github.com/CovenantSQL/CovenantSQL/utils/log"
@@ -142,7 +141,7 @@ func TestPubKey(t *testing.T) {
}
func TestPublicKey_MarshalBinary(t *testing.T) {
- Convey("marshal unmarshal key", t, func() {
+ Convey("marshal unmarshal public key", t, func() {
_, publicKey, _ := GenSecp256k1KeyPair()
publicKey2 := new(PublicKey)
buf, _ := publicKey.MarshalBinary()
@@ -150,13 +149,40 @@ func TestPublicKey_MarshalBinary(t *testing.T) {
So(publicKey.IsEqual(publicKey2), ShouldBeTrue)
+ publicKey3 := new(PublicKey)
+ publicKey3.UnmarshalBinary(buf)
+
buf1, _ := publicKey.MarshalHash()
buf2, _ := publicKey2.MarshalHash()
+ buf3, _ := publicKey3.MarshalHash()
+
So(buf1, ShouldResemble, buf2)
+ So(buf1, ShouldResemble, buf3)
So(publicKey.Msgsize(), ShouldEqual, publicKey2.Msgsize())
})
}
+func TestPrivateKey_Serialize(t *testing.T) {
+ Convey("marshal unmarshal private key", t, func() {
+ pk, _, _ := GenSecp256k1KeyPair()
+ buf := pk.Serialize()
+ priv2, pub2 := PrivKeyFromBytes(buf)
+
+ So(priv2.PubKey().IsEqual(pub2), ShouldBeTrue)
+ })
+}
+
+func TestPaddedAppend(t *testing.T) {
+ Convey("paddedAppend", t, func() {
+ src := []byte("aaaa")
+ dst := make([]byte, 0, 16)
+ dst = paddedAppend(16, dst, src)
+
+ So(len(dst), ShouldEqual, 16)
+ So(dst, ShouldResemble, append([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, src...))
+ })
+}
+
func unmarshalAndMarshal(str string) string {
var key PublicKey
yaml.Unmarshal([]byte(str), &key)
diff --git a/crypto/asymmetric/signature.go b/crypto/asymmetric/signature.go
index 19d9b310a..77ac14580 100644
--- a/crypto/asymmetric/signature.go
+++ b/crypto/asymmetric/signature.go
@@ -20,7 +20,6 @@ import (
"crypto/elliptic"
"errors"
"math/big"
-
"sync"
"github.com/CovenantSQL/CovenantSQL/crypto/secp256k1"
diff --git a/crypto/etls/conn.go b/crypto/etls/conn.go
index 4820cfadb..fe471adfc 100644
--- a/crypto/etls/conn.go
+++ b/crypto/etls/conn.go
@@ -49,7 +49,7 @@ func NewConn(c net.Conn, cipher *Cipher, nodeID *proto.RawNodeID) *CryptoConn {
func Dial(network, address string, cipher *Cipher) (c *CryptoConn, err error) {
conn, err := net.Dial(network, address)
if err != nil {
- log.Errorf("connect to %s failed: %s", address, err)
+ log.WithField("addr", address).WithError(err).Error("connect failed")
return
}
@@ -67,7 +67,7 @@ func (c *CryptoConn) Read(b []byte) (n int, err error) {
if c.decStream == nil {
iv := make([]byte, c.info.ivLen)
if _, err = io.ReadFull(c.Conn, iv); err != nil {
- log.Infof("ReadFull failed: %s", err)
+ log.WithError(err).Info("read full failed")
return
}
if err = c.initDecrypt(iv); err != nil {
@@ -82,7 +82,6 @@ func (c *CryptoConn) Read(b []byte) (n int, err error) {
n, err = c.Conn.Read(cipherData)
if err != nil {
- log.Debugf("Read got: %s", err)
return
}
if n > 0 {
diff --git a/crypto/etls/conn_test.go b/crypto/etls/conn_test.go
index a76d0bcda..e9aa09224 100644
--- a/crypto/etls/conn_test.go
+++ b/crypto/etls/conn_test.go
@@ -35,7 +35,7 @@ type Result struct {
func (f *Foo) Bar(args *string, res *Result) error {
res.Data = len(*args)
log.Printf("Received %q, its length is %d", *args, res.Data)
- //return fmt.Errorf("Whoops, error happened")
+ //return fmt.Error("Whoops, error happened")
return nil
}
diff --git a/crypto/etls/encrypt_test.go b/crypto/etls/encrypt_test.go
index 9c98b47c2..129ccf94c 100644
--- a/crypto/etls/encrypt_test.go
+++ b/crypto/etls/encrypt_test.go
@@ -17,9 +17,8 @@
package etls
import (
- "testing"
-
"bytes"
+ "testing"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
. "github.com/smartystreets/goconvey/convey"
diff --git a/crypto/hash/hash.go b/crypto/hash/hash.go
index a9ae982b2..8108e9f3e 100644
--- a/crypto/hash/hash.go
+++ b/crypto/hash/hash.go
@@ -127,7 +127,7 @@ func (h *Hash) UnmarshalYAML(unmarshal func(interface{}) error) error {
// load hash
err := Decode(h, str)
if err != nil {
- log.Errorf("Error in UnmarshalYAML: %v", err)
+ log.WithError(err).Error("unmarshal YAML failed")
return err
}
return nil
diff --git a/crypto/hash/hash_test.go b/crypto/hash/hash_test.go
index 2811a3bfd..0ef77d42b 100644
--- a/crypto/hash/hash_test.go
+++ b/crypto/hash/hash_test.go
@@ -101,14 +101,14 @@ func TestHash(t *testing.T) {
// Invalid size for SetBytes.
err = hash.SetBytes([]byte{0x00})
if err == nil {
- t.Errorf("SetBytes: failed to received expected err - got: nil")
+ t.Error("SetBytes: failed to received expected err - got: nil")
}
// Invalid size for NewHash.
invalidHash := make([]byte, HashSize+1)
_, err = NewHash(invalidHash)
if err == nil {
- t.Errorf("NewHash: failed to received expected err - got: nil")
+ t.Error("NewHash: failed to received expected err - got: nil")
}
}
diff --git a/crypto/hash/hashfuncs.go b/crypto/hash/hashfuncs.go
index ba3d16caf..6235c4964 100644
--- a/crypto/hash/hashfuncs.go
+++ b/crypto/hash/hashfuncs.go
@@ -19,11 +19,9 @@ package hash
import (
"encoding/binary"
"hash/fnv"
-
// "crypto/sha256" benchmark is at least 10% faster on
// i7-4870HQ CPU @ 2.50GHz than "github.com/minio/sha256-simd"
"crypto/sha256"
-
// "minio/blake2b-simd" benchmark is at least 3% faster on
// i7-4870HQ CPU @ 2.50GHz than "golang.org/x/crypto/blake2b"
// and supports more CPU instructions
diff --git a/crypto/kms/privatekeystore.go b/crypto/kms/privatekeystore.go
index fb2bcfb34..ef4daf926 100644
--- a/crypto/kms/privatekeystore.go
+++ b/crypto/kms/privatekeystore.go
@@ -41,20 +41,22 @@ var (
func LoadPrivateKey(keyFilePath string, masterKey []byte) (key *asymmetric.PrivateKey, err error) {
fileContent, err := ioutil.ReadFile(keyFilePath)
if err != nil {
- log.Errorf("error read key file: %s, err: %s", keyFilePath, err)
+ log.WithField("path", keyFilePath).WithError(err).Error("read key file failed")
return
}
decData, err := symmetric.DecryptWithPassword(fileContent, masterKey)
if err != nil {
- log.Errorf("decrypt private key error")
+ log.Error("decrypt private key error")
return
}
// sha256 + privateKey
if len(decData) != hash.HashBSize+asymmetric.PrivateKeyBytesLen {
- log.Errorf("private key file size should be %d bytes",
- hash.HashBSize+asymmetric.PrivateKeyBytesLen)
+ log.WithFields(log.Fields{
+ "expected": hash.HashBSize + asymmetric.PrivateKeyBytesLen,
+ "actual": len(decData),
+ }).Error("wrong private key file size")
return nil, ErrNotKeyFile
}
@@ -87,33 +89,33 @@ func InitLocalKeyPair(privateKeyPath string, masterKey []byte) (err error) {
initLocalKeyStore()
privateKey, err = LoadPrivateKey(privateKeyPath, masterKey)
if err != nil {
- log.Infof("load private key failed: %s", err)
+ log.WithError(err).Info("load private key failed")
if err == ErrNotKeyFile {
- log.Errorf("not a valid private key file: %s", privateKeyPath)
+ log.WithField("path", privateKeyPath).Error("not a valid private key file")
return
}
if _, ok := err.(*os.PathError); (ok || err == os.ErrNotExist) && conf.GConf.GenerateKeyPair {
log.Info("private key file not exist, generating one")
privateKey, publicKey, err = asymmetric.GenSecp256k1KeyPair()
if err != nil {
- log.Errorf("generate private key failed: %s", err)
+ log.WithError(err).Error("generate private key failed")
return
}
- log.Infof("saving new private key file: %s", privateKeyPath)
+ log.WithField("path", privateKeyPath).Info("saving new private key file")
err = SavePrivateKey(privateKeyPath, privateKey, masterKey)
if err != nil {
- log.Errorf("save private key failed: %s", err)
+ log.WithError(err).Error("save private key failed")
return
}
} else {
- log.Errorf("unexpected error while loading private key: %s", err)
+ log.WithError(err).Error("unexpected error while loading private key")
return
}
}
if publicKey == nil {
publicKey = privateKey.PubKey()
}
- log.Debugf("\n### Public Key ###\n%x\n### Public Key ###\n", publicKey.Serialize())
+ log.Debugf("\n### Public Key ###\n%#x\n### Public Key ###\n", publicKey.Serialize())
SetLocalKeyPair(privateKey, publicKey)
return
}
diff --git a/crypto/kms/privatekeystore_test.go b/crypto/kms/privatekeystore_test.go
index 44682c76f..0485552af 100644
--- a/crypto/kms/privatekeystore_test.go
+++ b/crypto/kms/privatekeystore_test.go
@@ -17,14 +17,11 @@
package kms
import (
+ "bytes"
"encoding/hex"
- "testing"
-
- "os"
-
"io/ioutil"
-
- "bytes"
+ "os"
+ "testing"
"github.com/CovenantSQL/CovenantSQL/conf"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
diff --git a/crypto/kms/pubkeystore.go b/crypto/kms/pubkeystore.go
index 7a952605a..0c3e15e6f 100644
--- a/crypto/kms/pubkeystore.go
+++ b/crypto/kms/pubkeystore.go
@@ -17,7 +17,6 @@
package kms
import (
- "bytes"
"errors"
"os"
"path/filepath"
@@ -26,14 +25,13 @@ import (
"sync"
"github.com/CovenantSQL/CovenantSQL/conf"
- "github.com/CovenantSQL/CovenantSQL/utils/log"
-
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
mine "github.com/CovenantSQL/CovenantSQL/pow/cpuminer"
"github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/utils"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
"github.com/coreos/bbolt"
- "github.com/ugorji/go/codec"
)
// PublicKeyStore holds db and bucket name
@@ -69,13 +67,13 @@ func init() {
strings.HasPrefix(filepath.Base(os.Args[0]), "___") {
_, testFile, _, _ := runtime.Caller(0)
confFile := filepath.Join(filepath.Dir(testFile), "config.yaml")
- log.Debugf("Current test filename: %s", confFile)
- log.Debugf("os.Args: %v", os.Args)
+ log.WithField("conf", confFile).Debug("current test filename")
+ log.Debugf("os.Args: %#v", os.Args)
var err error
conf.GConf, err = conf.LoadConfig(confFile)
if err != nil {
- log.Fatalf("load config for test in kms failed: %s", err)
+ log.WithError(err).Fatal("load config for test in kms failed")
}
InitBP()
}
@@ -90,7 +88,7 @@ func InitBP() {
err := hash.Decode(&BP.RawNodeID.Hash, string(BP.NodeID))
if err != nil {
- log.Fatalf("BP.NodeID error: %s", err)
+ log.WithError(err).Fatal("BP.NodeID error")
}
}
@@ -120,7 +118,7 @@ func InitPublicKeyStore(dbPath string, initNodes []proto.Node) (err error) {
var bdb *bolt.DB
bdb, err = bolt.Open(dbPath, 0600, nil)
if err != nil {
- log.Errorf("InitPublicKeyStore failed: %s", err)
+ log.WithError(err).Error("InitPublicKeyStore failed")
pksLock.Unlock()
return
}
@@ -128,13 +126,13 @@ func InitPublicKeyStore(dbPath string, initNodes []proto.Node) (err error) {
name := []byte(kmsBucketName)
err = bdb.Update(func(tx *bolt.Tx) error {
if _, err := tx.CreateBucketIfNotExists(name); err != nil {
- log.Errorf("could not create bucket: %s", err)
+ log.WithError(err).Error("could not create bucket")
return err
}
return nil // return from Update func
})
if err != nil {
- log.Errorf("InitPublicKeyStore failed: %s", err)
+ log.WithError(err).Error("InitPublicKeyStore failed")
pksLock.Unlock()
return
}
@@ -149,7 +147,7 @@ func InitPublicKeyStore(dbPath string, initNodes []proto.Node) (err error) {
for _, n := range initNodes {
err = setNode(&n)
if err != nil {
- log.Errorf("set init nodes failed: %v", err)
+ log.WithError(err).Error("set init nodes failed")
return
}
}
@@ -185,16 +183,12 @@ func GetNodeInfo(id proto.NodeID) (nodeInfo *proto.Node, err error) {
if byteVal == nil {
return ErrKeyNotFound
}
- reader := bytes.NewReader(byteVal)
- mh := &codec.MsgpackHandle{}
- dec := codec.NewDecoder(reader, mh)
- nodeInfo = proto.NewNode()
- err = dec.Decode(nodeInfo)
- log.Debugf("get node info: %v", nodeInfo)
+ err = utils.DecodeMsgPack(byteVal, &nodeInfo)
+ log.Debugf("get node info: %#v", nodeInfo)
return err // return from View func
})
if err != nil {
- log.Infof("get node info failed: %s", err)
+ log.WithError(err).Error("get node info failed")
}
return
}
@@ -218,7 +212,7 @@ func GetAllNodeID() (nodeIDs []proto.NodeID, err error) {
return err // return from View func
})
if err != nil {
- log.Errorf("get all node id failed: %s", err)
+ log.WithError(err).Error("get all node id failed")
}
return
@@ -266,15 +260,12 @@ func setNode(nodeInfo *proto.Node) (err error) {
return ErrPKSNotInitialized
}
- nodeBuf := new(bytes.Buffer)
- mh := &codec.MsgpackHandle{}
- enc := codec.NewEncoder(nodeBuf, mh)
- err = enc.Encode(*nodeInfo)
+ nodeBuf, err := utils.EncodeMsgPack(nodeInfo)
if err != nil {
- log.Errorf("marshal node info failed: %s", err)
+ log.WithError(err).Error("marshal node info failed")
return
}
- log.Debugf("set node: %v", nodeInfo)
+ log.Debugf("set node: %#v", nodeInfo)
err = pks.db.Update(func(tx *bolt.Tx) error {
bucket := tx.Bucket(pks.bucket)
@@ -284,7 +275,7 @@ func setNode(nodeInfo *proto.Node) (err error) {
return bucket.Put([]byte(nodeInfo.ID), nodeBuf.Bytes())
})
if err != nil {
- log.Errorf("get node info failed: %s", err)
+ log.WithError(err).Error("get node info failed")
}
return
@@ -306,7 +297,7 @@ func DelNode(id proto.NodeID) (err error) {
return bucket.Delete([]byte(id))
})
if err != nil {
- log.Errorf("del node failed: %s", err)
+ log.WithError(err).Error("del node failed")
}
return
}
@@ -320,7 +311,7 @@ func removeBucket() (err error) {
return tx.DeleteBucket([]byte(kmsBucketName))
})
if err != nil {
- log.Errorf("remove bucket failed: %s", err)
+ log.WithError(err).Error("remove bucket failed")
return
}
// ks.bucket == nil means bucket not exist
@@ -343,7 +334,7 @@ func ResetBucket() error {
})
pks.bucket = bucketName
if err != nil {
- log.Errorf("reset bucket failed: %s", err)
+ log.WithError(err).Error("reset bucket failed")
}
return err
diff --git a/crypto/kms/pubkeystore_test.go b/crypto/kms/pubkeystore_test.go
index de6c6fba7..eae61e309 100644
--- a/crypto/kms/pubkeystore_test.go
+++ b/crypto/kms/pubkeystore_test.go
@@ -17,7 +17,6 @@
package kms
import (
- "bytes"
"os"
"reflect"
"testing"
@@ -25,9 +24,9 @@ import (
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/pow/cpuminer"
"github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/utils"
"github.com/CovenantSQL/CovenantSQL/utils/log"
. "github.com/smartystreets/goconvey/convey"
- "github.com/ugorji/go/codec"
"gopkg.in/yaml.v2"
)
@@ -38,13 +37,13 @@ func TestDB(t *testing.T) {
privKey1, pubKey1, _ := asymmetric.GenSecp256k1KeyPair()
privKey2, pubKey2, _ := asymmetric.GenSecp256k1KeyPair()
node1 := &proto.Node{
- ID: proto.NodeID("node1"),
+ ID: proto.NodeID("1111"),
Addr: "",
PublicKey: pubKey1,
Nonce: cpuminer.Uint256{},
}
node2 := &proto.Node{
- ID: proto.NodeID("node2"),
+ ID: proto.NodeID("2222"),
Addr: "",
PublicKey: pubKey2,
Nonce: cpuminer.Uint256{},
@@ -70,7 +69,7 @@ func TestDB(t *testing.T) {
So(err, ShouldBeNil)
So(pubk.IsEqual(BP.PublicKey), ShouldBeTrue)
- pubk, err = GetPublicKey(proto.NodeID("not exist"))
+ pubk, err = GetPublicKey(proto.NodeID("99999999"))
So(pubk, ShouldBeNil)
So(err, ShouldEqual, ErrKeyNotFound)
@@ -89,15 +88,15 @@ func TestDB(t *testing.T) {
err = SetPublicKey(BP.NodeID, cpuminer.Uint256{}, BP.PublicKey)
So(err, ShouldEqual, ErrNodeIDKeyNonceNotMatch)
- err = SetPublicKey(proto.NodeID("0"+BP.NodeID), BP.Nonce, BP.PublicKey)
+ err = SetPublicKey(proto.NodeID("00"+BP.NodeID), BP.Nonce, BP.PublicKey)
So(err, ShouldEqual, ErrNodeIDKeyNonceNotMatch)
- pubk, err = GetPublicKey(proto.NodeID("node1"))
+ pubk, err = GetPublicKey(proto.NodeID("1111"))
So(pubk, ShouldNotBeNil)
So(err, ShouldBeNil)
So(privKey1.PubKey().IsEqual(pubKey1), ShouldBeTrue)
- pubk, err = GetPublicKey(proto.NodeID("node2"))
+ pubk, err = GetPublicKey(proto.NodeID("2222"))
So(pubk, ShouldNotBeNil)
So(err, ShouldBeNil)
So(privKey2.PubKey().IsEqual(pubKey2), ShouldBeTrue)
@@ -105,17 +104,17 @@ func TestDB(t *testing.T) {
IDs, err := GetAllNodeID()
So(err, ShouldBeNil)
So(IDs, ShouldHaveLength, 3)
- So(IDs, ShouldContain, proto.NodeID("node1"))
- So(IDs, ShouldContain, proto.NodeID("node2"))
+ So(IDs, ShouldContain, proto.NodeID("1111"))
+ So(IDs, ShouldContain, proto.NodeID("2222"))
So(IDs, ShouldContain, BP.NodeID)
- err = DelNode(proto.NodeID("node2"))
+ err = DelNode(proto.NodeID("2222"))
So(err, ShouldBeNil)
- err = DelNode(proto.NodeID("node2"))
+ err = DelNode(proto.NodeID("2222"))
So(err, ShouldBeNil)
- pubk, err = GetPublicKey(proto.NodeID("node2"))
+ pubk, err = GetPublicKey(proto.NodeID("2222"))
So(pubk, ShouldBeNil)
So(err, ShouldEqual, ErrKeyNotFound)
@@ -129,7 +128,7 @@ func TestDB(t *testing.T) {
err = setNode(node1)
So(err, ShouldEqual, ErrBucketNotInitialized)
- err = DelNode(proto.NodeID("node2"))
+ err = DelNode(proto.NodeID("2222"))
So(err, ShouldEqual, ErrBucketNotInitialized)
IDs, err = GetAllNodeID()
@@ -139,7 +138,7 @@ func TestDB(t *testing.T) {
err = ResetBucket()
So(err, ShouldBeNil)
- pubk, err = GetPublicKey(proto.NodeID("node2"))
+ pubk, err = GetPublicKey(proto.NodeID("2222"))
So(pubk, ShouldBeNil)
So(err, ShouldEqual, ErrKeyNotFound)
@@ -161,7 +160,7 @@ func TestErrorPath(t *testing.T) {
func TestMarshalNode(t *testing.T) {
Convey("marshal unmarshal node", t, func() {
nodeInfo := &proto.Node{
- ID: "abc",
+ ID: "0000000000000000000000000000000000000000000000000000000000001111",
Addr: "addr",
PublicKey: nil,
Nonce: cpuminer.Uint256{
@@ -171,18 +170,13 @@ func TestMarshalNode(t *testing.T) {
D: 4,
},
}
- nodeBuf := new(bytes.Buffer)
- mh := &codec.MsgpackHandle{}
- enc := codec.NewEncoder(nodeBuf, mh)
- err := enc.Encode(nodeInfo)
+ nodeBuf, err := utils.EncodeMsgPack(nodeInfo)
if err != nil {
log.Errorf("encode error: %s", err)
}
nodeDec := proto.NewNode()
- reader := bytes.NewReader(nodeBuf.Bytes())
- dec := codec.NewDecoder(reader, mh)
- err = dec.Decode(nodeDec)
+ err = utils.DecodeMsgPack(nodeBuf.Bytes(), nodeDec)
So(reflect.DeepEqual(nodeDec, nodeInfo), ShouldBeTrue)
})
diff --git a/crypto/symmetric/aes.go b/crypto/symmetric/aes.go
index f04414dc7..41c7a0f1d 100644
--- a/crypto/symmetric/aes.go
+++ b/crypto/symmetric/aes.go
@@ -21,9 +21,8 @@ import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
- "io"
-
"errors"
+ "io"
"github.com/CovenantSQL/CovenantSQL/crypto"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
diff --git a/kayak/boltdb_store_test.go b/kayak/boltdb_store_test.go
index b022bf62d..994f12857 100644
--- a/kayak/boltdb_store_test.go
+++ b/kayak/boltdb_store_test.go
@@ -87,7 +87,7 @@ func TestBoltOptionsTimeout(t *testing.T) {
So(err, ShouldNotBeNil)
So(err.Error(), ShouldEqual, "timeout")
case <-time.After(5 * time.Second):
- Printf("Gave up waiting for timeout response")
+ Print("Gave up waiting for timeout response")
}
})
}
diff --git a/kayak/twopc_runner.go b/kayak/twopc_runner.go
index e36cd3648..3f9c75069 100644
--- a/kayak/twopc_runner.go
+++ b/kayak/twopc_runner.go
@@ -19,6 +19,7 @@ package kayak
import (
"context"
"fmt"
+ "runtime/trace"
"sync"
"time"
@@ -73,7 +74,6 @@ type TwoPCRunner struct {
shutdownLock sync.Mutex
// Lock/events
- processLock sync.Mutex
processReq chan []byte
processRes chan logProcessResult
updatePeersLock sync.Mutex
@@ -193,8 +193,10 @@ func (r *TwoPCRunner) tryRestore() error {
if lastIndex > lastCommitted {
// uncommitted log found, print warning
- log.Warningf("truncating local uncommitted log, uncommitted: %d, committed: %d",
- lastIndex, lastCommitted)
+ log.WithFields(log.Fields{
+ "uncommitted": lastIndex,
+ "committed": lastCommitted,
+ }).Warning("truncating local uncommitted log")
// truncate local uncommitted logs
r.logStore.DeleteRange(lastCommitted+1, lastIndex)
@@ -278,14 +280,12 @@ func (r *TwoPCRunner) UpdatePeers(peers *Peers) error {
// Apply implements Runner.Apply.
func (r *TwoPCRunner) Apply(data []byte) (uint64, error) {
- r.processLock.Lock()
- defer r.processLock.Unlock()
-
// check leader privilege
if r.role != proto.Leader {
return 0, ErrNotLeader
}
+ //TODO(auxten): need throughput optimization
r.processReq <- data
res := <-r.processRes
@@ -335,6 +335,11 @@ func (r *TwoPCRunner) safeForPeersUpdate() chan *Peers {
}
func (r *TwoPCRunner) processNewLog(data []byte) (res logProcessResult) {
+ ctx := context.Background()
+ ctx, task := trace.NewTask(ctx, "processNewLog")
+ defer task.End()
+ defer trace.StartRegion(ctx, "processNewLogRegion").End()
+
// build Log
l := &Log{
Index: r.lastLogIndex + 1,
@@ -428,6 +433,11 @@ func (r *TwoPCRunner) getState() ServerState {
}
func (r *TwoPCRunner) processRequest(req Request) {
+ ctx := context.Background()
+ ctx, task := trace.NewTask(ctx, "processRequest")
+ defer task.End()
+ defer trace.StartRegion(ctx, "processRequestRegion").End()
+
// verify call from leader
if err := r.verifyLeader(req); err != nil {
req.SendResponse(nil, err)
diff --git a/kayak/types.go b/kayak/types.go
index 15d9c4749..e71aa5872 100644
--- a/kayak/types.go
+++ b/kayak/types.go
@@ -221,6 +221,7 @@ func (c *Peers) Serialize() []byte {
// Sign generates signature.
func (c *Peers) Sign(signer *asymmetric.PrivateKey) error {
+ c.PubKey = signer.PubKey()
h := hash.THashB(c.Serialize())
sig, err := signer.Sign(h)
diff --git a/merkle/merkletrie_test.go b/merkle/merkletrie_test.go
index 973ae4650..58a94cbe0 100644
--- a/merkle/merkletrie_test.go
+++ b/merkle/merkletrie_test.go
@@ -1,13 +1,10 @@
package merkle
import (
- "testing"
-
"bytes"
-
"crypto/rand"
-
"math"
+ "testing"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
. "github.com/smartystreets/goconvey/convey"
diff --git a/merkle/patriciatrie_test.go b/merkle/patriciatrie_test.go
index 375d2c8bb..c5cf5ce62 100644
--- a/merkle/patriciatrie_test.go
+++ b/merkle/patriciatrie_test.go
@@ -1,12 +1,10 @@
package merkle
import (
- "testing"
-
"bytes"
"encoding/gob"
-
"strings"
+ "testing"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
. "github.com/smartystreets/goconvey/convey"
diff --git a/metric/covenantmetric_test.go b/metric/covenantmetric_test.go
index dbaa8d00b..90d8646e2 100644
--- a/metric/covenantmetric_test.go
+++ b/metric/covenantmetric_test.go
@@ -31,7 +31,7 @@ func TestMetrics(t *testing.T) {
log.SetLevel(log.DebugLevel)
reg := prometheus.NewRegistry()
reg.MustRegister(NewCovenantSQLCollector())
- log.Debugf("Gauge Collector 'CovenantSQLCollector' registered.")
+ log.Debug("Gauge Collector 'CovenantSQLCollector' registered.")
time.Sleep(1100 * time.Millisecond)
Convey("get metric", t, func() {
diff --git a/metric/cpu_dragonfly_test.go b/metric/cpu_dragonfly_test.go
index 7355437a3..a01d2d835 100644
--- a/metric/cpu_dragonfly_test.go
+++ b/metric/cpu_dragonfly_test.go
@@ -31,7 +31,7 @@ func TestCPU(t *testing.T) {
}
if len(times) == 0 {
- t.Fatalf("no cputimes found")
+ t.Fatal("no cputimes found")
}
want := runtime.NumCPU() * fieldsCount
diff --git a/metric/metric.go b/metric/metric.go
index 94f58113f..10895dc41 100644
--- a/metric/metric.go
+++ b/metric/metric.go
@@ -49,18 +49,18 @@ func init() {
func StartMetricCollector() (registry *prometheus.Registry) {
nc, err := NewNodeCollector()
if err != nil {
- log.Errorf("couldn't create node collector: %s", err)
+ log.WithError(err).Error("couldn't create node collector")
return
}
registry = prometheus.NewRegistry()
err = registry.Register(nc)
if err != nil {
- log.Errorf("couldn't register collector: %s", err)
+ log.WithError(err).Error("couldn't register collector")
return nil
}
- log.Infof("Enabled collectors:")
+ log.Info("Enabled collectors:")
var collectors []string
for n := range nc.Collectors {
collectors = append(collectors, n)
diff --git a/metric/ntp.go b/metric/ntp.go
index 2dfa395d9..5b12c0434 100644
--- a/metric/ntp.go
+++ b/metric/ntp.go
@@ -16,6 +16,7 @@
package metric
import (
+ "errors"
"fmt"
"net"
"time"
@@ -53,7 +54,7 @@ type ntpCollector struct {
func NewNtpCollector() (Collector, error) {
ipaddr := net.ParseIP(ntpServer)
if !ntpServerIsLocal && (ipaddr == nil || !ipaddr.IsLoopback()) {
- return nil, fmt.Errorf("only IP address of local NTP server is valid for --collector.ntp.server")
+ return nil, errors.New("only IP address of local NTP server is valid for --collector.ntp.server")
}
if ntpProtocolVersion < 2 || ntpProtocolVersion > 4 {
@@ -61,7 +62,7 @@ func NewNtpCollector() (Collector, error) {
}
if ntpOffsetTolerance < 0 {
- return nil, fmt.Errorf("Offset tolerance must be non-negative")
+ return nil, errors.New("Offset tolerance must be non-negative")
}
return &ntpCollector{
diff --git a/pow/cpuminer/miner_test.go b/pow/cpuminer/miner_test.go
index 814204f33..24e81380d 100644
--- a/pow/cpuminer/miner_test.go
+++ b/pow/cpuminer/miner_test.go
@@ -17,11 +17,9 @@
package cpuminer
import (
+ "sync"
"testing"
-
"time"
-
- "sync"
)
func TestCPUMiner_HashBlock(t *testing.T) {
diff --git a/pow/cpuminer/uint256_test.go b/pow/cpuminer/uint256_test.go
index 53204f680..d6d87ee81 100644
--- a/pow/cpuminer/uint256_test.go
+++ b/pow/cpuminer/uint256_test.go
@@ -19,11 +19,9 @@ package cpuminer
import (
"math"
"testing"
-
- "github.com/CovenantSQL/CovenantSQL/utils/log"
-
"unsafe"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
. "github.com/smartystreets/goconvey/convey"
)
diff --git a/proto/nodeinfo.go b/proto/nodeinfo.go
index 5c40549aa..019e32237 100644
--- a/proto/nodeinfo.go
+++ b/proto/nodeinfo.go
@@ -114,7 +114,7 @@ func (id *NodeID) Difficulty() (difficulty int) {
func (id *NodeID) ToRawNodeID() *RawNodeID {
idHash, err := hash.NewHashFromStr(string(*id))
if err != nil {
- log.Errorf("error node id %s %s", *id, err)
+ log.WithField("id", *id).WithError(err).Error("error node id")
return nil
}
return &RawNodeID{*idHash}
@@ -130,6 +130,26 @@ func (id *NodeID) IsEqual(target *NodeID) bool {
return strings.Compare(string(*id), string(*target)) == 0
}
+// MarshalBinary does the serialization
+func (id *NodeID) MarshalBinary() (keyBytes []byte, err error) {
+ if id == nil {
+ return []byte{}, nil
+ }
+ h, err := hash.NewHashFromStr(string(*id))
+ return h[:], err
+}
+
+// UnmarshalBinary does the deserialization
+func (id *NodeID) UnmarshalBinary(keyBytes []byte) (err error) {
+ h, err := hash.NewHash(keyBytes)
+ if err != nil {
+ log.Error("nodeID bytes len should be 32")
+ return
+ }
+ *id = NodeID(h.String())
+ return
+}
+
// InitNodeCryptoInfo generate Node asymmetric key pair and generate Node.NonceInfo
// Node.ID = Node.NonceInfo.Hash
func (node *Node) InitNodeCryptoInfo(timeThreshold time.Duration) (err error) {
@@ -141,7 +161,7 @@ func (node *Node) InitNodeCryptoInfo(timeThreshold time.Duration) (err error) {
nonce := asymmetric.GetPubKeyNonce(node.PublicKey, NewNodeIDDifficulty, timeThreshold, nil)
node.ID = NodeID(nonce.Hash.String())
node.Nonce = nonce.Nonce
- log.Debugf("Node: %v", node)
+ log.Debugf("Node: %#v", node)
return
}
diff --git a/proto/nodeinfo_test.go b/proto/nodeinfo_test.go
index d66f4f3bf..f033d7865 100644
--- a/proto/nodeinfo_test.go
+++ b/proto/nodeinfo_test.go
@@ -19,7 +19,6 @@ package proto
import (
"strings"
"testing"
-
"time"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
@@ -129,3 +128,24 @@ func TestNodeID_IsEmpty(t *testing.T) {
So(node.IsEmpty(), ShouldBeTrue)
})
}
+
+func TestNodeID_MarshalBinary(t *testing.T) {
+ Convey("NodeID MarshalBinary", t, func() {
+ var nodeID, nodeID2 NodeID
+
+ nb, err := nodeID.MarshalBinary()
+ So(err, ShouldBeNil)
+
+ nodeID = NodeID("0000000000000000000000000000000000000000000000000000000000000000")
+ nb, err = nodeID.MarshalBinary()
+ So(err, ShouldBeNil)
+ So(len(nb), ShouldEqual, hash.HashSize)
+
+ err = nodeID2.UnmarshalBinary([]byte("0000"))
+ So(err, ShouldNotBeNil)
+
+ err = nodeID2.UnmarshalBinary(nb)
+ So(err, ShouldBeNil)
+ So(nodeID2, ShouldResemble, nodeID)
+ })
+}
diff --git a/proto/proto.go b/proto/proto.go
index 7bda48178..2f5a812f8 100644
--- a/proto/proto.go
+++ b/proto/proto.go
@@ -39,10 +39,10 @@ type EnvelopeAPI interface {
// Envelope is the protocol header
type Envelope struct {
- Version string
- TTL time.Duration
- Expire time.Duration
- NodeID *RawNodeID
+ Version string `json:"v"`
+ TTL time.Duration `json:"t"`
+ Expire time.Duration `json:"e"`
+ NodeID *RawNodeID `json:"id"`
}
// PingReq is Ping RPC request
@@ -72,9 +72,9 @@ type UploadMetricsResp struct {
// FindNeighborReq is FindNeighbor RPC request
type FindNeighborReq struct {
- NodeID NodeID
- Roles []ServerRole
- Count int
+ ID NodeID
+ Roles []ServerRole
+ Count int
Envelope
}
@@ -87,7 +87,7 @@ type FindNeighborResp struct {
// FindNodeReq is FindNode RPC request
type FindNodeReq struct {
- NodeID NodeID
+ ID NodeID
Envelope
}
diff --git a/proto/proto_gen.go b/proto/proto_gen.go
index 2a1454710..d0aab0198 100644
--- a/proto/proto_gen.go
+++ b/proto/proto_gen.go
@@ -68,7 +68,7 @@ func (z *FindNeighborReq) MarshalHash() (o []byte, err error) {
o = hsp.AppendBytes(o, oTemp)
}
o = append(o, 0x84)
- if oTemp, err := z.NodeID.MarshalHash(); err != nil {
+ if oTemp, err := z.ID.MarshalHash(); err != nil {
return nil, err
} else {
o = hsp.AppendBytes(o, oTemp)
@@ -89,7 +89,7 @@ func (z *FindNeighborReq) MarshalHash() (o []byte, err error) {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *FindNeighborReq) Msgsize() (s int) {
- s = 1 + 9 + z.Envelope.Msgsize() + 7 + z.NodeID.Msgsize() + 6 + hsp.ArrayHeaderSize
+ s = 1 + 9 + z.Envelope.Msgsize() + 3 + z.ID.Msgsize() + 6 + hsp.ArrayHeaderSize
for za0001 := range z.Roles {
s += z.Roles[za0001].Msgsize()
}
@@ -144,7 +144,7 @@ func (z *FindNodeReq) MarshalHash() (o []byte, err error) {
o = hsp.AppendBytes(o, oTemp)
}
o = append(o, 0x82)
- if oTemp, err := z.NodeID.MarshalHash(); err != nil {
+ if oTemp, err := z.ID.MarshalHash(); err != nil {
return nil, err
} else {
o = hsp.AppendBytes(o, oTemp)
@@ -154,7 +154,7 @@ func (z *FindNodeReq) MarshalHash() (o []byte, err error) {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *FindNodeReq) Msgsize() (s int) {
- s = 1 + 9 + z.Envelope.Msgsize() + 7 + z.NodeID.Msgsize()
+ s = 1 + 9 + z.Envelope.Msgsize() + 3 + z.ID.Msgsize()
return
}
diff --git a/proto/proto_test.go b/proto/proto_test.go
index fdca927f6..82428d995 100644
--- a/proto/proto_test.go
+++ b/proto/proto_test.go
@@ -18,7 +18,6 @@ package proto
import (
"testing"
-
"time"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
diff --git a/route/acl.go b/route/acl.go
index 5c6b073d3..25fdf7494 100644
--- a/route/acl.go
+++ b/route/acl.go
@@ -101,6 +101,10 @@ const (
SQLCFetchBlock
// SQLCFetchAckedQuery is used by sqlchain to fetch response ack from adjacent nodes
SQLCFetchAckedQuery
+ // SQLCSignBilling is used by sqlchain to response billing signature for periodic billing request
+ SQLCSignBilling
+ // SQLCLaunchBilling is used by blockproducer to trigger the billing process in sqlchain
+ SQLCLaunchBilling
// SQLCSubscribeTransactions is used by sqlchain to handle observer subscription request
SQLCSubscribeTransactions
// SQLCCancelSubscription is used by sqlchain to handle observer subscription cancellation request
@@ -109,16 +113,39 @@ const (
OBSAdviseAckedQuery
// OBSAdviseNewBlock is used by sqlchain to push new block to observers
OBSAdviseNewBlock
+ // MCCAdviseNewBlock is used by block producer to push block to adjacent nodes
+ MCCAdviseNewBlock
+ // MCCAdviseTxBilling is used by block producer to push billing transaction to adjacent nodes
+ MCCAdviseTxBilling
+ // MCCAdviseBillingRequest is used by block producer to push billing request to adjacent nodes
+ MCCAdviseBillingRequest
+ // MCCFetchBlock is used by nodes to fetch block from block producer
+ MCCFetchBlock
+ // MCCFetchBlockByCount is used by nodes to fetch block from block producer by block count since genesis
+ MCCFetchBlockByCount
+ // MCCFetchTxBilling is used by nodes to fetch billing transaction from block producer
+ MCCFetchTxBilling
// MCCNextAccountNonce is used by block producer main chain to allocate next nonce for transactions
MCCNextAccountNonce
// MCCAddTx is used by block producer main chain to upload transaction
MCCAddTx
- // MCCAddTxTransfer is used by block producer main chain to upload transfer transaction
- MCCAddTxTransfer
// MCCQueryAccountStableBalance is used by block producer to provide account stable coin balance
MCCQueryAccountStableBalance
// MCCQueryAccountCovenantBalance is used by block producer to provide account covenant coin balance
MCCQueryAccountCovenantBalance
+
+ // DHTRPCName defines the block producer dh-rpc service name
+ DHTRPCName = "DHT"
+ // BlockProducerRPCName defines main chain rpc name
+ BlockProducerRPCName = "MCC"
+ // SQLChainRPCName defines the sql chain rpc name
+ SQLChainRPCName = "SQLC"
+ // DBRPCName defines the sql chain db service rpc name
+ DBRPCName = "DBS"
+ // BPDBRPCName defines the block producer db service rpc name
+ BPDBRPCName = "BPDB"
+ // ObserverRPCName defines the observer node service rpc name
+ ObserverRPCName = "OBS"
)
// String returns the RemoteFunc string
@@ -164,6 +191,10 @@ func (s RemoteFunc) String() string {
return "SQLC.FetchBlock"
case SQLCFetchAckedQuery:
return "SQLC.FetchAckedQuery"
+ case SQLCSignBilling:
+ return "SQLC.SignBilling"
+ case SQLCLaunchBilling:
+ return "SQLC.LaunchBilling"
case SQLCSubscribeTransactions:
return "SQLC.SubscribeTransactions"
case SQLCCancelSubscription:
@@ -172,12 +203,22 @@ func (s RemoteFunc) String() string {
return "OBS.AdviseAckedQuery"
case OBSAdviseNewBlock:
return "OBS.AdviseNewBlock"
+ case MCCAdviseNewBlock:
+ return "MCC.AdviseNewBlock"
+ case MCCAdviseTxBilling:
+ return "MCC.AdviseTxBilling"
+ case MCCAdviseBillingRequest:
+ return "MCC.AdviseBillingRequest"
+ case MCCFetchBlock:
+ return "MCC.FetchBlock"
+ case MCCFetchBlockByCount:
+ return "MCC.FetchBlockByCount"
+ case MCCFetchTxBilling:
+ return "MCC.FetchTxBilling"
case MCCNextAccountNonce:
return "MCC.NextAccountNonce"
case MCCAddTx:
return "MCC.AddTx"
- case MCCAddTxTransfer:
- return "MCC.AddTxTransfer"
case MCCQueryAccountStableBalance:
return "MCC.QueryAccountStableBalance"
case MCCQueryAccountCovenantBalance:
@@ -195,7 +236,7 @@ func IsPermitted(callerEnvelope *proto.Envelope, funcName RemoteFunc) (ok bool)
if callerETLSNodeID != nil {
if callerETLSNodeID.IsEqual(&kms.AnonymousRawNodeID.Hash) {
if funcName != DHTPing {
- log.Warnf("anonymous ETLS connection can not used by %s", funcName)
+ log.WithField("field", funcName).Warning("anonymous ETLS connection can not used")
return false
}
}
diff --git a/route/bootstrap.go b/route/bootstrap.go
index 9f27aa105..3ad304699 100644
--- a/route/bootstrap.go
+++ b/route/bootstrap.go
@@ -71,7 +71,7 @@ func NewDNSClient() *DNSClient {
} else {
clientConfig, err = dns.ClientConfigFromFile("/etc/resolv.conf")
if err != nil || clientConfig == nil {
- log.Errorf("can not initialize the local resolver: %s", err)
+ log.WithError(err).Error("can not initialize the local resolver")
}
}
@@ -95,7 +95,7 @@ func (dc *DNSClient) Query(qname string, qtype uint16) (*dns.Msg, error) {
}
return r, fmt.Errorf("DNS query failed with Rcode %v", r.Rcode)
}
- return nil, fmt.Errorf("no available name server")
+ return nil, errors.New("no available name server")
}
// GetKey returns the DNSKey for a name server
@@ -111,7 +111,7 @@ func (dc *DNSClient) GetKey(name string, keytag uint16) (*dns.DNSKEY, error) {
}
}
}
- return nil, fmt.Errorf("no DNSKEY returned by nameserver")
+ return nil, errors.New("no DNSKEY returned by nameserver")
}
// VerifySection checks RRSIGs to make sure the name server is authentic
@@ -134,16 +134,24 @@ func (dc *DNSClient) VerifySection(set []dns.RR) error {
if !validDNSKey {
return fmt.Errorf("DNSKEY %s not valid", key.PublicKey)
}
- log.Debugf("valid DNSKEY %s of %s", key.PublicKey, domain)
+ log.WithFields(log.Fields{
+ "pub": key.PublicKey,
+ "domain": domain,
+ }).Debug("valid DNSKEY")
if err := rr.(*dns.RRSIG).Verify(key, rrset); err != nil {
return fmt.Errorf(";- Bogus signature, %s does not validate (DNSKEY %s/%d) [%s]",
shortSig(rr.(*dns.RRSIG)), key.Header().Name, key.KeyTag(), err.Error())
}
- log.Debugf(";+ Secure signature, %s validates (DNSKEY %s/%d %s)", shortSig(rr.(*dns.RRSIG)), key.Header().Name, key.KeyTag(), key.PublicKey)
+ log.WithFields(log.Fields{
+ "rrsig": shortSig(rr.(*dns.RRSIG)),
+ "name": key.Header().Name,
+ "tag": key.KeyTag(),
+ "pub": key.PublicKey,
+ }).Debug("signature secured")
return nil
}
}
- return fmt.Errorf("not DNSSEC record")
+ return errors.New("not DNSSEC record")
}
// GetRRSet returns the RRset belonging to the signature with name and type t
@@ -166,12 +174,12 @@ func shortSig(sig *dns.RRSIG) string {
func (dc *DNSClient) GetBPFromDNSSeed(BPDomain string) (BPNodes IDNodeMap, err error) {
srvRR := dc.GetSRVRecords(BPDomain)
if srvRR == nil {
- err = fmt.Errorf("got empty SRV records set")
+ err = errors.New("got empty SRV records set")
log.Error(err)
return
}
if err = dc.VerifySection(srvRR.Answer); err != nil {
- log.Errorf("record verify failed: %s", err)
+ log.WithError(err).Error("record verify failed")
return
}
BPNodes = make(IDNodeMap)
@@ -183,7 +191,7 @@ func (dc *DNSClient) GetBPFromDNSSeed(BPDomain string) (BPNodes IDNodeMap, err e
aRR := dc.GetARecord(srv.Target)
if aRR != nil {
if err = dc.VerifySection(aRR.Answer); err != nil {
- log.Errorf("verify SRV section failed: %v", err)
+ log.WithError(err).Error("verify SRV section failed")
return
}
for _, rr1 := range aRR.Answer {
@@ -207,11 +215,11 @@ func (dc *DNSClient) GetBPFromDNSSeed(BPDomain string) (BPNodes IDNodeMap, err e
ABIPv6R := dc.GetAAAARecord(target)
if ABIPv6R == nil {
err = errors.New("empty AAAA record")
- log.Errorf("get AAAA section of %s failed: %v", target, err)
+ log.WithField("target", target).WithError(err).Error("get AAAA section failed")
return
}
if err = dc.VerifySection(ABIPv6R.Answer); err != nil {
- log.Errorf("verify ab AAAA section of %s failed: %v", target, err)
+ log.WithError(err).WithError(err).Error("verify ab AAAA section failed")
return
}
for _, rr := range ABIPv6R.Answer {
@@ -225,12 +233,12 @@ func (dc *DNSClient) GetBPFromDNSSeed(BPDomain string) (BPNodes IDNodeMap, err e
CDIPv6R := dc.GetAAAARecord(target)
if CDIPv6R == nil {
err = errors.New("empty AAAA record")
- log.Errorf("get AAAA section of %s failed: %v", target, err)
+ log.WithField("target", target).WithError(err).Error("get AAAA section failed")
return
}
if err = dc.VerifySection(CDIPv6R.Answer); err != nil {
- log.Errorf("verify cd AAAA section of %s failed: %v", target, err)
+ log.WithField("target", target).WithError(err).Error("verify cd AAAA section failed")
return
}
for _, rr := range CDIPv6R.Answer {
@@ -243,7 +251,7 @@ func (dc *DNSClient) GetBPFromDNSSeed(BPDomain string) (BPNodes IDNodeMap, err e
var nonce *mine.Uint256
nonce, err = mine.FromIPv6(ab, cd)
if err != nil {
- log.Errorf("convert IPv6 addr to nonce failed: %v", err)
+ log.WithError(err).Error("convert IPv6 addr to nonce failed")
return
}
@@ -251,33 +259,33 @@ func (dc *DNSClient) GetBPFromDNSSeed(BPDomain string) (BPNodes IDNodeMap, err e
publicKeyTXTR := dc.GetTXTRecord(srv.Target)
if publicKeyTXTR == nil {
err = errors.New("empty TXT record")
- log.Errorf("get TXT section of %s failed: %v", srv.Target, err)
+ log.WithField("target", srv.Target).WithError(err).Error("get TXT section failed")
return
}
if err = dc.VerifySection(publicKeyTXTR.Answer); err != nil {
- log.Errorf("verify TXT section of %s failed: %v", srv.Target, err)
+ log.WithField("target", srv.Target).WithError(err).Error("verify TXT section failed")
return
}
for _, rr := range publicKeyTXTR.Answer {
if ss, ok := rr.(*dns.TXT); ok {
if len(ss.Txt) == 0 {
err = errors.New("empty TXT record")
- log.Errorf("%v for %s", err, srv.Target)
+ log.WithField("target", srv.Target).WithError(err).Error("got empty TXT record")
return
}
publicKeyStr := ss.Txt[0]
- log.Debugf("TXT Record: %s", publicKeyStr)
+ log.Debugf("TXT Record: %#v", publicKeyStr)
var pubKeyBytes []byte
// load public key string
pubKeyBytes, err = hex.DecodeString(publicKeyStr)
if err != nil {
- log.Errorf("decode TXT record to hex failed: %v", err)
+ log.WithError(err).Error("decode TXT record to hex failed")
return
}
err = publicKey.UnmarshalBinary(pubKeyBytes)
if err != nil {
- log.Errorf("unmarshal TXT record to public key failed: %v", err)
+ log.WithError(err).Error("unmarshal TXT record to public key failed")
return
}
@@ -306,7 +314,7 @@ func (dc *DNSClient) GetBPFromDNSSeed(BPDomain string) (BPNodes IDNodeMap, err e
func (dc *DNSClient) GetSRVRecords(name string) *dns.Msg {
in, err := dc.Query(name, dns.TypeSRV)
if err != nil {
- log.Errorf("SRV record query failed: %v", err)
+ log.WithField("name", name).WithError(err).Error("SRV record query failed")
return nil
}
return in
@@ -316,7 +324,7 @@ func (dc *DNSClient) GetSRVRecords(name string) *dns.Msg {
func (dc *DNSClient) GetARecord(name string) *dns.Msg {
in, err := dc.Query(name, dns.TypeA)
if err != nil {
- log.Errorf("A record query failed: %v", err)
+ log.WithField("name", name).WithError(err).Error("A record query failed")
return nil
}
return in
@@ -326,7 +334,7 @@ func (dc *DNSClient) GetARecord(name string) *dns.Msg {
func (dc *DNSClient) GetAAAARecord(name string) *dns.Msg {
in, err := dc.Query(name, dns.TypeAAAA)
if err != nil {
- log.Errorf("AAAA record query failed: %v", err)
+ log.WithField("name", name).WithError(err).Error("AAAA record query failed")
return nil
}
return in
@@ -336,7 +344,7 @@ func (dc *DNSClient) GetAAAARecord(name string) *dns.Msg {
func (dc *DNSClient) GetTXTRecord(name string) *dns.Msg {
in, err := dc.Query(name, dns.TypeTXT)
if err != nil {
- log.Errorf("TXT record query failed: %v", err)
+ log.WithField("name", name).WithError(err).Error("TXT record query failed")
return nil
}
return in
diff --git a/route/dns.go b/route/dns.go
index 53c9bde4e..e3647f968 100644
--- a/route/dns.go
+++ b/route/dns.go
@@ -135,7 +135,7 @@ func initBPNodeIDs() (bpNodeIDs NodeIDAddressMap) {
var err error
BPNodes, err = dc.GetBPFromDNSSeed(seedDomain)
if err != nil {
- log.Errorf("getting BP addr from DNS %s failed: %s", seedDomain, err)
+ log.WithField("seed", seedDomain).WithError(err).Error("getting BP addr from DNS failed")
return
}
}
@@ -192,7 +192,10 @@ func InitKMS(PubKeyStoreFile string) {
for _, n := range conf.GConf.KnownNodes {
rawNodeID := n.ID.ToRawNodeID()
- log.Debugf("set node addr: %v, %v", rawNodeID, n.Addr)
+ log.WithFields(log.Fields{
+ "node": rawNodeID.String(),
+ "addr": n.Addr,
+ }).Debug("set node addr")
SetNodeAddrCache(rawNodeID, n.Addr)
node := &proto.Node{
ID: n.ID,
@@ -201,15 +204,15 @@ func InitKMS(PubKeyStoreFile string) {
Nonce: n.Nonce,
Role: n.Role,
}
- log.Debugf("known node to set: %v", node)
+ log.WithField("node", node).Debug("known node to set")
err := kms.SetNode(node)
if err != nil {
- log.Errorf("set node failed: %v\n %s", node, err)
+ log.WithField("node", node).WithError(err).Error("set node failed")
}
if n.ID == conf.GConf.ThisNodeID {
kms.SetLocalNodeIDNonce(rawNodeID.CloneBytes(), &n.Nonce)
}
}
}
- log.Debugf("AllNodes:\n %v\n", conf.GConf.KnownNodes)
+ log.Debugf("AllNodes:\n %#v\n", conf.GConf.KnownNodes)
}
diff --git a/route/service.go b/route/service.go
index a234b57fc..ad7d34da7 100644
--- a/route/service.go
+++ b/route/service.go
@@ -43,12 +43,17 @@ func NewDHTServiceWithRing(c *consistent.Consistent) (s *DHTService, err error)
func NewDHTService(DHTStorePath string, persistImpl consistent.Persistence, initBP bool) (s *DHTService, err error) {
c, err := consistent.InitConsistent(DHTStorePath, persistImpl, initBP)
if err != nil {
- log.Errorf("init DHT service failed: %s", err)
+ log.WithError(err).Error("init DHT service failed")
return
}
return NewDHTServiceWithRing(c)
}
+// Nil RPC does nothing just for probe
+func (DHT *DHTService) Nil(req *proto.PingReq, resp *proto.PingResp) (err error) {
+ return
+}
+
// FindNode RPC returns node with requested node id from DHT
func (DHT *DHTService) FindNode(req *proto.FindNodeReq, resp *proto.FindNodeResp) (err error) {
if !IsPermitted(&req.Envelope, DHTFindNode) {
@@ -56,7 +61,7 @@ func (DHT *DHTService) FindNode(req *proto.FindNodeReq, resp *proto.FindNodeResp
log.Error(err)
return
}
- node, err := DHT.Consistent.GetNode(string(req.NodeID))
+ node, err := DHT.Consistent.GetNode(string(req.ID))
if err != nil {
err = fmt.Errorf("get node %s from DHT failed: %s", req.NodeID, err)
log.Error(err)
@@ -74,14 +79,17 @@ func (DHT *DHTService) FindNeighbor(req *proto.FindNeighborReq, resp *proto.Find
return
}
- nodes, err := DHT.Consistent.GetNeighborsEx(string(req.NodeID), req.Count, req.Roles)
+ nodes, err := DHT.Consistent.GetNeighborsEx(string(req.ID), req.Count, req.Roles)
if err != nil {
err = fmt.Errorf("get nodes from DHT failed: %s", err)
log.Error(err)
return
}
resp.Nodes = nodes
- log.Debugf("found %v nodes for find neighbor request %v", len(nodes), req)
+ log.WithFields(log.Fields{
+ "neighCount": len(nodes),
+ "req": req,
+ }).Debug("found nodes for find neighbor request")
return
}
diff --git a/route/service_test.go b/route/service_test.go
index 620c56e75..3125f5590 100644
--- a/route/service_test.go
+++ b/route/service_test.go
@@ -29,9 +29,9 @@ import (
"github.com/CovenantSQL/CovenantSQL/consistent"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
. "github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/utils"
"github.com/CovenantSQL/CovenantSQL/utils/log"
. "github.com/smartystreets/goconvey/convey"
- "github.com/ugorji/go/codec"
)
const DHTStorePath = "./DHTStore"
@@ -43,7 +43,7 @@ func TestDHTService_FindNeighbor_FindNode(t *testing.T) {
addr := "127.0.0.1:0"
dht, _ := NewDHTService(DHTStorePath+"1", new(consistent.KMSStorage), false)
kms.ResetBucket()
- rpc.RegisterName("DHT", dht)
+ rpc.RegisterName(DHTRPCName, dht)
ln, err := net.Listen("tcp", addr)
if err != nil {
fmt.Println(err)
@@ -65,8 +65,8 @@ func TestDHTService_FindNeighbor_FindNode(t *testing.T) {
}
req := &FindNeighborReq{
- NodeID: "123",
- Count: 2,
+ ID: "123",
+ Count: 2,
}
resp := new(FindNeighborResp)
err = client.Call("DHT.FindNeighbor", req, resp)
@@ -81,7 +81,7 @@ func TestDHTService_FindNeighbor_FindNode(t *testing.T) {
})
reqFN1 := &FindNodeReq{
- NodeID: "123",
+ ID: "123",
}
respFN1 := new(FindNodeResp)
err = client.Call("DHT.FindNode", reqFN1, respFN1)
@@ -110,7 +110,7 @@ func TestDHTService_FindNeighbor_FindNode(t *testing.T) {
log.Debugf("respA: %v", respA)
reqFN2 := &FindNodeReq{
- NodeID: node1.ID,
+ ID: node1.ID,
}
respFN2 := new(FindNodeResp)
err = client.Call("DHT.FindNode", reqFN2, respFN2)
@@ -140,8 +140,8 @@ func TestDHTService_FindNeighbor_FindNode(t *testing.T) {
log.Debugf("respA: %v", respB)
req = &FindNeighborReq{
- NodeID: "123",
- Count: 10,
+ ID: "123",
+ Count: 10,
}
resp = new(FindNeighborResp)
err = client.Call("DHT.FindNeighbor", req, resp)
@@ -160,9 +160,9 @@ func TestDHTService_FindNeighbor_FindNode(t *testing.T) {
})
req = &FindNeighborReq{
- NodeID: "123",
- Count: 10,
- Roles: ServerRoles{Miner},
+ ID: "123",
+ Count: 10,
+ Roles: ServerRoles{Miner},
}
resp = new(FindNeighborResp)
err = client.Call("DHT.FindNeighbor", req, resp)
@@ -181,7 +181,7 @@ func TestDHTService_FindNeighbor_FindNode(t *testing.T) {
})
reqFN3 := &FindNodeReq{
- NodeID: node2.ID,
+ ID: node2.ID,
}
respFN3 := new(FindNodeResp)
err = client.Call("DHT.FindNode", reqFN3, respFN3)
@@ -207,13 +207,12 @@ func TestDHTService_Ping(t *testing.T) {
addr := "127.0.0.1:0"
dht, _ := NewDHTService(DHTStorePath, new(consistent.KMSStorage), false)
- rpc.RegisterName("DHT", dht)
+ rpc.RegisterName(DHTRPCName, dht)
ln, err := net.Listen("tcp", addr)
if err != nil {
fmt.Println(err)
return
}
- mh := &codec.MsgpackHandle{}
go func() {
for {
@@ -221,8 +220,7 @@ func TestDHTService_Ping(t *testing.T) {
if err != nil {
continue
}
- msgpackCodec := codec.MsgpackSpecRpc.ServerCodec(c, mh)
- go rpc.ServeCodec(msgpackCodec)
+ go rpc.ServeCodec(utils.GetMsgPackServerCodec(c))
}
}()
@@ -239,8 +237,7 @@ func TestDHTService_Ping(t *testing.T) {
Node: *node1,
}
respA := new(PingResp)
- msgpackCodec := codec.MsgpackSpecRpc.ClientCodec(client, mh)
- rc := rpc.NewClientWithCodec(msgpackCodec)
+ rc := rpc.NewClientWithCodec(utils.GetMsgPackClientCodec(client))
err = rc.Call("DHT.Ping", reqA, respA)
if err != nil {
t.Error(err)
@@ -251,8 +248,7 @@ func TestDHTService_Ping(t *testing.T) {
respA3 := new(PingResp)
conf.GConf.MinNodeIDDifficulty = 256
client, _ = net.Dial("tcp", ln.Addr().String())
- msgpackCodec = codec.MsgpackSpecRpc.ClientCodec(client, mh)
- rc = rpc.NewClientWithCodec(msgpackCodec)
+ rc = rpc.NewClientWithCodec(utils.GetMsgPackClientCodec(client))
err = rc.Call("DHT.Ping", reqA, respA3)
if err == nil || !strings.Contains(err.Error(), "difficulty too low") {
t.Error(err)
@@ -263,8 +259,7 @@ func TestDHTService_Ping(t *testing.T) {
respA2 := new(PingResp)
reqA.Node.Nonce.A = ^uint64(0)
client, _ = net.Dial("tcp", ln.Addr().String())
- msgpackCodec = codec.MsgpackSpecRpc.ClientCodec(client, mh)
- rc = rpc.NewClientWithCodec(msgpackCodec)
+ rc = rpc.NewClientWithCodec(utils.GetMsgPackClientCodec(client))
err = rc.Call("DHT.Ping", reqA, respA2)
if err == nil || !strings.Contains(err.Error(), "nonce public key not match") {
t.Error(err)
diff --git a/rpc/README.md b/rpc/README.md
index 4aafc248d..a68aa9b1a 100644
--- a/rpc/README.md
+++ b/rpc/README.md
@@ -21,7 +21,7 @@ CovenantSQL is built on DH-RPC, including:
## Usage
-
+
Alice Client:
@@ -164,7 +164,7 @@ func main() {
}
// Register DHT service
- server, err := rpc.NewServerWithService(rpc.ServiceMap{"DHT": dht})
+ server, err := rpc.NewServerWithService(rpc.ServiceMap{route.DHTRPCName: dht})
if err != nil {
log.Fatal(err)
}
diff --git a/rpc/_example/tracker/main.go b/rpc/_example/tracker/main.go
index 1b00d67d7..706d35afa 100644
--- a/rpc/_example/tracker/main.go
+++ b/rpc/_example/tracker/main.go
@@ -25,7 +25,7 @@ func main() {
}
// Register DHT service
- server, err := rpc.NewServerWithService(rpc.ServiceMap{"DHT": dht})
+ server, err := rpc.NewServerWithService(rpc.ServiceMap{route.DHTRPCName: dht})
if err != nil {
log.Fatal(err)
}
diff --git a/rpc/client.go b/rpc/client.go
index b918e1b5e..0600d8dac 100644
--- a/rpc/client.go
+++ b/rpc/client.go
@@ -21,15 +21,13 @@ import (
"net"
"net/rpc"
- "io/ioutil"
-
"github.com/CovenantSQL/CovenantSQL/crypto/etls"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
"github.com/CovenantSQL/CovenantSQL/pow/cpuminer"
"github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/utils"
"github.com/CovenantSQL/CovenantSQL/utils/log"
- "github.com/hashicorp/yamux"
- "github.com/ugorji/go/codec"
+ mux "github.com/xtaci/smux"
)
// Client is RPC client
@@ -41,14 +39,13 @@ type Client struct {
var (
// YamuxConfig holds the default Yamux config
- YamuxConfig *yamux.Config
+ YamuxConfig *mux.Config
// DefaultDialer holds the default dialer of SessionPool
DefaultDialer func(nodeID proto.NodeID) (conn net.Conn, err error)
)
func init() {
- YamuxConfig = yamux.DefaultConfig()
- YamuxConfig.LogOutput = ioutil.Discard
+ YamuxConfig = mux.DefaultConfig()
DefaultDialer = dialToNode
}
@@ -57,7 +54,7 @@ func init() {
func dial(network, address string, remoteNodeID *proto.RawNodeID, cipher *etls.Cipher, isAnonymous bool) (c *etls.CryptoConn, err error) {
conn, err := net.Dial(network, address)
if err != nil {
- log.Errorf("connect to %s failed: %s", address, err)
+ log.WithField("addr", address).WithError(err).Error("connect to node failed")
return
}
var writeBuf []byte
@@ -69,19 +66,19 @@ func dial(network, address string, remoteNodeID *proto.RawNodeID, cipher *etls.C
var nonce *cpuminer.Uint256
nodeIDBytes, err = kms.GetLocalNodeIDBytes()
if err != nil {
- log.Errorf("get local node id failed: %s", err)
+ log.WithError(err).Error("get local node id failed")
return
}
nonce, err = kms.GetLocalNonce()
if err != nil {
- log.Errorf("get local nonce failed: %s", err)
+ log.WithError(err).Error("get local nonce failed")
return
}
writeBuf = append(nodeIDBytes, nonce.Bytes()...)
}
wrote, err := conn.Write(writeBuf)
if err != nil || wrote != len(writeBuf) {
- log.Errorf("write node id and nonce failed: %s", err)
+ log.WithError(err).Error("write node id and nonce failed")
return
}
@@ -93,24 +90,24 @@ func dial(network, address string, remoteNodeID *proto.RawNodeID, cipher *etls.C
func DialToNode(nodeID proto.NodeID, pool *SessionPool, isAnonymous bool) (conn net.Conn, err error) {
if pool == nil || isAnonymous {
var ETLSConn net.Conn
- var sess *yamux.Session
+ var sess *mux.Session
ETLSConn, err = dialToNodeEx(nodeID, isAnonymous)
if err != nil {
- log.Errorf("dialToNode failed: %s", err)
+ log.WithField("target", nodeID).WithError(err).Error("dialToNode failed")
return
}
- sess, err = yamux.Client(ETLSConn, YamuxConfig)
+ sess, err = mux.Client(ETLSConn, YamuxConfig)
if err != nil {
- log.Errorf("init yamux client failed: %s", err)
+ log.WithField("target", nodeID).WithError(err).Error("init yamux client failed")
return
}
- conn, err = sess.Open()
+ conn, err = sess.OpenStream()
if err != nil {
- log.Errorf("open new session failed: %s", err)
+ log.WithField("target", nodeID).WithError(err).Error("open new session failed")
}
return
}
- log.Debugf("session pool len: %d", pool.Len())
+ log.WithField("poolSize", pool.Len()).Debug("session pool size")
conn, err = pool.Get(nodeID)
return
}
@@ -140,20 +137,23 @@ func dialToNodeEx(nodeID proto.NodeID, isAnonymous bool) (conn net.Conn, err err
*/
symmetricKey, err := GetSharedSecretWith(rawNodeID, isAnonymous)
if err != nil {
- log.Errorf("get shared secret for %s failed: %s", rawNodeID.ToNodeID(), err)
+ log.WithField("target", rawNodeID.String()).WithError(err).Error("get shared secret failed")
return
}
nodeAddr, err := GetNodeAddr(rawNodeID)
if err != nil {
- log.Errorf("resolve node %x failed, err: %s", *rawNodeID, err)
+ log.WithField("target", rawNodeID.String()).WithError(err).Error("resolve node failed")
return
}
cipher := etls.NewCipher(symmetricKey)
conn, err = dial("tcp", nodeAddr, rawNodeID, cipher, isAnonymous)
if err != nil {
- log.Errorf("connect to %s: %s", nodeAddr, err)
+ log.WithFields(log.Fields{
+ "target": rawNodeID.String(),
+ "addr": nodeAddr,
+ }).WithError(err).Error("connect failed")
return
}
@@ -177,29 +177,24 @@ func initClient(addr string) (client *Client, err error) {
// InitClientConn initializes client with connection to given addr
func InitClientConn(conn net.Conn) (client *Client, err error) {
client = NewClient()
- var muxConn *yamux.Stream
- muxConn, ok := conn.(*yamux.Stream)
+ var muxConn *mux.Stream
+ muxConn, ok := conn.(*mux.Stream)
if !ok {
- var sess *yamux.Session
- sess, err = yamux.Client(conn, YamuxConfig)
+ var sess *mux.Session
+ sess, err = mux.Client(conn, YamuxConfig)
if err != nil {
- log.Errorf("init yamux client failed: %v", err)
+ log.WithError(err).Error("init yamux client failed")
return
}
muxConn, err = sess.OpenStream()
if err != nil {
- log.Errorf("open stream failed: %v", err)
+ log.WithError(err).Error("open stream failed")
return
}
}
client.Conn = muxConn
- mh := &codec.MsgpackHandle{
- WriteExt: true,
- RawToString: true,
- }
- msgpackCodec := codec.MsgpackSpecRpc.ClientCodec(muxConn, mh)
- client.Client = rpc.NewClientWithCodec(msgpackCodec)
+ client.Client = rpc.NewClientWithCodec(utils.GetMsgPackClientCodec(muxConn))
client.RemoteAddr = conn.RemoteAddr().String()
return client, nil
@@ -207,6 +202,6 @@ func InitClientConn(conn net.Conn) (client *Client, err error) {
// Close the client RPC connection
func (c *Client) Close() {
- log.Debugf("closing %s", c.RemoteAddr)
+ log.WithField("addr", c.RemoteAddr).Debug("closing client")
c.Client.Close()
}
diff --git a/rpc/leak_test.go b/rpc/leak_test.go
index 73a26ccb4..d90f4fe83 100644
--- a/rpc/leak_test.go
+++ b/rpc/leak_test.go
@@ -97,7 +97,7 @@ func TestSessionPool_SessionBroken(t *testing.T) {
reqType = "FindNode"
reqFN := &proto.FindNodeReq{
- NodeID: thisClient.ID,
+ ID: thisClient.ID,
}
respFN := new(proto.FindNodeResp)
err = caller.CallNode(leaderNodeID, "DHT."+reqType, reqFN, respFN)
@@ -113,7 +113,7 @@ func TestSessionPool_SessionBroken(t *testing.T) {
reqType = "FindNode"
reqFN = &proto.FindNodeReq{
- NodeID: thisClient.ID,
+ ID: thisClient.ID,
}
respFN = new(proto.FindNodeResp)
err = caller.CallNode(leaderNodeID, "DHT."+reqType, reqFN, respFN)
diff --git a/rpc/pool.go b/rpc/pool.go
index 9193ff3f2..ae45102c0 100644
--- a/rpc/pool.go
+++ b/rpc/pool.go
@@ -22,7 +22,7 @@ import (
"github.com/CovenantSQL/CovenantSQL/proto"
"github.com/CovenantSQL/CovenantSQL/utils/log"
- "github.com/hashicorp/yamux"
+ mux "github.com/xtaci/smux"
)
// SessPool is the session pool interface
@@ -43,7 +43,8 @@ type SessionMap map[proto.NodeID]*Session
// Session is the Session type of SessionPool
type Session struct {
ID proto.NodeID
- Sess *yamux.Session
+ Sess *mux.Session
+ conn net.Conn
}
// SessionPool is the struct type of session pool
@@ -79,10 +80,10 @@ func GetSessionPoolInstance() *SessionPool {
return instance
}
-// toSession wraps net.Conn to yamux.Session
+// toSession wraps net.Conn to mux.Session
func toSession(id proto.NodeID, conn net.Conn) (sess *Session, err error) {
- // create yamux session
- newSess, err := yamux.Client(conn, YamuxConfig)
+ // create mux session
+ newSess, err := mux.Client(conn, YamuxConfig)
if err != nil {
//log.Errorf("dial to new node %s failed: %s", id, err) // no log in lock
return
@@ -91,6 +92,7 @@ func toSession(id proto.NodeID, conn net.Conn) (sess *Session, err error) {
sess = &Session{
ID: id,
Sess: newSess,
+ conn: conn,
}
return
}
@@ -103,7 +105,7 @@ func (p *SessionPool) LoadOrStore(id proto.NodeID, newSess *Session) (sess *Sess
defer p.Unlock()
sess, exist := p.sessions[id]
if exist {
- log.Debugf("load session for %s", id)
+ log.WithField("node", id).Debug("load session for target node")
loaded = true
} else {
sess = newSess
@@ -124,33 +126,33 @@ func (p *SessionPool) Get(id proto.NodeID) (conn net.Conn, err error) {
// first try to get one session from pool
cachedConn, ok := p.getSessionFromPool(id)
if ok {
- conn, err = cachedConn.Sess.Open()
+ conn, err = cachedConn.Sess.OpenStream()
if err == nil {
- log.Debugf("reusing session to %s", id)
+ log.WithField("node", id).Debug("reusing session")
return
}
- log.Errorf("open session to %s from pool failed: %v", id, err)
+ log.WithField("target", id).WithError(err).Error("open session failed")
p.Remove(id)
}
- log.Debugf("dial new session to %s", id)
+ log.WithField("target", id).Debug("dialing new session")
// Can't find existing Session, try to dial one
newConn, err := p.nodeDialer(id)
if err != nil {
- log.Errorf("dial new session to node %s failed: %v", id, err)
+ log.WithField("node", id).WithError(err).Error("dial new session failed")
return
}
newSess, err := toSession(id, newConn)
if err != nil {
newConn.Close()
- log.Errorf("dial new session to node %s failed: %v", id, err)
+ log.WithField("node", id).WithError(err).Error("dial new session failed")
return
}
sess, loaded := p.LoadOrStore(id, newSess)
if loaded {
newSess.Close()
}
- return sess.Sess.Open()
+ return sess.Sess.OpenStream()
}
// Set tries to set a new connection to the pool, typically from Accept()
diff --git a/rpc/pool_test.go b/rpc/pool_test.go
index 69abbcdfa..6e003e901 100644
--- a/rpc/pool_test.go
+++ b/rpc/pool_test.go
@@ -25,8 +25,8 @@ import (
"github.com/CovenantSQL/CovenantSQL/proto"
"github.com/CovenantSQL/CovenantSQL/utils"
"github.com/CovenantSQL/CovenantSQL/utils/log"
- "github.com/hashicorp/yamux"
. "github.com/smartystreets/goconvey/convey"
+ mux "github.com/xtaci/smux"
)
const (
@@ -53,9 +53,9 @@ func server(c C, localAddr string, wg *sync.WaitGroup, p *SessionPool, n int) er
conn, err := listener.Accept()
c.So(err, ShouldBeNil)
- // Setup server side of yamux
+ // Setup server side of mux
log.Println("creating server session")
- session, err := yamux.Server(conn, nil)
+ session, err := mux.Server(conn, nil)
c.So(err, ShouldBeNil)
for i := 0; i < concurrency; i++ {
@@ -68,7 +68,7 @@ func server(c C, localAddr string, wg *sync.WaitGroup, p *SessionPool, n int) er
//c2.So(string(buf1), ShouldEqual, "ping")
defer wg.Done()
log.Println("accepting stream")
- stream, err := session.Accept()
+ stream, err := session.AcceptStream()
if err == nil {
buf1 := make([]byte, 4)
for i := 0; i < n; i++ {
diff --git a/rpc/rpcutil.go b/rpc/rpcutil.go
index 5b9033496..cf971c554 100644
--- a/rpc/rpcutil.go
+++ b/rpc/rpcutil.go
@@ -29,7 +29,7 @@ import (
"github.com/CovenantSQL/CovenantSQL/proto"
"github.com/CovenantSQL/CovenantSQL/route"
"github.com/CovenantSQL/CovenantSQL/utils/log"
- "github.com/hashicorp/yamux"
+ mux "github.com/xtaci/smux"
)
var (
@@ -68,13 +68,13 @@ func (c *PersistentCaller) initClient(method string) (err error) {
var conn net.Conn
conn, err = DialToNode(c.TargetID, c.pool, method == route.DHTPing.String())
if err != nil {
- log.Errorf("dialing to node: %s failed: %s", c.TargetID, err)
+ log.WithField("target", c.TargetID).WithError(err).Error("dial to node failed")
return
}
//conn.SetDeadline(time.Time{})
c.client, err = InitClientConn(conn)
if err != nil {
- log.Errorf("init RPC client failed: %s", err)
+ log.WithError(err).Error("init RPC client failed")
return
}
}
@@ -83,7 +83,11 @@ func (c *PersistentCaller) initClient(method string) (err error) {
// Call invokes the named function, waits for it to complete, and returns its error status.
func (c *PersistentCaller) Call(method string, args interface{}, reply interface{}) (err error) {
- c.initClient(method)
+ err = c.initClient(method)
+ if err != nil {
+ log.WithError(err).Error("init PersistentCaller client failed")
+ return
+ }
err = c.client.Call(method, args, reply)
if err != nil {
if err == io.EOF || err == io.ErrUnexpectedEOF {
@@ -92,26 +96,39 @@ func (c *PersistentCaller) Call(method string, args interface{}, reply interface
c.Close()
c.client = nil
c.Unlock()
- c.initClient(method)
+ err = c.initClient(method)
+ if err != nil {
+ log.WithField("rpc", method).WithError(err).Error("second init client for RPC failed")
+ return
+ }
err = c.client.Call(method, args, reply)
if err != nil {
- log.Errorf("second time call RPC %s failed: %v", method, err)
+ log.WithField("rpc", method).WithError(err).Error("second time call RPC failed")
return
}
}
- log.Errorf("call RPC %s failed: %v", method, err)
+ log.WithField("rpc", method).WithError(err).Error("call RPC failed")
}
return
}
// Close closes the stream and RPC client
-func (c *PersistentCaller) Close() {
- stream, ok := c.client.Conn.(*yamux.Stream)
- if ok {
- stream.Close()
+func (c *PersistentCaller) CloseStream() {
+ if c.client != nil {
+ if c.client.Conn != nil {
+ stream, ok := c.client.Conn.(*mux.Stream)
+ if ok {
+ stream.Close()
+ }
+ }
+ c.client.Close()
}
- c.client.Close()
- c.pool.Remove(c.TargetID)
+}
+
+// Close closes the stream and RPC client
+func (c *PersistentCaller) Close() {
+ c.CloseStream()
+ //c.pool.Remove(c.TargetID)
}
// Caller is a wrapper for session pooling and RPC calling.
@@ -137,14 +154,14 @@ func (c *Caller) CallNodeWithContext(
ctx context.Context, node proto.NodeID, method string, args interface{}, reply interface{}) (err error) {
conn, err := DialToNode(node, c.pool, method == route.DHTPing.String())
if err != nil {
- log.Errorf("dialing to node: %s failed: %s", node, err)
+ log.WithField("node", node).WithError(err).Error("dial to node failed")
return
}
defer func() {
- // call the yamux stream Close explicitly
+ // call the mux stream Close explicitly
//TODO(auxten) maybe a rpc client pool will gain much more performance
- stream, ok := conn.(*yamux.Stream)
+ stream, ok := conn.(*mux.Stream)
if ok {
stream.Close()
}
@@ -152,7 +169,7 @@ func (c *Caller) CallNodeWithContext(
client, err := InitClientConn(conn)
if err != nil {
- log.Errorf("init RPC client failed: %s", err)
+ log.WithError(err).Error("init RPC client failed")
return
}
@@ -175,16 +192,16 @@ func (c *Caller) CallNodeWithContext(
func GetNodeAddr(id *proto.RawNodeID) (addr string, err error) {
addr, err = route.GetNodeAddrCache(id)
if err != nil {
- log.Infof("get node %s addr failed: %s", id, err)
+ log.WithField("target", id.String()).WithError(err).Info("get node addr from cache failed")
if err == route.ErrUnknownNodeID {
BPs := route.GetBPs()
if len(BPs) == 0 {
- log.Errorf("no available BP")
+ log.Error("no available BP")
return
}
client := NewCaller()
reqFN := &proto.FindNodeReq{
- NodeID: proto.NodeID(id.String()),
+ ID: proto.NodeID(id.String()),
}
respFN := new(proto.FindNodeResp)
@@ -192,7 +209,10 @@ func GetNodeAddr(id *proto.RawNodeID) (addr string, err error) {
method := "DHT.FindNode"
err = client.CallNode(bp, method, reqFN, respFN)
if err != nil {
- log.Errorf("call %s %s failed: %s", bp, method, err)
+ log.WithFields(log.Fields{
+ "bpNode": bp,
+ "rpc": method,
+ }).WithError(err).Error("call dht rpc failed")
return
}
route.SetNodeAddrCache(id, respFN.Node.Addr)
@@ -206,33 +226,36 @@ func GetNodeAddr(id *proto.RawNodeID) (addr string, err error) {
func GetNodeInfo(id *proto.RawNodeID) (nodeInfo *proto.Node, err error) {
nodeInfo, err = kms.GetNodeInfo(proto.NodeID(id.String()))
if err != nil {
- log.Infof("get node info from KMS for %s failed: %s", id, err)
+ log.WithField("target", id.String()).WithError(err).Info("get node info from KMS failed")
if err == kms.ErrKeyNotFound {
BPs := route.GetBPs()
if len(BPs) == 0 {
- log.Errorf("no available BP")
+ log.Error("no available BP")
return
}
client := NewCaller()
reqFN := &proto.FindNodeReq{
- NodeID: proto.NodeID(id.String()),
+ ID: proto.NodeID(id.String()),
}
respFN := new(proto.FindNodeResp)
bp := BPs[rand.Intn(len(BPs))]
method := "DHT.FindNode"
err = client.CallNode(bp, method, reqFN, respFN)
if err != nil {
- log.Errorf("call %s %s failed: %s", bp, method, err)
+ log.WithFields(log.Fields{
+ "bpNode": bp,
+ "rpc": method,
+ }).WithError(err).Error("call dht rpc failed")
return
}
nodeInfo = respFN.Node
errSet := route.SetNodeAddrCache(id, nodeInfo.Addr)
if errSet != nil {
- log.Warnf("set node addr cache failed: %v", errSet)
+ log.WithError(errSet).Warning("set node addr cache failed")
}
errSet = kms.SetNode(nodeInfo)
if errSet != nil {
- log.Warnf("set node to kms failed: %v", errSet)
+ log.WithError(errSet).Warning("set node to kms failed")
}
}
}
@@ -250,10 +273,10 @@ func PingBP(node *proto.Node, BPNodeID proto.NodeID) (err error) {
resp := new(proto.PingResp)
err = client.CallNode(BPNodeID, "DHT.Ping", req, resp)
if err != nil {
- log.Errorf("call DHT.Ping failed: %v", err)
+ log.WithError(err).Error("call DHT.Ping failed")
return
}
- log.Debugf("PingBP resp: %v", resp)
+ log.Debugf("PingBP resp: %#v", resp)
return
}
@@ -285,7 +308,7 @@ func GetCurrentBP() (bpNodeID proto.NodeID, err error) {
// call random block producer for nearest block producer node
req := &proto.FindNeighborReq{
- NodeID: localNodeID,
+ ID: localNodeID,
Roles: []proto.ServerRole{
proto.Leader,
// only leader is capable of allocating database in current implementation
diff --git a/rpc/rpcutil_test.go b/rpc/rpcutil_test.go
index e10da5c6d..c3442336c 100644
--- a/rpc/rpcutil_test.go
+++ b/rpc/rpcutil_test.go
@@ -21,12 +21,11 @@ import (
"os"
"path/filepath"
"runtime"
+ "strings"
"sync"
"testing"
"time"
- "strings"
-
"github.com/CovenantSQL/CovenantSQL/conf"
"github.com/CovenantSQL/CovenantSQL/consistent"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
@@ -40,7 +39,7 @@ import (
const (
DHTStorePath = "./DHTStore"
RPCConcurrent = 10
- RPCCount = 10
+ RPCCount = 100
)
func TestCaller_CallNode(t *testing.T) {
@@ -64,7 +63,7 @@ func TestCaller_CallNode(t *testing.T) {
masterKey := []byte("")
dht, err := route.NewDHTService(PubKeyStorePath, new(consistent.KMSStorage), true)
- server, err := NewServerWithService(ServiceMap{"DHT": dht})
+ server, err := NewServerWithService(ServiceMap{route.DHTRPCName: dht})
if err != nil {
t.Fatal(err)
}
@@ -90,7 +89,7 @@ func TestCaller_CallNode(t *testing.T) {
}
respA := new(proto.PingResp)
- err = client.CallNode(conf.GConf.BP.NodeID, "DHT.Ping", reqA, respA)
+ err = client.CallNode(conf.GConf.BP.NodeID, route.DHTPing.String(), reqA, respA)
if err != nil {
t.Fatal(err)
}
@@ -160,6 +159,7 @@ func TestCaller_CallNode(t *testing.T) {
}
server.Stop()
+ client.pool.Close()
}
func TestNewPersistentCaller(t *testing.T) {
@@ -169,18 +169,8 @@ func TestNewPersistentCaller(t *testing.T) {
os.Remove(publicKeyStore)
defer os.Remove(publicKeyStore)
- ctx, cancel := context.WithTimeout(context.Background(), time.Second*15)
- defer cancel()
- err := utils.WaitForPorts(ctx, "127.0.0.1", []int{
- 2230,
- }, time.Millisecond*200)
-
- if err != nil {
- log.Fatalf("wait for port ready timeout: %v", err)
- }
-
_, testFile, _, _ := runtime.Caller(0)
- confFile := filepath.Join(filepath.Dir(testFile), "../test/node_standalone/config.yaml")
+ confFile := filepath.Join(filepath.Dir(testFile), "../test/node_standalone/config2.yaml")
privateKeyPath := filepath.Join(filepath.Dir(testFile), "../test/node_standalone/private.key")
conf.GConf, _ = conf.LoadConfig(confFile)
@@ -193,12 +183,25 @@ func TestNewPersistentCaller(t *testing.T) {
masterKey := []byte("")
dht, err := route.NewDHTService(PubKeyStorePath, new(consistent.KMSStorage), true)
- server, err := NewServerWithService(ServiceMap{"DHT": dht})
+ server, err := NewServerWithService(ServiceMap{route.DHTRPCName: dht})
if err != nil {
t.Fatal(err)
}
- server.InitRPCServer(addr, privateKeyPath, masterKey)
+ ctx, cancel := context.WithTimeout(context.Background(), time.Second*15)
+ defer cancel()
+ err = utils.WaitForPorts(ctx, "127.0.0.1", []int{
+ 12230,
+ }, time.Millisecond*200)
+
+ if err != nil {
+ log.Fatalf("wait for port ready timeout: %v", err)
+ }
+
+ err = server.InitRPCServer(addr, privateKeyPath, masterKey)
+ if err != nil {
+ t.Fatal(err)
+ }
go server.Serve()
client := NewPersistentCaller(conf.GConf.BP.NodeID)
@@ -218,8 +221,8 @@ func TestNewPersistentCaller(t *testing.T) {
log.Debugf("respA: %v", respA)
req := &proto.FindNeighborReq{
- NodeID: "1234",
- Count: 10,
+ ID: "1234567812345678123456781234567812345678123456781234567812345678",
+ Count: 10,
}
resp := new(proto.FindNeighborResp)
@@ -234,13 +237,13 @@ func TestNewPersistentCaller(t *testing.T) {
wg := sync.WaitGroup{}
client = NewPersistentCaller(conf.GConf.BP.NodeID)
+ wg.Add(RPCConcurrent * RPCCount)
for i := 0; i < RPCConcurrent; i++ {
- wg.Add(1)
go func(tt *testing.T, wg *sync.WaitGroup) {
for j := 0; j < RPCCount; j++ {
reqF := &proto.FindNeighborReq{
- NodeID: "1234",
- Count: 10,
+ ID: "1234567812345678123456781234567812345678123456781234567812345678",
+ Count: 10,
}
respF := new(proto.FindNeighborResp)
err := client.Call("DHT.FindNeighbor", reqF, respF)
@@ -248,13 +251,38 @@ func TestNewPersistentCaller(t *testing.T) {
tt.Error(err)
}
log.Debugf("resp: %v", respF)
+ wg.Done()
}
- wg.Done()
}(t, &wg)
}
+ client2 := NewPersistentCaller(conf.GConf.BP.NodeID)
+ reqF2 := &proto.FindNeighborReq{
+ ID: "1234567812345678123456781234567812345678123456781234567812345678",
+ Count: 10,
+ }
+ respF2 := new(proto.FindNeighborResp)
+
+ err = client2.Call("DHT.FindNeighbor", reqF2, respF2)
+ if err != nil {
+ t.Error(err)
+ }
+ client2.CloseStream()
+
wg.Wait()
- server.Stop()
+ sess, ok := client2.pool.getSessionFromPool(conf.GConf.BP.NodeID)
+ if !ok {
+ t.Fatalf("can not find session for %s", conf.GConf.BP.NodeID)
+ }
+ sess.conn.Close()
+
+ client3 := NewPersistentCaller(conf.GConf.BP.NodeID)
+ err = client3.Call("DHT.FindNeighbor", reqF2, respF2)
+ if err != nil {
+ t.Error(err)
+ }
+ client3.CloseStream()
+
}
func BenchmarkPersistentCaller_Call(b *testing.B) {
@@ -288,7 +316,7 @@ func BenchmarkPersistentCaller_Call(b *testing.B) {
masterKey := []byte("")
dht, err := route.NewDHTService(PubKeyStorePath, new(consistent.KMSStorage), true)
- server, err := NewServerWithService(ServiceMap{"DHT": dht})
+ server, err := NewServerWithService(ServiceMap{route.DHTRPCName: dht})
if err != nil {
b.Fatal(err)
}
@@ -312,14 +340,30 @@ func BenchmarkPersistentCaller_Call(b *testing.B) {
}
log.Debugf("respA: %v", respA)
+ client = NewPersistentCaller(conf.GConf.BP.NodeID)
+ b.Run("benchmark Persistent Call Nil", func(b *testing.B) {
+ var (
+ req proto.PingReq
+ resp proto.PingResp
+ )
+
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ err = client.Call("DHT.Nil", &req, &resp)
+ if err != nil {
+ b.Error(err)
+ }
+ }
+ })
+
req := &proto.FindNeighborReq{
- NodeID: "1234",
- Count: 10,
+ ID: "1234567812345678123456781234567812345678123456781234567812345678",
+ Count: 10,
}
resp := new(proto.FindNeighborResp)
- b.Run("benchmark Persistent", func(b *testing.B) {
- client = NewPersistentCaller(conf.GConf.BP.NodeID)
+ client = NewPersistentCaller(conf.GConf.BP.NodeID)
+ b.Run("benchmark Persistent Call", func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
err = client.Call("DHT.FindNeighbor", req, resp)
@@ -329,6 +373,32 @@ func BenchmarkPersistentCaller_Call(b *testing.B) {
}
})
+ routineCount := runtime.NumGoroutine()
+ if routineCount > 100 {
+ b.Errorf("go routine count: %d", routineCount)
+ } else {
+ log.Infof("go routine count: %d", routineCount)
+ }
+
+ b.Run("benchmark Persistent New and Call", func(b *testing.B) {
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ client = NewPersistentCaller(conf.GConf.BP.NodeID)
+ err = client.Call("DHT.FindNeighbor", req, resp)
+ if err != nil {
+ b.Error(err)
+ }
+ client.Close()
+ }
+ })
+
+ routineCount = runtime.NumGoroutine()
+ if routineCount > 100 {
+ b.Errorf("go routine count: %d", routineCount)
+ } else {
+ log.Infof("go routine count: %d", routineCount)
+ }
+
b.Run("benchmark non-Persistent", func(b *testing.B) {
oldClient := NewCaller()
b.ResetTimer()
@@ -339,5 +409,13 @@ func BenchmarkPersistentCaller_Call(b *testing.B) {
}
}
})
+
+ routineCount = runtime.NumGoroutine()
+ if routineCount > 100 {
+ b.Errorf("go routine count: %d", routineCount)
+ } else {
+ log.Infof("go routine count: %d", routineCount)
+ }
+
server.Stop()
}
diff --git a/rpc/server.go b/rpc/server.go
index 321d9169c..159ad76a0 100644
--- a/rpc/server.go
+++ b/rpc/server.go
@@ -26,9 +26,9 @@ import (
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
"github.com/CovenantSQL/CovenantSQL/pow/cpuminer"
"github.com/CovenantSQL/CovenantSQL/proto"
+ "github.com/CovenantSQL/CovenantSQL/utils"
"github.com/CovenantSQL/CovenantSQL/utils/log"
- "github.com/hashicorp/yamux"
- "github.com/ugorji/go/codec"
+ mux "github.com/xtaci/smux"
)
// ServiceMap maps service name to service instance
@@ -63,13 +63,13 @@ func (s *Server) InitRPCServer(
err = kms.InitLocalKeyPair(privateKeyPath, masterKey)
if err != nil {
- log.Errorf("init local key pair failed: %s", err)
+ log.WithError(err).Error("init local key pair failed")
return
}
l, err := etls.NewCryptoListener("tcp", addr, handleCipher)
if err != nil {
- log.Errorf("create crypto listener failed: %s", err)
+ log.WithError(err).Error("create crypto listener failed")
return
}
@@ -80,7 +80,6 @@ func (s *Server) InitRPCServer(
// NewServerWithService also return a new Server, and also register the Server.ServiceMap
func NewServerWithService(serviceMap ServiceMap) (server *Server, err error) {
-
server = NewServer()
for k, v := range serviceMap {
err = server.RegisterService(k, v)
@@ -108,7 +107,6 @@ serverLoop:
default:
conn, err := s.Listener.Accept()
if err != nil {
- log.Info(err)
continue
}
go s.handleConn(conn)
@@ -128,7 +126,7 @@ func (s *Server) handleConn(conn net.Conn) {
remoteNodeID = c.NodeID
}
- sess, err := yamux.Server(conn, YamuxConfig)
+ sess, err := mux.Server(conn, YamuxConfig)
if err != nil {
log.Error(err)
return
@@ -145,23 +143,16 @@ sessionLoop:
muxConn, err := sess.AcceptStream()
if err != nil {
if err == io.EOF {
- log.Infof("session %s connection closed", remoteNodeID)
+ log.WithField("remote", remoteNodeID).Debug("session connection closed")
} else {
- log.Errorf("session %s accept failed: %s", remoteNodeID, err)
+ log.WithField("remote", remoteNodeID).WithError(err).Error("session accept failed")
}
break sessionLoop
}
- log.Debugf("session accepted %d for %v", muxConn.StreamID(), remoteNodeID)
- msgpackCodec := codec.MsgpackSpecRpc.ServerCodec(muxConn, &codec.MsgpackHandle{
- WriteExt: true,
- RawToString: true,
- })
- nodeAwareCodec := NewNodeAwareServerCodec(msgpackCodec, remoteNodeID)
+ nodeAwareCodec := NewNodeAwareServerCodec(utils.GetMsgPackServerCodec(muxConn), remoteNodeID)
go s.rpcServer.ServeCodec(nodeAwareCodec)
}
}
-
- log.Debugf("Server.handleConn finished for %s %s", remoteNodeID, conn.RemoteAddr())
}
// RegisterService with a Service name, used by Client RPC
@@ -182,7 +173,7 @@ func handleCipher(conn net.Conn) (cryptoConn *etls.CryptoConn, err error) {
headerBuf := make([]byte, hash.HashBSize+32)
rCount, err := conn.Read(headerBuf)
if err != nil || rCount != hash.HashBSize+32 {
- log.Errorf("read node header error: %s", err)
+ log.WithError(err).Error("read node header error")
return
}
@@ -197,7 +188,7 @@ func handleCipher(conn net.Conn) (cryptoConn *etls.CryptoConn, err error) {
rawNodeID.IsEqual(&kms.AnonymousRawNodeID.Hash),
)
if err != nil {
- log.Errorf("get shared secret for %s failed: %s", rawNodeID.ToNodeID(), err)
+ log.WithField("target", rawNodeID.String()).WithError(err).Error("get shared secret")
return
}
cipher := etls.NewCipher(symmetricKey)
diff --git a/rpc/server_test.go b/rpc/server_test.go
index ba901f804..04b92bcc8 100644
--- a/rpc/server_test.go
+++ b/rpc/server_test.go
@@ -59,14 +59,20 @@ func NewTestService() *TestService {
}
func (s *TestService) IncCounter(req *TestReq, rep *TestRep) error {
- log.Debugf("calling IncCounter req:%v, rep:%v", *req, *rep)
+ log.WithFields(log.Fields{
+ "req": *req,
+ "reply": *rep,
+ }).Debug("calling IncCounter")
s.counter += req.Step
rep.Ret = s.counter
return nil
}
func (s *TestService) IncCounterSimpleArgs(step int, ret *int) error {
- log.Debugf("calling IncCounter req:%v, rep:%v", step, ret)
+ log.WithFields(log.Fields{
+ "req": step,
+ "reply": ret,
+ }).Debug("calling IncCounter")
s.counter += step
*ret = s.counter
return nil
@@ -187,7 +193,7 @@ func TestEncPingFindNeighbor(t *testing.T) {
masterKey := []byte("abc")
dht, err := route.NewDHTService(PubKeyStorePath, new(consistent.KMSStorage), true)
- server, err := NewServerWithService(ServiceMap{"DHT": dht})
+ server, err := NewServerWithService(ServiceMap{route.DHTRPCName: dht})
if err != nil {
log.Fatal(err)
}
@@ -238,8 +244,8 @@ func TestEncPingFindNeighbor(t *testing.T) {
log.Debugf("respB: %v", respB)
req := &proto.FindNeighborReq{
- NodeID: "123",
- Count: 10,
+ ID: "1234567812345678123456781234567812345678123456781234567812345678",
+ Count: 10,
}
resp := new(proto.FindNeighborResp)
err = client.Call("DHT.FindNeighbor", req, resp)
diff --git a/rpc/sharedsecret.go b/rpc/sharedsecret.go
index 936a1179e..e9166a1c3 100644
--- a/rpc/sharedsecret.go
+++ b/rpc/sharedsecret.go
@@ -17,6 +17,8 @@
package rpc
import (
+ "sync"
+
"github.com/CovenantSQL/CovenantSQL/conf"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
@@ -25,42 +27,53 @@ import (
"github.com/CovenantSQL/CovenantSQL/utils/log"
)
+var symmetricKeyCache sync.Map
+
// GetSharedSecretWith gets shared symmetric key with ECDH
func GetSharedSecretWith(nodeID *proto.RawNodeID, isAnonymous bool) (symmetricKey []byte, err error) {
if isAnonymous {
symmetricKey = []byte(`!&\\!qEyey*\cbLc,aKl`)
log.Debug("using anonymous ETLS")
} else {
- var remotePublicKey *asymmetric.PublicKey
- if route.IsBPNodeID(nodeID) {
- remotePublicKey = kms.BP.PublicKey
- } else if conf.RoleTag[0] == conf.BlockProducerBuildTag[0] {
- remotePublicKey, err = kms.GetPublicKey(proto.NodeID(nodeID.String()))
- if err != nil {
- log.Errorf("get public key locally failed, node id: %s, err: %s", nodeID.ToNodeID(), err)
- return
- }
+ symmetricKeyI, ok := symmetricKeyCache.Load(nodeID)
+ if ok {
+ symmetricKey, _ = symmetricKeyI.([]byte)
} else {
- // if non BP running and key not found, ask BlockProducer
- var nodeInfo *proto.Node
- nodeInfo, err = GetNodeInfo(nodeID)
+ var remotePublicKey *asymmetric.PublicKey
+ if route.IsBPNodeID(nodeID) {
+ remotePublicKey = kms.BP.PublicKey
+ } else if conf.RoleTag[0] == conf.BlockProducerBuildTag[0] {
+ remotePublicKey, err = kms.GetPublicKey(proto.NodeID(nodeID.String()))
+ if err != nil {
+ log.WithField("node", nodeID).WithError(err).Error("get public key locally failed")
+ return
+ }
+ } else {
+ // if non BP running and key not found, ask BlockProducer
+ var nodeInfo *proto.Node
+ nodeInfo, err = GetNodeInfo(nodeID)
+ if err != nil {
+ log.WithField("node", nodeID).WithError(err).Error("get public key failed")
+ return
+ }
+ remotePublicKey = nodeInfo.PublicKey
+ }
+
+ var localPrivateKey *asymmetric.PrivateKey
+ localPrivateKey, err = kms.GetLocalPrivateKey()
if err != nil {
- log.Errorf("get public key failed, node id: %s, err: %s", nodeID.ToNodeID(), err)
+ log.WithError(err).Error("get local private key failed")
return
}
- remotePublicKey = nodeInfo.PublicKey
- }
- var localPrivateKey *asymmetric.PrivateKey
- localPrivateKey, err = kms.GetLocalPrivateKey()
- if err != nil {
- log.Errorf("get local private key failed: %s", err)
- return
+ symmetricKey = asymmetric.GenECDHSharedSecret(localPrivateKey, remotePublicKey)
+ symmetricKeyCache.Store(nodeID, symmetricKey)
+ log.WithFields(log.Fields{
+ "node": nodeID.String(),
+ "remotePub": remotePublicKey.Serialize(),
+ "sessionKey": symmetricKey,
+ }).Debug("generated shared secret")
}
-
- symmetricKey = asymmetric.GenECDHSharedSecret(localPrivateKey, remotePublicKey)
- log.Debugf("ECDH for %s Public Key: %x, Session Key: %x",
- nodeID.ToNodeID(), remotePublicKey.Serialize(), symmetricKey)
//log.Debugf("ECDH for %s Public Key: %x, Private Key: %x Session Key: %x",
// nodeID.ToNodeID(), remotePublicKey.Serialize(), localPrivateKey.Serialize(), symmetricKey)
}
diff --git a/sqlchain/blockindex_test.go b/sqlchain/blockindex_test.go
index c00691765..df47a4cdd 100644
--- a/sqlchain/blockindex_test.go
+++ b/sqlchain/blockindex_test.go
@@ -55,7 +55,7 @@ func TestNewBlockNode(t *testing.T) {
parent := newBlockNode(0, testBlocks[0], nil)
if parent == nil {
- t.Fatalf("unexpected result: nil")
+ t.Fatal("unexpected result: nil")
} else if parent.parent != nil {
t.Fatalf("unexpected parent: %v", parent.parent)
} else if parent.count != 0 {
@@ -65,7 +65,7 @@ func TestNewBlockNode(t *testing.T) {
child := newBlockNode(1, testBlocks[1], parent)
if child == nil {
- t.Fatalf("unexpected result: nil")
+ t.Fatal("unexpected result: nil")
} else if child.parent != parent {
t.Fatalf("unexpected parent: %v", child.parent)
} else if child.count != parent.count+1 {
@@ -89,7 +89,7 @@ func TestInitBlockNode(t *testing.T) {
parent.initBlockNode(0, testBlocks[0], nil)
if parent == nil {
- t.Fatalf("unexpected result: nil")
+ t.Fatal("unexpected result: nil")
} else if parent.parent != nil {
t.Fatalf("unexpected parent: %v", parent.parent)
} else if parent.count != 0 {
@@ -99,7 +99,7 @@ func TestInitBlockNode(t *testing.T) {
child.initBlockNode(1, testBlocks[1], parent)
if child == nil {
- t.Fatalf("unexpected result: nil")
+ t.Fatal("unexpected result: nil")
} else if child.parent != parent {
t.Fatalf("unexpected parent: %v", child.parent)
} else if child.count != parent.count+1 {
diff --git a/sqlchain/chain.go b/sqlchain/chain.go
index 8817ed6e4..8984fd8aa 100644
--- a/sqlchain/chain.go
+++ b/sqlchain/chain.go
@@ -21,7 +21,6 @@ import (
"encoding/binary"
"fmt"
"os"
- "reflect"
"sync"
"time"
@@ -38,7 +37,6 @@ import (
"github.com/CovenantSQL/CovenantSQL/utils"
"github.com/CovenantSQL/CovenantSQL/utils/log"
wt "github.com/CovenantSQL/CovenantSQL/worker/types"
- "github.com/coreos/bbolt"
"github.com/pkg/errors"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/opt"
@@ -46,14 +44,12 @@ import (
)
var (
- metaBucket = [4]byte{0x0, 0x0, 0x0, 0x0}
- metaStateKey = []byte("covenantsql-state")
- metaBlockIndexBucket = []byte("covenantsql-block-index-bucket")
- metaHeightIndexBucket = []byte("covenantsql-query-height-index-bucket")
- metaRequestIndexBucket = []byte("covenantsql-query-request-index-bucket")
- metaResponseIndexBucket = []byte("covenantsql-query-response-index-bucket")
- metaAckIndexBucket = [4]byte{'Q', 'A', 'C', 'K'}
- leveldbConf = opt.Options{}
+ metaState = [4]byte{'S', 'T', 'A', 'T'}
+ metaBlockIndex = [4]byte{'B', 'L', 'C', 'K'}
+ metaRequestIndex = [4]byte{'R', 'E', 'Q', 'U'}
+ metaResponseIndex = [4]byte{'R', 'E', 'S', 'P'}
+ metaAckIndex = [4]byte{'Q', 'A', 'C', 'K'}
+ leveldbConf = opt.Options{}
)
func init() {
@@ -75,10 +71,28 @@ func keyToHeight(k []byte) int32 {
return int32(binary.BigEndian.Uint32(k))
}
+// keyWithSymbolToHeight converts a height back from a key(ack/resp/req/block) in bytes.
+// ack key:
+// ['Q', 'A', 'C', 'K', height, hash]
+// resp key:
+// ['R', 'E', 'S', 'P', height, hash]
+// req key:
+// ['R', 'E', 'Q', 'U', height, hash]
+// block key:
+// ['B', 'L', 'C', 'K', height, hash]
+func keyWithSymbolToHeight(k []byte) int32 {
+ if len(k) < 8 {
+ return -1
+ }
+ return int32(binary.BigEndian.Uint32(k[4:]))
+}
+
// Chain represents a sql-chain.
type Chain struct {
- db *bolt.DB
- ldb *leveldb.DB
+ // bdb stores state and block
+ bdb *leveldb.DB
+ // tdb stores ack/request/response
+ tdb *leveldb.DB
bi *blockIndex
qi *queryIndex
cl *rpc.Caller
@@ -107,7 +121,7 @@ func NewChain(c *Config) (chain *Chain, err error) {
// TODO(leventeliu): this is a rough solution, you may also want to clean database file and
// force rebuilding.
var fi os.FileInfo
- if fi, err = os.Stat(c.DataFile); err == nil && fi.Mode().IsRegular() {
+ if fi, err = os.Stat(c.DataFile + "-block-state.ldb"); err == nil && fi.Mode().IsDir() {
return LoadChain(c)
}
@@ -116,42 +130,26 @@ func NewChain(c *Config) (chain *Chain, err error) {
return
}
- // Open DB file
- db, err := bolt.Open(c.DataFile, 0600, nil)
+ // Open LevelDB for block and state
+ bdbFile := c.DataFile + "-block-state.ldb"
+ bdb, err := leveldb.OpenFile(bdbFile, &leveldbConf)
if err != nil {
+ err = errors.Wrapf(err, "open leveldb %s", bdbFile)
return
}
- // Create buckets for chain meta
- if err = db.Update(func(tx *bolt.Tx) (err error) {
- bucket, err := tx.CreateBucketIfNotExists(metaBucket[:])
-
- if err != nil {
- return
- }
-
- if _, err = bucket.CreateBucketIfNotExists(metaBlockIndexBucket); err != nil {
- return
- }
-
- _, err = bucket.CreateBucketIfNotExists(metaHeightIndexBucket)
- return
- }); err != nil {
- return
- }
-
- // Open LevelDB
- ldbFile := c.DataFile + ".ldb"
- ldb, err := leveldb.OpenFile(ldbFile, &leveldbConf)
+ // Open LevelDB for ack/request/response
+ tdbFile := c.DataFile + "-ack-req-resp.ldb"
+ tdb, err := leveldb.OpenFile(tdbFile, &leveldbConf)
if err != nil {
- err = errors.Wrapf(err, "open leveldb %s", ldbFile)
+ err = errors.Wrapf(err, "open leveldb %s", tdbFile)
return
}
// Create chain state
chain = &Chain{
- db: db,
- ldb: ldb,
+ bdb: bdb,
+ tdb: tdb,
bi: newBlockIndex(c),
qi: newQueryIndex(),
cl: rpc.NewCaller(),
@@ -177,24 +175,27 @@ func NewChain(c *Config) (chain *Chain, err error) {
// LoadChain loads the chain state from the specified database and rebuilds a memory index.
func LoadChain(c *Config) (chain *Chain, err error) {
- // Open DB file
- db, err := bolt.Open(c.DataFile, 0600, nil)
+
+ // Open LevelDB for block and state
+ bdbFile := c.DataFile + "-block-state.ldb"
+ bdb, err := leveldb.OpenFile(bdbFile, &leveldbConf)
if err != nil {
+ err = errors.Wrapf(err, "open leveldb %s", bdbFile)
return
}
- // Open LevelDB
- ldbFile := c.DataFile + ".ldb"
- ldb, err := leveldb.OpenFile(ldbFile, &leveldbConf)
+ // Open LevelDB for ack/request/response
+ tdbFile := c.DataFile + "-ack-req-resp.ldb"
+ tdb, err := leveldb.OpenFile(tdbFile, &leveldbConf)
if err != nil {
- err = errors.Wrapf(err, "open leveldb %s", ldbFile)
+ err = errors.Wrapf(err, "open leveldb %s", tdbFile)
return
}
// Create chain state
chain = &Chain{
- db: db,
- ldb: ldb,
+ bdb: bdb,
+ tdb: tdb,
bi: newBlockIndex(c),
qi: newQueryIndex(),
cl: rpc.NewCaller(),
@@ -211,145 +212,133 @@ func LoadChain(c *Config) (chain *Chain, err error) {
replCh: make(chan struct{}),
}
- err = chain.db.View(func(tx *bolt.Tx) (err error) {
- // Read state struct
- meta := tx.Bucket(metaBucket[:])
- metaEnc := meta.Get(metaStateKey)
- if metaEnc == nil {
- return ErrMetaStateNotFound
- }
- st := &state{}
- if err = utils.DecodeMsgPack(metaEnc, st); err != nil {
- return err
+ // Read state struct
+ stateEnc, err := chain.bdb.Get(metaState[:], nil)
+ if err != nil {
+ return nil, err
+ }
+ st := &state{}
+ if err = utils.DecodeMsgPack(stateEnc, st); err != nil {
+ return nil, err
+ }
+
+ log.WithFields(log.Fields{
+ "peer": chain.rt.getPeerInfoString(),
+ "state": st,
+ }).Debug("Loading state from database")
+
+ // Read blocks and rebuild memory index
+ var last *blockNode
+ var index int32
+ // TODO(lambda): select a better init length
+ nodes := make([]blockNode, 100)
+ blockIter := chain.bdb.NewIterator(util.BytesPrefix(metaBlockIndex[:]), nil)
+ defer blockIter.Release()
+ for blockIter.Next() {
+ k := blockIter.Key()
+ v := blockIter.Value()
+
+ block := &ct.Block{}
+
+ if err = utils.DecodeMsgPack(v, block); err != nil {
+ err = errors.Wrapf(err, "block height %d, key index %s", keyWithSymbolToHeight(k), string(k))
+ return
}
log.WithFields(log.Fields{
"peer": chain.rt.getPeerInfoString(),
- "state": st,
- }).Debug("Loading state from database")
-
- // Read blocks and rebuild memory index
- var last *blockNode
- var index int32
- blocks := meta.Bucket(metaBlockIndexBucket)
- nodes := make([]blockNode, blocks.Stats().KeyN)
+ "block": block.BlockHash().String(),
+ }).Debug("Loading block from database")
+ parent := (*blockNode)(nil)
- if err = blocks.ForEach(func(k, v []byte) (err error) {
- block := &ct.Block{}
-
- if err = utils.DecodeMsgPack(v, block); err != nil {
+ if last == nil {
+ if err = block.VerifyAsGenesis(); err != nil {
return
}
- log.WithFields(log.Fields{
- "peer": chain.rt.getPeerInfoString(),
- "block": block.BlockHash().String(),
- }).Debug("Loading block from database")
- parent := (*blockNode)(nil)
-
- if last == nil {
- if err = block.VerifyAsGenesis(); err != nil {
- return
- }
-
- // Set constant fields from genesis block
- chain.rt.setGenesis(block)
- } else if block.ParentHash().IsEqual(&last.hash) {
- if err = block.Verify(); err != nil {
- return
- }
+ // Set constant fields from genesis block
+ chain.rt.setGenesis(block)
+ } else if block.ParentHash().IsEqual(&last.hash) {
+ if err = block.Verify(); err != nil {
+ return
+ }
- parent = last
- } else {
- parent = chain.bi.lookupNode(block.ParentHash())
+ parent = last
+ } else {
+ parent = chain.bi.lookupNode(block.ParentHash())
- if parent == nil {
- return ErrParentNotFound
- }
+ if parent == nil {
+ return nil, ErrParentNotFound
}
+ }
- height := chain.rt.getHeightFromTime(block.Timestamp())
- nodes[index].initBlockNode(height, block, parent)
- chain.bi.addBlock(&nodes[index])
- last = &nodes[index]
- index++
+ height := chain.rt.getHeightFromTime(block.Timestamp())
+ nodes[index].initBlockNode(height, block, parent)
+ chain.bi.addBlock(&nodes[index])
+ last = &nodes[index]
+ index++
+ }
+ if err = blockIter.Error(); err != nil {
+ err = errors.Wrap(err, "load block")
+ return
+ }
+
+ // Set chain state
+ st.node = last
+ chain.rt.setHead(st)
+
+ // Read queries and rebuild memory index
+ respIter := chain.tdb.NewIterator(util.BytesPrefix(metaResponseIndex[:]), nil)
+ defer respIter.Release()
+ for respIter.Next() {
+ k := respIter.Key()
+ v := respIter.Value()
+ h := keyWithSymbolToHeight(k)
+ var resp = &wt.SignedResponseHeader{}
+ if err = utils.DecodeMsgPack(v, resp); err != nil {
+ err = errors.Wrapf(err, "load resp, height %d, index %s", h, string(k))
return
- }); err != nil {
+ }
+ log.WithFields(log.Fields{
+ "height": h,
+ "header": resp.HeaderHash.String(),
+ }).Debug("Loaded new resp header")
+ err = chain.qi.addResponse(h, resp)
+ if err != nil {
+ err = errors.Wrapf(err, "load resp, height %d, hash %s", h, resp.HeaderHash.String())
return
}
+ }
+ if err = respIter.Error(); err != nil {
+ err = errors.Wrap(err, "load resp")
+ return
+ }
- // Set chain state
- st.node = last
- chain.rt.setHead(st)
-
- // Read queries and rebuild memory index
- heights := meta.Bucket(metaHeightIndexBucket)
-
- if err = heights.ForEach(func(k, v []byte) (err error) {
- h := keyToHeight(k)
-
- if resps := heights.Bucket(k).Bucket(
- metaResponseIndexBucket); resps != nil {
- if err = resps.ForEach(func(k []byte, v []byte) (err error) {
- var resp = &wt.SignedResponseHeader{}
- if err = utils.DecodeMsgPack(v, resp); err != nil {
- return
- }
- log.WithFields(log.Fields{
- "height": h,
- "header": resp.HeaderHash.String(),
- }).Debug("Loaded new resp header")
- return chain.qi.addResponse(h, resp)
- }); err != nil {
- return
- }
- }
-
- ldbKey := make([]byte, 0, len(metaAckIndexBucket)+len(k)+hash.HashSize)
- ldbKey = append(append(ldbKey, metaAckIndexBucket[:]...), k...)
- iter := ldb.NewIterator(util.BytesPrefix(ldbKey), nil)
- defer iter.Release()
- for iter.Next() {
- var ack = &wt.SignedAckHeader{}
- if err = utils.DecodeMsgPack(iter.Value(), ack); err != nil {
- return
- }
- log.WithFields(log.Fields{
- "height": h,
- "header": ack.HeaderHash.String(),
- }).Debug("Loaded new ack header")
- return chain.qi.addAck(h, ack)
- }
- err = iter.Error()
- if err != nil {
- err = errors.Wrap(err, "load new ack header")
- return
- }
-
- //acks := heights.Bucket(k).Bucket(metaAckIndexBucket)
- //if acks != nil {
- // if err = acks.ForEach(func(k []byte, v []byte) (err error) {
- // var ack = &wt.SignedAckHeader{}
- // if err = utils.DecodeMsgPack(v, ack); err != nil {
- // return
- // }
- // log.WithFields(log.Fields{
- // "height": h,
- // "header": ack.HeaderHash.String(),
- // }).Debug("Loaded new ack header")
- // return chain.qi.addAck(h, ack)
- // }); err != nil {
- // return
- // }
- //}
-
+ ackIter := chain.tdb.NewIterator(util.BytesPrefix(metaAckIndex[:]), nil)
+ defer ackIter.Release()
+ for ackIter.Next() {
+ k := ackIter.Key()
+ v := ackIter.Value()
+ h := keyWithSymbolToHeight(k)
+ var ack = &wt.SignedAckHeader{}
+ if err = utils.DecodeMsgPack(v, ack); err != nil {
+ err = errors.Wrapf(err, "load ack, height %d, index %s", h, string(k))
return
- }); err != nil {
+ }
+ log.WithFields(log.Fields{
+ "height": h,
+ "header": ack.HeaderHash.String(),
+ }).Debug("Loaded new ack header")
+ err = chain.qi.addAck(h, ack)
+ if err != nil {
+ err = errors.Wrapf(err, "load ack, height %d, hash %s", h, ack.HeaderHash.String())
return
}
-
+ }
+ if err = respIter.Error(); err != nil {
+ err = errors.Wrap(err, "load ack")
return
- })
+ }
return
}
@@ -375,21 +364,26 @@ func (c *Chain) pushBlock(b *ct.Block) (err error) {
}
// Update in transaction
- err = c.db.Update(func(tx *bolt.Tx) (err error) {
- if err = tx.Bucket(metaBucket[:]).Put(metaStateKey, encState.Bytes()); err != nil {
- return
- }
-
- if err = tx.Bucket(metaBucket[:]).Bucket(metaBlockIndexBucket).Put(
- node.indexKey(), encBlock.Bytes()); err != nil {
- return
- }
-
- c.rt.setHead(st)
- c.bi.addBlock(node)
- c.qi.setSignedBlock(h, b)
+ t, err := c.bdb.OpenTransaction()
+ if err = t.Put(metaState[:], encState.Bytes(), nil); err != nil {
+ err = errors.Wrapf(err, "put %s", string(metaState[:]))
+ t.Discard()
+ return
+ }
+ blockKey := utils.ConcatAll(metaBlockIndex[:], node.indexKey())
+ if err = t.Put(blockKey, encBlock.Bytes(), nil); err != nil {
+ err = errors.Wrapf(err, "put %s", string(node.indexKey()))
+ t.Discard()
+ return
+ }
+ if err = t.Commit(); err != nil {
+ err = errors.Wrapf(err, "commit error")
+ t.Discard()
return
- })
+ }
+ c.rt.setHead(st)
+ c.bi.addBlock(node)
+ c.qi.setSignedBlock(h, b)
if err == nil {
log.WithFields(log.Fields{
@@ -414,27 +408,6 @@ func (c *Chain) pushBlock(b *ct.Block) (err error) {
return
}
-func ensureHeight(tx *bolt.Tx, k []byte) (hb *bolt.Bucket, err error) {
- b := tx.Bucket(metaBucket[:]).Bucket(metaHeightIndexBucket)
-
- if hb = b.Bucket(k); hb == nil {
- // Create and initialize bucket in new height
- if hb, err = b.CreateBucketIfNotExists(k); err != nil {
- return
- }
-
- if _, err = hb.CreateBucketIfNotExists(metaRequestIndexBucket); err != nil {
- return
- }
-
- if _, err = hb.CreateBucketIfNotExists(metaResponseIndexBucket); err != nil {
- return
- }
- }
-
- return
-}
-
// pushResponedQuery pushes a responsed, signed and verified query into the chain.
func (c *Chain) pushResponedQuery(resp *wt.SignedResponseHeader) (err error) {
h := c.rt.getHeightFromTime(resp.Request.Timestamp)
@@ -445,25 +418,23 @@ func (c *Chain) pushResponedQuery(resp *wt.SignedResponseHeader) (err error) {
return
}
- return c.db.Update(func(tx *bolt.Tx) (err error) {
- heightBucket, err := ensureHeight(tx, k)
-
- if err != nil {
- return
- }
+ tdbKey := utils.ConcatAll(metaResponseIndex[:], k, resp.HeaderHash[:])
+ if err = c.tdb.Put(tdbKey, enc.Bytes(), nil); err != nil {
+ err = errors.Wrapf(err, "put response %d %s", h, resp.HeaderHash.String())
+ return
+ }
- if err = heightBucket.Bucket(metaResponseIndexBucket).Put(
- resp.HeaderHash[:], enc.Bytes()); err != nil {
- return
- }
+ if err = c.qi.addResponse(h, resp); err != nil {
+ err = errors.Wrapf(err, "add resp h %d hash %s", h, resp.HeaderHash)
+ return err
+ }
- // Always put memory changes which will not be affected by rollback after DB operations
- return c.qi.addResponse(h, resp)
- })
+ return
}
// pushAckedQuery pushes a acknowledged, signed and verified query into the chain.
func (c *Chain) pushAckedQuery(ack *wt.SignedAckHeader) (err error) {
+ log.Debugf("push ack %s", ack.HeaderHash.String())
h := c.rt.getHeightFromTime(ack.SignedResponseHeader().Timestamp)
k := heightToKey(h)
var enc *bytes.Buffer
@@ -472,28 +443,19 @@ func (c *Chain) pushAckedQuery(ack *wt.SignedAckHeader) (err error) {
return
}
- return c.db.Update(func(tx *bolt.Tx) (err error) {
- _, err = ensureHeight(tx, k)
- if err != nil {
- return
- }
+ tdbKey := utils.ConcatAll(metaAckIndex[:], k, ack.HeaderHash[:])
- ldbKey := make([]byte, 0, len(metaAckIndexBucket)+len(k)+hash.HashSize)
- ldbKey = append(append(append(ldbKey, metaAckIndexBucket[:]...), k...), ack.HeaderHash[:]...)
- err = c.ldb.Put(ldbKey, enc.Bytes(), nil)
- //err = b.Bucket(metaAckIndexBucket).Put(ack.HeaderHash[:], enc.Bytes())
- if err != nil {
- err = errors.Wrapf(err, "put %s %d %s", string(metaAckIndexBucket[:]), h, ack.HeaderHash)
- return
- }
+ if err = c.tdb.Put(tdbKey, enc.Bytes(), nil); err != nil {
+ err = errors.Wrapf(err, "put ack %d %s", h, ack.HeaderHash.String())
+ return
+ }
- // Always put memory changes which will not be affected by rollback after DB operations
- if err = c.qi.addAck(h, ack); err != nil {
- return
- }
+ if err = c.qi.addAck(h, ack); err != nil {
+ err = errors.Wrapf(err, "add ack h %d hash %s", h, ack.HeaderHash)
+ return err
+ }
- return
- })
+ return
}
// produceBlock prepares, signs and advises the pending block to the orther peers.
@@ -708,15 +670,15 @@ func (c *Chain) mainCycle() {
c.syncHead()
if t, d := c.rt.nextTick(); d > 0 {
- log.WithFields(log.Fields{
- "peer": c.rt.getPeerInfoString(),
- "time": c.rt.getChainTimeString(),
- "next_turn": c.rt.getNextTurn(),
- "head_height": c.rt.getHead().Height,
- "head_block": c.rt.getHead().Head.String(),
- "using_timestamp": t.Format(time.RFC3339Nano),
- "duration": d,
- }).Debug("Main cycle")
+ //log.WithFields(log.Fields{
+ // "peer": c.rt.getPeerInfoString(),
+ // "time": c.rt.getChainTimeString(),
+ // "next_turn": c.rt.getNextTurn(),
+ // "head_height": c.rt.getHead().Height,
+ // "head_block": c.rt.getHead().Head.String(),
+ // "using_timestamp": t.Format(time.RFC3339Nano),
+ // "duration": d,
+ //}).Debug("Main cycle")
time.Sleep(d)
} else {
c.runCurrentTurn(t)
@@ -812,7 +774,7 @@ func (c *Chain) processBlocks() {
"head_block": c.rt.getHead().Head.String(),
"block_height": height,
"block_hash": block.BlockHash().String(),
- }).Error("Failed to check and push new block")
+ }).WithError(err).Error("Failed to check and push new block")
}
}
}
@@ -878,14 +840,13 @@ func (c *Chain) Stop() (err error) {
"peer": c.rt.getPeerInfoString(),
"time": c.rt.getChainTimeString(),
}).Debug("Chain service stopped")
- // Close database file
- err = c.db.Close()
+ // Close LevelDB file
+ err = c.bdb.Close()
log.WithFields(log.Fields{
"peer": c.rt.getPeerInfoString(),
"time": c.rt.getChainTimeString(),
}).Debug("Chain database closed")
- // Close LevelDB file
- err = c.ldb.Close()
+ err = c.tdb.Close()
log.WithFields(log.Fields{
"peer": c.rt.getPeerInfoString(),
"time": c.rt.getChainTimeString(),
@@ -896,15 +857,20 @@ func (c *Chain) Stop() (err error) {
// FetchBlock fetches the block at specified height from local cache.
func (c *Chain) FetchBlock(height int32) (b *ct.Block, err error) {
if n := c.rt.getHead().node.ancestor(height); n != nil {
- k := n.indexKey()
- err = c.db.View(func(tx *bolt.Tx) (err error) {
- if v := tx.Bucket(metaBucket[:]).Bucket(metaBlockIndexBucket).Get(k); v != nil {
- b = &ct.Block{}
- err = utils.DecodeMsgPack(v, b)
- }
+ k := utils.ConcatAll(metaBlockIndex[:], n.indexKey())
+ var v []byte
+ v, err = c.bdb.Get(k, nil)
+ if err != nil {
+ err = errors.Wrapf(err, "fetch block %s", string(k))
+ return
+ }
+ b = &ct.Block{}
+ err = utils.DecodeMsgPack(v, b)
+ if err != nil {
+ err = errors.Wrapf(err, "fetch block %s", string(k))
return
- })
+ }
}
return
@@ -914,33 +880,31 @@ func (c *Chain) FetchBlock(height int32) (b *ct.Block, err error) {
func (c *Chain) FetchAckedQuery(height int32, header *hash.Hash) (
ack *wt.SignedAckHeader, err error,
) {
- if ack, err = c.qi.getAck(height, header); err == nil && ack != nil {
- return
- }
- err = c.db.View(func(tx *bolt.Tx) (err error) {
- var hb = tx.Bucket(metaBucket[:]).Bucket(metaHeightIndexBucket)
+ if ack, err = c.qi.getAck(height, header); err != nil || ack == nil {
for h := height - c.rt.queryTTL - 1; h <= height; h++ {
k := heightToKey(h)
- if ab := hb.Bucket(heightToKey(h)); ab != nil {
- ldbKey := make([]byte, 0, len(metaAckIndexBucket)+len(k)+hash.HashSize)
- ldbKey = append(append(append(ldbKey, metaAckIndexBucket[:]...), k...), header[:]...)
- v, _ := c.ldb.Get(ldbKey, nil)
- //v := ab.Bucket(metaAckIndexBucket).Get(header[:])
- if v != nil {
- var dec = &wt.SignedAckHeader{}
- if err = utils.DecodeMsgPack(v, dec); err != nil {
- return
- }
- ack = dec
- break
+ ackKey := utils.ConcatAll(metaAckIndex[:], k, header[:])
+ var v []byte
+ if v, err = c.tdb.Get(ackKey, nil); err != nil {
+ // if err == leveldb.ErrNotFound, just loop for next h
+ if err != leveldb.ErrNotFound {
+ err = errors.Wrapf(err, "fetch ack in height %d hash %s", h, header.String())
+ return
}
+ } else {
+ var dec = &wt.SignedAckHeader{}
+ if err = utils.DecodeMsgPack(v, dec); err != nil {
+ err = errors.Wrapf(err, "fetch ack in height %d hash %s", h, header.String())
+ return
+ }
+ ack = dec
+ break
}
}
- if ack == nil {
- err = ErrAckQueryNotFound
- }
- return
- })
+ }
+ if ack == nil {
+ err = errors.Wrapf(ErrAckQueryNotFound, "fetch ack not found")
+ }
return
}
@@ -998,7 +962,7 @@ func (c *Chain) CheckAndPushNewBlock(block *ct.Block) (err error) {
total := int32(len(peers.Servers))
next := func() int32 {
if total > 0 {
- return (head.Height + 1) % total
+ return (c.rt.getNextTurn() - 1) % total
}
return -1
}()
@@ -1081,10 +1045,12 @@ func (c *Chain) CheckAndPushNewBlock(block *ct.Block) (err error) {
func (c *Chain) VerifyAndPushResponsedQuery(resp *wt.SignedResponseHeader) (err error) {
// TODO(leventeliu): check resp.
if c.rt.queryTimeIsExpired(resp.Timestamp) {
- return ErrQueryExpired
+ err = errors.Wrapf(ErrQueryExpired, "Verify response query, min valid height %d, response height %d", c.rt.getMinValidHeight(), c.rt.getHeightFromTime(resp.Timestamp))
+ return
}
if err = resp.Verify(); err != nil {
+ err = errors.Wrapf(err, "")
return
}
@@ -1095,7 +1061,8 @@ func (c *Chain) VerifyAndPushResponsedQuery(resp *wt.SignedResponseHeader) (err
func (c *Chain) VerifyAndPushAckedQuery(ack *wt.SignedAckHeader) (err error) {
// TODO(leventeliu): check ack.
if c.rt.queryTimeIsExpired(ack.SignedResponseHeader().Timestamp) {
- return ErrQueryExpired
+ err = errors.Wrapf(ErrQueryExpired, "Verify ack query, min valid height %d, ack height %d", c.rt.getMinValidHeight(), c.rt.getHeightFromTime(ack.Timestamp))
+ return
}
if err = ack.Verify(); err != nil {
@@ -1221,32 +1188,41 @@ func (c *Chain) collectBillingSignatures(billings *pt.BillingRequest) {
proWG.Add(1)
go func() {
defer proWG.Done()
- for resp := range respC {
- req.Signees = append(req.Signees, resp.Signee)
- req.Signatures = append(req.Signatures, resp.Signature)
+
+ bpReq := &ct.AdviseBillingReq{
+ Req: billings,
}
var (
- bp proto.NodeID
- err error
+ bpNodeID proto.NodeID
+ err error
)
+ for resp := range respC {
+ if err = bpReq.Req.AddSignature(resp.Signee, resp.Signature, false); err != nil {
+ // consume all rpc result
+ for range respC {
+ }
+
+ return
+ }
+ }
+
defer log.WithFields(log.Fields{
"peer": c.rt.getPeerInfoString(),
"time": c.rt.getChainTimeString(),
"signees_count": len(req.Signees),
"signatures_count": len(req.Signatures),
- "bp": bp,
+ "bp": bpNodeID,
}).WithError(err).Debug(
"Sent billing request")
- if bp, err = rpc.GetCurrentBP(); err != nil {
+ if bpNodeID, err = rpc.GetCurrentBP(); err != nil {
return
}
- resp := &pt.BillingResponse{}
-
- if err = c.cl.CallNode(bp, "MCC.AdviseBillingRequest", req, resp); err != nil {
+ var resp interface{}
+ if err = c.cl.CallNode(bpNodeID, route.MCCAdviseBillingRequest.String(), bpReq, resp); err != nil {
return
}
}()
@@ -1266,7 +1242,7 @@ func (c *Chain) collectBillingSignatures(billings *pt.BillingRequest) {
defer rpcWG.Done()
resp := &MuxSignBillingResp{}
- if err := c.cl.CallNode(id, "SQLC.SignBilling", req, resp); err != nil {
+ if err := c.cl.CallNode(id, route.SQLCSignBilling.String(), req, resp); err != nil {
log.WithFields(log.Fields{
"peer": c.rt.getPeerInfoString(),
"time": c.rt.getChainTimeString(),
@@ -1285,7 +1261,6 @@ func (c *Chain) collectBillingSignatures(billings *pt.BillingRequest) {
func (c *Chain) LaunchBilling(low, high int32) (err error) {
var (
req *pt.BillingRequest
- h *hash.Hash
)
defer log.WithFields(log.Fields{
@@ -1299,11 +1274,10 @@ func (c *Chain) LaunchBilling(low, high int32) (err error) {
return
}
- if h, err = req.PackRequestHeader(); err != nil {
+ if _, err = req.PackRequestHeader(); err != nil {
return
}
- req.RequestHash = *h
c.rt.wg.Add(1)
go c.collectBillingSignatures(req)
return
@@ -1314,7 +1288,6 @@ func (c *Chain) SignBilling(req *pt.BillingRequest) (
pub *asymmetric.PublicKey, sig *asymmetric.Signature, err error,
) {
var (
- h *hash.Hash
loc *pt.BillingRequest
)
defer log.WithFields(log.Fields{
@@ -1325,12 +1298,7 @@ func (c *Chain) SignBilling(req *pt.BillingRequest) (
}).WithError(err).Debug("Processing sign billing request")
// Verify billing results
- if h, err = req.PackRequestHeader(); err != nil {
- return
- }
-
- if !req.RequestHash.IsEqual(h) {
- err = ErrBillingNotMatch
+ if err = req.VerifySignatures(); err != nil {
return
}
@@ -1338,25 +1306,7 @@ func (c *Chain) SignBilling(req *pt.BillingRequest) (
return
}
- if !req.Header.LowBlock.IsEqual(&loc.Header.LowBlock) ||
- !req.Header.HighBlock.IsEqual(&loc.Header.HighBlock) {
- err = ErrBillingNotMatch
- return
- }
-
- reqMap := make(map[proto.AccountAddress]*proto.AddrAndGas)
- locMap := make(map[proto.AccountAddress]*proto.AddrAndGas)
-
- for _, v := range req.Header.GasAmounts {
- reqMap[v.AccountAddress] = v
- }
-
- for _, v := range loc.Header.GasAmounts {
- locMap[v.AccountAddress] = v
- }
-
- if !reflect.DeepEqual(reqMap, locMap) {
- err = ErrBillingNotMatch
+ if err = req.Compare(loc); err != nil {
return
}
@@ -1367,11 +1317,8 @@ func (c *Chain) SignBilling(req *pt.BillingRequest) (
return
}
- if sig, err = req.SignRequestHeader(priv); err != nil {
- return
- }
+ pub, sig, err = req.SignRequestHeader(priv, false)
- pub = priv.PubKey()
return
}
diff --git a/sqlchain/chain_test.go b/sqlchain/chain_test.go
index fd69cdb59..5afd1f227 100644
--- a/sqlchain/chain_test.go
+++ b/sqlchain/chain_test.go
@@ -33,6 +33,7 @@ import (
"github.com/CovenantSQL/CovenantSQL/proto"
"github.com/CovenantSQL/CovenantSQL/route"
"github.com/CovenantSQL/CovenantSQL/rpc"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
)
var (
@@ -41,7 +42,6 @@ var (
testTick = 100 * time.Millisecond
testQueryTTL int32 = 10
testDatabaseID proto.DatabaseID = "tdb-test"
- testChainService = "SQLC"
testPeriodNumber int32 = 10
testClientNumberPerChain = 3
)
@@ -87,6 +87,7 @@ func TestIndexKey(t *testing.T) {
}
func TestMultiChain(t *testing.T) {
+ log.SetLevel(log.InfoLevel)
// Create genesis block
genesis, err := createRandomBlock(genesisHash, true)
@@ -155,7 +156,7 @@ func TestMultiChain(t *testing.T) {
defer server.Stop()
// Create multiplexing service from RPC server
- mux := NewMuxService(testChainService, server)
+ mux := NewMuxService(route.SQLChainRPCName, server)
// Create chain instance
config := &Config{
@@ -183,6 +184,8 @@ func TestMultiChain(t *testing.T) {
config: config,
chain: chain,
}
+
+
}
// Create a master BP for RPC test
@@ -232,7 +235,7 @@ func TestMultiChain(t *testing.T) {
// Start BP
if dht, err := route.NewDHTService(testDHTStoreFile, new(consistent.KMSStorage), true); err != nil {
t.Fatalf("Error occurred: %v", err)
- } else if err = bpsvr.RegisterService("DHT", dht); err != nil {
+ } else if err = bpsvr.RegisterService(route.DHTRPCName, dht); err != nil {
t.Fatalf("Error occurred: %v", err)
}
diff --git a/sqlchain/errors.go b/sqlchain/errors.go
index 707ef6fcb..0cbf1c682 100644
--- a/sqlchain/errors.go
+++ b/sqlchain/errors.go
@@ -84,9 +84,6 @@ var (
// given in its hash field.
ErrHashNotMatch = errors.New("hash value doesn't match")
- // ErrBillingNotMatch indicates that the billing request doesn't match the local result.
- ErrBillingNotMatch = errors.New("billing request doesn't match")
-
// ErrMetaStateNotFound indicates that meta state not found in db.
ErrMetaStateNotFound = errors.New("meta state not found in db")
diff --git a/sqlchain/observer.go b/sqlchain/observer.go
index ca76876df..495c723d3 100644
--- a/sqlchain/observer.go
+++ b/sqlchain/observer.go
@@ -91,28 +91,43 @@ func (r *observerReplicator) replicate() {
curHeight := r.c.rt.getHead().Height
if r.height == ct.ReplicateFromNewest {
- log.Warningf("observer %v set to read from the newest block, which is in height %v", r.nodeID, curHeight)
+ log.WithFields(log.Fields{
+ "node": r.nodeID,
+ "height": curHeight,
+ }).Warning("observer being set to read from the newest block")
r.height = curHeight
} else if r.height > curHeight+1 {
- log.Warningf("observer %v subscribes block height %v, which is not produced yet", r.nodeID, r.height)
- log.Warningf("reset observer %v height to %v", r.nodeID, curHeight+1)
+ log.WithFields(log.Fields{
+ "node": r.nodeID,
+ "height": r.height,
+ }).Warning("observer subscribes to height not yet produced")
+ log.WithFields(log.Fields{
+ "node": r.nodeID,
+ "height": curHeight + 1,
+ }).Warning("reset observer to height")
r.height = curHeight + 1
} else if r.height == curHeight+1 {
// wait for next block
- log.Infof("no more blocks for observer %v to read", r.nodeID)
+ log.WithField("node", r.nodeID).Info("no more blocks for observer to read")
return
}
- log.Debugf("try replicating block %v for observer %v", r.height, r.nodeID)
+ log.WithFields(log.Fields{
+ "node": r.nodeID,
+ "height": r.height,
+ }).Debug("try replicating block for observer")
// replicate one record
var block *ct.Block
if block, err = r.c.FetchBlock(r.height); err != nil {
// fetch block failed
- log.Warningf("fetch block with height %v failed: %v", r.height, err)
+ log.WithField("height", r.height).WithError(err).Warning("fetch block with height failed")
return
} else if block == nil {
- log.Debugf("no block of height %v for observer %v", r.height, r.nodeID)
+ log.WithFields(log.Fields{
+ "node": r.nodeID,
+ "height": r.height,
+ }).Debug("no block of height for observer")
// black hole in chain?
// find last available block
@@ -124,8 +139,10 @@ func (r *observerReplicator) replicate() {
for h := r.height - 1; h >= 0; h-- {
if lastBlock, err = r.c.FetchBlock(h); err == nil && lastBlock != nil {
lastHeight = h
- log.Debugf("found last available block %v with height %v",
- lastBlock.BlockHash().String(), lastHeight)
+ log.WithFields(log.Fields{
+ "block": lastBlock.BlockHash().String(),
+ "height": lastHeight,
+ }).Debug("found last available block of height")
break
}
}
@@ -141,17 +158,22 @@ func (r *observerReplicator) replicate() {
if nextBlock, err = r.c.FetchBlock(h); err == nil && nextBlock != nil {
if !nextBlock.ParentHash().IsEqual(lastBlock.BlockHash()) {
// inconsistency
- log.Warningf("inconsistency detected during hole detection, "+
- "last block height: %v, hash: %v, next block height: %v, hash: %v, parent hash: %v",
- lastBlock.BlockHash().String(), lastHeight,
- nextBlock.BlockHash().String(), h, nextBlock.ParentHash().String())
+ log.WithFields(log.Fields{
+ "lastHeight": lastHeight,
+ "lastHash": lastBlock.BlockHash().String(),
+ "nextHeight": h,
+ "nextHash": nextBlock.BlockHash().String(),
+ "actualParentHash": nextBlock.ParentHash().String(),
+ }).Warning("inconsistency detected during hole detection")
return
}
nextHeight = h
- log.Debugf("found next available block %v with height %v",
- nextBlock.BlockHash().String(), nextHeight)
+ log.WithFields(log.Fields{
+ "block": nextBlock.BlockHash().String(),
+ "height": nextHeight,
+ }).Debug("found next available block of height")
break
}
}
@@ -163,21 +185,31 @@ func (r *observerReplicator) replicate() {
}
// successfully found a hole in chain
- log.Debugf("found a hole in chain, started with block: %v, height: %v to block: %v, height: %v, skipped %v blocks",
- lastBlock.BlockHash().String(), lastHeight, nextBlock.BlockHash().String(), nextHeight, nextHeight-lastHeight-1)
+ log.WithFields(log.Fields{
+ "fromBlock": lastBlock.BlockHash().String(),
+ "fromHeight": lastHeight,
+ "toBlock": nextBlock.BlockHash().String(),
+ "toHeight": nextHeight,
+ "skipped": nextHeight - lastHeight - 1,
+ }).Debug("found a hole in chain, skipping")
r.height = nextHeight
block = nextBlock
- log.Debugf("finish block height hole detection, skipping to block: %v, height: %v",
- block.BlockHash().String(), r.height)
+ log.WithFields(log.Fields{
+ "block": block.BlockHash().String(),
+ "height": r.height,
+ }).Debug("finish block height hole detection, skipping")
}
// fetch acks in block
for _, h := range block.Queries {
var ack *wt.SignedAckHeader
if ack, err = r.c.queryOrSyncAckedQuery(r.height, h, block.Producer()); err != nil || ack == nil {
- log.Warningf("fetch ack %v in block height %v failed: %v", h, r.height, err)
+ log.WithFields(log.Fields{
+ "ack": h.String(),
+ "height": r.height,
+ }).WithError(err).Warning("fetch ack of block height")
continue
}
@@ -192,8 +224,10 @@ func (r *observerReplicator) replicate() {
resp := &MuxAdviseAckedQueryResp{}
err = r.c.cl.CallNode(r.nodeID, route.OBSAdviseAckedQuery.String(), req, resp)
if err != nil {
- log.Warningf("send ack advise for block height %v to observer %v failed: %v",
- r.height, r.nodeID, err)
+ log.WithFields(log.Fields{
+ "node": r.nodeID,
+ "height": r.height,
+ }).WithError(err).Warning("send ack advise to observer")
return
}
}
@@ -218,7 +252,10 @@ func (r *observerReplicator) replicate() {
resp := &MuxAdviseNewBlockResp{}
err = r.c.cl.CallNode(r.nodeID, route.OBSAdviseNewBlock.String(), req, resp)
if err != nil {
- log.Warningf("send block height %v advise to observer %v failed: %v", r.height, r.nodeID, err)
+ log.WithFields(log.Fields{
+ "node": r.nodeID,
+ "height": r.height,
+ }).WithError(err).Warning("send block advise to observer failed")
return
}
diff --git a/sqlchain/queryindex.go b/sqlchain/queryindex.go
index 7a8a28fd0..27fa77ca9 100644
--- a/sqlchain/queryindex.go
+++ b/sqlchain/queryindex.go
@@ -19,6 +19,7 @@ package sqlchain
// TODO(leventeliu): use pooled objects to speed up this index.
import (
+ "github.com/pkg/errors"
"sync"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
@@ -482,7 +483,7 @@ func (i *queryIndex) checkAckFromBlock(h int32, b *hash.Hash, ack *hash.Hash) (
l := i.getBarrier()
if h < l {
- err = ErrQueryExpired
+ err = errors.Wrapf(ErrQueryExpired, "check Ack, height %d, barrier %d", h, l)
return
}
@@ -527,7 +528,7 @@ func (i *queryIndex) getAck(h int32, header *hash.Hash) (ack *wt.SignedAckHeader
b := i.getBarrier()
if h < b {
- err = ErrQueryExpired
+ err = errors.Wrapf(ErrQueryExpired, "get Ack, height %d, barrier %d", h, b)
return
}
diff --git a/sqlchain/queryindex_test.go b/sqlchain/queryindex_test.go
index b567107d1..609b55b35 100644
--- a/sqlchain/queryindex_test.go
+++ b/sqlchain/queryindex_test.go
@@ -17,11 +17,13 @@
package sqlchain
import (
+ "github.com/pkg/errors"
"math/rand"
"reflect"
"testing"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
)
const (
@@ -129,7 +131,7 @@ func TestCheckAckFromBlock(t *testing.T) {
if _, err := qi.checkAckFromBlock(
0, b1.BlockHash(), b1.Queries[0],
- ); err != ErrQueryExpired {
+ ); errors.Cause(err) != ErrQueryExpired {
t.Fatalf("Unexpected error: %v", err)
}
@@ -247,16 +249,17 @@ func TestGetAck(t *testing.T) {
qi := newQueryIndex()
qh := &hash.Hash{}
- if _, err := qi.getAck(-1, qh); err != ErrQueryExpired {
+ if _, err := qi.getAck(-1, qh); errors.Cause(err) != ErrQueryExpired {
t.Fatalf("Unexpected error: %v", err)
}
- if _, err := qi.getAck(0, qh); err != ErrQueryNotCached {
+ if _, err := qi.getAck(0, qh); errors.Cause(err) != ErrQueryNotCached {
t.Fatalf("Unexpected error: %v", err)
}
}
func TestQueryIndex(t *testing.T) {
+ log.SetLevel(log.InfoLevel)
// Initialize clients and workers
clients, err := newRandomNodes(testClientNumber)
@@ -303,7 +306,7 @@ func TestQueryIndex(t *testing.T) {
t.Fatalf("Error occurred: %v", err)
}
- t.Logf("i = %d, j = %d, k = %d\n\tseqno = %+v, req = %v, resp = %v", i, j, k,
+ log.Debugf("i = %d, j = %d, k = %d\n\tseqno = %+v, req = %v, resp = %v", i, j, k,
resp.Request.GetQueryKey(), &req.HeaderHash, &resp.HeaderHash)
if err = qi.addResponse(int32(i), resp); err != nil {
@@ -316,7 +319,7 @@ func TestQueryIndex(t *testing.T) {
for l := 0; l < dupAckNumber; l++ {
ack, err := createRandomQueryAckWithResponse(resp, cli)
- t.Logf("i = %d, j = %d, k = %d, l = %d\n\tseqno = %+v, "+
+ log.Debugf("i = %d, j = %d, k = %d, l = %d\n\tseqno = %+v, "+
"req = %v, resp = %v, ack = %v",
i, j, k, l,
ack.SignedRequestHeader().GetQueryKey(),
@@ -383,7 +386,7 @@ func TestQueryIndex(t *testing.T) {
); err != nil {
t.Fatalf("Error occurred: %v", err)
} else if !isKnown {
- t.Fatalf("Unexpected result: block is known")
+ t.Fatal("Unexpected result: block is known")
}
}
}
diff --git a/sqlchain/runtime.go b/sqlchain/runtime.go
index d88c30d2f..c846bf2b9 100644
--- a/sqlchain/runtime.go
+++ b/sqlchain/runtime.go
@@ -298,17 +298,6 @@ func (r *runtime) isMyTurn() (ret bool) {
return
}
-func (r *runtime) getNextProducerIndex() int32 {
- r.stateMutex.Lock()
- defer r.stateMutex.Unlock()
-
- if r.total > 0 {
- return (r.head.Height + 1) % r.total
- }
-
- return -1
-}
-
func (r *runtime) getPeers() *kayak.Peers {
r.peersMutex.Lock()
defer r.peersMutex.Unlock()
diff --git a/sqlchain/storage/storage.go b/sqlchain/storage/storage.go
index d0190ba94..d902b3e61 100644
--- a/sqlchain/storage/storage.go
+++ b/sqlchain/storage/storage.go
@@ -26,7 +26,6 @@ import (
"github.com/CovenantSQL/CovenantSQL/twopc"
"github.com/CovenantSQL/CovenantSQL/utils/log"
-
// Register CovenantSQL/go-sqlite3-encrypt engine.
_ "github.com/CovenantSQL/go-sqlite3-encrypt"
)
@@ -63,7 +62,7 @@ func openDB(dsn string) (db *sql.DB, err error) {
}
d.AddParam("_journal_mode", "WAL")
- d.AddParam("_synchronous", "FULL")
+ d.AddParam("_synchronous", "NORMAL")
fdsn := d.Format()
fn := d.GetFileName()
@@ -187,7 +186,7 @@ func (s *Storage) Commit(ctx context.Context, wb twopc.WriteBatch) (err error) {
_, err = s.tx.ExecContext(ctx, q.Pattern, args...)
if err != nil {
- log.Debugf("commit query failed: %v", err)
+ log.WithError(err).Debug("commit query failed")
s.tx.Rollback()
s.tx = nil
s.queries = nil
@@ -254,7 +253,7 @@ func (s *Storage) Query(ctx context.Context, queries []Query) (columns []string,
// always rollback on complete
defer tx.Rollback()
- q := queries[0]
+ q := queries[len(queries)-1]
// convert arguments types
args := make([]interface{}, len(q.Args))
@@ -328,7 +327,7 @@ func (s *Storage) Exec(ctx context.Context, queries []Query) (rowsAffected int64
var result sql.Result
if result, err = tx.Exec(q.Pattern, args...); err != nil {
- log.Debugf("execute query failed: %v", err)
+ log.WithError(err).Debug("execute query failed")
return
}
diff --git a/sqlchain/storage/storage_test.go b/sqlchain/storage/storage_test.go
index ef93c821a..e72d57b26 100644
--- a/sqlchain/storage/storage_test.go
+++ b/sqlchain/storage/storage_test.go
@@ -247,7 +247,7 @@ func TestStorage(t *testing.T) {
columns, types, data, err = st.Query(context.Background(), []Query{newQuery("SQL???? WHAT!!!!")})
if err == nil {
- t.Fatalf("Query should failed")
+ t.Fatal("Query should failed")
} else {
t.Logf("Query failed as expected with: %v", err.Error())
}
diff --git a/sqlchain/storageproof_test.go b/sqlchain/storageproof_test.go
index 062ed12ab..17594bd01 100644
--- a/sqlchain/storageproof_test.go
+++ b/sqlchain/storageproof_test.go
@@ -104,13 +104,13 @@ func TestGetNextVerifier(t *testing.T) {
func TestSelectRecord(t *testing.T) {
if strings.Compare(selectRecord(0), "hello world") != 0 {
- t.Errorf("It should be hello world")
+ t.Error("It should be hello world")
}
}
func TestCheckValid(t *testing.T) {
if !CheckValid(answers) {
- t.Errorf("It should be true")
+ t.Error("It should be true")
}
}
diff --git a/blockproducer/types/tx.go b/sqlchain/types/billing_req.go
similarity index 59%
rename from blockproducer/types/tx.go
rename to sqlchain/types/billing_req.go
index 3e102d338..00ee3cde2 100644
--- a/blockproducer/types/tx.go
+++ b/sqlchain/types/billing_req.go
@@ -16,27 +16,19 @@
package types
-//go:generate hsp
-
-// TxType represents the type of tx.
-type TxType byte
-
-const (
- // TxTypeBilling defines TxType for database service billing.
- TxTypeBilling TxType = 0
+import (
+ pt "github.com/CovenantSQL/CovenantSQL/blockproducer/types"
+ "github.com/CovenantSQL/CovenantSQL/proto"
)
-// String returns the TxType name.
-func (tt *TxType) String() string {
- switch *tt {
- case TxTypeBilling:
- return "TxBilling"
- default:
- return "TxUnknown"
- }
+// AdviseBillingReq defines a request of the AdviseBillingRequest RPC method.
+type AdviseBillingReq struct {
+ proto.Envelope
+ Req *pt.BillingRequest
}
-// ToByte returns the the that represents the TxType.
-func (tt *TxType) ToByte() byte {
- return byte(*tt)
+// AdviseBillingResp defines a request of the AdviseBillingRequest RPC method.
+type AdviseBillingResp struct {
+ proto.Envelope
+ Resp *pt.BillingRequest
}
diff --git a/sqlchain/types/block.go b/sqlchain/types/block.go
index faec9b3db..22b10167d 100644
--- a/sqlchain/types/block.go
+++ b/sqlchain/types/block.go
@@ -98,14 +98,13 @@ func (s *SignedHeader) Verify() error {
// VerifyAsGenesis verifies the signed header as a genesis block header.
func (s *SignedHeader) VerifyAsGenesis() (err error) {
- log.Debugf("verify genesis header: producer = %s, root = %s, parent = %s, merkle = %s,"+
- " block = %s",
- string(s.Producer[:]),
- s.GenesisHash.String(),
- s.ParentHash.String(),
- s.MerkleRoot.String(),
- s.BlockHash.String(),
- )
+ log.WithFields(log.Fields{
+ "producer": s.Producer,
+ "root": s.GenesisHash.String(),
+ "parent": s.ParentHash.String(),
+ "merkle": s.MerkleRoot.String(),
+ "block": s.BlockHash.String(),
+ }).Debug("verify genesis header")
// Assume that we can fetch public key from kms after initialization.
pk, err := kms.GetPublicKey(s.Producer)
diff --git a/sqlchain/types/block_test.go b/sqlchain/types/block_test.go
index cfb40b505..2a0f74dee 100644
--- a/sqlchain/types/block_test.go
+++ b/sqlchain/types/block_test.go
@@ -17,12 +17,11 @@
package types
import (
+ "bytes"
"math/big"
"reflect"
"testing"
- "bytes"
-
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
"github.com/CovenantSQL/CovenantSQL/utils"
diff --git a/sqlchain/types/observer.go b/sqlchain/types/observer.go
index 9e0aa35cc..112e99257 100644
--- a/sqlchain/types/observer.go
+++ b/sqlchain/types/observer.go
@@ -17,8 +17,6 @@
package types
const (
- // ObserverService is the service name for observer to receive.
- ObserverService = "OBS"
// ReplicateFromBeginning is the replication offset observes from genesis block.
ReplicateFromBeginning = int32(0)
// ReplicateFromNewest is the replication offset observes from block head of current node.
diff --git a/sqlchain/types/xxx_test.go b/sqlchain/types/xxx_test.go
index 1a21a213c..d6545d79d 100644
--- a/sqlchain/types/xxx_test.go
+++ b/sqlchain/types/xxx_test.go
@@ -98,8 +98,6 @@ func createRandomBlock(parent hash.Hash, isGenesis bool) (b *Block, err error) {
ParentHash: parent,
Timestamp: time.Now().UTC(),
},
- Signee: pub,
- Signature: nil,
},
}
diff --git a/sqlchain/xxx_test.go b/sqlchain/xxx_test.go
index 1aea3d25d..96870cc01 100644
--- a/sqlchain/xxx_test.go
+++ b/sqlchain/xxx_test.go
@@ -131,8 +131,6 @@ func createRandomQueryRequest(cli *nodeProfile) (r *wt.SignedRequestHeader, err
Timestamp: time.Now().UTC(),
// BatchCount and QueriesHash will be set by req.Sign()
},
- Signee: cli.PublicKey,
- Signature: nil,
},
Payload: wt.RequestPayload{
Queries: createRandomStorageQueries(10, 10, 10, 10),
@@ -165,8 +163,6 @@ func createRandomQueryResponse(cli, worker *nodeProfile) (
NodeID: worker.NodeID,
Timestamp: createRandomTimeAfter(req.Timestamp, 100),
},
- Signee: worker.PublicKey,
- Signature: nil,
},
Payload: wt.ResponsePayload{
Columns: createRandomStrings(10, 10, 10, 10),
@@ -201,8 +197,6 @@ func createRandomQueryResponseWithRequest(req *wt.SignedRequestHeader, worker *n
NodeID: worker.NodeID,
Timestamp: createRandomTimeAfter(req.Timestamp, 100),
},
- Signee: worker.PublicKey,
- Signature: nil,
},
Payload: wt.ResponsePayload{
Columns: createRandomStrings(10, 10, 10, 10),
@@ -237,12 +231,10 @@ func createRandomQueryAckWithResponse(resp *wt.SignedResponseHeader, cli *nodePr
NodeID: cli.NodeID,
Timestamp: createRandomTimeAfter(resp.Timestamp, 100),
},
- Signee: cli.PublicKey,
- Signature: nil,
},
}
- if err = ack.Sign(cli.PrivateKey); err != nil {
+ if err = ack.Sign(cli.PrivateKey, true); err != nil {
return
}
@@ -264,12 +256,10 @@ func createRandomQueryAck(cli, worker *nodeProfile) (r *wt.SignedAckHeader, err
NodeID: cli.NodeID,
Timestamp: createRandomTimeAfter(resp.Timestamp, 100),
},
- Signee: cli.PublicKey,
- Signature: nil,
},
}
- if err = ack.Sign(cli.PrivateKey); err != nil {
+ if err = ack.Sign(cli.PrivateKey, true); err != nil {
return
}
@@ -351,8 +341,6 @@ func createRandomBlock(parent hash.Hash, isGenesis bool) (b *ct.Block, err error
ParentHash: parent,
Timestamp: time.Now().UTC(),
},
- Signee: pub,
- Signature: nil,
},
}
@@ -397,7 +385,7 @@ func createRandomBlockWithQueries(genesis, parent hash.Hash, acks []*wt.SignedAc
b *ct.Block, err error,
) {
// Generate key pair
- priv, pub, err := asymmetric.GenSecp256k1KeyPair()
+ priv, _, err := asymmetric.GenSecp256k1KeyPair()
if err != nil {
return
@@ -415,8 +403,6 @@ func createRandomBlockWithQueries(genesis, parent hash.Hash, acks []*wt.SignedAc
ParentHash: parent,
Timestamp: time.Now().UTC(),
},
- Signee: pub,
- Signature: nil,
},
}
diff --git a/storage/storage.go b/storage/storage.go
index 9632d8ff5..55141a8d9 100644
--- a/storage/storage.go
+++ b/storage/storage.go
@@ -32,7 +32,6 @@ import (
"database/sql"
"fmt"
"sync"
-
// Register CovenantSQL/go-sqlite3-encrypt engine.
_ "github.com/CovenantSQL/go-sqlite3-encrypt"
)
diff --git a/test/GNTE/GNTE b/test/GNTE/GNTE
index 51de88917..46a509a58 160000
--- a/test/GNTE/GNTE
+++ b/test/GNTE/GNTE
@@ -1 +1 @@
-Subproject commit 51de889172de377ec104900b9566ef8c8510525e
+Subproject commit 46a509a5800a5acf9f6f243fd259e48551b856c2
diff --git a/test/GNTE/conf/gnte.yaml b/test/GNTE/conf/gnte.yaml
index 7a9d6b90a..11c5eebb6 100644
--- a/test/GNTE/conf/gnte.yaml
+++ b/test/GNTE/conf/gnte.yaml
@@ -3,13 +3,13 @@ group:
-
name: bp
nodes:
- - # node_0
+ - # bp10.250.1.2
ip: 10.250.1.2/32
cmd: "cd /scripts && ./bin/cqld -config ./node_0/config.yaml"
- - # node_1
+ - # bp10.250.1.3
ip: 10.250.1.3/32
cmd: "cd /scripts && ./bin/cqld -config ./node_1/config.yaml"
- - # node_2
+ - # bp10.250.1.4
ip: 10.250.1.4/32
cmd: "cd /scripts && ./bin/cqld -config ./node_2/config.yaml"
delay: "100ms 1ms 1%"
@@ -17,23 +17,41 @@ group:
-
name: miner
nodes:
- - # miner_0
- ip: 10.250.1.5/32
- cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_0/config.yaml"
- - # miner_1
- ip: 10.250.1.6/32
- cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_1/config.yaml"
- - # miner_2
- ip: 10.250.1.7/32
- cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_2/config.yaml"
+ - # miner10.250.100.2
+ ip: 10.250.100.2/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.2/config.yaml"
+ - # miner10.250.100.3
+ ip: 10.250.100.3/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.3/config.yaml"
+ - # miner10.250.100.4
+ ip: 10.250.100.4/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.4/config.yaml"
+ - # miner10.250.100.5
+ ip: 10.250.100.5/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.5/config.yaml"
+ - # miner10.250.100.6
+ ip: 10.250.100.6/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.6/config.yaml"
+ - # miner10.250.100.7
+ ip: 10.250.100.7/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.7/config.yaml"
+ - # miner10.250.100.8
+ ip: 10.250.100.8/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.8/config.yaml"
+ - # miner10.250.100.9
+ ip: 10.250.100.9/32
+ cmd: "cd /scripts && ./bin/cql-minerd -config ./node_miner_10.250.100.9/config.yaml"
delay: "100ms 1ms 1%"
rate: "100mbit"
-
name: client
nodes:
- # node_c
- ip: 10.250.1.8/32
+ ip: 10.250.0.2/32
cmd: "ping -c3 g.cn"
+ - # node_adapter
+ ip: 10.250.0.254/32
+ cmd: "cd /scripts && ./bin/cql-adapter -config ./node_c/config.yaml"
delay: "100ms 1ms 1%"
rate: "100mbit"
diff --git a/test/GNTE/conf/node_0/config.yaml b/test/GNTE/conf/node_0/config.yaml
index a5fb370cd..d0f183e52 100644
--- a/test/GNTE/conf/node_0/config.yaml
+++ b/test/GNTE/conf/node_0/config.yaml
@@ -76,7 +76,7 @@ KnownNodes:
b: 0
c: 0
d: 3104982049
- Addr: 10.250.1.5:4661
+ Addr: 10.250.100.2:4661
PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
Role: Miner
- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
@@ -85,7 +85,7 @@ KnownNodes:
b: 0
c: 0
d: 2305843010430351476
- Addr: 10.250.1.6:4661
+ Addr: 10.250.100.3:4661
PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
Role: Miner
- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
@@ -94,6 +94,51 @@ KnownNodes:
b: 0
c: 0
d: 13835058056920509601
- Addr: 10.250.1.7:4661
+ Addr: 10.250.100.4:4661
PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
Role: Miner
+- ID: 00eda359cd2aa0920cdd37b083b896cb18cd26b3bd51744d1b4f127830f820f2
+ Nonce:
+ a: 11
+ b: 0
+ c: 2686176025
+ d: 0
+ Addr: 10.250.100.5:4661
+ PublicKey: 02b0da0b36dec5db1b2cf88b5ddbe2dc433d09ddc9a4401a9624995d2319c1d233
+ Role: Miner
+- ID: 0017017845ff9f9f7e8599d308652eb8ce480e689fbd49afb6b44cc9726cf84b
+ Nonce:
+ a: 60
+ b: 3189902350
+ c: 0
+ d: 0
+ Addr: 10.250.100.6:4661
+ PublicKey: 03075d6743c22bb79208da88c6324b18f3db418d4089c4bad696296c866a65e0e1
+ Role: Miner
+- ID: 0075b97519d0a5cf9f7269a61b82bb3e082a5e7d796604e877ee28d08491979a
+ Nonce:
+ a: 34
+ b: 0
+ c: 0
+ d: 4246204982
+ Addr: 10.250.100.7:4661
+ PublicKey: 0306678beed432377133f1dfb83b0bdb534d2b0c44e09f457cbb86762a13e88fe1
+ Role: Miner
+- ID: 0060bb3394f5185f760af690b0c124a70acbaf952fd79d794a0d394c37d7c0bc
+ Nonce:
+ a: 13
+ b: 515393120
+ c: 0
+ d: 0
+ Addr: 10.250.100.8:4661
+ PublicKey: 0303e066f858f98b473ae6cb342c01f1f328021144621dcafce93a023223cba606
+ Role: Miner
+- ID: 004e5cf49e88f6e35e344f35d73ffe6232d4ebe93a63a825e171b8f6f2a88859
+ Nonce:
+ a: 17
+ b: 4213590245
+ c: 0
+ d: 0
+ Addr: 10.250.100.9:4661
+ PublicKey: 0297e8deccd7ada1ace2e1ed5b565abf2d3e8aa64b1bb5b36f485714e0f570adba
+ Role: Miner
diff --git a/test/GNTE/conf/node_1/config.yaml b/test/GNTE/conf/node_1/config.yaml
index ac4101ce4..70f6ca0f8 100644
--- a/test/GNTE/conf/node_1/config.yaml
+++ b/test/GNTE/conf/node_1/config.yaml
@@ -76,7 +76,7 @@ KnownNodes:
b: 0
c: 0
d: 3104982049
- Addr: 10.250.1.5:4661
+ Addr: 10.250.100.2:4661
PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
Role: Miner
- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
@@ -85,7 +85,7 @@ KnownNodes:
b: 0
c: 0
d: 2305843010430351476
- Addr: 10.250.1.6:4661
+ Addr: 10.250.100.3:4661
PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
Role: Miner
- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
@@ -94,6 +94,51 @@ KnownNodes:
b: 0
c: 0
d: 13835058056920509601
- Addr: 10.250.1.7:4661
+ Addr: 10.250.100.4:4661
PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
Role: Miner
+- ID: 00eda359cd2aa0920cdd37b083b896cb18cd26b3bd51744d1b4f127830f820f2
+ Nonce:
+ a: 11
+ b: 0
+ c: 2686176025
+ d: 0
+ Addr: 10.250.100.5:4661
+ PublicKey: 02b0da0b36dec5db1b2cf88b5ddbe2dc433d09ddc9a4401a9624995d2319c1d233
+ Role: Miner
+- ID: 0017017845ff9f9f7e8599d308652eb8ce480e689fbd49afb6b44cc9726cf84b
+ Nonce:
+ a: 60
+ b: 3189902350
+ c: 0
+ d: 0
+ Addr: 10.250.100.6:4661
+ PublicKey: 03075d6743c22bb79208da88c6324b18f3db418d4089c4bad696296c866a65e0e1
+ Role: Miner
+- ID: 0075b97519d0a5cf9f7269a61b82bb3e082a5e7d796604e877ee28d08491979a
+ Nonce:
+ a: 34
+ b: 0
+ c: 0
+ d: 4246204982
+ Addr: 10.250.100.7:4661
+ PublicKey: 0306678beed432377133f1dfb83b0bdb534d2b0c44e09f457cbb86762a13e88fe1
+ Role: Miner
+- ID: 0060bb3394f5185f760af690b0c124a70acbaf952fd79d794a0d394c37d7c0bc
+ Nonce:
+ a: 13
+ b: 515393120
+ c: 0
+ d: 0
+ Addr: 10.250.100.8:4661
+ PublicKey: 0303e066f858f98b473ae6cb342c01f1f328021144621dcafce93a023223cba606
+ Role: Miner
+- ID: 004e5cf49e88f6e35e344f35d73ffe6232d4ebe93a63a825e171b8f6f2a88859
+ Nonce:
+ a: 17
+ b: 4213590245
+ c: 0
+ d: 0
+ Addr: 10.250.100.9:4661
+ PublicKey: 0297e8deccd7ada1ace2e1ed5b565abf2d3e8aa64b1bb5b36f485714e0f570adba
+ Role: Miner
diff --git a/test/GNTE/conf/node_2/config.yaml b/test/GNTE/conf/node_2/config.yaml
index d40e26700..c1321a15c 100644
--- a/test/GNTE/conf/node_2/config.yaml
+++ b/test/GNTE/conf/node_2/config.yaml
@@ -76,7 +76,7 @@ KnownNodes:
b: 0
c: 0
d: 3104982049
- Addr: 10.250.1.5:4661
+ Addr: 10.250.100.2:4661
PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
Role: Miner
- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
@@ -85,7 +85,7 @@ KnownNodes:
b: 0
c: 0
d: 2305843010430351476
- Addr: 10.250.1.6:4661
+ Addr: 10.250.100.3:4661
PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
Role: Miner
- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
@@ -94,6 +94,51 @@ KnownNodes:
b: 0
c: 0
d: 13835058056920509601
- Addr: 10.250.1.7:4661
+ Addr: 10.250.100.4:4661
PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
Role: Miner
+- ID: 00eda359cd2aa0920cdd37b083b896cb18cd26b3bd51744d1b4f127830f820f2
+ Nonce:
+ a: 11
+ b: 0
+ c: 2686176025
+ d: 0
+ Addr: 10.250.100.5:4661
+ PublicKey: 02b0da0b36dec5db1b2cf88b5ddbe2dc433d09ddc9a4401a9624995d2319c1d233
+ Role: Miner
+- ID: 0017017845ff9f9f7e8599d308652eb8ce480e689fbd49afb6b44cc9726cf84b
+ Nonce:
+ a: 60
+ b: 3189902350
+ c: 0
+ d: 0
+ Addr: 10.250.100.6:4661
+ PublicKey: 03075d6743c22bb79208da88c6324b18f3db418d4089c4bad696296c866a65e0e1
+ Role: Miner
+- ID: 0075b97519d0a5cf9f7269a61b82bb3e082a5e7d796604e877ee28d08491979a
+ Nonce:
+ a: 34
+ b: 0
+ c: 0
+ d: 4246204982
+ Addr: 10.250.100.7:4661
+ PublicKey: 0306678beed432377133f1dfb83b0bdb534d2b0c44e09f457cbb86762a13e88fe1
+ Role: Miner
+- ID: 0060bb3394f5185f760af690b0c124a70acbaf952fd79d794a0d394c37d7c0bc
+ Nonce:
+ a: 13
+ b: 515393120
+ c: 0
+ d: 0
+ Addr: 10.250.100.8:4661
+ PublicKey: 0303e066f858f98b473ae6cb342c01f1f328021144621dcafce93a023223cba606
+ Role: Miner
+- ID: 004e5cf49e88f6e35e344f35d73ffe6232d4ebe93a63a825e171b8f6f2a88859
+ Nonce:
+ a: 17
+ b: 4213590245
+ c: 0
+ d: 0
+ Addr: 10.250.100.9:4661
+ PublicKey: 0297e8deccd7ada1ace2e1ed5b565abf2d3e8aa64b1bb5b36f485714e0f570adba
+ Role: Miner
diff --git a/test/GNTE/conf/node_c/config.yaml b/test/GNTE/conf/node_c/config.yaml
index 5073d8108..75aa1975c 100644
--- a/test/GNTE/conf/node_c/config.yaml
+++ b/test/GNTE/conf/node_c/config.yaml
@@ -3,7 +3,7 @@ WorkingRoot: "./"
PubKeyStoreFile: "public.keystore"
PrivateKeyFile: "private.key"
DHTFileName: "dht.db"
-ListenAddr: "10.250.1.4:4661"
+ListenAddr: "10.250.0.254:4661"
ThisNodeID: "00000f3b43288fe99831eb533ab77ec455d13e11fc38ec35a42d4edd17aa320d"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
@@ -76,7 +76,7 @@ KnownNodes:
b: 0
c: 0
d: 3104982049
- Addr: 10.250.1.5:4661
+ Addr: 10.250.100.2:4661
PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
Role: Miner
- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
@@ -85,7 +85,7 @@ KnownNodes:
b: 0
c: 0
d: 2305843010430351476
- Addr: 10.250.1.6:4661
+ Addr: 10.250.100.3:4661
PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
Role: Miner
- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
@@ -94,17 +94,62 @@ KnownNodes:
b: 0
c: 0
d: 13835058056920509601
- Addr: 10.250.1.7:4661
+ Addr: 10.250.100.4:4661
PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
Role: Miner
+- ID: 00eda359cd2aa0920cdd37b083b896cb18cd26b3bd51744d1b4f127830f820f2
+ Nonce:
+ a: 11
+ b: 0
+ c: 2686176025
+ d: 0
+ Addr: 10.250.100.5:4661
+ PublicKey: 02b0da0b36dec5db1b2cf88b5ddbe2dc433d09ddc9a4401a9624995d2319c1d233
+ Role: Miner
+- ID: 0017017845ff9f9f7e8599d308652eb8ce480e689fbd49afb6b44cc9726cf84b
+ Nonce:
+ a: 60
+ b: 3189902350
+ c: 0
+ d: 0
+ Addr: 10.250.100.6:4661
+ PublicKey: 03075d6743c22bb79208da88c6324b18f3db418d4089c4bad696296c866a65e0e1
+ Role: Miner
+- ID: 0075b97519d0a5cf9f7269a61b82bb3e082a5e7d796604e877ee28d08491979a
+ Nonce:
+ a: 34
+ b: 0
+ c: 0
+ d: 4246204982
+ Addr: 10.250.100.7:4661
+ PublicKey: 0306678beed432377133f1dfb83b0bdb534d2b0c44e09f457cbb86762a13e88fe1
+ Role: Miner
+- ID: 0060bb3394f5185f760af690b0c124a70acbaf952fd79d794a0d394c37d7c0bc
+ Nonce:
+ a: 13
+ b: 515393120
+ c: 0
+ d: 0
+ Addr: 10.250.100.8:4661
+ PublicKey: 0303e066f858f98b473ae6cb342c01f1f328021144621dcafce93a023223cba606
+ Role: Miner
+- ID: 004e5cf49e88f6e35e344f35d73ffe6232d4ebe93a63a825e171b8f6f2a88859
+ Nonce:
+ a: 17
+ b: 4213590245
+ c: 0
+ d: 0
+ Addr: 10.250.100.9:4661
+ PublicKey: 0297e8deccd7ada1ace2e1ed5b565abf2d3e8aa64b1bb5b36f485714e0f570adba
+ Role: Miner
Adapter:
ListenAddr: 0.0.0.0:4661
- CertificatePath: ./node_c/server.test.covenantsql.io.pem
- PrivateKeyPath: ./node_c/server.test.covenantsql.io-key.pem
+ CertificatePath: ./server.test.covenantsql.io.pem
+ PrivateKeyPath: ./server.test.covenantsql.io-key.pem
VerifyCertificate: true
- ClientCAPath: ./node_c/rootCA.pem
+ ClientCAPath: ./rootCA.pem
AdminCerts:
- - ./node_c/admin.test.covenantsql.io.pem
+ - ./admin.test.covenantsql.io.pem
WriteCerts:
- - ./node_c/write.test.covenantsql.io.pem
+ - ./write.test.covenantsql.io.pem
StorageDriver: covenantsql
diff --git a/test/GNTE/conf/node_miner_0/config.yaml b/test/GNTE/conf/node_miner_10.250.100.2/config.yaml
similarity index 67%
rename from test/GNTE/conf/node_miner_0/config.yaml
rename to test/GNTE/conf/node_miner_10.250.100.2/config.yaml
index 25c8362c5..97cb6d3a4 100644
--- a/test/GNTE/conf/node_miner_0/config.yaml
+++ b/test/GNTE/conf/node_miner_10.250.100.2/config.yaml
@@ -3,7 +3,7 @@ WorkingRoot: "./"
PubKeyStoreFile: "public.keystore"
PrivateKeyFile: "private.key"
DHTFileName: "dht.db"
-ListenAddr: "10.250.1.5:4661"
+ListenAddr: "10.250.100.2:4661"
ThisNodeID: "000005aa62048f85da4ae9698ed59c14ec0d48a88a07c15a32265634e7e64ade"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
@@ -27,7 +27,7 @@ BlockProducer:
Miner:
IsTestMode: true
RootDir: "./data"
- MaxReqTimeGap: "2s"
+ MaxReqTimeGap: "60s"
MetricCollectInterval: "60s"
KnownNodes:
- ID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
@@ -72,7 +72,7 @@ KnownNodes:
b: 0
c: 0
d: 3104982049
- Addr: 10.250.1.5:4661
+ Addr: 10.250.100.2:4661
PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
Role: Miner
- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
@@ -81,7 +81,7 @@ KnownNodes:
b: 0
c: 0
d: 2305843010430351476
- Addr: 10.250.1.6:4661
+ Addr: 10.250.100.3:4661
PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
Role: Miner
- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
@@ -90,6 +90,51 @@ KnownNodes:
b: 0
c: 0
d: 13835058056920509601
- Addr: 10.250.1.7:4661
+ Addr: 10.250.100.4:4661
PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
Role: Miner
+- ID: 00eda359cd2aa0920cdd37b083b896cb18cd26b3bd51744d1b4f127830f820f2
+ Nonce:
+ a: 11
+ b: 0
+ c: 2686176025
+ d: 0
+ Addr: 10.250.100.5:4661
+ PublicKey: 02b0da0b36dec5db1b2cf88b5ddbe2dc433d09ddc9a4401a9624995d2319c1d233
+ Role: Miner
+- ID: 0017017845ff9f9f7e8599d308652eb8ce480e689fbd49afb6b44cc9726cf84b
+ Nonce:
+ a: 60
+ b: 3189902350
+ c: 0
+ d: 0
+ Addr: 10.250.100.6:4661
+ PublicKey: 03075d6743c22bb79208da88c6324b18f3db418d4089c4bad696296c866a65e0e1
+ Role: Miner
+- ID: 0075b97519d0a5cf9f7269a61b82bb3e082a5e7d796604e877ee28d08491979a
+ Nonce:
+ a: 34
+ b: 0
+ c: 0
+ d: 4246204982
+ Addr: 10.250.100.7:4661
+ PublicKey: 0306678beed432377133f1dfb83b0bdb534d2b0c44e09f457cbb86762a13e88fe1
+ Role: Miner
+- ID: 0060bb3394f5185f760af690b0c124a70acbaf952fd79d794a0d394c37d7c0bc
+ Nonce:
+ a: 13
+ b: 515393120
+ c: 0
+ d: 0
+ Addr: 10.250.100.8:4661
+ PublicKey: 0303e066f858f98b473ae6cb342c01f1f328021144621dcafce93a023223cba606
+ Role: Miner
+- ID: 004e5cf49e88f6e35e344f35d73ffe6232d4ebe93a63a825e171b8f6f2a88859
+ Nonce:
+ a: 17
+ b: 4213590245
+ c: 0
+ d: 0
+ Addr: 10.250.100.9:4661
+ PublicKey: 0297e8deccd7ada1ace2e1ed5b565abf2d3e8aa64b1bb5b36f485714e0f570adba
+ Role: Miner
diff --git a/test/GNTE/conf/node_miner_0/private.key b/test/GNTE/conf/node_miner_10.250.100.2/private.key
similarity index 100%
rename from test/GNTE/conf/node_miner_0/private.key
rename to test/GNTE/conf/node_miner_10.250.100.2/private.key
diff --git a/test/GNTE/conf/node_miner_1/config.yaml b/test/GNTE/conf/node_miner_10.250.100.3/config.yaml
similarity index 67%
rename from test/GNTE/conf/node_miner_1/config.yaml
rename to test/GNTE/conf/node_miner_10.250.100.3/config.yaml
index 9a5170f0e..af65305fa 100644
--- a/test/GNTE/conf/node_miner_1/config.yaml
+++ b/test/GNTE/conf/node_miner_10.250.100.3/config.yaml
@@ -3,7 +3,7 @@ WorkingRoot: "./"
PubKeyStoreFile: "public.keystore"
PrivateKeyFile: "private.key"
DHTFileName: "dht.db"
-ListenAddr: "10.250.1.6:4661"
+ListenAddr: "10.250.100.3:4661"
ThisNodeID: "000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
@@ -27,7 +27,7 @@ BlockProducer:
Miner:
IsTestMode: true
RootDir: "./data"
- MaxReqTimeGap: "2s"
+ MaxReqTimeGap: "60s"
MetricCollectInterval: "60s"
KnownNodes:
- ID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
@@ -72,7 +72,7 @@ KnownNodes:
b: 0
c: 0
d: 3104982049
- Addr: 10.250.1.5:4661
+ Addr: 10.250.100.2:4661
PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
Role: Miner
- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
@@ -81,7 +81,7 @@ KnownNodes:
b: 0
c: 0
d: 2305843010430351476
- Addr: 10.250.1.6:4661
+ Addr: 10.250.100.3:4661
PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
Role: Miner
- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
@@ -90,6 +90,51 @@ KnownNodes:
b: 0
c: 0
d: 13835058056920509601
- Addr: 10.250.1.7:4661
+ Addr: 10.250.100.4:4661
PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
Role: Miner
+- ID: 00eda359cd2aa0920cdd37b083b896cb18cd26b3bd51744d1b4f127830f820f2
+ Nonce:
+ a: 11
+ b: 0
+ c: 2686176025
+ d: 0
+ Addr: 10.250.100.5:4661
+ PublicKey: 02b0da0b36dec5db1b2cf88b5ddbe2dc433d09ddc9a4401a9624995d2319c1d233
+ Role: Miner
+- ID: 0017017845ff9f9f7e8599d308652eb8ce480e689fbd49afb6b44cc9726cf84b
+ Nonce:
+ a: 60
+ b: 3189902350
+ c: 0
+ d: 0
+ Addr: 10.250.100.6:4661
+ PublicKey: 03075d6743c22bb79208da88c6324b18f3db418d4089c4bad696296c866a65e0e1
+ Role: Miner
+- ID: 0075b97519d0a5cf9f7269a61b82bb3e082a5e7d796604e877ee28d08491979a
+ Nonce:
+ a: 34
+ b: 0
+ c: 0
+ d: 4246204982
+ Addr: 10.250.100.7:4661
+ PublicKey: 0306678beed432377133f1dfb83b0bdb534d2b0c44e09f457cbb86762a13e88fe1
+ Role: Miner
+- ID: 0060bb3394f5185f760af690b0c124a70acbaf952fd79d794a0d394c37d7c0bc
+ Nonce:
+ a: 13
+ b: 515393120
+ c: 0
+ d: 0
+ Addr: 10.250.100.8:4661
+ PublicKey: 0303e066f858f98b473ae6cb342c01f1f328021144621dcafce93a023223cba606
+ Role: Miner
+- ID: 004e5cf49e88f6e35e344f35d73ffe6232d4ebe93a63a825e171b8f6f2a88859
+ Nonce:
+ a: 17
+ b: 4213590245
+ c: 0
+ d: 0
+ Addr: 10.250.100.9:4661
+ PublicKey: 0297e8deccd7ada1ace2e1ed5b565abf2d3e8aa64b1bb5b36f485714e0f570adba
+ Role: Miner
diff --git a/test/GNTE/conf/node_miner_1/private.key b/test/GNTE/conf/node_miner_10.250.100.3/private.key
similarity index 100%
rename from test/GNTE/conf/node_miner_1/private.key
rename to test/GNTE/conf/node_miner_10.250.100.3/private.key
diff --git a/test/GNTE/conf/node_miner_2/config.yaml b/test/GNTE/conf/node_miner_10.250.100.4/config.yaml
similarity index 67%
rename from test/GNTE/conf/node_miner_2/config.yaml
rename to test/GNTE/conf/node_miner_10.250.100.4/config.yaml
index dea5534c4..1b829fb70 100644
--- a/test/GNTE/conf/node_miner_2/config.yaml
+++ b/test/GNTE/conf/node_miner_10.250.100.4/config.yaml
@@ -3,7 +3,7 @@ WorkingRoot: "./"
PubKeyStoreFile: "public.keystore"
PrivateKeyFile: "private.key"
DHTFileName: "dht.db"
-ListenAddr: "10.250.1.7:4661"
+ListenAddr: "10.250.100.4:4661"
ThisNodeID: "000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8"
ValidDNSKeys:
koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
@@ -27,7 +27,7 @@ BlockProducer:
Miner:
IsTestMode: true
RootDir: "./data"
- MaxReqTimeGap: "2s"
+ MaxReqTimeGap: "60s"
MetricCollectInterval: "60s"
KnownNodes:
- ID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
@@ -72,7 +72,7 @@ KnownNodes:
b: 0
c: 0
d: 3104982049
- Addr: 10.250.1.5:4661
+ Addr: 10.250.100.2:4661
PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
Role: Miner
- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
@@ -81,7 +81,7 @@ KnownNodes:
b: 0
c: 0
d: 2305843010430351476
- Addr: 10.250.1.6:4661
+ Addr: 10.250.100.3:4661
PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
Role: Miner
- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
@@ -90,6 +90,51 @@ KnownNodes:
b: 0
c: 0
d: 13835058056920509601
- Addr: 10.250.1.7:4661
+ Addr: 10.250.100.4:4661
PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
Role: Miner
+- ID: 00eda359cd2aa0920cdd37b083b896cb18cd26b3bd51744d1b4f127830f820f2
+ Nonce:
+ a: 11
+ b: 0
+ c: 2686176025
+ d: 0
+ Addr: 10.250.100.5:4661
+ PublicKey: 02b0da0b36dec5db1b2cf88b5ddbe2dc433d09ddc9a4401a9624995d2319c1d233
+ Role: Miner
+- ID: 0017017845ff9f9f7e8599d308652eb8ce480e689fbd49afb6b44cc9726cf84b
+ Nonce:
+ a: 60
+ b: 3189902350
+ c: 0
+ d: 0
+ Addr: 10.250.100.6:4661
+ PublicKey: 03075d6743c22bb79208da88c6324b18f3db418d4089c4bad696296c866a65e0e1
+ Role: Miner
+- ID: 0075b97519d0a5cf9f7269a61b82bb3e082a5e7d796604e877ee28d08491979a
+ Nonce:
+ a: 34
+ b: 0
+ c: 0
+ d: 4246204982
+ Addr: 10.250.100.7:4661
+ PublicKey: 0306678beed432377133f1dfb83b0bdb534d2b0c44e09f457cbb86762a13e88fe1
+ Role: Miner
+- ID: 0060bb3394f5185f760af690b0c124a70acbaf952fd79d794a0d394c37d7c0bc
+ Nonce:
+ a: 13
+ b: 515393120
+ c: 0
+ d: 0
+ Addr: 10.250.100.8:4661
+ PublicKey: 0303e066f858f98b473ae6cb342c01f1f328021144621dcafce93a023223cba606
+ Role: Miner
+- ID: 004e5cf49e88f6e35e344f35d73ffe6232d4ebe93a63a825e171b8f6f2a88859
+ Nonce:
+ a: 17
+ b: 4213590245
+ c: 0
+ d: 0
+ Addr: 10.250.100.9:4661
+ PublicKey: 0297e8deccd7ada1ace2e1ed5b565abf2d3e8aa64b1bb5b36f485714e0f570adba
+ Role: Miner
diff --git a/test/GNTE/conf/node_miner_2/private.key b/test/GNTE/conf/node_miner_10.250.100.4/private.key
similarity index 100%
rename from test/GNTE/conf/node_miner_2/private.key
rename to test/GNTE/conf/node_miner_10.250.100.4/private.key
diff --git a/test/GNTE/conf/node_miner_10.250.100.5/config.yaml b/test/GNTE/conf/node_miner_10.250.100.5/config.yaml
new file mode 100755
index 000000000..810af9a5f
--- /dev/null
+++ b/test/GNTE/conf/node_miner_10.250.100.5/config.yaml
@@ -0,0 +1,140 @@
+IsTestMode: true
+WorkingRoot: "./"
+PubKeyStoreFile: "public.keystore"
+PrivateKeyFile: "private.key"
+DHTFileName: "dht.db"
+ListenAddr: "10.250.100.5:4661"
+ThisNodeID: "00eda359cd2aa0920cdd37b083b896cb18cd26b3bd51744d1b4f127830f820f2"
+ValidDNSKeys:
+ koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
+ mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: 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
+Miner:
+ IsTestMode: true
+ RootDir: "./data"
+ MaxReqTimeGap: "60s"
+ MetricCollectInterval: "60s"
+KnownNodes:
+- ID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ Addr: 10.250.1.2:4661
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Leader
+- ID: 00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35
+ Nonce:
+ a: 478373
+ b: 0
+ c: 0
+ d: 2305843009893772025
+ Addr: 10.250.1.3:4661
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582
+ Nonce:
+ a: 259939
+ b: 0
+ c: 0
+ d: 2305843012544226372
+ Addr: 10.250.1.4:4661
+ 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: 10.250.100.2:4661
+ PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
+ Role: Miner
+- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
+ Nonce:
+ a: 240524
+ b: 0
+ c: 0
+ d: 2305843010430351476
+ Addr: 10.250.100.3:4661
+ PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
+ Role: Miner
+- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
+ Nonce:
+ a: 606016
+ b: 0
+ c: 0
+ d: 13835058056920509601
+ Addr: 10.250.100.4:4661
+ PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
+ Role: Miner
+- ID: 00eda359cd2aa0920cdd37b083b896cb18cd26b3bd51744d1b4f127830f820f2
+ Nonce:
+ a: 11
+ b: 0
+ c: 2686176025
+ d: 0
+ Addr: 10.250.100.5:4661
+ PublicKey: 02b0da0b36dec5db1b2cf88b5ddbe2dc433d09ddc9a4401a9624995d2319c1d233
+ Role: Miner
+- ID: 0017017845ff9f9f7e8599d308652eb8ce480e689fbd49afb6b44cc9726cf84b
+ Nonce:
+ a: 60
+ b: 3189902350
+ c: 0
+ d: 0
+ Addr: 10.250.100.6:4661
+ PublicKey: 03075d6743c22bb79208da88c6324b18f3db418d4089c4bad696296c866a65e0e1
+ Role: Miner
+- ID: 0075b97519d0a5cf9f7269a61b82bb3e082a5e7d796604e877ee28d08491979a
+ Nonce:
+ a: 34
+ b: 0
+ c: 0
+ d: 4246204982
+ Addr: 10.250.100.7:4661
+ PublicKey: 0306678beed432377133f1dfb83b0bdb534d2b0c44e09f457cbb86762a13e88fe1
+ Role: Miner
+- ID: 0060bb3394f5185f760af690b0c124a70acbaf952fd79d794a0d394c37d7c0bc
+ Nonce:
+ a: 13
+ b: 515393120
+ c: 0
+ d: 0
+ Addr: 10.250.100.8:4661
+ PublicKey: 0303e066f858f98b473ae6cb342c01f1f328021144621dcafce93a023223cba606
+ Role: Miner
+- ID: 004e5cf49e88f6e35e344f35d73ffe6232d4ebe93a63a825e171b8f6f2a88859
+ Nonce:
+ a: 17
+ b: 4213590245
+ c: 0
+ d: 0
+ Addr: 10.250.100.9:4661
+ PublicKey: 0297e8deccd7ada1ace2e1ed5b565abf2d3e8aa64b1bb5b36f485714e0f570adba
+ Role: Miner
diff --git a/test/GNTE/conf/node_miner_10.250.100.5/private.key b/test/GNTE/conf/node_miner_10.250.100.5/private.key
new file mode 100644
index 000000000..d221df53f
--- /dev/null
+++ b/test/GNTE/conf/node_miner_10.250.100.5/private.key
@@ -0,0 +1,2 @@
+>Z0t,_SKs,_ߚd}0C8N`3&Mu 2E# mvv
/B+=
+zq=DWJa &p
\ No newline at end of file
diff --git a/test/GNTE/conf/node_miner_10.250.100.6/config.yaml b/test/GNTE/conf/node_miner_10.250.100.6/config.yaml
new file mode 100755
index 000000000..7e07f7965
--- /dev/null
+++ b/test/GNTE/conf/node_miner_10.250.100.6/config.yaml
@@ -0,0 +1,140 @@
+IsTestMode: true
+WorkingRoot: "./"
+PubKeyStoreFile: "public.keystore"
+PrivateKeyFile: "private.key"
+DHTFileName: "dht.db"
+ListenAddr: "10.250.100.6:4661"
+ThisNodeID: "0017017845ff9f9f7e8599d308652eb8ce480e689fbd49afb6b44cc9726cf84b"
+ValidDNSKeys:
+ koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
+ mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: 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
+Miner:
+ IsTestMode: true
+ RootDir: "./data"
+ MaxReqTimeGap: "60s"
+ MetricCollectInterval: "60s"
+KnownNodes:
+- ID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ Addr: 10.250.1.2:4661
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Leader
+- ID: 00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35
+ Nonce:
+ a: 478373
+ b: 0
+ c: 0
+ d: 2305843009893772025
+ Addr: 10.250.1.3:4661
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582
+ Nonce:
+ a: 259939
+ b: 0
+ c: 0
+ d: 2305843012544226372
+ Addr: 10.250.1.4:4661
+ 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: 10.250.100.2:4661
+ PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
+ Role: Miner
+- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
+ Nonce:
+ a: 240524
+ b: 0
+ c: 0
+ d: 2305843010430351476
+ Addr: 10.250.100.3:4661
+ PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
+ Role: Miner
+- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
+ Nonce:
+ a: 606016
+ b: 0
+ c: 0
+ d: 13835058056920509601
+ Addr: 10.250.100.4:4661
+ PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
+ Role: Miner
+- ID: 00eda359cd2aa0920cdd37b083b896cb18cd26b3bd51744d1b4f127830f820f2
+ Nonce:
+ a: 11
+ b: 0
+ c: 2686176025
+ d: 0
+ Addr: 10.250.100.5:4661
+ PublicKey: 02b0da0b36dec5db1b2cf88b5ddbe2dc433d09ddc9a4401a9624995d2319c1d233
+ Role: Miner
+- ID: 0017017845ff9f9f7e8599d308652eb8ce480e689fbd49afb6b44cc9726cf84b
+ Nonce:
+ a: 60
+ b: 3189902350
+ c: 0
+ d: 0
+ Addr: 10.250.100.6:4661
+ PublicKey: 03075d6743c22bb79208da88c6324b18f3db418d4089c4bad696296c866a65e0e1
+ Role: Miner
+- ID: 0075b97519d0a5cf9f7269a61b82bb3e082a5e7d796604e877ee28d08491979a
+ Nonce:
+ a: 34
+ b: 0
+ c: 0
+ d: 4246204982
+ Addr: 10.250.100.7:4661
+ PublicKey: 0306678beed432377133f1dfb83b0bdb534d2b0c44e09f457cbb86762a13e88fe1
+ Role: Miner
+- ID: 0060bb3394f5185f760af690b0c124a70acbaf952fd79d794a0d394c37d7c0bc
+ Nonce:
+ a: 13
+ b: 515393120
+ c: 0
+ d: 0
+ Addr: 10.250.100.8:4661
+ PublicKey: 0303e066f858f98b473ae6cb342c01f1f328021144621dcafce93a023223cba606
+ Role: Miner
+- ID: 004e5cf49e88f6e35e344f35d73ffe6232d4ebe93a63a825e171b8f6f2a88859
+ Nonce:
+ a: 17
+ b: 4213590245
+ c: 0
+ d: 0
+ Addr: 10.250.100.9:4661
+ PublicKey: 0297e8deccd7ada1ace2e1ed5b565abf2d3e8aa64b1bb5b36f485714e0f570adba
+ Role: Miner
diff --git a/test/GNTE/conf/node_miner_10.250.100.6/private.key b/test/GNTE/conf/node_miner_10.250.100.6/private.key
new file mode 100644
index 000000000..d8705e3c2
--- /dev/null
+++ b/test/GNTE/conf/node_miner_10.250.100.6/private.key
@@ -0,0 +1 @@
+g1sf:l_t~6whS\Y-SvX6{+{yvk֛cr>t A8Q
\ No newline at end of file
diff --git a/test/GNTE/conf/node_miner_10.250.100.7/config.yaml b/test/GNTE/conf/node_miner_10.250.100.7/config.yaml
new file mode 100755
index 000000000..3b60c4402
--- /dev/null
+++ b/test/GNTE/conf/node_miner_10.250.100.7/config.yaml
@@ -0,0 +1,140 @@
+IsTestMode: true
+WorkingRoot: "./"
+PubKeyStoreFile: "public.keystore"
+PrivateKeyFile: "private.key"
+DHTFileName: "dht.db"
+ListenAddr: "10.250.100.7:4661"
+ThisNodeID: "0075b97519d0a5cf9f7269a61b82bb3e082a5e7d796604e877ee28d08491979a"
+ValidDNSKeys:
+ koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
+ mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: 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
+Miner:
+ IsTestMode: true
+ RootDir: "./data"
+ MaxReqTimeGap: "60s"
+ MetricCollectInterval: "60s"
+KnownNodes:
+- ID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ Addr: 10.250.1.2:4661
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Leader
+- ID: 00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35
+ Nonce:
+ a: 478373
+ b: 0
+ c: 0
+ d: 2305843009893772025
+ Addr: 10.250.1.3:4661
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582
+ Nonce:
+ a: 259939
+ b: 0
+ c: 0
+ d: 2305843012544226372
+ Addr: 10.250.1.4:4661
+ 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: 10.250.100.2:4661
+ PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
+ Role: Miner
+- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
+ Nonce:
+ a: 240524
+ b: 0
+ c: 0
+ d: 2305843010430351476
+ Addr: 10.250.100.3:4661
+ PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
+ Role: Miner
+- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
+ Nonce:
+ a: 606016
+ b: 0
+ c: 0
+ d: 13835058056920509601
+ Addr: 10.250.100.4:4661
+ PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
+ Role: Miner
+- ID: 00eda359cd2aa0920cdd37b083b896cb18cd26b3bd51744d1b4f127830f820f2
+ Nonce:
+ a: 11
+ b: 0
+ c: 2686176025
+ d: 0
+ Addr: 10.250.100.5:4661
+ PublicKey: 02b0da0b36dec5db1b2cf88b5ddbe2dc433d09ddc9a4401a9624995d2319c1d233
+ Role: Miner
+- ID: 0017017845ff9f9f7e8599d308652eb8ce480e689fbd49afb6b44cc9726cf84b
+ Nonce:
+ a: 60
+ b: 3189902350
+ c: 0
+ d: 0
+ Addr: 10.250.100.6:4661
+ PublicKey: 03075d6743c22bb79208da88c6324b18f3db418d4089c4bad696296c866a65e0e1
+ Role: Miner
+- ID: 0075b97519d0a5cf9f7269a61b82bb3e082a5e7d796604e877ee28d08491979a
+ Nonce:
+ a: 34
+ b: 0
+ c: 0
+ d: 4246204982
+ Addr: 10.250.100.7:4661
+ PublicKey: 0306678beed432377133f1dfb83b0bdb534d2b0c44e09f457cbb86762a13e88fe1
+ Role: Miner
+- ID: 0060bb3394f5185f760af690b0c124a70acbaf952fd79d794a0d394c37d7c0bc
+ Nonce:
+ a: 13
+ b: 515393120
+ c: 0
+ d: 0
+ Addr: 10.250.100.8:4661
+ PublicKey: 0303e066f858f98b473ae6cb342c01f1f328021144621dcafce93a023223cba606
+ Role: Miner
+- ID: 004e5cf49e88f6e35e344f35d73ffe6232d4ebe93a63a825e171b8f6f2a88859
+ Nonce:
+ a: 17
+ b: 4213590245
+ c: 0
+ d: 0
+ Addr: 10.250.100.9:4661
+ PublicKey: 0297e8deccd7ada1ace2e1ed5b565abf2d3e8aa64b1bb5b36f485714e0f570adba
+ Role: Miner
diff --git a/test/GNTE/conf/node_miner_10.250.100.7/private.key b/test/GNTE/conf/node_miner_10.250.100.7/private.key
new file mode 100644
index 000000000..724d9a781
--- /dev/null
+++ b/test/GNTE/conf/node_miner_10.250.100.7/private.key
@@ -0,0 +1,3 @@
+vwJ
+|6sU^{]:/ch)VMWN&bioH,~-t~9XEHH/F?h-
+i,ނ
\ No newline at end of file
diff --git a/test/GNTE/conf/node_miner_10.250.100.8/config.yaml b/test/GNTE/conf/node_miner_10.250.100.8/config.yaml
new file mode 100755
index 000000000..d81332473
--- /dev/null
+++ b/test/GNTE/conf/node_miner_10.250.100.8/config.yaml
@@ -0,0 +1,140 @@
+IsTestMode: true
+WorkingRoot: "./"
+PubKeyStoreFile: "public.keystore"
+PrivateKeyFile: "private.key"
+DHTFileName: "dht.db"
+ListenAddr: "10.250.100.8:4661"
+ThisNodeID: "0060bb3394f5185f760af690b0c124a70acbaf952fd79d794a0d394c37d7c0bc"
+ValidDNSKeys:
+ koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
+ mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: 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
+Miner:
+ IsTestMode: true
+ RootDir: "./data"
+ MaxReqTimeGap: "60s"
+ MetricCollectInterval: "60s"
+KnownNodes:
+- ID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ Addr: 10.250.1.2:4661
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Leader
+- ID: 00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35
+ Nonce:
+ a: 478373
+ b: 0
+ c: 0
+ d: 2305843009893772025
+ Addr: 10.250.1.3:4661
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582
+ Nonce:
+ a: 259939
+ b: 0
+ c: 0
+ d: 2305843012544226372
+ Addr: 10.250.1.4:4661
+ 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: 10.250.100.2:4661
+ PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
+ Role: Miner
+- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
+ Nonce:
+ a: 240524
+ b: 0
+ c: 0
+ d: 2305843010430351476
+ Addr: 10.250.100.3:4661
+ PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
+ Role: Miner
+- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
+ Nonce:
+ a: 606016
+ b: 0
+ c: 0
+ d: 13835058056920509601
+ Addr: 10.250.100.4:4661
+ PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
+ Role: Miner
+- ID: 00eda359cd2aa0920cdd37b083b896cb18cd26b3bd51744d1b4f127830f820f2
+ Nonce:
+ a: 11
+ b: 0
+ c: 2686176025
+ d: 0
+ Addr: 10.250.100.5:4661
+ PublicKey: 02b0da0b36dec5db1b2cf88b5ddbe2dc433d09ddc9a4401a9624995d2319c1d233
+ Role: Miner
+- ID: 0017017845ff9f9f7e8599d308652eb8ce480e689fbd49afb6b44cc9726cf84b
+ Nonce:
+ a: 60
+ b: 3189902350
+ c: 0
+ d: 0
+ Addr: 10.250.100.6:4661
+ PublicKey: 03075d6743c22bb79208da88c6324b18f3db418d4089c4bad696296c866a65e0e1
+ Role: Miner
+- ID: 0075b97519d0a5cf9f7269a61b82bb3e082a5e7d796604e877ee28d08491979a
+ Nonce:
+ a: 34
+ b: 0
+ c: 0
+ d: 4246204982
+ Addr: 10.250.100.7:4661
+ PublicKey: 0306678beed432377133f1dfb83b0bdb534d2b0c44e09f457cbb86762a13e88fe1
+ Role: Miner
+- ID: 0060bb3394f5185f760af690b0c124a70acbaf952fd79d794a0d394c37d7c0bc
+ Nonce:
+ a: 13
+ b: 515393120
+ c: 0
+ d: 0
+ Addr: 10.250.100.8:4661
+ PublicKey: 0303e066f858f98b473ae6cb342c01f1f328021144621dcafce93a023223cba606
+ Role: Miner
+- ID: 004e5cf49e88f6e35e344f35d73ffe6232d4ebe93a63a825e171b8f6f2a88859
+ Nonce:
+ a: 17
+ b: 4213590245
+ c: 0
+ d: 0
+ Addr: 10.250.100.9:4661
+ PublicKey: 0297e8deccd7ada1ace2e1ed5b565abf2d3e8aa64b1bb5b36f485714e0f570adba
+ Role: Miner
diff --git a/test/GNTE/conf/node_miner_10.250.100.8/private.key b/test/GNTE/conf/node_miner_10.250.100.8/private.key
new file mode 100644
index 000000000..b00985df8
Binary files /dev/null and b/test/GNTE/conf/node_miner_10.250.100.8/private.key differ
diff --git a/test/GNTE/conf/node_miner_10.250.100.9/config.yaml b/test/GNTE/conf/node_miner_10.250.100.9/config.yaml
new file mode 100755
index 000000000..6ca3fae99
--- /dev/null
+++ b/test/GNTE/conf/node_miner_10.250.100.9/config.yaml
@@ -0,0 +1,140 @@
+IsTestMode: true
+WorkingRoot: "./"
+PubKeyStoreFile: "public.keystore"
+PrivateKeyFile: "private.key"
+DHTFileName: "dht.db"
+ListenAddr: "10.250.100.9:4661"
+ThisNodeID: "004e5cf49e88f6e35e344f35d73ffe6232d4ebe93a63a825e171b8f6f2a88859"
+ValidDNSKeys:
+ koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
+ mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: 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
+Miner:
+ IsTestMode: true
+ RootDir: "./data"
+ MaxReqTimeGap: "60s"
+ MetricCollectInterval: "60s"
+KnownNodes:
+- ID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ Addr: 10.250.1.2:4661
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Leader
+- ID: 00000381d46fd6cf7742d7fb94e2422033af989c0e348b5781b3219599a3af35
+ Nonce:
+ a: 478373
+ b: 0
+ c: 0
+ d: 2305843009893772025
+ Addr: 10.250.1.3:4661
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Follower
+- ID: 000000172580063ded88e010556b0aca2851265be8845b1ef397e8fce6ab5582
+ Nonce:
+ a: 259939
+ b: 0
+ c: 0
+ d: 2305843012544226372
+ Addr: 10.250.1.4:4661
+ 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: 10.250.100.2:4661
+ PublicKey: 0367aa51809a7c1dc0f82c02452fec9557b3e1d10ce7c919d8e73d90048df86d20
+ Role: Miner
+- ID: 000005f4f22c06f76c43c4f48d5a7ec1309cc94030cbf9ebae814172884ac8b5
+ Nonce:
+ a: 240524
+ b: 0
+ c: 0
+ d: 2305843010430351476
+ Addr: 10.250.100.3:4661
+ PublicKey: 02914bca0806f040dd842207c44474ab41ecd29deee7f2d355789c5c78d448ca16
+ Role: Miner
+- ID: 000003f49592f83d0473bddb70d543f1096b4ffed5e5f942a3117e256b7052b8
+ Nonce:
+ a: 606016
+ b: 0
+ c: 0
+ d: 13835058056920509601
+ Addr: 10.250.100.4:4661
+ PublicKey: 03ae859eac5b72ee428c7a85f10b2ce748d9de5e480aefbb70f6597dfa8b2175e5
+ Role: Miner
+- ID: 00eda359cd2aa0920cdd37b083b896cb18cd26b3bd51744d1b4f127830f820f2
+ Nonce:
+ a: 11
+ b: 0
+ c: 2686176025
+ d: 0
+ Addr: 10.250.100.5:4661
+ PublicKey: 02b0da0b36dec5db1b2cf88b5ddbe2dc433d09ddc9a4401a9624995d2319c1d233
+ Role: Miner
+- ID: 0017017845ff9f9f7e8599d308652eb8ce480e689fbd49afb6b44cc9726cf84b
+ Nonce:
+ a: 60
+ b: 3189902350
+ c: 0
+ d: 0
+ Addr: 10.250.100.6:4661
+ PublicKey: 03075d6743c22bb79208da88c6324b18f3db418d4089c4bad696296c866a65e0e1
+ Role: Miner
+- ID: 0075b97519d0a5cf9f7269a61b82bb3e082a5e7d796604e877ee28d08491979a
+ Nonce:
+ a: 34
+ b: 0
+ c: 0
+ d: 4246204982
+ Addr: 10.250.100.7:4661
+ PublicKey: 0306678beed432377133f1dfb83b0bdb534d2b0c44e09f457cbb86762a13e88fe1
+ Role: Miner
+- ID: 0060bb3394f5185f760af690b0c124a70acbaf952fd79d794a0d394c37d7c0bc
+ Nonce:
+ a: 13
+ b: 515393120
+ c: 0
+ d: 0
+ Addr: 10.250.100.8:4661
+ PublicKey: 0303e066f858f98b473ae6cb342c01f1f328021144621dcafce93a023223cba606
+ Role: Miner
+- ID: 004e5cf49e88f6e35e344f35d73ffe6232d4ebe93a63a825e171b8f6f2a88859
+ Nonce:
+ a: 17
+ b: 4213590245
+ c: 0
+ d: 0
+ Addr: 10.250.100.9:4661
+ PublicKey: 0297e8deccd7ada1ace2e1ed5b565abf2d3e8aa64b1bb5b36f485714e0f570adba
+ Role: Miner
diff --git a/test/GNTE/conf/node_miner_10.250.100.9/private.key b/test/GNTE/conf/node_miner_10.250.100.9/private.key
new file mode 100644
index 000000000..c1c7fb93b
Binary files /dev/null and b/test/GNTE/conf/node_miner_10.250.100.9/private.key differ
diff --git a/test/GNTE/run.sh b/test/GNTE/run.sh
index ac90a3967..44fc9624c 100755
--- a/test/GNTE/run.sh
+++ b/test/GNTE/run.sh
@@ -1,10 +1,8 @@
#!/bin/bash -x
-BUILD_IMG="covenantsql/build"
TEST_WD=$(cd $(dirname $0)/; pwd)
PROJECT_DIR=$(cd ${TEST_WD}/../../; pwd)
-BENCH_CONTAIN="bench10.250.1.8"
echo ${PROJECT_DIR}
@@ -24,15 +22,17 @@ cd ${TEST_WD}/GNTE && bash -x ./build.sh
cd ${TEST_WD}/GNTE && bash -x ./generate.sh ./scripts/gnte.yaml
rm -rf ${TEST_WD}/GNTE/scripts/bin.bak
-INSIDE_GOPATH=$(docker run -it --rm ${BUILD_IMG} bash -c 'echo -n "$GOPATH"')
-docker run -itd \
- --name ${BENCH_CONTAIN}\
- --net container:client10.250.1.8 \
- -v ${PROJECT_DIR}/../:${INSIDE_GOPATH}/src/github.com/CovenantSQL/ \
- ${BUILD_IMG} tail -f /dev/null
-
-docker exec -it ${BENCH_CONTAIN} bash -c \
- "cd ${INSIDE_GOPATH}/src/github.com/CovenantSQL/CovenantSQL/client && go test -bench . -run BenchmarkCovenantSQLDriver"
-
-docker rm -f ${BENCH_CONTAIN}
+#BUILD_IMG="covenantsql/build"
+#BENCH_CONTAIN="bench10.250.1.8"
+#INSIDE_GOPATH=$(docker run -it --rm ${BUILD_IMG} bash -c 'echo -n "$GOPATH"')
+#docker run -itd \
+# --name ${BENCH_CONTAIN}\
+# --net container:client10.250.1.8 \
+# -v ${PROJECT_DIR}/../:${INSIDE_GOPATH}/src/github.com/CovenantSQL/ \
+# ${BUILD_IMG} tail -f /dev/null
+#
+#docker exec -it ${BENCH_CONTAIN} bash -c \
+# "cd ${INSIDE_GOPATH}/src/github.com/CovenantSQL/CovenantSQL/client && go test -bench . -run BenchmarkCovenantSQLDriver"
+#
+#docker rm -f ${BENCH_CONTAIN}
diff --git a/test/node_standalone/config2.yaml b/test/node_standalone/config2.yaml
new file mode 100644
index 000000000..7921f4cd1
--- /dev/null
+++ b/test/node_standalone/config2.yaml
@@ -0,0 +1,45 @@
+IsTestMode: true
+WorkingRoot: "./"
+PubKeyStoreFile: "public.keystore"
+PrivateKeyFile: "private.key"
+DHTFileName: "dht.db"
+ListenAddr: "127.0.0.1:12230"
+ThisNodeID: "00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9"
+ValidDNSKeys:
+ koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==: cloudflare.com
+ mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==: 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
+KnownNodes:
+- ID: 00000bef611d346c0cbe1beaa76e7f0ed705a194fdf9ac3a248ec70e9c198bf9
+ Nonce:
+ a: 313283
+ b: 0
+ c: 0
+ d: 0
+ Addr: 127.0.0.1:12230
+ PublicKey: "02c76216704d797c64c58bc11519fb68582e8e63de7e5b3b2dbbbe8733efe5fd24"
+ Role: Leader
diff --git a/twopc/twopc.go b/twopc/twopc.go
index 31d247e7b..3912077d7 100644
--- a/twopc/twopc.go
+++ b/twopc/twopc.go
@@ -18,11 +18,11 @@ package twopc
import (
"context"
- "fmt"
"sync"
"time"
"github.com/CovenantSQL/CovenantSQL/utils/log"
+ "github.com/pkg/errors"
)
// Hook are called during 2PC running
@@ -98,7 +98,7 @@ func (c *Coordinator) rollback(ctx context.Context, workers []Worker, wb WriteBa
}
}
- return fmt.Errorf("twopc: rollback")
+ return errors.New("twopc: rollback")
}
func (c *Coordinator) commit(ctx context.Context, workers []Worker, wb WriteBatch) (err error) {
@@ -154,7 +154,7 @@ func (c *Coordinator) Put(workers []Worker, wb WriteBatch) (err error) {
for index, err := range errs {
if err != nil {
returnErr = err
- log.Debugf("prepare failed on %v: err = %v", workers[index], err)
+ log.WithField("worker", workers[index]).WithError(err).Debug("prepare failed")
goto ROLLBACK
}
}
@@ -162,7 +162,7 @@ func (c *Coordinator) Put(workers []Worker, wb WriteBatch) (err error) {
if c.option.beforeCommit != nil {
if err := c.option.beforeCommit(ctx); err != nil {
returnErr = err
- log.Debugf("before commit failed: err = %v", err)
+ log.WithError(err).Debug("before commit failed")
goto ROLLBACK
}
}
@@ -171,7 +171,7 @@ func (c *Coordinator) Put(workers []Worker, wb WriteBatch) (err error) {
if c.option.afterCommit != nil {
if err = c.option.afterCommit(ctx); err != nil {
- log.Debugf("after commit failed: err = %v", err)
+ log.WithError(err).Debug("after commit failed")
}
}
diff --git a/twopc/twopc_test.go b/twopc/twopc_test.go
index 6525d3b87..dfb3504a8 100644
--- a/twopc/twopc_test.go
+++ b/twopc/twopc_test.go
@@ -18,16 +18,14 @@ package twopc
import (
"context"
+ "errors"
"fmt"
+ "net"
"os"
"sync"
"testing"
"time"
- "net"
-
- "errors"
-
"github.com/CovenantSQL/CovenantSQL/crypto/etls"
"github.com/CovenantSQL/CovenantSQL/rpc"
"github.com/CovenantSQL/CovenantSQL/utils/log"
@@ -205,13 +203,19 @@ func (r *RaftNodeRPCServer) RPCRollback(req *RaftRollbackReq, resp *RaftRollback
}
func (r *RaftNode) Prepare(ctx context.Context, wb WriteBatch) (err error) {
- log.Debugf("executing 2pc: addr = %s, phase = prepare", r.addr)
- defer log.Debugf("2pc result: addr = %s, phase = prepare, result = %v", r.addr, err)
+ log.WithFields(log.Fields{
+ "addr": r.addr,
+ "phase": "prepare",
+ }).Debug("executing 2pc")
+ defer log.WithFields(log.Fields{
+ "addr": r.addr,
+ "phase": "prepare",
+ }).WithError(err).Debug("2pc result")
rwb, ok := wb.(*RaftWriteBatchReq)
if !ok {
- err = fmt.Errorf("unexpected WriteBatch type")
+ err = errors.New("unexpected WriteBatch type")
return err
}
@@ -259,7 +263,7 @@ func (r *RaftNode) Commit(ctx context.Context, wb WriteBatch) (err error) {
rwb, ok := wb.(*RaftWriteBatchReq)
if !ok {
- err = fmt.Errorf("unexpected WriteBatch type")
+ err = errors.New("unexpected WriteBatch type")
return err
}
@@ -307,7 +311,7 @@ func (r *RaftNode) Rollback(ctx context.Context, wb WriteBatch) (err error) {
rwb, ok := wb.(*RaftWriteBatchReq)
if !ok {
- err = fmt.Errorf("unexpected WriteBatch type")
+ err = errors.New("unexpected WriteBatch type")
return err
}
diff --git a/utils/big.go b/utils/big.go
index 0c7e75930..6568671f5 100644
--- a/utils/big.go
+++ b/utils/big.go
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see .
-// Package math provides integer math utilities.
+// Package utils provides integer math utilities.
package utils
import (
diff --git a/utils/bytes.go b/utils/bytes.go
new file mode 100644
index 000000000..5f0b77459
--- /dev/null
+++ b/utils/bytes.go
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2018 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
+
+// ConcatAll concatenate several bytes slice into one.
+func ConcatAll(args ...[]byte) []byte {
+ var bLen int
+ for i := range args {
+ bLen += len(args[i])
+ }
+
+ key := make([]byte, bLen)
+ position := 0
+ for i := range args {
+ copy(key[position:], args[i])
+ position += len(args[i])
+ }
+ return key
+}
diff --git a/utils/bytes_test.go b/utils/bytes_test.go
new file mode 100644
index 000000000..9276681de
--- /dev/null
+++ b/utils/bytes_test.go
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2018 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 (
+ "testing"
+
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
+ . "github.com/smartystreets/goconvey/convey"
+)
+
+func TestNewLevelDBKey(t *testing.T) {
+ Convey("new bytes", t, func() {
+ log.SetLevel(log.DebugLevel)
+ So(ConcatAll(nil), ShouldResemble, []byte{})
+ So(ConcatAll([]byte{}), ShouldResemble, []byte{})
+ So(ConcatAll([]byte{'0'}, []byte{'1'}), ShouldResemble, []byte{'0', '1'})
+ So(ConcatAll([]byte{'0'}, nil), ShouldResemble, []byte{'0'})
+ So(ConcatAll(nil, []byte{'0'}), ShouldResemble, []byte{'0'})
+ So(ConcatAll([]byte{'0', '1', '2', '3'}, []byte{'a', 'b', 'c', 'd', 'e'}, []byte{'x', 'y', 'z'}),
+ ShouldResemble, []byte{'0', '1', '2', '3', 'a', 'b', 'c', 'd', 'e', 'x', 'y', 'z'})
+ So(ConcatAll([]byte{'0', '1', '2', '3'}, nil, []byte{'x', 'y', 'z'}),
+ ShouldResemble, []byte{'0', '1', '2', '3', 'x', 'y', 'z'})
+ So(ConcatAll([]byte{'0', '1', '2', '3'}, []byte{}, []byte{'x', 'y', 'z'}),
+ ShouldResemble, []byte{'0', '1', '2', '3','x', 'y', 'z'})
+ So(ConcatAll(nil, []byte{'0', '1', '2', '3'}, nil, []byte{'x', 'y', 'z'}),
+ ShouldResemble, []byte{'0', '1', '2', '3', 'x', 'y', 'z'})
+ So(ConcatAll([]byte{}, []byte{'0', '1', '2', '3'}, nil, []byte{'x', 'y', 'z'}, nil),
+ ShouldResemble, []byte{'0', '1', '2', '3', 'x', 'y', 'z'})
+ })
+}
diff --git a/utils/exec.go b/utils/exec.go
index 596bbe5d7..303e000aa 100644
--- a/utils/exec.go
+++ b/utils/exec.go
@@ -46,15 +46,32 @@ func Build() (err error) {
wd := GetProjectSrcDir()
err = os.Chdir(wd)
if err != nil {
- log.Errorf("change working dir failed: %s", err)
+ log.WithError(err).Error("change working dir failed")
return
}
cmd := exec.Command("./build.sh")
output, err := cmd.CombinedOutput()
if err != nil {
- log.Errorf("build failed: %s", err)
+ log.WithError(err).Error("build failed")
}
- log.Debugf("build output info: %s", string(output))
+ log.Debugf("build output info: %#v", string(output))
+ return
+}
+
+// CleanupDB runs cleanupDB.sh
+func CleanupDB() (err error) {
+ wd := GetProjectSrcDir()
+ err = os.Chdir(wd)
+ if err != nil {
+ log.WithError(err).Error("change working dir failed")
+ return
+ }
+ cmd := exec.Command("./cleanupDB.sh")
+ output, err := cmd.CombinedOutput()
+ if err != nil {
+ log.WithError(err).Error("cleanupDB failed")
+ }
+ log.Debugf("cleanupDB output info: %#v", string(output))
return
}
@@ -63,12 +80,19 @@ func Build() (err error) {
func RunCommand(bin string, args []string, processName string, workingDir string, logDir string, toStd bool) (err error) {
cmd, err := RunCommandNB(bin, args, processName, workingDir, logDir, toStd)
if err != nil {
- log.Errorf("start command failed: %v", err)
+ log.WithFields(log.Fields{
+ "bin": bin,
+ "args": args,
+ "process": processName,
+ }).WithError(err).Error("start command failed")
return
}
err = cmd.Cmd.Wait()
if err != nil {
- log.Errorf("cmd %s args %s failed with %v", cmd.Cmd.Path, cmd.Cmd.Args, err)
+ log.WithFields(log.Fields{
+ "path": cmd.Cmd.Path,
+ "args": cmd.Cmd.Args,
+ }).WithError(err).Error("wait command failed")
return
}
return
@@ -80,13 +104,13 @@ func RunCommandNB(bin string, args []string, processName string, workingDir stri
cmd.LogPath = FJ(logDir, processName+".log")
logFD, err := os.Create(cmd.LogPath)
if err != nil {
- log.Errorf("create log file failed: %s", err)
+ log.WithField("path", cmd.LogPath).WithError(err).Error("create log file failed")
return
}
err = os.Chdir(workingDir)
if err != nil {
- log.Errorf("change working dir failed: %s", err)
+ log.WithField("wd", workingDir).Error("change working dir failed")
return
}
cmd.Cmd = exec.Command(bin, args...)
@@ -104,14 +128,14 @@ func RunCommandNB(bin string, args []string, processName string, workingDir stri
err = cmd.Cmd.Start()
if err != nil {
- log.Errorf("cmd.Start() failed with '%v'", err)
+ log.WithError(err).Error("cmd.Start() failed")
return
}
go func() {
_, err := io.Copy(stdout, stdoutIn)
if err != nil {
- log.Errorf("failed to capture stdout %s", err)
+ log.WithError(err).Error("failed to capture stdout")
return
}
}()
@@ -119,7 +143,7 @@ func RunCommandNB(bin string, args []string, processName string, workingDir stri
go func() {
_, err := io.Copy(stderr, stderrIn)
if err != nil {
- log.Errorf("failed to capture stderr %s", err)
+ log.WithError(err).Error("failed to capture stderr")
return
}
}()
diff --git a/utils/exec_test.go b/utils/exec_test.go
index f0e37b55e..695b40ee9 100644
--- a/utils/exec_test.go
+++ b/utils/exec_test.go
@@ -38,6 +38,13 @@ func TestBuild(t *testing.T) {
})
}
+func TestCleanupDB(t *testing.T) {
+ Convey("CleanupDB", t, func() {
+ log.SetLevel(log.DebugLevel)
+ So(CleanupDB(), ShouldBeNil)
+ })
+}
+
func TestRunServer(t *testing.T) {
Convey("build", t, func() {
log.SetLevel(log.DebugLevel)
diff --git a/utils/log/entrylogwrapper.go b/utils/log/entrylogwrapper.go
new file mode 100644
index 000000000..125c05b74
--- /dev/null
+++ b/utils/log/entrylogwrapper.go
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2018 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 log
+
+import (
+ "time"
+
+ "github.com/sirupsen/logrus"
+)
+
+type Entry logrus.Entry
+
+func NewEntry(logger *Logger) *Entry {
+ return &Entry{
+ Logger: (*logrus.Logger)(logger),
+ // Default is five fields, give a little extra room
+ Data: make(logrus.Fields, 5),
+ }
+}
+
+// Returns the string representation from the reader and ultimately the
+// formatter.
+func (entry *Entry) String() (string, error) {
+ return (*logrus.Entry)(entry).String()
+}
+
+// Add an error as single field (using the key defined in ErrorKey) to the Entry.
+func (entry *Entry) WithError(err error) *Entry {
+ return (*Entry)((*logrus.Entry)(entry).WithError(err))
+}
+
+// Add a single field to the Entry.
+func (entry *Entry) WithField(key string, value interface{}) *Entry {
+ return (*Entry)((*logrus.Entry)(entry).WithField(key, value))
+}
+
+// Add a map of fields to the Entry.
+func (entry *Entry) WithFields(fields Fields) *Entry {
+ return (*Entry)((*logrus.Entry)(entry).WithFields((logrus.Fields)(fields)))
+}
+
+// Overrides the time of the Entry.
+func (entry *Entry) WithTime(t time.Time) *Entry {
+ return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t}
+}
+
+func (entry *Entry) Debug(args ...interface{}) {
+ (*logrus.Entry)(entry).Debug(args...)
+}
+
+func (entry *Entry) Print(args ...interface{}) {
+ (*logrus.Entry)(entry).Print(args...)
+}
+
+func (entry *Entry) Info(args ...interface{}) {
+ (*logrus.Entry)(entry).Info(args...)
+}
+
+func (entry *Entry) Warn(args ...interface{}) {
+ (*logrus.Entry)(entry).Warn(args...)
+}
+
+func (entry *Entry) Warning(args ...interface{}) {
+ (*logrus.Entry)(entry).Warning(args...)
+}
+
+func (entry *Entry) Error(args ...interface{}) {
+ (*logrus.Entry)(entry).Error(args...)
+}
+
+func (entry *Entry) Fatal(args ...interface{}) {
+ (*logrus.Entry)(entry).Fatal(args...)
+}
+
+func (entry *Entry) Panic(args ...interface{}) {
+ (*logrus.Entry)(entry).Panic(args...)
+}
+
+// Entry Printf family functions
+
+func (entry *Entry) Debugf(format string, args ...interface{}) {
+ (*logrus.Entry)(entry).Debugf(format, args...)
+}
+
+func (entry *Entry) Infof(format string, args ...interface{}) {
+ (*logrus.Entry)(entry).Infof(format, args...)
+}
+
+func (entry *Entry) Printf(format string, args ...interface{}) {
+ (*logrus.Entry)(entry).Printf(format, args...)
+}
+
+func (entry *Entry) Warnf(format string, args ...interface{}) {
+ (*logrus.Entry)(entry).Warnf(format, args...)
+}
+
+func (entry *Entry) Warningf(format string, args ...interface{}) {
+ (*logrus.Entry)(entry).Warningf(format, args...)
+}
+
+func (entry *Entry) Errorf(format string, args ...interface{}) {
+ (*logrus.Entry)(entry).Errorf(format, args...)
+}
+
+func (entry *Entry) Fatalf(format string, args ...interface{}) {
+ (*logrus.Entry)(entry).Fatalf(format, args...)
+}
+
+func (entry *Entry) Panicf(format string, args ...interface{}) {
+ (*logrus.Entry)(entry).Panicf(format, args...)
+}
+
+// Entry Println family functions
+
+func (entry *Entry) Debugln(args ...interface{}) {
+ (*logrus.Entry)(entry).Debugln(args...)
+}
+
+func (entry *Entry) Infoln(args ...interface{}) {
+ (*logrus.Entry)(entry).Infoln(args...)
+}
+
+func (entry *Entry) Println(args ...interface{}) {
+ (*logrus.Entry)(entry).Println(args...)
+}
+
+func (entry *Entry) Warnln(args ...interface{}) {
+ (*logrus.Entry)(entry).Warnln(args...)
+}
+
+func (entry *Entry) Warningln(args ...interface{}) {
+ (*logrus.Entry)(entry).Warningln(args...)
+}
+
+func (entry *Entry) Errorln(args ...interface{}) {
+ (*logrus.Entry)(entry).Errorln(args...)
+}
+
+func (entry *Entry) Fatalln(args ...interface{}) {
+ (*logrus.Entry)(entry).Fatalln(args...)
+}
+
+func (entry *Entry) Panicln(args ...interface{}) {
+ (*logrus.Entry)(entry).Panicln(args...)
+}
diff --git a/utils/log/logwrapper.go b/utils/log/logwrapper.go
index a013cfcb4..3c32421f5 100644
--- a/utils/log/logwrapper.go
+++ b/utils/log/logwrapper.go
@@ -22,6 +22,7 @@ import (
"path/filepath"
"runtime"
"strings"
+ "time"
"github.com/sirupsen/logrus"
)
@@ -49,6 +50,7 @@ const (
// if package name exists and log level is more verbose, the log will be dropped
var PkgDebugLogFilter = map[string]logrus.Level{
"metric": InfoLevel,
+ "rpc": InfoLevel,
}
// Logger wraps logrus logger type.
@@ -58,11 +60,28 @@ type Logger logrus.Logger
type Fields logrus.Fields
// CallerHook defines caller awareness hook for logrus.
-type CallerHook struct{}
+type CallerHook struct {
+ StackLevels []logrus.Level
+}
+
+// NewCallerHook creates new CallerHook
+func NewCallerHook(stackLevels []logrus.Level) *CallerHook {
+ return &CallerHook{
+ StackLevels: stackLevels,
+ }
+}
+
+// StandardCallerHook is a convenience initializer for LogrusStackHook{} with
+// default args.
+func StandardCallerHook() *CallerHook {
+ return NewCallerHook(
+ []logrus.Level{logrus.PanicLevel, logrus.FatalLevel, logrus.ErrorLevel},
+ )
+}
// Fire defines hook event handler.
func (hook *CallerHook) Fire(entry *logrus.Entry) error {
- funcDesc, caller := hook.caller()
+ funcDesc, caller := hook.caller(entry)
fields := strings.SplitN(funcDesc, ".", 2)
if len(fields) > 0 {
level, ok := PkgDebugLogFilter[fields[0]]
@@ -89,27 +108,61 @@ func (hook *CallerHook) Levels() []logrus.Level {
}
}
-func (hook *CallerHook) caller() (relFuncName, caller string) {
- var (
- file = "unknown"
- line = 0
- ok = false
- funcName = "unknown"
- pc uintptr
- )
- pc, file, line, ok = runtime.Caller(10)
- details := runtime.FuncForPC(pc)
- if ok && details != nil {
- funcName = details.Name()
+func (hook *CallerHook) caller(entry *logrus.Entry) (relFuncName, caller string) {
+ var skipFrames int
+ if len(entry.Data) == 0 {
+ // When WithField(s) is not used, we have 8 logrus frames to skip.
+ skipFrames = 8
+ } else {
+ // When WithField(s) is used, we have 6 logrus frames to skip.
+ skipFrames = 6
}
- relFuncName = strings.TrimPrefix(funcName, "github.com/CovenantSQL/CovenantSQL/")
- funcLocation := fmt.Sprintf("%s:%d %s", filepath.Base(file), line, relFuncName)
- return relFuncName, funcLocation
+ pcs := make([]uintptr, 12)
+ stacks := make([]runtime.Frame, 0, 12)
+ if runtime.Callers(skipFrames, pcs) > 0 {
+ var foundCaller bool
+ _frames := runtime.CallersFrames(pcs)
+ for {
+ f, more := _frames.Next()
+ //fmt.Printf("%s:%d %s\n", f.File, f.Line, f.Function)
+ if !foundCaller && strings.HasSuffix(f.File, "logwrapper.go") && more {
+ f, _ = _frames.Next()
+ relFuncName = strings.TrimPrefix(f.Function, "github.com/CovenantSQL/CovenantSQL/")
+ caller = fmt.Sprintf("%s:%d %s", filepath.Base(f.File), f.Line, relFuncName)
+ foundCaller = true
+ }
+ if foundCaller {
+ stacks = append(stacks, f)
+ }
+ if !more {
+ break
+ }
+ }
+ }
+
+ if len(stacks) > 0 {
+ for _, level := range hook.StackLevels {
+ if entry.Level == level {
+ stacksStr := make([]string, 0, len(stacks))
+ for i, s := range stacks {
+ if s.Line > 0 {
+ fName := strings.TrimPrefix(s.Function, "github.com/CovenantSQL/CovenantSQL/")
+ stackStr := fmt.Sprintf("#%d %s@%s:%d ", i, fName, filepath.Base(s.File), s.Line)
+ stacksStr = append(stacksStr, stackStr)
+ }
+ }
+ entry.Data["stack"] = stacksStr
+ break
+ }
+ }
+ }
+
+ return relFuncName, caller
}
func init() {
- AddHook(&CallerHook{})
+ AddHook(StandardCallerHook())
}
//var (
@@ -148,8 +201,8 @@ func AddHook(hook logrus.Hook) {
}
// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key.
-func WithError(err error) *logrus.Entry {
- return logrus.WithField(logrus.ErrorKey, err)
+func WithError(err error) *Entry {
+ return WithField(logrus.ErrorKey, err)
}
// WithField creates an entry from the standard logger and adds a field to
@@ -157,8 +210,8 @@ func WithError(err error) *logrus.Entry {
//
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
// or Panic on the Entry it returns.
-func WithField(key string, value interface{}) *logrus.Entry {
- return logrus.WithField(key, value)
+func WithField(key string, value interface{}) *Entry {
+ return (*Entry)(logrus.WithField(key, value))
}
// WithFields creates an entry from the standard logger and adds multiple
@@ -167,8 +220,12 @@ func WithField(key string, value interface{}) *logrus.Entry {
//
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
// or Panic on the Entry it returns.
-func WithFields(fields Fields) *logrus.Entry {
- return logrus.WithFields(logrus.Fields(fields))
+func WithFields(fields Fields) *Entry {
+ return (*Entry)(logrus.WithFields(logrus.Fields(fields)))
+}
+
+func WithTime(t time.Time) *Entry {
+ return (*Entry)(logrus.WithTime(t))
}
// Debug logs a message at level Debug on the standard logger.
@@ -219,6 +276,11 @@ func Debugf(format string, args ...interface{}) {
logrus.Debugf(format, args...)
}
+// Printf logs a message at level Info on the standard logger.
+func (l *Logger) Printf(format string, args ...interface{}) {
+ Printf(format, args...)
+}
+
// Printf logs a message at level Info on the standard logger.
func Printf(format string, args ...interface{}) {
logrus.Printf(format, args...)
diff --git a/utils/log/logwrapper_test.go b/utils/log/logwrapper_test.go
new file mode 100644
index 000000000..acc6dfc0d
--- /dev/null
+++ b/utils/log/logwrapper_test.go
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2018 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 log
+
+import (
+ "fmt"
+ "testing"
+ "time"
+
+ "github.com/pkg/errors"
+
+ "github.com/sirupsen/logrus"
+)
+
+func init() {
+ AddHook(&CallerHook{})
+}
+
+func TestStandardLogger(t *testing.T) {
+ SetLevel(DebugLevel)
+ if GetLevel() != DebugLevel {
+ t.Fail()
+ }
+ Debug("Debug")
+ Debugln("Debugln")
+ Debugf("Debugf %d", 1)
+ Print("Print")
+ Println("Println")
+ Printf("Printf %d", 1)
+ Info("Info")
+ Infoln("Infoln")
+ Infof("Infof %d", 1)
+ Warning("Warning")
+ Warningln("Warningln")
+ Warningf("Warningf %d", 1)
+ Warn("Warn")
+ Warnln("Warnln")
+ Warnln("Warnln")
+ Warnf("Warnf %d", 1)
+ Error("Error")
+ Errorln("Errorln")
+ Errorf("Errorf %d", 1)
+ defer func() {
+ if r := recover(); r != nil {
+ fmt.Println("Recovered in f", r)
+ }
+ defer func() {
+ if r := recover(); r != nil {
+ fmt.Println("Recovered in f", r)
+ }
+ defer func() {
+ if r := recover(); r != nil {
+ fmt.Println("Recovered in f", r)
+ }
+ n := NilFormatter{}
+ a, b := n.Format(&logrus.Entry{})
+ if a != nil || b != nil {
+ t.Fail()
+ }
+ }()
+ Panicf("Panicf %d", 1)
+ }()
+ Panicln("Panicln")
+
+ }()
+
+ Panic("Panic")
+
+}
+
+func call0() {
+ call1()
+}
+
+func call1() {
+ call2()
+}
+
+func call2() {
+ WithField("k", "v").Error("Error")
+ Error("call2 error")
+}
+
+func TestWithField(t *testing.T) {
+ SetLevel(DebugLevel)
+ if GetLevel() != DebugLevel {
+ t.Fail()
+ }
+
+ call0()
+
+ f := new(Fields)
+ WithError(errors.New("new")).WithFields(*f).WithTime(time.Now()).Debug("Debug")
+
+ WithFields(*f).Debug("Debug")
+ WithTime(time.Now()).WithError(errors.New("new")).Debug("Debug")
+ NewEntry(StandardLogger()).WithTime(time.Now()).String()
+
+ WithField("k", "v").Debug("Debug")
+ WithField("k", "v").Debugln("Debugln")
+ WithField("k", "v").Debugf("Debugf %d", 1)
+ WithField("k", "v").Print("Print")
+ WithField("k", "v").Println("Println")
+ WithField("k", "v").Printf("Printf %d", 1)
+ WithField("k", "v").Info("Info")
+ WithField("k", "v").Infoln("Infoln")
+ WithField("k", "v").Infof("Infof %d", 1)
+ WithField("k", "v").Warning("Warning")
+ WithField("k", "v").Warningln("Warningln")
+ WithField("k", "v").Warningf("Warningf %d", 1)
+ WithField("k", "v").Warn("Warn")
+ WithField("k", "v").Warnln("Warnln")
+ WithField("k", "v").Warnln("Warnln")
+ WithField("k", "v").Warnf("Warnf %d", 1)
+ WithField("k", "v").Error("Error")
+ WithField("k", "v").Errorln("Errorln")
+ WithField("k", "v").Errorf("Errorf %d", 1)
+ defer func() {
+ if r := recover(); r != nil {
+ fmt.Println("Recovered in f", r)
+ }
+ defer func() {
+ if r := recover(); r != nil {
+ fmt.Println("Recovered in f", r)
+ }
+ defer func() {
+ if r := recover(); r != nil {
+ fmt.Println("Recovered in f", r)
+ }
+ n := NilFormatter{}
+ a, b := n.Format(&logrus.Entry{})
+ if a != nil || b != nil {
+ t.Fail()
+ }
+ }()
+ WithField("k", "v").Panicf("Panicf %d", 1)
+ }()
+ WithField("k", "v").Panicln("Panicln")
+ }()
+
+ WithField("k", "v").Panic("Panic")
+}
diff --git a/utils/msgpack.go b/utils/msgpack.go
index fdaa89b64..f443c9184 100644
--- a/utils/msgpack.go
+++ b/utils/msgpack.go
@@ -18,39 +18,56 @@ package utils
import (
"bytes"
+ "net"
+ "net/rpc"
+ "reflect"
"github.com/ugorji/go/codec"
)
-// DecodeMsgPack reverses the encode operation on a byte slice input.
-func DecodeMsgPack(buf []byte, out interface{}) error {
- r := bytes.NewBuffer(buf)
- hd := codec.MsgpackHandle{
+var (
+ msgPackHandle = &codec.MsgpackHandle{
WriteExt: true,
RawToString: true,
}
- dec := codec.NewDecoder(r, &hd)
+)
+
+// RegisterInterfaceToMsgPack binds interface decode/encode to specified implementation.
+func RegisterInterfaceToMsgPack(intf, impl reflect.Type) (err error) {
+ return msgPackHandle.Intf2Impl(intf, impl)
+}
+
+// DecodeMsgPack reverses the encode operation on a byte slice input.
+func DecodeMsgPack(buf []byte, out interface{}) error {
+ r := bytes.NewBuffer(buf)
+ dec := codec.NewDecoder(r, msgPackHandle)
return dec.Decode(out)
}
// DecodeMsgPackPlain reverses the encode operation on a byte slice input without RawToString setting.
func DecodeMsgPackPlain(buf []byte, out interface{}) error {
r := bytes.NewBuffer(buf)
- hd := codec.MsgpackHandle{
+ hd := &codec.MsgpackHandle{
WriteExt: true,
}
- dec := codec.NewDecoder(r, &hd)
+ dec := codec.NewDecoder(r, hd)
return dec.Decode(out)
}
// EncodeMsgPack writes an encoded object to a new bytes buffer.
func EncodeMsgPack(in interface{}) (*bytes.Buffer, error) {
buf := bytes.NewBuffer(nil)
- hd := codec.MsgpackHandle{
- WriteExt: true,
- RawToString: true,
- }
- enc := codec.NewEncoder(buf, &hd)
+ enc := codec.NewEncoder(buf, msgPackHandle)
err := enc.Encode(in)
return buf, err
}
+
+// GetMsgPackServerCodec returns msgpack server codec for connection.
+func GetMsgPackServerCodec(c net.Conn) rpc.ServerCodec {
+ return codec.MsgpackSpecRpc.ServerCodec(c, msgPackHandle)
+}
+
+// GetMsgPackClientCodec returns msgpack client codec for connection.
+func GetMsgPackClientCodec(c net.Conn) rpc.ClientCodec {
+ return codec.MsgpackSpecRpc.ClientCodec(c, msgPackHandle)
+}
diff --git a/utils/net.go b/utils/net.go
index bad128d16..40c6d7a48 100644
--- a/utils/net.go
+++ b/utils/net.go
@@ -24,6 +24,8 @@ import (
"net"
"sync"
"time"
+
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
)
var (
@@ -34,6 +36,17 @@ var (
allocateLock sync.Mutex
)
+func testPortConnectable(addr string, timeout time.Duration) bool {
+ conn, err := net.DialTimeout("tcp", addr, timeout)
+ if err != nil {
+ log.Infof("test dial to %s failed", addr)
+ return false
+ } else {
+ conn.Close()
+ return true
+ }
+}
+
func testPort(bindAddr string, port int, excludeAllocated bool) bool {
addr := net.JoinHostPort(bindAddr, fmt.Sprint(port))
@@ -51,7 +64,27 @@ func testPort(bindAddr string, port int, excludeAllocated bool) bool {
return true
}
-// WaitForPorts returns only when port is ready or canceled by context.
+// WaitToConnect returns only when port is ready to connect or canceled by context.
+func WaitToConnect(ctx context.Context, bindAddr string, ports []int, interval time.Duration) (err error) {
+ for {
+ continueCheckC:
+ select {
+ case <-ctx.Done():
+ err = ctx.Err()
+ return
+ case <-time.After(interval):
+ for _, port := range ports {
+ addr := net.JoinHostPort(bindAddr, fmt.Sprint(port))
+ if !testPortConnectable(addr, 100*time.Millisecond) {
+ goto continueCheckC
+ }
+ }
+ return
+ }
+ }
+}
+
+// WaitForPorts returns only when port is ready to listen or canceled by context.
func WaitForPorts(ctx context.Context, bindAddr string, ports []int, interval time.Duration) (err error) {
for {
continueCheck:
diff --git a/utils/net_test.go b/utils/net_test.go
index cf458f123..bf7c82157 100644
--- a/utils/net_test.go
+++ b/utils/net_test.go
@@ -17,12 +17,10 @@
package utils
import (
- "testing"
-
- "net"
-
"context"
"fmt"
+ "net"
+ "testing"
"time"
. "github.com/smartystreets/goconvey/convey"
@@ -87,13 +85,21 @@ func TestWaitForPorts(t *testing.T) {
err = WaitForPorts(context.Background(), "127.0.0.1", ports, time.Millisecond*100)
So(err, ShouldBeNil)
+ ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*300)
+ defer cancel()
+ err = WaitToConnect(ctx, "127.0.0.1", ports, time.Millisecond*100)
+ So(err, ShouldNotBeNil)
+
// listen
ln, err := net.Listen("tcp", net.JoinHostPort("127.0.0.1", fmt.Sprint(ports[0])))
So(ln, ShouldNotBeNil)
So(err, ShouldBeNil)
defer ln.Close()
- ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*300)
+ err = WaitToConnect(context.Background(), "127.0.0.1", ports, time.Millisecond*100)
+ So(err, ShouldBeNil)
+
+ ctx, cancel = context.WithTimeout(context.Background(), time.Millisecond*300)
defer cancel()
err = WaitForPorts(ctx, "127.0.0.1", ports, time.Millisecond*100)
So(err, ShouldNotBeNil)
diff --git a/utils/path_test.go b/utils/path_test.go
index c2363a593..b0c4fa8b3 100644
--- a/utils/path_test.go
+++ b/utils/path_test.go
@@ -17,11 +17,9 @@
package utils
import (
- "testing"
-
"io/ioutil"
-
"os"
+ "testing"
. "github.com/smartystreets/goconvey/convey"
)
diff --git a/utils/profiler.go b/utils/profiler.go
index 369355437..013dd3e7c 100644
--- a/utils/profiler.go
+++ b/utils/profiler.go
@@ -34,10 +34,10 @@ func StartProfile(cpuprofile, memprofile string) error {
if cpuprofile != "" {
f, err := os.Create(cpuprofile)
if err != nil {
- log.Errorf("failed to create CPU profile file at %s: %s", cpuprofile, err.Error())
+ log.WithField("file", cpuprofile).WithError(err).Error("failed to create CPU profile file")
return err
}
- log.Infof("writing CPU profile to: %s\n", cpuprofile)
+ log.WithField("file", cpuprofile).Info("writing CPU profiling to file")
prof.cpu = f
pprof.StartCPUProfile(prof.cpu)
}
@@ -45,10 +45,10 @@ func StartProfile(cpuprofile, memprofile string) error {
if memprofile != "" {
f, err := os.Create(memprofile)
if err != nil {
- log.Errorf("failed to create memory profile file at %s: %s", cpuprofile, err.Error())
+ log.WithField("file", memprofile).WithError(err).Error("failed to create memory profile file")
return err
}
- log.Infof("writing memory profile to: %s\n", memprofile)
+ log.WithField("file", cpuprofile).WithError(err).Info("writing memory profiling to file")
prof.mem = f
runtime.MemProfileRate = 4096
}
@@ -60,11 +60,11 @@ func StopProfile() {
if prof.cpu != nil {
pprof.StopCPUProfile()
prof.cpu.Close()
- log.Infof("CPU profiling stopped")
+ log.Info("CPU profiling stopped")
}
if prof.mem != nil {
pprof.Lookup("heap").WriteTo(prof.mem, 0)
prof.mem.Close()
- log.Infof("memory profiling stopped")
+ log.Info("memory profiling stopped")
}
}
diff --git a/utils/profiler_test.go b/utils/profiler_test.go
index aeba66718..80bc8b9ee 100644
--- a/utils/profiler_test.go
+++ b/utils/profiler_test.go
@@ -17,9 +17,8 @@
package utils
import (
- "testing"
-
"os"
+ "testing"
. "github.com/smartystreets/goconvey/convey"
)
diff --git a/vendor/github.com/CovenantSQL/sqlparser/sql.go b/vendor/github.com/CovenantSQL/sqlparser/sql.go
index 553226726..54f4cdef6 100644
--- a/vendor/github.com/CovenantSQL/sqlparser/sql.go
+++ b/vendor/github.com/CovenantSQL/sqlparser/sql.go
@@ -135,90 +135,92 @@ const COMMENT = 57389
const NULL = 57390
const TRUE = 57391
const FALSE = 57392
-const OR = 57393
-const AND = 57394
-const NOT = 57395
-const BETWEEN = 57396
-const CASE = 57397
-const WHEN = 57398
-const THEN = 57399
-const ELSE = 57400
-const END = 57401
-const LE = 57402
-const GE = 57403
-const NE = 57404
-const IS = 57405
-const LIKE = 57406
-const REGEXP = 57407
-const IN = 57408
-const NULL_SAFE_NOTEQUAL = 57409
-const SHIFT_LEFT = 57410
-const SHIFT_RIGHT = 57411
-const DIV = 57412
-const MOD = 57413
-const UNARY = 57414
-const INTERVAL = 57415
-const CREATE = 57416
-const ALTER = 57417
-const DROP = 57418
-const RENAME = 57419
-const ADD = 57420
-const TABLE = 57421
-const INDEX = 57422
-const TO = 57423
-const IGNORE = 57424
-const IF = 57425
-const UNIQUE = 57426
-const PRIMARY = 57427
-const COLUMN = 57428
-const CONSTRAINT = 57429
-const FOREIGN = 57430
-const SHOW = 57431
-const DESCRIBE = 57432
-const DATE = 57433
-const ESCAPE = 57434
-const TINYINT = 57435
-const SMALLINT = 57436
-const MEDIUMINT = 57437
-const INT = 57438
-const INTEGER = 57439
-const BIGINT = 57440
-const INTNUM = 57441
-const REAL = 57442
-const DOUBLE = 57443
-const FLOAT_TYPE = 57444
-const DECIMAL = 57445
-const NUMERIC = 57446
-const TIME = 57447
-const TIMESTAMP = 57448
-const DATETIME = 57449
-const YEAR = 57450
-const CHAR = 57451
-const VARCHAR = 57452
-const BOOL = 57453
-const NCHAR = 57454
-const TEXT = 57455
-const TINYTEXT = 57456
-const MEDIUMTEXT = 57457
-const LONGTEXT = 57458
-const BLOB = 57459
-const TINYBLOB = 57460
-const MEDIUMBLOB = 57461
-const LONGBLOB = 57462
-const AUTO_INCREMENT = 57463
-const SIGNED = 57464
-const UNSIGNED = 57465
-const ZEROFILL = 57466
-const TABLES = 57467
-const CURRENT_TIMESTAMP = 57468
-const CURRENT_DATE = 57469
-const CURRENT_TIME = 57470
-const REPLACE = 57471
-const CAST = 57472
-const SUBSTR = 57473
-const GROUP_CONCAT = 57474
-const SEPARATOR = 57475
-const UNUSED = 57476
+const FULL = 57393
+const COLUMNS = 57394
+const OR = 57395
+const AND = 57396
+const NOT = 57397
+const BETWEEN = 57398
+const CASE = 57399
+const WHEN = 57400
+const THEN = 57401
+const ELSE = 57402
+const END = 57403
+const LE = 57404
+const GE = 57405
+const NE = 57406
+const IS = 57407
+const LIKE = 57408
+const REGEXP = 57409
+const IN = 57410
+const NULL_SAFE_NOTEQUAL = 57411
+const SHIFT_LEFT = 57412
+const SHIFT_RIGHT = 57413
+const DIV = 57414
+const MOD = 57415
+const UNARY = 57416
+const INTERVAL = 57417
+const CREATE = 57418
+const ALTER = 57419
+const DROP = 57420
+const RENAME = 57421
+const ADD = 57422
+const TABLE = 57423
+const INDEX = 57424
+const TO = 57425
+const IGNORE = 57426
+const IF = 57427
+const UNIQUE = 57428
+const PRIMARY = 57429
+const COLUMN = 57430
+const CONSTRAINT = 57431
+const FOREIGN = 57432
+const SHOW = 57433
+const DESCRIBE = 57434
+const DATE = 57435
+const ESCAPE = 57436
+const TINYINT = 57437
+const SMALLINT = 57438
+const MEDIUMINT = 57439
+const INT = 57440
+const INTEGER = 57441
+const BIGINT = 57442
+const INTNUM = 57443
+const REAL = 57444
+const DOUBLE = 57445
+const FLOAT_TYPE = 57446
+const DECIMAL = 57447
+const NUMERIC = 57448
+const TIME = 57449
+const TIMESTAMP = 57450
+const DATETIME = 57451
+const YEAR = 57452
+const CHAR = 57453
+const VARCHAR = 57454
+const BOOL = 57455
+const NCHAR = 57456
+const TEXT = 57457
+const TINYTEXT = 57458
+const MEDIUMTEXT = 57459
+const LONGTEXT = 57460
+const BLOB = 57461
+const TINYBLOB = 57462
+const MEDIUMBLOB = 57463
+const LONGBLOB = 57464
+const AUTO_INCREMENT = 57465
+const SIGNED = 57466
+const UNSIGNED = 57467
+const ZEROFILL = 57468
+const TABLES = 57469
+const CURRENT_TIMESTAMP = 57470
+const CURRENT_DATE = 57471
+const CURRENT_TIME = 57472
+const REPLACE = 57473
+const CAST = 57474
+const SUBSTR = 57475
+const GROUP_CONCAT = 57476
+const SEPARATOR = 57477
+const UNUSED = 57478
var yyToknames = [...]string{
"$end",
@@ -274,6 +276,8 @@ var yyToknames = [...]string{
"NULL",
"TRUE",
"FALSE",
+ "FULL",
+ "COLUMNS",
"OR",
"AND",
"NOT",
@@ -388,400 +392,391 @@ var yyExca = [...]int{
-1, 3,
5, 17,
-2, 4,
- -1, 113,
- 1, 153,
- 5, 153,
- 11, 153,
- 12, 153,
- 13, 153,
- 14, 153,
- 16, 153,
- 27, 153,
- 30, 153,
- 31, 153,
- 33, 153,
- 35, 153,
- 36, 153,
- 37, 153,
- 38, 153,
- 40, 153,
- 41, 153,
- 152, 153,
- -2, 166,
- -1, 180,
- 90, 353,
- -2, 349,
- -1, 181,
- 90, 354,
- -2, 350,
- -1, 398,
- 5, 17,
- -2, 322,
- -1, 514,
- 90, 356,
+ -1, 114,
+ 1, 156,
+ 5, 156,
+ 11, 156,
+ 12, 156,
+ 13, 156,
+ 14, 156,
+ 16, 156,
+ 27, 156,
+ 30, 156,
+ 31, 156,
+ 33, 156,
+ 35, 156,
+ 36, 156,
+ 37, 156,
+ 38, 156,
+ 40, 156,
+ 41, 156,
+ 154, 156,
+ -2, 169,
+ -1, 183,
+ 92, 356,
-2, 352,
- -1, 546,
- 5, 18,
- -2, 225,
- -1, 604,
- 5, 18,
- -2, 323,
- -1, 669,
+ -1, 184,
+ 92, 357,
+ -2, 353,
+ -1, 402,
5, 17,
-2, 325,
- -1, 726,
+ -1, 519,
+ 92, 359,
+ -2, 355,
+ -1, 551,
+ 5, 18,
+ -2, 228,
+ -1, 609,
5, 18,
-2, 326,
+ -1, 672,
+ 5, 17,
+ -2, 328,
+ -1, 732,
+ 5, 18,
+ -2, 329,
}
const yyPrivate = 57344
-const yyLast = 3998
+const yyLast = 4079
var yyAct = [...]int{
- 181, 377, 618, 133, 529, 425, 455, 509, 333, 530,
- 139, 98, 31, 582, 426, 424, 484, 402, 521, 46,
- 165, 469, 203, 93, 93, 118, 331, 541, 436, 204,
- 3, 421, 513, 460, 167, 430, 131, 183, 93, 44,
- 144, 207, 194, 451, 401, 30, 110, 709, 135, 561,
- 443, 511, 109, 622, 699, 96, 623, 624, 625, 697,
- 108, 681, 461, 626, 24, 26, 15, 16, 462, 125,
- 86, 122, 106, 461, 438, 88, 87, 255, 635, 84,
- 85, 22, 120, 127, 93, 250, 249, 713, 83, 93,
- 638, 555, 607, 589, 539, 473, 376, 28, 350, 351,
- 352, 353, 354, 355, 356, 349, 93, 130, 136, 184,
- 349, 335, 124, 337, 185, 93, 93, 93, 538, 168,
- 25, 89, 93, 664, 522, 93, 337, 93, 93, 491,
- 522, 93, 596, 186, 146, 440, 248, 682, 680, 438,
- 441, 97, 489, 490, 488, 25, 437, 340, 339, 18,
- 19, 20, 115, 103, 559, 627, 119, 114, 370, 371,
- 372, 373, 374, 256, 21, 23, 258, 684, 477, 479,
- 480, 338, 113, 478, 28, 90, 94, 378, 575, 576,
- 577, 384, 444, 330, 487, 336, 335, 336, 335, 93,
- 394, 190, 683, 93, 93, 93, 93, 393, 126, 564,
- 563, 337, 93, 337, 27, 562, 93, 417, 418, 93,
- 725, 437, 404, 46, 620, 435, 434, 398, 714, 715,
- 591, 677, 676, 25, 352, 353, 354, 355, 356, 349,
- 391, 392, 403, 429, 205, 419, 123, 336, 335, 431,
- 407, 129, 409, 415, 666, 406, 119, 408, 556, 113,
- 420, 507, 457, 337, 336, 335, 93, 246, 189, 134,
- 367, 369, 336, 335, 466, 134, 631, 630, 720, 211,
- 337, 606, 134, 719, 247, 628, 368, 251, 337, 253,
- 254, 515, 134, 24, 463, 375, 453, 454, 379, 380,
- 381, 382, 32, 385, 192, 134, 467, 386, 387, 388,
- 24, 213, 212, 196, 199, 668, 197, 399, 198, 200,
- 542, 543, 114, 114, 114, 114, 28, 422, 466, 191,
- 515, 396, 397, 602, 192, 205, 466, 113, 113, 113,
- 113, 629, 192, 28, 46, 537, 592, 24, 466, 549,
- 113, 400, 389, 28, 474, 475, 537, 481, 482, 445,
- 456, 613, 483, 552, 471, 492, 493, 494, 495, 496,
- 497, 498, 499, 500, 501, 502, 503, 504, 505, 506,
- 28, 542, 543, 196, 199, 46, 197, 485, 198, 200,
- 452, 516, 458, 40, 12, 545, 412, 411, 378, 517,
- 413, 512, 414, 199, 410, 508, 558, 429, 184, 718,
- 46, 717, 404, 446, 447, 553, 404, 459, 464, 419,
- 252, 202, 514, 132, 448, 449, 450, 404, 102, 519,
- 535, 104, 518, 546, 99, 46, 523, 527, 688, 533,
- 550, 548, 531, 536, 547, 100, 544, 403, 524, 525,
- 526, 528, 32, 687, 35, 429, 348, 347, 357, 358,
- 350, 351, 352, 353, 354, 355, 356, 349, 637, 93,
- 37, 38, 422, 93, 554, 128, 116, 34, 93, 95,
- 36, 46, 29, 1, 617, 433, 423, 486, 117, 39,
- 583, 432, 679, 621, 404, 439, 566, 560, 512, 25,
- 571, 471, 572, 570, 429, 442, 557, 569, 216, 379,
- 579, 580, 581, 217, 568, 578, 574, 215, 219, 514,
- 218, 585, 214, 586, 646, 632, 201, 532, 206, 25,
- 468, 41, 121, 485, 590, 366, 105, 598, 599, 600,
- 601, 597, 674, 534, 390, 182, 603, 604, 605, 595,
- 686, 378, 636, 594, 383, 520, 145, 610, 476, 608,
- 46, 612, 46, 46, 611, 609, 155, 616, 404, 614,
- 429, 152, 587, 154, 153, 615, 46, 142, 395, 341,
- 429, 593, 429, 619, 143, 514, 137, 112, 403, 187,
- 634, 195, 193, 540, 111, 465, 429, 114, 708, 14,
- 46, 643, 33, 639, 641, 642, 644, 107, 11, 10,
- 17, 9, 113, 662, 645, 665, 663, 46, 46, 8,
- 429, 565, 667, 7, 46, 567, 46, 6, 5, 4,
- 673, 550, 166, 486, 101, 13, 2, 671, 672, 0,
- 0, 0, 588, 0, 675, 669, 429, 531, 0, 46,
- 0, 0, 0, 0, 0, 91, 91, 0, 691, 0,
- 692, 690, 0, 645, 0, 0, 404, 695, 0, 429,
- 91, 0, 0, 0, 0, 0, 706, 0, 0, 0,
- 0, 0, 0, 711, 0, 710, 685, 0, 46, 0,
- 716, 0, 0, 0, 0, 633, 0, 0, 0, 0,
- 722, 0, 0, 0, 0, 0, 721, 378, 619, 0,
- 712, 0, 0, 531, 0, 0, 91, 0, 0, 0,
- 0, 91, 724, 0, 46, 46, 726, 0, 723, 0,
- 0, 0, 532, 0, 0, 670, 0, 729, 91, 0,
- 0, 0, 0, 0, 727, 728, 0, 91, 209, 91,
- 0, 0, 0, 0, 91, 0, 0, 91, 0, 91,
- 91, 0, 0, 257, 334, 230, 0, 235, 236, 237,
- 238, 239, 240, 0, 241, 242, 243, 244, 245, 231,
- 232, 233, 234, 220, 221, 0, 0, 222, 223, 224,
- 225, 226, 227, 228, 229, 0, 0, 0, 532, 0,
- 25, 347, 357, 358, 350, 351, 352, 353, 354, 355,
- 356, 349, 678, 0, 0, 0, 0, 0, 0, 0,
- 0, 91, 0, 0, 405, 91, 91, 91, 91, 0,
- 0, 0, 0, 0, 416, 0, 0, 0, 91, 0,
- 693, 209, 694, 0, 696, 0, 698, 0, 700, 701,
- 702, 703, 704, 705, 323, 314, 293, 325, 274, 285,
- 329, 286, 287, 308, 265, 301, 67, 0, 277, 261,
- 283, 262, 275, 295, 298, 273, 316, 327, 59, 297,
- 299, 313, 292, 309, 268, 303, 306, 326, 91, 0,
- 0, 45, 0, 427, 428, 0, 0, 0, 0, 0,
- 305, 322, 284, 307, 260, 304, 0, 264, 266, 328,
- 320, 280, 281, 551, 0, 0, 0, 0, 0, 296,
- 300, 310, 290, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 278, 0, 302, 0, 0, 0, 294, 0,
- 267, 0, 279, 311, 259, 318, 291, 321, 289, 288,
- 324, 68, 0, 0, 56, 317, 276, 51, 282, 76,
- 71, 63, 57, 58, 47, 0, 69, 54, 55, 53,
- 66, 73, 74, 52, 81, 50, 80, 49, 65, 72,
- 77, 64, 61, 48, 75, 62, 60, 263, 70, 78,
- 82, 319, 271, 269, 270, 312, 0, 272, 0, 315,
- 79, 0, 0, 0, 0, 0, 0, 0, 334, 257,
- 0, 0, 0, 0, 405, 0, 67, 0, 405, 334,
- 334, 334, 0, 0, 0, 0, 0, 0, 59, 405,
- 0, 0, 0, 0, 343, 0, 346, 0, 0, 0,
- 0, 45, 359, 360, 361, 362, 363, 364, 0, 344,
- 345, 342, 365, 348, 347, 357, 358, 350, 351, 352,
- 353, 354, 355, 356, 349, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 348, 347, 357, 358, 350, 351,
- 352, 353, 354, 355, 356, 349, 0, 0, 0, 0,
- 0, 91, 0, 0, 0, 91, 405, 0, 0, 334,
- 91, 68, 0, 0, 56, 0, 257, 51, 0, 76,
+ 184, 381, 623, 136, 534, 429, 459, 514, 337, 535,
+ 142, 99, 31, 587, 428, 434, 207, 3, 406, 46,
+ 168, 526, 518, 94, 94, 489, 474, 147, 170, 440,
+ 405, 206, 119, 464, 546, 430, 335, 455, 94, 44,
+ 425, 210, 97, 186, 197, 134, 30, 111, 715, 138,
+ 132, 516, 566, 116, 110, 447, 627, 628, 629, 630,
+ 705, 122, 703, 466, 631, 684, 465, 123, 465, 109,
+ 126, 107, 638, 442, 84, 85, 91, 95, 121, 258,
+ 253, 252, 719, 128, 94, 83, 641, 353, 90, 94,
+ 560, 352, 351, 361, 362, 354, 355, 356, 357, 358,
+ 359, 360, 353, 612, 594, 125, 667, 94, 544, 139,
+ 187, 478, 380, 133, 341, 188, 94, 94, 94, 171,
+ 25, 189, 543, 94, 527, 588, 94, 86, 94, 94,
+ 340, 339, 88, 87, 94, 251, 339, 124, 527, 131,
+ 601, 444, 130, 685, 683, 25, 341, 441, 445, 262,
+ 344, 341, 448, 104, 496, 442, 260, 115, 632, 98,
+ 192, 374, 375, 376, 377, 378, 564, 494, 495, 493,
+ 193, 214, 120, 580, 581, 582, 250, 687, 686, 254,
+ 382, 256, 257, 249, 388, 569, 334, 24, 26, 15,
+ 16, 127, 94, 398, 568, 596, 94, 94, 94, 94,
+ 397, 340, 339, 28, 22, 94, 567, 402, 669, 94,
+ 421, 422, 94, 492, 731, 408, 46, 341, 720, 721,
+ 28, 625, 407, 137, 25, 423, 726, 395, 396, 441,
+ 120, 340, 339, 439, 438, 208, 433, 356, 357, 358,
+ 359, 360, 353, 561, 411, 404, 413, 341, 419, 435,
+ 410, 512, 412, 424, 462, 461, 680, 679, 725, 94,
+ 94, 340, 339, 371, 373, 354, 355, 356, 357, 358,
+ 359, 360, 353, 633, 18, 19, 20, 341, 471, 137,
+ 343, 636, 635, 457, 458, 611, 137, 467, 379, 21,
+ 23, 383, 384, 385, 386, 520, 389, 482, 484, 485,
+ 390, 391, 392, 342, 483, 520, 137, 195, 137, 607,
+ 403, 195, 468, 469, 32, 115, 115, 115, 115, 340,
+ 339, 216, 215, 472, 24, 426, 634, 542, 208, 27,
+ 597, 471, 554, 393, 194, 341, 199, 202, 46, 200,
+ 471, 201, 203, 547, 548, 400, 401, 195, 479, 480,
+ 24, 486, 487, 471, 542, 28, 488, 28, 476, 497,
+ 498, 499, 500, 501, 502, 503, 504, 505, 506, 507,
+ 508, 509, 510, 511, 449, 490, 450, 451, 460, 46,
+ 618, 24, 557, 28, 664, 521, 456, 452, 453, 454,
+ 547, 548, 382, 522, 40, 570, 519, 418, 202, 513,
+ 423, 433, 187, 671, 46, 12, 408, 416, 550, 415,
+ 408, 417, 414, 523, 28, 563, 517, 528, 724, 723,
+ 538, 408, 558, 463, 540, 255, 205, 551, 407, 46,
+ 536, 533, 524, 135, 555, 553, 105, 532, 552, 103,
+ 100, 694, 529, 530, 531, 101, 541, 549, 32, 433,
+ 651, 693, 660, 661, 662, 659, 426, 663, 640, 259,
+ 129, 117, 653, 34, 656, 658, 652, 94, 650, 559,
+ 36, 654, 29, 94, 199, 202, 46, 200, 1, 201,
+ 203, 655, 657, 89, 622, 437, 427, 118, 408, 39,
+ 149, 436, 682, 25, 519, 573, 476, 571, 626, 433,
+ 443, 579, 577, 383, 576, 584, 585, 586, 575, 565,
+ 446, 574, 562, 219, 517, 220, 590, 218, 591, 583,
+ 572, 537, 490, 25, 222, 221, 217, 649, 114, 595,
+ 688, 204, 603, 604, 605, 606, 602, 209, 473, 41,
+ 370, 608, 609, 610, 106, 677, 382, 600, 539, 394,
+ 185, 692, 615, 639, 613, 46, 617, 46, 46, 599,
+ 519, 614, 621, 408, 619, 433, 387, 592, 525, 620,
+ 407, 94, 148, 481, 158, 433, 598, 433, 624, 155,
+ 616, 351, 361, 362, 354, 355, 356, 357, 358, 359,
+ 360, 353, 115, 157, 156, 46, 646, 145, 642, 644,
+ 645, 647, 399, 345, 146, 140, 114, 113, 665, 190,
+ 668, 666, 46, 46, 198, 433, 196, 670, 545, 46,
+ 112, 46, 470, 714, 637, 676, 555, 672, 14, 33,
+ 648, 108, 674, 675, 11, 372, 536, 593, 46, 678,
+ 35, 433, 46, 10, 17, 9, 8, 169, 7, 6,
+ 5, 697, 4, 698, 696, 102, 37, 38, 433, 408,
+ 701, 13, 433, 2, 0, 96, 691, 713, 137, 712,
+ 92, 92, 0, 690, 0, 0, 717, 648, 716, 0,
+ 0, 46, 0, 722, 0, 92, 114, 114, 114, 114,
+ 718, 0, 0, 0, 0, 0, 728, 0, 0, 114,
+ 536, 624, 727, 382, 352, 351, 361, 362, 354, 355,
+ 356, 357, 358, 359, 360, 353, 0, 0, 730, 0,
+ 46, 46, 732, 0, 729, 0, 0, 537, 0, 0,
+ 673, 92, 0, 735, 0, 0, 92, 0, 0, 0,
+ 733, 734, 352, 351, 361, 362, 354, 355, 356, 357,
+ 358, 359, 360, 353, 92, 0, 0, 689, 0, 0,
+ 0, 0, 0, 92, 212, 92, 0, 0, 0, 0,
+ 92, 0, 0, 92, 0, 92, 92, 681, 0, 0,
+ 0, 261, 338, 137, 0, 0, 0, 0, 0, 0,
+ 0, 537, 0, 25, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 699, 0, 700, 0, 702, 0, 704,
+ 0, 706, 707, 708, 709, 710, 711, 0, 0, 352,
+ 351, 361, 362, 354, 355, 356, 357, 358, 359, 360,
+ 353, 0, 0, 0, 0, 0, 0, 491, 0, 92,
+ 643, 0, 409, 92, 92, 92, 92, 0, 0, 0,
+ 0, 0, 420, 0, 0, 0, 92, 0, 0, 212,
+ 352, 351, 361, 362, 354, 355, 356, 357, 358, 359,
+ 360, 353, 361, 362, 354, 355, 356, 357, 358, 359,
+ 360, 353, 0, 67, 0, 515, 0, 144, 0, 0,
+ 0, 0, 143, 0, 176, 59, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 28, 92, 92, 183, 160,
+ 159, 161, 162, 163, 164, 589, 0, 165, 166, 167,
+ 0, 0, 0, 0, 141, 153, 0, 175, 0, 0,
+ 0, 0, 0, 0, 0, 352, 351, 361, 362, 354,
+ 355, 356, 357, 358, 359, 360, 353, 150, 151, 336,
+ 0, 0, 0, 181, 0, 152, 0, 154, 0, 0,
+ 0, 0, 0, 114, 0, 0, 0, 0, 180, 0,
+ 68, 0, 0, 56, 0, 0, 51, 0, 76, 71,
+ 63, 57, 58, 47, 491, 69, 54, 55, 53, 66,
+ 73, 74, 52, 81, 50, 80, 49, 65, 72, 77,
+ 64, 61, 48, 75, 62, 60, 0, 70, 78, 82,
+ 0, 177, 178, 179, 182, 172, 173, 174, 0, 79,
+ 0, 0, 0, 0, 0, 0, 0, 338, 261, 0,
+ 0, 0, 0, 409, 67, 0, 0, 409, 338, 338,
+ 338, 0, 0, 0, 0, 0, 59, 0, 409, 0,
+ 0, 233, 0, 238, 239, 240, 241, 242, 243, 45,
+ 244, 245, 246, 247, 248, 234, 235, 236, 237, 223,
+ 224, 0, 0, 225, 226, 227, 228, 229, 230, 231,
+ 232, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 352, 351, 361, 362, 354, 355,
+ 356, 357, 358, 359, 360, 353, 0, 0, 0, 0,
+ 0, 0, 0, 0, 92, 409, 0, 0, 0, 338,
+ 92, 68, 0, 0, 56, 0, 261, 51, 0, 76,
71, 63, 57, 58, 47, 0, 69, 54, 55, 53,
66, 73, 74, 52, 81, 50, 80, 49, 65, 72,
- 77, 64, 61, 48, 75, 62, 60, 640, 70, 78,
- 82, 0, 0, 334, 0, 0, 0, 0, 0, 0,
- 79, 0, 334, 0, 0, 0, 0, 348, 347, 357,
- 358, 350, 351, 352, 353, 354, 355, 356, 349, 0,
- 405, 0, 257, 357, 358, 350, 351, 352, 353, 354,
- 355, 356, 349, 323, 314, 293, 325, 274, 285, 329,
- 286, 287, 308, 265, 301, 67, 0, 277, 261, 283,
- 262, 275, 295, 298, 273, 316, 327, 59, 297, 299,
- 313, 292, 309, 268, 303, 306, 326, 0, 0, 0,
- 45, 334, 427, 428, 0, 0, 0, 0, 0, 305,
- 322, 284, 307, 260, 304, 0, 264, 266, 328, 320,
- 280, 281, 0, 0, 0, 0, 0, 0, 296, 300,
- 310, 290, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 278, 0, 302, 0, 0, 0, 294, 405, 267,
- 0, 279, 311, 259, 318, 291, 321, 289, 288, 324,
- 68, 0, 0, 56, 317, 276, 51, 282, 76, 71,
- 63, 57, 58, 47, 0, 69, 54, 55, 53, 66,
- 73, 74, 52, 81, 50, 80, 49, 65, 72, 77,
- 64, 61, 48, 75, 62, 60, 263, 70, 78, 82,
- 319, 271, 269, 270, 312, 0, 272, 0, 315, 79,
- 323, 314, 293, 325, 274, 285, 329, 286, 287, 308,
- 265, 301, 67, 0, 277, 261, 283, 262, 275, 295,
- 298, 273, 316, 327, 59, 297, 299, 313, 292, 309,
- 268, 303, 306, 326, 0, 0, 0, 45, 0, 0,
- 0, 0, 0, 0, 0, 0, 305, 322, 284, 307,
- 260, 304, 0, 264, 266, 328, 320, 280, 281, 0,
- 0, 0, 0, 0, 0, 296, 300, 310, 290, 0,
- 0, 0, 0, 0, 0, 0, 689, 0, 278, 0,
- 302, 0, 0, 0, 294, 0, 267, 0, 279, 311,
- 259, 318, 291, 321, 289, 288, 324, 68, 0, 0,
- 56, 317, 276, 51, 282, 76, 71, 63, 57, 58,
- 47, 0, 69, 54, 55, 53, 66, 73, 74, 52,
- 81, 50, 80, 49, 65, 72, 77, 64, 61, 48,
- 75, 62, 60, 263, 70, 78, 82, 319, 271, 269,
- 270, 312, 0, 272, 0, 315, 79, 323, 314, 293,
- 325, 274, 285, 329, 286, 287, 308, 265, 301, 67,
- 0, 277, 261, 283, 262, 275, 295, 298, 273, 316,
- 327, 59, 297, 299, 313, 292, 309, 268, 303, 306,
- 326, 28, 0, 0, 45, 0, 0, 0, 0, 0,
- 0, 0, 0, 305, 322, 284, 307, 260, 304, 0,
- 264, 266, 328, 320, 280, 281, 0, 0, 0, 0,
- 0, 0, 296, 300, 310, 290, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 278, 0, 302, 0, 0,
- 0, 294, 0, 267, 0, 279, 311, 259, 318, 291,
- 321, 289, 288, 324, 68, 0, 0, 56, 317, 276,
- 51, 282, 76, 71, 63, 57, 58, 47, 0, 69,
+ 77, 64, 61, 48, 75, 62, 60, 0, 70, 78,
+ 82, 0, 0, 338, 0, 0, 0, 0, 0, 0,
+ 79, 0, 338, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 409, 0, 261, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 327, 318, 297, 329, 278,
+ 289, 333, 290, 291, 312, 269, 305, 67, 92, 281,
+ 265, 287, 266, 279, 299, 302, 277, 320, 331, 59,
+ 301, 303, 317, 296, 313, 272, 307, 310, 330, 0,
+ 0, 338, 45, 0, 431, 432, 0, 0, 0, 0,
+ 0, 309, 326, 288, 0, 0, 311, 264, 308, 0,
+ 268, 270, 332, 324, 284, 285, 556, 0, 0, 0,
+ 0, 0, 300, 304, 314, 294, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 282, 409, 306, 0, 0,
+ 0, 298, 0, 271, 0, 283, 315, 263, 322, 295,
+ 325, 293, 292, 328, 68, 0, 0, 56, 321, 280,
+ 51, 286, 76, 71, 63, 57, 58, 47, 0, 69,
54, 55, 53, 66, 73, 74, 52, 81, 50, 80,
49, 65, 72, 77, 64, 61, 48, 75, 62, 60,
- 263, 70, 78, 82, 319, 271, 269, 270, 312, 0,
- 272, 0, 315, 79, 323, 314, 293, 325, 274, 285,
- 329, 286, 287, 308, 265, 301, 67, 0, 277, 261,
- 283, 262, 275, 295, 298, 273, 316, 327, 59, 297,
- 299, 313, 292, 309, 268, 303, 306, 326, 0, 0,
- 0, 180, 0, 0, 0, 0, 0, 0, 0, 0,
- 305, 322, 284, 307, 260, 304, 0, 264, 266, 328,
- 320, 280, 281, 0, 0, 0, 0, 0, 0, 296,
- 300, 310, 290, 0, 0, 0, 0, 0, 0, 0,
- 573, 0, 278, 0, 302, 0, 0, 0, 294, 0,
- 267, 0, 279, 311, 259, 318, 291, 321, 289, 288,
- 324, 68, 0, 0, 56, 317, 276, 51, 282, 76,
- 71, 63, 57, 58, 47, 0, 69, 54, 55, 53,
- 66, 73, 74, 52, 81, 50, 80, 49, 65, 72,
- 77, 64, 61, 48, 75, 62, 60, 263, 70, 78,
- 82, 319, 271, 269, 270, 312, 0, 272, 0, 315,
- 79, 323, 314, 293, 325, 274, 285, 329, 286, 287,
- 308, 265, 301, 67, 0, 277, 261, 283, 262, 275,
- 295, 298, 273, 316, 327, 59, 297, 299, 313, 292,
- 309, 268, 303, 306, 326, 0, 0, 0, 45, 0,
- 0, 0, 0, 0, 0, 0, 0, 305, 322, 284,
- 307, 260, 304, 0, 264, 266, 328, 320, 280, 281,
- 0, 0, 0, 0, 0, 0, 296, 300, 310, 290,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 278,
- 0, 302, 0, 0, 0, 294, 0, 267, 0, 279,
- 311, 259, 318, 291, 321, 289, 288, 324, 68, 0,
- 0, 56, 317, 276, 51, 282, 76, 71, 63, 57,
- 58, 47, 0, 69, 54, 55, 53, 66, 73, 74,
- 52, 81, 50, 80, 49, 65, 72, 77, 64, 61,
- 48, 75, 62, 60, 263, 70, 78, 82, 319, 271,
- 269, 270, 312, 0, 272, 0, 315, 79, 323, 314,
- 293, 325, 274, 285, 329, 286, 287, 308, 265, 301,
- 67, 0, 277, 261, 283, 262, 275, 295, 298, 273,
- 316, 327, 59, 297, 299, 313, 292, 309, 268, 303,
- 306, 326, 0, 0, 0, 180, 0, 0, 0, 0,
- 0, 0, 0, 0, 305, 322, 284, 307, 260, 304,
- 0, 264, 266, 328, 320, 280, 281, 0, 0, 0,
- 0, 0, 0, 296, 300, 310, 290, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 278, 0, 302, 0,
- 0, 0, 294, 0, 267, 0, 279, 311, 259, 318,
- 291, 321, 289, 288, 324, 68, 0, 0, 56, 317,
- 276, 51, 282, 76, 71, 63, 57, 58, 47, 0,
- 69, 54, 55, 53, 66, 73, 74, 52, 81, 50,
- 80, 49, 65, 72, 77, 64, 61, 48, 75, 62,
- 60, 263, 70, 78, 82, 319, 271, 269, 270, 312,
- 0, 272, 0, 315, 79, 323, 314, 293, 325, 274,
- 285, 329, 286, 287, 308, 265, 301, 67, 0, 277,
- 261, 283, 262, 275, 295, 298, 273, 316, 327, 59,
- 297, 299, 313, 292, 309, 268, 303, 306, 326, 0,
- 0, 0, 92, 0, 0, 0, 0, 0, 0, 0,
- 0, 305, 322, 284, 307, 260, 304, 0, 264, 266,
- 328, 320, 280, 281, 0, 0, 0, 0, 0, 0,
- 296, 300, 310, 290, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 278, 0, 302, 0, 0, 0, 294,
- 0, 267, 0, 279, 311, 259, 318, 291, 321, 289,
- 288, 324, 68, 0, 0, 56, 317, 276, 51, 282,
+ 267, 70, 78, 82, 323, 275, 273, 274, 316, 0,
+ 276, 0, 319, 79, 327, 318, 297, 329, 278, 289,
+ 333, 290, 291, 312, 269, 305, 67, 0, 281, 265,
+ 287, 266, 279, 299, 302, 277, 320, 331, 59, 301,
+ 303, 317, 296, 313, 272, 307, 310, 330, 0, 0,
+ 0, 45, 0, 431, 432, 0, 0, 0, 0, 0,
+ 309, 326, 288, 0, 0, 311, 264, 308, 0, 268,
+ 270, 332, 324, 284, 285, 0, 0, 0, 0, 0,
+ 0, 300, 304, 314, 294, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 282, 0, 306, 0, 0, 0,
+ 298, 0, 271, 0, 283, 315, 263, 322, 295, 325,
+ 293, 292, 328, 68, 0, 0, 56, 321, 280, 51,
+ 286, 76, 71, 63, 57, 58, 47, 0, 69, 54,
+ 55, 53, 66, 73, 74, 52, 81, 50, 80, 49,
+ 65, 72, 77, 64, 61, 48, 75, 62, 60, 267,
+ 70, 78, 82, 323, 275, 273, 274, 316, 0, 276,
+ 0, 319, 79, 327, 318, 297, 329, 278, 289, 333,
+ 290, 291, 312, 269, 305, 67, 0, 281, 265, 287,
+ 266, 279, 299, 302, 277, 320, 331, 59, 301, 303,
+ 317, 296, 313, 272, 307, 310, 330, 0, 0, 0,
+ 45, 0, 0, 0, 0, 0, 0, 0, 0, 309,
+ 326, 288, 0, 0, 311, 264, 308, 0, 268, 270,
+ 332, 324, 284, 285, 0, 0, 0, 0, 0, 0,
+ 300, 304, 314, 294, 0, 0, 0, 0, 0, 0,
+ 0, 695, 0, 282, 0, 306, 0, 0, 0, 298,
+ 0, 271, 0, 283, 315, 263, 322, 295, 325, 293,
+ 292, 328, 68, 0, 0, 56, 321, 280, 51, 286,
76, 71, 63, 57, 58, 47, 0, 69, 54, 55,
53, 66, 73, 74, 52, 81, 50, 80, 49, 65,
- 72, 77, 64, 61, 48, 75, 62, 60, 263, 70,
- 78, 82, 319, 271, 269, 270, 312, 0, 272, 0,
- 315, 79, 67, 0, 510, 0, 141, 0, 0, 0,
- 0, 140, 0, 173, 59, 707, 134, 0, 0, 0,
- 0, 0, 0, 0, 28, 0, 0, 180, 157, 156,
- 158, 159, 160, 161, 0, 0, 162, 163, 164, 0,
- 0, 138, 150, 0, 172, 0, 0, 0, 0, 0,
- 348, 347, 357, 358, 350, 351, 352, 353, 354, 355,
- 356, 349, 0, 0, 147, 148, 332, 0, 0, 0,
- 178, 0, 149, 0, 151, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 177, 0, 68, 0, 0,
- 56, 0, 0, 51, 0, 76, 71, 63, 57, 58,
- 47, 0, 69, 54, 55, 53, 66, 73, 74, 52,
- 81, 50, 80, 49, 65, 72, 77, 64, 61, 48,
- 75, 62, 60, 0, 70, 78, 82, 0, 174, 175,
- 176, 179, 169, 170, 171, 67, 79, 0, 0, 141,
- 0, 0, 0, 0, 140, 134, 173, 59, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 28, 0, 0,
- 180, 157, 156, 158, 159, 160, 161, 0, 0, 162,
- 163, 164, 0, 0, 138, 150, 0, 172, 0, 348,
- 347, 357, 358, 350, 351, 352, 353, 354, 355, 356,
- 349, 0, 0, 0, 0, 0, 0, 147, 148, 332,
- 0, 0, 0, 178, 0, 149, 0, 151, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 177, 0,
- 68, 0, 0, 56, 0, 0, 51, 0, 76, 71,
+ 72, 77, 64, 61, 48, 75, 62, 60, 267, 70,
+ 78, 82, 323, 275, 273, 274, 316, 0, 276, 0,
+ 319, 79, 327, 318, 297, 329, 278, 289, 333, 290,
+ 291, 312, 269, 305, 67, 0, 281, 265, 287, 266,
+ 279, 299, 302, 277, 320, 331, 59, 301, 303, 317,
+ 296, 313, 272, 307, 310, 330, 28, 0, 0, 45,
+ 0, 0, 0, 0, 0, 0, 0, 0, 309, 326,
+ 288, 0, 0, 311, 264, 308, 0, 268, 270, 332,
+ 324, 284, 285, 0, 0, 0, 0, 0, 0, 300,
+ 304, 314, 294, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 282, 0, 306, 0, 0, 0, 298, 0,
+ 271, 0, 283, 315, 263, 322, 295, 325, 293, 292,
+ 328, 68, 0, 0, 56, 321, 280, 51, 286, 76,
+ 71, 63, 57, 58, 47, 0, 69, 54, 55, 53,
+ 66, 73, 74, 52, 81, 50, 80, 49, 65, 72,
+ 77, 64, 61, 48, 75, 62, 60, 267, 70, 78,
+ 82, 323, 275, 273, 274, 316, 0, 276, 0, 319,
+ 79, 327, 318, 297, 329, 278, 289, 333, 290, 291,
+ 312, 269, 305, 67, 0, 281, 265, 287, 266, 279,
+ 299, 302, 277, 320, 331, 59, 301, 303, 317, 296,
+ 313, 272, 307, 310, 330, 0, 0, 0, 183, 0,
+ 0, 0, 0, 0, 0, 0, 0, 309, 326, 288,
+ 0, 0, 311, 264, 308, 0, 268, 270, 332, 324,
+ 284, 285, 0, 0, 0, 0, 0, 0, 300, 304,
+ 314, 294, 0, 0, 0, 0, 0, 0, 0, 578,
+ 0, 282, 0, 306, 0, 0, 0, 298, 0, 271,
+ 0, 283, 315, 263, 322, 295, 325, 293, 292, 328,
+ 68, 0, 0, 56, 321, 280, 51, 286, 76, 71,
63, 57, 58, 47, 0, 69, 54, 55, 53, 66,
73, 74, 52, 81, 50, 80, 49, 65, 72, 77,
- 64, 61, 48, 75, 62, 60, 0, 70, 78, 82,
- 0, 174, 175, 176, 179, 169, 170, 171, 67, 79,
- 0, 0, 141, 0, 0, 0, 0, 140, 0, 173,
- 59, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 28, 584, 134, 180, 157, 156, 158, 159, 160, 161,
- 0, 0, 162, 163, 164, 0, 0, 138, 150, 0,
- 172, 348, 347, 357, 358, 350, 351, 352, 353, 354,
- 355, 356, 349, 0, 0, 0, 0, 0, 0, 0,
- 147, 148, 0, 0, 0, 0, 178, 0, 149, 0,
- 151, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 177, 0, 68, 0, 0, 56, 0, 0, 51,
- 0, 76, 71, 63, 57, 58, 47, 0, 69, 54,
- 55, 53, 66, 73, 74, 52, 81, 50, 80, 49,
- 65, 72, 77, 64, 61, 48, 75, 62, 60, 0,
- 70, 78, 82, 24, 174, 175, 176, 179, 169, 170,
- 171, 0, 79, 0, 67, 0, 0, 0, 141, 0,
- 0, 0, 0, 140, 0, 173, 59, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 28, 0, 0, 180,
- 157, 156, 158, 159, 160, 161, 0, 0, 162, 163,
- 164, 0, 0, 138, 150, 0, 172, 348, 347, 357,
- 358, 350, 351, 352, 353, 354, 355, 356, 349, 0,
- 0, 0, 0, 0, 0, 0, 147, 148, 0, 0,
- 0, 0, 178, 0, 149, 0, 151, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 177, 0, 68,
- 0, 0, 56, 0, 0, 51, 0, 76, 71, 63,
+ 64, 61, 48, 75, 62, 60, 267, 70, 78, 82,
+ 323, 275, 273, 274, 316, 0, 276, 0, 319, 79,
+ 327, 318, 297, 329, 278, 289, 333, 290, 291, 312,
+ 269, 305, 67, 0, 281, 265, 287, 266, 279, 299,
+ 302, 277, 320, 331, 59, 301, 303, 317, 296, 313,
+ 272, 307, 310, 330, 0, 0, 0, 45, 0, 0,
+ 0, 0, 0, 0, 0, 0, 309, 326, 288, 0,
+ 0, 311, 264, 308, 0, 268, 270, 332, 324, 284,
+ 285, 0, 0, 0, 0, 0, 0, 300, 304, 314,
+ 294, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 282, 0, 306, 0, 0, 0, 298, 0, 271, 0,
+ 283, 315, 263, 322, 295, 325, 293, 292, 328, 68,
+ 0, 0, 56, 321, 280, 51, 286, 76, 71, 63,
57, 58, 47, 0, 69, 54, 55, 53, 66, 73,
74, 52, 81, 50, 80, 49, 65, 72, 77, 64,
- 61, 48, 75, 62, 60, 0, 70, 78, 82, 0,
- 174, 175, 176, 179, 169, 170, 171, 67, 79, 0,
- 0, 141, 0, 0, 0, 0, 140, 0, 173, 59,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 28,
- 0, 0, 180, 157, 156, 158, 159, 160, 161, 0,
- 0, 162, 163, 164, 0, 0, 138, 150, 0, 172,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 147,
- 148, 0, 0, 0, 0, 178, 0, 149, 0, 151,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 177, 0, 68, 0, 0, 56, 0, 0, 51, 0,
- 76, 71, 63, 57, 58, 47, 0, 69, 54, 55,
- 53, 66, 73, 74, 52, 81, 50, 80, 49, 65,
- 72, 77, 64, 61, 48, 75, 62, 60, 0, 70,
- 78, 82, 67, 174, 175, 176, 179, 169, 170, 171,
- 0, 79, 0, 173, 59, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 28, 0, 0, 180, 157, 156,
- 158, 159, 160, 161, 0, 0, 162, 163, 164, 0,
- 0, 0, 150, 0, 172, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 147, 148, 0, 0, 0, 0,
- 178, 0, 149, 661, 151, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 177, 0, 68, 0, 0,
- 56, 0, 0, 51, 0, 76, 71, 63, 57, 58,
+ 61, 48, 75, 62, 60, 267, 70, 78, 82, 323,
+ 275, 273, 274, 316, 0, 276, 0, 319, 79, 327,
+ 318, 297, 329, 278, 289, 333, 290, 291, 312, 269,
+ 305, 67, 0, 281, 265, 287, 266, 279, 299, 302,
+ 277, 320, 331, 59, 301, 303, 317, 296, 313, 272,
+ 307, 310, 330, 0, 0, 0, 183, 0, 0, 0,
+ 0, 0, 0, 0, 0, 309, 326, 288, 0, 0,
+ 311, 264, 308, 0, 268, 270, 332, 324, 284, 285,
+ 0, 0, 0, 0, 0, 0, 300, 304, 314, 294,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 282,
+ 0, 306, 0, 0, 0, 298, 0, 271, 0, 283,
+ 315, 263, 322, 295, 325, 293, 292, 328, 68, 0,
+ 0, 56, 321, 280, 51, 286, 76, 71, 63, 57,
+ 58, 47, 0, 69, 54, 55, 53, 66, 73, 74,
+ 52, 81, 50, 80, 49, 65, 72, 77, 64, 61,
+ 48, 75, 62, 60, 267, 70, 78, 82, 323, 275,
+ 273, 274, 316, 0, 276, 0, 319, 79, 327, 318,
+ 297, 329, 278, 289, 333, 290, 291, 312, 269, 305,
+ 67, 0, 281, 265, 287, 266, 279, 299, 302, 277,
+ 320, 331, 59, 301, 303, 317, 296, 313, 272, 307,
+ 310, 330, 0, 0, 0, 93, 0, 0, 0, 0,
+ 0, 0, 0, 0, 309, 326, 288, 0, 0, 311,
+ 264, 308, 0, 268, 270, 332, 324, 284, 285, 0,
+ 0, 0, 0, 0, 0, 300, 304, 314, 294, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 282, 0,
+ 306, 0, 0, 0, 298, 0, 271, 0, 283, 315,
+ 263, 322, 295, 325, 293, 292, 328, 68, 0, 0,
+ 56, 321, 280, 51, 286, 76, 71, 63, 57, 58,
47, 0, 69, 54, 55, 53, 66, 73, 74, 52,
81, 50, 80, 49, 65, 72, 77, 64, 61, 48,
- 75, 62, 60, 0, 70, 78, 82, 0, 174, 175,
- 176, 179, 169, 170, 171, 67, 79, 648, 470, 657,
- 658, 659, 656, 0, 660, 0, 0, 59, 0, 650,
- 0, 653, 655, 649, 0, 647, 0, 0, 651, 0,
- 45, 0, 472, 0, 0, 0, 24, 0, 652, 654,
- 0, 0, 336, 335, 0, 0, 0, 67, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 337, 59,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 28,
- 0, 0, 45, 0, 0, 0, 0, 0, 0, 0,
+ 75, 62, 60, 267, 70, 78, 82, 323, 275, 273,
+ 274, 316, 0, 276, 67, 319, 79, 0, 144, 0,
+ 0, 0, 0, 143, 0, 176, 59, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 28, 0, 0, 183,
+ 160, 159, 161, 162, 163, 164, 0, 0, 165, 166,
+ 167, 0, 0, 0, 0, 141, 153, 0, 175, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 0, 0, 56, 0, 0, 51, 0, 76, 71,
- 63, 57, 58, 47, 0, 69, 54, 55, 53, 66,
- 73, 74, 52, 81, 50, 80, 49, 65, 72, 77,
- 64, 61, 48, 75, 62, 60, 0, 70, 78, 82,
- 0, 0, 68, 0, 0, 56, 0, 0, 51, 79,
- 76, 71, 63, 57, 58, 47, 0, 69, 54, 55,
- 53, 66, 73, 74, 52, 81, 50, 80, 49, 65,
- 72, 77, 64, 61, 48, 75, 62, 60, 24, 70,
- 78, 82, 0, 0, 0, 0, 0, 0, 0, 67,
- 0, 79, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 59, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 28, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 150, 151,
+ 336, 0, 0, 0, 181, 0, 152, 0, 154, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 180,
+ 0, 68, 0, 0, 56, 0, 0, 51, 0, 76,
+ 71, 63, 57, 58, 47, 0, 69, 54, 55, 53,
+ 66, 73, 74, 52, 81, 50, 80, 49, 65, 72,
+ 77, 64, 61, 48, 75, 62, 60, 0, 70, 78,
+ 82, 0, 177, 178, 179, 182, 172, 173, 174, 67,
+ 79, 0, 0, 144, 0, 0, 0, 0, 143, 0,
+ 176, 59, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 28, 0, 137, 183, 160, 159, 161, 162, 163,
+ 164, 0, 0, 165, 166, 167, 0, 0, 0, 0,
+ 141, 153, 0, 175, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 67, 0, 0, 208, 0, 0, 0, 0, 0,
- 0, 0, 0, 59, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 92, 0, 210, 0,
+ 0, 0, 0, 150, 151, 0, 0, 0, 0, 181,
+ 0, 152, 0, 154, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 180, 0, 68, 0, 0, 56,
+ 0, 0, 51, 0, 76, 71, 63, 57, 58, 47,
+ 0, 69, 54, 55, 53, 66, 73, 74, 52, 81,
+ 50, 80, 49, 65, 72, 77, 64, 61, 48, 75,
+ 62, 60, 0, 70, 78, 82, 24, 177, 178, 179,
+ 182, 172, 173, 174, 0, 79, 0, 67, 0, 0,
+ 0, 144, 0, 0, 0, 0, 143, 0, 176, 59,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 28,
+ 0, 0, 183, 160, 159, 161, 162, 163, 164, 0,
+ 0, 165, 166, 167, 0, 0, 0, 0, 141, 153,
+ 0, 175, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 0, 0, 56, 0, 0,
+ 0, 150, 151, 0, 0, 0, 0, 181, 0, 152,
+ 0, 154, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 180, 0, 68, 0, 0, 56, 0, 0,
51, 0, 76, 71, 63, 57, 58, 47, 0, 69,
54, 55, 53, 66, 73, 74, 52, 81, 50, 80,
49, 65, 72, 77, 64, 61, 48, 75, 62, 60,
- 0, 70, 78, 82, 0, 0, 68, 0, 0, 56,
- 0, 0, 51, 79, 76, 71, 63, 57, 58, 47,
+ 0, 70, 78, 82, 0, 177, 178, 179, 182, 172,
+ 173, 174, 67, 79, 0, 0, 144, 0, 0, 0,
+ 0, 143, 0, 176, 59, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 28, 0, 0, 183, 160, 159,
+ 161, 162, 163, 164, 0, 0, 165, 166, 167, 0,
+ 0, 0, 0, 141, 153, 0, 175, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 150, 151, 0, 0,
+ 0, 0, 181, 0, 152, 0, 154, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 180, 0, 68,
+ 0, 0, 56, 0, 0, 51, 0, 76, 71, 63,
+ 57, 58, 47, 0, 69, 54, 55, 53, 66, 73,
+ 74, 52, 81, 50, 80, 49, 65, 72, 77, 64,
+ 61, 48, 75, 62, 60, 0, 70, 78, 82, 67,
+ 177, 178, 179, 182, 172, 173, 174, 0, 79, 0,
+ 176, 59, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 28, 0, 0, 183, 160, 159, 161, 162, 163,
+ 164, 0, 0, 165, 166, 167, 0, 0, 0, 0,
+ 0, 153, 0, 175, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 150, 151, 0, 0, 0, 0, 181,
+ 0, 152, 0, 154, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 180, 0, 68, 0, 0, 56,
+ 0, 0, 51, 0, 76, 71, 63, 57, 58, 47,
0, 69, 54, 55, 53, 66, 73, 74, 52, 81,
50, 80, 49, 65, 72, 77, 64, 61, 48, 75,
- 62, 60, 67, 70, 78, 82, 0, 0, 0, 0,
- 0, 0, 0, 0, 59, 79, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 45, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 67, 0, 0, 0, 0, 0,
+ 62, 60, 0, 70, 78, 82, 0, 177, 178, 179,
+ 182, 172, 173, 174, 67, 79, 0, 475, 0, 0,
0, 0, 0, 0, 0, 0, 59, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 45,
- 0, 472, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 42, 0, 0, 0, 0, 43, 68, 0, 0,
+ 0, 477, 0, 0, 0, 24, 0, 0, 0, 0,
+ 0, 0, 0, 340, 339, 0, 67, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 59, 341,
+ 0, 0, 0, 0, 0, 0, 0, 0, 28, 0,
+ 0, 45, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 68, 0, 0, 56, 0, 0, 51, 0, 76,
+ 71, 63, 57, 58, 47, 0, 69, 54, 55, 53,
+ 66, 73, 74, 52, 81, 50, 80, 49, 65, 72,
+ 77, 64, 61, 48, 75, 62, 60, 0, 70, 78,
+ 82, 0, 0, 68, 0, 0, 56, 0, 0, 51,
+ 79, 76, 71, 63, 57, 58, 47, 0, 69, 54,
+ 55, 53, 66, 73, 74, 52, 81, 50, 80, 49,
+ 65, 72, 77, 64, 61, 48, 75, 62, 60, 24,
+ 70, 78, 82, 0, 0, 0, 0, 0, 0, 0,
+ 67, 0, 79, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 59, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 28, 0, 0, 93, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 67, 0, 0, 211, 0, 0, 0, 0,
+ 0, 0, 0, 0, 59, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 93, 0, 213,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 68, 0, 0,
56, 0, 0, 51, 0, 76, 71, 63, 57, 58,
47, 0, 69, 54, 55, 53, 66, 73, 74, 52,
81, 50, 80, 49, 65, 72, 77, 64, 61, 48,
@@ -791,151 +786,169 @@ var yyAct = [...]int{
74, 52, 81, 50, 80, 49, 65, 72, 77, 64,
61, 48, 75, 62, 60, 67, 70, 78, 82, 0,
0, 0, 0, 0, 0, 0, 0, 59, 79, 0,
- 0, 0, 0, 0, 0, 0, 0, 28, 0, 0,
- 92, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 45, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 67, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 59,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 92, 0, 210, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 0, 0, 56, 0, 0, 51, 0, 76, 71,
- 63, 57, 58, 47, 0, 69, 54, 55, 53, 66,
- 73, 74, 52, 81, 50, 80, 49, 65, 72, 77,
- 64, 61, 48, 75, 62, 60, 0, 70, 78, 82,
- 0, 0, 68, 0, 0, 56, 0, 0, 51, 79,
+ 0, 0, 45, 0, 477, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 42, 0, 0, 0,
+ 0, 43, 68, 0, 0, 56, 0, 0, 51, 0,
76, 71, 63, 57, 58, 47, 0, 69, 54, 55,
53, 66, 73, 74, 52, 81, 50, 80, 49, 65,
- 72, 77, 64, 61, 48, 75, 62, 60, 67, 70,
- 78, 82, 0, 0, 0, 188, 0, 0, 0, 0,
- 59, 79, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 92, 0, 0, 0, 0, 0, 0,
+ 72, 77, 64, 61, 48, 75, 62, 60, 0, 70,
+ 78, 82, 0, 0, 68, 0, 0, 56, 0, 0,
+ 51, 79, 76, 71, 63, 57, 58, 47, 0, 69,
+ 54, 55, 53, 66, 73, 74, 52, 81, 50, 80,
+ 49, 65, 72, 77, 64, 61, 48, 75, 62, 60,
+ 67, 70, 78, 82, 0, 0, 0, 0, 0, 0,
+ 0, 0, 59, 79, 0, 0, 0, 0, 0, 0,
+ 0, 0, 28, 0, 0, 93, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 67, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 59, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 45, 0, 0, 0, 0,
+ 0, 0, 67, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 59, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 93, 0, 213,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 68, 0, 0, 56, 0, 0, 51,
- 0, 76, 71, 63, 57, 58, 47, 0, 69, 54,
- 55, 53, 66, 73, 74, 52, 81, 50, 80, 49,
- 65, 72, 77, 64, 61, 48, 75, 62, 60, 0,
- 70, 78, 82, 0, 0, 68, 0, 0, 56, 0,
- 0, 51, 79, 76, 71, 63, 57, 58, 47, 0,
- 69, 54, 55, 53, 66, 73, 74, 52, 81, 50,
- 80, 49, 65, 72, 77, 64, 61, 48, 75, 62,
- 60, 67, 70, 78, 82, 0, 0, 0, 0, 0,
- 0, 0, 0, 59, 79, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 180, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 68, 0, 0,
+ 56, 0, 0, 51, 0, 76, 71, 63, 57, 58,
+ 47, 0, 69, 54, 55, 53, 66, 73, 74, 52,
+ 81, 50, 80, 49, 65, 72, 77, 64, 61, 48,
+ 75, 62, 60, 0, 70, 78, 82, 0, 0, 68,
+ 0, 0, 56, 0, 0, 51, 79, 76, 71, 63,
+ 57, 58, 47, 0, 69, 54, 55, 53, 66, 73,
+ 74, 52, 81, 50, 80, 49, 65, 72, 77, 64,
+ 61, 48, 75, 62, 60, 67, 70, 78, 82, 0,
+ 0, 0, 191, 0, 0, 0, 0, 59, 79, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 67, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 59, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 92, 0,
+ 93, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 67, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 347, 59,
+ 350, 0, 0, 0, 0, 0, 363, 364, 365, 366,
+ 367, 368, 45, 348, 349, 346, 369, 352, 351, 361,
+ 362, 354, 355, 356, 357, 358, 359, 360, 353, 0,
+ 0, 0, 68, 0, 0, 56, 0, 0, 51, 0,
+ 76, 71, 63, 57, 58, 47, 0, 69, 54, 55,
+ 53, 66, 73, 74, 52, 81, 50, 80, 49, 65,
+ 72, 77, 64, 61, 48, 75, 62, 60, 0, 70,
+ 78, 82, 0, 0, 68, 0, 0, 56, 0, 0,
+ 51, 79, 76, 71, 63, 57, 58, 47, 0, 69,
+ 54, 55, 53, 66, 73, 74, 52, 81, 50, 80,
+ 49, 65, 72, 77, 64, 61, 48, 75, 62, 60,
+ 67, 70, 78, 82, 0, 0, 0, 0, 0, 0,
+ 0, 0, 59, 79, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 183, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 68, 0, 0, 56,
- 0, 0, 51, 0, 76, 71, 63, 57, 58, 47,
- 0, 69, 54, 55, 53, 66, 73, 74, 52, 81,
- 50, 80, 49, 65, 72, 77, 64, 61, 48, 75,
- 62, 60, 0, 70, 78, 82, 0, 0, 68, 0,
- 0, 56, 0, 0, 51, 79, 76, 71, 63, 57,
- 58, 47, 0, 69, 54, 55, 53, 66, 73, 74,
- 52, 81, 50, 80, 49, 65, 72, 77, 64, 61,
- 48, 75, 62, 60, 0, 70, 78, 82, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 79,
+ 0, 0, 67, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 59, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 93, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 68, 0, 0,
+ 56, 0, 0, 51, 0, 76, 71, 63, 57, 58,
+ 47, 0, 69, 54, 55, 53, 66, 73, 74, 52,
+ 81, 50, 80, 49, 65, 72, 77, 64, 61, 48,
+ 75, 62, 60, 0, 70, 78, 82, 0, 0, 68,
+ 0, 0, 56, 0, 0, 51, 79, 76, 71, 63,
+ 57, 58, 47, 0, 69, 54, 55, 53, 66, 73,
+ 74, 52, 81, 50, 80, 49, 65, 72, 77, 64,
+ 61, 48, 75, 62, 60, 0, 70, 78, 82, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 79,
}
var yyPact = [...]int{
- 58, -1000, -107, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
- -1000, -1000, 428, 462, -1000, -1000, -1000, 344, 3315, -8,
- -17, -21, 3846, 3846, -1000, 331, 87, -1000, -1000, -1000,
- -1000, 408, 420, 331, 403, -27, -1000, 3478, 456, -1000,
- 204, -15, -29, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+ 181, -1000, -108, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+ -1000, -1000, 434, 458, -1000, -1000, -1000, 355, 3388, -13,
+ -24, 34, 3925, 3925, -1000, 344, 103, -1000, -1000, -1000,
+ -1000, 424, 430, 344, 418, -30, -1000, 3553, 451, -1000,
+ 188, -21, -35, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+ -1000, -1000, -1000, 3925, -32, -32, -15, 450, 3925, -5,
+ -1000, -1000, 21, -1000, -1000, -1000, 414, 182, -99, -1000,
+ 2785, 2785, 434, -1000, 344, -1000, 3718, -1000, 120, 307,
+ 444, -1000, -1000, -1000, 406, 3223, 3265, 3925, 281, -1000,
+ 941, -35, 3925, 77, -16, 3925, 404, 3925, 3925, -19,
+ -1000, -1000, 449, 2243, 2377, -1000, -1000, -1000, -1000, 263,
+ -1000, 2785, 3730, 316, 316, -1000, -1000, -1000, -1000, -1000,
+ 2912, 2912, 2912, 2912, 2912, -1000, -1000, -1000, -1000, -1000,
+ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 316, 20,
+ -1000, 2650, 316, 316, 316, 2785, 316, -1000, -1000, -1000,
+ 316, 316, 316, -1000, -1000, 293, -1000, 205, 424, 182,
+ 318, 3925, -1000, -1000, 3883, 3553, 3553, 3553, 3553, -1000,
+ 382, 379, 377, 367, 3925, -1000, 267, 182, 3223, -1000,
+ -1000, 3595, -1000, -1000, 445, 1349, 130, 90, -87, -1000,
+ -1000, 335, -1000, 335, 335, -1000, -1000, -1000, -1000, -1000,
+ -1000, -1000, -1000, -1000, 335, 335, 335, -1000, -1000, -1000,
+ -1000, -1000, -1000, -1000, 347, 347, 347, 339, 339, 212,
+ -1000, 402, -39, -37, -1000, -1000, -1000, -1000, 3925, 3925,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
- -1000, -1000, -1000, 3846, -31, -31, -13, 455, 3846, -1000,
- -1000, 17, -1000, -1000, -1000, 394, 218, -98, -1000, 2720,
- 2720, 428, -1000, 331, -1000, 3641, -1000, 141, 292, 343,
- -1000, -1000, -1000, 391, 3152, 3194, 3846, 261, -1000, 647,
- 215, 3846, 80, -9, 3846, 389, 3846, 3846, -19, -1000,
- 2050, 2318, -1000, -1000, -1000, -1000, 131, -1000, 2720, 968,
- 304, 304, -1000, -1000, -1000, -1000, -1000, 2845, 2845, 2845,
- 2845, 2845, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
- -1000, -1000, -1000, -1000, -1000, 304, 6, -1000, 2587, 304,
- 304, 304, 2720, 304, -1000, -1000, -1000, 304, 304, 304,
- -1000, -1000, 302, -1000, 208, 408, 218, 294, 3846, -1000,
- -1000, 3804, 3478, 3478, 3478, 3478, -1000, 364, 357, 356,
- 362, 3846, -1000, 254, 218, 3152, -1000, -1000, 3520, -1000,
- -1000, 451, 1168, 114, 84, -90, -1000, -1000, 310, -1000,
- 310, 310, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
- -1000, 310, 310, 310, -1000, -1000, -1000, -1000, -1000, -1000,
- -1000, 341, 341, 341, 311, 311, 345, -1000, 386, -41,
- -30, -1000, -1000, -1000, -1000, 3846, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+ -1000, -1000, -1000, -1000, 313, -1000, -1000, 3047, 19, 2785,
+ 2785, 246, 2785, 2785, 42, 2912, 164, 94, 2912, 2912,
+ 2912, 2912, 2912, 2912, 2912, 2912, 2912, 2912, 2912, 2912,
+ 2912, 2912, 2912, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+ -1000, 209, -1000, 344, -1000, -1000, -1000, -1000, 1017, 866,
+ 2094, 265, 74, 2650, 2785, 3883, 414, 62, 74, 3883,
+ 2377, 2377, 2377, 2785, -1000, -1000, -1000, -1000, -1000, -1000,
+ 3883, 316, -1000, 3089, -1000, 314, -1000, 56, -1000, 16,
+ 444, 353, 306, -1000, -1000, -1000, -1000, 378, -1000, -1000,
+ -1000, -1000, -1000, 182, -1000, 434, 2785, 292, 1200, -1000,
+ -1000, -1000, -1000, -1000, -1000, -1000, -1000, 343, 397, 48,
+ 201, -1000, -1000, 389, -1000, 115, -91, -1000, -1000, 161,
+ -1000, -1000, -1000, -1000, -1000, -1000, 149, -1000, -1000, -1000,
+ 140, -1000, 358, -1000, 188, -1000, 3925, 3883, -1000, -1000,
+ 445, 2377, 3553, -1000, -1000, 3430, -1000, -1000, 1796, 42,
+ 79, -1000, -1000, 122, -1000, -1000, 74, 74, 665, -1000,
+ -1000, -1000, -1000, 164, 2912, 2912, 2912, 14, 665, 858,
+ 793, 503, -1000, 154, 154, -1, -1, -1, -1, -1,
+ 184, 184, 182, -1000, 182, 2377, 291, 316, 12, -1000,
+ 2785, -1000, 175, 290, 2377, 76, -1000, 2785, 182, 238,
+ 238, 238, -1000, 287, 269, -1000, -1000, 2512, 182, 245,
+ 11, 434, 3883, 2785, 2094, -1000, -1000, 2785, 341, -1000,
+ -1000, -1000, 424, 74, 1349, -1000, 1349, 3760, -1000, 179,
+ -1000, -1000, -84, 13, -1000, -1000, -1000, 232, 286, 241,
+ 3925, -1000, -1000, -28, 446, -1000, 271, -1000, -1000, -6,
+ -1000, -1000, -1000, -1000, 14, 665, 783, -1000, 2912, 2912,
+ -1000, -1000, 238, 2377, 1945, 74, 340, 2912, 300, 41,
+ -1000, 2785, 145, -1000, -1000, -1000, -1000, 316, -1000, -1000,
+ 375, 3760, 3760, 424, -1000, 74, -1000, 74, 3760, -1000,
+ 1200, -1000, 216, -1000, 335, -1000, 40, -1000, -1000, -1000,
+ -1000, -1000, -1000, -1000, 133, -1000, 132, 1647, 3883, 438,
+ 426, 1498, -1000, 2912, 665, 665, -1000, 182, -1000, 182,
+ 335, -1000, 335, 339, 335, -54, 335, -56, 335, 335,
+ 335, 335, 335, 335, -1000, 627, -104, -1000, 74, 2785,
+ -1000, 316, -1000, 344, -10, -1000, -1000, 178, -1000, -1000,
+ 3760, -1000, -1000, 394, -1000, 393, 217, 185, -1000, -1000,
+ -1000, -1000, -1000, 2785, 2785, -1000, 665, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
- 286, -1000, -1000, 2978, 5, 2720, 2720, 117, 2720, 2720,
- 43, 2845, 135, 71, 2845, 2845, 2845, 2845, 2845, 2845,
- 2845, 2845, 2845, 2845, 2845, 2845, 2845, 2845, 2845, -1000,
- -1000, -1000, -1000, -1000, -1000, -1000, -1000, 209, -1000, 331,
- -1000, -1000, -1000, -1000, 989, 2185, 1903, 241, 133, 2587,
- 2720, 3804, 394, 64, 133, 3804, 2318, 2318, 2318, 2720,
- -1000, -1000, -1000, -1000, -1000, -1000, 3804, 304, -1000, 3020,
- -1000, 306, -1000, 54, -1000, 4, 343, 334, 273, -1000,
- -1000, -1000, -1000, 355, -1000, -1000, -1000, -1000, -1000, 218,
- -1000, 428, 2720, 299, 839, -1000, -1000, -1000, -1000, -1000,
- -1000, -1000, -1000, 314, 380, 49, 206, -1000, -1000, 370,
- -1000, 103, -92, -1000, -1000, 160, -1000, -1000, -1000, -1000,
- -1000, -1000, 155, -1000, -1000, -1000, 154, -1000, 3846, -1000,
- 204, -1000, 3846, 3804, -1000, 451, 2318, 3478, -1000, -1000,
- 3357, -1000, -1000, 1609, 43, 56, -1000, -1000, 127, -1000,
- -1000, 133, 133, 2572, -1000, -1000, -1000, -1000, 135, 2845,
- 2845, 2845, 371, 2572, 2436, 1086, 715, -1000, 143, 143,
- 24, 24, 24, 24, 24, 19, 19, 218, -1000, 218,
- 2318, 298, 304, 3, -1000, 2720, -1000, 200, 296, 2318,
- 70, -1000, 2720, 218, 224, 224, 224, -1000, 295, 283,
- -1000, -1000, 2451, 218, 231, 2, 428, 3804, 2720, 1903,
- -1000, -1000, 2720, 312, -1000, -1000, -1000, 408, 133, 1168,
- -1000, 1168, 3683, -1000, 172, -1000, -1000, -85, 12, -1000,
- -1000, -1000, 234, 291, 226, 1462, -1000, -1000, -20, 446,
- -1000, 284, -1000, -1000, 0, -1000, -1000, -1000, -1000, 371,
- 2572, 1072, -1000, 2845, 2845, -1000, -1000, 224, 2318, 1756,
- 133, 2889, 2845, 278, 60, -1000, 2720, 183, -1000, -1000,
- -1000, -1000, 304, -1000, -1000, 277, 3683, 3683, 408, -1000,
- 133, -1000, 133, 3683, -1000, 839, -1000, 181, -1000, 310,
- -1000, 36, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 147,
- -1000, 122, -1000, -1000, -1000, 3804, 430, 413, 1315, -1000,
- 2845, 2572, 2572, -1000, 218, -1000, 218, 310, -1000, 310,
- 311, 310, -55, 310, -60, 310, 310, 310, 310, 310,
- 310, -1000, 2175, -103, -1000, 133, 2720, -1000, 304, -1000,
- 331, -3, -1000, -1000, 178, -1000, -1000, 3683, -1000, -1000,
- 376, -1000, 374, 232, 227, -1000, -1000, 2720, 2720, -1000,
- 2572, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
- -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2845, 218, 166,
- 133, 283, 218, 3683, 3683, -1000, -1000, -1000, -1000, -1000,
- -1000, 133, 280, 2304, -1000, -1000, -1000, -1000, -1000, -1000,
+ -1000, -1000, -1000, 2912, 182, 170, 74, 269, 182, 3760,
+ 3760, -1000, -1000, -1000, -1000, -1000, -1000, 74, 255, 742,
+ -1000, -1000, -1000, -1000, -1000, -1000,
}
var yyPgo = [...]int{
- 0, 626, 29, 384, 625, 624, 619, 618, 617, 613,
- 609, 601, 600, 599, 598, 444, 597, 592, 589, 36,
- 588, 13, 51, 7, 26, 8, 585, 22, 52, 46,
- 584, 27, 583, 582, 42, 581, 152, 579, 577, 31,
- 576, 574, 569, 568, 567, 10, 564, 563, 561, 556,
- 548, 16, 1, 4, 34, 9, 546, 134, 40, 545,
- 18, 544, 543, 542, 540, 12, 535, 37, 534, 11,
- 533, 532, 44, 17, 526, 525, 112, 522, 521, 35,
- 0, 20, 14, 21, 520, 622, 32, 41, 518, 516,
- 515, 514, 512, 510, 508, 507, 503, 498, 182, 496,
- 495, 487, 43, 6, 485, 483, 482, 25, 481, 28,
- 479, 478, 476, 15, 5, 475, 2, 474, 33, 473,
- 472, 119, 3, 470,
+ 0, 663, 16, 405, 661, 655, 652, 650, 649, 648,
+ 646, 645, 644, 643, 634, 640, 631, 629, 628, 45,
+ 623, 13, 51, 7, 36, 8, 622, 31, 54, 47,
+ 620, 34, 618, 616, 44, 614, 53, 609, 607, 40,
+ 605, 604, 603, 602, 597, 10, 594, 593, 579, 574,
+ 573, 25, 1, 4, 28, 9, 572, 490, 27, 568,
+ 21, 566, 559, 553, 551, 12, 550, 43, 549, 11,
+ 548, 545, 30, 18, 544, 540, 105, 61, 539, 15,
+ 0, 20, 35, 26, 538, 647, 22, 41, 537, 531,
+ 530, 527, 526, 525, 524, 517, 515, 513, 152, 512,
+ 510, 509, 37, 6, 500, 498, 492, 32, 491, 29,
+ 489, 487, 486, 14, 5, 485, 2, 484, 33, 483,
+ 478, 472, 119, 3, 470,
}
var yyR1 = [...]int{
- 0, 119, 120, 120, 1, 1, 1, 1, 1, 1,
+ 0, 120, 121, 121, 1, 1, 1, 1, 1, 1,
1, 1, 1, 2, 2, 3, 3, 4, 4, 5,
5, 6, 6, 18, 18, 18, 7, 8, 9, 9,
12, 110, 111, 111, 111, 107, 92, 92, 92, 95,
@@ -947,47 +960,48 @@ var yyR1 = [...]int{
106, 106, 106, 106, 108, 115, 115, 115, 115, 109,
109, 117, 117, 116, 112, 112, 112, 113, 113, 113,
114, 114, 114, 10, 10, 10, 118, 118, 11, 11,
- 13, 13, 13, 13, 14, 14, 123, 15, 16, 16,
- 17, 17, 19, 19, 23, 23, 22, 22, 24, 24,
- 24, 24, 84, 84, 84, 83, 83, 26, 27, 27,
- 28, 28, 29, 29, 29, 29, 38, 71, 71, 30,
- 30, 30, 31, 31, 32, 32, 89, 89, 88, 88,
- 88, 87, 87, 33, 33, 33, 34, 34, 35, 35,
- 37, 37, 36, 36, 39, 39, 25, 25, 25, 25,
- 25, 25, 25, 75, 75, 41, 41, 40, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 50, 50, 50,
- 50, 50, 50, 42, 42, 42, 42, 42, 42, 42,
- 21, 21, 51, 51, 51, 57, 52, 52, 45, 45,
+ 13, 13, 13, 13, 13, 119, 119, 14, 14, 124,
+ 15, 16, 16, 17, 17, 19, 19, 23, 23, 22,
+ 22, 24, 24, 24, 24, 84, 84, 84, 83, 83,
+ 26, 27, 27, 28, 28, 29, 29, 29, 29, 38,
+ 71, 71, 30, 30, 30, 31, 31, 32, 32, 89,
+ 89, 88, 88, 88, 87, 87, 33, 33, 33, 34,
+ 34, 35, 35, 37, 37, 36, 36, 39, 39, 25,
+ 25, 25, 25, 25, 25, 25, 75, 75, 41, 41,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 50, 50, 50, 50, 50, 50, 42, 42, 42, 42,
+ 42, 42, 42, 21, 21, 51, 51, 51, 57, 52,
+ 52, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 48, 48, 48, 46, 46, 46,
- 46, 46, 46, 47, 47, 47, 49, 49, 49, 91,
- 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
- 91, 91, 91, 91, 91, 91, 61, 61, 20, 20,
- 59, 59, 60, 62, 62, 58, 58, 58, 44, 44,
- 44, 44, 44, 44, 44, 63, 63, 64, 64, 65,
- 65, 66, 66, 67, 68, 68, 68, 69, 69, 69,
- 69, 43, 43, 43, 43, 43, 43, 70, 70, 70,
- 70, 53, 53, 55, 55, 54, 56, 72, 72, 73,
- 76, 76, 77, 77, 74, 74, 78, 78, 78, 81,
- 81, 82, 82, 85, 85, 86, 86, 79, 79, 79,
+ 45, 45, 45, 45, 45, 45, 45, 48, 48, 48,
+ 46, 46, 46, 46, 46, 46, 47, 47, 47, 49,
+ 49, 49, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 61,
+ 61, 20, 20, 59, 59, 60, 62, 62, 58, 58,
+ 58, 44, 44, 44, 44, 44, 44, 44, 63, 63,
+ 64, 64, 65, 65, 66, 66, 67, 68, 68, 68,
+ 69, 69, 69, 69, 43, 43, 43, 43, 43, 43,
+ 70, 70, 70, 70, 53, 53, 55, 55, 54, 56,
+ 72, 72, 73, 76, 76, 77, 77, 74, 74, 78,
+ 78, 78, 81, 81, 82, 82, 85, 85, 86, 86,
79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
+ 79, 80, 80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 121, 122, 90, 90, 90,
+ 80, 80, 80, 80, 80, 80, 80, 122, 123, 90,
+ 90, 90,
}
var yyR2 = [...]int{
0, 2, 0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 3, 5, 8, 4, 1, 3, 1,
- 3, 5, 6, 1, 1, 3, 8, 7, 2, 7,
+ 3, 5, 6, 1, 1, 3, 8, 7, 2, 8,
4, 4, 1, 3, 3, 6, 3, 1, 1, 2,
1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 2, 1, 2, 2, 2, 1, 2, 2, 1,
@@ -997,29 +1011,29 @@ var yyR2 = [...]int{
2, 1, 2, 1, 4, 2, 3, 2, 2, 1,
1, 1, 3, 2, 0, 1, 3, 1, 2, 3,
1, 1, 1, 6, 6, 8, 0, 1, 4, 4,
- 4, 5, 3, 2, 2, 2, 0, 2, 0, 2,
- 1, 2, 0, 1, 0, 1, 1, 3, 1, 2,
- 3, 5, 0, 1, 2, 1, 1, 2, 1, 3,
- 1, 1, 1, 1, 3, 3, 2, 1, 3, 4,
- 4, 3, 2, 4, 0, 1, 0, 1, 0, 1,
- 2, 1, 1, 1, 2, 2, 2, 3, 2, 2,
- 2, 1, 1, 3, 0, 2, 1, 3, 3, 2,
- 3, 1, 2, 0, 3, 1, 1, 3, 3, 4,
- 4, 5, 3, 4, 5, 6, 2, 1, 2, 1,
- 2, 1, 2, 1, 1, 1, 1, 1, 1, 1,
- 0, 2, 1, 1, 1, 3, 1, 3, 1, 1,
- 1, 1, 1, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 2, 2, 2, 2, 3,
- 1, 1, 1, 1, 4, 5, 6, 6, 6, 8,
- 7, 5, 4, 1, 1, 1, 4, 4, 4, 2,
- 1, 2, 2, 2, 1, 2, 2, 1, 2, 2,
- 2, 2, 2, 2, 2, 1, 0, 1, 0, 2,
- 1, 2, 4, 0, 2, 1, 3, 5, 1, 1,
- 1, 1, 1, 1, 1, 0, 3, 0, 2, 0,
- 3, 1, 3, 2, 0, 1, 1, 0, 2, 4,
- 4, 2, 1, 3, 5, 4, 6, 1, 3, 3,
- 5, 1, 3, 1, 2, 3, 1, 1, 3, 3,
- 0, 2, 0, 3, 0, 1, 0, 1, 1, 1,
+ 4, 5, 3, 3, 5, 0, 1, 2, 2, 0,
+ 2, 0, 2, 1, 2, 0, 1, 0, 1, 1,
+ 3, 1, 2, 3, 5, 0, 1, 2, 1, 1,
+ 2, 1, 3, 1, 1, 1, 1, 3, 3, 2,
+ 1, 3, 4, 4, 3, 2, 4, 0, 1, 0,
+ 1, 0, 1, 2, 1, 1, 1, 2, 2, 2,
+ 3, 2, 2, 2, 1, 1, 3, 0, 2, 1,
+ 3, 3, 2, 3, 1, 2, 0, 3, 1, 1,
+ 3, 3, 4, 4, 5, 3, 4, 5, 6, 2,
+ 1, 2, 1, 2, 1, 2, 1, 1, 1, 1,
+ 1, 1, 1, 0, 2, 1, 1, 1, 3, 1,
+ 3, 1, 1, 1, 1, 1, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 2, 2,
+ 2, 2, 3, 1, 1, 1, 1, 4, 5, 6,
+ 6, 6, 8, 7, 5, 4, 1, 1, 1, 4,
+ 4, 4, 2, 1, 2, 2, 2, 1, 2, 2,
+ 1, 2, 2, 2, 2, 2, 2, 2, 1, 0,
+ 1, 0, 2, 1, 2, 4, 0, 2, 1, 3,
+ 5, 1, 1, 1, 1, 1, 1, 1, 0, 3,
+ 0, 2, 0, 3, 1, 3, 2, 0, 1, 1,
+ 0, 2, 4, 4, 2, 1, 3, 5, 4, 6,
+ 1, 3, 3, 5, 1, 3, 1, 2, 3, 1,
+ 1, 3, 3, 0, 2, 0, 3, 0, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -1031,175 +1045,178 @@ var yyR2 = [...]int{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 0, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 1, 1,
}
var yyChk = [...]int{
- -1000, -119, -1, -2, -6, -7, -8, -9, -10, -11,
- -13, -14, -3, -4, -18, 8, 9, -12, 91, 92,
- 93, 106, 23, 107, 6, -121, 7, 146, 39, -120,
- 152, -65, 14, -17, 5, -15, -123, -15, -15, -110,
- 39, -78, 96, 101, -81, 42, -80, 115, 134, 128,
- 126, 108, 124, 120, 118, 119, 105, 113, 114, 29,
- 137, 133, 136, 112, 132, 129, 121, 17, 102, 117,
- 139, 111, 130, 122, 123, 135, 110, 131, 140, 151,
- 127, 125, 141, 96, 96, 97, 91, 97, 96, 142,
- -36, -85, 42, -80, -36, -15, -2, 54, -69, 16,
- 15, -5, -3, -121, 18, -74, 99, -16, -27, -28,
- -29, -30, -38, -57, -121, -36, 10, -111, -107, 42,
- 97, -77, 100, -36, -76, 100, -76, 96, 10, -36,
- 90, -19, 19, -122, 41, 146, -25, -40, 56, -45,
- 26, 21, -44, -41, -58, -56, -57, 79, 80, 87,
- 57, 89, -48, -46, -47, -49, 44, 43, 45, 46,
- 47, 48, 51, 52, 53, -81, -85, -54, -121, 147,
- 148, 149, 59, 28, 143, 144, 145, 100, 85, 146,
- 42, -80, -66, -67, -25, -65, -2, -37, 24, -36,
- 50, 27, 40, -33, -34, -35, 30, 33, 35, 31,
- 36, -89, 20, -27, -2, -121, -88, -87, 20, -85,
- 44, -36, 41, 40, -92, -95, -97, -96, -93, -94,
- 126, 127, 130, 131, 132, 133, 134, 135, 136, 137,
- 108, 122, 123, 124, 125, 110, 111, 112, 113, 114,
- 115, 117, 118, 119, 120, 121, 42, -36, 56, 95,
- 94, -36, 21, -36, -36, 96, -86, -85, -79, 95,
- 55, 20, 22, 138, 58, 15, 59, 91, 35, 144,
- 145, 143, 148, 26, 9, 23, 107, 19, 83, 93,
- 62, 63, 109, 21, 53, 10, 12, 13, 100, 99,
- 73, 97, 33, 7, 89, 24, 70, 30, 25, 31,
- 71, 16, 85, 36, 56, 51, 37, 54, 14, 34,
- 72, 94, 146, 32, 6, 150, 27, 106, 96, 142,
- 61, 98, 52, 5, 101, 8, 38, 28, 60, 11,
- -22, -24, 81, -25, -85, 55, 54, 70, 40, 17,
- -25, -42, 73, 56, 71, 72, 58, 76, 75, 86,
- 79, 80, 81, 82, 83, 84, 85, 77, 78, 64,
- 65, 66, 67, 68, 69, 74, -75, -121, -57, -121,
- -45, -45, -45, -45, -45, -121, 90, -52, -25, -121,
- -121, -121, -121, -61, -25, -121, -121, -121, -121, 40,
- -68, 22, 23, -69, -122, -43, 27, 28, -2, -121,
- -36, -72, -73, -58, -81, -85, -28, -29, -28, -29,
- 30, 30, 30, 34, 30, -34, -85, -122, -122, -2,
- -87, -39, 11, -112, -113, -114, -82, 44, 45, -81,
- -79, -107, -108, -115, 102, 101, -109, 97, 25, -104,
- 51, 56, -100, 140, -98, 39, -98, -98, -98, -98,
- -98, -102, 39, -102, -102, -103, 39, -103, 37, 21,
- -118, 103, 98, -118, -36, -26, 40, 10, -84, -83,
- 20, -81, 44, 90, -25, -25, -50, 51, 56, 52,
- 53, -25, -25, -45, -51, -54, -57, 49, 73, 71,
- 72, 58, -45, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, -45, -45, -45, -45, -45, 42, -81, -23,
- 19, -22, -82, -86, -79, 40, -122, -25, -58, -19,
- -59, -60, 60, -58, -22, -22, -22, -67, -72, -53,
- -55, -54, -121, -2, -70, -81, -39, 40, 64, 90,
- -32, -31, 37, 38, -31, 30, -122, -65, -25, 40,
- -114, 64, 39, 25, -109, 42, 42, -99, 26, 51,
- -101, 141, 45, 45, 45, -36, -107, -36, -58, -39,
- -24, -27, -83, 81, -86, 51, 52, 53, -51, -45,
- -45, -45, -21, 109, 55, -122, -122, -22, -121, 90,
- -25, 20, 40, -22, -62, -60, 62, -25, -122, -122,
- -122, -122, 40, -122, -122, -122, 40, 90, -65, -73,
- -25, -82, -25, 39, -69, -113, -114, -117, -116, -81,
- 42, -105, 138, 44, 45, 46, 51, 143, 41, 40,
- 41, 40, -90, -121, -82, 98, -63, 12, 90, -21,
- 55, -45, -45, -122, -23, -82, -91, 126, 108, 124,
- 120, 129, 139, 122, 140, 123, 113, 110, 111, 112,
- 115, 44, -45, -65, 63, -25, 61, -55, 28, -2,
- -121, -81, -81, -69, -71, -81, 41, 40, -98, -106,
- 102, 25, 101, 45, 45, -58, -64, 13, 15, 81,
- -45, -122, -122, -98, -98, -103, -98, 114, -98, 114,
- -98, -98, -98, -98, -98, -98, -122, 40, -20, 150,
- -25, -53, -2, 90, 40, 41, -116, 25, 25, 41,
- 41, -25, -52, -45, -122, 44, -122, -81, -81, -122,
+ -1000, -120, -1, -2, -6, -7, -8, -9, -10, -11,
+ -13, -14, -3, -4, -18, 8, 9, -12, 93, 94,
+ 95, 108, 23, 109, 6, -122, 7, 148, 39, -121,
+ 154, -65, 14, -17, 5, -15, -124, -15, -15, -110,
+ 39, -78, 98, 103, -81, 42, -80, 117, 136, 130,
+ 128, 110, 126, 122, 120, 121, 107, 115, 116, 29,
+ 139, 135, 138, 114, 134, 131, 123, 17, 104, 119,
+ 141, 113, 132, 124, 125, 137, 112, 133, 142, 153,
+ 129, 127, 143, 98, 98, 99, 93, 99, 98, -119,
+ 54, -36, -85, 42, -80, -36, -15, -2, 56, -69,
+ 16, 15, -5, -3, -122, 18, -74, 101, -16, -27,
+ -28, -29, -30, -38, -57, -122, -36, 10, -111, -107,
+ 42, 99, -77, 102, -36, -76, 102, -76, 98, 10,
+ -36, 144, 55, 92, -19, 19, -123, 41, 148, -25,
+ -40, 58, -45, 26, 21, -44, -41, -58, -56, -57,
+ 81, 82, 89, 59, 91, -48, -46, -47, -49, 44,
+ 43, 45, 46, 47, 48, 51, 52, 53, -81, -85,
+ -54, -122, 149, 150, 151, 61, 28, 145, 146, 147,
+ 102, 87, 148, 42, -80, -66, -67, -25, -65, -2,
+ -37, 24, -36, 50, 27, 40, -33, -34, -35, 30,
+ 33, 35, 31, 36, -89, 20, -27, -2, -122, -88,
+ -87, 20, -85, 44, -36, 41, 40, -92, -95, -97,
+ -96, -93, -94, 128, 129, 132, 133, 134, 135, 136,
+ 137, 138, 139, 110, 124, 125, 126, 127, 112, 113,
+ 114, 115, 116, 117, 119, 120, 121, 122, 123, -77,
+ -36, 58, 97, 96, -36, 21, -36, -36, 98, 10,
+ -86, -85, -79, 97, 57, 20, 22, 140, 60, 15,
+ 61, 93, 35, 146, 147, 145, 150, 26, 9, 23,
+ 109, 19, 85, 95, 64, 65, 111, 21, 53, 10,
+ 12, 13, 102, 101, 75, 99, 33, 7, 91, 24,
+ 72, 30, 25, 31, 73, 16, 87, 36, 58, 51,
+ 37, 56, 14, 34, 74, 96, 148, 32, 6, 152,
+ 27, 108, 98, 144, 63, 100, 52, 5, 103, 8,
+ 38, 28, 62, 11, -22, -24, 83, -25, -85, 57,
+ 56, 72, 40, 17, -25, -42, 75, 58, 73, 74,
+ 60, 78, 77, 88, 81, 82, 83, 84, 85, 86,
+ 87, 79, 80, 66, 67, 68, 69, 70, 71, 76,
+ -75, -122, -57, -122, -45, -45, -45, -45, -45, -122,
+ 92, -52, -25, -122, -122, -122, -122, -61, -25, -122,
+ -122, -122, -122, 40, -68, 22, 23, -69, -123, -43,
+ 27, 28, -2, -122, -36, -72, -73, -58, -81, -85,
+ -28, -29, -28, -29, 30, 30, 30, 34, 30, -34,
+ -85, -123, -123, -2, -87, -39, 11, -112, -113, -114,
+ -82, 44, 45, -81, -79, -107, -108, -115, 104, 103,
+ -109, 99, 25, -104, 51, 58, -100, 142, -98, 39,
+ -98, -98, -98, -98, -98, -102, 39, -102, -102, -103,
+ 39, -103, 42, 21, -118, 105, 100, -118, -36, -36,
+ -26, 40, 10, -84, -83, 20, -81, 44, 92, -25,
+ -25, -50, 51, 58, 52, 53, -25, -25, -45, -51,
+ -54, -57, 49, 75, 73, 74, 60, -45, -45, -45,
+ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, 42, -81, -23, 19, -22, -82, -86, -79,
+ 40, -123, -25, -58, -19, -59, -60, 62, -58, -22,
+ -22, -22, -67, -72, -53, -55, -54, -122, -2, -70,
+ -81, -39, 40, 66, 92, -32, -31, 37, 38, -31,
+ 30, -123, -65, -25, 40, -114, 66, 39, 25, -109,
+ 42, 42, -99, 26, 51, -101, 143, 45, 45, 45,
+ 37, -107, -36, -58, -39, -24, -27, -83, 83, -86,
+ 51, 52, 53, -51, -45, -45, -45, -21, 111, 57,
+ -123, -123, -22, -122, 92, -25, 20, 40, -22, -62,
+ -60, 64, -25, -123, -123, -123, -123, 40, -123, -123,
+ -123, 40, 92, -65, -73, -25, -82, -25, 39, -69,
+ -113, -114, -117, -116, -81, 42, -105, 140, 44, 45,
+ 46, 51, 145, 41, 40, 41, 40, -36, 100, -63,
+ 12, 92, -21, 57, -45, -45, -123, -23, -82, -91,
+ 128, 110, 126, 122, 131, 141, 124, 142, 125, 115,
+ 112, 113, 114, 117, 44, -45, -65, 65, -25, 63,
+ -55, 28, -2, -122, -81, -81, -69, -71, -81, 41,
+ 40, -98, -106, 104, 25, 103, 45, 45, -90, -122,
+ -82, -58, -64, 13, 15, 83, -45, -123, -123, -98,
+ -98, -103, -98, 116, -98, 116, -98, -98, -98, -98,
+ -98, -98, -123, 40, -20, 152, -25, -53, -2, 92,
+ 40, 41, -116, 25, 25, 41, 41, -25, -52, -45,
+ -123, 44, -123, -81, -81, -123,
}
var yyDef = [...]int{
0, -2, 2, -2, 5, 6, 7, 8, 9, 10,
- 11, 12, 309, 0, 126, 126, 126, 0, 346, 0,
- 0, 0, 0, 0, 126, 0, 23, 24, 464, 1,
- 3, 317, 0, 0, 130, 344, 128, 0, 0, 28,
- 0, 0, 342, 347, 348, 349, 350, 428, 429, 430,
- 431, 432, 433, 434, 435, 436, 437, 438, 439, 440,
- 441, 442, 443, 444, 445, 446, 447, 448, 449, 450,
- 451, 452, 453, 454, 455, 456, 457, 458, 459, 460,
- 461, 462, 463, 0, 340, 340, 0, 0, 0, 123,
- 124, 182, 353, 354, 125, 132, 17, 0, 13, 0,
- 0, 309, 19, 0, 131, 0, 345, 127, 0, 148,
- 150, 151, 152, -2, 0, 168, 0, 0, 32, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 122,
- 0, 0, 133, 18, 465, 25, 318, 186, 0, 191,
- 193, 0, 228, 229, 230, 231, 232, 0, 0, 0,
- 0, 0, 250, 251, 252, 253, 298, 299, 300, 301,
- 302, 303, 304, 195, 196, 295, 0, 336, 0, 0,
- 0, 0, 286, 0, 263, 264, 265, 0, 0, 0,
- -2, -2, 310, 311, 314, 317, 17, 0, 0, 181,
- 129, 0, 0, 0, 0, 0, 173, 0, 0, 0,
- 0, 0, 167, 0, 17, 0, 156, 169, 0, 171,
- 172, 184, 104, 0, 78, 74, 37, 38, 67, 40,
- 67, 67, 59, 60, 61, 62, 63, 64, 65, 66,
- 52, 67, 67, 67, 56, 41, 42, 43, 44, 45,
- 46, 69, 69, 69, 71, 71, 0, 30, 0, 116,
- 116, 118, 341, 119, 120, 0, 183, 355, 356, 357,
- 358, 359, 360, 361, 362, 363, 364, 365, 366, 367,
- 368, 369, 370, 371, 372, 373, 374, 375, 376, 377,
- 378, 379, 380, 381, 382, 383, 384, 385, 386, 387,
- 388, 389, 390, 391, 392, 393, 394, 395, 396, 397,
- 398, 399, 400, 401, 402, 403, 404, 405, 406, 407,
- 408, 409, 410, 411, 412, 413, 414, 415, 416, 417,
- 418, 419, 420, 421, 422, 423, 424, 425, 426, 427,
- 16, 136, 138, 142, 0, 0, 0, 0, 0, 0,
- 189, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 213,
- 214, 215, 216, 217, 218, 219, 192, 0, 206, 0,
- 245, 246, 247, 248, 0, 134, 0, 0, 226, 0,
- 0, 0, 132, 0, 287, 0, 0, 0, 0, 0,
- 313, 315, 316, 14, 20, 21, 0, 0, -2, 0,
- 180, 184, 337, 0, 295, 0, 149, 164, 0, 161,
- 174, 175, 176, 0, 178, 179, 154, 155, 225, 17,
- 170, 309, 0, 31, 105, 107, 110, 111, 112, 351,
- 352, 33, 34, 0, 0, 0, 0, 99, 100, 81,
- 79, 0, 76, 75, 39, 0, 57, 58, 53, 54,
- 55, 47, 0, 48, 49, 50, 0, 51, 0, 343,
- 0, 117, 0, 0, 121, 184, 0, 0, 139, 143,
- 0, 145, 146, 0, 187, 188, 190, 207, 0, 209,
- 211, 319, 320, 197, 198, 222, 223, 224, 0, 0,
- 0, 0, 220, 202, 0, 233, 234, 235, 236, 237,
- 238, 239, 240, 241, 242, 243, 244, 0, 249, 0,
- 0, 135, 296, 0, -2, 0, 335, 0, 0, 0,
- 293, 290, 0, 0, 0, 0, 0, 312, 22, 321,
- 331, 333, 0, 17, 0, 327, 309, 0, 0, 0,
- 159, 165, 0, 0, 160, 177, -2, 317, 185, 0,
- 108, 0, 0, 95, 0, 97, 98, 87, 0, 80,
- 36, 77, 0, 0, 0, 466, 113, 114, 0, 305,
- 137, 147, 144, 140, 0, 208, 210, 212, 199, 220,
- 203, 0, 200, 0, 0, 194, 254, 0, 134, 0,
- 227, 0, 0, 309, 0, 291, 0, 0, 262, 266,
- 267, 268, 0, 334, -2, 0, 0, 0, 317, 338,
- 339, 296, 162, 0, 27, 106, 109, 0, 101, 67,
- 96, 89, 88, 82, 83, 84, 85, 86, 68, 0,
- 72, 0, 29, 467, 468, 0, 307, 0, 0, 201,
- 0, 221, 204, 255, 0, 297, 0, 67, 270, 67,
- 71, 67, 274, 67, 277, 67, 67, 67, 67, 67,
- 67, 285, 0, 288, 261, 294, 0, 332, 0, -2,
- 0, 329, 328, 26, 0, 157, 94, 0, 103, 35,
- 0, 91, 93, 0, 0, 115, 15, 0, 0, 141,
- 205, 256, 257, 269, 271, 272, 273, 275, 276, 278,
- 279, 280, 281, 282, 283, 284, 258, 0, 0, 0,
- 292, 324, 17, 0, 0, 163, 102, 90, 92, 70,
- 73, 308, 306, 0, 260, 289, -2, 330, 158, 259,
+ 11, 12, 312, 0, 129, 129, 129, 0, 349, 0,
+ 0, 125, 0, 0, 129, 0, 23, 24, 467, 1,
+ 3, 320, 0, 0, 133, 347, 131, 0, 0, 28,
+ 0, 0, 345, 350, 351, 352, 353, 431, 432, 433,
+ 434, 435, 436, 437, 438, 439, 440, 441, 442, 443,
+ 444, 445, 446, 447, 448, 449, 450, 451, 452, 453,
+ 454, 455, 456, 457, 458, 459, 460, 461, 462, 463,
+ 464, 465, 466, 0, 343, 343, 0, 0, 0, 0,
+ 126, 127, 185, 356, 357, 128, 135, 17, 0, 13,
+ 0, 0, 312, 19, 0, 134, 0, 348, 130, 0,
+ 151, 153, 154, 155, -2, 0, 171, 0, 0, 32,
+ 0, 345, 0, 0, 0, 0, 0, 0, 0, 0,
+ 122, 123, 0, 0, 0, 136, 18, 468, 25, 321,
+ 189, 0, 194, 196, 0, 231, 232, 233, 234, 235,
+ 0, 0, 0, 0, 0, 253, 254, 255, 256, 301,
+ 302, 303, 304, 305, 306, 307, 198, 199, 298, 0,
+ 339, 0, 0, 0, 0, 289, 0, 266, 267, 268,
+ 0, 0, 0, -2, -2, 313, 314, 317, 320, 17,
+ 0, 0, 184, 132, 0, 0, 0, 0, 0, 176,
+ 0, 0, 0, 0, 0, 170, 0, 17, 0, 159,
+ 172, 0, 174, 175, 187, 104, 0, 78, 74, 37,
+ 38, 67, 40, 67, 67, 59, 60, 61, 62, 63,
+ 64, 65, 66, 52, 67, 67, 67, 56, 41, 42,
+ 43, 44, 45, 46, 69, 69, 69, 71, 71, 0,
+ 30, 0, 116, 116, 118, 344, 119, 120, 0, 0,
+ 186, 358, 359, 360, 361, 362, 363, 364, 365, 366,
+ 367, 368, 369, 370, 371, 372, 373, 374, 375, 376,
+ 377, 378, 379, 380, 381, 382, 383, 384, 385, 386,
+ 387, 388, 389, 390, 391, 392, 393, 394, 395, 396,
+ 397, 398, 399, 400, 401, 402, 403, 404, 405, 406,
+ 407, 408, 409, 410, 411, 412, 413, 414, 415, 416,
+ 417, 418, 419, 420, 421, 422, 423, 424, 425, 426,
+ 427, 428, 429, 430, 16, 139, 141, 145, 0, 0,
+ 0, 0, 0, 0, 192, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 216, 217, 218, 219, 220, 221, 222,
+ 195, 0, 209, 0, 248, 249, 250, 251, 0, 137,
+ 0, 0, 229, 0, 0, 0, 135, 0, 290, 0,
+ 0, 0, 0, 0, 316, 318, 319, 14, 20, 21,
+ 0, 0, -2, 0, 183, 187, 340, 0, 298, 0,
+ 152, 167, 0, 164, 177, 178, 179, 0, 181, 182,
+ 157, 158, 228, 17, 173, 312, 0, 31, 105, 107,
+ 110, 111, 112, 354, 355, 33, 34, 0, 0, 0,
+ 0, 99, 100, 81, 79, 0, 76, 75, 39, 0,
+ 57, 58, 53, 54, 55, 47, 0, 48, 49, 50,
+ 0, 51, 0, 346, 0, 117, 0, 0, 121, 124,
+ 187, 0, 0, 142, 146, 0, 148, 149, 0, 190,
+ 191, 193, 210, 0, 212, 214, 322, 323, 200, 201,
+ 225, 226, 227, 0, 0, 0, 0, 223, 205, 0,
+ 236, 237, 238, 239, 240, 241, 242, 243, 244, 245,
+ 246, 247, 0, 252, 0, 0, 138, 299, 0, -2,
+ 0, 338, 0, 0, 0, 296, 293, 0, 0, 0,
+ 0, 0, 315, 22, 324, 334, 336, 0, 17, 0,
+ 330, 312, 0, 0, 0, 162, 168, 0, 0, 163,
+ 180, -2, 320, 188, 0, 108, 0, 0, 95, 0,
+ 97, 98, 87, 0, 80, 36, 77, 0, 0, 0,
+ 0, 113, 114, 0, 308, 140, 150, 147, 143, 0,
+ 211, 213, 215, 202, 223, 206, 0, 203, 0, 0,
+ 197, 257, 0, 137, 0, 230, 0, 0, 312, 0,
+ 294, 0, 0, 265, 269, 270, 271, 0, 337, -2,
+ 0, 0, 0, 320, 341, 342, 299, 165, 0, 27,
+ 106, 109, 0, 101, 67, 96, 89, 88, 82, 83,
+ 84, 85, 86, 68, 0, 72, 0, 469, 0, 310,
+ 0, 0, 204, 0, 224, 207, 258, 0, 300, 0,
+ 67, 273, 67, 71, 67, 277, 67, 280, 67, 67,
+ 67, 67, 67, 67, 288, 0, 291, 264, 297, 0,
+ 335, 0, -2, 0, 332, 331, 26, 0, 160, 94,
+ 0, 103, 35, 0, 91, 93, 0, 0, 29, 470,
+ 471, 115, 15, 0, 0, 144, 208, 259, 260, 272,
+ 274, 275, 276, 278, 279, 281, 282, 283, 284, 285,
+ 286, 287, 261, 0, 0, 0, 295, 327, 17, 0,
+ 0, 166, 102, 90, 92, 70, 73, 311, 309, 0,
+ 263, 292, -2, 333, 161, 262,
}
var yyTok1 = [...]int{
1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 57, 3, 3, 3, 84, 76, 3,
- 39, 41, 81, 79, 40, 80, 90, 82, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 152,
- 65, 64, 66, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 59, 3, 3, 3, 86, 78, 3,
+ 39, 41, 83, 81, 40, 82, 92, 84, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 154,
+ 67, 66, 68, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 86, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 88, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 75, 3, 87,
+ 3, 3, 3, 3, 77, 3, 89,
}
var yyTok2 = [...]int{
@@ -1208,15 +1225,15 @@ var yyTok2 = [...]int{
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 42, 43, 44,
45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 58, 59, 60, 61, 62, 63, 67, 68,
- 69, 70, 71, 72, 73, 74, 77, 78, 83, 85,
- 88, 89, 91, 92, 93, 94, 95, 96, 97, 98,
+ 55, 56, 57, 58, 60, 61, 62, 63, 64, 65,
+ 69, 70, 71, 72, 73, 74, 75, 76, 79, 80,
+ 85, 87, 90, 91, 93, 94, 95, 96, 97, 98,
99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
139, 140, 141, 142, 143, 144, 145, 146, 147, 148,
- 149, 150, 151,
+ 149, 150, 151, 152, 153,
}
var yyTok3 = [...]int{
0,
@@ -1561,29 +1578,29 @@ yydefault:
case 1:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:242
+ //line sql.y:244
{
setParseTree(yylex, yyDollar[1].statement)
}
case 2:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:247
+ //line sql.y:249
{
}
case 3:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:248
+ //line sql.y:250
{
}
case 4:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:252
+ //line sql.y:254
{
yyVAL.statement = yyDollar[1].selStmt
}
case 13:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:266
+ //line sql.y:268
{
sel := yyDollar[1].selStmt.(*Select)
sel.OrderBy = yyDollar[2].orderBy
@@ -1592,49 +1609,49 @@ yydefault:
}
case 14:
yyDollar = yyS[yypt-5 : yypt+1]
- //line sql.y:273
+ //line sql.y:275
{
yyVAL.selStmt = &Union{Type: yyDollar[2].str, Left: yyDollar[1].selStmt, Right: yyDollar[3].selStmt, OrderBy: yyDollar[4].orderBy, Limit: yyDollar[5].limit}
}
case 15:
yyDollar = yyS[yypt-8 : yypt+1]
- //line sql.y:280
+ //line sql.y:282
{
yyVAL.selStmt = &Select{Comments: Comments(yyDollar[2].bytes2), Distinct: yyDollar[3].str, SelectExprs: yyDollar[4].selectExprs, From: yyDollar[5].tableExprs, Where: NewWhere(WhereStr, yyDollar[6].expr), GroupBy: GroupBy(yyDollar[7].exprs), Having: NewWhere(HavingStr, yyDollar[8].expr)}
}
case 16:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:284
+ //line sql.y:286
{
yyVAL.selStmt = &Select{Comments: Comments(yyDollar[2].bytes2), Distinct: yyDollar[3].str, SelectExprs: yyDollar[4].selectExprs}
}
case 17:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:290
+ //line sql.y:292
{
yyVAL.selStmt = yyDollar[1].selStmt
}
case 18:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:294
+ //line sql.y:296
{
yyVAL.selStmt = &ParenSelect{Select: yyDollar[2].selStmt}
}
case 19:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:300
+ //line sql.y:302
{
yyVAL.selStmt = yyDollar[1].selStmt
}
case 20:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:304
+ //line sql.y:306
{
yyVAL.selStmt = &ParenSelect{Select: yyDollar[2].selStmt}
}
case 21:
yyDollar = yyS[yypt-5 : yypt+1]
- //line sql.y:311
+ //line sql.y:313
{
// insert_data returns a *Insert pre-filled with Columns & Values
ins := yyDollar[5].ins
@@ -1646,7 +1663,7 @@ yydefault:
}
case 22:
yyDollar = yyS[yypt-6 : yypt+1]
- //line sql.y:321
+ //line sql.y:323
{
cols := make(Columns, 0, len(yyDollar[6].updateExprs))
vals := make(ValTuple, 0, len(yyDollar[6].updateExprs))
@@ -1658,84 +1675,84 @@ yydefault:
}
case 23:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:333
+ //line sql.y:335
{
yyVAL.str = InsertStr
}
case 24:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:337
+ //line sql.y:339
{
yyVAL.str = ReplaceStr
}
case 25:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:341
+ //line sql.y:343
{
yyVAL.str = ReplaceStr
}
case 26:
yyDollar = yyS[yypt-8 : yypt+1]
- //line sql.y:347
+ //line sql.y:349
{
yyVAL.statement = &Update{Comments: Comments(yyDollar[2].bytes2), TableExprs: yyDollar[3].tableExprs, Exprs: yyDollar[5].updateExprs, Where: NewWhere(WhereStr, yyDollar[6].expr), OrderBy: yyDollar[7].orderBy, Limit: yyDollar[8].limit}
}
case 27:
yyDollar = yyS[yypt-7 : yypt+1]
- //line sql.y:353
+ //line sql.y:355
{
yyVAL.statement = &Delete{Comments: Comments(yyDollar[2].bytes2), TableExprs: TableExprs{&AliasedTableExpr{Expr: yyDollar[4].tableName}}, Where: NewWhere(WhereStr, yyDollar[5].expr), OrderBy: yyDollar[6].orderBy, Limit: yyDollar[7].limit}
}
case 28:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:359
+ //line sql.y:361
{
yyDollar[1].ddl.TableSpec = yyDollar[2].TableSpec
yyVAL.statement = yyDollar[1].ddl
}
case 29:
- yyDollar = yyS[yypt-7 : yypt+1]
- //line sql.y:364
+ yyDollar = yyS[yypt-8 : yypt+1]
+ //line sql.y:366
{
// Change this to an alter statement
- yyVAL.statement = &DDL{Action: CreateIndexStr, Table: yyDollar[6].tableName, NewName: yyDollar[6].tableName}
+ yyVAL.statement = &DDL{Action: CreateIndexStr, Table: yyDollar[7].tableName, NewName: yyDollar[7].tableName}
}
case 30:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:371
+ //line sql.y:373
{
yyVAL.ddl = &DDL{Action: CreateStr, NewName: yyDollar[4].tableName}
setDDL(yylex, yyVAL.ddl)
}
case 31:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:378
+ //line sql.y:380
{
yyVAL.TableSpec = yyDollar[2].TableSpec
yyVAL.TableSpec.Options = yyDollar[4].str
}
case 32:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:385
+ //line sql.y:387
{
yyVAL.TableSpec = &TableSpec{}
yyVAL.TableSpec.AddColumn(yyDollar[1].columnDefinition)
}
case 33:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:390
+ //line sql.y:392
{
yyVAL.TableSpec.AddColumn(yyDollar[3].columnDefinition)
}
case 34:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:394
+ //line sql.y:396
{
yyVAL.TableSpec.AddIndex(yyDollar[3].indexDefinition)
}
case 35:
yyDollar = yyS[yypt-6 : yypt+1]
- //line sql.y:400
+ //line sql.y:402
{
yyDollar[2].columnType.NotNull = yyDollar[3].boolVal
yyDollar[2].columnType.Default = yyDollar[4].optVal
@@ -1745,7 +1762,7 @@ yydefault:
}
case 36:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:409
+ //line sql.y:411
{
yyVAL.columnType = yyDollar[1].columnType
yyVAL.columnType.Unsigned = yyDollar[2].boolVal
@@ -1753,56 +1770,56 @@ yydefault:
}
case 39:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:419
+ //line sql.y:421
{
yyVAL.columnType = yyDollar[1].columnType
yyVAL.columnType.Length = yyDollar[2].optVal
}
case 40:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:424
+ //line sql.y:426
{
yyVAL.columnType = yyDollar[1].columnType
}
case 41:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:430
+ //line sql.y:432
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
}
case 42:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:434
+ //line sql.y:436
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
}
case 43:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:438
+ //line sql.y:440
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
}
case 44:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:442
+ //line sql.y:444
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
}
case 45:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:446
+ //line sql.y:448
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
}
case 46:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:450
+ //line sql.y:452
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
}
case 47:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:456
+ //line sql.y:458
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length
@@ -1810,7 +1827,7 @@ yydefault:
}
case 48:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:462
+ //line sql.y:464
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length
@@ -1818,7 +1835,7 @@ yydefault:
}
case 49:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:468
+ //line sql.y:470
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length
@@ -1826,7 +1843,7 @@ yydefault:
}
case 50:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:474
+ //line sql.y:476
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length
@@ -1834,7 +1851,7 @@ yydefault:
}
case 51:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:480
+ //line sql.y:482
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length
@@ -1842,115 +1859,115 @@ yydefault:
}
case 52:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:488
+ //line sql.y:490
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
}
case 53:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:492
+ //line sql.y:494
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal}
}
case 54:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:496
+ //line sql.y:498
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal}
}
case 55:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:500
+ //line sql.y:502
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal}
}
case 56:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:504
+ //line sql.y:506
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
}
case 57:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:510
+ //line sql.y:512
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal}
}
case 58:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:514
+ //line sql.y:516
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal}
}
case 59:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:518
+ //line sql.y:520
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
}
case 60:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:522
+ //line sql.y:524
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
}
case 61:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:526
+ //line sql.y:528
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
}
case 62:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:530
+ //line sql.y:532
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
}
case 63:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:534
+ //line sql.y:536
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
}
case 64:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:538
+ //line sql.y:540
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
}
case 65:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:542
+ //line sql.y:544
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
}
case 66:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:546
+ //line sql.y:548
{
yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)}
}
case 67:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:551
+ //line sql.y:553
{
yyVAL.optVal = nil
}
case 68:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:555
+ //line sql.y:557
{
yyVAL.optVal = NewIntVal(yyDollar[2].bytes)
}
case 69:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:560
+ //line sql.y:562
{
yyVAL.LengthScaleOption = LengthScaleOption{}
}
case 70:
yyDollar = yyS[yypt-5 : yypt+1]
- //line sql.y:564
+ //line sql.y:566
{
yyVAL.LengthScaleOption = LengthScaleOption{
Length: NewIntVal(yyDollar[2].bytes),
@@ -1959,13 +1976,13 @@ yydefault:
}
case 71:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:572
+ //line sql.y:574
{
yyVAL.LengthScaleOption = LengthScaleOption{}
}
case 72:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:576
+ //line sql.y:578
{
yyVAL.LengthScaleOption = LengthScaleOption{
Length: NewIntVal(yyDollar[2].bytes),
@@ -1973,7 +1990,7 @@ yydefault:
}
case 73:
yyDollar = yyS[yypt-5 : yypt+1]
- //line sql.y:582
+ //line sql.y:584
{
yyVAL.LengthScaleOption = LengthScaleOption{
Length: NewIntVal(yyDollar[2].bytes),
@@ -1982,266 +1999,266 @@ yydefault:
}
case 74:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:590
+ //line sql.y:592
{
yyVAL.boolVal = BoolVal(false)
}
case 75:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:594
+ //line sql.y:596
{
yyVAL.boolVal = BoolVal(true)
}
case 76:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:599
+ //line sql.y:601
{
yyVAL.boolVal = BoolVal(false)
}
case 77:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:603
+ //line sql.y:605
{
yyVAL.boolVal = BoolVal(true)
}
case 78:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:609
+ //line sql.y:611
{
yyVAL.boolVal = BoolVal(false)
}
case 79:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:613
+ //line sql.y:615
{
yyVAL.boolVal = BoolVal(false)
}
case 80:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:617
+ //line sql.y:619
{
yyVAL.boolVal = BoolVal(true)
}
case 81:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:622
+ //line sql.y:624
{
yyVAL.optVal = nil
}
case 82:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:626
+ //line sql.y:628
{
yyVAL.optVal = NewStrVal(yyDollar[2].bytes)
}
case 83:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:630
+ //line sql.y:632
{
yyVAL.optVal = NewIntVal(yyDollar[2].bytes)
}
case 84:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:634
+ //line sql.y:636
{
yyVAL.optVal = NewFloatVal(yyDollar[2].bytes)
}
case 85:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:638
+ //line sql.y:640
{
yyVAL.optVal = NewValArg(yyDollar[2].bytes)
}
case 86:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:642
+ //line sql.y:644
{
yyVAL.optVal = NewValArg(yyDollar[2].bytes)
}
case 87:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:647
+ //line sql.y:649
{
yyVAL.boolVal = BoolVal(false)
}
case 88:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:651
+ //line sql.y:653
{
yyVAL.boolVal = BoolVal(true)
}
case 89:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:656
+ //line sql.y:658
{
yyVAL.colKeyOpt = colKeyNone
}
case 90:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:660
+ //line sql.y:662
{
yyVAL.colKeyOpt = colKeyPrimary
}
case 91:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:664
+ //line sql.y:666
{
yyVAL.colKeyOpt = colKey
}
case 92:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:668
+ //line sql.y:670
{
yyVAL.colKeyOpt = colKeyUniqueKey
}
case 93:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:672
+ //line sql.y:674
{
yyVAL.colKeyOpt = colKeyUnique
}
case 94:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:678
+ //line sql.y:680
{
yyVAL.indexDefinition = &IndexDefinition{Info: yyDollar[1].indexInfo, Columns: yyDollar[3].indexColumns}
}
case 95:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:684
+ //line sql.y:686
{
yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].bytes), Name: NewColIdent("PRIMARY"), Primary: true, Unique: true}
}
case 96:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:688
+ //line sql.y:690
{
yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].str), Name: NewColIdent(string(yyDollar[3].bytes)), Unique: true}
}
case 97:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:692
+ //line sql.y:694
{
yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes), Name: NewColIdent(string(yyDollar[2].bytes)), Unique: true}
}
case 98:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:696
+ //line sql.y:698
{
yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].str), Name: NewColIdent(string(yyDollar[2].bytes)), Unique: false}
}
case 99:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:702
+ //line sql.y:704
{
yyVAL.str = string(yyDollar[1].bytes)
}
case 100:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:706
+ //line sql.y:708
{
yyVAL.str = string(yyDollar[1].bytes)
}
case 101:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:712
+ //line sql.y:714
{
yyVAL.indexColumns = []*IndexColumn{yyDollar[1].indexColumn}
}
case 102:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:716
+ //line sql.y:718
{
yyVAL.indexColumns = append(yyVAL.indexColumns, yyDollar[3].indexColumn)
}
case 103:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:722
+ //line sql.y:724
{
yyVAL.indexColumn = &IndexColumn{Column: yyDollar[1].colIdent, Length: yyDollar[2].optVal}
}
case 104:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:727
+ //line sql.y:729
{
yyVAL.str = ""
}
case 105:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:731
+ //line sql.y:733
{
yyVAL.str = " " + string(yyDollar[1].str)
}
case 106:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:735
+ //line sql.y:737
{
yyVAL.str = string(yyDollar[1].str) + ", " + string(yyDollar[3].str)
}
case 107:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:743
+ //line sql.y:745
{
yyVAL.str = yyDollar[1].str
}
case 108:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:747
+ //line sql.y:749
{
yyVAL.str = yyDollar[1].str + " " + yyDollar[2].str
}
case 109:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:751
+ //line sql.y:753
{
yyVAL.str = yyDollar[1].str + "=" + yyDollar[3].str
}
case 110:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:757
+ //line sql.y:759
{
yyVAL.str = yyDollar[1].colIdent.String()
}
case 111:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:761
+ //line sql.y:763
{
yyVAL.str = "'" + string(yyDollar[1].bytes) + "'"
}
case 112:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:765
+ //line sql.y:767
{
yyVAL.str = string(yyDollar[1].bytes)
}
case 113:
yyDollar = yyS[yypt-6 : yypt+1]
- //line sql.y:771
+ //line sql.y:773
{
yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[3].tableName, NewName: yyDollar[3].tableName}
}
case 114:
yyDollar = yyS[yypt-6 : yypt+1]
- //line sql.y:775
+ //line sql.y:777
{
// Change this to a rename statement
yyVAL.statement = &DDL{Action: RenameStr, Table: yyDollar[3].tableName, NewName: yyDollar[6].tableName}
}
case 115:
yyDollar = yyS[yypt-8 : yypt+1]
- //line sql.y:780
+ //line sql.y:782
{
// Rename an index can just be an alter
yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[3].tableName, NewName: yyDollar[3].tableName}
}
case 116:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:786
+ //line sql.y:788
{
}
case 118:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:790
+ //line sql.y:792
{
var exists bool
if yyDollar[3].byt != 0 {
@@ -2251,7 +2268,7 @@ yydefault:
}
case 119:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:798
+ //line sql.y:800
{
var exists bool
if yyDollar[3].byt != 0 {
@@ -2261,734 +2278,752 @@ yydefault:
}
case 120:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:808
+ //line sql.y:810
{
yyVAL.statement = &Show{Type: string(yyDollar[3].bytes), ShowCreate: true, OnTable: yyDollar[4].tableName}
}
case 121:
yyDollar = yyS[yypt-5 : yypt+1]
- //line sql.y:812
+ //line sql.y:814
{
yyVAL.statement = &Show{Type: string(yyDollar[2].bytes), OnTable: yyDollar[5].tableName}
}
case 122:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:816
+ //line sql.y:818
{
yyVAL.statement = &Show{Type: string(yyDollar[2].bytes), OnTable: yyDollar[3].tableName}
}
case 123:
- yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:820
+ yyDollar = yyS[yypt-3 : yypt+1]
+ //line sql.y:822
{
- yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)}
+ yyVAL.statement = &Show{Type: string(yyDollar[3].bytes)}
}
case 124:
- yyDollar = yyS[yypt-2 : yypt+1]
+ yyDollar = yyS[yypt-5 : yypt+1]
//line sql.y:826
{
- yyVAL.statement = &Show{Type: "table", OnTable: yyDollar[2].tableName}
+ yyVAL.statement = &Show{Type: "table", OnTable: yyDollar[5].tableName}
}
case 125:
+ yyDollar = yyS[yypt-0 : yypt+1]
+ //line sql.y:831
+ {
+ yyVAL.bytes = nil
+ }
+ case 126:
+ yyDollar = yyS[yypt-1 : yypt+1]
+ //line sql.y:835
+ {
+ yyVAL.bytes = nil
+ }
+ case 127:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:830
+ //line sql.y:841
{
yyVAL.statement = &Show{Type: "table", OnTable: yyDollar[2].tableName}
}
- case 126:
+ case 128:
+ yyDollar = yyS[yypt-2 : yypt+1]
+ //line sql.y:845
+ {
+ yyVAL.statement = &Show{Type: "table", OnTable: yyDollar[2].tableName}
+ }
+ case 129:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:835
+ //line sql.y:850
{
setAllowComments(yylex, true)
}
- case 127:
+ case 130:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:839
+ //line sql.y:854
{
yyVAL.bytes2 = yyDollar[2].bytes2
setAllowComments(yylex, false)
}
- case 128:
+ case 131:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:845
+ //line sql.y:860
{
yyVAL.bytes2 = nil
}
- case 129:
+ case 132:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:849
+ //line sql.y:864
{
yyVAL.bytes2 = append(yyDollar[1].bytes2, yyDollar[2].bytes)
}
- case 130:
+ case 133:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:855
+ //line sql.y:870
{
yyVAL.str = UnionStr
}
- case 131:
+ case 134:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:859
+ //line sql.y:874
{
yyVAL.str = UnionAllStr
}
- case 132:
+ case 135:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:864
+ //line sql.y:879
{
yyVAL.str = ""
}
- case 133:
+ case 136:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:868
+ //line sql.y:883
{
yyVAL.str = DistinctStr
}
- case 134:
+ case 137:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:873
+ //line sql.y:888
{
yyVAL.selectExprs = nil
}
- case 135:
+ case 138:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:877
+ //line sql.y:892
{
yyVAL.selectExprs = yyDollar[1].selectExprs
}
- case 136:
+ case 139:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:883
+ //line sql.y:898
{
yyVAL.selectExprs = SelectExprs{yyDollar[1].selectExpr}
}
- case 137:
+ case 140:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:887
+ //line sql.y:902
{
yyVAL.selectExprs = append(yyVAL.selectExprs, yyDollar[3].selectExpr)
}
- case 138:
+ case 141:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:893
+ //line sql.y:908
{
yyVAL.selectExpr = &StarExpr{}
}
- case 139:
+ case 142:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:897
+ //line sql.y:912
{
yyVAL.selectExpr = &AliasedExpr{Expr: yyDollar[1].expr, As: yyDollar[2].colIdent}
}
- case 140:
+ case 143:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:901
+ //line sql.y:916
{
yyVAL.selectExpr = &StarExpr{TableName: TableName{Name: yyDollar[1].tableIdent}}
}
- case 141:
+ case 144:
yyDollar = yyS[yypt-5 : yypt+1]
- //line sql.y:905
+ //line sql.y:920
{
yyVAL.selectExpr = &StarExpr{TableName: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}}
}
- case 142:
+ case 145:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:910
+ //line sql.y:925
{
yyVAL.colIdent = ColIdent{}
}
- case 143:
+ case 146:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:914
+ //line sql.y:929
{
yyVAL.colIdent = yyDollar[1].colIdent
}
- case 144:
+ case 147:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:918
+ //line sql.y:933
{
yyVAL.colIdent = yyDollar[2].colIdent
}
- case 146:
+ case 149:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:925
+ //line sql.y:940
{
yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes))
}
- case 147:
+ case 150:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:931
+ //line sql.y:946
{
yyVAL.tableExprs = yyDollar[2].tableExprs
}
- case 148:
+ case 151:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:937
+ //line sql.y:952
{
yyVAL.tableExprs = TableExprs{yyDollar[1].tableExpr}
}
- case 149:
+ case 152:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:941
+ //line sql.y:956
{
yyVAL.tableExprs = append(yyVAL.tableExprs, yyDollar[3].tableExpr)
}
- case 152:
+ case 155:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:951
+ //line sql.y:966
{
yyVAL.tableExpr = yyDollar[1].aliasedTableName
}
- case 153:
+ case 156:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:955
+ //line sql.y:970
{
yyVAL.tableExpr = &AliasedTableExpr{Expr: yyDollar[1].subquery}
}
- case 154:
+ case 157:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:959
+ //line sql.y:974
{
yyVAL.tableExpr = &AliasedTableExpr{Expr: yyDollar[1].subquery, As: yyDollar[3].tableIdent}
}
- case 155:
+ case 158:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:963
+ //line sql.y:978
{
yyVAL.tableExpr = &ParenTableExpr{Exprs: yyDollar[2].tableExprs}
}
- case 156:
+ case 159:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:969
+ //line sql.y:984
{
yyVAL.aliasedTableName = &AliasedTableExpr{Expr: yyDollar[1].tableName, As: yyDollar[2].tableIdent}
}
- case 157:
+ case 160:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:975
+ //line sql.y:990
{
yyVAL.columns = Columns{yyDollar[1].colIdent}
}
- case 158:
+ case 161:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:979
+ //line sql.y:994
{
yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent)
}
- case 159:
+ case 162:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:985
+ //line sql.y:1000
{
yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition}
}
- case 160:
+ case 163:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:989
+ //line sql.y:1004
{
yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition}
}
- case 161:
+ case 164:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:993
+ //line sql.y:1008
{
yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr}
}
- case 162:
+ case 165:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:999
+ //line sql.y:1014
{
yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr}
}
- case 163:
+ case 166:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:1001
+ //line sql.y:1016
{
yyVAL.joinCondition = JoinCondition{Using: yyDollar[3].columns}
}
- case 164:
+ case 167:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1005
+ //line sql.y:1020
{
yyVAL.joinCondition = JoinCondition{}
}
- case 165:
+ case 168:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1007
+ //line sql.y:1022
{
yyVAL.joinCondition = yyDollar[1].joinCondition
}
- case 166:
+ case 169:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1010
+ //line sql.y:1025
{
yyVAL.empty = struct{}{}
}
- case 167:
+ case 170:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1012
+ //line sql.y:1027
{
yyVAL.empty = struct{}{}
}
- case 168:
+ case 171:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1015
+ //line sql.y:1030
{
yyVAL.tableIdent = NewTableIdent("")
}
- case 169:
+ case 172:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1019
+ //line sql.y:1034
{
yyVAL.tableIdent = yyDollar[1].tableIdent
}
- case 170:
+ case 173:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1023
+ //line sql.y:1038
{
yyVAL.tableIdent = yyDollar[2].tableIdent
}
- case 172:
+ case 175:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1030
+ //line sql.y:1045
{
yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes))
}
- case 173:
+ case 176:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1036
+ //line sql.y:1051
{
yyVAL.str = JoinStr
}
- case 174:
+ case 177:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1040
+ //line sql.y:1055
{
yyVAL.str = InnerJoinStr
}
- case 175:
+ case 178:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1044
+ //line sql.y:1059
{
yyVAL.str = CrossJoinStr
}
- case 176:
+ case 179:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1050
+ //line sql.y:1065
{
yyVAL.str = LeftJoinStr
}
- case 177:
+ case 180:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1054
+ //line sql.y:1069
{
yyVAL.str = LeftJoinStr
}
- case 178:
+ case 181:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1060
+ //line sql.y:1075
{
yyVAL.str = NaturalJoinStr
}
- case 179:
+ case 182:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1064
+ //line sql.y:1079
{
yyVAL.str = NaturalLeftJoinStr
}
- case 180:
+ case 183:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1070
+ //line sql.y:1085
{
yyVAL.tableName = yyDollar[2].tableName
}
- case 181:
+ case 184:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1074
+ //line sql.y:1089
{
yyVAL.tableName = yyDollar[1].tableName
}
- case 182:
+ case 185:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1080
+ //line sql.y:1095
{
yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent}
}
- case 183:
+ case 186:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1084
+ //line sql.y:1099
{
yyVAL.tableName = TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}
}
- case 184:
+ case 187:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1089
+ //line sql.y:1104
{
yyVAL.expr = nil
}
- case 185:
+ case 188:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1093
+ //line sql.y:1108
{
yyVAL.expr = yyDollar[2].expr
}
- case 186:
+ case 189:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1099
+ //line sql.y:1114
{
yyVAL.expr = yyDollar[1].expr
}
- case 187:
+ case 190:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1103
+ //line sql.y:1118
{
yyVAL.expr = &AndExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr}
}
- case 188:
+ case 191:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1107
+ //line sql.y:1122
{
yyVAL.expr = &OrExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr}
}
- case 189:
+ case 192:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1111
+ //line sql.y:1126
{
yyVAL.expr = &NotExpr{Expr: yyDollar[2].expr}
}
- case 190:
+ case 193:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1115
+ //line sql.y:1130
{
yyVAL.expr = &IsExpr{Operator: yyDollar[3].str, Expr: yyDollar[1].expr}
}
- case 191:
+ case 194:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1119
+ //line sql.y:1134
{
yyVAL.expr = yyDollar[1].expr
}
- case 192:
+ case 195:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1123
+ //line sql.y:1138
{
yyVAL.expr = &Default{ColName: yyDollar[2].str}
}
- case 193:
+ case 196:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1129
+ //line sql.y:1144
{
yyVAL.str = ""
}
- case 194:
+ case 197:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1133
+ //line sql.y:1148
{
yyVAL.str = string(yyDollar[2].bytes)
}
- case 195:
+ case 198:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1139
+ //line sql.y:1154
{
yyVAL.boolVal = BoolVal(true)
}
- case 196:
+ case 199:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1143
+ //line sql.y:1158
{
yyVAL.boolVal = BoolVal(false)
}
- case 197:
+ case 200:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1149
+ //line sql.y:1164
{
yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: yyDollar[2].str, Right: yyDollar[3].expr}
}
- case 198:
+ case 201:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1153
+ //line sql.y:1168
{
yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: InStr, Right: yyDollar[3].colTuple}
}
- case 199:
+ case 202:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:1157
+ //line sql.y:1172
{
yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotInStr, Right: yyDollar[4].colTuple}
}
- case 200:
+ case 203:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:1161
+ //line sql.y:1176
{
yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: LikeStr, Right: yyDollar[3].expr, Escape: yyDollar[4].expr}
}
- case 201:
+ case 204:
yyDollar = yyS[yypt-5 : yypt+1]
- //line sql.y:1165
+ //line sql.y:1180
{
yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotLikeStr, Right: yyDollar[4].expr, Escape: yyDollar[5].expr}
}
- case 202:
+ case 205:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1169
+ //line sql.y:1184
{
yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: RegexpStr, Right: yyDollar[3].expr}
}
- case 203:
+ case 206:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:1173
+ //line sql.y:1188
{
yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotRegexpStr, Right: yyDollar[4].expr}
}
- case 204:
+ case 207:
yyDollar = yyS[yypt-5 : yypt+1]
- //line sql.y:1177
+ //line sql.y:1192
{
yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: BetweenStr, From: yyDollar[3].expr, To: yyDollar[5].expr}
}
- case 205:
+ case 208:
yyDollar = yyS[yypt-6 : yypt+1]
- //line sql.y:1181
+ //line sql.y:1196
{
yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: NotBetweenStr, From: yyDollar[4].expr, To: yyDollar[6].expr}
}
- case 206:
+ case 209:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1185
+ //line sql.y:1200
{
yyVAL.expr = &ExistsExpr{Subquery: yyDollar[2].subquery}
}
- case 207:
+ case 210:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1191
+ //line sql.y:1206
{
yyVAL.str = IsNullStr
}
- case 208:
+ case 211:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1195
+ //line sql.y:1210
{
yyVAL.str = IsNotNullStr
}
- case 209:
+ case 212:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1199
+ //line sql.y:1214
{
yyVAL.str = IsTrueStr
}
- case 210:
+ case 213:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1203
+ //line sql.y:1218
{
yyVAL.str = IsNotTrueStr
}
- case 211:
+ case 214:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1207
+ //line sql.y:1222
{
yyVAL.str = IsFalseStr
}
- case 212:
+ case 215:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1211
+ //line sql.y:1226
{
yyVAL.str = IsNotFalseStr
}
- case 213:
+ case 216:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1217
+ //line sql.y:1232
{
yyVAL.str = EqualStr
}
- case 214:
+ case 217:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1221
+ //line sql.y:1236
{
yyVAL.str = LessThanStr
}
- case 215:
+ case 218:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1225
+ //line sql.y:1240
{
yyVAL.str = GreaterThanStr
}
- case 216:
+ case 219:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1229
+ //line sql.y:1244
{
yyVAL.str = LessEqualStr
}
- case 217:
+ case 220:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1233
+ //line sql.y:1248
{
yyVAL.str = GreaterEqualStr
}
- case 218:
+ case 221:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1237
+ //line sql.y:1252
{
yyVAL.str = NotEqualStr
}
- case 219:
+ case 222:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1241
+ //line sql.y:1256
{
yyVAL.str = NullSafeNotEqualStr
}
- case 220:
+ case 223:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1246
+ //line sql.y:1261
{
yyVAL.expr = nil
}
- case 221:
+ case 224:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1250
+ //line sql.y:1265
{
yyVAL.expr = yyDollar[2].expr
}
- case 222:
+ case 225:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1256
+ //line sql.y:1271
{
yyVAL.colTuple = yyDollar[1].valTuple
}
- case 223:
+ case 226:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1260
+ //line sql.y:1275
{
yyVAL.colTuple = yyDollar[1].subquery
}
- case 224:
+ case 227:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1264
+ //line sql.y:1279
{
yyVAL.colTuple = ListArg(yyDollar[1].bytes)
}
- case 225:
+ case 228:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1270
+ //line sql.y:1285
{
yyVAL.subquery = &Subquery{yyDollar[2].selStmt}
}
- case 226:
+ case 229:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1276
+ //line sql.y:1291
{
yyVAL.exprs = Exprs{yyDollar[1].expr}
}
- case 227:
+ case 230:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1280
+ //line sql.y:1295
{
yyVAL.exprs = append(yyDollar[1].exprs, yyDollar[3].expr)
}
- case 228:
+ case 231:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1286
+ //line sql.y:1301
{
yyVAL.expr = yyDollar[1].expr
}
- case 229:
+ case 232:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1290
+ //line sql.y:1305
{
yyVAL.expr = yyDollar[1].boolVal
}
- case 230:
+ case 233:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1294
+ //line sql.y:1309
{
yyVAL.expr = yyDollar[1].colName
}
- case 231:
+ case 234:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1298
+ //line sql.y:1313
{
yyVAL.expr = yyDollar[1].expr
}
- case 232:
+ case 235:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1302
+ //line sql.y:1317
{
yyVAL.expr = yyDollar[1].subquery
}
- case 233:
+ case 236:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1306
+ //line sql.y:1321
{
yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitAndStr, Right: yyDollar[3].expr}
}
- case 234:
+ case 237:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1310
+ //line sql.y:1325
{
yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitOrStr, Right: yyDollar[3].expr}
}
- case 235:
+ case 238:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1314
+ //line sql.y:1329
{
yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitXorStr, Right: yyDollar[3].expr}
}
- case 236:
+ case 239:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1318
+ //line sql.y:1333
{
yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: PlusStr, Right: yyDollar[3].expr}
}
- case 237:
+ case 240:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1322
+ //line sql.y:1337
{
yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MinusStr, Right: yyDollar[3].expr}
}
- case 238:
+ case 241:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1326
+ //line sql.y:1341
{
yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MultStr, Right: yyDollar[3].expr}
}
- case 239:
+ case 242:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1330
+ //line sql.y:1345
{
yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: DivStr, Right: yyDollar[3].expr}
}
- case 240:
+ case 243:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1334
+ //line sql.y:1349
{
yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: IntDivStr, Right: yyDollar[3].expr}
}
- case 241:
+ case 244:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1338
+ //line sql.y:1353
{
yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModStr, Right: yyDollar[3].expr}
}
- case 242:
+ case 245:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1342
+ //line sql.y:1357
{
yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModStr, Right: yyDollar[3].expr}
}
- case 243:
+ case 246:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1346
+ //line sql.y:1361
{
yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftLeftStr, Right: yyDollar[3].expr}
}
- case 244:
+ case 247:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1350
+ //line sql.y:1365
{
yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftRightStr, Right: yyDollar[3].expr}
}
- case 245:
+ case 248:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1354
+ //line sql.y:1369
{
if num, ok := yyDollar[2].expr.(*SQLVal); ok && num.Type == IntVal {
yyVAL.expr = num
@@ -2996,9 +3031,9 @@ yydefault:
yyVAL.expr = &UnaryExpr{Operator: UPlusStr, Expr: yyDollar[2].expr}
}
}
- case 246:
+ case 249:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1362
+ //line sql.y:1377
{
if num, ok := yyDollar[2].expr.(*SQLVal); ok && num.Type == IntVal {
// Handle double negative
@@ -3012,21 +3047,21 @@ yydefault:
yyVAL.expr = &UnaryExpr{Operator: UMinusStr, Expr: yyDollar[2].expr}
}
}
- case 247:
+ case 250:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1376
+ //line sql.y:1391
{
yyVAL.expr = &UnaryExpr{Operator: TildaStr, Expr: yyDollar[2].expr}
}
- case 248:
+ case 251:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1380
+ //line sql.y:1395
{
yyVAL.expr = &UnaryExpr{Operator: BangStr, Expr: yyDollar[2].expr}
}
- case 249:
+ case 252:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1384
+ //line sql.y:1399
{
// This rule prevents the usage of INTERVAL
// as a function. If support is needed for that,
@@ -3034,505 +3069,505 @@ yydefault:
// will be non-trivial because of grammar conflicts.
yyVAL.expr = &IntervalExpr{Expr: yyDollar[2].expr, Unit: yyDollar[3].colIdent.String()}
}
- case 254:
+ case 257:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:1402
+ //line sql.y:1417
{
yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Exprs: yyDollar[3].selectExprs}
}
- case 255:
+ case 258:
yyDollar = yyS[yypt-5 : yypt+1]
- //line sql.y:1406
+ //line sql.y:1421
{
yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Distinct: true, Exprs: yyDollar[4].selectExprs}
}
- case 256:
+ case 259:
yyDollar = yyS[yypt-6 : yypt+1]
- //line sql.y:1410
+ //line sql.y:1425
{
yyVAL.expr = &FuncExpr{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].colIdent, Exprs: yyDollar[5].selectExprs}
}
- case 257:
+ case 260:
yyDollar = yyS[yypt-6 : yypt+1]
- //line sql.y:1420
+ //line sql.y:1435
{
yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType}
}
- case 258:
+ case 261:
yyDollar = yyS[yypt-6 : yypt+1]
- //line sql.y:1424
+ //line sql.y:1439
{
yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: nil}
}
- case 259:
+ case 262:
yyDollar = yyS[yypt-8 : yypt+1]
- //line sql.y:1428
+ //line sql.y:1443
{
yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr}
}
- case 260:
+ case 263:
yyDollar = yyS[yypt-7 : yypt+1]
- //line sql.y:1432
+ //line sql.y:1447
{
yyVAL.expr = &GroupConcatExpr{Distinct: yyDollar[3].str, Exprs: yyDollar[4].selectExprs, OrderBy: yyDollar[5].orderBy, Separator: yyDollar[6].str}
}
- case 261:
+ case 264:
yyDollar = yyS[yypt-5 : yypt+1]
- //line sql.y:1436
+ //line sql.y:1451
{
yyVAL.expr = &CaseExpr{Expr: yyDollar[2].expr, Whens: yyDollar[3].whens, Else: yyDollar[4].expr}
}
- case 262:
+ case 265:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:1440
+ //line sql.y:1455
{
yyVAL.expr = &ValuesFuncExpr{Name: yyDollar[3].colName}
}
- case 263:
+ case 266:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1450
+ //line sql.y:1465
{
yyVAL.expr = &TimeExpr{Expr: NewColIdent("current_timestamp")}
}
- case 264:
+ case 267:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1455
+ //line sql.y:1470
{
yyVAL.expr = &TimeExpr{Expr: NewColIdent("current_date")}
}
- case 265:
+ case 268:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1460
+ //line sql.y:1475
{
yyVAL.expr = &TimeExpr{Expr: NewColIdent("current_time")}
}
- case 266:
+ case 269:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:1470
+ //line sql.y:1485
{
yyVAL.expr = &FuncExpr{Name: NewColIdent("if"), Exprs: yyDollar[3].selectExprs}
}
- case 267:
+ case 270:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:1474
+ //line sql.y:1489
{
yyVAL.expr = &FuncExpr{Name: NewColIdent("mod"), Exprs: yyDollar[3].selectExprs}
}
- case 268:
+ case 271:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:1478
+ //line sql.y:1493
{
yyVAL.expr = &FuncExpr{Name: NewColIdent("replace"), Exprs: yyDollar[3].selectExprs}
}
- case 269:
+ case 272:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1484
+ //line sql.y:1499
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal}
}
- case 270:
+ case 273:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1488
+ //line sql.y:1503
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)}
}
- case 271:
+ case 274:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1492
+ //line sql.y:1507
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal}
}
- case 272:
+ case 275:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1496
+ //line sql.y:1511
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)}
yyVAL.convertType.Length = yyDollar[2].LengthScaleOption.Length
yyVAL.convertType.Scale = yyDollar[2].LengthScaleOption.Scale
}
- case 273:
+ case 276:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1502
+ //line sql.y:1517
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal}
}
- case 274:
+ case 277:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1506
+ //line sql.y:1521
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)}
}
- case 275:
+ case 278:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1510
+ //line sql.y:1525
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)}
}
- case 276:
+ case 279:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1514
+ //line sql.y:1529
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal}
}
- case 277:
+ case 280:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1518
+ //line sql.y:1533
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)}
}
- case 278:
+ case 281:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1522
+ //line sql.y:1537
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)}
}
- case 279:
+ case 282:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1526
+ //line sql.y:1541
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal}
}
- case 280:
+ case 283:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1530
+ //line sql.y:1545
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal}
}
- case 281:
+ case 284:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1534
+ //line sql.y:1549
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal}
}
- case 282:
+ case 285:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1538
+ //line sql.y:1553
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal}
}
- case 283:
+ case 286:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1542
+ //line sql.y:1557
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal}
}
- case 284:
+ case 287:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1546
+ //line sql.y:1561
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal}
}
- case 285:
+ case 288:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1550
+ //line sql.y:1565
{
yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)}
}
- case 286:
+ case 289:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1555
+ //line sql.y:1570
{
yyVAL.expr = nil
}
- case 287:
+ case 290:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1559
+ //line sql.y:1574
{
yyVAL.expr = yyDollar[1].expr
}
- case 288:
+ case 291:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1564
+ //line sql.y:1579
{
yyVAL.str = string("")
}
- case 289:
+ case 292:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1568
+ //line sql.y:1583
{
yyVAL.str = " separator '" + string(yyDollar[2].bytes) + "'"
}
- case 290:
+ case 293:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1574
+ //line sql.y:1589
{
yyVAL.whens = []*When{yyDollar[1].when}
}
- case 291:
+ case 294:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1578
+ //line sql.y:1593
{
yyVAL.whens = append(yyDollar[1].whens, yyDollar[2].when)
}
- case 292:
+ case 295:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:1584
+ //line sql.y:1599
{
yyVAL.when = &When{Cond: yyDollar[2].expr, Val: yyDollar[4].expr}
}
- case 293:
+ case 296:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1589
+ //line sql.y:1604
{
yyVAL.expr = nil
}
- case 294:
+ case 297:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1593
+ //line sql.y:1608
{
yyVAL.expr = yyDollar[2].expr
}
- case 295:
+ case 298:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1599
+ //line sql.y:1614
{
yyVAL.colName = &ColName{Name: yyDollar[1].colIdent}
}
- case 296:
+ case 299:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1603
+ //line sql.y:1618
{
yyVAL.colName = &ColName{Qualifier: TableName{Name: yyDollar[1].tableIdent}, Name: yyDollar[3].colIdent}
}
- case 297:
+ case 300:
yyDollar = yyS[yypt-5 : yypt+1]
- //line sql.y:1607
+ //line sql.y:1622
{
yyVAL.colName = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}, Name: yyDollar[5].colIdent}
}
- case 298:
+ case 301:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1613
+ //line sql.y:1628
{
yyVAL.expr = NewStrVal(yyDollar[1].bytes)
}
- case 299:
+ case 302:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1617
+ //line sql.y:1632
{
yyVAL.expr = NewHexVal(yyDollar[1].bytes)
}
- case 300:
+ case 303:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1621
+ //line sql.y:1636
{
yyVAL.expr = NewIntVal(yyDollar[1].bytes)
}
- case 301:
+ case 304:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1625
+ //line sql.y:1640
{
yyVAL.expr = NewFloatVal(yyDollar[1].bytes)
}
- case 302:
+ case 305:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1629
+ //line sql.y:1644
{
yyVAL.expr = NewHexNum(yyDollar[1].bytes)
}
- case 303:
+ case 306:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1633
+ //line sql.y:1648
{
yyVAL.expr = NewValArg(yyDollar[1].bytes)
}
- case 304:
+ case 307:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1637
+ //line sql.y:1652
{
yyVAL.expr = &NullVal{}
}
- case 305:
+ case 308:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1642
+ //line sql.y:1657
{
yyVAL.exprs = nil
}
- case 306:
+ case 309:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1646
+ //line sql.y:1661
{
yyVAL.exprs = yyDollar[3].exprs
}
- case 307:
+ case 310:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1651
+ //line sql.y:1666
{
yyVAL.expr = nil
}
- case 308:
+ case 311:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1655
+ //line sql.y:1670
{
yyVAL.expr = yyDollar[2].expr
}
- case 309:
+ case 312:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1660
+ //line sql.y:1675
{
yyVAL.orderBy = nil
}
- case 310:
+ case 313:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1664
+ //line sql.y:1679
{
yyVAL.orderBy = yyDollar[3].orderBy
}
- case 311:
+ case 314:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1670
+ //line sql.y:1685
{
yyVAL.orderBy = OrderBy{yyDollar[1].order}
}
- case 312:
+ case 315:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1674
+ //line sql.y:1689
{
yyVAL.orderBy = append(yyDollar[1].orderBy, yyDollar[3].order)
}
- case 313:
+ case 316:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1680
+ //line sql.y:1695
{
yyVAL.order = &Order{Expr: yyDollar[1].expr, Direction: yyDollar[2].str}
}
- case 314:
+ case 317:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1685
+ //line sql.y:1700
{
yyVAL.str = AscScr
}
- case 315:
+ case 318:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1689
+ //line sql.y:1704
{
yyVAL.str = AscScr
}
- case 316:
+ case 319:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1693
+ //line sql.y:1708
{
yyVAL.str = DescScr
}
- case 317:
+ case 320:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1698
+ //line sql.y:1713
{
yyVAL.limit = nil
}
- case 318:
+ case 321:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1702
+ //line sql.y:1717
{
yyVAL.limit = &Limit{Rowcount: yyDollar[2].expr}
}
- case 319:
+ case 322:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:1706
+ //line sql.y:1721
{
yyVAL.limit = &Limit{Offset: yyDollar[2].expr, Rowcount: yyDollar[4].expr}
}
- case 320:
+ case 323:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:1710
+ //line sql.y:1725
{
yyVAL.limit = &Limit{Offset: yyDollar[4].expr, Rowcount: yyDollar[2].expr}
}
- case 321:
+ case 324:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1723
+ //line sql.y:1738
{
yyVAL.ins = &Insert{Rows: yyDollar[2].values}
}
- case 322:
+ case 325:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1727
+ //line sql.y:1742
{
yyVAL.ins = &Insert{Rows: yyDollar[1].selStmt}
}
- case 323:
+ case 326:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1731
+ //line sql.y:1746
{
// Drop the redundant parenthesis.
yyVAL.ins = &Insert{Rows: yyDollar[2].selStmt}
}
- case 324:
+ case 327:
yyDollar = yyS[yypt-5 : yypt+1]
- //line sql.y:1736
+ //line sql.y:1751
{
yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].values}
}
- case 325:
+ case 328:
yyDollar = yyS[yypt-4 : yypt+1]
- //line sql.y:1740
+ //line sql.y:1755
{
yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[4].selStmt}
}
- case 326:
+ case 329:
yyDollar = yyS[yypt-6 : yypt+1]
- //line sql.y:1744
+ //line sql.y:1759
{
// Drop the redundant parenthesis.
yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].selStmt}
}
- case 327:
+ case 330:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1751
+ //line sql.y:1766
{
yyVAL.columns = Columns{yyDollar[1].colIdent}
}
- case 328:
+ case 331:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1755
+ //line sql.y:1770
{
yyVAL.columns = Columns{yyDollar[3].colIdent}
}
- case 329:
+ case 332:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1759
+ //line sql.y:1774
{
yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent)
}
- case 330:
+ case 333:
yyDollar = yyS[yypt-5 : yypt+1]
- //line sql.y:1763
+ //line sql.y:1778
{
yyVAL.columns = append(yyVAL.columns, yyDollar[5].colIdent)
}
- case 331:
+ case 334:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1769
+ //line sql.y:1784
{
yyVAL.values = Values{yyDollar[1].valTuple}
}
- case 332:
+ case 335:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1773
+ //line sql.y:1788
{
yyVAL.values = append(yyDollar[1].values, yyDollar[3].valTuple)
}
- case 333:
+ case 336:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1779
+ //line sql.y:1794
{
yyVAL.valTuple = yyDollar[1].valTuple
}
- case 334:
+ case 337:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1783
+ //line sql.y:1798
{
yyVAL.valTuple = ValTuple{}
}
- case 335:
+ case 338:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1789
+ //line sql.y:1804
{
yyVAL.valTuple = ValTuple(yyDollar[2].exprs)
}
- case 336:
+ case 339:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1795
+ //line sql.y:1810
{
if len(yyDollar[1].valTuple) == 1 {
yyVAL.expr = &ParenExpr{yyDollar[1].valTuple[0]}
@@ -3540,144 +3575,144 @@ yydefault:
yyVAL.expr = yyDollar[1].valTuple
}
}
- case 337:
+ case 340:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1805
+ //line sql.y:1820
{
yyVAL.updateExprs = UpdateExprs{yyDollar[1].updateExpr}
}
- case 338:
+ case 341:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1809
+ //line sql.y:1824
{
yyVAL.updateExprs = append(yyDollar[1].updateExprs, yyDollar[3].updateExpr)
}
- case 339:
+ case 342:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1815
+ //line sql.y:1830
{
yyVAL.updateExpr = &UpdateExpr{Name: yyDollar[1].colName, Expr: yyDollar[3].expr}
}
- case 340:
+ case 343:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1820
+ //line sql.y:1835
{
yyVAL.byt = 0
}
- case 341:
+ case 344:
yyDollar = yyS[yypt-2 : yypt+1]
- //line sql.y:1822
+ //line sql.y:1837
{
yyVAL.byt = 1
}
- case 342:
+ case 345:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1825
+ //line sql.y:1840
{
yyVAL.empty = struct{}{}
}
- case 343:
+ case 346:
yyDollar = yyS[yypt-3 : yypt+1]
- //line sql.y:1827
+ //line sql.y:1842
{
yyVAL.empty = struct{}{}
}
- case 344:
+ case 347:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1830
+ //line sql.y:1845
{
yyVAL.str = ""
}
- case 345:
+ case 348:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1832
+ //line sql.y:1847
{
yyVAL.str = IgnoreStr
}
- case 346:
+ case 349:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:1835
+ //line sql.y:1850
{
yyVAL.empty = struct{}{}
}
- case 347:
+ case 350:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1837
+ //line sql.y:1852
{
yyVAL.empty = struct{}{}
}
- case 348:
+ case 351:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1839
+ //line sql.y:1854
{
yyVAL.empty = struct{}{}
}
- case 349:
+ case 352:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1843
+ //line sql.y:1858
{
yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes))
}
- case 350:
+ case 353:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1847
+ //line sql.y:1862
{
yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes))
}
- case 352:
+ case 355:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1854
+ //line sql.y:1869
{
yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes))
}
- case 353:
+ case 356:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1860
+ //line sql.y:1875
{
yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes))
}
- case 354:
+ case 357:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1864
+ //line sql.y:1879
{
yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes))
}
- case 356:
+ case 359:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:1871
+ //line sql.y:1886
{
yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes))
}
- case 464:
+ case 467:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:2004
+ //line sql.y:2019
{
if incNesting(yylex) {
yylex.Error("max nesting level reached")
return 1
}
}
- case 465:
+ case 468:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:2013
+ //line sql.y:2028
{
decNesting(yylex)
}
- case 466:
+ case 469:
yyDollar = yyS[yypt-0 : yypt+1]
- //line sql.y:2018
+ //line sql.y:2033
{
forceEOF(yylex)
}
- case 467:
+ case 470:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:2022
+ //line sql.y:2037
{
forceEOF(yylex)
}
- case 468:
+ case 471:
yyDollar = yyS[yypt-1 : yypt+1]
- //line sql.y:2026
+ //line sql.y:2041
{
forceEOF(yylex)
}
diff --git a/vendor/github.com/CovenantSQL/sqlparser/sql.y b/vendor/github.com/CovenantSQL/sqlparser/sql.y
index b0199ec56..6e70d8a16 100644
--- a/vendor/github.com/CovenantSQL/sqlparser/sql.y
+++ b/vendor/github.com/CovenantSQL/sqlparser/sql.y
@@ -112,6 +112,7 @@ func forceEOF(yylex interface{}) {
%token '(' ',' ')'
%token ID HEX STRING INTEGRAL FLOAT HEXNUM VALUE_ARG LIST_ARG COMMENT
%token NULL TRUE FALSE
+%token FULL COLUMNS
// Precedence dictated by mysql. But the vitess grammar is simplified.
// Some of these operators don't conflict in our situation. Nevertheless,
@@ -232,6 +233,7 @@ func forceEOF(yylex interface{}) {
%type index_column
%type index_column_list
%type alter_object_type
+%type full_opt
%start any_command
@@ -360,10 +362,10 @@ create_statement:
$1.TableSpec = $2
$$ = $1
}
-| CREATE constraint_opt INDEX ID ON table_name ddl_force_eof
+| CREATE constraint_opt INDEX not_exists_opt ID ON table_name ddl_force_eof
{
// Change this to an alter statement
- $$ = &DDL{Action: CreateIndexStr, Table: $6, NewName:$6}
+ $$ = &DDL{Action: CreateIndexStr, Table: $7, NewName:$7}
}
create_table_prefix:
@@ -816,9 +818,22 @@ SHOW CREATE TABLE table_name
{
$$ = &Show{Type: string($2), OnTable: $3}
}
-| SHOW TABLES
+| SHOW full_opt TABLES
{
- $$ = &Show{Type: string($2)}
+ $$ = &Show{Type: string($3)}
+ }
+| SHOW full_opt COLUMNS FROM table_name
+ {
+ $$ = &Show{Type: "table", OnTable: $5}
+ }
+
+full_opt:
+ {
+ $$ = nil
+ }
+| FULL
+ {
+ $$ = nil
}
other_statement:
diff --git a/vendor/github.com/CovenantSQL/sqlparser/token.go b/vendor/github.com/CovenantSQL/sqlparser/token.go
index 53ec0c9d3..8dfc057fa 100644
--- a/vendor/github.com/CovenantSQL/sqlparser/token.go
+++ b/vendor/github.com/CovenantSQL/sqlparser/token.go
@@ -107,6 +107,7 @@ var keywords = map[string]int{
"char": CHAR,
"check": UNUSED,
"column": COLUMN,
+ "columns": COLUMNS,
"condition": UNUSED,
"constraint": CONSTRAINT,
"continue": UNUSED,
@@ -154,6 +155,7 @@ var keywords = map[string]int{
"float8": UNUSED,
"foreign": FOREIGN,
"from": FROM,
+ "full": FULL,
"generated": UNUSED,
"get": UNUSED,
"grant": UNUSED,
diff --git a/vendor/github.com/cyberdelia/go-metrics-graphite/AUTHORS b/vendor/github.com/cyberdelia/go-metrics-graphite/AUTHORS
new file mode 100644
index 000000000..b430b78ea
--- /dev/null
+++ b/vendor/github.com/cyberdelia/go-metrics-graphite/AUTHORS
@@ -0,0 +1,8 @@
+These people have provided bug fixes, new features or improved the documentation.
+
+* Daniel Garcia
+* Peter Teichman
+* Phillip Kovalev
+* Richard Crowley
+* Timothée Peignier
+* Tomás Senart
diff --git a/vendor/github.com/cyberdelia/go-metrics-graphite/LICENSE b/vendor/github.com/cyberdelia/go-metrics-graphite/LICENSE
new file mode 100644
index 000000000..fdfc8abff
--- /dev/null
+++ b/vendor/github.com/cyberdelia/go-metrics-graphite/LICENSE
@@ -0,0 +1,22 @@
+Copyright 2015 Timothée Peignier. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/cyberdelia/go-metrics-graphite/README.md b/vendor/github.com/cyberdelia/go-metrics-graphite/README.md
new file mode 100644
index 000000000..96ee1482d
--- /dev/null
+++ b/vendor/github.com/cyberdelia/go-metrics-graphite/README.md
@@ -0,0 +1,19 @@
+This is a reporter for the [go-metrics](https://github.com/rcrowley/go-metrics)
+library which will post the metrics to Graphite. It was originally part of the
+`go-metrics` library itself, but has been split off to make maintenance of
+both the core library and the client easier.
+
+### Usage
+
+```go
+import "github.com/cyberdelia/go-metrics-graphite"
+
+
+go graphite.Graphite(metrics.DefaultRegistry,
+ 1*time.Second, "some.prefix", addr)
+```
+
+### Migrating from `rcrowley/go-metrics` implementation
+
+Simply modify the import from `"github.com/rcrowley/go-metrics/graphite"` to
+`"github.com/cyberdelia/go-metrics-graphite"` and it should Just Work.
diff --git a/vendor/github.com/cyberdelia/go-metrics-graphite/graphite.go b/vendor/github.com/cyberdelia/go-metrics-graphite/graphite.go
new file mode 100644
index 000000000..4489f0beb
--- /dev/null
+++ b/vendor/github.com/cyberdelia/go-metrics-graphite/graphite.go
@@ -0,0 +1,120 @@
+package graphite
+
+import (
+ "bufio"
+ "fmt"
+ "log"
+ "net"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/rcrowley/go-metrics"
+)
+
+// Config provides a container with configuration parameters for
+// the Graphite exporter
+type Config struct {
+ Addr *net.TCPAddr // Network address to connect to
+ Registry metrics.Registry // Registry to be exported
+ FlushInterval time.Duration // Flush interval
+ DurationUnit time.Duration // Time conversion unit for durations
+ Prefix string // Prefix to be prepended to metric names
+ Percentiles []float64 // Percentiles to export from timers and histograms
+}
+
+// Graphite is a blocking exporter function which reports metrics in r
+// to a graphite server located at addr, flushing them every d duration
+// and prepending metric names with prefix.
+func Graphite(r metrics.Registry, d time.Duration, prefix string, addr *net.TCPAddr) {
+ WithConfig(Config{
+ Addr: addr,
+ Registry: r,
+ FlushInterval: d,
+ DurationUnit: time.Nanosecond,
+ Prefix: prefix,
+ Percentiles: []float64{0.5, 0.75, 0.95, 0.99, 0.999},
+ })
+}
+
+// WithConfig is a blocking exporter function just like Graphite,
+// but it takes a GraphiteConfig instead.
+func WithConfig(c Config) {
+ for _ = range time.Tick(c.FlushInterval) {
+ if err := graphite(&c); nil != err {
+ log.Println(err)
+ }
+ }
+}
+
+// Once performs a single submission to Graphite, returning a
+// non-nil error on failed connections. This can be used in a loop
+// similar to GraphiteWithConfig for custom error handling.
+func Once(c Config) error {
+ return graphite(&c)
+}
+
+func graphite(c *Config) error {
+ now := time.Now().Unix()
+ du := float64(c.DurationUnit)
+ flushSeconds := float64(c.FlushInterval) / float64(time.Second)
+ conn, err := net.DialTCP("tcp", nil, c.Addr)
+ if nil != err {
+ return err
+ }
+ defer conn.Close()
+ w := bufio.NewWriter(conn)
+ c.Registry.Each(func(name string, i interface{}) {
+ switch metric := i.(type) {
+ case metrics.Counter:
+ count := metric.Count()
+ fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, count, now)
+ fmt.Fprintf(w, "%s.%s.count_ps %.2f %d\n", c.Prefix, name, float64(count)/flushSeconds, now)
+ case metrics.Gauge:
+ fmt.Fprintf(w, "%s.%s.value %d %d\n", c.Prefix, name, metric.Value(), now)
+ case metrics.GaugeFloat64:
+ fmt.Fprintf(w, "%s.%s.value %f %d\n", c.Prefix, name, metric.Value(), now)
+ case metrics.Histogram:
+ h := metric.Snapshot()
+ ps := h.Percentiles(c.Percentiles)
+ fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, h.Count(), now)
+ fmt.Fprintf(w, "%s.%s.min %d %d\n", c.Prefix, name, h.Min(), now)
+ fmt.Fprintf(w, "%s.%s.max %d %d\n", c.Prefix, name, h.Max(), now)
+ fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, h.Mean(), now)
+ fmt.Fprintf(w, "%s.%s.std-dev %.2f %d\n", c.Prefix, name, h.StdDev(), now)
+ for psIdx, psKey := range c.Percentiles {
+ key := strings.Replace(strconv.FormatFloat(psKey*100.0, 'f', -1, 64), ".", "", 1)
+ fmt.Fprintf(w, "%s.%s.%s-percentile %.2f %d\n", c.Prefix, name, key, ps[psIdx], now)
+ }
+ case metrics.Meter:
+ m := metric.Snapshot()
+ fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, m.Count(), now)
+ fmt.Fprintf(w, "%s.%s.one-minute %.2f %d\n", c.Prefix, name, m.Rate1(), now)
+ fmt.Fprintf(w, "%s.%s.five-minute %.2f %d\n", c.Prefix, name, m.Rate5(), now)
+ fmt.Fprintf(w, "%s.%s.fifteen-minute %.2f %d\n", c.Prefix, name, m.Rate15(), now)
+ fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, m.RateMean(), now)
+ case metrics.Timer:
+ t := metric.Snapshot()
+ ps := t.Percentiles(c.Percentiles)
+ count := t.Count()
+ fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, count, now)
+ fmt.Fprintf(w, "%s.%s.count_ps %.2f %d\n", c.Prefix, name, float64(count)/flushSeconds, now)
+ fmt.Fprintf(w, "%s.%s.min %d %d\n", c.Prefix, name, t.Min()/int64(du), now)
+ fmt.Fprintf(w, "%s.%s.max %d %d\n", c.Prefix, name, t.Max()/int64(du), now)
+ fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, t.Mean()/du, now)
+ fmt.Fprintf(w, "%s.%s.std-dev %.2f %d\n", c.Prefix, name, t.StdDev()/du, now)
+ for psIdx, psKey := range c.Percentiles {
+ key := strings.Replace(strconv.FormatFloat(psKey*100.0, 'f', -1, 64), ".", "", 1)
+ fmt.Fprintf(w, "%s.%s.%s-percentile %.2f %d\n", c.Prefix, name, key, ps[psIdx]/du, now)
+ }
+ fmt.Fprintf(w, "%s.%s.one-minute %.2f %d\n", c.Prefix, name, t.Rate1(), now)
+ fmt.Fprintf(w, "%s.%s.five-minute %.2f %d\n", c.Prefix, name, t.Rate5(), now)
+ fmt.Fprintf(w, "%s.%s.fifteen-minute %.2f %d\n", c.Prefix, name, t.Rate15(), now)
+ fmt.Fprintf(w, "%s.%s.mean-rate %.2f %d\n", c.Prefix, name, t.RateMean(), now)
+ default:
+ log.Printf("unable to record metric of type %T\n", i)
+ }
+ w.Flush()
+ })
+ return nil
+}
diff --git a/vendor/github.com/hashicorp/yamux/.gitignore b/vendor/github.com/hashicorp/yamux/.gitignore
deleted file mode 100644
index 836562412..000000000
--- a/vendor/github.com/hashicorp/yamux/.gitignore
+++ /dev/null
@@ -1,23 +0,0 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-*.test
diff --git a/vendor/github.com/hashicorp/yamux/LICENSE b/vendor/github.com/hashicorp/yamux/LICENSE
deleted file mode 100644
index f0e5c79e1..000000000
--- a/vendor/github.com/hashicorp/yamux/LICENSE
+++ /dev/null
@@ -1,362 +0,0 @@
-Mozilla Public License, version 2.0
-
-1. Definitions
-
-1.1. "Contributor"
-
- means each individual or legal entity that creates, contributes to the
- creation of, or owns Covered Software.
-
-1.2. "Contributor Version"
-
- means the combination of the Contributions of others (if any) used by a
- Contributor and that particular Contributor's Contribution.
-
-1.3. "Contribution"
-
- means Covered Software of a particular Contributor.
-
-1.4. "Covered Software"
-
- means Source Code Form to which the initial Contributor has attached the
- notice in Exhibit A, the Executable Form of such Source Code Form, and
- Modifications of such Source Code Form, in each case including portions
- thereof.
-
-1.5. "Incompatible With Secondary Licenses"
- means
-
- a. that the initial Contributor has attached the notice described in
- Exhibit B to the Covered Software; or
-
- b. that the Covered Software was made available under the terms of
- version 1.1 or earlier of the License, but not also under the terms of
- a Secondary License.
-
-1.6. "Executable Form"
-
- means any form of the work other than Source Code Form.
-
-1.7. "Larger Work"
-
- means a work that combines Covered Software with other material, in a
- separate file or files, that is not Covered Software.
-
-1.8. "License"
-
- means this document.
-
-1.9. "Licensable"
-
- means having the right to grant, to the maximum extent possible, whether
- at the time of the initial grant or subsequently, any and all of the
- rights conveyed by this License.
-
-1.10. "Modifications"
-
- means any of the following:
-
- a. any file in Source Code Form that results from an addition to,
- deletion from, or modification of the contents of Covered Software; or
-
- b. any new file in Source Code Form that contains any Covered Software.
-
-1.11. "Patent Claims" of a Contributor
-
- means any patent claim(s), including without limitation, method,
- process, and apparatus claims, in any patent Licensable by such
- Contributor that would be infringed, but for the grant of the License,
- by the making, using, selling, offering for sale, having made, import,
- or transfer of either its Contributions or its Contributor Version.
-
-1.12. "Secondary License"
-
- means either the GNU General Public License, Version 2.0, the GNU Lesser
- General Public License, Version 2.1, the GNU Affero General Public
- License, Version 3.0, or any later versions of those licenses.
-
-1.13. "Source Code Form"
-
- means the form of the work preferred for making modifications.
-
-1.14. "You" (or "Your")
-
- means an individual or a legal entity exercising rights under this
- License. For legal entities, "You" includes any entity that controls, is
- controlled by, or is under common control with You. For purposes of this
- definition, "control" means (a) the power, direct or indirect, to cause
- the direction or management of such entity, whether by contract or
- otherwise, or (b) ownership of more than fifty percent (50%) of the
- outstanding shares or beneficial ownership of such entity.
-
-
-2. License Grants and Conditions
-
-2.1. Grants
-
- Each Contributor hereby grants You a world-wide, royalty-free,
- non-exclusive license:
-
- a. under intellectual property rights (other than patent or trademark)
- Licensable by such Contributor to use, reproduce, make available,
- modify, display, perform, distribute, and otherwise exploit its
- Contributions, either on an unmodified basis, with Modifications, or
- as part of a Larger Work; and
-
- b. under Patent Claims of such Contributor to make, use, sell, offer for
- sale, have made, import, and otherwise transfer either its
- Contributions or its Contributor Version.
-
-2.2. Effective Date
-
- The licenses granted in Section 2.1 with respect to any Contribution
- become effective for each Contribution on the date the Contributor first
- distributes such Contribution.
-
-2.3. Limitations on Grant Scope
-
- The licenses granted in this Section 2 are the only rights granted under
- this License. No additional rights or licenses will be implied from the
- distribution or licensing of Covered Software under this License.
- Notwithstanding Section 2.1(b) above, no patent license is granted by a
- Contributor:
-
- a. for any code that a Contributor has removed from Covered Software; or
-
- b. for infringements caused by: (i) Your and any other third party's
- modifications of Covered Software, or (ii) the combination of its
- Contributions with other software (except as part of its Contributor
- Version); or
-
- c. under Patent Claims infringed by Covered Software in the absence of
- its Contributions.
-
- This License does not grant any rights in the trademarks, service marks,
- or logos of any Contributor (except as may be necessary to comply with
- the notice requirements in Section 3.4).
-
-2.4. Subsequent Licenses
-
- No Contributor makes additional grants as a result of Your choice to
- distribute the Covered Software under a subsequent version of this
- License (see Section 10.2) or under the terms of a Secondary License (if
- permitted under the terms of Section 3.3).
-
-2.5. Representation
-
- Each Contributor represents that the Contributor believes its
- Contributions are its original creation(s) or it has sufficient rights to
- grant the rights to its Contributions conveyed by this License.
-
-2.6. Fair Use
-
- This License is not intended to limit any rights You have under
- applicable copyright doctrines of fair use, fair dealing, or other
- equivalents.
-
-2.7. Conditions
-
- Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
- Section 2.1.
-
-
-3. Responsibilities
-
-3.1. Distribution of Source Form
-
- All distribution of Covered Software in Source Code Form, including any
- Modifications that You create or to which You contribute, must be under
- the terms of this License. You must inform recipients that the Source
- Code Form of the Covered Software is governed by the terms of this
- License, and how they can obtain a copy of this License. You may not
- attempt to alter or restrict the recipients' rights in the Source Code
- Form.
-
-3.2. Distribution of Executable Form
-
- If You distribute Covered Software in Executable Form then:
-
- a. such Covered Software must also be made available in Source Code Form,
- as described in Section 3.1, and You must inform recipients of the
- Executable Form how they can obtain a copy of such Source Code Form by
- reasonable means in a timely manner, at a charge no more than the cost
- of distribution to the recipient; and
-
- b. You may distribute such Executable Form under the terms of this
- License, or sublicense it under different terms, provided that the
- license for the Executable Form does not attempt to limit or alter the
- recipients' rights in the Source Code Form under this License.
-
-3.3. Distribution of a Larger Work
-
- You may create and distribute a Larger Work under terms of Your choice,
- provided that You also comply with the requirements of this License for
- the Covered Software. If the Larger Work is a combination of Covered
- Software with a work governed by one or more Secondary Licenses, and the
- Covered Software is not Incompatible With Secondary Licenses, this
- License permits You to additionally distribute such Covered Software
- under the terms of such Secondary License(s), so that the recipient of
- the Larger Work may, at their option, further distribute the Covered
- Software under the terms of either this License or such Secondary
- License(s).
-
-3.4. Notices
-
- You may not remove or alter the substance of any license notices
- (including copyright notices, patent notices, disclaimers of warranty, or
- limitations of liability) contained within the Source Code Form of the
- Covered Software, except that You may alter any license notices to the
- extent required to remedy known factual inaccuracies.
-
-3.5. Application of Additional Terms
-
- You may choose to offer, and to charge a fee for, warranty, support,
- indemnity or liability obligations to one or more recipients of Covered
- Software. However, You may do so only on Your own behalf, and not on
- behalf of any Contributor. You must make it absolutely clear that any
- such warranty, support, indemnity, or liability obligation is offered by
- You alone, and You hereby agree to indemnify every Contributor for any
- liability incurred by such Contributor as a result of warranty, support,
- indemnity or liability terms You offer. You may include additional
- disclaimers of warranty and limitations of liability specific to any
- jurisdiction.
-
-4. Inability to Comply Due to Statute or Regulation
-
- If it is impossible for You to comply with any of the terms of this License
- with respect to some or all of the Covered Software due to statute,
- judicial order, or regulation then You must: (a) comply with the terms of
- this License to the maximum extent possible; and (b) describe the
- limitations and the code they affect. Such description must be placed in a
- text file included with all distributions of the Covered Software under
- this License. Except to the extent prohibited by statute or regulation,
- such description must be sufficiently detailed for a recipient of ordinary
- skill to be able to understand it.
-
-5. Termination
-
-5.1. The rights granted under this License will terminate automatically if You
- fail to comply with any of its terms. However, if You become compliant,
- then the rights granted under this License from a particular Contributor
- are reinstated (a) provisionally, unless and until such Contributor
- explicitly and finally terminates Your grants, and (b) on an ongoing
- basis, if such Contributor fails to notify You of the non-compliance by
- some reasonable means prior to 60 days after You have come back into
- compliance. Moreover, Your grants from a particular Contributor are
- reinstated on an ongoing basis if such Contributor notifies You of the
- non-compliance by some reasonable means, this is the first time You have
- received notice of non-compliance with this License from such
- Contributor, and You become compliant prior to 30 days after Your receipt
- of the notice.
-
-5.2. If You initiate litigation against any entity by asserting a patent
- infringement claim (excluding declaratory judgment actions,
- counter-claims, and cross-claims) alleging that a Contributor Version
- directly or indirectly infringes any patent, then the rights granted to
- You by any and all Contributors for the Covered Software under Section
- 2.1 of this License shall terminate.
-
-5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
- license agreements (excluding distributors and resellers) which have been
- validly granted by You or Your distributors under this License prior to
- termination shall survive termination.
-
-6. Disclaimer of Warranty
-
- Covered Software is provided under this License on an "as is" basis,
- without warranty of any kind, either expressed, implied, or statutory,
- including, without limitation, warranties that the Covered Software is free
- of defects, merchantable, fit for a particular purpose or non-infringing.
- The entire risk as to the quality and performance of the Covered Software
- is with You. Should any Covered Software prove defective in any respect,
- You (not any Contributor) assume the cost of any necessary servicing,
- repair, or correction. This disclaimer of warranty constitutes an essential
- part of this License. No use of any Covered Software is authorized under
- this License except under this disclaimer.
-
-7. Limitation of Liability
-
- Under no circumstances and under no legal theory, whether tort (including
- negligence), contract, or otherwise, shall any Contributor, or anyone who
- distributes Covered Software as permitted above, be liable to You for any
- direct, indirect, special, incidental, or consequential damages of any
- character including, without limitation, damages for lost profits, loss of
- goodwill, work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses, even if such party shall have been
- informed of the possibility of such damages. This limitation of liability
- shall not apply to liability for death or personal injury resulting from
- such party's negligence to the extent applicable law prohibits such
- limitation. Some jurisdictions do not allow the exclusion or limitation of
- incidental or consequential damages, so this exclusion and limitation may
- not apply to You.
-
-8. Litigation
-
- Any litigation relating to this License may be brought only in the courts
- of a jurisdiction where the defendant maintains its principal place of
- business and such litigation shall be governed by laws of that
- jurisdiction, without reference to its conflict-of-law provisions. Nothing
- in this Section shall prevent a party's ability to bring cross-claims or
- counter-claims.
-
-9. Miscellaneous
-
- This License represents the complete agreement concerning the subject
- matter hereof. If any provision of this License is held to be
- unenforceable, such provision shall be reformed only to the extent
- necessary to make it enforceable. Any law or regulation which provides that
- the language of a contract shall be construed against the drafter shall not
- be used to construe this License against a Contributor.
-
-
-10. Versions of the License
-
-10.1. New Versions
-
- Mozilla Foundation is the license steward. Except as provided in Section
- 10.3, no one other than the license steward has the right to modify or
- publish new versions of this License. Each version will be given a
- distinguishing version number.
-
-10.2. Effect of New Versions
-
- You may distribute the Covered Software under the terms of the version
- of the License under which You originally received the Covered Software,
- or under the terms of any subsequent version published by the license
- steward.
-
-10.3. Modified Versions
-
- If you create software not governed by this License, and you want to
- create a new license for such software, you may create and use a
- modified version of this License if you rename the license and remove
- any references to the name of the license steward (except to note that
- such modified license differs from this License).
-
-10.4. Distributing Source Code Form that is Incompatible With Secondary
- Licenses If You choose to distribute Source Code Form that is
- Incompatible With Secondary Licenses under the terms of this version of
- the License, the notice described in Exhibit B of this License must be
- attached.
-
-Exhibit A - Source Code Form License Notice
-
- This Source Code Form is subject to the
- terms of the Mozilla Public License, v.
- 2.0. If a copy of the MPL was not
- distributed with this file, You can
- obtain one at
- http://mozilla.org/MPL/2.0/.
-
-If it is not possible or desirable to put the notice in a particular file,
-then You may include the notice in a location (such as a LICENSE file in a
-relevant directory) where a recipient would be likely to look for such a
-notice.
-
-You may add additional accurate notices of copyright ownership.
-
-Exhibit B - "Incompatible With Secondary Licenses" Notice
-
- This Source Code Form is "Incompatible
- With Secondary Licenses", as defined by
- the Mozilla Public License, v. 2.0.
\ No newline at end of file
diff --git a/vendor/github.com/hashicorp/yamux/README.md b/vendor/github.com/hashicorp/yamux/README.md
deleted file mode 100644
index d4db7fc99..000000000
--- a/vendor/github.com/hashicorp/yamux/README.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Yamux
-
-Yamux (Yet another Multiplexer) is a multiplexing library for Golang.
-It relies on an underlying connection to provide reliability
-and ordering, such as TCP or Unix domain sockets, and provides
-stream-oriented multiplexing. It is inspired by SPDY but is not
-interoperable with it.
-
-Yamux features include:
-
-* Bi-directional streams
- * Streams can be opened by either client or server
- * Useful for NAT traversal
- * Server-side push support
-* Flow control
- * Avoid starvation
- * Back-pressure to prevent overwhelming a receiver
-* Keep Alives
- * Enables persistent connections over a load balancer
-* Efficient
- * Enables thousands of logical streams with low overhead
-
-## Documentation
-
-For complete documentation, see the associated [Godoc](http://godoc.org/github.com/hashicorp/yamux).
-
-## Specification
-
-The full specification for Yamux is provided in the `spec.md` file.
-It can be used as a guide to implementors of interoperable libraries.
-
-## Usage
-
-Using Yamux is remarkably simple:
-
-```go
-
-func client() {
- // Get a TCP connection
- conn, err := net.Dial(...)
- if err != nil {
- panic(err)
- }
-
- // Setup client side of yamux
- session, err := yamux.Client(conn, nil)
- if err != nil {
- panic(err)
- }
-
- // Open a new stream
- stream, err := session.Open()
- if err != nil {
- panic(err)
- }
-
- // Stream implements net.Conn
- stream.Write([]byte("ping"))
-}
-
-func server() {
- // Accept a TCP connection
- conn, err := listener.Accept()
- if err != nil {
- panic(err)
- }
-
- // Setup server side of yamux
- session, err := yamux.Server(conn, nil)
- if err != nil {
- panic(err)
- }
-
- // Accept a stream
- stream, err := session.Accept()
- if err != nil {
- panic(err)
- }
-
- // Listen for a message
- buf := make([]byte, 4)
- stream.Read(buf)
-}
-
-```
-
diff --git a/vendor/github.com/hashicorp/yamux/addr.go b/vendor/github.com/hashicorp/yamux/addr.go
deleted file mode 100644
index be6ebca9c..000000000
--- a/vendor/github.com/hashicorp/yamux/addr.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package yamux
-
-import (
- "fmt"
- "net"
-)
-
-// hasAddr is used to get the address from the underlying connection
-type hasAddr interface {
- LocalAddr() net.Addr
- RemoteAddr() net.Addr
-}
-
-// yamuxAddr is used when we cannot get the underlying address
-type yamuxAddr struct {
- Addr string
-}
-
-func (*yamuxAddr) Network() string {
- return "yamux"
-}
-
-func (y *yamuxAddr) String() string {
- return fmt.Sprintf("yamux:%s", y.Addr)
-}
-
-// Addr is used to get the address of the listener.
-func (s *Session) Addr() net.Addr {
- return s.LocalAddr()
-}
-
-// LocalAddr is used to get the local address of the
-// underlying connection.
-func (s *Session) LocalAddr() net.Addr {
- addr, ok := s.conn.(hasAddr)
- if !ok {
- return &yamuxAddr{"local"}
- }
- return addr.LocalAddr()
-}
-
-// RemoteAddr is used to get the address of remote end
-// of the underlying connection
-func (s *Session) RemoteAddr() net.Addr {
- addr, ok := s.conn.(hasAddr)
- if !ok {
- return &yamuxAddr{"remote"}
- }
- return addr.RemoteAddr()
-}
-
-// LocalAddr returns the local address
-func (s *Stream) LocalAddr() net.Addr {
- return s.session.LocalAddr()
-}
-
-// LocalAddr returns the remote address
-func (s *Stream) RemoteAddr() net.Addr {
- return s.session.RemoteAddr()
-}
diff --git a/vendor/github.com/hashicorp/yamux/const.go b/vendor/github.com/hashicorp/yamux/const.go
deleted file mode 100644
index 4f5293828..000000000
--- a/vendor/github.com/hashicorp/yamux/const.go
+++ /dev/null
@@ -1,157 +0,0 @@
-package yamux
-
-import (
- "encoding/binary"
- "fmt"
-)
-
-var (
- // ErrInvalidVersion means we received a frame with an
- // invalid version
- ErrInvalidVersion = fmt.Errorf("invalid protocol version")
-
- // ErrInvalidMsgType means we received a frame with an
- // invalid message type
- ErrInvalidMsgType = fmt.Errorf("invalid msg type")
-
- // ErrSessionShutdown is used if there is a shutdown during
- // an operation
- ErrSessionShutdown = fmt.Errorf("session shutdown")
-
- // ErrStreamsExhausted is returned if we have no more
- // stream ids to issue
- ErrStreamsExhausted = fmt.Errorf("streams exhausted")
-
- // ErrDuplicateStream is used if a duplicate stream is
- // opened inbound
- ErrDuplicateStream = fmt.Errorf("duplicate stream initiated")
-
- // ErrReceiveWindowExceeded indicates the window was exceeded
- ErrRecvWindowExceeded = fmt.Errorf("recv window exceeded")
-
- // ErrTimeout is used when we reach an IO deadline
- ErrTimeout = fmt.Errorf("i/o deadline reached")
-
- // ErrStreamClosed is returned when using a closed stream
- ErrStreamClosed = fmt.Errorf("stream closed")
-
- // ErrUnexpectedFlag is set when we get an unexpected flag
- ErrUnexpectedFlag = fmt.Errorf("unexpected flag")
-
- // ErrRemoteGoAway is used when we get a go away from the other side
- ErrRemoteGoAway = fmt.Errorf("remote end is not accepting connections")
-
- // ErrConnectionReset is sent if a stream is reset. This can happen
- // if the backlog is exceeded, or if there was a remote GoAway.
- ErrConnectionReset = fmt.Errorf("connection reset")
-
- // ErrConnectionWriteTimeout indicates that we hit the "safety valve"
- // timeout writing to the underlying stream connection.
- ErrConnectionWriteTimeout = fmt.Errorf("connection write timeout")
-
- // ErrKeepAliveTimeout is sent if a missed keepalive caused the stream close
- ErrKeepAliveTimeout = fmt.Errorf("keepalive timeout")
-)
-
-const (
- // protoVersion is the only version we support
- protoVersion uint8 = 0
-)
-
-const (
- // Data is used for data frames. They are followed
- // by length bytes worth of payload.
- typeData uint8 = iota
-
- // WindowUpdate is used to change the window of
- // a given stream. The length indicates the delta
- // update to the window.
- typeWindowUpdate
-
- // Ping is sent as a keep-alive or to measure
- // the RTT. The StreamID and Length value are echoed
- // back in the response.
- typePing
-
- // GoAway is sent to terminate a session. The StreamID
- // should be 0 and the length is an error code.
- typeGoAway
-)
-
-const (
- // SYN is sent to signal a new stream. May
- // be sent with a data payload
- flagSYN uint16 = 1 << iota
-
- // ACK is sent to acknowledge a new stream. May
- // be sent with a data payload
- flagACK
-
- // FIN is sent to half-close the given stream.
- // May be sent with a data payload.
- flagFIN
-
- // RST is used to hard close a given stream.
- flagRST
-)
-
-const (
- // initialStreamWindow is the initial stream window size
- initialStreamWindow uint32 = 256 * 1024
-)
-
-const (
- // goAwayNormal is sent on a normal termination
- goAwayNormal uint32 = iota
-
- // goAwayProtoErr sent on a protocol error
- goAwayProtoErr
-
- // goAwayInternalErr sent on an internal error
- goAwayInternalErr
-)
-
-const (
- sizeOfVersion = 1
- sizeOfType = 1
- sizeOfFlags = 2
- sizeOfStreamID = 4
- sizeOfLength = 4
- headerSize = sizeOfVersion + sizeOfType + sizeOfFlags +
- sizeOfStreamID + sizeOfLength
-)
-
-type header []byte
-
-func (h header) Version() uint8 {
- return h[0]
-}
-
-func (h header) MsgType() uint8 {
- return h[1]
-}
-
-func (h header) Flags() uint16 {
- return binary.BigEndian.Uint16(h[2:4])
-}
-
-func (h header) StreamID() uint32 {
- return binary.BigEndian.Uint32(h[4:8])
-}
-
-func (h header) Length() uint32 {
- return binary.BigEndian.Uint32(h[8:12])
-}
-
-func (h header) String() string {
- return fmt.Sprintf("Vsn:%d Type:%d Flags:%d StreamID:%d Length:%d",
- h.Version(), h.MsgType(), h.Flags(), h.StreamID(), h.Length())
-}
-
-func (h header) encode(msgType uint8, flags uint16, streamID uint32, length uint32) {
- h[0] = protoVersion
- h[1] = msgType
- binary.BigEndian.PutUint16(h[2:4], flags)
- binary.BigEndian.PutUint32(h[4:8], streamID)
- binary.BigEndian.PutUint32(h[8:12], length)
-}
diff --git a/vendor/github.com/hashicorp/yamux/go.mod b/vendor/github.com/hashicorp/yamux/go.mod
deleted file mode 100644
index 672a0e581..000000000
--- a/vendor/github.com/hashicorp/yamux/go.mod
+++ /dev/null
@@ -1 +0,0 @@
-module github.com/hashicorp/yamux
diff --git a/vendor/github.com/hashicorp/yamux/mux.go b/vendor/github.com/hashicorp/yamux/mux.go
deleted file mode 100644
index 18a078c8a..000000000
--- a/vendor/github.com/hashicorp/yamux/mux.go
+++ /dev/null
@@ -1,98 +0,0 @@
-package yamux
-
-import (
- "fmt"
- "io"
- "log"
- "os"
- "time"
-)
-
-// Config is used to tune the Yamux session
-type Config struct {
- // AcceptBacklog is used to limit how many streams may be
- // waiting an accept.
- AcceptBacklog int
-
- // EnableKeepalive is used to do a period keep alive
- // messages using a ping.
- EnableKeepAlive bool
-
- // KeepAliveInterval is how often to perform the keep alive
- KeepAliveInterval time.Duration
-
- // ConnectionWriteTimeout is meant to be a "safety valve" timeout after
- // we which will suspect a problem with the underlying connection and
- // close it. This is only applied to writes, where's there's generally
- // an expectation that things will move along quickly.
- ConnectionWriteTimeout time.Duration
-
- // MaxStreamWindowSize is used to control the maximum
- // window size that we allow for a stream.
- MaxStreamWindowSize uint32
-
- // LogOutput is used to control the log destination. Either Logger or
- // LogOutput can be set, not both.
- LogOutput io.Writer
-
- // Logger is used to pass in the logger to be used. Either Logger or
- // LogOutput can be set, not both.
- Logger *log.Logger
-}
-
-// DefaultConfig is used to return a default configuration
-func DefaultConfig() *Config {
- return &Config{
- AcceptBacklog: 256,
- EnableKeepAlive: true,
- KeepAliveInterval: 30 * time.Second,
- ConnectionWriteTimeout: 10 * time.Second,
- MaxStreamWindowSize: initialStreamWindow,
- LogOutput: os.Stderr,
- }
-}
-
-// VerifyConfig is used to verify the sanity of configuration
-func VerifyConfig(config *Config) error {
- if config.AcceptBacklog <= 0 {
- return fmt.Errorf("backlog must be positive")
- }
- if config.KeepAliveInterval == 0 {
- return fmt.Errorf("keep-alive interval must be positive")
- }
- if config.MaxStreamWindowSize < initialStreamWindow {
- return fmt.Errorf("MaxStreamWindowSize must be larger than %d", initialStreamWindow)
- }
- if config.LogOutput != nil && config.Logger != nil {
- return fmt.Errorf("both Logger and LogOutput may not be set, select one")
- } else if config.LogOutput == nil && config.Logger == nil {
- return fmt.Errorf("one of Logger or LogOutput must be set, select one")
- }
- return nil
-}
-
-// Server is used to initialize a new server-side connection.
-// There must be at most one server-side connection. If a nil config is
-// provided, the DefaultConfiguration will be used.
-func Server(conn io.ReadWriteCloser, config *Config) (*Session, error) {
- if config == nil {
- config = DefaultConfig()
- }
- if err := VerifyConfig(config); err != nil {
- return nil, err
- }
- return newSession(config, conn, false), nil
-}
-
-// Client is used to initialize a new client-side connection.
-// There must be at most one client-side connection.
-func Client(conn io.ReadWriteCloser, config *Config) (*Session, error) {
- if config == nil {
- config = DefaultConfig()
- }
-
- if err := VerifyConfig(config); err != nil {
- return nil, err
- }
- return newSession(config, conn, true), nil
-}
diff --git a/vendor/github.com/hashicorp/yamux/session.go b/vendor/github.com/hashicorp/yamux/session.go
deleted file mode 100644
index a80ddec35..000000000
--- a/vendor/github.com/hashicorp/yamux/session.go
+++ /dev/null
@@ -1,653 +0,0 @@
-package yamux
-
-import (
- "bufio"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "math"
- "net"
- "strings"
- "sync"
- "sync/atomic"
- "time"
-)
-
-// Session is used to wrap a reliable ordered connection and to
-// multiplex it into multiple streams.
-type Session struct {
- // remoteGoAway indicates the remote side does
- // not want futher connections. Must be first for alignment.
- remoteGoAway int32
-
- // localGoAway indicates that we should stop
- // accepting futher connections. Must be first for alignment.
- localGoAway int32
-
- // nextStreamID is the next stream we should
- // send. This depends if we are a client/server.
- nextStreamID uint32
-
- // config holds our configuration
- config *Config
-
- // logger is used for our logs
- logger *log.Logger
-
- // conn is the underlying connection
- conn io.ReadWriteCloser
-
- // bufRead is a buffered reader
- bufRead *bufio.Reader
-
- // pings is used to track inflight pings
- pings map[uint32]chan struct{}
- pingID uint32
- pingLock sync.Mutex
-
- // streams maps a stream id to a stream, and inflight has an entry
- // for any outgoing stream that has not yet been established. Both are
- // protected by streamLock.
- streams map[uint32]*Stream
- inflight map[uint32]struct{}
- streamLock sync.Mutex
-
- // synCh acts like a semaphore. It is sized to the AcceptBacklog which
- // is assumed to be symmetric between the client and server. This allows
- // the client to avoid exceeding the backlog and instead blocks the open.
- synCh chan struct{}
-
- // acceptCh is used to pass ready streams to the client
- acceptCh chan *Stream
-
- // sendCh is used to mark a stream as ready to send,
- // or to send a header out directly.
- sendCh chan sendReady
-
- // recvDoneCh is closed when recv() exits to avoid a race
- // between stream registration and stream shutdown
- recvDoneCh chan struct{}
-
- // shutdown is used to safely close a session
- shutdown bool
- shutdownErr error
- shutdownCh chan struct{}
- shutdownLock sync.Mutex
-}
-
-// sendReady is used to either mark a stream as ready
-// or to directly send a header
-type sendReady struct {
- Hdr []byte
- Body io.Reader
- Err chan error
-}
-
-// newSession is used to construct a new session
-func newSession(config *Config, conn io.ReadWriteCloser, client bool) *Session {
- logger := config.Logger
- if logger == nil {
- logger = log.New(config.LogOutput, "", log.LstdFlags)
- }
-
- s := &Session{
- config: config,
- logger: logger,
- conn: conn,
- bufRead: bufio.NewReader(conn),
- pings: make(map[uint32]chan struct{}),
- streams: make(map[uint32]*Stream),
- inflight: make(map[uint32]struct{}),
- synCh: make(chan struct{}, config.AcceptBacklog),
- acceptCh: make(chan *Stream, config.AcceptBacklog),
- sendCh: make(chan sendReady, 64),
- recvDoneCh: make(chan struct{}),
- shutdownCh: make(chan struct{}),
- }
- if client {
- s.nextStreamID = 1
- } else {
- s.nextStreamID = 2
- }
- go s.recv()
- go s.send()
- if config.EnableKeepAlive {
- go s.keepalive()
- }
- return s
-}
-
-// IsClosed does a safe check to see if we have shutdown
-func (s *Session) IsClosed() bool {
- select {
- case <-s.shutdownCh:
- return true
- default:
- return false
- }
-}
-
-// CloseChan returns a read-only channel which is closed as
-// soon as the session is closed.
-func (s *Session) CloseChan() <-chan struct{} {
- return s.shutdownCh
-}
-
-// NumStreams returns the number of currently open streams
-func (s *Session) NumStreams() int {
- s.streamLock.Lock()
- num := len(s.streams)
- s.streamLock.Unlock()
- return num
-}
-
-// Open is used to create a new stream as a net.Conn
-func (s *Session) Open() (net.Conn, error) {
- conn, err := s.OpenStream()
- if err != nil {
- return nil, err
- }
- return conn, nil
-}
-
-// OpenStream is used to create a new stream
-func (s *Session) OpenStream() (*Stream, error) {
- if s.IsClosed() {
- return nil, ErrSessionShutdown
- }
- if atomic.LoadInt32(&s.remoteGoAway) == 1 {
- return nil, ErrRemoteGoAway
- }
-
- // Block if we have too many inflight SYNs
- select {
- case s.synCh <- struct{}{}:
- case <-s.shutdownCh:
- return nil, ErrSessionShutdown
- }
-
-GET_ID:
- // Get an ID, and check for stream exhaustion
- id := atomic.LoadUint32(&s.nextStreamID)
- if id >= math.MaxUint32-1 {
- return nil, ErrStreamsExhausted
- }
- if !atomic.CompareAndSwapUint32(&s.nextStreamID, id, id+2) {
- goto GET_ID
- }
-
- // Register the stream
- stream := newStream(s, id, streamInit)
- s.streamLock.Lock()
- s.streams[id] = stream
- s.inflight[id] = struct{}{}
- s.streamLock.Unlock()
-
- // Send the window update to create
- if err := stream.sendWindowUpdate(); err != nil {
- select {
- case <-s.synCh:
- default:
- s.logger.Printf("[ERR] yamux: aborted stream open without inflight syn semaphore")
- }
- return nil, err
- }
- return stream, nil
-}
-
-// Accept is used to block until the next available stream
-// is ready to be accepted.
-func (s *Session) Accept() (net.Conn, error) {
- conn, err := s.AcceptStream()
- if err != nil {
- return nil, err
- }
- return conn, err
-}
-
-// AcceptStream is used to block until the next available stream
-// is ready to be accepted.
-func (s *Session) AcceptStream() (*Stream, error) {
- select {
- case stream := <-s.acceptCh:
- if err := stream.sendWindowUpdate(); err != nil {
- return nil, err
- }
- return stream, nil
- case <-s.shutdownCh:
- return nil, s.shutdownErr
- }
-}
-
-// Close is used to close the session and all streams.
-// Attempts to send a GoAway before closing the connection.
-func (s *Session) Close() error {
- s.shutdownLock.Lock()
- defer s.shutdownLock.Unlock()
-
- if s.shutdown {
- return nil
- }
- s.shutdown = true
- if s.shutdownErr == nil {
- s.shutdownErr = ErrSessionShutdown
- }
- close(s.shutdownCh)
- s.conn.Close()
- <-s.recvDoneCh
-
- s.streamLock.Lock()
- defer s.streamLock.Unlock()
- for _, stream := range s.streams {
- stream.forceClose()
- }
- return nil
-}
-
-// exitErr is used to handle an error that is causing the
-// session to terminate.
-func (s *Session) exitErr(err error) {
- s.shutdownLock.Lock()
- if s.shutdownErr == nil {
- s.shutdownErr = err
- }
- s.shutdownLock.Unlock()
- s.Close()
-}
-
-// GoAway can be used to prevent accepting further
-// connections. It does not close the underlying conn.
-func (s *Session) GoAway() error {
- return s.waitForSend(s.goAway(goAwayNormal), nil)
-}
-
-// goAway is used to send a goAway message
-func (s *Session) goAway(reason uint32) header {
- atomic.SwapInt32(&s.localGoAway, 1)
- hdr := header(make([]byte, headerSize))
- hdr.encode(typeGoAway, 0, 0, reason)
- return hdr
-}
-
-// Ping is used to measure the RTT response time
-func (s *Session) Ping() (time.Duration, error) {
- // Get a channel for the ping
- ch := make(chan struct{})
-
- // Get a new ping id, mark as pending
- s.pingLock.Lock()
- id := s.pingID
- s.pingID++
- s.pings[id] = ch
- s.pingLock.Unlock()
-
- // Send the ping request
- hdr := header(make([]byte, headerSize))
- hdr.encode(typePing, flagSYN, 0, id)
- if err := s.waitForSend(hdr, nil); err != nil {
- return 0, err
- }
-
- // Wait for a response
- start := time.Now()
- select {
- case <-ch:
- case <-time.After(s.config.ConnectionWriteTimeout):
- s.pingLock.Lock()
- delete(s.pings, id) // Ignore it if a response comes later.
- s.pingLock.Unlock()
- return 0, ErrTimeout
- case <-s.shutdownCh:
- return 0, ErrSessionShutdown
- }
-
- // Compute the RTT
- return time.Now().Sub(start), nil
-}
-
-// keepalive is a long running goroutine that periodically does
-// a ping to keep the connection alive.
-func (s *Session) keepalive() {
- for {
- select {
- case <-time.After(s.config.KeepAliveInterval):
- _, err := s.Ping()
- if err != nil {
- if err != ErrSessionShutdown {
- s.logger.Printf("[ERR] yamux: keepalive failed: %v", err)
- s.exitErr(ErrKeepAliveTimeout)
- }
- return
- }
- case <-s.shutdownCh:
- return
- }
- }
-}
-
-// waitForSendErr waits to send a header, checking for a potential shutdown
-func (s *Session) waitForSend(hdr header, body io.Reader) error {
- errCh := make(chan error, 1)
- return s.waitForSendErr(hdr, body, errCh)
-}
-
-// waitForSendErr waits to send a header with optional data, checking for a
-// potential shutdown. Since there's the expectation that sends can happen
-// in a timely manner, we enforce the connection write timeout here.
-func (s *Session) waitForSendErr(hdr header, body io.Reader, errCh chan error) error {
- t := timerPool.Get()
- timer := t.(*time.Timer)
- timer.Reset(s.config.ConnectionWriteTimeout)
- defer func() {
- timer.Stop()
- select {
- case <-timer.C:
- default:
- }
- timerPool.Put(t)
- }()
-
- ready := sendReady{Hdr: hdr, Body: body, Err: errCh}
- select {
- case s.sendCh <- ready:
- case <-s.shutdownCh:
- return ErrSessionShutdown
- case <-timer.C:
- return ErrConnectionWriteTimeout
- }
-
- select {
- case err := <-errCh:
- return err
- case <-s.shutdownCh:
- return ErrSessionShutdown
- case <-timer.C:
- return ErrConnectionWriteTimeout
- }
-}
-
-// sendNoWait does a send without waiting. Since there's the expectation that
-// the send happens right here, we enforce the connection write timeout if we
-// can't queue the header to be sent.
-func (s *Session) sendNoWait(hdr header) error {
- t := timerPool.Get()
- timer := t.(*time.Timer)
- timer.Reset(s.config.ConnectionWriteTimeout)
- defer func() {
- timer.Stop()
- select {
- case <-timer.C:
- default:
- }
- timerPool.Put(t)
- }()
-
- select {
- case s.sendCh <- sendReady{Hdr: hdr}:
- return nil
- case <-s.shutdownCh:
- return ErrSessionShutdown
- case <-timer.C:
- return ErrConnectionWriteTimeout
- }
-}
-
-// send is a long running goroutine that sends data
-func (s *Session) send() {
- for {
- select {
- case ready := <-s.sendCh:
- // Send a header if ready
- if ready.Hdr != nil {
- sent := 0
- for sent < len(ready.Hdr) {
- n, err := s.conn.Write(ready.Hdr[sent:])
- if err != nil {
- s.logger.Printf("[ERR] yamux: Failed to write header: %v", err)
- asyncSendErr(ready.Err, err)
- s.exitErr(err)
- return
- }
- sent += n
- }
- }
-
- // Send data from a body if given
- if ready.Body != nil {
- _, err := io.Copy(s.conn, ready.Body)
- if err != nil {
- s.logger.Printf("[ERR] yamux: Failed to write body: %v", err)
- asyncSendErr(ready.Err, err)
- s.exitErr(err)
- return
- }
- }
-
- // No error, successful send
- asyncSendErr(ready.Err, nil)
- case <-s.shutdownCh:
- return
- }
- }
-}
-
-// recv is a long running goroutine that accepts new data
-func (s *Session) recv() {
- if err := s.recvLoop(); err != nil {
- s.exitErr(err)
- }
-}
-
-// Ensure that the index of the handler (typeData/typeWindowUpdate/etc) matches the message type
-var (
- handlers = []func(*Session, header) error{
- typeData: (*Session).handleStreamMessage,
- typeWindowUpdate: (*Session).handleStreamMessage,
- typePing: (*Session).handlePing,
- typeGoAway: (*Session).handleGoAway,
- }
-)
-
-// recvLoop continues to receive data until a fatal error is encountered
-func (s *Session) recvLoop() error {
- defer close(s.recvDoneCh)
- hdr := header(make([]byte, headerSize))
- for {
- // Read the header
- if _, err := io.ReadFull(s.bufRead, hdr); err != nil {
- if err != io.EOF && !strings.Contains(err.Error(), "closed") && !strings.Contains(err.Error(), "reset by peer") {
- s.logger.Printf("[ERR] yamux: Failed to read header: %v", err)
- }
- return err
- }
-
- // Verify the version
- if hdr.Version() != protoVersion {
- s.logger.Printf("[ERR] yamux: Invalid protocol version: %d", hdr.Version())
- return ErrInvalidVersion
- }
-
- mt := hdr.MsgType()
- if mt < typeData || mt > typeGoAway {
- return ErrInvalidMsgType
- }
-
- if err := handlers[mt](s, hdr); err != nil {
- return err
- }
- }
-}
-
-// handleStreamMessage handles either a data or window update frame
-func (s *Session) handleStreamMessage(hdr header) error {
- // Check for a new stream creation
- id := hdr.StreamID()
- flags := hdr.Flags()
- if flags&flagSYN == flagSYN {
- if err := s.incomingStream(id); err != nil {
- return err
- }
- }
-
- // Get the stream
- s.streamLock.Lock()
- stream := s.streams[id]
- s.streamLock.Unlock()
-
- // If we do not have a stream, likely we sent a RST
- if stream == nil {
- // Drain any data on the wire
- if hdr.MsgType() == typeData && hdr.Length() > 0 {
- s.logger.Printf("[WARN] yamux: Discarding data for stream: %d", id)
- if _, err := io.CopyN(ioutil.Discard, s.bufRead, int64(hdr.Length())); err != nil {
- s.logger.Printf("[ERR] yamux: Failed to discard data: %v", err)
- return nil
- }
- } else {
- s.logger.Printf("[WARN] yamux: frame for missing stream: %v", hdr)
- }
- return nil
- }
-
- // Check if this is a window update
- if hdr.MsgType() == typeWindowUpdate {
- if err := stream.incrSendWindow(hdr, flags); err != nil {
- if sendErr := s.sendNoWait(s.goAway(goAwayProtoErr)); sendErr != nil {
- s.logger.Printf("[WARN] yamux: failed to send go away: %v", sendErr)
- }
- return err
- }
- return nil
- }
-
- // Read the new data
- if err := stream.readData(hdr, flags, s.bufRead); err != nil {
- if sendErr := s.sendNoWait(s.goAway(goAwayProtoErr)); sendErr != nil {
- s.logger.Printf("[WARN] yamux: failed to send go away: %v", sendErr)
- }
- return err
- }
- return nil
-}
-
-// handlePing is invokde for a typePing frame
-func (s *Session) handlePing(hdr header) error {
- flags := hdr.Flags()
- pingID := hdr.Length()
-
- // Check if this is a query, respond back in a separate context so we
- // don't interfere with the receiving thread blocking for the write.
- if flags&flagSYN == flagSYN {
- go func() {
- hdr := header(make([]byte, headerSize))
- hdr.encode(typePing, flagACK, 0, pingID)
- if err := s.sendNoWait(hdr); err != nil {
- s.logger.Printf("[WARN] yamux: failed to send ping reply: %v", err)
- }
- }()
- return nil
- }
-
- // Handle a response
- s.pingLock.Lock()
- ch := s.pings[pingID]
- if ch != nil {
- delete(s.pings, pingID)
- close(ch)
- }
- s.pingLock.Unlock()
- return nil
-}
-
-// handleGoAway is invokde for a typeGoAway frame
-func (s *Session) handleGoAway(hdr header) error {
- code := hdr.Length()
- switch code {
- case goAwayNormal:
- atomic.SwapInt32(&s.remoteGoAway, 1)
- case goAwayProtoErr:
- s.logger.Printf("[ERR] yamux: received protocol error go away")
- return fmt.Errorf("yamux protocol error")
- case goAwayInternalErr:
- s.logger.Printf("[ERR] yamux: received internal error go away")
- return fmt.Errorf("remote yamux internal error")
- default:
- s.logger.Printf("[ERR] yamux: received unexpected go away")
- return fmt.Errorf("unexpected go away received")
- }
- return nil
-}
-
-// incomingStream is used to create a new incoming stream
-func (s *Session) incomingStream(id uint32) error {
- // Reject immediately if we are doing a go away
- if atomic.LoadInt32(&s.localGoAway) == 1 {
- hdr := header(make([]byte, headerSize))
- hdr.encode(typeWindowUpdate, flagRST, id, 0)
- return s.sendNoWait(hdr)
- }
-
- // Allocate a new stream
- stream := newStream(s, id, streamSYNReceived)
-
- s.streamLock.Lock()
- defer s.streamLock.Unlock()
-
- // Check if stream already exists
- if _, ok := s.streams[id]; ok {
- s.logger.Printf("[ERR] yamux: duplicate stream declared")
- if sendErr := s.sendNoWait(s.goAway(goAwayProtoErr)); sendErr != nil {
- s.logger.Printf("[WARN] yamux: failed to send go away: %v", sendErr)
- }
- return ErrDuplicateStream
- }
-
- // Register the stream
- s.streams[id] = stream
-
- // Check if we've exceeded the backlog
- select {
- case s.acceptCh <- stream:
- return nil
- default:
- // Backlog exceeded! RST the stream
- s.logger.Printf("[WARN] yamux: backlog exceeded, forcing connection reset")
- delete(s.streams, id)
- stream.sendHdr.encode(typeWindowUpdate, flagRST, id, 0)
- return s.sendNoWait(stream.sendHdr)
- }
-}
-
-// closeStream is used to close a stream once both sides have
-// issued a close. If there was an in-flight SYN and the stream
-// was not yet established, then this will give the credit back.
-func (s *Session) closeStream(id uint32) {
- s.streamLock.Lock()
- if _, ok := s.inflight[id]; ok {
- select {
- case <-s.synCh:
- default:
- s.logger.Printf("[ERR] yamux: SYN tracking out of sync")
- }
- }
- delete(s.streams, id)
- s.streamLock.Unlock()
-}
-
-// establishStream is used to mark a stream that was in the
-// SYN Sent state as established.
-func (s *Session) establishStream(id uint32) {
- s.streamLock.Lock()
- if _, ok := s.inflight[id]; ok {
- delete(s.inflight, id)
- } else {
- s.logger.Printf("[ERR] yamux: established stream without inflight SYN (no tracking entry)")
- }
- select {
- case <-s.synCh:
- default:
- s.logger.Printf("[ERR] yamux: established stream without inflight SYN (didn't have semaphore)")
- }
- s.streamLock.Unlock()
-}
diff --git a/vendor/github.com/hashicorp/yamux/spec.md b/vendor/github.com/hashicorp/yamux/spec.md
deleted file mode 100644
index 183d797bd..000000000
--- a/vendor/github.com/hashicorp/yamux/spec.md
+++ /dev/null
@@ -1,140 +0,0 @@
-# Specification
-
-We use this document to detail the internal specification of Yamux.
-This is used both as a guide for implementing Yamux, but also for
-alternative interoperable libraries to be built.
-
-# Framing
-
-Yamux uses a streaming connection underneath, but imposes a message
-framing so that it can be shared between many logical streams. Each
-frame contains a header like:
-
-* Version (8 bits)
-* Type (8 bits)
-* Flags (16 bits)
-* StreamID (32 bits)
-* Length (32 bits)
-
-This means that each header has a 12 byte overhead.
-All fields are encoded in network order (big endian).
-Each field is described below:
-
-## Version Field
-
-The version field is used for future backward compatibility. At the
-current time, the field is always set to 0, to indicate the initial
-version.
-
-## Type Field
-
-The type field is used to switch the frame message type. The following
-message types are supported:
-
-* 0x0 Data - Used to transmit data. May transmit zero length payloads
- depending on the flags.
-
-* 0x1 Window Update - Used to updated the senders receive window size.
- This is used to implement per-session flow control.
-
-* 0x2 Ping - Used to measure RTT. It can also be used to heart-beat
- and do keep-alives over TCP.
-
-* 0x3 Go Away - Used to close a session.
-
-## Flag Field
-
-The flags field is used to provide additional information related
-to the message type. The following flags are supported:
-
-* 0x1 SYN - Signals the start of a new stream. May be sent with a data or
- window update message. Also sent with a ping to indicate outbound.
-
-* 0x2 ACK - Acknowledges the start of a new stream. May be sent with a data
- or window update message. Also sent with a ping to indicate response.
-
-* 0x4 FIN - Performs a half-close of a stream. May be sent with a data
- message or window update.
-
-* 0x8 RST - Reset a stream immediately. May be sent with a data or
- window update message.
-
-## StreamID Field
-
-The StreamID field is used to identify the logical stream the frame
-is addressing. The client side should use odd ID's, and the server even.
-This prevents any collisions. Additionally, the 0 ID is reserved to represent
-the session.
-
-Both Ping and Go Away messages should always use the 0 StreamID.
-
-## Length Field
-
-The meaning of the length field depends on the message type:
-
-* Data - provides the length of bytes following the header
-* Window update - provides a delta update to the window size
-* Ping - Contains an opaque value, echoed back
-* Go Away - Contains an error code
-
-# Message Flow
-
-There is no explicit connection setup, as Yamux relies on an underlying
-transport to be provided. However, there is a distinction between client
-and server side of the connection.
-
-## Opening a stream
-
-To open a stream, an initial data or window update frame is sent
-with a new StreamID. The SYN flag should be set to signal a new stream.
-
-The receiver must then reply with either a data or window update frame
-with the StreamID along with the ACK flag to accept the stream or with
-the RST flag to reject the stream.
-
-Because we are relying on the reliable stream underneath, a connection
-can begin sending data once the SYN flag is sent. The corresponding
-ACK does not need to be received. This is particularly well suited
-for an RPC system where a client wants to open a stream and immediately
-fire a request without waiting for the RTT of the ACK.
-
-This does introduce the possibility of a connection being rejected
-after data has been sent already. This is a slight semantic difference
-from TCP, where the conection cannot be refused after it is opened.
-Clients should be prepared to handle this by checking for an error
-that indicates a RST was received.
-
-## Closing a stream
-
-To close a stream, either side sends a data or window update frame
-along with the FIN flag. This does a half-close indicating the sender
-will send no further data.
-
-Once both sides have closed the connection, the stream is closed.
-
-Alternatively, if an error occurs, the RST flag can be used to
-hard close a stream immediately.
-
-## Flow Control
-
-When Yamux is initially starts each stream with a 256KB window size.
-There is no window size for the session.
-
-To prevent the streams from stalling, window update frames should be
-sent regularly. Yamux can be configured to provide a larger limit for
-windows sizes. Both sides assume the initial 256KB window, but can
-immediately send a window update as part of the SYN/ACK indicating a
-larger window.
-
-Both sides should track the number of bytes sent in Data frames
-only, as only they are tracked as part of the window size.
-
-## Session termination
-
-When a session is being terminated, the Go Away message should
-be sent. The Length should be set to one of the following to
-provide an error code:
-
-* 0x0 Normal termination
-* 0x1 Protocol error
-* 0x2 Internal error
diff --git a/vendor/github.com/hashicorp/yamux/stream.go b/vendor/github.com/hashicorp/yamux/stream.go
deleted file mode 100644
index aa2391973..000000000
--- a/vendor/github.com/hashicorp/yamux/stream.go
+++ /dev/null
@@ -1,470 +0,0 @@
-package yamux
-
-import (
- "bytes"
- "io"
- "sync"
- "sync/atomic"
- "time"
-)
-
-type streamState int
-
-const (
- streamInit streamState = iota
- streamSYNSent
- streamSYNReceived
- streamEstablished
- streamLocalClose
- streamRemoteClose
- streamClosed
- streamReset
-)
-
-// Stream is used to represent a logical stream
-// within a session.
-type Stream struct {
- recvWindow uint32
- sendWindow uint32
-
- id uint32
- session *Session
-
- state streamState
- stateLock sync.Mutex
-
- recvBuf *bytes.Buffer
- recvLock sync.Mutex
-
- controlHdr header
- controlErr chan error
- controlHdrLock sync.Mutex
-
- sendHdr header
- sendErr chan error
- sendLock sync.Mutex
-
- recvNotifyCh chan struct{}
- sendNotifyCh chan struct{}
-
- readDeadline atomic.Value // time.Time
- writeDeadline atomic.Value // time.Time
-}
-
-// newStream is used to construct a new stream within
-// a given session for an ID
-func newStream(session *Session, id uint32, state streamState) *Stream {
- s := &Stream{
- id: id,
- session: session,
- state: state,
- controlHdr: header(make([]byte, headerSize)),
- controlErr: make(chan error, 1),
- sendHdr: header(make([]byte, headerSize)),
- sendErr: make(chan error, 1),
- recvWindow: initialStreamWindow,
- sendWindow: initialStreamWindow,
- recvNotifyCh: make(chan struct{}, 1),
- sendNotifyCh: make(chan struct{}, 1),
- }
- s.readDeadline.Store(time.Time{})
- s.writeDeadline.Store(time.Time{})
- return s
-}
-
-// Session returns the associated stream session
-func (s *Stream) Session() *Session {
- return s.session
-}
-
-// StreamID returns the ID of this stream
-func (s *Stream) StreamID() uint32 {
- return s.id
-}
-
-// Read is used to read from the stream
-func (s *Stream) Read(b []byte) (n int, err error) {
- defer asyncNotify(s.recvNotifyCh)
-START:
- s.stateLock.Lock()
- switch s.state {
- case streamLocalClose:
- fallthrough
- case streamRemoteClose:
- fallthrough
- case streamClosed:
- s.recvLock.Lock()
- if s.recvBuf == nil || s.recvBuf.Len() == 0 {
- s.recvLock.Unlock()
- s.stateLock.Unlock()
- return 0, io.EOF
- }
- s.recvLock.Unlock()
- case streamReset:
- s.stateLock.Unlock()
- return 0, ErrConnectionReset
- }
- s.stateLock.Unlock()
-
- // If there is no data available, block
- s.recvLock.Lock()
- if s.recvBuf == nil || s.recvBuf.Len() == 0 {
- s.recvLock.Unlock()
- goto WAIT
- }
-
- // Read any bytes
- n, _ = s.recvBuf.Read(b)
- s.recvLock.Unlock()
-
- // Send a window update potentially
- err = s.sendWindowUpdate()
- return n, err
-
-WAIT:
- var timeout <-chan time.Time
- var timer *time.Timer
- readDeadline := s.readDeadline.Load().(time.Time)
- if !readDeadline.IsZero() {
- delay := readDeadline.Sub(time.Now())
- timer = time.NewTimer(delay)
- timeout = timer.C
- }
- select {
- case <-s.recvNotifyCh:
- if timer != nil {
- timer.Stop()
- }
- goto START
- case <-timeout:
- return 0, ErrTimeout
- }
-}
-
-// Write is used to write to the stream
-func (s *Stream) Write(b []byte) (n int, err error) {
- s.sendLock.Lock()
- defer s.sendLock.Unlock()
- total := 0
- for total < len(b) {
- n, err := s.write(b[total:])
- total += n
- if err != nil {
- return total, err
- }
- }
- return total, nil
-}
-
-// write is used to write to the stream, may return on
-// a short write.
-func (s *Stream) write(b []byte) (n int, err error) {
- var flags uint16
- var max uint32
- var body io.Reader
-START:
- s.stateLock.Lock()
- switch s.state {
- case streamLocalClose:
- fallthrough
- case streamClosed:
- s.stateLock.Unlock()
- return 0, ErrStreamClosed
- case streamReset:
- s.stateLock.Unlock()
- return 0, ErrConnectionReset
- }
- s.stateLock.Unlock()
-
- // If there is no data available, block
- window := atomic.LoadUint32(&s.sendWindow)
- if window == 0 {
- goto WAIT
- }
-
- // Determine the flags if any
- flags = s.sendFlags()
-
- // Send up to our send window
- max = min(window, uint32(len(b)))
- body = bytes.NewReader(b[:max])
-
- // Send the header
- s.sendHdr.encode(typeData, flags, s.id, max)
- if err = s.session.waitForSendErr(s.sendHdr, body, s.sendErr); err != nil {
- return 0, err
- }
-
- // Reduce our send window
- atomic.AddUint32(&s.sendWindow, ^uint32(max-1))
-
- // Unlock
- return int(max), err
-
-WAIT:
- var timeout <-chan time.Time
- writeDeadline := s.writeDeadline.Load().(time.Time)
- if !writeDeadline.IsZero() {
- delay := writeDeadline.Sub(time.Now())
- timeout = time.After(delay)
- }
- select {
- case <-s.sendNotifyCh:
- goto START
- case <-timeout:
- return 0, ErrTimeout
- }
- return 0, nil
-}
-
-// sendFlags determines any flags that are appropriate
-// based on the current stream state
-func (s *Stream) sendFlags() uint16 {
- s.stateLock.Lock()
- defer s.stateLock.Unlock()
- var flags uint16
- switch s.state {
- case streamInit:
- flags |= flagSYN
- s.state = streamSYNSent
- case streamSYNReceived:
- flags |= flagACK
- s.state = streamEstablished
- }
- return flags
-}
-
-// sendWindowUpdate potentially sends a window update enabling
-// further writes to take place. Must be invoked with the lock.
-func (s *Stream) sendWindowUpdate() error {
- s.controlHdrLock.Lock()
- defer s.controlHdrLock.Unlock()
-
- // Determine the delta update
- max := s.session.config.MaxStreamWindowSize
- var bufLen uint32
- s.recvLock.Lock()
- if s.recvBuf != nil {
- bufLen = uint32(s.recvBuf.Len())
- }
- delta := (max - bufLen) - s.recvWindow
-
- // Determine the flags if any
- flags := s.sendFlags()
-
- // Check if we can omit the update
- if delta < (max/2) && flags == 0 {
- s.recvLock.Unlock()
- return nil
- }
-
- // Update our window
- s.recvWindow += delta
- s.recvLock.Unlock()
-
- // Send the header
- s.controlHdr.encode(typeWindowUpdate, flags, s.id, delta)
- if err := s.session.waitForSendErr(s.controlHdr, nil, s.controlErr); err != nil {
- return err
- }
- return nil
-}
-
-// sendClose is used to send a FIN
-func (s *Stream) sendClose() error {
- s.controlHdrLock.Lock()
- defer s.controlHdrLock.Unlock()
-
- flags := s.sendFlags()
- flags |= flagFIN
- s.controlHdr.encode(typeWindowUpdate, flags, s.id, 0)
- if err := s.session.waitForSendErr(s.controlHdr, nil, s.controlErr); err != nil {
- return err
- }
- return nil
-}
-
-// Close is used to close the stream
-func (s *Stream) Close() error {
- closeStream := false
- s.stateLock.Lock()
- switch s.state {
- // Opened means we need to signal a close
- case streamSYNSent:
- fallthrough
- case streamSYNReceived:
- fallthrough
- case streamEstablished:
- s.state = streamLocalClose
- goto SEND_CLOSE
-
- case streamLocalClose:
- case streamRemoteClose:
- s.state = streamClosed
- closeStream = true
- goto SEND_CLOSE
-
- case streamClosed:
- case streamReset:
- default:
- panic("unhandled state")
- }
- s.stateLock.Unlock()
- return nil
-SEND_CLOSE:
- s.stateLock.Unlock()
- s.sendClose()
- s.notifyWaiting()
- if closeStream {
- s.session.closeStream(s.id)
- }
- return nil
-}
-
-// forceClose is used for when the session is exiting
-func (s *Stream) forceClose() {
- s.stateLock.Lock()
- s.state = streamClosed
- s.stateLock.Unlock()
- s.notifyWaiting()
-}
-
-// processFlags is used to update the state of the stream
-// based on set flags, if any. Lock must be held
-func (s *Stream) processFlags(flags uint16) error {
- // Close the stream without holding the state lock
- closeStream := false
- defer func() {
- if closeStream {
- s.session.closeStream(s.id)
- }
- }()
-
- s.stateLock.Lock()
- defer s.stateLock.Unlock()
- if flags&flagACK == flagACK {
- if s.state == streamSYNSent {
- s.state = streamEstablished
- }
- s.session.establishStream(s.id)
- }
- if flags&flagFIN == flagFIN {
- switch s.state {
- case streamSYNSent:
- fallthrough
- case streamSYNReceived:
- fallthrough
- case streamEstablished:
- s.state = streamRemoteClose
- s.notifyWaiting()
- case streamLocalClose:
- s.state = streamClosed
- closeStream = true
- s.notifyWaiting()
- default:
- s.session.logger.Printf("[ERR] yamux: unexpected FIN flag in state %d", s.state)
- return ErrUnexpectedFlag
- }
- }
- if flags&flagRST == flagRST {
- s.state = streamReset
- closeStream = true
- s.notifyWaiting()
- }
- return nil
-}
-
-// notifyWaiting notifies all the waiting channels
-func (s *Stream) notifyWaiting() {
- asyncNotify(s.recvNotifyCh)
- asyncNotify(s.sendNotifyCh)
-}
-
-// incrSendWindow updates the size of our send window
-func (s *Stream) incrSendWindow(hdr header, flags uint16) error {
- if err := s.processFlags(flags); err != nil {
- return err
- }
-
- // Increase window, unblock a sender
- atomic.AddUint32(&s.sendWindow, hdr.Length())
- asyncNotify(s.sendNotifyCh)
- return nil
-}
-
-// readData is used to handle a data frame
-func (s *Stream) readData(hdr header, flags uint16, conn io.Reader) error {
- if err := s.processFlags(flags); err != nil {
- return err
- }
-
- // Check that our recv window is not exceeded
- length := hdr.Length()
- if length == 0 {
- return nil
- }
-
- // Wrap in a limited reader
- conn = &io.LimitedReader{R: conn, N: int64(length)}
-
- // Copy into buffer
- s.recvLock.Lock()
-
- if length > s.recvWindow {
- s.session.logger.Printf("[ERR] yamux: receive window exceeded (stream: %d, remain: %d, recv: %d)", s.id, s.recvWindow, length)
- return ErrRecvWindowExceeded
- }
-
- if s.recvBuf == nil {
- // Allocate the receive buffer just-in-time to fit the full data frame.
- // This way we can read in the whole packet without further allocations.
- s.recvBuf = bytes.NewBuffer(make([]byte, 0, length))
- }
- if _, err := io.Copy(s.recvBuf, conn); err != nil {
- s.session.logger.Printf("[ERR] yamux: Failed to read stream data: %v", err)
- s.recvLock.Unlock()
- return err
- }
-
- // Decrement the receive window
- s.recvWindow -= length
- s.recvLock.Unlock()
-
- // Unblock any readers
- asyncNotify(s.recvNotifyCh)
- return nil
-}
-
-// SetDeadline sets the read and write deadlines
-func (s *Stream) SetDeadline(t time.Time) error {
- if err := s.SetReadDeadline(t); err != nil {
- return err
- }
- if err := s.SetWriteDeadline(t); err != nil {
- return err
- }
- return nil
-}
-
-// SetReadDeadline sets the deadline for future Read calls.
-func (s *Stream) SetReadDeadline(t time.Time) error {
- s.readDeadline.Store(t)
- return nil
-}
-
-// SetWriteDeadline sets the deadline for future Write calls
-func (s *Stream) SetWriteDeadline(t time.Time) error {
- s.writeDeadline.Store(t)
- return nil
-}
-
-// Shrink is used to compact the amount of buffers utilized
-// This is useful when using Yamux in a connection pool to reduce
-// the idle memory utilization.
-func (s *Stream) Shrink() {
- s.recvLock.Lock()
- if s.recvBuf != nil && s.recvBuf.Len() == 0 {
- s.recvBuf = nil
- }
- s.recvLock.Unlock()
-}
diff --git a/vendor/github.com/hashicorp/yamux/util.go b/vendor/github.com/hashicorp/yamux/util.go
deleted file mode 100644
index 8a73e9249..000000000
--- a/vendor/github.com/hashicorp/yamux/util.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package yamux
-
-import (
- "sync"
- "time"
-)
-
-var (
- timerPool = &sync.Pool{
- New: func() interface{} {
- timer := time.NewTimer(time.Hour * 1e6)
- timer.Stop()
- return timer
- },
- }
-)
-
-// asyncSendErr is used to try an async send of an error
-func asyncSendErr(ch chan error, err error) {
- if ch == nil {
- return
- }
- select {
- case ch <- err:
- default:
- }
-}
-
-// asyncNotify is used to signal a waiting goroutine
-func asyncNotify(ch chan struct{}) {
- select {
- case ch <- struct{}{}:
- default:
- }
-}
-
-// min computes the minimum of two values
-func min(a, b uint32) uint32 {
- if a < b {
- return a
- }
- return b
-}
diff --git a/vendor/github.com/miekg/dns/README.md b/vendor/github.com/miekg/dns/README.md
index 77874642b..7f1aaa5de 100644
--- a/vendor/github.com/miekg/dns/README.md
+++ b/vendor/github.com/miekg/dns/README.md
@@ -67,6 +67,7 @@ A not-so-up-to-date-list-that-may-be-actually-current:
* https://github.com/xor-gate/sshfp
* https://github.com/rs/dnstrace
* https://blitiri.com.ar/p/dnss ([github mirror](https://github.com/albertito/dnss))
+* https://github.com/semihalev/sdns
Send pull request if you want to be listed here.
diff --git a/vendor/github.com/miekg/dns/dnssec_keyscan.go b/vendor/github.com/miekg/dns/dnssec_keyscan.go
index 719198659..5e6542230 100644
--- a/vendor/github.com/miekg/dns/dnssec_keyscan.go
+++ b/vendor/github.com/miekg/dns/dnssec_keyscan.go
@@ -1,6 +1,7 @@
package dns
import (
+ "bufio"
"crypto"
"crypto/dsa"
"crypto/ecdsa"
@@ -194,23 +195,12 @@ func readPrivateKeyED25519(m map[string]string) (ed25519.PrivateKey, error) {
// parseKey reads a private key from r. It returns a map[string]string,
// with the key-value pairs, or an error when the file is not correct.
func parseKey(r io.Reader, file string) (map[string]string, error) {
- s, cancel := scanInit(r)
m := make(map[string]string)
- c := make(chan lex)
- k := ""
- defer func() {
- cancel()
- // zlexer can send up to two tokens, the next one and possibly 1 remainders.
- // Do a non-blocking read.
- _, ok := <-c
- _, ok = <-c
- if !ok {
- // too bad
- }
- }()
- // Start the lexer
- go klexer(s, c)
- for l := range c {
+ var k string
+
+ c := newKLexer(r)
+
+ for l, ok := c.Next(); ok; l, ok = c.Next() {
// It should alternate
switch l.value {
case zKey:
@@ -219,41 +209,111 @@ func parseKey(r io.Reader, file string) (map[string]string, error) {
if k == "" {
return nil, &ParseError{file, "no private key seen", l}
}
- //println("Setting", strings.ToLower(k), "to", l.token, "b")
+
m[strings.ToLower(k)] = l.token
k = ""
}
}
+
+ // Surface any read errors from r.
+ if err := c.Err(); err != nil {
+ return nil, &ParseError{file: file, err: err.Error()}
+ }
+
return m, nil
}
-// klexer scans the sourcefile and returns tokens on the channel c.
-func klexer(s *scan, c chan lex) {
- var l lex
- str := "" // Hold the current read text
- commt := false
- key := true
- x, err := s.tokenText()
- defer close(c)
- for err == nil {
- l.column = s.position.Column
- l.line = s.position.Line
+type klexer struct {
+ br io.ByteReader
+
+ readErr error
+
+ line int
+ column int
+
+ key bool
+
+ eol bool // end-of-line
+}
+
+func newKLexer(r io.Reader) *klexer {
+ br, ok := r.(io.ByteReader)
+ if !ok {
+ br = bufio.NewReaderSize(r, 1024)
+ }
+
+ return &klexer{
+ br: br,
+
+ line: 1,
+
+ key: true,
+ }
+}
+
+func (kl *klexer) Err() error {
+ if kl.readErr == io.EOF {
+ return nil
+ }
+
+ return kl.readErr
+}
+
+// readByte returns the next byte from the input
+func (kl *klexer) readByte() (byte, bool) {
+ if kl.readErr != nil {
+ return 0, false
+ }
+
+ c, err := kl.br.ReadByte()
+ if err != nil {
+ kl.readErr = err
+ return 0, false
+ }
+
+ // delay the newline handling until the next token is delivered,
+ // fixes off-by-one errors when reporting a parse error.
+ if kl.eol {
+ kl.line++
+ kl.column = 0
+ kl.eol = false
+ }
+
+ if c == '\n' {
+ kl.eol = true
+ } else {
+ kl.column++
+ }
+
+ return c, true
+}
+
+func (kl *klexer) Next() (lex, bool) {
+ var (
+ l lex
+
+ str strings.Builder
+
+ commt bool
+ )
+
+ for x, ok := kl.readByte(); ok; x, ok = kl.readByte() {
+ l.line, l.column = kl.line, kl.column
+
switch x {
case ':':
- if commt {
+ if commt || !kl.key {
break
}
- l.token = str
- if key {
- l.value = zKey
- c <- l
- // Next token is a space, eat it
- s.tokenText()
- key = false
- str = ""
- } else {
- l.value = zValue
- }
+
+ kl.key = false
+
+ // Next token is a space, eat it
+ kl.readByte()
+
+ l.value = zKey
+ l.token = str.String()
+ return l, true
case ';':
commt = true
case '\n':
@@ -261,24 +321,32 @@ func klexer(s *scan, c chan lex) {
// Reset a comment
commt = false
}
+
+ kl.key = true
+
l.value = zValue
- l.token = str
- c <- l
- str = ""
- commt = false
- key = true
+ l.token = str.String()
+ return l, true
default:
if commt {
break
}
- str += string(x)
+
+ str.WriteByte(x)
}
- x, err = s.tokenText()
}
- if len(str) > 0 {
+
+ if kl.readErr != nil && kl.readErr != io.EOF {
+ // Don't return any tokens after a read error occurs.
+ return lex{value: zEOF}, false
+ }
+
+ if str.Len() > 0 {
// Send remainder
- l.token = str
l.value = zValue
- c <- l
+ l.token = str.String()
+ return l, true
}
+
+ return lex{value: zEOF}, false
}
diff --git a/vendor/github.com/miekg/dns/generate.go b/vendor/github.com/miekg/dns/generate.go
index 91d928c83..97bc39f58 100644
--- a/vendor/github.com/miekg/dns/generate.go
+++ b/vendor/github.com/miekg/dns/generate.go
@@ -2,8 +2,8 @@ package dns
import (
"bytes"
- "errors"
"fmt"
+ "io"
"strconv"
"strings"
)
@@ -18,154 +18,225 @@ import (
// * rhs (rdata)
// But we are lazy here, only the range is parsed *all* occurrences
// of $ after that are interpreted.
-// Any error are returned as a string value, the empty string signals
-// "no error".
-func generate(l lex, c chan lex, t chan *Token, o string) string {
+func (zp *ZoneParser) generate(l lex) (RR, bool) {
+ token := l.token
step := 1
- if i := strings.IndexAny(l.token, "/"); i != -1 {
- if i+1 == len(l.token) {
- return "bad step in $GENERATE range"
+ if i := strings.IndexByte(token, '/'); i >= 0 {
+ if i+1 == len(token) {
+ return zp.setParseError("bad step in $GENERATE range", l)
}
- if s, err := strconv.Atoi(l.token[i+1:]); err == nil {
- if s < 0 {
- return "bad step in $GENERATE range"
- }
- step = s
- } else {
- return "bad step in $GENERATE range"
+
+ s, err := strconv.Atoi(token[i+1:])
+ if err != nil || s <= 0 {
+ return zp.setParseError("bad step in $GENERATE range", l)
}
- l.token = l.token[:i]
+
+ step = s
+ token = token[:i]
}
- sx := strings.SplitN(l.token, "-", 2)
+
+ sx := strings.SplitN(token, "-", 2)
if len(sx) != 2 {
- return "bad start-stop in $GENERATE range"
+ return zp.setParseError("bad start-stop in $GENERATE range", l)
}
+
start, err := strconv.Atoi(sx[0])
if err != nil {
- return "bad start in $GENERATE range"
+ return zp.setParseError("bad start in $GENERATE range", l)
}
+
end, err := strconv.Atoi(sx[1])
if err != nil {
- return "bad stop in $GENERATE range"
+ return zp.setParseError("bad stop in $GENERATE range", l)
}
if end < 0 || start < 0 || end < start {
- return "bad range in $GENERATE range"
+ return zp.setParseError("bad range in $GENERATE range", l)
}
- <-c // _BLANK
+ zp.c.Next() // _BLANK
+
// Create a complete new string, which we then parse again.
- s := ""
-BuildRR:
- l = <-c
- if l.value != zNewline && l.value != zEOF {
+ var s string
+ for l, ok := zp.c.Next(); ok; l, ok = zp.c.Next() {
+ if l.err {
+ return zp.setParseError("bad data in $GENERATE directive", l)
+ }
+ if l.value == zNewline {
+ break
+ }
+
s += l.token
- goto BuildRR
- }
- for i := start; i <= end; i += step {
- var (
- escape bool
- dom bytes.Buffer
- mod string
- err error
- offset int
- )
-
- for j := 0; j < len(s); j++ { // No 'range' because we need to jump around
- switch s[j] {
- case '\\':
- if escape {
- dom.WriteByte('\\')
- escape = false
- continue
- }
- escape = true
- case '$':
- mod = "%d"
- offset = 0
- if escape {
- dom.WriteByte('$')
- escape = false
- continue
- }
- escape = false
- if j+1 >= len(s) { // End of the string
- dom.WriteString(fmt.Sprintf(mod, i+offset))
- continue
- } else {
- if s[j+1] == '$' {
- dom.WriteByte('$')
- j++
- continue
- }
- }
- // Search for { and }
- if s[j+1] == '{' { // Modifier block
- sep := strings.Index(s[j+2:], "}")
- if sep == -1 {
- return "bad modifier in $GENERATE"
- }
- mod, offset, err = modToPrintf(s[j+2 : j+2+sep])
- if err != nil {
- return err.Error()
- } else if start + offset < 0 || end + offset > 1<<31-1 {
- return "bad offset in $GENERATE"
- }
- j += 2 + sep // Jump to it
- }
- dom.WriteString(fmt.Sprintf(mod, i+offset))
- default:
- if escape { // Pretty useless here
- escape = false
- continue
- }
- dom.WriteByte(s[j])
+ }
+
+ r := &generateReader{
+ s: s,
+
+ cur: start,
+ start: start,
+ end: end,
+ step: step,
+
+ file: zp.file,
+ lex: &l,
+ }
+ zp.sub = NewZoneParser(r, zp.origin, zp.file)
+ zp.sub.includeDepth, zp.sub.includeAllowed = zp.includeDepth, zp.includeAllowed
+ zp.sub.SetDefaultTTL(defaultTtl)
+ return zp.subNext()
+}
+
+type generateReader struct {
+ s string
+ si int
+
+ cur int
+ start int
+ end int
+ step int
+
+ mod bytes.Buffer
+
+ escape bool
+
+ eof bool
+
+ file string
+ lex *lex
+}
+
+func (r *generateReader) parseError(msg string, end int) *ParseError {
+ r.eof = true // Make errors sticky.
+
+ l := *r.lex
+ l.token = r.s[r.si-1 : end]
+ l.column += r.si // l.column starts one zBLANK before r.s
+
+ return &ParseError{r.file, msg, l}
+}
+
+func (r *generateReader) Read(p []byte) (int, error) {
+ // NewZLexer, through NewZoneParser, should use ReadByte and
+ // not end up here.
+
+ panic("not implemented")
+}
+
+func (r *generateReader) ReadByte() (byte, error) {
+ if r.eof {
+ return 0, io.EOF
+ }
+ if r.mod.Len() > 0 {
+ return r.mod.ReadByte()
+ }
+
+ if r.si >= len(r.s) {
+ r.si = 0
+ r.cur += r.step
+
+ r.eof = r.cur > r.end || r.cur < 0
+ return '\n', nil
+ }
+
+ si := r.si
+ r.si++
+
+ switch r.s[si] {
+ case '\\':
+ if r.escape {
+ r.escape = false
+ return '\\', nil
+ }
+
+ r.escape = true
+ return r.ReadByte()
+ case '$':
+ if r.escape {
+ r.escape = false
+ return '$', nil
+ }
+
+ mod := "%d"
+
+ if si >= len(r.s)-1 {
+ // End of the string
+ fmt.Fprintf(&r.mod, mod, r.cur)
+ return r.mod.ReadByte()
+ }
+
+ if r.s[si+1] == '$' {
+ r.si++
+ return '$', nil
+ }
+
+ var offset int
+
+ // Search for { and }
+ if r.s[si+1] == '{' {
+ // Modifier block
+ sep := strings.Index(r.s[si+2:], "}")
+ if sep < 0 {
+ return 0, r.parseError("bad modifier in $GENERATE", len(r.s))
+ }
+
+ var errMsg string
+ mod, offset, errMsg = modToPrintf(r.s[si+2 : si+2+sep])
+ if errMsg != "" {
+ return 0, r.parseError(errMsg, si+3+sep)
}
+ if r.start+offset < 0 || r.end+offset > 1<<31-1 {
+ return 0, r.parseError("bad offset in $GENERATE", si+3+sep)
+ }
+
+ r.si += 2 + sep // Jump to it
}
- // Re-parse the RR and send it on the current channel t
- rx, err := NewRR("$ORIGIN " + o + "\n" + dom.String())
- if err != nil {
- return err.Error()
+
+ fmt.Fprintf(&r.mod, mod, r.cur+offset)
+ return r.mod.ReadByte()
+ default:
+ if r.escape { // Pretty useless here
+ r.escape = false
+ return r.ReadByte()
}
- t <- &Token{RR: rx}
- // Its more efficient to first built the rrlist and then parse it in
- // one go! But is this a problem?
+
+ return r.s[si], nil
}
- return ""
}
// Convert a $GENERATE modifier 0,0,d to something Printf can deal with.
-func modToPrintf(s string) (string, int, error) {
- xs := strings.Split(s, ",")
-
+func modToPrintf(s string) (string, int, string) {
// Modifier is { offset [ ,width [ ,base ] ] } - provide default
// values for optional width and type, if necessary.
- switch len(xs) {
+ var offStr, widthStr, base string
+ switch xs := strings.Split(s, ","); len(xs) {
case 1:
- xs = append(xs, "0", "d")
+ offStr, widthStr, base = xs[0], "0", "d"
case 2:
- xs = append(xs, "d")
+ offStr, widthStr, base = xs[0], xs[1], "d"
case 3:
+ offStr, widthStr, base = xs[0], xs[1], xs[2]
default:
- return "", 0, errors.New("bad modifier in $GENERATE")
+ return "", 0, "bad modifier in $GENERATE"
}
- // xs[0] is offset, xs[1] is width, xs[2] is base
- if xs[2] != "o" && xs[2] != "d" && xs[2] != "x" && xs[2] != "X" {
- return "", 0, errors.New("bad base in $GENERATE")
+ switch base {
+ case "o", "d", "x", "X":
+ default:
+ return "", 0, "bad base in $GENERATE"
}
- offset, err := strconv.Atoi(xs[0])
+
+ offset, err := strconv.Atoi(offStr)
if err != nil {
- return "", 0, errors.New("bad offset in $GENERATE")
+ return "", 0, "bad offset in $GENERATE"
}
- width, err := strconv.Atoi(xs[1])
- if err != nil || width > 255 {
- return "", offset, errors.New("bad width in $GENERATE")
+
+ width, err := strconv.Atoi(widthStr)
+ if err != nil || width < 0 || width > 255 {
+ return "", 0, "bad width in $GENERATE"
}
- switch {
- case width < 0:
- return "", offset, errors.New("bad width in $GENERATE")
- case width == 0:
- return "%" + xs[1] + xs[2], offset, nil
+
+ if width == 0 {
+ return "%" + base, offset, ""
}
- return "%0" + xs[1] + xs[2], offset, nil
+
+ return "%0" + widthStr + base, offset, ""
}
diff --git a/vendor/github.com/miekg/dns/privaterr.go b/vendor/github.com/miekg/dns/privaterr.go
index d931da7ef..74544a74e 100644
--- a/vendor/github.com/miekg/dns/privaterr.go
+++ b/vendor/github.com/miekg/dns/privaterr.go
@@ -105,7 +105,7 @@ func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata)
return rr, off, err
}
- setPrivateRR := func(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+ setPrivateRR := func(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := mkPrivateRR(h.Rrtype)
rr.Hdr = h
@@ -115,7 +115,7 @@ func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata)
for {
// TODO(miek): we could also be returning _QUOTE, this might or might not
// be an issue (basically parsing TXT becomes hard)
- switch l = <-c; l.value {
+ switch l, _ = c.Next(); l.value {
case zNewline, zEOF:
break Fetch
case zString:
diff --git a/vendor/github.com/miekg/dns/scan.go b/vendor/github.com/miekg/dns/scan.go
index a752dbd01..61ace121e 100644
--- a/vendor/github.com/miekg/dns/scan.go
+++ b/vendor/github.com/miekg/dns/scan.go
@@ -1,6 +1,7 @@
package dns
import (
+ "bufio"
"fmt"
"io"
"os"
@@ -11,6 +12,10 @@ import (
const maxTok = 2048 // Largest token we can return.
+// The maximum depth of $INCLUDE directives supported by the
+// ZoneParser API.
+const maxIncludeDepth = 7
+
// Tokinize a RFC 1035 zone file. The tokenizer will normalize it:
// * Add ownernames if they are left blank;
// * Suppress sequences of spaces;
@@ -74,15 +79,13 @@ func (e *ParseError) Error() (s string) {
}
type lex struct {
- token string // text of the token
- tokenUpper string // uppercase text of the token
- length int // length of the token
- err bool // when true, token text has lexer error
- value uint8 // value: zString, _BLANK, etc.
- torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar
- line int // line in the file
- column int // column in the file
- comment string // any comment text seen
+ token string // text of the token
+ err bool // when true, token text has lexer error
+ value uint8 // value: zString, _BLANK, etc.
+ torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar
+ line int // line in the file
+ column int // column in the file
+ comment string // any comment text seen
}
// Token holds the token that are returned when a zone file is parsed.
@@ -102,10 +105,14 @@ type ttlState struct {
}
// NewRR reads the RR contained in the string s. Only the first RR is
-// returned. If s contains no RR, return nil with no error. The class
-// defaults to IN and TTL defaults to 3600. The full zone file syntax
-// like $TTL, $ORIGIN, etc. is supported. All fields of the returned
-// RR are set, except RR.Header().Rdlength which is set to 0.
+// returned. If s contains no records, NewRR will return nil with no
+// error.
+//
+// The class defaults to IN and TTL defaults to 3600. The full zone
+// file syntax like $TTL, $ORIGIN, etc. is supported.
+//
+// All fields of the returned RR are set, except RR.Header().Rdlength
+// which is set to 0.
func NewRR(s string) (RR, error) {
if len(s) > 0 && s[len(s)-1] != '\n' { // We need a closing newline
return ReadRR(strings.NewReader(s+"\n"), "")
@@ -113,28 +120,31 @@ func NewRR(s string) (RR, error) {
return ReadRR(strings.NewReader(s), "")
}
-// ReadRR reads the RR contained in q.
+// ReadRR reads the RR contained in r.
+//
+// The string file is used in error reporting and to resolve relative
+// $INCLUDE directives.
+//
// See NewRR for more documentation.
-func ReadRR(q io.Reader, filename string) (RR, error) {
- defttl := &ttlState{defaultTtl, false}
- r := <-parseZoneHelper(q, ".", filename, defttl, 1)
- if r == nil {
- return nil, nil
- }
-
- if r.Error != nil {
- return nil, r.Error
- }
- return r.RR, nil
+func ReadRR(r io.Reader, file string) (RR, error) {
+ zp := NewZoneParser(r, ".", file)
+ zp.SetDefaultTTL(defaultTtl)
+ zp.SetIncludeAllowed(true)
+ rr, _ := zp.Next()
+ return rr, zp.Err()
}
-// ParseZone reads a RFC 1035 style zonefile from r. It returns *Tokens on the
-// returned channel, each consisting of either a parsed RR and optional comment
-// or a nil RR and an error. The string file is only used
-// in error reporting. The string origin is used as the initial origin, as
-// if the file would start with an $ORIGIN directive.
-// The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are supported.
-// The channel t is closed by ParseZone when the end of r is reached.
+// ParseZone reads a RFC 1035 style zonefile from r. It returns
+// *Tokens on the returned channel, each consisting of either a
+// parsed RR and optional comment or a nil RR and an error. The
+// channel is closed by ParseZone when the end of r is reached.
+//
+// The string file is used in error reporting and to resolve relative
+// $INCLUDE directives. The string origin is used as the initial
+// origin, as if the file would start with an $ORIGIN directive.
+//
+// The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are all
+// supported.
//
// Basic usage pattern when reading from a string (z) containing the
// zone data:
@@ -147,90 +157,246 @@ func ReadRR(q io.Reader, filename string) (RR, error) {
// }
// }
//
-// Comments specified after an RR (and on the same line!) are returned too:
+// Comments specified after an RR (and on the same line!) are
+// returned too:
//
// foo. IN A 10.0.0.1 ; this is a comment
//
-// The text "; this is comment" is returned in Token.Comment. Comments inside the
-// RR are discarded. Comments on a line by themselves are discarded too.
+// The text "; this is comment" is returned in Token.Comment.
+// Comments inside the RR are returned concatenated along with the
+// RR. Comments on a line by themselves are discarded.
+//
+// To prevent memory leaks it is important to always fully drain the
+// returned channel. If an error occurs, it will always be the last
+// Token sent on the channel.
+//
+// Deprecated: New users should prefer the ZoneParser API.
func ParseZone(r io.Reader, origin, file string) chan *Token {
- return parseZoneHelper(r, origin, file, nil, 10000)
-}
-
-func parseZoneHelper(r io.Reader, origin, file string, defttl *ttlState, chansize int) chan *Token {
- t := make(chan *Token, chansize)
- go parseZone(r, origin, file, defttl, t, 0)
+ t := make(chan *Token, 10000)
+ go parseZone(r, origin, file, t)
return t
}
-func parseZone(r io.Reader, origin, f string, defttl *ttlState, t chan *Token, include int) {
- defer func() {
- if include == 0 {
- close(t)
- }
- }()
- s, cancel := scanInit(r)
- c := make(chan lex)
- // Start the lexer
- go zlexer(s, c)
-
- defer func() {
- cancel()
- // zlexer can send up to three tokens, the next one and possibly 2 remainders.
- // Do a non-blocking read.
- _, ok := <-c
- _, ok = <-c
- _, ok = <-c
+func parseZone(r io.Reader, origin, file string, t chan *Token) {
+ defer close(t)
+
+ zp := NewZoneParser(r, origin, file)
+ zp.SetIncludeAllowed(true)
+
+ for rr, ok := zp.Next(); ok; rr, ok = zp.Next() {
+ t <- &Token{RR: rr, Comment: zp.Comment()}
+ }
+
+ if err := zp.Err(); err != nil {
+ pe, ok := err.(*ParseError)
if !ok {
- // too bad
+ pe = &ParseError{file: file, err: err.Error()}
}
- }()
- // 6 possible beginnings of a line, _ is a space
- // 0. zRRTYPE -> all omitted until the rrtype
- // 1. zOwner _ zRrtype -> class/ttl omitted
- // 2. zOwner _ zString _ zRrtype -> class omitted
- // 3. zOwner _ zString _ zClass _ zRrtype -> ttl/class
- // 4. zOwner _ zClass _ zRrtype -> ttl omitted
- // 5. zOwner _ zClass _ zString _ zRrtype -> class/ttl (reversed)
- // After detecting these, we know the zRrtype so we can jump to functions
- // handling the rdata for each of these types.
+ t <- &Token{Error: pe}
+ }
+}
+
+// ZoneParser is a parser for an RFC 1035 style zonefile.
+//
+// Each parsed RR in the zone is returned sequentially from Next. An
+// optional comment can be retrieved with Comment.
+//
+// The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are all
+// supported. Although $INCLUDE is disabled by default.
+//
+// Basic usage pattern when reading from a string (z) containing the
+// zone data:
+//
+// zp := NewZoneParser(strings.NewReader(z), "", "")
+//
+// for rr, ok := zp.Next(); ok; rr, ok = zp.Next() {
+// // Do something with rr
+// }
+//
+// if err := zp.Err(); err != nil {
+// // log.Println(err)
+// }
+//
+// Comments specified after an RR (and on the same line!) are
+// returned too:
+//
+// foo. IN A 10.0.0.1 ; this is a comment
+//
+// The text "; this is comment" is returned from Comment. Comments inside
+// the RR are returned concatenated along with the RR. Comments on a line
+// by themselves are discarded.
+type ZoneParser struct {
+ c *zlexer
+
+ parseErr *ParseError
+
+ origin string
+ file string
+
+ defttl *ttlState
+
+ h RR_Header
+
+ // sub is used to parse $INCLUDE files and $GENERATE directives.
+ // Next, by calling subNext, forwards the resulting RRs from this
+ // sub parser to the calling code.
+ sub *ZoneParser
+ osFile *os.File
+
+ com string
+
+ includeDepth uint8
+
+ includeAllowed bool
+}
+
+// NewZoneParser returns an RFC 1035 style zonefile parser that reads
+// from r.
+//
+// The string file is used in error reporting and to resolve relative
+// $INCLUDE directives. The string origin is used as the initial
+// origin, as if the file would start with an $ORIGIN directive.
+func NewZoneParser(r io.Reader, origin, file string) *ZoneParser {
+ var pe *ParseError
if origin != "" {
origin = Fqdn(origin)
if _, ok := IsDomainName(origin); !ok {
- t <- &Token{Error: &ParseError{f, "bad initial origin name", lex{}}}
- return
+ pe = &ParseError{file, "bad initial origin name", lex{}}
}
}
+ return &ZoneParser{
+ c: newZLexer(r),
+
+ parseErr: pe,
+
+ origin: origin,
+ file: file,
+ }
+}
+
+// SetDefaultTTL sets the parsers default TTL to ttl.
+func (zp *ZoneParser) SetDefaultTTL(ttl uint32) {
+ zp.defttl = &ttlState{ttl, false}
+}
+
+// SetIncludeAllowed controls whether $INCLUDE directives are
+// allowed. $INCLUDE directives are not supported by default.
+//
+// The $INCLUDE directive will open and read from a user controlled
+// file on the system. Even if the file is not a valid zonefile, the
+// contents of the file may be revealed in error messages, such as:
+//
+// /etc/passwd: dns: not a TTL: "root:x:0:0:root:/root:/bin/bash" at line: 1:31
+// /etc/shadow: dns: not a TTL: "root:$6$::0:99999:7:::" at line: 1:125
+func (zp *ZoneParser) SetIncludeAllowed(v bool) {
+ zp.includeAllowed = v
+}
+
+// Err returns the first non-EOF error that was encountered by the
+// ZoneParser.
+func (zp *ZoneParser) Err() error {
+ if zp.parseErr != nil {
+ return zp.parseErr
+ }
+
+ if zp.sub != nil {
+ if err := zp.sub.Err(); err != nil {
+ return err
+ }
+ }
+
+ return zp.c.Err()
+}
+
+func (zp *ZoneParser) setParseError(err string, l lex) (RR, bool) {
+ zp.parseErr = &ParseError{zp.file, err, l}
+ return nil, false
+}
+
+// Comment returns an optional text comment that occurred alongside
+// the RR.
+func (zp *ZoneParser) Comment() string {
+ return zp.com
+}
+
+func (zp *ZoneParser) subNext() (RR, bool) {
+ if rr, ok := zp.sub.Next(); ok {
+ zp.com = zp.sub.com
+ return rr, true
+ }
+
+ if zp.sub.osFile != nil {
+ zp.sub.osFile.Close()
+ zp.sub.osFile = nil
+ }
+
+ if zp.sub.Err() != nil {
+ // We have errors to surface.
+ return nil, false
+ }
+
+ zp.sub = nil
+ return zp.Next()
+}
+
+// Next advances the parser to the next RR in the zonefile and
+// returns the (RR, true). It will return (nil, false) when the
+// parsing stops, either by reaching the end of the input or an
+// error. After Next returns (nil, false), the Err method will return
+// any error that occurred during parsing.
+func (zp *ZoneParser) Next() (RR, bool) {
+ zp.com = ""
+
+ if zp.parseErr != nil {
+ return nil, false
+ }
+ if zp.sub != nil {
+ return zp.subNext()
+ }
+
+ // 6 possible beginnings of a line (_ is a space):
+ //
+ // 0. zRRTYPE -> all omitted until the rrtype
+ // 1. zOwner _ zRrtype -> class/ttl omitted
+ // 2. zOwner _ zString _ zRrtype -> class omitted
+ // 3. zOwner _ zString _ zClass _ zRrtype -> ttl/class
+ // 4. zOwner _ zClass _ zRrtype -> ttl omitted
+ // 5. zOwner _ zClass _ zString _ zRrtype -> class/ttl (reversed)
+ //
+ // After detecting these, we know the zRrtype so we can jump to functions
+ // handling the rdata for each of these types.
+
st := zExpectOwnerDir // initial state
- var h RR_Header
- var prevName string
- for l := range c {
- // Lexer spotted an error already
+ h := &zp.h
+
+ for l, ok := zp.c.Next(); ok; l, ok = zp.c.Next() {
+ // zlexer spotted an error already
if l.err {
- t <- &Token{Error: &ParseError{f, l.token, l}}
- return
+ return zp.setParseError(l.token, l)
}
+
switch st {
case zExpectOwnerDir:
// We can also expect a directive, like $TTL or $ORIGIN
- if defttl != nil {
- h.Ttl = defttl.ttl
+ if zp.defttl != nil {
+ h.Ttl = zp.defttl.ttl
}
+
h.Class = ClassINET
+
switch l.value {
case zNewline:
st = zExpectOwnerDir
case zOwner:
- h.Name = l.token
- name, ok := toAbsoluteName(l.token, origin)
+ name, ok := toAbsoluteName(l.token, zp.origin)
if !ok {
- t <- &Token{Error: &ParseError{f, "bad owner name", l}}
- return
+ return zp.setParseError("bad owner name", l)
}
+
h.Name = name
- prevName = h.Name
+
st = zExpectOwnerBl
case zDirTTL:
st = zExpectDirTTLBl
@@ -241,12 +407,12 @@ func parseZone(r io.Reader, origin, f string, defttl *ttlState, t chan *Token, i
case zDirGenerate:
st = zExpectDirGenerateBl
case zRrtpe:
- h.Name = prevName
h.Rrtype = l.torc
+
st = zExpectRdata
case zClass:
- h.Name = prevName
h.Class = l.torc
+
st = zExpectAnyNoClassBl
case zBlank:
// Discard, can happen when there is nothing on the
@@ -254,297 +420,400 @@ func parseZone(r io.Reader, origin, f string, defttl *ttlState, t chan *Token, i
case zString:
ttl, ok := stringToTTL(l.token)
if !ok {
- t <- &Token{Error: &ParseError{f, "not a TTL", l}}
- return
+ return zp.setParseError("not a TTL", l)
}
+
h.Ttl = ttl
- if defttl == nil || !defttl.isByDirective {
- defttl = &ttlState{ttl, false}
+
+ if zp.defttl == nil || !zp.defttl.isByDirective {
+ zp.defttl = &ttlState{ttl, false}
}
- st = zExpectAnyNoTTLBl
+ st = zExpectAnyNoTTLBl
default:
- t <- &Token{Error: &ParseError{f, "syntax error at beginning", l}}
- return
+ return zp.setParseError("syntax error at beginning", l)
}
case zExpectDirIncludeBl:
if l.value != zBlank {
- t <- &Token{Error: &ParseError{f, "no blank after $INCLUDE-directive", l}}
- return
+ return zp.setParseError("no blank after $INCLUDE-directive", l)
}
+
st = zExpectDirInclude
case zExpectDirInclude:
if l.value != zString {
- t <- &Token{Error: &ParseError{f, "expecting $INCLUDE value, not this...", l}}
- return
+ return zp.setParseError("expecting $INCLUDE value, not this...", l)
}
- neworigin := origin // There may be optionally a new origin set after the filename, if not use current one
- switch l := <-c; l.value {
+
+ neworigin := zp.origin // There may be optionally a new origin set after the filename, if not use current one
+ switch l, _ := zp.c.Next(); l.value {
case zBlank:
- l := <-c
+ l, _ := zp.c.Next()
if l.value == zString {
- name, ok := toAbsoluteName(l.token, origin)
+ name, ok := toAbsoluteName(l.token, zp.origin)
if !ok {
- t <- &Token{Error: &ParseError{f, "bad origin name", l}}
- return
+ return zp.setParseError("bad origin name", l)
}
+
neworigin = name
}
case zNewline, zEOF:
// Ok
default:
- t <- &Token{Error: &ParseError{f, "garbage after $INCLUDE", l}}
- return
+ return zp.setParseError("garbage after $INCLUDE", l)
}
+
+ if !zp.includeAllowed {
+ return zp.setParseError("$INCLUDE directive not allowed", l)
+ }
+ if zp.includeDepth >= maxIncludeDepth {
+ return zp.setParseError("too deeply nested $INCLUDE", l)
+ }
+
// Start with the new file
includePath := l.token
if !filepath.IsAbs(includePath) {
- includePath = filepath.Join(filepath.Dir(f), includePath)
+ includePath = filepath.Join(filepath.Dir(zp.file), includePath)
}
+
r1, e1 := os.Open(includePath)
if e1 != nil {
- msg := fmt.Sprintf("failed to open `%s'", l.token)
+ var as string
if !filepath.IsAbs(l.token) {
- msg += fmt.Sprintf(" as `%s'", includePath)
+ as = fmt.Sprintf(" as `%s'", includePath)
}
- t <- &Token{Error: &ParseError{f, msg, l}}
- return
- }
- if include+1 > 7 {
- t <- &Token{Error: &ParseError{f, "too deeply nested $INCLUDE", l}}
- return
+
+ msg := fmt.Sprintf("failed to open `%s'%s: %v", l.token, as, e1)
+ return zp.setParseError(msg, l)
}
- parseZone(r1, neworigin, includePath, defttl, t, include+1)
- st = zExpectOwnerDir
+
+ zp.sub = NewZoneParser(r1, neworigin, includePath)
+ zp.sub.defttl, zp.sub.includeDepth, zp.sub.osFile = zp.defttl, zp.includeDepth+1, r1
+ zp.sub.SetIncludeAllowed(true)
+ return zp.subNext()
case zExpectDirTTLBl:
if l.value != zBlank {
- t <- &Token{Error: &ParseError{f, "no blank after $TTL-directive", l}}
- return
+ return zp.setParseError("no blank after $TTL-directive", l)
}
+
st = zExpectDirTTL
case zExpectDirTTL:
if l.value != zString {
- t <- &Token{Error: &ParseError{f, "expecting $TTL value, not this...", l}}
- return
+ return zp.setParseError("expecting $TTL value, not this...", l)
}
- if e, _ := slurpRemainder(c, f); e != nil {
- t <- &Token{Error: e}
- return
+
+ if e, _ := slurpRemainder(zp.c, zp.file); e != nil {
+ zp.parseErr = e
+ return nil, false
}
+
ttl, ok := stringToTTL(l.token)
if !ok {
- t <- &Token{Error: &ParseError{f, "expecting $TTL value, not this...", l}}
- return
+ return zp.setParseError("expecting $TTL value, not this...", l)
}
- defttl = &ttlState{ttl, true}
+
+ zp.defttl = &ttlState{ttl, true}
+
st = zExpectOwnerDir
case zExpectDirOriginBl:
if l.value != zBlank {
- t <- &Token{Error: &ParseError{f, "no blank after $ORIGIN-directive", l}}
- return
+ return zp.setParseError("no blank after $ORIGIN-directive", l)
}
+
st = zExpectDirOrigin
case zExpectDirOrigin:
if l.value != zString {
- t <- &Token{Error: &ParseError{f, "expecting $ORIGIN value, not this...", l}}
- return
+ return zp.setParseError("expecting $ORIGIN value, not this...", l)
}
- if e, _ := slurpRemainder(c, f); e != nil {
- t <- &Token{Error: e}
+
+ if e, _ := slurpRemainder(zp.c, zp.file); e != nil {
+ zp.parseErr = e
+ return nil, false
}
- name, ok := toAbsoluteName(l.token, origin)
+
+ name, ok := toAbsoluteName(l.token, zp.origin)
if !ok {
- t <- &Token{Error: &ParseError{f, "bad origin name", l}}
- return
+ return zp.setParseError("bad origin name", l)
}
- origin = name
+
+ zp.origin = name
+
st = zExpectOwnerDir
case zExpectDirGenerateBl:
if l.value != zBlank {
- t <- &Token{Error: &ParseError{f, "no blank after $GENERATE-directive", l}}
- return
+ return zp.setParseError("no blank after $GENERATE-directive", l)
}
+
st = zExpectDirGenerate
case zExpectDirGenerate:
if l.value != zString {
- t <- &Token{Error: &ParseError{f, "expecting $GENERATE value, not this...", l}}
- return
- }
- if errMsg := generate(l, c, t, origin); errMsg != "" {
- t <- &Token{Error: &ParseError{f, errMsg, l}}
- return
+ return zp.setParseError("expecting $GENERATE value, not this...", l)
}
- st = zExpectOwnerDir
+
+ return zp.generate(l)
case zExpectOwnerBl:
if l.value != zBlank {
- t <- &Token{Error: &ParseError{f, "no blank after owner", l}}
- return
+ return zp.setParseError("no blank after owner", l)
}
+
st = zExpectAny
case zExpectAny:
switch l.value {
case zRrtpe:
- if defttl == nil {
- t <- &Token{Error: &ParseError{f, "missing TTL with no previous value", l}}
- return
+ if zp.defttl == nil {
+ return zp.setParseError("missing TTL with no previous value", l)
}
+
h.Rrtype = l.torc
+
st = zExpectRdata
case zClass:
h.Class = l.torc
+
st = zExpectAnyNoClassBl
case zString:
ttl, ok := stringToTTL(l.token)
if !ok {
- t <- &Token{Error: &ParseError{f, "not a TTL", l}}
- return
+ return zp.setParseError("not a TTL", l)
}
+
h.Ttl = ttl
- if defttl == nil || !defttl.isByDirective {
- defttl = &ttlState{ttl, false}
+
+ if zp.defttl == nil || !zp.defttl.isByDirective {
+ zp.defttl = &ttlState{ttl, false}
}
+
st = zExpectAnyNoTTLBl
default:
- t <- &Token{Error: &ParseError{f, "expecting RR type, TTL or class, not this...", l}}
- return
+ return zp.setParseError("expecting RR type, TTL or class, not this...", l)
}
case zExpectAnyNoClassBl:
if l.value != zBlank {
- t <- &Token{Error: &ParseError{f, "no blank before class", l}}
- return
+ return zp.setParseError("no blank before class", l)
}
+
st = zExpectAnyNoClass
case zExpectAnyNoTTLBl:
if l.value != zBlank {
- t <- &Token{Error: &ParseError{f, "no blank before TTL", l}}
- return
+ return zp.setParseError("no blank before TTL", l)
}
+
st = zExpectAnyNoTTL
case zExpectAnyNoTTL:
switch l.value {
case zClass:
h.Class = l.torc
+
st = zExpectRrtypeBl
case zRrtpe:
h.Rrtype = l.torc
+
st = zExpectRdata
default:
- t <- &Token{Error: &ParseError{f, "expecting RR type or class, not this...", l}}
- return
+ return zp.setParseError("expecting RR type or class, not this...", l)
}
case zExpectAnyNoClass:
switch l.value {
case zString:
ttl, ok := stringToTTL(l.token)
if !ok {
- t <- &Token{Error: &ParseError{f, "not a TTL", l}}
- return
+ return zp.setParseError("not a TTL", l)
}
+
h.Ttl = ttl
- if defttl == nil || !defttl.isByDirective {
- defttl = &ttlState{ttl, false}
+
+ if zp.defttl == nil || !zp.defttl.isByDirective {
+ zp.defttl = &ttlState{ttl, false}
}
+
st = zExpectRrtypeBl
case zRrtpe:
h.Rrtype = l.torc
+
st = zExpectRdata
default:
- t <- &Token{Error: &ParseError{f, "expecting RR type or TTL, not this...", l}}
- return
+ return zp.setParseError("expecting RR type or TTL, not this...", l)
}
case zExpectRrtypeBl:
if l.value != zBlank {
- t <- &Token{Error: &ParseError{f, "no blank before RR type", l}}
- return
+ return zp.setParseError("no blank before RR type", l)
}
+
st = zExpectRrtype
case zExpectRrtype:
if l.value != zRrtpe {
- t <- &Token{Error: &ParseError{f, "unknown RR type", l}}
- return
+ return zp.setParseError("unknown RR type", l)
}
+
h.Rrtype = l.torc
+
st = zExpectRdata
case zExpectRdata:
- r, e, c1 := setRR(h, c, origin, f)
+ r, e, c1 := setRR(*h, zp.c, zp.origin, zp.file)
if e != nil {
// If e.lex is nil than we have encounter a unknown RR type
// in that case we substitute our current lex token
if e.lex.token == "" && e.lex.value == 0 {
e.lex = l // Uh, dirty
}
- t <- &Token{Error: e}
- return
+
+ zp.parseErr = e
+ return nil, false
}
- t <- &Token{RR: r, Comment: c1}
- st = zExpectOwnerDir
+
+ zp.com = c1
+ return r, true
}
}
+
// If we get here, we and the h.Rrtype is still zero, we haven't parsed anything, this
// is not an error, because an empty zone file is still a zone file.
+ return nil, false
+}
+
+type zlexer struct {
+ br io.ByteReader
+
+ readErr error
+
+ line int
+ column int
+
+ com string
+
+ l lex
+
+ brace int
+ quote bool
+ space bool
+ commt bool
+ rrtype bool
+ owner bool
+
+ nextL bool
+
+ eol bool // end-of-line
+}
+
+func newZLexer(r io.Reader) *zlexer {
+ br, ok := r.(io.ByteReader)
+ if !ok {
+ br = bufio.NewReaderSize(r, 1024)
+ }
+
+ return &zlexer{
+ br: br,
+
+ line: 1,
+
+ owner: true,
+ }
+}
+
+func (zl *zlexer) Err() error {
+ if zl.readErr == io.EOF {
+ return nil
+ }
+
+ return zl.readErr
}
-// zlexer scans the sourcefile and returns tokens on the channel c.
-func zlexer(s *scan, c chan lex) {
- var l lex
- str := make([]byte, maxTok) // Should be enough for any token
- stri := 0 // Offset in str (0 means empty)
- com := make([]byte, maxTok) // Hold comment text
- comi := 0
- quote := false
- escape := false
- space := false
- commt := false
- rrtype := false
- owner := true
- brace := 0
- x, err := s.tokenText()
- defer close(c)
- for err == nil {
- l.column = s.position.Column
- l.line = s.position.Line
- if stri >= maxTok {
+// readByte returns the next byte from the input
+func (zl *zlexer) readByte() (byte, bool) {
+ if zl.readErr != nil {
+ return 0, false
+ }
+
+ c, err := zl.br.ReadByte()
+ if err != nil {
+ zl.readErr = err
+ return 0, false
+ }
+
+ // delay the newline handling until the next token is delivered,
+ // fixes off-by-one errors when reporting a parse error.
+ if zl.eol {
+ zl.line++
+ zl.column = 0
+ zl.eol = false
+ }
+
+ if c == '\n' {
+ zl.eol = true
+ } else {
+ zl.column++
+ }
+
+ return c, true
+}
+
+func (zl *zlexer) Next() (lex, bool) {
+ l := &zl.l
+ if zl.nextL {
+ zl.nextL = false
+ return *l, true
+ }
+ if l.err {
+ // Parsing errors should be sticky.
+ return lex{value: zEOF}, false
+ }
+
+ var (
+ str [maxTok]byte // Hold string text
+ com [maxTok]byte // Hold comment text
+
+ stri int // Offset in str (0 means empty)
+ comi int // Offset in com (0 means empty)
+
+ escape bool
+ )
+
+ if zl.com != "" {
+ comi = copy(com[:], zl.com)
+ zl.com = ""
+ }
+
+ for x, ok := zl.readByte(); ok; x, ok = zl.readByte() {
+ l.line, l.column = zl.line, zl.column
+ l.comment = ""
+
+ if stri >= len(str) {
l.token = "token length insufficient for parsing"
l.err = true
- c <- l
- return
+ return *l, true
}
- if comi >= maxTok {
+ if comi >= len(com) {
l.token = "comment length insufficient for parsing"
l.err = true
- c <- l
- return
+ return *l, true
}
switch x {
case ' ', '\t':
- if escape {
- escape = false
- str[stri] = x
- stri++
- break
- }
- if quote {
- // Inside quotes this is legal
+ if escape || zl.quote {
+ // Inside quotes or escaped this is legal.
str[stri] = x
stri++
+
+ escape = false
break
}
- if commt {
+
+ if zl.commt {
com[comi] = x
comi++
break
}
+
+ var retL lex
if stri == 0 {
// Space directly in the beginning, handled in the grammar
- } else if owner {
+ } else if zl.owner {
// If we have a string and its the first, make it an owner
l.value = zOwner
l.token = string(str[:stri])
- l.tokenUpper = strings.ToUpper(l.token)
- l.length = stri
+
// escape $... start with a \ not a $, so this will work
- switch l.tokenUpper {
+ switch strings.ToUpper(l.token) {
case "$TTL":
l.value = zDirTTL
case "$ORIGIN":
@@ -554,258 +823,316 @@ func zlexer(s *scan, c chan lex) {
case "$GENERATE":
l.value = zDirGenerate
}
- c <- l
+
+ retL = *l
} else {
l.value = zString
l.token = string(str[:stri])
- l.tokenUpper = strings.ToUpper(l.token)
- l.length = stri
- if !rrtype {
- if t, ok := StringToType[l.tokenUpper]; ok {
+
+ if !zl.rrtype {
+ tokenUpper := strings.ToUpper(l.token)
+ if t, ok := StringToType[tokenUpper]; ok {
l.value = zRrtpe
l.torc = t
- rrtype = true
- } else {
- if strings.HasPrefix(l.tokenUpper, "TYPE") {
- t, ok := typeToInt(l.token)
- if !ok {
- l.token = "unknown RR type"
- l.err = true
- c <- l
- return
- }
- l.value = zRrtpe
- rrtype = true
- l.torc = t
+
+ zl.rrtype = true
+ } else if strings.HasPrefix(tokenUpper, "TYPE") {
+ t, ok := typeToInt(l.token)
+ if !ok {
+ l.token = "unknown RR type"
+ l.err = true
+ return *l, true
}
+
+ l.value = zRrtpe
+ l.torc = t
+
+ zl.rrtype = true
}
- if t, ok := StringToClass[l.tokenUpper]; ok {
+
+ if t, ok := StringToClass[tokenUpper]; ok {
l.value = zClass
l.torc = t
- } else {
- if strings.HasPrefix(l.tokenUpper, "CLASS") {
- t, ok := classToInt(l.token)
- if !ok {
- l.token = "unknown class"
- l.err = true
- c <- l
- return
- }
- l.value = zClass
- l.torc = t
+ } else if strings.HasPrefix(tokenUpper, "CLASS") {
+ t, ok := classToInt(l.token)
+ if !ok {
+ l.token = "unknown class"
+ l.err = true
+ return *l, true
}
+
+ l.value = zClass
+ l.torc = t
}
}
- c <- l
+
+ retL = *l
}
- stri = 0
- if !space && !commt {
+ zl.owner = false
+
+ if !zl.space {
+ zl.space = true
+
l.value = zBlank
l.token = " "
- l.length = 1
- c <- l
+
+ if retL == (lex{}) {
+ return *l, true
+ }
+
+ zl.nextL = true
+ }
+
+ if retL != (lex{}) {
+ return retL, true
}
- owner = false
- space = true
case ';':
- if escape {
- escape = false
+ if escape || zl.quote {
+ // Inside quotes or escaped this is legal.
str[stri] = x
stri++
+
+ escape = false
break
}
- if quote {
- // Inside quotes this is legal
- str[stri] = x
- stri++
- break
+
+ zl.commt = true
+ zl.com = ""
+
+ if comi > 1 {
+ // A newline was previously seen inside a comment that
+ // was inside braces and we delayed adding it until now.
+ com[comi] = ' ' // convert newline to space
+ comi++
}
+
+ com[comi] = ';'
+ comi++
+
if stri > 0 {
+ zl.com = string(com[:comi])
+
l.value = zString
l.token = string(str[:stri])
- l.tokenUpper = strings.ToUpper(l.token)
- l.length = stri
- c <- l
- stri = 0
+ return *l, true
}
- commt = true
- com[comi] = ';'
- comi++
case '\r':
escape = false
- if quote {
+
+ if zl.quote {
str[stri] = x
stri++
}
+
// discard if outside of quotes
case '\n':
escape = false
+
// Escaped newline
- if quote {
+ if zl.quote {
str[stri] = x
stri++
break
}
- // inside quotes this is legal
- if commt {
+
+ if zl.commt {
// Reset a comment
- commt = false
- rrtype = false
- stri = 0
+ zl.commt = false
+ zl.rrtype = false
+
// If not in a brace this ends the comment AND the RR
- if brace == 0 {
- owner = true
- owner = true
+ if zl.brace == 0 {
+ zl.owner = true
+
l.value = zNewline
l.token = "\n"
- l.tokenUpper = l.token
- l.length = 1
l.comment = string(com[:comi])
- c <- l
- l.comment = ""
- comi = 0
- break
+ return *l, true
}
- com[comi] = ' ' // convert newline to space
- comi++
+
+ zl.com = string(com[:comi])
break
}
- if brace == 0 {
+ if zl.brace == 0 {
// If there is previous text, we should output it here
+ var retL lex
if stri != 0 {
l.value = zString
l.token = string(str[:stri])
- l.tokenUpper = strings.ToUpper(l.token)
- l.length = stri
- if !rrtype {
- if t, ok := StringToType[l.tokenUpper]; ok {
+ if !zl.rrtype {
+ tokenUpper := strings.ToUpper(l.token)
+ if t, ok := StringToType[tokenUpper]; ok {
+ zl.rrtype = true
+
l.value = zRrtpe
l.torc = t
- rrtype = true
}
}
- c <- l
+
+ retL = *l
}
+
l.value = zNewline
l.token = "\n"
- l.tokenUpper = l.token
- l.length = 1
- c <- l
- stri = 0
- commt = false
- rrtype = false
- owner = true
- comi = 0
+ l.comment = zl.com
+
+ zl.com = ""
+ zl.rrtype = false
+ zl.owner = true
+
+ if retL != (lex{}) {
+ zl.nextL = true
+ return retL, true
+ }
+
+ return *l, true
}
case '\\':
// comments do not get escaped chars, everything is copied
- if commt {
+ if zl.commt {
com[comi] = x
comi++
break
}
+
// something already escaped must be in string
if escape {
str[stri] = x
stri++
+
escape = false
break
}
+
// something escaped outside of string gets added to string
str[stri] = x
stri++
+
escape = true
case '"':
- if commt {
+ if zl.commt {
com[comi] = x
comi++
break
}
+
if escape {
str[stri] = x
stri++
+
escape = false
break
}
- space = false
+
+ zl.space = false
+
// send previous gathered text and the quote
+ var retL lex
if stri != 0 {
l.value = zString
l.token = string(str[:stri])
- l.tokenUpper = strings.ToUpper(l.token)
- l.length = stri
- c <- l
- stri = 0
+ retL = *l
}
// send quote itself as separate token
l.value = zQuote
l.token = "\""
- l.tokenUpper = l.token
- l.length = 1
- c <- l
- quote = !quote
+
+ zl.quote = !zl.quote
+
+ if retL != (lex{}) {
+ zl.nextL = true
+ return retL, true
+ }
+
+ return *l, true
case '(', ')':
- if commt {
+ if zl.commt {
com[comi] = x
comi++
break
}
- if escape {
+
+ if escape || zl.quote {
+ // Inside quotes or escaped this is legal.
str[stri] = x
stri++
+
escape = false
break
}
- if quote {
- str[stri] = x
- stri++
- break
- }
+
switch x {
case ')':
- brace--
- if brace < 0 {
+ zl.brace--
+
+ if zl.brace < 0 {
l.token = "extra closing brace"
- l.tokenUpper = l.token
l.err = true
- c <- l
- return
+ return *l, true
}
case '(':
- brace++
+ zl.brace++
}
default:
escape = false
- if commt {
+
+ if zl.commt {
com[comi] = x
comi++
break
}
+
str[stri] = x
stri++
- space = false
+
+ zl.space = false
}
- x, err = s.tokenText()
}
+
+ if zl.readErr != nil && zl.readErr != io.EOF {
+ // Don't return any tokens after a read error occurs.
+ return lex{value: zEOF}, false
+ }
+
+ var retL lex
if stri > 0 {
- // Send remainder
- l.token = string(str[:stri])
- l.tokenUpper = strings.ToUpper(l.token)
- l.length = stri
+ // Send remainder of str
l.value = zString
- c <- l
+ l.token = string(str[:stri])
+ retL = *l
+
+ if comi <= 0 {
+ return retL, true
+ }
}
- if brace != 0 {
+
+ if comi > 0 {
+ // Send remainder of com
+ l.value = zNewline
+ l.token = "\n"
+ l.comment = string(com[:comi])
+
+ if retL != (lex{}) {
+ zl.nextL = true
+ return retL, true
+ }
+
+ return *l, true
+ }
+
+ if zl.brace != 0 {
+ l.comment = "" // in case there was left over string and comment
l.token = "unbalanced brace"
- l.tokenUpper = l.token
l.err = true
- c <- l
+ return *l, true
}
+
+ return lex{value: zEOF}, false
}
// Extract the class number from CLASSxx
@@ -966,12 +1293,12 @@ func locCheckEast(token string, longitude uint32) (uint32, bool) {
}
// "Eat" the rest of the "line". Return potential comments
-func slurpRemainder(c chan lex, f string) (*ParseError, string) {
- l := <-c
+func slurpRemainder(c *zlexer, f string) (*ParseError, string) {
+ l, _ := c.Next()
com := ""
switch l.value {
case zBlank:
- l = <-c
+ l, _ = c.Next()
com = l.comment
if l.value != zNewline && l.value != zEOF {
return &ParseError{f, "garbage after rdata", l}, ""
diff --git a/vendor/github.com/miekg/dns/scan_rr.go b/vendor/github.com/miekg/dns/scan_rr.go
index 67f884b0d..935d22c3f 100644
--- a/vendor/github.com/miekg/dns/scan_rr.go
+++ b/vendor/github.com/miekg/dns/scan_rr.go
@@ -11,7 +11,7 @@ type parserFunc struct {
// Func defines the function that parses the tokens and returns the RR
// or an error. The last string contains any comments in the line as
// they returned by the lexer as well.
- Func func(h RR_Header, c chan lex, origin string, file string) (RR, *ParseError, string)
+ Func func(h RR_Header, c *zlexer, origin string, file string) (RR, *ParseError, string)
// Signals if the RR ending is of variable length, like TXT or records
// that have Hexadecimal or Base64 as their last element in the Rdata. Records
// that have a fixed ending or for instance A, AAAA, SOA and etc.
@@ -23,7 +23,7 @@ type parserFunc struct {
// After the rdata there may come a zBlank and then a zNewline
// or immediately a zNewline. If this is not the case we flag
// an *ParseError: garbage after rdata.
-func setRR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setRR(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
parserfunc, ok := typeToparserFunc[h.Rrtype]
if ok {
r, e, cm := parserfunc.Func(h, c, o, f)
@@ -45,9 +45,9 @@ func setRR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
// A remainder of the rdata with embedded spaces, return the parsed string (sans the spaces)
// or an error
-func endingToString(c chan lex, errstr, f string) (string, *ParseError, string) {
+func endingToString(c *zlexer, errstr, f string) (string, *ParseError, string) {
s := ""
- l := <-c // zString
+ l, _ := c.Next() // zString
for l.value != zNewline && l.value != zEOF {
if l.err {
return s, &ParseError{f, errstr, l}, ""
@@ -59,16 +59,16 @@ func endingToString(c chan lex, errstr, f string) (string, *ParseError, string)
default:
return "", &ParseError{f, errstr, l}, ""
}
- l = <-c
+ l, _ = c.Next()
}
return s, nil, l.comment
}
// A remainder of the rdata with embedded spaces, split on unquoted whitespace
// and return the parsed string slice or an error
-func endingToTxtSlice(c chan lex, errstr, f string) ([]string, *ParseError, string) {
+func endingToTxtSlice(c *zlexer, errstr, f string) ([]string, *ParseError, string) {
// Get the remaining data until we see a zNewline
- l := <-c
+ l, _ := c.Next()
if l.err {
return nil, &ParseError{f, errstr, l}, ""
}
@@ -117,7 +117,7 @@ func endingToTxtSlice(c chan lex, errstr, f string) ([]string, *ParseError, stri
default:
return nil, &ParseError{f, errstr, l}, ""
}
- l = <-c
+ l, _ = c.Next()
}
if quote {
return nil, &ParseError{f, errstr, l}, ""
@@ -125,12 +125,12 @@ func endingToTxtSlice(c chan lex, errstr, f string) ([]string, *ParseError, stri
return s, nil, l.comment
}
-func setA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setA(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(A)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -141,12 +141,12 @@ func setA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setAAAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setAAAA(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(AAAA)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -157,13 +157,13 @@ func setAAAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setNS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setNS(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(NS)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
rr.Ns = l.token
- if l.length == 0 { // dynamic update rr.
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -175,13 +175,13 @@ func setNS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setPTR(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(PTR)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
rr.Ptr = l.token
- if l.length == 0 { // dynamic update rr.
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -193,13 +193,13 @@ func setPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setNSAPPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setNSAPPTR(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(NSAPPTR)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
rr.Ptr = l.token
- if l.length == 0 { // dynamic update rr.
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -211,13 +211,13 @@ func setNSAPPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string)
return rr, nil, ""
}
-func setRP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setRP(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(RP)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
rr.Mbox = l.token
- if l.length == 0 { // dynamic update rr.
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -227,8 +227,8 @@ func setRP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Mbox = mbox
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
rr.Txt = l.token
txt, txtOk := toAbsoluteName(l.token, o)
@@ -240,13 +240,13 @@ func setRP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setMR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setMR(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(MR)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
rr.Mr = l.token
- if l.length == 0 { // dynamic update rr.
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -258,13 +258,13 @@ func setMR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setMB(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setMB(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(MB)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
rr.Mb = l.token
- if l.length == 0 { // dynamic update rr.
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -276,13 +276,13 @@ func setMB(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setMG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setMG(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(MG)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
rr.Mg = l.token
- if l.length == 0 { // dynamic update rr.
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -294,7 +294,7 @@ func setMG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setHINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setHINFO(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(HINFO)
rr.Hdr = h
@@ -320,13 +320,13 @@ func setHINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setMINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setMINFO(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(MINFO)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
rr.Rmail = l.token
- if l.length == 0 { // dynamic update rr.
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -336,8 +336,8 @@ func setMINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Rmail = rmail
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
rr.Email = l.token
email, emailOk := toAbsoluteName(l.token, o)
@@ -349,13 +349,13 @@ func setMINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setMF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setMF(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(MF)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
rr.Mf = l.token
- if l.length == 0 { // dynamic update rr.
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -367,13 +367,13 @@ func setMF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setMD(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setMD(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(MD)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
rr.Md = l.token
- if l.length == 0 { // dynamic update rr.
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -385,12 +385,12 @@ func setMD(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setMX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setMX(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(MX)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -400,8 +400,8 @@ func setMX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Preference = uint16(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
rr.Mx = l.token
name, nameOk := toAbsoluteName(l.token, o)
@@ -413,12 +413,12 @@ func setMX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setRT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setRT(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(RT)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -428,8 +428,8 @@ func setRT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Preference = uint16(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
rr.Host = l.token
name, nameOk := toAbsoluteName(l.token, o)
@@ -441,12 +441,12 @@ func setRT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setAFSDB(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setAFSDB(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(AFSDB)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -456,8 +456,8 @@ func setAFSDB(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Subtype = uint16(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
rr.Hostname = l.token
name, nameOk := toAbsoluteName(l.token, o)
@@ -468,12 +468,12 @@ func setAFSDB(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setX25(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setX25(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(X25)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -484,12 +484,12 @@ func setX25(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setKX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setKX(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(KX)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -499,8 +499,8 @@ func setKX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Preference = uint16(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
rr.Exchanger = l.token
name, nameOk := toAbsoluteName(l.token, o)
@@ -511,13 +511,13 @@ func setKX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setCNAME(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setCNAME(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(CNAME)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
rr.Target = l.token
- if l.length == 0 { // dynamic update rr.
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -529,13 +529,13 @@ func setCNAME(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setDNAME(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setDNAME(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(DNAME)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
rr.Target = l.token
- if l.length == 0 { // dynamic update rr.
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -547,13 +547,13 @@ func setDNAME(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setSOA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setSOA(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(SOA)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
rr.Ns = l.token
- if l.length == 0 { // dynamic update rr.
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -563,8 +563,8 @@ func setSOA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Ns = ns
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
rr.Mbox = l.token
mbox, mboxOk := toAbsoluteName(l.token, o)
@@ -573,14 +573,14 @@ func setSOA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Mbox = mbox
- <-c // zBlank
+ c.Next() // zBlank
var (
v uint32
ok bool
)
for i := 0; i < 5; i++ {
- l = <-c
+ l, _ = c.Next()
if l.err {
return nil, &ParseError{f, "bad SOA zone parameter", l}, ""
}
@@ -600,16 +600,16 @@ func setSOA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
switch i {
case 0:
rr.Serial = v
- <-c // zBlank
+ c.Next() // zBlank
case 1:
rr.Refresh = v
- <-c // zBlank
+ c.Next() // zBlank
case 2:
rr.Retry = v
- <-c // zBlank
+ c.Next() // zBlank
case 3:
rr.Expire = v
- <-c // zBlank
+ c.Next() // zBlank
case 4:
rr.Minttl = v
}
@@ -617,12 +617,12 @@ func setSOA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setSRV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setSRV(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(SRV)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -632,24 +632,24 @@ func setSRV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Priority = uint16(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
i, e = strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err {
return nil, &ParseError{f, "bad SRV Weight", l}, ""
}
rr.Weight = uint16(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
i, e = strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err {
return nil, &ParseError{f, "bad SRV Port", l}, ""
}
rr.Port = uint16(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
rr.Target = l.token
name, nameOk := toAbsoluteName(l.token, o)
@@ -660,12 +660,12 @@ func setSRV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setNAPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setNAPTR(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(NAPTR)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -675,8 +675,8 @@ func setNAPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Order = uint16(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
i, e = strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err {
return nil, &ParseError{f, "bad NAPTR Preference", l}, ""
@@ -684,15 +684,15 @@ func setNAPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr.Preference = uint16(i)
// Flags
- <-c // zBlank
- l = <-c // _QUOTE
+ c.Next() // zBlank
+ l, _ = c.Next() // _QUOTE
if l.value != zQuote {
return nil, &ParseError{f, "bad NAPTR Flags", l}, ""
}
- l = <-c // Either String or Quote
+ l, _ = c.Next() // Either String or Quote
if l.value == zString {
rr.Flags = l.token
- l = <-c // _QUOTE
+ l, _ = c.Next() // _QUOTE
if l.value != zQuote {
return nil, &ParseError{f, "bad NAPTR Flags", l}, ""
}
@@ -703,15 +703,15 @@ func setNAPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
// Service
- <-c // zBlank
- l = <-c // _QUOTE
+ c.Next() // zBlank
+ l, _ = c.Next() // _QUOTE
if l.value != zQuote {
return nil, &ParseError{f, "bad NAPTR Service", l}, ""
}
- l = <-c // Either String or Quote
+ l, _ = c.Next() // Either String or Quote
if l.value == zString {
rr.Service = l.token
- l = <-c // _QUOTE
+ l, _ = c.Next() // _QUOTE
if l.value != zQuote {
return nil, &ParseError{f, "bad NAPTR Service", l}, ""
}
@@ -722,15 +722,15 @@ func setNAPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
// Regexp
- <-c // zBlank
- l = <-c // _QUOTE
+ c.Next() // zBlank
+ l, _ = c.Next() // _QUOTE
if l.value != zQuote {
return nil, &ParseError{f, "bad NAPTR Regexp", l}, ""
}
- l = <-c // Either String or Quote
+ l, _ = c.Next() // Either String or Quote
if l.value == zString {
rr.Regexp = l.token
- l = <-c // _QUOTE
+ l, _ = c.Next() // _QUOTE
if l.value != zQuote {
return nil, &ParseError{f, "bad NAPTR Regexp", l}, ""
}
@@ -741,8 +741,8 @@ func setNAPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
// After quote no space??
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
rr.Replacement = l.token
name, nameOk := toAbsoluteName(l.token, o)
@@ -753,13 +753,13 @@ func setNAPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setTALINK(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setTALINK(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(TALINK)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
rr.PreviousName = l.token
- if l.length == 0 { // dynamic update rr.
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -769,8 +769,8 @@ func setTALINK(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.PreviousName = previousName
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
rr.NextName = l.token
nextName, nextNameOk := toAbsoluteName(l.token, o)
@@ -782,7 +782,7 @@ func setTALINK(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setLOC(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(LOC)
rr.Hdr = h
// Non zero defaults for LOC record, see RFC 1876, Section 3.
@@ -792,8 +792,8 @@ func setLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
ok := false
// North
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
i, e := strconv.ParseUint(l.token, 10, 32)
@@ -802,9 +802,9 @@ func setLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Latitude = 1000 * 60 * 60 * uint32(i)
- <-c // zBlank
+ c.Next() // zBlank
// Either number, 'N' or 'S'
- l = <-c
+ l, _ = c.Next()
if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
goto East
}
@@ -814,16 +814,16 @@ func setLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Latitude += 1000 * 60 * uint32(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
if i, e := strconv.ParseFloat(l.token, 32); e != nil || l.err {
return nil, &ParseError{f, "bad LOC Latitude seconds", l}, ""
} else {
rr.Latitude += uint32(1000 * i)
}
- <-c // zBlank
+ c.Next() // zBlank
// Either number, 'N' or 'S'
- l = <-c
+ l, _ = c.Next()
if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
goto East
}
@@ -832,16 +832,16 @@ func setLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
East:
// East
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err {
return nil, &ParseError{f, "bad LOC Longitude", l}, ""
} else {
rr.Longitude = 1000 * 60 * 60 * uint32(i)
}
- <-c // zBlank
+ c.Next() // zBlank
// Either number, 'E' or 'W'
- l = <-c
+ l, _ = c.Next()
if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
goto Altitude
}
@@ -850,16 +850,16 @@ East:
} else {
rr.Longitude += 1000 * 60 * uint32(i)
}
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
if i, e := strconv.ParseFloat(l.token, 32); e != nil || l.err {
return nil, &ParseError{f, "bad LOC Longitude seconds", l}, ""
} else {
rr.Longitude += uint32(1000 * i)
}
- <-c // zBlank
+ c.Next() // zBlank
// Either number, 'E' or 'W'
- l = <-c
+ l, _ = c.Next()
if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
goto Altitude
}
@@ -867,9 +867,9 @@ East:
return nil, &ParseError{f, "bad LOC Longitude East/West", l}, ""
Altitude:
- <-c // zBlank
- l = <-c
- if l.length == 0 || l.err {
+ c.Next() // zBlank
+ l, _ = c.Next()
+ if len(l.token) == 0 || l.err {
return nil, &ParseError{f, "bad LOC Altitude", l}, ""
}
if l.token[len(l.token)-1] == 'M' || l.token[len(l.token)-1] == 'm' {
@@ -882,7 +882,7 @@ Altitude:
}
// And now optionally the other values
- l = <-c
+ l, _ = c.Next()
count := 0
for l.value != zNewline && l.value != zEOF {
switch l.value {
@@ -913,18 +913,18 @@ Altitude:
default:
return nil, &ParseError{f, "bad LOC Size, HorizPre or VertPre", l}, ""
}
- l = <-c
+ l, _ = c.Next()
}
return rr, nil, ""
}
-func setHIP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setHIP(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(HIP)
rr.Hdr = h
// HitLength is not represented
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, l.comment
}
@@ -934,24 +934,24 @@ func setHIP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.PublicKeyAlgorithm = uint8(i)
- <-c // zBlank
- l = <-c // zString
- if l.length == 0 || l.err {
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ if len(l.token) == 0 || l.err {
return nil, &ParseError{f, "bad HIP Hit", l}, ""
}
rr.Hit = l.token // This can not contain spaces, see RFC 5205 Section 6.
rr.HitLength = uint8(len(rr.Hit)) / 2
- <-c // zBlank
- l = <-c // zString
- if l.length == 0 || l.err {
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
+ if len(l.token) == 0 || l.err {
return nil, &ParseError{f, "bad HIP PublicKey", l}, ""
}
rr.PublicKey = l.token // This cannot contain spaces
rr.PublicKeyLength = uint16(base64.StdEncoding.DecodedLen(len(rr.PublicKey)))
// RendezvousServers (if any)
- l = <-c
+ l, _ = c.Next()
var xs []string
for l.value != zNewline && l.value != zEOF {
switch l.value {
@@ -966,18 +966,18 @@ func setHIP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
default:
return nil, &ParseError{f, "bad HIP RendezvousServers", l}, ""
}
- l = <-c
+ l, _ = c.Next()
}
rr.RendezvousServers = xs
return rr, nil, l.comment
}
-func setCERT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setCERT(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(CERT)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, l.comment
}
@@ -988,15 +988,15 @@ func setCERT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
} else {
rr.Type = uint16(i)
}
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err {
return nil, &ParseError{f, "bad CERT KeyTag", l}, ""
}
rr.KeyTag = uint16(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
if v, ok := StringToAlgorithm[l.token]; ok {
rr.Algorithm = v
} else if i, e := strconv.ParseUint(l.token, 10, 8); e != nil {
@@ -1012,7 +1012,7 @@ func setCERT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, c1
}
-func setOPENPGPKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setOPENPGPKEY(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(OPENPGPKEY)
rr.Hdr = h
@@ -1024,12 +1024,12 @@ func setOPENPGPKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, strin
return rr, nil, c1
}
-func setCSYNC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setCSYNC(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(CSYNC)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, l.comment
}
j, e := strconv.ParseUint(l.token, 10, 32)
@@ -1039,9 +1039,9 @@ func setCSYNC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Serial = uint32(j)
- <-c // zBlank
+ c.Next() // zBlank
- l = <-c
+ l, _ = c.Next()
j, e = strconv.ParseUint(l.token, 10, 16)
if e != nil {
// Serial must be a number
@@ -1054,14 +1054,15 @@ func setCSYNC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
k uint16
ok bool
)
- l = <-c
+ l, _ = c.Next()
for l.value != zNewline && l.value != zEOF {
switch l.value {
case zBlank:
// Ok
case zString:
- if k, ok = StringToType[l.tokenUpper]; !ok {
- if k, ok = typeToInt(l.tokenUpper); !ok {
+ tokenUpper := strings.ToUpper(l.token)
+ if k, ok = StringToType[tokenUpper]; !ok {
+ if k, ok = typeToInt(l.token); !ok {
return nil, &ParseError{f, "bad CSYNC TypeBitMap", l}, ""
}
}
@@ -1069,12 +1070,12 @@ func setCSYNC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
default:
return nil, &ParseError{f, "bad CSYNC TypeBitMap", l}, ""
}
- l = <-c
+ l, _ = c.Next()
}
return rr, nil, l.comment
}
-func setSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setSIG(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
r, e, s := setRRSIG(h, c, o, f)
if r != nil {
return &SIG{*r.(*RRSIG)}, e, s
@@ -1082,18 +1083,19 @@ func setSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return nil, e, s
}
-func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setRRSIG(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(RRSIG)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, l.comment
}
- if t, ok := StringToType[l.tokenUpper]; !ok {
- if strings.HasPrefix(l.tokenUpper, "TYPE") {
- t, ok = typeToInt(l.tokenUpper)
+ tokenUpper := strings.ToUpper(l.token)
+ if t, ok := StringToType[tokenUpper]; !ok {
+ if strings.HasPrefix(tokenUpper, "TYPE") {
+ t, ok = typeToInt(l.token)
if !ok {
return nil, &ParseError{f, "bad RRSIG Typecovered", l}, ""
}
@@ -1105,32 +1107,32 @@ func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr.TypeCovered = t
}
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
i, err := strconv.ParseUint(l.token, 10, 8)
if err != nil || l.err {
return nil, &ParseError{f, "bad RRSIG Algorithm", l}, ""
}
rr.Algorithm = uint8(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
i, err = strconv.ParseUint(l.token, 10, 8)
if err != nil || l.err {
return nil, &ParseError{f, "bad RRSIG Labels", l}, ""
}
rr.Labels = uint8(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
i, err = strconv.ParseUint(l.token, 10, 32)
if err != nil || l.err {
return nil, &ParseError{f, "bad RRSIG OrigTtl", l}, ""
}
rr.OrigTtl = uint32(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
if i, err := StringToTime(l.token); err != nil {
// Try to see if all numeric and use it as epoch
if i, err := strconv.ParseInt(l.token, 10, 64); err == nil {
@@ -1143,8 +1145,8 @@ func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr.Expiration = i
}
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
if i, err := StringToTime(l.token); err != nil {
if i, err := strconv.ParseInt(l.token, 10, 64); err == nil {
rr.Inception = uint32(i)
@@ -1155,16 +1157,16 @@ func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr.Inception = i
}
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
i, err = strconv.ParseUint(l.token, 10, 16)
if err != nil || l.err {
return nil, &ParseError{f, "bad RRSIG KeyTag", l}, ""
}
rr.KeyTag = uint16(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
rr.SignerName = l.token
name, nameOk := toAbsoluteName(l.token, o)
if l.err || !nameOk {
@@ -1181,13 +1183,13 @@ func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, c1
}
-func setNSEC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setNSEC(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(NSEC)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
rr.NextDomain = l.token
- if l.length == 0 { // dynamic update rr.
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, l.comment
}
@@ -1202,14 +1204,15 @@ func setNSEC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
k uint16
ok bool
)
- l = <-c
+ l, _ = c.Next()
for l.value != zNewline && l.value != zEOF {
switch l.value {
case zBlank:
// Ok
case zString:
- if k, ok = StringToType[l.tokenUpper]; !ok {
- if k, ok = typeToInt(l.tokenUpper); !ok {
+ tokenUpper := strings.ToUpper(l.token)
+ if k, ok = StringToType[tokenUpper]; !ok {
+ if k, ok = typeToInt(l.token); !ok {
return nil, &ParseError{f, "bad NSEC TypeBitMap", l}, ""
}
}
@@ -1217,17 +1220,17 @@ func setNSEC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
default:
return nil, &ParseError{f, "bad NSEC TypeBitMap", l}, ""
}
- l = <-c
+ l, _ = c.Next()
}
return rr, nil, l.comment
}
-func setNSEC3(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setNSEC3(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(NSEC3)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, l.comment
}
@@ -1236,22 +1239,22 @@ func setNSEC3(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return nil, &ParseError{f, "bad NSEC3 Hash", l}, ""
}
rr.Hash = uint8(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err {
return nil, &ParseError{f, "bad NSEC3 Flags", l}, ""
}
rr.Flags = uint8(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
i, e = strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err {
return nil, &ParseError{f, "bad NSEC3 Iterations", l}, ""
}
rr.Iterations = uint16(i)
- <-c
- l = <-c
+ c.Next()
+ l, _ = c.Next()
if len(l.token) == 0 || l.err {
return nil, &ParseError{f, "bad NSEC3 Salt", l}, ""
}
@@ -1260,8 +1263,8 @@ func setNSEC3(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr.Salt = l.token
}
- <-c
- l = <-c
+ c.Next()
+ l, _ = c.Next()
if len(l.token) == 0 || l.err {
return nil, &ParseError{f, "bad NSEC3 NextDomain", l}, ""
}
@@ -1273,14 +1276,15 @@ func setNSEC3(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
k uint16
ok bool
)
- l = <-c
+ l, _ = c.Next()
for l.value != zNewline && l.value != zEOF {
switch l.value {
case zBlank:
// Ok
case zString:
- if k, ok = StringToType[l.tokenUpper]; !ok {
- if k, ok = typeToInt(l.tokenUpper); !ok {
+ tokenUpper := strings.ToUpper(l.token)
+ if k, ok = StringToType[tokenUpper]; !ok {
+ if k, ok = typeToInt(l.token); !ok {
return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, ""
}
}
@@ -1288,17 +1292,17 @@ func setNSEC3(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
default:
return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, ""
}
- l = <-c
+ l, _ = c.Next()
}
return rr, nil, l.comment
}
-func setNSEC3PARAM(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setNSEC3PARAM(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(NSEC3PARAM)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -1307,22 +1311,22 @@ func setNSEC3PARAM(h RR_Header, c chan lex, o, f string) (RR, *ParseError, strin
return nil, &ParseError{f, "bad NSEC3PARAM Hash", l}, ""
}
rr.Hash = uint8(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err {
return nil, &ParseError{f, "bad NSEC3PARAM Flags", l}, ""
}
rr.Flags = uint8(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
i, e = strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err {
return nil, &ParseError{f, "bad NSEC3PARAM Iterations", l}, ""
}
rr.Iterations = uint16(i)
- <-c
- l = <-c
+ c.Next()
+ l, _ = c.Next()
if l.token != "-" {
rr.SaltLength = uint8(len(l.token))
rr.Salt = l.token
@@ -1330,16 +1334,16 @@ func setNSEC3PARAM(h RR_Header, c chan lex, o, f string) (RR, *ParseError, strin
return rr, nil, ""
}
-func setEUI48(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setEUI48(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(EUI48)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
- if l.length != 17 || l.err {
+ if len(l.token) != 17 || l.err {
return nil, &ParseError{f, "bad EUI48 Address", l}, ""
}
addr := make([]byte, 12)
@@ -1363,16 +1367,16 @@ func setEUI48(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setEUI64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setEUI64(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(EUI64)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
- if l.length != 23 || l.err {
+ if len(l.token) != 23 || l.err {
return nil, &ParseError{f, "bad EUI64 Address", l}, ""
}
addr := make([]byte, 16)
@@ -1396,12 +1400,12 @@ func setEUI64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setSSHFP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setSSHFP(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(SSHFP)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -1410,14 +1414,14 @@ func setSSHFP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return nil, &ParseError{f, "bad SSHFP Algorithm", l}, ""
}
rr.Algorithm = uint8(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err {
return nil, &ParseError{f, "bad SSHFP Type", l}, ""
}
rr.Type = uint8(i)
- <-c // zBlank
+ c.Next() // zBlank
s, e1, c1 := endingToString(c, "bad SSHFP Fingerprint", f)
if e1 != nil {
return nil, e1, c1
@@ -1426,12 +1430,12 @@ func setSSHFP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setDNSKEYs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string) {
+func setDNSKEYs(h RR_Header, c *zlexer, o, f, typ string) (RR, *ParseError, string) {
rr := new(DNSKEY)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, l.comment
}
@@ -1440,15 +1444,15 @@ func setDNSKEYs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, str
return nil, &ParseError{f, "bad " + typ + " Flags", l}, ""
}
rr.Flags = uint16(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err {
return nil, &ParseError{f, "bad " + typ + " Protocol", l}, ""
}
rr.Protocol = uint8(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err {
return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, ""
@@ -1462,7 +1466,7 @@ func setDNSKEYs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, str
return rr, nil, c1
}
-func setKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setKEY(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
r, e, s := setDNSKEYs(h, c, o, f, "KEY")
if r != nil {
return &KEY{*r.(*DNSKEY)}, e, s
@@ -1470,12 +1474,12 @@ func setKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return nil, e, s
}
-func setDNSKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setDNSKEY(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
r, e, s := setDNSKEYs(h, c, o, f, "DNSKEY")
return r, e, s
}
-func setCDNSKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setCDNSKEY(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
r, e, s := setDNSKEYs(h, c, o, f, "CDNSKEY")
if r != nil {
return &CDNSKEY{*r.(*DNSKEY)}, e, s
@@ -1483,12 +1487,12 @@ func setCDNSKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string)
return nil, e, s
}
-func setRKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setRKEY(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(RKEY)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, l.comment
}
@@ -1497,15 +1501,15 @@ func setRKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return nil, &ParseError{f, "bad RKEY Flags", l}, ""
}
rr.Flags = uint16(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err {
return nil, &ParseError{f, "bad RKEY Protocol", l}, ""
}
rr.Protocol = uint8(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err {
return nil, &ParseError{f, "bad RKEY Algorithm", l}, ""
@@ -1519,7 +1523,7 @@ func setRKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, c1
}
-func setEID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setEID(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(EID)
rr.Hdr = h
s, e, c1 := endingToString(c, "bad EID Endpoint", f)
@@ -1530,7 +1534,7 @@ func setEID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, c1
}
-func setNIMLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setNIMLOC(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(NIMLOC)
rr.Hdr = h
s, e, c1 := endingToString(c, "bad NIMLOC Locator", f)
@@ -1541,12 +1545,12 @@ func setNIMLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, c1
}
-func setGPOS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setGPOS(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(GPOS)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -1555,15 +1559,15 @@ func setGPOS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return nil, &ParseError{f, "bad GPOS Longitude", l}, ""
}
rr.Longitude = l.token
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
_, e = strconv.ParseFloat(l.token, 64)
if e != nil || l.err {
return nil, &ParseError{f, "bad GPOS Latitude", l}, ""
}
rr.Latitude = l.token
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
_, e = strconv.ParseFloat(l.token, 64)
if e != nil || l.err {
return nil, &ParseError{f, "bad GPOS Altitude", l}, ""
@@ -1572,12 +1576,12 @@ func setGPOS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setDSs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string) {
+func setDSs(h RR_Header, c *zlexer, o, f, typ string) (RR, *ParseError, string) {
rr := new(DS)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, l.comment
}
@@ -1586,10 +1590,11 @@ func setDSs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string)
return nil, &ParseError{f, "bad " + typ + " KeyTag", l}, ""
}
rr.KeyTag = uint16(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
if i, e = strconv.ParseUint(l.token, 10, 8); e != nil {
- i, ok := StringToAlgorithm[l.tokenUpper]
+ tokenUpper := strings.ToUpper(l.token)
+ i, ok := StringToAlgorithm[tokenUpper]
if !ok || l.err {
return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, ""
}
@@ -1597,8 +1602,8 @@ func setDSs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string)
} else {
rr.Algorithm = uint8(i)
}
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err {
return nil, &ParseError{f, "bad " + typ + " DigestType", l}, ""
@@ -1612,12 +1617,12 @@ func setDSs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string)
return rr, nil, c1
}
-func setDS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setDS(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
r, e, s := setDSs(h, c, o, f, "DS")
return r, e, s
}
-func setDLV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setDLV(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
r, e, s := setDSs(h, c, o, f, "DLV")
if r != nil {
return &DLV{*r.(*DS)}, e, s
@@ -1625,7 +1630,7 @@ func setDLV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return nil, e, s
}
-func setCDS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setCDS(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
r, e, s := setDSs(h, c, o, f, "CDS")
if r != nil {
return &CDS{*r.(*DS)}, e, s
@@ -1633,12 +1638,12 @@ func setCDS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return nil, e, s
}
-func setTA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setTA(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(TA)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, l.comment
}
@@ -1647,10 +1652,11 @@ func setTA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return nil, &ParseError{f, "bad TA KeyTag", l}, ""
}
rr.KeyTag = uint16(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
if i, e := strconv.ParseUint(l.token, 10, 8); e != nil {
- i, ok := StringToAlgorithm[l.tokenUpper]
+ tokenUpper := strings.ToUpper(l.token)
+ i, ok := StringToAlgorithm[tokenUpper]
if !ok || l.err {
return nil, &ParseError{f, "bad TA Algorithm", l}, ""
}
@@ -1658,8 +1664,8 @@ func setTA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
} else {
rr.Algorithm = uint8(i)
}
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err {
return nil, &ParseError{f, "bad TA DigestType", l}, ""
@@ -1673,12 +1679,12 @@ func setTA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, c1
}
-func setTLSA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setTLSA(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(TLSA)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, l.comment
}
@@ -1687,15 +1693,15 @@ func setTLSA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return nil, &ParseError{f, "bad TLSA Usage", l}, ""
}
rr.Usage = uint8(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err {
return nil, &ParseError{f, "bad TLSA Selector", l}, ""
}
rr.Selector = uint8(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err {
return nil, &ParseError{f, "bad TLSA MatchingType", l}, ""
@@ -1710,12 +1716,12 @@ func setTLSA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, c1
}
-func setSMIMEA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setSMIMEA(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(SMIMEA)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, l.comment
}
@@ -1724,15 +1730,15 @@ func setSMIMEA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return nil, &ParseError{f, "bad SMIMEA Usage", l}, ""
}
rr.Usage = uint8(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err {
return nil, &ParseError{f, "bad SMIMEA Selector", l}, ""
}
rr.Selector = uint8(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err {
return nil, &ParseError{f, "bad SMIMEA MatchingType", l}, ""
@@ -1747,17 +1753,17 @@ func setSMIMEA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, c1
}
-func setRFC3597(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setRFC3597(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(RFC3597)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
if l.token != "\\#" {
return nil, &ParseError{f, "bad RFC3597 Rdata", l}, ""
}
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
rdlength, e := strconv.Atoi(l.token)
if e != nil || l.err {
return nil, &ParseError{f, "bad RFC3597 Rdata ", l}, ""
@@ -1774,7 +1780,7 @@ func setRFC3597(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string)
return rr, nil, c1
}
-func setSPF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setSPF(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(SPF)
rr.Hdr = h
@@ -1786,7 +1792,7 @@ func setSPF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, c1
}
-func setAVC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setAVC(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(AVC)
rr.Hdr = h
@@ -1798,7 +1804,7 @@ func setAVC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, c1
}
-func setTXT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setTXT(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(TXT)
rr.Hdr = h
@@ -1812,7 +1818,7 @@ func setTXT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
// identical to setTXT
-func setNINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setNINFO(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(NINFO)
rr.Hdr = h
@@ -1824,12 +1830,12 @@ func setNINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, c1
}
-func setURI(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setURI(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(URI)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -1838,15 +1844,15 @@ func setURI(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return nil, &ParseError{f, "bad URI Priority", l}, ""
}
rr.Priority = uint16(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
i, e = strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err {
return nil, &ParseError{f, "bad URI Weight", l}, ""
}
rr.Weight = uint16(i)
- <-c // zBlank
+ c.Next() // zBlank
s, err, c1 := endingToTxtSlice(c, "bad URI Target", f)
if err != nil {
return nil, err, ""
@@ -1858,7 +1864,7 @@ func setURI(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, c1
}
-func setDHCID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setDHCID(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
// awesome record to parse!
rr := new(DHCID)
rr.Hdr = h
@@ -1871,12 +1877,12 @@ func setDHCID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, c1
}
-func setNID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setNID(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(NID)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -1885,8 +1891,8 @@ func setNID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return nil, &ParseError{f, "bad NID Preference", l}, ""
}
rr.Preference = uint16(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
u, err := stringToNodeID(l)
if err != nil || l.err {
return nil, err, ""
@@ -1895,12 +1901,12 @@ func setNID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setL32(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setL32(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(L32)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -1909,8 +1915,8 @@ func setL32(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return nil, &ParseError{f, "bad L32 Preference", l}, ""
}
rr.Preference = uint16(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
rr.Locator32 = net.ParseIP(l.token)
if rr.Locator32 == nil || l.err {
return nil, &ParseError{f, "bad L32 Locator", l}, ""
@@ -1918,12 +1924,12 @@ func setL32(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setLP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setLP(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(LP)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -1933,8 +1939,8 @@ func setLP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Preference = uint16(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
rr.Fqdn = l.token
name, nameOk := toAbsoluteName(l.token, o)
if l.err || !nameOk {
@@ -1945,12 +1951,12 @@ func setLP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setL64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setL64(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(L64)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -1959,8 +1965,8 @@ func setL64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return nil, &ParseError{f, "bad L64 Preference", l}, ""
}
rr.Preference = uint16(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
u, err := stringToNodeID(l)
if err != nil || l.err {
return nil, err, ""
@@ -1969,12 +1975,12 @@ func setL64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setUID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setUID(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(UID)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -1986,12 +1992,12 @@ func setUID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setGID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setGID(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(GID)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -2003,7 +2009,7 @@ func setGID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setUINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setUINFO(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(UINFO)
rr.Hdr = h
@@ -2018,12 +2024,12 @@ func setUINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, c1
}
-func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setPX(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(PX)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, ""
}
@@ -2033,8 +2039,8 @@ func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Preference = uint16(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
rr.Map822 = l.token
map822, map822Ok := toAbsoluteName(l.token, o)
if l.err || !map822Ok {
@@ -2042,8 +2048,8 @@ func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Map822 = map822
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
rr.Mapx400 = l.token
mapx400, mapx400Ok := toAbsoluteName(l.token, o)
if l.err || !mapx400Ok {
@@ -2054,12 +2060,12 @@ func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
-func setCAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setCAA(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(CAA)
rr.Hdr = h
- l := <-c
- if l.length == 0 { // dynamic update rr.
+ l, _ := c.Next()
+ if len(l.token) == 0 { // dynamic update rr.
return rr, nil, l.comment
}
@@ -2069,14 +2075,14 @@ func setCAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
}
rr.Flag = uint8(i)
- <-c // zBlank
- l = <-c // zString
+ c.Next() // zBlank
+ l, _ = c.Next() // zString
if l.value != zString {
return nil, &ParseError{f, "bad CAA Tag", l}, ""
}
rr.Tag = l.token
- <-c // zBlank
+ c.Next() // zBlank
s, e, c1 := endingToTxtSlice(c, "bad CAA Value", f)
if e != nil {
return nil, e, ""
@@ -2088,43 +2094,43 @@ func setCAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, c1
}
-func setTKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+func setTKEY(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) {
rr := new(TKEY)
rr.Hdr = h
- l := <-c
+ l, _ := c.Next()
// Algorithm
if l.value != zString {
return nil, &ParseError{f, "bad TKEY algorithm", l}, ""
}
rr.Algorithm = l.token
- <-c // zBlank
+ c.Next() // zBlank
// Get the key length and key values
- l = <-c
+ l, _ = c.Next()
i, err := strconv.ParseUint(l.token, 10, 8)
if err != nil || l.err {
return nil, &ParseError{f, "bad TKEY key length", l}, ""
}
rr.KeySize = uint16(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
if l.value != zString {
return nil, &ParseError{f, "bad TKEY key", l}, ""
}
rr.Key = l.token
- <-c // zBlank
+ c.Next() // zBlank
// Get the otherdata length and string data
- l = <-c
+ l, _ = c.Next()
i, err = strconv.ParseUint(l.token, 10, 8)
if err != nil || l.err {
return nil, &ParseError{f, "bad TKEY otherdata length", l}, ""
}
rr.OtherLen = uint16(i)
- <-c // zBlank
- l = <-c
+ c.Next() // zBlank
+ l, _ = c.Next()
if l.value != zString {
return nil, &ParseError{f, "bad TKEY otherday", l}, ""
}
diff --git a/vendor/github.com/miekg/dns/scanner.go b/vendor/github.com/miekg/dns/scanner.go
deleted file mode 100644
index 5b124ec59..000000000
--- a/vendor/github.com/miekg/dns/scanner.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package dns
-
-// Implement a simple scanner, return a byte stream from an io reader.
-
-import (
- "bufio"
- "context"
- "io"
- "text/scanner"
-)
-
-type scan struct {
- src *bufio.Reader
- position scanner.Position
- eof bool // Have we just seen a eof
- ctx context.Context
-}
-
-func scanInit(r io.Reader) (*scan, context.CancelFunc) {
- s := new(scan)
- s.src = bufio.NewReader(r)
- s.position.Line = 1
-
- ctx, cancel := context.WithCancel(context.Background())
- s.ctx = ctx
-
- return s, cancel
-}
-
-// tokenText returns the next byte from the input
-func (s *scan) tokenText() (byte, error) {
- c, err := s.src.ReadByte()
- if err != nil {
- return c, err
- }
- select {
- case <-s.ctx.Done():
- return c, context.Canceled
- default:
- break
- }
-
- // delay the newline handling until the next token is delivered,
- // fixes off-by-one errors when reporting a parse error.
- if s.eof {
- s.position.Line++
- s.position.Column = 0
- s.eof = false
- }
- if c == '\n' {
- s.eof = true
- return c, nil
- }
- s.position.Column++
- return c, nil
-}
diff --git a/vendor/github.com/miekg/dns/version.go b/vendor/github.com/miekg/dns/version.go
index 403b9ef97..0b0e9b6d8 100644
--- a/vendor/github.com/miekg/dns/version.go
+++ b/vendor/github.com/miekg/dns/version.go
@@ -3,7 +3,7 @@ package dns
import "fmt"
// Version is current version of this library.
-var Version = V{1, 0, 13}
+var Version = V{1, 0, 14}
// V holds the version of this library.
type V struct {
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/http.go b/vendor/github.com/prometheus/client_golang/prometheus/http.go
index 4b8e60273..9f0875bfc 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/http.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/http.go
@@ -15,9 +15,7 @@ package prometheus
import (
"bufio"
- "bytes"
"compress/gzip"
- "fmt"
"io"
"net"
"net/http"
@@ -41,19 +39,10 @@ const (
acceptEncodingHeader = "Accept-Encoding"
)
-var bufPool sync.Pool
-
-func getBuf() *bytes.Buffer {
- buf := bufPool.Get()
- if buf == nil {
- return &bytes.Buffer{}
- }
- return buf.(*bytes.Buffer)
-}
-
-func giveBuf(buf *bytes.Buffer) {
- buf.Reset()
- bufPool.Put(buf)
+var gzipPool = sync.Pool{
+ New: func() interface{} {
+ return gzip.NewWriter(nil)
+ },
}
// Handler returns an HTTP handler for the DefaultGatherer. It is
@@ -71,58 +60,40 @@ func Handler() http.Handler {
// Deprecated: Use promhttp.HandlerFor(DefaultGatherer, promhttp.HandlerOpts{})
// instead. See there for further documentation.
func UninstrumentedHandler() http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+ return http.HandlerFunc(func(rsp http.ResponseWriter, req *http.Request) {
mfs, err := DefaultGatherer.Gather()
if err != nil {
- http.Error(w, "An error has occurred during metrics collection:\n\n"+err.Error(), http.StatusInternalServerError)
+ httpError(rsp, err)
return
}
contentType := expfmt.Negotiate(req.Header)
- buf := getBuf()
- defer giveBuf(buf)
- writer, encoding := decorateWriter(req, buf)
- enc := expfmt.NewEncoder(writer, contentType)
- var lastErr error
+ header := rsp.Header()
+ header.Set(contentTypeHeader, string(contentType))
+
+ w := io.Writer(rsp)
+ if gzipAccepted(req.Header) {
+ header.Set(contentEncodingHeader, "gzip")
+ gz := gzipPool.Get().(*gzip.Writer)
+ defer gzipPool.Put(gz)
+
+ gz.Reset(w)
+ defer gz.Close()
+
+ w = gz
+ }
+
+ enc := expfmt.NewEncoder(w, contentType)
+
for _, mf := range mfs {
if err := enc.Encode(mf); err != nil {
- lastErr = err
- http.Error(w, "An error has occurred during metrics encoding:\n\n"+err.Error(), http.StatusInternalServerError)
+ httpError(rsp, err)
return
}
}
- if closer, ok := writer.(io.Closer); ok {
- closer.Close()
- }
- if lastErr != nil && buf.Len() == 0 {
- http.Error(w, "No metrics encoded, last error:\n\n"+lastErr.Error(), http.StatusInternalServerError)
- return
- }
- header := w.Header()
- header.Set(contentTypeHeader, string(contentType))
- header.Set(contentLengthHeader, fmt.Sprint(buf.Len()))
- if encoding != "" {
- header.Set(contentEncodingHeader, encoding)
- }
- w.Write(buf.Bytes())
})
}
-// decorateWriter wraps a writer to handle gzip compression if requested. It
-// returns the decorated writer and the appropriate "Content-Encoding" header
-// (which is empty if no compression is enabled).
-func decorateWriter(request *http.Request, writer io.Writer) (io.Writer, string) {
- header := request.Header.Get(acceptEncodingHeader)
- parts := strings.Split(header, ",")
- for _, part := range parts {
- part = strings.TrimSpace(part)
- if part == "gzip" || strings.HasPrefix(part, "gzip;") {
- return gzip.NewWriter(writer), "gzip"
- }
- }
- return writer, ""
-}
-
var instLabels = []string{"method", "code"}
type nower interface {
@@ -503,3 +474,31 @@ func sanitizeCode(s int) string {
return strconv.Itoa(s)
}
}
+
+// gzipAccepted returns whether the client will accept gzip-encoded content.
+func gzipAccepted(header http.Header) bool {
+ a := header.Get(acceptEncodingHeader)
+ parts := strings.Split(a, ",")
+ for _, part := range parts {
+ part = strings.TrimSpace(part)
+ if part == "gzip" || strings.HasPrefix(part, "gzip;") {
+ return true
+ }
+ }
+ return false
+}
+
+// httpError removes any content-encoding header and then calls http.Error with
+// the provided error and http.StatusInternalServerErrer. Error contents is
+// supposed to be uncompressed plain text. However, same as with a plain
+// http.Error, any header settings will be void if the header has already been
+// sent. The error message will still be written to the writer, but it will
+// probably be of limited use.
+func httpError(rsp http.ResponseWriter, err error) {
+ rsp.Header().Del(contentEncodingHeader)
+ http.Error(
+ rsp,
+ "An error has occurred while serving metrics:\n\n"+err.Error(),
+ http.StatusInternalServerError,
+ )
+}
diff --git a/vendor/github.com/prometheus/common/expfmt/text_create.go b/vendor/github.com/prometheus/common/expfmt/text_create.go
index 46b74364e..8e473d0fe 100644
--- a/vendor/github.com/prometheus/common/expfmt/text_create.go
+++ b/vendor/github.com/prometheus/common/expfmt/text_create.go
@@ -19,6 +19,7 @@ import (
"io"
"math"
"strconv"
+ "strings"
"sync"
"github.com/prometheus/common/model"
@@ -43,7 +44,7 @@ const (
var (
bufPool = sync.Pool{
New: func() interface{} {
- return bytes.NewBuffer(make([]byte, 0, initialNumBufSize))
+ return bytes.NewBuffer(make([]byte, 0, initialBufSize))
},
}
numBufPool = sync.Pool{
@@ -416,32 +417,17 @@ func writeLabelPairs(
// writeEscapedString replaces '\' by '\\', new line character by '\n', and - if
// includeDoubleQuote is true - '"' by '\"'.
+var (
+ escaper = strings.NewReplacer("\\", `\\`, "\n", `\n`)
+ quotedEscaper = strings.NewReplacer("\\", `\\`, "\n", `\n`, "\"", `\"`)
+)
+
func writeEscapedString(w enhancedWriter, v string, includeDoubleQuote bool) (int, error) {
- var (
- written, n int
- err error
- )
- for _, r := range v {
- switch r {
- case '\\':
- n, err = w.WriteString(`\\`)
- case '\n':
- n, err = w.WriteString(`\n`)
- case '"':
- if includeDoubleQuote {
- n, err = w.WriteString(`\"`)
- } else {
- n, err = w.WriteRune(r)
- }
- default:
- n, err = w.WriteRune(r)
- }
- written += n
- if err != nil {
- return written, err
- }
+ if includeDoubleQuote {
+ return quotedEscaper.WriteString(w, v)
+ } else {
+ return escaper.WriteString(w, v)
}
- return written, nil
}
// writeFloat is equivalent to fmt.Fprint with a float64 argument but hardcodes
diff --git a/vendor/github.com/prometheus/common/model/time.go b/vendor/github.com/prometheus/common/model/time.go
index 74ed5a9f7..46259b1f1 100644
--- a/vendor/github.com/prometheus/common/model/time.go
+++ b/vendor/github.com/prometheus/common/model/time.go
@@ -43,7 +43,7 @@ const (
// (1970-01-01 00:00 UTC) excluding leap seconds.
type Time int64
-// Interval describes and interval between two timestamps.
+// Interval describes an interval between two timestamps.
type Interval struct {
Start, End Time
}
diff --git a/vendor/github.com/rcrowley/go-metrics/LICENSE b/vendor/github.com/rcrowley/go-metrics/LICENSE
new file mode 100644
index 000000000..363fa9ee7
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/LICENSE
@@ -0,0 +1,29 @@
+Copyright 2012 Richard Crowley. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY RICHARD CROWLEY ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL RICHARD CROWLEY OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation
+are those of the authors and should not be interpreted as representing
+official policies, either expressed or implied, of Richard Crowley.
diff --git a/vendor/github.com/rcrowley/go-metrics/README.md b/vendor/github.com/rcrowley/go-metrics/README.md
new file mode 100644
index 000000000..b7356b5fc
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/README.md
@@ -0,0 +1,168 @@
+go-metrics
+==========
+
+
+
+Go port of Coda Hale's Metrics library: .
+
+Documentation: .
+
+Usage
+-----
+
+Create and update metrics:
+
+```go
+c := metrics.NewCounter()
+metrics.Register("foo", c)
+c.Inc(47)
+
+g := metrics.NewGauge()
+metrics.Register("bar", g)
+g.Update(47)
+
+r := NewRegistry()
+g := metrics.NewRegisteredFunctionalGauge("cache-evictions", r, func() int64 { return cache.getEvictionsCount() })
+
+s := metrics.NewExpDecaySample(1028, 0.015) // or metrics.NewUniformSample(1028)
+h := metrics.NewHistogram(s)
+metrics.Register("baz", h)
+h.Update(47)
+
+m := metrics.NewMeter()
+metrics.Register("quux", m)
+m.Mark(47)
+
+t := metrics.NewTimer()
+metrics.Register("bang", t)
+t.Time(func() {})
+t.Update(47)
+```
+
+Register() is not threadsafe. For threadsafe metric registration use
+GetOrRegister:
+
+```go
+t := metrics.GetOrRegisterTimer("account.create.latency", nil)
+t.Time(func() {})
+t.Update(47)
+```
+
+**NOTE:** Be sure to unregister short-lived meters and timers otherwise they will
+leak memory:
+
+```go
+// Will call Stop() on the Meter to allow for garbage collection
+metrics.Unregister("quux")
+// Or similarly for a Timer that embeds a Meter
+metrics.Unregister("bang")
+```
+
+Periodically log every metric in human-readable form to standard error:
+
+```go
+go metrics.Log(metrics.DefaultRegistry, 5 * time.Second, log.New(os.Stderr, "metrics: ", log.Lmicroseconds))
+```
+
+Periodically log every metric in slightly-more-parseable form to syslog:
+
+```go
+w, _ := syslog.Dial("unixgram", "/dev/log", syslog.LOG_INFO, "metrics")
+go metrics.Syslog(metrics.DefaultRegistry, 60e9, w)
+```
+
+Periodically emit every metric to Graphite using the [Graphite client](https://github.com/cyberdelia/go-metrics-graphite):
+
+```go
+
+import "github.com/cyberdelia/go-metrics-graphite"
+
+addr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:2003")
+go graphite.Graphite(metrics.DefaultRegistry, 10e9, "metrics", addr)
+```
+
+Periodically emit every metric into InfluxDB:
+
+**NOTE:** this has been pulled out of the library due to constant fluctuations
+in the InfluxDB API. In fact, all client libraries are on their way out. see
+issues [#121](https://github.com/rcrowley/go-metrics/issues/121) and
+[#124](https://github.com/rcrowley/go-metrics/issues/124) for progress and details.
+
+```go
+import "github.com/vrischmann/go-metrics-influxdb"
+
+go influxdb.InfluxDB(metrics.DefaultRegistry,
+ 10e9,
+ "127.0.0.1:8086",
+ "database-name",
+ "username",
+ "password"
+)
+```
+
+Periodically upload every metric to Librato using the [Librato client](https://github.com/mihasya/go-metrics-librato):
+
+**Note**: the client included with this repository under the `librato` package
+has been deprecated and moved to the repository linked above.
+
+```go
+import "github.com/mihasya/go-metrics-librato"
+
+go librato.Librato(metrics.DefaultRegistry,
+ 10e9, // interval
+ "example@example.com", // account owner email address
+ "token", // Librato API token
+ "hostname", // source
+ []float64{0.95}, // percentiles to send
+ time.Millisecond, // time unit
+)
+```
+
+Periodically emit every metric to StatHat:
+
+```go
+import "github.com/rcrowley/go-metrics/stathat"
+
+go stathat.Stathat(metrics.DefaultRegistry, 10e9, "example@example.com")
+```
+
+Maintain all metrics along with expvars at `/debug/metrics`:
+
+This uses the same mechanism as [the official expvar](http://golang.org/pkg/expvar/)
+but exposed under `/debug/metrics`, which shows a json representation of all your usual expvars
+as well as all your go-metrics.
+
+
+```go
+import "github.com/rcrowley/go-metrics/exp"
+
+exp.Exp(metrics.DefaultRegistry)
+```
+
+Installation
+------------
+
+```sh
+go get github.com/rcrowley/go-metrics
+```
+
+StatHat support additionally requires their Go client:
+
+```sh
+go get github.com/stathat/go
+```
+
+Publishing Metrics
+------------------
+
+Clients are available for the following destinations:
+
+* Librato - https://github.com/mihasya/go-metrics-librato
+* Graphite - https://github.com/cyberdelia/go-metrics-graphite
+* InfluxDB - https://github.com/vrischmann/go-metrics-influxdb
+* Ganglia - https://github.com/appscode/metlia
+* Prometheus - https://github.com/deathowl/go-metrics-prometheus
+* DataDog - https://github.com/syntaqx/go-metrics-datadog
+* SignalFX - https://github.com/pascallouisperez/go-metrics-signalfx
+* Honeycomb - https://github.com/getspine/go-metrics-honeycomb
+* Wavefront - https://github.com/wavefrontHQ/go-metrics-wavefront
diff --git a/vendor/github.com/rcrowley/go-metrics/counter.go b/vendor/github.com/rcrowley/go-metrics/counter.go
new file mode 100644
index 000000000..bb7b039cb
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/counter.go
@@ -0,0 +1,112 @@
+package metrics
+
+import "sync/atomic"
+
+// Counters hold an int64 value that can be incremented and decremented.
+type Counter interface {
+ Clear()
+ Count() int64
+ Dec(int64)
+ Inc(int64)
+ Snapshot() Counter
+}
+
+// GetOrRegisterCounter returns an existing Counter or constructs and registers
+// a new StandardCounter.
+func GetOrRegisterCounter(name string, r Registry) Counter {
+ if nil == r {
+ r = DefaultRegistry
+ }
+ return r.GetOrRegister(name, NewCounter).(Counter)
+}
+
+// NewCounter constructs a new StandardCounter.
+func NewCounter() Counter {
+ if UseNilMetrics {
+ return NilCounter{}
+ }
+ return &StandardCounter{0}
+}
+
+// NewRegisteredCounter constructs and registers a new StandardCounter.
+func NewRegisteredCounter(name string, r Registry) Counter {
+ c := NewCounter()
+ if nil == r {
+ r = DefaultRegistry
+ }
+ r.Register(name, c)
+ return c
+}
+
+// CounterSnapshot is a read-only copy of another Counter.
+type CounterSnapshot int64
+
+// Clear panics.
+func (CounterSnapshot) Clear() {
+ panic("Clear called on a CounterSnapshot")
+}
+
+// Count returns the count at the time the snapshot was taken.
+func (c CounterSnapshot) Count() int64 { return int64(c) }
+
+// Dec panics.
+func (CounterSnapshot) Dec(int64) {
+ panic("Dec called on a CounterSnapshot")
+}
+
+// Inc panics.
+func (CounterSnapshot) Inc(int64) {
+ panic("Inc called on a CounterSnapshot")
+}
+
+// Snapshot returns the snapshot.
+func (c CounterSnapshot) Snapshot() Counter { return c }
+
+// NilCounter is a no-op Counter.
+type NilCounter struct{}
+
+// Clear is a no-op.
+func (NilCounter) Clear() {}
+
+// Count is a no-op.
+func (NilCounter) Count() int64 { return 0 }
+
+// Dec is a no-op.
+func (NilCounter) Dec(i int64) {}
+
+// Inc is a no-op.
+func (NilCounter) Inc(i int64) {}
+
+// Snapshot is a no-op.
+func (NilCounter) Snapshot() Counter { return NilCounter{} }
+
+// StandardCounter is the standard implementation of a Counter and uses the
+// sync/atomic package to manage a single int64 value.
+type StandardCounter struct {
+ count int64
+}
+
+// Clear sets the counter to zero.
+func (c *StandardCounter) Clear() {
+ atomic.StoreInt64(&c.count, 0)
+}
+
+// Count returns the current count.
+func (c *StandardCounter) Count() int64 {
+ return atomic.LoadInt64(&c.count)
+}
+
+// Dec decrements the counter by the given amount.
+func (c *StandardCounter) Dec(i int64) {
+ atomic.AddInt64(&c.count, -i)
+}
+
+// Inc increments the counter by the given amount.
+func (c *StandardCounter) Inc(i int64) {
+ atomic.AddInt64(&c.count, i)
+}
+
+// Snapshot returns a read-only copy of the counter.
+func (c *StandardCounter) Snapshot() Counter {
+ return CounterSnapshot(c.Count())
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/debug.go b/vendor/github.com/rcrowley/go-metrics/debug.go
new file mode 100644
index 000000000..043ccefab
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/debug.go
@@ -0,0 +1,76 @@
+package metrics
+
+import (
+ "runtime/debug"
+ "time"
+)
+
+var (
+ debugMetrics struct {
+ GCStats struct {
+ LastGC Gauge
+ NumGC Gauge
+ Pause Histogram
+ //PauseQuantiles Histogram
+ PauseTotal Gauge
+ }
+ ReadGCStats Timer
+ }
+ gcStats debug.GCStats
+)
+
+// Capture new values for the Go garbage collector statistics exported in
+// debug.GCStats. This is designed to be called as a goroutine.
+func CaptureDebugGCStats(r Registry, d time.Duration) {
+ for _ = range time.Tick(d) {
+ CaptureDebugGCStatsOnce(r)
+ }
+}
+
+// Capture new values for the Go garbage collector statistics exported in
+// debug.GCStats. This is designed to be called in a background goroutine.
+// Giving a registry which has not been given to RegisterDebugGCStats will
+// panic.
+//
+// Be careful (but much less so) with this because debug.ReadGCStats calls
+// the C function runtime·lock(runtime·mheap) which, while not a stop-the-world
+// operation, isn't something you want to be doing all the time.
+func CaptureDebugGCStatsOnce(r Registry) {
+ lastGC := gcStats.LastGC
+ t := time.Now()
+ debug.ReadGCStats(&gcStats)
+ debugMetrics.ReadGCStats.UpdateSince(t)
+
+ debugMetrics.GCStats.LastGC.Update(int64(gcStats.LastGC.UnixNano()))
+ debugMetrics.GCStats.NumGC.Update(int64(gcStats.NumGC))
+ if lastGC != gcStats.LastGC && 0 < len(gcStats.Pause) {
+ debugMetrics.GCStats.Pause.Update(int64(gcStats.Pause[0]))
+ }
+ //debugMetrics.GCStats.PauseQuantiles.Update(gcStats.PauseQuantiles)
+ debugMetrics.GCStats.PauseTotal.Update(int64(gcStats.PauseTotal))
+}
+
+// Register metrics for the Go garbage collector statistics exported in
+// debug.GCStats. The metrics are named by their fully-qualified Go symbols,
+// i.e. debug.GCStats.PauseTotal.
+func RegisterDebugGCStats(r Registry) {
+ debugMetrics.GCStats.LastGC = NewGauge()
+ debugMetrics.GCStats.NumGC = NewGauge()
+ debugMetrics.GCStats.Pause = NewHistogram(NewExpDecaySample(1028, 0.015))
+ //debugMetrics.GCStats.PauseQuantiles = NewHistogram(NewExpDecaySample(1028, 0.015))
+ debugMetrics.GCStats.PauseTotal = NewGauge()
+ debugMetrics.ReadGCStats = NewTimer()
+
+ r.Register("debug.GCStats.LastGC", debugMetrics.GCStats.LastGC)
+ r.Register("debug.GCStats.NumGC", debugMetrics.GCStats.NumGC)
+ r.Register("debug.GCStats.Pause", debugMetrics.GCStats.Pause)
+ //r.Register("debug.GCStats.PauseQuantiles", debugMetrics.GCStats.PauseQuantiles)
+ r.Register("debug.GCStats.PauseTotal", debugMetrics.GCStats.PauseTotal)
+ r.Register("debug.ReadGCStats", debugMetrics.ReadGCStats)
+}
+
+// Allocate an initial slice for gcStats.Pause to avoid allocations during
+// normal operation.
+func init() {
+ gcStats.Pause = make([]time.Duration, 11)
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/ewma.go b/vendor/github.com/rcrowley/go-metrics/ewma.go
new file mode 100644
index 000000000..a8183dd7e
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/ewma.go
@@ -0,0 +1,138 @@
+package metrics
+
+import (
+ "math"
+ "sync"
+ "sync/atomic"
+)
+
+// EWMAs continuously calculate an exponentially-weighted moving average
+// based on an outside source of clock ticks.
+type EWMA interface {
+ Rate() float64
+ Snapshot() EWMA
+ Tick()
+ Update(int64)
+}
+
+// NewEWMA constructs a new EWMA with the given alpha.
+func NewEWMA(alpha float64) EWMA {
+ if UseNilMetrics {
+ return NilEWMA{}
+ }
+ return &StandardEWMA{alpha: alpha}
+}
+
+// NewEWMA1 constructs a new EWMA for a one-minute moving average.
+func NewEWMA1() EWMA {
+ return NewEWMA(1 - math.Exp(-5.0/60.0/1))
+}
+
+// NewEWMA5 constructs a new EWMA for a five-minute moving average.
+func NewEWMA5() EWMA {
+ return NewEWMA(1 - math.Exp(-5.0/60.0/5))
+}
+
+// NewEWMA15 constructs a new EWMA for a fifteen-minute moving average.
+func NewEWMA15() EWMA {
+ return NewEWMA(1 - math.Exp(-5.0/60.0/15))
+}
+
+// EWMASnapshot is a read-only copy of another EWMA.
+type EWMASnapshot float64
+
+// Rate returns the rate of events per second at the time the snapshot was
+// taken.
+func (a EWMASnapshot) Rate() float64 { return float64(a) }
+
+// Snapshot returns the snapshot.
+func (a EWMASnapshot) Snapshot() EWMA { return a }
+
+// Tick panics.
+func (EWMASnapshot) Tick() {
+ panic("Tick called on an EWMASnapshot")
+}
+
+// Update panics.
+func (EWMASnapshot) Update(int64) {
+ panic("Update called on an EWMASnapshot")
+}
+
+// NilEWMA is a no-op EWMA.
+type NilEWMA struct{}
+
+// Rate is a no-op.
+func (NilEWMA) Rate() float64 { return 0.0 }
+
+// Snapshot is a no-op.
+func (NilEWMA) Snapshot() EWMA { return NilEWMA{} }
+
+// Tick is a no-op.
+func (NilEWMA) Tick() {}
+
+// Update is a no-op.
+func (NilEWMA) Update(n int64) {}
+
+// StandardEWMA is the standard implementation of an EWMA and tracks the number
+// of uncounted events and processes them on each tick. It uses the
+// sync/atomic package to manage uncounted events.
+type StandardEWMA struct {
+ uncounted int64 // /!\ this should be the first member to ensure 64-bit alignment
+ alpha float64
+ rate uint64
+ init uint32
+ mutex sync.Mutex
+}
+
+// Rate returns the moving average rate of events per second.
+func (a *StandardEWMA) Rate() float64 {
+ currentRate := math.Float64frombits(atomic.LoadUint64(&a.rate)) * float64(1e9)
+ return currentRate
+}
+
+// Snapshot returns a read-only copy of the EWMA.
+func (a *StandardEWMA) Snapshot() EWMA {
+ return EWMASnapshot(a.Rate())
+}
+
+// Tick ticks the clock to update the moving average. It assumes it is called
+// every five seconds.
+func (a *StandardEWMA) Tick() {
+ // Optimization to avoid mutex locking in the hot-path.
+ if atomic.LoadUint32(&a.init) == 1 {
+ a.updateRate(a.fetchInstantRate())
+ } else {
+ // Slow-path: this is only needed on the first Tick() and preserves transactional updating
+ // of init and rate in the else block. The first conditional is needed below because
+ // a different thread could have set a.init = 1 between the time of the first atomic load and when
+ // the lock was acquired.
+ a.mutex.Lock()
+ if atomic.LoadUint32(&a.init) == 1 {
+ // The fetchInstantRate() uses atomic loading, which is unecessary in this critical section
+ // but again, this section is only invoked on the first successful Tick() operation.
+ a.updateRate(a.fetchInstantRate())
+ } else {
+ atomic.StoreUint32(&a.init, 1)
+ atomic.StoreUint64(&a.rate, math.Float64bits(a.fetchInstantRate()))
+ }
+ a.mutex.Unlock()
+ }
+}
+
+func (a *StandardEWMA) fetchInstantRate() float64 {
+ count := atomic.LoadInt64(&a.uncounted)
+ atomic.AddInt64(&a.uncounted, -count)
+ instantRate := float64(count) / float64(5e9)
+ return instantRate
+}
+
+func (a *StandardEWMA) updateRate(instantRate float64) {
+ currentRate := math.Float64frombits(atomic.LoadUint64(&a.rate))
+ currentRate += a.alpha * (instantRate - currentRate)
+ atomic.StoreUint64(&a.rate, math.Float64bits(currentRate))
+}
+
+// Update adds n uncounted events.
+func (a *StandardEWMA) Update(n int64) {
+ atomic.AddInt64(&a.uncounted, n)
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/gauge.go b/vendor/github.com/rcrowley/go-metrics/gauge.go
new file mode 100644
index 000000000..cb57a9388
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/gauge.go
@@ -0,0 +1,120 @@
+package metrics
+
+import "sync/atomic"
+
+// Gauges hold an int64 value that can be set arbitrarily.
+type Gauge interface {
+ Snapshot() Gauge
+ Update(int64)
+ Value() int64
+}
+
+// GetOrRegisterGauge returns an existing Gauge or constructs and registers a
+// new StandardGauge.
+func GetOrRegisterGauge(name string, r Registry) Gauge {
+ if nil == r {
+ r = DefaultRegistry
+ }
+ return r.GetOrRegister(name, NewGauge).(Gauge)
+}
+
+// NewGauge constructs a new StandardGauge.
+func NewGauge() Gauge {
+ if UseNilMetrics {
+ return NilGauge{}
+ }
+ return &StandardGauge{0}
+}
+
+// NewRegisteredGauge constructs and registers a new StandardGauge.
+func NewRegisteredGauge(name string, r Registry) Gauge {
+ c := NewGauge()
+ if nil == r {
+ r = DefaultRegistry
+ }
+ r.Register(name, c)
+ return c
+}
+
+// NewFunctionalGauge constructs a new FunctionalGauge.
+func NewFunctionalGauge(f func() int64) Gauge {
+ if UseNilMetrics {
+ return NilGauge{}
+ }
+ return &FunctionalGauge{value: f}
+}
+
+// NewRegisteredFunctionalGauge constructs and registers a new StandardGauge.
+func NewRegisteredFunctionalGauge(name string, r Registry, f func() int64) Gauge {
+ c := NewFunctionalGauge(f)
+ if nil == r {
+ r = DefaultRegistry
+ }
+ r.Register(name, c)
+ return c
+}
+
+// GaugeSnapshot is a read-only copy of another Gauge.
+type GaugeSnapshot int64
+
+// Snapshot returns the snapshot.
+func (g GaugeSnapshot) Snapshot() Gauge { return g }
+
+// Update panics.
+func (GaugeSnapshot) Update(int64) {
+ panic("Update called on a GaugeSnapshot")
+}
+
+// Value returns the value at the time the snapshot was taken.
+func (g GaugeSnapshot) Value() int64 { return int64(g) }
+
+// NilGauge is a no-op Gauge.
+type NilGauge struct{}
+
+// Snapshot is a no-op.
+func (NilGauge) Snapshot() Gauge { return NilGauge{} }
+
+// Update is a no-op.
+func (NilGauge) Update(v int64) {}
+
+// Value is a no-op.
+func (NilGauge) Value() int64 { return 0 }
+
+// StandardGauge is the standard implementation of a Gauge and uses the
+// sync/atomic package to manage a single int64 value.
+type StandardGauge struct {
+ value int64
+}
+
+// Snapshot returns a read-only copy of the gauge.
+func (g *StandardGauge) Snapshot() Gauge {
+ return GaugeSnapshot(g.Value())
+}
+
+// Update updates the gauge's value.
+func (g *StandardGauge) Update(v int64) {
+ atomic.StoreInt64(&g.value, v)
+}
+
+// Value returns the gauge's current value.
+func (g *StandardGauge) Value() int64 {
+ return atomic.LoadInt64(&g.value)
+}
+
+// FunctionalGauge returns value from given function
+type FunctionalGauge struct {
+ value func() int64
+}
+
+// Value returns the gauge's current value.
+func (g FunctionalGauge) Value() int64 {
+ return g.value()
+}
+
+// Snapshot returns the snapshot.
+func (g FunctionalGauge) Snapshot() Gauge { return GaugeSnapshot(g.Value()) }
+
+// Update panics.
+func (FunctionalGauge) Update(int64) {
+ panic("Update called on a FunctionalGauge")
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/gauge_float64.go b/vendor/github.com/rcrowley/go-metrics/gauge_float64.go
new file mode 100644
index 000000000..3962e6db0
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/gauge_float64.go
@@ -0,0 +1,125 @@
+package metrics
+
+import (
+ "math"
+ "sync/atomic"
+)
+
+// GaugeFloat64s hold a float64 value that can be set arbitrarily.
+type GaugeFloat64 interface {
+ Snapshot() GaugeFloat64
+ Update(float64)
+ Value() float64
+}
+
+// GetOrRegisterGaugeFloat64 returns an existing GaugeFloat64 or constructs and registers a
+// new StandardGaugeFloat64.
+func GetOrRegisterGaugeFloat64(name string, r Registry) GaugeFloat64 {
+ if nil == r {
+ r = DefaultRegistry
+ }
+ return r.GetOrRegister(name, NewGaugeFloat64()).(GaugeFloat64)
+}
+
+// NewGaugeFloat64 constructs a new StandardGaugeFloat64.
+func NewGaugeFloat64() GaugeFloat64 {
+ if UseNilMetrics {
+ return NilGaugeFloat64{}
+ }
+ return &StandardGaugeFloat64{
+ value: 0.0,
+ }
+}
+
+// NewRegisteredGaugeFloat64 constructs and registers a new StandardGaugeFloat64.
+func NewRegisteredGaugeFloat64(name string, r Registry) GaugeFloat64 {
+ c := NewGaugeFloat64()
+ if nil == r {
+ r = DefaultRegistry
+ }
+ r.Register(name, c)
+ return c
+}
+
+// NewFunctionalGauge constructs a new FunctionalGauge.
+func NewFunctionalGaugeFloat64(f func() float64) GaugeFloat64 {
+ if UseNilMetrics {
+ return NilGaugeFloat64{}
+ }
+ return &FunctionalGaugeFloat64{value: f}
+}
+
+// NewRegisteredFunctionalGauge constructs and registers a new StandardGauge.
+func NewRegisteredFunctionalGaugeFloat64(name string, r Registry, f func() float64) GaugeFloat64 {
+ c := NewFunctionalGaugeFloat64(f)
+ if nil == r {
+ r = DefaultRegistry
+ }
+ r.Register(name, c)
+ return c
+}
+
+// GaugeFloat64Snapshot is a read-only copy of another GaugeFloat64.
+type GaugeFloat64Snapshot float64
+
+// Snapshot returns the snapshot.
+func (g GaugeFloat64Snapshot) Snapshot() GaugeFloat64 { return g }
+
+// Update panics.
+func (GaugeFloat64Snapshot) Update(float64) {
+ panic("Update called on a GaugeFloat64Snapshot")
+}
+
+// Value returns the value at the time the snapshot was taken.
+func (g GaugeFloat64Snapshot) Value() float64 { return float64(g) }
+
+// NilGauge is a no-op Gauge.
+type NilGaugeFloat64 struct{}
+
+// Snapshot is a no-op.
+func (NilGaugeFloat64) Snapshot() GaugeFloat64 { return NilGaugeFloat64{} }
+
+// Update is a no-op.
+func (NilGaugeFloat64) Update(v float64) {}
+
+// Value is a no-op.
+func (NilGaugeFloat64) Value() float64 { return 0.0 }
+
+// StandardGaugeFloat64 is the standard implementation of a GaugeFloat64 and uses
+// sync.Mutex to manage a single float64 value.
+type StandardGaugeFloat64 struct {
+ value uint64
+}
+
+// Snapshot returns a read-only copy of the gauge.
+func (g *StandardGaugeFloat64) Snapshot() GaugeFloat64 {
+ return GaugeFloat64Snapshot(g.Value())
+}
+
+// Update updates the gauge's value.
+func (g *StandardGaugeFloat64) Update(v float64) {
+ atomic.StoreUint64(&g.value, math.Float64bits(v))
+}
+
+// Value returns the gauge's current value.
+func (g *StandardGaugeFloat64) Value() float64 {
+ return math.Float64frombits(atomic.LoadUint64(&g.value))
+}
+
+// FunctionalGaugeFloat64 returns value from given function
+type FunctionalGaugeFloat64 struct {
+ value func() float64
+}
+
+// Value returns the gauge's current value.
+func (g FunctionalGaugeFloat64) Value() float64 {
+ return g.value()
+}
+
+// Snapshot returns the snapshot.
+func (g FunctionalGaugeFloat64) Snapshot() GaugeFloat64 { return GaugeFloat64Snapshot(g.Value()) }
+
+// Update panics.
+func (FunctionalGaugeFloat64) Update(float64) {
+ panic("Update called on a FunctionalGaugeFloat64")
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/graphite.go b/vendor/github.com/rcrowley/go-metrics/graphite.go
new file mode 100644
index 000000000..abd0a7d29
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/graphite.go
@@ -0,0 +1,113 @@
+package metrics
+
+import (
+ "bufio"
+ "fmt"
+ "log"
+ "net"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// GraphiteConfig provides a container with configuration parameters for
+// the Graphite exporter
+type GraphiteConfig struct {
+ Addr *net.TCPAddr // Network address to connect to
+ Registry Registry // Registry to be exported
+ FlushInterval time.Duration // Flush interval
+ DurationUnit time.Duration // Time conversion unit for durations
+ Prefix string // Prefix to be prepended to metric names
+ Percentiles []float64 // Percentiles to export from timers and histograms
+}
+
+// Graphite is a blocking exporter function which reports metrics in r
+// to a graphite server located at addr, flushing them every d duration
+// and prepending metric names with prefix.
+func Graphite(r Registry, d time.Duration, prefix string, addr *net.TCPAddr) {
+ GraphiteWithConfig(GraphiteConfig{
+ Addr: addr,
+ Registry: r,
+ FlushInterval: d,
+ DurationUnit: time.Nanosecond,
+ Prefix: prefix,
+ Percentiles: []float64{0.5, 0.75, 0.95, 0.99, 0.999},
+ })
+}
+
+// GraphiteWithConfig is a blocking exporter function just like Graphite,
+// but it takes a GraphiteConfig instead.
+func GraphiteWithConfig(c GraphiteConfig) {
+ log.Printf("WARNING: This go-metrics client has been DEPRECATED! It has been moved to https://github.com/cyberdelia/go-metrics-graphite and will be removed from rcrowley/go-metrics on August 12th 2015")
+ for _ = range time.Tick(c.FlushInterval) {
+ if err := graphite(&c); nil != err {
+ log.Println(err)
+ }
+ }
+}
+
+// GraphiteOnce performs a single submission to Graphite, returning a
+// non-nil error on failed connections. This can be used in a loop
+// similar to GraphiteWithConfig for custom error handling.
+func GraphiteOnce(c GraphiteConfig) error {
+ log.Printf("WARNING: This go-metrics client has been DEPRECATED! It has been moved to https://github.com/cyberdelia/go-metrics-graphite and will be removed from rcrowley/go-metrics on August 12th 2015")
+ return graphite(&c)
+}
+
+func graphite(c *GraphiteConfig) error {
+ now := time.Now().Unix()
+ du := float64(c.DurationUnit)
+ conn, err := net.DialTCP("tcp", nil, c.Addr)
+ if nil != err {
+ return err
+ }
+ defer conn.Close()
+ w := bufio.NewWriter(conn)
+ c.Registry.Each(func(name string, i interface{}) {
+ switch metric := i.(type) {
+ case Counter:
+ fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, metric.Count(), now)
+ case Gauge:
+ fmt.Fprintf(w, "%s.%s.value %d %d\n", c.Prefix, name, metric.Value(), now)
+ case GaugeFloat64:
+ fmt.Fprintf(w, "%s.%s.value %f %d\n", c.Prefix, name, metric.Value(), now)
+ case Histogram:
+ h := metric.Snapshot()
+ ps := h.Percentiles(c.Percentiles)
+ fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, h.Count(), now)
+ fmt.Fprintf(w, "%s.%s.min %d %d\n", c.Prefix, name, h.Min(), now)
+ fmt.Fprintf(w, "%s.%s.max %d %d\n", c.Prefix, name, h.Max(), now)
+ fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, h.Mean(), now)
+ fmt.Fprintf(w, "%s.%s.std-dev %.2f %d\n", c.Prefix, name, h.StdDev(), now)
+ for psIdx, psKey := range c.Percentiles {
+ key := strings.Replace(strconv.FormatFloat(psKey*100.0, 'f', -1, 64), ".", "", 1)
+ fmt.Fprintf(w, "%s.%s.%s-percentile %.2f %d\n", c.Prefix, name, key, ps[psIdx], now)
+ }
+ case Meter:
+ m := metric.Snapshot()
+ fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, m.Count(), now)
+ fmt.Fprintf(w, "%s.%s.one-minute %.2f %d\n", c.Prefix, name, m.Rate1(), now)
+ fmt.Fprintf(w, "%s.%s.five-minute %.2f %d\n", c.Prefix, name, m.Rate5(), now)
+ fmt.Fprintf(w, "%s.%s.fifteen-minute %.2f %d\n", c.Prefix, name, m.Rate15(), now)
+ fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, m.RateMean(), now)
+ case Timer:
+ t := metric.Snapshot()
+ ps := t.Percentiles(c.Percentiles)
+ fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, t.Count(), now)
+ fmt.Fprintf(w, "%s.%s.min %d %d\n", c.Prefix, name, t.Min()/int64(du), now)
+ fmt.Fprintf(w, "%s.%s.max %d %d\n", c.Prefix, name, t.Max()/int64(du), now)
+ fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, t.Mean()/du, now)
+ fmt.Fprintf(w, "%s.%s.std-dev %.2f %d\n", c.Prefix, name, t.StdDev()/du, now)
+ for psIdx, psKey := range c.Percentiles {
+ key := strings.Replace(strconv.FormatFloat(psKey*100.0, 'f', -1, 64), ".", "", 1)
+ fmt.Fprintf(w, "%s.%s.%s-percentile %.2f %d\n", c.Prefix, name, key, ps[psIdx], now)
+ }
+ fmt.Fprintf(w, "%s.%s.one-minute %.2f %d\n", c.Prefix, name, t.Rate1(), now)
+ fmt.Fprintf(w, "%s.%s.five-minute %.2f %d\n", c.Prefix, name, t.Rate5(), now)
+ fmt.Fprintf(w, "%s.%s.fifteen-minute %.2f %d\n", c.Prefix, name, t.Rate15(), now)
+ fmt.Fprintf(w, "%s.%s.mean-rate %.2f %d\n", c.Prefix, name, t.RateMean(), now)
+ }
+ w.Flush()
+ })
+ return nil
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/healthcheck.go b/vendor/github.com/rcrowley/go-metrics/healthcheck.go
new file mode 100644
index 000000000..445131cae
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/healthcheck.go
@@ -0,0 +1,61 @@
+package metrics
+
+// Healthchecks hold an error value describing an arbitrary up/down status.
+type Healthcheck interface {
+ Check()
+ Error() error
+ Healthy()
+ Unhealthy(error)
+}
+
+// NewHealthcheck constructs a new Healthcheck which will use the given
+// function to update its status.
+func NewHealthcheck(f func(Healthcheck)) Healthcheck {
+ if UseNilMetrics {
+ return NilHealthcheck{}
+ }
+ return &StandardHealthcheck{nil, f}
+}
+
+// NilHealthcheck is a no-op.
+type NilHealthcheck struct{}
+
+// Check is a no-op.
+func (NilHealthcheck) Check() {}
+
+// Error is a no-op.
+func (NilHealthcheck) Error() error { return nil }
+
+// Healthy is a no-op.
+func (NilHealthcheck) Healthy() {}
+
+// Unhealthy is a no-op.
+func (NilHealthcheck) Unhealthy(error) {}
+
+// StandardHealthcheck is the standard implementation of a Healthcheck and
+// stores the status and a function to call to update the status.
+type StandardHealthcheck struct {
+ err error
+ f func(Healthcheck)
+}
+
+// Check runs the healthcheck function to update the healthcheck's status.
+func (h *StandardHealthcheck) Check() {
+ h.f(h)
+}
+
+// Error returns the healthcheck's status, which will be nil if it is healthy.
+func (h *StandardHealthcheck) Error() error {
+ return h.err
+}
+
+// Healthy marks the healthcheck as healthy.
+func (h *StandardHealthcheck) Healthy() {
+ h.err = nil
+}
+
+// Unhealthy marks the healthcheck as unhealthy. The error is stored and
+// may be retrieved by the Error method.
+func (h *StandardHealthcheck) Unhealthy(err error) {
+ h.err = err
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/histogram.go b/vendor/github.com/rcrowley/go-metrics/histogram.go
new file mode 100644
index 000000000..dbc837fe4
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/histogram.go
@@ -0,0 +1,202 @@
+package metrics
+
+// Histograms calculate distribution statistics from a series of int64 values.
+type Histogram interface {
+ Clear()
+ Count() int64
+ Max() int64
+ Mean() float64
+ Min() int64
+ Percentile(float64) float64
+ Percentiles([]float64) []float64
+ Sample() Sample
+ Snapshot() Histogram
+ StdDev() float64
+ Sum() int64
+ Update(int64)
+ Variance() float64
+}
+
+// GetOrRegisterHistogram returns an existing Histogram or constructs and
+// registers a new StandardHistogram.
+func GetOrRegisterHistogram(name string, r Registry, s Sample) Histogram {
+ if nil == r {
+ r = DefaultRegistry
+ }
+ return r.GetOrRegister(name, func() Histogram { return NewHistogram(s) }).(Histogram)
+}
+
+// NewHistogram constructs a new StandardHistogram from a Sample.
+func NewHistogram(s Sample) Histogram {
+ if UseNilMetrics {
+ return NilHistogram{}
+ }
+ return &StandardHistogram{sample: s}
+}
+
+// NewRegisteredHistogram constructs and registers a new StandardHistogram from
+// a Sample.
+func NewRegisteredHistogram(name string, r Registry, s Sample) Histogram {
+ c := NewHistogram(s)
+ if nil == r {
+ r = DefaultRegistry
+ }
+ r.Register(name, c)
+ return c
+}
+
+// HistogramSnapshot is a read-only copy of another Histogram.
+type HistogramSnapshot struct {
+ sample *SampleSnapshot
+}
+
+// Clear panics.
+func (*HistogramSnapshot) Clear() {
+ panic("Clear called on a HistogramSnapshot")
+}
+
+// Count returns the number of samples recorded at the time the snapshot was
+// taken.
+func (h *HistogramSnapshot) Count() int64 { return h.sample.Count() }
+
+// Max returns the maximum value in the sample at the time the snapshot was
+// taken.
+func (h *HistogramSnapshot) Max() int64 { return h.sample.Max() }
+
+// Mean returns the mean of the values in the sample at the time the snapshot
+// was taken.
+func (h *HistogramSnapshot) Mean() float64 { return h.sample.Mean() }
+
+// Min returns the minimum value in the sample at the time the snapshot was
+// taken.
+func (h *HistogramSnapshot) Min() int64 { return h.sample.Min() }
+
+// Percentile returns an arbitrary percentile of values in the sample at the
+// time the snapshot was taken.
+func (h *HistogramSnapshot) Percentile(p float64) float64 {
+ return h.sample.Percentile(p)
+}
+
+// Percentiles returns a slice of arbitrary percentiles of values in the sample
+// at the time the snapshot was taken.
+func (h *HistogramSnapshot) Percentiles(ps []float64) []float64 {
+ return h.sample.Percentiles(ps)
+}
+
+// Sample returns the Sample underlying the histogram.
+func (h *HistogramSnapshot) Sample() Sample { return h.sample }
+
+// Snapshot returns the snapshot.
+func (h *HistogramSnapshot) Snapshot() Histogram { return h }
+
+// StdDev returns the standard deviation of the values in the sample at the
+// time the snapshot was taken.
+func (h *HistogramSnapshot) StdDev() float64 { return h.sample.StdDev() }
+
+// Sum returns the sum in the sample at the time the snapshot was taken.
+func (h *HistogramSnapshot) Sum() int64 { return h.sample.Sum() }
+
+// Update panics.
+func (*HistogramSnapshot) Update(int64) {
+ panic("Update called on a HistogramSnapshot")
+}
+
+// Variance returns the variance of inputs at the time the snapshot was taken.
+func (h *HistogramSnapshot) Variance() float64 { return h.sample.Variance() }
+
+// NilHistogram is a no-op Histogram.
+type NilHistogram struct{}
+
+// Clear is a no-op.
+func (NilHistogram) Clear() {}
+
+// Count is a no-op.
+func (NilHistogram) Count() int64 { return 0 }
+
+// Max is a no-op.
+func (NilHistogram) Max() int64 { return 0 }
+
+// Mean is a no-op.
+func (NilHistogram) Mean() float64 { return 0.0 }
+
+// Min is a no-op.
+func (NilHistogram) Min() int64 { return 0 }
+
+// Percentile is a no-op.
+func (NilHistogram) Percentile(p float64) float64 { return 0.0 }
+
+// Percentiles is a no-op.
+func (NilHistogram) Percentiles(ps []float64) []float64 {
+ return make([]float64, len(ps))
+}
+
+// Sample is a no-op.
+func (NilHistogram) Sample() Sample { return NilSample{} }
+
+// Snapshot is a no-op.
+func (NilHistogram) Snapshot() Histogram { return NilHistogram{} }
+
+// StdDev is a no-op.
+func (NilHistogram) StdDev() float64 { return 0.0 }
+
+// Sum is a no-op.
+func (NilHistogram) Sum() int64 { return 0 }
+
+// Update is a no-op.
+func (NilHistogram) Update(v int64) {}
+
+// Variance is a no-op.
+func (NilHistogram) Variance() float64 { return 0.0 }
+
+// StandardHistogram is the standard implementation of a Histogram and uses a
+// Sample to bound its memory use.
+type StandardHistogram struct {
+ sample Sample
+}
+
+// Clear clears the histogram and its sample.
+func (h *StandardHistogram) Clear() { h.sample.Clear() }
+
+// Count returns the number of samples recorded since the histogram was last
+// cleared.
+func (h *StandardHistogram) Count() int64 { return h.sample.Count() }
+
+// Max returns the maximum value in the sample.
+func (h *StandardHistogram) Max() int64 { return h.sample.Max() }
+
+// Mean returns the mean of the values in the sample.
+func (h *StandardHistogram) Mean() float64 { return h.sample.Mean() }
+
+// Min returns the minimum value in the sample.
+func (h *StandardHistogram) Min() int64 { return h.sample.Min() }
+
+// Percentile returns an arbitrary percentile of the values in the sample.
+func (h *StandardHistogram) Percentile(p float64) float64 {
+ return h.sample.Percentile(p)
+}
+
+// Percentiles returns a slice of arbitrary percentiles of the values in the
+// sample.
+func (h *StandardHistogram) Percentiles(ps []float64) []float64 {
+ return h.sample.Percentiles(ps)
+}
+
+// Sample returns the Sample underlying the histogram.
+func (h *StandardHistogram) Sample() Sample { return h.sample }
+
+// Snapshot returns a read-only copy of the histogram.
+func (h *StandardHistogram) Snapshot() Histogram {
+ return &HistogramSnapshot{sample: h.sample.Snapshot().(*SampleSnapshot)}
+}
+
+// StdDev returns the standard deviation of the values in the sample.
+func (h *StandardHistogram) StdDev() float64 { return h.sample.StdDev() }
+
+// Sum returns the sum in the sample.
+func (h *StandardHistogram) Sum() int64 { return h.sample.Sum() }
+
+// Update samples a new value.
+func (h *StandardHistogram) Update(v int64) { h.sample.Update(v) }
+
+// Variance returns the variance of the values in the sample.
+func (h *StandardHistogram) Variance() float64 { return h.sample.Variance() }
diff --git a/vendor/github.com/rcrowley/go-metrics/json.go b/vendor/github.com/rcrowley/go-metrics/json.go
new file mode 100644
index 000000000..174b9477e
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/json.go
@@ -0,0 +1,31 @@
+package metrics
+
+import (
+ "encoding/json"
+ "io"
+ "time"
+)
+
+// MarshalJSON returns a byte slice containing a JSON representation of all
+// the metrics in the Registry.
+func (r *StandardRegistry) MarshalJSON() ([]byte, error) {
+ return json.Marshal(r.GetAll())
+}
+
+// WriteJSON writes metrics from the given registry periodically to the
+// specified io.Writer as JSON.
+func WriteJSON(r Registry, d time.Duration, w io.Writer) {
+ for _ = range time.Tick(d) {
+ WriteJSONOnce(r, w)
+ }
+}
+
+// WriteJSONOnce writes metrics from the given registry to the specified
+// io.Writer as JSON.
+func WriteJSONOnce(r Registry, w io.Writer) {
+ json.NewEncoder(w).Encode(r)
+}
+
+func (p *PrefixedRegistry) MarshalJSON() ([]byte, error) {
+ return json.Marshal(p.GetAll())
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/log.go b/vendor/github.com/rcrowley/go-metrics/log.go
new file mode 100644
index 000000000..f8074c045
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/log.go
@@ -0,0 +1,80 @@
+package metrics
+
+import (
+ "time"
+)
+
+type Logger interface {
+ Printf(format string, v ...interface{})
+}
+
+func Log(r Registry, freq time.Duration, l Logger) {
+ LogScaled(r, freq, time.Nanosecond, l)
+}
+
+// Output each metric in the given registry periodically using the given
+// logger. Print timings in `scale` units (eg time.Millisecond) rather than nanos.
+func LogScaled(r Registry, freq time.Duration, scale time.Duration, l Logger) {
+ du := float64(scale)
+ duSuffix := scale.String()[1:]
+
+ for _ = range time.Tick(freq) {
+ r.Each(func(name string, i interface{}) {
+ switch metric := i.(type) {
+ case Counter:
+ l.Printf("counter %s\n", name)
+ l.Printf(" count: %9d\n", metric.Count())
+ case Gauge:
+ l.Printf("gauge %s\n", name)
+ l.Printf(" value: %9d\n", metric.Value())
+ case GaugeFloat64:
+ l.Printf("gauge %s\n", name)
+ l.Printf(" value: %f\n", metric.Value())
+ case Healthcheck:
+ metric.Check()
+ l.Printf("healthcheck %s\n", name)
+ l.Printf(" error: %v\n", metric.Error())
+ case Histogram:
+ h := metric.Snapshot()
+ ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
+ l.Printf("histogram %s\n", name)
+ l.Printf(" count: %9d\n", h.Count())
+ l.Printf(" min: %9d\n", h.Min())
+ l.Printf(" max: %9d\n", h.Max())
+ l.Printf(" mean: %12.2f\n", h.Mean())
+ l.Printf(" stddev: %12.2f\n", h.StdDev())
+ l.Printf(" median: %12.2f\n", ps[0])
+ l.Printf(" 75%%: %12.2f\n", ps[1])
+ l.Printf(" 95%%: %12.2f\n", ps[2])
+ l.Printf(" 99%%: %12.2f\n", ps[3])
+ l.Printf(" 99.9%%: %12.2f\n", ps[4])
+ case Meter:
+ m := metric.Snapshot()
+ l.Printf("meter %s\n", name)
+ l.Printf(" count: %9d\n", m.Count())
+ l.Printf(" 1-min rate: %12.2f\n", m.Rate1())
+ l.Printf(" 5-min rate: %12.2f\n", m.Rate5())
+ l.Printf(" 15-min rate: %12.2f\n", m.Rate15())
+ l.Printf(" mean rate: %12.2f\n", m.RateMean())
+ case Timer:
+ t := metric.Snapshot()
+ ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
+ l.Printf("timer %s\n", name)
+ l.Printf(" count: %9d\n", t.Count())
+ l.Printf(" min: %12.2f%s\n", float64(t.Min())/du, duSuffix)
+ l.Printf(" max: %12.2f%s\n", float64(t.Max())/du, duSuffix)
+ l.Printf(" mean: %12.2f%s\n", t.Mean()/du, duSuffix)
+ l.Printf(" stddev: %12.2f%s\n", t.StdDev()/du, duSuffix)
+ l.Printf(" median: %12.2f%s\n", ps[0]/du, duSuffix)
+ l.Printf(" 75%%: %12.2f%s\n", ps[1]/du, duSuffix)
+ l.Printf(" 95%%: %12.2f%s\n", ps[2]/du, duSuffix)
+ l.Printf(" 99%%: %12.2f%s\n", ps[3]/du, duSuffix)
+ l.Printf(" 99.9%%: %12.2f%s\n", ps[4]/du, duSuffix)
+ l.Printf(" 1-min rate: %12.2f\n", t.Rate1())
+ l.Printf(" 5-min rate: %12.2f\n", t.Rate5())
+ l.Printf(" 15-min rate: %12.2f\n", t.Rate15())
+ l.Printf(" mean rate: %12.2f\n", t.RateMean())
+ }
+ })
+ }
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/memory.md b/vendor/github.com/rcrowley/go-metrics/memory.md
new file mode 100644
index 000000000..47454f54b
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/memory.md
@@ -0,0 +1,285 @@
+Memory usage
+============
+
+(Highly unscientific.)
+
+Command used to gather static memory usage:
+
+```sh
+grep ^Vm "/proc/$(ps fax | grep [m]etrics-bench | awk '{print $1}')/status"
+```
+
+Program used to gather baseline memory usage:
+
+```go
+package main
+
+import "time"
+
+func main() {
+ time.Sleep(600e9)
+}
+```
+
+Baseline
+--------
+
+```
+VmPeak: 42604 kB
+VmSize: 42604 kB
+VmLck: 0 kB
+VmHWM: 1120 kB
+VmRSS: 1120 kB
+VmData: 35460 kB
+VmStk: 136 kB
+VmExe: 1020 kB
+VmLib: 1848 kB
+VmPTE: 36 kB
+VmSwap: 0 kB
+```
+
+Program used to gather metric memory usage (with other metrics being similar):
+
+```go
+package main
+
+import (
+ "fmt"
+ "metrics"
+ "time"
+)
+
+func main() {
+ fmt.Sprintf("foo")
+ metrics.NewRegistry()
+ time.Sleep(600e9)
+}
+```
+
+1000 counters registered
+------------------------
+
+```
+VmPeak: 44016 kB
+VmSize: 44016 kB
+VmLck: 0 kB
+VmHWM: 1928 kB
+VmRSS: 1928 kB
+VmData: 36868 kB
+VmStk: 136 kB
+VmExe: 1024 kB
+VmLib: 1848 kB
+VmPTE: 40 kB
+VmSwap: 0 kB
+```
+
+**1.412 kB virtual, TODO 0.808 kB resident per counter.**
+
+100000 counters registered
+--------------------------
+
+```
+VmPeak: 55024 kB
+VmSize: 55024 kB
+VmLck: 0 kB
+VmHWM: 12440 kB
+VmRSS: 12440 kB
+VmData: 47876 kB
+VmStk: 136 kB
+VmExe: 1024 kB
+VmLib: 1848 kB
+VmPTE: 64 kB
+VmSwap: 0 kB
+```
+
+**0.1242 kB virtual, 0.1132 kB resident per counter.**
+
+1000 gauges registered
+----------------------
+
+```
+VmPeak: 44012 kB
+VmSize: 44012 kB
+VmLck: 0 kB
+VmHWM: 1928 kB
+VmRSS: 1928 kB
+VmData: 36868 kB
+VmStk: 136 kB
+VmExe: 1020 kB
+VmLib: 1848 kB
+VmPTE: 40 kB
+VmSwap: 0 kB
+```
+
+**1.408 kB virtual, 0.808 kB resident per counter.**
+
+100000 gauges registered
+------------------------
+
+```
+VmPeak: 55020 kB
+VmSize: 55020 kB
+VmLck: 0 kB
+VmHWM: 12432 kB
+VmRSS: 12432 kB
+VmData: 47876 kB
+VmStk: 136 kB
+VmExe: 1020 kB
+VmLib: 1848 kB
+VmPTE: 60 kB
+VmSwap: 0 kB
+```
+
+**0.12416 kB virtual, 0.11312 resident per gauge.**
+
+1000 histograms with a uniform sample size of 1028
+--------------------------------------------------
+
+```
+VmPeak: 72272 kB
+VmSize: 72272 kB
+VmLck: 0 kB
+VmHWM: 16204 kB
+VmRSS: 16204 kB
+VmData: 65100 kB
+VmStk: 136 kB
+VmExe: 1048 kB
+VmLib: 1848 kB
+VmPTE: 80 kB
+VmSwap: 0 kB
+```
+
+**29.668 kB virtual, TODO 15.084 resident per histogram.**
+
+10000 histograms with a uniform sample size of 1028
+---------------------------------------------------
+
+```
+VmPeak: 256912 kB
+VmSize: 256912 kB
+VmLck: 0 kB
+VmHWM: 146204 kB
+VmRSS: 146204 kB
+VmData: 249740 kB
+VmStk: 136 kB
+VmExe: 1048 kB
+VmLib: 1848 kB
+VmPTE: 448 kB
+VmSwap: 0 kB
+```
+
+**21.4308 kB virtual, 14.5084 kB resident per histogram.**
+
+50000 histograms with a uniform sample size of 1028
+---------------------------------------------------
+
+```
+VmPeak: 908112 kB
+VmSize: 908112 kB
+VmLck: 0 kB
+VmHWM: 645832 kB
+VmRSS: 645588 kB
+VmData: 900940 kB
+VmStk: 136 kB
+VmExe: 1048 kB
+VmLib: 1848 kB
+VmPTE: 1716 kB
+VmSwap: 1544 kB
+```
+
+**17.31016 kB virtual, 12.88936 kB resident per histogram.**
+
+1000 histograms with an exponentially-decaying sample size of 1028 and alpha of 0.015
+-------------------------------------------------------------------------------------
+
+```
+VmPeak: 62480 kB
+VmSize: 62480 kB
+VmLck: 0 kB
+VmHWM: 11572 kB
+VmRSS: 11572 kB
+VmData: 55308 kB
+VmStk: 136 kB
+VmExe: 1048 kB
+VmLib: 1848 kB
+VmPTE: 64 kB
+VmSwap: 0 kB
+```
+
+**19.876 kB virtual, 10.452 kB resident per histogram.**
+
+10000 histograms with an exponentially-decaying sample size of 1028 and alpha of 0.015
+--------------------------------------------------------------------------------------
+
+```
+VmPeak: 153296 kB
+VmSize: 153296 kB
+VmLck: 0 kB
+VmHWM: 101176 kB
+VmRSS: 101176 kB
+VmData: 146124 kB
+VmStk: 136 kB
+VmExe: 1048 kB
+VmLib: 1848 kB
+VmPTE: 240 kB
+VmSwap: 0 kB
+```
+
+**11.0692 kB virtual, 10.0056 kB resident per histogram.**
+
+50000 histograms with an exponentially-decaying sample size of 1028 and alpha of 0.015
+--------------------------------------------------------------------------------------
+
+```
+VmPeak: 557264 kB
+VmSize: 557264 kB
+VmLck: 0 kB
+VmHWM: 501056 kB
+VmRSS: 501056 kB
+VmData: 550092 kB
+VmStk: 136 kB
+VmExe: 1048 kB
+VmLib: 1848 kB
+VmPTE: 1032 kB
+VmSwap: 0 kB
+```
+
+**10.2932 kB virtual, 9.99872 kB resident per histogram.**
+
+1000 meters
+-----------
+
+```
+VmPeak: 74504 kB
+VmSize: 74504 kB
+VmLck: 0 kB
+VmHWM: 24124 kB
+VmRSS: 24124 kB
+VmData: 67340 kB
+VmStk: 136 kB
+VmExe: 1040 kB
+VmLib: 1848 kB
+VmPTE: 92 kB
+VmSwap: 0 kB
+```
+
+**31.9 kB virtual, 23.004 kB resident per meter.**
+
+10000 meters
+------------
+
+```
+VmPeak: 278920 kB
+VmSize: 278920 kB
+VmLck: 0 kB
+VmHWM: 227300 kB
+VmRSS: 227300 kB
+VmData: 271756 kB
+VmStk: 136 kB
+VmExe: 1040 kB
+VmLib: 1848 kB
+VmPTE: 488 kB
+VmSwap: 0 kB
+```
+
+**23.6316 kB virtual, 22.618 kB resident per meter.**
diff --git a/vendor/github.com/rcrowley/go-metrics/meter.go b/vendor/github.com/rcrowley/go-metrics/meter.go
new file mode 100644
index 000000000..223669bcb
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/meter.go
@@ -0,0 +1,251 @@
+package metrics
+
+import (
+ "math"
+ "sync"
+ "sync/atomic"
+ "time"
+)
+
+// Meters count events to produce exponentially-weighted moving average rates
+// at one-, five-, and fifteen-minutes and a mean rate.
+type Meter interface {
+ Count() int64
+ Mark(int64)
+ Rate1() float64
+ Rate5() float64
+ Rate15() float64
+ RateMean() float64
+ Snapshot() Meter
+ Stop()
+}
+
+// GetOrRegisterMeter returns an existing Meter or constructs and registers a
+// new StandardMeter.
+// Be sure to unregister the meter from the registry once it is of no use to
+// allow for garbage collection.
+func GetOrRegisterMeter(name string, r Registry) Meter {
+ if nil == r {
+ r = DefaultRegistry
+ }
+ return r.GetOrRegister(name, NewMeter).(Meter)
+}
+
+// NewMeter constructs a new StandardMeter and launches a goroutine.
+// Be sure to call Stop() once the meter is of no use to allow for garbage collection.
+func NewMeter() Meter {
+ if UseNilMetrics {
+ return NilMeter{}
+ }
+ m := newStandardMeter()
+ arbiter.Lock()
+ defer arbiter.Unlock()
+ arbiter.meters[m] = struct{}{}
+ if !arbiter.started {
+ arbiter.started = true
+ go arbiter.tick()
+ }
+ return m
+}
+
+// NewMeter constructs and registers a new StandardMeter and launches a
+// goroutine.
+// Be sure to unregister the meter from the registry once it is of no use to
+// allow for garbage collection.
+func NewRegisteredMeter(name string, r Registry) Meter {
+ c := NewMeter()
+ if nil == r {
+ r = DefaultRegistry
+ }
+ r.Register(name, c)
+ return c
+}
+
+// MeterSnapshot is a read-only copy of another Meter.
+type MeterSnapshot struct {
+ count int64
+ rate1, rate5, rate15, rateMean uint64
+}
+
+// Count returns the count of events at the time the snapshot was taken.
+func (m *MeterSnapshot) Count() int64 { return m.count }
+
+// Mark panics.
+func (*MeterSnapshot) Mark(n int64) {
+ panic("Mark called on a MeterSnapshot")
+}
+
+// Rate1 returns the one-minute moving average rate of events per second at the
+// time the snapshot was taken.
+func (m *MeterSnapshot) Rate1() float64 { return math.Float64frombits(m.rate1) }
+
+// Rate5 returns the five-minute moving average rate of events per second at
+// the time the snapshot was taken.
+func (m *MeterSnapshot) Rate5() float64 { return math.Float64frombits(m.rate5) }
+
+// Rate15 returns the fifteen-minute moving average rate of events per second
+// at the time the snapshot was taken.
+func (m *MeterSnapshot) Rate15() float64 { return math.Float64frombits(m.rate15) }
+
+// RateMean returns the meter's mean rate of events per second at the time the
+// snapshot was taken.
+func (m *MeterSnapshot) RateMean() float64 { return math.Float64frombits(m.rateMean) }
+
+// Snapshot returns the snapshot.
+func (m *MeterSnapshot) Snapshot() Meter { return m }
+
+// Stop is a no-op.
+func (m *MeterSnapshot) Stop() {}
+
+// NilMeter is a no-op Meter.
+type NilMeter struct{}
+
+// Count is a no-op.
+func (NilMeter) Count() int64 { return 0 }
+
+// Mark is a no-op.
+func (NilMeter) Mark(n int64) {}
+
+// Rate1 is a no-op.
+func (NilMeter) Rate1() float64 { return 0.0 }
+
+// Rate5 is a no-op.
+func (NilMeter) Rate5() float64 { return 0.0 }
+
+// Rate15is a no-op.
+func (NilMeter) Rate15() float64 { return 0.0 }
+
+// RateMean is a no-op.
+func (NilMeter) RateMean() float64 { return 0.0 }
+
+// Snapshot is a no-op.
+func (NilMeter) Snapshot() Meter { return NilMeter{} }
+
+// Stop is a no-op.
+func (NilMeter) Stop() {}
+
+// StandardMeter is the standard implementation of a Meter.
+type StandardMeter struct {
+ snapshot *MeterSnapshot
+ a1, a5, a15 EWMA
+ startTime time.Time
+ stopped uint32
+}
+
+func newStandardMeter() *StandardMeter {
+ return &StandardMeter{
+ snapshot: &MeterSnapshot{},
+ a1: NewEWMA1(),
+ a5: NewEWMA5(),
+ a15: NewEWMA15(),
+ startTime: time.Now(),
+ }
+}
+
+// Stop stops the meter, Mark() will be a no-op if you use it after being stopped.
+func (m *StandardMeter) Stop() {
+ if atomic.CompareAndSwapUint32(&m.stopped, 0, 1) {
+ arbiter.Lock()
+ delete(arbiter.meters, m)
+ arbiter.Unlock()
+ }
+}
+
+// Count returns the number of events recorded.
+func (m *StandardMeter) Count() int64 {
+ return atomic.LoadInt64(&m.snapshot.count)
+}
+
+// Mark records the occurance of n events.
+func (m *StandardMeter) Mark(n int64) {
+ if atomic.LoadUint32(&m.stopped) == 1 {
+ return
+ }
+
+ atomic.AddInt64(&m.snapshot.count, n)
+
+ m.a1.Update(n)
+ m.a5.Update(n)
+ m.a15.Update(n)
+ m.updateSnapshot()
+}
+
+// Rate1 returns the one-minute moving average rate of events per second.
+func (m *StandardMeter) Rate1() float64 {
+ return math.Float64frombits(atomic.LoadUint64(&m.snapshot.rate1))
+}
+
+// Rate5 returns the five-minute moving average rate of events per second.
+func (m *StandardMeter) Rate5() float64 {
+ return math.Float64frombits(atomic.LoadUint64(&m.snapshot.rate5))
+}
+
+// Rate15 returns the fifteen-minute moving average rate of events per second.
+func (m *StandardMeter) Rate15() float64 {
+ return math.Float64frombits(atomic.LoadUint64(&m.snapshot.rate15))
+}
+
+// RateMean returns the meter's mean rate of events per second.
+func (m *StandardMeter) RateMean() float64 {
+ return math.Float64frombits(atomic.LoadUint64(&m.snapshot.rateMean))
+}
+
+// Snapshot returns a read-only copy of the meter.
+func (m *StandardMeter) Snapshot() Meter {
+ copiedSnapshot := MeterSnapshot{
+ count: atomic.LoadInt64(&m.snapshot.count),
+ rate1: atomic.LoadUint64(&m.snapshot.rate1),
+ rate5: atomic.LoadUint64(&m.snapshot.rate5),
+ rate15: atomic.LoadUint64(&m.snapshot.rate15),
+ rateMean: atomic.LoadUint64(&m.snapshot.rateMean),
+ }
+ return &copiedSnapshot
+}
+
+func (m *StandardMeter) updateSnapshot() {
+ rate1 := math.Float64bits(m.a1.Rate())
+ rate5 := math.Float64bits(m.a5.Rate())
+ rate15 := math.Float64bits(m.a15.Rate())
+ rateMean := math.Float64bits(float64(m.Count()) / time.Since(m.startTime).Seconds())
+
+ atomic.StoreUint64(&m.snapshot.rate1, rate1)
+ atomic.StoreUint64(&m.snapshot.rate5, rate5)
+ atomic.StoreUint64(&m.snapshot.rate15, rate15)
+ atomic.StoreUint64(&m.snapshot.rateMean, rateMean)
+}
+
+func (m *StandardMeter) tick() {
+ m.a1.Tick()
+ m.a5.Tick()
+ m.a15.Tick()
+ m.updateSnapshot()
+}
+
+// meterArbiter ticks meters every 5s from a single goroutine.
+// meters are references in a set for future stopping.
+type meterArbiter struct {
+ sync.RWMutex
+ started bool
+ meters map[*StandardMeter]struct{}
+ ticker *time.Ticker
+}
+
+var arbiter = meterArbiter{ticker: time.NewTicker(5e9), meters: make(map[*StandardMeter]struct{})}
+
+// Ticks meters on the scheduled interval
+func (ma *meterArbiter) tick() {
+ for {
+ select {
+ case <-ma.ticker.C:
+ ma.tickMeters()
+ }
+ }
+}
+
+func (ma *meterArbiter) tickMeters() {
+ ma.RLock()
+ defer ma.RUnlock()
+ for meter := range ma.meters {
+ meter.tick()
+ }
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/metrics.go b/vendor/github.com/rcrowley/go-metrics/metrics.go
new file mode 100644
index 000000000..b97a49ed1
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/metrics.go
@@ -0,0 +1,13 @@
+// Go port of Coda Hale's Metrics library
+//
+//
+//
+// Coda Hale's original work:
+package metrics
+
+// UseNilMetrics is checked by the constructor functions for all of the
+// standard metrics. If it is true, the metric returned is a stub.
+//
+// This global kill-switch helps quantify the observer effect and makes
+// for less cluttered pprof profiles.
+var UseNilMetrics bool = false
diff --git a/vendor/github.com/rcrowley/go-metrics/opentsdb.go b/vendor/github.com/rcrowley/go-metrics/opentsdb.go
new file mode 100644
index 000000000..266b6c93d
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/opentsdb.go
@@ -0,0 +1,119 @@
+package metrics
+
+import (
+ "bufio"
+ "fmt"
+ "log"
+ "net"
+ "os"
+ "strings"
+ "time"
+)
+
+var shortHostName string = ""
+
+// OpenTSDBConfig provides a container with configuration parameters for
+// the OpenTSDB exporter
+type OpenTSDBConfig struct {
+ Addr *net.TCPAddr // Network address to connect to
+ Registry Registry // Registry to be exported
+ FlushInterval time.Duration // Flush interval
+ DurationUnit time.Duration // Time conversion unit for durations
+ Prefix string // Prefix to be prepended to metric names
+}
+
+// OpenTSDB is a blocking exporter function which reports metrics in r
+// to a TSDB server located at addr, flushing them every d duration
+// and prepending metric names with prefix.
+func OpenTSDB(r Registry, d time.Duration, prefix string, addr *net.TCPAddr) {
+ OpenTSDBWithConfig(OpenTSDBConfig{
+ Addr: addr,
+ Registry: r,
+ FlushInterval: d,
+ DurationUnit: time.Nanosecond,
+ Prefix: prefix,
+ })
+}
+
+// OpenTSDBWithConfig is a blocking exporter function just like OpenTSDB,
+// but it takes a OpenTSDBConfig instead.
+func OpenTSDBWithConfig(c OpenTSDBConfig) {
+ for _ = range time.Tick(c.FlushInterval) {
+ if err := openTSDB(&c); nil != err {
+ log.Println(err)
+ }
+ }
+}
+
+func getShortHostname() string {
+ if shortHostName == "" {
+ host, _ := os.Hostname()
+ if index := strings.Index(host, "."); index > 0 {
+ shortHostName = host[:index]
+ } else {
+ shortHostName = host
+ }
+ }
+ return shortHostName
+}
+
+func openTSDB(c *OpenTSDBConfig) error {
+ shortHostname := getShortHostname()
+ now := time.Now().Unix()
+ du := float64(c.DurationUnit)
+ conn, err := net.DialTCP("tcp", nil, c.Addr)
+ if nil != err {
+ return err
+ }
+ defer conn.Close()
+ w := bufio.NewWriter(conn)
+ c.Registry.Each(func(name string, i interface{}) {
+ switch metric := i.(type) {
+ case Counter:
+ fmt.Fprintf(w, "put %s.%s.count %d %d host=%s\n", c.Prefix, name, now, metric.Count(), shortHostname)
+ case Gauge:
+ fmt.Fprintf(w, "put %s.%s.value %d %d host=%s\n", c.Prefix, name, now, metric.Value(), shortHostname)
+ case GaugeFloat64:
+ fmt.Fprintf(w, "put %s.%s.value %d %f host=%s\n", c.Prefix, name, now, metric.Value(), shortHostname)
+ case Histogram:
+ h := metric.Snapshot()
+ ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
+ fmt.Fprintf(w, "put %s.%s.count %d %d host=%s\n", c.Prefix, name, now, h.Count(), shortHostname)
+ fmt.Fprintf(w, "put %s.%s.min %d %d host=%s\n", c.Prefix, name, now, h.Min(), shortHostname)
+ fmt.Fprintf(w, "put %s.%s.max %d %d host=%s\n", c.Prefix, name, now, h.Max(), shortHostname)
+ fmt.Fprintf(w, "put %s.%s.mean %d %.2f host=%s\n", c.Prefix, name, now, h.Mean(), shortHostname)
+ fmt.Fprintf(w, "put %s.%s.std-dev %d %.2f host=%s\n", c.Prefix, name, now, h.StdDev(), shortHostname)
+ fmt.Fprintf(w, "put %s.%s.50-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[0], shortHostname)
+ fmt.Fprintf(w, "put %s.%s.75-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[1], shortHostname)
+ fmt.Fprintf(w, "put %s.%s.95-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[2], shortHostname)
+ fmt.Fprintf(w, "put %s.%s.99-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[3], shortHostname)
+ fmt.Fprintf(w, "put %s.%s.999-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[4], shortHostname)
+ case Meter:
+ m := metric.Snapshot()
+ fmt.Fprintf(w, "put %s.%s.count %d %d host=%s\n", c.Prefix, name, now, m.Count(), shortHostname)
+ fmt.Fprintf(w, "put %s.%s.one-minute %d %.2f host=%s\n", c.Prefix, name, now, m.Rate1(), shortHostname)
+ fmt.Fprintf(w, "put %s.%s.five-minute %d %.2f host=%s\n", c.Prefix, name, now, m.Rate5(), shortHostname)
+ fmt.Fprintf(w, "put %s.%s.fifteen-minute %d %.2f host=%s\n", c.Prefix, name, now, m.Rate15(), shortHostname)
+ fmt.Fprintf(w, "put %s.%s.mean %d %.2f host=%s\n", c.Prefix, name, now, m.RateMean(), shortHostname)
+ case Timer:
+ t := metric.Snapshot()
+ ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
+ fmt.Fprintf(w, "put %s.%s.count %d %d host=%s\n", c.Prefix, name, now, t.Count(), shortHostname)
+ fmt.Fprintf(w, "put %s.%s.min %d %d host=%s\n", c.Prefix, name, now, t.Min()/int64(du), shortHostname)
+ fmt.Fprintf(w, "put %s.%s.max %d %d host=%s\n", c.Prefix, name, now, t.Max()/int64(du), shortHostname)
+ fmt.Fprintf(w, "put %s.%s.mean %d %.2f host=%s\n", c.Prefix, name, now, t.Mean()/du, shortHostname)
+ fmt.Fprintf(w, "put %s.%s.std-dev %d %.2f host=%s\n", c.Prefix, name, now, t.StdDev()/du, shortHostname)
+ fmt.Fprintf(w, "put %s.%s.50-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[0]/du, shortHostname)
+ fmt.Fprintf(w, "put %s.%s.75-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[1]/du, shortHostname)
+ fmt.Fprintf(w, "put %s.%s.95-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[2]/du, shortHostname)
+ fmt.Fprintf(w, "put %s.%s.99-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[3]/du, shortHostname)
+ fmt.Fprintf(w, "put %s.%s.999-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[4]/du, shortHostname)
+ fmt.Fprintf(w, "put %s.%s.one-minute %d %.2f host=%s\n", c.Prefix, name, now, t.Rate1(), shortHostname)
+ fmt.Fprintf(w, "put %s.%s.five-minute %d %.2f host=%s\n", c.Prefix, name, now, t.Rate5(), shortHostname)
+ fmt.Fprintf(w, "put %s.%s.fifteen-minute %d %.2f host=%s\n", c.Prefix, name, now, t.Rate15(), shortHostname)
+ fmt.Fprintf(w, "put %s.%s.mean-rate %d %.2f host=%s\n", c.Prefix, name, now, t.RateMean(), shortHostname)
+ }
+ w.Flush()
+ })
+ return nil
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/registry.go b/vendor/github.com/rcrowley/go-metrics/registry.go
new file mode 100644
index 000000000..b3bab64e1
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/registry.go
@@ -0,0 +1,363 @@
+package metrics
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+ "sync"
+)
+
+// DuplicateMetric is the error returned by Registry.Register when a metric
+// already exists. If you mean to Register that metric you must first
+// Unregister the existing metric.
+type DuplicateMetric string
+
+func (err DuplicateMetric) Error() string {
+ return fmt.Sprintf("duplicate metric: %s", string(err))
+}
+
+// A Registry holds references to a set of metrics by name and can iterate
+// over them, calling callback functions provided by the user.
+//
+// This is an interface so as to encourage other structs to implement
+// the Registry API as appropriate.
+type Registry interface {
+
+ // Call the given function for each registered metric.
+ Each(func(string, interface{}))
+
+ // Get the metric by the given name or nil if none is registered.
+ Get(string) interface{}
+
+ // GetAll metrics in the Registry.
+ GetAll() map[string]map[string]interface{}
+
+ // Gets an existing metric or registers the given one.
+ // The interface can be the metric to register if not found in registry,
+ // or a function returning the metric for lazy instantiation.
+ GetOrRegister(string, interface{}) interface{}
+
+ // Register the given metric under the given name.
+ Register(string, interface{}) error
+
+ // Run all registered healthchecks.
+ RunHealthchecks()
+
+ // Unregister the metric with the given name.
+ Unregister(string)
+
+ // Unregister all metrics. (Mostly for testing.)
+ UnregisterAll()
+}
+
+// The standard implementation of a Registry is a mutex-protected map
+// of names to metrics.
+type StandardRegistry struct {
+ metrics map[string]interface{}
+ mutex sync.RWMutex
+}
+
+// Create a new registry.
+func NewRegistry() Registry {
+ return &StandardRegistry{metrics: make(map[string]interface{})}
+}
+
+// Call the given function for each registered metric.
+func (r *StandardRegistry) Each(f func(string, interface{})) {
+ for name, i := range r.registered() {
+ f(name, i)
+ }
+}
+
+// Get the metric by the given name or nil if none is registered.
+func (r *StandardRegistry) Get(name string) interface{} {
+ r.mutex.RLock()
+ defer r.mutex.RUnlock()
+ return r.metrics[name]
+}
+
+// Gets an existing metric or creates and registers a new one. Threadsafe
+// alternative to calling Get and Register on failure.
+// The interface can be the metric to register if not found in registry,
+// or a function returning the metric for lazy instantiation.
+func (r *StandardRegistry) GetOrRegister(name string, i interface{}) interface{} {
+ // access the read lock first which should be re-entrant
+ r.mutex.RLock()
+ metric, ok := r.metrics[name]
+ r.mutex.RUnlock()
+ if ok {
+ return metric
+ }
+
+ // only take the write lock if we'll be modifying the metrics map
+ r.mutex.Lock()
+ defer r.mutex.Unlock()
+ if metric, ok := r.metrics[name]; ok {
+ return metric
+ }
+ if v := reflect.ValueOf(i); v.Kind() == reflect.Func {
+ i = v.Call(nil)[0].Interface()
+ }
+ r.register(name, i)
+ return i
+}
+
+// Register the given metric under the given name. Returns a DuplicateMetric
+// if a metric by the given name is already registered.
+func (r *StandardRegistry) Register(name string, i interface{}) error {
+ r.mutex.Lock()
+ defer r.mutex.Unlock()
+ return r.register(name, i)
+}
+
+// Run all registered healthchecks.
+func (r *StandardRegistry) RunHealthchecks() {
+ r.mutex.RLock()
+ defer r.mutex.RUnlock()
+ for _, i := range r.metrics {
+ if h, ok := i.(Healthcheck); ok {
+ h.Check()
+ }
+ }
+}
+
+// GetAll metrics in the Registry
+func (r *StandardRegistry) GetAll() map[string]map[string]interface{} {
+ data := make(map[string]map[string]interface{})
+ r.Each(func(name string, i interface{}) {
+ values := make(map[string]interface{})
+ switch metric := i.(type) {
+ case Counter:
+ values["count"] = metric.Count()
+ case Gauge:
+ values["value"] = metric.Value()
+ case GaugeFloat64:
+ values["value"] = metric.Value()
+ case Healthcheck:
+ values["error"] = nil
+ metric.Check()
+ if err := metric.Error(); nil != err {
+ values["error"] = metric.Error().Error()
+ }
+ case Histogram:
+ h := metric.Snapshot()
+ ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
+ values["count"] = h.Count()
+ values["min"] = h.Min()
+ values["max"] = h.Max()
+ values["mean"] = h.Mean()
+ values["stddev"] = h.StdDev()
+ values["median"] = ps[0]
+ values["75%"] = ps[1]
+ values["95%"] = ps[2]
+ values["99%"] = ps[3]
+ values["99.9%"] = ps[4]
+ case Meter:
+ m := metric.Snapshot()
+ values["count"] = m.Count()
+ values["1m.rate"] = m.Rate1()
+ values["5m.rate"] = m.Rate5()
+ values["15m.rate"] = m.Rate15()
+ values["mean.rate"] = m.RateMean()
+ case Timer:
+ t := metric.Snapshot()
+ ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
+ values["count"] = t.Count()
+ values["min"] = t.Min()
+ values["max"] = t.Max()
+ values["mean"] = t.Mean()
+ values["stddev"] = t.StdDev()
+ values["median"] = ps[0]
+ values["75%"] = ps[1]
+ values["95%"] = ps[2]
+ values["99%"] = ps[3]
+ values["99.9%"] = ps[4]
+ values["1m.rate"] = t.Rate1()
+ values["5m.rate"] = t.Rate5()
+ values["15m.rate"] = t.Rate15()
+ values["mean.rate"] = t.RateMean()
+ }
+ data[name] = values
+ })
+ return data
+}
+
+// Unregister the metric with the given name.
+func (r *StandardRegistry) Unregister(name string) {
+ r.mutex.Lock()
+ defer r.mutex.Unlock()
+ r.stop(name)
+ delete(r.metrics, name)
+}
+
+// Unregister all metrics. (Mostly for testing.)
+func (r *StandardRegistry) UnregisterAll() {
+ r.mutex.Lock()
+ defer r.mutex.Unlock()
+ for name, _ := range r.metrics {
+ r.stop(name)
+ delete(r.metrics, name)
+ }
+}
+
+func (r *StandardRegistry) register(name string, i interface{}) error {
+ if _, ok := r.metrics[name]; ok {
+ return DuplicateMetric(name)
+ }
+ switch i.(type) {
+ case Counter, Gauge, GaugeFloat64, Healthcheck, Histogram, Meter, Timer:
+ r.metrics[name] = i
+ }
+ return nil
+}
+
+func (r *StandardRegistry) registered() map[string]interface{} {
+ r.mutex.Lock()
+ defer r.mutex.Unlock()
+ metrics := make(map[string]interface{}, len(r.metrics))
+ for name, i := range r.metrics {
+ metrics[name] = i
+ }
+ return metrics
+}
+
+func (r *StandardRegistry) stop(name string) {
+ if i, ok := r.metrics[name]; ok {
+ if s, ok := i.(Stoppable); ok {
+ s.Stop()
+ }
+ }
+}
+
+// Stoppable defines the metrics which has to be stopped.
+type Stoppable interface {
+ Stop()
+}
+
+type PrefixedRegistry struct {
+ underlying Registry
+ prefix string
+}
+
+func NewPrefixedRegistry(prefix string) Registry {
+ return &PrefixedRegistry{
+ underlying: NewRegistry(),
+ prefix: prefix,
+ }
+}
+
+func NewPrefixedChildRegistry(parent Registry, prefix string) Registry {
+ return &PrefixedRegistry{
+ underlying: parent,
+ prefix: prefix,
+ }
+}
+
+// Call the given function for each registered metric.
+func (r *PrefixedRegistry) Each(fn func(string, interface{})) {
+ wrappedFn := func(prefix string) func(string, interface{}) {
+ return func(name string, iface interface{}) {
+ if strings.HasPrefix(name, prefix) {
+ fn(name, iface)
+ } else {
+ return
+ }
+ }
+ }
+
+ baseRegistry, prefix := findPrefix(r, "")
+ baseRegistry.Each(wrappedFn(prefix))
+}
+
+func findPrefix(registry Registry, prefix string) (Registry, string) {
+ switch r := registry.(type) {
+ case *PrefixedRegistry:
+ return findPrefix(r.underlying, r.prefix+prefix)
+ case *StandardRegistry:
+ return r, prefix
+ }
+ return nil, ""
+}
+
+// Get the metric by the given name or nil if none is registered.
+func (r *PrefixedRegistry) Get(name string) interface{} {
+ realName := r.prefix + name
+ return r.underlying.Get(realName)
+}
+
+// Gets an existing metric or registers the given one.
+// The interface can be the metric to register if not found in registry,
+// or a function returning the metric for lazy instantiation.
+func (r *PrefixedRegistry) GetOrRegister(name string, metric interface{}) interface{} {
+ realName := r.prefix + name
+ return r.underlying.GetOrRegister(realName, metric)
+}
+
+// Register the given metric under the given name. The name will be prefixed.
+func (r *PrefixedRegistry) Register(name string, metric interface{}) error {
+ realName := r.prefix + name
+ return r.underlying.Register(realName, metric)
+}
+
+// Run all registered healthchecks.
+func (r *PrefixedRegistry) RunHealthchecks() {
+ r.underlying.RunHealthchecks()
+}
+
+// GetAll metrics in the Registry
+func (r *PrefixedRegistry) GetAll() map[string]map[string]interface{} {
+ return r.underlying.GetAll()
+}
+
+// Unregister the metric with the given name. The name will be prefixed.
+func (r *PrefixedRegistry) Unregister(name string) {
+ realName := r.prefix + name
+ r.underlying.Unregister(realName)
+}
+
+// Unregister all metrics. (Mostly for testing.)
+func (r *PrefixedRegistry) UnregisterAll() {
+ r.underlying.UnregisterAll()
+}
+
+var DefaultRegistry Registry = NewRegistry()
+
+// Call the given function for each registered metric.
+func Each(f func(string, interface{})) {
+ DefaultRegistry.Each(f)
+}
+
+// Get the metric by the given name or nil if none is registered.
+func Get(name string) interface{} {
+ return DefaultRegistry.Get(name)
+}
+
+// Gets an existing metric or creates and registers a new one. Threadsafe
+// alternative to calling Get and Register on failure.
+func GetOrRegister(name string, i interface{}) interface{} {
+ return DefaultRegistry.GetOrRegister(name, i)
+}
+
+// Register the given metric under the given name. Returns a DuplicateMetric
+// if a metric by the given name is already registered.
+func Register(name string, i interface{}) error {
+ return DefaultRegistry.Register(name, i)
+}
+
+// Register the given metric under the given name. Panics if a metric by the
+// given name is already registered.
+func MustRegister(name string, i interface{}) {
+ if err := Register(name, i); err != nil {
+ panic(err)
+ }
+}
+
+// Run all registered healthchecks.
+func RunHealthchecks() {
+ DefaultRegistry.RunHealthchecks()
+}
+
+// Unregister the metric with the given name.
+func Unregister(name string) {
+ DefaultRegistry.Unregister(name)
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/runtime.go b/vendor/github.com/rcrowley/go-metrics/runtime.go
new file mode 100644
index 000000000..11c6b785a
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/runtime.go
@@ -0,0 +1,212 @@
+package metrics
+
+import (
+ "runtime"
+ "runtime/pprof"
+ "time"
+)
+
+var (
+ memStats runtime.MemStats
+ runtimeMetrics struct {
+ MemStats struct {
+ Alloc Gauge
+ BuckHashSys Gauge
+ DebugGC Gauge
+ EnableGC Gauge
+ Frees Gauge
+ HeapAlloc Gauge
+ HeapIdle Gauge
+ HeapInuse Gauge
+ HeapObjects Gauge
+ HeapReleased Gauge
+ HeapSys Gauge
+ LastGC Gauge
+ Lookups Gauge
+ Mallocs Gauge
+ MCacheInuse Gauge
+ MCacheSys Gauge
+ MSpanInuse Gauge
+ MSpanSys Gauge
+ NextGC Gauge
+ NumGC Gauge
+ GCCPUFraction GaugeFloat64
+ PauseNs Histogram
+ PauseTotalNs Gauge
+ StackInuse Gauge
+ StackSys Gauge
+ Sys Gauge
+ TotalAlloc Gauge
+ }
+ NumCgoCall Gauge
+ NumGoroutine Gauge
+ NumThread Gauge
+ ReadMemStats Timer
+ }
+ frees uint64
+ lookups uint64
+ mallocs uint64
+ numGC uint32
+ numCgoCalls int64
+
+ threadCreateProfile = pprof.Lookup("threadcreate")
+)
+
+// Capture new values for the Go runtime statistics exported in
+// runtime.MemStats. This is designed to be called as a goroutine.
+func CaptureRuntimeMemStats(r Registry, d time.Duration) {
+ for _ = range time.Tick(d) {
+ CaptureRuntimeMemStatsOnce(r)
+ }
+}
+
+// Capture new values for the Go runtime statistics exported in
+// runtime.MemStats. This is designed to be called in a background
+// goroutine. Giving a registry which has not been given to
+// RegisterRuntimeMemStats will panic.
+//
+// Be very careful with this because runtime.ReadMemStats calls the C
+// functions runtime·semacquire(&runtime·worldsema) and runtime·stoptheworld()
+// and that last one does what it says on the tin.
+func CaptureRuntimeMemStatsOnce(r Registry) {
+ t := time.Now()
+ runtime.ReadMemStats(&memStats) // This takes 50-200us.
+ runtimeMetrics.ReadMemStats.UpdateSince(t)
+
+ runtimeMetrics.MemStats.Alloc.Update(int64(memStats.Alloc))
+ runtimeMetrics.MemStats.BuckHashSys.Update(int64(memStats.BuckHashSys))
+ if memStats.DebugGC {
+ runtimeMetrics.MemStats.DebugGC.Update(1)
+ } else {
+ runtimeMetrics.MemStats.DebugGC.Update(0)
+ }
+ if memStats.EnableGC {
+ runtimeMetrics.MemStats.EnableGC.Update(1)
+ } else {
+ runtimeMetrics.MemStats.EnableGC.Update(0)
+ }
+
+ runtimeMetrics.MemStats.Frees.Update(int64(memStats.Frees - frees))
+ runtimeMetrics.MemStats.HeapAlloc.Update(int64(memStats.HeapAlloc))
+ runtimeMetrics.MemStats.HeapIdle.Update(int64(memStats.HeapIdle))
+ runtimeMetrics.MemStats.HeapInuse.Update(int64(memStats.HeapInuse))
+ runtimeMetrics.MemStats.HeapObjects.Update(int64(memStats.HeapObjects))
+ runtimeMetrics.MemStats.HeapReleased.Update(int64(memStats.HeapReleased))
+ runtimeMetrics.MemStats.HeapSys.Update(int64(memStats.HeapSys))
+ runtimeMetrics.MemStats.LastGC.Update(int64(memStats.LastGC))
+ runtimeMetrics.MemStats.Lookups.Update(int64(memStats.Lookups - lookups))
+ runtimeMetrics.MemStats.Mallocs.Update(int64(memStats.Mallocs - mallocs))
+ runtimeMetrics.MemStats.MCacheInuse.Update(int64(memStats.MCacheInuse))
+ runtimeMetrics.MemStats.MCacheSys.Update(int64(memStats.MCacheSys))
+ runtimeMetrics.MemStats.MSpanInuse.Update(int64(memStats.MSpanInuse))
+ runtimeMetrics.MemStats.MSpanSys.Update(int64(memStats.MSpanSys))
+ runtimeMetrics.MemStats.NextGC.Update(int64(memStats.NextGC))
+ runtimeMetrics.MemStats.NumGC.Update(int64(memStats.NumGC - numGC))
+ runtimeMetrics.MemStats.GCCPUFraction.Update(gcCPUFraction(&memStats))
+
+ //
+ i := numGC % uint32(len(memStats.PauseNs))
+ ii := memStats.NumGC % uint32(len(memStats.PauseNs))
+ if memStats.NumGC-numGC >= uint32(len(memStats.PauseNs)) {
+ for i = 0; i < uint32(len(memStats.PauseNs)); i++ {
+ runtimeMetrics.MemStats.PauseNs.Update(int64(memStats.PauseNs[i]))
+ }
+ } else {
+ if i > ii {
+ for ; i < uint32(len(memStats.PauseNs)); i++ {
+ runtimeMetrics.MemStats.PauseNs.Update(int64(memStats.PauseNs[i]))
+ }
+ i = 0
+ }
+ for ; i < ii; i++ {
+ runtimeMetrics.MemStats.PauseNs.Update(int64(memStats.PauseNs[i]))
+ }
+ }
+ frees = memStats.Frees
+ lookups = memStats.Lookups
+ mallocs = memStats.Mallocs
+ numGC = memStats.NumGC
+
+ runtimeMetrics.MemStats.PauseTotalNs.Update(int64(memStats.PauseTotalNs))
+ runtimeMetrics.MemStats.StackInuse.Update(int64(memStats.StackInuse))
+ runtimeMetrics.MemStats.StackSys.Update(int64(memStats.StackSys))
+ runtimeMetrics.MemStats.Sys.Update(int64(memStats.Sys))
+ runtimeMetrics.MemStats.TotalAlloc.Update(int64(memStats.TotalAlloc))
+
+ currentNumCgoCalls := numCgoCall()
+ runtimeMetrics.NumCgoCall.Update(currentNumCgoCalls - numCgoCalls)
+ numCgoCalls = currentNumCgoCalls
+
+ runtimeMetrics.NumGoroutine.Update(int64(runtime.NumGoroutine()))
+
+ runtimeMetrics.NumThread.Update(int64(threadCreateProfile.Count()))
+}
+
+// Register runtimeMetrics for the Go runtime statistics exported in runtime and
+// specifically runtime.MemStats. The runtimeMetrics are named by their
+// fully-qualified Go symbols, i.e. runtime.MemStats.Alloc.
+func RegisterRuntimeMemStats(r Registry) {
+ runtimeMetrics.MemStats.Alloc = NewGauge()
+ runtimeMetrics.MemStats.BuckHashSys = NewGauge()
+ runtimeMetrics.MemStats.DebugGC = NewGauge()
+ runtimeMetrics.MemStats.EnableGC = NewGauge()
+ runtimeMetrics.MemStats.Frees = NewGauge()
+ runtimeMetrics.MemStats.HeapAlloc = NewGauge()
+ runtimeMetrics.MemStats.HeapIdle = NewGauge()
+ runtimeMetrics.MemStats.HeapInuse = NewGauge()
+ runtimeMetrics.MemStats.HeapObjects = NewGauge()
+ runtimeMetrics.MemStats.HeapReleased = NewGauge()
+ runtimeMetrics.MemStats.HeapSys = NewGauge()
+ runtimeMetrics.MemStats.LastGC = NewGauge()
+ runtimeMetrics.MemStats.Lookups = NewGauge()
+ runtimeMetrics.MemStats.Mallocs = NewGauge()
+ runtimeMetrics.MemStats.MCacheInuse = NewGauge()
+ runtimeMetrics.MemStats.MCacheSys = NewGauge()
+ runtimeMetrics.MemStats.MSpanInuse = NewGauge()
+ runtimeMetrics.MemStats.MSpanSys = NewGauge()
+ runtimeMetrics.MemStats.NextGC = NewGauge()
+ runtimeMetrics.MemStats.NumGC = NewGauge()
+ runtimeMetrics.MemStats.GCCPUFraction = NewGaugeFloat64()
+ runtimeMetrics.MemStats.PauseNs = NewHistogram(NewExpDecaySample(1028, 0.015))
+ runtimeMetrics.MemStats.PauseTotalNs = NewGauge()
+ runtimeMetrics.MemStats.StackInuse = NewGauge()
+ runtimeMetrics.MemStats.StackSys = NewGauge()
+ runtimeMetrics.MemStats.Sys = NewGauge()
+ runtimeMetrics.MemStats.TotalAlloc = NewGauge()
+ runtimeMetrics.NumCgoCall = NewGauge()
+ runtimeMetrics.NumGoroutine = NewGauge()
+ runtimeMetrics.NumThread = NewGauge()
+ runtimeMetrics.ReadMemStats = NewTimer()
+
+ r.Register("runtime.MemStats.Alloc", runtimeMetrics.MemStats.Alloc)
+ r.Register("runtime.MemStats.BuckHashSys", runtimeMetrics.MemStats.BuckHashSys)
+ r.Register("runtime.MemStats.DebugGC", runtimeMetrics.MemStats.DebugGC)
+ r.Register("runtime.MemStats.EnableGC", runtimeMetrics.MemStats.EnableGC)
+ r.Register("runtime.MemStats.Frees", runtimeMetrics.MemStats.Frees)
+ r.Register("runtime.MemStats.HeapAlloc", runtimeMetrics.MemStats.HeapAlloc)
+ r.Register("runtime.MemStats.HeapIdle", runtimeMetrics.MemStats.HeapIdle)
+ r.Register("runtime.MemStats.HeapInuse", runtimeMetrics.MemStats.HeapInuse)
+ r.Register("runtime.MemStats.HeapObjects", runtimeMetrics.MemStats.HeapObjects)
+ r.Register("runtime.MemStats.HeapReleased", runtimeMetrics.MemStats.HeapReleased)
+ r.Register("runtime.MemStats.HeapSys", runtimeMetrics.MemStats.HeapSys)
+ r.Register("runtime.MemStats.LastGC", runtimeMetrics.MemStats.LastGC)
+ r.Register("runtime.MemStats.Lookups", runtimeMetrics.MemStats.Lookups)
+ r.Register("runtime.MemStats.Mallocs", runtimeMetrics.MemStats.Mallocs)
+ r.Register("runtime.MemStats.MCacheInuse", runtimeMetrics.MemStats.MCacheInuse)
+ r.Register("runtime.MemStats.MCacheSys", runtimeMetrics.MemStats.MCacheSys)
+ r.Register("runtime.MemStats.MSpanInuse", runtimeMetrics.MemStats.MSpanInuse)
+ r.Register("runtime.MemStats.MSpanSys", runtimeMetrics.MemStats.MSpanSys)
+ r.Register("runtime.MemStats.NextGC", runtimeMetrics.MemStats.NextGC)
+ r.Register("runtime.MemStats.NumGC", runtimeMetrics.MemStats.NumGC)
+ r.Register("runtime.MemStats.GCCPUFraction", runtimeMetrics.MemStats.GCCPUFraction)
+ r.Register("runtime.MemStats.PauseNs", runtimeMetrics.MemStats.PauseNs)
+ r.Register("runtime.MemStats.PauseTotalNs", runtimeMetrics.MemStats.PauseTotalNs)
+ r.Register("runtime.MemStats.StackInuse", runtimeMetrics.MemStats.StackInuse)
+ r.Register("runtime.MemStats.StackSys", runtimeMetrics.MemStats.StackSys)
+ r.Register("runtime.MemStats.Sys", runtimeMetrics.MemStats.Sys)
+ r.Register("runtime.MemStats.TotalAlloc", runtimeMetrics.MemStats.TotalAlloc)
+ r.Register("runtime.NumCgoCall", runtimeMetrics.NumCgoCall)
+ r.Register("runtime.NumGoroutine", runtimeMetrics.NumGoroutine)
+ r.Register("runtime.NumThread", runtimeMetrics.NumThread)
+ r.Register("runtime.ReadMemStats", runtimeMetrics.ReadMemStats)
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/runtime_cgo.go b/vendor/github.com/rcrowley/go-metrics/runtime_cgo.go
new file mode 100644
index 000000000..e3391f4e8
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/runtime_cgo.go
@@ -0,0 +1,10 @@
+// +build cgo
+// +build !appengine
+
+package metrics
+
+import "runtime"
+
+func numCgoCall() int64 {
+ return runtime.NumCgoCall()
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/runtime_gccpufraction.go b/vendor/github.com/rcrowley/go-metrics/runtime_gccpufraction.go
new file mode 100644
index 000000000..ca12c05ba
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/runtime_gccpufraction.go
@@ -0,0 +1,9 @@
+// +build go1.5
+
+package metrics
+
+import "runtime"
+
+func gcCPUFraction(memStats *runtime.MemStats) float64 {
+ return memStats.GCCPUFraction
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/runtime_no_cgo.go b/vendor/github.com/rcrowley/go-metrics/runtime_no_cgo.go
new file mode 100644
index 000000000..616a3b475
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/runtime_no_cgo.go
@@ -0,0 +1,7 @@
+// +build !cgo appengine
+
+package metrics
+
+func numCgoCall() int64 {
+ return 0
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/runtime_no_gccpufraction.go b/vendor/github.com/rcrowley/go-metrics/runtime_no_gccpufraction.go
new file mode 100644
index 000000000..be96aa6f1
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/runtime_no_gccpufraction.go
@@ -0,0 +1,9 @@
+// +build !go1.5
+
+package metrics
+
+import "runtime"
+
+func gcCPUFraction(memStats *runtime.MemStats) float64 {
+ return 0
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/sample.go b/vendor/github.com/rcrowley/go-metrics/sample.go
new file mode 100644
index 000000000..fecee5ef6
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/sample.go
@@ -0,0 +1,616 @@
+package metrics
+
+import (
+ "math"
+ "math/rand"
+ "sort"
+ "sync"
+ "time"
+)
+
+const rescaleThreshold = time.Hour
+
+// Samples maintain a statistically-significant selection of values from
+// a stream.
+type Sample interface {
+ Clear()
+ Count() int64
+ Max() int64
+ Mean() float64
+ Min() int64
+ Percentile(float64) float64
+ Percentiles([]float64) []float64
+ Size() int
+ Snapshot() Sample
+ StdDev() float64
+ Sum() int64
+ Update(int64)
+ Values() []int64
+ Variance() float64
+}
+
+// ExpDecaySample is an exponentially-decaying sample using a forward-decaying
+// priority reservoir. See Cormode et al's "Forward Decay: A Practical Time
+// Decay Model for Streaming Systems".
+//
+//
+type ExpDecaySample struct {
+ alpha float64
+ count int64
+ mutex sync.Mutex
+ reservoirSize int
+ t0, t1 time.Time
+ values *expDecaySampleHeap
+}
+
+// NewExpDecaySample constructs a new exponentially-decaying sample with the
+// given reservoir size and alpha.
+func NewExpDecaySample(reservoirSize int, alpha float64) Sample {
+ if UseNilMetrics {
+ return NilSample{}
+ }
+ s := &ExpDecaySample{
+ alpha: alpha,
+ reservoirSize: reservoirSize,
+ t0: time.Now(),
+ values: newExpDecaySampleHeap(reservoirSize),
+ }
+ s.t1 = s.t0.Add(rescaleThreshold)
+ return s
+}
+
+// Clear clears all samples.
+func (s *ExpDecaySample) Clear() {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ s.count = 0
+ s.t0 = time.Now()
+ s.t1 = s.t0.Add(rescaleThreshold)
+ s.values.Clear()
+}
+
+// Count returns the number of samples recorded, which may exceed the
+// reservoir size.
+func (s *ExpDecaySample) Count() int64 {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ return s.count
+}
+
+// Max returns the maximum value in the sample, which may not be the maximum
+// value ever to be part of the sample.
+func (s *ExpDecaySample) Max() int64 {
+ return SampleMax(s.Values())
+}
+
+// Mean returns the mean of the values in the sample.
+func (s *ExpDecaySample) Mean() float64 {
+ return SampleMean(s.Values())
+}
+
+// Min returns the minimum value in the sample, which may not be the minimum
+// value ever to be part of the sample.
+func (s *ExpDecaySample) Min() int64 {
+ return SampleMin(s.Values())
+}
+
+// Percentile returns an arbitrary percentile of values in the sample.
+func (s *ExpDecaySample) Percentile(p float64) float64 {
+ return SamplePercentile(s.Values(), p)
+}
+
+// Percentiles returns a slice of arbitrary percentiles of values in the
+// sample.
+func (s *ExpDecaySample) Percentiles(ps []float64) []float64 {
+ return SamplePercentiles(s.Values(), ps)
+}
+
+// Size returns the size of the sample, which is at most the reservoir size.
+func (s *ExpDecaySample) Size() int {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ return s.values.Size()
+}
+
+// Snapshot returns a read-only copy of the sample.
+func (s *ExpDecaySample) Snapshot() Sample {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ vals := s.values.Values()
+ values := make([]int64, len(vals))
+ for i, v := range vals {
+ values[i] = v.v
+ }
+ return &SampleSnapshot{
+ count: s.count,
+ values: values,
+ }
+}
+
+// StdDev returns the standard deviation of the values in the sample.
+func (s *ExpDecaySample) StdDev() float64 {
+ return SampleStdDev(s.Values())
+}
+
+// Sum returns the sum of the values in the sample.
+func (s *ExpDecaySample) Sum() int64 {
+ return SampleSum(s.Values())
+}
+
+// Update samples a new value.
+func (s *ExpDecaySample) Update(v int64) {
+ s.update(time.Now(), v)
+}
+
+// Values returns a copy of the values in the sample.
+func (s *ExpDecaySample) Values() []int64 {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ vals := s.values.Values()
+ values := make([]int64, len(vals))
+ for i, v := range vals {
+ values[i] = v.v
+ }
+ return values
+}
+
+// Variance returns the variance of the values in the sample.
+func (s *ExpDecaySample) Variance() float64 {
+ return SampleVariance(s.Values())
+}
+
+// update samples a new value at a particular timestamp. This is a method all
+// its own to facilitate testing.
+func (s *ExpDecaySample) update(t time.Time, v int64) {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ s.count++
+ if s.values.Size() == s.reservoirSize {
+ s.values.Pop()
+ }
+ s.values.Push(expDecaySample{
+ k: math.Exp(t.Sub(s.t0).Seconds()*s.alpha) / rand.Float64(),
+ v: v,
+ })
+ if t.After(s.t1) {
+ values := s.values.Values()
+ t0 := s.t0
+ s.values.Clear()
+ s.t0 = t
+ s.t1 = s.t0.Add(rescaleThreshold)
+ for _, v := range values {
+ v.k = v.k * math.Exp(-s.alpha*s.t0.Sub(t0).Seconds())
+ s.values.Push(v)
+ }
+ }
+}
+
+// NilSample is a no-op Sample.
+type NilSample struct{}
+
+// Clear is a no-op.
+func (NilSample) Clear() {}
+
+// Count is a no-op.
+func (NilSample) Count() int64 { return 0 }
+
+// Max is a no-op.
+func (NilSample) Max() int64 { return 0 }
+
+// Mean is a no-op.
+func (NilSample) Mean() float64 { return 0.0 }
+
+// Min is a no-op.
+func (NilSample) Min() int64 { return 0 }
+
+// Percentile is a no-op.
+func (NilSample) Percentile(p float64) float64 { return 0.0 }
+
+// Percentiles is a no-op.
+func (NilSample) Percentiles(ps []float64) []float64 {
+ return make([]float64, len(ps))
+}
+
+// Size is a no-op.
+func (NilSample) Size() int { return 0 }
+
+// Sample is a no-op.
+func (NilSample) Snapshot() Sample { return NilSample{} }
+
+// StdDev is a no-op.
+func (NilSample) StdDev() float64 { return 0.0 }
+
+// Sum is a no-op.
+func (NilSample) Sum() int64 { return 0 }
+
+// Update is a no-op.
+func (NilSample) Update(v int64) {}
+
+// Values is a no-op.
+func (NilSample) Values() []int64 { return []int64{} }
+
+// Variance is a no-op.
+func (NilSample) Variance() float64 { return 0.0 }
+
+// SampleMax returns the maximum value of the slice of int64.
+func SampleMax(values []int64) int64 {
+ if 0 == len(values) {
+ return 0
+ }
+ var max int64 = math.MinInt64
+ for _, v := range values {
+ if max < v {
+ max = v
+ }
+ }
+ return max
+}
+
+// SampleMean returns the mean value of the slice of int64.
+func SampleMean(values []int64) float64 {
+ if 0 == len(values) {
+ return 0.0
+ }
+ return float64(SampleSum(values)) / float64(len(values))
+}
+
+// SampleMin returns the minimum value of the slice of int64.
+func SampleMin(values []int64) int64 {
+ if 0 == len(values) {
+ return 0
+ }
+ var min int64 = math.MaxInt64
+ for _, v := range values {
+ if min > v {
+ min = v
+ }
+ }
+ return min
+}
+
+// SamplePercentiles returns an arbitrary percentile of the slice of int64.
+func SamplePercentile(values int64Slice, p float64) float64 {
+ return SamplePercentiles(values, []float64{p})[0]
+}
+
+// SamplePercentiles returns a slice of arbitrary percentiles of the slice of
+// int64.
+func SamplePercentiles(values int64Slice, ps []float64) []float64 {
+ scores := make([]float64, len(ps))
+ size := len(values)
+ if size > 0 {
+ sort.Sort(values)
+ for i, p := range ps {
+ pos := p * float64(size+1)
+ if pos < 1.0 {
+ scores[i] = float64(values[0])
+ } else if pos >= float64(size) {
+ scores[i] = float64(values[size-1])
+ } else {
+ lower := float64(values[int(pos)-1])
+ upper := float64(values[int(pos)])
+ scores[i] = lower + (pos-math.Floor(pos))*(upper-lower)
+ }
+ }
+ }
+ return scores
+}
+
+// SampleSnapshot is a read-only copy of another Sample.
+type SampleSnapshot struct {
+ count int64
+ values []int64
+}
+
+func NewSampleSnapshot(count int64, values []int64) *SampleSnapshot {
+ return &SampleSnapshot{
+ count: count,
+ values: values,
+ }
+}
+
+// Clear panics.
+func (*SampleSnapshot) Clear() {
+ panic("Clear called on a SampleSnapshot")
+}
+
+// Count returns the count of inputs at the time the snapshot was taken.
+func (s *SampleSnapshot) Count() int64 { return s.count }
+
+// Max returns the maximal value at the time the snapshot was taken.
+func (s *SampleSnapshot) Max() int64 { return SampleMax(s.values) }
+
+// Mean returns the mean value at the time the snapshot was taken.
+func (s *SampleSnapshot) Mean() float64 { return SampleMean(s.values) }
+
+// Min returns the minimal value at the time the snapshot was taken.
+func (s *SampleSnapshot) Min() int64 { return SampleMin(s.values) }
+
+// Percentile returns an arbitrary percentile of values at the time the
+// snapshot was taken.
+func (s *SampleSnapshot) Percentile(p float64) float64 {
+ return SamplePercentile(s.values, p)
+}
+
+// Percentiles returns a slice of arbitrary percentiles of values at the time
+// the snapshot was taken.
+func (s *SampleSnapshot) Percentiles(ps []float64) []float64 {
+ return SamplePercentiles(s.values, ps)
+}
+
+// Size returns the size of the sample at the time the snapshot was taken.
+func (s *SampleSnapshot) Size() int { return len(s.values) }
+
+// Snapshot returns the snapshot.
+func (s *SampleSnapshot) Snapshot() Sample { return s }
+
+// StdDev returns the standard deviation of values at the time the snapshot was
+// taken.
+func (s *SampleSnapshot) StdDev() float64 { return SampleStdDev(s.values) }
+
+// Sum returns the sum of values at the time the snapshot was taken.
+func (s *SampleSnapshot) Sum() int64 { return SampleSum(s.values) }
+
+// Update panics.
+func (*SampleSnapshot) Update(int64) {
+ panic("Update called on a SampleSnapshot")
+}
+
+// Values returns a copy of the values in the sample.
+func (s *SampleSnapshot) Values() []int64 {
+ values := make([]int64, len(s.values))
+ copy(values, s.values)
+ return values
+}
+
+// Variance returns the variance of values at the time the snapshot was taken.
+func (s *SampleSnapshot) Variance() float64 { return SampleVariance(s.values) }
+
+// SampleStdDev returns the standard deviation of the slice of int64.
+func SampleStdDev(values []int64) float64 {
+ return math.Sqrt(SampleVariance(values))
+}
+
+// SampleSum returns the sum of the slice of int64.
+func SampleSum(values []int64) int64 {
+ var sum int64
+ for _, v := range values {
+ sum += v
+ }
+ return sum
+}
+
+// SampleVariance returns the variance of the slice of int64.
+func SampleVariance(values []int64) float64 {
+ if 0 == len(values) {
+ return 0.0
+ }
+ m := SampleMean(values)
+ var sum float64
+ for _, v := range values {
+ d := float64(v) - m
+ sum += d * d
+ }
+ return sum / float64(len(values))
+}
+
+// A uniform sample using Vitter's Algorithm R.
+//
+//
+type UniformSample struct {
+ count int64
+ mutex sync.Mutex
+ reservoirSize int
+ values []int64
+}
+
+// NewUniformSample constructs a new uniform sample with the given reservoir
+// size.
+func NewUniformSample(reservoirSize int) Sample {
+ if UseNilMetrics {
+ return NilSample{}
+ }
+ return &UniformSample{
+ reservoirSize: reservoirSize,
+ values: make([]int64, 0, reservoirSize),
+ }
+}
+
+// Clear clears all samples.
+func (s *UniformSample) Clear() {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ s.count = 0
+ s.values = make([]int64, 0, s.reservoirSize)
+}
+
+// Count returns the number of samples recorded, which may exceed the
+// reservoir size.
+func (s *UniformSample) Count() int64 {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ return s.count
+}
+
+// Max returns the maximum value in the sample, which may not be the maximum
+// value ever to be part of the sample.
+func (s *UniformSample) Max() int64 {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ return SampleMax(s.values)
+}
+
+// Mean returns the mean of the values in the sample.
+func (s *UniformSample) Mean() float64 {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ return SampleMean(s.values)
+}
+
+// Min returns the minimum value in the sample, which may not be the minimum
+// value ever to be part of the sample.
+func (s *UniformSample) Min() int64 {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ return SampleMin(s.values)
+}
+
+// Percentile returns an arbitrary percentile of values in the sample.
+func (s *UniformSample) Percentile(p float64) float64 {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ return SamplePercentile(s.values, p)
+}
+
+// Percentiles returns a slice of arbitrary percentiles of values in the
+// sample.
+func (s *UniformSample) Percentiles(ps []float64) []float64 {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ return SamplePercentiles(s.values, ps)
+}
+
+// Size returns the size of the sample, which is at most the reservoir size.
+func (s *UniformSample) Size() int {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ return len(s.values)
+}
+
+// Snapshot returns a read-only copy of the sample.
+func (s *UniformSample) Snapshot() Sample {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ values := make([]int64, len(s.values))
+ copy(values, s.values)
+ return &SampleSnapshot{
+ count: s.count,
+ values: values,
+ }
+}
+
+// StdDev returns the standard deviation of the values in the sample.
+func (s *UniformSample) StdDev() float64 {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ return SampleStdDev(s.values)
+}
+
+// Sum returns the sum of the values in the sample.
+func (s *UniformSample) Sum() int64 {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ return SampleSum(s.values)
+}
+
+// Update samples a new value.
+func (s *UniformSample) Update(v int64) {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ s.count++
+ if len(s.values) < s.reservoirSize {
+ s.values = append(s.values, v)
+ } else {
+ r := rand.Int63n(s.count)
+ if r < int64(len(s.values)) {
+ s.values[int(r)] = v
+ }
+ }
+}
+
+// Values returns a copy of the values in the sample.
+func (s *UniformSample) Values() []int64 {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ values := make([]int64, len(s.values))
+ copy(values, s.values)
+ return values
+}
+
+// Variance returns the variance of the values in the sample.
+func (s *UniformSample) Variance() float64 {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ return SampleVariance(s.values)
+}
+
+// expDecaySample represents an individual sample in a heap.
+type expDecaySample struct {
+ k float64
+ v int64
+}
+
+func newExpDecaySampleHeap(reservoirSize int) *expDecaySampleHeap {
+ return &expDecaySampleHeap{make([]expDecaySample, 0, reservoirSize)}
+}
+
+// expDecaySampleHeap is a min-heap of expDecaySamples.
+// The internal implementation is copied from the standard library's container/heap
+type expDecaySampleHeap struct {
+ s []expDecaySample
+}
+
+func (h *expDecaySampleHeap) Clear() {
+ h.s = h.s[:0]
+}
+
+func (h *expDecaySampleHeap) Push(s expDecaySample) {
+ n := len(h.s)
+ h.s = h.s[0 : n+1]
+ h.s[n] = s
+ h.up(n)
+}
+
+func (h *expDecaySampleHeap) Pop() expDecaySample {
+ n := len(h.s) - 1
+ h.s[0], h.s[n] = h.s[n], h.s[0]
+ h.down(0, n)
+
+ n = len(h.s)
+ s := h.s[n-1]
+ h.s = h.s[0 : n-1]
+ return s
+}
+
+func (h *expDecaySampleHeap) Size() int {
+ return len(h.s)
+}
+
+func (h *expDecaySampleHeap) Values() []expDecaySample {
+ return h.s
+}
+
+func (h *expDecaySampleHeap) up(j int) {
+ for {
+ i := (j - 1) / 2 // parent
+ if i == j || !(h.s[j].k < h.s[i].k) {
+ break
+ }
+ h.s[i], h.s[j] = h.s[j], h.s[i]
+ j = i
+ }
+}
+
+func (h *expDecaySampleHeap) down(i, n int) {
+ for {
+ j1 := 2*i + 1
+ if j1 >= n || j1 < 0 { // j1 < 0 after int overflow
+ break
+ }
+ j := j1 // left child
+ if j2 := j1 + 1; j2 < n && !(h.s[j1].k < h.s[j2].k) {
+ j = j2 // = 2*i + 2 // right child
+ }
+ if !(h.s[j].k < h.s[i].k) {
+ break
+ }
+ h.s[i], h.s[j] = h.s[j], h.s[i]
+ i = j
+ }
+}
+
+type int64Slice []int64
+
+func (p int64Slice) Len() int { return len(p) }
+func (p int64Slice) Less(i, j int) bool { return p[i] < p[j] }
+func (p int64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
diff --git a/vendor/github.com/rcrowley/go-metrics/syslog.go b/vendor/github.com/rcrowley/go-metrics/syslog.go
new file mode 100644
index 000000000..693f19085
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/syslog.go
@@ -0,0 +1,78 @@
+// +build !windows
+
+package metrics
+
+import (
+ "fmt"
+ "log/syslog"
+ "time"
+)
+
+// Output each metric in the given registry to syslog periodically using
+// the given syslogger.
+func Syslog(r Registry, d time.Duration, w *syslog.Writer) {
+ for _ = range time.Tick(d) {
+ r.Each(func(name string, i interface{}) {
+ switch metric := i.(type) {
+ case Counter:
+ w.Info(fmt.Sprintf("counter %s: count: %d", name, metric.Count()))
+ case Gauge:
+ w.Info(fmt.Sprintf("gauge %s: value: %d", name, metric.Value()))
+ case GaugeFloat64:
+ w.Info(fmt.Sprintf("gauge %s: value: %f", name, metric.Value()))
+ case Healthcheck:
+ metric.Check()
+ w.Info(fmt.Sprintf("healthcheck %s: error: %v", name, metric.Error()))
+ case Histogram:
+ h := metric.Snapshot()
+ ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
+ w.Info(fmt.Sprintf(
+ "histogram %s: count: %d min: %d max: %d mean: %.2f stddev: %.2f median: %.2f 75%%: %.2f 95%%: %.2f 99%%: %.2f 99.9%%: %.2f",
+ name,
+ h.Count(),
+ h.Min(),
+ h.Max(),
+ h.Mean(),
+ h.StdDev(),
+ ps[0],
+ ps[1],
+ ps[2],
+ ps[3],
+ ps[4],
+ ))
+ case Meter:
+ m := metric.Snapshot()
+ w.Info(fmt.Sprintf(
+ "meter %s: count: %d 1-min: %.2f 5-min: %.2f 15-min: %.2f mean: %.2f",
+ name,
+ m.Count(),
+ m.Rate1(),
+ m.Rate5(),
+ m.Rate15(),
+ m.RateMean(),
+ ))
+ case Timer:
+ t := metric.Snapshot()
+ ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
+ w.Info(fmt.Sprintf(
+ "timer %s: count: %d min: %d max: %d mean: %.2f stddev: %.2f median: %.2f 75%%: %.2f 95%%: %.2f 99%%: %.2f 99.9%%: %.2f 1-min: %.2f 5-min: %.2f 15-min: %.2f mean-rate: %.2f",
+ name,
+ t.Count(),
+ t.Min(),
+ t.Max(),
+ t.Mean(),
+ t.StdDev(),
+ ps[0],
+ ps[1],
+ ps[2],
+ ps[3],
+ ps[4],
+ t.Rate1(),
+ t.Rate5(),
+ t.Rate15(),
+ t.RateMean(),
+ ))
+ }
+ })
+ }
+}
diff --git a/vendor/github.com/rcrowley/go-metrics/timer.go b/vendor/github.com/rcrowley/go-metrics/timer.go
new file mode 100644
index 000000000..d6ec4c626
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/timer.go
@@ -0,0 +1,329 @@
+package metrics
+
+import (
+ "sync"
+ "time"
+)
+
+// Timers capture the duration and rate of events.
+type Timer interface {
+ Count() int64
+ Max() int64
+ Mean() float64
+ Min() int64
+ Percentile(float64) float64
+ Percentiles([]float64) []float64
+ Rate1() float64
+ Rate5() float64
+ Rate15() float64
+ RateMean() float64
+ Snapshot() Timer
+ StdDev() float64
+ Stop()
+ Sum() int64
+ Time(func())
+ Update(time.Duration)
+ UpdateSince(time.Time)
+ Variance() float64
+}
+
+// GetOrRegisterTimer returns an existing Timer or constructs and registers a
+// new StandardTimer.
+// Be sure to unregister the meter from the registry once it is of no use to
+// allow for garbage collection.
+func GetOrRegisterTimer(name string, r Registry) Timer {
+ if nil == r {
+ r = DefaultRegistry
+ }
+ return r.GetOrRegister(name, NewTimer).(Timer)
+}
+
+// NewCustomTimer constructs a new StandardTimer from a Histogram and a Meter.
+// Be sure to call Stop() once the timer is of no use to allow for garbage collection.
+func NewCustomTimer(h Histogram, m Meter) Timer {
+ if UseNilMetrics {
+ return NilTimer{}
+ }
+ return &StandardTimer{
+ histogram: h,
+ meter: m,
+ }
+}
+
+// NewRegisteredTimer constructs and registers a new StandardTimer.
+// Be sure to unregister the meter from the registry once it is of no use to
+// allow for garbage collection.
+func NewRegisteredTimer(name string, r Registry) Timer {
+ c := NewTimer()
+ if nil == r {
+ r = DefaultRegistry
+ }
+ r.Register(name, c)
+ return c
+}
+
+// NewTimer constructs a new StandardTimer using an exponentially-decaying
+// sample with the same reservoir size and alpha as UNIX load averages.
+// Be sure to call Stop() once the timer is of no use to allow for garbage collection.
+func NewTimer() Timer {
+ if UseNilMetrics {
+ return NilTimer{}
+ }
+ return &StandardTimer{
+ histogram: NewHistogram(NewExpDecaySample(1028, 0.015)),
+ meter: NewMeter(),
+ }
+}
+
+// NilTimer is a no-op Timer.
+type NilTimer struct {
+ h Histogram
+ m Meter
+}
+
+// Count is a no-op.
+func (NilTimer) Count() int64 { return 0 }
+
+// Max is a no-op.
+func (NilTimer) Max() int64 { return 0 }
+
+// Mean is a no-op.
+func (NilTimer) Mean() float64 { return 0.0 }
+
+// Min is a no-op.
+func (NilTimer) Min() int64 { return 0 }
+
+// Percentile is a no-op.
+func (NilTimer) Percentile(p float64) float64 { return 0.0 }
+
+// Percentiles is a no-op.
+func (NilTimer) Percentiles(ps []float64) []float64 {
+ return make([]float64, len(ps))
+}
+
+// Rate1 is a no-op.
+func (NilTimer) Rate1() float64 { return 0.0 }
+
+// Rate5 is a no-op.
+func (NilTimer) Rate5() float64 { return 0.0 }
+
+// Rate15 is a no-op.
+func (NilTimer) Rate15() float64 { return 0.0 }
+
+// RateMean is a no-op.
+func (NilTimer) RateMean() float64 { return 0.0 }
+
+// Snapshot is a no-op.
+func (NilTimer) Snapshot() Timer { return NilTimer{} }
+
+// StdDev is a no-op.
+func (NilTimer) StdDev() float64 { return 0.0 }
+
+// Stop is a no-op.
+func (NilTimer) Stop() {}
+
+// Sum is a no-op.
+func (NilTimer) Sum() int64 { return 0 }
+
+// Time is a no-op.
+func (NilTimer) Time(func()) {}
+
+// Update is a no-op.
+func (NilTimer) Update(time.Duration) {}
+
+// UpdateSince is a no-op.
+func (NilTimer) UpdateSince(time.Time) {}
+
+// Variance is a no-op.
+func (NilTimer) Variance() float64 { return 0.0 }
+
+// StandardTimer is the standard implementation of a Timer and uses a Histogram
+// and Meter.
+type StandardTimer struct {
+ histogram Histogram
+ meter Meter
+ mutex sync.Mutex
+}
+
+// Count returns the number of events recorded.
+func (t *StandardTimer) Count() int64 {
+ return t.histogram.Count()
+}
+
+// Max returns the maximum value in the sample.
+func (t *StandardTimer) Max() int64 {
+ return t.histogram.Max()
+}
+
+// Mean returns the mean of the values in the sample.
+func (t *StandardTimer) Mean() float64 {
+ return t.histogram.Mean()
+}
+
+// Min returns the minimum value in the sample.
+func (t *StandardTimer) Min() int64 {
+ return t.histogram.Min()
+}
+
+// Percentile returns an arbitrary percentile of the values in the sample.
+func (t *StandardTimer) Percentile(p float64) float64 {
+ return t.histogram.Percentile(p)
+}
+
+// Percentiles returns a slice of arbitrary percentiles of the values in the
+// sample.
+func (t *StandardTimer) Percentiles(ps []float64) []float64 {
+ return t.histogram.Percentiles(ps)
+}
+
+// Rate1 returns the one-minute moving average rate of events per second.
+func (t *StandardTimer) Rate1() float64 {
+ return t.meter.Rate1()
+}
+
+// Rate5 returns the five-minute moving average rate of events per second.
+func (t *StandardTimer) Rate5() float64 {
+ return t.meter.Rate5()
+}
+
+// Rate15 returns the fifteen-minute moving average rate of events per second.
+func (t *StandardTimer) Rate15() float64 {
+ return t.meter.Rate15()
+}
+
+// RateMean returns the meter's mean rate of events per second.
+func (t *StandardTimer) RateMean() float64 {
+ return t.meter.RateMean()
+}
+
+// Snapshot returns a read-only copy of the timer.
+func (t *StandardTimer) Snapshot() Timer {
+ t.mutex.Lock()
+ defer t.mutex.Unlock()
+ return &TimerSnapshot{
+ histogram: t.histogram.Snapshot().(*HistogramSnapshot),
+ meter: t.meter.Snapshot().(*MeterSnapshot),
+ }
+}
+
+// StdDev returns the standard deviation of the values in the sample.
+func (t *StandardTimer) StdDev() float64 {
+ return t.histogram.StdDev()
+}
+
+// Stop stops the meter.
+func (t *StandardTimer) Stop() {
+ t.meter.Stop()
+}
+
+// Sum returns the sum in the sample.
+func (t *StandardTimer) Sum() int64 {
+ return t.histogram.Sum()
+}
+
+// Record the duration of the execution of the given function.
+func (t *StandardTimer) Time(f func()) {
+ ts := time.Now()
+ f()
+ t.Update(time.Since(ts))
+}
+
+// Record the duration of an event.
+func (t *StandardTimer) Update(d time.Duration) {
+ t.mutex.Lock()
+ defer t.mutex.Unlock()
+ t.histogram.Update(int64(d))
+ t.meter.Mark(1)
+}
+
+// Record the duration of an event that started at a time and ends now.
+func (t *StandardTimer) UpdateSince(ts time.Time) {
+ t.mutex.Lock()
+ defer t.mutex.Unlock()
+ t.histogram.Update(int64(time.Since(ts)))
+ t.meter.Mark(1)
+}
+
+// Variance returns the variance of the values in the sample.
+func (t *StandardTimer) Variance() float64 {
+ return t.histogram.Variance()
+}
+
+// TimerSnapshot is a read-only copy of another Timer.
+type TimerSnapshot struct {
+ histogram *HistogramSnapshot
+ meter *MeterSnapshot
+}
+
+// Count returns the number of events recorded at the time the snapshot was
+// taken.
+func (t *TimerSnapshot) Count() int64 { return t.histogram.Count() }
+
+// Max returns the maximum value at the time the snapshot was taken.
+func (t *TimerSnapshot) Max() int64 { return t.histogram.Max() }
+
+// Mean returns the mean value at the time the snapshot was taken.
+func (t *TimerSnapshot) Mean() float64 { return t.histogram.Mean() }
+
+// Min returns the minimum value at the time the snapshot was taken.
+func (t *TimerSnapshot) Min() int64 { return t.histogram.Min() }
+
+// Percentile returns an arbitrary percentile of sampled values at the time the
+// snapshot was taken.
+func (t *TimerSnapshot) Percentile(p float64) float64 {
+ return t.histogram.Percentile(p)
+}
+
+// Percentiles returns a slice of arbitrary percentiles of sampled values at
+// the time the snapshot was taken.
+func (t *TimerSnapshot) Percentiles(ps []float64) []float64 {
+ return t.histogram.Percentiles(ps)
+}
+
+// Rate1 returns the one-minute moving average rate of events per second at the
+// time the snapshot was taken.
+func (t *TimerSnapshot) Rate1() float64 { return t.meter.Rate1() }
+
+// Rate5 returns the five-minute moving average rate of events per second at
+// the time the snapshot was taken.
+func (t *TimerSnapshot) Rate5() float64 { return t.meter.Rate5() }
+
+// Rate15 returns the fifteen-minute moving average rate of events per second
+// at the time the snapshot was taken.
+func (t *TimerSnapshot) Rate15() float64 { return t.meter.Rate15() }
+
+// RateMean returns the meter's mean rate of events per second at the time the
+// snapshot was taken.
+func (t *TimerSnapshot) RateMean() float64 { return t.meter.RateMean() }
+
+// Snapshot returns the snapshot.
+func (t *TimerSnapshot) Snapshot() Timer { return t }
+
+// StdDev returns the standard deviation of the values at the time the snapshot
+// was taken.
+func (t *TimerSnapshot) StdDev() float64 { return t.histogram.StdDev() }
+
+// Stop is a no-op.
+func (t *TimerSnapshot) Stop() {}
+
+// Sum returns the sum at the time the snapshot was taken.
+func (t *TimerSnapshot) Sum() int64 { return t.histogram.Sum() }
+
+// Time panics.
+func (*TimerSnapshot) Time(func()) {
+ panic("Time called on a TimerSnapshot")
+}
+
+// Update panics.
+func (*TimerSnapshot) Update(time.Duration) {
+ panic("Update called on a TimerSnapshot")
+}
+
+// UpdateSince panics.
+func (*TimerSnapshot) UpdateSince(time.Time) {
+ panic("UpdateSince called on a TimerSnapshot")
+}
+
+// Variance returns the variance of the values at the time the snapshot was
+// taken.
+func (t *TimerSnapshot) Variance() float64 { return t.histogram.Variance() }
diff --git a/vendor/github.com/rcrowley/go-metrics/validate.sh b/vendor/github.com/rcrowley/go-metrics/validate.sh
new file mode 100755
index 000000000..c4ae91e64
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/validate.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+set -e
+
+# check there are no formatting issues
+GOFMT_LINES=`gofmt -l . | wc -l | xargs`
+test $GOFMT_LINES -eq 0 || echo "gofmt needs to be run, ${GOFMT_LINES} files have issues"
+
+# run the tests for the root package
+go test -race .
diff --git a/vendor/github.com/rcrowley/go-metrics/writer.go b/vendor/github.com/rcrowley/go-metrics/writer.go
new file mode 100644
index 000000000..091e971d2
--- /dev/null
+++ b/vendor/github.com/rcrowley/go-metrics/writer.go
@@ -0,0 +1,100 @@
+package metrics
+
+import (
+ "fmt"
+ "io"
+ "sort"
+ "time"
+)
+
+// Write sorts writes each metric in the given registry periodically to the
+// given io.Writer.
+func Write(r Registry, d time.Duration, w io.Writer) {
+ for _ = range time.Tick(d) {
+ WriteOnce(r, w)
+ }
+}
+
+// WriteOnce sorts and writes metrics in the given registry to the given
+// io.Writer.
+func WriteOnce(r Registry, w io.Writer) {
+ var namedMetrics namedMetricSlice
+ r.Each(func(name string, i interface{}) {
+ namedMetrics = append(namedMetrics, namedMetric{name, i})
+ })
+
+ sort.Sort(namedMetrics)
+ for _, namedMetric := range namedMetrics {
+ switch metric := namedMetric.m.(type) {
+ case Counter:
+ fmt.Fprintf(w, "counter %s\n", namedMetric.name)
+ fmt.Fprintf(w, " count: %9d\n", metric.Count())
+ case Gauge:
+ fmt.Fprintf(w, "gauge %s\n", namedMetric.name)
+ fmt.Fprintf(w, " value: %9d\n", metric.Value())
+ case GaugeFloat64:
+ fmt.Fprintf(w, "gauge %s\n", namedMetric.name)
+ fmt.Fprintf(w, " value: %f\n", metric.Value())
+ case Healthcheck:
+ metric.Check()
+ fmt.Fprintf(w, "healthcheck %s\n", namedMetric.name)
+ fmt.Fprintf(w, " error: %v\n", metric.Error())
+ case Histogram:
+ h := metric.Snapshot()
+ ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
+ fmt.Fprintf(w, "histogram %s\n", namedMetric.name)
+ fmt.Fprintf(w, " count: %9d\n", h.Count())
+ fmt.Fprintf(w, " min: %9d\n", h.Min())
+ fmt.Fprintf(w, " max: %9d\n", h.Max())
+ fmt.Fprintf(w, " mean: %12.2f\n", h.Mean())
+ fmt.Fprintf(w, " stddev: %12.2f\n", h.StdDev())
+ fmt.Fprintf(w, " median: %12.2f\n", ps[0])
+ fmt.Fprintf(w, " 75%%: %12.2f\n", ps[1])
+ fmt.Fprintf(w, " 95%%: %12.2f\n", ps[2])
+ fmt.Fprintf(w, " 99%%: %12.2f\n", ps[3])
+ fmt.Fprintf(w, " 99.9%%: %12.2f\n", ps[4])
+ case Meter:
+ m := metric.Snapshot()
+ fmt.Fprintf(w, "meter %s\n", namedMetric.name)
+ fmt.Fprintf(w, " count: %9d\n", m.Count())
+ fmt.Fprintf(w, " 1-min rate: %12.2f\n", m.Rate1())
+ fmt.Fprintf(w, " 5-min rate: %12.2f\n", m.Rate5())
+ fmt.Fprintf(w, " 15-min rate: %12.2f\n", m.Rate15())
+ fmt.Fprintf(w, " mean rate: %12.2f\n", m.RateMean())
+ case Timer:
+ t := metric.Snapshot()
+ ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
+ fmt.Fprintf(w, "timer %s\n", namedMetric.name)
+ fmt.Fprintf(w, " count: %9d\n", t.Count())
+ fmt.Fprintf(w, " min: %9d\n", t.Min())
+ fmt.Fprintf(w, " max: %9d\n", t.Max())
+ fmt.Fprintf(w, " mean: %12.2f\n", t.Mean())
+ fmt.Fprintf(w, " stddev: %12.2f\n", t.StdDev())
+ fmt.Fprintf(w, " median: %12.2f\n", ps[0])
+ fmt.Fprintf(w, " 75%%: %12.2f\n", ps[1])
+ fmt.Fprintf(w, " 95%%: %12.2f\n", ps[2])
+ fmt.Fprintf(w, " 99%%: %12.2f\n", ps[3])
+ fmt.Fprintf(w, " 99.9%%: %12.2f\n", ps[4])
+ fmt.Fprintf(w, " 1-min rate: %12.2f\n", t.Rate1())
+ fmt.Fprintf(w, " 5-min rate: %12.2f\n", t.Rate5())
+ fmt.Fprintf(w, " 15-min rate: %12.2f\n", t.Rate15())
+ fmt.Fprintf(w, " mean rate: %12.2f\n", t.RateMean())
+ }
+ }
+}
+
+type namedMetric struct {
+ name string
+ m interface{}
+}
+
+// namedMetricSlice is a slice of namedMetrics that implements sort.Interface.
+type namedMetricSlice []namedMetric
+
+func (nms namedMetricSlice) Len() int { return len(nms) }
+
+func (nms namedMetricSlice) Swap(i, j int) { nms[i], nms[j] = nms[j], nms[i] }
+
+func (nms namedMetricSlice) Less(i, j int) bool {
+ return nms[i].name < nms[j].name
+}
diff --git a/vendor/github.com/satori/go.uuid/README.md b/vendor/github.com/satori/go.uuid/README.md
index 770284969..362b27067 100644
--- a/vendor/github.com/satori/go.uuid/README.md
+++ b/vendor/github.com/satori/go.uuid/README.md
@@ -23,7 +23,7 @@ Use the `go` command:
## Requirements
-UUID package requires Go >= 1.2.
+UUID package tested against Go >= 1.6.
## Example
@@ -53,6 +53,7 @@ func main() {
u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
if err != nil {
fmt.Printf("Something went wrong: %s", err)
+ return
}
fmt.Printf("Successfully parsed: %s", u2)
}
diff --git a/vendor/github.com/satori/go.uuid/generator.go b/vendor/github.com/satori/go.uuid/generator.go
index 499dc35fb..c50d33cab 100644
--- a/vendor/github.com/satori/go.uuid/generator.go
+++ b/vendor/github.com/satori/go.uuid/generator.go
@@ -165,7 +165,7 @@ func (g *rfc4122Generator) NewV3(ns UUID, name string) UUID {
// NewV4 returns random generated UUID.
func (g *rfc4122Generator) NewV4() (UUID, error) {
u := UUID{}
- if _, err := g.rand.Read(u[:]); err != nil {
+ if _, err := io.ReadFull(g.rand, u[:]); err != nil {
return Nil, err
}
u.SetVersion(V4)
@@ -188,7 +188,7 @@ func (g *rfc4122Generator) getClockSequence() (uint64, uint16, error) {
var err error
g.clockSequenceOnce.Do(func() {
buf := make([]byte, 2)
- if _, err = g.rand.Read(buf); err != nil {
+ if _, err = io.ReadFull(g.rand, buf); err != nil {
return
}
g.clockSequence = binary.BigEndian.Uint16(buf)
@@ -222,7 +222,7 @@ func (g *rfc4122Generator) getHardwareAddr() ([]byte, error) {
// Initialize hardwareAddr randomly in case
// of real network interfaces absence.
- if _, err = g.rand.Read(g.hardwareAddr[:]); err != nil {
+ if _, err = io.ReadFull(g.rand, g.hardwareAddr[:]); err != nil {
return
}
// Set multicast bit as recommended by RFC 4122
diff --git a/vendor/github.com/siddontang/go-mysql/mysql/util.go b/vendor/github.com/siddontang/go-mysql/mysql/util.go
index 7fe41fa21..1e74246fa 100644
--- a/vendor/github.com/siddontang/go-mysql/mysql/util.go
+++ b/vendor/github.com/siddontang/go-mysql/mysql/util.go
@@ -1,11 +1,11 @@
package mysql
import (
- "crypto/rand"
"crypto/sha1"
"encoding/binary"
"fmt"
"io"
+ "math/rand"
"runtime"
"strings"
@@ -48,17 +48,14 @@ func CalcPassword(scramble, password []byte) []byte {
return scramble
}
+// Copy from github.com/pingcap/tidb mysql/util.go
+// See https://github.com/mysql/mysql-server/blob/5.7/mysys_ssl/crypt_genhash_impl.cc#L435
func RandomBuf(size int) ([]byte, error) {
buf := make([]byte, size)
-
- if _, err := io.ReadFull(rand.Reader, buf); err != nil {
- return nil, errors.Trace(err)
- }
-
- // avoid to generate '\0'
- for i, b := range buf {
- if uint8(b) == 0 {
- buf[i] = '0'
+ for i := 0; i < size; i++ {
+ buf[i] = byte(rand.Intn(127))
+ if buf[i] == 0 || buf[i] == byte('$') {
+ buf[i]++
}
}
diff --git a/vendor/github.com/siddontang/go-mysql/server/auth.go b/vendor/github.com/siddontang/go-mysql/server/auth.go
index b66ea4e0c..cb6ca160f 100644
--- a/vendor/github.com/siddontang/go-mysql/server/auth.go
+++ b/vendor/github.com/siddontang/go-mysql/server/auth.go
@@ -89,20 +89,37 @@ func (c *Conn) readHandshakeResponse(password string) error {
return NewDefaultError(ER_NO_SUCH_USER, user, c.RemoteAddr().String())
}
- //auth length and auth
- authLen := int(data[pos])
- pos++
- auth := data[pos : pos+authLen]
+ var auth []byte
+
+ if c.capability&CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA > 0 {
+ // Fix from github.com/pingcap/tidb
+ // MySQL client sets the wrong capability, it will set this bit even server doesn't
+ // support ClientPluginAuthLenencClientData.
+ // https://github.com/mysql/mysql-server/blob/5.7/sql-common/client.c#L3478
+ num, null, off := LengthEncodedInt(data[pos:])
+ pos += off
+ if !null {
+ auth = data[pos : pos+int(num)]
+ pos += int(num)
+ }
+ } else if c.capability&CLIENT_SECURE_CONNECTION > 0 {
+ //auth length and auth
+ authLen := int(data[pos])
+ pos++
+ auth = data[pos : pos+authLen]
+ pos += authLen
+ } else {
+ auth = data[pos : pos+bytes.IndexByte(data[pos:], 0)]
+ pos += len(auth) + 1
+ }
checkAuth := CalcPassword(c.salt, []byte(password))
if !bytes.Equal(auth, checkAuth) {
- return NewDefaultError(ER_ACCESS_DENIED_ERROR, c.RemoteAddr().String(), c.user, "Yes")
+ return NewDefaultError(ER_ACCESS_DENIED_ERROR, c.user, c.RemoteAddr().String(), "Yes")
}
- pos += authLen
-
- if c.capability|CLIENT_CONNECT_WITH_DB > 0 {
+ if c.capability&CLIENT_CONNECT_WITH_DB > 0 {
if len(data[pos:]) == 0 {
return nil
}
diff --git a/vendor/github.com/xo/tblfmt/go.mod b/vendor/github.com/xo/tblfmt/go.mod
index b8dc613f2..f66af95c8 100644
--- a/vendor/github.com/xo/tblfmt/go.mod
+++ b/vendor/github.com/xo/tblfmt/go.mod
@@ -1,3 +1,6 @@
module github.com/xo/tblfmt
-require github.com/mattn/go-runewidth v0.0.3
+require (
+ github.com/mattn/go-runewidth v0.0.3
+ github.com/xo/dburl v0.0.0-20180921222126-e33971d4c132
+)
diff --git a/vendor/github.com/xo/tblfmt/go.sum b/vendor/github.com/xo/tblfmt/go.sum
index 1c1891604..977b1d669 100644
--- a/vendor/github.com/xo/tblfmt/go.sum
+++ b/vendor/github.com/xo/tblfmt/go.sum
@@ -1,2 +1,4 @@
github.com/mattn/go-runewidth v0.0.3 h1:a+kO+98RDGEfo6asOGMmpodZq4FNtnGP54yps8BzLR4=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/xo/dburl v0.0.0-20180921222126-e33971d4c132 h1:cRKJ4yZeCZbCEXJmjZMa9s2z+3eavo2a4qu/usvVopI=
+github.com/xo/dburl v0.0.0-20180921222126-e33971d4c132/go.mod h1:g6rdekR8vgfVZrkLWfobLTm0kVez7GAN23mWtkGCJ14=
diff --git a/vendor/github.com/xo/usql/stmt/parse.go b/vendor/github.com/xo/usql/stmt/parse.go
index f804bf5f2..2da055830 100644
--- a/vendor/github.com/xo/usql/stmt/parse.go
+++ b/vendor/github.com/xo/usql/stmt/parse.go
@@ -310,7 +310,7 @@ loop:
// add space when remaining runes begin with space, and previous
// captured word did not
- if sl := len(s); sl != 0 && IsSpace(r[0]) && !IsSpace(s[sl-1]) {
+ if sl := len(s); sl != 0 && len(r) > 0 && IsSpace(r[0]) && !IsSpace(s[sl-1]) {
s = append(s, ' ')
}
diff --git a/vendor/github.com/xtaci/smux/LICENSE b/vendor/github.com/xtaci/smux/LICENSE
new file mode 100644
index 000000000..eed41acb1
--- /dev/null
+++ b/vendor/github.com/xtaci/smux/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2016-2017 Daniel Fu
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/xtaci/smux/README.md b/vendor/github.com/xtaci/smux/README.md
new file mode 100644
index 000000000..c01c346ee
--- /dev/null
+++ b/vendor/github.com/xtaci/smux/README.md
@@ -0,0 +1,99 @@
+
+
+[![GoDoc][1]][2] [![MIT licensed][3]][4] [![Build Status][5]][6] [![Go Report Card][7]][8] [![Coverage Statusd][9]][10]
+
+
+
+[1]: https://godoc.org/github.com/xtaci/smux?status.svg
+[2]: https://godoc.org/github.com/xtaci/smux
+[3]: https://img.shields.io/badge/license-MIT-blue.svg
+[4]: LICENSE
+[5]: https://travis-ci.org/xtaci/smux.svg?branch=master
+[6]: https://travis-ci.org/xtaci/smux
+[7]: https://goreportcard.com/badge/github.com/xtaci/smux
+[8]: https://goreportcard.com/report/github.com/xtaci/smux
+[9]: https://codecov.io/gh/xtaci/smux/branch/master/graph/badge.svg
+[10]: https://codecov.io/gh/xtaci/smux
+
+## Introduction
+
+Smux ( **S**imple **MU**ltiple**X**ing) is a multiplexing library for Golang. It relies on an underlying connection to provide reliability and ordering, such as TCP or [KCP](https://github.com/xtaci/kcp-go), and provides stream-oriented multiplexing. The original intention of this library is to power the connection management for [kcp-go](https://github.com/xtaci/kcp-go).
+
+## Features
+
+1. Tiny, less than 600 LOC.
+2. ***Token bucket*** controlled receiving, which provides smoother bandwidth graph(see picture below).
+3. Session-wide receive buffer, shared among streams, tightly controlled overall memory usage.
+4. Minimized header(8Bytes), maximized payload.
+5. Well-tested on millions of devices in [kcptun](https://github.com/xtaci/kcptun).
+
+
+
+## Documentation
+
+For complete documentation, see the associated [Godoc](https://godoc.org/github.com/xtaci/smux).
+
+## Specification
+
+```
+VERSION(1B) | CMD(1B) | LENGTH(2B) | STREAMID(4B) | DATA(LENGTH)
+```
+
+## Usage
+
+The API of smux are mostly taken from [yamux](https://github.com/hashicorp/yamux)
+
+```go
+
+func client() {
+ // Get a TCP connection
+ conn, err := net.Dial(...)
+ if err != nil {
+ panic(err)
+ }
+
+ // Setup client side of smux
+ session, err := smux.Client(conn, nil)
+ if err != nil {
+ panic(err)
+ }
+
+ // Open a new stream
+ stream, err := session.OpenStream()
+ if err != nil {
+ panic(err)
+ }
+
+ // Stream implements io.ReadWriteCloser
+ stream.Write([]byte("ping"))
+}
+
+func server() {
+ // Accept a TCP connection
+ conn, err := listener.Accept()
+ if err != nil {
+ panic(err)
+ }
+
+ // Setup server side of smux
+ session, err := smux.Server(conn, nil)
+ if err != nil {
+ panic(err)
+ }
+
+ // Accept a stream
+ stream, err := session.AcceptStream()
+ if err != nil {
+ panic(err)
+ }
+
+ // Listen for a message
+ buf := make([]byte, 4)
+ stream.Read(buf)
+}
+
+```
+
+## Status
+
+Stable
diff --git a/vendor/github.com/xtaci/smux/curve.jpg b/vendor/github.com/xtaci/smux/curve.jpg
new file mode 100644
index 000000000..3fc4863f4
Binary files /dev/null and b/vendor/github.com/xtaci/smux/curve.jpg differ
diff --git a/vendor/github.com/xtaci/smux/frame.go b/vendor/github.com/xtaci/smux/frame.go
new file mode 100644
index 000000000..71d3d44a3
--- /dev/null
+++ b/vendor/github.com/xtaci/smux/frame.go
@@ -0,0 +1,60 @@
+package smux
+
+import (
+ "encoding/binary"
+ "fmt"
+)
+
+const (
+ version = 1
+)
+
+const ( // cmds
+ cmdSYN byte = iota // stream open
+ cmdFIN // stream close, a.k.a EOF mark
+ cmdPSH // data push
+ cmdNOP // no operation
+)
+
+const (
+ sizeOfVer = 1
+ sizeOfCmd = 1
+ sizeOfLength = 2
+ sizeOfSid = 4
+ headerSize = sizeOfVer + sizeOfCmd + sizeOfSid + sizeOfLength
+)
+
+// Frame defines a packet from or to be multiplexed into a single connection
+type Frame struct {
+ ver byte
+ cmd byte
+ sid uint32
+ data []byte
+}
+
+func newFrame(cmd byte, sid uint32) Frame {
+ return Frame{ver: version, cmd: cmd, sid: sid}
+}
+
+type rawHeader [headerSize]byte
+
+func (h rawHeader) Version() byte {
+ return h[0]
+}
+
+func (h rawHeader) Cmd() byte {
+ return h[1]
+}
+
+func (h rawHeader) Length() uint16 {
+ return binary.LittleEndian.Uint16(h[2:])
+}
+
+func (h rawHeader) StreamID() uint32 {
+ return binary.LittleEndian.Uint32(h[4:])
+}
+
+func (h rawHeader) String() string {
+ return fmt.Sprintf("Version:%d Cmd:%d StreamID:%d Length:%d",
+ h.Version(), h.Cmd(), h.StreamID(), h.Length())
+}
diff --git a/vendor/github.com/xtaci/smux/mux.go b/vendor/github.com/xtaci/smux/mux.go
new file mode 100644
index 000000000..3cc8f114f
--- /dev/null
+++ b/vendor/github.com/xtaci/smux/mux.go
@@ -0,0 +1,80 @@
+package smux
+
+import (
+ "fmt"
+ "io"
+ "time"
+
+ "github.com/pkg/errors"
+)
+
+// Config is used to tune the Smux session
+type Config struct {
+ // KeepAliveInterval is how often to send a NOP command to the remote
+ KeepAliveInterval time.Duration
+
+ // KeepAliveTimeout is how long the session
+ // will be closed if no data has arrived
+ KeepAliveTimeout time.Duration
+
+ // MaxFrameSize is used to control the maximum
+ // frame size to sent to the remote
+ MaxFrameSize int
+
+ // MaxReceiveBuffer is used to control the maximum
+ // number of data in the buffer pool
+ MaxReceiveBuffer int
+}
+
+// DefaultConfig is used to return a default configuration
+func DefaultConfig() *Config {
+ return &Config{
+ KeepAliveInterval: 10 * time.Second,
+ KeepAliveTimeout: 30 * time.Second,
+ MaxFrameSize: 32768,
+ MaxReceiveBuffer: 4194304,
+ }
+}
+
+// VerifyConfig is used to verify the sanity of configuration
+func VerifyConfig(config *Config) error {
+ if config.KeepAliveInterval == 0 {
+ return errors.New("keep-alive interval must be positive")
+ }
+ if config.KeepAliveTimeout < config.KeepAliveInterval {
+ return fmt.Errorf("keep-alive timeout must be larger than keep-alive interval")
+ }
+ if config.MaxFrameSize <= 0 {
+ return errors.New("max frame size must be positive")
+ }
+ if config.MaxFrameSize > 65535 {
+ return errors.New("max frame size must not be larger than 65535")
+ }
+ if config.MaxReceiveBuffer <= 0 {
+ return errors.New("max receive buffer must be positive")
+ }
+ return nil
+}
+
+// Server is used to initialize a new server-side connection.
+func Server(conn io.ReadWriteCloser, config *Config) (*Session, error) {
+ if config == nil {
+ config = DefaultConfig()
+ }
+ if err := VerifyConfig(config); err != nil {
+ return nil, err
+ }
+ return newSession(config, conn, false), nil
+}
+
+// Client is used to initialize a new client-side connection.
+func Client(conn io.ReadWriteCloser, config *Config) (*Session, error) {
+ if config == nil {
+ config = DefaultConfig()
+ }
+
+ if err := VerifyConfig(config); err != nil {
+ return nil, err
+ }
+ return newSession(config, conn, true), nil
+}
diff --git a/vendor/github.com/xtaci/smux/mux.jpg b/vendor/github.com/xtaci/smux/mux.jpg
new file mode 100644
index 000000000..dde2e11aa
Binary files /dev/null and b/vendor/github.com/xtaci/smux/mux.jpg differ
diff --git a/vendor/github.com/xtaci/smux/session.go b/vendor/github.com/xtaci/smux/session.go
new file mode 100644
index 000000000..c29634e21
--- /dev/null
+++ b/vendor/github.com/xtaci/smux/session.go
@@ -0,0 +1,350 @@
+package smux
+
+import (
+ "encoding/binary"
+ "io"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/pkg/errors"
+)
+
+const (
+ defaultAcceptBacklog = 1024
+)
+
+const (
+ errBrokenPipe = "broken pipe"
+ errInvalidProtocol = "invalid protocol version"
+ errGoAway = "stream id overflows, should start a new connection"
+)
+
+type writeRequest struct {
+ frame Frame
+ result chan writeResult
+}
+
+type writeResult struct {
+ n int
+ err error
+}
+
+// Session defines a multiplexed connection for streams
+type Session struct {
+ conn io.ReadWriteCloser
+
+ config *Config
+ nextStreamID uint32 // next stream identifier
+ nextStreamIDLock sync.Mutex
+
+ bucket int32 // token bucket
+ bucketNotify chan struct{} // used for waiting for tokens
+
+ streams map[uint32]*Stream // all streams in this session
+ streamLock sync.Mutex // locks streams
+
+ die chan struct{} // flag session has died
+ dieLock sync.Mutex
+ chAccepts chan *Stream
+
+ dataReady int32 // flag data has arrived
+
+ goAway int32 // flag id exhausted
+
+ deadline atomic.Value
+
+ writes chan writeRequest
+}
+
+func newSession(config *Config, conn io.ReadWriteCloser, client bool) *Session {
+ s := new(Session)
+ s.die = make(chan struct{})
+ s.conn = conn
+ s.config = config
+ s.streams = make(map[uint32]*Stream)
+ s.chAccepts = make(chan *Stream, defaultAcceptBacklog)
+ s.bucket = int32(config.MaxReceiveBuffer)
+ s.bucketNotify = make(chan struct{}, 1)
+ s.writes = make(chan writeRequest)
+
+ if client {
+ s.nextStreamID = 1
+ } else {
+ s.nextStreamID = 0
+ }
+ go s.recvLoop()
+ go s.sendLoop()
+ go s.keepalive()
+ return s
+}
+
+// OpenStream is used to create a new stream
+func (s *Session) OpenStream() (*Stream, error) {
+ if s.IsClosed() {
+ return nil, errors.New(errBrokenPipe)
+ }
+
+ // generate stream id
+ s.nextStreamIDLock.Lock()
+ if s.goAway > 0 {
+ s.nextStreamIDLock.Unlock()
+ return nil, errors.New(errGoAway)
+ }
+
+ s.nextStreamID += 2
+ sid := s.nextStreamID
+ if sid == sid%2 { // stream-id overflows
+ s.goAway = 1
+ s.nextStreamIDLock.Unlock()
+ return nil, errors.New(errGoAway)
+ }
+ s.nextStreamIDLock.Unlock()
+
+ stream := newStream(sid, s.config.MaxFrameSize, s)
+
+ if _, err := s.writeFrame(newFrame(cmdSYN, sid)); err != nil {
+ return nil, errors.Wrap(err, "writeFrame")
+ }
+
+ s.streamLock.Lock()
+ s.streams[sid] = stream
+ s.streamLock.Unlock()
+ return stream, nil
+}
+
+// AcceptStream is used to block until the next available stream
+// is ready to be accepted.
+func (s *Session) AcceptStream() (*Stream, error) {
+ var deadline <-chan time.Time
+ if d, ok := s.deadline.Load().(time.Time); ok && !d.IsZero() {
+ timer := time.NewTimer(time.Until(d))
+ defer timer.Stop()
+ deadline = timer.C
+ }
+ select {
+ case stream := <-s.chAccepts:
+ return stream, nil
+ case <-deadline:
+ return nil, errTimeout
+ case <-s.die:
+ return nil, errors.New(errBrokenPipe)
+ }
+}
+
+// Close is used to close the session and all streams.
+func (s *Session) Close() (err error) {
+ s.dieLock.Lock()
+
+ select {
+ case <-s.die:
+ s.dieLock.Unlock()
+ return errors.New(errBrokenPipe)
+ default:
+ close(s.die)
+ s.dieLock.Unlock()
+ s.streamLock.Lock()
+ for k := range s.streams {
+ s.streams[k].sessionClose()
+ }
+ s.streamLock.Unlock()
+ s.notifyBucket()
+ return s.conn.Close()
+ }
+}
+
+// notifyBucket notifies recvLoop that bucket is available
+func (s *Session) notifyBucket() {
+ select {
+ case s.bucketNotify <- struct{}{}:
+ default:
+ }
+}
+
+// IsClosed does a safe check to see if we have shutdown
+func (s *Session) IsClosed() bool {
+ select {
+ case <-s.die:
+ return true
+ default:
+ return false
+ }
+}
+
+// NumStreams returns the number of currently open streams
+func (s *Session) NumStreams() int {
+ if s.IsClosed() {
+ return 0
+ }
+ s.streamLock.Lock()
+ defer s.streamLock.Unlock()
+ return len(s.streams)
+}
+
+// SetDeadline sets a deadline used by Accept* calls.
+// A zero time value disables the deadline.
+func (s *Session) SetDeadline(t time.Time) error {
+ s.deadline.Store(t)
+ return nil
+}
+
+// notify the session that a stream has closed
+func (s *Session) streamClosed(sid uint32) {
+ s.streamLock.Lock()
+ if n := s.streams[sid].recycleTokens(); n > 0 { // return remaining tokens to the bucket
+ if atomic.AddInt32(&s.bucket, int32(n)) > 0 {
+ s.notifyBucket()
+ }
+ }
+ delete(s.streams, sid)
+ s.streamLock.Unlock()
+}
+
+// returnTokens is called by stream to return token after read
+func (s *Session) returnTokens(n int) {
+ if atomic.AddInt32(&s.bucket, int32(n)) > 0 {
+ s.notifyBucket()
+ }
+}
+
+// session read a frame from underlying connection
+// it's data is pointed to the input buffer
+func (s *Session) readFrame(buffer []byte) (f Frame, err error) {
+ var hdr rawHeader
+ if _, err := io.ReadFull(s.conn, hdr[:]); err != nil {
+ return f, errors.Wrap(err, "readFrame")
+ }
+
+ if hdr.Version() != version {
+ return f, errors.New(errInvalidProtocol)
+ }
+
+ f.ver = hdr.Version()
+ f.cmd = hdr.Cmd()
+ f.sid = hdr.StreamID()
+ if length := hdr.Length(); length > 0 {
+ f.data = buffer[:length]
+ if _, err := io.ReadFull(s.conn, f.data); err != nil {
+ return f, errors.Wrap(err, "readFrame")
+ }
+ }
+ return f, nil
+}
+
+// recvLoop keeps on reading from underlying connection if tokens are available
+func (s *Session) recvLoop() {
+ buffer := make([]byte, 1<<16)
+ for {
+ for atomic.LoadInt32(&s.bucket) <= 0 && !s.IsClosed() {
+ <-s.bucketNotify
+ }
+
+ if f, err := s.readFrame(buffer); err == nil {
+ atomic.StoreInt32(&s.dataReady, 1)
+
+ switch f.cmd {
+ case cmdNOP:
+ case cmdSYN:
+ s.streamLock.Lock()
+ if _, ok := s.streams[f.sid]; !ok {
+ stream := newStream(f.sid, s.config.MaxFrameSize, s)
+ s.streams[f.sid] = stream
+ select {
+ case s.chAccepts <- stream:
+ case <-s.die:
+ }
+ }
+ s.streamLock.Unlock()
+ case cmdFIN:
+ s.streamLock.Lock()
+ if stream, ok := s.streams[f.sid]; ok {
+ stream.markRST()
+ stream.notifyReadEvent()
+ }
+ s.streamLock.Unlock()
+ case cmdPSH:
+ s.streamLock.Lock()
+ if stream, ok := s.streams[f.sid]; ok {
+ atomic.AddInt32(&s.bucket, -int32(len(f.data)))
+ stream.pushBytes(f.data)
+ stream.notifyReadEvent()
+ }
+ s.streamLock.Unlock()
+ default:
+ s.Close()
+ return
+ }
+ } else {
+ s.Close()
+ return
+ }
+ }
+}
+
+func (s *Session) keepalive() {
+ tickerPing := time.NewTicker(s.config.KeepAliveInterval)
+ tickerTimeout := time.NewTicker(s.config.KeepAliveTimeout)
+ defer tickerPing.Stop()
+ defer tickerTimeout.Stop()
+ for {
+ select {
+ case <-tickerPing.C:
+ s.writeFrame(newFrame(cmdNOP, 0))
+ s.notifyBucket() // force a signal to the recvLoop
+ case <-tickerTimeout.C:
+ if !atomic.CompareAndSwapInt32(&s.dataReady, 1, 0) {
+ s.Close()
+ return
+ }
+ case <-s.die:
+ return
+ }
+ }
+}
+
+func (s *Session) sendLoop() {
+ buf := make([]byte, (1<<16)+headerSize)
+ for {
+ select {
+ case <-s.die:
+ return
+ case request := <-s.writes:
+ buf[0] = request.frame.ver
+ buf[1] = request.frame.cmd
+ binary.LittleEndian.PutUint16(buf[2:], uint16(len(request.frame.data)))
+ binary.LittleEndian.PutUint32(buf[4:], request.frame.sid)
+ copy(buf[headerSize:], request.frame.data)
+ n, err := s.conn.Write(buf[:headerSize+len(request.frame.data)])
+
+ n -= headerSize
+ if n < 0 {
+ n = 0
+ }
+
+ result := writeResult{
+ n: n,
+ err: err,
+ }
+
+ request.result <- result
+ close(request.result)
+ }
+ }
+}
+
+// writeFrame writes the frame to the underlying connection
+// and returns the number of bytes written if successful
+func (s *Session) writeFrame(f Frame) (n int, err error) {
+ req := writeRequest{
+ frame: f,
+ result: make(chan writeResult, 1),
+ }
+ select {
+ case <-s.die:
+ return 0, errors.New(errBrokenPipe)
+ case s.writes <- req:
+ }
+
+ result := <-req.result
+ return result.n, result.err
+}
diff --git a/vendor/github.com/xtaci/smux/smux.png b/vendor/github.com/xtaci/smux/smux.png
new file mode 100644
index 000000000..26aba3b72
Binary files /dev/null and b/vendor/github.com/xtaci/smux/smux.png differ
diff --git a/vendor/github.com/xtaci/smux/stream.go b/vendor/github.com/xtaci/smux/stream.go
new file mode 100644
index 000000000..2ce00d2d9
--- /dev/null
+++ b/vendor/github.com/xtaci/smux/stream.go
@@ -0,0 +1,262 @@
+package smux
+
+import (
+ "bytes"
+ "io"
+ "net"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/pkg/errors"
+)
+
+// Stream implements net.Conn
+type Stream struct {
+ id uint32
+ rstflag int32
+ sess *Session
+ buffer bytes.Buffer
+ bufferLock sync.Mutex
+ frameSize int
+ chReadEvent chan struct{} // notify a read event
+ die chan struct{} // flag the stream has closed
+ dieLock sync.Mutex
+ readDeadline atomic.Value
+ writeDeadline atomic.Value
+}
+
+// newStream initiates a Stream struct
+func newStream(id uint32, frameSize int, sess *Session) *Stream {
+ s := new(Stream)
+ s.id = id
+ s.chReadEvent = make(chan struct{}, 1)
+ s.frameSize = frameSize
+ s.sess = sess
+ s.die = make(chan struct{})
+ return s
+}
+
+// ID returns the unique stream ID.
+func (s *Stream) ID() uint32 {
+ return s.id
+}
+
+// Read implements net.Conn
+func (s *Stream) Read(b []byte) (n int, err error) {
+ if len(b) == 0 {
+ select {
+ case <-s.die:
+ return 0, errors.New(errBrokenPipe)
+ default:
+ return 0, nil
+ }
+ }
+
+ var deadline <-chan time.Time
+ if d, ok := s.readDeadline.Load().(time.Time); ok && !d.IsZero() {
+ timer := time.NewTimer(time.Until(d))
+ defer timer.Stop()
+ deadline = timer.C
+ }
+
+READ:
+ s.bufferLock.Lock()
+ n, _ = s.buffer.Read(b)
+ s.bufferLock.Unlock()
+
+ if n > 0 {
+ s.sess.returnTokens(n)
+ return n, nil
+ } else if atomic.LoadInt32(&s.rstflag) == 1 {
+ _ = s.Close()
+ return 0, io.EOF
+ }
+
+ select {
+ case <-s.chReadEvent:
+ goto READ
+ case <-deadline:
+ return n, errTimeout
+ case <-s.die:
+ return 0, errors.New(errBrokenPipe)
+ }
+}
+
+// Write implements net.Conn
+func (s *Stream) Write(b []byte) (n int, err error) {
+ var deadline <-chan time.Time
+ if d, ok := s.writeDeadline.Load().(time.Time); ok && !d.IsZero() {
+ timer := time.NewTimer(time.Until(d))
+ defer timer.Stop()
+ deadline = timer.C
+ }
+
+ select {
+ case <-s.die:
+ return 0, errors.New(errBrokenPipe)
+ default:
+ }
+
+ frames := s.split(b, cmdPSH, s.id)
+ sent := 0
+ for k := range frames {
+ req := writeRequest{
+ frame: frames[k],
+ result: make(chan writeResult, 1),
+ }
+
+ select {
+ case s.sess.writes <- req:
+ case <-s.die:
+ return sent, errors.New(errBrokenPipe)
+ case <-deadline:
+ return sent, errTimeout
+ }
+
+ select {
+ case result := <-req.result:
+ sent += result.n
+ if result.err != nil {
+ return sent, result.err
+ }
+ case <-s.die:
+ return sent, errors.New(errBrokenPipe)
+ case <-deadline:
+ return sent, errTimeout
+ }
+ }
+ return sent, nil
+}
+
+// Close implements net.Conn
+func (s *Stream) Close() error {
+ s.dieLock.Lock()
+
+ select {
+ case <-s.die:
+ s.dieLock.Unlock()
+ return errors.New(errBrokenPipe)
+ default:
+ close(s.die)
+ s.dieLock.Unlock()
+ s.sess.streamClosed(s.id)
+ _, err := s.sess.writeFrame(newFrame(cmdFIN, s.id))
+ return err
+ }
+}
+
+// SetReadDeadline sets the read deadline as defined by
+// net.Conn.SetReadDeadline.
+// A zero time value disables the deadline.
+func (s *Stream) SetReadDeadline(t time.Time) error {
+ s.readDeadline.Store(t)
+ return nil
+}
+
+// SetWriteDeadline sets the write deadline as defined by
+// net.Conn.SetWriteDeadline.
+// A zero time value disables the deadline.
+func (s *Stream) SetWriteDeadline(t time.Time) error {
+ s.writeDeadline.Store(t)
+ return nil
+}
+
+// SetDeadline sets both read and write deadlines as defined by
+// net.Conn.SetDeadline.
+// A zero time value disables the deadlines.
+func (s *Stream) SetDeadline(t time.Time) error {
+ if err := s.SetReadDeadline(t); err != nil {
+ return err
+ }
+ if err := s.SetWriteDeadline(t); err != nil {
+ return err
+ }
+ return nil
+}
+
+// session closes the stream
+func (s *Stream) sessionClose() {
+ s.dieLock.Lock()
+ defer s.dieLock.Unlock()
+
+ select {
+ case <-s.die:
+ default:
+ close(s.die)
+ }
+}
+
+// LocalAddr satisfies net.Conn interface
+func (s *Stream) LocalAddr() net.Addr {
+ if ts, ok := s.sess.conn.(interface {
+ LocalAddr() net.Addr
+ }); ok {
+ return ts.LocalAddr()
+ }
+ return nil
+}
+
+// RemoteAddr satisfies net.Conn interface
+func (s *Stream) RemoteAddr() net.Addr {
+ if ts, ok := s.sess.conn.(interface {
+ RemoteAddr() net.Addr
+ }); ok {
+ return ts.RemoteAddr()
+ }
+ return nil
+}
+
+// pushBytes a slice into buffer
+func (s *Stream) pushBytes(p []byte) {
+ s.bufferLock.Lock()
+ s.buffer.Write(p)
+ s.bufferLock.Unlock()
+}
+
+// recycleTokens transform remaining bytes to tokens(will truncate buffer)
+func (s *Stream) recycleTokens() (n int) {
+ s.bufferLock.Lock()
+ n = s.buffer.Len()
+ s.buffer.Reset()
+ s.bufferLock.Unlock()
+ return
+}
+
+// split large byte buffer into smaller frames, reference only
+func (s *Stream) split(bts []byte, cmd byte, sid uint32) []Frame {
+ frames := make([]Frame, 0, len(bts)/s.frameSize+1)
+ for len(bts) > s.frameSize {
+ frame := newFrame(cmd, sid)
+ frame.data = bts[:s.frameSize]
+ bts = bts[s.frameSize:]
+ frames = append(frames, frame)
+ }
+ if len(bts) > 0 {
+ frame := newFrame(cmd, sid)
+ frame.data = bts
+ frames = append(frames, frame)
+ }
+ return frames
+}
+
+// notify read event
+func (s *Stream) notifyReadEvent() {
+ select {
+ case s.chReadEvent <- struct{}{}:
+ default:
+ }
+}
+
+// mark this stream has been reset
+func (s *Stream) markRST() {
+ atomic.StoreInt32(&s.rstflag, 1)
+}
+
+var errTimeout error = &timeoutError{}
+
+type timeoutError struct{}
+
+func (e *timeoutError) Error() string { return "i/o timeout" }
+func (e *timeoutError) Timeout() bool { return true }
+func (e *timeoutError) Temporary() bool { return true }
diff --git a/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s b/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s
new file mode 100644
index 000000000..06f84b855
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s
@@ -0,0 +1,17 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !gccgo
+
+#include "textflag.h"
+
+//
+// System calls for ppc64, AIX are implemented in runtime/syscall_aix.go
+//
+
+TEXT ·syscall6(SB),NOSPLIT,$0-88
+ JMP syscall·syscall6(SB)
+
+TEXT ·rawSyscall6(SB),NOSPLIT,$0-88
+ JMP syscall·rawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/mkall.sh b/vendor/golang.org/x/sys/unix/mkall.sh
index edb176f16..9b76ad669 100755
--- a/vendor/golang.org/x/sys/unix/mkall.sh
+++ b/vendor/golang.org/x/sys/unix/mkall.sh
@@ -61,12 +61,12 @@ _* | *_ | _)
;;
aix_ppc)
mkerrors="$mkerrors -maix32"
- mksyscall="perl mksyscall_aix.pl -aix"
+ mksyscall="./mksyscall_aix_ppc.pl -aix"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
aix_ppc64)
mkerrors="$mkerrors -maix64"
- mksyscall="perl mksyscall_aix.pl -aix"
+ mksyscall="./mksyscall_aix_ppc64.pl -aix"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
darwin_386)
@@ -187,8 +187,14 @@ esac
syscall_goos="syscall_bsd.go $syscall_goos"
;;
esac
- if [ -n "$mksyscall" ]; then echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go"; fi
- ;;
+ if [ -n "$mksyscall" ]; then
+ if [ "$GOOSARCH" == "aix_ppc64" ]; then
+ # aix/ppc64 script generates files instead of writing to stdin.
+ echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ;
+ else
+ echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go";
+ fi
+ fi
esac
if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh
index 7943853ff..73e179a89 100755
--- a/vendor/golang.org/x/sys/unix/mkerrors.sh
+++ b/vendor/golang.org/x/sys/unix/mkerrors.sh
@@ -197,6 +197,7 @@ struct ltchars {
#include
#include
#include
+#include
#include
#include
#include
@@ -449,6 +450,7 @@ ccflags="$@"
$2 ~ /^KEXEC_/ ||
$2 ~ /^LINUX_REBOOT_CMD_/ ||
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
+ $2 ~ /^MODULE_INIT_/ ||
$2 !~ "NLA_TYPE_MASK" &&
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ ||
$2 ~ /^SIOC/ ||
diff --git a/vendor/golang.org/x/sys/unix/mksyscall_aix.pl b/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.pl
old mode 100644
new mode 100755
similarity index 98%
rename from vendor/golang.org/x/sys/unix/mksyscall_aix.pl
rename to vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.pl
index c9b3954ba..c44de8d31
--- a/vendor/golang.org/x/sys/unix/mksyscall_aix.pl
+++ b/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.pl
@@ -19,7 +19,7 @@
use strict;
-my $cmdline = "mksyscall_aix.pl " . join(' ', @ARGV);
+my $cmdline = "mksyscall_aix_ppc.pl " . join(' ', @ARGV);
my $errors = 0;
my $_32bit = "";
my $tags = ""; # build tags
@@ -72,7 +72,7 @@ ($)
my $package = "";
my $text = "";
-my $c_extern = "/*\n#include \n";
+my $c_extern = "/*\n#include \n#include \n";
my @vars = ();
while(<>) {
chomp;
@@ -369,7 +369,6 @@ package $package
import "C"
import (
"unsafe"
- "syscall"
)
diff --git a/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.pl b/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.pl
new file mode 100755
index 000000000..53df26bb9
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.pl
@@ -0,0 +1,579 @@
+#!/usr/bin/env perl
+# Copyright 2018 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# This program reads a file containing function prototypes
+# (like syscall_aix.go) and generates system call bodies.
+# The prototypes are marked by lines beginning with "//sys"
+# and read like func declarations if //sys is replaced by func, but:
+# * The parameter lists must give a name for each argument.
+# This includes return parameters.
+# * The parameter lists must give a type for each argument:
+# the (x, y, z int) shorthand is not allowed.
+# * If the return parameter is an error number, it must be named err.
+# * If go func name needs to be different than its libc name,
+# * or the function is not in libc, name could be specified
+# * at the end, after "=" sign, like
+# //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
+
+# This program will generate three files and handle both gc and gccgo implementation:
+# - zsyscall_aix_ppc64.go: the common part of each implementation (error handler, pointer creation)
+# - zsyscall_aix_ppc64_gc.go: gc part with //go_cgo_import_dynamic and a call to syscall6
+# - zsyscall_aix_ppc64_gccgo.go: gccgo part with C function and conversion to C type.
+
+# The generated code looks like this
+#
+# zsyscall_aix_ppc64.go
+# func asyscall(...) (n int, err error) {
+# // Pointer Creation
+# r1, e1 := callasyscall(...)
+# // Type Conversion
+# // Error Handler
+# return
+# }
+#
+# zsyscall_aix_ppc64_gc.go
+# //go:cgo_import_dynamic libc_asyscall asyscall "libc.a/shr_64.o"
+# //go:linkname libc_asyscall libc_asyscall
+# var asyscall syscallFunc
+#
+# func callasyscall(...) (r1 uintptr, e1 Errno) {
+# r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_asyscall)), "nb_args", ... )
+# return
+# }
+#
+# zsyscall_aix_ppc64_ggcgo.go
+# /*
+# int asyscall(...)
+#
+# */
+# import "C"
+#
+# func callasyscall(...) (r1 uintptr, e1 Errno) {
+# r1 = uintptr(C.asyscall(...))
+# e1 = syscall.GetErrno()
+# return
+# }
+
+
+
+use strict;
+
+my $cmdline = "mksyscall_aix_ppc64.pl " . join(' ', @ARGV);
+my $errors = 0;
+my $_32bit = "";
+my $tags = ""; # build tags
+my $aix = 0;
+my $solaris = 0;
+
+binmode STDOUT;
+
+if($ARGV[0] eq "-b32") {
+ $_32bit = "big-endian";
+ shift;
+} elsif($ARGV[0] eq "-l32") {
+ $_32bit = "little-endian";
+ shift;
+}
+if($ARGV[0] eq "-aix") {
+ $aix = 1;
+ shift;
+}
+if($ARGV[0] eq "-tags") {
+ shift;
+ $tags = $ARGV[0];
+ shift;
+}
+
+if($ARGV[0] =~ /^-/) {
+ print STDERR "usage: mksyscall_aix.pl [-b32 | -l32] [-tags x,y] [file ...]\n";
+ exit 1;
+}
+
+sub parseparamlist($) {
+ my ($list) = @_;
+ $list =~ s/^\s*//;
+ $list =~ s/\s*$//;
+ if($list eq "") {
+ return ();
+ }
+ return split(/\s*,\s*/, $list);
+}
+
+sub parseparam($) {
+ my ($p) = @_;
+ if($p !~ /^(\S*) (\S*)$/) {
+ print STDERR "$ARGV:$.: malformed parameter: $p\n";
+ $errors = 1;
+ return ("xx", "int");
+ }
+ return ($1, $2);
+}
+
+my $package = "";
+# GCCGO
+my $textgccgo = "";
+my $c_extern = "/*\n#include \n";
+# GC
+my $textgc = "";
+my $dynimports = "";
+my $linknames = "";
+my @vars = ();
+# COMMUN
+my $textcommon = "";
+
+while(<>) {
+ chomp;
+ s/\s+/ /g;
+ s/^\s+//;
+ s/\s+$//;
+ $package = $1 if !$package && /^package (\S+)$/;
+ my $nonblock = /^\/\/sysnb /;
+ next if !/^\/\/sys / && !$nonblock;
+
+ # Line must be of the form
+ # func Open(path string, mode int, perm int) (fd int, err error)
+ # Split into name, in params, out params.
+ if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) {
+ print STDERR "$ARGV:$.: malformed //sys declaration\n";
+ $errors = 1;
+ next;
+ }
+ my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6);
+
+ # Split argument lists on comma.
+ my @in = parseparamlist($in);
+ my @out = parseparamlist($out);
+
+ $in = join(', ', @in);
+ $out = join(', ', @out);
+
+ if($sysname eq "") {
+ $sysname = "$func";
+ }
+
+ my $onlyCommon = 0;
+ if ($func eq "readlen" || $func eq "writelen" || $func eq "FcntlInt" || $func eq "FcntlFlock") {
+ # This function call another syscall which is already implemented.
+ # Therefore, the gc and gccgo part must not be generated.
+ $onlyCommon = 1
+ }
+
+ # Try in vain to keep people from editing this file.
+ # The theory is that they jump into the middle of the file
+ # without reading the header.
+
+ $textcommon .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
+ if (!$onlyCommon) {
+ $textgccgo .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
+ $textgc .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
+ }
+
+
+ # Check if value return, err return available
+ my $errvar = "";
+ my $retvar = "";
+ my $rettype = "";
+ foreach my $p (@out) {
+ my ($name, $type) = parseparam($p);
+ if($type eq "error") {
+ $errvar = $name;
+ } else {
+ $retvar = $name;
+ $rettype = $type;
+ }
+ }
+
+
+ $sysname =~ s/([a-z])([A-Z])/${1}_$2/g;
+ $sysname =~ y/A-Z/a-z/; # All libc functions are lowercase.
+
+ # GCCGO Prototype return type
+ my $C_rettype = "";
+ if($rettype eq "unsafe.Pointer") {
+ $C_rettype = "uintptr_t";
+ } elsif($rettype eq "uintptr") {
+ $C_rettype = "uintptr_t";
+ } elsif($rettype =~ /^_/) {
+ $C_rettype = "uintptr_t";
+ } elsif($rettype eq "int") {
+ $C_rettype = "int";
+ } elsif($rettype eq "int32") {
+ $C_rettype = "int";
+ } elsif($rettype eq "int64") {
+ $C_rettype = "long long";
+ } elsif($rettype eq "uint32") {
+ $C_rettype = "unsigned int";
+ } elsif($rettype eq "uint64") {
+ $C_rettype = "unsigned long long";
+ } else {
+ $C_rettype = "int";
+ }
+ if($sysname eq "exit") {
+ $C_rettype = "void";
+ }
+
+ # GCCGO Prototype arguments type
+ my @c_in = ();
+ foreach my $i (0 .. $#in) {
+ my ($name, $type) = parseparam($in[$i]);
+ if($type =~ /^\*/) {
+ push @c_in, "uintptr_t";
+ } elsif($type eq "string") {
+ push @c_in, "uintptr_t";
+ } elsif($type =~ /^\[\](.*)/) {
+ push @c_in, "uintptr_t", "size_t";
+ } elsif($type eq "unsafe.Pointer") {
+ push @c_in, "uintptr_t";
+ } elsif($type eq "uintptr") {
+ push @c_in, "uintptr_t";
+ } elsif($type =~ /^_/) {
+ push @c_in, "uintptr_t";
+ } elsif($type eq "int") {
+ if (($i == 0 || $i == 2) && $func eq "fcntl"){
+ # These fcntl arguments needs to be uintptr to be able to call FcntlInt and FcntlFlock
+ push @c_in, "uintptr_t";
+ } else {
+ push @c_in, "int";
+ }
+ } elsif($type eq "int32") {
+ push @c_in, "int";
+ } elsif($type eq "int64") {
+ push @c_in, "long long";
+ } elsif($type eq "uint32") {
+ push @c_in, "unsigned int";
+ } elsif($type eq "uint64") {
+ push @c_in, "unsigned long long";
+ } else {
+ push @c_in, "int";
+ }
+ }
+
+ if (!$onlyCommon){
+ # GCCGO Prototype Generation
+ # Imports of system calls from libc
+ $c_extern .= "$C_rettype $sysname";
+ my $c_in = join(', ', @c_in);
+ $c_extern .= "($c_in);\n";
+ }
+
+ # GC Library name
+ if($modname eq "") {
+ $modname = "libc.a/shr_64.o";
+ } else {
+ print STDERR "$func: only syscall using libc are available\n";
+ $errors = 1;
+ next;
+ }
+ my $sysvarname = "libc_${sysname}";
+
+ if (!$onlyCommon){
+ # GC Runtime import of function to allow cross-platform builds.
+ $dynimports .= "//go:cgo_import_dynamic ${sysvarname} ${sysname} \"$modname\"\n";
+ # GC Link symbol to proc address variable.
+ $linknames .= "//go:linkname ${sysvarname} ${sysvarname}\n";
+ # GC Library proc address variable.
+ push @vars, $sysvarname;
+ }
+
+ my $strconvfunc ="BytePtrFromString";
+ my $strconvtype = "*byte";
+
+ # Go function header.
+ if($out ne "") {
+ $out = " ($out)";
+ }
+ if($textcommon ne "") {
+ $textcommon .= "\n"
+ }
+
+ $textcommon .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out ;
+
+ # Prepare arguments to call.
+ my @argscommun = (); # Arguments in the commun part
+ my @argscall = (); # Arguments for call prototype
+ my @argsgc = (); # Arguments for gc call (with syscall6)
+ my @argsgccgo = (); # Arguments for gccgo call (with C.name_of_syscall)
+ my $n = 0;
+ my $arg_n = 0;
+ foreach my $p (@in) {
+ my ($name, $type) = parseparam($p);
+ if($type =~ /^\*/) {
+ push @argscommun, "uintptr(unsafe.Pointer($name))";
+ push @argscall, "$name uintptr";
+ push @argsgc, "$name";
+ push @argsgccgo, "C.uintptr_t($name)";
+ } elsif($type eq "string" && $errvar ne "") {
+ $textcommon .= "\tvar _p$n $strconvtype\n";
+ $textcommon .= "\t_p$n, $errvar = $strconvfunc($name)\n";
+ $textcommon .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
+
+ push @argscommun, "uintptr(unsafe.Pointer(_p$n))";
+ push @argscall, "_p$n uintptr ";
+ push @argsgc, "_p$n";
+ push @argsgccgo, "C.uintptr_t(_p$n)";
+ $n++;
+ } elsif($type eq "string") {
+ print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
+ $textcommon .= "\tvar _p$n $strconvtype\n";
+ $textcommon .= "\t_p$n, $errvar = $strconvfunc($name)\n";
+ $textcommon .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
+
+ push @argscommun, "uintptr(unsafe.Pointer(_p$n))";
+ push @argscall, "_p$n uintptr";
+ push @argsgc, "_p$n";
+ push @argsgccgo, "C.uintptr_t(_p$n)";
+ $n++;
+ } elsif($type =~ /^\[\](.*)/) {
+ # Convert slice into pointer, length.
+ # Have to be careful not to take address of &a[0] if len == 0:
+ # pass nil in that case.
+ $textcommon .= "\tvar _p$n *$1\n";
+ $textcommon .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n";
+ push @argscommun, "uintptr(unsafe.Pointer(_p$n))", "len($name)";
+ push @argscall, "_p$n uintptr", "_lenp$n int";
+ push @argsgc, "_p$n", "uintptr(_lenp$n)";
+ push @argsgccgo, "C.uintptr_t(_p$n)", "C.size_t(_lenp$n)";
+ $n++;
+ } elsif($type eq "int64" && $_32bit ne "") {
+ print STDERR "$ARGV:$.: $func uses int64 with 32 bits mode. Case not yet implemented\n";
+ # if($_32bit eq "big-endian") {
+ # push @args, "uintptr($name >> 32)", "uintptr($name)";
+ # } else {
+ # push @args, "uintptr($name)", "uintptr($name >> 32)";
+ # }
+ # $n++;
+ } elsif($type eq "bool") {
+ print STDERR "$ARGV:$.: $func uses bool. Case not yet implemented\n";
+ # $text .= "\tvar _p$n uint32\n";
+ # $text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n";
+ # push @args, "_p$n";
+ # $n++;
+ } elsif($type =~ /^_/ ||$type eq "unsafe.Pointer") {
+ push @argscommun, "uintptr($name)";
+ push @argscall, "$name uintptr";
+ push @argsgc, "$name";
+ push @argsgccgo, "C.uintptr_t($name)";
+ } elsif($type eq "int") {
+ if (($arg_n == 0 || $arg_n == 2) && ($func eq "fcntl" || $func eq "FcntlInt" || $func eq "FcntlFlock")) {
+ # These fcntl arguments need to be uintptr to be able to call FcntlInt and FcntlFlock
+ push @argscommun, "uintptr($name)";
+ push @argscall, "$name uintptr";
+ push @argsgc, "$name";
+ push @argsgccgo, "C.uintptr_t($name)";
+ } else {
+ push @argscommun, "$name";
+ push @argscall, "$name int";
+ push @argsgc, "uintptr($name)";
+ push @argsgccgo, "C.int($name)";
+ }
+ } elsif($type eq "int32") {
+ push @argscommun, "$name";
+ push @argscall, "$name int32";
+ push @argsgc, "uintptr($name)";
+ push @argsgccgo, "C.int($name)";
+ } elsif($type eq "int64") {
+ push @argscommun, "$name";
+ push @argscall, "$name int64";
+ push @argsgc, "uintptr($name)";
+ push @argsgccgo, "C.longlong($name)";
+ } elsif($type eq "uint32") {
+ push @argscommun, "$name";
+ push @argscall, "$name uint32";
+ push @argsgc, "uintptr($name)";
+ push @argsgccgo, "C.uint($name)";
+ } elsif($type eq "uint64") {
+ push @argscommun, "$name";
+ push @argscall, "$name uint64";
+ push @argsgc, "uintptr($name)";
+ push @argsgccgo, "C.ulonglong($name)";
+ } elsif($type eq "uintptr") {
+ push @argscommun, "$name";
+ push @argscall, "$name uintptr";
+ push @argsgc, "$name";
+ push @argsgccgo, "C.uintptr_t($name)";
+ } else {
+ push @argscommun, "int($name)";
+ push @argscall, "$name int";
+ push @argsgc, "uintptr($name)";
+ push @argsgccgo, "C.int($name)";
+ }
+ $arg_n++;
+ }
+ my $nargs = @argsgc;
+
+ # COMMUN function generation
+ my $argscommun = join(', ', @argscommun);
+ my $callcommun = "call$sysname($argscommun)";
+ my @ret = ("_", "_");
+ my $body = "";
+ my $do_errno = 0;
+ for(my $i=0; $i<@out; $i++) {
+ my $p = $out[$i];
+ my ($name, $type) = parseparam($p);
+ my $reg = "";
+ if($name eq "err") {
+ $reg = "e1";
+ $ret[1] = $reg;
+ $do_errno = 1;
+ } else {
+ $reg = "r0";
+ $ret[0] = $reg;
+ }
+ if($type eq "bool") {
+ $reg = "$reg != 0";
+ }
+ if($reg ne "e1") {
+ $body .= "\t$name = $type($reg)\n";
+ }
+ }
+ if ($ret[0] eq "_" && $ret[1] eq "_") {
+ $textcommon .= "\t$callcommun\n";
+ } else {
+ $textcommon .= "\t$ret[0], $ret[1] := $callcommun\n";
+ }
+ $textcommon .= $body;
+
+ if ($do_errno) {
+ $textcommon .= "\tif e1 != 0 {\n";
+ $textcommon .= "\t\terr = errnoErr(e1)\n";
+ $textcommon .= "\t}\n";
+ }
+ $textcommon .= "\treturn\n";
+ $textcommon .= "}\n";
+
+ if ($onlyCommon){
+ next
+ }
+ # CALL Prototype
+ my $callProto = sprintf "func call%s(%s) (r1 uintptr, e1 Errno) {\n", $sysname, join(', ', @argscall);
+
+ # GC function generation
+ my $asm = "syscall6";
+ if ($nonblock) {
+ $asm = "rawSyscall6";
+ }
+
+ if(@argsgc <= 6) {
+ while(@argsgc < 6) {
+ push @argsgc, "0";
+ }
+ } else {
+ print STDERR "$ARGV:$.: too many arguments to system call\n";
+ }
+ my $argsgc = join(', ', @argsgc);
+ my $callgc = "$asm(uintptr(unsafe.Pointer(&$sysvarname)), $nargs, $argsgc)";
+
+ $textgc .= $callProto;
+ $textgc .= "\tr1, _, e1 = $callgc\n";
+ $textgc .= "\treturn\n}\n";
+
+ # GCCGO function generation
+ my $argsgccgo = join(', ', @argsgccgo);
+ my $callgccgo = "C.$sysname($argsgccgo)";
+ $textgccgo .= $callProto;
+ $textgccgo .= "\tr1 = uintptr($callgccgo)\n";
+ $textgccgo .= "\te1 = syscall.GetErrno()\n";
+ $textgccgo .= "\treturn\n}\n";
+}
+
+if($errors) {
+ exit 1;
+}
+
+# Print zsyscall_aix_ppc64.go
+open(my $fcommun, '>', 'zsyscall_aix_ppc64.go');
+my $tofcommun = <', 'zsyscall_aix_ppc64_gc.go');
+my $tofgc = <', 'zsyscall_aix_ppc64_gccgo.go');
+my $tofgccgo = <>8) & 0xFF
+ return Signal(w>>8) & 0xFF
}
func (w WaitStatus) Exited() bool { return w&0xFF == 0 }
@@ -321,11 +321,11 @@ func (w WaitStatus) ExitStatus() int {
}
func (w WaitStatus) Signaled() bool { return w&0x40 == 0 && w&0xFF != 0 }
-func (w WaitStatus) Signal() syscall.Signal {
+func (w WaitStatus) Signal() Signal {
if !w.Signaled() {
return -1
}
- return syscall.Signal(w>>16) & 0xFF
+ return Signal(w>>16) & 0xFF
}
func (w WaitStatus) Continued() bool { return w&0x01000000 != 0 }
@@ -383,6 +383,8 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
//sys FcntlFlock(fd uintptr, cmd int, lk *Flock_t) (err error) = fcntl
+//sys fcntl(fd int, cmd int, arg int) (val int, err error)
+
func Flock(fd int, how int) (err error) {
return syscall.Flock(fd, how)
}
@@ -396,15 +398,12 @@ func Flock(fd int, how int) (err error) {
//sys Chroot(path string) (err error)
//sys Close(fd int) (err error)
//sys Dup(oldfd int) (fd int, err error)
-//sys Dup3(oldfd int, newfd int, flags int) (err error)
//sys Exit(code int)
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
-//sys Fallocate(fd int, mode uint32, off int64, len int64) (err error)
//sys Fchdir(fd int) (err error)
//sys Fchmod(fd int, mode uint32) (err error)
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
-//sys fcntl(fd int, cmd int, arg int) (val int, err error)
//sys Fdatasync(fd int) (err error)
//sys Fsync(fd int) (err error)
// readdir_r
@@ -417,7 +416,7 @@ func Flock(fd int, how int) (err error) {
//sys Getpriority(which int, who int) (prio int, err error)
//sysnb Getrusage(who int, rusage *Rusage) (err error)
//sysnb Getsid(pid int) (sid int, err error)
-//sysnb Kill(pid int, sig syscall.Signal) (err error)
+//sysnb Kill(pid int, sig Signal) (err error)
//sys Klogctl(typ int, buf []byte) (n int, err error) = syslog
//sys Mkdir(dirfd int, path string, mode uint32) (err error)
//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
@@ -429,7 +428,6 @@ func Flock(fd int, how int) (err error) {
//sys Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
//sys read(fd int, p []byte) (n int, err error)
//sys Readlink(path string, buf []byte) (n int, err error)
-//sys Removexattr(path string, attr string) (err error)
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Setdomainname(p []byte) (err error)
//sys Sethostname(p []byte) (err error)
@@ -443,7 +441,6 @@ func Flock(fd int, how int) (err error) {
//sys Setpriority(which int, who int, prio int) (err error)
//sys Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error)
//sys Sync()
-//sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
//sysnb Times(tms *Tms) (ticks uintptr, err error)
//sysnb Umask(mask int) (oldmask int)
//sysnb Uname(buf *Utsname) (err error)
@@ -451,7 +448,6 @@ func Flock(fd int, how int) (err error) {
// //sys Unmount(target string, flags int) (err error) = umount
//sys Unlink(path string) (err error)
//sys Unlinkat(dirfd int, path string, flags int) (err error)
-//sys Unshare(flags int) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys write(fd int, p []byte) (n int, err error)
//sys readlen(fd int, p *byte, np int) (n int, err error) = read
@@ -537,19 +533,6 @@ func Pipe(p []int) (err error) {
return
}
-//sysnb pipe2(p *[2]_C_int, flags int) (err error)
-
-func Pipe2(p []int, flags int) (err error) {
- if len(p) != 2 {
- return EINVAL
- }
- var pp [2]_C_int
- err = pipe2(&pp, flags)
- p[0] = int(pp[0])
- p[1] = int(pp[1])
- return
-}
-
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
diff --git a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go
index 79d125b30..6401e3a29 100644
--- a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go
+++ b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go
@@ -287,6 +287,7 @@ func Uname(uname *Utsname) error {
//sys Mknod(path string, mode uint32, dev int) (err error)
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys Open(path string, mode int, perm uint32) (fd int, err error)
+//sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val int, err error)
//sys read(fd int, p []byte) (n int, err error)
//sys Readlink(path string, buf []byte) (n int, err error)
diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/vendor/golang.org/x/sys/unix/syscall_freebsd.go
index 77a634c76..085a808cc 100644
--- a/vendor/golang.org/x/sys/unix/syscall_freebsd.go
+++ b/vendor/golang.org/x/sys/unix/syscall_freebsd.go
@@ -13,9 +13,34 @@
package unix
import (
+ "sync"
"unsafe"
)
+const (
+ SYS_FSTAT_FREEBSD12 = 551 // { int fstat(int fd, _Out_ struct stat *sb); }
+ SYS_FSTATAT_FREEBSD12 = 552 // { int fstatat(int fd, _In_z_ char *path, \
+ SYS_GETDIRENTRIES_FREEBSD12 = 554 // { ssize_t getdirentries(int fd, \
+ SYS_STATFS_FREEBSD12 = 555 // { int statfs(_In_z_ char *path, \
+ SYS_FSTATFS_FREEBSD12 = 556 // { int fstatfs(int fd, \
+ SYS_GETFSSTAT_FREEBSD12 = 557 // { int getfsstat( \
+ SYS_MKNODAT_FREEBSD12 = 559 // { int mknodat(int fd, _In_z_ char *path, \
+)
+
+// See https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/versions.html.
+var (
+ osreldateOnce sync.Once
+ osreldate uint32
+)
+
+// INO64_FIRST from /usr/src/lib/libc/sys/compat-ino64.h
+const _ino64First = 1200031
+
+func supportsABI(ver uint32) bool {
+ osreldateOnce.Do(func() { osreldate, _ = SysctlUint32("kern.osreldate") })
+ return osreldate >= ver
+}
+
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
type SockaddrDatalink struct {
Len uint8
@@ -121,17 +146,39 @@ func Getwd() (string, error) {
}
func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
- var _p0 unsafe.Pointer
- var bufsize uintptr
+ var (
+ _p0 unsafe.Pointer
+ bufsize uintptr
+ oldBuf []statfs_freebsd11_t
+ needsConvert bool
+ )
+
if len(buf) > 0 {
- _p0 = unsafe.Pointer(&buf[0])
- bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
+ if supportsABI(_ino64First) {
+ _p0 = unsafe.Pointer(&buf[0])
+ bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
+ } else {
+ n := len(buf)
+ oldBuf = make([]statfs_freebsd11_t, n)
+ _p0 = unsafe.Pointer(&oldBuf[0])
+ bufsize = unsafe.Sizeof(statfs_freebsd11_t{}) * uintptr(n)
+ needsConvert = true
+ }
}
- r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
+ var sysno uintptr = SYS_GETFSSTAT
+ if supportsABI(_ino64First) {
+ sysno = SYS_GETFSSTAT_FREEBSD12
+ }
+ r0, _, e1 := Syscall(sysno, uintptr(_p0), bufsize, uintptr(flags))
n = int(r0)
if e1 != 0 {
err = e1
}
+ if e1 == 0 && needsConvert {
+ for i := range oldBuf {
+ buf[i].convertFrom(&oldBuf[i])
+ }
+ }
return
}
@@ -225,6 +272,234 @@ func Uname(uname *Utsname) error {
return nil
}
+func Stat(path string, st *Stat_t) (err error) {
+ var oldStat stat_freebsd11_t
+ if supportsABI(_ino64First) {
+ return fstatat_freebsd12(AT_FDCWD, path, st, 0)
+ }
+ err = stat(path, &oldStat)
+ if err != nil {
+ return err
+ }
+
+ st.convertFrom(&oldStat)
+ return nil
+}
+
+func Lstat(path string, st *Stat_t) (err error) {
+ var oldStat stat_freebsd11_t
+ if supportsABI(_ino64First) {
+ return fstatat_freebsd12(AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW)
+ }
+ err = lstat(path, &oldStat)
+ if err != nil {
+ return err
+ }
+
+ st.convertFrom(&oldStat)
+ return nil
+}
+
+func Fstat(fd int, st *Stat_t) (err error) {
+ var oldStat stat_freebsd11_t
+ if supportsABI(_ino64First) {
+ return fstat_freebsd12(fd, st)
+ }
+ err = fstat(fd, &oldStat)
+ if err != nil {
+ return err
+ }
+
+ st.convertFrom(&oldStat)
+ return nil
+}
+
+func Fstatat(fd int, path string, st *Stat_t, flags int) (err error) {
+ var oldStat stat_freebsd11_t
+ if supportsABI(_ino64First) {
+ return fstatat_freebsd12(fd, path, st, flags)
+ }
+ err = fstatat(fd, path, &oldStat, flags)
+ if err != nil {
+ return err
+ }
+
+ st.convertFrom(&oldStat)
+ return nil
+}
+
+func Statfs(path string, st *Statfs_t) (err error) {
+ var oldStatfs statfs_freebsd11_t
+ if supportsABI(_ino64First) {
+ return statfs_freebsd12(path, st)
+ }
+ err = statfs(path, &oldStatfs)
+ if err != nil {
+ return err
+ }
+
+ st.convertFrom(&oldStatfs)
+ return nil
+}
+
+func Fstatfs(fd int, st *Statfs_t) (err error) {
+ var oldStatfs statfs_freebsd11_t
+ if supportsABI(_ino64First) {
+ return fstatfs_freebsd12(fd, st)
+ }
+ err = fstatfs(fd, &oldStatfs)
+ if err != nil {
+ return err
+ }
+
+ st.convertFrom(&oldStatfs)
+ return nil
+}
+
+func Getdents(fd int, buf []byte) (n int, err error) {
+ return Getdirentries(fd, buf, nil)
+}
+
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+ if supportsABI(_ino64First) {
+ return getdirentries_freebsd12(fd, buf, basep)
+ }
+
+ // The old syscall entries are smaller than the new. Use 1/4 of the original
+ // buffer size rounded up to DIRBLKSIZ (see /usr/src/lib/libc/sys/getdirentries.c).
+ oldBufLen := roundup(len(buf)/4, _dirblksiz)
+ oldBuf := make([]byte, oldBufLen)
+ n, err = getdirentries(fd, oldBuf, basep)
+ if err == nil && n > 0 {
+ n = convertFromDirents11(buf, oldBuf[:n])
+ }
+ return
+}
+
+func Mknod(path string, mode uint32, dev uint64) (err error) {
+ var oldDev int
+ if supportsABI(_ino64First) {
+ return mknodat_freebsd12(AT_FDCWD, path, mode, dev)
+ }
+ oldDev = int(dev)
+ return mknod(path, mode, oldDev)
+}
+
+func Mknodat(fd int, path string, mode uint32, dev uint64) (err error) {
+ var oldDev int
+ if supportsABI(_ino64First) {
+ return mknodat_freebsd12(fd, path, mode, dev)
+ }
+ oldDev = int(dev)
+ return mknodat(fd, path, mode, oldDev)
+}
+
+// round x to the nearest multiple of y, larger or equal to x.
+//
+// from /usr/include/sys/param.h Macros for counting and rounding.
+// #define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
+func roundup(x, y int) int {
+ return ((x + y - 1) / y) * y
+}
+
+func (s *Stat_t) convertFrom(old *stat_freebsd11_t) {
+ *s = Stat_t{
+ Dev: uint64(old.Dev),
+ Ino: uint64(old.Ino),
+ Nlink: uint64(old.Nlink),
+ Mode: old.Mode,
+ Uid: old.Uid,
+ Gid: old.Gid,
+ Rdev: uint64(old.Rdev),
+ Atim: old.Atim,
+ Mtim: old.Mtim,
+ Ctim: old.Ctim,
+ Birthtim: old.Birthtim,
+ Size: old.Size,
+ Blocks: old.Blocks,
+ Blksize: old.Blksize,
+ Flags: old.Flags,
+ Gen: uint64(old.Gen),
+ }
+}
+
+func (s *Statfs_t) convertFrom(old *statfs_freebsd11_t) {
+ *s = Statfs_t{
+ Version: _statfsVersion,
+ Type: old.Type,
+ Flags: old.Flags,
+ Bsize: old.Bsize,
+ Iosize: old.Iosize,
+ Blocks: old.Blocks,
+ Bfree: old.Bfree,
+ Bavail: old.Bavail,
+ Files: old.Files,
+ Ffree: old.Ffree,
+ Syncwrites: old.Syncwrites,
+ Asyncwrites: old.Asyncwrites,
+ Syncreads: old.Syncreads,
+ Asyncreads: old.Asyncreads,
+ // Spare
+ Namemax: old.Namemax,
+ Owner: old.Owner,
+ Fsid: old.Fsid,
+ // Charspare
+ // Fstypename
+ // Mntfromname
+ // Mntonname
+ }
+
+ sl := old.Fstypename[:]
+ n := clen(*(*[]byte)(unsafe.Pointer(&sl)))
+ copy(s.Fstypename[:], old.Fstypename[:n])
+
+ sl = old.Mntfromname[:]
+ n = clen(*(*[]byte)(unsafe.Pointer(&sl)))
+ copy(s.Mntfromname[:], old.Mntfromname[:n])
+
+ sl = old.Mntonname[:]
+ n = clen(*(*[]byte)(unsafe.Pointer(&sl)))
+ copy(s.Mntonname[:], old.Mntonname[:n])
+}
+
+func convertFromDirents11(buf []byte, old []byte) int {
+ const (
+ fixedSize = int(unsafe.Offsetof(Dirent{}.Name))
+ oldFixedSize = int(unsafe.Offsetof(dirent_freebsd11{}.Name))
+ )
+
+ dstPos := 0
+ srcPos := 0
+ for dstPos+fixedSize < len(buf) && srcPos+oldFixedSize < len(old) {
+ dstDirent := (*Dirent)(unsafe.Pointer(&buf[dstPos]))
+ srcDirent := (*dirent_freebsd11)(unsafe.Pointer(&old[srcPos]))
+
+ reclen := roundup(fixedSize+int(srcDirent.Namlen)+1, 8)
+ if dstPos+reclen > len(buf) {
+ break
+ }
+
+ dstDirent.Fileno = uint64(srcDirent.Fileno)
+ dstDirent.Off = 0
+ dstDirent.Reclen = uint16(reclen)
+ dstDirent.Type = srcDirent.Type
+ dstDirent.Pad0 = 0
+ dstDirent.Namlen = uint16(srcDirent.Namlen)
+ dstDirent.Pad1 = 0
+
+ copy(dstDirent.Name[:], srcDirent.Name[:srcDirent.Namlen])
+ padding := buf[dstPos+fixedSize+int(dstDirent.Namlen) : dstPos+reclen]
+ for i := range padding {
+ padding[i] = 0
+ }
+
+ dstPos += int(dstDirent.Reclen)
+ srcPos += int(srcDirent.Reclen)
+ }
+
+ return dstPos
+}
+
/*
* Exposed directly
*/
@@ -264,13 +539,16 @@ func Uname(uname *Utsname) error {
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//sys Flock(fd int, how int) (err error)
//sys Fpathconf(fd int, name int) (val int, err error)
-//sys Fstat(fd int, stat *Stat_t) (err error)
-//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
-//sys Fstatfs(fd int, stat *Statfs_t) (err error)
+//sys fstat(fd int, stat *stat_freebsd11_t) (err error)
+//sys fstat_freebsd12(fd int, stat *Stat_t) (err error)
+//sys fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error)
+//sys fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error)
+//sys fstatfs(fd int, stat *statfs_freebsd11_t) (err error)
+//sys fstatfs_freebsd12(fd int, stat *Statfs_t) (err error)
//sys Fsync(fd int) (err error)
//sys Ftruncate(fd int, length int64) (err error)
-//sys Getdents(fd int, buf []byte) (n int, err error)
-//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error)
+//sys getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error)
+//sys getdirentries_freebsd12(fd int, buf []byte, basep *uintptr) (n int, err error)
//sys Getdtablesize() (size int)
//sysnb Getegid() (egid int)
//sysnb Geteuid() (uid int)
@@ -292,11 +570,13 @@ func Uname(uname *Utsname) error {
//sys Link(path string, link string) (err error)
//sys Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error)
//sys Listen(s int, backlog int) (err error)
-//sys Lstat(path string, stat *Stat_t) (err error)
+//sys lstat(path string, stat *stat_freebsd11_t) (err error)
//sys Mkdir(path string, mode uint32) (err error)
//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
//sys Mkfifo(path string, mode uint32) (err error)
-//sys Mknod(path string, mode uint32, dev int) (err error)
+//sys mknod(path string, mode uint32, dev int) (err error)
+//sys mknodat(fd int, path string, mode uint32, dev int) (err error)
+//sys mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error)
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys Open(path string, mode int, perm uint32) (fd int, err error)
//sys Openat(fdat int, path string, mode int, perm uint32) (fd int, err error)
@@ -326,8 +606,9 @@ func Uname(uname *Utsname) error {
//sysnb Setsid() (pid int, err error)
//sysnb Settimeofday(tp *Timeval) (err error)
//sysnb Setuid(uid int) (err error)
-//sys Stat(path string, stat *Stat_t) (err error)
-//sys Statfs(path string, stat *Statfs_t) (err error)
+//sys stat(path string, stat *stat_freebsd11_t) (err error)
+//sys statfs(path string, stat *statfs_freebsd11_t) (err error)
+//sys statfs_freebsd12(path string, stat *Statfs_t) (err error)
//sys Symlink(path string, link string) (err error)
//sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
//sys Sync() (err error)
@@ -382,6 +663,7 @@ func Uname(uname *Utsname) error {
// Kqueue_portset
// Getattrlist
// Setattrlist
+// Getdents
// Getdirentriesattr
// Searchfs
// Delete
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go
index bfa20a971..84aa8ea03 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux.go
@@ -1304,6 +1304,7 @@ func Mount(source string, target string, fstype string, flags uintptr, data stri
//sys ClockGettime(clockid int32, time *Timespec) (err error)
//sys Close(fd int) (err error)
//sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
+//sys DeleteModule(name string, flags int) (err error)
//sys Dup(oldfd int) (fd int, err error)
//sys Dup3(oldfd int, newfd int, flags int) (err error)
//sysnb EpollCreate1(flag int) (fd int, err error)
@@ -1317,6 +1318,7 @@ func Mount(source string, target string, fstype string, flags uintptr, data stri
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
//sys Fdatasync(fd int) (err error)
//sys Fgetxattr(fd int, attr string, dest []byte) (sz int, err error)
+//sys FinitModule(fd int, params string, flags int) (err error)
//sys Flistxattr(fd int, dest []byte) (sz int, err error)
//sys Flock(fd int, how int) (err error)
//sys Fremovexattr(fd int, attr string) (err error)
@@ -1338,6 +1340,7 @@ func Getpgrp() (pid int) {
//sysnb Getsid(pid int) (sid int, err error)
//sysnb Gettid() (tid int)
//sys Getxattr(path string, attr string, dest []byte) (sz int, err error)
+//sys InitModule(moduleImage []byte, params string) (err error)
//sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
//sysnb InotifyInit1(flags int) (fd int, err error)
//sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
@@ -1527,8 +1530,6 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
// ClockNanosleep
// ClockSettime
// Clone
-// CreateModule
-// DeleteModule
// EpollCtlOld
// EpollPwait
// EpollWaitOld
@@ -1572,7 +1573,6 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
// Pselect6
// Ptrace
// Putpmsg
-// QueryModule
// Quotactl
// Readahead
// Readv
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
index 646f295ad..fa5a9a6f6 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
@@ -191,12 +191,9 @@ func Dup2(oldfd int, newfd int) (err error) {
return Dup3(oldfd, newfd, 0)
}
-func Pause() (err error) {
- _, _, e1 := Syscall6(SYS_PPOLL, 0, 0, 0, 0, 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
+func Pause() error {
+ _, err := ppoll(nil, 0, nil, nil)
+ return err
}
func Poll(fds []PollFd, timeout int) (n int, err error) {
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
index 512077fe8..44aa1227a 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
@@ -191,12 +191,9 @@ func Dup2(oldfd int, newfd int) (err error) {
return Dup3(oldfd, newfd, 0)
}
-func Pause() (err error) {
- _, _, e1 := Syscall6(SYS_PPOLL, 0, 0, 0, 0, 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
+func Pause() error {
+ _, err := ppoll(nil, 0, nil, nil)
+ return err
}
func Poll(fds []PollFd, timeout int) (n int, err error) {
diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/vendor/golang.org/x/sys/unix/syscall_netbsd.go
index 206ce2af8..871fe65c3 100644
--- a/vendor/golang.org/x/sys/unix/syscall_netbsd.go
+++ b/vendor/golang.org/x/sys/unix/syscall_netbsd.go
@@ -300,6 +300,7 @@ func Uname(uname *Utsname) error {
//sys Mknod(path string, mode uint32, dev int) (err error)
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys Open(path string, mode int, perm uint32) (fd int, err error)
+//sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val int, err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error)
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd.go b/vendor/golang.org/x/sys/unix/syscall_openbsd.go
index 2c674a5c8..2b9f26a63 100644
--- a/vendor/golang.org/x/sys/unix/syscall_openbsd.go
+++ b/vendor/golang.org/x/sys/unix/syscall_openbsd.go
@@ -158,6 +158,15 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
return &value, err
}
+//sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
+
+func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
+ if len(fds) == 0 {
+ return ppoll(nil, 0, timeout, sigmask)
+ }
+ return ppoll(&fds[0], len(fds), timeout, sigmask)
+}
+
func Uname(uname *Utsname) error {
mib := []_C_int{CTL_KERN, KERN_OSTYPE}
n := unsafe.Sizeof(uname.Sysname)
@@ -257,6 +266,7 @@ func Uname(uname *Utsname) error {
//sys Mknod(path string, mode uint32, dev int) (err error)
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys Open(path string, mode int, perm uint32) (fd int, err error)
+//sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val int, err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error)
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
@@ -347,7 +357,6 @@ func Uname(uname *Utsname) error {
// msgsnd
// nfssvc
// nnpfspioctl
-// openat
// preadv
// profil
// pwritev
diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/syscall_openbsd_386.go
index 994964a91..d62da60d1 100644
--- a/vendor/golang.org/x/sys/unix/syscall_openbsd_386.go
+++ b/vendor/golang.org/x/sys/unix/syscall_openbsd_386.go
@@ -31,3 +31,7 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
+
+// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
+// of openbsd/386 the syscall is called sysctl instead of __sysctl.
+const SYS___SYSCTL = SYS_SYSCTL
diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go
index 59844f504..5d812aaea 100644
--- a/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go
@@ -31,3 +31,7 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
+
+// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
+// of openbsd/arm the syscall is called sysctl instead of __sysctl.
+const SYS___SYSCTL = SYS_SYSCTL
diff --git a/vendor/golang.org/x/sys/unix/types_freebsd.go b/vendor/golang.org/x/sys/unix/types_freebsd.go
index a0a5843b9..8421ccf1c 100644
--- a/vendor/golang.org/x/sys/unix/types_freebsd.go
+++ b/vendor/golang.org/x/sys/unix/types_freebsd.go
@@ -14,7 +14,11 @@ Input to cgo -godefs. See README.md
package unix
/*
-#define KERNEL
+#define _WANT_FREEBSD11_STAT 1
+#define _WANT_FREEBSD11_STATFS 1
+#define _WANT_FREEBSD11_DIRENT 1
+#define _WANT_FREEBSD11_KEVENT 1
+
#include
#include
#include
@@ -63,50 +67,6 @@ struct sockaddr_any {
char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
};
-// This structure is a duplicate of stat on FreeBSD 8-STABLE.
-// See /usr/include/sys/stat.h.
-struct stat8 {
-#undef st_atimespec st_atim
-#undef st_mtimespec st_mtim
-#undef st_ctimespec st_ctim
-#undef st_birthtimespec st_birthtim
- __dev_t st_dev;
- ino_t st_ino;
- mode_t st_mode;
- nlink_t st_nlink;
- uid_t st_uid;
- gid_t st_gid;
- __dev_t st_rdev;
-#if __BSD_VISIBLE
- struct timespec st_atimespec;
- struct timespec st_mtimespec;
- struct timespec st_ctimespec;
-#else
- time_t st_atime;
- long __st_atimensec;
- time_t st_mtime;
- long __st_mtimensec;
- time_t st_ctime;
- long __st_ctimensec;
-#endif
- off_t st_size;
- blkcnt_t st_blocks;
- blksize_t st_blksize;
- fflags_t st_flags;
- __uint32_t st_gen;
- __int32_t st_lspare;
-#if __BSD_VISIBLE
- struct timespec st_birthtimespec;
- unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec));
- unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec));
-#else
- time_t st_birthtime;
- long st_birthtimensec;
- unsigned int :(8 / 2) * (16 - (int)sizeof(struct __timespec));
- unsigned int :(8 / 2) * (16 - (int)sizeof(struct __timespec));
-#endif
-};
-
// This structure is a duplicate of if_data on FreeBSD 8-STABLE.
// See /usr/include/net/if.h.
struct if_data8 {
@@ -189,14 +149,25 @@ type _Gid_t C.gid_t
// Files
-type Stat_t C.struct_stat8
+const (
+ _statfsVersion = C.STATFS_VERSION
+ _dirblksiz = C.DIRBLKSIZ
+)
+
+type Stat_t C.struct_stat
+
+type stat_freebsd11_t C.struct_freebsd11_stat
type Statfs_t C.struct_statfs
+type statfs_freebsd11_t C.struct_freebsd11_statfs
+
type Flock_t C.struct_flock
type Dirent C.struct_dirent
+type dirent_freebsd11 C.struct_freebsd11_dirent
+
type Fsid C.struct_fsid
// File system limits
@@ -279,7 +250,7 @@ const (
// Events (kqueue, kevent)
-type Kevent_t C.struct_kevent
+type Kevent_t C.struct_kevent_freebsd11
// Select
diff --git a/vendor/golang.org/x/sys/unix/types_openbsd.go b/vendor/golang.org/x/sys/unix/types_openbsd.go
index 297e40d37..4e5e57f9a 100644
--- a/vendor/golang.org/x/sys/unix/types_openbsd.go
+++ b/vendor/golang.org/x/sys/unix/types_openbsd.go
@@ -261,6 +261,10 @@ const (
POLLWRNORM = C.POLLWRNORM
)
+// Signal Sets
+
+type Sigset_t C.sigset_t
+
// Uname
type Utsname C.struct_utsname
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
index 86b980a5a..673152b94 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
@@ -1008,7 +1008,9 @@ const (
MFD_HUGE_256MB = 0x70000000
MFD_HUGE_2GB = 0x7c000000
MFD_HUGE_2MB = 0x54000000
+ MFD_HUGE_32MB = 0x64000000
MFD_HUGE_512KB = 0x4c000000
+ MFD_HUGE_512MB = 0x74000000
MFD_HUGE_64KB = 0x40000000
MFD_HUGE_8MB = 0x5c000000
MFD_HUGE_MASK = 0x3f
@@ -1021,6 +1023,8 @@ const (
MNT_DETACH = 0x2
MNT_EXPIRE = 0x4
MNT_FORCE = 0x1
+ MODULE_INIT_IGNORE_MODVERSIONS = 0x1
+ MODULE_INIT_IGNORE_VERMAGIC = 0x2
MSDOS_SUPER_MAGIC = 0x4d44
MSG_BATCH = 0x40000
MSG_CMSG_CLOEXEC = 0x40000000
@@ -1584,6 +1588,7 @@ const (
RTM_DELACTION = 0x31
RTM_DELADDR = 0x15
RTM_DELADDRLABEL = 0x49
+ RTM_DELCHAIN = 0x65
RTM_DELLINK = 0x11
RTM_DELMDB = 0x55
RTM_DELNEIGH = 0x1d
@@ -1604,6 +1609,7 @@ const (
RTM_GETADDR = 0x16
RTM_GETADDRLABEL = 0x4a
RTM_GETANYCAST = 0x3e
+ RTM_GETCHAIN = 0x66
RTM_GETDCB = 0x4e
RTM_GETLINK = 0x12
RTM_GETMDB = 0x56
@@ -1618,11 +1624,12 @@ const (
RTM_GETSTATS = 0x5e
RTM_GETTCLASS = 0x2a
RTM_GETTFILTER = 0x2e
- RTM_MAX = 0x63
+ RTM_MAX = 0x67
RTM_NEWACTION = 0x30
RTM_NEWADDR = 0x14
RTM_NEWADDRLABEL = 0x48
RTM_NEWCACHEREPORT = 0x60
+ RTM_NEWCHAIN = 0x64
RTM_NEWLINK = 0x10
RTM_NEWMDB = 0x54
RTM_NEWNDUSEROPT = 0x44
@@ -1637,8 +1644,8 @@ const (
RTM_NEWSTATS = 0x5c
RTM_NEWTCLASS = 0x28
RTM_NEWTFILTER = 0x2c
- RTM_NR_FAMILIES = 0x15
- RTM_NR_MSGTYPES = 0x54
+ RTM_NR_FAMILIES = 0x16
+ RTM_NR_MSGTYPES = 0x58
RTM_SETDCB = 0x4f
RTM_SETLINK = 0x13
RTM_SETNEIGHTBL = 0x43
@@ -1687,6 +1694,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
+ SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_MODE_DISABLED = 0x0
SECCOMP_MODE_FILTER = 0x2
@@ -1891,6 +1899,7 @@ const (
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPNS = 0x23
+ SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
SO_VM_SOCKETS_BUFFER_MIN_SIZE = 0x1
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
index 286311572..5735bcf3c 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
@@ -1008,7 +1008,9 @@ const (
MFD_HUGE_256MB = 0x70000000
MFD_HUGE_2GB = 0x7c000000
MFD_HUGE_2MB = 0x54000000
+ MFD_HUGE_32MB = 0x64000000
MFD_HUGE_512KB = 0x4c000000
+ MFD_HUGE_512MB = 0x74000000
MFD_HUGE_64KB = 0x40000000
MFD_HUGE_8MB = 0x5c000000
MFD_HUGE_MASK = 0x3f
@@ -1021,6 +1023,8 @@ const (
MNT_DETACH = 0x2
MNT_EXPIRE = 0x4
MNT_FORCE = 0x1
+ MODULE_INIT_IGNORE_MODVERSIONS = 0x1
+ MODULE_INIT_IGNORE_VERMAGIC = 0x2
MSDOS_SUPER_MAGIC = 0x4d44
MSG_BATCH = 0x40000
MSG_CMSG_CLOEXEC = 0x40000000
@@ -1585,6 +1589,7 @@ const (
RTM_DELACTION = 0x31
RTM_DELADDR = 0x15
RTM_DELADDRLABEL = 0x49
+ RTM_DELCHAIN = 0x65
RTM_DELLINK = 0x11
RTM_DELMDB = 0x55
RTM_DELNEIGH = 0x1d
@@ -1605,6 +1610,7 @@ const (
RTM_GETADDR = 0x16
RTM_GETADDRLABEL = 0x4a
RTM_GETANYCAST = 0x3e
+ RTM_GETCHAIN = 0x66
RTM_GETDCB = 0x4e
RTM_GETLINK = 0x12
RTM_GETMDB = 0x56
@@ -1619,11 +1625,12 @@ const (
RTM_GETSTATS = 0x5e
RTM_GETTCLASS = 0x2a
RTM_GETTFILTER = 0x2e
- RTM_MAX = 0x63
+ RTM_MAX = 0x67
RTM_NEWACTION = 0x30
RTM_NEWADDR = 0x14
RTM_NEWADDRLABEL = 0x48
RTM_NEWCACHEREPORT = 0x60
+ RTM_NEWCHAIN = 0x64
RTM_NEWLINK = 0x10
RTM_NEWMDB = 0x54
RTM_NEWNDUSEROPT = 0x44
@@ -1638,8 +1645,8 @@ const (
RTM_NEWSTATS = 0x5c
RTM_NEWTCLASS = 0x28
RTM_NEWTFILTER = 0x2c
- RTM_NR_FAMILIES = 0x15
- RTM_NR_MSGTYPES = 0x54
+ RTM_NR_FAMILIES = 0x16
+ RTM_NR_MSGTYPES = 0x58
RTM_SETDCB = 0x4f
RTM_SETLINK = 0x13
RTM_SETNEIGHTBL = 0x43
@@ -1688,6 +1695,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
+ SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_MODE_DISABLED = 0x0
SECCOMP_MODE_FILTER = 0x2
@@ -1892,6 +1900,7 @@ const (
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPNS = 0x23
+ SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
SO_VM_SOCKETS_BUFFER_MIN_SIZE = 0x1
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
index 1b58da1e7..d8e8442e5 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
@@ -1006,7 +1006,9 @@ const (
MFD_HUGE_256MB = 0x70000000
MFD_HUGE_2GB = 0x7c000000
MFD_HUGE_2MB = 0x54000000
+ MFD_HUGE_32MB = 0x64000000
MFD_HUGE_512KB = 0x4c000000
+ MFD_HUGE_512MB = 0x74000000
MFD_HUGE_64KB = 0x40000000
MFD_HUGE_8MB = 0x5c000000
MFD_HUGE_MASK = 0x3f
@@ -1019,6 +1021,8 @@ const (
MNT_DETACH = 0x2
MNT_EXPIRE = 0x4
MNT_FORCE = 0x1
+ MODULE_INIT_IGNORE_MODVERSIONS = 0x1
+ MODULE_INIT_IGNORE_VERMAGIC = 0x2
MSDOS_SUPER_MAGIC = 0x4d44
MSG_BATCH = 0x40000
MSG_CMSG_CLOEXEC = 0x40000000
@@ -1591,6 +1595,7 @@ const (
RTM_DELACTION = 0x31
RTM_DELADDR = 0x15
RTM_DELADDRLABEL = 0x49
+ RTM_DELCHAIN = 0x65
RTM_DELLINK = 0x11
RTM_DELMDB = 0x55
RTM_DELNEIGH = 0x1d
@@ -1611,6 +1616,7 @@ const (
RTM_GETADDR = 0x16
RTM_GETADDRLABEL = 0x4a
RTM_GETANYCAST = 0x3e
+ RTM_GETCHAIN = 0x66
RTM_GETDCB = 0x4e
RTM_GETLINK = 0x12
RTM_GETMDB = 0x56
@@ -1625,11 +1631,12 @@ const (
RTM_GETSTATS = 0x5e
RTM_GETTCLASS = 0x2a
RTM_GETTFILTER = 0x2e
- RTM_MAX = 0x63
+ RTM_MAX = 0x67
RTM_NEWACTION = 0x30
RTM_NEWADDR = 0x14
RTM_NEWADDRLABEL = 0x48
RTM_NEWCACHEREPORT = 0x60
+ RTM_NEWCHAIN = 0x64
RTM_NEWLINK = 0x10
RTM_NEWMDB = 0x54
RTM_NEWNDUSEROPT = 0x44
@@ -1644,8 +1651,8 @@ const (
RTM_NEWSTATS = 0x5c
RTM_NEWTCLASS = 0x28
RTM_NEWTFILTER = 0x2c
- RTM_NR_FAMILIES = 0x15
- RTM_NR_MSGTYPES = 0x54
+ RTM_NR_FAMILIES = 0x16
+ RTM_NR_MSGTYPES = 0x58
RTM_SETDCB = 0x4f
RTM_SETLINK = 0x13
RTM_SETNEIGHTBL = 0x43
@@ -1694,6 +1701,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
+ SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_MODE_DISABLED = 0x0
SECCOMP_MODE_FILTER = 0x2
@@ -1898,6 +1906,7 @@ const (
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPNS = 0x23
+ SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
SO_VM_SOCKETS_BUFFER_MIN_SIZE = 0x1
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
index 08377eb4f..5d79b789b 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
@@ -1009,7 +1009,9 @@ const (
MFD_HUGE_256MB = 0x70000000
MFD_HUGE_2GB = 0x7c000000
MFD_HUGE_2MB = 0x54000000
+ MFD_HUGE_32MB = 0x64000000
MFD_HUGE_512KB = 0x4c000000
+ MFD_HUGE_512MB = 0x74000000
MFD_HUGE_64KB = 0x40000000
MFD_HUGE_8MB = 0x5c000000
MFD_HUGE_MASK = 0x3f
@@ -1022,6 +1024,8 @@ const (
MNT_DETACH = 0x2
MNT_EXPIRE = 0x4
MNT_FORCE = 0x1
+ MODULE_INIT_IGNORE_MODVERSIONS = 0x1
+ MODULE_INIT_IGNORE_VERMAGIC = 0x2
MSDOS_SUPER_MAGIC = 0x4d44
MSG_BATCH = 0x40000
MSG_CMSG_CLOEXEC = 0x40000000
@@ -1575,6 +1579,7 @@ const (
RTM_DELACTION = 0x31
RTM_DELADDR = 0x15
RTM_DELADDRLABEL = 0x49
+ RTM_DELCHAIN = 0x65
RTM_DELLINK = 0x11
RTM_DELMDB = 0x55
RTM_DELNEIGH = 0x1d
@@ -1595,6 +1600,7 @@ const (
RTM_GETADDR = 0x16
RTM_GETADDRLABEL = 0x4a
RTM_GETANYCAST = 0x3e
+ RTM_GETCHAIN = 0x66
RTM_GETDCB = 0x4e
RTM_GETLINK = 0x12
RTM_GETMDB = 0x56
@@ -1609,11 +1615,12 @@ const (
RTM_GETSTATS = 0x5e
RTM_GETTCLASS = 0x2a
RTM_GETTFILTER = 0x2e
- RTM_MAX = 0x63
+ RTM_MAX = 0x67
RTM_NEWACTION = 0x30
RTM_NEWADDR = 0x14
RTM_NEWADDRLABEL = 0x48
RTM_NEWCACHEREPORT = 0x60
+ RTM_NEWCHAIN = 0x64
RTM_NEWLINK = 0x10
RTM_NEWMDB = 0x54
RTM_NEWNDUSEROPT = 0x44
@@ -1628,8 +1635,8 @@ const (
RTM_NEWSTATS = 0x5c
RTM_NEWTCLASS = 0x28
RTM_NEWTFILTER = 0x2c
- RTM_NR_FAMILIES = 0x15
- RTM_NR_MSGTYPES = 0x54
+ RTM_NR_FAMILIES = 0x16
+ RTM_NR_MSGTYPES = 0x58
RTM_SETDCB = 0x4f
RTM_SETLINK = 0x13
RTM_SETNEIGHTBL = 0x43
@@ -1678,6 +1685,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
+ SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_MODE_DISABLED = 0x0
SECCOMP_MODE_FILTER = 0x2
@@ -1882,6 +1890,7 @@ const (
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPNS = 0x23
+ SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
SO_VM_SOCKETS_BUFFER_MIN_SIZE = 0x1
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
index 5de2c7aa4..3c91615c8 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
@@ -1006,7 +1006,9 @@ const (
MFD_HUGE_256MB = 0x70000000
MFD_HUGE_2GB = 0x7c000000
MFD_HUGE_2MB = 0x54000000
+ MFD_HUGE_32MB = 0x64000000
MFD_HUGE_512KB = 0x4c000000
+ MFD_HUGE_512MB = 0x74000000
MFD_HUGE_64KB = 0x40000000
MFD_HUGE_8MB = 0x5c000000
MFD_HUGE_MASK = 0x3f
@@ -1019,6 +1021,8 @@ const (
MNT_DETACH = 0x2
MNT_EXPIRE = 0x4
MNT_FORCE = 0x1
+ MODULE_INIT_IGNORE_MODVERSIONS = 0x1
+ MODULE_INIT_IGNORE_VERMAGIC = 0x2
MSDOS_SUPER_MAGIC = 0x4d44
MSG_BATCH = 0x40000
MSG_CMSG_CLOEXEC = 0x40000000
@@ -1584,6 +1588,7 @@ const (
RTM_DELACTION = 0x31
RTM_DELADDR = 0x15
RTM_DELADDRLABEL = 0x49
+ RTM_DELCHAIN = 0x65
RTM_DELLINK = 0x11
RTM_DELMDB = 0x55
RTM_DELNEIGH = 0x1d
@@ -1604,6 +1609,7 @@ const (
RTM_GETADDR = 0x16
RTM_GETADDRLABEL = 0x4a
RTM_GETANYCAST = 0x3e
+ RTM_GETCHAIN = 0x66
RTM_GETDCB = 0x4e
RTM_GETLINK = 0x12
RTM_GETMDB = 0x56
@@ -1618,11 +1624,12 @@ const (
RTM_GETSTATS = 0x5e
RTM_GETTCLASS = 0x2a
RTM_GETTFILTER = 0x2e
- RTM_MAX = 0x63
+ RTM_MAX = 0x67
RTM_NEWACTION = 0x30
RTM_NEWADDR = 0x14
RTM_NEWADDRLABEL = 0x48
RTM_NEWCACHEREPORT = 0x60
+ RTM_NEWCHAIN = 0x64
RTM_NEWLINK = 0x10
RTM_NEWMDB = 0x54
RTM_NEWNDUSEROPT = 0x44
@@ -1637,8 +1644,8 @@ const (
RTM_NEWSTATS = 0x5c
RTM_NEWTCLASS = 0x28
RTM_NEWTFILTER = 0x2c
- RTM_NR_FAMILIES = 0x15
- RTM_NR_MSGTYPES = 0x54
+ RTM_NR_FAMILIES = 0x16
+ RTM_NR_MSGTYPES = 0x58
RTM_SETDCB = 0x4f
RTM_SETLINK = 0x13
RTM_SETNEIGHTBL = 0x43
@@ -1687,6 +1694,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
+ SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_MODE_DISABLED = 0x0
SECCOMP_MODE_FILTER = 0x2
@@ -1892,6 +1900,7 @@ const (
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPNS = 0x23
+ SO_TXTIME = 0x3d
SO_TYPE = 0x1008
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
SO_VM_SOCKETS_BUFFER_MIN_SIZE = 0x1
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
index 51015f354..e1f86c1cd 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
@@ -1006,7 +1006,9 @@ const (
MFD_HUGE_256MB = 0x70000000
MFD_HUGE_2GB = 0x7c000000
MFD_HUGE_2MB = 0x54000000
+ MFD_HUGE_32MB = 0x64000000
MFD_HUGE_512KB = 0x4c000000
+ MFD_HUGE_512MB = 0x74000000
MFD_HUGE_64KB = 0x40000000
MFD_HUGE_8MB = 0x5c000000
MFD_HUGE_MASK = 0x3f
@@ -1019,6 +1021,8 @@ const (
MNT_DETACH = 0x2
MNT_EXPIRE = 0x4
MNT_FORCE = 0x1
+ MODULE_INIT_IGNORE_MODVERSIONS = 0x1
+ MODULE_INIT_IGNORE_VERMAGIC = 0x2
MSDOS_SUPER_MAGIC = 0x4d44
MSG_BATCH = 0x40000
MSG_CMSG_CLOEXEC = 0x40000000
@@ -1584,6 +1588,7 @@ const (
RTM_DELACTION = 0x31
RTM_DELADDR = 0x15
RTM_DELADDRLABEL = 0x49
+ RTM_DELCHAIN = 0x65
RTM_DELLINK = 0x11
RTM_DELMDB = 0x55
RTM_DELNEIGH = 0x1d
@@ -1604,6 +1609,7 @@ const (
RTM_GETADDR = 0x16
RTM_GETADDRLABEL = 0x4a
RTM_GETANYCAST = 0x3e
+ RTM_GETCHAIN = 0x66
RTM_GETDCB = 0x4e
RTM_GETLINK = 0x12
RTM_GETMDB = 0x56
@@ -1618,11 +1624,12 @@ const (
RTM_GETSTATS = 0x5e
RTM_GETTCLASS = 0x2a
RTM_GETTFILTER = 0x2e
- RTM_MAX = 0x63
+ RTM_MAX = 0x67
RTM_NEWACTION = 0x30
RTM_NEWADDR = 0x14
RTM_NEWADDRLABEL = 0x48
RTM_NEWCACHEREPORT = 0x60
+ RTM_NEWCHAIN = 0x64
RTM_NEWLINK = 0x10
RTM_NEWMDB = 0x54
RTM_NEWNDUSEROPT = 0x44
@@ -1637,8 +1644,8 @@ const (
RTM_NEWSTATS = 0x5c
RTM_NEWTCLASS = 0x28
RTM_NEWTFILTER = 0x2c
- RTM_NR_FAMILIES = 0x15
- RTM_NR_MSGTYPES = 0x54
+ RTM_NR_FAMILIES = 0x16
+ RTM_NR_MSGTYPES = 0x58
RTM_SETDCB = 0x4f
RTM_SETLINK = 0x13
RTM_SETNEIGHTBL = 0x43
@@ -1687,6 +1694,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
+ SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_MODE_DISABLED = 0x0
SECCOMP_MODE_FILTER = 0x2
@@ -1892,6 +1900,7 @@ const (
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPNS = 0x23
+ SO_TXTIME = 0x3d
SO_TYPE = 0x1008
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
SO_VM_SOCKETS_BUFFER_MIN_SIZE = 0x1
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
index fdd388deb..d09e3b68b 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
@@ -1006,7 +1006,9 @@ const (
MFD_HUGE_256MB = 0x70000000
MFD_HUGE_2GB = 0x7c000000
MFD_HUGE_2MB = 0x54000000
+ MFD_HUGE_32MB = 0x64000000
MFD_HUGE_512KB = 0x4c000000
+ MFD_HUGE_512MB = 0x74000000
MFD_HUGE_64KB = 0x40000000
MFD_HUGE_8MB = 0x5c000000
MFD_HUGE_MASK = 0x3f
@@ -1019,6 +1021,8 @@ const (
MNT_DETACH = 0x2
MNT_EXPIRE = 0x4
MNT_FORCE = 0x1
+ MODULE_INIT_IGNORE_MODVERSIONS = 0x1
+ MODULE_INIT_IGNORE_VERMAGIC = 0x2
MSDOS_SUPER_MAGIC = 0x4d44
MSG_BATCH = 0x40000
MSG_CMSG_CLOEXEC = 0x40000000
@@ -1584,6 +1588,7 @@ const (
RTM_DELACTION = 0x31
RTM_DELADDR = 0x15
RTM_DELADDRLABEL = 0x49
+ RTM_DELCHAIN = 0x65
RTM_DELLINK = 0x11
RTM_DELMDB = 0x55
RTM_DELNEIGH = 0x1d
@@ -1604,6 +1609,7 @@ const (
RTM_GETADDR = 0x16
RTM_GETADDRLABEL = 0x4a
RTM_GETANYCAST = 0x3e
+ RTM_GETCHAIN = 0x66
RTM_GETDCB = 0x4e
RTM_GETLINK = 0x12
RTM_GETMDB = 0x56
@@ -1618,11 +1624,12 @@ const (
RTM_GETSTATS = 0x5e
RTM_GETTCLASS = 0x2a
RTM_GETTFILTER = 0x2e
- RTM_MAX = 0x63
+ RTM_MAX = 0x67
RTM_NEWACTION = 0x30
RTM_NEWADDR = 0x14
RTM_NEWADDRLABEL = 0x48
RTM_NEWCACHEREPORT = 0x60
+ RTM_NEWCHAIN = 0x64
RTM_NEWLINK = 0x10
RTM_NEWMDB = 0x54
RTM_NEWNDUSEROPT = 0x44
@@ -1637,8 +1644,8 @@ const (
RTM_NEWSTATS = 0x5c
RTM_NEWTCLASS = 0x28
RTM_NEWTFILTER = 0x2c
- RTM_NR_FAMILIES = 0x15
- RTM_NR_MSGTYPES = 0x54
+ RTM_NR_FAMILIES = 0x16
+ RTM_NR_MSGTYPES = 0x58
RTM_SETDCB = 0x4f
RTM_SETLINK = 0x13
RTM_SETNEIGHTBL = 0x43
@@ -1687,6 +1694,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
+ SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_MODE_DISABLED = 0x0
SECCOMP_MODE_FILTER = 0x2
@@ -1892,6 +1900,7 @@ const (
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPNS = 0x23
+ SO_TXTIME = 0x3d
SO_TYPE = 0x1008
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
SO_VM_SOCKETS_BUFFER_MIN_SIZE = 0x1
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
index 2d1504612..f78108dfb 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
@@ -1006,7 +1006,9 @@ const (
MFD_HUGE_256MB = 0x70000000
MFD_HUGE_2GB = 0x7c000000
MFD_HUGE_2MB = 0x54000000
+ MFD_HUGE_32MB = 0x64000000
MFD_HUGE_512KB = 0x4c000000
+ MFD_HUGE_512MB = 0x74000000
MFD_HUGE_64KB = 0x40000000
MFD_HUGE_8MB = 0x5c000000
MFD_HUGE_MASK = 0x3f
@@ -1019,6 +1021,8 @@ const (
MNT_DETACH = 0x2
MNT_EXPIRE = 0x4
MNT_FORCE = 0x1
+ MODULE_INIT_IGNORE_MODVERSIONS = 0x1
+ MODULE_INIT_IGNORE_VERMAGIC = 0x2
MSDOS_SUPER_MAGIC = 0x4d44
MSG_BATCH = 0x40000
MSG_CMSG_CLOEXEC = 0x40000000
@@ -1584,6 +1588,7 @@ const (
RTM_DELACTION = 0x31
RTM_DELADDR = 0x15
RTM_DELADDRLABEL = 0x49
+ RTM_DELCHAIN = 0x65
RTM_DELLINK = 0x11
RTM_DELMDB = 0x55
RTM_DELNEIGH = 0x1d
@@ -1604,6 +1609,7 @@ const (
RTM_GETADDR = 0x16
RTM_GETADDRLABEL = 0x4a
RTM_GETANYCAST = 0x3e
+ RTM_GETCHAIN = 0x66
RTM_GETDCB = 0x4e
RTM_GETLINK = 0x12
RTM_GETMDB = 0x56
@@ -1618,11 +1624,12 @@ const (
RTM_GETSTATS = 0x5e
RTM_GETTCLASS = 0x2a
RTM_GETTFILTER = 0x2e
- RTM_MAX = 0x63
+ RTM_MAX = 0x67
RTM_NEWACTION = 0x30
RTM_NEWADDR = 0x14
RTM_NEWADDRLABEL = 0x48
RTM_NEWCACHEREPORT = 0x60
+ RTM_NEWCHAIN = 0x64
RTM_NEWLINK = 0x10
RTM_NEWMDB = 0x54
RTM_NEWNDUSEROPT = 0x44
@@ -1637,8 +1644,8 @@ const (
RTM_NEWSTATS = 0x5c
RTM_NEWTCLASS = 0x28
RTM_NEWTFILTER = 0x2c
- RTM_NR_FAMILIES = 0x15
- RTM_NR_MSGTYPES = 0x54
+ RTM_NR_FAMILIES = 0x16
+ RTM_NR_MSGTYPES = 0x58
RTM_SETDCB = 0x4f
RTM_SETLINK = 0x13
RTM_SETNEIGHTBL = 0x43
@@ -1687,6 +1694,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
+ SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_MODE_DISABLED = 0x0
SECCOMP_MODE_FILTER = 0x2
@@ -1892,6 +1900,7 @@ const (
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPNS = 0x23
+ SO_TXTIME = 0x3d
SO_TYPE = 0x1008
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
SO_VM_SOCKETS_BUFFER_MIN_SIZE = 0x1
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
index cd8fcd35c..8da57a99c 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
@@ -1005,7 +1005,9 @@ const (
MFD_HUGE_256MB = 0x70000000
MFD_HUGE_2GB = 0x7c000000
MFD_HUGE_2MB = 0x54000000
+ MFD_HUGE_32MB = 0x64000000
MFD_HUGE_512KB = 0x4c000000
+ MFD_HUGE_512MB = 0x74000000
MFD_HUGE_64KB = 0x40000000
MFD_HUGE_8MB = 0x5c000000
MFD_HUGE_MASK = 0x3f
@@ -1018,6 +1020,8 @@ const (
MNT_DETACH = 0x2
MNT_EXPIRE = 0x4
MNT_FORCE = 0x1
+ MODULE_INIT_IGNORE_MODVERSIONS = 0x1
+ MODULE_INIT_IGNORE_VERMAGIC = 0x2
MSDOS_SUPER_MAGIC = 0x4d44
MSG_BATCH = 0x40000
MSG_CMSG_CLOEXEC = 0x40000000
@@ -1640,6 +1644,7 @@ const (
RTM_DELACTION = 0x31
RTM_DELADDR = 0x15
RTM_DELADDRLABEL = 0x49
+ RTM_DELCHAIN = 0x65
RTM_DELLINK = 0x11
RTM_DELMDB = 0x55
RTM_DELNEIGH = 0x1d
@@ -1660,6 +1665,7 @@ const (
RTM_GETADDR = 0x16
RTM_GETADDRLABEL = 0x4a
RTM_GETANYCAST = 0x3e
+ RTM_GETCHAIN = 0x66
RTM_GETDCB = 0x4e
RTM_GETLINK = 0x12
RTM_GETMDB = 0x56
@@ -1674,11 +1680,12 @@ const (
RTM_GETSTATS = 0x5e
RTM_GETTCLASS = 0x2a
RTM_GETTFILTER = 0x2e
- RTM_MAX = 0x63
+ RTM_MAX = 0x67
RTM_NEWACTION = 0x30
RTM_NEWADDR = 0x14
RTM_NEWADDRLABEL = 0x48
RTM_NEWCACHEREPORT = 0x60
+ RTM_NEWCHAIN = 0x64
RTM_NEWLINK = 0x10
RTM_NEWMDB = 0x54
RTM_NEWNDUSEROPT = 0x44
@@ -1693,8 +1700,8 @@ const (
RTM_NEWSTATS = 0x5c
RTM_NEWTCLASS = 0x28
RTM_NEWTFILTER = 0x2c
- RTM_NR_FAMILIES = 0x15
- RTM_NR_MSGTYPES = 0x54
+ RTM_NR_FAMILIES = 0x16
+ RTM_NR_MSGTYPES = 0x58
RTM_SETDCB = 0x4f
RTM_SETLINK = 0x13
RTM_SETNEIGHTBL = 0x43
@@ -1743,6 +1750,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
+ SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_MODE_DISABLED = 0x0
SECCOMP_MODE_FILTER = 0x2
@@ -1947,6 +1955,7 @@ const (
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPNS = 0x23
+ SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
SO_VM_SOCKETS_BUFFER_MIN_SIZE = 0x1
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
index cdb608876..1832c0a7c 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
@@ -1005,7 +1005,9 @@ const (
MFD_HUGE_256MB = 0x70000000
MFD_HUGE_2GB = 0x7c000000
MFD_HUGE_2MB = 0x54000000
+ MFD_HUGE_32MB = 0x64000000
MFD_HUGE_512KB = 0x4c000000
+ MFD_HUGE_512MB = 0x74000000
MFD_HUGE_64KB = 0x40000000
MFD_HUGE_8MB = 0x5c000000
MFD_HUGE_MASK = 0x3f
@@ -1018,6 +1020,8 @@ const (
MNT_DETACH = 0x2
MNT_EXPIRE = 0x4
MNT_FORCE = 0x1
+ MODULE_INIT_IGNORE_MODVERSIONS = 0x1
+ MODULE_INIT_IGNORE_VERMAGIC = 0x2
MSDOS_SUPER_MAGIC = 0x4d44
MSG_BATCH = 0x40000
MSG_CMSG_CLOEXEC = 0x40000000
@@ -1640,6 +1644,7 @@ const (
RTM_DELACTION = 0x31
RTM_DELADDR = 0x15
RTM_DELADDRLABEL = 0x49
+ RTM_DELCHAIN = 0x65
RTM_DELLINK = 0x11
RTM_DELMDB = 0x55
RTM_DELNEIGH = 0x1d
@@ -1660,6 +1665,7 @@ const (
RTM_GETADDR = 0x16
RTM_GETADDRLABEL = 0x4a
RTM_GETANYCAST = 0x3e
+ RTM_GETCHAIN = 0x66
RTM_GETDCB = 0x4e
RTM_GETLINK = 0x12
RTM_GETMDB = 0x56
@@ -1674,11 +1680,12 @@ const (
RTM_GETSTATS = 0x5e
RTM_GETTCLASS = 0x2a
RTM_GETTFILTER = 0x2e
- RTM_MAX = 0x63
+ RTM_MAX = 0x67
RTM_NEWACTION = 0x30
RTM_NEWADDR = 0x14
RTM_NEWADDRLABEL = 0x48
RTM_NEWCACHEREPORT = 0x60
+ RTM_NEWCHAIN = 0x64
RTM_NEWLINK = 0x10
RTM_NEWMDB = 0x54
RTM_NEWNDUSEROPT = 0x44
@@ -1693,8 +1700,8 @@ const (
RTM_NEWSTATS = 0x5c
RTM_NEWTCLASS = 0x28
RTM_NEWTFILTER = 0x2c
- RTM_NR_FAMILIES = 0x15
- RTM_NR_MSGTYPES = 0x54
+ RTM_NR_FAMILIES = 0x16
+ RTM_NR_MSGTYPES = 0x58
RTM_SETDCB = 0x4f
RTM_SETLINK = 0x13
RTM_SETNEIGHTBL = 0x43
@@ -1743,6 +1750,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
+ SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_MODE_DISABLED = 0x0
SECCOMP_MODE_FILTER = 0x2
@@ -1947,6 +1955,7 @@ const (
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPNS = 0x23
+ SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
SO_VM_SOCKETS_BUFFER_MIN_SIZE = 0x1
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
index 9e9472bec..c6bd4efff 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
@@ -1006,7 +1006,9 @@ const (
MFD_HUGE_256MB = 0x70000000
MFD_HUGE_2GB = 0x7c000000
MFD_HUGE_2MB = 0x54000000
+ MFD_HUGE_32MB = 0x64000000
MFD_HUGE_512KB = 0x4c000000
+ MFD_HUGE_512MB = 0x74000000
MFD_HUGE_64KB = 0x40000000
MFD_HUGE_8MB = 0x5c000000
MFD_HUGE_MASK = 0x3f
@@ -1019,6 +1021,8 @@ const (
MNT_DETACH = 0x2
MNT_EXPIRE = 0x4
MNT_FORCE = 0x1
+ MODULE_INIT_IGNORE_MODVERSIONS = 0x1
+ MODULE_INIT_IGNORE_VERMAGIC = 0x2
MSDOS_SUPER_MAGIC = 0x4d44
MSG_BATCH = 0x40000
MSG_CMSG_CLOEXEC = 0x40000000
@@ -1572,6 +1576,7 @@ const (
RTM_DELACTION = 0x31
RTM_DELADDR = 0x15
RTM_DELADDRLABEL = 0x49
+ RTM_DELCHAIN = 0x65
RTM_DELLINK = 0x11
RTM_DELMDB = 0x55
RTM_DELNEIGH = 0x1d
@@ -1592,6 +1597,7 @@ const (
RTM_GETADDR = 0x16
RTM_GETADDRLABEL = 0x4a
RTM_GETANYCAST = 0x3e
+ RTM_GETCHAIN = 0x66
RTM_GETDCB = 0x4e
RTM_GETLINK = 0x12
RTM_GETMDB = 0x56
@@ -1606,11 +1612,12 @@ const (
RTM_GETSTATS = 0x5e
RTM_GETTCLASS = 0x2a
RTM_GETTFILTER = 0x2e
- RTM_MAX = 0x63
+ RTM_MAX = 0x67
RTM_NEWACTION = 0x30
RTM_NEWADDR = 0x14
RTM_NEWADDRLABEL = 0x48
RTM_NEWCACHEREPORT = 0x60
+ RTM_NEWCHAIN = 0x64
RTM_NEWLINK = 0x10
RTM_NEWMDB = 0x54
RTM_NEWNDUSEROPT = 0x44
@@ -1625,8 +1632,8 @@ const (
RTM_NEWSTATS = 0x5c
RTM_NEWTCLASS = 0x28
RTM_NEWTFILTER = 0x2c
- RTM_NR_FAMILIES = 0x15
- RTM_NR_MSGTYPES = 0x54
+ RTM_NR_FAMILIES = 0x16
+ RTM_NR_MSGTYPES = 0x58
RTM_SETDCB = 0x4f
RTM_SETLINK = 0x13
RTM_SETNEIGHTBL = 0x43
@@ -1675,6 +1682,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
+ SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_MODE_DISABLED = 0x0
SECCOMP_MODE_FILTER = 0x2
@@ -1879,6 +1887,7 @@ const (
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPNS = 0x23
+ SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
SO_VM_SOCKETS_BUFFER_MIN_SIZE = 0x1
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
index f33d031ad..8cdf353dc 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
@@ -1006,7 +1006,9 @@ const (
MFD_HUGE_256MB = 0x70000000
MFD_HUGE_2GB = 0x7c000000
MFD_HUGE_2MB = 0x54000000
+ MFD_HUGE_32MB = 0x64000000
MFD_HUGE_512KB = 0x4c000000
+ MFD_HUGE_512MB = 0x74000000
MFD_HUGE_64KB = 0x40000000
MFD_HUGE_8MB = 0x5c000000
MFD_HUGE_MASK = 0x3f
@@ -1019,6 +1021,8 @@ const (
MNT_DETACH = 0x2
MNT_EXPIRE = 0x4
MNT_FORCE = 0x1
+ MODULE_INIT_IGNORE_MODVERSIONS = 0x1
+ MODULE_INIT_IGNORE_VERMAGIC = 0x2
MSDOS_SUPER_MAGIC = 0x4d44
MSG_BATCH = 0x40000
MSG_CMSG_CLOEXEC = 0x40000000
@@ -1645,6 +1649,7 @@ const (
RTM_DELACTION = 0x31
RTM_DELADDR = 0x15
RTM_DELADDRLABEL = 0x49
+ RTM_DELCHAIN = 0x65
RTM_DELLINK = 0x11
RTM_DELMDB = 0x55
RTM_DELNEIGH = 0x1d
@@ -1665,6 +1670,7 @@ const (
RTM_GETADDR = 0x16
RTM_GETADDRLABEL = 0x4a
RTM_GETANYCAST = 0x3e
+ RTM_GETCHAIN = 0x66
RTM_GETDCB = 0x4e
RTM_GETLINK = 0x12
RTM_GETMDB = 0x56
@@ -1679,11 +1685,12 @@ const (
RTM_GETSTATS = 0x5e
RTM_GETTCLASS = 0x2a
RTM_GETTFILTER = 0x2e
- RTM_MAX = 0x63
+ RTM_MAX = 0x67
RTM_NEWACTION = 0x30
RTM_NEWADDR = 0x14
RTM_NEWADDRLABEL = 0x48
RTM_NEWCACHEREPORT = 0x60
+ RTM_NEWCHAIN = 0x64
RTM_NEWLINK = 0x10
RTM_NEWMDB = 0x54
RTM_NEWNDUSEROPT = 0x44
@@ -1698,8 +1705,8 @@ const (
RTM_NEWSTATS = 0x5c
RTM_NEWTCLASS = 0x28
RTM_NEWTFILTER = 0x2c
- RTM_NR_FAMILIES = 0x15
- RTM_NR_MSGTYPES = 0x54
+ RTM_NR_FAMILIES = 0x16
+ RTM_NR_MSGTYPES = 0x58
RTM_SETDCB = 0x4f
RTM_SETLINK = 0x13
RTM_SETNEIGHTBL = 0x43
@@ -1748,6 +1755,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
+ SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_MODE_DISABLED = 0x0
SECCOMP_MODE_FILTER = 0x2
@@ -1952,6 +1960,7 @@ const (
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPNS = 0x23
+ SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
SO_VM_SOCKETS_BUFFER_MIN_SIZE = 0x1
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go
index ab2f76122..6bae21e5d 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go
@@ -1,4 +1,4 @@
-// mksyscall_aix.pl -aix -tags aix,ppc syscall_aix.go syscall_aix_ppc.go
+// mksyscall_aix_ppc.pl -aix -tags aix,ppc syscall_aix.go syscall_aix_ppc.go
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build aix,ppc
@@ -7,6 +7,7 @@ package unix
/*
#include
+#include
int utimes(uintptr_t, uintptr_t);
int utimensat(int, uintptr_t, uintptr_t, int);
int getcwd(uintptr_t, size_t);
@@ -20,10 +21,8 @@ int chdir(uintptr_t);
int chroot(uintptr_t);
int close(int);
int dup(int);
-int dup3(int, int, int);
void exit(int);
int faccessat(int, uintptr_t, unsigned int, int);
-int fallocate(int, unsigned int, long long, long long);
int fchdir(int);
int fchmod(int, unsigned int);
int fchmodat(int, uintptr_t, unsigned int, int);
@@ -49,7 +48,6 @@ int open64(uintptr_t, int, unsigned int);
int openat(int, uintptr_t, int, unsigned int);
int read(int, uintptr_t, size_t);
int readlink(uintptr_t, uintptr_t, size_t);
-int removexattr(uintptr_t, uintptr_t);
int renameat(int, uintptr_t, int, uintptr_t);
int setdomainname(uintptr_t, size_t);
int sethostname(uintptr_t, size_t);
@@ -61,13 +59,11 @@ int setgid(int);
int setpriority(int, int, int);
int statx(int, uintptr_t, int, int, uintptr_t);
int sync();
-long long tee(int, int, int, int);
uintptr_t times(uintptr_t);
int umask(int);
int uname(uintptr_t);
int unlink(uintptr_t);
int unlinkat(int, uintptr_t, int);
-int unshare(int);
int ustat(int, uintptr_t);
int write(int, uintptr_t, size_t);
int dup2(int, int);
@@ -118,7 +114,6 @@ int msync(uintptr_t, size_t, int);
int munlock(uintptr_t, size_t);
int munlockall();
int pipe(uintptr_t);
-int pipe2(uintptr_t, int);
int poll(uintptr_t, int, int);
int gettimeofday(uintptr_t, uintptr_t);
int time(uintptr_t);
@@ -131,7 +126,6 @@ uintptr_t mmap(uintptr_t, uintptr_t, int, int, int, long long);
*/
import "C"
import (
- "syscall"
"unsafe"
)
@@ -245,6 +239,17 @@ func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+ r0, er := C.fcntl(C.uintptr_t(fd), C.int(cmd), C.uintptr_t(arg))
+ val = int(r0)
+ if r0 == -1 && er != nil {
+ err = er
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Acct(path string) (err error) {
_p0 := uintptr(unsafe.Pointer(C.CString(path)))
r0, er := C.acct(C.uintptr_t(_p0))
@@ -299,16 +304,6 @@ func Dup(oldfd int) (fd int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Dup3(oldfd int, newfd int, flags int) (err error) {
- r0, er := C.dup3(C.int(oldfd), C.int(newfd), C.int(flags))
- if r0 == -1 && er != nil {
- err = er
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
func Exit(code int) {
C.exit(C.int(code))
return
@@ -327,16 +322,6 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
- r0, er := C.fallocate(C.int(fd), C.uint(mode), C.longlong(off), C.longlong(len))
- if r0 == -1 && er != nil {
- err = er
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
func Fchdir(fd int) (err error) {
r0, er := C.fchdir(C.int(fd))
if r0 == -1 && er != nil {
@@ -379,17 +364,6 @@ func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
- r0, er := C.fcntl(C.uintptr_t(fd), C.int(cmd), C.uintptr_t(arg))
- val = int(r0)
- if r0 == -1 && er != nil {
- err = er
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
func Fdatasync(fd int) (err error) {
r0, er := C.fdatasync(C.int(fd))
if r0 == -1 && er != nil {
@@ -477,7 +451,7 @@ func Getsid(pid int) (sid int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Kill(pid int, sig syscall.Signal) (err error) {
+func Kill(pid int, sig Signal) (err error) {
r0, er := C.kill(C.int(pid), C.int(sig))
if r0 == -1 && er != nil {
err = er
@@ -628,18 +602,6 @@ func Readlink(path string, buf []byte) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Removexattr(path string, attr string) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- _p1 := uintptr(unsafe.Pointer(C.CString(attr)))
- r0, er := C.removexattr(C.uintptr_t(_p0), C.uintptr_t(_p1))
- if r0 == -1 && er != nil {
- err = er
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
_p0 := uintptr(unsafe.Pointer(C.CString(oldpath)))
_p1 := uintptr(unsafe.Pointer(C.CString(newpath)))
@@ -763,17 +725,6 @@ func Sync() {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
- r0, er := C.tee(C.int(rfd), C.int(wfd), C.int(len), C.int(flags))
- n = int64(r0)
- if r0 == -1 && er != nil {
- err = er
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
func Times(tms *Tms) (ticks uintptr, err error) {
r0, er := C.times(C.uintptr_t(uintptr(unsafe.Pointer(tms))))
ticks = uintptr(r0)
@@ -825,16 +776,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Unshare(flags int) (err error) {
- r0, er := C.unshare(C.int(flags))
- if r0 == -1 && er != nil {
- err = er
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
func Ustat(dev int, ubuf *Ustat_t) (err error) {
r0, er := C.ustat(C.int(dev), C.uintptr_t(uintptr(unsafe.Pointer(ubuf))))
if r0 == -1 && er != nil {
@@ -1425,16 +1366,6 @@ func pipe(p *[2]_C_int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func pipe2(p *[2]_C_int, flags int) (err error) {
- r0, er := C.pipe2(C.uintptr_t(uintptr(unsafe.Pointer(p))), C.int(flags))
- if r0 == -1 && er != nil {
- err = er
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
r0, er := C.poll(C.uintptr_t(uintptr(unsafe.Pointer(fds))), C.int(nfds), C.int(timeout))
n = int(r0)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go
index 2e4f93fb1..3e929e520 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go
@@ -1,147 +1,25 @@
-// mksyscall_aix.pl -aix -tags aix,ppc64 syscall_aix.go syscall_aix_ppc64.go
+// mksyscall_aix_ppc64.pl -aix -tags aix,ppc64 syscall_aix.go syscall_aix_ppc64.go
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build aix,ppc64
package unix
-/*
-#include
-int utimes(uintptr_t, uintptr_t);
-int utimensat(int, uintptr_t, uintptr_t, int);
-int getcwd(uintptr_t, size_t);
-int accept(int, uintptr_t, uintptr_t);
-int getdirent(int, uintptr_t, size_t);
-int wait4(int, uintptr_t, int, uintptr_t);
-int ioctl(int, int, uintptr_t);
-int fcntl(uintptr_t, int, uintptr_t);
-int acct(uintptr_t);
-int chdir(uintptr_t);
-int chroot(uintptr_t);
-int close(int);
-int dup(int);
-int dup3(int, int, int);
-void exit(int);
-int faccessat(int, uintptr_t, unsigned int, int);
-int fallocate(int, unsigned int, long long, long long);
-int fchdir(int);
-int fchmod(int, unsigned int);
-int fchmodat(int, uintptr_t, unsigned int, int);
-int fchownat(int, uintptr_t, int, int, int);
-int fdatasync(int);
-int fsync(int);
-int getpgid(int);
-int getpgrp();
-int getpid();
-int getppid();
-int getpriority(int, int);
-int getrusage(int, uintptr_t);
-int getsid(int);
-int kill(int, int);
-int syslog(int, uintptr_t, size_t);
-int mkdir(int, uintptr_t, unsigned int);
-int mkdirat(int, uintptr_t, unsigned int);
-int mkfifo(uintptr_t, unsigned int);
-int mknod(uintptr_t, unsigned int, int);
-int mknodat(int, uintptr_t, unsigned int, int);
-int nanosleep(uintptr_t, uintptr_t);
-int open64(uintptr_t, int, unsigned int);
-int openat(int, uintptr_t, int, unsigned int);
-int read(int, uintptr_t, size_t);
-int readlink(uintptr_t, uintptr_t, size_t);
-int removexattr(uintptr_t, uintptr_t);
-int renameat(int, uintptr_t, int, uintptr_t);
-int setdomainname(uintptr_t, size_t);
-int sethostname(uintptr_t, size_t);
-int setpgid(int, int);
-int setsid();
-int settimeofday(uintptr_t);
-int setuid(int);
-int setgid(int);
-int setpriority(int, int, int);
-int statx(int, uintptr_t, int, int, uintptr_t);
-int sync();
-long long tee(int, int, int, int);
-uintptr_t times(uintptr_t);
-int umask(int);
-int uname(uintptr_t);
-int unlink(uintptr_t);
-int unlinkat(int, uintptr_t, int);
-int unshare(int);
-int ustat(int, uintptr_t);
-int write(int, uintptr_t, size_t);
-int dup2(int, int);
-int posix_fadvise64(int, long long, long long, int);
-int fchown(int, int, int);
-int fstat(int, uintptr_t);
-int fstatat(int, uintptr_t, uintptr_t, int);
-int fstatfs(int, uintptr_t);
-int ftruncate(int, long long);
-int getegid();
-int geteuid();
-int getgid();
-int getuid();
-int lchown(uintptr_t, int, int);
-int listen(int, int);
-int lstat(uintptr_t, uintptr_t);
-int pause();
-int pread64(int, uintptr_t, size_t, long long);
-int pwrite64(int, uintptr_t, size_t, long long);
-int pselect(int, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
-int setregid(int, int);
-int setreuid(int, int);
-int shutdown(int, int);
-long long splice(int, uintptr_t, int, uintptr_t, int, int);
-int stat(uintptr_t, uintptr_t);
-int statfs(uintptr_t, uintptr_t);
-int truncate(uintptr_t, long long);
-int bind(int, uintptr_t, uintptr_t);
-int connect(int, uintptr_t, uintptr_t);
-int getgroups(int, uintptr_t);
-int setgroups(int, uintptr_t);
-int getsockopt(int, int, int, uintptr_t, uintptr_t);
-int setsockopt(int, int, int, uintptr_t, uintptr_t);
-int socket(int, int, int);
-int socketpair(int, int, int, uintptr_t);
-int getpeername(int, uintptr_t, uintptr_t);
-int getsockname(int, uintptr_t, uintptr_t);
-int recvfrom(int, uintptr_t, size_t, int, uintptr_t, uintptr_t);
-int sendto(int, uintptr_t, size_t, int, uintptr_t, uintptr_t);
-int recvmsg(int, uintptr_t, int);
-int sendmsg(int, uintptr_t, int);
-int munmap(uintptr_t, uintptr_t);
-int madvise(uintptr_t, size_t, int);
-int mprotect(uintptr_t, size_t, int);
-int mlock(uintptr_t, size_t);
-int mlockall(int);
-int msync(uintptr_t, size_t, int);
-int munlock(uintptr_t, size_t);
-int munlockall();
-int pipe(uintptr_t);
-int pipe2(uintptr_t, int);
-int poll(uintptr_t, int, int);
-int gettimeofday(uintptr_t, uintptr_t);
-int time(uintptr_t);
-int utime(uintptr_t, uintptr_t);
-int getrlimit(int, uintptr_t);
-int setrlimit(int, uintptr_t);
-long long lseek(int, long long, int);
-uintptr_t mmap64(uintptr_t, uintptr_t, int, int, int, long long);
-
-*/
-import "C"
import (
- "syscall"
"unsafe"
)
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func utimes(path string, times *[2]Timeval) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.utimes(C.uintptr_t(_p0), C.uintptr_t(uintptr(unsafe.Pointer(times))))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callutimes(uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -149,10 +27,14 @@ func utimes(path string, times *[2]Timeval) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.utimensat(C.int(dirfd), C.uintptr_t(_p0), C.uintptr_t(uintptr(unsafe.Pointer(times))), C.int(flag))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callutimensat(dirfd, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), flag)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -164,11 +46,9 @@ func getcwd(buf []byte) (err error) {
if len(buf) > 0 {
_p0 = &buf[0]
}
- var _p1 int
- _p1 = len(buf)
- r0, er := C.getcwd(C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callgetcwd(uintptr(unsafe.Pointer(_p0)), len(buf))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -176,10 +56,10 @@ func getcwd(buf []byte) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
- r0, er := C.accept(C.int(s), C.uintptr_t(uintptr(unsafe.Pointer(rsa))), C.uintptr_t(uintptr(unsafe.Pointer(addrlen))))
+ r0, e1 := callaccept(s, uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
fd = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -191,12 +71,10 @@ func getdirent(fd int, buf []byte) (n int, err error) {
if len(buf) > 0 {
_p0 = &buf[0]
}
- var _p1 int
- _p1 = len(buf)
- r0, er := C.getdirent(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1))
+ r0, e1 := callgetdirent(fd, uintptr(unsafe.Pointer(_p0)), len(buf))
n = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -204,10 +82,10 @@ func getdirent(fd int, buf []byte) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func wait4(pid Pid_t, status *_C_int, options int, rusage *Rusage) (wpid Pid_t, err error) {
- r0, er := C.wait4(C.int(pid), C.uintptr_t(uintptr(unsafe.Pointer(status))), C.int(options), C.uintptr_t(uintptr(unsafe.Pointer(rusage))))
+ r0, e1 := callwait4(int(pid), uintptr(unsafe.Pointer(status)), options, uintptr(unsafe.Pointer(rusage)))
wpid = Pid_t(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -215,9 +93,9 @@ func wait4(pid Pid_t, status *_C_int, options int, rusage *Rusage) (wpid Pid_t,
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ioctl(fd int, req uint, arg uintptr) (err error) {
- r0, er := C.ioctl(C.int(fd), C.int(req), C.uintptr_t(arg))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callioctl(fd, int(req), arg)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -225,10 +103,10 @@ func ioctl(fd int, req uint, arg uintptr) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func FcntlInt(fd uintptr, cmd int, arg int) (r int, err error) {
- r0, er := C.fcntl(C.uintptr_t(fd), C.int(cmd), C.uintptr_t(arg))
+ r0, e1 := callfcntl(fd, cmd, uintptr(arg))
r = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -236,73 +114,86 @@ func FcntlInt(fd uintptr, cmd int, arg int) (r int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) (err error) {
- r0, er := C.fcntl(C.uintptr_t(fd), C.int(cmd), C.uintptr_t(uintptr(unsafe.Pointer(lk))))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callfcntl(fd, cmd, uintptr(unsafe.Pointer(lk)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Acct(path string) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.acct(C.uintptr_t(_p0))
- if r0 == -1 && er != nil {
- err = er
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+ r0, e1 := callfcntl(uintptr(fd), cmd, uintptr(arg))
+ val = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Chdir(path string) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.chdir(C.uintptr_t(_p0))
- if r0 == -1 && er != nil {
- err = er
+func Acct(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callacct(uintptr(unsafe.Pointer(_p0)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Chroot(path string) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.chroot(C.uintptr_t(_p0))
- if r0 == -1 && er != nil {
- err = er
+func Chdir(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callchdir(uintptr(unsafe.Pointer(_p0)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Close(fd int) (err error) {
- r0, er := C.close(C.int(fd))
- if r0 == -1 && er != nil {
- err = er
+func Chroot(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callchroot(uintptr(unsafe.Pointer(_p0)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Dup(oldfd int) (fd int, err error) {
- r0, er := C.dup(C.int(oldfd))
- fd = int(r0)
- if r0 == -1 && er != nil {
- err = er
+func Close(fd int) (err error) {
+ _, e1 := callclose(fd)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Dup3(oldfd int, newfd int, flags int) (err error) {
- r0, er := C.dup3(C.int(oldfd), C.int(newfd), C.int(flags))
- if r0 == -1 && er != nil {
- err = er
+func Dup(oldfd int) (fd int, err error) {
+ r0, e1 := calldup(oldfd)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -310,27 +201,21 @@ func Dup3(oldfd int, newfd int, flags int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Exit(code int) {
- C.exit(C.int(code))
+ callexit(code)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.faccessat(C.int(dirfd), C.uintptr_t(_p0), C.uint(mode), C.int(flags))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
}
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
- r0, er := C.fallocate(C.int(fd), C.uint(mode), C.longlong(off), C.longlong(len))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callfaccessat(dirfd, uintptr(unsafe.Pointer(_p0)), mode, flags)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -338,9 +223,9 @@ func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fchdir(fd int) (err error) {
- r0, er := C.fchdir(C.int(fd))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callfchdir(fd)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -348,9 +233,9 @@ func Fchdir(fd int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fchmod(fd int, mode uint32) (err error) {
- r0, er := C.fchmod(C.int(fd), C.uint(mode))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callfchmod(fd, mode)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -358,10 +243,14 @@ func Fchmod(fd int, mode uint32) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.fchmodat(C.int(dirfd), C.uintptr_t(_p0), C.uint(mode), C.int(flags))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callfchmodat(dirfd, uintptr(unsafe.Pointer(_p0)), mode, flags)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -369,21 +258,14 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.fchownat(C.int(dirfd), C.uintptr_t(_p0), C.int(uid), C.int(gid), C.int(flags))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
}
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
- r0, er := C.fcntl(C.uintptr_t(fd), C.int(cmd), C.uintptr_t(arg))
- val = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callfchownat(dirfd, uintptr(unsafe.Pointer(_p0)), uid, gid, flags)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -391,9 +273,9 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fdatasync(fd int) (err error) {
- r0, er := C.fdatasync(C.int(fd))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callfdatasync(fd)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -401,9 +283,9 @@ func Fdatasync(fd int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fsync(fd int) (err error) {
- r0, er := C.fsync(C.int(fd))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callfsync(fd)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -411,10 +293,10 @@ func Fsync(fd int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Getpgid(pid int) (pgid int, err error) {
- r0, er := C.getpgid(C.int(pid))
+ r0, e1 := callgetpgid(pid)
pgid = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -422,7 +304,7 @@ func Getpgid(pid int) (pgid int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Getpgrp() (pid int) {
- r0, _ := C.getpgrp()
+ r0, _ := callgetpgrp()
pid = int(r0)
return
}
@@ -430,7 +312,7 @@ func Getpgrp() (pid int) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Getpid() (pid int) {
- r0, _ := C.getpid()
+ r0, _ := callgetpid()
pid = int(r0)
return
}
@@ -438,7 +320,7 @@ func Getpid() (pid int) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Getppid() (ppid int) {
- r0, _ := C.getppid()
+ r0, _ := callgetppid()
ppid = int(r0)
return
}
@@ -446,10 +328,10 @@ func Getppid() (ppid int) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Getpriority(which int, who int) (prio int, err error) {
- r0, er := C.getpriority(C.int(which), C.int(who))
+ r0, e1 := callgetpriority(which, who)
prio = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -457,9 +339,9 @@ func Getpriority(which int, who int) (prio int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Getrusage(who int, rusage *Rusage) (err error) {
- r0, er := C.getrusage(C.int(who), C.uintptr_t(uintptr(unsafe.Pointer(rusage))))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callgetrusage(who, uintptr(unsafe.Pointer(rusage)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -467,20 +349,20 @@ func Getrusage(who int, rusage *Rusage) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Getsid(pid int) (sid int, err error) {
- r0, er := C.getsid(C.int(pid))
+ r0, e1 := callgetsid(pid)
sid = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Kill(pid int, sig syscall.Signal) (err error) {
- r0, er := C.kill(C.int(pid), C.int(sig))
- if r0 == -1 && er != nil {
- err = er
+func Kill(pid int, sig Signal) (err error) {
+ _, e1 := callkill(pid, int(sig))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -492,12 +374,10 @@ func Klogctl(typ int, buf []byte) (n int, err error) {
if len(buf) > 0 {
_p0 = &buf[0]
}
- var _p1 int
- _p1 = len(buf)
- r0, er := C.syslog(C.int(typ), C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1))
+ r0, e1 := callsyslog(typ, uintptr(unsafe.Pointer(_p0)), len(buf))
n = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -505,10 +385,14 @@ func Klogctl(typ int, buf []byte) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Mkdir(dirfd int, path string, mode uint32) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.mkdir(C.int(dirfd), C.uintptr_t(_p0), C.uint(mode))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callmkdir(dirfd, uintptr(unsafe.Pointer(_p0)), mode)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -516,10 +400,14 @@ func Mkdir(dirfd int, path string, mode uint32) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Mkdirat(dirfd int, path string, mode uint32) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.mkdirat(C.int(dirfd), C.uintptr_t(_p0), C.uint(mode))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callmkdirat(dirfd, uintptr(unsafe.Pointer(_p0)), mode)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -527,10 +415,14 @@ func Mkdirat(dirfd int, path string, mode uint32) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Mkfifo(path string, mode uint32) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.mkfifo(C.uintptr_t(_p0), C.uint(mode))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callmkfifo(uintptr(unsafe.Pointer(_p0)), mode)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -538,10 +430,14 @@ func Mkfifo(path string, mode uint32) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Mknod(path string, mode uint32, dev int) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.mknod(C.uintptr_t(_p0), C.uint(mode), C.int(dev))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callmknod(uintptr(unsafe.Pointer(_p0)), mode, dev)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -549,10 +445,14 @@ func Mknod(path string, mode uint32, dev int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.mknodat(C.int(dirfd), C.uintptr_t(_p0), C.uint(mode), C.int(dev))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callmknodat(dirfd, uintptr(unsafe.Pointer(_p0)), mode, dev)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -560,9 +460,9 @@ func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
- r0, er := C.nanosleep(C.uintptr_t(uintptr(unsafe.Pointer(time))), C.uintptr_t(uintptr(unsafe.Pointer(leftover))))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callnanosleep(uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -570,11 +470,15 @@ func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Open(path string, mode int, perm uint32) (fd int, err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.open64(C.uintptr_t(_p0), C.int(mode), C.uint(perm))
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, e1 := callopen64(uintptr(unsafe.Pointer(_p0)), mode, perm)
fd = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -582,11 +486,15 @@ func Open(path string, mode int, perm uint32) (fd int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.openat(C.int(dirfd), C.uintptr_t(_p0), C.int(flags), C.uint(mode))
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, e1 := callopenat(dirfd, uintptr(unsafe.Pointer(_p0)), flags, mode)
fd = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -598,12 +506,10 @@ func read(fd int, p []byte) (n int, err error) {
if len(p) > 0 {
_p0 = &p[0]
}
- var _p1 int
- _p1 = len(p)
- r0, er := C.read(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1))
+ r0, e1 := callread(fd, uintptr(unsafe.Pointer(_p0)), len(p))
n = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -611,29 +517,19 @@ func read(fd int, p []byte) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Readlink(path string, buf []byte) (n int, err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
var _p1 *byte
if len(buf) > 0 {
_p1 = &buf[0]
}
- var _p2 int
- _p2 = len(buf)
- r0, er := C.readlink(C.uintptr_t(_p0), C.uintptr_t(uintptr(unsafe.Pointer(_p1))), C.size_t(_p2))
+ r0, e1 := callreadlink(uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), len(buf))
n = int(r0)
- if r0 == -1 && er != nil {
- err = er
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Removexattr(path string, attr string) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- _p1 := uintptr(unsafe.Pointer(C.CString(attr)))
- r0, er := C.removexattr(C.uintptr_t(_p0), C.uintptr_t(_p1))
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -641,11 +537,19 @@ func Removexattr(path string, attr string) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(oldpath)))
- _p1 := uintptr(unsafe.Pointer(C.CString(newpath)))
- r0, er := C.renameat(C.int(olddirfd), C.uintptr_t(_p0), C.int(newdirfd), C.uintptr_t(_p1))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(oldpath)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(newpath)
+ if err != nil {
+ return
+ }
+ _, e1 := callrenameat(olddirfd, uintptr(unsafe.Pointer(_p0)), newdirfd, uintptr(unsafe.Pointer(_p1)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -657,11 +561,9 @@ func Setdomainname(p []byte) (err error) {
if len(p) > 0 {
_p0 = &p[0]
}
- var _p1 int
- _p1 = len(p)
- r0, er := C.setdomainname(C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callsetdomainname(uintptr(unsafe.Pointer(_p0)), len(p))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -673,11 +575,9 @@ func Sethostname(p []byte) (err error) {
if len(p) > 0 {
_p0 = &p[0]
}
- var _p1 int
- _p1 = len(p)
- r0, er := C.sethostname(C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callsethostname(uintptr(unsafe.Pointer(_p0)), len(p))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -685,9 +585,9 @@ func Sethostname(p []byte) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Setpgid(pid int, pgid int) (err error) {
- r0, er := C.setpgid(C.int(pid), C.int(pgid))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callsetpgid(pid, pgid)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -695,10 +595,10 @@ func Setpgid(pid int, pgid int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Setsid() (pid int, err error) {
- r0, er := C.setsid()
+ r0, e1 := callsetsid()
pid = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -706,9 +606,9 @@ func Setsid() (pid int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Settimeofday(tv *Timeval) (err error) {
- r0, er := C.settimeofday(C.uintptr_t(uintptr(unsafe.Pointer(tv))))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callsettimeofday(uintptr(unsafe.Pointer(tv)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -716,9 +616,9 @@ func Settimeofday(tv *Timeval) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Setuid(uid int) (err error) {
- r0, er := C.setuid(C.int(uid))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callsetuid(uid)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -726,9 +626,9 @@ func Setuid(uid int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Setgid(uid int) (err error) {
- r0, er := C.setgid(C.int(uid))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callsetgid(uid)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -736,9 +636,9 @@ func Setgid(uid int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Setpriority(which int, who int, prio int) (err error) {
- r0, er := C.setpriority(C.int(which), C.int(who), C.int(prio))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callsetpriority(which, who, prio)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -746,10 +646,14 @@ func Setpriority(which int, who int, prio int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.statx(C.int(dirfd), C.uintptr_t(_p0), C.int(flags), C.int(mask), C.uintptr_t(uintptr(unsafe.Pointer(stat))))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callstatx(dirfd, uintptr(unsafe.Pointer(_p0)), flags, mask, uintptr(unsafe.Pointer(stat)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -757,28 +661,17 @@ func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err erro
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Sync() {
- C.sync()
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
- r0, er := C.tee(C.int(rfd), C.int(wfd), C.int(len), C.int(flags))
- n = int64(r0)
- if r0 == -1 && er != nil {
- err = er
- }
+ callsync()
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Times(tms *Tms) (ticks uintptr, err error) {
- r0, er := C.times(C.uintptr_t(uintptr(unsafe.Pointer(tms))))
+ r0, e1 := calltimes(uintptr(unsafe.Pointer(tms)))
ticks = uintptr(r0)
- if uintptr(r0) == ^uintptr(0) && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -786,7 +679,7 @@ func Times(tms *Tms) (ticks uintptr, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Umask(mask int) (oldmask int) {
- r0, _ := C.umask(C.int(mask))
+ r0, _ := callumask(mask)
oldmask = int(r0)
return
}
@@ -794,9 +687,9 @@ func Umask(mask int) (oldmask int) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Uname(buf *Utsname) (err error) {
- r0, er := C.uname(C.uintptr_t(uintptr(unsafe.Pointer(buf))))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := calluname(uintptr(unsafe.Pointer(buf)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -804,10 +697,14 @@ func Uname(buf *Utsname) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Unlink(path string) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.unlink(C.uintptr_t(_p0))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callunlink(uintptr(unsafe.Pointer(_p0)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -815,20 +712,14 @@ func Unlink(path string) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Unlinkat(dirfd int, path string, flags int) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.unlinkat(C.int(dirfd), C.uintptr_t(_p0), C.int(flags))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
}
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unshare(flags int) (err error) {
- r0, er := C.unshare(C.int(flags))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callunlinkat(dirfd, uintptr(unsafe.Pointer(_p0)), flags)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -836,9 +727,9 @@ func Unshare(flags int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Ustat(dev int, ubuf *Ustat_t) (err error) {
- r0, er := C.ustat(C.int(dev), C.uintptr_t(uintptr(unsafe.Pointer(ubuf))))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callustat(dev, uintptr(unsafe.Pointer(ubuf)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -850,12 +741,10 @@ func write(fd int, p []byte) (n int, err error) {
if len(p) > 0 {
_p0 = &p[0]
}
- var _p1 int
- _p1 = len(p)
- r0, er := C.write(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1))
+ r0, e1 := callwrite(fd, uintptr(unsafe.Pointer(_p0)), len(p))
n = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -863,10 +752,10 @@ func write(fd int, p []byte) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func readlen(fd int, p *byte, np int) (n int, err error) {
- r0, er := C.read(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(p))), C.size_t(np))
+ r0, e1 := callread(fd, uintptr(unsafe.Pointer(p)), np)
n = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -874,10 +763,10 @@ func readlen(fd int, p *byte, np int) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func writelen(fd int, p *byte, np int) (n int, err error) {
- r0, er := C.write(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(p))), C.size_t(np))
+ r0, e1 := callwrite(fd, uintptr(unsafe.Pointer(p)), np)
n = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -885,9 +774,9 @@ func writelen(fd int, p *byte, np int) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Dup2(oldfd int, newfd int) (err error) {
- r0, er := C.dup2(C.int(oldfd), C.int(newfd))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := calldup2(oldfd, newfd)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -895,9 +784,9 @@ func Dup2(oldfd int, newfd int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
- r0, er := C.posix_fadvise64(C.int(fd), C.longlong(offset), C.longlong(length), C.int(advice))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callposix_fadvise64(fd, offset, length, advice)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -905,9 +794,9 @@ func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fchown(fd int, uid int, gid int) (err error) {
- r0, er := C.fchown(C.int(fd), C.int(uid), C.int(gid))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callfchown(fd, uid, gid)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -915,9 +804,9 @@ func Fchown(fd int, uid int, gid int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fstat(fd int, stat *Stat_t) (err error) {
- r0, er := C.fstat(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(stat))))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callfstat(fd, uintptr(unsafe.Pointer(stat)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -925,10 +814,14 @@ func Fstat(fd int, stat *Stat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.fstatat(C.int(dirfd), C.uintptr_t(_p0), C.uintptr_t(uintptr(unsafe.Pointer(stat))), C.int(flags))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callfstatat(dirfd, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), flags)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -936,9 +829,9 @@ func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fstatfs(fd int, buf *Statfs_t) (err error) {
- r0, er := C.fstatfs(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(buf))))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callfstatfs(fd, uintptr(unsafe.Pointer(buf)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -946,9 +839,9 @@ func Fstatfs(fd int, buf *Statfs_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Ftruncate(fd int, length int64) (err error) {
- r0, er := C.ftruncate(C.int(fd), C.longlong(length))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callftruncate(fd, length)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -956,7 +849,7 @@ func Ftruncate(fd int, length int64) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Getegid() (egid int) {
- r0, _ := C.getegid()
+ r0, _ := callgetegid()
egid = int(r0)
return
}
@@ -964,7 +857,7 @@ func Getegid() (egid int) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Geteuid() (euid int) {
- r0, _ := C.geteuid()
+ r0, _ := callgeteuid()
euid = int(r0)
return
}
@@ -972,7 +865,7 @@ func Geteuid() (euid int) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Getgid() (gid int) {
- r0, _ := C.getgid()
+ r0, _ := callgetgid()
gid = int(r0)
return
}
@@ -980,7 +873,7 @@ func Getgid() (gid int) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Getuid() (uid int) {
- r0, _ := C.getuid()
+ r0, _ := callgetuid()
uid = int(r0)
return
}
@@ -988,10 +881,14 @@ func Getuid() (uid int) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Lchown(path string, uid int, gid int) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.lchown(C.uintptr_t(_p0), C.int(uid), C.int(gid))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := calllchown(uintptr(unsafe.Pointer(_p0)), uid, gid)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -999,9 +896,9 @@ func Lchown(path string, uid int, gid int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Listen(s int, n int) (err error) {
- r0, er := C.listen(C.int(s), C.int(n))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := calllisten(s, n)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1009,10 +906,14 @@ func Listen(s int, n int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Lstat(path string, stat *Stat_t) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.lstat(C.uintptr_t(_p0), C.uintptr_t(uintptr(unsafe.Pointer(stat))))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := calllstat(uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1020,9 +921,9 @@ func Lstat(path string, stat *Stat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pause() (err error) {
- r0, er := C.pause()
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callpause()
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1034,12 +935,10 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {
if len(p) > 0 {
_p0 = &p[0]
}
- var _p1 int
- _p1 = len(p)
- r0, er := C.pread64(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1), C.longlong(offset))
+ r0, e1 := callpread64(fd, uintptr(unsafe.Pointer(_p0)), len(p), offset)
n = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1051,12 +950,10 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
if len(p) > 0 {
_p0 = &p[0]
}
- var _p1 int
- _p1 = len(p)
- r0, er := C.pwrite64(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1), C.longlong(offset))
+ r0, e1 := callpwrite64(fd, uintptr(unsafe.Pointer(_p0)), len(p), offset)
n = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1064,10 +961,10 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
- r0, er := C.pselect(C.int(nfd), C.uintptr_t(uintptr(unsafe.Pointer(r))), C.uintptr_t(uintptr(unsafe.Pointer(w))), C.uintptr_t(uintptr(unsafe.Pointer(e))), C.uintptr_t(uintptr(unsafe.Pointer(timeout))), C.uintptr_t(uintptr(unsafe.Pointer(sigmask))))
+ r0, e1 := callpselect(nfd, uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)))
n = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1075,9 +972,9 @@ func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Setregid(rgid int, egid int) (err error) {
- r0, er := C.setregid(C.int(rgid), C.int(egid))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callsetregid(rgid, egid)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1085,9 +982,9 @@ func Setregid(rgid int, egid int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Setreuid(ruid int, euid int) (err error) {
- r0, er := C.setreuid(C.int(ruid), C.int(euid))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callsetreuid(ruid, euid)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1095,9 +992,9 @@ func Setreuid(ruid int, euid int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Shutdown(fd int, how int) (err error) {
- r0, er := C.shutdown(C.int(fd), C.int(how))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callshutdown(fd, how)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1105,10 +1002,10 @@ func Shutdown(fd int, how int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) {
- r0, er := C.splice(C.int(rfd), C.uintptr_t(uintptr(unsafe.Pointer(roff))), C.int(wfd), C.uintptr_t(uintptr(unsafe.Pointer(woff))), C.int(len), C.int(flags))
+ r0, e1 := callsplice(rfd, uintptr(unsafe.Pointer(roff)), wfd, uintptr(unsafe.Pointer(woff)), len, flags)
n = int64(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1116,10 +1013,14 @@ func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n i
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Stat(path string, stat *Stat_t) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.stat(C.uintptr_t(_p0), C.uintptr_t(uintptr(unsafe.Pointer(stat))))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callstat(uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1127,10 +1028,14 @@ func Stat(path string, stat *Stat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Statfs(path string, buf *Statfs_t) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.statfs(C.uintptr_t(_p0), C.uintptr_t(uintptr(unsafe.Pointer(buf))))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callstatfs(uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1138,10 +1043,14 @@ func Statfs(path string, buf *Statfs_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Truncate(path string, length int64) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.truncate(C.uintptr_t(_p0), C.longlong(length))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := calltruncate(uintptr(unsafe.Pointer(_p0)), length)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1149,9 +1058,9 @@ func Truncate(path string, length int64) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
- r0, er := C.bind(C.int(s), C.uintptr_t(uintptr(addr)), C.uintptr_t(uintptr(addrlen)))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callbind(s, uintptr(addr), uintptr(addrlen))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1159,9 +1068,9 @@ func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
- r0, er := C.connect(C.int(s), C.uintptr_t(uintptr(addr)), C.uintptr_t(uintptr(addrlen)))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callconnect(s, uintptr(addr), uintptr(addrlen))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1169,10 +1078,10 @@ func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getgroups(n int, list *_Gid_t) (nn int, err error) {
- r0, er := C.getgroups(C.int(n), C.uintptr_t(uintptr(unsafe.Pointer(list))))
+ r0, e1 := callgetgroups(n, uintptr(unsafe.Pointer(list)))
nn = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1180,9 +1089,9 @@ func getgroups(n int, list *_Gid_t) (nn int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func setgroups(n int, list *_Gid_t) (err error) {
- r0, er := C.setgroups(C.int(n), C.uintptr_t(uintptr(unsafe.Pointer(list))))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callsetgroups(n, uintptr(unsafe.Pointer(list)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1190,9 +1099,9 @@ func setgroups(n int, list *_Gid_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
- r0, er := C.getsockopt(C.int(s), C.int(level), C.int(name), C.uintptr_t(uintptr(val)), C.uintptr_t(uintptr(unsafe.Pointer(vallen))))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callgetsockopt(s, level, name, uintptr(val), uintptr(unsafe.Pointer(vallen)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1200,9 +1109,9 @@ func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
- r0, er := C.setsockopt(C.int(s), C.int(level), C.int(name), C.uintptr_t(uintptr(val)), C.uintptr_t(vallen))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callsetsockopt(s, level, name, uintptr(val), vallen)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1210,10 +1119,10 @@ func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr)
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func socket(domain int, typ int, proto int) (fd int, err error) {
- r0, er := C.socket(C.int(domain), C.int(typ), C.int(proto))
+ r0, e1 := callsocket(domain, typ, proto)
fd = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1221,9 +1130,9 @@ func socket(domain int, typ int, proto int) (fd int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
- r0, er := C.socketpair(C.int(domain), C.int(typ), C.int(proto), C.uintptr_t(uintptr(unsafe.Pointer(fd))))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callsocketpair(domain, typ, proto, uintptr(unsafe.Pointer(fd)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1231,9 +1140,9 @@ func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
- r0, er := C.getpeername(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(rsa))), C.uintptr_t(uintptr(unsafe.Pointer(addrlen))))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callgetpeername(fd, uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1241,9 +1150,9 @@ func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
- r0, er := C.getsockname(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(rsa))), C.uintptr_t(uintptr(unsafe.Pointer(addrlen))))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callgetsockname(fd, uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1255,12 +1164,10 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl
if len(p) > 0 {
_p0 = &p[0]
}
- var _p1 int
- _p1 = len(p)
- r0, er := C.recvfrom(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1), C.int(flags), C.uintptr_t(uintptr(unsafe.Pointer(from))), C.uintptr_t(uintptr(unsafe.Pointer(fromlen))))
+ r0, e1 := callrecvfrom(fd, uintptr(unsafe.Pointer(_p0)), len(p), flags, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
n = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1272,11 +1179,9 @@ func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (
if len(buf) > 0 {
_p0 = &buf[0]
}
- var _p1 int
- _p1 = len(buf)
- r0, er := C.sendto(C.int(s), C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1), C.int(flags), C.uintptr_t(uintptr(to)), C.uintptr_t(uintptr(addrlen)))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callsendto(s, uintptr(unsafe.Pointer(_p0)), len(buf), flags, uintptr(to), uintptr(addrlen))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1284,10 +1189,10 @@ func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
- r0, er := C.recvmsg(C.int(s), C.uintptr_t(uintptr(unsafe.Pointer(msg))), C.int(flags))
+ r0, e1 := callrecvmsg(s, uintptr(unsafe.Pointer(msg)), flags)
n = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1295,10 +1200,10 @@ func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
- r0, er := C.sendmsg(C.int(s), C.uintptr_t(uintptr(unsafe.Pointer(msg))), C.int(flags))
+ r0, e1 := callsendmsg(s, uintptr(unsafe.Pointer(msg)), flags)
n = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1306,9 +1211,9 @@ func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func munmap(addr uintptr, length uintptr) (err error) {
- r0, er := C.munmap(C.uintptr_t(addr), C.uintptr_t(length))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callmunmap(addr, length)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1320,11 +1225,9 @@ func Madvise(b []byte, advice int) (err error) {
if len(b) > 0 {
_p0 = &b[0]
}
- var _p1 int
- _p1 = len(b)
- r0, er := C.madvise(C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1), C.int(advice))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callmadvise(uintptr(unsafe.Pointer(_p0)), len(b), advice)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1336,11 +1239,9 @@ func Mprotect(b []byte, prot int) (err error) {
if len(b) > 0 {
_p0 = &b[0]
}
- var _p1 int
- _p1 = len(b)
- r0, er := C.mprotect(C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1), C.int(prot))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callmprotect(uintptr(unsafe.Pointer(_p0)), len(b), prot)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1352,11 +1253,9 @@ func Mlock(b []byte) (err error) {
if len(b) > 0 {
_p0 = &b[0]
}
- var _p1 int
- _p1 = len(b)
- r0, er := C.mlock(C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callmlock(uintptr(unsafe.Pointer(_p0)), len(b))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1364,9 +1263,9 @@ func Mlock(b []byte) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Mlockall(flags int) (err error) {
- r0, er := C.mlockall(C.int(flags))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callmlockall(flags)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1378,11 +1277,9 @@ func Msync(b []byte, flags int) (err error) {
if len(b) > 0 {
_p0 = &b[0]
}
- var _p1 int
- _p1 = len(b)
- r0, er := C.msync(C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1), C.int(flags))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callmsync(uintptr(unsafe.Pointer(_p0)), len(b), flags)
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1394,11 +1291,9 @@ func Munlock(b []byte) (err error) {
if len(b) > 0 {
_p0 = &b[0]
}
- var _p1 int
- _p1 = len(b)
- r0, er := C.munlock(C.uintptr_t(uintptr(unsafe.Pointer(_p0))), C.size_t(_p1))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callmunlock(uintptr(unsafe.Pointer(_p0)), len(b))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1406,9 +1301,9 @@ func Munlock(b []byte) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Munlockall() (err error) {
- r0, er := C.munlockall()
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callmunlockall()
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1416,19 +1311,9 @@ func Munlockall() (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func pipe(p *[2]_C_int) (err error) {
- r0, er := C.pipe(C.uintptr_t(uintptr(unsafe.Pointer(p))))
- if r0 == -1 && er != nil {
- err = er
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe2(p *[2]_C_int, flags int) (err error) {
- r0, er := C.pipe2(C.uintptr_t(uintptr(unsafe.Pointer(p))), C.int(flags))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callpipe(uintptr(unsafe.Pointer(p)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1436,10 +1321,10 @@ func pipe2(p *[2]_C_int, flags int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
- r0, er := C.poll(C.uintptr_t(uintptr(unsafe.Pointer(fds))), C.int(nfds), C.int(timeout))
+ r0, e1 := callpoll(uintptr(unsafe.Pointer(fds)), nfds, timeout)
n = int(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1447,9 +1332,9 @@ func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func gettimeofday(tv *Timeval, tzp *Timezone) (err error) {
- r0, er := C.gettimeofday(C.uintptr_t(uintptr(unsafe.Pointer(tv))), C.uintptr_t(uintptr(unsafe.Pointer(tzp))))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callgettimeofday(uintptr(unsafe.Pointer(tv)), uintptr(unsafe.Pointer(tzp)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1457,10 +1342,10 @@ func gettimeofday(tv *Timeval, tzp *Timezone) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Time(t *Time_t) (tt Time_t, err error) {
- r0, er := C.time(C.uintptr_t(uintptr(unsafe.Pointer(t))))
+ r0, e1 := calltime(uintptr(unsafe.Pointer(t)))
tt = Time_t(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1468,10 +1353,14 @@ func Time(t *Time_t) (tt Time_t, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Utime(path string, buf *Utimbuf) (err error) {
- _p0 := uintptr(unsafe.Pointer(C.CString(path)))
- r0, er := C.utime(C.uintptr_t(_p0), C.uintptr_t(uintptr(unsafe.Pointer(buf))))
- if r0 == -1 && er != nil {
- err = er
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, e1 := callutime(uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1479,9 +1368,9 @@ func Utime(path string, buf *Utimbuf) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Getrlimit(resource int, rlim *Rlimit) (err error) {
- r0, er := C.getrlimit(C.int(resource), C.uintptr_t(uintptr(unsafe.Pointer(rlim))))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callgetrlimit(resource, uintptr(unsafe.Pointer(rlim)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1489,9 +1378,9 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Setrlimit(resource int, rlim *Rlimit) (err error) {
- r0, er := C.setrlimit(C.int(resource), C.uintptr_t(uintptr(unsafe.Pointer(rlim))))
- if r0 == -1 && er != nil {
- err = er
+ _, e1 := callsetrlimit(resource, uintptr(unsafe.Pointer(rlim)))
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1499,10 +1388,10 @@ func Setrlimit(resource int, rlim *Rlimit) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Seek(fd int, offset int64, whence int) (off int64, err error) {
- r0, er := C.lseek(C.int(fd), C.longlong(offset), C.int(whence))
+ r0, e1 := calllseek(fd, offset, whence)
off = int64(r0)
- if r0 == -1 && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
@@ -1510,10 +1399,10 @@ func Seek(fd int, offset int64, whence int) (off int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
- r0, er := C.mmap64(C.uintptr_t(addr), C.uintptr_t(length), C.int(prot), C.int(flags), C.int(fd), C.longlong(offset))
+ r0, e1 := callmmap64(addr, length, prot, flags, fd, offset)
xaddr = uintptr(r0)
- if uintptr(r0) == ^uintptr(0) && er != nil {
- err = er
+ if e1 != 0 {
+ err = errnoErr(e1)
}
return
}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go
new file mode 100644
index 000000000..a185ee842
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go
@@ -0,0 +1,1162 @@
+// mksyscall_aix_ppc64.pl -aix -tags aix,ppc64 syscall_aix.go syscall_aix_ppc64.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build aix,ppc64
+// +build !gccgo
+
+package unix
+
+import (
+ "unsafe"
+)
+
+//go:cgo_import_dynamic libc_utimes utimes "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_utimensat utimensat "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getcwd getcwd "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_accept accept "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getdirent getdirent "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_wait4 wait4 "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_ioctl ioctl "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_fcntl fcntl "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_acct acct "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_chdir chdir "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_chroot chroot "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_close close "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_dup dup "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_exit exit "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_faccessat faccessat "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_fchdir fchdir "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_fchmod fchmod "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_fchmodat fchmodat "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_fchownat fchownat "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_fdatasync fdatasync "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_fsync fsync "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getpgid getpgid "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getpgrp getpgrp "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getpid getpid "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getppid getppid "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getpriority getpriority "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getrusage getrusage "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getsid getsid "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_kill kill "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_syslog syslog "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_mkdir mkdir "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_mkdirat mkdirat "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_mkfifo mkfifo "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_mknod mknod "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_mknodat mknodat "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_nanosleep nanosleep "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_open64 open64 "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_openat openat "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_read read "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_readlink readlink "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_renameat renameat "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_setdomainname setdomainname "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_sethostname sethostname "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_setpgid setpgid "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_setsid setsid "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_settimeofday settimeofday "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_setuid setuid "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_setgid setgid "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_setpriority setpriority "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_statx statx "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_sync sync "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_times times "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_umask umask "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_uname uname "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_unlink unlink "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_ustat ustat "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_write write "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_dup2 dup2 "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_posix_fadvise64 posix_fadvise64 "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_fchown fchown "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_fstat fstat "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_fstatat fstatat "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_fstatfs fstatfs "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_ftruncate ftruncate "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getegid getegid "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_geteuid geteuid "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getgid getgid "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getuid getuid "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_lchown lchown "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_listen listen "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_lstat lstat "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_pause pause "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_pread64 pread64 "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_pwrite64 pwrite64 "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_pselect pselect "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_setregid setregid "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_setreuid setreuid "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_shutdown shutdown "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_splice splice "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_stat stat "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_statfs statfs "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_truncate truncate "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_bind bind "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_connect connect "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getgroups getgroups "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_setgroups setgroups "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getsockopt getsockopt "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_setsockopt setsockopt "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_socket socket "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_socketpair socketpair "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getpeername getpeername "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getsockname getsockname "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_recvfrom recvfrom "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_sendto sendto "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_recvmsg recvmsg "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_sendmsg sendmsg "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_munmap munmap "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_madvise madvise "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_mprotect mprotect "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_mlock mlock "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_mlockall mlockall "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_msync msync "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_munlock munlock "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_munlockall munlockall "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_pipe pipe "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_poll poll "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_time time "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_utime utime "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_getrlimit getrlimit "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_lseek lseek "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_mmap64 mmap64 "libc.a/shr_64.o"
+
+//go:linkname libc_utimes libc_utimes
+//go:linkname libc_utimensat libc_utimensat
+//go:linkname libc_getcwd libc_getcwd
+//go:linkname libc_accept libc_accept
+//go:linkname libc_getdirent libc_getdirent
+//go:linkname libc_wait4 libc_wait4
+//go:linkname libc_ioctl libc_ioctl
+//go:linkname libc_fcntl libc_fcntl
+//go:linkname libc_acct libc_acct
+//go:linkname libc_chdir libc_chdir
+//go:linkname libc_chroot libc_chroot
+//go:linkname libc_close libc_close
+//go:linkname libc_dup libc_dup
+//go:linkname libc_exit libc_exit
+//go:linkname libc_faccessat libc_faccessat
+//go:linkname libc_fchdir libc_fchdir
+//go:linkname libc_fchmod libc_fchmod
+//go:linkname libc_fchmodat libc_fchmodat
+//go:linkname libc_fchownat libc_fchownat
+//go:linkname libc_fdatasync libc_fdatasync
+//go:linkname libc_fsync libc_fsync
+//go:linkname libc_getpgid libc_getpgid
+//go:linkname libc_getpgrp libc_getpgrp
+//go:linkname libc_getpid libc_getpid
+//go:linkname libc_getppid libc_getppid
+//go:linkname libc_getpriority libc_getpriority
+//go:linkname libc_getrusage libc_getrusage
+//go:linkname libc_getsid libc_getsid
+//go:linkname libc_kill libc_kill
+//go:linkname libc_syslog libc_syslog
+//go:linkname libc_mkdir libc_mkdir
+//go:linkname libc_mkdirat libc_mkdirat
+//go:linkname libc_mkfifo libc_mkfifo
+//go:linkname libc_mknod libc_mknod
+//go:linkname libc_mknodat libc_mknodat
+//go:linkname libc_nanosleep libc_nanosleep
+//go:linkname libc_open64 libc_open64
+//go:linkname libc_openat libc_openat
+//go:linkname libc_read libc_read
+//go:linkname libc_readlink libc_readlink
+//go:linkname libc_renameat libc_renameat
+//go:linkname libc_setdomainname libc_setdomainname
+//go:linkname libc_sethostname libc_sethostname
+//go:linkname libc_setpgid libc_setpgid
+//go:linkname libc_setsid libc_setsid
+//go:linkname libc_settimeofday libc_settimeofday
+//go:linkname libc_setuid libc_setuid
+//go:linkname libc_setgid libc_setgid
+//go:linkname libc_setpriority libc_setpriority
+//go:linkname libc_statx libc_statx
+//go:linkname libc_sync libc_sync
+//go:linkname libc_times libc_times
+//go:linkname libc_umask libc_umask
+//go:linkname libc_uname libc_uname
+//go:linkname libc_unlink libc_unlink
+//go:linkname libc_unlinkat libc_unlinkat
+//go:linkname libc_ustat libc_ustat
+//go:linkname libc_write libc_write
+//go:linkname libc_dup2 libc_dup2
+//go:linkname libc_posix_fadvise64 libc_posix_fadvise64
+//go:linkname libc_fchown libc_fchown
+//go:linkname libc_fstat libc_fstat
+//go:linkname libc_fstatat libc_fstatat
+//go:linkname libc_fstatfs libc_fstatfs
+//go:linkname libc_ftruncate libc_ftruncate
+//go:linkname libc_getegid libc_getegid
+//go:linkname libc_geteuid libc_geteuid
+//go:linkname libc_getgid libc_getgid
+//go:linkname libc_getuid libc_getuid
+//go:linkname libc_lchown libc_lchown
+//go:linkname libc_listen libc_listen
+//go:linkname libc_lstat libc_lstat
+//go:linkname libc_pause libc_pause
+//go:linkname libc_pread64 libc_pread64
+//go:linkname libc_pwrite64 libc_pwrite64
+//go:linkname libc_pselect libc_pselect
+//go:linkname libc_setregid libc_setregid
+//go:linkname libc_setreuid libc_setreuid
+//go:linkname libc_shutdown libc_shutdown
+//go:linkname libc_splice libc_splice
+//go:linkname libc_stat libc_stat
+//go:linkname libc_statfs libc_statfs
+//go:linkname libc_truncate libc_truncate
+//go:linkname libc_bind libc_bind
+//go:linkname libc_connect libc_connect
+//go:linkname libc_getgroups libc_getgroups
+//go:linkname libc_setgroups libc_setgroups
+//go:linkname libc_getsockopt libc_getsockopt
+//go:linkname libc_setsockopt libc_setsockopt
+//go:linkname libc_socket libc_socket
+//go:linkname libc_socketpair libc_socketpair
+//go:linkname libc_getpeername libc_getpeername
+//go:linkname libc_getsockname libc_getsockname
+//go:linkname libc_recvfrom libc_recvfrom
+//go:linkname libc_sendto libc_sendto
+//go:linkname libc_recvmsg libc_recvmsg
+//go:linkname libc_sendmsg libc_sendmsg
+//go:linkname libc_munmap libc_munmap
+//go:linkname libc_madvise libc_madvise
+//go:linkname libc_mprotect libc_mprotect
+//go:linkname libc_mlock libc_mlock
+//go:linkname libc_mlockall libc_mlockall
+//go:linkname libc_msync libc_msync
+//go:linkname libc_munlock libc_munlock
+//go:linkname libc_munlockall libc_munlockall
+//go:linkname libc_pipe libc_pipe
+//go:linkname libc_poll libc_poll
+//go:linkname libc_gettimeofday libc_gettimeofday
+//go:linkname libc_time libc_time
+//go:linkname libc_utime libc_utime
+//go:linkname libc_getrlimit libc_getrlimit
+//go:linkname libc_setrlimit libc_setrlimit
+//go:linkname libc_lseek libc_lseek
+//go:linkname libc_mmap64 libc_mmap64
+
+type syscallFunc uintptr
+
+var (
+ libc_utimes,
+ libc_utimensat,
+ libc_getcwd,
+ libc_accept,
+ libc_getdirent,
+ libc_wait4,
+ libc_ioctl,
+ libc_fcntl,
+ libc_acct,
+ libc_chdir,
+ libc_chroot,
+ libc_close,
+ libc_dup,
+ libc_exit,
+ libc_faccessat,
+ libc_fchdir,
+ libc_fchmod,
+ libc_fchmodat,
+ libc_fchownat,
+ libc_fdatasync,
+ libc_fsync,
+ libc_getpgid,
+ libc_getpgrp,
+ libc_getpid,
+ libc_getppid,
+ libc_getpriority,
+ libc_getrusage,
+ libc_getsid,
+ libc_kill,
+ libc_syslog,
+ libc_mkdir,
+ libc_mkdirat,
+ libc_mkfifo,
+ libc_mknod,
+ libc_mknodat,
+ libc_nanosleep,
+ libc_open64,
+ libc_openat,
+ libc_read,
+ libc_readlink,
+ libc_renameat,
+ libc_setdomainname,
+ libc_sethostname,
+ libc_setpgid,
+ libc_setsid,
+ libc_settimeofday,
+ libc_setuid,
+ libc_setgid,
+ libc_setpriority,
+ libc_statx,
+ libc_sync,
+ libc_times,
+ libc_umask,
+ libc_uname,
+ libc_unlink,
+ libc_unlinkat,
+ libc_ustat,
+ libc_write,
+ libc_dup2,
+ libc_posix_fadvise64,
+ libc_fchown,
+ libc_fstat,
+ libc_fstatat,
+ libc_fstatfs,
+ libc_ftruncate,
+ libc_getegid,
+ libc_geteuid,
+ libc_getgid,
+ libc_getuid,
+ libc_lchown,
+ libc_listen,
+ libc_lstat,
+ libc_pause,
+ libc_pread64,
+ libc_pwrite64,
+ libc_pselect,
+ libc_setregid,
+ libc_setreuid,
+ libc_shutdown,
+ libc_splice,
+ libc_stat,
+ libc_statfs,
+ libc_truncate,
+ libc_bind,
+ libc_connect,
+ libc_getgroups,
+ libc_setgroups,
+ libc_getsockopt,
+ libc_setsockopt,
+ libc_socket,
+ libc_socketpair,
+ libc_getpeername,
+ libc_getsockname,
+ libc_recvfrom,
+ libc_sendto,
+ libc_recvmsg,
+ libc_sendmsg,
+ libc_munmap,
+ libc_madvise,
+ libc_mprotect,
+ libc_mlock,
+ libc_mlockall,
+ libc_msync,
+ libc_munlock,
+ libc_munlockall,
+ libc_pipe,
+ libc_poll,
+ libc_gettimeofday,
+ libc_time,
+ libc_utime,
+ libc_getrlimit,
+ libc_setrlimit,
+ libc_lseek,
+ libc_mmap64 syscallFunc
+)
+
+// Implemented in runtime/syscall_aix.go.
+func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callutimes(_p0 uintptr, times uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_utimes)), 2, _p0, times, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callutimensat(dirfd int, _p0 uintptr, times uintptr, flag int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_utimensat)), 4, uintptr(dirfd), _p0, times, uintptr(flag), 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetcwd(_p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_getcwd)), 2, _p0, uintptr(_lenp0), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callaccept(s int, rsa uintptr, addrlen uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_accept)), 3, uintptr(s), rsa, addrlen, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetdirent(fd int, _p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_getdirent)), 3, uintptr(fd), _p0, uintptr(_lenp0), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callwait4(pid int, status uintptr, options int, rusage uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_wait4)), 4, uintptr(pid), status, uintptr(options), rusage, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callioctl(fd int, req int, arg uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_ioctl)), 3, uintptr(fd), uintptr(req), arg, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfcntl(fd uintptr, cmd int, arg uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fcntl)), 3, fd, uintptr(cmd), arg, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callacct(_p0 uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_acct)), 1, _p0, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callchdir(_p0 uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_chdir)), 1, _p0, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callchroot(_p0 uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_chroot)), 1, _p0, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callclose(fd int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_close)), 1, uintptr(fd), 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calldup(oldfd int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_dup)), 1, uintptr(oldfd), 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callexit(code int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_exit)), 1, uintptr(code), 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfaccessat(dirfd int, _p0 uintptr, mode uint32, flags int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_faccessat)), 4, uintptr(dirfd), _p0, uintptr(mode), uintptr(flags), 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfchdir(fd int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fchdir)), 1, uintptr(fd), 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfchmod(fd int, mode uint32) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fchmod)), 2, uintptr(fd), uintptr(mode), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfchmodat(dirfd int, _p0 uintptr, mode uint32, flags int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fchmodat)), 4, uintptr(dirfd), _p0, uintptr(mode), uintptr(flags), 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfchownat(dirfd int, _p0 uintptr, uid int, gid int, flags int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fchownat)), 5, uintptr(dirfd), _p0, uintptr(uid), uintptr(gid), uintptr(flags), 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfdatasync(fd int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fdatasync)), 1, uintptr(fd), 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfsync(fd int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fsync)), 1, uintptr(fd), 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetpgid(pid int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_getpgid)), 1, uintptr(pid), 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetpgrp() (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_getpgrp)), 0, 0, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetpid() (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_getpid)), 0, 0, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetppid() (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_getppid)), 0, 0, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetpriority(which int, who int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_getpriority)), 2, uintptr(which), uintptr(who), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetrusage(who int, rusage uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_getrusage)), 2, uintptr(who), rusage, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetsid(pid int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_getsid)), 1, uintptr(pid), 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callkill(pid int, sig int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_kill)), 2, uintptr(pid), uintptr(sig), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsyslog(typ int, _p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_syslog)), 3, uintptr(typ), _p0, uintptr(_lenp0), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmkdir(dirfd int, _p0 uintptr, mode uint32) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_mkdir)), 3, uintptr(dirfd), _p0, uintptr(mode), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmkdirat(dirfd int, _p0 uintptr, mode uint32) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_mkdirat)), 3, uintptr(dirfd), _p0, uintptr(mode), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmkfifo(_p0 uintptr, mode uint32) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_mkfifo)), 2, _p0, uintptr(mode), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmknod(_p0 uintptr, mode uint32, dev int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_mknod)), 3, _p0, uintptr(mode), uintptr(dev), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmknodat(dirfd int, _p0 uintptr, mode uint32, dev int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_mknodat)), 4, uintptr(dirfd), _p0, uintptr(mode), uintptr(dev), 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callnanosleep(time uintptr, leftover uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_nanosleep)), 2, time, leftover, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callopen64(_p0 uintptr, mode int, perm uint32) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_open64)), 3, _p0, uintptr(mode), uintptr(perm), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callopenat(dirfd int, _p0 uintptr, flags int, mode uint32) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_openat)), 4, uintptr(dirfd), _p0, uintptr(flags), uintptr(mode), 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callread(fd int, _p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_read)), 3, uintptr(fd), _p0, uintptr(_lenp0), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callreadlink(_p0 uintptr, _p1 uintptr, _lenp1 int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_readlink)), 3, _p0, _p1, uintptr(_lenp1), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callrenameat(olddirfd int, _p0 uintptr, newdirfd int, _p1 uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_renameat)), 4, uintptr(olddirfd), _p0, uintptr(newdirfd), _p1, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetdomainname(_p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_setdomainname)), 2, _p0, uintptr(_lenp0), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsethostname(_p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_sethostname)), 2, _p0, uintptr(_lenp0), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetpgid(pid int, pgid int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_setpgid)), 2, uintptr(pid), uintptr(pgid), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetsid() (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_setsid)), 0, 0, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsettimeofday(tv uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_settimeofday)), 1, tv, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetuid(uid int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_setuid)), 1, uintptr(uid), 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetgid(uid int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_setgid)), 1, uintptr(uid), 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetpriority(which int, who int, prio int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_setpriority)), 3, uintptr(which), uintptr(who), uintptr(prio), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callstatx(dirfd int, _p0 uintptr, flags int, mask int, stat uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_statx)), 5, uintptr(dirfd), _p0, uintptr(flags), uintptr(mask), stat, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsync() (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_sync)), 0, 0, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calltimes(tms uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_times)), 1, tms, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callumask(mask int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_umask)), 1, uintptr(mask), 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calluname(buf uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_uname)), 1, buf, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callunlink(_p0 uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_unlink)), 1, _p0, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callunlinkat(dirfd int, _p0 uintptr, flags int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_unlinkat)), 3, uintptr(dirfd), _p0, uintptr(flags), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callustat(dev int, ubuf uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_ustat)), 2, uintptr(dev), ubuf, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callwrite(fd int, _p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_write)), 3, uintptr(fd), _p0, uintptr(_lenp0), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calldup2(oldfd int, newfd int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_dup2)), 2, uintptr(oldfd), uintptr(newfd), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callposix_fadvise64(fd int, offset int64, length int64, advice int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_posix_fadvise64)), 4, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfchown(fd int, uid int, gid int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fchown)), 3, uintptr(fd), uintptr(uid), uintptr(gid), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfstat(fd int, stat uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fstat)), 2, uintptr(fd), stat, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfstatat(dirfd int, _p0 uintptr, stat uintptr, flags int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fstatat)), 4, uintptr(dirfd), _p0, stat, uintptr(flags), 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfstatfs(fd int, buf uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fstatfs)), 2, uintptr(fd), buf, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callftruncate(fd int, length int64) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_ftruncate)), 2, uintptr(fd), uintptr(length), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetegid() (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_getegid)), 0, 0, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgeteuid() (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_geteuid)), 0, 0, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetgid() (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_getgid)), 0, 0, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetuid() (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_getuid)), 0, 0, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calllchown(_p0 uintptr, uid int, gid int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_lchown)), 3, _p0, uintptr(uid), uintptr(gid), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calllisten(s int, n int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_listen)), 2, uintptr(s), uintptr(n), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calllstat(_p0 uintptr, stat uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_lstat)), 2, _p0, stat, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callpause() (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_pause)), 0, 0, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callpread64(fd int, _p0 uintptr, _lenp0 int, offset int64) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_pread64)), 4, uintptr(fd), _p0, uintptr(_lenp0), uintptr(offset), 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callpwrite64(fd int, _p0 uintptr, _lenp0 int, offset int64) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_pwrite64)), 4, uintptr(fd), _p0, uintptr(_lenp0), uintptr(offset), 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callpselect(nfd int, r uintptr, w uintptr, e uintptr, timeout uintptr, sigmask uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_pselect)), 6, uintptr(nfd), r, w, e, timeout, sigmask)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetregid(rgid int, egid int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_setregid)), 2, uintptr(rgid), uintptr(egid), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetreuid(ruid int, euid int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_setreuid)), 2, uintptr(ruid), uintptr(euid), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callshutdown(fd int, how int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_shutdown)), 2, uintptr(fd), uintptr(how), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsplice(rfd int, roff uintptr, wfd int, woff uintptr, len int, flags int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_splice)), 6, uintptr(rfd), roff, uintptr(wfd), woff, uintptr(len), uintptr(flags))
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callstat(_p0 uintptr, stat uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_stat)), 2, _p0, stat, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callstatfs(_p0 uintptr, buf uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_statfs)), 2, _p0, buf, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calltruncate(_p0 uintptr, length int64) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_truncate)), 2, _p0, uintptr(length), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callbind(s int, addr uintptr, addrlen uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_bind)), 3, uintptr(s), addr, addrlen, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callconnect(s int, addr uintptr, addrlen uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_connect)), 3, uintptr(s), addr, addrlen, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetgroups(n int, list uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_getgroups)), 2, uintptr(n), list, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetgroups(n int, list uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_setgroups)), 2, uintptr(n), list, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetsockopt(s int, level int, name int, val uintptr, vallen uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_getsockopt)), 5, uintptr(s), uintptr(level), uintptr(name), val, vallen, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetsockopt(s int, level int, name int, val uintptr, vallen uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_setsockopt)), 5, uintptr(s), uintptr(level), uintptr(name), val, vallen, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsocket(domain int, typ int, proto int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_socket)), 3, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsocketpair(domain int, typ int, proto int, fd uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_socketpair)), 4, uintptr(domain), uintptr(typ), uintptr(proto), fd, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetpeername(fd int, rsa uintptr, addrlen uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_getpeername)), 3, uintptr(fd), rsa, addrlen, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetsockname(fd int, rsa uintptr, addrlen uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_getsockname)), 3, uintptr(fd), rsa, addrlen, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callrecvfrom(fd int, _p0 uintptr, _lenp0 int, flags int, from uintptr, fromlen uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_recvfrom)), 6, uintptr(fd), _p0, uintptr(_lenp0), uintptr(flags), from, fromlen)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsendto(s int, _p0 uintptr, _lenp0 int, flags int, to uintptr, addrlen uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_sendto)), 6, uintptr(s), _p0, uintptr(_lenp0), uintptr(flags), to, addrlen)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callrecvmsg(s int, msg uintptr, flags int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_recvmsg)), 3, uintptr(s), msg, uintptr(flags), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsendmsg(s int, msg uintptr, flags int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_sendmsg)), 3, uintptr(s), msg, uintptr(flags), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmunmap(addr uintptr, length uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_munmap)), 2, addr, length, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmadvise(_p0 uintptr, _lenp0 int, advice int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_madvise)), 3, _p0, uintptr(_lenp0), uintptr(advice), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmprotect(_p0 uintptr, _lenp0 int, prot int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_mprotect)), 3, _p0, uintptr(_lenp0), uintptr(prot), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmlock(_p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_mlock)), 2, _p0, uintptr(_lenp0), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmlockall(flags int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_mlockall)), 1, uintptr(flags), 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmsync(_p0 uintptr, _lenp0 int, flags int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_msync)), 3, _p0, uintptr(_lenp0), uintptr(flags), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmunlock(_p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_munlock)), 2, _p0, uintptr(_lenp0), 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmunlockall() (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_munlockall)), 0, 0, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callpipe(p uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_pipe)), 1, p, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callpoll(fds uintptr, nfds int, timeout int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_poll)), 3, fds, uintptr(nfds), uintptr(timeout), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgettimeofday(tv uintptr, tzp uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_gettimeofday)), 2, tv, tzp, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calltime(t uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_time)), 1, t, 0, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callutime(_p0 uintptr, buf uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_utime)), 2, _p0, buf, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetrlimit(resource int, rlim uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_getrlimit)), 2, uintptr(resource), rlim, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetrlimit(resource int, rlim uintptr) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_setrlimit)), 2, uintptr(resource), rlim, 0, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calllseek(fd int, offset int64, whence int) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_lseek)), 3, uintptr(fd), uintptr(offset), uintptr(whence), 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmmap64(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (r1 uintptr, e1 Errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_mmap64)), 6, addr, length, uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset))
+ return
+}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go
new file mode 100644
index 000000000..aef7c0e78
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go
@@ -0,0 +1,1042 @@
+// mksyscall_aix_ppc64.pl -aix -tags aix,ppc64 syscall_aix.go syscall_aix_ppc64.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build aix,ppc64
+// +build gccgo
+
+package unix
+
+/*
+#include
+int utimes(uintptr_t, uintptr_t);
+int utimensat(int, uintptr_t, uintptr_t, int);
+int getcwd(uintptr_t, size_t);
+int accept(int, uintptr_t, uintptr_t);
+int getdirent(int, uintptr_t, size_t);
+int wait4(int, uintptr_t, int, uintptr_t);
+int ioctl(int, int, uintptr_t);
+int fcntl(uintptr_t, int, uintptr_t);
+int acct(uintptr_t);
+int chdir(uintptr_t);
+int chroot(uintptr_t);
+int close(int);
+int dup(int);
+void exit(int);
+int faccessat(int, uintptr_t, unsigned int, int);
+int fchdir(int);
+int fchmod(int, unsigned int);
+int fchmodat(int, uintptr_t, unsigned int, int);
+int fchownat(int, uintptr_t, int, int, int);
+int fdatasync(int);
+int fsync(int);
+int getpgid(int);
+int getpgrp();
+int getpid();
+int getppid();
+int getpriority(int, int);
+int getrusage(int, uintptr_t);
+int getsid(int);
+int kill(int, int);
+int syslog(int, uintptr_t, size_t);
+int mkdir(int, uintptr_t, unsigned int);
+int mkdirat(int, uintptr_t, unsigned int);
+int mkfifo(uintptr_t, unsigned int);
+int mknod(uintptr_t, unsigned int, int);
+int mknodat(int, uintptr_t, unsigned int, int);
+int nanosleep(uintptr_t, uintptr_t);
+int open64(uintptr_t, int, unsigned int);
+int openat(int, uintptr_t, int, unsigned int);
+int read(int, uintptr_t, size_t);
+int readlink(uintptr_t, uintptr_t, size_t);
+int renameat(int, uintptr_t, int, uintptr_t);
+int setdomainname(uintptr_t, size_t);
+int sethostname(uintptr_t, size_t);
+int setpgid(int, int);
+int setsid();
+int settimeofday(uintptr_t);
+int setuid(int);
+int setgid(int);
+int setpriority(int, int, int);
+int statx(int, uintptr_t, int, int, uintptr_t);
+int sync();
+uintptr_t times(uintptr_t);
+int umask(int);
+int uname(uintptr_t);
+int unlink(uintptr_t);
+int unlinkat(int, uintptr_t, int);
+int ustat(int, uintptr_t);
+int write(int, uintptr_t, size_t);
+int dup2(int, int);
+int posix_fadvise64(int, long long, long long, int);
+int fchown(int, int, int);
+int fstat(int, uintptr_t);
+int fstatat(int, uintptr_t, uintptr_t, int);
+int fstatfs(int, uintptr_t);
+int ftruncate(int, long long);
+int getegid();
+int geteuid();
+int getgid();
+int getuid();
+int lchown(uintptr_t, int, int);
+int listen(int, int);
+int lstat(uintptr_t, uintptr_t);
+int pause();
+int pread64(int, uintptr_t, size_t, long long);
+int pwrite64(int, uintptr_t, size_t, long long);
+int pselect(int, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+int setregid(int, int);
+int setreuid(int, int);
+int shutdown(int, int);
+long long splice(int, uintptr_t, int, uintptr_t, int, int);
+int stat(uintptr_t, uintptr_t);
+int statfs(uintptr_t, uintptr_t);
+int truncate(uintptr_t, long long);
+int bind(int, uintptr_t, uintptr_t);
+int connect(int, uintptr_t, uintptr_t);
+int getgroups(int, uintptr_t);
+int setgroups(int, uintptr_t);
+int getsockopt(int, int, int, uintptr_t, uintptr_t);
+int setsockopt(int, int, int, uintptr_t, uintptr_t);
+int socket(int, int, int);
+int socketpair(int, int, int, uintptr_t);
+int getpeername(int, uintptr_t, uintptr_t);
+int getsockname(int, uintptr_t, uintptr_t);
+int recvfrom(int, uintptr_t, size_t, int, uintptr_t, uintptr_t);
+int sendto(int, uintptr_t, size_t, int, uintptr_t, uintptr_t);
+int recvmsg(int, uintptr_t, int);
+int sendmsg(int, uintptr_t, int);
+int munmap(uintptr_t, uintptr_t);
+int madvise(uintptr_t, size_t, int);
+int mprotect(uintptr_t, size_t, int);
+int mlock(uintptr_t, size_t);
+int mlockall(int);
+int msync(uintptr_t, size_t, int);
+int munlock(uintptr_t, size_t);
+int munlockall();
+int pipe(uintptr_t);
+int poll(uintptr_t, int, int);
+int gettimeofday(uintptr_t, uintptr_t);
+int time(uintptr_t);
+int utime(uintptr_t, uintptr_t);
+int getrlimit(int, uintptr_t);
+int setrlimit(int, uintptr_t);
+long long lseek(int, long long, int);
+uintptr_t mmap64(uintptr_t, uintptr_t, int, int, int, long long);
+
+*/
+import "C"
+import (
+ "syscall"
+)
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callutimes(_p0 uintptr, times uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.utimes(C.uintptr_t(_p0), C.uintptr_t(times)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callutimensat(dirfd int, _p0 uintptr, times uintptr, flag int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.utimensat(C.int(dirfd), C.uintptr_t(_p0), C.uintptr_t(times), C.int(flag)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetcwd(_p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getcwd(C.uintptr_t(_p0), C.size_t(_lenp0)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callaccept(s int, rsa uintptr, addrlen uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.accept(C.int(s), C.uintptr_t(rsa), C.uintptr_t(addrlen)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetdirent(fd int, _p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getdirent(C.int(fd), C.uintptr_t(_p0), C.size_t(_lenp0)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callwait4(pid int, status uintptr, options int, rusage uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.wait4(C.int(pid), C.uintptr_t(status), C.int(options), C.uintptr_t(rusage)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callioctl(fd int, req int, arg uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.ioctl(C.int(fd), C.int(req), C.uintptr_t(arg)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfcntl(fd uintptr, cmd int, arg uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.fcntl(C.uintptr_t(fd), C.int(cmd), C.uintptr_t(arg)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callacct(_p0 uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.acct(C.uintptr_t(_p0)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callchdir(_p0 uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.chdir(C.uintptr_t(_p0)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callchroot(_p0 uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.chroot(C.uintptr_t(_p0)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callclose(fd int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.close(C.int(fd)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calldup(oldfd int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.dup(C.int(oldfd)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callexit(code int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.exit(C.int(code)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfaccessat(dirfd int, _p0 uintptr, mode uint32, flags int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.faccessat(C.int(dirfd), C.uintptr_t(_p0), C.uint(mode), C.int(flags)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfchdir(fd int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.fchdir(C.int(fd)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfchmod(fd int, mode uint32) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.fchmod(C.int(fd), C.uint(mode)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfchmodat(dirfd int, _p0 uintptr, mode uint32, flags int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.fchmodat(C.int(dirfd), C.uintptr_t(_p0), C.uint(mode), C.int(flags)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfchownat(dirfd int, _p0 uintptr, uid int, gid int, flags int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.fchownat(C.int(dirfd), C.uintptr_t(_p0), C.int(uid), C.int(gid), C.int(flags)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfdatasync(fd int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.fdatasync(C.int(fd)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfsync(fd int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.fsync(C.int(fd)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetpgid(pid int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getpgid(C.int(pid)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetpgrp() (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getpgrp())
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetpid() (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getpid())
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetppid() (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getppid())
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetpriority(which int, who int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getpriority(C.int(which), C.int(who)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetrusage(who int, rusage uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getrusage(C.int(who), C.uintptr_t(rusage)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetsid(pid int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getsid(C.int(pid)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callkill(pid int, sig int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.kill(C.int(pid), C.int(sig)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsyslog(typ int, _p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.syslog(C.int(typ), C.uintptr_t(_p0), C.size_t(_lenp0)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmkdir(dirfd int, _p0 uintptr, mode uint32) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.mkdir(C.int(dirfd), C.uintptr_t(_p0), C.uint(mode)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmkdirat(dirfd int, _p0 uintptr, mode uint32) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.mkdirat(C.int(dirfd), C.uintptr_t(_p0), C.uint(mode)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmkfifo(_p0 uintptr, mode uint32) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.mkfifo(C.uintptr_t(_p0), C.uint(mode)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmknod(_p0 uintptr, mode uint32, dev int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.mknod(C.uintptr_t(_p0), C.uint(mode), C.int(dev)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmknodat(dirfd int, _p0 uintptr, mode uint32, dev int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.mknodat(C.int(dirfd), C.uintptr_t(_p0), C.uint(mode), C.int(dev)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callnanosleep(time uintptr, leftover uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.nanosleep(C.uintptr_t(time), C.uintptr_t(leftover)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callopen64(_p0 uintptr, mode int, perm uint32) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.open64(C.uintptr_t(_p0), C.int(mode), C.uint(perm)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callopenat(dirfd int, _p0 uintptr, flags int, mode uint32) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.openat(C.int(dirfd), C.uintptr_t(_p0), C.int(flags), C.uint(mode)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callread(fd int, _p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.read(C.int(fd), C.uintptr_t(_p0), C.size_t(_lenp0)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callreadlink(_p0 uintptr, _p1 uintptr, _lenp1 int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.readlink(C.uintptr_t(_p0), C.uintptr_t(_p1), C.size_t(_lenp1)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callrenameat(olddirfd int, _p0 uintptr, newdirfd int, _p1 uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.renameat(C.int(olddirfd), C.uintptr_t(_p0), C.int(newdirfd), C.uintptr_t(_p1)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetdomainname(_p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.setdomainname(C.uintptr_t(_p0), C.size_t(_lenp0)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsethostname(_p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.sethostname(C.uintptr_t(_p0), C.size_t(_lenp0)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetpgid(pid int, pgid int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.setpgid(C.int(pid), C.int(pgid)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetsid() (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.setsid())
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsettimeofday(tv uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.settimeofday(C.uintptr_t(tv)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetuid(uid int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.setuid(C.int(uid)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetgid(uid int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.setgid(C.int(uid)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetpriority(which int, who int, prio int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.setpriority(C.int(which), C.int(who), C.int(prio)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callstatx(dirfd int, _p0 uintptr, flags int, mask int, stat uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.statx(C.int(dirfd), C.uintptr_t(_p0), C.int(flags), C.int(mask), C.uintptr_t(stat)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsync() (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.sync())
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calltimes(tms uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.times(C.uintptr_t(tms)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callumask(mask int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.umask(C.int(mask)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calluname(buf uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.uname(C.uintptr_t(buf)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callunlink(_p0 uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.unlink(C.uintptr_t(_p0)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callunlinkat(dirfd int, _p0 uintptr, flags int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.unlinkat(C.int(dirfd), C.uintptr_t(_p0), C.int(flags)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callustat(dev int, ubuf uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.ustat(C.int(dev), C.uintptr_t(ubuf)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callwrite(fd int, _p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.write(C.int(fd), C.uintptr_t(_p0), C.size_t(_lenp0)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calldup2(oldfd int, newfd int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.dup2(C.int(oldfd), C.int(newfd)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callposix_fadvise64(fd int, offset int64, length int64, advice int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.posix_fadvise64(C.int(fd), C.longlong(offset), C.longlong(length), C.int(advice)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfchown(fd int, uid int, gid int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.fchown(C.int(fd), C.int(uid), C.int(gid)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfstat(fd int, stat uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.fstat(C.int(fd), C.uintptr_t(stat)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfstatat(dirfd int, _p0 uintptr, stat uintptr, flags int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.fstatat(C.int(dirfd), C.uintptr_t(_p0), C.uintptr_t(stat), C.int(flags)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callfstatfs(fd int, buf uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.fstatfs(C.int(fd), C.uintptr_t(buf)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callftruncate(fd int, length int64) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.ftruncate(C.int(fd), C.longlong(length)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetegid() (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getegid())
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgeteuid() (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.geteuid())
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetgid() (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getgid())
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetuid() (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getuid())
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calllchown(_p0 uintptr, uid int, gid int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.lchown(C.uintptr_t(_p0), C.int(uid), C.int(gid)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calllisten(s int, n int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.listen(C.int(s), C.int(n)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calllstat(_p0 uintptr, stat uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.lstat(C.uintptr_t(_p0), C.uintptr_t(stat)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callpause() (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.pause())
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callpread64(fd int, _p0 uintptr, _lenp0 int, offset int64) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.pread64(C.int(fd), C.uintptr_t(_p0), C.size_t(_lenp0), C.longlong(offset)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callpwrite64(fd int, _p0 uintptr, _lenp0 int, offset int64) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.pwrite64(C.int(fd), C.uintptr_t(_p0), C.size_t(_lenp0), C.longlong(offset)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callpselect(nfd int, r uintptr, w uintptr, e uintptr, timeout uintptr, sigmask uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.pselect(C.int(nfd), C.uintptr_t(r), C.uintptr_t(w), C.uintptr_t(e), C.uintptr_t(timeout), C.uintptr_t(sigmask)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetregid(rgid int, egid int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.setregid(C.int(rgid), C.int(egid)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetreuid(ruid int, euid int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.setreuid(C.int(ruid), C.int(euid)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callshutdown(fd int, how int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.shutdown(C.int(fd), C.int(how)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsplice(rfd int, roff uintptr, wfd int, woff uintptr, len int, flags int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.splice(C.int(rfd), C.uintptr_t(roff), C.int(wfd), C.uintptr_t(woff), C.int(len), C.int(flags)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callstat(_p0 uintptr, stat uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.stat(C.uintptr_t(_p0), C.uintptr_t(stat)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callstatfs(_p0 uintptr, buf uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.statfs(C.uintptr_t(_p0), C.uintptr_t(buf)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calltruncate(_p0 uintptr, length int64) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.truncate(C.uintptr_t(_p0), C.longlong(length)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callbind(s int, addr uintptr, addrlen uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.bind(C.int(s), C.uintptr_t(addr), C.uintptr_t(addrlen)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callconnect(s int, addr uintptr, addrlen uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.connect(C.int(s), C.uintptr_t(addr), C.uintptr_t(addrlen)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetgroups(n int, list uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getgroups(C.int(n), C.uintptr_t(list)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetgroups(n int, list uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.setgroups(C.int(n), C.uintptr_t(list)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetsockopt(s int, level int, name int, val uintptr, vallen uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getsockopt(C.int(s), C.int(level), C.int(name), C.uintptr_t(val), C.uintptr_t(vallen)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetsockopt(s int, level int, name int, val uintptr, vallen uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.setsockopt(C.int(s), C.int(level), C.int(name), C.uintptr_t(val), C.uintptr_t(vallen)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsocket(domain int, typ int, proto int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.socket(C.int(domain), C.int(typ), C.int(proto)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsocketpair(domain int, typ int, proto int, fd uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.socketpair(C.int(domain), C.int(typ), C.int(proto), C.uintptr_t(fd)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetpeername(fd int, rsa uintptr, addrlen uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getpeername(C.int(fd), C.uintptr_t(rsa), C.uintptr_t(addrlen)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetsockname(fd int, rsa uintptr, addrlen uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getsockname(C.int(fd), C.uintptr_t(rsa), C.uintptr_t(addrlen)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callrecvfrom(fd int, _p0 uintptr, _lenp0 int, flags int, from uintptr, fromlen uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.recvfrom(C.int(fd), C.uintptr_t(_p0), C.size_t(_lenp0), C.int(flags), C.uintptr_t(from), C.uintptr_t(fromlen)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsendto(s int, _p0 uintptr, _lenp0 int, flags int, to uintptr, addrlen uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.sendto(C.int(s), C.uintptr_t(_p0), C.size_t(_lenp0), C.int(flags), C.uintptr_t(to), C.uintptr_t(addrlen)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callrecvmsg(s int, msg uintptr, flags int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.recvmsg(C.int(s), C.uintptr_t(msg), C.int(flags)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsendmsg(s int, msg uintptr, flags int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.sendmsg(C.int(s), C.uintptr_t(msg), C.int(flags)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmunmap(addr uintptr, length uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.munmap(C.uintptr_t(addr), C.uintptr_t(length)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmadvise(_p0 uintptr, _lenp0 int, advice int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.madvise(C.uintptr_t(_p0), C.size_t(_lenp0), C.int(advice)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmprotect(_p0 uintptr, _lenp0 int, prot int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.mprotect(C.uintptr_t(_p0), C.size_t(_lenp0), C.int(prot)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmlock(_p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.mlock(C.uintptr_t(_p0), C.size_t(_lenp0)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmlockall(flags int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.mlockall(C.int(flags)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmsync(_p0 uintptr, _lenp0 int, flags int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.msync(C.uintptr_t(_p0), C.size_t(_lenp0), C.int(flags)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmunlock(_p0 uintptr, _lenp0 int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.munlock(C.uintptr_t(_p0), C.size_t(_lenp0)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmunlockall() (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.munlockall())
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callpipe(p uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.pipe(C.uintptr_t(p)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callpoll(fds uintptr, nfds int, timeout int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.poll(C.uintptr_t(fds), C.int(nfds), C.int(timeout)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgettimeofday(tv uintptr, tzp uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.gettimeofday(C.uintptr_t(tv), C.uintptr_t(tzp)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calltime(t uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.time(C.uintptr_t(t)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callutime(_p0 uintptr, buf uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.utime(C.uintptr_t(_p0), C.uintptr_t(buf)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callgetrlimit(resource int, rlim uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.getrlimit(C.int(resource), C.uintptr_t(rlim)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callsetrlimit(resource int, rlim uintptr) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.setrlimit(C.int(resource), C.uintptr_t(rlim)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func calllseek(fd int, offset int64, whence int) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.lseek(C.int(fd), C.longlong(offset), C.int(whence)))
+ e1 = syscall.GetErrno()
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func callmmap64(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (r1 uintptr, e1 Errno) {
+ r1 = uintptr(C.mmap64(C.uintptr_t(addr), C.uintptr_t(length), C.int(prot), C.int(flags), C.int(fd), C.longlong(offset)))
+ e1 = syscall.GetErrno()
+ return
+}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go
index 91f36e9ec..12da7b41f 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go
@@ -1023,6 +1023,22 @@ func Open(path string, mode int, perm uint32) (fd int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Pathconf(path string, name int) (val int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go
index ad77882b8..9bbbf9662 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go
@@ -912,7 +912,7 @@ func Fpathconf(fd int, name int) (val int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Fstat(fd int, stat *Stat_t) (err error) {
+func fstat(fd int, stat *stat_freebsd11_t) (err error) {
_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
if e1 != 0 {
err = errnoErr(e1)
@@ -922,7 +922,17 @@ func Fstat(fd int, stat *Stat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
+func fstat_freebsd12(fd int, stat *Stat_t) (err error) {
+ _, _, e1 := Syscall(SYS_FSTAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -937,7 +947,22 @@ func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Fstatfs(fd int, stat *Statfs_t) (err error) {
+func fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_FSTATAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fstatfs(fd int, stat *statfs_freebsd11_t) (err error) {
_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
if e1 != 0 {
err = errnoErr(e1)
@@ -947,6 +972,16 @@ func Fstatfs(fd int, stat *Statfs_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func fstatfs_freebsd12(fd int, stat *Statfs_t) (err error) {
+ _, _, e1 := Syscall(SYS_FSTATFS_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Fsync(fd int) (err error) {
_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
if e1 != 0 {
@@ -967,14 +1002,14 @@ func Ftruncate(fd int, length int64) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Getdents(fd int, buf []byte) (n int, err error) {
+func getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
- r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+ r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
@@ -984,14 +1019,14 @@ func Getdents(fd int, buf []byte) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+func getdirentries_freebsd12(fd int, buf []byte, basep *uintptr) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
- r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+ r0, _, e1 := Syscall6(SYS_GETDIRENTRIES_FREEBSD12, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
@@ -1222,7 +1257,7 @@ func Listen(s int, backlog int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Lstat(path string, stat *Stat_t) (err error) {
+func lstat(path string, stat *stat_freebsd11_t) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -1282,7 +1317,7 @@ func Mkfifo(path string, mode uint32) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Mknod(path string, mode uint32, dev int) (err error) {
+func mknod(path string, mode uint32, dev int) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -1297,6 +1332,36 @@ func Mknod(path string, mode uint32, dev int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func mknodat(fd int, path string, mode uint32, dev int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_MKNODAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
if e1 != 0 {
@@ -1687,7 +1752,7 @@ func Setuid(uid int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Stat(path string, stat *Stat_t) (err error) {
+func stat(path string, stat *stat_freebsd11_t) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -1702,7 +1767,7 @@ func Stat(path string, stat *Stat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Statfs(path string, stat *Statfs_t) (err error) {
+func statfs(path string, stat *statfs_freebsd11_t) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -1717,6 +1782,21 @@ func Statfs(path string, stat *Statfs_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func statfs_freebsd12(path string, stat *Statfs_t) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_STATFS_FREEBSD12, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Symlink(path string, link string) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go
index d3ba6c46f..ee7090ff4 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go
@@ -912,7 +912,7 @@ func Fpathconf(fd int, name int) (val int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Fstat(fd int, stat *Stat_t) (err error) {
+func fstat(fd int, stat *stat_freebsd11_t) (err error) {
_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
if e1 != 0 {
err = errnoErr(e1)
@@ -922,7 +922,17 @@ func Fstat(fd int, stat *Stat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
+func fstat_freebsd12(fd int, stat *Stat_t) (err error) {
+ _, _, e1 := Syscall(SYS_FSTAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -937,7 +947,22 @@ func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Fstatfs(fd int, stat *Statfs_t) (err error) {
+func fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_FSTATAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fstatfs(fd int, stat *statfs_freebsd11_t) (err error) {
_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
if e1 != 0 {
err = errnoErr(e1)
@@ -947,6 +972,16 @@ func Fstatfs(fd int, stat *Statfs_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func fstatfs_freebsd12(fd int, stat *Statfs_t) (err error) {
+ _, _, e1 := Syscall(SYS_FSTATFS_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Fsync(fd int) (err error) {
_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
if e1 != 0 {
@@ -967,14 +1002,14 @@ func Ftruncate(fd int, length int64) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Getdents(fd int, buf []byte) (n int, err error) {
+func getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
- r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+ r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
@@ -984,14 +1019,14 @@ func Getdents(fd int, buf []byte) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+func getdirentries_freebsd12(fd int, buf []byte, basep *uintptr) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
- r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+ r0, _, e1 := Syscall6(SYS_GETDIRENTRIES_FREEBSD12, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
@@ -1222,7 +1257,7 @@ func Listen(s int, backlog int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Lstat(path string, stat *Stat_t) (err error) {
+func lstat(path string, stat *stat_freebsd11_t) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -1282,7 +1317,7 @@ func Mkfifo(path string, mode uint32) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Mknod(path string, mode uint32, dev int) (err error) {
+func mknod(path string, mode uint32, dev int) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -1297,6 +1332,36 @@ func Mknod(path string, mode uint32, dev int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func mknodat(fd int, path string, mode uint32, dev int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_MKNODAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
if e1 != 0 {
@@ -1687,7 +1752,7 @@ func Setuid(uid int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Stat(path string, stat *Stat_t) (err error) {
+func stat(path string, stat *stat_freebsd11_t) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -1702,7 +1767,7 @@ func Stat(path string, stat *Stat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Statfs(path string, stat *Statfs_t) (err error) {
+func statfs(path string, stat *statfs_freebsd11_t) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -1717,6 +1782,21 @@ func Statfs(path string, stat *Statfs_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func statfs_freebsd12(path string, stat *Statfs_t) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_STATFS_FREEBSD12, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Symlink(path string, link string) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go
index 9dfd77b62..9aeff5131 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go
@@ -912,7 +912,7 @@ func Fpathconf(fd int, name int) (val int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Fstat(fd int, stat *Stat_t) (err error) {
+func fstat(fd int, stat *stat_freebsd11_t) (err error) {
_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
if e1 != 0 {
err = errnoErr(e1)
@@ -922,7 +922,17 @@ func Fstat(fd int, stat *Stat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
+func fstat_freebsd12(fd int, stat *Stat_t) (err error) {
+ _, _, e1 := Syscall(SYS_FSTAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -937,7 +947,22 @@ func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Fstatfs(fd int, stat *Statfs_t) (err error) {
+func fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_FSTATAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fstatfs(fd int, stat *statfs_freebsd11_t) (err error) {
_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
if e1 != 0 {
err = errnoErr(e1)
@@ -947,6 +972,16 @@ func Fstatfs(fd int, stat *Statfs_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func fstatfs_freebsd12(fd int, stat *Statfs_t) (err error) {
+ _, _, e1 := Syscall(SYS_FSTATFS_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Fsync(fd int) (err error) {
_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
if e1 != 0 {
@@ -967,14 +1002,14 @@ func Ftruncate(fd int, length int64) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Getdents(fd int, buf []byte) (n int, err error) {
+func getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
- r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+ r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
@@ -984,14 +1019,14 @@ func Getdents(fd int, buf []byte) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+func getdirentries_freebsd12(fd int, buf []byte, basep *uintptr) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
- r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+ r0, _, e1 := Syscall6(SYS_GETDIRENTRIES_FREEBSD12, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
@@ -1222,7 +1257,7 @@ func Listen(s int, backlog int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Lstat(path string, stat *Stat_t) (err error) {
+func lstat(path string, stat *stat_freebsd11_t) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -1282,7 +1317,7 @@ func Mkfifo(path string, mode uint32) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Mknod(path string, mode uint32, dev int) (err error) {
+func mknod(path string, mode uint32, dev int) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -1297,6 +1332,36 @@ func Mknod(path string, mode uint32, dev int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func mknodat(fd int, path string, mode uint32, dev int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_MKNODAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
if e1 != 0 {
@@ -1687,7 +1752,7 @@ func Setuid(uid int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Stat(path string, stat *Stat_t) (err error) {
+func stat(path string, stat *stat_freebsd11_t) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -1702,7 +1767,7 @@ func Stat(path string, stat *Stat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func Statfs(path string, stat *Statfs_t) (err error) {
+func statfs(path string, stat *statfs_freebsd11_t) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -1717,6 +1782,21 @@ func Statfs(path string, stat *Statfs_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func statfs_freebsd12(path string, stat *Statfs_t) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_STATFS_FREEBSD12, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Symlink(path string, link string) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
index 35b155a02..cd94680d1 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
@@ -458,6 +458,21 @@ func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags in
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func DeleteModule(name string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_DELETE_MODULE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Dup(oldfd int) (fd int, err error) {
r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0)
fd = int(r0)
@@ -606,6 +621,21 @@ func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func FinitModule(fd int, params string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FINIT_MODULE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Flistxattr(fd int, dest []byte) (sz int, err error) {
var _p0 unsafe.Pointer
if len(dest) > 0 {
@@ -807,6 +837,27 @@ func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func InitModule(moduleImage []byte, params string) (err error) {
+ var _p0 unsafe.Pointer
+ if len(moduleImage) > 0 {
+ _p0 = unsafe.Pointer(&moduleImage[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_INIT_MODULE, uintptr(_p0), uintptr(len(moduleImage)), uintptr(unsafe.Pointer(_p1)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(pathname)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
index 46e9ddfb5..96e9df7da 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
@@ -458,6 +458,21 @@ func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags in
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func DeleteModule(name string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_DELETE_MODULE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Dup(oldfd int) (fd int, err error) {
r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0)
fd = int(r0)
@@ -606,6 +621,21 @@ func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func FinitModule(fd int, params string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FINIT_MODULE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Flistxattr(fd int, dest []byte) (sz int, err error) {
var _p0 unsafe.Pointer
if len(dest) > 0 {
@@ -807,6 +837,27 @@ func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func InitModule(moduleImage []byte, params string) (err error) {
+ var _p0 unsafe.Pointer
+ if len(moduleImage) > 0 {
+ _p0 = unsafe.Pointer(&moduleImage[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_INIT_MODULE, uintptr(_p0), uintptr(len(moduleImage)), uintptr(unsafe.Pointer(_p1)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(pathname)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
index 914f25f06..e8d82d14c 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
@@ -458,6 +458,21 @@ func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags in
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func DeleteModule(name string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_DELETE_MODULE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Dup(oldfd int) (fd int, err error) {
r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0)
fd = int(r0)
@@ -606,6 +621,21 @@ func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func FinitModule(fd int, params string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FINIT_MODULE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Flistxattr(fd int, dest []byte) (sz int, err error) {
var _p0 unsafe.Pointer
if len(dest) > 0 {
@@ -807,6 +837,27 @@ func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func InitModule(moduleImage []byte, params string) (err error) {
+ var _p0 unsafe.Pointer
+ if len(moduleImage) > 0 {
+ _p0 = unsafe.Pointer(&moduleImage[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_INIT_MODULE, uintptr(_p0), uintptr(len(moduleImage)), uintptr(unsafe.Pointer(_p1)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(pathname)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
index 1d6c55628..41f2d0cf0 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
@@ -458,6 +458,21 @@ func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags in
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func DeleteModule(name string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_DELETE_MODULE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Dup(oldfd int) (fd int, err error) {
r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0)
fd = int(r0)
@@ -606,6 +621,21 @@ func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func FinitModule(fd int, params string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FINIT_MODULE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Flistxattr(fd int, dest []byte) (sz int, err error) {
var _p0 unsafe.Pointer
if len(dest) > 0 {
@@ -807,6 +837,27 @@ func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func InitModule(moduleImage []byte, params string) (err error) {
+ var _p0 unsafe.Pointer
+ if len(moduleImage) > 0 {
+ _p0 = unsafe.Pointer(&moduleImage[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_INIT_MODULE, uintptr(_p0), uintptr(len(moduleImage)), uintptr(unsafe.Pointer(_p1)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(pathname)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go
index 260631d14..7e65fe0b7 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go
@@ -458,6 +458,21 @@ func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags in
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func DeleteModule(name string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_DELETE_MODULE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Dup(oldfd int) (fd int, err error) {
r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0)
fd = int(r0)
@@ -606,6 +621,21 @@ func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func FinitModule(fd int, params string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FINIT_MODULE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Flistxattr(fd int, dest []byte) (sz int, err error) {
var _p0 unsafe.Pointer
if len(dest) > 0 {
@@ -807,6 +837,27 @@ func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func InitModule(moduleImage []byte, params string) (err error) {
+ var _p0 unsafe.Pointer
+ if len(moduleImage) > 0 {
+ _p0 = unsafe.Pointer(&moduleImage[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_INIT_MODULE, uintptr(_p0), uintptr(len(moduleImage)), uintptr(unsafe.Pointer(_p1)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(pathname)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go
index ff2d84fb9..fd06fb890 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go
@@ -458,6 +458,21 @@ func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags in
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func DeleteModule(name string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_DELETE_MODULE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Dup(oldfd int) (fd int, err error) {
r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0)
fd = int(r0)
@@ -606,6 +621,21 @@ func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func FinitModule(fd int, params string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FINIT_MODULE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Flistxattr(fd int, dest []byte) (sz int, err error) {
var _p0 unsafe.Pointer
if len(dest) > 0 {
@@ -807,6 +837,27 @@ func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func InitModule(moduleImage []byte, params string) (err error) {
+ var _p0 unsafe.Pointer
+ if len(moduleImage) > 0 {
+ _p0 = unsafe.Pointer(&moduleImage[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_INIT_MODULE, uintptr(_p0), uintptr(len(moduleImage)), uintptr(unsafe.Pointer(_p1)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(pathname)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go
index 48d14e607..9e8ec28c9 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go
@@ -458,6 +458,21 @@ func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags in
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func DeleteModule(name string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_DELETE_MODULE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Dup(oldfd int) (fd int, err error) {
r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0)
fd = int(r0)
@@ -606,6 +621,21 @@ func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func FinitModule(fd int, params string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FINIT_MODULE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Flistxattr(fd int, dest []byte) (sz int, err error) {
var _p0 unsafe.Pointer
if len(dest) > 0 {
@@ -807,6 +837,27 @@ func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func InitModule(moduleImage []byte, params string) (err error) {
+ var _p0 unsafe.Pointer
+ if len(moduleImage) > 0 {
+ _p0 = unsafe.Pointer(&moduleImage[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_INIT_MODULE, uintptr(_p0), uintptr(len(moduleImage)), uintptr(unsafe.Pointer(_p1)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(pathname)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go
index 12c17a92b..b4d2ccbb0 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go
@@ -458,6 +458,21 @@ func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags in
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func DeleteModule(name string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_DELETE_MODULE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Dup(oldfd int) (fd int, err error) {
r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0)
fd = int(r0)
@@ -606,6 +621,21 @@ func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func FinitModule(fd int, params string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FINIT_MODULE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Flistxattr(fd int, dest []byte) (sz int, err error) {
var _p0 unsafe.Pointer
if len(dest) > 0 {
@@ -807,6 +837,27 @@ func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func InitModule(moduleImage []byte, params string) (err error) {
+ var _p0 unsafe.Pointer
+ if len(moduleImage) > 0 {
+ _p0 = unsafe.Pointer(&moduleImage[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_INIT_MODULE, uintptr(_p0), uintptr(len(moduleImage)), uintptr(unsafe.Pointer(_p1)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(pathname)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
index c8ca4279e..bca3d2536 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
@@ -458,6 +458,21 @@ func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags in
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func DeleteModule(name string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_DELETE_MODULE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Dup(oldfd int) (fd int, err error) {
r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0)
fd = int(r0)
@@ -606,6 +621,21 @@ func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func FinitModule(fd int, params string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FINIT_MODULE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Flistxattr(fd int, dest []byte) (sz int, err error) {
var _p0 unsafe.Pointer
if len(dest) > 0 {
@@ -807,6 +837,27 @@ func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func InitModule(moduleImage []byte, params string) (err error) {
+ var _p0 unsafe.Pointer
+ if len(moduleImage) > 0 {
+ _p0 = unsafe.Pointer(&moduleImage[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_INIT_MODULE, uintptr(_p0), uintptr(len(moduleImage)), uintptr(unsafe.Pointer(_p1)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(pathname)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
index 870c8f6db..e34089c66 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
@@ -458,6 +458,21 @@ func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags in
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func DeleteModule(name string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_DELETE_MODULE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Dup(oldfd int) (fd int, err error) {
r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0)
fd = int(r0)
@@ -606,6 +621,21 @@ func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func FinitModule(fd int, params string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FINIT_MODULE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Flistxattr(fd int, dest []byte) (sz int, err error) {
var _p0 unsafe.Pointer
if len(dest) > 0 {
@@ -807,6 +837,27 @@ func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func InitModule(moduleImage []byte, params string) (err error) {
+ var _p0 unsafe.Pointer
+ if len(moduleImage) > 0 {
+ _p0 = unsafe.Pointer(&moduleImage[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_INIT_MODULE, uintptr(_p0), uintptr(len(moduleImage)), uintptr(unsafe.Pointer(_p1)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(pathname)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go
index 542f3a3a3..312b2afaf 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go
@@ -458,6 +458,21 @@ func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags in
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func DeleteModule(name string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_DELETE_MODULE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Dup(oldfd int) (fd int, err error) {
r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0)
fd = int(r0)
@@ -606,6 +621,21 @@ func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func FinitModule(fd int, params string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FINIT_MODULE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Flistxattr(fd int, dest []byte) (sz int, err error) {
var _p0 unsafe.Pointer
if len(dest) > 0 {
@@ -807,6 +837,27 @@ func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func InitModule(moduleImage []byte, params string) (err error) {
+ var _p0 unsafe.Pointer
+ if len(moduleImage) > 0 {
+ _p0 = unsafe.Pointer(&moduleImage[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_INIT_MODULE, uintptr(_p0), uintptr(len(moduleImage)), uintptr(unsafe.Pointer(_p1)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(pathname)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go
index 55e79d640..04ec8befe 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go
@@ -458,6 +458,21 @@ func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags in
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func DeleteModule(name string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_DELETE_MODULE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Dup(oldfd int) (fd int, err error) {
r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0)
fd = int(r0)
@@ -606,6 +621,21 @@ func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func FinitModule(fd int, params string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FINIT_MODULE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Flistxattr(fd int, dest []byte) (sz int, err error) {
var _p0 unsafe.Pointer
if len(dest) > 0 {
@@ -807,6 +837,27 @@ func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func InitModule(moduleImage []byte, params string) (err error) {
+ var _p0 unsafe.Pointer
+ if len(moduleImage) > 0 {
+ _p0 = unsafe.Pointer(&moduleImage[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(params)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_INIT_MODULE, uintptr(_p0), uintptr(len(moduleImage)), uintptr(unsafe.Pointer(_p1)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(pathname)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go
index f1874d5a1..c0d856c55 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go
@@ -1210,6 +1210,22 @@ func Open(path string, mode int, perm uint32) (fd int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Pathconf(path string, name int) (val int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go
index eb8028397..1466a8ca1 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go
@@ -1210,6 +1210,22 @@ func Open(path string, mode int, perm uint32) (fd int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Pathconf(path string, name int) (val int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go
index 7b36499d5..2ca54f029 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go
@@ -1210,6 +1210,22 @@ func Open(path string, mode int, perm uint32) (fd int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Pathconf(path string, name int) (val int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go
index 1942049b0..082235681 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go
@@ -431,6 +431,17 @@ func ioctl(fd int, req uint, arg uintptr) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
+ r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Access(path string, mode uint32) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
@@ -1005,6 +1016,22 @@ func Open(path string, mode int, perm uint32) (fd int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Pathconf(path string, name int) (val int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go
index d351c72cb..3d0bae427 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go
@@ -431,6 +431,17 @@ func ioctl(fd int, req uint, arg uintptr) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
+ r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Access(path string, mode uint32) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
@@ -1005,6 +1016,22 @@ func Open(path string, mode int, perm uint32) (fd int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Pathconf(path string, name int) (val int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
index 617d47f0f..6422c4605 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
@@ -431,6 +431,17 @@ func ioctl(fd int, req uint, arg uintptr) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
+ r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Access(path string, mode uint32) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
@@ -1005,6 +1016,22 @@ func Open(path string, mode int, perm uint32) (fd int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func Pathconf(path string, name int) (val int, err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
index a1db143f8..6e281d6b3 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
@@ -360,4 +360,5 @@ const (
SYS_PKEY_FREE = 396
SYS_STATX = 397
SYS_RSEQ = 398
+ SYS_IO_PGETEVENTS = 399
)
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
index 2e4cee70d..f9157e192 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
@@ -284,4 +284,5 @@ const (
SYS_PKEY_FREE = 290
SYS_STATX = 291
SYS_IO_PGETEVENTS = 292
+ SYS_RSEQ = 293
)
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
index 41e4fd1d3..a5d991915 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
@@ -283,4 +283,5 @@ const (
SYS_PKEY_FREE = 290
SYS_STATX = 291
SYS_IO_PGETEVENTS = 292
+ SYS_RSEQ = 293
)
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go
index 07787301f..f93f391d2 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go
@@ -1,5 +1,5 @@
// mksysnum_openbsd.pl
-// Code generated by the command above; DO NOT EDIT.
+// Code generated by the command above; see README.md. DO NOT EDIT.
// +build 386,openbsd
@@ -12,6 +12,7 @@ const (
SYS_WRITE = 4 // { ssize_t sys_write(int fd, const void *buf, \
SYS_OPEN = 5 // { int sys_open(const char *path, \
SYS_CLOSE = 6 // { int sys_close(int fd); }
+ SYS_GETENTROPY = 7 // { int sys_getentropy(void *buf, size_t nbyte); }
SYS___TFORK = 8 // { int sys___tfork(const struct __tfork *param, \
SYS_LINK = 9 // { int sys_link(const char *path, const char *link); }
SYS_UNLINK = 10 // { int sys_unlink(const char *path); }
@@ -37,11 +38,10 @@ const (
SYS_ACCEPT = 30 // { int sys_accept(int s, struct sockaddr *name, \
SYS_GETPEERNAME = 31 // { int sys_getpeername(int fdes, struct sockaddr *asa, \
SYS_GETSOCKNAME = 32 // { int sys_getsockname(int fdes, struct sockaddr *asa, \
- SYS_ACCESS = 33 // { int sys_access(const char *path, int flags); }
+ SYS_ACCESS = 33 // { int sys_access(const char *path, int amode); }
SYS_CHFLAGS = 34 // { int sys_chflags(const char *path, u_int flags); }
SYS_FCHFLAGS = 35 // { int sys_fchflags(int fd, u_int flags); }
SYS_SYNC = 36 // { void sys_sync(void); }
- SYS_KILL = 37 // { int sys_kill(int pid, int signum); }
SYS_STAT = 38 // { int sys_stat(const char *path, struct stat *ub); }
SYS_GETPPID = 39 // { pid_t sys_getppid(void); }
SYS_LSTAT = 40 // { int sys_lstat(const char *path, struct stat *ub); }
@@ -53,7 +53,6 @@ const (
SYS_SIGACTION = 46 // { int sys_sigaction(int signum, \
SYS_GETGID = 47 // { gid_t sys_getgid(void); }
SYS_SIGPROCMASK = 48 // { int sys_sigprocmask(int how, sigset_t mask); }
- SYS_GETLOGIN = 49 // { int sys_getlogin(char *namebuf, u_int namelen); }
SYS_SETLOGIN = 50 // { int sys_setlogin(const char *namebuf); }
SYS_ACCT = 51 // { int sys_acct(const char *path); }
SYS_SIGPENDING = 52 // { int sys_sigpending(void); }
@@ -62,7 +61,7 @@ const (
SYS_REBOOT = 55 // { int sys_reboot(int opt); }
SYS_REVOKE = 56 // { int sys_revoke(const char *path); }
SYS_SYMLINK = 57 // { int sys_symlink(const char *path, \
- SYS_READLINK = 58 // { int sys_readlink(const char *path, char *buf, \
+ SYS_READLINK = 58 // { ssize_t sys_readlink(const char *path, \
SYS_EXECVE = 59 // { int sys_execve(const char *path, \
SYS_UMASK = 60 // { mode_t sys_umask(mode_t newmask); }
SYS_CHROOT = 61 // { int sys_chroot(const char *path); }
@@ -86,15 +85,18 @@ const (
SYS_GETGROUPS = 79 // { int sys_getgroups(int gidsetsize, \
SYS_SETGROUPS = 80 // { int sys_setgroups(int gidsetsize, \
SYS_GETPGRP = 81 // { int sys_getpgrp(void); }
- SYS_SETPGID = 82 // { int sys_setpgid(pid_t pid, int pgid); }
+ SYS_SETPGID = 82 // { int sys_setpgid(pid_t pid, pid_t pgid); }
+ SYS_FUTEX = 83 // { int sys_futex(uint32_t *f, int op, int val, \
SYS_UTIMENSAT = 84 // { int sys_utimensat(int fd, const char *path, \
SYS_FUTIMENS = 85 // { int sys_futimens(int fd, \
+ SYS_KBIND = 86 // { int sys_kbind(const struct __kbind *param, \
SYS_CLOCK_GETTIME = 87 // { int sys_clock_gettime(clockid_t clock_id, \
SYS_CLOCK_SETTIME = 88 // { int sys_clock_settime(clockid_t clock_id, \
SYS_CLOCK_GETRES = 89 // { int sys_clock_getres(clockid_t clock_id, \
SYS_DUP2 = 90 // { int sys_dup2(int from, int to); }
SYS_NANOSLEEP = 91 // { int sys_nanosleep(const struct timespec *rqtp, \
SYS_FCNTL = 92 // { int sys_fcntl(int fd, int cmd, ... void *arg); }
+ SYS_ACCEPT4 = 93 // { int sys_accept4(int s, struct sockaddr *name, \
SYS___THRSLEEP = 94 // { int sys___thrsleep(const volatile void *ident, \
SYS_FSYNC = 95 // { int sys_fsync(int fd); }
SYS_SETPRIORITY = 96 // { int sys_setpriority(int which, id_t who, int prio); }
@@ -102,16 +104,24 @@ const (
SYS_CONNECT = 98 // { int sys_connect(int s, const struct sockaddr *name, \
SYS_GETDENTS = 99 // { int sys_getdents(int fd, void *buf, size_t buflen); }
SYS_GETPRIORITY = 100 // { int sys_getpriority(int which, id_t who); }
+ SYS_PIPE2 = 101 // { int sys_pipe2(int *fdp, int flags); }
+ SYS_DUP3 = 102 // { int sys_dup3(int from, int to, int flags); }
SYS_SIGRETURN = 103 // { int sys_sigreturn(struct sigcontext *sigcntxp); }
SYS_BIND = 104 // { int sys_bind(int s, const struct sockaddr *name, \
SYS_SETSOCKOPT = 105 // { int sys_setsockopt(int s, int level, int name, \
SYS_LISTEN = 106 // { int sys_listen(int s, int backlog); }
+ SYS_CHFLAGSAT = 107 // { int sys_chflagsat(int fd, const char *path, \
+ SYS_PLEDGE = 108 // { int sys_pledge(const char *promises, \
SYS_PPOLL = 109 // { int sys_ppoll(struct pollfd *fds, \
SYS_PSELECT = 110 // { int sys_pselect(int nd, fd_set *in, fd_set *ou, \
SYS_SIGSUSPEND = 111 // { int sys_sigsuspend(int mask); }
+ SYS_SENDSYSLOG = 112 // { int sys_sendsyslog(const char *buf, size_t nbyte, \
+ SYS_UNVEIL = 114 // { int sys_unveil(const char *path, \
SYS_GETSOCKOPT = 118 // { int sys_getsockopt(int s, int level, int name, \
+ SYS_THRKILL = 119 // { int sys_thrkill(pid_t tid, int signum, void *tcb); }
SYS_READV = 120 // { ssize_t sys_readv(int fd, \
SYS_WRITEV = 121 // { ssize_t sys_writev(int fd, \
+ SYS_KILL = 122 // { int sys_kill(int pid, int signum); }
SYS_FCHOWN = 123 // { int sys_fchown(int fd, uid_t uid, gid_t gid); }
SYS_FCHMOD = 124 // { int sys_fchmod(int fd, mode_t mode); }
SYS_SETREUID = 126 // { int sys_setreuid(uid_t ruid, uid_t euid); }
@@ -125,6 +135,7 @@ const (
SYS_MKDIR = 136 // { int sys_mkdir(const char *path, mode_t mode); }
SYS_RMDIR = 137 // { int sys_rmdir(const char *path); }
SYS_ADJTIME = 140 // { int sys_adjtime(const struct timeval *delta, \
+ SYS_GETLOGIN_R = 141 // { int sys_getlogin_r(char *namebuf, u_int namelen); }
SYS_SETSID = 147 // { int sys_setsid(void); }
SYS_QUOTACTL = 148 // { int sys_quotactl(const char *path, int cmd, \
SYS_NFSSVC = 155 // { int sys_nfssvc(int flag, void *argp); }
@@ -144,7 +155,7 @@ const (
SYS_LSEEK = 199 // { off_t sys_lseek(int fd, int pad, off_t offset, \
SYS_TRUNCATE = 200 // { int sys_truncate(const char *path, int pad, \
SYS_FTRUNCATE = 201 // { int sys_ftruncate(int fd, int pad, off_t length); }
- SYS___SYSCTL = 202 // { int sys___sysctl(const int *name, u_int namelen, \
+ SYS_SYSCTL = 202 // { int sys_sysctl(const int *name, u_int namelen, \
SYS_MLOCK = 203 // { int sys_mlock(const void *addr, size_t len); }
SYS_MUNLOCK = 204 // { int sys_munlock(const void *addr, size_t len); }
SYS_GETPGID = 207 // { pid_t sys_getpgid(pid_t pid); }
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go
index 7a1693acb..be1198d91 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go
@@ -1,5 +1,5 @@
// mksysnum_openbsd.pl
-// Code generated by the command above; DO NOT EDIT.
+// Code generated by the command above; see README.md. DO NOT EDIT.
// +build arm,openbsd
@@ -53,7 +53,6 @@ const (
SYS_SIGACTION = 46 // { int sys_sigaction(int signum, \
SYS_GETGID = 47 // { gid_t sys_getgid(void); }
SYS_SIGPROCMASK = 48 // { int sys_sigprocmask(int how, sigset_t mask); }
- SYS_GETLOGIN = 49 // { int sys_getlogin(char *namebuf, u_int namelen); }
SYS_SETLOGIN = 50 // { int sys_setlogin(const char *namebuf); }
SYS_ACCT = 51 // { int sys_acct(const char *path); }
SYS_SIGPENDING = 52 // { int sys_sigpending(void); }
@@ -87,9 +86,10 @@ const (
SYS_SETGROUPS = 80 // { int sys_setgroups(int gidsetsize, \
SYS_GETPGRP = 81 // { int sys_getpgrp(void); }
SYS_SETPGID = 82 // { int sys_setpgid(pid_t pid, pid_t pgid); }
- SYS_SENDSYSLOG = 83 // { int sys_sendsyslog(const void *buf, size_t nbyte); }
+ SYS_FUTEX = 83 // { int sys_futex(uint32_t *f, int op, int val, \
SYS_UTIMENSAT = 84 // { int sys_utimensat(int fd, const char *path, \
SYS_FUTIMENS = 85 // { int sys_futimens(int fd, \
+ SYS_KBIND = 86 // { int sys_kbind(const struct __kbind *param, \
SYS_CLOCK_GETTIME = 87 // { int sys_clock_gettime(clockid_t clock_id, \
SYS_CLOCK_SETTIME = 88 // { int sys_clock_settime(clockid_t clock_id, \
SYS_CLOCK_GETRES = 89 // { int sys_clock_getres(clockid_t clock_id, \
@@ -111,10 +111,14 @@ const (
SYS_SETSOCKOPT = 105 // { int sys_setsockopt(int s, int level, int name, \
SYS_LISTEN = 106 // { int sys_listen(int s, int backlog); }
SYS_CHFLAGSAT = 107 // { int sys_chflagsat(int fd, const char *path, \
+ SYS_PLEDGE = 108 // { int sys_pledge(const char *promises, \
SYS_PPOLL = 109 // { int sys_ppoll(struct pollfd *fds, \
SYS_PSELECT = 110 // { int sys_pselect(int nd, fd_set *in, fd_set *ou, \
SYS_SIGSUSPEND = 111 // { int sys_sigsuspend(int mask); }
+ SYS_SENDSYSLOG = 112 // { int sys_sendsyslog(const char *buf, size_t nbyte, \
+ SYS_UNVEIL = 114 // { int sys_unveil(const char *path, \
SYS_GETSOCKOPT = 118 // { int sys_getsockopt(int s, int level, int name, \
+ SYS_THRKILL = 119 // { int sys_thrkill(pid_t tid, int signum, void *tcb); }
SYS_READV = 120 // { ssize_t sys_readv(int fd, \
SYS_WRITEV = 121 // { ssize_t sys_writev(int fd, \
SYS_KILL = 122 // { int sys_kill(int pid, int signum); }
@@ -131,6 +135,7 @@ const (
SYS_MKDIR = 136 // { int sys_mkdir(const char *path, mode_t mode); }
SYS_RMDIR = 137 // { int sys_rmdir(const char *path); }
SYS_ADJTIME = 140 // { int sys_adjtime(const struct timeval *delta, \
+ SYS_GETLOGIN_R = 141 // { int sys_getlogin_r(char *namebuf, u_int namelen); }
SYS_SETSID = 147 // { int sys_setsid(void); }
SYS_QUOTACTL = 148 // { int sys_quotactl(const char *path, int cmd, \
SYS_NFSSVC = 155 // { int sys_nfssvc(int flag, void *argp); }
@@ -150,7 +155,7 @@ const (
SYS_LSEEK = 199 // { off_t sys_lseek(int fd, int pad, off_t offset, \
SYS_TRUNCATE = 200 // { int sys_truncate(const char *path, int pad, \
SYS_FTRUNCATE = 201 // { int sys_ftruncate(int fd, int pad, off_t length); }
- SYS___SYSCTL = 202 // { int sys___sysctl(const int *name, u_int namelen, \
+ SYS_SYSCTL = 202 // { int sys_sysctl(const int *name, u_int namelen, \
SYS_MLOCK = 203 // { int sys_mlock(const void *addr, size_t len); }
SYS_MUNLOCK = 204 // { int sys_munlock(const void *addr, size_t len); }
SYS_GETPGID = 207 // { pid_t sys_getpgid(pid_t pid); }
diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go
index 11380294a..28ef5242f 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go
@@ -56,28 +56,84 @@ type Rlimit struct {
type _Gid_t uint32
+const (
+ _statfsVersion = 0x20140518
+ _dirblksiz = 0x400
+)
+
type Stat_t struct {
- Dev uint32
- Ino uint32
- Mode uint16
- Nlink uint16
- Uid uint32
- Gid uint32
- Rdev uint32
- Atimespec Timespec
- Mtimespec Timespec
- Ctimespec Timespec
- Size int64
- Blocks int64
- Blksize int32
- Flags uint32
- Gen uint32
- Lspare int32
- Birthtimespec Timespec
- Pad_cgo_0 [8]byte
+ Dev uint64
+ Ino uint64
+ Nlink uint64
+ Mode uint16
+ _0 int16
+ Uid uint32
+ Gid uint32
+ _1 int32
+ Rdev uint64
+ Atim_ext int32
+ Atim Timespec
+ Mtim_ext int32
+ Mtim Timespec
+ Ctim_ext int32
+ Ctim Timespec
+ Btim_ext int32
+ Birthtim Timespec
+ Size int64
+ Blocks int64
+ Blksize int32
+ Flags uint32
+ Gen uint64
+ Spare [10]uint64
+}
+
+type stat_freebsd11_t struct {
+ Dev uint32
+ Ino uint32
+ Mode uint16
+ Nlink uint16
+ Uid uint32
+ Gid uint32
+ Rdev uint32
+ Atim Timespec
+ Mtim Timespec
+ Ctim Timespec
+ Size int64
+ Blocks int64
+ Blksize int32
+ Flags uint32
+ Gen uint32
+ Lspare int32
+ Birthtim Timespec
+ _ [8]byte
}
type Statfs_t struct {
+ Version uint32
+ Type uint32
+ Flags uint64
+ Bsize uint64
+ Iosize uint64
+ Blocks uint64
+ Bfree uint64
+ Bavail int64
+ Files uint64
+ Ffree int64
+ Syncwrites uint64
+ Asyncwrites uint64
+ Syncreads uint64
+ Asyncreads uint64
+ Spare [10]uint64
+ Namemax uint32
+ Owner uint32
+ Fsid Fsid
+ Charspare [80]int8
+ Fstypename [16]int8
+ Mntfromname [1024]int8
+ Mntonname [1024]int8
+}
+
+type statfs_freebsd11_t struct {
Version uint32
Type uint32
Flags uint64
@@ -112,6 +168,17 @@ type Flock_t struct {
}
type Dirent struct {
+ Fileno uint64
+ Off int64
+ Reclen uint16
+ Type uint8
+ Pad0 uint8
+ Namlen uint16
+ Pad1 uint16
+ Name [256]int8
+}
+
+type dirent_freebsd11 struct {
Fileno uint32
Reclen uint16
Type uint8
@@ -272,7 +339,7 @@ type Kevent_t struct {
}
type FdSet struct {
- X__fds_bits [32]uint32
+ _ [32]uint32
}
const (
@@ -288,53 +355,53 @@ const (
)
type ifMsghdr struct {
- Msglen uint16
- Version uint8
- Type uint8
- Addrs int32
- Flags int32
- Index uint16
- Pad_cgo_0 [2]byte
- Data ifData
+ Msglen uint16
+ Version uint8
+ Type uint8
+ Addrs int32
+ Flags int32
+ Index uint16
+ _ [2]byte
+ Data ifData
}
type IfMsghdr struct {
- Msglen uint16
- Version uint8
- Type uint8
- Addrs int32
- Flags int32
- Index uint16
- Pad_cgo_0 [2]byte
- Data IfData
+ Msglen uint16
+ Version uint8
+ Type uint8
+ Addrs int32
+ Flags int32
+ Index uint16
+ _ [2]byte
+ Data IfData
}
type ifData struct {
- Type uint8
- Physical uint8
- Addrlen uint8
- Hdrlen uint8
- Link_state uint8
- Vhid uint8
- Datalen uint16
- Mtu uint32
- Metric uint32
- Baudrate uint64
- Ipackets uint64
- Ierrors uint64
- Opackets uint64
- Oerrors uint64
- Collisions uint64
- Ibytes uint64
- Obytes uint64
- Imcasts uint64
- Omcasts uint64
- Iqdrops uint64
- Oqdrops uint64
- Noproto uint64
- Hwassist uint64
- X__ifi_epoch [8]byte
- X__ifi_lastchange [16]byte
+ Type uint8
+ Physical uint8
+ Addrlen uint8
+ Hdrlen uint8
+ Link_state uint8
+ Vhid uint8
+ Datalen uint16
+ Mtu uint32
+ Metric uint32
+ Baudrate uint64
+ Ipackets uint64
+ Ierrors uint64
+ Opackets uint64
+ Oerrors uint64
+ Collisions uint64
+ Ibytes uint64
+ Obytes uint64
+ Imcasts uint64
+ Omcasts uint64
+ Iqdrops uint64
+ Oqdrops uint64
+ Noproto uint64
+ Hwassist uint64
+ _ [8]byte
+ _ [16]byte
}
type IfData struct {
@@ -366,24 +433,24 @@ type IfData struct {
}
type IfaMsghdr struct {
- Msglen uint16
- Version uint8
- Type uint8
- Addrs int32
- Flags int32
- Index uint16
- Pad_cgo_0 [2]byte
- Metric int32
+ Msglen uint16
+ Version uint8
+ Type uint8
+ Addrs int32
+ Flags int32
+ Index uint16
+ _ [2]byte
+ Metric int32
}
type IfmaMsghdr struct {
- Msglen uint16
- Version uint8
- Type uint8
- Addrs int32
- Flags int32
- Index uint16
- Pad_cgo_0 [2]byte
+ Msglen uint16
+ Version uint8
+ Type uint8
+ Addrs int32
+ Flags int32
+ Index uint16
+ _ [2]byte
}
type IfAnnounceMsghdr struct {
@@ -396,19 +463,19 @@ type IfAnnounceMsghdr struct {
}
type RtMsghdr struct {
- Msglen uint16
- Version uint8
- Type uint8
- Index uint16
- Pad_cgo_0 [2]byte
- Flags int32
- Addrs int32
- Pid int32
- Seq int32
- Errno int32
- Fmask int32
- Inits uint32
- Rmx RtMetrics
+ Msglen uint16
+ Version uint8
+ Type uint8
+ Index uint16
+ _ [2]byte
+ Flags int32
+ Addrs int32
+ Pid int32
+ Seq int32
+ Errno int32
+ Fmask int32
+ Inits uint32
+ Rmx RtMetrics
}
type RtMetrics struct {
@@ -465,18 +532,18 @@ type BpfInsn struct {
}
type BpfHdr struct {
- Tstamp Timeval
- Caplen uint32
- Datalen uint32
- Hdrlen uint16
- Pad_cgo_0 [2]byte
+ Tstamp Timeval
+ Caplen uint32
+ Datalen uint32
+ Hdrlen uint16
+ _ [2]byte
}
type BpfZbufHeader struct {
Kernel_gen uint32
Kernel_len uint32
User_gen uint32
- X_bzh_pad [5]uint32
+ _ [5]uint32
}
type Termios struct {
diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go
index a6fc12718..e2d984a48 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go
@@ -56,27 +56,79 @@ type Rlimit struct {
type _Gid_t uint32
+const (
+ _statfsVersion = 0x20140518
+ _dirblksiz = 0x400
+)
+
type Stat_t struct {
- Dev uint32
- Ino uint32
- Mode uint16
- Nlink uint16
- Uid uint32
- Gid uint32
- Rdev uint32
- Atimespec Timespec
- Mtimespec Timespec
- Ctimespec Timespec
- Size int64
- Blocks int64
- Blksize int32
- Flags uint32
- Gen uint32
- Lspare int32
- Birthtimespec Timespec
+ Dev uint64
+ Ino uint64
+ Nlink uint64
+ Mode uint16
+ _0 int16
+ Uid uint32
+ Gid uint32
+ _1 int32
+ Rdev uint64
+ Atim Timespec
+ Mtim Timespec
+ Ctim Timespec
+ Birthtim Timespec
+ Size int64
+ Blocks int64
+ Blksize int32
+ Flags uint32
+ Gen uint64
+ Spare [10]uint64
+}
+
+type stat_freebsd11_t struct {
+ Dev uint32
+ Ino uint32
+ Mode uint16
+ Nlink uint16
+ Uid uint32
+ Gid uint32
+ Rdev uint32
+ Atim Timespec
+ Mtim Timespec
+ Ctim Timespec
+ Size int64
+ Blocks int64
+ Blksize int32
+ Flags uint32
+ Gen uint32
+ Lspare int32
+ Birthtim Timespec
}
type Statfs_t struct {
+ Version uint32
+ Type uint32
+ Flags uint64
+ Bsize uint64
+ Iosize uint64
+ Blocks uint64
+ Bfree uint64
+ Bavail int64
+ Files uint64
+ Ffree int64
+ Syncwrites uint64
+ Asyncwrites uint64
+ Syncreads uint64
+ Asyncreads uint64
+ Spare [10]uint64
+ Namemax uint32
+ Owner uint32
+ Fsid Fsid
+ Charspare [80]int8
+ Fstypename [16]int8
+ Mntfromname [1024]int8
+ Mntonname [1024]int8
+}
+
+type statfs_freebsd11_t struct {
Version uint32
Type uint32
Flags uint64
@@ -102,16 +154,27 @@ type Statfs_t struct {
}
type Flock_t struct {
- Start int64
- Len int64
- Pid int32
- Type int16
- Whence int16
- Sysid int32
- Pad_cgo_0 [4]byte
+ Start int64
+ Len int64
+ Pid int32
+ Type int16
+ Whence int16
+ Sysid int32
+ _ [4]byte
}
type Dirent struct {
+ Fileno uint64
+ Off int64
+ Reclen uint16
+ Type uint8
+ Pad0 uint8
+ Namlen uint16
+ Pad1 uint16
+ Name [256]int8
+}
+
+type dirent_freebsd11 struct {
Fileno uint32
Reclen uint16
Type uint8
@@ -212,10 +275,10 @@ type IPv6Mreq struct {
type Msghdr struct {
Name *byte
Namelen uint32
- Pad_cgo_0 [4]byte
+ _ [4]byte
Iov *Iovec
Iovlen int32
- Pad_cgo_1 [4]byte
+ _ [4]byte
Control *byte
Controllen uint32
Flags int32
@@ -274,7 +337,7 @@ type Kevent_t struct {
}
type FdSet struct {
- X__fds_bits [16]uint64
+ _ [16]uint64
}
const (
@@ -290,53 +353,53 @@ const (
)
type ifMsghdr struct {
- Msglen uint16
- Version uint8
- Type uint8
- Addrs int32
- Flags int32
- Index uint16
- Pad_cgo_0 [2]byte
- Data ifData
+ Msglen uint16
+ Version uint8
+ Type uint8
+ Addrs int32
+ Flags int32
+ Index uint16
+ _ [2]byte
+ Data ifData
}
type IfMsghdr struct {
- Msglen uint16
- Version uint8
- Type uint8
- Addrs int32
- Flags int32
- Index uint16
- Pad_cgo_0 [2]byte
- Data IfData
+ Msglen uint16
+ Version uint8
+ Type uint8
+ Addrs int32
+ Flags int32
+ Index uint16
+ _ [2]byte
+ Data IfData
}
type ifData struct {
- Type uint8
- Physical uint8
- Addrlen uint8
- Hdrlen uint8
- Link_state uint8
- Vhid uint8
- Datalen uint16
- Mtu uint32
- Metric uint32
- Baudrate uint64
- Ipackets uint64
- Ierrors uint64
- Opackets uint64
- Oerrors uint64
- Collisions uint64
- Ibytes uint64
- Obytes uint64
- Imcasts uint64
- Omcasts uint64
- Iqdrops uint64
- Oqdrops uint64
- Noproto uint64
- Hwassist uint64
- X__ifi_epoch [8]byte
- X__ifi_lastchange [16]byte
+ Type uint8
+ Physical uint8
+ Addrlen uint8
+ Hdrlen uint8
+ Link_state uint8
+ Vhid uint8
+ Datalen uint16
+ Mtu uint32
+ Metric uint32
+ Baudrate uint64
+ Ipackets uint64
+ Ierrors uint64
+ Opackets uint64
+ Oerrors uint64
+ Collisions uint64
+ Ibytes uint64
+ Obytes uint64
+ Imcasts uint64
+ Omcasts uint64
+ Iqdrops uint64
+ Oqdrops uint64
+ Noproto uint64
+ Hwassist uint64
+ _ [8]byte
+ _ [16]byte
}
type IfData struct {
@@ -368,24 +431,24 @@ type IfData struct {
}
type IfaMsghdr struct {
- Msglen uint16
- Version uint8
- Type uint8
- Addrs int32
- Flags int32
- Index uint16
- Pad_cgo_0 [2]byte
- Metric int32
+ Msglen uint16
+ Version uint8
+ Type uint8
+ Addrs int32
+ Flags int32
+ Index uint16
+ _ [2]byte
+ Metric int32
}
type IfmaMsghdr struct {
- Msglen uint16
- Version uint8
- Type uint8
- Addrs int32
- Flags int32
- Index uint16
- Pad_cgo_0 [2]byte
+ Msglen uint16
+ Version uint8
+ Type uint8
+ Addrs int32
+ Flags int32
+ Index uint16
+ _ [2]byte
}
type IfAnnounceMsghdr struct {
@@ -398,19 +461,19 @@ type IfAnnounceMsghdr struct {
}
type RtMsghdr struct {
- Msglen uint16
- Version uint8
- Type uint8
- Index uint16
- Pad_cgo_0 [2]byte
- Flags int32
- Addrs int32
- Pid int32
- Seq int32
- Errno int32
- Fmask int32
- Inits uint64
- Rmx RtMetrics
+ Msglen uint16
+ Version uint8
+ Type uint8
+ Index uint16
+ _ [2]byte
+ Flags int32
+ Addrs int32
+ Pid int32
+ Seq int32
+ Errno int32
+ Fmask int32
+ Inits uint64
+ Rmx RtMetrics
}
type RtMetrics struct {
@@ -455,9 +518,9 @@ type BpfZbuf struct {
}
type BpfProgram struct {
- Len uint32
- Pad_cgo_0 [4]byte
- Insns *BpfInsn
+ Len uint32
+ _ [4]byte
+ Insns *BpfInsn
}
type BpfInsn struct {
@@ -468,18 +531,18 @@ type BpfInsn struct {
}
type BpfHdr struct {
- Tstamp Timeval
- Caplen uint32
- Datalen uint32
- Hdrlen uint16
- Pad_cgo_0 [6]byte
+ Tstamp Timeval
+ Caplen uint32
+ Datalen uint32
+ Hdrlen uint16
+ _ [6]byte
}
type BpfZbufHeader struct {
Kernel_gen uint32
Kernel_len uint32
User_gen uint32
- X_bzh_pad [5]uint32
+ _ [5]uint32
}
type Termios struct {
diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
index 6b3006d6b..9b415aba4 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
@@ -21,15 +21,15 @@ type (
)
type Timespec struct {
- Sec int64
- Nsec int32
- Pad_cgo_0 [4]byte
+ Sec int64
+ Nsec int32
+ _ [4]byte
}
type Timeval struct {
- Sec int64
- Usec int32
- Pad_cgo_0 [4]byte
+ Sec int64
+ Usec int32
+ _ [4]byte
}
type Rusage struct {
@@ -58,27 +58,79 @@ type Rlimit struct {
type _Gid_t uint32
+const (
+ _statfsVersion = 0x20140518
+ _dirblksiz = 0x400
+)
+
type Stat_t struct {
- Dev uint32
- Ino uint32
- Mode uint16
- Nlink uint16
- Uid uint32
- Gid uint32
- Rdev uint32
- Atimespec Timespec
- Mtimespec Timespec
- Ctimespec Timespec
- Size int64
- Blocks int64
- Blksize int32
- Flags uint32
- Gen uint32
- Lspare int32
- Birthtimespec Timespec
+ Dev uint64
+ Ino uint64
+ Nlink uint64
+ Mode uint16
+ _0 int16
+ Uid uint32
+ Gid uint32
+ _1 int32
+ Rdev uint64
+ Atim Timespec
+ Mtim Timespec
+ Ctim Timespec
+ Birthtim Timespec
+ Size int64
+ Blocks int64
+ Blksize int32
+ Flags uint32
+ Gen uint64
+ Spare [10]uint64
+}
+
+type stat_freebsd11_t struct {
+ Dev uint32
+ Ino uint32
+ Mode uint16
+ Nlink uint16
+ Uid uint32
+ Gid uint32
+ Rdev uint32
+ Atim Timespec
+ Mtim Timespec
+ Ctim Timespec
+ Size int64
+ Blocks int64
+ Blksize int32
+ Flags uint32
+ Gen uint32
+ Lspare int32
+ Birthtim Timespec
}
type Statfs_t struct {
+ Version uint32
+ Type uint32
+ Flags uint64
+ Bsize uint64
+ Iosize uint64
+ Blocks uint64
+ Bfree uint64
+ Bavail int64
+ Files uint64
+ Ffree int64
+ Syncwrites uint64
+ Asyncwrites uint64
+ Syncreads uint64
+ Asyncreads uint64
+ Spare [10]uint64
+ Namemax uint32
+ Owner uint32
+ Fsid Fsid
+ Charspare [80]int8
+ Fstypename [16]int8
+ Mntfromname [1024]int8
+ Mntonname [1024]int8
+}
+
+type statfs_freebsd11_t struct {
Version uint32
Type uint32
Flags uint64
@@ -104,16 +156,27 @@ type Statfs_t struct {
}
type Flock_t struct {
- Start int64
- Len int64
- Pid int32
- Type int16
- Whence int16
- Sysid int32
- Pad_cgo_0 [4]byte
+ Start int64
+ Len int64
+ Pid int32
+ Type int16
+ Whence int16
+ Sysid int32
+ _ [4]byte
}
type Dirent struct {
+ Fileno uint64
+ Off int64
+ Reclen uint16
+ Type uint8
+ Pad0 uint8
+ Namlen uint16
+ Pad1 uint16
+ Name [256]int8
+}
+
+type dirent_freebsd11 struct {
Fileno uint32
Reclen uint16
Type uint8
@@ -274,7 +337,7 @@ type Kevent_t struct {
}
type FdSet struct {
- X__fds_bits [32]uint32
+ _ [32]uint32
}
const (
@@ -290,53 +353,53 @@ const (
)
type ifMsghdr struct {
- Msglen uint16
- Version uint8
- Type uint8
- Addrs int32
- Flags int32
- Index uint16
- Pad_cgo_0 [2]byte
- Data ifData
+ Msglen uint16
+ Version uint8
+ Type uint8
+ Addrs int32
+ Flags int32
+ Index uint16
+ _ [2]byte
+ Data ifData
}
type IfMsghdr struct {
- Msglen uint16
- Version uint8
- Type uint8
- Addrs int32
- Flags int32
- Index uint16
- Pad_cgo_0 [2]byte
- Data IfData
+ Msglen uint16
+ Version uint8
+ Type uint8
+ Addrs int32
+ Flags int32
+ Index uint16
+ _ [2]byte
+ Data IfData
}
type ifData struct {
- Type uint8
- Physical uint8
- Addrlen uint8
- Hdrlen uint8
- Link_state uint8
- Vhid uint8
- Datalen uint16
- Mtu uint32
- Metric uint32
- Baudrate uint64
- Ipackets uint64
- Ierrors uint64
- Opackets uint64
- Oerrors uint64
- Collisions uint64
- Ibytes uint64
- Obytes uint64
- Imcasts uint64
- Omcasts uint64
- Iqdrops uint64
- Oqdrops uint64
- Noproto uint64
- Hwassist uint64
- X__ifi_epoch [8]byte
- X__ifi_lastchange [16]byte
+ Type uint8
+ Physical uint8
+ Addrlen uint8
+ Hdrlen uint8
+ Link_state uint8
+ Vhid uint8
+ Datalen uint16
+ Mtu uint32
+ Metric uint32
+ Baudrate uint64
+ Ipackets uint64
+ Ierrors uint64
+ Opackets uint64
+ Oerrors uint64
+ Collisions uint64
+ Ibytes uint64
+ Obytes uint64
+ Imcasts uint64
+ Omcasts uint64
+ Iqdrops uint64
+ Oqdrops uint64
+ Noproto uint64
+ Hwassist uint64
+ _ [8]byte
+ _ [16]byte
}
type IfData struct {
@@ -363,30 +426,30 @@ type IfData struct {
Iqdrops uint32
Noproto uint32
Hwassist uint32
- Pad_cgo_0 [4]byte
+ _ [4]byte
Epoch int64
Lastchange Timeval
}
type IfaMsghdr struct {
- Msglen uint16
- Version uint8
- Type uint8
- Addrs int32
- Flags int32
- Index uint16
- Pad_cgo_0 [2]byte
- Metric int32
+ Msglen uint16
+ Version uint8
+ Type uint8
+ Addrs int32
+ Flags int32
+ Index uint16
+ _ [2]byte
+ Metric int32
}
type IfmaMsghdr struct {
- Msglen uint16
- Version uint8
- Type uint8
- Addrs int32
- Flags int32
- Index uint16
- Pad_cgo_0 [2]byte
+ Msglen uint16
+ Version uint8
+ Type uint8
+ Addrs int32
+ Flags int32
+ Index uint16
+ _ [2]byte
}
type IfAnnounceMsghdr struct {
@@ -399,19 +462,19 @@ type IfAnnounceMsghdr struct {
}
type RtMsghdr struct {
- Msglen uint16
- Version uint8
- Type uint8
- Index uint16
- Pad_cgo_0 [2]byte
- Flags int32
- Addrs int32
- Pid int32
- Seq int32
- Errno int32
- Fmask int32
- Inits uint32
- Rmx RtMetrics
+ Msglen uint16
+ Version uint8
+ Type uint8
+ Index uint16
+ _ [2]byte
+ Flags int32
+ Addrs int32
+ Pid int32
+ Seq int32
+ Errno int32
+ Fmask int32
+ Inits uint32
+ Rmx RtMetrics
}
type RtMetrics struct {
@@ -468,18 +531,18 @@ type BpfInsn struct {
}
type BpfHdr struct {
- Tstamp Timeval
- Caplen uint32
- Datalen uint32
- Hdrlen uint16
- Pad_cgo_0 [6]byte
+ Tstamp Timeval
+ Caplen uint32
+ Datalen uint32
+ Hdrlen uint16
+ _ [6]byte
}
type BpfZbufHeader struct {
Kernel_gen uint32
Kernel_len uint32
User_gen uint32
- X_bzh_pad [5]uint32
+ _ [5]uint32
}
type Termios struct {
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
index 3879002a9..5f8f03492 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
@@ -494,7 +494,7 @@ const (
IFLA_EVENT = 0x2c
IFLA_NEW_NETNSID = 0x2d
IFLA_IF_NETNSID = 0x2e
- IFLA_MAX = 0x31
+ IFLA_MAX = 0x33
RT_SCOPE_UNIVERSE = 0x0
RT_SCOPE_SITE = 0xc8
RT_SCOPE_LINK = 0xfd
@@ -1965,3 +1965,24 @@ const (
NCSI_CHANNEL_ATTR_VLAN_LIST = 0x9
NCSI_CHANNEL_ATTR_VLAN_ID = 0xa
)
+
+const (
+ SOF_TIMESTAMPING_TX_HARDWARE = 0x1
+ SOF_TIMESTAMPING_TX_SOFTWARE = 0x2
+ SOF_TIMESTAMPING_RX_HARDWARE = 0x4
+ SOF_TIMESTAMPING_RX_SOFTWARE = 0x8
+ SOF_TIMESTAMPING_SOFTWARE = 0x10
+ SOF_TIMESTAMPING_SYS_HARDWARE = 0x20
+ SOF_TIMESTAMPING_RAW_HARDWARE = 0x40
+ SOF_TIMESTAMPING_OPT_ID = 0x80
+ SOF_TIMESTAMPING_TX_SCHED = 0x100
+ SOF_TIMESTAMPING_TX_ACK = 0x200
+ SOF_TIMESTAMPING_OPT_CMSG = 0x400
+ SOF_TIMESTAMPING_OPT_TSONLY = 0x800
+ SOF_TIMESTAMPING_OPT_STATS = 0x1000
+ SOF_TIMESTAMPING_OPT_PKTINFO = 0x2000
+ SOF_TIMESTAMPING_OPT_TX_SWHW = 0x4000
+
+ SOF_TIMESTAMPING_LAST = 0x4000
+ SOF_TIMESTAMPING_MASK = 0x7fff
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
index cbc2c7d07..aa52a439d 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
@@ -498,7 +498,7 @@ const (
IFLA_EVENT = 0x2c
IFLA_NEW_NETNSID = 0x2d
IFLA_IF_NETNSID = 0x2e
- IFLA_MAX = 0x31
+ IFLA_MAX = 0x33
RT_SCOPE_UNIVERSE = 0x0
RT_SCOPE_SITE = 0xc8
RT_SCOPE_LINK = 0xfd
@@ -1987,3 +1987,24 @@ const (
NCSI_CHANNEL_ATTR_VLAN_LIST = 0x9
NCSI_CHANNEL_ATTR_VLAN_ID = 0xa
)
+
+const (
+ SOF_TIMESTAMPING_TX_HARDWARE = 0x1
+ SOF_TIMESTAMPING_TX_SOFTWARE = 0x2
+ SOF_TIMESTAMPING_RX_HARDWARE = 0x4
+ SOF_TIMESTAMPING_RX_SOFTWARE = 0x8
+ SOF_TIMESTAMPING_SOFTWARE = 0x10
+ SOF_TIMESTAMPING_SYS_HARDWARE = 0x20
+ SOF_TIMESTAMPING_RAW_HARDWARE = 0x40
+ SOF_TIMESTAMPING_OPT_ID = 0x80
+ SOF_TIMESTAMPING_TX_SCHED = 0x100
+ SOF_TIMESTAMPING_TX_ACK = 0x200
+ SOF_TIMESTAMPING_OPT_CMSG = 0x400
+ SOF_TIMESTAMPING_OPT_TSONLY = 0x800
+ SOF_TIMESTAMPING_OPT_STATS = 0x1000
+ SOF_TIMESTAMPING_OPT_PKTINFO = 0x2000
+ SOF_TIMESTAMPING_OPT_TX_SWHW = 0x4000
+
+ SOF_TIMESTAMPING_LAST = 0x4000
+ SOF_TIMESTAMPING_MASK = 0x7fff
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
index 6ed804fa3..23c8438be 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
@@ -497,7 +497,7 @@ const (
IFLA_EVENT = 0x2c
IFLA_NEW_NETNSID = 0x2d
IFLA_IF_NETNSID = 0x2e
- IFLA_MAX = 0x31
+ IFLA_MAX = 0x33
RT_SCOPE_UNIVERSE = 0x0
RT_SCOPE_SITE = 0xc8
RT_SCOPE_LINK = 0xfd
@@ -1955,3 +1955,24 @@ const (
NCSI_CHANNEL_ATTR_VLAN_LIST = 0x9
NCSI_CHANNEL_ATTR_VLAN_ID = 0xa
)
+
+const (
+ SOF_TIMESTAMPING_TX_HARDWARE = 0x1
+ SOF_TIMESTAMPING_TX_SOFTWARE = 0x2
+ SOF_TIMESTAMPING_RX_HARDWARE = 0x4
+ SOF_TIMESTAMPING_RX_SOFTWARE = 0x8
+ SOF_TIMESTAMPING_SOFTWARE = 0x10
+ SOF_TIMESTAMPING_SYS_HARDWARE = 0x20
+ SOF_TIMESTAMPING_RAW_HARDWARE = 0x40
+ SOF_TIMESTAMPING_OPT_ID = 0x80
+ SOF_TIMESTAMPING_TX_SCHED = 0x100
+ SOF_TIMESTAMPING_TX_ACK = 0x200
+ SOF_TIMESTAMPING_OPT_CMSG = 0x400
+ SOF_TIMESTAMPING_OPT_TSONLY = 0x800
+ SOF_TIMESTAMPING_OPT_STATS = 0x1000
+ SOF_TIMESTAMPING_OPT_PKTINFO = 0x2000
+ SOF_TIMESTAMPING_OPT_TX_SWHW = 0x4000
+
+ SOF_TIMESTAMPING_LAST = 0x4000
+ SOF_TIMESTAMPING_MASK = 0x7fff
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
index b5fe7ddf7..d7a993e25 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
@@ -499,7 +499,7 @@ const (
IFLA_EVENT = 0x2c
IFLA_NEW_NETNSID = 0x2d
IFLA_IF_NETNSID = 0x2e
- IFLA_MAX = 0x31
+ IFLA_MAX = 0x33
RT_SCOPE_UNIVERSE = 0x0
RT_SCOPE_SITE = 0xc8
RT_SCOPE_LINK = 0xfd
@@ -1966,3 +1966,24 @@ const (
NCSI_CHANNEL_ATTR_VLAN_LIST = 0x9
NCSI_CHANNEL_ATTR_VLAN_ID = 0xa
)
+
+const (
+ SOF_TIMESTAMPING_TX_HARDWARE = 0x1
+ SOF_TIMESTAMPING_TX_SOFTWARE = 0x2
+ SOF_TIMESTAMPING_RX_HARDWARE = 0x4
+ SOF_TIMESTAMPING_RX_SOFTWARE = 0x8
+ SOF_TIMESTAMPING_SOFTWARE = 0x10
+ SOF_TIMESTAMPING_SYS_HARDWARE = 0x20
+ SOF_TIMESTAMPING_RAW_HARDWARE = 0x40
+ SOF_TIMESTAMPING_OPT_ID = 0x80
+ SOF_TIMESTAMPING_TX_SCHED = 0x100
+ SOF_TIMESTAMPING_TX_ACK = 0x200
+ SOF_TIMESTAMPING_OPT_CMSG = 0x400
+ SOF_TIMESTAMPING_OPT_TSONLY = 0x800
+ SOF_TIMESTAMPING_OPT_STATS = 0x1000
+ SOF_TIMESTAMPING_OPT_PKTINFO = 0x2000
+ SOF_TIMESTAMPING_OPT_TX_SWHW = 0x4000
+
+ SOF_TIMESTAMPING_LAST = 0x4000
+ SOF_TIMESTAMPING_MASK = 0x7fff
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
index 7379ad2d8..b8c3d0a4d 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
@@ -495,7 +495,7 @@ const (
IFLA_EVENT = 0x2c
IFLA_NEW_NETNSID = 0x2d
IFLA_IF_NETNSID = 0x2e
- IFLA_MAX = 0x31
+ IFLA_MAX = 0x33
RT_SCOPE_UNIVERSE = 0x0
RT_SCOPE_SITE = 0xc8
RT_SCOPE_LINK = 0xfd
@@ -1960,3 +1960,24 @@ const (
NCSI_CHANNEL_ATTR_VLAN_LIST = 0x9
NCSI_CHANNEL_ATTR_VLAN_ID = 0xa
)
+
+const (
+ SOF_TIMESTAMPING_TX_HARDWARE = 0x1
+ SOF_TIMESTAMPING_TX_SOFTWARE = 0x2
+ SOF_TIMESTAMPING_RX_HARDWARE = 0x4
+ SOF_TIMESTAMPING_RX_SOFTWARE = 0x8
+ SOF_TIMESTAMPING_SOFTWARE = 0x10
+ SOF_TIMESTAMPING_SYS_HARDWARE = 0x20
+ SOF_TIMESTAMPING_RAW_HARDWARE = 0x40
+ SOF_TIMESTAMPING_OPT_ID = 0x80
+ SOF_TIMESTAMPING_TX_SCHED = 0x100
+ SOF_TIMESTAMPING_TX_ACK = 0x200
+ SOF_TIMESTAMPING_OPT_CMSG = 0x400
+ SOF_TIMESTAMPING_OPT_TSONLY = 0x800
+ SOF_TIMESTAMPING_OPT_STATS = 0x1000
+ SOF_TIMESTAMPING_OPT_PKTINFO = 0x2000
+ SOF_TIMESTAMPING_OPT_TX_SWHW = 0x4000
+
+ SOF_TIMESTAMPING_LAST = 0x4000
+ SOF_TIMESTAMPING_MASK = 0x7fff
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
index 0b131a24e..a6f76149a 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
@@ -499,7 +499,7 @@ const (
IFLA_EVENT = 0x2c
IFLA_NEW_NETNSID = 0x2d
IFLA_IF_NETNSID = 0x2e
- IFLA_MAX = 0x31
+ IFLA_MAX = 0x33
RT_SCOPE_UNIVERSE = 0x0
RT_SCOPE_SITE = 0xc8
RT_SCOPE_LINK = 0xfd
@@ -1968,3 +1968,24 @@ const (
NCSI_CHANNEL_ATTR_VLAN_LIST = 0x9
NCSI_CHANNEL_ATTR_VLAN_ID = 0xa
)
+
+const (
+ SOF_TIMESTAMPING_TX_HARDWARE = 0x1
+ SOF_TIMESTAMPING_TX_SOFTWARE = 0x2
+ SOF_TIMESTAMPING_RX_HARDWARE = 0x4
+ SOF_TIMESTAMPING_RX_SOFTWARE = 0x8
+ SOF_TIMESTAMPING_SOFTWARE = 0x10
+ SOF_TIMESTAMPING_SYS_HARDWARE = 0x20
+ SOF_TIMESTAMPING_RAW_HARDWARE = 0x40
+ SOF_TIMESTAMPING_OPT_ID = 0x80
+ SOF_TIMESTAMPING_TX_SCHED = 0x100
+ SOF_TIMESTAMPING_TX_ACK = 0x200
+ SOF_TIMESTAMPING_OPT_CMSG = 0x400
+ SOF_TIMESTAMPING_OPT_TSONLY = 0x800
+ SOF_TIMESTAMPING_OPT_STATS = 0x1000
+ SOF_TIMESTAMPING_OPT_PKTINFO = 0x2000
+ SOF_TIMESTAMPING_OPT_TX_SWHW = 0x4000
+
+ SOF_TIMESTAMPING_LAST = 0x4000
+ SOF_TIMESTAMPING_MASK = 0x7fff
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
index 9191020cc..3dd194176 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
@@ -499,7 +499,7 @@ const (
IFLA_EVENT = 0x2c
IFLA_NEW_NETNSID = 0x2d
IFLA_IF_NETNSID = 0x2e
- IFLA_MAX = 0x31
+ IFLA_MAX = 0x33
RT_SCOPE_UNIVERSE = 0x0
RT_SCOPE_SITE = 0xc8
RT_SCOPE_LINK = 0xfd
@@ -1968,3 +1968,24 @@ const (
NCSI_CHANNEL_ATTR_VLAN_LIST = 0x9
NCSI_CHANNEL_ATTR_VLAN_ID = 0xa
)
+
+const (
+ SOF_TIMESTAMPING_TX_HARDWARE = 0x1
+ SOF_TIMESTAMPING_TX_SOFTWARE = 0x2
+ SOF_TIMESTAMPING_RX_HARDWARE = 0x4
+ SOF_TIMESTAMPING_RX_SOFTWARE = 0x8
+ SOF_TIMESTAMPING_SOFTWARE = 0x10
+ SOF_TIMESTAMPING_SYS_HARDWARE = 0x20
+ SOF_TIMESTAMPING_RAW_HARDWARE = 0x40
+ SOF_TIMESTAMPING_OPT_ID = 0x80
+ SOF_TIMESTAMPING_TX_SCHED = 0x100
+ SOF_TIMESTAMPING_TX_ACK = 0x200
+ SOF_TIMESTAMPING_OPT_CMSG = 0x400
+ SOF_TIMESTAMPING_OPT_TSONLY = 0x800
+ SOF_TIMESTAMPING_OPT_STATS = 0x1000
+ SOF_TIMESTAMPING_OPT_PKTINFO = 0x2000
+ SOF_TIMESTAMPING_OPT_TX_SWHW = 0x4000
+
+ SOF_TIMESTAMPING_LAST = 0x4000
+ SOF_TIMESTAMPING_MASK = 0x7fff
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
index 8fcad32bf..210de76cc 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
@@ -495,7 +495,7 @@ const (
IFLA_EVENT = 0x2c
IFLA_NEW_NETNSID = 0x2d
IFLA_IF_NETNSID = 0x2e
- IFLA_MAX = 0x31
+ IFLA_MAX = 0x33
RT_SCOPE_UNIVERSE = 0x0
RT_SCOPE_SITE = 0xc8
RT_SCOPE_LINK = 0xfd
@@ -1960,3 +1960,24 @@ const (
NCSI_CHANNEL_ATTR_VLAN_LIST = 0x9
NCSI_CHANNEL_ATTR_VLAN_ID = 0xa
)
+
+const (
+ SOF_TIMESTAMPING_TX_HARDWARE = 0x1
+ SOF_TIMESTAMPING_TX_SOFTWARE = 0x2
+ SOF_TIMESTAMPING_RX_HARDWARE = 0x4
+ SOF_TIMESTAMPING_RX_SOFTWARE = 0x8
+ SOF_TIMESTAMPING_SOFTWARE = 0x10
+ SOF_TIMESTAMPING_SYS_HARDWARE = 0x20
+ SOF_TIMESTAMPING_RAW_HARDWARE = 0x40
+ SOF_TIMESTAMPING_OPT_ID = 0x80
+ SOF_TIMESTAMPING_TX_SCHED = 0x100
+ SOF_TIMESTAMPING_TX_ACK = 0x200
+ SOF_TIMESTAMPING_OPT_CMSG = 0x400
+ SOF_TIMESTAMPING_OPT_TSONLY = 0x800
+ SOF_TIMESTAMPING_OPT_STATS = 0x1000
+ SOF_TIMESTAMPING_OPT_PKTINFO = 0x2000
+ SOF_TIMESTAMPING_OPT_TX_SWHW = 0x4000
+
+ SOF_TIMESTAMPING_LAST = 0x4000
+ SOF_TIMESTAMPING_MASK = 0x7fff
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
index a9d1b6c9f..b46d54e37 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
@@ -500,7 +500,7 @@ const (
IFLA_EVENT = 0x2c
IFLA_NEW_NETNSID = 0x2d
IFLA_IF_NETNSID = 0x2e
- IFLA_MAX = 0x31
+ IFLA_MAX = 0x33
RT_SCOPE_UNIVERSE = 0x0
RT_SCOPE_SITE = 0xc8
RT_SCOPE_LINK = 0xfd
@@ -1976,3 +1976,24 @@ const (
NCSI_CHANNEL_ATTR_VLAN_LIST = 0x9
NCSI_CHANNEL_ATTR_VLAN_ID = 0xa
)
+
+const (
+ SOF_TIMESTAMPING_TX_HARDWARE = 0x1
+ SOF_TIMESTAMPING_TX_SOFTWARE = 0x2
+ SOF_TIMESTAMPING_RX_HARDWARE = 0x4
+ SOF_TIMESTAMPING_RX_SOFTWARE = 0x8
+ SOF_TIMESTAMPING_SOFTWARE = 0x10
+ SOF_TIMESTAMPING_SYS_HARDWARE = 0x20
+ SOF_TIMESTAMPING_RAW_HARDWARE = 0x40
+ SOF_TIMESTAMPING_OPT_ID = 0x80
+ SOF_TIMESTAMPING_TX_SCHED = 0x100
+ SOF_TIMESTAMPING_TX_ACK = 0x200
+ SOF_TIMESTAMPING_OPT_CMSG = 0x400
+ SOF_TIMESTAMPING_OPT_TSONLY = 0x800
+ SOF_TIMESTAMPING_OPT_STATS = 0x1000
+ SOF_TIMESTAMPING_OPT_PKTINFO = 0x2000
+ SOF_TIMESTAMPING_OPT_TX_SWHW = 0x4000
+
+ SOF_TIMESTAMPING_LAST = 0x4000
+ SOF_TIMESTAMPING_MASK = 0x7fff
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
index f0f5214a5..6ee799cef 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
@@ -500,7 +500,7 @@ const (
IFLA_EVENT = 0x2c
IFLA_NEW_NETNSID = 0x2d
IFLA_IF_NETNSID = 0x2e
- IFLA_MAX = 0x31
+ IFLA_MAX = 0x33
RT_SCOPE_UNIVERSE = 0x0
RT_SCOPE_SITE = 0xc8
RT_SCOPE_LINK = 0xfd
@@ -1976,3 +1976,24 @@ const (
NCSI_CHANNEL_ATTR_VLAN_LIST = 0x9
NCSI_CHANNEL_ATTR_VLAN_ID = 0xa
)
+
+const (
+ SOF_TIMESTAMPING_TX_HARDWARE = 0x1
+ SOF_TIMESTAMPING_TX_SOFTWARE = 0x2
+ SOF_TIMESTAMPING_RX_HARDWARE = 0x4
+ SOF_TIMESTAMPING_RX_SOFTWARE = 0x8
+ SOF_TIMESTAMPING_SOFTWARE = 0x10
+ SOF_TIMESTAMPING_SYS_HARDWARE = 0x20
+ SOF_TIMESTAMPING_RAW_HARDWARE = 0x40
+ SOF_TIMESTAMPING_OPT_ID = 0x80
+ SOF_TIMESTAMPING_TX_SCHED = 0x100
+ SOF_TIMESTAMPING_TX_ACK = 0x200
+ SOF_TIMESTAMPING_OPT_CMSG = 0x400
+ SOF_TIMESTAMPING_OPT_TSONLY = 0x800
+ SOF_TIMESTAMPING_OPT_STATS = 0x1000
+ SOF_TIMESTAMPING_OPT_PKTINFO = 0x2000
+ SOF_TIMESTAMPING_OPT_TX_SWHW = 0x4000
+
+ SOF_TIMESTAMPING_LAST = 0x4000
+ SOF_TIMESTAMPING_MASK = 0x7fff
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
index 09c905866..60ae71e62 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
@@ -499,7 +499,7 @@ const (
IFLA_EVENT = 0x2c
IFLA_NEW_NETNSID = 0x2d
IFLA_IF_NETNSID = 0x2e
- IFLA_MAX = 0x31
+ IFLA_MAX = 0x33
RT_SCOPE_UNIVERSE = 0x0
RT_SCOPE_SITE = 0xc8
RT_SCOPE_LINK = 0xfd
@@ -1993,3 +1993,24 @@ const (
NCSI_CHANNEL_ATTR_VLAN_LIST = 0x9
NCSI_CHANNEL_ATTR_VLAN_ID = 0xa
)
+
+const (
+ SOF_TIMESTAMPING_TX_HARDWARE = 0x1
+ SOF_TIMESTAMPING_TX_SOFTWARE = 0x2
+ SOF_TIMESTAMPING_RX_HARDWARE = 0x4
+ SOF_TIMESTAMPING_RX_SOFTWARE = 0x8
+ SOF_TIMESTAMPING_SOFTWARE = 0x10
+ SOF_TIMESTAMPING_SYS_HARDWARE = 0x20
+ SOF_TIMESTAMPING_RAW_HARDWARE = 0x40
+ SOF_TIMESTAMPING_OPT_ID = 0x80
+ SOF_TIMESTAMPING_TX_SCHED = 0x100
+ SOF_TIMESTAMPING_TX_ACK = 0x200
+ SOF_TIMESTAMPING_OPT_CMSG = 0x400
+ SOF_TIMESTAMPING_OPT_TSONLY = 0x800
+ SOF_TIMESTAMPING_OPT_STATS = 0x1000
+ SOF_TIMESTAMPING_OPT_PKTINFO = 0x2000
+ SOF_TIMESTAMPING_OPT_TX_SWHW = 0x4000
+
+ SOF_TIMESTAMPING_LAST = 0x4000
+ SOF_TIMESTAMPING_MASK = 0x7fff
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
index 5e86e496c..dea88f7bb 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
@@ -498,7 +498,7 @@ const (
IFLA_EVENT = 0x2c
IFLA_NEW_NETNSID = 0x2d
IFLA_IF_NETNSID = 0x2e
- IFLA_MAX = 0x31
+ IFLA_MAX = 0x33
RT_SCOPE_UNIVERSE = 0x0
RT_SCOPE_SITE = 0xc8
RT_SCOPE_LINK = 0xfd
@@ -1993,3 +1993,24 @@ const (
NCSI_CHANNEL_ATTR_VLAN_LIST = 0x9
NCSI_CHANNEL_ATTR_VLAN_ID = 0xa
)
+
+const (
+ SOF_TIMESTAMPING_TX_HARDWARE = 0x1
+ SOF_TIMESTAMPING_TX_SOFTWARE = 0x2
+ SOF_TIMESTAMPING_RX_HARDWARE = 0x4
+ SOF_TIMESTAMPING_RX_SOFTWARE = 0x8
+ SOF_TIMESTAMPING_SOFTWARE = 0x10
+ SOF_TIMESTAMPING_SYS_HARDWARE = 0x20
+ SOF_TIMESTAMPING_RAW_HARDWARE = 0x40
+ SOF_TIMESTAMPING_OPT_ID = 0x80
+ SOF_TIMESTAMPING_TX_SCHED = 0x100
+ SOF_TIMESTAMPING_TX_ACK = 0x200
+ SOF_TIMESTAMPING_OPT_CMSG = 0x400
+ SOF_TIMESTAMPING_OPT_TSONLY = 0x800
+ SOF_TIMESTAMPING_OPT_STATS = 0x1000
+ SOF_TIMESTAMPING_OPT_PKTINFO = 0x2000
+ SOF_TIMESTAMPING_OPT_TX_SWHW = 0x4000
+
+ SOF_TIMESTAMPING_LAST = 0x4000
+ SOF_TIMESTAMPING_MASK = 0x7fff
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go
index c8509bf0e..8b37d8399 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go
@@ -458,6 +458,8 @@ const (
POLLWRNORM = 0x4
)
+type Sigset_t uint32
+
type Utsname struct {
Sysname [256]byte
Nodename [256]byte
diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go
index 200575d94..6efea4635 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go
@@ -458,6 +458,8 @@ const (
POLLWRNORM = 0x4
)
+type Sigset_t uint32
+
type Utsname struct {
Sysname [256]byte
Nodename [256]byte
diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go
index 3e20cdf09..87a637e3f 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go
@@ -451,6 +451,8 @@ const (
POLLWRNORM = 0x4
)
+type Sigset_t uint32
+
type Utsname struct {
Sysname [256]byte
Nodename [256]byte
diff --git a/worker/db.go b/worker/db.go
index dd2478eb4..a49209bb8 100644
--- a/worker/db.go
+++ b/worker/db.go
@@ -22,6 +22,7 @@ import (
"io"
"os"
"path/filepath"
+ "runtime/trace"
"strings"
"sync"
"time"
@@ -180,9 +181,10 @@ func (db *Database) UpdatePeers(peers *kayak.Peers) (err error) {
// Query defines database query interface.
func (db *Database) Query(request *wt.Request) (response *wt.Response, err error) {
- if err = request.Verify(); err != nil {
- return
- }
+ // Just need to verify signature in db.saveAck
+ //if err = request.Verify(); err != nil {
+ // return
+ //}
switch request.Header.QueryType {
case wt.ReadQuery:
@@ -197,9 +199,10 @@ func (db *Database) Query(request *wt.Request) (response *wt.Response, err error
// Ack defines client response ack interface.
func (db *Database) Ack(ack *wt.Ack) (err error) {
- if err = ack.Verify(); err != nil {
- return
- }
+ // Just need to verify signature in db.saveAck
+ //if err = ack.Verify(); err != nil {
+ // return
+ //}
return db.saveAck(&ack.Header)
}
@@ -255,6 +258,11 @@ func (db *Database) Destroy() (err error) {
}
func (db *Database) writeQuery(request *wt.Request) (response *wt.Response, err error) {
+ ctx := context.Background()
+ ctx, task := trace.NewTask(ctx, "writeQuery")
+ defer task.End()
+ defer trace.StartRegion(ctx, "writeQueryRegion").End()
+
// check database size first, wal/kayak/chain database size is not included
if db.cfg.SpaceLimit > 0 {
path := filepath.Join(db.cfg.DataDir, StorageFileName)
@@ -319,9 +327,6 @@ func (db *Database) buildQueryResponse(request *wt.Request, offset uint64,
response.Header.LogOffset = offset
response.Header.Timestamp = getLocalTime()
response.Header.RowCount = uint64(len(data))
- if response.Header.Signee, err = getLocalPubKey(); err != nil {
- return
- }
// set payload
response.Payload.Columns = columns
@@ -358,10 +363,6 @@ func getLocalTime() time.Time {
return time.Now().UTC()
}
-func getLocalPubKey() (pubKey *asymmetric.PublicKey, err error) {
- return kms.GetLocalPublicKey()
-}
-
func getLocalPrivateKey() (privateKey *asymmetric.PrivateKey, err error) {
return kms.GetLocalPrivateKey()
}
@@ -409,7 +410,10 @@ func convertAndSanitizeQuery(inQuery []wt.Query) (outQuery []storage.Query, err
query = "SELECT name FROM sqlite_master WHERE type = \"table\""
}
- log.Debugf("translated query from %v to %v", origQuery, query)
+ log.WithFields(log.Fields{
+ "from": origQuery,
+ "to": query,
+ }).Debug("query translated")
}
originalQueries = append(originalQueries, query)
diff --git a/worker/db_test.go b/worker/db_test.go
index 31e4afe0b..4e576bc5c 100644
--- a/worker/db_test.go
+++ b/worker/db_test.go
@@ -44,6 +44,7 @@ import (
"github.com/CovenantSQL/CovenantSQL/sqlchain"
ct "github.com/CovenantSQL/CovenantSQL/sqlchain/types"
"github.com/CovenantSQL/CovenantSQL/utils"
+ "github.com/CovenantSQL/CovenantSQL/utils/log"
wt "github.com/CovenantSQL/CovenantSQL/worker/types"
"github.com/fortytw2/leaktest"
. "github.com/smartystreets/goconvey/convey"
@@ -54,6 +55,7 @@ var rootHash = hash.Hash{}
const PubKeyStorePath = "./public.keystore"
func TestSingleDatabase(t *testing.T) {
+ log.SetLevel(log.DebugLevel)
// init as single node database
Convey("test database", t, func() {
var err error
@@ -125,8 +127,24 @@ func TestSingleDatabase(t *testing.T) {
So(res.Payload.Rows[0].Values, ShouldNotBeEmpty)
So(res.Payload.Rows[0].Values[0], ShouldResemble, []byte("test"))
- // test show create table
+ // test show full tables query
readQuery, err = buildQuery(wt.ReadQuery, 1, 3, []string{
+ "show full tables",
+ })
+ So(err, ShouldBeNil)
+
+ res, err = db.Query(readQuery)
+ So(err, ShouldBeNil)
+ err = res.Verify()
+ So(err, ShouldBeNil)
+
+ So(res.Header.RowCount, ShouldEqual, uint64(1))
+ So(res.Payload.Rows, ShouldNotBeEmpty)
+ So(res.Payload.Rows[0].Values, ShouldNotBeEmpty)
+ So(res.Payload.Rows[0].Values[0], ShouldResemble, []byte("test"))
+
+ // test show create table
+ readQuery, err = buildQuery(wt.ReadQuery, 1, 4, []string{
"show create table test",
})
So(err, ShouldBeNil)
@@ -144,7 +162,7 @@ func TestSingleDatabase(t *testing.T) {
So(strings.ToUpper(string(byteStr)), ShouldContainSubstring, "CREATE")
// test show table
- readQuery, err = buildQuery(wt.ReadQuery, 1, 4, []string{
+ readQuery, err = buildQuery(wt.ReadQuery, 1, 5, []string{
"show table test",
})
So(err, ShouldBeNil)
@@ -162,7 +180,7 @@ func TestSingleDatabase(t *testing.T) {
So(res.Payload.Rows[1].Values[1], ShouldResemble, []byte("col2"))
// test desc table
- readQuery, err = buildQuery(wt.ReadQuery, 1, 5, []string{
+ readQuery, err = buildQuery(wt.ReadQuery, 1, 6, []string{
"desc test",
})
So(err, ShouldBeNil)
@@ -180,7 +198,7 @@ func TestSingleDatabase(t *testing.T) {
So(res.Payload.Rows[1].Values[1], ShouldResemble, []byte("col2"))
// test show index from table
- readQuery, err = buildQuery(wt.ReadQuery, 1, 6, []string{
+ readQuery, err = buildQuery(wt.ReadQuery, 1, 7, []string{
"show index from table test",
})
So(err, ShouldBeNil)
@@ -533,10 +551,9 @@ func buildAck(res *wt.Response) (ack *wt.Ack, err error) {
}
// get private/public key
- var pubKey *asymmetric.PublicKey
var privateKey *asymmetric.PrivateKey
- if privateKey, pubKey, err = getKeys(); err != nil {
+ if privateKey, _, err = getKeys(); err != nil {
return
}
@@ -547,11 +564,10 @@ func buildAck(res *wt.Response) (ack *wt.Ack, err error) {
NodeID: nodeID,
Timestamp: getLocalTime(),
},
- Signee: pubKey,
},
}
- err = ack.Sign(privateKey)
+ err = ack.Sign(privateKey, true)
return
}
@@ -576,10 +592,9 @@ func buildQueryEx(queryType wt.QueryType, connID uint64, seqNo uint64, timeShift
}
// get private/public key
- var pubKey *asymmetric.PublicKey
var privateKey *asymmetric.PrivateKey
- if privateKey, pubKey, err = getKeys(); err != nil {
+ if privateKey, _, err = getKeys(); err != nil {
return
}
@@ -603,7 +618,6 @@ func buildQueryEx(queryType wt.QueryType, connID uint64, seqNo uint64, timeShift
SeqNo: seqNo,
Timestamp: tm,
},
- Signee: pubKey,
},
Payload: wt.RequestPayload{
Queries: realQueries,
@@ -693,12 +707,12 @@ func initNode() (cleanupFunc func(), server *rpc.Server, err error) {
}
// init rpc
- if server, err = rpc.NewServerWithService(rpc.ServiceMap{"DHT": dht}); err != nil {
+ if server, err = rpc.NewServerWithService(rpc.ServiceMap{route.DHTRPCName: dht}); err != nil {
return
}
// register bpdb service
- if err = server.RegisterService(bp.DBServiceName, &stubBPDBService{}); err != nil {
+ if err = server.RegisterService(route.BPDBRPCName, &stubBPDBService{}); err != nil {
return
}
@@ -743,8 +757,6 @@ func createRandomBlock(parent hash.Hash, isGenesis bool) (b *ct.Block, err error
ParentHash: parent,
Timestamp: time.Now().UTC(),
},
- Signee: pub,
- Signature: nil,
},
Queries: make([]*hash.Hash, rand.Intn(10)+10),
}
diff --git a/worker/dbms.go b/worker/dbms.go
index e945d5b88..4eb6ff748 100644
--- a/worker/dbms.go
+++ b/worker/dbms.go
@@ -23,6 +23,8 @@ import (
"path/filepath"
"sync"
+ "github.com/pkg/errors"
+
ka "github.com/CovenantSQL/CovenantSQL/kayak/api"
kt "github.com/CovenantSQL/CovenantSQL/kayak/transport"
"github.com/CovenantSQL/CovenantSQL/proto"
@@ -38,12 +40,6 @@ const (
// DBKayakRPCName defines rpc service name of database internal consensus.
DBKayakRPCName = "DBC" // aka. database consensus
- // SQLChainRPCName defines rpc service name of sql-chain internal consensus.
- SQLChainRPCName = "SQLC"
-
- // DBServiceRPCName defines rpc service name of database external query api.
- DBServiceRPCName = "DBS" // aka. database service
-
// DBMetaFileName defines dbms meta file name.
DBMetaFileName = "db.meta"
)
@@ -67,10 +63,10 @@ func NewDBMS(cfg *DBMSConfig) (dbms *DBMS, err error) {
dbms.kayakMux = ka.NewMuxService(DBKayakRPCName, cfg.Server)
// init sql-chain rpc mux
- dbms.chainMux = sqlchain.NewMuxService(SQLChainRPCName, cfg.Server)
+ dbms.chainMux = sqlchain.NewMuxService(route.SQLChainRPCName, cfg.Server)
// init service
- dbms.rpc = NewDBMSRPCService(DBServiceRPCName, cfg.Server, dbms)
+ dbms.rpc = NewDBMSRPCService(route.DBRPCName, cfg.Server, dbms)
return
}
@@ -127,17 +123,20 @@ func (dbms *DBMS) Init() (err error) {
// read meta
var localMeta *DBMSMeta
if localMeta, err = dbms.readMeta(); err != nil {
+ err = errors.Wrap(err, "read dbms meta failed")
return
}
// load current peers info from block producer
var dbMapping []wt.ServiceInstance
if dbMapping, err = dbms.getMappedInstances(); err != nil {
+ err = errors.Wrap(err, "get mapped instances failed")
return
}
// init database
if err = dbms.initDatabases(localMeta, dbMapping); err != nil {
+ err = errors.Wrap(err, "init databases with meta failed")
return
}
@@ -364,7 +363,7 @@ func (dbms *DBMS) Shutdown() (err error) {
db := rawDB.(*Database)
if err = db.Shutdown(); err != nil {
- log.Errorf("shutdown database failed: %v", err)
+ log.WithError(err).Error("shutdown database failed")
}
return true
diff --git a/worker/dbms_rpc.go b/worker/dbms_rpc.go
index 20c74eb87..b75cc9407 100644
--- a/worker/dbms_rpc.go
+++ b/worker/dbms_rpc.go
@@ -17,9 +17,18 @@
package worker
import (
+ "context"
+ "runtime/trace"
+
"github.com/CovenantSQL/CovenantSQL/route"
"github.com/CovenantSQL/CovenantSQL/rpc"
wt "github.com/CovenantSQL/CovenantSQL/worker/types"
+ "github.com/rcrowley/go-metrics"
+)
+
+var (
+ dbQuerySuccCounter metrics.Meter
+ dbQueryFailCounter metrics.Meter
)
// DBMSRPCService is the rpc endpoint of database management.
@@ -34,39 +43,55 @@ func NewDBMSRPCService(serviceName string, server *rpc.Server, dbms *DBMS) (serv
}
server.RegisterService(serviceName, service)
+ dbQuerySuccCounter = metrics.NewMeter()
+ metrics.Register("db-query-succ", dbQuerySuccCounter)
+ dbQueryFailCounter = metrics.NewMeter()
+ metrics.Register("db-query-fail", dbQueryFailCounter)
+
return
}
// Query rpc, called by client to issue read/write query.
func (rpc *DBMSRPCService) Query(req *wt.Request, res *wt.Response) (err error) {
- // verify checksum/signature
- if err = req.Verify(); err != nil {
- return
- }
-
+ // Just need to verify signature in db.saveAck
+ //if err = req.Verify(); err != nil {
+ // dbQueryFailCounter.Mark(1)
+ // return
+ //}
+ ctx := context.Background()
+ ctx, task := trace.NewTask(ctx, "Query")
+ defer task.End()
+ defer trace.StartRegion(ctx, "QueryRegion").End()
// verify query is sent from the request node
if req.Envelope.NodeID.String() != string(req.Header.NodeID) {
// node id mismatch
err = ErrInvalidRequest
+ dbQueryFailCounter.Mark(1)
return
}
var r *wt.Response
if r, err = rpc.dbms.Query(req); err != nil {
+ dbQueryFailCounter.Mark(1)
return
}
*res = *r
+ dbQuerySuccCounter.Mark(1)
return
}
// Ack rpc, called by client to confirm read request.
func (rpc *DBMSRPCService) Ack(ack *wt.Ack, _ *wt.AckResponse) (err error) {
- // verify checksum/signature
- if err = ack.Verify(); err != nil {
- return
- }
+ // Just need to verify signature in db.saveAck
+ //if err = ack.Verify(); err != nil {
+ // return
+ //}
+ ctx := context.Background()
+ ctx, task := trace.NewTask(ctx, "Ack")
+ defer task.End()
+ defer trace.StartRegion(ctx, "AckRegion").End()
// verify if ack node is the original ack node
if ack.Envelope.NodeID.String() != string(ack.Header.Response.Request.NodeID) {
diff --git a/worker/dbms_test.go b/worker/dbms_test.go
index f04d48554..a0f2875ae 100644
--- a/worker/dbms_test.go
+++ b/worker/dbms_test.go
@@ -41,9 +41,6 @@ func TestDBMS(t *testing.T) {
cleanup, server, err = initNode()
So(err, ShouldBeNil)
- var pubKey *asymmetric.PublicKey
- pubKey, err = kms.GetLocalPublicKey()
- So(err, ShouldBeNil)
var privateKey *asymmetric.PrivateKey
privateKey, err = kms.GetLocalPrivateKey()
So(err, ShouldBeNil)
@@ -90,7 +87,6 @@ func TestDBMS(t *testing.T) {
Peers: peers,
GenesisBlock: block,
}
- req.Header.Signee = pubKey
err = req.Sign(privateKey)
So(err, ShouldBeNil)
@@ -179,7 +175,6 @@ func TestDBMS(t *testing.T) {
DatabaseID: dbID,
Peers: peers,
}
- req.Header.Signee = pubKey
err = req.Sign(privateKey)
So(err, ShouldBeNil)
@@ -194,7 +189,6 @@ func TestDBMS(t *testing.T) {
req.Header.Instance = wt.ServiceInstance{
DatabaseID: dbID,
}
- req.Header.Signee = pubKey
err = req.Sign(privateKey)
So(err, ShouldBeNil)
diff --git a/worker/types/ack_type.go b/worker/types/ack_type.go
index a5deb68b7..564c70cf4 100644
--- a/worker/types/ack_type.go
+++ b/worker/types/ack_type.go
@@ -30,23 +30,23 @@ import (
// AckHeader defines client ack entity.
type AckHeader struct {
- Response SignedResponseHeader
- NodeID proto.NodeID // ack node id
- Timestamp time.Time // time in UTC zone
+ Response SignedResponseHeader `json:"r"`
+ NodeID proto.NodeID `json:"i"` // ack node id
+ Timestamp time.Time `json:"t"` // time in UTC zone
}
// SignedAckHeader defines client signed ack entity.
type SignedAckHeader struct {
AckHeader
- HeaderHash hash.Hash
- Signee *asymmetric.PublicKey
- Signature *asymmetric.Signature
+ HeaderHash hash.Hash `json:"hh"`
+ Signee *asymmetric.PublicKey `json:"e"`
+ Signature *asymmetric.Signature `json:"s"`
}
// Ack defines a whole client ack request entity.
type Ack struct {
proto.Envelope
- Header SignedAckHeader
+ Header SignedAckHeader `json:"h"`
}
// AckResponse defines client ack response entity.
@@ -109,10 +109,13 @@ func (sh *SignedAckHeader) Verify() (err error) {
}
// Sign the request.
-func (sh *SignedAckHeader) Sign(signer *asymmetric.PrivateKey) (err error) {
- // check original header signature
- if err = sh.Response.Verify(); err != nil {
- return
+func (sh *SignedAckHeader) Sign(signer *asymmetric.PrivateKey, verifyReqHeader bool) (err error) {
+ // Only used by ack worker, and ack.Header is verified before build ack
+ if verifyReqHeader {
+ // check original header signature
+ if err = sh.Response.Verify(); err != nil {
+ return
+ }
}
// build hash
@@ -120,6 +123,7 @@ func (sh *SignedAckHeader) Sign(signer *asymmetric.PrivateKey) (err error) {
// sign
sh.Signature, err = signer.Sign(sh.HeaderHash[:])
+ sh.Signee = signer.PubKey()
return
}
@@ -139,9 +143,9 @@ func (a *Ack) Verify() error {
}
// Sign the request.
-func (a *Ack) Sign(signer *asymmetric.PrivateKey) (err error) {
+func (a *Ack) Sign(signer *asymmetric.PrivateKey, verifyReqHeader bool) (err error) {
// sign
- return a.Header.Sign(signer)
+ return a.Header.Sign(signer, verifyReqHeader)
}
// ResponseHeaderHash returns the deep shadowed Response HeaderHash field.
diff --git a/worker/types/init_service_type.go b/worker/types/init_service_type.go
index cc87a6c51..8c97f1c5e 100644
--- a/worker/types/init_service_type.go
+++ b/worker/types/init_service_type.go
@@ -166,6 +166,7 @@ func (sh *SignedInitServiceResponseHeader) Sign(signer *asymmetric.PrivateKey) (
// sign
sh.Signature, err = signer.Sign(sh.HeaderHash[:])
+ sh.Signee = signer.PubKey()
return
}
diff --git a/worker/types/no_ack_report_type.go b/worker/types/no_ack_report_type.go
index 5d67eece1..aa163176e 100644
--- a/worker/types/no_ack_report_type.go
+++ b/worker/types/no_ack_report_type.go
@@ -141,6 +141,7 @@ func (sh *SignedNoAckReportHeader) Sign(signer *asymmetric.PrivateKey) (err erro
// sign
sh.Signature, err = signer.Sign(sh.HeaderHash[:])
+ sh.Signee = signer.PubKey()
return
}
@@ -240,6 +241,7 @@ func (sh *SignedAggrNoAckReportHeader) Sign(signer *asymmetric.PrivateKey) (err
// verify signature
sh.Signature, err = signer.Sign(sh.HeaderHash[:])
+ sh.Signee = signer.PubKey()
return
}
diff --git a/worker/types/request_type.go b/worker/types/request_type.go
index c58095973..26101475b 100644
--- a/worker/types/request_type.go
+++ b/worker/types/request_type.go
@@ -60,41 +60,41 @@ func (t QueryType) String() string {
// RequestPayload defines a queries payload.
type RequestPayload struct {
- Queries []Query
+ Queries []Query `json:"qs"`
}
// RequestHeader defines a query request header.
type RequestHeader struct {
- QueryType QueryType
- NodeID proto.NodeID // request node id
- DatabaseID proto.DatabaseID // request database id
- ConnectionID uint64
- SeqNo uint64
- Timestamp time.Time // time in UTC zone
- BatchCount uint64 // query count in this request
- QueriesHash hash.Hash // hash of query payload
+ QueryType QueryType `json:"qt"`
+ NodeID proto.NodeID `json:"id"` // request node id
+ DatabaseID proto.DatabaseID `json:"dbid"` // request database id
+ ConnectionID uint64 `json:"cid"`
+ SeqNo uint64 `json:"seq"`
+ Timestamp time.Time `json:"t"` // time in UTC zone
+ BatchCount uint64 `json:"bc"` // query count in this request
+ QueriesHash hash.Hash `json:"qh"` // hash of query payload
}
// QueryKey defines an unique query key of a request.
type QueryKey struct {
- NodeID proto.NodeID
- ConnectionID uint64
- SeqNo uint64
+ NodeID proto.NodeID `json:"id"`
+ ConnectionID uint64 `json:"cid"`
+ SeqNo uint64 `json:"seq"`
}
// SignedRequestHeader defines a signed query request header.
type SignedRequestHeader struct {
RequestHeader
- HeaderHash hash.Hash
- Signee *asymmetric.PublicKey
- Signature *asymmetric.Signature
+ HeaderHash hash.Hash `json:"hh"`
+ Signee *asymmetric.PublicKey `json:"e"`
+ Signature *asymmetric.Signature `json:"s"`
}
// Request defines a complete query request.
type Request struct {
proto.Envelope
- Header SignedRequestHeader
- Payload RequestPayload
+ Header SignedRequestHeader `json:"h"`
+ Payload RequestPayload `json:"p"`
}
// Serialize returns byte based binary form of struct.
@@ -168,12 +168,13 @@ func (sh *SignedRequestHeader) Sign(signer *asymmetric.PrivateKey) (err error) {
// compute hash
buildHash(&sh.RequestHeader, &sh.HeaderHash)
- if sh.Signee == nil || signer == nil {
+ if signer == nil {
return ErrSignRequest
}
// sign
sh.Signature, err = signer.Sign(sh.HeaderHash[:])
+ sh.Signee = signer.PubKey()
return
}
diff --git a/worker/types/response_type.go b/worker/types/response_type.go
index e2a28abac..1f0d3ee77 100644
--- a/worker/types/response_type.go
+++ b/worker/types/response_type.go
@@ -37,33 +37,33 @@ type ResponseRow struct {
// ResponsePayload defines column names and rows of query response.
type ResponsePayload struct {
- Columns []string
- DeclTypes []string
- Rows []ResponseRow
+ Columns []string `json:"c"`
+ DeclTypes []string `json:"t"`
+ Rows []ResponseRow `json:"r"`
}
// ResponseHeader defines a query response header.
type ResponseHeader struct {
- Request SignedRequestHeader
- NodeID proto.NodeID // response node id
- Timestamp time.Time // time in UTC zone
- RowCount uint64 // response row count of payload
- LogOffset uint64 // request log offset
- DataHash hash.Hash // hash of query response
+ Request SignedRequestHeader `json:"r"`
+ NodeID proto.NodeID `json:"id"` // response node id
+ Timestamp time.Time `json:"t"` // time in UTC zone
+ RowCount uint64 `json:"c"` // response row count of payload
+ LogOffset uint64 `json:"o"` // request log offset
+ DataHash hash.Hash `json:"dh"` // hash of query response
}
// SignedResponseHeader defines a signed query response header.
type SignedResponseHeader struct {
ResponseHeader
- HeaderHash hash.Hash
- Signee *asymmetric.PublicKey
- Signature *asymmetric.Signature
+ HeaderHash hash.Hash `json:"h"`
+ Signee *asymmetric.PublicKey `json:"e"`
+ Signature *asymmetric.Signature `json:"s"`
}
// Response defines a complete query response.
type Response struct {
- Header SignedResponseHeader
- Payload ResponsePayload
+ Header SignedResponseHeader `json:"h"`
+ Payload ResponsePayload `json:"p"`
}
// Serialize structure to bytes.
@@ -174,6 +174,7 @@ func (sh *SignedResponseHeader) Sign(signer *asymmetric.PrivateKey) (err error)
// sign
sh.Signature, err = signer.Sign(sh.HeaderHash[:])
+ sh.Signee = signer.PubKey()
return
}
diff --git a/worker/types/response_type_gen.go b/worker/types/response_type_gen.go
index 3126d6e1c..8ce0f4c36 100644
--- a/worker/types/response_type_gen.go
+++ b/worker/types/response_type_gen.go
@@ -36,35 +36,37 @@ func (z *Response) Msgsize() (s int) {
func (z *ResponseHeader) MarshalHash() (o []byte, err error) {
var b []byte
o = hsp.Require(b, z.Msgsize())
- // map header, size 5
- o = append(o, 0x85, 0x85)
+ // map header, size 6
+ o = append(o, 0x86, 0x86)
if oTemp, err := z.Request.MarshalHash(); err != nil {
return nil, err
} else {
o = hsp.AppendBytes(o, oTemp)
}
- o = append(o, 0x85)
+ o = append(o, 0x86)
if oTemp, err := z.DataHash.MarshalHash(); err != nil {
return nil, err
} else {
o = hsp.AppendBytes(o, oTemp)
}
- o = append(o, 0x85)
+ o = append(o, 0x86)
if oTemp, err := z.NodeID.MarshalHash(); err != nil {
return nil, err
} else {
o = hsp.AppendBytes(o, oTemp)
}
- o = append(o, 0x85)
+ o = append(o, 0x86)
o = hsp.AppendTime(o, z.Timestamp)
- o = append(o, 0x85)
+ o = append(o, 0x86)
o = hsp.AppendUint64(o, z.RowCount)
+ o = append(o, 0x86)
+ o = hsp.AppendUint64(o, z.LogOffset)
return
}
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *ResponseHeader) Msgsize() (s int) {
- s = 1 + 8 + z.Request.Msgsize() + 9 + z.DataHash.Msgsize() + 7 + z.NodeID.Msgsize() + 10 + hsp.TimeSize + 9 + hsp.Uint64Size
+ s = 1 + 8 + z.Request.Msgsize() + 9 + z.DataHash.Msgsize() + 7 + z.NodeID.Msgsize() + 10 + hsp.TimeSize + 9 + hsp.Uint64Size + 10 + hsp.Uint64Size
return
}
diff --git a/worker/types/types_test.go b/worker/types/types_test.go
index 67316cb43..9df73ff44 100644
--- a/worker/types/types_test.go
+++ b/worker/types/types_test.go
@@ -71,7 +71,7 @@ func Test_buildHash(t *testing.T) {
}
func TestSignedRequestHeader_Sign(t *testing.T) {
- privKey, pubKey := getCommKeys()
+ privKey, _ := getCommKeys()
Convey("sign", t, func() {
req := &SignedRequestHeader{
@@ -87,11 +87,6 @@ func TestSignedRequestHeader_Sign(t *testing.T) {
var err error
- // without signee
- err = req.Sign(privKey)
- So(err, ShouldNotBeNil)
-
- req.Signee = pubKey
err = req.Sign(privKey)
So(err, ShouldBeNil)
@@ -113,7 +108,7 @@ func TestSignedRequestHeader_Sign(t *testing.T) {
}
func TestRequest_Sign(t *testing.T) {
- privKey, pubKey := getCommKeys()
+ privKey, _ := getCommKeys()
Convey("sign", t, func() {
req := &Request{
@@ -126,7 +121,6 @@ func TestRequest_Sign(t *testing.T) {
SeqNo: uint64(2),
Timestamp: time.Now().UTC(),
},
- Signee: pubKey,
},
Payload: RequestPayload{
Queries: []Query{
@@ -218,7 +212,7 @@ func TestRequest_Sign(t *testing.T) {
}
func TestResponse_Sign(t *testing.T) {
- privKey, pubKey := getCommKeys()
+ privKey, _ := getCommKeys()
Convey("sign", t, func() {
res := &Response{
@@ -227,19 +221,17 @@ func TestResponse_Sign(t *testing.T) {
Request: SignedRequestHeader{
RequestHeader: RequestHeader{
QueryType: WriteQuery,
- NodeID: proto.NodeID("node1"),
+ NodeID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000001111"),
DatabaseID: proto.DatabaseID("db1"),
ConnectionID: uint64(1),
SeqNo: uint64(2),
Timestamp: time.Now().UTC(),
},
- Signee: pubKey,
},
- NodeID: proto.NodeID("node2"),
+ NodeID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000002222"),
Timestamp: time.Now().UTC(),
RowCount: uint64(1),
},
- Signee: pubKey,
},
Payload: ResponsePayload{
Columns: []string{
@@ -364,7 +356,7 @@ func TestResponse_Sign(t *testing.T) {
}
func TestAck_Sign(t *testing.T) {
- privKey, pubKey := getCommKeys()
+ privKey, _ := getCommKeys()
Convey("sign", t, func() {
ack := &Ack{
@@ -375,24 +367,21 @@ func TestAck_Sign(t *testing.T) {
Request: SignedRequestHeader{
RequestHeader: RequestHeader{
QueryType: WriteQuery,
- NodeID: proto.NodeID("node1"),
+ NodeID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000001111"),
DatabaseID: proto.DatabaseID("db1"),
ConnectionID: uint64(1),
SeqNo: uint64(2),
Timestamp: time.Now().UTC(),
},
- Signee: pubKey,
},
- NodeID: proto.NodeID("node2"),
+ NodeID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000002222"),
Timestamp: time.Now().UTC(),
RowCount: uint64(1),
},
- Signee: pubKey,
},
- NodeID: proto.NodeID("node1"),
+ NodeID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000001111"),
Timestamp: time.Now().UTC(),
},
- Signee: pubKey,
},
}
@@ -408,7 +397,9 @@ func TestAck_Sign(t *testing.T) {
})
// sign directly, embedded original response is not filled
- err = ack.Sign(privKey)
+ err = ack.Sign(privKey, false)
+ So(err, ShouldBeNil)
+ err = ack.Sign(privKey, true)
So(err, ShouldNotBeNil)
So(err, ShouldBeIn, []error{
ErrSignVerification,
@@ -422,7 +413,7 @@ func TestAck_Sign(t *testing.T) {
So(err, ShouldBeNil)
err = ack.Header.Response.Sign(privKey)
So(err, ShouldBeNil)
- err = ack.Sign(privKey)
+ err = ack.Sign(privKey, true)
So(err, ShouldBeNil)
Convey("serialize", func() {
@@ -487,35 +478,32 @@ func TestAck_Sign(t *testing.T) {
}
func TestNoAckReport_Sign(t *testing.T) {
- privKey, pubKey := getCommKeys()
+ privKey, _ := getCommKeys()
Convey("sign", t, func() {
noAck := &NoAckReport{
Header: SignedNoAckReportHeader{
NoAckReportHeader: NoAckReportHeader{
- NodeID: proto.NodeID("node2"),
+ NodeID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000002222"),
Timestamp: time.Now().UTC(),
Response: SignedResponseHeader{
ResponseHeader: ResponseHeader{
Request: SignedRequestHeader{
RequestHeader: RequestHeader{
QueryType: WriteQuery,
- NodeID: proto.NodeID("node1"),
+ NodeID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000001111"),
DatabaseID: proto.DatabaseID("db1"),
ConnectionID: uint64(1),
SeqNo: uint64(2),
Timestamp: time.Now().UTC(),
},
- Signee: pubKey,
},
- NodeID: proto.NodeID("node2"),
+ NodeID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000002222"),
Timestamp: time.Now().UTC(),
RowCount: uint64(1),
},
- Signee: pubKey,
},
},
- Signee: pubKey,
},
}
@@ -596,87 +584,80 @@ func TestNoAckReport_Sign(t *testing.T) {
}
func TestAggrNoAckReport_Sign(t *testing.T) {
- privKey, pubKey := getCommKeys()
+ privKey, _ := getCommKeys()
Convey("sign", t, func() {
aggrNoAck := &AggrNoAckReport{
Header: SignedAggrNoAckReportHeader{
AggrNoAckReportHeader: AggrNoAckReportHeader{
- NodeID: proto.NodeID("node3"),
+ NodeID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000003333"),
Timestamp: time.Now().UTC(),
Reports: []SignedNoAckReportHeader{
{
NoAckReportHeader: NoAckReportHeader{
- NodeID: proto.NodeID("node2"),
+ NodeID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000002222"),
Timestamp: time.Now().UTC(),
Response: SignedResponseHeader{
ResponseHeader: ResponseHeader{
Request: SignedRequestHeader{
RequestHeader: RequestHeader{
QueryType: WriteQuery,
- NodeID: proto.NodeID("node1"),
+ NodeID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000001111"),
DatabaseID: proto.DatabaseID("db1"),
ConnectionID: uint64(1),
SeqNo: uint64(2),
Timestamp: time.Now().UTC(),
},
- Signee: pubKey,
},
- NodeID: proto.NodeID("node2"),
+ NodeID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000002222"),
Timestamp: time.Now().UTC(),
RowCount: uint64(1),
},
- Signee: pubKey,
},
},
- Signee: pubKey,
},
{
NoAckReportHeader: NoAckReportHeader{
- NodeID: proto.NodeID("node3"),
+ NodeID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000003333"),
Timestamp: time.Now().UTC(),
Response: SignedResponseHeader{
ResponseHeader: ResponseHeader{
Request: SignedRequestHeader{
RequestHeader: RequestHeader{
QueryType: WriteQuery,
- NodeID: proto.NodeID("node1"),
+ NodeID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000001111"),
DatabaseID: proto.DatabaseID("db1"),
ConnectionID: uint64(1),
SeqNo: uint64(2),
Timestamp: time.Now().UTC(),
},
- Signee: pubKey,
},
- NodeID: proto.NodeID("node3"),
+ NodeID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000003333"),
Timestamp: time.Now().UTC(),
RowCount: uint64(1),
},
- Signee: pubKey,
},
},
- Signee: pubKey,
},
},
Peers: &kayak.Peers{
Term: uint64(1),
Leader: &kayak.Server{
Role: proto.Leader,
- ID: proto.NodeID("node3"),
+ ID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000003333"),
},
Servers: []*kayak.Server{
{
Role: proto.Leader,
- ID: proto.NodeID("node3"),
+ ID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000003333"),
},
{
Role: proto.Follower,
- ID: proto.NodeID("node2"),
+ ID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000002222"),
},
},
},
},
- Signee: pubKey,
},
}
@@ -787,16 +768,16 @@ func TestInitServiceResponse_Sign(t *testing.T) {
Term: uint64(1),
Leader: &kayak.Server{
Role: proto.Leader,
- ID: proto.NodeID("node3"),
+ ID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000003333"),
},
Servers: []*kayak.Server{
{
Role: proto.Leader,
- ID: proto.NodeID("node3"),
+ ID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000003333"),
},
{
Role: proto.Follower,
- ID: proto.NodeID("node2"),
+ ID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000002222"),
},
},
PubKey: pubKey,
@@ -807,7 +788,6 @@ func TestInitServiceResponse_Sign(t *testing.T) {
},
},
},
- Signee: pubKey,
},
}
@@ -879,16 +859,16 @@ func TestUpdateService_Sign(t *testing.T) {
Term: uint64(1),
Leader: &kayak.Server{
Role: proto.Leader,
- ID: proto.NodeID("node3"),
+ ID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000003333"),
},
Servers: []*kayak.Server{
{
Role: proto.Leader,
- ID: proto.NodeID("node3"),
+ ID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000003333"),
},
{
Role: proto.Follower,
- ID: proto.NodeID("node2"),
+ ID: proto.NodeID("0000000000000000000000000000000000000000000000000000000000002222"),
},
},
PubKey: pubKey,
@@ -898,8 +878,6 @@ func TestUpdateService_Sign(t *testing.T) {
GenesisBlock: nil,
},
},
-
- Signee: pubKey,
},
}
diff --git a/worker/types/update_service_type.go b/worker/types/update_service_type.go
index 470e39f24..ccea45e27 100644
--- a/worker/types/update_service_type.go
+++ b/worker/types/update_service_type.go
@@ -120,6 +120,7 @@ func (sh *SignedUpdateServiceHeader) Sign(signer *asymmetric.PrivateKey) (err er
// sign
sh.Signature, err = signer.Sign(sh.HeaderHash[:])
+ sh.Signee = signer.PubKey()
return
}